commit 9ae37cd0ea713ed5f8488755ea6198116bb8fbd4 Author: Andreas Lierschaft Date: Mon Aug 17 20:03:02 2026 +0200 Initial commit: client source diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..74d5e91 --- /dev/null +++ b/.gitignore @@ -0,0 +1,36 @@ +# Visual Studio Cache/Optionen +.vs/ +*.suo +*.user +*.sdf +*.opensdf +*.aps +*.ncb +*.VC.db +*.VC.VC.opendb + +# Build-Ausgabe (kompilierte Dateien, keine Quellen) +Debug/ +Release/ +Distribute/ +x64/ +x86/ +Win32/ +*.obj +*.exe +*.dll +*.pdb +*.ilk +*.exp +*.lib +*.idb +*.log +*.tlog +*.recipe +*.FileListAbsolute.txt +*.pch + +# Große Fremd-Abhängigkeiten / reine Build-Zwischendateien (kein eigener Code) +/extern/ +/vs_files/ +/binary/ diff --git a/DumpProto/Importer.sln b/DumpProto/Importer.sln new file mode 100644 index 0000000..1e283f1 --- /dev/null +++ b/DumpProto/Importer.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dump_proto", "dump_proto\dump_proto.vcxproj", "{DBCC99BC-1D68-4271-AC99-62EBBE37890F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lzo", "lzo\lzo.vcxproj", "{3AE0E6E6-B750-4769-9A6E-0D47012F1B40}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DBCC99BC-1D68-4271-AC99-62EBBE37890F}.Debug|Win32.ActiveCfg = Debug|Win32 + {DBCC99BC-1D68-4271-AC99-62EBBE37890F}.Debug|Win32.Build.0 = Debug|Win32 + {DBCC99BC-1D68-4271-AC99-62EBBE37890F}.Release|Win32.ActiveCfg = Release|Win32 + {DBCC99BC-1D68-4271-AC99-62EBBE37890F}.Release|Win32.Build.0 = Release|Win32 + {3AE0E6E6-B750-4769-9A6E-0D47012F1B40}.Debug|Win32.ActiveCfg = Debug|Win32 + {3AE0E6E6-B750-4769-9A6E-0D47012F1B40}.Debug|Win32.Build.0 = Debug|Win32 + {3AE0E6E6-B750-4769-9A6E-0D47012F1B40}.Release|Win32.ActiveCfg = Release|Win32 + {3AE0E6E6-B750-4769-9A6E-0D47012F1B40}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/DumpProto/dump_proto/CsvFile.cpp b/DumpProto/dump_proto/CsvFile.cpp new file mode 100644 index 0000000..8ef376c --- /dev/null +++ b/DumpProto/dump_proto/CsvFile.cpp @@ -0,0 +1,431 @@ +#include "CsvFile.h" +#include +#include + +#ifndef Assert + #include + #define Assert assert + #define LogToFile (void)(0); +#endif + +namespace +{ + /// Ľ̿ state Ű + enum ParseState + { + STATE_NORMAL = 0, ///< Ϲ + STATE_QUOTE ///< ǥ + }; + + /// ڿ ¿ ؼ ȯѴ. + std::string Trim(std::string str) + { + str = str.erase(str.find_last_not_of(" \t\r\n") + 1); + str = str.erase(0, str.find_first_not_of(" \t\r\n")); + return str; + } + + /// \brief ־ 忡 ִ ĺ ҹڷ ٲ۴. + std::string Lower(std::string original) + { + std::transform(original.begin(), original.end(), original.begin(), tolower); + return original; + } +} + +//////////////////////////////////////////////////////////////////////////////// +/// \brief ׼ , ̸ Ѵ. +/// \param name ̸ +/// \param index ε +//////////////////////////////////////////////////////////////////////////////// +void cCsvAlias::AddAlias(const char* name, size_t index) +{ + std::string converted(Lower(name)); + + Assert(m_Name2Index.find(converted) == m_Name2Index.end()); + Assert(m_Index2Name.find(index) == m_Index2Name.end()); + + m_Name2Index.insert(NAME2INDEX_MAP::value_type(converted, index)); + m_Index2Name.insert(INDEX2NAME_MAP::value_type(index, name)); +} + +//////////////////////////////////////////////////////////////////////////////// +/// \brief ͸ Ѵ. +//////////////////////////////////////////////////////////////////////////////// +void cCsvAlias::Destroy() +{ + m_Name2Index.clear(); + m_Index2Name.clear(); +} + +//////////////////////////////////////////////////////////////////////////////// +/// \brief ε ̸ ȯѴ. +/// \param index ε +/// \return const char* ̸ +//////////////////////////////////////////////////////////////////////////////// +const char* cCsvAlias::operator [] (size_t index) const +{ + INDEX2NAME_MAP::const_iterator itr(m_Index2Name.find(index)); + if (itr == m_Index2Name.end()) + { + LogToFile(NULL, "cannot find suitable conversion for %d", index); + Assert(false && "cannot find suitable conversion"); + return NULL; + } + + return itr->second.c_str(); +} + +//////////////////////////////////////////////////////////////////////////////// +/// \brief ̸ ε ȯѴ. +/// \param name ̸ +/// \return size_t ε +//////////////////////////////////////////////////////////////////////////////// +size_t cCsvAlias::operator [] (const char* name) const +{ + NAME2INDEX_MAP::const_iterator itr(m_Name2Index.find(Lower(name))); + if (itr == m_Name2Index.end()) + { + LogToFile(NULL, "cannot find suitable conversion for %s", name); + Assert(false && "cannot find suitable conversion"); + return 0; + } + + return itr->second; +} + +//////////////////////////////////////////////////////////////////////////////// +/// \brief ̸ CSV εѴ. +/// \param fileName CSV ̸ +/// \param seperator ʵ иڷ . ⺻ ','̴. +/// \param quote ǥ . ⺻ '"'̴. +/// \return bool εߴٸ true, ƴ϶ false +//////////////////////////////////////////////////////////////////////////////// +bool cCsvFile::Load(const char* fileName, const char seperator, const char quote) +{ + Assert(seperator != quote); + + std::ifstream file(fileName, std::ios::in); + if (!file) return false; + + Destroy(); // ͸ + + cCsvRow* row = NULL; + ParseState state = STATE_NORMAL; + std::string token = ""; + char buf[2048+1] = {0,}; + + while (file.good()) + { + file.getline(buf, 2048); + buf[sizeof(buf)-1] = 0; + + std::string line(Trim(buf)); + if (line.empty() || (state == STATE_NORMAL && line[0] == '#')) continue; + + std::string text = std::string(line) + " "; // Ľ lookahead ٿش. + size_t cur = 0; + + while (cur < text.size()) + { + // 尡 QUOTE , + if (state == STATE_QUOTE) + { + // '"' ̴. + // 1. ο Ư ڰ ̸ ˸ ¿ + // 2. '"' ڰ '"' 2 ġȯ + // ù° ִ CSV ̶, + // STATE_NORMAL ɸ Ǿִ. + // ׷Ƿ ⼭ ɸ 1 쳪, 2 ̴. + // 2 쿡 '"' ڰ 2 Ÿ. 1 + // 쿡 ƴϴ. ̸ ؼ ڵ带 ¥... + if (text[cur] == quote) + { + // ڰ '"' ڶ, ӵ '"' ڶ + // ̴ '"' ڰ ġȯ ̴. + if (text[cur+1] == quote) + { + token += quote; + ++cur; + } + // ڰ '"' ڰ ƴ϶ + // '"'ڴ ˸ ڶ ִ. + else + { + state = STATE_NORMAL; + } + } + else + { + token += text[cur]; + } + } + // 尡 NORMAL , + else if (state == STATE_NORMAL) + { + if (row == NULL) + row = new cCsvRow(); + + // ',' ڸ ٸ ǹѴ. + // ūμ Ʈٰ ְ, ū ʱȭѴ. + if (text[cur] == seperator) + { + row->push_back(token); + token.clear(); + } + // '"' ڸ ٸ, QUOTE ȯѴ. + else if (text[cur] == quote) + { + state = STATE_QUOTE; + } + // ٸ Ϲ ڶ ūٰ δ. + else + { + token += text[cur]; + } + } + + ++cur; + } + + // ',' ڰ ⼭ ߰Ѵ. + // , ó Ľ lookahead ̽ . + if (state == STATE_NORMAL) + { + Assert(row != NULL); + row->push_back(token.substr(0, token.size()-2)); + m_Rows.push_back(row); + token.clear(); + row = NULL; + } + else + { + token = token.substr(0, token.size()-2) + "\r\n"; + } + } + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +/// \brief ִ CSV Ͽ Ѵ. +/// \param fileName CSV ̸ +/// \param append true , Ͽ δ. false 쿡 +/// ϰ, . +/// \param seperator ʵ иڷ . ⺻ ','̴. +/// \param quote ǥ . ⺻ '"'̴. +/// \return bool ߴٸ true, 쿡 false +//////////////////////////////////////////////////////////////////////////////// +bool cCsvFile::Save(const char* fileName, bool append, char seperator, char quote) const +{ + Assert(seperator != quote); + + // 忡 ÷׷ Ѵ. + std::ofstream file; + if (append) { file.open(fileName, std::ios::out | std::ios::app); } + else { file.open(fileName, std::ios::out | std::ios::trunc); } + + // ߴٸ, false Ѵ. + if (!file) return false; + + char special_chars[5] = { seperator, quote, '\r', '\n', 0 }; + char quote_escape_string[3] = { quote, quote, 0 }; + + // Ⱦϸ鼭... + for (size_t i=0; isize(); +} + +//////////////////////////////////////////////////////////////////////////////// +/// \brief ε ̿ int ȯѴ. +/// \param index ε +/// \return int +//////////////////////////////////////////////////////////////////////////////// +int cCsvTable::AsInt(size_t index) const +{ + const cCsvRow* const row = CurRow(); + Assert(row); + Assert(index < row->size()); + return row->AsInt(index); +} + +//////////////////////////////////////////////////////////////////////////////// +/// \brief ε ̿ double ȯѴ. +/// \param index ε +/// \return double +//////////////////////////////////////////////////////////////////////////////// +double cCsvTable::AsDouble(size_t index) const +{ + const cCsvRow* const row = CurRow(); + Assert(row); + Assert(index < row->size()); + return row->AsDouble(index); +} + +//////////////////////////////////////////////////////////////////////////////// +/// \brief ε ̿ std::string ȯѴ. +/// \param index ε +/// \return const char* +//////////////////////////////////////////////////////////////////////////////// +const char* cCsvTable::AsStringByIndex(size_t index) const +{ + const cCsvRow* const row = CurRow(); + Assert(row); + Assert(index < row->size()); + return row->AsString(index); +} + +//////////////////////////////////////////////////////////////////////////////// +/// \brief alias ͸ Ѵ. +//////////////////////////////////////////////////////////////////////////////// +void cCsvTable::Destroy() +{ + m_File.Destroy(); + m_Alias.Destroy(); + m_CurRow = -1; +} + +//////////////////////////////////////////////////////////////////////////////// +/// \brief ȯѴ. +/// \return const cCsvRow* ׼ ϴ 쿡 +/// ͸ ȯϰ, ̻ ׼ 쿡 NULL +/// ȯѴ. +//////////////////////////////////////////////////////////////////////////////// +const cCsvRow* const cCsvTable::CurRow() const +{ + if (m_CurRow < 0) + { + Assert(false && "call Next() first!"); + return NULL; + } + else if (m_CurRow >= (int)m_File.GetRowCount()) + { + Assert(false && "no more rows!"); + return NULL; + } + + return m_File[m_CurRow]; +} + + + diff --git a/DumpProto/dump_proto/CsvFile.h b/DumpProto/dump_proto/CsvFile.h new file mode 100644 index 0000000..90c02c7 --- /dev/null +++ b/DumpProto/dump_proto/CsvFile.h @@ -0,0 +1,325 @@ +#ifndef __CSVFILE_H__ +#define __CSVFILE_H__ + +#include +#include + +#if _MSC_VER + //#include + #include +#else + #include +#endif + +//////////////////////////////////////////////////////////////////////////////// +/// \class cCsvAlias +/// \brief CSV ߻ϴ ε ̱ +/// ü. +/// +/// 0 ÷ A ϰ, 1 ÷ B +/// ϰ ־µ... +/// +///
+/// int a = row.AsInt(0);
+/// int b = row.AsInt(1);
+/// 
+/// +/// ̿ C ϴ ÷ , ϵڵǾ ִ +/// 1 ãƼ ľ ϴµ, ߻ϱ ۾̴. +/// +///
+/// int a = row.AsInt(0);
+/// int c = row.AsInt(1);
+/// int b = row.AsInt(2); <--  κ  Ű Ѵ.
+/// 
+/// +/// κ ڿ óϸ  ణ̳ +/// ִ. +//////////////////////////////////////////////////////////////////////////////// + +class cCsvAlias +{ +private: +#if _MSC_VER + //typedef stdext::hash_map NAME2INDEX_MAP; + //typedef stdext::hash_map INDEX2NAME_MAP; + typedef std::unordered_map NAME2INDEX_MAP; + typedef std::unordered_map INDEX2NAME_MAP; +#else + typedef std::map NAME2INDEX_MAP; + typedef std::map INDEX2NAME_MAP; +#endif + + NAME2INDEX_MAP m_Name2Index; ///< ε ϱ ̸ + INDEX2NAME_MAP m_Index2Name; ///< ߸ alias ˻ϱ ߰ + + +public: + /// \brief + cCsvAlias() {} + + /// \brief Ҹ + virtual ~cCsvAlias() {} + + +public: + /// \brief ׼ , ̸ Ѵ. + void AddAlias(const char* name, size_t index); + + /// \brief ͸ Ѵ. + void Destroy(); + + /// \brief ε ̸ ȯѴ. + const char* operator [] (size_t index) const; + + /// \brief ̸ ε ȯѴ. + size_t operator [] (const char* name) const; + + +private: + /// \brief + cCsvAlias(const cCsvAlias&) {} + + /// \brief + const cCsvAlias& operator = (const cCsvAlias&) { return *this; } +}; + + +//////////////////////////////////////////////////////////////////////////////// +/// \class cCsvRow +/// \brief CSV ĸȭ Ŭ +/// +/// CSV ⺻ ̴ ϳ ',' ڷ ̴. +/// , ȿ Ư ڷ ̴ ',' ڳ '"' ڰ  , +/// ణ ̻ϰ Ѵ. ȭ ̴. +/// +///
+///  ̴  |  CSV Ͽ ִ 
+/// ---------------------+----------------------------------------------------
+/// ItemPrice            | ItemPrice
+/// Item,Price           | "Item,Price"
+/// Item"Price           | "Item""Price"
+/// "ItemPrice"          | """ItemPrice"""
+/// "Item,Price"         | """Item,Price"""
+/// Item",Price          | "Item"",Price"
+/// 
+/// +/// μ ִ. +/// - ο ',' Ǵ '"' ڰ  , ¿쿡 '"' ڰ . +/// - '"' ڴ 2 ġȯȴ. +/// +/// \sa cCsvFile +//////////////////////////////////////////////////////////////////////////////// + +class cCsvRow : public std::vector +{ +public: + /// \brief ⺻ + cCsvRow() {} + + /// \brief Ҹ + ~cCsvRow() {} + + +public: + /// \brief ش ͸ int ȯѴ. + int AsInt(size_t index) const { return atoi(at(index).c_str()); } + + /// \brief ش ͸ double ȯѴ. + double AsDouble(size_t index) const { return atof(at(index).c_str()); } + + /// \brief ش ͸ ڿ ȯѴ. + const char* AsString(size_t index) const { return at(index).c_str(); } + + /// \brief شϴ ̸ ͸ int ȯѴ. + int AsInt(const char* name, const cCsvAlias& alias) const { + return atoi( at(alias[name]).c_str() ); + } + + /// \brief شϴ ̸ ͸ int ȯѴ. + double AsDouble(const char* name, const cCsvAlias& alias) const { + return atof( at(alias[name]).c_str() ); + } + + /// \brief شϴ ̸ ͸ ڿ ȯѴ. + const char* AsString(const char* name, const cCsvAlias& alias) const { + return at(alias[name]).c_str(); + } + + +private: + /// \brief + cCsvRow(const cCsvRow&) {} + + /// \brief + const cCsvRow& operator = (const cCsvRow&) { return *this; } +}; + + +//////////////////////////////////////////////////////////////////////////////// +/// \class cCsvFile +/// \brief CSV(Comma Seperated Values) read/writeϱ Ŭ +/// +/// sample +///
+/// cCsvFile file;
+///
+/// cCsvRow row1, row2, row3;
+/// row1.push_back("ItemPrice");
+/// row1.push_back("Item,Price");
+/// row1.push_back("Item\"Price");
+///
+/// row2.reserve(3);
+/// row2[0] = "\"ItemPrice\"";
+/// row2[1] = "\"Item,Price\"";
+/// row2[2] = "Item\",Price\"";
+///
+/// row3 = "\"ItemPrice\"\"Item,Price\"Item\",Price\"";
+///
+/// file.add(row1);
+/// file.add(row2);
+/// file.add(row3);
+/// file.save("test.csv", false);
+/// 
+/// +/// \todo Ͽ о ƴ϶, ޸ ҽκ д Լ +/// ־ ϴ. +//////////////////////////////////////////////////////////////////////////////// + +class cCsvFile +{ +private: + typedef std::vector ROWS; + + ROWS m_Rows; ///< ÷ + + +public: + /// \brief + cCsvFile() {} + + /// \brief Ҹ + virtual ~cCsvFile() { Destroy(); } + + +public: + /// \brief ̸ CSV εѴ. + bool Load(const char* fileName, const char seperator=',', const char quote='"'); + + /// \brief ִ CSV Ͽ Ѵ. + bool Save(const char* fileName, bool append=false, char seperator=',', char quote='"') const; + + /// \brief ͸ ޸𸮿 Ѵ. + void Destroy(); + + /// \brief شϴ ε ȯѴ. + cCsvRow* operator [] (size_t index); + + /// \brief شϴ ε ȯѴ. + const cCsvRow* operator [] (size_t index) const; + + /// \brief ȯѴ. + size_t GetRowCount() const { return m_Rows.size(); } + + +private: + /// \brief + cCsvFile(const cCsvFile&) {} + + /// \brief + const cCsvFile& operator = (const cCsvFile&) { return *this; } +}; + + +//////////////////////////////////////////////////////////////////////////////// +/// \class cCsvTable +/// \brief CSV ̿ ̺ ͸ εϴ 찡 , Ŭ +/// ۾ ϱ ƿƼ Ŭ. +/// +/// CSV εϴ , ڸ ̿ ׼ؾ ϴµ, CSV +/// ٲ , ڵ Ѵ. ۾ +/// Ű 䱸ϴ ٰ, ߻ϱ . ׷Ƿ ڷ +/// ׼ϱ⺸ٴ ڿ ׼ϴ ణ ٰ ִ. +/// +/// sample +///
+/// cCsvTable table;
+///
+/// table.alias(0, "ItemClass");
+/// table.alias(1, "ItemType");
+///
+/// if (table.load("test.csv"))
+/// {
+///     while (table.next())
+///     {
+///         std::string item_class = table.AsString("ItemClass");
+///         int         item_type  = table.AsInt("ItemType"); 
+///     }
+/// }
+/// 
+//////////////////////////////////////////////////////////////////////////////// + +class cCsvTable +{ +public : + cCsvFile m_File; ///< CSV ü +private: + cCsvAlias m_Alias; ///< ڿ ε ȯϱ ü + int m_CurRow; ///< Ⱦ ȣ + + +public: + /// \brief + cCsvTable(); + + /// \brief Ҹ + virtual ~cCsvTable(); + + +public: + /// \brief ̸ CSV εѴ. + bool Load(const char* fileName, const char seperator=',', const char quote='"'); + + /// \brief ׼ , ̸ Ѵ. + void AddAlias(const char* name, size_t index) { m_Alias.AddAlias(name, index); } + + /// \brief Ѿ. + bool Next(); + + /// \brief ڸ ȯѴ. + size_t ColCount() const; + + /// \brief ε ̿ int ȯѴ. + int AsInt(size_t index) const; + + /// \brief ε ̿ double ȯѴ. + double AsDouble(size_t index) const; + + /// \brief ε ̿ std::string ȯѴ. + const char* AsStringByIndex(size_t index) const; + + /// \brief ̸ ̿ int ȯѴ. + int AsInt(const char* name) const { return AsInt(m_Alias[name]); } + + /// \brief ̸ ̿ double ȯѴ. + double AsDouble(const char* name) const { return AsDouble(m_Alias[name]); } + + /// \brief ̸ ̿ std::string ȯѴ. + const char* AsString(const char* name) const { return AsStringByIndex(m_Alias[name]); } + + /// \brief alias ͸ Ѵ. + void Destroy(); + + +private: + /// \brief ȯѴ. + const cCsvRow* const CurRow() const; + + /// \brief + cCsvTable(const cCsvTable&) {} + + /// \brief + const cCsvTable& operator = (const cCsvTable&) { return *this; } +}; + +#endif //__CSVFILE_H__ diff --git a/DumpProto/dump_proto/ItemCSVReader.cpp b/DumpProto/dump_proto/ItemCSVReader.cpp new file mode 100644 index 0000000..547d747 --- /dev/null +++ b/DumpProto/dump_proto/ItemCSVReader.cpp @@ -0,0 +1,566 @@ +#include +#include "ItemCSVReader.h" + + + +using namespace std; + +inline string trim_left(const string& str) +{ + string::size_type n = str.find_first_not_of(" \t\v\n\r"); + return n == string::npos ? str : str.substr(n, str.length()); +} + +inline string trim_right(const string& str) +{ + string::size_type n = str.find_last_not_of(" \t\v\n\r"); + return n == string::npos ? str : str.substr(0, n + 1); +} + +string trim(const string& str){return trim_left(trim_right(str));} + +static string* StringSplit(string strOrigin, string strTok) +{ + int cutAt; //ڸġ + int index = 0; //ڿε + string* strResult = new string[30]; //return Һ + + //strTokãݺ + while ((cutAt = strOrigin.find_first_of(strTok)) != strOrigin.npos) + { + if (cutAt > 0) //ڸġ0ũ() + { + strResult[index++] = strOrigin.substr(0, cutAt); //迭߰ + } + strOrigin = strOrigin.substr(cutAt+1); //ڸκѳ + } + + if(strOrigin.length() > 0) //̾ + { + strResult[index++] = strOrigin.substr(0, cutAt); //迭߰ + } + + for( int i=0;i "; + for (int j=0;j "; + for (int j=0;j " << retValue << endl; + + return retValue; +} + +int get_Item_Flag_Value(string inputString) +{ + + string arFlag[] = {"ITEM_TUNABLE", "ITEM_SAVE", "ITEM_STACKABLE", "COUNT_PER_1GOLD", "ITEM_SLOW_QUERY", "ITEM_UNIQUE", + "ITEM_MAKECOUNT", "ITEM_IRREMOVABLE", "CONFIRM_WHEN_USE", "QUEST_USE", "QUEST_USE_MULTIPLE", + "QUEST_GIVE", "ITEM_QUEST", "LOG", "STACKABLE", "SLOW_QUERY", "REFINEABLE", "IRREMOVABLE", "ITEM_APPLICABLE"}; + + + int retValue = 0; + string* arInputString = StringSplit(inputString, "|"); // ܾ ɰ 迭. + for(int i =0;i " << retValue << endl; + + return retValue; +} + +int get_Item_WearFlag_Value(string inputString) +{ + + string arWearrFlag[] = {"WEAR_BODY", "WEAR_HEAD", "WEAR_FOOTS", "WEAR_WRIST", "WEAR_WEAPON", "WEAR_NECK", "WEAR_EAR", "WEAR_SHIELD", "WEAR_UNIQUE", + "WEAR_ARROW", "WEAR_HAIR", "WEAR_ABILITY"}; + + + int retValue = 0; + string* arInputString = StringSplit(inputString, "|"); // ܾ ɰ 迭. + for(int i =0;i " << retValue << endl; + + return retValue; +} + +int get_Item_Immune_Value(string inputString) +{ + + string arImmune[] = {"PARA","CURSE","STUN","SLEEP","SLOW","POISON","TERROR"}; + + int retValue = 0; + string* arInputString = StringSplit(inputString, "|"); // ܾ ɰ 迭. + for(int i =0;i " << retValue << endl; + + return retValue; +} + + + + +int get_Item_LimitType_Value(string inputString) +{ + string arLimitType[] = {"LIMIT_NONE", "LEVEL", "STR", "DEX", "INT", "CON", "PC_BANG", "REAL_TIME", "REAL_TIME_FIRST_USE", "TIMER_BASED_ON_WEAR"}; + + int retInt = -1; + //cout << "LimitType : " << limitTypeStr << " -> "; + for (int j=0;j "; + for (int j=0;j "; + for (int j=0;j "; + for (int j=0;j "; + for (int j=0;j "; + for (int j=0;j " << retValue << endl; + + return retValue; +} +int get_Mob_RaceFlag_Value(string inputString) +{ + string arRaceFlag[] = {"ANIMAL","UNDEAD","DEVIL","HUMAN","ORC","MILGYO","INSECT","FIRE","ICE","DESERT","TREE", + "ATT_ELEC","ATT_FIRE","ATT_ICE","ATT_WIND","ATT_EARTH","ATT_DARK"}; + + int retValue = 0; + string* arInputString = StringSplit(inputString, "|"); // ܾ ɰ 迭. + for(int i =0;i " << retValue << endl; + + return retValue; +} +int get_Mob_ImmuneFlag_Value(string inputString) +{ + string arImmuneFlag[] = {"STUN","SLOW","FALL","CURSE","POISON","TERROR"}; + + int retValue = 0; + string* arInputString = StringSplit(inputString, ","); // ܾ ɰ 迭. + for(int i =0;i " << retValue << endl; + + + return retValue; +} diff --git a/DumpProto/dump_proto/ItemCSVReader.h b/DumpProto/dump_proto/ItemCSVReader.h new file mode 100644 index 0000000..94d6ce0 --- /dev/null +++ b/DumpProto/dump_proto/ItemCSVReader.h @@ -0,0 +1,29 @@ +#ifndef __Item_CSV_READER_H__ +#define __Item_CSV_READER_H__ + +#include + +//csv оͼ ̺ ־ش. +void putItemIntoTable(); //(̺, ׽Ʈ) + +int get_Item_Type_Value(std::string inputString); +int get_Item_SubType_Value(int type_value, std::string inputString); +int get_Item_AntiFlag_Value(std::string inputString); +int get_Item_Flag_Value(std::string inputString); +int get_Item_WearFlag_Value(std::string inputString); +int get_Item_Immune_Value(std::string inputString); +int get_Item_LimitType_Value(std::string inputString); +int get_Item_ApplyType_Value(std::string inputString); + + +// 䵵 ִ. +int get_Mob_Rank_Value(std::string inputString); +int get_Mob_Type_Value(std::string inputString); +int get_Mob_BattleType_Value(std::string inputString); + +int get_Mob_Size_Value(std::string inputString); +int get_Mob_AIFlag_Value(std::string inputString); +int get_Mob_RaceFlag_Value(std::string inputString); +int get_Mob_ImmuneFlag_Value(std::string inputString); + +#endif \ No newline at end of file diff --git a/DumpProto/dump_proto/Singleton.h b/DumpProto/dump_proto/Singleton.h new file mode 100644 index 0000000..085059a --- /dev/null +++ b/DumpProto/dump_proto/Singleton.h @@ -0,0 +1,114 @@ +#ifndef __INC_ETERLIB_SINGLETON_H__ +#define __INC_ETERLIB_SINGLETON_H__ + +#include + +template class CSingleton +{ + static T * ms_singleton; + +public: + CSingleton() + { + assert(!ms_singleton); + int offset = (int) (T*) 1 - (int) (CSingleton *) (T*) 1; + ms_singleton = (T*) ((int) this + offset); + } + + virtual ~CSingleton() + { + assert(ms_singleton); + ms_singleton = 0; + } + + __forceinline static T & Instance() + { + assert(ms_singleton); + return (*ms_singleton); + } + + __forceinline static T * InstancePtr() + { + return (ms_singleton); + } + + __forceinline static T & instance() + { + assert(ms_singleton); + return (*ms_singleton); + } +}; + +template T * CSingleton ::ms_singleton = 0; + +// +// singleton for non-hungarian +// +template class singleton +{ + static T * ms_singleton; + +public: + singleton() + { + assert(!ms_singleton); + int offset = (int) (T*) 1 - (int) (CSingleton *) (T*) 1; + ms_singleton = (T*) ((int) this + offset); + } + + virtual ~singleton() + { + assert(ms_singleton); + ms_singleton = 0; + } + + __forceinline static T & Instance() + { + assert(ms_singleton); + return (*ms_singleton); + } + + __forceinline static T * InstancePtr() + { + return (ms_singleton); + } + + __forceinline static T & instance() + { + assert(ms_singleton); + return (*ms_singleton); + } +}; + +template T * singleton ::ms_singleton = 0; + +/* +template +class CSingleton : public T +{ + public: + static T & Instance() + { + assert(ms_pInstance != NULL); + return *ms_pInstance; + } + + CSingleton() + { + assert(ms_pInstance == NULL); + ms_pInstance = this; + } + + virtual ~CSingleton() + { + assert(ms_pInstance); + ms_pInstance = 0; + } + + protected: + static T * ms_pInstance; +}; + +template T * CSingleton::ms_pInstance = NULL; +*/ +#endif diff --git a/DumpProto/dump_proto/dump_proto.cpp b/DumpProto/dump_proto/dump_proto.cpp new file mode 100644 index 0000000..e0a75d2 --- /dev/null +++ b/DumpProto/dump_proto/dump_proto.cpp @@ -0,0 +1,1086 @@ +//#include "../../libthecore/include/stdafx.h" +//#include "" +//#define __WIN32__ +#include +#include +#include +#include +#include + +#include "lzo.h" + +//exe 鼭 ߰ : о ֵ Ͽ. +#include "CsvFile.h" +#include "ItemCSVReader.h" + + +#pragma comment(lib, "lzo.lib") + + +#define MAKEFOURCC(ch0, ch1, ch2, ch3) \ + ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \ + ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 )) + +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef unsigned long DWORD; + +enum EMisc +{ + CHARACTER_NAME_MAX_LEN = 24, + MOB_SKILL_MAX_NUM = 5, +}; + +enum EMobEnchants +{ + MOB_ENCHANT_CURSE, + MOB_ENCHANT_SLOW, + MOB_ENCHANT_POISON, + MOB_ENCHANT_STUN, + MOB_ENCHANT_CRITICAL, + MOB_ENCHANT_PENETRATE, + MOB_ENCHANTS_MAX_NUM +}; + +enum EMobResists +{ + MOB_RESIST_SWORD, + MOB_RESIST_TWOHAND, + MOB_RESIST_DAGGER, + MOB_RESIST_BELL, + MOB_RESIST_FAN, + MOB_RESIST_BOW, + MOB_RESIST_FIRE, + MOB_RESIST_ELECT, + MOB_RESIST_MAGIC, + MOB_RESIST_WIND, + MOB_RESIST_POISON, + MOB_RESISTS_MAX_NUM +}; + + +#pragma pack(1) +typedef struct SMobSkillLevel +{ + DWORD dwVnum; + BYTE bLevel; +} TMobSkillLevel; +#pragma pack() + +#pragma pack(1) +typedef struct SMobTable +{ + DWORD dwVnum; + char szName[CHARACTER_NAME_MAX_LEN + 1]; + char szLocaleName[CHARACTER_NAME_MAX_LEN + 1]; + + BYTE bType; // Monster, NPC + BYTE bRank; // PAWN, KNIGHT, KING + BYTE bBattleType; // MELEE, etc.. + BYTE bLevel; // Level + BYTE bSize; + + DWORD dwGoldMin; + DWORD dwGoldMax; + DWORD dwExp; + DWORD dwMaxHP; + BYTE bRegenCycle; + BYTE bRegenPercent; + WORD wDef; + + DWORD dwAIFlag; + DWORD dwRaceFlag; + DWORD dwImmuneFlag; + + BYTE bStr, bDex, bCon, bInt; + DWORD dwDamageRange[2]; + + short sAttackSpeed; + short sMovingSpeed; + BYTE bAggresiveHPPct; + WORD wAggressiveSight; + WORD wAttackRange; + + char cEnchants[MOB_ENCHANTS_MAX_NUM]; + char cResists[MOB_RESISTS_MAX_NUM]; + + DWORD dwResurrectionVnum; + DWORD dwDropItemVnum; + + BYTE bMountCapacity; + BYTE bOnClickType; + + BYTE bEmpire; + char szFolder[64 + 1]; + + float fDamMultiply; + + DWORD dwSummonVnum; + DWORD dwDrainSP; + DWORD dwMobColor; + DWORD dwPolymorphItemVnum; + + TMobSkillLevel Skills[MOB_SKILL_MAX_NUM]; + + BYTE bBerserkPoint; + BYTE bStoneSkinPoint; + BYTE bGodSpeedPoint; + BYTE bDeathBlowPoint; + BYTE bRevivePoint; +} TMobTable; +#pragma pack() + + +using namespace std; + +TMobTable * m_pMobTable = NULL; +int m_iMobTableSize = 0; + + +enum EItemMisc +{ + ITEM_NAME_MAX_LEN = 24, + ITEM_VALUES_MAX_NUM = 6, + ITEM_SMALL_DESCR_MAX_LEN = 256, + ITEM_LIMIT_MAX_NUM = 2, + ITEM_APPLY_MAX_NUM = 3, + ITEM_SOCKET_MAX_NUM = 3, + ITEM_MAX_COUNT = 200, + ITEM_ATTRIBUTE_MAX_NUM = 7, + ITEM_ATTRIBUTE_MAX_LEVEL = 5, + ITEM_AWARD_WHY_MAX_LEN = 50, + + REFINE_MATERIAL_MAX_NUM = 5, + + ITEM_ELK_VNUM = 50026, +}; +#pragma pack(1) +typedef struct SItemLimit +{ + BYTE bType; + long lValue; +} TItemLimit; +#pragma pack() + +#pragma pack(1) +typedef struct SItemApply +{ + BYTE bType; + long lValue; +} TItemApply; +#pragma pack() + +#pragma pack(1) +typedef struct +{ + DWORD dwVnum; + DWORD dwVnumRange; + char szName[ITEM_NAME_MAX_LEN + 1]; + char szLocaleName[ITEM_NAME_MAX_LEN + 1]; + BYTE bType; + BYTE bSubType; + + BYTE bWeight; + BYTE bSize; + + DWORD dwAntiFlags; + DWORD dwFlags; + DWORD dwWearFlags; + DWORD dwImmuneFlag; + + DWORD dwGold; + DWORD dwShopBuyPrice; + + TItemLimit aLimits[ITEM_LIMIT_MAX_NUM]; + TItemApply aApplies[ITEM_APPLY_MAX_NUM]; + long alValues[ITEM_VALUES_MAX_NUM]; + long alSockets[ITEM_SOCKET_MAX_NUM]; + DWORD dwRefinedVnum; + WORD wRefineSet; + BYTE bAlterToMagicItemPct; + BYTE bSpecular; + BYTE bGainSocketPct; +} TClientItemTable; +#pragma pack() +bool operator < (const TClientItemTable& lhs, const TClientItemTable& rhs) +{ + return lhs.dwVnum < rhs.dwVnum; +} + +TClientItemTable * m_pItemTable = NULL; +int m_iItemTableSize = 0; + + +bool Set_Proto_Mob_Table(TMobTable *mobTable, cCsvTable &csvTable, std::map &nameMap) +{ + int col = 0; + + mobTable->dwVnum = atoi(csvTable.AsStringByIndex(col++)); + strncpy(mobTable->szName, csvTable.AsStringByIndex(col++), CHARACTER_NAME_MAX_LEN); + // ϸ о. + map::iterator it; + it = nameMap.find(mobTable->dwVnum); + if (it != nameMap.end()) { + const char * localeName = it->second; + strncpy(mobTable->szLocaleName, localeName, sizeof (mobTable->szLocaleName)); + } else { // , ѱ ״ . + strncpy(mobTable->szLocaleName, mobTable->szName, sizeof (mobTable->szLocaleName)); + } + //4. RANK + int rankValue = get_Mob_Rank_Value(csvTable.AsStringByIndex(col++)); + mobTable->bRank = rankValue; + //5. TYPE + int typeValue = get_Mob_Type_Value(csvTable.AsStringByIndex(col++)); + mobTable->bType = typeValue; + //6. BATTLE_TYPE + int battleTypeValue = get_Mob_BattleType_Value(csvTable.AsStringByIndex(col++)); + mobTable->bBattleType = battleTypeValue; + + mobTable->bLevel = atoi(csvTable.AsStringByIndex(col++)); + //8. SIZE + int sizeValue = get_Mob_Size_Value(csvTable.AsStringByIndex(col++)); + mobTable->bSize = sizeValue; + //9. AI_FLAG + int aiFlagValue = get_Mob_AIFlag_Value(csvTable.AsStringByIndex(col++)); + mobTable->dwAIFlag = aiFlagValue; + col++; //mount_capacity; + //10. RACE_FLAG + int raceFlagValue = get_Mob_RaceFlag_Value(csvTable.AsStringByIndex(col++)); + mobTable->dwRaceFlag = raceFlagValue; + //11. IMMUNE_FLAG + int immuneFlagValue = get_Mob_ImmuneFlag_Value(csvTable.AsStringByIndex(col++)); + mobTable->dwImmuneFlag = immuneFlagValue; + + mobTable->bEmpire = atoi(csvTable.AsStringByIndex(col++)); + + //folder + strncpy(mobTable->szFolder, csvTable.AsStringByIndex(col++), sizeof(mobTable->szFolder)); + + + mobTable->bOnClickType = atoi(csvTable.AsStringByIndex(col++)); + + mobTable->bStr = atoi(csvTable.AsStringByIndex(col++)); + mobTable->bDex = atoi(csvTable.AsStringByIndex(col++)); + mobTable->bCon = atoi(csvTable.AsStringByIndex(col++)); + mobTable->bInt = atoi(csvTable.AsStringByIndex(col++)); + mobTable->dwDamageRange[0] = atoi(csvTable.AsStringByIndex(col++)); + mobTable->dwDamageRange[1] = atoi(csvTable.AsStringByIndex(col++)); + mobTable->dwMaxHP = atoi(csvTable.AsStringByIndex(col++)); + mobTable->bRegenCycle = atoi(csvTable.AsStringByIndex(col++)); + mobTable->bRegenPercent = atoi(csvTable.AsStringByIndex(col++)); + + col++; //gold min + col++; //gold max + mobTable->dwExp = atoi(csvTable.AsStringByIndex(col++)); + mobTable->wDef = atoi(csvTable.AsStringByIndex(col++)); + mobTable->sAttackSpeed = atoi(csvTable.AsStringByIndex(col++)); + mobTable->sMovingSpeed = atoi(csvTable.AsStringByIndex(col++)); + mobTable->bAggresiveHPPct = atoi(csvTable.AsStringByIndex(col++)); + mobTable->wAggressiveSight = atoi(csvTable.AsStringByIndex(col++)); + mobTable->wAttackRange = atoi(csvTable.AsStringByIndex(col++)); + + mobTable->dwDropItemVnum = atoi(csvTable.AsStringByIndex(col++)); + col++; //resurrectionVnum + + + for (int i = 0; i < MOB_ENCHANTS_MAX_NUM; ++i) + mobTable->cEnchants[i] = atoi(csvTable.AsStringByIndex(col++)); + + for (int i = 0; i < MOB_RESISTS_MAX_NUM; ++i) + mobTable->cResists[i] = atoi(csvTable.AsStringByIndex(col++)); + + mobTable->fDamMultiply = atoi(csvTable.AsStringByIndex(col++)); + mobTable->dwSummonVnum = atoi(csvTable.AsStringByIndex(col++)); + mobTable->dwDrainSP = atoi(csvTable.AsStringByIndex(col++)); + mobTable->dwMobColor = atoi(csvTable.AsStringByIndex(col++)); + + return true; +} + + +bool BuildMobTable() +{ + //%%% <Լ > %%%// + //1. : 'mob_proto.txt', 'mob_proto_test.txt', 'mob_names.txt' а, + // m_pMobTable Ѵ. + //2. + // 1)'mob_names.txt' о vnum:name . + // 2)'mob_proto_test.txt' о, + // test_mob_table , + // vnum:TMobTable . + // 3)'mob_proto.txt' а, m_pMobTable Ѵ. + // test_mob_table ִ vnum ׽Ʈ ͸ ִ´. + // 4)test_mob_table ߿, m_pMobTable ͸ ߰Ѵ. + //3. ׽Ʈ + // 1)'mob_proto.txt' m_pMobTable . -> Ϸ + // 2)'mob_names.txt' m_pMobTable . -> Ϸ + // 3)'mob_proto_test.txt' [ġ] m_pMobTable . -> Ϸ + // 4)'mob_proto_test.txt' [ο] m_pMobTable . -> Ϸ + //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// + + fprintf(stderr, "sizeof(TMobTable): %u\n", sizeof(TMobTable)); + + + //==============================================================// + //======local ̸ ϰ ִ [] vnum:name======// + //==============================================================// + bool isNameFile = true; + map localMap; + cCsvTable nameData; + if(!nameData.Load("mob_names.txt",'\t')) + { + fprintf(stderr, "mob_names.txt о ߽ϴ\n"); + isNameFile = false; + } else { + nameData.Next(); + while(nameData.Next()) { + localMap[atoi(nameData.AsStringByIndex(0))] = nameData.AsStringByIndex(1); + } + } + //______________________________________________________________// + + //=========================================// + //======͵ vnum []======// + // *׽Ʈ оö, // + // 1. ִ ȮҶ // + //=========================================// + set vnumSet; + //_________________________________________// + + //==================================================// + // 2)'mob_proto_test.txt' о, + // test_mob_table , + // vnum:TMobTable . + //==================================================// + map test_map_mobTableByVnum; + + //1. о. + cCsvTable test_data; + if(!test_data.Load("mob_proto_test.txt",'\t')) + { + fprintf(stderr, "mob_proto_test.txt о ߽ϴ\n"); + //return false; + } else { + test_data.Next(); // ο Ѿ. + + //2. ׽Ʈ ̺ . + TMobTable * test_mob_table = NULL; + int test_MobTableSize = test_data.m_File.GetRowCount()-1; + test_mob_table = new TMobTable[test_MobTableSize]; + memset(test_mob_table, 0, sizeof(TMobTable) * test_MobTableSize); + + //3. ׽Ʈ ̺ ְ, ʿ ֱ. + while(test_data.Next()) { + + if (!Set_Proto_Mob_Table(test_mob_table, test_data, localMap)) + { + fprintf(stderr, " ̺ .\n"); + } + + + test_map_mobTableByVnum.insert(std::map::value_type(test_mob_table->dwVnum, test_mob_table)); + ++test_mob_table; + } + } + + //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// + + + // о. + cCsvTable data; + if(!data.Load("mob_proto.txt",'\t')) + { + fprintf(stderr, "mob_proto.txt о ߽ϴ\n"); + return false; + } + data.Next(); // ( Į ϴ κ) + + + + //===== ̺ =====// + if (m_pMobTable) + { + delete m_pMobTable; + m_pMobTable = NULL; + } + + // ߰Ǵ ľѴ. + int addNumber = 0; + while(data.Next()) { + int vnum = atoi(data.AsStringByIndex(0)); + std::map::iterator it_map_mobTable; + it_map_mobTable = test_map_mobTableByVnum.find(vnum); + if(it_map_mobTable != test_map_mobTableByVnum.end()) { + addNumber++; + } + } + + + m_iMobTableSize = data.m_File.GetRowCount()-1 + addNumber; + + m_pMobTable = new TMobTable[m_iMobTableSize]; + memset(m_pMobTable, 0, sizeof(TMobTable) * m_iMobTableSize); + + TMobTable * mob_table = m_pMobTable; + + + //data ٽ ùٷ ű.(ٽ о´;;) + data.Destroy(); + if(!data.Load("mob_proto.txt",'\t')) + { + fprintf(stderr, "mob_proto.txt о ߽ϴ\n"); + return false; + } + data.Next(); // ( Į ϴ κ) + + while (data.Next()) + { + int col = 0; + //׽Ʈ Ͽ vnum ִ . + std::map::iterator it_map_mobTable; + it_map_mobTable = test_map_mobTableByVnum.find(atoi(data.AsStringByIndex(col))); + if(it_map_mobTable == test_map_mobTableByVnum.end()) { + + if (!Set_Proto_Mob_Table(mob_table, data, localMap)) + { + fprintf(stderr, " ̺ .\n"); + } + + } else { //$$$$$$$$$$$$$$$$$$$$$$$ ׽Ʈ ִ! + TMobTable *tempTable = it_map_mobTable->second; + + mob_table->dwVnum = tempTable->dwVnum; + strncpy(mob_table->szName, tempTable->szName, CHARACTER_NAME_MAX_LEN); + strncpy(mob_table->szLocaleName, tempTable->szLocaleName, CHARACTER_NAME_MAX_LEN); + mob_table->bRank = tempTable->bRank; + mob_table->bType = tempTable->bType; + mob_table->bBattleType = tempTable->bBattleType; + mob_table->bLevel = tempTable->bLevel; + mob_table->bSize = tempTable->bSize; + mob_table->dwAIFlag = tempTable->dwAIFlag; + mob_table->dwRaceFlag = tempTable->dwRaceFlag; + mob_table->dwImmuneFlag = tempTable->dwImmuneFlag; + mob_table->bEmpire = tempTable->bEmpire; + strncpy(mob_table->szFolder, tempTable->szFolder, CHARACTER_NAME_MAX_LEN); + mob_table->bOnClickType = tempTable->bOnClickType; + mob_table->bStr = tempTable->bStr; + mob_table->bDex = tempTable->bDex; + mob_table->bCon = tempTable->bCon; + mob_table->bInt = tempTable->bInt; + mob_table->dwDamageRange[0] = tempTable->dwDamageRange[0]; + mob_table->dwDamageRange[1] = tempTable->dwDamageRange[1]; + mob_table->dwMaxHP = tempTable->dwMaxHP; + mob_table->bRegenCycle = tempTable->bRegenCycle; + mob_table->bRegenPercent = tempTable->bRegenPercent; + mob_table->dwExp = tempTable->dwExp; + mob_table->wDef = tempTable->wDef; + mob_table->sAttackSpeed = tempTable->sAttackSpeed; + mob_table->sMovingSpeed = tempTable->sMovingSpeed; + mob_table->bAggresiveHPPct = tempTable->bAggresiveHPPct; + mob_table->wAggressiveSight = tempTable->wAggressiveSight; + mob_table->wAttackRange = tempTable->wAttackRange; + mob_table->dwDropItemVnum = tempTable->dwDropItemVnum; + for (int i = 0; i < MOB_ENCHANTS_MAX_NUM; ++i) + mob_table->cEnchants[i] = tempTable->cEnchants[i]; + for (int i = 0; i < MOB_RESISTS_MAX_NUM; ++i) + mob_table->cResists[i] = tempTable->cResists[i]; + mob_table->fDamMultiply = tempTable->fDamMultiply; + mob_table->dwSummonVnum = tempTable->dwSummonVnum; + mob_table->dwDrainSP = tempTable->dwDrainSP; + mob_table->dwMobColor = tempTable->dwMobColor; + + } + + fprintf(stdout, "MOB #%-5d %-16s %-16s sight: %u color %u[%s]\n", mob_table->dwVnum, mob_table->szName, mob_table->szLocaleName, mob_table->wAggressiveSight, mob_table->dwMobColor, 0); + + //¿ vnum ߰ + vnumSet.insert(mob_table->dwVnum); + + ++mob_table; + } + + + + //============================// + //===== ׽Ʈ ߰ =====// + //%%%% + //%% -> ο ߰ // + //ߺǴ ߰ // + //============================// + test_data.Destroy(); + if(!test_data.Load("mob_proto_test.txt",'\t')) + { + fprintf(stderr, "mob_proto_test.txt о ߽ϴ\n"); + //return false; + } else { + test_data.Next(); // ο Ѿ. + + while (test_data.Next()) //׽Ʈ Ⱦ,ο ߰Ѵ. + { + //ߺǴ κ̸ Ѿ. + set::iterator itVnum; + itVnum=vnumSet.find(atoi(test_data.AsStringByIndex(0))); + if (itVnum != vnumSet.end()) { + continue; + } + + + if (!Set_Proto_Mob_Table(mob_table, test_data, localMap)) + { + fprintf(stderr, " ̺ .\n"); + } + + fprintf(stdout, "[New]MOB #%-5d %-16s sight: %u color %u[%s]\n", mob_table->dwVnum, mob_table->szLocaleName, mob_table->wAggressiveSight, mob_table->dwMobColor, test_data.AsStringByIndex(54)); + + //¿ vnum ߰ + vnumSet.insert(mob_table->dwVnum); + + ++mob_table; + } + } + //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// + + + + return true; +} + + + + +DWORD g_adwMobProtoKey[4] = +{ + 4813894, + 18955, + 552631, + 6822045 +}; + + +void SaveMobProto() +{ + FILE * fp; + + fp = fopen("mob_proto", "wb"); + + if (!fp) + { + printf("cannot open %s for writing\n", "mob_proto"); + return; + } + + DWORD fourcc = MAKEFOURCC('M', 'M', 'P', 'T'); + fwrite(&fourcc, sizeof(DWORD), 1, fp); + + DWORD dwElements = m_iMobTableSize; + fwrite(&dwElements, sizeof(DWORD), 1, fp); + + CLZObject zObj; + + printf("sizeof(TMobTable) %d\n", sizeof(TMobTable)); + + if (!CLZO::instance().CompressEncryptedMemory(zObj, m_pMobTable, sizeof(TMobTable) * m_iMobTableSize, g_adwMobProtoKey)) + { + printf("cannot compress\n"); + fclose(fp); + return; + } + + const CLZObject::THeader & r = zObj.GetHeader(); + + printf("MobProto count %u\n%u --Compress--> %u --Encrypt--> %u, GetSize %u\n", + m_iMobTableSize, r.dwRealSize, r.dwCompressedSize, r.dwEncryptSize, zObj.GetSize()); + + DWORD dwDataSize = zObj.GetSize(); + fwrite(&dwDataSize, sizeof(DWORD), 1, fp); + fwrite(zObj.GetBuffer(), dwDataSize, 1, fp); + + fclose(fp); +} + +void LoadMobProto() +{ + FILE * fp; + DWORD fourcc, tableSize, dataSize; + + fp = fopen("mob_proto", "rb"); + + fread(&fourcc, sizeof(DWORD), 1, fp); + fread(&tableSize, sizeof(DWORD), 1, fp); + fread(&dataSize, sizeof(DWORD), 1, fp); + BYTE * data = (BYTE *) malloc(dataSize); + + if (data) + { + fread(data, dataSize, 1, fp); + + CLZObject zObj; + + if (CLZO::instance().Decompress(zObj, data, g_adwMobProtoKey)) + { + printf("real_size %u\n", zObj.GetSize()); + + for (DWORD i = 0; i < tableSize; ++i) + { + TMobTable & rTable = *((TMobTable *) zObj.GetBuffer() + i); + printf("%u %s\n", rTable.dwVnum, rTable.szName); + } + } + + free(data); + } + + fclose(fp); +} + + + + +//== ==// +//== ==// +//== ==// +//===== ⿡ =====// +//== ==// +//== ==// +//== ==// + +bool Set_Proto_Item_Table(TClientItemTable *itemTable, cCsvTable &csvTable, std::map &nameMap) +{ + // vnum vnum range б. + { + std::string s(csvTable.AsStringByIndex(0)); + int pos = s.find("~"); + // vnum ʵ忡 '~' ٸ н + if (std::string::npos == pos) + { + itemTable->dwVnum = atoi(s.c_str()); + if (0 == itemTable->dwVnum) + { + printf ("INVALID VNUM %s\n", s.c_str()); + return false; + } + itemTable->dwVnumRange = 0; + } + else + { + std::string s_start_vnum (s.substr(0, pos)); + std::string s_end_vnum (s.substr(pos +1 )); + + int start_vnum = atoi(s_start_vnum.c_str()); + int end_vnum = atoi(s_end_vnum.c_str()); + if (0 == start_vnum || (0 != end_vnum && end_vnum < start_vnum)) + { + printf ("INVALID VNUM RANGE%s\n", s.c_str()); + return false; + } + itemTable->dwVnum = start_vnum; + itemTable->dwVnumRange = end_vnum - start_vnum; + } + } + + int col = 1; + + strncpy(itemTable->szName, csvTable.AsStringByIndex(col++), ITEM_NAME_MAX_LEN); + // ϸ о. + map::iterator it; + it = nameMap.find(itemTable->dwVnum); + if (it != nameMap.end()) { + const char * localeName = it->second; + strncpy(itemTable->szLocaleName, localeName, sizeof(itemTable->szLocaleName)); + } else { // ѱ۷.. + strncpy(itemTable->szLocaleName, itemTable->szName, sizeof(itemTable->szLocaleName)); + } + itemTable->bType = get_Item_Type_Value(csvTable.AsStringByIndex(col++)); + itemTable->bSubType = get_Item_SubType_Value(itemTable->bType, csvTable.AsStringByIndex(col++)); + itemTable->bSize = atoi(csvTable.AsStringByIndex(col++)); + itemTable->dwAntiFlags = get_Item_AntiFlag_Value(csvTable.AsStringByIndex(col++)); + itemTable->dwFlags = get_Item_Flag_Value(csvTable.AsStringByIndex(col++)); + itemTable->dwWearFlags = get_Item_WearFlag_Value(csvTable.AsStringByIndex(col++)); + itemTable->dwImmuneFlag = get_Item_Immune_Value(csvTable.AsStringByIndex(col++)); + itemTable->dwGold = atoi(csvTable.AsStringByIndex(col++)); + itemTable->dwShopBuyPrice = atoi(csvTable.AsStringByIndex(col++)); + itemTable->dwRefinedVnum = atoi(csvTable.AsStringByIndex(col++)); + itemTable->wRefineSet = atoi(csvTable.AsStringByIndex(col++)); + itemTable->bAlterToMagicItemPct = atoi(csvTable.AsStringByIndex(col++)); + + int i; + + for (i = 0; i < ITEM_LIMIT_MAX_NUM; ++i) + { + itemTable->aLimits[i].bType = get_Item_LimitType_Value(csvTable.AsStringByIndex(col++)); + itemTable->aLimits[i].lValue = atoi(csvTable.AsStringByIndex(col++)); + } + + for (i = 0; i < ITEM_APPLY_MAX_NUM; ++i) + { + itemTable->aApplies[i].bType = get_Item_ApplyType_Value(csvTable.AsStringByIndex(col++)); + itemTable->aApplies[i].lValue = atoi(csvTable.AsStringByIndex(col++)); + } + + for (i = 0; i < ITEM_VALUES_MAX_NUM; ++i) + itemTable->alValues[i] = atoi(csvTable.AsStringByIndex(col++)); + + itemTable->bSpecular = atoi(csvTable.AsStringByIndex(col++)); + itemTable->bGainSocketPct = atoi(csvTable.AsStringByIndex(col++)); + col++; //AddonType + + itemTable->bWeight = 0; + + return true; +} + +bool BuildItemTable() +{ + //%%% <Լ > %%%// + //1. : 'item_proto.txt', 'item_proto_test.txt', 'item_names.txt' а, + // m_pItemTable Ѵ. + //2. + // 1)'item_names.txt' о vnum:name . + // 2)'item_proto_test.txt' о, + // test_item_table , + // vnum:TClientItemTable . + // 3)'item_proto.txt' а, m_pItemTable Ѵ. + // test_item_table ִ vnum ׽Ʈ ͸ ִ´. + // 4)test_item_table ߿, m_pItemTable ͸ ߰Ѵ. + //3. ׽Ʈ + // 1)'item_proto.txt' m_pItemTable . + // 2)'item_names.txt' m_pItemTable . + // 3)'item_proto_test.txt' [ġ] m_pItemTable . + // 4)'item_proto_test.txt' [ο] m_pItemTable . + //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// + + fprintf(stderr, "sizeof(TClientItemTable): %u\n", sizeof(TClientItemTable)); + + //=================================================================// + // 1)'item_names.txt' о vnum:name . + //=================================================================// + bool isNameFile = true; + map localMap; + cCsvTable nameData; + if(!nameData.Load("item_names.txt",'\t')) + { + fprintf(stderr, "item_names.txt о ߽ϴ\n"); + isNameFile = false; + } else { + nameData.Next(); + while(nameData.Next()) { + localMap[atoi(nameData.AsStringByIndex(0))] = nameData.AsStringByIndex(1); + } + } + //_________________________________________________________________// + + //===================== =======================// + // 2)'item_proto_test.txt' о, + // test_item_table , + // vnum:TClientItemTable . + //=============================================// + map test_map_itemTableByVnum; + + //1. о. + cCsvTable test_data; + if(!test_data.Load("item_proto_test.txt",'\t')) + { + fprintf(stderr, "item_proto_test.txt о ߽ϴ\n"); + //return false; + } else { + test_data.Next(); // ο Ѿ. + + //2. ׽Ʈ ̺ . + TClientItemTable * test_item_table = NULL; + int test_itemTableSize = test_data.m_File.GetRowCount()-1; + test_item_table = new TClientItemTable[test_itemTableSize]; + memset(test_item_table, 0, sizeof(TClientItemTable) * test_itemTableSize); + + //3. ׽Ʈ ̺ ְ, ʿ ֱ. + while(test_data.Next()) { + + if (!Set_Proto_Item_Table(test_item_table, test_data, localMap)) + { + fprintf(stderr, " ̺ .\n"); + } + + + test_map_itemTableByVnum.insert(std::map::value_type(test_item_table->dwVnum, test_item_table)); + ++test_item_table; + } + } + + //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// + + + //================================================================// + // 3)'item_proto.txt' а, m_pItemTable Ѵ. + // test_item_table ִ vnum ׽Ʈ ͸ ִ´. + //================================================================// + + //vnum . ο ׽Ʈ ǺҶ ȴ. + set vnumSet; + + // о. + cCsvTable data; + if(!data.Load("item_proto.txt",'\t')) + { + fprintf(stderr, "item_proto.txt о ߽ϴ\n"); + return false; + } + data.Next(); // ( Į ϴ κ) + + if (m_pItemTable) + { + free(m_pItemTable); + m_pItemTable = NULL; + } + + //===== ̺ =====// + // ߰Ǵ ľѴ. + int addNumber = 0; + while(data.Next()) { + int vnum = atoi(data.AsStringByIndex(0)); + std::map::iterator it_map_itemTable; + it_map_itemTable = test_map_itemTableByVnum.find(vnum); + if(it_map_itemTable != test_map_itemTableByVnum.end()) { + addNumber++; + } + } + //data ٽ ùٷ ű.(ٽ о´;;) + data.Destroy(); + if(!data.Load("item_proto.txt",'\t')) + { + fprintf(stderr, "item_proto.txt о ߽ϴ\n"); + return false; + } + data.Next(); // ( Į ϴ κ) + + m_iItemTableSize = data.m_File.GetRowCount()-1+addNumber; + m_pItemTable = new TClientItemTable[m_iItemTableSize]; + memset(m_pItemTable, 0, sizeof(TClientItemTable) * m_iItemTableSize); + + TClientItemTable * item_table = m_pItemTable; + + while (data.Next()) + { + int col = 0; + + //׽Ʈ Ͽ vnum ִ . + std::map::iterator it_map_itemTable; + it_map_itemTable = test_map_itemTableByVnum.find(atoi(data.AsStringByIndex(col))); + if(it_map_itemTable == test_map_itemTableByVnum.end()) { + + + if (!Set_Proto_Item_Table(item_table, data, localMap)) + { + fprintf(stderr, " ̺ .\n"); + } + } else { //$$$$$$$$$$$$$$$$$$$$$$$ ׽Ʈ ִ! + TClientItemTable *tempTable = it_map_itemTable->second; + + item_table->dwVnum = tempTable->dwVnum; + strncpy(item_table->szName, tempTable->szName, ITEM_NAME_MAX_LEN); + strncpy(item_table->szLocaleName, tempTable->szLocaleName, ITEM_NAME_MAX_LEN); + item_table->bType = tempTable->bType; + item_table->bSubType = tempTable->bSubType; + item_table->bSize = tempTable->bSize; + item_table->dwAntiFlags = tempTable->dwAntiFlags; + item_table->dwFlags = tempTable->dwFlags; + item_table->dwWearFlags = tempTable->dwWearFlags; + item_table->dwImmuneFlag = tempTable->dwImmuneFlag; + item_table->dwGold = tempTable->dwGold; + item_table->dwShopBuyPrice = tempTable->dwShopBuyPrice; + item_table->dwRefinedVnum = tempTable->dwRefinedVnum; + item_table->wRefineSet = tempTable->wRefineSet; + item_table->bAlterToMagicItemPct = tempTable->bAlterToMagicItemPct; + + int i; + for (i = 0; i < ITEM_LIMIT_MAX_NUM; ++i) + { + item_table->aLimits[i].bType = tempTable->aLimits[i].bType; + item_table->aLimits[i].lValue = tempTable->aLimits[i].lValue; + } + + for (i = 0; i < ITEM_APPLY_MAX_NUM; ++i) + { + item_table->aApplies[i].bType = tempTable->aApplies[i].bType; + item_table->aApplies[i].lValue = tempTable->aApplies[i].lValue; + } + + for (i = 0; i < ITEM_VALUES_MAX_NUM; ++i) + item_table->alValues[i] = tempTable->alValues[i]; + + item_table->bSpecular = tempTable->bSpecular; + item_table->bGainSocketPct = tempTable->bGainSocketPct; + + item_table->bWeight = tempTable->bWeight; + + } + + + fprintf(stdout, "ITEM #%-5u %-24s %-24s VAL: %ld %ld %ld %ld %ld %ld WEAR %u ANTI %u IMMUNE %u REFINE %u\n", + item_table->dwVnum, + item_table->szName, + item_table->szLocaleName, + item_table->alValues[0], + item_table->alValues[1], + item_table->alValues[2], + item_table->alValues[3], + item_table->alValues[4], + item_table->alValues[5], + item_table->dwWearFlags, + item_table->dwAntiFlags, + item_table->dwImmuneFlag, + item_table->dwRefinedVnum); + + //vnum . + vnumSet.insert(item_table->dwVnum); + ++item_table; + } + + //==========================================================================// + // 4)test_item_table ߿, m_pItemTable ͸ ߰Ѵ. + //==========================================================================// + test_data.Destroy(); + if(!test_data.Load("item_proto_test.txt",'\t')) + { + fprintf(stderr, "item_proto_test.txt о ߽ϴ\n"); + //return false; + } else { + test_data.Next(); // ο Ѿ. + + while (test_data.Next()) //׽Ʈ Ⱦ,ο ߰Ѵ. + { + //ߺǴ κ̸ Ѿ. + set::iterator itVnum; + itVnum=vnumSet.find(atoi(test_data.AsStringByIndex(0))); + if (itVnum != vnumSet.end()) { + continue; + } + + if (!Set_Proto_Item_Table(item_table, test_data, localMap)) + { + fprintf(stderr, " ̺ .\n"); + } + + fprintf(stdout, "[NEW]ITEM #%-5u %-24s %-24s VAL: %ld %ld %ld %ld %ld %ld WEAR %u ANTI %u IMMUNE %u REFINE %u\n", + item_table->dwVnum, + item_table->szName, + item_table->szLocaleName, + item_table->alValues[0], + item_table->alValues[1], + item_table->alValues[2], + item_table->alValues[3], + item_table->alValues[4], + item_table->alValues[5], + item_table->dwWearFlags, + item_table->dwAntiFlags, + item_table->dwImmuneFlag, + item_table->dwRefinedVnum); + + + //¿ vnum ߰ + vnumSet.insert(item_table->dwVnum); + + ++item_table; + + } + } + + return true; +} + +DWORD g_adwItemProtoKey[4] = +{ + 173217, + 72619434, + 408587239, + 27973291 +}; + +void SaveItemProto() +{ + FILE * fp; + + fp = fopen("item_proto", "wb"); + + if (!fp) + { + printf("cannot open %s for writing\n", "item_proto"); + return; + } + + DWORD fourcc = MAKEFOURCC('M', 'I', 'P', 'X'); + fwrite(&fourcc, sizeof(DWORD), 1, fp); + + DWORD dwVersion = 0x00000001; + fwrite(&dwVersion, sizeof(DWORD), 1, fp); + + DWORD dwStride = sizeof(TClientItemTable); + fwrite(&dwStride, sizeof(DWORD), 1, fp); + + DWORD dwElements = m_iItemTableSize; + fwrite(&dwElements, sizeof(DWORD), 1, fp); + + CLZObject zObj; + std::vector vec_item_table (&m_pItemTable[0], &m_pItemTable[m_iItemTableSize - 1]); + sort (&m_pItemTable[0], &m_pItemTable[0] + m_iItemTableSize); + if (!CLZO::instance().CompressEncryptedMemory(zObj, m_pItemTable, sizeof(TClientItemTable) * m_iItemTableSize, g_adwItemProtoKey)) + { + printf("cannot compress\n"); + fclose(fp); + return; + } + + const CLZObject::THeader & r = zObj.GetHeader(); + + printf("Elements %d\n%u --Compress--> %u --Encrypt--> %u, GetSize %u\n", + m_iItemTableSize, + r.dwRealSize, + r.dwCompressedSize, + r.dwEncryptSize, + zObj.GetSize()); + + DWORD dwDataSize = zObj.GetSize(); + fwrite(&dwDataSize, sizeof(DWORD), 1, fp); + fwrite(zObj.GetBuffer(), dwDataSize, 1, fp); + + fclose(fp); + + fp = fopen("item_proto", "rb"); + + if (!fp) + { + printf("Error!!\n"); + return; + } + + fread(&fourcc, sizeof(DWORD), 1, fp); + fread(&dwElements, sizeof(DWORD), 1, fp); + + printf("Elements Check %u fourcc match %d\n", dwElements, fourcc == MAKEFOURCC('M', 'I', 'P', 'T')); + fclose(fp); +} + + + +int main(int argc, char ** argv) +{ + + + if (BuildMobTable()) + { + SaveMobProto(); + LoadMobProto(); + cout << "BuildMobTable working normal" << endl; + } + + + + if (BuildItemTable()) + { + SaveItemProto(); + cout << "BuildItemTable working normal" << endl; + } + + + + return 0; +} + diff --git a/DumpProto/dump_proto/dump_proto.vcproj b/DumpProto/dump_proto/dump_proto.vcproj new file mode 100644 index 0000000..f62b10a --- /dev/null +++ b/DumpProto/dump_proto/dump_proto.vcproj @@ -0,0 +1,245 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DumpProto/dump_proto/dump_proto.vcproj.vspscc b/DumpProto/dump_proto/dump_proto.vcproj.vspscc new file mode 100644 index 0000000..b6d3289 --- /dev/null +++ b/DumpProto/dump_proto/dump_proto.vcproj.vspscc @@ -0,0 +1,10 @@ +"" +{ +"FILE_VERSION" = "9237" +"ENLISTMENT_CHOICE" = "NEVER" +"PROJECT_FILE_RELATIVE_PATH" = "" +"NUMBER_OF_EXCLUDED_FILES" = "0" +"ORIGINAL_PROJECT_FILE_PATH" = "" +"NUMBER_OF_NESTED_PROJECTS" = "0" +"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER" +} diff --git a/DumpProto/dump_proto/dump_proto.vcxproj b/DumpProto/dump_proto/dump_proto.vcxproj new file mode 100644 index 0000000..3755665 --- /dev/null +++ b/DumpProto/dump_proto/dump_proto.vcxproj @@ -0,0 +1,118 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {DBCC99BC-1D68-4271-AC99-62EBBE37890F} + dump_proto + SAK + SAK + SAK + SAK + Win32Proj + 10.0 + + + + Application + v143 + Unicode + true + + + Application + v143 + Unicode + + + + + + + + + + + + + <_ProjectFileVersion>12.0.21005.1 + + + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + + + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + + + + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + Level3 + EditAndContinue + + + true + Console + MachineX86 + + + + + MaxSpeed + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + Level3 + ProgramDatabase + + + true + Console + true + true + MachineX86 + + + + + {3ae0e6e6-b750-4769-9a6e-0d47012f1b40} + true + true + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DumpProto/dump_proto/dump_proto.vcxproj.filters b/DumpProto/dump_proto/dump_proto.vcxproj.filters new file mode 100644 index 0000000..22e007e --- /dev/null +++ b/DumpProto/dump_proto/dump_proto.vcxproj.filters @@ -0,0 +1,57 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + {58f4f6d1-dc21-492e-be8d-f11b650959c2} + + + {bf8e0d1b-bcab-4e18-8113-5b4447fd4ce2} + + + + + Resource Files + + + Resource Files + + + Resource Files + + + LZO + + + TEA + + + + + Resource Files + + + Resource Files + + + Resource Files + + + LZO + + + TEA + + + \ No newline at end of file diff --git a/DumpProto/dump_proto/lzo.cpp b/DumpProto/dump_proto/lzo.cpp new file mode 100644 index 0000000..e3cc25d --- /dev/null +++ b/DumpProto/dump_proto/lzo.cpp @@ -0,0 +1,248 @@ +//#include "common.h" +#include +#include +#include +#include "lzo.h" +#include "tea.h" + +CLZO asdfasdfasdfasdf; + +#define MAKEFOURCC(ch0, ch1, ch2, ch3) \ + ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \ + ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 )) + +DWORD CLZObject::ms_dwFourCC = MAKEFOURCC('M', 'C', 'O', 'Z'); + +CLZObject::CLZObject() +{ + Initialize(); +} + +void CLZObject::Initialize() +{ + m_pHeader = NULL; + m_pbBuffer = NULL; + m_dwBufferSize = 0; + m_pbIn = NULL; + m_bCompressed = false; +} + +void CLZObject::Clear() +{ + if (m_pbBuffer) + delete [] m_pbBuffer; + + Initialize(); +} + +CLZObject::~CLZObject() +{ + Clear(); +} + +DWORD CLZObject::GetSize() +{ + assert(m_pHeader); + + if (m_bCompressed) + { + if (m_pHeader->dwEncryptSize) + return sizeof(THeader) + sizeof(DWORD) + m_pHeader->dwEncryptSize; + else + return sizeof(THeader) + sizeof(DWORD) + m_pHeader->dwCompressedSize; + } + else + return m_pHeader->dwRealSize; +} + +void CLZObject::BeginCompress(const void * pvIn, UINT uiInLen) +{ + m_pbIn = (const BYTE *) pvIn; + + // sizeof(SHeader) + + // ȣȭ fourCC 4Ʈ + // ִ ִ 뷮 + + // ȣȭ 8 Ʈ + m_dwBufferSize = sizeof(THeader) + sizeof(DWORD) + (uiInLen + uiInLen / 64 + 16 + 3) + 8; + + m_pbBuffer = new BYTE[m_dwBufferSize]; + memset(m_pbBuffer, 0, m_dwBufferSize); + + m_pHeader = (THeader *) m_pbBuffer; + m_pHeader->dwFourCC = ms_dwFourCC; + m_pHeader->dwEncryptSize = m_pHeader->dwCompressedSize = m_pHeader->dwRealSize = 0; + m_pHeader->dwRealSize = uiInLen; +} + + +bool CLZObject::Compress() +{ + UINT iOutLen; + BYTE * pbBuffer; + + pbBuffer = m_pbBuffer + sizeof(THeader); + *(DWORD *) pbBuffer = ms_dwFourCC; + pbBuffer += sizeof(DWORD); + + int r = lzo1x_1_compress((BYTE *) m_pbIn, m_pHeader->dwRealSize, pbBuffer, &iOutLen, CLZO::instance().GetWorkMemory()); + + if (LZO_E_OK != r) + { + fprintf(stderr, "LZO: lzo1x_compress failed\n"); + return false; + } + + m_pHeader->dwCompressedSize = iOutLen; + m_bCompressed = true; + + return true; +} + +bool CLZObject::BeginDecompress(const void * pvIn) +{ + THeader * pHeader = (THeader *) pvIn; + + if (pHeader->dwFourCC != ms_dwFourCC) + { + fprintf(stderr, "LZObject: not a valid data"); + return false; + } + + m_pHeader = pHeader; + m_pbIn = (const BYTE *) pvIn + (sizeof(THeader) + sizeof(DWORD)); + + m_pbBuffer = new BYTE[pHeader->dwRealSize]; + memset(m_pbBuffer, 0, pHeader->dwRealSize); + return true; +} + +bool CLZObject::Decompress(DWORD * pdwKey) +{ + UINT uiSize; + int r; + + if (m_pHeader->dwEncryptSize) + { + BYTE * pbDecryptedBuffer = Decrypt(pdwKey); + + if (*(DWORD *) pbDecryptedBuffer != ms_dwFourCC) + { + fprintf(stderr, "LZObject: key incorrect"); + return false; + } + + if (LZO_E_OK != (r = lzo1x_decompress(pbDecryptedBuffer + sizeof(DWORD), m_pHeader->dwCompressedSize, m_pbBuffer, &uiSize, NULL))) + { + fprintf(stderr, "LZObject: Decompress failed(decrypt) ret %d\n", r); + return false; + } + + delete [] pbDecryptedBuffer; + } + else + { + uiSize = m_pHeader->dwRealSize; + + if (LZO_E_OK != (r = lzo1x_decompress_safe(m_pbIn, m_pHeader->dwCompressedSize, m_pbBuffer, &uiSize, NULL))) + { + fprintf(stderr, "LZObject: Decompress failed : ret %d, CompressedSize %d\n", r, m_pHeader->dwCompressedSize); + return false; + } + } + + if (uiSize != m_pHeader->dwRealSize) + { + fprintf(stderr, "LZObject: Size differs"); + return false; + } + + return true; +} + +bool CLZObject::Encrypt(DWORD * pdwKey) +{ + if (!m_bCompressed) + { + assert(!"not compressed yet"); + return false; + } + + BYTE * pbBuffer = m_pbBuffer + sizeof(THeader); + m_pHeader->dwEncryptSize = tea_encrypt((DWORD *) pbBuffer, (const DWORD *) pbBuffer, pdwKey, m_pHeader->dwCompressedSize + 19); + return true; +} + +BYTE * CLZObject::Decrypt(DWORD * pdwKey) +{ + assert(m_pbBuffer); + + BYTE * pbDecryptBuffer = new BYTE[m_pHeader->dwEncryptSize]; + + tea_encrypt((DWORD *) pbDecryptBuffer, (const DWORD *) (m_pbIn - sizeof(DWORD)), pdwKey, m_pHeader->dwEncryptSize); + return pbDecryptBuffer; +} + +CLZO::CLZO() : m_pWorkMem(NULL) +{ + if (lzo_init() != LZO_E_OK) + { + fprintf(stderr, "LZO: cannot initialize\n"); + return; + } + + m_pWorkMem = (BYTE *) malloc(LZO1X_MEM_COMPRESS); + + if (NULL == m_pWorkMem) + { + fprintf(stderr, "LZO: cannot alloc memory\n"); + return; + } +} + +CLZO::~CLZO() +{ + if (m_pWorkMem) + { + free(m_pWorkMem); + m_pWorkMem = NULL; + } +} + +bool CLZO::CompressMemory(CLZObject & rObj, const void * pIn, UINT uiInLen) +{ + rObj.BeginCompress(pIn, uiInLen); + return rObj.Compress(); +} + +bool CLZO::CompressEncryptedMemory(CLZObject & rObj, const void * pIn, UINT uiInLen, DWORD * pdwKey) +{ + rObj.BeginCompress(pIn, uiInLen); + + if (rObj.Compress()) + { + if (rObj.Encrypt(pdwKey)) + return true; + + return false; + } + + return false; +} + +bool CLZO::Decompress(CLZObject & rObj, const BYTE * pbBuf, DWORD * pdwKey) +{ + if (!rObj.BeginDecompress(pbBuf)) + return false; + + if (!rObj.Decompress(pdwKey)) + return false; + + return true; +} + + +BYTE * CLZO::GetWorkMemory() +{ + return m_pWorkMem; +} + diff --git a/DumpProto/dump_proto/lzo.h b/DumpProto/dump_proto/lzo.h new file mode 100644 index 0000000..f367acc --- /dev/null +++ b/DumpProto/dump_proto/lzo.h @@ -0,0 +1,72 @@ +#ifndef __INC_METIN_II_371GNFBQOCJ_LZO_H__ +#define __INC_METIN_II_371GNFBQOCJ_LZO_H__ + +#include "../lzo/lzoconf.h" +#include "../lzo/lzo1x.h" +#include "Singleton.h" + +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef unsigned long DWORD; +typedef unsigned int UINT; + +class CLZObject +{ + public: +#pragma pack(4) + typedef struct SHeader + { + DWORD dwFourCC; + DWORD dwEncryptSize; // ȣȭ ũ + DWORD dwCompressedSize; // ũ + DWORD dwRealSize; // ũ + } THeader; +#pragma pack() + + CLZObject(); + ~CLZObject(); + + void Clear(); + + void BeginCompress(const void * pvIn, UINT uiInLen); + bool Compress(); + + bool BeginDecompress(const void * pvIn); + bool Decompress(DWORD * pdwKey = NULL); + + bool Encrypt(DWORD * pdwKey); + BYTE * Decrypt(DWORD * pdwKey); + + const THeader & GetHeader() { return *m_pHeader; } + BYTE * GetBuffer() { return m_pbBuffer; } + DWORD GetSize(); + + private: + void Initialize(); + + BYTE * m_pbBuffer; + DWORD m_dwBufferSize; + + THeader * m_pHeader; + const BYTE * m_pbIn; + bool m_bCompressed; + + static DWORD ms_dwFourCC; +}; + +class CLZO : public singleton +{ + public: + CLZO(); + virtual ~CLZO(); + + bool CompressMemory(CLZObject & rObj, const void * pIn, UINT uiInLen); + bool CompressEncryptedMemory(CLZObject & rObj, const void * pIn, UINT uiInLen, DWORD * pdwKey); + bool Decompress(CLZObject & rObj, const BYTE * pbBuf, DWORD * pdwKey = NULL); + BYTE * GetWorkMemory(); + + private: + BYTE * m_pWorkMem; +}; + +#endif diff --git a/DumpProto/dump_proto/tea.cpp b/DumpProto/dump_proto/tea.cpp new file mode 100644 index 0000000..d8c9899 --- /dev/null +++ b/DumpProto/dump_proto/tea.cpp @@ -0,0 +1,100 @@ +/* +* Filename: tea.c +* Description: TEA ȣȭ +* +* Author: (aka. , Cronan), ۿ (aka. myevan, ڷ) +*/ +#include "tea.h" +#include + +/* +* TEA Encryption Module Instruction +* Edited by aka. , Cronan +* +* void tea_code(const unsigned long sz, const unsigned long sy, const unsigned long *key, unsigned long *dest) +* void tea_decode(const unsigned long sz, const unsigned long sy, const unsigned long *key, unsigned long *dest) +* 8Ʈ ȣ/ȣȭ Ҷ ȴ. key 16 Ʈ Ѵ. +* sz, sy 8Ʈ Ѵ. +* +* int tea_decrypt(unsigned long *dest, const unsigned long *src, const unsigned long *key, int size); +* int tea_encrypt(unsigned long *dest, const unsigned long *src, const unsigned long *key, int size); +* Ѳ 8 Ʈ ̻ ȣ/ȣȭ Ҷ Ѵ. size +* 8 ƴϸ 8 ũ⸦ "÷" ȣȭ Ѵ. +* +* ex. tea_code(pdwSrc[1], pdwSrc[0], pdwKey, pdwDest); +* tea_decrypt(pdwDest, pdwSrc, pdwKey, nSize); +*/ + +#define TEA_ROUND 32 // 32 ϸ, . +#define DELTA 0x9E3779B9 // DELTA ٲ . + +void tea_code(const unsigned long sz, const unsigned long sy, const unsigned long *key, unsigned long *dest) +{ + register unsigned long y = sy, z = sz, sum = 0; + unsigned long n = TEA_ROUND; + + while (n-- > 0) + { + y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); + sum += DELTA; + z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); + } + + *(dest++) = y; + *dest = z; +} + +void tea_decode(const unsigned long sz, const unsigned long sy, const unsigned long *key, unsigned long *dest) +{ +#pragma warning(disable:4307) + register unsigned long y = sy, z = sz, sum = DELTA * TEA_ROUND; +#pragma warning(default:4307) + + unsigned long n = TEA_ROUND; + + while (n-- > 0) + { + z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); + sum -= DELTA; + y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); + } + + *(dest++) = y; + *dest = z; +} + +int tea_encrypt(unsigned long *dest, const unsigned long *src, const unsigned long * key, int size) +{ + int i; + int resize; + + if (size % 8 != 0) + { + resize = size + 8 - (size % 8); + memset((char *) src + size, 0, resize - size); + } + else + resize = size; + + for (i = 0; i < resize >> 3; i++, dest += 2, src += 2) + tea_code(*(src + 1), *src, key, dest); + + return (resize); +} + +int tea_decrypt(unsigned long *dest, const unsigned long *src, const unsigned long * key, int size) +{ + int i; + int resize; + + if (size % 8 != 0) + resize = size + 8 - (size % 8); + else + resize = size; + + for (i = 0; i < resize >> 3; i++, dest += 2, src += 2) + tea_decode(*(src + 1), *src, key, dest); + + return (resize); +} + diff --git a/DumpProto/dump_proto/tea.h b/DumpProto/dump_proto/tea.h new file mode 100644 index 0000000..3555bc2 --- /dev/null +++ b/DumpProto/dump_proto/tea.h @@ -0,0 +1,17 @@ +#ifdef __cplusplus +extern "C" { +#endif + + /* TEA is a 64-bit symmetric block cipher with a 128-bit key, developed + by David J. Wheeler and Roger M. Needham, and described in their + paper at . + + This implementation is based on their code in + */ + + int tea_encrypt(unsigned long *dest, const unsigned long *src, const unsigned long *key, int size); + int tea_decrypt(unsigned long *dest, const unsigned long *src, const unsigned long *key, int size); + +#ifdef __cplusplus +}; +#endif diff --git a/DumpProto/lzo/alloc.c b/DumpProto/lzo/alloc.c new file mode 100644 index 0000000..bb25b4b --- /dev/null +++ b/DumpProto/lzo/alloc.c @@ -0,0 +1,151 @@ +/* alloc.c -- memory allocation + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + +#include "stdafx.h" +#include "lzo_conf.h" +#include + +#if defined(HAVE_MALLOC_H) +# include +#endif +#if defined(__palmos__) +# include +#endif + + +#undef lzo_alloc_hook +#undef lzo_free_hook +#undef lzo_alloc +#undef lzo_malloc +#undef lzo_free + + +/*********************************************************************** +// implementation +************************************************************************/ + +LZO_PRIVATE(lzo_voidp) +lzo_alloc_internal(lzo_uint nelems, lzo_uint size) +{ + lzo_voidp p = NULL; + unsigned long s = (unsigned long) nelems * size; + + if (nelems <= 0 || size <= 0 || s < nelems || s < size) + return NULL; + +#if defined(__palmos__) + p = (lzo_voidp) MemPtrNew(s); +#elif (LZO_UINT_MAX <= SIZE_T_MAX) + if (s < SIZE_T_MAX) + p = (lzo_voidp) malloc((size_t)s); +#elif defined(HAVE_HALLOC) && defined(__DMC__) + if (size < SIZE_T_MAX) + p = (lzo_voidp) _halloc(nelems,(size_t)size); +#elif defined(HAVE_HALLOC) + if (size < SIZE_T_MAX) + p = (lzo_voidp) halloc(nelems,(size_t)size); +#else + if (s < SIZE_T_MAX) + p = (lzo_voidp) malloc((size_t)s); +#endif + + return p; +} + + +LZO_PRIVATE(void) +lzo_free_internal(lzo_voidp p) +{ + if (!p) + return; + +#if defined(__palmos__) + MemPtrFree(p); +#elif (LZO_UINT_MAX <= SIZE_T_MAX) + free(p); +#elif defined(HAVE_HALLOC) && defined(__DMC__) + _hfree(p); +#elif defined(HAVE_HALLOC) + hfree(p); +#else + free(p); +#endif +} + + +/*********************************************************************** +// public interface using the global hooks +************************************************************************/ + +/* global allocator hooks */ +LZO_PUBLIC_VAR(lzo_alloc_hook_t) lzo_alloc_hook = lzo_alloc_internal; +LZO_PUBLIC_VAR(lzo_free_hook_t) lzo_free_hook = lzo_free_internal; + + +LZO_PUBLIC(lzo_voidp) +lzo_alloc(lzo_uint nelems, lzo_uint size) +{ + if (!lzo_alloc_hook) + return NULL; + + return lzo_alloc_hook(nelems,size); +} + + +LZO_PUBLIC(lzo_voidp) +lzo_malloc(lzo_uint size) +{ + if (!lzo_alloc_hook) + return NULL; + +#if defined(__palmos__) + return lzo_alloc_hook(size,1); +#elif (LZO_UINT_MAX <= SIZE_T_MAX) + return lzo_alloc_hook(size,1); +#elif defined(HAVE_HALLOC) + /* use segment granularity by default */ + if (size + 15 > size) /* avoid overflow */ + return lzo_alloc_hook((size+15)/16,16); + return lzo_alloc_hook(size,1); +#else + return lzo_alloc_hook(size,1); +#endif +} + + +LZO_PUBLIC(void) +lzo_free(lzo_voidp p) +{ + if (!lzo_free_hook) + return; + + lzo_free_hook(p); +} + + +/* +vi:ts=4:et +*/ diff --git a/DumpProto/lzo/compr1b.h b/DumpProto/lzo/compr1b.h new file mode 100644 index 0000000..bde412a --- /dev/null +++ b/DumpProto/lzo/compr1b.h @@ -0,0 +1,47 @@ + +#define LZO_NEED_DICT_H +#include "config1b.h" + + +#if !defined(COMPRESS_ID) +#define COMPRESS_ID _LZO_ECONCAT2(DD_BITS,CLEVEL) +#endif + + +#include "lzo1b_c.ch" + + +/*********************************************************************** +// +************************************************************************/ + +#define LZO_COMPRESS \ + _LZO_ECONCAT3(lzo1b_,COMPRESS_ID,_compress) + +#define LZO_COMPRESS_FUNC \ + _LZO_ECONCAT3(_lzo1b_,COMPRESS_ID,_compress_func) + + + +/*********************************************************************** +// +************************************************************************/ + +const lzo_compress_t LZO_COMPRESS_FUNC = do_compress; + +LZO_PUBLIC(int) +LZO_COMPRESS ( const lzo_byte *in, lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ +#if defined(__LZO_QUERY_COMPRESS) + if (__LZO_IS_COMPRESS_QUERY(in,in_len,out,out_len,wrkmem)) + return __LZO_QUERY_COMPRESS(in,in_len,out,out_len,wrkmem,D_SIZE,lzo_sizeof(lzo_dict_t)); +#endif + + return _lzo1b_do_compress(in,in_len,out,out_len,wrkmem,do_compress); +} + +/* +vi:ts=4:et +*/ diff --git a/DumpProto/lzo/compr1c.h b/DumpProto/lzo/compr1c.h new file mode 100644 index 0000000..83ba84b --- /dev/null +++ b/DumpProto/lzo/compr1c.h @@ -0,0 +1,47 @@ + +#define LZO_NEED_DICT_H +#include "config1c.h" + + +#if !defined(COMPRESS_ID) +#define COMPRESS_ID _LZO_ECONCAT2(DD_BITS,CLEVEL) +#endif + + +#include "lzo1b_c.ch" + + +/*********************************************************************** +// +************************************************************************/ + +#define LZO_COMPRESS \ + _LZO_ECONCAT3(lzo1c_,COMPRESS_ID,_compress) + +#define LZO_COMPRESS_FUNC \ + _LZO_ECONCAT3(_lzo1c_,COMPRESS_ID,_compress_func) + + + +/*********************************************************************** +// +************************************************************************/ + +const lzo_compress_t LZO_COMPRESS_FUNC = do_compress; + +LZO_PUBLIC(int) +LZO_COMPRESS ( const lzo_byte *in, lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ +#if defined(__LZO_QUERY_COMPRESS) + if (__LZO_IS_COMPRESS_QUERY(in,in_len,out,out_len,wrkmem)) + return __LZO_QUERY_COMPRESS(in,in_len,out,out_len,wrkmem,D_SIZE,lzo_sizeof(lzo_dict_t)); +#endif + + return _lzo1c_do_compress(in,in_len,out,out_len,wrkmem,do_compress); +} + +/* +vi:ts=4:et +*/ diff --git a/DumpProto/lzo/config1.h b/DumpProto/lzo/config1.h new file mode 100644 index 0000000..6cde6ad --- /dev/null +++ b/DumpProto/lzo/config1.h @@ -0,0 +1,43 @@ +/* config1.h -- configuration for the LZO1 algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the library and is subject + to change. + */ + + +#include + +#define LZO_NO_R1 +#include "config1a.h" + + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/config1a.h b/DumpProto/lzo/config1a.h new file mode 100644 index 0000000..4c8e066 --- /dev/null +++ b/DumpProto/lzo/config1a.h @@ -0,0 +1,187 @@ +/* config1a.h -- configuration for the LZO1A algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the library and is subject + to change. + */ + + +#ifndef __LZO_CONFIG1A_H +#define __LZO_CONFIG1A_H + +#include +#include "lzo_conf.h" + +#undef LZO_COLLECT_STATS /* no support for stats here */ + + +/*********************************************************************** +// algorithm configuration +************************************************************************/ + +/* run bits (4 - 5) - the compressor and the decompressor + * must use the same value. */ +#if !defined(RBITS) +# define RBITS 5 +#endif + +/* dictionary depth (0 - 6) - this only affects the compressor. + * 0 is fastest, 6 is best compression ratio */ +#if !defined(DDBITS) +# define DDBITS 0 +#endif + +/* compression level (1 - 9) - this only affects the compressor. + * 1 is fastest, 9 is best compression ratio */ +#if !defined(CLEVEL) +# define CLEVEL 1 /* fastest by default */ +#endif + + +/* check configuration */ +#if (RBITS < 4 || RBITS > 5) +# error "invalid RBITS" +#endif +#if (DDBITS < 0 || DDBITS > 6) +# error "invalid DDBITS" +#endif +#if (CLEVEL < 1 || CLEVEL > 9) +# error "invalid CLEVEL" +#endif + + +/*********************************************************************** +// internal configuration +************************************************************************/ + +/* add a special code so that the decompressor can detect the + * end of the compressed data block (overhead is 3 bytes per block) */ +#undef LZO_EOF_CODE + +/* return -1 instead of copying if the data cannot be compressed */ +#undef LZO_RETURN_IF_NOT_COMPRESSIBLE + + +/*********************************************************************** +// algorithm internal configuration +************************************************************************/ + +/* choose the hashing strategy */ +#ifndef LZO_HASH +#define LZO_HASH LZO_HASH_LZO_INCREMENTAL_A +#endif + +/* config */ +#define R_BITS RBITS +#define DD_BITS DDBITS +#ifndef D_BITS +#define D_BITS 16 +#endif + + +/*********************************************************************** +// optimization and debugging +************************************************************************/ + +/* Collect statistics */ +#if 0 && !defined(LZO_COLLECT_STATS) +# define LZO_COLLECT_STATS +#endif + + +/*********************************************************************** +// +************************************************************************/ + +#define M3O_BITS M2O_BITS +#define M3L_BITS CHAR_BIT +#define M3_MAX_LEN (M3_MIN_LEN + LZO_SIZE(M3L_BITS) - 1) +#define _MAX_OFFSET _M2_MAX_OFFSET +#define LZO_NO_M3 + +#include "lzo_util.h" +#include "lzo1b_de.h" +#include "stats1b.h" + +#include "lzo1b_cc.h" + + +/*********************************************************************** +// check for total LZO1/LZO1A compatibility +************************************************************************/ + +#undef M2_MARKER +#define M2_MARKER (1 << M2O_BITS) + +#if (R_BITS != 5) +# error +#endif +#if (M2O_BITS != 5) +# error +#endif +#if (M3O_BITS != 5) +# error +#endif +#if (M2_MIN_LEN != 3) +# error +#endif +#if (M2_MAX_LEN != 8) +# error +#endif +#if (M3_MIN_LEN != 9) +# error +#endif +#if (M3_MAX_LEN != 264) +# error +#endif +#if (_M2_MAX_OFFSET != (1u << 13)) +# error +#endif +#if (_M2_MAX_OFFSET != _M3_MAX_OFFSET) +# error +#endif +#if (_M2_MAX_OFFSET != _MAX_OFFSET) +# error +#endif +#if (R0MIN != 32) +# error +#endif +#if (R0MAX != 287) +# error +#endif +#if (R0FAST != 280) +# error +#endif + + +#endif /* already included */ + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/config1b.h b/DumpProto/lzo/config1b.h new file mode 100644 index 0000000..7f380c4 --- /dev/null +++ b/DumpProto/lzo/config1b.h @@ -0,0 +1,132 @@ +/* config1b.h -- configuration for the LZO1B algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the library and is subject + to change. + */ + + +#ifndef __LZO_CONFIG1B_H +#define __LZO_CONFIG1B_H + +#include +#include "lzo_conf.h" + + +/*********************************************************************** +// algorithm configuration +************************************************************************/ + +/* run bits (4 - 5) - the compressor and the decompressor + * must use the same value. */ +#if !defined(RBITS) +# define RBITS 5 +#endif + +/* dictionary depth (0 - 6) - this only affects the compressor. + * 0 is fastest, 6 is best compression ratio */ +#if !defined(DDBITS) +# define DDBITS 0 +#endif + +/* compression level (1 - 9) - this only affects the compressor. + * 1 is fastest, 9 is best compression ratio */ +#if !defined(CLEVEL) +# define CLEVEL 1 /* fastest by default */ +#endif + + +/* check configuration */ +#if (RBITS < 4 || RBITS > 5) +# error "invalid RBITS" +#endif +#if (DDBITS < 0 || DDBITS > 6) +# error "invalid DDBITS" +#endif +#if (CLEVEL < 1 || CLEVEL > 9) +# error "invalid CLEVEL" +#endif + + +/*********************************************************************** +// internal configuration +************************************************************************/ + +/* add a special code so that the decompressor can detect the + * end of the compressed data block (overhead is 3 bytes per block) */ +#undef LZO_EOF_CODE +#define LZO_EOF_CODE + +/* return -1 instead of copying if the data cannot be compressed */ +#undef LZO_RETURN_IF_NOT_COMPRESSIBLE + + +/*********************************************************************** +// algorithm internal configuration +************************************************************************/ + +/* choose the hashing strategy */ +#ifndef LZO_HASH +#define LZO_HASH LZO_HASH_LZO_INCREMENTAL_A +#endif + +/* config */ +#define R_BITS RBITS +#define DD_BITS DDBITS +#ifndef D_BITS +#define D_BITS 14 +#endif + + +/*********************************************************************** +// optimization and debugging +************************************************************************/ + +/* Collect statistics */ +#if 0 && !defined(LZO_COLLECT_STATS) +# define LZO_COLLECT_STATS +#endif + + +/*********************************************************************** +// +************************************************************************/ + +#include "lzo_util.h" +#include "lzo1b_de.h" +#include "stats1b.h" + +#include "lzo1b_cc.h" + + +#endif /* already included */ + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/config1c.h b/DumpProto/lzo/config1c.h new file mode 100644 index 0000000..f3a4795 --- /dev/null +++ b/DumpProto/lzo/config1c.h @@ -0,0 +1,137 @@ +/* config1c.h -- configuration for the LZO1C algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the library and is subject + to change. + */ + + +#ifndef __LZO_CONFIG1C_H +#define __LZO_CONFIG1C_H + +#include +#include "lzo_conf.h" + + +/*********************************************************************** +// algorithm configuration +************************************************************************/ + +/* run bits (4 - 5) - the compressor and the decompressor + * must use the same value. */ +#if !defined(RBITS) +# define RBITS 5 +#endif + +/* dictionary depth (0 - 6) - this only affects the compressor. + * 0 is fastest, 6 is best compression ratio */ +#if !defined(DDBITS) +# define DDBITS 0 +#endif + +/* compression level (1 - 9) - this only affects the compressor. + * 1 is fastest, 9 is best compression ratio */ +#if !defined(CLEVEL) +# define CLEVEL 1 /* fastest by default */ +#endif + + +/* check configuration */ +#if (RBITS < 4 || RBITS > 5) +# error "invalid RBITS" +#endif +#if (DDBITS < 0 || DDBITS > 6) +# error "invalid DDBITS" +#endif +#if (CLEVEL < 1 || CLEVEL > 9) +# error "invalid CLEVEL" +#endif + + +/*********************************************************************** +// internal configuration +************************************************************************/ + +/* add a special code so that the decompressor can detect the + * end of the compressed data block (overhead is 3 bytes per block) */ +#undef LZO_EOF_CODE +#define LZO_EOF_CODE + +/* return -1 instead of copying if the data cannot be compressed */ +#undef LZO_RETURN_IF_NOT_COMPRESSIBLE + + +/*********************************************************************** +// algorithm internal configuration +************************************************************************/ + +/* choose the hashing strategy */ +#ifndef LZO_HASH +#define LZO_HASH LZO_HASH_LZO_INCREMENTAL_A +#endif + +/* config */ +#define R_BITS RBITS +#define DD_BITS DDBITS +#ifndef D_BITS +#define D_BITS 14 +#endif + + +/*********************************************************************** +// optimization and debugging +************************************************************************/ + +/* Collect statistics */ +#if 0 && !defined(LZO_COLLECT_STATS) +# define LZO_COLLECT_STATS +#endif + + +/*********************************************************************** +// +************************************************************************/ + +/* good parameters when using a blocksize of 8kB */ +#define M3O_BITS 6 +#undef LZO_DETERMINISTIC + + +#include "lzo_util.h" +#include "lzo1b_de.h" +#include "stats1c.h" + +#include "lzo1c_cc.h" + + +#endif /* already included */ + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/config1f.h b/DumpProto/lzo/config1f.h new file mode 100644 index 0000000..8a4d914 --- /dev/null +++ b/DumpProto/lzo/config1f.h @@ -0,0 +1,85 @@ +/* config1f.h -- configuration for the LZO1F algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the library and is subject + to change. + */ + + +#ifndef __LZO_CONFIG1F_H +#define __LZO_CONFIG1F_H + +#include +#include "lzo_conf.h" +#include "lzo_util.h" + + +/*********************************************************************** +// +************************************************************************/ + +#define LZO_EOF_CODE +#undef LZO_DETERMINISTIC + +#define M2_MAX_OFFSET 0x0800 +#define M3_MAX_OFFSET 0x3fff + +#define M2_MIN_LEN 3 +#define M2_MAX_LEN 8 +#define M3_MIN_LEN 3 +#define M3_MAX_LEN 33 + +#define M3_MARKER 224 + + +/*********************************************************************** +// +************************************************************************/ + +#ifndef MIN_LOOKAHEAD +#define MIN_LOOKAHEAD (M2_MAX_LEN + 1) +#endif + +#if defined(LZO_NEED_DICT_H) + +#ifndef LZO_HASH +#define LZO_HASH LZO_HASH_LZO_INCREMENTAL_A +#endif +#define DL_MIN_LEN M2_MIN_LEN +#include "lzo_dict.h" + +#endif + + + +#endif /* already included */ + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/config1x.h b/DumpProto/lzo/config1x.h new file mode 100644 index 0000000..6168134 --- /dev/null +++ b/DumpProto/lzo/config1x.h @@ -0,0 +1,106 @@ +/* config1x.h -- configuration for the LZO1X algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the library and is subject + to change. + */ + + +#ifndef __LZO_CONFIG1X_H +#define __LZO_CONFIG1X_H + +#if !defined(LZO1X) && !defined(LZO1Y) && !defined(LZO1Z) +# define LZO1X +#endif + +#if !defined(__LZO_IN_MINILZO) +#include +#endif +#include "lzo_conf.h" +#include "lzo_util.h" + + +/*********************************************************************** +// +************************************************************************/ + +#define LZO_EOF_CODE +#undef LZO_DETERMINISTIC + +#define M1_MAX_OFFSET 0x0400 +#ifndef M2_MAX_OFFSET +#define M2_MAX_OFFSET 0x0800 +#endif +#define M3_MAX_OFFSET 0x4000 +#define M4_MAX_OFFSET 0xbfff + +#define MX_MAX_OFFSET (M1_MAX_OFFSET + M2_MAX_OFFSET) + +#define M1_MIN_LEN 2 +#define M1_MAX_LEN 2 +#define M2_MIN_LEN 3 +#ifndef M2_MAX_LEN +#define M2_MAX_LEN 8 +#endif +#define M3_MIN_LEN 3 +#define M3_MAX_LEN 33 +#define M4_MIN_LEN 3 +#define M4_MAX_LEN 9 + +#define M1_MARKER 0 +#define M2_MARKER 64 +#define M3_MARKER 32 +#define M4_MARKER 16 + + +/*********************************************************************** +// +************************************************************************/ + +#ifndef MIN_LOOKAHEAD +#define MIN_LOOKAHEAD (M2_MAX_LEN + 1) +#endif + +#if defined(LZO_NEED_DICT_H) + +#ifndef LZO_HASH +#define LZO_HASH LZO_HASH_LZO_INCREMENTAL_B +#endif +#define DL_MIN_LEN M2_MIN_LEN +#include "lzo_dict.h" + +#endif + + + +#endif /* already included */ + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/config1y.h b/DumpProto/lzo/config1y.h new file mode 100644 index 0000000..18ec13f --- /dev/null +++ b/DumpProto/lzo/config1y.h @@ -0,0 +1,52 @@ +/* config1y.h -- configuration for the LZO1Y algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the library and is subject + to change. + */ + + +#ifndef __LZO_CONFIG1Y_H +#define __LZO_CONFIG1Y_H + +#if !defined(LZO1Y) +# define LZO1Y +#endif + +#include + +#define M2_MAX_LEN 14 +#define M2_MAX_OFFSET 0x0400 +#include "config1x.h" + +#endif /* already included */ + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/config1z.h b/DumpProto/lzo/config1z.h new file mode 100644 index 0000000..63e82de --- /dev/null +++ b/DumpProto/lzo/config1z.h @@ -0,0 +1,51 @@ +/* config1z.h -- configuration for the LZO1Z algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the library and is subject + to change. + */ + + +#ifndef __LZO_CONFIG1Z_H +#define __LZO_CONFIG1Z_H + +#if !defined(LZO1Z) +# define LZO1Z +#endif + +#include + +#define M2_MAX_OFFSET 0x0700 +#include "config1x.h" + +#endif /* already included */ + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/config2a.h b/DumpProto/lzo/config2a.h new file mode 100644 index 0000000..1febf2f --- /dev/null +++ b/DumpProto/lzo/config2a.h @@ -0,0 +1,148 @@ +/* config2a.h -- configuration for the LZO2A algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the library and is subject + to change. + */ + + +#ifndef __LZO_CONFIG2A_H +#define __LZO_CONFIG2A_H + +#include +#include "lzo_conf.h" + +#include "lzo_util.h" + + +/*********************************************************************** +// algorithm configuration +************************************************************************/ + +/* dictionary depth (0 - 6) - this only affects the compressor. + * 0 is fastest, 6 is best compression ratio */ +#if !defined(DDBITS) +# define DDBITS 0 +#endif + +/* compression level (1 - 9) - this only affects the compressor. + * 1 is fastest, 9 is best compression ratio */ +#if !defined(CLEVEL) +# define CLEVEL 1 /* fastest by default */ +#endif + + +/* check configuration */ +#if (DDBITS < 0 || DDBITS > 6) +# error "invalid DDBITS" +#endif +#if (CLEVEL < 1 || CLEVEL > 9) +# error "invalid CLEVEL" +#endif + + +/*********************************************************************** +// internal configuration +************************************************************************/ + +#if 1 +#define N 8191 /* size of ring buffer */ +#else +#define N 16383 /* size of ring buffer */ +#endif + +#define M1_MIN_LEN 2 +#define M1_MAX_LEN 5 +#define M2_MIN_LEN 3 +#define M3_MIN_LEN 3 + + +/* add a special code so that the decompressor can detect the + * end of the compressed data block (overhead is 3 bytes per block) */ +#undef LZO_EOF_CODE +#define LZO_EOF_CODE + +/* return -1 instead of copying if the data cannot be compressed */ +#undef LZO_RETURN_IF_NOT_COMPRESSIBLE + +#undef LZO_DETERMINISTIC + + +/*********************************************************************** +// algorithm internal configuration +************************************************************************/ + +/* choose the hashing strategy */ +#ifndef LZO_HASH +#define LZO_HASH LZO_HASH_LZO_INCREMENTAL_A +#endif + +/* config */ +#define DD_BITS DDBITS +#ifndef D_BITS +#define D_BITS 14 +#endif + + + +/*********************************************************************** +// optimization and debugging +************************************************************************/ + +/* Collect statistics */ +#if 0 && !defined(LZO_COLLECT_STATS) +# define LZO_COLLECT_STATS +#endif + + +/*********************************************************************** +// +************************************************************************/ + +/* get bits */ +#define _NEEDBITS \ + { _NEEDBYTE; b |= ((lzo_uint32) _NEXTBYTE) << k; k += 8; assert(k <= 32); } +#define NEEDBITS(j) { assert((j) < 8); if (k < (j)) _NEEDBITS } + +/* set bits */ +#define SETBITS(j,x) { b |= (x) << k; k += (j); assert(k <= 32); } + +/* access bits */ +#define MASKBITS(j) (b & ((((lzo_uint32)1 << (j)) - 1))) + +/* drop bits */ +#define DUMPBITS(j) { assert(k >= j); b >>= (j); k -= (j); } + + + +#endif /* already included */ + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/fake16.h b/DumpProto/lzo/fake16.h new file mode 100644 index 0000000..e183e20 --- /dev/null +++ b/DumpProto/lzo/fake16.h @@ -0,0 +1,83 @@ +/* fake16.h -- fake the strict 16-bit memory model for test purposes + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* + * NOTE: + * this file is *only* for testing the strict 16-bit memory model + * on a 32-bit machine. Because things like integral promotion, + * size_t and ptrdiff_t cannot be faked this is no real substitute + * for testing under a real 16-bit system. + * + * See also + * + * Usage: #include "src/fake16.h" at the top of + */ + + +#ifndef __LZOFAKE16BIT_H +#define __LZOFAKE16BIT_H + +#ifdef __LZOCONF_H +# error "include this file before lzoconf.h" +#endif + +#include + +#if (USHRT_MAX == 0xffff) + +#ifdef __cplusplus +extern "C" { +#endif + +#define __LZO16BIT_H /* do not use */ + +#define __LZO_STRICT_16BIT +#define __LZO_FAKE_STRICT_16BIT + +#define LZO_99_UNSUPPORTED +#define LZO_999_UNSUPPORTED + +typedef unsigned short lzo_uint; +typedef short lzo_int; +#define LZO_UINT_MAX USHRT_MAX +#define LZO_INT_MAX SHRT_MAX + +#define lzo_sizeof_dict_t sizeof(lzo_uint) + +#if 1 +#define __LZO_NO_UNALIGNED +#define __LZO_NO_ALIGNED +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif + +#endif /* already included */ + diff --git a/DumpProto/lzo/i386/00README.TXT b/DumpProto/lzo/i386/00README.TXT new file mode 100644 index 0000000..51b641a --- /dev/null +++ b/DumpProto/lzo/i386/00README.TXT @@ -0,0 +1,41 @@ + +Directory overview: +=================== + src assembler sources for gcc/gas + d_asm1 sources converted for masm/tasm/wasm + d_asm2 sources converted for masm/tasm/wasm (in a `db' format) + d_asm3 sources converted for nasm (in a `db' format) + + +Notes: +====== + +- The assembler sources are designed for a flat 32 bit memory model + running in protected mode - they should work with most i386 + 32-bit compilers. + +- All functions expect a `cdecl' (C stack based) calling convention. + The function return value will be placed into `eax'. + All other registers are preserved. + +- There are no prototypes for the assembler functions - copy them + from ltest/asm.h if you need some. + +- For reasons of speed all fast assembler decompressors (having `_fast' + in their name) can access (write to) up to 3 bytes past the end of + the decompressed (output) block. Data past the end of the compressed + (input) block is never accessed (read from). + See also LZO.FAQ + +- The assembler functions are not available in a Windows or OS/2 DLL because + I don't know how to generate the necessary DLL export information. + +- You should prefer the sources in `d_asm2' over those in `d_asm1' - many + assemblers insert their own alignment instructions or perform some + other kinds of "optimizations". + +- Finally you should test if the assembler versions are actually faster + than the C version on your machine - some compilers can do a very good + optimization job, and they also can optimize the code for a specific + processor type. + diff --git a/DumpProto/lzo/i386/d_asm1/lzo1c_s1.asm b/DumpProto/lzo/i386/d_asm1/lzo1c_s1.asm new file mode 100644 index 0000000..2578a1a --- /dev/null +++ b/DumpProto/lzo/i386/d_asm1/lzo1c_s1.asm @@ -0,0 +1,141 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +.386p +.model flat + +.code +public _lzo1c_decompress_asm + +_lzo1c_decompress_asm: + push ebp + push edi + push esi + push ebx + push ecx + push edx + sub esp,0000000cH + cld + mov esi,+28H[esp] + mov edi,+30H[esp] + mov ebp,00000003H + nop +L3: xor eax,eax + mov al,[esi] + inc esi + cmp al,20H + jae L6 + or al,al + je L7 + mov ecx,eax +L4: repe movsb +L5: mov al,[esi] + inc esi + cmp al,20H + jb L9 +L6: cmp al,40H + jb L10 + mov ecx,eax + and al,1fH + lea edx,-1H[edi] + shr ecx,05H + sub edx,eax + mov al,[esi] + inc esi + shl eax,05H + sub edx,eax + inc ecx + xchg esi,edx + repe movsb + mov esi,edx + jmp L3 + lea esi,+0H[esi] +L7: mov al,[esi] + inc esi + lea ecx,+20H[eax] + cmp al,0f8H + jb L4 + mov ecx,00000118H + sub al,0f8H + je L8 + xchg eax,ecx + xor al,al + shl eax,cl + xchg eax,ecx +L8: repe movsb + jmp L3 + lea esi,+0H[esi] +L9: lea edx,-1H[edi] + sub edx,eax + mov al,[esi] + inc esi + shl eax,05H + sub edx,eax + xchg esi,edx + movsb + movsb + movsb + mov esi,edx + movsb + xor eax,eax + jmp L5 +L10: and al,1fH + mov ecx,eax + jne L13 + mov cl,1fH +L11: mov al,[esi] + inc esi + or al,al + jne L12 + add ecx,000000ffH + jmp L11 +L12: add ecx,eax +L13: mov al,[esi] + inc esi + mov ebx,eax + and al,3fH + mov edx,edi + sub edx,eax + mov al,[esi] + inc esi + shl eax,06H + sub edx,eax + cmp edx,edi + je L14 + xchg edx,esi + lea ecx,+3H[ecx] + repe movsb + mov esi,edx + xor eax,eax + shr ebx,06H + mov ecx,ebx + jne L4 + jmp L3 +L14: cmp ecx,00000001H + setne al + mov edx,+28H[esp] + add edx,+2cH[esp] + cmp esi,edx + ja L17 + jb L16 +L15: sub edi,+30H[esp] + mov edx,+34H[esp] + mov [edx],edi + neg eax + add esp,0000000cH + pop edx + pop ecx + pop ebx + pop esi + pop edi + pop ebp + ret + mov eax,00000001H + jmp L15 +L16: mov eax,00000008H + jmp L15 +L17: mov eax,00000004H + jmp L15 + nop + +end diff --git a/DumpProto/lzo/i386/d_asm1/lzo1c_s2.asm b/DumpProto/lzo/i386/d_asm1/lzo1c_s2.asm new file mode 100644 index 0000000..9db26fe --- /dev/null +++ b/DumpProto/lzo/i386/d_asm1/lzo1c_s2.asm @@ -0,0 +1,181 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +.386p +.model flat + +.code +public _lzo1c_decompress_asm_safe + +_lzo1c_decompress_asm_safe: + push ebp + push edi + push esi + push ebx + push ecx + push edx + sub esp,0000000cH + cld + mov esi,+28H[esp] + mov edi,+30H[esp] + mov ebp,00000003H + lea eax,-3H[esi] + add eax,+2cH[esp] + mov +4H[esp],eax + mov eax,edi + mov edx,+34H[esp] + add eax,[edx] + mov [esp],eax + lea esi,+0H[esi] +L3: xor eax,eax + mov al,[esi] + inc esi + cmp al,20H + jae L6 + or al,al + je L7 + mov ecx,eax +L4: lea ebx,[edi+ecx] + cmp [esp],ebx + jb L18 + lea ebx,[esi+ecx] + cmp +4H[esp],ebx + jb L17 + repe movsb +L5: mov al,[esi] + inc esi + cmp al,20H + jb L9 +L6: cmp al,40H + jb L10 + mov ecx,eax + and al,1fH + lea edx,-1H[edi] + shr ecx,05H + sub edx,eax + mov al,[esi] + inc esi + shl eax,05H + sub edx,eax + inc ecx + xchg esi,edx + cmp esi,+30H[esp] + jb L19 + lea ebx,[edi+ecx] + cmp [esp],ebx + jb L18 + repe movsb + mov esi,edx + jmp L3 + lea esi,+0H[esi] +L7: mov al,[esi] + inc esi + lea ecx,+20H[eax] + cmp al,0f8H + jb L4 + mov ecx,00000118H + sub al,0f8H + je L8 + xchg eax,ecx + xor al,al + shl eax,cl + xchg eax,ecx +L8: lea ebx,[edi+ecx] + cmp [esp],ebx + jb L18 + lea ebx,[esi+ecx] + cmp +4H[esp],ebx + jb L17 + repe movsb + jmp L3 + lea esi,+0H[esi] +L9: lea edx,-1H[edi] + sub edx,eax + mov al,[esi] + inc esi + shl eax,05H + sub edx,eax + xchg esi,edx + cmp esi,+30H[esp] + jb L19 + lea ebx,+4H[edi] + cmp [esp],ebx + jb L18 + movsb + movsb + movsb + mov esi,edx + movsb + xor eax,eax + jmp L5 +L10: and al,1fH + mov ecx,eax + jne L13 + mov cl,1fH +L11: mov al,[esi] + inc esi + or al,al + jne L12 + add ecx,000000ffH + jmp L11 + lea esi,+0H[esi] +L12: add ecx,eax +L13: mov al,[esi] + inc esi + mov ebx,eax + and al,3fH + mov edx,edi + sub edx,eax + mov al,[esi] + inc esi + shl eax,06H + sub edx,eax + cmp edx,edi + je L14 + xchg edx,esi + lea ecx,+3H[ecx] + cmp esi,+30H[esp] + jb L19 + lea eax,[edi+ecx] + cmp [esp],eax + jb L18 + repe movsb + mov esi,edx + xor eax,eax + shr ebx,06H + mov ecx,ebx + jne L4 + jmp L3 +L14: cmp ecx,00000001H + setne al + cmp edi,[esp] + ja L18 + mov edx,+28H[esp] + add edx,+2cH[esp] + cmp esi,edx + ja L17 + jb L16 +L15: sub edi,+30H[esp] + mov edx,+34H[esp] + mov [edx],edi + neg eax + add esp,0000000cH + pop edx + pop ecx + pop ebx + pop esi + pop edi + pop ebp + ret + mov eax,00000001H + jmp L15 +L16: mov eax,00000008H + jmp L15 +L17: mov eax,00000004H + jmp L15 +L18: mov eax,00000005H + jmp L15 +L19: mov eax,00000006H + jmp L15 + +end diff --git a/DumpProto/lzo/i386/d_asm1/lzo1f_f1.asm b/DumpProto/lzo/i386/d_asm1/lzo1f_f1.asm new file mode 100644 index 0000000..924fc99 --- /dev/null +++ b/DumpProto/lzo/i386/d_asm1/lzo1f_f1.asm @@ -0,0 +1,142 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +.386p +.model flat + +.code +public _lzo1f_decompress_asm_fast + +_lzo1f_decompress_asm_fast: + push ebp + push edi + push esi + push ebx + push ecx + push edx + sub esp,0000000cH + cld + mov esi,+28H[esp] + mov edi,+30H[esp] + mov ebp,00000003H + nop +L3: xor eax,eax + mov al,[esi] + inc esi + cmp al,1fH + ja L9 + or al,al + mov ecx,eax + jne L6 +L4: mov al,[esi] + inc esi + or al,al + jne L5 + add ecx,000000ffH + jmp L4 +L5: lea ecx,+1fH[eax+ecx] +L6: mov al,cl + shr ecx,02H + repe movsd + and al,03H + je L7 + mov ebx,[esi] + add esi,eax + mov [edi],ebx + add edi,eax +L7: mov al,[esi] + inc esi +L8: cmp al,1fH + jbe L13 +L9: cmp al,0dfH + ja L16 + mov ecx,eax + shr eax,02H + lea edx,-1H[edi] + and al,07H + shr ecx,05H + mov ebx,eax + mov al,[esi] + lea eax,[ebx+eax*8] + inc esi +L10: sub edx,eax + add ecx,00000002H + xchg edx,esi + cmp ecx,00000006H + jb L11 + cmp eax,00000004H + jb L11 + mov al,cl + shr ecx,02H + repe movsd + and al,03H + mov cl,al +L11: repe movsb + mov esi,edx +L12: mov cl,-2H[esi] + and ecx,00000003H + je L3 + mov eax,[esi] + add esi,ecx + mov [edi],eax + add edi,ecx + xor eax,eax + mov al,[esi] + inc esi + jmp L8 +L13: shr eax,02H + lea edx,-801H[edi] + mov ecx,eax + mov al,[esi] + inc esi + lea eax,[ecx+eax*8] + sub edx,eax + mov eax,[edx] + mov [edi],eax + add edi,00000003H + jmp L12 +L14: mov al,[esi] + inc esi + or al,al + jne L15 + add ecx,000000ffH + jmp L14 +L15: lea ecx,+1fH[eax+ecx] + jmp L17 + lea esi,+0H[esi] +L16: and al,1fH + mov ecx,eax + je L14 +L17: mov edx,edi + mov ax,[esi] + add esi,00000002H + shr eax,02H + jne L10 + cmp ecx,00000001H + setne al + mov edx,+28H[esp] + add edx,+2cH[esp] + cmp esi,edx + ja L20 + jb L19 +L18: sub edi,+30H[esp] + mov edx,+34H[esp] + mov [edx],edi + neg eax + add esp,0000000cH + pop edx + pop ecx + pop ebx + pop esi + pop edi + pop ebp + ret + mov eax,00000001H + jmp L18 +L19: mov eax,00000008H + jmp L18 +L20: mov eax,00000004H + jmp L18 + mov esi,esi + +end diff --git a/DumpProto/lzo/i386/d_asm1/lzo1f_f2.asm b/DumpProto/lzo/i386/d_asm1/lzo1f_f2.asm new file mode 100644 index 0000000..39da0da --- /dev/null +++ b/DumpProto/lzo/i386/d_asm1/lzo1f_f2.asm @@ -0,0 +1,171 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +.386p +.model flat + +.code +public _lzo1f_decompress_asm_fast_safe + +_lzo1f_decompress_asm_fast_safe: + push ebp + push edi + push esi + push ebx + push ecx + push edx + sub esp,0000000cH + cld + mov esi,+28H[esp] + mov edi,+30H[esp] + mov ebp,00000003H + lea eax,-3H[esi] + add eax,+2cH[esp] + mov +4H[esp],eax + mov eax,edi + mov edx,+34H[esp] + add eax,[edx] + mov [esp],eax + lea esi,+0H[esi] +L3: xor eax,eax + mov al,[esi] + inc esi + cmp al,1fH + ja L9 + or al,al + mov ecx,eax + jne L6 +L4: mov al,[esi] + inc esi + or al,al + jne L5 + add ecx,000000ffH + jmp L4 +L5: lea ecx,+1fH[eax+ecx] +L6: lea ebx,[edi+ecx] + cmp [esp],ebx + jb L21 + lea ebx,[esi+ecx] + cmp +4H[esp],ebx + jb L20 + mov al,cl + shr ecx,02H + repe movsd + and al,03H + je L7 + mov ebx,[esi] + add esi,eax + mov [edi],ebx + add edi,eax +L7: mov al,[esi] + inc esi +L8: cmp al,1fH + jbe L13 +L9: cmp al,0dfH + ja L16 + mov ecx,eax + shr eax,02H + lea edx,-1H[edi] + and al,07H + shr ecx,05H + mov ebx,eax + mov al,[esi] + lea eax,[ebx+eax*8] + inc esi +L10: sub edx,eax + add ecx,00000002H + xchg edx,esi + cmp esi,+30H[esp] + jb L22 + lea ebx,[edi+ecx] + cmp [esp],ebx + jb L21 + cmp ecx,00000006H + jb L11 + cmp eax,00000004H + jb L11 + mov al,cl + shr ecx,02H + repe movsd + and al,03H + mov cl,al +L11: repe movsb + mov esi,edx +L12: mov cl,-2H[esi] + and ecx,00000003H + je L3 + mov eax,[esi] + add esi,ecx + mov [edi],eax + add edi,ecx + xor eax,eax + mov al,[esi] + inc esi + jmp L8 +L13: lea edx,+3H[edi] + cmp [esp],edx + jb L21 + shr eax,02H + lea edx,-801H[edi] + mov ecx,eax + mov al,[esi] + inc esi + lea eax,[ecx+eax*8] + sub edx,eax + cmp edx,+30H[esp] + jb L22 + mov eax,[edx] + mov [edi],eax + add edi,00000003H + jmp L12 +L14: mov al,[esi] + inc esi + or al,al + jne L15 + add ecx,000000ffH + jmp L14 +L15: lea ecx,+1fH[eax+ecx] + jmp L17 + lea esi,+0H[esi] +L16: and al,1fH + mov ecx,eax + je L14 +L17: mov edx,edi + mov ax,[esi] + add esi,00000002H + shr eax,02H + jne L10 + cmp ecx,00000001H + setne al + cmp edi,[esp] + ja L21 + mov edx,+28H[esp] + add edx,+2cH[esp] + cmp esi,edx + ja L20 + jb L19 +L18: sub edi,+30H[esp] + mov edx,+34H[esp] + mov [edx],edi + neg eax + add esp,0000000cH + pop edx + pop ecx + pop ebx + pop esi + pop edi + pop ebp + ret + mov eax,00000001H + jmp L18 +L19: mov eax,00000008H + jmp L18 +L20: mov eax,00000004H + jmp L18 +L21: mov eax,00000005H + jmp L18 +L22: mov eax,00000006H + jmp L18 + lea esi,+0H[esi] + +end diff --git a/DumpProto/lzo/i386/d_asm1/lzo1x_f1.asm b/DumpProto/lzo/i386/d_asm1/lzo1x_f1.asm new file mode 100644 index 0000000..1a76fa2 --- /dev/null +++ b/DumpProto/lzo/i386/d_asm1/lzo1x_f1.asm @@ -0,0 +1,195 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +.386p +.model flat + +.code +public _lzo1x_decompress_asm_fast + +_lzo1x_decompress_asm_fast: + push ebp + push edi + push esi + push ebx + push ecx + push edx + sub esp,0000000cH + cld + mov esi,+28H[esp] + mov edi,+30H[esp] + mov ebp,00000003H + xor eax,eax + xor ebx,ebx + lodsb + cmp al,11H + jbe L6 + sub al,0eH + jmp L7 +L3: add eax,000000ffH +L4: mov bl,[esi] + inc esi + or bl,bl + je L3 + lea eax,+15H[eax+ebx] + jmp L7 + mov esi,esi +L5: mov al,[esi] + inc esi +L6: cmp al,10H + jae L9 + or al,al + je L4 + add eax,00000006H +L7: mov ecx,eax + xor eax,ebp + shr ecx,02H + and eax,ebp +L8: mov edx,[esi] + add esi,00000004H + mov [edi],edx + add edi,00000004H + dec ecx + jne L8 + sub esi,eax + sub edi,eax + mov al,[esi] + inc esi + cmp al,10H + jae L9 + shr eax,02H + mov bl,[esi] + lea edx,-801H[edi] + lea eax,[eax+ebx*4] + inc esi + sub edx,eax + mov ecx,[edx] + mov [edi],ecx + add edi,ebp + jmp L16 +L9: cmp al,40H + jb L12 + mov ecx,eax + shr eax,02H + lea edx,-1H[edi] + and eax,00000007H + mov bl,[esi] + shr ecx,05H + lea eax,[eax+ebx*8] + inc esi + sub edx,eax + add ecx,00000004H + cmp eax,ebp + jae L14 + jmp L17 +L10: add eax,000000ffH +L11: mov bl,[esi] + inc esi + or bl,bl + je L10 + lea ecx,+24H[eax+ebx] + xor eax,eax + jmp L13 + nop +L12: cmp al,20H + jb L20 + and eax,0000001fH + je L11 + lea ecx,+5H[eax] +L13: mov ax,[esi] + lea edx,-1H[edi] + shr eax,02H + add esi,00000002H + sub edx,eax + cmp eax,ebp + jb L17 +L14: lea eax,-3H[edi+ecx] + shr ecx,02H +L15: mov ebx,[edx] + add edx,00000004H + mov [edi],ebx + add edi,00000004H + dec ecx + jne L15 + mov edi,eax + xor ebx,ebx +L16: mov al,-2H[esi] + and eax,ebp + je L5 + mov edx,[esi] + add esi,eax + mov [edi],edx + add edi,eax + mov al,[esi] + inc esi + jmp L9 + lea esi,+0H[esi] +L17: xchg edx,esi + sub ecx,ebp + repe movsb + mov esi,edx + jmp L16 +L18: add ecx,000000ffH +L19: mov bl,[esi] + inc esi + or bl,bl + je L18 + lea ecx,+0cH[ebx+ecx] + jmp L21 + lea esi,+0H[esi] +L20: cmp al,10H + jb L22 + mov ecx,eax + and eax,00000008H + shl eax,0dH + and ecx,00000007H + je L19 + add ecx,00000005H +L21: mov ax,[esi] + add esi,00000002H + lea edx,-4000H[edi] + shr eax,02H + je L23 + sub edx,eax + jmp L14 + lea esi,+0H[esi] +L22: shr eax,02H + mov bl,[esi] + lea edx,-1H[edi] + lea eax,[eax+ebx*4] + inc esi + sub edx,eax + mov al,[edx] + mov [edi],al + mov bl,+1H[edx] + mov +1H[edi],bl + add edi,00000002H + jmp L16 +L23: cmp ecx,00000006H + setne al + mov edx,+28H[esp] + add edx,+2cH[esp] + cmp esi,edx + ja L26 + jb L25 +L24: sub edi,+30H[esp] + mov edx,+34H[esp] + mov [edx],edi + neg eax + add esp,0000000cH + pop edx + pop ecx + pop ebx + pop esi + pop edi + pop ebp + ret + mov eax,00000001H + jmp L24 +L25: mov eax,00000008H + jmp L24 +L26: mov eax,00000004H + jmp L24 + nop + +end diff --git a/DumpProto/lzo/i386/d_asm1/lzo1x_f2.asm b/DumpProto/lzo/i386/d_asm1/lzo1x_f2.asm new file mode 100644 index 0000000..abf5049 --- /dev/null +++ b/DumpProto/lzo/i386/d_asm1/lzo1x_f2.asm @@ -0,0 +1,250 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +.386p +.model flat + +.code +public _lzo1x_decompress_asm_fast_safe + +_lzo1x_decompress_asm_fast_safe: + push ebp + push edi + push esi + push ebx + push ecx + push edx + sub esp,0000000cH + cld + mov esi,+28H[esp] + mov edi,+30H[esp] + mov ebp,00000003H + lea eax,-3H[esi] + add eax,+2cH[esp] + mov +4H[esp],eax + mov eax,edi + mov edx,+34H[esp] + add eax,[edx] + mov [esp],eax + xor eax,eax + xor ebx,ebx + lodsb + cmp al,11H + jbe L6 + sub al,0eH + jmp L7 +L3: add eax,000000ffH + lea edx,+12H[esi+eax] + cmp +4H[esp],edx + jb L26 +L4: mov bl,[esi] + inc esi + or bl,bl + je L3 + lea eax,+15H[eax+ebx] + jmp L7 + lea esi,+0H[esi] +L5: cmp +4H[esp],esi + jb L26 + mov al,[esi] + inc esi +L6: cmp al,10H + jae L9 + or al,al + je L4 + add eax,00000006H +L7: lea edx,-3H[edi+eax] + cmp [esp],edx + jb L27 + lea edx,-3H[esi+eax] + cmp +4H[esp],edx + jb L26 + mov ecx,eax + xor eax,ebp + shr ecx,02H + and eax,ebp +L8: mov edx,[esi] + add esi,00000004H + mov [edi],edx + add edi,00000004H + dec ecx + jne L8 + sub esi,eax + sub edi,eax + mov al,[esi] + inc esi + cmp al,10H + jae L9 + lea edx,+3H[edi] + cmp [esp],edx + jb L27 + shr eax,02H + mov bl,[esi] + lea edx,-801H[edi] + lea eax,[eax+ebx*4] + inc esi + sub edx,eax + cmp edx,+30H[esp] + jb L28 + mov ecx,[edx] + mov [edi],ecx + add edi,ebp + jmp L16 + mov esi,esi +L9: cmp al,40H + jb L12 + mov ecx,eax + shr eax,02H + lea edx,-1H[edi] + and eax,00000007H + mov bl,[esi] + shr ecx,05H + lea eax,[eax+ebx*8] + inc esi + sub edx,eax + add ecx,00000004H + cmp eax,ebp + jae L14 + jmp L17 +L10: add eax,000000ffH + lea edx,+3H[esi] + cmp +4H[esp],edx + jb L26 +L11: mov bl,[esi] + inc esi + or bl,bl + je L10 + lea ecx,+24H[eax+ebx] + xor eax,eax + jmp L13 + nop +L12: cmp al,20H + jb L20 + and eax,0000001fH + je L11 + lea ecx,+5H[eax] +L13: mov ax,[esi] + lea edx,-1H[edi] + shr eax,02H + add esi,00000002H + sub edx,eax + cmp eax,ebp + jb L17 +L14: cmp edx,+30H[esp] + jb L28 + lea eax,-3H[edi+ecx] + shr ecx,02H + cmp [esp],eax + jb L27 +L15: mov ebx,[edx] + add edx,00000004H + mov [edi],ebx + add edi,00000004H + dec ecx + jne L15 + mov edi,eax + xor ebx,ebx +L16: mov al,-2H[esi] + and eax,ebp + je L5 + lea edx,[edi+eax] + cmp [esp],edx + jb L27 + lea edx,[esi+eax] + cmp +4H[esp],edx + jb L26 + mov edx,[esi] + add esi,eax + mov [edi],edx + add edi,eax + mov al,[esi] + inc esi + jmp L9 + lea esi,+0H[esi] +L17: cmp edx,+30H[esp] + jb L28 + lea eax,-3H[edi+ecx] + cmp [esp],eax + jb L27 + xchg edx,esi + sub ecx,ebp + repe movsb + mov esi,edx + jmp L16 +L18: add ecx,000000ffH + lea edx,+3H[esi] + cmp +4H[esp],edx + jb L26 +L19: mov bl,[esi] + inc esi + or bl,bl + je L18 + lea ecx,+0cH[ebx+ecx] + jmp L21 + lea esi,+0H[esi] +L20: cmp al,10H + jb L22 + mov ecx,eax + and eax,00000008H + shl eax,0dH + and ecx,00000007H + je L19 + add ecx,00000005H +L21: mov ax,[esi] + add esi,00000002H + lea edx,-4000H[edi] + shr eax,02H + je L23 + sub edx,eax + jmp L14 + lea esi,+0H[esi] +L22: lea edx,+2H[edi] + cmp [esp],edx + jb L27 + shr eax,02H + mov bl,[esi] + lea edx,-1H[edi] + lea eax,[eax+ebx*4] + inc esi + sub edx,eax + cmp edx,+30H[esp] + jb L28 + mov al,[edx] + mov [edi],al + mov bl,+1H[edx] + mov +1H[edi],bl + add edi,00000002H + jmp L16 +L23: cmp ecx,00000006H + setne al + cmp edi,[esp] + ja L27 + mov edx,+28H[esp] + add edx,+2cH[esp] + cmp esi,edx + ja L26 + jb L25 +L24: sub edi,+30H[esp] + mov edx,+34H[esp] + mov [edx],edi + neg eax + add esp,0000000cH + pop edx + pop ecx + pop ebx + pop esi + pop edi + pop ebp + ret + mov eax,00000001H + jmp L24 +L25: mov eax,00000008H + jmp L24 +L26: mov eax,00000004H + jmp L24 +L27: mov eax,00000005H + jmp L24 +L28: mov eax,00000006H + jmp L24 + +end diff --git a/DumpProto/lzo/i386/d_asm1/lzo1x_s1.asm b/DumpProto/lzo/i386/d_asm1/lzo1x_s1.asm new file mode 100644 index 0000000..6aea022 --- /dev/null +++ b/DumpProto/lzo/i386/d_asm1/lzo1x_s1.asm @@ -0,0 +1,210 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +.386p +.model flat + +.code +public _lzo1x_decompress_asm + +_lzo1x_decompress_asm: + push ebp + push edi + push esi + push ebx + push ecx + push edx + sub esp,0000000cH + cld + mov esi,+28H[esp] + mov edi,+30H[esp] + mov ebp,00000003H + xor eax,eax + xor ebx,ebx + lodsb + cmp al,11H + jbe L6 + sub al,11H + cmp al,04H + jae L7 + mov ecx,eax + jmp L9 +L3: add eax,000000ffH +L4: mov bl,[esi] + inc esi + or bl,bl + je L3 + lea eax,+12H[eax+ebx] + jmp L7 + lea esi,+0H[esi] +L5: mov al,[esi] + inc esi +L6: cmp al,10H + jae L10 + or al,al + je L4 + add eax,00000003H +L7: mov ecx,eax + shr eax,02H + and ecx,ebp +L8: mov edx,[esi] + add esi,00000004H + mov [edi],edx + add edi,00000004H + dec eax + jne L8 +L9: repe movsb + mov al,[esi] + inc esi + cmp al,10H + jae L10 + shr eax,02H + mov bl,[esi] + lea edx,-801H[edi] + lea eax,[eax+ebx*4] + inc esi + sub edx,eax + mov al,[edx] + mov [edi],al + mov al,+1H[edx] + mov +1H[edi],al + mov al,+2H[edx] + mov +2H[edi],al + add edi,ebp + jmp L18 +L10: cmp al,40H + jb L13 + mov ecx,eax + shr eax,02H + lea edx,-1H[edi] + and eax,00000007H + mov bl,[esi] + shr ecx,05H + lea eax,[eax+ebx*8] + inc esi + sub edx,eax + inc ecx + cmp eax,ebp + jae L15 + jmp L20 +L11: add eax,000000ffH +L12: mov bl,[esi] + inc esi + or bl,bl + je L11 + lea ecx,+21H[eax+ebx] + xor eax,eax + jmp L14 + lea esi,+0H[esi] +L13: cmp al,20H + jb L23 + and eax,0000001fH + je L12 + lea ecx,+2H[eax] +L14: mov ax,[esi] + lea edx,-1H[edi] + shr eax,02H + add esi,00000002H + sub edx,eax + cmp eax,ebp + jb L20 +L15: mov ebx,ecx + shr ebx,02H + je L17 +L16: mov eax,[edx] + add edx,00000004H + mov [edi],eax + add edi,00000004H + dec ebx + jne L16 + and ecx,ebp + je L18 +L17: mov al,[edx] + inc edx + mov [edi],al + inc edi + dec ecx + jne L17 +L18: mov al,-2H[esi] + and eax,ebp + je L5 +L19: mov cl,[esi] + inc esi + mov [edi],cl + inc edi + dec eax + jne L19 + mov al,[esi] + inc esi + jmp L10 + nop + lea esi,+0H[esi] +L20: xchg edx,esi + repe movsb + mov esi,edx + jmp L18 +L21: add ecx,000000ffH +L22: mov bl,[esi] + inc esi + or bl,bl + je L21 + lea ecx,+9H[ebx+ecx] + jmp L24 + nop + lea esi,+0H[esi] +L23: cmp al,10H + jb L25 + mov ecx,eax + and eax,00000008H + shl eax,0dH + and ecx,00000007H + je L22 + add ecx,00000002H +L24: mov ax,[esi] + add esi,00000002H + lea edx,-4000H[edi] + shr eax,02H + je L26 + sub edx,eax + jmp L15 + lea esi,+0H[esi] +L25: shr eax,02H + mov bl,[esi] + lea edx,-1H[edi] + lea eax,[eax+ebx*4] + inc esi + sub edx,eax + mov al,[edx] + mov [edi],al + mov bl,+1H[edx] + mov +1H[edi],bl + add edi,00000002H + jmp L18 +L26: cmp ecx,00000003H + setne al + mov edx,+28H[esp] + add edx,+2cH[esp] + cmp esi,edx + ja L29 + jb L28 +L27: sub edi,+30H[esp] + mov edx,+34H[esp] + mov [edx],edi + neg eax + add esp,0000000cH + pop edx + pop ecx + pop ebx + pop esi + pop edi + pop ebp + ret + mov eax,00000001H + jmp L27 +L28: mov eax,00000008H + jmp L27 +L29: mov eax,00000004H + jmp L27 + nop + +end diff --git a/DumpProto/lzo/i386/d_asm1/lzo1x_s2.asm b/DumpProto/lzo/i386/d_asm1/lzo1x_s2.asm new file mode 100644 index 0000000..b409290 --- /dev/null +++ b/DumpProto/lzo/i386/d_asm1/lzo1x_s2.asm @@ -0,0 +1,270 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +.386p +.model flat + +.code +public _lzo1x_decompress_asm_safe + +_lzo1x_decompress_asm_safe: + push ebp + push edi + push esi + push ebx + push ecx + push edx + sub esp,0000000cH + cld + mov esi,+28H[esp] + mov edi,+30H[esp] + mov ebp,00000003H + lea eax,-3H[esi] + add eax,+2cH[esp] + mov +4H[esp],eax + mov eax,edi + mov edx,+34H[esp] + add eax,[edx] + mov [esp],eax + xor eax,eax + xor ebx,ebx + lodsb + cmp al,11H + jbe L6 + sub al,11H + cmp al,04H + jae L7 + lea edx,[edi+eax] + cmp [esp],edx + jb L30 + lea edx,[esi+eax] + cmp +4H[esp],edx + jb L29 + mov ecx,eax + jmp L9 +L3: add eax,000000ffH + lea edx,+12H[esi+eax] + cmp +4H[esp],edx + jb L29 +L4: mov bl,[esi] + inc esi + or bl,bl + je L3 + lea eax,+12H[eax+ebx] + jmp L7 + lea esi,+0H[esi] +L5: cmp +4H[esp],esi + jb L29 + mov al,[esi] + inc esi +L6: cmp al,10H + jae L10 + or al,al + je L4 + add eax,00000003H +L7: lea edx,+0H[edi+eax] + cmp [esp],edx + jb L30 + lea edx,+0H[esi+eax] + cmp +4H[esp],edx + jb L29 + mov ecx,eax + shr eax,02H + and ecx,ebp +L8: mov edx,[esi] + add esi,00000004H + mov [edi],edx + add edi,00000004H + dec eax + jne L8 +L9: repe movsb + mov al,[esi] + inc esi + cmp al,10H + jae L10 + lea edx,+3H[edi] + cmp [esp],edx + jb L30 + shr eax,02H + mov bl,[esi] + lea edx,-801H[edi] + lea eax,[eax+ebx*4] + inc esi + sub edx,eax + cmp edx,+30H[esp] + jb L31 + mov al,[edx] + mov [edi],al + mov al,+1H[edx] + mov +1H[edi],al + mov al,+2H[edx] + mov +2H[edi],al + add edi,ebp + jmp L18 + mov esi,esi +L10: cmp al,40H + jb L13 + mov ecx,eax + shr eax,02H + lea edx,-1H[edi] + and eax,00000007H + mov bl,[esi] + shr ecx,05H + lea eax,[eax+ebx*8] + inc esi + sub edx,eax + inc ecx + cmp eax,ebp + jae L15 + jmp L20 +L11: add eax,000000ffH + lea edx,+3H[esi] + cmp +4H[esp],edx + jb L29 +L12: mov bl,[esi] + inc esi + or bl,bl + je L11 + lea ecx,+21H[eax+ebx] + xor eax,eax + jmp L14 + lea esi,+0H[esi] +L13: cmp al,20H + jb L23 + and eax,0000001fH + je L12 + lea ecx,+2H[eax] +L14: mov ax,[esi] + lea edx,-1H[edi] + shr eax,02H + add esi,00000002H + sub edx,eax + cmp eax,ebp + jb L20 +L15: cmp edx,+30H[esp] + jb L31 + lea eax,[edi+ecx] + cmp [esp],eax + jb L30 + mov ebx,ecx + shr ebx,02H + je L17 +L16: mov eax,[edx] + add edx,00000004H + mov [edi],eax + add edi,00000004H + dec ebx + jne L16 + and ecx,ebp + je L18 +L17: mov al,[edx] + inc edx + mov [edi],al + inc edi + dec ecx + jne L17 +L18: mov al,-2H[esi] + and eax,ebp + je L5 + lea edx,[edi+eax] + cmp [esp],edx + jb L30 + lea edx,[esi+eax] + cmp +4H[esp],edx + jb L29 +L19: mov cl,[esi] + inc esi + mov [edi],cl + inc edi + dec eax + jne L19 + mov al,[esi] + inc esi + jmp L10 + mov esi,esi +L20: cmp edx,+30H[esp] + jb L31 + lea eax,+0H[edi+ecx] + cmp [esp],eax + jb L30 + xchg edx,esi + repe movsb + mov esi,edx + jmp L18 +L21: add ecx,000000ffH + lea edx,+3H[esi] + cmp +4H[esp],edx + jb L29 +L22: mov bl,[esi] + inc esi + or bl,bl + je L21 + lea ecx,+9H[ebx+ecx] + jmp L24 + nop +L23: cmp al,10H + jb L25 + mov ecx,eax + and eax,00000008H + shl eax,0dH + and ecx,00000007H + je L22 + add ecx,00000002H +L24: mov ax,[esi] + add esi,00000002H + lea edx,-4000H[edi] + shr eax,02H + je L26 + sub edx,eax + jmp L15 + lea esi,+0H[esi] +L25: lea edx,+2H[edi] + cmp [esp],edx + jb L30 + shr eax,02H + mov bl,[esi] + lea edx,-1H[edi] + lea eax,[eax+ebx*4] + inc esi + sub edx,eax + cmp edx,+30H[esp] + jb L31 + mov al,[edx] + mov [edi],al + mov bl,+1H[edx] + mov +1H[edi],bl + add edi,00000002H + jmp L18 +L26: cmp ecx,00000003H + setne al + cmp edi,[esp] + ja L30 + mov edx,+28H[esp] + add edx,+2cH[esp] + cmp esi,edx + ja L29 + jb L28 +L27: sub edi,+30H[esp] + mov edx,+34H[esp] + mov [edx],edi + neg eax + add esp,0000000cH + pop edx + pop ecx + pop ebx + pop esi + pop edi + pop ebp + ret + mov eax,00000001H + jmp L27 +L28: mov eax,00000008H + jmp L27 +L29: mov eax,00000004H + jmp L27 +L30: mov eax,00000005H + jmp L27 +L31: mov eax,00000006H + jmp L27 + +end diff --git a/DumpProto/lzo/i386/d_asm1/lzo1y_f1.asm b/DumpProto/lzo/i386/d_asm1/lzo1y_f1.asm new file mode 100644 index 0000000..1d5f7db --- /dev/null +++ b/DumpProto/lzo/i386/d_asm1/lzo1y_f1.asm @@ -0,0 +1,195 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +.386p +.model flat + +.code +public _lzo1y_decompress_asm_fast + +_lzo1y_decompress_asm_fast: + push ebp + push edi + push esi + push ebx + push ecx + push edx + sub esp,0000000cH + cld + mov esi,+28H[esp] + mov edi,+30H[esp] + mov ebp,00000003H + xor eax,eax + xor ebx,ebx + lodsb + cmp al,11H + jbe L6 + sub al,0eH + jmp L7 +L3: add eax,000000ffH +L4: mov bl,[esi] + inc esi + or bl,bl + je L3 + lea eax,+15H[eax+ebx] + jmp L7 + mov esi,esi +L5: mov al,[esi] + inc esi +L6: cmp al,10H + jae L9 + or al,al + je L4 + add eax,00000006H +L7: mov ecx,eax + xor eax,ebp + shr ecx,02H + and eax,ebp +L8: mov edx,[esi] + add esi,00000004H + mov [edi],edx + add edi,00000004H + dec ecx + jne L8 + sub esi,eax + sub edi,eax + mov al,[esi] + inc esi + cmp al,10H + jae L9 + shr eax,02H + mov bl,[esi] + lea edx,-401H[edi] + lea eax,[eax+ebx*4] + inc esi + sub edx,eax + mov ecx,[edx] + mov [edi],ecx + add edi,ebp + jmp L16 +L9: cmp al,40H + jb L12 + mov ecx,eax + shr eax,02H + lea edx,-1H[edi] + and eax,ebp + mov bl,[esi] + shr ecx,04H + lea eax,[eax+ebx*4] + inc esi + sub edx,eax + add ecx,00000002H + cmp eax,ebp + jae L14 + jmp L17 +L10: add eax,000000ffH +L11: mov bl,[esi] + inc esi + or bl,bl + je L10 + lea ecx,+24H[eax+ebx] + xor eax,eax + jmp L13 + mov esi,esi +L12: cmp al,20H + jb L20 + and eax,0000001fH + je L11 + lea ecx,+5H[eax] +L13: mov ax,[esi] + lea edx,-1H[edi] + shr eax,02H + add esi,00000002H + sub edx,eax + cmp eax,ebp + jb L17 +L14: lea eax,-3H[edi+ecx] + shr ecx,02H +L15: mov ebx,[edx] + add edx,00000004H + mov [edi],ebx + add edi,00000004H + dec ecx + jne L15 + mov edi,eax + xor ebx,ebx +L16: mov al,-2H[esi] + and eax,ebp + je L5 + mov edx,[esi] + add esi,eax + mov [edi],edx + add edi,eax + mov al,[esi] + inc esi + jmp L9 + lea esi,+0H[esi] +L17: xchg edx,esi + sub ecx,ebp + repe movsb + mov esi,edx + jmp L16 +L18: add ecx,000000ffH +L19: mov bl,[esi] + inc esi + or bl,bl + je L18 + lea ecx,+0cH[ebx+ecx] + jmp L21 + lea esi,+0H[esi] +L20: cmp al,10H + jb L22 + mov ecx,eax + and eax,00000008H + shl eax,0dH + and ecx,00000007H + je L19 + add ecx,00000005H +L21: mov ax,[esi] + add esi,00000002H + lea edx,-4000H[edi] + shr eax,02H + je L23 + sub edx,eax + jmp L14 + lea esi,+0H[esi] +L22: shr eax,02H + mov bl,[esi] + lea edx,-1H[edi] + lea eax,[eax+ebx*4] + inc esi + sub edx,eax + mov al,[edx] + mov [edi],al + mov bl,+1H[edx] + mov +1H[edi],bl + add edi,00000002H + jmp L16 +L23: cmp ecx,00000006H + setne al + mov edx,+28H[esp] + add edx,+2cH[esp] + cmp esi,edx + ja L26 + jb L25 +L24: sub edi,+30H[esp] + mov edx,+34H[esp] + mov [edx],edi + neg eax + add esp,0000000cH + pop edx + pop ecx + pop ebx + pop esi + pop edi + pop ebp + ret + mov eax,00000001H + jmp L24 +L25: mov eax,00000008H + jmp L24 +L26: mov eax,00000004H + jmp L24 + nop + +end diff --git a/DumpProto/lzo/i386/d_asm1/lzo1y_f2.asm b/DumpProto/lzo/i386/d_asm1/lzo1y_f2.asm new file mode 100644 index 0000000..2dd6cb1 --- /dev/null +++ b/DumpProto/lzo/i386/d_asm1/lzo1y_f2.asm @@ -0,0 +1,250 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +.386p +.model flat + +.code +public _lzo1y_decompress_asm_fast_safe + +_lzo1y_decompress_asm_fast_safe: + push ebp + push edi + push esi + push ebx + push ecx + push edx + sub esp,0000000cH + cld + mov esi,+28H[esp] + mov edi,+30H[esp] + mov ebp,00000003H + lea eax,-3H[esi] + add eax,+2cH[esp] + mov +4H[esp],eax + mov eax,edi + mov edx,+34H[esp] + add eax,[edx] + mov [esp],eax + xor eax,eax + xor ebx,ebx + lodsb + cmp al,11H + jbe L6 + sub al,0eH + jmp L7 +L3: add eax,000000ffH + lea edx,+12H[esi+eax] + cmp +4H[esp],edx + jb L26 +L4: mov bl,[esi] + inc esi + or bl,bl + je L3 + lea eax,+15H[eax+ebx] + jmp L7 + lea esi,+0H[esi] +L5: cmp +4H[esp],esi + jb L26 + mov al,[esi] + inc esi +L6: cmp al,10H + jae L9 + or al,al + je L4 + add eax,00000006H +L7: lea edx,-3H[edi+eax] + cmp [esp],edx + jb L27 + lea edx,-3H[esi+eax] + cmp +4H[esp],edx + jb L26 + mov ecx,eax + xor eax,ebp + shr ecx,02H + and eax,ebp +L8: mov edx,[esi] + add esi,00000004H + mov [edi],edx + add edi,00000004H + dec ecx + jne L8 + sub esi,eax + sub edi,eax + mov al,[esi] + inc esi + cmp al,10H + jae L9 + lea edx,+3H[edi] + cmp [esp],edx + jb L27 + shr eax,02H + mov bl,[esi] + lea edx,-401H[edi] + lea eax,[eax+ebx*4] + inc esi + sub edx,eax + cmp edx,+30H[esp] + jb L28 + mov ecx,[edx] + mov [edi],ecx + add edi,ebp + jmp L16 + mov esi,esi +L9: cmp al,40H + jb L12 + mov ecx,eax + shr eax,02H + lea edx,-1H[edi] + and eax,ebp + mov bl,[esi] + shr ecx,04H + lea eax,[eax+ebx*4] + inc esi + sub edx,eax + add ecx,00000002H + cmp eax,ebp + jae L14 + jmp L17 +L10: add eax,000000ffH + lea edx,+3H[esi] + cmp +4H[esp],edx + jb L26 +L11: mov bl,[esi] + inc esi + or bl,bl + je L10 + lea ecx,+24H[eax+ebx] + xor eax,eax + jmp L13 + mov esi,esi +L12: cmp al,20H + jb L20 + and eax,0000001fH + je L11 + lea ecx,+5H[eax] +L13: mov ax,[esi] + lea edx,-1H[edi] + shr eax,02H + add esi,00000002H + sub edx,eax + cmp eax,ebp + jb L17 +L14: cmp edx,+30H[esp] + jb L28 + lea eax,-3H[edi+ecx] + shr ecx,02H + cmp [esp],eax + jb L27 +L15: mov ebx,[edx] + add edx,00000004H + mov [edi],ebx + add edi,00000004H + dec ecx + jne L15 + mov edi,eax + xor ebx,ebx +L16: mov al,-2H[esi] + and eax,ebp + je L5 + lea edx,[edi+eax] + cmp [esp],edx + jb L27 + lea edx,[esi+eax] + cmp +4H[esp],edx + jb L26 + mov edx,[esi] + add esi,eax + mov [edi],edx + add edi,eax + mov al,[esi] + inc esi + jmp L9 + lea esi,+0H[esi] +L17: cmp edx,+30H[esp] + jb L28 + lea eax,-3H[edi+ecx] + cmp [esp],eax + jb L27 + xchg edx,esi + sub ecx,ebp + repe movsb + mov esi,edx + jmp L16 +L18: add ecx,000000ffH + lea edx,+3H[esi] + cmp +4H[esp],edx + jb L26 +L19: mov bl,[esi] + inc esi + or bl,bl + je L18 + lea ecx,+0cH[ebx+ecx] + jmp L21 + lea esi,+0H[esi] +L20: cmp al,10H + jb L22 + mov ecx,eax + and eax,00000008H + shl eax,0dH + and ecx,00000007H + je L19 + add ecx,00000005H +L21: mov ax,[esi] + add esi,00000002H + lea edx,-4000H[edi] + shr eax,02H + je L23 + sub edx,eax + jmp L14 + lea esi,+0H[esi] +L22: lea edx,+2H[edi] + cmp [esp],edx + jb L27 + shr eax,02H + mov bl,[esi] + lea edx,-1H[edi] + lea eax,[eax+ebx*4] + inc esi + sub edx,eax + cmp edx,+30H[esp] + jb L28 + mov al,[edx] + mov [edi],al + mov bl,+1H[edx] + mov +1H[edi],bl + add edi,00000002H + jmp L16 +L23: cmp ecx,00000006H + setne al + cmp edi,[esp] + ja L27 + mov edx,+28H[esp] + add edx,+2cH[esp] + cmp esi,edx + ja L26 + jb L25 +L24: sub edi,+30H[esp] + mov edx,+34H[esp] + mov [edx],edi + neg eax + add esp,0000000cH + pop edx + pop ecx + pop ebx + pop esi + pop edi + pop ebp + ret + mov eax,00000001H + jmp L24 +L25: mov eax,00000008H + jmp L24 +L26: mov eax,00000004H + jmp L24 +L27: mov eax,00000005H + jmp L24 +L28: mov eax,00000006H + jmp L24 + +end diff --git a/DumpProto/lzo/i386/d_asm1/lzo1y_s1.asm b/DumpProto/lzo/i386/d_asm1/lzo1y_s1.asm new file mode 100644 index 0000000..3513964 --- /dev/null +++ b/DumpProto/lzo/i386/d_asm1/lzo1y_s1.asm @@ -0,0 +1,210 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +.386p +.model flat + +.code +public _lzo1y_decompress_asm + +_lzo1y_decompress_asm: + push ebp + push edi + push esi + push ebx + push ecx + push edx + sub esp,0000000cH + cld + mov esi,+28H[esp] + mov edi,+30H[esp] + mov ebp,00000003H + xor eax,eax + xor ebx,ebx + lodsb + cmp al,11H + jbe L6 + sub al,11H + cmp al,04H + jae L7 + mov ecx,eax + jmp L9 +L3: add eax,000000ffH +L4: mov bl,[esi] + inc esi + or bl,bl + je L3 + lea eax,+12H[eax+ebx] + jmp L7 + lea esi,+0H[esi] +L5: mov al,[esi] + inc esi +L6: cmp al,10H + jae L10 + or al,al + je L4 + add eax,00000003H +L7: mov ecx,eax + shr eax,02H + and ecx,ebp +L8: mov edx,[esi] + add esi,00000004H + mov [edi],edx + add edi,00000004H + dec eax + jne L8 +L9: repe movsb + mov al,[esi] + inc esi + cmp al,10H + jae L10 + shr eax,02H + mov bl,[esi] + lea edx,-401H[edi] + lea eax,[eax+ebx*4] + inc esi + sub edx,eax + mov al,[edx] + mov [edi],al + mov al,+1H[edx] + mov +1H[edi],al + mov al,+2H[edx] + mov +2H[edi],al + add edi,ebp + jmp L18 +L10: cmp al,40H + jb L13 + mov ecx,eax + shr eax,02H + lea edx,-1H[edi] + and eax,ebp + mov bl,[esi] + shr ecx,04H + lea eax,[eax+ebx*4] + inc esi + sub edx,eax + dec ecx + cmp eax,ebp + jae L15 + jmp L20 +L11: add eax,000000ffH +L12: mov bl,[esi] + inc esi + or bl,bl + je L11 + lea ecx,+21H[eax+ebx] + xor eax,eax + jmp L14 + lea esi,+0H[esi] +L13: cmp al,20H + jb L23 + and eax,0000001fH + je L12 + lea ecx,+2H[eax] +L14: mov ax,[esi] + lea edx,-1H[edi] + shr eax,02H + add esi,00000002H + sub edx,eax + cmp eax,ebp + jb L20 +L15: mov ebx,ecx + shr ebx,02H + je L17 +L16: mov eax,[edx] + add edx,00000004H + mov [edi],eax + add edi,00000004H + dec ebx + jne L16 + and ecx,ebp + je L18 +L17: mov al,[edx] + inc edx + mov [edi],al + inc edi + dec ecx + jne L17 +L18: mov al,-2H[esi] + and eax,ebp + je L5 +L19: mov cl,[esi] + inc esi + mov [edi],cl + inc edi + dec eax + jne L19 + mov al,[esi] + inc esi + jmp L10 + nop + lea esi,+0H[esi] +L20: xchg edx,esi + repe movsb + mov esi,edx + jmp L18 +L21: add ecx,000000ffH +L22: mov bl,[esi] + inc esi + or bl,bl + je L21 + lea ecx,+9H[ebx+ecx] + jmp L24 + nop + lea esi,+0H[esi] +L23: cmp al,10H + jb L25 + mov ecx,eax + and eax,00000008H + shl eax,0dH + and ecx,00000007H + je L22 + add ecx,00000002H +L24: mov ax,[esi] + add esi,00000002H + lea edx,-4000H[edi] + shr eax,02H + je L26 + sub edx,eax + jmp L15 + lea esi,+0H[esi] +L25: shr eax,02H + mov bl,[esi] + lea edx,-1H[edi] + lea eax,[eax+ebx*4] + inc esi + sub edx,eax + mov al,[edx] + mov [edi],al + mov bl,+1H[edx] + mov +1H[edi],bl + add edi,00000002H + jmp L18 +L26: cmp ecx,00000003H + setne al + mov edx,+28H[esp] + add edx,+2cH[esp] + cmp esi,edx + ja L29 + jb L28 +L27: sub edi,+30H[esp] + mov edx,+34H[esp] + mov [edx],edi + neg eax + add esp,0000000cH + pop edx + pop ecx + pop ebx + pop esi + pop edi + pop ebp + ret + mov eax,00000001H + jmp L27 +L28: mov eax,00000008H + jmp L27 +L29: mov eax,00000004H + jmp L27 + nop + +end diff --git a/DumpProto/lzo/i386/d_asm1/lzo1y_s2.asm b/DumpProto/lzo/i386/d_asm1/lzo1y_s2.asm new file mode 100644 index 0000000..bc6ba75 --- /dev/null +++ b/DumpProto/lzo/i386/d_asm1/lzo1y_s2.asm @@ -0,0 +1,270 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +.386p +.model flat + +.code +public _lzo1y_decompress_asm_safe + +_lzo1y_decompress_asm_safe: + push ebp + push edi + push esi + push ebx + push ecx + push edx + sub esp,0000000cH + cld + mov esi,+28H[esp] + mov edi,+30H[esp] + mov ebp,00000003H + lea eax,-3H[esi] + add eax,+2cH[esp] + mov +4H[esp],eax + mov eax,edi + mov edx,+34H[esp] + add eax,[edx] + mov [esp],eax + xor eax,eax + xor ebx,ebx + lodsb + cmp al,11H + jbe L6 + sub al,11H + cmp al,04H + jae L7 + lea edx,[edi+eax] + cmp [esp],edx + jb L30 + lea edx,[esi+eax] + cmp +4H[esp],edx + jb L29 + mov ecx,eax + jmp L9 +L3: add eax,000000ffH + lea edx,+12H[esi+eax] + cmp +4H[esp],edx + jb L29 +L4: mov bl,[esi] + inc esi + or bl,bl + je L3 + lea eax,+12H[eax+ebx] + jmp L7 + lea esi,+0H[esi] +L5: cmp +4H[esp],esi + jb L29 + mov al,[esi] + inc esi +L6: cmp al,10H + jae L10 + or al,al + je L4 + add eax,00000003H +L7: lea edx,+0H[edi+eax] + cmp [esp],edx + jb L30 + lea edx,+0H[esi+eax] + cmp +4H[esp],edx + jb L29 + mov ecx,eax + shr eax,02H + and ecx,ebp +L8: mov edx,[esi] + add esi,00000004H + mov [edi],edx + add edi,00000004H + dec eax + jne L8 +L9: repe movsb + mov al,[esi] + inc esi + cmp al,10H + jae L10 + lea edx,+3H[edi] + cmp [esp],edx + jb L30 + shr eax,02H + mov bl,[esi] + lea edx,-401H[edi] + lea eax,[eax+ebx*4] + inc esi + sub edx,eax + cmp edx,+30H[esp] + jb L31 + mov al,[edx] + mov [edi],al + mov al,+1H[edx] + mov +1H[edi],al + mov al,+2H[edx] + mov +2H[edi],al + add edi,ebp + jmp L18 + mov esi,esi +L10: cmp al,40H + jb L13 + mov ecx,eax + shr eax,02H + lea edx,-1H[edi] + and eax,ebp + mov bl,[esi] + shr ecx,04H + lea eax,[eax+ebx*4] + inc esi + sub edx,eax + dec ecx + cmp eax,ebp + jae L15 + jmp L20 +L11: add eax,000000ffH + lea edx,+3H[esi] + cmp +4H[esp],edx + jb L29 +L12: mov bl,[esi] + inc esi + or bl,bl + je L11 + lea ecx,+21H[eax+ebx] + xor eax,eax + jmp L14 + lea esi,+0H[esi] +L13: cmp al,20H + jb L23 + and eax,0000001fH + je L12 + lea ecx,+2H[eax] +L14: mov ax,[esi] + lea edx,-1H[edi] + shr eax,02H + add esi,00000002H + sub edx,eax + cmp eax,ebp + jb L20 +L15: cmp edx,+30H[esp] + jb L31 + lea eax,[edi+ecx] + cmp [esp],eax + jb L30 + mov ebx,ecx + shr ebx,02H + je L17 +L16: mov eax,[edx] + add edx,00000004H + mov [edi],eax + add edi,00000004H + dec ebx + jne L16 + and ecx,ebp + je L18 +L17: mov al,[edx] + inc edx + mov [edi],al + inc edi + dec ecx + jne L17 +L18: mov al,-2H[esi] + and eax,ebp + je L5 + lea edx,[edi+eax] + cmp [esp],edx + jb L30 + lea edx,[esi+eax] + cmp +4H[esp],edx + jb L29 +L19: mov cl,[esi] + inc esi + mov [edi],cl + inc edi + dec eax + jne L19 + mov al,[esi] + inc esi + jmp L10 + mov esi,esi +L20: cmp edx,+30H[esp] + jb L31 + lea eax,+0H[edi+ecx] + cmp [esp],eax + jb L30 + xchg edx,esi + repe movsb + mov esi,edx + jmp L18 +L21: add ecx,000000ffH + lea edx,+3H[esi] + cmp +4H[esp],edx + jb L29 +L22: mov bl,[esi] + inc esi + or bl,bl + je L21 + lea ecx,+9H[ebx+ecx] + jmp L24 + nop +L23: cmp al,10H + jb L25 + mov ecx,eax + and eax,00000008H + shl eax,0dH + and ecx,00000007H + je L22 + add ecx,00000002H +L24: mov ax,[esi] + add esi,00000002H + lea edx,-4000H[edi] + shr eax,02H + je L26 + sub edx,eax + jmp L15 + lea esi,+0H[esi] +L25: lea edx,+2H[edi] + cmp [esp],edx + jb L30 + shr eax,02H + mov bl,[esi] + lea edx,-1H[edi] + lea eax,[eax+ebx*4] + inc esi + sub edx,eax + cmp edx,+30H[esp] + jb L31 + mov al,[edx] + mov [edi],al + mov bl,+1H[edx] + mov +1H[edi],bl + add edi,00000002H + jmp L18 +L26: cmp ecx,00000003H + setne al + cmp edi,[esp] + ja L30 + mov edx,+28H[esp] + add edx,+2cH[esp] + cmp esi,edx + ja L29 + jb L28 +L27: sub edi,+30H[esp] + mov edx,+34H[esp] + mov [edx],edi + neg eax + add esp,0000000cH + pop edx + pop ecx + pop ebx + pop esi + pop edi + pop ebp + ret + mov eax,00000001H + jmp L27 +L28: mov eax,00000008H + jmp L27 +L29: mov eax,00000004H + jmp L27 +L30: mov eax,00000005H + jmp L27 +L31: mov eax,00000006H + jmp L27 + +end diff --git a/DumpProto/lzo/i386/d_asm2/lzo1c_s1.asm b/DumpProto/lzo/i386/d_asm2/lzo1c_s1.asm new file mode 100644 index 0000000..7a496e6 --- /dev/null +++ b/DumpProto/lzo/i386/d_asm2/lzo1c_s1.asm @@ -0,0 +1,140 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +.386p +.model flat + +.code +public _lzo1c_decompress_asm + +_lzo1c_decompress_asm: +db 85 +db 87 +db 86 +db 83 +db 81 +db 82 +db 131, 236, 12 +db 252 +db 139, 116, 36, 40 +db 139, 124, 36, 48 +db 189, 3, 0, 0, 0 +db 144 +db 49, 192 +db 138, 6 +db 70 +db 60, 32 +db 115, 15 +db 8, 192 +db 116, 51 +db 137, 193 +db 243, 164 +db 138, 6 +db 70 +db 60, 32 +db 114, 72 +db 60, 64 +db 114, 93 +db 137, 193 +db 36, 31 +db 141, 87, 255 +db 193, 233, 5 +db 41, 194 +db 138, 6 +db 70 +db 193, 224, 5 +db 41, 194 +db 65 +db 135, 242 +db 243, 164 +db 137, 214 +db 235, 199 +db 141, 180, 38, 0, 0, 0, 0 +db 138, 6 +db 70 +db 141, 72, 32 +db 60, 248 +db 114, 197 +db 185, 24, 1, 0, 0 +db 44, 248 +db 116, 6 +db 145 +db 48, 192 +db 211, 224 +db 145 +db 243, 164 +db 235, 163 +db 141, 118, 0 +db 141, 87, 255 +db 41, 194 +db 138, 6 +db 70 +db 193, 224, 5 +db 41, 194 +db 135, 242 +db 164 +db 164 +db 164 +db 137, 214 +db 164 +db 49, 192 +db 235, 152 +db 36, 31 +db 137, 193 +db 117, 19 +db 177, 31 +db 138, 6 +db 70 +db 8, 192 +db 117, 8 +db 129, 193, 255, 0, 0, 0 +db 235, 241 +db 1, 193 +db 138, 6 +db 70 +db 137, 195 +db 36, 63 +db 137, 250 +db 41, 194 +db 138, 6 +db 70 +db 193, 224, 6 +db 41, 194 +db 57, 250 +db 116, 27 +db 135, 214 +db 141, 73, 3 +db 243, 164 +db 137, 214 +db 49, 192 +db 193, 235, 6 +db 137, 217 +db 15, 133, 80, 255, 255, 255 +db 233, 60, 255, 255, 255 +db 131, 249, 1 +db 15, 149, 192 +db 139, 84, 36, 40 +db 3, 84, 36, 44 +db 57, 214 +db 119, 38 +db 114, 29 +db 43, 124, 36, 48 +db 139, 84, 36, 52 +db 137, 58 +db 247, 216 +db 131, 196, 12 +db 90 +db 89 +db 91 +db 94 +db 95 +db 93 +db 195 +db 184, 1, 0, 0, 0 +db 235, 227 +db 184, 8, 0, 0, 0 +db 235, 220 +db 184, 4, 0, 0, 0 +db 235, 213 + +end diff --git a/DumpProto/lzo/i386/d_asm2/lzo1c_s2.asm b/DumpProto/lzo/i386/d_asm2/lzo1c_s2.asm new file mode 100644 index 0000000..a9ac424 --- /dev/null +++ b/DumpProto/lzo/i386/d_asm2/lzo1c_s2.asm @@ -0,0 +1,181 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +.386p +.model flat + +.code +public _lzo1c_decompress_asm_safe + +_lzo1c_decompress_asm_safe: +db 85 +db 87 +db 86 +db 83 +db 81 +db 82 +db 131, 236, 12 +db 252 +db 139, 116, 36, 40 +db 139, 124, 36, 48 +db 189, 3, 0, 0, 0 +db 141, 70, 253 +db 3, 68, 36, 44 +db 137, 68, 36, 4 +db 137, 248 +db 139, 84, 36, 52 +db 3, 2 +db 137, 4, 36 +db 141, 118, 0 +db 49, 192 +db 138, 6 +db 70 +db 60, 32 +db 115, 40 +db 8, 192 +db 116, 99 +db 137, 193 +db 141, 28, 15 +db 57, 28, 36 +db 15, 130, 107, 1, 0, 0 +db 141, 28, 14 +db 57, 92, 36, 4 +db 15, 130, 87, 1, 0, 0 +db 243, 164 +db 138, 6 +db 70 +db 60, 32 +db 114, 127 +db 60, 64 +db 15, 130, 169, 0, 0, 0 +db 137, 193 +db 36, 31 +db 141, 87, 255 +db 193, 233, 5 +db 41, 194 +db 138, 6 +db 70 +db 193, 224, 5 +db 41, 194 +db 65 +db 135, 242 +db 59, 116, 36, 48 +db 15, 130, 51, 1, 0, 0 +db 141, 28, 15 +db 57, 28, 36 +db 15, 130, 32, 1, 0, 0 +db 243, 164 +db 137, 214 +db 235, 148 +db 141, 116, 38, 0 +db 138, 6 +db 70 +db 141, 72, 32 +db 60, 248 +db 114, 149 +db 185, 24, 1, 0, 0 +db 44, 248 +db 116, 6 +db 145 +db 48, 192 +db 211, 224 +db 145 +db 141, 28, 15 +db 57, 28, 36 +db 15, 130, 241, 0, 0, 0 +db 141, 28, 14 +db 57, 92, 36, 4 +db 15, 130, 221, 0, 0, 0 +db 243, 164 +db 233, 87, 255, 255, 255 +db 141, 180, 38, 0, 0, 0, 0 +db 141, 87, 255 +db 41, 194 +db 138, 6 +db 70 +db 193, 224, 5 +db 41, 194 +db 135, 242 +db 59, 116, 36, 48 +db 15, 130, 196, 0, 0, 0 +db 141, 95, 4 +db 57, 28, 36 +db 15, 130, 177, 0, 0, 0 +db 164 +db 164 +db 164 +db 137, 214 +db 164 +db 49, 192 +db 233, 72, 255, 255, 255 +db 36, 31 +db 137, 193 +db 117, 26 +db 177, 31 +db 138, 6 +db 70 +db 8, 192 +db 117, 15 +db 129, 193, 255, 0, 0, 0 +db 235, 241 +db 141, 180, 38, 0, 0, 0, 0 +db 1, 193 +db 138, 6 +db 70 +db 137, 195 +db 36, 63 +db 137, 250 +db 41, 194 +db 138, 6 +db 70 +db 193, 224, 6 +db 41, 194 +db 57, 250 +db 116, 41 +db 135, 214 +db 141, 73, 3 +db 59, 116, 36, 48 +db 114, 105 +db 141, 4, 15 +db 57, 4, 36 +db 114, 90 +db 243, 164 +db 137, 214 +db 49, 192 +db 193, 235, 6 +db 137, 217 +db 15, 133, 210, 254, 255, 255 +db 233, 190, 254, 255, 255 +db 131, 249, 1 +db 15, 149, 192 +db 59, 60, 36 +db 119, 57 +db 139, 84, 36, 40 +db 3, 84, 36, 44 +db 57, 214 +db 119, 38 +db 114, 29 +db 43, 124, 36, 48 +db 139, 84, 36, 52 +db 137, 58 +db 247, 216 +db 131, 196, 12 +db 90 +db 89 +db 91 +db 94 +db 95 +db 93 +db 195 +db 184, 1, 0, 0, 0 +db 235, 227 +db 184, 8, 0, 0, 0 +db 235, 220 +db 184, 4, 0, 0, 0 +db 235, 213 +db 184, 5, 0, 0, 0 +db 235, 206 +db 184, 6, 0, 0, 0 +db 235, 199 + +end diff --git a/DumpProto/lzo/i386/d_asm2/lzo1f_f1.asm b/DumpProto/lzo/i386/d_asm2/lzo1f_f1.asm new file mode 100644 index 0000000..2d5a7c7 --- /dev/null +++ b/DumpProto/lzo/i386/d_asm2/lzo1f_f1.asm @@ -0,0 +1,141 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +.386p +.model flat + +.code +public _lzo1f_decompress_asm_fast + +_lzo1f_decompress_asm_fast: +db 85 +db 87 +db 86 +db 83 +db 81 +db 82 +db 131, 236, 12 +db 252 +db 139, 116, 36, 40 +db 139, 124, 36, 48 +db 189, 3, 0, 0, 0 +db 144 +db 49, 192 +db 138, 6 +db 70 +db 60, 31 +db 119, 51 +db 8, 192 +db 137, 193 +db 117, 19 +db 138, 6 +db 70 +db 8, 192 +db 117, 8 +db 129, 193, 255, 0, 0, 0 +db 235, 241 +db 141, 76, 8, 31 +db 136, 200 +db 193, 233, 2 +db 243, 165 +db 36, 3 +db 116, 8 +db 139, 30 +db 1, 198 +db 137, 31 +db 1, 199 +db 138, 6 +db 70 +db 60, 31 +db 118, 88 +db 60, 223 +db 15, 135, 132, 0, 0, 0 +db 137, 193 +db 193, 232, 2 +db 141, 87, 255 +db 36, 7 +db 193, 233, 5 +db 137, 195 +db 138, 6 +db 141, 4, 195 +db 70 +db 41, 194 +db 131, 193, 2 +db 135, 214 +db 131, 249, 6 +db 114, 16 +db 131, 248, 4 +db 114, 11 +db 136, 200 +db 193, 233, 2 +db 243, 165 +db 36, 3 +db 136, 193 +db 243, 164 +db 137, 214 +db 138, 78, 254 +db 131, 225, 3 +db 15, 132, 123, 255, 255, 255 +db 139, 6 +db 1, 206 +db 137, 7 +db 1, 207 +db 49, 192 +db 138, 6 +db 70 +db 235, 164 +db 193, 232, 2 +db 141, 151, 255, 247, 255, 255 +db 137, 193 +db 138, 6 +db 70 +db 141, 4, 193 +db 41, 194 +db 139, 2 +db 137, 7 +db 131, 199, 3 +db 235, 201 +db 138, 6 +db 70 +db 8, 192 +db 117, 8 +db 129, 193, 255, 0, 0, 0 +db 235, 241 +db 141, 76, 8, 31 +db 235, 9 +db 141, 118, 0 +db 36, 31 +db 137, 193 +db 116, 226 +db 137, 250 +db 102, 139, 6 +db 131, 198, 2 +db 193, 232, 2 +db 15, 133, 122, 255, 255, 255 +db 131, 249, 1 +db 15, 149, 192 +db 139, 84, 36, 40 +db 3, 84, 36, 44 +db 57, 214 +db 119, 38 +db 114, 29 +db 43, 124, 36, 48 +db 139, 84, 36, 52 +db 137, 58 +db 247, 216 +db 131, 196, 12 +db 90 +db 89 +db 91 +db 94 +db 95 +db 93 +db 195 +db 184, 1, 0, 0, 0 +db 235, 227 +db 184, 8, 0, 0, 0 +db 235, 220 +db 184, 4, 0, 0, 0 +db 235, 213 + +end diff --git a/DumpProto/lzo/i386/d_asm2/lzo1f_f2.asm b/DumpProto/lzo/i386/d_asm2/lzo1f_f2.asm new file mode 100644 index 0000000..208162d --- /dev/null +++ b/DumpProto/lzo/i386/d_asm2/lzo1f_f2.asm @@ -0,0 +1,170 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +.386p +.model flat + +.code +public _lzo1f_decompress_asm_fast_safe + +_lzo1f_decompress_asm_fast_safe: +db 85 +db 87 +db 86 +db 83 +db 81 +db 82 +db 131, 236, 12 +db 252 +db 139, 116, 36, 40 +db 139, 124, 36, 48 +db 189, 3, 0, 0, 0 +db 141, 70, 253 +db 3, 68, 36, 44 +db 137, 68, 36, 4 +db 137, 248 +db 139, 84, 36, 52 +db 3, 2 +db 137, 4, 36 +db 141, 118, 0 +db 49, 192 +db 138, 6 +db 70 +db 60, 31 +db 119, 76 +db 8, 192 +db 137, 193 +db 117, 19 +db 138, 6 +db 70 +db 8, 192 +db 117, 8 +db 129, 193, 255, 0, 0, 0 +db 235, 241 +db 141, 76, 8, 31 +db 141, 28, 15 +db 57, 28, 36 +db 15, 130, 61, 1, 0, 0 +db 141, 28, 14 +db 57, 92, 36, 4 +db 15, 130, 41, 1, 0, 0 +db 136, 200 +db 193, 233, 2 +db 243, 165 +db 36, 3 +db 116, 8 +db 139, 30 +db 1, 198 +db 137, 31 +db 1, 199 +db 138, 6 +db 70 +db 60, 31 +db 118, 110 +db 60, 223 +db 15, 135, 179, 0, 0, 0 +db 137, 193 +db 193, 232, 2 +db 141, 87, 255 +db 36, 7 +db 193, 233, 5 +db 137, 195 +db 138, 6 +db 141, 4, 195 +db 70 +db 41, 194 +db 131, 193, 2 +db 135, 214 +db 59, 116, 36, 48 +db 15, 130, 239, 0, 0, 0 +db 141, 28, 15 +db 57, 28, 36 +db 15, 130, 220, 0, 0, 0 +db 131, 249, 6 +db 114, 16 +db 131, 248, 4 +db 114, 11 +db 136, 200 +db 193, 233, 2 +db 243, 165 +db 36, 3 +db 136, 193 +db 243, 164 +db 137, 214 +db 138, 78, 254 +db 131, 225, 3 +db 15, 132, 76, 255, 255, 255 +db 139, 6 +db 1, 206 +db 137, 7 +db 1, 207 +db 49, 192 +db 138, 6 +db 70 +db 235, 142 +db 141, 87, 3 +db 57, 20, 36 +db 15, 130, 156, 0, 0, 0 +db 193, 232, 2 +db 141, 151, 255, 247, 255, 255 +db 137, 193 +db 138, 6 +db 70 +db 141, 4, 193 +db 41, 194 +db 59, 84, 36, 48 +db 15, 130, 134, 0, 0, 0 +db 139, 2 +db 137, 7 +db 131, 199, 3 +db 235, 179 +db 138, 6 +db 70 +db 8, 192 +db 117, 8 +db 129, 193, 255, 0, 0, 0 +db 235, 241 +db 141, 76, 8, 31 +db 235, 12 +db 141, 182, 0, 0, 0, 0 +db 36, 31 +db 137, 193 +db 116, 223 +db 137, 250 +db 102, 139, 6 +db 131, 198, 2 +db 193, 232, 2 +db 15, 133, 75, 255, 255, 255 +db 131, 249, 1 +db 15, 149, 192 +db 59, 60, 36 +db 119, 57 +db 139, 84, 36, 40 +db 3, 84, 36, 44 +db 57, 214 +db 119, 38 +db 114, 29 +db 43, 124, 36, 48 +db 139, 84, 36, 52 +db 137, 58 +db 247, 216 +db 131, 196, 12 +db 90 +db 89 +db 91 +db 94 +db 95 +db 93 +db 195 +db 184, 1, 0, 0, 0 +db 235, 227 +db 184, 8, 0, 0, 0 +db 235, 220 +db 184, 4, 0, 0, 0 +db 235, 213 +db 184, 5, 0, 0, 0 +db 235, 206 +db 184, 6, 0, 0, 0 +db 235, 199 + +end diff --git a/DumpProto/lzo/i386/d_asm2/lzo1x_f1.asm b/DumpProto/lzo/i386/d_asm2/lzo1x_f1.asm new file mode 100644 index 0000000..4bedb1c --- /dev/null +++ b/DumpProto/lzo/i386/d_asm2/lzo1x_f1.asm @@ -0,0 +1,194 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +.386p +.model flat + +.code +public _lzo1x_decompress_asm_fast + +_lzo1x_decompress_asm_fast: +db 85 +db 87 +db 86 +db 83 +db 81 +db 82 +db 131, 236, 12 +db 252 +db 139, 116, 36, 40 +db 139, 124, 36, 48 +db 189, 3, 0, 0, 0 +db 49, 192 +db 49, 219 +db 172 +db 60, 17 +db 118, 27 +db 44, 14 +db 235, 34 +db 5, 255, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 244 +db 141, 68, 24, 21 +db 235, 16 +db 137, 246 +db 138, 6 +db 70 +db 60, 16 +db 115, 65 +db 8, 192 +db 116, 230 +db 131, 192, 6 +db 137, 193 +db 49, 232 +db 193, 233, 2 +db 33, 232 +db 139, 22 +db 131, 198, 4 +db 137, 23 +db 131, 199, 4 +db 73 +db 117, 243 +db 41, 198 +db 41, 199 +db 138, 6 +db 70 +db 60, 16 +db 115, 25 +db 193, 232, 2 +db 138, 30 +db 141, 151, 255, 247, 255, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 139, 10 +db 137, 15 +db 1, 239 +db 235, 110 +db 60, 64 +db 114, 52 +db 137, 193 +db 193, 232, 2 +db 141, 87, 255 +db 131, 224, 7 +db 138, 30 +db 193, 233, 5 +db 141, 4, 216 +db 70 +db 41, 194 +db 131, 193, 4 +db 57, 232 +db 115, 53 +db 235, 109 +db 5, 255, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 244 +db 141, 76, 24, 36 +db 49, 192 +db 235, 13 +db 144 +db 60, 32 +db 114, 116 +db 131, 224, 31 +db 116, 231 +db 141, 72, 5 +db 102, 139, 6 +db 141, 87, 255 +db 193, 232, 2 +db 131, 198, 2 +db 41, 194 +db 57, 232 +db 114, 58 +db 141, 68, 15, 253 +db 193, 233, 2 +db 139, 26 +db 131, 194, 4 +db 137, 31 +db 131, 199, 4 +db 73 +db 117, 243 +db 137, 199 +db 49, 219 +db 138, 70, 254 +db 33, 232 +db 15, 132, 63, 255, 255, 255 +db 139, 22 +db 1, 198 +db 137, 23 +db 1, 199 +db 138, 6 +db 70 +db 233, 119, 255, 255, 255 +db 141, 180, 38, 0, 0, 0, 0 +db 135, 214 +db 41, 233 +db 243, 164 +db 137, 214 +db 235, 212 +db 129, 193, 255, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 243 +db 141, 76, 11, 12 +db 235, 23 +db 141, 118, 0 +db 60, 16 +db 114, 44 +db 137, 193 +db 131, 224, 8 +db 193, 224, 13 +db 131, 225, 7 +db 116, 223 +db 131, 193, 5 +db 102, 139, 6 +db 131, 198, 2 +db 141, 151, 0, 192, 255, 255 +db 193, 232, 2 +db 116, 43 +db 41, 194 +db 233, 122, 255, 255, 255 +db 141, 116, 38, 0 +db 193, 232, 2 +db 138, 30 +db 141, 87, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 138, 2 +db 136, 7 +db 138, 90, 1 +db 136, 95, 1 +db 131, 199, 2 +db 233, 110, 255, 255, 255 +db 131, 249, 6 +db 15, 149, 192 +db 139, 84, 36, 40 +db 3, 84, 36, 44 +db 57, 214 +db 119, 38 +db 114, 29 +db 43, 124, 36, 48 +db 139, 84, 36, 52 +db 137, 58 +db 247, 216 +db 131, 196, 12 +db 90 +db 89 +db 91 +db 94 +db 95 +db 93 +db 195 +db 184, 1, 0, 0, 0 +db 235, 227 +db 184, 8, 0, 0, 0 +db 235, 220 +db 184, 4, 0, 0, 0 +db 235, 213 + +end diff --git a/DumpProto/lzo/i386/d_asm2/lzo1x_f2.asm b/DumpProto/lzo/i386/d_asm2/lzo1x_f2.asm new file mode 100644 index 0000000..786944c --- /dev/null +++ b/DumpProto/lzo/i386/d_asm2/lzo1x_f2.asm @@ -0,0 +1,250 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +.386p +.model flat + +.code +public _lzo1x_decompress_asm_fast_safe + +_lzo1x_decompress_asm_fast_safe: +db 85 +db 87 +db 86 +db 83 +db 81 +db 82 +db 131, 236, 12 +db 252 +db 139, 116, 36, 40 +db 139, 124, 36, 48 +db 189, 3, 0, 0, 0 +db 141, 70, 253 +db 3, 68, 36, 44 +db 137, 68, 36, 4 +db 137, 248 +db 139, 84, 36, 52 +db 3, 2 +db 137, 4, 36 +db 49, 192 +db 49, 219 +db 172 +db 60, 17 +db 118, 55 +db 44, 14 +db 235, 62 +db 5, 255, 0, 0, 0 +db 141, 84, 6, 18 +db 57, 84, 36, 4 +db 15, 130, 78, 2, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 230 +db 141, 68, 24, 21 +db 235, 30 +db 141, 182, 0, 0, 0, 0 +db 57, 116, 36, 4 +db 15, 130, 49, 2, 0, 0 +db 138, 6 +db 70 +db 60, 16 +db 115, 119 +db 8, 192 +db 116, 216 +db 131, 192, 6 +db 141, 84, 7, 253 +db 57, 20, 36 +db 15, 130, 29, 2, 0, 0 +db 141, 84, 6, 253 +db 57, 84, 36, 4 +db 15, 130, 8, 2, 0, 0 +db 137, 193 +db 49, 232 +db 193, 233, 2 +db 33, 232 +db 139, 22 +db 131, 198, 4 +db 137, 23 +db 131, 199, 4 +db 73 +db 117, 243 +db 41, 198 +db 41, 199 +db 138, 6 +db 70 +db 60, 16 +db 115, 52 +db 141, 87, 3 +db 57, 20, 36 +db 15, 130, 226, 1, 0, 0 +db 193, 232, 2 +db 138, 30 +db 141, 151, 255, 247, 255, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 59, 84, 36, 48 +db 15, 130, 206, 1, 0, 0 +db 139, 10 +db 137, 15 +db 1, 239 +db 233, 151, 0, 0, 0 +db 137, 246 +db 60, 64 +db 114, 68 +db 137, 193 +db 193, 232, 2 +db 141, 87, 255 +db 131, 224, 7 +db 138, 30 +db 193, 233, 5 +db 141, 4, 216 +db 70 +db 41, 194 +db 131, 193, 4 +db 57, 232 +db 115, 73 +db 233, 170, 0, 0, 0 +db 5, 255, 0, 0, 0 +db 141, 86, 3 +db 57, 84, 36, 4 +db 15, 130, 123, 1, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 231 +db 141, 76, 24, 36 +db 49, 192 +db 235, 17 +db 144 +db 60, 32 +db 15, 130, 200, 0, 0, 0 +db 131, 224, 31 +db 116, 227 +db 141, 72, 5 +db 102, 139, 6 +db 141, 87, 255 +db 193, 232, 2 +db 131, 198, 2 +db 41, 194 +db 57, 232 +db 114, 102 +db 59, 84, 36, 48 +db 15, 130, 77, 1, 0, 0 +db 141, 68, 15, 253 +db 193, 233, 2 +db 57, 4, 36 +db 15, 130, 54, 1, 0, 0 +db 139, 26 +db 131, 194, 4 +db 137, 31 +db 131, 199, 4 +db 73 +db 117, 243 +db 137, 199 +db 49, 219 +db 138, 70, 254 +db 33, 232 +db 15, 132, 216, 254, 255, 255 +db 141, 20, 7 +db 57, 20, 36 +db 15, 130, 14, 1, 0, 0 +db 141, 20, 6 +db 57, 84, 36, 4 +db 15, 130, 250, 0, 0, 0 +db 139, 22 +db 1, 198 +db 137, 23 +db 1, 199 +db 138, 6 +db 70 +db 233, 55, 255, 255, 255 +db 141, 180, 38, 0, 0, 0, 0 +db 59, 84, 36, 48 +db 15, 130, 231, 0, 0, 0 +db 141, 68, 15, 253 +db 57, 4, 36 +db 15, 130, 211, 0, 0, 0 +db 135, 214 +db 41, 233 +db 243, 164 +db 137, 214 +db 235, 164 +db 129, 193, 255, 0, 0, 0 +db 141, 86, 3 +db 57, 84, 36, 4 +db 15, 130, 175, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 230 +db 141, 76, 11, 12 +db 235, 27 +db 141, 180, 38, 0, 0, 0, 0 +db 60, 16 +db 114, 44 +db 137, 193 +db 131, 224, 8 +db 193, 224, 13 +db 131, 225, 7 +db 116, 219 +db 131, 193, 5 +db 102, 139, 6 +db 131, 198, 2 +db 141, 151, 0, 192, 255, 255 +db 193, 232, 2 +db 116, 57 +db 41, 194 +db 233, 38, 255, 255, 255 +db 141, 116, 38, 0 +db 141, 87, 2 +db 57, 20, 36 +db 114, 106 +db 193, 232, 2 +db 138, 30 +db 141, 87, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 59, 84, 36, 48 +db 114, 93 +db 138, 2 +db 136, 7 +db 138, 90, 1 +db 136, 95, 1 +db 131, 199, 2 +db 233, 31, 255, 255, 255 +db 131, 249, 6 +db 15, 149, 192 +db 59, 60, 36 +db 119, 57 +db 139, 84, 36, 40 +db 3, 84, 36, 44 +db 57, 214 +db 119, 38 +db 114, 29 +db 43, 124, 36, 48 +db 139, 84, 36, 52 +db 137, 58 +db 247, 216 +db 131, 196, 12 +db 90 +db 89 +db 91 +db 94 +db 95 +db 93 +db 195 +db 184, 1, 0, 0, 0 +db 235, 227 +db 184, 8, 0, 0, 0 +db 235, 220 +db 184, 4, 0, 0, 0 +db 235, 213 +db 184, 5, 0, 0, 0 +db 235, 206 +db 184, 6, 0, 0, 0 +db 235, 199 + +end diff --git a/DumpProto/lzo/i386/d_asm2/lzo1x_s1.asm b/DumpProto/lzo/i386/d_asm2/lzo1x_s1.asm new file mode 100644 index 0000000..78e5b86 --- /dev/null +++ b/DumpProto/lzo/i386/d_asm2/lzo1x_s1.asm @@ -0,0 +1,209 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +.386p +.model flat + +.code +public _lzo1x_decompress_asm + +_lzo1x_decompress_asm: +db 85 +db 87 +db 86 +db 83 +db 81 +db 82 +db 131, 236, 12 +db 252 +db 139, 116, 36, 40 +db 139, 124, 36, 48 +db 189, 3, 0, 0, 0 +db 49, 192 +db 49, 219 +db 172 +db 60, 17 +db 118, 35 +db 44, 17 +db 60, 4 +db 115, 40 +db 137, 193 +db 235, 56 +db 5, 255, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 244 +db 141, 68, 24, 18 +db 235, 18 +db 141, 116, 38, 0 +db 138, 6 +db 70 +db 60, 16 +db 115, 73 +db 8, 192 +db 116, 228 +db 131, 192, 3 +db 137, 193 +db 193, 232, 2 +db 33, 233 +db 139, 22 +db 131, 198, 4 +db 137, 23 +db 131, 199, 4 +db 72 +db 117, 243 +db 243, 164 +db 138, 6 +db 70 +db 60, 16 +db 115, 37 +db 193, 232, 2 +db 138, 30 +db 141, 151, 255, 247, 255, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 138, 2 +db 136, 7 +db 138, 66, 1 +db 136, 71, 1 +db 138, 66, 2 +db 136, 71, 2 +db 1, 239 +db 235, 119 +db 60, 64 +db 114, 52 +db 137, 193 +db 193, 232, 2 +db 141, 87, 255 +db 131, 224, 7 +db 138, 30 +db 193, 233, 5 +db 141, 4, 216 +db 70 +db 41, 194 +db 65 +db 57, 232 +db 115, 55 +db 235, 119 +db 5, 255, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 244 +db 141, 76, 24, 33 +db 49, 192 +db 235, 15 +db 141, 118, 0 +db 60, 32 +db 114, 124 +db 131, 224, 31 +db 116, 229 +db 141, 72, 2 +db 102, 139, 6 +db 141, 87, 255 +db 193, 232, 2 +db 131, 198, 2 +db 41, 194 +db 57, 232 +db 114, 66 +db 137, 203 +db 193, 235, 2 +db 116, 17 +db 139, 2 +db 131, 194, 4 +db 137, 7 +db 131, 199, 4 +db 75 +db 117, 243 +db 33, 233 +db 116, 9 +db 138, 2 +db 66 +db 136, 7 +db 71 +db 73 +db 117, 247 +db 138, 70, 254 +db 33, 232 +db 15, 132, 46, 255, 255, 255 +db 138, 14 +db 70 +db 136, 15 +db 71 +db 72 +db 117, 247 +db 138, 6 +db 70 +db 233, 109, 255, 255, 255 +db 144 +db 141, 116, 38, 0 +db 135, 214 +db 243, 164 +db 137, 214 +db 235, 215 +db 129, 193, 255, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 243 +db 141, 76, 11, 9 +db 235, 25 +db 144 +db 141, 116, 38, 0 +db 60, 16 +db 114, 44 +db 137, 193 +db 131, 224, 8 +db 193, 224, 13 +db 131, 225, 7 +db 116, 221 +db 131, 193, 2 +db 102, 139, 6 +db 131, 198, 2 +db 141, 151, 0, 192, 255, 255 +db 193, 232, 2 +db 116, 43 +db 41, 194 +db 233, 114, 255, 255, 255 +db 141, 116, 38, 0 +db 193, 232, 2 +db 138, 30 +db 141, 87, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 138, 2 +db 136, 7 +db 138, 90, 1 +db 136, 95, 1 +db 131, 199, 2 +db 233, 111, 255, 255, 255 +db 131, 249, 3 +db 15, 149, 192 +db 139, 84, 36, 40 +db 3, 84, 36, 44 +db 57, 214 +db 119, 38 +db 114, 29 +db 43, 124, 36, 48 +db 139, 84, 36, 52 +db 137, 58 +db 247, 216 +db 131, 196, 12 +db 90 +db 89 +db 91 +db 94 +db 95 +db 93 +db 195 +db 184, 1, 0, 0, 0 +db 235, 227 +db 184, 8, 0, 0, 0 +db 235, 220 +db 184, 4, 0, 0, 0 +db 235, 213 + +end diff --git a/DumpProto/lzo/i386/d_asm2/lzo1x_s2.asm b/DumpProto/lzo/i386/d_asm2/lzo1x_s2.asm new file mode 100644 index 0000000..d2559e5 --- /dev/null +++ b/DumpProto/lzo/i386/d_asm2/lzo1x_s2.asm @@ -0,0 +1,270 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +.386p +.model flat + +.code +public _lzo1x_decompress_asm_safe + +_lzo1x_decompress_asm_safe: +db 85 +db 87 +db 86 +db 83 +db 81 +db 82 +db 131, 236, 12 +db 252 +db 139, 116, 36, 40 +db 139, 124, 36, 48 +db 189, 3, 0, 0, 0 +db 141, 70, 253 +db 3, 68, 36, 44 +db 137, 68, 36, 4 +db 137, 248 +db 139, 84, 36, 52 +db 3, 2 +db 137, 4, 36 +db 49, 192 +db 49, 219 +db 172 +db 60, 17 +db 118, 87 +db 44, 17 +db 60, 4 +db 115, 92 +db 141, 20, 7 +db 57, 20, 36 +db 15, 130, 130, 2, 0, 0 +db 141, 20, 6 +db 57, 84, 36, 4 +db 15, 130, 110, 2, 0, 0 +db 137, 193 +db 235, 110 +db 5, 255, 0, 0, 0 +db 141, 84, 6, 18 +db 57, 84, 36, 4 +db 15, 130, 87, 2, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 230 +db 141, 68, 24, 18 +db 235, 31 +db 141, 180, 38, 0, 0, 0, 0 +db 57, 116, 36, 4 +db 15, 130, 57, 2, 0, 0 +db 138, 6 +db 70 +db 60, 16 +db 115, 127 +db 8, 192 +db 116, 215 +db 131, 192, 3 +db 141, 84, 7, 0 +db 57, 20, 36 +db 15, 130, 37, 2, 0, 0 +db 141, 84, 6, 0 +db 57, 84, 36, 4 +db 15, 130, 16, 2, 0, 0 +db 137, 193 +db 193, 232, 2 +db 33, 233 +db 139, 22 +db 131, 198, 4 +db 137, 23 +db 131, 199, 4 +db 72 +db 117, 243 +db 243, 164 +db 138, 6 +db 70 +db 60, 16 +db 115, 64 +db 141, 87, 3 +db 57, 20, 36 +db 15, 130, 238, 1, 0, 0 +db 193, 232, 2 +db 138, 30 +db 141, 151, 255, 247, 255, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 59, 84, 36, 48 +db 15, 130, 218, 1, 0, 0 +db 138, 2 +db 136, 7 +db 138, 66, 1 +db 136, 71, 1 +db 138, 66, 2 +db 136, 71, 2 +db 1, 239 +db 233, 163, 0, 0, 0 +db 137, 246 +db 60, 64 +db 114, 68 +db 137, 193 +db 193, 232, 2 +db 141, 87, 255 +db 131, 224, 7 +db 138, 30 +db 193, 233, 5 +db 141, 4, 216 +db 70 +db 41, 194 +db 65 +db 57, 232 +db 115, 75 +db 233, 180, 0, 0, 0 +db 5, 255, 0, 0, 0 +db 141, 86, 3 +db 57, 84, 36, 4 +db 15, 130, 125, 1, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 231 +db 141, 76, 24, 33 +db 49, 192 +db 235, 19 +db 141, 118, 0 +db 60, 32 +db 15, 130, 200, 0, 0, 0 +db 131, 224, 31 +db 116, 225 +db 141, 72, 2 +db 102, 139, 6 +db 141, 87, 255 +db 193, 232, 2 +db 131, 198, 2 +db 41, 194 +db 57, 232 +db 114, 110 +db 59, 84, 36, 48 +db 15, 130, 77, 1, 0, 0 +db 141, 4, 15 +db 57, 4, 36 +db 15, 130, 58, 1, 0, 0 +db 137, 203 +db 193, 235, 2 +db 116, 17 +db 139, 2 +db 131, 194, 4 +db 137, 7 +db 131, 199, 4 +db 75 +db 117, 243 +db 33, 233 +db 116, 9 +db 138, 2 +db 66 +db 136, 7 +db 71 +db 73 +db 117, 247 +db 138, 70, 254 +db 33, 232 +db 15, 132, 196, 254, 255, 255 +db 141, 20, 7 +db 57, 20, 36 +db 15, 130, 2, 1, 0, 0 +db 141, 20, 6 +db 57, 84, 36, 4 +db 15, 130, 238, 0, 0, 0 +db 138, 14 +db 70 +db 136, 15 +db 71 +db 72 +db 117, 247 +db 138, 6 +db 70 +db 233, 42, 255, 255, 255 +db 137, 246 +db 59, 84, 36, 48 +db 15, 130, 223, 0, 0, 0 +db 141, 68, 15, 0 +db 57, 4, 36 +db 15, 130, 203, 0, 0, 0 +db 135, 214 +db 243, 164 +db 137, 214 +db 235, 170 +db 129, 193, 255, 0, 0, 0 +db 141, 86, 3 +db 57, 84, 36, 4 +db 15, 130, 169, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 230 +db 141, 76, 11, 9 +db 235, 21 +db 144 +db 60, 16 +db 114, 44 +db 137, 193 +db 131, 224, 8 +db 193, 224, 13 +db 131, 225, 7 +db 116, 225 +db 131, 193, 2 +db 102, 139, 6 +db 131, 198, 2 +db 141, 151, 0, 192, 255, 255 +db 193, 232, 2 +db 116, 57 +db 41, 194 +db 233, 38, 255, 255, 255 +db 141, 116, 38, 0 +db 141, 87, 2 +db 57, 20, 36 +db 114, 106 +db 193, 232, 2 +db 138, 30 +db 141, 87, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 59, 84, 36, 48 +db 114, 93 +db 138, 2 +db 136, 7 +db 138, 90, 1 +db 136, 95, 1 +db 131, 199, 2 +db 233, 43, 255, 255, 255 +db 131, 249, 3 +db 15, 149, 192 +db 59, 60, 36 +db 119, 57 +db 139, 84, 36, 40 +db 3, 84, 36, 44 +db 57, 214 +db 119, 38 +db 114, 29 +db 43, 124, 36, 48 +db 139, 84, 36, 52 +db 137, 58 +db 247, 216 +db 131, 196, 12 +db 90 +db 89 +db 91 +db 94 +db 95 +db 93 +db 195 +db 184, 1, 0, 0, 0 +db 235, 227 +db 184, 8, 0, 0, 0 +db 235, 220 +db 184, 4, 0, 0, 0 +db 235, 213 +db 184, 5, 0, 0, 0 +db 235, 206 +db 184, 6, 0, 0, 0 +db 235, 199 + +end diff --git a/DumpProto/lzo/i386/d_asm2/lzo1y_f1.asm b/DumpProto/lzo/i386/d_asm2/lzo1y_f1.asm new file mode 100644 index 0000000..9313cf2 --- /dev/null +++ b/DumpProto/lzo/i386/d_asm2/lzo1y_f1.asm @@ -0,0 +1,194 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +.386p +.model flat + +.code +public _lzo1y_decompress_asm_fast + +_lzo1y_decompress_asm_fast: +db 85 +db 87 +db 86 +db 83 +db 81 +db 82 +db 131, 236, 12 +db 252 +db 139, 116, 36, 40 +db 139, 124, 36, 48 +db 189, 3, 0, 0, 0 +db 49, 192 +db 49, 219 +db 172 +db 60, 17 +db 118, 27 +db 44, 14 +db 235, 34 +db 5, 255, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 244 +db 141, 68, 24, 21 +db 235, 16 +db 137, 246 +db 138, 6 +db 70 +db 60, 16 +db 115, 65 +db 8, 192 +db 116, 230 +db 131, 192, 6 +db 137, 193 +db 49, 232 +db 193, 233, 2 +db 33, 232 +db 139, 22 +db 131, 198, 4 +db 137, 23 +db 131, 199, 4 +db 73 +db 117, 243 +db 41, 198 +db 41, 199 +db 138, 6 +db 70 +db 60, 16 +db 115, 25 +db 193, 232, 2 +db 138, 30 +db 141, 151, 255, 251, 255, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 139, 10 +db 137, 15 +db 1, 239 +db 235, 110 +db 60, 64 +db 114, 52 +db 137, 193 +db 193, 232, 2 +db 141, 87, 255 +db 33, 232 +db 138, 30 +db 193, 233, 4 +db 141, 4, 152 +db 70 +db 41, 194 +db 131, 193, 2 +db 57, 232 +db 115, 54 +db 235, 110 +db 5, 255, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 244 +db 141, 76, 24, 36 +db 49, 192 +db 235, 14 +db 137, 246 +db 60, 32 +db 114, 116 +db 131, 224, 31 +db 116, 230 +db 141, 72, 5 +db 102, 139, 6 +db 141, 87, 255 +db 193, 232, 2 +db 131, 198, 2 +db 41, 194 +db 57, 232 +db 114, 58 +db 141, 68, 15, 253 +db 193, 233, 2 +db 139, 26 +db 131, 194, 4 +db 137, 31 +db 131, 199, 4 +db 73 +db 117, 243 +db 137, 199 +db 49, 219 +db 138, 70, 254 +db 33, 232 +db 15, 132, 63, 255, 255, 255 +db 139, 22 +db 1, 198 +db 137, 23 +db 1, 199 +db 138, 6 +db 70 +db 233, 119, 255, 255, 255 +db 141, 180, 38, 0, 0, 0, 0 +db 135, 214 +db 41, 233 +db 243, 164 +db 137, 214 +db 235, 212 +db 129, 193, 255, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 243 +db 141, 76, 11, 12 +db 235, 23 +db 141, 118, 0 +db 60, 16 +db 114, 44 +db 137, 193 +db 131, 224, 8 +db 193, 224, 13 +db 131, 225, 7 +db 116, 223 +db 131, 193, 5 +db 102, 139, 6 +db 131, 198, 2 +db 141, 151, 0, 192, 255, 255 +db 193, 232, 2 +db 116, 43 +db 41, 194 +db 233, 122, 255, 255, 255 +db 141, 116, 38, 0 +db 193, 232, 2 +db 138, 30 +db 141, 87, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 138, 2 +db 136, 7 +db 138, 90, 1 +db 136, 95, 1 +db 131, 199, 2 +db 233, 110, 255, 255, 255 +db 131, 249, 6 +db 15, 149, 192 +db 139, 84, 36, 40 +db 3, 84, 36, 44 +db 57, 214 +db 119, 38 +db 114, 29 +db 43, 124, 36, 48 +db 139, 84, 36, 52 +db 137, 58 +db 247, 216 +db 131, 196, 12 +db 90 +db 89 +db 91 +db 94 +db 95 +db 93 +db 195 +db 184, 1, 0, 0, 0 +db 235, 227 +db 184, 8, 0, 0, 0 +db 235, 220 +db 184, 4, 0, 0, 0 +db 235, 213 + +end diff --git a/DumpProto/lzo/i386/d_asm2/lzo1y_f2.asm b/DumpProto/lzo/i386/d_asm2/lzo1y_f2.asm new file mode 100644 index 0000000..ceee322 --- /dev/null +++ b/DumpProto/lzo/i386/d_asm2/lzo1y_f2.asm @@ -0,0 +1,250 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +.386p +.model flat + +.code +public _lzo1y_decompress_asm_fast_safe + +_lzo1y_decompress_asm_fast_safe: +db 85 +db 87 +db 86 +db 83 +db 81 +db 82 +db 131, 236, 12 +db 252 +db 139, 116, 36, 40 +db 139, 124, 36, 48 +db 189, 3, 0, 0, 0 +db 141, 70, 253 +db 3, 68, 36, 44 +db 137, 68, 36, 4 +db 137, 248 +db 139, 84, 36, 52 +db 3, 2 +db 137, 4, 36 +db 49, 192 +db 49, 219 +db 172 +db 60, 17 +db 118, 55 +db 44, 14 +db 235, 62 +db 5, 255, 0, 0, 0 +db 141, 84, 6, 18 +db 57, 84, 36, 4 +db 15, 130, 78, 2, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 230 +db 141, 68, 24, 21 +db 235, 30 +db 141, 182, 0, 0, 0, 0 +db 57, 116, 36, 4 +db 15, 130, 49, 2, 0, 0 +db 138, 6 +db 70 +db 60, 16 +db 115, 119 +db 8, 192 +db 116, 216 +db 131, 192, 6 +db 141, 84, 7, 253 +db 57, 20, 36 +db 15, 130, 29, 2, 0, 0 +db 141, 84, 6, 253 +db 57, 84, 36, 4 +db 15, 130, 8, 2, 0, 0 +db 137, 193 +db 49, 232 +db 193, 233, 2 +db 33, 232 +db 139, 22 +db 131, 198, 4 +db 137, 23 +db 131, 199, 4 +db 73 +db 117, 243 +db 41, 198 +db 41, 199 +db 138, 6 +db 70 +db 60, 16 +db 115, 52 +db 141, 87, 3 +db 57, 20, 36 +db 15, 130, 226, 1, 0, 0 +db 193, 232, 2 +db 138, 30 +db 141, 151, 255, 251, 255, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 59, 84, 36, 48 +db 15, 130, 206, 1, 0, 0 +db 139, 10 +db 137, 15 +db 1, 239 +db 233, 151, 0, 0, 0 +db 137, 246 +db 60, 64 +db 114, 68 +db 137, 193 +db 193, 232, 2 +db 141, 87, 255 +db 33, 232 +db 138, 30 +db 193, 233, 4 +db 141, 4, 152 +db 70 +db 41, 194 +db 131, 193, 2 +db 57, 232 +db 115, 74 +db 233, 171, 0, 0, 0 +db 5, 255, 0, 0, 0 +db 141, 86, 3 +db 57, 84, 36, 4 +db 15, 130, 124, 1, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 231 +db 141, 76, 24, 36 +db 49, 192 +db 235, 18 +db 137, 246 +db 60, 32 +db 15, 130, 200, 0, 0, 0 +db 131, 224, 31 +db 116, 226 +db 141, 72, 5 +db 102, 139, 6 +db 141, 87, 255 +db 193, 232, 2 +db 131, 198, 2 +db 41, 194 +db 57, 232 +db 114, 102 +db 59, 84, 36, 48 +db 15, 130, 77, 1, 0, 0 +db 141, 68, 15, 253 +db 193, 233, 2 +db 57, 4, 36 +db 15, 130, 54, 1, 0, 0 +db 139, 26 +db 131, 194, 4 +db 137, 31 +db 131, 199, 4 +db 73 +db 117, 243 +db 137, 199 +db 49, 219 +db 138, 70, 254 +db 33, 232 +db 15, 132, 216, 254, 255, 255 +db 141, 20, 7 +db 57, 20, 36 +db 15, 130, 14, 1, 0, 0 +db 141, 20, 6 +db 57, 84, 36, 4 +db 15, 130, 250, 0, 0, 0 +db 139, 22 +db 1, 198 +db 137, 23 +db 1, 199 +db 138, 6 +db 70 +db 233, 55, 255, 255, 255 +db 141, 180, 38, 0, 0, 0, 0 +db 59, 84, 36, 48 +db 15, 130, 231, 0, 0, 0 +db 141, 68, 15, 253 +db 57, 4, 36 +db 15, 130, 211, 0, 0, 0 +db 135, 214 +db 41, 233 +db 243, 164 +db 137, 214 +db 235, 164 +db 129, 193, 255, 0, 0, 0 +db 141, 86, 3 +db 57, 84, 36, 4 +db 15, 130, 175, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 230 +db 141, 76, 11, 12 +db 235, 27 +db 141, 180, 38, 0, 0, 0, 0 +db 60, 16 +db 114, 44 +db 137, 193 +db 131, 224, 8 +db 193, 224, 13 +db 131, 225, 7 +db 116, 219 +db 131, 193, 5 +db 102, 139, 6 +db 131, 198, 2 +db 141, 151, 0, 192, 255, 255 +db 193, 232, 2 +db 116, 57 +db 41, 194 +db 233, 38, 255, 255, 255 +db 141, 116, 38, 0 +db 141, 87, 2 +db 57, 20, 36 +db 114, 106 +db 193, 232, 2 +db 138, 30 +db 141, 87, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 59, 84, 36, 48 +db 114, 93 +db 138, 2 +db 136, 7 +db 138, 90, 1 +db 136, 95, 1 +db 131, 199, 2 +db 233, 31, 255, 255, 255 +db 131, 249, 6 +db 15, 149, 192 +db 59, 60, 36 +db 119, 57 +db 139, 84, 36, 40 +db 3, 84, 36, 44 +db 57, 214 +db 119, 38 +db 114, 29 +db 43, 124, 36, 48 +db 139, 84, 36, 52 +db 137, 58 +db 247, 216 +db 131, 196, 12 +db 90 +db 89 +db 91 +db 94 +db 95 +db 93 +db 195 +db 184, 1, 0, 0, 0 +db 235, 227 +db 184, 8, 0, 0, 0 +db 235, 220 +db 184, 4, 0, 0, 0 +db 235, 213 +db 184, 5, 0, 0, 0 +db 235, 206 +db 184, 6, 0, 0, 0 +db 235, 199 + +end diff --git a/DumpProto/lzo/i386/d_asm2/lzo1y_s1.asm b/DumpProto/lzo/i386/d_asm2/lzo1y_s1.asm new file mode 100644 index 0000000..1c154ae --- /dev/null +++ b/DumpProto/lzo/i386/d_asm2/lzo1y_s1.asm @@ -0,0 +1,209 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +.386p +.model flat + +.code +public _lzo1y_decompress_asm + +_lzo1y_decompress_asm: +db 85 +db 87 +db 86 +db 83 +db 81 +db 82 +db 131, 236, 12 +db 252 +db 139, 116, 36, 40 +db 139, 124, 36, 48 +db 189, 3, 0, 0, 0 +db 49, 192 +db 49, 219 +db 172 +db 60, 17 +db 118, 35 +db 44, 17 +db 60, 4 +db 115, 40 +db 137, 193 +db 235, 56 +db 5, 255, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 244 +db 141, 68, 24, 18 +db 235, 18 +db 141, 116, 38, 0 +db 138, 6 +db 70 +db 60, 16 +db 115, 73 +db 8, 192 +db 116, 228 +db 131, 192, 3 +db 137, 193 +db 193, 232, 2 +db 33, 233 +db 139, 22 +db 131, 198, 4 +db 137, 23 +db 131, 199, 4 +db 72 +db 117, 243 +db 243, 164 +db 138, 6 +db 70 +db 60, 16 +db 115, 37 +db 193, 232, 2 +db 138, 30 +db 141, 151, 255, 251, 255, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 138, 2 +db 136, 7 +db 138, 66, 1 +db 136, 71, 1 +db 138, 66, 2 +db 136, 71, 2 +db 1, 239 +db 235, 119 +db 60, 64 +db 114, 52 +db 137, 193 +db 193, 232, 2 +db 141, 87, 255 +db 33, 232 +db 138, 30 +db 193, 233, 4 +db 141, 4, 152 +db 70 +db 41, 194 +db 73 +db 57, 232 +db 115, 56 +db 235, 120 +db 5, 255, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 244 +db 141, 76, 24, 33 +db 49, 192 +db 235, 16 +db 141, 116, 38, 0 +db 60, 32 +db 114, 124 +db 131, 224, 31 +db 116, 228 +db 141, 72, 2 +db 102, 139, 6 +db 141, 87, 255 +db 193, 232, 2 +db 131, 198, 2 +db 41, 194 +db 57, 232 +db 114, 66 +db 137, 203 +db 193, 235, 2 +db 116, 17 +db 139, 2 +db 131, 194, 4 +db 137, 7 +db 131, 199, 4 +db 75 +db 117, 243 +db 33, 233 +db 116, 9 +db 138, 2 +db 66 +db 136, 7 +db 71 +db 73 +db 117, 247 +db 138, 70, 254 +db 33, 232 +db 15, 132, 46, 255, 255, 255 +db 138, 14 +db 70 +db 136, 15 +db 71 +db 72 +db 117, 247 +db 138, 6 +db 70 +db 233, 109, 255, 255, 255 +db 144 +db 141, 116, 38, 0 +db 135, 214 +db 243, 164 +db 137, 214 +db 235, 215 +db 129, 193, 255, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 243 +db 141, 76, 11, 9 +db 235, 25 +db 144 +db 141, 116, 38, 0 +db 60, 16 +db 114, 44 +db 137, 193 +db 131, 224, 8 +db 193, 224, 13 +db 131, 225, 7 +db 116, 221 +db 131, 193, 2 +db 102, 139, 6 +db 131, 198, 2 +db 141, 151, 0, 192, 255, 255 +db 193, 232, 2 +db 116, 43 +db 41, 194 +db 233, 114, 255, 255, 255 +db 141, 116, 38, 0 +db 193, 232, 2 +db 138, 30 +db 141, 87, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 138, 2 +db 136, 7 +db 138, 90, 1 +db 136, 95, 1 +db 131, 199, 2 +db 233, 111, 255, 255, 255 +db 131, 249, 3 +db 15, 149, 192 +db 139, 84, 36, 40 +db 3, 84, 36, 44 +db 57, 214 +db 119, 38 +db 114, 29 +db 43, 124, 36, 48 +db 139, 84, 36, 52 +db 137, 58 +db 247, 216 +db 131, 196, 12 +db 90 +db 89 +db 91 +db 94 +db 95 +db 93 +db 195 +db 184, 1, 0, 0, 0 +db 235, 227 +db 184, 8, 0, 0, 0 +db 235, 220 +db 184, 4, 0, 0, 0 +db 235, 213 + +end diff --git a/DumpProto/lzo/i386/d_asm2/lzo1y_s2.asm b/DumpProto/lzo/i386/d_asm2/lzo1y_s2.asm new file mode 100644 index 0000000..428a05f --- /dev/null +++ b/DumpProto/lzo/i386/d_asm2/lzo1y_s2.asm @@ -0,0 +1,270 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +.386p +.model flat + +.code +public _lzo1y_decompress_asm_safe + +_lzo1y_decompress_asm_safe: +db 85 +db 87 +db 86 +db 83 +db 81 +db 82 +db 131, 236, 12 +db 252 +db 139, 116, 36, 40 +db 139, 124, 36, 48 +db 189, 3, 0, 0, 0 +db 141, 70, 253 +db 3, 68, 36, 44 +db 137, 68, 36, 4 +db 137, 248 +db 139, 84, 36, 52 +db 3, 2 +db 137, 4, 36 +db 49, 192 +db 49, 219 +db 172 +db 60, 17 +db 118, 87 +db 44, 17 +db 60, 4 +db 115, 92 +db 141, 20, 7 +db 57, 20, 36 +db 15, 130, 130, 2, 0, 0 +db 141, 20, 6 +db 57, 84, 36, 4 +db 15, 130, 110, 2, 0, 0 +db 137, 193 +db 235, 110 +db 5, 255, 0, 0, 0 +db 141, 84, 6, 18 +db 57, 84, 36, 4 +db 15, 130, 87, 2, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 230 +db 141, 68, 24, 18 +db 235, 31 +db 141, 180, 38, 0, 0, 0, 0 +db 57, 116, 36, 4 +db 15, 130, 57, 2, 0, 0 +db 138, 6 +db 70 +db 60, 16 +db 115, 127 +db 8, 192 +db 116, 215 +db 131, 192, 3 +db 141, 84, 7, 0 +db 57, 20, 36 +db 15, 130, 37, 2, 0, 0 +db 141, 84, 6, 0 +db 57, 84, 36, 4 +db 15, 130, 16, 2, 0, 0 +db 137, 193 +db 193, 232, 2 +db 33, 233 +db 139, 22 +db 131, 198, 4 +db 137, 23 +db 131, 199, 4 +db 72 +db 117, 243 +db 243, 164 +db 138, 6 +db 70 +db 60, 16 +db 115, 64 +db 141, 87, 3 +db 57, 20, 36 +db 15, 130, 238, 1, 0, 0 +db 193, 232, 2 +db 138, 30 +db 141, 151, 255, 251, 255, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 59, 84, 36, 48 +db 15, 130, 218, 1, 0, 0 +db 138, 2 +db 136, 7 +db 138, 66, 1 +db 136, 71, 1 +db 138, 66, 2 +db 136, 71, 2 +db 1, 239 +db 233, 163, 0, 0, 0 +db 137, 246 +db 60, 64 +db 114, 68 +db 137, 193 +db 193, 232, 2 +db 141, 87, 255 +db 33, 232 +db 138, 30 +db 193, 233, 4 +db 141, 4, 152 +db 70 +db 41, 194 +db 73 +db 57, 232 +db 115, 76 +db 233, 181, 0, 0, 0 +db 5, 255, 0, 0, 0 +db 141, 86, 3 +db 57, 84, 36, 4 +db 15, 130, 126, 1, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 231 +db 141, 76, 24, 33 +db 49, 192 +db 235, 20 +db 141, 116, 38, 0 +db 60, 32 +db 15, 130, 200, 0, 0, 0 +db 131, 224, 31 +db 116, 224 +db 141, 72, 2 +db 102, 139, 6 +db 141, 87, 255 +db 193, 232, 2 +db 131, 198, 2 +db 41, 194 +db 57, 232 +db 114, 110 +db 59, 84, 36, 48 +db 15, 130, 77, 1, 0, 0 +db 141, 4, 15 +db 57, 4, 36 +db 15, 130, 58, 1, 0, 0 +db 137, 203 +db 193, 235, 2 +db 116, 17 +db 139, 2 +db 131, 194, 4 +db 137, 7 +db 131, 199, 4 +db 75 +db 117, 243 +db 33, 233 +db 116, 9 +db 138, 2 +db 66 +db 136, 7 +db 71 +db 73 +db 117, 247 +db 138, 70, 254 +db 33, 232 +db 15, 132, 196, 254, 255, 255 +db 141, 20, 7 +db 57, 20, 36 +db 15, 130, 2, 1, 0, 0 +db 141, 20, 6 +db 57, 84, 36, 4 +db 15, 130, 238, 0, 0, 0 +db 138, 14 +db 70 +db 136, 15 +db 71 +db 72 +db 117, 247 +db 138, 6 +db 70 +db 233, 42, 255, 255, 255 +db 137, 246 +db 59, 84, 36, 48 +db 15, 130, 223, 0, 0, 0 +db 141, 68, 15, 0 +db 57, 4, 36 +db 15, 130, 203, 0, 0, 0 +db 135, 214 +db 243, 164 +db 137, 214 +db 235, 170 +db 129, 193, 255, 0, 0, 0 +db 141, 86, 3 +db 57, 84, 36, 4 +db 15, 130, 169, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 230 +db 141, 76, 11, 9 +db 235, 21 +db 144 +db 60, 16 +db 114, 44 +db 137, 193 +db 131, 224, 8 +db 193, 224, 13 +db 131, 225, 7 +db 116, 225 +db 131, 193, 2 +db 102, 139, 6 +db 131, 198, 2 +db 141, 151, 0, 192, 255, 255 +db 193, 232, 2 +db 116, 57 +db 41, 194 +db 233, 38, 255, 255, 255 +db 141, 116, 38, 0 +db 141, 87, 2 +db 57, 20, 36 +db 114, 106 +db 193, 232, 2 +db 138, 30 +db 141, 87, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 59, 84, 36, 48 +db 114, 93 +db 138, 2 +db 136, 7 +db 138, 90, 1 +db 136, 95, 1 +db 131, 199, 2 +db 233, 43, 255, 255, 255 +db 131, 249, 3 +db 15, 149, 192 +db 59, 60, 36 +db 119, 57 +db 139, 84, 36, 40 +db 3, 84, 36, 44 +db 57, 214 +db 119, 38 +db 114, 29 +db 43, 124, 36, 48 +db 139, 84, 36, 52 +db 137, 58 +db 247, 216 +db 131, 196, 12 +db 90 +db 89 +db 91 +db 94 +db 95 +db 93 +db 195 +db 184, 1, 0, 0, 0 +db 235, 227 +db 184, 8, 0, 0, 0 +db 235, 220 +db 184, 4, 0, 0, 0 +db 235, 213 +db 184, 5, 0, 0, 0 +db 235, 206 +db 184, 6, 0, 0, 0 +db 235, 199 + +end diff --git a/DumpProto/lzo/i386/d_asm3/lzo1c_s1.asm b/DumpProto/lzo/i386/d_asm3/lzo1c_s1.asm new file mode 100644 index 0000000..96283ff --- /dev/null +++ b/DumpProto/lzo/i386/d_asm3/lzo1c_s1.asm @@ -0,0 +1,139 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +BITS 32 + +SECTION .text +GLOBAL _lzo1c_decompress_asm + +_lzo1c_decompress_asm: +db 85 +db 87 +db 86 +db 83 +db 81 +db 82 +db 131, 236, 12 +db 252 +db 139, 116, 36, 40 +db 139, 124, 36, 48 +db 189, 3, 0, 0, 0 +db 144 +db 49, 192 +db 138, 6 +db 70 +db 60, 32 +db 115, 15 +db 8, 192 +db 116, 51 +db 137, 193 +db 243, 164 +db 138, 6 +db 70 +db 60, 32 +db 114, 72 +db 60, 64 +db 114, 93 +db 137, 193 +db 36, 31 +db 141, 87, 255 +db 193, 233, 5 +db 41, 194 +db 138, 6 +db 70 +db 193, 224, 5 +db 41, 194 +db 65 +db 135, 242 +db 243, 164 +db 137, 214 +db 235, 199 +db 141, 180, 38, 0, 0, 0, 0 +db 138, 6 +db 70 +db 141, 72, 32 +db 60, 248 +db 114, 197 +db 185, 24, 1, 0, 0 +db 44, 248 +db 116, 6 +db 145 +db 48, 192 +db 211, 224 +db 145 +db 243, 164 +db 235, 163 +db 141, 118, 0 +db 141, 87, 255 +db 41, 194 +db 138, 6 +db 70 +db 193, 224, 5 +db 41, 194 +db 135, 242 +db 164 +db 164 +db 164 +db 137, 214 +db 164 +db 49, 192 +db 235, 152 +db 36, 31 +db 137, 193 +db 117, 19 +db 177, 31 +db 138, 6 +db 70 +db 8, 192 +db 117, 8 +db 129, 193, 255, 0, 0, 0 +db 235, 241 +db 1, 193 +db 138, 6 +db 70 +db 137, 195 +db 36, 63 +db 137, 250 +db 41, 194 +db 138, 6 +db 70 +db 193, 224, 6 +db 41, 194 +db 57, 250 +db 116, 27 +db 135, 214 +db 141, 73, 3 +db 243, 164 +db 137, 214 +db 49, 192 +db 193, 235, 6 +db 137, 217 +db 15, 133, 80, 255, 255, 255 +db 233, 60, 255, 255, 255 +db 131, 249, 1 +db 15, 149, 192 +db 139, 84, 36, 40 +db 3, 84, 36, 44 +db 57, 214 +db 119, 38 +db 114, 29 +db 43, 124, 36, 48 +db 139, 84, 36, 52 +db 137, 58 +db 247, 216 +db 131, 196, 12 +db 90 +db 89 +db 91 +db 94 +db 95 +db 93 +db 195 +db 184, 1, 0, 0, 0 +db 235, 227 +db 184, 8, 0, 0, 0 +db 235, 220 +db 184, 4, 0, 0, 0 +db 235, 213 + +end diff --git a/DumpProto/lzo/i386/d_asm3/lzo1c_s2.asm b/DumpProto/lzo/i386/d_asm3/lzo1c_s2.asm new file mode 100644 index 0000000..f1e3228 --- /dev/null +++ b/DumpProto/lzo/i386/d_asm3/lzo1c_s2.asm @@ -0,0 +1,180 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +BITS 32 + +SECTION .text +GLOBAL _lzo1c_decompress_asm_safe + +_lzo1c_decompress_asm_safe: +db 85 +db 87 +db 86 +db 83 +db 81 +db 82 +db 131, 236, 12 +db 252 +db 139, 116, 36, 40 +db 139, 124, 36, 48 +db 189, 3, 0, 0, 0 +db 141, 70, 253 +db 3, 68, 36, 44 +db 137, 68, 36, 4 +db 137, 248 +db 139, 84, 36, 52 +db 3, 2 +db 137, 4, 36 +db 141, 118, 0 +db 49, 192 +db 138, 6 +db 70 +db 60, 32 +db 115, 40 +db 8, 192 +db 116, 99 +db 137, 193 +db 141, 28, 15 +db 57, 28, 36 +db 15, 130, 107, 1, 0, 0 +db 141, 28, 14 +db 57, 92, 36, 4 +db 15, 130, 87, 1, 0, 0 +db 243, 164 +db 138, 6 +db 70 +db 60, 32 +db 114, 127 +db 60, 64 +db 15, 130, 169, 0, 0, 0 +db 137, 193 +db 36, 31 +db 141, 87, 255 +db 193, 233, 5 +db 41, 194 +db 138, 6 +db 70 +db 193, 224, 5 +db 41, 194 +db 65 +db 135, 242 +db 59, 116, 36, 48 +db 15, 130, 51, 1, 0, 0 +db 141, 28, 15 +db 57, 28, 36 +db 15, 130, 32, 1, 0, 0 +db 243, 164 +db 137, 214 +db 235, 148 +db 141, 116, 38, 0 +db 138, 6 +db 70 +db 141, 72, 32 +db 60, 248 +db 114, 149 +db 185, 24, 1, 0, 0 +db 44, 248 +db 116, 6 +db 145 +db 48, 192 +db 211, 224 +db 145 +db 141, 28, 15 +db 57, 28, 36 +db 15, 130, 241, 0, 0, 0 +db 141, 28, 14 +db 57, 92, 36, 4 +db 15, 130, 221, 0, 0, 0 +db 243, 164 +db 233, 87, 255, 255, 255 +db 141, 180, 38, 0, 0, 0, 0 +db 141, 87, 255 +db 41, 194 +db 138, 6 +db 70 +db 193, 224, 5 +db 41, 194 +db 135, 242 +db 59, 116, 36, 48 +db 15, 130, 196, 0, 0, 0 +db 141, 95, 4 +db 57, 28, 36 +db 15, 130, 177, 0, 0, 0 +db 164 +db 164 +db 164 +db 137, 214 +db 164 +db 49, 192 +db 233, 72, 255, 255, 255 +db 36, 31 +db 137, 193 +db 117, 26 +db 177, 31 +db 138, 6 +db 70 +db 8, 192 +db 117, 15 +db 129, 193, 255, 0, 0, 0 +db 235, 241 +db 141, 180, 38, 0, 0, 0, 0 +db 1, 193 +db 138, 6 +db 70 +db 137, 195 +db 36, 63 +db 137, 250 +db 41, 194 +db 138, 6 +db 70 +db 193, 224, 6 +db 41, 194 +db 57, 250 +db 116, 41 +db 135, 214 +db 141, 73, 3 +db 59, 116, 36, 48 +db 114, 105 +db 141, 4, 15 +db 57, 4, 36 +db 114, 90 +db 243, 164 +db 137, 214 +db 49, 192 +db 193, 235, 6 +db 137, 217 +db 15, 133, 210, 254, 255, 255 +db 233, 190, 254, 255, 255 +db 131, 249, 1 +db 15, 149, 192 +db 59, 60, 36 +db 119, 57 +db 139, 84, 36, 40 +db 3, 84, 36, 44 +db 57, 214 +db 119, 38 +db 114, 29 +db 43, 124, 36, 48 +db 139, 84, 36, 52 +db 137, 58 +db 247, 216 +db 131, 196, 12 +db 90 +db 89 +db 91 +db 94 +db 95 +db 93 +db 195 +db 184, 1, 0, 0, 0 +db 235, 227 +db 184, 8, 0, 0, 0 +db 235, 220 +db 184, 4, 0, 0, 0 +db 235, 213 +db 184, 5, 0, 0, 0 +db 235, 206 +db 184, 6, 0, 0, 0 +db 235, 199 + +end diff --git a/DumpProto/lzo/i386/d_asm3/lzo1f_f1.asm b/DumpProto/lzo/i386/d_asm3/lzo1f_f1.asm new file mode 100644 index 0000000..3792e2a --- /dev/null +++ b/DumpProto/lzo/i386/d_asm3/lzo1f_f1.asm @@ -0,0 +1,140 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +BITS 32 + +SECTION .text +GLOBAL _lzo1f_decompress_asm_fast + +_lzo1f_decompress_asm_fast: +db 85 +db 87 +db 86 +db 83 +db 81 +db 82 +db 131, 236, 12 +db 252 +db 139, 116, 36, 40 +db 139, 124, 36, 48 +db 189, 3, 0, 0, 0 +db 144 +db 49, 192 +db 138, 6 +db 70 +db 60, 31 +db 119, 51 +db 8, 192 +db 137, 193 +db 117, 19 +db 138, 6 +db 70 +db 8, 192 +db 117, 8 +db 129, 193, 255, 0, 0, 0 +db 235, 241 +db 141, 76, 8, 31 +db 136, 200 +db 193, 233, 2 +db 243, 165 +db 36, 3 +db 116, 8 +db 139, 30 +db 1, 198 +db 137, 31 +db 1, 199 +db 138, 6 +db 70 +db 60, 31 +db 118, 88 +db 60, 223 +db 15, 135, 132, 0, 0, 0 +db 137, 193 +db 193, 232, 2 +db 141, 87, 255 +db 36, 7 +db 193, 233, 5 +db 137, 195 +db 138, 6 +db 141, 4, 195 +db 70 +db 41, 194 +db 131, 193, 2 +db 135, 214 +db 131, 249, 6 +db 114, 16 +db 131, 248, 4 +db 114, 11 +db 136, 200 +db 193, 233, 2 +db 243, 165 +db 36, 3 +db 136, 193 +db 243, 164 +db 137, 214 +db 138, 78, 254 +db 131, 225, 3 +db 15, 132, 123, 255, 255, 255 +db 139, 6 +db 1, 206 +db 137, 7 +db 1, 207 +db 49, 192 +db 138, 6 +db 70 +db 235, 164 +db 193, 232, 2 +db 141, 151, 255, 247, 255, 255 +db 137, 193 +db 138, 6 +db 70 +db 141, 4, 193 +db 41, 194 +db 139, 2 +db 137, 7 +db 131, 199, 3 +db 235, 201 +db 138, 6 +db 70 +db 8, 192 +db 117, 8 +db 129, 193, 255, 0, 0, 0 +db 235, 241 +db 141, 76, 8, 31 +db 235, 9 +db 141, 118, 0 +db 36, 31 +db 137, 193 +db 116, 226 +db 137, 250 +db 102, 139, 6 +db 131, 198, 2 +db 193, 232, 2 +db 15, 133, 122, 255, 255, 255 +db 131, 249, 1 +db 15, 149, 192 +db 139, 84, 36, 40 +db 3, 84, 36, 44 +db 57, 214 +db 119, 38 +db 114, 29 +db 43, 124, 36, 48 +db 139, 84, 36, 52 +db 137, 58 +db 247, 216 +db 131, 196, 12 +db 90 +db 89 +db 91 +db 94 +db 95 +db 93 +db 195 +db 184, 1, 0, 0, 0 +db 235, 227 +db 184, 8, 0, 0, 0 +db 235, 220 +db 184, 4, 0, 0, 0 +db 235, 213 + +end diff --git a/DumpProto/lzo/i386/d_asm3/lzo1f_f2.asm b/DumpProto/lzo/i386/d_asm3/lzo1f_f2.asm new file mode 100644 index 0000000..18cbb22 --- /dev/null +++ b/DumpProto/lzo/i386/d_asm3/lzo1f_f2.asm @@ -0,0 +1,169 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +BITS 32 + +SECTION .text +GLOBAL _lzo1f_decompress_asm_fast_safe + +_lzo1f_decompress_asm_fast_safe: +db 85 +db 87 +db 86 +db 83 +db 81 +db 82 +db 131, 236, 12 +db 252 +db 139, 116, 36, 40 +db 139, 124, 36, 48 +db 189, 3, 0, 0, 0 +db 141, 70, 253 +db 3, 68, 36, 44 +db 137, 68, 36, 4 +db 137, 248 +db 139, 84, 36, 52 +db 3, 2 +db 137, 4, 36 +db 141, 118, 0 +db 49, 192 +db 138, 6 +db 70 +db 60, 31 +db 119, 76 +db 8, 192 +db 137, 193 +db 117, 19 +db 138, 6 +db 70 +db 8, 192 +db 117, 8 +db 129, 193, 255, 0, 0, 0 +db 235, 241 +db 141, 76, 8, 31 +db 141, 28, 15 +db 57, 28, 36 +db 15, 130, 61, 1, 0, 0 +db 141, 28, 14 +db 57, 92, 36, 4 +db 15, 130, 41, 1, 0, 0 +db 136, 200 +db 193, 233, 2 +db 243, 165 +db 36, 3 +db 116, 8 +db 139, 30 +db 1, 198 +db 137, 31 +db 1, 199 +db 138, 6 +db 70 +db 60, 31 +db 118, 110 +db 60, 223 +db 15, 135, 179, 0, 0, 0 +db 137, 193 +db 193, 232, 2 +db 141, 87, 255 +db 36, 7 +db 193, 233, 5 +db 137, 195 +db 138, 6 +db 141, 4, 195 +db 70 +db 41, 194 +db 131, 193, 2 +db 135, 214 +db 59, 116, 36, 48 +db 15, 130, 239, 0, 0, 0 +db 141, 28, 15 +db 57, 28, 36 +db 15, 130, 220, 0, 0, 0 +db 131, 249, 6 +db 114, 16 +db 131, 248, 4 +db 114, 11 +db 136, 200 +db 193, 233, 2 +db 243, 165 +db 36, 3 +db 136, 193 +db 243, 164 +db 137, 214 +db 138, 78, 254 +db 131, 225, 3 +db 15, 132, 76, 255, 255, 255 +db 139, 6 +db 1, 206 +db 137, 7 +db 1, 207 +db 49, 192 +db 138, 6 +db 70 +db 235, 142 +db 141, 87, 3 +db 57, 20, 36 +db 15, 130, 156, 0, 0, 0 +db 193, 232, 2 +db 141, 151, 255, 247, 255, 255 +db 137, 193 +db 138, 6 +db 70 +db 141, 4, 193 +db 41, 194 +db 59, 84, 36, 48 +db 15, 130, 134, 0, 0, 0 +db 139, 2 +db 137, 7 +db 131, 199, 3 +db 235, 179 +db 138, 6 +db 70 +db 8, 192 +db 117, 8 +db 129, 193, 255, 0, 0, 0 +db 235, 241 +db 141, 76, 8, 31 +db 235, 12 +db 141, 182, 0, 0, 0, 0 +db 36, 31 +db 137, 193 +db 116, 223 +db 137, 250 +db 102, 139, 6 +db 131, 198, 2 +db 193, 232, 2 +db 15, 133, 75, 255, 255, 255 +db 131, 249, 1 +db 15, 149, 192 +db 59, 60, 36 +db 119, 57 +db 139, 84, 36, 40 +db 3, 84, 36, 44 +db 57, 214 +db 119, 38 +db 114, 29 +db 43, 124, 36, 48 +db 139, 84, 36, 52 +db 137, 58 +db 247, 216 +db 131, 196, 12 +db 90 +db 89 +db 91 +db 94 +db 95 +db 93 +db 195 +db 184, 1, 0, 0, 0 +db 235, 227 +db 184, 8, 0, 0, 0 +db 235, 220 +db 184, 4, 0, 0, 0 +db 235, 213 +db 184, 5, 0, 0, 0 +db 235, 206 +db 184, 6, 0, 0, 0 +db 235, 199 + +end diff --git a/DumpProto/lzo/i386/d_asm3/lzo1x_f1.asm b/DumpProto/lzo/i386/d_asm3/lzo1x_f1.asm new file mode 100644 index 0000000..d827e89 --- /dev/null +++ b/DumpProto/lzo/i386/d_asm3/lzo1x_f1.asm @@ -0,0 +1,193 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +BITS 32 + +SECTION .text +GLOBAL _lzo1x_decompress_asm_fast + +_lzo1x_decompress_asm_fast: +db 85 +db 87 +db 86 +db 83 +db 81 +db 82 +db 131, 236, 12 +db 252 +db 139, 116, 36, 40 +db 139, 124, 36, 48 +db 189, 3, 0, 0, 0 +db 49, 192 +db 49, 219 +db 172 +db 60, 17 +db 118, 27 +db 44, 14 +db 235, 34 +db 5, 255, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 244 +db 141, 68, 24, 21 +db 235, 16 +db 137, 246 +db 138, 6 +db 70 +db 60, 16 +db 115, 65 +db 8, 192 +db 116, 230 +db 131, 192, 6 +db 137, 193 +db 49, 232 +db 193, 233, 2 +db 33, 232 +db 139, 22 +db 131, 198, 4 +db 137, 23 +db 131, 199, 4 +db 73 +db 117, 243 +db 41, 198 +db 41, 199 +db 138, 6 +db 70 +db 60, 16 +db 115, 25 +db 193, 232, 2 +db 138, 30 +db 141, 151, 255, 247, 255, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 139, 10 +db 137, 15 +db 1, 239 +db 235, 110 +db 60, 64 +db 114, 52 +db 137, 193 +db 193, 232, 2 +db 141, 87, 255 +db 131, 224, 7 +db 138, 30 +db 193, 233, 5 +db 141, 4, 216 +db 70 +db 41, 194 +db 131, 193, 4 +db 57, 232 +db 115, 53 +db 235, 109 +db 5, 255, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 244 +db 141, 76, 24, 36 +db 49, 192 +db 235, 13 +db 144 +db 60, 32 +db 114, 116 +db 131, 224, 31 +db 116, 231 +db 141, 72, 5 +db 102, 139, 6 +db 141, 87, 255 +db 193, 232, 2 +db 131, 198, 2 +db 41, 194 +db 57, 232 +db 114, 58 +db 141, 68, 15, 253 +db 193, 233, 2 +db 139, 26 +db 131, 194, 4 +db 137, 31 +db 131, 199, 4 +db 73 +db 117, 243 +db 137, 199 +db 49, 219 +db 138, 70, 254 +db 33, 232 +db 15, 132, 63, 255, 255, 255 +db 139, 22 +db 1, 198 +db 137, 23 +db 1, 199 +db 138, 6 +db 70 +db 233, 119, 255, 255, 255 +db 141, 180, 38, 0, 0, 0, 0 +db 135, 214 +db 41, 233 +db 243, 164 +db 137, 214 +db 235, 212 +db 129, 193, 255, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 243 +db 141, 76, 11, 12 +db 235, 23 +db 141, 118, 0 +db 60, 16 +db 114, 44 +db 137, 193 +db 131, 224, 8 +db 193, 224, 13 +db 131, 225, 7 +db 116, 223 +db 131, 193, 5 +db 102, 139, 6 +db 131, 198, 2 +db 141, 151, 0, 192, 255, 255 +db 193, 232, 2 +db 116, 43 +db 41, 194 +db 233, 122, 255, 255, 255 +db 141, 116, 38, 0 +db 193, 232, 2 +db 138, 30 +db 141, 87, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 138, 2 +db 136, 7 +db 138, 90, 1 +db 136, 95, 1 +db 131, 199, 2 +db 233, 110, 255, 255, 255 +db 131, 249, 6 +db 15, 149, 192 +db 139, 84, 36, 40 +db 3, 84, 36, 44 +db 57, 214 +db 119, 38 +db 114, 29 +db 43, 124, 36, 48 +db 139, 84, 36, 52 +db 137, 58 +db 247, 216 +db 131, 196, 12 +db 90 +db 89 +db 91 +db 94 +db 95 +db 93 +db 195 +db 184, 1, 0, 0, 0 +db 235, 227 +db 184, 8, 0, 0, 0 +db 235, 220 +db 184, 4, 0, 0, 0 +db 235, 213 + +end diff --git a/DumpProto/lzo/i386/d_asm3/lzo1x_f2.asm b/DumpProto/lzo/i386/d_asm3/lzo1x_f2.asm new file mode 100644 index 0000000..a2c666b --- /dev/null +++ b/DumpProto/lzo/i386/d_asm3/lzo1x_f2.asm @@ -0,0 +1,249 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +BITS 32 + +SECTION .text +GLOBAL _lzo1x_decompress_asm_fast_safe + +_lzo1x_decompress_asm_fast_safe: +db 85 +db 87 +db 86 +db 83 +db 81 +db 82 +db 131, 236, 12 +db 252 +db 139, 116, 36, 40 +db 139, 124, 36, 48 +db 189, 3, 0, 0, 0 +db 141, 70, 253 +db 3, 68, 36, 44 +db 137, 68, 36, 4 +db 137, 248 +db 139, 84, 36, 52 +db 3, 2 +db 137, 4, 36 +db 49, 192 +db 49, 219 +db 172 +db 60, 17 +db 118, 55 +db 44, 14 +db 235, 62 +db 5, 255, 0, 0, 0 +db 141, 84, 6, 18 +db 57, 84, 36, 4 +db 15, 130, 78, 2, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 230 +db 141, 68, 24, 21 +db 235, 30 +db 141, 182, 0, 0, 0, 0 +db 57, 116, 36, 4 +db 15, 130, 49, 2, 0, 0 +db 138, 6 +db 70 +db 60, 16 +db 115, 119 +db 8, 192 +db 116, 216 +db 131, 192, 6 +db 141, 84, 7, 253 +db 57, 20, 36 +db 15, 130, 29, 2, 0, 0 +db 141, 84, 6, 253 +db 57, 84, 36, 4 +db 15, 130, 8, 2, 0, 0 +db 137, 193 +db 49, 232 +db 193, 233, 2 +db 33, 232 +db 139, 22 +db 131, 198, 4 +db 137, 23 +db 131, 199, 4 +db 73 +db 117, 243 +db 41, 198 +db 41, 199 +db 138, 6 +db 70 +db 60, 16 +db 115, 52 +db 141, 87, 3 +db 57, 20, 36 +db 15, 130, 226, 1, 0, 0 +db 193, 232, 2 +db 138, 30 +db 141, 151, 255, 247, 255, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 59, 84, 36, 48 +db 15, 130, 206, 1, 0, 0 +db 139, 10 +db 137, 15 +db 1, 239 +db 233, 151, 0, 0, 0 +db 137, 246 +db 60, 64 +db 114, 68 +db 137, 193 +db 193, 232, 2 +db 141, 87, 255 +db 131, 224, 7 +db 138, 30 +db 193, 233, 5 +db 141, 4, 216 +db 70 +db 41, 194 +db 131, 193, 4 +db 57, 232 +db 115, 73 +db 233, 170, 0, 0, 0 +db 5, 255, 0, 0, 0 +db 141, 86, 3 +db 57, 84, 36, 4 +db 15, 130, 123, 1, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 231 +db 141, 76, 24, 36 +db 49, 192 +db 235, 17 +db 144 +db 60, 32 +db 15, 130, 200, 0, 0, 0 +db 131, 224, 31 +db 116, 227 +db 141, 72, 5 +db 102, 139, 6 +db 141, 87, 255 +db 193, 232, 2 +db 131, 198, 2 +db 41, 194 +db 57, 232 +db 114, 102 +db 59, 84, 36, 48 +db 15, 130, 77, 1, 0, 0 +db 141, 68, 15, 253 +db 193, 233, 2 +db 57, 4, 36 +db 15, 130, 54, 1, 0, 0 +db 139, 26 +db 131, 194, 4 +db 137, 31 +db 131, 199, 4 +db 73 +db 117, 243 +db 137, 199 +db 49, 219 +db 138, 70, 254 +db 33, 232 +db 15, 132, 216, 254, 255, 255 +db 141, 20, 7 +db 57, 20, 36 +db 15, 130, 14, 1, 0, 0 +db 141, 20, 6 +db 57, 84, 36, 4 +db 15, 130, 250, 0, 0, 0 +db 139, 22 +db 1, 198 +db 137, 23 +db 1, 199 +db 138, 6 +db 70 +db 233, 55, 255, 255, 255 +db 141, 180, 38, 0, 0, 0, 0 +db 59, 84, 36, 48 +db 15, 130, 231, 0, 0, 0 +db 141, 68, 15, 253 +db 57, 4, 36 +db 15, 130, 211, 0, 0, 0 +db 135, 214 +db 41, 233 +db 243, 164 +db 137, 214 +db 235, 164 +db 129, 193, 255, 0, 0, 0 +db 141, 86, 3 +db 57, 84, 36, 4 +db 15, 130, 175, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 230 +db 141, 76, 11, 12 +db 235, 27 +db 141, 180, 38, 0, 0, 0, 0 +db 60, 16 +db 114, 44 +db 137, 193 +db 131, 224, 8 +db 193, 224, 13 +db 131, 225, 7 +db 116, 219 +db 131, 193, 5 +db 102, 139, 6 +db 131, 198, 2 +db 141, 151, 0, 192, 255, 255 +db 193, 232, 2 +db 116, 57 +db 41, 194 +db 233, 38, 255, 255, 255 +db 141, 116, 38, 0 +db 141, 87, 2 +db 57, 20, 36 +db 114, 106 +db 193, 232, 2 +db 138, 30 +db 141, 87, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 59, 84, 36, 48 +db 114, 93 +db 138, 2 +db 136, 7 +db 138, 90, 1 +db 136, 95, 1 +db 131, 199, 2 +db 233, 31, 255, 255, 255 +db 131, 249, 6 +db 15, 149, 192 +db 59, 60, 36 +db 119, 57 +db 139, 84, 36, 40 +db 3, 84, 36, 44 +db 57, 214 +db 119, 38 +db 114, 29 +db 43, 124, 36, 48 +db 139, 84, 36, 52 +db 137, 58 +db 247, 216 +db 131, 196, 12 +db 90 +db 89 +db 91 +db 94 +db 95 +db 93 +db 195 +db 184, 1, 0, 0, 0 +db 235, 227 +db 184, 8, 0, 0, 0 +db 235, 220 +db 184, 4, 0, 0, 0 +db 235, 213 +db 184, 5, 0, 0, 0 +db 235, 206 +db 184, 6, 0, 0, 0 +db 235, 199 + +end diff --git a/DumpProto/lzo/i386/d_asm3/lzo1x_s1.asm b/DumpProto/lzo/i386/d_asm3/lzo1x_s1.asm new file mode 100644 index 0000000..7f24a0d --- /dev/null +++ b/DumpProto/lzo/i386/d_asm3/lzo1x_s1.asm @@ -0,0 +1,208 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +BITS 32 + +SECTION .text +GLOBAL _lzo1x_decompress_asm + +_lzo1x_decompress_asm: +db 85 +db 87 +db 86 +db 83 +db 81 +db 82 +db 131, 236, 12 +db 252 +db 139, 116, 36, 40 +db 139, 124, 36, 48 +db 189, 3, 0, 0, 0 +db 49, 192 +db 49, 219 +db 172 +db 60, 17 +db 118, 35 +db 44, 17 +db 60, 4 +db 115, 40 +db 137, 193 +db 235, 56 +db 5, 255, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 244 +db 141, 68, 24, 18 +db 235, 18 +db 141, 116, 38, 0 +db 138, 6 +db 70 +db 60, 16 +db 115, 73 +db 8, 192 +db 116, 228 +db 131, 192, 3 +db 137, 193 +db 193, 232, 2 +db 33, 233 +db 139, 22 +db 131, 198, 4 +db 137, 23 +db 131, 199, 4 +db 72 +db 117, 243 +db 243, 164 +db 138, 6 +db 70 +db 60, 16 +db 115, 37 +db 193, 232, 2 +db 138, 30 +db 141, 151, 255, 247, 255, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 138, 2 +db 136, 7 +db 138, 66, 1 +db 136, 71, 1 +db 138, 66, 2 +db 136, 71, 2 +db 1, 239 +db 235, 119 +db 60, 64 +db 114, 52 +db 137, 193 +db 193, 232, 2 +db 141, 87, 255 +db 131, 224, 7 +db 138, 30 +db 193, 233, 5 +db 141, 4, 216 +db 70 +db 41, 194 +db 65 +db 57, 232 +db 115, 55 +db 235, 119 +db 5, 255, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 244 +db 141, 76, 24, 33 +db 49, 192 +db 235, 15 +db 141, 118, 0 +db 60, 32 +db 114, 124 +db 131, 224, 31 +db 116, 229 +db 141, 72, 2 +db 102, 139, 6 +db 141, 87, 255 +db 193, 232, 2 +db 131, 198, 2 +db 41, 194 +db 57, 232 +db 114, 66 +db 137, 203 +db 193, 235, 2 +db 116, 17 +db 139, 2 +db 131, 194, 4 +db 137, 7 +db 131, 199, 4 +db 75 +db 117, 243 +db 33, 233 +db 116, 9 +db 138, 2 +db 66 +db 136, 7 +db 71 +db 73 +db 117, 247 +db 138, 70, 254 +db 33, 232 +db 15, 132, 46, 255, 255, 255 +db 138, 14 +db 70 +db 136, 15 +db 71 +db 72 +db 117, 247 +db 138, 6 +db 70 +db 233, 109, 255, 255, 255 +db 144 +db 141, 116, 38, 0 +db 135, 214 +db 243, 164 +db 137, 214 +db 235, 215 +db 129, 193, 255, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 243 +db 141, 76, 11, 9 +db 235, 25 +db 144 +db 141, 116, 38, 0 +db 60, 16 +db 114, 44 +db 137, 193 +db 131, 224, 8 +db 193, 224, 13 +db 131, 225, 7 +db 116, 221 +db 131, 193, 2 +db 102, 139, 6 +db 131, 198, 2 +db 141, 151, 0, 192, 255, 255 +db 193, 232, 2 +db 116, 43 +db 41, 194 +db 233, 114, 255, 255, 255 +db 141, 116, 38, 0 +db 193, 232, 2 +db 138, 30 +db 141, 87, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 138, 2 +db 136, 7 +db 138, 90, 1 +db 136, 95, 1 +db 131, 199, 2 +db 233, 111, 255, 255, 255 +db 131, 249, 3 +db 15, 149, 192 +db 139, 84, 36, 40 +db 3, 84, 36, 44 +db 57, 214 +db 119, 38 +db 114, 29 +db 43, 124, 36, 48 +db 139, 84, 36, 52 +db 137, 58 +db 247, 216 +db 131, 196, 12 +db 90 +db 89 +db 91 +db 94 +db 95 +db 93 +db 195 +db 184, 1, 0, 0, 0 +db 235, 227 +db 184, 8, 0, 0, 0 +db 235, 220 +db 184, 4, 0, 0, 0 +db 235, 213 + +end diff --git a/DumpProto/lzo/i386/d_asm3/lzo1x_s2.asm b/DumpProto/lzo/i386/d_asm3/lzo1x_s2.asm new file mode 100644 index 0000000..b8beb21 --- /dev/null +++ b/DumpProto/lzo/i386/d_asm3/lzo1x_s2.asm @@ -0,0 +1,269 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +BITS 32 + +SECTION .text +GLOBAL _lzo1x_decompress_asm_safe + +_lzo1x_decompress_asm_safe: +db 85 +db 87 +db 86 +db 83 +db 81 +db 82 +db 131, 236, 12 +db 252 +db 139, 116, 36, 40 +db 139, 124, 36, 48 +db 189, 3, 0, 0, 0 +db 141, 70, 253 +db 3, 68, 36, 44 +db 137, 68, 36, 4 +db 137, 248 +db 139, 84, 36, 52 +db 3, 2 +db 137, 4, 36 +db 49, 192 +db 49, 219 +db 172 +db 60, 17 +db 118, 87 +db 44, 17 +db 60, 4 +db 115, 92 +db 141, 20, 7 +db 57, 20, 36 +db 15, 130, 130, 2, 0, 0 +db 141, 20, 6 +db 57, 84, 36, 4 +db 15, 130, 110, 2, 0, 0 +db 137, 193 +db 235, 110 +db 5, 255, 0, 0, 0 +db 141, 84, 6, 18 +db 57, 84, 36, 4 +db 15, 130, 87, 2, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 230 +db 141, 68, 24, 18 +db 235, 31 +db 141, 180, 38, 0, 0, 0, 0 +db 57, 116, 36, 4 +db 15, 130, 57, 2, 0, 0 +db 138, 6 +db 70 +db 60, 16 +db 115, 127 +db 8, 192 +db 116, 215 +db 131, 192, 3 +db 141, 84, 7, 0 +db 57, 20, 36 +db 15, 130, 37, 2, 0, 0 +db 141, 84, 6, 0 +db 57, 84, 36, 4 +db 15, 130, 16, 2, 0, 0 +db 137, 193 +db 193, 232, 2 +db 33, 233 +db 139, 22 +db 131, 198, 4 +db 137, 23 +db 131, 199, 4 +db 72 +db 117, 243 +db 243, 164 +db 138, 6 +db 70 +db 60, 16 +db 115, 64 +db 141, 87, 3 +db 57, 20, 36 +db 15, 130, 238, 1, 0, 0 +db 193, 232, 2 +db 138, 30 +db 141, 151, 255, 247, 255, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 59, 84, 36, 48 +db 15, 130, 218, 1, 0, 0 +db 138, 2 +db 136, 7 +db 138, 66, 1 +db 136, 71, 1 +db 138, 66, 2 +db 136, 71, 2 +db 1, 239 +db 233, 163, 0, 0, 0 +db 137, 246 +db 60, 64 +db 114, 68 +db 137, 193 +db 193, 232, 2 +db 141, 87, 255 +db 131, 224, 7 +db 138, 30 +db 193, 233, 5 +db 141, 4, 216 +db 70 +db 41, 194 +db 65 +db 57, 232 +db 115, 75 +db 233, 180, 0, 0, 0 +db 5, 255, 0, 0, 0 +db 141, 86, 3 +db 57, 84, 36, 4 +db 15, 130, 125, 1, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 231 +db 141, 76, 24, 33 +db 49, 192 +db 235, 19 +db 141, 118, 0 +db 60, 32 +db 15, 130, 200, 0, 0, 0 +db 131, 224, 31 +db 116, 225 +db 141, 72, 2 +db 102, 139, 6 +db 141, 87, 255 +db 193, 232, 2 +db 131, 198, 2 +db 41, 194 +db 57, 232 +db 114, 110 +db 59, 84, 36, 48 +db 15, 130, 77, 1, 0, 0 +db 141, 4, 15 +db 57, 4, 36 +db 15, 130, 58, 1, 0, 0 +db 137, 203 +db 193, 235, 2 +db 116, 17 +db 139, 2 +db 131, 194, 4 +db 137, 7 +db 131, 199, 4 +db 75 +db 117, 243 +db 33, 233 +db 116, 9 +db 138, 2 +db 66 +db 136, 7 +db 71 +db 73 +db 117, 247 +db 138, 70, 254 +db 33, 232 +db 15, 132, 196, 254, 255, 255 +db 141, 20, 7 +db 57, 20, 36 +db 15, 130, 2, 1, 0, 0 +db 141, 20, 6 +db 57, 84, 36, 4 +db 15, 130, 238, 0, 0, 0 +db 138, 14 +db 70 +db 136, 15 +db 71 +db 72 +db 117, 247 +db 138, 6 +db 70 +db 233, 42, 255, 255, 255 +db 137, 246 +db 59, 84, 36, 48 +db 15, 130, 223, 0, 0, 0 +db 141, 68, 15, 0 +db 57, 4, 36 +db 15, 130, 203, 0, 0, 0 +db 135, 214 +db 243, 164 +db 137, 214 +db 235, 170 +db 129, 193, 255, 0, 0, 0 +db 141, 86, 3 +db 57, 84, 36, 4 +db 15, 130, 169, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 230 +db 141, 76, 11, 9 +db 235, 21 +db 144 +db 60, 16 +db 114, 44 +db 137, 193 +db 131, 224, 8 +db 193, 224, 13 +db 131, 225, 7 +db 116, 225 +db 131, 193, 2 +db 102, 139, 6 +db 131, 198, 2 +db 141, 151, 0, 192, 255, 255 +db 193, 232, 2 +db 116, 57 +db 41, 194 +db 233, 38, 255, 255, 255 +db 141, 116, 38, 0 +db 141, 87, 2 +db 57, 20, 36 +db 114, 106 +db 193, 232, 2 +db 138, 30 +db 141, 87, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 59, 84, 36, 48 +db 114, 93 +db 138, 2 +db 136, 7 +db 138, 90, 1 +db 136, 95, 1 +db 131, 199, 2 +db 233, 43, 255, 255, 255 +db 131, 249, 3 +db 15, 149, 192 +db 59, 60, 36 +db 119, 57 +db 139, 84, 36, 40 +db 3, 84, 36, 44 +db 57, 214 +db 119, 38 +db 114, 29 +db 43, 124, 36, 48 +db 139, 84, 36, 52 +db 137, 58 +db 247, 216 +db 131, 196, 12 +db 90 +db 89 +db 91 +db 94 +db 95 +db 93 +db 195 +db 184, 1, 0, 0, 0 +db 235, 227 +db 184, 8, 0, 0, 0 +db 235, 220 +db 184, 4, 0, 0, 0 +db 235, 213 +db 184, 5, 0, 0, 0 +db 235, 206 +db 184, 6, 0, 0, 0 +db 235, 199 + +end diff --git a/DumpProto/lzo/i386/d_asm3/lzo1y_f1.asm b/DumpProto/lzo/i386/d_asm3/lzo1y_f1.asm new file mode 100644 index 0000000..6c757f3 --- /dev/null +++ b/DumpProto/lzo/i386/d_asm3/lzo1y_f1.asm @@ -0,0 +1,193 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +BITS 32 + +SECTION .text +GLOBAL _lzo1y_decompress_asm_fast + +_lzo1y_decompress_asm_fast: +db 85 +db 87 +db 86 +db 83 +db 81 +db 82 +db 131, 236, 12 +db 252 +db 139, 116, 36, 40 +db 139, 124, 36, 48 +db 189, 3, 0, 0, 0 +db 49, 192 +db 49, 219 +db 172 +db 60, 17 +db 118, 27 +db 44, 14 +db 235, 34 +db 5, 255, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 244 +db 141, 68, 24, 21 +db 235, 16 +db 137, 246 +db 138, 6 +db 70 +db 60, 16 +db 115, 65 +db 8, 192 +db 116, 230 +db 131, 192, 6 +db 137, 193 +db 49, 232 +db 193, 233, 2 +db 33, 232 +db 139, 22 +db 131, 198, 4 +db 137, 23 +db 131, 199, 4 +db 73 +db 117, 243 +db 41, 198 +db 41, 199 +db 138, 6 +db 70 +db 60, 16 +db 115, 25 +db 193, 232, 2 +db 138, 30 +db 141, 151, 255, 251, 255, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 139, 10 +db 137, 15 +db 1, 239 +db 235, 110 +db 60, 64 +db 114, 52 +db 137, 193 +db 193, 232, 2 +db 141, 87, 255 +db 33, 232 +db 138, 30 +db 193, 233, 4 +db 141, 4, 152 +db 70 +db 41, 194 +db 131, 193, 2 +db 57, 232 +db 115, 54 +db 235, 110 +db 5, 255, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 244 +db 141, 76, 24, 36 +db 49, 192 +db 235, 14 +db 137, 246 +db 60, 32 +db 114, 116 +db 131, 224, 31 +db 116, 230 +db 141, 72, 5 +db 102, 139, 6 +db 141, 87, 255 +db 193, 232, 2 +db 131, 198, 2 +db 41, 194 +db 57, 232 +db 114, 58 +db 141, 68, 15, 253 +db 193, 233, 2 +db 139, 26 +db 131, 194, 4 +db 137, 31 +db 131, 199, 4 +db 73 +db 117, 243 +db 137, 199 +db 49, 219 +db 138, 70, 254 +db 33, 232 +db 15, 132, 63, 255, 255, 255 +db 139, 22 +db 1, 198 +db 137, 23 +db 1, 199 +db 138, 6 +db 70 +db 233, 119, 255, 255, 255 +db 141, 180, 38, 0, 0, 0, 0 +db 135, 214 +db 41, 233 +db 243, 164 +db 137, 214 +db 235, 212 +db 129, 193, 255, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 243 +db 141, 76, 11, 12 +db 235, 23 +db 141, 118, 0 +db 60, 16 +db 114, 44 +db 137, 193 +db 131, 224, 8 +db 193, 224, 13 +db 131, 225, 7 +db 116, 223 +db 131, 193, 5 +db 102, 139, 6 +db 131, 198, 2 +db 141, 151, 0, 192, 255, 255 +db 193, 232, 2 +db 116, 43 +db 41, 194 +db 233, 122, 255, 255, 255 +db 141, 116, 38, 0 +db 193, 232, 2 +db 138, 30 +db 141, 87, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 138, 2 +db 136, 7 +db 138, 90, 1 +db 136, 95, 1 +db 131, 199, 2 +db 233, 110, 255, 255, 255 +db 131, 249, 6 +db 15, 149, 192 +db 139, 84, 36, 40 +db 3, 84, 36, 44 +db 57, 214 +db 119, 38 +db 114, 29 +db 43, 124, 36, 48 +db 139, 84, 36, 52 +db 137, 58 +db 247, 216 +db 131, 196, 12 +db 90 +db 89 +db 91 +db 94 +db 95 +db 93 +db 195 +db 184, 1, 0, 0, 0 +db 235, 227 +db 184, 8, 0, 0, 0 +db 235, 220 +db 184, 4, 0, 0, 0 +db 235, 213 + +end diff --git a/DumpProto/lzo/i386/d_asm3/lzo1y_f2.asm b/DumpProto/lzo/i386/d_asm3/lzo1y_f2.asm new file mode 100644 index 0000000..7729ada --- /dev/null +++ b/DumpProto/lzo/i386/d_asm3/lzo1y_f2.asm @@ -0,0 +1,249 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +BITS 32 + +SECTION .text +GLOBAL _lzo1y_decompress_asm_fast_safe + +_lzo1y_decompress_asm_fast_safe: +db 85 +db 87 +db 86 +db 83 +db 81 +db 82 +db 131, 236, 12 +db 252 +db 139, 116, 36, 40 +db 139, 124, 36, 48 +db 189, 3, 0, 0, 0 +db 141, 70, 253 +db 3, 68, 36, 44 +db 137, 68, 36, 4 +db 137, 248 +db 139, 84, 36, 52 +db 3, 2 +db 137, 4, 36 +db 49, 192 +db 49, 219 +db 172 +db 60, 17 +db 118, 55 +db 44, 14 +db 235, 62 +db 5, 255, 0, 0, 0 +db 141, 84, 6, 18 +db 57, 84, 36, 4 +db 15, 130, 78, 2, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 230 +db 141, 68, 24, 21 +db 235, 30 +db 141, 182, 0, 0, 0, 0 +db 57, 116, 36, 4 +db 15, 130, 49, 2, 0, 0 +db 138, 6 +db 70 +db 60, 16 +db 115, 119 +db 8, 192 +db 116, 216 +db 131, 192, 6 +db 141, 84, 7, 253 +db 57, 20, 36 +db 15, 130, 29, 2, 0, 0 +db 141, 84, 6, 253 +db 57, 84, 36, 4 +db 15, 130, 8, 2, 0, 0 +db 137, 193 +db 49, 232 +db 193, 233, 2 +db 33, 232 +db 139, 22 +db 131, 198, 4 +db 137, 23 +db 131, 199, 4 +db 73 +db 117, 243 +db 41, 198 +db 41, 199 +db 138, 6 +db 70 +db 60, 16 +db 115, 52 +db 141, 87, 3 +db 57, 20, 36 +db 15, 130, 226, 1, 0, 0 +db 193, 232, 2 +db 138, 30 +db 141, 151, 255, 251, 255, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 59, 84, 36, 48 +db 15, 130, 206, 1, 0, 0 +db 139, 10 +db 137, 15 +db 1, 239 +db 233, 151, 0, 0, 0 +db 137, 246 +db 60, 64 +db 114, 68 +db 137, 193 +db 193, 232, 2 +db 141, 87, 255 +db 33, 232 +db 138, 30 +db 193, 233, 4 +db 141, 4, 152 +db 70 +db 41, 194 +db 131, 193, 2 +db 57, 232 +db 115, 74 +db 233, 171, 0, 0, 0 +db 5, 255, 0, 0, 0 +db 141, 86, 3 +db 57, 84, 36, 4 +db 15, 130, 124, 1, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 231 +db 141, 76, 24, 36 +db 49, 192 +db 235, 18 +db 137, 246 +db 60, 32 +db 15, 130, 200, 0, 0, 0 +db 131, 224, 31 +db 116, 226 +db 141, 72, 5 +db 102, 139, 6 +db 141, 87, 255 +db 193, 232, 2 +db 131, 198, 2 +db 41, 194 +db 57, 232 +db 114, 102 +db 59, 84, 36, 48 +db 15, 130, 77, 1, 0, 0 +db 141, 68, 15, 253 +db 193, 233, 2 +db 57, 4, 36 +db 15, 130, 54, 1, 0, 0 +db 139, 26 +db 131, 194, 4 +db 137, 31 +db 131, 199, 4 +db 73 +db 117, 243 +db 137, 199 +db 49, 219 +db 138, 70, 254 +db 33, 232 +db 15, 132, 216, 254, 255, 255 +db 141, 20, 7 +db 57, 20, 36 +db 15, 130, 14, 1, 0, 0 +db 141, 20, 6 +db 57, 84, 36, 4 +db 15, 130, 250, 0, 0, 0 +db 139, 22 +db 1, 198 +db 137, 23 +db 1, 199 +db 138, 6 +db 70 +db 233, 55, 255, 255, 255 +db 141, 180, 38, 0, 0, 0, 0 +db 59, 84, 36, 48 +db 15, 130, 231, 0, 0, 0 +db 141, 68, 15, 253 +db 57, 4, 36 +db 15, 130, 211, 0, 0, 0 +db 135, 214 +db 41, 233 +db 243, 164 +db 137, 214 +db 235, 164 +db 129, 193, 255, 0, 0, 0 +db 141, 86, 3 +db 57, 84, 36, 4 +db 15, 130, 175, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 230 +db 141, 76, 11, 12 +db 235, 27 +db 141, 180, 38, 0, 0, 0, 0 +db 60, 16 +db 114, 44 +db 137, 193 +db 131, 224, 8 +db 193, 224, 13 +db 131, 225, 7 +db 116, 219 +db 131, 193, 5 +db 102, 139, 6 +db 131, 198, 2 +db 141, 151, 0, 192, 255, 255 +db 193, 232, 2 +db 116, 57 +db 41, 194 +db 233, 38, 255, 255, 255 +db 141, 116, 38, 0 +db 141, 87, 2 +db 57, 20, 36 +db 114, 106 +db 193, 232, 2 +db 138, 30 +db 141, 87, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 59, 84, 36, 48 +db 114, 93 +db 138, 2 +db 136, 7 +db 138, 90, 1 +db 136, 95, 1 +db 131, 199, 2 +db 233, 31, 255, 255, 255 +db 131, 249, 6 +db 15, 149, 192 +db 59, 60, 36 +db 119, 57 +db 139, 84, 36, 40 +db 3, 84, 36, 44 +db 57, 214 +db 119, 38 +db 114, 29 +db 43, 124, 36, 48 +db 139, 84, 36, 52 +db 137, 58 +db 247, 216 +db 131, 196, 12 +db 90 +db 89 +db 91 +db 94 +db 95 +db 93 +db 195 +db 184, 1, 0, 0, 0 +db 235, 227 +db 184, 8, 0, 0, 0 +db 235, 220 +db 184, 4, 0, 0, 0 +db 235, 213 +db 184, 5, 0, 0, 0 +db 235, 206 +db 184, 6, 0, 0, 0 +db 235, 199 + +end diff --git a/DumpProto/lzo/i386/d_asm3/lzo1y_s1.asm b/DumpProto/lzo/i386/d_asm3/lzo1y_s1.asm new file mode 100644 index 0000000..63ecc98 --- /dev/null +++ b/DumpProto/lzo/i386/d_asm3/lzo1y_s1.asm @@ -0,0 +1,208 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +BITS 32 + +SECTION .text +GLOBAL _lzo1y_decompress_asm + +_lzo1y_decompress_asm: +db 85 +db 87 +db 86 +db 83 +db 81 +db 82 +db 131, 236, 12 +db 252 +db 139, 116, 36, 40 +db 139, 124, 36, 48 +db 189, 3, 0, 0, 0 +db 49, 192 +db 49, 219 +db 172 +db 60, 17 +db 118, 35 +db 44, 17 +db 60, 4 +db 115, 40 +db 137, 193 +db 235, 56 +db 5, 255, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 244 +db 141, 68, 24, 18 +db 235, 18 +db 141, 116, 38, 0 +db 138, 6 +db 70 +db 60, 16 +db 115, 73 +db 8, 192 +db 116, 228 +db 131, 192, 3 +db 137, 193 +db 193, 232, 2 +db 33, 233 +db 139, 22 +db 131, 198, 4 +db 137, 23 +db 131, 199, 4 +db 72 +db 117, 243 +db 243, 164 +db 138, 6 +db 70 +db 60, 16 +db 115, 37 +db 193, 232, 2 +db 138, 30 +db 141, 151, 255, 251, 255, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 138, 2 +db 136, 7 +db 138, 66, 1 +db 136, 71, 1 +db 138, 66, 2 +db 136, 71, 2 +db 1, 239 +db 235, 119 +db 60, 64 +db 114, 52 +db 137, 193 +db 193, 232, 2 +db 141, 87, 255 +db 33, 232 +db 138, 30 +db 193, 233, 4 +db 141, 4, 152 +db 70 +db 41, 194 +db 73 +db 57, 232 +db 115, 56 +db 235, 120 +db 5, 255, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 244 +db 141, 76, 24, 33 +db 49, 192 +db 235, 16 +db 141, 116, 38, 0 +db 60, 32 +db 114, 124 +db 131, 224, 31 +db 116, 228 +db 141, 72, 2 +db 102, 139, 6 +db 141, 87, 255 +db 193, 232, 2 +db 131, 198, 2 +db 41, 194 +db 57, 232 +db 114, 66 +db 137, 203 +db 193, 235, 2 +db 116, 17 +db 139, 2 +db 131, 194, 4 +db 137, 7 +db 131, 199, 4 +db 75 +db 117, 243 +db 33, 233 +db 116, 9 +db 138, 2 +db 66 +db 136, 7 +db 71 +db 73 +db 117, 247 +db 138, 70, 254 +db 33, 232 +db 15, 132, 46, 255, 255, 255 +db 138, 14 +db 70 +db 136, 15 +db 71 +db 72 +db 117, 247 +db 138, 6 +db 70 +db 233, 109, 255, 255, 255 +db 144 +db 141, 116, 38, 0 +db 135, 214 +db 243, 164 +db 137, 214 +db 235, 215 +db 129, 193, 255, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 243 +db 141, 76, 11, 9 +db 235, 25 +db 144 +db 141, 116, 38, 0 +db 60, 16 +db 114, 44 +db 137, 193 +db 131, 224, 8 +db 193, 224, 13 +db 131, 225, 7 +db 116, 221 +db 131, 193, 2 +db 102, 139, 6 +db 131, 198, 2 +db 141, 151, 0, 192, 255, 255 +db 193, 232, 2 +db 116, 43 +db 41, 194 +db 233, 114, 255, 255, 255 +db 141, 116, 38, 0 +db 193, 232, 2 +db 138, 30 +db 141, 87, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 138, 2 +db 136, 7 +db 138, 90, 1 +db 136, 95, 1 +db 131, 199, 2 +db 233, 111, 255, 255, 255 +db 131, 249, 3 +db 15, 149, 192 +db 139, 84, 36, 40 +db 3, 84, 36, 44 +db 57, 214 +db 119, 38 +db 114, 29 +db 43, 124, 36, 48 +db 139, 84, 36, 52 +db 137, 58 +db 247, 216 +db 131, 196, 12 +db 90 +db 89 +db 91 +db 94 +db 95 +db 93 +db 195 +db 184, 1, 0, 0, 0 +db 235, 227 +db 184, 8, 0, 0, 0 +db 235, 220 +db 184, 4, 0, 0, 0 +db 235, 213 + +end diff --git a/DumpProto/lzo/i386/d_asm3/lzo1y_s2.asm b/DumpProto/lzo/i386/d_asm3/lzo1y_s2.asm new file mode 100644 index 0000000..541af2d --- /dev/null +++ b/DumpProto/lzo/i386/d_asm3/lzo1y_s2.asm @@ -0,0 +1,269 @@ +; /*** DO NOT EDIT - GENERATED AUTOMATICALLY ***/ +; /*** Copyright (C) 1996-2002 Markus F.X.J. Oberhumer ***/ + +BITS 32 + +SECTION .text +GLOBAL _lzo1y_decompress_asm_safe + +_lzo1y_decompress_asm_safe: +db 85 +db 87 +db 86 +db 83 +db 81 +db 82 +db 131, 236, 12 +db 252 +db 139, 116, 36, 40 +db 139, 124, 36, 48 +db 189, 3, 0, 0, 0 +db 141, 70, 253 +db 3, 68, 36, 44 +db 137, 68, 36, 4 +db 137, 248 +db 139, 84, 36, 52 +db 3, 2 +db 137, 4, 36 +db 49, 192 +db 49, 219 +db 172 +db 60, 17 +db 118, 87 +db 44, 17 +db 60, 4 +db 115, 92 +db 141, 20, 7 +db 57, 20, 36 +db 15, 130, 130, 2, 0, 0 +db 141, 20, 6 +db 57, 84, 36, 4 +db 15, 130, 110, 2, 0, 0 +db 137, 193 +db 235, 110 +db 5, 255, 0, 0, 0 +db 141, 84, 6, 18 +db 57, 84, 36, 4 +db 15, 130, 87, 2, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 230 +db 141, 68, 24, 18 +db 235, 31 +db 141, 180, 38, 0, 0, 0, 0 +db 57, 116, 36, 4 +db 15, 130, 57, 2, 0, 0 +db 138, 6 +db 70 +db 60, 16 +db 115, 127 +db 8, 192 +db 116, 215 +db 131, 192, 3 +db 141, 84, 7, 0 +db 57, 20, 36 +db 15, 130, 37, 2, 0, 0 +db 141, 84, 6, 0 +db 57, 84, 36, 4 +db 15, 130, 16, 2, 0, 0 +db 137, 193 +db 193, 232, 2 +db 33, 233 +db 139, 22 +db 131, 198, 4 +db 137, 23 +db 131, 199, 4 +db 72 +db 117, 243 +db 243, 164 +db 138, 6 +db 70 +db 60, 16 +db 115, 64 +db 141, 87, 3 +db 57, 20, 36 +db 15, 130, 238, 1, 0, 0 +db 193, 232, 2 +db 138, 30 +db 141, 151, 255, 251, 255, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 59, 84, 36, 48 +db 15, 130, 218, 1, 0, 0 +db 138, 2 +db 136, 7 +db 138, 66, 1 +db 136, 71, 1 +db 138, 66, 2 +db 136, 71, 2 +db 1, 239 +db 233, 163, 0, 0, 0 +db 137, 246 +db 60, 64 +db 114, 68 +db 137, 193 +db 193, 232, 2 +db 141, 87, 255 +db 33, 232 +db 138, 30 +db 193, 233, 4 +db 141, 4, 152 +db 70 +db 41, 194 +db 73 +db 57, 232 +db 115, 76 +db 233, 181, 0, 0, 0 +db 5, 255, 0, 0, 0 +db 141, 86, 3 +db 57, 84, 36, 4 +db 15, 130, 126, 1, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 231 +db 141, 76, 24, 33 +db 49, 192 +db 235, 20 +db 141, 116, 38, 0 +db 60, 32 +db 15, 130, 200, 0, 0, 0 +db 131, 224, 31 +db 116, 224 +db 141, 72, 2 +db 102, 139, 6 +db 141, 87, 255 +db 193, 232, 2 +db 131, 198, 2 +db 41, 194 +db 57, 232 +db 114, 110 +db 59, 84, 36, 48 +db 15, 130, 77, 1, 0, 0 +db 141, 4, 15 +db 57, 4, 36 +db 15, 130, 58, 1, 0, 0 +db 137, 203 +db 193, 235, 2 +db 116, 17 +db 139, 2 +db 131, 194, 4 +db 137, 7 +db 131, 199, 4 +db 75 +db 117, 243 +db 33, 233 +db 116, 9 +db 138, 2 +db 66 +db 136, 7 +db 71 +db 73 +db 117, 247 +db 138, 70, 254 +db 33, 232 +db 15, 132, 196, 254, 255, 255 +db 141, 20, 7 +db 57, 20, 36 +db 15, 130, 2, 1, 0, 0 +db 141, 20, 6 +db 57, 84, 36, 4 +db 15, 130, 238, 0, 0, 0 +db 138, 14 +db 70 +db 136, 15 +db 71 +db 72 +db 117, 247 +db 138, 6 +db 70 +db 233, 42, 255, 255, 255 +db 137, 246 +db 59, 84, 36, 48 +db 15, 130, 223, 0, 0, 0 +db 141, 68, 15, 0 +db 57, 4, 36 +db 15, 130, 203, 0, 0, 0 +db 135, 214 +db 243, 164 +db 137, 214 +db 235, 170 +db 129, 193, 255, 0, 0, 0 +db 141, 86, 3 +db 57, 84, 36, 4 +db 15, 130, 169, 0, 0, 0 +db 138, 30 +db 70 +db 8, 219 +db 116, 230 +db 141, 76, 11, 9 +db 235, 21 +db 144 +db 60, 16 +db 114, 44 +db 137, 193 +db 131, 224, 8 +db 193, 224, 13 +db 131, 225, 7 +db 116, 225 +db 131, 193, 2 +db 102, 139, 6 +db 131, 198, 2 +db 141, 151, 0, 192, 255, 255 +db 193, 232, 2 +db 116, 57 +db 41, 194 +db 233, 38, 255, 255, 255 +db 141, 116, 38, 0 +db 141, 87, 2 +db 57, 20, 36 +db 114, 106 +db 193, 232, 2 +db 138, 30 +db 141, 87, 255 +db 141, 4, 152 +db 70 +db 41, 194 +db 59, 84, 36, 48 +db 114, 93 +db 138, 2 +db 136, 7 +db 138, 90, 1 +db 136, 95, 1 +db 131, 199, 2 +db 233, 43, 255, 255, 255 +db 131, 249, 3 +db 15, 149, 192 +db 59, 60, 36 +db 119, 57 +db 139, 84, 36, 40 +db 3, 84, 36, 44 +db 57, 214 +db 119, 38 +db 114, 29 +db 43, 124, 36, 48 +db 139, 84, 36, 52 +db 137, 58 +db 247, 216 +db 131, 196, 12 +db 90 +db 89 +db 91 +db 94 +db 95 +db 93 +db 195 +db 184, 1, 0, 0, 0 +db 235, 227 +db 184, 8, 0, 0, 0 +db 235, 220 +db 184, 4, 0, 0, 0 +db 235, 213 +db 184, 5, 0, 0, 0 +db 235, 206 +db 184, 6, 0, 0, 0 +db 235, 199 + +end diff --git a/DumpProto/lzo/i386/src/enter.sh b/DumpProto/lzo/i386/src/enter.sh new file mode 100644 index 0000000..caebc84 --- /dev/null +++ b/DumpProto/lzo/i386/src/enter.sh @@ -0,0 +1,75 @@ +/* enter.sh -- LZO assembler stuff + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/*********************************************************************** +// +************************************************************************/ + + pushl %ebp + pushl %edi + pushl %esi + pushl %ebx + pushl %ecx + pushl %edx + subl $12,%esp + + cld + + movl INP,%esi + movl OUTP,%edi +#if defined(N_3_EBP) + movl $3,%ebp +#endif +#if defined(N_255_EBP) + movl $255,%ebp +#endif + +#if defined(LZO_TEST_DECOMPRESS_OVERRUN_INPUT) +#if defined(INIT_OVERRUN) + INIT_OVERRUN +# undef INIT_OVERRUN +#endif + leal -3(%esi),%eax /* 3 == length of EOF code */ + addl INS,%eax + movl %eax,INEND +#endif + +#if defined(LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT) +#if defined(INIT_OVERRUN) + INIT_OVERRUN +# undef INIT_OVERRUN +#endif + movl %edi,%eax + movl OUTS,%edx + addl (%edx),%eax + movl %eax,OUTEND +#endif + + +/* +vi:ts=4 +*/ + diff --git a/DumpProto/lzo/i386/src/leave.sh b/DumpProto/lzo/i386/src/leave.sh new file mode 100644 index 0000000..77628e3 --- /dev/null +++ b/DumpProto/lzo/i386/src/leave.sh @@ -0,0 +1,100 @@ +/* leave.sh -- LZO assembler stuff + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/*********************************************************************** +// +************************************************************************/ + +/* check uncompressed size */ +#if defined(LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT) + cmpl OUTEND,%edi + ja .L_output_overrun +#endif + +/* check compressed size */ + movl INP,%edx + addl INS,%edx + cmpl %edx,%esi /* check compressed size */ + ja .L_input_overrun + jb .L_input_not_consumed + +.L_leave: + subl OUTP,%edi /* write back the uncompressed size */ + movl OUTS,%edx + movl %edi,(%edx) + + negl %eax + addl $12,%esp + popl %edx + popl %ecx + popl %ebx + popl %esi + popl %edi + popl %ebp +#if 1 + ret +#else + jmp .L_end +#endif + + +.L_error: + movl $1,%eax /* LZO_E_ERROR */ + jmp .L_leave + +.L_input_not_consumed: + movl $8,%eax /* LZO_E_INPUT_NOT_CONSUMED */ + jmp .L_leave + +.L_input_overrun: + movl $4,%eax /* LZO_E_INPUT_OVERRUN */ + jmp .L_leave + +#if defined(LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT) +.L_output_overrun: + movl $5,%eax /* LZO_E_OUTPUT_OVERRUN */ + jmp .L_leave +#endif + +#if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND) +.L_lookbehind_overrun: + movl $6,%eax /* LZO_E_LOOKBEHIND_OVERRUN */ + jmp .L_leave +#endif + +#if defined(LZO_DEBUG) +.L_assert_fail: + movl $99,%eax + jmp .L_leave +#endif + +.L_end: + + +/* +vi:ts=4 +*/ + diff --git a/DumpProto/lzo/i386/src/lzo1c_d.sh b/DumpProto/lzo/i386/src/lzo1c_d.sh new file mode 100644 index 0000000..8bc9ce4 --- /dev/null +++ b/DumpProto/lzo/i386/src/lzo1c_d.sh @@ -0,0 +1,178 @@ +/* lzo1c_d.sh -- assembler implementation of the LZO1C decompression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* + * This file has been adapted from code generously contributed by + * Laszlo Molnar aka ML1050 + * + * Many thanks, Laszlo ! + */ + + +/*********************************************************************** +// +************************************************************************/ + + ALIGN3 +.L1: + xorl %eax,%eax + movb (%esi),%al + incl %esi + cmpb $32,%al + jnb .LMATCH + + orb %al,%al + jz .L12 + movl %eax,%ecx +.LIT: + TEST_OP((%edi,%ecx),%ebx) + TEST_IP((%esi,%ecx),%ebx) + rep + movsb +.LM1: + movb (%esi),%al + incl %esi + + cmpb $32,%al + jb .LM2 +.LMATCH: + cmpb $64,%al + jb .LN3 + + movl %eax,%ecx + andb $31,%al + leal -1(%edi),%edx + shrl $5,%ecx + subl %eax,%edx + movb (%esi),%al + incl %esi + + shll $5,%eax + subl %eax,%edx + incl %ecx + xchgl %esi,%edx + TEST_LOOKBEHIND(%esi) + TEST_OP((%edi,%ecx),%ebx) + rep + movsb + movl %edx,%esi + jmp .L1 + + ALIGN3 +.L12: + LODSB + leal 32(%eax),%ecx + cmpb $248,%al + jb .LIT + + movl $280,%ecx + subb $248,%al + jz .L11 + xchgl %eax,%ecx + xorb %al,%al + shll %cl,%eax + xchgl %eax,%ecx +.L11: + TEST_OP((%edi,%ecx),%ebx) + TEST_IP((%esi,%ecx),%ebx) + rep + movsb + jmp .L1 + + ALIGN3 +.LM2: + leal -1(%edi),%edx + subl %eax,%edx + LODSB + shll $5,%eax + subl %eax,%edx + xchgl %esi,%edx + TEST_LOOKBEHIND(%esi) + TEST_OP(4(%edi),%ebx) + movsb + movsb + movsb + movl %edx,%esi + movsb + xorl %eax,%eax + jmp .LM1 +.LN3: + andb $31,%al + movl %eax,%ecx + jnz .LN6 + movb $31,%cl +.LN4: + LODSB + orb %al,%al + jnz .LN5 + addl N_255,%ecx + jmp .LN4 + + ALIGN3 +.LN5: + addl %eax,%ecx +.LN6: + movb (%esi),%al + incl %esi + + movl %eax,%ebx + andb $63,%al + movl %edi,%edx + subl %eax,%edx + + movb (%esi),%al + incl %esi + + shll $6,%eax + subl %eax,%edx + cmpl %edi,%edx + jz .LEOF + + xchgl %edx,%esi + leal 3(%ecx),%ecx + TEST_LOOKBEHIND(%esi) + TEST_OP((%edi,%ecx),%eax) + rep + movsb + + movl %edx,%esi + xorl %eax,%eax + shrl $6,%ebx + movl %ebx,%ecx + jnz .LIT + jmp .L1 + +.LEOF: +/**** xorl %eax,%eax eax=0 from above */ + + cmpl $1,%ecx /* ecx must be 1 */ + setnz %al + + +/* +vi:ts=4 +*/ + diff --git a/DumpProto/lzo/i386/src/lzo1c_s1.s b/DumpProto/lzo/i386/src/lzo1c_s1.s new file mode 100644 index 0000000..4b924ac --- /dev/null +++ b/DumpProto/lzo/i386/src/lzo1c_s1.s @@ -0,0 +1,47 @@ +/* lzo1c_s1.s -- LZO1C decompression in assembler (i386 + gcc) + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/*********************************************************************** +// +************************************************************************/ + +#include "lzo_asm.h" + + .text + + LZO_PUBLIC(lzo1c_decompress_asm) + +#include "enter.sh" +#include "lzo1c_d.sh" +#include "leave.sh" + + LZO_PUBLIC_END(lzo1c_decompress_asm) + + +/* +vi:ts=4 +*/ + diff --git a/DumpProto/lzo/i386/src/lzo1c_s2.s b/DumpProto/lzo/i386/src/lzo1c_s2.s new file mode 100644 index 0000000..80cae6d --- /dev/null +++ b/DumpProto/lzo/i386/src/lzo1c_s2.s @@ -0,0 +1,51 @@ +/* lzo1c_s2.s -- LZO1C decompression in assembler (i386 + gcc) + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/*********************************************************************** +// +************************************************************************/ + +#define LZO_TEST_DECOMPRESS_OVERRUN_INPUT +#define LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT +#define LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND + +#include "lzo_asm.h" + + .text + + LZO_PUBLIC(lzo1c_decompress_asm_safe) + +#include "enter.sh" +#include "lzo1c_d.sh" +#include "leave.sh" + + LZO_PUBLIC_END(lzo1c_decompress_asm_safe) + + +/* +vi:ts=4 +*/ + diff --git a/DumpProto/lzo/i386/src/lzo1f_d.sh b/DumpProto/lzo/i386/src/lzo1f_d.sh new file mode 100644 index 0000000..f0c3fc2 --- /dev/null +++ b/DumpProto/lzo/i386/src/lzo1f_d.sh @@ -0,0 +1,170 @@ +/* lzo1f_d.sh -- assembler implementation of the LZO1F decompression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* + * This file has been adapted from code generously contributed by + * Laszlo Molnar aka ML1050 + * + * Many thanks, Laszlo ! + */ + + +/*********************************************************************** +// +************************************************************************/ + + ALIGN3 +.L0: + xorl %eax,%eax + movb (%esi),%al + incl %esi + cmpb $31,%al + ja .LM2 + + orb %al,%al + movl %eax,%ecx + jnz .L2 +1: + LODSB + orb %al,%al + jnz 2f + addl N_255,%ecx + jmp 1b +2: + lea 31(%eax,%ecx),%ecx +.L2: + TEST_OP((%edi,%ecx),%ebx) + TEST_IP((%esi,%ecx),%ebx) + movb %cl,%al + shrl $2,%ecx + rep + movsl + andb $3,%al + jz 1f + movl (%esi),%ebx + addl %eax,%esi + movl %ebx,(%edi) + addl %eax,%edi +1: + movb (%esi),%al + incl %esi +.LM1: + cmpb $31,%al + jbe .LM21 + +.LM2: + cmpb $223,%al + ja .LM3 + + movl %eax,%ecx + shrl $2,%eax + lea -1(%edi),%edx + andb $7,%al + shrl $5,%ecx + movl %eax,%ebx + + movb (%esi),%al + leal (%ebx,%eax,8),%eax + incl %esi +.LM5: + subl %eax,%edx + addl $2,%ecx + xchgl %edx,%esi + TEST_LOOKBEHIND(%esi) + TEST_OP((%edi,%ecx),%ebx) + cmpl $6,%ecx + jb 1f + cmpl $4,%eax + jb 1f + movb %cl,%al + shrl $2,%ecx + rep + movsl + andb $3,%al + movb %al,%cl +1: + rep + movsb + movl %edx,%esi +.LN1: + movb -2(%esi),%cl + andl $3,%ecx + jz .L0 + movl (%esi),%eax + addl %ecx,%esi + movl %eax,(%edi) + addl %ecx,%edi + xorl %eax,%eax + movb (%esi),%al + incl %esi + jmp .LM1 +.LM21: + TEST_OP(3(%edi),%edx) + shrl $2,%eax + leal -0x801(%edi),%edx + movl %eax,%ecx + movb (%esi),%al + incl %esi + leal (%ecx,%eax,8),%eax + subl %eax,%edx + TEST_LOOKBEHIND(%edx) + movl (%edx),%eax + movl %eax,(%edi) + addl $3,%edi + jmp .LN1 +1: + LODSB + orb %al,%al + jnz 2f + addl N_255,%ecx + jmp 1b +2: + lea 31(%eax,%ecx),%ecx + jmp .LM4 + + ALIGN3 +.LM3: + andb $31,%al + movl %eax,%ecx + jz 1b +.LM4: + movl %edi,%edx + movw (%esi),%ax + addl $2,%esi + shrl $2,%eax + jnz .LM5 + +.LEOF: +/**** xorl %eax,%eax eax=0 from above */ + + cmpl $1,%ecx /* ecx must be 1 */ + setnz %al + + +/* +vi:ts=4 +*/ + diff --git a/DumpProto/lzo/i386/src/lzo1f_f1.s b/DumpProto/lzo/i386/src/lzo1f_f1.s new file mode 100644 index 0000000..a672fc2 --- /dev/null +++ b/DumpProto/lzo/i386/src/lzo1f_f1.s @@ -0,0 +1,47 @@ +/* lzo1f_f1.s -- fast LZO1F decompression in assembler (i386 + gcc) + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/*********************************************************************** +// +************************************************************************/ + +#include "lzo_asm.h" + + .text + + LZO_PUBLIC(lzo1f_decompress_asm_fast) + +#include "enter.sh" +#include "lzo1f_d.sh" +#include "leave.sh" + + LZO_PUBLIC_END(lzo1f_decompress_asm_fast) + + +/* +vi:ts=4 +*/ + diff --git a/DumpProto/lzo/i386/src/lzo1f_f2.s b/DumpProto/lzo/i386/src/lzo1f_f2.s new file mode 100644 index 0000000..9b5e451 --- /dev/null +++ b/DumpProto/lzo/i386/src/lzo1f_f2.s @@ -0,0 +1,51 @@ +/* lzo1f_f2.s -- fast LZO1F decompression in assembler (i386 + gcc) + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/*********************************************************************** +// +************************************************************************/ + +#define LZO_TEST_DECOMPRESS_OVERRUN_INPUT +#define LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT +#define LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND + +#include "lzo_asm.h" + + .text + + LZO_PUBLIC(lzo1f_decompress_asm_fast_safe) + +#include "enter.sh" +#include "lzo1f_d.sh" +#include "leave.sh" + + LZO_PUBLIC_END(lzo1f_decompress_asm_fast_safe) + + +/* +vi:ts=4 +*/ + diff --git a/DumpProto/lzo/i386/src/lzo1x_d.sh b/DumpProto/lzo/i386/src/lzo1x_d.sh new file mode 100644 index 0000000..f297bea --- /dev/null +++ b/DumpProto/lzo/i386/src/lzo1x_d.sh @@ -0,0 +1,397 @@ +/* lzo1x_d.sh -- assembler implementation of the LZO1X decompression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* + * This file has been adapted from code generously contributed by + * Laszlo Molnar aka ML1050 + * + * Many thanks, Laszlo ! + * + * I (Markus) have optimized the fast version a lot, so enjoy... + */ + + +#if !defined(LZO1X) && !defined(LZO1Y) +# define LZO1X +#endif + +#if defined(LZO_FAST) +# define NN 3 +#else +# define NN 0 +#endif + + +/*********************************************************************** +// init +************************************************************************/ + + xorl %eax,%eax + xorl %ebx,%ebx /* high bits 9-32 stay 0 */ + lodsb + cmpb $17,%al + jbe .L01 + subb $17-NN,%al +#if defined(LZO_FAST) + jmp .LFLR +#else + cmpb $4,%al + jae .LFLR +#if 1 + TEST_OP((%edi,%eax),%edx) + TEST_IP((%esi,%eax),%edx) + movl %eax,%ecx + jmp .LFLR2 +#else + jmp .LFLR3 +#endif +#endif + + +/*********************************************************************** +// literal run +************************************************************************/ + +0: addl N_255,%eax + TEST_IP(18(%esi,%eax),%edx) /* minimum */ +1: movb (%esi),%bl + incl %esi + orb %bl,%bl + jz 0b + leal 18+NN(%eax,%ebx),%eax + jmp 3f + + + ALIGN3 +.L00: +#ifdef LZO_DEBUG + andl $0xffffff00,%eax ; jnz .L_assert_fail + andl $0xffffff00,%ebx ; jnz .L_assert_fail + xorl %eax,%eax ; xorl %ebx,%ebx + xorl %ecx,%ecx ; xorl %edx,%edx +#endif + TEST_IP_R(%esi) + LODSB +.L01: + cmpb $16,%al + jae .LMATCH + +/* a literal run */ + orb %al,%al + jz 1b + addl $3+NN,%eax +3: +.LFLR: + TEST_OP(-NN(%edi,%eax),%edx) + TEST_IP(-NN(%esi,%eax),%edx) +#if defined(LZO_FAST) + movl %eax,%ecx + NOTL_3(%eax) + shrl $2,%ecx + andl N_3,%eax + COPYL(%esi,%edi,%edx) + subl %eax,%esi + subl %eax,%edi +#else + movl %eax,%ecx + shrl $2,%eax + andl N_3,%ecx + COPYL_C(%esi,%edi,%edx,%eax) +.LFLR2: + rep + movsb +#endif + +#ifdef LZO_DEBUG + andl $0xffffff00,%eax ; jnz .L_assert_fail + andl $0xffffff00,%ebx ; jnz .L_assert_fail + xorl %eax,%eax ; xorl %ebx,%ebx + xorl %ecx,%ecx ; xorl %edx,%edx +#endif + LODSB + cmpb $16,%al + jae .LMATCH + + +/*********************************************************************** +// R1 +************************************************************************/ + + TEST_OP(3(%edi),%edx) + shrl $2,%eax + movb (%esi),%bl +#if defined(LZO1X) + leal -0x801(%edi),%edx +#elif defined(LZO1Y) + leal -0x401(%edi),%edx +#endif + leal (%eax,%ebx,4),%eax + incl %esi + subl %eax,%edx + TEST_LOOKBEHIND(%edx) +#if defined(LZO_FAST) + movl (%edx),%ecx + movl %ecx,(%edi) +#else + movb (%edx),%al + movb %al,(%edi) + movb 1(%edx),%al + movb %al,1(%edi) + movb 2(%edx),%al + movb %al,2(%edi) +#endif + addl N_3,%edi + jmp .LMDONE + + +/*********************************************************************** +// M2 +************************************************************************/ + + ALIGN3 +.LMATCH: + cmpb $64,%al + jb .LM3MATCH + +/* a M2 match */ + movl %eax,%ecx + shrl $2,%eax + leal -1(%edi),%edx +#if defined(LZO1X) + andl $7,%eax + movb (%esi),%bl + shrl $5,%ecx + leal (%eax,%ebx,8),%eax +#elif defined(LZO1Y) + andl N_3,%eax + movb (%esi),%bl + shrl $4,%ecx + leal (%eax,%ebx,4),%eax +#endif + incl %esi + subl %eax,%edx + +#if defined(LZO_FAST) +#if defined(LZO1X) + addl $1+3,%ecx +#elif defined(LZO1Y) + addl $2,%ecx +#endif +#else +#if defined(LZO1X) + incl %ecx +#elif defined(LZO1Y) + decl %ecx +#endif +#endif + + cmpl N_3,%eax + jae .LCOPYLONG + jmp .LCOPYBYTE + + +/*********************************************************************** +// M3 +************************************************************************/ + +0: addl N_255,%eax + TEST_IP(3(%esi),%edx) /* minimum */ +1: movb (%esi),%bl + incl %esi + orb %bl,%bl + jz 0b + leal 33+NN(%eax,%ebx),%ecx + xorl %eax,%eax + jmp 3f + + + ALIGN3 +.LM3MATCH: + cmpb $32,%al + jb .LM4MATCH + +/* a M3 match */ + andl $31,%eax + jz 1b + lea 2+NN(%eax),%ecx +3: +#ifdef LZO_DEBUG + andl $0xffff0000,%eax ; jnz .L_assert_fail +#endif + movw (%esi),%ax + leal -1(%edi),%edx + shrl $2,%eax + addl $2,%esi + subl %eax,%edx + + cmpl N_3,%eax + jb .LCOPYBYTE + + +/*********************************************************************** +// copy match +************************************************************************/ + + ALIGN1 +.LCOPYLONG: /* copy match using longwords */ + TEST_LOOKBEHIND(%edx) +#if defined(LZO_FAST) + leal -3(%edi,%ecx),%eax + shrl $2,%ecx + TEST_OP_R(%eax) + COPYL(%edx,%edi,%ebx) + movl %eax,%edi + xorl %ebx,%ebx +#else + TEST_OP((%edi,%ecx),%eax) + movl %ecx,%ebx + shrl $2,%ebx + jz 2f + COPYL_C(%edx,%edi,%eax,%ebx) + andl N_3,%ecx + jz 1f +2: COPYB_C(%edx,%edi,%al,%ecx) +1: +#endif + +.LMDONE: + movb -2(%esi),%al + andl N_3,%eax + jz .L00 +.LFLR3: + TEST_OP((%edi,%eax),%edx) + TEST_IP((%esi,%eax),%edx) +#if defined(LZO_FAST) + movl (%esi),%edx + addl %eax,%esi + movl %edx,(%edi) + addl %eax,%edi +#else + COPYB_C(%esi,%edi,%cl,%eax) +#endif + +#ifdef LZO_DEBUG + andl $0xffffff00,%eax ; jnz .L_assert_fail + andl $0xffffff00,%ebx ; jnz .L_assert_fail + xorl %eax,%eax ; xorl %ebx,%ebx + xorl %ecx,%ecx ; xorl %edx,%edx +#endif + LODSB + jmp .LMATCH + + + ALIGN3 +.LCOPYBYTE: /* copy match using bytes */ + TEST_LOOKBEHIND(%edx) + TEST_OP(-NN(%edi,%ecx),%eax) + xchgl %edx,%esi +#if defined(LZO_FAST) + subl N_3,%ecx +#endif + rep + movsb + movl %edx,%esi + jmp .LMDONE + + +/*********************************************************************** +// M4 +************************************************************************/ + +0: addl N_255,%ecx + TEST_IP(3(%esi),%edx) /* minimum */ +1: movb (%esi),%bl + incl %esi + orb %bl,%bl + jz 0b + leal 9+NN(%ebx,%ecx),%ecx + jmp 3f + + + ALIGN3 +.LM4MATCH: + cmpb $16,%al + jb .LM1MATCH + +/* a M4 match */ + movl %eax,%ecx + andl $8,%eax + shll $13,%eax /* save in bit 16 */ + andl $7,%ecx + jz 1b + addl $2+NN,%ecx +3: +#ifdef LZO_DEBUG + movl %eax,%edx ; andl $0xfffe0000,%edx ; jnz .L_assert_fail +#endif + movw (%esi),%ax + addl $2,%esi + leal -0x4000(%edi),%edx + shrl $2,%eax + jz .LEOF + subl %eax,%edx + jmp .LCOPYLONG + + +/*********************************************************************** +// M1 +************************************************************************/ + + ALIGN3 +.LM1MATCH: +/* a M1 match */ + TEST_OP(2(%edi),%edx) + shrl $2,%eax + movb (%esi),%bl + leal -1(%edi),%edx + leal (%eax,%ebx,4),%eax + incl %esi + subl %eax,%edx + TEST_LOOKBEHIND(%edx) + + movb (%edx),%al /* we must use this because edx can be edi-1 */ + movb %al,(%edi) + movb 1(%edx),%bl + movb %bl,1(%edi) + addl $2,%edi + jmp .LMDONE + + +/*********************************************************************** +// +************************************************************************/ + +.LEOF: +/**** xorl %eax,%eax eax=0 from above */ + + cmpl $3+NN,%ecx /* ecx must be 3/6 */ + setnz %al + + +/* +vi:ts=4 +*/ + diff --git a/DumpProto/lzo/i386/src/lzo1x_f1.s b/DumpProto/lzo/i386/src/lzo1x_f1.s new file mode 100644 index 0000000..96a03e2 --- /dev/null +++ b/DumpProto/lzo/i386/src/lzo1x_f1.s @@ -0,0 +1,49 @@ +/* lzo1x_f1.s -- fast LZO1X decompression in assembler (i386 + gcc) + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/*********************************************************************** +// +************************************************************************/ + +#define LZO_FAST + +#include "lzo_asm.h" + + .text + + LZO_PUBLIC(lzo1x_decompress_asm_fast) + +#include "enter.sh" +#include "lzo1x_d.sh" +#include "leave.sh" + + LZO_PUBLIC_END(lzo1x_decompress_asm_fast) + + +/* +vi:ts=4 +*/ + diff --git a/DumpProto/lzo/i386/src/lzo1x_f2.s b/DumpProto/lzo/i386/src/lzo1x_f2.s new file mode 100644 index 0000000..d3d5880 --- /dev/null +++ b/DumpProto/lzo/i386/src/lzo1x_f2.s @@ -0,0 +1,53 @@ +/* lzo1x_f2.s -- fast LZO1X decompression in assembler (i386 + gcc) + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/*********************************************************************** +// +************************************************************************/ + +#define LZO_FAST + +#define LZO_TEST_DECOMPRESS_OVERRUN_INPUT +#define LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT +#define LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND + +#include "lzo_asm.h" + + .text + + LZO_PUBLIC(lzo1x_decompress_asm_fast_safe) + +#include "enter.sh" +#include "lzo1x_d.sh" +#include "leave.sh" + + LZO_PUBLIC_END(lzo1x_decompress_asm_fast_safe) + + +/* +vi:ts=4 +*/ + diff --git a/DumpProto/lzo/i386/src/lzo1x_s1.s b/DumpProto/lzo/i386/src/lzo1x_s1.s new file mode 100644 index 0000000..c5c36b7 --- /dev/null +++ b/DumpProto/lzo/i386/src/lzo1x_s1.s @@ -0,0 +1,47 @@ +/* lzo1x_s1.s -- LZO1X decompression in assembler (i386 + gcc) + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/*********************************************************************** +// +************************************************************************/ + +#include "lzo_asm.h" + + .text + + LZO_PUBLIC(lzo1x_decompress_asm) + +#include "enter.sh" +#include "lzo1x_d.sh" +#include "leave.sh" + + LZO_PUBLIC_END(lzo1x_decompress_asm) + + +/* +vi:ts=4 +*/ + diff --git a/DumpProto/lzo/i386/src/lzo1x_s2.s b/DumpProto/lzo/i386/src/lzo1x_s2.s new file mode 100644 index 0000000..db3817a --- /dev/null +++ b/DumpProto/lzo/i386/src/lzo1x_s2.s @@ -0,0 +1,51 @@ +/* lzo1x_s2.s -- LZO1X decompression in assembler (i386 + gcc) + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/*********************************************************************** +// +************************************************************************/ + +#define LZO_TEST_DECOMPRESS_OVERRUN_INPUT +#define LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT +#define LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND + +#include "lzo_asm.h" + + .text + + LZO_PUBLIC(lzo1x_decompress_asm_safe) + +#include "enter.sh" +#include "lzo1x_d.sh" +#include "leave.sh" + + LZO_PUBLIC_END(lzo1x_decompress_asm_safe) + + +/* +vi:ts=4 +*/ + diff --git a/DumpProto/lzo/i386/src/lzo1y_f1.s b/DumpProto/lzo/i386/src/lzo1y_f1.s new file mode 100644 index 0000000..f2a407e --- /dev/null +++ b/DumpProto/lzo/i386/src/lzo1y_f1.s @@ -0,0 +1,51 @@ +/* lzo1y_f1.s -- fast LZO1Y decompression in assembler (i386 + gcc) + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/*********************************************************************** +// +************************************************************************/ + +#define LZO_FAST + +#include "lzo_asm.h" + + .text + + LZO_PUBLIC(lzo1y_decompress_asm_fast) + +#define LZO1Y + +#include "enter.sh" +#include "lzo1x_d.sh" +#include "leave.sh" + + LZO_PUBLIC_END(lzo1y_decompress_asm_fast) + + +/* +vi:ts=4 +*/ + diff --git a/DumpProto/lzo/i386/src/lzo1y_f2.s b/DumpProto/lzo/i386/src/lzo1y_f2.s new file mode 100644 index 0000000..34028ca --- /dev/null +++ b/DumpProto/lzo/i386/src/lzo1y_f2.s @@ -0,0 +1,55 @@ +/* lzo1y_f2.s -- fast LZO1Y decompression in assembler (i386 + gcc) + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/*********************************************************************** +// +************************************************************************/ + +#define LZO_FAST + +#define LZO_TEST_DECOMPRESS_OVERRUN_INPUT +#define LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT +#define LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND + +#include "lzo_asm.h" + + .text + + LZO_PUBLIC(lzo1y_decompress_asm_fast_safe) + +#define LZO1Y + +#include "enter.sh" +#include "lzo1x_d.sh" +#include "leave.sh" + + LZO_PUBLIC_END(lzo1y_decompress_asm_fast_safe) + + +/* +vi:ts=4 +*/ + diff --git a/DumpProto/lzo/i386/src/lzo1y_s1.s b/DumpProto/lzo/i386/src/lzo1y_s1.s new file mode 100644 index 0000000..d9989ee --- /dev/null +++ b/DumpProto/lzo/i386/src/lzo1y_s1.s @@ -0,0 +1,49 @@ +/* lzo1y_s1.s -- LZO1Y decompression in assembler (i386 + gcc) + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/*********************************************************************** +// +************************************************************************/ + +#include "lzo_asm.h" + + .text + + LZO_PUBLIC(lzo1y_decompress_asm) + +#define LZO1Y + +#include "enter.sh" +#include "lzo1x_d.sh" +#include "leave.sh" + + LZO_PUBLIC_END(lzo1y_decompress_asm) + + +/* +vi:ts=4 +*/ + diff --git a/DumpProto/lzo/i386/src/lzo1y_s2.s b/DumpProto/lzo/i386/src/lzo1y_s2.s new file mode 100644 index 0000000..68a19b0 --- /dev/null +++ b/DumpProto/lzo/i386/src/lzo1y_s2.s @@ -0,0 +1,53 @@ +/* lzo1y_s2.s -- LZO1Y decompression in assembler (i386 + gcc) + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/*********************************************************************** +// +************************************************************************/ + +#define LZO_TEST_DECOMPRESS_OVERRUN_INPUT +#define LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT +#define LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND + +#include "lzo_asm.h" + + .text + + LZO_PUBLIC(lzo1y_decompress_asm_safe) + +#define LZO1Y + +#include "enter.sh" +#include "lzo1x_d.sh" +#include "leave.sh" + + LZO_PUBLIC_END(lzo1y_decompress_asm_safe) + + +/* +vi:ts=4 +*/ + diff --git a/DumpProto/lzo/i386/src/lzo_asm.h b/DumpProto/lzo/i386/src/lzo_asm.h new file mode 100644 index 0000000..ade9df0 --- /dev/null +++ b/DumpProto/lzo/i386/src/lzo_asm.h @@ -0,0 +1,257 @@ +/* lzo_asm.h -- LZO assembler stuff + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/*********************************************************************** +// +************************************************************************/ + +#if !defined(__i386__) +# error +#endif + +#if !defined(IN_CONFIGURE) +#if defined(LZO_HAVE_CONFIG_H) +# include +#else + /* manual configuration - see defaults below */ +# if defined(__ELF__) +# define MFX_ASM_HAVE_TYPE +# define MFX_ASM_NAME_NO_UNDERSCORES +# elif defined(__linux__) /* Linux a.out */ +# define MFX_ASM_ALIGN_PTWO +# elif defined(__DJGPP__) +# define MFX_ASM_ALIGN_PTWO +# elif defined(__GO32__) /* djgpp v1 */ +# define MFX_ASM_CANNOT_USE_EBP +# elif defined(__EMX__) +# define MFX_ASM_ALIGN_PTWO +# define MFX_ASM_CANNOT_USE_EBP +# endif +#endif +#endif + + +/*********************************************************************** +// name always uses underscores +// [ OLD: name (default: with underscores) ] +************************************************************************/ + +#if !defined(LZO_ASM_NAME) +# define LZO_ASM_NAME(n) _ ## n +#if 0 +# if defined(MFX_ASM_NAME_NO_UNDERSCORES) +# define LZO_ASM_NAME(n) n +# else +# define LZO_ASM_NAME(n) _ ## n +# endif +#endif +#endif + + +/*********************************************************************** +// .type (default: do not use) +************************************************************************/ + +#if defined(MFX_ASM_HAVE_TYPE) +# define LZO_PUBLIC(func) \ + ALIGN3 ; .type LZO_ASM_NAME(func),@function ; \ + .globl LZO_ASM_NAME(func) ; LZO_ASM_NAME(func): +# define LZO_PUBLIC_END(func) \ + .size LZO_ASM_NAME(func),.-LZO_ASM_NAME(func) +#else +# define LZO_PUBLIC(func) \ + ALIGN3 ; .globl LZO_ASM_NAME(func) ; LZO_ASM_NAME(func): +# define LZO_PUBLIC_END(func) +#endif + + +/*********************************************************************** +// .align (default: bytes) +************************************************************************/ + +#if !defined(MFX_ASM_ALIGN_BYTES) && !defined(MFX_ASM_ALIGN_PTWO) +# define MFX_ASM_ALIGN_BYTES +#endif + +#if !defined(LZO_ASM_ALIGN) +# if defined(MFX_ASM_ALIGN_PTWO) +# define LZO_ASM_ALIGN(x) .align x +# else +# define LZO_ASM_ALIGN(x) .align (1 << (x)) +# endif +#endif + +#define ALIGN1 LZO_ASM_ALIGN(1) +#define ALIGN2 LZO_ASM_ALIGN(2) +#define ALIGN3 LZO_ASM_ALIGN(3) + + +/*********************************************************************** +// ebp usage (default: can use) +************************************************************************/ + +#if !defined(MFX_ASM_CANNOT_USE_EBP) +# if 1 && !defined(N_3_EBP) && !defined(N_255_EBP) +# define N_3_EBP +# endif +# if 0 && !defined(N_3_EBP) && !defined(N_255_EBP) +# define N_255_EBP +# endif +#endif + +#if defined(N_3_EBP) && defined(N_255_EBP) +# error +#endif +#if defined(MFX_ASM_CANNOT_USE_EBP) +# if defined(N_3_EBP) || defined(N_255_EBP) +# error +# endif +#endif + +#if !defined(N_3) +# if defined(N_3_EBP) +# define N_3 %ebp +# else +# define N_3 $3 +# endif +#endif + +#if !defined(N_255) +# if defined(N_255_EBP) +# define N_255 %ebp +# define NOTL_3(r) xorl %ebp,r +# else +# define N_255 $255 +# endif +#endif + +#if !defined(NOTL_3) +# define NOTL_3(r) xorl N_3,r +#endif + + +/*********************************************************************** +// +************************************************************************/ + +#ifndef INP +#define INP 4+36(%esp) +#define INS 8+36(%esp) +#define OUTP 12+36(%esp) +#define OUTS 16+36(%esp) +#endif + +#define INEND 4(%esp) +#define OUTEND (%esp) + + +#if defined(LZO_TEST_DECOMPRESS_OVERRUN_INPUT) +# define TEST_IP_R(r) cmpl r,INEND ; jb .L_input_overrun +# define TEST_IP(addr,r) leal addr,r ; TEST_IP_R(r) +#else +# define TEST_IP_R(r) +# define TEST_IP(addr,r) +#endif + +#if defined(LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT) +# define TEST_OP_R(r) cmpl r,OUTEND ; jb .L_output_overrun +# define TEST_OP(addr,r) leal addr,r ; TEST_OP_R(r) +#else +# define TEST_OP_R(r) +# define TEST_OP(addr,r) +#endif + +#if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND) +# define TEST_LOOKBEHIND(r) cmpl OUTP,r ; jb .L_lookbehind_overrun +#else +# define TEST_LOOKBEHIND(r) +#endif + + +/*********************************************************************** +// +************************************************************************/ + +#define LODSB movb (%esi),%al ; incl %esi + +#define MOVSB(r1,r2,x) movb (r1),x ; incl r1 ; movb x,(r2) ; incl r2 +#define MOVSW(r1,r2,x) movb (r1),x ; movb x,(r2) ; \ + movb 1(r1),x ; addl $2,r1 ; \ + movb x,1(r2) ; addl $2,r2 +#define MOVSL(r1,r2,x) movl (r1),x ; addl $4,r1 ; movl x,(r2) ; addl $4,r2 + +#if defined(LZO_DEBUG) +#define COPYB_C(r1,r2,x,rc) \ + cmpl $0,rc ; jz .L_assert_fail; \ + 9: MOVSB(r1,r2,x) ; decl rc ; jnz 9b +#define COPYL_C(r1,r2,x,rc) \ + cmpl $0,rc ; jz .L_assert_fail; \ + 9: MOVSL(r1,r2,x) ; decl rc ; jnz 9b +#else +#define COPYB_C(r1,r2,x,rc) \ + 9: MOVSB(r1,r2,x) ; decl rc ; jnz 9b +#define COPYL_C(r1,r2,x,rc) \ + 9: MOVSL(r1,r2,x) ; decl rc ; jnz 9b +#endif + +#define COPYB(r1,r2,x) COPYB_C(r1,r2,x,%ecx) +#define COPYL(r1,r2,x) COPYL_C(r1,r2,x,%ecx) + + +/*********************************************************************** +// not used +************************************************************************/ + +#if 0 + +#if 0 +#define REP_MOVSB(x) rep ; movsb +#define REP_MOVSL(x) shrl $2,%ecx ; rep ; movsl +#elif 1 +#define REP_MOVSB(x) COPYB(%esi,%edi,x) +#define REP_MOVSL(x) shrl $2,%ecx ; COPYL(%esi,%edi,x) +#else +#define REP_MOVSB(x) rep ; movsb +#define REP_MOVSL(x) jmp 9f ; 8: movsb ; decl %ecx ; \ + 9: testl $3,%edi ; jnz 8b ; \ + movl %ecx,x ; shrl $2,%ecx ; andl $3,x ; \ + rep ; movsl ; movl x,%ecx ; rep ; movsb +#endif + +#if 1 +#define NEGL(x) negl x +#else +#define NEGL(x) xorl $-1,x ; incl x +#endif + +#endif + + + +/* +vi:ts=4 +*/ + diff --git a/DumpProto/lzo/io.c b/DumpProto/lzo/io.c new file mode 100644 index 0000000..6d71fcc --- /dev/null +++ b/DumpProto/lzo/io.c @@ -0,0 +1,107 @@ +/* io.c -- portable io functions + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "lzo_conf.h" +#include + + +#if !defined(NO_STDIO_H) + +#include + +#undef lzo_fread +#undef lzo_fwrite + + +/*********************************************************************** +// +************************************************************************/ + +LZO_PUBLIC(lzo_uint) +lzo_fread(LZO_FILEP ff, lzo_voidp s, lzo_uint len) +{ + FILE *f = (FILE *) ff; +#if 1 && (LZO_UINT_MAX <= SIZE_T_MAX) + return fread(s,1,len,f); +#else + lzo_byte *p = (lzo_byte *) s; + lzo_uint l = 0; + size_t k; + unsigned char *b; + unsigned char buf[512]; + + while (l < len) + { + k = len - l > sizeof(buf) ? sizeof(buf) : (size_t) (len - l); + k = fread(buf,1,k,f); + if (k <= 0) + break; + l += k; + b = buf; do *p++ = *b++; while (--k > 0); + } + return l; +#endif +} + + +/*********************************************************************** +// +************************************************************************/ + +LZO_PUBLIC(lzo_uint) +lzo_fwrite(LZO_FILEP ff, const lzo_voidp s, lzo_uint len) +{ + FILE *f = (FILE *) ff; +#if 1 && (LZO_UINT_MAX <= SIZE_T_MAX) + return fwrite(s,1,len,f); +#else + const lzo_byte *p = (const lzo_byte *) s; + lzo_uint l = 0; + size_t k, n; + unsigned char *b; + unsigned char buf[512]; + + while (l < len) + { + k = len - l > sizeof(buf) ? sizeof(buf) : (size_t) (len - l); + b = buf; n = k; do *b++ = *p++; while (--n > 0); + k = fwrite(buf,1,k,f); + if (k <= 0) + break; + l += k; + } + return l; +#endif +} + + +#endif /* !NO_STDIO_H */ + + +/* +vi:ts=4:et +*/ diff --git a/DumpProto/lzo/lzo.vcproj b/DumpProto/lzo/lzo.vcproj new file mode 100644 index 0000000..839a7a7 --- /dev/null +++ b/DumpProto/lzo/lzo.vcproj @@ -0,0 +1,615 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DumpProto/lzo/lzo.vcproj.vspscc b/DumpProto/lzo/lzo.vcproj.vspscc new file mode 100644 index 0000000..b6d3289 --- /dev/null +++ b/DumpProto/lzo/lzo.vcproj.vspscc @@ -0,0 +1,10 @@ +"" +{ +"FILE_VERSION" = "9237" +"ENLISTMENT_CHOICE" = "NEVER" +"PROJECT_FILE_RELATIVE_PATH" = "" +"NUMBER_OF_EXCLUDED_FILES" = "0" +"ORIGINAL_PROJECT_FILE_PATH" = "" +"NUMBER_OF_NESTED_PROJECTS" = "0" +"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER" +} diff --git a/DumpProto/lzo/lzo.vcxproj b/DumpProto/lzo/lzo.vcxproj new file mode 100644 index 0000000..fc3e849 --- /dev/null +++ b/DumpProto/lzo/lzo.vcxproj @@ -0,0 +1,200 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {3AE0E6E6-B750-4769-9A6E-0D47012F1B40} + lzo + SAK + SAK + SAK + SAK + Win32Proj + 10.0 + + + + StaticLibrary + v143 + MultiByte + true + + + StaticLibrary + v143 + MultiByte + + + + + + + + + + + + + <_ProjectFileVersion>12.0.21005.1 + + + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + + + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + + + + Disabled + .;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + Level3 + EditAndContinue + + + + + MaxSpeed + true + .;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreaded + true + + Level3 + ProgramDatabase + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DumpProto/lzo/lzo.vcxproj.filters b/DumpProto/lzo/lzo.vcxproj.filters new file mode 100644 index 0000000..1adfcc1 --- /dev/null +++ b/DumpProto/lzo/lzo.vcxproj.filters @@ -0,0 +1,341 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + 소스 파일 + + + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + 헤더 파일 + + + \ No newline at end of file diff --git a/DumpProto/lzo/lzo1.c b/DumpProto/lzo/lzo1.c new file mode 100644 index 0000000..a7c38e8 --- /dev/null +++ b/DumpProto/lzo/lzo1.c @@ -0,0 +1,643 @@ +/* lzo1.c -- implementation of the LZO1 algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include +#include "lzo_conf.h" + + +/*********************************************************************** +// The next two defines can be changed to customize LZO1. +// The default version is LZO1-5/1. +************************************************************************/ + +/* run bits (3 - 5) - the compressor and the decompressor + * must use the same value. */ +#if !defined(RBITS) +# define RBITS 5 +#endif + +/* compression level (1 - 9) - this only affects the compressor. + * 1 is fastest, 9 is best compression ratio */ +#if !defined(CLEVEL) +# define CLEVEL 1 /* fastest by default */ +#endif + + +/* check configuration */ +#if (RBITS < 3 || RBITS > 5) +# error "invalid RBITS" +#endif +#if (CLEVEL < 1 || CLEVEL > 9) +# error "invalid CLEVEL" +#endif + + +/*********************************************************************** +// You should not have to change anything below this line. +************************************************************************/ + +#include "lzo_util.h" + + +/*********************************************************************** +// +************************************************************************/ + +/* + Format of the marker byte + + + 76543210 + -------- + 00000000 a long run (a 'R0' run) - there are short and long R0 runs + 000rrrrr a short run with len r + mmmooooo a short match (len = 2+m, o = offset low bits) + 111ooooo a long match (o = offset low bits) +*/ + + +#define RSIZE (1 << RBITS) +#define RMASK (RSIZE - 1) + +#define OBITS RBITS /* offset and run-length use same bits */ +#define OSIZE (1 << OBITS) +#define OMASK (OSIZE - 1) + +#define MBITS (8 - OBITS) +#define MSIZE (1 << MBITS) +#define MMASK (MSIZE - 1) + + +/* sanity checks */ +#if (OBITS < 3 || OBITS > 5) +# error "invalid OBITS" +#endif +#if (MBITS < 3 || MBITS > 5) +# error "invalid MBITS" +#endif + + +/*********************************************************************** +// some macros to improve readability +************************************************************************/ + +/* Minimum len of a match */ +#define MIN_MATCH 3 +#define THRESHOLD (MIN_MATCH - 1) + +/* Minimum len of match coded in 2 bytes */ +#define MIN_MATCH_SHORT MIN_MATCH + +/* Maximum len of match coded in 2 bytes */ +#define MAX_MATCH_SHORT (THRESHOLD + (MSIZE - 2)) +/* MSIZE - 2: 0 is used to indicate runs, + * MSIZE-1 is used to indicate a long match */ + +/* Minimum len of match coded in 3 bytes */ +#define MIN_MATCH_LONG (MAX_MATCH_SHORT + 1) + +/* Maximum len of match coded in 3 bytes */ +#define MAX_MATCH_LONG (MIN_MATCH_LONG + 255) + +/* Maximum offset of a match */ +#define MAX_OFFSET (1 << (8 + OBITS)) + + +/* + +RBITS | MBITS MIN THR. MSIZE MAXS MINL MAXL MAXO R0MAX R0FAST +======+=============================================================== + 3 | 5 3 2 32 32 33 288 2048 263 256 + 4 | 4 3 2 16 16 17 272 4096 271 264 + 5 | 3 3 2 8 8 9 264 8192 287 280 + + */ + + +/*********************************************************************** +// internal configuration +// all of these affect compression only +************************************************************************/ + +/* return -1 instead of copying if the data cannot be compressed */ +#undef LZO_RETURN_IF_NOT_COMPRESSIBLE + + +/* choose the hashing strategy */ +#ifndef LZO_HASH +#define LZO_HASH LZO_HASH_LZO_INCREMENTAL_A +#endif +#define D_INDEX1(d,p) d = DM((0x21*DX2(p,5,5)) >> 5) +#define D_INDEX2(d,p) d = d ^ D_MASK + +#define DBITS (8 + RBITS) +#include "lzo_dict.h" +#define DVAL_LEN DVAL_LOOKAHEAD + + +/*********************************************************************** +// get algorithm info, return memory required for compression +************************************************************************/ + +LZO_EXTERN(lzo_uint) lzo1_info ( int *rbits, int *clevel ); + +LZO_PUBLIC(lzo_uint) +lzo1_info ( int *rbits, int *clevel ) +{ + if (rbits) + *rbits = RBITS; + if (clevel) + *clevel = CLEVEL; + return D_SIZE * lzo_sizeof(lzo_byte *); +} + + +/*********************************************************************** +// decode a R0 literal run (a long run) +************************************************************************/ + +#define R0MIN (RSIZE) /* Minimum len of R0 run of literals */ +#define R0MAX (R0MIN + 255) /* Maximum len of R0 run of literals */ +#define R0FAST (R0MAX & ~7u) /* R0MAX aligned to 8 byte boundary */ + +#if (R0MAX - R0FAST != 7) || ((R0FAST & 7) != 0) +# error "something went wrong" +#endif + +/* 7 special codes from R0FAST+1 .. R0MAX + * these codes mean long R0 runs with lengths + * 512, 1024, 2048, 4096, 8192, 16384, 32768 */ + + +/*********************************************************************** +// LZO1 decompress a block of data. +// +// Could be easily translated into assembly code. +************************************************************************/ + +LZO_PUBLIC(int) +lzo1_decompress ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ + lzo_byte *op; + const lzo_byte *ip; + const lzo_byte * const ip_end = in + in_len; + lzo_uint t; + + LZO_UNUSED(wrkmem); + +#if defined(__LZO_QUERY_DECOMPRESS) + if (__LZO_IS_DECOMPRESS_QUERY(in,in_len,out,out_len,wrkmem)) + return __LZO_QUERY_DECOMPRESS(in,in_len,out,out_len,wrkmem,0,0); +#endif + + op = out; + ip = in; + while (ip < ip_end) + { + t = *ip++; /* get marker */ + + if (t < R0MIN) /* a literal run */ + { + if (t == 0) /* a R0 literal run */ + { + t = *ip++; + if (t >= R0FAST - R0MIN) /* a long R0 run */ + { + t -= R0FAST - R0MIN; + if (t == 0) + t = R0FAST; + else + { +#if 0 + t = 256u << ((unsigned) t); +#else + /* help the optimizer */ + lzo_uint tt = 256; + do tt <<= 1; while (--t > 0); + t = tt; +#endif + } + MEMCPY8_DS(op,ip,t); + continue; + } + t += R0MIN; + } + MEMCPY_DS(op,ip,t); + } + else /* a match */ + { + lzo_uint tt; + /* get match offset */ + const lzo_byte *m_pos = op - 1; + m_pos -= (lzo_uint)(t & OMASK) | (((lzo_uint) *ip++) << OBITS); + + /* get match len */ + if (t >= ((MSIZE - 1) << OBITS)) /* all m-bits set */ + tt = (MIN_MATCH_LONG - THRESHOLD) + *ip++; /* a long match */ + else + tt = t >> OBITS; /* a short match */ + + assert(m_pos >= out); + assert(m_pos < op); + /* a half unrolled loop */ + *op++ = *m_pos++; + *op++ = *m_pos++; + MEMMOVE_DS(op,m_pos,tt); + } + } + + *out_len = op - out; + + /* the next line is the only check in the decompressor ! */ + return (ip == ip_end ? LZO_E_OK : + (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); +} + + +/*********************************************************************** +// code a literal run +************************************************************************/ + +static lzo_byte * +store_run(lzo_byte *op, const lzo_byte *ii, lzo_uint r_len) +{ + assert(r_len > 0); + + /* code a long R0 run */ + if (r_len >= 512) + { + unsigned r_bits = 7; /* 256 << 7 == 32768 */ + do { + while (r_len >= (256u << r_bits)) + { + r_len -= (256u << r_bits); + *op++ = 0; *op++ = LZO_BYTE((R0FAST - R0MIN) + r_bits); + MEMCPY8_DS(op, ii, (256u << r_bits)); + } + } while (--r_bits > 0); + } + while (r_len >= R0FAST) + { + r_len -= R0FAST; + *op++ = 0; *op++ = R0FAST - R0MIN; + MEMCPY8_DS(op, ii, R0FAST); + } + + if (r_len >= R0MIN) + { + /* code a short R0 run */ + *op++ = 0; *op++ = LZO_BYTE(r_len - R0MIN); + MEMCPY_DS(op, ii, r_len); + } + else if (r_len > 0) + { + /* code a 'normal' run */ + *op++ = LZO_BYTE(r_len); + MEMCPY_DS(op, ii, r_len); + } + + assert(r_len == 0); + return op; +} + + + +/*********************************************************************** +// LZO1 compress a block of data. +// +// Could be translated into assembly code without too much effort. +// +// I apologize for the spaghetti code, but it really helps the optimizer. +************************************************************************/ + +static int +do_compress ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ + const lzo_byte *ip; +#if defined(__LZO_HASH_INCREMENTAL) + lzo_uint32 dv; +#endif + lzo_byte *op; + const lzo_byte *m_pos; + const lzo_byte * const ip_end = in+in_len - DVAL_LEN - MIN_MATCH_LONG; + const lzo_byte * const in_end = in+in_len - DVAL_LEN; + const lzo_byte *ii; + lzo_dict_p const dict = (lzo_dict_p) wrkmem; + +#if !defined(NDEBUG) + const lzo_byte *m_pos_sav; +#endif + + op = out; + ip = in; + ii = ip; /* point to start of literal run */ + if (in_len <= MIN_MATCH_LONG + DVAL_LEN + 1) + goto the_end; + + /* init dictionary */ +#if defined(LZO_DETERMINISTIC) + BZERO8_PTR(wrkmem,sizeof(lzo_dict_t),D_SIZE); +#endif + + DVAL_FIRST(dv,ip); + UPDATE_D(dict,0,dv,ip,in); + ip++; + DVAL_NEXT(dv,ip); + + do { + lzo_moff_t m_off; + lzo_uint dindex; + + DINDEX1(dindex,ip); + GINDEX(m_pos,m_off,dict,dindex,in); + if (LZO_CHECK_MPOS(m_pos,m_off,in,ip,MAX_OFFSET)) + goto literal; + if (m_pos[0] == ip[0] && m_pos[1] == ip[1] && m_pos[2] == ip[2]) + goto match; + DINDEX2(dindex,ip); + GINDEX(m_pos,m_off,dict,dindex,in); + if (LZO_CHECK_MPOS(m_pos,m_off,in,ip,MAX_OFFSET)) + goto literal; + if (m_pos[0] == ip[0] && m_pos[1] == ip[1] && m_pos[2] == ip[2]) + goto match; + goto literal; + + +literal: + UPDATE_I(dict,0,dindex,ip,in); + if (++ip >= ip_end) + break; + continue; + +match: + UPDATE_I(dict,0,dindex,ip,in); +#if !defined(NDEBUG) && defined(LZO_DICT_USE_PTR) + m_pos_sav = m_pos; +#endif + m_pos += 3; + { + /* we have found a match (of at least length 3) */ +#if !defined(NDEBUG) && !defined(LZO_DICT_USE_PTR) + assert((m_pos_sav = ip - m_off) == (m_pos - 3)); +#endif + /* 1) store the current literal run */ + if (pd(ip,ii) > 0) + { + lzo_uint t = pd(ip,ii); +#if 1 + /* OPTIMIZED: inline the copying of a short run */ + if (t < R0MIN) + { + *op++ = LZO_BYTE(t); + MEMCPY_DS(op, ii, t); + } + else +#endif + op = store_run(op,ii,t); + } + + /* 2a) compute match len */ + ii = ip; /* point to start of current match */ + + /* we already matched MIN_MATCH bytes, + * m_pos also already advanced MIN_MATCH bytes */ + ip += MIN_MATCH; + assert(m_pos < ip); + + /* try to match another MIN_MATCH_LONG - MIN_MATCH bytes + * to see if we get a long match */ + +#define PS *m_pos++ != *ip++ + +#if (MIN_MATCH_LONG - MIN_MATCH == 2) /* MBITS == 2 */ + if (PS || PS) +#elif (MIN_MATCH_LONG - MIN_MATCH == 6) /* MBITS == 3 */ + if (PS || PS || PS || PS || PS || PS) +#elif (MIN_MATCH_LONG - MIN_MATCH == 14) /* MBITS == 4 */ + if (PS || PS || PS || PS || PS || PS || PS || + PS || PS || PS || PS || PS || PS || PS) +#elif (MIN_MATCH_LONG - MIN_MATCH == 30) /* MBITS == 5 */ + if (PS || PS || PS || PS || PS || PS || PS || PS || + PS || PS || PS || PS || PS || PS || PS || PS || + PS || PS || PS || PS || PS || PS || PS || PS || + PS || PS || PS || PS || PS || PS) +#else +# error "MBITS not yet implemented" +#endif + { + lzo_uint m_len; + + /* 2b) code a short match */ + assert((lzo_moff_t)(ip-m_pos) == m_off); + --ip; /* ran one too far, point back to non-match */ + m_len = ip - ii; + assert(m_len >= MIN_MATCH_SHORT); + assert(m_len <= MAX_MATCH_SHORT); + assert(m_off > 0); + assert(m_off <= MAX_OFFSET); + assert(ii-m_off == m_pos_sav); + assert(lzo_memcmp(m_pos_sav,ii,m_len) == 0); + --m_off; + /* code short match len + low offset bits */ + *op++ = LZO_BYTE(((m_len - THRESHOLD) << OBITS) | + (m_off & OMASK)); + /* code high offset bits */ + *op++ = LZO_BYTE(m_off >> OBITS); + + + /* 2c) Insert phrases (beginning with ii+1) into the dictionary. */ + +#define SI /* nothing */ +#define DI ++ii; DVAL_NEXT(dv,ii); UPDATE_D(dict,0,dv,ii,in); +#define XI assert(ii < ip); ii = ip; DVAL_FIRST(dv,(ip)); + +#if (CLEVEL == 9) || (CLEVEL >= 7 && MBITS <= 4) || (CLEVEL >= 5 && MBITS <= 3) + /* Insert the whole match (ii+1)..(ip-1) into dictionary. */ + ++ii; + do { + DVAL_NEXT(dv,ii); + UPDATE_D(dict,0,dv,ii,in); + } while (++ii < ip); + DVAL_NEXT(dv,ii); + assert(ii == ip); + DVAL_ASSERT(dv,ip); +#elif (CLEVEL >= 3) + SI DI DI XI +#elif (CLEVEL >= 2) + SI DI XI +#else + XI +#endif + + } + else + { + /* we've found a long match - see how far we can still go */ + const lzo_byte *end; + lzo_uint m_len; + + assert(ip <= in_end); + assert(ii == ip - MIN_MATCH_LONG); + +#if defined(__LZO_CHECKER) + if (in_end - ip <= (MAX_MATCH_LONG - MIN_MATCH_LONG)) +#else + if (in_end <= ip + (MAX_MATCH_LONG - MIN_MATCH_LONG)) +#endif + end = in_end; + else + { + end = ip + (MAX_MATCH_LONG - MIN_MATCH_LONG); + assert(end < in_end); + } + + while (ip < end && *m_pos == *ip) + m_pos++, ip++; + assert(ip <= in_end); + + /* 2b) code the long match */ + m_len = ip - ii; + assert(m_len >= MIN_MATCH_LONG); + assert(m_len <= MAX_MATCH_LONG); + assert(m_off > 0); + assert(m_off <= MAX_OFFSET); + assert(ii-m_off == m_pos_sav); + assert(lzo_memcmp(m_pos_sav,ii,m_len) == 0); + assert((lzo_moff_t)(ip-m_pos) == m_off); + --m_off; + /* code long match flag + low offset bits */ + *op++ = LZO_BYTE(((MSIZE - 1) << OBITS) | (m_off & OMASK)); + /* code high offset bits */ + *op++ = LZO_BYTE(m_off >> OBITS); + /* code match len */ + *op++ = LZO_BYTE(m_len - MIN_MATCH_LONG); + + + /* 2c) Insert phrases (beginning with ii+1) into the dictionary. */ +#if (CLEVEL == 9) + /* Insert the whole match (ii+1)..(ip-1) into dictionary. */ + /* This is not recommended because it is slow. */ + ++ii; + do { + DVAL_NEXT(dv,ii); + UPDATE_D(dict,0,dv,ii,in); + } while (++ii < ip); + DVAL_NEXT(dv,ii); + assert(ii == ip); + DVAL_ASSERT(dv,ip); +#elif (CLEVEL >= 8) + SI DI DI DI DI DI DI DI DI XI +#elif (CLEVEL >= 7) + SI DI DI DI DI DI DI DI XI +#elif (CLEVEL >= 6) + SI DI DI DI DI DI DI XI +#elif (CLEVEL >= 5) + SI DI DI DI DI XI +#elif (CLEVEL >= 4) + SI DI DI DI XI +#elif (CLEVEL >= 3) + SI DI DI XI +#elif (CLEVEL >= 2) + SI DI XI +#else + XI +#endif + } + + /* ii now points to the start of next literal run */ + assert(ii == ip); + } + } while (ip < ip_end); + + + +the_end: + assert(ip <= in_end); + + +#if defined(LZO_RETURN_IF_NOT_COMPRESSIBLE) + /* return -1 if op == out to indicate that we + * couldn't compress and didn't copy anything. + */ + if (op == out) + { + *out_len = 0; + return LZO_E_NOT_COMPRESSIBLE; + } +#endif + + + /* store the final literal run */ + if (pd(in_end+DVAL_LEN,ii) > 0) + op = store_run(op,ii,pd(in_end+DVAL_LEN,ii)); + + *out_len = op - out; + return 0; /* compression went ok */ +} + + +/*********************************************************************** +// compress public entry point. +************************************************************************/ + +LZO_PUBLIC(int) +lzo1_compress ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ + int r = LZO_E_OK; + +#if defined(__LZO_QUERY_COMPRESS) + if (__LZO_IS_COMPRESS_QUERY(in,in_len,out,out_len,wrkmem)) + return __LZO_QUERY_COMPRESS(in,in_len,out,out_len,wrkmem,D_SIZE,lzo_sizeof(lzo_dict_t)); +#endif + + /* don't try to compress a block that's too short */ + if (in_len <= 0) + *out_len = 0; + else if (in_len <= MIN_MATCH_LONG + DVAL_LEN + 1) + { +#if defined(LZO_RETURN_IF_NOT_COMPRESSIBLE) + r = LZO_E_NOT_COMPRESSIBLE; +#else + *out_len = store_run(out,in,in_len) - out; +#endif + } + else + r = do_compress(in,in_len,out,out_len,wrkmem); + + return r; +} + + +/* +vi:ts=4:et +*/ diff --git a/DumpProto/lzo/lzo1.h b/DumpProto/lzo/lzo1.h new file mode 100644 index 0000000..cb67949 --- /dev/null +++ b/DumpProto/lzo/lzo1.h @@ -0,0 +1,90 @@ +/* lzo1.h -- public interface of the LZO1 compression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __LZO1_H +#define __LZO1_H + +#ifndef __LZOCONF_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// +************************************************************************/ + +/* Memory required for the wrkmem parameter. + * When the required size is 0, you can also pass a NULL pointer. + */ + +#define LZO1_MEM_COMPRESS ((lzo_uint32) (8192L * lzo_sizeof_dict_t)) +#define LZO1_MEM_DECOMPRESS (0) + + +LZO_EXTERN(int) +lzo1_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +LZO_EXTERN(int) +lzo1_decompress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + + +/*********************************************************************** +// better compression ratio at the cost of more memory and time +************************************************************************/ + +#define LZO1_99_MEM_COMPRESS ((lzo_uint32) (65536L * lzo_sizeof_dict_t)) + +#if !defined(LZO_99_UNSUPPORTED) +LZO_EXTERN(int) +lzo1_99_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); +#endif + + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + diff --git a/DumpProto/lzo/lzo16bit.h b/DumpProto/lzo/lzo16bit.h new file mode 100644 index 0000000..5d6c77e --- /dev/null +++ b/DumpProto/lzo/lzo16bit.h @@ -0,0 +1,99 @@ +/* lzo16bit.h -- configuration for the strict 16-bit memory model + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + + +/* + * NOTE: + * the strict 16-bit memory model is *not* officially supported. + * This file is only included for the sake of completeness. + */ + + +#ifndef __LZOCONF_H +# include +#endif + +#ifndef __LZO16BIT_H +#define __LZO16BIT_H + +#if defined(__LZO_STRICT_16BIT) +#if (UINT_MAX < LZO_0xffffffffL) + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// +************************************************************************/ + +#ifndef LZO_99_UNSUPPORTED +#define LZO_99_UNSUPPORTED +#endif +#ifndef LZO_999_UNSUPPORTED +#define LZO_999_UNSUPPORTED +#endif + +typedef unsigned int lzo_uint; +typedef int lzo_int; +#define LZO_UINT_MAX UINT_MAX +#define LZO_INT_MAX INT_MAX + +#define lzo_sizeof_dict_t sizeof(lzo_uint) + + +/*********************************************************************** +// +************************************************************************/ + +#if defined(__LZO_DOS16) || defined(__LZO_WIN16) + +#if 0 +#define __LZO_MMODEL __far +#else +#define __LZO_MMODEL +#endif + +#endif /* defined(__LZO_DOS16) || defined(__LZO_WIN16) */ + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* (UINT_MAX < LZO_0xffffffffL) */ +#endif /* defined(__LZO_STRICT_16BIT) */ + +#endif /* already included */ + diff --git a/DumpProto/lzo/lzo1_99.c b/DumpProto/lzo/lzo1_99.c new file mode 100644 index 0000000..2d172a4 --- /dev/null +++ b/DumpProto/lzo/lzo1_99.c @@ -0,0 +1,126 @@ +/* lzo1_99.c -- implementation of the LZO1-99 algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + + +#include +#if !defined(LZO_99_UNSUPPORTED) + +#define COMPRESS_ID 99 + +#define DDBITS 3 +#define CLEVEL 9 + + +/*********************************************************************** +// +************************************************************************/ + +#define LZO_NEED_DICT_H +#include "config1.h" + + +/*********************************************************************** +// compression internal entry point. +************************************************************************/ + +static int +_lzo1_do_compress ( const lzo_byte *in, lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem, + lzo_compress_t func ) +{ + int r; + + /* don't try to compress a block that's too short */ + if (in_len <= 0) + { + *out_len = 0; + r = LZO_E_OK; + } + else if (in_len <= MIN_LOOKAHEAD + 1) + { +#if defined(LZO_RETURN_IF_NOT_COMPRESSIBLE) + *out_len = 0; + r = LZO_E_NOT_COMPRESSIBLE; +#else + *out_len = STORE_RUN(out,in,in_len) - out; + r = (*out_len > in_len) ? LZO_E_OK : LZO_E_ERROR; +#endif + } + else + r = func(in,in_len,out,out_len,wrkmem); + + return r; +} + + +/*********************************************************************** +// +************************************************************************/ + +#if !defined(COMPRESS_ID) +#define COMPRESS_ID _LZO_ECONCAT2(DD_BITS,CLEVEL) +#endif + + +#define LZO_CODE_MATCH_INCLUDE_FILE "lzo1_cm.ch" +#include "lzo1b_c.ch" + + +/*********************************************************************** +// +************************************************************************/ + +#define LZO_COMPRESS \ + _LZO_ECONCAT3(lzo1_,COMPRESS_ID,_compress) + +#define LZO_COMPRESS_FUNC \ + _LZO_ECONCAT3(_lzo1_,COMPRESS_ID,_compress_func) + + +/*********************************************************************** +// +************************************************************************/ + +LZO_PUBLIC(int) +LZO_COMPRESS ( const lzo_byte *in, lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ +#if defined(__LZO_QUERY_COMPRESS) + if (__LZO_IS_COMPRESS_QUERY(in,in_len,out,out_len,wrkmem)) + return __LZO_QUERY_COMPRESS(in,in_len,out,out_len,wrkmem,D_SIZE,lzo_sizeof(lzo_dict_t)); +#endif + + return _lzo1_do_compress(in,in_len,out,out_len,wrkmem,do_compress); +} + +#endif + +/* +vi:ts=4:et +*/ diff --git a/DumpProto/lzo/lzo1_cm.ch b/DumpProto/lzo/lzo1_cm.ch new file mode 100644 index 0000000..089782b --- /dev/null +++ b/DumpProto/lzo/lzo1_cm.ch @@ -0,0 +1,39 @@ +/* lzo1_cm.ch -- implementation of the LZO1 compression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the library and is subject + to change. + */ + + +#include "lzo1a_cm.ch" + + +/* +vi:ts=4:et +*/ diff --git a/DumpProto/lzo/lzo1_d.ch b/DumpProto/lzo/lzo1_d.ch new file mode 100644 index 0000000..29067a7 --- /dev/null +++ b/DumpProto/lzo/lzo1_d.ch @@ -0,0 +1,139 @@ +/* lzo1_d.ch -- common decompression stuff + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + + +#if defined(LZO_TEST_DECOMPRESS_OVERRUN) +# if !defined(LZO_TEST_DECOMPRESS_OVERRUN_INPUT) +# define LZO_TEST_DECOMPRESS_OVERRUN_INPUT 2 +# endif +# if !defined(LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT) +# define LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT 2 +# endif +# if !defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND) +# define LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND +# endif +#endif + + +/*********************************************************************** +// Overrun detection is internally handled by these macros: +// +// TEST_IP test input overrun at loop begin +// NEED_IP test input overrun at every input byte +// +// TEST_OP test output overrun at loop begin +// NEED_OP test output overrun at every output byte +// +// TEST_LOOKBEHIND test match postion +// +// The fastest decompressor results when testing for no overruns +// and using LZO_EOF_CODE. +************************************************************************/ + +#undef TEST_IP +#undef TEST_OP +#undef TEST_LOOKBEHIND +#undef NEED_IP +#undef NEED_OP +#undef HAVE_TEST_IP +#undef HAVE_TEST_OP +#undef HAVE_NEED_IP +#undef HAVE_NEED_OP +#undef HAVE_ANY_IP +#undef HAVE_ANY_OP + + +#if defined(LZO_TEST_DECOMPRESS_OVERRUN_INPUT) +# if (LZO_TEST_DECOMPRESS_OVERRUN_INPUT >= 1) +# define TEST_IP (ip < ip_end) +# endif +# if (LZO_TEST_DECOMPRESS_OVERRUN_INPUT >= 2) +# define NEED_IP(x) \ + if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun +# endif +#endif + +#if defined(LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT) +# if (LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT >= 1) +# define TEST_OP (op <= op_end) +# endif +# if (LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT >= 2) +# undef TEST_OP /* don't need both of the tests here */ +# define NEED_OP(x) \ + if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun +# endif +#endif + +#if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND) +# define TEST_LOOKBEHIND(m_pos,out) if (m_pos < out) goto lookbehind_overrun +#else +# define TEST_LOOKBEHIND(m_pos,op) ((void) 0) +#endif + + +#if !defined(LZO_EOF_CODE) && !defined(TEST_IP) + /* if we have no EOF code, we have to test for the end of the input */ +# define TEST_IP (ip < ip_end) +#endif + + +#if defined(TEST_IP) +# define HAVE_TEST_IP +#else +# define TEST_IP 1 +#endif +#if defined(TEST_OP) +# define HAVE_TEST_OP +#else +# define TEST_OP 1 +#endif + +#if defined(NEED_IP) +# define HAVE_NEED_IP +#else +# define NEED_IP(x) ((void) 0) +#endif +#if defined(NEED_OP) +# define HAVE_NEED_OP +#else +# define NEED_OP(x) ((void) 0) +#endif + + +#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP) +# define HAVE_ANY_IP +#endif +#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP) +# define HAVE_ANY_OP +#endif + + + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/lzo1a.c b/DumpProto/lzo/lzo1a.c new file mode 100644 index 0000000..a81c2fd --- /dev/null +++ b/DumpProto/lzo/lzo1a.c @@ -0,0 +1,674 @@ +/* lzo1a.c -- implementation of the LZO1A algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include +#include "lzo_conf.h" + + +/*********************************************************************** +// The next two defines can be changed to customize LZO1A. +// The default version is LZO1A-5/1. +************************************************************************/ + +/* run bits (3 - 5) - the compressor and the decompressor + * must use the same value. */ +#if !defined(RBITS) +# define RBITS 5 +#endif + +/* compression level (1 - 9) - this only affects the compressor. + * 1 is fastest, 9 is best compression ratio + */ +#if !defined(CLEVEL) +# define CLEVEL 1 /* fastest by default */ +#endif + + +/* Collect statistics */ +#if 0 && !defined(LZO_COLLECT_STATS) +# define LZO_COLLECT_STATS +#endif + + +/*********************************************************************** +// You should not have to change anything below this line. +************************************************************************/ + +/* check configuration */ +#if (RBITS < 3 || RBITS > 5) +# error "invalid RBITS" +#endif +#if (CLEVEL < 1 || CLEVEL > 9) +# error "invalid CLEVEL" +#endif + + +/*********************************************************************** +// internal configuration +// all of these affect compression only +************************************************************************/ + +/* return -1 instead of copying if the data cannot be compressed */ +#undef LZO_RETURN_IF_NOT_COMPRESSIBLE + + +/* choose the hashing strategy */ +#ifndef LZO_HASH +#define LZO_HASH LZO_HASH_LZO_INCREMENTAL_A +#endif +#define D_INDEX1(d,p) d = DM((0x21*DX2(p,5,5)) >> 5) +#define D_INDEX2(d,p) d = d ^ D_MASK + +#include "lzo1a_de.h" +#include "stats1a.h" +#include "lzo_util.h" + + +/* check other constants */ +#if (LBITS < 5 || LBITS > 8) +# error "invalid LBITS" +#endif + + +#if defined(LZO_COLLECT_STATS) + static lzo1a_stats_t lzo_statistics; + lzo1a_stats_t *lzo1a_stats = &lzo_statistics; +# define lzo_stats lzo1a_stats +#endif + + +/*********************************************************************** +// get algorithm info, return memory required for compression +************************************************************************/ + +LZO_EXTERN(lzo_uint) lzo1a_info ( int *rbits, int *clevel ); + +LZO_PUBLIC(lzo_uint) +lzo1a_info ( int *rbits, int *clevel ) +{ + if (rbits) + *rbits = RBITS; + if (clevel) + *clevel = CLEVEL; + return D_SIZE * lzo_sizeof(lzo_byte *); +} + + +/*********************************************************************** +// LZO1A decompress a block of data. +// +// Could be easily translated into assembly code. +************************************************************************/ + +LZO_PUBLIC(int) +lzo1a_decompress ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ +#if defined(LZO_OPTIMIZE_GNUC_i386) + register lzo_byte *op __asm__("%edi"); + register const lzo_byte *ip __asm__("%esi"); + register lzo_uint t __asm__("%ecx"); + register const lzo_byte *m_pos __asm__("%ebx"); +#else + register lzo_byte *op; + register const lzo_byte *ip; + register lzo_uint t; + register const lzo_byte *m_pos; +#endif + const lzo_byte * const ip_end = in + in_len; + + LZO_UNUSED(wrkmem); + +#if defined(__LZO_QUERY_DECOMPRESS) + if (__LZO_IS_DECOMPRESS_QUERY(in,in_len,out,out_len,wrkmem)) + return __LZO_QUERY_DECOMPRESS(in,in_len,out,out_len,wrkmem,0,0); +#endif + + op = out; + ip = in; + while (ip < ip_end) + { + t = *ip++; /* get marker */ + LZO_STATS(lzo_stats->marker[t]++); + + if (t == 0) /* a R0 literal run */ + { + t = *ip++; + if (t >= R0FAST - R0MIN) /* a long R0 run */ + { + t -= R0FAST - R0MIN; + if (t == 0) + t = R0FAST; + else + { +#if 0 + t = 256u << ((unsigned) t); +#else + /* help the optimizer */ + lzo_uint tt = 256; + do tt <<= 1; while (--t > 0); + t = tt; +#endif + } + MEMCPY8_DS(op,ip,t); + continue; + } + t += R0MIN; + goto literal; + } + else if (t < R0MIN) /* a short literal run */ + { +literal: + MEMCPY_DS(op,ip,t); + + /* after a literal a match must follow */ + while (ip < ip_end) + { + t = *ip++; /* get R1 marker */ + if (t >= R0MIN) + goto match; + + /* R1 match - a context sensitive 3 byte match + 1 byte literal */ + assert((t & OMASK) == t); + m_pos = op - MIN_OFFSET; + m_pos -= t | (((lzo_uint) *ip++) << OBITS); + assert(m_pos >= out); assert(m_pos < op); + *op++ = *m_pos++; + *op++ = *m_pos++; + *op++ = *m_pos++; + *op++ = *ip++; + } + } + else /* a match */ + { +match: + /* get match offset */ + m_pos = op - MIN_OFFSET; + m_pos -= (t & OMASK) | (((lzo_uint) *ip++) << OBITS); + assert(m_pos >= out); assert(m_pos < op); + + /* get match len */ + if (t < ((MSIZE - 1) << OBITS)) /* a short match */ + { + t >>= OBITS; + *op++ = *m_pos++; + *op++ = *m_pos++; + MEMMOVE_DS(op,m_pos,t); + } + else /* a long match */ + { +#if (LBITS < 8) + t = (MIN_MATCH_LONG - THRESHOLD) + ((lzo_uint)(*ip++) & LMASK); +#else + t = (MIN_MATCH_LONG - THRESHOLD) + (lzo_uint)(*ip++); +#endif + *op++ = *m_pos++; + *op++ = *m_pos++; + MEMMOVE_DS(op,m_pos,t); +#if (LBITS < 8) + /* a very short literal following a long match */ + t = ip[-1] >> LBITS; + if (t) do + *op++ = *ip++; + while (--t); +#endif + } + } + } + + *out_len = op - out; + + /* the next line is the only check in the decompressor */ + return (ip == ip_end ? LZO_E_OK : + (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); +} + + + +/*********************************************************************** +// LZO1A compress a block of data. +// +// I apologize for the spaghetti code, but it really helps the optimizer. +************************************************************************/ + +#include "lzo1a_cr.ch" + +static int +do_compress ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ +#if defined(LZO_OPTIMIZE_GNUC_i386) + register const lzo_byte *ip __asm__("%esi"); +#else + register const lzo_byte *ip; +#endif +#if defined(__LZO_HASH_INCREMENTAL) + lzo_uint32 dv; +#endif + const lzo_byte *m_pos; + lzo_byte *op; + const lzo_byte * const ip_end = in+in_len - DVAL_LEN - MIN_MATCH_LONG; + const lzo_byte * const in_end = in+in_len - DVAL_LEN; + const lzo_byte *ii; + lzo_dict_p const dict = (lzo_dict_p) wrkmem; + const lzo_byte *r1 = ip_end; /* pointer for R1 match (none yet) */ +#if (LBITS < 8) + const lzo_byte *im = ip_end; /* pointer to last match start */ +#endif + +#if !defined(NDEBUG) + const lzo_byte *m_pos_sav; +#endif + + op = out; + ip = in; + ii = ip; /* point to start of current literal run */ + + /* init dictionary */ +#if defined(LZO_DETERMINISTIC) + BZERO8_PTR(wrkmem,sizeof(lzo_dict_t),D_SIZE); +#endif + + DVAL_FIRST(dv,ip); UPDATE_D(dict,0,dv,ip,in); ip++; + DVAL_NEXT(dv,ip); + + do { + lzo_moff_t m_off; + lzo_uint dindex; + + DINDEX1(dindex,ip); + GINDEX(m_pos,m_off,dict,dindex,in); + if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,MAX_OFFSET)) + goto literal; + if (m_pos[0] == ip[0] && m_pos[1] == ip[1] && m_pos[2] == ip[2]) + goto match; + DINDEX2(dindex,ip); + GINDEX(m_pos,m_off,dict,dindex,in); + if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,MAX_OFFSET)) + goto literal; + if (m_pos[0] == ip[0] && m_pos[1] == ip[1] && m_pos[2] == ip[2]) + goto match; + goto literal; + +literal: + UPDATE_I(dict,0,dindex,ip,in); + if (++ip >= ip_end) + break; + continue; + +match: + UPDATE_I(dict,0,dindex,ip,in); +#if !defined(NDEBUG) && defined(LZO_DICT_USE_PTR) + assert(m_pos == NULL || m_pos >= in); + m_pos_sav = m_pos; +#endif + m_pos += 3; + { + /* we have found a match (of at least length 3) */ + +#if !defined(NDEBUG) && !defined(LZO_DICT_USE_PTR) + assert((m_pos_sav = ip - m_off) == (m_pos - 3)); +#endif + + assert(m_pos >= in); + assert(ip < ip_end); + + /* 1) store the current literal run */ + if (pd(ip,ii) > 0) + { + lzo_uint t = pd(ip,ii); + + if (ip - r1 == MIN_MATCH + 1) + { + /* Code a context sensitive R1 match. + * This is tricky and somewhat difficult to explain: + * multiplex a literal run of length 1 into the previous + * short match of length MIN_MATCH. + * The key idea is: + * - after a short run a match MUST follow + * - therefore the value m = 000 in the mmmooooo marker is free + * - use 000ooooo to indicate a MIN_MATCH match (this + * is already coded) plus a 1 byte literal + */ + assert(t == 1); + /* modify marker byte */ + assert((op[-2] >> OBITS) == (MIN_MATCH - THRESHOLD)); + op[-2] &= OMASK; + assert((op[-2] >> OBITS) == 0); + /* copy 1 literal */ + *op++ = *ii; + LZO_STATS(lzo_stats->r1_matches++); + r1 = ip; /* set new R1 pointer */ + } + else if (t < R0MIN) + { + /* inline the copying of a short run */ +#if (LBITS < 8) + if (t < (1 << (8-LBITS)) && ii - im >= MIN_MATCH_LONG) + { + /* Code a very short literal run into the + * previous long match length byte. + */ + LZO_STATS(lzo_stats->lit_runs_after_long_match++); + LZO_STATS(lzo_stats->lit_run_after_long_match[t]++); + assert(ii - im <= MAX_MATCH_LONG); + assert((op[-1] >> LBITS) == 0); + op[-1] |= t << LBITS; + MEMCPY_DS(op, ii, t); + } + else +#endif + { + LZO_STATS(lzo_stats->lit_runs++); + LZO_STATS(lzo_stats->lit_run[t]++); + *op++ = LZO_BYTE(t); + MEMCPY_DS(op, ii, t); + r1 = ip; /* set new R1 pointer */ + } + } + else if (t < R0FAST) + { + /* inline the copying of a short R0 run */ + LZO_STATS(lzo_stats->r0short_runs++); + *op++ = 0; *op++ = LZO_BYTE(t - R0MIN); + MEMCPY_DS(op, ii, t); + r1 = ip; /* set new R1 pointer */ + } + else + op = store_run(op,ii,t); + } +#if (LBITS < 8) + im = ip; +#endif + + + /* 2) compute match len */ + ii = ip; /* point to start of current match */ + + /* we already matched MIN_MATCH bytes, + * m_pos also already advanced MIN_MATCH bytes */ + ip += MIN_MATCH; + assert(m_pos < ip); + + /* try to match another MIN_MATCH_LONG - MIN_MATCH bytes + * to see if we get a long match */ + +#define PS *m_pos++ != *ip++ + +#if (MIN_MATCH_LONG - MIN_MATCH == 2) /* MBITS == 2 */ + if (PS || PS) +#elif (MIN_MATCH_LONG - MIN_MATCH == 6) /* MBITS == 3 */ + if (PS || PS || PS || PS || PS || PS) +#elif (MIN_MATCH_LONG - MIN_MATCH == 14) /* MBITS == 4 */ + if (PS || PS || PS || PS || PS || PS || PS || + PS || PS || PS || PS || PS || PS || PS) +#elif (MIN_MATCH_LONG - MIN_MATCH == 30) /* MBITS == 5 */ + if (PS || PS || PS || PS || PS || PS || PS || PS || + PS || PS || PS || PS || PS || PS || PS || PS || + PS || PS || PS || PS || PS || PS || PS || PS || + PS || PS || PS || PS || PS || PS) +#else +# error "MBITS not yet implemented" +#endif + { + /* we've found a short match */ + lzo_uint m_len; + + /* 2a) compute match parameters */ + assert(ip-m_pos == (int)m_off); + --ip; /* ran one too far, point back to non-match */ + m_len = ip - ii; + assert(m_len >= MIN_MATCH_SHORT); + assert(m_len <= MAX_MATCH_SHORT); + assert(m_off >= MIN_OFFSET); + assert(m_off <= MAX_OFFSET); + assert(ii-m_off == m_pos_sav); + assert(lzo_memcmp(m_pos_sav,ii,m_len) == 0); + m_off -= MIN_OFFSET; + + /* 2b) code a short match */ + /* code short match len + low offset bits */ + *op++ = LZO_BYTE(((m_len - THRESHOLD) << OBITS) | + (m_off & OMASK)); + /* code high offset bits */ + *op++ = LZO_BYTE(m_off >> OBITS); + + +#if defined(LZO_COLLECT_STATS) + lzo_stats->short_matches++; + lzo_stats->short_match[m_len]++; + if (m_off < OSIZE) + lzo_stats->short_match_offset_osize[m_len]++; + if (m_off < 256) + lzo_stats->short_match_offset_256[m_len]++; + if (m_off < 1024) + lzo_stats->short_match_offset_1024[m_len]++; +#endif + + + /* 2c) Insert phrases (beginning with ii+1) into the dictionary. */ + +#define SI /* nothing */ +#define DI ++ii; DVAL_NEXT(dv,ii); UPDATE_D(dict,0,dv,ii,in); +#define XI assert(ii < ip); ii = ip; DVAL_FIRST(dv,(ip)); + +#if (CLEVEL == 9) || (CLEVEL >= 7 && MBITS <= 4) || (CLEVEL >= 5 && MBITS <= 3) + /* Insert the whole match (ii+1)..(ip-1) into dictionary. */ + ++ii; + do { + DVAL_NEXT(dv,ii); + UPDATE_D(dict,0,dv,ii,in); + } while (++ii < ip); + DVAL_NEXT(dv,ii); + assert(ii == ip); + DVAL_ASSERT(dv,ip); +#elif (CLEVEL >= 3) + SI DI DI XI +#elif (CLEVEL >= 2) + SI DI XI +#else + XI +#endif + + } + else + { + /* we've found a long match - see how far we can still go */ + const lzo_byte *end; + lzo_uint m_len; + + assert(ip <= in_end); + assert(ii == ip - MIN_MATCH_LONG); + +#if defined(__LZO_CHECKER) + if (in_end - ip <= (MAX_MATCH_LONG - MIN_MATCH_LONG)) +#else + if (in_end <= ip + (MAX_MATCH_LONG - MIN_MATCH_LONG)) +#endif + end = in_end; + else + { + end = ip + (MAX_MATCH_LONG - MIN_MATCH_LONG); + assert(end < in_end); + } + + while (ip < end && *m_pos == *ip) + m_pos++, ip++; + assert(ip <= in_end); + + /* 2a) compute match parameters */ + m_len = (ip - ii); + assert(m_len >= MIN_MATCH_LONG); + assert(m_len <= MAX_MATCH_LONG); + assert(m_off >= MIN_OFFSET); + assert(m_off <= MAX_OFFSET); + assert(ii-m_off == m_pos_sav); + assert(lzo_memcmp(m_pos_sav,ii,m_len) == 0); + assert(ip-m_pos == (int)m_off); + m_off -= MIN_OFFSET; + + /* 2b) code the long match */ + /* code long match flag + low offset bits */ + *op++ = LZO_BYTE(((MSIZE - 1) << OBITS) | (m_off & OMASK)); + /* code high offset bits */ + *op++ = LZO_BYTE(m_off >> OBITS); + /* code match len */ + *op++ = LZO_BYTE(m_len - MIN_MATCH_LONG); + + +#if defined(LZO_COLLECT_STATS) + lzo_stats->long_matches++; + lzo_stats->long_match[m_len]++; +#endif + + + /* 2c) Insert phrases (beginning with ii+1) into the dictionary. */ +#if (CLEVEL == 9) + /* Insert the whole match (ii+1)..(ip-1) into dictionary. */ + /* This is not recommended because it is slow. */ + ++ii; + do { + DVAL_NEXT(dv,ii); + UPDATE_D(dict,0,dv,ii,in); + } while (++ii < ip); + DVAL_NEXT(dv,ii); + assert(ii == ip); + DVAL_ASSERT(dv,ip); +#elif (CLEVEL >= 8) + SI DI DI DI DI DI DI DI DI XI +#elif (CLEVEL >= 7) + SI DI DI DI DI DI DI DI XI +#elif (CLEVEL >= 6) + SI DI DI DI DI DI DI XI +#elif (CLEVEL >= 5) + SI DI DI DI DI XI +#elif (CLEVEL >= 4) + SI DI DI DI XI +#elif (CLEVEL >= 3) + SI DI DI XI +#elif (CLEVEL >= 2) + SI DI XI +#else + XI +#endif + } + + /* ii now points to the start of the next literal run */ + assert(ii == ip); + } + + } while (ip < ip_end); + + assert(ip <= in_end); + + +#if defined(LZO_RETURN_IF_NOT_COMPRESSIBLE) + /* return -1 if op == out to indicate that we + * couldn't compress and didn't copy anything. + */ + if (op == out) + { + *out_len = 0; + return LZO_E_NOT_COMPRESSIBLE; + } +#endif + + /* store the final literal run */ + if (pd(in_end+DVAL_LEN,ii) > 0) + op = store_run(op,ii,pd(in_end+DVAL_LEN,ii)); + + *out_len = op - out; + return 0; /* compression went ok */ +} + + +/*********************************************************************** +// LZO1A compress public entry point. +************************************************************************/ + +LZO_PUBLIC(int) +lzo1a_compress ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ + int r = LZO_E_OK; + +#if defined(__LZO_QUERY_COMPRESS) + if (__LZO_IS_COMPRESS_QUERY(in,in_len,out,out_len,wrkmem)) + return __LZO_QUERY_COMPRESS(in,in_len,out,out_len,wrkmem,D_SIZE,lzo_sizeof(lzo_dict_t)); +#endif + + +#if defined(LZO_COLLECT_STATS) + memset(lzo_stats,0,sizeof(*lzo_stats)); + lzo_stats->rbits = RBITS; + lzo_stats->clevel = CLEVEL; + lzo_stats->dbits = DBITS; + lzo_stats->lbits = LBITS; + lzo_stats->min_match_short = MIN_MATCH_SHORT; + lzo_stats->max_match_short = MAX_MATCH_SHORT; + lzo_stats->min_match_long = MIN_MATCH_LONG; + lzo_stats->max_match_long = MAX_MATCH_LONG; + lzo_stats->min_offset = MIN_OFFSET; + lzo_stats->max_offset = MAX_OFFSET; + lzo_stats->r0min = R0MIN; + lzo_stats->r0fast = R0FAST; + lzo_stats->r0max = R0MAX; + lzo_stats->in_len = in_len; +#endif + + + /* don't try to compress a block that's too short */ + if (in_len <= 0) + *out_len = 0; + else if (in_len <= MIN_MATCH_LONG + DVAL_LEN + 1) + { +#if defined(LZO_RETURN_IF_NOT_COMPRESSIBLE) + r = LZO_E_NOT_COMPRESSIBLE; +#else + *out_len = store_run(out,in,in_len) - out; +#endif + } + else + r = do_compress(in,in_len,out,out_len,wrkmem); + + +#if defined(LZO_COLLECT_STATS) + lzo_stats->short_matches -= lzo_stats->r1_matches; + lzo_stats->short_match[MIN_MATCH] -= lzo_stats->r1_matches; + lzo_stats->out_len = *out_len; +#endif + + return r; +} + + +/* +vi:ts=4:et +*/ diff --git a/DumpProto/lzo/lzo1a.h b/DumpProto/lzo/lzo1a.h new file mode 100644 index 0000000..1944867 --- /dev/null +++ b/DumpProto/lzo/lzo1a.h @@ -0,0 +1,90 @@ +/* lzo1a.h -- public interface of the LZO1A compression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __LZO1A_H +#define __LZO1A_H + +#ifndef __LZOCONF_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// +************************************************************************/ + +/* Memory required for the wrkmem parameter. + * When the required size is 0, you can also pass a NULL pointer. + */ + +#define LZO1A_MEM_COMPRESS ((lzo_uint32) (8192L * lzo_sizeof_dict_t)) +#define LZO1A_MEM_DECOMPRESS (0) + + +LZO_EXTERN(int) +lzo1a_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +LZO_EXTERN(int) +lzo1a_decompress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + + +/*********************************************************************** +// better compression ratio at the cost of more memory and time +************************************************************************/ + +#define LZO1A_99_MEM_COMPRESS ((lzo_uint32) (65536L * lzo_sizeof_dict_t)) + +#if !defined(LZO_99_UNSUPPORTED) +LZO_EXTERN(int) +lzo1a_99_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); +#endif + + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + diff --git a/DumpProto/lzo/lzo1a_99.c b/DumpProto/lzo/lzo1a_99.c new file mode 100644 index 0000000..1eb3a5e --- /dev/null +++ b/DumpProto/lzo/lzo1a_99.c @@ -0,0 +1,126 @@ +/* lzo1a_99.c -- implementation of the LZO1A-99 algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + + +#include +#if !defined(LZO_99_UNSUPPORTED) + +#define COMPRESS_ID 99 + +#define DDBITS 3 +#define CLEVEL 9 + + +/*********************************************************************** +// +************************************************************************/ + +#define LZO_NEED_DICT_H +#include "config1a.h" + + +/*********************************************************************** +// compression internal entry point. +************************************************************************/ + +static int +_lzo1a_do_compress ( const lzo_byte *in, lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem, + lzo_compress_t func ) +{ + int r; + + /* don't try to compress a block that's too short */ + if (in_len <= 0) + { + *out_len = 0; + r = LZO_E_OK; + } + else if (in_len <= MIN_LOOKAHEAD + 1) + { +#if defined(LZO_RETURN_IF_NOT_COMPRESSIBLE) + *out_len = 0; + r = LZO_E_NOT_COMPRESSIBLE; +#else + *out_len = STORE_RUN(out,in,in_len) - out; + r = (*out_len > in_len) ? LZO_E_OK : LZO_E_ERROR; +#endif + } + else + r = func(in,in_len,out,out_len,wrkmem); + + return r; +} + + +/*********************************************************************** +// +************************************************************************/ + +#if !defined(COMPRESS_ID) +#define COMPRESS_ID _LZO_ECONCAT2(DD_BITS,CLEVEL) +#endif + + +#define LZO_CODE_MATCH_INCLUDE_FILE "lzo1a_cm.ch" +#include "lzo1b_c.ch" + + +/*********************************************************************** +// +************************************************************************/ + +#define LZO_COMPRESS \ + _LZO_ECONCAT3(lzo1a_,COMPRESS_ID,_compress) + +#define LZO_COMPRESS_FUNC \ + _LZO_ECONCAT3(_lzo1a_,COMPRESS_ID,_compress_func) + + +/*********************************************************************** +// +************************************************************************/ + +LZO_PUBLIC(int) +LZO_COMPRESS ( const lzo_byte *in, lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ +#if defined(__LZO_QUERY_COMPRESS) + if (__LZO_IS_COMPRESS_QUERY(in,in_len,out,out_len,wrkmem)) + return __LZO_QUERY_COMPRESS(in,in_len,out,out_len,wrkmem,D_SIZE,lzo_sizeof(lzo_dict_t)); +#endif + + return _lzo1a_do_compress(in,in_len,out,out_len,wrkmem,do_compress); +} + +#endif + +/* +vi:ts=4:et +*/ diff --git a/DumpProto/lzo/lzo1a_cm.ch b/DumpProto/lzo/lzo1a_cm.ch new file mode 100644 index 0000000..68dd241 --- /dev/null +++ b/DumpProto/lzo/lzo1a_cm.ch @@ -0,0 +1,233 @@ +/* lzo1a_cm.ch -- implementation of the LZO1A compression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the library and is subject + to change. + */ + + + +/*********************************************************************** +// code the match in LZO1 compatible format +************************************************************************/ + +#define THRESHOLD (M2_MIN_LEN - 1) +#define MSIZE LZO_SIZE(M2L_BITS) + + +/*********************************************************************** +// +************************************************************************/ + +#if (DD_BITS == 0) + + /* we already matched M2_MIN_LEN bytes, + * m_pos also already advanced M2_MIN_LEN bytes */ + ip += M2_MIN_LEN; + assert(m_pos < ip); + + /* try to match another M2_MAX_LEN + 1 - M2_MIN_LEN bytes + * to see if we get more than a M2 match */ +#define M2_OR_M3 (MATCH_M2) + +#else /* (DD_BITS == 0) */ + + /* we already matched m_len bytes */ + assert(m_len >= M2_MIN_LEN); + ip += m_len; + assert(ip <= in_end); + +#define M2_OR_M3 (m_len <= M2_MAX_LEN) + +#endif /* (DD_BITS == 0) */ + + + if (M2_OR_M3) + { + /* we've found a short match */ + assert(ip <= in_end); + + /* 2a) compute match parameters */ +#if (DD_BITS == 0) + assert((lzo_moff_t)(ip-m_pos) == m_off); + --ip; /* ran one too far, point back to non-match */ + m_len = ip - ii; +#endif + assert(m_len >= M2_MIN_LEN); + assert(m_len <= M2_MAX_LEN); + + assert(m_off >= M2_MIN_OFFSET); + assert(m_off <= M2_MAX_OFFSET); + assert(ii-m_off == m_pos_sav); + assert(lzo_memcmp(m_pos_sav,ii,m_len) == 0); + + /* 2b) code the match */ + m_off -= M2_MIN_OFFSET; + /* code short match len + low offset bits */ + *op++ = LZO_BYTE(((m_len - THRESHOLD) << M2O_BITS) | + (m_off & M2O_MASK)); + /* code high offset bits */ + *op++ = LZO_BYTE(m_off >> M2O_BITS); + + + if (ip >= ip_end) + { + ii = ip; + break; + } + + + /* 2c) Insert phrases (beginning with ii+1) into the dictionary. */ + +#if (CLEVEL == 9) || (CLEVEL >= 7 && M2L_BITS <= 4) || (CLEVEL >= 5 && M2L_BITS <= 3) + /* Insert the whole match (ii+1)..(ip-1) into dictionary. */ + ++ii; + do { + DVAL_NEXT(dv,ii); +#if 0 + UPDATE_D(dict,drun,dv,ii,in); +#else + dict[ DINDEX(dv,ii) ] = DENTRY(ii,in); +#endif + MI + } while (++ii < ip); + DVAL_NEXT(dv,ii); + assert(ii == ip); + DVAL_ASSERT(dv,ip); +#elif (CLEVEL >= 3) + SI DI DI XI +#elif (CLEVEL >= 2) + SI DI XI +#else + XI +#endif + } + + else + + { + /* we've found a long match - see how far we can still go */ + const lzo_byte *end; + + assert(ip <= in_end); + assert(ii == ip - (M2_MAX_LEN + 1)); + assert(lzo_memcmp(m_pos_sav,ii,(lzo_uint)(ip-ii)) == 0); + +#if (DD_BITS > 0) + assert(m_len == (lzo_uint)(ip-ii)); + m_pos = ip - m_off; + assert(m_pos == m_pos_sav + m_len); +#endif + +#if defined(__LZO_CHECKER) + if (in_end - ip <= (lzo_ptrdiff_t) (M3_MAX_LEN - M3_MIN_LEN)) +#else + if (in_end <= ip + (M3_MAX_LEN - M3_MIN_LEN)) +#endif + end = in_end; + else + { + end = ip + (M3_MAX_LEN - M3_MIN_LEN); + assert(end < in_end); + } + + while (ip < end && *m_pos == *ip) + m_pos++, ip++; + assert(ip <= in_end); + + /* 2a) compute match parameters */ + m_len = (ip - ii); + assert(m_len >= M3_MIN_LEN); + assert(m_len <= M3_MAX_LEN); + + assert(m_off >= M3_MIN_OFFSET); + assert(m_off <= M3_MAX_OFFSET); + assert(ii-m_off == m_pos_sav); + assert(lzo_memcmp(m_pos_sav,ii,m_len) == 0); + assert((lzo_moff_t)(ip-m_pos) == m_off); + + /* 2b) code the match */ + m_off -= M3_MIN_OFFSET - M3_EOF_OFFSET; + /* code long match flag + low offset bits */ + *op++ = LZO_BYTE(((MSIZE - 1) << M3O_BITS) | (m_off & M3O_MASK)); + /* code high offset bits */ + *op++ = LZO_BYTE(m_off >> M3O_BITS); + /* code match len */ + *op++ = LZO_BYTE(m_len - M3_MIN_LEN); + + + if (ip >= ip_end) + { + ii = ip; + break; + } + + + /* 2c) Insert phrases (beginning with ii+1) into the dictionary. */ +#if (CLEVEL == 9) + /* Insert the whole match (ii+1)..(ip-1) into dictionary. */ + /* This is not recommended because it can be slow. */ + ++ii; + do { + DVAL_NEXT(dv,ii); +#if 0 + UPDATE_D(dict,drun,dv,ii,in); +#else + dict[ DINDEX(dv,ii) ] = DENTRY(ii,in); +#endif + MI + } while (++ii < ip); + DVAL_NEXT(dv,ii); + assert(ii == ip); + DVAL_ASSERT(dv,ip); +#elif (CLEVEL >= 8) + SI DI DI DI DI DI DI DI DI XI +#elif (CLEVEL >= 7) + SI DI DI DI DI DI DI DI XI +#elif (CLEVEL >= 6) + SI DI DI DI DI DI DI XI +#elif (CLEVEL >= 5) + SI DI DI DI DI XI +#elif (CLEVEL >= 4) + SI DI DI DI XI +#elif (CLEVEL >= 3) + SI DI DI XI +#elif (CLEVEL >= 2) + SI DI XI +#else + XI +#endif + } + + /* ii now points to the start of the next literal run */ + assert(ii == ip); + + +/* +vi:ts=4:et +*/ diff --git a/DumpProto/lzo/lzo1a_cr.ch b/DumpProto/lzo/lzo1a_cr.ch new file mode 100644 index 0000000..ba7273f --- /dev/null +++ b/DumpProto/lzo/lzo1a_cr.ch @@ -0,0 +1,121 @@ +/* lzo1a_cr.ch -- literal run handling for the the LZO1A algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the LZO package and is subject + to change. + */ + + +#ifndef __LZO1A_CR_H +#define __LZO1A_CR_H + + +/*********************************************************************** +// code a literal run +************************************************************************/ + +static lzo_byte * +store_run(lzo_byte * const oo, const lzo_byte * const ii, lzo_uint r_len) +{ +#if defined(LZO_OPTIMIZE_GNUC_i386) + register lzo_byte *op __asm__("%edi"); + register const lzo_byte *ip __asm__("%esi"); + register lzo_uint t __asm__("%ecx"); +#else + register lzo_byte *op; + register const lzo_byte *ip; + register lzo_uint t; +#endif + + op = oo; + ip = ii; + assert(r_len > 0); + + /* code a long R0 run */ + if (r_len >= 512) + { + unsigned r_bits = 6; /* 256 << 6 == 16384 */ + lzo_uint tt = 32768u; + + while (r_len >= (t = tt)) + { + r_len -= t; + *op++ = 0; *op++ = (R0MAX - R0MIN); + MEMCPY8_DS(op, ip, t); + LZO_STATS(lzo_stats->r0long_runs++); + } + tt >>= 1; + do { + if (r_len >= (t = tt)) + { + r_len -= t; + *op++ = 0; *op++ = LZO_BYTE((R0FAST - R0MIN) + r_bits); + MEMCPY8_DS(op, ip, t); + LZO_STATS(lzo_stats->r0long_runs++); + } + tt >>= 1; + } while (--r_bits > 0); + } + assert(r_len < 512); + + while (r_len >= (t = R0FAST)) + { + r_len -= t; + *op++ = 0; *op++ = (R0FAST - R0MIN); + MEMCPY8_DS(op, ip, t); + LZO_STATS(lzo_stats->r0fast_runs++); + } + + t = r_len; + if (t >= R0MIN) + { + /* code a short R0 run */ + *op++ = 0; *op++ = LZO_BYTE(t - R0MIN); + MEMCPY_DS(op, ip, t); + LZO_STATS(lzo_stats->r0short_runs++); + } + else if (t > 0) + { + /* code a short literal run */ + LZO_STATS(lzo_stats->lit_runs++); + LZO_STATS(lzo_stats->lit_run[t]++); + *op++ = LZO_BYTE(t); + MEMCPY_DS(op, ip, t); + } + + return op; +} + + + +#endif /* already included */ + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/lzo1a_de.h b/DumpProto/lzo/lzo1a_de.h new file mode 100644 index 0000000..d403707 --- /dev/null +++ b/DumpProto/lzo/lzo1a_de.h @@ -0,0 +1,145 @@ +/* lzo1a_de.h -- definitions for the the LZO1A algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the LZO package and is subject + to change. + */ + + +#ifndef __LZO_DEFS_H +#define __LZO_DEFS_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// +************************************************************************/ + +/* + Format of the marker byte + + + 76543210 + -------- + 00000000 a long literal run ('R0' run) - there are short and long R0 runs + 000rrrrr a short literal run with len r + mmmooooo a short match (len = 2+m, o = offset low bits) + 111ooooo a long match (o = offset low bits) +*/ + + +#define RSIZE (1 << RBITS) +#define RMASK (RSIZE - 1) + +#define MBITS (8 - OBITS) +#define MSIZE (1 << MBITS) +#define MMASK (MSIZE - 1) + +#define OBITS RBITS /* offset and run-length use same bits */ +#define OSIZE (1 << OBITS) +#define OMASK (OSIZE - 1) + + +/* additional bits for coding the length in a long match */ +#define LBITS 8 +#define LSIZE (1 << LBITS) +#define LMASK (LSIZE - 1) + + +/*********************************************************************** +// some macros to improve readability +************************************************************************/ + +/* Minimum len of a match */ +#define MIN_MATCH 3 +#define THRESHOLD (MIN_MATCH - 1) + +/* Min-/Maximum len of a match coded in 2 bytes */ +#define MIN_MATCH_SHORT (MIN_MATCH) +#define MAX_MATCH_SHORT (MIN_MATCH_SHORT + (MSIZE - 2) - 1) +/* why (MSIZE - 2) ? because 0 is used to mark runs, + * and MSIZE-1 is used to mark a long match */ + +/* Min-/Maximum len of a match coded in 3 bytes */ +#define MIN_MATCH_LONG (MAX_MATCH_SHORT + 1) +#define MAX_MATCH_LONG (MIN_MATCH_LONG + LSIZE - 1) + +/* Min-/Maximum offset of a match */ +#define MIN_OFFSET 1 +#define MAX_OFFSET (1 << (CHAR_BIT + OBITS)) + + +/* R0 literal run (a long run) */ + +#define R0MIN (RSIZE) /* Minimum len of R0 run of literals */ +#define R0MAX (R0MIN + 255) /* Maximum len of R0 run of literals */ +#define R0FAST (R0MAX & ~7) /* R0MAX aligned to 8 byte boundary */ + +#if (R0MAX - R0FAST != 7) || ((R0FAST & 7) != 0) +# error "something went wrong" +#endif + +/* 7 special codes from R0FAST+1 .. R0MAX + * these codes mean long R0 runs with lengths + * 512, 1024, 2048, 4096, 8192, 16384, 32768 */ + + +/* + +RBITS | MBITS MIN THR. MSIZE MAXS MINL MAXL MAXO R0MAX R0FAST +======+=============================================================== + 3 | 5 3 2 32 32 33 288 2048 263 256 + 4 | 4 3 2 16 16 17 272 4096 271 264 + 5 | 3 3 2 8 8 9 264 8192 287 280 + + */ + + +/*********************************************************************** +// +************************************************************************/ + +#define DBITS 13 +#include "lzo_dict.h" +#define DVAL_LEN DVAL_LOOKAHEAD + + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/lzo1b.h b/DumpProto/lzo/lzo1b.h new file mode 100644 index 0000000..ba25aae --- /dev/null +++ b/DumpProto/lzo/lzo1b.h @@ -0,0 +1,156 @@ +/* lzo1b.h -- public interface of the LZO1B compression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __LZO1B_H +#define __LZO1B_H + +#ifndef __LZOCONF_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// +************************************************************************/ + +/* Memory required for the wrkmem parameter. + * When the required size is 0, you can also pass a NULL pointer. + */ + +#define LZO1B_MEM_COMPRESS ((lzo_uint32) (16384L * lzo_sizeof_dict_t)) +#define LZO1B_MEM_DECOMPRESS (0) + + +/* compression levels */ +#define LZO1B_BEST_SPEED 1 +#define LZO1B_BEST_COMPRESSION 9 +#define LZO1B_DEFAULT_COMPRESSION (-1) /* fastest by default */ + + +LZO_EXTERN(int) +lzo1b_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem, + int compression_level ); + +/* decompression */ +LZO_EXTERN(int) +lzo1b_decompress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + +/* safe decompression with overrun testing */ +LZO_EXTERN(int) +lzo1b_decompress_safe ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + + +/*********************************************************************** +// +************************************************************************/ + +LZO_EXTERN(int) +lzo1b_1_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); +LZO_EXTERN(int) +lzo1b_2_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); +LZO_EXTERN(int) +lzo1b_3_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); +LZO_EXTERN(int) +lzo1b_4_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); +LZO_EXTERN(int) +lzo1b_5_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); +LZO_EXTERN(int) +lzo1b_6_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); +LZO_EXTERN(int) +lzo1b_7_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); +LZO_EXTERN(int) +lzo1b_8_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); +LZO_EXTERN(int) +lzo1b_9_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + + +/*********************************************************************** +// better compression ratio at the cost of more memory and time +************************************************************************/ + +#define LZO1B_99_MEM_COMPRESS ((lzo_uint32) (65536L * lzo_sizeof_dict_t)) + +#if !defined(LZO_99_UNSUPPORTED) +LZO_EXTERN(int) +lzo1b_99_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); +#endif + + +#define LZO1B_999_MEM_COMPRESS ((lzo_uint32) (3 * 65536L * sizeof(lzo_uint32))) + +#if !defined(LZO_999_UNSUPPORTED) +LZO_EXTERN(int) +lzo1b_999_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); +#endif + + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + diff --git a/DumpProto/lzo/lzo1b_1.c b/DumpProto/lzo/lzo1b_1.c new file mode 100644 index 0000000..54ce618 --- /dev/null +++ b/DumpProto/lzo/lzo1b_1.c @@ -0,0 +1,6 @@ +#define COMPRESS_ID 1 + +#define DDBITS 0 +#define CLEVEL 1 +#include "compr1b.h" + diff --git a/DumpProto/lzo/lzo1b_2.c b/DumpProto/lzo/lzo1b_2.c new file mode 100644 index 0000000..76b5fda --- /dev/null +++ b/DumpProto/lzo/lzo1b_2.c @@ -0,0 +1,6 @@ +#define COMPRESS_ID 2 + +#define DDBITS 0 +#define CLEVEL 2 +#include "compr1b.h" + diff --git a/DumpProto/lzo/lzo1b_3.c b/DumpProto/lzo/lzo1b_3.c new file mode 100644 index 0000000..fbe1c95 --- /dev/null +++ b/DumpProto/lzo/lzo1b_3.c @@ -0,0 +1,6 @@ +#define COMPRESS_ID 3 + +#define DDBITS 0 +#define CLEVEL 3 +#include "compr1b.h" + diff --git a/DumpProto/lzo/lzo1b_4.c b/DumpProto/lzo/lzo1b_4.c new file mode 100644 index 0000000..aab99ce --- /dev/null +++ b/DumpProto/lzo/lzo1b_4.c @@ -0,0 +1,6 @@ +#define COMPRESS_ID 4 + +#define DDBITS 1 +#define CLEVEL 2 +#include "compr1b.h" + diff --git a/DumpProto/lzo/lzo1b_5.c b/DumpProto/lzo/lzo1b_5.c new file mode 100644 index 0000000..d73ec0c --- /dev/null +++ b/DumpProto/lzo/lzo1b_5.c @@ -0,0 +1,6 @@ +#define COMPRESS_ID 5 + +#define DDBITS 1 +#define CLEVEL 3 +#include "compr1b.h" + diff --git a/DumpProto/lzo/lzo1b_6.c b/DumpProto/lzo/lzo1b_6.c new file mode 100644 index 0000000..b551dbf --- /dev/null +++ b/DumpProto/lzo/lzo1b_6.c @@ -0,0 +1,6 @@ +#define COMPRESS_ID 6 + +#define DDBITS 1 +#define CLEVEL 5 +#include "compr1b.h" + diff --git a/DumpProto/lzo/lzo1b_7.c b/DumpProto/lzo/lzo1b_7.c new file mode 100644 index 0000000..539cfbf --- /dev/null +++ b/DumpProto/lzo/lzo1b_7.c @@ -0,0 +1,6 @@ +#define COMPRESS_ID 7 + +#define DDBITS 2 +#define CLEVEL 3 +#include "compr1b.h" + diff --git a/DumpProto/lzo/lzo1b_8.c b/DumpProto/lzo/lzo1b_8.c new file mode 100644 index 0000000..6b8c93c --- /dev/null +++ b/DumpProto/lzo/lzo1b_8.c @@ -0,0 +1,6 @@ +#define COMPRESS_ID 8 + +#define DDBITS 2 +#define CLEVEL 8 +#include "compr1b.h" + diff --git a/DumpProto/lzo/lzo1b_9.c b/DumpProto/lzo/lzo1b_9.c new file mode 100644 index 0000000..09ce76e --- /dev/null +++ b/DumpProto/lzo/lzo1b_9.c @@ -0,0 +1,6 @@ +#define COMPRESS_ID 9 + +#define DDBITS 2 +#define CLEVEL 9 +#include "compr1b.h" + diff --git a/DumpProto/lzo/lzo1b_99.c b/DumpProto/lzo/lzo1b_99.c new file mode 100644 index 0000000..79ceb84 --- /dev/null +++ b/DumpProto/lzo/lzo1b_99.c @@ -0,0 +1,13 @@ +#include +#if !defined(LZO_99_UNSUPPORTED) + +#define COMPRESS_ID 99 + +#define DDBITS 3 +#define CLEVEL 9 + +#define D_BITS 16 +#define MATCH_IP_END in_end +#include "compr1b.h" + +#endif diff --git a/DumpProto/lzo/lzo1b_9x.c b/DumpProto/lzo/lzo1b_9x.c new file mode 100644 index 0000000..9298b91 --- /dev/null +++ b/DumpProto/lzo/lzo1b_9x.c @@ -0,0 +1,370 @@ +/* lzo1b_9x.c -- implementation of the LZO1B-999 compression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + + +#include +#if !defined(LZO_999_UNSUPPORTED) + +#include +#include "config1b.h" + +#if 0 +#undef NDEBUG +#include +#endif + + +/*********************************************************************** +// +************************************************************************/ + +#define N 0xffffL /* size of ring buffer */ +#define THRESHOLD 2 /* lower limit for match length */ +#define F 2048 /* upper limit for match length */ + + +#define LZO1B +#define LZO_COMPRESS_T lzo1b_999_t +#define lzo_swd_t lzo1b_999_swd_t +#include "lzo_mchw.ch" + + + +/*********************************************************************** +// +************************************************************************/ + +static lzo_byte * +code_match ( LZO_COMPRESS_T *c, lzo_byte *op, lzo_uint m_len, lzo_uint m_off ) +{ + if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET) + { + assert(m_len >= M2_MIN_LEN); + assert(m_off >= M2_MIN_OFFSET); + + m_off -= M2_MIN_OFFSET; + /* code match len + low offset bits */ + *op++ = LZO_BYTE(((m_len - (M2_MIN_LEN - 2)) << M2O_BITS) | + (m_off & M2O_MASK)); + /* code high offset bits */ + *op++ = LZO_BYTE(m_off >> M2O_BITS); + c->m2_m++; + } + else + { + assert(m_len >= M3_MIN_LEN); + assert(m_off <= M3_MAX_OFFSET); + + m_off -= M3_MIN_OFFSET - M3_EOF_OFFSET; + /* code match len */ + if (m_len <= M3_MAX_LEN) + *op++ = LZO_BYTE(M3_MARKER | (m_len - (M3_MIN_LEN - 1))); + else + { + assert(m_len >= M4_MIN_LEN); + /* code M4 match len flag */ + *op++ = M4_MARKER; + /* code match len */ + m_len -= M4_MIN_LEN - 1; + while (m_len > 255) + { + m_len -= 255; + *op++ = 0; + } + assert(m_len > 0); + *op++ = LZO_BYTE(m_len); + } + /* code low offset bits */ + *op++ = LZO_BYTE(m_off & M3O_MASK); + /* code high offset bits */ + *op++ = LZO_BYTE(m_off >> M3O_BITS); + + c->r1_m_len = 0; + c->m3_m++; + } + return op; +} + + +/*********************************************************************** +// this is a public function, but there is no prototype in a header file +************************************************************************/ + +LZO_EXTERN(int) +lzo1b_999_compress_callback ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem, + lzo_progress_callback_t cb, + lzo_uint max_chain ); + +LZO_PUBLIC(int) +lzo1b_999_compress_callback ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem, + lzo_progress_callback_t cb, + lzo_uint max_chain ) +{ + lzo_byte *op; + const lzo_byte *ii; + lzo_uint lit; + lzo_uint m_len, m_off; + LZO_COMPRESS_T cc; + LZO_COMPRESS_T * const c = &cc; + lzo_swd_t * const swd = (lzo_swd_t *) wrkmem; + int r; + +#if defined(__LZO_QUERY_COMPRESS) + if (__LZO_IS_COMPRESS_QUERY(in,in_len,out,out_len,wrkmem)) + return __LZO_QUERY_COMPRESS(in,in_len,out,out_len,wrkmem,1,lzo_sizeof(lzo_swd_t)); +#endif + + /* sanity check */ + if (!lzo_assert(LZO1B_999_MEM_COMPRESS >= lzo_sizeof(lzo_swd_t))) + return LZO_E_ERROR; + + c->init = 0; + c->ip = c->in = in; + c->in_end = in + in_len; + c->cb = cb; + c->r1_r = c->m3_r = c->m2_m = c->m3_m = 0; + + op = out; + ii = c->ip; /* point to start of literal run */ + lit = 0; + c->r1_m_len = 0; + + r = init_match(c,swd,NULL,0,0); + if (r != 0) + return r; + if (max_chain > 0) + swd->max_chain = max_chain; + + r = find_match(c,swd,0,0); + if (r != 0) + return r; + while (c->look > 0) + { + int lazy_match_min_gain = -1; + lzo_uint ahead = 0; + + m_len = c->m_len; + m_off = c->m_off; + +#if 0 + printf("%5ld: %5d len:%3d off:%5d\n", (c->ip-c->look)-in, c->look, + m_len, m_off); +#endif + + assert(c->ip - c->look >= in); + if (lit == 0) + ii = c->ip - c->look; + assert(ii + lit == c->ip - c->look); + assert(swd->b_char == *(c->ip - c->look)); + + if ((m_len < M2_MIN_LEN) || + (m_len < M3_MIN_LEN && m_off > M2_MAX_OFFSET)) + { + m_len = 0; + } + else + { + assert(c->ip - c->look - m_off >= in); + assert(c->ip - c->look - m_off + m_len < c->ip); + assert(lzo_memcmp(c->ip - c->look, c->ip - c->look - m_off, + m_len) == 0); + + if (lit > 0) + { + /* we have a current literal run: do not try a lazy match, + if the literal could be coded into a r1 match */ + if (lit == 1 && c->r1_m_len == M2_MIN_LEN) + lazy_match_min_gain = -1; + else + lazy_match_min_gain = 1; + +#if (M2_MIN_LEN == 2) + if (m_len == 2) + { + /* don't code a match of len 2 if we have to + code a literal run. Code a literal instead. */ + m_len = 0; + } +#endif +#if (M2_MIN_LEN == M3_MIN_LEN) + if (m_len == M2_MIN_LEN && m_off > M2_MAX_OFFSET) + { + /* don't code a M3 match of len 3 if we have to + code a literal run. Code a literal instead. */ + m_len = 0; + } +#endif + } + else + { + /* no current literal run: only try a lazy match, + if the literal could be coded into a r1 match */ + if (c->r1_m_len == M2_MIN_LEN) + lazy_match_min_gain = 0; + else + lazy_match_min_gain = -1; + } + } + + + /* try a lazy match */ + if (m_len == 0) + lazy_match_min_gain = -1; + if (lazy_match_min_gain >= 0 && c->look > m_len) + { + assert(m_len > 0); + + r = find_match(c,swd,1,0); + assert(r == 0); + assert(c->look > 0); + + if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET && + c->m_off > M2_MAX_OFFSET) + lazy_match_min_gain += 1; + + if (c->m_len >= m_len + lazy_match_min_gain) + { + c->lazy++; +#if !defined(NDEBUG) + m_len = c->m_len; + m_off = c->m_off; + assert(lzo_memcmp(c->ip - c->look, c->ip - c->look - m_off, + m_len) == 0); +#endif + lit++; + assert(ii + lit == c->ip - c->look); + continue; + } + else + { + ahead = 1; + assert(ii + lit + 1 == c->ip - c->look); + } + assert(m_len > 0); + } + assert(ii + lit + ahead == c->ip - c->look); + + + if (m_len == 0) + { + /* a literal */ + lit++; + r = find_match(c,swd,1,0); + assert(r == 0); + } + else + { + /* 1 - store run */ + if (lit > 0) + { + /* code current literal run */ + if (lit == 1 && c->r1_m_len == M2_MIN_LEN) + { + /* Code a context sensitive R1 match. */ + assert((op[-2] >> M2O_BITS) == (M2_MARKER >> M2O_BITS)); + op[-2] &= M2O_MASK; + assert((op[-2] >> M2O_BITS) == 0); + /* copy 1 literal */ + *op++ = *ii++; + assert(ii + ahead == c->ip - c->look); + c->r1_r++; + } + else + { + op = STORE_RUN(op,ii,lit); + } + if (lit < R0FAST) + c->r1_m_len = m_len; + else + c->r1_m_len = 0; + lit = 0; + } + else + c->r1_m_len = 0; + + /* 2 - code match */ + op = code_match(c,op,m_len,m_off); + r = find_match(c,swd,m_len,1+ahead); + assert(r == 0); + } + + c->codesize = op - out; + } + + + /* store final run */ + if (lit > 0) + op = STORE_RUN(op,ii,lit); + +#if defined(LZO_EOF_CODE) + *op++ = M3_MARKER | 1; + *op++ = 0; + *op++ = 0; +#endif + + c->codesize = op - out; + assert(c->textsize == in_len); + + *out_len = op - out; + + if (c->cb) + (*c->cb)(c->textsize,c->codesize); + +#if 0 + printf("%ld %ld -> %ld: %ld %ld %ld %ld %ld\n", + (long) c->textsize, (long)in_len, (long) c->codesize, + c->r1_r, c->m3_r, c->m2_m, c->m3_m, c->lazy); +#endif + return LZO_E_OK; +} + + + +/*********************************************************************** +// +************************************************************************/ + +LZO_PUBLIC(int) +lzo1b_999_compress ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ + return lzo1b_999_compress_callback(in,in_len,out,out_len,wrkmem, + (lzo_progress_callback_t) 0, 0); +} + + +#endif /* !defined(LZO_999_UNSUPPORTED) */ + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/lzo1b_c.ch b/DumpProto/lzo/lzo1b_c.ch new file mode 100644 index 0000000..1b97ab2 --- /dev/null +++ b/DumpProto/lzo/lzo1b_c.ch @@ -0,0 +1,263 @@ +/* lzo1b_c.ch -- implementation of the LZO1B compression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + + +/*********************************************************************** +// +************************************************************************/ + +#if !defined(LZO_HAVE_R1) && !defined(LZO_NO_R1) +# define LZO_HAVE_R1 +#endif + +#if !defined(LZO_HAVE_M3) && !defined(LZO_NO_M3) +# if (M3O_BITS < 8) +# define LZO_HAVE_M3 +# endif +#endif + + +#define MI +#define SI MI +#if (DD_BITS > 0) +#define DI ++ii; DVAL_NEXT(dv,ii); UPDATE_D(dict,drun,dv,ii,in); MI +#define XI assert(ii < ip); ii = ip; DVAL_FIRST(dv,(ip)); +#else +#define DI ++ii; DINDEX1(dindex,ii); UPDATE_I(dict,0,dindex,ii,in); MI +#define XI assert(ii < ip); ii = ip; +#endif + + +/*********************************************************************** +// compress a block of data. +// +// I really apologize for this spaghetti code. +************************************************************************/ + +LZO_PRIVATE(int) +do_compress ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ +/* this seems to work with buggy gcc */ +/* #if defined(LZO_OPTIMIZE_GNUC_i386) */ +#if 0 && defined(__GNUC__) && defined(__i386__) + register const lzo_byte *ip __asm__("%esi"); +#else + register const lzo_byte *ip; +#endif +#if (DD_BITS > 0) +#if defined(__LZO_HASH_INCREMENTAL) + lzo_uint32 dv; +#endif + unsigned drun = 0; +#endif + lzo_byte *op; + const lzo_byte * const in_end = in + in_len; + const lzo_byte * const ip_end = in + in_len - MIN_LOOKAHEAD; + const lzo_byte *ii; +#if defined(LZO_HAVE_R1) + const lzo_byte *r1 = ip_end; /* pointer for R1 match (none yet) */ +#endif +#if defined(LZO_HAVE_M3) + lzo_byte *m3 = out + 1; /* pointer after last m3/m4 match */ +#endif + + lzo_dict_p const dict = (lzo_dict_p) wrkmem; + + +#if defined(LZO_COLLECT_STATS) + lzo_stats->r_bits = R_BITS; + lzo_stats->m3o_bits = M3O_BITS; + lzo_stats->dd_bits = DD_BITS; + lzo_stats->clevel = CLEVEL; + lzo_stats->d_bits = D_BITS; + lzo_stats->min_lookahead = MIN_LOOKAHEAD; + lzo_stats->max_lookbehind = MAX_LOOKBEHIND; + lzo_stats->compress_id = _LZO_MEXPAND(COMPRESS_ID); +#endif + + /* init dictionary */ +#if defined(LZO_DETERMINISTIC) + BZERO8_PTR(wrkmem,sizeof(lzo_dict_t),D_SIZE); +#endif + + + op = out; + ip = in; + ii = ip; /* point to start of current literal run */ + + +#if (DD_BITS > 0) + DVAL_FIRST(dv,ip); + UPDATE_D(dict,drun,dv,ip,in); + ip++; + DVAL_NEXT(dv,ip); +#else + ip++; +#endif + + assert(ip < ip_end); + for (;;) + { + const lzo_byte *m_pos; +#if !defined(NDEBUG) + const lzo_byte *m_pos_sav = NULL; +#endif + lzo_moff_t m_off; +#if (DD_BITS == 0) + lzo_uint dindex; +#endif + lzo_uint m_len; + + +/*********************************************************************** +// search for a match +************************************************************************/ + +#if !defined(LZO_SEARCH_MATCH_INCLUDE_FILE) +# define LZO_SEARCH_MATCH_INCLUDE_FILE "lzo1b_sm.ch" +#endif + +#include LZO_SEARCH_MATCH_INCLUDE_FILE + + +#if !defined(LZO_TEST_MATCH_INCLUDE_FILE) +# define LZO_TEST_MATCH_INCLUDE_FILE "lzo1b_tm.ch" +#endif + +#include LZO_TEST_MATCH_INCLUDE_FILE + + + +/*********************************************************************** +// found a literal +************************************************************************/ + + + /* a literal */ +literal: +#if (DD_BITS == 0) + UPDATE_I(dict,0,dindex,ip,in); +#endif + if (++ip >= ip_end) + break; +#if (DD_BITS > 0) + DVAL_NEXT(dv,ip); +#endif + continue; + + + +/*********************************************************************** +// found a match +************************************************************************/ + +match: +#if (DD_BITS == 0) + UPDATE_I(dict,0,dindex,ip,in); +#endif + /* we have found a match of at least M2_MIN_LEN */ + + +#if !defined(LZO_CODE_RUN_INCLUDE_FILE) +# define LZO_CODE_RUN_INCLUDE_FILE "lzo1b_cr.ch" +#endif + +#include LZO_CODE_RUN_INCLUDE_FILE + + + /* ii now points to the start of the current match */ + assert(ii == ip); + + +/*********************************************************************** +// code the match +************************************************************************/ + +#if !defined(LZO_CODE_MATCH_INCLUDE_FILE) +# define LZO_CODE_MATCH_INCLUDE_FILE "lzo1b_cm.ch" +#endif + +#include LZO_CODE_MATCH_INCLUDE_FILE + + + /* ii now points to the start of the next literal run */ + assert(ii == ip); + + } + + +/*********************************************************************** +// end of block +************************************************************************/ + + assert(ip <= in_end); + +#if defined(LZO_COLLECT_STATS) + { + lzo_uint i; + const lzo_byte *p; + + for (i = 0; i < D_SIZE; i++) + { + p = dict[i]; + if (BOUNDS_CHECKING_OFF_IN_EXPR(p == NULL || p < in || p > in_end)) + lzo_stats->unused_dict_entries++; + } + lzo_stats->unused_dict_entries_percent = + 100.0 * lzo_stats->unused_dict_entries / D_SIZE; + } +#endif + + +#if defined(LZO_RETURN_IF_NOT_COMPRESSIBLE) + /* return if op == out to indicate that we + * couldn't compress and didn't copy anything. + */ + if (op == out) + { + *out_len = 0; + return LZO_E_NOT_COMPRESSIBLE; + } +#endif + + /* store the final literal run */ + if (pd(in_end,ii) > 0) + { + lzo_uint t = pd(in_end,ii); + op = STORE_RUN(op,ii,t); + } + + *out_len = op - out; + return LZO_E_OK; /* compression went ok */ +} + + +/* +vi:ts=4:et +*/ diff --git a/DumpProto/lzo/lzo1b_cc.c b/DumpProto/lzo/lzo1b_cc.c new file mode 100644 index 0000000..c59c812 --- /dev/null +++ b/DumpProto/lzo/lzo1b_cc.c @@ -0,0 +1,154 @@ +/* lzo1b_cc.c -- LZO1B compression internal entry point + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#define LZO_NEED_DICT_H +#include "config1b.h" + + +/*********************************************************************** +// compression internal entry point. +************************************************************************/ + +int _lzo1b_do_compress ( const lzo_byte *in, lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem, + lzo_compress_t func ) +{ + int r; +#if defined(LZO_TEST_COMPRESS_OVERRUN) + lzo_uint avail_out = *out_len; +#endif + + +#if defined(LZO_COLLECT_STATS) + _lzo1b_stats_init(lzo_stats); + lzo_stats->in_len = in_len; +#endif + + + /* don't try to compress a block that's too short */ + if (in_len <= 0) + { + *out_len = 0; + r = LZO_E_OK; + } + else if (in_len <= MIN_LOOKAHEAD + 1) + { +#if defined(LZO_RETURN_IF_NOT_COMPRESSIBLE) + *out_len = 0; + r = LZO_E_NOT_COMPRESSIBLE; +#else + *out_len = STORE_RUN(out,in,in_len) - out; + r = (*out_len > in_len) ? LZO_E_OK : LZO_E_ERROR; +#endif + } + else + r = func(in,in_len,out,out_len,wrkmem); + + +#if defined(LZO_EOF_CODE) +#if defined(LZO_TEST_COMPRESS_OVERRUN) + if (r == LZO_E_OK && avail_out - *out_len < 3) + r = LZO_E_COMPRESS_OVERRUN; +#endif + if (r == LZO_E_OK) + { + lzo_byte *op = out + *out_len; + *op++ = M3_MARKER | 1; + *op++ = 0; + *op++ = 0; + *out_len += 3; + } +#endif + + +#if defined(LZO_COLLECT_STATS) + lzo_stats->out_len = *out_len; + lzo_stats->match_bytes = + 1 * lzo_stats->m1_matches + 2 * lzo_stats->m2_matches + + 3 * lzo_stats->m3_matches + 4 * lzo_stats->m4_matches; + _lzo1b_stats_calc(lzo_stats); +#endif + + return r; +} + + +/*********************************************************************** +// note: this is not thread safe, but as it is used for finetuning only +// we don't care +************************************************************************/ + +#undef lzo_stats +/* lzo_stats_t is still defined */ + + +#if defined(LZO_COLLECT_STATS) + +static lzo_stats_t lzo_statistics; +lzo_stats_t * const lzo1b_stats = &lzo_statistics; + + +void _lzo1b_stats_init(lzo_stats_t *lzo_stats) +{ + memset(lzo_stats,0,sizeof(*lzo_stats)); +} + + +void _lzo1b_stats_calc(lzo_stats_t *lzo_stats) +{ + lzo_stats->matches = + lzo_stats->m1_matches + lzo_stats->m2_matches + + lzo_stats->m3_matches + lzo_stats->m4_matches; + + lzo_stats->literal_overhead = lzo_stats->lit_runs + + 2 * (lzo_stats->r0short_runs + lzo_stats->r0fast_runs + + lzo_stats->r0long_runs); + lzo_stats->literal_bytes = lzo_stats->literals + + lzo_stats->literal_overhead; + +#if 0 + assert(lzo_stats->match_bytes + lzo_stats->literal_bytes == + lzo_stats->out_len); +#endif + + lzo_stats->m2_matches -= lzo_stats->r1_matches; + lzo_stats->m2_match[M2_MIN_LEN] -= lzo_stats->r1_matches; + + if (lzo_stats->literals > 0) + lzo_stats->literal_overhead_percent = + 100.0 * lzo_stats->literal_overhead / lzo_stats->literals; +} + + +#endif + + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/lzo1b_cc.h b/DumpProto/lzo/lzo1b_cc.h new file mode 100644 index 0000000..a563b82 --- /dev/null +++ b/DumpProto/lzo/lzo1b_cc.h @@ -0,0 +1,80 @@ +/* lzo1b_cc.h -- definitions for the the LZO1B compression driver + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the library and is subject + to change. + */ + + +#ifndef __LZO1B_CC_H +#define __LZO1B_CC_H + + +/*********************************************************************** +// +************************************************************************/ + +extern const lzo_compress_t _lzo1b_1_compress_func; +extern const lzo_compress_t _lzo1b_2_compress_func; +extern const lzo_compress_t _lzo1b_3_compress_func; +extern const lzo_compress_t _lzo1b_4_compress_func; +extern const lzo_compress_t _lzo1b_5_compress_func; +extern const lzo_compress_t _lzo1b_6_compress_func; +extern const lzo_compress_t _lzo1b_7_compress_func; +extern const lzo_compress_t _lzo1b_8_compress_func; +extern const lzo_compress_t _lzo1b_9_compress_func; + +extern const lzo_compress_t _lzo1b_99_compress_func; + + +/*********************************************************************** +// +************************************************************************/ + +LZO_EXTERN(lzo_byte *) +_lzo1b_store_run ( lzo_byte * const oo, const lzo_byte * const ii, + lzo_uint r_len); + +#define STORE_RUN _lzo1b_store_run + + +lzo_compress_t _lzo1b_get_compress_func(int clevel); + +int _lzo1b_do_compress ( const lzo_byte *in, lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem, + lzo_compress_t func ); + + +#endif /* already included */ + +/* +vi:ts=4:et +*/ + + diff --git a/DumpProto/lzo/lzo1b_cm.ch b/DumpProto/lzo/lzo1b_cm.ch new file mode 100644 index 0000000..48ab6ea --- /dev/null +++ b/DumpProto/lzo/lzo1b_cm.ch @@ -0,0 +1,281 @@ +/* lzo1b_cm.ch -- implementation of the LZO1B compression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the library and is subject + to change. + */ + + + +/*********************************************************************** +// code the match +************************************************************************/ + +#if (DD_BITS == 0) + + /* we already matched M2_MIN_LEN bytes, + * m_pos also already advanced M2_MIN_LEN bytes */ + ip += M2_MIN_LEN; + assert(m_pos < ip); + + /* try to match another M2_MAX_LEN + 1 - M2_MIN_LEN bytes + * to see if we get more than a M2 match */ +#define M2_OR_M3 (MATCH_M2) + +#else /* (DD_BITS == 0) */ + + /* we already matched m_len bytes */ + assert(m_len >= M2_MIN_LEN); + ip += m_len; + assert(ip <= in_end); + +#define M2_OR_M3 (m_len <= M2_MAX_LEN) + +#endif /* (DD_BITS == 0) */ + + + + if (M2_OR_M3) + { + /* we've found a M2 or M3 match */ + assert(ip <= in_end); + + /* 2a) compute match parameters */ +#if (DD_BITS == 0) + assert((lzo_moff_t)(ip-m_pos) == m_off); + --ip; /* ran one too far, point back to non-match */ + m_len = ip - ii; +#endif + + /* 2a2) verify match parameters */ + assert(m_len >= M2_MIN_LEN); + assert(m_len <= M2_MAX_LEN); + assert(m_len <= M3_MAX_LEN); + + assert(m_off >= M2_MIN_OFFSET); + assert(m_off >= M3_MIN_OFFSET); + assert(m_off <= M3_MAX_OFFSET); + assert(ii-m_off == m_pos_sav); + assert(lzo_memcmp(m_pos_sav,ii,m_len) == 0); + + /* 2b) code the match */ +#if (_M2_MAX_OFFSET != _M3_MAX_OFFSET) + if (m_off <= M2_MAX_OFFSET) + { +#else + assert(m_off <= M2_MAX_OFFSET); +#endif + m_off -= M2_MIN_OFFSET; + /* code match len + low offset bits */ + *op++ = LZO_BYTE(((m_len - (M2_MIN_LEN - 2)) << M2O_BITS) | + (m_off & M2O_MASK)); + /* code high offset bits */ + *op++ = LZO_BYTE(m_off >> M2O_BITS); + LZO_STATS(lzo_stats->m2_matches++); + LZO_STATS(lzo_stats->m2_match[m_len]++); +#if (_M2_MAX_OFFSET != _M3_MAX_OFFSET) + } + else + { +#if defined(LZO_HAVE_R1) +#if (M3_MIN_LEN == M2_MIN_LEN) + r1 = ip_end; /* invalidate R1 pointer */ +#endif +#endif + assert(m_len >= M3_MIN_LEN); + m_off -= M3_MIN_OFFSET - M3_EOF_OFFSET; + /* code match len */ + *op++ = LZO_BYTE(M3_MARKER | (m_len - (M3_MIN_LEN - 1))); + /* code low offset bits */ + *op++ = LZO_BYTE(m_off & M3O_MASK); + /* code high offset bits */ + *op++ = LZO_BYTE(m_off >> M3O_BITS); + LZO_STATS(lzo_stats->m3_matches++); + LZO_STATS(lzo_stats->m3_match[m_len]++); +#if defined(LZO_HAVE_M3) + m3 = op; /* set M3 pointer */ +#endif + } +#endif /* (_M2_MAX_OFFSET != _M3_MAX_OFFSET) */ + + + if (ip >= ip_end) + { + ii = ip; + break; + } + + + /* 2c) Insert phrases (beginning with ii+1) into the dictionary. */ + +#if (CLEVEL == 9) || (CLEVEL >= 7 && M2L_BITS <= 4) || (CLEVEL >= 5 && M2L_BITS <= 3) + /* Insert the whole match (ii+1)..(ip-1) into dictionary. */ + ++ii; + do { + DVAL_NEXT(dv,ii); +#if 0 + UPDATE_D(dict,drun,dv,ii,in); +#else + dict[ DINDEX(dv,ii) ] = DENTRY(ii,in); +#endif + MI + } while (++ii < ip); + DVAL_NEXT(dv,ii); + assert(ii == ip); + DVAL_ASSERT(dv,ip); +#elif (CLEVEL >= 3) + SI DI DI XI +#elif (CLEVEL >= 2) + SI DI XI +#else + XI +#endif + } + + else + + { + /* we've found a M3 or M4 match - see how far we can still go */ + assert(ip <= in_end); + assert(lzo_memcmp(m_pos_sav,ii,(lzo_uint)(ip-ii)) == 0); + + /* 2a) compute match parameters */ +#if !defined(MATCH_IP_END) + assert(ii == ip - (M2_MAX_LEN + 1)); +#if (DD_BITS > 0) + assert(m_len == (lzo_uint)(ip-ii)); + m_pos = ip - m_off; + assert(m_pos == m_pos_sav + m_len); +#endif + { + const lzo_byte *end; + end = in_end; + while (ip < end && *m_pos == *ip) + m_pos++, ip++; + assert(ip <= in_end); + m_len = (ip - ii); + } + assert((lzo_moff_t)(ip-m_pos) == m_off); +#endif + + /* 2a2) verify match parameters */ + assert(m_len >= M3_MIN_LEN); + + assert(m_off >= M3_MIN_OFFSET); + assert(m_off >= M4_MIN_OFFSET); + assert(m_off <= M3_MAX_OFFSET); + assert(m_off <= M4_MAX_OFFSET); + assert(ii-m_off == m_pos_sav); + assert(lzo_memcmp(m_pos_sav,ii,m_len) == 0); + + /* 2b) code the match */ + if (m_len <= M3_MAX_LEN) + { + /* code match len */ + *op++ = LZO_BYTE(M3_MARKER | (m_len - (M3_MIN_LEN - 1))); + LZO_STATS(lzo_stats->m3_matches++); + LZO_STATS(lzo_stats->m3_match[m_len]++); + } + else + { + assert(m_len >= M4_MIN_LEN); + /* code M4 match len flag */ + *op++ = M4_MARKER; + /* code match len */ + m_len -= M4_MIN_LEN - 1; + while (m_len > 255) + { + m_len -= 255; + *op++ = 0; + } + assert(m_len > 0); + *op++ = LZO_BYTE(m_len); + LZO_STATS(lzo_stats->m4_matches++); + } + + m_off -= M3_MIN_OFFSET - M3_EOF_OFFSET; + /* code low offset bits */ + *op++ = LZO_BYTE(m_off & M3O_MASK); + /* code high offset bits */ + *op++ = LZO_BYTE(m_off >> M3O_BITS); + +#if defined(LZO_HAVE_M3) + m3 = op; /* set M3 pointer */ +#endif + + + if (ip >= ip_end) + { + ii = ip; + break; + } + + + /* 2c) Insert phrases (beginning with ii+1) into the dictionary. */ +#if (CLEVEL == 9) + /* Insert the whole match (ii+1)..(ip-1) into dictionary. */ + /* This is not recommended because it can be slow. */ + ++ii; + do { + DVAL_NEXT(dv,ii); +#if 0 + UPDATE_D(dict,drun,dv,ii,in); +#else + dict[ DINDEX(dv,ii) ] = DENTRY(ii,in); +#endif + MI + } while (++ii < ip); + DVAL_NEXT(dv,ii); + assert(ii == ip); + DVAL_ASSERT(dv,ip); +#elif (CLEVEL >= 8) + SI DI DI DI DI DI DI DI DI XI +#elif (CLEVEL >= 7) + SI DI DI DI DI DI DI DI XI +#elif (CLEVEL >= 6) + SI DI DI DI DI DI DI XI +#elif (CLEVEL >= 5) + SI DI DI DI DI XI +#elif (CLEVEL >= 4) + SI DI DI DI XI +#elif (CLEVEL >= 3) + SI DI DI XI +#elif (CLEVEL >= 2) + SI DI XI +#else + XI +#endif + } + + /* ii now points to the start of the next literal run */ + assert(ii == ip); + + +/* +vi:ts=4:et +*/ diff --git a/DumpProto/lzo/lzo1b_cr.ch b/DumpProto/lzo/lzo1b_cr.ch new file mode 100644 index 0000000..550c22b --- /dev/null +++ b/DumpProto/lzo/lzo1b_cr.ch @@ -0,0 +1,113 @@ +/* lzo1b_cr.ch -- implementation of the LZO1B compression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the library and is subject + to change. + */ + + + +/*********************************************************************** +// store the current literal run +************************************************************************/ + + assert(ip < ip_end); + if (pd(ip,ii) > 0) + { + lzo_uint t = pd(ip,ii); + +#if defined(LZO_HAVE_R1) + if (ip == r1) + { + /* Code a context sensitive R1 match. */ + LZO_STATS(lzo_stats->literals += t); + LZO_STATS(lzo_stats->r1_matches++); + assert(t == 1); + /* modify marker byte */ + assert((op[-2] >> M2O_BITS) == (M2_MARKER >> M2O_BITS)); + op[-2] &= M2O_MASK; + assert((op[-2] >> M2O_BITS) == 0); + /* copy 1 literal */ + *op++ = *ii++; + r1 = ip + (M2_MIN_LEN + 1); /* set new R1 pointer */ + } + else +#endif + if (t < R0MIN) + { + /* inline the copying of a short run */ + LZO_STATS(lzo_stats->literals += t); + LZO_STATS(lzo_stats->lit_runs++); + LZO_STATS(lzo_stats->lit_run[t]++); +#if defined(LZO_HAVE_M3) + if (t < LZO_SIZE(8-M3O_BITS) && op == m3) + { + /* Code a very short literal run into the low offset bits + * of the previous M3/M4 match. + */ + LZO_STATS(lzo_stats->lit_runs_after_m3_match++); + LZO_STATS(lzo_stats->lit_run_after_m3_match[t]++); + assert((m3[-2] >> M3O_BITS) == 0); + m3[-2] |= LZO_BYTE(t << M3O_BITS); + } + else +#endif + { + *op++ = LZO_BYTE(t); + } + MEMCPY_DS(op, ii, t); +#if defined(LZO_HAVE_R1) + r1 = ip + (M2_MIN_LEN + 1); /* set new R1 pointer */ +#endif + } + else if (t < R0FAST) + { + /* inline the copying of a short R0 run */ + LZO_STATS(lzo_stats->literals += t); + LZO_STATS(lzo_stats->r0short_runs++); + *op++ = 0; *op++ = LZO_BYTE(t - R0MIN); + MEMCPY_DS(op, ii, t); +#if defined(LZO_HAVE_R1) + r1 = ip + (M2_MIN_LEN + 1); /* set new R1 pointer */ +#endif + } + else + { + op = STORE_RUN(op,ii,t); + ii = ip; + } + } + + + /* ii now points to the start of the current match */ + assert(ii == ip); + + +/* +vi:ts=4:et +*/ diff --git a/DumpProto/lzo/lzo1b_d.ch b/DumpProto/lzo/lzo1b_d.ch new file mode 100644 index 0000000..e142ffc --- /dev/null +++ b/DumpProto/lzo/lzo1b_d.ch @@ -0,0 +1,287 @@ +/* lzo1b_d.ch -- implementation of the LZO1B decompression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "lzo1_d.ch" + + +#if defined(HAVE_ANY_IP) && defined(HAVE_ANY_OP) + /* too many local variables, cannot allocate registers */ +# undef LZO_OPTIMIZE_GNUC_i386 +#endif + + +/*********************************************************************** +// decompress a block of data. +************************************************************************/ + +LZO_PUBLIC(int) +DO_DECOMPRESS ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ +#if defined(LZO_OPTIMIZE_GNUC_i386) + register lzo_byte *op __asm__("%edi"); + register const lzo_byte *ip __asm__("%esi"); + register lzo_uint t __asm__("%ecx"); + register const lzo_byte *m_pos __asm__("%ebx"); +#else + register lzo_byte *op; + register const lzo_byte *ip; + register lzo_uint t; + register const lzo_byte *m_pos; +#endif + + const lzo_byte * const ip_end = in + in_len; +#if defined(HAVE_ANY_OP) + lzo_byte * const op_end = out + *out_len; +#endif + + LZO_UNUSED(wrkmem); + +#if defined(__LZO_QUERY_DECOMPRESS) + if (__LZO_IS_DECOMPRESS_QUERY(in,in_len,out,out_len,wrkmem)) + return __LZO_QUERY_DECOMPRESS(in,in_len,out,out_len,wrkmem,0,0); +#endif + + op = out; + ip = in; + + while (TEST_IP && TEST_OP) + { + t = *ip++; /* get marker */ + + if (t < R0MIN) /* a literal run */ + { + if (t == 0) /* a R0 literal run */ + { + NEED_IP(1); + t = *ip++; + if (t >= R0FAST - R0MIN) /* a long R0 run */ + { + t -= R0FAST - R0MIN; + if (t == 0) + t = R0FAST; + else + { +#if 0 + t = 256u << ((unsigned) t); +#else + /* help the optimizer */ + lzo_uint tt = 256; + do tt <<= 1; while (--t > 0); + t = tt; +#endif + } + + NEED_IP(t); NEED_OP(t); +#if 1 && defined(LZO_UNALIGNED_OK_4) + do { + * (lzo_uint32p) (op+0) = * (const lzo_uint32p) (ip+0); + * (lzo_uint32p) (op+4) = * (const lzo_uint32p) (ip+4); + op += 8; ip += 8; + t -= 8; + } while (t > 0); +#else + MEMCPY8_DS(op,ip,t); +#endif + continue; + } + t += R0MIN; /* a short R0 run */ + } + + NEED_IP(t); NEED_OP(t); + /* copy literal run */ +#if 1 && defined(LZO_UNALIGNED_OK_4) + if (t >= 4) + { + do { + * (lzo_uint32p) op = * (const lzo_uint32p) ip; + op += 4; ip += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *ip++; while (--t > 0); + } + else +#endif + { +#if (M3O_BITS < 7) +literal1: +#endif + do *op++ = *ip++; while (--t > 0); + } + +#if (M3O_BITS == 7) +literal2: +#endif + + /* after a literal a match must follow */ + while (TEST_IP && TEST_OP) + { + t = *ip++; /* get R1 marker */ + if (t >= R0MIN) + goto match; + + NEED_IP(2); NEED_OP(M2_MIN_LEN + 1); + + /* R1 match - a M2_MIN_LEN match + 1 byte literal */ + assert((t & M2O_MASK) == t); + m_pos = op - M2_MIN_OFFSET; + m_pos -= t | (((lzo_uint) *ip++) << M2O_BITS); + assert(m_pos >= out); assert(m_pos < op); + TEST_LOOKBEHIND(m_pos,out); + COPY_M2; + *op++ = *ip++; + } + +#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP) + break; +#endif + } + +match: + + if (t >= M2_MARKER) /* a M2 match */ + { + /* get match offset */ + NEED_IP(1); + m_pos = op - M2_MIN_OFFSET; + m_pos -= (t & M2O_MASK) | (((lzo_uint) *ip++) << M2O_BITS); + assert(m_pos >= out); assert(m_pos < op); + TEST_LOOKBEHIND(m_pos,out); + + /* get match len */ + t = (t >> M2O_BITS) - 1; + NEED_OP(t + M2_MIN_LEN - 1); + COPY_M2X; + MEMMOVE_DS(op,m_pos,t); + } + else /* a M3 or M4 match */ + { + /* get match len */ + t &= M3L_MASK; + if (t == 0) /* a M4 match */ + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += (M4_MIN_LEN - M3_MIN_LEN) + *ip++; + } + + /* get match offset */ + NEED_IP(2); + m_pos = op - (M3_MIN_OFFSET - M3_EOF_OFFSET); + m_pos -= *ip++ & M3O_MASK; + m_pos -= (lzo_uint)(*ip++) << M3O_BITS; +#if defined(LZO_EOF_CODE) + if (m_pos == op) + goto eof_found; +#endif + + /* copy match */ + assert(m_pos >= out); assert(m_pos < op); + TEST_LOOKBEHIND(m_pos,out); NEED_OP(t + M3_MIN_LEN - 1); +#if defined(LZO_UNALIGNED_OK_4) + if (t >= 2 * 4 - (M3_MIN_LEN - 1) && (op - m_pos) >= 4) + { + * (lzo_uint32p) op = * (const lzo_uint32p) m_pos; + op += 4; m_pos += 4; t -= 4 - (M3_MIN_LEN - 1); + do { + * (lzo_uint32p) op = * (const lzo_uint32p) m_pos; + op += 4; m_pos += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *m_pos++; while (--t > 0); + } + else +#endif + { + COPY_M3X; + MEMMOVE_DS(op,m_pos,t); + } + + +#if (M3O_BITS < 7) + t = ip[-2] >> M3O_BITS; + if (t) + { + NEED_IP(t); NEED_OP(t); + goto literal1; + } +#elif (M3O_BITS == 7) + /* optimized version */ + if (ip[-2] & (1 << M3O_BITS)) + { + NEED_IP(1); NEED_OP(1); + *op++ = *ip++; + goto literal2; + } +#endif + } + } + + +#if defined(LZO_EOF_CODE) +#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP) + /* no EOF code was found */ + *out_len = op - out; + return LZO_E_EOF_NOT_FOUND; +#endif + +eof_found: + assert(t == 1); +#endif + *out_len = op - out; + return (ip == ip_end ? LZO_E_OK : + (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); + + +#if defined(HAVE_NEED_IP) +input_overrun: + *out_len = op - out; + return LZO_E_INPUT_OVERRUN; +#endif + +#if defined(HAVE_NEED_OP) +output_overrun: + *out_len = op - out; + return LZO_E_OUTPUT_OVERRUN; +#endif + +#if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND) +lookbehind_overrun: + *out_len = op - out; + return LZO_E_LOOKBEHIND_OVERRUN; +#endif +} + + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/lzo1b_d1.c b/DumpProto/lzo/lzo1b_d1.c new file mode 100644 index 0000000..ab40b10 --- /dev/null +++ b/DumpProto/lzo/lzo1b_d1.c @@ -0,0 +1,33 @@ +/* lzo1b_d1.c -- LZO1B decompression + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "config1b.h" + +#undef LZO_TEST_DECOMPRESS_OVERRUN +#define DO_DECOMPRESS lzo1b_decompress + +#include "lzo1b_d.ch" diff --git a/DumpProto/lzo/lzo1b_d2.c b/DumpProto/lzo/lzo1b_d2.c new file mode 100644 index 0000000..1be80ed --- /dev/null +++ b/DumpProto/lzo/lzo1b_d2.c @@ -0,0 +1,33 @@ +/* lzo1b_d2.c -- LZO1B decompression with overrun testing + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "config1b.h" + +#define LZO_TEST_DECOMPRESS_OVERRUN +#define DO_DECOMPRESS lzo1b_decompress_safe + +#include "lzo1b_d.ch" diff --git a/DumpProto/lzo/lzo1b_de.h b/DumpProto/lzo/lzo1b_de.h new file mode 100644 index 0000000..aa334d0 --- /dev/null +++ b/DumpProto/lzo/lzo1b_de.h @@ -0,0 +1,331 @@ +/* lzo1b_de.h -- definitions for the the LZO1B/LZO1C algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the library and is subject + to change. + */ + + +#ifndef __LZO_DEFS_H +#define __LZO_DEFS_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// +************************************************************************/ + +/* + Format of the marker byte + + 76543210 + -------- + 00000000 R0 - a long literal run ('R0' run) + 000rrrrr R - a short literal run with len r + 00100000 M4 - a very long match + 001mmmmm M3 - a long match (len = m+M3_MIN_LEN) + mmmooooo M2 - a short match (len = m+M2_MIN_LEN, o = offset low bits) + + M1 is not used ! +*/ + + +#ifndef R_BITS +#define R_BITS (5) +#endif + + +#ifndef M1L_BITS +#define M1L_BITS (0) +#endif +#ifndef M2L_BITS +#define M2L_BITS (CHAR_BIT - M2O_BITS) +#endif +#ifndef M3L_BITS +#define M3L_BITS (R_BITS) +#endif +#ifndef M4L_BITS +#define M4L_BITS (CHAR_BIT) +#endif + +#ifndef M1O_BITS +#define M1O_BITS (6) +#endif +#ifndef M2O_BITS +#define M2O_BITS (R_BITS) +#endif +#ifndef M3O_BITS +#define M3O_BITS (CHAR_BIT) +#endif +#ifndef M4O_BITS +#define M4O_BITS (M3O_BITS) /* must be the same */ +#endif + +#ifndef M1X_BITS +#define M1X_BITS (M1O_BITS) +#endif +#ifndef M2X_BITS +#define M2X_BITS (M2O_BITS + CHAR_BIT) +#endif +#ifndef M3X_BITS +#define M3X_BITS (M3O_BITS + CHAR_BIT) +#endif +#ifndef M4X_BITS +#define M4X_BITS M3X_BITS +#endif + + +#define __MIN_OFFSET(bits) 1 +#define __MAX_OFFSET(bits) (LZO_LSIZE(bits) - __MIN_OFFSET(bits) + 1) + +#define M1_MIN_OFFSET __MIN_OFFSET(M1X_BITS) +#define M2_MIN_OFFSET __MIN_OFFSET(M2X_BITS) +#define M3_MIN_OFFSET __MIN_OFFSET(M3X_BITS) +#define M4_MIN_OFFSET M3_MIN_OFFSET + +#if defined(LZO_EOF_CODE) && !defined(M3_EOF_OFFSET) +#define M3_EOF_OFFSET 1 +#else +#define M3_EOF_OFFSET 0 +#endif + +#ifndef _M1_MAX_OFFSET +#define _M1_MAX_OFFSET __MAX_OFFSET(M1X_BITS) +#endif +#ifndef _M2_MAX_OFFSET +#define _M2_MAX_OFFSET __MAX_OFFSET(M2X_BITS) +#endif +#ifndef _M3_MAX_OFFSET +#define _M3_MAX_OFFSET (__MAX_OFFSET(M3X_BITS) - M3_EOF_OFFSET) +#endif +#ifndef _M4_MAX_OFFSET +#define _M4_MAX_OFFSET _M3_MAX_OFFSET +#endif +#ifndef _MAX_OFFSET +#define _MAX_OFFSET _M4_MAX_OFFSET +#endif + +#if (M3_EOF_OFFSET > 0) && (_M2_MAX_OFFSET == _M3_MAX_OFFSET + M3_EOF_OFFSET) +# undef _M2_MAX_OFFSET +# define _M2_MAX_OFFSET _M3_MAX_OFFSET +#endif +#if (_M2_MAX_OFFSET > _M3_MAX_OFFSET) +# error +#endif + +#define M1_MAX_OFFSET ((lzo_ptrdiff_t) _M1_MAX_OFFSET) +#define M2_MAX_OFFSET ((lzo_ptrdiff_t) _M2_MAX_OFFSET) +#define M3_MAX_OFFSET ((lzo_ptrdiff_t) _M3_MAX_OFFSET) +#define M4_MAX_OFFSET ((lzo_ptrdiff_t) _M4_MAX_OFFSET) +#define MAX_OFFSET ((lzo_ptrdiff_t) _MAX_OFFSET) + + +#ifndef M1_MIN_LEN +#define M1_MIN_LEN (2) +#endif +#ifndef M2_MIN_LEN +#define M2_MIN_LEN (3) +#endif +#ifndef M3_MIN_LEN +#if (M3X_BITS == M2X_BITS) +#define M3_MIN_LEN (M2_MAX_LEN + 1) +#else +#define M3_MIN_LEN (4) +#endif +#endif +#ifndef M4_MIN_LEN +#define M4_MIN_LEN (M3_MAX_LEN + 1) +#endif + +#ifndef M1_MAX_LEN +#define M1_MAX_LEN (M1_MIN_LEN + LZO_SIZE(M1L_BITS) - 1) +#endif +#ifndef M2_MAX_LEN +#define M2_MAX_LEN (M2_MIN_LEN + LZO_SIZE(M2L_BITS) - 1 - 2) +#endif +#ifndef M3_MAX_LEN +#define M3_MAX_LEN (M3_MIN_LEN + LZO_SIZE(M3L_BITS) - 1 - 1) +#endif +#ifndef M4_MAX_LEN +#define M4_MAX_LEN (ULONG_MAX) +#endif + + +#define M1O_MASK LZO_MASK(M1O_BITS) +#define M1L_MASK LZO_MASK(M1L_BITS) +#define M2O_MASK LZO_MASK(M2O_BITS) +#define M2L_MASK LZO_MASK(M2L_BITS) +#define M3O_MASK LZO_MASK(M3O_BITS) +#define M3L_MASK LZO_MASK(M3L_BITS) +#define M4O_MASK LZO_MASK(M4O_BITS) +#define M4L_MASK LZO_MASK(M4L_BITS) + + +#define M1_MARKER (1 << M1O_BITS) +#define M2_MARKER (2 << M2O_BITS) +#define M3_MARKER (1 << M3L_BITS) +#define M4_MARKER M3_MARKER + + +/*********************************************************************** +// R0 literal run (a long run) +************************************************************************/ + +#ifndef R0MIN +#define R0MIN (LZO_SIZE(R_BITS)) /* Minimum len of R0 run of literals */ +#endif +#define R0MAX (R0MIN + 256 - 1) /* Maximum len of R0 run of literals */ + +#if (R0MAX - (R0MAX & ~7u) >= 7) +#define R0FAST (R0MAX & ~7u) /* R0MAX aligned to 8 byte boundary */ +#else +#define R0FAST (R0MAX & ~15u) /* R0MAX aligned to 8 byte boundary */ +#endif + +#if (R0MAX - R0FAST < 7) || ((R0FAST & 7) != 0) +# error "something went wrong" +#endif +#if (R0FAST * 2 < 512) +# error "R0FAST is not big enough" +#endif + +/* 7 special codes from R0FAST+1 .. R0MAX + * these codes mean long R0 runs with lengths + * 512, 1024, 2048, 4096, 8192, 16384, 32768 + */ + + + +/*********************************************************************** +// matching +************************************************************************/ + +#define PS *m_pos++ != *ip++ + + +/* We already matched M2_MIN_LEN bytes. + * Try to match another M2_MAX_LEN - M2_MIN_LEN bytes. */ + +#if (M2_MAX_LEN - M2_MIN_LEN == 4) +# define MATCH_M2X (PS || PS || PS || PS) +#elif (M2_MAX_LEN - M2_MIN_LEN == 5) +# define MATCH_M2X (PS || PS || PS || PS || PS) +#elif (M2_MAX_LEN - M2_MIN_LEN == 6) +# define MATCH_M2X (PS || PS || PS || PS || PS || PS) +#elif (M2_MAX_LEN - M2_MIN_LEN == 7) +# define MATCH_M2X (PS || PS || PS || PS || PS || PS || PS) +#elif (M2_MAX_LEN - M2_MIN_LEN == 13) +# define MATCH_M2X (PS || PS || PS || PS || PS || PS || PS || PS || \ + PS || PS || PS || PS || PS) +#elif (M2_MAX_LEN - M2_MIN_LEN == 14) +# define MATCH_M2X (PS || PS || PS || PS || PS || PS || PS || PS || \ + PS || PS || PS || PS || PS || PS) +#elif (M2_MAX_LEN - M2_MIN_LEN == 16) +# define MATCH_M2X (PS || PS || PS || PS || PS || PS || PS || PS || \ + PS || PS || PS || PS || PS || PS || PS || PS) +#elif (M2_MAX_LEN - M2_MIN_LEN == 29) +# define MATCH_M2X (PS || PS || PS || PS || PS || PS || PS || PS || \ + PS || PS || PS || PS || PS || PS || PS || PS || \ + PS || PS || PS || PS || PS || PS || PS || PS || \ + PS || PS || PS || PS || PS) +#else +# error "MATCH_M2X not yet implemented" +#endif + + +/* We already matched M2_MIN_LEN bytes. + * Try to match another M2_MAX_LEN + 1 - M2_MIN_LEN bytes + * to see if we get more than a M2 match */ + +#define MATCH_M2 (MATCH_M2X || PS) + + +/*********************************************************************** +// copying +************************************************************************/ + +#define _CP *op++ = *m_pos++ + +#if (M2_MIN_LEN == 2) +# define COPY_M2X _CP +#elif (M2_MIN_LEN == 3) +# define COPY_M2X _CP; _CP +#elif (M2_MIN_LEN == 4) +# define COPY_M2X _CP; _CP; _CP +#else +# error "COPY_M2X not yet implemented" +#endif + +#if (M3_MIN_LEN == 3) +# define COPY_M3X _CP; _CP +#elif (M3_MIN_LEN == 4) +# define COPY_M3X _CP; _CP; _CP +#elif (M3_MIN_LEN == 9) +# define COPY_M3X _CP; _CP; _CP; _CP; _CP; _CP; _CP; _CP +#else +# error "COPY_M3X not yet implemented" +#endif + +#define COPY_M2 COPY_M2X; *op++ = *m_pos++ +#define COPY_M3 COPY_M3X; *op++ = *m_pos++ + + +/*********************************************************************** +// +************************************************************************/ + +#if defined(LZO_NEED_DICT_H) + +#define DL_MIN_LEN M2_MIN_LEN +#define D_INDEX1(d,p) d = DM((0x21*DX3(p,5,5,6)) >> 5) +#define D_INDEX2(d,p) d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f) +#include "lzo_dict.h" + +#ifndef MIN_LOOKAHEAD +#define MIN_LOOKAHEAD (M2_MAX_LEN + 1) +#endif +#ifndef MAX_LOOKBEHIND +#define MAX_LOOKBEHIND (MAX_OFFSET) +#endif + +#endif /* defined(LZO_NEED_DICT_H) */ + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/lzo1b_r.ch b/DumpProto/lzo/lzo1b_r.ch new file mode 100644 index 0000000..4a4c5d3 --- /dev/null +++ b/DumpProto/lzo/lzo1b_r.ch @@ -0,0 +1,110 @@ +/* lzo1b_r.ch -- literal run handling for the the LZO1B/LZO1C algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/*********************************************************************** +// store a literal run (internal) +************************************************************************/ + +LZO_PUBLIC(lzo_byte *) +STORE_RUN ( lzo_byte * const oo, const lzo_byte * const ii, lzo_uint r_len) +{ +#if defined(LZO_OPTIMIZE_GNUC_i386) + register lzo_byte *op __asm__("%edi"); + register const lzo_byte *ip __asm__("%esi"); + register lzo_uint t __asm__("%ecx"); +#else + register lzo_byte *op; + register const lzo_byte *ip; + register lzo_uint t; +#endif + + LZO_STATS(lzo_stats->literals += r_len); + + op = oo; + ip = ii; + assert(r_len > 0); + + /* code a long R0 run */ + if (r_len >= 512) + { + unsigned r_bits = 6; /* 256 << 6 == 16384 */ + lzo_uint tt = 32768u; + + while (r_len >= (t = tt)) + { + r_len -= t; + *op++ = 0; *op++ = (R0FAST - R0MIN) + 7; + MEMCPY8_DS(op, ip, t); + LZO_STATS(lzo_stats->r0long_runs++); + } + tt >>= 1; + do { + if (r_len >= (t = tt)) + { + r_len -= t; + *op++ = 0; *op++ = LZO_BYTE((R0FAST - R0MIN) + r_bits); + MEMCPY8_DS(op, ip, t); + LZO_STATS(lzo_stats->r0long_runs++); + } + tt >>= 1; + } while (--r_bits > 0); + } + assert(r_len < 512); + + while (r_len >= (t = R0FAST)) + { + r_len -= t; + *op++ = 0; *op++ = (R0FAST - R0MIN); + MEMCPY8_DS(op, ip, t); + LZO_STATS(lzo_stats->r0fast_runs++); + } + + t = r_len; + if (t >= R0MIN) + { + /* code a short R0 run */ + *op++ = 0; *op++ = LZO_BYTE(t - R0MIN); + MEMCPY_DS(op, ip, t); + LZO_STATS(lzo_stats->r0short_runs++); + } + else if (t > 0) + { + /* code a short literal run */ + LZO_STATS(lzo_stats->lit_runs++); + LZO_STATS(lzo_stats->lit_run[t]++); + *op++ = LZO_BYTE(t); + MEMCPY_DS(op, ip, t); + } + + return op; +} + + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/lzo1b_rr.c b/DumpProto/lzo/lzo1b_rr.c new file mode 100644 index 0000000..9fbad1e --- /dev/null +++ b/DumpProto/lzo/lzo1b_rr.c @@ -0,0 +1,30 @@ +/* lzo1b_rr.c -- literal run handling + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "config1b.h" + +#include "lzo1b_r.ch" diff --git a/DumpProto/lzo/lzo1b_sm.ch b/DumpProto/lzo/lzo1b_sm.ch new file mode 100644 index 0000000..6a8152c --- /dev/null +++ b/DumpProto/lzo/lzo1b_sm.ch @@ -0,0 +1,197 @@ +/* lzo1b_sm.ch -- implementation of the LZO1B compression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the library and is subject + to change. + */ + + + +/*********************************************************************** +// search for a match +************************************************************************/ + +#if (DD_BITS == 0) + + /* search ip in the dictionary */ + DINDEX1(dindex,ip); + GINDEX(m_pos,m_off,dict,dindex,in); + if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M3_MAX_OFFSET)) + goto literal; +#if 1 + if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) + goto try_match; + DINDEX2(dindex,ip); +#endif + GINDEX(m_pos,m_off,dict,dindex,in); + if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M3_MAX_OFFSET)) + goto literal; + if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) + goto try_match; + goto literal; + + +#else /* (DD_BITS == 0) */ + + + + /* search ip in the deepened dictionary */ + { + lzo_dict_p d = &dict [ DINDEX(dv,ip) ]; + const lzo_byte *ip_sav; + unsigned j = DD_SIZE; + lzo_uint x_len; + lzo_moff_t x_off; + + DVAL_ASSERT(dv,ip); + + ip_sav = ip; + m_len = 0; + do { +#if !defined(NDEBUG) + const lzo_byte *z_pos = NULL; +#endif +#if defined(LZO_DICT_USE_PTR) + m_pos = *d; + assert((z_pos = m_pos) == *d); +#if defined(LZO_DETERMINISTIC) + assert(m_pos == NULL || m_pos >= in); + assert(m_pos == NULL || m_pos < ip); +#endif +#else + x_off = *d; +#endif + assert(ip == ip_sav); + + if (LZO_CHECK_MPOS(m_pos,x_off,in,ip,MAX_OFFSET)) +#if (CLEVEL == 9) + *d = DENTRY(ip,in); +#else + ((void)(0)); +#endif + else if (m_pos[m_len] != ip[m_len]) + ((void)(0)); + else if (*m_pos++ == *ip++ && *m_pos++ == *ip++ && *m_pos++ == *ip++) + { +#if !defined(LZO_DICT_USE_PTR) + assert((z_pos = ip - 3 - x_off) == (m_pos - 3)); +#endif + /* a match */ + if (MATCH_M2) + { + x_len = (ip - 1) - ip_sav; + if (x_len > m_len) + { + m_len = x_len; + m_off = x_off; + assert((m_pos_sav = z_pos) != NULL); + } +#if (CLEVEL == 9) + /* try to find a closer match */ + else if (x_len == m_len && x_off < m_off) + { + m_off = x_off; + assert((m_pos_sav = z_pos) != NULL); + } +#endif + } + else + { + assert((ip - ip_sav) == M2_MAX_LEN + 1); +#if (CLEVEL == 9) +#if defined(MATCH_IP_END) + { + const lzo_byte *end; + end = MATCH_IP_END; + while (ip < end && *m_pos == *ip) + m_pos++, ip++; + assert(ip <= in_end); + x_len = ip - ip_sav; + } + if (x_len > m_len) + { + m_len = x_len; + m_off = x_off; + assert((m_pos_sav = z_pos) != NULL); + if (ip >= MATCH_IP_END) + { + ip = ip_sav; +#if 0 + /* not needed - we are at the end */ + d -= DD_SIZE - j; + assert(d == &dict [ DINDEX(dv,ip) ]); + UPDATE_P(d,drun,ip,in); +#endif + goto match; + } + } + else if (x_len == m_len && x_off < m_off) + { + m_off = x_off; + assert((m_pos_sav = z_pos) != NULL); + } +#else + /* try to find a closer match */ + if (m_len < M2_MAX_LEN + 1 || x_off < m_off) + { + m_len = M2_MAX_LEN + 1; + m_off = x_off; + assert((m_pos_sav = z_pos) != NULL); + } +#endif +#else + /* don't search for a longer/closer match */ + m_len = M2_MAX_LEN + 1; + m_off = x_off; + assert((m_pos_sav = z_pos) != NULL); + ip = ip_sav; + d -= DD_SIZE - j; + assert(d == &dict [ DINDEX(dv,ip) ]); + UPDATE_P(d,drun,ip,in); + goto match; +#endif + } + ip = ip_sav; + } + else + ip = ip_sav; + d++; + } while (--j > 0); + assert(ip == ip_sav); + + d -= DD_SIZE; + assert(d == &dict [ DINDEX(dv,ip) ]); + UPDATE_P(d,drun,ip,in); + } + +#endif /* (DD_BITS == 0) */ + + +/* +vi:ts=4:et +*/ diff --git a/DumpProto/lzo/lzo1b_tm.ch b/DumpProto/lzo/lzo1b_tm.ch new file mode 100644 index 0000000..cac39cf --- /dev/null +++ b/DumpProto/lzo/lzo1b_tm.ch @@ -0,0 +1,86 @@ +/* lzo1b_tm.ch -- implementation of the LZO1B compression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the library and is subject + to change. + */ + + + +/*********************************************************************** +// test for a potential match +************************************************************************/ + + +#if (DD_BITS == 0) + +try_match: +#if !defined(NDEBUG) && defined(LZO_DICT_USE_PTR) +#if defined(LZO_DETERMINISTIC) + assert(m_pos == NULL || m_pos >= in); + assert(m_pos == NULL || m_pos < ip); +#endif + m_pos_sav = m_pos; +#endif + if (m_pos[0] == ip[0] && m_pos[1] == ip[1] && m_pos[2] == ip[2]) + { + m_pos += 3; + goto match; + } + + +#else /* (DD_BITS == 0) */ + + + /* test potential match */ + + if (m_len > M2_MIN_LEN) + goto match; + if (m_len == M2_MIN_LEN) + { +#if (_MAX_OFFSET == _M2_MAX_OFFSET) + goto match; +#else + if (m_off <= M2_MAX_OFFSET) + goto match; +#if 0 && (M3_MIN_LEN == M2_MIN_LEN) + if (ip == ii) + goto match; +#endif +#endif + } + goto literal; + + +#endif /* (DD_BITS == 0) */ + + + +/* +vi:ts=4:et +*/ diff --git a/DumpProto/lzo/lzo1b_xx.c b/DumpProto/lzo/lzo1b_xx.c new file mode 100644 index 0000000..5b4d016 --- /dev/null +++ b/DumpProto/lzo/lzo1b_xx.c @@ -0,0 +1,85 @@ +/* lzo1b_xx.c -- LZO1B compression public entry point + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "config1b.h" + + +/*********************************************************************** +// +************************************************************************/ + +static const lzo_compress_t * const c_funcs [9] = +{ + &_lzo1b_1_compress_func, + &_lzo1b_2_compress_func, + &_lzo1b_3_compress_func, + &_lzo1b_4_compress_func, + &_lzo1b_5_compress_func, + &_lzo1b_6_compress_func, + &_lzo1b_7_compress_func, + &_lzo1b_8_compress_func, + &_lzo1b_9_compress_func +}; + + +lzo_compress_t _lzo1b_get_compress_func(int clevel) +{ + const lzo_compress_t *f; + + if (clevel < LZO1B_BEST_SPEED || clevel > LZO1B_BEST_COMPRESSION) + { + if (clevel == LZO1B_DEFAULT_COMPRESSION) + clevel = LZO1B_BEST_SPEED; + else + return 0; + } + f = c_funcs[clevel-1]; + assert(f && *f); + return *f; +} + + +LZO_PUBLIC(int) +lzo1b_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem, + int clevel ) +{ + lzo_compress_t f; + + f = _lzo1b_get_compress_func(clevel); + if (!f) + return LZO_E_ERROR; + return _lzo1b_do_compress(src,src_len,dst,dst_len,wrkmem,f); +} + + + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/lzo1c.h b/DumpProto/lzo/lzo1c.h new file mode 100644 index 0000000..a0d4d9b --- /dev/null +++ b/DumpProto/lzo/lzo1c.h @@ -0,0 +1,156 @@ +/* lzo1c.h -- public interface of the LZO1C compression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __LZO1C_H +#define __LZO1C_H + +#ifndef __LZOCONF_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// +************************************************************************/ + +/* Memory required for the wrkmem parameter. + * When the required size is 0, you can also pass a NULL pointer. + */ + +#define LZO1C_MEM_COMPRESS ((lzo_uint32) (16384L * lzo_sizeof_dict_t)) +#define LZO1C_MEM_DECOMPRESS (0) + + +/* compression levels */ +#define LZO1C_BEST_SPEED 1 +#define LZO1C_BEST_COMPRESSION 9 +#define LZO1C_DEFAULT_COMPRESSION (-1) /* fastest by default */ + + +LZO_EXTERN(int) +lzo1c_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem, + int compression_level ); + +/* decompression */ +LZO_EXTERN(int) +lzo1c_decompress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + +/* safe decompression with overrun testing */ +LZO_EXTERN(int) +lzo1c_decompress_safe ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + + +/*********************************************************************** +// +************************************************************************/ + +LZO_EXTERN(int) +lzo1c_1_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); +LZO_EXTERN(int) +lzo1c_2_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); +LZO_EXTERN(int) +lzo1c_3_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); +LZO_EXTERN(int) +lzo1c_4_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); +LZO_EXTERN(int) +lzo1c_5_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); +LZO_EXTERN(int) +lzo1c_6_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); +LZO_EXTERN(int) +lzo1c_7_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); +LZO_EXTERN(int) +lzo1c_8_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); +LZO_EXTERN(int) +lzo1c_9_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + + +/*********************************************************************** +// better compression ratio at the cost of more memory and time +************************************************************************/ + +#define LZO1C_99_MEM_COMPRESS ((lzo_uint32) (65536L * lzo_sizeof_dict_t)) + +#if !defined(LZO_99_UNSUPPORTED) +LZO_EXTERN(int) +lzo1c_99_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); +#endif + + +#define LZO1C_999_MEM_COMPRESS ((lzo_uint32) (5 * 16384L * sizeof(short))) + +#if !defined(LZO_999_UNSUPPORTED) +LZO_EXTERN(int) +lzo1c_999_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); +#endif + + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + diff --git a/DumpProto/lzo/lzo1c_1.c b/DumpProto/lzo/lzo1c_1.c new file mode 100644 index 0000000..c537292 --- /dev/null +++ b/DumpProto/lzo/lzo1c_1.c @@ -0,0 +1,6 @@ +#define COMPRESS_ID 1 + +#define DDBITS 0 +#define CLEVEL 1 +#include "compr1c.h" + diff --git a/DumpProto/lzo/lzo1c_2.c b/DumpProto/lzo/lzo1c_2.c new file mode 100644 index 0000000..7b6962a --- /dev/null +++ b/DumpProto/lzo/lzo1c_2.c @@ -0,0 +1,6 @@ +#define COMPRESS_ID 2 + +#define DDBITS 0 +#define CLEVEL 2 +#include "compr1c.h" + diff --git a/DumpProto/lzo/lzo1c_3.c b/DumpProto/lzo/lzo1c_3.c new file mode 100644 index 0000000..dcd6d67 --- /dev/null +++ b/DumpProto/lzo/lzo1c_3.c @@ -0,0 +1,6 @@ +#define COMPRESS_ID 3 + +#define DDBITS 0 +#define CLEVEL 3 +#include "compr1c.h" + diff --git a/DumpProto/lzo/lzo1c_4.c b/DumpProto/lzo/lzo1c_4.c new file mode 100644 index 0000000..5837f22 --- /dev/null +++ b/DumpProto/lzo/lzo1c_4.c @@ -0,0 +1,6 @@ +#define COMPRESS_ID 4 + +#define DDBITS 1 +#define CLEVEL 2 +#include "compr1c.h" + diff --git a/DumpProto/lzo/lzo1c_5.c b/DumpProto/lzo/lzo1c_5.c new file mode 100644 index 0000000..ba5601e --- /dev/null +++ b/DumpProto/lzo/lzo1c_5.c @@ -0,0 +1,6 @@ +#define COMPRESS_ID 5 + +#define DDBITS 1 +#define CLEVEL 3 +#include "compr1c.h" + diff --git a/DumpProto/lzo/lzo1c_6.c b/DumpProto/lzo/lzo1c_6.c new file mode 100644 index 0000000..fd62697 --- /dev/null +++ b/DumpProto/lzo/lzo1c_6.c @@ -0,0 +1,6 @@ +#define COMPRESS_ID 6 + +#define DDBITS 1 +#define CLEVEL 5 +#include "compr1c.h" + diff --git a/DumpProto/lzo/lzo1c_7.c b/DumpProto/lzo/lzo1c_7.c new file mode 100644 index 0000000..2b91973 --- /dev/null +++ b/DumpProto/lzo/lzo1c_7.c @@ -0,0 +1,6 @@ +#define COMPRESS_ID 7 + +#define DDBITS 2 +#define CLEVEL 3 +#include "compr1c.h" + diff --git a/DumpProto/lzo/lzo1c_8.c b/DumpProto/lzo/lzo1c_8.c new file mode 100644 index 0000000..a509251 --- /dev/null +++ b/DumpProto/lzo/lzo1c_8.c @@ -0,0 +1,6 @@ +#define COMPRESS_ID 8 + +#define DDBITS 2 +#define CLEVEL 8 +#include "compr1c.h" + diff --git a/DumpProto/lzo/lzo1c_9.c b/DumpProto/lzo/lzo1c_9.c new file mode 100644 index 0000000..9856f3e --- /dev/null +++ b/DumpProto/lzo/lzo1c_9.c @@ -0,0 +1,6 @@ +#define COMPRESS_ID 9 + +#define DDBITS 2 +#define CLEVEL 9 +#include "compr1c.h" + diff --git a/DumpProto/lzo/lzo1c_99.c b/DumpProto/lzo/lzo1c_99.c new file mode 100644 index 0000000..2ddd868 --- /dev/null +++ b/DumpProto/lzo/lzo1c_99.c @@ -0,0 +1,13 @@ +#include +#if !defined(LZO_99_UNSUPPORTED) + +#define COMPRESS_ID 99 + +#define DDBITS 3 +#define CLEVEL 9 + +#define D_BITS 16 +#define MATCH_IP_END in_end +#include "compr1c.h" + +#endif diff --git a/DumpProto/lzo/lzo1c_9x.c b/DumpProto/lzo/lzo1c_9x.c new file mode 100644 index 0000000..c6535a6 --- /dev/null +++ b/DumpProto/lzo/lzo1c_9x.c @@ -0,0 +1,384 @@ +/* lzo1c_9x.c -- implementation of the LZO1C-999 compression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + + +#include +#if !defined(LZO_999_UNSUPPORTED) + +#include +#include "config1c.h" + +#if 0 +#undef NDEBUG +#include +#endif + + +/*********************************************************************** +// +************************************************************************/ + +#define N 16383 /* size of ring buffer */ +#define THRESHOLD 2 /* lower limit for match length */ +#define F 2048 /* upper limit for match length */ + + +#define LZO1C +#define LZO_COMPRESS_T lzo1c_999_t +#define lzo_swd_t lzo1c_999_swd_t +#include "lzo_mchw.ch" + + + +/*********************************************************************** +// +************************************************************************/ + +static lzo_byte * +code_match ( LZO_COMPRESS_T *c, lzo_byte *op, lzo_uint m_len, lzo_uint m_off ) +{ + if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET) + { + assert(m_len >= M2_MIN_LEN); + assert(m_off >= M2_MIN_OFFSET); + + m_off -= M2_MIN_OFFSET; + /* code match len + low offset bits */ + *op++ = LZO_BYTE(((m_len - (M2_MIN_LEN - 2)) << M2O_BITS) | + (m_off & M2O_MASK)); + /* code high offset bits */ + *op++ = LZO_BYTE(m_off >> M2O_BITS); + c->m2_m++; + } + else + { + assert(m_len >= M3_MIN_LEN); + assert(m_off <= M3_MAX_OFFSET); + + m_off -= M3_MIN_OFFSET - M3_EOF_OFFSET; + /* code match len */ + if (m_len <= M3_MAX_LEN) + *op++ = LZO_BYTE(M3_MARKER | (m_len - (M3_MIN_LEN - 1))); + else + { + assert(m_len >= M4_MIN_LEN); + /* code M4 match len flag */ + *op++ = M4_MARKER; + /* code match len */ + m_len -= M4_MIN_LEN - 1; + while (m_len > 255) + { + m_len -= 255; + *op++ = 0; + } + assert(m_len > 0); + *op++ = LZO_BYTE(m_len); + } + /* code low offset bits */ + *op++ = LZO_BYTE(m_off & M3O_MASK); + /* code high offset bits */ + *op++ = LZO_BYTE(m_off >> M3O_BITS); + + c->r1_m_len = 0; + c->m3 = op; + c->m3_m++; + } + return op; +} + + +/*********************************************************************** +// this is a public function, but there is no prototype in a header file +************************************************************************/ + +LZO_EXTERN(int) +lzo1c_999_compress_callback ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem, + lzo_progress_callback_t cb, + lzo_uint max_chain ); + +LZO_PUBLIC(int) +lzo1c_999_compress_callback ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem, + lzo_progress_callback_t cb, + lzo_uint max_chain ) +{ + lzo_byte *op; + const lzo_byte *ii; + lzo_uint lit; + lzo_uint m_len, m_off; + LZO_COMPRESS_T cc; + LZO_COMPRESS_T * const c = &cc; + lzo_swd_t * const swd = (lzo_swd_t *) wrkmem; + int r; + +#if defined(__LZO_QUERY_COMPRESS) + if (__LZO_IS_COMPRESS_QUERY(in,in_len,out,out_len,wrkmem)) + return __LZO_QUERY_COMPRESS(in,in_len,out,out_len,wrkmem,1,lzo_sizeof(lzo_swd_t)); +#endif + + /* sanity check */ + if (!lzo_assert(LZO1C_999_MEM_COMPRESS >= lzo_sizeof(lzo_swd_t))) + return LZO_E_ERROR; + + c->init = 0; + c->ip = c->in = in; + c->in_end = in + in_len; + c->cb = cb; + c->r1_r = c->m3_r = c->m2_m = c->m3_m = 0; + + op = out; + ii = c->ip; /* point to start of literal run */ + lit = 0; + c->r1_m_len = 0; + c->m3 = out + 1; /* pointer after last m3/m4 match */ + + r = init_match(c,swd,NULL,0,0); + if (r != 0) + return r; + if (max_chain > 0) + swd->max_chain = max_chain; + + r = find_match(c,swd,0,0); + if (r != 0) + return r; + while (c->look > 0) + { + int lazy_match_min_gain = -1; + lzo_uint ahead = 0; + + m_len = c->m_len; + m_off = c->m_off; + +#if 0 + printf("%5ld: %5d len:%3d off:%5d\n", (c->ip-c->look)-in, c->look, + m_len, m_off); +#endif + + assert(c->ip - c->look >= in); + if (lit == 0) + ii = c->ip - c->look; + assert(ii + lit == c->ip - c->look); + assert(swd->b_char == *(c->ip - c->look)); + + if ((m_len < M2_MIN_LEN) || + (m_len < M3_MIN_LEN && m_off > M2_MAX_OFFSET)) + { + m_len = 0; + } + else + { + assert(c->ip - c->look - m_off >= in); + assert(c->ip - c->look - m_off + m_len < c->ip); + assert(lzo_memcmp(c->ip - c->look, c->ip - c->look - m_off, + m_len) == 0); + + if (lit > 0) + { + /* we have a current literal run: do not try a lazy match, + if the literal could be coded into a r1 or m3 match */ + if (lit == 1 && c->r1_m_len == M2_MIN_LEN) + lazy_match_min_gain = -1; + else if (lit == 3 && op == c->m3) + lazy_match_min_gain = -1; + else if (lit < 3 && op == c->m3) + lazy_match_min_gain = 0; + else + lazy_match_min_gain = 1; + +#if (M2_MIN_LEN == 2) + if (m_len == 2) + { + /* don't code a match of len 2 if we have to + code a literal run. Code a literal instead. */ + m_len = 0; + } +#endif +#if (M2_MIN_LEN == M3_MIN_LEN) + if (m_len == M2_MIN_LEN && m_off > M2_MAX_OFFSET) + { + /* don't code a M3 match of len 3 if we have to + code a literal run. Code a literal instead. */ + m_len = 0; + } +#endif + } + else + { + /* no current literal run: only try a lazy match, + if the literal could be coded into a r1 or m3 match */ + if (c->r1_m_len == M2_MIN_LEN || op == c->m3) + lazy_match_min_gain = 0; + else + lazy_match_min_gain = -1; + } + } + + + /* try a lazy match */ + if (m_len == 0) + lazy_match_min_gain = -1; + if (lazy_match_min_gain >= 0 && c->look > m_len) + { + assert(m_len > 0); + + r = find_match(c,swd,1,0); + assert(r == 0); + assert(c->look > 0); + + if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET && + c->m_off > M2_MAX_OFFSET) + lazy_match_min_gain += 1; + + if (c->m_len >= m_len + lazy_match_min_gain) + { + c->lazy++; +#if !defined(NDEBUG) + m_len = c->m_len; + m_off = c->m_off; + assert(lzo_memcmp(c->ip - c->look, c->ip - c->look - m_off, + m_len) == 0); +#endif + lit++; + assert(ii + lit == c->ip - c->look); + continue; + } + else + { + ahead = 1; + assert(ii + lit + 1 == c->ip - c->look); + } + assert(m_len > 0); + } + assert(ii + lit + ahead == c->ip - c->look); + + + if (m_len == 0) + { + /* a literal */ + lit++; + r = find_match(c,swd,1,0); + assert(r == 0); + } + else + { + /* 1 - store run */ + if (lit > 0) + { + /* code current literal run */ + if (lit == 1 && c->r1_m_len == M2_MIN_LEN) + { + /* Code a context sensitive R1 match. */ + assert((op[-2] >> M2O_BITS) == (M2_MARKER >> M2O_BITS)); + op[-2] &= M2O_MASK; + assert((op[-2] >> M2O_BITS) == 0); + /* copy 1 literal */ + *op++ = *ii++; + assert(ii + ahead == c->ip - c->look); + c->r1_r++; + } + else if (lit < 4 && op == c->m3) + { + assert((c->m3[-2] >> M3O_BITS) == 0); + c->m3[-2] |= LZO_BYTE(lit << M3O_BITS); + MEMCPY_DS(op, ii, lit); + assert(ii + ahead == c->ip - c->look); + c->m3_r++; + } + else + { + op = STORE_RUN(op,ii,lit); + } + if (lit < R0FAST) + c->r1_m_len = m_len; + else + c->r1_m_len = 0; + lit = 0; + } + else + c->r1_m_len = 0; + + /* 2 - code match */ + op = code_match(c,op,m_len,m_off); + r = find_match(c,swd,m_len,1+ahead); + assert(r == 0); + } + + c->codesize = op - out; + } + + + /* store final run */ + if (lit > 0) + op = STORE_RUN(op,ii,lit); + +#if defined(LZO_EOF_CODE) + *op++ = M3_MARKER | 1; + *op++ = 0; + *op++ = 0; +#endif + + c->codesize = op - out; + assert(c->textsize == in_len); + + *out_len = op - out; + + if (c->cb) + (*c->cb)(c->textsize,c->codesize); + +#if 0 + printf("%ld %ld -> %ld: %ld %ld %ld %ld %ld\n", + (long) c->textsize, (long)in_len, (long) c->codesize, + c->r1_r, c->m3_r, c->m2_m, c->m3_m, c->lazy); +#endif + return LZO_E_OK; +} + + + +/*********************************************************************** +// +************************************************************************/ + +LZO_PUBLIC(int) +lzo1c_999_compress ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ + return lzo1c_999_compress_callback(in,in_len,out,out_len,wrkmem, + (lzo_progress_callback_t) 0, 0); +} + + +#endif /* !defined(LZO_999_UNSUPPORTED) */ + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/lzo1c_cc.c b/DumpProto/lzo/lzo1c_cc.c new file mode 100644 index 0000000..6971c0a --- /dev/null +++ b/DumpProto/lzo/lzo1c_cc.c @@ -0,0 +1,154 @@ +/* lzo1c_cc.c -- LZO1C compression internal entry point + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#define LZO_NEED_DICT_H +#include "config1c.h" + + +/*********************************************************************** +// compression internal entry point. +************************************************************************/ + +int _lzo1c_do_compress ( const lzo_byte *in, lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem, + lzo_compress_t func ) +{ + int r; +#if defined(LZO_TEST_COMPRESS_OVERRUN) + lzo_uint avail_out = *out_len; +#endif + + +#if defined(LZO_COLLECT_STATS) + _lzo1c_stats_init(lzo_stats); + lzo_stats->in_len = in_len; +#endif + + + /* don't try to compress a block that's too short */ + if (in_len <= 0) + { + *out_len = 0; + r = LZO_E_OK; + } + else if (in_len <= MIN_LOOKAHEAD + 1) + { +#if defined(LZO_RETURN_IF_NOT_COMPRESSIBLE) + *out_len = 0; + r = LZO_E_NOT_COMPRESSIBLE; +#else + *out_len = STORE_RUN(out,in,in_len) - out; + r = (*out_len > in_len) ? LZO_E_OK : LZO_E_ERROR; +#endif + } + else + r = func(in,in_len,out,out_len,wrkmem); + + +#if defined(LZO_EOF_CODE) +#if defined(LZO_TEST_COMPRESS_OVERRUN) + if (r == LZO_E_OK && avail_out - *out_len < 3) + r = LZO_E_COMPRESS_OVERRUN; +#endif + if (r == LZO_E_OK) + { + lzo_byte *op = out + *out_len; + *op++ = M3_MARKER | 1; + *op++ = 0; + *op++ = 0; + *out_len += 3; + } +#endif + + +#if defined(LZO_COLLECT_STATS) + lzo_stats->out_len = *out_len; + lzo_stats->match_bytes = + 1 * lzo_stats->m1_matches + 2 * lzo_stats->m2_matches + + 3 * lzo_stats->m3_matches + 4 * lzo_stats->m4_matches; + _lzo1c_stats_calc(lzo_stats); +#endif + + return r; +} + + +/*********************************************************************** +// note: this is not thread safe, but as it is used for finetuning only +// we don't care +************************************************************************/ + +#undef lzo_stats +/* lzo_stats_t is still defined */ + + +#if defined(LZO_COLLECT_STATS) + +static lzo_stats_t lzo_statistics; +lzo_stats_t * const lzo1c_stats = &lzo_statistics; + + +void _lzo1c_stats_init(lzo_stats_t *lzo_stats) +{ + memset(lzo_stats,0,sizeof(*lzo_stats)); +} + + +void _lzo1c_stats_calc(lzo_stats_t *lzo_stats) +{ + lzo_stats->matches = + lzo_stats->m1_matches + lzo_stats->m2_matches + + lzo_stats->m3_matches + lzo_stats->m4_matches; + + lzo_stats->literal_overhead = lzo_stats->lit_runs + + 2 * (lzo_stats->r0short_runs + lzo_stats->r0fast_runs + + lzo_stats->r0long_runs); + lzo_stats->literal_bytes = lzo_stats->literals + + lzo_stats->literal_overhead; + +#if 0 + assert(lzo_stats->match_bytes + lzo_stats->literal_bytes == + lzo_stats->out_len); +#endif + + lzo_stats->m2_matches -= lzo_stats->r1_matches; + lzo_stats->m2_match[M2_MIN_LEN] -= lzo_stats->r1_matches; + + if (lzo_stats->literals > 0) + lzo_stats->literal_overhead_percent = + 100.0 * lzo_stats->literal_overhead / lzo_stats->literals; +} + + +#endif + + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/lzo1c_cc.h b/DumpProto/lzo/lzo1c_cc.h new file mode 100644 index 0000000..deb8f3b --- /dev/null +++ b/DumpProto/lzo/lzo1c_cc.h @@ -0,0 +1,80 @@ +/* lzo1c_cc.h -- definitions for the the LZO1C compression driver + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the library and is subject + to change. + */ + + +#ifndef __LZO1C_CC_H +#define __LZO1C_CC_H + + +/*********************************************************************** +// +************************************************************************/ + +extern const lzo_compress_t _lzo1c_1_compress_func; +extern const lzo_compress_t _lzo1c_2_compress_func; +extern const lzo_compress_t _lzo1c_3_compress_func; +extern const lzo_compress_t _lzo1c_4_compress_func; +extern const lzo_compress_t _lzo1c_5_compress_func; +extern const lzo_compress_t _lzo1c_6_compress_func; +extern const lzo_compress_t _lzo1c_7_compress_func; +extern const lzo_compress_t _lzo1c_8_compress_func; +extern const lzo_compress_t _lzo1c_9_compress_func; + +extern const lzo_compress_t _lzo1c_99_compress_func; + + +/*********************************************************************** +// +************************************************************************/ + +LZO_EXTERN(lzo_byte *) +_lzo1c_store_run ( lzo_byte * const oo, const lzo_byte * const ii, + lzo_uint r_len); + +#define STORE_RUN _lzo1c_store_run + + +lzo_compress_t _lzo1c_get_compress_func(int clevel); + +int _lzo1c_do_compress ( const lzo_byte *in, lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem, + lzo_compress_t func ); + + +#endif /* already included */ + +/* +vi:ts=4:et +*/ + + diff --git a/DumpProto/lzo/lzo1c_d1.c b/DumpProto/lzo/lzo1c_d1.c new file mode 100644 index 0000000..3dec20b --- /dev/null +++ b/DumpProto/lzo/lzo1c_d1.c @@ -0,0 +1,33 @@ +/* lzo1c_d1.c -- LZO1C decompression + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "config1c.h" + +#undef LZO_TEST_DECOMPRESS_OVERRUN +#define DO_DECOMPRESS lzo1c_decompress + +#include "lzo1b_d.ch" diff --git a/DumpProto/lzo/lzo1c_d2.c b/DumpProto/lzo/lzo1c_d2.c new file mode 100644 index 0000000..68eec12 --- /dev/null +++ b/DumpProto/lzo/lzo1c_d2.c @@ -0,0 +1,33 @@ +/* lzo1c_d2.c -- LZO1C decompression with overrun testing + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "config1c.h" + +#define LZO_TEST_DECOMPRESS_OVERRUN +#define DO_DECOMPRESS lzo1c_decompress_safe + +#include "lzo1b_d.ch" diff --git a/DumpProto/lzo/lzo1c_rr.c b/DumpProto/lzo/lzo1c_rr.c new file mode 100644 index 0000000..2009de6 --- /dev/null +++ b/DumpProto/lzo/lzo1c_rr.c @@ -0,0 +1,30 @@ +/* lzo1c_rr.c -- literal run handling + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "config1c.h" + +#include "lzo1b_r.ch" diff --git a/DumpProto/lzo/lzo1c_xx.c b/DumpProto/lzo/lzo1c_xx.c new file mode 100644 index 0000000..31be16d --- /dev/null +++ b/DumpProto/lzo/lzo1c_xx.c @@ -0,0 +1,85 @@ +/* lzo1c_xx.c -- LZO1C compression public entry point + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "config1c.h" + + +/*********************************************************************** +// +************************************************************************/ + +static const lzo_compress_t * const c_funcs [9] = +{ + &_lzo1c_1_compress_func, + &_lzo1c_2_compress_func, + &_lzo1c_3_compress_func, + &_lzo1c_4_compress_func, + &_lzo1c_5_compress_func, + &_lzo1c_6_compress_func, + &_lzo1c_7_compress_func, + &_lzo1c_8_compress_func, + &_lzo1c_9_compress_func +}; + + +lzo_compress_t _lzo1c_get_compress_func(int clevel) +{ + const lzo_compress_t *f; + + if (clevel < LZO1C_BEST_SPEED || clevel > LZO1C_BEST_COMPRESSION) + { + if (clevel == LZO1C_DEFAULT_COMPRESSION) + clevel = LZO1C_BEST_SPEED; + else + return 0; + } + f = c_funcs[clevel-1]; + assert(f && *f); + return *f; +} + + +LZO_PUBLIC(int) +lzo1c_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem, + int clevel ) +{ + lzo_compress_t f; + + f = _lzo1c_get_compress_func(clevel); + if (!f) + return LZO_E_ERROR; + return _lzo1c_do_compress(src,src_len,dst,dst_len,wrkmem,f); +} + + + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/lzo1f.h b/DumpProto/lzo/lzo1f.h new file mode 100644 index 0000000..c44f13c --- /dev/null +++ b/DumpProto/lzo/lzo1f.h @@ -0,0 +1,102 @@ +/* lzo1f.h -- public interface of the LZO1F compression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __LZO1F_H +#define __LZO1F_H + +#ifndef __LZOCONF_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// +************************************************************************/ + +/* Memory required for the wrkmem parameter. + * When the required size is 0, you can also pass a NULL pointer. + */ + +#define LZO1F_MEM_COMPRESS ((lzo_uint32) (16384L * lzo_sizeof_dict_t)) +#define LZO1F_MEM_DECOMPRESS (0) + + +/* decompression */ +LZO_EXTERN(int) +lzo1f_decompress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + +/* safe decompression with overrun testing */ +LZO_EXTERN(int) +lzo1f_decompress_safe ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + + +/*********************************************************************** +// +************************************************************************/ + +LZO_EXTERN(int) +lzo1f_1_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + + +/*********************************************************************** +// better compression ratio at the cost of more memory and time +************************************************************************/ + +#define LZO1F_999_MEM_COMPRESS ((lzo_uint32) (5 * 16384L * sizeof(short))) + +#if !defined(LZO_999_UNSUPPORTED) +LZO_EXTERN(int) +lzo1f_999_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); +#endif + + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + diff --git a/DumpProto/lzo/lzo1f_1.c b/DumpProto/lzo/lzo1f_1.c new file mode 100644 index 0000000..495f096 --- /dev/null +++ b/DumpProto/lzo/lzo1f_1.c @@ -0,0 +1,312 @@ +/* lzo1f_1.c -- implementation of the LZO1F-1 compression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include +#include "lzo_conf.h" + + +/*********************************************************************** +// +************************************************************************/ + +#define M2_MAX_OFFSET 0x0800 +#define M3_MAX_OFFSET 0x3fff +#define M3_MARKER 224 + + +#ifndef LZO_HASH +#define LZO_HASH LZO_HASH_LZO_INCREMENTAL_A +#endif +#define D_BITS 14 +#define D_INDEX1(d,p) d = DM((0x21*DX3(p,5,5,6)) >> 5) +#define D_INDEX2(d,p) d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f) +#include "lzo_dict.h" + + +/*********************************************************************** +// compress a block of data. +************************************************************************/ + +static +int do_compress ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ +#if 0 && defined(__GNUC__) && defined(__i386__) + register const lzo_byte *ip __asm__("%esi"); +#else + register const lzo_byte *ip; +#endif + lzo_byte *op; + const lzo_byte * const in_end = in + in_len; + const lzo_byte * const ip_end = in + in_len - 9; + const lzo_byte *ii; + lzo_dict_p const dict = (lzo_dict_p) wrkmem; + + op = out; + ip = in; + ii = ip; + + ip++; + for (;;) + { +#if 0 && defined(__GNUC__) && defined(__i386__) + register const lzo_byte *m_pos __asm__("%edi"); +#else + register const lzo_byte *m_pos; +#endif + lzo_moff_t m_off; + lzo_uint m_len; + lzo_uint dindex; + lzo_uint lit; + + DINDEX1(dindex,ip); + GINDEX(m_pos,m_off,dict,dindex,in); + if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M3_MAX_OFFSET)) + goto literal; +#if 1 + if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) + goto try_match; + DINDEX2(dindex,ip); +#endif + GINDEX(m_pos,m_off,dict,dindex,in); + if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M3_MAX_OFFSET)) + goto literal; + if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) + goto try_match; + goto literal; + + +try_match: +#if 0 && defined(LZO_UNALIGNED_OK_2) + if (* (const lzo_ushortp) m_pos != * (const lzo_ushortp) ip) +#else + if (m_pos[0] != ip[0] || m_pos[1] != ip[1]) +#endif + { + } + else + { + if (m_pos[2] == ip[2]) + { + m_pos += 3; +#if 0 + if (m_off <= M2_MAX_OFFSET) + goto match; + if (lit <= 3) + goto match; + if (lit == 3) /* better compression, but slower */ + { + assert(op - 2 > out); op[-2] |= LZO_BYTE(3); + *op++ = *ii++; *op++ = *ii++; *op++ = *ii++; + goto code_match; + } + if (*m_pos == ip[3]) +#endif + goto match; + } + } + + + /* a literal */ +literal: + UPDATE_I(dict,0,dindex,ip,in); + if (++ip >= ip_end) + break; + continue; + + + /* a match */ +match: + UPDATE_I(dict,0,dindex,ip,in); + /* store current literal run */ + lit = pd(ip,ii); + if (lit > 0) + { + register lzo_uint t = lit; + + if (t < 4 && op > out) + op[-2] |= LZO_BYTE(t); + else if (t <= 31) + *op++ = LZO_BYTE(t); + else + { + register lzo_uint tt = t - 31; + + *op++ = 0; + while (tt > 255) + { + tt -= 255; + *op++ = 0; + } + assert(tt > 0); + *op++ = LZO_BYTE(tt); + } + do *op++ = *ii++; while (--t > 0); + } + assert(ii == ip); + + + /* code the match */ + ip += 3; + if (*m_pos++ != *ip++ || *m_pos++ != *ip++ || *m_pos++ != *ip++ || + *m_pos++ != *ip++ || *m_pos++ != *ip++ || *m_pos++ != *ip++) + { + --ip; + m_len = ip - ii; + assert(m_len >= 3); assert(m_len <= 8); + + if (m_off <= M2_MAX_OFFSET) + { + m_off -= 1; + *op++ = LZO_BYTE(((m_len - 2) << 5) | ((m_off & 7) << 2)); + *op++ = LZO_BYTE(m_off >> 3); + } + else if (m_len == 3 && m_off <= 2*M2_MAX_OFFSET && lit > 0) + { + m_off -= 1; + /* m_off -= M2_MAX_OFFSET; */ + *op++ = LZO_BYTE(((m_off & 7) << 2)); + *op++ = LZO_BYTE(m_off >> 3); + } + else + { + *op++ = LZO_BYTE(M3_MARKER | (m_len - 2)); + *op++ = LZO_BYTE((m_off & 63) << 2); + *op++ = LZO_BYTE(m_off >> 6); + } + } + else + { + { + const lzo_byte *end; + end = in_end; + while (ip < end && *m_pos == *ip) + m_pos++, ip++; + m_len = (ip - ii); + } + assert(m_len >= 3); + + if (m_len <= 33) + *op++ = LZO_BYTE(M3_MARKER | (m_len - 2)); + else + { + m_len -= 33; + *op++ = M3_MARKER | 0; + while (m_len > 255) + { + m_len -= 255; + *op++ = 0; + } + assert(m_len > 0); + *op++ = LZO_BYTE(m_len); + } + *op++ = LZO_BYTE((m_off & 63) << 2); + *op++ = LZO_BYTE(m_off >> 6); + } + + ii = ip; + if (ip >= ip_end) + break; + } + + + /* store final literal run */ + if (pd(in_end,ii) > 0) + { + register lzo_uint t = pd(in_end,ii); + + if (t < 4 && op > out) + op[-2] |= LZO_BYTE(t); + else if (t <= 31) + *op++ = LZO_BYTE(t); + else + { + register lzo_uint tt = t - 31; + + *op++ = 0; + while (tt > 255) + { + tt -= 255; + *op++ = 0; + } + assert(tt > 0); + *op++ = LZO_BYTE(tt); + } + do *op++ = *ii++; while (--t > 0); + } + + *out_len = op - out; + return LZO_E_OK; +} + + +/*********************************************************************** +// public entry point +************************************************************************/ + +LZO_PUBLIC(int) +lzo1f_1_compress ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ + lzo_byte *op = out; + int r = LZO_E_OK; + +#if defined(__LZO_QUERY_COMPRESS) + if (__LZO_IS_COMPRESS_QUERY(in,in_len,out,out_len,wrkmem)) + return __LZO_QUERY_COMPRESS(in,in_len,out,out_len,wrkmem,D_SIZE,lzo_sizeof(lzo_dict_t)); +#endif + + if (in_len <= 0) + *out_len = 0; + else if (in_len <= 10) + { + *op++ = LZO_BYTE(in_len); + do *op++ = *in++; while (--in_len > 0); + *out_len = op - out; + } + else + r = do_compress(in,in_len,out,out_len,wrkmem); + + if (r == LZO_E_OK) + { + op = out + *out_len; + *op++ = M3_MARKER | 1; + *op++ = 0; + *op++ = 0; + *out_len += 3; + } + + return r; +} + + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/lzo1f_9x.c b/DumpProto/lzo/lzo1f_9x.c new file mode 100644 index 0000000..8627d5e --- /dev/null +++ b/DumpProto/lzo/lzo1f_9x.c @@ -0,0 +1,350 @@ +/* lzo1f_9x.c -- implementation of the LZO1F-999 compression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + + +#include +#if !defined(LZO_999_UNSUPPORTED) + +#include +#include "config1f.h" + +#if 0 +#undef NDEBUG +#include +#endif + + +/*********************************************************************** +// +************************************************************************/ + +#define N 16383 /* size of ring buffer */ +#define THRESHOLD 2 /* lower limit for match length */ +#define F 2048 /* upper limit for match length */ + + +#define LZO1F +#define LZO_COMPRESS_T lzo1f_999_t +#define lzo_swd_t lzo1f_999_swd_t +#include "lzo_mchw.ch" + + + +/*********************************************************************** +// +************************************************************************/ + +static lzo_byte * +code_match ( LZO_COMPRESS_T *c, lzo_byte *op, lzo_uint m_len, lzo_uint m_off ) +{ + if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET) + { + m_off -= 1; + *op++ = LZO_BYTE(((m_len - 2) << 5) | ((m_off & 7) << 2)); + *op++ = LZO_BYTE(m_off >> 3); + c->m2_m++; + } + else if (m_len == M2_MIN_LEN && m_off <= 2 * M2_MAX_OFFSET && + c->r1_lit > 0) + { + assert(m_off > M2_MAX_OFFSET); + m_off -= 1 + M2_MAX_OFFSET; + *op++ = LZO_BYTE(((m_off & 7) << 2)); + *op++ = LZO_BYTE(m_off >> 3); + c->r1_r++; + } + else + { + if (m_len <= M3_MAX_LEN) + *op++ = LZO_BYTE(M3_MARKER | (m_len - 2)); + else + { + m_len -= M3_MAX_LEN; + *op++ = M3_MARKER | 0; + while (m_len > 255) + { + m_len -= 255; + *op++ = 0; + } + assert(m_len > 0); + *op++ = LZO_BYTE(m_len); + } + *op++ = LZO_BYTE((m_off & 63) << 2); + *op++ = LZO_BYTE(m_off >> 6); + c->m3_m++; + } + + return op; +} + + +static lzo_byte * +STORE_RUN ( lzo_byte *op, const lzo_byte *ii, lzo_uint t, lzo_byte *out ) +{ + if (t < 4 && op > out) + op[-2] |= LZO_BYTE(t); + else if (t <= 31) + *op++ = LZO_BYTE(t); + else + { + lzo_uint tt = t - 31; + + *op++ = 0; + while (tt > 255) + { + tt -= 255; + *op++ = 0; + } + assert(tt > 0); + *op++ = LZO_BYTE(tt); + } + do *op++ = *ii++; while (--t > 0); + + return op; +} + + +/*********************************************************************** +// this is a public function, but there is no prototype in a header file +************************************************************************/ + +LZO_EXTERN(int) +lzo1f_999_compress_callback ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem, + lzo_progress_callback_t cb, + lzo_uint max_chain ); + +LZO_PUBLIC(int) +lzo1f_999_compress_callback ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem, + lzo_progress_callback_t cb, + lzo_uint max_chain ) +{ + lzo_byte *op; + const lzo_byte *ii; + lzo_uint lit; + lzo_uint m_len, m_off; + LZO_COMPRESS_T cc; + LZO_COMPRESS_T * const c = &cc; + lzo_swd_t * const swd = (lzo_swd_t *) wrkmem; + int r; + +#if defined(__LZO_QUERY_COMPRESS) + if (__LZO_IS_COMPRESS_QUERY(in,in_len,out,out_len,wrkmem)) + return __LZO_QUERY_COMPRESS(in,in_len,out,out_len,wrkmem,1,lzo_sizeof(lzo_swd_t)); +#endif + + /* sanity check */ + if (!lzo_assert(LZO1F_999_MEM_COMPRESS >= lzo_sizeof(lzo_swd_t))) + return LZO_E_ERROR; + + c->init = 0; + c->ip = c->in = in; + c->in_end = in + in_len; + c->cb = cb; + c->r1_r = c->m2_m = c->m3_m = 0; + + op = out; + ii = c->ip; /* point to start of literal run */ + lit = 0; + c->r1_lit = c->r1_m_len = 0; + + r = init_match(c,swd,NULL,0,0); + if (r != 0) + return r; + if (max_chain > 0) + swd->max_chain = max_chain; + + r = find_match(c,swd,0,0); + if (r != 0) + return r; + while (c->look > 0) + { + int lazy_match_min_gain = -1; + lzo_uint ahead = 0; + + m_len = c->m_len; + m_off = c->m_off; + + assert(c->ip - c->look >= in); + if (lit == 0) + ii = c->ip - c->look; + assert(ii + lit == c->ip - c->look); + assert(swd->b_char == *(c->ip - c->look)); + + if ((m_len < M2_MIN_LEN) || + (m_len < M3_MIN_LEN && m_off > M2_MAX_OFFSET)) + { + m_len = 0; + } + else + { + assert(c->ip - c->look - m_off >= in); + assert(c->ip - c->look - m_off + m_len < c->ip); + assert(lzo_memcmp(c->ip - c->look, c->ip - c->look - m_off, + m_len) == 0); + + if (lit < 3) + lazy_match_min_gain = 1; + else if (lit == 3) + lazy_match_min_gain = 3; + else if (lit == 31) + lazy_match_min_gain = 3; + else + lazy_match_min_gain = 1; + } + + /* try a lazy match */ + if (m_len > 0 && lazy_match_min_gain >= 0 && c->look > m_len) + { + r = find_match(c,swd,1,0); + assert(r == 0); + assert(c->look > 0); + + if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET && + c->m_off > M2_MAX_OFFSET) + { + lazy_match_min_gain += 1; + } + else if (c->m_len <= M2_MAX_LEN && + c->m_off <= M2_MAX_OFFSET && + m_off > M2_MAX_OFFSET) + { + if (lazy_match_min_gain > 0) + lazy_match_min_gain -= 1; + } + else if (m_len == M2_MIN_LEN && c->m_len == M2_MIN_LEN && + c->m_off <= 2 * M2_MAX_OFFSET && + m_off > M2_MAX_OFFSET) + { + if (lazy_match_min_gain > 0) + lazy_match_min_gain -= 1; + } + + if (c->m_len >= m_len + lazy_match_min_gain) + { + c->lazy++; +#if !defined(NDEBUG) + m_len = c->m_len; + m_off = c->m_off; + assert(lzo_memcmp(c->ip - c->look, c->ip - c->look - m_off, + m_len) == 0); +#endif + lit++; + assert(ii + lit == c->ip - c->look); + continue; + } + else + { + ahead = 1; + assert(ii + lit + 1 == c->ip - c->look); + } + assert(m_len > 0); + } + assert(ii + lit + ahead == c->ip - c->look); + + + if (m_len == 0) + { + /* a literal */ + lit++; + r = find_match(c,swd,1,0); + assert(r == 0); + } + else + { + /* 1 - store run */ + if (lit > 0) + { + op = STORE_RUN(op,ii,lit,out); + c->r1_m_len = m_len; + c->r1_lit = lit; + lit = 0; + } + else + c->r1_lit = c->r1_m_len = 0; + + /* 2 - code match */ + op = code_match(c,op,m_len,m_off); + r = find_match(c,swd,m_len,1+ahead); + assert(r == 0); + } + + c->codesize = op - out; + } + + + /* store final run */ + if (lit > 0) + op = STORE_RUN(op,ii,lit,out); + +#if defined(LZO_EOF_CODE) + *op++ = M3_MARKER | 1; + *op++ = 0; + *op++ = 0; +#endif + + c->codesize = op - out; + assert(c->textsize == in_len); + + *out_len = op - out; + + if (c->cb) + (*c->cb)(c->textsize,c->codesize); + +#if 0 + printf("%ld %ld -> %ld: %ld %ld %ld %ld\n", + (long) c->textsize, (long)in_len, (long) c->codesize, + c->r1_r, c->m2_m, c->m3_m, c->lazy); +#endif + return LZO_E_OK; +} + + + +/*********************************************************************** +// +************************************************************************/ + +LZO_PUBLIC(int) +lzo1f_999_compress ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ + return lzo1f_999_compress_callback(in,in_len,out,out_len,wrkmem, + (lzo_progress_callback_t) 0, 0); +} + + +#endif /* !defined(LZO_999_UNSUPPORTED) */ + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/lzo1f_d.ch b/DumpProto/lzo/lzo1f_d.ch new file mode 100644 index 0000000..27d5fd2 --- /dev/null +++ b/DumpProto/lzo/lzo1f_d.ch @@ -0,0 +1,215 @@ +/* lzo1f_d.ch -- implementation of the LZO1F decompression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "lzo1_d.ch" + + +/*********************************************************************** +// decompress a block of data. +************************************************************************/ + +LZO_PUBLIC(int) +DO_DECOMPRESS ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ + register lzo_byte *op; + register const lzo_byte *ip; + register lzo_uint t; + register const lzo_byte *m_pos; + + const lzo_byte * const ip_end = in + in_len; +#if defined(HAVE_ANY_OP) + lzo_byte * const op_end = out + *out_len; +#endif + + LZO_UNUSED(wrkmem); + +#if defined(__LZO_QUERY_DECOMPRESS) + if (__LZO_IS_DECOMPRESS_QUERY(in,in_len,out,out_len,wrkmem)) + return __LZO_QUERY_DECOMPRESS(in,in_len,out,out_len,wrkmem,0,0); +#endif + + *out_len = 0; + + op = out; + ip = in; + + while (TEST_IP && TEST_OP) + { + t = *ip++; + if (t > 31) + goto match; + + /* a literal run */ + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 31 + *ip++; + } + /* copy literals */ + assert(t > 0); NEED_OP(t); NEED_IP(t+1); +#if defined(LZO_UNALIGNED_OK_4) + if (t >= 4) + { + do { + * (lzo_uint32p) op = * (const lzo_uint32p) ip; + op += 4; ip += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *ip++; while (--t > 0); + } + else +#endif + do *op++ = *ip++; while (--t > 0); + + t = *ip++; + + while (TEST_IP && TEST_OP) + { + /* handle matches */ + if (t < 32) + { + m_pos = op - 1 - 0x800; + m_pos -= (t >> 2) & 7; + m_pos -= *ip++ << 3; + TEST_LOOKBEHIND(m_pos,out); NEED_OP(3); + *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos++; + } + else + { +match: + if (t < M3_MARKER) + { + m_pos = op - 1; + m_pos -= (t >> 2) & 7; + m_pos -= *ip++ << 3; + t >>= 5; + TEST_LOOKBEHIND(m_pos,out); assert(t > 0); NEED_OP(t+3-1); + goto copy_match; + } + else + { + t &= 31; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 31 + *ip++; + } + NEED_IP(2); + m_pos = op; +#if defined(LZO_UNALIGNED_OK_2) && (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN) + m_pos -= (* (const lzo_ushortp) ip) >> 2; + ip += 2; +#else + m_pos -= *ip++ >> 2; + m_pos -= *ip++ << 6; +#endif + if (m_pos == op) + goto eof_found; + } + + /* copy match */ + TEST_LOOKBEHIND(m_pos,out); assert(t > 0); NEED_OP(t+3-1); +#if defined(LZO_UNALIGNED_OK_4) + if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) + { + * (lzo_uint32p) op = * (const lzo_uint32p) m_pos; + op += 4; m_pos += 4; t -= 4 - (3 - 1); + do { + * (lzo_uint32p) op = * (const lzo_uint32p) m_pos; + op += 4; m_pos += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *m_pos++; while (--t > 0); + } + else +#endif + { +copy_match: + *op++ = *m_pos++; *op++ = *m_pos++; + do *op++ = *m_pos++; while (--t > 0); + } + } + t = ip[-2] & 3; + if (t == 0) + break; + + /* copy literals */ + assert(t > 0); NEED_OP(t); NEED_IP(t+1); + do *op++ = *ip++; while (--t > 0); + t = *ip++; + } + } + +#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP) + /* no EOF code was found */ + *out_len = op - out; + return LZO_E_EOF_NOT_FOUND; +#endif + +eof_found: + assert(t == 1); + *out_len = op - out; + return (ip == ip_end ? LZO_E_OK : + (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); + + +#if defined(HAVE_NEED_IP) +input_overrun: + *out_len = op - out; + return LZO_E_INPUT_OVERRUN; +#endif + +#if defined(HAVE_NEED_OP) +output_overrun: + *out_len = op - out; + return LZO_E_OUTPUT_OVERRUN; +#endif + +#if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND) +lookbehind_overrun: + *out_len = op - out; + return LZO_E_LOOKBEHIND_OVERRUN; +#endif +} + + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/lzo1f_d1.c b/DumpProto/lzo/lzo1f_d1.c new file mode 100644 index 0000000..b719bba --- /dev/null +++ b/DumpProto/lzo/lzo1f_d1.c @@ -0,0 +1,33 @@ +/* lzo1f_d1.c -- LZO1F decompression + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "config1f.h" + +#undef LZO_TEST_DECOMPRESS_OVERRUN +#define DO_DECOMPRESS lzo1f_decompress + +#include "lzo1f_d.ch" diff --git a/DumpProto/lzo/lzo1f_d2.c b/DumpProto/lzo/lzo1f_d2.c new file mode 100644 index 0000000..1c7542c --- /dev/null +++ b/DumpProto/lzo/lzo1f_d2.c @@ -0,0 +1,33 @@ +/* lzo1f_d2.c -- LZO1F decompression with overrun testing + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "config1f.h" + +#define LZO_TEST_DECOMPRESS_OVERRUN +#define DO_DECOMPRESS lzo1f_decompress_safe + +#include "lzo1f_d.ch" diff --git a/DumpProto/lzo/lzo1x.h b/DumpProto/lzo/lzo1x.h new file mode 100644 index 0000000..6d4ac03 --- /dev/null +++ b/DumpProto/lzo/lzo1x.h @@ -0,0 +1,173 @@ +/* lzo1x.h -- public interface of the LZO1X compression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __LZO1X_H +#define __LZO1X_H + +#ifndef __LZOCONF_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// +************************************************************************/ + +/* Memory required for the wrkmem parameter. + * When the required size is 0, you can also pass a NULL pointer. + */ + +#define LZO1X_MEM_COMPRESS LZO1X_1_MEM_COMPRESS +#define LZO1X_MEM_DECOMPRESS (0) +#define LZO1X_MEM_OPTIMIZE (0) + + +/* decompression */ +LZO_EXTERN(int) +lzo1x_decompress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + +/* safe decompression with overrun testing */ +LZO_EXTERN(int) +lzo1x_decompress_safe ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + + +/*********************************************************************** +// +************************************************************************/ + +#define LZO1X_1_MEM_COMPRESS ((lzo_uint32) (16384L * lzo_sizeof_dict_t)) + +LZO_EXTERN(int) +lzo1x_1_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + + +/*********************************************************************** +// special compressor versions +************************************************************************/ + +/* this version needs only 8 kB work memory */ +#define LZO1X_1_11_MEM_COMPRESS ((lzo_uint32) (2048L * lzo_sizeof_dict_t)) + +LZO_EXTERN(int) +lzo1x_1_11_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + + +/* this version needs 16 kB work memory */ +#define LZO1X_1_12_MEM_COMPRESS ((lzo_uint32) (4096L * lzo_sizeof_dict_t)) + +LZO_EXTERN(int) +lzo1x_1_12_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + + +/* use this version if you need a little more compression speed */ +#define LZO1X_1_15_MEM_COMPRESS ((lzo_uint32) (32768L * lzo_sizeof_dict_t)) + +LZO_EXTERN(int) +lzo1x_1_15_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + + +/*********************************************************************** +// better compression ratio at the cost of more memory and time +************************************************************************/ + +#define LZO1X_999_MEM_COMPRESS ((lzo_uint32) (14 * 16384L * sizeof(short))) + +#if !defined(LZO_999_UNSUPPORTED) +LZO_EXTERN(int) +lzo1x_999_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); +#endif + + +/*********************************************************************** +// +************************************************************************/ + +#if !defined(LZO_999_UNSUPPORTED) +LZO_EXTERN(int) +lzo1x_999_compress_dict ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem, + const lzo_byte *dict, lzo_uint dict_len ); + +LZO_EXTERN(int) +lzo1x_999_compress_level ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem, + const lzo_byte *dict, lzo_uint dict_len, + lzo_progress_callback_t cb, + int compression_level ); +#endif + +LZO_EXTERN(int) +lzo1x_decompress_dict_safe ( const lzo_byte *in, lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem /* NOT USED */, + const lzo_byte *dict, lzo_uint dict_len ); + + +/*********************************************************************** +// optimize a compressed data block +************************************************************************/ + +LZO_EXTERN(int) +lzo1x_optimize ( lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem ); + + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + diff --git a/DumpProto/lzo/lzo1x_1.c b/DumpProto/lzo/lzo1x_1.c new file mode 100644 index 0000000..c38edb2 --- /dev/null +++ b/DumpProto/lzo/lzo1x_1.c @@ -0,0 +1,37 @@ +/* lzo1x_1.c -- LZO1X-1 compression + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#define LZO_NEED_DICT_H +#define D_BITS 14 +#define D_INDEX1(d,p) d = DM((0x21*DX3(p,5,5,6)) >> 5) +#define D_INDEX2(d,p) d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f) + +#include "config1x.h" + +#define DO_COMPRESS lzo1x_1_compress + +#include "lzo1x_c.ch" diff --git a/DumpProto/lzo/lzo1x_1k.c b/DumpProto/lzo/lzo1x_1k.c new file mode 100644 index 0000000..c4b7dae --- /dev/null +++ b/DumpProto/lzo/lzo1x_1k.c @@ -0,0 +1,37 @@ +/* lzo1x_1k.c -- LZO1X-1(11) compression (needs only 8kB work memory) + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#define LZO_NEED_DICT_H +#define D_BITS 11 +#define D_INDEX1(d,p) d = DM((0x21*DX2(p,3,5)) >> 5) +#define D_INDEX2(d,p) d = d ^ D_MASK + +#include "config1x.h" + +#define DO_COMPRESS lzo1x_1_11_compress + +#include "lzo1x_c.ch" diff --git a/DumpProto/lzo/lzo1x_1l.c b/DumpProto/lzo/lzo1x_1l.c new file mode 100644 index 0000000..37a15ab --- /dev/null +++ b/DumpProto/lzo/lzo1x_1l.c @@ -0,0 +1,37 @@ +/* lzo1x_1l.c -- LZO1X-1(12) compression + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#define LZO_NEED_DICT_H +#define D_BITS 12 +#define D_INDEX1(d,p) d = DM((0x21*DX2(p,4,5)) >> 5) +#define D_INDEX2(d,p) d = d ^ D_MASK + +#include "config1x.h" + +#define DO_COMPRESS lzo1x_1_12_compress + +#include "lzo1x_c.ch" diff --git a/DumpProto/lzo/lzo1x_1o.c b/DumpProto/lzo/lzo1x_1o.c new file mode 100644 index 0000000..3e0a300 --- /dev/null +++ b/DumpProto/lzo/lzo1x_1o.c @@ -0,0 +1,37 @@ +/* lzo1x_1o.c -- LZO1X-1(15) compression + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#define LZO_NEED_DICT_H +#define D_BITS 15 +#define D_INDEX1(d,p) d = DM((0x21*DX3(p,5,5,6)) >> 5) +#define D_INDEX2(d,p) d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f) + +#include "config1x.h" + +#define DO_COMPRESS lzo1x_1_15_compress + +#include "lzo1x_c.ch" diff --git a/DumpProto/lzo/lzo1x_9x.c b/DumpProto/lzo/lzo1x_9x.c new file mode 100644 index 0000000..9b4b948 --- /dev/null +++ b/DumpProto/lzo/lzo1x_9x.c @@ -0,0 +1,879 @@ +/* lzo1x_9x.c -- implementation of the LZO1X-999 compression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + + +#include +#if !defined(LZO_999_UNSUPPORTED) + +#if !defined(LZO1X) && !defined(LZO1Y) && !defined(LZO1Z) +# define LZO1X +#endif + +#if 0 +#undef LZO_DEBUG +#define LZO_DEBUG +#endif + +#include +#if defined(LZO1X) +# include "config1x.h" +#elif defined(LZO1Y) +# include "config1y.h" +#elif defined(LZO1Z) +# include "config1z.h" +#endif + +#if 0 && !defined(LZO_DEBUG) +#undef NDEBUG +#include +#endif + + +/*********************************************************************** +// +************************************************************************/ + +#define N M4_MAX_OFFSET /* size of ring buffer */ +#define THRESHOLD 1 /* lower limit for match length */ +#define F 2048 /* upper limit for match length */ + +#define SWD_BEST_OFF (LZO_MAX3( M2_MAX_LEN, M3_MAX_LEN, M4_MAX_LEN ) + 1) + +#if defined(LZO1X) +# define LZO_COMPRESS_T lzo1x_999_t +# define lzo_swd_t lzo1x_999_swd_t +#elif defined(LZO1Y) +# define LZO_COMPRESS_T lzo1y_999_t +# define lzo_swd_t lzo1y_999_swd_t +# define lzo1x_999_compress_internal lzo1y_999_compress_internal +# define lzo1x_999_compress_dict lzo1y_999_compress_dict +# define lzo1x_999_compress_level lzo1y_999_compress_level +# define lzo1x_999_compress lzo1y_999_compress +#elif defined(LZO1Z) +# define LZO_COMPRESS_T lzo1z_999_t +# define lzo_swd_t lzo1z_999_swd_t +# define lzo1x_999_compress_internal lzo1z_999_compress_internal +# define lzo1x_999_compress_dict lzo1z_999_compress_dict +# define lzo1x_999_compress_level lzo1z_999_compress_level +# define lzo1x_999_compress lzo1z_999_compress +#endif + +#if 0 +# define HEAD3(b,p) \ + ((((((lzo_uint32)b[p]<<3)^b[p+1])<<3)^b[p+2]) & (SWD_HSIZE-1)) +#endif +#if 0 && defined(LZO_UNALIGNED_OK_4) && (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN) +# define HEAD3(b,p) \ + (((* (lzo_uint32p) &b[p]) ^ ((* (lzo_uint32p) &b[p])>>10)) & (SWD_HSIZE-1)) +#endif + +#include "lzo_mchw.ch" + + +/* this is a public functions, but there is no prototype in a header file */ +LZO_EXTERN(int) +lzo1x_999_compress_internal ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem, + const lzo_byte *dict, lzo_uint dict_len, + lzo_progress_callback_t cb, + int try_lazy, + lzo_uint good_length, + lzo_uint max_lazy, + lzo_uint nice_length, + lzo_uint max_chain, + lzo_uint32 flags ); + + +/*********************************************************************** +// +************************************************************************/ + +static lzo_byte * +code_match ( LZO_COMPRESS_T *c, lzo_byte *op, lzo_uint m_len, lzo_uint m_off ) +{ + lzo_uint x_len = m_len; + lzo_uint x_off = m_off; + + c->match_bytes += m_len; + +#if 0 +/* + static lzo_uint last_m_len = 0, last_m_off = 0; + static lzo_uint prev_m_off[4]; + static int prev_m_off_ptr = 0; + int i; + + //if (m_len >= 3 && m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET) + if (m_len >= 3 && m_len <= M2_MAX_LEN) + { + //if (m_len == last_m_len && m_off == last_m_off) + //printf("last_m_len + last_m_off\n"); + //else + if (m_off == last_m_off) + printf("last_m_off\n"); + else + { + for (i = 0; i < 4; i++) + if (m_off == prev_m_off[i]) + printf("prev_m_off %d: %5ld\n",i,(long)m_off); + } + } + last_m_len = m_len; + last_m_off = prev_m_off[prev_m_off_ptr] = m_off; + prev_m_off_ptr = (prev_m_off_ptr + 1) & 3; +*/ +#endif + + assert(op > c->out); + if (m_len == 2) + { + assert(m_off <= M1_MAX_OFFSET); + assert(c->r1_lit > 0); assert(c->r1_lit < 4); + m_off -= 1; +#if defined(LZO1Z) + *op++ = LZO_BYTE(M1_MARKER | (m_off >> 6)); + *op++ = LZO_BYTE(m_off << 2); +#else + *op++ = LZO_BYTE(M1_MARKER | ((m_off & 3) << 2)); + *op++ = LZO_BYTE(m_off >> 2); +#endif + c->m1a_m++; + } +#if defined(LZO1Z) + else if (m_len <= M2_MAX_LEN && (m_off <= M2_MAX_OFFSET || m_off == c->last_m_off)) +#else + else if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET) +#endif + { + assert(m_len >= 3); +#if defined(LZO1X) + m_off -= 1; + *op++ = LZO_BYTE(((m_len - 1) << 5) | ((m_off & 7) << 2)); + *op++ = LZO_BYTE(m_off >> 3); + assert(op[-2] >= M2_MARKER); +#elif defined(LZO1Y) + m_off -= 1; + *op++ = LZO_BYTE(((m_len + 1) << 4) | ((m_off & 3) << 2)); + *op++ = LZO_BYTE(m_off >> 2); + assert(op[-2] >= M2_MARKER); +#elif defined(LZO1Z) + if (m_off == c->last_m_off) + *op++ = LZO_BYTE(((m_len - 1) << 5) | (0x700 >> 6)); + else + { + m_off -= 1; + *op++ = LZO_BYTE(((m_len - 1) << 5) | (m_off >> 6)); + *op++ = LZO_BYTE(m_off << 2); + } +#endif + c->m2_m++; + } + else if (m_len == M2_MIN_LEN && m_off <= MX_MAX_OFFSET && c->r1_lit >= 4) + { + assert(m_len == 3); + assert(m_off > M2_MAX_OFFSET); + m_off -= 1 + M2_MAX_OFFSET; +#if defined(LZO1Z) + *op++ = LZO_BYTE(M1_MARKER | (m_off >> 6)); + *op++ = LZO_BYTE(m_off << 2); +#else + *op++ = LZO_BYTE(M1_MARKER | ((m_off & 3) << 2)); + *op++ = LZO_BYTE(m_off >> 2); +#endif + c->m1b_m++; + } + else if (m_off <= M3_MAX_OFFSET) + { + assert(m_len >= 3); + m_off -= 1; + if (m_len <= M3_MAX_LEN) + *op++ = LZO_BYTE(M3_MARKER | (m_len - 2)); + else + { + m_len -= M3_MAX_LEN; + *op++ = M3_MARKER | 0; + while (m_len > 255) + { + m_len -= 255; + *op++ = 0; + } + assert(m_len > 0); + *op++ = LZO_BYTE(m_len); + } +#if defined(LZO1Z) + *op++ = LZO_BYTE(m_off >> 6); + *op++ = LZO_BYTE(m_off << 2); +#else + *op++ = LZO_BYTE(m_off << 2); + *op++ = LZO_BYTE(m_off >> 6); +#endif + c->m3_m++; + } + else + { + lzo_uint k; + + assert(m_len >= 3); + assert(m_off > 0x4000); assert(m_off <= 0xbfff); + m_off -= 0x4000; + k = (m_off & 0x4000) >> 11; + if (m_len <= M4_MAX_LEN) + *op++ = LZO_BYTE(M4_MARKER | k | (m_len - 2)); + else + { + m_len -= M4_MAX_LEN; + *op++ = LZO_BYTE(M4_MARKER | k | 0); + while (m_len > 255) + { + m_len -= 255; + *op++ = 0; + } + assert(m_len > 0); + *op++ = LZO_BYTE(m_len); + } +#if defined(LZO1Z) + *op++ = LZO_BYTE(m_off >> 6); + *op++ = LZO_BYTE(m_off << 2); +#else + *op++ = LZO_BYTE(m_off << 2); + *op++ = LZO_BYTE(m_off >> 6); +#endif + c->m4_m++; + } + + c->last_m_len = x_len; + c->last_m_off = x_off; + return op; +} + + +static lzo_byte * +STORE_RUN ( LZO_COMPRESS_T *c, lzo_byte *op, const lzo_byte *ii, lzo_uint t ) +{ + c->lit_bytes += t; + + if (op == c->out && t <= 238) + { + *op++ = LZO_BYTE(17 + t); + } + else if (t <= 3) + { +#if defined(LZO1Z) + op[-1] |= LZO_BYTE(t); +#else + op[-2] |= LZO_BYTE(t); +#endif + c->lit1_r++; + } + else if (t <= 18) + { + *op++ = LZO_BYTE(t - 3); + c->lit2_r++; + } + else + { + lzo_uint tt = t - 18; + + *op++ = 0; + while (tt > 255) + { + tt -= 255; + *op++ = 0; + } + assert(tt > 0); + *op++ = LZO_BYTE(tt); + c->lit3_r++; + } + do *op++ = *ii++; while (--t > 0); + + return op; +} + + +static lzo_byte * +code_run ( LZO_COMPRESS_T *c, lzo_byte *op, const lzo_byte *ii, + lzo_uint lit, lzo_uint m_len ) +{ + if (lit > 0) + { + assert(m_len >= 2); + op = STORE_RUN(c,op,ii,lit); + c->r1_m_len = m_len; + c->r1_lit = lit; + } + else + { + assert(m_len >= 3); + c->r1_m_len = 0; + c->r1_lit = 0; + } + + return op; +} + + +/*********************************************************************** +// +************************************************************************/ + +static int +len_of_coded_match ( lzo_uint m_len, lzo_uint m_off, lzo_uint lit ) +{ + int n = 4; + + if (m_len < 2) + return -1; + if (m_len == 2) + return (m_off <= M1_MAX_OFFSET && lit > 0 && lit < 4) ? 2 : -1; + if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET) + return 2; + if (m_len == M2_MIN_LEN && m_off <= MX_MAX_OFFSET && lit >= 4) + return 2; + if (m_off <= M3_MAX_OFFSET) + { + if (m_len <= M3_MAX_LEN) + return 3; + m_len -= M3_MAX_LEN; + while (m_len > 255) + { + m_len -= 255; + n++; + } + return n; + } + if (m_off <= M4_MAX_OFFSET) + { + if (m_len <= M4_MAX_LEN) + return 3; + m_len -= M4_MAX_LEN; + while (m_len > 255) + { + m_len -= 255; + n++; + } + return n; + } + return -1; +} + + +static lzo_int +min_gain(lzo_uint ahead, lzo_uint lit1, lzo_uint lit2, int l1, int l2, int l3) +{ + lzo_int lazy_match_min_gain = 0; + + assert (ahead >= 1); + lazy_match_min_gain += ahead; + +#if 0 + if (l3 > 0) + lit2 -= ahead; +#endif + + if (lit1 <= 3) + lazy_match_min_gain += (lit2 <= 3) ? 0 : 2; + else if (lit1 <= 18) + lazy_match_min_gain += (lit2 <= 18) ? 0 : 1; + + lazy_match_min_gain += (l2 - l1) * 2; + if (l3 > 0) + lazy_match_min_gain -= (ahead - l3) * 2; + + if (lazy_match_min_gain < 0) + lazy_match_min_gain = 0; + +#if 0 + if (l1 == 2) + if (lazy_match_min_gain == 0) + lazy_match_min_gain = 1; +#endif + + return lazy_match_min_gain; +} + + +/*********************************************************************** +// +************************************************************************/ + +#if !defined(NDEBUG) +static +void assert_match( const lzo_swd_t *swd, lzo_uint m_len, lzo_uint m_off ) +{ + const LZO_COMPRESS_T *c = swd->c; + lzo_uint d_off; + + assert(m_len >= 2); + if (m_off <= (lzo_uint) (c->bp - c->in)) + { + assert(c->bp - m_off + m_len < c->ip); + assert(lzo_memcmp(c->bp, c->bp - m_off, m_len) == 0); + } + else + { + assert(swd->dict != NULL); + d_off = m_off - (lzo_uint) (c->bp - c->in); + assert(d_off <= swd->dict_len); + if (m_len > d_off) + { + assert(lzo_memcmp(c->bp, swd->dict_end - d_off, d_off) == 0); + assert(c->in + m_len - d_off < c->ip); + assert(lzo_memcmp(c->bp + d_off, c->in, m_len - d_off) == 0); + } + else + { + assert(lzo_memcmp(c->bp, swd->dict_end - d_off, m_len) == 0); + } + } +} +#else +# define assert_match(a,b,c) ((void)0) +#endif + + +#if defined(SWD_BEST_OFF) + +static void +better_match ( const lzo_swd_t *swd, lzo_uint *m_len, lzo_uint *m_off ) +{ +#if defined(LZO1Z) + const LZO_COMPRESS_T *c = swd->c; +#endif + + if (*m_len <= M2_MIN_LEN) + return; +#if defined(LZO1Z) + if (*m_off == c->last_m_off && *m_len <= M2_MAX_LEN) + return; +#if 1 + if (*m_len >= M2_MIN_LEN + 1 && *m_len <= M2_MAX_LEN + 1 && + c->last_m_off && swd->best_off[*m_len-1] == c->last_m_off) + { + *m_len = *m_len - 1; + *m_off = swd->best_off[*m_len]; + return; + } +#endif +#endif + + if (*m_off <= M2_MAX_OFFSET) + return; + +#if 1 + /* M3/M4 -> M2 */ + if (*m_off > M2_MAX_OFFSET && + *m_len >= M2_MIN_LEN + 1 && *m_len <= M2_MAX_LEN + 1 && + swd->best_off[*m_len-1] && swd->best_off[*m_len-1] <= M2_MAX_OFFSET) + { + *m_len = *m_len - 1; + *m_off = swd->best_off[*m_len]; + return; + } +#endif + +#if 1 + /* M4 -> M2 */ + if (*m_off > M3_MAX_OFFSET && + *m_len >= M4_MAX_LEN + 1 && *m_len <= M2_MAX_LEN + 2 && + swd->best_off[*m_len-2] && swd->best_off[*m_len-2] <= M2_MAX_OFFSET) + { + *m_len = *m_len - 2; + *m_off = swd->best_off[*m_len]; + return; + } +#endif + +#if 1 + /* M4 -> M3 */ + if (*m_off > M3_MAX_OFFSET && + *m_len >= M4_MAX_LEN + 1 && *m_len <= M3_MAX_LEN + 1 && + swd->best_off[*m_len-1] && swd->best_off[*m_len-1] <= M3_MAX_OFFSET) + { + *m_len = *m_len - 1; + *m_off = swd->best_off[*m_len]; + } +#endif +} + +#endif + + +/*********************************************************************** +// +************************************************************************/ + +LZO_PUBLIC(int) +lzo1x_999_compress_internal ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem, + const lzo_byte *dict, lzo_uint dict_len, + lzo_progress_callback_t cb, + int try_lazy, + lzo_uint good_length, + lzo_uint max_lazy, + lzo_uint nice_length, + lzo_uint max_chain, + lzo_uint32 flags ) +{ + lzo_byte *op; + const lzo_byte *ii; + lzo_uint lit; + lzo_uint m_len, m_off; + LZO_COMPRESS_T cc; + LZO_COMPRESS_T * const c = &cc; + lzo_swd_t * const swd = (lzo_swd_t *) wrkmem; + int r; + +#if defined(__LZO_QUERY_COMPRESS) + if (__LZO_IS_COMPRESS_QUERY(in,in_len,out,out_len,wrkmem)) + return __LZO_QUERY_COMPRESS(in,in_len,out,out_len,wrkmem,1,lzo_sizeof(lzo_swd_t)); +#endif + + /* sanity check */ + if (!lzo_assert(LZO1X_999_MEM_COMPRESS >= lzo_sizeof(lzo_swd_t))) + return LZO_E_ERROR; + +/* setup parameter defaults */ + /* number of lazy match tries */ + if (try_lazy < 0) + try_lazy = 1; + /* reduce lazy match search if we already have a match with this length */ + if (good_length <= 0) + good_length = 32; + /* do not try a lazy match if we already have a match with this length */ + if (max_lazy <= 0) + max_lazy = 32; + /* stop searching for longer matches than this one */ + if (nice_length <= 0) + nice_length = 0; + /* don't search more positions than this */ + if (max_chain <= 0) + max_chain = SWD_MAX_CHAIN; + + c->init = 0; + c->ip = c->in = in; + c->in_end = in + in_len; + c->out = out; + c->cb = cb; + c->m1a_m = c->m1b_m = c->m2_m = c->m3_m = c->m4_m = 0; + c->lit1_r = c->lit2_r = c->lit3_r = 0; + + op = out; + ii = c->ip; /* point to start of literal run */ + lit = 0; + c->r1_lit = c->r1_m_len = 0; + + r = init_match(c,swd,dict,dict_len,flags); + if (r != 0) + return r; + if (max_chain > 0) + swd->max_chain = max_chain; + if (nice_length > 0) + swd->nice_length = nice_length; + + r = find_match(c,swd,0,0); + if (r != 0) + return r; + while (c->look > 0) + { + lzo_uint ahead; + lzo_uint max_ahead; + int l1, l2, l3; + + c->codesize = op - out; + + m_len = c->m_len; + m_off = c->m_off; + + assert(c->bp == c->ip - c->look); + assert(c->bp >= in); + if (lit == 0) + ii = c->bp; + assert(ii + lit == c->bp); + assert(swd->b_char == *(c->bp)); + + if ( m_len < 2 || + (m_len == 2 && (m_off > M1_MAX_OFFSET || lit == 0 || lit >= 4)) || +#if 1 + /* Do not accept this match for compressed-data compatibility + * with LZO v1.01 and before + * [ might be a problem for decompress() and optimize() ] + */ + (m_len == 2 && op == out) || +#endif + (op == out && lit == 0)) + { + /* a literal */ + m_len = 0; + } + else if (m_len == M2_MIN_LEN) + { + /* compression ratio improves if we code a literal in some cases */ + if (m_off > MX_MAX_OFFSET && lit >= 4) + m_len = 0; + } + + if (m_len == 0) + { + /* a literal */ + lit++; + swd->max_chain = max_chain; + r = find_match(c,swd,1,0); + assert(r == 0); + continue; + } + + /* a match */ +#if defined(SWD_BEST_OFF) + if (swd->use_best_off) + better_match(swd,&m_len,&m_off); +#endif + assert_match(swd,m_len,m_off); + + + + /* shall we try a lazy match ? */ + ahead = 0; + if (try_lazy <= 0 || m_len >= max_lazy) + { + /* no */ + l1 = 0; + max_ahead = 0; + } + else + { + /* yes, try a lazy match */ + l1 = len_of_coded_match(m_len,m_off,lit); + assert(l1 > 0); +#if 1 + max_ahead = LZO_MIN(try_lazy, l1 - 1); +#else + max_ahead = LZO_MIN3(try_lazy, l1, m_len - 1); +#endif + } + + + while (ahead < max_ahead && c->look > m_len) + { + lzo_int lazy_match_min_gain; + + if (m_len >= good_length) + swd->max_chain = max_chain >> 2; + else + swd->max_chain = max_chain; + r = find_match(c,swd,1,0); + ahead++; + + assert(r == 0); + assert(c->look > 0); + assert(ii + lit + ahead == c->bp); + +#if defined(LZO1Z) + if (m_off == c->last_m_off && c->m_off != c->last_m_off) + if (m_len >= M2_MIN_LEN && m_len <= M2_MAX_LEN) + c->m_len = 0; +#endif + if (c->m_len < m_len) + continue; +#if 1 + if (c->m_len == m_len && c->m_off >= m_off) + continue; +#endif +#if defined(SWD_BEST_OFF) + if (swd->use_best_off) + better_match(swd,&c->m_len,&c->m_off); +#endif + l2 = len_of_coded_match(c->m_len,c->m_off,lit+ahead); + if (l2 < 0) + continue; +#if 0 + if (c->m_len == m_len && l2 >= l1) + continue; +#endif + + +#if 1 + /* compressed-data compatibility [see above] */ + l3 = (op == out) ? -1 : len_of_coded_match(ahead,m_off,lit); +#else + l3 = len_of_coded_match(ahead,m_off,lit); +#endif + + lazy_match_min_gain = min_gain(ahead,lit,lit+ahead,l1,l2,l3); + if (c->m_len >= m_len + lazy_match_min_gain) + { + c->lazy++; + assert_match(swd,c->m_len,c->m_off); + + if (l3 > 0) + { + /* code previous run */ + op = code_run(c,op,ii,lit,ahead); + lit = 0; + /* code shortened match */ + op = code_match(c,op,ahead,m_off); + } + else + { + lit += ahead; + assert(ii + lit == c->bp); + } + goto lazy_match_done; + } + } + + + assert(ii + lit + ahead == c->bp); + + /* 1 - code run */ + op = code_run(c,op,ii,lit,m_len); + lit = 0; + + /* 2 - code match */ + op = code_match(c,op,m_len,m_off); + swd->max_chain = max_chain; + r = find_match(c,swd,m_len,1+ahead); + assert(r == 0); + +lazy_match_done: ; + } + + + /* store final run */ + if (lit > 0) + op = STORE_RUN(c,op,ii,lit); + +#if defined(LZO_EOF_CODE) + *op++ = M4_MARKER | 1; + *op++ = 0; + *op++ = 0; +#endif + + c->codesize = op - out; + assert(c->textsize == in_len); + + *out_len = op - out; + + if (c->cb) + (*c->cb)(c->textsize,c->codesize); + +#if 0 + printf("%ld %ld -> %ld %ld: %ld %ld %ld %ld %ld %ld: %ld %ld %ld %ld\n", + (long) c->textsize, (long) in_len, (long) c->codesize, + c->match_bytes, c->m1a_m, c->m1b_m, c->m2_m, c->m3_m, c->m4_m, + c->lit_bytes, c->lit1_r, c->lit2_r, c->lit3_r, c->lazy); +#endif + assert(c->lit_bytes + c->match_bytes == in_len); + + return LZO_E_OK; +} + + +/*********************************************************************** +// +************************************************************************/ + +LZO_PUBLIC(int) +lzo1x_999_compress_level ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem, + const lzo_byte *dict, lzo_uint dict_len, + lzo_progress_callback_t cb, + int compression_level ) +{ + static const struct + { + int try_lazy; + lzo_uint good_length; + lzo_uint max_lazy; + lzo_uint nice_length; + lzo_uint max_chain; + lzo_uint32 flags; + } c[9] = { + { 0, 0, 0, 8, 4, 0 }, /* faster compression */ + { 0, 0, 0, 16, 8, 0 }, + { 0, 0, 0, 32, 16, 0 }, + + { 1, 4, 4, 16, 16, 0 }, + { 1, 8, 16, 32, 32, 0 }, + { 1, 8, 16, 128, 128, 0 }, + + { 2, 8, 32, 128, 256, 0 }, + { 2, 32, 128, F, 2048, 1 }, + { 2, F, F, F, 4096, 1 } /* max. compression */ + }; + + if (compression_level < 1 || compression_level > 9) + return LZO_E_ERROR; + + compression_level -= 1; + return lzo1x_999_compress_internal(in, in_len, out, out_len, wrkmem, + dict, dict_len, cb, + c[compression_level].try_lazy, + c[compression_level].good_length, + c[compression_level].max_lazy, +#if 0 + c[compression_level].nice_length, +#else + 0, +#endif + c[compression_level].max_chain, + c[compression_level].flags); +} + + +/*********************************************************************** +// +************************************************************************/ + +LZO_PUBLIC(int) +lzo1x_999_compress_dict ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem, + const lzo_byte *dict, lzo_uint dict_len ) +{ + return lzo1x_999_compress_level(in, in_len, out, out_len, wrkmem, + dict, dict_len, 0, 8); +} + +LZO_PUBLIC(int) +lzo1x_999_compress ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ + return lzo1x_999_compress_level(in, in_len, out, out_len, wrkmem, + NULL, 0, 0, 8); +} + + +#endif /* !defined(LZO_999_UNSUPPORTED) */ + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/lzo1x_c.ch b/DumpProto/lzo/lzo1x_c.ch new file mode 100644 index 0000000..38e6442 --- /dev/null +++ b/DumpProto/lzo/lzo1x_c.ch @@ -0,0 +1,351 @@ +/* lzo1x_c.ch -- implementation of the LZO1[XY]-1 compression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + + +/*********************************************************************** +// compress a block of data. +************************************************************************/ + +static +lzo_uint do_compress ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ +#if 0 && defined(__GNUC__) && defined(__i386__) + register const lzo_byte *ip __asm__("%esi"); +#else + register const lzo_byte *ip; +#endif + lzo_byte *op; + const lzo_byte * const in_end = in + in_len; + const lzo_byte * const ip_end = in + in_len - M2_MAX_LEN - 5; + const lzo_byte *ii; + lzo_dict_p const dict = (lzo_dict_p) wrkmem; + + op = out; + ip = in; + ii = ip; + + ip += 4; + for (;;) + { +#if 0 && defined(__GNUC__) && defined(__i386__) + register const lzo_byte *m_pos __asm__("%edi"); +#else + register const lzo_byte *m_pos; +#endif + lzo_moff_t m_off; + lzo_uint m_len; + lzo_uint dindex; + + DINDEX1(dindex,ip); + GINDEX(m_pos,m_off,dict,dindex,in); + if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET)) + goto literal; +#if 1 + if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) + goto try_match; + DINDEX2(dindex,ip); +#endif + GINDEX(m_pos,m_off,dict,dindex,in); + if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET)) + goto literal; + if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) + goto try_match; + goto literal; + + +try_match: +#if 1 && defined(LZO_UNALIGNED_OK_2) + if (* (const lzo_ushortp) m_pos != * (const lzo_ushortp) ip) +#else + if (m_pos[0] != ip[0] || m_pos[1] != ip[1]) +#endif + { + } + else + { + if (m_pos[2] == ip[2]) + { +#if 0 + if (m_off <= M2_MAX_OFFSET) + goto match; + if (lit <= 3) + goto match; + if (lit == 3) /* better compression, but slower */ + { + assert(op - 2 > out); op[-2] |= LZO_BYTE(3); + *op++ = *ii++; *op++ = *ii++; *op++ = *ii++; + goto code_match; + } + if (m_pos[3] == ip[3]) +#endif + goto match; + } + else + { + /* still need a better way for finding M1 matches */ +#if 0 + /* a M1 match */ +#if 0 + if (m_off <= M1_MAX_OFFSET && lit > 0 && lit <= 3) +#else + if (m_off <= M1_MAX_OFFSET && lit == 3) +#endif + { + register lzo_uint t; + + t = lit; + assert(op - 2 > out); op[-2] |= LZO_BYTE(t); + do *op++ = *ii++; while (--t > 0); + assert(ii == ip); + m_off -= 1; + *op++ = LZO_BYTE(M1_MARKER | ((m_off & 3) << 2)); + *op++ = LZO_BYTE(m_off >> 2); + ip += 2; + goto match_done; + } +#endif + } + } + + + /* a literal */ +literal: + UPDATE_I(dict,0,dindex,ip,in); + ++ip; + if (ip >= ip_end) + break; + continue; + + + /* a match */ +match: + UPDATE_I(dict,0,dindex,ip,in); + /* store current literal run */ + if (pd(ip,ii) > 0) + { + register lzo_uint t = pd(ip,ii); + + if (t <= 3) + { + assert(op - 2 > out); + op[-2] |= LZO_BYTE(t); + } + else if (t <= 18) + *op++ = LZO_BYTE(t - 3); + else + { + register lzo_uint tt = t - 18; + + *op++ = 0; + while (tt > 255) + { + tt -= 255; + *op++ = 0; + } + assert(tt > 0); + *op++ = LZO_BYTE(tt); + } + do *op++ = *ii++; while (--t > 0); + } + + /* code the match */ + assert(ii == ip); + ip += 3; + if (m_pos[3] != *ip++ || m_pos[4] != *ip++ || m_pos[5] != *ip++ || + m_pos[6] != *ip++ || m_pos[7] != *ip++ || m_pos[8] != *ip++ +#ifdef LZO1Y + || m_pos[ 9] != *ip++ || m_pos[10] != *ip++ || m_pos[11] != *ip++ + || m_pos[12] != *ip++ || m_pos[13] != *ip++ || m_pos[14] != *ip++ +#endif + ) + { + --ip; + m_len = ip - ii; + assert(m_len >= 3); assert(m_len <= M2_MAX_LEN); + + if (m_off <= M2_MAX_OFFSET) + { + m_off -= 1; +#if defined(LZO1X) + *op++ = LZO_BYTE(((m_len - 1) << 5) | ((m_off & 7) << 2)); + *op++ = LZO_BYTE(m_off >> 3); +#elif defined(LZO1Y) + *op++ = LZO_BYTE(((m_len + 1) << 4) | ((m_off & 3) << 2)); + *op++ = LZO_BYTE(m_off >> 2); +#endif + } + else if (m_off <= M3_MAX_OFFSET) + { + m_off -= 1; + *op++ = LZO_BYTE(M3_MARKER | (m_len - 2)); + goto m3_m4_offset; + } + else +#if defined(LZO1X) + { + m_off -= 0x4000; + assert(m_off > 0); assert(m_off <= 0x7fff); + *op++ = LZO_BYTE(M4_MARKER | + ((m_off & 0x4000) >> 11) | (m_len - 2)); + goto m3_m4_offset; + } +#elif defined(LZO1Y) + goto m4_match; +#endif + } + else + { + { + const lzo_byte *end = in_end; + const lzo_byte *m = m_pos + M2_MAX_LEN + 1; + while (ip < end && *m == *ip) + m++, ip++; + m_len = (ip - ii); + } + assert(m_len > M2_MAX_LEN); + + if (m_off <= M3_MAX_OFFSET) + { + m_off -= 1; + if (m_len <= 33) + *op++ = LZO_BYTE(M3_MARKER | (m_len - 2)); + else + { + m_len -= 33; + *op++ = M3_MARKER | 0; + goto m3_m4_len; + } + } + else + { +#if defined(LZO1Y) +m4_match: +#endif + m_off -= 0x4000; + assert(m_off > 0); assert(m_off <= 0x7fff); + if (m_len <= M4_MAX_LEN) + *op++ = LZO_BYTE(M4_MARKER | + ((m_off & 0x4000) >> 11) | (m_len - 2)); + else + { + m_len -= M4_MAX_LEN; + *op++ = LZO_BYTE(M4_MARKER | ((m_off & 0x4000) >> 11)); +m3_m4_len: + while (m_len > 255) + { + m_len -= 255; + *op++ = 0; + } + assert(m_len > 0); + *op++ = LZO_BYTE(m_len); + } + } + +m3_m4_offset: + *op++ = LZO_BYTE((m_off & 63) << 2); + *op++ = LZO_BYTE(m_off >> 6); + } + +#if 0 +match_done: +#endif + ii = ip; + if (ip >= ip_end) + break; + } + + *out_len = op - out; + return pd(in_end,ii); +} + + +/*********************************************************************** +// public entry point +************************************************************************/ + +LZO_PUBLIC(int) +DO_COMPRESS ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ + lzo_byte *op = out; + lzo_uint t; + +#if defined(__LZO_QUERY_COMPRESS) + if (__LZO_IS_COMPRESS_QUERY(in,in_len,out,out_len,wrkmem)) + return __LZO_QUERY_COMPRESS(in,in_len,out,out_len,wrkmem,D_SIZE,lzo_sizeof(lzo_dict_t)); +#endif + + if (in_len <= M2_MAX_LEN + 5) + t = in_len; + else + { + t = do_compress(in,in_len,op,out_len,wrkmem); + op += *out_len; + } + + if (t > 0) + { + const lzo_byte *ii = in + in_len - t; + + if (op == out && t <= 238) + *op++ = LZO_BYTE(17 + t); + else if (t <= 3) + op[-2] |= LZO_BYTE(t); + else if (t <= 18) + *op++ = LZO_BYTE(t - 3); + else + { + lzo_uint tt = t - 18; + + *op++ = 0; + while (tt > 255) + { + tt -= 255; + *op++ = 0; + } + assert(tt > 0); + *op++ = LZO_BYTE(tt); + } + do *op++ = *ii++; while (--t > 0); + } + + *op++ = M4_MARKER | 1; + *op++ = 0; + *op++ = 0; + + *out_len = op - out; + return LZO_E_OK; +} + + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/lzo1x_d.ch b/DumpProto/lzo/lzo1x_d.ch new file mode 100644 index 0000000..d617935 --- /dev/null +++ b/DumpProto/lzo/lzo1x_d.ch @@ -0,0 +1,454 @@ +/* lzo1x_d.ch -- implementation of the LZO1X decompression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "lzo1_d.ch" + + +#undef __COPY4 +#define __COPY4(dst,src) * (lzo_uint32p)(dst) = * (const lzo_uint32p)(src) + +#undef COPY4 +#if defined(LZO_UNALIGNED_OK_4) +# define COPY4(dst,src) __COPY4(dst,src) +#elif defined(LZO_ALIGNED_OK_4) +# define COPY4(dst,src) __COPY4((lzo_ptr_t)(dst),(lzo_ptr_t)(src)) +#endif + + +/*********************************************************************** +// decompress a block of data. +************************************************************************/ + +#if defined(DO_DECOMPRESS) +LZO_PUBLIC(int) +DO_DECOMPRESS ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem ) +#endif +{ + register lzo_byte *op; + register const lzo_byte *ip; + register lzo_uint t; +#if defined(COPY_DICT) + lzo_uint m_off; + const lzo_byte *dict_end; +#else + register const lzo_byte *m_pos; +#endif + + const lzo_byte * const ip_end = in + in_len; +#if defined(HAVE_ANY_OP) + lzo_byte * const op_end = out + *out_len; +#endif +#if defined(LZO1Z) + lzo_uint last_m_off = 0; +#endif + + LZO_UNUSED(wrkmem); + +#if defined(__LZO_QUERY_DECOMPRESS) + if (__LZO_IS_DECOMPRESS_QUERY(in,in_len,out,out_len,wrkmem)) + return __LZO_QUERY_DECOMPRESS(in,in_len,out,out_len,wrkmem,0,0); +#endif + +#if defined(COPY_DICT) + if (dict) + { + if (dict_len > M4_MAX_OFFSET) + { + dict += dict_len - M4_MAX_OFFSET; + dict_len = M4_MAX_OFFSET; + } + dict_end = dict + dict_len; + } + else + { + dict_len = 0; + dict_end = NULL; + } +#endif /* COPY_DICT */ + + *out_len = 0; + + op = out; + ip = in; + + if (*ip > 17) + { + t = *ip++ - 17; + if (t < 4) + goto match_next; + assert(t > 0); NEED_OP(t); NEED_IP(t+1); + do *op++ = *ip++; while (--t > 0); + goto first_literal_run; + } + + while (TEST_IP && TEST_OP) + { + t = *ip++; + if (t >= 16) + goto match; + /* a literal run */ + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 15 + *ip++; + } + /* copy literals */ + assert(t > 0); NEED_OP(t+3); NEED_IP(t+4); +#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) +#if !defined(LZO_UNALIGNED_OK_4) + if (PTR_ALIGNED2_4(op,ip)) + { +#endif + COPY4(op,ip); + op += 4; ip += 4; + if (--t > 0) + { + if (t >= 4) + { + do { + COPY4(op,ip); + op += 4; ip += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *ip++; while (--t > 0); + } + else + do *op++ = *ip++; while (--t > 0); + } +#if !defined(LZO_UNALIGNED_OK_4) + } + else +#endif +#endif +#if !defined(LZO_UNALIGNED_OK_4) + { + *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; + do *op++ = *ip++; while (--t > 0); + } +#endif + + +first_literal_run: + + + t = *ip++; + if (t >= 16) + goto match; +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(3); + t = 3; COPY_DICT(t,m_off) +#else /* !COPY_DICT */ +#if defined(LZO1Z) + t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - (1 + M2_MAX_OFFSET); + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LOOKBEHIND(m_pos,out); NEED_OP(3); + *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; +#endif /* COPY_DICT */ + goto match_done; + + + /* handle matches */ + while (TEST_IP && TEST_OP) + { +match: + if (t >= 64) /* a M2 match */ + { +#if defined(COPY_DICT) +#if defined(LZO1X) + m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); + t = (t >> 4) - 3; +#elif defined(LZO1Z) + m_off = t & 0x1f; + if (m_off >= 0x1c) + m_off = last_m_off; + else + { + m_off = 1 + (m_off << 6) + (*ip++ >> 2); + last_m_off = m_off; + } + t = (t >> 5) - 1; +#endif +#else /* !COPY_DICT */ +#if defined(LZO1X) + m_pos = op - 1; + m_pos -= (t >> 2) & 7; + m_pos -= *ip++ << 3; + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_pos = op - 1; + m_pos -= (t >> 2) & 3; + m_pos -= *ip++ << 2; + t = (t >> 4) - 3; +#elif defined(LZO1Z) + { + lzo_uint off = t & 0x1f; + m_pos = op; + if (off >= 0x1c) + { + assert(last_m_off > 0); + m_pos -= last_m_off; + } + else + { + off = 1 + (off << 6) + (*ip++ >> 2); + m_pos -= off; + last_m_off = off; + } + } + t = (t >> 5) - 1; +#endif + TEST_LOOKBEHIND(m_pos,out); assert(t > 0); NEED_OP(t+3-1); + goto copy_match; +#endif /* COPY_DICT */ + } + else if (t >= 32) /* a M3 match */ + { + t &= 31; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 31 + *ip++; + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); + last_m_off = m_off; +#else + m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); +#endif +#else /* !COPY_DICT */ +#if defined(LZO1Z) + { + lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); + m_pos = op - off; + last_m_off = off; + } +#elif defined(LZO_UNALIGNED_OK_2) && (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN) + m_pos = op - 1; + m_pos -= (* (const lzo_ushortp) ip) >> 2; +#else + m_pos = op - 1; + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif +#endif /* COPY_DICT */ + ip += 2; + } + else if (t >= 16) /* a M4 match */ + { +#if defined(COPY_DICT) + m_off = (t & 8) << 11; +#else /* !COPY_DICT */ + m_pos = op; + m_pos -= (t & 8) << 11; +#endif /* COPY_DICT */ + t &= 7; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 7 + *ip++; + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off += (ip[0] << 6) + (ip[1] >> 2); +#else + m_off += (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_off == 0) + goto eof_found; + m_off += 0x4000; +#if defined(LZO1Z) + last_m_off = m_off; +#endif +#else /* !COPY_DICT */ +#if defined(LZO1Z) + m_pos -= (ip[0] << 6) + (ip[1] >> 2); +#elif defined(LZO_UNALIGNED_OK_2) && (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN) + m_pos -= (* (const lzo_ushortp) ip) >> 2; +#else + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_pos == op) + goto eof_found; + m_pos -= 0x4000; +#if defined(LZO1Z) + last_m_off = op - m_pos; +#endif +#endif /* COPY_DICT */ + } + else /* a M1 match */ + { +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = 1 + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(2); + t = 2; COPY_DICT(t,m_off) +#else /* !COPY_DICT */ +#if defined(LZO1Z) + t = 1 + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - 1; + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LOOKBEHIND(m_pos,out); NEED_OP(2); + *op++ = *m_pos++; *op++ = *m_pos; +#endif /* COPY_DICT */ + goto match_done; + } + + /* copy match */ +#if defined(COPY_DICT) + + NEED_OP(t+3-1); + t += 3-1; COPY_DICT(t,m_off) + +#else /* !COPY_DICT */ + + TEST_LOOKBEHIND(m_pos,out); assert(t > 0); NEED_OP(t+3-1); +#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) +#if !defined(LZO_UNALIGNED_OK_4) + if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) + { + assert((op - m_pos) >= 4); /* both pointers are aligned */ +#else + if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) + { +#endif + COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4 - (3 - 1); + do { + COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *m_pos++; while (--t > 0); + } + else +#endif + { +copy_match: + *op++ = *m_pos++; *op++ = *m_pos++; + do *op++ = *m_pos++; while (--t > 0); + } + +#endif /* COPY_DICT */ + +match_done: +#if defined(LZO1Z) + t = ip[-1] & 3; +#else + t = ip[-2] & 3; +#endif + if (t == 0) + break; + + /* copy literals */ +match_next: + assert(t > 0); NEED_OP(t); NEED_IP(t+1); + do *op++ = *ip++; while (--t > 0); + t = *ip++; + } + } + +#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP) + /* no EOF code was found */ + *out_len = op - out; + return LZO_E_EOF_NOT_FOUND; +#endif + +eof_found: + assert(t == 1); + *out_len = op - out; + return (ip == ip_end ? LZO_E_OK : + (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); + + +#if defined(HAVE_NEED_IP) +input_overrun: + *out_len = op - out; + return LZO_E_INPUT_OVERRUN; +#endif + +#if defined(HAVE_NEED_OP) +output_overrun: + *out_len = op - out; + return LZO_E_OUTPUT_OVERRUN; +#endif + +#if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND) +lookbehind_overrun: + *out_len = op - out; + return LZO_E_LOOKBEHIND_OVERRUN; +#endif +} + + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/lzo1x_d1.c b/DumpProto/lzo/lzo1x_d1.c new file mode 100644 index 0000000..346b98b --- /dev/null +++ b/DumpProto/lzo/lzo1x_d1.c @@ -0,0 +1,33 @@ +/* lzo1x_d1.c -- LZO1X decompression + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "config1x.h" + +#undef LZO_TEST_DECOMPRESS_OVERRUN +#define DO_DECOMPRESS lzo1x_decompress + +#include "lzo1x_d.ch" diff --git a/DumpProto/lzo/lzo1x_d2.c b/DumpProto/lzo/lzo1x_d2.c new file mode 100644 index 0000000..05fb459 --- /dev/null +++ b/DumpProto/lzo/lzo1x_d2.c @@ -0,0 +1,33 @@ +/* lzo1x_d2.c -- LZO1X decompression with overrun testing + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "config1x.h" + +#define LZO_TEST_DECOMPRESS_OVERRUN +#define DO_DECOMPRESS lzo1x_decompress_safe + +#include "lzo1x_d.ch" diff --git a/DumpProto/lzo/lzo1x_d3.c b/DumpProto/lzo/lzo1x_d3.c new file mode 100644 index 0000000..af29a89 --- /dev/null +++ b/DumpProto/lzo/lzo1x_d3.c @@ -0,0 +1,108 @@ +/* lzo1x_d3.c -- LZO1X decompression with preset dictionary + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "config1x.h" + +#if 0 +#undef NDEBUG +#include +#endif + +#define LZO_TEST_DECOMPRESS_OVERRUN + +#if 0 && defined(__linux__) +# include +#endif + + +#define SLOW_MEMCPY(a,b,l) { do *a++ = *b++; while (--l > 0); } +#if 1 && defined(HAVE_MEMCPY) +# if !defined(__LZO_DOS16) && !defined(__LZO_WIN16) +# define FAST_MEMCPY(a,b,l) { memcpy(a,b,l); a += l; } +# endif +#endif + +#if 1 && defined(FAST_MEMCPY) +# define DICT_MEMMOVE(op,m_pos,m_len,m_off) \ + if (m_off >= (m_len)) \ + FAST_MEMCPY(op,m_pos,m_len) \ + else \ + SLOW_MEMCPY(op,m_pos,m_len) +#else +# define DICT_MEMMOVE(op,m_pos,m_len,m_off) \ + SLOW_MEMCPY(op,m_pos,m_len) +#endif + +#if !defined(FAST_MEMCPY) +# define FAST_MEMCPY SLOW_MEMCPY +#endif + + +#define COPY_DICT_DICT(m_len,m_off) \ + { \ + register const lzo_byte *m_pos; \ + m_off -= (lzo_moff_t) (op - out); assert(m_off > 0); \ + if (m_off > dict_len) goto lookbehind_overrun; \ + m_pos = dict_end - m_off; \ + if (m_len > m_off) \ + { \ + m_len -= m_off; \ + FAST_MEMCPY(op,m_pos,m_off) \ + m_pos = out; \ + SLOW_MEMCPY(op,m_pos,m_len) \ + } \ + else \ + FAST_MEMCPY(op,m_pos,m_len) \ + } + +#define COPY_DICT(m_len,m_off) \ + assert(m_len >= 2); assert(m_off > 0); assert(op > out); \ + if (m_off <= (lzo_moff_t) (op - out)) \ + { \ + register const lzo_byte *m_pos = op - m_off; \ + DICT_MEMMOVE(op,m_pos,m_len,m_off) \ + } \ + else \ + COPY_DICT_DICT(m_len,m_off) + + + + +LZO_PUBLIC(int) +lzo1x_decompress_dict_safe ( const lzo_byte *in, lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem /* NOT USED */, + const lzo_byte *dict, lzo_uint dict_len) + + +#include "lzo1x_d.ch" + + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/lzo1x_o.c b/DumpProto/lzo/lzo1x_o.c new file mode 100644 index 0000000..8199012 --- /dev/null +++ b/DumpProto/lzo/lzo1x_o.c @@ -0,0 +1,32 @@ +/* lzo1x_o.c -- LZO1X compressed data optimizer + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "config1x.h" + +#define DO_OPTIMIZE lzo1x_optimize + +#include "lzo1x_oo.ch" diff --git a/DumpProto/lzo/lzo1x_oo.ch b/DumpProto/lzo/lzo1x_oo.ch new file mode 100644 index 0000000..ddd7322 --- /dev/null +++ b/DumpProto/lzo/lzo1x_oo.ch @@ -0,0 +1,363 @@ +/* lzo1x_oo.ch -- LZO1X compressed data optimizer + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include +#if 0 +#undef NDEBUG +#include +#endif + +#define TEST_IP (ip < ip_end) +#define TEST_OP (op <= op_end) + +#define NO_LIT LZO_UINT_MAX + + +/*********************************************************************** +// +************************************************************************/ + +static void copy2(lzo_byte *ip, const lzo_byte *m_pos, lzo_ptrdiff_t off) +{ + assert(off > 0); + ip[0] = m_pos[0]; + if (off == 1) + ip[1] = m_pos[0]; + else + ip[1] = m_pos[1]; +} + + +static void copy3(lzo_byte *ip, const lzo_byte *m_pos, lzo_ptrdiff_t off) +{ + assert(off > 0); + ip[0] = m_pos[0]; + if (off == 1) + { + ip[2] = ip[1] = m_pos[0]; + } + else if (off == 2) + { + ip[1] = m_pos[1]; + ip[2] = m_pos[0]; + } + else + { + ip[1] = m_pos[1]; + ip[2] = m_pos[2]; + } +} + + +/*********************************************************************** +// optimize a block of data. +************************************************************************/ + +LZO_PUBLIC(int) +DO_OPTIMIZE ( lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ + lzo_byte *op; + lzo_byte *ip; + lzo_uint t; + lzo_byte *m_pos; + lzo_byte * const ip_end = in + in_len; + lzo_byte * const op_end = out + *out_len; + lzo_byte *litp = NULL; + lzo_uint lit = 0; + lzo_uint next_lit = NO_LIT; + lzo_uint nl; + long o_m1_a = 0, o_m1_b = 0, o_m2 = 0, o_m3_a = 0, o_m3_b = 0; + + LZO_UNUSED(wrkmem); + +#if defined(__LZO_QUERY_OPTIMIZE) + if (__LZO_IS_OPTIMIZE_QUERY(in,in_len,out,out_len,wrkmem)) + return __LZO_QUERY_OPTIMIZE(in,in_len,out,out_len,wrkmem,0,0); +#endif + + *out_len = 0; + + op = out; + ip = in; + + assert(in_len >= 3); + if (*ip > 17) + { + t = *ip++ - 17; + if (t < 4) + goto match_next; + goto first_literal_run; + } + assert(*ip < 16 || (*ip == 17 && in_len == 3)); + + while (TEST_IP && TEST_OP) + { + t = *ip++; + if (t >= 16) + goto match; + /* a literal run */ + litp = ip - 1; + if (t == 0) + { + t = 15; + while (*ip == 0) + t += 255, ip++; + t += *ip++; + } + lit = t + 3; + /* copy literals */ +copy_literal_run: + *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; +first_literal_run: + do *op++ = *ip++; while (--t > 0); + + + t = *ip++; + + if (t >= 16) + goto match; +#if defined(LZO1X) + m_pos = op - 1 - 0x800; +#elif defined(LZO1Y) + m_pos = op - 1 - 0x400; +#endif + m_pos -= t >> 2; + m_pos -= *ip++ << 2; + *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos++; + lit = 0; + goto match_done; + + + /* handle matches */ + while (TEST_IP && TEST_OP) + { + if (t < 16) /* a M1 match */ + { + m_pos = op - 1; + m_pos -= t >> 2; + m_pos -= *ip++ << 2; + + if (litp == NULL) + goto copy_m1; + + /* assert that there was a match just before */ + assert(lit >= 1 && lit <= 3); + assert(litp == ip - 2 - lit - 2); + assert((lzo_uint)(*litp & 3) == lit); + nl = ip[-2] & 3; + /* test if a match follows */ + if (nl == 0 && lit == 1 && ip[0] >= 16) + { + next_lit = nl; + /* adjust length of previous short run */ + lit += 2; + *litp = LZO_BYTE((*litp & ~3) | lit); + /* copy over the 2 literals that replace the match */ + copy2(ip-2,m_pos,op-m_pos); + o_m1_a++; + } + /* test if a literal run follows */ + else if (nl == 0 && ip[0] < 16 && ip[0] != 0 && + (lit + 2 + ip[0] < 16)) + { + t = *ip++; + /* remove short run */ + *litp &= ~3; + /* copy over the 2 literals that replace the match */ + copy2(ip-3+1,m_pos,op-m_pos); + /* move literals 1 byte ahead */ + litp += 2; + if (lit > 0) + lzo_memmove(litp+1,litp,lit); + /* insert new length of long literal run */ + lit += 2 + t + 3; assert(lit <= 18); + *litp = LZO_BYTE(lit - 3); + + o_m1_b++; + *op++ = *m_pos++; *op++ = *m_pos++; + goto copy_literal_run; + } +copy_m1: + *op++ = *m_pos++; *op++ = *m_pos++; + } + else + { +match: + if (t >= 64) /* a M2 match */ + { + m_pos = op - 1; +#if defined(LZO1X) + m_pos -= (t >> 2) & 7; + m_pos -= *ip++ << 3; + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_pos -= (t >> 2) & 3; + m_pos -= *ip++ << 2; + t = (t >> 4) - 3; +#endif + if (litp == NULL) + goto copy_m; + + nl = ip[-2] & 3; + /* test if in beetween two long literal runs */ + if (t == 1 && lit > 3 && nl == 0 && + ip[0] < 16 && ip[0] != 0 && (lit + 3 + ip[0] < 16)) + { + assert(*litp == lit - 3); + t = *ip++; + /* copy over the 3 literals that replace the match */ + copy3(ip-1-2,m_pos,op-m_pos); + /* set new length of previous literal run */ + lit += 3 + t + 3; assert(lit <= 18); + *litp = LZO_BYTE(lit - 3); + o_m2++; + *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos++; + goto copy_literal_run; + } + } + else + { + if (t >= 32) /* a M3 match */ + { + t &= 31; + if (t == 0) + { + t = 31; + while (*ip == 0) + t += 255, ip++; + t += *ip++; + } + m_pos = op - 1; + m_pos -= *ip++ >> 2; + m_pos -= *ip++ << 6; + } + else /* a M4 match */ + { + m_pos = op; + m_pos -= (t & 8) << 11; + t &= 7; + if (t == 0) + { + t = 7; + while (*ip == 0) + t += 255, ip++; + t += *ip++; + } + m_pos -= *ip++ >> 2; + m_pos -= *ip++ << 6; + if (m_pos == op) + goto eof_found; + m_pos -= 0x4000; + } + if (litp == NULL) + goto copy_m; + + nl = ip[-2] & 3; + /* test if in beetween two matches */ + if (t == 1 && lit == 0 && nl == 0 && ip[0] >= 16) + { + assert(litp == ip - 3 - lit - 2); + assert((lzo_uint)(*litp & 3) == lit); + next_lit = nl; + /* make a previous short run */ + lit += 3; + *litp = LZO_BYTE((*litp & ~3) | lit); + /* copy over the 3 literals that replace the match */ + copy3(ip-3,m_pos,op-m_pos); + o_m3_a++; + } + /* test if a literal run follows */ + else if (t == 1 && lit <= 3 && nl == 0 && + ip[0] < 16 && ip[0] != 0 && (lit + 3 + ip[0] < 16)) + { + assert(litp == ip - 3 - lit - 2); + assert((lzo_uint)(*litp & 3) == lit); + t = *ip++; + /* remove short run */ + *litp &= ~3; + /* copy over the 3 literals that replace the match */ + copy3(ip-4+1,m_pos,op-m_pos); + /* move literals 1 byte ahead */ + litp += 2; + if (lit > 0) + lzo_memmove(litp+1,litp,lit); + /* insert new length of long literal run */ + lit += 3 + t + 3; assert(lit <= 18); + *litp = LZO_BYTE(lit - 3); + + o_m3_b++; + *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos++; + goto copy_literal_run; + } + } +copy_m: + *op++ = *m_pos++; *op++ = *m_pos++; + do *op++ = *m_pos++; while (--t > 0); + } + +match_done: + if (next_lit == NO_LIT) + { + t = ip[-2] & 3; + lit = t; + litp = ip - 2; + } + else + t = next_lit; + assert(t <= 3); + next_lit = NO_LIT; + if (t == 0) + break; + /* copy literals */ +match_next: + do *op++ = *ip++; while (--t > 0); + t = *ip++; + } + } + + /* no EOF code was found */ + *out_len = op - out; + return LZO_E_EOF_NOT_FOUND; + +eof_found: + assert(t == 1); +#if 0 + printf("optimize: %lu %lu %lu %lu %lu\n", + o_m1_a, o_m1_b, o_m2, o_m3_a, o_m3_b); +#endif + *out_len = op - out; + return (ip == ip_end ? LZO_E_OK : + (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); +} + + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/lzo1y.h b/DumpProto/lzo/lzo1y.h new file mode 100644 index 0000000..9f52e07 --- /dev/null +++ b/DumpProto/lzo/lzo1y.h @@ -0,0 +1,141 @@ +/* lzo1y.h -- public interface of the LZO1Y compression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __LZO1Y_H +#define __LZO1Y_H + +#ifndef __LZOCONF_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// +************************************************************************/ + +/* Memory required for the wrkmem parameter. + * When the required size is 0, you can also pass a NULL pointer. + */ + +#define LZO1Y_MEM_COMPRESS ((lzo_uint32) (16384L * lzo_sizeof_dict_t)) +#define LZO1Y_MEM_DECOMPRESS (0) +#define LZO1Y_MEM_OPTIMIZE (0) + + +/* decompression */ +LZO_EXTERN(int) +lzo1y_decompress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + +/* safe decompression with overrun testing */ +LZO_EXTERN(int) +lzo1y_decompress_safe ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + + +/*********************************************************************** +// +************************************************************************/ + +LZO_EXTERN(int) +lzo1y_1_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + + +/*********************************************************************** +// better compression ratio at the cost of more memory and time +************************************************************************/ + +#define LZO1Y_999_MEM_COMPRESS ((lzo_uint32) (14 * 16384L * sizeof(short))) + +#if !defined(LZO_999_UNSUPPORTED) +LZO_EXTERN(int) +lzo1y_999_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); +#endif + + + +/*********************************************************************** +// +************************************************************************/ + +#if !defined(LZO_999_UNSUPPORTED) +LZO_EXTERN(int) +lzo1y_999_compress_dict ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem, + const lzo_byte *dict, lzo_uint dict_len ); + +LZO_EXTERN(int) +lzo1y_999_compress_level ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem, + const lzo_byte *dict, lzo_uint dict_len, + lzo_progress_callback_t cb, + int compression_level ); +#endif + +LZO_EXTERN(int) +lzo1y_decompress_dict_safe ( const lzo_byte *in, lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem /* NOT USED */, + const lzo_byte *dict, lzo_uint dict_len ); + + +/*********************************************************************** +// optimize a compressed data block +************************************************************************/ + +LZO_EXTERN(int) +lzo1y_optimize ( lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem ); + + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + diff --git a/DumpProto/lzo/lzo1y_1.c b/DumpProto/lzo/lzo1y_1.c new file mode 100644 index 0000000..9a502a4 --- /dev/null +++ b/DumpProto/lzo/lzo1y_1.c @@ -0,0 +1,37 @@ +/* lzo1y_1.c -- LZO1Y-1 compression + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#define LZO_NEED_DICT_H +#define D_BITS 14 +#define D_INDEX1(d,p) d = DX3(p,5,5,6); d += d >> 5; d = DM(d) +#define D_INDEX2(d,p) d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f) + +#include "config1y.h" + +#define DO_COMPRESS lzo1y_1_compress + +#include "lzo1x_c.ch" diff --git a/DumpProto/lzo/lzo1y_9x.c b/DumpProto/lzo/lzo1y_9x.c new file mode 100644 index 0000000..2a64a45 --- /dev/null +++ b/DumpProto/lzo/lzo1y_9x.c @@ -0,0 +1,29 @@ +/* lzo1y_9x.c -- implementation of the LZO1Y-999 compression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#define LZO1Y +#include "lzo1x_9x.c" diff --git a/DumpProto/lzo/lzo1y_d1.c b/DumpProto/lzo/lzo1y_d1.c new file mode 100644 index 0000000..6b0a530 --- /dev/null +++ b/DumpProto/lzo/lzo1y_d1.c @@ -0,0 +1,33 @@ +/* lzo1y_d1.c -- LZO1Y decompression + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "config1y.h" + +#undef LZO_TEST_DECOMPRESS_OVERRUN +#define DO_DECOMPRESS lzo1y_decompress + +#include "lzo1x_d.ch" diff --git a/DumpProto/lzo/lzo1y_d2.c b/DumpProto/lzo/lzo1y_d2.c new file mode 100644 index 0000000..773fbf9 --- /dev/null +++ b/DumpProto/lzo/lzo1y_d2.c @@ -0,0 +1,33 @@ +/* lzo1y_d2.c -- LZO1Y decompression with overrun testing + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "config1y.h" + +#define LZO_TEST_DECOMPRESS_OVERRUN +#define DO_DECOMPRESS lzo1y_decompress_safe + +#include "lzo1x_d.ch" diff --git a/DumpProto/lzo/lzo1y_d3.c b/DumpProto/lzo/lzo1y_d3.c new file mode 100644 index 0000000..3921c74 --- /dev/null +++ b/DumpProto/lzo/lzo1y_d3.c @@ -0,0 +1,32 @@ +/* lzo1y_d3.c -- LZO1Y decompression with preset dictionary + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "config1y.h" + +#define lzo1x_decompress_dict_safe lzo1y_decompress_dict_safe + +#include "lzo1x_d3.c" diff --git a/DumpProto/lzo/lzo1y_o.c b/DumpProto/lzo/lzo1y_o.c new file mode 100644 index 0000000..e7e9cef --- /dev/null +++ b/DumpProto/lzo/lzo1y_o.c @@ -0,0 +1,32 @@ +/* lzo1y_o.c -- LZO1Y compressed data optimizer + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "config1y.h" + +#define DO_OPTIMIZE lzo1y_optimize + +#include "lzo1x_oo.ch" diff --git a/DumpProto/lzo/lzo1z.h b/DumpProto/lzo/lzo1z.h new file mode 100644 index 0000000..654a4ec --- /dev/null +++ b/DumpProto/lzo/lzo1z.h @@ -0,0 +1,146 @@ +/* lzo1z.h -- public interface of the LZO1Z compression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __LZO1Z_H +#define __LZO1Z_H + +#ifndef __LZOCONF_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// +************************************************************************/ + +/* Memory required for the wrkmem parameter. + * When the required size is 0, you can also pass a NULL pointer. + */ + +#define LZO1Z_MEM_COMPRESS ((lzo_uint32) (16384L * lzo_sizeof_dict_t)) +#define LZO1Z_MEM_DECOMPRESS (0) +#define LZO1Z_MEM_OPTIMIZE (0) + + +/* decompression */ +LZO_EXTERN(int) +lzo1z_decompress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + +/* safe decompression with overrun testing */ +LZO_EXTERN(int) +lzo1z_decompress_safe ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + + +/*********************************************************************** +// +************************************************************************/ + +#if 0 +/* not yet implemented */ +LZO_EXTERN(int) +lzo1z_1_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); +#endif + + +/*********************************************************************** +// better compression ratio at the cost of more memory and time +************************************************************************/ + +#define LZO1Z_999_MEM_COMPRESS ((lzo_uint32) (14 * 16384L * sizeof(short))) + +#if !defined(LZO_999_UNSUPPORTED) +LZO_EXTERN(int) +lzo1z_999_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); +#endif + + +/*********************************************************************** +// +************************************************************************/ + +#if !defined(LZO_999_UNSUPPORTED) +LZO_EXTERN(int) +lzo1z_999_compress_dict ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem, + const lzo_byte *dict, lzo_uint dict_len ); + +LZO_EXTERN(int) +lzo1z_999_compress_level ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem, + const lzo_byte *dict, lzo_uint dict_len, + lzo_progress_callback_t cb, + int compression_level ); +#endif + +LZO_EXTERN(int) +lzo1z_decompress_dict_safe ( const lzo_byte *in, lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem /* NOT USED */, + const lzo_byte *dict, lzo_uint dict_len ); + + +/*********************************************************************** +// optimize a compressed data block +************************************************************************/ + +#if 0 +/* not yet implemented */ +LZO_EXTERN(int) +lzo1z_optimize ( lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem ); +#endif + + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + diff --git a/DumpProto/lzo/lzo1z_9x.c b/DumpProto/lzo/lzo1z_9x.c new file mode 100644 index 0000000..c29aec5 --- /dev/null +++ b/DumpProto/lzo/lzo1z_9x.c @@ -0,0 +1,29 @@ +/* lzo1z_9x.c -- implementation of the LZO1Z-999 compression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#define LZO1Z +#include "lzo1x_9x.c" diff --git a/DumpProto/lzo/lzo1z_d1.c b/DumpProto/lzo/lzo1z_d1.c new file mode 100644 index 0000000..e92db39 --- /dev/null +++ b/DumpProto/lzo/lzo1z_d1.c @@ -0,0 +1,33 @@ +/* lzo1z_d1.c -- LZO1Z decompression + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "config1z.h" + +#undef LZO_TEST_DECOMPRESS_OVERRUN +#define DO_DECOMPRESS lzo1z_decompress + +#include "lzo1x_d.ch" diff --git a/DumpProto/lzo/lzo1z_d2.c b/DumpProto/lzo/lzo1z_d2.c new file mode 100644 index 0000000..333049f --- /dev/null +++ b/DumpProto/lzo/lzo1z_d2.c @@ -0,0 +1,33 @@ +/* lzo1z_d2.c -- LZO1Z decompression with overrun testing + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "config1z.h" + +#define LZO_TEST_DECOMPRESS_OVERRUN +#define DO_DECOMPRESS lzo1z_decompress_safe + +#include "lzo1x_d.ch" diff --git a/DumpProto/lzo/lzo1z_d3.c b/DumpProto/lzo/lzo1z_d3.c new file mode 100644 index 0000000..4176e2b --- /dev/null +++ b/DumpProto/lzo/lzo1z_d3.c @@ -0,0 +1,32 @@ +/* lzo1z_d3.c -- LZO1Z decompression with preset dictionary + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "config1z.h" + +#define lzo1x_decompress_dict_safe lzo1z_decompress_dict_safe + +#include "lzo1x_d3.c" diff --git a/DumpProto/lzo/lzo2a.h b/DumpProto/lzo/lzo2a.h new file mode 100644 index 0000000..47b6ba0 --- /dev/null +++ b/DumpProto/lzo/lzo2a.h @@ -0,0 +1,86 @@ +/* lzo2a.h -- public interface of the LZO2A compression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __LZO2A_H +#define __LZO2A_H + +#ifndef __LZOCONF_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// +************************************************************************/ + +#define LZO2A_MEM_DECOMPRESS (0) + +/* decompression */ +LZO_EXTERN(int) +lzo2a_decompress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + +/* safe decompression with overrun testing */ +LZO_EXTERN(int) +lzo2a_decompress_safe ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + + +/*********************************************************************** +// better compression ratio at the cost of more memory and time +************************************************************************/ + +#define LZO2A_999_MEM_COMPRESS ((lzo_uint32) (8 * 16384L * sizeof(short))) + +#if !defined(LZO_999_UNSUPPORTED) +LZO_EXTERN(int) +lzo2a_999_compress ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); +#endif + + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + diff --git a/DumpProto/lzo/lzo2a_9x.c b/DumpProto/lzo/lzo2a_9x.c new file mode 100644 index 0000000..3f1a524 --- /dev/null +++ b/DumpProto/lzo/lzo2a_9x.c @@ -0,0 +1,354 @@ +/* lzo2a_9x.c -- implementation of the LZO2A-999 compression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + + +#include +#if !defined(LZO_999_UNSUPPORTED) + +#include +#include "config2a.h" + +#if 0 +#undef NDEBUG +#include +#endif + + +/*********************************************************************** +// +************************************************************************/ + +#define THRESHOLD 1 /* lower limit for match length */ +#define F 2048 /* upper limit for match length */ + + +#define LZO2A +#define LZO_COMPRESS_T lzo2a_999_t +#define lzo_swd_t lzo2a_999_swd_t +#include "lzo_mchw.ch" + + + +/*********************************************************************** +// +************************************************************************/ + +#define putbyte(x) *op++ = LZO_BYTE(x) + +#define putbits(j,x) \ + if (k == 0) bitp = op++; \ + SETBITS(j,x); \ + if (k >= 8) { *bitp = LZO_BYTE(MASKBITS(8)); DUMPBITS(8); \ + if (k > 0) bitp = op++; } + +#define putbit(x) putbits(1,x) + + +/*********************************************************************** +// this is a public function, but there is no prototype in a header file +************************************************************************/ + +LZO_EXTERN(int) +lzo2a_999_compress_callback ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem, + lzo_progress_callback_t cb, + lzo_uint max_chain ); + +LZO_PUBLIC(int) +lzo2a_999_compress_callback ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem, + lzo_progress_callback_t cb, + lzo_uint max_chain ) +{ + lzo_byte *op; + lzo_byte *bitp = 0; + lzo_uint m_len, m_off; + LZO_COMPRESS_T cc; + LZO_COMPRESS_T * const c = &cc; + lzo_swd_t * const swd = (lzo_swd_t *) wrkmem; + int r; + + lzo_uint32 b = 0; /* bit buffer */ + unsigned k = 0; /* bits in bit buffer */ + +#if defined(__LZO_QUERY_COMPRESS) + if (__LZO_IS_COMPRESS_QUERY(in,in_len,out,out_len,wrkmem)) + return __LZO_QUERY_COMPRESS(in,in_len,out,out_len,wrkmem,1,lzo_sizeof(lzo_swd_t)); +#endif + + /* sanity check */ + if (!lzo_assert(LZO2A_999_MEM_COMPRESS >= lzo_sizeof(lzo_swd_t))) + return LZO_E_ERROR; + + c->init = 0; + c->ip = c->in = in; + c->in_end = in + in_len; + c->cb = cb; + c->m1 = c->m2 = c->m3 = c->m4 = 0; + + op = out; + + r = init_match(c,swd,NULL,0,0); + if (r != 0) + return r; + if (max_chain > 0) + swd->max_chain = max_chain; + + r = find_match(c,swd,0,0); + if (r != 0) + return r; + while (c->look > 0) + { + int lazy_match_min_gain = 0; + int extra1 = 0; + int extra2 = 0; + lzo_uint ahead = 0; + + LZO_UNUSED(extra1); + + m_len = c->m_len; + m_off = c->m_off; + +#if (N >= 8192) + if (m_off >= 8192) + { + if (m_len < M3_MIN_LEN) + m_len = 0; + else + lazy_match_min_gain = 1; + } + else +#endif + if (m_len >= M1_MIN_LEN && m_len <= M1_MAX_LEN && m_off <= 256) + { + lazy_match_min_gain = 2; + extra1 = 3; + extra2 = 2; + } + else if (m_len >= 10) + lazy_match_min_gain = 1; + else if (m_len >= 3) + { + lazy_match_min_gain = 1; + extra1 = 1; + } + else + m_len = 0; + + + /* try a lazy match */ + if (lazy_match_min_gain > 0 && c->look > m_len) + { + int lit = swd->b_char; + + r = find_match(c,swd,1,0); + assert(r == 0); + assert(c->look > 0); + +#if (N >= 8192) + if (m_off < 8192 && c->m_off >= 8192) + lazy_match_min_gain += extra1; + else +#endif + if (m_len >= M1_MIN_LEN && m_len <= M1_MAX_LEN && m_off <= 256) + { + if (!(c->m_len >= M1_MIN_LEN && + c->m_len <= M1_MAX_LEN && c->m_off <= 256)) + lazy_match_min_gain += extra2; + } + if (c->m_len >= M1_MIN_LEN && + c->m_len <= M1_MAX_LEN && c->m_off <= 256) + { + lazy_match_min_gain -= 1; + } + + if (lazy_match_min_gain < 1) + lazy_match_min_gain = 1; + + if (c->m_len >= m_len + lazy_match_min_gain) + { + c->lazy++; +#if !defined(NDEBUG) + m_len = c->m_len; + m_off = c->m_off; + assert(lzo_memcmp(c->ip - c->look, c->ip - c->look - m_off, + m_len) == 0); + assert(m_len >= 3 || (m_len >= 2 && m_off <= 256)); +#endif + /* code literal */ + putbit(0); + putbyte(lit); + c->lit_bytes++; + continue; + } + else + ahead = 1; + assert(m_len > 0); + } + + + if (m_len == 0) + { + /* a literal */ + putbit(0); + putbyte(swd->b_char); + c->lit_bytes++; + r = find_match(c,swd,1,0); + assert(r == 0); + } + else + { + assert(m_len >= M1_MIN_LEN); + assert(m_off > 0); + assert(m_off <= N); + + /* 2 - code match */ + if (m_len >= M1_MIN_LEN && m_len <= M1_MAX_LEN && m_off <= 256) + { + putbit(1); + putbit(0); + putbits(2,m_len - M1_MIN_LEN); + putbyte(m_off - 1); + c->m1++; + } +#if (N >= 8192) + else if (m_off >= 8192) + { + unsigned len = m_len; + assert(m_len >= M3_MIN_LEN); + putbit(1); + putbit(1); + putbyte(m_off & 31); + putbyte(m_off >> 5); + putbit(1); + len -= M3_MIN_LEN - 1; + while (len > 255) + { + len -= 255; + putbyte(0); + } + putbyte(len); + c->m4++; + } +#endif + else + { + assert(m_len >= 3); + + putbit(1); + putbit(1); + if (m_len <= 9) + { + putbyte(((m_len - 2) << 5) | (m_off & 31)); + putbyte(m_off >> 5); + c->m2++; + } + else + { + lzo_uint len = m_len; + putbyte(m_off & 31); + putbyte(m_off >> 5); +#if (N >= 8192) + putbit(0); +#endif + len -= 10 - 1; + while (len > 255) + { + len -= 255; + putbyte(0); + } + putbyte(len); + c->m3++; + } + } + r = find_match(c,swd,m_len,1+ahead); + assert(r == 0); + } + + c->codesize = op - out; + } + +#if defined(LZO_EOF_CODE) + /* code EOF code */ + putbit(1); + putbit(1); + putbyte(1 << 5); + putbyte(0); +#endif + + /* flush remaining bits */ + assert(k < CHAR_BIT); + if (k > 0) + { + assert(b == MASKBITS(k)); + assert(op - bitp > 1); + *bitp = LZO_BYTE(MASKBITS(k)); + DUMPBITS(k); + assert(b == 0); + assert(k == 0); + } + + assert(c->textsize == in_len); + c->codesize = op - out; + + *out_len = op - out; + + if (c->cb) + (*c->cb)(c->textsize,c->codesize); + +#if 0 + printf("%ld -> %ld: %ld %ld %ld %ld %ld %ld\n", + (long) c->textsize, (long) c->codesize, + c->lit_bytes, c->m1, c->m2, c->m3, c->m4, c->lazy); +#endif + return LZO_E_OK; +} + + + +/*********************************************************************** +// +************************************************************************/ + +LZO_PUBLIC(int) +lzo2a_999_compress ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ + return lzo2a_999_compress_callback(in,in_len,out,out_len,wrkmem, + (lzo_progress_callback_t) 0, 0); +} + + +#endif /* !defined(LZO_999_UNSUPPORTED) */ + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/lzo2a_d.ch b/DumpProto/lzo/lzo2a_d.ch new file mode 100644 index 0000000..bcb7dc3 --- /dev/null +++ b/DumpProto/lzo/lzo2a_d.ch @@ -0,0 +1,192 @@ +/* lzo2a_d.ch -- implementation of the LZO2A decompression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "lzo1_d.ch" + + +#if defined(HAVE_ANY_IP) && defined(HAVE_ANY_OP) + /* too many local variables, cannot allocate registers */ +# undef LZO_OPTIMIZE_GNUC_i386 +#endif + + +/*********************************************************************** +// decompress a block of data. +************************************************************************/ + +#define _NEEDBYTE NEED_IP(1) +#define _NEXTBYTE (*ip++) + +LZO_PUBLIC(int) +DO_DECOMPRESS ( const lzo_byte *in , lzo_uint in_len, + lzo_byte *out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ +#if defined(LZO_OPTIMIZE_GNUC_i386) + register lzo_byte *op __asm__("%edi"); + register const lzo_byte *ip __asm__("%esi"); + register const lzo_byte *m_pos __asm__("%ebx"); +#else + register lzo_byte *op; + register const lzo_byte *ip; + register const lzo_byte *m_pos; +#endif + + lzo_uint t; + const lzo_byte * const ip_end = in + in_len; +#if defined(HAVE_ANY_OP) + lzo_byte * const op_end = out + *out_len; +#endif + + lzo_uint32 b = 0; /* bit buffer */ + unsigned k = 0; /* bits in bit buffer */ + + LZO_UNUSED(wrkmem); + +#if defined(__LZO_QUERY_DECOMPRESS) + if (__LZO_IS_DECOMPRESS_QUERY(in,in_len,out,out_len,wrkmem)) + return __LZO_QUERY_DECOMPRESS(in,in_len,out,out_len,wrkmem,0,0); +#endif + + op = out; + ip = in; + + while (TEST_IP && TEST_OP) + { + NEEDBITS(1); + if (MASKBITS(1) == 0) + { + DUMPBITS(1); + /* a literal */ + NEED_IP(1); NEED_OP(1); + *op++ = *ip++; + continue; + } + DUMPBITS(1); + + NEEDBITS(1); + if (MASKBITS(1) == 0) + { + DUMPBITS(1); + /* a M1 match */ + NEEDBITS(2); + t = M1_MIN_LEN + (lzo_uint) MASKBITS(2); + DUMPBITS(2); + NEED_IP(1); NEED_OP(t); + m_pos = op - 1 - *ip++; + assert(m_pos >= out); assert(m_pos < op); + TEST_LOOKBEHIND(m_pos,out); + MEMMOVE_DS(op,m_pos,t); + continue; + } + DUMPBITS(1); + + NEED_IP(2); + t = *ip++; + m_pos = op; + m_pos -= (t & 31) | (((lzo_uint) *ip++) << 5); + t >>= 5; + if (t == 0) + { +#if (N >= 8192) + NEEDBITS(1); + t = MASKBITS(1); + DUMPBITS(1); + if (t == 0) + t = 10 - 1; + else + { + /* a M3 match */ + m_pos -= 8192; /* t << 13 */ + t = M3_MIN_LEN - 1; + } +#else + t = 10 - 1; +#endif + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += *ip++; + } + else + { +#if defined(LZO_EOF_CODE) + if (m_pos == op) + goto eof_found; +#endif + t += 2; + } + assert(m_pos >= out); assert(m_pos < op); + TEST_LOOKBEHIND(m_pos,out); + NEED_OP(t); + MEMMOVE_DS(op,m_pos,t); + } + + +#if defined(LZO_EOF_CODE) +#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP) + /* no EOF code was found */ + *out_len = op - out; + return LZO_E_EOF_NOT_FOUND; +#endif + +eof_found: + assert(t == 1); +#endif + *out_len = op - out; + return (ip == ip_end ? LZO_E_OK : + (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); + + +#if defined(HAVE_NEED_IP) +input_overrun: + *out_len = op - out; + return LZO_E_INPUT_OVERRUN; +#endif + +#if defined(HAVE_NEED_OP) +output_overrun: + *out_len = op - out; + return LZO_E_OUTPUT_OVERRUN; +#endif + +#if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND) +lookbehind_overrun: + *out_len = op - out; + return LZO_E_LOOKBEHIND_OVERRUN; +#endif +} + + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/lzo2a_d1.c b/DumpProto/lzo/lzo2a_d1.c new file mode 100644 index 0000000..efafe8d --- /dev/null +++ b/DumpProto/lzo/lzo2a_d1.c @@ -0,0 +1,33 @@ +/* lzo2a_d2.c -- LZO2A decompression with overrun testing + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "config2a.h" + +#undef LZO_TEST_DECOMPRESS_OVERRUN +#define DO_DECOMPRESS lzo2a_decompress + +#include "lzo2a_d.ch" diff --git a/DumpProto/lzo/lzo2a_d2.c b/DumpProto/lzo/lzo2a_d2.c new file mode 100644 index 0000000..f16f5b1 --- /dev/null +++ b/DumpProto/lzo/lzo2a_d2.c @@ -0,0 +1,33 @@ +/* lzo2a_d2.c -- LZO2A decompression with overrun testing + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "config2a.h" + +#define LZO_TEST_DECOMPRESS_OVERRUN +#define DO_DECOMPRESS lzo2a_decompress_safe + +#include "lzo2a_d.ch" diff --git a/DumpProto/lzo/lzo_conf.h b/DumpProto/lzo/lzo_conf.h new file mode 100644 index 0000000..218c373 --- /dev/null +++ b/DumpProto/lzo/lzo_conf.h @@ -0,0 +1,413 @@ +/* lzo_conf.h -- main internal configuration file for the the LZO library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the library and is subject + to change. + */ + + +#ifndef __LZO_CONF_H +#define __LZO_CONF_H + +#if !defined(__LZO_IN_MINILZO) +# ifndef __LZOCONF_H +# include +# endif +#endif + + +/*********************************************************************** +// memory checkers +************************************************************************/ + +#if defined(__BOUNDS_CHECKING_ON) +# include +#else +# define BOUNDS_CHECKING_OFF_DURING(stmt) stmt +# define BOUNDS_CHECKING_OFF_IN_EXPR(expr) (expr) +#endif + + +/*********************************************************************** +// autoconf section +************************************************************************/ + +#if !defined(LZO_HAVE_CONFIG_H) +# include /* ptrdiff_t, size_t */ +# include /* memcpy, memmove, memcmp, memset */ +# if !defined(NO_STDLIB_H) +# include +# endif +# define HAVE_MEMCMP +# define HAVE_MEMCPY +# define HAVE_MEMMOVE +# define HAVE_MEMSET +#else +# include +# if defined(HAVE_STDDEF_H) +# include +# endif +# if defined(STDC_HEADERS) +# include +# include +# endif +#endif + +#if defined(__LZO_DOS16) || defined(__LZO_WIN16) +# define HAVE_MALLOC_H +# define HAVE_HALLOC +#endif + + +#undef NDEBUG +#if !defined(LZO_DEBUG) +# define NDEBUG +#endif +#if defined(LZO_DEBUG) || !defined(NDEBUG) +# if !defined(NO_STDIO_H) +# include +# endif +#endif +#include + + +#if !defined(LZO_COMPILE_TIME_ASSERT) +# define LZO_COMPILE_TIME_ASSERT(expr) \ + { typedef int __lzo_compile_time_assert_fail[1 - 2 * !(expr)]; } +#endif + + +#if !defined(LZO_UNUSED) +# if 1 +# define LZO_UNUSED(var) ((void)&var) +# elif 0 +# define LZO_UNUSED(var) { typedef int __lzo_unused[sizeof(var) ? 2 : 1]; } +# else +# define LZO_UNUSED(parm) (parm = parm) +# endif +#endif + + +#if !defined(__inline__) && !defined(__GNUC__) +# if defined(__cplusplus) +# define __inline__ inline +# else +# define __inline__ /* nothing */ +# endif +#endif + + +#if defined(NO_MEMCMP) +# undef HAVE_MEMCMP +#endif + +#if !defined(HAVE_MEMCMP) +# undef memcmp +# define memcmp lzo_memcmp +#endif +#if !defined(HAVE_MEMCPY) +# undef memcpy +# define memcpy lzo_memcpy +#endif +#if !defined(HAVE_MEMMOVE) +# undef memmove +# define memmove lzo_memmove +#endif +#if !defined(HAVE_MEMSET) +# undef memset +# define memset lzo_memset +#endif + + +/*********************************************************************** +// +************************************************************************/ + +#if 0 +# define LZO_BYTE(x) ((unsigned char) (x)) +#else +# define LZO_BYTE(x) ((unsigned char) ((x) & 0xff)) +#endif + +#define LZO_MAX(a,b) ((a) >= (b) ? (a) : (b)) +#define LZO_MIN(a,b) ((a) <= (b) ? (a) : (b)) +#define LZO_MAX3(a,b,c) ((a) >= (b) ? LZO_MAX(a,c) : LZO_MAX(b,c)) +#define LZO_MIN3(a,b,c) ((a) <= (b) ? LZO_MIN(a,c) : LZO_MIN(b,c)) + +#define lzo_sizeof(type) ((lzo_uint) (sizeof(type))) + +#define LZO_HIGH(array) ((lzo_uint) (sizeof(array)/sizeof(*(array)))) + +/* this always fits into 16 bits */ +#define LZO_SIZE(bits) (1u << (bits)) +#define LZO_MASK(bits) (LZO_SIZE(bits) - 1) + +#define LZO_LSIZE(bits) (1ul << (bits)) +#define LZO_LMASK(bits) (LZO_LSIZE(bits) - 1) + +#define LZO_USIZE(bits) ((lzo_uint) 1 << (bits)) +#define LZO_UMASK(bits) (LZO_USIZE(bits) - 1) + +/* Maximum value of a signed/unsigned type. + Do not use casts, avoid overflows ! */ +#define LZO_STYPE_MAX(b) (((1l << (8*(b)-2)) - 1l) + (1l << (8*(b)-2))) +#define LZO_UTYPE_MAX(b) (((1ul << (8*(b)-1)) - 1ul) + (1ul << (8*(b)-1))) + + +/*********************************************************************** +// +************************************************************************/ + +#if !defined(SIZEOF_UNSIGNED) +# if (UINT_MAX == 0xffff) +# define SIZEOF_UNSIGNED 2 +# elif (UINT_MAX == LZO_0xffffffffL) +# define SIZEOF_UNSIGNED 4 +# elif (UINT_MAX >= LZO_0xffffffffL) +# define SIZEOF_UNSIGNED 8 +# else +# error "SIZEOF_UNSIGNED" +# endif +#endif + +#if !defined(SIZEOF_UNSIGNED_LONG) +# if (ULONG_MAX == LZO_0xffffffffL) +# define SIZEOF_UNSIGNED_LONG 4 +# elif (ULONG_MAX >= LZO_0xffffffffL) +# define SIZEOF_UNSIGNED_LONG 8 +# else +# error "SIZEOF_UNSIGNED_LONG" +# endif +#endif + + +#if !defined(SIZEOF_SIZE_T) +# define SIZEOF_SIZE_T SIZEOF_UNSIGNED +#endif +#if !defined(SIZE_T_MAX) +# define SIZE_T_MAX LZO_UTYPE_MAX(SIZEOF_SIZE_T) +#endif + + +/*********************************************************************** +// compiler and architecture specific stuff +************************************************************************/ + +/* Some defines that indicate if memory can be accessed at unaligned + * memory addresses. You should also test that this is actually faster + * even if it is allowed by your system. + */ + +#if 1 && defined(__LZO_i386) && (UINT_MAX == LZO_0xffffffffL) +# if !defined(LZO_UNALIGNED_OK_2) && (USHRT_MAX == 0xffff) +# define LZO_UNALIGNED_OK_2 +# endif +# if !defined(LZO_UNALIGNED_OK_4) && (LZO_UINT32_MAX == LZO_0xffffffffL) +# define LZO_UNALIGNED_OK_4 +# endif +#endif + +#if defined(LZO_UNALIGNED_OK_2) || defined(LZO_UNALIGNED_OK_4) +# if !defined(LZO_UNALIGNED_OK) +# define LZO_UNALIGNED_OK +# endif +#endif + +#if defined(__LZO_NO_UNALIGNED) +# undef LZO_UNALIGNED_OK +# undef LZO_UNALIGNED_OK_2 +# undef LZO_UNALIGNED_OK_4 +#endif + +#if defined(LZO_UNALIGNED_OK_2) && (USHRT_MAX != 0xffff) +# error "LZO_UNALIGNED_OK_2 must not be defined on this system" +#endif +#if defined(LZO_UNALIGNED_OK_4) && (LZO_UINT32_MAX != LZO_0xffffffffL) +# error "LZO_UNALIGNED_OK_4 must not be defined on this system" +#endif + + +/* Many modern processors can transfer 32bit words much faster than + * bytes - this can significantly speed decompression. + */ + +#if defined(__LZO_NO_ALIGNED) +# undef LZO_ALIGNED_OK_4 +#endif + +#if defined(LZO_ALIGNED_OK_4) && (LZO_UINT32_MAX != LZO_0xffffffffL) +# error "LZO_ALIGNED_OK_4 must not be defined on this system" +#endif + + +/* Definitions for byte order, according to significance of bytes, from low + * addresses to high addresses. The value is what you get by putting '4' + * in the most significant byte, '3' in the second most significant byte, + * '2' in the second least significant byte, and '1' in the least + * significant byte. + * The byte order is only needed if we use LZO_UNALIGNED_OK. + */ + +#define LZO_LITTLE_ENDIAN 1234 +#define LZO_BIG_ENDIAN 4321 +#define LZO_PDP_ENDIAN 3412 + +#if !defined(LZO_BYTE_ORDER) +# if defined(MFX_BYTE_ORDER) +# define LZO_BYTE_ORDER MFX_BYTE_ORDER +# elif defined(__LZO_i386) +# define LZO_BYTE_ORDER LZO_LITTLE_ENDIAN +# elif defined(BYTE_ORDER) +# define LZO_BYTE_ORDER BYTE_ORDER +# elif defined(__BYTE_ORDER) +# define LZO_BYTE_ORDER __BYTE_ORDER +# endif +#endif + +#if defined(LZO_BYTE_ORDER) +# if (LZO_BYTE_ORDER != LZO_LITTLE_ENDIAN) && \ + (LZO_BYTE_ORDER != LZO_BIG_ENDIAN) +# error "invalid LZO_BYTE_ORDER" +# endif +#endif + +#if defined(LZO_UNALIGNED_OK) && !defined(LZO_BYTE_ORDER) +# error "LZO_BYTE_ORDER is not defined" +#endif + + +/*********************************************************************** +// optimization +************************************************************************/ + +/* gcc 2.6.3 and gcc 2.7.2 have a bug with 'register xxx __asm__("%yyy")' */ +#define LZO_OPTIMIZE_GNUC_i386_IS_BUGGY + +/* Help the gcc optimizer with register allocation. */ +#if defined(NDEBUG) && !defined(LZO_DEBUG) && !defined(__LZO_CHECKER) +# if defined(__GNUC__) && defined(__i386__) +# if !defined(LZO_OPTIMIZE_GNUC_i386_IS_BUGGY) +# define LZO_OPTIMIZE_GNUC_i386 +# endif +# endif +#endif + + +/*********************************************************************** +// some globals +************************************************************************/ + +__LZO_EXTERN_C int __lzo_init_done; +__LZO_EXTERN_C const lzo_byte __lzo_copyright[]; +LZO_EXTERN(const lzo_byte *) lzo_copyright(void); +__LZO_EXTERN_C const lzo_uint32 _lzo_crc32_table[256]; + + +/*********************************************************************** +// ANSI C preprocessor macros +************************************************************************/ + +#define _LZO_STRINGIZE(x) #x +#define _LZO_MEXPAND(x) _LZO_STRINGIZE(x) + +/* concatenate */ +#define _LZO_CONCAT2(a,b) a ## b +#define _LZO_CONCAT3(a,b,c) a ## b ## c +#define _LZO_CONCAT4(a,b,c,d) a ## b ## c ## d +#define _LZO_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e + +/* expand and concatenate (by using one level of indirection) */ +#define _LZO_ECONCAT2(a,b) _LZO_CONCAT2(a,b) +#define _LZO_ECONCAT3(a,b,c) _LZO_CONCAT3(a,b,c) +#define _LZO_ECONCAT4(a,b,c,d) _LZO_CONCAT4(a,b,c,d) +#define _LZO_ECONCAT5(a,b,c,d,e) _LZO_CONCAT5(a,b,c,d,e) + + +/*********************************************************************** +// Query-interface to the algorithms +************************************************************************/ + +#if 0 + +#define __LZO_IS_COMPRESS_QUERY(i,il,o,ol,w) ((lzo_voidp)(o) == (w)) +#define __LZO_QUERY_COMPRESS(i,il,o,ol,w,n,s) \ + (*ol = (n)*(s), LZO_E_OK) + +#define __LZO_IS_DECOMPRESS_QUERY(i,il,o,ol,w) ((lzo_voidp)(o) == (w)) +#define __LZO_QUERY_DECOMPRESS(i,il,o,ol,w,n,s) \ + (*ol = (n)*(s), LZO_E_OK) + +#define __LZO_IS_OPTIMIZE_QUERY(i,il,o,ol,w) ((lzo_voidp)(o) == (w)) +#define __LZO_QUERY_OPTIMIZE(i,il,o,ol,w,n,s) \ + (*ol = (n)*(s), LZO_E_OK) + +#endif + + +/*********************************************************************** +// +************************************************************************/ + +#include "lzo_ptr.h" + + +/* Generate compressed data in a deterministic way. + * This is fully portable, and compression can be faster as well. + * A reason NOT to be deterministic is when the block size is + * very small (e.g. 8kB) or the dictionary is big, because + * then the initialization of the dictionary becomes a relevant + * magnitude for compression speed. + */ +#define LZO_DETERMINISTIC + + +#define LZO_DICT_USE_PTR +#if defined(__LZO_DOS16) || defined(__LZO_WIN16) || defined(__LZO_STRICT_16BIT) +# undef LZO_DICT_USE_PTR +#endif + +#if defined(LZO_DICT_USE_PTR) +# define lzo_dict_t const lzo_bytep +# define lzo_dict_p lzo_dict_t __LZO_MMODEL * +#else +# define lzo_dict_t lzo_uint +# define lzo_dict_p lzo_dict_t __LZO_MMODEL * +#endif + +#if !defined(lzo_moff_t) +/* must be unsigned */ +#define lzo_moff_t lzo_uint +#endif + + +#endif /* already included */ + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/lzo_crc.c b/DumpProto/lzo/lzo_crc.c new file mode 100644 index 0000000..3f2b9d7 --- /dev/null +++ b/DumpProto/lzo/lzo_crc.c @@ -0,0 +1,134 @@ +/* lzo_crc.c -- crc checksum for the the LZO library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "lzo_conf.h" +#include "lzo_util.h" + + +/*********************************************************************** +// crc32 checksum +// adapted from free code by Mark Adler +// see http://www.cdrom.com/pub/infozip/zlib/ +************************************************************************/ + +const lzo_uint32 _lzo_crc32_table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; + + +#if 1 +#define LZO_DO1(buf,i) \ + crc = _lzo_crc32_table[((int)crc ^ buf[i]) & 0xff] ^ (crc >> 8) +#else +#define LZO_DO1(buf,i) \ + crc = _lzo_crc32_table[(unsigned char)((unsigned char)crc ^ buf[i])] ^ (crc >> 8) +#endif +#define LZO_DO2(buf,i) LZO_DO1(buf,i); LZO_DO1(buf,i+1); +#define LZO_DO4(buf,i) LZO_DO2(buf,i); LZO_DO2(buf,i+2); +#define LZO_DO8(buf,i) LZO_DO4(buf,i); LZO_DO4(buf,i+4); +#define LZO_DO16(buf,i) LZO_DO8(buf,i); LZO_DO8(buf,i+8); + + +LZO_PUBLIC(lzo_uint32) +lzo_crc32(lzo_uint32 c, const lzo_byte *buf, lzo_uint len) +{ + lzo_uint32 crc = (c & LZO_0xffffffffL) ^ LZO_0xffffffffL; + + if (buf == NULL) + return 0; + + if (len >= 16) do + { + LZO_DO16(buf,0); + buf += 16; + len -= 16; + } while (len >= 16); + if (len != 0) do + { + LZO_DO1(buf,0); + buf += 1; + len -= 1; + } while (len > 0); + + return crc ^ LZO_0xffffffffL; +} + + +/* +vi:ts=4:et +*/ diff --git a/DumpProto/lzo/lzo_dict.h b/DumpProto/lzo/lzo_dict.h new file mode 100644 index 0000000..eb7d2b0 --- /dev/null +++ b/DumpProto/lzo/lzo_dict.h @@ -0,0 +1,301 @@ +/* lzo_dict.h -- dictionary definitions for the the LZO library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the library and is subject + to change. + */ + + +#ifndef __LZO_DICT_H +#define __LZO_DICT_H + +#ifdef __cplusplus +extern "C" { +#endif + + + +/*********************************************************************** +// dictionary size +************************************************************************/ + +/* dictionary needed for compression */ +#if !defined(D_BITS) && defined(DBITS) +# define D_BITS DBITS +#endif +#if !defined(D_BITS) +# error "D_BITS is not defined" +#endif +#if (D_BITS < 16) +# define D_SIZE LZO_SIZE(D_BITS) +# define D_MASK LZO_MASK(D_BITS) +#else +# define D_SIZE LZO_USIZE(D_BITS) +# define D_MASK LZO_UMASK(D_BITS) +#endif +#define D_HIGH ((D_MASK >> 1) + 1) + + +/* dictionary depth */ +#if !defined(DD_BITS) +# define DD_BITS 0 +#endif +#define DD_SIZE LZO_SIZE(DD_BITS) +#define DD_MASK LZO_MASK(DD_BITS) + +/* dictionary length */ +#if !defined(DL_BITS) +# define DL_BITS (D_BITS - DD_BITS) +#endif +#if (DL_BITS < 16) +# define DL_SIZE LZO_SIZE(DL_BITS) +# define DL_MASK LZO_MASK(DL_BITS) +#else +# define DL_SIZE LZO_USIZE(DL_BITS) +# define DL_MASK LZO_UMASK(DL_BITS) +#endif + + +#if (D_BITS != DL_BITS + DD_BITS) +# error "D_BITS does not match" +#endif +#if (D_BITS < 8 || D_BITS > 18) +# error "invalid D_BITS" +#endif +#if (DL_BITS < 8 || DL_BITS > 20) +# error "invalid DL_BITS" +#endif +#if (DD_BITS < 0 || DD_BITS > 6) +# error "invalid DD_BITS" +#endif + + +#if !defined(DL_MIN_LEN) +# define DL_MIN_LEN 3 +#endif +#if !defined(DL_SHIFT) +# define DL_SHIFT ((DL_BITS + (DL_MIN_LEN - 1)) / DL_MIN_LEN) +#endif + + + +/*********************************************************************** +// dictionary access +************************************************************************/ + +#define LZO_HASH_GZIP 1 +#define LZO_HASH_GZIP_INCREMENTAL 2 +#define LZO_HASH_LZO_INCREMENTAL_A 3 +#define LZO_HASH_LZO_INCREMENTAL_B 4 + +#if !defined(LZO_HASH) +# error "choose a hashing strategy" +#endif + + +#if (DL_MIN_LEN == 3) +# define _DV2_A(p,shift1,shift2) \ + (((( (lzo_uint32)((p)[0]) << shift1) ^ (p)[1]) << shift2) ^ (p)[2]) +# define _DV2_B(p,shift1,shift2) \ + (((( (lzo_uint32)((p)[2]) << shift1) ^ (p)[1]) << shift2) ^ (p)[0]) +# define _DV3_B(p,shift1,shift2,shift3) \ + ((_DV2_B((p)+1,shift1,shift2) << (shift3)) ^ (p)[0]) +#elif (DL_MIN_LEN == 2) +# define _DV2_A(p,shift1,shift2) \ + (( (lzo_uint32)(p[0]) << shift1) ^ p[1]) +# define _DV2_B(p,shift1,shift2) \ + (( (lzo_uint32)(p[1]) << shift1) ^ p[2]) +#else +# error "invalid DL_MIN_LEN" +#endif +#define _DV_A(p,shift) _DV2_A(p,shift,shift) +#define _DV_B(p,shift) _DV2_B(p,shift,shift) +#define DA2(p,s1,s2) \ + (((((lzo_uint32)((p)[2]) << (s2)) + (p)[1]) << (s1)) + (p)[0]) +#define DS2(p,s1,s2) \ + (((((lzo_uint32)((p)[2]) << (s2)) - (p)[1]) << (s1)) - (p)[0]) +#define DX2(p,s1,s2) \ + (((((lzo_uint32)((p)[2]) << (s2)) ^ (p)[1]) << (s1)) ^ (p)[0]) +#define DA3(p,s1,s2,s3) ((DA2((p)+1,s2,s3) << (s1)) + (p)[0]) +#define DS3(p,s1,s2,s3) ((DS2((p)+1,s2,s3) << (s1)) - (p)[0]) +#define DX3(p,s1,s2,s3) ((DX2((p)+1,s2,s3) << (s1)) ^ (p)[0]) +#define DMS(v,s) ((lzo_uint) (((v) & (D_MASK >> (s))) << (s))) +#define DM(v) DMS(v,0) + + + +#if (LZO_HASH == LZO_HASH_GZIP) + /* hash function like in gzip/zlib (deflate) */ +# define _DINDEX(dv,p) (_DV_A((p),DL_SHIFT)) + +#elif (LZO_HASH == LZO_HASH_GZIP_INCREMENTAL) + /* incremental hash like in gzip/zlib (deflate) */ +# define __LZO_HASH_INCREMENTAL +# define DVAL_FIRST(dv,p) dv = _DV_A((p),DL_SHIFT) +# define DVAL_NEXT(dv,p) dv = (((dv) << DL_SHIFT) ^ p[2]) +# define _DINDEX(dv,p) (dv) +# define DVAL_LOOKAHEAD DL_MIN_LEN + +#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_A) + /* incremental LZO hash version A */ +# define __LZO_HASH_INCREMENTAL +# define DVAL_FIRST(dv,p) dv = _DV_A((p),5) +# define DVAL_NEXT(dv,p) \ + dv ^= (lzo_uint32)(p[-1]) << (2*5); dv = (((dv) << 5) ^ p[2]) +# define _DINDEX(dv,p) ((0x9f5f * (dv)) >> 5) +# define DVAL_LOOKAHEAD DL_MIN_LEN + +#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_B) + /* incremental LZO hash version B */ +# define __LZO_HASH_INCREMENTAL +# define DVAL_FIRST(dv,p) dv = _DV_B((p),5) +# define DVAL_NEXT(dv,p) \ + dv ^= p[-1]; dv = (((dv) >> 5) ^ ((lzo_uint32)(p[2]) << (2*5))) +# define _DINDEX(dv,p) ((0x9f5f * (dv)) >> 5) +# define DVAL_LOOKAHEAD DL_MIN_LEN + +#else +# error "choose a hashing strategy" +#endif + + +#ifndef DINDEX +#define DINDEX(dv,p) ((lzo_uint)((_DINDEX(dv,p)) & DL_MASK) << DD_BITS) +#endif +#if !defined(DINDEX1) && defined(D_INDEX1) +#define DINDEX1 D_INDEX1 +#endif +#if !defined(DINDEX2) && defined(D_INDEX2) +#define DINDEX2 D_INDEX2 +#endif + + + +#if !defined(__LZO_HASH_INCREMENTAL) +# define DVAL_FIRST(dv,p) ((void) 0) +# define DVAL_NEXT(dv,p) ((void) 0) +# define DVAL_LOOKAHEAD 0 +#endif + + +#if !defined(DVAL_ASSERT) +#if defined(__LZO_HASH_INCREMENTAL) && !defined(NDEBUG) +static void DVAL_ASSERT(lzo_uint32 dv, const lzo_byte *p) +{ + lzo_uint32 df; + DVAL_FIRST(df,(p)); + assert(DINDEX(dv,p) == DINDEX(df,p)); +} +#else +# define DVAL_ASSERT(dv,p) ((void) 0) +#endif +#endif + + + +/*********************************************************************** +// dictionary updating +************************************************************************/ + +#if defined(LZO_DICT_USE_PTR) +# define DENTRY(p,in) (p) +# define GINDEX(m_pos,m_off,dict,dindex,in) m_pos = dict[dindex] +#else +# define DENTRY(p,in) ((lzo_uint) ((p)-(in))) +# define GINDEX(m_pos,m_off,dict,dindex,in) m_off = dict[dindex] +#endif + + +#if (DD_BITS == 0) + +# define UPDATE_D(dict,drun,dv,p,in) dict[ DINDEX(dv,p) ] = DENTRY(p,in) +# define UPDATE_I(dict,drun,index,p,in) dict[index] = DENTRY(p,in) +# define UPDATE_P(ptr,drun,p,in) (ptr)[0] = DENTRY(p,in) + +#else + +# define UPDATE_D(dict,drun,dv,p,in) \ + dict[ DINDEX(dv,p) + drun++ ] = DENTRY(p,in); drun &= DD_MASK +# define UPDATE_I(dict,drun,index,p,in) \ + dict[ (index) + drun++ ] = DENTRY(p,in); drun &= DD_MASK +# define UPDATE_P(ptr,drun,p,in) \ + (ptr) [ drun++ ] = DENTRY(p,in); drun &= DD_MASK + +#endif + + +/*********************************************************************** +// test for a match +************************************************************************/ + +#if defined(LZO_DICT_USE_PTR) + +/* m_pos is either NULL or a valid pointer */ +#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \ + (m_pos == NULL || (m_off = (lzo_moff_t) (ip - m_pos)) > max_offset) + +/* m_pos may point anywhere... */ +#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \ + (BOUNDS_CHECKING_OFF_IN_EXPR( \ + (PTR_LT(m_pos,in) || \ + (m_off = (lzo_moff_t) PTR_DIFF(ip,m_pos)) <= 0 || \ + m_off > max_offset) )) + +#else + +#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \ + (m_off == 0 || \ + ((m_off = (lzo_moff_t) ((ip)-(in)) - m_off) > max_offset) || \ + (m_pos = (ip) - (m_off), 0) ) + +#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \ + ((lzo_moff_t) ((ip)-(in)) <= m_off || \ + ((m_off = (lzo_moff_t) ((ip)-(in)) - m_off) > max_offset) || \ + (m_pos = (ip) - (m_off), 0) ) + +#endif + + +#if defined(LZO_DETERMINISTIC) +# define LZO_CHECK_MPOS LZO_CHECK_MPOS_DET +#else +# define LZO_CHECK_MPOS LZO_CHECK_MPOS_NON_DET +#endif + + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/lzo_dll.c b/DumpProto/lzo/lzo_dll.c new file mode 100644 index 0000000..7e1a755 --- /dev/null +++ b/DumpProto/lzo/lzo_dll.c @@ -0,0 +1,63 @@ +/* lzo_dll.c -- DLL initialization of the LZO library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "lzo_conf.h" + +#if defined(LZO_BUILD_DLL) + + +/*********************************************************************** +// Windows 16 bit + Watcom C + DLL +************************************************************************/ + +#if defined(__LZO_WIN16) && defined(__WATCOMC__) && defined(__SW_BD) + +/* don't pull in - we don't need it */ +#if 0 +#include +#endif + +#pragma off (unreferenced); +#if 0 && defined(WINVER) +BOOL FAR PASCAL LibMain ( HANDLE hInstance, WORD wDataSegment, + WORD wHeapSize, LPSTR lpszCmdLine ) +#else +int __far __pascal LibMain ( int a, short b, short c, long d ) +#endif +#pragma on (unreferenced); +{ + return 1; +} + +#endif + + +#endif /* defined(LZO_BUILD_DLL) */ + +/* +vi:ts=4:et +*/ diff --git a/DumpProto/lzo/lzo_init.c b/DumpProto/lzo/lzo_init.c new file mode 100644 index 0000000..0533247 --- /dev/null +++ b/DumpProto/lzo/lzo_init.c @@ -0,0 +1,570 @@ +/* lzo_init.c -- initialization of the LZO library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "lzo_conf.h" +#include "lzo_util.h" + + +#if 0 +# define IS_SIGNED(type) (((type) (1ul << (8 * sizeof(type) - 1))) < 0) +# define IS_UNSIGNED(type) (((type) (1ul << (8 * sizeof(type) - 1))) > 0) +#else +# define IS_SIGNED(type) (((type) (-1)) < ((type) 0)) +# define IS_UNSIGNED(type) (((type) (-1)) > ((type) 0)) +#endif + +#define IS_POWER_OF_2(x) (((x) & ((x) - 1)) == 0) + + +/*********************************************************************** +// Runtime check of the assumptions about the size of builtin types, +// memory model, byte order and other low-level constructs. +// +// We are really paranoid here - LZO should either fail (or crash) +// at startup or not at all. +// +// Because of inlining much of these functions evaluates to nothing. +************************************************************************/ + +static lzo_bool schedule_insns_bug(void); /* avoid inlining */ +static lzo_bool strength_reduce_bug(int *); /* avoid inlining */ + + +#if 0 || defined(LZO_DEBUG) +#include +static lzo_bool __lzo_assert_fail(const char *s, unsigned line) +{ +#if defined(__palmos__) + printf("LZO assertion failed in line %u: '%s'\n",line,s); +#else + fprintf(stderr,"LZO assertion failed in line %u: '%s'\n",line,s); +#endif + return 0; +} +# define __lzo_assert(x) ((x) ? 1 : __lzo_assert_fail(#x,__LINE__)) +#else +# define __lzo_assert(x) ((x) ? 1 : 0) +#endif + + +#undef COMPILE_TIME_ASSERT +#if 0 +# define COMPILE_TIME_ASSERT(expr) r &= __lzo_assert(expr) +#else +# define COMPILE_TIME_ASSERT(expr) LZO_COMPILE_TIME_ASSERT(expr) +#endif + + +/*********************************************************************** +// The next two functions should get completely optimized out of existance. +// Some assertions are redundant - but included for clarity. +************************************************************************/ + +static lzo_bool basic_integral_check(void) +{ + lzo_bool r = 1; + + /* paranoia */ + COMPILE_TIME_ASSERT(CHAR_BIT == 8); + COMPILE_TIME_ASSERT(sizeof(char) == 1); + COMPILE_TIME_ASSERT(sizeof(short) >= 2); + COMPILE_TIME_ASSERT(sizeof(long) >= 4); + COMPILE_TIME_ASSERT(sizeof(int) >= sizeof(short)); + COMPILE_TIME_ASSERT(sizeof(long) >= sizeof(int)); + + COMPILE_TIME_ASSERT(sizeof(lzo_uint) == sizeof(lzo_int)); + COMPILE_TIME_ASSERT(sizeof(lzo_uint32) == sizeof(lzo_int32)); + + COMPILE_TIME_ASSERT(sizeof(lzo_uint32) >= 4); + COMPILE_TIME_ASSERT(sizeof(lzo_uint32) >= sizeof(unsigned)); +#if defined(__LZO_STRICT_16BIT) + COMPILE_TIME_ASSERT(sizeof(lzo_uint) == 2); +#else + COMPILE_TIME_ASSERT(sizeof(lzo_uint) >= 4); + COMPILE_TIME_ASSERT(sizeof(lzo_uint) >= sizeof(unsigned)); +#endif + + /* paranoia - check header */ +#if (USHRT_MAX == 65535u) + COMPILE_TIME_ASSERT(sizeof(short) == 2); +#elif (USHRT_MAX == LZO_0xffffffffL) + COMPILE_TIME_ASSERT(sizeof(short) == 4); +#elif (USHRT_MAX >= LZO_0xffffffffL) + COMPILE_TIME_ASSERT(sizeof(short) > 4); +#endif +#if (UINT_MAX == 65535u) + COMPILE_TIME_ASSERT(sizeof(int) == 2); +#elif (UINT_MAX == LZO_0xffffffffL) + COMPILE_TIME_ASSERT(sizeof(int) == 4); +#elif (UINT_MAX >= LZO_0xffffffffL) + COMPILE_TIME_ASSERT(sizeof(int) > 4); +#endif +#if (ULONG_MAX == 65535ul) + COMPILE_TIME_ASSERT(sizeof(long) == 2); +#elif (ULONG_MAX == LZO_0xffffffffL) + COMPILE_TIME_ASSERT(sizeof(long) == 4); +#elif (ULONG_MAX >= LZO_0xffffffffL) + COMPILE_TIME_ASSERT(sizeof(long) > 4); +#endif + +#if defined(SIZEOF_UNSIGNED) + COMPILE_TIME_ASSERT(SIZEOF_UNSIGNED == sizeof(unsigned)); +#endif +#if defined(SIZEOF_UNSIGNED_LONG) + COMPILE_TIME_ASSERT(SIZEOF_UNSIGNED_LONG == sizeof(unsigned long)); +#endif +#if defined(SIZEOF_UNSIGNED_SHORT) + COMPILE_TIME_ASSERT(SIZEOF_UNSIGNED_SHORT == sizeof(unsigned short)); +#endif +#if !defined(__LZO_IN_MINILZO) +#if defined(SIZEOF_SIZE_T) + COMPILE_TIME_ASSERT(SIZEOF_SIZE_T == sizeof(size_t)); +#endif +#endif + + /* assert the signedness of our integral types */ + COMPILE_TIME_ASSERT(IS_UNSIGNED(unsigned char)); + COMPILE_TIME_ASSERT(IS_UNSIGNED(unsigned short)); + COMPILE_TIME_ASSERT(IS_UNSIGNED(unsigned)); + COMPILE_TIME_ASSERT(IS_UNSIGNED(unsigned long)); + COMPILE_TIME_ASSERT(IS_SIGNED(short)); + COMPILE_TIME_ASSERT(IS_SIGNED(int)); + COMPILE_TIME_ASSERT(IS_SIGNED(long)); + + COMPILE_TIME_ASSERT(IS_UNSIGNED(lzo_uint32)); + COMPILE_TIME_ASSERT(IS_UNSIGNED(lzo_uint)); + COMPILE_TIME_ASSERT(IS_SIGNED(lzo_int32)); + COMPILE_TIME_ASSERT(IS_SIGNED(lzo_int)); + + COMPILE_TIME_ASSERT(INT_MAX == LZO_STYPE_MAX(sizeof(int))); + COMPILE_TIME_ASSERT(UINT_MAX == LZO_UTYPE_MAX(sizeof(unsigned))); + COMPILE_TIME_ASSERT(LONG_MAX == LZO_STYPE_MAX(sizeof(long))); + COMPILE_TIME_ASSERT(ULONG_MAX == LZO_UTYPE_MAX(sizeof(unsigned long))); + COMPILE_TIME_ASSERT(SHRT_MAX == LZO_STYPE_MAX(sizeof(short))); + COMPILE_TIME_ASSERT(USHRT_MAX == LZO_UTYPE_MAX(sizeof(unsigned short))); + COMPILE_TIME_ASSERT(LZO_UINT32_MAX == LZO_UTYPE_MAX(sizeof(lzo_uint32))); + COMPILE_TIME_ASSERT(LZO_UINT_MAX == LZO_UTYPE_MAX(sizeof(lzo_uint))); +#if !defined(__LZO_IN_MINILZO) + COMPILE_TIME_ASSERT(SIZE_T_MAX == LZO_UTYPE_MAX(sizeof(size_t))); +#endif + + r &= __lzo_assert(LZO_BYTE(257) == 1); + + return r; +} + + +static lzo_bool basic_ptr_check(void) +{ + lzo_bool r = 1; + + COMPILE_TIME_ASSERT(sizeof(char *) >= sizeof(int)); + COMPILE_TIME_ASSERT(sizeof(lzo_byte *) >= sizeof(char *)); + + COMPILE_TIME_ASSERT(sizeof(lzo_voidp) == sizeof(lzo_byte *)); + COMPILE_TIME_ASSERT(sizeof(lzo_voidp) == sizeof(lzo_voidpp)); + COMPILE_TIME_ASSERT(sizeof(lzo_voidp) == sizeof(lzo_bytepp)); + COMPILE_TIME_ASSERT(sizeof(lzo_voidp) >= sizeof(lzo_uint)); + + COMPILE_TIME_ASSERT(sizeof(lzo_ptr_t) == sizeof(lzo_voidp)); + COMPILE_TIME_ASSERT(sizeof(lzo_ptr_t) == sizeof(lzo_sptr_t)); + COMPILE_TIME_ASSERT(sizeof(lzo_ptr_t) >= sizeof(lzo_uint)); + + COMPILE_TIME_ASSERT(sizeof(lzo_ptrdiff_t) >= 4); + COMPILE_TIME_ASSERT(sizeof(lzo_ptrdiff_t) >= sizeof(ptrdiff_t)); + + COMPILE_TIME_ASSERT(sizeof(ptrdiff_t) >= sizeof(size_t)); + COMPILE_TIME_ASSERT(sizeof(lzo_ptrdiff_t) >= sizeof(lzo_uint)); + +#if defined(SIZEOF_CHAR_P) + COMPILE_TIME_ASSERT(SIZEOF_CHAR_P == sizeof(char *)); +#endif +#if defined(SIZEOF_PTRDIFF_T) + COMPILE_TIME_ASSERT(SIZEOF_PTRDIFF_T == sizeof(ptrdiff_t)); +#endif + + /* assert the signedness of our integral types */ + COMPILE_TIME_ASSERT(IS_SIGNED(ptrdiff_t)); + COMPILE_TIME_ASSERT(IS_UNSIGNED(size_t)); + COMPILE_TIME_ASSERT(IS_SIGNED(lzo_ptrdiff_t)); + COMPILE_TIME_ASSERT(IS_SIGNED(lzo_sptr_t)); + COMPILE_TIME_ASSERT(IS_UNSIGNED(lzo_ptr_t)); + COMPILE_TIME_ASSERT(IS_UNSIGNED(lzo_moff_t)); + + return r; +} + + +/*********************************************************************** +// +************************************************************************/ + +static lzo_bool ptr_check(void) +{ + lzo_bool r = 1; + int i; + char _wrkmem[10 * sizeof(lzo_byte *) + sizeof(lzo_full_align_t)]; + lzo_bytep wrkmem; + lzo_bytepp dict; + unsigned char x[4 * sizeof(lzo_full_align_t)]; + long d; + lzo_full_align_t a; + lzo_full_align_t u; + + for (i = 0; i < (int) sizeof(x); i++) + x[i] = LZO_BYTE(i); + + wrkmem = LZO_PTR_ALIGN_UP((lzo_byte *)_wrkmem,sizeof(lzo_full_align_t)); + +#if 0 + dict = (lzo_bytepp) wrkmem; +#else + /* Avoid a compiler warning on architectures that + * do not allow unaligned access. */ + u.a_lzo_bytep = wrkmem; dict = u.a_lzo_bytepp; +#endif + + d = (long) ((const lzo_bytep) dict - (const lzo_bytep) _wrkmem); + r &= __lzo_assert(d >= 0); + r &= __lzo_assert(d < (long) sizeof(lzo_full_align_t)); + + memset(&a,0,sizeof(a)); + r &= __lzo_assert(a.a_lzo_voidp == NULL); + + memset(&a,0xff,sizeof(a)); + r &= __lzo_assert(a.a_ushort == USHRT_MAX); + r &= __lzo_assert(a.a_uint == UINT_MAX); + r &= __lzo_assert(a.a_ulong == ULONG_MAX); + r &= __lzo_assert(a.a_lzo_uint == LZO_UINT_MAX); + r &= __lzo_assert(a.a_lzo_uint32 == LZO_UINT32_MAX); + + /* sanity check of the memory model */ + if (r == 1) + { + for (i = 0; i < 8; i++) + r &= __lzo_assert((const lzo_voidp) (&dict[i]) == (const lzo_voidp) (&wrkmem[i * sizeof(lzo_byte *)])); + } + + /* check BZERO8_PTR and that NULL == 0 */ + memset(&a,0,sizeof(a)); + r &= __lzo_assert(a.a_char_p == NULL); + r &= __lzo_assert(a.a_lzo_bytep == NULL); + r &= __lzo_assert(NULL == (void *)0); + if (r == 1) + { + for (i = 0; i < 10; i++) + dict[i] = wrkmem; + BZERO8_PTR(dict+1,sizeof(dict[0]),8); + r &= __lzo_assert(dict[0] == wrkmem); + for (i = 1; i < 9; i++) + r &= __lzo_assert(dict[i] == NULL); + r &= __lzo_assert(dict[9] == wrkmem); + } + + /* check that the pointer constructs work as expected */ + if (r == 1) + { + unsigned k = 1; + const unsigned n = (unsigned) sizeof(lzo_uint32); + lzo_byte *p0; + lzo_byte *p1; + + k += __lzo_align_gap(&x[k],n); + p0 = (lzo_bytep) &x[k]; +#if defined(PTR_LINEAR) + r &= __lzo_assert((PTR_LINEAR(p0) & (n-1)) == 0); +#else + r &= __lzo_assert(n == 4); + r &= __lzo_assert(PTR_ALIGNED_4(p0)); +#endif + + r &= __lzo_assert(k >= 1); + p1 = (lzo_bytep) &x[1]; + r &= __lzo_assert(PTR_GE(p0,p1)); + + r &= __lzo_assert(k < 1+n); + p1 = (lzo_bytep) &x[1+n]; + r &= __lzo_assert(PTR_LT(p0,p1)); + + /* now check that aligned memory access doesn't core dump */ + if (r == 1) + { + lzo_uint32 v0, v1; +#if 0 + v0 = * (lzo_uint32 *) &x[k]; + v1 = * (lzo_uint32 *) &x[k+n]; +#else + /* Avoid compiler warnings on architectures that + * do not allow unaligned access. */ + u.a_uchar_p = &x[k]; + v0 = *u.a_lzo_uint32_p; + u.a_uchar_p = &x[k+n]; + v1 = *u.a_lzo_uint32_p; +#endif + r &= __lzo_assert(v0 > 0); + r &= __lzo_assert(v1 > 0); + } + } + + return r; +} + + +/*********************************************************************** +// +************************************************************************/ + +LZO_PUBLIC(int) +_lzo_config_check(void) +{ + lzo_bool r = 1; + int i; + union { + lzo_uint32 a; + unsigned short b; + lzo_uint32 aa[4]; + unsigned char x[4*sizeof(lzo_full_align_t)]; + } u; + + /* check that the compiler correctly casts signed to unsigned */ + COMPILE_TIME_ASSERT( (int) ((unsigned char) ((signed char) -1)) == 255); + /* check that the compiler correctly promotes integrals */ + COMPILE_TIME_ASSERT( (((unsigned char)128) << (int)(8*sizeof(int)-8)) < 0); + +#if 0 + /* paranoia - the following is guaranteed by definition anyway */ + r &= __lzo_assert((const void *)&u == (const void *)&u.a); + r &= __lzo_assert((const void *)&u == (const void *)&u.b); + r &= __lzo_assert((const void *)&u == (const void *)&u.x[0]); + r &= __lzo_assert((const void *)&u == (const void *)&u.aa[0]); +#endif + + r &= basic_integral_check(); + r &= basic_ptr_check(); + if (r != 1) + return LZO_E_ERROR; + + u.a = 0; u.b = 0; + for (i = 0; i < (int) sizeof(u.x); i++) + u.x[i] = LZO_BYTE(i); + + /* check LZO_BYTE_ORDER */ +#if defined(LZO_BYTE_ORDER) + if (r == 1) + { +# if (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN) + lzo_uint32 a = (lzo_uint32) (u.a & LZO_0xffffffffL); + unsigned short b = (unsigned short) (u.b & 0xffff); + r &= __lzo_assert(a == 0x03020100L); + r &= __lzo_assert(b == 0x0100); +# elif (LZO_BYTE_ORDER == LZO_BIG_ENDIAN) + lzo_uint32 a = u.a >> (8 * sizeof(u.a) - 32); + unsigned short b = u.b >> (8 * sizeof(u.b) - 16); + r &= __lzo_assert(a == 0x00010203L); + r &= __lzo_assert(b == 0x0001); +# else +# error "invalid LZO_BYTE_ORDER" +# endif + } +#endif + + /* check that unaligned memory access works as expected */ +#if defined(LZO_UNALIGNED_OK_2) + COMPILE_TIME_ASSERT(sizeof(short) == 2); + if (r == 1) + { + unsigned short b[4]; + + for (i = 0; i < 4; i++) + b[i] = * (const unsigned short *) &u.x[i]; + +# if (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN) + r &= __lzo_assert(b[0] == 0x0100); + r &= __lzo_assert(b[1] == 0x0201); + r &= __lzo_assert(b[2] == 0x0302); + r &= __lzo_assert(b[3] == 0x0403); +# elif (LZO_BYTE_ORDER == LZO_BIG_ENDIAN) + r &= __lzo_assert(b[0] == 0x0001); + r &= __lzo_assert(b[1] == 0x0102); + r &= __lzo_assert(b[2] == 0x0203); + r &= __lzo_assert(b[3] == 0x0304); +# endif + } +#endif + +#if defined(LZO_UNALIGNED_OK_4) + COMPILE_TIME_ASSERT(sizeof(lzo_uint32) == 4); + if (r == 1) + { + lzo_uint32 a[4]; + + for (i = 0; i < 4; i++) + a[i] = * (const lzo_uint32 *) &u.x[i]; + +# if (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN) + r &= __lzo_assert(a[0] == 0x03020100L); + r &= __lzo_assert(a[1] == 0x04030201L); + r &= __lzo_assert(a[2] == 0x05040302L); + r &= __lzo_assert(a[3] == 0x06050403L); +# elif (LZO_BYTE_ORDER == LZO_BIG_ENDIAN) + r &= __lzo_assert(a[0] == 0x00010203L); + r &= __lzo_assert(a[1] == 0x01020304L); + r &= __lzo_assert(a[2] == 0x02030405L); + r &= __lzo_assert(a[3] == 0x03040506L); +# endif + } +#endif + +#if defined(LZO_ALIGNED_OK_4) + COMPILE_TIME_ASSERT(sizeof(lzo_uint32) == 4); +#endif + + COMPILE_TIME_ASSERT(lzo_sizeof_dict_t == sizeof(lzo_dict_t)); + + /* save space and don't require linking in the lzo_adler32() function */ +#if defined(__LZO_IN_MINLZO) + /* check the lzo_adler32() function */ + if (r == 1) + { + lzo_uint32 adler; + adler = lzo_adler32(0, NULL, 0); + adler = lzo_adler32(adler, lzo_copyright(), 200); + r &= __lzo_assert(adler == 0xc76f1751L); + } +#endif + + /* check for the gcc schedule-insns optimization bug */ + if (r == 1) + { + r &= __lzo_assert(!schedule_insns_bug()); + } + + /* check for the gcc strength-reduce optimization bug */ + if (r == 1) + { + static int x[3]; + static unsigned xn = 3; + register unsigned j; + + for (j = 0; j < xn; j++) + x[j] = (int)j - 3; + r &= __lzo_assert(!strength_reduce_bug(x)); + } + + /* now for the low-level pointer checks */ + if (r == 1) + { + r &= ptr_check(); + } + + return r == 1 ? LZO_E_OK : LZO_E_ERROR; +} + + +static lzo_bool schedule_insns_bug(void) +{ +#if defined(__LZO_CHECKER) + /* for some reason checker complains about uninitialized memory access */ + return 0; +#else + const int clone[] = {1, 2, 0}; + const int *q; + q = clone; + return (*q) ? 0 : 1; +#endif +} + + +static lzo_bool strength_reduce_bug(int *x) +{ + return x[0] != -3 || x[1] != -2 || x[2] != -1; +} + + +#undef COMPILE_TIME_ASSERT + + +/*********************************************************************** +// +************************************************************************/ + +int __lzo_init_done = 0; + +LZO_PUBLIC(int) +__lzo_init2(unsigned v, int s1, int s2, int s3, int s4, int s5, + int s6, int s7, int s8, int s9) +{ + int r; + + __lzo_init_done = 1; + + if (v == 0) + return LZO_E_ERROR; + + r = (s1 == -1 || s1 == (int) sizeof(short)) && + (s2 == -1 || s2 == (int) sizeof(int)) && + (s3 == -1 || s3 == (int) sizeof(long)) && + (s4 == -1 || s4 == (int) sizeof(lzo_uint32)) && + (s5 == -1 || s5 == (int) sizeof(lzo_uint)) && + (s6 == -1 || s6 == (int) lzo_sizeof_dict_t) && + (s7 == -1 || s7 == (int) sizeof(char *)) && + (s8 == -1 || s8 == (int) sizeof(lzo_voidp)) && + (s9 == -1 || s9 == (int) sizeof(lzo_compress_t)); + if (!r) + return LZO_E_ERROR; + + r = _lzo_config_check(); + if (r != LZO_E_OK) + return r; + + return r; +} + + +/*********************************************************************** +// backward compatibility with v1.01 +************************************************************************/ + +#if !defined(__LZO_IN_MINILZO) + +LZO_EXTERN(int) +__lzo_init(unsigned v,int s1,int s2,int s3,int s4,int s5,int s6,int s7); + +LZO_PUBLIC(int) +__lzo_init(unsigned v,int s1,int s2,int s3,int s4,int s5,int s6,int s7) +{ + if (v == 0 || v > 0x1010) + return LZO_E_ERROR; + return __lzo_init2(v,s1,s2,s3,s4,s5,-1,-1,s6,s7); +} + +#endif + + +/* +vi:ts=4:et +*/ diff --git a/DumpProto/lzo/lzo_mchw.ch b/DumpProto/lzo/lzo_mchw.ch new file mode 100644 index 0000000..fe32f7d --- /dev/null +++ b/DumpProto/lzo/lzo_mchw.ch @@ -0,0 +1,230 @@ +/* lzo_mchw.ch -- matching functions using a window + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + + + +/*********************************************************************** +// +************************************************************************/ + +typedef struct +{ + int init; + + lzo_uint look; /* bytes in lookahead buffer */ + + lzo_uint m_len; + lzo_uint m_off; + + lzo_uint last_m_len; + lzo_uint last_m_off; + + const lzo_byte *bp; + const lzo_byte *ip; + const lzo_byte *in; + const lzo_byte *in_end; + lzo_byte *out; + + lzo_progress_callback_t cb; + + lzo_uint textsize; /* text size counter */ + lzo_uint codesize; /* code size counter */ + lzo_uint printcount; /* counter for reporting progress every 1K bytes */ + + /* some stats */ + unsigned long lit_bytes; + unsigned long match_bytes; + unsigned long rep_bytes; + unsigned long lazy; + +#if defined(LZO1B) + lzo_uint r1_m_len; + + /* some stats */ + unsigned long r1_r, m3_r, m2_m, m3_m; +#endif + +#if defined(LZO1C) + lzo_uint r1_m_len; + lzo_byte *m3; + + /* some stats */ + unsigned long r1_r, m3_r, m2_m, m3_m; +#endif + +#if defined(LZO1F) + lzo_uint r1_lit; + lzo_uint r1_m_len; + + /* some stats */ + unsigned long r1_r, m2_m, m3_m; +#endif + +#if defined(LZO1X) || defined(LZO1Y) || defined(LZO1Z) + lzo_uint r1_lit; + lzo_uint r1_m_len; + + /* some stats */ + unsigned long m1a_m, m1b_m, m2_m, m3_m, m4_m; + unsigned long lit1_r, lit2_r, lit3_r; +#endif + +#if defined(LZO2A) + /* some stats */ + unsigned long m1, m2, m3, m4; +#endif +} +LZO_COMPRESS_T; + + + +#if defined(__PUREC__) +/* the cast is needed to work around a bug in Pure C (Atari ST) */ +#define getbyte(c) ((c).ip < (c).in_end ? (unsigned) *((c).ip)++ : (-1)) +#else +#define getbyte(c) ((c).ip < (c).in_end ? *((c).ip)++ : (-1)) +#endif + +#include "lzo_swd.ch" + + + +/*********************************************************************** +// +************************************************************************/ + +static int +init_match ( LZO_COMPRESS_T *c, lzo_swd_t *s, + const lzo_byte *dict, lzo_uint dict_len, + lzo_uint32 flags ) +{ + int r; + + assert(!c->init); + c->init = 1; + + s->c = c; + + c->last_m_len = c->last_m_off = 0; + + c->textsize = c->codesize = c->printcount = 0; + c->lit_bytes = c->match_bytes = c->rep_bytes = 0; + c->lazy = 0; + + r = swd_init(s,dict,dict_len); + if (r != 0) + return r; + + s->use_best_off = (flags & 1) ? 1 : 0; + return r; +} + + +/*********************************************************************** +// +************************************************************************/ + +static int +find_match ( LZO_COMPRESS_T *c, lzo_swd_t *s, + lzo_uint this_len, lzo_uint skip ) +{ + assert(c->init); + + if (skip > 0) + { + assert(this_len >= skip); + swd_accept(s, this_len - skip); + c->textsize += this_len - skip + 1; + } + else + { + assert(this_len <= 1); + c->textsize += this_len - skip; + } + + s->m_len = 1; + s->m_len = THRESHOLD; +#ifdef SWD_BEST_OFF + if (s->use_best_off) + memset(s->best_pos,0,sizeof(s->best_pos)); +#endif + swd_findbest(s); + c->m_len = s->m_len; + c->m_off = s->m_off; + + swd_getbyte(s); + + if (s->b_char < 0) + { + c->look = 0; + c->m_len = 0; + swd_exit(s); + } + else + { + c->look = s->look + 1; + } + c->bp = c->ip - c->look; + +#if 0 + /* brute force match search */ + if (c->m_len > THRESHOLD && c->m_len + 1 <= c->look) + { + const lzo_byte *ip = c->bp; + const lzo_byte *m = c->bp - c->m_off; + const lzo_byte *in = c->in; + + if (ip - in > N) + in = ip - N; + for (;;) + { + while (*in != *ip) + in++; + if (in == ip) + break; + if (in != m) + if (memcmp(in,ip,c->m_len+1) == 0) + printf("%p %p %p %5d\n",in,ip,m,c->m_len); + in++; + } + } +#endif + + if (c->cb && c->textsize > c->printcount) + { + (*c->cb)(c->textsize,c->codesize); + c->printcount += 1024; + } + + return LZO_E_OK; +} + + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/lzo_ptr.c b/DumpProto/lzo/lzo_ptr.c new file mode 100644 index 0000000..536a0c8 --- /dev/null +++ b/DumpProto/lzo/lzo_ptr.c @@ -0,0 +1,80 @@ +/* lzo_ptr.c -- low-level pointer constructs + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "lzo_conf.h" + + +/*********************************************************************** +// +************************************************************************/ + +LZO_PUBLIC(lzo_ptr_t) +__lzo_ptr_linear(const lzo_voidp ptr) +{ + lzo_ptr_t p; + +#if defined(__LZO_DOS16) || defined(__LZO_WIN16) + p = (((lzo_ptr_t)(_FP_SEG(ptr))) << (16 - __LZO_HShift)) + (_FP_OFF(ptr)); +#else + p = PTR_LINEAR(ptr); +#endif + + return p; +} + + +/*********************************************************************** +// +************************************************************************/ + +LZO_PUBLIC(unsigned) +__lzo_align_gap(const lzo_voidp ptr, lzo_uint size) +{ + lzo_ptr_t p, s, n; + + assert(size > 0); + + p = __lzo_ptr_linear(ptr); + s = (lzo_ptr_t) (size - 1); +#if 0 + assert((size & (size - 1)) == 0); + n = ((p + s) & ~s) - p; +#else + n = (((p + s) / size) * size) - p; +#endif + + assert((long)n >= 0); + assert(n <= s); + + return (unsigned)n; +} + + + +/* +vi:ts=4:et +*/ diff --git a/DumpProto/lzo/lzo_ptr.h b/DumpProto/lzo/lzo_ptr.h new file mode 100644 index 0000000..2f03cc9 --- /dev/null +++ b/DumpProto/lzo/lzo_ptr.h @@ -0,0 +1,207 @@ +/* lzo_ptr.h -- low-level pointer constructs + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the library and is subject + to change. + */ + + +#ifndef __LZO_PTR_H +#define __LZO_PTR_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* This is the lowest part of the LZO library. + * It deals with pointer representations at bit level. + */ + + +/*********************************************************************** +// Includes +************************************************************************/ + +#if defined(__LZO_DOS16) || defined(__LZO_WIN16) +# include +# if 1 && defined(__WATCOMC__) +# include + __LZO_EXTERN_C unsigned char _HShift; +# define __LZO_HShift _HShift +# elif 1 && defined(_MSC_VER) + __LZO_EXTERN_C unsigned short __near _AHSHIFT; +# define __LZO_HShift ((unsigned) &_AHSHIFT) +# elif defined(__LZO_WIN16) +# define __LZO_HShift 3 +# else +# define __LZO_HShift 12 +# endif +# if !defined(_FP_SEG) && defined(FP_SEG) +# define _FP_SEG FP_SEG +# endif +# if !defined(_FP_OFF) && defined(FP_OFF) +# define _FP_OFF FP_OFF +# endif +#endif + + +/*********************************************************************** +// Integral types +************************************************************************/ + +/* ptrdiff_t */ +#if !defined(lzo_ptrdiff_t) +# if (UINT_MAX >= LZO_0xffffffffL) + typedef ptrdiff_t lzo_ptrdiff_t; +# else + typedef long lzo_ptrdiff_t; +# endif +#endif + + +/* Integral types that have *exactly* the same number of bits as a lzo_voidp */ +#if !defined(__LZO_HAVE_PTR_T) +# if defined(lzo_ptr_t) +# define __LZO_HAVE_PTR_T +# endif +#endif +#if !defined(__LZO_HAVE_PTR_T) +# if defined(SIZEOF_CHAR_P) && defined(SIZEOF_UNSIGNED_LONG) +# if (SIZEOF_CHAR_P == SIZEOF_UNSIGNED_LONG) + typedef unsigned long lzo_ptr_t; + typedef long lzo_sptr_t; +# define __LZO_HAVE_PTR_T +# endif +# endif +#endif +#if !defined(__LZO_HAVE_PTR_T) +# if defined(SIZEOF_CHAR_P) && defined(SIZEOF_UNSIGNED) +# if (SIZEOF_CHAR_P == SIZEOF_UNSIGNED) + typedef unsigned int lzo_ptr_t; + typedef int lzo_sptr_t; +# define __LZO_HAVE_PTR_T +# endif +# endif +#endif +#if !defined(__LZO_HAVE_PTR_T) +# if defined(SIZEOF_CHAR_P) && defined(SIZEOF_UNSIGNED_SHORT) +# if (SIZEOF_CHAR_P == SIZEOF_UNSIGNED_SHORT) + typedef unsigned short lzo_ptr_t; + typedef short lzo_sptr_t; +# define __LZO_HAVE_PTR_T +# endif +# endif +#endif +#if !defined(__LZO_HAVE_PTR_T) +# if defined(LZO_HAVE_CONFIG_H) || defined(SIZEOF_CHAR_P) +# error "no suitable type for lzo_ptr_t" +# else + typedef unsigned long lzo_ptr_t; + typedef long lzo_sptr_t; +# define __LZO_HAVE_PTR_T +# endif +#endif + + +/*********************************************************************** +// +************************************************************************/ + +/* Always use the integral version for pointer comparisions. + * + * Note that this only works if the representation and ordering + * of the pointer and the integral is the same (at bit level). + */ + +#if defined(__LZO_DOS16) || defined(__LZO_WIN16) +#define PTR(a) ((lzo_bytep) (a)) +/* only need the low bits of the pointer -> offset is ok */ +#define PTR_ALIGNED_4(a) ((_FP_OFF(a) & 3) == 0) +#define PTR_ALIGNED2_4(a,b) (((_FP_OFF(a) | _FP_OFF(b)) & 3) == 0) +#else +#define PTR(a) ((lzo_ptr_t) (a)) +#define PTR_LINEAR(a) PTR(a) +#define PTR_ALIGNED_4(a) ((PTR_LINEAR(a) & 3) == 0) +#define PTR_ALIGNED_8(a) ((PTR_LINEAR(a) & 7) == 0) +#define PTR_ALIGNED2_4(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 3) == 0) +#define PTR_ALIGNED2_8(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 7) == 0) +#endif + +#define PTR_LT(a,b) (PTR(a) < PTR(b)) +#define PTR_GE(a,b) (PTR(a) >= PTR(b)) +#define PTR_DIFF(a,b) ((lzo_ptrdiff_t) (PTR(a) - PTR(b))) +#define pd(a,b) ((lzo_uint) ((a)-(b))) + + +LZO_EXTERN(lzo_ptr_t) +__lzo_ptr_linear(const lzo_voidp ptr); + + +typedef union +{ + char a_char; + unsigned char a_uchar; + short a_short; + unsigned short a_ushort; + int a_int; + unsigned int a_uint; + long a_long; + unsigned long a_ulong; + lzo_int a_lzo_int; + lzo_uint a_lzo_uint; + lzo_int32 a_lzo_int32; + lzo_uint32 a_lzo_uint32; + ptrdiff_t a_ptrdiff_t; + lzo_ptrdiff_t a_lzo_ptrdiff_t; + lzo_ptr_t a_lzo_ptr_t; + lzo_voidp a_lzo_voidp; + void * a_void_p; + lzo_bytep a_lzo_bytep; + lzo_bytepp a_lzo_bytepp; + lzo_uintp a_lzo_uintp; + lzo_uint * a_lzo_uint_p; + lzo_uint32p a_lzo_uint32p; + lzo_uint32 * a_lzo_uint32_p; + unsigned char * a_uchar_p; + char * a_char_p; +} +lzo_full_align_t; + + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/lzo_str.c b/DumpProto/lzo/lzo_str.c new file mode 100644 index 0000000..c16b367 --- /dev/null +++ b/DumpProto/lzo/lzo_str.c @@ -0,0 +1,127 @@ +/* lzo_str.c -- string functions for the the LZO library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "lzo_conf.h" + + +/*********************************************************************** +// slow but portable stuff, only used in assertions +************************************************************************/ + +LZO_PUBLIC(int) +lzo_memcmp(const lzo_voidp s1, const lzo_voidp s2, lzo_uint len) +{ +#if (LZO_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMCMP) + return memcmp(s1,s2,len); +#else + const lzo_byte *p1 = (const lzo_byte *) s1; + const lzo_byte *p2 = (const lzo_byte *) s2; + int d; + + if (len > 0) do + { + d = *p1 - *p2; + if (d != 0) + return d; + p1++; + p2++; + } + while (--len > 0); + return 0; +#endif +} + + +LZO_PUBLIC(lzo_voidp) +lzo_memcpy(lzo_voidp dest, const lzo_voidp src, lzo_uint len) +{ +#if (LZO_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMCPY) + return memcpy(dest,src,len); +#else + lzo_byte *p1 = (lzo_byte *) dest; + const lzo_byte *p2 = (const lzo_byte *) src; + + if (len <= 0 || p1 == p2) + return dest; + do + *p1++ = *p2++; + while (--len > 0); + return dest; +#endif +} + + +LZO_PUBLIC(lzo_voidp) +lzo_memmove(lzo_voidp dest, const lzo_voidp src, lzo_uint len) +{ +#if (LZO_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMMOVE) + return memmove(dest,src,len); +#else + lzo_byte *p1 = (lzo_byte *) dest; + const lzo_byte *p2 = (const lzo_byte *) src; + + if (len <= 0 || p1 == p2) + return dest; + + if (p1 < p2) + { + do + *p1++ = *p2++; + while (--len > 0); + } + else + { + p1 += len; + p2 += len; + do + *--p1 = *--p2; + while (--len > 0); + } + return dest; +#endif +} + + +LZO_PUBLIC(lzo_voidp) +lzo_memset(lzo_voidp s, int c, lzo_uint len) +{ +#if (LZO_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMSET) + return memset(s,c,len); +#else + lzo_byte *p = (lzo_byte *) s; + + if (len > 0) do + *p++ = LZO_BYTE(c); + while (--len > 0); + return s; +#endif +} + + +/* +vi:ts=4:et +*/ diff --git a/DumpProto/lzo/lzo_swd.ch b/DumpProto/lzo/lzo_swd.ch new file mode 100644 index 0000000..2921b95 --- /dev/null +++ b/DumpProto/lzo/lzo_swd.ch @@ -0,0 +1,649 @@ +/* lzo_swd.ch -- sliding window dictionary + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#if (LZO_UINT_MAX < LZO_0xffffffffL) +# error "LZO_UINT_MAX" +#endif + + +/*********************************************************************** +// +************************************************************************/ + +#ifndef SWD_N +# define SWD_N N +#endif +#ifndef SWD_F +# define SWD_F F +#endif +#ifndef SWD_THRESHOLD +# define SWD_THRESHOLD THRESHOLD +#endif + +/* unsigned type for dictionary access - don't waste memory here */ +#if (SWD_N + SWD_F + SWD_F < USHRT_MAX) + typedef unsigned short swd_uint; +# define SWD_UINT_MAX USHRT_MAX +#else + typedef lzo_uint swd_uint; +# define SWD_UINT_MAX LZO_UINT_MAX +#endif +#define SWD_UINT(x) ((swd_uint)(x)) + + +#ifndef SWD_HSIZE +# define SWD_HSIZE 16384 +#endif +#ifndef SWD_MAX_CHAIN +# define SWD_MAX_CHAIN 2048 +#endif + +#if !defined(HEAD3) +#if 1 +# define HEAD3(b,p) \ + (((0x9f5f*(((((lzo_uint32)b[p]<<5)^b[p+1])<<5)^b[p+2]))>>5) & (SWD_HSIZE-1)) +#else +# define HEAD3(b,p) \ + (((0x9f5f*(((((lzo_uint32)b[p+2]<<5)^b[p+1])<<5)^b[p]))>>5) & (SWD_HSIZE-1)) +#endif +#endif + +#if (SWD_THRESHOLD == 1) && !defined(HEAD2) +# if 1 && defined(LZO_UNALIGNED_OK_2) +# define HEAD2(b,p) (* (lzo_ushortp) &(b[p])) +# else +# define HEAD2(b,p) (b[p] ^ ((unsigned)b[p+1]<<8)) +# endif +# define NIL2 SWD_UINT_MAX +#endif + + +typedef struct +{ +/* public - "built-in" */ + lzo_uint n; + lzo_uint f; + lzo_uint threshold; + +/* public - configuration */ + lzo_uint max_chain; + lzo_uint nice_length; + lzo_bool use_best_off; + lzo_uint lazy_insert; + +/* public - output */ + lzo_uint m_len; + lzo_uint m_off; + lzo_uint look; + int b_char; +#if defined(SWD_BEST_OFF) + lzo_uint best_off[ SWD_BEST_OFF ]; +#endif + +/* semi public */ + LZO_COMPRESS_T *c; + lzo_uint m_pos; +#if defined(SWD_BEST_OFF) + lzo_uint best_pos[ SWD_BEST_OFF ]; +#endif + +/* private */ + const lzo_byte *dict; + const lzo_byte *dict_end; + lzo_uint dict_len; + +/* private */ + lzo_uint ip; /* input pointer (lookahead) */ + lzo_uint bp; /* buffer pointer */ + lzo_uint rp; /* remove pointer */ + lzo_uint b_size; + + unsigned char *b_wrap; + + lzo_uint node_count; + lzo_uint first_rp; + +#if defined(__LZO_CHECKER) + /* malloc arrays of the exact size to detect any overrun */ + unsigned char *b; + swd_uint *head3; + swd_uint *succ3; + swd_uint *best3; + swd_uint *llen3; +#ifdef HEAD2 + swd_uint *head2; +#endif +#else + unsigned char b [ SWD_N + SWD_F + SWD_F ]; + swd_uint head3 [ SWD_HSIZE ]; + swd_uint succ3 [ SWD_N + SWD_F ]; + swd_uint best3 [ SWD_N + SWD_F ]; + swd_uint llen3 [ SWD_HSIZE ]; +#ifdef HEAD2 + swd_uint head2 [ 65536L ]; +#endif +#endif +} +lzo_swd_t; + + +/* Access macro for head3. + * head3[key] may be uninitialized, but then its value will never be used. + */ +#if defined(__LZO_CHECKER) +# define s_head3(s,key) \ + ((s->llen3[key] == 0) ? SWD_UINT_MAX : s->head3[key]) +#else +# define s_head3(s,key) s->head3[key] +#endif + + +/*********************************************************************** +// +************************************************************************/ + +static +void swd_initdict(lzo_swd_t *s, const lzo_byte *dict, lzo_uint dict_len) +{ + s->dict = s->dict_end = NULL; + s->dict_len = 0; + + if (!dict || dict_len <= 0) + return; + if (dict_len > s->n) + { + dict += dict_len - s->n; + dict_len = s->n; + } + + s->dict = dict; + s->dict_len = dict_len; + s->dict_end = dict + dict_len; + memcpy(s->b,dict,dict_len); + s->ip = dict_len; +} + + +static +void swd_insertdict(lzo_swd_t *s, lzo_uint node, lzo_uint len) +{ + lzo_uint key; + + s->node_count = s->n - len; + s->first_rp = node; + + while (len-- > 0) + { + key = HEAD3(s->b,node); + s->succ3[node] = s_head3(s,key); + s->head3[key] = SWD_UINT(node); + s->best3[node] = SWD_UINT(s->f + 1); + s->llen3[key]++; + assert(s->llen3[key] <= SWD_N); + +#ifdef HEAD2 + key = HEAD2(s->b,node); + s->head2[key] = SWD_UINT(node); +#endif + + node++; + } +} + + +/*********************************************************************** +// +************************************************************************/ + +static +int swd_init(lzo_swd_t *s, const lzo_byte *dict, lzo_uint dict_len) +{ + lzo_uint i = 0; + int c = 0; + +#if defined(__LZO_CHECKER) + s->b = malloc(SWD_N + SWD_F + SWD_F); + s->head3 = malloc(sizeof(swd_uint) * SWD_HSIZE); + s->succ3 = malloc(sizeof(swd_uint) * (SWD_N + SWD_F)); + s->best3 = malloc(sizeof(swd_uint) * (SWD_N + SWD_F)); + s->llen3 = malloc(sizeof(swd_uint) * SWD_HSIZE); +#ifdef HEAD2 + s->head2 = malloc(sizeof(swd_uint) * 65536L); +#endif +#endif + + s->n = SWD_N; + s->f = SWD_F; + s->threshold = SWD_THRESHOLD; + + /* defaults */ + s->max_chain = SWD_MAX_CHAIN; + s->nice_length = SWD_F; + s->use_best_off = 0; + s->lazy_insert = 0; + + s->b_size = s->n + s->f; + if (2 * s->f >= s->n || s->b_size + s->f >= SWD_UINT_MAX) + return LZO_E_ERROR; + s->b_wrap = s->b + s->b_size; + s->node_count = s->n; + + memset(s->llen3, 0, sizeof(s->llen3[0]) * SWD_HSIZE); +#ifdef HEAD2 +#if 1 + memset(s->head2, 0xff, sizeof(s->head2[0]) * 65536L); + assert(s->head2[0] == NIL2); +#else + for (i = 0; i < 65536L; i++) + s->head2[i] = NIL2; +#endif +#endif + + s->ip = 0; + swd_initdict(s,dict,dict_len); + s->bp = s->ip; + s->first_rp = s->ip; + + assert(s->ip + s->f <= s->b_size); +#if 1 + s->look = (lzo_uint) (s->c->in_end - s->c->ip); + if (s->look > 0) + { + if (s->look > s->f) + s->look = s->f; + memcpy(&s->b[s->ip],s->c->ip,s->look); + s->c->ip += s->look; + s->ip += s->look; + } +#else + s->look = 0; + while (s->look < s->f) + { + if ((c = getbyte(*(s->c))) < 0) + break; + s->b[s->ip] = LZO_BYTE(c); + s->ip++; + s->look++; + } +#endif + if (s->ip == s->b_size) + s->ip = 0; + + if (s->look >= 2 && s->dict_len > 0) + swd_insertdict(s,0,s->dict_len); + + s->rp = s->first_rp; + if (s->rp >= s->node_count) + s->rp -= s->node_count; + else + s->rp += s->b_size - s->node_count; + +#if defined(__LZO_CHECKER) + /* initialize memory for the first few HEAD3 (if s->ip is not far + * enough ahead to do this job for us). The value doesn't matter. */ + if (s->look < 3) + memset(&s->b[s->bp+s->look],0,3); +#endif + + LZO_UNUSED(i); + LZO_UNUSED(c); + return LZO_E_OK; +} + + +static +void swd_exit(lzo_swd_t *s) +{ +#if defined(__LZO_CHECKER) + /* free in reverse order of allocations */ +#ifdef HEAD2 + free(s->head2); s->head2 = NULL; +#endif + free(s->llen3); s->llen3 = NULL; + free(s->best3); s->best3 = NULL; + free(s->succ3); s->succ3 = NULL; + free(s->head3); s->head3 = NULL; + free(s->b); s->b = NULL; +#else + LZO_UNUSED(s); +#endif +} + + +#define swd_pos2off(s,pos) \ + (s->bp > (pos) ? s->bp - (pos) : s->b_size - ((pos) - s->bp)) + + +/*********************************************************************** +// +************************************************************************/ + +static __inline__ +void swd_getbyte(lzo_swd_t *s) +{ + int c; + + if ((c = getbyte(*(s->c))) < 0) + { + if (s->look > 0) + --s->look; +#if defined(__LZO_CHECKER) + /* initialize memory - value doesn't matter */ + s->b[s->ip] = 0; + if (s->ip < s->f) + s->b_wrap[s->ip] = 0; +#endif + } + else + { + s->b[s->ip] = LZO_BYTE(c); + if (s->ip < s->f) + s->b_wrap[s->ip] = LZO_BYTE(c); + } + if (++s->ip == s->b_size) + s->ip = 0; + if (++s->bp == s->b_size) + s->bp = 0; + if (++s->rp == s->b_size) + s->rp = 0; +} + + +/*********************************************************************** +// remove node from lists +************************************************************************/ + +static __inline__ +void swd_remove_node(lzo_swd_t *s, lzo_uint node) +{ + if (s->node_count == 0) + { + lzo_uint key; + +#ifdef LZO_DEBUG + if (s->first_rp != LZO_UINT_MAX) + { + if (node != s->first_rp) + printf("Remove %5d: %5d %5d %5d %5d %6d %6d\n", + node, s->rp, s->ip, s->bp, s->first_rp, + s->ip - node, s->ip - s->bp); + assert(node == s->first_rp); + s->first_rp = LZO_UINT_MAX; + } +#endif + + key = HEAD3(s->b,node); + assert(s->llen3[key] > 0); + --s->llen3[key]; + +#ifdef HEAD2 + key = HEAD2(s->b,node); + assert(s->head2[key] != NIL2); + if ((lzo_uint) s->head2[key] == node) + s->head2[key] = NIL2; +#endif + } + else + --s->node_count; +} + + +/*********************************************************************** +// +************************************************************************/ + +static +void swd_accept(lzo_swd_t *s, lzo_uint n) +{ + assert(n <= s->look); + + while (n--) + { + lzo_uint key; + + swd_remove_node(s,s->rp); + + /* add bp into HEAD3 */ + key = HEAD3(s->b,s->bp); + s->succ3[s->bp] = s_head3(s,key); + s->head3[key] = SWD_UINT(s->bp); + s->best3[s->bp] = SWD_UINT(s->f + 1); + s->llen3[key]++; + assert(s->llen3[key] <= SWD_N); + +#ifdef HEAD2 + /* add bp into HEAD2 */ + key = HEAD2(s->b,s->bp); + s->head2[key] = SWD_UINT(s->bp); +#endif + + swd_getbyte(s); + } +} + + +/*********************************************************************** +// +************************************************************************/ + +static +void swd_search(lzo_swd_t *s, lzo_uint node, lzo_uint cnt) +{ +#if 0 && defined(__GNUC__) && defined(__i386__) + register const unsigned char *p1 __asm__("%edi"); + register const unsigned char *p2 __asm__("%esi"); + register const unsigned char *px __asm__("%edx"); +#else + const unsigned char *p1; + const unsigned char *p2; + const unsigned char *px; +#endif + lzo_uint m_len = s->m_len; + const unsigned char * b = s->b; + const unsigned char * bp = s->b + s->bp; + const unsigned char * bx = s->b + s->bp + s->look; + unsigned char scan_end1; + + assert(s->m_len > 0); + + scan_end1 = bp[m_len - 1]; + for ( ; cnt-- > 0; node = s->succ3[node]) + { + p1 = bp; + p2 = b + node; + px = bx; + + assert(m_len < s->look); + + if ( +#if 1 + p2[m_len - 1] == scan_end1 && + p2[m_len] == p1[m_len] && +#endif + p2[0] == p1[0] && + p2[1] == p1[1]) + { + lzo_uint i; + assert(memcmp(bp,&b[node],3) == 0); + +#if 0 && defined(LZO_UNALIGNED_OK_4) + p1 += 3; p2 += 3; + while (p1 < px && * (const lzo_uint32p) p1 == * (const lzo_uint32p) p2) + p1 += 4, p2 += 4; + while (p1 < px && *p1 == *p2) + p1 += 1, p2 += 1; +#else + p1 += 2; p2 += 2; + do {} while (++p1 < px && *p1 == *++p2); +#endif + i = p1 - bp; + +#ifdef LZO_DEBUG + if (memcmp(bp,&b[node],i) != 0) + printf("%5ld %5ld %02x%02x %02x%02x\n", + (long)s->bp, (long) node, + bp[0], bp[1], b[node], b[node+1]); +#endif + assert(memcmp(bp,&b[node],i) == 0); + +#if defined(SWD_BEST_OFF) + if (i < SWD_BEST_OFF) + { + if (s->best_pos[i] == 0) + s->best_pos[i] = node + 1; + } +#endif + if (i > m_len) + { + s->m_len = m_len = i; + s->m_pos = node; + if (m_len == s->look) + return; + if (m_len >= s->nice_length) + return; + if (m_len > (lzo_uint) s->best3[node]) + return; + scan_end1 = bp[m_len - 1]; + } + } + } +} + + +/*********************************************************************** +// +************************************************************************/ + +#ifdef HEAD2 + +static +lzo_bool swd_search2(lzo_swd_t *s) +{ + lzo_uint key; + + assert(s->look >= 2); + assert(s->m_len > 0); + + key = s->head2[ HEAD2(s->b,s->bp) ]; + if (key == NIL2) + return 0; +#ifdef LZO_DEBUG + if (memcmp(&s->b[s->bp],&s->b[key],2) != 0) + printf("%5ld %5ld %02x%02x %02x%02x\n", (long)s->bp, (long)key, + s->b[s->bp], s->b[s->bp+1], s->b[key], s->b[key+1]); +#endif + assert(memcmp(&s->b[s->bp],&s->b[key],2) == 0); +#if defined(SWD_BEST_OFF) + if (s->best_pos[2] == 0) + s->best_pos[2] = key + 1; +#endif + + if (s->m_len < 2) + { + s->m_len = 2; + s->m_pos = key; + } + return 1; +} + +#endif + + +/*********************************************************************** +// +************************************************************************/ + +static +void swd_findbest(lzo_swd_t *s) +{ + lzo_uint key; + lzo_uint cnt, node; + lzo_uint len; + + assert(s->m_len > 0); + + /* get current head, add bp into HEAD3 */ + key = HEAD3(s->b,s->bp); + node = s->succ3[s->bp] = s_head3(s,key); + cnt = s->llen3[key]++; + assert(s->llen3[key] <= SWD_N + SWD_F); + if (cnt > s->max_chain && s->max_chain > 0) + cnt = s->max_chain; + s->head3[key] = SWD_UINT(s->bp); + + s->b_char = s->b[s->bp]; + len = s->m_len; + if (s->m_len >= s->look) + { + if (s->look == 0) + s->b_char = -1; + s->m_off = 0; + s->best3[s->bp] = SWD_UINT(s->f + 1); + } + else + { +#ifdef HEAD2 + if (swd_search2(s)) +#endif + if (s->look >= 3) + swd_search(s,node,cnt); + if (s->m_len > len) + s->m_off = swd_pos2off(s,s->m_pos); + s->best3[s->bp] = SWD_UINT(s->m_len); + +#if defined(SWD_BEST_OFF) + if (s->use_best_off) + { + int i; + for (i = 2; i < SWD_BEST_OFF; i++) + if (s->best_pos[i] > 0) + s->best_off[i] = swd_pos2off(s,s->best_pos[i]-1); + else + s->best_off[i] = 0; + } +#endif + } + + swd_remove_node(s,s->rp); + +#ifdef HEAD2 + /* add bp into HEAD2 */ + key = HEAD2(s->b,s->bp); + s->head2[key] = SWD_UINT(s->bp); +#endif +} + + +#undef HEAD3 +#undef HEAD2 +#undef s_head3 + + +/* +vi:ts=4:et +*/ + diff --git a/DumpProto/lzo/lzo_util.c b/DumpProto/lzo/lzo_util.c new file mode 100644 index 0000000..799bbeb --- /dev/null +++ b/DumpProto/lzo/lzo_util.c @@ -0,0 +1,218 @@ +/* lzo_util.c -- utilities for the LZO library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include "lzo_conf.h" +#include "lzo_util.h" + + +/*********************************************************************** +// +************************************************************************/ + +LZO_PUBLIC(lzo_bool) +lzo_assert(int expr) +{ + return (expr) ? 1 : 0; +} + + +/*********************************************************************** +// +************************************************************************/ + +/* If you use the LZO library in a product, you *must* keep this + * copyright string in the executable of your product. +.*/ + +const lzo_byte __lzo_copyright[] = +#if !defined(__LZO_IN_MINLZO) + /* save space as some people want a really small decompressor */ + LZO_VERSION_STRING; +#else + "\n\n\n" + "LZO real-time data compression library.\n" + "Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 Markus Franz Xaver Johannes Oberhumer\n" + "\n" + "http://www.oberhumer.com/opensource/lzo/\n" + "\n" + "LZO version: v" LZO_VERSION_STRING ", " LZO_VERSION_DATE "\n" + "LZO build date: " __DATE__ " " __TIME__ "\n\n" + "LZO special compilation options:\n" +#ifdef __cplusplus + " __cplusplus\n" +#endif +#if defined(__PIC__) + " __PIC__\n" +#elif defined(__pic__) + " __pic__\n" +#endif +#if (UINT_MAX < LZO_0xffffffffL) + " 16BIT\n" +#endif +#if defined(__LZO_STRICT_16BIT) + " __LZO_STRICT_16BIT\n" +#endif +#if (UINT_MAX > LZO_0xffffffffL) + " UINT_MAX=" _LZO_MEXPAND(UINT_MAX) "\n" +#endif +#if (ULONG_MAX > LZO_0xffffffffL) + " ULONG_MAX=" _LZO_MEXPAND(ULONG_MAX) "\n" +#endif +#if defined(LZO_BYTE_ORDER) + " LZO_BYTE_ORDER=" _LZO_MEXPAND(LZO_BYTE_ORDER) "\n" +#endif +#if defined(LZO_UNALIGNED_OK_2) + " LZO_UNALIGNED_OK_2\n" +#endif +#if defined(LZO_UNALIGNED_OK_4) + " LZO_UNALIGNED_OK_4\n" +#endif +#if defined(LZO_ALIGNED_OK_4) + " LZO_ALIGNED_OK_4\n" +#endif +#if defined(LZO_DICT_USE_PTR) + " LZO_DICT_USE_PTR\n" +#endif +#if defined(__LZO_QUERY_COMPRESS) + " __LZO_QUERY_COMPRESS\n" +#endif +#if defined(__LZO_QUERY_DECOMPRESS) + " __LZO_QUERY_DECOMPRESS\n" +#endif +#if defined(__LZO_IN_MINILZO) + " __LZO_IN_MINILZO\n" +#endif + "\n\n" +/* RCS information */ + "$Id: LZO " LZO_VERSION_STRING " built " __DATE__ " " __TIME__ +#if defined(__GNUC__) && defined(__VERSION__) + " by gcc " __VERSION__ +#elif defined(__BORLANDC__) + " by Borland C " _LZO_MEXPAND(__BORLANDC__) +#elif defined(_MSC_VER) + " by Microsoft C " _LZO_MEXPAND(_MSC_VER) +#elif defined(__PUREC__) + " by Pure C " _LZO_MEXPAND(__PUREC__) +#elif defined(__SC__) + " by Symantec C " _LZO_MEXPAND(__SC__) +#elif defined(__TURBOC__) + " by Turbo C " _LZO_MEXPAND(__TURBOC__) +#elif defined(__WATCOMC__) + " by Watcom C " _LZO_MEXPAND(__WATCOMC__) +#endif + " $\n" + "$Copyright: LZO (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 Markus Franz Xaver Johannes Oberhumer $\n"; +#endif + +LZO_PUBLIC(const lzo_byte *) +lzo_copyright(void) +{ + return __lzo_copyright; +} + +LZO_PUBLIC(unsigned) +lzo_version(void) +{ + return LZO_VERSION; +} + +LZO_PUBLIC(const char *) +lzo_version_string(void) +{ + return LZO_VERSION_STRING; +} + +LZO_PUBLIC(const char *) +lzo_version_date(void) +{ + return LZO_VERSION_DATE; +} + +LZO_PUBLIC(const lzo_charp) +_lzo_version_string(void) +{ + return LZO_VERSION_STRING; +} + +LZO_PUBLIC(const lzo_charp) +_lzo_version_date(void) +{ + return LZO_VERSION_DATE; +} + + +/*********************************************************************** +// adler32 checksum +// adapted from free code by Mark Adler +// see http://www.cdrom.com/pub/infozip/zlib/ +************************************************************************/ + +#define LZO_BASE 65521u /* largest prime smaller than 65536 */ +#define LZO_NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define LZO_DO1(buf,i) {s1 += buf[i]; s2 += s1;} +#define LZO_DO2(buf,i) LZO_DO1(buf,i); LZO_DO1(buf,i+1); +#define LZO_DO4(buf,i) LZO_DO2(buf,i); LZO_DO2(buf,i+2); +#define LZO_DO8(buf,i) LZO_DO4(buf,i); LZO_DO4(buf,i+4); +#define LZO_DO16(buf,i) LZO_DO8(buf,i); LZO_DO8(buf,i+8); + +LZO_PUBLIC(lzo_uint32) +lzo_adler32(lzo_uint32 adler, const lzo_byte *buf, lzo_uint len) +{ + lzo_uint32 s1 = adler & 0xffff; + lzo_uint32 s2 = (adler >> 16) & 0xffff; + int k; + + if (buf == NULL) + return 1; + + while (len > 0) + { + k = len < LZO_NMAX ? (int) len : LZO_NMAX; + len -= k; + if (k >= 16) do + { + LZO_DO16(buf,0); + buf += 16; + k -= 16; + } while (k >= 16); + if (k != 0) do + { + s1 += *buf++; + s2 += s1; + } while (--k > 0); + s1 %= LZO_BASE; + s2 %= LZO_BASE; + } + return (s2 << 16) | s1; +} + + +/* +vi:ts=4:et +*/ diff --git a/DumpProto/lzo/lzo_util.h b/DumpProto/lzo/lzo_util.h new file mode 100644 index 0000000..2785eaa --- /dev/null +++ b/DumpProto/lzo/lzo_util.h @@ -0,0 +1,195 @@ +/* lzo_util.h -- utilities for the LZO library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the library and is subject + to change. + */ + + +#ifndef __LZO_UTIL_H +#define __LZO_UTIL_H + +#ifndef __LZO_CONF_H +# include "lzo_conf.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// fast memcpy that copies multiples of 8 byte chunks. +// len is the number of bytes. +// note: all parameters must be lvalues, len >= 8 +// dest and src advance, len is undefined afterwards +************************************************************************/ + +#if 1 && defined(HAVE_MEMCPY) +#if !defined(__LZO_DOS16) && !defined(__LZO_WIN16) + +#define MEMCPY8_DS(dest,src,len) \ + memcpy(dest,src,len); \ + dest += len; \ + src += len + +#endif +#endif + + +#if 0 && !defined(MEMCPY8_DS) + +#define MEMCPY8_DS(dest,src,len) \ + { do { \ + *dest++ = *src++; \ + *dest++ = *src++; \ + *dest++ = *src++; \ + *dest++ = *src++; \ + *dest++ = *src++; \ + *dest++ = *src++; \ + *dest++ = *src++; \ + *dest++ = *src++; \ + len -= 8; \ + } while (len > 0); } + +#endif + + +#if !defined(MEMCPY8_DS) + +#define MEMCPY8_DS(dest,src,len) \ + { register lzo_uint __l = (len) / 8; \ + do { \ + *dest++ = *src++; \ + *dest++ = *src++; \ + *dest++ = *src++; \ + *dest++ = *src++; \ + *dest++ = *src++; \ + *dest++ = *src++; \ + *dest++ = *src++; \ + *dest++ = *src++; \ + } while (--__l > 0); } + +#endif + + +/*********************************************************************** +// memcpy and pseudo-memmove +// len is the number of bytes. +// note: all parameters must be lvalues, len > 0 +// dest and src advance, len is undefined afterwards +************************************************************************/ + +#define MEMCPY_DS(dest,src,len) \ + do *dest++ = *src++; \ + while (--len > 0) + +#define MEMMOVE_DS(dest,src,len) \ + do *dest++ = *src++; \ + while (--len > 0) + + +/*********************************************************************** +// fast bzero that clears multiples of 8 pointers +// n is the number of pointers. +// note: n > 0 +// s and n are undefined afterwards +************************************************************************/ + +#if 0 && defined(LZO_OPTIMIZE_GNUC_i386) + +#define BZERO8_PTR(s,l,n) \ +__asm__ __volatile__( \ + "movl %0,%%eax \n" \ + "movl %1,%%edi \n" \ + "movl %2,%%ecx \n" \ + "cld \n" \ + "rep \n" \ + "stosl %%eax,(%%edi) \n" \ + : /* no outputs */ \ + :"g" (0),"g" (s),"g" (n) \ + :"eax","edi","ecx", "memory", "cc" \ +) + +#elif (LZO_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMSET) + +#if 1 +#define BZERO8_PTR(s,l,n) memset((s),0,(lzo_uint)(l)*(n)) +#else +#define BZERO8_PTR(s,l,n) memset((lzo_voidp)(s),0,(lzo_uint)(l)*(n)) +#endif + +#else + +#define BZERO8_PTR(s,l,n) \ + lzo_memset((lzo_voidp)(s),0,(lzo_uint)(l)*(n)) + +#endif + + +/*********************************************************************** +// rotate (currently not used) +************************************************************************/ + +#if 0 +#if defined(__GNUC__) && defined(__i386__) + +unsigned char lzo_rotr8(unsigned char value, int shift); +extern __inline__ unsigned char lzo_rotr8(unsigned char value, int shift) +{ + unsigned char result; + + __asm__ __volatile__ ("movb %b1, %b0; rorb %b2, %b0" + : "=a"(result) : "g"(value), "c"(shift)); + return result; +} + +unsigned short lzo_rotr16(unsigned short value, int shift); +extern __inline__ unsigned short lzo_rotr16(unsigned short value, int shift) +{ + unsigned short result; + + __asm__ __volatile__ ("movw %b1, %b0; rorw %b2, %b0" + : "=a"(result) : "g"(value), "c"(shift)); + return result; +} + +#endif +#endif + + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + +/* +vi:ts=4:et +*/ diff --git a/DumpProto/lzo/lzoconf.h b/DumpProto/lzo/lzoconf.h new file mode 100644 index 0000000..96db180 --- /dev/null +++ b/DumpProto/lzo/lzoconf.h @@ -0,0 +1,451 @@ +/* lzoconf.h -- configuration for the LZO real-time data compression library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __LZOCONF_H +#define __LZOCONF_H + +#define LZO_VERSION 0x1080 +#define LZO_VERSION_STRING "1.08" +#define LZO_VERSION_DATE "Jul 12 2002" + +/* internal Autoconf configuration file - only used when building LZO */ +#if defined(LZO_HAVE_CONFIG_H) +# include +#endif +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// LZO requires a conforming +************************************************************************/ + +#if !defined(CHAR_BIT) || (CHAR_BIT != 8) +# error "invalid CHAR_BIT" +#endif +#if !defined(UCHAR_MAX) || !defined(UINT_MAX) || !defined(ULONG_MAX) +# error "check your compiler installation" +#endif +#if (USHRT_MAX < 1) || (UINT_MAX < 1) || (ULONG_MAX < 1) +# error "your limits.h macros are broken" +#endif + +/* workaround a cpp bug under hpux 10.20 */ +#define LZO_0xffffffffL 4294967295ul + +#if !defined(LZO_UINT32_C) +# if (UINT_MAX < LZO_0xffffffffL) +# define LZO_UINT32_C(c) c ## UL +# else +# define LZO_UINT32_C(c) c ## U +# endif +#endif + + +/*********************************************************************** +// architecture defines +************************************************************************/ + +#if !defined(__LZO_WIN) && !defined(__LZO_DOS) && !defined(__LZO_OS2) +# if defined(__WINDOWS__) || defined(_WINDOWS) || defined(_Windows) +# define __LZO_WIN +# elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32) +# define __LZO_WIN +# elif defined(__NT__) || defined(__NT_DLL__) || defined(__WINDOWS_386__) +# define __LZO_WIN +# elif defined(__DOS__) || defined(__MSDOS__) || defined(MSDOS) +# define __LZO_DOS +# elif defined(__OS2__) || defined(__OS2V2__) || defined(OS2) +# define __LZO_OS2 +# elif defined(__palmos__) +# define __LZO_PALMOS +# elif defined(__TOS__) || defined(__atarist__) +# define __LZO_TOS +# endif +#endif + +#if (UINT_MAX < LZO_0xffffffffL) +# if defined(__LZO_WIN) +# define __LZO_WIN16 +# elif defined(__LZO_DOS) +# define __LZO_DOS16 +# elif defined(__LZO_PALMOS) +# define __LZO_PALMOS16 +# elif defined(__LZO_TOS) +# define __LZO_TOS16 +# elif defined(__C166__) +# else + /* porting hint: for pure 16-bit architectures try compiling + * everything with -D__LZO_STRICT_16BIT */ +# error "16-bit target not supported - contact me for porting hints" +# endif +#endif + +#if !defined(__LZO_i386) +# if defined(__LZO_DOS) || defined(__LZO_WIN16) +# define __LZO_i386 +# elif defined(__i386__) || defined(__386__) || defined(_M_IX86) +# define __LZO_i386 +# endif +#endif + +#if defined(__LZO_STRICT_16BIT) +# if (UINT_MAX < LZO_0xffffffffL) +# include +# endif +#endif + +/* memory checkers */ +#if !defined(__LZO_CHECKER) +# if defined(__BOUNDS_CHECKING_ON) +# define __LZO_CHECKER +# elif defined(__CHECKER__) +# define __LZO_CHECKER +# elif defined(__INSURE__) +# define __LZO_CHECKER +# elif defined(__PURIFY__) +# define __LZO_CHECKER +# endif +#endif + + +/*********************************************************************** +// integral and pointer types +************************************************************************/ + +/* Integral types with 32 bits or more */ +#if !defined(LZO_UINT32_MAX) +# if (UINT_MAX >= LZO_0xffffffffL) + typedef unsigned int lzo_uint32; + typedef int lzo_int32; +# define LZO_UINT32_MAX UINT_MAX +# define LZO_INT32_MAX INT_MAX +# define LZO_INT32_MIN INT_MIN +# elif (ULONG_MAX >= LZO_0xffffffffL) + typedef unsigned long lzo_uint32; + typedef long lzo_int32; +# define LZO_UINT32_MAX ULONG_MAX +# define LZO_INT32_MAX LONG_MAX +# define LZO_INT32_MIN LONG_MIN +# else +# error "lzo_uint32" +# endif +#endif + +/* lzo_uint is used like size_t */ +#if !defined(LZO_UINT_MAX) +# if (UINT_MAX >= LZO_0xffffffffL) + typedef unsigned int lzo_uint; + typedef int lzo_int; +# define LZO_UINT_MAX UINT_MAX +# define LZO_INT_MAX INT_MAX +# define LZO_INT_MIN INT_MIN +# elif (ULONG_MAX >= LZO_0xffffffffL) + typedef unsigned long lzo_uint; + typedef long lzo_int; +# define LZO_UINT_MAX ULONG_MAX +# define LZO_INT_MAX LONG_MAX +# define LZO_INT_MIN LONG_MIN +# else +# error "lzo_uint" +# endif +#endif + +typedef int lzo_bool; + + +/*********************************************************************** +// memory models +************************************************************************/ + +/* Memory model for the public code segment. */ +#if !defined(__LZO_CMODEL) +# if defined(__LZO_DOS16) || defined(__LZO_WIN16) +# define __LZO_CMODEL __far +# elif defined(__LZO_i386) && defined(__WATCOMC__) +# define __LZO_CMODEL __near +# else +# define __LZO_CMODEL +# endif +#endif + +/* Memory model for the public data segment. */ +#if !defined(__LZO_DMODEL) +# if defined(__LZO_DOS16) || defined(__LZO_WIN16) +# define __LZO_DMODEL __far +# elif defined(__LZO_i386) && defined(__WATCOMC__) +# define __LZO_DMODEL __near +# else +# define __LZO_DMODEL +# endif +#endif + +/* Memory model that allows to access memory at offsets of lzo_uint. */ +#if !defined(__LZO_MMODEL) +# if (LZO_UINT_MAX <= UINT_MAX) +# define __LZO_MMODEL +# elif defined(__LZO_DOS16) || defined(__LZO_WIN16) +# define __LZO_MMODEL __huge +# define LZO_999_UNSUPPORTED +# elif defined(__LZO_PALMOS16) || defined(__LZO_TOS16) +# define __LZO_MMODEL +# else +# error "__LZO_MMODEL" +# endif +#endif + +/* no typedef here because of const-pointer issues */ +#define lzo_byte unsigned char __LZO_MMODEL +#define lzo_bytep unsigned char __LZO_MMODEL * +#define lzo_charp char __LZO_MMODEL * +#define lzo_voidp void __LZO_MMODEL * +#define lzo_shortp short __LZO_MMODEL * +#define lzo_ushortp unsigned short __LZO_MMODEL * +#define lzo_uint32p lzo_uint32 __LZO_MMODEL * +#define lzo_int32p lzo_int32 __LZO_MMODEL * +#define lzo_uintp lzo_uint __LZO_MMODEL * +#define lzo_intp lzo_int __LZO_MMODEL * +#define lzo_voidpp lzo_voidp __LZO_MMODEL * +#define lzo_bytepp lzo_bytep __LZO_MMODEL * + +#ifndef lzo_sizeof_dict_t +# define lzo_sizeof_dict_t sizeof(lzo_bytep) +#endif + + +/*********************************************************************** +// calling conventions and function types +************************************************************************/ + +/* linkage */ +#if !defined(__LZO_EXTERN_C) +# ifdef __cplusplus +# define __LZO_EXTERN_C extern "C" +# else +# define __LZO_EXTERN_C extern +# endif +#endif + +/* calling convention */ +#if !defined(__LZO_CDECL) +# if defined(__LZO_DOS16) || defined(__LZO_WIN16) +# define __LZO_CDECL __LZO_CMODEL __cdecl +# elif defined(__LZO_i386) && defined(_MSC_VER) +# define __LZO_CDECL __LZO_CMODEL __cdecl +# elif defined(__LZO_i386) && defined(__WATCOMC__) +# define __LZO_CDECL __LZO_CMODEL __cdecl +# else +# define __LZO_CDECL __LZO_CMODEL +# endif +#endif +#if !defined(__LZO_ENTRY) +# define __LZO_ENTRY __LZO_CDECL +#endif + +/* C++ exception specification for extern "C" function types */ +#if !defined(__cplusplus) +# undef LZO_NOTHROW +# define LZO_NOTHROW +#elif !defined(LZO_NOTHROW) +# define LZO_NOTHROW +#endif + + +typedef int +(__LZO_ENTRY *lzo_compress_t) ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +typedef int +(__LZO_ENTRY *lzo_decompress_t) ( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +typedef int +(__LZO_ENTRY *lzo_optimize_t) ( lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +typedef int +(__LZO_ENTRY *lzo_compress_dict_t)(const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem, + const lzo_byte *dict, lzo_uint dict_len ); + +typedef int +(__LZO_ENTRY *lzo_decompress_dict_t)(const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem, + const lzo_byte *dict, lzo_uint dict_len ); + + +/* assembler versions always use __cdecl */ +typedef int +(__LZO_CDECL *lzo_compress_asm_t)( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +typedef int +(__LZO_CDECL *lzo_decompress_asm_t)( const lzo_byte *src, lzo_uint src_len, + lzo_byte *dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + + +/* a progress indicator callback function */ +typedef void (__LZO_ENTRY *lzo_progress_callback_t) (lzo_uint, lzo_uint); + + +/*********************************************************************** +// export information +************************************************************************/ + +/* DLL export information */ +#if !defined(__LZO_EXPORT1) +# define __LZO_EXPORT1 +#endif +#if !defined(__LZO_EXPORT2) +# define __LZO_EXPORT2 +#endif + +/* exported calling convention for C functions */ +#if !defined(LZO_PUBLIC) +# define LZO_PUBLIC(_rettype) \ + __LZO_EXPORT1 _rettype __LZO_EXPORT2 __LZO_ENTRY +#endif +#if !defined(LZO_EXTERN) +# define LZO_EXTERN(_rettype) __LZO_EXTERN_C LZO_PUBLIC(_rettype) +#endif +#if !defined(LZO_PRIVATE) +# define LZO_PRIVATE(_rettype) static _rettype __LZO_ENTRY +#endif + +/* exported __cdecl calling convention for assembler functions */ +#if !defined(LZO_PUBLIC_CDECL) +# define LZO_PUBLIC_CDECL(_rettype) \ + __LZO_EXPORT1 _rettype __LZO_EXPORT2 __LZO_CDECL +#endif +#if !defined(LZO_EXTERN_CDECL) +# define LZO_EXTERN_CDECL(_rettype) __LZO_EXTERN_C LZO_PUBLIC_CDECL(_rettype) +#endif + +/* exported global variables (LZO currently uses no static variables and + * is fully thread safe) */ +#if !defined(LZO_PUBLIC_VAR) +# define LZO_PUBLIC_VAR(_type) \ + __LZO_EXPORT1 _type __LZO_EXPORT2 __LZO_DMODEL +#endif +#if !defined(LZO_EXTERN_VAR) +# define LZO_EXTERN_VAR(_type) extern LZO_PUBLIC_VAR(_type) +#endif + + +/*********************************************************************** +// error codes and prototypes +************************************************************************/ + +/* Error codes for the compression/decompression functions. Negative + * values are errors, positive values will be used for special but + * normal events. + */ +#define LZO_E_OK 0 +#define LZO_E_ERROR (-1) +#define LZO_E_OUT_OF_MEMORY (-2) /* not used right now */ +#define LZO_E_NOT_COMPRESSIBLE (-3) /* not used right now */ +#define LZO_E_INPUT_OVERRUN (-4) +#define LZO_E_OUTPUT_OVERRUN (-5) +#define LZO_E_LOOKBEHIND_OVERRUN (-6) +#define LZO_E_EOF_NOT_FOUND (-7) +#define LZO_E_INPUT_NOT_CONSUMED (-8) + + +/* lzo_init() should be the first function you call. + * Check the return code ! + * + * lzo_init() is a macro to allow checking that the library and the + * compiler's view of various types are consistent. + */ +#define lzo_init() __lzo_init2(LZO_VERSION,(int)sizeof(short),(int)sizeof(int),\ + (int)sizeof(long),(int)sizeof(lzo_uint32),(int)sizeof(lzo_uint),\ + (int)lzo_sizeof_dict_t,(int)sizeof(char *),(int)sizeof(lzo_voidp),\ + (int)sizeof(lzo_compress_t)) +LZO_EXTERN(int) __lzo_init2(unsigned,int,int,int,int,int,int,int,int,int); + +/* version functions (useful for shared libraries) */ +LZO_EXTERN(unsigned) lzo_version(void); +LZO_EXTERN(const char *) lzo_version_string(void); +LZO_EXTERN(const char *) lzo_version_date(void); +LZO_EXTERN(const lzo_charp) _lzo_version_string(void); +LZO_EXTERN(const lzo_charp) _lzo_version_date(void); + +/* string functions */ +LZO_EXTERN(int) +lzo_memcmp(const lzo_voidp _s1, const lzo_voidp _s2, lzo_uint _len); +LZO_EXTERN(lzo_voidp) +lzo_memcpy(lzo_voidp _dest, const lzo_voidp _src, lzo_uint _len); +LZO_EXTERN(lzo_voidp) +lzo_memmove(lzo_voidp _dest, const lzo_voidp _src, lzo_uint _len); +LZO_EXTERN(lzo_voidp) +lzo_memset(lzo_voidp _s, int _c, lzo_uint _len); + +/* checksum functions */ +LZO_EXTERN(lzo_uint32) +lzo_adler32(lzo_uint32 _adler, const lzo_byte *_buf, lzo_uint _len); +LZO_EXTERN(lzo_uint32) +lzo_crc32(lzo_uint32 _c, const lzo_byte *_buf, lzo_uint _len); + +/* misc. */ +LZO_EXTERN(lzo_bool) lzo_assert(int _expr); +LZO_EXTERN(int) _lzo_config_check(void); +typedef union { lzo_bytep p; lzo_uint u; } __lzo_pu_u; +typedef union { lzo_bytep p; lzo_uint32 u32; } __lzo_pu32_u; +typedef union { void *vp; lzo_bytep bp; lzo_uint32 u32; long l; } lzo_align_t; + +/* align a char pointer on a boundary that is a multiple of `size' */ +LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp _ptr, lzo_uint _size); +#define LZO_PTR_ALIGN_UP(_ptr,_size) \ + ((_ptr) + (lzo_uint) __lzo_align_gap((const lzo_voidp)(_ptr),(lzo_uint)(_size))) + +/* deprecated - only for backward compatibility */ +#define LZO_ALIGN(_ptr,_size) LZO_PTR_ALIGN_UP(_ptr,_size) + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + diff --git a/DumpProto/lzo/lzoutil.h b/DumpProto/lzo/lzoutil.h new file mode 100644 index 0000000..69ad214 --- /dev/null +++ b/DumpProto/lzo/lzoutil.h @@ -0,0 +1,91 @@ +/* lzoutil.h -- utilitiy functions for use by applications + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __LZOUTIL_H +#define __LZOUTIL_H + +#ifndef __LZOCONF_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// portable memory allocation +// +// The LZO library does not allocate any memory (you always pass a +// pre-allocated pointer via the `wrkmem' parameter), but these +// functions are handy for application programs. +************************************************************************/ + +LZO_EXTERN(lzo_voidp) lzo_alloc(lzo_uint _nelems, lzo_uint _size); +LZO_EXTERN(lzo_voidp) lzo_malloc(lzo_uint _size); +LZO_EXTERN(void) lzo_free(lzo_voidp _ptr); + +typedef lzo_voidp (__LZO_ENTRY *lzo_alloc_hook_t) (lzo_uint, lzo_uint); +typedef void (__LZO_ENTRY *lzo_free_hook_t) (lzo_voidp); + +LZO_EXTERN_VAR(lzo_alloc_hook_t) lzo_alloc_hook; +LZO_EXTERN_VAR(lzo_free_hook_t) lzo_free_hook; + + +/*********************************************************************** +// portable file io +************************************************************************/ + +#if !defined(LZO_FILEP) +# define LZO_FILEP void * +#endif + +LZO_EXTERN(lzo_uint) +lzo_fread(LZO_FILEP f, lzo_voidp buf, lzo_uint size); +LZO_EXTERN(lzo_uint) +lzo_fwrite(LZO_FILEP f, const lzo_voidp buf, lzo_uint size); + + +#if (LZO_UINT_MAX <= UINT_MAX) +# define lzo_fread(f,b,s) (fread(b,1,s,f)) +# define lzo_fwrite(f,b,s) (fwrite(b,1,s,f)) +#endif + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + diff --git a/DumpProto/lzo/stats1a.h b/DumpProto/lzo/stats1a.h new file mode 100644 index 0000000..6a9bdac --- /dev/null +++ b/DumpProto/lzo/stats1a.h @@ -0,0 +1,124 @@ +/* stats1a.h -- statistics for the the LZO1A algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the LZO package and is subject + to change. + */ + + +#ifndef __LZO_STATS1A_H +#define __LZO_STATS1A_H + +#ifdef __cplusplus +extern "C" { +#endif + + + +/*********************************************************************** +// collect statistical information when compressing +// used for finetuning, view with a debugger +************************************************************************/ + +#if defined(LZO_COLLECT_STATS) +# define LZO_STATS(expr) expr +#else +# define LZO_STATS(expr) ((void) 0) +#endif + + +/*********************************************************************** +// +************************************************************************/ + +typedef struct { + +/* configuration */ + unsigned rbits; + unsigned clevel; + +/* internal configuration */ + unsigned dbits; + unsigned lbits; + +/* constants */ + unsigned min_match_short; + unsigned max_match_short; + unsigned min_match_long; + unsigned max_match_long; + unsigned min_offset; + unsigned max_offset; + unsigned r0min; + unsigned r0fast; + unsigned r0max; + +/* counts */ + long short_matches; + long long_matches; + long r1_matches; + long lit_runs; + long lit_runs_after_long_match; + long r0short_runs; + long r0fast_runs; + long r0long_runs; + +/* */ + long lit_run[RSIZE]; + long lit_run_after_long_match[RSIZE]; + long short_match[MAX_MATCH_SHORT + 1]; + long long_match[MAX_MATCH_LONG + 1]; + long marker[256]; + +/* these could prove useful for further optimizations */ + long short_match_offset_osize[MAX_MATCH_SHORT + 1]; + long short_match_offset_256[MAX_MATCH_SHORT + 1]; + long short_match_offset_1024[MAX_MATCH_SHORT + 1]; + long matches_out_of_range; + long matches_out_of_range_2; + long matches_out_of_range_4; + long match_out_of_range[MAX_MATCH_SHORT + 1]; + +/* */ + long in_len; + long out_len; +} +lzo1a_stats_t; + +extern lzo1a_stats_t *lzo1a_stats; + + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + +/* +vi:ts=4:et +*/ diff --git a/DumpProto/lzo/stats1b.h b/DumpProto/lzo/stats1b.h new file mode 100644 index 0000000..7976627 --- /dev/null +++ b/DumpProto/lzo/stats1b.h @@ -0,0 +1,129 @@ +/* stats1b.h -- statistics for the the LZO library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the library and is subject + to change. + */ + + +#ifndef __LZO_STATS1B_H +#define __LZO_STATS1B_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// Collect statistical information when compressing. +// Useful for finetuning the compression algorithm. +// Examine the symbol 'lzo1b_stats' with a debugger. +************************************************************************/ + +#if defined(LZO_COLLECT_STATS) +# define LZO_STATS(expr) expr +#else +# define LZO_STATS(expr) ((void) 0) +#endif + + +#if defined(LZO_COLLECT_STATS) + +typedef struct +{ +/* algorithm configuration */ + unsigned r_bits; + unsigned m3o_bits; + unsigned dd_bits; + unsigned clevel; + +/* internal configuration */ + unsigned d_bits; + long min_lookahead; + long max_lookbehind; + const char *compress_id; + +/* counts */ + long lit_runs; + long r0short_runs; + long r0fast_runs; + long r0long_runs; + long m1_matches; + long m2_matches; + long m3_matches; + long m4_matches; + long r1_matches; + +/* */ + long lit_run[R0MIN]; + long m2_match[M2_MAX_LEN + 1]; + long m3_match[M3_MAX_LEN + 1]; +#if (M3O_BITS < 8) + long lit_runs_after_m3_match; + long lit_run_after_m3_match[LZO_SIZE(8-M3O_BITS)]; +#endif + +/* */ + long matches; + long match_bytes; + long literals; + long literal_overhead; + long literal_bytes; + float literal_overhead_percent; + +/* */ + long unused_dict_entries; + float unused_dict_entries_percent; + +/* */ + long in_len; + long out_len; +} +lzo1b_stats_t; + + +void _lzo1b_stats_init(lzo1b_stats_t *lzo_stats); +void _lzo1b_stats_calc(lzo1b_stats_t *lzo_stats); + +extern lzo1b_stats_t * const lzo1b_stats; + +#define lzo_stats_t lzo1b_stats_t +#define lzo_stats lzo1b_stats + +#endif + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + +/* +vi:ts=4:et +*/ diff --git a/DumpProto/lzo/stats1c.h b/DumpProto/lzo/stats1c.h new file mode 100644 index 0000000..b03fb60 --- /dev/null +++ b/DumpProto/lzo/stats1c.h @@ -0,0 +1,48 @@ +/* stats1c.h -- statistics for the the LZO library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the library and is subject + to change. + */ + + +#ifndef __LZO_STATS1C_H +#define __LZO_STATS1C_H + +#define lzo1b_stats_t lzo1c_stats_t +#define lzo1b_stats lzo1c_stats +#define _lzo1b_stats_init _lzo1c_stats_init +#define _lzo1b_stats_calc _lzo1c_stats_calc + +#include "stats1b.h" + +#endif /* already included */ + +/* +vi:ts=4:et +*/ diff --git a/DumpProto/lzo/stdafx.cpp b/DumpProto/lzo/stdafx.cpp new file mode 100644 index 0000000..bc08a2d --- /dev/null +++ b/DumpProto/lzo/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : ǥ ϸ ִ ҽ Դϴ. +// lzo.pch ̸ ϵ ˴ϴ. +// stdafx.obj ̸ ϵ Ե˴ϴ. + +#include "stdafx.h" + +// TODO: ʿ ߰ +// ƴ STDAFX.H մϴ. diff --git a/DumpProto/lzo/stdafx.h b/DumpProto/lzo/stdafx.h new file mode 100644 index 0000000..a525d12 --- /dev/null +++ b/DumpProto/lzo/stdafx.h @@ -0,0 +1,14 @@ +// stdafx.h : ʴ +// ǥ ý Ʈ +// ִ Դϴ. +// + +#pragma once + +#include "targetver.h" + +#define WIN32_LEAN_AND_MEAN // ʴ Windows մϴ. + + + +// TODO: α׷ ʿ ߰ ⿡ մϴ. diff --git a/DumpProto/lzo/targetver.h b/DumpProto/lzo/targetver.h new file mode 100644 index 0000000..34ebfda --- /dev/null +++ b/DumpProto/lzo/targetver.h @@ -0,0 +1,13 @@ +#pragma once + +// ũδ ʿ ּ ÷ մϴ. ʿ ּ ÷ +// α׷ ϴ ʿ Ե Windows, Internet Explorer +// Դϴ. ũδ ̻ ÷ Ȱȭؾ +// ۵մϴ. + +// Ʒ ÷ 켱ϴ ÷ ϴ Ǹ Ͻʽÿ. +// ٸ ÷ Ǵ ش ֽ MSDN Ͻʽÿ. +#ifndef _WIN32_WINNT // ʿ ּ ÷ Windows Vista մϴ. +#define _WIN32_WINNT 0x0600 // ٸ Windows µ ֽʽÿ. +#endif + diff --git a/client.sln b/client.sln new file mode 100644 index 0000000..ea61fba --- /dev/null +++ b/client.sln @@ -0,0 +1,156 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31423.177 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CWebBrowser", "vs_files\CWebBrowser\CWebBrowser.vcxproj", "{2E953487-E73A-4C43-A9B6-174AB7B9A7E2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EffectLib", "vs_files\EffectLib\EffectLib.vcxproj", "{7F1EC9EC-35DA-4332-A339-B68E3C95976F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EterBase", "vs_files\EterBase\EterBase.vcxproj", "{D8C71073-CDC3-4AB1-A84A-5829F28BFF56}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EterGrnLib", "vs_files\EterGrnLib\EterGrnLib.vcxproj", "{935F7B65-3574-41C4-B4F9-1C2EC950463A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EterImageLib", "vs_files\EterImageLib\EterImageLib.vcxproj", "{3AA4BFA3-DF0E-42B9-A82C-E1BE16139AF3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EterLib", "vs_files\EterLib\EterLib.vcxproj", "{634437B1-4B3B-48C5-9220-619FB4D8F99B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EterLocale", "vs_files\EterLocale\EterLocale.vcxproj", "{08E76C01-D25C-4684-911C-876A33F27CE1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EterPack", "vs_files\EterPack\EterPack.vcxproj", "{EEAB8CB2-0891-4579-905E-B37A5F04F1D1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EterPythonLib", "vs_files\EterPythonLib\EterPythonLib.vcxproj", "{396764A4-9226-4F33-930F-E577A3BF51D4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GameLib", "vs_files\GameLib\GameLib.vcxproj", "{0C8DEF2C-F22D-4AD8-9D59-3147604C6B22}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MilesLib", "vs_files\MilesLib\MilesLib.vcxproj", "{FE2F4549-76C4-4448-88D7-67D8CAF477D2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PRTerrainLib", "vs_files\TerrainLib\TerrainLib.vcxproj", "{A1ED61AC-6324-43B1-BC9B-548208D625CF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ScriptLib", "vs_files\ScriptLib\ScriptLib.vcxproj", "{2084D43E-5FEE-4540-8EC9-8B159AD9D765}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SpeedTreeLib", "vs_files\SpeedTreeLib\SpeedTreeLib.vcxproj", "{602EF21F-918B-4678-85AE-44CCF1561DB8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SphereLib", "vs_files\SphereLib\SphereLib.vcxproj", "{B1F24BAE-61E8-41E9-B2BB-A6905E5D64FD}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UserInterface", "vs_files\UserInterface\UserInterface.vcxproj", "{E0DC3917-08C3-4F15-A7E7-6CB395EC83F0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Discord", "vs_files\Discord\Discord.vcxproj", "{034F4297-9DF7-47E8-83C3-89DF19A09E4A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Distribute|Win32 = Distribute|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2E953487-E73A-4C43-A9B6-174AB7B9A7E2}.Debug|Win32.ActiveCfg = Debug|Win32 + {2E953487-E73A-4C43-A9B6-174AB7B9A7E2}.Debug|Win32.Build.0 = Debug|Win32 + {2E953487-E73A-4C43-A9B6-174AB7B9A7E2}.Distribute|Win32.ActiveCfg = Distribute|Win32 + {2E953487-E73A-4C43-A9B6-174AB7B9A7E2}.Distribute|Win32.Build.0 = Distribute|Win32 + {2E953487-E73A-4C43-A9B6-174AB7B9A7E2}.Release|Win32.ActiveCfg = Release|Win32 + {2E953487-E73A-4C43-A9B6-174AB7B9A7E2}.Release|Win32.Build.0 = Release|Win32 + {7F1EC9EC-35DA-4332-A339-B68E3C95976F}.Debug|Win32.ActiveCfg = Debug|Win32 + {7F1EC9EC-35DA-4332-A339-B68E3C95976F}.Debug|Win32.Build.0 = Debug|Win32 + {7F1EC9EC-35DA-4332-A339-B68E3C95976F}.Distribute|Win32.ActiveCfg = Distribute|Win32 + {7F1EC9EC-35DA-4332-A339-B68E3C95976F}.Distribute|Win32.Build.0 = Distribute|Win32 + {7F1EC9EC-35DA-4332-A339-B68E3C95976F}.Release|Win32.ActiveCfg = Release|Win32 + {7F1EC9EC-35DA-4332-A339-B68E3C95976F}.Release|Win32.Build.0 = Release|Win32 + {D8C71073-CDC3-4AB1-A84A-5829F28BFF56}.Debug|Win32.ActiveCfg = Debug|Win32 + {D8C71073-CDC3-4AB1-A84A-5829F28BFF56}.Debug|Win32.Build.0 = Debug|Win32 + {D8C71073-CDC3-4AB1-A84A-5829F28BFF56}.Distribute|Win32.ActiveCfg = Distribute|Win32 + {D8C71073-CDC3-4AB1-A84A-5829F28BFF56}.Distribute|Win32.Build.0 = Distribute|Win32 + {D8C71073-CDC3-4AB1-A84A-5829F28BFF56}.Release|Win32.ActiveCfg = Release|Win32 + {D8C71073-CDC3-4AB1-A84A-5829F28BFF56}.Release|Win32.Build.0 = Release|Win32 + {935F7B65-3574-41C4-B4F9-1C2EC950463A}.Debug|Win32.ActiveCfg = Debug|Win32 + {935F7B65-3574-41C4-B4F9-1C2EC950463A}.Debug|Win32.Build.0 = Debug|Win32 + {935F7B65-3574-41C4-B4F9-1C2EC950463A}.Distribute|Win32.ActiveCfg = Distribute|Win32 + {935F7B65-3574-41C4-B4F9-1C2EC950463A}.Distribute|Win32.Build.0 = Distribute|Win32 + {935F7B65-3574-41C4-B4F9-1C2EC950463A}.Release|Win32.ActiveCfg = Release|Win32 + {935F7B65-3574-41C4-B4F9-1C2EC950463A}.Release|Win32.Build.0 = Release|Win32 + {3AA4BFA3-DF0E-42B9-A82C-E1BE16139AF3}.Debug|Win32.ActiveCfg = Debug|Win32 + {3AA4BFA3-DF0E-42B9-A82C-E1BE16139AF3}.Debug|Win32.Build.0 = Debug|Win32 + {3AA4BFA3-DF0E-42B9-A82C-E1BE16139AF3}.Distribute|Win32.ActiveCfg = Distribute|Win32 + {3AA4BFA3-DF0E-42B9-A82C-E1BE16139AF3}.Distribute|Win32.Build.0 = Distribute|Win32 + {3AA4BFA3-DF0E-42B9-A82C-E1BE16139AF3}.Release|Win32.ActiveCfg = Release|Win32 + {3AA4BFA3-DF0E-42B9-A82C-E1BE16139AF3}.Release|Win32.Build.0 = Release|Win32 + {634437B1-4B3B-48C5-9220-619FB4D8F99B}.Debug|Win32.ActiveCfg = Debug|Win32 + {634437B1-4B3B-48C5-9220-619FB4D8F99B}.Debug|Win32.Build.0 = Debug|Win32 + {634437B1-4B3B-48C5-9220-619FB4D8F99B}.Distribute|Win32.ActiveCfg = Distribute|Win32 + {634437B1-4B3B-48C5-9220-619FB4D8F99B}.Distribute|Win32.Build.0 = Distribute|Win32 + {634437B1-4B3B-48C5-9220-619FB4D8F99B}.Release|Win32.ActiveCfg = Release|Win32 + {634437B1-4B3B-48C5-9220-619FB4D8F99B}.Release|Win32.Build.0 = Release|Win32 + {08E76C01-D25C-4684-911C-876A33F27CE1}.Debug|Win32.ActiveCfg = Debug|Win32 + {08E76C01-D25C-4684-911C-876A33F27CE1}.Debug|Win32.Build.0 = Debug|Win32 + {08E76C01-D25C-4684-911C-876A33F27CE1}.Distribute|Win32.ActiveCfg = Distribute|Win32 + {08E76C01-D25C-4684-911C-876A33F27CE1}.Distribute|Win32.Build.0 = Distribute|Win32 + {08E76C01-D25C-4684-911C-876A33F27CE1}.Release|Win32.ActiveCfg = Release|Win32 + {08E76C01-D25C-4684-911C-876A33F27CE1}.Release|Win32.Build.0 = Release|Win32 + {EEAB8CB2-0891-4579-905E-B37A5F04F1D1}.Debug|Win32.ActiveCfg = Debug|Win32 + {EEAB8CB2-0891-4579-905E-B37A5F04F1D1}.Debug|Win32.Build.0 = Debug|Win32 + {EEAB8CB2-0891-4579-905E-B37A5F04F1D1}.Distribute|Win32.ActiveCfg = Distribute|Win32 + {EEAB8CB2-0891-4579-905E-B37A5F04F1D1}.Distribute|Win32.Build.0 = Distribute|Win32 + {EEAB8CB2-0891-4579-905E-B37A5F04F1D1}.Release|Win32.ActiveCfg = Release|Win32 + {EEAB8CB2-0891-4579-905E-B37A5F04F1D1}.Release|Win32.Build.0 = Release|Win32 + {396764A4-9226-4F33-930F-E577A3BF51D4}.Debug|Win32.ActiveCfg = Debug|Win32 + {396764A4-9226-4F33-930F-E577A3BF51D4}.Debug|Win32.Build.0 = Debug|Win32 + {396764A4-9226-4F33-930F-E577A3BF51D4}.Distribute|Win32.ActiveCfg = Distribute|Win32 + {396764A4-9226-4F33-930F-E577A3BF51D4}.Distribute|Win32.Build.0 = Distribute|Win32 + {396764A4-9226-4F33-930F-E577A3BF51D4}.Release|Win32.ActiveCfg = Release|Win32 + {396764A4-9226-4F33-930F-E577A3BF51D4}.Release|Win32.Build.0 = Release|Win32 + {0C8DEF2C-F22D-4AD8-9D59-3147604C6B22}.Debug|Win32.ActiveCfg = Debug|Win32 + {0C8DEF2C-F22D-4AD8-9D59-3147604C6B22}.Debug|Win32.Build.0 = Debug|Win32 + {0C8DEF2C-F22D-4AD8-9D59-3147604C6B22}.Distribute|Win32.ActiveCfg = Distribute|Win32 + {0C8DEF2C-F22D-4AD8-9D59-3147604C6B22}.Distribute|Win32.Build.0 = Distribute|Win32 + {0C8DEF2C-F22D-4AD8-9D59-3147604C6B22}.Release|Win32.ActiveCfg = Release|Win32 + {0C8DEF2C-F22D-4AD8-9D59-3147604C6B22}.Release|Win32.Build.0 = Release|Win32 + {FE2F4549-76C4-4448-88D7-67D8CAF477D2}.Debug|Win32.ActiveCfg = Debug|Win32 + {FE2F4549-76C4-4448-88D7-67D8CAF477D2}.Debug|Win32.Build.0 = Debug|Win32 + {FE2F4549-76C4-4448-88D7-67D8CAF477D2}.Distribute|Win32.ActiveCfg = Distribute|Win32 + {FE2F4549-76C4-4448-88D7-67D8CAF477D2}.Distribute|Win32.Build.0 = Distribute|Win32 + {FE2F4549-76C4-4448-88D7-67D8CAF477D2}.Release|Win32.ActiveCfg = Release|Win32 + {FE2F4549-76C4-4448-88D7-67D8CAF477D2}.Release|Win32.Build.0 = Release|Win32 + {A1ED61AC-6324-43B1-BC9B-548208D625CF}.Debug|Win32.ActiveCfg = Debug|Win32 + {A1ED61AC-6324-43B1-BC9B-548208D625CF}.Debug|Win32.Build.0 = Debug|Win32 + {A1ED61AC-6324-43B1-BC9B-548208D625CF}.Distribute|Win32.ActiveCfg = Distribute|Win32 + {A1ED61AC-6324-43B1-BC9B-548208D625CF}.Distribute|Win32.Build.0 = Distribute|Win32 + {A1ED61AC-6324-43B1-BC9B-548208D625CF}.Release|Win32.ActiveCfg = Release|Win32 + {A1ED61AC-6324-43B1-BC9B-548208D625CF}.Release|Win32.Build.0 = Release|Win32 + {2084D43E-5FEE-4540-8EC9-8B159AD9D765}.Debug|Win32.ActiveCfg = Debug|Win32 + {2084D43E-5FEE-4540-8EC9-8B159AD9D765}.Debug|Win32.Build.0 = Debug|Win32 + {2084D43E-5FEE-4540-8EC9-8B159AD9D765}.Distribute|Win32.ActiveCfg = Distribute|Win32 + {2084D43E-5FEE-4540-8EC9-8B159AD9D765}.Distribute|Win32.Build.0 = Distribute|Win32 + {2084D43E-5FEE-4540-8EC9-8B159AD9D765}.Release|Win32.ActiveCfg = Release|Win32 + {2084D43E-5FEE-4540-8EC9-8B159AD9D765}.Release|Win32.Build.0 = Release|Win32 + {602EF21F-918B-4678-85AE-44CCF1561DB8}.Debug|Win32.ActiveCfg = Debug|Win32 + {602EF21F-918B-4678-85AE-44CCF1561DB8}.Debug|Win32.Build.0 = Debug|Win32 + {602EF21F-918B-4678-85AE-44CCF1561DB8}.Distribute|Win32.ActiveCfg = Distribute|Win32 + {602EF21F-918B-4678-85AE-44CCF1561DB8}.Distribute|Win32.Build.0 = Distribute|Win32 + {602EF21F-918B-4678-85AE-44CCF1561DB8}.Release|Win32.ActiveCfg = Release|Win32 + {602EF21F-918B-4678-85AE-44CCF1561DB8}.Release|Win32.Build.0 = Release|Win32 + {B1F24BAE-61E8-41E9-B2BB-A6905E5D64FD}.Debug|Win32.ActiveCfg = Debug|Win32 + {B1F24BAE-61E8-41E9-B2BB-A6905E5D64FD}.Debug|Win32.Build.0 = Debug|Win32 + {B1F24BAE-61E8-41E9-B2BB-A6905E5D64FD}.Distribute|Win32.ActiveCfg = Distribute|Win32 + {B1F24BAE-61E8-41E9-B2BB-A6905E5D64FD}.Distribute|Win32.Build.0 = Distribute|Win32 + {B1F24BAE-61E8-41E9-B2BB-A6905E5D64FD}.Release|Win32.ActiveCfg = Release|Win32 + {B1F24BAE-61E8-41E9-B2BB-A6905E5D64FD}.Release|Win32.Build.0 = Release|Win32 + {E0DC3917-08C3-4F15-A7E7-6CB395EC83F0}.Debug|Win32.ActiveCfg = Debug|Win32 + {E0DC3917-08C3-4F15-A7E7-6CB395EC83F0}.Debug|Win32.Build.0 = Debug|Win32 + {E0DC3917-08C3-4F15-A7E7-6CB395EC83F0}.Distribute|Win32.ActiveCfg = Distribute|Win32 + {E0DC3917-08C3-4F15-A7E7-6CB395EC83F0}.Distribute|Win32.Build.0 = Distribute|Win32 + {E0DC3917-08C3-4F15-A7E7-6CB395EC83F0}.Release|Win32.ActiveCfg = Release|Win32 + {E0DC3917-08C3-4F15-A7E7-6CB395EC83F0}.Release|Win32.Build.0 = Release|Win32 + {034F4297-9DF7-47E8-83C3-89DF19A09E4A}.Debug|Win32.ActiveCfg = Debug|Win32 + {034F4297-9DF7-47E8-83C3-89DF19A09E4A}.Debug|Win32.Build.0 = Debug|Win32 + {034F4297-9DF7-47E8-83C3-89DF19A09E4A}.Distribute|Win32.ActiveCfg = Distribute|Win32 + {034F4297-9DF7-47E8-83C3-89DF19A09E4A}.Distribute|Win32.Build.0 = Distribute|Win32 + {034F4297-9DF7-47E8-83C3-89DF19A09E4A}.Release|Win32.ActiveCfg = Release|Win32 + {034F4297-9DF7-47E8-83C3-89DF19A09E4A}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {F46A540A-7868-41C7-AA54-AC5713509850} + EndGlobalSection +EndGlobal diff --git a/source.txt b/source.txt new file mode 100644 index 0000000..1305ecd --- /dev/null +++ b/source.txt @@ -0,0 +1 @@ +Special thanks to Mali: https://metin2.dev/topic/22115-compile-client-with-visual-studio-2022-src/ diff --git a/source/CWebBrowser/CWebBrowser.c b/source/CWebBrowser/CWebBrowser.c new file mode 100644 index 0000000..6461871 --- /dev/null +++ b/source/CWebBrowser/CWebBrowser.c @@ -0,0 +1,1717 @@ +/* Simple.c + +This is a Win32 C application (ie, no MFC, WTL, nor even any C++ -- just plain C) that demonstrates +how to embed a browser "control" (actually, an OLE object) in your own window (in order to display a +web page, or an HTML file on disk). + +This example opens two windows, each containing a browser object. The first window displays an HTML +string in memory. The second window displays Microsoft's web site. We also disable the pop-up context +menu, and resize the browser to fill our window. + +This is very loosely based upon a C++ example written by Chris Becke. I used that to learn the minimum +of what I needed to know about hosting the browser object. Then I wrote this example from the ground up +in C. + +This requires IE 5.0 (or better) -- due to the IDocHostUIHandler interface, or a browser that supports +the same level of OLE in-place activation. +*/ + + +#include +#include // Defines of stuff like IWebBrowser2. This is an include file with Visual C 6 and above +#include // Defines of stuff like IHTMLDocument2. This is an include file with Visual C 6 and above +#include // Defines of stuff like IDocHostUIHandler. This is an include file with Visual C 6 and above +//#include // for _ASSERT() + +#define _ASSERT(x) + + + +// A running count of how many windows we have open that contain a browser object +unsigned char WindowCount = 0; + +// The class name of our Window to host the browser. It can be anything of your choosing. +static const TCHAR ClassName[] = "Browser Example"; + +// This is used by DisplayHTMLStr(). It can be global because we never change it. +static const SAFEARRAYBOUND ArrayBound = {1, 0}; + + + + + + + + + + +// Our IOleInPlaceFrame functions that the browser may call +HRESULT STDMETHODCALLTYPE Frame_QueryInterface(IOleInPlaceFrame FAR* This, REFIID riid, LPVOID FAR* ppvObj); +HRESULT STDMETHODCALLTYPE Frame_AddRef(IOleInPlaceFrame FAR* This); +HRESULT STDMETHODCALLTYPE Frame_Release(IOleInPlaceFrame FAR* This); +HRESULT STDMETHODCALLTYPE Frame_GetWindow(IOleInPlaceFrame FAR* This, HWND FAR* lphwnd); +HRESULT STDMETHODCALLTYPE Frame_ContextSensitiveHelp(IOleInPlaceFrame FAR* This, BOOL fEnterMode); +HRESULT STDMETHODCALLTYPE Frame_GetBorder(IOleInPlaceFrame FAR* This, LPRECT lprectBorder); +HRESULT STDMETHODCALLTYPE Frame_RequestBorderSpace(IOleInPlaceFrame FAR* This, LPCBORDERWIDTHS pborderwidths); +HRESULT STDMETHODCALLTYPE Frame_SetBorderSpace(IOleInPlaceFrame FAR* This, LPCBORDERWIDTHS pborderwidths); +HRESULT STDMETHODCALLTYPE Frame_SetActiveObject(IOleInPlaceFrame FAR* This, IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName); +HRESULT STDMETHODCALLTYPE Frame_InsertMenus(IOleInPlaceFrame FAR* This, HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths); +HRESULT STDMETHODCALLTYPE Frame_SetMenu(IOleInPlaceFrame FAR* This, HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject); +HRESULT STDMETHODCALLTYPE Frame_RemoveMenus(IOleInPlaceFrame FAR* This, HMENU hmenuShared); +HRESULT STDMETHODCALLTYPE Frame_SetStatusText(IOleInPlaceFrame FAR* This, LPCOLESTR pszStatusText); +HRESULT STDMETHODCALLTYPE Frame_EnableModeless(IOleInPlaceFrame FAR* This, BOOL fEnable); +HRESULT STDMETHODCALLTYPE Frame_TranslateAccelerator(IOleInPlaceFrame FAR* This, LPMSG lpmsg, WORD wID); + +// Our IOleInPlaceFrame VTable. This is the array of pointers to the above functions in our C +// program that the browser may call in order to interact with our frame window that contains +// the browser object. We must define a particular set of functions that comprise the +// IOleInPlaceFrame set of functions (see above), and then stuff pointers to those functions +// in their respective 'slots' in this table. We want the browser to use this VTable with our +// IOleInPlaceFrame structure. +IOleInPlaceFrameVtbl MyIOleInPlaceFrameTable = {Frame_QueryInterface, +Frame_AddRef, +Frame_Release, +Frame_GetWindow, +Frame_ContextSensitiveHelp, +Frame_GetBorder, +Frame_RequestBorderSpace, +Frame_SetBorderSpace, +Frame_SetActiveObject, +Frame_InsertMenus, +Frame_SetMenu, +Frame_RemoveMenus, +Frame_SetStatusText, +Frame_EnableModeless, +Frame_TranslateAccelerator}; + +// We need to return an IOleInPlaceFrame struct to the browser object. And one of our IOleInPlaceFrame +// functions (Frame_GetWindow) is going to need to access our window handle. So let's create our own +// struct that starts off with an IOleInPlaceFrame struct (and that's important -- the IOleInPlaceFrame +// struct *must* be first), and then has an extra data field where we can store our own window's HWND. +// +// And because we may want to create multiple windows, each hosting its own browser object (to +// display its own web page), then we need to create a IOleInPlaceFrame struct for each window. So, +// we're not going to declare our IOleInPlaceFrame struct globally. We'll allocate it later using +// GlobalAlloc, and then stuff the appropriate HWND in it then, and also stuff a pointer to +// MyIOleInPlaceFrameTable in it. But let's just define it here. +typedef struct { + IOleInPlaceFrame frame; // The IOleInPlaceFrame must be first! + + /////////////////////////////////////////////////// + // Here you add any extra variables that you need + // to access in your IOleInPlaceFrame functions. + // You don't want those functions to access global + // variables, because then you couldn't use more + // than one browser object. (ie, You couldn't have + // multiple windows, each with its own embedded + // browser object to display a different web page). + // + // So here is where I added my extra HWND that my + // IOleInPlaceFrame function Frame_GetWindow() needs + // to access. + /////////////////////////////////////////////////// + HWND window; +} _IOleInPlaceFrameEx; + + + + + + +// Our IOleClientSite functions that the browser may call +HRESULT STDMETHODCALLTYPE Site_QueryInterface(IOleClientSite FAR* This, REFIID riid, void ** ppvObject); +HRESULT STDMETHODCALLTYPE Site_AddRef(IOleClientSite FAR* This); +HRESULT STDMETHODCALLTYPE Site_Release(IOleClientSite FAR* This); +HRESULT STDMETHODCALLTYPE Site_SaveObject(IOleClientSite FAR* This); +HRESULT STDMETHODCALLTYPE Site_GetMoniker(IOleClientSite FAR* This, DWORD dwAssign, DWORD dwWhichMoniker, IMoniker ** ppmk); +HRESULT STDMETHODCALLTYPE Site_GetContainer(IOleClientSite FAR* This, LPOLECONTAINER FAR* ppContainer); +HRESULT STDMETHODCALLTYPE Site_ShowObject(IOleClientSite FAR* This); +HRESULT STDMETHODCALLTYPE Site_OnShowWindow(IOleClientSite FAR* This, BOOL fShow); +HRESULT STDMETHODCALLTYPE Site_RequestNewObjectLayout(IOleClientSite FAR* This); + +// Our IOleClientSite VTable. This is the array of pointers to the above functions in our C +// program that the browser may call in order to interact with our frame window that contains +// the browser object. We must define a particular set of functions that comprise the +// IOleClientSite set of functions (see above), and then stuff pointers to those functions +// in their respective 'slots' in this table. We want the browser to use this VTable with our +// IOleClientSite structure. +IOleClientSiteVtbl MyIOleClientSiteTable = {Site_QueryInterface, +Site_AddRef, +Site_Release, +Site_SaveObject, +Site_GetMoniker, +Site_GetContainer, +Site_ShowObject, +Site_OnShowWindow, +Site_RequestNewObjectLayout}; + + + + + + +// Our IDocHostUIHandler functions that the browser may call +HRESULT STDMETHODCALLTYPE UI_QueryInterface(IDocHostUIHandler FAR* This, REFIID riid, void ** ppvObject); +HRESULT STDMETHODCALLTYPE UI_AddRef(IDocHostUIHandler FAR* This); +HRESULT STDMETHODCALLTYPE UI_Release(IDocHostUIHandler FAR* This); +HRESULT STDMETHODCALLTYPE UI_ShowContextMenu(IDocHostUIHandler FAR* This, DWORD dwID, POINT __RPC_FAR *ppt, IUnknown __RPC_FAR *pcmdtReserved, IDispatch __RPC_FAR *pdispReserved); +HRESULT STDMETHODCALLTYPE UI_GetHostInfo(IDocHostUIHandler FAR* This, DOCHOSTUIINFO __RPC_FAR *pInfo); +HRESULT STDMETHODCALLTYPE UI_ShowUI(IDocHostUIHandler FAR* This, DWORD dwID, IOleInPlaceActiveObject __RPC_FAR *pActiveObject, IOleCommandTarget __RPC_FAR *pCommandTarget, IOleInPlaceFrame __RPC_FAR *pFrame, IOleInPlaceUIWindow __RPC_FAR *pDoc); +HRESULT STDMETHODCALLTYPE UI_HideUI(IDocHostUIHandler FAR* This); +HRESULT STDMETHODCALLTYPE UI_UpdateUI(IDocHostUIHandler FAR* This); +HRESULT STDMETHODCALLTYPE UI_EnableModeless(IDocHostUIHandler FAR* This, BOOL fEnable); +HRESULT STDMETHODCALLTYPE UI_OnDocWindowActivate(IDocHostUIHandler FAR* This, BOOL fActivate); +HRESULT STDMETHODCALLTYPE UI_OnFrameWindowActivate(IDocHostUIHandler FAR* This, BOOL fActivate); +HRESULT STDMETHODCALLTYPE UI_ResizeBorder(IDocHostUIHandler FAR* This, LPCRECT prcBorder, IOleInPlaceUIWindow __RPC_FAR *pUIWindow, BOOL fRameWindow); +HRESULT STDMETHODCALLTYPE UI_TranslateAccelerator(IDocHostUIHandler FAR* This, LPMSG lpMsg, const GUID __RPC_FAR *pguidCmdGroup, DWORD nCmdID); +HRESULT STDMETHODCALLTYPE UI_GetOptionKeyPath(IDocHostUIHandler FAR* This, LPOLESTR __RPC_FAR *pchKey, DWORD dw); +HRESULT STDMETHODCALLTYPE UI_GetDropTarget(IDocHostUIHandler FAR* This, IDropTarget __RPC_FAR *pDropTarget, IDropTarget __RPC_FAR *__RPC_FAR *ppDropTarget); +HRESULT STDMETHODCALLTYPE UI_GetExternal(IDocHostUIHandler FAR* This, IDispatch __RPC_FAR *__RPC_FAR *ppDispatch); +HRESULT STDMETHODCALLTYPE UI_TranslateUrl(IDocHostUIHandler FAR* This, DWORD dwTranslate, OLECHAR __RPC_FAR *pchURLIn, OLECHAR __RPC_FAR *__RPC_FAR *ppchURLOut); +HRESULT STDMETHODCALLTYPE UI_FilterDataObject(IDocHostUIHandler FAR* This, IDataObject __RPC_FAR *pDO, IDataObject __RPC_FAR *__RPC_FAR *ppDORet); + +// Our IDocHostUIHandler VTable. This is the array of pointers to the above functions in our C +// program that the browser may call in order to replace/set certain user interface considerations +// (such as whether to display a pop-up context menu when the user right-clicks on the embedded +// browser object). We must define a particular set of functions that comprise the +// IDocHostUIHandler set of functions (see above), and then stuff pointers to those functions +// in their respective 'slots' in this table. We want the browser to use this VTable with our +// IDocHostUIHandler structure. +IDocHostUIHandlerVtbl MyIDocHostUIHandlerTable = {UI_QueryInterface, +UI_AddRef, +UI_Release, +UI_ShowContextMenu, +UI_GetHostInfo, +UI_ShowUI, +UI_HideUI, +UI_UpdateUI, +UI_EnableModeless, +UI_OnDocWindowActivate, +UI_OnFrameWindowActivate, +UI_ResizeBorder, +UI_TranslateAccelerator, +UI_GetOptionKeyPath, +UI_GetDropTarget, +UI_GetExternal, +UI_TranslateUrl, +UI_FilterDataObject}; + +// We'll allocate our IDocHostUIHandler object dynamically with GlobalAlloc() for reasons outlined later. + + + +// Our IOleInPlaceSite functions that the browser may call +HRESULT STDMETHODCALLTYPE InPlace_QueryInterface(IOleInPlaceSite FAR* This, REFIID riid, void ** ppvObject); +HRESULT STDMETHODCALLTYPE InPlace_AddRef(IOleInPlaceSite FAR* This); +HRESULT STDMETHODCALLTYPE InPlace_Release(IOleInPlaceSite FAR* This); +HRESULT STDMETHODCALLTYPE InPlace_GetWindow(IOleInPlaceSite FAR* This, HWND FAR* lphwnd); +HRESULT STDMETHODCALLTYPE InPlace_ContextSensitiveHelp(IOleInPlaceSite FAR* This, BOOL fEnterMode); +HRESULT STDMETHODCALLTYPE InPlace_CanInPlaceActivate(IOleInPlaceSite FAR* This); +HRESULT STDMETHODCALLTYPE InPlace_OnInPlaceActivate(IOleInPlaceSite FAR* This); +HRESULT STDMETHODCALLTYPE InPlace_OnUIActivate(IOleInPlaceSite FAR* This); +HRESULT STDMETHODCALLTYPE InPlace_GetWindowContext(IOleInPlaceSite FAR* This, LPOLEINPLACEFRAME FAR* lplpFrame,LPOLEINPLACEUIWINDOW FAR* lplpDoc,LPRECT lprcPosRect,LPRECT lprcClipRect,LPOLEINPLACEFRAMEINFO lpFrameInfo); +HRESULT STDMETHODCALLTYPE InPlace_Scroll(IOleInPlaceSite FAR* This, SIZE scrollExtent); +HRESULT STDMETHODCALLTYPE InPlace_OnUIDeactivate(IOleInPlaceSite FAR* This, BOOL fUndoable); +HRESULT STDMETHODCALLTYPE InPlace_OnInPlaceDeactivate(IOleInPlaceSite FAR* This); +HRESULT STDMETHODCALLTYPE InPlace_DiscardUndoState(IOleInPlaceSite FAR* This); +HRESULT STDMETHODCALLTYPE InPlace_DeactivateAndUndo(IOleInPlaceSite FAR* This); +HRESULT STDMETHODCALLTYPE InPlace_OnPosRectChange(IOleInPlaceSite FAR* This, LPCRECT lprcPosRect); + +// Our IOleInPlaceSite VTable. This is the array of pointers to the above functions in our C +// program that the browser may call in order to interact with our frame window that contains +// the browser object. We must define a particular set of functions that comprise the +// IOleInPlaceSite set of functions (see above), and then stuff pointers to those functions +// in their respective 'slots' in this table. We want the browser to use this VTable with our +// IOleInPlaceSite structure. +IOleInPlaceSiteVtbl MyIOleInPlaceSiteTable = {InPlace_QueryInterface, +InPlace_AddRef, +InPlace_Release, +InPlace_GetWindow, +InPlace_ContextSensitiveHelp, +InPlace_CanInPlaceActivate, +InPlace_OnInPlaceActivate, +InPlace_OnUIActivate, +InPlace_GetWindowContext, +InPlace_Scroll, +InPlace_OnUIDeactivate, +InPlace_OnInPlaceDeactivate, +InPlace_DiscardUndoState, +InPlace_DeactivateAndUndo, +InPlace_OnPosRectChange}; + +// We need to pass our IOleClientSite structure to OleCreate (which in turn gives it to the browser). +// But the browser is also going to ask our IOleClientSite's QueryInterface() to return a pointer to +// our IOleInPlaceSite and/or IDocHostUIHandler structs. So we'll need to have those pointers handy. +// Plus, some of our IOleClientSite and IOleInPlaceSite functions will need to have the HWND to our +// window, and also a pointer to our IOleInPlaceFrame struct. So let's create a single struct that +// has the IOleClientSite, IOleInPlaceSite, IDocHostUIHandler, and IOleInPlaceFrame structs all inside +// it (so we can easily get a pointer to any one from any of those structs' functions). As long as the +// IOleClientSite struct is the very first thing in this custom struct, it's all ok. We can still pass +// it to OleCreate() and pretend that it's an ordinary IOleClientSite. We'll call this new struct a +// _IOleClientSiteEx. +// +// And because we may want to create multiple windows, each hosting its own browser object (to +// display its own web page), then we need to create a unique _IOleClientSiteEx struct for +// each window. So, we're not going to declare this struct globally. We'll allocate it later +// using GlobalAlloc, and then initialize the structs within it. + +typedef struct { + IOleInPlaceSite inplace; // My IOleInPlaceSite object. Must be first with in _IOleInPlaceSiteEx. + + /////////////////////////////////////////////////// + // Here you add any extra variables that you need + // to access in your IOleInPlaceSite functions. + // + // So here is where I added my IOleInPlaceFrame + // struct. If you need extra variables, add them + // at the end. + /////////////////////////////////////////////////// + _IOleInPlaceFrameEx frame; // My IOleInPlaceFrame object. Must be first within my _IOleInPlaceFrameEx +} _IOleInPlaceSiteEx; + +typedef struct { + IDocHostUIHandler ui; // My IDocHostUIHandler object. Must be first. + + /////////////////////////////////////////////////// + // Here you add any extra variables that you need + // to access in your IDocHostUIHandler functions. + /////////////////////////////////////////////////// +} _IDocHostUIHandlerEx; + +typedef struct { + IOleClientSite client; // My IOleClientSite object. Must be first. + _IOleInPlaceSiteEx inplace; // My IOleInPlaceSite object. A convenient place to put it. + _IDocHostUIHandlerEx ui; // My IDocHostUIHandler object. Must be first within my _IDocHostUIHandlerEx. + + /////////////////////////////////////////////////// + // Here you add any extra variables that you need + // to access in your IOleClientSite functions. + /////////////////////////////////////////////////// +} _IOleClientSiteEx; + + + + + + + + + + + + + +// This is a simple C example. There are lots more things you can control about the browser object, but +// we don't do it in this example. _Many_ of the functions we provide below for the browser to call, will +// never actually be called by the browser in our example. Why? Because we don't do certain things +// with the browser that would require it to call those functions (even though we need to provide +// at least some stub for all of the functions). +// +// So, for these "dummy functions" that we don't expect the browser to call, we'll just stick in some +// assembly code that causes a debugger breakpoint and tells the browser object that we don't support +// the functionality. That way, if you try to do more things with the browser object, and it starts +// calling these "dummy functions", you'll know which ones you should add more meaningful code to. +#define NOTIMPLEMENTED _ASSERT(0); return(E_NOTIMPL) + + + + + +//////////////////////////////////// My IDocHostUIHandler functions ////////////////////////////////////// +// The browser object asks us for the pointer to our IDocHostUIHandler object by calling our IOleClientSite's +// QueryInterface (ie, Site_QueryInterface) and specifying a REFIID of IID_IDocHostUIHandler. +// +// NOTE: You need at least IE 4.0. Previous versions do not ask for, nor utilize, our IDocHostUIHandler functions. + +HRESULT STDMETHODCALLTYPE UI_QueryInterface(IDocHostUIHandler FAR* This, REFIID riid, LPVOID FAR* ppvObj) +{ + // The browser assumes that our IDocHostUIHandler object is associated with our IOleClientSite + // object. So it is possible that the browser may call our IDocHostUIHandler's QueryInterface() + // to ask us to return a pointer to our IOleClientSite, in the same way that the browser calls + // our IOleClientSite's QueryInterface() to ask for a pointer to our IDocHostUIHandler. + // + // Rather than duplicate much of the code in IOleClientSite's QueryInterface, let's just get + // a pointer to our _IOleClientSiteEx object, substitute it as the 'This' arg, and call our + // our IOleClientSite's QueryInterface. Note that since our _IDocHostUIHandlerEx is embedded right + // inside our _IOleClientSiteEx, and comes immediately after the _IOleInPlaceSiteEx, we can employ + // the following trickery to get the pointer to our _IOleClientSiteEx. + return(Site_QueryInterface((IOleClientSite *)((char *)This - sizeof(IOleClientSite) - sizeof(_IOleInPlaceSiteEx)), riid, ppvObj)); +} + +HRESULT STDMETHODCALLTYPE UI_AddRef(IDocHostUIHandler FAR* This) +{ + return(1); +} + +HRESULT STDMETHODCALLTYPE UI_Release(IDocHostUIHandler FAR* This) +{ + return(1); +} + +// Called when the browser object is about to display its context menu. +HRESULT STDMETHODCALLTYPE UI_ShowContextMenu(IDocHostUIHandler FAR* This, DWORD dwID, POINT __RPC_FAR *ppt, IUnknown __RPC_FAR *pcmdtReserved, IDispatch __RPC_FAR *pdispReserved) +{ + // If desired, we can pop up your own custom context menu here. Of course, + // we would need some way to get our window handle, so what we'd probably + // do is like what we did with our IOleInPlaceFrame object. We'd define and create + // our own IDocHostUIHandlerEx object with an embedded IDocHostUIHandler at the + // start of it. Then we'd add an extra HWND field to store our window handle. + // It could look like this: + // + // typedef struct _IDocHostUIHandlerEx { + // IDocHostUIHandler ui; // The IDocHostUIHandler must be first! + // HWND window; + // } IDocHostUIHandlerEx; + // + // Of course, we'd need a unique IDocHostUIHandlerEx object for each window, so + // EmbedBrowserObject() would have to allocate one of those too. And that's + // what we'd pass to our browser object (and it would in turn pass it to us + // here, instead of 'This' being a IDocHostUIHandler *). + + // We will return S_OK to tell the browser not to display its default context menu, + // or return S_FALSE to let the browser show its default context menu. For this + // example, we wish to disable the browser's default context menu. + return(S_OK); +} + +// Called at initialization of the browser object UI. We can set various features of the browser object here. +HRESULT STDMETHODCALLTYPE UI_GetHostInfo(IDocHostUIHandler FAR* This, DOCHOSTUIINFO __RPC_FAR *pInfo) +{ + pInfo->cbSize = sizeof(DOCHOSTUIINFO); + + // Set some flags. We don't want any 3D border. You can do other things like hide + // the scroll bar (DOCHOSTUIFLAG_SCROLL_NO), display picture display (DOCHOSTUIFLAG_NOPICS), + // disable any script running when the page is loaded (DOCHOSTUIFLAG_DISABLE_SCRIPT_INACTIVE), + // open a site in a new browser window when the user clicks on some link (DOCHOSTUIFLAG_OPENNEWWIN), + // and lots of other things. See the MSDN docs on the DOCHOSTUIINFO struct passed to us. + pInfo->dwFlags = DOCHOSTUIFLAG_NO3DBORDER; + + // Set what happens when the user double-clicks on the object. Here we use the default. + pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT; + + return(S_OK); +} + +// Called when the browser object shows its UI. This allows us to replace its menus and toolbars by creating our +// own and displaying them here. +HRESULT STDMETHODCALLTYPE UI_ShowUI(IDocHostUIHandler FAR* This, DWORD dwID, IOleInPlaceActiveObject __RPC_FAR *pActiveObject, IOleCommandTarget __RPC_FAR *pCommandTarget, IOleInPlaceFrame __RPC_FAR *pFrame, IOleInPlaceUIWindow __RPC_FAR *pDoc) +{ + // We've already got our own UI in place so just return S_OK to tell the browser + // not to display its menus/toolbars. Otherwise we'd return S_FALSE to let it do + // that. + return(S_OK); +} + +// Called when browser object hides its UI. This allows us to hide any menus/toolbars we created in ShowUI. +HRESULT STDMETHODCALLTYPE UI_HideUI(IDocHostUIHandler FAR* This) +{ + return(S_OK); +} + +// Called when the browser object wants to notify us that the command state has changed. We should update any +// controls we have that are dependent upon our embedded object, such as "Back", "Forward", "Stop", or "Home" +// buttons. +HRESULT STDMETHODCALLTYPE UI_UpdateUI(IDocHostUIHandler FAR* This) +{ + // We update our UI in our window message loop so we don't do anything here. + return(S_OK); +} + +// Called from the browser object's IOleInPlaceActiveObject object's EnableModeless() function. Also +// called when the browser displays a modal dialog box. +HRESULT STDMETHODCALLTYPE UI_EnableModeless(IDocHostUIHandler FAR* This, BOOL fEnable) +{ + return(S_OK); +} + +// Called from the browser object's IOleInPlaceActiveObject object's OnDocWindowActivate() function. +// This informs off of when the object is getting/losing the focus. +HRESULT STDMETHODCALLTYPE UI_OnDocWindowActivate(IDocHostUIHandler FAR* This, BOOL fActivate) +{ + return(S_OK); +} + +// Called from the browser object's IOleInPlaceActiveObject object's OnFrameWindowActivate() function. +HRESULT STDMETHODCALLTYPE UI_OnFrameWindowActivate(IDocHostUIHandler FAR* This, BOOL fActivate) +{ + return(S_OK); +} + +// Called from the browser object's IOleInPlaceActiveObject object's ResizeBorder() function. +HRESULT STDMETHODCALLTYPE UI_ResizeBorder(IDocHostUIHandler FAR* This, LPCRECT prcBorder, IOleInPlaceUIWindow __RPC_FAR *pUIWindow, BOOL fRameWindow) +{ + return(S_OK); +} + +// Called from the browser object's TranslateAccelerator routines to translate key strokes to commands. +HRESULT STDMETHODCALLTYPE UI_TranslateAccelerator(IDocHostUIHandler FAR* This, LPMSG lpMsg, const GUID __RPC_FAR *pguidCmdGroup, DWORD nCmdID) +{ + // We don't intercept any keystrokes, so we do nothing here. But for example, if we wanted to + // override the TAB key, perhaps do something with it ourselves, and then tell the browser + // not to do anything with this keystroke, we'd do: + // + // if (pMsg && pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_TAB) + // { + // // Here we do something as a result of a TAB key press. + // + // // Tell the browser not to do anything with it. + // return(S_FALSE); + // } + // + // // Otherwise, let the browser do something with this message. + // return(S_OK); + + // For our example, we want to make sure that the user can invoke some key to popup the context + // menu, so we'll tell it to ignore all messages. + return(S_FALSE); +} + +// Called by the browser object to find where the host wishes the browser to get its options in the registry. +// We can use this to prevent the browser from using its default settings in the registry, by telling it to use +// some other registry key we've setup with the options we want. +HRESULT STDMETHODCALLTYPE UI_GetOptionKeyPath(IDocHostUIHandler FAR* This, LPOLESTR __RPC_FAR *pchKey, DWORD dw) +{ + // Let the browser use its default registry settings. + return(S_FALSE); +} + +// Called by the browser object when it is used as a drop target. We can supply our own IDropTarget object, +// IDropTarget functions, and IDropTarget VTable if we want to determine what happens when someone drags and +// drops some object on our embedded browser object. +HRESULT STDMETHODCALLTYPE UI_GetDropTarget(IDocHostUIHandler FAR* This, IDropTarget __RPC_FAR *pDropTarget, IDropTarget __RPC_FAR *__RPC_FAR *ppDropTarget) +{ + // Return our IDropTarget object associated with this IDocHostUIHandler object. I don't + // know why we don't do this via UI_QueryInterface(), but we don't. + + // NOTE: If we want/need an IDropTarget interface, then we would have had to setup our own + // IDropTarget functions, IDropTarget VTable, and create an IDropTarget object. We'd want to put + // a pointer to the IDropTarget object in our own custom IDocHostUIHandlerEx object (like how + // we may add an HWND field for the use of UI_ShowContextMenu). So when we created our + // IDocHostUIHandlerEx object, maybe we'd add a 'idrop' field to the end of it, and + // store a pointer to our IDropTarget object there. Then we could return this pointer as so: + // + // *pDropTarget = ((IDocHostUIHandlerEx FAR *)This)->idrop; + // return(S_OK); + + // But for our purposes, we don't need an IDropTarget object, so we'll tell whomever is calling + // us that we don't have one. + return(S_FALSE); +} + +// Called by the browser when it wants a pointer to our IDispatch object. This object allows us to expose +// our own automation interface (ie, our own COM objects) to other entities that are running within the +// context of the browser so they can call our functions if they want. An example could be a javascript +// running in the URL we display could call our IDispatch functions. We'd write them so that any args passed +// to them would use the generic datatypes like a BSTR for utmost flexibility. +HRESULT STDMETHODCALLTYPE UI_GetExternal(IDocHostUIHandler FAR* This, IDispatch __RPC_FAR *__RPC_FAR *ppDispatch) +{ + // Return our IDispatch object associated with this IDocHostUIHandler object. I don't + // know why we don't do this via UI_QueryInterface(), but we don't. + + // NOTE: If we want/need an IDispatch interface, then we would have had to setup our own + // IDispatch functions, IDispatch VTable, and create an IDispatch object. We'd want to put + // a pointer to the IDispatch object in our custom _IDocHostUIHandlerEx object (like how + // we may add an HWND field for the use of UI_ShowContextMenu). So when we defined our + // _IDocHostUIHandlerEx object, maybe we'd add a 'idispatch' field to the end of it, and + // store a pointer to our IDispatch object there. Then we could return this pointer as so: + // + // *ppDispatch = ((_IDocHostUIHandlerEx FAR *)This)->idispatch; + // return(S_OK); + + // But for our purposes, we don't need an IDispatch object, so we'll tell whomever is calling + // us that we don't have one. Note: We must set ppDispatch to 0 if we don't return our own + // IDispatch object. + *ppDispatch = 0; + return(S_FALSE); +} + +// Called by the browser object to give us an opportunity to modify the URL to be loaded. +HRESULT STDMETHODCALLTYPE UI_TranslateUrl(IDocHostUIHandler FAR* This, DWORD dwTranslate, OLECHAR __RPC_FAR *pchURLIn, OLECHAR __RPC_FAR *__RPC_FAR *ppchURLOut) +{ + // We don't need to modify the URL. Note: We need to set ppchURLOut to 0 if we don't + // return an OLECHAR (buffer) containing a modified version of pchURLIn. + *ppchURLOut = 0; + return(S_FALSE); +} + +// Called by the browser when it does cut/paste to the clipboard. This allows us to block certain clipboard +// formats or support additional clipboard formats. +HRESULT STDMETHODCALLTYPE UI_FilterDataObject(IDocHostUIHandler FAR* This, IDataObject __RPC_FAR *pDO, IDataObject __RPC_FAR *__RPC_FAR *ppDORet) +{ + // Return our IDataObject object associated with this IDocHostUIHandler object. I don't + // know why we don't do this via UI_QueryInterface(), but we don't. + + // NOTE: If we want/need an IDataObject interface, then we would have had to setup our own + // IDataObject functions, IDataObject VTable, and create an IDataObject object. We'd want to put + // a pointer to the IDataObject object in our custom _IDocHostUIHandlerEx object (like how + // we may add an HWND field for the use of UI_ShowContextMenu). So when we defined our + // _IDocHostUIHandlerEx object, maybe we'd add a 'idata' field to the end of it, and + // store a pointer to our IDataObject object there. Then we could return this pointer as so: + // + // *ppDORet = ((_IDocHostUIHandlerEx FAR *)This)->idata; + // return(S_OK); + + // But for our purposes, we don't need an IDataObject object, so we'll tell whomever is calling + // us that we don't have one. Note: We must set ppDORet to 0 if we don't return our own + // IDataObject object. + *ppDORet = 0; + return(S_FALSE); +} + + + + + + + + + + + + + +////////////////////////////////////// My IOleClientSite functions ///////////////////////////////////// +// We give the browser object a pointer to our IOleClientSite object when we call OleCreate() or DoVerb(). + +/************************* Site_QueryInterface() ************************* + * The browser object calls this when it wants a pointer to one of our + * IOleClientSite, IDocHostUIHandler, or IOleInPlaceSite structures. They + * are all accessible via the _IOleClientSiteEx struct we allocated in + * EmbedBrowserObject() and passed to DoVerb() and OleCreate(). + * + * This = A pointer to whatever _IOleClientSiteEx struct we passed to + * OleCreate() or DoVerb(). + * riid = A GUID struct that the browser passes us to clue us as to + * which type of struct (object) it would like a pointer + * returned for. + * ppvObject = Where the browser wants us to return a pointer to the + * appropriate struct. (ie, It passes us a handle to fill in). + * + * RETURNS: S_OK if we return the struct, or E_NOINTERFACE if we don't have + * the requested struct. + */ + +HRESULT STDMETHODCALLTYPE Site_QueryInterface(IOleClientSite FAR* This, REFIID riid, void ** ppvObject) +{ + // It just so happens that the first arg passed to us is our _IOleClientSiteEx struct we allocated + // and passed to DoVerb() and OleCreate(). Nevermind that 'This' is declared is an IOleClientSite *. + // Remember that in EmbedBrowserObject(), we allocated our own _IOleClientSiteEx struct, and lied + // to OleCreate() and DoVerb() -- passing our _IOleClientSiteEx struct and saying it was an + // IOleClientSite struct. It's ok. An _IOleClientSiteEx starts with an embedded IOleClientSite, so + // the browser didn't mind. So that's what the browser object is passing us now. The browser doesn't + // know that it's really an _IOleClientSiteEx struct. But we do. So we can recast it and use it as + // so here. + + // If the browser is asking us to match IID_IOleClientSite, then it wants us to return a pointer to + // our IOleClientSite struct. Then the browser will use the VTable in that struct to call our + // IOleClientSite functions. It will also pass this same pointer to all of our IOleClientSite + // functions. + // + // Actually, we're going to lie to the browser again. We're going to return our own _IOleClientSiteEx + // struct, and tell the browser that it's a IOleClientSite struct. It's ok. The first thing in our + // _IOleClientSiteEx is an embedded IOleClientSite, so the browser doesn't mind. We want the browser + // to continue passing our _IOleClientSiteEx pointer wherever it would normally pass a IOleClientSite + // pointer. + // + // The IUnknown interface uses the same VTable as the first object in our _IOleClientSiteEx + // struct (which happens to be an IOleClientSite). So if the browser is asking us to match + // IID_IUnknown, then we'll also return a pointer to our _IOleClientSiteEx. + + if (!memcmp(riid, &IID_IUnknown, sizeof(GUID)) || !memcmp(riid, &IID_IOleClientSite, sizeof(GUID))) + *ppvObject = &((_IOleClientSiteEx *)This)->client; + + // If the browser is asking us to match IID_IOleInPlaceSite, then it wants us to return a pointer to + // our IOleInPlaceSite struct. Then the browser will use the VTable in that struct to call our + // IOleInPlaceSite functions. It will also pass this same pointer to all of our IOleInPlaceSite + // functions (except for Site_QueryInterface, Site_AddRef, and Site_Release. Those will always get + // the pointer to our _IOleClientSiteEx. + // + // Actually, we're going to lie to the browser. We're going to return our own _IOleInPlaceSiteEx + // struct, and tell the browser that it's a IOleInPlaceSite struct. It's ok. The first thing in + // our _IOleInPlaceSiteEx is an embedded IOleInPlaceSite, so the browser doesn't mind. We want the + // browser to continue passing our _IOleInPlaceSiteEx pointer wherever it would normally pass a + // IOleInPlaceSite pointer. + else if (!memcmp(riid, &IID_IOleInPlaceSite, sizeof(GUID))) + *ppvObject = &((_IOleClientSiteEx *)This)->inplace; + + // If the browser is asking us to match IID_IDocHostUIHandler, then it wants us to return a pointer to + // our IDocHostUIHandler struct. Then the browser will use the VTable in that struct to call our + // IDocHostUIHandler functions. It will also pass this same pointer to all of our IDocHostUIHandler + // functions (except for Site_QueryInterface, Site_AddRef, and Site_Release. Those will always get + // the pointer to our _IOleClientSiteEx. + // + // Actually, we're going to lie to the browser. We're going to return our own _IDocHostUIHandlerEx + // struct, and tell the browser that it's a IDocHostUIHandler struct. It's ok. The first thing in + // our _IDocHostUIHandlerEx is an embedded IDocHostUIHandler, so the browser doesn't mind. We want the + // browser to continue passing our _IDocHostUIHandlerEx pointer wherever it would normally pass a + // IDocHostUIHandler pointer. My, we're really playing dirty tricks on the browser here. heheh. + else if (!memcmp(riid, &IID_IDocHostUIHandler, sizeof(GUID))) + *ppvObject = &((_IOleClientSiteEx *)This)->ui; + + // For other types of objects the browser wants, just report that we don't have any such objects. + // NOTE: If you want to add additional functionality to your browser hosting, you may need to + // provide some more objects here. You'll have to investigate what the browser is asking for + // (ie, what REFIID it is passing). + else + { + *ppvObject = 0; + return(E_NOINTERFACE); + } + + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE Site_AddRef(IOleClientSite FAR* This) +{ + return(1); +} + +HRESULT STDMETHODCALLTYPE Site_Release(IOleClientSite FAR* This) +{ + return(1); +} + +HRESULT STDMETHODCALLTYPE Site_SaveObject(IOleClientSite FAR* This) +{ + NOTIMPLEMENTED; +} + +HRESULT STDMETHODCALLTYPE Site_GetMoniker(IOleClientSite FAR* This, DWORD dwAssign, DWORD dwWhichMoniker, IMoniker ** ppmk) +{ + NOTIMPLEMENTED; +} + +HRESULT STDMETHODCALLTYPE Site_GetContainer(IOleClientSite FAR* This, LPOLECONTAINER FAR* ppContainer) +{ + // Tell the browser that we are a simple object and don't support a container + *ppContainer = 0; + + return(E_NOINTERFACE); +} + +HRESULT STDMETHODCALLTYPE Site_ShowObject(IOleClientSite FAR* This) +{ + return(NOERROR); +} + +HRESULT STDMETHODCALLTYPE Site_OnShowWindow(IOleClientSite FAR* This, BOOL fShow) +{ + NOTIMPLEMENTED; +} + +HRESULT STDMETHODCALLTYPE Site_RequestNewObjectLayout(IOleClientSite FAR* This) +{ + NOTIMPLEMENTED; +} + + + + + + + + + + + +////////////////////////////////////// My IOleInPlaceSite functions ///////////////////////////////////// +// The browser object asks us for the pointer to our IOleInPlaceSite object by calling our IOleClientSite's +// QueryInterface (ie, Site_QueryInterface) and specifying a REFIID of IID_IOleInPlaceSite. + +HRESULT STDMETHODCALLTYPE InPlace_QueryInterface(IOleInPlaceSite FAR* This, REFIID riid, LPVOID FAR* ppvObj) +{ + // The browser assumes that our IOleInPlaceSite object is associated with our IOleClientSite + // object. So it is possible that the browser may call our IOleInPlaceSite's QueryInterface() + // to ask us to return a pointer to our IOleClientSite, in the same way that the browser calls + // our IOleClientSite's QueryInterface() to ask for a pointer to our IOleInPlaceSite. + // + // Rather than duplicate much of the code in IOleClientSite's QueryInterface, let's just get + // a pointer to our _IOleClientSiteEx object, substitute it as the 'This' arg, and call our + // our IOleClientSite's QueryInterface. Note that since our IOleInPlaceSite is embedded right + // inside our _IOleClientSiteEx, and comes immediately after the IOleClientSite, we can employ + // the following trickery to get the pointer to our _IOleClientSiteEx. + return(Site_QueryInterface((IOleClientSite *)((char *)This - sizeof(IOleClientSite)), riid, ppvObj)); +} + +HRESULT STDMETHODCALLTYPE InPlace_AddRef(IOleInPlaceSite FAR* This) +{ + return(1); +} + +HRESULT STDMETHODCALLTYPE InPlace_Release(IOleInPlaceSite FAR* This) +{ + return(1); +} + +HRESULT STDMETHODCALLTYPE InPlace_GetWindow(IOleInPlaceSite FAR* This, HWND FAR* lphwnd) +{ + // Return the HWND of the window that contains this browser object. We stored that + // HWND in our _IOleInPlaceSiteEx struct. Nevermind that the function declaration for + // Site_GetWindow says that 'This' is an IOleInPlaceSite *. Remember that in + // EmbedBrowserObject(), we allocated our own _IOleInPlaceSiteEx struct which + // contained an embedded IOleInPlaceSite struct within it. And when the browser + // called Site_QueryInterface() to get a pointer to our IOleInPlaceSite object, we + // returned a pointer to our _IOleClientSiteEx. The browser doesn't know this. But + // we do. That's what we're really being passed, so we can recast it and use it as + // so here. + *lphwnd = ((_IOleInPlaceSiteEx FAR*)This)->frame.window; + + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE InPlace_ContextSensitiveHelp(IOleInPlaceSite FAR* This, BOOL fEnterMode) +{ + NOTIMPLEMENTED; +} + +HRESULT STDMETHODCALLTYPE InPlace_CanInPlaceActivate(IOleInPlaceSite FAR* This) +{ + // Tell the browser we can in place activate + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE InPlace_OnInPlaceActivate(IOleInPlaceSite FAR* This) +{ + // Tell the browser we did it ok + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE InPlace_OnUIActivate(IOleInPlaceSite FAR* This) +{ + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE InPlace_GetWindowContext(IOleInPlaceSite FAR* This, LPOLEINPLACEFRAME FAR* lplpFrame, LPOLEINPLACEUIWINDOW FAR* lplpDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo) +{ + // Give the browser the pointer to our IOleInPlaceFrame struct. We stored that pointer + // in our _IOleInPlaceSiteEx struct. Nevermind that the function declaration for + // Site_GetWindowContext says that 'This' is an IOleInPlaceSite *. Remember that in + // EmbedBrowserObject(), we allocated our own _IOleInPlaceSiteEx struct which + // contained an embedded IOleInPlaceSite struct within it. And when the browser + // called Site_QueryInterface() to get a pointer to our IOleInPlaceSite object, we + // returned a pointer to our _IOleClientSiteEx. The browser doesn't know this. But + // we do. That's what we're really being passed, so we can recast it and use it as + // so here. + // + // Actually, we're giving the browser a pointer to our own _IOleInPlaceSiteEx struct, + // but telling the browser that it's a IOleInPlaceSite struct. No problem. Our + // _IOleInPlaceSiteEx starts with an embedded IOleInPlaceSite, so the browser is + // cool with it. And we want the browser to pass a pointer to this _IOleInPlaceSiteEx + // wherever it would pass a IOleInPlaceSite struct to our IOleInPlaceSite functions. + *lplpFrame = (LPOLEINPLACEFRAME)&((_IOleInPlaceSiteEx *)This)->frame; + + // We have no OLEINPLACEUIWINDOW + *lplpDoc = 0; + + // Fill in some other info for the browser + lpFrameInfo->fMDIApp = FALSE; + lpFrameInfo->hwndFrame = ((_IOleInPlaceFrameEx *)*lplpFrame)->window; + lpFrameInfo->haccel = 0; + lpFrameInfo->cAccelEntries = 0; + + // Give the browser the dimensions of where it can draw. We give it our entire window to fill. + // We do this in InPlace_OnPosRectChange() which is called right when a window is first + // created anyway, so no need to duplicate it here. +// GetClientRect(lpFrameInfo->hwndFrame, lprcPosRect); +// GetClientRect(lpFrameInfo->hwndFrame, lprcClipRect); + + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE InPlace_Scroll(IOleInPlaceSite FAR* This, SIZE scrollExtent) +{ + NOTIMPLEMENTED; +} + +HRESULT STDMETHODCALLTYPE InPlace_OnUIDeactivate(IOleInPlaceSite FAR* This, BOOL fUndoable) +{ + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE InPlace_OnInPlaceDeactivate(IOleInPlaceSite FAR* This) +{ + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE InPlace_DiscardUndoState(IOleInPlaceSite FAR* This) +{ + NOTIMPLEMENTED; +} + +HRESULT STDMETHODCALLTYPE InPlace_DeactivateAndUndo(IOleInPlaceSite FAR* This) +{ + NOTIMPLEMENTED; +} + +// Called when the position of the browser object is changed, such as when we call the IWebBrowser2's put_Width(), +// put_Height(), put_Left(), or put_Right(). +HRESULT STDMETHODCALLTYPE InPlace_OnPosRectChange(IOleInPlaceSite FAR* This, LPCRECT lprcPosRect) +{ + IOleObject *browserObject; + IOleInPlaceObject *inplace; + + // We need to get the browser's IOleInPlaceObject object so we can call its SetObjectRects + // function. + browserObject = *((IOleObject **)((char *)This - sizeof(IOleObject *) - sizeof(IOleClientSite))); + if (!browserObject->lpVtbl->QueryInterface(browserObject, &IID_IOleInPlaceObject, (void**)&inplace)) + { + // Give the browser the dimensions of where it can draw. + inplace->lpVtbl->SetObjectRects(inplace, lprcPosRect, lprcPosRect); + inplace->lpVtbl->Release(inplace); + } + + return(S_OK); +} + + + + + + + +////////////////////////////////////// My IOleInPlaceFrame functions ///////////////////////////////////////// + +HRESULT STDMETHODCALLTYPE Frame_QueryInterface(IOleInPlaceFrame FAR* This, REFIID riid, LPVOID FAR* ppvObj) +{ + NOTIMPLEMENTED; +} + +HRESULT STDMETHODCALLTYPE Frame_AddRef(IOleInPlaceFrame FAR* This) +{ + return(1); +} + +HRESULT STDMETHODCALLTYPE Frame_Release(IOleInPlaceFrame FAR* This) +{ + return(1); +} + +HRESULT STDMETHODCALLTYPE Frame_GetWindow(IOleInPlaceFrame FAR* This, HWND FAR* lphwnd) +{ + // Give the browser the HWND to our window that contains the browser object. We + // stored that HWND in our IOleInPlaceFrame struct. Nevermind that the function + // declaration for Frame_GetWindow says that 'This' is an IOleInPlaceFrame *. Remember + // that in EmbedBrowserObject(), we allocated our own IOleInPlaceFrameEx struct which + // contained an embedded IOleInPlaceFrame struct within it. And then we lied when + // Site_GetWindowContext() returned that IOleInPlaceFrameEx. So that's what the + // browser is passing us. It doesn't know that. But we do. So we can recast it and + // use it as so here. + *lphwnd = ((_IOleInPlaceFrameEx *)This)->window; + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE Frame_ContextSensitiveHelp(IOleInPlaceFrame FAR* This, BOOL fEnterMode) +{ + NOTIMPLEMENTED; +} + +HRESULT STDMETHODCALLTYPE Frame_GetBorder(IOleInPlaceFrame FAR* This, LPRECT lprectBorder) +{ + NOTIMPLEMENTED; +} + +HRESULT STDMETHODCALLTYPE Frame_RequestBorderSpace(IOleInPlaceFrame FAR* This, LPCBORDERWIDTHS pborderwidths) +{ + NOTIMPLEMENTED; +} + +HRESULT STDMETHODCALLTYPE Frame_SetBorderSpace(IOleInPlaceFrame FAR* This, LPCBORDERWIDTHS pborderwidths) +{ + NOTIMPLEMENTED; +} + +HRESULT STDMETHODCALLTYPE Frame_SetActiveObject(IOleInPlaceFrame FAR* This, IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName) +{ + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE Frame_InsertMenus(IOleInPlaceFrame FAR* This, HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths) +{ + NOTIMPLEMENTED; +} + +HRESULT STDMETHODCALLTYPE Frame_SetMenu(IOleInPlaceFrame FAR* This, HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject) +{ + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE Frame_RemoveMenus(IOleInPlaceFrame FAR* This, HMENU hmenuShared) +{ + NOTIMPLEMENTED; +} + +HRESULT STDMETHODCALLTYPE Frame_SetStatusText(IOleInPlaceFrame FAR* This, LPCOLESTR pszStatusText) +{ + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE Frame_EnableModeless(IOleInPlaceFrame FAR* This, BOOL fEnable) +{ + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE Frame_TranslateAccelerator(IOleInPlaceFrame FAR* This, LPMSG lpmsg, WORD wID) +{ + NOTIMPLEMENTED; +} + + + + + + + + +/*************************** UnEmbedBrowserObject() ************************ + * Called to detach the browser object from our host window, and free its + * resources, right before we destroy our window. + * + * hwnd = Handle to the window hosting the browser object. + * + * NOTE: The pointer to the browser object must have been stored in the + * window's USERDATA field. In other words, don't call UnEmbedBrowserObject(). + * with a HWND that wasn't successfully passed to EmbedBrowserObject(). + */ + +void UnEmbedBrowserObject(HWND hwnd) +{ + IOleObject **browserHandle; + IOleObject *browserObject; + + // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when + // we initially attached the browser object to this window. + if ((browserHandle = (IOleObject **)GetWindowLong(hwnd, GWL_USERDATA))) + { + // Unembed the browser object, and release its resources. + browserObject = *browserHandle; + browserObject->lpVtbl->Close(browserObject, OLECLOSE_NOSAVE); + browserObject->lpVtbl->Release(browserObject); + + GlobalFree(browserHandle); + + return; + } + + // You must have called this for a window that wasn't successfully passed to EmbedBrowserObject(). + // Bad boy! + _ASSERT(0); +} + + + + + + +#define WEBPAGE_GOBACK 0 +#define WEBPAGE_GOFORWARD 1 +#define WEBPAGE_GOHOME 2 +#define WEBPAGE_SEARCH 3 +#define WEBPAGE_REFRESH 4 +#define WEBPAGE_STOP 5 + +/******************************* DoPageAction() ************************** + * Implements the functionality of a "Back". "Forward", "Home", "Search", + * "Refresh", or "Stop" button. + * + * hwnd = Handle to the window hosting the browser object. + * action = One of the following: + * 0 = Move back to the previously viewed web page. + * 1 = Move forward to the previously viewed web page. + * 2 = Move to the home page. + * 3 = Search. + * 4 = Refresh the page. + * 5 = Stop the currently loading page. + * + * NOTE: EmbedBrowserObject() must have been successfully called once with the + * specified window, prior to calling this function. You need call + * EmbedBrowserObject() once only, and then you can make multiple calls to + * this function to display numerous pages in the specified window. + */ + +void DoPageAction(HWND hwnd, DWORD action) +{ + IWebBrowser2 *webBrowser2; + IOleObject *browserObject; + + // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when + // we initially attached the browser object to this window. + browserObject = *((IOleObject **)GetWindowLong(hwnd, GWL_USERDATA)); + + // We want to get the base address (ie, a pointer) to the IWebBrowser2 object embedded within the browser + // object, so we can call some of the functions in the former's table. + if (!browserObject->lpVtbl->QueryInterface(browserObject, &IID_IWebBrowser2, (void**)&webBrowser2)) + { + // Ok, now the pointer to our IWebBrowser2 object is in 'webBrowser2', and so its VTable is + // webBrowser2->lpVtbl. + + // Call the desired function + switch (action) + { + case WEBPAGE_GOBACK: + { + // Call the IWebBrowser2 object's GoBack function. + webBrowser2->lpVtbl->GoBack(webBrowser2); + break; + } + + case WEBPAGE_GOFORWARD: + { + // Call the IWebBrowser2 object's GoForward function. + webBrowser2->lpVtbl->GoForward(webBrowser2); + break; + } + + case WEBPAGE_GOHOME: + { + // Call the IWebBrowser2 object's GoHome function. + webBrowser2->lpVtbl->GoHome(webBrowser2); + break; + } + + case WEBPAGE_SEARCH: + { + // Call the IWebBrowser2 object's GoSearch function. + webBrowser2->lpVtbl->GoSearch(webBrowser2); + break; + } + + case WEBPAGE_REFRESH: + { + // Call the IWebBrowser2 object's Refresh function. + webBrowser2->lpVtbl->Refresh(webBrowser2); + break; + } + + case WEBPAGE_STOP: + { + // Call the IWebBrowser2 object's Stop function. + webBrowser2->lpVtbl->Stop(webBrowser2); + break; + } + } + + // Release the IWebBrowser2 object. + webBrowser2->lpVtbl->Release(webBrowser2); + } +} + + + + + +/******************************* DisplayHTMLStr() **************************** + * Takes a string containing some HTML BODY, and displays it in the specified + * window. For example, perhaps you want to display the HTML text of... + * + *

This is a picture.

+ * + * hwnd = Handle to the window hosting the browser object. + * string = Pointer to nul-terminated string containing the HTML BODY. + * (NOTE: No tags are required in the string). + * + * RETURNS: 0 if success, or non-zero if an error. + * + * NOTE: EmbedBrowserObject() must have been successfully called once with the + * specified window, prior to calling this function. You need call + * EmbedBrowserObject() once only, and then you can make multiple calls to + * this function to display numerous pages in the specified window. + */ + +long DisplayHTMLStr(HWND hwnd, LPCTSTR string) +{ + IWebBrowser2 *webBrowser2; + LPDISPATCH lpDispatch; + IHTMLDocument2 *htmlDoc2; + IOleObject *browserObject; + SAFEARRAY *sfArray; + VARIANT myURL; + VARIANT *pVar; + BSTR bstr; + + // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when + // we initially attached the browser object to this window. + browserObject = *((IOleObject **)GetWindowLong(hwnd, GWL_USERDATA)); + + // Assume an error. + bstr = 0; + + // We want to get the base address (ie, a pointer) to the IWebBrowser2 object embedded within the browser + // object, so we can call some of the functions in the former's table. + if (!browserObject->lpVtbl->QueryInterface(browserObject, &IID_IWebBrowser2, (void**)&webBrowser2)) + { + // Ok, now the pointer to our IWebBrowser2 object is in 'webBrowser2', and so its VTable is + // webBrowser2->lpVtbl. + + // Before we can get_Document(), we actually need to have some HTML page loaded in the browser. So, + // let's load an empty HTML page. Then, once we have that empty page, we can get_Document() and + // write() to stuff our HTML string into it. + VariantInit(&myURL); + myURL.vt = VT_BSTR; + myURL.bstrVal = SysAllocString(L"about:blank"); + + // Call the Navigate2() function to actually display the page. + webBrowser2->lpVtbl->Navigate2(webBrowser2, &myURL, 0, 0, 0, 0); + + // Free any resources (including the BSTR). + VariantClear(&myURL); + + // Call the IWebBrowser2 object's get_Document so we can get its DISPATCH object. I don't know why you + // don't get the DISPATCH object via the browser object's QueryInterface(), but you don't. + if (!webBrowser2->lpVtbl->get_Document(webBrowser2, &lpDispatch)) + { + // We want to get a pointer to the IHTMLDocument2 object embedded within the DISPATCH + // object, so we can call some of the functions in the former's table. + if (!lpDispatch->lpVtbl->QueryInterface(lpDispatch, &IID_IHTMLDocument2, (void**)&htmlDoc2)) + { + // Ok, now the pointer to our IHTMLDocument2 object is in 'htmlDoc2', and so its VTable is + // htmlDoc2->lpVtbl. + + // Our HTML must be in the form of a BSTR. And it must be passed to write() in an + // array of "VARIENT" structs. So let's create all that. + if ((sfArray = SafeArrayCreate(VT_VARIANT, 1, (SAFEARRAYBOUND *)&ArrayBound))) + { + if (!SafeArrayAccessData(sfArray, (void**)&pVar)) + { + pVar->vt = VT_BSTR; +#ifndef UNICODE + { + wchar_t *buffer; + DWORD size; + + size = MultiByteToWideChar(CP_ACP, 0, string, -1, 0, 0); + if (!(buffer = (wchar_t *)GlobalAlloc(GMEM_FIXED, sizeof(wchar_t) * size))) goto bad; + MultiByteToWideChar(CP_ACP, 0, string, -1, buffer, size); + bstr = SysAllocString(buffer); + GlobalFree(buffer); + } +#else + bstr = SysAllocString(string); +#endif + // Store our BSTR pointer in the VARIENT. + if ((pVar->bstrVal = bstr)) + { + // Pass the VARIENT with its BSTR to write() in order to shove our desired HTML string + // into the body of that empty page we created above. + htmlDoc2->lpVtbl->write(htmlDoc2, sfArray); + + // Close the document. If we don't do this, subsequent calls to DisplayHTMLStr + // would append to the current contents of the page + htmlDoc2->lpVtbl->close(htmlDoc2); + + // Normally, we'd need to free our BSTR, but SafeArrayDestroy() does it for us +// SysFreeString(bstr); + } + } + + // Free the array. This also frees the VARIENT that SafeArrayAccessData created for us, + // and even frees the BSTR we allocated with SysAllocString + SafeArrayDestroy(sfArray); + } + + // Release the IHTMLDocument2 object. +bad: htmlDoc2->lpVtbl->Release(htmlDoc2); + } + + // Release the DISPATCH object. + lpDispatch->lpVtbl->Release(lpDispatch); + } + + // Release the IWebBrowser2 object. + webBrowser2->lpVtbl->Release(webBrowser2); + } + + // No error? + if (bstr) return(0); + + // An error + return(-1); +} + + + + + + +/******************************* DisplayHTMLPage() **************************** + * Displays a URL, or HTML file on disk. + * + * hwnd = Handle to the window hosting the browser object. + * webPageName = Pointer to nul-terminated name of the URL/file. + * + * RETURNS: 0 if success, or non-zero if an error. + * + * NOTE: EmbedBrowserObject() must have been successfully called once with the + * specified window, prior to calling this function. You need call + * EmbedBrowserObject() once only, and then you can make multiple calls to + * this function to display numerous pages in the specified window. + */ + +long DisplayHTMLPage(HWND hwnd, LPTSTR webPageName) +{ + IWebBrowser2 *webBrowser2; + VARIANT myURL; + IOleObject *browserObject; + + // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when + // we initially attached the browser object to this window. + browserObject = *((IOleObject **)GetWindowLong(hwnd, GWL_USERDATA)); + + // We want to get the base address (ie, a pointer) to the IWebBrowser2 object embedded within the browser + // object, so we can call some of the functions in the former's table. + if (!browserObject->lpVtbl->QueryInterface(browserObject, &IID_IWebBrowser2, (void**)&webBrowser2)) + { + // Ok, now the pointer to our IWebBrowser2 object is in 'webBrowser2', and so its VTable is + // webBrowser2->lpVtbl. + + // Our URL (ie, web address, such as "http://www.microsoft.com" or an HTM filename on disk + // such as "c:\myfile.htm") must be passed to the IWebBrowser2's Navigate2() function as a BSTR. + // A BSTR is like a pascal version of a double-byte character string. In other words, the + // first unsigned short is a count of how many characters are in the string, and then this + // is followed by those characters, each expressed as an unsigned short (rather than a + // char). The string is not nul-terminated. The OS function SysAllocString can allocate and + // copy a UNICODE C string to a BSTR. Of course, we'll need to free that BSTR after we're done + // with it. If we're not using UNICODE, we first have to convert to a UNICODE string. + // + // What's more, our BSTR needs to be stuffed into a VARIENT struct, and that VARIENT struct is + // then passed to Navigate2(). Why? The VARIENT struct makes it possible to define generic + // 'datatypes' that can be used with all languages. Not all languages support things like + // nul-terminated C strings. So, by using a VARIENT, whose first field tells what sort of + // data (ie, string, float, etc) is in the VARIENT, COM interfaces can be used by just about + // any language. + VariantInit(&myURL); + myURL.vt = VT_BSTR; + +#ifndef UNICODE + { + wchar_t *buffer; + DWORD size; + + size = MultiByteToWideChar(CP_ACP, 0, webPageName, -1, 0, 0); + if (!(buffer = (wchar_t *)GlobalAlloc(GMEM_FIXED, sizeof(wchar_t) * size))) goto badalloc; + MultiByteToWideChar(CP_ACP, 0, webPageName, -1, buffer, size); + myURL.bstrVal = SysAllocString(buffer); + GlobalFree(buffer); + } +#else + myURL.bstrVal = SysAllocString(webPageName); +#endif + if (!myURL.bstrVal) + { +badalloc: webBrowser2->lpVtbl->Release(webBrowser2); + return(-6); + } + + // Call the Navigate2() function to actually display the page. + webBrowser2->lpVtbl->Navigate2(webBrowser2, &myURL, 0, 0, 0, 0); + + // Free any resources (including the BSTR we allocated above). + VariantClear(&myURL); + + // We no longer need the IWebBrowser2 object (ie, we don't plan to call any more functions in it, + // so we can release our hold on it). Note that we'll still maintain our hold on the browser + // object. + webBrowser2->lpVtbl->Release(webBrowser2); + + // Success + return(0); + } + + return(-5); +} + + + + + +/******************************* ResizeBrowser() **************************** + * Resizes the browser object for the specified window to the specified + * width and height. + * + * hwnd = Handle to the window hosting the browser object. + * width = Width. + * height = Height. + * + * NOTE: EmbedBrowserObject() must have been successfully called once with the + * specified window, prior to calling this function. You need call + * EmbedBrowserObject() once only, and then you can make multiple calls to + * this function to resize the browser object. + */ + +void ResizeBrowser(HWND hwnd, DWORD width, DWORD height) +{ + IWebBrowser2 *webBrowser2; + IOleObject *browserObject; + + // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when + // we initially attached the browser object to this window. + browserObject = *((IOleObject **)GetWindowLong(hwnd, GWL_USERDATA)); + + // We want to get the base address (ie, a pointer) to the IWebBrowser2 object embedded within the browser + // object, so we can call some of the functions in the former's table. + if (!browserObject->lpVtbl->QueryInterface(browserObject, &IID_IWebBrowser2, (void**)&webBrowser2)) + { + // Ok, now the pointer to our IWebBrowser2 object is in 'webBrowser2', and so its VTable is + // webBrowser2->lpVtbl. + + // Call are put_Width() and put_Height() to set the new width/height. + webBrowser2->lpVtbl->put_Width(webBrowser2, width); + webBrowser2->lpVtbl->put_Height(webBrowser2, height); + + // We no longer need the IWebBrowser2 object (ie, we don't plan to call any more functions in it, + // so we can release our hold on it). Note that we'll still maintain our hold on the browser + // object. + webBrowser2->lpVtbl->Release(webBrowser2); + } +} + + + + + +/***************************** EmbedBrowserObject() ************************** + * Puts the browser object inside our host window, and save a pointer to this + * window's browser object in the window's GWL_USERDATA field. + * + * hwnd = Handle of our window into which we embed the browser object. + * + * RETURNS: 0 if success, or non-zero if an error. + * + * NOTE: We tell the browser object to occupy the entire client area of the + * window. + * + * NOTE: No HTML page will be displayed here. We can do that with a subsequent + * call to either DisplayHTMLPage() or DisplayHTMLStr(). This is merely once-only + * initialization for using the browser object. In a nutshell, what we do + * here is get a pointer to the browser object in our window's GWL_USERDATA + * so we can access that object's functions whenever we want, and we also pass + * the browser a pointer to our IOleClientSite struct so that the browser can + * call our functions in our struct's VTable. + */ + +long EmbedBrowserObject(HWND hwnd) +{ + HRESULT hr; + LPCLASSFACTORY pClassFactory; + IOleObject *browserObject; + IWebBrowser2 *webBrowser2; + RECT rect; + char *ptr; + _IOleClientSiteEx *_iOleClientSiteEx; + + // Our IOleClientSite, IOleInPlaceSite, and IOleInPlaceFrame functions need to get our window handle. We + // could store that in some global. But then, that would mean that our functions would work with only that + // one window. If we want to create multiple windows, each hosting its own browser object (to display its + // own web page), then we need to create unique IOleClientSite, IOleInPlaceSite, and IOleInPlaceFrame + // structs for each window. And we'll put an extra field at the end of those structs to store our extra + // data such as a window handle. So, our functions won't have to touch global data, and can therefore be + // re-entrant and work with multiple objects/windows. + // + // Remember that a pointer to our IOleClientSite we create here will be passed as the first arg to every + // one of our IOleClientSite functions. Ditto with the IOleInPlaceFrame object we create here, and the + // IOleInPlaceFrame functions. So, our functions are able to retrieve the window handle we'll store here, + // and then, they'll work with all such windows containing a browser control. + // + // Furthermore, since the browser will be calling our IOleClientSite's QueryInterface to get a pointer to + // our IOleInPlaceSite and IDocHostUIHandler objects, that means that our IOleClientSite QueryInterface + // must have an easy way to grab those pointers. Probably the easiest thing to do is just embed our + // IOleInPlaceSite and IDocHostUIHandler objects inside of an extended IOleClientSite which we'll call + // a _IOleClientSiteEx. As long as they come after the pointer to the IOleClientSite VTable, then we're + // ok. + // + // Of course, we need to GlobalAlloc the above structs now. We'll just get all 4 with a single call to + // GlobalAlloc, especially since 3 of them are all contained inside of our _IOleClientSiteEx anyway. + // + // So, we're not actually allocating separate IOleClientSite, IOleInPlaceSite, IOleInPlaceFrame and + // IDocHostUIHandler structs. + // + // One final thing. We're going to allocate extra room to store the pointer to the browser object. + if (!(ptr = (char *)GlobalAlloc(GMEM_FIXED, sizeof(_IOleClientSiteEx) + sizeof(IOleObject *)))) + { + return(-1); + } + + // Initialize our IOleClientSite object with a pointer to our IOleClientSite VTable. + _iOleClientSiteEx = (_IOleClientSiteEx *)(ptr + sizeof(IOleObject *)); + _iOleClientSiteEx->client.lpVtbl = &MyIOleClientSiteTable; + + // Initialize our IOleInPlaceSite object with a pointer to our IOleInPlaceSite VTable. + _iOleClientSiteEx->inplace.inplace.lpVtbl = &MyIOleInPlaceSiteTable; + + // Initialize our IOleInPlaceFrame object with a pointer to our IOleInPlaceFrame VTable. + _iOleClientSiteEx->inplace.frame.frame.lpVtbl = &MyIOleInPlaceFrameTable; + + // Save our HWND (in the IOleInPlaceFrame object) so our IOleInPlaceFrame functions can retrieve it. + _iOleClientSiteEx->inplace.frame.window = hwnd; + + // Initialize our IDocHostUIHandler object with a pointer to our IDocHostUIHandler VTable. + _iOleClientSiteEx->ui.ui.lpVtbl = &MyIDocHostUIHandlerTable; + + // Get a pointer to the browser object and lock it down (so it doesn't "disappear" while we're using + // it in this program). We do this by calling the OS function CoGetClassObject(). + // + // NOTE: We need this pointer to interact with and control the browser. With normal WIN32 controls such as a + // Static, Edit, Combobox, etc, you obtain an HWND and send messages to it with SendMessage(). Not so with + // the browser object. You need to get a pointer to its "base structure" (as returned by CoGetClassObject()). This + // structure contains an array of pointers to functions you can call within the browser object. Actually, the + // base structure contains a 'lpVtbl' field that is a pointer to that array. We'll call the array a 'VTable'. + // + // For example, the browser object happens to have a SetHostNames() function we want to call. So, after we + // retrieve the pointer to the browser object (in a local we'll name 'browserObject'), then we can call that + // function, and pass it args, as so: + // + // browserObject->lpVtbl->SetHostNames(browserObject, SomeString, SomeString); + // + // There's our pointer to the browser object in 'browserObject'. And there's the pointer to the browser object's + // VTable in 'browserObject->lpVtbl'. And the pointer to the SetHostNames function happens to be stored in an + // field named 'SetHostNames' within the VTable. So we are actually indirectly calling SetHostNames by using + // a pointer to it. That's how you use a VTable. + // + // NOTE: We pass our _IOleClientSiteEx struct and lie -- saying that it's a IOleClientSite. It's ok. A + // _IOleClientSiteEx struct starts with an embedded IOleClientSite. So the browser won't care, and we want + // this extended struct passed to our IOleClientSite functions. + + // Get a pointer to the browser object's IClassFactory object via CoGetClassObject() + + pClassFactory = 0; + hr = + CoGetClassObject( + &CLSID_WebBrowser, + CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, NULL, &IID_IClassFactory, (void **)&pClassFactory) && pClassFactory; + + if (!hr||!pClassFactory) + { + // Call the IClassFactory's CreateInstance() to create a browser object + if (!pClassFactory->lpVtbl->CreateInstance(pClassFactory, 0, &IID_IOleObject, &browserObject)) + { + // Free the IClassFactory. We need it only to create a browser object instance + pClassFactory->lpVtbl->Release(pClassFactory); + + // Ok, we now have the pointer to the browser object in 'browserObject'. Let's save this in the + // memory block we allocated above, and then save the pointer to that whole thing in our window's + // USERDATA field. That way, if we need multiple windows each hosting its own browser object, we can + // call EmbedBrowserObject() for each one, and easily associate the appropriate browser object with + // its matching window and its own objects containing per-window data. + *((IOleObject **)ptr) = browserObject; + SetWindowLong(hwnd, GWL_USERDATA, (LONG)ptr); + + // Give the browser a pointer to my IOleClientSite object + if (!browserObject->lpVtbl->SetClientSite(browserObject, (IOleClientSite *)_iOleClientSiteEx)) + { + // We can now call the browser object's SetHostNames function. SetHostNames lets the browser object know our + // application's name and the name of the document in which we're embedding the browser. (Since we have no + // document name, we'll pass a 0 for the latter). When the browser object is opened for editing, it displays + // these names in its titlebar. + // + // We are passing 3 args to SetHostNames. You'll note that the first arg to SetHostNames is the base + // address of our browser control. This is something that you always have to remember when working in C + // (as opposed to C++). When calling a VTable function, the first arg to that function must always be the + // structure which contains the VTable. (In this case, that's the browser control itself). Why? That's + // because that function is always assumed to be written in C++. And the first argument to any C++ function + // must be its 'this' pointer (ie, the base address of its class, which in this case is our browser object + // pointer). In C++, you don't have to pass this first arg, because the C++ compiler is smart enough to + // produce an executable that always adds this first arg. In fact, the C++ compiler is smart enough to + // know to fetch the function pointer from the VTable, so you don't even need to reference that. In other + // words, the C++ equivalent code would be: + // + // browserObject->SetHostNames(L"My Host Name", 0); + // + // So, when you're trying to convert C++ code to C, always remember to add this first arg whenever you're + // dealing with a VTable (ie, the field is usually named 'lpVtbl') in the standard objects, and also add + // the reference to the VTable itself. + // + // Oh yeah, the L is because we need UNICODE strings. And BTW, the host and document names can be anything + // you want. + browserObject->lpVtbl->SetHostNames(browserObject, L"My Host Name", 0); + + GetClientRect(hwnd, &rect); + + // Let browser object know that it is embedded in an OLE container. + if (!OleSetContainedObject((struct IUnknown *)browserObject, TRUE) && + + // Set the display area of our browser control the same as our window's size + // and actually put the browser object into our window. + !browserObject->lpVtbl->DoVerb(browserObject, OLEIVERB_SHOW, NULL, (IOleClientSite *)_iOleClientSiteEx, -1, hwnd, &rect) && + + // Ok, now things may seem to get even trickier, One of those function pointers in the browser's VTable is + // to the QueryInterface() function. What does this function do? It lets us grab the base address of any + // other object that may be embedded within the browser object. And this other object has its own VTable + // containing pointers to more functions we can call for that object. + // + // We want to get the base address (ie, a pointer) to the IWebBrowser2 object embedded within the browser + // object, so we can call some of the functions in the former's table. For example, one IWebBrowser2 function + // we intend to call below will be Navigate2(). So we call the browser object's QueryInterface to get our + // pointer to the IWebBrowser2 object. + !browserObject->lpVtbl->QueryInterface(browserObject, &IID_IWebBrowser2, (void**)&webBrowser2)) + { + // Ok, now the pointer to our IWebBrowser2 object is in 'webBrowser2', and so its VTable is + // webBrowser2->lpVtbl. + + // Let's call several functions in the IWebBrowser2 object to position the browser display area + // in our window. The functions we call are put_Left(), put_Top(), put_Width(), and put_Height(). + // Note that we reference the IWebBrowser2 object's VTable to get pointers to those functions. And + // also note that the first arg we pass to each is the pointer to the IWebBrowser2 object. + webBrowser2->lpVtbl->put_Left(webBrowser2, 0); + webBrowser2->lpVtbl->put_Top(webBrowser2, 0); + webBrowser2->lpVtbl->put_Width(webBrowser2, rect.right); + webBrowser2->lpVtbl->put_Height(webBrowser2, rect.bottom); + + // We no longer need the IWebBrowser2 object (ie, we don't plan to call any more functions in it + // right now, so we can release our hold on it). Note that we'll still maintain our hold on the + // browser object until we're done with that object. + webBrowser2->lpVtbl->Release(webBrowser2); + + // Success + return(0); + } + } + + // Something went wrong setting up the browser! + UnEmbedBrowserObject(hwnd); + return(-4); + } + + pClassFactory->lpVtbl->Release(pClassFactory); + GlobalFree(ptr); + + // Can't create an instance of the browser! + return(-3); + } + + GlobalFree(ptr); + + // Can't get the web browser's IClassFactory! + return(-2); +} + + + + + +/****************************** WindowProc() *************************** + * Our message handler for our window to host the browser. + */ + + +LRESULT CALLBACK WebBrowser_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_SIZE: + { + // Resize the browser object to fit the window + //ResizeBrowser(hwnd, LOWORD(lParam), HIWORD(lParam)); + return(0); + } + + case WM_CREATE: + { + // Embed the browser object into our host window. We need do this only + // once. Note that the browser object will start calling some of our + // IOleInPlaceFrame and IOleClientSite functions as soon as we start + // calling browser object functions in EmbedBrowserObject(). + if (EmbedBrowserObject(hwnd)) + return(-1); + + // Another window created with an embedded browser object + + // Success + return(0); + } + + case WM_DESTROY: + { + // Detach the browser object from this window, and free resources. + UnEmbedBrowserObject(hwnd); + return(TRUE); + } + + + } + + return(DefWindowProc(hwnd, uMsg, wParam, lParam)); +} + +static const char* WEBBROWSER_CLASSNAME = "WEBBROWSER"; +static HINSTANCE gs_hInstance = NULL; +static HWND gs_hWndWebBrowser = NULL; +static HWND gs_hWndParent = NULL; + + +int WebBrowser_Show(HWND hParent, const char* addr, const RECT* rc) +{ + if (gs_hWndWebBrowser) + return 0; + + gs_hWndParent = hParent; + gs_hWndWebBrowser = CreateWindowEx(0, WEBBROWSER_CLASSNAME, "web browser", WS_CHILD|WS_VISIBLE, + rc->left, rc->top, rc->right - rc->left, rc->bottom - rc->top, + hParent, NULL, gs_hInstance, 0); + + if (!gs_hWndWebBrowser) + return 0; + + DisplayHTMLPage(gs_hWndWebBrowser, (LPTSTR)addr); + + ShowWindow(gs_hWndWebBrowser, SW_SHOW); + UpdateWindow(gs_hWndWebBrowser); + + SetFocus(gs_hWndWebBrowser); + return 1; +} + +void WebBrowser_Move(const RECT* rc) +{ + MoveWindow(gs_hWndWebBrowser, rc->left, rc->top, rc->right - rc->left, rc->bottom - rc->top, 1 ); +} + +void WebBrowser_Hide() +{ + if (!gs_hWndWebBrowser) + return; + + ShowWindow(gs_hWndWebBrowser, SW_HIDE); + + if (IsWindow(gs_hWndWebBrowser)) + DestroyWindow(gs_hWndWebBrowser); + gs_hWndWebBrowser = NULL; + + SetFocus(gs_hWndParent); +} + +int WebBrowser_IsVisible() +{ + return (gs_hWndWebBrowser != NULL); +} + +void WebBrowser_Destroy() +{ + WebBrowser_Hide(); +} + +int WebBrowser_Startup(HINSTANCE hInstance) +{ + if (OleInitialize(NULL) != S_OK) + { + return 0; + } + + { + WNDCLASSEX wc; + ZeroMemory(&wc, sizeof(WNDCLASSEX)); + wc.cbSize = sizeof(WNDCLASSEX); + wc.hInstance = hInstance; + wc.lpfnWndProc = WebBrowser_WindowProc; + wc.lpszClassName = WEBBROWSER_CLASSNAME; + RegisterClassEx(&wc); + } + gs_hInstance = hInstance; + return 1; +} + +void WebBrowser_Cleanup() +{ + if (gs_hInstance) + UnregisterClass(WEBBROWSER_CLASSNAME, gs_hInstance); + + OleUninitialize(); +} diff --git a/source/CWebBrowser/CWebBrowser.h b/source/CWebBrowser/CWebBrowser.h new file mode 100644 index 0000000..de3ea91 --- /dev/null +++ b/source/CWebBrowser/CWebBrowser.h @@ -0,0 +1,19 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN + +#include + +extern "C" { + +int WebBrowser_Startup(HINSTANCE hInstance); +void WebBrowser_Cleanup(); +void WebBrowser_Destroy(); +int WebBrowser_Show(HWND parent, const char* addr, const RECT* rcWebBrowser); +void WebBrowser_Hide(); +void WebBrowser_Move(const RECT* rcWebBrowser); + +int WebBrowser_IsVisible(); +const RECT& WebBrowser_GetRect(); + +} \ No newline at end of file diff --git a/source/Discord/backoff.h b/source/Discord/backoff.h new file mode 100644 index 0000000..a3e736f --- /dev/null +++ b/source/Discord/backoff.h @@ -0,0 +1,40 @@ +#pragma once + +#include +#include +#include +#include + +struct Backoff { + int64_t minAmount; + int64_t maxAmount; + int64_t current; + int fails; + std::mt19937_64 randGenerator; + std::uniform_real_distribution<> randDistribution; + + double rand01() { return randDistribution(randGenerator); } + + Backoff(int64_t min, int64_t max) + : minAmount(min) + , maxAmount(max) + , current(min) + , fails(0) + , randGenerator((uint64_t)time(0)) + { + } + + void reset() + { + fails = 0; + current = minAmount; + } + + int64_t nextDelay() + { + ++fails; + int64_t delay = (int64_t)((double)current * 2.0 * rand01()); + current = std::min(current + delay, maxAmount); + return current; + } +}; diff --git a/source/Discord/connection.h b/source/Discord/connection.h new file mode 100644 index 0000000..a8f99b9 --- /dev/null +++ b/source/Discord/connection.h @@ -0,0 +1,19 @@ +#pragma once + +// This is to wrap the platform specific kinds of connect/read/write. + +#include +#include + +// not really connectiony, but need per-platform +int GetProcessId(); + +struct BaseConnection { + static BaseConnection* Create(); + static void Destroy(BaseConnection*&); + bool isOpen{false}; + bool Open(); + bool Close(); + bool Write(const void* data, size_t length); + bool Read(void* data, size_t length); +}; diff --git a/source/Discord/connection_win.cpp b/source/Discord/connection_win.cpp new file mode 100644 index 0000000..2dd2750 --- /dev/null +++ b/source/Discord/connection_win.cpp @@ -0,0 +1,128 @@ +#include "connection.h" + +#define WIN32_LEAN_AND_MEAN +#define NOMCX +#define NOSERVICE +#define NOIME +#include +#include + +int GetProcessId() +{ + return (int)::GetCurrentProcessId(); +} + +struct BaseConnectionWin : public BaseConnection { + HANDLE pipe{INVALID_HANDLE_VALUE}; +}; + +static BaseConnectionWin Connection; + +/*static*/ BaseConnection* BaseConnection::Create() +{ + return &Connection; +} + +/*static*/ void BaseConnection::Destroy(BaseConnection*& c) +{ + auto self = reinterpret_cast(c); + self->Close(); + c = nullptr; +} + +bool BaseConnection::Open() +{ + wchar_t pipeName[]{L"\\\\?\\pipe\\discord-ipc-0"}; + const size_t pipeDigit = sizeof(pipeName) / sizeof(wchar_t) - 2; + pipeName[pipeDigit] = L'0'; + auto self = reinterpret_cast(this); + for (;;) { + self->pipe = ::CreateFileW( + pipeName, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr); + if (self->pipe != INVALID_HANDLE_VALUE) { + self->isOpen = true; + return true; + } + + auto lastError = GetLastError(); + if (lastError == ERROR_FILE_NOT_FOUND) { + if (pipeName[pipeDigit] < L'9') { + pipeName[pipeDigit]++; + continue; + } + } + else if (lastError == ERROR_PIPE_BUSY) { + if (!WaitNamedPipeW(pipeName, 10000)) { + return false; + } + continue; + } + return false; + } +} + +bool BaseConnection::Close() +{ + auto self = reinterpret_cast(this); + ::CloseHandle(self->pipe); + self->pipe = INVALID_HANDLE_VALUE; + self->isOpen = false; + return true; +} + +bool BaseConnection::Write(const void* data, size_t length) +{ + if (length == 0) { + return true; + } + auto self = reinterpret_cast(this); + assert(self); + if (!self) { + return false; + } + if (self->pipe == INVALID_HANDLE_VALUE) { + return false; + } + assert(data); + if (!data) { + return false; + } + const DWORD bytesLength = (DWORD)length; + DWORD bytesWritten = 0; + return ::WriteFile(self->pipe, data, bytesLength, &bytesWritten, nullptr) == TRUE && + bytesWritten == bytesLength; +} + +bool BaseConnection::Read(void* data, size_t length) +{ + assert(data); + if (!data) { + return false; + } + auto self = reinterpret_cast(this); + assert(self); + if (!self) { + return false; + } + if (self->pipe == INVALID_HANDLE_VALUE) { + return false; + } + DWORD bytesAvailable = 0; + if (::PeekNamedPipe(self->pipe, nullptr, 0, nullptr, &bytesAvailable, nullptr)) { + if (bytesAvailable >= length) { + DWORD bytesToRead = (DWORD)length; + DWORD bytesRead = 0; + if (::ReadFile(self->pipe, data, bytesToRead, &bytesRead, nullptr) == TRUE) { + assert(bytesToRead == bytesRead); + return true; + } + else { + Close(); + } + } + } + else { + Close(); + } + return false; +} diff --git a/source/Discord/discord_register_win.cpp b/source/Discord/discord_register_win.cpp new file mode 100644 index 0000000..0b1c4a1 --- /dev/null +++ b/source/Discord/discord_register_win.cpp @@ -0,0 +1,186 @@ +#include "discord_rpc.h" +#include "discord_register.h" + +#define WIN32_LEAN_AND_MEAN +#define NOMCX +#define NOSERVICE +#define NOIME +#include +#include +#include + +/** + * Updated fixes for MinGW and WinXP + * This block is written the way it does not involve changing the rest of the code + * Checked to be compiling + * 1) strsafe.h belongs to Windows SDK and cannot be added to MinGW + * #include guarded, functions redirected to substitutes + * 2) RegSetKeyValueW and LSTATUS are not declared in + * The entire function is rewritten + */ +#ifdef __MINGW32__ +#include +/// strsafe.h fixes +static HRESULT StringCbPrintfW(LPWSTR pszDest, size_t cbDest, LPCWSTR pszFormat, ...) +{ + HRESULT ret; + va_list va; + va_start(va, pszFormat); + cbDest /= 2; // Size is divided by 2 to convert from bytes to wide characters - causes segfault + // othervise + ret = vsnwprintf(pszDest, cbDest, pszFormat, va); + pszDest[cbDest - 1] = 0; // Terminate the string in case a buffer overflow; -1 will be returned + va_end(va); + return ret; +} +#else +#include +#include +#endif // __MINGW32__ + +/// winreg.h fixes +#ifndef LSTATUS +#define LSTATUS LONG +#endif +#ifdef RegSetKeyValueW +#undefine RegSetKeyValueW +#endif +#define RegSetKeyValueW regset +static LSTATUS regset(HKEY hkey, + LPCWSTR subkey, + LPCWSTR name, + DWORD type, + const void* data, + DWORD len) +{ + HKEY htkey = hkey, hsubkey = nullptr; + LSTATUS ret; + if (subkey && subkey[0]) { + if ((ret = RegCreateKeyExW(hkey, subkey, 0, 0, 0, KEY_ALL_ACCESS, 0, &hsubkey, 0)) != + ERROR_SUCCESS) + return ret; + htkey = hsubkey; + } + ret = RegSetValueExW(htkey, name, 0, type, (const BYTE*)data, len); + if (hsubkey && hsubkey != hkey) + RegCloseKey(hsubkey); + return ret; +} + +static void Discord_RegisterW(const wchar_t* applicationId, const wchar_t* command) +{ + // https://msdn.microsoft.com/en-us/library/aa767914(v=vs.85).aspx + // we want to register games so we can run them as discord-:// + // Update the HKEY_CURRENT_USER, because it doesn't seem to require special permissions. + + wchar_t exeFilePath[MAX_PATH]; + DWORD exeLen = GetModuleFileNameW(nullptr, exeFilePath, MAX_PATH); + wchar_t openCommand[1024]; + + if (command && command[0]) { + StringCbPrintfW(openCommand, sizeof(openCommand), L"%s", command); + } + else { + // StringCbCopyW(openCommand, sizeof(openCommand), exeFilePath); + StringCbPrintfW(openCommand, sizeof(openCommand), L"%s", exeFilePath); + } + + wchar_t protocolName[64]; + StringCbPrintfW(protocolName, sizeof(protocolName), L"discord-%s", applicationId); + wchar_t protocolDescription[128]; + StringCbPrintfW( + protocolDescription, sizeof(protocolDescription), L"URL:Run game %s protocol", applicationId); + wchar_t urlProtocol = 0; + + wchar_t keyName[256]; + StringCbPrintfW(keyName, sizeof(keyName), L"Software\\Classes\\%s", protocolName); + HKEY key; + auto status = + RegCreateKeyExW(HKEY_CURRENT_USER, keyName, 0, nullptr, 0, KEY_WRITE, nullptr, &key, nullptr); + if (status != ERROR_SUCCESS) { + fprintf(stderr, "Error creating key\n"); + return; + } + DWORD len; + LSTATUS result; + len = (DWORD)lstrlenW(protocolDescription) + 1; + result = + RegSetKeyValueW(key, nullptr, nullptr, REG_SZ, protocolDescription, len * sizeof(wchar_t)); + if (FAILED(result)) { + fprintf(stderr, "Error writing description\n"); + } + + len = (DWORD)lstrlenW(protocolDescription) + 1; + result = RegSetKeyValueW(key, nullptr, L"URL Protocol", REG_SZ, &urlProtocol, sizeof(wchar_t)); + if (FAILED(result)) { + fprintf(stderr, "Error writing description\n"); + } + + result = RegSetKeyValueW( + key, L"DefaultIcon", nullptr, REG_SZ, exeFilePath, (exeLen + 1) * sizeof(wchar_t)); + if (FAILED(result)) { + fprintf(stderr, "Error writing icon\n"); + } + + len = (DWORD)lstrlenW(openCommand) + 1; + result = RegSetKeyValueW( + key, L"shell\\open\\command", nullptr, REG_SZ, openCommand, len * sizeof(wchar_t)); + if (FAILED(result)) { + fprintf(stderr, "Error writing command\n"); + } + RegCloseKey(key); +} + +extern "C" DISCORD_EXPORT void Discord_Register(const char* applicationId, const char* command) +{ + wchar_t appId[32]; + MultiByteToWideChar(CP_UTF8, 0, applicationId, -1, appId, 32); + + wchar_t openCommand[1024]; + const wchar_t* wcommand = nullptr; + if (command && command[0]) { + const auto commandBufferLen = sizeof(openCommand) / sizeof(*openCommand); + MultiByteToWideChar(CP_UTF8, 0, command, -1, openCommand, commandBufferLen); + wcommand = openCommand; + } + + Discord_RegisterW(appId, wcommand); +} + +extern "C" DISCORD_EXPORT void Discord_RegisterSteamGame(const char* applicationId, + const char* steamId) +{ + wchar_t appId[32]; + MultiByteToWideChar(CP_UTF8, 0, applicationId, -1, appId, 32); + + wchar_t wSteamId[32]; + MultiByteToWideChar(CP_UTF8, 0, steamId, -1, wSteamId, 32); + + HKEY key; + auto status = RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Valve\\Steam", 0, KEY_READ, &key); + if (status != ERROR_SUCCESS) { + fprintf(stderr, "Error opening Steam key\n"); + return; + } + + wchar_t steamPath[MAX_PATH]; + DWORD pathBytes = sizeof(steamPath); + status = RegQueryValueExW(key, L"SteamExe", nullptr, nullptr, (BYTE*)steamPath, &pathBytes); + RegCloseKey(key); + if (status != ERROR_SUCCESS || pathBytes < 1) { + fprintf(stderr, "Error reading SteamExe key\n"); + return; + } + + DWORD pathChars = pathBytes / sizeof(wchar_t); + for (DWORD i = 0; i < pathChars; ++i) { + if (steamPath[i] == L'/') { + steamPath[i] = L'\\'; + } + } + + wchar_t command[1024]; + StringCbPrintfW(command, sizeof(command), L"\"%s\" steam://rungameid/%s", steamPath, wSteamId); + + Discord_RegisterW(appId, command); +} diff --git a/source/Discord/discord_rpc.cpp b/source/Discord/discord_rpc.cpp new file mode 100644 index 0000000..0392453 --- /dev/null +++ b/source/Discord/discord_rpc.cpp @@ -0,0 +1,504 @@ +#include "discord_rpc.h" + +#include "backoff.h" +#include "discord_register.h" +#include "msg_queue.h" +#include "rpc_connection.h" +#include "serialization.h" + +#include +#include +#include + +#ifndef DISCORD_DISABLE_IO_THREAD +#include +#include +#endif + +constexpr size_t MaxMessageSize{16 * 1024}; +constexpr size_t MessageQueueSize{8}; +constexpr size_t JoinQueueSize{8}; + +struct QueuedMessage { + size_t length; + char buffer[MaxMessageSize]; + + void Copy(const QueuedMessage& other) + { + length = other.length; + if (length) { + memcpy(buffer, other.buffer, length); + } + } +}; + +struct User { + // snowflake (64bit int), turned into a ascii decimal string, at most 20 chars +1 null + // terminator = 21 + char userId[32]; + // 32 unicode glyphs is max name size => 4 bytes per glyph in the worst case, +1 for null + // terminator = 129 + char username[344]; + // 4 decimal digits + 1 null terminator = 5 + char discriminator[8]; + // optional 'a_' + md5 hex digest (32 bytes) + null terminator = 35 + char avatar[128]; + // Rounded way up because I'm paranoid about games breaking from future changes in these sizes +}; + +static RpcConnection* Connection{nullptr}; +static DiscordEventHandlers QueuedHandlers{}; +static DiscordEventHandlers Handlers{}; +static std::atomic_bool WasJustConnected{false}; +static std::atomic_bool WasJustDisconnected{false}; +static std::atomic_bool GotErrorMessage{false}; +static std::atomic_bool WasJoinGame{false}; +static std::atomic_bool WasSpectateGame{false}; +static std::atomic_bool UpdatePresence{false}; +static char JoinGameSecret[256]; +static char SpectateGameSecret[256]; +static int LastErrorCode{0}; +static char LastErrorMessage[256]; +static int LastDisconnectErrorCode{0}; +static char LastDisconnectErrorMessage[256]; +static std::mutex PresenceMutex; +static std::mutex HandlerMutex; +static QueuedMessage QueuedPresence{}; +static MsgQueue SendQueue; +static MsgQueue JoinAskQueue; +static User connectedUser; + +// We want to auto connect, and retry on failure, but not as fast as possible. This does expoential +// backoff from 0.5 seconds to 1 minute +static Backoff ReconnectTimeMs(500, 60 * 1000); +static auto NextConnect = std::chrono::system_clock::now(); +static int Pid{0}; +static int Nonce{1}; + +#ifndef DISCORD_DISABLE_IO_THREAD +static void Discord_UpdateConnection(void); +class IoThreadHolder { +private: + std::atomic_bool keepRunning{true}; + std::mutex waitForIOMutex; + std::condition_variable waitForIOActivity; + std::thread ioThread; + +public: + void Start() + { + keepRunning.store(true); + ioThread = std::thread([&]() { + const std::chrono::duration maxWait{500LL}; + Discord_UpdateConnection(); + while (keepRunning.load()) { + std::unique_lock lock(waitForIOMutex); + waitForIOActivity.wait_for(lock, maxWait); + Discord_UpdateConnection(); + } + }); + } + + void Notify() { waitForIOActivity.notify_all(); } + + void Stop() + { + keepRunning.exchange(false); + Notify(); + if (ioThread.joinable()) { + ioThread.join(); + } + } + + ~IoThreadHolder() { Stop(); } +}; +#else +class IoThreadHolder { +public: + void Start() {} + void Stop() {} + void Notify() {} +}; +#endif // DISCORD_DISABLE_IO_THREAD +static IoThreadHolder* IoThread{nullptr}; + +static void UpdateReconnectTime() +{ + NextConnect = std::chrono::system_clock::now() + + std::chrono::duration{ReconnectTimeMs.nextDelay()}; +} + +#ifdef DISCORD_DISABLE_IO_THREAD +extern "C" DISCORD_EXPORT void Discord_UpdateConnection(void) +#else +static void Discord_UpdateConnection(void) +#endif +{ + if (!Connection) { + return; + } + + if (!Connection->IsOpen()) { + if (std::chrono::system_clock::now() >= NextConnect) { + UpdateReconnectTime(); + Connection->Open(); + } + } + else { + // reads + + for (;;) { + JsonDocument message; + + if (!Connection->Read(message)) { + break; + } + + const char* evtName = GetStrMember(&message, "evt"); + const char* nonce = GetStrMember(&message, "nonce"); + + if (nonce) { + // in responses only -- should use to match up response when needed. + + if (evtName && strcmp(evtName, "ERROR") == 0) { + auto data = GetObjMember(&message, "data"); + LastErrorCode = GetIntMember(data, "code"); + StringCopy(LastErrorMessage, GetStrMember(data, "message", "")); + GotErrorMessage.store(true); + } + } + else { + // should have evt == name of event, optional data + if (evtName == nullptr) { + continue; + } + + auto data = GetObjMember(&message, "data"); + + if (strcmp(evtName, "ACTIVITY_JOIN") == 0) { + auto secret = GetStrMember(data, "secret"); + if (secret) { + StringCopy(JoinGameSecret, secret); + WasJoinGame.store(true); + } + } + else if (strcmp(evtName, "ACTIVITY_SPECTATE") == 0) { + auto secret = GetStrMember(data, "secret"); + if (secret) { + StringCopy(SpectateGameSecret, secret); + WasSpectateGame.store(true); + } + } + else if (strcmp(evtName, "ACTIVITY_JOIN_REQUEST") == 0) { + auto user = GetObjMember(data, "user"); + auto userId = GetStrMember(user, "id"); + auto username = GetStrMember(user, "username"); + auto avatar = GetStrMember(user, "avatar"); + auto joinReq = JoinAskQueue.GetNextAddMessage(); + if (userId && username && joinReq) { + StringCopy(joinReq->userId, userId); + StringCopy(joinReq->username, username); + auto discriminator = GetStrMember(user, "discriminator"); + if (discriminator) { + StringCopy(joinReq->discriminator, discriminator); + } + if (avatar) { + StringCopy(joinReq->avatar, avatar); + } + else { + joinReq->avatar[0] = 0; + } + JoinAskQueue.CommitAdd(); + } + } + } + } + + // writes + if (UpdatePresence.exchange(false) && QueuedPresence.length) { + QueuedMessage local; + { + std::lock_guard guard(PresenceMutex); + local.Copy(QueuedPresence); + } + if (!Connection->Write(local.buffer, local.length)) { + // if we fail to send, requeue + std::lock_guard guard(PresenceMutex); + QueuedPresence.Copy(local); + UpdatePresence.exchange(true); + } + } + + while (SendQueue.HavePendingSends()) { + auto qmessage = SendQueue.GetNextSendMessage(); + Connection->Write(qmessage->buffer, qmessage->length); + SendQueue.CommitSend(); + } + } +} + +static void SignalIOActivity() +{ + if (IoThread != nullptr) { + IoThread->Notify(); + } +} + +static bool RegisterForEvent(const char* evtName) +{ + auto qmessage = SendQueue.GetNextAddMessage(); + if (qmessage) { + qmessage->length = + JsonWriteSubscribeCommand(qmessage->buffer, sizeof(qmessage->buffer), Nonce++, evtName); + SendQueue.CommitAdd(); + SignalIOActivity(); + return true; + } + return false; +} + +static bool DeregisterForEvent(const char* evtName) +{ + auto qmessage = SendQueue.GetNextAddMessage(); + if (qmessage) { + qmessage->length = + JsonWriteUnsubscribeCommand(qmessage->buffer, sizeof(qmessage->buffer), Nonce++, evtName); + SendQueue.CommitAdd(); + SignalIOActivity(); + return true; + } + return false; +} + +extern "C" DISCORD_EXPORT void Discord_Initialize(const char* applicationId, + DiscordEventHandlers* handlers, + int autoRegister, + const char* optionalSteamId) +{ + IoThread = new (std::nothrow) IoThreadHolder(); + if (IoThread == nullptr) { + return; + } + + if (autoRegister) { + if (optionalSteamId && optionalSteamId[0]) { + Discord_RegisterSteamGame(applicationId, optionalSteamId); + } + else { + Discord_Register(applicationId, nullptr); + } + } + + Pid = GetProcessId(); + + { + std::lock_guard guard(HandlerMutex); + + if (handlers) { + QueuedHandlers = *handlers; + } + else { + QueuedHandlers = {}; + } + + Handlers = {}; + } + + if (Connection) { + return; + } + + Connection = RpcConnection::Create(applicationId); + Connection->onConnect = [](JsonDocument& readyMessage) { + Discord_UpdateHandlers(&QueuedHandlers); + if (QueuedPresence.length > 0) { + UpdatePresence.exchange(true); + SignalIOActivity(); + } + auto data = GetObjMember(&readyMessage, "data"); + auto user = GetObjMember(data, "user"); + auto userId = GetStrMember(user, "id"); + auto username = GetStrMember(user, "username"); + auto avatar = GetStrMember(user, "avatar"); + if (userId && username) { + StringCopy(connectedUser.userId, userId); + StringCopy(connectedUser.username, username); + auto discriminator = GetStrMember(user, "discriminator"); + if (discriminator) { + StringCopy(connectedUser.discriminator, discriminator); + } + if (avatar) { + StringCopy(connectedUser.avatar, avatar); + } + else { + connectedUser.avatar[0] = 0; + } + } + WasJustConnected.exchange(true); + ReconnectTimeMs.reset(); + }; + Connection->onDisconnect = [](int err, const char* message) { + LastDisconnectErrorCode = err; + StringCopy(LastDisconnectErrorMessage, message); + WasJustDisconnected.exchange(true); + UpdateReconnectTime(); + }; + + IoThread->Start(); +} + +extern "C" DISCORD_EXPORT void Discord_Shutdown(void) +{ + if (!Connection) { + return; + } + Connection->onConnect = nullptr; + Connection->onDisconnect = nullptr; + Handlers = {}; + QueuedPresence.length = 0; + UpdatePresence.exchange(false); + if (IoThread != nullptr) { + IoThread->Stop(); + delete IoThread; + IoThread = nullptr; + } + + RpcConnection::Destroy(Connection); +} + +extern "C" DISCORD_EXPORT void Discord_UpdatePresence(const DiscordRichPresence* presence) +{ + { + std::lock_guard guard(PresenceMutex); + QueuedPresence.length = JsonWriteRichPresenceObj( + QueuedPresence.buffer, sizeof(QueuedPresence.buffer), Nonce++, Pid, presence); + UpdatePresence.exchange(true); + } + SignalIOActivity(); +} + +extern "C" DISCORD_EXPORT void Discord_ClearPresence(void) +{ + Discord_UpdatePresence(nullptr); +} + +extern "C" DISCORD_EXPORT void Discord_Respond(const char* userId, /* DISCORD_REPLY_ */ int reply) +{ + // if we are not connected, let's not batch up stale messages for later + if (!Connection || !Connection->IsOpen()) { + return; + } + auto qmessage = SendQueue.GetNextAddMessage(); + if (qmessage) { + qmessage->length = + JsonWriteJoinReply(qmessage->buffer, sizeof(qmessage->buffer), userId, reply, Nonce++); + SendQueue.CommitAdd(); + SignalIOActivity(); + } +} + +extern "C" DISCORD_EXPORT void Discord_RunCallbacks(void) +{ + // Note on some weirdness: internally we might connect, get other signals, disconnect any number + // of times inbetween calls here. Externally, we want the sequence to seem sane, so any other + // signals are book-ended by calls to ready and disconnect. + + if (!Connection) { + return; + } + + bool wasDisconnected = WasJustDisconnected.exchange(false); + bool isConnected = Connection->IsOpen(); + + if (isConnected) { + // if we are connected, disconnect cb first + std::lock_guard guard(HandlerMutex); + if (wasDisconnected && Handlers.disconnected) { + Handlers.disconnected(LastDisconnectErrorCode, LastDisconnectErrorMessage); + } + } + + if (WasJustConnected.exchange(false)) { + std::lock_guard guard(HandlerMutex); + if (Handlers.ready) { + DiscordUser du{connectedUser.userId, + connectedUser.username, + connectedUser.discriminator, + connectedUser.avatar}; + Handlers.ready(&du); + } + } + + if (GotErrorMessage.exchange(false)) { + std::lock_guard guard(HandlerMutex); + if (Handlers.errored) { + Handlers.errored(LastErrorCode, LastErrorMessage); + } + } + + if (WasJoinGame.exchange(false)) { + std::lock_guard guard(HandlerMutex); + if (Handlers.joinGame) { + Handlers.joinGame(JoinGameSecret); + } + } + + if (WasSpectateGame.exchange(false)) { + std::lock_guard guard(HandlerMutex); + if (Handlers.spectateGame) { + Handlers.spectateGame(SpectateGameSecret); + } + } + + // Right now this batches up any requests and sends them all in a burst; I could imagine a world + // where the implementer would rather sequentially accept/reject each one before the next invite + // is sent. I left it this way because I could also imagine wanting to process these all and + // maybe show them in one common dialog and/or start fetching the avatars in parallel, and if + // not it should be trivial for the implementer to make a queue themselves. + while (JoinAskQueue.HavePendingSends()) { + auto req = JoinAskQueue.GetNextSendMessage(); + { + std::lock_guard guard(HandlerMutex); + if (Handlers.joinRequest) { + DiscordUser du{req->userId, req->username, req->discriminator, req->avatar}; + Handlers.joinRequest(&du); + } + } + JoinAskQueue.CommitSend(); + } + + if (!isConnected) { + // if we are not connected, disconnect message last + std::lock_guard guard(HandlerMutex); + if (wasDisconnected && Handlers.disconnected) { + Handlers.disconnected(LastDisconnectErrorCode, LastDisconnectErrorMessage); + } + } +} + +extern "C" DISCORD_EXPORT void Discord_UpdateHandlers(DiscordEventHandlers* newHandlers) +{ + if (newHandlers) { +#define HANDLE_EVENT_REGISTRATION(handler_name, event) \ + if (!Handlers.handler_name && newHandlers->handler_name) { \ + RegisterForEvent(event); \ + } \ + else if (Handlers.handler_name && !newHandlers->handler_name) { \ + DeregisterForEvent(event); \ + } + + std::lock_guard guard(HandlerMutex); + HANDLE_EVENT_REGISTRATION(joinGame, "ACTIVITY_JOIN") + HANDLE_EVENT_REGISTRATION(spectateGame, "ACTIVITY_SPECTATE") + HANDLE_EVENT_REGISTRATION(joinRequest, "ACTIVITY_JOIN_REQUEST") + +#undef HANDLE_EVENT_REGISTRATION + + Handlers = *newHandlers; + } + else { + std::lock_guard guard(HandlerMutex); + Handlers = {}; + } + return; +} diff --git a/source/Discord/dllmain.cpp b/source/Discord/dllmain.cpp new file mode 100644 index 0000000..fbfc295 --- /dev/null +++ b/source/Discord/dllmain.cpp @@ -0,0 +1,8 @@ +#include + +// outsmart GCC's missing-declarations warning +BOOL WINAPI DllMain(HMODULE, DWORD, LPVOID); +BOOL WINAPI DllMain(HMODULE, DWORD, LPVOID) +{ + return TRUE; +} diff --git a/source/Discord/msg_queue.h b/source/Discord/msg_queue.h new file mode 100644 index 0000000..77f380e --- /dev/null +++ b/source/Discord/msg_queue.h @@ -0,0 +1,36 @@ +#pragma once + +#include + +// A simple queue. No locks, but only works with a single thread as producer and a single thread as +// a consumer. Mutex up as needed. + +template +class MsgQueue { + ElementType queue_[QueueSize]; + std::atomic_uint nextAdd_{0}; + std::atomic_uint nextSend_{0}; + std::atomic_uint pendingSends_{0}; + +public: + MsgQueue() {} + + ElementType* GetNextAddMessage() + { + // if we are falling behind, bail + if (pendingSends_.load() >= QueueSize) { + return nullptr; + } + auto index = (nextAdd_++) % QueueSize; + return &queue_[index]; + } + void CommitAdd() { ++pendingSends_; } + + bool HavePendingSends() const { return pendingSends_.load() != 0; } + ElementType* GetNextSendMessage() + { + auto index = (nextSend_++) % QueueSize; + return &queue_[index]; + } + void CommitSend() { --pendingSends_; } +}; diff --git a/source/Discord/rpc_connection.cpp b/source/Discord/rpc_connection.cpp new file mode 100644 index 0000000..0933162 --- /dev/null +++ b/source/Discord/rpc_connection.cpp @@ -0,0 +1,137 @@ +#include "rpc_connection.h" +#include "serialization.h" + +#include + +static const int RpcVersion = 1; +static RpcConnection Instance; + +/*static*/ RpcConnection* RpcConnection::Create(const char* applicationId) +{ + Instance.connection = BaseConnection::Create(); + StringCopy(Instance.appId, applicationId); + return &Instance; +} + +/*static*/ void RpcConnection::Destroy(RpcConnection*& c) +{ + c->Close(); + BaseConnection::Destroy(c->connection); + c = nullptr; +} + +void RpcConnection::Open() +{ + if (state == State::Connected) { + return; + } + + if (state == State::Disconnected && !connection->Open()) { + return; + } + + if (state == State::SentHandshake) { + JsonDocument message; + if (Read(message)) { + auto cmd = GetStrMember(&message, "cmd"); + auto evt = GetStrMember(&message, "evt"); + if (cmd && evt && !strcmp(cmd, "DISPATCH") && !strcmp(evt, "READY")) { + state = State::Connected; + if (onConnect) { + onConnect(message); + } + } + } + } + else { + sendFrame.opcode = Opcode::Handshake; + sendFrame.length = (uint32_t)JsonWriteHandshakeObj( + sendFrame.message, sizeof(sendFrame.message), RpcVersion, appId); + + if (connection->Write(&sendFrame, sizeof(MessageFrameHeader) + sendFrame.length)) { + state = State::SentHandshake; + } + else { + Close(); + } + } +} + +void RpcConnection::Close() +{ + if (onDisconnect && (state == State::Connected || state == State::SentHandshake)) { + onDisconnect(lastErrorCode, lastErrorMessage); + } + connection->Close(); + state = State::Disconnected; +} + +bool RpcConnection::Write(const void* data, size_t length) +{ + sendFrame.opcode = Opcode::Frame; + memcpy(sendFrame.message, data, length); + sendFrame.length = (uint32_t)length; + if (!connection->Write(&sendFrame, sizeof(MessageFrameHeader) + length)) { + Close(); + return false; + } + return true; +} + +bool RpcConnection::Read(JsonDocument& message) +{ + if (state != State::Connected && state != State::SentHandshake) { + return false; + } + MessageFrame readFrame; + for (;;) { + bool didRead = connection->Read(&readFrame, sizeof(MessageFrameHeader)); + if (!didRead) { + if (!connection->isOpen) { + lastErrorCode = (int)ErrorCode::PipeClosed; + StringCopy(lastErrorMessage, "Pipe closed"); + Close(); + } + return false; + } + + if (readFrame.length > 0) { + didRead = connection->Read(readFrame.message, readFrame.length); + if (!didRead) { + lastErrorCode = (int)ErrorCode::ReadCorrupt; + StringCopy(lastErrorMessage, "Partial data in frame"); + Close(); + return false; + } + readFrame.message[readFrame.length] = 0; + } + + switch (readFrame.opcode) { + case Opcode::Close: { + message.ParseInsitu(readFrame.message); + lastErrorCode = GetIntMember(&message, "code"); + StringCopy(lastErrorMessage, GetStrMember(&message, "message", "")); + Close(); + return false; + } + case Opcode::Frame: + message.ParseInsitu(readFrame.message); + return true; + case Opcode::Ping: + readFrame.opcode = Opcode::Pong; + if (!connection->Write(&readFrame, sizeof(MessageFrameHeader) + readFrame.length)) { + Close(); + } + break; + case Opcode::Pong: + break; + case Opcode::Handshake: + default: + // something bad happened + lastErrorCode = (int)ErrorCode::ReadCorrupt; + StringCopy(lastErrorMessage, "Bad ipc frame"); + Close(); + return false; + } + } +} diff --git a/source/Discord/rpc_connection.h b/source/Discord/rpc_connection.h new file mode 100644 index 0000000..bbdd05c --- /dev/null +++ b/source/Discord/rpc_connection.h @@ -0,0 +1,59 @@ +#pragma once + +#include "connection.h" +#include "serialization.h" + +// I took this from the buffer size libuv uses for named pipes; I suspect ours would usually be much +// smaller. +constexpr size_t MaxRpcFrameSize = 64 * 1024; + +struct RpcConnection { + enum class ErrorCode : int { + Success = 0, + PipeClosed = 1, + ReadCorrupt = 2, + }; + + enum class Opcode : uint32_t { + Handshake = 0, + Frame = 1, + Close = 2, + Ping = 3, + Pong = 4, + }; + + struct MessageFrameHeader { + Opcode opcode; + uint32_t length; + }; + + struct MessageFrame : public MessageFrameHeader { + char message[MaxRpcFrameSize - sizeof(MessageFrameHeader)]; + }; + + enum class State : uint32_t { + Disconnected, + SentHandshake, + AwaitingResponse, + Connected, + }; + + BaseConnection* connection{nullptr}; + State state{State::Disconnected}; + void (*onConnect)(JsonDocument& message){nullptr}; + void (*onDisconnect)(int errorCode, const char* message){nullptr}; + char appId[64]{}; + int lastErrorCode{0}; + char lastErrorMessage[256]{}; + RpcConnection::MessageFrame sendFrame; + + static RpcConnection* Create(const char* applicationId); + static void Destroy(RpcConnection*&); + + inline bool IsOpen() const { return state == State::Connected; } + + void Open(); + void Close(); + bool Write(const void* data, size_t length); + bool Read(JsonDocument& message); +}; diff --git a/source/Discord/serialization.cpp b/source/Discord/serialization.cpp new file mode 100644 index 0000000..6cc1e90 --- /dev/null +++ b/source/Discord/serialization.cpp @@ -0,0 +1,245 @@ +#include "serialization.h" +#include "connection.h" +#include "discord_rpc.h" + +template +void NumberToString(char* dest, T number) +{ + if (!number) { + *dest++ = '0'; + *dest++ = 0; + return; + } + if (number < 0) { + *dest++ = '-'; + number = -number; + } + char temp[32]; + int place = 0; + while (number) { + auto digit = number % 10; + number = number / 10; + temp[place++] = '0' + (char)digit; + } + for (--place; place >= 0; --place) { + *dest++ = temp[place]; + } + *dest = 0; +} + +// it's ever so slightly faster to not have to strlen the key +template +void WriteKey(JsonWriter& w, T& k) +{ + w.Key(k, sizeof(T) - 1); +} + +struct WriteObject { + JsonWriter& writer; + WriteObject(JsonWriter& w) + : writer(w) + { + writer.StartObject(); + } + template + WriteObject(JsonWriter& w, T& name) + : writer(w) + { + WriteKey(writer, name); + writer.StartObject(); + } + ~WriteObject() { writer.EndObject(); } +}; + +struct WriteArray { + JsonWriter& writer; + template + WriteArray(JsonWriter& w, T& name) + : writer(w) + { + WriteKey(writer, name); + writer.StartArray(); + } + ~WriteArray() { writer.EndArray(); } +}; + +template +void WriteOptionalString(JsonWriter& w, T& k, const char* value) +{ + if (value && value[0]) { + w.Key(k, sizeof(T) - 1); + w.String(value); + } +} + +static void JsonWriteNonce(JsonWriter& writer, int nonce) +{ + WriteKey(writer, "nonce"); + char nonceBuffer[32]; + NumberToString(nonceBuffer, nonce); + writer.String(nonceBuffer); +} + +size_t JsonWriteRichPresenceObj(char* dest, + size_t maxLen, + int nonce, + int pid, + const DiscordRichPresence* presence) +{ + JsonWriter writer(dest, maxLen); + + { + WriteObject top(writer); + + JsonWriteNonce(writer, nonce); + + WriteKey(writer, "cmd"); + writer.String("SET_ACTIVITY"); + + { + WriteObject args(writer, "args"); + + WriteKey(writer, "pid"); + writer.Int(pid); + + if (presence != nullptr) { + WriteObject activity(writer, "activity"); + + WriteOptionalString(writer, "state", presence->state); + WriteOptionalString(writer, "details", presence->details); + + if (presence->startTimestamp || presence->endTimestamp) { + WriteObject timestamps(writer, "timestamps"); + + if (presence->startTimestamp) { + WriteKey(writer, "start"); + writer.Int64(presence->startTimestamp); + } + + if (presence->endTimestamp) { + WriteKey(writer, "end"); + writer.Int64(presence->endTimestamp); + } + } + + if ((presence->largeImageKey && presence->largeImageKey[0]) || + (presence->largeImageText && presence->largeImageText[0]) || + (presence->smallImageKey && presence->smallImageKey[0]) || + (presence->smallImageText && presence->smallImageText[0])) { + WriteObject assets(writer, "assets"); + WriteOptionalString(writer, "large_image", presence->largeImageKey); + WriteOptionalString(writer, "large_text", presence->largeImageText); + WriteOptionalString(writer, "small_image", presence->smallImageKey); + WriteOptionalString(writer, "small_text", presence->smallImageText); + } + + if ((presence->partyId && presence->partyId[0]) || presence->partySize || + presence->partyMax) { + WriteObject party(writer, "party"); + WriteOptionalString(writer, "id", presence->partyId); + if (presence->partySize && presence->partyMax) { + WriteArray size(writer, "size"); + writer.Int(presence->partySize); + writer.Int(presence->partyMax); + } + } + + if ((presence->matchSecret && presence->matchSecret[0]) || + (presence->joinSecret && presence->joinSecret[0]) || + (presence->spectateSecret && presence->spectateSecret[0])) { + WriteObject secrets(writer, "secrets"); + WriteOptionalString(writer, "match", presence->matchSecret); + WriteOptionalString(writer, "join", presence->joinSecret); + WriteOptionalString(writer, "spectate", presence->spectateSecret); + } + + writer.Key("instance"); + writer.Bool(presence->instance != 0); + } + } + } + + return writer.Size(); +} + +size_t JsonWriteHandshakeObj(char* dest, size_t maxLen, int version, const char* applicationId) +{ + JsonWriter writer(dest, maxLen); + + { + WriteObject obj(writer); + WriteKey(writer, "v"); + writer.Int(version); + WriteKey(writer, "client_id"); + writer.String(applicationId); + } + + return writer.Size(); +} + +size_t JsonWriteSubscribeCommand(char* dest, size_t maxLen, int nonce, const char* evtName) +{ + JsonWriter writer(dest, maxLen); + + { + WriteObject obj(writer); + + JsonWriteNonce(writer, nonce); + + WriteKey(writer, "cmd"); + writer.String("SUBSCRIBE"); + + WriteKey(writer, "evt"); + writer.String(evtName); + } + + return writer.Size(); +} + +size_t JsonWriteUnsubscribeCommand(char* dest, size_t maxLen, int nonce, const char* evtName) +{ + JsonWriter writer(dest, maxLen); + + { + WriteObject obj(writer); + + JsonWriteNonce(writer, nonce); + + WriteKey(writer, "cmd"); + writer.String("UNSUBSCRIBE"); + + WriteKey(writer, "evt"); + writer.String(evtName); + } + + return writer.Size(); +} + +size_t JsonWriteJoinReply(char* dest, size_t maxLen, const char* userId, int reply, int nonce) +{ + JsonWriter writer(dest, maxLen); + + { + WriteObject obj(writer); + + WriteKey(writer, "cmd"); + if (reply == DISCORD_REPLY_YES) { + writer.String("SEND_ACTIVITY_JOIN_INVITE"); + } + else { + writer.String("CLOSE_ACTIVITY_JOIN_REQUEST"); + } + + WriteKey(writer, "args"); + { + WriteObject args(writer); + + WriteKey(writer, "user_id"); + writer.String(userId); + } + + JsonWriteNonce(writer, nonce); + } + + return writer.Size(); +} diff --git a/source/Discord/serialization.h b/source/Discord/serialization.h new file mode 100644 index 0000000..9c462dc --- /dev/null +++ b/source/Discord/serialization.h @@ -0,0 +1,215 @@ +#pragma once + +#include + +#ifndef __MINGW32__ +#pragma warning(push) + +#pragma warning(disable : 4061) // enum is not explicitly handled by a case label +#pragma warning(disable : 4365) // signed/unsigned mismatch +#pragma warning(disable : 4464) // relative include path contains +#pragma warning(disable : 4668) // is not defined as a preprocessor macro +#pragma warning(disable : 6313) // Incorrect operator +#endif // __MINGW32__ + +#include "rapidjson/document.h" +#include "rapidjson/stringbuffer.h" +#include "rapidjson/writer.h" + +#ifndef __MINGW32__ +#pragma warning(pop) +#endif // __MINGW32__ + +// if only there was a standard library function for this +template +inline size_t StringCopy(char (&dest)[Len], const char* src) +{ + if (!src || !Len) { + return 0; + } + size_t copied; + char* out = dest; + for (copied = 1; *src && copied < Len; ++copied) { + *out++ = *src++; + } + *out = 0; + return copied - 1; +} + +size_t JsonWriteHandshakeObj(char* dest, size_t maxLen, int version, const char* applicationId); + +// Commands +struct DiscordRichPresence; +size_t JsonWriteRichPresenceObj(char* dest, + size_t maxLen, + int nonce, + int pid, + const DiscordRichPresence* presence); +size_t JsonWriteSubscribeCommand(char* dest, size_t maxLen, int nonce, const char* evtName); + +size_t JsonWriteUnsubscribeCommand(char* dest, size_t maxLen, int nonce, const char* evtName); + +size_t JsonWriteJoinReply(char* dest, size_t maxLen, const char* userId, int reply, int nonce); + +// I want to use as few allocations as I can get away with, and to do that with RapidJson, you need +// to supply some of your own allocators for stuff rather than use the defaults + +class LinearAllocator { +public: + char* buffer_; + char* end_; + LinearAllocator() + { + assert(0); // needed for some default case in rapidjson, should not use + } + LinearAllocator(char* buffer, size_t size) + : buffer_(buffer) + , end_(buffer + size) + { + } + static const bool kNeedFree = false; + void* Malloc(size_t size) + { + char* res = buffer_; + buffer_ += size; + if (buffer_ > end_) { + buffer_ = res; + return nullptr; + } + return res; + } + void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) + { + if (newSize == 0) { + return nullptr; + } + // allocate how much you need in the first place + assert(!originalPtr && !originalSize); + // unused parameter warning + (void)(originalPtr); + (void)(originalSize); + return Malloc(newSize); + } + static void Free(void* ptr) + { + /* shrug */ + (void)ptr; + } +}; + +template +class FixedLinearAllocator : public LinearAllocator { +public: + char fixedBuffer_[Size]; + FixedLinearAllocator() + : LinearAllocator(fixedBuffer_, Size) + { + } + static const bool kNeedFree = false; +}; + +// wonder why this isn't a thing already, maybe I missed it +class DirectStringBuffer { +public: + using Ch = char; + char* buffer_; + char* end_; + char* current_; + + DirectStringBuffer(char* buffer, size_t maxLen) + : buffer_(buffer) + , end_(buffer + maxLen) + , current_(buffer) + { + } + + void Put(char c) + { + if (current_ < end_) { + *current_++ = c; + } + } + void Flush() {} + size_t GetSize() const { return (size_t)(current_ - buffer_); } +}; + +using MallocAllocator = rapidjson::CrtAllocator; +using PoolAllocator = rapidjson::MemoryPoolAllocator; +using UTF8 = rapidjson::UTF8; +// Writer appears to need about 16 bytes per nested object level (with 64bit size_t) +using StackAllocator = FixedLinearAllocator<2048>; +constexpr size_t WriterNestingLevels = 2048 / (2 * sizeof(size_t)); +using JsonWriterBase = + rapidjson::Writer; +class JsonWriter : public JsonWriterBase { +public: + DirectStringBuffer stringBuffer_; + StackAllocator stackAlloc_; + + JsonWriter(char* dest, size_t maxLen) + : JsonWriterBase(stringBuffer_, &stackAlloc_, WriterNestingLevels) + , stringBuffer_(dest, maxLen) + , stackAlloc_() + { + } + + size_t Size() const { return stringBuffer_.GetSize(); } +}; + +using JsonDocumentBase = rapidjson::GenericDocument; +class JsonDocument : public JsonDocumentBase { +public: + static const int kDefaultChunkCapacity = 32 * 1024; + // json parser will use this buffer first, then allocate more if needed; I seriously doubt we + // send any messages that would use all of this, though. + char parseBuffer_[32 * 1024]; + MallocAllocator mallocAllocator_; + PoolAllocator poolAllocator_; + StackAllocator stackAllocator_; + JsonDocument() + : JsonDocumentBase(rapidjson::kObjectType, + &poolAllocator_, + sizeof(stackAllocator_.fixedBuffer_), + &stackAllocator_) + , poolAllocator_(parseBuffer_, sizeof(parseBuffer_), kDefaultChunkCapacity, &mallocAllocator_) + , stackAllocator_() + { + } +}; + +using JsonValue = rapidjson::GenericValue; + +inline JsonValue* GetObjMember(JsonValue* obj, const char* name) +{ + if (obj) { + auto member = obj->FindMember(name); + if (member != obj->MemberEnd() && member->value.IsObject()) { + return &member->value; + } + } + return nullptr; +} + +inline int GetIntMember(JsonValue* obj, const char* name, int notFoundDefault = 0) +{ + if (obj) { + auto member = obj->FindMember(name); + if (member != obj->MemberEnd() && member->value.IsInt()) { + return member->value.GetInt(); + } + } + return notFoundDefault; +} + +inline const char* GetStrMember(JsonValue* obj, + const char* name, + const char* notFoundDefault = nullptr) +{ + if (obj) { + auto member = obj->FindMember(name); + if (member != obj->MemberEnd() && member->value.IsString()) { + return member->value.GetString(); + } + } + return notFoundDefault; +} diff --git a/source/EffectLib/EffectData.cpp b/source/EffectLib/EffectData.cpp new file mode 100644 index 0000000..41ca5d0 --- /dev/null +++ b/source/EffectLib/EffectData.cpp @@ -0,0 +1,221 @@ +#include "StdAfx.h" +#include "EffectData.h" + +CDynamicPool CEffectData::ms_kPool; + +CEffectData* CEffectData::New() +{ + return ms_kPool.Alloc(); +} + +void CEffectData::Delete(CEffectData* pkData) +{ + pkData->Clear(); + ms_kPool.Free(pkData); +} + +void CEffectData::DestroySystem() +{ + ms_kPool.Destroy(); + + CParticleSystemData::DestroySystem(); + CEffectMeshScript::DestroySystem(); + CLightData::DestroySystem(); +} + +bool CEffectData::LoadScript(const char * c_szFileName) +{ + m_strFileName = c_szFileName; + CFileNameHelper::StringPath(m_strFileName); + + CTextFileLoader TextFileLoader; + if (!TextFileLoader.Load(c_szFileName)) + return false; + + TextFileLoader.SetTop(); + + if (!TextFileLoader.GetTokenFloat("boundingsphereradius", &m_fBoundingSphereRadius)) + { + m_fBoundingSphereRadius = 0.0f; + } + + if (!TextFileLoader.GetTokenVector3("boundingsphereposition", &m_v3BoundingSpherePosition)) + { + m_v3BoundingSpherePosition.x = m_v3BoundingSpherePosition.y = m_v3BoundingSpherePosition.z = 0.0f; + } + + for (DWORD i = 0; i < TextFileLoader.GetChildNodeCount(); ++i) + { + if (!TextFileLoader.SetChildNode(i)) + continue; + + std::string strName; + + if (!TextFileLoader.GetCurrentNodeName(&strName)) + continue; + + if (0 == strName.compare("mesh")) + { + CEffectMeshScript * pMesh = AllocMesh(); + pMesh->Clear(); + pMesh->LoadScript(TextFileLoader); + } + else if (0 == strName.compare("particle")) + { + CParticleSystemData * pParticleSystemData = AllocParticle(); + pParticleSystemData->Clear(); + pParticleSystemData->LoadScript(TextFileLoader); + } + else if (0 == strName.compare("light")) + { + CLightData * pLightData = AllocLight(); + pLightData->Clear(); + pLightData->LoadScript(TextFileLoader); + } + + TextFileLoader.SetParentNode(); + } + + // Load Sound + std::string strPathHeader = "d:/ymir work/"; + std::string strNoExtensionName = CFileNameHelper::NoExtension(m_strFileName); + int iPos = strNoExtensionName.find(strPathHeader.c_str()); + if (iPos >= 0) + if (strNoExtensionName.size() > strPathHeader.size()) + { + std::string strSoundFileName; + strSoundFileName = "sound/"; + strSoundFileName += &strNoExtensionName[strPathHeader.size()]; + strSoundFileName += ".mss"; + + LoadSoundScriptData(strSoundFileName.c_str()); + } + + return true; +} + +bool CEffectData::LoadSoundScriptData(const char * c_szFileName) +{ + NSound::TSoundDataVector SoundDataVector; + + if (NSound::LoadSoundInformationPiece(c_szFileName, SoundDataVector)) + { + NSound::DataToInstance(SoundDataVector, &m_SoundInstanceVector); + return false; + } + + return true; +} + +CParticleSystemData * CEffectData::AllocParticle() +{ + CParticleSystemData * pParticle = CParticleSystemData::New(); + m_ParticleVector.push_back(pParticle); + return pParticle; +} + +CEffectMeshScript * CEffectData::AllocMesh() +{ + CEffectMeshScript * pMesh = CEffectMeshScript::New(); + m_MeshVector.push_back(pMesh); + return pMesh; +} + +CLightData * CEffectData::AllocLight() +{ + CLightData * pLight = CLightData::New(); + m_LightVector.push_back(pLight); + return pLight; +} + +DWORD CEffectData::GetLightCount() +{ + return m_LightVector.size(); +} + +CLightData * CEffectData::GetLightPointer(DWORD dwPosition) +{ + assert(dwPosition < m_LightVector.size()); + return m_LightVector[dwPosition]; +} + +DWORD CEffectData::GetParticleCount() +{ + return m_ParticleVector.size(); +} +CParticleSystemData * CEffectData::GetParticlePointer(DWORD dwPosition) +{ + if(dwPosition < m_ParticleVector.size()) + return m_ParticleVector[dwPosition]; + else + { + assert(false); + return NULL; + } +} + +DWORD CEffectData::GetMeshCount() +{ + return m_MeshVector.size(); +} +CEffectMeshScript * CEffectData::GetMeshPointer(DWORD dwPosition) +{ + assert(dwPosition < m_MeshVector.size()); + return m_MeshVector[dwPosition]; +} + +NSound::TSoundInstanceVector * CEffectData::GetSoundInstanceVector() +{ + return &m_SoundInstanceVector; +} + +float CEffectData::GetBoundingSphereRadius() +{ + return m_fBoundingSphereRadius; +} + +D3DXVECTOR3 CEffectData::GetBoundingSpherePosition() +{ + return m_v3BoundingSpherePosition; +} + +const char * CEffectData::GetFileName() const +{ + return m_strFileName.c_str(); +} + +void CEffectData::__ClearParticleDataVector() +{ + std::for_each(m_ParticleVector.begin(), m_ParticleVector.end(), CParticleSystemData::Delete); + m_ParticleVector.clear(); +} + +void CEffectData::__ClearLightDataVector() +{ + std::for_each(m_LightVector.begin(), m_LightVector.end(), CLightData::Delete); + m_LightVector.clear(); +} + +void CEffectData::__ClearMeshDataVector() +{ + std::for_each(m_MeshVector.begin(), m_MeshVector.end(), CEffectMeshScript::Delete); + m_MeshVector.clear(); +} + +void CEffectData::Clear() +{ + m_fBoundingSphereRadius = 0.0f; + m_v3BoundingSpherePosition.x = m_v3BoundingSpherePosition.y = m_v3BoundingSpherePosition.z = 0.0f; + __ClearParticleDataVector(); + __ClearLightDataVector(); + __ClearMeshDataVector(); +} + +CEffectData::CEffectData() +{ + m_fBoundingSphereRadius = 0.0f; + m_v3BoundingSpherePosition.x = m_v3BoundingSpherePosition.y = m_v3BoundingSpherePosition.z = 0.0f; +} +CEffectData::~CEffectData() +{ +} diff --git a/source/EffectLib/EffectData.h b/source/EffectLib/EffectData.h new file mode 100644 index 0000000..739f6ff --- /dev/null +++ b/source/EffectLib/EffectData.h @@ -0,0 +1,69 @@ +#pragma once + +#include "../milesLib/Type.h" + +#include "ParticleSystemData.h" +#include "EffectMesh.h" +#include "SimpleLightData.h" + +class CEffectData +{ + public: + typedef std::vector TParticleVector; + typedef std::vector TMeshVector; + typedef std::vector TLightVector; + + public: + CEffectData(); + virtual ~CEffectData(); + + void Clear(); + bool LoadScript(const char * c_szFileName); + bool LoadSoundScriptData(const char * c_szFileName); + + DWORD GetParticleCount(); + CParticleSystemData * GetParticlePointer(DWORD dwPosition); + + DWORD GetMeshCount(); + CEffectMeshScript * GetMeshPointer(DWORD dwPosition); + + DWORD GetLightCount(); + CLightData * GetLightPointer(DWORD dwPosition); + + NSound::TSoundInstanceVector * GetSoundInstanceVector(); + + float GetBoundingSphereRadius(); + D3DXVECTOR3 GetBoundingSpherePosition(); + + const char * GetFileName() const; + + protected: + void __ClearParticleDataVector(); + void __ClearLightDataVector(); + void __ClearMeshDataVector(); + + // FIXME : κ ״ ʴ´. ̵ ãƳ ġ. + // (Ưȭ) ̽ ٲ Ѵٴ ϴ. - [levites] + virtual CParticleSystemData * AllocParticle(); + virtual CEffectMeshScript * AllocMesh(); + virtual CLightData * AllocLight(); + + protected: + TParticleVector m_ParticleVector; + TMeshVector m_MeshVector; + TLightVector m_LightVector; + NSound::TSoundInstanceVector m_SoundInstanceVector; + + float m_fBoundingSphereRadius; + D3DXVECTOR3 m_v3BoundingSpherePosition; + + std::string m_strFileName; + + public: + static void DestroySystem(); + + static CEffectData* New(); + static void Delete(CEffectData* pkData); + + static CDynamicPool ms_kPool; +}; \ No newline at end of file diff --git a/source/EffectLib/EffectElementBase.cpp b/source/EffectLib/EffectElementBase.cpp new file mode 100644 index 0000000..d8330dd --- /dev/null +++ b/source/EffectLib/EffectElementBase.cpp @@ -0,0 +1,168 @@ +#include "StdAfx.h" +#include "EffectElementBase.h" + + +void CEffectElementBase::GetPosition(float fTime, D3DXVECTOR3 & rPosition) +{ + if (m_TimeEventTablePosition.empty()) + { + rPosition = D3DXVECTOR3(0.0f, 0.0f, 0.0f); + return; + } + if (m_TimeEventTablePosition.size()==1) + { + rPosition = m_TimeEventTablePosition[0].m_vecPosition; + return; + } + if (m_TimeEventTablePosition.front().m_fTime > fTime) + { + rPosition = m_TimeEventTablePosition.front().m_vecPosition; + return; + } + if (m_TimeEventTablePosition.back().m_fTime < fTime) + { + rPosition = m_TimeEventTablePosition.back().m_vecPosition; + return; + } + + typedef TTimeEventTablePosition::iterator iterator; + iterator result = std::lower_bound( m_TimeEventTablePosition.begin(), m_TimeEventTablePosition.end(), fTime ); + + TEffectPosition & rEffectPosition = *result; + iterator rPrev = result; + if (m_TimeEventTablePosition.begin() != result) + { + rPrev = result-1; + } + else + { + rPosition = result->m_vecPosition; + return; + } + TEffectPosition & rPrevEffectPosition = *rPrev; + int iMovingType = rPrevEffectPosition.m_iMovingType; + + if (MOVING_TYPE_DIRECT == iMovingType) + { + float Head = fabs(rEffectPosition.m_fTime - fTime) / fabs(rEffectPosition.m_fTime - rPrevEffectPosition.m_fTime); + float Tail = 1.0f - fabs(rEffectPosition.m_fTime - fTime) / fabs(rEffectPosition.m_fTime - rPrevEffectPosition.m_fTime); + rPosition = (rPrevEffectPosition.m_vecPosition*Head) + (rEffectPosition.m_vecPosition*Tail); + } + else if (MOVING_TYPE_BEZIER_CURVE == iMovingType) + { + float ft = (fTime - rPrevEffectPosition.m_fTime) / (rEffectPosition.m_fTime - rPrevEffectPosition.m_fTime); + + rPosition = rPrevEffectPosition.m_vecPosition * (1.0f - ft) * (1.0f - ft) + + (rPrevEffectPosition.m_vecPosition + rPrevEffectPosition.m_vecControlPoint) * (1.0f - ft) * ft * 2 + + rEffectPosition.m_vecPosition * ft * ft; + } +} + +/* +bool CEffectElementBase::isVisible(float fTime) +{ + for (DWORD i = 0; i < m_TimeEventTableVisible.size(); ++i) + { + float fPointTime = m_TimeEventTableVisible[i]; + + if (fTime < fPointTime) + { + if (1 == i % 2) + return true; + else + return false; + } + } + + return 1 == (m_TimeEventTableVisible.size() % 2); +} + +void CEffectElementBase::GetAlpha(float fTime, float * pAlpha) +{ + GetTimeEventBlendValue(fTime, m_TimeEventAlpha, pAlpha); +} + +void CEffectElementBase::GetScale(float fTime, float * pScale) +{ + GetTimeEventBlendValue(fTime, m_TimeEventScale, pScale); +} +*/ + +bool CEffectElementBase::isData() +{ + return OnIsData(); +} + +void CEffectElementBase::Clear() +{ + m_fStartTime = 0.0f; + + OnClear(); +} + +BOOL CEffectElementBase::LoadScript(CTextFileLoader & rTextFileLoader) +{ + CTokenVector * pTokenVector; + if (!rTextFileLoader.GetTokenFloat("starttime",&m_fStartTime)) + { + m_fStartTime = 0.0f; + } + if (rTextFileLoader.GetTokenVector("timeeventposition", &pTokenVector)) + { + m_TimeEventTablePosition.clear(); + + DWORD dwIndex = 0; + for (DWORD i = 0; i < pTokenVector->size(); ++dwIndex) + { + TEffectPosition EffectPosition; + EffectPosition.m_fTime = atof(pTokenVector->at(i++).c_str()); + if (pTokenVector->at(i)=="MOVING_TYPE_BEZIER_CURVE") + { + i++; + + EffectPosition.m_iMovingType = MOVING_TYPE_BEZIER_CURVE; + + EffectPosition.m_vecPosition.x = atof(pTokenVector->at(i++).c_str()); + EffectPosition.m_vecPosition.y = atof(pTokenVector->at(i++).c_str()); + EffectPosition.m_vecPosition.z = atof(pTokenVector->at(i++).c_str()); + + EffectPosition.m_vecControlPoint.x = atof(pTokenVector->at(i++).c_str()); + EffectPosition.m_vecControlPoint.y = atof(pTokenVector->at(i++).c_str()); + EffectPosition.m_vecControlPoint.z = atof(pTokenVector->at(i++).c_str()); + } + else if (pTokenVector->at(i) == "MOVING_TYPE_DIRECT") + { + i++; + + EffectPosition.m_iMovingType = MOVING_TYPE_DIRECT; + + EffectPosition.m_vecPosition.x = atof(pTokenVector->at(i++).c_str()); + EffectPosition.m_vecPosition.y = atof(pTokenVector->at(i++).c_str()); + EffectPosition.m_vecPosition.z = atof(pTokenVector->at(i++).c_str()); + + EffectPosition.m_vecControlPoint = D3DXVECTOR3(0.0f,0.0f,0.0f); + } + else + { + return FALSE; + } + + m_TimeEventTablePosition.push_back(EffectPosition); + } + } + + return OnLoadScript(rTextFileLoader); +} + +float CEffectElementBase::GetStartTime() +{ + return m_fStartTime; +} + +CEffectElementBase::CEffectElementBase() +{ + m_fStartTime = 0.0f; +} +CEffectElementBase::~CEffectElementBase() +{ +} diff --git a/source/EffectLib/EffectElementBase.h b/source/EffectLib/EffectElementBase.h new file mode 100644 index 0000000..870db31 --- /dev/null +++ b/source/EffectLib/EffectElementBase.h @@ -0,0 +1,37 @@ +#pragma once + +#include "Type.h" + +class CEffectElementBase +{ + public: + CEffectElementBase(); + virtual ~CEffectElementBase(); + + void Clear(); + bool isData(); + + BOOL LoadScript(CTextFileLoader & rTextFileLoader); + + void GetPosition(float fTime, D3DXVECTOR3 & rPosition); + float GetStartTime(); +/* + bool isVisible(float fTime); + void GetAlpha(float fTime, float * pAlpha); + void GetScale(float fTime, float * pScale); +*/ + + protected: + virtual void OnClear() = 0; + virtual bool OnIsData() = 0; + virtual BOOL OnLoadScript(CTextFileLoader & rTextFileLoader) = 0; + + protected: + float m_fStartTime; + TTimeEventTablePosition m_TimeEventTablePosition; +/* + TTimeEventTable m_TimeEventTableVisible; + TTimeEventTableFloat m_TimeEventAlpha; + TTimeEventTableFloat m_TimeEventScale; +*/ +}; diff --git a/source/EffectLib/EffectElementBaseInstance.cpp b/source/EffectLib/EffectElementBaseInstance.cpp new file mode 100644 index 0000000..80f64aa --- /dev/null +++ b/source/EffectLib/EffectElementBaseInstance.cpp @@ -0,0 +1,97 @@ +#include "StdAfx.h" +#include "EffectElementBaseInstance.h" + +bool CEffectElementBaseInstance::Update(float fElapsedTime) +{ + if (m_bStart) + { + m_fElapsedTime = fElapsedTime; + m_fLocalTime += fElapsedTime; + + return OnUpdate(fElapsedTime); + } + else + { + m_fRemainingTime -= fElapsedTime; + if (m_fRemainingTime<=0.0f) + m_bStart = true; + return true; + } +} + +void CEffectElementBaseInstance::Render() +{ + if (!m_bStart) + return; + + assert(mc_pmatLocal); + + OnRender(); +} + +void CEffectElementBaseInstance::SetLocalMatrixPointer(const D3DXMATRIX * c_pMatrix) +{ + mc_pmatLocal = c_pMatrix; +} + +void CEffectElementBaseInstance::SetDataPointer(CEffectElementBase * pElement) +{ + m_pBase = pElement; + + m_dwStartTime = CTimer::Instance().GetCurrentMillisecond(); + + ////////////////////////////////////////////////////////////////////////// + //add by ipkn, start time management + + m_fRemainingTime = pElement->GetStartTime(); + if (m_fRemainingTime<=0.0f) + m_bStart = true; + else + m_bStart = false; + + ////////////////////////////////////////////////////////////////////////// + + OnSetDataPointer(pElement); +} + +bool CEffectElementBaseInstance::isActive() +{ + return m_isActive; +} +void CEffectElementBaseInstance::SetActive() +{ + m_isActive = true; +} +void CEffectElementBaseInstance::SetDeactive() +{ + m_isActive = false; +} + +void CEffectElementBaseInstance::Initialize() +{ + mc_pmatLocal = NULL; + + m_isActive = true; + + m_fLocalTime = 0.0f; + m_dwStartTime = 0; + m_fElapsedTime = 0.0f; + + m_bStart = false; + m_fRemainingTime = 0.0f; + + OnInitialize(); +} + +void CEffectElementBaseInstance::Destroy() +{ + OnDestroy(); + Initialize(); +} + +CEffectElementBaseInstance::CEffectElementBaseInstance() +{ +} +CEffectElementBaseInstance::~CEffectElementBaseInstance() +{ +} \ No newline at end of file diff --git a/source/EffectLib/EffectElementBaseInstance.h b/source/EffectLib/EffectElementBaseInstance.h new file mode 100644 index 0000000..19d394d --- /dev/null +++ b/source/EffectLib/EffectElementBaseInstance.h @@ -0,0 +1,46 @@ +#pragma once + +#include "EffectElementBase.h" + +class CEffectElementBaseInstance +{ + public: + CEffectElementBaseInstance(); + virtual ~CEffectElementBaseInstance(); + + void SetDataPointer(CEffectElementBase * pElement); + + void Initialize(); + void Destroy(); + + void SetLocalMatrixPointer(const D3DXMATRIX * c_pMatrix); + bool Update(float fElapsedTime); + void Render(); + + bool isActive(); + void SetActive(); + void SetDeactive(); + + protected: + virtual void OnSetDataPointer(CEffectElementBase * pElement) = 0; + + virtual void OnInitialize() = 0; + virtual void OnDestroy() = 0; + + virtual bool OnUpdate(float fElapsedTime) = 0; + virtual void OnRender() = 0; + + protected: + const D3DXMATRIX * mc_pmatLocal; + + bool m_isActive; + + float m_fLocalTime; + DWORD m_dwStartTime; + float m_fElapsedTime; + float m_fRemainingTime; + bool m_bStart; + + private: + CEffectElementBase * m_pBase; +}; \ No newline at end of file diff --git a/source/EffectLib/EffectInstance.cpp b/source/EffectLib/EffectInstance.cpp new file mode 100644 index 0000000..de156cd --- /dev/null +++ b/source/EffectLib/EffectInstance.cpp @@ -0,0 +1,288 @@ +#include "StdAfx.h" +#include "EffectInstance.h" +#include "ParticleSystemInstance.h" +#include "SimpleLightInstance.h" + +#include "../eterBase/Stl.h" +#include "../eterLib/StateManager.h" +#include "../MilesLib/SoundManager.h" + +CDynamicPool CEffectInstance::ms_kPool; +int CEffectInstance::ms_iRenderingEffectCount = 0; + +bool CEffectInstance::LessRenderOrder(CEffectInstance* pkEftInst) +{ + return (m_pkEftDatam_pkEftData); +} + +void CEffectInstance::ResetRenderingEffectCount() +{ + ms_iRenderingEffectCount = 0; +} + +int CEffectInstance::GetRenderingEffectCount() +{ + return ms_iRenderingEffectCount; +} + +CEffectInstance* CEffectInstance::New() +{ + CEffectInstance* pkEftInst=ms_kPool.Alloc(); + return pkEftInst; +} + +void CEffectInstance::Delete(CEffectInstance* pkEftInst) +{ + pkEftInst->Clear(); + ms_kPool.Free(pkEftInst); +} + +void CEffectInstance::DestroySystem() +{ + ms_kPool.Destroy(); + + CParticleSystemInstance::DestroySystem(); + CEffectMeshInstance::DestroySystem(); + CLightInstance::DestroySystem(); +} + +void CEffectInstance::UpdateSound() +{ + if (m_pSoundInstanceVector) + { + CSoundManager& rkSndMgr=CSoundManager::Instance(); + rkSndMgr.UpdateSoundInstance(m_matGlobal._41, m_matGlobal._42, m_matGlobal._43, m_dwFrame, m_pSoundInstanceVector); + // NOTE : Ʈ ġ ´ - [levites] + } + ++m_dwFrame; +} + +struct FEffectUpdator +{ + BOOL isAlive; + float fElapsedTime; + FEffectUpdator(float fElapsedTime) + : isAlive(FALSE), fElapsedTime(fElapsedTime) + { + } + void operator () (CEffectElementBaseInstance * pInstance) + { + if (pInstance->Update(fElapsedTime)) + isAlive = TRUE; + } +}; + +void CEffectInstance::OnUpdate() +{ + Transform(); + +#ifdef WORLD_EDITOR + FEffectUpdator f(CTimer::Instance().GetElapsedSecond()); +#else + FEffectUpdator f(CTimer::Instance().GetCurrentSecond()-m_fLastTime); +#endif + f = std::for_each(m_ParticleInstanceVector.begin(), m_ParticleInstanceVector.end(),f); + f = std::for_each(m_MeshInstanceVector.begin(), m_MeshInstanceVector.end(),f); + f = std::for_each(m_LightInstanceVector.begin(), m_LightInstanceVector.end(),f); + m_isAlive = f.isAlive; + + m_fLastTime = CTimer::Instance().GetCurrentSecond(); +} + +void CEffectInstance::OnRender() +{ + STATEMANAGER.SaveTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_NONE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_NONE); + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, FALSE); + STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, FALSE); + ///// + + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_TEX1); + std::for_each(m_ParticleInstanceVector.begin(),m_ParticleInstanceVector.end(),std::mem_fn(&CEffectElementBaseInstance::Render)); + std::for_each(m_MeshInstanceVector.begin(),m_MeshInstanceVector.end(),std::mem_fn(&CEffectElementBaseInstance::Render)); + + ///// + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MINFILTER); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MAGFILTER); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND); + STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE); + STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE); + + ++ms_iRenderingEffectCount; +} + +void CEffectInstance::SetGlobalMatrix(const D3DXMATRIX & c_rmatGlobal) +{ + m_matGlobal = c_rmatGlobal; +} + +BOOL CEffectInstance::isAlive() +{ + return m_isAlive; +} + +void CEffectInstance::SetActive() +{ + std::for_each( + m_ParticleInstanceVector.begin(), + m_ParticleInstanceVector.end(), + std::mem_fn(&CEffectElementBaseInstance::SetActive)); + std::for_each( + m_MeshInstanceVector.begin(), + m_MeshInstanceVector.end(), + std::mem_fn(&CEffectElementBaseInstance::SetActive)); + std::for_each( + m_LightInstanceVector.begin(), + m_LightInstanceVector.end(), + std::mem_fn(&CEffectElementBaseInstance::SetActive)); +} + +void CEffectInstance::SetDeactive() +{ + std::for_each( + m_ParticleInstanceVector.begin(), + m_ParticleInstanceVector.end(), + std::mem_fn(&CEffectElementBaseInstance::SetDeactive)); + std::for_each( + m_MeshInstanceVector.begin(), + m_MeshInstanceVector.end(), + std::mem_fn(&CEffectElementBaseInstance::SetDeactive)); + std::for_each( + m_LightInstanceVector.begin(), + m_LightInstanceVector.end(), + std::mem_fn(&CEffectElementBaseInstance::SetDeactive)); +} + +void CEffectInstance::__SetParticleData(CParticleSystemData * pData) +{ + CParticleSystemInstance * pInstance = CParticleSystemInstance::New(); + pInstance->SetDataPointer(pData); + pInstance->SetLocalMatrixPointer(&m_matGlobal); + + m_ParticleInstanceVector.push_back(pInstance); +} +void CEffectInstance::__SetMeshData(CEffectMeshScript * pMesh) +{ + CEffectMeshInstance * pMeshInstance = CEffectMeshInstance::New(); + pMeshInstance->SetDataPointer(pMesh); + pMeshInstance->SetLocalMatrixPointer(&m_matGlobal); + + m_MeshInstanceVector.push_back(pMeshInstance); +} + +void CEffectInstance::__SetLightData(CLightData* pData) +{ + CLightInstance * pInstance = CLightInstance::New(); + pInstance->SetDataPointer(pData); + pInstance->SetLocalMatrixPointer(&m_matGlobal); + + m_LightInstanceVector.push_back(pInstance); +} + +void CEffectInstance::SetEffectDataPointer(CEffectData * pEffectData) +{ + m_isAlive=true; + + m_pkEftData=pEffectData; + + m_fLastTime = CTimer::Instance().GetCurrentSecond(); + m_fBoundingSphereRadius = pEffectData->GetBoundingSphereRadius(); + m_v3BoundingSpherePosition = pEffectData->GetBoundingSpherePosition(); + + if (m_fBoundingSphereRadius > 0.0f) + CGraphicObjectInstance::RegisterBoundingSphere(); + + DWORD i; + + for (i = 0; i < pEffectData->GetParticleCount(); ++i) + { + CParticleSystemData * pParticle = pEffectData->GetParticlePointer(i); + + __SetParticleData(pParticle); + } + + for (i = 0; i < pEffectData->GetMeshCount(); ++i) + { + CEffectMeshScript * pMesh = pEffectData->GetMeshPointer(i); + + __SetMeshData(pMesh); + } + + for (i = 0; i < pEffectData->GetLightCount(); ++i) + { + CLightData * pLight = pEffectData->GetLightPointer(i); + + __SetLightData(pLight); + } + + m_pSoundInstanceVector = pEffectData->GetSoundInstanceVector(); +} + +bool CEffectInstance::GetBoundingSphere(D3DXVECTOR3 & v3Center, float & fRadius) +{ + v3Center.x = m_matGlobal._41 + m_v3BoundingSpherePosition.x; + v3Center.y = m_matGlobal._42 + m_v3BoundingSpherePosition.y; + v3Center.z = m_matGlobal._43 + m_v3BoundingSpherePosition.z; + fRadius = m_fBoundingSphereRadius; + return true; +} + +void CEffectInstance::Clear() +{ + if (!m_ParticleInstanceVector.empty()) + { + std::for_each(m_ParticleInstanceVector.begin(), m_ParticleInstanceVector.end(), CParticleSystemInstance::Delete); + m_ParticleInstanceVector.clear(); + } + + if (!m_MeshInstanceVector.empty()) + { + std::for_each(m_MeshInstanceVector.begin(), m_MeshInstanceVector.end(), CEffectMeshInstance::Delete); + m_MeshInstanceVector.clear(); + } + + if (!m_LightInstanceVector.empty()) + { + std::for_each(m_LightInstanceVector.begin(), m_LightInstanceVector.end(), CLightInstance::Delete); + m_LightInstanceVector.clear(); + } + + __Initialize(); +} + +void CEffectInstance::__Initialize() +{ + m_isAlive = FALSE; + m_dwFrame = 0; + m_pSoundInstanceVector = NULL; + m_fBoundingSphereRadius = 0.0f; + m_v3BoundingSpherePosition.x = m_v3BoundingSpherePosition.y = m_v3BoundingSpherePosition.z = 0.0f; + + m_pkEftData=NULL; + + D3DXMatrixIdentity(&m_matGlobal); +} + +CEffectInstance::CEffectInstance() +{ + __Initialize(); +} +CEffectInstance::~CEffectInstance() +{ + assert(m_ParticleInstanceVector.empty()); + assert(m_MeshInstanceVector.empty()); + assert(m_LightInstanceVector.empty()); +} diff --git a/source/EffectLib/EffectInstance.h b/source/EffectLib/EffectInstance.h new file mode 100644 index 0000000..98e3331 --- /dev/null +++ b/source/EffectLib/EffectInstance.h @@ -0,0 +1,90 @@ +#pragma once + +#include "../eterlib/GrpObjectInstance.h" +#include "../eterlib/Pool.h" +#include "../mileslib/Type.h" + +#include "EffectElementBaseInstance.h" +#include "EffectData.h" +#include "EffectMeshInstance.h" +#include "ParticleSystemInstance.h" +#include "SimpleLightInstance.h" + +class CEffectInstance : public CGraphicObjectInstance +{ + public: + typedef std::vector TEffectElementInstanceVector; + + enum + { + ID = EFFECT_OBJECT + }; + int GetType() const + { + return CEffectInstance::ID; + } + + bool GetBoundingSphere(D3DXVECTOR3 & v3Center, float & fRadius); + + static void DestroySystem(); + + static CEffectInstance* New(); + static void Delete(CEffectInstance* pkEftInst); + + static void ResetRenderingEffectCount(); + static int GetRenderingEffectCount(); + + public: + CEffectInstance(); + virtual ~CEffectInstance(); + + bool LessRenderOrder(CEffectInstance* pkEftInst); + + void SetEffectDataPointer(CEffectData * pEffectData); + + void Clear(); + BOOL isAlive(); + void SetActive(); + void SetDeactive(); + void SetGlobalMatrix(const D3DXMATRIX & c_rmatGlobal); + void UpdateSound(); + void OnUpdate(); + void OnRender(); + void OnBlendRender() {} // Not used + void OnRenderToShadowMap() {} // Not used + void OnRenderShadow() {} // Not used + void OnRenderPCBlocker() {} // Not used + + protected: + void __Initialize(); + + void __SetParticleData(CParticleSystemData * pData); + void __SetMeshData(CEffectMeshScript * pMesh); + void __SetLightData(CLightData * pData); + + virtual void OnUpdateCollisionData(const CStaticCollisionDataVector * pscdVector) {} // Not used + virtual void OnUpdateHeighInstance(CAttributeInstance * pAttributeInstance) {} + virtual bool OnGetObjectHeight(float fX, float fY, float * pfHeight) { return false; } + + protected: + BOOL m_isAlive; + DWORD m_dwFrame; + D3DXMATRIX m_matGlobal; + + CEffectData * m_pkEftData; + + std::vector m_ParticleInstanceVector; + std::vector m_MeshInstanceVector; + std::vector m_LightInstanceVector; + + NSound::TSoundInstanceVector * m_pSoundInstanceVector; + + float m_fBoundingSphereRadius; + D3DXVECTOR3 m_v3BoundingSpherePosition; + + float m_fLastTime; + + public: + static CDynamicPool ms_kPool; + static int ms_iRenderingEffectCount; +}; diff --git a/source/EffectLib/EffectManager.cpp b/source/EffectLib/EffectManager.cpp new file mode 100644 index 0000000..480f825 --- /dev/null +++ b/source/EffectLib/EffectManager.cpp @@ -0,0 +1,468 @@ +#include "StdAfx.h" +#include "../eterBase/Random.h" +#include "../eterlib/StateManager.h" +#include "EffectManager.h" + + + +void CEffectManager::GetInfo(std::string* pstInfo) +{ + char szInfo[256]; + + sprintf(szInfo, "Effect: Inst - ED %d, EI %d Pool - PSI %d, MI %d, LI %d, PI %d, EI %d, ED %d, PSD %d, EM %d, LD %d", + m_kEftDataMap.size(), + m_kEftInstMap.size(), + CParticleSystemInstance::ms_kPool.GetCapacity(), + CEffectMeshInstance::ms_kPool.GetCapacity(), + CLightInstance::ms_kPool.GetCapacity(), + CParticleInstance::ms_kPool.GetCapacity(), + //CRayParticleInstance::ms_kPool.GetCapacity(), + CEffectInstance::ms_kPool.GetCapacity(), + CEffectData::ms_kPool.GetCapacity(), + CParticleSystemData::ms_kPool.GetCapacity(), + CEffectMeshScript::ms_kPool.GetCapacity(), + CLightData::ms_kPool.GetCapacity() + ); + pstInfo->append(szInfo); +} + +void CEffectManager::UpdateSound() +{ + for (TEffectInstanceMap::iterator itor = m_kEftInstMap.begin(); itor != m_kEftInstMap.end(); ++itor) + { + CEffectInstance * pEffectInstance = itor->second; + + pEffectInstance->UpdateSound(); + } +} + +bool CEffectManager::IsAliveEffect(DWORD dwInstanceIndex) +{ + TEffectInstanceMap::iterator f = m_kEftInstMap.find(dwInstanceIndex); + if (m_kEftInstMap.end()==f) + return false; + + return f->second->isAlive() ? true : false; +} + +void CEffectManager::Update() +{ + + // 2004. 3. 1. myevan. Ʈ ͸ ϴ ڵ + /* + if (GetAsyncKeyState(VK_F9)) + { + Tracenf("CEffectManager::m_EffectInstancePool %d", m_EffectInstancePool.GetCapacity()); + Tracenf("CEffectManager::m_EffectDataPool %d", m_EffectDataPool.GetCapacity()); + Tracenf("CEffectInstance::ms_LightInstancePool %d", CEffectInstance::ms_LightInstancePool.GetCapacity()); + Tracenf("CEffectInstance::ms_MeshInstancePool %d", CEffectInstance::ms_MeshInstancePool.GetCapacity()); + Tracenf("CEffectInstance::ms_ParticleSystemInstancePool %d", CEffectInstance::ms_ParticleSystemInstancePool.GetCapacity()); + Tracenf("CParticleInstance::ms_ParticleInstancePool %d", CParticleInstance::ms_kPool.GetCapacity()); + Tracenf("CRayParticleInstance::ms_RayParticleInstancePool %d", CRayParticleInstance::ms_kPool.GetCapacity()); + Tracen("---------------------------------------------"); + } + */ + + for (TEffectInstanceMap::iterator itor = m_kEftInstMap.begin(); itor != m_kEftInstMap.end();) + { + CEffectInstance * pEffectInstance = itor->second; + + pEffectInstance->Update(/*fElapsedTime*/); + + if (!pEffectInstance->isAlive()) + { + itor = m_kEftInstMap.erase(itor); + + CEffectInstance::Delete(pEffectInstance); + } + else + { + ++itor; + } + } +} + + +struct CEffectManager_LessEffectInstancePtrRenderOrder +{ + bool operator() (CEffectInstance* pkLeft, CEffectInstance* pkRight) + { + return pkLeft->LessRenderOrder(pkRight); + } +}; + +struct CEffectManager_FEffectInstanceRender +{ + inline void operator () (CEffectInstance * pkEftInst) + { + pkEftInst->Render(); + } +}; + +void CEffectManager::Render() +{ + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SetTexture(1, NULL); + + if (m_isDisableSortRendering) + { + for (TEffectInstanceMap::iterator itor = m_kEftInstMap.begin(); itor != m_kEftInstMap.end();) + { + CEffectInstance * pEffectInstance = itor->second; + pEffectInstance->Render(); + ++itor; + } + } + else + { + static std::vector s_kVct_pkEftInstSort; + s_kVct_pkEftInstSort.clear(); + + TEffectInstanceMap& rkMap_pkEftInstSrc=m_kEftInstMap; + TEffectInstanceMap::iterator i; + for (i=rkMap_pkEftInstSrc.begin(); i!=rkMap_pkEftInstSrc.end(); ++i) + s_kVct_pkEftInstSort.push_back(i->second); + + std::sort(s_kVct_pkEftInstSort.begin(), s_kVct_pkEftInstSort.end(), CEffectManager_LessEffectInstancePtrRenderOrder()); + std::for_each(s_kVct_pkEftInstSort.begin(), s_kVct_pkEftInstSort.end(), CEffectManager_FEffectInstanceRender()); + } +} + +BOOL CEffectManager::RegisterEffect(const char * c_szFileName,bool isExistDelete,bool isNeedCache) +{ + std::string strFileName; + StringPath(c_szFileName, strFileName); + DWORD dwCRC = GetCaseCRC32(strFileName.c_str(), strFileName.length()); + + TEffectDataMap::iterator itor = m_kEftDataMap.find(dwCRC); + if (m_kEftDataMap.end() != itor) + { + if (isExistDelete) + { + CEffectData* pkEftData=itor->second; + CEffectData::Delete(pkEftData); + m_kEftDataMap.erase(itor); + } + else + { + //TraceError("CEffectManager::RegisterEffect - m_kEftDataMap.find [%s] Already Exist", c_szFileName); + return TRUE; + } + } + + CEffectData * pkEftData = CEffectData::New(); + + if (!pkEftData->LoadScript(c_szFileName)) + { + TraceError("CEffectManager::RegisterEffect - LoadScript(%s) Error", c_szFileName); + CEffectData::Delete(pkEftData); + return FALSE; + } + + m_kEftDataMap.insert(TEffectDataMap::value_type(dwCRC, pkEftData)); + + if (isNeedCache) + { + if (m_kEftCacheMap.find(dwCRC)==m_kEftCacheMap.end()) + { + CEffectInstance* pkNewEftInst=CEffectInstance::New(); + pkNewEftInst->SetEffectDataPointer(pkEftData); + m_kEftCacheMap.insert(TEffectInstanceMap::value_type(dwCRC, pkNewEftInst)); + } + } + + return TRUE; +} +// CEffectData ϰ ϰ.. +// CEffectData CRC ְ Ѵ +BOOL CEffectManager::RegisterEffect2(const char * c_szFileName, DWORD* pdwRetCRC, bool isNeedCache) +{ + std::string strFileName; + StringPath(c_szFileName, strFileName); + DWORD dwCRC = GetCaseCRC32(strFileName.c_str(), strFileName.length()); + *pdwRetCRC=dwCRC; + + return RegisterEffect(c_szFileName,false,isNeedCache); +} + +int CEffectManager::CreateEffect(const char * c_szFileName, const D3DXVECTOR3 & c_rv3Position, const D3DXVECTOR3 & c_rv3Rotation) +{ + DWORD dwID = GetCaseCRC32(c_szFileName, strlen(c_szFileName)); + return CreateEffect(dwID, c_rv3Position, c_rv3Rotation); +} + +int CEffectManager::CreateEffect(DWORD dwID, const D3DXVECTOR3 & c_rv3Position, const D3DXVECTOR3 & c_rv3Rotation) +{ + int iInstanceIndex = GetEmptyIndex(); + + CreateEffectInstance(iInstanceIndex, dwID); + SelectEffectInstance(iInstanceIndex); + D3DXMATRIX mat; + D3DXMatrixRotationYawPitchRoll(&mat,D3DXToRadian(c_rv3Rotation.x),D3DXToRadian(c_rv3Rotation.y),D3DXToRadian(c_rv3Rotation.z)); + mat._41 = c_rv3Position.x; + mat._42 = c_rv3Position.y; + mat._43 = c_rv3Position.z; + SetEffectInstanceGlobalMatrix(mat); + + return iInstanceIndex; +} + +void CEffectManager::CreateEffectInstance(DWORD dwInstanceIndex, DWORD dwID) +{ + if (!dwID) + return; + + CEffectData * pEffect; + if (!GetEffectData(dwID, &pEffect)) + { + Tracef("CEffectManager::CreateEffectInstance - NO DATA :%d\n", dwID); + return; + } + + CEffectInstance * pEffectInstance = CEffectInstance::New(); + pEffectInstance->SetEffectDataPointer(pEffect); + + m_kEftInstMap.insert(TEffectInstanceMap::value_type(dwInstanceIndex, pEffectInstance)); +} + +bool CEffectManager::DestroyEffectInstance(DWORD dwInstanceIndex) +{ + TEffectInstanceMap::iterator itor = m_kEftInstMap.find(dwInstanceIndex); + + if (itor == m_kEftInstMap.end()) + return false; + + CEffectInstance * pEffectInstance = itor->second; + + m_kEftInstMap.erase(itor); + + CEffectInstance::Delete(pEffectInstance); + + return true; +} + +void CEffectManager::DeactiveEffectInstance(DWORD dwInstanceIndex) +{ + TEffectInstanceMap::iterator itor = m_kEftInstMap.find(dwInstanceIndex); + + if (itor == m_kEftInstMap.end()) + return; + + CEffectInstance * pEffectInstance = itor->second; + pEffectInstance->SetDeactive(); +} + +void CEffectManager::CreateUnsafeEffectInstance(DWORD dwEffectDataID, CEffectInstance ** ppEffectInstance) +{ + CEffectData * pEffect; + if (!GetEffectData(dwEffectDataID, &pEffect)) + { + Tracef("CEffectManager::CreateEffectInstance - NO DATA :%d\n", dwEffectDataID); + return; + } + + CEffectInstance* pkEftInstNew=CEffectInstance::New(); + pkEftInstNew->SetEffectDataPointer(pEffect); + + *ppEffectInstance = pkEftInstNew; +} + +bool CEffectManager::DestroyUnsafeEffectInstance(CEffectInstance * pEffectInstance) +{ + if (!pEffectInstance) + return false; + + CEffectInstance::Delete(pEffectInstance); + + return true; +} + +BOOL CEffectManager::SelectEffectInstance(DWORD dwInstanceIndex) +{ + TEffectInstanceMap::iterator itor = m_kEftInstMap.find(dwInstanceIndex); + + m_pSelectedEffectInstance = NULL; + + if (m_kEftInstMap.end() == itor) + return FALSE; + + m_pSelectedEffectInstance = itor->second; + + return TRUE; +} + +void CEffectManager::SetEffectTextures(DWORD dwID, std::vector textures) +{ + CEffectData * pEffectData; + if (!GetEffectData(dwID, &pEffectData)) + { + Tracef("CEffectManager::CreateEffectInstance - NO DATA :%d\n", dwID); + return; + } + + for(DWORD i = 0; i < textures.size(); i++) + { + CParticleSystemData * pParticle = pEffectData->GetParticlePointer(i); + pParticle->ChangeTexture(textures.at(i).c_str()); + } +} + +void CEffectManager::SetEffectInstancePosition(const D3DXVECTOR3 & c_rv3Position) +{ + if (!m_pSelectedEffectInstance) + { +// assert(!"Instance to use is not yet set!"); + return; + } + + m_pSelectedEffectInstance->SetPosition(c_rv3Position); +} + +void CEffectManager::SetEffectInstanceRotation(const D3DXVECTOR3 & c_rv3Rotation) +{ + if (!m_pSelectedEffectInstance) + { +// assert(!"Instance to use is not yet set!"); + return; + } + + m_pSelectedEffectInstance->SetRotation(c_rv3Rotation.x,c_rv3Rotation.y,c_rv3Rotation.z); +} + +void CEffectManager::SetEffectInstanceGlobalMatrix(const D3DXMATRIX & c_rmatGlobal) +{ + if (!m_pSelectedEffectInstance) + return; + + m_pSelectedEffectInstance->SetGlobalMatrix(c_rmatGlobal); +} + +void CEffectManager::ShowEffect() +{ + if (!m_pSelectedEffectInstance) + return; + + m_pSelectedEffectInstance->Show(); +} + +void CEffectManager::HideEffect() +{ + if (!m_pSelectedEffectInstance) + return; + + m_pSelectedEffectInstance->Hide(); +} + +bool CEffectManager::GetEffectData(DWORD dwID, CEffectData ** ppEffect) +{ + TEffectDataMap::iterator itor = m_kEftDataMap.find(dwID); + + if (itor == m_kEftDataMap.end()) + return false; + + *ppEffect = itor->second; + + return true; +} + +bool CEffectManager::GetEffectData(DWORD dwID, const CEffectData ** c_ppEffect) +{ + TEffectDataMap::iterator itor = m_kEftDataMap.find(dwID); + + if (itor == m_kEftDataMap.end()) + return false; + + *c_ppEffect = itor->second; + + return true; +} + +DWORD CEffectManager::GetRandomEffect() +{ + int iIndex = random() % m_kEftDataMap.size(); + + TEffectDataMap::iterator itor = m_kEftDataMap.begin(); + for (int i = 0; i < iIndex; ++i, ++itor); + + return itor->first; +} + +int CEffectManager::GetEmptyIndex() +{ + static int iMaxIndex=1; + + if (iMaxIndex>2100000000) + iMaxIndex = 1; + + int iNextIndex = iMaxIndex++; + while(m_kEftInstMap.find(iNextIndex) != m_kEftInstMap.end()) + iNextIndex++; + + return iNextIndex; +} + +void CEffectManager::DeleteAllInstances() +{ + __DestroyEffectInstanceMap(); +} + +void CEffectManager::__DestroyEffectInstanceMap() +{ + for (TEffectInstanceMap::iterator i = m_kEftInstMap.begin(); i != m_kEftInstMap.end(); ++i) + { + CEffectInstance * pkEftInst = i->second; + CEffectInstance::Delete(pkEftInst); + } + + m_kEftInstMap.clear(); +} + +void CEffectManager::__DestroyEffectCacheMap() +{ + for (TEffectInstanceMap::iterator i = m_kEftCacheMap.begin(); i != m_kEftCacheMap.end(); ++i) + { + CEffectInstance * pkEftInst = i->second; + CEffectInstance::Delete(pkEftInst); + } + + m_kEftCacheMap.clear(); +} + +void CEffectManager::__DestroyEffectDataMap() +{ + for (TEffectDataMap::iterator i = m_kEftDataMap.begin(); i != m_kEftDataMap.end(); ++i) + { + CEffectData * pData = i->second; + CEffectData::Delete(pData); + } + + m_kEftDataMap.clear(); +} + +void CEffectManager::Destroy() +{ + __DestroyEffectInstanceMap(); + __DestroyEffectCacheMap(); + __DestroyEffectDataMap(); + + __Initialize(); +} + +void CEffectManager::__Initialize() +{ + m_pSelectedEffectInstance = NULL; + m_isDisableSortRendering = false; +} + +CEffectManager::CEffectManager() +{ + __Initialize(); +} + +CEffectManager::~CEffectManager() +{ + Destroy(); +} + +// just for map effect + diff --git a/source/EffectLib/EffectManager.h b/source/EffectLib/EffectManager.h new file mode 100644 index 0000000..682f1fd --- /dev/null +++ b/source/EffectLib/EffectManager.h @@ -0,0 +1,86 @@ +#pragma once + +#include "EffectInstance.h" + +class CEffectManager : public CScreen, public CSingleton +{ + public: + enum EEffectType + { + EFFECT_TYPE_NONE = 0, + EFFECT_TYPE_PARTICLE = 1, + EFFECT_TYPE_ANIMATION_TEXTURE = 2, + EFFECT_TYPE_MESH = 3, + EFFECT_TYPE_SIMPLE_LIGHT = 4, + + EFFECT_TYPE_MAX_NUM = 4, + }; + + typedef std::map TEffectDataMap; + typedef std::map TEffectInstanceMap; + + public: + CEffectManager(); + virtual ~CEffectManager(); + + void Destroy(); + + void UpdateSound(); + void Update(); + void Render(); + + void GetInfo(std::string* pstInfo); + + bool IsAliveEffect(DWORD dwInstanceIndex); + + // Register + BOOL RegisterEffect(const char * c_szFileName,bool isExistDelete=false,bool isNeedCache=false); + BOOL RegisterEffect2(const char * c_szFileName, DWORD* pdwRetCRC, bool isNeedCache=false); + + void DeleteAllInstances(); + + // Usage + int CreateEffect(DWORD dwID, const D3DXVECTOR3 & c_rv3Position, const D3DXVECTOR3 & c_rv3Rotation); + int CreateEffect(const char * c_szFileName, const D3DXVECTOR3 & c_rv3Position, const D3DXVECTOR3 & c_rv3Rotation); + + void CreateEffectInstance(DWORD dwInstanceIndex, DWORD dwID); + BOOL SelectEffectInstance(DWORD dwInstanceIndex); + bool DestroyEffectInstance(DWORD dwInstanceIndex); + void DeactiveEffectInstance(DWORD dwInstanceIndex); + + void SetEffectTextures(DWORD dwID, std::vector textures); + void SetEffectInstancePosition(const D3DXVECTOR3 & c_rv3Position); + void SetEffectInstanceRotation(const D3DXVECTOR3 & c_rv3Rotation); + void SetEffectInstanceGlobalMatrix(const D3DXMATRIX & c_rmatGlobal); + + void ShowEffect(); + void HideEffect(); + + // Temporary function + DWORD GetRandomEffect(); + int GetEmptyIndex(); + bool GetEffectData(DWORD dwID, CEffectData ** ppEffect); + bool GetEffectData(DWORD dwID, const CEffectData ** c_ppEffect); + + // Area Effect Լ... EffectInstance Pointer ȯѴ. + // EffectManager EffectInstanceMap ̿ ʴ´. + void CreateUnsafeEffectInstance(DWORD dwEffectDataID, CEffectInstance ** ppEffectInstance); + bool DestroyUnsafeEffectInstance(CEffectInstance * pEffectInstance); + + int GetRenderingEffectCount(); + + protected: + void __Initialize(); + + void __DestroyEffectInstanceMap(); + void __DestroyEffectCacheMap(); + void __DestroyEffectDataMap(); + + protected: + bool m_isDisableSortRendering; + TEffectDataMap m_kEftDataMap; + TEffectInstanceMap m_kEftInstMap; + TEffectInstanceMap m_kEftCacheMap; + + CEffectInstance * m_pSelectedEffectInstance; +}; diff --git a/source/EffectLib/EffectMesh.cpp b/source/EffectLib/EffectMesh.cpp new file mode 100644 index 0000000..91cae49 --- /dev/null +++ b/source/EffectLib/EffectMesh.cpp @@ -0,0 +1,699 @@ +#include "StdAfx.h" +#include "../eterlib/StateManager.h" +#include "../eterlib/ResourceManager.h" +#include "../eterpack/EterPackManager.h" +#include "EffectMesh.h" + +CDynamicPool CEffectMesh::SEffectMeshData::ms_kPool; + +CEffectMesh::SEffectMeshData* CEffectMesh::SEffectMeshData::New() +{ + return ms_kPool.Alloc(); +} + +void CEffectMesh::SEffectMeshData::Delete(SEffectMeshData* pkData) +{ + pkData->EffectFrameDataVector.clear(); + pkData->pImageVector.clear(); + + ms_kPool.Free(pkData); +} + +void CEffectMesh::SEffectMeshData::DestroySystem() +{ + ms_kPool.Destroy(); +} + + +DWORD CEffectMesh::GetFrameCount() +{ + return m_iFrameCount; +} + +DWORD CEffectMesh::GetMeshCount() +{ + return m_pEffectMeshDataVector.size(); +} + +CEffectMesh::TEffectMeshData * CEffectMesh::GetMeshDataPointer(DWORD dwMeshIndex) +{ + assert(dwMeshIndex < m_pEffectMeshDataVector.size()); + return m_pEffectMeshDataVector[dwMeshIndex]; +} + +std::vector* CEffectMesh::GetTextureVectorPointer(DWORD dwMeshIndex) +{ + if (dwMeshIndex>=m_pEffectMeshDataVector.size()) + return NULL; + + return &m_pEffectMeshDataVector[dwMeshIndex]->pImageVector; +} + +std::vector & CEffectMesh::GetTextureVectorReference(DWORD dwMeshIndex) +{ + return m_pEffectMeshDataVector[dwMeshIndex]->pImageVector; +} + +CEffectMesh::TType CEffectMesh::Type() +{ + static TType s_type = StringToType("CEffectMesh"); + return s_type; +} + +bool CEffectMesh::OnIsType(TType type) +{ + if (CEffectMesh::Type() == type) + return true; + + return CResource::OnIsType(type); +} + +bool CEffectMesh::OnLoad(int iSize, const void * c_pvBuf) +{ + if (!c_pvBuf) + return false; + + const BYTE * c_pbBuf = static_cast (c_pvBuf); + + char szHeader[10+1]; + memcpy(szHeader, c_pbBuf, 10+1); + c_pbBuf += 10+1; + + if (0 == strcmp("EffectData", szHeader)) + { + if (!__LoadData_Ver001(iSize, c_pbBuf)) + return false; + } + else if (0 == strcmp("MDEData002", szHeader)) + { + if (!__LoadData_Ver002(iSize, c_pbBuf)) + return false; + } + else + { + return false; + } + + m_isData = true; + return true; +} + +BOOL CEffectMesh::__LoadData_Ver002(int iSize, const BYTE * c_pbBuf) +{ + std::vector v3VertexVector; + std::vector iIndexVector; + std::vector v3TextureVertexVector; + std::vector iTextureIndexVector; + + m_iGeomCount = *(int *)c_pbBuf; + c_pbBuf += 4; + m_iFrameCount = *(int *)c_pbBuf; + c_pbBuf += 4; + + m_pEffectMeshDataVector.clear(); + m_pEffectMeshDataVector.resize(m_iGeomCount); + + for (short n = 0; n < m_iGeomCount; ++n) + { + SEffectMeshData * pMeshData = SEffectMeshData::New(); + + memcpy(pMeshData->szObjectName, c_pbBuf, 32); + c_pbBuf += 32; + memcpy(pMeshData->szDiffuseMapFileName, c_pbBuf, 128); + c_pbBuf += 128; + + pMeshData->EffectFrameDataVector.clear(); + pMeshData->EffectFrameDataVector.resize(m_iFrameCount); + + for(int i = 0; i < m_iFrameCount; ++i) + { + TEffectFrameData & rFrameData = pMeshData->EffectFrameDataVector[i]; + + memcpy(&rFrameData.byChangedFrame, c_pbBuf, sizeof(BYTE)); + c_pbBuf += sizeof(BYTE); + + memcpy(&rFrameData.fVisibility, c_pbBuf, sizeof(float)); + c_pbBuf += sizeof(float); + + memcpy(&rFrameData.dwVertexCount, c_pbBuf, sizeof(DWORD)); + c_pbBuf += sizeof(DWORD); + + memcpy(&rFrameData.dwIndexCount, c_pbBuf, sizeof(DWORD)); + c_pbBuf += sizeof(DWORD); + + memcpy(&rFrameData.dwTextureVertexCount, c_pbBuf, sizeof(DWORD)); + c_pbBuf += sizeof(DWORD); + + v3VertexVector.clear(); + v3VertexVector.resize(rFrameData.dwVertexCount); + iIndexVector.clear(); + iIndexVector.resize(rFrameData.dwIndexCount); + v3TextureVertexVector.clear(); + v3TextureVertexVector.resize(rFrameData.dwTextureVertexCount); + iTextureIndexVector.clear(); + iTextureIndexVector.resize(rFrameData.dwIndexCount); + + memcpy(&v3VertexVector[0], c_pbBuf, rFrameData.dwVertexCount*sizeof(D3DXVECTOR3)); + c_pbBuf += rFrameData.dwVertexCount*sizeof(D3DXVECTOR3); + memcpy(&iIndexVector[0], c_pbBuf, rFrameData.dwIndexCount*sizeof(int)); + c_pbBuf += rFrameData.dwIndexCount*sizeof(int); + memcpy(&v3TextureVertexVector[0], c_pbBuf, rFrameData.dwTextureVertexCount*sizeof(D3DXVECTOR2)); + c_pbBuf += rFrameData.dwTextureVertexCount*sizeof(D3DXVECTOR2); + memcpy(&iTextureIndexVector[0], c_pbBuf, rFrameData.dwIndexCount*sizeof(int)); + c_pbBuf += rFrameData.dwIndexCount*sizeof(int); + + /////////////////////////////// + + rFrameData.PDTVertexVector.clear(); + rFrameData.PDTVertexVector.resize(rFrameData.dwIndexCount); + for (DWORD j = 0; j < rFrameData.dwIndexCount; ++j) + { + TPTVertex & rVertex = rFrameData.PDTVertexVector[j]; + + DWORD dwIndex = iIndexVector[j]; + DWORD dwTextureIndex = iTextureIndexVector[j]; + + assert(dwIndex < v3VertexVector.size()); + assert(dwTextureIndex < v3TextureVertexVector.size()); + + rVertex.position = v3VertexVector[dwIndex]; + rVertex.texCoord = v3TextureVertexVector[dwTextureIndex]; + rVertex.texCoord.y *= -1; + } + } + + //////////////////////////////////// + + pMeshData->pImageVector.clear(); + + std::string strExtension; + GetFileExtension(pMeshData->szDiffuseMapFileName, strlen(pMeshData->szDiffuseMapFileName), &strExtension); + stl_lowers(strExtension); + + if (0 == strExtension.compare("ifl")) + { + LPCVOID pMotionData; + CMappedFile File; + + if (CEterPackManager::Instance().Get(File, pMeshData->szDiffuseMapFileName, &pMotionData)) + { + CMemoryTextFileLoader textFileLoader; + std::vector stTokenVector; + + textFileLoader.Bind(File.Size(), pMotionData); + + std::string strPathName; + GetOnlyPathName(pMeshData->szDiffuseMapFileName, strPathName); + + std::string strTextureFileName; + for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i) + { + const std::string & c_rstrFileName = textFileLoader.GetLineString(i); + + if (c_rstrFileName.empty()) + continue; + + strTextureFileName = strPathName; + strTextureFileName += c_rstrFileName; + + CGraphicImage * pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer(strTextureFileName.c_str()); + + pMeshData->pImageVector.push_back(pImage); + } + } + } + else + { + CGraphicImage * pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer(pMeshData->szDiffuseMapFileName); + + pMeshData->pImageVector.push_back(pImage); + } + + //////////////////////////////////// + + m_pEffectMeshDataVector[n] = pMeshData; + } + + return TRUE; +} + +BOOL CEffectMesh::__LoadData_Ver001(int iSize, const BYTE * c_pbBuf) +{ + std::vector v3VertexVector; + std::vector iIndexVector; + std::vector v3TextureVertexVector; + std::vector iTextureIndexVector; + + m_iGeomCount = *(int *)c_pbBuf; + c_pbBuf += 4; + m_iFrameCount = *(int *)c_pbBuf; + c_pbBuf += 4; + + m_pEffectMeshDataVector.clear(); + m_pEffectMeshDataVector.resize(m_iGeomCount); + + for (short n = 0; n < m_iGeomCount; ++n) + { + SEffectMeshData * pMeshData = SEffectMeshData::New(); + + memcpy(pMeshData->szObjectName, c_pbBuf, 32); + c_pbBuf += 32; + memcpy(pMeshData->szDiffuseMapFileName, c_pbBuf, 128); + c_pbBuf += 128; + + // + + DWORD dwVertexCount; + DWORD dwIndexCount; + DWORD dwTextureVertexCount; + + memcpy(&dwVertexCount, c_pbBuf, sizeof(DWORD)); + c_pbBuf += sizeof(DWORD); + + memcpy(&dwIndexCount, c_pbBuf, sizeof(DWORD)); + c_pbBuf += sizeof(DWORD); + + memcpy(&dwTextureVertexCount, c_pbBuf, sizeof(DWORD)); + c_pbBuf += sizeof(DWORD); + + pMeshData->EffectFrameDataVector.clear(); + pMeshData->EffectFrameDataVector.resize(m_iFrameCount); + + for(int i = 0; i < m_iFrameCount; ++i) + { + TEffectFrameData & rFrameData = pMeshData->EffectFrameDataVector[i]; + + rFrameData.dwVertexCount = dwVertexCount; + rFrameData.dwIndexCount = dwIndexCount; + rFrameData.dwTextureVertexCount = dwTextureVertexCount; + + v3VertexVector.clear(); + v3VertexVector.resize(rFrameData.dwVertexCount); + iIndexVector.clear(); + iIndexVector.resize(rFrameData.dwIndexCount); + v3TextureVertexVector.clear(); + v3TextureVertexVector.resize(rFrameData.dwTextureVertexCount); + iTextureIndexVector.clear(); + iTextureIndexVector.resize(rFrameData.dwIndexCount); + + memcpy(&rFrameData.fVisibility, c_pbBuf, sizeof(float)); + c_pbBuf += sizeof(float); + memcpy(&v3VertexVector[0], c_pbBuf, rFrameData.dwVertexCount*sizeof(D3DXVECTOR3)); + c_pbBuf += rFrameData.dwVertexCount*sizeof(D3DXVECTOR3); + memcpy(&iIndexVector[0], c_pbBuf, rFrameData.dwIndexCount*sizeof(int)); + c_pbBuf += rFrameData.dwIndexCount*sizeof(int); + memcpy(&v3TextureVertexVector[0], c_pbBuf, rFrameData.dwTextureVertexCount*sizeof(D3DXVECTOR2)); + c_pbBuf += rFrameData.dwTextureVertexCount*sizeof(D3DXVECTOR2); + memcpy(&iTextureIndexVector[0], c_pbBuf, rFrameData.dwIndexCount*sizeof(int)); + c_pbBuf += rFrameData.dwIndexCount*sizeof(int); + + /////////////////////////////// + + rFrameData.PDTVertexVector.clear(); + rFrameData.PDTVertexVector.resize(rFrameData.dwIndexCount); + for (DWORD j = 0; j < rFrameData.dwIndexCount; ++j) + { + TPTVertex & rVertex = rFrameData.PDTVertexVector[j]; + + DWORD dwIndex = iIndexVector[j]; + DWORD dwTextureIndex = iTextureIndexVector[j]; + + assert(dwIndex < v3VertexVector.size()); + assert(dwTextureIndex < v3TextureVertexVector.size()); + + rVertex.position = v3VertexVector[dwIndex]; + rVertex.texCoord = v3TextureVertexVector[dwTextureIndex]; + rVertex.texCoord.y *= -1; + } + } + + //////////////////////////////////// + + pMeshData->pImageVector.clear(); + + std::string strExtension; + GetFileExtension(pMeshData->szDiffuseMapFileName, strlen(pMeshData->szDiffuseMapFileName), &strExtension); + stl_lowers(strExtension); + + if (0 == strExtension.compare("ifl")) + { + LPCVOID pMotionData; + CMappedFile File; + + if (CEterPackManager::Instance().Get(File, pMeshData->szDiffuseMapFileName, &pMotionData)) + { + CMemoryTextFileLoader textFileLoader; + std::vector stTokenVector; + + textFileLoader.Bind(File.Size(), pMotionData); + + std::string strPathName; + GetOnlyPathName(pMeshData->szDiffuseMapFileName, strPathName); + + std::string strTextureFileName; + for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i) + { + const std::string & c_rstrFileName = textFileLoader.GetLineString(i); + + if (c_rstrFileName.empty()) + continue; + + strTextureFileName = strPathName; + strTextureFileName += c_rstrFileName; + + CGraphicImage * pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer(strTextureFileName.c_str()); + + pMeshData->pImageVector.push_back(pImage); + } + } + } + else + { + CGraphicImage * pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer(pMeshData->szDiffuseMapFileName); + + pMeshData->pImageVector.push_back(pImage); + } + + //////////////////////////////////// + + m_pEffectMeshDataVector[n] = pMeshData; + } + + return TRUE; +} + +BOOL CEffectMesh::GetMeshElementPointer(DWORD dwMeshIndex, TEffectMeshData ** ppMeshData) +{ + if (dwMeshIndex >= m_pEffectMeshDataVector.size()) + return FALSE; + + *ppMeshData = m_pEffectMeshDataVector[dwMeshIndex]; + + return TRUE; +} + +void CEffectMesh::OnClear() +{ + if (!m_isData) + return; + + for (DWORD i = 0; i < m_pEffectMeshDataVector.size(); ++i) + { + m_pEffectMeshDataVector[i]->pImageVector.clear(); + m_pEffectMeshDataVector[i]->EffectFrameDataVector.clear(); + + SEffectMeshData::Delete(m_pEffectMeshDataVector[i]); + } + m_pEffectMeshDataVector.clear(); + + m_isData = false; +} + +bool CEffectMesh::OnIsEmpty() const +{ + return !m_isData; +} + +CEffectMesh::CEffectMesh(const char * c_szFileName) : CResource(c_szFileName) +{ + m_iGeomCount = 0; + m_iFrameCount = 0; + m_isData = false; +} + +CEffectMesh::~CEffectMesh() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////// + +CDynamicPool CEffectMeshScript::ms_kPool; + +void CEffectMeshScript::DestroySystem() +{ + ms_kPool.Destroy(); +} + +CEffectMeshScript* CEffectMeshScript::New() +{ + return ms_kPool.Alloc(); +} + +void CEffectMeshScript::Delete(CEffectMeshScript* pkData) +{ + pkData->Clear(); + ms_kPool.Free(pkData); +} + +void CEffectMeshScript::ReserveMeshData(DWORD dwMeshCount) +{ + if (m_MeshDataVector.size() == dwMeshCount) + return; + + m_MeshDataVector.clear(); + m_MeshDataVector.resize(dwMeshCount); + + for (DWORD i = 0; i < m_MeshDataVector.size(); ++i) + { + TMeshData & rMeshData = m_MeshDataVector[i]; + + rMeshData.byBillboardType = MESH_BILLBOARD_TYPE_NONE; + rMeshData.bBlendingEnable = TRUE; + rMeshData.byBlendingSrcType = D3DBLEND_SRCCOLOR; + rMeshData.byBlendingDestType = D3DBLEND_ONE; + rMeshData.bTextureAlphaEnable = FALSE; + + rMeshData.byColorOperationType = D3DTOP_MODULATE; + rMeshData.ColorFactor = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); + + rMeshData.bTextureAnimationLoopEnable = true; + rMeshData.fTextureAnimationFrameDelay = 0.02f; + rMeshData.dwTextureAnimationStartFrame = 0; + } +} + +const char * CEffectMeshScript::GetMeshFileName() +{ + return m_strMeshFileName.c_str(); +} + +bool CEffectMeshScript::CheckMeshIndex(DWORD dwMeshIndex) +{ + if (dwMeshIndex >= m_MeshDataVector.size()) + return false; + + return true; +} + +bool CEffectMeshScript::GetMeshDataPointer(DWORD dwMeshIndex, TMeshData ** ppMeshData) +{ + if (!CheckMeshIndex(dwMeshIndex)) + return false; + + *ppMeshData = &m_MeshDataVector[dwMeshIndex]; + + return true; +} + +int CEffectMeshScript::GetMeshDataCount() +{ + return m_MeshDataVector.size(); +} + +int CEffectMeshScript::GetBillboardType(DWORD dwMeshIndex) +{ + if (!CheckMeshIndex(dwMeshIndex)) + return 0; + + return m_MeshDataVector[dwMeshIndex].byBillboardType; +} +BOOL CEffectMeshScript::isBlendingEnable(DWORD dwMeshIndex) +{ + if (!CheckMeshIndex(dwMeshIndex)) + return FALSE; + + return m_MeshDataVector[dwMeshIndex].bBlendingEnable; +} +BYTE CEffectMeshScript::GetBlendingSrcType(DWORD dwMeshIndex) +{ + if (!CheckMeshIndex(dwMeshIndex)) + return false; + + return m_MeshDataVector[dwMeshIndex].byBlendingSrcType; +} +BYTE CEffectMeshScript::GetBlendingDestType(DWORD dwMeshIndex) +{ + if (!CheckMeshIndex(dwMeshIndex)) + return false; + + return m_MeshDataVector[dwMeshIndex].byBlendingDestType; +} +BOOL CEffectMeshScript::isTextureAlphaEnable(DWORD dwMeshIndex) +{ + if (!CheckMeshIndex(dwMeshIndex)) + return false; + + return m_MeshDataVector[dwMeshIndex].bTextureAlphaEnable; +} + +BOOL CEffectMeshScript::GetColorOperationType(DWORD dwMeshIndex, BYTE * pbyType) +{ + if (!CheckMeshIndex(dwMeshIndex)) + return FALSE; + + *pbyType = m_MeshDataVector[dwMeshIndex].byColorOperationType; + + return TRUE; +} +BOOL CEffectMeshScript::GetColorFactor(DWORD dwMeshIndex, D3DXCOLOR * pColor) +{ + if (!CheckMeshIndex(dwMeshIndex)) + return FALSE; + + *pColor = m_MeshDataVector[dwMeshIndex].ColorFactor; + + return TRUE; +} + +BOOL CEffectMeshScript::GetTimeTableAlphaPointer(DWORD dwMeshIndex, TTimeEventTableFloat ** pTimeEventAlpha) +{ + if (!CheckMeshIndex(dwMeshIndex)) + return FALSE; + + *pTimeEventAlpha = &m_MeshDataVector[dwMeshIndex].TimeEventAlpha; + + return TRUE; +} + + +BOOL CEffectMeshScript::isMeshAnimationLoop() +{ + return m_isMeshAnimationLoop; +} +int CEffectMeshScript::GetMeshAnimationLoopCount() +{ + return m_iMeshAnimationLoopCount; +} +float CEffectMeshScript::GetMeshAnimationFrameDelay() +{ + return m_fMeshAnimationFrameDelay; +} + +BOOL CEffectMeshScript::isTextureAnimationLoop(DWORD dwMeshIndex) +{ + if (!CheckMeshIndex(dwMeshIndex)) + return 0.0f; + + return m_MeshDataVector[dwMeshIndex].bTextureAnimationLoopEnable; +} +float CEffectMeshScript::GetTextureAnimationFrameDelay(DWORD dwMeshIndex) +{ + if (!CheckMeshIndex(dwMeshIndex)) + return 0.0f; + + return m_MeshDataVector[dwMeshIndex].fTextureAnimationFrameDelay; +} + +DWORD CEffectMeshScript::GetTextureAnimationStartFrame(DWORD dwMeshIndex) +{ + if (!CheckMeshIndex(dwMeshIndex)) + return 0; + + return m_MeshDataVector[dwMeshIndex].dwTextureAnimationStartFrame; +} + +BOOL CEffectMeshScript::OnLoadScript(CTextFileLoader & rTextFileLoader) +{ + if (rTextFileLoader.GetTokenString("meshfilename", &m_strMeshFileName)) + { + if (!IsGlobalFileName(m_strMeshFileName.c_str())) + { + m_strMeshFileName = GetOnlyPathName(rTextFileLoader.GetFileName()) + m_strMeshFileName; + } + } + else + { + return FALSE; + } + + if (!rTextFileLoader.GetTokenInteger("meshanimationloopenable", &m_isMeshAnimationLoop)) + return FALSE; + if (!rTextFileLoader.GetTokenInteger("meshanimationloopcount", &m_iMeshAnimationLoopCount)) + { + m_iMeshAnimationLoopCount = 0; + } + if (!rTextFileLoader.GetTokenFloat("meshanimationframedelay", &m_fMeshAnimationFrameDelay)) + return FALSE; + + DWORD dwMeshElementCount; + if (!rTextFileLoader.GetTokenDoubleWord("meshelementcount", &dwMeshElementCount)) + return FALSE; + + m_MeshDataVector.clear(); + m_MeshDataVector.resize(dwMeshElementCount); + for (DWORD i = 0; i < m_MeshDataVector.size(); ++i) + { + CTextFileLoader::CGotoChild GotoChild(&rTextFileLoader, i); + + TMeshData & rMeshData = m_MeshDataVector[i]; + + if (!rTextFileLoader.GetTokenByte("billboardtype", &rMeshData.byBillboardType)) + return FALSE; + if (!rTextFileLoader.GetTokenBoolean("blendingenable", &rMeshData.bBlendingEnable)) + return FALSE; + if (!rTextFileLoader.GetTokenByte("blendingsrctype", &rMeshData.byBlendingSrcType)) + return FALSE; + if (!rTextFileLoader.GetTokenByte("blendingdesttype", &rMeshData.byBlendingDestType)) + return FALSE; + + if (!rTextFileLoader.GetTokenBoolean("textureanimationloopenable", &rMeshData.bTextureAnimationLoopEnable)) + return FALSE; + if (!rTextFileLoader.GetTokenFloat("textureanimationframedelay", &rMeshData.fTextureAnimationFrameDelay)) + return FALSE; + if (!rTextFileLoader.GetTokenDoubleWord("textureanimationstartframe", &rMeshData.dwTextureAnimationStartFrame)) + { + rMeshData.dwTextureAnimationStartFrame = 0; + } + + if (!rTextFileLoader.GetTokenByte("coloroperationtype", &rMeshData.byColorOperationType)) + { + rMeshData.byColorOperationType = D3DTOP_MODULATE; + } + if (!rTextFileLoader.GetTokenColor("colorfactor", &rMeshData.ColorFactor)) + { + rMeshData.ColorFactor = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); + } + + if (!GetTokenTimeEventFloat(rTextFileLoader, "timeeventalpha", &rMeshData.TimeEventAlpha)) + { + rMeshData.TimeEventAlpha.clear(); + } + } + + return TRUE; +} + +bool CEffectMeshScript::OnIsData() +{ + if (0 == m_strMeshFileName.length()) + return false; + + return true; +} + +void CEffectMeshScript::OnClear() +{ + m_isMeshAnimationLoop = false; + m_iMeshAnimationLoopCount = 0; + m_fMeshAnimationFrameDelay = 0.02f; + + m_MeshDataVector.clear(); + m_strMeshFileName = ""; +} + +CEffectMeshScript::CEffectMeshScript() +{ +} +CEffectMeshScript::~CEffectMeshScript() +{ +} diff --git a/source/EffectLib/EffectMesh.h b/source/EffectLib/EffectMesh.h new file mode 100644 index 0000000..b0219af --- /dev/null +++ b/source/EffectLib/EffectMesh.h @@ -0,0 +1,157 @@ +#pragma once + +#include + +#include "../eterlib/GrpScreen.h" +#include "../eterlib/Resource.h" +#include "../eterlib/GrpImageInstance.h" +#include "../eterLib/TextFileLoader.h" + +#include "Type.h" +#include "EffectElementBase.h" + +class CEffectMesh : public CResource +{ + public: + typedef struct SEffectFrameData + { + BYTE byChangedFrame; + float fVisibility; + DWORD dwVertexCount; + DWORD dwTextureVertexCount; + DWORD dwIndexCount; + std::vector PDTVertexVector; + } TEffectFrameData; + + typedef struct SEffectMeshData + { + char szObjectName[32]; + char szDiffuseMapFileName[128]; + + std::vector EffectFrameDataVector; + std::vector pImageVector; + + static SEffectMeshData* New(); + static void Delete(SEffectMeshData* pkData); + + static void DestroySystem(); + + static CDynamicPool ms_kPool; + } TEffectMeshData; + + // About Resource Code + public: + typedef CRef TRef; + + public: + static TType Type(); + + public: + CEffectMesh(const char * c_szFileName); + virtual ~CEffectMesh(); + + DWORD GetFrameCount(); + DWORD GetMeshCount(); + TEffectMeshData * GetMeshDataPointer(DWORD dwMeshIndex); + + std::vector* GetTextureVectorPointer(DWORD dwMeshIndex); + std::vector& GetTextureVectorReference(DWORD dwMeshIndex); + + // Exceptional function for tool + BOOL GetMeshElementPointer(DWORD dwMeshIndex, TEffectMeshData ** ppMeshData); + + protected: + bool OnLoad(int iSize, const void * c_pvBuf); + + void OnClear(); + bool OnIsEmpty() const; + bool OnIsType(TType type); + + BOOL __LoadData_Ver001(int iSize, const BYTE * c_pbBuf); + BOOL __LoadData_Ver002(int iSize, const BYTE * c_pbBuf); + + protected: + int m_iGeomCount; + int m_iFrameCount; + std::vector m_pEffectMeshDataVector; + + bool m_isData; +}; + +class CEffectMeshScript : public CEffectElementBase +{ + public: + typedef struct SMeshData + { + BYTE byBillboardType; + + BOOL bBlendingEnable; + BYTE byBlendingSrcType; + BYTE byBlendingDestType; + BOOL bTextureAlphaEnable; + + BYTE byColorOperationType; + D3DXCOLOR ColorFactor; + + BOOL bTextureAnimationLoopEnable; + float fTextureAnimationFrameDelay; + + DWORD dwTextureAnimationStartFrame; + + TTimeEventTableFloat TimeEventAlpha; + + SMeshData() + { + TimeEventAlpha.clear(); + } + } TMeshData; + typedef std::vector TMeshDataVector; + + public: + CEffectMeshScript(); + virtual ~CEffectMeshScript(); + + const char * GetMeshFileName(); + + void ReserveMeshData(DWORD dwMeshCount); + bool CheckMeshIndex(DWORD dwMeshIndex); + bool GetMeshDataPointer(DWORD dwMeshIndex, TMeshData ** ppMeshData); + int GetMeshDataCount(); + + int GetBillboardType(DWORD dwMeshIndex); + BOOL isBlendingEnable(DWORD dwMeshIndex); + BYTE GetBlendingSrcType(DWORD dwMeshIndex); + BYTE GetBlendingDestType(DWORD dwMeshIndex); + BOOL isTextureAlphaEnable(DWORD dwMeshIndex); + BOOL GetColorOperationType(DWORD dwMeshIndex, BYTE * pbyType); + BOOL GetColorFactor(DWORD dwMeshIndex, D3DXCOLOR * pColor); + BOOL GetTimeTableAlphaPointer(DWORD dwMeshIndex, TTimeEventTableFloat ** pTimeEventAlpha); + + BOOL isMeshAnimationLoop(); + BOOL GetMeshAnimationLoopCount(); + float GetMeshAnimationFrameDelay(); + BOOL isTextureAnimationLoop(DWORD dwMeshIndex); + float GetTextureAnimationFrameDelay(DWORD dwMeshIndex); + DWORD GetTextureAnimationStartFrame(DWORD dwMeshIndex); + + protected: + void OnClear(); + bool OnIsData(); + BOOL OnLoadScript(CTextFileLoader & rTextFileLoader); + + protected: + BOOL m_isMeshAnimationLoop; + int m_iMeshAnimationLoopCount; + float m_fMeshAnimationFrameDelay; + TMeshDataVector m_MeshDataVector; + + std::string m_strMeshFileName; + + public: + static void DestroySystem(); + + static CEffectMeshScript* New(); + static void Delete(CEffectMeshScript* pkData); + + static CDynamicPool ms_kPool; +}; \ No newline at end of file diff --git a/source/EffectLib/EffectMeshInstance.cpp b/source/EffectLib/EffectMeshInstance.cpp new file mode 100644 index 0000000..a749055 --- /dev/null +++ b/source/EffectLib/EffectMeshInstance.cpp @@ -0,0 +1,271 @@ +#include "StdAfx.h" +#include "../eterLib/StateManager.h" +#include "../eterLib/ResourceManager.h" +#include "EffectMeshInstance.h" +#include "../eterlib/GrpMath.h" + +CDynamicPool CEffectMeshInstance::ms_kPool; + +void CEffectMeshInstance::DestroySystem() +{ + ms_kPool.Destroy(); +} + +CEffectMeshInstance* CEffectMeshInstance::New() +{ + return ms_kPool.Alloc(); +} + +void CEffectMeshInstance::Delete(CEffectMeshInstance* pkMeshInstance) +{ + pkMeshInstance->Destroy(); + ms_kPool.Free(pkMeshInstance); +} + +BOOL CEffectMeshInstance::isActive() +{ + if (!CEffectElementBaseInstance::isActive()) + return FALSE; + + if (!m_MeshFrameController.isActive()) + return FALSE; + + for (DWORD j = 0; j < m_TextureInstanceVector.size(); ++j) + { + int iCurrentFrame = m_MeshFrameController.GetCurrentFrame(); + if (m_TextureInstanceVector[j].TextureFrameController.isActive(iCurrentFrame)) + return TRUE; + } + + return FALSE; +} + +bool CEffectMeshInstance::OnUpdate(float fElapsedTime) +{ + if (!isActive()) + return false; + + if (m_MeshFrameController.isActive()) + m_MeshFrameController.Update(fElapsedTime); + + for (DWORD j = 0; j < m_TextureInstanceVector.size(); ++j) + { + int iCurrentFrame = m_MeshFrameController.GetCurrentFrame(); + if (m_TextureInstanceVector[j].TextureFrameController.isActive(iCurrentFrame)) + m_TextureInstanceVector[j].TextureFrameController.Update(fElapsedTime); + } + + return true; +} + +void CEffectMeshInstance::OnRender() +{ + if (!isActive()) + return; + + CEffectMesh * pEffectMesh = m_roMesh.GetPointer(); + + for (DWORD i = 0; i < pEffectMesh->GetMeshCount(); ++i) + { + assert(i < m_TextureInstanceVector.size()); + + CFrameController & rTextureFrameController = m_TextureInstanceVector[i].TextureFrameController; + if (!rTextureFrameController.isActive(m_MeshFrameController.GetCurrentFrame())) + continue; + + int iBillboardType = m_pMeshScript->GetBillboardType(i); + + D3DXMATRIX m_matWorld; + D3DXMatrixIdentity(&m_matWorld); + + switch(iBillboardType) + { + case MESH_BILLBOARD_TYPE_ALL: + { + D3DXMATRIX matTemp; + D3DXMatrixRotationX(&matTemp, 90.0f); + D3DXMatrixInverse(&m_matWorld, NULL, &CScreen::GetViewMatrix()); + + m_matWorld = matTemp * m_matWorld; + } + break; + + case MESH_BILLBOARD_TYPE_Y: + { + D3DXMATRIX matTemp; + D3DXMatrixIdentity(&matTemp); + + D3DXMatrixInverse(&matTemp, NULL, &CScreen::GetViewMatrix()); + m_matWorld._11 = matTemp._11; + m_matWorld._12 = matTemp._12; + m_matWorld._21 = matTemp._21; + m_matWorld._22 = matTemp._22; + } + break; + + case MESH_BILLBOARD_TYPE_MOVE: + { + D3DXVECTOR3 Position; + m_pMeshScript->GetPosition(m_fLocalTime, Position); + D3DXVECTOR3 LastPosition; + m_pMeshScript->GetPosition(m_fLocalTime-CTimer::Instance().GetElapsedSecond(), LastPosition); + Position -= LastPosition; + if (D3DXVec3LengthSq(&Position)>0.001f) + { + D3DXVec3Normalize(&Position,&Position); + D3DXQUATERNION q = SafeRotationNormalizedArc(D3DXVECTOR3(0.0f,-1.0f,0.0f),Position); + D3DXMatrixRotationQuaternion(&m_matWorld,&q); + } + } + break; + } + + if (!m_pMeshScript->isBlendingEnable(i)) + { + STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + else + { + int iBlendingSrcType = m_pMeshScript->GetBlendingSrcType(i); + int iBlendingDestType = m_pMeshScript->GetBlendingDestType(i); + STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, iBlendingSrcType); + STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, iBlendingDestType); + } + + D3DXVECTOR3 Position; + m_pMeshScript->GetPosition(m_fLocalTime, Position); + m_matWorld._41 = Position.x; + m_matWorld._42 = Position.y; + m_matWorld._43 = Position.z; + m_matWorld = m_matWorld * *mc_pmatLocal; + STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matWorld); + + BYTE byType; + D3DXCOLOR Color(1.0f, 1.0f, 1.0f, 1.0f); + if (m_pMeshScript->GetColorOperationType(i, &byType)) + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, byType); + m_pMeshScript->GetColorFactor(i, &Color); + + TTimeEventTableFloat * TableAlpha; + + float fAlpha = 1.0f; + if (m_pMeshScript->GetTimeTableAlphaPointer(i, &TableAlpha) && !TableAlpha->empty()) + GetTimeEventBlendValue(m_fLocalTime,*TableAlpha, &fAlpha); + + // Render // + CEffectMesh::TEffectMeshData * pMeshData = pEffectMesh->GetMeshDataPointer(i); + + assert(m_MeshFrameController.GetCurrentFrame() < pMeshData->EffectFrameDataVector.size()); + CEffectMesh::TEffectFrameData & rFrameData = pMeshData->EffectFrameDataVector[m_MeshFrameController.GetCurrentFrame()]; + + DWORD dwcurTextureFrame = rTextureFrameController.GetCurrentFrame(); + if (dwcurTextureFrame < m_TextureInstanceVector[i].TextureInstanceVector.size()) + { + CGraphicImageInstance * pImageInstance = m_TextureInstanceVector[i].TextureInstanceVector[dwcurTextureFrame]; + STATEMANAGER.SetTexture(0, pImageInstance->GetTexturePointer()->GetD3DTexture()); + } + + Color.a = fAlpha * rFrameData.fVisibility; + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, DWORD(Color)); + STATEMANAGER.SetVertexShader(D3DFVF_XYZ | D3DFVF_TEX1); + STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLELIST, + rFrameData.dwIndexCount/3, + &rFrameData.PDTVertexVector[0], + sizeof(TPTVertex)); + // Render // + } +} + +void CEffectMeshInstance::OnSetDataPointer(CEffectElementBase * pElement) +{ + CEffectMeshScript * pMesh = (CEffectMeshScript *)pElement; + m_pMeshScript = pMesh; + + const char * c_szMeshFileName = pMesh->GetMeshFileName(); + + m_pEffectMesh = (CEffectMesh *) CResourceManager::Instance().GetResourcePointer(c_szMeshFileName); + + if (!m_pEffectMesh) + return; + + m_roMesh.SetPointer(m_pEffectMesh); + + m_MeshFrameController.Clear(); + m_MeshFrameController.SetMaxFrame(m_roMesh.GetPointer()->GetFrameCount()); + m_MeshFrameController.SetFrameTime(pMesh->GetMeshAnimationFrameDelay()); + m_MeshFrameController.SetLoopFlag(pMesh->isMeshAnimationLoop()); + m_MeshFrameController.SetLoopCount(pMesh->GetMeshAnimationLoopCount()); + m_MeshFrameController.SetStartFrame(0); + + m_TextureInstanceVector.clear(); + m_TextureInstanceVector.resize(m_pEffectMesh->GetMeshCount()); + for (DWORD j = 0; j < m_TextureInstanceVector.size(); ++j) + { + CEffectMeshScript::TMeshData * pMeshData; + if (!m_pMeshScript->GetMeshDataPointer(j, &pMeshData)) + continue; + + CEffectMesh* pkEftMesh=m_roMesh.GetPointer(); + + if (!pkEftMesh) + continue; + + std::vector* pTextureVector = pkEftMesh->GetTextureVectorPointer(j); + if (!pTextureVector) + continue; + + std::vector& rTextureVector = *pTextureVector; + + CFrameController & rFrameController = m_TextureInstanceVector[j].TextureFrameController; + rFrameController.Clear(); + rFrameController.SetMaxFrame(rTextureVector.size()); + rFrameController.SetFrameTime(pMeshData->fTextureAnimationFrameDelay); + rFrameController.SetLoopFlag(pMeshData->bTextureAnimationLoopEnable); + rFrameController.SetStartFrame(pMeshData->dwTextureAnimationStartFrame); + + std::vector & rImageInstanceVector = m_TextureInstanceVector[j].TextureInstanceVector; + rImageInstanceVector.clear(); + rImageInstanceVector.reserve(rTextureVector.size()); + for (std::vector::iterator itor = rTextureVector.begin(); itor != rTextureVector.end(); ++itor) + { + CGraphicImage * pImage = *itor; + CGraphicImageInstance * pImageInstance = CGraphicImageInstance::ms_kPool.Alloc(); + pImageInstance->SetImagePointer(pImage); + rImageInstanceVector.push_back(pImageInstance); + } + } +} + +void CEffectMeshInstance_DeleteImageInstance(CGraphicImageInstance * pkInstance) +{ + CGraphicImageInstance::ms_kPool.Free(pkInstance); +} + +void CEffectMeshInstance_DeleteTextureInstance(CEffectMeshInstance::TTextureInstance & rkInstance) +{ + std::vector & rVector = rkInstance.TextureInstanceVector; + for_each(rVector.begin(), rVector.end(), CEffectMeshInstance_DeleteImageInstance); + rVector.clear(); +} + +void CEffectMeshInstance::OnInitialize() +{ +} + +void CEffectMeshInstance::OnDestroy() +{ + for_each(m_TextureInstanceVector.begin(), m_TextureInstanceVector.end(), CEffectMeshInstance_DeleteTextureInstance); + m_TextureInstanceVector.clear(); + m_roMesh.SetPointer(NULL); +} + +CEffectMeshInstance::CEffectMeshInstance() +{ + Initialize(); +} + +CEffectMeshInstance::~CEffectMeshInstance() +{ + Destroy(); +} \ No newline at end of file diff --git a/source/EffectLib/EffectMeshInstance.h b/source/EffectLib/EffectMeshInstance.h new file mode 100644 index 0000000..eaf17d1 --- /dev/null +++ b/source/EffectLib/EffectMeshInstance.h @@ -0,0 +1,50 @@ +#pragma once + +#include "../eterlib/GrpScreen.h" +#include "../eterlib/GrpImageInstance.h" +#include "EffectElementBaseInstance.h" +#include "FrameController.h" +#include "EffectMesh.h" + +class CEffectMeshInstance : public CEffectElementBaseInstance +{ + public: + // NOTE : Mesh ؽ Ÿ νϽ̴. + typedef struct STextureInstance + { + CFrameController TextureFrameController; + std::vector TextureInstanceVector; + } TTextureInstance; + + public: + CEffectMeshInstance(); + virtual ~CEffectMeshInstance(); + + public: + static void DestroySystem(); + + static CEffectMeshInstance* New(); + static void Delete(CEffectMeshInstance* pkMeshInstance); + + static CDynamicPool ms_kPool; + + protected: + void OnSetDataPointer(CEffectElementBase * pElement); + + void OnInitialize(); + void OnDestroy(); + + bool OnUpdate(float fElapsedTime); + void OnRender(); + + BOOL isActive(); + + protected: + CEffectMeshScript * m_pMeshScript; + CEffectMesh * m_pEffectMesh; + + CFrameController m_MeshFrameController; + std::vector m_TextureInstanceVector; + + CEffectMesh::TRef m_roMesh; +}; \ No newline at end of file diff --git a/source/EffectLib/EffectUpdateDecorator.cpp b/source/EffectLib/EffectUpdateDecorator.cpp new file mode 100644 index 0000000..26922cf --- /dev/null +++ b/source/EffectLib/EffectUpdateDecorator.cpp @@ -0,0 +1,39 @@ +#include "stdafx.h" +#include "EffectUpdateDecorator.h" +#include "ParticleInstance.h" +namespace NEffectUpdateDecorator +{ + + CBaseDecorator* CAirResistanceDecorator::__Clone(CParticleInstance* pfi, CParticleInstance* pi) + { + pi->m_fAirResistance = pfi->m_fAirResistance; + return new CAirResistanceDecorator; + } + + void CAirResistanceDecorator::__Excute(const CDecoratorData & d) + { + d.pInstance->m_v3Velocity *= 1.0f-d.pInstance->m_fAirResistance; + } + CBaseDecorator* CGravityDecorator::__Clone(CParticleInstance* pfi, CParticleInstance* pi) + { + pi->m_fGravity = pfi->m_fGravity; + return new CGravityDecorator; + } + + void CGravityDecorator::__Excute(const CDecoratorData& d) + { + d.pInstance->m_v3Velocity.z -= d.pInstance->m_fGravity * d.fElapsedTime; + } + + CBaseDecorator* CRotationDecorator::__Clone(CParticleInstance* pfi, CParticleInstance* pi) + { + pi->m_fRotationSpeed = pfi->m_fRotationSpeed; + return new CRotationDecorator; + } + + void CRotationDecorator::__Excute(const CDecoratorData& d) + { + d.pInstance->m_fRotation += d.pInstance->m_fRotationSpeed * d.fElapsedTime; + } + +} \ No newline at end of file diff --git a/source/EffectLib/EffectUpdateDecorator.h b/source/EffectLib/EffectUpdateDecorator.h new file mode 100644 index 0000000..16169c4 --- /dev/null +++ b/source/EffectLib/EffectUpdateDecorator.h @@ -0,0 +1,282 @@ +#pragma once + +#include "Type.h" +#include "../eterbase/Random.h" +#include "../eterlib/Pool.h" +class CParticleInstance; + +namespace NEffectUpdateDecorator +{ + class CDecoratorData + { + public: + float fTime; + float fElapsedTime; + CParticleInstance * pInstance; + CDecoratorData(float fTime, float fElapsedTime, CParticleInstance * pInstance) + : fTime(fTime), fElapsedTime(fElapsedTime), pInstance(pInstance) + {} + }; + class CBaseDecorator + { + friend class CParticleSystemData; + public: + CBaseDecorator() :m_NextDecorator(0), m_PrevDecorator(0) {} + virtual ~CBaseDecorator(){} + + void Excute(const CDecoratorData & d) + { + CBaseDecorator* pd = this; + while(pd) + { + CBaseDecorator* pNextDecorator = pd->m_NextDecorator; + pd->__Excute(d); + pd = pNextDecorator; + } + } + CBaseDecorator * AddChainFront(CBaseDecorator * pd) + { + pd->m_NextDecorator = this; + m_PrevDecorator = pd; + return pd; + } + void DeleteThis() + { + //return; + if (m_NextDecorator) + m_NextDecorator->DeleteThis(); + delete this; + } + CBaseDecorator * Clone(CParticleInstance* pFirstInstance, CParticleInstance* pInstance) + { + CBaseDecorator * pNewDecorator = __Clone(pFirstInstance, pInstance); + CBaseDecorator * pSrc = this; + CBaseDecorator * pDest = pNewDecorator; + while (pSrc->m_NextDecorator) + { + pDest->m_NextDecorator = pSrc->m_NextDecorator->__Clone(pFirstInstance, pInstance); + pDest->m_NextDecorator->m_PrevDecorator = pDest; + + pSrc = pSrc->m_NextDecorator; + pDest = pDest->m_NextDecorator; + } + return pNewDecorator; + } + protected: + virtual void __Excute(const CDecoratorData & d) = 0; + virtual CBaseDecorator* __Clone(CParticleInstance* pFirstInstance, CParticleInstance* pInstance) = 0; + void RemoveMe() + { + m_PrevDecorator->m_NextDecorator = m_NextDecorator; + m_NextDecorator->m_PrevDecorator=m_PrevDecorator; + delete this; + } + CBaseDecorator * m_NextDecorator; + CBaseDecorator * m_PrevDecorator; + }; + + class CHeaderDecorator : public CBaseDecorator, public CPooledObject + { + public: + CHeaderDecorator() {} + virtual ~CHeaderDecorator() {} + protected: + virtual void __Excute(const CDecoratorData&) {} + virtual CBaseDecorator* __Clone(CParticleInstance*, CParticleInstance*) { return new CHeaderDecorator; } + }; + + class CNullDecorator : public CBaseDecorator, public CPooledObject + { + public: + CNullDecorator(){} + virtual ~CNullDecorator(){} + + protected: + virtual void __Excute(const CDecoratorData & d) {} + virtual CBaseDecorator* __Clone(CParticleInstance*, CParticleInstance* ) { return new CNullDecorator; } + }; + + template class CTimeEventDecorator : public CBaseDecorator, public CPooledObject > + { + public: + typedef CTimeEvent TTimeEventType; + typedef std::vector TTimeEventContainerType; + CTimeEventDecorator(const TTimeEventContainerType& TimeEventContainer, T * pValue = 0) + : it_start(TimeEventContainer.begin()), + it_cur(TimeEventContainer.begin()), + it_next(TimeEventContainer.begin()), + it_end(TimeEventContainer.end()), + pData(pValue) + { + if (it_start == it_end) + *pValue = T(); + else + ++it_next; + } + virtual ~CTimeEventDecorator() {} + + void SetData( T * pValue ) { pData = pValue; } + + protected: + //CTimeEventDecorator(CTimeEventDecorator& ted, CParticleInstance * pFirstInstance, CParticleInstance * pInstance); + CTimeEventDecorator(CTimeEventDecorator& ted, CParticleInstance* pFirstInstance, CParticleInstance* pInstance) + : it_start(ted.it_start), + it_end(ted.it_end), + it_cur(ted.it_cur), + it_next(ted.it_next), + pData((T*)( (unsigned char*)ted.pData - (DWORD)pFirstInstance + (DWORD)pInstance)) + { + if (it_start == it_end) + *pData = T(); + } + virtual CBaseDecorator* __Clone(CParticleInstance* pFirstInstance, CParticleInstance* pInstance) { return new CTimeEventDecorator(*this, pFirstInstance, pInstance); } + virtual void __Excute(const CDecoratorData & d) + { + if (it_start==it_end) + { + RemoveMe(); + } + else if (it_cur->m_fTime>d.fTime) + { + *pData = it_cur->m_Value; + } + else + { + while (it_next!=it_end && it_next->m_fTime<=d.fTime) + ++it_cur, ++it_next; + if (it_next == it_end) + { + // setting value + *pData = it_cur->m_Value; + + RemoveMe(); + } + else + { + float length = it_next->m_fTime - it_cur->m_fTime; + //*pData = it_cur->m_Value + (it_next->m_Value - it_cur->m_Value)*(d.fTime-it_cur->m_fTime)/length; + *pData = it_cur->m_Value*(1-(d.fTime-it_cur->m_fTime)/length) ; + *pData += it_next->m_Value * ((d.fTime-it_cur->m_fTime)/length); + } + } + } + + typename TTimeEventContainerType::const_iterator it_start; + typename TTimeEventContainerType::const_iterator it_end; + typename TTimeEventContainerType::const_iterator it_cur; + typename TTimeEventContainerType::const_iterator it_next; + T * pData; + }; + + typedef CTimeEventDecorator CScaleValueDecorator; + typedef CTimeEventDecorator CColorValueDecorator; + typedef CTimeEventDecorator CColorAllDecorator; + typedef CTimeEventDecorator CAirResistanceValueDecorator; + typedef CTimeEventDecorator CGravityValueDecorator; + typedef CTimeEventDecorator CRotationSpeedValueDecorator; + + class CTextureAnimationCWDecorator : public CBaseDecorator, public CPooledObject + { + public: + CTextureAnimationCWDecorator(float fFrameTime, DWORD n, BYTE * pIdx) :n(n),pIdx(pIdx),fFrameTime(fFrameTime),fLastFrameTime(fFrameTime){} + virtual ~CTextureAnimationCWDecorator(){} + protected: + virtual CBaseDecorator* __Clone(CParticleInstance* pfi, CParticleInstance* pi) { return new CTextureAnimationCWDecorator(fFrameTime,n,(BYTE*)((unsigned char*)pi+((BYTE*)pIdx-(BYTE*)pfi))); } + virtual void __Excute(const CDecoratorData & d) + { + fLastFrameTime -= d.fElapsedTime; + while (fLastFrameTime<0.0f) + { + fLastFrameTime += fFrameTime; + if (++(*pIdx) >= n) + *pIdx = 0; + } + } + DWORD n; + float fLastFrameTime; + float fFrameTime; + BYTE* pIdx; + + }; + class CTextureAnimationCCWDecorator : public CBaseDecorator, public CPooledObject + { + public: + CTextureAnimationCCWDecorator(float fFrameTime, BYTE n, BYTE * pIdx) :n(n),pIdx(pIdx),fFrameTime(fFrameTime),fLastFrameTime(fFrameTime){} + virtual ~CTextureAnimationCCWDecorator(){} + protected: + virtual CBaseDecorator* __Clone(CParticleInstance* pfi, CParticleInstance* pi) { return new CTextureAnimationCCWDecorator(fFrameTime,n,(BYTE*)((unsigned char*)pi+((BYTE*)pIdx-(BYTE*)pfi))); } + virtual void __Excute(const CDecoratorData & d) + { + fLastFrameTime -= d.fElapsedTime; + while (fLastFrameTime<0.0f) + { + fLastFrameTime += fFrameTime; + + if (--(*pIdx) >= n && n != 0) // Because variable is unsigned.. + *pIdx = BYTE(n - 1); + } + } + BYTE n; + float fLastFrameTime; + float fFrameTime; + BYTE* pIdx; + + }; + class CTextureAnimationRandomDecorator : public CBaseDecorator, public CPooledObject + { + public: + CTextureAnimationRandomDecorator(float fFrameTime, BYTE n, BYTE * pIdx) :n(n),pIdx(pIdx),fFrameTime(fFrameTime),fLastFrameTime(fFrameTime){} + virtual ~CTextureAnimationRandomDecorator(){} + protected: + virtual CBaseDecorator* __Clone(CParticleInstance* pfi, CParticleInstance* pi) { return new CTextureAnimationRandomDecorator(fFrameTime,n,(BYTE*)((unsigned char*)pi+((BYTE*)pIdx-(BYTE*)pfi))); } + virtual void __Excute(const CDecoratorData & d) + { + fLastFrameTime -= d.fElapsedTime; + if (fLastFrameTime<0.0f && n!=0) + { + *pIdx = (BYTE)random_range(0,n-1); + } + while (fLastFrameTime<0.0f) + fLastFrameTime += fFrameTime; + } + BYTE n; + float fLastFrameTime; + float fFrameTime; + BYTE* pIdx; + + }; + + class CAirResistanceDecorator : public CBaseDecorator, public CPooledObject + { + public: + CAirResistanceDecorator(){} + virtual ~CAirResistanceDecorator(){} + + protected: + virtual void __Excute(const CDecoratorData & d); + virtual CBaseDecorator* __Clone(CParticleInstance* pfi, CParticleInstance* pi); + }; + + class CGravityDecorator : public CBaseDecorator, public CPooledObject + { + public: + CGravityDecorator(){} + virtual ~CGravityDecorator(){} + protected: + virtual void __Excute(const CDecoratorData& d); + virtual CBaseDecorator* __Clone(CParticleInstance* pfi, CParticleInstance* pi); + }; + + class CRotationDecorator : public CBaseDecorator, public CPooledObject + { + public: + CRotationDecorator(){} + virtual ~CRotationDecorator() + { + } + protected: + virtual void __Excute(const CDecoratorData& d); + virtual CBaseDecorator* __Clone(CParticleInstance* pfi, CParticleInstance* pi) ; + }; + +} \ No newline at end of file diff --git a/source/EffectLib/EmitterProperty.cpp b/source/EffectLib/EmitterProperty.cpp new file mode 100644 index 0000000..91b7fbb --- /dev/null +++ b/source/EffectLib/EmitterProperty.cpp @@ -0,0 +1,102 @@ +#include "StdAfx.h" +#include "EmitterProperty.h" + +BYTE CEmitterProperty::GetEmitterShape() +{ + return m_byEmitterShape; +} +BYTE CEmitterProperty::GetEmitterAdvancedType() +{ + return m_byEmitterAdvancedType; +} +BOOL CEmitterProperty::isEmitFromEdge() +{ + return m_bEmitFromEdgeFlag; +} + +void CEmitterProperty::GetEmittingSize(float fTime, float * pfValue) +{ + //GetTimeEventBlendValue(fTime, m_TimeEventEmittingSize, pfValue); + GetTimeEventBlendValue(fTime, m_TimeEventEmittingSize, pfValue); +} +void CEmitterProperty::GetEmittingAngularVelocity(float fTime, float * pfValue) +{ + //GetTimeEventBlendValue(fTime, m_TimeEventEmittingAngularVelocity, pfValue); + GetTimeEventBlendValue(fTime, m_TimeEventEmittingAngularVelocity, pfValue); +} +void CEmitterProperty::GetEmittingDirectionX(float fTime, float * pfValue) +{ + //GetTimeEventBlendValue(fTime, m_TimeEventEmittingDirectionX, pfValue); + GetTimeEventBlendValue(fTime, m_TimeEventEmittingDirectionX, pfValue); +} +void CEmitterProperty::GetEmittingDirectionY(float fTime, float * pfValue) +{ + //GetTimeEventBlendValue(fTime, m_TimeEventEmittingDirectionY, pfValue); + GetTimeEventBlendValue(fTime, m_TimeEventEmittingDirectionY, pfValue); +} +void CEmitterProperty::GetEmittingDirectionZ(float fTime, float * pfValue) +{ + //GetTimeEventBlendValue(fTime, m_TimeEventEmittingDirectionZ, pfValue); + GetTimeEventBlendValue(fTime, m_TimeEventEmittingDirectionZ, pfValue); +} +void CEmitterProperty::GetEmittingVelocity(float fTime, float * pfValue) +{ + //GetTimeEventBlendValue(fTime, m_TimeEventEmittingVelocity, pfValue); + GetTimeEventBlendValue(fTime, m_TimeEventEmittingVelocity, pfValue); +} +void CEmitterProperty::GetEmissionCountPerSecond(float fTime, float * pfValue) +{ + //GetTimeEventBlendValue(fTime, m_TimeEventEmissionCountPerSecond, pfValue); + GetTimeEventBlendValue(fTime, m_TimeEventEmissionCountPerSecond, pfValue); +} +void CEmitterProperty::GetParticleLifeTime(float fTime, float * pfValue) +{ + //GetTimeEventBlendValue(fTime, m_TimeEventLifeTime, pfValue); + GetTimeEventBlendValue(fTime, m_TimeEventLifeTime, pfValue); +} +void CEmitterProperty::GetParticleSizeX(float fTime, float * pfValue) +{ + //GetTimeEventBlendValue(fTime, m_TimeEventSizeX, pfValue); + GetTimeEventBlendValue(fTime, m_TimeEventSizeX, pfValue); +} +void CEmitterProperty::GetParticleSizeY(float fTime, float * pfValue) +{ + //GetTimeEventBlendValue(fTime, m_TimeEventSizeY, pfValue); + GetTimeEventBlendValue(fTime, m_TimeEventSizeY, pfValue); +} + +void CEmitterProperty::Clear() +{ + m_dwMaxEmissionCount = 0; + + m_fCycleLength = 0.0f; + m_bCycleLoopFlag = FALSE; + m_iLoopCount = 0; + + m_byEmitterShape = EMITTER_SHAPE_POINT; + m_byEmitterAdvancedType = EMITTER_ADVANCED_TYPE_FREE; + m_bEmitFromEdgeFlag = FALSE; + m_v3EmittingSize = D3DXVECTOR3(0.0f, 0.0f, 0.0f); + m_fEmittingRadius = 0.0f; + + m_v3EmittingDirection = D3DXVECTOR3(0.0f, 0.0f, 0.0f); + + m_TimeEventEmittingSize.clear(); + m_TimeEventEmittingDirectionX.clear(); + m_TimeEventEmittingDirectionY.clear(); + m_TimeEventEmittingDirectionZ.clear(); + m_TimeEventEmittingVelocity.clear(); + m_TimeEventEmissionCountPerSecond.clear(); + m_TimeEventLifeTime.clear(); + m_TimeEventSizeX.clear(); + m_TimeEventSizeY.clear(); + m_TimeEventEmittingAngularVelocity.clear(); +} + +CEmitterProperty::CEmitterProperty() +{ + Clear(); +} +CEmitterProperty::~CEmitterProperty() +{ +} diff --git a/source/EffectLib/EmitterProperty.h b/source/EffectLib/EmitterProperty.h new file mode 100644 index 0000000..b475dbc --- /dev/null +++ b/source/EffectLib/EmitterProperty.h @@ -0,0 +1,95 @@ +#pragma once + +#include "Type.h" + +class CEmitterProperty +{ + friend class CParticleSystemData; + friend class CParticleSystemInstance; + public: + enum + { + EMITTER_SHAPE_POINT, + EMITTER_SHAPE_ELLIPSE, + EMITTER_SHAPE_SQUARE, + EMITTER_SHAPE_SPHERE, + }; + + enum + { + EMITTER_ADVANCED_TYPE_FREE, + EMITTER_ADVANCED_TYPE_OUTER, + EMITTER_ADVANCED_TYPE_INNER, + }; + + public: + CEmitterProperty(); + virtual ~CEmitterProperty(); + + void Clear(); + + DWORD GetMaxEmissionCount() + { + return m_dwMaxEmissionCount; + } + + float GetCycleLength() + { + return m_fCycleLength; + } + + BOOL isCycleLoop() + { + return m_bCycleLoopFlag; + } + + int GetLoopCount() + { + return m_iLoopCount; + } + + + BYTE GetEmitterShape(); + BYTE GetEmitterAdvancedType(); + BOOL isEmitFromEdge(); + + void GetEmittingSize(float fTime, float * pfValue); + void GetEmittingAngularVelocity(float fTime, float * pfValue); + + void GetEmittingDirectionX(float fTime, float * pfValue); + void GetEmittingDirectionY(float fTime, float * pfValue); + void GetEmittingDirectionZ(float fTime, float * pfValue); + void GetEmittingVelocity(float fTime, float * pfValue); + void GetEmissionCountPerSecond(float fTime, float * pfValue); + void GetParticleLifeTime(float fTime, float * pfValue); + void GetParticleSizeX(float fTime, float * pfValue); + void GetParticleSizeY(float fTime, float * pfValue); + + ///// + + DWORD m_dwMaxEmissionCount; + + float m_fCycleLength; + BOOL m_bCycleLoopFlag; + int m_iLoopCount; + + BYTE m_byEmitterShape; + BYTE m_byEmitterAdvancedType; + BOOL m_bEmitFromEdgeFlag; + D3DXVECTOR3 m_v3EmittingSize; + float m_fEmittingRadius; + + D3DXVECTOR3 m_v3EmittingDirection; + + //TTimeEventTableFloat m_TimeEventEmittingRadius; + TTimeEventTableFloat m_TimeEventEmittingSize; + TTimeEventTableFloat m_TimeEventEmittingAngularVelocity; + TTimeEventTableFloat m_TimeEventEmittingDirectionX; + TTimeEventTableFloat m_TimeEventEmittingDirectionY; + TTimeEventTableFloat m_TimeEventEmittingDirectionZ; + TTimeEventTableFloat m_TimeEventEmittingVelocity; + TTimeEventTableFloat m_TimeEventEmissionCountPerSecond; + TTimeEventTableFloat m_TimeEventLifeTime; + TTimeEventTableFloat m_TimeEventSizeX; + TTimeEventTableFloat m_TimeEventSizeY; +}; diff --git a/source/EffectLib/FrameController.cpp b/source/EffectLib/FrameController.cpp new file mode 100644 index 0000000..c5b1cbc --- /dev/null +++ b/source/EffectLib/FrameController.cpp @@ -0,0 +1,106 @@ +#include "StdAfx.h" +#include "FrameController.h" + +void CFrameController::Update(float fElapsedTime) +{ + m_fLastFrameTime -= fElapsedTime; + + for (int i = 0; i < 20; ++i) + { + if (m_fLastFrameTime < 0.0f) + { + m_fLastFrameTime += m_fFrameTime; + ++m_dwcurFrame; + + if (m_dwcurFrame >= m_dwMaxFrame) + { + if (m_isLoop && --m_iLoopCount!=0) + { + if (m_iLoopCount<0) + m_iLoopCount = 0; + m_dwcurFrame = 0; + } + else + { + m_iLoopCount = 1; + m_dwcurFrame = 0; + m_isActive = FALSE; + return; + } + } + } + else + { + break; + } + } +} + +void CFrameController::SetCurrentFrame(DWORD dwFrame) +{ + m_dwcurFrame = dwFrame; +} + +BYTE CFrameController::GetCurrentFrame() +{ + return m_dwcurFrame; +} + +void CFrameController::SetMaxFrame(DWORD dwMaxFrame) +{ + m_dwMaxFrame = dwMaxFrame; +} +void CFrameController::SetFrameTime(float fTime) +{ + m_fFrameTime = fTime; + m_fLastFrameTime = fTime; +} +void CFrameController::SetStartFrame(DWORD dwStartFrame) +{ + m_dwStartFrame = dwStartFrame; +} + +void CFrameController::SetLoopFlag(BOOL bFlag) +{ + m_isLoop = bFlag; +} + +void CFrameController::SetLoopCount(int iLoopCount) +{ + m_iLoopCount = iLoopCount; +} + +void CFrameController::SetActive(BOOL bFlag) +{ + m_isActive = bFlag; +} + +BOOL CFrameController::isActive(DWORD dwMainFrame) +{ + if (dwMainFrame < m_dwStartFrame) + return FALSE; + + return m_isActive; +} + +void CFrameController::Clear() +{ + m_isActive = TRUE; + m_dwcurFrame = 0; + m_fLastFrameTime = 0.0f; +} + +CFrameController::CFrameController() +{ + m_isActive = TRUE; + m_dwcurFrame = 0; + m_fLastFrameTime = 0.0f; + + m_isLoop = FALSE; + m_dwMaxFrame = 0; + m_fFrameTime = 0.0f; + m_dwStartFrame = 0; +} +CFrameController::~CFrameController() +{ +} diff --git a/source/EffectLib/FrameController.h b/source/EffectLib/FrameController.h new file mode 100644 index 0000000..835a29c --- /dev/null +++ b/source/EffectLib/FrameController.h @@ -0,0 +1,38 @@ +#pragma once + +class CFrameController +{ + public: + CFrameController(); + virtual ~CFrameController(); + + void Clear(); + + void Update(float fElapsedTime); + + void SetCurrentFrame(DWORD dwFrame); + BYTE GetCurrentFrame(); + + void SetMaxFrame(DWORD dwMaxFrame); + void SetFrameTime(float fTime); + void SetStartFrame(DWORD dwStartFrame); + void SetLoopFlag(BOOL bFlag); + void SetLoopCount(int iLoopCount); + + void SetActive(BOOL bFlag); + BOOL isActive(DWORD dwMainFrame = 0); + + protected: + // Dynamic + BOOL m_isActive; + DWORD m_dwcurFrame; + float m_fLastFrameTime; + + int m_iLoopCount; + + // Static + BOOL m_isLoop; + DWORD m_dwMaxFrame; + float m_fFrameTime; + DWORD m_dwStartFrame; +}; diff --git a/source/EffectLib/ParticleInstance.cpp b/source/EffectLib/ParticleInstance.cpp new file mode 100644 index 0000000..748936a --- /dev/null +++ b/source/EffectLib/ParticleInstance.cpp @@ -0,0 +1,516 @@ +#include "StdAfx.h" +#include "ParticleInstance.h" +#include "ParticleProperty.h" + +#include "../eterBase/Random.h" +#include "../eterLib/Camera.h" +#include "../eterLib/StateManager.h" + +CDynamicPool CParticleInstance::ms_kPool; + +using namespace NEffectUpdateDecorator; + +void CParticleInstance::DestroySystem() +{ + ms_kPool.Destroy(); +} + +CParticleInstance* CParticleInstance::New() +{ + return ms_kPool.Alloc(); +} + +void CParticleInstance::DeleteThis() +{ + Destroy(); + + ms_kPool.Free(this); +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//CDynamicPool CRayParticleInstance::ms_kPool; + +/*void CRayParticleInstance::DestroySystem() +{ + ms_kPool.Destroy(); +} + +CRayParticleInstance* CRayParticleInstance::New() +{ + return ms_kPool.Alloc(); +} + +void CRayParticleInstance::DeleteThis() +{ +#ifdef RAY_TO_AFTERIMAGE + m_PositionList.clear(); +#else + m_bStart = false; +#endif + ms_kPool.Free(this); +} +*/ +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +float CParticleInstance::GetRadiusApproximation() +{ + return m_v2HalfSize.y*m_v2Scale.y + m_v2HalfSize.x*m_v2Scale.x; +} +/* +D3DXVECTOR3 CBaseParticleInstance::GetCenterApproximation() +{ + return D3DXVECTOR3( + m_v3Position.x + mc_pmatLocal._41, + m_v3Position.y + mc_pmatLocal._42, + m_v3Position.z + mc_pmatLocal._43 + ); +}*/ + + +BOOL CParticleInstance::Update(float fElapsedTime, float fAngle) +{ + m_fLastLifeTime -= fElapsedTime; + if (m_fLastLifeTime < 0.0f) + return FALSE; + + float fLifePercentage = (m_fLifeTime - m_fLastLifeTime) / m_fLifeTime; + + m_pDecorator->Excute(CDecoratorData(fLifePercentage,fElapsedTime,this)); + + m_v3LastPosition = m_v3Position; + m_v3Position += m_v3Velocity * fElapsedTime; + + if (fAngle) + { + if (m_pParticleProperty->m_bAttachFlag) + { + float fCos, fSin; + fAngle = D3DXToRadian(fAngle); + fCos = cos(fAngle); + fSin = sin(fAngle); + + float rx = m_v3Position.x - m_v3StartPosition.x; + float ry = m_v3Position.y - m_v3StartPosition.y; + + m_v3Position.x = fCos * rx + fSin * ry + m_v3StartPosition.x; + m_v3Position.y = - fSin * rx + fCos * ry + m_v3StartPosition.y; + } + else + { + D3DXQUATERNION q,qc; + D3DXQuaternionRotationAxis(&q,&m_pParticleProperty->m_v3ZAxis,D3DXToRadian(fAngle)); + D3DXQuaternionConjugate(&qc,&q); + + D3DXQUATERNION qr( + m_v3Position.x-m_v3StartPosition.x, + m_v3Position.y-m_v3StartPosition.y, + m_v3Position.z-m_v3StartPosition.z, + 0.0f); + D3DXQuaternionMultiply(&qr,&q,&qr); + D3DXQuaternionMultiply(&qr,&qr,&qc); + + m_v3Position.x = qr.x; + m_v3Position.y = qr.y; + m_v3Position.z = qr.z; + + m_v3Position += m_v3StartPosition; + } + } + + return TRUE; +} + +void CParticleInstance::Transform(const D3DXMATRIX * c_matLocal) +{ +#ifdef WORLD_EDITOR + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, m_Color); +#else + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, m_dcColor); +#endif + + ///// + + D3DXVECTOR3 v3Up; + D3DXVECTOR3 v3Cross; + + if (!m_pParticleProperty->m_bStretchFlag) + { + CCamera * pCurrentCamera = CCameraManager::Instance().GetCurrentCamera(); + const D3DXVECTOR3 & c_rv3Up = pCurrentCamera->GetUp(); + const D3DXVECTOR3 & c_rv3Cross = pCurrentCamera->GetCross(); + + D3DXVECTOR3 v3Rotation; + + switch(m_pParticleProperty->m_byBillboardType) { + case BILLBOARD_TYPE_LIE: + { + float fCos = cosf(D3DXToRadian(m_fRotation)), fSin = sinf(D3DXToRadian(m_fRotation)); + v3Up.x = fCos; + v3Up.y = -fSin; + v3Up.z = 0; + v3Cross.x = fSin; + v3Cross.y = fCos; + v3Cross.z = 0; + } + break; + case BILLBOARD_TYPE_2FACE: + case BILLBOARD_TYPE_3FACE: + // using setting with y, and local rotation at render + case BILLBOARD_TYPE_Y: + { + v3Up = D3DXVECTOR3(0.0f,0.0f,1.0f); + //v3Up = D3DXVECTOR3(cosf(D3DXToRadian(m_fRotation)),0.0f,-sinf(D3DXToRadian(m_fRotation))); + const D3DXVECTOR3 & c_rv3View = pCurrentCamera->GetView(); + if (v3Up.x * c_rv3View.y - v3Up.y * c_rv3View.x<0) + v3Up*=-1; + auto d3dd = D3DXVECTOR3(c_rv3View.x, c_rv3View.y, 0); + D3DXVec3Cross(&v3Cross, &v3Up, &d3dd); + D3DXVec3Normalize(&v3Cross, &v3Cross); + + if (m_fRotation) + { + float fCos = -sinf(D3DXToRadian(m_fRotation)); // + 90 + float fSin = cosf(D3DXToRadian(m_fRotation)); + + D3DXVECTOR3 v3Temp = v3Up * fCos - v3Cross * fSin; + v3Cross = v3Cross * fCos + v3Up * fSin; + v3Up = v3Temp; + } + + //D3DXVECTOR3 v3Rotation; + //D3DXVec3Cross(&v3Rotation, &v3Up, &v3Cross); + + } + break; + case BILLBOARD_TYPE_ALL: + default: + { + // NOTE : Rotation Routine. Camera Up Vector Cross Vector ü View Vector + // Rotation Ų. + // FIXME : ݵ ȭ ! + if (m_fRotation==0.0f) + { + v3Up = -c_rv3Cross; + v3Cross = c_rv3Up; + } + else + { + const D3DXVECTOR3 & c_rv3View = pCurrentCamera->GetView(); + D3DXQUATERNION q,qc; + D3DXQuaternionRotationAxis(&q, &c_rv3View, D3DXToRadian(m_fRotation)); + D3DXQuaternionConjugate(&qc, &q); + + { + D3DXQUATERNION qr(-c_rv3Cross.x, -c_rv3Cross.y, -c_rv3Cross.z, 0); + D3DXQuaternionMultiply(&qr,&qc,&qr); + D3DXQuaternionMultiply(&qr,&qr,&q); + v3Up.x = qr.x; + v3Up.y = qr.y; + v3Up.z = qr.z; + } + { + D3DXQUATERNION qr(c_rv3Up.x, c_rv3Up.y, c_rv3Up.z, 0); + D3DXQuaternionMultiply(&qr,&qc,&qr); + D3DXQuaternionMultiply(&qr,&qr,&q); + v3Cross.x = qr.x; + v3Cross.y = qr.y; + v3Cross.z = qr.z; + } + + } + //D3DXMATRIX matRotation; + + //D3DXMatrixRotationAxis(&matRotation, &c_rv3View, D3DXToRadian(m_fRotation)); + + //D3DXVec3TransformCoord(&v3Up, &(-c_rv3Cross), &matRotation); + //D3DXVec3TransformCoord(&v3Cross, &c_rv3Up, &matRotation); + } + break; + } + + } + else + { + v3Up = m_v3Position - m_v3LastPosition; + + if (c_matLocal) + { + //if (!m_pParticleProperty->m_bAttachFlag) + D3DXVec3TransformNormal(&v3Up, &v3Up, c_matLocal); + } + + // NOTE: ӵ ̿ ִ : log(velocity)ŭ þ. + float length = D3DXVec3Length(&v3Up); + if (length == 0.0f) + { + v3Up = D3DXVECTOR3(0.0f,0.0f,1.0f); + } + else + v3Up *=(1+log(1+length))/length; + + CCamera * pCurrentCamera = CCameraManager::Instance().GetCurrentCamera(); + const D3DXVECTOR3 & c_rv3View = pCurrentCamera->GetView(); + D3DXVec3Cross(&v3Cross, &v3Up, &c_rv3View); + D3DXVec3Normalize(&v3Cross, &v3Cross); + + } + + v3Cross = -(m_v2HalfSize.x*m_v2Scale.x) * v3Cross; + v3Up = (m_v2HalfSize.y*m_v2Scale.y) * v3Up; + + if (c_matLocal && m_pParticleProperty->m_bAttachFlag) + { + D3DXVECTOR3 v3Position; + D3DXVec3TransformCoord(&v3Position, &m_v3Position, c_matLocal); + m_ParticleMesh[0].position = v3Position - v3Up + v3Cross; + m_ParticleMesh[1].position = v3Position - v3Up - v3Cross; + m_ParticleMesh[2].position = v3Position + v3Up + v3Cross; + m_ParticleMesh[3].position = v3Position + v3Up - v3Cross; + } + else + { + m_ParticleMesh[0].position = m_v3Position - v3Up + v3Cross; + m_ParticleMesh[1].position = m_v3Position - v3Up - v3Cross; + m_ParticleMesh[2].position = m_v3Position + v3Up + v3Cross; + m_ParticleMesh[3].position = m_v3Position + v3Up - v3Cross; + } +} + + +void CParticleInstance::Transform(const D3DXMATRIX * c_matLocal, const float c_fZRotation) +{ +#ifdef WORLD_EDITOR + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, m_Color); +#else + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, (DWORD)m_dcColor); +#endif + + ///// + + D3DXVECTOR3 v3Up; + D3DXVECTOR3 v3Cross; + + if (!m_pParticleProperty->m_bStretchFlag) + { + CCamera * pCurrentCamera = CCameraManager::Instance().GetCurrentCamera(); + const D3DXVECTOR3 & c_rv3Up = pCurrentCamera->GetUp(); + const D3DXVECTOR3 & c_rv3Cross = pCurrentCamera->GetCross(); + + D3DXVECTOR3 v3Rotation; + + switch(m_pParticleProperty->m_byBillboardType) { + case BILLBOARD_TYPE_LIE: + { + float fCos = cosf(D3DXToRadian(m_fRotation)), fSin = sinf(D3DXToRadian(m_fRotation)); + v3Up.x = fCos; + v3Up.y = -fSin; + v3Up.z = 0; + + v3Cross.x = fSin; + v3Cross.y = fCos; + v3Cross.z = 0; + } + break; + case BILLBOARD_TYPE_2FACE: + case BILLBOARD_TYPE_3FACE: + // using setting with y, and local rotation at render + case BILLBOARD_TYPE_Y: + { + v3Up = D3DXVECTOR3(0.0f,0.0f,1.0f); + //v3Up = D3DXVECTOR3(cosf(D3DXToRadian(m_fRotation)),0.0f,-sinf(D3DXToRadian(m_fRotation))); + const D3DXVECTOR3 & c_rv3View = pCurrentCamera->GetView(); + if (v3Up.x * c_rv3View.y - v3Up.y * c_rv3View.x<0) + v3Up*=-1; + auto d3dd = D3DXVECTOR3(c_rv3View.x, c_rv3View.y, 0); + D3DXVec3Cross(&v3Cross, &v3Up, &d3dd); + D3DXVec3Normalize(&v3Cross, &v3Cross); + + if (m_fRotation) + { + float fCos = -sinf(D3DXToRadian(m_fRotation)); // + 90 + float fSin = cosf(D3DXToRadian(m_fRotation)); + + D3DXVECTOR3 v3Temp = v3Up * fCos - v3Cross * fSin; + v3Cross = v3Cross * fCos + v3Up * fSin; + v3Up = v3Temp; + } + + //D3DXVECTOR3 v3Rotation; + //D3DXVec3Cross(&v3Rotation, &v3Up, &v3Cross); + + } + break; + case BILLBOARD_TYPE_ALL: + default: + { + // NOTE : Rotation Routine. Camera Up Vector Cross Vector ü View Vector + // Rotation Ų. + // FIXME : ݵ ȭ ! + if (m_fRotation==0.0f) + { + v3Up = -c_rv3Cross; + v3Cross = c_rv3Up; + } + else + { + const D3DXVECTOR3 & c_rv3View = pCurrentCamera->GetView(); + D3DXMATRIX matRotation; + + D3DXMatrixRotationAxis(&matRotation, &c_rv3View, D3DXToRadian(m_fRotation)); + auto d3dd = (-c_rv3Cross); + D3DXVec3TransformCoord(&v3Up, &d3dd, &matRotation); + D3DXVec3TransformCoord(&v3Cross, &c_rv3Up, &matRotation); + } + } + break; + } + } + else + { + v3Up = m_v3Position - m_v3LastPosition; + + if (c_matLocal) + { + //if (!m_pParticleProperty->m_bAttachFlag) + D3DXVec3TransformNormal(&v3Up, &v3Up, c_matLocal); + } + + // NOTE: ӵ ̿ ִ : log(velocity)ŭ þ. + float length = D3DXVec3Length(&v3Up); + if (length == 0.0f) + { + v3Up = D3DXVECTOR3(0.0f,0.0f,1.0f); + } + else + v3Up *=(1+log(1+length))/length; + //D3DXVec3Normalize(&v3Up,&v3Up); + //v3Up *= 1+log(1+length); + + CCamera * pCurrentCamera = CCameraManager::Instance().GetCurrentCamera(); + const D3DXVECTOR3 & c_rv3View = pCurrentCamera->GetView(); + D3DXVec3Cross(&v3Cross, &v3Up, &c_rv3View); + D3DXVec3Normalize(&v3Cross, &v3Cross); + + } + + if (c_fZRotation) + { + float x, y; + float fCos = cosf(c_fZRotation); + float fSin = sinf(c_fZRotation); + + x = v3Up.x; + y = v3Up.y; + v3Up.x = x * fCos - y * fSin; + v3Up.y = y * fCos + x * fSin; + + x = v3Cross.x; + y = v3Cross.y; + v3Cross.x = x * fCos - y * fSin; + v3Cross.y = y * fCos + x * fSin; + } + + v3Cross = -(m_v2HalfSize.x*m_v2Scale.x) * v3Cross; + v3Up = (m_v2HalfSize.y*m_v2Scale.y) * v3Up; + + if (c_matLocal && m_pParticleProperty->m_bAttachFlag) + { + D3DXVECTOR3 v3Position; + D3DXVec3TransformCoord(&v3Position, &m_v3Position, c_matLocal); + m_ParticleMesh[0].position = v3Position - v3Up + v3Cross; + m_ParticleMesh[1].position = v3Position - v3Up - v3Cross; + m_ParticleMesh[2].position = v3Position + v3Up + v3Cross; + m_ParticleMesh[3].position = v3Position + v3Up - v3Cross; + } + else + { + m_ParticleMesh[0].position = m_v3Position - v3Up + v3Cross; + m_ParticleMesh[1].position = m_v3Position - v3Up - v3Cross; + m_ParticleMesh[2].position = m_v3Position + v3Up + v3Cross; + m_ParticleMesh[3].position = m_v3Position + v3Up - v3Cross; + } +} + +void CParticleInstance::Destroy() +{ + if (m_pDecorator) + m_pDecorator->DeleteThis(); + + __Initialize(); + +} + +void CParticleInstance::__Initialize() +{ + //* + m_pDecorator=NULL; + + m_v3Position = D3DXVECTOR3(0.0f, 0.0f, 0.0f); + m_v3LastPosition = m_v3Position; + m_v3Velocity = D3DXVECTOR3(0.0f, 0.0f, 0.0f); + + m_v2Scale = D3DXVECTOR2(1.0f, 1.0f); +#ifdef WORLD_EDITOR + m_Color = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); +#else + m_dcColor.m_dwColor = 0xffffffff; +#endif + + m_byFrameIndex = 0; + m_ParticleMesh[0].texCoord = D3DXVECTOR2(0.0f, 1.0f); + m_ParticleMesh[1].texCoord = D3DXVECTOR2(0.0f, 0.0f); + m_ParticleMesh[2].texCoord = D3DXVECTOR2(1.0f, 1.0f); + m_ParticleMesh[3].texCoord = D3DXVECTOR2(1.0f, 0.0f); +} + +CParticleInstance::CParticleInstance() +{ + __Initialize(); +} + +CParticleInstance::~CParticleInstance() +{ + Destroy(); +} + +/*CRayParticleInstance::CRayParticleInstance() +{ +#ifdef RAY_TO_AFTERIMAGE + int i; + for(i=0;i ms_kPool; + +}; diff --git a/source/EffectLib/ParticleProperty.cpp b/source/EffectLib/ParticleProperty.cpp new file mode 100644 index 0000000..d2db34f --- /dev/null +++ b/source/EffectLib/ParticleProperty.cpp @@ -0,0 +1,121 @@ +#include "StdAfx.h" +#include "ParticleProperty.h" +#include "../eterlib/ResourceManager.h" + +void CParticleProperty::InsertTexture(const char * c_szFileName) +{ + CGraphicImage * pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer(c_szFileName); + + m_ImageVector.push_back(pImage); +#ifdef WORLD_EDITOR + m_TextureNameVector.push_back(c_szFileName); +#endif +} + +bool CParticleProperty::SetTexture(const char * c_szFileName) +{ + if (m_ImageVector.size() > 1) + { + assert(false); + return false; + } + m_ImageVector.clear(); +#ifdef WORLD_EDITOR + m_TextureNameVector.clear(); +#endif + InsertTexture(c_szFileName); + return true; +} + +void CParticleProperty::Clear() +{ + m_byRotationType = 0; + m_fRotationSpeed = 0.0f; + m_wRotationRandomStartingBegin = 0; + m_wRotationRandomStartingEnd = 0; + + m_bAttachFlag = FALSE; + m_bStretchFlag = FALSE; + + m_bySrcBlendType = D3DBLEND_SRCALPHA; + m_byDestBlendType = D3DBLEND_ONE; + m_byColorOperationType = D3DTOP_MODULATE; + + m_byBillboardType = BILLBOARD_TYPE_NONE; + + m_byTexAniType = TEXTURE_ANIMATION_TYPE_NONE; + m_fTexAniDelay = 0.05f; + m_bTexAniRandomStartFrameFlag = FALSE; + + //m_fGravity = 0.0f; + //m_fAirResistance = 0.0f; + + m_TimeEventGravity.clear(); + m_TimeEventAirResistance.clear(); + + m_TimeEventScaleX.clear(); + m_TimeEventScaleY.clear(); + //m_TimeEventScaleXY.clear(); +#ifdef WORLD_EDITOR + m_TimeEventColorRed.clear(); + m_TimeEventColorGreen.clear(); + m_TimeEventColorBlue.clear(); + m_TimeEventAlpha.clear(); + m_TextureNameVector.clear(); +#else + m_TimeEventColor.clear(); +#endif + m_TimeEventRotation.clear(); + + m_ImageVector.clear(); +} + +CParticleProperty::CParticleProperty() +{ +} +CParticleProperty::~CParticleProperty() +{ +} + +CParticleProperty & CParticleProperty::operator = ( const CParticleProperty& c_ParticleProperty ) +{ + m_byTexAniType = c_ParticleProperty.m_byTexAniType; + m_fTexAniDelay = c_ParticleProperty.m_fTexAniDelay; + m_bTexAniRandomStartFrameFlag = c_ParticleProperty.m_bTexAniRandomStartFrameFlag; + + m_bySrcBlendType = c_ParticleProperty.m_bySrcBlendType; + m_byDestBlendType = c_ParticleProperty.m_byDestBlendType; + m_byColorOperationType = c_ParticleProperty.m_byColorOperationType; + + m_byBillboardType = c_ParticleProperty.m_byBillboardType; + + m_byRotationType = c_ParticleProperty.m_byRotationType; + m_fRotationSpeed = c_ParticleProperty.m_fRotationSpeed; + m_wRotationRandomStartingBegin = c_ParticleProperty.m_wRotationRandomStartingBegin; + m_wRotationRandomStartingEnd = c_ParticleProperty.m_wRotationRandomStartingEnd; + + m_bAttachFlag = c_ParticleProperty.m_bAttachFlag; + m_bStretchFlag = c_ParticleProperty.m_bStretchFlag; + + m_TimeEventGravity = c_ParticleProperty.m_TimeEventGravity; + m_TimeEventAirResistance = c_ParticleProperty.m_TimeEventAirResistance; + + m_TimeEventScaleX = c_ParticleProperty.m_TimeEventScaleX; + m_TimeEventScaleY = c_ParticleProperty.m_TimeEventScaleY; + +#ifdef WORLD_EDITOR + m_TimeEventColorRed = c_ParticleProperty.m_TimeEventColorRed; + m_TimeEventColorGreen = c_ParticleProperty.m_TimeEventColorGreen; + m_TimeEventColorBlue = c_ParticleProperty.m_TimeEventColorBlue; + m_TimeEventAlpha = c_ParticleProperty.m_TimeEventAlpha; + + m_TextureNameVector = c_ParticleProperty.m_TextureNameVector; +#else + m_TimeEventColor = c_ParticleProperty.m_TimeEventColor; +#endif + m_TimeEventRotation = c_ParticleProperty.m_TimeEventRotation; + + m_ImageVector = c_ParticleProperty.m_ImageVector; + + return *this; +} \ No newline at end of file diff --git a/source/EffectLib/ParticleProperty.h b/source/EffectLib/ParticleProperty.h new file mode 100644 index 0000000..4bf9f77 --- /dev/null +++ b/source/EffectLib/ParticleProperty.h @@ -0,0 +1,96 @@ +#pragma once + +#include +#include "../eterlib/GrpImageInstance.h" + +#include "Type.h" + +class CParticleProperty +{ + friend class CParticleSystemData; + friend class CParticleSystemInstance; + public: + enum + { + ROTATION_TYPE_NONE, + ROTATION_TYPE_TIME_EVENT, + ROTATION_TYPE_CW, + ROTATION_TYPE_CCW, + ROTATION_TYPE_RANDOM_DIRECTION, + }; + + enum + { + TEXTURE_ANIMATION_TYPE_NONE, + TEXTURE_ANIMATION_TYPE_CW, + TEXTURE_ANIMATION_TYPE_CCW, + TEXTURE_ANIMATION_TYPE_RANDOM_FRAME, + TEXTURE_ANIMATION_TYPE_RANDOM_DIRECTION, + }; + + public: + CParticleProperty(); + virtual ~CParticleProperty(); + + void Clear(); + + void InsertTexture(const char * c_szFileName); + bool SetTexture(const char * c_szFileName); + + __forceinline BYTE GetTextureAnimationType() + { + return m_byTexAniType; + } + + __forceinline DWORD GetTextureAnimationFrameCount() + { + return m_ImageVector.size(); + } + + __forceinline float GetTextureAnimationFrameDelay() + { + return m_fTexAniDelay; + } + + + BYTE m_byTexAniType; + float m_fTexAniDelay; + BOOL m_bTexAniRandomStartFrameFlag; + + BYTE m_bySrcBlendType; + BYTE m_byDestBlendType; + BYTE m_byColorOperationType; + BYTE m_byBillboardType; + + BYTE m_byRotationType; + float m_fRotationSpeed; + WORD m_wRotationRandomStartingBegin; + WORD m_wRotationRandomStartingEnd; + + BOOL m_bAttachFlag; + BOOL m_bStretchFlag; + + TTimeEventTableFloat m_TimeEventGravity; + TTimeEventTableFloat m_TimeEventAirResistance; + + TTimeEventTableFloat m_TimeEventScaleX; + TTimeEventTableFloat m_TimeEventScaleY; +#ifdef WORLD_EDITOR + TTimeEventTableFloat m_TimeEventColorRed; + TTimeEventTableFloat m_TimeEventColorGreen; + TTimeEventTableFloat m_TimeEventColorBlue; + TTimeEventTableFloat m_TimeEventAlpha; + + std::vector m_TextureNameVector; +#else + TTimeEventTableColor m_TimeEventColor; +#endif + TTimeEventTableFloat m_TimeEventRotation; + + std::vector m_ImageVector; + + CParticleProperty & operator = ( const CParticleProperty& c_ParticleProperty ); + + // pre-transformed variables + D3DXVECTOR3 m_v3ZAxis; +}; diff --git a/source/EffectLib/ParticleSystemData.cpp b/source/EffectLib/ParticleSystemData.cpp new file mode 100644 index 0000000..a759ce9 --- /dev/null +++ b/source/EffectLib/ParticleSystemData.cpp @@ -0,0 +1,424 @@ +#include "StdAfx.h" +#include "ParticleSystemData.h" +#include "EffectUpdateDecorator.h" +#include "ParticleInstance.h" + +CDynamicPool CParticleSystemData::ms_kPool; + +void CParticleSystemData::DestroySystem() +{ + ms_kPool.Destroy(); +} + +CParticleSystemData* CParticleSystemData::New() +{ + return ms_kPool.Alloc(); +} + +void CParticleSystemData::Delete(CParticleSystemData* pkData) +{ + pkData->Clear(); + ms_kPool.Free(pkData); +} + +CEmitterProperty * CParticleSystemData::GetEmitterPropertyPointer() +{ + return &m_EmitterProperty; +} +CParticleProperty * CParticleSystemData::GetParticlePropertyPointer() +{ + return &m_ParticleProperty; +} + +BOOL CParticleSystemData::OnLoadScript(CTextFileLoader & rTextFileLoader) +{ + { + CTextFileLoader::CGotoChild GotoChild(&rTextFileLoader, "emitterproperty"); + + if (!rTextFileLoader.GetTokenDoubleWord("maxemissioncount", &m_EmitterProperty.m_dwMaxEmissionCount)) + return FALSE; + + if (!rTextFileLoader.GetTokenFloat("cyclelength", &m_EmitterProperty.m_fCycleLength)) + { + m_EmitterProperty.m_fCycleLength = 0.05f; + } + if (!rTextFileLoader.GetTokenBoolean("cycleloopenable", &m_EmitterProperty.m_bCycleLoopFlag)) + { + m_EmitterProperty.m_bCycleLoopFlag = FALSE; + } + if (!rTextFileLoader.GetTokenInteger("loopcount",&m_EmitterProperty.m_iLoopCount)) + { + m_EmitterProperty.m_iLoopCount = 0; + } + + if (!rTextFileLoader.GetTokenByte("emittershape", &m_EmitterProperty.m_byEmitterShape)) + return FALSE; + + if (!rTextFileLoader.GetTokenByte("emitteradvancedtype", &m_EmitterProperty.m_byEmitterAdvancedType)) + { + m_EmitterProperty.m_byEmitterShape = CEmitterProperty::EMITTER_ADVANCED_TYPE_FREE; + } + if (!rTextFileLoader.GetTokenPosition("emittingsize", &m_EmitterProperty.m_v3EmittingSize)) + { + m_EmitterProperty.m_v3EmittingSize = D3DXVECTOR3(0.0f, 0.0f, 0.0f); + } + if (!rTextFileLoader.GetTokenFloat("emittingradius", &m_EmitterProperty.m_fEmittingRadius)) + { + m_EmitterProperty.m_fEmittingRadius = 0.0f; + } + + if (!rTextFileLoader.GetTokenBoolean("emitteremitfromedgeflag", &m_EmitterProperty.m_bEmitFromEdgeFlag)) + { + m_EmitterProperty.m_bEmitFromEdgeFlag = FALSE; + } + + if (!rTextFileLoader.GetTokenPosition("emittingdirection", &m_EmitterProperty.m_v3EmittingDirection)) + { + m_EmitterProperty.m_v3EmittingDirection = D3DXVECTOR3(0.0f, 0.0f, 0.0f); + } + + if (!GetTokenTimeEventFloat(rTextFileLoader, "timeeventemittingsize", &m_EmitterProperty.m_TimeEventEmittingSize)) + { + m_EmitterProperty.m_TimeEventEmittingSize.clear(); + TTimeEventTypeFloat TimeEventFloat; + TimeEventFloat.m_fTime = 0.0f; + TimeEventFloat.m_Value = 0.0f; + m_EmitterProperty.m_TimeEventEmittingSize.push_back(TimeEventFloat); + } + + if (!GetTokenTimeEventFloat(rTextFileLoader, "timeeventemittingangularvelocity", &m_EmitterProperty.m_TimeEventEmittingAngularVelocity)) + { + m_EmitterProperty.m_TimeEventEmittingAngularVelocity.clear(); + TTimeEventTypeFloat TimeEventFloat; + TimeEventFloat.m_fTime = 0.0f; + TimeEventFloat.m_Value = 0.0f; + m_EmitterProperty.m_TimeEventEmittingAngularVelocity.push_back(TimeEventFloat); + } + + if (!GetTokenTimeEventFloat(rTextFileLoader, "timeeventemittingdirectionx", &m_EmitterProperty.m_TimeEventEmittingDirectionX)) + { + m_EmitterProperty.m_TimeEventEmittingDirectionX.clear(); + TTimeEventTypeFloat TimeEventFloat; + TimeEventFloat.m_fTime = 0.0f; + TimeEventFloat.m_Value = 0.0f; + m_EmitterProperty.m_TimeEventEmittingDirectionX.push_back(TimeEventFloat); + } + if (!GetTokenTimeEventFloat(rTextFileLoader, "timeeventemittingdirectiony", &m_EmitterProperty.m_TimeEventEmittingDirectionY)) + { + m_EmitterProperty.m_TimeEventEmittingDirectionY.clear(); + TTimeEventTypeFloat TimeEventFloat; + TimeEventFloat.m_fTime = 0.0f; + TimeEventFloat.m_Value = 0.0f; + m_EmitterProperty.m_TimeEventEmittingDirectionY.push_back(TimeEventFloat); + } + if (!GetTokenTimeEventFloat(rTextFileLoader, "timeeventemittingdirectionz", &m_EmitterProperty.m_TimeEventEmittingDirectionZ)) + { + m_EmitterProperty.m_TimeEventEmittingDirectionZ.clear(); + TTimeEventTypeFloat TimeEventFloat; + TimeEventFloat.m_fTime = 0.0f; + TimeEventFloat.m_Value = 0.0f; + m_EmitterProperty.m_TimeEventEmittingDirectionZ.push_back(TimeEventFloat); + } + if (!GetTokenTimeEventFloat(rTextFileLoader, "timeeventemittingvelocity", &m_EmitterProperty.m_TimeEventEmittingVelocity)) + { + m_EmitterProperty.m_TimeEventEmittingVelocity.clear(); + TTimeEventTypeFloat TimeEventFloat; + TimeEventFloat.m_fTime = 0.0f; + TimeEventFloat.m_Value = 0.0f; + m_EmitterProperty.m_TimeEventEmittingVelocity.push_back(TimeEventFloat); + } + if (!GetTokenTimeEventFloat(rTextFileLoader, "timeeventemissioncountpersecond", &m_EmitterProperty.m_TimeEventEmissionCountPerSecond)) + return FALSE; + if (!GetTokenTimeEventFloat(rTextFileLoader, "timeeventlifetime", &m_EmitterProperty.m_TimeEventLifeTime)) + return FALSE; + if (!GetTokenTimeEventFloat(rTextFileLoader, "timeeventsizex", &m_EmitterProperty.m_TimeEventSizeX)) + return FALSE; + if (!GetTokenTimeEventFloat(rTextFileLoader, "timeeventsizey", &m_EmitterProperty.m_TimeEventSizeY)) + return FALSE; + } + + { + CTextFileLoader::CGotoChild GotoChild(&rTextFileLoader, "particleproperty"); + + if (!rTextFileLoader.GetTokenByte("srcblendtype", &m_ParticleProperty.m_bySrcBlendType)) + { + m_ParticleProperty.m_bySrcBlendType = D3DBLEND_SRCALPHA; + } + if (!rTextFileLoader.GetTokenByte("destblendtype", &m_ParticleProperty.m_byDestBlendType)) + { + m_ParticleProperty.m_byDestBlendType = D3DBLEND_ONE; + } + if (!rTextFileLoader.GetTokenByte("coloroperationtype", &m_ParticleProperty.m_byColorOperationType)) + { + m_ParticleProperty.m_byColorOperationType = D3DTOP_MODULATE; + } + + if (!rTextFileLoader.GetTokenByte("billboardtype", &m_ParticleProperty.m_byBillboardType)) + return FALSE; + + if (!rTextFileLoader.GetTokenByte("rotationtype", &m_ParticleProperty.m_byRotationType)) + return FALSE; + if (!rTextFileLoader.GetTokenFloat("rotationspeed", &m_ParticleProperty.m_fRotationSpeed)) + return FALSE; + if (!rTextFileLoader.GetTokenWord("rotationrandomstartingbegin", &m_ParticleProperty.m_wRotationRandomStartingBegin)) + return FALSE; + if (!rTextFileLoader.GetTokenWord("rotationrandomstartingend", &m_ParticleProperty.m_wRotationRandomStartingEnd)) + return FALSE; + + if (!rTextFileLoader.GetTokenBoolean("attachenable", &m_ParticleProperty.m_bAttachFlag)) + { + m_ParticleProperty.m_bAttachFlag = FALSE; + } + if (!rTextFileLoader.GetTokenBoolean("stretchenable", &m_ParticleProperty.m_bStretchFlag)) + return FALSE; + + if (!rTextFileLoader.GetTokenByte("texanitype", &m_ParticleProperty.m_byTexAniType)) + return FALSE; + if (!rTextFileLoader.GetTokenFloat("texanidelay", &m_ParticleProperty.m_fTexAniDelay)) + return FALSE; + if (!rTextFileLoader.GetTokenBoolean("texanirandomstartframeenable", &m_ParticleProperty.m_bTexAniRandomStartFrameFlag)) + return FALSE; + + float fGravity; + + if (rTextFileLoader.GetTokenFloat("gravity", &fGravity)) + { + TTimeEventTypeFloat f; + f.m_fTime = 0.0f; + f.m_Value = fGravity; + m_ParticleProperty.m_TimeEventGravity.push_back(f); + } + else if (!GetTokenTimeEventFloat(rTextFileLoader, "timeeventgravity", &m_ParticleProperty.m_TimeEventGravity)) + { + m_ParticleProperty.m_TimeEventGravity.clear(); + } + + float fAirResistance; + if (rTextFileLoader.GetTokenFloat("airresistance", &fAirResistance)) + { + TTimeEventTypeFloat f; + f.m_fTime = 0.0f; + f.m_Value = fAirResistance; + m_ParticleProperty.m_TimeEventAirResistance.push_back(f); + } + else if (!GetTokenTimeEventFloat(rTextFileLoader, "timeeventairresistance", &m_ParticleProperty.m_TimeEventAirResistance)) + { + m_ParticleProperty.m_TimeEventAirResistance.clear(); + } + + if (!GetTokenTimeEventFloat(rTextFileLoader, "timeeventscalex", &m_ParticleProperty.m_TimeEventScaleX)) + return FALSE; + if (!GetTokenTimeEventFloat(rTextFileLoader, "timeeventscaley", &m_ParticleProperty.m_TimeEventScaleY)) + return FALSE; + +#ifdef WORLD_EDITOR + if (!GetTokenTimeEventFloat(rTextFileLoader, "timeeventcolorred", &m_ParticleProperty.m_TimeEventColorRed)) + return FALSE; + if (!GetTokenTimeEventFloat(rTextFileLoader, "timeeventcolorgreen", &m_ParticleProperty.m_TimeEventColorGreen)) + return FALSE; + if (!GetTokenTimeEventFloat(rTextFileLoader, "timeeventcolorblue", &m_ParticleProperty.m_TimeEventColorBlue)) + return FALSE; + + if (!GetTokenTimeEventFloat(rTextFileLoader, "timeeventalpha", &m_ParticleProperty.m_TimeEventAlpha)) + return FALSE; +#else + TTimeEventTableFloat TimeEventR; + TTimeEventTableFloat TimeEventB; + TTimeEventTableFloat TimeEventG; + TTimeEventTableFloat TimeEventA; + if (!GetTokenTimeEventFloat(rTextFileLoader, "timeeventcolorred", &TimeEventR)) + return FALSE; + if (!GetTokenTimeEventFloat(rTextFileLoader, "timeeventcolorgreen", &TimeEventG)) + return FALSE; + if (!GetTokenTimeEventFloat(rTextFileLoader, "timeeventcolorblue", &TimeEventB)) + return FALSE; + if (!GetTokenTimeEventFloat(rTextFileLoader, "timeeventalpha", &TimeEventA)) + return FALSE; + + m_ParticleProperty.m_TimeEventColor.clear(); + { + std::set times; + int i; + for(i=0;i::iterator it; + for(it = times.begin(); it != times.end(); ++it) + { + float fTime = *it; + float fR, fG, fB, fA; + GetTimeEventBlendValue(fTime, TimeEventR, &fR); + GetTimeEventBlendValue(fTime, TimeEventG, &fG); + GetTimeEventBlendValue(fTime, TimeEventB, &fB); + GetTimeEventBlendValue(fTime, TimeEventA, &fA); + TTimeEventTypeColor t; + t.m_fTime = fTime; + D3DXCOLOR c; + c.r = fR; + c.g = fG; + c.b = fB; + c.a = fA; + t.m_Value.m_dwColor = /*(DWORD)*/ (DWORD)c; + m_ParticleProperty.m_TimeEventColor.push_back(t); + } + } +#endif + + if (!GetTokenTimeEventFloat(rTextFileLoader, "timeeventrotation", &m_ParticleProperty.m_TimeEventRotation)) + return FALSE; + + CTokenVector * pTextureVector; + + if (!rTextFileLoader.GetTokenVector("texturefiles", &pTextureVector)) + return FALSE; + + for (DWORD i = 0; i < pTextureVector->size(); ++i) + { + std::string strTextureFileName = pTextureVector->at(i).c_str(); + + if (!IsGlobalFileName(strTextureFileName.c_str())) + strTextureFileName = GetOnlyPathName(rTextFileLoader.GetFileName()) + strTextureFileName; + + m_ParticleProperty.InsertTexture(strTextureFileName.c_str()); + } + } + + return TRUE; +} + +void CParticleSystemData::ChangeTexture(const char * c_szFileName) +{ + m_ParticleProperty.SetTexture(c_szFileName); +} + +void CParticleSystemData::OnClear() +{ + m_EmitterProperty.Clear(); + m_ParticleProperty.Clear(); +} + +bool CParticleSystemData::OnIsData() +{ + return true; +} + +void CParticleSystemData::BuildDecorator(CParticleInstance * pInstance) +{ + using namespace NEffectUpdateDecorator; + + pInstance->m_pDecorator = new CNullDecorator; + + ////// + + if (m_ParticleProperty.m_TimeEventAirResistance.size()>1) + { + pInstance->m_pDecorator=pInstance->m_pDecorator->AddChainFront(new CAirResistanceDecorator); + pInstance->m_pDecorator=pInstance->m_pDecorator->AddChainFront( + new CAirResistanceValueDecorator(m_ParticleProperty.m_TimeEventAirResistance, &pInstance->m_fAirResistance) + ); + } + else if (m_ParticleProperty.m_TimeEventAirResistance.size()==1) + { + pInstance->m_fAirResistance = m_ParticleProperty.m_TimeEventAirResistance[0].m_Value; + pInstance->m_pDecorator=pInstance->m_pDecorator->AddChainFront(new CAirResistanceDecorator); + } + + if (m_ParticleProperty.m_TimeEventGravity.size() > 1) + { + pInstance->m_pDecorator = pInstance->m_pDecorator->AddChainFront(new CGravityDecorator); + pInstance->m_pDecorator = pInstance->m_pDecorator->AddChainFront( + new CGravityValueDecorator(m_ParticleProperty.m_TimeEventGravity, &pInstance->m_fGravity) + ); + } + else if (m_ParticleProperty.m_TimeEventGravity.size() == 1) + { + pInstance->m_fGravity = m_ParticleProperty.m_TimeEventGravity[0].m_Value; + pInstance->m_pDecorator = pInstance->m_pDecorator->AddChainFront(new CGravityDecorator); + } +#ifdef WORLD_EDITOR + pInstance->m_pDecorator = pInstance->m_pDecorator->AddChainFront( + new CColorValueDecorator(m_ParticleProperty.m_TimeEventColorRed, &pInstance->m_Color.r)); + pInstance->m_pDecorator = pInstance->m_pDecorator->AddChainFront( + new CColorValueDecorator(m_ParticleProperty.m_TimeEventColorGreen, &pInstance->m_Color.g)); + pInstance->m_pDecorator = pInstance->m_pDecorator->AddChainFront( + new CColorValueDecorator(m_ParticleProperty.m_TimeEventColorBlue, &pInstance->m_Color.b)); + pInstance->m_pDecorator = pInstance->m_pDecorator->AddChainFront( + new CColorValueDecorator(m_ParticleProperty.m_TimeEventAlpha, &pInstance->m_Color.a)); +#else + pInstance->m_pDecorator = pInstance->m_pDecorator->AddChainFront( + new CColorAllDecorator(m_ParticleProperty.m_TimeEventColor, &pInstance->m_dcColor)); +#endif + + pInstance->m_pDecorator = pInstance->m_pDecorator->AddChainFront( + new CScaleValueDecorator(m_ParticleProperty.m_TimeEventScaleX, &pInstance->m_v2Scale.x)); + pInstance->m_pDecorator = pInstance->m_pDecorator->AddChainFront( + new CScaleValueDecorator(m_ParticleProperty.m_TimeEventScaleY, &pInstance->m_v2Scale.y)); + + if (m_ParticleProperty.GetTextureAnimationFrameCount()>1 &&m_ParticleProperty.GetTextureAnimationFrameDelay()>1e-6) + { + switch (pInstance->m_byTextureAnimationType) + { + case CParticleProperty::TEXTURE_ANIMATION_TYPE_CW: + pInstance->m_pDecorator=pInstance->m_pDecorator->AddChainFront( + new CTextureAnimationCWDecorator(m_ParticleProperty.GetTextureAnimationFrameDelay(), m_ParticleProperty.GetTextureAnimationFrameCount(), &pInstance->m_byFrameIndex)); + break; + case CParticleProperty::TEXTURE_ANIMATION_TYPE_CCW: + pInstance->m_pDecorator=pInstance->m_pDecorator->AddChainFront( + new CTextureAnimationCCWDecorator(m_ParticleProperty.GetTextureAnimationFrameDelay(), m_ParticleProperty.GetTextureAnimationFrameCount(), &pInstance->m_byFrameIndex)); + break; + case CParticleProperty::TEXTURE_ANIMATION_TYPE_RANDOM_FRAME: + pInstance->m_pDecorator=pInstance->m_pDecorator->AddChainFront( + new CTextureAnimationRandomDecorator(m_ParticleProperty.GetTextureAnimationFrameDelay(), m_ParticleProperty.GetTextureAnimationFrameCount(), &pInstance->m_byFrameIndex)); + break; + } + } + + BYTE byRotationType = m_ParticleProperty.m_byRotationType; + + if (m_ParticleProperty.m_fRotationSpeed==0.0f && byRotationType!=CParticleProperty::ROTATION_TYPE_TIME_EVENT) + { + byRotationType = CParticleProperty::ROTATION_TYPE_NONE; + } + else if (byRotationType==CParticleProperty::ROTATION_TYPE_RANDOM_DIRECTION) + { + byRotationType = (random()&1)?CParticleProperty::ROTATION_TYPE_CW:CParticleProperty::ROTATION_TYPE_CCW; + } + + switch(byRotationType) + { + case CParticleProperty::ROTATION_TYPE_TIME_EVENT: + pInstance->m_pDecorator=pInstance->m_pDecorator->AddChainFront( + new CRotationDecorator()); + pInstance->m_pDecorator=pInstance->m_pDecorator->AddChainFront( + new CRotationSpeedValueDecorator(m_ParticleProperty.m_TimeEventRotation,&pInstance->m_fRotationSpeed)); + break; + + case CParticleProperty::ROTATION_TYPE_CW: + pInstance->m_fRotationSpeed = m_ParticleProperty.m_fRotationSpeed; + pInstance->m_pDecorator=pInstance->m_pDecorator->AddChainFront( + new CRotationDecorator()); + break; + + case CParticleProperty::ROTATION_TYPE_CCW: + pInstance->m_fRotationSpeed = - m_ParticleProperty.m_fRotationSpeed; + pInstance->m_pDecorator=pInstance->m_pDecorator->AddChainFront( + new CRotationDecorator()); + break; + } + + ///// + + pInstance->m_pDecorator=pInstance->m_pDecorator->AddChainFront(new CHeaderDecorator); +} + +CParticleSystemData::CParticleSystemData() +{ +} +CParticleSystemData::~CParticleSystemData() +{ +} diff --git a/source/EffectLib/ParticleSystemData.h b/source/EffectLib/ParticleSystemData.h new file mode 100644 index 0000000..0202d1b --- /dev/null +++ b/source/EffectLib/ParticleSystemData.h @@ -0,0 +1,41 @@ +#pragma once + +#include "../eterLib/TextFileLoader.h" + +#include "EffectElementBase.h" +#include "EmitterProperty.h" +#include "ParticleProperty.h" +//#include "ParticleInstance.h" + +class CParticleInstance; + +class CParticleSystemData : public CEffectElementBase +{ + public: + virtual ~CParticleSystemData(); + CParticleSystemData(); + + CEmitterProperty * GetEmitterPropertyPointer(); + CParticleProperty * GetParticlePropertyPointer(); + + void ChangeTexture(const char * c_szFileName); + + void BuildDecorator(CParticleInstance * pInstance); + protected: + BOOL OnLoadScript(CTextFileLoader & rTextFileLoader); + + void OnClear(); + bool OnIsData(); + + + CEmitterProperty m_EmitterProperty; + CParticleProperty m_ParticleProperty; + + public: + static void DestroySystem(); + + static CParticleSystemData* New(); + static void Delete(CParticleSystemData* pkData); + + static CDynamicPool ms_kPool; +}; diff --git a/source/EffectLib/ParticleSystemInstance.cpp b/source/EffectLib/ParticleSystemInstance.cpp new file mode 100644 index 0000000..5f8b643 --- /dev/null +++ b/source/EffectLib/ParticleSystemInstance.cpp @@ -0,0 +1,528 @@ +#include "StdAfx.h" +#include "../eterBase/Random.h" +#include "../eterLib/StateManager.h" +#include "ParticleSystemData.h" +#include "ParticleSystemInstance.h" +#include "ParticleInstance.h" + +CDynamicPool CParticleSystemInstance::ms_kPool; + +using namespace NEffectUpdateDecorator; + +void CParticleSystemInstance::DestroySystem() +{ + ms_kPool.Destroy(); + + CParticleInstance::DestroySystem(); + //CRayParticleInstance::DestroySystem(); +} + +CParticleSystemInstance* CParticleSystemInstance::New() +{ + return ms_kPool.Alloc(); +} + +void CParticleSystemInstance::Delete(CParticleSystemInstance* pkPSInst) +{ + pkPSInst->Destroy(); + ms_kPool.Free(pkPSInst); +} + + + +DWORD CParticleSystemInstance::GetEmissionCount() +{ + return m_dwCurrentEmissionCount; +} + +void CParticleSystemInstance::CreateParticles(float fElapsedTime) +{ + float fEmissionCount; + m_pEmitterProperty->GetEmissionCountPerSecond(m_fLocalTime, &fEmissionCount); + + float fCreatingValue = fEmissionCount * (fElapsedTime / 1.0f) + m_fEmissionResidue; + int iCreatingCount = int(fCreatingValue); + m_fEmissionResidue = fCreatingValue - iCreatingCount; + + int icurEmissionCount = GetEmissionCount(); + int iMaxEmissionCount = int(m_pEmitterProperty->GetMaxEmissionCount()); + int iNextEmissionCount = int(icurEmissionCount + iCreatingCount); + iCreatingCount -= max(0, iNextEmissionCount - iMaxEmissionCount); + + float fLifeTime = 0.0f; + float fEmittingSize = 0.0f; + D3DXVECTOR3 _v3TimePosition; + D3DXVECTOR3 _v3Velocity; + float fVelocity = 0.0f; + D3DXVECTOR2 v2HalfSize; + float fLieRotation = 0; + if (iCreatingCount) + { + m_pEmitterProperty->GetParticleLifeTime(m_fLocalTime, &fLifeTime); + if (fLifeTime==0.0f) + { + return; + } + + m_pEmitterProperty->GetEmittingSize(m_fLocalTime, &fEmittingSize); + + m_pData->GetPosition(m_fLocalTime, _v3TimePosition); + + m_pEmitterProperty->GetEmittingDirectionX(m_fLocalTime, &_v3Velocity.x); + m_pEmitterProperty->GetEmittingDirectionY(m_fLocalTime, &_v3Velocity.y); + m_pEmitterProperty->GetEmittingDirectionZ(m_fLocalTime, &_v3Velocity.z); + + m_pEmitterProperty->GetEmittingVelocity(m_fLocalTime, &fVelocity); + + m_pEmitterProperty->GetParticleSizeX(m_fLocalTime, &v2HalfSize.x); + m_pEmitterProperty->GetParticleSizeY(m_fLocalTime, &v2HalfSize.y); + + if (BILLBOARD_TYPE_LIE == m_pParticleProperty->m_byBillboardType && mc_pmatLocal) + { + float fsx = mc_pmatLocal->_32; + float fcx = sqrtf(1.0f - fsx * fsx); + + if (fcx >= 0.00001f) + fLieRotation = D3DXToDegree(atan2f(-mc_pmatLocal->_12, mc_pmatLocal->_22)); + } + + } + + CParticleInstance * pFirstInstance = 0; + + for (int i = 0; i < iCreatingCount; ++i) + { + CParticleInstance * pInstance; + + pInstance = CParticleInstance::New(); + pInstance->m_pParticleProperty = m_pParticleProperty; + pInstance->m_pEmitterProperty = m_pEmitterProperty; + + // LifeTime + pInstance->m_fLifeTime = fLifeTime; + pInstance->m_fLastLifeTime = fLifeTime; + + // Position + switch (m_pEmitterProperty->GetEmitterShape()) + { + case CEmitterProperty::EMITTER_SHAPE_POINT: + pInstance->m_v3Position.x = 0.0f; + pInstance->m_v3Position.y = 0.0f; + pInstance->m_v3Position.z = 0.0f; + break; + + case CEmitterProperty::EMITTER_SHAPE_ELLIPSE: + pInstance->m_v3Position.x = frandom(-500.0f, 500.0f); + pInstance->m_v3Position.y = frandom(-500.0f, 500.0f); + pInstance->m_v3Position.z = 0.0f; + D3DXVec3Normalize(&pInstance->m_v3Position, &pInstance->m_v3Position); + + if (m_pEmitterProperty->isEmitFromEdge()) + { + pInstance->m_v3Position *= (m_pEmitterProperty->m_fEmittingRadius + fEmittingSize); + } + else + { + pInstance->m_v3Position *= (frandom(0.0f, m_pEmitterProperty->m_fEmittingRadius) + fEmittingSize); + } + break; + + case CEmitterProperty::EMITTER_SHAPE_SQUARE: + pInstance->m_v3Position.x = (frandom(-m_pEmitterProperty->m_v3EmittingSize.x/2.0f, m_pEmitterProperty->m_v3EmittingSize.x/2.0f) + fEmittingSize); + pInstance->m_v3Position.y = (frandom(-m_pEmitterProperty->m_v3EmittingSize.y/2.0f, m_pEmitterProperty->m_v3EmittingSize.y/2.0f) + fEmittingSize); + pInstance->m_v3Position.z = (frandom(-m_pEmitterProperty->m_v3EmittingSize.z/2.0f, m_pEmitterProperty->m_v3EmittingSize.z/2.0f) + fEmittingSize); + break; + + case CEmitterProperty::EMITTER_SHAPE_SPHERE: + pInstance->m_v3Position.x = frandom(-500.0f, 500.0f); + pInstance->m_v3Position.y = frandom(-500.0f, 500.0f); + pInstance->m_v3Position.z = frandom(-500.0f, 500.0f); + D3DXVec3Normalize(&pInstance->m_v3Position, &pInstance->m_v3Position); + + if (m_pEmitterProperty->isEmitFromEdge()) + { + pInstance->m_v3Position *= (m_pEmitterProperty->m_fEmittingRadius + fEmittingSize); + } + else + { + pInstance->m_v3Position *= (frandom(0.0f, m_pEmitterProperty->m_fEmittingRadius) + fEmittingSize); + } + break; + } + + // Position + D3DXVECTOR3 v3TimePosition=_v3TimePosition; + + pInstance->m_v3Position += v3TimePosition; + + if (mc_pmatLocal && !m_pParticleProperty->m_bAttachFlag) + { + D3DXVec3TransformCoord(&pInstance->m_v3Position,&pInstance->m_v3Position,mc_pmatLocal); + D3DXVec3TransformCoord(&v3TimePosition, &v3TimePosition, mc_pmatLocal); + } + pInstance->m_v3StartPosition = v3TimePosition; + // NOTE : Update ȣ ʰ Rendering DZ length 0 Ǵ ִ. + // Velocity ׸ŭ ʱȭ ֵ ٲ - [levites] + //pInstance->m_v3LastPosition = pInstance->m_v3Position; + + // Direction & Velocity + pInstance->m_v3Velocity.x = 0.0f; + pInstance->m_v3Velocity.y = 0.0f; + pInstance->m_v3Velocity.z = 0.0f; + + if (CEmitterProperty::EMITTER_ADVANCED_TYPE_INNER == m_pEmitterProperty->GetEmitterAdvancedType()) + { + auto d3dd = (pInstance->m_v3Position - v3TimePosition); + D3DXVec3Normalize(&pInstance->m_v3Velocity, &d3dd); + pInstance->m_v3Velocity *= -100.0f; + } + else if (CEmitterProperty::EMITTER_ADVANCED_TYPE_OUTER == m_pEmitterProperty->GetEmitterAdvancedType()) + { + if (m_pEmitterProperty->GetEmitterShape() == CEmitterProperty::EMITTER_SHAPE_POINT) + { + pInstance->m_v3Velocity.x = frandom(-100.0f, 100.0f); + pInstance->m_v3Velocity.y = frandom(-100.0f, 100.0f); + pInstance->m_v3Velocity.z = frandom(-100.0f, 100.0f); + } + else + { + auto d3dd = (pInstance->m_v3Position - v3TimePosition); + D3DXVec3Normalize(&pInstance->m_v3Velocity, &d3dd); + pInstance->m_v3Velocity *= 100.0f; + } + } + + D3DXVECTOR3 v3Velocity = _v3Velocity; + if (mc_pmatLocal && !m_pParticleProperty->m_bAttachFlag) + { + D3DXVec3TransformNormal(&v3Velocity, &v3Velocity, mc_pmatLocal); + } + + pInstance->m_v3Velocity += v3Velocity; + if (m_pEmitterProperty->m_v3EmittingDirection.x > 0.0f) + pInstance->m_v3Velocity.x += frandom(-m_pEmitterProperty->m_v3EmittingDirection.x/2.0f, m_pEmitterProperty->m_v3EmittingDirection.x/2.0f) * 1000.0f; + if (m_pEmitterProperty->m_v3EmittingDirection.y > 0.0f) + pInstance->m_v3Velocity.y += frandom(-m_pEmitterProperty->m_v3EmittingDirection.y/2.0f, m_pEmitterProperty->m_v3EmittingDirection.y/2.0f) * 1000.0f; + if (m_pEmitterProperty->m_v3EmittingDirection.z > 0.0f) + pInstance->m_v3Velocity.z += frandom(-m_pEmitterProperty->m_v3EmittingDirection.z/2.0f, m_pEmitterProperty->m_v3EmittingDirection.z/2.0f) * 1000.0f; + + pInstance->m_v3Velocity *= fVelocity; + + // Size + pInstance->m_v2HalfSize = v2HalfSize; + + // Rotation + pInstance->m_fRotation = m_pParticleProperty->m_wRotationRandomStartingBegin; + pInstance->m_fRotation = frandom(m_pParticleProperty->m_wRotationRandomStartingBegin,m_pParticleProperty->m_wRotationRandomStartingEnd); + // Rotation - Lie LocalMatrix Rotation Random Ѵ. + // Ź ʿ . ȭ ʿ. - [levites] + if (BILLBOARD_TYPE_LIE == m_pParticleProperty->m_byBillboardType && mc_pmatLocal) + { + pInstance->m_fRotation += fLieRotation; + } + + // Texture Animation + pInstance->m_byFrameIndex = 0; + pInstance->m_byTextureAnimationType = m_pParticleProperty->GetTextureAnimationType(); + + if (m_pParticleProperty->GetTextureAnimationFrameCount() > 1) + { + if (CParticleProperty::TEXTURE_ANIMATION_TYPE_RANDOM_DIRECTION == m_pParticleProperty->GetTextureAnimationType()) + { + if (random() & 1) + { + pInstance->m_byFrameIndex = 0; + pInstance->m_byTextureAnimationType = CParticleProperty::TEXTURE_ANIMATION_TYPE_CW; + } + else + { + pInstance->m_byFrameIndex = m_pParticleProperty->GetTextureAnimationFrameCount() - 1; + pInstance->m_byTextureAnimationType = CParticleProperty::TEXTURE_ANIMATION_TYPE_CCW; + } + } + if (m_pParticleProperty->m_bTexAniRandomStartFrameFlag) + { + pInstance->m_byFrameIndex = random_range(0,m_pParticleProperty->GetTextureAnimationFrameCount()-1); + } + } + + // Simple Update + { + pInstance->m_v3LastPosition = pInstance->m_v3Position - (pInstance->m_v3Velocity * fElapsedTime); + pInstance->m_v2Scale.x = m_pParticleProperty->m_TimeEventScaleX.front().m_Value; + pInstance->m_v2Scale.y= m_pParticleProperty->m_TimeEventScaleY.front().m_Value; + //pInstance->m_v2Scale = m_pParticleProperty->m_TimeEventScaleXY.front().m_Value; +#ifdef WORLD_EDITOR + pInstance->m_Color.r = m_pParticleProperty->m_TimeEventColorRed.front().m_Value; + pInstance->m_Color.g = m_pParticleProperty->m_TimeEventColorGreen.front().m_Value; + pInstance->m_Color.b = m_pParticleProperty->m_TimeEventColorBlue.front().m_Value; + pInstance->m_Color.a = m_pParticleProperty->m_TimeEventAlpha.front().m_Value; +#else + pInstance->m_dcColor = m_pParticleProperty->m_TimeEventColor.front().m_Value; +#endif + } + + if (!pFirstInstance) + { + m_pData->BuildDecorator(pInstance); + pFirstInstance = pInstance; + } + else + { + pInstance->m_pDecorator = pFirstInstance->m_pDecorator->Clone(pFirstInstance,pInstance); + } + + m_ParticleInstanceListVector[pInstance->m_byFrameIndex].push_back(pInstance); + m_dwCurrentEmissionCount++; + } +} + +bool CParticleSystemInstance::OnUpdate(float fElapsedTime) +{ + bool bMakeParticle = true; + + ///// + + if (m_fLocalTime >= m_pEmitterProperty->GetCycleLength()) + { + if (m_pEmitterProperty->isCycleLoop() && --m_iLoopCount!=0) + { + if (m_iLoopCount<0) + m_iLoopCount = 0; + m_fLocalTime = m_fLocalTime - m_pEmitterProperty->GetCycleLength(); + } + else + { + bMakeParticle = false; + m_iLoopCount=1; + if (GetEmissionCount()==0) + return false; + } + } + + ///// + + int dwFrameIndex; + int dwFrameCount = m_pParticleProperty->GetTextureAnimationFrameCount(); + + float fAngularVelocity; + m_pEmitterProperty->GetEmittingAngularVelocity(m_fLocalTime,&fAngularVelocity); + + if (fAngularVelocity && !m_pParticleProperty->m_bAttachFlag) + { + auto d3dd = D3DXVECTOR3(0.0f, 0.0f, 1.0f); + D3DXVec3TransformNormal(&m_pParticleProperty->m_v3ZAxis,&d3dd,mc_pmatLocal); + } + + for (dwFrameIndex = 0; dwFrameIndex < dwFrameCount; dwFrameIndex++) + { + TParticleInstanceList::iterator itor = m_ParticleInstanceListVector[dwFrameIndex].begin(); + for (; itor != m_ParticleInstanceListVector[dwFrameIndex].end();) + { + CParticleInstance * pInstance = *itor; + + if (!pInstance->Update(fElapsedTime,fAngularVelocity)) + { + pInstance->DeleteThis(); + + itor = m_ParticleInstanceListVector[dwFrameIndex].erase(itor); + m_dwCurrentEmissionCount--; + } + else + { + if (pInstance->m_byFrameIndex != dwFrameIndex) + { + m_ParticleInstanceListVector[dwFrameCount+pInstance->m_byFrameIndex].push_back(*itor); + itor = m_ParticleInstanceListVector[dwFrameIndex].erase(itor); + } + else + ++itor; + } + } + } + if (isActive() && bMakeParticle) + CreateParticles(fElapsedTime); + + for (dwFrameIndex = 0; dwFrameIndex < dwFrameCount; ++dwFrameIndex) + { + m_ParticleInstanceListVector[dwFrameIndex].splice(m_ParticleInstanceListVector[dwFrameIndex].end(),m_ParticleInstanceListVector[dwFrameIndex+dwFrameCount]); + m_ParticleInstanceListVector[dwFrameIndex+dwFrameCount].clear(); + } + + return true; +} + +namespace NParticleRenderer +{ + struct TwoSideRenderer + { + const D3DXMATRIX * pmat; + TwoSideRenderer(const D3DXMATRIX * pmat=NULL) + : pmat(pmat) + { + } + + inline void operator () (CParticleInstance * pInstance) + { + pInstance->Transform(pmat,D3DXToRadian(-30.0f)); + STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pInstance->GetParticleMeshPointer(), sizeof(TPTVertex)); + + pInstance->Transform(pmat,D3DXToRadian(+30.0f)); + STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pInstance->GetParticleMeshPointer(), sizeof(TPTVertex)); + } + }; + + struct ThreeSideRenderer + { + const D3DXMATRIX * pmat; + ThreeSideRenderer(const D3DXMATRIX * pmat=NULL) + : pmat(pmat) + { + } + + inline void operator () (CParticleInstance * pInstance) + { + pInstance->Transform(pmat); + STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pInstance->GetParticleMeshPointer(), sizeof(TPTVertex)); + pInstance->Transform(pmat,D3DXToRadian(-60.0f)); + STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pInstance->GetParticleMeshPointer(), sizeof(TPTVertex)); + pInstance->Transform(pmat,D3DXToRadian(+60.0f)); + STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pInstance->GetParticleMeshPointer(), sizeof(TPTVertex)); + } + }; + + struct NormalRenderer + { + inline void operator () (CParticleInstance * pInstance) + { + pInstance->Transform(); + STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pInstance->GetParticleMeshPointer(), sizeof(TPTVertex)); + } + }; + struct AttachRenderer + { + const D3DXMATRIX* pmat; + AttachRenderer(const D3DXMATRIX * pmat) + : pmat(pmat) + { + } + + inline void operator () (CParticleInstance * pInstance) + { + pInstance->Transform(pmat); + STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pInstance->GetParticleMeshPointer(), sizeof(TPTVertex)); + } + }; +} + +void CParticleSystemInstance::OnRender() +{ + CScreen::Identity(); + STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, m_pParticleProperty->m_bySrcBlendType); + STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, m_pParticleProperty->m_byDestBlendType); + STATEMANAGER.SetTextureStageState(0,D3DTSS_COLOROP,m_pParticleProperty->m_byColorOperationType); + if (m_pParticleProperty->m_byBillboardType < BILLBOARD_TYPE_2FACE) + { + if (!m_pParticleProperty->m_bAttachFlag) + { + auto obj = NParticleRenderer::NormalRenderer(); + ForEachParticleRendering(obj); + } + else + { + auto obj = NParticleRenderer::AttachRenderer(mc_pmatLocal); + ForEachParticleRendering(obj); + } + } + else if (m_pParticleProperty->m_byBillboardType == BILLBOARD_TYPE_2FACE) + { + if (!m_pParticleProperty->m_bAttachFlag) + { + auto obj = NParticleRenderer::TwoSideRenderer(); + ForEachParticleRendering(obj); + } + else + { + auto obj = NParticleRenderer::TwoSideRenderer(mc_pmatLocal); + ForEachParticleRendering(obj); + } + } + else if (m_pParticleProperty->m_byBillboardType == BILLBOARD_TYPE_3FACE) + { + if (!m_pParticleProperty->m_bAttachFlag) + { + auto obj = NParticleRenderer::ThreeSideRenderer(); + ForEachParticleRendering(obj); + } + else + { + auto obj = NParticleRenderer::ThreeSideRenderer(mc_pmatLocal); + ForEachParticleRendering(obj); + } + } +} + +void CParticleSystemInstance::OnSetDataPointer(CEffectElementBase * pElement) +{ + m_pData = (CParticleSystemData *)pElement; + + m_dwCurrentEmissionCount = 0; + m_pParticleProperty = m_pData->GetParticlePropertyPointer(); + m_pEmitterProperty = m_pData->GetEmitterPropertyPointer(); + m_iLoopCount = m_pEmitterProperty->GetLoopCount(); + m_ParticleInstanceListVector.resize(m_pParticleProperty->GetTextureAnimationFrameCount()*2+2); + + ///// + + assert(m_kVct_pkImgInst.empty()); + m_kVct_pkImgInst.reserve(m_pParticleProperty->m_ImageVector.size()); + for (DWORD i = 0; i < m_pParticleProperty->m_ImageVector.size(); ++i) + { + CGraphicImage * pImage = m_pParticleProperty->m_ImageVector[i]; + + CGraphicImageInstance* pkImgInstNew = CGraphicImageInstance::New(); + pkImgInstNew->SetImagePointer(pImage); + m_kVct_pkImgInst.push_back(pkImgInstNew); + } +} + +void CParticleSystemInstance::OnInitialize() +{ + m_dwCurrentEmissionCount = 0; + m_iLoopCount = 0; + m_fEmissionResidue = 0.0f; +} + +void CParticleSystemInstance::OnDestroy() +{ + // 2004. 3. 1. myevan. ƼŬ ƾ + TParticleInstanceListVector::iterator i; + for(i = m_ParticleInstanceListVector.begin(); i!=m_ParticleInstanceListVector.end(); ++i) + { + TParticleInstanceList& rkLst_kParticleInst=*i; + + TParticleInstanceList::iterator j; + for(j = rkLst_kParticleInst.begin(); j!=rkLst_kParticleInst.end(); ++j) + { + CParticleInstance* pkParticleInst=*j; + pkParticleInst->DeleteThis(); + } + + rkLst_kParticleInst.clear(); + } + m_ParticleInstanceListVector.clear(); + + std::for_each(m_kVct_pkImgInst.begin(), m_kVct_pkImgInst.end(), CGraphicImageInstance::Delete); + m_kVct_pkImgInst.clear(); +} + +CParticleSystemInstance::CParticleSystemInstance() +{ + Initialize(); +} + +CParticleSystemInstance::~CParticleSystemInstance() +{ + assert(m_ParticleInstanceListVector.empty()); + assert(m_kVct_pkImgInst.empty()); +} diff --git a/source/EffectLib/ParticleSystemInstance.h b/source/EffectLib/ParticleSystemInstance.h new file mode 100644 index 0000000..720a327 --- /dev/null +++ b/source/EffectLib/ParticleSystemInstance.h @@ -0,0 +1,85 @@ +#pragma once + +#include "EffectElementBaseInstance.h" +#include "ParticleInstance.h" +#include "ParticleProperty.h" + +#include "../eterlib/GrpScreen.h" +#include "../eterlib/StateManager.h" +#include "../eterLib/GrpImageInstance.h" +#include "EmitterProperty.h" + +class CParticleSystemInstance : public CEffectElementBaseInstance +{ + public: + static void DestroySystem(); + + static CParticleSystemInstance* New(); + static void Delete(CParticleSystemInstance* pkData); + + static CDynamicPool ms_kPool; + + public: + template + inline void ForEachParticleRendering(T & FunObj) + { + DWORD dwFrameIndex; + for(dwFrameIndex=0; dwFrameIndexGetTextureReference().GetD3DTexture()); + TParticleInstanceList::iterator itor = m_ParticleInstanceListVector[dwFrameIndex].begin(); + for (; itor != m_ParticleInstanceListVector[dwFrameIndex].end(); ++itor) + { + if (!InFrustum(*itor)) + return; + FunObj(*itor); + } + } + } + + CParticleSystemInstance(); + virtual ~CParticleSystemInstance(); + + void OnSetDataPointer(CEffectElementBase * pElement); + + void CreateParticles(float fElapsedTime); + + inline bool InFrustum(CParticleInstance * pInstance) + { + if (m_pParticleProperty->m_bAttachFlag) + return CScreen::GetFrustum().ViewVolumeTest(Vector3d( + pInstance->m_v3Position.x + mc_pmatLocal->_41, + pInstance->m_v3Position.y + mc_pmatLocal->_42, + pInstance->m_v3Position.z + mc_pmatLocal->_43 + ),pInstance->GetRadiusApproximation())!=VS_OUTSIDE; + else + return CScreen::GetFrustum().ViewVolumeTest(Vector3d(pInstance->m_v3Position.x,pInstance->m_v3Position.y,pInstance->m_v3Position.z),pInstance->GetRadiusApproximation())!=VS_OUTSIDE; + } + + DWORD GetEmissionCount(); + + protected: + void OnInitialize(); + void OnDestroy(); + + bool OnUpdate(float fElapsedTime); + void OnRender(); + + protected: + float m_fEmissionResidue; + + DWORD m_dwCurrentEmissionCount; + int m_iLoopCount; + + typedef std::list TParticleInstanceList; + typedef std::vector TParticleInstanceListVector; + TParticleInstanceListVector m_ParticleInstanceListVector; + + typedef std::vector TImageInstanceVector; + TImageInstanceVector m_kVct_pkImgInst; + + CParticleSystemData * m_pData; + + CParticleProperty * m_pParticleProperty; + CEmitterProperty * m_pEmitterProperty; +}; diff --git a/source/EffectLib/SimpleLightData.cpp b/source/EffectLib/SimpleLightData.cpp new file mode 100644 index 0000000..b3fedf4 --- /dev/null +++ b/source/EffectLib/SimpleLightData.cpp @@ -0,0 +1,164 @@ +#include "StdAfx.h" +#include "SimpleLightData.h" + +CDynamicPool CLightData::ms_kPool; + +void CLightData::DestroySystem() +{ + ms_kPool.Destroy(); +} + +CLightData* CLightData::New() +{ + return ms_kPool.Alloc(); +} + +void CLightData::Delete(CLightData* pkData) +{ + pkData->Clear(); + ms_kPool.Free(pkData); +} + + + +void CLightData::OnClear() +{ + m_fMaxRange = 300.0f; + + m_TimeEventTableRange.clear(); + + m_cAmbient.r = 0.5f; + m_cAmbient.g = 0.5f; + m_cAmbient.b = 0.5f; + m_cAmbient.a = 1.0f; + m_cDiffuse.r = 0.0f; + m_cDiffuse.g = 0.0f; + m_cDiffuse.b = 0.0f; + m_cDiffuse.a = 1.0f; + + m_fDuration = 1.0f; + + m_fAttenuation0 = 0.0f; + m_fAttenuation1 = 0.1f; + m_fAttenuation2 = 0.0f; + + m_bLoopFlag = false; + m_iLoopCount = 0; +} +void CLightData::GetRange(float fTime, float& rRange) +{ + if (m_TimeEventTableRange.empty()) + { + rRange = 1.0f * m_fMaxRange; + if (rRange<0.0f) + rRange = 0.0f; + return; + } + + GetTimeEventBlendValue(fTime, m_TimeEventTableRange, &rRange); + rRange *= m_fMaxRange; + if (rRange<0.0f) + rRange = 0.0f; + return; + /* + float vecLastRange = m_TimeEventTableRange[0].m_Value; + + for (DWORD dwIndex = 0; dwIndex < m_TimeEventTableRange.size(); ++dwIndex) + { + if(fTime < m_TimeEventTableRange[dwIndex].m_fTime) + { + break; + } + } + + if (dwIndex >= m_TimeEventTableRange.size()) + { + rRange = m_TimeEventTableRange[m_TimeEventTableRange.size()-1].m_Value * m_fMaxRange; + if (rRange<0.0f) + rRange = 0.0f; + return; + } + + TTimeEventTypeFloat & rEffectRange = m_TimeEventTableRange[dwIndex]; + TTimeEventTypeFloat & rPrevEffectRange = m_TimeEventTableRange[dwIndex-1]; + + float Head = fabs(rEffectRange.m_fTime - fTime) / fabs(rEffectRange.m_fTime - rPrevEffectRange.m_fTime); + float Tail = 1.0f - fabs(rEffectRange.m_fTime - fTime) / fabs(rEffectRange.m_fTime - rPrevEffectRange.m_fTime); + rRange = ((rPrevEffectRange.m_Value*Head) + (rEffectRange.m_Value*Tail) )*m_fMaxRange; + if (rRange<0.0f) + rRange = 0.0f; + */ +} + +bool CLightData::OnIsData() +{ + return true; +} + +BOOL CLightData::OnLoadScript(CTextFileLoader & rTextFileLoader) +{ + if (!rTextFileLoader.GetTokenFloat("duration",&m_fDuration)) + m_fDuration = 1.0f; + + if (!rTextFileLoader.GetTokenBoolean("loopflag",&m_bLoopFlag)) + m_bLoopFlag = false; + + if (!rTextFileLoader.GetTokenInteger("loopcount",&m_iLoopCount)) + m_iLoopCount = 0; + + if (!rTextFileLoader.GetTokenColor("ambientcolor",&m_cAmbient)) + return FALSE; + + if (!rTextFileLoader.GetTokenColor("diffusecolor",&m_cDiffuse)) + return FALSE; + + if (!rTextFileLoader.GetTokenFloat("maxrange",&m_fMaxRange)) + return FALSE; + + if (!rTextFileLoader.GetTokenFloat("attenuation0",&m_fAttenuation0)) + return FALSE; + + if (!rTextFileLoader.GetTokenFloat("attenuation1",&m_fAttenuation1)) + return FALSE; + + if (!rTextFileLoader.GetTokenFloat("attenuation2",&m_fAttenuation2)) + return FALSE; + + if (!GetTokenTimeEventFloat(rTextFileLoader,"timeeventrange",&m_TimeEventTableRange)) + { + m_TimeEventTableRange.clear(); + } + + return true; +} + +CLightData::CLightData() +{ + Clear(); +} + +CLightData::~CLightData() +{ +} + +float CLightData::GetDuration() +{ + return m_fDuration; +} +void CLightData::InitializeLight(D3DLIGHT8& light) +{ + light.Type = D3DLIGHT_POINT; + + light.Ambient = m_cAmbient; + light.Diffuse = m_cDiffuse; + light.Attenuation0 = m_fAttenuation0; + light.Attenuation1 = m_fAttenuation1; + light.Attenuation2 = m_fAttenuation2; + + + D3DXVECTOR3 position; + GetPosition( 0.0f, position); + light.Position = position; + + GetRange(0.0f, light.Range); +} \ No newline at end of file diff --git a/source/EffectLib/SimpleLightData.h b/source/EffectLib/SimpleLightData.h new file mode 100644 index 0000000..d296bf0 --- /dev/null +++ b/source/EffectLib/SimpleLightData.h @@ -0,0 +1,57 @@ +#pragma once + +#include + +#include "../eterLib/TextFileLoader.h" + +#include "Type.h" +#include "EffectElementBase.h" + +class CLightData : public CEffectElementBase +{ + friend class CLightInstance; + public: + CLightData(); + virtual ~CLightData(); + + void GetRange(float fTime, float& rRange); + float GetDuration(); + BOOL isLoop() + { + return m_bLoopFlag; + } + int GetLoopCount() + { + return m_iLoopCount; + } + void InitializeLight(D3DLIGHT8& light); + + protected: + void OnClear(); + bool OnIsData(); + + BOOL OnLoadScript(CTextFileLoader & rTextFileLoader); + + protected: + float m_fMaxRange; + float m_fDuration; + TTimeEventTableFloat m_TimeEventTableRange; + + D3DXCOLOR m_cAmbient; + D3DXCOLOR m_cDiffuse; + + BOOL m_bLoopFlag; + int m_iLoopCount; + + float m_fAttenuation0; + float m_fAttenuation1; + float m_fAttenuation2; + + public: + static void DestroySystem(); + + static CLightData* New(); + static void Delete(CLightData* pkData); + + static CDynamicPool ms_kPool; +}; diff --git a/source/EffectLib/SimpleLightInstance.cpp b/source/EffectLib/SimpleLightInstance.cpp new file mode 100644 index 0000000..0a22410 --- /dev/null +++ b/source/EffectLib/SimpleLightInstance.cpp @@ -0,0 +1,138 @@ +#include "Stdafx.h" +#include "../eterLib/GrpLightManager.h" + +#include "SimpleLightInstance.h" + +CDynamicPool CLightInstance::ms_kPool; + +void CLightInstance::DestroySystem() +{ + ms_kPool.Destroy(); +} + +CLightInstance* CLightInstance::New() +{ + return ms_kPool.Alloc(); +} + +void CLightInstance::Delete(CLightInstance* pkData) +{ + pkData->Destroy(); + ms_kPool.Free(pkData); +} + +void CLightInstance::OnSetDataPointer(CEffectElementBase * pElement) +{ + Destroy(); + + m_pData = ((CLightData*)pElement); + + m_iLoopCount = m_pData->GetLoopCount(); + + D3DLIGHT8 Light; + m_pData->InitializeLight(Light); + CLightManager::Instance().RegisterLight(LIGHT_TYPE_DYNAMIC, &m_LightID, Light); +} + +bool CLightInstance::OnUpdate(float fElapsedTime) +{ + if (!isActive()) + { + Destroy(); + return false; + } + + if (m_fLocalTime >= m_pData->GetDuration()) + { + if (m_pData->isLoop() && --m_iLoopCount!=0) + { + if (m_iLoopCount<0) + m_iLoopCount = 0; + m_fLocalTime -= m_pData->GetDuration(); + } + else + { + Destroy(); + m_iLoopCount = 1; + return false; + } + /* + if (!m_pData->isLoop()) + { + OnClear(); + return false; + } + m_fLocalTime -= m_pData->GetDuration(); + */ + } + + CLight * pLight = CLightManager::Instance().GetLight(m_LightID); + + if (pLight) + { + pLight->SetAmbientColor(m_pData->m_cAmbient.r, m_pData->m_cAmbient.g, m_pData->m_cAmbient.b, m_pData->m_cAmbient.a); + pLight->SetDiffuseColor(m_pData->m_cDiffuse.r, m_pData->m_cDiffuse.g, m_pData->m_cDiffuse.b, m_pData->m_cDiffuse.a); + + /*if (m_pData->m_TimeEventTableRange.size() + && m_fLocalTime>=m_pData->GetDuration()*m_pData->m_TimeEventTableRange[m_dwRangeIndex].m_fTime) + { + while(m_dwRangeIndexm_TimeEventTableRange.size() + && m_fLocalTime>=m_pData->GetDuration()*m_pData->m_TimeEventTableRange[m_dwRangeIndex].m_fTime) + m_dwRangeIndex++; + float fLastTime; + float fLastRange=m_pData->m_TimeEventTableRange[m_pData->m_TimeEventTableRange.size()-1].m_Value; + if (m_dwRangeIndex == m_pData->m_TimeEventTableRange.size()) + fLastTime = 1.0f; + else + { + fLastTime = m_pData->m_TimeEventTableRange[m_dwRangeIndex].m_fTime; + fLastRange = m_pData->m_TimeEventTableRange[m_dwRangeIndex].m_Value; + } + m_dwRangeIndex--; + pLight->BlendRange(fLastRange*m_pData->m_fMaxRange, + (fLastTime-m_pData->m_TimeEventTableRange[m_dwRangeIndex].m_fTime)*m_pData->GetDuration()); + m_dwRangeIndex++; + }*/ + + float fRange; + m_pData->GetRange(m_fLocalTime, fRange); + pLight->SetRange(fRange); + + D3DXVECTOR3 pos; + m_pData->GetPosition(m_fLocalTime,pos); + D3DXVec3TransformCoord(&pos,&pos,mc_pmatLocal); + pLight->SetPosition(pos.x,pos.y,pos.z); + + } + + return true; +} + +void CLightInstance::OnRender() +{ + //OnUpdate(0); +} + +void CLightInstance::OnInitialize() +{ + m_LightID = 0; + m_dwRangeIndex = 0; +} + +void CLightInstance::OnDestroy() +{ + if (m_LightID) + { + CLightManager::Instance().DeleteLight(m_LightID); + } +} + +CLightInstance::CLightInstance() +{ + Initialize(); +} + +CLightInstance::~CLightInstance() +{ + Destroy(); +} diff --git a/source/EffectLib/SimpleLightInstance.h b/source/EffectLib/SimpleLightInstance.h new file mode 100644 index 0000000..a7ad069 --- /dev/null +++ b/source/EffectLib/SimpleLightInstance.h @@ -0,0 +1,39 @@ +#pragma once + +#include "../eterLib/GrpScreen.h" + +#include "EffectElementBaseInstance.h" +#include "SimpleLightData.h" + +class CLightInstance : public CEffectElementBaseInstance +{ + public: + friend class CLightData; + + CLightInstance(); + virtual ~CLightInstance(); + + protected: + + void OnSetDataPointer(CEffectElementBase * pElement); + + void OnInitialize(); + void OnDestroy(); + + bool OnUpdate(float fElapsedTime); + void OnRender(); + + DWORD m_LightID; + CLightData * m_pData; + DWORD m_dwRangeIndex; + + DWORD m_iLoopCount; + + public: + static void DestroySystem(); + + static CLightInstance* New(); + static void Delete(CLightInstance* pkData); + + static CDynamicPool ms_kPool; +}; \ No newline at end of file diff --git a/source/EffectLib/StdAfx.cpp b/source/EffectLib/StdAfx.cpp new file mode 100644 index 0000000..45cf0e1 --- /dev/null +++ b/source/EffectLib/StdAfx.cpp @@ -0,0 +1,2 @@ +#include "StdAfx.h" + diff --git a/source/EffectLib/StdAfx.h b/source/EffectLib/StdAfx.h new file mode 100644 index 0000000..bb26ba8 --- /dev/null +++ b/source/EffectLib/StdAfx.h @@ -0,0 +1,40 @@ +#pragma once + +//#include + +#include "../eterBase/StdAfx.h" + +#include "../eterBase/Utils.h" +#include "../eterBase/Timer.h" +#include "../eterBase/CRC32.h" +#include "../eterBase/Debug.h" + +#include "../eterLib/StdAfx.h" +#include "../eterLib/TextFileLoader.h" + +#include "../milesLib/StdAfx.h" + +/* +#include "FrameController.h" + +#include "EffectElementBase.h" +#include "EffectElementBaseInstance.h" + +#include "ParticleProperty.h" +#include "ParticleInstance.h" +#include "EmitterProperty.h" + +#include "ParticleSystemData.h" +#include "ParticleSystemInstance.h" + +#include "EffectMesh.h" +#include "EffectMeshInstance.h" + +#include "SimpleLightData.h" +#include "SimpleLightInstance.h" + +#include "EffectData.h" +#include "EffectInstance.h" + +#include "EffectManager.h" +*/ \ No newline at end of file diff --git a/source/EffectLib/Type.cpp b/source/EffectLib/Type.cpp new file mode 100644 index 0000000..354412c --- /dev/null +++ b/source/EffectLib/Type.cpp @@ -0,0 +1,38 @@ +#include "StdAfx.h" +#include "Type.h" + +BOOL GetTokenTimeEventFloat(CTextFileLoader & rTextFileLoader, const char * c_szKey, TTimeEventTableFloat * pTimeEventTableFloat) +{ + CTokenVector * pTokenVector; + if (!rTextFileLoader.GetTokenVector(c_szKey, &pTokenVector)) + return FALSE; + + pTimeEventTableFloat->clear(); + pTimeEventTableFloat->resize(pTokenVector->size() / 2); + + DWORD dwIndex = 0; + for (DWORD i = 0; i < pTokenVector->size(); i+=2, ++dwIndex) + { + pTimeEventTableFloat->at(dwIndex).m_fTime = atof(pTokenVector->at(i).c_str()); + pTimeEventTableFloat->at(dwIndex).m_Value = atof(pTokenVector->at(i+1).c_str()); + } + + return TRUE; +} + +void InsertItemTimeEventFloat(TTimeEventTableFloat * pTable, float fTime, float fValue) +{ + TTimeEventTableFloat::iterator itor = pTable->begin(); + for (; itor != pTable->end(); ++itor) + { + TTimeEventTypeFloat & rTimeEvent = *itor; + if (rTimeEvent.m_fTime > fTime) + break; + } + + TTimeEventTypeFloat TimeEvent; + TimeEvent.m_fTime = fTime; + TimeEvent.m_Value = fValue; + + pTable->insert(itor, TimeEvent); +} diff --git a/source/EffectLib/Type.h b/source/EffectLib/Type.h new file mode 100644 index 0000000..ecbd20e --- /dev/null +++ b/source/EffectLib/Type.h @@ -0,0 +1,283 @@ +#pragma once + +#define Clamp(x, min, max) x = (x +class CTimeEvent +{ +public: + CTimeEvent(){} + ~CTimeEvent(){} + + float m_fTime; + T m_Value; +}; +#define AG_MASK 0xff00ff00 +#define RB_MASK 0x00ff00ff + +struct DWORDCOLOR +{ + DWORD m_dwColor; + + DWORDCOLOR() + { + } + DWORDCOLOR(const DWORDCOLOR& r) + : m_dwColor(r.m_dwColor) + {} + + DWORDCOLOR& operator = (const DWORDCOLOR& r) + { + m_dwColor = r.m_dwColor; + return *this; + } + + DWORDCOLOR& operator *= (float f) + { + DWORD idx = DWORD(f * 256); + m_dwColor = + (((DWORD)(((m_dwColor & AG_MASK)>>8) * idx)) & AG_MASK) + +((DWORD)(((m_dwColor & RB_MASK) * idx)>>8) & RB_MASK); + //m_dwColor = + // ((DWORD)((m_dwColor & AG_MASK) * f) & AG_MASK) + // +((DWORD)((m_dwColor & RB_MASK) * f) & RB_MASK); + return *this; + } + DWORDCOLOR& operator += (const DWORDCOLOR& r) + { + m_dwColor += r.m_dwColor; + return *this; + } + operator DWORD() + { + return m_dwColor; + } +}; +#undef AG_MASK +#undef RB_MASK + +inline DWORDCOLOR operator * (DWORDCOLOR dc, float f) +{ + DWORDCOLOR tmp(dc); + tmp *= f; + return tmp; +} + +inline DWORDCOLOR operator * (float f, DWORDCOLOR dc) +{ + DWORDCOLOR tmp(dc); + tmp *= f; + return tmp; +} + +template +__forceinline bool operator < (const CTimeEvent & lhs, const CTimeEvent & rhs) +{ + return lhs.m_fTime < rhs.m_fTime; +} + +template +__forceinline bool operator < (const CTimeEvent & lhs, const float & rhs) +{ + return lhs.m_fTime < rhs; +} + +template +__forceinline bool operator < (const float & lhs, const CTimeEvent & rhs) +{ + return lhs < rhs.m_fTime; +} + +typedef CTimeEvent TTimeEventTypeCharacter; +typedef CTimeEvent TTimeEventTypeShort; +typedef CTimeEvent TTimeEventTypeFloat; +typedef CTimeEvent TTimeEventTypeWord; +typedef CTimeEvent TTimeEventTypeDoubleWord; +typedef CTimeEvent TTimeEventTypeColor; +typedef CTimeEvent TTimeEventTypeVector2; +typedef CTimeEvent TTimeEventTypeVector3; + +typedef std::vector TTimeEventTable; +typedef std::vector TTimeEventTablePosition; +typedef std::vector TTimeEventTableCharacter; +typedef std::vector TTimeEventTableShort; +typedef std::vector TTimeEventTableFloat; +typedef std::vector TTimeEventTableWord; +typedef std::vector TTimeEventTableDoubleWord; +typedef std::vector TTimeEventTableColor; +typedef std::vector TTimeEventTableVector2; +typedef std::vector TTimeEventTableVector3; + + +// NOTE : TimeEventValue Լ Ѱ ƾ ϴ Ƿ +// ƴ ۼ ߽ϴ. - [levites] + +template +__forceinline void GetTimeEventBlendValue(float fElapsedTime, std::vector >& rVector, T * pReturnValue) +{ + if (rVector.empty()) + { + *pReturnValue = T(); + return; + } + + if(rVector.begin()+1==rVector.end()) + { + *pReturnValue = rVector.front().m_Value; + return; + } + + if (fElapsedTime < rVector.front().m_fTime) + { + *pReturnValue = rVector.front().m_Value; + return; + } + + if (fElapsedTime > rVector.back().m_fTime) + { + *pReturnValue = rVector.back().m_Value; + return; + } + + typedef typename std::vector >::iterator iterator; + + std::pair result = std::equal_range(rVector.begin(), rVector.end(), fElapsedTime); + + if (result.first != result.second) + *pReturnValue = result.first->m_Value; + else + { + --result.first; + float Head = (result.second->m_fTime - fElapsedTime) / (result.second->m_fTime - result.first->m_fTime); + *pReturnValue = T((result.first->m_Value-result.second->m_Value)*Head+(result.second->m_Value)); + } + +} + +extern BOOL GetTokenTimeEventFloat(CTextFileLoader & rTextFileLoader, const char * c_szKey, TTimeEventTableFloat * pTimeEventTableFloat); +//extern void InsertItemTimeEventFloat(TTimeEventTableFloat * pTable, float fTime, float fValue); + +template +void InsertItemTimeEvent(std::vector > * pTable, float fTime, T fValue) +{ + typedef std::vector >::iterator iterator; + + iterator itor = std::lower_bound(pTable->begin(), pTable->end(), fTime); + + CTimeEvent TimeEvent; + TimeEvent.m_fTime = fTime; + TimeEvent.m_Value = fValue; + + pTable->insert(itor, TimeEvent); +} diff --git a/source/EterBase/CPostIt.cpp b/source/EterBase/CPostIt.cpp new file mode 100644 index 0000000..60c7f09 --- /dev/null +++ b/source/EterBase/CPostIt.cpp @@ -0,0 +1,299 @@ +#include "StdAfx.h" +#include "CPostIt.h" +#include "../eterBase/utils.h" + +class _CPostItMemoryBlock +{ +public: + _CPostItMemoryBlock( void ); + ~_CPostItMemoryBlock( void ); + + BOOL Assign( HANDLE hBlock ); + HANDLE CreateHandle( void ); + BOOL DestroyHandle( void ); + + LPSTR Find( LPCSTR lpszKeyName ); + BOOL Put( LPCSTR lpBuffer ); + BOOL Put( LPCSTR lpszKeyName, LPCSTR lpBuffer ); + BOOL Get( LPCSTR lpszKeyName, LPSTR lpBuffer, DWORD nSize ); + +protected: + typedef std::list StrList; + typedef StrList::iterator StrListItr; + + HANDLE m_hHandle; + StrList m_StrList; +}; + +CPostIt::CPostIt( LPCSTR szAppName ) : m_pMemoryBlock(NULL), m_bModified(FALSE) +{ + Init( szAppName ); +} + +CPostIt::~CPostIt( void ) +{ + Destroy(); +} + +BOOL CPostIt::Init( LPCSTR szAppName ) +{ + if( szAppName == NULL || !*szAppName ) { + strcpy( m_szClipFormatName, "YMCF" ); + } else { + strcpy( m_szClipFormatName, "YMCF_" ); + strcat( m_szClipFormatName, szAppName ); + } + return TRUE; +} + +BOOL CPostIt::CopyTo( CPostIt *pPostIt, LPCSTR lpszKeyName ) +{ + if( m_pMemoryBlock == NULL ) + return FALSE; + LPSTR szText = m_pMemoryBlock->Find( lpszKeyName ); + if( szText == NULL ) + return FALSE; + return pPostIt->Set( szText ); +} + +BOOL CPostIt::Flush( void ) +{ + if( m_bModified == FALSE ) + return FALSE; + if( m_pMemoryBlock == NULL ) + return FALSE; + UINT uDGPFormat; + + uDGPFormat = ::RegisterClipboardFormatA( m_szClipFormatName ); + if( ::OpenClipboard( NULL ) == FALSE ) + return FALSE; + if( ::SetClipboardData( uDGPFormat, m_pMemoryBlock->CreateHandle() ) == NULL ) { +// DWORD dwLastError = ::GetLastError(); + m_pMemoryBlock->DestroyHandle(); + ::CloseClipboard(); + m_bModified = FALSE; + return FALSE; + } + ::CloseClipboard(); + m_bModified = FALSE; + return TRUE; +} + +void CPostIt::Empty( void ) +{ + SAFE_DELETE( m_pMemoryBlock ); + + UINT uDGPFormat; + + uDGPFormat = ::RegisterClipboardFormatA( m_szClipFormatName ); + if( ::OpenClipboard( NULL ) == FALSE ) + return; + HANDLE hClipboardMemory = ::GetClipboardData( uDGPFormat ); + if( hClipboardMemory ) { +// ::GlobalFree( hClipboardMemory ); + ::SetClipboardData( uDGPFormat, NULL ); + } + ::CloseClipboard(); + + m_bModified = FALSE; +} + +void CPostIt::Destroy( void ) +{ + Flush(); + SAFE_DELETE( m_pMemoryBlock ); +} + +BOOL CPostIt::Set( LPCSTR lpszKeyName, LPCSTR lpBuffer ) +{ + if( m_pMemoryBlock == NULL ) + m_pMemoryBlock = new _CPostItMemoryBlock; + m_pMemoryBlock->Put( lpszKeyName, lpBuffer ); + m_bModified = TRUE; + return TRUE; +} + +BOOL CPostIt::Set( LPCSTR lpszKeyName, DWORD dwValue ) +{ + CHAR szValue[12]; + + _snprintf( szValue, 12, "%d", dwValue ); + return Set( lpszKeyName, szValue ); +} + +BOOL CPostIt::Set( LPCSTR lpBuffer ) +{ + if( lpBuffer == NULL ) + return FALSE; + if( m_pMemoryBlock == NULL ) + m_pMemoryBlock = new _CPostItMemoryBlock; + m_pMemoryBlock->Put( lpBuffer ); + m_bModified = TRUE; + return TRUE; +} + +BOOL CPostIt::Get( LPCSTR lpszKeyName, LPSTR lpBuffer, DWORD nSize ) +{ + if( m_pMemoryBlock == NULL ) { + UINT uDGPFormat; + + uDGPFormat = ::RegisterClipboardFormatA( m_szClipFormatName ); + if( ::OpenClipboard( NULL ) == FALSE ) + return FALSE; + + HANDLE hClipboardMemory = ::GetClipboardData( uDGPFormat ); + + if( hClipboardMemory == NULL ) { + ::CloseClipboard(); + return FALSE; + } + m_pMemoryBlock = new _CPostItMemoryBlock; + m_pMemoryBlock->Assign( hClipboardMemory ); + + ::CloseClipboard(); + } + + return m_pMemoryBlock->Get( lpszKeyName, lpBuffer, nSize ); +} + +_CPostItMemoryBlock::_CPostItMemoryBlock( void ) : m_hHandle( NULL ) +{ +} + +_CPostItMemoryBlock::~_CPostItMemoryBlock( void ) +{ + for( StrListItr itr = m_StrList.begin(); itr != m_StrList.end(); ) { + LPSTR lpszText = *itr; + SAFE_DELETE_ARRAY( lpszText ); + itr = m_StrList.erase( itr ); + } +} + +BOOL _CPostItMemoryBlock::Assign( HANDLE hBlock ) +{ + if( hBlock == NULL || hBlock == INVALID_HANDLE_VALUE ) + return FALSE; + LPBYTE lpBuffer = (LPBYTE) ::GlobalLock( hBlock ); + + if( lpBuffer == NULL ) + return FALSE; + DWORD dwCount = *((LPDWORD) lpBuffer); lpBuffer += sizeof( DWORD ); + for( DWORD dwI=0; dwI < dwCount; dwI++ ) { + WORD wLen = *((LPWORD) lpBuffer); lpBuffer += sizeof( WORD ); + + LPSTR lpszText = new CHAR[ wLen + 1 ]; + ::CopyMemory( lpszText, lpBuffer, wLen ); + lpszText[ wLen ] = '\0'; + + lpBuffer += wLen; + + Put( lpszText ); + } + ::GlobalUnlock( hBlock ); + return TRUE; +} + +HANDLE _CPostItMemoryBlock::CreateHandle( void ) +{ + if( m_StrList.size() == 0 ) + return INVALID_HANDLE_VALUE; + DWORD dwBlockSize = sizeof( DWORD ); + StrListItr itr; + + // Calculation for Memory Block Size + for( itr = m_StrList.begin(); itr != m_StrList.end(); ++itr ) { + dwBlockSize += sizeof( WORD ); + dwBlockSize += (DWORD) strlen( *itr ); + } + + HANDLE hBlock = ::GlobalAlloc( GMEM_ZEROINIT | GMEM_MOVEABLE, dwBlockSize ); + if( hBlock == NULL ) + return INVALID_HANDLE_VALUE; + LPBYTE lpBuffer = (LPBYTE) ::GlobalLock( hBlock ); + if( lpBuffer == NULL ) { + ::GlobalFree( hBlock ); + return INVALID_HANDLE_VALUE; + } + *((LPDWORD) lpBuffer) = (DWORD) m_StrList.size(); lpBuffer += sizeof( DWORD ); + for( itr = m_StrList.begin(); itr != m_StrList.end(); ++itr ) { + *((LPWORD) lpBuffer) = (WORD) strlen( *itr ); lpBuffer += sizeof( WORD ); + ::CopyMemory( lpBuffer, *itr, strlen( *itr ) ); lpBuffer += strlen( *itr ); + } + ::GlobalUnlock( hBlock ); + + m_hHandle = hBlock; + return hBlock; +} + +BOOL _CPostItMemoryBlock::DestroyHandle( void ) +{ + ::GlobalFree( m_hHandle ); + m_hHandle = NULL; + return TRUE; +} + +LPSTR _CPostItMemoryBlock::Find( LPCSTR lpszKeyName ) +{ + for( StrListItr itr = m_StrList.begin(); itr != m_StrList.end(); ++itr ) { + LPSTR lpszText = *itr; + + if( _strnicmp( lpszText, lpszKeyName, strlen( lpszKeyName ) ) != 0 ) + continue; + if( *(lpszText + strlen( lpszKeyName )) != '=' ) + continue; + return lpszText; + } + return NULL; +} + +BOOL _CPostItMemoryBlock::Put( LPCSTR lpszKeyName, LPCSTR lpBuffer ) +{ + LPSTR lpszText; + + if( (lpszText = Find( lpszKeyName )) != NULL ) { + for( StrListItr itr = m_StrList.begin(); itr != m_StrList.end(); ++itr ) { + if( lpszText == *itr ) { + SAFE_DELETE_ARRAY( lpszText ); + m_StrList.erase( itr ); + break; + } + } + } + if( lpBuffer == NULL || !*lpBuffer ) + return TRUE; + size_t nStrLen = strlen( lpszKeyName ) + 1 /* '=' */ + strlen( lpBuffer ); + lpszText = new CHAR[ nStrLen + 1 ]; + ::CopyMemory( lpszText, lpszKeyName, strlen( lpszKeyName ) ); + *(lpszText + strlen( lpszKeyName )) = '='; + ::CopyMemory( lpszText + strlen( lpszKeyName ) + 1, lpBuffer, strlen( lpBuffer ) ); + *(lpszText + nStrLen) = '\0'; + + m_StrList.push_back( lpszText ); + return TRUE; +} + +BOOL _CPostItMemoryBlock::Put( LPCSTR lpBuffer ) +{ + LPSTR lpszText; + + if( lpBuffer == NULL || !*lpBuffer ) + return TRUE; + size_t nStrLen = strlen( lpBuffer ); + lpszText = new CHAR[ nStrLen + 1 ]; + ::CopyMemory( lpszText, lpBuffer, nStrLen ); + *(lpszText + nStrLen) = '\0'; + + m_StrList.push_back( lpszText ); + return TRUE; +} + +BOOL _CPostItMemoryBlock::Get( LPCSTR lpszKeyName, LPSTR lpBuffer, DWORD nSize ) +{ + LPSTR lpszText = Find( lpszKeyName ); + if( lpszText == NULL ) + return FALSE; + lpszText += (strlen( lpszKeyName ) + 1); + ::ZeroMemory( lpBuffer, nSize ); + strncpy( lpBuffer, lpszText, (nSize < strlen( lpszText )) ? nSize : strlen( lpszText ) ); + return TRUE; +} diff --git a/source/EterBase/CPostIt.h b/source/EterBase/CPostIt.h new file mode 100644 index 0000000..d5f00cc --- /dev/null +++ b/source/EterBase/CPostIt.h @@ -0,0 +1,80 @@ +#ifndef _EL_CPOSTIT_H_ +#define _EL_CPOSTIT_H_ + +// _CPostItMemoryBlock is defined in CPostIt.cpp +class _CPostItMemoryBlock; + +/** + * @class CPostIt + * @brief ӷó Ŭ̾Ʈ Ŭ̾Ʈ ϱ Ͽ Ǵ Ŭ + */ +class CPostIt +{ +public: + /** + * @brief CPostIt constructor + * @param [in] szAppName : ̸ . + */ + explicit CPostIt( LPCSTR szAppName ); + + /** + * @brief CPostIt destructor + */ + ~CPostIt( void ); + + /** + * @brief CPostIt class ϰ ִ Ÿ Ŭ忡 Ѵ. + */ + BOOL Flush( void ); + + /** + * @brief CPostIt class ϰ ִ Ÿ Ŭ忡 ִ . + */ + void Empty( void ); + + /** + * @brief Ÿ о´. + * @param [in] lpszKeyName : ҷ Ÿ Ű. "KEY" ִ´. + * @param [in] lpszData : ҷ Ÿ + * @param [in] nSize : lpszData ִ + */ + BOOL Get( LPCSTR lpszKeyName, LPSTR lpszData, DWORD nSize ); + + /** + * @brief Ÿ ִ´. + * @param [in] lpBuffer : Ÿ. "KEY=DATA" ִ´. + */ + BOOL Set( LPCSTR lpszData ); + + /** + * @brief Ÿ ִ´. + * @param [in] lpszKeyName : Ÿ Ű. "KEY" ִ´. + * @param [in] lpszData : Ÿ. "DATA" ִ´. + */ + BOOL Set( LPCSTR lpszKeyName, LPCSTR lpszData ); + + /** + * @brief Ÿ(DWORD) ִ´. + * @param [in] lpBuffer : Ÿ. "KEY=DATA" Ÿ ִ´. + * @param [in] dwValue : Ÿ. (DWORD) + */ + BOOL Set( LPCSTR lpszKeyName, DWORD dwValue ); + + /** + * @brief CPostIt class Ѵ. (Ŭ constructor ̸ ڰ ֱ , ̸ ؾ) + * @param [in] pPostIt : Destination class + * @param [in] lpszKeyName : Destination class's new app-name + */ + BOOL CopyTo( CPostIt *pPostIt, LPCSTR lpszKeyName ); + +protected: + BOOL Init( LPCSTR szAppName ); + void Destroy( void ); + +protected: + BOOL m_bModified; + CHAR m_szClipFormatName[_MAX_PATH]; + _CPostItMemoryBlock* m_pMemoryBlock; +}; + +#endif /* _EL_CPOSTIT_H_ */ diff --git a/source/EterBase/CRC32.cpp b/source/EterBase/CRC32.cpp new file mode 100644 index 0000000..86ab919 --- /dev/null +++ b/source/EterBase/CRC32.cpp @@ -0,0 +1,211 @@ +#include "StdAfx.h" +#include "CRC32.h" + +static unsigned long CRCTable[256] = +{ + 0x00000000,0x77073096,0xEE0E612C,0x990951BA,0x076DC419,0x706AF48F, + 0xE963A535,0x9E6495A3,0x0EDB8832,0x79DCB8A4,0xE0D5E91E,0x97D2D988, + 0x09B64C2B,0x7EB17CBD,0xE7B82D07,0x90BF1D91,0x1DB71064,0x6AB020F2, + 0xF3B97148,0x84BE41DE,0x1ADAD47D,0x6DDDE4EB,0xF4D4B551,0x83D385C7, + 0x136C9856,0x646BA8C0,0xFD62F97A,0x8A65C9EC,0x14015C4F,0x63066CD9, + 0xFA0F3D63,0x8D080DF5,0x3B6E20C8,0x4C69105E,0xD56041E4,0xA2677172, + 0x3C03E4D1,0x4B04D447,0xD20D85FD,0xA50AB56B,0x35B5A8FA,0x42B2986C, + 0xDBBBC9D6,0xACBCF940,0x32D86CE3,0x45DF5C75,0xDCD60DCF,0xABD13D59, + 0x26D930AC,0x51DE003A,0xC8D75180,0xBFD06116,0x21B4F4B5,0x56B3C423, + 0xCFBA9599,0xB8BDA50F,0x2802B89E,0x5F058808,0xC60CD9B2,0xB10BE924, + 0x2F6F7C87,0x58684C11,0xC1611DAB,0xB6662D3D,0x76DC4190,0x01DB7106, + 0x98D220BC,0xEFD5102A,0x71B18589,0x06B6B51F,0x9FBFE4A5,0xE8B8D433, + 0x7807C9A2,0x0F00F934,0x9609A88E,0xE10E9818,0x7F6A0DBB,0x086D3D2D, + 0x91646C97,0xE6635C01,0x6B6B51F4,0x1C6C6162,0x856530D8,0xF262004E, + 0x6C0695ED,0x1B01A57B,0x8208F4C1,0xF50FC457,0x65B0D9C6,0x12B7E950, + 0x8BBEB8EA,0xFCB9887C,0x62DD1DDF,0x15DA2D49,0x8CD37CF3,0xFBD44C65, + 0x4DB26158,0x3AB551CE,0xA3BC0074,0xD4BB30E2,0x4ADFA541,0x3DD895D7, + 0xA4D1C46D,0xD3D6F4FB,0x4369E96A,0x346ED9FC,0xAD678846,0xDA60B8D0, + 0x44042D73,0x33031DE5,0xAA0A4C5F,0xDD0D7CC9,0x5005713C,0x270241AA, + 0xBE0B1010,0xC90C2086,0x5768B525,0x206F85B3,0xB966D409,0xCE61E49F, + 0x5EDEF90E,0x29D9C998,0xB0D09822,0xC7D7A8B4,0x59B33D17,0x2EB40D81, + 0xB7BD5C3B,0xC0BA6CAD,0xEDB88320,0x9ABFB3B6,0x03B6E20C,0x74B1D29A, + 0xEAD54739,0x9DD277AF,0x04DB2615,0x73DC1683,0xE3630B12,0x94643B84, + 0x0D6D6A3E,0x7A6A5AA8,0xE40ECF0B,0x9309FF9D,0x0A00AE27,0x7D079EB1, + 0xF00F9344,0x8708A3D2,0x1E01F268,0x6906C2FE,0xF762575D,0x806567CB, + 0x196C3671,0x6E6B06E7,0xFED41B76,0x89D32BE0,0x10DA7A5A,0x67DD4ACC, + 0xF9B9DF6F,0x8EBEEFF9,0x17B7BE43,0x60B08ED5,0xD6D6A3E8,0xA1D1937E, + 0x38D8C2C4,0x4FDFF252,0xD1BB67F1,0xA6BC5767,0x3FB506DD,0x48B2364B, + 0xD80D2BDA,0xAF0A1B4C,0x36034AF6,0x41047A60,0xDF60EFC3,0xA867DF55, + 0x316E8EEF,0x4669BE79,0xCB61B38C,0xBC66831A,0x256FD2A0,0x5268E236, + 0xCC0C7795,0xBB0B4703,0x220216B9,0x5505262F,0xC5BA3BBE,0xB2BD0B28, + 0x2BB45A92,0x5CB36A04,0xC2D7FFA7,0xB5D0CF31,0x2CD99E8B,0x5BDEAE1D, + 0x9B64C2B0,0xEC63F226,0x756AA39C,0x026D930A,0x9C0906A9,0xEB0E363F, + 0x72076785,0x05005713,0x95BF4A82,0xE2B87A14,0x7BB12BAE,0x0CB61B38, + 0x92D28E9B,0xE5D5BE0D,0x7CDCEFB7,0x0BDBDF21,0x86D3D2D4,0xF1D4E242, + 0x68DDB3F8,0x1FDA836E,0x81BE16CD,0xF6B9265B,0x6FB077E1,0x18B74777, + 0x88085AE6,0xFF0F6A70,0x66063BCA,0x11010B5C,0x8F659EFF,0xF862AE69, + 0x616BFFD3,0x166CCF45,0xA00AE278,0xD70DD2EE,0x4E048354,0x3903B3C2, + 0xA7672661,0xD06016F7,0x4969474D,0x3E6E77DB,0xAED16A4A,0xD9D65ADC, + 0x40DF0B66,0x37D83BF0,0xA9BCAE53,0xDEBB9EC5,0x47B2CF7F,0x30B5FFE9, + 0xBDBDF21C,0xCABAC28A,0x53B39330,0x24B4A3A6,0xBAD03605,0xCDD70693, + 0x54DE5729,0x23D967BF,0xB3667A2E,0xC4614AB8,0x5D681B02,0x2A6F2B94, + 0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D +}; + +#define DO1(buf, i) crc = CRCTable[(crc ^ buf[i]) & 0xff] ^ (crc >> 8) +#define DO2(buf, i) DO1(buf, i); DO1(buf, i + 1); +#define DO4(buf, i) DO2(buf, i); DO2(buf, i + 2); +#define DO8(buf, i) DO4(buf, i); DO4(buf, i + 4); +#define DO16(buf, i) DO8(buf, i); DO8(buf, i + 8); + +DWORD GetCRC32(const char * buf, size_t len) +{ + DWORD crc = 0xffffffff; + + if (len >= 16) + { + do + { + DO16(buf, 0); + + buf += 16; + len -= 16; + } while (len >= 16); + } + + if (len != 0) + { + do + { + DO1(buf, 0); + ++buf; + --len; + } while (len > 0); + } + + crc ^= 0xffffffff; + return crc; +} + +#ifndef UPPER +#define UPPER(c) (((c)>='a' && (c) <= 'z') ? ((c)+('A'-'a')) : (c)) +#endif + +#define DO1CI(buf, i) crc = CRCTable[(crc ^ UPPER(buf[i])) & 0xff] ^ (crc >> 8) +#define DO2CI(buf, i) DO1CI(buf, i); DO1CI(buf, i + 1); +#define DO4CI(buf, i) DO2CI(buf, i); DO2CI(buf, i + 2); +#define DO8CI(buf, i) DO4CI(buf, i); DO4CI(buf, i + 4); +#define DO16CI(buf, i) DO8CI(buf, i); DO8CI(buf, i + 8); + +DWORD GetCaseCRC32(const char * buf, size_t len) +{ + DWORD crc = 0xffffffff; + + if (16 <= len) + { + do + { + DO16CI(buf, 0); + + buf += 16; + len -= 16; + } while (len >= 16); + } + + if (0 != len) + { + do + { + DO1CI(buf, 0); + + ++buf; + --len; + } while (len > 0); + } + + crc ^= 0xffffffff; + return crc; +} + +DWORD GetHFILECRC32(HANDLE hFile) +{ + DWORD dwRetCRC32=0; + + DWORD dwFileSize = GetFileSize(hFile, NULL); + + DWORD dataOffset=0; + DWORD mapSize=dwFileSize; + + SYSTEM_INFO SysInfo; + GetSystemInfo(&SysInfo); + + DWORD dwSysGran = SysInfo.dwAllocationGranularity; + DWORD dwFileMapStart = (dataOffset / dwSysGran) * dwSysGran; + DWORD dwMapViewSize = (dataOffset % dwSysGran) + mapSize; + //INT iViewDelta = dataOffset - dwFileMapStart; + + HANDLE hFM = CreateFileMapping(hFile, // handle + NULL, // security + PAGE_READONLY, // flProtect + 0, // high + dataOffset + mapSize, // low + NULL); // name + if (hFM) + { + LPVOID lpMapData = MapViewOfFile(hFM, + FILE_MAP_READ, + 0, + dwFileMapStart, + dwMapViewSize); + + dwRetCRC32=GetCRC32((const char*)lpMapData, dwFileSize); + + + if (lpMapData) + { + + UnmapViewOfFile(lpMapData); + } + + CloseHandle(hFM); + } + + return dwRetCRC32; +} + +DWORD GetFileCRC32(const char* c_szFileName) +{ + HANDLE hFile = CreateFile(c_szFileName, // name of the file + GENERIC_READ, // desired access + FILE_SHARE_READ, // share mode + NULL, // security attributes + OPEN_EXISTING, // creation disposition + FILE_ATTRIBUTE_NORMAL, // flags and attr + NULL); // template file + + if (INVALID_HANDLE_VALUE == hFile) + return 0; + + + DWORD dwRetCRC32=GetHFILECRC32(hFile); + + CloseHandle(hFile); + + return dwRetCRC32; +} + +DWORD GetFileSize(const char* c_szFileName) +{ + HANDLE hFile = CreateFile(c_szFileName, // name of the file + GENERIC_READ, // desired access + FILE_SHARE_READ, // share mode + NULL, // security attributes + OPEN_EXISTING, // creation disposition + FILE_ATTRIBUTE_NORMAL, // flags and attr + NULL); // template file + + if (INVALID_HANDLE_VALUE == hFile) + return 0; + + DWORD dwSize = GetFileSize(hFile, NULL); + + CloseHandle(hFile); + + return dwSize; +} diff --git a/source/EterBase/CRC32.h b/source/EterBase/CRC32.h new file mode 100644 index 0000000..ee515cf --- /dev/null +++ b/source/EterBase/CRC32.h @@ -0,0 +1,12 @@ +#ifndef __INC_CRC32_H__ +#define __INC_CRC32_H__ + +#include + +DWORD GetCRC32(const char* buffer, size_t count); +DWORD GetCaseCRC32(const char * buf, size_t len); +DWORD GetHFILECRC32(HANDLE hFile); +DWORD GetFileCRC32(const char* c_szFileName); +DWORD GetFileSize(const char* c_szFileName); + +#endif diff --git a/source/EterBase/Debug.cpp b/source/EterBase/Debug.cpp new file mode 100644 index 0000000..74f0191 --- /dev/null +++ b/source/EterBase/Debug.cpp @@ -0,0 +1,326 @@ +#include "StdAfx.h" + +#include +#include +#include "Debug.h" +#include "Singleton.h" +#include "Timer.h" + +const DWORD DEBUG_STRING_MAX_LEN = 1024; + +static int isLogFile = false; +HWND g_PopupHwnd = NULL; + +class CLogFile : public CSingleton +{ + public: + CLogFile() : m_fp(NULL) + { + } + + virtual ~CLogFile() + { + if (m_fp) + fclose(m_fp); + + m_fp = NULL; + } + + void Initialize() + { + m_fp = fopen("log.txt", "w"); + } + + void Write(const char * c_pszMsg) + { + if (!m_fp) + return; + + time_t ct = time(0); + struct tm ctm = *localtime(&ct); + + fprintf(m_fp, "%02d%02d %02d:%02d:%05d :: %s", + ctm.tm_mon + 1, + ctm.tm_mday, + ctm.tm_hour, + ctm.tm_min, + ELTimer_GetMSec() % 60000, + c_pszMsg); + + fflush(m_fp); + } + + protected: + FILE * m_fp; +}; + +static CLogFile gs_logfile; + +static UINT gs_uLevel=0; + +void SetLogLevel(UINT uLevel) +{ + gs_uLevel=uLevel; +} + +void Log(UINT uLevel, const char* c_szMsg) +{ + if (uLevel>=gs_uLevel) + Trace(c_szMsg); +} + +void Logn(UINT uLevel, const char* c_szMsg) +{ + if (uLevel>=gs_uLevel) + Tracen(c_szMsg); +} + +void Logf(UINT uLevel, const char* c_szFormat, ...) +{ + if (uLevel 0) + { + szBuf[len] = '\n'; + szBuf[len + 1] = '\0'; + } + va_end(args); +#ifdef _DEBUG + OutputDebugString(szBuf); + puts(szBuf); +#endif + + if (isLogFile) + LogFile(szBuf); +} + + +void Trace(const char * c_szMsg) +{ +#ifdef _DEBUG + OutputDebugString(c_szMsg); + printf("%s", c_szMsg); +#endif + + if (isLogFile) + LogFile(c_szMsg); +} + +void Tracen(const char* c_szMsg) +{ +#ifdef _DEBUG + char szBuf[DEBUG_STRING_MAX_LEN+1]; + _snprintf(szBuf, sizeof(szBuf), "%s\n", c_szMsg); + OutputDebugString(szBuf); + puts(c_szMsg); + + if (isLogFile) + LogFile(szBuf); + + puts(c_szMsg); + putc('\n', stdout); +#else + if (isLogFile) + { + LogFile(c_szMsg); + LogFile("\n"); + } +#endif +} + +void Tracenf(const char* c_szFormat, ...) +{ + va_list args; + va_start(args, c_szFormat); + + char szBuf[DEBUG_STRING_MAX_LEN+2]; + int len = _vsnprintf(szBuf, sizeof(szBuf)-1, c_szFormat, args); + + if (len > 0) + { + szBuf[len] = '\n'; + szBuf[len + 1] = '\0'; + } + va_end(args); +#ifdef _DEBUG + OutputDebugString(szBuf); + printf("%s", szBuf); +#endif + + if (isLogFile) + LogFile(szBuf); +} + +void Tracef(const char* c_szFormat, ...) +{ + char szBuf[DEBUG_STRING_MAX_LEN+1]; + + va_list args; + va_start(args, c_szFormat); + _vsnprintf(szBuf, sizeof(szBuf), c_szFormat, args); + va_end(args); + +#ifdef _DEBUG + OutputDebugString(szBuf); + fputs(szBuf, stdout); +#endif + + if (isLogFile) + LogFile(szBuf); +} + +void TraceError(const char* c_szFormat, ...) +{ +#ifndef _DISTRIBUTE + + char szBuf[DEBUG_STRING_MAX_LEN+2]; + + strncpy(szBuf, "SYSERR: ", DEBUG_STRING_MAX_LEN); + int len = strlen(szBuf); + + va_list args; + va_start(args, c_szFormat); + len = _vsnprintf(szBuf + len, sizeof(szBuf) - (len + 1), c_szFormat, args) + len; + va_end(args); + + szBuf[len] = '\n'; + szBuf[len + 1] = '\0'; + + time_t ct = time(0); + struct tm ctm = *localtime(&ct); + + fprintf(stderr, "%02d%02d %02d:%02d:%05d :: %s", + ctm.tm_mon + 1, + ctm.tm_mday, + ctm.tm_hour, + ctm.tm_min, + ELTimer_GetMSec() % 60000, + szBuf + 8); + fflush(stderr); + +#ifdef _DEBUG + OutputDebugString(szBuf); + fputs(szBuf, stdout); +#endif + + if (isLogFile) + LogFile(szBuf); + +#endif +} + +void TraceErrorWithoutEnter(const char* c_szFormat, ...) +{ +#ifndef _DISTRIBUTE + + char szBuf[DEBUG_STRING_MAX_LEN]; + + va_list args; + va_start(args, c_szFormat); + _vsnprintf(szBuf, sizeof(szBuf), c_szFormat, args); + va_end(args); + + time_t ct = time(0); + struct tm ctm = *localtime(&ct); + + fprintf(stderr, "%02d%02d %02d:%02d:%05d :: %s", + ctm.tm_mon + 1, + ctm.tm_mday, + ctm.tm_hour, + ctm.tm_min, + ELTimer_GetMSec() % 60000, + szBuf + 8); + fflush(stderr); + +#ifdef _DEBUG + OutputDebugString(szBuf); + fputs(szBuf, stdout); +#endif + + if (isLogFile) + LogFile(szBuf); +#endif +} + +void LogBoxf(const char* c_szFormat, ...) +{ + va_list args; + va_start(args, c_szFormat); + + char szBuf[2048]; + _vsnprintf(szBuf, sizeof(szBuf), c_szFormat, args); + + LogBox(szBuf); +} + +void LogBox(const char* c_szMsg, const char * c_szCaption, HWND hWnd) +{ + if (!hWnd) + hWnd = g_PopupHwnd; + + MessageBox(hWnd, c_szMsg, c_szCaption ? c_szCaption : "LOG", MB_OK); + Tracen(c_szMsg); +} + +void LogFile(const char * c_szMsg) +{ + CLogFile::Instance().Write(c_szMsg); +} + +void LogFilef(const char * c_szMessage, ...) +{ + va_list args; + va_start(args, c_szMessage); + char szBuf[DEBUG_STRING_MAX_LEN+1]; + _vsnprintf(szBuf, sizeof(szBuf), c_szMessage, args); + + CLogFile::Instance().Write(szBuf); +} + +void OpenLogFile(bool bUseLogFIle) +{ +#ifndef _DISTRIBUTE + freopen("syserr.txt", "w", stderr); + + if (bUseLogFIle) + { + isLogFile = true; + CLogFile::Instance().Initialize(); + } +#endif +} + +void OpenConsoleWindow() +{ + AllocConsole(); + + freopen("CONOUT$", "a", stdout); + freopen("CONIN$", "r", stdin); +} diff --git a/source/EterBase/Debug.h b/source/EterBase/Debug.h new file mode 100644 index 0000000..7058e44 --- /dev/null +++ b/source/EterBase/Debug.h @@ -0,0 +1,40 @@ +#ifndef __INC_ETERLIB_DEBUG_H__ +#define __INC_ETERLIB_DEBUG_H__ + +#include + +extern void SetLogLevel(UINT uLevel); +extern void Log(UINT uLevel, const char* c_szMsg); +extern void Logn(UINT uLevel, const char* c_szMsg); +extern void Logf(UINT uLevel, const char* c_szFormat, ...); +extern void Lognf(UINT uLevel, const char* c_szFormat, ...); + +extern void Trace(const char* c_szMsg); +extern void Tracen(const char* c_szMsg); +extern void Tracenf(const char* c_szFormat, ...); +extern void Tracef(const char* c_szFormat, ...); +extern void TraceError(const char* c_szFormat, ...); +extern void TraceErrorWithoutEnter(const char* c_szFormat, ...); + +extern void LogBox(const char* c_szMsg, const char * c_szCaption = NULL, HWND hWnd = NULL); +extern void LogBoxf(const char* c_szMsg, ...); + +extern void LogFile(const char* c_szMsg); +extern void LogFilef(const char * c_szMessage, ...); +extern void OpenConsoleWindow(void); +extern void CloseConsoleWindow(); +extern void SetupLog(void); + +extern void OpenLogFile(bool bUseLogFile = true); +extern void CloseLogFile(); + +extern HWND g_PopupHwnd; + +#define CHECK_RETURN(flag, string) \ + if (flag) \ + { \ + LogBox(string); \ + return; \ + } \ + +#endif diff --git a/source/EterBase/FileBase.cpp b/source/EterBase/FileBase.cpp new file mode 100644 index 0000000..b9174bd --- /dev/null +++ b/source/EterBase/FileBase.cpp @@ -0,0 +1,115 @@ +#include "StdAfx.h" +#include "FileBase.h" + +CFileBase::CFileBase() : m_hFile(NULL), m_dwSize(0) +{ +} + +CFileBase::~CFileBase() +{ + Destroy(); +} + +char * CFileBase::GetFileName() +{ + return m_filename; +} + +void CFileBase::Destroy() +{ + Close(); + m_dwSize = 0; +} + +void CFileBase::Close() +{ + if (m_hFile) + { + CloseHandle(m_hFile); + m_hFile = NULL; + } +} + +BOOL CFileBase::Create(const char* filename, EFileMode mode) +{ + Destroy(); + + strncpy(m_filename, filename, MAX_PATH); + + DWORD dwMode, dwShareMode = FILE_SHARE_READ; + + if (mode == FILEMODE_WRITE) + { + dwMode = GENERIC_READ | GENERIC_WRITE; + dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; + } + else + dwMode = GENERIC_READ; + + m_hFile = CreateFile(filename, // name of the file + dwMode, // desired access + dwShareMode, // share mode + NULL, // security attributes + mode == FILEMODE_READ ? OPEN_EXISTING : OPEN_ALWAYS, // creation disposition + FILE_ATTRIBUTE_NORMAL, // flags and attr + NULL); // template file + + if (m_hFile != INVALID_HANDLE_VALUE) + { + m_dwSize = GetFileSize(m_hFile, NULL); + m_mode = mode; + return true; + } + +/* char buf[256]; + GetCurrentDirectory(256, buf); + DWORD dwErr = GetLastError();*/ + m_hFile = NULL; + return false; +} + +DWORD CFileBase::Size() +{ + return (m_dwSize); +} + +void CFileBase::SeekCur(DWORD size) +{ + SetFilePointer(m_hFile, size, NULL, FILE_CURRENT); +} + +void CFileBase::Seek(DWORD offset) +{ + if (offset > m_dwSize) + offset = m_dwSize; + + SetFilePointer(m_hFile, offset, NULL, FILE_BEGIN); +} + +DWORD CFileBase::GetPosition() +{ + return SetFilePointer(m_hFile, 0, NULL, FILE_CURRENT); +} + +BOOL CFileBase::Write(const void* src, int bytes) +{ + DWORD dwUseless; + BOOL ret = WriteFile(m_hFile, src, bytes, &dwUseless, NULL); + + if (!ret) + return false; + + m_dwSize = GetFileSize(m_hFile, NULL); + return true; +} + +BOOL CFileBase::Read(void* dest, int bytes) +{ + DWORD dwUseless; + return ReadFile(m_hFile, dest, bytes, &dwUseless, NULL); +} + +BOOL CFileBase::IsNull() +{ + return !m_hFile ? true : false; +} diff --git a/source/EterBase/FileBase.h b/source/EterBase/FileBase.h new file mode 100644 index 0000000..54538ed --- /dev/null +++ b/source/EterBase/FileBase.h @@ -0,0 +1,40 @@ +#ifndef __INC_ETERBASE_FILEBASE_H__ +#define __INC_ETERBASE_FILEBASE_H__ + +#include + +class CFileBase +{ + public: + enum EFileMode + { + FILEMODE_READ = (1 << 0), + FILEMODE_WRITE = (1 << 1) + }; + + CFileBase(); + virtual ~CFileBase(); + + void Destroy(); + void Close(); + + BOOL Create(const char* filename, EFileMode mode); + DWORD Size(); + void SeekCur(DWORD size); + void Seek(DWORD offset); + DWORD GetPosition(); + + virtual BOOL Write(const void* src, int bytes); + BOOL Read(void* dest, int bytes); + + char* GetFileName(); + BOOL IsNull(); + + protected: + int m_mode; + char m_filename[MAX_PATH+1]; + HANDLE m_hFile; + DWORD m_dwSize; +}; + +#endif diff --git a/source/EterBase/FileDir.cpp b/source/EterBase/FileDir.cpp new file mode 100644 index 0000000..8a20745 --- /dev/null +++ b/source/EterBase/FileDir.cpp @@ -0,0 +1,105 @@ +#include "StdAfx.h" +#include "FileDir.h" +#include + +CDir::CDir() +{ + Initialize(); +} + +CDir::~CDir() +{ + Destroy(); +} + +void CDir::Destroy() +{ + if (m_hFind) + FindClose(m_hFind); + + Initialize(); +} + +bool CDir::Create(const char * c_szFilter, const char* c_szPath, BOOL bCheckedExtension) +{ + Destroy(); + + std::string stPath = c_szPath; + + if (stPath.length()) + { + char end = stPath[stPath.length() - 1]; + + if (end != '\\') + stPath+='\\'; + } + + std::string stQuery; + stQuery += stPath; + stQuery += "*.*"; + + m_wfd.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY; + m_hFind = FindFirstFile(stQuery.c_str(), &m_wfd); + + if (m_hFind == INVALID_HANDLE_VALUE) + return true; + + do + { + if (*m_wfd.cFileName == '.') + continue; + + if (IsFolder()) + { + if (!OnFolder(c_szFilter, stPath.c_str(), m_wfd.cFileName)) + return false; + } + else + { + const char * c_szExtension = strchr(m_wfd.cFileName, '.'); + if (!c_szExtension) + continue; + + // NOTE : ӽ - [levites] + // δ TRUE · . + // Ʈ CDir ϴ Extension "wav", "gr2" ̷ ְԲ Ѵ. - [levites] + if (bCheckedExtension) + { + std::string strFilter = c_szFilter; + int iPos = strFilter.find_first_of(';', 0); + if (iPos > 0) + { + std::string strFirstFilter = std::string(c_szFilter).substr(0, iPos); + std::string strSecondFilter = std::string(c_szFilter).substr(iPos+1, strlen(c_szFilter)); + if (0 != strFirstFilter.compare(c_szExtension+1) && 0 != strSecondFilter.compare(c_szExtension+1)) + continue; + } + else + { + if (0 != stricmp(c_szExtension+1, c_szFilter)) + continue; + } + } + + if (!OnFile(stPath.c_str(), m_wfd.cFileName)) + return false; + } + } + while (FindNextFile(m_hFind, &m_wfd)); + + return true; +} + +bool CDir::IsFolder() +{ + if (m_wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + return true; + + return false; +} + +void CDir::Initialize() +{ + memset(&m_wfd, 0, sizeof(m_wfd)); + m_hFind = NULL; +} diff --git a/source/EterBase/FileDir.h b/source/EterBase/FileDir.h new file mode 100644 index 0000000..22aa1c4 --- /dev/null +++ b/source/EterBase/FileDir.h @@ -0,0 +1,30 @@ +#ifndef __ETER_FILE_DIR__ +#define __ETER_FILE_DIR__ + +#include + +class CDir +{ + public: + CDir(); + virtual ~CDir(); + + void Destroy(); + bool Create(const char* c_szFilter, const char* c_szPath="", BOOL bCheckedExtension = FALSE); + + protected: + virtual bool OnFolder(const char* c_szFilter, const char* c_szPath, const char* c_szName) = 0; + virtual bool OnFile(const char* c_szPath, const char* c_szName) = 0; + + protected: + bool IsFolder(); + + void Initialize(); + + protected: + WIN32_FIND_DATA m_wfd; + HANDLE m_hFind; +}; + + +#endif \ No newline at end of file diff --git a/source/EterBase/FileLoader.cpp b/source/EterBase/FileLoader.cpp new file mode 100644 index 0000000..8414436 --- /dev/null +++ b/source/EterBase/FileLoader.cpp @@ -0,0 +1,288 @@ +#include "StdAfx.h" +#include "FileLoader.h" +#include + +CMemoryTextFileLoader::CMemoryTextFileLoader() +{ +} + +CMemoryTextFileLoader::~CMemoryTextFileLoader() +{ +} + +bool CMemoryTextFileLoader::SplitLineByTab(DWORD dwLine, CTokenVector* pstTokenVector) +{ + pstTokenVector->reserve(10); + pstTokenVector->clear(); + + const std::string & c_rstLine = GetLineString(dwLine); + const int c_iLineLength = c_rstLine.length(); + + if (0 == c_iLineLength) + return false; + + int basePos = 0; + + do + { + int beginPos = c_rstLine.find_first_of("\t", basePos); + + pstTokenVector->push_back(c_rstLine.substr(basePos, beginPos-basePos)); + + basePos = beginPos+1; + } while (basePos < c_iLineLength && basePos > 0); + + return true; +} + +int CMemoryTextFileLoader::SplitLine2(DWORD dwLine, CTokenVector* pstTokenVector, const char * c_szDelimeter) +{ + pstTokenVector->reserve(10); + pstTokenVector->clear(); + + std::string stToken; + const std::string & c_rstLine = GetLineString(dwLine); + + DWORD basePos = 0; + + do + { + int beginPos = c_rstLine.find_first_not_of(c_szDelimeter, basePos); + + if (beginPos < 0) + return -1; + + int endPos; + + if (c_rstLine[beginPos] == '"') + { + ++beginPos; + endPos = c_rstLine.find_first_of("\"", beginPos); + + if (endPos < 0) + return -2; + + basePos = endPos + 1; + } + else + { + endPos = c_rstLine.find_first_of(c_szDelimeter, beginPos); + basePos = endPos; + } + + pstTokenVector->push_back(c_rstLine.substr(beginPos, endPos - beginPos)); + + // ߰ ڵ. ǵڿ ִ 츦 üũѴ. - [levites] + if (int(c_rstLine.find_first_not_of(c_szDelimeter, basePos)) < 0) + break; + } while (basePos < c_rstLine.length()); + + return 0; +} + +bool CMemoryTextFileLoader::SplitLine(DWORD dwLine, CTokenVector* pstTokenVector, const char * c_szDelimeter) +{ + pstTokenVector->reserve(10); + pstTokenVector->clear(); + + std::string stToken; + const std::string & c_rstLine = GetLineString(dwLine); + + DWORD basePos = 0; + + do + { + int beginPos = c_rstLine.find_first_not_of(c_szDelimeter, basePos); + if (beginPos < 0) + return false; + + int endPos; + + if (c_rstLine[beginPos] == '"') + { + ++beginPos; + endPos = c_rstLine.find_first_of("\"", beginPos); + + if (endPos < 0) + return false; + + basePos = endPos + 1; + } + else + { + endPos = c_rstLine.find_first_of(c_szDelimeter, beginPos); + basePos = endPos; + } + + pstTokenVector->push_back(c_rstLine.substr(beginPos, endPos - beginPos)); + + // ߰ ڵ. ǵڿ ִ 츦 üũѴ. - [levites] + if (int(c_rstLine.find_first_not_of(c_szDelimeter, basePos)) < 0) + break; + } while (basePos < c_rstLine.length()); + + return true; +} + +DWORD CMemoryTextFileLoader::GetLineCount() +{ + return m_stLineVector.size(); +} + +bool CMemoryTextFileLoader::CheckLineIndex(DWORD dwLine) +{ + if (dwLine >= m_stLineVector.size()) + return false; + + return true; +} + +const std::string & CMemoryTextFileLoader::GetLineString(DWORD dwLine) +{ + assert(CheckLineIndex(dwLine)); + return m_stLineVector[dwLine]; +} + +void CMemoryTextFileLoader::Bind(int bufSize, const void* c_pvBuf) +{ + m_stLineVector.reserve(128); + m_stLineVector.clear(); + + const char * c_pcBuf = (const char *)c_pvBuf; + std::string stLine; + int pos = 0; + + while (pos < bufSize) + { + const char c = c_pcBuf[pos++]; + + if ('\n' == c || '\r' == c) + { + if (pos < bufSize) + if ('\n' == c_pcBuf[pos] || '\r' == c_pcBuf[pos]) + ++pos; + + m_stLineVector.push_back(stLine); + stLine = ""; + } + else if (c < 0) + { + stLine.append(c_pcBuf + (pos-1), 2); + ++pos; + } + else + { + stLine += c; + } + } + + m_stLineVector.push_back(stLine); +} + +////////////////////////////////////////////////////////////////////////////////////////////////// +int CMemoryFileLoader::GetSize() +{ + return m_size; +} + +int CMemoryFileLoader::GetPosition() +{ + return m_pos; +} + +bool CMemoryFileLoader::IsReadableSize(int size) +{ + if (m_pos + size > m_size) + return false; + + return true; +} + +bool CMemoryFileLoader::Read(int size, void* pvDst) +{ + if (!IsReadableSize(size)) + return false; + + memcpy(pvDst, GetCurrentPositionPointer(), size); + m_pos += size; + return true; +} + +const char* CMemoryFileLoader::GetCurrentPositionPointer() +{ + assert(m_pcBase != NULL); + return (m_pcBase + m_pos); +} + +CMemoryFileLoader::CMemoryFileLoader(int size, const void* c_pvMemoryFile) +{ + assert(c_pvMemoryFile != NULL); + + m_pos = 0; + m_size = size; + m_pcBase = (const char *) c_pvMemoryFile; +} + +CMemoryFileLoader::~CMemoryFileLoader() +{ +} + +////////////////////////////////////////////////////////////////////////////////////////////////// +int CDiskFileLoader::GetSize() +{ + return m_size; +} + +bool CDiskFileLoader::Read(int size, void* pvDst) +{ + assert(m_fp != NULL); + + int ret = fread(pvDst, size, 1, m_fp); + + if (ret <= 0) + return false; + + return true; +} + +bool CDiskFileLoader::Open(const char* c_szFileName) +{ + Close(); + + if (!c_szFileName[0]) + return false; + + m_fp = fopen(c_szFileName, "rb"); + + if (!m_fp) + return false; + + fseek(m_fp, 0, SEEK_END); + m_size = ftell(m_fp); + fseek(m_fp, 0, SEEK_SET); + return true; +} + +void CDiskFileLoader::Close() +{ + if (m_fp) + fclose(m_fp); + + Initialize(); +} + +void CDiskFileLoader::Initialize() +{ + m_fp = NULL; + m_size = 0; +} + +CDiskFileLoader::CDiskFileLoader() +{ + Initialize(); +} + +CDiskFileLoader::~CDiskFileLoader() +{ + Close(); +} diff --git a/source/EterBase/FileLoader.h b/source/EterBase/FileLoader.h new file mode 100644 index 0000000..90d8b7d --- /dev/null +++ b/source/EterBase/FileLoader.h @@ -0,0 +1,71 @@ +#pragma once + +#pragma warning(disable:4786) // character 255 Ѿ° + +#include +#include +#include + +#include "Stl.h" + +class CMemoryTextFileLoader +{ + public: + CMemoryTextFileLoader(); + virtual ~CMemoryTextFileLoader(); + + void Bind(int bufSize, const void* c_pvBuf); + DWORD GetLineCount(); + bool CheckLineIndex(DWORD dwLine); + bool SplitLine(DWORD dwLine, CTokenVector * pstTokenVector, const char * c_szDelimeter = " \t"); + int SplitLine2(DWORD dwLine, CTokenVector * pstTokenVector, const char * c_szDelimeter = " \t"); + bool SplitLineByTab(DWORD dwLine, CTokenVector* pstTokenVector); + const std::string & GetLineString(DWORD dwLine); + + protected: + std::vector m_stLineVector; +}; + +class CMemoryFileLoader +{ + public: + CMemoryFileLoader(int size, const void * c_pvMemoryFile); + virtual ~CMemoryFileLoader(); + + bool Read(int size, void* pvDst); + + int GetPosition(); + int GetSize(); + + protected: + bool IsReadableSize(int size); + const char * GetCurrentPositionPointer(); + + protected: + const char * m_pcBase; + int m_size; + int m_pos; +}; + +////////////////////////////////////////////////////////////////////////////////////////////////// +class CDiskFileLoader +{ + public: + CDiskFileLoader(); + virtual ~CDiskFileLoader(); + + void Close(); + bool Open(const char * c_szFileName); + bool Read(int size, void * pvDst); + + int GetSize(); + + protected: + void Initialize(); + + protected: + FILE * m_fp; + int m_size; +}; + +typedef std::map TStringMap; \ No newline at end of file diff --git a/source/EterBase/Filename.h b/source/EterBase/Filename.h new file mode 100644 index 0000000..1a6313e --- /dev/null +++ b/source/EterBase/Filename.h @@ -0,0 +1,254 @@ +/////////////////////////////////////////////////////////////////////// +// CFilename Class +// +// (c) 2003 IDV, Inc. +// +// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION *** +// +// This software is supplied under the terms of a license agreement or +// nondisclosure agreement with Interactive Data Visualization and may +// not be copied or disclosed except in accordance with the terms of +// that agreement. +// +// Copyright (c) 2001-2003 IDV, Inc. +// All Rights Reserved. +// +// IDV, Inc. +// 1233 Washington St. Suite 610 +// Columbia, SC 29201 +// Voice: (803) 799-1699 +// Fax: (803) 931-0320 +// Web: http://www.idvinc.com +// + + +#pragma once +#include + +/////////////////////////////////////////////////////////////////////// +// CFilename Class + +//class CFilename +//{ +// public: +// CFilename() { } +// CFilename(const char* pFilename) { m_sRaw = pFilename; } +// CFilename(std::string strFilename) { m_sRaw = strFilename; } +// +// virtual ~CFilename() {} +// +// operator const std::string() const { return m_sRaw; } +// operator std::string&() { return m_sRaw; } +// CFilename& operator =(const CFilename& r) { m_sRaw = r.m_sRaw; return *this; } +// bool operator ==(const CFilename& r) const { return m_sRaw == r.m_sRaw; } +// CFilename operator +(const CFilename& r) const { return CFilename(m_sRaw + r.m_sRaw); } +// CFilename& operator +=(const CFilename& r) { m_sRaw += r.m_sRaw; return *this; } +// const char& operator[](size_t nIdx) const { return m_sRaw[nIdx]; } +// const char* c_str() const { return m_sRaw.c_str(); } +// size_t find(const char* pcszSrc) const { return m_sRaw.find(pcszSrc); } +// bool empty() const { return m_sRaw.empty(); } +// size_t size() const { return m_sRaw.size(); } +// size_t length() const { return m_sRaw.length(); } +// +// string& GetString() { return m_sRaw; } +// +// void ChangeDosPath() +// { +// size_t nLength = m_sRaw.length(); +// +// for (size_t i = 0; i < nLength; ++i) +// { +// if (m_sRaw.at(i) == '/') +// m_sRaw.at(i) = '\\'; +// } +// } +// +// void std::stringPath() +// { +// size_t nLength = m_sRaw.length(); +// +// for (size_t i = 0; i 0) + { + size_t iExtensionStartPos = nLength - 1; + + for (size_t i = nLength - 1; i > 0; i--) + { + if (str[i] == '.') + { + iExtensionStartPos = i; + } + + if (str[i] == '/') + { + strName = std::string(str.c_str() + i + 1); + strName.resize(iExtensionStartPos - i - 1); + break; + } + } + } + + return strName; +} + + +/////////////////////////////////////////////////////////////////////// +// CFilenameHelper::GetExtension + +inline std::string CFileNameHelper::GetExtension(std::string& str) +{ + std::string strExtension; + + size_t nLength = str.length(); + + if (nLength > 0) + { + for (size_t i = nLength - 1; i > 0 && str[i] != '/'; i--) + if (str[i] == '.') + { + strExtension = std::string(str.c_str( ) + i + 1); + break; + } + } + + return strExtension; +} + + +/////////////////////////////////////////////////////////////////////// +// CFilenameHelper::GetPath + +inline std::string CFileNameHelper::GetPath(std::string& str) +{ + char szPath[1024]; + szPath[0] = '\0'; + + size_t nLength = str.length(); + + if (nLength > 0) + { + for (size_t i = nLength - 1; i > 0; i--) + { + if (str[i] == '/' || str[i] == '\\') + { + for (size_t j = 0; j < i + 1; j++) + szPath[j] = str[j]; + szPath[i+1] = '\0'; + break; + } + + if (0 == i) + break; + } + } + return szPath; +} + + +/////////////////////////////////////////////////////////////////////// +// CFilenameHelper::NoExtension + +inline std::string CFileNameHelper::NoExtension(std::string& str) +{ + std::size_t npos = str.find_last_of('.'); + + if (std::string::npos != npos) + return std::string(str, 0, npos); + + return str; +} + + +/////////////////////////////////////////////////////////////////////// +// CFilenameHelper::NoPath + +inline std::string CFileNameHelper::NoPath(std::string& str) +{ + char szPath[1024]; + szPath[0] = '\0'; + + size_t nLength = str.length(); + + if (nLength > 0) + { + strcpy(szPath, str.c_str()); + + for (size_t i = nLength - 1; i > 0; i--) + { + if (str[i] == '/' || str[i] == '\\') + { + int k = 0; + for (size_t j = i + 1; j < nLength; j++, k++) + szPath[k] = str[j]; + szPath[k] = '\0'; + break; + } + + if (0 == i) + break; + } + } + + return szPath; +} \ No newline at end of file diff --git a/source/EterBase/MappedFile.cpp b/source/EterBase/MappedFile.cpp new file mode 100644 index 0000000..4745cb6 --- /dev/null +++ b/source/EterBase/MappedFile.cpp @@ -0,0 +1,259 @@ +#include "StdAfx.h" +#include "MappedFile.h" +#include "Debug.h" + +CMappedFile::CMappedFile() : +m_hFM(NULL), +m_lpMapData(NULL), +m_dataOffset(0), +m_mapSize(0), +m_seekPosition(0), +m_pLZObj(NULL), +m_pbBufLinkData(NULL), +m_dwBufLinkSize(0), +m_pbAppendResultDataBlock(NULL), +m_dwAppendResultDataSize(0) +{ +} + +CMappedFile::~CMappedFile() +{ + Destroy(); +} + +BOOL CMappedFile::Create(const char * filename) +{ + Destroy(); + return CFileBase::Create(filename, FILEMODE_READ); +} + +BOOL CMappedFile::Create(const char * filename, const void** dest, int offset, int size) +{ + if (!CMappedFile::Create(filename)) + return NULL; + + int ret = Map(dest, offset, size); + return (ret) > 0; +} + +LPCVOID CMappedFile::Get() +{ + return m_lpData; +} + +void CMappedFile::Link(DWORD dwBufSize, const void* c_pvBufData) +{ + m_dwBufLinkSize=dwBufSize; + m_pbBufLinkData=(BYTE*)c_pvBufData; +} + +void CMappedFile::BindLZObject(CLZObject * pLZObj) +{ + assert(m_pLZObj == NULL); + m_pLZObj = pLZObj; + + Link(m_pLZObj->GetSize(), m_pLZObj->GetBuffer()); +} + +void CMappedFile::BindLZObjectWithBufferedSize(CLZObject * pLZObj) +{ + assert(m_pLZObj == NULL); + m_pLZObj = pLZObj; + + Link(m_pLZObj->GetBufferSize(), m_pLZObj->GetBuffer()); +} + +BYTE* CMappedFile::AppendDataBlock( const void* pBlock, DWORD dwBlockSize ) +{ + if( m_pbAppendResultDataBlock ) + { + delete []m_pbAppendResultDataBlock; + } + + //realloc + m_dwAppendResultDataSize = m_dwBufLinkSize+dwBlockSize; + m_pbAppendResultDataBlock = new BYTE[m_dwAppendResultDataSize]; + + memcpy(m_pbAppendResultDataBlock, m_pbBufLinkData, m_dwBufLinkSize ); + memcpy(m_pbAppendResultDataBlock + m_dwBufLinkSize, pBlock, dwBlockSize ); + + //redirect + Link(m_dwAppendResultDataSize, m_pbAppendResultDataBlock); + + return m_pbAppendResultDataBlock; +} + +void CMappedFile::Destroy() +{ + if (m_pLZObj) // Ͱ ͷ ȴ + { + delete m_pLZObj; + m_pLZObj = NULL; + } + + if (NULL != m_lpMapData) + { + Unmap(m_lpMapData); + m_lpMapData = NULL; + } + + if (NULL != m_hFM) + { + CloseHandle(m_hFM); + m_hFM = NULL; + } + + if( m_pbAppendResultDataBlock ) + { + delete []m_pbAppendResultDataBlock; + m_pbAppendResultDataBlock = NULL; + } + + m_dwAppendResultDataSize = 0; + + m_pbBufLinkData = NULL; + m_dwBufLinkSize = 0; + + m_seekPosition = 0; + m_dataOffset = 0; + m_mapSize = 0; + + CFileBase::Destroy(); +} + +int CMappedFile::Seek(DWORD offset, int iSeekType) +{ + switch (iSeekType) + { + case SEEK_TYPE_BEGIN: + if (offset > m_dwSize) + offset = m_dwSize; + + m_seekPosition = offset; + break; + + case SEEK_TYPE_CURRENT: + m_seekPosition = min(m_seekPosition + offset, Size()); + break; + + case SEEK_TYPE_END: + m_seekPosition = max(0, Size() - offset); + break; + } + + return m_seekPosition; +} + +// 2004.09.16.myevan.MemoryMappedFile 98/ME üũ +//DWORD g_dwCount=0; + +int CMappedFile::Map(const void **dest, int offset, int size) +{ + m_dataOffset = offset; + + if (size == 0) + m_mapSize = m_dwSize; + else + m_mapSize = size; + + if (m_dataOffset + m_mapSize > m_dwSize) + return NULL; + + SYSTEM_INFO SysInfo; + GetSystemInfo(&SysInfo); + DWORD dwSysGran = SysInfo.dwAllocationGranularity; + DWORD dwFileMapStart = (m_dataOffset / dwSysGran) * dwSysGran; + DWORD dwMapViewSize = (m_dataOffset % dwSysGran) + m_mapSize; + INT iViewDelta = m_dataOffset - dwFileMapStart; + + + m_hFM = CreateFileMapping(m_hFile, // handle + NULL, // security + PAGE_READONLY, // flProtect + 0, // high + m_dataOffset + m_mapSize, // low + NULL); // name + + if (!m_hFM) + { + OutputDebugString("CMappedFile::Map !m_hFM\n"); + return NULL; + } + + m_lpMapData = MapViewOfFile(m_hFM, + FILE_MAP_READ, + 0, + dwFileMapStart, + dwMapViewSize); + + if (!m_lpMapData) // Success + { + TraceError("CMappedFile::Map !m_lpMapData %lu", GetLastError()); + return 0; + } + + // 2004.09.16.myevan.MemoryMappedFile 98/ME üũ + //g_dwCount++; + //Tracenf("MAPFILE %d", g_dwCount); + + m_lpData = (char*) m_lpMapData + iViewDelta; + *dest = (char*) m_lpData; + m_seekPosition = 0; + + Link(m_mapSize, m_lpData); + + return (m_mapSize); +} + +BYTE * CMappedFile::GetCurrentSeekPoint() +{ + return m_pbBufLinkData+m_seekPosition; + //return m_pLZObj ? m_pLZObj->GetBuffer() + m_seekPosition : (BYTE *) m_lpData + m_seekPosition; +} + + +DWORD CMappedFile::Size() +{ + return m_dwBufLinkSize; + /* + if (m_pLZObj) + return m_pLZObj->GetSize(); + + return (m_mapSize); + */ +} + +DWORD CMappedFile::GetPosition() +{ + return m_dataOffset; +} + +BOOL CMappedFile::Read(void * dest, int bytes) +{ + if (m_seekPosition + bytes > Size()) + return FALSE; + + memcpy(dest, GetCurrentSeekPoint(), bytes); + m_seekPosition += bytes; + return TRUE; +} + +DWORD CMappedFile::GetSeekPosition(void) +{ + return m_seekPosition; +} + +void CMappedFile::Unmap(LPCVOID data) +{ + if (UnmapViewOfFile(data)) + { + // 2004.09.16.myevan.MemoryMappedFile 98/ME üũ + //g_dwCount--; + //Tracenf("UNMAPFILE %d", g_dwCount); + } + else + { + TraceError("CMappedFile::Unmap - Error"); + } + m_lpData = NULL; +} diff --git a/source/EterBase/MappedFile.h b/source/EterBase/MappedFile.h new file mode 100644 index 0000000..6913099 --- /dev/null +++ b/source/EterBase/MappedFile.h @@ -0,0 +1,59 @@ +#ifndef __INC_MAPPEDFILE_H__ +#define __INC_MAPPEDFILE_H__ + +#include "lzo.h" +#include "FileBase.h" + +class CMappedFile : public CFileBase +{ +public: + enum ESeekType + { + SEEK_TYPE_BEGIN, + SEEK_TYPE_CURRENT, + SEEK_TYPE_END + }; + +public: + CMappedFile(); + virtual ~CMappedFile(); + + void Link(DWORD dwBufSize, const void* c_pvBufData); + + BOOL Create(const char* filename); + BOOL Create(const char* filename, const void** dest, int offset, int size); + LPCVOID Get(); + void Destroy(); + int Seek(DWORD offset, int iSeekType = SEEK_TYPE_BEGIN); + int Map(const void **dest, int offset=0, int size=0); + DWORD Size(); + DWORD GetPosition(); + BOOL Read(void* dest, int bytes); + DWORD GetSeekPosition(); + void BindLZObject(CLZObject * pLZObj); + void BindLZObjectWithBufferedSize(CLZObject * pLZObj); + BYTE* AppendDataBlock( const void* pBlock, DWORD dwBlockSize ); + + BYTE * GetCurrentSeekPoint(); + +private: + void Unmap(LPCVOID data); + +private: + BYTE* m_pbBufLinkData; + DWORD m_dwBufLinkSize; + + BYTE* m_pbAppendResultDataBlock; + DWORD m_dwAppendResultDataSize; + + DWORD m_seekPosition; + HANDLE m_hFM; + DWORD m_dataOffset; + DWORD m_mapSize; + LPVOID m_lpMapData; + LPVOID m_lpData; + + CLZObject * m_pLZObj; +}; + +#endif diff --git a/source/EterBase/Poly/Base.cpp b/source/EterBase/Poly/Base.cpp new file mode 100644 index 0000000..b084b79 --- /dev/null +++ b/source/EterBase/Poly/Base.cpp @@ -0,0 +1,27 @@ +#include "StdAfx.h" +#include "Base.h" + +CBase::CBase() +{ + id = 0; +} + +CBase::~CBase() +{ +} + +bool CBase::isNumber() +{ + return (id & MID_NUMBER) != 0 ? true : false; +} + +bool CBase::isVar() +{ + return (id & MID_VARIABLE) != 0 ? true : false; +} + +bool CBase::isSymbol() +{ + return (id & MID_SYMBOL) != 0 ? true : false; +} + diff --git a/source/EterBase/Poly/Base.h b/source/EterBase/Poly/Base.h new file mode 100644 index 0000000..a7b0187 --- /dev/null +++ b/source/EterBase/Poly/Base.h @@ -0,0 +1,25 @@ +#ifndef __POLY_BASE_H__ +#define __POLY_BASE_H__ + +#define MID_UNKNOWN 0 +#define MID_NUMBER 256 +#define MID_VARIABLE 512 +#define MID_SYMBOL 1024 + +#define MID_LONG MID_NUMBER + 1 +#define MID_SQRT MID_NUMBER + 2 +#define MID_FRACTION MID_NUMBER + 3 + +class CBase +{ + public: + bool isSymbol(); + bool isVar(); + bool isNumber(); + int id; + CBase(); + virtual ~CBase(); + +}; + +#endif diff --git a/source/EterBase/Poly/Poly.cpp b/source/EterBase/Poly/Poly.cpp new file mode 100644 index 0000000..d10f7dd --- /dev/null +++ b/source/EterBase/Poly/Poly.cpp @@ -0,0 +1,622 @@ +#include "StdAfx.h" +#include +#include + +#include "Poly.h" +#include +#include +#include + +using namespace std; + +double _random() +{ + return rand() / (RAND_MAX + 1.0); +} + +void CPoly::SetRandom(int iRandomType) +{ + m_iRandomType = iRandomType; +} + +int CPoly::my_irandom(double start, double end) +{ + switch (m_iRandomType) + { + case RANDOM_TYPE_FORCE_MIN: + return int(start); + break; + case RANDOM_TYPE_FORCE_MAX: + return int(end); + break; + } + + // Make range as inclusive-exclusive + int is = int(start + 0.5); + int ie = int(end - start + 0.5) + 1; + + return int(_random() * ie + is); +} + +double CPoly::my_frandom(double start, double end) +{ + return _random() * (end - start) + start; +} + +CPoly::CPoly() +{ + m_iRandomType = RANDOM_TYPE_FREELY; + uiLookPos = 0; + ErrorOccur = true; + lSymbol.clear(); + STSize = 0; + MathSymbolCount = 0; + lSymbol.reserve(50); + init(); +} + +CPoly::~CPoly() +{ + Clear(); +} + +void CPoly::SetStr(const string & str) +{ + strData = str; +} + +float CPoly::Eval() +{ + int stNow; + double save[POLY_MAXSTACK],t; + int iSp=0; + if (ErrorOccur) + { + /*THROW(new CEvalException("Evaluate Error"));*/ + return 0; + } + + //TEST + //list::iterator pos = tokenBase.begin(); + //list::iterator posn = numBase.begin(); + vector::iterator pos = tokenBase.begin(); + vector::iterator posn = numBase.begin(); + while (pos != tokenBase.end()) + { + + stNow=*pos; + ++pos; + switch (stNow) + { + case POLY_NUM: + save[iSp++]=*posn++; break; + case POLY_ID: + save[iSp++]= + lSymbol[ *pos ]->dVal; + pos++; + break; + //case '+': + case POLY_PLU: + iSp--; + save[iSp-1]+=save[iSp]; break; + //case '-': + case POLY_MIN: + iSp--; + save[iSp-1]-=save[iSp]; break; + //case '*': + case POLY_MUL: + iSp--; + save[iSp-1]*=save[iSp]; break; + //case '%': + case POLY_MOD: + iSp--; + if (save[iSp]==0) + { + //THROW(new CEvalException("Divide by 0")); + return 0; + } + save[iSp-1]=fmod(save[iSp-1],save[iSp]); break; + //case '/': + case POLY_DIV: + iSp--; + if (save[iSp]==0) + { + //THROW(new CEvalException("Divide by 0")); + return 0; + } + save[iSp-1]/=save[iSp]; break; + //case '^': + case POLY_POW: + iSp--; + save[iSp-1]=pow(save[iSp-1],save[iSp]); break; + case POLY_ROOT: + if (save[iSp-1]<0) + { + //THROW(new CEvalException("Negative in root")); + return 0; + } + save[iSp-1]=sqrt(save[iSp-1]); break; + case POLY_COS: + save[iSp-1]=cos(save[iSp-1]); break; + case POLY_SIN: + save[iSp-1]=sin(save[iSp-1]); break; + case POLY_TAN: + if (!(t=cos(save[iSp-1]))) + { + //THROW (new CEvalException("Divide by 0")); + return 0; + } + save[iSp-1]=tan(save[iSp-1]); break; + case POLY_CSC: + if (!(t=sin(save[iSp-1]))) + { + //THROW(new CEvalException("Divide by 0")); + return 0; + } + save[iSp-1]=1/t; break; + case POLY_SEC: + if (!(t=cos(save[iSp-1]))) + { + //THROW(new CEvalException("Divide by 0")); + return 0; + } + save[iSp-1]=1/t; break; + case POLY_COT: + if (!(t=sin(save[iSp-1]))) + { + //THROW(new CEvalException("Divide by 0")); + return 0; + } + save[iSp-1]=cos(save[iSp-1])/t; break; + case POLY_LN: + if (save[iSp-1]<=0) + { + //THROW( new CEvalException("Call Log with minus number")); + return 0; + } + save[iSp-1]=log(save[iSp-1]); break; + case POLY_LOG10: + if (save[iSp-1]<=0) + { + //THROW( new CEvalException("Call Log with minus number")); + return 0; + } + save[iSp-1]=log10(save[iSp-1]); break; + case POLY_LOG: + if (save[iSp-1]<=0) + { + //THROW( new CEvalException("Call Log with minus number")); + return 0; + } + if (save[iSp-2]<=0 || save[iSp-2]==1) + { + //THROW( new CEvalException("Call Log with minus number")); + return 0; + } + + save[iSp-2]=log(save[iSp-1])/log(save[iSp-2]); + iSp--; + break; + case POLY_ABS: + save[iSp-1]=fabs(save[iSp-1]); + break; + case POLY_FLOOR: + save[iSp-1]=floor(save[iSp-1]); + break; + case POLY_IRAND: + save[iSp-2]=my_irandom(save[iSp-2],save[iSp-1]); + iSp--; + break; + case POLY_FRAND: + save[iSp-2]=my_frandom(save[iSp-2],save[iSp-1]); + iSp--; + break; + case POLY_MINF: + save[iSp-2]=(save[iSp-2]save[iSp-1])?save[iSp-2]:save[iSp-1]; + iSp--; + break; + /*case POLY_MOD: + save[iSp-2]=fmod(save[iSp-2],save[iSp-1]); + iSp--; + break;*/ + default: + return 0; + //THROW(new CEvalException("Token Error")); + } + } + return float(save[iSp-1]); +} + +int CPoly::Analyze(const char * pszStr) +{ + if (pszStr) + SetStr(pszStr); + + if (0 == strData.length()) + return true; + + //DisposeList(); + ErrorOccur = false; + uiLookPos = 0; + iLookAhead = lexan(); + + expr(); + + if (tokenBase.empty()) + { + //THROW(new CParseException("No Data")); + return false; + } + + return !ErrorOccur; +} + +void CPoly::Clear() +{ + int i; + //while (!tokenBase.IsEmpty()) listBase.RemoveTail(); + //while (!numBase.IsEmpty()) numBase.RemoveTail(); + tokenBase.clear(); + numBase.clear(); + + for (i = 0;i < STSize; ++i) + { + if (lSymbol[i]) delete lSymbol[i]; + lSymbol[i]=NULL; + } + //lSymbol.FreeExtra(); + lSymbol.clear(); + SymbolIndex.clear(); + STSize=0; + MathSymbolCount=0; +} + +void CPoly::expr() +{ + int t; + + switch (iLookAhead) + { + case '+': + case '-': + uiLookPos--; + iLookAhead = POLY_NUM; + iNumToken = iToken = 0; + + } + + term(); + + while (!ErrorOccur) + { + switch (iLookAhead) + { + case '+': + case '-': + t=iLookAhead; + match(t); + term(); + emit(t,POLY_NONE); + continue; + case POLY_EOS: case ')': case ',': return; + default: + error(); + //THROW( new CParseException("Error Parsing")); + return; + } + } +} + +void CPoly::error() +{ + iErrorPos=uiLookPos; + ErrorOccur=true; +} + +int CPoly::lexan() +{ + int t; + double tt; + + while (uiLookPos < strData.size()) + { + if (strData[uiLookPos] == ' ' || strData[uiLookPos] == '\t') + ; + else if (isdigit(strData[uiLookPos])) + { + t = 0; + for (;uiLookPostoken; + } + else + { + iToken=0; + return strData[uiLookPos++]; + } + uiLookPos++; + } + return POLY_EOS; +} + +void CPoly::term() +{ + int t; + factor(); + while (!ErrorOccur) + { + switch (iLookAhead) + { + case '*': + case '/': + case '%': + t=iLookAhead; + match(t); + factor(); + emit(t,POLY_NONE); + continue; + default: + return; + } + } +} + +void CPoly::factor() +{ + int t; + expo(); + while (!ErrorOccur) + { + switch (iLookAhead) + { + case '^': + t=iLookAhead; + match(t); + expo(); + emit(t,POLY_NONE); + continue; + default: + return; + } + } +} + +void CPoly::expo() +{ + int t; + switch (iLookAhead) + { + case '(': + match('('); expr(); match(')'); break; + case POLY_NUM: + emit(POLY_NUM, iToken); match(POLY_NUM); break; + case POLY_ID: + emit(POLY_ID,(int)/*FindIndex*/(iToken)); match(POLY_ID); break; + case POLY_ROOT: + case POLY_SIN: + case POLY_COT: + case POLY_TAN: + case POLY_CSC: + case POLY_SEC: + case POLY_LN: + case POLY_LOG10: + case POLY_COS: + case POLY_ABS: + case POLY_FLOOR: + t=iLookAhead; + match(iLookAhead); match('('); expr(); match(')'); emit(t,iToken); + break; + case POLY_LOG: + case POLY_MINF: + case POLY_MAXF: + case POLY_IRAND: + case POLY_FRAND: + case POLY_MOD: + t=iLookAhead; + match(iLookAhead); match('('); expr(); match(','); expr(); match(')'); emit(t,iToken); + break; + case POLY_EOS: + break; + default: + error(); + //THROW( new CParseException("Error Parsing")); + } +} + +void CPoly::match(int t) +{ + if (iLookAhead==t) iLookAhead=lexan(); else error(); +} + +void CPoly::emit(int t, int tval) +{ + switch (t) + { + case '+': + tokenBase.push_back(POLY_PLU); + break; + case '-': + tokenBase.push_back(POLY_MIN); + break; + case '*': + tokenBase.push_back(POLY_MUL); + break; + case '/': + tokenBase.push_back(POLY_DIV); + break; + case '%': + tokenBase.push_back(POLY_MOD); + break; + case '^': + tokenBase.push_back(POLY_POW); + break; + case POLY_ROOT: + case POLY_SIN: + case POLY_TAN: + case POLY_COT: + case POLY_COS: + case POLY_CSC: + case POLY_SEC: + case POLY_LOG: + case POLY_LN: + case POLY_LOG10: + case POLY_ABS: + case POLY_MINF: + case POLY_MAXF: + case POLY_IRAND: + case POLY_FRAND: + case POLY_MOD: + case POLY_FLOOR: + tokenBase.push_back(t); + break; + case POLY_NUM: + tokenBase.push_back(t); + numBase.push_back(iNumToken); + break; + case POLY_ID: + tokenBase.push_back(t); + tokenBase.push_back(tval); break; + default: + error(); + Clear(); + //THROW( new CParseException("Error Parsing")); + return; + } +} + +int CPoly::find(const string & s) +{ + int l, m, r; + + l = 0; + r = STSize - 1; + + while (l <= r) + { + m = (l + r) >> 1; + + if (lSymbol[SymbolIndex[m]]->strlex == s) + return SymbolIndex[m]; + else if (lSymbol[SymbolIndex[m]]->strlex < s) + l = m + 1; + else + r = m - 1; + } + return -1; +} + +int CPoly::insert(const string & s, int tok) +{ + int i; + bool bAdded=false; + + lSymbol.push_back(new CSymTable(tok,s)); + for (i=0;istrlex) + { + SymbolIndex.insert(SymbolIndex.begin()+i,STSize); + bAdded=true; + break; + } + } + if (!bAdded) + { + //SymbolIndex.SetAtGrow(STSize,STSize); + SymbolIndex.push_back(STSize); + } + STSize++; + return STSize-1; +} + +int CPoly::SetVar(const string & strName, double dVar) +{ + + if (ErrorOccur) return false; + int index=find(strName); + if (index==-1) return false; + CSymTable* stVar = lSymbol[(/*FindIndex*/(index))]; + stVar->dVal=dVar; + return true; +} + +int CPoly::GetVarCount() +{ + return lSymbol.size() - MathSymbolCount; +} + +const char * CPoly::GetVarName(unsigned int dwIndex) +{ + assert(dwIndex + MathSymbolCount < lSymbol.size()); + return lSymbol[dwIndex + MathSymbolCount]->strlex.c_str(); +} + +void CPoly::init() +{ + insert("min",POLY_MINF); + insert("max",POLY_MAXF); + insert("number", POLY_IRAND); + insert("irandom", POLY_IRAND); + insert("irand", POLY_IRAND); + insert("frandom",POLY_FRAND); + insert("frand",POLY_FRAND); + insert("rt",POLY_ROOT); + insert("sqrt",POLY_ROOT); + insert("cos",POLY_COS); + insert("sin",POLY_SIN); + insert("tan",POLY_TAN); + insert("cot",POLY_COT); + insert("csc",POLY_CSC); + insert("cosec",POLY_COSEC); + insert("sec",POLY_SEC); + insert("pi",POLY_PI); + SetVar("pi",3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068); + insert("e",POLY_EXP); + SetVar("e",2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427); + insert("log",POLY_LOG); + insert("ln",POLY_LN); + insert("log10",POLY_LOG10); + insert("abs",POLY_ABS); + insert("mod",POLY_MOD); + insert("floor",POLY_FLOOR); + MathSymbolCount = STSize; +} diff --git a/source/EterBase/Poly/Poly.h b/source/EterBase/Poly/Poly.h new file mode 100644 index 0000000..8bdc6bf --- /dev/null +++ b/source/EterBase/Poly/Poly.h @@ -0,0 +1,106 @@ +#ifndef __POLY_POLY_H__ +#define __POLY_POLY_H__ + +#include "SymTable.h" + +#pragma warning ( push, 3 ) + +#include +#include +#include + +#pragma warning ( pop ) + +#define POLY_MAXVALUE 0 +#define POLY_NONE POLY_MAXVALUE +#define POLY_ROOT POLY_MAXVALUE + 1 +#define POLY_MUL POLY_MAXVALUE + 2 +#define POLY_PLU POLY_MAXVALUE + 3 +#define POLY_POW POLY_MAXVALUE + 4 +#define POLY_MIN POLY_MAXVALUE + 5 +#define POLY_DIV POLY_MAXVALUE + 6 +#define POLY_OPEN POLY_MAXVALUE + 7 +#define POLY_CLOSE POLY_MAXVALUE + 8 +#define POLY_NUM POLY_MAXVALUE + 9 +#define POLY_ID POLY_MAXVALUE + 10 +#define POLY_EOS POLY_MAXVALUE + 11 +#define POLY_COS POLY_MAXVALUE + 12 +#define POLY_SIN POLY_MAXVALUE + 13 +#define POLY_TAN POLY_MAXVALUE + 14 +#define POLY_COSEC POLY_MAXVALUE + 15 +#define POLY_CSC POLY_COSEC +#define POLY_SEC POLY_MAXVALUE + 16 +#define POLY_COT POLY_MAXVALUE + 17 +#define POLY_PI POLY_ID +#define POLY_EXP POLY_ID +#define POLY_LOG POLY_MAXVALUE + 18 +#define POLY_LN POLY_MAXVALUE + 19 +#define POLY_LOG10 POLY_MAXVALUE + 20 + +#define POLY_ABS POLY_MAXVALUE + 21 +#define POLY_MINF POLY_MAXVALUE + 22 +#define POLY_MAXF POLY_MAXVALUE + 23 +#define POLY_IRAND POLY_MAXVALUE + 24 +#define POLY_FRAND POLY_MAXVALUE + 25 +#define POLY_MOD POLY_MAXVALUE + 26 +#define POLY_FLOOR POLY_MAXVALUE + 27 + +#define POLY_MAXSTACK 100 + +class CPoly +{ +public: + enum ERandomType + { + RANDOM_TYPE_FREELY, + RANDOM_TYPE_FORCE_MIN, + RANDOM_TYPE_FORCE_MAX, + }; + +public: + CPoly(); + virtual ~CPoly(); + + int Analyze(const char * pszStr = NULL); + float Eval(); + void SetRandom(int iRandomType); + void SetStr(const std::string & str); + int SetVar(const std::string & strName, double dVar); + int GetVarCount(); + const char * GetVarName(unsigned int dwIndex); + void Clear(); + + protected: + int my_irandom(double start, double end); + double my_frandom(double start, double end); + + void init(); + int insert(const std::string & s, int tok); + int find(const std::string & s); + void emit(int t,int tval); + void match(int t); + void expo(); + void factor(); + void term(); + int iToken; + double iNumToken; + int iLookAhead; + int lexan(); + int iErrorPos; + void error(); + void expr(); + bool ErrorOccur; + unsigned int uiLookPos; + + // NOTE: list is slight faster than vector, why?! + std::vector tokenBase; + std::vector numBase; + std::vector lSymbol; + std::vector SymbolIndex; + int STSize; + int MathSymbolCount; + std::string strData; + int m_iRandomType; +}; + +#endif diff --git a/source/EterBase/Poly/StdAfx.h b/source/EterBase/Poly/StdAfx.h new file mode 100644 index 0000000..4ad2d49 --- /dev/null +++ b/source/EterBase/Poly/StdAfx.h @@ -0,0 +1,2 @@ +#pragma once +#include "..\StdAfx.h" diff --git a/source/EterBase/Poly/SymTable.cpp b/source/EterBase/Poly/SymTable.cpp new file mode 100644 index 0000000..935587f --- /dev/null +++ b/source/EterBase/Poly/SymTable.cpp @@ -0,0 +1,11 @@ +#include "StdAfx.h" +#include "SymTable.h" + +CSymTable::CSymTable(int aTok, std::string aStr) : dVal(0), token(aTok), strlex(aStr) +{ +} + +CSymTable::~CSymTable() +{ +} + diff --git a/source/EterBase/Poly/SymTable.h b/source/EterBase/Poly/SymTable.h new file mode 100644 index 0000000..50db283 --- /dev/null +++ b/source/EterBase/Poly/SymTable.h @@ -0,0 +1,17 @@ +#ifndef __POLY_SYMTABLE_H__ +#define __POLY_SYMTABLE_H__ + +#include + +class CSymTable +{ + public: + CSymTable(int aTok, std::string aStr); + virtual ~CSymTable(); + + double dVal; + int token; + std::string strlex; +}; + +#endif diff --git a/source/EterBase/Poly/Symbol.cpp b/source/EterBase/Poly/Symbol.cpp new file mode 100644 index 0000000..dff6b5d --- /dev/null +++ b/source/EterBase/Poly/Symbol.cpp @@ -0,0 +1,50 @@ +#include "StdAfx.h" +#include "Symbol.h" + +CSymbol::CSymbol() +{ + id = MID_SYMBOL; + iType = ST_UNKNOWN; +} + +CSymbol::~CSymbol() +{ + +} + +bool CSymbol::Equal(CSymbol dif) +{ + if (dif.iType/10 == iType/10) return true; + return false; +} + +bool CSymbol::Less(CSymbol dif) +{ + if (dif.iType/10 > iType/10) return true; + return false; +} + +int CSymbol::GetType() +{ + return iType; +} + +void CSymbol::SetType(int Type) +{ + iType=Type; +} + +int CSymbol::issymbol(int ch) +{ + switch(ch) + { + case SY_PLUS : return ST_PLUS; + case SY_MINUS : return ST_MINUS; + case SY_MULTIPLY: return ST_MULTIPLY; + case SY_DIVIDE : return SY_DIVIDE; + case SY_CARET : return SY_CARET; + case SY_OPEN : return SY_OPEN; + case SY_CLOSE : return ST_CLOSE; + } + return 0; +} diff --git a/source/EterBase/Poly/Symbol.h b/source/EterBase/Poly/Symbol.h new file mode 100644 index 0000000..427cfe5 --- /dev/null +++ b/source/EterBase/Poly/Symbol.h @@ -0,0 +1,39 @@ +#ifndef __POLY_SYMBOL_H__ +#define __POLY_SYMBOL_H__ + +#include "Base.h" + +#define ST_UNKNOWN 0 +#define ST_PLUS 11 +#define ST_MINUS 12 +#define ST_MULTIPLY 23 +#define ST_DIVIDE 24 +#define ST_CARET 35 +#define ST_OPEN 06 +#define ST_CLOSE 07 + +#define SY_PLUS '+' +#define SY_MINUS '-' +#define SY_MULTIPLY '*' +#define SY_DIVIDE '/' +#define SY_CARET '^' +#define SY_OPEN '(' +#define SY_CLOSE ')' + +class CSymbol : public CBase +{ + private: + int iType; + + public: + CSymbol(); + virtual ~CSymbol(); + + static int issymbol(int ch); + void SetType(int Type); + int GetType(); + bool Equal(CSymbol dif); + bool Less(CSymbol dif); +}; + +#endif diff --git a/source/EterBase/Random.cpp b/source/EterBase/Random.cpp new file mode 100644 index 0000000..ab4b8b2 --- /dev/null +++ b/source/EterBase/Random.cpp @@ -0,0 +1,48 @@ +#include "StdAfx.h" + +#include + +static unsigned long randseed = 1; + +void srandom(unsigned long seed) +{ + randseed = seed; +} + +/* + * Pseudo-random number generator for randomizing the profiling clock, + * and whatever else we might use it for. The result is uniform on + * [0, 2^31 - 1]. + */ +unsigned long random() +{ + long x, hi, lo, t; + + /* + * Compute x[n + 1] = (7^5 * x[n]) mod (2^31 - 1). + * From "Random number generators: good ones are hard to find", + * Park and Miller, Communications of the ACM, vol. 31, no. 10, + * October 1988, p. 1195. + */ + x = randseed; + hi = x / 127773; + lo = x % 127773; + t = 16807 * lo - 2836 * hi; + if (t <= 0) + t += 0x7fffffff; + randseed = t; + return (t); +} + + +float frandom(float flLow, float flHigh) +{ + float fl = float(random()) / float(2147483648.0f); // float in [0,1) + return (fl * (flHigh - flLow)) + flLow; // float in [low,high) +} + +long random_range(long from, long to) +{ + assert(from <= to); + return ((random() % (to - from + 1)) + from); +} diff --git a/source/EterBase/Random.h b/source/EterBase/Random.h new file mode 100644 index 0000000..77b5a5d --- /dev/null +++ b/source/EterBase/Random.h @@ -0,0 +1,9 @@ +#ifndef __INC_ETERBASE_RANDOM_H__ +#define __INC_ETERBASE_RANDOM_H__ + +extern void srandom(unsigned long seed); +extern unsigned long random(); +extern float frandom(float flLow, float flHigh); +extern long random_range(long from, long to); + +#endif \ No newline at end of file diff --git a/source/EterBase/ServiceDefs.h b/source/EterBase/ServiceDefs.h new file mode 100644 index 0000000..af66f88 --- /dev/null +++ b/source/EterBase/ServiceDefs.h @@ -0,0 +1,6 @@ +#ifndef _EL_SERVICEDEFS_H_ +#define _EL_SERVICEDEFS_H_ + +#define _IMPROVED_PACKET_ENCRYPTION_ + +#endif //_EL_SERVICEDEFS_H_ diff --git a/source/EterBase/Singleton.h b/source/EterBase/Singleton.h new file mode 100644 index 0000000..1b5924c --- /dev/null +++ b/source/EterBase/Singleton.h @@ -0,0 +1,85 @@ +#ifndef __INC_ETERLIB_SINGLETON_H__ +#define __INC_ETERLIB_SINGLETON_H__ + +#include + +template class CSingleton +{ + static T * ms_singleton; + +public: + CSingleton() + { + assert(!ms_singleton); + int offset = (int) (T*) 1 - (int) (CSingleton *) (T*) 1; + ms_singleton = (T*) ((int) this + offset); + } + + virtual ~CSingleton() + { + assert(ms_singleton); + ms_singleton = 0; + } + + __forceinline static T & Instance() + { + assert(ms_singleton); + return (*ms_singleton); + } + + __forceinline static T * InstancePtr() + { + return (ms_singleton); + } + + __forceinline static T & instance() + { + assert(ms_singleton); + return (*ms_singleton); + } +}; + +template T * CSingleton ::ms_singleton = 0; + +// +// singleton for non-hungarian +// +template class singleton +{ + static T * ms_singleton; + +public: + singleton() + { + assert(!ms_singleton); + int offset = (int) (T*) 1 - (int) (singleton *) (T*) 1; + ms_singleton = (T*) ((int) this + offset); + } + + virtual ~singleton() + { + assert(ms_singleton); + ms_singleton = 0; + } + + __forceinline static T & Instance() + { + assert(ms_singleton); + return (*ms_singleton); + } + + __forceinline static T * InstancePtr() + { + return (ms_singleton); + } + + __forceinline static T & instance() + { + assert(ms_singleton); + return (*ms_singleton); + } +}; + +template T * singleton ::ms_singleton = 0; + +#endif diff --git a/source/EterBase/StdAfx.cpp b/source/EterBase/StdAfx.cpp new file mode 100644 index 0000000..f37e732 --- /dev/null +++ b/source/EterBase/StdAfx.cpp @@ -0,0 +1,6 @@ +// stdafx.cpp : source file that includes just the standard includes +// eterBase.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + diff --git a/source/EterBase/StdAfx.h b/source/EterBase/StdAfx.h new file mode 100644 index 0000000..a74b839 --- /dev/null +++ b/source/EterBase/StdAfx.h @@ -0,0 +1,56 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif + +#pragma warning(disable:4710) // not inlined +#pragma warning(disable:4786) // character 255 Ѿ° +#pragma warning(disable:4244) // type conversion possible lose of data + +#include +#include +#include +#pragma warning ( disable : 4201 ) +#include +#pragma warning ( default : 4201 ) +#include +#include + +#pragma warning ( push, 3 ) + +#include +#include +#include +#include +#include +#include + +#pragma warning ( pop ) + +#if _MSC_VER >= 1400 +#define stricmp _stricmp +#define strnicmp _strnicmp +#define strupt _strupr +#define strcmpi _strcmpi +#define fileno _fileno +//#define access _access_s +//#define _access _access_s +#define atoi _atoi64 +#endif + +// Armadillo nanomite protection +#ifndef NANOBEGIN + #ifdef __BORLANDC__ + #define NANOBEGIN __emit__ (0xEB,0x03,0xD6,0xD7,0x01) + #define NANOEND __emit__ (0xEB,0x03,0xD6,0xD7,0x00) + #else + #define NANOBEGIN __asm _emit 0xEB __asm _emit 0x03 __asm _emit 0xD6 __asm _emit 0xD7 __asm _emit 0x01 + #define NANOEND __asm _emit 0xEB __asm _emit 0x03 __asm _emit 0xD6 __asm _emit 0xD7 __asm _emit 0x00 + #endif +#endif + +#include "vk.h" +#include "filename.h" +#include "ServiceDefs.h" diff --git a/source/EterBase/Stl.cpp b/source/EterBase/Stl.cpp new file mode 100644 index 0000000..14cfad5 --- /dev/null +++ b/source/EterBase/Stl.cpp @@ -0,0 +1,92 @@ +#include "StdAfx.h" +#include "stl.h" + +static std::list s_stList; + +char korean_tolower(const char c) +{ + char ret = c; + if (c >= 'A' && c <= 'Z') + ret = c - 'A' + 'a'; + + assert(ret == tolower(c)); + return ret; +} + +std::string& stl_static_string(const char * c_sz) +{ + std::string str; + str.assign(c_sz); + + s_stList.push_back(str); + return s_stList.back(); +} + +void stl_lowers(std::string& rstRet) +{ + for (size_t i = 0; i < rstRet.length(); ++i) + rstRet[i] = korean_tolower(rstRet[i]); +} + +int split_string(const std::string& input, const std::string& delimiter, std::vector& results, bool includeEmpties) +{ + int iPos = 0; + int newPos = -1; + UINT sizeS2 = delimiter.size(); + UINT isize = input.size(); + + if ((isize == 0) || (sizeS2 == 0)) + { + return 0; + } + + std::vector positions; + + newPos = input.find(delimiter, 0); + + if (newPos < 0) + return 0; + + int numFound = 0; + + while (newPos >= iPos) + { + numFound++; + positions.push_back(newPos); + iPos = newPos; + newPos = input.find(delimiter, iPos+sizeS2); + } + + if (numFound == 0) + return 0; + + for (UINT i = 0; i <= positions.size(); ++i) + { + std::string s(""); + if (i == 0) + { + s = input.substr(i, positions[i]); + } + else + { + UINT offset = positions[i-1] + sizeS2; + + if (offset < isize) + { + if (i == positions.size()) + { + s = input.substr(offset); + } + else if (i > 0) + { + s = input.substr(positions[i-1] + sizeS2, positions[i] - positions[i-1] - sizeS2); + } + } + } + if (includeEmpties || (s.size() > 0)) + { + results.push_back(s); + } + } + return numFound; +} diff --git a/source/EterBase/Stl.h b/source/EterBase/Stl.h new file mode 100644 index 0000000..bc74865 --- /dev/null +++ b/source/EterBase/Stl.h @@ -0,0 +1,444 @@ +#ifndef __INC_ETERBASE_STL_H__ +#define __INC_ETERBASE_STL_H__ + +#pragma warning(disable:4786) // identifier was truncated to '255' characters in the browser information +#pragma warning(disable:4018) // signed <-> unsigned mismatch +#pragma warning(disable:4503) // decorated name length exceeded, name was truncated +#pragma warning(disable:4018) // '<' : signed/unsigned mismatch + +#include + +#pragma warning ( push, 3 ) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#pragma warning ( pop ) + +extern char korean_tolower(const char c); +extern std::string& stl_static_string(const char* c_sz); +extern void stl_lowers(std::string& rstRet); +extern int split_string(const std::string & input, const std::string & delimiter, std::vector& results, bool includeEmpties); + +struct stl_sz_less +{ + bool operator() (char * const & left, char * const & right) const + { + return (strcmp(left, right) < 0); + } +}; + +template +inline void stl_wipe(TContainer& container) +{ + for (auto i = container.begin(); i != container.end(); ++i) + { + delete *i; + *i = NULL; + } + + container.clear(); +} + +template +inline int hex2dec(TString szhex) +{ + int hex0 = toupper(szhex[0]); + int hex1 = toupper(szhex[1]); + + return (hex1 >= 'A' ? hex1 - 'A' + 10 : hex1 - '0') + + (hex0 >= 'A' ? hex0 - 'A' + 10 : hex0 - '0') * 16; +} + +template +inline unsigned long htmlColorStringToARGB(TString str) +{ + unsigned long alp = hex2dec(str); + unsigned long red = hex2dec(str + 2); + unsigned long green = hex2dec(str + 4); + unsigned long blue = hex2dec(str + 6); + return (alp << 24 | red << 16 | green << 8 | blue); +} + +template +inline void stl_wipe_second(TContainer& container) +{ + for (auto i = container.begin(); i != container.end(); ++i) + { + delete i->second; + } + + container.clear(); +} + +template +inline void safe_release(T& rpObject) +{ + if (!rpObject) + return; + + rpObject->Release(); + rpObject = NULL; +} + +template +void DeleteVectorItem(std::vector * pVector, unsigned long dwIndex) +{ + if (dwIndex >= pVector->size()) + { + assert(!"Wrong index to delete!"); + return; + } + if (1 == pVector->size()) + { + pVector->clear(); + return; + } + + auto itor = pVector->begin(); + for (unsigned long i = 0; i < dwIndex; ++i) + ++itor; + + pVector->erase(itor); +} + +template +void DeleteVectorItem(T * pVector, unsigned long dwStartIndex, unsigned long dwEndIndex) +{ + if (dwStartIndex >= pVector->size()) + { + assert(!"Wrong start index to delete!"); + return; + } + if (dwEndIndex >= pVector->size()) + { + assert(!"Wrong end index to delete!"); + return; + } + + auto itorStart = pVector->begin(); + for (unsigned long i = 0; i < dwStartIndex; ++i) + ++itorStart; + auto itorEnd = pVector->begin(); + for (unsigned long j = 0; j < dwEndIndex; ++j) + ++itorEnd; + + pVector->erase(itorStart, itorEnd); +} + +template +void DeleteVectorItem(std::vector * pVector, T pItem) +{ + auto itor = pVector->begin(); + for (; itor != pVector->end(); ++itor) + { + if (pItem == *itor) + { + if (1 == pVector->size()) + { + pVector->clear(); + } + else + { + pVector->erase(itor); + } + break; + } + } +} + +template +void DeleteListItem(std::list * pList, T pItem) +{ + auto itor = pList->begin(); + for (; itor != pList->end(); ++itor) + { + if (pItem == *itor) + { + if (1 == pList->size()) + { + pList->clear(); + } + else + { + pList->erase(itor); + } + break; + } + } +} + +template +void stl_vector_qsort(std::vector& rdataVector, F comp) +{ + if (rdataVector.empty()) return; + qsort(&rdataVector[0], rdataVector.size(), sizeof(T), comp); +} + +template +class stl_stack_pool +{ + public: + stl_stack_pool() + { + m_pos = 0; + } + + stl_stack_pool(int capacity) + { + m_pos = 0; + initialize(capacity); + } + + virtual ~stl_stack_pool() + { + } + + void initialize(int capacity) + { + m_dataVector.clear(); + m_dataVector.resize(capacity); + } + + void clear() + { + m_pos = 0; + } + + TData * alloc() + { + assert(!m_dataVector.empty() && "stl_stack_pool::alloc you MUST run stl_stack_pool::initialize"); + + int max = m_dataVector.size(); + + if (m_pos >= max) + { + assert(!"stl_stack_pool::alloc OUT of memory"); + m_pos = 0; + } + + return &m_dataVector[m_pos++]; + } + + TData* base() + { + return &m_dataVector[0]; + } + + int size() + { + return m_pos; + } + + private: + int m_pos; + + std::vector m_dataVector; +}; + +template +class stl_circle_pool +{ + public: + typedef bool TFlag; + + public: + stl_circle_pool() + { + initialize(); + } + virtual ~stl_circle_pool() + { + destroy(); + } + void destroy() + { + if (m_datas) + { + delete [] m_datas; + m_datas=NULL; + } + if (m_flags) + { + delete [] m_flags; + m_flags=NULL; + } + } + void create(int size) + { + destroy(); + + initialize(); + + m_size=size; + m_datas=new TData[m_size]; + m_flags=new TFlag[m_size]; + + for (int i=0; i=m_size) return false; + return true; + } + inline int size() + { + return m_size; + } + inline TData& refer(THandle handle) + { + assert(check(handle) && "Out of RANGE"); + return m_datas[handle]; + } + + protected: + void initialize() + { + m_datas=NULL; + m_flags=NULL; + m_pos=0; + m_size=0; + } + + + protected: + TData* m_datas; + TFlag* m_flags; + + THandle m_size; + + THandle m_pos; + +}; + +typedef std::vector CTokenVector; +typedef std::map CTokenMap; +typedef std::map CTokenVectorMap; + +//class CTokenVector : public std::vector +//{ +// public: +// CTokenVector() : std::vector () +// { +// } +// virtual ~CTokenVector() +// { +// } +//}; +// +//class CTokenMap : public std::map +//{ +// public: +// CTokenMap() : std::map() +// { +// } +// virtual ~CTokenMap() +// { +// } +//}; +// +//class CTokenVectorMap : public std::map +//{ +// public: +// CTokenVectorMap() : std::map() +// { +// } +// virtual ~CTokenVectorMap() +// { +// } +// +//}; + + +/* +template +class CMapIterator +{ +public: + typedef std::map TMapType; + +public: + CMapIterator(TMapType & rMap) + { + m_it = rMap.begin(); + m_itEnd = rMap.end(); + } + + inline T2 operator * () { return m_it->second; } + + inline bool operator ++() + { + if (m_itEnd == m_it) + return false; + + ++m_it; + return m_itEnd != m_it; + } + + inline T1 GetFirst() { return m_it->first; } + inline T2 GetSecond() { return m_it->second; } + + private: + TMapType::iterator m_it; + TMapType::iterator m_itEnd; +}; +*/ + +struct stringhash +{ + size_t GetHash(const std::string & str) const + { + const unsigned char * s = (const unsigned char*) str.c_str(); + const unsigned char * end = s + str.size(); + size_t h = 0; + + while (s < end) + { + h *= 16777619; + h ^= (unsigned char) *(unsigned char *) (s++); + } + + return h; + } + + size_t operator () (const std::string & str) const + { + return GetHash(str); + } +}; + +#endif diff --git a/source/EterBase/TempFile.cpp b/source/EterBase/TempFile.cpp new file mode 100644 index 0000000..f55e8bd --- /dev/null +++ b/source/EterBase/TempFile.cpp @@ -0,0 +1,21 @@ +#include "StdAfx.h" +#include "TempFile.h" +#include "Utils.h" +#include "Debug.h" + +CTempFile::~CTempFile() +{ + Destroy(); + DeleteFile(m_szFileName); +} + +CTempFile::CTempFile(const char * c_pszPrefix) +{ + strncpy(m_szFileName, CreateTempFileName(c_pszPrefix), MAX_PATH); + + if (!Create(m_szFileName, CFileBase::FILEMODE_WRITE)) + { + TraceError("CTempFile::CTempFile cannot create temporary file. (filename: %s)", m_szFileName); + return; + } +} diff --git a/source/EterBase/TempFile.h b/source/EterBase/TempFile.h new file mode 100644 index 0000000..1943092 --- /dev/null +++ b/source/EterBase/TempFile.h @@ -0,0 +1,16 @@ +#ifndef __INC_ETERBASE_TEMPFILE_H__ +#define __INC_ETERBASE_TEMPFILE_H__ + +#include "FileBase.h" + +class CTempFile : public CFileBase +{ + public: + CTempFile(const char * c_pszPrefix = NULL); + virtual ~CTempFile(); + + protected: + char m_szFileName[MAX_PATH+1]; +}; + +#endif diff --git a/source/EterBase/Timer.cpp b/source/EterBase/Timer.cpp new file mode 100644 index 0000000..f1ec5f6 --- /dev/null +++ b/source/EterBase/Timer.cpp @@ -0,0 +1,156 @@ +#include "StdAfx.h" +#include "Timer.h" + +static LARGE_INTEGER gs_liTickCountPerSec; +static DWORD gs_dwBaseTime=0; +static DWORD gs_dwServerTime=0; +static DWORD gs_dwClientTime=0; +static DWORD gs_dwFrameTime=0; + +#pragma comment(lib, "winmm.lib") + +BOOL ELTimer_Init() +{ + /* + gs_liTickCountPerSec.QuadPart=0; + + if (!QueryPerformanceFrequency(&gs_liTickCountPerSec)) + return 0; + + LARGE_INTEGER liTickCount; + QueryPerformanceCounter(&liTickCount); + gs_dwBaseTime= (liTickCount.QuadPart*1000 / gs_liTickCountPerSec.QuadPart); + */ + gs_dwBaseTime = timeGetTime(); + return 1; +} + +DWORD ELTimer_GetMSec() +{ + //assert(gs_dwBaseTime!=0 && "ELTimer_Init ϼ"); + //LARGE_INTEGER liTickCount; + //QueryPerformanceCounter(&liTickCount); + return timeGetTime() - gs_dwBaseTime; //(liTickCount.QuadPart*1000 / gs_liTickCountPerSec.QuadPart)-gs_dwBaseTime; +} + +VOID ELTimer_SetServerMSec(DWORD dwServerTime) +{ + NANOBEGIN + if (0 != dwServerTime) // nanomite if + { + gs_dwServerTime = dwServerTime; + gs_dwClientTime = CTimer::instance().GetCurrentMillisecond(); + } + NANOEND +} + +DWORD ELTimer_GetServerMSec() +{ + return CTimer::instance().GetCurrentMillisecond() - gs_dwClientTime + gs_dwServerTime; + //return ELTimer_GetMSec() - gs_dwClientTime + gs_dwServerTime; +} + +DWORD ELTimer_GetFrameMSec() +{ + return gs_dwFrameTime; +} + +DWORD ELTimer_GetServerFrameMSec() +{ + return ELTimer_GetFrameMSec() - gs_dwClientTime + gs_dwServerTime; +} + +VOID ELTimer_SetFrameMSec() +{ + gs_dwFrameTime = ELTimer_GetMSec(); +} + +CTimer::CTimer() +{ + ELTimer_Init(); + + NANOBEGIN + if (this) // nanomite if + { + m_dwCurrentTime = 0; + m_bUseRealTime = true; + m_index = 0; + + m_dwElapsedTime = 0; + + m_fCurrentTime = 0.0f; + } + NANOEND +} + +CTimer::~CTimer() +{ +} + +void CTimer::SetBaseTime() +{ + m_dwCurrentTime = 0; +} + +void CTimer::Advance() +{ + if (!m_bUseRealTime) + { + ++m_index; + + if (m_index == 1) + m_index = -1; + + m_dwCurrentTime += 16 + (m_index & 1); + m_fCurrentTime = m_dwCurrentTime / 1000.0f; + } + else + { + DWORD currentTime = ELTimer_GetMSec(); + + if (m_dwCurrentTime == 0) + m_dwCurrentTime = currentTime; + + m_dwElapsedTime = currentTime - m_dwCurrentTime; + m_dwCurrentTime = currentTime; + } +} + +void CTimer::Adjust(int iTimeGap) +{ + m_dwCurrentTime += iTimeGap; +} + +float CTimer::GetCurrentSecond() +{ + if (m_bUseRealTime) + return ELTimer_GetMSec() / 1000.0f; + + return m_fCurrentTime; +} + +DWORD CTimer::GetCurrentMillisecond() +{ + if (m_bUseRealTime) + return ELTimer_GetMSec(); + + return m_dwCurrentTime; +} + +float CTimer::GetElapsedSecond() +{ + return GetElapsedMilliecond() / 1000.0f; +} + +DWORD CTimer::GetElapsedMilliecond() +{ + if (!m_bUseRealTime) + return 16 + (m_index & 1); + + return m_dwElapsedTime; +} + +void CTimer::UseCustomTime() +{ + m_bUseRealTime = false; +} diff --git a/source/EterBase/Timer.h b/source/EterBase/Timer.h new file mode 100644 index 0000000..4865232 --- /dev/null +++ b/source/EterBase/Timer.h @@ -0,0 +1,41 @@ +#pragma once + +#include +#include "Singleton.h" + +class CTimer : public CSingleton +{ + public: + CTimer(); + virtual ~CTimer(); + + void Advance(); + void Adjust(int iTimeGap); + void SetBaseTime(); + + float GetCurrentSecond(); + DWORD GetCurrentMillisecond(); + + float GetElapsedSecond(); + DWORD GetElapsedMilliecond(); + + void UseCustomTime(); + + protected: + bool m_bUseRealTime; + DWORD m_dwBaseTime; + DWORD m_dwCurrentTime; + float m_fCurrentTime; + DWORD m_dwElapsedTime; + int m_index; +}; + +BOOL ELTimer_Init(); + +DWORD ELTimer_GetMSec(); + +VOID ELTimer_SetServerMSec(DWORD dwServerTime); +DWORD ELTimer_GetServerMSec(); + +VOID ELTimer_SetFrameMSec(); +DWORD ELTimer_GetFrameMSec(); \ No newline at end of file diff --git a/source/EterBase/Utils.cpp b/source/EterBase/Utils.cpp new file mode 100644 index 0000000..548106a --- /dev/null +++ b/source/EterBase/Utils.cpp @@ -0,0 +1,676 @@ +#include "StdAfx.h" + +#include +#include +#include +#include +#include +#include "Utils.h" +#include "filedir.h" + +char korean_tolower(const char c); + +const char * CreateTempFileName(const char * c_pszPrefix) +{ + char szTempPath[MAX_PATH + 1]; + static char szTempName[MAX_PATH + 1]; + + GetTempPath(MAX_PATH, szTempPath); + + GetTempFileName(szTempPath, // directory for temp files + c_pszPrefix ? c_pszPrefix : "etb", // temp file name prefix + c_pszPrefix ? true : false, // create unique name + szTempName); // buffer for name + + return (szTempName); +} + +void GetFilePathNameExtension(const char * c_szFile, int len, std::string * pstPath, std::string * pstName, std::string * pstExt) +{ + assert(pstPath != NULL); + assert(pstName != NULL); + assert(pstExt != NULL); + + int ext = len; + int pos = len; + + while (pos > 0) + { + --pos; + char c = c_szFile[pos]; + + if (ext == len && c == '.') + { + ext = pos; + break; + } + + if (c == '/' || c == '\\') + break; + } + + while (pos > 0) + { + --pos; + char c = c_szFile[pos]; + + if (c == '/' || c == '\\') + break; + } + + if (pos) + { + ++pos; + pstPath->append(c_szFile, pos); + } + + if (ext > pos) + pstName->append(c_szFile + pos, ext - pos); + + ++ext; + + if (len > ext) + pstExt->append(c_szFile + ext, len - ext); +} + +void GetFileExtension(const char* c_szFile, int len, std::string* pstExt) +{ + int ext = len; + int pos = len; + while (pos > 0) + { + --pos; + char c=c_szFile[pos]; + if (ext==len && c=='.') + { + ext=pos; + break; + } + + if (c=='/') break; + else if (c=='\\') break; + } + + ++ext; + if (len>ext) + pstExt->append(c_szFile+ext, len-ext); +} + +void GetFileNameParts(const char* c_szFile, int len, char* pszPath, char* pszName, char* pszExt) +{ + assert(pszPath!=NULL); + assert(pszName!=NULL); + assert(pszExt!=NULL); + + int ext=len; + int pos=len; + while (pos>0) + { + --pos; + char c=c_szFile[pos]; + if (ext==len && c=='.') + { + ext=pos; + break; + } + + if (c=='/') break; + else if (c=='\\') break; + } + + while (pos>0) + { + --pos; + char c=c_szFile[pos]; + + if (c=='/') break; + else if (c=='\\') break; + } + + if (pos) + { + ++pos; + for (int i = 0; i < pos; ++i) + { + pszPath[i] = c_szFile[i]; + } + pszPath[pos] = '\0'; + } + + if (ext>pos) + { + int count = 0; + for (int i = pos; i < ext; ++i) + { + pszName[count++] = c_szFile[i]; + } + pszName[count] = '\0'; + } + + ++ext; + if (len > ext) + { + int count = 0; + for (int i = ext; i < len; ++i) + { + pszExt[count++] = c_szFile[i]; + } + pszExt[count] = '\0'; + } +} + +void GetOldIndexingName(char * szName, int Index) +{ + int dec, sign; + char Temp[512]; + + strcpy(Temp, _ecvt(Index, 256, &dec, &sign)); + Temp[dec] = '\0'; + + strcat(szName, Temp); +} + +void GetIndexingName(char * szName, DWORD Index) +{ + sprintf(szName + strlen(szName), "%u", Index); +} + +void GetOnlyFileName(const char * sz_Name, std::string & strFileName) +{ + strFileName = ""; + + int i; + for (i=strlen(sz_Name)-1; i>=0; --i) + { + if ('\\' == sz_Name[i] || '/' == sz_Name[i]) + { + ++i; + break; + } + } + + if (i == -1) + i = 0; + + for (size_t j = i; j < strlen(sz_Name); ++j) + { + strFileName += sz_Name[j]; + } + + strFileName += "\0"; +} + +void GetExceptionPathName(const char * sz_Name, std::string & OnlyFileName) +{ + GetOnlyFileName(sz_Name, OnlyFileName); +} + +void GetOnlyPathName(const char * sz_Name, std::string & OnlyPathName) +{ + int i; + for (i = strlen(sz_Name) - 1; i >= 0; --i) + { + if ('\\' == sz_Name[i] || '/' == sz_Name[i]) + { + ++i; + break; + } + } + + if (i == -1) + i = 0; + + OnlyPathName.reserve(strlen(sz_Name)); + OnlyPathName = ""; + + for (int j=0; j= strFullPathFileName.length()) + return false; + + DWORD length = min(strGlobalPath.length(), strFullPathFileName.length()); + for (DWORD dwPos = 0; dwPos < length; ++dwPos) + { + if (strGlobalPath[dwPos] != strFullPathFileName[dwPos]) + return false; + } + + *pstrLocalFileName = &c_szFullPathFileName[length]; + + return true; +} + +void GetWorkingFolder(std::string & strFileName) +{ + char buf[128+1]; + _getcwd(buf, 128); + strcat(buf, "/"); + strFileName = buf; +} + +void StringLowers(char * String) +{ + for (DWORD i = 0; i < strlen(String); ++i) + { + String[i] = korean_tolower(String[i]); + } +} + +void StringPath(std::string & rString) +{ + for (DWORD i = 0; i < rString.length(); ++i) + { + if (rString[i] == '\\') + rString[i] = '/'; + else + rString[i] = korean_tolower(rString[i]); + } +} + +void StringPath(char * pString) +{ + for (DWORD i = 0; i < strlen(pString); ++i) + { + if (pString[i] == '\\') + pString[i] = '/'; + else + pString[i] = korean_tolower(pString[i]); + } +} + +void StringPath(const char * c_szSrc, char * szDest) +{ + for (DWORD i = 0; i < strlen(c_szSrc); ++i) + { + if (c_szSrc[i] == '\\') + szDest[i] = '/'; + else + szDest[i] = korean_tolower(c_szSrc[i]); + } +} + +void StringPath(const char * c_szSrc, std::string & rString) +{ + rString = ""; + rString.resize(strlen(c_szSrc)); + + for (DWORD i = 0; i < strlen(c_szSrc); ++i) + { + if (c_szSrc[i] == '\\') + rString[i] = '/'; + else + rString[i] = korean_tolower(c_szSrc[i]); + } +} + +#define ishprint(x) ((((x) & 0xE0) > 0x90) || isprint(x)) + +void PrintAsciiData(const void* void_data, int bytes) +{ + int i, j, k; + const unsigned char* p; + const unsigned char* data; + + data = (const unsigned char*) void_data; + + fprintf(stdout, "------------------------------------------------------------------\n"); + j = bytes; + while (1) + { + k = j >= 16 ? 16 : j; + + p = data; + for (i = 0; i < 16; ++i) + { + if (i >= k) + fprintf(stdout, " "); + else + fprintf(stdout, "%02x ", *p); + p++; + } + + fprintf(stdout, "| "); + + p = data; + for (i = 0; i < k; ++i) + { + if (i >= k) + fprintf(stdout, " "); + else + fprintf(stdout, "%c", ishprint(*p) ? *p : '.'); + p++; + } + + fprintf(stdout, "\n"); + + j -= 16; + data += 16; + + if (j <= 0) + break; + } + + fprintf(stdout, "------------------------------------------------------------------\n"); +} + +int MIN(int a, int b) +{ + return a < b ? a : b; +} + +int MAX(int a, int b) +{ + return a > b ? a : b; +} + +int MINMAX(int min, int value, int max) +{ + if (max < min) + return MAX(min, value); + + int tv; + tv = (min > value ? min : value); + return (max < tv) ? max : tv; +} + +float fMIN(float a, float b) +{ + return a < b ? a : b; +} + +float fMAX(float a, float b) +{ + return a > b ? a : b; +} + +float fMINMAX(float min, float value, float max) +{ + float tv; + + tv = (min > value ? min : value); + return (max < tv) ? max : tv; +} + +bool IsFile(const char* filename) +{ + return _access(filename, 0) == 0 ? true : false; +} + +bool IsGlobalFileName(const char * c_szFileName) +{ + return strchr(c_szFileName, ':') != NULL; +} + +void MyCreateDirectory(const char* path) +{ + if (!path || !*path) + return; + + char * dir; + const char * p; + + if (strlen(path) >= 3) + { + if (*(path + 1) == ':') // C:, D: 츦 üũ + path += 3; + } + + p = path; + + int len = strlen(path) + 1; + dir = new char[len]; + + while (*p) + { + if (*p == '/' || *p == '\\') + { + memset(dir, 0, len); + strncpy(dir, path, p - path); + CreateDirectory(dir, NULL); + } + + ++p; + } + + delete [] dir; +} + +class CDirRemover : public CDir +{ + public: + CDirRemover() + { + } + virtual ~CDirRemover() + { + } + + bool OnFolder(const char* c_szFilter, const char* c_szPathName, const char* c_szFileName) + { + std::string strFullPathName; + strFullPathName = c_szPathName; + strFullPathName += c_szFileName; + + CDirRemover remover; + remover.Create(c_szFilter, strFullPathName.c_str()); + + std::string strWorkingFolder; + GetWorkingFolder(strWorkingFolder); + strWorkingFolder += strFullPathName; + strWorkingFolder += "/"; + StringPath(strWorkingFolder); + ms_strDirectoryDeque.push_back(strWorkingFolder); + return true; + } + bool OnFile(const char* c_szPathName, const char* c_szFileName) + { + std::string strFullPathName; + strFullPathName = c_szPathName; + strFullPathName += c_szFileName; + _chmod(strFullPathName.c_str(), _S_IWRITE); + DeleteFile(strFullPathName.c_str()); + return true; + } + + static void RemoveAllDirectory() + { + for (std::deque::iterator itor = ms_strDirectoryDeque.begin(); itor != ms_strDirectoryDeque.end(); ++itor) + { + const std::string & c_rstrDirectory = *itor; + RemoveDirectory(c_rstrDirectory.c_str()); + } + + ms_strDirectoryDeque.clear(); + } + + protected: + static std::deque ms_strDirectoryDeque; +}; + +std::deque CDirRemover::ms_strDirectoryDeque; + +void RemoveAllDirectory(const char * c_szDirectoryName) +{ + { + CDirRemover remover; + remover.Create("*.*", c_szDirectoryName); + CDirRemover::RemoveAllDirectory(); + } + RemoveDirectory(c_szDirectoryName); +} + +void StringExceptCharacter(std::string * pstrString, const char * c_szCharacter) +{ + int icurPos = 0; + int iNextPos = 0; + + while((iNextPos = pstrString->find_first_of(c_szCharacter, icurPos)) >= 0) + { + std::string strFront = pstrString->substr(icurPos, iNextPos - icurPos); + std::string strBack = pstrString->substr(iNextPos+1, pstrString->length() - iNextPos - 1); + *pstrString = strFront + strBack; + } +} + +bool SplitLine(const char * c_szLine, const char * c_szDelimeter, std::vector * pkVec_strToken) +{ + pkVec_strToken->reserve(10); + pkVec_strToken->clear(); + + std::string strLine = c_szLine; + + DWORD basePos = 0; + + do + { + int beginPos = strLine.find_first_not_of(c_szDelimeter, basePos); + if (beginPos < 0) + return false; + + int endPos; + + if (strLine[beginPos] == '"') + { + ++beginPos; + endPos = strLine.find_first_of("\"", beginPos); + + if (endPos < 0) + return false; + + basePos = endPos + 1; + } + else + { + endPos = strLine.find_first_of(c_szDelimeter, beginPos); + basePos = endPos; + } + + pkVec_strToken->push_back(strLine.substr(beginPos, endPos - beginPos)); + } while (basePos < strLine.length()); + + return true; +} + +void GetExcutedFileName(std::string & r_str) +{ + char szPath[MAX_PATH+1]; + + GetModuleFileName(NULL, szPath, MAX_PATH); + szPath[MAX_PATH] = '\0'; + + r_str = szPath; +} + +const char * _getf(const char* c_szFormat, ...) +{ + static char szBuf[256]; + + va_list args; + va_start(args, c_szFormat); + _vsnprintf(szBuf, sizeof(szBuf), c_szFormat, args); + va_end(args); + + return szBuf; +} + +PCHAR* CommandLineToArgv( PCHAR CmdLine, int* _argc ) +{ + PCHAR* argv; + PCHAR _argv; + ULONG len; + ULONG argc; + CHAR a; + ULONG i, j; + + BOOLEAN in_QM; + BOOLEAN in_TEXT; + BOOLEAN in_SPACE; + + len = strlen(CmdLine); + i = ((len+2)/2)*sizeof(PVOID) + sizeof(PVOID); + + argv = (PCHAR*)GlobalAlloc(GMEM_FIXED, + i + (len+2)*sizeof(CHAR)); + + _argv = (PCHAR)(((PUCHAR)argv)+i); + + argc = 0; + argv[argc] = _argv; + in_QM = FALSE; + in_TEXT = FALSE; + in_SPACE = TRUE; + i = 0; + j = 0; + + while( a = CmdLine[i] ) { + if(in_QM) { + if(a == '\"') { + in_QM = FALSE; + } else { + _argv[j] = a; + j++; + } + } else { + switch(a) { + case '\"': + in_QM = TRUE; + in_TEXT = TRUE; + if(in_SPACE) { + argv[argc] = _argv+j; + argc++; + } + in_SPACE = FALSE; + break; + case ' ': + case '\t': + case '\n': + case '\r': + if(in_TEXT) { + _argv[j] = '\0'; + j++; + } + in_TEXT = FALSE; + in_SPACE = TRUE; + break; + default: + in_TEXT = TRUE; + if(in_SPACE) { + argv[argc] = _argv+j; + argc++; + } + _argv[j] = a; + j++; + in_SPACE = FALSE; + break; + } + } + i++; + } + _argv[j] = '\0'; + argv[argc] = NULL; + + (*_argc) = argc; + return argv; +} diff --git a/source/EterBase/Utils.h b/source/EterBase/Utils.h new file mode 100644 index 0000000..cfaacc8 --- /dev/null +++ b/source/EterBase/Utils.h @@ -0,0 +1,218 @@ +#ifndef __INC_ETER2_ETERBASE_UTILS_H__ +#define __INC_ETER2_ETERBASE_UTILS_H__ + +#include +#include +#include + +#ifndef SAFE_DELETE +#define SAFE_DELETE(p) { if (p) { delete (p); (p) = NULL; } } +#endif + +#ifndef SAFE_DELETE_ARRAY +#define SAFE_DELETE_ARRAY(p) { if (p) { delete[] (p); (p) = NULL; } } +#endif + +#ifndef SAFE_RELEASE +#define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p) = NULL; } } +#endif + +#ifndef SAFE_FREE_GLOBAL +#define SAFE_FREE_GLOBAL(p) { if (p) { ::GlobalFree(p); (p) = NULL; } } +#endif + +#ifndef SAFE_FREE_LIBRARY +#define SAFE_FREE_LIBRARY(p) { if (p) { ::FreeLibrary(p); (p) = NULL; } } +#endif + +#define AssertLog(str) TraceError(str); assert(!str) + +#ifndef MAKEFOURCC +#define MAKEFOURCC(ch0, ch1, ch2, ch3) \ + ((DWORD)(BYTE) (ch0 ) | ((DWORD)(BYTE) (ch1) << 8) | \ + ((DWORD)(BYTE) (ch2) << 16) | ((DWORD)(BYTE) (ch3) << 24)) +#endif // defined(MAKEFOURCC) + +#ifndef IS_SET +#define IS_SET(flag,bit) ((flag) & (bit)) +#endif + +#ifndef SET_BIT +#define SET_BIT(var,bit) ((var) |= (bit)) +#endif + +#ifndef REMOVE_BIT +#define REMOVE_BIT(var,bit) ((var) &= ~(bit)) +#endif + +#ifndef TOGGLE_BIT +#define TOGGLE_BIT(var,bit) ((var) = (var) ^ (bit)) +#endif + +extern const char * CreateTempFileName(const char * c_pszPrefix = NULL); +extern void GetFilePathNameExtension(const char* c_szFile, int len, std::string* pstPath, std::string* pstName, std::string* pstExt); +extern void GetFileExtension(const char* c_szFile, int len, std::string* pstExt); +extern void GetFileNameParts(const char* c_szFile, int len, char* pszPath, char* pszName, char* pszExt); +extern void GetOldIndexingName(char * szName, int Index); +extern void GetIndexingName(char * szName, DWORD Index); +extern void stl_lowers(std::string& rstRet); +extern void GetOnlyFileName(const char * sz_Name, std::string & strFileName); +extern void GetOnlyPathName(const char * sz_Name, std::string & OnlyPathName); +extern const char * GetOnlyPathName(const char * c_szName); +bool GetLocalFileName(const char * c_szGlobalPath, const char * c_szFullPathFileName, std::string * pstrLocalFileName); +extern void GetExceptionPathName(const char * sz_Name, std::string & OnlyFileName); +extern void GetWorkingFolder(std::string & strFileName); +extern void StringLowers(char * pString); +extern void StringPath(std::string & rString); +extern void StringPath(char * pString); // ҹڷ , \ / ٲ۴. +extern void StringPath(const char * c_szSrc, char * szDest); // ҹڷ , \ / ٲ۴. +extern void StringPath(const char * c_szSrc, std::string & rString); // ҹڷ , \ / ٲ۴. +extern void PrintAsciiData(const void* data, int bytes); +bool IsFile(const char* filename); +bool IsGlobalFileName(const char * c_szFileName); +int MIN(int a, int b); +int MAX(int a, int b); +int MINMAX(int min, int value, int max); +float fMIN(float a, float b); +float fMAX(float a, float b); +float fMINMAX(float min, float value, float max); +void MyCreateDirectory(const char* path); +void RemoveAllDirectory(const char * c_szDirectoryName); +bool SplitLine(const char * c_szLine, const char * c_szDelimeter, std::vector * pkVec_strToken); +const char * _getf(const char* c_szFormat, ...); +PCHAR* CommandLineToArgv( PCHAR CmdLine, int* _argc ); + +template +T EL_DegreeToRadian(T degree) +{ + const T PI = T(3.141592); + return T(PI*degree/180.0f); +} + +template +void ELPlainCoord_GetRotatedPixelPosition(T centerX, T centerY, T distance, T rotDegree, T* pdstX, T* pdstY) +{ + T rotRadian=EL_DegreeToRadian(rotDegree); + *pdstX=centerX+distance*T(sin((double)rotRadian)); + *pdstY=centerY+distance*T(cos((double)rotRadian)); +} + +template +T EL_SignedDegreeToUnsignedDegree(T fSrc) +{ + if (fSrc<0.0f) + return T(360.0+T(fmod(fSrc, 360.0))); + + return T(fmod(fSrc, 360.0)); +} + +template +T ELRightCoord_ConvertToPlainCoordDegree(T srcDegree) +{ + return T(fmod(450.0 - srcDegree, 360.0)); +} + +template +void string_join(const std::string& sep, const C& container, std::string* ret) +{ + unsigned int capacity = sep.length() * container.size() - 1; + + // calculate string sequence + { + for (auto i = container.begin(); i != container.end(); ++i) + capacity += (*i).length(); + } + + std::string buf; + buf.reserve(capacity); + + // join strings + { + auto cur = container.begin(); + auto end = container.end(); + --end; + + while (cur != end) + { + buf.append(*cur++); + buf.append(sep); + } + buf.append(*cur); + } + + swap(*ret, buf); +} + +__forceinline int htoi(const wchar_t *s, int size) +{ + const wchar_t *t = s; + int x = 0, y = 1; + s += size; + + while (t <= --s) + { + if (L'0' <= *s && *s <= L'9') + x += y * (*s - L'0'); + else if (L'a' <= *s && *s <= L'f') + x += y * (*s - L'a' + 10); + else if (L'A' <= *s && *s <= L'F') + x += y * (10 + *s - L'A'); + else + return -1; /* invalid input! */ + y <<= 4; + } + + return x; +} + +__forceinline int htoi(const char *s, int size) +{ + const char *t = s; + int x = 0, y = 1; + s += size; + + while (t <= --s) + { + if ('0' <= *s && *s <= '9') + x += y * (*s - '0'); + else if ('a' <= *s && *s <= 'f') + x += y * (*s - 'a' + 10); + else if ('A' <= *s && *s <= 'F') + x += y * (10 + *s - 'A'); + else + return -1; /* invalid input! */ + y <<= 4; + } + + return x; +} + +__forceinline int htoi(const char *s) +{ + const char *t = s; + int x = 0, y = 1; + s += strlen(s); + + while (t <= --s) + { + if ('0' <= *s && *s <= '9') + x += y * (*s - '0'); + else if ('a' <= *s && *s <= 'f') + x += y * (*s - 'a' + 10); + else if ('A' <= *s && *s <= 'F') + x += y * (10 + *s - 'A'); + else + return -1; /* invalid input! */ + y <<= 4; + } + + return x; +} + +typedef std::vector TTokenVector; + +void StringExceptCharacter(std::string * pstrString, const char * c_szCharacter); + +extern void GetExcutedFileName(std::string & r_str); + +#endif \ No newline at end of file diff --git a/source/EterBase/cipher.cpp b/source/EterBase/cipher.cpp new file mode 100644 index 0000000..1a7e96b --- /dev/null +++ b/source/EterBase/cipher.cpp @@ -0,0 +1,448 @@ +#include "stdafx.h" + +#include "cipher.h" + +#ifdef _IMPROVED_PACKET_ENCRYPTION_ + +//#pragma warning(push) +//#pragma warning(disable: 4100 4127 4189 4231 4512 4706) + +#include +#include +#include + +// Diffie-Hellman key agreement +#include +#include + +// AES winner and candidates +#include +#include +#include +#include +#include +#include +// Other block ciphers +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __THEMIDA__ +#include +#endif + +#include "Debug.h" + + +using namespace CryptoPP; + +// Block cipher algorithm selector abstract base class. +struct BlockCipherAlgorithm { + enum { + kDefault, // to give more chances to default algorithm + // AES winner and candidates +// kAES, // Rijndael + kRC6, + kMARS, + kTwofish, + kSerpent, + kCAST256, + // Other block ciphers + kIDEA, + k3DES, // DES-EDE2 + kCamellia, + kSEED, + kRC5, + kBlowfish, + kTEA, + //kSKIPJACK, + kSHACAL2, + // End sentinel + kMaxAlgorithms + }; + + BlockCipherAlgorithm() {} + virtual ~BlockCipherAlgorithm() {} + + static BlockCipherAlgorithm* Pick(int hint); + + virtual int GetBlockSize() const = 0; + virtual int GetDefaultKeyLength() const = 0; + virtual int GetIVLength() const = 0; + + virtual SymmetricCipher* CreateEncoder(const CryptoPP::byte* key, size_t keylen, + const CryptoPP::byte* iv) const = 0; + virtual SymmetricCipher* CreateDecoder(const CryptoPP::byte* key, size_t keylen, + const CryptoPP::byte* iv) const = 0; +}; + +// Block cipher (with CTR mode) algorithm selector template class. +template +struct BlockCipherDetail : public BlockCipherAlgorithm { + BlockCipherDetail() {} + virtual ~BlockCipherDetail() {} + + virtual int GetBlockSize() const { return T::BLOCKSIZE; } + virtual int GetDefaultKeyLength() const { return T::DEFAULT_KEYLENGTH; } + virtual int GetIVLength() const { return T::IV_LENGTH; } + + virtual SymmetricCipher* CreateEncoder(const CryptoPP::byte* key, size_t keylen, + const CryptoPP::byte* iv) const + { + return new typename CTR_Mode::Encryption(key, keylen, iv); + } + virtual SymmetricCipher* CreateDecoder(const CryptoPP::byte* key, size_t keylen, + const CryptoPP::byte* iv) const + { + return new typename CTR_Mode::Decryption(key, keylen, iv); + } +}; + +// Key agreement scheme abstract class. +class KeyAgreement { +public: + KeyAgreement() {} + virtual ~KeyAgreement() {} + + virtual size_t Prepare(void* buffer, size_t* length) = 0; + virtual bool Agree(size_t agreed_length, const void* buffer, size_t length) = 0; + + const SecByteBlock& shared() const { return shared_; } + +protected: + SecByteBlock shared_; +}; + +// Crypto++ Unified Diffie-Hellman key agreement scheme implementation. +class DH2KeyAgreement : public KeyAgreement { +public: + DH2KeyAgreement(); + virtual ~DH2KeyAgreement(); + + virtual size_t Prepare(void* buffer, size_t* length); + virtual bool Agree(size_t agreed_length, const void* buffer, size_t length); + +private: + DH dh_; + DH2 dh2_; + SecByteBlock spriv_key_; + SecByteBlock epriv_key_; +}; + +Cipher::Cipher() +: activated_(false), encoder_(NULL), decoder_(NULL), key_agreement_(NULL) { +} + +Cipher::~Cipher() { + if (activated_) { + CleanUp(); + } +} + +void Cipher::CleanUp() { + if (encoder_ != NULL) { + delete encoder_; + encoder_ = NULL; + } + if (decoder_ != NULL) { + delete decoder_; + decoder_ = NULL; + } + if (key_agreement_ != NULL) { + delete key_agreement_; + key_agreement_ = NULL; + } + activated_ = false; +} + +size_t Cipher::Prepare(void* buffer, size_t* length) { +#ifdef __THEMIDA__ + VM_START +#endif + + assert(key_agreement_ == NULL); + key_agreement_ = new DH2KeyAgreement(); + assert(key_agreement_ != NULL); + size_t agreed_length = key_agreement_->Prepare(buffer, length); + if (agreed_length == 0) { + delete key_agreement_; + key_agreement_ = NULL; + } +#ifdef __THEMIDA__ + VM_END +#endif + + return agreed_length; +} + +bool Cipher::Activate(bool polarity, size_t agreed_length, + const void* buffer, size_t length) { +#ifdef __THEMIDA__ + VM_START +#endif + + assert(activated_ == false); + assert(key_agreement_ != NULL); + bool result = false; + if (key_agreement_->Agree(agreed_length, buffer, length)) { + result = SetUp(polarity); + } + delete key_agreement_; + key_agreement_ = NULL; +#ifdef __THEMIDA__ + VM_END +#endif + + return result; +} + +bool Cipher::SetUp(bool polarity) { +#ifdef __THEMIDA__ + VM_START +#endif + + assert(key_agreement_ != NULL); + const SecByteBlock& shared = key_agreement_->shared(); + + // Pick a block cipher algorithm + + if (shared.size() < 2) { + return false; + } + + int hint_0 = shared.BytePtr()[*(shared.BytePtr()) % shared.size()]; + int hint_1 = shared.BytePtr()[*(shared.BytePtr() + 1) % shared.size()]; + BlockCipherAlgorithm* detail_0 = BlockCipherAlgorithm::Pick(hint_0); + BlockCipherAlgorithm* detail_1 = BlockCipherAlgorithm::Pick(hint_1); + assert(detail_0 != NULL); + assert(detail_1 != NULL); + std::unique_ptr algorithm_0(detail_0); + std::unique_ptr algorithm_1(detail_1); + + const size_t key_length_0 = algorithm_0->GetDefaultKeyLength(); + const size_t iv_length_0 = algorithm_0->GetBlockSize(); + + if (shared.size() < key_length_0 || shared.size() < iv_length_0) { + return false; + } + + const size_t key_length_1 = algorithm_1->GetDefaultKeyLength(); + const size_t iv_length_1 = algorithm_1->GetBlockSize(); + + if (shared.size() < key_length_1 || shared.size() < iv_length_1) { + return false; + } + + // Pick encryption keys and initial vectors + + SecByteBlock key_0(key_length_0), iv_0(iv_length_0); + SecByteBlock key_1(key_length_1), iv_1(iv_length_1); + + size_t offset; + + key_0.Assign(shared, key_length_0); + offset = key_length_0; + offset = min(key_length_0, shared.size() - key_length_1); + key_1.Assign(shared.BytePtr() + offset, key_length_1); + + offset = shared.size() - iv_length_0; + iv_0.Assign(shared.BytePtr() + offset, iv_length_0); + offset = (offset < iv_length_1 ? 0 : offset - iv_length_1); + iv_1.Assign(shared.BytePtr() + offset, iv_length_1); + + // Create encryption/decryption objects + + if (polarity) { + encoder_ = algorithm_1->CreateEncoder(key_1, key_1.size(), iv_1); + decoder_ = algorithm_0->CreateDecoder(key_0, key_0.size(), iv_0); + } else { + encoder_ = algorithm_0->CreateEncoder(key_0, key_0.size(), iv_0); + decoder_ = algorithm_1->CreateDecoder(key_1, key_1.size(), iv_1); + } + + assert(encoder_ != NULL); + assert(decoder_ != NULL); +#ifdef __THEMIDA__ + VM_END +#endif + + return true; +} + +BlockCipherAlgorithm* BlockCipherAlgorithm::Pick(int hint) { + BlockCipherAlgorithm* detail; + int selector = hint % kMaxAlgorithms; + switch (selector) { + //case kAES: + // detail = new BlockCipherDetail(); + break; + case kRC6: + detail = new BlockCipherDetail(); + break; + case kMARS: + detail = new BlockCipherDetail(); + break; + case kTwofish: + detail = new BlockCipherDetail(); + break; + case kSerpent: + detail = new BlockCipherDetail(); + break; + case kCAST256: + detail = new BlockCipherDetail(); + break; + case kIDEA: + detail = new BlockCipherDetail(); + break; + case k3DES: + detail = new BlockCipherDetail(); + break; + case kCamellia: + detail = new BlockCipherDetail(); + break; + case kSEED: + detail = new BlockCipherDetail(); + break; + case kRC5: + detail = new BlockCipherDetail(); + break; + case kBlowfish: + detail = new BlockCipherDetail(); + break; + case kTEA: + detail = new BlockCipherDetail(); + break; +// case kSKIPJACK: +// detail = new BlockCipherDetail(); +// break; + case kSHACAL2: + detail = new BlockCipherDetail(); + break; + case kDefault: + default: + detail = new BlockCipherDetail(); // default algorithm + break; + } + + return detail; +} + +DH2KeyAgreement::DH2KeyAgreement() : dh_(), dh2_(dh_) { +} + +DH2KeyAgreement::~DH2KeyAgreement() { +} + +size_t DH2KeyAgreement::Prepare(void* buffer, size_t* length) { +#ifdef __THEMIDA__ + VM_START +#endif + + // RFC 5114, 1024-bit MODP Group with 160-bit Prime Order Subgroup + // http://tools.ietf.org/html/rfc5114#section-2.1 + Integer p("0xB10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C6" + "9A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C0" + "13ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD70" + "98488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0" + "A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708" + "DF1FB2BC2E4A4371"); + + Integer g("0xA4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507F" + "D6406CFF14266D31266FEA1E5C41564B777E690F5504F213" + "160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1" + "909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28A" + "D662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24" + "855E6EEB22B3B2E5"); + + Integer q("0xF518AA8781A8DF278ABA4E7D64B7CB9D49462353"); + + // Schnorr Group primes are of the form p = rq + 1, p and q prime. They + // provide a subgroup order. In the case of 1024-bit MODP Group, the + // security level is 80 bits (based on the 160-bit prime order subgroup). + + // For a compare/contrast of using the maximum security level, see + // dh-unified.zip. Also see http://www.cryptopp.com/wiki/Diffie-Hellman + // and http://www.cryptopp.com/wiki/Security_level . + + AutoSeededRandomPool rnd; + + dh_.AccessGroupParameters().Initialize(p, q, g); + + if(!dh_.GetGroupParameters().ValidateGroup(rnd, 3)) { + // Failed to validate prime and generator + return 0; + } + + size_t count = 0; + + p = dh_.GetGroupParameters().GetModulus(); + q = dh_.GetGroupParameters().GetSubgroupOrder(); + g = dh_.GetGroupParameters().GetGenerator(); + + // http://groups.google.com/group/sci.crypt/browse_thread/thread/7dc7eeb04a09f0ce + Integer v = ModularExponentiation(g, q, p); + + if(v != Integer::One()) { + // Failed to verify order of the subgroup + return 0; + } + + ////////////////////////////////////////////////////////////// + + spriv_key_.New(dh2_.StaticPrivateKeyLength()); + epriv_key_.New(dh2_.EphemeralPrivateKeyLength()); + SecByteBlock spub_key(dh2_.StaticPublicKeyLength()); + SecByteBlock epub_key(dh2_.EphemeralPublicKeyLength()); + + dh2_.GenerateStaticKeyPair(rnd, spriv_key_, spub_key); + dh2_.GenerateEphemeralKeyPair(rnd, epriv_key_, epub_key); + + // Prepare key agreement data + const size_t spub_key_length = spub_key.size(); + const size_t epub_key_length = epub_key.size(); + const size_t data_length = spub_key_length + epub_key_length; + + if (*length < data_length) { + // Not enough data buffer length b-l-a-c-k + return 0; + } + + *length = data_length; + CryptoPP::byte* buf = (CryptoPP::byte*)buffer; + memcpy(buf, spub_key.BytePtr(), spub_key_length); + memcpy(buf + spub_key_length, epub_key.BytePtr(), epub_key_length); + +#ifdef __THEMIDA__ + VM_END +#endif + + return dh2_.AgreedValueLength(); +} + +bool DH2KeyAgreement::Agree(size_t agreed_length, const void* buffer, size_t length) { + if (agreed_length != dh2_.AgreedValueLength()) { + // Shared secret size mismatch + return false; + } + const size_t spub_key_length = dh2_.StaticPublicKeyLength(); + const size_t epub_key_length = dh2_.EphemeralPublicKeyLength(); + if (length != (spub_key_length + epub_key_length)) { + // Wrong data length + return false; + } + shared_.New(dh2_.AgreedValueLength()); + const CryptoPP::byte* buf = (const CryptoPP::byte*)buffer; + if (!dh2_.Agree(shared_, spriv_key_, epriv_key_, buf, buf + spub_key_length)) { + // Failed to reach shared secret + return false; + } + return true; +} + +#endif diff --git a/source/EterBase/cipher.h b/source/EterBase/cipher.h new file mode 100644 index 0000000..038c5cd --- /dev/null +++ b/source/EterBase/cipher.h @@ -0,0 +1,62 @@ +#ifndef __CIPHER_H__ +#define __CIPHER_H__ + +#ifdef _IMPROVED_PACKET_ENCRYPTION_ + +#pragma warning(push) +#pragma warning(disable: 4100 4127 4189 4231 4512 4706) +#include +#pragma warning(pop) +// Forward declaration +class KeyAgreement; + +//THEMIDA +// Communication channel encryption handler. +class Cipher { + public: + explicit Cipher(); + ~Cipher(); + + void CleanUp(); + + // Returns agreed value length in CryptoPP::bytes, or zero on failure. + size_t Prepare(void* buffer, size_t* length); + // Try to activate cipher algorithm with agreement data received from peer. + bool Activate(bool polarity, size_t agreed_length, + const void* buffer, size_t length); + + // Encrypts the given block of data. (no padding required) + void Encrypt(void* buffer, size_t length) { + assert(activated_); + if (!activated_) { + return; + } + encoder_->ProcessData((CryptoPP::byte*)buffer, (const CryptoPP::byte*)buffer, length); + } + // Decrypts the given block of data. (no padding required) + void Decrypt(void* buffer, size_t length) { + assert(activated_); + if (!activated_) { + return; + } + decoder_->ProcessData((CryptoPP::byte*)buffer, (const CryptoPP::byte*)buffer, length); + } + + bool activated() const { return activated_; } + + void set_activated(bool value) { activated_ = value; } + + private: + bool SetUp(bool polarity); + + bool activated_; + + CryptoPP::SymmetricCipher* encoder_; + CryptoPP::SymmetricCipher* decoder_; + + KeyAgreement* key_agreement_; +}; + +#endif // _IMPROVED_PACKET_ENCRYPTION_ + +#endif // __CIPHER_H__ diff --git a/source/EterBase/error.cpp b/source/EterBase/error.cpp new file mode 100644 index 0000000..b815904 --- /dev/null +++ b/source/EterBase/error.cpp @@ -0,0 +1,208 @@ +#include "StdAfx.h" + +#include +#include +#include +#include + +FILE * fException; + +/* +static char __msg[4000], __cmsg[4000]; +static int __idx; +CLZObject __l; +*/ +/* +typedef BOOL +(CALLBACK *PENUMLOADED_MODULES_CALLBACK)( + __in PCSTR ModuleName, + __in ULONG ModuleBase, + __in ULONG ModuleSize, + __in_opt PVOID UserContext + ); +*/ +#if _MSC_VER >= 1400 +BOOL CALLBACK EnumerateLoadedModulesProc(PCSTR ModuleName, ULONG ModuleBase, ULONG ModuleSize, PVOID UserContext) +#else +BOOL CALLBACK EnumerateLoadedModulesProc(PSTR ModuleName, ULONG ModuleBase, ULONG ModuleSize, PVOID UserContext) +#endif +{ + DWORD offset = *((DWORD*)UserContext); + + if (offset >= ModuleBase && offset <= ModuleBase + ModuleSize) + { + fprintf(fException, "%s", ModuleName); + //__idx += sprintf(__msg+__idx, "%s", ModuleName); + return FALSE; + } + else + return TRUE; +} + +LONG __stdcall EterExceptionFilter(_EXCEPTION_POINTERS* pExceptionInfo) +{ + HANDLE hProcess = GetCurrentProcess(); + HANDLE hThread = GetCurrentThread(); + + fException = fopen("ErrorLog.txt", "wt"); + if (fException) + { + char module_name[256]; + time_t module_time; + + HMODULE hModule = GetModuleHandle(NULL); + + GetModuleFileName(hModule, module_name, sizeof(module_name)); + module_time = (time_t)GetTimestampForLoadedLibrary(hModule); + + fprintf(fException, "Module Name: %s\n", module_name); + fprintf(fException, "Time Stamp: 0x%08x - %s\n", module_time, ctime(&module_time)); + fprintf(fException, "\n"); + fprintf(fException, "Exception Type: 0x%08x\n", pExceptionInfo->ExceptionRecord->ExceptionCode); + fprintf(fException, "\n"); + + /* + { + __idx+=sprintf(__msg+__idx,"Module Name: %s\n", module_name); + __idx+=sprintf(__msg+__idx, "Time Stamp: 0x%08x - %s\n", module_time, ctime(&module_time)); + __idx+=sprintf(__msg+__idx, "\n"); + __idx+=sprintf(__msg+__idx, "Exception Type: 0x%08x\n", pExceptionInfo->ExceptionRecord->ExceptionCode); + __idx+=sprintf(__msg+__idx, "\n"); + } + */ + + CONTEXT& context = *pExceptionInfo->ContextRecord; + + fprintf(fException, "eax: 0x%08x\tebx: 0x%08x\n", context.Eax, context.Ebx); + fprintf(fException, "ecx: 0x%08x\tedx: 0x%08x\n", context.Ecx, context.Edx); + fprintf(fException, "esi: 0x%08x\tedi: 0x%08x\n", context.Esi, context.Edi); + fprintf(fException, "ebp: 0x%08x\tesp: 0x%08x\n", context.Ebp, context.Esp); + fprintf(fException, "\n"); + /* + { + __idx+=sprintf(__msg+__idx, "eax: 0x%08x\tebx: 0x%08x\n", context.Eax, context.Ebx); + __idx+=sprintf(__msg+__idx, "ecx: 0x%08x\tedx: 0x%08x\n", context.Ecx, context.Edx); + __idx+=sprintf(__msg+__idx, "esi: 0x%08x\tedi: 0x%08x\n", context.Esi, context.Edi); + __idx+=sprintf(__msg+__idx, "ebp: 0x%08x\tesp: 0x%08x\n", context.Ebp, context.Esp); + __idx+=sprintf(__msg+__idx, "\n"); + } + */ + + STACKFRAME stackFrame = {0,}; + stackFrame.AddrPC.Offset = context.Eip; + stackFrame.AddrPC.Mode = AddrModeFlat; + stackFrame.AddrStack.Offset = context.Esp; + stackFrame.AddrStack.Mode = AddrModeFlat; + stackFrame.AddrFrame.Offset = context.Ebp; + stackFrame.AddrFrame.Mode = AddrModeFlat; + + for (int i=0; i < 512 && stackFrame.AddrPC.Offset; ++i) + { + if (StackWalk(IMAGE_FILE_MACHINE_I386, hProcess, hThread, &stackFrame, &context, NULL, NULL, NULL, NULL) != FALSE) + { + fprintf(fException, "0x%08x\t", stackFrame.AddrPC.Offset); + //__idx+=sprintf(__msg+__idx, "0x%08x\t", stackFrame.AddrPC.Offset); + EnumerateLoadedModules(hProcess, (PENUMLOADED_MODULES_CALLBACK) EnumerateLoadedModulesProc, &stackFrame.AddrPC.Offset); + fprintf(fException, "\n"); + + //__idx+=sprintf(__msg+__idx, "\n"); + } + else + { + break; + } + } + + fprintf(fException, "\n"); + //__idx+=sprintf(__msg+__idx, "\n"); + + +/* + BYTE* stack = (BYTE*)(context.Esp); + fprintf(fException, "stack %08x - %08x\n", context.Esp, context.Esp+1024); + //__idx+=sprintf(__msg+__idx, "stack %08x - %08x\n", context.Esp, context.Esp+1024); + + for(i=0; i<16; ++i) + { + fprintf(fException, "%08X : ", context.Esp+i*16); + //__idx+=sprintf(__msg+__idx, "%08X : ", context.Esp+i*16); + for(int j=0; j<16; ++j) + { + fprintf(fException, "%02X ", stack[i*16+j]); + //__idx+=sprintf(__msg+__idx, "%02X ", stack[i*16+j]); + } + fprintf(fException, "\n"); + //__idx+=sprintf(__msg+__idx, "\n"); + } + fprintf(fException, "\n"); + //__idx+=sprintf(__msg+__idx, "\n"); +*/ + + fflush(fException); + + fclose(fException); + fException = NULL; + + //WinExec() + /*CreateProcess("cmd.exe",NULL,NULL,NULL,FALSE, + CREATE_NEW_PROCESS_GROUP|DETACHED_PROCESS,NULL,NULL,NULL,NULL); + MessageBox(NULL," ࿡ ġ ߻Ͽϴ.\n ϰ α׸ ϴ.\n α׸ ðڽϱ?"," ߻!",MB_YESNO);*/ + + /* + __l.BeginCompressInBuffer(__msg,__idx,__cmsg); + if (__l.Compress()) + { + //fprintf(fException,"Compress printing\n"); + // send this to server + SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + + ioctlsocket(s,FIONBIO,0); + + if (s==INVALID_SOCKET) + { + //fprintf(fException,"INVALID %X\n",WSAGetLastError()); + } + + sockaddr_in sa; + sa.sin_family = AF_INET; + sa.sin_port = htons(19294); + sa.sin_addr.s_addr = inet_addr("147.46.127.42"); + if (connect(s,(sockaddr*)&sa,sizeof(sa))) + { + //fprintf(fException,"%X\n",WSAGetLastError()); + } + + int total = 0; + int ret=0; + while(1) + { + //ret = send(s,(char*)__msg+total,__idx-total,0); + ret = send(s,(char*)__l.GetBuffer()+total,__l.GetSize()-total,0); + //fprintf(fException,"send %d\n",ret); + if (ret<0) + { + //fprintf(fException,"%X\n",WSAGetLastError()); + break; + } + total+=ret; + if (total>=__idx) + //if (total>=__l.GetSize()) + break; + } + //__l.GetBuffer(); + Sleep(500); + closesocket(s); + }*/ + + WinExec("errorlog.exe",SW_SHOW); + + + } + + return EXCEPTION_EXECUTE_HANDLER; +} + +void SetEterExceptionHandler() +{ + SetUnhandledExceptionFilter(EterExceptionFilter); +} \ No newline at end of file diff --git a/source/EterBase/error.h b/source/EterBase/error.h new file mode 100644 index 0000000..1f86045 --- /dev/null +++ b/source/EterBase/error.h @@ -0,0 +1,2 @@ +#pragma once +extern void SetEterExceptionHandler(); \ No newline at end of file diff --git a/source/EterBase/lzo.cpp b/source/EterBase/lzo.cpp new file mode 100644 index 0000000..f42d8d4 --- /dev/null +++ b/source/EterBase/lzo.cpp @@ -0,0 +1,411 @@ +#include "StdAfx.h" +#include +#include + +#include "lzo.h" +#include "tea.h" +#include "debug.h" + +#define dbg_printf + +static class LZOFreeMemoryMgr +{ +public: + enum + { + REUSING_CAPACITY = 64*1024, + }; +public: + ~LZOFreeMemoryMgr() + { + std::vector::iterator i; + for (i = m_freeVector.begin(); i != m_freeVector.end(); ++i) + delete *i; + + m_freeVector.clear(); + } + BYTE* Alloc(unsigned capacity) + { + assert(capacity > 0); + if (capacity < REUSING_CAPACITY) + { + if (!m_freeVector.empty()) + { + BYTE* freeMem = m_freeVector.back(); + m_freeVector.pop_back(); + + dbg_printf("lzo.reuse_alloc\t%p(%d) free\n", freeMem, capacity); + return freeMem; + } + BYTE* newMem = new BYTE[REUSING_CAPACITY]; + dbg_printf("lzo.reuse_alloc\t%p(%d) real\n", newMem, capacity); + return newMem; + } + BYTE* newMem = new BYTE[capacity]; + dbg_printf("lzo.real_alloc\t%p(%d)\n", newMem, capacity); + return newMem; + } + void Free(BYTE* ptr, unsigned capacity) + { + assert(ptr != NULL); + assert(capacity > 0); + if (capacity < REUSING_CAPACITY) + { + dbg_printf("lzo.reuse_free\t%p(%d)\n", ptr, capacity); + m_freeVector.push_back(ptr); + return; + } + + dbg_printf("lzo.real_free\t%p(%d)\n", ptr, capacity); + delete [] ptr; + } +private: + std::vector m_freeVector; +} gs_freeMemMgr; + + + +DWORD CLZObject::ms_dwFourCC = MAKEFOURCC('M', 'C', 'O', 'Z'); + +CLZObject::CLZObject() +{ + Initialize(); +} + +void CLZObject::Initialize() +{ + m_bInBuffer = false; + m_pbBuffer = NULL; + m_dwBufferSize = 0; + + m_pHeader = NULL; + m_pbIn = NULL; + m_bCompressed = false; +} + +void CLZObject::Clear() +{ + if (m_pbBuffer && !m_bInBuffer) + gs_freeMemMgr.Free(m_pbBuffer, m_dwBufferSize); + + if (m_dwBufferSize > 0) + { + dbg_printf("lzo.free %d\n", m_dwBufferSize); + } + + Initialize(); +} + +CLZObject::~CLZObject() +{ + Clear(); +} + +DWORD CLZObject::GetSize() +{ + assert(m_pHeader); + + if (m_bCompressed) + { + if (m_pHeader->dwEncryptSize) + return sizeof(THeader) + sizeof(DWORD) + m_pHeader->dwEncryptSize; + else + return sizeof(THeader) + sizeof(DWORD) + m_pHeader->dwCompressedSize; + } + else + return m_pHeader->dwRealSize; +} + +void CLZObject::BeginCompress(const void * pvIn, UINT uiInLen) +{ + m_pbIn = (const BYTE *) pvIn; + + // sizeof(SHeader) + + // ȣȭ fourCC 4Ʈ + // ִ ִ 뷮 + + // ȣȭ 8 Ʈ + m_dwBufferSize = sizeof(THeader) + sizeof(DWORD) + (uiInLen + uiInLen / 64 + 16 + 3) + 8; + + m_pbBuffer = gs_freeMemMgr.Alloc(m_dwBufferSize); + memset(m_pbBuffer, 0, m_dwBufferSize); + + m_pHeader = (THeader *) m_pbBuffer; + m_pHeader->dwFourCC = ms_dwFourCC; + m_pHeader->dwEncryptSize = m_pHeader->dwCompressedSize = m_pHeader->dwRealSize = 0; + m_pHeader->dwRealSize = uiInLen; +} + +void CLZObject::BeginCompressInBuffer(const void * pvIn, UINT uiInLen, void * /*pvOut*/) +{ + m_pbIn = (const BYTE *) pvIn; + + // sizeof(SHeader) + + // ȣȭ fourCC 4Ʈ + // ִ ִ 뷮 + + // ȣȭ 8 Ʈ + m_dwBufferSize = sizeof(THeader) + sizeof(DWORD) + (uiInLen + uiInLen / 64 + 16 + 3) + 8; + + m_pbBuffer = gs_freeMemMgr.Alloc(m_dwBufferSize); + memset(m_pbBuffer, 0, m_dwBufferSize); + + m_pHeader = (THeader *) m_pbBuffer; + m_pHeader->dwFourCC = ms_dwFourCC; + m_pHeader->dwEncryptSize = m_pHeader->dwCompressedSize = m_pHeader->dwRealSize = 0; + m_pHeader->dwRealSize = uiInLen; + m_bInBuffer = true; +} + +bool CLZObject::Compress() +{ + UINT iOutLen; + BYTE * pbBuffer; + + pbBuffer = m_pbBuffer + sizeof(THeader); + *(DWORD *) pbBuffer = ms_dwFourCC; + pbBuffer += sizeof(DWORD); + +#if defined( LZO1X_999_MEM_COMPRESS ) + int r = lzo1x_999_compress((BYTE *) m_pbIn, m_pHeader->dwRealSize, pbBuffer, (lzo_uint*) &iOutLen, CLZO::Instance().GetWorkMemory()); +#else + int r = lzo1x_1_compress((BYTE *) m_pbIn, m_pHeader->dwRealSize, pbBuffer, (lzo_uint*) &iOutLen, CLZO::Instance().GetWorkMemory()); +#endif + + if (LZO_E_OK != r) + { + TraceError("LZO: lzo1x_999_compress failed"); + return false; + } + + m_pHeader->dwCompressedSize = iOutLen; + m_bCompressed = true; + return true; +} + +bool CLZObject::BeginDecompress(const void * pvIn) +{ + THeader * pHeader = (THeader *) pvIn; + + if (pHeader->dwFourCC != ms_dwFourCC) + { + TraceError("LZObject: not a valid data"); + return false; + } + + m_pHeader = pHeader; + m_pbIn = (const BYTE *) pvIn + (sizeof(THeader) + sizeof(DWORD)); + + /* + static unsigned sum = 0; + static unsigned count = 0; + sum += pHeader->dwRealSize; + count++; + printf("decompress cur: %d, ave: %d\n", pHeader->dwRealSize, sum/count); + */ + m_dwBufferSize = pHeader->dwRealSize; + m_pbBuffer = gs_freeMemMgr.Alloc(m_dwBufferSize); + memset(m_pbBuffer, 0, pHeader->dwRealSize); + return true; +} + +class DecryptBuffer +{ +public: + enum + { + LOCAL_BUF_SIZE = 8 * 1024, + }; +public: + DecryptBuffer(unsigned size) + { + static unsigned count = 0; + static unsigned sum = 0; + static unsigned maxSize = 0; + + sum += size; + count++; + + maxSize = max(size, maxSize); + if (size >= LOCAL_BUF_SIZE) + { + m_buf = new char[size]; + dbg_printf("DecryptBuffer - AllocHeap %d max(%d) ave(%d)\n", size, maxSize/1024, sum/count); + } + else + { + dbg_printf("DecryptBuffer - AllocStack %d max(%d) ave(%d)\n", size, maxSize/1024, sum/count); + m_buf = m_local_buf; + } + } + ~DecryptBuffer() + { + if (m_local_buf != m_buf) + { + dbg_printf("DecruptBuffer - FreeHeap\n"); + delete [] m_buf; + } + else + { + dbg_printf("DecruptBuffer - FreeStack\n"); + } + } + void* GetBufferPtr() + { + return m_buf; + } + +private: + char* m_buf; + char m_local_buf[LOCAL_BUF_SIZE]; +}; + +bool CLZObject::Decompress(DWORD * pdwKey) +{ + UINT uiSize; + int r; + + if (m_pHeader->dwEncryptSize) + { + DecryptBuffer buf(m_pHeader->dwEncryptSize); + + BYTE* pbDecryptedBuffer = (BYTE*)buf.GetBufferPtr(); + + __Decrypt(pdwKey, pbDecryptedBuffer); + + if (*(DWORD *) pbDecryptedBuffer != ms_dwFourCC) + { + TraceError("LZObject: key incorrect"); + return false; + } + + if (LZO_E_OK != (r = lzo1x_decompress(pbDecryptedBuffer + sizeof(DWORD), m_pHeader->dwCompressedSize, m_pbBuffer, (lzo_uint*) &uiSize, NULL))) + { + TraceError("LZObject: Decompress failed(decrypt) ret %d\n", r); + return false; + } + } + else + { + uiSize = m_pHeader->dwRealSize; + + //if (LZO_E_OK != (r = lzo1x_decompress_safe(m_pbIn, m_pHeader->dwCompressedSize, m_pbBuffer, (lzo_uint*) &uiSize, NULL))) + if (LZO_E_OK != (r = lzo1x_decompress(m_pbIn, m_pHeader->dwCompressedSize, m_pbBuffer, (lzo_uint*) &uiSize, NULL))) + { + TraceError("LZObject: Decompress failed : ret %d, CompressedSize %d\n", r, m_pHeader->dwCompressedSize); + return false; + } + } + + if (uiSize != m_pHeader->dwRealSize) + { + TraceError("LZObject: Size differs"); + return false; + } + + return true; +} + +bool CLZObject::Encrypt(DWORD * pdwKey) +{ + if (!m_bCompressed) + { + assert(!"not compressed yet"); + return false; + } + + BYTE * pbBuffer = m_pbBuffer + sizeof(THeader); + m_pHeader->dwEncryptSize = tea_encrypt((DWORD *) pbBuffer, (const DWORD *) pbBuffer, pdwKey, m_pHeader->dwCompressedSize + 19); + return true; +} + +bool CLZObject::__Decrypt(DWORD * key, BYTE* data) +{ + assert(m_pbBuffer); + + tea_decrypt((DWORD *) data, (const DWORD *) (m_pbIn - sizeof(DWORD)), key, m_pHeader->dwEncryptSize); + return true; +} + +void CLZObject::AllocBuffer(DWORD dwSrcSize) +{ + if (m_pbBuffer && !m_bInBuffer) + gs_freeMemMgr.Free(m_pbBuffer, m_dwBufferSize); + + m_pbBuffer = gs_freeMemMgr.Alloc(dwSrcSize); + m_dwBufferSize = dwSrcSize; +} +/* +void CLZObject::CopyBuffer(const char* pbSrc, DWORD dwSrcSize) +{ + AllocBuffer(dwSrcSize); + memcpy(m_pbBuffer, pbSrc, dwSrcSize); +} +*/ + +CLZO::CLZO() : m_pWorkMem(NULL) +{ + if (lzo_init() != LZO_E_OK) + { + TraceError("LZO: cannot initialize"); + return; + } + +#if defined( LZO1X_999_MEM_COMPRESS ) + m_pWorkMem = (BYTE *) malloc(LZO1X_999_MEM_COMPRESS); +#else + m_pWorkMem = (BYTE *) malloc(LZO1X_1_MEM_COMPRESS); +#endif + + if (NULL == m_pWorkMem) + { + TraceError("LZO: cannot alloc memory"); + return; + } +} + +CLZO::~CLZO() +{ + if (m_pWorkMem) + { + free(m_pWorkMem); + m_pWorkMem = NULL; + } +} + +bool CLZO::CompressMemory(CLZObject & rObj, const void * pIn, UINT uiInLen) +{ + rObj.BeginCompress(pIn, uiInLen); + return rObj.Compress(); +} + +bool CLZO::CompressEncryptedMemory(CLZObject & rObj, const void * pIn, UINT uiInLen, DWORD * pdwKey) +{ + rObj.BeginCompress(pIn, uiInLen); + + if (rObj.Compress()) + { + if (rObj.Encrypt(pdwKey)) + return true; + + return false; + } + + return false; +} + +bool CLZO::Decompress(CLZObject & rObj, const BYTE * pbBuf, DWORD * pdwKey) +{ + if (!rObj.BeginDecompress(pbBuf)) + return false; + + if (!rObj.Decompress(pdwKey)) + return false; + + return true; +} + + +BYTE * CLZO::GetWorkMemory() +{ + return m_pWorkMem; +} + diff --git a/source/EterBase/lzo.h b/source/EterBase/lzo.h new file mode 100644 index 0000000..21810cd --- /dev/null +++ b/source/EterBase/lzo.h @@ -0,0 +1,74 @@ +#ifndef __INC_METIN_II_371GNFBQOCJ_LZO_H__ +#define __INC_METIN_II_371GNFBQOCJ_LZO_H__ + +#include +#include +#include "Singleton.h" + +class CLZObject +{ + public: + #pragma pack(4) + typedef struct SHeader + { + DWORD dwFourCC; + DWORD dwEncryptSize; // ȣȭ ũ + DWORD dwCompressedSize; // ũ + DWORD dwRealSize; // ũ + } THeader; + #pragma pack() + + CLZObject(); + ~CLZObject(); + + void Clear(); + + void BeginCompress(const void * pvIn, UINT uiInLen); + void BeginCompressInBuffer(const void * pvIn, UINT uiInLen, void * pvOut); + bool Compress(); + + bool BeginDecompress(const void * pvIn); + bool Decompress(DWORD * pdwKey = NULL); + + bool Encrypt(DWORD * pdwKey); + bool __Decrypt(DWORD * key, BYTE* data); + + const THeader & GetHeader() { return *m_pHeader; } + BYTE * GetBuffer() { return m_pbBuffer; } + DWORD GetSize(); + void AllocBuffer(DWORD dwSize); + DWORD GetBufferSize() { return m_dwBufferSize; } + //void CopyBuffer(const char* pbSrc, DWORD dwSrcSize); + + private: + void Initialize(); + + BYTE * m_pbBuffer; + DWORD m_dwBufferSize; + + THeader * m_pHeader; + const BYTE * m_pbIn; + bool m_bCompressed; + + bool m_bInBuffer; + + public: + static DWORD ms_dwFourCC; +}; + +class CLZO : public CSingleton +{ + public: + CLZO(); + virtual ~CLZO(); + + bool CompressMemory(CLZObject & rObj, const void * pIn, UINT uiInLen); + bool CompressEncryptedMemory(CLZObject & rObj, const void * pIn, UINT uiInLen, DWORD * pdwKey); + bool Decompress(CLZObject & rObj, const BYTE * pbBuf, DWORD * pdwKey = NULL); + BYTE * GetWorkMemory(); + + private: + BYTE * m_pWorkMem; +}; + +#endif diff --git a/source/EterBase/tea.cpp b/source/EterBase/tea.cpp new file mode 100644 index 0000000..5d03bde --- /dev/null +++ b/source/EterBase/tea.cpp @@ -0,0 +1,101 @@ +/* +* Filename: tea.c +* Description: TEA ȣȭ +* +* Author: (aka. , Cronan), ۿ (aka. myevan, ڷ) +*/ +#include "StdAfx.h" +#include "tea.h" +#include + +/* +* TEA Encryption Module Instruction +* Edited by aka. , Cronan +* +* void tea_code(const unsigned long sz, const unsigned long sy, const unsigned long *key, unsigned long *dest) +* void tea_decode(const unsigned long sz, const unsigned long sy, const unsigned long *key, unsigned long *dest) +* 8Ʈ ȣ/ȣȭ Ҷ ȴ. key 16 Ʈ Ѵ. +* sz, sy 8Ʈ Ѵ. +* +* int tea_decrypt(unsigned long *dest, const unsigned long *src, const unsigned long *key, int size); +* int tea_encrypt(unsigned long *dest, const unsigned long *src, const unsigned long *key, int size); +* Ѳ 8 Ʈ ̻ ȣ/ȣȭ Ҷ Ѵ. size +* 8 ƴϸ 8 ũ⸦ "÷" ȣȭ Ѵ. +* +* ex. tea_code(pdwSrc[1], pdwSrc[0], pdwKey, pdwDest); +* tea_decrypt(pdwDest, pdwSrc, pdwKey, nSize); +*/ + +#define TEA_ROUND 32 // 32 ϸ, . +#define DELTA 0x9E3779B9 // DELTA ٲ . + +void tea_code(const unsigned long sz, const unsigned long sy, const unsigned long *key, unsigned long *dest) +{ + unsigned long y = sy, z = sz, sum = 0; + unsigned long n = TEA_ROUND; + + while (n-- > 0) + { + y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); + sum += DELTA; + z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); + } + + *(dest++) = y; + *dest = z; +} + +void tea_decode(const unsigned long sz, const unsigned long sy, const unsigned long *key, unsigned long *dest) +{ +#pragma warning(disable:4307) + unsigned long y = sy, z = sz, sum = DELTA * TEA_ROUND; +#pragma warning(default:4307) + + unsigned long n = TEA_ROUND; + + while (n-- > 0) + { + z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); + sum -= DELTA; + y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); + } + + *(dest++) = y; + *dest = z; +} + +int tea_encrypt(unsigned long *dest, const unsigned long *src, const unsigned long * key, int size) +{ + int i; + int resize; + + if (size % 8 != 0) + { + resize = size + 8 - (size % 8); + memset((char *) src + size, 0, resize - size); + } + else + resize = size; + + for (i = 0; i < resize >> 3; i++, dest += 2, src += 2) + tea_code(*(src + 1), *src, key, dest); + + return (resize); +} + +int tea_decrypt(unsigned long *dest, const unsigned long *src, const unsigned long * key, int size) +{ + int i; + int resize; + + if (size % 8 != 0) + resize = size + 8 - (size % 8); + else + resize = size; + + for (i = 0; i < resize >> 3; i++, dest += 2, src += 2) + tea_decode(*(src + 1), *src, key, dest); + + return (resize); +} + diff --git a/source/EterBase/tea.h b/source/EterBase/tea.h new file mode 100644 index 0000000..c93f503 --- /dev/null +++ b/source/EterBase/tea.h @@ -0,0 +1,19 @@ +#ifdef __cplusplus +extern "C" { +#endif + + /* TEA is a 64-bit symmetric block cipher with a 128-bit key, developed + by David J. Wheeler and Roger M. Needham, and described in their + paper at . + + This implementation is based on their code in + */ + + #define TEA_KEY_LENGTH 16 + + int tea_encrypt(unsigned long *dest, const unsigned long *src, const unsigned long *key, int size); + int tea_decrypt(unsigned long *dest, const unsigned long *src, const unsigned long *key, int size); + +#ifdef __cplusplus +}; +#endif diff --git a/source/EterBase/vk.h b/source/EterBase/vk.h new file mode 100644 index 0000000..3b38a10 --- /dev/null +++ b/source/EterBase/vk.h @@ -0,0 +1,45 @@ +#ifndef __VK_H__ +#define __VK_H__ +#ifndef VK_0 +#define VK_0 0x30 +#define VK_1 0x31 +#define VK_2 0x32 +#define VK_3 0x33 +#define VK_4 0x34 +#define VK_5 0x35 +#define VK_6 0x36 +#define VK_7 0x37 +#define VK_8 0x38 +#define VK_9 0x39 +#endif + +#ifndef VK_A +#define VK_A 0x41 +#define VK_B 0x42 +#define VK_C 0x43 +#define VK_D 0x44 +#define VK_E 0x45 +#define VK_F 0x46 +#define VK_G 0x47 +#define VK_H 0x48 +#define VK_I 0x49 +#define VK_J 0x4A +#define VK_K 0x4B +#define VK_L 0x4C +#define VK_M 0x4D +#define VK_N 0x4E +#define VK_O 0x4F +#define VK_P 0x50 +#define VK_Q 0x51 +#define VK_R 0x52 +#define VK_S 0x53 +#define VK_T 0x54 +#define VK_U 0x55 +#define VK_V 0x56 +#define VK_W 0x57 +#define VK_X 0x58 +#define VK_Y 0x59 +#define VK_Z 0x5A +#endif + +#endif diff --git a/source/EterGrnLib/LODController.cpp b/source/EterGrnLib/LODController.cpp new file mode 100644 index 0000000..1a52f50 --- /dev/null +++ b/source/EterGrnLib/LODController.cpp @@ -0,0 +1,695 @@ +#include "StdAfx.h" +#include "LODController.h" + +static float LODHEIGHT_ACTOR = 500.0f; +static float LODDISTANCE_ACTOR = 5000.0f; +static float LODDISTANCE_BUILDING = 25000.0f; + +static const float c_fNearLodScale = 3.0f; +static const float c_fFarLodScale = 25.0f; +static const float LOD_APPLY_MAX = 2000.0f; +static const float LOD_APPLY_MIN = 500.0f; + +bool ms_isMinLODModeEnable=false; + +enum +{ + SHARED_VB_500 = 0, + SHARED_VB_1000 = 1, + SHARED_VB_1500 = 2, + SHARED_VB_2000 = 3, + SHARED_VB_2500 = 4, + SHARED_VB_3000 = 5, + SHARED_VB_3500 = 6, + SHARED_VB_4000 = 7, + SHARED_VB_NUM = 9, +}; + +static std::vector gs_vbs[SHARED_VB_NUM]; + +static CGraphicVertexBuffer gs_emptyVB; + +#include + +static CGraphicVertexBuffer* __AllocDeformVertexBuffer(unsigned deformableVertexCount) +{ + if (deformableVertexCount == 0) + return &gs_emptyVB; + + unsigned capacity = (((deformableVertexCount-1) / 500) + 1) * 500; + unsigned index = (deformableVertexCount-1) / 500; + if (index < SHARED_VB_NUM) + { + std::vector& vbs = gs_vbs[index]; + if (!vbs.empty()) + { + //TraceError("REUSE %d(%d)", capacity, deformableVertexCount); + + CGraphicVertexBuffer* pkRetVB = vbs.back(); + vbs.pop_back(); + return pkRetVB; + } + } + + + static time_t base = time(NULL); + //TraceError("NEW %8d: %d(%d)", time(NULL) - base, capacity, deformableVertexCount); + + CGraphicVertexBuffer* pkNewVB = new CGraphicVertexBuffer; + + if (!pkNewVB->Create( + capacity, + D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1, + D3DUSAGE_WRITEONLY, + D3DPOOL_MANAGED)) + { + TraceError("NEW_ERROR %8d: %d(%d)", time(NULL) - base, capacity, deformableVertexCount); + } + + return pkNewVB; +} + +void __FreeDeformVertexBuffer(CGraphicVertexBuffer* pkDelVB) +{ + if (pkDelVB) + { + if (pkDelVB == &gs_emptyVB) + return; + + unsigned index = (pkDelVB->GetVertexCount() - 1) / 500; + if (index < SHARED_VB_NUM) + { + gs_vbs[index].push_back(pkDelVB); + } + else + { + pkDelVB->Destroy(); + delete pkDelVB; + } + } +} + +void __ReserveSharedVertexBuffers(unsigned index, unsigned count) +{ + NANOBEGIN + if (index >= SHARED_VB_NUM) + return; + + unsigned capacity = (index + 1) * 500; + + for (unsigned i = 0; i != count; ++i) + { + CGraphicVertexBuffer* pkNewVB = new CGraphicVertexBuffer; + pkNewVB->Create( + capacity, + D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1, + D3DUSAGE_WRITEONLY, + D3DPOOL_MANAGED); + gs_vbs[index].push_back(pkNewVB); + } + NANOEND +} + +void GrannyCreateSharedDeformBuffer() +{ + __ReserveSharedVertexBuffers(SHARED_VB_500, 40); + __ReserveSharedVertexBuffers(SHARED_VB_1000, 20); + __ReserveSharedVertexBuffers(SHARED_VB_1500, 20); + __ReserveSharedVertexBuffers(SHARED_VB_2000, 40); + __ReserveSharedVertexBuffers(SHARED_VB_3000, 20); +} + +void GrannyDestroySharedDeformBuffer() +{ +#ifdef _DEBUG + TraceError("granny_shared_vbs:"); +#endif + for (int i = 0; i != SHARED_VB_NUM; ++i) + { + std::vector& vbs = gs_vbs[i]; +#ifdef _DEBUG + TraceError("\t%d: %d", i, vbs.size()); +#endif + + std::vector::iterator v; + for (v = vbs.begin(); v != vbs.end(); ++v) + { + CGraphicVertexBuffer* pkEachVB = (*v); + pkEachVB->Destroy(); + delete pkEachVB; + } + vbs.clear(); + } + +} + +void CGrannyLODController::SetMinLODMode(bool isEnable) +{ + ms_isMinLODModeEnable=isEnable; +} + +void CGrannyLODController::SetMaterialImagePointer(const char* c_szImageName, CGraphicImage* pImage) +{ + std::deque::iterator i; + for (i=m_que_pkModelInst.begin(); i!=m_que_pkModelInst.end(); ++i) + { + CGrannyModelInstance* pkModelInst=(*i); + pkModelInst->SetMaterialImagePointer(c_szImageName, pImage); + } +} + +void CGrannyLODController::SetMaterialData(const char* c_szImageName, const SMaterialData& c_rkMaterialData) +{ + std::deque::iterator i; + for (i=m_que_pkModelInst.begin(); i!=m_que_pkModelInst.end(); ++i) + { + CGrannyModelInstance* pkModelInst=(*i); + pkModelInst->SetMaterialData(c_szImageName, c_rkMaterialData); + } +} + +void CGrannyLODController::SetSpecularInfo(const char* c_szMtrlName, BOOL bEnable, float fPower) +{ + std::deque::iterator i; + for (i=m_que_pkModelInst.begin(); i!=m_que_pkModelInst.end(); ++i) + { + CGrannyModelInstance* pkModelInst=(*i); + pkModelInst->SetSpecularInfo(c_szMtrlName, bEnable, fPower); + } +} + +CGrannyLODController::CGrannyLODController() : + m_pCurrentModelInstance(NULL), + m_bLODLevel(0), + m_pAttachedParentModel(NULL), + m_fLODDistance(0.0f), + m_dwLODAniFPS(CGrannyModelInstance::ANIFPS_MAX), + m_pkSharedDeformableVertexBuffer(NULL) + ///////////////////////////////////////////////////// +{ +} + +CGrannyLODController::~CGrannyLODController() +{ + __FreeDeformVertexBuffer(m_pkSharedDeformableVertexBuffer); + + Clear(); +} + +void CGrannyLODController::Clear() +{ + if (m_pAttachedParentModel) + { + m_pAttachedParentModel->DetachModelInstance(this); + } + + m_pCurrentModelInstance = NULL; + m_pAttachedParentModel = NULL; + + std::for_each(m_que_pkModelInst.begin(), m_que_pkModelInst.end(), CGrannyModelInstance::Delete); + m_que_pkModelInst.clear(); + + std::vector::iterator itor = m_AttachedModelDataVector.begin(); + for (; m_AttachedModelDataVector.end() != itor; ++itor) + { + TAttachingModelData & rData = *itor; + rData.pkLODController->m_pAttachedParentModel = NULL; + } + + m_AttachedModelDataVector.clear(); +} + +void CGrannyLODController::AddModel(CGraphicThing * pThing, int iSrcModel, CGrannyLODController * pSkelLODController) +{ + if (!pThing) + return; + + if (pSkelLODController && pSkelLODController->m_que_pkModelInst.empty()) + { + assert(!"EMPTY SKELETON(CANNON LINK)"); + return; + } + + assert(pThing->GetReferenceCount()>=1); + + pThing->AddReference(); + + if (pThing->GetModelCount() <= iSrcModel) + { + pThing->Release(); + return; + } + CGrannyModel * pModel = pThing->GetModelPointer(iSrcModel); + if (!pModel) + { + pThing->Release(); + return; + } + + CGrannyModelInstance * pModelInstance = CGrannyModelInstance::New(); + + __ReserveSharedDeformableVertexBuffer(pModel->GetDeformVertexCount()); + + if (pSkelLODController) + { + pModelInstance->SetLinkedModelPointer(pModel, m_pkSharedDeformableVertexBuffer, &pSkelLODController->m_pCurrentModelInstance); + } + else + { + pModelInstance->SetLinkedModelPointer(pModel, m_pkSharedDeformableVertexBuffer, NULL); + } + + // END_OF_WORK + + if (!m_pCurrentModelInstance) + { + m_pCurrentModelInstance = pModelInstance; + pModelInstance->DeformNoSkin(&ms_matIdentity); + + D3DXVECTOR3 vtMin, vtMax; + pModelInstance->GetBoundBox(&vtMin, &vtMax); + + float fSize = 0.0f; + fSize = fMAX(fSize, fabs(vtMin.x - vtMax.x)); + fSize = fMAX(fSize, fabs(vtMin.y - vtMax.y)); + fSize = fMAX(fSize, fabs(vtMin.z - vtMax.z)); + + if (fSizeDeformNoSkin(&ms_matIdentity); + } + + pThing->Release(); + + m_que_pkModelInst.push_front(pModelInstance); +} + + + +void CGrannyLODController::__ReserveSharedDeformableVertexBuffer(DWORD deformableVertexCount) +{ + if (m_pkSharedDeformableVertexBuffer && + m_pkSharedDeformableVertexBuffer->GetVertexCount() >= deformableVertexCount) + return; + + __FreeDeformVertexBuffer(m_pkSharedDeformableVertexBuffer); + + m_pkSharedDeformableVertexBuffer = __AllocDeformVertexBuffer(deformableVertexCount); +} + +void CGrannyLODController::AttachModelInstance(CGrannyLODController * pSrcLODController, const char * c_szBoneName) +{ + CGrannyModelInstance * pSrcInstance = pSrcLODController->GetModelInstance(); + if (!pSrcInstance) + return; + + CGrannyModelInstance * pDestInstance = GetModelInstance(); + if (pDestInstance) + { + pSrcInstance->SetParentModelInstance(pDestInstance, c_szBoneName); + } + + if (!pSrcLODController->GetModelInstance()) + return; + + // Link Parent Data + pSrcLODController->m_pAttachedParentModel = this; + + // Link Child Data + std::vector::iterator itor = m_AttachedModelDataVector.begin(); + for (; m_AttachedModelDataVector.end() != itor;) + { + TAttachingModelData & rData = *itor; + if (pSrcLODController == rData.pkLODController) + { + itor = m_AttachedModelDataVector.erase(itor); + } + else + { + ++itor; + } + } + + TAttachingModelData AttachingModelData; + AttachingModelData.pkLODController = pSrcLODController; + AttachingModelData.strBoneName = c_szBoneName; + m_AttachedModelDataVector.push_back(AttachingModelData); +} + +void CGrannyLODController::DetachModelInstance(CGrannyLODController * pSrcLODController) +{ + CGrannyModelInstance * pSrcInstance = pSrcLODController->GetModelInstance(); + if (!pSrcInstance) + return; + + CGrannyModelInstance * pDestInstance = GetModelInstance(); + if (pDestInstance) + { + pSrcInstance->SetParentModelInstance(NULL, 0); + } + +// if (!pSrcLODController->GetModelInstance()) +// return; + + // Unlink Child Data + std::vector::iterator itor = m_AttachedModelDataVector.begin(); + for (; m_AttachedModelDataVector.end() != itor;) + { + TAttachingModelData & rData = *itor; + if (pSrcLODController == rData.pkLODController) + { + itor = m_AttachedModelDataVector.erase(itor); + } + else + { + ++itor; + } + } + + // Unlink Parent Data + pSrcLODController->m_pAttachedParentModel = NULL; +} + +void CGrannyLODController::SetLODLimits(float /*fNearLOD*/, float fFarLOD) +{ + m_fLODDistance = fFarLOD; +} + +void CGrannyLODController::SetLODLevel(BYTE bLodLevel) +{ + assert(m_que_pkModelInst.size() > 0); + + if (m_que_pkModelInst.size() > 0) + m_bLODLevel = (BYTE) MIN(m_que_pkModelInst.size() - 1, bLodLevel); +} + +void CGrannyLODController::CreateDeviceObjects() +{ + std::for_each(m_que_pkModelInst.begin(), + m_que_pkModelInst.end(), + CGrannyModelInstance::FCreateDeviceObjects()); +} + +void CGrannyLODController::DestroyDeviceObjects() +{ + std::for_each(m_que_pkModelInst.begin(), + m_que_pkModelInst.end(), + CGrannyModelInstance::FDestroyDeviceObjects()); +} + +void CGrannyLODController::RenderWithOneTexture() +{ + assert(m_pCurrentModelInstance != NULL); + +//#define CHECK_LOD +#ifdef CHECK_LOD + if (m_que_pkModelInst.size() > 0 && m_pCurrentModelInstance == m_que_pkModelInst[0]) + m_pCurrentModelInstance->RenderWithoutTexture(); + + if (m_que_pkModelInst.size() > 1 && m_pCurrentModelInstance == m_que_pkModelInst[1]) + m_pCurrentModelInstance->RenderWithOneTexture(); + + if (m_que_pkModelInst.size() > 2 && m_pCurrentModelInstance == m_que_pkModelInst[2]) + m_pCurrentModelInstance->RenderWithOneTexture(); + + if (m_que_pkModelInst.size() > 3 && m_pCurrentModelInstance == m_que_pkModelInst[3]) + m_pCurrentModelInstance->RenderWithOneTexture(); + +#else + m_pCurrentModelInstance->RenderWithOneTexture(); +#endif +} + +void CGrannyLODController::BlendRenderWithOneTexture() +{ + assert(m_pCurrentModelInstance != NULL); + m_pCurrentModelInstance->BlendRenderWithOneTexture(); +} + +void CGrannyLODController::RenderWithTwoTexture() +{ + assert(m_pCurrentModelInstance != NULL); + m_pCurrentModelInstance->RenderWithTwoTexture(); +} + +void CGrannyLODController::BlendRenderWithTwoTexture() +{ + assert(m_pCurrentModelInstance != NULL); + m_pCurrentModelInstance->BlendRenderWithTwoTexture(); +} + +void CGrannyLODController::Update(float fElapsedTime, float fDistanceFromCenter, float fDistanceFromCamera) +{ + UpdateLODLevel(fDistanceFromCenter, fDistanceFromCamera); + UpdateTime(fElapsedTime); +} + +void CGrannyLODController::UpdateLODLevel(float fDistanceFromCenter, float fDistanceFromCamera) +{ + if (m_que_pkModelInst.size()<=1) + return; + + assert(m_pCurrentModelInstance != NULL); + + + if (fDistanceFromCenter > LOD_APPLY_MIN) // ߽ LOD + { + // ī޶ ־ fLODRate ۾ + // 3 LOD .. հ 0, ڰ Ŀ + + // 100fps 50fps 33fps 25fps 20fps + // 10ms 20ms 30ms 40ms 50ms + float fLODFactor = fMINMAX(0.0f, (m_fLODDistance-fDistanceFromCamera), m_fLODDistance); + + if (m_fLODDistance>0.0f) + m_dwLODAniFPS = (DWORD) ((CGrannyModelInstance::ANIFPS_MAX - CGrannyModelInstance::ANIFPS_MIN) * fLODFactor / m_fLODDistance + static_cast(CGrannyModelInstance::ANIFPS_MIN)); + else + m_dwLODAniFPS = CGrannyModelInstance::ANIFPS_MIN; + + assert(m_dwLODAniFPS > 0); + m_dwLODAniFPS /= 10; + m_dwLODAniFPS *= 10; + + float fLODStep = m_fLODDistance / m_que_pkModelInst.size(); + BYTE bLODLevel = BYTE(fLODFactor / fLODStep); + + if (m_fLODDistance <= 5000.0f) + { + if (fDistanceFromCamera < 500.0f) + { + bLODLevel = 0; + } + else if (fDistanceFromCamera < 1500.0f) + { + bLODLevel = 1; + } + else if (fDistanceFromCamera < 2500.0f) + { + bLODLevel = 2; + } + else + { + bLODLevel = 3; + } + + bLODLevel = (BYTE) (m_que_pkModelInst.size() - min(bLODLevel, m_que_pkModelInst.size()) - 1); + } + + if (ms_isMinLODModeEnable) + bLODLevel=0; + + SetLODLevel(bLODLevel); + + if (m_pCurrentModelInstance != m_que_pkModelInst[m_bLODLevel]) + { + SetCurrentModelInstance(m_que_pkModelInst[m_bLODLevel]); + } + } + else + { + m_dwLODAniFPS=CGrannyModelInstance::ANIFPS_MAX; + + if (!m_que_pkModelInst.empty()) + { + if (m_pCurrentModelInstance != m_que_pkModelInst.back()) + { + SetCurrentModelInstance(m_que_pkModelInst.back()); + } + } + } +} + +void CGrannyLODController::UpdateTime(float fElapsedTime) +{ + assert(m_pCurrentModelInstance != NULL); + + m_pCurrentModelInstance->Update(m_dwLODAniFPS); + + //DWORD t3=timeGetTime(); + m_pCurrentModelInstance->UpdateLocalTime(fElapsedTime); + + //DWORD t4=timeGetTime(); + +#ifdef __PERFORMANCE_CHECKER__ + { + static FILE* fp=fopen("perf_lod_update.txt", "w"); + + if (t4-t1>3) + { + fprintf(fp, "LOD.Total %d (Time %f)\n", t4-t1, timeGetTime()/1000.0f); + fprintf(fp, "LOD.SMI %d\n", t2-t1); + fprintf(fp, "LOD.UP %d\n", t3-t2); + fprintf(fp, "LOD.UL %d\n", t4-t3); + fprintf(fp, "-------------------------------- \n"); + fflush(fp); + } + fflush(fp); + } +#endif +} + +void CGrannyLODController::SetCurrentModelInstance(CGrannyModelInstance * pgrnModelInstance) +{ + // Copy Motion + pgrnModelInstance->CopyMotion(m_pCurrentModelInstance, true); + m_pCurrentModelInstance = pgrnModelInstance; + + // Change children attaching link + RefreshAttachedModelInstance(); + + // Change parent attaching link + if (m_pAttachedParentModel) + { + m_pAttachedParentModel->RefreshAttachedModelInstance(); + } +} + +void CGrannyLODController::RefreshAttachedModelInstance() +{ + if (!m_pCurrentModelInstance) + return; + + for (DWORD i = 0; i < m_AttachedModelDataVector.size(); ++i) + { + TAttachingModelData & rModelData = m_AttachedModelDataVector[i]; + + CGrannyModelInstance * pSrcInstance = rModelData.pkLODController->GetModelInstance(); + if (!pSrcInstance) + { + Tracenf("CGrannyLODController::RefreshAttachedModelInstance : m_AttachedModelDataVector[%d]->pkLODController->GetModelIntance()==NULL", i); + continue; + } + + pSrcInstance->SetParentModelInstance(m_pCurrentModelInstance, rModelData.strBoneName.c_str()); + } +} + +void CGrannyLODController::UpdateSkeleton(const D3DXMATRIX * c_pWorldMatrix, float fElapsedTime) +{ + if (m_pCurrentModelInstance) + m_pCurrentModelInstance->UpdateSkeleton(c_pWorldMatrix, fElapsedTime); +} + +void CGrannyLODController::DeformAll(const D3DXMATRIX * c_pWorldMatrix) +{ + std::deque::iterator i; + for (i=m_que_pkModelInst.begin(); i!=m_que_pkModelInst.end(); ++i) + { + CGrannyModelInstance* pkModelInst=(*i); + pkModelInst->Deform(c_pWorldMatrix); + } +} + +void CGrannyLODController::DeformNoSkin(const D3DXMATRIX * c_pWorldMatrix) +{ + if (m_pCurrentModelInstance) + m_pCurrentModelInstance->DeformNoSkin(c_pWorldMatrix); +} + +void CGrannyLODController::Deform(const D3DXMATRIX * c_pWorldMatrix) +{ + if (m_pCurrentModelInstance) + m_pCurrentModelInstance->Deform(c_pWorldMatrix); +} + +void CGrannyLODController::RenderToShadowMap() +{ + if (m_pCurrentModelInstance) + m_pCurrentModelInstance->RenderWithoutTexture(); +} + +void CGrannyLODController::RenderShadow() +{ + if (m_pCurrentModelInstance) + m_pCurrentModelInstance->RenderWithOneTexture(); +} + +void CGrannyLODController::ReloadTexture() +{ + if (m_pCurrentModelInstance) + m_pCurrentModelInstance->ReloadTexture(); +} + +void CGrannyLODController::GetBoundBox(D3DXVECTOR3 * vtMin, D3DXVECTOR3 * vtMax) +{ + if (m_pCurrentModelInstance) + m_pCurrentModelInstance->GetBoundBox(vtMin, vtMax); +} + +bool CGrannyLODController::Intersect(const D3DXMATRIX * c_pMatrix, float * u, float * v, float * t) +{ + if (!m_pCurrentModelInstance) + return false; + return m_pCurrentModelInstance->Intersect(c_pMatrix, u, v, t); +} + +void CGrannyLODController::SetLocalTime(float fLocalTime) +{ + if (m_pCurrentModelInstance) + m_pCurrentModelInstance->SetLocalTime(fLocalTime); +} + +void CGrannyLODController::ResetLocalTime() +{ + assert(m_pCurrentModelInstance != NULL); + m_pCurrentModelInstance->ResetLocalTime(); +} + +void CGrannyLODController::SetMotionPointer(const CGrannyMotion * c_pMotion, float fBlendTime, int iLoopCount, float speedRatio) +{ + assert(m_pCurrentModelInstance != NULL); + m_pCurrentModelInstance->SetMotionPointer(c_pMotion, fBlendTime, iLoopCount, speedRatio); +} + +void CGrannyLODController::ChangeMotionPointer(const CGrannyMotion * c_pMotion, int iLoopCount, float speedRatio) +{ + assert(m_pCurrentModelInstance != NULL); + m_pCurrentModelInstance->ChangeMotionPointer(c_pMotion, iLoopCount, speedRatio); +} + +void CGrannyLODController::SetMotionAtEnd() +{ + if (m_pCurrentModelInstance) + m_pCurrentModelInstance->SetMotionAtEnd(); +} + +BOOL CGrannyLODController::isModelInstance() +{ + if (!m_pCurrentModelInstance) + return FALSE; + + return TRUE; +} + +CGrannyModelInstance * CGrannyLODController::GetModelInstance() +{ + return m_pCurrentModelInstance; +} diff --git a/source/EterGrnLib/LODController.h b/source/EterGrnLib/LODController.h new file mode 100644 index 0000000..93d896d --- /dev/null +++ b/source/EterGrnLib/LODController.h @@ -0,0 +1,304 @@ +#pragma once + +#pragma warning(disable:4786) + +#include +#include "Thing.h" +#include "ModelInstance.h" + +class CGrannyLODController : public CGraphicBase +{ + public: + static void SetMinLODMode(bool isEnable); + + public: + struct FSetLocalTime + { + float fLocalTime; + void operator() (CGrannyLODController * pController) + { + pController->SetLocalTime(fLocalTime); + } + }; + + struct FUpdateTime + { + float fElapsedTime; + + void operator() (CGrannyLODController * pController) + { + if (pController->isModelInstance()) + pController->UpdateTime(fElapsedTime); + } + }; + + struct FUpdateLODLevel + { + float fDistanceFromCenter; + float fDistanceFromCamera; + + void operator() (CGrannyLODController * pController) + { + if (pController->isModelInstance()) + pController->UpdateLODLevel(fDistanceFromCenter, fDistanceFromCamera); + } + }; + + struct FRenderWithOneTexture + { + void operator() (CGrannyLODController * pController) + { + if (pController->isModelInstance()) + pController->RenderWithOneTexture(); + } + }; + + struct FBlendRenderWithOneTexture + { + void operator() (CGrannyLODController * pController) + { + if (pController->isModelInstance()) + pController->BlendRenderWithOneTexture(); + } + }; + + struct FRenderWithTwoTexture + { + void operator() (CGrannyLODController * pController) + { + if (pController->isModelInstance()) + pController->RenderWithTwoTexture(); + } + }; + + struct FBlendRenderWithTwoTexture + { + void operator() (CGrannyLODController * pController) + { + if (pController->isModelInstance()) + pController->BlendRenderWithTwoTexture(); + } + }; + + struct FRenderToShadowMap + { + void operator() (CGrannyLODController * pController) + { + if (pController->isModelInstance()) + pController->RenderToShadowMap(); + } + }; + + struct FRenderShadow + { + void operator() (CGrannyLODController * pController) + { + if (pController->isModelInstance()) + pController->RenderShadow(); + } + }; + + struct FDeform + { + const D3DXMATRIX * mc_pWorldMatrix; + + void operator() (CGrannyLODController * pController) + { + if (pController->isModelInstance()) + pController->Deform(mc_pWorldMatrix); + } + }; + struct FDeformNoSkin + { + const D3DXMATRIX * mc_pWorldMatrix; + + void operator() (CGrannyLODController * pController) + { + if (pController->isModelInstance()) + pController->DeformNoSkin(mc_pWorldMatrix); + } + }; + struct FDeformAll + { + const D3DXMATRIX * mc_pWorldMatrix; + + void operator() (CGrannyLODController * pController) + { + if (pController->isModelInstance()) + pController->DeformAll(mc_pWorldMatrix); + } + }; + + struct FCreateDeviceObjects + { + void operator() (CGrannyLODController * pController) + { + if (pController->isModelInstance()) + pController->CreateDeviceObjects(); + } + }; + + struct FDestroyDeviceObjects + { + void operator() (CGrannyLODController * pController) + { + if (pController->isModelInstance()) + pController->DestroyDeviceObjects(); + } + }; + + struct FBoundBox + { + D3DXVECTOR3* m_vtMin; + D3DXVECTOR3* m_vtMax; + + FBoundBox(D3DXVECTOR3 * vtMin, D3DXVECTOR3 * vtMax) + { + m_vtMin = vtMin; + m_vtMax = vtMax; + } + + void operator() (CGrannyLODController * pController) + { + if (pController->isModelInstance()) + pController->GetBoundBox(m_vtMin, m_vtMax); + } + }; + + struct FResetLocalTime + { + void operator() (CGrannyLODController * pController) + { + if (pController->isModelInstance()) + pController->ResetLocalTime(); + } + }; + + struct FReloadTexture + { + void operator () (CGrannyLODController * pController) + { + if (pController->isModelInstance()) + pController->ReloadTexture(); + } + }; + + struct FSetMotionPointer + { + const CGrannyMotion * m_pMotion; + float m_speedRatio; + float m_blendTime; + int m_loopCount; + + void operator() (CGrannyLODController * pController) + { + if (pController->isModelInstance()) + pController->SetMotionPointer(m_pMotion, m_blendTime, m_loopCount, m_speedRatio); + } + }; + + struct FChangeMotionPointer + { + const CGrannyMotion * m_pMotion; + float m_speedRatio; + int m_loopCount; + + void operator() (CGrannyLODController * pController) + { + if (pController->isModelInstance()) + pController->ChangeMotionPointer(m_pMotion, m_loopCount, m_speedRatio); + } + }; + + struct FEndStopMotionPointer + { + const CGrannyMotion * m_pMotion; + + void operator () (CGrannyLODController * pController) + { + if (pController->isModelInstance()) + pController->SetMotionAtEnd(); + } + }; + + CGrannyLODController(); + virtual ~CGrannyLODController(); + + void Clear(); + + void CreateDeviceObjects(); + void DestroyDeviceObjects(); + + void AddModel(CGraphicThing * pThing, int iSrcModel, CGrannyLODController * pSkelLODController=NULL); + void AttachModelInstance(CGrannyLODController * pSrcLODController, const char * c_szBoneName); + void DetachModelInstance(CGrannyLODController * pSrcLODController); + void SetLODLimits(float fNearLOD, float fFarLOD); + void SetLODLevel(BYTE bLODLevel); + BYTE GetLODLevel() { return m_bLODLevel; } + void SetMaterialImagePointer(const char* c_szImageName, CGraphicImage* pImage); + void SetMaterialData(const char* c_szImageName, const SMaterialData& c_rkMaterialData); + void SetSpecularInfo(const char* c_szMtrlName, BOOL bEnable, float fPower); + + void RenderWithOneTexture(); + void RenderWithTwoTexture(); + void BlendRenderWithOneTexture(); + void BlendRenderWithTwoTexture(); + + void Update(float fElapsedTime, float fDistanceFromCenter, float fDistanceFromCamera); + void UpdateLODLevel(float fDistanceFromCenter, float fDistanceFromCamera); + void UpdateTime(float fElapsedTime); + + void UpdateSkeleton(const D3DXMATRIX * c_pWorldMatrix, float fElapsedTime); + void Deform(const D3DXMATRIX * c_pWorldMatrix); + void DeformNoSkin(const D3DXMATRIX * c_pWorldMatrix); + void DeformAll(const D3DXMATRIX * c_pWorldMatrix); + + void RenderToShadowMap(); + void RenderShadow(); + void ReloadTexture(); + + void GetBoundBox(D3DXVECTOR3 * vtMin, D3DXVECTOR3 * vtMax); + bool Intersect(const D3DXMATRIX * c_pMatrix, float * u, float * v, float * t); + + void SetLocalTime(float fLocalTime); + void ResetLocalTime(); + + void SetMotionPointer(const CGrannyMotion * c_pMotion, float fBlendTime, int iLoopCount, float speedRatio); + void ChangeMotionPointer(const CGrannyMotion * c_pMotion, int iLoopCount, float speedRatio); + void SetMotionAtEnd(); + + BOOL isModelInstance(); + CGrannyModelInstance* GetModelInstance(); + bool HaveBlendThing() { return 0 != GetModelInstance() ? GetModelInstance()->HaveBlendThing() : false; } // NOTE: GetModelInstance() == 0 Ŭ ũ (2012. 05. 07) + + protected: + void SetCurrentModelInstance(CGrannyModelInstance * pgrnModelInstance); + void RefreshAttachedModelInstance(); + + void __ReserveSharedDeformableVertexBuffer(DWORD deformableVertexCount); + + protected: + float m_fLODDistance; + DWORD m_dwLODAniFPS; + + //// Attaching Link Data + // Data of Parent Side + typedef struct SAttachingModelData + { + CGrannyLODController * pkLODController; + std::string strBoneName; + } TAttachingModelData; + + std::vector m_AttachedModelDataVector; + // Data of Child Side + CGrannyLODController * m_pAttachedParentModel; + + BYTE m_bLODLevel; + CGrannyModelInstance * m_pCurrentModelInstance; + + // WORK + std::deque m_que_pkModelInst; + + CGraphicVertexBuffer* m_pkSharedDeformableVertexBuffer; + // END_OF_WORK +}; diff --git a/source/EterGrnLib/Material.cpp b/source/EterGrnLib/Material.cpp new file mode 100644 index 0000000..d17d9b2 --- /dev/null +++ b/source/EterGrnLib/Material.cpp @@ -0,0 +1,560 @@ +#include "StdAfx.h" +#include "Material.h" +#include "Mesh.h" +#include "../eterbase/Filename.h" +#include "../eterlib/ResourceManager.h" +#include "../eterlib/StateManager.h" +#include "../eterlib/GrpScreen.h" + +CGraphicImageInstance CGrannyMaterial::ms_akSphereMapInstance[SPHEREMAP_NUM]; + +D3DXVECTOR3 CGrannyMaterial::ms_v3SpecularTrans(0.0f, 0.0f, 0.0f); +D3DXMATRIX CGrannyMaterial::ms_matSpecular; + +D3DXCOLOR g_fSpecularColor = D3DXCOLOR(0.0f, 0.0f, 0.0f, 0.0f); + +void CGrannyMaterial::TranslateSpecularMatrix(float fAddX, float fAddY, float fAddZ) +{ + static float SPECULAR_TRANSLATE_MAX = 1000000.0f; + + ms_v3SpecularTrans.x+=fAddX; + ms_v3SpecularTrans.y+=fAddY; + ms_v3SpecularTrans.z+=fAddZ; + + if (ms_v3SpecularTrans.x>=SPECULAR_TRANSLATE_MAX) + ms_v3SpecularTrans.x=0.0f; + + if (ms_v3SpecularTrans.y>=SPECULAR_TRANSLATE_MAX) + ms_v3SpecularTrans.y=0.0f; + + if (ms_v3SpecularTrans.z>=SPECULAR_TRANSLATE_MAX) + ms_v3SpecularTrans.z=0.0f; + + D3DXMatrixTranslation(&ms_matSpecular, + ms_v3SpecularTrans.x, + ms_v3SpecularTrans.y, + ms_v3SpecularTrans.z + ); +} + +void CGrannyMaterial::ApplyRenderState() +{ + assert(m_pfnApplyRenderState!=NULL && "CGrannyMaterial::SaveRenderState"); + (this->*m_pfnApplyRenderState)(); +} + +void CGrannyMaterial::RestoreRenderState() +{ + assert(m_pfnRestoreRenderState!=NULL && "CGrannyMaterial::RestoreRenderState"); + (this->*m_pfnRestoreRenderState)(); +} + +void CGrannyMaterial::Copy(CGrannyMaterial& rkMtrl) +{ + m_pgrnMaterial = rkMtrl.m_pgrnMaterial; + m_roImage[0] = rkMtrl.m_roImage[0]; + m_roImage[1] = rkMtrl.m_roImage[1]; + m_eType = rkMtrl.m_eType; +} + +CGrannyMaterial::CGrannyMaterial() +{ + m_bTwoSideRender = false; + m_dwLastCullRenderStateForTwoSideRendering = D3DCULL_CW; + + Initialize(); +} + +CGrannyMaterial::~CGrannyMaterial() +{ +} + +CGrannyMaterial::EType CGrannyMaterial::GetType() const +{ + return m_eType; +} + +void CGrannyMaterial::SetImagePointer(int iStage, CGraphicImage* pImage) +{ + assert(iStage<2 && "CGrannyMaterial::SetImagePointer"); + m_roImage[iStage]=pImage; +} + +bool CGrannyMaterial::IsIn(const char* c_szImageName, int* piStage) +{ + std::string strImageName = c_szImageName; + CFileNameHelper::StringPath(strImageName); + + granny_texture * pgrnDiffuseTexture = GrannyGetMaterialTextureByType(m_pgrnMaterial, GrannyDiffuseColorTexture); + if (pgrnDiffuseTexture) + { + std::string strDiffuseFileName = pgrnDiffuseTexture->FromFileName; + CFileNameHelper::StringPath(strDiffuseFileName); + if (strDiffuseFileName == strImageName) + { + *piStage=0; + return true; + } + } + + granny_texture * pgrnOpacityTexture = GrannyGetMaterialTextureByType(m_pgrnMaterial, GrannyOpacityTexture); + if (pgrnOpacityTexture) + { + std::string strOpacityFileName = pgrnOpacityTexture->FromFileName; + CFileNameHelper::StringPath(strOpacityFileName); + if (strOpacityFileName == strImageName) + { + *piStage=1; + return true; + } + } + + return false; +} + +void CGrannyMaterial::SetSpecularInfo(BOOL bFlag, float fPower, BYTE uSphereMapIndex) +{ + m_fSpecularPower = fPower; + m_bSphereMapIndex = uSphereMapIndex; + m_bSpecularEnable = bFlag; + + if (bFlag) + { + m_pfnApplyRenderState = &CGrannyMaterial::__ApplySpecularRenderState; + m_pfnRestoreRenderState = &CGrannyMaterial::__RestoreSpecularRenderState; + } + else + { + m_pfnApplyRenderState = &CGrannyMaterial::__ApplyDiffuseRenderState; + m_pfnRestoreRenderState = &CGrannyMaterial::__RestoreDiffuseRenderState; + } +} + +bool CGrannyMaterial::IsEqual(granny_material* pgrnMaterial) const +{ + if (m_pgrnMaterial==pgrnMaterial) + return true; + + return false; +} + + +LPDIRECT3DTEXTURE8 CGrannyMaterial::GetD3DTexture(int iStage) const +{ + const CGraphicImage::TRef & ratImage = m_roImage[iStage]; + + if (ratImage.IsNull()) + return NULL; + + CGraphicImage * pImage = ratImage.GetPointer(); + const CGraphicTexture * pTexture = pImage->GetTexturePointer(); + return pTexture->GetD3DTexture(); +} + +CGraphicImage * CGrannyMaterial::GetImagePointer(int iStage) const +{ + const CGraphicImage::TRef & ratImage = m_roImage[iStage]; + + if (ratImage.IsNull()) + return NULL; + + CGraphicImage * pImage = ratImage.GetPointer(); + return pImage; +} + +const CGraphicTexture* CGrannyMaterial::GetDiffuseTexture() const +{ + if (m_roImage[0].IsNull()) + return NULL; + + return m_roImage[0].GetPointer()->GetTexturePointer(); +} + +const CGraphicTexture* CGrannyMaterial::GetOpacityTexture() const +{ + if (m_roImage[1].IsNull()) + return NULL; + + return m_roImage[1].GetPointer()->GetTexturePointer(); +} + +BOOL CGrannyMaterial::__IsSpecularEnable() const +{ + return m_bSpecularEnable; +} + +float CGrannyMaterial::__GetSpecularPower() const +{ + return m_fSpecularPower; +} + +extern const std::string& GetModelLocalPath(); + +CGraphicImage* CGrannyMaterial::__GetImagePointer(const char* fileName) +{ + assert(*fileName != '\0'); + + CResourceManager& rkResMgr = CResourceManager::Instance(); + + // SUPPORT_LOCAL_TEXTURE + int fileName_len = strlen(fileName); + if (fileName_len > 2 && fileName[1] != ':') + { + char localFileName[256]; + const std::string& modelLocalPath = GetModelLocalPath(); + + int localFileName_len = modelLocalPath.length() + 1 + fileName_len; + if (localFileName_len < sizeof(localFileName) - 1) + { + _snprintf(localFileName, sizeof(localFileName), "%s%s", GetModelLocalPath().c_str(), fileName); + CResource* pResource = rkResMgr.GetResourcePointer(localFileName); + return static_cast(pResource); + } + } + // END_OF_SUPPORT_LOCAL_TEXTURE + + + CResource* pResource = rkResMgr.GetResourcePointer(fileName); + return static_cast(pResource); +} + +bool CGrannyMaterial::CreateFromGrannyMaterialPointer(granny_material * pgrnMaterial) +{ + m_pgrnMaterial = pgrnMaterial; + + granny_texture * pgrnDiffuseTexture = NULL; + granny_texture * pgrnOpacityTexture = NULL; + + if (pgrnMaterial) + { + if (pgrnMaterial->MapCount > 1 && !_strnicmp(pgrnMaterial->Name, "Blend", 5)) + { + pgrnDiffuseTexture = GrannyGetMaterialTextureByType(pgrnMaterial->Maps[0].Material, GrannyDiffuseColorTexture); + pgrnOpacityTexture = GrannyGetMaterialTextureByType(pgrnMaterial->Maps[1].Material, GrannyDiffuseColorTexture); + } + else + { + pgrnDiffuseTexture = GrannyGetMaterialTextureByType(m_pgrnMaterial, GrannyDiffuseColorTexture); + pgrnOpacityTexture = GrannyGetMaterialTextureByType(m_pgrnMaterial, GrannyOpacityTexture); + } + + // Two-Side ʿ ˻ + { + granny_int32 twoSided = 0; + granny_data_type_definition TwoSidedFieldType[] = + { + {GrannyInt32Member, "Two-sided"}, + {GrannyEndMember}, + }; + + granny_variant twoSideResult; + + if (GrannyFindMatchingMember(pgrnMaterial->ExtendedData.Type, pgrnMaterial->ExtendedData.Object, "Two-sided", &twoSideResult) && NULL != twoSideResult.Type) + GrannyConvertSingleObject(twoSideResult.Type, twoSideResult.Object, TwoSidedFieldType, &twoSided, NULL); + + m_bTwoSideRender = 1 == twoSided; + } + } + + if (pgrnDiffuseTexture) + m_roImage[0].SetPointer(__GetImagePointer(pgrnDiffuseTexture->FromFileName)); + + if (pgrnOpacityTexture) + m_roImage[1].SetPointer(__GetImagePointer(pgrnOpacityTexture->FromFileName)); + + // ۽Ƽ ޽ + if (!m_roImage[1].IsNull()) + m_eType = TYPE_BLEND_PNT; + else + m_eType = TYPE_DIFFUSE_PNT; + + return true; +} + +void CGrannyMaterial::Initialize() +{ + m_roImage[0] = NULL; + m_roImage[1] = NULL; + + SetSpecularInfo(FALSE, 0.0f, 0); +} + +void CGrannyMaterial::__ApplyDiffuseRenderState() +{ + STATEMANAGER.SetTexture(0, GetD3DTexture(0)); + + if (m_bTwoSideRender) + { + // -_- μ ... Save & Restore ϸ δ. Save & Restore . + m_dwLastCullRenderStateForTwoSideRendering = STATEMANAGER.GetRenderState(D3DRS_CULLMODE); + STATEMANAGER.SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + } +} + +void CGrannyMaterial::__RestoreDiffuseRenderState() +{ + if (m_bTwoSideRender) + { + STATEMANAGER.SetRenderState(D3DRS_CULLMODE, m_dwLastCullRenderStateForTwoSideRendering); + } +} + +void CGrannyMaterial::__ApplySpecularRenderState() +{ + if (TRUE == STATEMANAGER.GetRenderState(D3DRS_ALPHABLENDENABLE)) + { + __ApplyDiffuseRenderState(); + return; + } + + CGraphicTexture* pkTexture=ms_akSphereMapInstance[m_bSphereMapIndex].GetTexturePointer(); + + STATEMANAGER.SetTexture(0, GetD3DTexture(0)); + + if (pkTexture) + STATEMANAGER.SetTexture(1, pkTexture->GetD3DTexture()); + else + STATEMANAGER.SetTexture(1, NULL); + + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, D3DXCOLOR(g_fSpecularColor.r, g_fSpecularColor.g, g_fSpecularColor.b, __GetSpecularPower())); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATEALPHA_ADDCOLOR); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + + STATEMANAGER.SetTransform(D3DTS_TEXTURE1, &ms_matSpecular); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); +} + +void CGrannyMaterial::__RestoreSpecularRenderState() +{ + if (TRUE == STATEMANAGER.GetRenderState(D3DRS_ALPHABLENDENABLE)) + { + __RestoreDiffuseRenderState(); + return; + } + + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSU); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSV); + + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXCOORDINDEX); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG2); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAARG1); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAARG2); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAOP); +} + +void CGrannyMaterial::CreateSphereMap(UINT uMapIndex, const char* c_szSphereMapImageFileName) +{ + CResourceManager& rkResMgr = CResourceManager::Instance(); + CGraphicImage * pImage = (CGraphicImage *)rkResMgr.GetResourcePointer(c_szSphereMapImageFileName); + ms_akSphereMapInstance[uMapIndex].SetImagePointer(pImage); +} + +void CGrannyMaterial::DestroySphereMap() +{ + for (UINT uMapIndex=0; uMapIndexIsIn(c_szImageName, &iStage)) + { + CGrannyMaterial* pkNewMtrl=new CGrannyMaterial; + pkNewMtrl->Copy(*roMtrl.GetPointer()); + pkNewMtrl->SetImagePointer(iStage, pImage); + roMtrl=pkNewMtrl; + + return; + } + } +} + +void CGrannyMaterialPalette::SetMaterialData(const char* c_szMtrlName, const SMaterialData& c_rkMaterialData) +{ + if (c_szMtrlName) + { + std::vector::iterator i; + for (i=m_mtrlVector.begin(); i!=m_mtrlVector.end(); ++i) + { + CGrannyMaterial::TRef& roMtrl=*i; + + int iStage; + if (roMtrl->IsIn(c_szMtrlName, &iStage)) + { + CGrannyMaterial* pkNewMtrl=new CGrannyMaterial; + pkNewMtrl->Copy(*roMtrl.GetPointer()); + pkNewMtrl->SetImagePointer(iStage, c_rkMaterialData.pImage); + pkNewMtrl->SetSpecularInfo(c_rkMaterialData.isSpecularEnable, c_rkMaterialData.fSpecularPower, c_rkMaterialData.bSphereMapIndex); + roMtrl=pkNewMtrl; + + return; + } + } + } + else + { + std::vector::iterator i; + for (i=m_mtrlVector.begin(); i!=m_mtrlVector.end(); ++i) + { + CGrannyMaterial::TRef& roMtrl=*i; + roMtrl->SetSpecularInfo(c_rkMaterialData.isSpecularEnable, c_rkMaterialData.fSpecularPower, c_rkMaterialData.bSphereMapIndex); + } + } +} + +void CGrannyMaterialPalette::SetSpecularInfo(const char* c_szMtrlName, BOOL bEnable, float fPower) +{ + DWORD size=m_mtrlVector.size(); + DWORD i; + if (c_szMtrlName) + { + for (i=0; iIsIn(c_szMtrlName, &iStage)) + { + roMtrl->SetSpecularInfo(bEnable, fPower, 0); + return; + } + } + } + else + { + for (i=0; iSetSpecularInfo(bEnable, fPower, 0); + } + } +} + +DWORD CGrannyMaterialPalette::RegisterMaterial(granny_material* pgrnMaterial) +{ + DWORD size=m_mtrlVector.size(); + DWORD i; + for (i=0; iIsEqual(pgrnMaterial)) + return i; + } + + CGrannyMaterial* pkNewMtrl=new CGrannyMaterial; + pkNewMtrl->CreateFromGrannyMaterialPointer(pgrnMaterial); + m_mtrlVector.push_back(pkNewMtrl); + + return size; +} + +DWORD CGrannyMaterialPalette::GetMaterialCount() const +{ + return m_mtrlVector.size(); +} + +/* +void CActorInstance::BeginSpecularRender() +{ + // NOTE - Blendingؼ κ Specular Ű ʴ´ - [levites] + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, D3DXCOLOR(1.0f, 1.0f, 1.0f, m_AddColor.r)); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATEALPHA_ADDCOLOR); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + +// STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); +// STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); +// STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); +// STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); +// +// STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); +// STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE); +// STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATEALPHA_ADDCOLOR); +// STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT); +// STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + +// D3DXMATRIX texMatrix; +// GetSphereMatrix(&texMatrix); +// STATEMANAGER.SetTransform(D3DTS_TEXTURE1, &texMatrix); +// STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); + + // Type 1 +// STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); +// // Type 2 +// STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACENORMAL); +} + +void CActorInstance::EndSpecularRender() +{ +// STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); +// STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); +} +*/ diff --git a/source/EterGrnLib/Material.h b/source/EterGrnLib/Material.h new file mode 100644 index 0000000..368c5cb --- /dev/null +++ b/source/EterGrnLib/Material.h @@ -0,0 +1,120 @@ +#pragma once + +#include +#include +#include + +#include "../eterlib/ReferenceObject.h" +#include "../eterlib/Ref.h" +#include "../eterlib/GrpImageInstance.h" +#include "Util.h" + +class CGrannyMaterial : public CReferenceObject +{ + public: + typedef CRef TRef; + + static void CreateSphereMap(UINT uMapIndex, const char* c_szSphereMapImageFileName); + static void DestroySphereMap(); + + public: + enum EType + { + TYPE_DIFFUSE_PNT, + TYPE_BLEND_PNT, + TYPE_MAX_NUM + }; + + public: + static void TranslateSpecularMatrix(float fAddX, float fAddY, float fAddZ); + + private: + static D3DXMATRIX ms_matSpecular; + static D3DXVECTOR3 ms_v3SpecularTrans; + + public: + CGrannyMaterial(); + virtual ~CGrannyMaterial(); + + void Destroy(); + void Copy(CGrannyMaterial& rkMtrl); + bool IsEqual(granny_material * pgrnMaterial) const; + bool IsIn(const char* c_szImageName, int* iStage); + void SetSpecularInfo(BOOL bFlag, float fPower, BYTE uSphereMapIndex); + + void ApplyRenderState(); + void RestoreRenderState(); + + protected: + void Initialize(); + + public: + bool CreateFromGrannyMaterialPointer(granny_material* pgrnMaterial); + void SetImagePointer(int iStage, CGraphicImage* pImage); + + CGrannyMaterial::EType GetType() const; + CGraphicImage * GetImagePointer(int iStage) const; + + const CGraphicTexture * GetDiffuseTexture() const; + const CGraphicTexture * GetOpacityTexture() const; + + LPDIRECT3DTEXTURE8 GetD3DTexture(int iStage) const; + + bool IsTwoSided() const { return m_bTwoSideRender; } + + + protected: + CGraphicImage * __GetImagePointer(const char * c_szFileName); + + BOOL __IsSpecularEnable() const; + float __GetSpecularPower() const; + + void __ApplyDiffuseRenderState(); + void __RestoreDiffuseRenderState(); + void __ApplySpecularRenderState(); + void __RestoreSpecularRenderState(); + + protected: + granny_material * m_pgrnMaterial; + CGraphicImage::TRef m_roImage[2]; + EType m_eType; + + float m_fSpecularPower; + BOOL m_bSpecularEnable; + bool m_bTwoSideRender; + DWORD m_dwLastCullRenderStateForTwoSideRendering; + BYTE m_bSphereMapIndex; + + + void (CGrannyMaterial::*m_pfnApplyRenderState)(); + void (CGrannyMaterial::*m_pfnRestoreRenderState)(); + + private: + enum + { + SPHEREMAP_NUM = 10, + }; + static CGraphicImageInstance ms_akSphereMapInstance[SPHEREMAP_NUM]; +}; + +class CGrannyMaterialPalette +{ + public: + CGrannyMaterialPalette(); + virtual ~CGrannyMaterialPalette(); + + void Clear(); + void Copy(const CGrannyMaterialPalette& rkMtrlPalSrc); + + DWORD RegisterMaterial(granny_material* pgrnMaterial); + void SetMaterialImagePointer(const char* c_szMtrlName, CGraphicImage* pImage); + void SetMaterialData(const char* c_szMtrlName, const SMaterialData& c_rkMaterialData); + void SetSpecularInfo(const char* c_szMtrlName, BOOL bEnable, float fPower); + + CGrannyMaterial& GetMaterialRef(DWORD mtrlIndex); + + DWORD GetMaterialCount() const; + + protected: + std::vector m_mtrlVector; +}; \ No newline at end of file diff --git a/source/EterGrnLib/Mesh.cpp b/source/EterGrnLib/Mesh.cpp new file mode 100644 index 0000000..94fdcb1 --- /dev/null +++ b/source/EterGrnLib/Mesh.cpp @@ -0,0 +1,311 @@ +#include "StdAfx.h" +#include "Mesh.h" +#include "Model.h" +#include "Material.h" + +granny_data_type_definition GrannyPNT3322VertexType[5] = +{ + {GrannyReal32Member, GrannyVertexPositionName, 0, 3}, + {GrannyReal32Member, GrannyVertexNormalName, 0, 3}, + {GrannyReal32Member, GrannyVertexTextureCoordinatesName"0", 0, 2}, + {GrannyReal32Member, GrannyVertexTextureCoordinatesName"1", 0, 2}, + {GrannyEndMember} +}; + +void CGrannyMesh::LoadIndices(void * dstBaseIndices) +{ + const granny_mesh * pgrnMesh = GetGrannyMeshPointer(); + + TIndex * dstIndices = ((TIndex *)dstBaseIndices) + m_idxBasePos; + GrannyCopyMeshIndices(pgrnMesh, sizeof(TIndex), dstIndices); +} + +void CGrannyMesh::LoadPNTVertices(void * dstBaseVertices) +{ + const granny_mesh * pgrnMesh = GetGrannyMeshPointer(); + + if (!GrannyMeshIsRigid(pgrnMesh)) + return; + + TPNTVertex * dstVertices = ((TPNTVertex *)dstBaseVertices) + m_vtxBasePos; + GrannyCopyMeshVertices(pgrnMesh, m_pgrnMeshType, dstVertices); +} + +void CGrannyMesh::NEW_LoadVertices(void * dstBaseVertices) +{ + const granny_mesh * pgrnMesh = GetGrannyMeshPointer(); + + if (!GrannyMeshIsRigid(pgrnMesh)) + return; + + TPNTVertex * dstVertices = ((TPNTVertex *)dstBaseVertices) + m_vtxBasePos; + GrannyCopyMeshVertices(pgrnMesh, m_pgrnMeshType, dstVertices); +} + +void CGrannyMesh::DeformPNTVertices(void * dstBaseVertices, D3DXMATRIX * boneMatrices, granny_mesh_binding* pgrnMeshBinding) const +{ + assert(dstBaseVertices != NULL); + assert(boneMatrices != NULL); + assert(m_pgrnMeshDeformer != NULL); + + const granny_mesh * pgrnMesh = GetGrannyMeshPointer(); + + TPNTVertex * srcVertices = (TPNTVertex *) GrannyGetMeshVertices(pgrnMesh); + TPNTVertex * dstVertices = ((TPNTVertex *) dstBaseVertices) + m_vtxBasePos; + + int vtxCount = GrannyGetMeshVertexCount(pgrnMesh); + + // WORK + int * boneIndices = (int*)GrannyGetMeshBindingToBoneIndices(pgrnMeshBinding); + // END_OF_WORK + + GrannyDeformVertices( + m_pgrnMeshDeformer, + boneIndices, + (float *)boneMatrices, + vtxCount, + srcVertices, + dstVertices); +} + +bool CGrannyMesh::CanDeformPNTVertices() const +{ + return m_canDeformPNTVertex; +} + +const granny_mesh * CGrannyMesh::GetGrannyMeshPointer() const +{ + return m_pgrnMesh; +} + +const CGrannyMesh::TTriGroupNode * CGrannyMesh::GetTriGroupNodeList(CGrannyMaterial::EType eMtrlType) const +{ + return m_triGroupNodeLists[eMtrlType]; +} + +int CGrannyMesh::GetVertexCount() const +{ + assert(m_pgrnMesh!=NULL); + return GrannyGetMeshVertexCount(m_pgrnMesh); +} + +int CGrannyMesh::GetVertexBasePosition() const +{ + return m_vtxBasePos; +} + +int CGrannyMesh::GetIndexBasePosition() const +{ + return m_idxBasePos; +} + +// WORK +int * CGrannyMesh::GetDefaultBoneIndices() const +{ + return (int*)GrannyGetMeshBindingToBoneIndices(m_pgrnMeshBindingTemp); +} +// END_OF_WORK + +bool CGrannyMesh::IsEmpty() const +{ + if (m_pgrnMesh) + return false; + + return true; +} + +bool CGrannyMesh::CreateFromGrannyMeshPointer(granny_skeleton * pgrnSkeleton, granny_mesh * pgrnMesh, int vtxBasePos, int idxBasePos, CGrannyMaterialPalette& rkMtrlPal) +{ + assert(IsEmpty()); + + m_pgrnMesh = pgrnMesh; + m_vtxBasePos = vtxBasePos; + m_idxBasePos = idxBasePos; + + if (m_pgrnMesh->BoneBindingCount < 0) + return true; + + // WORK + m_pgrnMeshBindingTemp = GrannyNewMeshBinding(m_pgrnMesh, pgrnSkeleton, pgrnSkeleton); + // END_OF_WORK + + if (!GrannyMeshIsRigid(m_pgrnMesh)) + { + m_canDeformPNTVertex = true; + + granny_data_type_definition * pgrnInputType = GrannyGetMeshVertexType(m_pgrnMesh); + granny_data_type_definition * pgrnOutputType = m_pgrnMeshType; + + m_pgrnMeshDeformer = GrannyNewMeshDeformer(pgrnInputType, pgrnOutputType, GrannyDeformPositionNormal, GrannyAllowUncopiedTail); + assert(m_pgrnMeshDeformer != NULL && "Cannot create mesh deformer"); + } + + // Two Side Mesh + if (!strncmp(m_pgrnMesh->Name, "2x", 2)) + m_isTwoSide = true; + + if (!LoadMaterials(rkMtrlPal)) + return false; + + if (!LoadTriGroupNodeList(rkMtrlPal)) + return false; + + return true; +} + +bool CGrannyMesh::LoadTriGroupNodeList(CGrannyMaterialPalette& rkMtrlPal) +{ + assert(m_pgrnMesh != NULL); + assert(m_triGroupNodes == NULL); + + int mtrlCount = m_pgrnMesh->MaterialBindingCount; + if (mtrlCount <= 0) // õ 2 ũ ߻ + return true; + + int GroupNodeCount = GrannyGetMeshTriangleGroupCount(m_pgrnMesh); + if (GroupNodeCount <= 0) + return true; + + m_triGroupNodes = new TTriGroupNode[GroupNodeCount]; + + const granny_tri_material_group * c_pgrnTriGroups = GrannyGetMeshTriangleGroups(m_pgrnMesh); + + for (int g = 0; g < GroupNodeCount; ++g) + { + const granny_tri_material_group & c_rgrnTriGroup = c_pgrnTriGroups[g]; + TTriGroupNode * pTriGroupNode = m_triGroupNodes + g; + + pTriGroupNode->idxPos = m_idxBasePos + c_rgrnTriGroup.TriFirst * 3; + pTriGroupNode->triCount = c_rgrnTriGroup.TriCount; + + int iMtrl = c_rgrnTriGroup.MaterialIndex; + if (iMtrl < 0 || iMtrl >= mtrlCount) + { + pTriGroupNode->mtrlIndex=0;//m_mtrlIndexVector[iMtrl]; + } + else + { + pTriGroupNode->mtrlIndex=m_mtrlIndexVector[iMtrl]; + } + + const CGrannyMaterial& rkMtrl=rkMtrlPal.GetMaterialRef(pTriGroupNode->mtrlIndex); + pTriGroupNode->pNextTriGroupNode = m_triGroupNodeLists[rkMtrl.GetType()]; + m_triGroupNodeLists[rkMtrl.GetType()] = pTriGroupNode; + + } + + return true; +} + +void CGrannyMesh::RebuildTriGroupNodeList() +{ + assert(!"CGrannyMesh::RebuildTriGroupNodeList() - 带 ϴ°- -?"); + /* + int mtrlCount = m_pgrnMesh->MaterialBindingCount; + int GroupNodeCount = GrannyGetMeshTriangleGroupCount(m_pgrnMesh); + + if (GroupNodeCount <= 0) + return; + + const granny_tri_material_group * c_pgrnTriGroups = GrannyGetMeshTriangleGroups(m_pgrnMesh); + + for (int g = 0; g < GroupNodeCount; ++g) + { + const granny_tri_material_group& c_rgrnTriGroup = c_pgrnTriGroups[g]; + TTriGroupNode * pTriGroupNode = m_triGroupNodes + g; + + int iMtrl = c_rgrnTriGroup.MaterialIndex; + + if (iMtrl >= 0 && iMtrl < mtrlCount) + { + CGrannyMaterial & rMtrl = m_mtrls[iMtrl]; + + pTriGroupNode->lpd3dTextures[0] = rMtrl.GetD3DTexture(0); + pTriGroupNode->lpd3dTextures[1] = rMtrl.GetD3DTexture(1); + + } + } + */ +} + +bool CGrannyMesh::LoadMaterials(CGrannyMaterialPalette& rkMtrlPal) +{ + assert(m_pgrnMesh != NULL); + + if (m_pgrnMesh->MaterialBindingCount <= 0) + return true; + + int mtrlCount = m_pgrnMesh->MaterialBindingCount; + bool bHaveBlendThing = false; + + for (int m = 0; m < mtrlCount; ++m) + { + granny_material* pgrnMaterial = m_pgrnMesh->MaterialBindings[m].Material; + DWORD mtrlIndex=rkMtrlPal.RegisterMaterial(pgrnMaterial); + m_mtrlIndexVector.push_back(mtrlIndex); + bHaveBlendThing |= rkMtrlPal.GetMaterialRef(mtrlIndex).GetType() == CGrannyMaterial::TYPE_BLEND_PNT; + } + m_bHaveBlendThing = bHaveBlendThing; + + return true; +} + +bool CGrannyMesh::IsTwoSide() const +{ + return m_isTwoSide; +} + +void CGrannyMesh::SetPNT2Mesh() +{ + m_pgrnMeshType = GrannyPNT3322VertexType; +} + +void CGrannyMesh::Destroy() +{ + if (m_triGroupNodes) + delete [] m_triGroupNodes; + + m_mtrlIndexVector.clear(); + + // WORK + if (m_pgrnMeshBindingTemp) + GrannyFreeMeshBinding(m_pgrnMeshBindingTemp); + // END_OF_WORK + + if (m_pgrnMeshDeformer) + GrannyFreeMeshDeformer(m_pgrnMeshDeformer); + + Initialize(); +} + +void CGrannyMesh::Initialize() +{ + for (int r = 0; r < CGrannyMaterial::TYPE_MAX_NUM; ++r) + m_triGroupNodeLists[r] = NULL; + + m_pgrnMeshType = GrannyPNT332VertexType; + m_pgrnMesh = NULL; + // WORK + m_pgrnMeshBindingTemp = NULL; + // END_OF_WORK + m_pgrnMeshDeformer = NULL; + + m_triGroupNodes = NULL; + + m_vtxBasePos = 0; + m_idxBasePos = 0; + + m_canDeformPNTVertex = false; + m_isTwoSide = false; + m_bHaveBlendThing = false; +} + +CGrannyMesh::CGrannyMesh() +{ + Initialize(); +} + +CGrannyMesh::~CGrannyMesh() +{ + Destroy(); +} diff --git a/source/EterGrnLib/Mesh.h b/source/EterGrnLib/Mesh.h new file mode 100644 index 0000000..30ad265 --- /dev/null +++ b/source/EterGrnLib/Mesh.h @@ -0,0 +1,98 @@ +#pragma once + +#include "Material.h" + +extern granny_data_type_definition GrannyPNT3322VertexType[5]; + +struct granny_pnt3322_vertex +{ + granny_real32 Position[3]; + granny_real32 Normal[3]; + granny_real32 UV0[2]; + granny_real32 UV1[2]; +}; + +class CGrannyMesh +{ + public: + enum EType + { + TYPE_RIGID, + TYPE_DEFORM, + TYPE_MAX_NUM + }; + + typedef struct STriGroupNode + { + STriGroupNode * pNextTriGroupNode; + int idxPos; + int triCount; + DWORD mtrlIndex; + } TTriGroupNode; + + public: + CGrannyMesh(); + virtual ~CGrannyMesh(); + + bool IsEmpty() const; + bool CreateFromGrannyMeshPointer(granny_skeleton* pgrnSkeleton, granny_mesh* pgrnMesh, int vtxBasePos, int idxBasePos, CGrannyMaterialPalette& rkMtrlPal); + void LoadIndices(void* dstBaseIndices); + void LoadPNTVertices(void* dstBaseVertices); + void NEW_LoadVertices(void* dstBaseVertices); + void Destroy(); + + void SetPNT2Mesh(); + + void DeformPNTVertices(void* dstBaseVertices, D3DXMATRIX* boneMatrices, granny_mesh_binding* pgrnMeshBinding) const; + bool CanDeformPNTVertices() const; + bool IsTwoSide() const; + + int GetVertexCount() const; + + // WORK + int * GetDefaultBoneIndices() const; + // END_OF_WORK + + int GetVertexBasePosition() const; + int GetIndexBasePosition() const; + + const granny_mesh * GetGrannyMeshPointer() const; + const CGrannyMesh::TTriGroupNode * GetTriGroupNodeList(CGrannyMaterial::EType eMtrlType) const; + + void RebuildTriGroupNodeList(); + void ReloadMaterials(); + + protected: + void Initialize(); + + bool LoadMaterials(CGrannyMaterialPalette& rkMtrlPal); + bool LoadTriGroupNodeList(CGrannyMaterialPalette& rkMtrlPal); + + protected: + // Granny Mesh Data + granny_data_type_definition * m_pgrnMeshType; + granny_mesh * m_pgrnMesh; + + // WORK + granny_mesh_binding * m_pgrnMeshBindingTemp; + // END_OF_WORK + + granny_mesh_deformer * m_pgrnMeshDeformer; + + // Granny Material Data + std::vector m_mtrlIndexVector; + + // TriGroups Data + TTriGroupNode * m_triGroupNodes; + TTriGroupNode * m_triGroupNodeLists[CGrannyMaterial::TYPE_MAX_NUM]; + + int m_vtxBasePos; + int m_idxBasePos; + + bool m_canDeformPNTVertex; + bool m_isTwoSide; + private: + bool m_bHaveBlendThing; + public: + bool HaveBlendThing() { return m_bHaveBlendThing; } +}; \ No newline at end of file diff --git a/source/EterGrnLib/Model.cpp b/source/EterGrnLib/Model.cpp new file mode 100644 index 0000000..b8d53af --- /dev/null +++ b/source/EterGrnLib/Model.cpp @@ -0,0 +1,419 @@ +#include "StdAfx.h" +#include "Model.h" +#include "Mesh.h" + +const CGrannyMaterialPalette& CGrannyModel::GetMaterialPalette() const +{ + return m_kMtrlPal; +} + +const CGrannyModel::TMeshNode* CGrannyModel::GetMeshNodeList(CGrannyMesh::EType eMeshType, CGrannyMaterial::EType eMtrlType) const +{ + return m_meshNodeLists[eMeshType][eMtrlType]; +} + +CGrannyMesh * CGrannyModel::GetMeshPointer(int iMesh) +{ + assert(CheckMeshIndex(iMesh)); + assert(m_meshs != NULL); + + return m_meshs + iMesh; +} + +const CGrannyMesh* CGrannyModel::GetMeshPointer(int iMesh) const +{ + assert(CheckMeshIndex(iMesh)); + assert(m_meshs != NULL); + + return m_meshs + iMesh; +} + +bool CGrannyModel::CanDeformPNTVertices() const +{ + return m_canDeformPNVertices; +} + +void CGrannyModel::DeformPNTVertices(void * dstBaseVertices, D3DXMATRIX * boneMatrices, const std::vector& c_rvct_pgrnMeshBinding) const +{ + int meshCount = GetMeshCount(); + + for (int iMesh = 0; iMesh < meshCount; ++iMesh) + { + assert(iMesh < c_rvct_pgrnMeshBinding.size()); + + CGrannyMesh & rMesh = m_meshs[iMesh]; + if (rMesh.CanDeformPNTVertices()) + rMesh.DeformPNTVertices(dstBaseVertices, boneMatrices, c_rvct_pgrnMeshBinding[iMesh]); + } +} + +int CGrannyModel::GetRigidVertexCount() const +{ + return m_rigidVtxCount; +} + +int CGrannyModel::GetDeformVertexCount() const +{ + return m_deformVtxCount; +} + +int CGrannyModel::GetVertexCount() const +{ + return m_vtxCount; +} + +int CGrannyModel::GetMeshCount() const +{ + return m_pgrnModel ? m_pgrnModel->MeshBindingCount : 0; +} + +granny_model* CGrannyModel::GetGrannyModelPointer() +{ + return m_pgrnModel; +} + +LPDIRECT3DINDEXBUFFER8 CGrannyModel::GetD3DIndexBuffer() const +{ + return m_idxBuf.GetD3DIndexBuffer(); +} + +LPDIRECT3DVERTEXBUFFER8 CGrannyModel::GetPNTD3DVertexBuffer() const +{ + return m_pntVtxBuf.GetD3DVertexBuffer(); +} + +bool CGrannyModel::LockVertices(void** indicies, void** vertices) const +{ + if (!m_idxBuf.Lock(indicies)) + return false; + + if (!m_pntVtxBuf.Lock(vertices)) + { + m_idxBuf.Unlock(); + return false; + } + + return true; +} + +void CGrannyModel::UnlockVertices() const +{ + m_idxBuf.Unlock(); + m_pntVtxBuf.Unlock(); +} + +bool CGrannyModel::LoadPNTVertices() +{ + if (m_rigidVtxCount <= 0) + return true; + + assert(m_meshs != NULL); + + if (!m_pntVtxBuf.Create(m_rigidVtxCount, m_dwFvF, D3DUSAGE_WRITEONLY, D3DPOOL_MANAGED)) + return false; + + void* vertices; + if (!m_pntVtxBuf.Lock(&vertices)) + return false; + + for (int m = 0; m < m_pgrnModel->MeshBindingCount; ++m) + { + CGrannyMesh& rMesh = m_meshs[m]; + rMesh.LoadPNTVertices(vertices); + } + + m_pntVtxBuf.Unlock(); + return true; +} + +bool CGrannyModel::LoadIndices() +{ + //assert(m_idxCount > 0); + if (m_idxCount <= 0) + return true; + + if (!m_idxBuf.Create(m_idxCount, D3DFMT_INDEX16)) + return false; + + void * indices; + + if (!m_idxBuf.Lock((void**)&indices)) + return false; + + for (int m = 0; m < m_pgrnModel->MeshBindingCount; ++m) + { + CGrannyMesh& rMesh = m_meshs[m]; + rMesh.LoadIndices(indices); + } + + m_idxBuf.Unlock(); + return true; +} + +bool CGrannyModel::LoadMeshs() +{ + assert(m_meshs == NULL); + assert(m_pgrnModel != NULL); + + if (m_pgrnModel->MeshBindingCount <= 0) // ޽ + return true; + + granny_skeleton * pgrnSkeleton = m_pgrnModel->Skeleton; + + int vtxRigidPos = 0; + int vtxDeformPos = 0; + int vtxPos = 0; + int idxPos = 0; + + int diffusePNTMeshNodeCount = 0; + int blendPNTMeshNodeCount = 0; + int blendPNT2MeshNodeCount = 0; + + int meshCount = GetMeshCount(); + m_meshs = new CGrannyMesh[meshCount]; + + m_dwFvF = 0; + + for (int m = 0; m < meshCount; ++m) + { + CGrannyMesh& rMesh = m_meshs[m]; + granny_mesh* pgrnMesh = m_pgrnModel->MeshBindings[m].Mesh; + + if (GrannyMeshIsRigid(pgrnMesh)) + { + if (!rMesh.CreateFromGrannyMeshPointer(pgrnSkeleton, pgrnMesh, vtxRigidPos, idxPos, m_kMtrlPal)) + return false; + + vtxRigidPos += GrannyGetMeshVertexCount(pgrnMesh); + } + else + { + if (!rMesh.CreateFromGrannyMeshPointer(pgrnSkeleton, pgrnMesh, vtxDeformPos, idxPos, m_kMtrlPal)) + return false; + + vtxDeformPos += GrannyGetMeshVertexCount(pgrnMesh); + m_canDeformPNVertices |= rMesh.CanDeformPNTVertices(); + } + m_bHaveBlendThing |= rMesh.HaveBlendThing(); + + granny_int32x grni32xTypeCount = GrannyGetTotalTypeSize(pgrnMesh->PrimaryVertexData->VertexType) / 32; + int i = 0; + while (i < grni32xTypeCount) + { + if (NULL == pgrnMesh->PrimaryVertexData->VertexType[i].Name || 0 == strlen(pgrnMesh->PrimaryVertexData->VertexType[i].Name)) + { + ++i; + continue; + } + if ( 0 == strcmp(pgrnMesh->PrimaryVertexData->VertexType[i].Name, GrannyVertexPositionName) ) + m_dwFvF |= D3DFVF_XYZ; + else if ( 0 == strcmp(pgrnMesh->PrimaryVertexData->VertexType[i].Name, GrannyVertexNormalName) ) + m_dwFvF |= D3DFVF_NORMAL; + else if ( 0 == strcmp(pgrnMesh->PrimaryVertexData->VertexType[i].Name, GrannyVertexTextureCoordinatesName"0") ) + m_dwFvF |= D3DFVF_TEX1; + else if ( 0 == strcmp(pgrnMesh->PrimaryVertexData->VertexType[i].Name, GrannyVertexTextureCoordinatesName"1") ) + m_dwFvF |= D3DFVF_TEX2; + ++i; + } + + vtxPos += GrannyGetMeshVertexCount(pgrnMesh); + idxPos += GrannyGetMeshIndexCount(pgrnMesh); + + if (rMesh.GetTriGroupNodeList(CGrannyMaterial::TYPE_DIFFUSE_PNT)) + ++diffusePNTMeshNodeCount; + + if (rMesh.GetTriGroupNodeList(CGrannyMaterial::TYPE_BLEND_PNT)) + ++blendPNTMeshNodeCount; + } + + m_meshNodeCapacity = diffusePNTMeshNodeCount + blendPNTMeshNodeCount + blendPNT2MeshNodeCount; + m_meshNodes = new TMeshNode[m_meshNodeCapacity]; + + for (int n = 0; n < meshCount; ++n) + { + CGrannyMesh& rMesh = m_meshs[n]; + granny_mesh* pgrnMesh = m_pgrnModel->MeshBindings[n].Mesh; + + CGrannyMesh::EType eMeshType = GrannyMeshIsRigid(pgrnMesh) ? CGrannyMesh::TYPE_RIGID : CGrannyMesh::TYPE_DEFORM; + + if (rMesh.GetTriGroupNodeList(CGrannyMaterial::TYPE_DIFFUSE_PNT)) + AppendMeshNode(eMeshType, CGrannyMaterial::TYPE_DIFFUSE_PNT, n); + + if (rMesh.GetTriGroupNodeList(CGrannyMaterial::TYPE_BLEND_PNT)) + AppendMeshNode(eMeshType, CGrannyMaterial::TYPE_BLEND_PNT, n); + } + + // For Dungeon Block + if ((D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1|D3DFVF_TEX2) == m_dwFvF) + { + for (int n = 0; n < meshCount; ++n) + { + CGrannyMesh& rMesh = m_meshs[n]; + rMesh.SetPNT2Mesh(); + } + } + + m_rigidVtxCount = vtxRigidPos; + m_deformVtxCount = vtxDeformPos; + + m_vtxCount = vtxPos; + m_idxCount = idxPos; + return true; +} + +BOOL CGrannyModel::CheckMeshIndex(int iIndex) const +{ + if (iIndex < 0) + return FALSE; + if (iIndex >= m_meshNodeSize) + return FALSE; + + return TRUE; +} + +void CGrannyModel::AppendMeshNode(CGrannyMesh::EType eMeshType, CGrannyMaterial::EType eMtrlType, int iMesh) +{ + assert(m_meshNodeSize < m_meshNodeCapacity); + + TMeshNode& rMeshNode = m_meshNodes[m_meshNodeSize++]; + + rMeshNode.iMesh = iMesh; + rMeshNode.pMesh = m_meshs + iMesh; + rMeshNode.pNextMeshNode = m_meshNodeLists[eMeshType][eMtrlType]; + m_meshNodeLists[eMeshType][eMtrlType] = &rMeshNode; +} + +bool CGrannyModel::CreateFromGrannyModelPointer(granny_model* pgrnModel) +{ + assert(IsEmpty()); + + m_pgrnModel = pgrnModel; + + if (!LoadMeshs()) + return false; + + if (!__LoadVertices()) + return false; + + if (!LoadIndices()) + return false; + + AddReference(); + + return true; +} + +int CGrannyModel::GetIdxCount() +{ + return m_idxCount; +} + +bool CGrannyModel::CreateDeviceObjects() +{ + if (m_rigidVtxCount > 0) + if (!m_pntVtxBuf.CreateDeviceObjects()) + return false; + + if (m_idxCount > 0) + if (!m_idxBuf.CreateDeviceObjects()) + return false; + + int meshCount = GetMeshCount(); + + for (int i = 0; i < meshCount; ++i) + { + CGrannyMesh& rMesh = m_meshs[i]; + rMesh.RebuildTriGroupNodeList(); + } + + return true; +} + +void CGrannyModel::DestroyDeviceObjects() +{ + m_pntVtxBuf.DestroyDeviceObjects(); + m_idxBuf.DestroyDeviceObjects(); +} + +bool CGrannyModel::IsEmpty() const +{ + if (m_pgrnModel) + return false; + + return true; +} + +void CGrannyModel::Destroy() +{ + m_kMtrlPal.Clear(); + + if (m_meshNodes) + delete [] m_meshNodes; + + if (m_meshs) + delete [] m_meshs; + + m_pntVtxBuf.Destroy(); + m_idxBuf.Destroy(); + + Initialize(); +} + +bool CGrannyModel::__LoadVertices() +{ + if (m_rigidVtxCount <= 0) + return true; + + assert(m_meshs != NULL); + +// assert((m_dwFvF & (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1)) == m_dwFvF); + +// if (!m_pntVtxBuf.Create(m_rigidVtxCount, D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1, D3DUSAGE_WRITEONLY, D3DPOOL_MANAGED)) + if (!m_pntVtxBuf.Create(m_rigidVtxCount, m_dwFvF, D3DUSAGE_WRITEONLY, D3DPOOL_MANAGED)) + return false; + + void* vertices; + if (!m_pntVtxBuf.Lock(&vertices)) + return false; + + for (int m = 0; m < m_pgrnModel->MeshBindingCount; ++m) + { + CGrannyMesh& rMesh = m_meshs[m]; + rMesh.NEW_LoadVertices(vertices); + } + + m_pntVtxBuf.Unlock(); + return true; +} + +void CGrannyModel::Initialize() +{ + memset(m_meshNodeLists, 0, sizeof(m_meshNodeLists)); + + m_pgrnModel = NULL; + m_meshs = NULL; + m_meshNodes = NULL; + + m_meshNodeSize = 0; + m_meshNodeCapacity = 0; + + m_rigidVtxCount = 0; + m_deformVtxCount = 0; + m_vtxCount = 0; + m_idxCount = 0; + + m_canDeformPNVertices = false; + + m_dwFvF = 0; + m_bHaveBlendThing = false; +} + +CGrannyModel::CGrannyModel() +{ + Initialize(); +} + +CGrannyModel::~CGrannyModel() +{ + Destroy(); +} diff --git a/source/EterGrnLib/Model.h b/source/EterGrnLib/Model.h new file mode 100644 index 0000000..553d9df --- /dev/null +++ b/source/EterGrnLib/Model.h @@ -0,0 +1,98 @@ +#pragma once + +#include "../eterlib/GrpVertexBuffer.h" +#include "../eterlib/GrpIndexBuffer.h" + +#include "Mesh.h" + +class CGrannyModel : public CReferenceObject +{ + public: + typedef struct SMeshNode + { + int iMesh; + const CGrannyMesh * pMesh; + SMeshNode * pNextMeshNode; + } TMeshNode; + + public: + CGrannyModel(); + virtual ~CGrannyModel(); + + bool IsEmpty() const; + bool CreateFromGrannyModelPointer(granny_model* pgrnModel); + bool CreateDeviceObjects(); + void DestroyDeviceObjects(); + void Destroy(); + + int GetRigidVertexCount() const; + int GetDeformVertexCount() const; + int GetVertexCount() const; + + bool CanDeformPNTVertices() const; + void DeformPNTVertices(void* dstBaseVertices, D3DXMATRIX* boneMatrices, const std::vector& c_rvct_pgrnMeshBinding) const; + + int GetIdxCount(); + int GetMeshCount() const; + CGrannyMesh * GetMeshPointer(int iMesh); + granny_model * GetGrannyModelPointer(); + const CGrannyMesh* GetMeshPointer(int iMesh) const; + + LPDIRECT3DVERTEXBUFFER8 GetPNTD3DVertexBuffer() const; + LPDIRECT3DINDEXBUFFER8 GetD3DIndexBuffer() const; + + const CGrannyModel::TMeshNode* GetMeshNodeList(CGrannyMesh::EType eMeshType, CGrannyMaterial::EType eMtrlType) const; + + bool LockVertices(void** indicies, void** vertices) const; + void UnlockVertices() const; + + const CGrannyMaterialPalette& GetMaterialPalette() const; + + protected: + bool LoadMeshs(); + bool LoadPNTVertices(); + bool LoadIndices(); + void Initialize(); + + BOOL CheckMeshIndex(int iIndex) const; + void AppendMeshNode(CGrannyMesh::EType eMeshType, CGrannyMaterial::EType eMtrlType, int iMesh); + + protected: + // Granny Data + granny_model * m_pgrnModel; + + // Static Data + CGrannyMesh * m_meshs; + + CGraphicVertexBuffer m_pntVtxBuf; // for rigid mesh + CGraphicIndexBuffer m_idxBuf; + + TMeshNode * m_meshNodes; + TMeshNode * m_meshNodeLists[CGrannyMesh::TYPE_MAX_NUM][CGrannyMaterial::TYPE_MAX_NUM]; + + int m_deformVtxCount; + int m_rigidVtxCount; + int m_vtxCount; + int m_idxCount; + + int m_meshNodeSize; + int m_meshNodeCapacity; + + bool m_canDeformPNVertices; + + CGrannyMaterialPalette m_kMtrlPal; + private: + bool m_bHaveBlendThing; + public: + bool HaveBlendThing() { return m_bHaveBlendThing; } + + ////////////////////////////////////////////////////////////////////////// + // New members to support PNT2 type models + protected: + bool __LoadVertices(); + protected: + DWORD m_dwFvF; + // New members to support PNT2 type models + ////////////////////////////////////////////////////////////////////////// + +}; diff --git a/source/EterGrnLib/ModelInstance.cpp b/source/EterGrnLib/ModelInstance.cpp new file mode 100644 index 0000000..da20138 --- /dev/null +++ b/source/EterGrnLib/ModelInstance.cpp @@ -0,0 +1,140 @@ +#include "StdAfx.h" +#include "ModelInstance.h" +#include "Model.h" +#include "../EterLib/ResourceManager.h" + + +CGrannyModel* CGrannyModelInstance::GetModel() +{ + return m_pModel; +} + +void CGrannyModelInstance::SetMaterialImagePointer(const char* c_szImageName, CGraphicImage* pImage) +{ + m_kMtrlPal.SetMaterialImagePointer(c_szImageName, pImage); +} + +void CGrannyModelInstance::SetMaterialData(const char* c_szImageName, const SMaterialData& c_rkMaterialData) +{ + m_kMtrlPal.SetMaterialData(c_szImageName, c_rkMaterialData); +} + +void CGrannyModelInstance::SetSpecularInfo(const char* c_szMtrlName, BOOL bEnable, float fPower) +{ + m_kMtrlPal.SetSpecularInfo(c_szMtrlName, bEnable, fPower); +} + +void CGrannyModelInstance::SetLocalTime(float fLocalTime) +{ + m_fLocalTime = fLocalTime; +} + +int CGrannyModelInstance::ResetLocalTime() +{ + m_fLocalTime = 0.0f; + return 0; +} + +float CGrannyModelInstance::GetLocalTime() +{ + return m_fLocalTime; +} + +void CGrannyModelInstance::SetParentModelInstance(const CGrannyModelInstance* c_pParentModelInstance, const char * c_szBoneName) +{ + int iBoneIndex; + if (!c_pParentModelInstance->GetBoneIndexByName(c_szBoneName, &iBoneIndex)) + return; + + SetParentModelInstance(c_pParentModelInstance, iBoneIndex); +} + +void CGrannyModelInstance::SetParentModelInstance(const CGrannyModelInstance* c_pParentModelInstance, int iBone) +{ + mc_pParentInstance = c_pParentModelInstance; + m_iParentBoneIndex = iBone; +} + +bool CGrannyModelInstance::IsEmpty() +{ + if (m_pModel) + { + // NO_MESH_BUG_FIX + if (!m_meshMatrices) + return true; + // END_OF_NO_MESH_BUG_FIX + return false; + } + + return true; +} + +bool CGrannyModelInstance::CreateDeviceObjects() +{ + __CreateDynamicVertexBuffer(); + + return true; +} + +void CGrannyModelInstance::DestroyDeviceObjects() +{ + __DestroyDynamicVertexBuffer(); +} + +void CGrannyModelInstance::__Initialize() +{ + if (m_pModel) + { + m_pModel->Release(); + } + m_pModel = NULL; + mc_pParentInstance = NULL; + m_iParentBoneIndex = 0; + + m_pgrnModelInstance = NULL; + + // WORK + m_pgrnWorldPoseReal = NULL; + // END_OF_WORK + + // TEST + // m_pgrnWorldPose = NULL; + m_ppkSkeletonInst = NULL; + // END_OF_TEST + + m_meshMatrices = NULL; + m_pgrnCtrl = NULL; + m_pgrnAni = NULL; + + m_dwOldUpdateFrame=0; + +} + +CGrannyModelInstance::CGrannyModelInstance() +{ + m_pModel = NULL; + __Initialize(); +} + +CGrannyModelInstance::~CGrannyModelInstance() +{ + Clear(); +} + +CDynamicPool CGrannyModelInstance::ms_kPool; + +CGrannyModelInstance* CGrannyModelInstance::New() +{ + return ms_kPool.Alloc(); +} + +void CGrannyModelInstance::Delete(CGrannyModelInstance* pkInst) +{ + pkInst->Clear(); + ms_kPool.Free(pkInst); +} + +void CGrannyModelInstance::DestroySystem() +{ + ms_kPool.Destroy(); +} \ No newline at end of file diff --git a/source/EterGrnLib/ModelInstance.h b/source/EterGrnLib/ModelInstance.h new file mode 100644 index 0000000..c7a9a33 --- /dev/null +++ b/source/EterGrnLib/ModelInstance.h @@ -0,0 +1,202 @@ +#pragma once + +//#define CACHE_DEFORMED_VERTEX +#include "../eterlib/GrpImage.h" +#include "../eterlib/GrpCollisionObject.h" + +#include "Model.h" +#include "Motion.h" + +class CGrannyModelInstance : public CGraphicCollisionObject +{ + public: + enum + { + ANIFPS_MIN = 30, + ANIFPS_MAX = 120, + }; + public: + static void DestroySystem(); + + static CGrannyModelInstance* New(); + static void Delete(CGrannyModelInstance* pkInst); + + static CDynamicPool ms_kPool; + + public: + struct FCreateDeviceObjects + { + void operator() (CGrannyModelInstance * pModelInstance) + {pModelInstance->CreateDeviceObjects();} + }; + + struct FDestroyDeviceObjects + { + void operator() (CGrannyModelInstance * pModelInstance) + {pModelInstance->DestroyDeviceObjects();} + }; + + public: + CGrannyModelInstance(); + virtual ~CGrannyModelInstance(); + + bool IsEmpty(); + void Clear(); + + bool CreateDeviceObjects(); + void DestroyDeviceObjects(); + + // Update & Render + void Update(DWORD dwAniFPS); + void UpdateLocalTime(float fElapsedTime); + void UpdateTransform(D3DXMATRIX * pMatrix, float fSecondsElapsed); + + void UpdateSkeleton(const D3DXMATRIX * c_pWorldMatrix, float fLocalTime); + void DeformNoSkin(const D3DXMATRIX * c_pWorldMatrix); + void Deform(const D3DXMATRIX * c_pWorldMatrix); + + // FIXME : ϵ Ѱ 2 ؽ Ǿִ ̱⿡ ̷ + // Ҿ Ű簡 , ñ ( ؽ ) + (ȿ ؽ) + // ̷ ڵ ̷ ʳ մϴ. - [levites] + // NOTE : ο if Ű ٴ ŷ ̷ Լ ü и + // Ű ս 鿡 ϴ. - [levites] + // NOTE : ǹ OneTexture. ijʹ 쿡 TwoTexture. + void RenderWithOneTexture(); + void RenderWithTwoTexture(); + void BlendRenderWithOneTexture(); + void BlendRenderWithTwoTexture(); + void RenderWithoutTexture(); + + // Model + CGrannyModel* GetModel(); + void SetMaterialImagePointer(const char* c_szImageName, CGraphicImage* pImage); + void SetMaterialData(const char* c_szImageName, const SMaterialData& c_rkMaterialData); + void SetSpecularInfo(const char* c_szMtrlName, BOOL bEnable, float fPower); + + void SetMainModelPointer(CGrannyModel* pkModel, CGraphicVertexBuffer* pkSharedDefromableVertexBuffer); + void SetLinkedModelPointer(CGrannyModel* pkModel, CGraphicVertexBuffer* pkSharedDefromableVertexBuffer, CGrannyModelInstance** ppkSkeletonInst); + + // Motion + void SetMotionPointer(const CGrannyMotion* pMotion, float blendTime=0.0f, int loopCount=0, float speedRatio=1.0f); + void ChangeMotionPointer(const CGrannyMotion* pMotion, int loopCount=0, float speedRatio=1.0f); + void SetMotionAtEnd(); + bool IsMotionPlaying(); + + void CopyMotion(CGrannyModelInstance * pModelInstance, bool bIsFreeSourceControl=false); + + // Time + void SetLocalTime(float fLocalTime); + int ResetLocalTime(); + float GetLocalTime(); + float GetNextTime(); + + // WORK + DWORD GetDeformableVertexCount(); + DWORD GetVertexCount(); + + // END_OF_WORK + + // Bone & Attaching + const float * GetBoneMatrixPointer(int iBone) const; + const float * GetCompositeBoneMatrixPointer(int iBone) const; + bool GetMeshMatrixPointer(int iMesh, const D3DXMATRIX ** c_ppMatrix) const; + bool GetBoneIndexByName(const char * c_szBoneName, int * pBoneIndex) const; + void SetParentModelInstance(const CGrannyModelInstance* c_pParentModelInstance, const char * c_szBoneName); + void SetParentModelInstance(const CGrannyModelInstance* c_pParentModelInstance, int iBone); + + // Collision Detection + bool Intersect(const D3DXMATRIX * c_pMatrix, float * pu, float * pv, float * pt); + void MakeBoundBox(TBoundBox* pBoundBox, const float* mat, const float* OBBMin, const float* OBBMax, D3DXVECTOR3* vtMin, D3DXVECTOR3* vtMax); + void GetBoundBox(D3DXVECTOR3 * vtMin, D3DXVECTOR3* vtMax); + + // Reload Texture + void ReloadTexture(); + + + protected: + void __Initialize(); + + void __DestroyModelInstance(); + void __DestroyMeshMatrices(); + void __DestroyDynamicVertexBuffer(); + + + void __CreateModelInstance(); + void __CreateMeshMatrices(); + void __CreateDynamicVertexBuffer(); + + // WORK + void __DestroyWorldPose(); + void __CreateWorldPose(CGrannyModelInstance* pkSrcModelInst); + + bool __CreateMeshBindingVector(CGrannyModelInstance* pkDstModelInst); + void __DestroyMeshBindingVector(); + + int* __GetMeshBoneIndices(unsigned int iMeshBinding) const; + + bool __IsDeformableVertexBuffer(); + void __SetSharedDeformableVertexBuffer(CGraphicVertexBuffer* pkSharedDeformableVertexBuffer); + + IDirect3DVertexBuffer8* __GetDeformableD3DVertexBufferPtr(); + CGraphicVertexBuffer& __GetDeformableVertexBufferRef(); + + granny_world_pose* __GetWorldPosePtr() const; + // END_OF_WORK + + + // Update & Render + void UpdateWorldPose(); + void UpdateWorldMatrices(const D3DXMATRIX * c_pWorldMatrix); + void DeformPNTVertices(void * pvDest); + + void RenderMeshNodeListWithOneTexture(CGrannyMesh::EType eMeshType, CGrannyMaterial::EType eMtrlType); + void RenderMeshNodeListWithTwoTexture(CGrannyMesh::EType eMeshType, CGrannyMaterial::EType eMtrlType); + void RenderMeshNodeListWithoutTexture(CGrannyMesh::EType eMeshType, CGrannyMaterial::EType eMtrlType); + + protected: + // Static Data + CGrannyModel * m_pModel; + + // Granny Data + granny_model_instance * m_pgrnModelInstance; + + //granny_world_pose * m_pgrnWorldPose; // + + granny_control * m_pgrnCtrl; + granny_animation * m_pgrnAni; + + // Meshes' Transform Data + D3DXMATRIX * m_meshMatrices; + + + // Attaching Data + const CGrannyModelInstance * mc_pParentInstance; + int m_iParentBoneIndex; + + // Game Data + float m_fLocalTime; + float m_fSecondsElapsed; + + DWORD m_dwOldUpdateFrame; + + CGrannyMaterialPalette m_kMtrlPal; + + // WORK + granny_world_pose* m_pgrnWorldPoseReal; // ޸𸮴 ⿡ Ҵ + std::vector m_vct_pgrnMeshBinding; + + // Dynamic Vertex Buffer + CGraphicVertexBuffer* m_pkSharedDeformableVertexBuffer; + CGraphicVertexBuffer m_kLocalDeformableVertexBuffer; + bool m_isDeformableVertexBuffer; + // END_OF_WORK + + // TEST + CGrannyModelInstance** m_ppkSkeletonInst; + // END_OF_TEST +#ifdef _TEST + D3DXMATRIX TEST_matWorld; +#endif + public: + bool HaveBlendThing() { return m_pModel->HaveBlendThing(); } +}; diff --git a/source/EterGrnLib/ModelInstanceCollisionDetection.cpp b/source/EterGrnLib/ModelInstanceCollisionDetection.cpp new file mode 100644 index 0000000..4b5c21b --- /dev/null +++ b/source/EterGrnLib/ModelInstanceCollisionDetection.cpp @@ -0,0 +1,267 @@ +#include "Stdafx.h" +#include "ModelInstance.h" +#include "Model.h" + +void CGrannyModelInstance::MakeBoundBox(TBoundBox* pBoundBox, + const float* mat, + const float* OBBMin, + const float* OBBMax, + D3DXVECTOR3* vtMin, + D3DXVECTOR3* vtMax) +{ + pBoundBox->sx = OBBMin[0] * mat[0] + OBBMin[1] * mat[4] + OBBMin[2] * mat[8] + mat[12]; + pBoundBox->sy = OBBMin[0] * mat[1] + OBBMin[1] * mat[5] + OBBMin[2] * mat[9] + mat[13]; + pBoundBox->sz = OBBMin[0] * mat[2] + OBBMin[1] * mat[6] + OBBMin[2] * mat[10] + mat[14]; + + pBoundBox->ex = OBBMax[0] * mat[0] + OBBMax[1] * mat[4] + OBBMax[2] * mat[8] + mat[12]; + pBoundBox->ey = OBBMax[0] * mat[1] + OBBMax[1] * mat[5] + OBBMax[2] * mat[9] + mat[13]; + pBoundBox->ez = OBBMax[0] * mat[2] + OBBMax[1] * mat[6] + OBBMax[2] * mat[10] + mat[14]; + + vtMin->x = min(vtMin->x, pBoundBox->sx); + vtMin->x = min(vtMin->x, pBoundBox->ex); + vtMin->y = min(vtMin->y, pBoundBox->sy); + vtMin->y = min(vtMin->y, pBoundBox->ey); + vtMin->z = min(vtMin->z, pBoundBox->sz); + vtMin->z = min(vtMin->z, pBoundBox->ez); + + vtMax->x = max(vtMax->x, pBoundBox->sx); + vtMax->x = max(vtMax->x, pBoundBox->ex); + vtMax->y = max(vtMax->y, pBoundBox->sy); + vtMax->y = max(vtMax->y, pBoundBox->ey); + vtMax->z = max(vtMax->z, pBoundBox->sz); + vtMax->z = max(vtMax->z, pBoundBox->ez); +} + +bool CGrannyModelInstance::Intersect(const D3DXMATRIX * c_pMatrix, + float * /*pu*/, float * /*pv*/, float * pt) +{ + if (!m_pgrnModelInstance) + return false; + + float u, v, t; + bool ret = false; + *pt = 100000000.0f; + + float max = 10000000.0f; + D3DXVECTOR3 vtMin, vtMax; + vtMin.x = vtMin.y = vtMin.z = max; + vtMax.x = vtMax.y = vtMax.z = -max; + + static stl_stack_pool s_boundBoxPool(1024); + s_boundBoxPool.clear(); + + int meshCount = m_pModel->GetMeshCount(); + + for (int m = 0; m < meshCount; ++m) + { + //const CGrannyMesh * pMesh = m_pModel->GetMeshPointer(m); + const granny_mesh * pgrnMesh = m_pModel->GetGrannyModelPointer()->MeshBindings[m].Mesh; + + for (int b = 0; b < pgrnMesh->BoneBindingCount; ++b) + { + const granny_bone_binding& rgrnBoneBinding = pgrnMesh->BoneBindings[b]; + + TBoundBox * pBoundBox = s_boundBoxPool.alloc(); + + // WORK + float * Transform = GrannyGetWorldPose4x4(__GetWorldPosePtr(), __GetMeshBoneIndices(m)[b]); + // END_OF_WORK + + MakeBoundBox(pBoundBox, + Transform, + rgrnBoneBinding.OBBMin, + rgrnBoneBinding.OBBMax, + &vtMin, + &vtMax); + + pBoundBox->meshIndex = m; + pBoundBox->boneIndex = b; + } + } + + if (!IntersectCube(c_pMatrix, + vtMin.x, vtMin.y, vtMin.z, + vtMax.x, vtMax.y, vtMax.z, + ms_vtPickRayOrig, ms_vtPickRayDir, + &u, &v, &t)) + { + return ret; + } + + return true; + +/* + TBoundBox* boundBoxs = s_boundBoxPool.base(); + for (int i = 0; i < s_boundBoxPool.size(); ++i) + { + TBoundBox& rcurBoundBox=boundBoxs[i]; + + if (!IntersectBoundBox(c_pMatrix, rcurBoundBox, &u, &v, &t)) + continue; + + granny_matrix_4x4* pgrnMatCompositeBuffer = GrannyGetWorldPoseComposite4x4Array(m_pgrnWorldPose); + const CGrannyMesh* c_pMesh = m_pModel->GetMeshPointer(rcurBoundBox.meshIndex); + const granny_mesh* c_pgrnMesh = c_pMesh->GetGrannyMeshPointer(); + + if (!GrannyMeshIsRigid(c_pgrnMesh)) + { + //continue; + ret = true; + } + else + { + D3DXMATRIX matMesh; + int* toBoneIndices = c_pMesh->GetBoneIndices(); + D3DXMatrixMultiply(&matMesh, (D3DXMATRIX*) pgrnMatCompositeBuffer[toBoneIndices[0]], c_pMatrix); + + granny_tri_material_group* pgrnTriGroups = GrannyGetMeshTriangleGroups(c_pgrnMesh); + int mtrlCount = c_pMesh->GetGrannyMeshPointer()->MaterialBindingCount; + int vtxCount = GrannyGetMeshVertexCount(c_pgrnMesh); + int groupCount = GrannyGetMeshTriangleGroupCount(c_pgrnMesh); + + TIndex* modelIndices; + TPNTVertex* modelVertices; + + if (m_pModel->LockVertices((void**)&modelIndices, (void**)&modelVertices)) + { + TIndex* meshIndices = modelIndices + c_pMesh->GetIndexBasePosition(); + TPNTVertex* meshVertices = modelVertices + c_pMesh->GetVertexBasePosition(); + + for (int i = 0; i < groupCount; ++i) + { + granny_tri_material_group& rgrnTriGroup = pgrnTriGroups[i]; + + if (rgrnTriGroup.MaterialIndex < 0 || rgrnTriGroup.MaterialIndex >= mtrlCount) + continue; + + if (IntersectMesh(&matMesh, + meshVertices, + sizeof(TPNTVertex), + vtxCount, + meshIndices, + GrannyGetMeshIndexCount(c_pgrnMesh), + ms_vtPickRayOrig, + ms_vtPickRayDir, + &u, &v, &t)) + { + ret = true; + break; + } + } + + m_pModel->UnlockVertices(); + } + } + + if (ret) + { + *pu = u; + *pv = v; + *pt = -t; + + if (c_szModelName) + { + if (!strncmp(c_pgrnMesh->Name, c_szModelName, strlen(c_szModelName))) + return ret; + + ret = false; + continue; + } + + return ret; + } + } + + return (ret); +*/ +} + +#include "../EterBase/Timer.h" + +void CGrannyModelInstance::GetBoundBox(D3DXVECTOR3* vtMin, D3DXVECTOR3* vtMax) +{ + if (!m_pgrnModelInstance) + return; + + TBoundBox BoundBox; + + vtMin->x = vtMin->y = vtMin->z = +100000.0f; + vtMax->x = vtMax->y = vtMax->z = -100000.0f; + + int meshCount = m_pModel->GetMeshCount(); + for (int m = 0; m < meshCount; ++m) + { + //const CGrannyMesh* pMesh = m_pModel->GetMeshPointer(m); + const granny_mesh* pgrnMesh = m_pModel->GetGrannyModelPointer()->MeshBindings[m].Mesh; + + // WORK + int* boneIndices = __GetMeshBoneIndices(m); + // END_OF_WORK + for (int b = 0; b < pgrnMesh->BoneBindingCount; ++b) + { + const granny_bone_binding& rgrnBoneBinding = pgrnMesh->BoneBindings[b]; + + MakeBoundBox(&BoundBox, + GrannyGetWorldPose4x4(__GetWorldPosePtr(), boneIndices[b]), + rgrnBoneBinding.OBBMin, rgrnBoneBinding.OBBMax, vtMin, vtMax); + } + } +} + +bool CGrannyModelInstance::GetMeshMatrixPointer(int iMesh, const D3DXMATRIX ** c_ppMatrix) const +{ + if (!m_pgrnModelInstance) + return false; + + int meshCount = m_pModel->GetMeshCount(); + + if (meshCount <= 0) + return false; + + // WORK + //const CGrannyMesh * pMesh = m_pModel->GetMeshPointer(iMesh); + *c_ppMatrix = (D3DXMATRIX *)GrannyGetWorldPose4x4(__GetWorldPosePtr(), __GetMeshBoneIndices(iMesh)[0]); + // END_OF_WORK + + return true; +} + +/* +void CGraphicThingInstance::DrawBoundBox() +{ + if (!mc_pMeshVector) + return; + + if (!m_pgrnWorldPose) + return; + + D3DXVECTOR3 vtMin; + D3DXVECTOR3 vtMax; + + SetDiffuseColor(0.0f, 1.0f, 0.0f); + // ij ٿ ڽ + //GetBoundBox(&vtMin, &vtMax); + //DrawLineCube(vtMin.x, vtMin.y, vtMin.z, vtMax.x, vtMax.y, vtMax.z); + //const CThing::TMeshVector& rmeshVector=mc_pModel->meshVector; + ms_lpd3dMatStack->LoadMatrix(&m_Matrix); + + for (size_t m=0; msize(); ++m) + { + const CThing::TMesh& rmesh=mc_pMeshVector->at(m); + + for (int b=0; bBoneBindingCount; ++b) + { + granny_bone_binding& rgrnBoneBinding=rmesh.pgrnMesh->BoneBindings[b]; + + int* toBoneIndices=GrannyGetMeshBindingToBoneIndices(rmesh.pgrnMeshBinding); + + D3DXMATRIX* pmat=(D3DXMATRIX*)GrannyGetWorldPose4x4(m_pgrnWorldPose, toBoneIndices[b]); + + D3DXVec3TransformCoord(&vtMin, &D3DXVECTOR3(rgrnBoneBinding.OBBMin), pmat); + D3DXVec3TransformCoord(&vtMax, &D3DXVECTOR3(rgrnBoneBinding.OBBMax), pmat); + + DrawLineCube(vtMin.x, vtMin.y, vtMin.z, vtMax.x, vtMax.y, vtMax.z); + } + } +} +*/ diff --git a/source/EterGrnLib/ModelInstanceModel.cpp b/source/EterGrnLib/ModelInstanceModel.cpp new file mode 100644 index 0000000..d7f25d5 --- /dev/null +++ b/source/EterGrnLib/ModelInstanceModel.cpp @@ -0,0 +1,300 @@ +#include "StdAfx.h" +#include "ModelInstance.h" +#include "Model.h" + +void CGrannyModelInstance::Clear() +{ + m_kMtrlPal.Clear(); + + DestroyDeviceObjects(); + // WORK + __DestroyMeshBindingVector(); + // END_OF_WORK + __DestroyMeshMatrices(); + __DestroyModelInstance(); + __DestroyWorldPose(); + + __Initialize(); +} + +void CGrannyModelInstance::SetMainModelPointer(CGrannyModel* pModel, CGraphicVertexBuffer* pkSharedDeformableVertexBuffer) +{ + SetLinkedModelPointer(pModel, pkSharedDeformableVertexBuffer, NULL); +} + +void CGrannyModelInstance::SetLinkedModelPointer(CGrannyModel* pkModel, CGraphicVertexBuffer* pkSharedDeformableVertexBuffer, CGrannyModelInstance** ppkSkeletonInst) +{ + Clear(); + + if (m_pModel) + m_pModel->Release(); + + m_pModel = pkModel; + + m_pModel->AddReference(); + + if (pkSharedDeformableVertexBuffer) + __SetSharedDeformableVertexBuffer(pkSharedDeformableVertexBuffer); + else + __CreateDynamicVertexBuffer(); + + __CreateModelInstance(); + + // WORK + if (ppkSkeletonInst && *ppkSkeletonInst) + { + m_ppkSkeletonInst = ppkSkeletonInst; + __CreateWorldPose(*ppkSkeletonInst); + __CreateMeshBindingVector(*ppkSkeletonInst); + } + else + { + __CreateWorldPose(NULL); + __CreateMeshBindingVector(NULL); + } + // END_OF_WORK + + __CreateMeshMatrices(); + + ResetLocalTime(); + + m_kMtrlPal.Copy(pkModel->GetMaterialPalette()); +} + +// WORK +granny_world_pose* CGrannyModelInstance::__GetWorldPosePtr() const +{ + if (m_pgrnWorldPoseReal) + return m_pgrnWorldPoseReal; + + if (m_ppkSkeletonInst && *m_ppkSkeletonInst) + return (*m_ppkSkeletonInst)->m_pgrnWorldPoseReal; + + assert(m_ppkSkeletonInst!=NULL && "__GetWorldPosePtr - NO HAVE SKELETON"); + return NULL; +} + +int* CGrannyModelInstance::__GetMeshBoneIndices(unsigned int iMeshBinding) const +{ + assert(iMeshBindingGetGrannyModelPointer(); + if (!pgrnModel) + return false; + + granny_skeleton* pgrnDstSkeleton = pgrnModel->Skeleton; + if (pkDstModelInst && pkDstModelInst->m_pModel && pkDstModelInst->m_pModel->GetGrannyModelPointer()) + pgrnDstSkeleton = pkDstModelInst->m_pModel->GetGrannyModelPointer()->Skeleton; + + m_vct_pgrnMeshBinding.reserve(pgrnModel->MeshBindingCount); + + granny_int32 iMeshBinding; + for (iMeshBinding = 0; iMeshBinding != pgrnModel->MeshBindingCount; ++iMeshBinding) + m_vct_pgrnMeshBinding.push_back(GrannyNewMeshBinding(pgrnModel->MeshBindings[iMeshBinding].Mesh, pgrnModel->Skeleton, pgrnDstSkeleton)); + + return true; +} + +void CGrannyModelInstance::__DestroyMeshBindingVector() +{ + std::for_each(m_vct_pgrnMeshBinding.begin(), m_vct_pgrnMeshBinding.end(), GrannyFreeMeshBinding); + m_vct_pgrnMeshBinding.clear(); +} + +// END_OF_WORK + + +void CGrannyModelInstance::__CreateWorldPose(CGrannyModelInstance* pkSkeletonInst) +{ + assert(m_pgrnModelInstance != NULL); + assert(m_pgrnWorldPoseReal == NULL); + + // WORK + if (pkSkeletonInst) + return; + // END_OF_WORK + + granny_skeleton * pgrnSkeleton = GrannyGetSourceSkeleton(m_pgrnModelInstance); + + // WORK + m_pgrnWorldPoseReal = GrannyNewWorldPose(pgrnSkeleton->BoneCount); + // END_OF_WORK +} + +void CGrannyModelInstance::__DestroyWorldPose() +{ + if (!m_pgrnWorldPoseReal) + return; + + GrannyFreeWorldPose(m_pgrnWorldPoseReal); + m_pgrnWorldPoseReal = NULL; +} + +void CGrannyModelInstance::__CreateModelInstance() +{ + assert(m_pModel != NULL); + assert(m_pgrnModelInstance == NULL); + + const granny_model * pgrnModel = m_pModel->GetGrannyModelPointer(); + m_pgrnModelInstance = GrannyInstantiateModel(pgrnModel); +} + +void CGrannyModelInstance::__DestroyModelInstance() +{ + if (!m_pgrnModelInstance) + return; + + GrannyFreeModelInstance(m_pgrnModelInstance); + m_pgrnModelInstance = NULL; +} + +void CGrannyModelInstance::__CreateMeshMatrices() +{ + assert(m_pModel != NULL); + + if (m_pModel->GetMeshCount() <= 0) // ޽ (ī޶ ) 𵨵 Ȥ ִ.. + return; + + int meshCount = m_pModel->GetMeshCount(); + m_meshMatrices = new D3DXMATRIX[meshCount]; +} + +void CGrannyModelInstance::__DestroyMeshMatrices() +{ + if (!m_meshMatrices) + return; + + delete [] m_meshMatrices; + m_meshMatrices = NULL; +} + +DWORD CGrannyModelInstance::GetDeformableVertexCount() +{ + if (!m_pModel) + return 0; + + return m_pModel->GetDeformVertexCount(); +} + +DWORD CGrannyModelInstance::GetVertexCount() +{ + if (!m_pModel) + return 0; + + return m_pModel->GetVertexCount(); +} + +// WORK + +void CGrannyModelInstance::__SetSharedDeformableVertexBuffer(CGraphicVertexBuffer* pkSharedDeformableVertexBuffer) +{ + m_pkSharedDeformableVertexBuffer = pkSharedDeformableVertexBuffer; +} + +bool CGrannyModelInstance::__IsDeformableVertexBuffer() +{ + if (m_pkSharedDeformableVertexBuffer) + return true; + + return m_kLocalDeformableVertexBuffer.IsEmpty(); +} + +IDirect3DVertexBuffer8* CGrannyModelInstance::__GetDeformableD3DVertexBufferPtr() +{ + return __GetDeformableVertexBufferRef().GetD3DVertexBuffer(); +} + +CGraphicVertexBuffer& CGrannyModelInstance::__GetDeformableVertexBufferRef() +{ + if (m_pkSharedDeformableVertexBuffer) + return *m_pkSharedDeformableVertexBuffer; + + return m_kLocalDeformableVertexBuffer; +} + +void CGrannyModelInstance::__CreateDynamicVertexBuffer() +{ + assert(m_pModel != NULL); + assert(m_kLocalDeformableVertexBuffer.IsEmpty()); + + int vtxCount = m_pModel->GetDeformVertexCount(); + + if (0 != vtxCount) + { + if (!m_kLocalDeformableVertexBuffer.Create(vtxCount, + D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1, + //D3DUSAGE_DYNAMIC, D3DPOOL_SYSTEMMEM + + D3DUSAGE_WRITEONLY, D3DPOOL_MANAGED + )) + return; + } +} + +void CGrannyModelInstance::__DestroyDynamicVertexBuffer() +{ + m_kLocalDeformableVertexBuffer.Destroy(); + m_pkSharedDeformableVertexBuffer = NULL; +} + +// END_OF_WORK + +bool CGrannyModelInstance::GetBoneIndexByName(const char * c_szBoneName, int * pBoneIndex) const +{ + assert(m_pgrnModelInstance != NULL); + + granny_skeleton * pgrnSkeleton = GrannyGetSourceSkeleton(m_pgrnModelInstance); + + if (!GrannyFindBoneByName(pgrnSkeleton, c_szBoneName, pBoneIndex)) + return false; + + return true; +} + +const float * CGrannyModelInstance::GetBoneMatrixPointer(int iBone) const +{ + const float* bones = GrannyGetWorldPose4x4(__GetWorldPosePtr(), iBone); + if (!bones) + { + granny_model* pModel = m_pModel->GetGrannyModelPointer(); + //TraceError("GrannyModelInstance(%s).GetBoneMatrixPointer(boneIndex(%d)).NOT_FOUND_BONE", pModel->Name, iBone); + return NULL; + } + return bones; +} + +const float * CGrannyModelInstance::GetCompositeBoneMatrixPointer(int iBone) const +{ + // NOTE : GrannyGetWorldPose4x4 ߸ .. ׷ϰ ӵ + // GrannyGetWorldPose4x4 matrix Ҹ + return GrannyGetWorldPoseComposite4x4(__GetWorldPosePtr(), iBone); +} + +void CGrannyModelInstance::ReloadTexture() +{ + assert(" - CGrannyModelInstance::ReloadTexture()"); +/* + assert(m_pModel != NULL); + const CGrannyMaterialPalette & c_rGrannyMaterialPalette = m_pModel->GetMaterialPalette(); + DWORD dwMaterialCount = c_rGrannyMaterialPalette.GetMaterialCount(); + for (DWORD dwMtrIndex = 0; dwMtrIndex < dwMaterialCount; ++dwMtrIndex) + { + const CGrannyMaterial & c_rGrannyMaterial = c_rGrannyMaterialPalette.GetMaterialRef(dwMtrIndex); + CGraphicImage * pImageStage0 = c_rGrannyMaterial.GetImagePointer(0); + if (pImageStage0) + pImageStage0->Reload(); + CGraphicImage * pImageStage1 = c_rGrannyMaterial.GetImagePointer(1); + if (pImageStage1) + pImageStage1->Reload(); + } +*/ +} \ No newline at end of file diff --git a/source/EterGrnLib/ModelInstanceMotion.cpp b/source/EterGrnLib/ModelInstanceMotion.cpp new file mode 100644 index 0000000..3c19e88 --- /dev/null +++ b/source/EterGrnLib/ModelInstanceMotion.cpp @@ -0,0 +1,148 @@ +#include "StdAfx.h" +#include "ModelInstance.h" +#include "Model.h" + +void CGrannyModelInstance::CopyMotion(CGrannyModelInstance * pModelInstance, bool bIsFreeSourceControl) +{ + if (!pModelInstance->IsMotionPlaying()) + return; + + if (m_pgrnCtrl) + GrannyFreeControl(m_pgrnCtrl); + + float localTime = GetLocalTime(); + m_pgrnAni = pModelInstance->m_pgrnAni; + m_pgrnCtrl = GrannyPlayControlledAnimation(localTime, m_pgrnAni, m_pgrnModelInstance); + + if (!m_pgrnCtrl) + return; + + GrannySetControlSpeed(m_pgrnCtrl, GrannyGetControlSpeed(pModelInstance->m_pgrnCtrl)); + GrannySetControlLoopCount(m_pgrnCtrl, GrannyGetControlLoopCount(pModelInstance->m_pgrnCtrl)); + + GrannySetControlEaseIn(m_pgrnCtrl, true); + GrannySetControlEaseOut(m_pgrnCtrl, false); + + GrannySetControlRawLocalClock(m_pgrnCtrl, GrannyGetControlRawLocalClock(pModelInstance->m_pgrnCtrl)); + + GrannyFreeControlOnceUnused(m_pgrnCtrl); + + if (bIsFreeSourceControl) + { + GrannyFreeControl(pModelInstance->m_pgrnCtrl); + pModelInstance->m_pgrnCtrl = NULL; + } +} + +bool CGrannyModelInstance::IsMotionPlaying() +{ + if (!m_pgrnCtrl) + return false; + + if (GrannyControlIsComplete(m_pgrnCtrl)) + return false; + + return true; +} + +void CGrannyModelInstance::SetMotionPointer(const CGrannyMotion * pMotion, float blendTime, int loopCount, float speedRatio) +{ + // TEST + if (!m_pgrnWorldPoseReal) + return; + // END_OF_TEST + + granny_model_instance * pgrnModelInstance = m_pgrnModelInstance; + if (!pgrnModelInstance) + return; + + float localTime = GetLocalTime(); + + bool isFirst=false; + if (m_pgrnCtrl) + { + //float durationLeft = GrannyGetControlDurationLeft(m_pgrnCtrl); + //float easeOutTime = (blendTime < durationLeft) ? blendTime : durationLeft; + //float oldCtrlFinishTime = GrannyEaseControlOut(m_pgrnCtrl, blendTime); //easeOutTime); + GrannySetControlEaseOutCurve(m_pgrnCtrl, localTime, localTime + blendTime, 1.0f, 1.0f, 0.0f, 0.0f); + + GrannySetControlEaseIn(m_pgrnCtrl, false); + GrannySetControlEaseOut(m_pgrnCtrl, true); + + //Tracef("easeOut %f\n", easeOutTime); + GrannyCompleteControlAt(m_pgrnCtrl, localTime + blendTime); + //GrannyCompleteControlAt(m_pgrnCtrl, oldCtrlFinishTime); + //GrannyCompleteControlAt(m_pgrnCtrl, localTime); + GrannyFreeControlIfComplete(m_pgrnCtrl); + } + else + { + isFirst=true; + } + + m_pgrnAni = pMotion->GetGrannyAnimationPointer(); + m_pgrnCtrl = GrannyPlayControlledAnimation(localTime, m_pgrnAni, pgrnModelInstance); + if (!m_pgrnCtrl) + return; + + GrannySetControlSpeed(m_pgrnCtrl, speedRatio); + GrannySetControlLoopCount(m_pgrnCtrl, loopCount); + + if (isFirst) + { + GrannySetControlEaseIn(m_pgrnCtrl, false); + GrannySetControlEaseOut(m_pgrnCtrl, false); + } + else + { + GrannySetControlEaseIn(m_pgrnCtrl, true); + GrannySetControlEaseOut(m_pgrnCtrl, false); + if (blendTime > 0.0f) + GrannySetControlEaseInCurve(m_pgrnCtrl, localTime, localTime + blendTime, 0.0f, 0.0f, 1.0f, 1.0f); + } + + //GrannyEaseControlIn(m_pgrnCtrl, blendTime, false); + GrannyFreeControlOnceUnused(m_pgrnCtrl); + //Tracef("easeIn %f\n", blendTime); +} + +void CGrannyModelInstance::ChangeMotionPointer(const CGrannyMotion* pMotion, int loopCount, float speedRatio) +{ + granny_model_instance * pgrnModelInstance = m_pgrnModelInstance; + if (!pgrnModelInstance) + return; + + // Ǵ պκ ŵ ϱ LocalTime Ѵ. - [levites] + float fSkipTime = 0.3f; + float localTime = GetLocalTime() - fSkipTime; + + if (m_pgrnCtrl) + { + GrannySetControlEaseIn(m_pgrnCtrl, false); + GrannySetControlEaseOut(m_pgrnCtrl, false); + GrannyCompleteControlAt(m_pgrnCtrl, localTime); + GrannyFreeControlIfComplete(m_pgrnCtrl); + } + + m_pgrnAni = pMotion->GetGrannyAnimationPointer(); + m_pgrnCtrl = GrannyPlayControlledAnimation(localTime, m_pgrnAni, pgrnModelInstance); + if (!m_pgrnCtrl) + return; + + GrannySetControlSpeed(m_pgrnCtrl, speedRatio); + GrannySetControlLoopCount(m_pgrnCtrl, loopCount); + GrannySetControlEaseIn(m_pgrnCtrl, false); + GrannySetControlEaseOut(m_pgrnCtrl, false); + + GrannyFreeControlOnceUnused(m_pgrnCtrl); +} + +void CGrannyModelInstance::SetMotionAtEnd() +{ + if (!m_pgrnCtrl) + return; + + //Tracef("%f\n", endingTime); + float endingTime = GrannyGetControlLocalDuration(m_pgrnCtrl); + GrannySetControlRawLocalClock(m_pgrnCtrl, endingTime); +} diff --git a/source/EterGrnLib/ModelInstanceRender.cpp b/source/EterGrnLib/ModelInstanceRender.cpp new file mode 100644 index 0000000..33fcdde --- /dev/null +++ b/source/EterGrnLib/ModelInstanceRender.cpp @@ -0,0 +1,407 @@ +#include "StdAfx.h" +#include "../eterlib/StateManager.h" +#include "ModelInstance.h" +#include "Model.h" + +#ifdef _TEST + +#include "../eterlib/GrpScreen.h" + +void Granny_RenderBoxBones(const granny_skeleton* pkGrnSkeleton, const granny_world_pose* pkGrnWorldPose, const D3DXMATRIX& matBase) +{ + D3DXMATRIX matWorld; + CScreen screen; + for (int iBone = 0; iBone != pkGrnSkeleton->BoneCount; ++iBone) + { + const granny_bone& rkGrnBone = pkGrnSkeleton->Bones[iBone]; + const D3DXMATRIX* c_matBone=(const D3DXMATRIX*)GrannyGetWorldPose4x4(pkGrnWorldPose, iBone); + + D3DXMatrixMultiply(&matWorld, c_matBone, &matBase); + + STATEMANAGER.SetTransform(D3DTS_WORLD, &matWorld); + screen.RenderBox3d(-5.0f, -5.0f, -5.0f, 5.0f, 5.0f, 5.0f); + } +} + +#endif + + +void CGrannyModelInstance::DeformNoSkin(const D3DXMATRIX * c_pWorldMatrix) +{ + if (IsEmpty()) + return; + + // DELETED + //m_pgrnWorldPose = m_pgrnWorldPoseReal; + /////////////////////////////// + + UpdateWorldPose(); + UpdateWorldMatrices(c_pWorldMatrix); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +//// Render +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +// With One Texture +void CGrannyModelInstance::RenderWithOneTexture() +{ + // FIXME : Deform, Render, BlendRender ɷִ - [levites] + if (IsEmpty()) + return; + +#ifdef _TEST + Granny_RenderBoxBones(GrannyGetSourceSkeleton(m_pgrnModelInstance), m_pgrnWorldPose, TEST_matWorld); + if (GetAsyncKeyState('P')) + Tracef("render %x", m_pgrnModelInstance); + return; +#endif + + STATEMANAGER.SetVertexShader(ms_pntVS); + + // WORK + LPDIRECT3DVERTEXBUFFER8 lpd3dDeformPNTVtxBuf = __GetDeformableD3DVertexBufferPtr(); + // END_OF_WORK + + LPDIRECT3DVERTEXBUFFER8 lpd3dRigidPNTVtxBuf = m_pModel->GetPNTD3DVertexBuffer(); + + if (lpd3dDeformPNTVtxBuf) + { + STATEMANAGER.SetStreamSource(0, lpd3dDeformPNTVtxBuf, sizeof(TPNTVertex)); + RenderMeshNodeListWithOneTexture(CGrannyMesh::TYPE_DEFORM, CGrannyMaterial::TYPE_DIFFUSE_PNT); + } + if (lpd3dRigidPNTVtxBuf) + { + STATEMANAGER.SetStreamSource(0, lpd3dRigidPNTVtxBuf, sizeof(TPNTVertex)); + RenderMeshNodeListWithOneTexture(CGrannyMesh::TYPE_RIGID, CGrannyMaterial::TYPE_DIFFUSE_PNT); + } +} + +void CGrannyModelInstance::BlendRenderWithOneTexture() +{ + if (IsEmpty()) + return; + + // WORK + LPDIRECT3DVERTEXBUFFER8 lpd3dDeformPNTVtxBuf = __GetDeformableD3DVertexBufferPtr(); + // END_OF_WORK + LPDIRECT3DVERTEXBUFFER8 lpd3dRigidPNTVtxBuf = m_pModel->GetPNTD3DVertexBuffer(); + + STATEMANAGER.SetVertexShader(ms_pntVS); + + if (lpd3dDeformPNTVtxBuf) + { + STATEMANAGER.SetStreamSource(0, lpd3dDeformPNTVtxBuf, sizeof(TPNTVertex)); + RenderMeshNodeListWithOneTexture(CGrannyMesh::TYPE_DEFORM, CGrannyMaterial::TYPE_BLEND_PNT); + } + + if (lpd3dRigidPNTVtxBuf) + { + STATEMANAGER.SetStreamSource(0, lpd3dRigidPNTVtxBuf, sizeof(TPNTVertex)); + RenderMeshNodeListWithOneTexture(CGrannyMesh::TYPE_RIGID, CGrannyMaterial::TYPE_BLEND_PNT); + } +} + +// With Two Texture +void CGrannyModelInstance::RenderWithTwoTexture() +{ + // FIXME : Deform, Render, BlendRender ɷִ - [levites] + if (IsEmpty()) + return; + + STATEMANAGER.SetVertexShader(ms_pntVS); + + // WORK + LPDIRECT3DVERTEXBUFFER8 lpd3dDeformPNTVtxBuf = __GetDeformableD3DVertexBufferPtr(); + // END_OF_WORK + LPDIRECT3DVERTEXBUFFER8 lpd3dRigidPNTVtxBuf = m_pModel->GetPNTD3DVertexBuffer(); + + if (lpd3dDeformPNTVtxBuf) + { + STATEMANAGER.SetStreamSource(0, lpd3dDeformPNTVtxBuf, sizeof(TPNTVertex)); + RenderMeshNodeListWithTwoTexture(CGrannyMesh::TYPE_DEFORM, CGrannyMaterial::TYPE_DIFFUSE_PNT); + } + if (lpd3dRigidPNTVtxBuf) + { + STATEMANAGER.SetStreamSource(0, lpd3dRigidPNTVtxBuf, sizeof(TPNTVertex)); + RenderMeshNodeListWithTwoTexture(CGrannyMesh::TYPE_RIGID, CGrannyMaterial::TYPE_DIFFUSE_PNT); + } +} + +void CGrannyModelInstance::BlendRenderWithTwoTexture() +{ + if (IsEmpty()) + return; + + // WORK + LPDIRECT3DVERTEXBUFFER8 lpd3dDeformPNTVtxBuf = __GetDeformableD3DVertexBufferPtr(); + // END_OF_WORK + LPDIRECT3DVERTEXBUFFER8 lpd3dRigidPNTVtxBuf = m_pModel->GetPNTD3DVertexBuffer(); + + STATEMANAGER.SetVertexShader(ms_pntVS); + + if (lpd3dDeformPNTVtxBuf) + { + STATEMANAGER.SetStreamSource(0, lpd3dDeformPNTVtxBuf, sizeof(TPNTVertex)); + RenderMeshNodeListWithTwoTexture(CGrannyMesh::TYPE_DEFORM, CGrannyMaterial::TYPE_BLEND_PNT); + } + + if (lpd3dRigidPNTVtxBuf) + { + STATEMANAGER.SetStreamSource(0, lpd3dRigidPNTVtxBuf, sizeof(TPNTVertex)); + RenderMeshNodeListWithTwoTexture(CGrannyMesh::TYPE_RIGID, CGrannyMaterial::TYPE_BLEND_PNT); + } +} + +void CGrannyModelInstance::RenderWithoutTexture() +{ + if (IsEmpty()) + return; + + STATEMANAGER.SetVertexShader(ms_pntVS); + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SetTexture(1, NULL); + + // WORK + LPDIRECT3DVERTEXBUFFER8 lpd3dDeformPNTVtxBuf = __GetDeformableD3DVertexBufferPtr(); + // END_OF_WORK + LPDIRECT3DVERTEXBUFFER8 lpd3dRigidPNTVtxBuf = m_pModel->GetPNTD3DVertexBuffer(); + + if (lpd3dDeformPNTVtxBuf) + { + STATEMANAGER.SetStreamSource(0, lpd3dDeformPNTVtxBuf, sizeof(TPNTVertex)); + RenderMeshNodeListWithoutTexture(CGrannyMesh::TYPE_DEFORM, CGrannyMaterial::TYPE_DIFFUSE_PNT); + RenderMeshNodeListWithoutTexture(CGrannyMesh::TYPE_DEFORM, CGrannyMaterial::TYPE_BLEND_PNT); + } + + if (lpd3dRigidPNTVtxBuf) + { + STATEMANAGER.SetStreamSource(0, lpd3dRigidPNTVtxBuf, sizeof(TPNTVertex)); + RenderMeshNodeListWithoutTexture(CGrannyMesh::TYPE_RIGID, CGrannyMaterial::TYPE_DIFFUSE_PNT); + RenderMeshNodeListWithoutTexture(CGrannyMesh::TYPE_RIGID, CGrannyMaterial::TYPE_BLEND_PNT); + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +//// Render Mesh List +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// + +// With One Texture +void CGrannyModelInstance::RenderMeshNodeListWithOneTexture(CGrannyMesh::EType eMeshType, CGrannyMaterial::EType eMtrlType) +{ + assert(m_pModel != NULL); + + LPDIRECT3DINDEXBUFFER8 lpd3dIdxBuf = m_pModel->GetD3DIndexBuffer(); + assert(lpd3dIdxBuf != NULL); + + const CGrannyModel::TMeshNode * pMeshNode = m_pModel->GetMeshNodeList(eMeshType, eMtrlType); + + while (pMeshNode) + { + const CGrannyMesh * pMesh = pMeshNode->pMesh; + int vtxMeshBasePos = pMesh->GetVertexBasePosition(); + + STATEMANAGER.SetIndices(lpd3dIdxBuf, vtxMeshBasePos); + STATEMANAGER.SetTransform(D3DTS_WORLD, &m_meshMatrices[pMeshNode->iMesh]); + + ///// + const CGrannyMesh::TTriGroupNode* pTriGroupNode = pMesh->GetTriGroupNodeList(eMtrlType); + int vtxCount = pMesh->GetVertexCount(); + while (pTriGroupNode) + { + ms_faceCount += pTriGroupNode->triCount; + + CGrannyMaterial& rkMtrl=m_kMtrlPal.GetMaterialRef(pTriGroupNode->mtrlIndex); + rkMtrl.ApplyRenderState(); + STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, vtxCount, pTriGroupNode->idxPos, pTriGroupNode->triCount); + rkMtrl.RestoreRenderState(); + + pTriGroupNode = pTriGroupNode->pNextTriGroupNode; + } + ///// + + pMeshNode = pMeshNode->pNextMeshNode; + } +} + +// With Two Texture +void CGrannyModelInstance::RenderMeshNodeListWithTwoTexture(CGrannyMesh::EType eMeshType, CGrannyMaterial::EType eMtrlType) +{ + assert(m_pModel != NULL); + + LPDIRECT3DINDEXBUFFER8 lpd3dIdxBuf = m_pModel->GetD3DIndexBuffer(); + assert(lpd3dIdxBuf != NULL); + + const CGrannyModel::TMeshNode * pMeshNode = m_pModel->GetMeshNodeList(eMeshType, eMtrlType); + + while (pMeshNode) + { + const CGrannyMesh * pMesh = pMeshNode->pMesh; + int vtxMeshBasePos = pMesh->GetVertexBasePosition(); + + STATEMANAGER.SetIndices(lpd3dIdxBuf, vtxMeshBasePos); + STATEMANAGER.SetTransform(D3DTS_WORLD, &m_meshMatrices[pMeshNode->iMesh]); + + ///// + const CGrannyMesh::TTriGroupNode* pTriGroupNode = pMesh->GetTriGroupNodeList(eMtrlType); + int vtxCount = pMesh->GetVertexCount(); + while (pTriGroupNode) + { + ms_faceCount += pTriGroupNode->triCount; + + const CGrannyMaterial& rkMtrl=m_kMtrlPal.GetMaterialRef(pTriGroupNode->mtrlIndex); + STATEMANAGER.SetTexture(0, rkMtrl.GetD3DTexture(0)); + STATEMANAGER.SetTexture(1, rkMtrl.GetD3DTexture(1)); + STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, vtxCount, pTriGroupNode->idxPos, pTriGroupNode->triCount); + pTriGroupNode = pTriGroupNode->pNextTriGroupNode; + } + ///// + + pMeshNode = pMeshNode->pNextMeshNode; + } +} + +// Without Texture +void CGrannyModelInstance::RenderMeshNodeListWithoutTexture(CGrannyMesh::EType eMeshType, CGrannyMaterial::EType eMtrlType) +{ + assert(m_pModel != NULL); + + LPDIRECT3DINDEXBUFFER8 lpd3dIdxBuf = m_pModel->GetD3DIndexBuffer(); + assert(lpd3dIdxBuf != NULL); + + const CGrannyModel::TMeshNode * pMeshNode = m_pModel->GetMeshNodeList(eMeshType, eMtrlType); + + while (pMeshNode) + { + const CGrannyMesh * pMesh = pMeshNode->pMesh; + int vtxMeshBasePos = pMesh->GetVertexBasePosition(); + + STATEMANAGER.SetIndices(lpd3dIdxBuf, vtxMeshBasePos); + STATEMANAGER.SetTransform(D3DTS_WORLD, &m_meshMatrices[pMeshNode->iMesh]); + + ///// + const CGrannyMesh::TTriGroupNode* pTriGroupNode = pMesh->GetTriGroupNodeList(eMtrlType); + int vtxCount = pMesh->GetVertexCount(); + + while (pTriGroupNode) + { + ms_faceCount += pTriGroupNode->triCount; + STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, vtxCount, pTriGroupNode->idxPos, pTriGroupNode->triCount); + pTriGroupNode = pTriGroupNode->pNextTriGroupNode; + } + ///// + + pMeshNode = pMeshNode->pNextMeshNode; + } +} + +/* +void CGrannyModelInstance::RenderMeshNodeList(CGrannyMesh::EType eMeshType, CGrannyMaterial::EType eMtrlType) +{ + assert(m_pModel != NULL); + + LPDIRECT3DINDEXBUFFER8 lpd3dIdxBuf = m_pModel->GetD3DIndexBuffer(); + assert(lpd3dIdxBuf != NULL); + + const CGrannyModel::TMeshNode * pMeshNode = m_pModel->GetMeshNodeList(eMeshType, eMtrlType); + + while (pMeshNode) + { + const CGrannyMesh * pMesh = pMeshNode->pMesh; + int vtxMeshBasePos = pMesh->GetVertexBasePosition(); + + STATEMANAGER.SetIndices(lpd3dIdxBuf, vtxMeshBasePos); + STATEMANAGER.SetTransform(D3DTS_WORLD, &m_meshMatrices[pMeshNode->iMesh]); + + ///// + const CGrannyMesh::TTriGroupNode* pTriGroupNode = pMesh->GetTriGroupNodeList(eMtrlType); + int vtxCount = pMesh->GetVertexCount(); + while (pTriGroupNode) + { + ms_faceCount += pTriGroupNode->triCount; + STATEMANAGER.SetTexture(0, pTriGroupNode->lpd3dTextures[0]); + + if (pTriGroupNode->lpd3dTextures[1]) + STATEMANAGER.SetTexture(1, pTriGroupNode->lpd3dTextures[1]); + else + { + STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); + STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); + + STATEMANAGER.SetTexture(1, m_FogInstance.GetTexturePointer()->GetD3DTexture()); + + D3DXMATRIX mat; + memset(&mat, 0, sizeof(D3DXMATRIX)); + mat._31 = -0.001f; + mat._41 = -7.0f; + mat._42 = 0.5f; + STATEMANAGER.SetTransform(D3DTS_TEXTURE1, &mat); + } + + STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, vtxCount, pTriGroupNode->idxPos, pTriGroupNode->triCount); + + if (!pTriGroupNode->lpd3dTextures[1]) + { + STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); + STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + + pTriGroupNode = pTriGroupNode->pNextTriGroupNode; + } + ///// + + pMeshNode = pMeshNode->pNextMeshNode; + } +} +void CGrannyModelInstance::RenderToShadowMap() +{ + if (IsEmpty()) + return; + + STATEMANAGER.SetVertexShader(ms_pntVS); + +// LPDIRECT3DVERTEXBUFFER8 lpd3dDynamicPNTVtxBuf = m_dynamicPNTVtxBuf.GetD3DVertexBuffer(); + LPDIRECT3DVERTEXBUFFER8 lpd3dDeformPNTVtxBuf = m_dynamicPNTVtxBuf.GetD3DVertexBuffer(); + LPDIRECT3DVERTEXBUFFER8 lpd3dRigidPNTVtxBuf = m_pModel->GetPNTD3DVertexBuffer(); + +// STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, TRUE); +// STATEMANAGER.SaveRenderState(D3DRS_ALPHAREF, 0); +// STATEMANAGER.SaveRenderState(D3DRS_ALPHAFUNC, D3DCMP_NOTEQUAL); +// +// if (lpd3dDynamicPNTVtxBuf) +// { +// STATEMANAGER.SetStreamSource(0, lpd3dDynamicPNTVtxBuf, sizeof(TPNTVertex)); +// RenderMeshNodeListWithoutTexture(CGrannyMesh::TYPE_DEFORM, CGrannyMaterial::TYPE_BLEND_PNT); +// } +// +// STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE); +// STATEMANAGER.RestoreRenderState(D3DRS_ALPHAREF); +// STATEMANAGER.RestoreRenderState(D3DRS_ALPHAFUNC); + + if (lpd3dDeformPNTVtxBuf) + { + STATEMANAGER.SetStreamSource(0, lpd3dDeformPNTVtxBuf, sizeof(TPNTVertex)); + RenderMeshNodeListWithoutTexture(CGrannyMesh::TYPE_DEFORM, CGrannyMaterial::TYPE_DIFFUSE_PNT); + } + + if (lpd3dRigidPNTVtxBuf) + { + STATEMANAGER.SetStreamSource(0, lpd3dRigidPNTVtxBuf, sizeof(TPNTVertex)); + RenderMeshNodeListWithoutTexture(CGrannyMesh::TYPE_RIGID, CGrannyMaterial::TYPE_DIFFUSE_PNT); + } +} +*/ diff --git a/source/EterGrnLib/ModelInstanceUpdate.cpp b/source/EterGrnLib/ModelInstanceUpdate.cpp new file mode 100644 index 0000000..1fe0037 --- /dev/null +++ b/source/EterGrnLib/ModelInstanceUpdate.cpp @@ -0,0 +1,208 @@ +#include "StdAfx.h" +#include "../eterbase/Debug.h" +#include "ModelInstance.h" +#include "Model.h" + + +void CGrannyModelInstance::Update(DWORD dwAniFPS) +{ + if (!dwAniFPS) + return; + + const DWORD c_dwCurUpdateFrame = (DWORD) (GetLocalTime() * static_cast(ANIFPS_MAX)); + const DWORD ANIFPS_STEP = ANIFPS_MAX/dwAniFPS; + if (c_dwCurUpdateFrame>ANIFPS_STEP && c_dwCurUpdateFrame/ANIFPS_STEP==m_dwOldUpdateFrame/ANIFPS_STEP) + return; + + m_dwOldUpdateFrame=c_dwCurUpdateFrame; + + GrannyFreeCompletedModelControls(m_pgrnModelInstance); //Black screen fix + + //DWORD t1=timeGetTime(); + GrannySetModelClock(m_pgrnModelInstance, GetLocalTime()); + //DWORD t2=timeGetTime(); + +#ifdef __PERFORMANCE_CHECKER__ + { + static FILE* fp=fopen("perf_grn_setmodelclock.txt", "w"); + + if (t2-t1>3) + { + fprintf(fp, "%f:%x:- GrannySetModelClock(time=%f) = %dms\n", timeGetTime()/1000.0f, this, GetLocalTime(), t2-t1); + fflush(fp); + } + } +#endif + +} + +void CGrannyModelInstance::UpdateLocalTime(float fElapsedTime) +{ + m_fSecondsElapsed = fElapsedTime; + m_fLocalTime += fElapsedTime; +} + +void CGrannyModelInstance::UpdateTransform(D3DXMATRIX * pMatrix, float fSecondsElapsed) +{ + if (!m_pgrnModelInstance) + { + TraceError("CGrannyModelIstance::UpdateTransform - m_pgrnModelInstance = NULL"); + return; + } + GrannyUpdateModelMatrix(m_pgrnModelInstance, fSecondsElapsed, (const float *) pMatrix, (float *) pMatrix, false); + //Tracef("%f %f %f",pMatrix->_41,pMatrix->_42,pMatrix->_43); + +} + +void CGrannyModelInstance::Deform(const D3DXMATRIX * c_pWorldMatrix) +{ + if (IsEmpty()) + return; + + // DELETED + //m_pgrnWorldPose = m_pgrnWorldPoseReal; + ///////////////////////////////////////////// + + UpdateWorldPose(); + UpdateWorldMatrices(c_pWorldMatrix); + + if (m_pModel->CanDeformPNTVertices()) + { + // WORK + CGraphicVertexBuffer& rkDeformableVertexBuffer = __GetDeformableVertexBufferRef(); + TPNTVertex* pntVertices; + if (rkDeformableVertexBuffer.LockRange(m_pModel->GetDeformVertexCount(), (void **)&pntVertices)) + { + DeformPNTVertices(pntVertices); + rkDeformableVertexBuffer.Unlock(); + } + else + { + TraceError("GRANNY DEFORM DYNAMIC BUFFER LOCK ERROR"); + } + // END_OF_WORK + } +} + +////////////////////////////////////////////////////// +class CGrannyLocalPose +{ + public: + CGrannyLocalPose() + { + m_pgrnLocalPose = NULL; + m_boneCount = 0; + } + + virtual ~CGrannyLocalPose() + { + if (m_pgrnLocalPose) + GrannyFreeLocalPose(m_pgrnLocalPose); + } + + granny_local_pose * Get(int boneCount) + { + if (m_pgrnLocalPose) + { + if (m_boneCount >= boneCount) + return m_pgrnLocalPose; + + GrannyFreeLocalPose(m_pgrnLocalPose); + } + + m_boneCount = boneCount; + m_pgrnLocalPose = GrannyNewLocalPose(m_boneCount); + return m_pgrnLocalPose; + } + + private: + granny_local_pose * m_pgrnLocalPose; + int m_boneCount; +}; +////////////////////////////////////////////////////// + +void CGrannyModelInstance::UpdateSkeleton(const D3DXMATRIX * c_pWorldMatrix, float /*fLocalTime*/) +{ + // DELETED + //m_pgrnWorldPose = m_pgrnWorldPoseReal; + /////////////////////////////////////////// + UpdateWorldPose(); + UpdateWorldMatrices(c_pWorldMatrix); +} + +void CGrannyModelInstance::UpdateWorldPose() +{ + // WEP = m_iParentBoneIndex != 0 -> UpdateWorldPose(O) + // LOD = UpdateWorldPose(O) + // Hair = UpdateWorldPose(X) + + if (m_ppkSkeletonInst) + if (*m_ppkSkeletonInst!=this) + return; + + static CGrannyLocalPose s_SharedLocalPose; + + granny_skeleton * pgrnSkeleton = GrannyGetSourceSkeleton(m_pgrnModelInstance); + granny_local_pose * pgrnLocalPose = s_SharedLocalPose.Get(pgrnSkeleton->BoneCount); + + const float * pAttachBoneMatrix = (mc_pParentInstance) ? mc_pParentInstance->GetBoneMatrixPointer(m_iParentBoneIndex) : NULL; + + GrannySampleModelAnimationsAccelerated(m_pgrnModelInstance, pgrnSkeleton->BoneCount, pAttachBoneMatrix, pgrnLocalPose, __GetWorldPosePtr()); + /* + GrannySampleModelAnimations(m_pgrnModelInstance, 0, pgrnSkeleton->BoneCount, pgrnLocalPose); + GrannyBuildWorldPose(pgrnSkeleton, 0, pgrnSkeleton->BoneCount, pgrnLocalPose, pAttachBoneMatrix, m_pgrnWorldPose); + */ + GrannyFreeCompletedModelControls(m_pgrnModelInstance); + +} + +void CGrannyModelInstance::UpdateWorldMatrices(const D3DXMATRIX* c_pWorldMatrix) +{ + // NO_MESH_BUG_FIX + if (!m_meshMatrices) + return; + // END_OF_NO_MESH_BUG_FIX + + assert(m_pModel != NULL); + assert(ms_lpd3dMatStack != NULL); + + int meshCount = m_pModel->GetMeshCount(); + + granny_matrix_4x4 * pgrnMatCompositeBuffer = GrannyGetWorldPoseComposite4x4Array(__GetWorldPosePtr()); + D3DXMATRIX * boneMatrices = (D3DXMATRIX *) pgrnMatCompositeBuffer; + + for (int i = 0; i < meshCount; ++i) + { + D3DXMATRIX & rWorldMatrix = m_meshMatrices[i]; + + const CGrannyMesh * pMesh = m_pModel->GetMeshPointer(i); + + // WORK + int * boneIndices = __GetMeshBoneIndices(i); + // END_OF_WORK + + if (pMesh->CanDeformPNTVertices()) + { + rWorldMatrix = *c_pWorldMatrix; + } + else + { + int iBone = *boneIndices; + D3DXMatrixMultiply(&rWorldMatrix, &boneMatrices[iBone], c_pWorldMatrix); + } + } + +#ifdef _TEST + TEST_matWorld = *c_pWorldMatrix; +#endif +} + +void CGrannyModelInstance::DeformPNTVertices(void * pvDest) +{ + assert(m_pModel != NULL); + assert(m_pModel->CanDeformPNTVertices()); + + // WORK + m_pModel->DeformPNTVertices(pvDest, (D3DXMATRIX *) GrannyGetWorldPoseComposite4x4Array(__GetWorldPosePtr()), m_vct_pgrnMeshBinding); + // END_OF_WORK +} diff --git a/source/EterGrnLib/Motion.cpp b/source/EterGrnLib/Motion.cpp new file mode 100644 index 0000000..02a5f9e --- /dev/null +++ b/source/EterGrnLib/Motion.cpp @@ -0,0 +1,70 @@ +#include "StdAfx.h" +#include "Motion.h" + +CGrannyMotion::CGrannyMotion() +{ + Initialize(); +} + +CGrannyMotion::~CGrannyMotion() +{ + Destroy(); +} + +bool CGrannyMotion::IsEmpty() +{ + return m_pgrnAni ? false : true; +} + +void CGrannyMotion::Destroy() +{ + Initialize(); +} + +void CGrannyMotion::Initialize() +{ + m_pgrnAni = NULL; +} + +bool CGrannyMotion::BindGrannyAnimation(granny_animation * pgrnAni) +{ + assert(IsEmpty()); + + m_pgrnAni = pgrnAni; + return true; +} + +granny_animation* CGrannyMotion::GetGrannyAnimationPointer() const +{ + return m_pgrnAni; +} + +const char * CGrannyMotion::GetName() const +{ + return m_pgrnAni->Name; +} + +float CGrannyMotion::GetDuration() const +{ + return m_pgrnAni->Duration; +} + +void CGrannyMotion::GetTextTrack(const char * c_szTextTrackName, int * pCount, float * pArray) const +{ + if (m_pgrnAni->TrackGroupCount != 1) + { +// assert(!"CGrannyMotion::GetTextTrack - TrackCount is not 1"); + } + + granny_track_group * pTrack = m_pgrnAni->TrackGroups[0]; + + for (int i = 0; i < pTrack->TextTrackCount; ++i) + { + granny_text_track & rTextTrack = pTrack->TextTracks[i]; + + for (int j = 0; j < rTextTrack.EntryCount; ++j) + if (!_stricmp(c_szTextTrackName, rTextTrack.Entries[j].Text)) + pArray[(*pCount)++] = rTextTrack.Entries[j].TimeStamp; + } +} + diff --git a/source/EterGrnLib/Motion.h b/source/EterGrnLib/Motion.h new file mode 100644 index 0000000..cf3031f --- /dev/null +++ b/source/EterGrnLib/Motion.h @@ -0,0 +1,25 @@ +#pragma once + +class CGrannyMotion +{ + public: + CGrannyMotion(); + virtual ~CGrannyMotion(); + + bool IsEmpty(); + + void Destroy(); + bool BindGrannyAnimation(granny_animation* pgrnAni); + + granny_animation * GetGrannyAnimationPointer() const; + + const char * GetName() const; + float GetDuration() const; + void GetTextTrack(const char * c_szTextTrackName, int * pCount, float * pArray) const; + + protected: + void Initialize(); + + protected: + granny_animation * m_pgrnAni; +}; diff --git a/source/EterGrnLib/StdAfx.cpp b/source/EterGrnLib/StdAfx.cpp new file mode 100644 index 0000000..804d088 --- /dev/null +++ b/source/EterGrnLib/StdAfx.cpp @@ -0,0 +1,2 @@ +#include "stdafx.h" + diff --git a/source/EterGrnLib/StdAfx.h b/source/EterGrnLib/StdAfx.h new file mode 100644 index 0000000..0a6c3da --- /dev/null +++ b/source/EterGrnLib/StdAfx.h @@ -0,0 +1,23 @@ +#pragma once + +#pragma warning(disable:4786) // character 255 Ѿ° + +//#include +#include + +#include "../eterBase/Utils.h" +#include "../eterBase/Debug.h" +#include "../eterBase/Stl.h" + +#include "Util.h" + +// Armadillo nanomite protection +#ifndef NANOBEGIN + #ifdef __BORLANDC__ + #define NANOBEGIN __emit__ (0xEB,0x03,0xD6,0xD7,0x01) + #define NANOEND __emit__ (0xEB,0x03,0xD6,0xD7,0x00) + #else + #define NANOBEGIN __asm _emit 0xEB __asm _emit 0x03 __asm _emit 0xD6 __asm _emit 0xD7 __asm _emit 0x01 + #define NANOEND __asm _emit 0xEB __asm _emit 0x03 __asm _emit 0xD6 __asm _emit 0xD7 __asm _emit 0x00 + #endif +#endif diff --git a/source/EterGrnLib/Thing.cpp b/source/EterGrnLib/Thing.cpp new file mode 100644 index 0000000..6fd5335 --- /dev/null +++ b/source/EterGrnLib/Thing.cpp @@ -0,0 +1,242 @@ +#include "StdAfx.h" +#include "../eterbase/Debug.h" +#include "Thing.h" +#include "ThingInstance.h" + +CGraphicThing::CGraphicThing(const char* c_szFileName) : CResource(c_szFileName) +{ + Initialize(); +} + +CGraphicThing::~CGraphicThing() +{ + //OnClear(); + Clear(); +} + +void CGraphicThing::Initialize() +{ + m_pgrnFile = NULL; + m_pgrnFileInfo = NULL; + m_pgrnAni = NULL; + + m_models = NULL; + m_motions = NULL; +} + +void CGraphicThing::OnClear() +{ + if (m_motions) + delete [] m_motions; + + if (m_models) + delete [] m_models; + + if (m_pgrnFile) + GrannyFreeFile(m_pgrnFile); + + Initialize(); +} + +CGraphicThing::TType CGraphicThing::Type() +{ + static TType s_type = StringToType("CGraphicThing"); + return s_type; +} + +bool CGraphicThing::OnIsEmpty() const +{ + return m_pgrnFile ? false : true; +} + +bool CGraphicThing::OnIsType(TType type) +{ + if (CGraphicThing::Type() == type) + return true; + + return CResource::OnIsType(type); +} + +bool CGraphicThing::CreateDeviceObjects() +{ + if (!m_pgrnFileInfo) + return true; + + for (int m = 0; m < m_pgrnFileInfo->ModelCount; ++m) + { + CGrannyModel & rModel = m_models[m]; + rModel.CreateDeviceObjects(); + } + + return true; +} + +void CGraphicThing::DestroyDeviceObjects() +{ + if (!m_pgrnFileInfo) + return; + + for (int m = 0; m < m_pgrnFileInfo->ModelCount; ++m) + { + CGrannyModel & rModel = m_models[m]; + rModel.DestroyDeviceObjects(); + } +} + +bool CGraphicThing::CheckModelIndex(int iModel) const +{ + if (!m_pgrnFileInfo) + { + Tracef("m_pgrnFileInfo == NULL: %s\n", GetFileName()); + return false; + } + + assert(m_pgrnFileInfo != NULL); + + if (iModel < 0) + return false; + + if (iModel >= m_pgrnFileInfo->ModelCount) + return false; + + return true; +} + +bool CGraphicThing::CheckMotionIndex(int iMotion) const +{ + // Temporary + if (!m_pgrnFileInfo) + return false; + // Temporary + + assert(m_pgrnFileInfo != NULL); + + if (iMotion < 0) + return false; + + if (iMotion >= m_pgrnFileInfo->AnimationCount) + return false; + + return true; +} + +CGrannyModel * CGraphicThing::GetModelPointer(int iModel) +{ + assert(CheckModelIndex(iModel)); + assert(m_models != NULL); + return m_models + iModel; +} + +CGrannyMotion * CGraphicThing::GetMotionPointer(int iMotion) +{ + assert(CheckMotionIndex(iMotion)); + + if (iMotion >= m_pgrnFileInfo->AnimationCount) + return NULL; + + assert(m_motions != NULL); + return (m_motions + iMotion); +} + +int CGraphicThing::GetModelCount() const +{ + if (!m_pgrnFileInfo) + return 0; + + return (m_pgrnFileInfo->ModelCount); +} + +int CGraphicThing::GetMotionCount() const +{ + if (!m_pgrnFileInfo) + return 0; + + return (m_pgrnFileInfo->AnimationCount); +} + +bool CGraphicThing::OnLoad(int iSize, const void * c_pvBuf) +{ + if (!c_pvBuf) + return false; + + m_pgrnFile = GrannyReadEntireFileFromMemory(iSize, (void *) c_pvBuf); + + if (!m_pgrnFile) + return false; + + m_pgrnFileInfo = GrannyGetFileInfo(m_pgrnFile); + + if (!m_pgrnFileInfo) + return false; + + LoadModels(); + LoadMotions(); + return true; +} + +// SUPPORT_LOCAL_TEXTURE +static std::string gs_modelLocalPath; + +const std::string& GetModelLocalPath() +{ + return gs_modelLocalPath; +} +// END_OF_SUPPORT_LOCAL_TEXTURE + +bool CGraphicThing::LoadModels() +{ + assert(m_pgrnFile != NULL); + assert(m_models == NULL); + + if (m_pgrnFileInfo->ModelCount <= 0) + return false; + + // SUPPORT_LOCAL_TEXTURE + const std::string& fileName = GetFileNameString(); + + //char localPath[256] = ""; + if (fileName.length() > 2 && fileName[1] != ':') + { + int sepPos = fileName.rfind('\\'); + gs_modelLocalPath.assign(fileName, 0, sepPos+1); + } + // END_OF_SUPPORT_LOCAL_TEXTURE + + int modelCount = m_pgrnFileInfo->ModelCount; + + m_models = new CGrannyModel[modelCount]; + + for (int m = 0; m < modelCount; ++m) + { + CGrannyModel & rModel = m_models[m]; + granny_model * pgrnModel = m_pgrnFileInfo->Models[m]; + + if (!rModel.CreateFromGrannyModelPointer(pgrnModel)) + return false; + } + + GrannyFreeFileSection(m_pgrnFile, GrannyStandardRigidVertexSection); + GrannyFreeFileSection(m_pgrnFile, GrannyStandardRigidIndexSection); + GrannyFreeFileSection(m_pgrnFile, GrannyStandardDeformableIndexSection); + GrannyFreeFileSection(m_pgrnFile, GrannyStandardTextureSection); + return true; +} + +bool CGraphicThing::LoadMotions() +{ + assert(m_pgrnFile != NULL); + assert(m_motions == NULL); + + if (m_pgrnFileInfo->AnimationCount <= 0) + return false; + + int motionCount = m_pgrnFileInfo->AnimationCount; + + m_motions = new CGrannyMotion[motionCount]; + + for (int m = 0; m < motionCount; ++m) + if (!m_motions[m].BindGrannyAnimation(m_pgrnFileInfo->Animations[m])) + return false; + + return true; +} diff --git a/source/EterGrnLib/Thing.h b/source/EterGrnLib/Thing.h new file mode 100644 index 0000000..d879643 --- /dev/null +++ b/source/EterGrnLib/Thing.h @@ -0,0 +1,49 @@ +#pragma once + +#include "Model.h" +#include "Motion.h" + +class CGraphicThing : public CResource +{ + public: + typedef CRef TRef; + + public: + static CGraphicThing::TType Type(); + + public: + CGraphicThing(const char * c_szFileName); + virtual ~CGraphicThing(); + + virtual bool CreateDeviceObjects(); + virtual void DestroyDeviceObjects(); + + bool CheckModelIndex(int iModel) const; + CGrannyModel * GetModelPointer(int iModel); + int GetModelCount() const; + + bool CheckMotionIndex(int iMotion) const; + CGrannyMotion * GetMotionPointer(int iMotion); + int GetMotionCount() const; + + protected: + void Initialize(); + + bool LoadModels(); + bool LoadMotions(); + + protected: + bool OnLoad(int iSize, const void* c_pvBuf); + void OnClear(); + bool OnIsEmpty() const; + bool OnIsType(TType type); + + protected: + granny_file * m_pgrnFile; + granny_file_info * m_pgrnFileInfo; + + granny_animation * m_pgrnAni; + + CGrannyModel * m_models; + CGrannyMotion * m_motions; +}; diff --git a/source/EterGrnLib/ThingInstance.cpp b/source/EterGrnLib/ThingInstance.cpp new file mode 100644 index 0000000..e14ab2c --- /dev/null +++ b/source/EterGrnLib/ThingInstance.cpp @@ -0,0 +1,967 @@ +#include "StdAfx.h" +#include "../eterbase/Debug.h" +#include "../eterlib/Camera.h" +#include "../eterBase/Timer.h" +#include "ThingInstance.h" +#include "Thing.h" +#include "ModelInstance.h" + +CDynamicPool CGraphicThingInstance::ms_kPool; + +CGraphicThing* CGraphicThingInstance::GetBaseThingPtr() +{ + if (m_modelThingSetVector.empty()) + return NULL; + + TModelThingSet& rkModelThingSet=m_modelThingSetVector[0]; + if (rkModelThingSet.m_pLODThingRefVector.empty()) + return NULL; + + CGraphicThing::TRef* proThing=rkModelThingSet.m_pLODThingRefVector[0]; + if (!proThing) + return NULL; + + CGraphicThing::TRef roThing=*proThing; + return roThing.GetPointer(); +} + +bool CGraphicThingInstance::LessRenderOrder(CGraphicThingInstance* pkThingInst) +{ + return (GetBaseThingPtr()GetBaseThingPtr()); +} + +void CGraphicThingInstance::CreateSystem(UINT uCapacity) +{ + ms_kPool.Create(uCapacity); +} + +void CGraphicThingInstance::DestroySystem() +{ + ms_kPool.Destroy(); +} + +CGraphicThingInstance* CGraphicThingInstance::New() +{ + return ms_kPool.Alloc(); +} + +void CGraphicThingInstance::Delete(CGraphicThingInstance* pkThingInst) +{ + pkThingInst->Clear(); + ms_kPool.Free(pkThingInst); +} + +void CGraphicThingInstance::SetMotionAtEnd() +{ + std::for_each(m_LODControllerVector.begin(), m_LODControllerVector.end(), std::mem_fn(&CGrannyLODController::SetMotionAtEnd)); +} + +bool CGraphicThingInstance::Picking(const D3DXVECTOR3 & v, const D3DXVECTOR3 & dir, float & out_x, float & out_y) +{ + if (!m_pHeightAttributeInstance) + return false; + return m_pHeightAttributeInstance->Picking(v,dir,out_x,out_y); +} + + +void CGraphicThingInstance::OnUpdateCollisionData(const CStaticCollisionDataVector * pscdVector) +{ + assert(pscdVector); + CStaticCollisionDataVector::const_iterator it; + for(it = pscdVector->begin();it!=pscdVector->end();++it) + { + AddCollision(&(*it),&GetTransform()); + } +} + +void CGraphicThingInstance::OnUpdateHeighInstance(CAttributeInstance * pAttributeInstance) +{ + assert(pAttributeInstance); + SetHeightInstance(pAttributeInstance); +} + +bool CGraphicThingInstance::OnGetObjectHeight(float fX, float fY, float * pfHeight) +{ + if (m_pHeightAttributeInstance && m_pHeightAttributeInstance->GetHeight(fX, fY, pfHeight)) + return true; + return false; +} + +void CGraphicThingInstance::BuildBoundingSphere() +{ + D3DXVECTOR3 v3Min, v3Max; + GetBoundBox(0, &v3Min, &v3Max); + m_v3Center = (v3Min + v3Max) * 0.5f; + D3DXVECTOR3 vDelta = (v3Max - v3Min); + + m_fRadius = D3DXVec3Length(&vDelta) * 0.5f + 50.0f; // extra length for attached objects +} + +bool CGraphicThingInstance::GetBoundingSphere(D3DXVECTOR3 & v3Center, float & fRadius) +{ + if (m_fRadius <= 0) + { + BuildBoundingSphere(); + + fRadius = m_fRadius; + v3Center = m_v3Center; + } + else + { + fRadius = m_fRadius; + v3Center = m_v3Center; + } + + D3DXVec3TransformCoord(&v3Center, &v3Center, &GetTransform()); + return true; +} + +void CGraphicThingInstance::BuildBoundingAABB() +{ + D3DXVECTOR3 v3Min, v3Max; + GetBoundBox(0, &v3Min, &v3Max); + m_v3Center = (v3Min + v3Max) * 0.5f; + m_v3Min = v3Min; + m_v3Max = v3Max; +} + +bool CGraphicThingInstance::GetBoundingAABB(D3DXVECTOR3 & v3Min, D3DXVECTOR3 & v3Max) +{ + BuildBoundingAABB(); + + v3Min = m_v3Min; + v3Max = m_v3Max; + + D3DXVec3TransformCoord(&m_v3Center, &m_v3Center, &GetTransform()); + return true; +} + +void CGraphicThingInstance::CalculateBBox() +{ + GetBoundBox(&m_v3BBoxMin, &m_v3BBoxMax); + + m_v4TBBox[0] = D3DXVECTOR4(m_v3BBoxMin.x, m_v3BBoxMin.y, m_v3BBoxMin.z, 1.0f); + m_v4TBBox[1] = D3DXVECTOR4(m_v3BBoxMin.x, m_v3BBoxMax.y, m_v3BBoxMin.z, 1.0f); + m_v4TBBox[2] = D3DXVECTOR4(m_v3BBoxMax.x, m_v3BBoxMin.y, m_v3BBoxMin.z, 1.0f); + m_v4TBBox[3] = D3DXVECTOR4(m_v3BBoxMax.x, m_v3BBoxMax.y, m_v3BBoxMin.z, 1.0f); + m_v4TBBox[4] = D3DXVECTOR4(m_v3BBoxMin.x, m_v3BBoxMin.y, m_v3BBoxMax.z, 1.0f); + m_v4TBBox[5] = D3DXVECTOR4(m_v3BBoxMin.x, m_v3BBoxMax.y, m_v3BBoxMax.z, 1.0f); + m_v4TBBox[6] = D3DXVECTOR4(m_v3BBoxMax.x, m_v3BBoxMin.y, m_v3BBoxMax.z, 1.0f); + m_v4TBBox[7] = D3DXVECTOR4(m_v3BBoxMax.x, m_v3BBoxMax.y, m_v3BBoxMax.z, 1.0f); + + const D3DXMATRIX & c_rmatTransform = GetTransform(); + + for (DWORD i = 0; i < 8; ++i) + { + D3DXVec4Transform(&m_v4TBBox[i], &m_v4TBBox[i], &c_rmatTransform); + if (0 == i) + { + m_v3TBBoxMin.x = m_v4TBBox[i].x; + m_v3TBBoxMin.y = m_v4TBBox[i].y; + m_v3TBBoxMin.z = m_v4TBBox[i].z; + m_v3TBBoxMax.x = m_v4TBBox[i].x; + m_v3TBBoxMax.y = m_v4TBBox[i].y; + m_v3TBBoxMax.z = m_v4TBBox[i].z; + } + else + { + if (m_v3TBBoxMin.x > m_v4TBBox[i].x) + m_v3TBBoxMin.x = m_v4TBBox[i].x; + if (m_v3TBBoxMax.x < m_v4TBBox[i].x) + m_v3TBBoxMax.x = m_v4TBBox[i].x; + if (m_v3TBBoxMin.y > m_v4TBBox[i].y) + m_v3TBBoxMin.y = m_v4TBBox[i].y; + if (m_v3TBBoxMax.y < m_v4TBBox[i].y) + m_v3TBBoxMax.y = m_v4TBBox[i].y; + if (m_v3TBBoxMin.z > m_v4TBBox[i].z) + m_v3TBBoxMin.z = m_v4TBBox[i].z; + if (m_v3TBBoxMax.z < m_v4TBBox[i].z) + m_v3TBBoxMax.z = m_v4TBBox[i].z; + } + } +} + +bool CGraphicThingInstance::CreateDeviceObjects() +{ + CGrannyLODController::FCreateDeviceObjects createDeviceObjects; + std::for_each(m_LODControllerVector.begin(), m_LODControllerVector.end(), createDeviceObjects); + return true; +} + +void CGraphicThingInstance::DestroyDeviceObjects() +{ + CGrannyLODController::FDestroyDeviceObjects destroyDeviceObjects; + std::for_each(m_LODControllerVector.begin(), m_LODControllerVector.end(), destroyDeviceObjects); +} + +bool CGraphicThingInstance::CheckModelInstanceIndex(int iModelInstance) +{ + if (iModelInstance < 0) + return false; + + int max = m_LODControllerVector.size(); + + if (iModelInstance >= max) + return false; + + return true; +} + +bool CGraphicThingInstance::CheckModelThingIndex(int iModelThing) +{ + if (iModelThing < 0) + return false; + + int max = m_modelThingSetVector.size(); + + if (iModelThing >= max) + return false; + + return true; +} + +bool CGraphicThingInstance::CheckMotionThingIndex(DWORD dwMotionKey) +{ + std::map::iterator itor = m_roMotionThingMap.find(dwMotionKey); + + if (m_roMotionThingMap.end() == itor) + return false; + + return true; +} + +bool CGraphicThingInstance::GetMotionThingPointer(DWORD dwKey, CGraphicThing ** ppMotion) +{ + if (!CheckMotionThingIndex(dwKey)) + return false; + + *ppMotion = m_roMotionThingMap[dwKey]->GetPointer(); + return true; +} + +bool CGraphicThingInstance::IsMotionThing() +{ + return !m_roMotionThingMap.empty(); +} + +void CGraphicThingInstance::ReserveModelInstance(int iCount) +{ + stl_wipe(m_LODControllerVector); + + for (int i = 0; i < iCount; ++i) + { + CGrannyLODController * pInstance = new CGrannyLODController; + m_LODControllerVector.push_back(pInstance); + } +} + +void CGraphicThingInstance::ReserveModelThing(int iCount) +{ + m_modelThingSetVector.resize(iCount); +} + +bool CGraphicThingInstance::FindBoneIndex(int iModelInstance, const char* c_szBoneName, int* iRetBone) +{ + assert(CheckModelInstanceIndex(iModelInstance)); + + CGrannyModelInstance * pModelInstance = m_LODControllerVector[iModelInstance]->GetModelInstance(); + + if (!pModelInstance) + return false; + + return pModelInstance->GetBoneIndexByName(c_szBoneName, iRetBone); +} + +void CGraphicThingInstance::AttachModelInstance(int iDstModelInstance, const char * c_szBoneName, int iSrcModelInstance) +{ + if (!CheckModelInstanceIndex(iSrcModelInstance)) + { + TraceError("CGraphicThingInstance::AttachModelInstance(iDstModelInstance=%d, c_szBoneName=%s, iSrcModelInstance=%d)", iDstModelInstance, c_szBoneName, iSrcModelInstance); + return; + } + if (!CheckModelInstanceIndex(iDstModelInstance)) + { + TraceError("CGraphicThingInstance::AttachModelInstance(iDstModelInstance=%d, c_szBoneName=%s, iSrcModelInstance=%d)", iDstModelInstance, c_szBoneName, iSrcModelInstance); + return; + } + + CGrannyLODController * pSrcLODController = m_LODControllerVector[iSrcModelInstance]; + CGrannyLODController * pDstLODController = m_LODControllerVector[iDstModelInstance]; + pDstLODController->AttachModelInstance(pSrcLODController, c_szBoneName); +} + +void CGraphicThingInstance::AttachModelInstance(int iDstModelInstance, const char * c_szBoneName, CGraphicThingInstance & rSrcInstance, int iSrcModelInstance) +{ + if (!CheckModelInstanceIndex(iDstModelInstance)) + { + TraceError("CGraphicThingInstance::AttachModelInstance(iDstModelInstance=%d, c_szBoneName=%s, iSrcModelInstance=%d)", iDstModelInstance, c_szBoneName, iSrcModelInstance); + return; + } + if (!rSrcInstance.CheckModelInstanceIndex(iSrcModelInstance)) + { + TraceError("CGraphicThingInstance::AttachModelInstance(iDstModelInstance=%d, c_szBoneName=%s, iSrcModelInstance=%d)", iDstModelInstance, c_szBoneName, iSrcModelInstance); + return; + } + + CGrannyLODController * pDstLODController = m_LODControllerVector[iDstModelInstance]; + CGrannyLODController * pSrcLODController = rSrcInstance.m_LODControllerVector[iSrcModelInstance]; + pDstLODController->AttachModelInstance(pSrcLODController, c_szBoneName); +} + +void CGraphicThingInstance::DetachModelInstance(int iDstModelInstance, CGraphicThingInstance & rSrcInstance, int iSrcModelInstance) +{ + if (!CheckModelInstanceIndex(iDstModelInstance)) + { + TraceError("CGraphicThingInstance::AttachModelInstance(iDstModelInstance=%d, iSrcModelInstance=%d)", iDstModelInstance, iSrcModelInstance); + return; + } + if (!rSrcInstance.CheckModelInstanceIndex(iSrcModelInstance)) + { + TraceError("CGraphicThingInstance::AttachModelInstance(iDstModelInstance=%d, iSrcModelInstance=%d)", iDstModelInstance, iSrcModelInstance); + return; + } + + CGrannyLODController * pDstLODController = m_LODControllerVector[iDstModelInstance]; + CGrannyLODController * pSrcLODController = rSrcInstance.m_LODControllerVector[iSrcModelInstance]; + pDstLODController->DetachModelInstance(pSrcLODController); +} + +bool CGraphicThingInstance::GetBonePosition(int iModelIndex, int iBoneIndex, float * pfx, float * pfy, float * pfz) +{ + assert(CheckModelInstanceIndex(iModelIndex)); + + CGrannyModelInstance * pModelInstance = m_LODControllerVector[iModelIndex]->GetModelInstance(); + + if (!pModelInstance) + return false; + + const float * pfMatrix = pModelInstance->GetBoneMatrixPointer(iBoneIndex); + + *pfx = pfMatrix[12]; + *pfy = pfMatrix[13]; + *pfz = pfMatrix[14]; + return true; +} +//iSkelInstance ⺻ Link( ٴ°)Ű, +// ⺻ attach(ǥ °) ˴ϴ. +bool CGraphicThingInstance::SetModelInstance(int iDstModelInstance, int iSrcModelThing, int iSrcModel,int iSkelInstance) +{ + if (!CheckModelInstanceIndex(iDstModelInstance)) + { + TraceError("CGraphicThingInstance::SetModelInstance(iDstModelInstance=%d, pModelThing=%d, iSrcModel=%d)\n", iDstModelInstance, iSrcModelThing, iSrcModel); + return false; + } + if (!CheckModelThingIndex(iSrcModelThing)) + { + TraceError("CGraphicThingInstance::SetModelInstance(iDstModelInstance=%d, pModelThing=%d, iSrcModel=%d)\n", iDstModelInstance, iSrcModelThing, iSrcModel); + return false; + } + + CGrannyLODController * pController = m_LODControllerVector[iDstModelInstance]; + if (!pController) + return false; + + // HAIR_LINK + CGrannyLODController * pSkelController = NULL; + if (iSkelInstance != DONTUSEVALUE) + { + if (!CheckModelInstanceIndex(iSkelInstance)) + { + TraceError("CGraphicThingInstance::SetModelInstanceByOtherSkeletonInstance(iSkelInstance=%d, iDstModelInstance=%d, pModelThing=%d, iSrcModel=%d)\n", iSkelInstance, iDstModelInstance, iSrcModelThing, iSrcModel); + return false; + } + pSkelController = m_LODControllerVector[iSkelInstance]; + if (!pSkelController) + return false; + } + // END_OF_HAIR_LINK + + TModelThingSet & rModelThingSet = m_modelThingSetVector[iSrcModelThing]; + + pController->Clear(); + + + for (DWORD i = 0; i < rModelThingSet.m_pLODThingRefVector.size(); ++i) + { + if (rModelThingSet.m_pLODThingRefVector[i]->IsNull()) + return false; + + pController->AddModel(rModelThingSet.m_pLODThingRefVector[i]->GetPointer(), iSrcModel, pSkelController); + } + return true; +} + +void CGraphicThingInstance::SetMaterialImagePointer(UINT ePart, const char* c_szImageName, CGraphicImage* pImage) +{ + if (ePart>=m_LODControllerVector.size()) + { + TraceError("CGraphicThingInstance::SetMaterialImagePointer(ePart(%d)GetFileName()); + + return; + } + + if (!m_LODControllerVector[ePart]) + { + TraceError("CGraphicThingInstance::SetMaterialImagePointer(ePart(%d), c_szImageName=%s, pImage=%s) - ePart Data is NULL", + ePart, m_LODControllerVector.size(), c_szImageName, pImage->GetFileName()); + + return; + } + + m_LODControllerVector[ePart]->SetMaterialImagePointer(c_szImageName, pImage); +} + +void CGraphicThingInstance::SetMaterialData(UINT ePart, const char* c_szImageName, SMaterialData kMaterialData) +{ + if (ePart>=m_LODControllerVector.size()) + { + TraceError("CGraphicThingInstance::SetMaterialData(ePart(%d)SetMaterialData(c_szImageName, kMaterialData); +} + +void CGraphicThingInstance::SetSpecularInfo(UINT ePart, const char* c_szMtrlName, BOOL bEnable, float fPower) +{ + if (ePart>=m_LODControllerVector.size()) + { + TraceError("CGraphicThingInstance::SetSpecularInfo(ePart(%d)SetSpecularInfo(c_szMtrlName, bEnable, fPower); +} + +bool CGraphicThingInstance::SetMotion(DWORD dwMotionKey, float blendTime, int loopCount, float speedRatio) +{ + if (!CheckMotionThingIndex(dwMotionKey)) + return false; + + std::map::iterator itor = m_roMotionThingMap.find(dwMotionKey); + CGraphicThing::TRef * proMotionThing = itor->second; + CGraphicThing * pMotionThing = proMotionThing->GetPointer(); + + if (!pMotionThing) + return false; + + if (!pMotionThing->CheckMotionIndex(0)) + return false; + + CGrannyLODController::FSetMotionPointer SetMotionPointer; + SetMotionPointer.m_pMotion = pMotionThing->GetMotionPointer(0); + SetMotionPointer.m_blendTime = blendTime; + SetMotionPointer.m_loopCount = loopCount; + SetMotionPointer.m_speedRatio = speedRatio; + + std::for_each(m_LODControllerVector.begin(), m_LODControllerVector.end(), SetMotionPointer); + return true; +} + +bool CGraphicThingInstance::ChangeMotion(DWORD dwMotionKey, int loopCount, float speedRatio) +{ + if (!CheckMotionThingIndex(dwMotionKey)) + return false; + + std::map::iterator itor = m_roMotionThingMap.find(dwMotionKey); + CGraphicThing::TRef * proMotionThing = itor->second; + CGraphicThing * pMotionThing = proMotionThing->GetPointer(); + + if (!pMotionThing) + return false; + + if (!pMotionThing->CheckMotionIndex(0)) + return false; + + CGrannyLODController::FChangeMotionPointer ChangeMotionPointer; + ChangeMotionPointer.m_pMotion = pMotionThing->GetMotionPointer(0); + ChangeMotionPointer.m_loopCount = loopCount; + ChangeMotionPointer.m_speedRatio = speedRatio; + + std::for_each(m_LODControllerVector.begin(), m_LODControllerVector.end(), ChangeMotionPointer); + return true; +} + +void CGraphicThingInstance::SetEndStopMotion() +{ + std::for_each(m_LODControllerVector.begin(), m_LODControllerVector.end(), CGrannyLODController::FEndStopMotionPointer()); +} + +void CGraphicThingInstance::RegisterModelThing(int iModelThing, CGraphicThing * pModelThing) +{ + if (!CheckModelThingIndex(iModelThing)) + { + TraceError("CGraphicThingInstance::RegisterModelThing(iModelThing=%d, pModelThing=%s)\n", iModelThing, pModelThing->GetFileName()); + return; + } + + m_modelThingSetVector[iModelThing].Clear(); + + if (pModelThing) + RegisterLODThing(iModelThing, pModelThing); +} + +void CGraphicThingInstance::RegisterLODThing(int iModelThing, CGraphicThing * pModelThing) +{ + assert(CheckModelThingIndex(iModelThing)); + CGraphicThing::TRef * pModelRef = new CGraphicThing::TRef; + pModelRef->SetPointer(pModelThing); + m_modelThingSetVector[iModelThing].m_pLODThingRefVector.push_back(pModelRef); +} + +void CGraphicThingInstance::RegisterMotionThing(DWORD dwMotionKey, CGraphicThing* pMotionThing) +{ + CGraphicThing::TRef * pMotionRef = new CGraphicThing::TRef; + pMotionRef->SetPointer(pMotionThing); + m_roMotionThingMap.insert(std::map::value_type(dwMotionKey, pMotionRef)); +} + +void CGraphicThingInstance::ResetLocalTime() +{ + //m_clockLast = GrannyGetSystemSeconds(); + m_fLastLocalTime = 0.0f; + m_fLocalTime = 0.0f; + + CGrannyLODController::FResetLocalTime resetLocalTime; + std::for_each(m_LODControllerVector.begin(), m_LODControllerVector.end(), resetLocalTime); +} + +/* +void CGraphicThingInstance::SetMotionSpeed(float fRate) +{ + m_fMotionTimeSpeed = fRate; +} +*/ +void CGraphicThingInstance::InsertDelay(float fDelay) +{ + m_fDelay = fDelay; +} + +float CGraphicThingInstance::GetLastLocalTime() +{ + return m_fLastLocalTime; +} + +float CGraphicThingInstance::GetLocalTime() +{ + return m_fLocalTime; +} + +float CGraphicThingInstance::GetSecondElapsed() +{ + return m_fSecondElapsed; +} + +float CGraphicThingInstance::GetAverageSecondElapsed() +{ + return m_fAverageSecondElapsed; +} + +bool CGraphicThingInstance::Intersect(float* pu, float* pv, float* pt) +{ + if (!CGraphicObjectInstance::isShow()) + return false; + if (!m_bUpdated) + return false; + + if (m_LODControllerVector.empty()) + { + //TraceError("CGraphicThingInstance::Intersect - m_LODControllerVector is empty"); + return false; + } + + return m_LODControllerVector[0]->Intersect(&GetTransform(), pu, pv, pt); +} + +void CGraphicThingInstance::GetBoundBox(D3DXVECTOR3* vtMin, D3DXVECTOR3* vtMax) +{ + vtMin->x = vtMin->y = vtMin->z = 100000.0f; + vtMax->x = vtMax->y = vtMax->z = -100000.0f; + std::for_each(m_LODControllerVector.begin(), m_LODControllerVector.end(), CGrannyLODController::FBoundBox(vtMin, vtMax)); +} + +BOOL CGraphicThingInstance::GetBoundBox(DWORD dwModelInstanceIndex, D3DXVECTOR3 * vtMin, D3DXVECTOR3 * vtMax) +{ + if (!CheckModelInstanceIndex(dwModelInstanceIndex)) + return FALSE; + + vtMin->x = vtMin->y = vtMin->z = 100000.0f; + vtMax->x = vtMax->y = vtMax->z = -100000.0f; + + CGrannyLODController * pController = m_LODControllerVector[dwModelInstanceIndex]; + if (!pController->isModelInstance()) + return FALSE; + + CGrannyModelInstance * pModelInstance = pController->GetModelInstance(); + pModelInstance->GetBoundBox(vtMin, vtMax); + return TRUE; +} + +BOOL CGraphicThingInstance::GetBoneMatrix(DWORD dwModelInstanceIndex, DWORD dwBoneIndex, D3DXMATRIX ** ppMatrix) +{ + if (!CheckModelInstanceIndex(dwModelInstanceIndex)) + return FALSE; + + CGrannyModelInstance * pModelInstance = m_LODControllerVector[dwModelInstanceIndex]->GetModelInstance(); + if (!pModelInstance) + return FALSE; + + *ppMatrix = (D3DXMATRIX *)pModelInstance->GetBoneMatrixPointer(dwBoneIndex); + if (!*ppMatrix) + return FALSE; + + return TRUE; +} + +BOOL CGraphicThingInstance::GetCompositeBoneMatrix(DWORD dwModelInstanceIndex, DWORD dwBoneIndex, D3DXMATRIX ** ppMatrix) +{ + if (!CheckModelInstanceIndex(dwModelInstanceIndex)) + return FALSE; + + CGrannyModelInstance * pModelInstance = m_LODControllerVector[dwModelInstanceIndex]->GetModelInstance(); + if (!pModelInstance) + { + //TraceError("CGraphicThingInstance::GetCompositeBoneMatrix(dwModelInstanceIndex=%d, dwBoneIndex=%d, D3DXMATRIX ** ppMatrix)", dwModelInstanceIndex, dwBoneIndex); + return FALSE; + } + + *ppMatrix = (D3DXMATRIX *)pModelInstance->GetCompositeBoneMatrixPointer(dwBoneIndex); + + return TRUE; +} + +void CGraphicThingInstance::UpdateTransform(D3DXMATRIX * pMatrix, float fSecondsElapsed, int iModelInstanceIndex) +{ + //TraceError("%s",GetBaseThingPtr()->GetFileName()); + int nLODCount=m_LODControllerVector.size(); + if (iModelInstanceIndex>=nLODCount) + { + //TraceError("void CGraphicThingInstance::UpdateTransform(pMatrix, fSecondsElapsed=%f, iModelInstanceIndex=%d/nLODCount=%d)", + // fSecondsElapsed, iModelInstanceIndex, nLODCount); + return; + } + + CGrannyLODController* pkLODCtrl=m_LODControllerVector[iModelInstanceIndex]; + if (!pkLODCtrl) + { + //TraceError("void CGraphicThingInstance::UpdateTransform(pMatrix, fSecondsElapsed=%f, iModelInstanceIndex=%d/nLODCount=%d) - m_LODControllerVector[iModelInstanceIndex] == NULL", + // fSecondsElapsed, iModelInstanceIndex, nLODCount); + return; + } + + CGrannyModelInstance * pModelInstance = pkLODCtrl->GetModelInstance(); + if (!pModelInstance) + { + /* TraceError("void CGraphicThingInstance::UpdateTransform(pMatrix, fSecondsElapsed=%f, iModelInstanceIndex=%d/nLODCount=%d) - pkLODCtrl->GetModelInstance() == NULL", + fSecondsElapsed, iModelInstanceIndex, nLODCount);*/ + return; + } + + pModelInstance->UpdateTransform(pMatrix, fSecondsElapsed); +} + +void CGraphicThingInstance::DeformAll() +{ + m_bUpdated = true; + + CGrannyLODController::FDeformAll deform; + deform.mc_pWorldMatrix = &m_worldMatrix; + std::for_each(m_LODControllerVector.begin(), m_LODControllerVector.end(), deform); +} + +void CGraphicThingInstance::DeformNoSkin() +{ + m_bUpdated = true; + + std::vector::iterator i; + for (i=m_LODControllerVector.begin(); i!=m_LODControllerVector.end(); ++i) + { + CGrannyLODController* pkLOD=*i; + if (pkLOD->isModelInstance()) + pkLOD->DeformNoSkin(&m_worldMatrix); + } +} + +void CGraphicThingInstance::OnDeform() +{ + m_bUpdated = true; + + CGrannyLODController::FDeform deform; + deform.mc_pWorldMatrix = &m_worldMatrix; + std::for_each(m_LODControllerVector.begin(), m_LODControllerVector.end(), deform); +} + +void CGraphicThingInstance::__SetLocalTime(float fLocalTime) +{ + m_fLastLocalTime = m_fLocalTime; + m_fLocalTime = fLocalTime; + + CGrannyLODController::FSetLocalTime SetLocalTime; + SetLocalTime.fLocalTime = fLocalTime; + std::for_each(m_LODControllerVector.begin(), m_LODControllerVector.end(), SetLocalTime); +} + +void CGraphicThingInstance::UpdateLODLevel() +{ + CCamera * pcurCamera = CCameraManager::Instance().GetCurrentCamera(); + if (!pcurCamera) + { + TraceError("CGraphicThingInstance::UpdateLODLevel - GetCurrentCamera() == NULL"); + return; + } + + const D3DXVECTOR3 & c_rv3TargetPosition = pcurCamera->GetTarget(); + const D3DXVECTOR3 & c_rv3CameraPosition = pcurCamera->GetEye(); + const D3DXVECTOR3 & c_v3Position = GetPosition(); + + // NOTE : ߽κ Ÿ 꿡 z ̴ ʴ´. - [levites] + CGrannyLODController::FUpdateLODLevel update; + update.fDistanceFromCenter = sqrtf((c_rv3TargetPosition.x - c_v3Position.x) * (c_rv3TargetPosition.x - c_v3Position.x) + + (c_rv3TargetPosition.y - c_v3Position.y) * (c_rv3TargetPosition.y - c_v3Position.y)); + update.fDistanceFromCamera = sqrtf((c_rv3CameraPosition.x - c_v3Position.x) * (c_rv3CameraPosition.x - c_v3Position.x) + + (c_rv3CameraPosition.y - c_v3Position.y) * (c_rv3CameraPosition.y - c_v3Position.y) + + (c_rv3CameraPosition.z - c_v3Position.z) * (c_rv3CameraPosition.z - c_v3Position.z)); + + std::for_each(m_LODControllerVector.begin(), m_LODControllerVector.end(), update); +} + +void CGraphicThingInstance::UpdateTime() +{ + //granny_system_clock clockNow = GrannyGetSystemSeconds(); + //m_fSecondElapsed = GrannyGetSecondsElapsed(&m_clockLast, &clockNow) * m_fMotionTimeSpeed; + + //DWORD t1=ELTimer_GetMSec(); + + m_fSecondElapsed=CTimer::Instance().GetElapsedSecond(); + + if (m_fDelay > m_fSecondElapsed) + { + m_fDelay -= m_fSecondElapsed; + m_fSecondElapsed = 0.0f; + } + else + { + m_fSecondElapsed -= m_fDelay; + m_fDelay = 0.0f; + } + + m_fLastLocalTime = m_fLocalTime; + m_fLocalTime += m_fSecondElapsed; + m_fAverageSecondElapsed = m_fAverageSecondElapsed + (m_fSecondElapsed - m_fAverageSecondElapsed) / 4.0f; + //m_clockLast = clockNow; + + CGrannyLODController::FUpdateTime update; + update.fElapsedTime = m_fSecondElapsed; + std::for_each(m_LODControllerVector.begin(), m_LODControllerVector.end(), update); +} + +void CGraphicThingInstance::OnUpdate() +{ +#ifdef __PERFORMANCE_CHECKER__ + DWORD t1=timeGetTime(); +#endif + UpdateLODLevel(); +#ifdef __PERFORMANCE_CHECKER__ + DWORD t2=timeGetTime(); +#endif + UpdateTime(); +#ifdef __PERFORMANCE_CHECKER__ + DWORD t3=timeGetTime(); +#endif + +#ifdef __PERFORMANCE_CHECKER__ + { + static FILE* fp=fopen("perf_thing_onupdate.txt", "w"); + + if (t3-t1>3) + { + fprintf(fp, "GTU.Total %d (Time %f)\n", + t3-t1, ELTimer_GetMSec()/1000.0f); + fprintf(fp, "GTU.CAL %d\n", t2-t1); + fprintf(fp, "GTU.UP %d\n", t3-t2); + fprintf(fp, "-------------------------------- \n"); + fflush(fp); + } + fflush(fp); + } +#endif +} + +void CGraphicThingInstance::OnRender() +{ + RenderWithOneTexture(); +} + +void CGraphicThingInstance::OnBlendRender() +{ + BlendRenderWithOneTexture(); +} + +void CGraphicThingInstance::RenderWithOneTexture() +{ + //assert(m_bUpdated); + if (!m_bUpdated) + return; + + CGrannyLODController::FRenderWithOneTexture render; + std::for_each(m_LODControllerVector.begin(), m_LODControllerVector.end(), render); +} + +void CGraphicThingInstance::BlendRenderWithOneTexture() +{ + //assert(m_bUpdated); + if (!m_bUpdated) + return; + + CGrannyLODController::FBlendRenderWithOneTexture blendRender; + std::for_each(m_LODControllerVector.begin(), m_LODControllerVector.end(), blendRender); +} + +void CGraphicThingInstance::RenderWithTwoTexture() +{ + //assert(m_bUpdated); + if (!m_bUpdated) + return; + + CGrannyLODController::FRenderWithTwoTexture render; + std::for_each(m_LODControllerVector.begin(), m_LODControllerVector.end(), render); +} + +void CGraphicThingInstance::BlendRenderWithTwoTexture() +{ + //assert(m_bUpdated); + if (!m_bUpdated) + return; + + CGrannyLODController::FRenderWithTwoTexture blendRender; + std::for_each(m_LODControllerVector.begin(), m_LODControllerVector.end(), blendRender); +} + +void CGraphicThingInstance::OnRenderToShadowMap() +{ + if (!m_bUpdated) + return; + + CGrannyLODController::FRenderToShadowMap RenderToShadowMap; + std::for_each(m_LODControllerVector.begin(), m_LODControllerVector.end(), RenderToShadowMap); +} + +void CGraphicThingInstance::OnRenderShadow() +{ + CGrannyLODController::FRenderShadow RenderShadow; + std::for_each(m_LODControllerVector.begin(), m_LODControllerVector.end(), RenderShadow); +} + +void CGraphicThingInstance::OnRenderPCBlocker() +{ + CGrannyLODController::FRenderWithOneTexture RenderPCBlocker; + std::for_each(m_LODControllerVector.begin(), m_LODControllerVector.end(), RenderPCBlocker); +} + +DWORD CGraphicThingInstance::GetLODControllerCount() const +{ + return m_LODControllerVector.size(); +} + +CGrannyLODController * CGraphicThingInstance::GetLODControllerPointer(DWORD dwModelIndex) const +{ + assert(dwModelIndex < m_LODControllerVector.size()); + return m_LODControllerVector[dwModelIndex]; +} + +CGrannyLODController * CGraphicThingInstance::GetLODControllerPointer(DWORD dwModelIndex) +{ + assert(dwModelIndex < m_LODControllerVector.size()); + return m_LODControllerVector[dwModelIndex]; +} + +BYTE CGraphicThingInstance::GetLODLevel(DWORD dwModelInstance) +{ + assert(dwModelInstance < m_LODControllerVector.size()); + return (m_LODControllerVector[dwModelInstance]->GetLODLevel()); +} + +float CGraphicThingInstance::GetHeight() +{ + if (m_LODControllerVector.empty()) + return 0.0f; + + CGrannyModelInstance * pModelInstance = m_LODControllerVector[0]->GetModelInstance(); + if (!pModelInstance) + return 0.0f; + + D3DXVECTOR3 vtMin, vtMax; + pModelInstance->GetBoundBox(&vtMin, &vtMax); + + return fabs(vtMin.z - vtMax.z); +} + +void CGraphicThingInstance::ReloadTexture() +{ + CGrannyLODController::FReloadTexture ReloadTexture; + std::for_each(m_LODControllerVector.begin(), m_LODControllerVector.end(), ReloadTexture); +} + +bool CGraphicThingInstance::HaveBlendThing() +{ + for (int i = 0; i < m_LODControllerVector.size(); i++) + { + if (m_LODControllerVector[i]->HaveBlendThing()) + return true; + } + return false; +} + + +void CGraphicThingInstance::OnClear() +{ + stl_wipe(m_LODControllerVector); + stl_wipe_second(m_roMotionThingMap); + + for (DWORD d = 0; d < m_modelThingSetVector.size(); ++d) + m_modelThingSetVector[d].Clear(); +} + +void CGraphicThingInstance::OnInitialize() +{ + m_bUpdated = false; + m_fLastLocalTime = 0.0f; + m_fLocalTime = 0.0f; + m_fDelay = 0.0; + m_fSecondElapsed = 0.0f; + m_fAverageSecondElapsed = 0.03f; + m_fRadius = -1.0f; + m_v3Center = D3DXVECTOR3(0.0f, 0.0f, 0.0f); + + ResetLocalTime(); +} + +CGraphicThingInstance::CGraphicThingInstance() +{ + Initialize(); +} + +CGraphicThingInstance::~CGraphicThingInstance() +{ +} diff --git a/source/EterGrnLib/ThingInstance.h b/source/EterGrnLib/ThingInstance.h new file mode 100644 index 0000000..857558a --- /dev/null +++ b/source/EterGrnLib/ThingInstance.h @@ -0,0 +1,158 @@ +#pragma once + +#include "../eterbase/Stl.h" +#include "../eterlib/GrpObjectInstance.h" +#include "../eterlib/GrpShadowTexture.h" + +#include "LODController.h" + +const int DONTUSEVALUE = -1; +class CGraphicThingInstance : public CGraphicObjectInstance +{ + public: + typedef struct SModelThingSet + { + void Clear() + { + stl_wipe(m_pLODThingRefVector); + } + + std::vector m_pLODThingRefVector; + } TModelThingSet; + + public: + enum + { + ID = THING_OBJECT + }; + int GetType() const { return ID; } + + CGraphicThingInstance(); + virtual ~CGraphicThingInstance(); + + void DeformNoSkin(); + + void UpdateLODLevel(); + void UpdateTime(); + void DeformAll(); // LOD + + bool LessRenderOrder(CGraphicThingInstance* pkThingInst); + + bool Picking(const D3DXVECTOR3 & v, const D3DXVECTOR3 & dir, float & out_x, float & out_y); + + void OnInitialize(); + + bool CreateDeviceObjects(); + void DestroyDeviceObjects(); + + void ReserveModelInstance(int iCount); + void ReserveModelThing(int iCount); + + bool CheckModelInstanceIndex(int iModelInstance); + bool CheckModelThingIndex(int iModelThing); + bool CheckMotionThingIndex(DWORD dwMotionKey); + bool GetMotionThingPointer(DWORD dwKey, CGraphicThing ** ppMotion); + bool IsMotionThing(); + + void RegisterModelThing(int iModelThing, CGraphicThing * pModelThing); + void RegisterLODThing(int iModelThing, CGraphicThing * pModelThing); + void RegisterMotionThing(DWORD dwMotionKey, CGraphicThing * pMotionThing); + + bool SetModelInstance(int iDstModelInstance, int iSrcModelThing, int iSrcModel,int iSkelInstance = DONTUSEVALUE); + void SetEndStopMotion(); + void SetMotionAtEnd(); + + void AttachModelInstance(int iDstModelInstance, const char * c_szBoneName, int iSrcModelInstance); + void AttachModelInstance(int iDstModelInstance, const char * c_szBoneName, CGraphicThingInstance & rsrcInstance, int iSrcModelInstance); + void DetachModelInstance(int iDstModelInstance, CGraphicThingInstance & rSrcInstance, int SrcModelInstance); + bool FindBoneIndex(int iModelInstance, const char* c_szBoneName, int * iRetBone); + bool GetBonePosition(int iModelIndex, int iBoneIndex, float * pfx, float * pfy, float * pfz); + + void ResetLocalTime(); + void InsertDelay(float fDelay); + + void SetMaterialImagePointer(UINT ePart, const char* c_szImageName, CGraphicImage* pImage); + void SetMaterialData(UINT ePart, const char* c_szImageName, SMaterialData kMaterialData); + void SetSpecularInfo(UINT ePart, const char* c_szMtrlName, BOOL bEnable, float fPower); + + void __SetLocalTime(float fLocalTime); // Only Used by Tools + float GetLastLocalTime(); + float GetLocalTime(); + float GetSecondElapsed(); + float GetAverageSecondElapsed(); + + BYTE GetLODLevel(DWORD dwModelInstance); + float GetHeight(); + + void RenderWithOneTexture(); + void RenderWithTwoTexture(); + void BlendRenderWithOneTexture(); + void BlendRenderWithTwoTexture(); + + DWORD GetLODControllerCount() const; + CGrannyLODController * GetLODControllerPointer(DWORD dwModelIndex) const; + CGrannyLODController * GetLODControllerPointer(DWORD dwModelIndex); + + void ReloadTexture(); + + public: + CGraphicThing* GetBaseThingPtr(); + + bool SetMotion(DWORD dwMotionKey, float blendTime = 0.0f, int loopCount = 0, float speedRatio=1.0f); + bool ChangeMotion(DWORD dwMotionKey, int loopCount = 0, float speedRatio=1.0f); + bool Intersect(float * pu, float * pv, float * pt); + void GetBoundBox(D3DXVECTOR3 * vtMin, D3DXVECTOR3 * vtMax); + BOOL GetBoundBox(DWORD dwModelInstanceIndex, D3DXVECTOR3 * vtMin, D3DXVECTOR3 * vtMax); + BOOL GetBoneMatrix(DWORD dwModelInstanceIndex, DWORD dwBoneIndex, D3DXMATRIX ** ppMatrix); + BOOL GetCompositeBoneMatrix(DWORD dwModelInstanceIndex, DWORD dwBoneIndex, D3DXMATRIX ** ppMatrix); + void UpdateTransform(D3DXMATRIX * pMatrix, float fSecondsElapsed = 0.0f, int iModelInstanceIndex = 0); + void ProjectShadow(const CGraphicShadowTexture & c_rShadowTexture); + + public: + void BuildBoundingSphere(); + void BuildBoundingAABB(); + virtual void CalculateBBox(); + virtual bool GetBoundingSphere(D3DXVECTOR3 & v3Center, float & fRadius); + virtual bool GetBoundingAABB(D3DXVECTOR3 & v3Min, D3DXVECTOR3 & v3Max); + + protected: + void OnClear(); + void OnDeform(); + void OnUpdate(); + void OnRender(); + void OnBlendRender(); + void OnRenderToShadowMap(); + void OnRenderShadow(); + void OnRenderPCBlocker(); + + protected: + bool m_bUpdated; + float m_fLastLocalTime; + float m_fLocalTime; + float m_fDelay; + float m_fSecondElapsed; + float m_fAverageSecondElapsed; + float m_fRadius; + D3DXVECTOR3 m_v3Center; + D3DXVECTOR3 m_v3Min, m_v3Max; + + std::vector m_LODControllerVector; + std::vector m_modelThingSetVector; + std::map m_roMotionThingMap; + + protected: + virtual void OnUpdateCollisionData(const CStaticCollisionDataVector * pscdVector); + virtual void OnUpdateHeighInstance(CAttributeInstance * pAttributeInstance); + virtual bool OnGetObjectHeight(float fX, float fY, float * pfHeight); + + public: + static void CreateSystem(UINT uCapacity); + static void DestroySystem(); + + static CGraphicThingInstance* New(); + static void Delete(CGraphicThingInstance* pkInst); + + static CDynamicPool ms_kPool; + + bool HaveBlendThing(); +}; diff --git a/source/EterGrnLib/Util.cpp b/source/EterGrnLib/Util.cpp new file mode 100644 index 0000000..054579e --- /dev/null +++ b/source/EterGrnLib/Util.cpp @@ -0,0 +1,55 @@ +#include "StdAfx.h" +#include "Util.h" + +/* +bool GrannyMeshGetTextureAnimation(granny_mesh* pgrnMesh, float* puVelocity, float* pvVelocity) +{ + static granny_data_type_definition s_UVType[] = + { + {GrannyInt32Member, "UV Animation Flag"}, + {GrannyInt32Member, "X Velocity"}, + {GrannyInt32Member, "Y Velocity"}, + {GrannyEndMember} + }; + + typedef struct SUVData + { + granny_int32 UVAnimationFlag; + granny_int32 xVelocity; + granny_int32 yVelocity; + } TUVData; + + TUVData UVData; + + granny_variant& rExtendedData = pgrnMesh->ExtendedData; + GrannyConvertSingleObject(rExtendedData.Type, rExtendedData.Object, s_UVType, &UVData); + + *puVelocity = float(UVData.xVelocity) / 100000.0f; + *pvVelocity = float(UVData.yVelocity) / 100000.0f; + + return UVData.UVAnimationFlag ? true : false; +} +*/ + +/* +bool GrannyMeshIsTextureAnimation(granny_mesh* pgrnMesh) +{ + if (GrannyMeshIsRigid(pgrnMesh)) + { + float xVelocity, yVelocity; + + if (GrannyMeshGetTextureAnimation(pgrnMesh, &xVelocity, &yVelocity)) + return true; + } + + return false; +} +*/ + +bool GrannyMeshIsDeform(granny_mesh* pgrnMesh) +{ + if (GrannyMeshIsRigid(pgrnMesh)) + return false; + + return true; +} diff --git a/source/EterGrnLib/Util.h b/source/EterGrnLib/Util.h new file mode 100644 index 0000000..50e0d01 --- /dev/null +++ b/source/EterGrnLib/Util.h @@ -0,0 +1,16 @@ +#pragma once + +// bool GrannyMeshGetTextureAnimation(granny_mesh* pgrnMesh, float* puVelocity, float* pvVelocity); +// bool GrannyMeshIsTextureAnimation(granny_mesh* pgrnMesh); +bool GrannyMeshIsDeform(granny_mesh* pgrnMesh); + +class CGraphicImage; + +struct SMaterialData +{ + CGraphicImage * pImage; + float fSpecularPower; + BOOL isSpecularEnable; + BYTE bSphereMapIndex; +}; + diff --git a/source/EterImageLib/DXTCImage.cpp b/source/EterImageLib/DXTCImage.cpp new file mode 100644 index 0000000..b0aeba4 --- /dev/null +++ b/source/EterImageLib/DXTCImage.cpp @@ -0,0 +1,1645 @@ +// need the d3d.h for things in format of .dds file +#include "StdAfx.h" + +#include +#include +#include +#include + +#include "../eterBase/MappedFile.h" +#include "../eterBase/Debug.h" + +#include "DXTCImage.h" + +struct DXTColBlock +{ + WORD col0; + WORD col1; + + // no bit fields - use bytes + BYTE row[4]; +}; + +struct DXTAlphaBlockExplicit +{ + WORD row[4]; +}; + +struct DXTAlphaBlock3BitLinear +{ + BYTE alpha0; + BYTE alpha1; + + BYTE stuff[6]; +}; + +// use cast to struct instead of RGBA_MAKE as struct is much +struct Color8888 +{ + BYTE b; // Last one is MSB, 1st is LSB. + BYTE g; // order of the output ARGB or BGRA, etc... + BYTE r; // change the order of names to change the + BYTE a; +}; + +struct Color565 +{ + unsigned nBlue : 5; // order of names changes + unsigned nGreen : 6; // byte order of output to 32 bit + unsigned nRed : 5; +}; + +///////////////////////////////////// +// should be in ddraw.h +#ifndef MAKEFOURCC +#define MAKEFOURCC(ch0, ch1, ch2, ch3) \ + ((DWORD)(BYTE) (ch0 ) | ((DWORD)(BYTE) (ch1) << 8) | \ + ((DWORD)(BYTE) (ch2) << 16) | ((DWORD)(BYTE) (ch3) << 24)) +#endif // defined(MAKEFOURCC) + +CDXTCImage::CDXTCImage() +{ + Initialize(); +} + +CDXTCImage::~CDXTCImage() +{ +} + +void CDXTCImage::Initialize() +{ + m_nWidth = 0; + m_nHeight = 0; + + for (int i = 0; i < MAX_MIPLEVELS; ++i) + m_pbCompBufferByLevels[i] = NULL; +} + +void CDXTCImage::Clear() +{ + for (int i = 0; i < MAX_MIPLEVELS; ++i) + m_bCompVector[i].clear(); + + Initialize(); +} + +bool CDXTCImage::LoadFromFile(const char * filename) +{ + // only understands .dds files for now + // return true if success + int next = 1; + + static char fileupper[MAX_PATH+1]; + + strncpy(fileupper, filename, MAX_PATH); + _strupr(fileupper); + + int i; + bool knownformat = false; + + for (i = 0; i < next; ++i) + { + char * found = strstr(fileupper, ".DDS"); + + if (found != NULL) + { + knownformat = true; + break; + } + } + + if (knownformat == false) + { + Tracef("Unknown file format encountered! [%s]\n", filename); + return(false); + } + + CMappedFile mappedFile; + LPCVOID pvMap; + + if (!mappedFile.Create(filename, &pvMap, 0, 0)) + { + Tracef("Can't open file for reading! [%s]\n", filename); + return false; + } + + return LoadFromMemory((const BYTE*) pvMap); +} + +bool CDXTCImage::LoadHeaderFromMemory(const BYTE * c_pbMap) +{ + ////////////////////////////////////// + // start reading the file + // from Microsoft's mssdk D3DIM example "Compress" + DWORD dwMagic; + + // Read magic number + dwMagic = *(DWORD *) c_pbMap; + c_pbMap += sizeof(DWORD); + +//!@# +// if (dwMagic != MAKEFOURCC('D','D','S',' ')) +// return false; + + DDSURFACEDESC2 ddsd; // read from dds file + + // Read the surface description + memcpy(&ddsd, c_pbMap, sizeof(DDSURFACEDESC2)); + c_pbMap += sizeof(DDSURFACEDESC2); + + // Does texture have mipmaps? + m_bMipTexture = (ddsd.dwMipMapCount > 0) ? TRUE : FALSE; + + // Clear unwanted flags + // Can't do this!!! surface not re-created here + // ddsd.dwFlags &= (~DDSD_PITCH); + // ddsd.dwFlags &= (~DDSD_LINEARSIZE); + + // Is it DXTC ? + // I sure hope pixelformat is valid! + m_xddPixelFormat.dwFlags = ddsd.ddpfPixelFormat.dwFlags; + m_xddPixelFormat.dwFourCC = ddsd.ddpfPixelFormat.dwFourCC; + m_xddPixelFormat.dwSize = ddsd.ddpfPixelFormat.dwSize; + m_xddPixelFormat.dwRGBBitCount = ddsd.ddpfPixelFormat.dwRGBBitCount; + m_xddPixelFormat.dwRGBAlphaBitMask = ddsd.ddpfPixelFormat.dwRGBAlphaBitMask; + m_xddPixelFormat.dwRBitMask = ddsd.ddpfPixelFormat.dwRBitMask; + m_xddPixelFormat.dwGBitMask = ddsd.ddpfPixelFormat.dwGBitMask; + m_xddPixelFormat.dwBBitMask = ddsd.ddpfPixelFormat.dwBBitMask; + + DecodePixelFormat(m_strFormat, &m_xddPixelFormat); + + if (m_CompFormat != PF_DXT1 && + m_CompFormat != PF_DXT3 && + m_CompFormat != PF_DXT5) + { + return false; + } + + if (ddsd.dwMipMapCount > MAX_MIPLEVELS) + ddsd.dwMipMapCount = MAX_MIPLEVELS; + + m_nWidth = ddsd.dwWidth; + m_nHeight = ddsd.dwHeight; + //!@# + m_dwMipMapCount = max(1, ddsd.dwMipMapCount); + m_dwFlags = ddsd.dwFlags; + + if (ddsd.dwFlags & DDSD_PITCH) + { + m_lPitch = ddsd.lPitch; + m_pbCompBufferByLevels[0] = c_pbMap; + } + else + { + m_lPitch = ddsd.dwLinearSize; + + if (ddsd.dwFlags & DDSD_MIPMAPCOUNT) + { + for (DWORD dwLinearSize = ddsd.dwLinearSize, i = 0; i < m_dwMipMapCount; ++i, dwLinearSize >>= 2) + { + m_pbCompBufferByLevels[i] = c_pbMap; + c_pbMap += dwLinearSize; + } + } + else + { + m_pbCompBufferByLevels[0] = c_pbMap; + } + } + + return true; +} + +////////////////////////////////////////////////////////////////////// +bool CDXTCImage::LoadFromMemory(const BYTE * c_pbMap) +{ + if (!LoadHeaderFromMemory(c_pbMap)) + return false; + + if (m_dwFlags & DDSD_PITCH) + { + DWORD dwBytesPerRow = m_nWidth * m_xddPixelFormat.dwRGBBitCount / 8; + + m_nCompSize = m_lPitch * m_nHeight; + m_nCompLineSz = dwBytesPerRow; + + m_bCompVector[0].resize(m_nCompSize); + BYTE * pDest = &m_bCompVector[0][0]; + + c_pbMap = m_pbCompBufferByLevels[0]; + + for (int yp = 0; yp < m_nHeight; ++yp) + { + memcpy(pDest, c_pbMap, dwBytesPerRow); + pDest += m_lPitch; + c_pbMap += m_lPitch; + } + } + else + { + if (m_dwFlags & DDSD_MIPMAPCOUNT) + { + for (DWORD dwLinearSize = m_lPitch, i = 0; i < m_dwMipMapCount; ++i, dwLinearSize >>= 2) + { + m_bCompVector[i].resize(dwLinearSize); + Copy(i, &m_bCompVector[i][0], dwLinearSize); + } + } + else + { + m_bCompVector[0].resize(m_lPitch); + Copy(0, &m_bCompVector[0][0], m_lPitch); + } + } + + // done reading file + return true; +} + +bool CDXTCImage::Copy(int miplevel, BYTE * pbDest, long lDestPitch) +{ + if (!(m_dwFlags & DDSD_MIPMAPCOUNT)) + if (miplevel) + return false; + + /* + DXTColBlock * pBlock; + WORD * pPos = (WORD *) &m_pbCompBufferByLevels[miplevel][0]; + int xblocks = (m_nWidth >> miplevel) / 4; + int yblocks = (m_nHeight >> miplevel) / 4; + + for (int y = 0; y < yblocks; ++y) + { + // 8 bytes per block + pBlock = (DXTColBlock*) ((DWORD) pPos + y * xblocks * 8); + + memcpy(pbDest, pBlock, xblocks * 8); + pbDest += lDestPitch; + } + */ + + memcpy(pbDest, m_pbCompBufferByLevels[miplevel], m_lPitch >> (miplevel * 2)); + pbDest += lDestPitch; + return true; +} + +void CDXTCImage::Unextract(BYTE * pbDest, int /*iWidth*/, int /*iHeight*/, int iPitch) +{ + if (!m_pbCompBufferByLevels[0]) + return; + + DXTColBlock * pBlock; + BYTE * pPos = (BYTE *) &m_pbCompBufferByLevels[0][0]; + int xblocks = m_nWidth / 4; + int yblocks = (m_nHeight / 4) * ((iPitch / m_nWidth) / 2); + + for (int y = 0; y < yblocks; ++y) + { + pBlock = (DXTColBlock*) (pPos + y * xblocks * 8); + + memcpy(pbDest, pBlock, xblocks * 8); + pbDest += xblocks * 8; + } + + /* + for (int y = 0; y < iHeight; ++y) + { + memcpy(pbDest, &m_pbCompBufferByLevels[0][0] + y*iWidth, iWidth); + pbDest += iWidth; + } + */ +} + +void CDXTCImage::Decompress(int miplevel, DWORD * pdwDest) +{ + switch (m_CompFormat) + { + case PF_DXT1: + DecompressDXT1(miplevel, pdwDest); + break; + + case PF_DXT3: + DecompressDXT3(miplevel, pdwDest); + break; + + case PF_DXT5: + DecompressDXT5(miplevel, pdwDest); + break; + + case PF_ARGB: + DecompressARGB(miplevel, pdwDest); + break; + + case PF_UNKNOWN: + break; + } +} + +inline void GetColorBlockColors(DXTColBlock * pBlock, Color8888 * col_0, Color8888 * col_1, + Color8888 * col_2, Color8888 * col_3, + WORD & wrd) +{ + // There are 4 methods to use - see the Time_ functions. + // 1st = shift = does normal approach per byte for color comps + // 2nd = use freak variable bit field color565 for component extraction + // 3rd = use super-freak DWORD adds BEFORE shifting the color components + // This lets you do only 1 add per color instead of 3 BYTE adds and + // might be faster + // Call RunTimingSession() to run each of them & output result to txt file + + // freak variable bit structure method + // normal math + // This method is fastest + Color565 * pCol; + + pCol = (Color565*) & (pBlock->col0); + + col_0->a = 0xff; + col_0->r = pCol->nRed; + col_0->r <<= 3; // shift to full precision + col_0->g = pCol->nGreen; + col_0->g <<= 2; + col_0->b = pCol->nBlue; + col_0->b <<= 3; + + pCol = (Color565*) & (pBlock->col1); + col_1->a = 0xff; + col_1->r = pCol->nRed; + col_1->r <<= 3; // shift to full precision + col_1->g = pCol->nGreen; + col_1->g <<= 2; + col_1->b = pCol->nBlue; + col_1->b <<= 3; + + if (pBlock->col0 > pBlock->col1) + { + // Four-color block: derive the other two colors. + // 00 = color_0, 01 = color_1, 10 = color_2, 11 = color_3 + // These two bit codes correspond to the 2-bit fields + // stored in the 64-bit block. + wrd = (WORD) (((WORD) col_0->r * 2 + (WORD) col_1->r) / 3); + // no +1 for rounding + // as bits have been shifted to 888 + col_2->r = (BYTE)wrd; + + wrd = (WORD) (((WORD) col_0->g * 2 + (WORD) col_1->g) / 3); + col_2->g = (BYTE)wrd; + + wrd = (WORD) (((WORD) col_0->b * 2 + (WORD) col_1->b) / 3); + col_2->b = (BYTE)wrd; + col_2->a = 0xff; + + wrd = (WORD) (((WORD) col_0->r + (WORD) col_1->r * 2) / 3); + col_3->r = (BYTE)wrd; + + wrd = (WORD) (((WORD) col_0->g + (WORD) col_1->g * 2) / 3); + col_3->g = (BYTE)wrd; + + wrd = (WORD) (((WORD) col_0->b + (WORD) col_1->b * 2) / 3); + col_3->b = (BYTE)wrd; + col_3->a = 0xff; + } + else + { + // Three-color block: derive the other color. + // 00 = color_0, 01 = color_1, 10 = color_2, + // 11 = transparent. + // These two bit codes correspond to the 2-bit fields + // stored in the 64-bit block. + + // explicit for each component, unlike some refrasts... + + // Tracef("block has alpha\n"); + wrd = (WORD) (((WORD) col_0->r + (WORD) col_1->r) / 2); + col_2->r = (BYTE)wrd; + wrd = (WORD) (((WORD) col_0->g + (WORD) col_1->g) / 2); + col_2->g = (BYTE)wrd; + wrd = (WORD) (((WORD) col_0->b + (WORD) col_1->b) / 2); + col_2->b = (BYTE)wrd; + col_2->a = 0xff; + + col_3->r = 0x00; // random color to indicate alpha + col_3->g = 0x00; + col_3->b = 0x00; + col_3->a = 0x00; + } +} // Get color block colors (...) + + +inline void DecodeColorBlock(DWORD * pImPos, + DXTColBlock * pColorBlock, + int width, + DWORD * col_0, + DWORD * col_1, + DWORD * col_2, + DWORD * col_3) +{ + // width is width of image in pixels + DWORD bits; + int y, n; + + // bit masks = 00000011, 00001100, 00110000, 11000000 + const DWORD masks[] = { 3, 12, 3 << 4, 3 << 6 }; + const int shift[] = { 0, 2, 4, 6 }; + + // r steps through lines in y + for (y = 0; y < 4; ++y, pImPos += width - 4) // no width * 4 as DWORD ptr inc will * 4 + { + // width * 4 bytes per pixel per line + // each j dxtc row is 4 lines of pixels + + // pImPos = (DWORD*) ((DWORD) pBase + i * 16 + (y + j * 4) * m_nWidth * 4); + + // n steps through pixels + for (n = 0; n < 4; ++n) + { + bits = pColorBlock->row[y] & masks[n]; + bits >>= shift[n]; + + switch (bits) + { + case 0: + *pImPos = *col_0; + pImPos++; // increment to next DWORD + break; + + case 1: + *pImPos = *col_1; + pImPos++; + break; + + case 2: + *pImPos = *col_2; + pImPos++; + break; + + case 3: + *pImPos = *col_3; + pImPos++; + break; + + default: + Tracef("Your logic is jacked! bits == 0x%x\n", bits); + pImPos++; + break; + } + } + } +} + +inline void DecodeAlphaExplicit(DWORD * pImPos, DXTAlphaBlockExplicit * pAlphaBlock, + int width, DWORD alphazero) +{ + // alphazero is a bit mask that when & with the image color + // will zero the alpha bits, so if the image DWORDs are + // ARGB then alphazero will be 0x00ffffff or if + // RGBA then alphazero will be 0xffffff00 + // alphazero constructed automaticaly from field order of Color8888 structure + + // decodes to 32 bit format only + int row, pix; + + WORD wrd; + + Color8888 col; + col.r = col.g = col.b = 0; + + //Tracef("\n"); + for (row = 0; row < 4; row++, pImPos += width - 4) + { + // pImPow += pImPos += width-4 moves to next row down + wrd = pAlphaBlock->row[row]; + + // Tracef("0x%.8x\t\t", wrd); + for (pix = 0; pix < 4; ++pix) + { + // zero the alpha bits of image pixel + *pImPos &= alphazero; + + col.a = (BYTE) (wrd & 0x000f); // get only low 4 bits + // col.a <<= 4; // shift to full byte precision + // NOTE: with just a << 4 you'll never have alpha + // of 0xff, 0xf0 is max so pure shift doesn't quite + // cover full alpha range. + // It's much cheaper than divide & scale though. + // To correct for this, and get 0xff for max alpha, + // or the low bits back in after left shifting + col.a = (BYTE) (col.a | (col.a << 4)); // This allows max 4 bit alpha to be 0xff alpha + // in final image, and is crude approach to full + // range scale + + *pImPos |= *((DWORD*)&col); // or the bits into the prev. nulled alpha + + wrd >>= 4; // move next bits to lowest 4 + + pImPos++; // move to next pixel in the row + } + } +} + +static BYTE gBits[4][4]; +static WORD gAlphas[8]; +static Color8888 gACol[4][4]; + +inline void DecodeAlpha3BitLinear(DWORD * pImPos, DXTAlphaBlock3BitLinear * pAlphaBlock, + int width, DWORD alphazero) +{ + gAlphas[0] = pAlphaBlock->alpha0; + gAlphas[1] = pAlphaBlock->alpha1; + + // 8-alpha or 6-alpha block? + if (gAlphas[0] > gAlphas[1]) + { + // 8-alpha block: derive the other 6 alphas. + // 000 = alpha_0, 001 = alpha_1, others are interpolated + gAlphas[2] = (WORD) ((6 * gAlphas[0] + gAlphas[1]) / 7); // Bit code 010 + gAlphas[3] = (WORD) ((5 * gAlphas[0] + 2 * gAlphas[1]) / 7); // Bit code 011 + gAlphas[4] = (WORD) ((4 * gAlphas[0] + 3 * gAlphas[1]) / 7); // Bit code 100 + gAlphas[5] = (WORD) ((3 * gAlphas[0] + 4 * gAlphas[1]) / 7); // Bit code 101 + gAlphas[6] = (WORD) ((2 * gAlphas[0] + 5 * gAlphas[1]) / 7); // Bit code 110 + gAlphas[7] = (WORD) (( gAlphas[0] + 6 * gAlphas[1]) / 7); // Bit code 111 + } + else + { + // 6-alpha block: derive the other alphas. + // 000 = alpha_0, 001 = alpha_1, others are interpolated + gAlphas[2] = (WORD) ((4 * gAlphas[0] + gAlphas[1]) / 5); // Bit code 010 + gAlphas[3] = (WORD) ((3 * gAlphas[0] + 2 * gAlphas[1]) / 5); // Bit code 011 + gAlphas[4] = (WORD) ((2 * gAlphas[0] + 3 * gAlphas[1]) / 5); // Bit code 100 + gAlphas[5] = (WORD) (( gAlphas[0] + 4 * gAlphas[1]) / 5); // Bit code 101 + gAlphas[6] = 0; // Bit code 110 + gAlphas[7] = 255; // Bit code 111 + } + + // Decode 3-bit fields into array of 16 BYTES with same value + + // first two rows of 4 pixels each: + // pRows = (Alpha3BitRows*) & (pAlphaBlock->stuff[0]); + const DWORD mask = 0x00000007; // bits = 00 00 01 11 + DWORD bits = *((DWORD*) & (pAlphaBlock->stuff[0])); + + gBits[0][0] = (BYTE) (bits & mask); + bits >>= 3; + gBits[0][1] = (BYTE) (bits & mask); + bits >>= 3; + gBits[0][2] = (BYTE) (bits & mask); + bits >>= 3; + gBits[0][3] = (BYTE) (bits & mask); + bits >>= 3; + gBits[1][0] = (BYTE) (bits & mask); + bits >>= 3; + gBits[1][1] = (BYTE) (bits & mask); + bits >>= 3; + gBits[1][2] = (BYTE) (bits & mask); + bits >>= 3; + gBits[1][3] = (BYTE) (bits & mask); + + // now for last two rows: + bits = *((DWORD*) & (pAlphaBlock->stuff[3])); // last 3 bytes + + gBits[2][0] = (BYTE) (bits & mask); + bits >>= 3; + gBits[2][1] = (BYTE) (bits & mask); + bits >>= 3; + gBits[2][2] = (BYTE) (bits & mask); + bits >>= 3; + gBits[2][3] = (BYTE) (bits & mask); + bits >>= 3; + gBits[3][0] = (BYTE) (bits & mask); + bits >>= 3; + gBits[3][1] = (BYTE) (bits & mask); + bits >>= 3; + gBits[3][2] = (BYTE) (bits & mask); + bits >>= 3; + gBits[3][3] = (BYTE) (bits & mask); + + // decode the codes into alpha values + int row, pix; + + for (row = 0; row < 4; ++row) + { + for (pix = 0; pix < 4; ++pix) + { + gACol[row][pix].a = (BYTE) gAlphas[gBits[row][pix]]; + + assert(gACol[row][pix].r == 0); + assert(gACol[row][pix].g == 0); + assert(gACol[row][pix].b == 0); + } + } + + // Write out alpha values to the image bits + for (row = 0; row < 4; ++row, pImPos += width - 4) + { + // pImPow += pImPos += width - 4 moves to next row down + for (pix = 0; pix < 4; ++pix) + { + // zero the alpha bits of image pixel + *pImPos &= alphazero; + *pImPos |= *((DWORD*) &(gACol[row][pix])); // or the bits into the prev. nulled alpha + pImPos++; + } + } +} + +void CDXTCImage::DecompressDXT1(int miplevel, DWORD * pdwDest) +{ + // This was hacked up pretty quick & slopily + // decompresses to 32 bit format 0xARGB + int xblocks, yblocks; +#ifdef DEBUG + if ((ddsd.dwWidth % 4) != 0) + { + Tracef("****** warning width not div by 4! %d\n", ddsd.dwWidth); + } + + if ((ddsd.dwHeight % 4) != 0) + { + Tracef("****** warning Height not div by 4! %d\n", ddsd.dwHeight); + } + + Tracef("end check\n"); +#endif + UINT nWidth = m_nWidth >> miplevel; + UINT nHeight = m_nHeight >> miplevel; + + xblocks = nWidth / 4; + yblocks = nHeight / 4; + + int x, y; + DWORD * pBase = (DWORD *) pdwDest; + WORD * pPos = (WORD *) &m_bCompVector[miplevel][0];; // pos in compressed data + DWORD * pImPos; + + DXTColBlock * pBlock; + + Color8888 col_0, col_1, col_2, col_3; + WORD wrd; + + for (y = 0; y < yblocks; ++y) + { + // 8 bytes per block + pBlock = (DXTColBlock *) ((DWORD) pPos + y * xblocks * 8); + + for (x = 0; x < xblocks; ++x, ++pBlock) + { + // inline func: + GetColorBlockColors(pBlock, &col_0, &col_1, &col_2, &col_3, wrd); + + pImPos = (DWORD *) ((DWORD) pBase + x*16 + (y*4) * nWidth * 4); + DecodeColorBlock(pImPos, pBlock, nWidth, (DWORD *)&col_0, (DWORD *)&col_1, (DWORD *)&col_2, (DWORD *)&col_3); + // Set to RGB test pattern + // pImPos = (DWORD*) ((DWORD) pBase + i * 4 + j * m_nWidth * 4); + // *pImPos = ((i * 4) << 16) | ((j * 4) << 8) | ((63 - i) * 4); + + // checkerboard of only col_0 and col_1 basis colors: + // pImPos = (DWORD *) ((DWORD) pBase + i * 8 + j * m_nWidth * 8); + // *pImPos = *((DWORD *) &col_0); + // pImPos += 1 + m_nWidth; + // *pImPos = *((DWORD *) &col_1); + } + } +} + +void CDXTCImage::DecompressDXT3(int miplevel, DWORD* pdwDest) +{ + int xblocks, yblocks; +#ifdef DEBUG + if ((ddsd.dwWidth % 4) != 0) + { + Tracef("****** warning width not div by 4! %d\n", ddsd.dwWidth); + } + + if ((ddsd.dwHeight % 4) != 0) + { + Tracef("****** warning Height not div by 4! %d\n", ddsd.dwHeight); + } + + Tracef("end check\n"); +#endif + UINT nWidth = m_nWidth >> miplevel; + UINT nHeight = m_nHeight >> miplevel; + + xblocks = nWidth / 4; + yblocks = nHeight / 4; + + int x, y; + DWORD * pBase = (DWORD *) pdwDest; + WORD * pPos = (WORD *) &m_bCompVector[miplevel][0]; // pos in compressed data + DWORD * pImPos; // pos in decompressed data + + DXTColBlock * pBlock; + DXTAlphaBlockExplicit * pAlphaBlock; + + Color8888 col_0, col_1, col_2, col_3; + WORD wrd; + + // fill alphazero with appropriate value to zero out alpha when + // alphazero is ANDed with the image color 32 bit DWORD: + col_0.a = 0; + col_0.r = col_0.g = col_0.b = 0xff; + + DWORD alphazero = *((DWORD *) &col_0); + + for (y = 0; y < yblocks; ++y) + { + // 8 bytes per block + // 1 block for alpha, 1 block for color + pBlock = (DXTColBlock *) ((DWORD) (pPos + y * xblocks * 16)); + + for (x = 0; x < xblocks; ++x, ++pBlock) + { + // inline + // Get alpha block + pAlphaBlock = (DXTAlphaBlockExplicit *) pBlock; + + // inline func: + // Get color block & colors + pBlock++; + GetColorBlockColors(pBlock, &col_0, &col_1, &col_2, &col_3, wrd); + + // Decode the color block into the bitmap bits + // inline func: + pImPos = (DWORD *) ((DWORD) (pBase + x * 16 + (y * 4) * nWidth * 4)); + + DecodeColorBlock(pImPos, + pBlock, + nWidth, + (DWORD *) &col_0, (DWORD *) &col_1, (DWORD *) &col_2, (DWORD *) &col_3); + + // Overwrite the previous alpha bits with the alpha block + // info + // inline func: + DecodeAlphaExplicit(pImPos, pAlphaBlock, nWidth, alphazero); + } + } +} + +void CDXTCImage::DecompressDXT5(int level, DWORD * pdwDest) +{ + int xblocks, yblocks; +#ifdef DEBUG + if ((ddsd.dwWidth % 4) != 0) + { + Tracef("****** warning width not div by 4! %d\n", ddsd.dwWidth); + } + + if ((ddsd.dwHeight % 4) != 0) + { + Tracef("****** warning Height not div by 4! %d\n", ddsd.dwHeight); + } + + Tracef("end check\n"); +#endif + UINT nWidth = m_nWidth >> level; + UINT nHeight = m_nHeight >> level; + + xblocks = nWidth / 4; + yblocks = nHeight / 4; + + int x, y; + + DWORD * pBase = (DWORD *) pdwDest; + WORD * pPos = pPos = (WORD *) &m_bCompVector[level][0]; // pos in compressed data + DWORD * pImPos; // pos in decompressed data + + DXTColBlock * pBlock; + DXTAlphaBlock3BitLinear * pAlphaBlock; + + Color8888 col_0, col_1, col_2, col_3; + WORD wrd; + + // fill alphazero with appropriate value to zero out alpha when + // alphazero is ANDed with the image color 32 bit DWORD: + col_0.a = 0; + col_0.r = col_0.g = col_0.b = 0xff; + DWORD alphazero = *((DWORD *) &col_0); + + //////////////////////////////// + // Tracef("blocks: x: %d y: %d\n", xblocks, yblocks); + for (y = 0; y < yblocks; ++y) + { + // 8 bytes per block + // 1 block for alpha, 1 block for color + pBlock = (DXTColBlock*) ((DWORD) (pPos + y * xblocks * 16)); + + for (x = 0; x < xblocks; ++x, ++pBlock) + { + // inline + // Get alpha block + pAlphaBlock = (DXTAlphaBlock3BitLinear*) pBlock; + + // inline func: + // Get color block & colors + pBlock++; + + // Tracef("pBlock: 0x%.8x\n", pBlock); + GetColorBlockColors(pBlock, &col_0, &col_1, &col_2, &col_3, wrd); + + // Decode the color block into the bitmap bits + // inline func: + pImPos = (DWORD *) ((DWORD) (pBase + x * 16 + (y * 4) * nWidth * 4)); + + //DecodeColorBlock(pImPos, pBlock, nWidth, (DWORD *)&col_0, (DWORD *)&col_1, (DWORD *)&col_2, (DWORD *)&col_3); + DecodeColorBlock(pImPos, pBlock, nWidth, (DWORD *)&col_0, (DWORD *)&col_1, (DWORD *)&col_2, (DWORD *)&col_3); + + // Overwrite the previous alpha bits with the alpha block + // info + DecodeAlpha3BitLinear(pImPos, pAlphaBlock, nWidth, alphazero); + } + } +} // dxt5 + +void CDXTCImage::DecompressARGB(int level, DWORD * pdwDest) +{ + UINT lPitch = m_lPitch >> (level * 2); + memcpy(pdwDest, &m_bCompVector[level][0], lPitch); +} +/* +typedef struct _DDSURFACEDESC2 { +DWORD dwSize; +DWORD dwFlags; +DWORD dwHeight; +DWORD dwWidth; +union +{ +LONG lPitch; +DWORD dwLinearSize; +} DUMMYUNIONNAMEN(1); +DWORD dwBackBufferCount; +union +{ +DWORD dwMipMapCount; +DWORD dwRefreshRate; +} DUMMYUNIONNAMEN(2); +DWORD dwAlphaBitDepth; +DWORD dwReserved; +LPVOID lpSurface; +union +{ +DDCOLORKEY ddckCKDestOverlay; +DWORD dwEmptyFaceColor; +} DUMMYUNIONNAMEN(3); +DDCOLORKEY ddckCKDestBlt; +DDCOLORKEY ddckCKSrcOverlay; +DDCOLORKEY ddckCKSrcBlt; +DDPIXELFORMAT ddpfPixelFormat; +DDSCAPS2 ddsCaps; +DWORD dwTextureStage; +} DDSURFACEDESC2, FAR* LPDDSURFACEDESC2; +*/ + +//----------------------------------------------------------------------------- +// Name: GetNumberOfBits() +// Desc: Returns the number of bits set in a DWORD mask +// from microsoft mssdk d3dim sample "Compress" +//----------------------------------------------------------------------------- +static WORD GetNumberOfBits(DWORD dwMask) +{ + WORD wBits; + for (wBits = 0; dwMask; wBits++) + dwMask = (dwMask & (dwMask - 1)); + + return wBits; +} + +//----------------------------------------------------------------------------- +// Name: PixelFormatToString() +// Desc: Creates a string describing a pixel format. +// adapted from microsoft mssdk D3DIM Compress example +// PixelFormatToString() +//----------------------------------------------------------------------------- +VOID CDXTCImage::DecodePixelFormat(CHAR* strPixelFormat, XDDPIXELFORMAT* pxddpf) +{ + switch (pxddpf->dwFourCC) + { + case 0: + { + // This dds texture isn't compressed so write out ARGB format + WORD a = GetNumberOfBits(pxddpf->dwRGBAlphaBitMask); + WORD r = GetNumberOfBits(pxddpf->dwRBitMask); + WORD g = GetNumberOfBits(pxddpf->dwGBitMask); + WORD b = GetNumberOfBits(pxddpf->dwBBitMask); + + _snprintf(strPixelFormat, 31, "ARGB-%d%d%d%d%s", a, r, g, b, + pxddpf->dwBBitMask & DDPF_ALPHAPREMULT ? "-premul" : ""); + m_CompFormat = PF_ARGB; + } + break; + + case MAKEFOURCC('D','X','T','1'): + strncpy(strPixelFormat, "DXT1", 31); + m_CompFormat = PF_DXT1; + break; + + case MAKEFOURCC('D','X','T','2'): + strncpy(strPixelFormat, "DXT2", 31); + m_CompFormat = PF_DXT2; + break; + + case MAKEFOURCC('D','X','T','3'): + strncpy(strPixelFormat, "DXT3", 31); + m_CompFormat = PF_DXT3; + break; + + case MAKEFOURCC('D','X','T','4'): + strncpy(strPixelFormat, "DXT4", 31); + m_CompFormat = PF_DXT4; + break; + + case MAKEFOURCC('D','X','T','5'): + strncpy(strPixelFormat, "DXT5", 31); + m_CompFormat = PF_DXT5; + break; + + default: + strcpy(strPixelFormat, "Format Unknown"); + m_CompFormat = PF_UNKNOWN; + break; + } +} + +/* +// Struct to hold various timing values +struct TimingInfo +{ + LARGE_INTEGER m_start_clk; + LARGE_INTEGER m_end_clk; + + int m_nSamples; + LARGE_INTEGER m_interval_sum; // sum of all end-start, nSamples number added in + + CString m_csName; // text desc of what timed +}; + +void CDXTCImage::RunTimingSession() +{ + // Must have a dxt5 texture loaded + // No special reason - just lazy coding + // Functions called to time code are separate from non-timed + // code. It's alogorithm that counts. + ASSERT(m_pCompBytes != NULL); + ASSERT(m_pDecompBytes != NULL); // must already have allocated memory + + switch (m_CompFormat) + { + case PF_DXT1: + case PF_DXT2: + case PF_DXT3: + case PF_DXT4: + case PF_UNKNOWN: + Tracef("You must have a DXT5 texture loaded to RunTimingSession()!!\n"); + Tracef("Now I will be nasty and ASSERT(false)!\n"); + ASSERT(false); + break; + + case PF_DXT5: + Tracef("Running code timing session on DXT5 color decompress\n"); + break; + } + + LARGE_INTEGER start_clk, end_clk; + QueryPerformanceCounter(&start_clk); +#define NMETHOD 4 +#define NBATCHES 4 + int passes[NBATCHES]; + passes[0] = 1; + passes[1] = 10; + passes[2] = 30; + passes[3] = 50; + + TimingInfo method[NMETHOD][NBATCHES]; + + int i, n; + + FILE * pf = fopen("timing.txt", "wt"); + + if (pf == NULL) + { + return; + } + + fprintf(pf, "\n\n"); + + for (i = 0; i < NBATCHES; ++i) + { + Sleep(50); + fprintf(pf,"i: %d passes[i]: %d\n", i, passes[i]); + Time_Decomp5_01(passes[i], &(method[0][i])); + Time_Decomp5_02(passes[i], &(method[1][i])); + Time_Decomp5_03(passes[i], &(method[2][i])); + Time_Decomp5_04(passes[i], &(method[3][i])); + } + + QueryPerformanceCounter(&end_clk); + + // unsigned long total; + // total = (unsigned long) (end_clk - start_clk); + LARGE_INTEGER freq; + QueryPerformanceFrequency(& freq); + + fprintf(pf, "\nCounter freq = %u %d \n", freq.LowPart, freq.HighPart); + fprintf(pf, "start: %u %u end: %u %u\n", start_clk.LowPart, start_clk.HighPart, end_clk.LowPart, end_clk.HighPart); + + Tracef("\nCounter freq = %u %d \n", freq.LowPart, freq.HighPart); + Tracef("start: %u %u end: %u %u\n", start_clk.LowPart, start_clk.HighPart, end_clk.LowPart, end_clk.HighPart); + + double dur = ((double)end_clk.LowPart - (double)start_clk.LowPart) / (double)freq.LowPart; + + fprintf(pf, "Total timing session took: %u cycles = %f seconds\n", (end_clk.LowPart - start_clk.LowPart), dur); + fprintf(pf, "\n\n"); + + Tracef("Total timing session took: %u cycles = %f seconds\n", (end_clk.LowPart - start_clk.LowPart), dur); + Tracef("\n\n"); + + for (n = 0; n < NMETHOD; ++n) + { + for (i = 0; i < NBATCHES; ++i) + { + fprintf(pf, "method %d:\n", n); + fprintf(pf, " %s", method[n][i].m_csName); + fprintf(pf, " tot: %u %u\n", method[n][i].m_interval_sum.HighPart, method[n][i].m_interval_sum.LowPart); + + Tracef("method %d:\n", n); + Tracef(" %s", method[n][i].m_csName); + Tracef(" tot: %u %u\n", method[n][i].m_interval_sum.HighPart, method[n][i].m_interval_sum.LowPart); + + dur = ((double)method[n][i].m_interval_sum.LowPart) / ((double)method[n][i].m_nSamples * (double)freq.LowPart); + + fprintf(pf, " avg: %u\n", method[n][i].m_interval_sum.LowPart / method[n][i].m_nSamples); + fprintf(pf, " avg time: %f sec\n", dur); + + Tracef(" avg: %u\n", method[n][i].m_interval_sum.LowPart / method[n][i].m_nSamples); + Tracef(" avg time: %f sec\n", dur); + } + + fprintf(pf, "\n\n"); + Tracef("\n\n"); + } + + fclose(pf); + + MessageBeep(MB_OK); + //BOOL QueryPerformanceFrequency( + // LARGE_INTEGER *lpFrequency // address of current frequency + //); +} + +inline void GetColorBlockColors_m2(DXTColBlock * pBlock, Color8888 * col_0, Color8888 * col_1, + Color8888 * col_2, Color8888 * col_3, + WORD & wrd ) +{ + // method 2 + // freak variable bit structure method + // normal math + Color565 * pCol; + + pCol = (Color565*) & (pBlock->col0); + + col_0->a = 0xff; + col_0->r = pCol->nRed; + col_0->r <<= 3; // shift to full precision + col_0->g = pCol->nGreen; + col_0->g <<= 2; + col_0->b = pCol->nBlue; + col_0->b <<= 3; + + pCol = (Color565*) & (pBlock->col1); + col_1->a = 0xff; + col_1->r = pCol->nRed; + col_1->r <<= 3; // shift to full precision + col_1->g = pCol->nGreen; + col_1->g <<= 2; + col_1->b = pCol->nBlue; + col_1->b <<= 3; + + if (pBlock->col0 > pBlock->col1) + { + // Four-color block: derive the other two colors. + // 00 = color_0, 01 = color_1, 10 = color_2, 11 = color_3 + // These two bit codes correspond to the 2-bit fields + // stored in the 64-bit block. + wrd = ((WORD) col_0->r * 2 + (WORD) col_1->r) / 3; + // no +1 for rounding + // as bits have been shifted to 888 + col_2->r = (BYTE)wrd; + + wrd = ((WORD) col_0->g * 2 + (WORD) col_1->g) / 3; + col_2->g = (BYTE)wrd; + + wrd = ((WORD) col_0->b * 2 + (WORD) col_1->b) / 3; + col_2->b = (BYTE)wrd; + col_2->a = 0xff; + + wrd = ((WORD) col_0->r + (WORD) col_1->r * 2) / 3; + col_3->r = (BYTE)wrd; + + wrd = ((WORD) col_0->g + (WORD) col_1->g * 2) / 3; + col_3->g = (BYTE)wrd; + + wrd = ((WORD) col_0->b + (WORD) col_1->b * 2) / 3; + col_3->b = (BYTE)wrd; + col_3->a = 0xff; + + } + else + { + // Three-color block: derive the other color. + // 00 = color_0, 01 = color_1, 10 = color_2, + // 11 = transparent. + // These two bit codes correspond to the 2-bit fields + // stored in the 64-bit block. + + // explicit for each component, unlike some refrasts... + + // Tracef("block has alpha\n"); + wrd = ((WORD) col_0->r + (WORD) col_1->r) / 2; + col_2->r = (BYTE)wrd; + wrd = ((WORD) col_0->g + (WORD) col_1->g) / 2; + col_2->g = (BYTE)wrd; + wrd = ((WORD) col_0->b + (WORD) col_1->b) / 2; + col_2->b = (BYTE)wrd; + col_2->a = 0xff; + + col_3->r = 0x00; // random color to indicate alpha + col_3->g = 0xff; + col_3->b = 0xff; + col_3->a = 0x00; + } +} + + + +inline void GetColorBlockColors_m3(DXTColBlock * pBlock, Color8888 * col_0, Color8888 * col_1, + Color8888 * col_2, Color8888 * col_3, + WORD & wrd ) +{ + // method 3 + ////////////////////////////////////////////////////// + // super-freak variable bit structure with + // Cool Math Trick (tm) + + // Do 2/3 1/3 math BEFORE bit shift on the whole DWORD + // as the fields will NEVER carry into the next + // or overflow!! =) + + Color565 * pCol; + + pCol = (Color565*) & (pBlock->col0); + + col_0->a = 0x00; // must set to 0 to avoid overflow in DWORD add + col_0->r = pCol->nRed; + col_0->g = pCol->nGreen; + col_0->b = pCol->nBlue; + + pCol = (Color565*) & (pBlock->col1); + col_1->a = 0x00; + col_1->r = pCol->nRed; + col_1->g = pCol->nGreen; + col_1->b = pCol->nBlue; + + if (pBlock->col0 > pBlock->col1) + { + *((DWORD*)col_2) = ((*((DWORD*)col_0)) * 2 + (*((DWORD*)col_1))); + + *((DWORD*)col_3) = ((*((DWORD*)col_0)) + (*((DWORD*)col_1)) * 2); + + // now shift to appropriate precision & divide by 3. + col_2->r = ((WORD) col_2->r << 3) / (WORD)3; + col_2->g = ((WORD) col_2->g << 2) / (WORD)3; + col_2->b = ((WORD) col_2->b << 3) / (WORD)3; + + col_3->r = ((WORD) col_3->r << 3) / (WORD)3; + col_3->g = ((WORD) col_3->g << 2) / (WORD)3; + col_3->b = ((WORD) col_3->b << 3) / (WORD)3; + + col_0->a = 0xff; // now set appropriate alpha + col_1->a = 0xff; + col_2->a = 0xff; + col_3->a = 0xff; + } + else + { + *((DWORD*)col_2) = ((*((DWORD*)col_0)) + (*((DWORD*)col_1))); + + // now shift to appropriate precision & divide by 2. + // << 3) / 2 == << 2 + // << 2) / 2 == << 1 + col_2->r = ((WORD) col_2->r << 2); + col_2->g = ((WORD) col_2->g << 1); + col_2->b = ((WORD) col_2->b << 2); + + col_2->a = 0xff; + + col_3->a = 0x00; // + col_3->r = 0x00; // random color to indicate alpha + col_3->g = 0xff; + col_3->b = 0xff; + } + + // now shift orig color components + col_0->r <<= 3; + col_0->g <<= 2; + col_0->b <<= 3; + + col_1->r <<= 3; + col_1->g <<= 2; + col_1->b <<= 3; +} + + +inline void GetColorBlockColors_m4(DXTColBlock * pBlock, Color8888 * col_0, Color8888 * col_1, + Color8888 * col_2, Color8888 * col_3, + WORD & wrd ) +{ + + // m1 color extraction from 5-6-5 + // m3 color math on DWORD before bit shift to full precision + wrd = pBlock->col0; + col_0->a = 0x00; // must set to 0 to avoid possible overflow & carry to next field in DWORD add + + // extract r,g,b bits + col_0->b = (unsigned char) wrd & 0x1f; // 0x1f = 0001 1111 to mask out upper 3 bits + wrd >>= 5; + col_0->g = (unsigned char) wrd & 0x3f; // 0x3f = 0011 1111 to mask out upper 2 bits + wrd >>= 6; + col_0->r = (unsigned char) wrd & 0x1f; + + + // same for col # 2: + wrd = pBlock->col1; + col_1->a = 0x00; // must set to 0 to avoid possible overflow in DWORD add + + // extract r,g,b bits + col_1->b = (unsigned char) wrd & 0x1f; + wrd >>= 5; + col_1->g = (unsigned char) wrd & 0x3f; + wrd >>= 6; + col_1->r = (unsigned char) wrd & 0x1f; + + if (pBlock->col0 > pBlock->col1) + { + *((DWORD*)col_2) = ((*((DWORD*)col_0)) * 2 + (*((DWORD*)col_1))); + *((DWORD*)col_3) = ((*((DWORD*)col_0)) + (*((DWORD*)col_1)) * 2); + + // shift to appropriate precision & divide by 3. + col_2->r = ((WORD) col_2->r << 3) / (WORD)3; + col_2->g = ((WORD) col_2->g << 2) / (WORD)3; + col_2->b = ((WORD) col_2->b << 3) / (WORD)3; + + col_3->r = ((WORD) col_3->r << 3) / (WORD)3; + col_3->g = ((WORD) col_3->g << 2) / (WORD)3; + col_3->b = ((WORD) col_3->b << 3) / (WORD)3; + + col_0->a = 0xff; // set appropriate alpha + col_1->a = 0xff; + col_2->a = 0xff; + col_3->a = 0xff; + } + else + { + *((DWORD*)col_2) = ((*((DWORD*)col_0)) + (*((DWORD*)col_1))); + + // shift to appropriate precision & divide by 2. + // << 3) / 2 == << 2 + // << 2) / 2 == << 1 + col_2->r = ((WORD) col_2->r << 2); + col_2->g = ((WORD) col_2->g << 1); + col_2->b = ((WORD) col_2->b << 2); + + col_2->a = 0xff; + + col_3->a = 0x00; // + col_3->r = 0x00; // random color to indicate alpha + col_3->g = 0xff; + col_3->b = 0xff; + } + + // shift orig color components to full precision + col_0->r <<= 3; + col_0->g <<= 2; + col_0->b <<= 3; + + col_1->r <<= 3; + col_1->g <<= 2; + col_1->b <<= 3; +} + + +inline void GetColorBlockColors_m1(DXTColBlock * pBlock, Color8888 * col_0, Color8888 * col_1, + Color8888 * col_2, Color8888 * col_3, + WORD & wrd ) +{ + + // Method 1: + // Shifty method + wrd = pBlock->col0; + col_0->a = 0xff; + + // extract r,g,b bits + col_0->b = (unsigned char) wrd; + col_0->b <<= 3; // shift to full precision + wrd >>= 5; + col_0->g = (unsigned char) wrd; + col_0->g <<= 2; // shift to full precision + wrd >>= 6; + col_0->r = (unsigned char) wrd; + col_0->r <<= 3; // shift to full precision + + // same for col # 2: + wrd = pBlock->col1; + col_1->a = 0xff; + + // extract r,g,b bits + col_1->b = (unsigned char) wrd; + col_1->b <<= 3; // shift to full precision + wrd >>= 5; + col_1->g = (unsigned char) wrd; + col_1->g <<= 2; // shift to full precision + wrd >>= 6; + col_1->r = (unsigned char) wrd; + col_1->r <<= 3; // shift to full precision + + // use this for all but the super-freak math method + if (pBlock->col0 > pBlock->col1) + { + // Four-color block: derive the other two colors. + // 00 = color_0, 01 = color_1, 10 = color_2, 11 = color_3 + // These two bit codes correspond to the 2-bit fields + // stored in the 64-bit block. + + wrd = ((WORD) col_0->r * 2 + (WORD) col_1->r) / 3; + // no +1 for rounding + // as bits have been shifted to 888 + col_2->r = (BYTE)wrd; + + wrd = ((WORD) col_0->g * 2 + (WORD) col_1->g) / 3; + col_2->g = (BYTE)wrd; + + wrd = ((WORD) col_0->b * 2 + (WORD) col_1->b) / 3; + col_2->b = (BYTE)wrd; + col_2->a = 0xff; + + wrd = ((WORD) col_0->r + (WORD) col_1->r * 2) / 3; + col_3->r = (BYTE)wrd; + + wrd = ((WORD) col_0->g + (WORD) col_1->g * 2) / 3; + col_3->g = (BYTE)wrd; + + wrd = ((WORD) col_0->b + (WORD) col_1->b * 2) / 3; + col_3->b = (BYTE)wrd; + col_3->a = 0xff; + } + else + { + // Three-color block: derive the other color. + // 00 = color_0, 01 = color_1, 10 = color_2, + // 11 = transparent. + // These two bit codes correspond to the 2-bit fields + // stored in the 64-bit block. + + // explicit for each component, unlike some refrasts... + + // Tracef("block has alpha\n"); + + wrd = ((WORD) col_0->r + (WORD) col_1->r) / 2; + col_2->r = (BYTE)wrd; + wrd = ((WORD) col_0->g + (WORD) col_1->g) / 2; + col_2->g = (BYTE)wrd; + wrd = ((WORD) col_0->b + (WORD) col_1->b) / 2; + col_2->b = (BYTE)wrd; + col_2->a = 0xff; + + col_3->r = 0x00; // random color to indicate alpha + col_3->g = 0xff; + col_3->b = 0xff; + col_3->a = 0x00; + } +} // Get color block colors (...) + +void CDXTCImage::Time_Decomp5_01(int ntimes, TimingInfo * info) +{ + int n; + + info->m_nSamples = 0; + info->m_interval_sum.QuadPart = 0; + info->m_csName.Format("Timing decomp method 1: bit shift, for %d times\n", ntimes); + + for (n = 0; n < ntimes; n++) + { + QueryPerformanceCounter(& info->m_start_clk); + + int xblocks, yblocks; + + xblocks = m_DDSD.dwWidth / 4; + yblocks = m_DDSD.dwHeight / 4; + + int i,j; + + DWORD * pBase = (DWORD*) m_pDecompBytes; + DWORD * pImPos = (DWORD*) pBase; // pos in decompressed data + WORD * pPos = (WORD*) m_pCompBytes; // pos in compressed data + + DXTColBlock * pBlock; + DXTAlphaBlock3BitLinear * pAlphaBlock; + + Color8888 col_0, col_1, col_2, col_3; + WORD wrd; + + // fill alphazero with appropriate value to zero out alpha when + // alphazero is ANDed with the image color 32 bit DWORD: + col_0.a = 0; + col_0.r = col_0.g = col_0.b = 0xff; + DWORD alphazero = *((DWORD*) &col_0); + + // ** See DecompressDXT5 code for comments!! + for (j = 0; j < yblocks; ++j) + { + pBlock = (DXTColBlock*) ((DWORD)m_pCompBytes + j * xblocks * 16); + for (i = 0; i < xblocks; ++i, ++pBlock) + { + pAlphaBlock = (DXTAlphaBlock3BitLinear*) pBlock; + pBlock++; + + GetColorBlockColors_m1(pBlock, &col_0, &col_1, &col_2, &col_3, wrd); + + pImPos = (DWORD*)((DWORD)pBase + i*16 + (j*4) * m_nWidth * 4); + DecodeColorBlock(pImPos, pBlock, m_nWidth, (DWORD*)&col_0, (DWORD*)&col_1, + (DWORD*)&col_2, (DWORD*)&col_3); + DecodeAlpha3BitLinear(pImPos, pAlphaBlock, m_nWidth, alphazero); + } + } + + QueryPerformanceCounter(& info->m_end_clk); + + info->m_nSamples ++; + info->m_interval_sum.QuadPart += info->m_end_clk.QuadPart - info->m_start_clk.QuadPart; + } +} + + +void CDXTCImage::Time_Decomp5_02(int ntimes, TimingInfo * info) +{ + int n; + + info->m_nSamples = 0; + info->m_interval_sum.QuadPart = 0; + info->m_csName.Format("Timing decomp method 2: bit field struct, for %d times\n", ntimes); + + for (n = 0; n < ntimes; n++) + { + QueryPerformanceCounter(& info->m_start_clk); + + int xblocks, yblocks; + xblocks = m_DDSD.dwWidth / 4; + yblocks = m_DDSD.dwHeight / 4; + int i,j; + DWORD * pBase = (DWORD*) m_pDecompBytes; + DWORD * pImPos = (DWORD*) pBase; // pos in decompressed data + WORD * pPos = (WORD*) m_pCompBytes; // pos in compressed data + DXTColBlock * pBlock; + DXTAlphaBlock3BitLinear * pAlphaBlock; + Color8888 col_0, col_1, col_2, col_3; + WORD wrd; + // fill alphazero with appropriate value to zero out alpha when + // alphazero is ANDed with the image color 32 bit DWORD: + col_0.a = 0; + col_0.r = col_0.g = col_0.b = 0xff; + DWORD alphazero = *((DWORD*) &col_0); + + // ** See DecompressDXT5 code for comments!! + for (j = 0; j < yblocks; ++j) + { + pBlock = (DXTColBlock*) ((DWORD)m_pCompBytes + j * xblocks * 16); + for (i = 0; i < xblocks; ++i, ++pBlock) + { + pAlphaBlock = (DXTAlphaBlock3BitLinear*) pBlock; + pBlock++; + + GetColorBlockColors_m2(pBlock, &col_0, &col_1, &col_2, &col_3, wrd); + + pImPos = (DWORD*)((DWORD)pBase + i*16 + (j*4) * m_nWidth * 4); + DecodeColorBlock(pImPos, pBlock, m_nWidth, (DWORD*)&col_0, (DWORD*)&col_1, + (DWORD*)&col_2, (DWORD*)&col_3); + DecodeAlpha3BitLinear(pImPos, pAlphaBlock, m_nWidth, alphazero); + } + } + + QueryPerformanceCounter(& info->m_end_clk); + + info->m_nSamples ++; + info->m_interval_sum.QuadPart += info->m_end_clk.QuadPart - info->m_start_clk.QuadPart; + } +} + +void CDXTCImage::Time_Decomp5_03(int ntimes, TimingInfo * info) +{ + int n; + + info->m_nSamples = 0; + info->m_interval_sum.QuadPart = 0; + info->m_csName.Format("Timing decomp method 3: bit field struct w/ pre-shift math, for %d times\n", ntimes); + + for (n = 0; n < ntimes; n++) + { + QueryPerformanceCounter(& info->m_start_clk); + + int xblocks, yblocks; + xblocks = m_DDSD.dwWidth / 4; + yblocks = m_DDSD.dwHeight / 4; + int i,j; + DWORD * pBase = (DWORD*) m_pDecompBytes; + DWORD * pImPos = (DWORD*) pBase; // pos in decompressed data + WORD * pPos = (WORD*) m_pCompBytes; // pos in compressed data + DXTColBlock * pBlock; + DXTAlphaBlock3BitLinear * pAlphaBlock; + Color8888 col_0, col_1, col_2, col_3; + WORD wrd; + + // fill alphazero with appropriate value to zero out alpha when + // alphazero is ANDed with the image color 32 bit DWORD: + col_0.a = 0; + col_0.r = col_0.g = col_0.b = 0xff; + DWORD alphazero = *((DWORD*) &col_0); + + // ** See DecompressDXT5 code for comments!! + for (j = 0; j < yblocks; ++j) + { + pBlock = (DXTColBlock*) ((DWORD)m_pCompBytes + j * xblocks * 16); + for (i = 0; i < xblocks; ++i, ++pBlock) + { + pAlphaBlock = (DXTAlphaBlock3BitLinear*) pBlock; + pBlock++; + + GetColorBlockColors_m3(pBlock, &col_0, &col_1, &col_2, &col_3, wrd); + + pImPos = (DWORD*)((DWORD)pBase + i*16 + (j*4) * m_nWidth * 4); + DecodeColorBlock(pImPos, pBlock, m_nWidth, (DWORD*)&col_0, (DWORD*)&col_1, + (DWORD*)&col_2, (DWORD*)&col_3); + DecodeAlpha3BitLinear(pImPos, pAlphaBlock, m_nWidth, alphazero); + } + } + + QueryPerformanceCounter(& info->m_end_clk); + + info->m_nSamples ++; + info->m_interval_sum.QuadPart += info->m_end_clk.QuadPart - info->m_start_clk.QuadPart; + } +} + + +void CDXTCImage::Time_Decomp5_04(int ntimes, TimingInfo * info) +{ + int n; + + info->m_nSamples = 0; + info->m_interval_sum.QuadPart = 0; + info->m_csName.Format("Timing decomp method 4: shift extract w/ pre-shift math, for %d times\n", ntimes); + + QueryPerformanceCounter(& info->m_start_clk); + + for (n = 0; n < ntimes; n++) + { + int xblocks, yblocks; + xblocks = m_DDSD.dwWidth / 4; + yblocks = m_DDSD.dwHeight / 4; + int i,j; + DWORD * pBase = (DWORD*) m_pDecompBytes; + DWORD * pImPos = (DWORD*) pBase; // pos in decompressed data + WORD * pPos = (WORD*) m_pCompBytes; // pos in compressed data + DXTColBlock * pBlock; + DXTAlphaBlock3BitLinear * pAlphaBlock; + Color8888 col_0, col_1, col_2, col_3; + WORD wrd; + // fill alphazero with appropriate value to zero out alpha when + // alphazero is ANDed with the image color 32 bit DWORD: + col_0.a = 0; + col_0.r = col_0.g = col_0.b = 0xff; + DWORD alphazero = *((DWORD*) &col_0); + + // ** See DecompressDXT5 code for comments!! + for (j = 0; j < yblocks; ++j) + { + pBlock = (DXTColBlock*) ((DWORD)m_pCompBytes + j * xblocks * 16); + for (i = 0; i < xblocks; ++i, ++pBlock) + { + pAlphaBlock = (DXTAlphaBlock3BitLinear*) pBlock; + pBlock++; + + GetColorBlockColors_m4(pBlock, &col_0, &col_1, &col_2, &col_3, wrd); + + pImPos = (DWORD*)((DWORD)pBase + i*16 + (j*4) * m_nWidth * 4); + DecodeColorBlock(pImPos, pBlock, m_nWidth, (DWORD*)&col_0, (DWORD*)&col_1, + (DWORD*)&col_2, (DWORD*)&col_3); + DecodeAlpha3BitLinear(pImPos, pAlphaBlock, m_nWidth, alphazero); + } + } + } + + QueryPerformanceCounter(& info->m_end_clk); + + info->m_nSamples = ntimes; + info->m_interval_sum.QuadPart += info->m_end_clk.QuadPart - info->m_start_clk.QuadPart; + +} +*/ diff --git a/source/EterImageLib/DXTCImage.h b/source/EterImageLib/DXTCImage.h new file mode 100644 index 0000000..7337fd5 --- /dev/null +++ b/source/EterImageLib/DXTCImage.h @@ -0,0 +1,143 @@ +#ifndef AFX_IMAGE_DXTC_H__4B89D8D0_7857_11D4_9630_00A0C996DE3D__INCLUDED_ +#define AFX_IMAGE_DXTC_H__4B89D8D0_7857_11D4_9630_00A0C996DE3D__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include + +enum EPixFormat +{ + PF_ARGB, + PF_DXT1, + PF_DXT2, + PF_DXT3, + PF_DXT4, + PF_DXT5, + PF_UNKNOWN +}; + +#define MAX_MIPLEVELS 12 + +#ifndef DUMMYUNIONNAMEN +#if defined(__cplusplus) || !defined(NONAMELESSUNION) +#define DUMMYUNIONNAMEN(n) +#else +#define DUMMYUNIONNAMEN(n) u##n +#endif +#endif + +typedef struct _XDDPIXELFORMAT +{ + DWORD dwSize; // size of structure + DWORD dwFlags; // pixel format flags + DWORD dwFourCC; // (FOURCC code) + + union + { + DWORD dwRGBBitCount; // how many bits per pixel + DWORD dwYUVBitCount; // how many bits per pixel + DWORD dwZBufferBitDepth; // how many total bits/pixel in z buffer (including any stencil bits) + DWORD dwAlphaBitDepth; // how many bits for alpha channels + DWORD dwLuminanceBitCount; // how many bits per pixel + DWORD dwBumpBitCount; // how many bits per "buxel", total + DWORD dwPrivateFormatBitCount;// Bits per pixel of private driver formats. Only valid in texture + // format list and if DDPF_D3DFORMAT is set + } DUMMYUNIONNAMEN(1); + union + { + DWORD dwRBitMask; // mask for red bit + DWORD dwYBitMask; // mask for Y bits + DWORD dwStencilBitDepth; // how many stencil bits (note: dwZBufferBitDepth-dwStencilBitDepth is total Z-only bits) + DWORD dwLuminanceBitMask; // mask for luminance bits + DWORD dwBumpDuBitMask; // mask for bump map U delta bits + DWORD dwOperations; // DDPF_D3DFORMAT Operations + } DUMMYUNIONNAMEN(2); + union + { + DWORD dwGBitMask; // mask for green bits + DWORD dwUBitMask; // mask for U bits + DWORD dwZBitMask; // mask for Z bits + DWORD dwBumpDvBitMask; // mask for bump map V delta bits + struct + { + WORD wFlipMSTypes; // Multisample methods supported via flip for this D3DFORMAT + WORD wBltMSTypes; // Multisample methods supported via blt for this D3DFORMAT + } MultiSampleCaps; + + } DUMMYUNIONNAMEN(3); + union + { + DWORD dwBBitMask; // mask for blue bits + DWORD dwVBitMask; // mask for V bits + DWORD dwStencilBitMask; // mask for stencil bits + DWORD dwBumpLuminanceBitMask; // mask for luminance in bump map + } DUMMYUNIONNAMEN(4); + union + { + DWORD dwRGBAlphaBitMask; // mask for alpha channel + DWORD dwYUVAlphaBitMask; // mask for alpha channel + DWORD dwLuminanceAlphaBitMask;// mask for alpha channel + DWORD dwRGBZBitMask; // mask for Z channel + DWORD dwYUVZBitMask; // mask for Z channel + } DUMMYUNIONNAMEN(5); +} XDDPIXELFORMAT; + + +class CDXTCImage +{ + public: + CDXTCImage(); + virtual ~CDXTCImage(); + + void Initialize(); + void Clear(); + + public: + const BYTE * m_pbCompBufferByLevels[MAX_MIPLEVELS]; + std::vector m_bCompVector[MAX_MIPLEVELS]; + + int m_nCompSize; + int m_nCompLineSz; + + char m_strFormat[32]; + EPixFormat m_CompFormat; + + long m_lPitch; + DWORD m_dwMipMapCount; + bool m_bMipTexture; // texture has mipmaps? + DWORD m_dwFlags; + + int m_nWidth; // in pixels of uncompressed image + int m_nHeight; + + XDDPIXELFORMAT m_xddPixelFormat; + + bool LoadFromFile(const char * filename); // true if success + bool LoadFromMemory(const BYTE * c_pbMap); + bool LoadHeaderFromMemory(const BYTE * c_pbMap); + bool Copy(int miplevel, BYTE * pbDest, long lDestPitch); + + void Decompress(int miplevel, DWORD * pdwDest); + void DecompressDXT1(int miplevel, DWORD * pdwDest); + void DecompressDXT3(int miplevel, DWORD * pdwDest); + void DecompressDXT5(int miplevel, DWORD * pdwDest); + void DecompressARGB(int miplevel, DWORD * pdwDest); + + VOID DecodePixelFormat(CHAR* strPixelFormat, XDDPIXELFORMAT* pddpf); + + void Unextract(BYTE * pbDest, int iWidth, int iHeight, int iPitch); + /* + struct TimingInfo; // defined in Image_DXTC.cpp + void RunTimingSession(); // run a few methods & time the code + + // must use dxt5 texture + void Time_Decomp5_01(int ntimes, TimingInfo * info); + void Time_Decomp5_02(int ntimes, TimingInfo * info); + void Time_Decomp5_03(int ntimes, TimingInfo * info); + void Time_Decomp5_04(int ntimes, TimingInfo * info); + */ +}; + +#endif // #ifndef AFX_IMAGE_DXTC_H__4B89D8D0_7857_11D4_9630_00A0C996DE3D__INCLUDED_ diff --git a/source/EterImageLib/Image.cpp b/source/EterImageLib/Image.cpp new file mode 100644 index 0000000..716ebaa --- /dev/null +++ b/source/EterImageLib/Image.cpp @@ -0,0 +1,143 @@ +#include "StdAfx.h" + +#include +#include "Image.h" + +CImage::CImage(CImage & image) +{ + Initialize(); + + int w = image.GetWidth(); + int h = image.GetHeight(); + + Create(w, h); + + DWORD * pdwDest = GetBasePointer(); + DWORD * pdwSrc = image.GetBasePointer(); + + memcpy(pdwDest, pdwSrc, w * h * sizeof(DWORD)); +} + +void CImage::SetFileName(const char* c_szFileName) +{ + m_stFileName = c_szFileName; +} + +const std::string& CImage::GetFileNameString() +{ + return m_stFileName; +} + +void CImage::PutImage(int x, int y, CImage* pImage) +{ + assert(x >= 0 && x + pImage->GetWidth() <= GetWidth()); + assert(y >= 0 && y + pImage->GetHeight() <= GetHeight()); + + int len = pImage->GetWidth() * sizeof(DWORD); + + for (int j = 0; j < pImage->GetHeight(); ++j) + { + DWORD * pdwDest = GetLinePointer(y + j) + x; + memcpy(pdwDest, pImage->GetLinePointer(j), len); + } +} + +DWORD* CImage::GetBasePointer() +{ + assert(m_pdwColors != NULL); + return m_pdwColors; +} + +DWORD* CImage::GetLinePointer(int line) +{ + assert(m_pdwColors != NULL); + return m_pdwColors + line * m_width; +} + +int CImage::GetWidth() const +{ + assert(m_pdwColors != NULL); + return m_width; +} + +int CImage::GetHeight() const +{ + assert(m_pdwColors != NULL); + return m_height; +} + +void CImage::Clear(DWORD color) +{ + assert(m_pdwColors != NULL); + + for (int y = 0; y < m_height; ++y) + { + DWORD * colorLine = &m_pdwColors[y * m_width]; + + for (int x = 0; x < m_width; ++x) + colorLine[x] = color; + } +} + +void CImage::Create(int width, int height) +{ + Destroy(); + + m_width = width; + m_height = height; + m_pdwColors = new DWORD[m_width*m_height]; +} + +void CImage::Destroy() +{ + if (m_pdwColors) + { + delete [] m_pdwColors; + m_pdwColors = NULL; + } +} + +void CImage::Initialize() +{ + m_pdwColors = NULL; + m_width = 0; + m_height = 0; +} + +bool CImage::IsEmpty() const +{ + return (m_pdwColors == NULL) ? true : false; +} + +void CImage::FlipTopToBottom() +{ + DWORD * swap = new DWORD[m_width * m_height]; + + int row; + UINT width = GetWidth(); + UINT height = GetHeight(); + DWORD * end_row; + DWORD * start_row; + + for (row = 0; row < GetHeight() / 2; row++) + { + end_row = &(m_pdwColors[width * (height - row - 1)]); + start_row = &(m_pdwColors[width * row]); + + memcpy(swap, end_row, width * sizeof(DWORD)); + memcpy(end_row, start_row, width * sizeof(DWORD)); + memcpy(start_row, swap, width * sizeof(DWORD)); + } + + delete [] swap; +} + +CImage::CImage() +{ + Initialize(); +} + +CImage::~CImage() +{ + Destroy(); +} diff --git a/source/EterImageLib/Image.h b/source/EterImageLib/Image.h new file mode 100644 index 0000000..a9f5c3e --- /dev/null +++ b/source/EterImageLib/Image.h @@ -0,0 +1,71 @@ +#ifndef __INC_ETERIMAGELIB_IMAGE_H__ +#define __INC_ETERIMAGELIB_IMAGE_H__ + +#include +#include + +#pragma pack(push) +#pragma pack(1) +struct TGA_HEADER +{ + char idLen; // 0 + char palType; // ķƮ 1, 0 + char imgType; // ķƮ 1, 2 + WORD colorBegin; // 0 + WORD colorCount; // ķƮ 256, 0 + char palEntrySize; // ķƮ 24, 0 + WORD left; + WORD top; + WORD width; + WORD height; + char colorBits; + char desc; +}; +#define IMAGEDESC_ORIGIN_MASK 0x30 +#define IMAGEDESC_TOPLEFT 0x20 +#define IMAGEDESC_BOTLEFT 0x00 +#define IMAGEDESC_BOTRIGHT 0x10 +#define IMAGEDESC_TOPRIGHT 0x30 +#pragma pack(pop) + +class CImage +{ + public: + CImage(); + CImage(CImage & image); + + virtual ~CImage(); + + void Destroy(); + + void Create(int width, int height); + + void Clear(DWORD color = 0); + + int GetWidth() const; + int GetHeight() const; + + DWORD * GetBasePointer(); + DWORD * GetLinePointer(int line); + + void PutImage(int x, int y, CImage* pImage); + void FlipTopToBottom(); + + void SetFileName(const char* c_szFileName); + + const std::string & GetFileNameString(); + + bool IsEmpty() const; + + protected: + void Initialize(); + + protected: + DWORD * m_pdwColors; + int m_width; + int m_height; + + std::string m_stFileName; +}; + +#endif diff --git a/source/EterImageLib/StdAfx.cpp b/source/EterImageLib/StdAfx.cpp new file mode 100644 index 0000000..a710b46 --- /dev/null +++ b/source/EterImageLib/StdAfx.cpp @@ -0,0 +1,6 @@ +// stdafx.cpp : source file that includes just the standard includes +// eterImageLib.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + diff --git a/source/EterImageLib/StdAfx.h b/source/EterImageLib/StdAfx.h new file mode 100644 index 0000000..9db5822 --- /dev/null +++ b/source/EterImageLib/StdAfx.h @@ -0,0 +1,48 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__BCF68E23_E7D8_4BF3_A905_AFDBEF92B0F6__INCLUDED_) +#define AFX_STDAFX_H__BCF68E23_E7D8_4BF3_A905_AFDBEF92B0F6__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#pragma warning(disable:4786) + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +//#include + +#include +#include + +#pragma warning(push, 3) +#include +#include +#pragma warning(pop) + +inline void _TraceForImage(const char* c_szFormat, ...) +{ + va_list args; + va_start(args, c_szFormat); + + static char szBuf[1024]; + _vsnprintf(szBuf, sizeof(szBuf), c_szFormat, args); +#ifdef _DEBUG + OutputDebugString(szBuf); +#endif + va_end(args); + printf(szBuf); +} + +#pragma warning(default:4018) + +// TODO: reference additional headers your program requires here + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__BCF68E23_E7D8_4BF3_A905_AFDBEF92B0F6__INCLUDED_) diff --git a/source/EterImageLib/TGAImage.cpp b/source/EterImageLib/TGAImage.cpp new file mode 100644 index 0000000..6126139 --- /dev/null +++ b/source/EterImageLib/TGAImage.cpp @@ -0,0 +1,364 @@ +#include "StdAfx.h" + +#include + +#include "../eterBase/MappedFile.h" +#include "TGAImage.h" + +CTGAImage::CTGAImage() : m_dwFlag(0) +{ +} + +CTGAImage::~CTGAImage() +{ +} + +CTGAImage::CTGAImage(CImage &image) : m_dwFlag(0) +{ + int w = image.GetWidth(); + int h = image.GetHeight(); + + Create(w, h); + + DWORD * pdwDest = GetBasePointer(); + memcpy(pdwDest, image.GetBasePointer(), w * h * sizeof(DWORD)); + FlipTopToBottom(); +} + +void CTGAImage::Create(int width, int height) +{ + memset(&m_Header, 0, sizeof(m_Header)); + + m_Header.imgType = 2; + m_Header.width = (short) width; + m_Header.height = (short) height; + m_Header.colorBits = 32; + m_Header.desc = 0x08; // alpha channel + + CImage::Create(width, height); +} + +bool CTGAImage::LoadFromMemory(int iSize, const BYTE * c_pbMem) +{ + memcpy(&m_Header, c_pbMem, 18); + c_pbMem += 18; + iSize -= 18; + + CImage::Create(m_Header.width, m_Header.height); + + UINT hxw = m_Header.width * m_Header.height; + BYTE r, g, b, a; + DWORD i; + + DWORD * pdwDest = GetBasePointer(); + + switch (m_Header.imgType) + { + case 3: // ĸ ִ (1bytes per pixel, Ⱦ) + { + for (i = 0; i < hxw; ++i) + { + a = (char) *(c_pbMem++); + pdwDest[i] = (a << 24) | (a << 16) | (a << 8) | a; + } + } + break; + + case 2: // ȵ TGA + { + if (m_Header.colorBits == 16) // 16bit + { + for (i = 0; i < hxw; ++i) + { + WORD w; + + memcpy(&w, c_pbMem, sizeof(WORD)); + c_pbMem += sizeof(WORD); + iSize -= sizeof(WORD); + + b = (BYTE) (w & 0x1F); + g = (BYTE) ((w >> 5) & 0x1F); + r = (BYTE) ((w >> 10) & 0x1F); + + b <<= 3; + g <<= 3; + r <<= 3; + a = 0xff; + + pdwDest[i] = (a << 24) | (r << 16) | (g << 8) | b; + } + } + else if (m_Header.colorBits == 24) // 24bit + { + for (i = 0; i < hxw; ++i) + { + r = (BYTE) *(c_pbMem++); --iSize; + g = (BYTE) *(c_pbMem++); --iSize; + b = (BYTE) *(c_pbMem++); --iSize; + a = 0xff; + + pdwDest[i] = (a << 24) | (r << 16) | (g << 8) | b; + } + } + else if (m_Header.colorBits == 32) // 32bit + { + int size = GetWidth(); + size *= GetHeight() * 4; + + memcpy(pdwDest, c_pbMem, size); + c_pbMem += size; + iSize -= size; + } + } + break; + + case 10: // TGA (RLE) + { + BYTE rle; + + if (m_Header.colorBits == 24) + { + i = 0; + while (i < hxw) + { + rle = (BYTE) *(c_pbMem++); --iSize; + + if (rle < 0x80) // ȵ + { + rle++; + + while (rle) + { + b = (BYTE) *(c_pbMem++); --iSize; + g = (BYTE) *(c_pbMem++); --iSize; + r = (BYTE) *(c_pbMem++); --iSize; + a = 0xff; + pdwDest[i++] = (a << 24) | (r << 16) | (g << 8) | b; + + if (i > hxw) + { + assert(!"RLE overflow"); + printf("RLE overflow"); + return false; + } + --rle; + } + } + else + { + // + rle -= 127; + + b = (BYTE) *(c_pbMem++); --iSize; + g = (BYTE) *(c_pbMem++); --iSize; + r = (BYTE) *(c_pbMem++); --iSize; + a = 0xff; + + while (rle) + { + pdwDest[i++] = (a << 24) | (r << 16) | (g << 8) | b; + + if (i > hxw) + { + assert(!"RLE overflow"); + printf("RLE overflow"); + return false; + } + --rle; + } + } + } + } + else if (m_Header.colorBits == 32) + { + i = 0; + while (i < hxw) + { + rle = (BYTE) *(c_pbMem++); --iSize; + + if (rle < 0x80) + { + rle++; + + while (rle) + { + b = (BYTE) *(c_pbMem++); --iSize; + g = (BYTE) *(c_pbMem++); --iSize; + r = (BYTE) *(c_pbMem++); --iSize; + a = (BYTE) *(c_pbMem++); --iSize; + pdwDest[i++] = (a << 24) | (r << 16) | (g << 8) | b; + + if (i > hxw) + { + assert(!"RLE overflow"); + printf("RLE overflow"); + return false; + } + --rle; + } + } + else + { + rle -= 127; + + b = (BYTE) *(c_pbMem++); --iSize; + g = (BYTE) *(c_pbMem++); --iSize; + r = (BYTE) *(c_pbMem++); --iSize; + a = (BYTE) *(c_pbMem++); --iSize; + + while (rle) + { + pdwDest[i++] = (a << 24) | (r << 16) | (g << 8) | b; + + if (i > hxw) + { + assert(!"RLE overflow"); + printf("RLE overflow"); + return false; + } + + --rle; + } + } + } + } + } + break; + } + + if (!(m_Header.desc & 0x20)) + { + FlipTopToBottom(); + } + + return true; +} + +bool CTGAImage::LoadFromDiskFile(const char * c_szFileName) +{ + CMappedFile file; + + const BYTE * c_pbMap; + + if (!file.Create(c_szFileName, (const void **) &c_pbMap, 0, 0)) + return false; + + return LoadFromMemory(file.Size(), c_pbMap); +} + +int CTGAImage::GetRLEPixelCount(const DWORD * data) +{ + int r = 0; + DWORD pixel; + + r = 1; + + if (data >= m_pdwEndPtr) + return 0; + + pixel = *data; + + while ((r < 127) && (data < m_pdwEndPtr)) + { + if (pixel != *(++data)) + return r; + + r++; + } + + return r; +} + +int CTGAImage::GetRawPixelCount(const DWORD * data) +{ + int i = 0; + + if (data >= m_pdwEndPtr) + return 0; + + while ((data < m_pdwEndPtr) && (i < 127)) + { + int rle = GetRLEPixelCount(data); + + if (rle >= 4) + break; + + data++; + i++; + } + + return i; +} + +void CTGAImage::SetCompressed(bool isCompress) +{ + if (isCompress) + m_Header.imgType = 10; + else + m_Header.imgType = 2; +} + +void CTGAImage::SetAlphaChannel(bool isExist) +{ + if (isExist) + m_Header.desc |= 0x08; + else + m_Header.desc &= ~0x08; +} + +bool CTGAImage::SaveToDiskFile(const char* c_szFileName) +{ + FILE * fp = fopen(c_szFileName, "wb"); + + if (!fp) + return false; + + fwrite(&m_Header, 18, 1, fp); + + if (m_Header.imgType == 10) // RLE + { + DWORD * data = GetBasePointer(); + + while (data < m_pdwEndPtr) + { + int rle = GetRLEPixelCount(data); + + if (rle < 4) + { + int raw = GetRawPixelCount(data); + + if (raw == 0) + break; + + fputc(raw - 1, fp); + + while (raw) + { + fwrite(data, sizeof(DWORD), 1, fp); + data++; + raw--; + } + } + else + { + fputc((rle - 1) | 0x80, fp); + fwrite(data, sizeof(DWORD), 1, fp); + data += rle; + } + } + } + else + { + int size = GetWidth(); + size *= GetHeight() * 4; + fwrite(GetBasePointer(), size, 1, fp); + } + + fclose(fp); + return true; +} + +TGA_HEADER & CTGAImage::GetHeader() +{ + return m_Header; +} diff --git a/source/EterImageLib/TGAImage.h b/source/EterImageLib/TGAImage.h new file mode 100644 index 0000000..9b1e58c --- /dev/null +++ b/source/EterImageLib/TGAImage.h @@ -0,0 +1,37 @@ +#ifndef __INC_ETERIMAGELIB_TGAIMAGE_H__ +#define __INC_ETERIMAGELIB_TGAIMAGE_H__ + +#include "Image.h" + +class CTGAImage : public CImage +{ + public: + enum ETGAImageFlags + { + FLAG_RLE_COMPRESS = (1 << 0) + }; + + CTGAImage(); + CTGAImage(CImage &image); + virtual ~CTGAImage(); + + virtual void Create(int width, int height); + virtual bool LoadFromMemory(int iSize, const BYTE * c_pbMem); + virtual bool LoadFromDiskFile(const char * c_szFileName); + virtual bool SaveToDiskFile(const char* c_szFileName); + + void SetCompressed(bool isCompress = true); + void SetAlphaChannel(bool isExist = true); + + TGA_HEADER & GetHeader(); + protected: + int GetRawPixelCount(const DWORD * data); + int GetRLEPixelCount(const DWORD * data); + + protected: + TGA_HEADER m_Header; + DWORD m_dwFlag; + DWORD * m_pdwEndPtr; +}; + +#endif diff --git a/source/EterLib/AttributeData.cpp b/source/EterLib/AttributeData.cpp new file mode 100644 index 0000000..61e0e19 --- /dev/null +++ b/source/EterLib/AttributeData.cpp @@ -0,0 +1,200 @@ +#include "StdAfx.h" +#include "../eterBase/Utils.h" +#include "AttributeData.h" + +const char c_szAttributeDataFileHeader[] = "AttributeData"; +const int c_iAttributeDataFileHeaderLength = 13; + +/*DWORD CAttributeData::GetCollisionDataCount() const +{ + return m_CollisionDataVector.size(); +} + +BOOL CAttributeData::GetCollisionDataPointer(DWORD dwIndex, const TCollisionData ** c_ppCollisionData) const +{ + if (dwIndex >= GetCollisionDataCount()) + return FALSE; + + *c_ppCollisionData = &m_CollisionDataVector[dwIndex]; + + return TRUE; +} +*/ + +const CStaticCollisionDataVector & CAttributeData::GetCollisionDataVector() const +{ + return m_StaticCollisionDataVector; +} + +const THeightDataVector & CAttributeData::GetHeightDataVector() const +{ + return m_HeightDataVector; +} + +DWORD CAttributeData::GetHeightDataCount() const +{ + return m_HeightDataVector.size(); +} + +BOOL CAttributeData::GetHeightDataPointer(DWORD dwIndex, const THeightData ** c_ppHeightData) const +{ + if (dwIndex >= GetHeightDataCount()) + return FALSE; + + *c_ppHeightData = &m_HeightDataVector[dwIndex]; + + return TRUE; +} + +float CAttributeData::GetMaximizeRadius() +{ + return m_fMaximizeRadius; +} + +size_t CAttributeData::AddCollisionData(const CStaticCollisionData& data) +{ + m_StaticCollisionDataVector.push_back(data); + return m_StaticCollisionDataVector.size(); +} + +bool CAttributeData::OnLoad(int /*iSize*/, const void * c_pvBuf) +{ + if (!c_pvBuf) + { + // NOTE: ٸ ׷ 浹 ͸ ϴ ҽ ı ʰ Ŵ. + return true; + } + + const BYTE * c_pbBuf = static_cast (c_pvBuf); + + char szHeader[c_iAttributeDataFileHeaderLength+1]; + memcpy(szHeader, c_pbBuf, c_iAttributeDataFileHeaderLength+1); + c_pbBuf += c_iAttributeDataFileHeaderLength+1; + if (strcmp(szHeader, c_szAttributeDataFileHeader)) + return FALSE; + + DWORD dwCollisionDataCount; + DWORD dwHeightDataCount; + memcpy(&dwCollisionDataCount, c_pbBuf, sizeof(DWORD)); + c_pbBuf += sizeof(DWORD); + memcpy(&dwHeightDataCount, c_pbBuf, sizeof(DWORD)); + c_pbBuf += sizeof(DWORD); + + m_StaticCollisionDataVector.clear(); + m_StaticCollisionDataVector.resize(dwCollisionDataCount); + m_HeightDataVector.clear(); + m_HeightDataVector.resize(dwHeightDataCount); + + for (DWORD i = 0; i < dwCollisionDataCount; ++i) + { + CStaticCollisionData & rCollisionData = m_StaticCollisionDataVector[i]; + memcpy(&rCollisionData.dwType, c_pbBuf, sizeof(DWORD)); + c_pbBuf += sizeof(DWORD); + memcpy(rCollisionData.szName, c_pbBuf, 32); + c_pbBuf += 32; + memcpy(&rCollisionData.v3Position, c_pbBuf, sizeof(D3DXVECTOR3)); + c_pbBuf += sizeof(D3DXVECTOR3); + + switch(rCollisionData.dwType) + { + case COLLISION_TYPE_PLANE: + memcpy(rCollisionData.fDimensions, c_pbBuf, 2*sizeof(float)); + c_pbBuf += 2*sizeof(float); + break; + case COLLISION_TYPE_BOX: + memcpy(rCollisionData.fDimensions, c_pbBuf, 3*sizeof(float)); + c_pbBuf += 3*sizeof(float); + break; + case COLLISION_TYPE_SPHERE: + memcpy(rCollisionData.fDimensions, c_pbBuf, sizeof(float)); + c_pbBuf += sizeof(float); + break; + case COLLISION_TYPE_CYLINDER: + memcpy(rCollisionData.fDimensions, c_pbBuf, 2*sizeof(float)); + c_pbBuf += 2*sizeof(float); + break; + case COLLISION_TYPE_AABB: + memcpy(rCollisionData.fDimensions, c_pbBuf, 3*sizeof(float)); + c_pbBuf += 3*sizeof(float); + break; + case COLLISION_TYPE_OBB: + memcpy(rCollisionData.fDimensions, c_pbBuf, 3*sizeof(float)); + c_pbBuf += 3*sizeof(float); + break; + } + + memcpy(rCollisionData.quatRotation, c_pbBuf, sizeof(D3DXQUATERNION)); + c_pbBuf += sizeof(D3DXQUATERNION); + } + + for (DWORD j = 0; j < dwHeightDataCount; ++j) + { + THeightData & rHeightData = m_HeightDataVector[j]; + memcpy(rHeightData.szName, c_pbBuf, 32); + c_pbBuf += 32; + + DWORD dwPrimitiveCount; + memcpy(&dwPrimitiveCount, c_pbBuf, sizeof(DWORD)); + c_pbBuf += sizeof(DWORD); + + rHeightData.v3VertexVector.clear(); + rHeightData.v3VertexVector.resize(dwPrimitiveCount); + memcpy(&rHeightData.v3VertexVector[0], c_pbBuf, dwPrimitiveCount*sizeof(D3DXVECTOR3)); + c_pbBuf += dwPrimitiveCount*sizeof(D3DXVECTOR3); + + // Getting Maximize Radius + for (DWORD k = 0; k < rHeightData.v3VertexVector.size(); ++k) + { + m_fMaximizeRadius = fMAX(m_fMaximizeRadius, fabs(rHeightData.v3VertexVector[k].x)+50.0f); + m_fMaximizeRadius = fMAX(m_fMaximizeRadius, fabs(rHeightData.v3VertexVector[k].y)+50.0f); + m_fMaximizeRadius = fMAX(m_fMaximizeRadius, fabs(rHeightData.v3VertexVector[k].z)+50.0f); + } + // Getting Maximize Radius + } + + return true; +} + +void CAttributeData::OnClear() +{ + m_StaticCollisionDataVector.clear(); + m_HeightDataVector.clear(); +} + +bool CAttributeData::OnIsEmpty() const +{ + if (!m_StaticCollisionDataVector.empty()) + return false; + if (!m_HeightDataVector.empty()) + return false; + + return true; +} + +bool CAttributeData::OnIsType(TType type) +{ + if (CAttributeData::Type() == type) + return true; + + return CResource::OnIsType(type); +} + +CAttributeData::TType CAttributeData::Type() +{ + static TType s_type = StringToType("CAttributeData"); + return s_type; +} + +void CAttributeData::OnSelfDestruct() +{ + Clear(); +} + +CAttributeData::CAttributeData(const char * c_szFileName) : CResource(c_szFileName) +{ + m_fMaximizeRadius = 0.0f; +} + +CAttributeData::~CAttributeData() +{ +} diff --git a/source/EterLib/AttributeData.h b/source/EterLib/AttributeData.h new file mode 100644 index 0000000..fac4630 --- /dev/null +++ b/source/EterLib/AttributeData.h @@ -0,0 +1,71 @@ +#pragma once + +#include "Resource.h" +#include "Ref.h" +#include "CollisionData.h" + +typedef struct SHeightData +{ + char szName[32+1]; + std::vector v3VertexVector; +} THeightData; + +typedef std::vector THeightDataVector; + +class CAttributeData : public CResource +{ + public: + typedef CRef TRef; + + /* + enum ECollisionType + { + COLLISION_TYPE_PLANE, + COLLISION_TYPE_BOX, + COLLISION_TYPE_SPHERE, + COLLISION_TYPE_CYLINDER, + }; + + typedef struct SCollisionData + { + DWORD dwType; + char szName[32+1]; + + D3DXVECTOR3 v3Position; + float fDimensions[3]; + D3DXQUATERNION quatRotation; + } TCollisionData;*/ + + public: + static TType Type(); + + public: + CAttributeData(const char * c_szFileName); + virtual ~CAttributeData(); + + //DWORD GetCollisionDataCount() const; + //BOOL GetCollisionDataPointer(DWORD dwIndex, const TCollisionData ** c_ppCollisionData) const; + const CStaticCollisionDataVector & GetCollisionDataVector() const; + const THeightDataVector & GetHeightDataVector() const; + + size_t AddCollisionData(const CStaticCollisionData& collisionData); // return m_StaticCollisionDataVector.size(); + + DWORD GetHeightDataCount() const; + BOOL GetHeightDataPointer(DWORD dwIndex, const THeightData ** c_ppHeightData) const; + + float GetMaximizeRadius(); + + protected: + bool OnLoad(int iSize, const void * c_pvBuf); + void OnClear(); + bool OnIsEmpty() const; + bool OnIsType(TType type); + void OnSelfDestruct(); + + protected: + float m_fMaximizeRadius; + + //std::vector m_CollisionDataVector; + CStaticCollisionDataVector m_StaticCollisionDataVector; + THeightDataVector m_HeightDataVector; +}; diff --git a/source/EterLib/AttributeInstance.cpp b/source/EterLib/AttributeInstance.cpp new file mode 100644 index 0000000..3c96ddc --- /dev/null +++ b/source/EterLib/AttributeInstance.cpp @@ -0,0 +1,222 @@ +#include "StdAfx.h" +#include "../eterBase/Utils.h" +#include "AttributeInstance.h" +#include "GrpMath.h" + +CDynamicPool CAttributeInstance::ms_kPool; + +const float c_fStepSize = 50.0f; + +bool CAttributeInstance::Picking(const D3DXVECTOR3 & v, const D3DXVECTOR3 & dir, float & out_x, float & out_y) +{ + if (IsEmpty()) + return FALSE; + //fy *= -1.0f; + + bool bPicked = false; + float nx = 0; + float ny = 0; + + for (DWORD i = 0; i < m_v3HeightDataVector.size(); ++i) + for (DWORD j = 0; j < m_v3HeightDataVector[i].size(); j+=3) + { + const D3DXVECTOR3 & cv0 = m_v3HeightDataVector[i][j]; + const D3DXVECTOR3 & cv2 = m_v3HeightDataVector[i][j+1]; + const D3DXVECTOR3 & cv1 = m_v3HeightDataVector[i][j+2]; + + D3DXVECTOR3 n; + const auto vvv = (cv1 - cv0); + const auto vvv2 = (cv2 - cv0); + const auto vvv3 = (cv2 - cv1); + D3DXVec3Cross(&n,&vvv,&vvv2); + D3DXVECTOR3 x; + float t; + const auto _vv = (v - cv0); + t = - D3DXVec3Dot(&_vv,&n)/D3DXVec3Dot(&dir,&n); + + x = v+t*dir; + const auto vvv4 = (x - cv0); + const auto vvv5 = (x - cv1); + const auto vvv6 = (x - cv2); + D3DXVECTOR3 temp; + D3DXVec3Cross(&temp,&vvv,&vvv4); + if (D3DXVec3Dot(&temp,&n)<0) continue; + D3DXVec3Cross(&temp,&vvv3,&vvv5); + if (D3DXVec3Dot(&temp,&n)<0) continue; + const auto _vv_ = (cv0 - cv2); + D3DXVec3Cross(&temp,&_vv_,&vvv6); + if (D3DXVec3Dot(&temp,&n)<0) continue; + + if (bPicked) + { + if ((v.x-x.x)*(v.x-x.x)+(v.y-x.y)*(v.y-x.y)<(v.x-nx)*(v.x-nx)+(v.y-ny)*(v.y-ny)) + { + nx=x.x; + ny=x.y; + } + } + else + { + nx = x.x; + ny = x.y; + } + bPicked = true; + } + if (bPicked) + { + out_x = nx; + out_y = ny; + } + return bPicked; +} + +BOOL CAttributeInstance::GetHeight(float fx, float fy, float * pfHeight) +{ + if(IsEmpty()) + return FALSE; + + fy *= -1.0f; + + if (!IsInHeight(fx, fy)) + return FALSE; + + BOOL bFlag = FALSE; + + for (DWORD i = 0; i < m_v3HeightDataVector.size(); ++i) + for (DWORD j = 0; j < m_v3HeightDataVector[i].size(); j+=3) + { + const D3DXVECTOR3 & c_rv3Vertex0 = m_v3HeightDataVector[i][j]; + const D3DXVECTOR3 & c_rv3Vertex1 = m_v3HeightDataVector[i][j+1]; + const D3DXVECTOR3 & c_rv3Vertex2 = m_v3HeightDataVector[i][j+2]; + + if ( + fxc_rv3Vertex0.x && fx>c_rv3Vertex1.x && fx>c_rv3Vertex2.x || + fyc_rv3Vertex0.y && fy>c_rv3Vertex1.y && fy>c_rv3Vertex2.y + ) + continue; + + if (IsInTriangle2D(c_rv3Vertex0.x, c_rv3Vertex0.y, + c_rv3Vertex1.x, c_rv3Vertex1.y, + c_rv3Vertex2.x, c_rv3Vertex2.y, fx, fy)) + { + D3DXVECTOR3 v3Line1 = c_rv3Vertex1 - c_rv3Vertex0; + D3DXVECTOR3 v3Line2 = c_rv3Vertex2 - c_rv3Vertex0; + D3DXVECTOR3 v3Cross; + + D3DXVec3Cross(&v3Cross, &v3Line1, &v3Line2); + D3DXVec3Normalize(&v3Cross, &v3Cross); + + if (0.0f != v3Cross.z) + { + float fd = (v3Cross.x*c_rv3Vertex0.x + v3Cross.y*c_rv3Vertex0.y + v3Cross.z*c_rv3Vertex0.z); + float fm = (v3Cross.x*fx + v3Cross.y*fy); + *pfHeight = fMAX((fd - fm) / v3Cross.z, *pfHeight); + + bFlag = TRUE; + } + } + } + + return bFlag; +} + +CAttributeData * CAttributeInstance::GetObjectPointer() const +{ + return m_roAttributeData.GetPointer(); +} +BOOL CAttributeInstance::IsInHeight(float fx, float fy) +{ + float fdx = m_matGlobal._41 - fx; + float fdy = m_matGlobal._42 - fy; + if (sqrtf(fdx*fdx + fdy*fdy) > m_fHeightRadius) + return FALSE; + + return TRUE; +} + +void CAttributeInstance::SetObjectPointer(CAttributeData * pAttributeData) +{ + Clear(); + m_roAttributeData.SetPointer(pAttributeData); +} + +void CAttributeInstance::RefreshObject(const D3DXMATRIX & c_rmatGlobal) +{ + assert(!m_roAttributeData.IsNull()); + + m_matGlobal = c_rmatGlobal; + + // Height + m_fHeightRadius = m_roAttributeData->GetMaximizeRadius(); + + DWORD dwHeightDataCount = m_roAttributeData->GetHeightDataCount(); + m_v3HeightDataVector.clear(); + m_v3HeightDataVector.resize(dwHeightDataCount); + for (DWORD i = 0; i < dwHeightDataCount; ++i) + { + const THeightData * c_pHeightData; + if (!m_roAttributeData->GetHeightDataPointer(i, &c_pHeightData)) + continue; + + DWORD dwVertexCount = c_pHeightData->v3VertexVector.size(); + m_v3HeightDataVector[i].clear(); + m_v3HeightDataVector[i].resize(dwVertexCount); + for (DWORD j = 0; j < dwVertexCount; ++j) + { + D3DXVec3TransformCoord(&m_v3HeightDataVector[i][j], &c_pHeightData->v3VertexVector[j], &m_matGlobal); + } + } +} + +const char * CAttributeInstance::GetDataFileName() const +{ + return m_roAttributeData->GetFileName(); +} + +void CAttributeInstance::CreateSystem(UINT uCapacity) +{ + ms_kPool.Create(uCapacity); +} + +void CAttributeInstance::DestroySystem() +{ + ms_kPool.Destroy(); +} + +CAttributeInstance* CAttributeInstance::New() +{ + return ms_kPool.Alloc(); +} + +void CAttributeInstance::Delete(CAttributeInstance* pkInst) +{ + ms_kPool.Free(pkInst); +} + +BOOL CAttributeInstance::IsEmpty() const +{ + if (!m_v3HeightDataVector.empty()) + return FALSE; + + return TRUE; +} + +void CAttributeInstance::Clear() +{ + m_fHeightRadius = 0.0f; + m_fCollisionRadius = 0.0f; + D3DXMatrixIdentity(&m_matGlobal); + + m_v3HeightDataVector.clear(); + + m_roAttributeData.SetPointer(NULL); +} + +CAttributeInstance::CAttributeInstance() +{ +} +CAttributeInstance::~CAttributeInstance() +{ +} diff --git a/source/EterLib/AttributeInstance.h b/source/EterLib/AttributeInstance.h new file mode 100644 index 0000000..22b3914 --- /dev/null +++ b/source/EterLib/AttributeInstance.h @@ -0,0 +1,66 @@ +#pragma once + +#include +#include "AttributeData.h" +#include "Pool.h" + +class CAttributeInstance +{ + public: + CAttributeInstance(); + virtual ~CAttributeInstance(); + + void Clear(); + BOOL IsEmpty() const; + + const char * GetDataFileName() const; + + // NOTE : Object + void SetObjectPointer(CAttributeData * pAttributeData); + void RefreshObject(const D3DXMATRIX & c_rmatGlobal); + CAttributeData * GetObjectPointer() const; + + bool Picking(const D3DXVECTOR3 & v, const D3DXVECTOR3 & dir, float & out_x, float & out_y); + + BOOL IsInHeight(float fx, float fy); + BOOL GetHeight(float fx, float fy, float * pfHeight); + + BOOL IsHeightData() const; + + protected: + void SetGlobalMatrix(const D3DXMATRIX & c_rmatGlobal); + void SetGlobalPosition(const D3DXVECTOR3 & c_rv3Position); + + protected: + float m_fCollisionRadius; + float m_fHeightRadius; + + D3DXMATRIX m_matGlobal; + + std::vector< std::vector > m_v3HeightDataVector; + + CAttributeData::TRef m_roAttributeData; + + /* + BOOL m_isHeightCached; + struct SHeightCacheData + { + float fxMin; + float fyMin; + float fxMax; + float fyMax; + DWORD dwxStep; + DWORD dwyStep; + std::vector kVec_fHeight; + } m_kHeightCacheData; + */ + + public: + static void CreateSystem(UINT uCapacity); + static void DestroySystem(); + + static CAttributeInstance* New(); + static void Delete(CAttributeInstance* pkInst); + + static CDynamicPool ms_kPool; +}; diff --git a/source/EterLib/BlockTexture.cpp b/source/EterLib/BlockTexture.cpp new file mode 100644 index 0000000..cede005 --- /dev/null +++ b/source/EterLib/BlockTexture.cpp @@ -0,0 +1,183 @@ +#include "StdAfx.h" +#include "BlockTexture.h" +#include "GrpBase.h" +#include "GrpDib.h" +#include "../eterbase/Stl.h" +#include "../eterlib/StateManager.h" + +void CBlockTexture::SetClipRect(const RECT & c_rRect) +{ + m_bClipEnable = TRUE; + m_clipRect = c_rRect; +} + +void CBlockTexture::Render(int ix, int iy) +{ + int isx = ix + m_rect.left; + int isy = iy + m_rect.top; + int iex = ix + m_rect.left + m_dwWidth; + int iey = iy + m_rect.top + m_dwHeight; + + float su = 0.0f; + float sv = 0.0f; + float eu = 1.0f; + float ev = 1.0f; + + if (m_bClipEnable) + { + if (isx > m_clipRect.right) + return; + if (iex < m_clipRect.left) + return; + + if (isy > m_clipRect.bottom) + return; + if (iey < m_clipRect.top) + return; + + if (m_clipRect.left > isx) + { + int idx = m_clipRect.left - isx; + isx += idx; + su += float(idx) / float(m_dwWidth); + } + if (iex > m_clipRect.right) + { + int idx = iex - m_clipRect.right; + iex -= idx; + eu -= float(idx) / float(m_dwWidth); + } + + if (m_clipRect.top > isy) + { + int idy = m_clipRect.top - isy; + isy += idy; + sv += float(idy) / float(m_dwHeight); + } + if (iey > m_clipRect.bottom) + { + int idy = iey - m_clipRect.bottom; + iey -= idy; + ev -= float(idy) / float(m_dwHeight); + } + } + + TPDTVertex vertices[4]; + vertices[0].position.x = isx - 0.5f; + vertices[0].position.y = isy - 0.5f; + vertices[0].position.z = 0.0f; + vertices[0].texCoord = TTextureCoordinate(su, sv); + vertices[0].diffuse = 0xffffffff; + + vertices[1].position.x = iex - 0.5f; + vertices[1].position.y = isy - 0.5f; + vertices[1].position.z = 0.0f; + vertices[1].texCoord = TTextureCoordinate(eu, sv); + vertices[1].diffuse = 0xffffffff; + + vertices[2].position.x = isx - 0.5f; + vertices[2].position.y = iey - 0.5f; + vertices[2].position.z = 0.0f; + vertices[2].texCoord = TTextureCoordinate(su, ev); + vertices[2].diffuse = 0xffffffff; + + vertices[3].position.x = iex - 0.5f; + vertices[3].position.y = iey - 0.5f; + vertices[3].position.z = 0.0f; + vertices[3].texCoord = TTextureCoordinate(eu, ev); + vertices[3].diffuse = 0xffffffff; + + if (CGraphicBase::SetPDTStream(vertices, 4)) + { + CGraphicBase::SetDefaultIndexBuffer(CGraphicBase::DEFAULT_IB_FILL_RECT); + + STATEMANAGER.SetTexture(0, m_lpd3dTexture); + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_TEX1|D3DFVF_DIFFUSE); + STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 4, 0, 2); + } +} + +void CBlockTexture::InvalidateRect(const RECT & c_rsrcRect) +{ + RECT dstRect = m_rect; + if (c_rsrcRect.right < dstRect.left || + c_rsrcRect.left > dstRect.right || + c_rsrcRect.bottom < dstRect.top || + c_rsrcRect.top > dstRect.bottom) + { + Tracef("InvalidateRect() - Strange rect"); + return; + } + + + // DIBBAR_LONGSIZE_BUGFIX + const RECT clipRect = { + max(c_rsrcRect.left - dstRect.left, 0), + max(c_rsrcRect.top - dstRect.top, 0), + min(c_rsrcRect.right - dstRect.left, dstRect.right - dstRect.left), + min(c_rsrcRect.bottom - dstRect.top, dstRect.bottom - dstRect.top), + }; + // END_OF_DIBBAR_LONGSIZE_BUGFIX + + + DWORD * pdwSrc; + pdwSrc = (DWORD *)m_pDIB->GetPointer(); + pdwSrc += dstRect.left + dstRect.top*m_pDIB->GetWidth(); + + D3DLOCKED_RECT lockedRect; + if (FAILED(m_lpd3dTexture->LockRect(0, &lockedRect, &clipRect, 0))) + { + Tracef("InvalidateRect() - Failed to LockRect"); + return; + } + + int iclipWidth = clipRect.right - clipRect.left; + int iclipHeight = clipRect.bottom - clipRect.top; + DWORD * pdwDst = (DWORD *)lockedRect.pBits; + DWORD dwDstWidth = lockedRect.Pitch>>2; + DWORD dwSrcWidth = m_pDIB->GetWidth(); + for (int i = 0; i < iclipHeight; ++i) + { + for (int i = 0; i < iclipWidth; ++i) + { + if (pdwSrc[i]) + pdwDst[i] = pdwSrc[i] | 0xff000000; + else + pdwDst[i] = 0; + } + pdwDst += dwDstWidth; + pdwSrc += dwSrcWidth; + } + + m_lpd3dTexture->UnlockRect(0); +} + +bool CBlockTexture::Create(CGraphicDib * pDIB, const RECT & c_rRect, DWORD dwWidth, DWORD dwHeight) +{ + if (FAILED(ms_lpd3dDevice->CreateTexture(dwWidth, dwHeight, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &m_lpd3dTexture))) + { + Tracef("Failed to create block texture %u, %u\n", dwWidth, dwHeight); + return false; + } + + m_pDIB = pDIB; + m_rect = c_rRect; + m_dwWidth = dwWidth; + m_dwHeight = dwHeight; + m_bClipEnable = FALSE; + + return true; +} + +CBlockTexture::CBlockTexture() +{ + m_pDIB = NULL; + m_lpd3dTexture = NULL; +} + +CBlockTexture::~CBlockTexture() +{ + safe_release(m_lpd3dTexture); + m_lpd3dTexture = NULL; +} diff --git a/source/EterLib/BlockTexture.h b/source/EterLib/BlockTexture.h new file mode 100644 index 0000000..0b747d0 --- /dev/null +++ b/source/EterLib/BlockTexture.h @@ -0,0 +1,26 @@ +#pragma once + +#include "GrpBase.h" + +class CGraphicDib; + +class CBlockTexture : public CGraphicBase +{ + public: + CBlockTexture(); + virtual ~CBlockTexture(); + + bool Create(CGraphicDib * pDIB, const RECT & c_rRect, DWORD dwWidth, DWORD dwHeight); + void SetClipRect(const RECT & c_rRect); + void Render(int ix, int iy); + void InvalidateRect(const RECT & c_rsrcRect); + + protected: + CGraphicDib * m_pDIB; + RECT m_rect; + RECT m_clipRect; + BOOL m_bClipEnable; + DWORD m_dwWidth; + DWORD m_dwHeight; + LPDIRECT3DTEXTURE8 m_lpd3dTexture; +}; diff --git a/source/EterLib/Camera.cpp b/source/EterLib/Camera.cpp new file mode 100644 index 0000000..8537951 --- /dev/null +++ b/source/EterLib/Camera.cpp @@ -0,0 +1,633 @@ +// Camera.cpp: implementation of the CCamera class. +// +////////////////////////////////////////////////////////////////////// + +#include "StdAfx.h" +#include "../eterBase/Utils.h" +#include "Camera.h" + +const float c_fDefaultResistance = 0.3f; + +CCameraManager aCameraManager; // CCameraManager Instance + +void CCamera::SetCameraMaxDistance(float fMax) +{ + CAMERA_MAX_DISTANCE = fMax; +} + +float CCamera::GetTargetHeight() +{ + return m_fTarget_; +} + +void CCamera::SetTargetHeight(float fTarget) +{ + m_fTarget_=fTarget; +} + + +////////////////////////////////////////////////////////////////////////// +// CCamera +////////////////////////////////////////////////////////////////////////// + + +CCamera::CCamera() : +m_fEyeGroundHeightRatio(0.3f), +m_fTargetHeightLimitRatio(2.0f), +m_fResistance(c_fDefaultResistance), +m_isLock(false) +{ + m_fDistance = 1.0f; + m_eCameraState = CAMERA_STATE_NORMAL; + m_eCameraStatePrev = CAMERA_STATE_NORMAL; + m_ulNumScreenBuilding = 0; + + m_fPitchSum = 0.0f; + m_fRollSum = 0.0f; + + m_fTerrainCollisionRadius = 50.0f; + m_fObjectCollisionRadius = 50.0f; + + m_bDrag = false; + + m_lMousePosX = -1; + m_lMousePosY = -1; + + m_fTarget_ = CAMERA_TARGET_STANDARD; + + m_v3AngularAcceleration = D3DXVECTOR3(0.0f, 0.0f, 0.0f); + m_v3AngularVelocity = D3DXVECTOR3(0.0f, 0.0f, 0.0f); + + m_bProcessTerrainCollision = true; + + SetViewParams(D3DXVECTOR3(0.0f,0.0f,1.0f), D3DXVECTOR3(0.0f,0.0f,0.0f), D3DXVECTOR3(0.0f,1.0f,0.0f)); +} + +CCamera::~CCamera() +{ +} + +void CCamera::Lock() +{ + m_isLock = true; +} + +void CCamera::Unlock() +{ + m_isLock = false; +} + +bool CCamera::IsLock() +{ + return m_isLock; +} + +void CCamera::SetResistance(float fResistance) +{ + m_fResistance = c_fDefaultResistance * fResistance; +} + +void CCamera::Wheel(int nLen) +{ + if (IsLock()) + return; + + m_v3AngularVelocity.y = (float)(nLen) * m_fResistance; +} + +void CCamera::BeginDrag(int nMouseX, int nMouseY) +{ + if (IsLock()) + return; + + m_bDrag = true; + m_lMousePosX = nMouseX; + m_lMousePosY = nMouseY; + m_fPitchSum = 0.0f; + m_fRollSum = 0.0f; +} + +bool CCamera::IsDraging() +{ + if (IsLock()) + return false; + + return m_bDrag; +} + +bool CCamera::EndDrag() +{ + if (IsLock()) + return false; + + m_bDrag = false; + + float fSum=sqrt(m_fPitchSum*m_fPitchSum+m_fRollSum*m_fRollSum); + + m_fPitchSum = 0.0f; + m_fRollSum = 0.0f; + + if (fSum<1.0f) + return false; + + return true; +} + +bool CCamera::Drag(int nMouseX, int nMouseY, LPPOINT lpReturnPoint) +{ + if (IsLock()) + return false; + + if (!m_bDrag) + { + m_lMousePosX = nMouseX; + m_lMousePosY = nMouseY; + lpReturnPoint->x = m_lMousePosX; + lpReturnPoint->y = m_lMousePosY; + return false; + } + + long lMouseX = nMouseX; + long lMouseY = nMouseY; + + float fNewPitchVelocity = (float)(lMouseY - m_lMousePosY) * m_fResistance; + float fNewRotationVelocity = (float)(lMouseX - m_lMousePosX) * m_fResistance; + + m_fPitchSum += fNewPitchVelocity; + m_fRollSum += fNewRotationVelocity; + + + if (CAMERA_STATE_CANTGOLEFT == GetCameraState()) + fNewRotationVelocity = fMAX(0.0f, fNewRotationVelocity); + if (CAMERA_STATE_CANTGORIGHT == GetCameraState()) + fNewRotationVelocity = fMIN(0.0f, fNewRotationVelocity); + if (CAMERA_STATE_CANTGODOWN == GetCameraState()) + fNewPitchVelocity = fMAX(0.0f, fNewPitchVelocity); + + m_v3AngularVelocity.x = fNewRotationVelocity; + m_v3AngularVelocity.z = fNewPitchVelocity; + + lpReturnPoint->x = m_lMousePosX; + lpReturnPoint->y = m_lMousePosY; + return true; +} + +////////////////////////////////////////////////////////////////////////// +// Update + +void CCamera::SetCameraState(eCameraState eNewCameraState) +{ + if (eNewCameraState == m_eCameraState) + return; + + m_eCameraStatePrev = m_eCameraState; + m_eCameraState = eNewCameraState; + +/* + if ((CAMERA_STATE_NORMAL == m_eCameraStatePrev)) + { + m_fDistanceBackup = m_fDistance; + m_fPitchBackup = m_fPitch; + m_fRollBackup = m_fRoll; + } + else if ((CAMERA_STATE_CANTGODOWN == m_eCameraStatePrev) && (CAMERA_STATE_CANTGODOWN == m_eCameraState) ) + { + m_v3EyeBackup = m_v3Eye; + } +*/ +} + +void CCamera::IncreaseNumSrcreenBuilding() +{ + ++m_ulNumScreenBuilding; +} + +void CCamera::ResetNumScreenBuilding() +{ + m_ulNumScreenBuilding = 0; +} + +////////////////////////////////////////////////////////////////////////// +// Property +void CCamera::SetViewParams( const D3DXVECTOR3 &v3Eye, const D3DXVECTOR3& v3Target, const D3DXVECTOR3& v3Up) +{ + if (IsLock()) + return; + + // Set attributes for the view matrix + m_v3Eye = v3Eye; + m_v3Target = v3Target; + m_v3Up = v3Up; + + SetViewMatrix(); +} + +void CCamera::SetEye(const D3DXVECTOR3 & v3Eye) +{ + if (IsLock()) + return; + + m_v3Eye = v3Eye; + + SetViewMatrix(); +} + +void CCamera::SetTarget(const D3DXVECTOR3 & v3Target) +{ + if (IsLock()) + return; + + m_v3Target = v3Target; + + SetViewMatrix(); +} + +void CCamera::SetUp(const D3DXVECTOR3 & v3Up) +{ + if (IsLock()) + return; + + m_v3Up = v3Up; + + SetViewMatrix(); +} + +void CCamera::SetViewMatrix() +{ + m_v3View = m_v3Target - m_v3Eye; + D3DXVECTOR3 v3CenterRay = -m_v3View; + CalculateRoll(); + m_fDistance = D3DXVec3Length(&m_v3View); + assert(m_fDistance >= 0); + D3DXVec3Normalize(&m_v3View , &m_v3View); + + D3DXVec3Cross(&m_v3Cross, &m_v3Up, &m_v3View); + D3DXVec3Normalize(&m_v3Cross, &m_v3Cross); + + D3DXVec3Cross(&m_v3Up, &m_v3View, &m_v3Cross); + D3DXVec3Normalize(&m_v3Up, &m_v3Up); + const auto vv = D3DXVECTOR3(0.0f, 0.0f, 1.0f); + m_fPitch = D3DXVec3Dot(&m_v3Up, &vv);// / D3DXVec2Length(&v2ViewYZ); + if (m_fPitch >= 1) + m_fPitch = 1; + else if (m_fPitch <= -1) + m_fPitch = -1; + m_fPitch = acosf(m_fPitch); + m_fPitch *= (180.0f / D3DX_PI); + if ( 0 < m_v3View.z ) + m_fPitch = -m_fPitch; + + D3DXMatrixLookAtRH(&m_matView, &m_v3Eye, &m_v3Target, &m_v3Up); + + float fDeterminantD3DMatView = D3DXMatrixfDeterminant(&m_matView); + D3DXMatrixInverse(&m_matInverseView, &fDeterminantD3DMatView, &m_matView); + + m_matBillboard = m_matInverseView; + m_matBillboard._41 = 0.0f; + m_matBillboard._42 = 0.0f; + m_matBillboard._43 = 0.0f; + + m_ViewRay.SetStartPoint(m_v3Target); + m_ViewRay.SetDirection(v3CenterRay, m_fDistance); + + m_kCameraBottomToTerrainRay.SetStartPoint(m_v3Eye); + m_kCameraFrontToTerrainRay.SetStartPoint(m_v3Eye); + m_kCameraBackToTerrainRay.SetStartPoint(m_v3Eye); + m_kCameraLeftToTerrainRay.SetStartPoint(m_v3Eye); + m_kCameraRightToTerrainRay.SetStartPoint(m_v3Eye); + m_kTargetToCameraBottomRay.SetStartPoint(m_v3Target); + + m_kCameraBottomToTerrainRay.SetDirection(-m_v3Up, 2.0f * m_fTerrainCollisionRadius); + m_kCameraFrontToTerrainRay.SetDirection(m_v3View, 4.0f * m_fTerrainCollisionRadius); + m_kCameraBackToTerrainRay.SetDirection(-m_v3View, m_fTerrainCollisionRadius); + m_kCameraLeftToTerrainRay.SetDirection(-m_v3Cross, 3.0f * m_fTerrainCollisionRadius); + m_kCameraRightToTerrainRay.SetDirection(m_v3Cross, 3.0f * m_fTerrainCollisionRadius); + const auto vv2 = (v3CenterRay - m_fTerrainCollisionRadius * m_v3Up); + m_kTargetToCameraBottomRay.SetDirection(v3CenterRay - m_fTerrainCollisionRadius * m_v3Up, D3DXVec3Length(&vv2)); + + m_kLeftObjectCollisionRay.SetStartPoint(m_v3Target); + m_kTopObjectCollisionRay.SetStartPoint(m_v3Target); + m_kRightObjectCollisionRay.SetStartPoint(m_v3Target); + m_kBottomObjectCollisionRay.SetStartPoint(m_v3Target); + const auto vv3 = (v3CenterRay + m_fObjectCollisionRadius * m_v3Cross); + const auto vv4 = (v3CenterRay - m_fObjectCollisionRadius * m_v3Cross); + const auto vv5 = (v3CenterRay + m_fObjectCollisionRadius * m_v3Up); + const auto vv6 = (v3CenterRay + m_fObjectCollisionRadius * m_v3Up); + m_kLeftObjectCollisionRay.SetDirection(v3CenterRay + m_fObjectCollisionRadius * m_v3Cross, D3DXVec3Length(&vv3)); + m_kRightObjectCollisionRay.SetDirection(v3CenterRay - m_fObjectCollisionRadius * m_v3Cross, D3DXVec3Length(&vv4)); + m_kTopObjectCollisionRay.SetDirection(v3CenterRay + m_fObjectCollisionRadius * m_v3Up, D3DXVec3Length(&vv5)); + m_kBottomObjectCollisionRay.SetDirection(v3CenterRay - m_fObjectCollisionRadius * m_v3Up, D3DXVec3Length(&vv6)); +} + +void CCamera::Move(const D3DXVECTOR3 & v3Displacement) +{ + if (IsLock()) + return; + + m_v3Eye += v3Displacement; + m_v3Target += v3Displacement; + + SetViewMatrix(); +} + +void CCamera::Zoom(float fRatio) +{ + if (IsLock()) + return; + + if (fRatio == 1.0f) + return; + + D3DXVECTOR3 v3Temp = m_v3Eye - m_v3Target; + v3Temp *= fRatio; + m_v3Eye = v3Temp + m_v3Target; + + SetViewMatrix(); +} + +void CCamera::MoveAlongView(float fDistance) +{ + if (IsLock()) + return; + + D3DXVECTOR3 v3Temp; + D3DXVec3Normalize(&v3Temp, &m_v3View); + + m_v3Eye += v3Temp * fDistance; + m_v3Target += v3Temp * fDistance; + + SetViewMatrix(); +} + +void CCamera::MoveAlongCross(float fDistance) +{ + if (IsLock()) + return; + + D3DXVECTOR3 v3Temp; + D3DXVec3Normalize(&v3Temp, &m_v3Cross); + + m_v3Eye += v3Temp * fDistance; + m_v3Target += v3Temp * fDistance; + + SetViewMatrix(); +} + +void CCamera::MoveAlongUp(FLOAT fDistance) +{ + if (IsLock()) + return; + + D3DXVECTOR3 v3Temp ; + D3DXVec3Normalize(&v3Temp, &m_v3Up); + m_v3Target += v3Temp * fDistance; + m_v3Eye += v3Temp * fDistance; + SetViewMatrix(); +} + +void CCamera::MoveLateral(float fDistance) +{ + if (IsLock()) + return; + + MoveAlongCross(fDistance); +} + +void CCamera::MoveFront(float fDistance) +{ + if (IsLock()) + return; + + D3DXVECTOR3 v3Temp = D3DXVECTOR3(m_v3View.x, m_v3View.y, 0.0f); + D3DXVec3Normalize(&v3Temp, &v3Temp); + + m_v3Eye += v3Temp * fDistance; + m_v3Target += v3Temp * fDistance; + + SetViewMatrix(); +} + +void CCamera::MoveVertical(float fDistance) +{ + if (IsLock()) + return; + + m_v3Eye.z += fDistance; + m_v3Target.z += fDistance; + + SetViewMatrix(); +} + +//void CCamera::RotateUpper(float fDegree) +//{ +// D3DXMATRIX matRot; +// D3DXMatrixRotationAxis(&matRot, &m_v3Cross, -D3DXToRadian(fDegree)); +// D3DXVec3TransformCoord(&m_v3View, &m_v3View, &matRot) ; +// D3DXVec3Cross(&m_v3Up, &m_v3View, &m_v3Cross); +// +// m_v3Target = m_v3Eye + m_v3View; +// +// SetViewMatrix() ; +//} + +void CCamera::RotateEyeAroundTarget(float fPitchDegree, float fRollDegree) +{ + if (IsLock()) + return; + + D3DXMATRIX matRot, matRotPitch, matRotRoll; + + // Ӹ Ѿ ... + if (m_fPitch + fPitchDegree > 80.0f) + { + fPitchDegree = 80.0f - m_fPitch; + } + else if( m_fPitch + fPitchDegree < -80.0f) + { + fPitchDegree = -80.0f - m_fPitch; + } + + D3DXMatrixRotationAxis(&matRotPitch, &m_v3Cross, D3DXToRadian(fPitchDegree)); + + D3DXMatrixRotationZ(&matRotRoll, -D3DXToRadian(fRollDegree)); + matRot = matRotPitch * matRotRoll; + + D3DXVECTOR3 v3Temp = m_v3Eye - m_v3Target; + D3DXVec3TransformCoord(&m_v3Eye, &v3Temp, &matRot); + m_v3Eye += m_v3Target; + + SetUp(D3DXVECTOR3(0.0f, 0.0f, 1.0f)); + + m_fRoll += fRollDegree; + + if (m_fRoll > 360.0f) + m_fRoll -= 360.0f; + else if (m_fRoll < -360.0f) + m_fRoll += 360.0f; +} + +void CCamera::RotateEyeAroundPoint(const D3DXVECTOR3 & v3Point, float fPitchDegree, float fRollDegree) +{ +// if (IsLock()) +// return; + + D3DXMATRIX matRot, matRotPitch, matRotRoll; + + D3DXMatrixRotationAxis(&matRotPitch, &m_v3Cross, D3DXToRadian(fPitchDegree)); + + D3DXMatrixRotationZ(&matRotRoll, -D3DXToRadian(fRollDegree)); + matRot = matRotPitch * matRotRoll; + + D3DXVECTOR3 v3Temp = m_v3Eye - v3Point; + D3DXVec3TransformCoord(&m_v3Eye, &v3Temp, &matRot); + m_v3Eye += v3Point; + + const auto vv2 = (v3Temp + m_v3Up); + D3DXVec3TransformCoord(&m_v3Up, &vv2, &matRot); + m_v3Up -= (m_v3Eye - v3Point); + + v3Temp = m_v3Target - v3Point; + D3DXVec3TransformCoord(&m_v3Target, &v3Temp, &matRot); + m_v3Target += v3Point; + + SetViewMatrix(); +} + +void CCamera::Pitch(const float fPitchDelta) +{ +// if (IsLock()) +// return; + + RotateEyeAroundTarget(fPitchDelta, 0.0f); +} + +void CCamera::Roll(const float fRollDelta) +{ +// if (IsLock()) +// return; + + RotateEyeAroundTarget(0.0f, fRollDelta); +} + +void CCamera::SetDistance(const float fdistance) +{ +// if (IsLock()) +// return; + + Zoom(fdistance/m_fDistance); +} + +void CCamera::CalculateRoll() +{ + D3DXVECTOR2 v2ViewXY; + v2ViewXY.x = m_v3View.x; + v2ViewXY.y = m_v3View.y; + D3DXVec2Normalize(&v2ViewXY, &v2ViewXY); + const auto vv = D3DXVECTOR2(0.0f, 1.0f); + float fDot = D3DXVec2Dot(&v2ViewXY, &vv); + if (fDot >= 1) + fDot = 1; + else if (fDot <= -1) + fDot = -1; + fDot = acosf(fDot); + fDot *= (180.0f / D3DX_PI); + float fCross = D3DXVec2CCW (&v2ViewXY, &vv); + if ( 0 > fCross) + { + fDot = -fDot; + } + + m_fRoll = fDot; + +} + +////////////////////////////////////////////////////////////////////////// +// CCameraMananger +////////////////////////////////////////////////////////////////////////// + +CCameraManager::CCameraManager() : +m_pCurrentCamera(NULL), +m_pPreviousCamera(NULL) +{ + AddCamera(DEFAULT_PERSPECTIVE_CAMERA); + AddCamera(DEFAULT_ORTHO_CAMERA); + + SetCurrentCamera(DEFAULT_PERSPECTIVE_CAMERA); +} + +CCameraManager::~CCameraManager() +{ + for (TCameraMap::iterator itor = m_CameraMap.begin(); itor != m_CameraMap.end(); ++itor) + { + delete (*itor).second; + } + m_CameraMap.clear(); +} + +CCamera * CCameraManager::GetCurrentCamera() +{ + if (!m_pCurrentCamera) + assert(false); + return m_pCurrentCamera; +} + +void CCameraManager::SetCurrentCamera(unsigned char ucCameraNum) +{ + if (m_pCurrentCamera != m_CameraMap[ucCameraNum]) + m_pPreviousCamera = m_pCurrentCamera; + + m_pCurrentCamera = m_CameraMap[ucCameraNum]; +} + +void CCameraManager::ResetToPreviousCamera() +{ + if (!m_pPreviousCamera) + assert(false); + m_pCurrentCamera = m_pPreviousCamera; + m_pPreviousCamera = NULL; +} + +bool CCameraManager::isCurrentCamera(unsigned char ucCameraNum) +{ + if (m_CameraMap[ucCameraNum] == m_pCurrentCamera) + return true; + return false; +} + +// ⽺ Լ... +bool CCameraManager::AddCamera(unsigned char ucCameraNum) +{ + if(m_CameraMap.end() != m_CameraMap.find(ucCameraNum)) + return false; + m_CameraMap.insert(TCameraMap::value_type(ucCameraNum, new CCamera)); + return true; +} + +bool CCameraManager::RemoveCamera(unsigned char ucCameraNum) +{ + TCameraMap::iterator itor = m_CameraMap.find(ucCameraNum); + if(m_CameraMap.end() == itor) + return false; + m_CameraMap.erase(itor); + return true; +} + +unsigned char CCameraManager::GetCurrentCameraNum() +{ + if (!m_pCurrentCamera) + return NO_CURRENT_CAMERA; + for (TCameraMap::iterator itor = m_CameraMap.begin(); itor != m_CameraMap.end(); ++itor) + if(m_pCurrentCamera == (*itor).second) + return (*itor).first; + return NO_CURRENT_CAMERA; +} + +bool CCameraManager::isTerrainCollisionEnable() +{ + return m_pCurrentCamera->isTerrainCollisionEnable(); +} + +void CCameraManager::SetTerrainCollision(bool bEnable) +{ + m_pCurrentCamera->SetTerrainCollision(bEnable); +} diff --git a/source/EterLib/Camera.h b/source/EterLib/Camera.h new file mode 100644 index 0000000..4ef3cea --- /dev/null +++ b/source/EterLib/Camera.h @@ -0,0 +1,285 @@ +// Camera.h: interface for the CCamera class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_CAMERA_H__C5D086BE_7A03_4246_9145_336747C47D9E__INCLUDED_) +#define AFX_CAMERA_H__C5D086BE_7A03_4246_9145_336747C47D9E__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include + +#include "../eterBase/Singleton.h" +#include "Ray.h" + +const float CAMERA_TARGET_STANDARD = 100.0f; +const float CAMERA_TARGET_FACE = 150.0f; + + +typedef enum _eCameraState_ +{ + CAMERA_STATE_NORMAL, + CAMERA_STATE_CANTGODOWN, + CAMERA_STATE_CANTGORIGHT, + CAMERA_STATE_CANTGOLEFT, + CAMERA_STATE_SCREEN_BY_BUILDING, + CAMERA_STATE_SCREEN_BY_BUILDING_AND_TOOCLOSE, +} eCameraState; + +class CCamera +{ + public: + CCamera(); + virtual ~CCamera(); + + static void SetCameraMaxDistance(float fMax); + + void Lock(); + void Unlock(); + bool IsLock(); + + void Wheel(int nWheelLen); + bool Drag(int nMouseX, int nMouseY, LPPOINT lpReturnPoint); + + bool EndDrag(); + void BeginDrag(int nMouseX, int nMouseY); + + bool IsDraging(); + + void SetResistance(float fResistance); + + private: + const CCamera & operator = (const CCamera &) ; // + CCamera (const CCamera & ) ; // + + // Camera Update + eCameraState m_eCameraState; + eCameraState m_eCameraStatePrev; + float m_fPitchBackup; + float m_fRollBackup; + float m_fDistanceBackup; + float m_fTargetZBackUp; + + D3DXVECTOR3 m_v3EyeBackup; + + unsigned long m_ulNumScreenBuilding; + +// protected: + + bool m_isLock; + + // Attributes for view matrix + D3DXVECTOR3 m_v3Eye; + D3DXVECTOR3 m_v3Target; + D3DXVECTOR3 m_v3Up; + + // m_v3View = m_v3Target - m_v3Eye + D3DXVECTOR3 m_v3View; + // m_v3Cross = Cross(m_v3Up, m_v3View) + D3DXVECTOR3 m_v3Cross; + + //ViewMatrixes + D3DXMATRIX m_matView; + D3DXMATRIX m_matInverseView; + D3DXMATRIX m_matBillboard; // Special matrix for billboarding effects + + //߰ + float m_fPitch; + float m_fRoll; + float m_fDistance; + + // ī޶ AI Ray + + // ī޶ ѷ Ray + CRay m_kCameraBottomToTerrainRay; + CRay m_kCameraFrontToTerrainRay; + CRay m_kCameraBackToTerrainRay; + CRay m_kCameraLeftToTerrainRay; + CRay m_kCameraRightToTerrainRay; + + CRay m_kTargetToCameraBottomRay; + + CRay m_ViewRay; + CRay m_kLeftObjectCollisionRay; + CRay m_kTopObjectCollisionRay; + CRay m_kRightObjectCollisionRay; + CRay m_kBottomObjectCollisionRay; + + float m_fTerrainCollisionRadius; + float m_fObjectCollisionRadius; + +// protected: + float m_fTarget_; + + float m_fEyeGroundHeightRatio; + float m_fTargetHeightLimitRatio; + float m_fPitchSum; + float m_fRollSum; + + long m_lMousePosX; + long m_lMousePosY; + + bool m_bDrag; + +// protected: + // + D3DXVECTOR3 m_v3AngularAcceleration; + D3DXVECTOR3 m_v3AngularVelocity; + + float m_fResistance; + public: + ////////////////////////////////////////////////////////////////////////// + // + ////////////////////////////////////////////////////////////////////////// + void SetAngularAcceleration(D3DXVECTOR3 v3AngularAcceleration) { m_v3AngularAcceleration = v3AngularAcceleration; } + + ////////////////////////////////////////////////////////////////////////// + // AI + ////////////////////////////////////////////////////////////////////////// + void SetTerrainCollisionRadius(float fTerrainCollisionRadius) { m_fTerrainCollisionRadius = fTerrainCollisionRadius; } + void SetObjectCollisionRadius(float fObjectCollisionRadius) { m_fObjectCollisionRadius = fObjectCollisionRadius; } + + CRay & GetViewRay() { return m_ViewRay; } + CRay & GetLeftObjectCollisionRay() { return m_kLeftObjectCollisionRay; } + CRay & GetRightObjectCollisionRay() { return m_kRightObjectCollisionRay; } + CRay & GetTopObjectCollisionRay() { return m_kTopObjectCollisionRay; } + CRay & GetBottomObjectCollisionRay() { return m_kBottomObjectCollisionRay; } + + ////////////////////////////////////////////////////////////////////////// + // Update + ////////////////////////////////////////////////////////////////////////// + void Update(); + eCameraState GetCameraState() {return m_eCameraState;} + void SetCameraState(eCameraState eNewCameraState); + void IncreaseNumSrcreenBuilding(); + void ResetNumScreenBuilding(); + unsigned long & GetNumScreenBuilding() { return m_ulNumScreenBuilding; } + + const float & GetPitchBackUp() { return m_fPitchBackup; } + const float & GetRollBackUp() { return m_fRollBackup; } + const float & GetDistanceBackUp() { return m_fDistanceBackup; } + + ////////////////////////////////////////////////////////////////////////// + // properties + ////////////////////////////////////////////////////////////////////////// + + const D3DXVECTOR3 & GetEye() const { return m_v3Eye; } + const D3DXVECTOR3 & GetTarget() const { return m_v3Target; } + const D3DXVECTOR3 & GetUp() const { return m_v3Up; } + const D3DXVECTOR3 & GetView() const { return m_v3View; } + const D3DXVECTOR3 & GetCross() const { return m_v3Cross; } + + const D3DXMATRIX & GetViewMatrix() const { return m_matView; } + const D3DXMATRIX & GetInverseViewMatrix() const { return m_matInverseView; } + const D3DXMATRIX & GetBillboardMatrix()const { return m_matBillboard; } + + void SetViewParams(const D3DXVECTOR3 & v3Eye, const D3DXVECTOR3& v3Target, const D3DXVECTOR3& v3Up ); + + void SetEye(const D3DXVECTOR3 & v3Eye); + void SetTarget(const D3DXVECTOR3 & v3Target); + void SetUp(const D3DXVECTOR3 & v3Up); + + float GetPitch() const { return m_fPitch; } + float GetRoll() const { return m_fRoll; } + float GetDistance() const { return m_fDistance; } + + void Pitch(const float fPitchDelta); //ư ִ´. + void Roll(const float fRollDelta); + void SetDistance(const float fdistance); + + ////////////////////////////////////////////////////////////////////////// + // camera movement + ////////////////////////////////////////////////////////////////////////// + + // ״ ̵... ī޶ ġ Ÿ ġ ޶. + void Move(const D3DXVECTOR3 & v3Displacement); + // .. ī޶ ġ ̵.. Ÿ ġ ... + void Zoom(float fRatio); + + // ̵.. Ÿġ ޶Ƿ ܰ ٸ... + void MoveAlongView(float fDistance); + // ī޶ ̵.. + void MoveAlongCross(float fDistance); + // ī޶ ̵... + void MoveAlongUp(float fDistance); + + // ī޶ ̵... MoveAlongCross .. + void MoveLateral(float fDistance); + // Z XY ̵.. + void MoveFront(float fDistance); + // Z( ) ̵... + void MoveVertical(float fDistance); + + // //ī޶ ġ Ű Ӹ . Ÿ ޶? + // //ȸ ƴ "(Degree)" ִ´. + // void RotateUpper(float fDegree); + + // Ÿ ߽ . Eterlib SetAroundCamera ɰ ... + // fPitchDegree (0)κ Ʒ ... + // fRollDegree Ÿ ߽ ð ... + void RotateEyeAroundTarget(float fPitchDegree, float fRollDegree); + + // ߽ ߽ . Ÿ ޶? + void RotateEyeAroundPoint(const D3DXVECTOR3 & v3Point, float fPitchDegree, float fRollDegree); + + protected: + void SetViewMatrix(); + void CalculateRoll(); + + public: + float GetTargetHeight(); + void SetTargetHeight(float fTarget); + bool isTerrainCollisionEnable() { return m_bProcessTerrainCollision; } + void SetTerrainCollision(bool bEnable) { m_bProcessTerrainCollision = bEnable; } + + private: + void ProcessTerrainCollision(); + void ProcessBuildingCollision(); + + private: + bool m_bProcessTerrainCollision; + + static float CAMERA_MIN_DISTANCE; + static float CAMERA_MAX_DISTANCE; +}; + +typedef std::map TCameraMap; + +class CCameraManager : public CSingleton +{ + public: + enum ECameraNum + { + NO_CURRENT_CAMERA, + DEFAULT_PERSPECTIVE_CAMERA, + DEFAULT_ORTHO_CAMERA, + CAMERA_MAX = 255 + }; + + CCameraManager(); + virtual ~CCameraManager(); + + bool AddCamera(unsigned char ucCameraNum); + bool RemoveCamera(unsigned char ucCameraNum); + + CCamera * GetCurrentCamera(); + void SetCurrentCamera(unsigned char ucCameraNum); + void ResetToPreviousCamera(); + + bool isCurrentCamera(unsigned char ucCameraNum); + + unsigned char GetCurrentCameraNum(); + + bool isTerrainCollisionEnable(); + void SetTerrainCollision(bool bEnable); + + private: + TCameraMap m_CameraMap; + CCamera * m_pCurrentCamera; + CCamera * m_pPreviousCamera; +}; + + +#endif // !defined(AFX_CAMERA_H__C5D086BE_7A03_4246_9145_336747C47D9E__INCLUDED_) diff --git a/source/EterLib/CollisionData.cpp b/source/EterLib/CollisionData.cpp new file mode 100644 index 0000000..96e4653 --- /dev/null +++ b/source/EterLib/CollisionData.cpp @@ -0,0 +1,840 @@ +#include "Stdafx.h" +#include "CollisionData.h" +#include "Pool.h" +#include "GrpScreen.h" +#include "GrpMath.h" +#include "lineintersect_utils.h" +#include "StateManager.h" +const float gc_fReduceMove = 0.5f; + +//const float gc_fSlideMoveSpeed = 5.0f; +/*inline D3DXVECTOR3 FitAtSpecifiedLength(const D3DXVECTOR3 & v3Vector, float length) +{ + D3DXVECTOR3 v; + D3DXVec3Normalize(&v,&v3Vector); + return v*length; +} +*/ +CDynamicPool gs_sci; +CDynamicPool gs_cci; +CDynamicPool gs_pci; +CDynamicPool gs_aci; +CDynamicPool gs_oci; + +void DestroyCollisionInstanceSystem() +{ + gs_sci.Destroy(); + gs_cci.Destroy(); + gs_pci.Destroy(); + gs_aci.Destroy(); + gs_oci.Destroy(); +} + +///////////////////////////////////////////// +// Base +CBaseCollisionInstance * CBaseCollisionInstance::BuildCollisionInstance(const CStaticCollisionData * c_pCollisionData, const D3DXMATRIX * pMat) +{ + switch(c_pCollisionData->dwType) + { + case COLLISION_TYPE_PLANE: + { + CPlaneCollisionInstance * ppci = gs_pci.Alloc(); + D3DXMATRIX matRotation; + D3DXMATRIX matTranslationLocal; + D3DXMatrixRotationQuaternion(&matRotation, &c_pCollisionData->quatRotation); + D3DXMatrixTranslation(&matTranslationLocal, c_pCollisionData->v3Position.x, c_pCollisionData->v3Position.y, c_pCollisionData->v3Position.z); + D3DXMATRIX matTransform = matRotation * matTranslationLocal * *pMat; + + TPlaneData & PlaneData = ppci->GetAttribute(); + D3DXVec3TransformCoord(&PlaneData.v3Position, &c_pCollisionData->v3Position, pMat); + float fHalfWidth = c_pCollisionData->fDimensions[0] / 2.0f; + float fHalfLength = c_pCollisionData->fDimensions[1] / 2.0f; + + PlaneData.v3QuadPosition[0].x = -fHalfWidth; + PlaneData.v3QuadPosition[0].y = -fHalfLength; + PlaneData.v3QuadPosition[0].z = 0.0f; + PlaneData.v3QuadPosition[1].x = +fHalfWidth; + PlaneData.v3QuadPosition[1].y = -fHalfLength; + PlaneData.v3QuadPosition[1].z = 0.0f; + PlaneData.v3QuadPosition[2].x = -fHalfWidth; + PlaneData.v3QuadPosition[2].y = +fHalfLength; + PlaneData.v3QuadPosition[2].z = 0.0f; + PlaneData.v3QuadPosition[3].x = +fHalfWidth; + PlaneData.v3QuadPosition[3].y = +fHalfLength; + PlaneData.v3QuadPosition[3].z = 0.0f; + for (DWORD i = 0; i < 4; ++i) + D3DXVec3TransformCoord(&PlaneData.v3QuadPosition[i], &PlaneData.v3QuadPosition[i], &matTransform); + D3DXVECTOR3 v3Line0 = PlaneData.v3QuadPosition[1] - PlaneData.v3QuadPosition[0]; + D3DXVECTOR3 v3Line1 = PlaneData.v3QuadPosition[2] - PlaneData.v3QuadPosition[0]; + D3DXVECTOR3 v3Line2 = PlaneData.v3QuadPosition[1] - PlaneData.v3QuadPosition[3]; + D3DXVECTOR3 v3Line3 = PlaneData.v3QuadPosition[2] - PlaneData.v3QuadPosition[3]; + D3DXVec3Normalize(&v3Line0, &v3Line0); + D3DXVec3Normalize(&v3Line1, &v3Line1); + D3DXVec3Normalize(&v3Line2, &v3Line2); + D3DXVec3Normalize(&v3Line3, &v3Line3); + D3DXVec3Cross(&PlaneData.v3Normal, &v3Line0, &v3Line1); + D3DXVec3Normalize(&PlaneData.v3Normal, &PlaneData.v3Normal); + + D3DXVec3Cross(&PlaneData.v3InsideVector[0], &PlaneData.v3Normal, &v3Line0 ); + D3DXVec3Cross(&PlaneData.v3InsideVector[1], &v3Line1, &PlaneData.v3Normal); + D3DXVec3Cross(&PlaneData.v3InsideVector[2], &v3Line2, &PlaneData.v3Normal); + D3DXVec3Cross(&PlaneData.v3InsideVector[3], &PlaneData.v3Normal, &v3Line3); + + return ppci; + } + break; + case COLLISION_TYPE_BOX: + assert(false && "COLLISION_TYPE_BOX not implemented"); + break; + case COLLISION_TYPE_AABB: + { + CAABBCollisionInstance * paci = gs_aci.Alloc(); + + D3DXMATRIX matTranslationLocal; + D3DXMatrixTranslation(&matTranslationLocal, c_pCollisionData->v3Position.x, c_pCollisionData->v3Position.y, c_pCollisionData->v3Position.z); + D3DXMATRIX matTransform = *pMat; + + D3DXVECTOR3 v3Pos; + v3Pos.x = matTranslationLocal._41; + v3Pos.y = matTranslationLocal._42; + v3Pos.z = matTranslationLocal._43; + + TAABBData & AABBData = paci->GetAttribute(); + AABBData.v3Min.x = v3Pos.x - c_pCollisionData->fDimensions[0]; + AABBData.v3Min.y = v3Pos.y - c_pCollisionData->fDimensions[1]; + AABBData.v3Min.z = v3Pos.z - c_pCollisionData->fDimensions[2]; + AABBData.v3Max.x = v3Pos.x + c_pCollisionData->fDimensions[0]; + AABBData.v3Max.y = v3Pos.y + c_pCollisionData->fDimensions[1]; + AABBData.v3Max.z = v3Pos.z + c_pCollisionData->fDimensions[2]; + + D3DXVec3TransformCoord(&AABBData.v3Min, &AABBData.v3Min, &matTransform); + D3DXVec3TransformCoord(&AABBData.v3Max, &AABBData.v3Max, &matTransform); + + return paci; + } + break; + case COLLISION_TYPE_OBB: + { + COBBCollisionInstance * poci = gs_oci.Alloc(); + + D3DXMATRIX matTranslationLocal; D3DXMatrixTranslation(&matTranslationLocal, c_pCollisionData->v3Position.x, c_pCollisionData->v3Position.y, c_pCollisionData->v3Position.z); + D3DXMATRIX matRotation; D3DXMatrixRotationQuaternion(&matRotation, &c_pCollisionData->quatRotation); + + D3DXMATRIX matTranslationWorld; D3DXMatrixIdentity(&matTranslationWorld); + matTranslationWorld._41 = pMat->_41; matTranslationWorld._42 = pMat->_42; matTranslationWorld._43 = pMat->_43; matTranslationWorld._44 = pMat->_44; + + D3DXVECTOR3 v3Min, v3Max; + v3Min.x = c_pCollisionData->v3Position.x - c_pCollisionData->fDimensions[0]; + v3Min.y = c_pCollisionData->v3Position.y - c_pCollisionData->fDimensions[1]; + v3Min.z = c_pCollisionData->v3Position.z - c_pCollisionData->fDimensions[2]; + v3Max.x = c_pCollisionData->v3Position.x + c_pCollisionData->fDimensions[0]; + v3Max.y = c_pCollisionData->v3Position.y + c_pCollisionData->fDimensions[1]; + v3Max.z = c_pCollisionData->v3Position.z + c_pCollisionData->fDimensions[2]; + + D3DXVec3TransformCoord(&v3Min, &v3Min, pMat); + D3DXVec3TransformCoord(&v3Max, &v3Max, pMat); + D3DXVECTOR3 v3Position = (v3Min + v3Max) * 0.5f; + + TOBBData & OBBData = poci->GetAttribute(); + OBBData.v3Min.x = v3Position.x - c_pCollisionData->fDimensions[0]; + OBBData.v3Min.y = v3Position.y - c_pCollisionData->fDimensions[1]; + OBBData.v3Min.z = v3Position.z - c_pCollisionData->fDimensions[2]; + OBBData.v3Max.x = v3Position.x + c_pCollisionData->fDimensions[0]; + OBBData.v3Max.y = v3Position.y + c_pCollisionData->fDimensions[1]; + OBBData.v3Max.z = v3Position.z + c_pCollisionData->fDimensions[2]; + + + + D3DXMATRIX matTransform = *pMat; + + D3DXMatrixIdentity(&OBBData.matRot); OBBData.matRot = *pMat; + OBBData.matRot._41 = 0; OBBData.matRot._42 = 0; OBBData.matRot._43 = 0; OBBData.matRot._44 = 1; + + + + + return poci; + } + break; + case COLLISION_TYPE_SPHERE: + { + CSphereCollisionInstance * psci = gs_sci.Alloc(); + + D3DXMATRIX matTranslationLocal; + D3DXMatrixTranslation(&matTranslationLocal, c_pCollisionData->v3Position.x, c_pCollisionData->v3Position.y, c_pCollisionData->v3Position.z); + matTranslationLocal = matTranslationLocal * *pMat; + + TSphereData & SphereData = psci->GetAttribute(); + SphereData.v3Position.x = matTranslationLocal._41; + SphereData.v3Position.y = matTranslationLocal._42; + SphereData.v3Position.z = matTranslationLocal._43; + SphereData.fRadius = c_pCollisionData->fDimensions[0]; + + return psci; + } + break; + case COLLISION_TYPE_CYLINDER: + { + CCylinderCollisionInstance * pcci = gs_cci.Alloc(); + + D3DXMATRIX matTranslationLocal; + D3DXMatrixTranslation(&matTranslationLocal, c_pCollisionData->v3Position.x, c_pCollisionData->v3Position.y, c_pCollisionData->v3Position.z); + matTranslationLocal = matTranslationLocal * *pMat; + + TCylinderData & CylinderData = pcci->GetAttribute(); + CylinderData.fRadius = c_pCollisionData->fDimensions[0]; + CylinderData.fHeight = c_pCollisionData->fDimensions[1]; + CylinderData.v3Position.x = matTranslationLocal._41; + CylinderData.v3Position.y = matTranslationLocal._42; + CylinderData.v3Position.z = matTranslationLocal._43 /*+ CylinderData.fHeight/2.0f*/; + + return pcci; + } + break; + } + assert(false && "NOT_REACHED"); + return 0; +} + +void CBaseCollisionInstance::Destroy() +{ + OnDestroy(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/*------------------------------------------------------Sphere---------------------------------------------------------------*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +TSphereData & CSphereCollisionInstance::GetAttribute() +{ + return m_attribute; +} + +const TSphereData & CSphereCollisionInstance::GetAttribute() const +{ + return m_attribute; +} + +void CSphereCollisionInstance::Render(D3DFILLMODE d3dFillMode) +{ + static CScreen s; + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xffffffff); + s.RenderSphere(NULL, m_attribute.v3Position.x, m_attribute.v3Position.y, m_attribute.v3Position.z, m_attribute.fRadius, d3dFillMode); +} + +void CSphereCollisionInstance::OnDestroy() +{ + gs_sci.Free(this); +} + +bool CSphereCollisionInstance::OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const +{ + if (square_distance_between_linesegment_and_point(s.v3LastPosition,s.v3Position,m_attribute.v3Position) < (m_attribute.fRadius+s.fRadius)*(m_attribute.fRadius+s.fRadius)) + { + // NOTE : Ÿ .. - [levites] + if (GetVector3Distance(s.v3Position, m_attribute.v3Position) < + GetVector3Distance(s.v3LastPosition, m_attribute.v3Position)) + return true; + } + + return false; +} + +bool CSphereCollisionInstance::OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const +{ + //Tracef("OnCollisionDynamicSphere\n"); + + if (square_distance_between_linesegment_and_point(s.v3LastPosition,s.v3Position,m_attribute.v3Position)<(m_attribute.fRadius+s.fRadius)*(m_attribute.fRadius+s.fRadius)) + { + return true; + } + + return false; +} + +D3DXVECTOR3 CSphereCollisionInstance::OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const +{ + const auto _vv__ = (s.v3Position - m_attribute.v3Position); + if (D3DXVec3LengthSq(&_vv__)>=(s.fRadius+m_attribute.fRadius)*(m_attribute.fRadius+s.fRadius)) + return D3DXVECTOR3(0.0f,0.0f,0.0f); + D3DXVECTOR3 c; + const auto _vv__2 = (s.v3Position - s.v3LastPosition); + const auto _vv_s_2 = D3DXVECTOR3(0.0f, 0.0f, 1.0f); + D3DXVec3Cross(&c, &_vv__2, &_vv_s_2); + + float sum = - D3DXVec3Dot(&c,&_vv__); + float mul = (s.fRadius+m_attribute.fRadius)*(s.fRadius+m_attribute.fRadius)-D3DXVec3LengthSq(&_vv__); + + if (sum*sum-4*mul<=0) + return D3DXVECTOR3(0.0f,0.0f,0.0f); + float sq = sqrt(sum*sum-4*mul); + float t1=-sum-sq, t2=-sum+sq; + t1*=0.5f; + t2*=0.5f; + + if (fabs(t1)<=fabs(t2)) + { + return (gc_fReduceMove*t1)*c; + } + else + return (gc_fReduceMove*t2)*c; + + /* + D3DXVECTOR3 p1 = s.v3Position+t1*c; + D3DXVECTOR3 p2 = s.v3Position+t2*c; + + if (D3DXVec3LengthSq(&(p2-s.v3Position))>D3DXVec3LengthSq(&(p1-s.v3Position))) + { + return p1-s.v3Position; + } + else + { + return p2-s.v3Position; + } + */ +} + +///////////////////////////////////////////// +// Plane +TPlaneData & CPlaneCollisionInstance::GetAttribute() +{ + return m_attribute; +} + +const TPlaneData & CPlaneCollisionInstance::GetAttribute() const +{ + return m_attribute; +} + +bool CPlaneCollisionInstance::OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const +{ + D3DXVECTOR3 v3SpherePosition = s.v3Position - m_attribute.v3Position; + D3DXVECTOR3 v3SphereLastPosition = s.v3LastPosition - m_attribute.v3Position; + + float fPosition1 = D3DXVec3Dot(&m_attribute.v3Normal, &v3SpherePosition); + float fPosition2 = D3DXVec3Dot(&m_attribute.v3Normal, &v3SphereLastPosition); + + if (fPosition1 >0.0f && fPosition2 < 0.0f || fPosition1 <0.0f && fPosition2 >0.0f + || (fPosition1) <= s.fRadius && fPosition1 >= -s.fRadius) + { + D3DXVECTOR3 v3QuadPosition1 = s.v3Position - m_attribute.v3QuadPosition[0]; + D3DXVECTOR3 v3QuadPosition2 = s.v3Position - m_attribute.v3QuadPosition[3]; + + if (D3DXVec3Dot(&v3QuadPosition1, &m_attribute.v3InsideVector[0]) > - s.fRadius/*0.0f*/) + if (D3DXVec3Dot(&v3QuadPosition1, &m_attribute.v3InsideVector[1]) > -s.fRadius/*0.0f*/) + if (D3DXVec3Dot(&v3QuadPosition2, &m_attribute.v3InsideVector[2]) > - s.fRadius/*0.0f*/) + if (D3DXVec3Dot(&v3QuadPosition2, &m_attribute.v3InsideVector[3]) > - s.fRadius/*0.0f*/) + { + // NOTE : Ÿ .. - [levites] + const auto _vv__3 = (s.v3Position - m_attribute.v3Position); + const auto _vv__4 = (s.v3LastPosition - m_attribute.v3Position); + if (fabs(D3DXVec3Dot(&_vv__3, &m_attribute.v3Normal)) < + fabs(D3DXVec3Dot(&_vv__4, &m_attribute.v3Normal))) + return true; + } + } + + return false; +} + +bool CPlaneCollisionInstance::OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const +{ + //Tracef("OnCollisionDynamicSphere\n"); + + D3DXVECTOR3 v3SpherePosition = s.v3Position - m_attribute.v3Position; + D3DXVECTOR3 v3SphereLastPosition = s.v3LastPosition - m_attribute.v3Position; + + float fPosition1 = D3DXVec3Dot(&m_attribute.v3Normal, &v3SpherePosition); + float fPosition2 = D3DXVec3Dot(&m_attribute.v3Normal, &v3SphereLastPosition); + + if (fPosition1 >0.0f && fPosition2 < 0.0f || fPosition1 <0.0f && fPosition2 >0.0f + || (fPosition1) <= s.fRadius && fPosition1 >= -s.fRadius) + { + D3DXVECTOR3 v3QuadPosition1 = s.v3Position - m_attribute.v3QuadPosition[0]; + D3DXVECTOR3 v3QuadPosition2 = s.v3Position - m_attribute.v3QuadPosition[3]; + + if (D3DXVec3Dot(&v3QuadPosition1, &m_attribute.v3InsideVector[0]) > - s.fRadius/*0.0f*/) + if (D3DXVec3Dot(&v3QuadPosition1, &m_attribute.v3InsideVector[1]) > -s.fRadius/*0.0f*/) + if (D3DXVec3Dot(&v3QuadPosition2, &m_attribute.v3InsideVector[2]) > - s.fRadius/*0.0f*/) + if (D3DXVec3Dot(&v3QuadPosition2, &m_attribute.v3InsideVector[3]) > - s.fRadius/*0.0f*/) + { + return true; + } + } + + return false; +} + +D3DXVECTOR3 CPlaneCollisionInstance::OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const +{ + D3DXVECTOR3 advance = s.v3Position-s.v3LastPosition; + + float d = D3DXVec3Dot(&m_attribute.v3Normal, &advance); + if (d>=-0.0001 && d<=0.0001) + return D3DXVECTOR3(0.0f,0.0f,0.0f); + const auto vv = (s.v3Position - m_attribute.v3Position); + float t= - D3DXVec3Dot(&m_attribute.v3Normal, &vv)/d; + + //D3DXVECTOR3 onplane = s.v3Position+t*advance; + + if (D3DXVec3Dot(&m_attribute.v3Normal, &advance)>=0) + { + //return m_attribute.v3Normal*((-s.fRadius+D3DXVec3Dot(&m_attribute.v3Normal, &(s.v3Position-m_attribute.v3Position)))*gc_fReduceMove); + return t*advance -s.fRadius*m_attribute.v3Normal; + } + else + { + //return m_attribute.v3Normal*((s.fRadius+D3DXVec3Dot(&m_attribute.v3Normal, &(s.v3Position-m_attribute.v3Position)))*gc_fReduceMove); + return t*advance +s.fRadius*m_attribute.v3Normal; + } + + + + /*if (D3DXVec3Dot(&m_attribute.v3Normal, &advance)>=0) + { + Tracef("%f %f\n",s.fRadius,-(D3DXVec3Dot(&m_attribute.v3Normal, &(s.v3Position-m_attribute.v3Position)))); + return m_attribute.v3Normal*((-s.fRadius+D3DXVec3Dot(&m_attribute.v3Normal, &(s.v3Position-m_attribute.v3Position)))*gc_fReduceMove); + } + else + { + Tracef("%f %f\n",(s.fRadius),(D3DXVec3Dot(&m_attribute.v3Normal, &(s.v3Position-m_attribute.v3Position)))); + return m_attribute.v3Normal*((s.fRadius+D3DXVec3Dot(&m_attribute.v3Normal, &(s.v3Position-m_attribute.v3Position)))*gc_fReduceMove); + }*/ + + + /* + D3DXVECTOR3 advance = s.v3Position-s.v3LastPosition; + D3DXVECTOR3 slide(-advance.y,advance.x,advance.z); + slide = m_attribute.v3Normal; + + D3DXVECTOR3 radius_adjust = advance; + D3DXVec3Normalize(&radius_adjust,&radius_adjust); + radius_adjust*=s.fRadius; + + float d = D3DXVec3Dot(&m_attribute.v3Normal, &slide); + if (d>=-0.0001 && d<=0.0001) + return D3DXVECTOR3(0.0f,0.0f,0.0f); + + float t= - D3DXVec3Dot(&m_attribute.v3Normal, &(s.v3Position+radius_adjust-m_attribute.v3Position)) + / d;*/ + + //D3DXVECTOR3 nextposition; + //nextposition = s.v3Position + t*slide; + //Tracef("$T %f",t); + //if (D3DXVec3Dot(&m_attribute.v3Normal, &advance)>=0) + // return (t*slide - m_attribute.v3Normal * s.fRadius)/**gc_fReduceMove*/; + //else + // return (t*slide + m_attribute.v3Normal * s.fRadius)/*gc_fReduceMove*/; + //if (D3DXVec3Dot(&m_attribute.v3Normal, &advance)>=0) + // return (t*slide + m_attribute.v3Normal * D3DXVec3Dot(&m_attribute.v3Normal,&(s.v3LastPosition-m_attribute.v3Position))/** s.fRadius*/)*gc_fReduceMove; + //else + // return (t*slide + m_attribute.v3Normal * D3DXVec3Dot(&m_attribute.v3Normal,&(s.v3LastPosition-m_attribute.v3Position))/*s.fRadius*/)*gc_fReduceMove; + // +} + +void CPlaneCollisionInstance::Render(D3DFILLMODE /*d3dFillMode*/) +{ + static CScreen s; + s.RenderBar3d(m_attribute.v3QuadPosition); +} + +void CPlaneCollisionInstance::OnDestroy() +{ + gs_pci.Free(this); +} + +///////////////////////////////////////////// +// Cylinder +TCylinderData & CCylinderCollisionInstance::GetAttribute() +{ + return m_attribute; +} + +const TCylinderData & CCylinderCollisionInstance::GetAttribute() const +{ + return m_attribute; +} + +bool CCylinderCollisionInstance::CollideCylinderVSDynamicSphere(const TCylinderData & c_rattribute, const CDynamicSphereInstance & s) const +{ + if (s.v3Position.z + s.fRadius < c_rattribute.v3Position.z) + return false; + + if (s.v3Position.z - s.fRadius > c_rattribute.v3Position.z + c_rattribute.fHeight) + return false; + + /*D3DXVECTOR2 v2curDistance(s.v3Position.x - c_rattribute.v3Position.x, s.v3Position.y - c_rattribute.v3Position.y); + float fDistance = D3DXVec2Length(&v2curDistance); + if (fDistance <= s.fRadius + c_rattribute.fRadius) + return true; + */ + + D3DXVECTOR3 oa, ob; + IntersectLineSegments(c_rattribute.v3Position, D3DXVECTOR3(c_rattribute.v3Position.x,c_rattribute.v3Position.y,c_rattribute.v3Position.z+c_rattribute.fHeight), s.v3LastPosition, s.v3Position, oa, ob); + const auto vv = (oa - ob); + return (D3DXVec3LengthSq(&vv)<=(c_rattribute.fRadius+s.fRadius)*(c_rattribute.fRadius+s.fRadius)); +} + +bool CCylinderCollisionInstance::OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const +{ + if (CollideCylinderVSDynamicSphere(m_attribute, s)) + { + // NOTE : Ÿ .. - [levites] + if (GetVector3Distance(s.v3Position, m_attribute.v3Position) < + GetVector3Distance(s.v3LastPosition, m_attribute.v3Position)) + return true; + } + + + // NOTE : ̵ Ÿ Ŭ ƴ ( ũ ) ̵ϸ鼭 üũ - [levites] + D3DXVECTOR3 v3Distance = s.v3Position - s.v3LastPosition; + float fDistance = D3DXVec3Length(&v3Distance); + if (s.fRadius<=0.0001f) + return false; + if (fDistance >= s.fRadius*2.0f) + { + TCylinderData cylinder; + cylinder = m_attribute; + cylinder.v3Position = s.v3LastPosition; + + int iStep = fDistance / s.fRadius*2.0f; + D3DXVECTOR3 v3Step = v3Distance / float(iStep); + + for (int i = 0; i < iStep; ++i) + { + cylinder.v3Position += v3Step; + if (CollideCylinderVSDynamicSphere(cylinder, s)) + return true; + + } + } + + return false; +} + +bool CCylinderCollisionInstance::OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const +{ + //Tracef("OnCollisionDynamicSphere\n"); + + return (CollideCylinderVSDynamicSphere(m_attribute, s)); +} + +D3DXVECTOR3 CCylinderCollisionInstance::OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const +{ + D3DXVECTOR3 v3Position = m_attribute.v3Position; + v3Position.z = s.v3Position.z; + const auto vv = (s.v3Position - v3Position); + if (D3DXVec3LengthSq(&vv)>=(s.fRadius+m_attribute.fRadius)*(m_attribute.fRadius+s.fRadius)) + return D3DXVECTOR3(0.0f,0.0f,0.0f); + D3DXVECTOR3 c; + D3DXVECTOR3 advance = s.v3Position - s.v3LastPosition; + advance.z = 0; + const auto vssa = D3DXVECTOR3(0.0f, 0.0f, 1.0f); + D3DXVec3Cross(&c, &advance, &vssa); + + const auto svsvs = (s.v3Position - v3Position); + float sum = - D3DXVec3Dot(&c,&svsvs); + float mul = (s.fRadius+m_attribute.fRadius)*(s.fRadius+m_attribute.fRadius)-D3DXVec3LengthSq(&svsvs); + + if (sum*sum-4*mul<=0) + return D3DXVECTOR3(0.0f,0.0f,0.0f); + float sq = sqrt(sum*sum-4*mul); + float t1=-sum-sq, t2=-sum+sq; + t1*=0.5f; + t2*=0.5f; + + + if (fabs(t1)<=fabs(t2)) + { + return (gc_fReduceMove*t1)*c; + } + else + return (gc_fReduceMove*t2)*c; + + /*D3DXVECTOR3 p1 = s.v3Position+t1*c; + D3DXVECTOR3 p2 = s.v3Position+t2*c; + + if (D3DXVec3LengthSq(&(p2-s.v3Position))>D3DXVec3LengthSq(&(p1-s.v3Position))) + { + return p1-s.v3Position; + } + else + { + return p2-s.v3Position; + }*/ +} + +void CCylinderCollisionInstance::Render(D3DFILLMODE d3dFillMode) +{ + static CScreen s; + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xffffffff); + s.RenderCylinder(NULL, m_attribute.v3Position.x, m_attribute.v3Position.y, m_attribute.v3Position.z+m_attribute.fHeight/2, m_attribute.fRadius, m_attribute.fHeight, d3dFillMode); +} + +void CCylinderCollisionInstance::OnDestroy() +{ + gs_cci.Free(this); +} + +///////////////////////////////////////////// +// AABB (Aligned Axis Bounding Box) +TAABBData & CAABBCollisionInstance::GetAttribute() +{ + return m_attribute; +} + +const TAABBData & CAABBCollisionInstance::GetAttribute() const +{ + + return m_attribute; +} + +bool CAABBCollisionInstance::OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const +{ + D3DXVECTOR3 v; + D3DXVECTOR3 v3center = (m_attribute.v3Min + m_attribute.v3Max) * 0.5f; + + memcpy(&v, &s.v3Position, sizeof(D3DXVECTOR3)); + + if(v.x < m_attribute.v3Min.x) v.x = m_attribute.v3Min.x; + if(v.x > m_attribute.v3Max.x) v.x = m_attribute.v3Max.x; + if(v.y < m_attribute.v3Min.y) v.x = m_attribute.v3Min.y; + if(v.y > m_attribute.v3Max.y) v.x = m_attribute.v3Max.y; + if(v.z < m_attribute.v3Min.z) v.z = m_attribute.v3Min.z; + if(v.z > m_attribute.v3Max.z) v.z = m_attribute.v3Max.z; + + if(GetVector3Distance(v, s.v3Position) <= s.fRadius * s.fRadius) + { + + return true; + } + + + memcpy(&v, &s.v3LastPosition, sizeof(D3DXVECTOR3)); + + if(v.x < m_attribute.v3Min.x) v.x = m_attribute.v3Min.x; + if(v.x > m_attribute.v3Max.x) v.x = m_attribute.v3Max.x; + if(v.y < m_attribute.v3Min.y) v.x = m_attribute.v3Min.y; + if(v.y > m_attribute.v3Max.y) v.x = m_attribute.v3Max.y; + if(v.z < m_attribute.v3Min.z) v.z = m_attribute.v3Min.z; + if(v.z > m_attribute.v3Max.z) v.z = m_attribute.v3Max.z; + + if(GetVector3Distance(v, s.v3LastPosition) <= s.fRadius * s.fRadius) + { + + return true; + } + + return false; +} + +bool CAABBCollisionInstance::OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const +{ + D3DXVECTOR3 v; + memcpy(&v, &s.v3Position, sizeof(D3DXVECTOR3)); + + if(v.x < m_attribute.v3Min.x) v.x = m_attribute.v3Min.x; + if(v.x > m_attribute.v3Max.x) v.x = m_attribute.v3Max.x; + if(v.y < m_attribute.v3Min.y) v.x = m_attribute.v3Min.y; + if(v.y > m_attribute.v3Max.y) v.x = m_attribute.v3Max.y; + if(v.z < m_attribute.v3Min.z) v.z = m_attribute.v3Min.z; + if(v.z > m_attribute.v3Max.z) v.z = m_attribute.v3Max.z; + + if(v.x > m_attribute.v3Min.x && v.x < m_attribute.v3Max.x && + v.y > m_attribute.v3Min.y && v.y < m_attribute.v3Max.y && + v.z > m_attribute.v3Min.z && v.z < m_attribute.v3Max.z) { return true; } + + if(GetVector3Distance(v, s.v3Position) <= s.fRadius * s.fRadius) { return true; } + + + memcpy(&v, &s.v3LastPosition, sizeof(D3DXVECTOR3)); + + if(v.x < m_attribute.v3Min.x) v.x = m_attribute.v3Min.x; + if(v.x > m_attribute.v3Max.x) v.x = m_attribute.v3Max.x; + if(v.y < m_attribute.v3Min.y) v.x = m_attribute.v3Min.y; + if(v.y > m_attribute.v3Max.y) v.x = m_attribute.v3Max.y; + if(v.z < m_attribute.v3Min.z) v.z = m_attribute.v3Min.z; + if(v.z > m_attribute.v3Max.z) v.z = m_attribute.v3Max.z; + + + + if(v.x > m_attribute.v3Min.x && v.x < m_attribute.v3Max.x && + v.y > m_attribute.v3Min.y && v.y < m_attribute.v3Max.y && + v.z > m_attribute.v3Min.z && v.z < m_attribute.v3Max.z) { return true; } + + if(GetVector3Distance(v, s.v3LastPosition) <= s.fRadius * s.fRadius) { return true; } + + + + return false; +} + +D3DXVECTOR3 CAABBCollisionInstance::OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const +{ + + //Tracef("OnGetCollisionMovementAdjust v3Min.x = %f, v3Max.x = %f\n", m_attribute.v3Min.x, m_attribute.v3Max.x); + /* + float fARadius = D3DXVec3Length(&(m_attribute.v3Min - m_attribute.v3Max)); + if (D3DXVec3LengthSq(&(s.v3Position-(m_attribute.v3Max + m_attribute.v3Min)))>=(s.fRadius+fARadius)*(fARadius+s.fRadius)) + return D3DXVECTOR3(0.0f,0.0f,0.0f); + D3DXVECTOR3 c; + D3DXVec3Cross(&c, &(s.v3Position-s.v3LastPosition), &D3DXVECTOR3(0.0f,0.0f,1.0f) ); + + float sum = - D3DXVec3Dot(&c,&(s.v3Position-(m_attribute.v3Max + m_attribute.v3Min))); + float mul = (s.fRadius+fARadius)*(s.fRadius+fARadius)-D3DXVec3LengthSq(&(s.v3Position-(m_attribute.v3Max + m_attribute.v3Min))); + + if (sum*sum-4*mul<=0) + return D3DXVECTOR3(0.0f,0.0f,0.0f); + float sq = sqrt(sum*sum-4*mul); + float t1=-sum-sq, t2=-sum+sq; + t1*=0.5f; + t2*=0.5f; + + if (fabs(t1)<=fabs(t2)) + { + return (gc_fReduceMove*t1)*c; + } + else + return (gc_fReduceMove*t2)*c; + */ + + D3DXVECTOR3 v3Temp; + if(s.v3Position.x + s.fRadius <= m_attribute.v3Min.x) { v3Temp.x = m_attribute.v3Min.x; } + else if(s.v3Position.x - s.fRadius >= m_attribute.v3Max.x) { v3Temp.x = m_attribute.v3Max.x; } + else if(s.v3Position.x + s.fRadius >= m_attribute.v3Min.x && s.v3Position.x + s.fRadius <= m_attribute.v3Max.x) { v3Temp.x = s.v3Position.x + s.fRadius; } + else { v3Temp.x = s.v3Position.x - s.fRadius; } + + if(s.v3Position.y + s.fRadius <= m_attribute.v3Min.y) { v3Temp.y = m_attribute.v3Min.y; } + else if(s.v3Position.y - s.fRadius >= m_attribute.v3Max.y) { v3Temp.y = m_attribute.v3Max.y; } + else if(s.v3Position.y + s.fRadius >= m_attribute.v3Min.y && s.v3Position.y + s.fRadius <= m_attribute.v3Max.y) { v3Temp.y = s.v3Position.y + s.fRadius; } + else { v3Temp.y = s.v3Position.y - s.fRadius; } + + if(s.v3Position.z + s.fRadius <= m_attribute.v3Min.z) { v3Temp.z = m_attribute.v3Min.z; } + else if(s.v3Position.z - s.fRadius >= m_attribute.v3Max.z) { v3Temp.z = m_attribute.v3Max.z; } + else if(s.v3Position.z + s.fRadius >= m_attribute.v3Min.z && s.v3Position.z + s.fRadius <= m_attribute.v3Max.z) { v3Temp.z = s.v3Position.z + s.fRadius; } + else { v3Temp.z = s.v3Position.z - s.fRadius; } + + + const auto vv = (v3Temp - s.v3Position); + if(D3DXVec3LengthSq(&vv) < s.fRadius * s.fRadius) + return D3DXVECTOR3(.0f, .0f, .0f); + + return D3DXVECTOR3(.0f, .0f, .0f); + +} + +void CAABBCollisionInstance::Render(D3DFILLMODE d3dFillMode) +{ + static CScreen s; + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xffffffff); + s.RenderCube(m_attribute.v3Min.x, m_attribute.v3Min.y, m_attribute.v3Min.z, m_attribute.v3Max.x, m_attribute.v3Max.y, m_attribute.v3Max.z); + return; +} + +void CAABBCollisionInstance::OnDestroy() +{ + gs_aci.Free(this); +} + +///////////////////////////////////////////// +// OBB + +TOBBData & COBBCollisionInstance::GetAttribute() +{ + return m_attribute; +} + +const TOBBData & COBBCollisionInstance::GetAttribute() const +{ + + return m_attribute; +} + +bool COBBCollisionInstance::OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const +{ + D3DXVECTOR3 v3Center = 0.5f * (m_attribute.v3Min + m_attribute.v3Max); + D3DXVECTOR3 v3Sphere = s.v3Position - v3Center; + D3DXVec3TransformCoord(&v3Sphere, &v3Sphere, &m_attribute.matRot); + v3Sphere = v3Sphere + v3Center; + + D3DXVECTOR3 v3Point = v3Sphere; + if(v3Point.x < m_attribute.v3Min.x) { v3Point.x = m_attribute.v3Min.x; } + if(v3Point.x > m_attribute.v3Max.x) { v3Point.x = m_attribute.v3Max.x; } + if(v3Point.y < m_attribute.v3Min.y) { v3Point.y = m_attribute.v3Min.y; } + if(v3Point.y > m_attribute.v3Max.y) { v3Point.y = m_attribute.v3Max.y; } + if(v3Point.z < m_attribute.v3Min.z) { v3Point.z = m_attribute.v3Min.z; } + if(v3Point.z > m_attribute.v3Max.z) { v3Point.z = m_attribute.v3Max.z; } + + if(GetVector3Distance(v3Point, v3Sphere) <= s.fRadius * s.fRadius) { return true; } + + v3Sphere = s.v3LastPosition - v3Center; + D3DXVec3TransformCoord(&v3Sphere, &v3Sphere, &m_attribute.matRot); + v3Sphere = v3Sphere + v3Center; + + v3Point = v3Sphere; + if(v3Point.x < m_attribute.v3Min.x) { v3Point.x = m_attribute.v3Min.x; } + if(v3Point.x > m_attribute.v3Max.x) { v3Point.x = m_attribute.v3Max.x; } + if(v3Point.y < m_attribute.v3Min.y) { v3Point.y = m_attribute.v3Min.y; } + if(v3Point.y > m_attribute.v3Max.y) { v3Point.y = m_attribute.v3Max.y; } + if(v3Point.z < m_attribute.v3Min.z) { v3Point.z = m_attribute.v3Min.z; } + if(v3Point.z > m_attribute.v3Max.z) { v3Point.z = m_attribute.v3Max.z; } + + if(GetVector3Distance(v3Point, v3Sphere) <= s.fRadius * s.fRadius) { return true; } + + return false; +} + +bool COBBCollisionInstance::OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const +{ + + D3DXVECTOR3 v3Center = 0.5f * (m_attribute.v3Min + m_attribute.v3Max); + D3DXVECTOR3 v3Sphere = s.v3Position - v3Center; + D3DXVec3TransformCoord(&v3Sphere, &v3Sphere, &m_attribute.matRot); + v3Sphere = v3Sphere + v3Center; + + D3DXVECTOR3 v3Point = v3Sphere; + if(v3Point.x < m_attribute.v3Min.x) { v3Point.x = m_attribute.v3Min.x; } + if(v3Point.x > m_attribute.v3Max.x) { v3Point.x = m_attribute.v3Max.x; } + if(v3Point.y < m_attribute.v3Min.y) { v3Point.y = m_attribute.v3Min.y; } + if(v3Point.y > m_attribute.v3Max.y) { v3Point.y = m_attribute.v3Max.y; } + if(v3Point.z < m_attribute.v3Min.z) { v3Point.z = m_attribute.v3Min.z; } + if(v3Point.z > m_attribute.v3Max.z) { v3Point.z = m_attribute.v3Max.z; } + + if(GetVector3Distance(v3Point, v3Sphere) <= s.fRadius * s.fRadius) { return true; } + + v3Sphere = s.v3LastPosition - v3Center; + D3DXVec3TransformCoord(&v3Sphere, &v3Sphere, &m_attribute.matRot); + v3Sphere = v3Sphere + v3Center; + + v3Point = v3Sphere; + if(v3Point.x < m_attribute.v3Min.x) { v3Point.x = m_attribute.v3Min.x; } + if(v3Point.x > m_attribute.v3Max.x) { v3Point.x = m_attribute.v3Max.x; } + if(v3Point.y < m_attribute.v3Min.y) { v3Point.y = m_attribute.v3Min.y; } + if(v3Point.y > m_attribute.v3Max.y) { v3Point.y = m_attribute.v3Max.y; } + if(v3Point.z < m_attribute.v3Min.z) { v3Point.z = m_attribute.v3Min.z; } + if(v3Point.z > m_attribute.v3Max.z) { v3Point.z = m_attribute.v3Max.z; } + + if(GetVector3Distance(v3Point, v3Sphere) <= s.fRadius * s.fRadius) { return true; } + + + return false; +} + +D3DXVECTOR3 COBBCollisionInstance::OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const +{ + + return D3DXVECTOR3(.0f, .0f, .0f); + +} + +void COBBCollisionInstance::Render(D3DFILLMODE d3dFillMode) +{ + static CScreen s; + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xffffffff); + s.RenderCube(m_attribute.v3Min.x, m_attribute.v3Min.y, m_attribute.v3Min.z, m_attribute.v3Max.x, m_attribute.v3Max.y, m_attribute.v3Max.z, m_attribute.matRot); + return; +} + +void COBBCollisionInstance::OnDestroy() +{ + gs_oci.Free(this); +} \ No newline at end of file diff --git a/source/EterLib/CollisionData.h b/source/EterLib/CollisionData.h new file mode 100644 index 0000000..7835829 --- /dev/null +++ b/source/EterLib/CollisionData.h @@ -0,0 +1,206 @@ +#pragma once + +// Collision Detection +typedef struct SSphereData +{ + D3DXVECTOR3 v3Position; + float fRadius; +} TSphereData; + +typedef struct SPlaneData +{ + D3DXVECTOR3 v3Position; + D3DXVECTOR3 v3Normal; + + D3DXVECTOR3 v3QuadPosition[4]; + D3DXVECTOR3 v3InsideVector[4]; +} TPlaneData; + +typedef struct SAABBData +{ + D3DXVECTOR3 v3Min; + D3DXVECTOR3 v3Max; + +} TAABBData; + +typedef struct SOBBData +{ + D3DXVECTOR3 v3Min; + D3DXVECTOR3 v3Max; + D3DXMATRIX matRot; + +} TOBBData; + +typedef struct SCylinderData +{ + D3DXVECTOR3 v3Position; + float fRadius; + float fHeight; +} TCylinderData; + +enum ECollisionType +{ + COLLISION_TYPE_PLANE, + COLLISION_TYPE_BOX, + COLLISION_TYPE_SPHERE, + COLLISION_TYPE_CYLINDER, + COLLISION_TYPE_AABB, + COLLISION_TYPE_OBB, +}; + +struct CDynamicSphereInstance +{ + D3DXVECTOR3 v3Position; + D3DXVECTOR3 v3LastPosition; + + float fRadius; +}; + +class CStaticCollisionData +{ +public: + DWORD dwType; + char szName[32+1]; + + D3DXVECTOR3 v3Position; + float fDimensions[3]; + D3DXQUATERNION quatRotation; +}; + +void DestroyCollisionInstanceSystem(); + +typedef std::vector CStaticCollisionDataVector; + +///////////////////////////////////////////// +// Base +class CBaseCollisionInstance +{ + public: + virtual void Render(D3DFILLMODE d3dFillMode = D3DFILL_SOLID) = 0; + + bool MovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const + { + return OnMovementCollisionDynamicSphere(s); + } + bool CollisionDynamicSphere(const CDynamicSphereInstance & s) const + { + return OnCollisionDynamicSphere(s); + } + + + D3DXVECTOR3 GetCollisionMovementAdjust(const CDynamicSphereInstance & s) const + { + return OnGetCollisionMovementAdjust(s); + } + + void Destroy(); + + static CBaseCollisionInstance * BuildCollisionInstance(const CStaticCollisionData * c_pCollisionData, const D3DXMATRIX * pMat); + + protected: + virtual D3DXVECTOR3 OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const = 0; + virtual bool OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const = 0; + virtual bool OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const = 0; + virtual void OnDestroy() = 0; +}; + +///////////////////////////////////////////// +// Sphere +class CSphereCollisionInstance : public CBaseCollisionInstance +{ + public: + TSphereData & GetAttribute(); + const TSphereData & GetAttribute() const; + virtual void Render(D3DFILLMODE d3dFillMode = D3DFILL_SOLID); + + protected: + void OnDestroy(); + bool OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const; + virtual bool OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const; + virtual D3DXVECTOR3 OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const; + + protected: + TSphereData m_attribute; +}; + +///////////////////////////////////////////// +// Plane +class CPlaneCollisionInstance : public CBaseCollisionInstance +{ + public: + TPlaneData & GetAttribute(); + const TPlaneData & GetAttribute() const; + virtual void Render(D3DFILLMODE d3dFillMode = D3DFILL_SOLID); + + protected: + void OnDestroy(); + bool OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const; + virtual bool OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const; + virtual D3DXVECTOR3 OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const; + + protected: + TPlaneData m_attribute; +}; + +///////////////////////////////////////////// +// AABB (Aligned Axis Bounding Box) +class CAABBCollisionInstance : public CBaseCollisionInstance +{ + public: + TAABBData & GetAttribute(); + const TAABBData & GetAttribute() const; + virtual void Render(D3DFILLMODE d3dFillMode = D3DFILL_SOLID); + + protected: + void OnDestroy(); + bool OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const; + virtual bool OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const; + virtual D3DXVECTOR3 OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const; + + protected: + TAABBData m_attribute; +}; + +///////////////////////////////////////////// +// OBB +class COBBCollisionInstance : public CBaseCollisionInstance +{ + public: + TOBBData & GetAttribute(); + const TOBBData & GetAttribute() const; + virtual void Render(D3DFILLMODE d3dFillMode = D3DFILL_SOLID); + + protected: + void OnDestroy(); + bool OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const; + virtual bool OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const; + virtual D3DXVECTOR3 OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const; + + protected: + TOBBData m_attribute; +}; + +///////////////////////////////////////////// +// Cylinder +class CCylinderCollisionInstance : public CBaseCollisionInstance +{ + public: + TCylinderData & GetAttribute(); + const TCylinderData & GetAttribute() const; + virtual void Render(D3DFILLMODE d3dFillMode = D3DFILL_SOLID); + + protected: + void OnDestroy(); + bool OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const; + virtual bool OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const; + virtual D3DXVECTOR3 OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const; + + bool CollideCylinderVSDynamicSphere(const TCylinderData & c_rattribute, const CDynamicSphereInstance & s) const; + + protected: + TCylinderData m_attribute; +}; + +typedef std::vector CSphereCollisionInstanceVector; +typedef std::vector CDynamicSphereInstanceVector; +typedef std::vector CCollisionInstanceVector; diff --git a/source/EterLib/ColorTransitionHelper.cpp b/source/EterLib/ColorTransitionHelper.cpp new file mode 100644 index 0000000..00603c4 --- /dev/null +++ b/source/EterLib/ColorTransitionHelper.cpp @@ -0,0 +1,104 @@ +#include "StdAfx.h" +#include "ColorTransitionHelper.h" + +void CColorTransitionHelper::Clear(const float & c_rfRed, + const float & c_rfGreen, + const float & c_rfBlue, + const float & c_rfAlpha) +{ + + m_fSrcRed = c_rfRed; + m_fSrcGreen = c_rfGreen; + m_fSrcBlue = c_rfBlue; + m_fSrcAlpha = c_rfAlpha; + + m_fDstRed = c_rfRed; + m_fDstGreen = c_rfGreen; + m_fDstBlue = c_rfBlue; + m_fDstAlpha = c_rfAlpha; + + m_dwCurColor = 0x00000000; + + m_dwStartTime = m_dwDuration = 0; +} + +void CColorTransitionHelper::SetSrcColor(const float & c_rfRed, + const float & c_rfGreen, + const float & c_rfBlue, + const float & c_rfAlpha) +{ + m_fSrcRed = c_rfRed; + m_fSrcGreen = c_rfGreen; + m_fSrcBlue = c_rfBlue; + m_fSrcAlpha = c_rfAlpha; +} + +void CColorTransitionHelper::SetTransition(const float & c_rfRed, + const float & c_rfGreen, + const float & c_rfBlue, + const float & c_rfAlpha, + const DWORD & dwDuration) +{ + m_fDstRed = c_rfRed; + m_fDstGreen = c_rfGreen; + m_fDstBlue = c_rfBlue; + m_fDstAlpha = c_rfAlpha; + + m_dwDuration = dwDuration; +} + +void CColorTransitionHelper::StartTransition() +{ + m_bTransitionStarted = true; + m_dwStartTime = GetCurrentTime(); +} + +bool CColorTransitionHelper::Update() +{ +// if (!m_bTransitionStarted) +// return false; + + DWORD dwCurTime = GetCurrentTime(); + DWORD dwElapsedTime = dwCurTime - m_dwStartTime; + + float fpercent = (float)(dwElapsedTime) / (float)(m_dwDuration); + if (fpercent <= 0.0f) + fpercent = 0.0f; + if (fpercent >= 1.0f) + fpercent = 1.0f; + float fCurRed, fCurGreen, fCurBlue, fCurAlpha; + fCurRed = m_fSrcRed + (m_fDstRed - m_fSrcRed) * fpercent; + fCurGreen = m_fSrcGreen + (m_fDstGreen - m_fSrcGreen) * fpercent; + fCurBlue = m_fSrcBlue + (m_fDstBlue - m_fSrcBlue) * fpercent; + fCurAlpha = m_fSrcAlpha + (m_fDstAlpha - m_fSrcAlpha) * fpercent; + +// Tracef("%f, %f, %f, %f\n", fCurRed, fCurGreen, fCurBlue, fCurAlpha); + + m_dwCurColor = (((DWORD)(fCurAlpha * 255.0f)&0xff)<< 24) | + (((DWORD)(fCurRed * 255.0f)&0xff) << 16) | + (((DWORD)(fCurGreen * 255.0f)&0xff) << 8) | + ((DWORD)(fCurBlue * 255.0f)&0xff); + + if ( (1.0f == fpercent) && (fCurAlpha == m_fDstAlpha) && (fCurRed == m_fDstRed) && (fCurGreen == m_fDstGreen) && (fCurBlue == m_fDstBlue) ) + { + m_bTransitionStarted = false; + return false; + } + + return true; +} + +const D3DCOLOR & CColorTransitionHelper::GetCurColor() +{ + return m_dwCurColor; +} + +CColorTransitionHelper::CColorTransitionHelper():m_bTransitionStarted(false) +{ + Clear(0.0f, 0.0f, 0.0f, 0.0f); +} + +CColorTransitionHelper::~CColorTransitionHelper() +{ + Clear(0.0f, 0.0f, 0.0f, 0.0f); +} diff --git a/source/EterLib/ColorTransitionHelper.h b/source/EterLib/ColorTransitionHelper.h new file mode 100644 index 0000000..deb7a60 --- /dev/null +++ b/source/EterLib/ColorTransitionHelper.h @@ -0,0 +1,39 @@ +#pragma once + +class CColorTransitionHelper +{ + public: + CColorTransitionHelper(); + ~CColorTransitionHelper(); + + void Clear(const float & c_rfRed, + const float & c_rfGreen, + const float & c_rfBlue, + const float & c_rfAlpha); + void SetSrcColor(const float & c_rfRed, + const float & c_rfGreen, + const float & c_rfBlue, + const float & c_rfAlpha); + void SetTransition(const float & c_rfRed, + const float & c_rfGreen, + const float & c_rfBlue, + const float & c_rfAlpha, + const DWORD & dwDuration); + const D3DCOLOR & GetCurColor();// { return m_dwCurColor; } + + void StartTransition(); + bool Update(); + + bool isTransitionStarted() { return m_bTransitionStarted; } + + private: + D3DCOLOR m_dwCurColor; // + + DWORD m_dwStartTime; // ٲ ϴ ð + DWORD m_dwDuration; // ȿ ٲ°? + + bool m_bTransitionStarted; + + float m_fSrcRed, m_fSrcGreen, m_fSrcBlue, m_fSrcAlpha; + float m_fDstRed, m_fDstGreen, m_fDstBlue, m_fDstAlpha; +}; diff --git a/source/EterLib/CullingManager.cpp b/source/EterLib/CullingManager.cpp new file mode 100644 index 0000000..86c89ec --- /dev/null +++ b/source/EterLib/CullingManager.cpp @@ -0,0 +1,176 @@ +#include "StdAfx.h" +#include "CullingManager.h" +#include "GrpObjectInstance.h" + +//#define COUNT_SHOWING_SPHERE + +#ifdef COUNT_SHOWING_SPHERE +int showingcount = 0; +#endif + +void CCullingManager::RayTraceCallback(const Vector3d &/*p1*/, // source pos of ray + const Vector3d &/*dir*/, // dest pos of ray + float distance, + const Vector3d &/*sect*/, + SpherePack *sphere) +{ + //if (state!=VS_OUTSIDE) + //{ + if (m_RayFarDistance<=0.0f || m_RayFarDistance>=distance) + { +#ifdef SPHERELIB_STRICT + if (sphere->IS_SPHERE) + puts("CCullingManager::RayTraceCallback"); +#endif + m_list.push_back((CGraphicObjectInstance *)sphere->GetUserData()); + } + //f((CGraphicObjectInstance *)sphere->GetUserData()); + //} +} + + +void CCullingManager::VisibilityCallback(const Frustum &/*f*/,SpherePack *sphere,ViewState state) +{ +#ifdef SPHERELIB_STRICT + if (sphere->IS_SPHERE) + puts("CCullingManager::VisibilityCallback"); +#endif + + CGraphicObjectInstance * pInstance = (CGraphicObjectInstance*)sphere->GetUserData(); + /*if (state == VS_PARTIAL) + { + Vector3d v; + float r; + pInstance->GetBoundingSphere(v,r); + state = f.ViewVolumeTest(v,r); + }*/ + if (state == VS_OUTSIDE) + { +#ifdef COUNT_SHOWING_SPHERE + if (pInstance->isShow()) + { + Tracef("SH : %p ",sphere->GetUserData()); + showingcount--; + Tracef("show size : %5d\n",showingcount); + } + +#endif + pInstance->Hide(); + } + else + { +#ifdef COUNT_SHOWING_SPHERE + if (!pInstance->isShow()) + { + Tracef("HS : %p ",sphere->GetUserData()); + showingcount++; + Tracef("show size : %5d\n",showingcount); + } +#endif + pInstance->Show(); + } +} + +void CCullingManager::RangeTestCallback(const Vector3d &/*p*/,float /*distance*/,SpherePack *sphere,ViewState state) +{ +#ifdef SPHERELIB_STRICT + if (sphere->IS_SPHERE) + puts("CCullingManager::RangeTestCallback"); +#endif + if (state!=VS_OUTSIDE) + { + m_list.push_back((CGraphicObjectInstance *)sphere->GetUserData()); + //f((CGraphicObjectInstance *)sphere->GetUserData()); + } + //assert(false && "NOT REACHED"); +} + +void CCullingManager::Reset() +{ + m_Factory->Reset(); +} + +void CCullingManager::Update() +{ + // TODO : update each object + // ϰ غ + + //DWORD time = ELTimer_GetMSec(); + //Reset(); + + m_Factory->Process(); + //Tracef("cull update : %3d ",ELTimer_GetMSec()-time); +} + +void CCullingManager::Process() +{ + //DWORD time = ELTimer_GetMSec(); + //Frustum f; + UpdateViewMatrix(); + UpdateProjMatrix(); + BuildViewFrustum(); + m_Factory->FrustumTest(GetFrustum(), this); + //Tracef("cull process : %3d ",ELTimer_GetMSec()-time); +} + +CCullingManager::CullingHandle CCullingManager::Register(CGraphicObjectInstance * obj) +{ + assert(obj); +#ifdef COUNT_SHOWING_SPHERE + Tracef("CR : %p ",obj); + showingcount++; + Tracef("show size : %5d\n",showingcount); +#endif + Vector3d center; + float radius; + obj->GetBoundingSphere(center,radius); + return m_Factory->AddSphere_(center,radius,obj, false); +} + +void CCullingManager::Unregister(CullingHandle h) +{ +#ifdef COUNT_SHOWING_SPHERE + if (((CGraphicObjectInstance*)h->GetUserData())->isShow()) + { + Tracef("DE : %p ",h->GetUserData()); + showingcount--; + Tracef("show size : %5d\n",showingcount); + } +#endif + m_Factory->Remove(h); +} + +CCullingManager::CCullingManager() +{ + m_Factory = new SpherePackFactory( + 10000, // maximum count + 6400, // root radius + 1600, // leaf radius + 400 // extra radius + ); +} + +CCullingManager::~CCullingManager() +{ + delete m_Factory; +} + +void CCullingManager::FindRange(const Vector3d &p, float radius) +{ + m_list.clear(); + m_Factory->RangeTest(p, radius, this); +} + +void CCullingManager::FindRay(const Vector3d &p1, const Vector3d &dir) +{ + m_RayFarDistance = -1; + m_list.clear(); + m_Factory->RayTrace(p1,dir,this); +} + +void CCullingManager::FindRayDistance(const Vector3d &p1, const Vector3d &dir, float distance) +{ + m_RayFarDistance = distance; + m_list.clear(); + m_Factory->RayTrace(p1,dir,this); +} \ No newline at end of file diff --git a/source/EterLib/CullingManager.h b/source/EterLib/CullingManager.h new file mode 100644 index 0000000..0891d77 --- /dev/null +++ b/source/EterLib/CullingManager.h @@ -0,0 +1,149 @@ +#pragma once + +#include "GrpScreen.h" + +#include "../eterbase/Singleton.h" +#include "../SphereLib/spherepack.h" + +class CGraphicObjectInstance; +template +struct RangeTester : public SpherePackCallback +{ + T * f; + float dist; + RangeTester(T * fn, float distance=-1) + : f(fn), dist(distance) + {} + + virtual ~RangeTester() + {} + + + virtual void RayTraceCallback(const Vector3d &p1, // source pos of ray + const Vector3d &dir, // dest pos of ray + float distance, + const Vector3d §, + SpherePack *sphere) + { +#ifdef SPHERELIB_STRICT + if (sphere->IS_SPHERE) + puts("RangeTester::RayTraceCallback"); +#endif + if (dist<=0.0f || dist>=distance) + (*f)((CGraphicObjectInstance *)sphere->GetUserData()); + }; + + + virtual void VisibilityCallback(const Frustum &f,SpherePack *sphere,ViewState state){}; + + virtual void RangeTestCallback(const Vector3d &p,float distance,SpherePack *sphere,ViewState state) + { +#ifdef SPHERELIB_STRICT + if (sphere->IS_SPHERE) + puts("RangeTester::RangeTestCallback"); +#endif + if (state!=VS_OUTSIDE) + (*f)((CGraphicObjectInstance *)sphere->GetUserData()); + } + + virtual void PointTest2dCallback(const Vector3d &p, SpherePack *sphere,ViewState state) + { +#ifdef SPHERELIB_STRICT + if (sphere->IS_SPHERE) + puts("RangeTester::PointTest2dCallback"); +#endif + if (state!=VS_OUTSIDE) + { +#ifdef SPHERELIB_STRICT + puts("FIND!!"); +#endif + (*f)((CGraphicObjectInstance *)sphere->GetUserData()); + } + } +}; + +class CCullingManager : public CSingleton, public SpherePackCallback, private CScreen +{ +public: + typedef SpherePack * CullingHandle; + typedef std::vector TRangeList; + + CCullingManager(); + virtual ~CCullingManager(); + + virtual void RayTraceCallback(const Vector3d &p1, // source pos of ray + const Vector3d &dir, // dest pos of ray + float distance, + const Vector3d §, + SpherePack *sphere); + + + virtual void VisibilityCallback(const Frustum &f,SpherePack *sphere,ViewState state); + + void RangeTestCallback(const Vector3d &p,float distance,SpherePack *sphere,ViewState state); + + void Reset(); + void Update(); + void Process(); + + void FindRange(const Vector3d &p, float radius); + void FindRay(const Vector3d &p1, const Vector3d &dir); + void FindRayDistance(const Vector3d &p1, const Vector3d &dir, float distance); + + void RangeTest(const Vector3d& p, float radius, SpherePackCallback* callback) + { + m_Factory->RangeTest(p, radius, callback); + } + + void PointTest2d(const Vector3d& p, SpherePackCallback* callback) + { + m_Factory->PointTest2d(p, callback); + } + + template + void ForInRange2d(const Vector3d& p, T* pFunc) + { + RangeTester r(pFunc); + m_Factory->PointTest2d(p, &r); + } + + template + void ForInRange(const Vector3d &p, float radius, T* pFunc) + { + RangeTester r(pFunc); + m_Factory->RangeTest(p, radius, &r/*this*/); + } + + template + void ForInRay(const Vector3d &p1, const Vector3d &dir, T* pFunc) + { + RangeTester r(pFunc); + /*Vector3d p2; + //p2.Set(p.x+(dir.x*50000.0f),p.y+(dir.y*50000.0f),p.z+(dir.z*50000.0f)); + p2.x = p.x+50000.0f*dir.x; + p2.y = p.y+50000.0f*dir.y; + p2.z = p.z+50000.0f*dir.z; + // p + (50000.0f*dir);//(p.x+(dir.x*50000.0f),p.y+(dir.y*50000.0f),p.z+(dir.z*50000.0f));*/ + m_Factory->RayTrace(p1, dir, &r/*this*/); + } + + template + void ForInRayDistance(const Vector3d &p, const Vector3d &dir, float distance, T* pFunc) + { + RangeTester r(pFunc, distance); + m_Factory->RayTrace(p, dir, &r/*this*/); + } + + CullingHandle Register(CGraphicObjectInstance * ob); + void Unregister(CullingHandle h); + + TRangeList::iterator begin() { return m_list.begin(); } + TRangeList::iterator end() { return m_list.end(); } + +protected: + TRangeList m_list; + + float m_RayFarDistance; + + SpherePackFactory * m_Factory; +}; diff --git a/source/EterLib/Decal.cpp b/source/EterLib/Decal.cpp new file mode 100644 index 0000000..8c374df --- /dev/null +++ b/source/EterLib/Decal.cpp @@ -0,0 +1,287 @@ +// Decal.cpp: implementation of the CDecal class. +// +////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "Decal.h" +#include "StateManager.h" + +////////////////////////////////////////////////////////////////////// +// CDecal +////////////////////////////////////////////////////////////////////// + +CDecal::CDecal():m_cfDecalEpsilon(0.25f) +{ + Clear(); +} + +CDecal::~CDecal() +{ + Clear(); +} + +void CDecal::Clear() +{ + m_v3Center = D3DXVECTOR3(0.0f, 0.0f, 0.0f); + m_v3Normal = D3DXVECTOR3(0.0f, 0.0f, 0.0f); + + m_v4LeftPlane = D3DXPLANE(0.0f, 0.0f, 0.0f, 0.0f); + m_v4RightPlane = D3DXPLANE(0.0f, 0.0f, 0.0f, 0.0f); + m_v4TopPlane = D3DXPLANE(0.0f, 0.0f, 0.0f, 0.0f); + m_v4BottomPlane = D3DXPLANE(0.0f, 0.0f, 0.0f, 0.0f); + m_v4FrontPlane = D3DXPLANE(0.0f, 0.0f, 0.0f, 0.0f); + m_v4BackPlane = D3DXPLANE(0.0f, 0.0f, 0.0f, 0.0f); + + m_dwVertexCount = 0; + m_dwPrimitiveCount = 0; + + m_TriangleFanStructVector.clear(); + + memset(m_Vertices, 0, sizeof(m_Vertices)); + memset(m_Indices, 0, sizeof(m_Indices)); +} + +void CDecal::ClipMesh(DWORD dwPrimitiveCount, const D3DXVECTOR3 *c_pv3Vertex, const D3DXVECTOR3 *c_pv3Normal) +{ + D3DXVECTOR3 v3NewVertex[9]; + D3DXVECTOR3 v3NewNormal[9]; + + // Clip one triangle at a time + for(DWORD dwi = 0; dwi < dwPrimitiveCount; ++dwi) + { + const D3DXVECTOR3 & v3_1 = c_pv3Vertex[3 * dwi]; + const D3DXVECTOR3 & v3_2 = c_pv3Vertex[3 * dwi + 1]; + const D3DXVECTOR3 & v3_3 = c_pv3Vertex[3 * dwi + 2]; + + D3DXVECTOR3 v3Cross; + const auto vv_ = (v3_2 - v3_1); + const auto vv_2 = (v3_3 - v3_1); + D3DXVec3Cross(&v3Cross, &vv_, &vv_2); + if (D3DXVec3Dot(&m_v3Normal, &v3Cross) > ( m_cfDecalEpsilon ) * D3DXVec3Length(&v3Cross)) + { + v3NewVertex[0] = v3_1; + v3NewVertex[1] = v3_2; + v3NewVertex[2] = v3_3; + + v3NewNormal[0] = c_pv3Normal[3 * dwi]; + v3NewNormal[1] = c_pv3Normal[3 * dwi + 1]; + v3NewNormal[2] = c_pv3Normal[3 * dwi + 2]; + + DWORD dwCount = ClipPolygon(3, v3NewVertex, v3NewNormal, v3NewVertex, v3NewNormal); + if ((dwCount != 0) && (!AddPolygon(dwCount, v3NewVertex, v3NewNormal))) break; + } + } +} + +bool CDecal::AddPolygon(DWORD dwAddCount, const D3DXVECTOR3 *c_pv3Vertex, const D3DXVECTOR3 * /*c_pv3Normal */) +{ + if (m_dwVertexCount + dwAddCount >= MAX_DECAL_VERTICES) + return false; + + TTRIANGLEFANSTRUCT aTriangleFanStruct; + aTriangleFanStruct.m_wMinIndex = m_dwVertexCount; + aTriangleFanStruct.m_dwVertexCount = dwAddCount; + aTriangleFanStruct.m_dwPrimitiveCount = dwAddCount - 2; + aTriangleFanStruct.m_dwVBOffset = m_dwVertexCount; + + m_TriangleFanStructVector.push_back(aTriangleFanStruct); + + DWORD dwCount = m_dwVertexCount; + + // Add polygon as a triangle fan + WORD * wIndex = m_Indices + dwCount; + + m_dwPrimitiveCount += dwAddCount - 2; + //float fOne_over_1MinusDecalEpsilon = 1.0f / (1.0f - m_cfDecalEpsilon); + + // Assign vertex colors + for (DWORD dwVertexNum = 0; dwVertexNum < dwAddCount; ++dwVertexNum) + { + *wIndex++ = (WORD) dwCount; + m_Vertices[dwCount].position = c_pv3Vertex[dwVertexNum]; + //const D3DXVECTOR3 & v3Normal = c_pv3Normal[dwVertexNum]; + //float fAlpha = (D3DXVec3Dot(&m_v3Normal, &v3Normal) / D3DXVec3Length(&v3Normal) - m_cfDecalEpsilon) * fOne_over_1MinusDecalEpsilon; + //m_Vertices[dwCount].diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, (fAlpha > 0.0f) ? fAlpha : 0.0f); + m_Vertices[dwCount].diffuse = 0xFFFFFFFF; + ++dwCount; + } + + m_dwVertexCount = dwCount; + return true; +} + +DWORD CDecal::ClipPolygon(DWORD dwVertexCount, + const D3DXVECTOR3 *c_pv3Vertex, + const D3DXVECTOR3 *c_pv3Normal, + D3DXVECTOR3 *c_pv3NewVertex, + D3DXVECTOR3 *c_pv3NewNormal) const +{ + D3DXVECTOR3 v3TempVertex[9]; + D3DXVECTOR3 v3TempNormal[9]; + + // Clip against all six planes + DWORD dwCount = ClipPolygonAgainstPlane(m_v4LeftPlane, dwVertexCount, c_pv3Vertex, c_pv3Normal, v3TempVertex, v3TempNormal); + if (dwCount != 0) + { + dwCount = ClipPolygonAgainstPlane(m_v4RightPlane, dwCount, v3TempVertex, v3TempNormal, c_pv3NewVertex, c_pv3NewNormal); + if (dwCount != 0) + { + dwCount = ClipPolygonAgainstPlane(m_v4BottomPlane, dwCount, c_pv3NewVertex, c_pv3NewNormal, v3TempVertex, v3TempNormal); + if (dwCount != 0) + { + dwCount = ClipPolygonAgainstPlane(m_v4TopPlane, dwCount, v3TempVertex, v3TempNormal, c_pv3NewVertex, c_pv3NewNormal); + if (dwCount != 0) + { + dwCount = ClipPolygonAgainstPlane(m_v4BackPlane, dwCount, c_pv3NewVertex, c_pv3NewNormal, v3TempVertex, v3TempNormal); + if (dwCount != 0) + { + dwCount = ClipPolygonAgainstPlane(m_v4FrontPlane, dwCount, v3TempVertex, v3TempNormal, c_pv3NewVertex, c_pv3NewNormal); + } + } + } + } + } + return dwCount; +} + +DWORD CDecal::ClipPolygonAgainstPlane(const D3DXPLANE& c_rv4Plane, + DWORD dwVertexCount, + const D3DXVECTOR3 *c_pv3Vertex, + const D3DXVECTOR3 *c_pv3Normal, + D3DXVECTOR3 *c_pv3NewVertex, + D3DXVECTOR3 *c_pv3NewNormal) +{ + bool bNegative[10]; + + // Classify vertices + DWORD dwNegativeCount = 0; + for (DWORD dwi = 0; dwi < dwVertexCount; ++dwi) + { + bool bNeg = (D3DXPlaneDotCoord(&c_rv4Plane, &c_pv3Vertex[dwi]) < 0.0F); + bNegative[dwi] = bNeg; + dwNegativeCount += bNeg; + } + + // Discard this polygon if it's completely culled + if (dwNegativeCount == dwVertexCount) + return 0; + + DWORD dwCount = 0; + for (DWORD dwCurIndex = 0; dwCurIndex < dwVertexCount; ++dwCurIndex) + { + // dwPrevIndex is the index of the previous vertex + DWORD dwPrevIndex = (dwCurIndex != 0) ? dwCurIndex - 1 : dwVertexCount - 1; + + if (bNegative[dwCurIndex]) + { + if (!bNegative[dwPrevIndex]) + { + // Current vertex is on negative side of plane, + // but previous vertex is on positive side. + const D3DXVECTOR3& v3_1 = c_pv3Vertex[dwPrevIndex]; + const D3DXVECTOR3& v3_2 = c_pv3Vertex[dwCurIndex]; + float ft = D3DXPlaneDotCoord(&c_rv4Plane, &v3_1) / (c_rv4Plane.a * (v3_1.x - v3_2.x) + c_rv4Plane.b * (v3_1.y - v3_2.y) + c_rv4Plane.c * (v3_1.z - v3_2.z)); + c_pv3NewVertex[dwCount] = v3_1 * (1.0f - ft) + v3_2 * ft; + const D3DXVECTOR3& v3_n1 = c_pv3Normal[dwPrevIndex]; + const D3DXVECTOR3& v3_n2 = c_pv3Normal[dwCurIndex]; + c_pv3NewNormal[dwCount] = v3_n1 * (1.0f - ft) + v3_n2 * ft; + ++dwCount; + } + } + else + { + if (bNegative[dwPrevIndex]) + { + // Current vertex is on positive side of plane, + // but previous vertex is on negative side. + const D3DXVECTOR3& v3_1 = c_pv3Vertex[dwCurIndex]; + const D3DXVECTOR3& v3_2 = c_pv3Vertex[dwPrevIndex]; + float ft = D3DXPlaneDotCoord(&c_rv4Plane, &v3_1) / (c_rv4Plane.a * (v3_1.x - v3_2.x) + c_rv4Plane.b * (v3_1.y - v3_2.y) + c_rv4Plane.c * (v3_1.z - v3_2.z)); + c_pv3NewVertex[dwCount] = v3_1 * (1.0f - ft) + v3_2 * ft; + const D3DXVECTOR3& v3_n1 = c_pv3Normal[dwCurIndex]; + const D3DXVECTOR3& v3_n2 = c_pv3Normal[dwPrevIndex]; + c_pv3NewNormal[dwCount] = v3_n1 * (1.0f - ft) + v3_n2 * ft; + ++dwCount; + } + + // Include current vertex + c_pv3NewVertex[dwCount] = c_pv3Vertex[dwCurIndex]; + c_pv3NewNormal[dwCount] = c_pv3Normal[dwCurIndex]; + ++dwCount; + } + } + + // Return number of vertices in clipped polygon + return dwCount; +} + +/* +void CDecal::Update() +{ +} +*/ + +void CDecal::Render() +{ + D3DXMATRIX matWorld; + D3DXMatrixIdentity(&matWorld); + STATEMANAGER.SetTransform(D3DTS_WORLD, &matWorld); + + STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + + for (DWORD dwi = 0; dwi < m_TriangleFanStructVector.size(); ++dwi) + STATEMANAGER.DrawIndexedPrimitiveUP(D3DPT_TRIANGLEFAN, + m_TriangleFanStructVector[dwi].m_wMinIndex, + m_TriangleFanStructVector[dwi].m_dwVertexCount, + m_TriangleFanStructVector[dwi].m_dwPrimitiveCount, + m_Indices + m_TriangleFanStructVector[dwi].m_wMinIndex, + D3DFMT_INDEX16, + m_Vertices, + sizeof(TPDTVertex)); +} + +/* +////////////////////////////////////////////////////////////////////////// +// CDecalManager +////////////////////////////////////////////////////////////////////////// +CDecalManager aDecalManager; + +CDecalManager::CDecalManager() +{ + m_DecalPtrVector.clear(); +} + +CDecalManager::~CDecalManager() +{ + m_DecalPtrVector.clear(); +} + +void CDecalManager::Add(CDecal * pDecal) +{ + m_DecalPtrVector.push_back(pDecal); +} + +void CDecalManager::Remove(CDecal * pDecal) +{ + std::vector::iterator aIterator; + for (aIterator = m_DecalPtrVector.begin(); aIterator != m_DecalPtrVector.end();) + { + if (*aIterator == pDecal) + aIterator = m_DecalPtrVector.erase(aIterator); + else + ++aIterator; + } +} + +void CDecalManager::Update() +{ + for (DWORD dwi = 0; dwi < m_DecalPtrVector.size(); ++dwi) + m_DecalPtrVector[dwi]->Update(); +} + +void CDecalManager::Render() +{ + for (DWORD dwi = 0; dwi < m_DecalPtrVector.size(); ++dwi) + m_DecalPtrVector[dwi]->Render(); +} +*/ diff --git a/source/EterLib/Decal.h b/source/EterLib/Decal.h new file mode 100644 index 0000000..a19ba98 --- /dev/null +++ b/source/EterLib/Decal.h @@ -0,0 +1,103 @@ +// Decal.h: interface for the CDecal class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_DECAL_H__E3D27DFC_30CB_4995_B9B9_396B5E8A5F02__INCLUDED_) +#define AFX_DECAL_H__E3D27DFC_30CB_4995_B9B9_396B5E8A5F02__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "GrpBase.h" + +class CDecal +{ +public: + + enum + { + MAX_DECAL_VERTICES = 256, + }; + + CDecal(); + virtual ~CDecal(); + + void Clear(); + + virtual void Make(D3DXVECTOR3 v3Center, D3DXVECTOR3 v3Normal, D3DXVECTOR3 v3Tangent, float fWidth, float fHeight, float fDepth) = 0; +// virtual void Update(); + virtual void Render(); + +protected: + // + D3DXVECTOR3 m_v3Center; + D3DXVECTOR3 m_v3Normal; + + // Clip Plane + D3DXPLANE m_v4LeftPlane; + D3DXPLANE m_v4RightPlane; + D3DXPLANE m_v4BottomPlane; + D3DXPLANE m_v4TopPlane; + D3DXPLANE m_v4FrontPlane; + D3DXPLANE m_v4BackPlane; + + // + DWORD m_dwVertexCount; + DWORD m_dwPrimitiveCount; + + // ý ۿ δ콺 +// CGraphicVertexBuffer m_GraphicVertexBuffer; +// CGraphicIndexBuffer m_GraphicIndexBuffer; + + // ý ۿ δ콺 ſ 迭 DrawIndexedPrimitiveUP ׸. + typedef struct + { + WORD m_wMinIndex; + DWORD m_dwVertexCount; + DWORD m_dwPrimitiveCount; + DWORD m_dwVBOffset; + } TTRIANGLEFANSTRUCT; + + std::vector m_TriangleFanStructVector; + + TPDTVertex m_Vertices[MAX_DECAL_VERTICES]; + WORD m_Indices[MAX_DECAL_VERTICES]; + + const float m_cfDecalEpsilon; + +protected: + bool AddPolygon(DWORD dwAddCount, const D3DXVECTOR3 *c_pv3Vertex, const D3DXVECTOR3 *c_pv3Normal); + void ClipMesh(DWORD dwPrimitiveCount, const D3DXVECTOR3 *c_pv3Vertex, const D3DXVECTOR3 *c_pv3Normal); + DWORD ClipPolygon(DWORD dwVertexCount, + const D3DXVECTOR3 *c_pv3Vertex, + const D3DXVECTOR3 *c_pv3Normal, + D3DXVECTOR3 *c_pv3NewVertex, + D3DXVECTOR3 *c_pv3NewNormal) const; + static DWORD ClipPolygonAgainstPlane(const D3DXPLANE& v4Plane, + DWORD dwVertexCount, + const D3DXVECTOR3 *c_pv3Vertex, + const D3DXVECTOR3 *c_pv3Normal, + D3DXVECTOR3 *c_pv3NewVertex, + D3DXVECTOR3 *c_pv3NewNormal); +}; +/* + +class CDecalManager : public CSingleton +{ +public: + CDecalManager(); + ~CDecalManager(); + + void Add(CDecal * pDecal); + void Remove(CDecal * pDecal); + void Update(); + void Render(); + +private: + std::vector m_DecalPtrVector; + +}; + +*/ +#endif // !defined(AFX_DECAL_H__E3D27DFC_30CB_4995_B9B9_396B5E8A5F02__INCLUDED_) diff --git a/source/EterLib/DibBar.cpp b/source/EterLib/DibBar.cpp new file mode 100644 index 0000000..2108a0b --- /dev/null +++ b/source/EterLib/DibBar.cpp @@ -0,0 +1,163 @@ +#include "StdAfx.h" +#include "DibBar.h" +#include "BlockTexture.h" + +void CDibBar::Invalidate() +{ + RECT rect = { static_cast(0), static_cast(0), static_cast(m_dwWidth), static_cast(m_dwHeight)}; + + std::vector::iterator itor = m_kVec_pkBlockTexture.begin(); + for (; itor != m_kVec_pkBlockTexture.end(); ++itor) + { + CBlockTexture * pTexture = *itor; + pTexture->InvalidateRect(rect); + } +} + +void CDibBar::SetClipRect(const RECT & c_rRect) +{ + std::vector::iterator itor = m_kVec_pkBlockTexture.begin(); + for (; itor != m_kVec_pkBlockTexture.end(); ++itor) + { + CBlockTexture * pTexture = *itor; + assert(pTexture); + if (!pTexture) + continue; + pTexture->SetClipRect(c_rRect); + } +} + +void CDibBar::ClearBar() +{ + DWORD * pdwBuf = (DWORD *)m_dib.GetPointer(); + memset(pdwBuf, 0, m_dib.GetWidth()*m_dib.GetHeight()*4); + Invalidate(); +} + +void CDibBar::Render(int ix, int iy) +{ + std::vector::iterator itor = m_kVec_pkBlockTexture.begin(); + for (; itor != m_kVec_pkBlockTexture.end(); ++itor) + { + CBlockTexture * pTexture = *itor; + pTexture->Render(ix, iy); + } +} + +DWORD CDibBar::__NearTextureSize(DWORD dwSize) +{ + if ((dwSize & (dwSize-1)) == 0) + return dwSize; + + DWORD dwRet = 2; + while (dwRet < dwSize) + { + dwRet <<= 1; + } + + return dwRet; +} + +void CDibBar::__DivideTextureSize(DWORD dwSize, DWORD dwMax, DWORD * pdwxStep, DWORD * pdwxCount, DWORD * pdwxRest) +{ + if (dwSize(dwxPos), static_cast(dwyPos), static_cast(dwxPos+dwImageWidth), static_cast(dwyPos+dwImageHeight)}; + + CBlockTexture * pBlockTexture = new CBlockTexture; + if (!pBlockTexture->Create(&m_dib, posRect, dwTextureWidth, dwTextureHeight)) + { + delete pBlockTexture; + return NULL; + } + + return pBlockTexture; +} + +void CDibBar::__BuildTextureBlockList(DWORD dwWidth, DWORD dwHeight, DWORD dwMax) +{ + DWORD dwxStep, dwyStep; + DWORD dwxCount, dwyCount; + DWORD dwxRest, dwyRest; + __DivideTextureSize(dwWidth, dwMax, &dwxStep, &dwxCount, &dwxRest); + __DivideTextureSize(dwHeight, dwMax, &dwyStep, &dwyCount, &dwyRest); + DWORD dwxTexRest = __NearTextureSize(dwxRest); + DWORD dwyTexRest = __NearTextureSize(dwyRest); + + for (DWORD y = 0; y < dwyCount; ++y) + { + for (DWORD x = 0; x < dwxCount; ++x) + { + CBlockTexture * pTexture = __BuildTextureBlock(x*dwxStep, y*dwyStep, + dwxStep, dwyStep, + dwMax, dwMax); + if (pTexture) + m_kVec_pkBlockTexture.push_back(pTexture); + } + + CBlockTexture * pTexture = __BuildTextureBlock(dwxCount*dwxStep, y*dwyStep, + dwxRest, dwyStep, + dwxTexRest, dwMax); + + if (pTexture) + m_kVec_pkBlockTexture.push_back(pTexture); + } + + for (DWORD x = 0; x < dwxCount; ++x) + { + CBlockTexture * pTexture = __BuildTextureBlock(x*dwxStep, dwyCount*dwyStep, + dwxStep, dwyRest, + dwMax, dwyTexRest); + if (pTexture) + m_kVec_pkBlockTexture.push_back(pTexture); + } + + if (dwxRest > 0 && dwyRest > 0) + { + CBlockTexture * pTexture = __BuildTextureBlock(dwxCount*dwxStep, dwyCount*dwyStep, + dwxRest, dwyRest, + dwxTexRest, dwyTexRest); + if (pTexture) + m_kVec_pkBlockTexture.push_back(pTexture); + } +} + +bool CDibBar::Create(HDC hdc, DWORD dwWidth, DWORD dwHeight) +{ + if (!m_dib.Create(hdc, dwWidth, dwHeight)) + { + Tracef(" Failed to create CDibBar\n"); + return false; + } + + m_dwWidth = dwWidth; + m_dwHeight = dwHeight; + + __BuildTextureBlockList(dwWidth, dwHeight); + OnCreate(); + + return true; +} + +CDibBar::CDibBar() +{ +} +CDibBar::~CDibBar() +{ +} diff --git a/source/EterLib/DibBar.h b/source/EterLib/DibBar.h new file mode 100644 index 0000000..29f16b3 --- /dev/null +++ b/source/EterLib/DibBar.h @@ -0,0 +1,33 @@ +#pragma once + +#include "GrpDib.h" + +class CBlockTexture; + +class CDibBar +{ + public: + CDibBar(); + virtual ~CDibBar(); + + bool Create(HDC hdc, DWORD dwWidth, DWORD dwHeight); + void Invalidate(); + void SetClipRect(const RECT & c_rRect); + void ClearBar(); + void Render(int ix, int iy); + + protected: + DWORD __NearTextureSize(DWORD dwSize); + void __DivideTextureSize(DWORD dwSize, DWORD dwMax, DWORD * pdwxStep, DWORD * pdwxCount, DWORD * pdwxRest); + CBlockTexture * __BuildTextureBlock(DWORD dwxPos, DWORD dwyPos, DWORD dwImageWidth, DWORD dwImageHeight, DWORD dwTextureWidth, DWORD dwTextureHeight); + void __BuildTextureBlockList(DWORD dwWidth, DWORD dwHeight, DWORD dwMax=256); + + virtual void OnCreate(){} + + protected: + CGraphicDib m_dib; + std::vector m_kVec_pkBlockTexture; + + DWORD m_dwWidth; + DWORD m_dwHeight; +}; diff --git a/source/EterLib/Dimm.h b/source/EterLib/Dimm.h new file mode 100644 index 0000000..c8255b0 --- /dev/null +++ b/source/EterLib/Dimm.h @@ -0,0 +1,6579 @@ + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 6.00.0361 */ +/* Compiler settings for dimm.idl: + Oicf, W1, Zp8, env=Win32 (32b run) + protocol : dce , ms_ext, c_ext + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +//@@MIDL_FILE_HEADING( ) + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 440 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __dimm_h__ +#define __dimm_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef __IEnumRegisterWordA_FWD_DEFINED__ +#define __IEnumRegisterWordA_FWD_DEFINED__ +typedef interface IEnumRegisterWordA IEnumRegisterWordA; +#endif /* __IEnumRegisterWordA_FWD_DEFINED__ */ + + +#ifndef __IEnumRegisterWordW_FWD_DEFINED__ +#define __IEnumRegisterWordW_FWD_DEFINED__ +typedef interface IEnumRegisterWordW IEnumRegisterWordW; +#endif /* __IEnumRegisterWordW_FWD_DEFINED__ */ + + +#ifndef __IEnumInputContext_FWD_DEFINED__ +#define __IEnumInputContext_FWD_DEFINED__ +typedef interface IEnumInputContext IEnumInputContext; +#endif /* __IEnumInputContext_FWD_DEFINED__ */ + + +#ifndef __IActiveIMMRegistrar_FWD_DEFINED__ +#define __IActiveIMMRegistrar_FWD_DEFINED__ +typedef interface IActiveIMMRegistrar IActiveIMMRegistrar; +#endif /* __IActiveIMMRegistrar_FWD_DEFINED__ */ + + +#ifndef __IActiveIMMMessagePumpOwner_FWD_DEFINED__ +#define __IActiveIMMMessagePumpOwner_FWD_DEFINED__ +typedef interface IActiveIMMMessagePumpOwner IActiveIMMMessagePumpOwner; +#endif /* __IActiveIMMMessagePumpOwner_FWD_DEFINED__ */ + + +#ifndef __IActiveIMMApp_FWD_DEFINED__ +#define __IActiveIMMApp_FWD_DEFINED__ +typedef interface IActiveIMMApp IActiveIMMApp; +#endif /* __IActiveIMMApp_FWD_DEFINED__ */ + + +#ifndef __IActiveIMMIME_FWD_DEFINED__ +#define __IActiveIMMIME_FWD_DEFINED__ +typedef interface IActiveIMMIME IActiveIMMIME; +#endif /* __IActiveIMMIME_FWD_DEFINED__ */ + + +#ifndef __IActiveIME_FWD_DEFINED__ +#define __IActiveIME_FWD_DEFINED__ +typedef interface IActiveIME IActiveIME; +#endif /* __IActiveIME_FWD_DEFINED__ */ + + +#ifndef __IActiveIME2_FWD_DEFINED__ +#define __IActiveIME2_FWD_DEFINED__ +typedef interface IActiveIME2 IActiveIME2; +#endif /* __IActiveIME2_FWD_DEFINED__ */ + + +#ifndef __CActiveIMM_FWD_DEFINED__ +#define __CActiveIMM_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class CActiveIMM CActiveIMM; +#else +typedef struct CActiveIMM CActiveIMM; +#endif /* __cplusplus */ + +#endif /* __CActiveIMM_FWD_DEFINED__ */ + + +/* header files for imported files */ +#include "unknwn.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +void * __RPC_USER MIDL_user_allocate(size_t); +void __RPC_USER MIDL_user_free( void * ); + +/* interface __MIDL_itf_dimm_0000 */ +/* [local] */ + +//=--------------------------------------------------------------------------= +// dimm.h +//=--------------------------------------------------------------------------= +// (C) Copyright 1995-1998 Microsoft Corporation. All Rights Reserved. +// +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A +// PARTICULAR PURPOSE. +//=--------------------------------------------------------------------------= + +#pragma comment(lib,"uuid.lib") + +//-------------------------------------------------------------------------- +// IActiveIMM Interfaces. + + + + +extern RPC_IF_HANDLE __MIDL_itf_dimm_0000_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_dimm_0000_v0_0_s_ifspec; + + +#ifndef __ActiveIMM_LIBRARY_DEFINED__ +#define __ActiveIMM_LIBRARY_DEFINED__ + +/* library ActiveIMM */ +/* [version][lcid][helpstring][uuid] */ + +#include +#if 0 +typedef WORD LANGID; + +typedef /* [public][public][public][public] */ struct __MIDL___MIDL_itf_dimm_0000_0001 + { + LPSTR lpReading; + LPSTR lpWord; + } REGISTERWORDA; + +typedef /* [public][public][public][public][public] */ struct __MIDL___MIDL_itf_dimm_0000_0002 + { + LPWSTR lpReading; + LPWSTR lpWord; + } REGISTERWORDW; + +typedef /* [public][public][public][public][public][public][public] */ struct __MIDL___MIDL_itf_dimm_0000_0003 + { + LONG lfHeight; + LONG lfWidth; + LONG lfEscapement; + LONG lfOrientation; + LONG lfWeight; + BYTE lfItalic; + BYTE lfUnderline; + BYTE lfStrikeOut; + BYTE lfCharSet; + BYTE lfOutPrecision; + BYTE lfClipPrecision; + BYTE lfQuality; + BYTE lfPitchAndFamily; + CHAR lfFaceName[ 32 ]; + } LOGFONTA; + +typedef /* [public][public][public][public][public][public][public] */ struct __MIDL___MIDL_itf_dimm_0000_0004 + { + LONG lfHeight; + LONG lfWidth; + LONG lfEscapement; + LONG lfOrientation; + LONG lfWeight; + BYTE lfItalic; + BYTE lfUnderline; + BYTE lfStrikeOut; + BYTE lfCharSet; + BYTE lfOutPrecision; + BYTE lfClipPrecision; + BYTE lfQuality; + BYTE lfPitchAndFamily; + WCHAR lfFaceName[ 32 ]; + } LOGFONTW; + +typedef DWORD HIMC; + +typedef DWORD HIMCC; + +typedef /* [public][public][public][public][public][public][public] */ struct __MIDL___MIDL_itf_dimm_0000_0005 + { + DWORD dwIndex; + DWORD dwStyle; + POINT ptCurrentPos; + RECT rcArea; + } CANDIDATEFORM; + +typedef /* [public][public][public][public][public][public][public] */ struct __MIDL___MIDL_itf_dimm_0000_0006 + { + DWORD dwStyle; + POINT ptCurrentPos; + RECT rcArea; + } COMPOSITIONFORM; + +typedef /* [public][public][public][public][public][public][public][public][public][public] */ struct __MIDL___MIDL_itf_dimm_0000_0007 + { + DWORD dwSize; + DWORD dwStyle; + DWORD dwCount; + DWORD dwSelection; + DWORD dwPageStart; + DWORD dwPageSize; + DWORD dwOffset[ 1 ]; + } CANDIDATELIST; + +typedef /* [public][public][public] */ struct __MIDL___MIDL_itf_dimm_0000_0008 + { + DWORD dwStyle; + CHAR szDescription[ 32 ]; + } STYLEBUFA; + +typedef /* [public][public][public][public] */ struct __MIDL___MIDL_itf_dimm_0000_0009 + { + DWORD dwStyle; + WCHAR szDescription[ 32 ]; + } STYLEBUFW; + +typedef WORD ATOM; + +#endif +#if (WINVER < 0x040A) +typedef /* [public][public][public][public][public] */ struct __MIDL___MIDL_itf_dimm_0000_0010 + { + UINT cbSize; + UINT fType; + UINT fState; + UINT wID; + HBITMAP hbmpChecked; + HBITMAP hbmpUnchecked; + DWORD dwItemData; + CHAR szString[ 80 ]; + HBITMAP hbmpItem; + } IMEMENUITEMINFOA; + +typedef /* [public][public][public][public][public] */ struct __MIDL___MIDL_itf_dimm_0000_0011 + { + UINT cbSize; + UINT fType; + UINT fState; + UINT wID; + HBITMAP hbmpChecked; + HBITMAP hbmpUnchecked; + DWORD dwItemData; + WCHAR szString[ 80 ]; + HBITMAP hbmpItem; + } IMEMENUITEMINFOW; + +#endif +#ifndef _DDKIMM_H_ +typedef /* [public][public] */ struct __MIDL___MIDL_itf_dimm_0000_0012 + { + HWND hWnd; + BOOL fOpen; + POINT ptStatusWndPos; + POINT ptSoftKbdPos; + DWORD fdwConversion; + DWORD fdwSentence; + union + { + LOGFONTA A; + LOGFONTW W; + } lfFont; + COMPOSITIONFORM cfCompForm; + CANDIDATEFORM cfCandForm[ 4 ]; + HIMCC hCompStr; + HIMCC hCandInfo; + HIMCC hGuideLine; + HIMCC hPrivate; + DWORD dwNumMsgBuf; + HIMCC hMsgBuf; + DWORD fdwInit; + DWORD dwReserve[ 3 ]; + } INPUTCONTEXT; + +typedef /* [public][public] */ struct __MIDL___MIDL_itf_dimm_0000_0014 + { + DWORD dwPrivateDataSize; + DWORD fdwProperty; + DWORD fdwConversionCaps; + DWORD fdwSentenceCaps; + DWORD fdwUICaps; + DWORD fdwSCSCaps; + DWORD fdwSelectCaps; + } IMEINFO; + +#endif + +EXTERN_C const IID LIBID_ActiveIMM; + +#ifndef __IEnumRegisterWordA_INTERFACE_DEFINED__ +#define __IEnumRegisterWordA_INTERFACE_DEFINED__ + +/* interface IEnumRegisterWordA */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_IEnumRegisterWordA; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("08C03412-F96B-11d0-A475-00AA006BCC59") + IEnumRegisterWordA : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ IEnumRegisterWordA **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG ulCount, + /* [out] */ REGISTERWORDA *rgRegisterWord, + /* [out] */ ULONG *pcFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG ulCount) = 0; + + }; + +#else /* C style interface */ + + typedef struct IEnumRegisterWordAVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IEnumRegisterWordA * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IEnumRegisterWordA * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IEnumRegisterWordA * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IEnumRegisterWordA * This, + /* [out] */ IEnumRegisterWordA **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IEnumRegisterWordA * This, + /* [in] */ ULONG ulCount, + /* [out] */ REGISTERWORDA *rgRegisterWord, + /* [out] */ ULONG *pcFetched); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IEnumRegisterWordA * This); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + IEnumRegisterWordA * This, + /* [in] */ ULONG ulCount); + + END_INTERFACE + } IEnumRegisterWordAVtbl; + + interface IEnumRegisterWordA + { + CONST_VTBL struct IEnumRegisterWordAVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IEnumRegisterWordA_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define IEnumRegisterWordA_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define IEnumRegisterWordA_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define IEnumRegisterWordA_Clone(This,ppEnum) \ + (This)->lpVtbl -> Clone(This,ppEnum) + +#define IEnumRegisterWordA_Next(This,ulCount,rgRegisterWord,pcFetched) \ + (This)->lpVtbl -> Next(This,ulCount,rgRegisterWord,pcFetched) + +#define IEnumRegisterWordA_Reset(This) \ + (This)->lpVtbl -> Reset(This) + +#define IEnumRegisterWordA_Skip(This,ulCount) \ + (This)->lpVtbl -> Skip(This,ulCount) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +HRESULT STDMETHODCALLTYPE IEnumRegisterWordA_Clone_Proxy( + IEnumRegisterWordA * This, + /* [out] */ IEnumRegisterWordA **ppEnum); + + +void __RPC_STUB IEnumRegisterWordA_Clone_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IEnumRegisterWordA_Next_Proxy( + IEnumRegisterWordA * This, + /* [in] */ ULONG ulCount, + /* [out] */ REGISTERWORDA *rgRegisterWord, + /* [out] */ ULONG *pcFetched); + + +void __RPC_STUB IEnumRegisterWordA_Next_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IEnumRegisterWordA_Reset_Proxy( + IEnumRegisterWordA * This); + + +void __RPC_STUB IEnumRegisterWordA_Reset_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IEnumRegisterWordA_Skip_Proxy( + IEnumRegisterWordA * This, + /* [in] */ ULONG ulCount); + + +void __RPC_STUB IEnumRegisterWordA_Skip_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IEnumRegisterWordA_INTERFACE_DEFINED__ */ + + +#ifndef __IEnumRegisterWordW_INTERFACE_DEFINED__ +#define __IEnumRegisterWordW_INTERFACE_DEFINED__ + +/* interface IEnumRegisterWordW */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_IEnumRegisterWordW; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("4955DD31-B159-11d0-8FCF-00AA006BCC59") + IEnumRegisterWordW : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ IEnumRegisterWordW **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG ulCount, + /* [out] */ REGISTERWORDW *rgRegisterWord, + /* [out] */ ULONG *pcFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG ulCount) = 0; + + }; + +#else /* C style interface */ + + typedef struct IEnumRegisterWordWVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IEnumRegisterWordW * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IEnumRegisterWordW * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IEnumRegisterWordW * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IEnumRegisterWordW * This, + /* [out] */ IEnumRegisterWordW **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IEnumRegisterWordW * This, + /* [in] */ ULONG ulCount, + /* [out] */ REGISTERWORDW *rgRegisterWord, + /* [out] */ ULONG *pcFetched); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IEnumRegisterWordW * This); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + IEnumRegisterWordW * This, + /* [in] */ ULONG ulCount); + + END_INTERFACE + } IEnumRegisterWordWVtbl; + + interface IEnumRegisterWordW + { + CONST_VTBL struct IEnumRegisterWordWVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IEnumRegisterWordW_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define IEnumRegisterWordW_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define IEnumRegisterWordW_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define IEnumRegisterWordW_Clone(This,ppEnum) \ + (This)->lpVtbl -> Clone(This,ppEnum) + +#define IEnumRegisterWordW_Next(This,ulCount,rgRegisterWord,pcFetched) \ + (This)->lpVtbl -> Next(This,ulCount,rgRegisterWord,pcFetched) + +#define IEnumRegisterWordW_Reset(This) \ + (This)->lpVtbl -> Reset(This) + +#define IEnumRegisterWordW_Skip(This,ulCount) \ + (This)->lpVtbl -> Skip(This,ulCount) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +HRESULT STDMETHODCALLTYPE IEnumRegisterWordW_Clone_Proxy( + IEnumRegisterWordW * This, + /* [out] */ IEnumRegisterWordW **ppEnum); + + +void __RPC_STUB IEnumRegisterWordW_Clone_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IEnumRegisterWordW_Next_Proxy( + IEnumRegisterWordW * This, + /* [in] */ ULONG ulCount, + /* [out] */ REGISTERWORDW *rgRegisterWord, + /* [out] */ ULONG *pcFetched); + + +void __RPC_STUB IEnumRegisterWordW_Next_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IEnumRegisterWordW_Reset_Proxy( + IEnumRegisterWordW * This); + + +void __RPC_STUB IEnumRegisterWordW_Reset_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IEnumRegisterWordW_Skip_Proxy( + IEnumRegisterWordW * This, + /* [in] */ ULONG ulCount); + + +void __RPC_STUB IEnumRegisterWordW_Skip_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IEnumRegisterWordW_INTERFACE_DEFINED__ */ + + +#ifndef __IEnumInputContext_INTERFACE_DEFINED__ +#define __IEnumInputContext_INTERFACE_DEFINED__ + +/* interface IEnumInputContext */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_IEnumInputContext; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("09b5eab0-f997-11d1-93d4-0060b067b86e") + IEnumInputContext : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ IEnumInputContext **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG ulCount, + /* [out] */ HIMC *rgInputContext, + /* [out] */ ULONG *pcFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG ulCount) = 0; + + }; + +#else /* C style interface */ + + typedef struct IEnumInputContextVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IEnumInputContext * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IEnumInputContext * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IEnumInputContext * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IEnumInputContext * This, + /* [out] */ IEnumInputContext **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IEnumInputContext * This, + /* [in] */ ULONG ulCount, + /* [out] */ HIMC *rgInputContext, + /* [out] */ ULONG *pcFetched); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IEnumInputContext * This); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + IEnumInputContext * This, + /* [in] */ ULONG ulCount); + + END_INTERFACE + } IEnumInputContextVtbl; + + interface IEnumInputContext + { + CONST_VTBL struct IEnumInputContextVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IEnumInputContext_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define IEnumInputContext_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define IEnumInputContext_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define IEnumInputContext_Clone(This,ppEnum) \ + (This)->lpVtbl -> Clone(This,ppEnum) + +#define IEnumInputContext_Next(This,ulCount,rgInputContext,pcFetched) \ + (This)->lpVtbl -> Next(This,ulCount,rgInputContext,pcFetched) + +#define IEnumInputContext_Reset(This) \ + (This)->lpVtbl -> Reset(This) + +#define IEnumInputContext_Skip(This,ulCount) \ + (This)->lpVtbl -> Skip(This,ulCount) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +HRESULT STDMETHODCALLTYPE IEnumInputContext_Clone_Proxy( + IEnumInputContext * This, + /* [out] */ IEnumInputContext **ppEnum); + + +void __RPC_STUB IEnumInputContext_Clone_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IEnumInputContext_Next_Proxy( + IEnumInputContext * This, + /* [in] */ ULONG ulCount, + /* [out] */ HIMC *rgInputContext, + /* [out] */ ULONG *pcFetched); + + +void __RPC_STUB IEnumInputContext_Next_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IEnumInputContext_Reset_Proxy( + IEnumInputContext * This); + + +void __RPC_STUB IEnumInputContext_Reset_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IEnumInputContext_Skip_Proxy( + IEnumInputContext * This, + /* [in] */ ULONG ulCount); + + +void __RPC_STUB IEnumInputContext_Skip_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IEnumInputContext_INTERFACE_DEFINED__ */ + + +#ifndef __IActiveIMMRegistrar_INTERFACE_DEFINED__ +#define __IActiveIMMRegistrar_INTERFACE_DEFINED__ + +/* interface IActiveIMMRegistrar */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_IActiveIMMRegistrar; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("b3458082-bd00-11d1-939b-0060b067b86e") + IActiveIMMRegistrar : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE RegisterIME( + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID lgid, + /* [in] */ LPCWSTR pszIconFile, + /* [in] */ LPCWSTR pszDesc) = 0; + + virtual HRESULT STDMETHODCALLTYPE UnregisterIME( + /* [in] */ REFCLSID rclsid) = 0; + + }; + +#else /* C style interface */ + + typedef struct IActiveIMMRegistrarVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IActiveIMMRegistrar * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IActiveIMMRegistrar * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IActiveIMMRegistrar * This); + + HRESULT ( STDMETHODCALLTYPE *RegisterIME )( + IActiveIMMRegistrar * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID lgid, + /* [in] */ LPCWSTR pszIconFile, + /* [in] */ LPCWSTR pszDesc); + + HRESULT ( STDMETHODCALLTYPE *UnregisterIME )( + IActiveIMMRegistrar * This, + /* [in] */ REFCLSID rclsid); + + END_INTERFACE + } IActiveIMMRegistrarVtbl; + + interface IActiveIMMRegistrar + { + CONST_VTBL struct IActiveIMMRegistrarVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IActiveIMMRegistrar_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define IActiveIMMRegistrar_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define IActiveIMMRegistrar_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define IActiveIMMRegistrar_RegisterIME(This,rclsid,lgid,pszIconFile,pszDesc) \ + (This)->lpVtbl -> RegisterIME(This,rclsid,lgid,pszIconFile,pszDesc) + +#define IActiveIMMRegistrar_UnregisterIME(This,rclsid) \ + (This)->lpVtbl -> UnregisterIME(This,rclsid) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +HRESULT STDMETHODCALLTYPE IActiveIMMRegistrar_RegisterIME_Proxy( + IActiveIMMRegistrar * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID lgid, + /* [in] */ LPCWSTR pszIconFile, + /* [in] */ LPCWSTR pszDesc); + + +void __RPC_STUB IActiveIMMRegistrar_RegisterIME_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMRegistrar_UnregisterIME_Proxy( + IActiveIMMRegistrar * This, + /* [in] */ REFCLSID rclsid); + + +void __RPC_STUB IActiveIMMRegistrar_UnregisterIME_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IActiveIMMRegistrar_INTERFACE_DEFINED__ */ + + +#ifndef __IActiveIMMMessagePumpOwner_INTERFACE_DEFINED__ +#define __IActiveIMMMessagePumpOwner_INTERFACE_DEFINED__ + +/* interface IActiveIMMMessagePumpOwner */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_IActiveIMMMessagePumpOwner; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("b5cf2cfa-8aeb-11d1-9364-0060b067b86e") + IActiveIMMMessagePumpOwner : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Start( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE End( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnTranslateMessage( + /* [in] */ const MSG *pMsg) = 0; + + virtual HRESULT STDMETHODCALLTYPE Pause( + /* [out] */ DWORD *pdwCookie) = 0; + + virtual HRESULT STDMETHODCALLTYPE Resume( + /* [in] */ DWORD dwCookie) = 0; + + }; + +#else /* C style interface */ + + typedef struct IActiveIMMMessagePumpOwnerVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IActiveIMMMessagePumpOwner * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IActiveIMMMessagePumpOwner * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IActiveIMMMessagePumpOwner * This); + + HRESULT ( STDMETHODCALLTYPE *Start )( + IActiveIMMMessagePumpOwner * This); + + HRESULT ( STDMETHODCALLTYPE *End )( + IActiveIMMMessagePumpOwner * This); + + HRESULT ( STDMETHODCALLTYPE *OnTranslateMessage )( + IActiveIMMMessagePumpOwner * This, + /* [in] */ const MSG *pMsg); + + HRESULT ( STDMETHODCALLTYPE *Pause )( + IActiveIMMMessagePumpOwner * This, + /* [out] */ DWORD *pdwCookie); + + HRESULT ( STDMETHODCALLTYPE *Resume )( + IActiveIMMMessagePumpOwner * This, + /* [in] */ DWORD dwCookie); + + END_INTERFACE + } IActiveIMMMessagePumpOwnerVtbl; + + interface IActiveIMMMessagePumpOwner + { + CONST_VTBL struct IActiveIMMMessagePumpOwnerVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IActiveIMMMessagePumpOwner_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define IActiveIMMMessagePumpOwner_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define IActiveIMMMessagePumpOwner_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define IActiveIMMMessagePumpOwner_Start(This) \ + (This)->lpVtbl -> Start(This) + +#define IActiveIMMMessagePumpOwner_End(This) \ + (This)->lpVtbl -> End(This) + +#define IActiveIMMMessagePumpOwner_OnTranslateMessage(This,pMsg) \ + (This)->lpVtbl -> OnTranslateMessage(This,pMsg) + +#define IActiveIMMMessagePumpOwner_Pause(This,pdwCookie) \ + (This)->lpVtbl -> Pause(This,pdwCookie) + +#define IActiveIMMMessagePumpOwner_Resume(This,dwCookie) \ + (This)->lpVtbl -> Resume(This,dwCookie) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +HRESULT STDMETHODCALLTYPE IActiveIMMMessagePumpOwner_Start_Proxy( + IActiveIMMMessagePumpOwner * This); + + +void __RPC_STUB IActiveIMMMessagePumpOwner_Start_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMMessagePumpOwner_End_Proxy( + IActiveIMMMessagePumpOwner * This); + + +void __RPC_STUB IActiveIMMMessagePumpOwner_End_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMMessagePumpOwner_OnTranslateMessage_Proxy( + IActiveIMMMessagePumpOwner * This, + /* [in] */ const MSG *pMsg); + + +void __RPC_STUB IActiveIMMMessagePumpOwner_OnTranslateMessage_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMMessagePumpOwner_Pause_Proxy( + IActiveIMMMessagePumpOwner * This, + /* [out] */ DWORD *pdwCookie); + + +void __RPC_STUB IActiveIMMMessagePumpOwner_Pause_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMMessagePumpOwner_Resume_Proxy( + IActiveIMMMessagePumpOwner * This, + /* [in] */ DWORD dwCookie); + + +void __RPC_STUB IActiveIMMMessagePumpOwner_Resume_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IActiveIMMMessagePumpOwner_INTERFACE_DEFINED__ */ + + +#ifndef __IActiveIMMApp_INTERFACE_DEFINED__ +#define __IActiveIMMApp_INTERFACE_DEFINED__ + +/* interface IActiveIMMApp */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_IActiveIMMApp; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("08c0e040-62d1-11d1-9326-0060b067b86e") + IActiveIMMApp : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE AssociateContext( + /* [in] */ HWND hWnd, + /* [in] */ HIMC hIME, + /* [out] */ HIMC *phPrev) = 0; + + virtual HRESULT STDMETHODCALLTYPE ConfigureIMEA( + /* [in] */ HKL hKL, + /* [in] */ HWND hWnd, + /* [in] */ DWORD dwMode, + /* [in] */ REGISTERWORDA *pData) = 0; + + virtual HRESULT STDMETHODCALLTYPE ConfigureIMEW( + /* [in] */ HKL hKL, + /* [in] */ HWND hWnd, + /* [in] */ DWORD dwMode, + /* [in] */ REGISTERWORDW *pData) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateContext( + /* [out] */ HIMC *phIMC) = 0; + + virtual HRESULT STDMETHODCALLTYPE DestroyContext( + /* [in] */ HIMC hIME) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnumRegisterWordA( + /* [in] */ HKL hKL, + /* [in] */ LPSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPSTR szRegister, + /* [in] */ LPVOID pData, + /* [out] */ IEnumRegisterWordA **pEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnumRegisterWordW( + /* [in] */ HKL hKL, + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szRegister, + /* [in] */ LPVOID pData, + /* [out] */ IEnumRegisterWordW **pEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE EscapeA( + /* [in] */ HKL hKL, + /* [in] */ HIMC hIMC, + /* [in] */ UINT uEscape, + /* [out][in] */ LPVOID pData, + /* [out] */ LRESULT *plResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE EscapeW( + /* [in] */ HKL hKL, + /* [in] */ HIMC hIMC, + /* [in] */ UINT uEscape, + /* [out][in] */ LPVOID pData, + /* [out] */ LRESULT *plResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCandidateListA( + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ UINT uBufLen, + /* [out] */ CANDIDATELIST *pCandList, + /* [out] */ UINT *puCopied) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCandidateListW( + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ UINT uBufLen, + /* [out] */ CANDIDATELIST *pCandList, + /* [out] */ UINT *puCopied) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCandidateListCountA( + /* [in] */ HIMC hIMC, + /* [out] */ DWORD *pdwListSize, + /* [out] */ DWORD *pdwBufLen) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCandidateListCountW( + /* [in] */ HIMC hIMC, + /* [out] */ DWORD *pdwListSize, + /* [out] */ DWORD *pdwBufLen) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCandidateWindow( + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [out] */ CANDIDATEFORM *pCandidate) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCompositionFontA( + /* [in] */ HIMC hIMC, + /* [out] */ LOGFONTA *plf) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCompositionFontW( + /* [in] */ HIMC hIMC, + /* [out] */ LOGFONTW *plf) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCompositionStringA( + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwBufLen, + /* [out] */ LONG *plCopied, + /* [out] */ LPVOID pBuf) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCompositionStringW( + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwBufLen, + /* [out] */ LONG *plCopied, + /* [out] */ LPVOID pBuf) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCompositionWindow( + /* [in] */ HIMC hIMC, + /* [out] */ COMPOSITIONFORM *pCompForm) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetContext( + /* [in] */ HWND hWnd, + /* [out] */ HIMC *phIMC) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetConversionListA( + /* [in] */ HKL hKL, + /* [in] */ HIMC hIMC, + /* [in] */ LPSTR pSrc, + /* [in] */ UINT uBufLen, + /* [in] */ UINT uFlag, + /* [out] */ CANDIDATELIST *pDst, + /* [out] */ UINT *puCopied) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetConversionListW( + /* [in] */ HKL hKL, + /* [in] */ HIMC hIMC, + /* [in] */ LPWSTR pSrc, + /* [in] */ UINT uBufLen, + /* [in] */ UINT uFlag, + /* [out] */ CANDIDATELIST *pDst, + /* [out] */ UINT *puCopied) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetConversionStatus( + /* [in] */ HIMC hIMC, + /* [out] */ DWORD *pfdwConversion, + /* [out] */ DWORD *pfdwSentence) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDefaultIMEWnd( + /* [in] */ HWND hWnd, + /* [out] */ HWND *phDefWnd) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDescriptionA( + /* [in] */ HKL hKL, + /* [in] */ UINT uBufLen, + /* [out] */ LPSTR szDescription, + /* [out] */ UINT *puCopied) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDescriptionW( + /* [in] */ HKL hKL, + /* [in] */ UINT uBufLen, + /* [out] */ LPWSTR szDescription, + /* [out] */ UINT *puCopied) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetGuideLineA( + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwBufLen, + /* [out] */ LPSTR pBuf, + /* [out] */ DWORD *pdwResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetGuideLineW( + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwBufLen, + /* [out] */ LPWSTR pBuf, + /* [out] */ DWORD *pdwResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetIMEFileNameA( + /* [in] */ HKL hKL, + /* [in] */ UINT uBufLen, + /* [out] */ LPSTR szFileName, + /* [out] */ UINT *puCopied) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetIMEFileNameW( + /* [in] */ HKL hKL, + /* [in] */ UINT uBufLen, + /* [out] */ LPWSTR szFileName, + /* [out] */ UINT *puCopied) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetOpenStatus( + /* [in] */ HIMC hIMC) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetProperty( + /* [in] */ HKL hKL, + /* [in] */ DWORD fdwIndex, + /* [out] */ DWORD *pdwProperty) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetRegisterWordStyleA( + /* [in] */ HKL hKL, + /* [in] */ UINT nItem, + /* [out] */ STYLEBUFA *pStyleBuf, + /* [out] */ UINT *puCopied) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetRegisterWordStyleW( + /* [in] */ HKL hKL, + /* [in] */ UINT nItem, + /* [out] */ STYLEBUFW *pStyleBuf, + /* [out] */ UINT *puCopied) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetStatusWindowPos( + /* [in] */ HIMC hIMC, + /* [out] */ POINT *pptPos) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetVirtualKey( + /* [in] */ HWND hWnd, + /* [out] */ UINT *puVirtualKey) = 0; + + virtual HRESULT STDMETHODCALLTYPE InstallIMEA( + /* [in] */ LPSTR szIMEFileName, + /* [in] */ LPSTR szLayoutText, + /* [out] */ HKL *phKL) = 0; + + virtual HRESULT STDMETHODCALLTYPE InstallIMEW( + /* [in] */ LPWSTR szIMEFileName, + /* [in] */ LPWSTR szLayoutText, + /* [out] */ HKL *phKL) = 0; + + virtual HRESULT STDMETHODCALLTYPE IsIME( + /* [in] */ HKL hKL) = 0; + + virtual HRESULT STDMETHODCALLTYPE IsUIMessageA( + /* [in] */ HWND hWndIME, + /* [in] */ UINT msg, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam) = 0; + + virtual HRESULT STDMETHODCALLTYPE IsUIMessageW( + /* [in] */ HWND hWndIME, + /* [in] */ UINT msg, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam) = 0; + + virtual HRESULT STDMETHODCALLTYPE NotifyIME( + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwAction, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwValue) = 0; + + virtual HRESULT STDMETHODCALLTYPE RegisterWordA( + /* [in] */ HKL hKL, + /* [in] */ LPSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPSTR szRegister) = 0; + + virtual HRESULT STDMETHODCALLTYPE RegisterWordW( + /* [in] */ HKL hKL, + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szRegister) = 0; + + virtual HRESULT STDMETHODCALLTYPE ReleaseContext( + /* [in] */ HWND hWnd, + /* [in] */ HIMC hIMC) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetCandidateWindow( + /* [in] */ HIMC hIMC, + /* [in] */ CANDIDATEFORM *pCandidate) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetCompositionFontA( + /* [in] */ HIMC hIMC, + /* [in] */ LOGFONTA *plf) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetCompositionFontW( + /* [in] */ HIMC hIMC, + /* [in] */ LOGFONTW *plf) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetCompositionStringA( + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ LPVOID pComp, + /* [in] */ DWORD dwCompLen, + /* [in] */ LPVOID pRead, + /* [in] */ DWORD dwReadLen) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetCompositionStringW( + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ LPVOID pComp, + /* [in] */ DWORD dwCompLen, + /* [in] */ LPVOID pRead, + /* [in] */ DWORD dwReadLen) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetCompositionWindow( + /* [in] */ HIMC hIMC, + /* [in] */ COMPOSITIONFORM *pCompForm) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetConversionStatus( + /* [in] */ HIMC hIMC, + /* [in] */ DWORD fdwConversion, + /* [in] */ DWORD fdwSentence) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetOpenStatus( + /* [in] */ HIMC hIMC, + /* [in] */ BOOL fOpen) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetStatusWindowPos( + /* [in] */ HIMC hIMC, + /* [in] */ POINT *pptPos) = 0; + + virtual HRESULT STDMETHODCALLTYPE SimulateHotKey( + /* [in] */ HWND hWnd, + /* [in] */ DWORD dwHotKeyID) = 0; + + virtual HRESULT STDMETHODCALLTYPE UnregisterWordA( + /* [in] */ HKL hKL, + /* [in] */ LPSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPSTR szUnregister) = 0; + + virtual HRESULT STDMETHODCALLTYPE UnregisterWordW( + /* [in] */ HKL hKL, + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szUnregister) = 0; + + virtual HRESULT STDMETHODCALLTYPE Activate( + /* [in] */ BOOL fRestoreLayout) = 0; + + virtual HRESULT STDMETHODCALLTYPE Deactivate( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnDefWindowProc( + /* [in] */ HWND hWnd, + /* [in] */ UINT Msg, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ LRESULT *plResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE FilterClientWindows( + /* [in] */ ATOM *aaClassList, + /* [in] */ UINT uSize) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCodePageA( + /* [in] */ HKL hKL, + /* [out] */ UINT *uCodePage) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetLangId( + /* [in] */ HKL hKL, + /* [out] */ LANGID *plid) = 0; + + virtual HRESULT STDMETHODCALLTYPE AssociateContextEx( + /* [in] */ HWND hWnd, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwFlags) = 0; + + virtual HRESULT STDMETHODCALLTYPE DisableIME( + /* [in] */ DWORD idThread) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetImeMenuItemsA( + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwFlags, + /* [in] */ DWORD dwType, + /* [in] */ IMEMENUITEMINFOA *pImeParentMenu, + /* [out] */ IMEMENUITEMINFOA *pImeMenu, + /* [in] */ DWORD dwSize, + /* [out] */ DWORD *pdwResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetImeMenuItemsW( + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwFlags, + /* [in] */ DWORD dwType, + /* [in] */ IMEMENUITEMINFOW *pImeParentMenu, + /* [out] */ IMEMENUITEMINFOW *pImeMenu, + /* [in] */ DWORD dwSize, + /* [out] */ DWORD *pdwResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnumInputContext( + /* [in] */ DWORD idThread, + /* [out] */ IEnumInputContext **ppEnum) = 0; + + }; + +#else /* C style interface */ + + typedef struct IActiveIMMAppVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IActiveIMMApp * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IActiveIMMApp * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IActiveIMMApp * This); + + HRESULT ( STDMETHODCALLTYPE *AssociateContext )( + IActiveIMMApp * This, + /* [in] */ HWND hWnd, + /* [in] */ HIMC hIME, + /* [out] */ HIMC *phPrev); + + HRESULT ( STDMETHODCALLTYPE *ConfigureIMEA )( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ HWND hWnd, + /* [in] */ DWORD dwMode, + /* [in] */ REGISTERWORDA *pData); + + HRESULT ( STDMETHODCALLTYPE *ConfigureIMEW )( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ HWND hWnd, + /* [in] */ DWORD dwMode, + /* [in] */ REGISTERWORDW *pData); + + HRESULT ( STDMETHODCALLTYPE *CreateContext )( + IActiveIMMApp * This, + /* [out] */ HIMC *phIMC); + + HRESULT ( STDMETHODCALLTYPE *DestroyContext )( + IActiveIMMApp * This, + /* [in] */ HIMC hIME); + + HRESULT ( STDMETHODCALLTYPE *EnumRegisterWordA )( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ LPSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPSTR szRegister, + /* [in] */ LPVOID pData, + /* [out] */ IEnumRegisterWordA **pEnum); + + HRESULT ( STDMETHODCALLTYPE *EnumRegisterWordW )( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szRegister, + /* [in] */ LPVOID pData, + /* [out] */ IEnumRegisterWordW **pEnum); + + HRESULT ( STDMETHODCALLTYPE *EscapeA )( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ HIMC hIMC, + /* [in] */ UINT uEscape, + /* [out][in] */ LPVOID pData, + /* [out] */ LRESULT *plResult); + + HRESULT ( STDMETHODCALLTYPE *EscapeW )( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ HIMC hIMC, + /* [in] */ UINT uEscape, + /* [out][in] */ LPVOID pData, + /* [out] */ LRESULT *plResult); + + HRESULT ( STDMETHODCALLTYPE *GetCandidateListA )( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ UINT uBufLen, + /* [out] */ CANDIDATELIST *pCandList, + /* [out] */ UINT *puCopied); + + HRESULT ( STDMETHODCALLTYPE *GetCandidateListW )( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ UINT uBufLen, + /* [out] */ CANDIDATELIST *pCandList, + /* [out] */ UINT *puCopied); + + HRESULT ( STDMETHODCALLTYPE *GetCandidateListCountA )( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [out] */ DWORD *pdwListSize, + /* [out] */ DWORD *pdwBufLen); + + HRESULT ( STDMETHODCALLTYPE *GetCandidateListCountW )( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [out] */ DWORD *pdwListSize, + /* [out] */ DWORD *pdwBufLen); + + HRESULT ( STDMETHODCALLTYPE *GetCandidateWindow )( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [out] */ CANDIDATEFORM *pCandidate); + + HRESULT ( STDMETHODCALLTYPE *GetCompositionFontA )( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [out] */ LOGFONTA *plf); + + HRESULT ( STDMETHODCALLTYPE *GetCompositionFontW )( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [out] */ LOGFONTW *plf); + + HRESULT ( STDMETHODCALLTYPE *GetCompositionStringA )( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwBufLen, + /* [out] */ LONG *plCopied, + /* [out] */ LPVOID pBuf); + + HRESULT ( STDMETHODCALLTYPE *GetCompositionStringW )( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwBufLen, + /* [out] */ LONG *plCopied, + /* [out] */ LPVOID pBuf); + + HRESULT ( STDMETHODCALLTYPE *GetCompositionWindow )( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [out] */ COMPOSITIONFORM *pCompForm); + + HRESULT ( STDMETHODCALLTYPE *GetContext )( + IActiveIMMApp * This, + /* [in] */ HWND hWnd, + /* [out] */ HIMC *phIMC); + + HRESULT ( STDMETHODCALLTYPE *GetConversionListA )( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ HIMC hIMC, + /* [in] */ LPSTR pSrc, + /* [in] */ UINT uBufLen, + /* [in] */ UINT uFlag, + /* [out] */ CANDIDATELIST *pDst, + /* [out] */ UINT *puCopied); + + HRESULT ( STDMETHODCALLTYPE *GetConversionListW )( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ HIMC hIMC, + /* [in] */ LPWSTR pSrc, + /* [in] */ UINT uBufLen, + /* [in] */ UINT uFlag, + /* [out] */ CANDIDATELIST *pDst, + /* [out] */ UINT *puCopied); + + HRESULT ( STDMETHODCALLTYPE *GetConversionStatus )( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [out] */ DWORD *pfdwConversion, + /* [out] */ DWORD *pfdwSentence); + + HRESULT ( STDMETHODCALLTYPE *GetDefaultIMEWnd )( + IActiveIMMApp * This, + /* [in] */ HWND hWnd, + /* [out] */ HWND *phDefWnd); + + HRESULT ( STDMETHODCALLTYPE *GetDescriptionA )( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ UINT uBufLen, + /* [out] */ LPSTR szDescription, + /* [out] */ UINT *puCopied); + + HRESULT ( STDMETHODCALLTYPE *GetDescriptionW )( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ UINT uBufLen, + /* [out] */ LPWSTR szDescription, + /* [out] */ UINT *puCopied); + + HRESULT ( STDMETHODCALLTYPE *GetGuideLineA )( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwBufLen, + /* [out] */ LPSTR pBuf, + /* [out] */ DWORD *pdwResult); + + HRESULT ( STDMETHODCALLTYPE *GetGuideLineW )( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwBufLen, + /* [out] */ LPWSTR pBuf, + /* [out] */ DWORD *pdwResult); + + HRESULT ( STDMETHODCALLTYPE *GetIMEFileNameA )( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ UINT uBufLen, + /* [out] */ LPSTR szFileName, + /* [out] */ UINT *puCopied); + + HRESULT ( STDMETHODCALLTYPE *GetIMEFileNameW )( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ UINT uBufLen, + /* [out] */ LPWSTR szFileName, + /* [out] */ UINT *puCopied); + + HRESULT ( STDMETHODCALLTYPE *GetOpenStatus )( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC); + + HRESULT ( STDMETHODCALLTYPE *GetProperty )( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ DWORD fdwIndex, + /* [out] */ DWORD *pdwProperty); + + HRESULT ( STDMETHODCALLTYPE *GetRegisterWordStyleA )( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ UINT nItem, + /* [out] */ STYLEBUFA *pStyleBuf, + /* [out] */ UINT *puCopied); + + HRESULT ( STDMETHODCALLTYPE *GetRegisterWordStyleW )( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ UINT nItem, + /* [out] */ STYLEBUFW *pStyleBuf, + /* [out] */ UINT *puCopied); + + HRESULT ( STDMETHODCALLTYPE *GetStatusWindowPos )( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [out] */ POINT *pptPos); + + HRESULT ( STDMETHODCALLTYPE *GetVirtualKey )( + IActiveIMMApp * This, + /* [in] */ HWND hWnd, + /* [out] */ UINT *puVirtualKey); + + HRESULT ( STDMETHODCALLTYPE *InstallIMEA )( + IActiveIMMApp * This, + /* [in] */ LPSTR szIMEFileName, + /* [in] */ LPSTR szLayoutText, + /* [out] */ HKL *phKL); + + HRESULT ( STDMETHODCALLTYPE *InstallIMEW )( + IActiveIMMApp * This, + /* [in] */ LPWSTR szIMEFileName, + /* [in] */ LPWSTR szLayoutText, + /* [out] */ HKL *phKL); + + HRESULT ( STDMETHODCALLTYPE *IsIME )( + IActiveIMMApp * This, + /* [in] */ HKL hKL); + + HRESULT ( STDMETHODCALLTYPE *IsUIMessageA )( + IActiveIMMApp * This, + /* [in] */ HWND hWndIME, + /* [in] */ UINT msg, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam); + + HRESULT ( STDMETHODCALLTYPE *IsUIMessageW )( + IActiveIMMApp * This, + /* [in] */ HWND hWndIME, + /* [in] */ UINT msg, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam); + + HRESULT ( STDMETHODCALLTYPE *NotifyIME )( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwAction, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwValue); + + HRESULT ( STDMETHODCALLTYPE *RegisterWordA )( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ LPSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPSTR szRegister); + + HRESULT ( STDMETHODCALLTYPE *RegisterWordW )( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szRegister); + + HRESULT ( STDMETHODCALLTYPE *ReleaseContext )( + IActiveIMMApp * This, + /* [in] */ HWND hWnd, + /* [in] */ HIMC hIMC); + + HRESULT ( STDMETHODCALLTYPE *SetCandidateWindow )( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ CANDIDATEFORM *pCandidate); + + HRESULT ( STDMETHODCALLTYPE *SetCompositionFontA )( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ LOGFONTA *plf); + + HRESULT ( STDMETHODCALLTYPE *SetCompositionFontW )( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ LOGFONTW *plf); + + HRESULT ( STDMETHODCALLTYPE *SetCompositionStringA )( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ LPVOID pComp, + /* [in] */ DWORD dwCompLen, + /* [in] */ LPVOID pRead, + /* [in] */ DWORD dwReadLen); + + HRESULT ( STDMETHODCALLTYPE *SetCompositionStringW )( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ LPVOID pComp, + /* [in] */ DWORD dwCompLen, + /* [in] */ LPVOID pRead, + /* [in] */ DWORD dwReadLen); + + HRESULT ( STDMETHODCALLTYPE *SetCompositionWindow )( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ COMPOSITIONFORM *pCompForm); + + HRESULT ( STDMETHODCALLTYPE *SetConversionStatus )( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD fdwConversion, + /* [in] */ DWORD fdwSentence); + + HRESULT ( STDMETHODCALLTYPE *SetOpenStatus )( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ BOOL fOpen); + + HRESULT ( STDMETHODCALLTYPE *SetStatusWindowPos )( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ POINT *pptPos); + + HRESULT ( STDMETHODCALLTYPE *SimulateHotKey )( + IActiveIMMApp * This, + /* [in] */ HWND hWnd, + /* [in] */ DWORD dwHotKeyID); + + HRESULT ( STDMETHODCALLTYPE *UnregisterWordA )( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ LPSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPSTR szUnregister); + + HRESULT ( STDMETHODCALLTYPE *UnregisterWordW )( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szUnregister); + + HRESULT ( STDMETHODCALLTYPE *Activate )( + IActiveIMMApp * This, + /* [in] */ BOOL fRestoreLayout); + + HRESULT ( STDMETHODCALLTYPE *Deactivate )( + IActiveIMMApp * This); + + HRESULT ( STDMETHODCALLTYPE *OnDefWindowProc )( + IActiveIMMApp * This, + /* [in] */ HWND hWnd, + /* [in] */ UINT Msg, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ LRESULT *plResult); + + HRESULT ( STDMETHODCALLTYPE *FilterClientWindows )( + IActiveIMMApp * This, + /* [in] */ ATOM *aaClassList, + /* [in] */ UINT uSize); + + HRESULT ( STDMETHODCALLTYPE *GetCodePageA )( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [out] */ UINT *uCodePage); + + HRESULT ( STDMETHODCALLTYPE *GetLangId )( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [out] */ LANGID *plid); + + HRESULT ( STDMETHODCALLTYPE *AssociateContextEx )( + IActiveIMMApp * This, + /* [in] */ HWND hWnd, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwFlags); + + HRESULT ( STDMETHODCALLTYPE *DisableIME )( + IActiveIMMApp * This, + /* [in] */ DWORD idThread); + + HRESULT ( STDMETHODCALLTYPE *GetImeMenuItemsA )( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwFlags, + /* [in] */ DWORD dwType, + /* [in] */ IMEMENUITEMINFOA *pImeParentMenu, + /* [out] */ IMEMENUITEMINFOA *pImeMenu, + /* [in] */ DWORD dwSize, + /* [out] */ DWORD *pdwResult); + + HRESULT ( STDMETHODCALLTYPE *GetImeMenuItemsW )( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwFlags, + /* [in] */ DWORD dwType, + /* [in] */ IMEMENUITEMINFOW *pImeParentMenu, + /* [out] */ IMEMENUITEMINFOW *pImeMenu, + /* [in] */ DWORD dwSize, + /* [out] */ DWORD *pdwResult); + + HRESULT ( STDMETHODCALLTYPE *EnumInputContext )( + IActiveIMMApp * This, + /* [in] */ DWORD idThread, + /* [out] */ IEnumInputContext **ppEnum); + + END_INTERFACE + } IActiveIMMAppVtbl; + + interface IActiveIMMApp + { + CONST_VTBL struct IActiveIMMAppVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IActiveIMMApp_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define IActiveIMMApp_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define IActiveIMMApp_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define IActiveIMMApp_AssociateContext(This,hWnd,hIME,phPrev) \ + (This)->lpVtbl -> AssociateContext(This,hWnd,hIME,phPrev) + +#define IActiveIMMApp_ConfigureIMEA(This,hKL,hWnd,dwMode,pData) \ + (This)->lpVtbl -> ConfigureIMEA(This,hKL,hWnd,dwMode,pData) + +#define IActiveIMMApp_ConfigureIMEW(This,hKL,hWnd,dwMode,pData) \ + (This)->lpVtbl -> ConfigureIMEW(This,hKL,hWnd,dwMode,pData) + +#define IActiveIMMApp_CreateContext(This,phIMC) \ + (This)->lpVtbl -> CreateContext(This,phIMC) + +#define IActiveIMMApp_DestroyContext(This,hIME) \ + (This)->lpVtbl -> DestroyContext(This,hIME) + +#define IActiveIMMApp_EnumRegisterWordA(This,hKL,szReading,dwStyle,szRegister,pData,pEnum) \ + (This)->lpVtbl -> EnumRegisterWordA(This,hKL,szReading,dwStyle,szRegister,pData,pEnum) + +#define IActiveIMMApp_EnumRegisterWordW(This,hKL,szReading,dwStyle,szRegister,pData,pEnum) \ + (This)->lpVtbl -> EnumRegisterWordW(This,hKL,szReading,dwStyle,szRegister,pData,pEnum) + +#define IActiveIMMApp_EscapeA(This,hKL,hIMC,uEscape,pData,plResult) \ + (This)->lpVtbl -> EscapeA(This,hKL,hIMC,uEscape,pData,plResult) + +#define IActiveIMMApp_EscapeW(This,hKL,hIMC,uEscape,pData,plResult) \ + (This)->lpVtbl -> EscapeW(This,hKL,hIMC,uEscape,pData,plResult) + +#define IActiveIMMApp_GetCandidateListA(This,hIMC,dwIndex,uBufLen,pCandList,puCopied) \ + (This)->lpVtbl -> GetCandidateListA(This,hIMC,dwIndex,uBufLen,pCandList,puCopied) + +#define IActiveIMMApp_GetCandidateListW(This,hIMC,dwIndex,uBufLen,pCandList,puCopied) \ + (This)->lpVtbl -> GetCandidateListW(This,hIMC,dwIndex,uBufLen,pCandList,puCopied) + +#define IActiveIMMApp_GetCandidateListCountA(This,hIMC,pdwListSize,pdwBufLen) \ + (This)->lpVtbl -> GetCandidateListCountA(This,hIMC,pdwListSize,pdwBufLen) + +#define IActiveIMMApp_GetCandidateListCountW(This,hIMC,pdwListSize,pdwBufLen) \ + (This)->lpVtbl -> GetCandidateListCountW(This,hIMC,pdwListSize,pdwBufLen) + +#define IActiveIMMApp_GetCandidateWindow(This,hIMC,dwIndex,pCandidate) \ + (This)->lpVtbl -> GetCandidateWindow(This,hIMC,dwIndex,pCandidate) + +#define IActiveIMMApp_GetCompositionFontA(This,hIMC,plf) \ + (This)->lpVtbl -> GetCompositionFontA(This,hIMC,plf) + +#define IActiveIMMApp_GetCompositionFontW(This,hIMC,plf) \ + (This)->lpVtbl -> GetCompositionFontW(This,hIMC,plf) + +#define IActiveIMMApp_GetCompositionStringA(This,hIMC,dwIndex,dwBufLen,plCopied,pBuf) \ + (This)->lpVtbl -> GetCompositionStringA(This,hIMC,dwIndex,dwBufLen,plCopied,pBuf) + +#define IActiveIMMApp_GetCompositionStringW(This,hIMC,dwIndex,dwBufLen,plCopied,pBuf) \ + (This)->lpVtbl -> GetCompositionStringW(This,hIMC,dwIndex,dwBufLen,plCopied,pBuf) + +#define IActiveIMMApp_GetCompositionWindow(This,hIMC,pCompForm) \ + (This)->lpVtbl -> GetCompositionWindow(This,hIMC,pCompForm) + +#define IActiveIMMApp_GetContext(This,hWnd,phIMC) \ + (This)->lpVtbl -> GetContext(This,hWnd,phIMC) + +#define IActiveIMMApp_GetConversionListA(This,hKL,hIMC,pSrc,uBufLen,uFlag,pDst,puCopied) \ + (This)->lpVtbl -> GetConversionListA(This,hKL,hIMC,pSrc,uBufLen,uFlag,pDst,puCopied) + +#define IActiveIMMApp_GetConversionListW(This,hKL,hIMC,pSrc,uBufLen,uFlag,pDst,puCopied) \ + (This)->lpVtbl -> GetConversionListW(This,hKL,hIMC,pSrc,uBufLen,uFlag,pDst,puCopied) + +#define IActiveIMMApp_GetConversionStatus(This,hIMC,pfdwConversion,pfdwSentence) \ + (This)->lpVtbl -> GetConversionStatus(This,hIMC,pfdwConversion,pfdwSentence) + +#define IActiveIMMApp_GetDefaultIMEWnd(This,hWnd,phDefWnd) \ + (This)->lpVtbl -> GetDefaultIMEWnd(This,hWnd,phDefWnd) + +#define IActiveIMMApp_GetDescriptionA(This,hKL,uBufLen,szDescription,puCopied) \ + (This)->lpVtbl -> GetDescriptionA(This,hKL,uBufLen,szDescription,puCopied) + +#define IActiveIMMApp_GetDescriptionW(This,hKL,uBufLen,szDescription,puCopied) \ + (This)->lpVtbl -> GetDescriptionW(This,hKL,uBufLen,szDescription,puCopied) + +#define IActiveIMMApp_GetGuideLineA(This,hIMC,dwIndex,dwBufLen,pBuf,pdwResult) \ + (This)->lpVtbl -> GetGuideLineA(This,hIMC,dwIndex,dwBufLen,pBuf,pdwResult) + +#define IActiveIMMApp_GetGuideLineW(This,hIMC,dwIndex,dwBufLen,pBuf,pdwResult) \ + (This)->lpVtbl -> GetGuideLineW(This,hIMC,dwIndex,dwBufLen,pBuf,pdwResult) + +#define IActiveIMMApp_GetIMEFileNameA(This,hKL,uBufLen,szFileName,puCopied) \ + (This)->lpVtbl -> GetIMEFileNameA(This,hKL,uBufLen,szFileName,puCopied) + +#define IActiveIMMApp_GetIMEFileNameW(This,hKL,uBufLen,szFileName,puCopied) \ + (This)->lpVtbl -> GetIMEFileNameW(This,hKL,uBufLen,szFileName,puCopied) + +#define IActiveIMMApp_GetOpenStatus(This,hIMC) \ + (This)->lpVtbl -> GetOpenStatus(This,hIMC) + +#define IActiveIMMApp_GetProperty(This,hKL,fdwIndex,pdwProperty) \ + (This)->lpVtbl -> GetProperty(This,hKL,fdwIndex,pdwProperty) + +#define IActiveIMMApp_GetRegisterWordStyleA(This,hKL,nItem,pStyleBuf,puCopied) \ + (This)->lpVtbl -> GetRegisterWordStyleA(This,hKL,nItem,pStyleBuf,puCopied) + +#define IActiveIMMApp_GetRegisterWordStyleW(This,hKL,nItem,pStyleBuf,puCopied) \ + (This)->lpVtbl -> GetRegisterWordStyleW(This,hKL,nItem,pStyleBuf,puCopied) + +#define IActiveIMMApp_GetStatusWindowPos(This,hIMC,pptPos) \ + (This)->lpVtbl -> GetStatusWindowPos(This,hIMC,pptPos) + +#define IActiveIMMApp_GetVirtualKey(This,hWnd,puVirtualKey) \ + (This)->lpVtbl -> GetVirtualKey(This,hWnd,puVirtualKey) + +#define IActiveIMMApp_InstallIMEA(This,szIMEFileName,szLayoutText,phKL) \ + (This)->lpVtbl -> InstallIMEA(This,szIMEFileName,szLayoutText,phKL) + +#define IActiveIMMApp_InstallIMEW(This,szIMEFileName,szLayoutText,phKL) \ + (This)->lpVtbl -> InstallIMEW(This,szIMEFileName,szLayoutText,phKL) + +#define IActiveIMMApp_IsIME(This,hKL) \ + (This)->lpVtbl -> IsIME(This,hKL) + +#define IActiveIMMApp_IsUIMessageA(This,hWndIME,msg,wParam,lParam) \ + (This)->lpVtbl -> IsUIMessageA(This,hWndIME,msg,wParam,lParam) + +#define IActiveIMMApp_IsUIMessageW(This,hWndIME,msg,wParam,lParam) \ + (This)->lpVtbl -> IsUIMessageW(This,hWndIME,msg,wParam,lParam) + +#define IActiveIMMApp_NotifyIME(This,hIMC,dwAction,dwIndex,dwValue) \ + (This)->lpVtbl -> NotifyIME(This,hIMC,dwAction,dwIndex,dwValue) + +#define IActiveIMMApp_RegisterWordA(This,hKL,szReading,dwStyle,szRegister) \ + (This)->lpVtbl -> RegisterWordA(This,hKL,szReading,dwStyle,szRegister) + +#define IActiveIMMApp_RegisterWordW(This,hKL,szReading,dwStyle,szRegister) \ + (This)->lpVtbl -> RegisterWordW(This,hKL,szReading,dwStyle,szRegister) + +#define IActiveIMMApp_ReleaseContext(This,hWnd,hIMC) \ + (This)->lpVtbl -> ReleaseContext(This,hWnd,hIMC) + +#define IActiveIMMApp_SetCandidateWindow(This,hIMC,pCandidate) \ + (This)->lpVtbl -> SetCandidateWindow(This,hIMC,pCandidate) + +#define IActiveIMMApp_SetCompositionFontA(This,hIMC,plf) \ + (This)->lpVtbl -> SetCompositionFontA(This,hIMC,plf) + +#define IActiveIMMApp_SetCompositionFontW(This,hIMC,plf) \ + (This)->lpVtbl -> SetCompositionFontW(This,hIMC,plf) + +#define IActiveIMMApp_SetCompositionStringA(This,hIMC,dwIndex,pComp,dwCompLen,pRead,dwReadLen) \ + (This)->lpVtbl -> SetCompositionStringA(This,hIMC,dwIndex,pComp,dwCompLen,pRead,dwReadLen) + +#define IActiveIMMApp_SetCompositionStringW(This,hIMC,dwIndex,pComp,dwCompLen,pRead,dwReadLen) \ + (This)->lpVtbl -> SetCompositionStringW(This,hIMC,dwIndex,pComp,dwCompLen,pRead,dwReadLen) + +#define IActiveIMMApp_SetCompositionWindow(This,hIMC,pCompForm) \ + (This)->lpVtbl -> SetCompositionWindow(This,hIMC,pCompForm) + +#define IActiveIMMApp_SetConversionStatus(This,hIMC,fdwConversion,fdwSentence) \ + (This)->lpVtbl -> SetConversionStatus(This,hIMC,fdwConversion,fdwSentence) + +#define IActiveIMMApp_SetOpenStatus(This,hIMC,fOpen) \ + (This)->lpVtbl -> SetOpenStatus(This,hIMC,fOpen) + +#define IActiveIMMApp_SetStatusWindowPos(This,hIMC,pptPos) \ + (This)->lpVtbl -> SetStatusWindowPos(This,hIMC,pptPos) + +#define IActiveIMMApp_SimulateHotKey(This,hWnd,dwHotKeyID) \ + (This)->lpVtbl -> SimulateHotKey(This,hWnd,dwHotKeyID) + +#define IActiveIMMApp_UnregisterWordA(This,hKL,szReading,dwStyle,szUnregister) \ + (This)->lpVtbl -> UnregisterWordA(This,hKL,szReading,dwStyle,szUnregister) + +#define IActiveIMMApp_UnregisterWordW(This,hKL,szReading,dwStyle,szUnregister) \ + (This)->lpVtbl -> UnregisterWordW(This,hKL,szReading,dwStyle,szUnregister) + +#define IActiveIMMApp_Activate(This,fRestoreLayout) \ + (This)->lpVtbl -> Activate(This,fRestoreLayout) + +#define IActiveIMMApp_Deactivate(This) \ + (This)->lpVtbl -> Deactivate(This) + +#define IActiveIMMApp_OnDefWindowProc(This,hWnd,Msg,wParam,lParam,plResult) \ + (This)->lpVtbl -> OnDefWindowProc(This,hWnd,Msg,wParam,lParam,plResult) + +#define IActiveIMMApp_FilterClientWindows(This,aaClassList,uSize) \ + (This)->lpVtbl -> FilterClientWindows(This,aaClassList,uSize) + +#define IActiveIMMApp_GetCodePageA(This,hKL,uCodePage) \ + (This)->lpVtbl -> GetCodePageA(This,hKL,uCodePage) + +#define IActiveIMMApp_GetLangId(This,hKL,plid) \ + (This)->lpVtbl -> GetLangId(This,hKL,plid) + +#define IActiveIMMApp_AssociateContextEx(This,hWnd,hIMC,dwFlags) \ + (This)->lpVtbl -> AssociateContextEx(This,hWnd,hIMC,dwFlags) + +#define IActiveIMMApp_DisableIME(This,idThread) \ + (This)->lpVtbl -> DisableIME(This,idThread) + +#define IActiveIMMApp_GetImeMenuItemsA(This,hIMC,dwFlags,dwType,pImeParentMenu,pImeMenu,dwSize,pdwResult) \ + (This)->lpVtbl -> GetImeMenuItemsA(This,hIMC,dwFlags,dwType,pImeParentMenu,pImeMenu,dwSize,pdwResult) + +#define IActiveIMMApp_GetImeMenuItemsW(This,hIMC,dwFlags,dwType,pImeParentMenu,pImeMenu,dwSize,pdwResult) \ + (This)->lpVtbl -> GetImeMenuItemsW(This,hIMC,dwFlags,dwType,pImeParentMenu,pImeMenu,dwSize,pdwResult) + +#define IActiveIMMApp_EnumInputContext(This,idThread,ppEnum) \ + (This)->lpVtbl -> EnumInputContext(This,idThread,ppEnum) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_AssociateContext_Proxy( + IActiveIMMApp * This, + /* [in] */ HWND hWnd, + /* [in] */ HIMC hIME, + /* [out] */ HIMC *phPrev); + + +void __RPC_STUB IActiveIMMApp_AssociateContext_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_ConfigureIMEA_Proxy( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ HWND hWnd, + /* [in] */ DWORD dwMode, + /* [in] */ REGISTERWORDA *pData); + + +void __RPC_STUB IActiveIMMApp_ConfigureIMEA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_ConfigureIMEW_Proxy( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ HWND hWnd, + /* [in] */ DWORD dwMode, + /* [in] */ REGISTERWORDW *pData); + + +void __RPC_STUB IActiveIMMApp_ConfigureIMEW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_CreateContext_Proxy( + IActiveIMMApp * This, + /* [out] */ HIMC *phIMC); + + +void __RPC_STUB IActiveIMMApp_CreateContext_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_DestroyContext_Proxy( + IActiveIMMApp * This, + /* [in] */ HIMC hIME); + + +void __RPC_STUB IActiveIMMApp_DestroyContext_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_EnumRegisterWordA_Proxy( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ LPSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPSTR szRegister, + /* [in] */ LPVOID pData, + /* [out] */ IEnumRegisterWordA **pEnum); + + +void __RPC_STUB IActiveIMMApp_EnumRegisterWordA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_EnumRegisterWordW_Proxy( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szRegister, + /* [in] */ LPVOID pData, + /* [out] */ IEnumRegisterWordW **pEnum); + + +void __RPC_STUB IActiveIMMApp_EnumRegisterWordW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_EscapeA_Proxy( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ HIMC hIMC, + /* [in] */ UINT uEscape, + /* [out][in] */ LPVOID pData, + /* [out] */ LRESULT *plResult); + + +void __RPC_STUB IActiveIMMApp_EscapeA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_EscapeW_Proxy( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ HIMC hIMC, + /* [in] */ UINT uEscape, + /* [out][in] */ LPVOID pData, + /* [out] */ LRESULT *plResult); + + +void __RPC_STUB IActiveIMMApp_EscapeW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetCandidateListA_Proxy( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ UINT uBufLen, + /* [out] */ CANDIDATELIST *pCandList, + /* [out] */ UINT *puCopied); + + +void __RPC_STUB IActiveIMMApp_GetCandidateListA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetCandidateListW_Proxy( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ UINT uBufLen, + /* [out] */ CANDIDATELIST *pCandList, + /* [out] */ UINT *puCopied); + + +void __RPC_STUB IActiveIMMApp_GetCandidateListW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetCandidateListCountA_Proxy( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [out] */ DWORD *pdwListSize, + /* [out] */ DWORD *pdwBufLen); + + +void __RPC_STUB IActiveIMMApp_GetCandidateListCountA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetCandidateListCountW_Proxy( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [out] */ DWORD *pdwListSize, + /* [out] */ DWORD *pdwBufLen); + + +void __RPC_STUB IActiveIMMApp_GetCandidateListCountW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetCandidateWindow_Proxy( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [out] */ CANDIDATEFORM *pCandidate); + + +void __RPC_STUB IActiveIMMApp_GetCandidateWindow_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetCompositionFontA_Proxy( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [out] */ LOGFONTA *plf); + + +void __RPC_STUB IActiveIMMApp_GetCompositionFontA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetCompositionFontW_Proxy( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [out] */ LOGFONTW *plf); + + +void __RPC_STUB IActiveIMMApp_GetCompositionFontW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetCompositionStringA_Proxy( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwBufLen, + /* [out] */ LONG *plCopied, + /* [out] */ LPVOID pBuf); + + +void __RPC_STUB IActiveIMMApp_GetCompositionStringA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetCompositionStringW_Proxy( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwBufLen, + /* [out] */ LONG *plCopied, + /* [out] */ LPVOID pBuf); + + +void __RPC_STUB IActiveIMMApp_GetCompositionStringW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetCompositionWindow_Proxy( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [out] */ COMPOSITIONFORM *pCompForm); + + +void __RPC_STUB IActiveIMMApp_GetCompositionWindow_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetContext_Proxy( + IActiveIMMApp * This, + /* [in] */ HWND hWnd, + /* [out] */ HIMC *phIMC); + + +void __RPC_STUB IActiveIMMApp_GetContext_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetConversionListA_Proxy( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ HIMC hIMC, + /* [in] */ LPSTR pSrc, + /* [in] */ UINT uBufLen, + /* [in] */ UINT uFlag, + /* [out] */ CANDIDATELIST *pDst, + /* [out] */ UINT *puCopied); + + +void __RPC_STUB IActiveIMMApp_GetConversionListA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetConversionListW_Proxy( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ HIMC hIMC, + /* [in] */ LPWSTR pSrc, + /* [in] */ UINT uBufLen, + /* [in] */ UINT uFlag, + /* [out] */ CANDIDATELIST *pDst, + /* [out] */ UINT *puCopied); + + +void __RPC_STUB IActiveIMMApp_GetConversionListW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetConversionStatus_Proxy( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [out] */ DWORD *pfdwConversion, + /* [out] */ DWORD *pfdwSentence); + + +void __RPC_STUB IActiveIMMApp_GetConversionStatus_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetDefaultIMEWnd_Proxy( + IActiveIMMApp * This, + /* [in] */ HWND hWnd, + /* [out] */ HWND *phDefWnd); + + +void __RPC_STUB IActiveIMMApp_GetDefaultIMEWnd_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetDescriptionA_Proxy( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ UINT uBufLen, + /* [out] */ LPSTR szDescription, + /* [out] */ UINT *puCopied); + + +void __RPC_STUB IActiveIMMApp_GetDescriptionA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetDescriptionW_Proxy( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ UINT uBufLen, + /* [out] */ LPWSTR szDescription, + /* [out] */ UINT *puCopied); + + +void __RPC_STUB IActiveIMMApp_GetDescriptionW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetGuideLineA_Proxy( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwBufLen, + /* [out] */ LPSTR pBuf, + /* [out] */ DWORD *pdwResult); + + +void __RPC_STUB IActiveIMMApp_GetGuideLineA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetGuideLineW_Proxy( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwBufLen, + /* [out] */ LPWSTR pBuf, + /* [out] */ DWORD *pdwResult); + + +void __RPC_STUB IActiveIMMApp_GetGuideLineW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetIMEFileNameA_Proxy( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ UINT uBufLen, + /* [out] */ LPSTR szFileName, + /* [out] */ UINT *puCopied); + + +void __RPC_STUB IActiveIMMApp_GetIMEFileNameA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetIMEFileNameW_Proxy( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ UINT uBufLen, + /* [out] */ LPWSTR szFileName, + /* [out] */ UINT *puCopied); + + +void __RPC_STUB IActiveIMMApp_GetIMEFileNameW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetOpenStatus_Proxy( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC); + + +void __RPC_STUB IActiveIMMApp_GetOpenStatus_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetProperty_Proxy( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ DWORD fdwIndex, + /* [out] */ DWORD *pdwProperty); + + +void __RPC_STUB IActiveIMMApp_GetProperty_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetRegisterWordStyleA_Proxy( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ UINT nItem, + /* [out] */ STYLEBUFA *pStyleBuf, + /* [out] */ UINT *puCopied); + + +void __RPC_STUB IActiveIMMApp_GetRegisterWordStyleA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetRegisterWordStyleW_Proxy( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ UINT nItem, + /* [out] */ STYLEBUFW *pStyleBuf, + /* [out] */ UINT *puCopied); + + +void __RPC_STUB IActiveIMMApp_GetRegisterWordStyleW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetStatusWindowPos_Proxy( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [out] */ POINT *pptPos); + + +void __RPC_STUB IActiveIMMApp_GetStatusWindowPos_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetVirtualKey_Proxy( + IActiveIMMApp * This, + /* [in] */ HWND hWnd, + /* [out] */ UINT *puVirtualKey); + + +void __RPC_STUB IActiveIMMApp_GetVirtualKey_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_InstallIMEA_Proxy( + IActiveIMMApp * This, + /* [in] */ LPSTR szIMEFileName, + /* [in] */ LPSTR szLayoutText, + /* [out] */ HKL *phKL); + + +void __RPC_STUB IActiveIMMApp_InstallIMEA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_InstallIMEW_Proxy( + IActiveIMMApp * This, + /* [in] */ LPWSTR szIMEFileName, + /* [in] */ LPWSTR szLayoutText, + /* [out] */ HKL *phKL); + + +void __RPC_STUB IActiveIMMApp_InstallIMEW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_IsIME_Proxy( + IActiveIMMApp * This, + /* [in] */ HKL hKL); + + +void __RPC_STUB IActiveIMMApp_IsIME_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_IsUIMessageA_Proxy( + IActiveIMMApp * This, + /* [in] */ HWND hWndIME, + /* [in] */ UINT msg, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam); + + +void __RPC_STUB IActiveIMMApp_IsUIMessageA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_IsUIMessageW_Proxy( + IActiveIMMApp * This, + /* [in] */ HWND hWndIME, + /* [in] */ UINT msg, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam); + + +void __RPC_STUB IActiveIMMApp_IsUIMessageW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_NotifyIME_Proxy( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwAction, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwValue); + + +void __RPC_STUB IActiveIMMApp_NotifyIME_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_RegisterWordA_Proxy( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ LPSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPSTR szRegister); + + +void __RPC_STUB IActiveIMMApp_RegisterWordA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_RegisterWordW_Proxy( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szRegister); + + +void __RPC_STUB IActiveIMMApp_RegisterWordW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_ReleaseContext_Proxy( + IActiveIMMApp * This, + /* [in] */ HWND hWnd, + /* [in] */ HIMC hIMC); + + +void __RPC_STUB IActiveIMMApp_ReleaseContext_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_SetCandidateWindow_Proxy( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ CANDIDATEFORM *pCandidate); + + +void __RPC_STUB IActiveIMMApp_SetCandidateWindow_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_SetCompositionFontA_Proxy( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ LOGFONTA *plf); + + +void __RPC_STUB IActiveIMMApp_SetCompositionFontA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_SetCompositionFontW_Proxy( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ LOGFONTW *plf); + + +void __RPC_STUB IActiveIMMApp_SetCompositionFontW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_SetCompositionStringA_Proxy( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ LPVOID pComp, + /* [in] */ DWORD dwCompLen, + /* [in] */ LPVOID pRead, + /* [in] */ DWORD dwReadLen); + + +void __RPC_STUB IActiveIMMApp_SetCompositionStringA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_SetCompositionStringW_Proxy( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ LPVOID pComp, + /* [in] */ DWORD dwCompLen, + /* [in] */ LPVOID pRead, + /* [in] */ DWORD dwReadLen); + + +void __RPC_STUB IActiveIMMApp_SetCompositionStringW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_SetCompositionWindow_Proxy( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ COMPOSITIONFORM *pCompForm); + + +void __RPC_STUB IActiveIMMApp_SetCompositionWindow_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_SetConversionStatus_Proxy( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD fdwConversion, + /* [in] */ DWORD fdwSentence); + + +void __RPC_STUB IActiveIMMApp_SetConversionStatus_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_SetOpenStatus_Proxy( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ BOOL fOpen); + + +void __RPC_STUB IActiveIMMApp_SetOpenStatus_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_SetStatusWindowPos_Proxy( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ POINT *pptPos); + + +void __RPC_STUB IActiveIMMApp_SetStatusWindowPos_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_SimulateHotKey_Proxy( + IActiveIMMApp * This, + /* [in] */ HWND hWnd, + /* [in] */ DWORD dwHotKeyID); + + +void __RPC_STUB IActiveIMMApp_SimulateHotKey_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_UnregisterWordA_Proxy( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ LPSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPSTR szUnregister); + + +void __RPC_STUB IActiveIMMApp_UnregisterWordA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_UnregisterWordW_Proxy( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szUnregister); + + +void __RPC_STUB IActiveIMMApp_UnregisterWordW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_Activate_Proxy( + IActiveIMMApp * This, + /* [in] */ BOOL fRestoreLayout); + + +void __RPC_STUB IActiveIMMApp_Activate_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_Deactivate_Proxy( + IActiveIMMApp * This); + + +void __RPC_STUB IActiveIMMApp_Deactivate_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_OnDefWindowProc_Proxy( + IActiveIMMApp * This, + /* [in] */ HWND hWnd, + /* [in] */ UINT Msg, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ LRESULT *plResult); + + +void __RPC_STUB IActiveIMMApp_OnDefWindowProc_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_FilterClientWindows_Proxy( + IActiveIMMApp * This, + /* [in] */ ATOM *aaClassList, + /* [in] */ UINT uSize); + + +void __RPC_STUB IActiveIMMApp_FilterClientWindows_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetCodePageA_Proxy( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [out] */ UINT *uCodePage); + + +void __RPC_STUB IActiveIMMApp_GetCodePageA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetLangId_Proxy( + IActiveIMMApp * This, + /* [in] */ HKL hKL, + /* [out] */ LANGID *plid); + + +void __RPC_STUB IActiveIMMApp_GetLangId_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_AssociateContextEx_Proxy( + IActiveIMMApp * This, + /* [in] */ HWND hWnd, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwFlags); + + +void __RPC_STUB IActiveIMMApp_AssociateContextEx_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_DisableIME_Proxy( + IActiveIMMApp * This, + /* [in] */ DWORD idThread); + + +void __RPC_STUB IActiveIMMApp_DisableIME_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetImeMenuItemsA_Proxy( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwFlags, + /* [in] */ DWORD dwType, + /* [in] */ IMEMENUITEMINFOA *pImeParentMenu, + /* [out] */ IMEMENUITEMINFOA *pImeMenu, + /* [in] */ DWORD dwSize, + /* [out] */ DWORD *pdwResult); + + +void __RPC_STUB IActiveIMMApp_GetImeMenuItemsA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_GetImeMenuItemsW_Proxy( + IActiveIMMApp * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwFlags, + /* [in] */ DWORD dwType, + /* [in] */ IMEMENUITEMINFOW *pImeParentMenu, + /* [out] */ IMEMENUITEMINFOW *pImeMenu, + /* [in] */ DWORD dwSize, + /* [out] */ DWORD *pdwResult); + + +void __RPC_STUB IActiveIMMApp_GetImeMenuItemsW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMApp_EnumInputContext_Proxy( + IActiveIMMApp * This, + /* [in] */ DWORD idThread, + /* [out] */ IEnumInputContext **ppEnum); + + +void __RPC_STUB IActiveIMMApp_EnumInputContext_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IActiveIMMApp_INTERFACE_DEFINED__ */ + + +#ifndef __IActiveIMMIME_INTERFACE_DEFINED__ +#define __IActiveIMMIME_INTERFACE_DEFINED__ + +/* interface IActiveIMMIME */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_IActiveIMMIME; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("08C03411-F96B-11d0-A475-00AA006BCC59") + IActiveIMMIME : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE AssociateContext( + /* [in] */ HWND hWnd, + /* [in] */ HIMC hIME, + /* [out] */ HIMC *phPrev) = 0; + + virtual HRESULT STDMETHODCALLTYPE ConfigureIMEA( + /* [in] */ HKL hKL, + /* [in] */ HWND hWnd, + /* [in] */ DWORD dwMode, + /* [in] */ REGISTERWORDA *pData) = 0; + + virtual HRESULT STDMETHODCALLTYPE ConfigureIMEW( + /* [in] */ HKL hKL, + /* [in] */ HWND hWnd, + /* [in] */ DWORD dwMode, + /* [in] */ REGISTERWORDW *pData) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateContext( + /* [out] */ HIMC *phIMC) = 0; + + virtual HRESULT STDMETHODCALLTYPE DestroyContext( + /* [in] */ HIMC hIME) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnumRegisterWordA( + /* [in] */ HKL hKL, + /* [in] */ LPSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPSTR szRegister, + /* [in] */ LPVOID pData, + /* [out] */ IEnumRegisterWordA **pEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnumRegisterWordW( + /* [in] */ HKL hKL, + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szRegister, + /* [in] */ LPVOID pData, + /* [out] */ IEnumRegisterWordW **pEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE EscapeA( + /* [in] */ HKL hKL, + /* [in] */ HIMC hIMC, + /* [in] */ UINT uEscape, + /* [out][in] */ LPVOID pData, + /* [out] */ LRESULT *plResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE EscapeW( + /* [in] */ HKL hKL, + /* [in] */ HIMC hIMC, + /* [in] */ UINT uEscape, + /* [out][in] */ LPVOID pData, + /* [out] */ LRESULT *plResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCandidateListA( + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ UINT uBufLen, + /* [out] */ CANDIDATELIST *pCandList, + /* [out] */ UINT *puCopied) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCandidateListW( + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ UINT uBufLen, + /* [out] */ CANDIDATELIST *pCandList, + /* [out] */ UINT *puCopied) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCandidateListCountA( + /* [in] */ HIMC hIMC, + /* [out] */ DWORD *pdwListSize, + /* [out] */ DWORD *pdwBufLen) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCandidateListCountW( + /* [in] */ HIMC hIMC, + /* [out] */ DWORD *pdwListSize, + /* [out] */ DWORD *pdwBufLen) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCandidateWindow( + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [out] */ CANDIDATEFORM *pCandidate) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCompositionFontA( + /* [in] */ HIMC hIMC, + /* [out] */ LOGFONTA *plf) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCompositionFontW( + /* [in] */ HIMC hIMC, + /* [out] */ LOGFONTW *plf) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCompositionStringA( + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwBufLen, + /* [out] */ LONG *plCopied, + /* [out] */ LPVOID pBuf) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCompositionStringW( + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwBufLen, + /* [out] */ LONG *plCopied, + /* [out] */ LPVOID pBuf) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCompositionWindow( + /* [in] */ HIMC hIMC, + /* [out] */ COMPOSITIONFORM *pCompForm) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetContext( + /* [in] */ HWND hWnd, + /* [out] */ HIMC *phIMC) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetConversionListA( + /* [in] */ HKL hKL, + /* [in] */ HIMC hIMC, + /* [in] */ LPSTR pSrc, + /* [in] */ UINT uBufLen, + /* [in] */ UINT uFlag, + /* [out] */ CANDIDATELIST *pDst, + /* [out] */ UINT *puCopied) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetConversionListW( + /* [in] */ HKL hKL, + /* [in] */ HIMC hIMC, + /* [in] */ LPWSTR pSrc, + /* [in] */ UINT uBufLen, + /* [in] */ UINT uFlag, + /* [out] */ CANDIDATELIST *pDst, + /* [out] */ UINT *puCopied) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetConversionStatus( + /* [in] */ HIMC hIMC, + /* [out] */ DWORD *pfdwConversion, + /* [out] */ DWORD *pfdwSentence) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDefaultIMEWnd( + /* [in] */ HWND hWnd, + /* [out] */ HWND *phDefWnd) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDescriptionA( + /* [in] */ HKL hKL, + /* [in] */ UINT uBufLen, + /* [out] */ LPSTR szDescription, + /* [out] */ UINT *puCopied) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDescriptionW( + /* [in] */ HKL hKL, + /* [in] */ UINT uBufLen, + /* [out] */ LPWSTR szDescription, + /* [out] */ UINT *puCopied) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetGuideLineA( + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwBufLen, + /* [out] */ LPSTR pBuf, + /* [out] */ DWORD *pdwResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetGuideLineW( + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwBufLen, + /* [out] */ LPWSTR pBuf, + /* [out] */ DWORD *pdwResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetIMEFileNameA( + /* [in] */ HKL hKL, + /* [in] */ UINT uBufLen, + /* [out] */ LPSTR szFileName, + /* [out] */ UINT *puCopied) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetIMEFileNameW( + /* [in] */ HKL hKL, + /* [in] */ UINT uBufLen, + /* [out] */ LPWSTR szFileName, + /* [out] */ UINT *puCopied) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetOpenStatus( + /* [in] */ HIMC hIMC) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetProperty( + /* [in] */ HKL hKL, + /* [in] */ DWORD fdwIndex, + /* [out] */ DWORD *pdwProperty) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetRegisterWordStyleA( + /* [in] */ HKL hKL, + /* [in] */ UINT nItem, + /* [out] */ STYLEBUFA *pStyleBuf, + /* [out] */ UINT *puCopied) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetRegisterWordStyleW( + /* [in] */ HKL hKL, + /* [in] */ UINT nItem, + /* [out] */ STYLEBUFW *pStyleBuf, + /* [out] */ UINT *puCopied) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetStatusWindowPos( + /* [in] */ HIMC hIMC, + /* [out] */ POINT *pptPos) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetVirtualKey( + /* [in] */ HWND hWnd, + /* [out] */ UINT *puVirtualKey) = 0; + + virtual HRESULT STDMETHODCALLTYPE InstallIMEA( + /* [in] */ LPSTR szIMEFileName, + /* [in] */ LPSTR szLayoutText, + /* [out] */ HKL *phKL) = 0; + + virtual HRESULT STDMETHODCALLTYPE InstallIMEW( + /* [in] */ LPWSTR szIMEFileName, + /* [in] */ LPWSTR szLayoutText, + /* [out] */ HKL *phKL) = 0; + + virtual HRESULT STDMETHODCALLTYPE IsIME( + /* [in] */ HKL hKL) = 0; + + virtual HRESULT STDMETHODCALLTYPE IsUIMessageA( + /* [in] */ HWND hWndIME, + /* [in] */ UINT msg, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam) = 0; + + virtual HRESULT STDMETHODCALLTYPE IsUIMessageW( + /* [in] */ HWND hWndIME, + /* [in] */ UINT msg, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam) = 0; + + virtual HRESULT STDMETHODCALLTYPE NotifyIME( + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwAction, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwValue) = 0; + + virtual HRESULT STDMETHODCALLTYPE RegisterWordA( + /* [in] */ HKL hKL, + /* [in] */ LPSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPSTR szRegister) = 0; + + virtual HRESULT STDMETHODCALLTYPE RegisterWordW( + /* [in] */ HKL hKL, + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szRegister) = 0; + + virtual HRESULT STDMETHODCALLTYPE ReleaseContext( + /* [in] */ HWND hWnd, + /* [in] */ HIMC hIMC) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetCandidateWindow( + /* [in] */ HIMC hIMC, + /* [in] */ CANDIDATEFORM *pCandidate) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetCompositionFontA( + /* [in] */ HIMC hIMC, + /* [in] */ LOGFONTA *plf) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetCompositionFontW( + /* [in] */ HIMC hIMC, + /* [in] */ LOGFONTW *plf) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetCompositionStringA( + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ LPVOID pComp, + /* [in] */ DWORD dwCompLen, + /* [in] */ LPVOID pRead, + /* [in] */ DWORD dwReadLen) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetCompositionStringW( + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ LPVOID pComp, + /* [in] */ DWORD dwCompLen, + /* [in] */ LPVOID pRead, + /* [in] */ DWORD dwReadLen) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetCompositionWindow( + /* [in] */ HIMC hIMC, + /* [in] */ COMPOSITIONFORM *pCompForm) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetConversionStatus( + /* [in] */ HIMC hIMC, + /* [in] */ DWORD fdwConversion, + /* [in] */ DWORD fdwSentence) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetOpenStatus( + /* [in] */ HIMC hIMC, + /* [in] */ BOOL fOpen) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetStatusWindowPos( + /* [in] */ HIMC hIMC, + /* [in] */ POINT *pptPos) = 0; + + virtual HRESULT STDMETHODCALLTYPE SimulateHotKey( + /* [in] */ HWND hWnd, + /* [in] */ DWORD dwHotKeyID) = 0; + + virtual HRESULT STDMETHODCALLTYPE UnregisterWordA( + /* [in] */ HKL hKL, + /* [in] */ LPSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPSTR szUnregister) = 0; + + virtual HRESULT STDMETHODCALLTYPE UnregisterWordW( + /* [in] */ HKL hKL, + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szUnregister) = 0; + + virtual HRESULT STDMETHODCALLTYPE GenerateMessage( + /* [in] */ HIMC hIMC) = 0; + + virtual HRESULT STDMETHODCALLTYPE LockIMC( + /* [in] */ HIMC hIMC, + /* [out] */ INPUTCONTEXT **ppIMC) = 0; + + virtual HRESULT STDMETHODCALLTYPE UnlockIMC( + /* [in] */ HIMC hIMC) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetIMCLockCount( + /* [in] */ HIMC hIMC, + /* [out] */ DWORD *pdwLockCount) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateIMCC( + /* [in] */ DWORD dwSize, + /* [out] */ HIMCC *phIMCC) = 0; + + virtual HRESULT STDMETHODCALLTYPE DestroyIMCC( + /* [in] */ HIMCC hIMCC) = 0; + + virtual HRESULT STDMETHODCALLTYPE LockIMCC( + /* [in] */ HIMCC hIMCC, + /* [out] */ void **ppv) = 0; + + virtual HRESULT STDMETHODCALLTYPE UnlockIMCC( + /* [in] */ HIMCC hIMCC) = 0; + + virtual HRESULT STDMETHODCALLTYPE ReSizeIMCC( + /* [in] */ HIMCC hIMCC, + /* [in] */ DWORD dwSize, + /* [out] */ HIMCC *phIMCC) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetIMCCSize( + /* [in] */ HIMCC hIMCC, + /* [out] */ DWORD *pdwSize) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetIMCCLockCount( + /* [in] */ HIMCC hIMCC, + /* [out] */ DWORD *pdwLockCount) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetHotKey( + /* [in] */ DWORD dwHotKeyID, + /* [out] */ UINT *puModifiers, + /* [out] */ UINT *puVKey, + /* [out] */ HKL *phKL) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetHotKey( + /* [in] */ DWORD dwHotKeyID, + /* [in] */ UINT uModifiers, + /* [in] */ UINT uVKey, + /* [in] */ HKL hKL) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateSoftKeyboard( + /* [in] */ UINT uType, + /* [in] */ HWND hOwner, + /* [in] */ int x, + /* [in] */ int y, + /* [out] */ HWND *phSoftKbdWnd) = 0; + + virtual HRESULT STDMETHODCALLTYPE DestroySoftKeyboard( + /* [in] */ HWND hSoftKbdWnd) = 0; + + virtual HRESULT STDMETHODCALLTYPE ShowSoftKeyboard( + /* [in] */ HWND hSoftKbdWnd, + /* [in] */ int nCmdShow) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCodePageA( + /* [in] */ HKL hKL, + /* [out] */ UINT *uCodePage) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetLangId( + /* [in] */ HKL hKL, + /* [out] */ LANGID *plid) = 0; + + virtual HRESULT STDMETHODCALLTYPE KeybdEvent( + /* [in] */ LANGID lgidIME, + /* [in] */ BYTE bVk, + /* [in] */ BYTE bScan, + /* [in] */ DWORD dwFlags, + /* [in] */ DWORD dwExtraInfo) = 0; + + virtual HRESULT STDMETHODCALLTYPE LockModal( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE UnlockModal( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE AssociateContextEx( + /* [in] */ HWND hWnd, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwFlags) = 0; + + virtual HRESULT STDMETHODCALLTYPE DisableIME( + /* [in] */ DWORD idThread) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetImeMenuItemsA( + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwFlags, + /* [in] */ DWORD dwType, + /* [in] */ IMEMENUITEMINFOA *pImeParentMenu, + /* [out] */ IMEMENUITEMINFOA *pImeMenu, + /* [in] */ DWORD dwSize, + /* [out] */ DWORD *pdwResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetImeMenuItemsW( + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwFlags, + /* [in] */ DWORD dwType, + /* [in] */ IMEMENUITEMINFOW *pImeParentMenu, + /* [out] */ IMEMENUITEMINFOW *pImeMenu, + /* [in] */ DWORD dwSize, + /* [out] */ DWORD *pdwResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnumInputContext( + /* [in] */ DWORD idThread, + /* [out] */ IEnumInputContext **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE RequestMessageA( + /* [in] */ HIMC hIMC, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ LRESULT *plResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE RequestMessageW( + /* [in] */ HIMC hIMC, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ LRESULT *plResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE SendIMCA( + /* [in] */ HWND hWnd, + /* [in] */ UINT uMsg, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ LRESULT *plResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE SendIMCW( + /* [in] */ HWND hWnd, + /* [in] */ UINT uMsg, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ LRESULT *plResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE IsSleeping( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct IActiveIMMIMEVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IActiveIMMIME * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IActiveIMMIME * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IActiveIMMIME * This); + + HRESULT ( STDMETHODCALLTYPE *AssociateContext )( + IActiveIMMIME * This, + /* [in] */ HWND hWnd, + /* [in] */ HIMC hIME, + /* [out] */ HIMC *phPrev); + + HRESULT ( STDMETHODCALLTYPE *ConfigureIMEA )( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ HWND hWnd, + /* [in] */ DWORD dwMode, + /* [in] */ REGISTERWORDA *pData); + + HRESULT ( STDMETHODCALLTYPE *ConfigureIMEW )( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ HWND hWnd, + /* [in] */ DWORD dwMode, + /* [in] */ REGISTERWORDW *pData); + + HRESULT ( STDMETHODCALLTYPE *CreateContext )( + IActiveIMMIME * This, + /* [out] */ HIMC *phIMC); + + HRESULT ( STDMETHODCALLTYPE *DestroyContext )( + IActiveIMMIME * This, + /* [in] */ HIMC hIME); + + HRESULT ( STDMETHODCALLTYPE *EnumRegisterWordA )( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ LPSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPSTR szRegister, + /* [in] */ LPVOID pData, + /* [out] */ IEnumRegisterWordA **pEnum); + + HRESULT ( STDMETHODCALLTYPE *EnumRegisterWordW )( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szRegister, + /* [in] */ LPVOID pData, + /* [out] */ IEnumRegisterWordW **pEnum); + + HRESULT ( STDMETHODCALLTYPE *EscapeA )( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ HIMC hIMC, + /* [in] */ UINT uEscape, + /* [out][in] */ LPVOID pData, + /* [out] */ LRESULT *plResult); + + HRESULT ( STDMETHODCALLTYPE *EscapeW )( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ HIMC hIMC, + /* [in] */ UINT uEscape, + /* [out][in] */ LPVOID pData, + /* [out] */ LRESULT *plResult); + + HRESULT ( STDMETHODCALLTYPE *GetCandidateListA )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ UINT uBufLen, + /* [out] */ CANDIDATELIST *pCandList, + /* [out] */ UINT *puCopied); + + HRESULT ( STDMETHODCALLTYPE *GetCandidateListW )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ UINT uBufLen, + /* [out] */ CANDIDATELIST *pCandList, + /* [out] */ UINT *puCopied); + + HRESULT ( STDMETHODCALLTYPE *GetCandidateListCountA )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [out] */ DWORD *pdwListSize, + /* [out] */ DWORD *pdwBufLen); + + HRESULT ( STDMETHODCALLTYPE *GetCandidateListCountW )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [out] */ DWORD *pdwListSize, + /* [out] */ DWORD *pdwBufLen); + + HRESULT ( STDMETHODCALLTYPE *GetCandidateWindow )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [out] */ CANDIDATEFORM *pCandidate); + + HRESULT ( STDMETHODCALLTYPE *GetCompositionFontA )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [out] */ LOGFONTA *plf); + + HRESULT ( STDMETHODCALLTYPE *GetCompositionFontW )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [out] */ LOGFONTW *plf); + + HRESULT ( STDMETHODCALLTYPE *GetCompositionStringA )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwBufLen, + /* [out] */ LONG *plCopied, + /* [out] */ LPVOID pBuf); + + HRESULT ( STDMETHODCALLTYPE *GetCompositionStringW )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwBufLen, + /* [out] */ LONG *plCopied, + /* [out] */ LPVOID pBuf); + + HRESULT ( STDMETHODCALLTYPE *GetCompositionWindow )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [out] */ COMPOSITIONFORM *pCompForm); + + HRESULT ( STDMETHODCALLTYPE *GetContext )( + IActiveIMMIME * This, + /* [in] */ HWND hWnd, + /* [out] */ HIMC *phIMC); + + HRESULT ( STDMETHODCALLTYPE *GetConversionListA )( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ HIMC hIMC, + /* [in] */ LPSTR pSrc, + /* [in] */ UINT uBufLen, + /* [in] */ UINT uFlag, + /* [out] */ CANDIDATELIST *pDst, + /* [out] */ UINT *puCopied); + + HRESULT ( STDMETHODCALLTYPE *GetConversionListW )( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ HIMC hIMC, + /* [in] */ LPWSTR pSrc, + /* [in] */ UINT uBufLen, + /* [in] */ UINT uFlag, + /* [out] */ CANDIDATELIST *pDst, + /* [out] */ UINT *puCopied); + + HRESULT ( STDMETHODCALLTYPE *GetConversionStatus )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [out] */ DWORD *pfdwConversion, + /* [out] */ DWORD *pfdwSentence); + + HRESULT ( STDMETHODCALLTYPE *GetDefaultIMEWnd )( + IActiveIMMIME * This, + /* [in] */ HWND hWnd, + /* [out] */ HWND *phDefWnd); + + HRESULT ( STDMETHODCALLTYPE *GetDescriptionA )( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ UINT uBufLen, + /* [out] */ LPSTR szDescription, + /* [out] */ UINT *puCopied); + + HRESULT ( STDMETHODCALLTYPE *GetDescriptionW )( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ UINT uBufLen, + /* [out] */ LPWSTR szDescription, + /* [out] */ UINT *puCopied); + + HRESULT ( STDMETHODCALLTYPE *GetGuideLineA )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwBufLen, + /* [out] */ LPSTR pBuf, + /* [out] */ DWORD *pdwResult); + + HRESULT ( STDMETHODCALLTYPE *GetGuideLineW )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwBufLen, + /* [out] */ LPWSTR pBuf, + /* [out] */ DWORD *pdwResult); + + HRESULT ( STDMETHODCALLTYPE *GetIMEFileNameA )( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ UINT uBufLen, + /* [out] */ LPSTR szFileName, + /* [out] */ UINT *puCopied); + + HRESULT ( STDMETHODCALLTYPE *GetIMEFileNameW )( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ UINT uBufLen, + /* [out] */ LPWSTR szFileName, + /* [out] */ UINT *puCopied); + + HRESULT ( STDMETHODCALLTYPE *GetOpenStatus )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC); + + HRESULT ( STDMETHODCALLTYPE *GetProperty )( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ DWORD fdwIndex, + /* [out] */ DWORD *pdwProperty); + + HRESULT ( STDMETHODCALLTYPE *GetRegisterWordStyleA )( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ UINT nItem, + /* [out] */ STYLEBUFA *pStyleBuf, + /* [out] */ UINT *puCopied); + + HRESULT ( STDMETHODCALLTYPE *GetRegisterWordStyleW )( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ UINT nItem, + /* [out] */ STYLEBUFW *pStyleBuf, + /* [out] */ UINT *puCopied); + + HRESULT ( STDMETHODCALLTYPE *GetStatusWindowPos )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [out] */ POINT *pptPos); + + HRESULT ( STDMETHODCALLTYPE *GetVirtualKey )( + IActiveIMMIME * This, + /* [in] */ HWND hWnd, + /* [out] */ UINT *puVirtualKey); + + HRESULT ( STDMETHODCALLTYPE *InstallIMEA )( + IActiveIMMIME * This, + /* [in] */ LPSTR szIMEFileName, + /* [in] */ LPSTR szLayoutText, + /* [out] */ HKL *phKL); + + HRESULT ( STDMETHODCALLTYPE *InstallIMEW )( + IActiveIMMIME * This, + /* [in] */ LPWSTR szIMEFileName, + /* [in] */ LPWSTR szLayoutText, + /* [out] */ HKL *phKL); + + HRESULT ( STDMETHODCALLTYPE *IsIME )( + IActiveIMMIME * This, + /* [in] */ HKL hKL); + + HRESULT ( STDMETHODCALLTYPE *IsUIMessageA )( + IActiveIMMIME * This, + /* [in] */ HWND hWndIME, + /* [in] */ UINT msg, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam); + + HRESULT ( STDMETHODCALLTYPE *IsUIMessageW )( + IActiveIMMIME * This, + /* [in] */ HWND hWndIME, + /* [in] */ UINT msg, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam); + + HRESULT ( STDMETHODCALLTYPE *NotifyIME )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwAction, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwValue); + + HRESULT ( STDMETHODCALLTYPE *RegisterWordA )( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ LPSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPSTR szRegister); + + HRESULT ( STDMETHODCALLTYPE *RegisterWordW )( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szRegister); + + HRESULT ( STDMETHODCALLTYPE *ReleaseContext )( + IActiveIMMIME * This, + /* [in] */ HWND hWnd, + /* [in] */ HIMC hIMC); + + HRESULT ( STDMETHODCALLTYPE *SetCandidateWindow )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ CANDIDATEFORM *pCandidate); + + HRESULT ( STDMETHODCALLTYPE *SetCompositionFontA )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ LOGFONTA *plf); + + HRESULT ( STDMETHODCALLTYPE *SetCompositionFontW )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ LOGFONTW *plf); + + HRESULT ( STDMETHODCALLTYPE *SetCompositionStringA )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ LPVOID pComp, + /* [in] */ DWORD dwCompLen, + /* [in] */ LPVOID pRead, + /* [in] */ DWORD dwReadLen); + + HRESULT ( STDMETHODCALLTYPE *SetCompositionStringW )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ LPVOID pComp, + /* [in] */ DWORD dwCompLen, + /* [in] */ LPVOID pRead, + /* [in] */ DWORD dwReadLen); + + HRESULT ( STDMETHODCALLTYPE *SetCompositionWindow )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ COMPOSITIONFORM *pCompForm); + + HRESULT ( STDMETHODCALLTYPE *SetConversionStatus )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD fdwConversion, + /* [in] */ DWORD fdwSentence); + + HRESULT ( STDMETHODCALLTYPE *SetOpenStatus )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ BOOL fOpen); + + HRESULT ( STDMETHODCALLTYPE *SetStatusWindowPos )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ POINT *pptPos); + + HRESULT ( STDMETHODCALLTYPE *SimulateHotKey )( + IActiveIMMIME * This, + /* [in] */ HWND hWnd, + /* [in] */ DWORD dwHotKeyID); + + HRESULT ( STDMETHODCALLTYPE *UnregisterWordA )( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ LPSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPSTR szUnregister); + + HRESULT ( STDMETHODCALLTYPE *UnregisterWordW )( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szUnregister); + + HRESULT ( STDMETHODCALLTYPE *GenerateMessage )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC); + + HRESULT ( STDMETHODCALLTYPE *LockIMC )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [out] */ INPUTCONTEXT **ppIMC); + + HRESULT ( STDMETHODCALLTYPE *UnlockIMC )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC); + + HRESULT ( STDMETHODCALLTYPE *GetIMCLockCount )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [out] */ DWORD *pdwLockCount); + + HRESULT ( STDMETHODCALLTYPE *CreateIMCC )( + IActiveIMMIME * This, + /* [in] */ DWORD dwSize, + /* [out] */ HIMCC *phIMCC); + + HRESULT ( STDMETHODCALLTYPE *DestroyIMCC )( + IActiveIMMIME * This, + /* [in] */ HIMCC hIMCC); + + HRESULT ( STDMETHODCALLTYPE *LockIMCC )( + IActiveIMMIME * This, + /* [in] */ HIMCC hIMCC, + /* [out] */ void **ppv); + + HRESULT ( STDMETHODCALLTYPE *UnlockIMCC )( + IActiveIMMIME * This, + /* [in] */ HIMCC hIMCC); + + HRESULT ( STDMETHODCALLTYPE *ReSizeIMCC )( + IActiveIMMIME * This, + /* [in] */ HIMCC hIMCC, + /* [in] */ DWORD dwSize, + /* [out] */ HIMCC *phIMCC); + + HRESULT ( STDMETHODCALLTYPE *GetIMCCSize )( + IActiveIMMIME * This, + /* [in] */ HIMCC hIMCC, + /* [out] */ DWORD *pdwSize); + + HRESULT ( STDMETHODCALLTYPE *GetIMCCLockCount )( + IActiveIMMIME * This, + /* [in] */ HIMCC hIMCC, + /* [out] */ DWORD *pdwLockCount); + + HRESULT ( STDMETHODCALLTYPE *GetHotKey )( + IActiveIMMIME * This, + /* [in] */ DWORD dwHotKeyID, + /* [out] */ UINT *puModifiers, + /* [out] */ UINT *puVKey, + /* [out] */ HKL *phKL); + + HRESULT ( STDMETHODCALLTYPE *SetHotKey )( + IActiveIMMIME * This, + /* [in] */ DWORD dwHotKeyID, + /* [in] */ UINT uModifiers, + /* [in] */ UINT uVKey, + /* [in] */ HKL hKL); + + HRESULT ( STDMETHODCALLTYPE *CreateSoftKeyboard )( + IActiveIMMIME * This, + /* [in] */ UINT uType, + /* [in] */ HWND hOwner, + /* [in] */ int x, + /* [in] */ int y, + /* [out] */ HWND *phSoftKbdWnd); + + HRESULT ( STDMETHODCALLTYPE *DestroySoftKeyboard )( + IActiveIMMIME * This, + /* [in] */ HWND hSoftKbdWnd); + + HRESULT ( STDMETHODCALLTYPE *ShowSoftKeyboard )( + IActiveIMMIME * This, + /* [in] */ HWND hSoftKbdWnd, + /* [in] */ int nCmdShow); + + HRESULT ( STDMETHODCALLTYPE *GetCodePageA )( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [out] */ UINT *uCodePage); + + HRESULT ( STDMETHODCALLTYPE *GetLangId )( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [out] */ LANGID *plid); + + HRESULT ( STDMETHODCALLTYPE *KeybdEvent )( + IActiveIMMIME * This, + /* [in] */ LANGID lgidIME, + /* [in] */ BYTE bVk, + /* [in] */ BYTE bScan, + /* [in] */ DWORD dwFlags, + /* [in] */ DWORD dwExtraInfo); + + HRESULT ( STDMETHODCALLTYPE *LockModal )( + IActiveIMMIME * This); + + HRESULT ( STDMETHODCALLTYPE *UnlockModal )( + IActiveIMMIME * This); + + HRESULT ( STDMETHODCALLTYPE *AssociateContextEx )( + IActiveIMMIME * This, + /* [in] */ HWND hWnd, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwFlags); + + HRESULT ( STDMETHODCALLTYPE *DisableIME )( + IActiveIMMIME * This, + /* [in] */ DWORD idThread); + + HRESULT ( STDMETHODCALLTYPE *GetImeMenuItemsA )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwFlags, + /* [in] */ DWORD dwType, + /* [in] */ IMEMENUITEMINFOA *pImeParentMenu, + /* [out] */ IMEMENUITEMINFOA *pImeMenu, + /* [in] */ DWORD dwSize, + /* [out] */ DWORD *pdwResult); + + HRESULT ( STDMETHODCALLTYPE *GetImeMenuItemsW )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwFlags, + /* [in] */ DWORD dwType, + /* [in] */ IMEMENUITEMINFOW *pImeParentMenu, + /* [out] */ IMEMENUITEMINFOW *pImeMenu, + /* [in] */ DWORD dwSize, + /* [out] */ DWORD *pdwResult); + + HRESULT ( STDMETHODCALLTYPE *EnumInputContext )( + IActiveIMMIME * This, + /* [in] */ DWORD idThread, + /* [out] */ IEnumInputContext **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *RequestMessageA )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ LRESULT *plResult); + + HRESULT ( STDMETHODCALLTYPE *RequestMessageW )( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ LRESULT *plResult); + + HRESULT ( STDMETHODCALLTYPE *SendIMCA )( + IActiveIMMIME * This, + /* [in] */ HWND hWnd, + /* [in] */ UINT uMsg, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ LRESULT *plResult); + + HRESULT ( STDMETHODCALLTYPE *SendIMCW )( + IActiveIMMIME * This, + /* [in] */ HWND hWnd, + /* [in] */ UINT uMsg, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ LRESULT *plResult); + + HRESULT ( STDMETHODCALLTYPE *IsSleeping )( + IActiveIMMIME * This); + + END_INTERFACE + } IActiveIMMIMEVtbl; + + interface IActiveIMMIME + { + CONST_VTBL struct IActiveIMMIMEVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IActiveIMMIME_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define IActiveIMMIME_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define IActiveIMMIME_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define IActiveIMMIME_AssociateContext(This,hWnd,hIME,phPrev) \ + (This)->lpVtbl -> AssociateContext(This,hWnd,hIME,phPrev) + +#define IActiveIMMIME_ConfigureIMEA(This,hKL,hWnd,dwMode,pData) \ + (This)->lpVtbl -> ConfigureIMEA(This,hKL,hWnd,dwMode,pData) + +#define IActiveIMMIME_ConfigureIMEW(This,hKL,hWnd,dwMode,pData) \ + (This)->lpVtbl -> ConfigureIMEW(This,hKL,hWnd,dwMode,pData) + +#define IActiveIMMIME_CreateContext(This,phIMC) \ + (This)->lpVtbl -> CreateContext(This,phIMC) + +#define IActiveIMMIME_DestroyContext(This,hIME) \ + (This)->lpVtbl -> DestroyContext(This,hIME) + +#define IActiveIMMIME_EnumRegisterWordA(This,hKL,szReading,dwStyle,szRegister,pData,pEnum) \ + (This)->lpVtbl -> EnumRegisterWordA(This,hKL,szReading,dwStyle,szRegister,pData,pEnum) + +#define IActiveIMMIME_EnumRegisterWordW(This,hKL,szReading,dwStyle,szRegister,pData,pEnum) \ + (This)->lpVtbl -> EnumRegisterWordW(This,hKL,szReading,dwStyle,szRegister,pData,pEnum) + +#define IActiveIMMIME_EscapeA(This,hKL,hIMC,uEscape,pData,plResult) \ + (This)->lpVtbl -> EscapeA(This,hKL,hIMC,uEscape,pData,plResult) + +#define IActiveIMMIME_EscapeW(This,hKL,hIMC,uEscape,pData,plResult) \ + (This)->lpVtbl -> EscapeW(This,hKL,hIMC,uEscape,pData,plResult) + +#define IActiveIMMIME_GetCandidateListA(This,hIMC,dwIndex,uBufLen,pCandList,puCopied) \ + (This)->lpVtbl -> GetCandidateListA(This,hIMC,dwIndex,uBufLen,pCandList,puCopied) + +#define IActiveIMMIME_GetCandidateListW(This,hIMC,dwIndex,uBufLen,pCandList,puCopied) \ + (This)->lpVtbl -> GetCandidateListW(This,hIMC,dwIndex,uBufLen,pCandList,puCopied) + +#define IActiveIMMIME_GetCandidateListCountA(This,hIMC,pdwListSize,pdwBufLen) \ + (This)->lpVtbl -> GetCandidateListCountA(This,hIMC,pdwListSize,pdwBufLen) + +#define IActiveIMMIME_GetCandidateListCountW(This,hIMC,pdwListSize,pdwBufLen) \ + (This)->lpVtbl -> GetCandidateListCountW(This,hIMC,pdwListSize,pdwBufLen) + +#define IActiveIMMIME_GetCandidateWindow(This,hIMC,dwIndex,pCandidate) \ + (This)->lpVtbl -> GetCandidateWindow(This,hIMC,dwIndex,pCandidate) + +#define IActiveIMMIME_GetCompositionFontA(This,hIMC,plf) \ + (This)->lpVtbl -> GetCompositionFontA(This,hIMC,plf) + +#define IActiveIMMIME_GetCompositionFontW(This,hIMC,plf) \ + (This)->lpVtbl -> GetCompositionFontW(This,hIMC,plf) + +#define IActiveIMMIME_GetCompositionStringA(This,hIMC,dwIndex,dwBufLen,plCopied,pBuf) \ + (This)->lpVtbl -> GetCompositionStringA(This,hIMC,dwIndex,dwBufLen,plCopied,pBuf) + +#define IActiveIMMIME_GetCompositionStringW(This,hIMC,dwIndex,dwBufLen,plCopied,pBuf) \ + (This)->lpVtbl -> GetCompositionStringW(This,hIMC,dwIndex,dwBufLen,plCopied,pBuf) + +#define IActiveIMMIME_GetCompositionWindow(This,hIMC,pCompForm) \ + (This)->lpVtbl -> GetCompositionWindow(This,hIMC,pCompForm) + +#define IActiveIMMIME_GetContext(This,hWnd,phIMC) \ + (This)->lpVtbl -> GetContext(This,hWnd,phIMC) + +#define IActiveIMMIME_GetConversionListA(This,hKL,hIMC,pSrc,uBufLen,uFlag,pDst,puCopied) \ + (This)->lpVtbl -> GetConversionListA(This,hKL,hIMC,pSrc,uBufLen,uFlag,pDst,puCopied) + +#define IActiveIMMIME_GetConversionListW(This,hKL,hIMC,pSrc,uBufLen,uFlag,pDst,puCopied) \ + (This)->lpVtbl -> GetConversionListW(This,hKL,hIMC,pSrc,uBufLen,uFlag,pDst,puCopied) + +#define IActiveIMMIME_GetConversionStatus(This,hIMC,pfdwConversion,pfdwSentence) \ + (This)->lpVtbl -> GetConversionStatus(This,hIMC,pfdwConversion,pfdwSentence) + +#define IActiveIMMIME_GetDefaultIMEWnd(This,hWnd,phDefWnd) \ + (This)->lpVtbl -> GetDefaultIMEWnd(This,hWnd,phDefWnd) + +#define IActiveIMMIME_GetDescriptionA(This,hKL,uBufLen,szDescription,puCopied) \ + (This)->lpVtbl -> GetDescriptionA(This,hKL,uBufLen,szDescription,puCopied) + +#define IActiveIMMIME_GetDescriptionW(This,hKL,uBufLen,szDescription,puCopied) \ + (This)->lpVtbl -> GetDescriptionW(This,hKL,uBufLen,szDescription,puCopied) + +#define IActiveIMMIME_GetGuideLineA(This,hIMC,dwIndex,dwBufLen,pBuf,pdwResult) \ + (This)->lpVtbl -> GetGuideLineA(This,hIMC,dwIndex,dwBufLen,pBuf,pdwResult) + +#define IActiveIMMIME_GetGuideLineW(This,hIMC,dwIndex,dwBufLen,pBuf,pdwResult) \ + (This)->lpVtbl -> GetGuideLineW(This,hIMC,dwIndex,dwBufLen,pBuf,pdwResult) + +#define IActiveIMMIME_GetIMEFileNameA(This,hKL,uBufLen,szFileName,puCopied) \ + (This)->lpVtbl -> GetIMEFileNameA(This,hKL,uBufLen,szFileName,puCopied) + +#define IActiveIMMIME_GetIMEFileNameW(This,hKL,uBufLen,szFileName,puCopied) \ + (This)->lpVtbl -> GetIMEFileNameW(This,hKL,uBufLen,szFileName,puCopied) + +#define IActiveIMMIME_GetOpenStatus(This,hIMC) \ + (This)->lpVtbl -> GetOpenStatus(This,hIMC) + +#define IActiveIMMIME_GetProperty(This,hKL,fdwIndex,pdwProperty) \ + (This)->lpVtbl -> GetProperty(This,hKL,fdwIndex,pdwProperty) + +#define IActiveIMMIME_GetRegisterWordStyleA(This,hKL,nItem,pStyleBuf,puCopied) \ + (This)->lpVtbl -> GetRegisterWordStyleA(This,hKL,nItem,pStyleBuf,puCopied) + +#define IActiveIMMIME_GetRegisterWordStyleW(This,hKL,nItem,pStyleBuf,puCopied) \ + (This)->lpVtbl -> GetRegisterWordStyleW(This,hKL,nItem,pStyleBuf,puCopied) + +#define IActiveIMMIME_GetStatusWindowPos(This,hIMC,pptPos) \ + (This)->lpVtbl -> GetStatusWindowPos(This,hIMC,pptPos) + +#define IActiveIMMIME_GetVirtualKey(This,hWnd,puVirtualKey) \ + (This)->lpVtbl -> GetVirtualKey(This,hWnd,puVirtualKey) + +#define IActiveIMMIME_InstallIMEA(This,szIMEFileName,szLayoutText,phKL) \ + (This)->lpVtbl -> InstallIMEA(This,szIMEFileName,szLayoutText,phKL) + +#define IActiveIMMIME_InstallIMEW(This,szIMEFileName,szLayoutText,phKL) \ + (This)->lpVtbl -> InstallIMEW(This,szIMEFileName,szLayoutText,phKL) + +#define IActiveIMMIME_IsIME(This,hKL) \ + (This)->lpVtbl -> IsIME(This,hKL) + +#define IActiveIMMIME_IsUIMessageA(This,hWndIME,msg,wParam,lParam) \ + (This)->lpVtbl -> IsUIMessageA(This,hWndIME,msg,wParam,lParam) + +#define IActiveIMMIME_IsUIMessageW(This,hWndIME,msg,wParam,lParam) \ + (This)->lpVtbl -> IsUIMessageW(This,hWndIME,msg,wParam,lParam) + +#define IActiveIMMIME_NotifyIME(This,hIMC,dwAction,dwIndex,dwValue) \ + (This)->lpVtbl -> NotifyIME(This,hIMC,dwAction,dwIndex,dwValue) + +#define IActiveIMMIME_RegisterWordA(This,hKL,szReading,dwStyle,szRegister) \ + (This)->lpVtbl -> RegisterWordA(This,hKL,szReading,dwStyle,szRegister) + +#define IActiveIMMIME_RegisterWordW(This,hKL,szReading,dwStyle,szRegister) \ + (This)->lpVtbl -> RegisterWordW(This,hKL,szReading,dwStyle,szRegister) + +#define IActiveIMMIME_ReleaseContext(This,hWnd,hIMC) \ + (This)->lpVtbl -> ReleaseContext(This,hWnd,hIMC) + +#define IActiveIMMIME_SetCandidateWindow(This,hIMC,pCandidate) \ + (This)->lpVtbl -> SetCandidateWindow(This,hIMC,pCandidate) + +#define IActiveIMMIME_SetCompositionFontA(This,hIMC,plf) \ + (This)->lpVtbl -> SetCompositionFontA(This,hIMC,plf) + +#define IActiveIMMIME_SetCompositionFontW(This,hIMC,plf) \ + (This)->lpVtbl -> SetCompositionFontW(This,hIMC,plf) + +#define IActiveIMMIME_SetCompositionStringA(This,hIMC,dwIndex,pComp,dwCompLen,pRead,dwReadLen) \ + (This)->lpVtbl -> SetCompositionStringA(This,hIMC,dwIndex,pComp,dwCompLen,pRead,dwReadLen) + +#define IActiveIMMIME_SetCompositionStringW(This,hIMC,dwIndex,pComp,dwCompLen,pRead,dwReadLen) \ + (This)->lpVtbl -> SetCompositionStringW(This,hIMC,dwIndex,pComp,dwCompLen,pRead,dwReadLen) + +#define IActiveIMMIME_SetCompositionWindow(This,hIMC,pCompForm) \ + (This)->lpVtbl -> SetCompositionWindow(This,hIMC,pCompForm) + +#define IActiveIMMIME_SetConversionStatus(This,hIMC,fdwConversion,fdwSentence) \ + (This)->lpVtbl -> SetConversionStatus(This,hIMC,fdwConversion,fdwSentence) + +#define IActiveIMMIME_SetOpenStatus(This,hIMC,fOpen) \ + (This)->lpVtbl -> SetOpenStatus(This,hIMC,fOpen) + +#define IActiveIMMIME_SetStatusWindowPos(This,hIMC,pptPos) \ + (This)->lpVtbl -> SetStatusWindowPos(This,hIMC,pptPos) + +#define IActiveIMMIME_SimulateHotKey(This,hWnd,dwHotKeyID) \ + (This)->lpVtbl -> SimulateHotKey(This,hWnd,dwHotKeyID) + +#define IActiveIMMIME_UnregisterWordA(This,hKL,szReading,dwStyle,szUnregister) \ + (This)->lpVtbl -> UnregisterWordA(This,hKL,szReading,dwStyle,szUnregister) + +#define IActiveIMMIME_UnregisterWordW(This,hKL,szReading,dwStyle,szUnregister) \ + (This)->lpVtbl -> UnregisterWordW(This,hKL,szReading,dwStyle,szUnregister) + +#define IActiveIMMIME_GenerateMessage(This,hIMC) \ + (This)->lpVtbl -> GenerateMessage(This,hIMC) + +#define IActiveIMMIME_LockIMC(This,hIMC,ppIMC) \ + (This)->lpVtbl -> LockIMC(This,hIMC,ppIMC) + +#define IActiveIMMIME_UnlockIMC(This,hIMC) \ + (This)->lpVtbl -> UnlockIMC(This,hIMC) + +#define IActiveIMMIME_GetIMCLockCount(This,hIMC,pdwLockCount) \ + (This)->lpVtbl -> GetIMCLockCount(This,hIMC,pdwLockCount) + +#define IActiveIMMIME_CreateIMCC(This,dwSize,phIMCC) \ + (This)->lpVtbl -> CreateIMCC(This,dwSize,phIMCC) + +#define IActiveIMMIME_DestroyIMCC(This,hIMCC) \ + (This)->lpVtbl -> DestroyIMCC(This,hIMCC) + +#define IActiveIMMIME_LockIMCC(This,hIMCC,ppv) \ + (This)->lpVtbl -> LockIMCC(This,hIMCC,ppv) + +#define IActiveIMMIME_UnlockIMCC(This,hIMCC) \ + (This)->lpVtbl -> UnlockIMCC(This,hIMCC) + +#define IActiveIMMIME_ReSizeIMCC(This,hIMCC,dwSize,phIMCC) \ + (This)->lpVtbl -> ReSizeIMCC(This,hIMCC,dwSize,phIMCC) + +#define IActiveIMMIME_GetIMCCSize(This,hIMCC,pdwSize) \ + (This)->lpVtbl -> GetIMCCSize(This,hIMCC,pdwSize) + +#define IActiveIMMIME_GetIMCCLockCount(This,hIMCC,pdwLockCount) \ + (This)->lpVtbl -> GetIMCCLockCount(This,hIMCC,pdwLockCount) + +#define IActiveIMMIME_GetHotKey(This,dwHotKeyID,puModifiers,puVKey,phKL) \ + (This)->lpVtbl -> GetHotKey(This,dwHotKeyID,puModifiers,puVKey,phKL) + +#define IActiveIMMIME_SetHotKey(This,dwHotKeyID,uModifiers,uVKey,hKL) \ + (This)->lpVtbl -> SetHotKey(This,dwHotKeyID,uModifiers,uVKey,hKL) + +#define IActiveIMMIME_CreateSoftKeyboard(This,uType,hOwner,x,y,phSoftKbdWnd) \ + (This)->lpVtbl -> CreateSoftKeyboard(This,uType,hOwner,x,y,phSoftKbdWnd) + +#define IActiveIMMIME_DestroySoftKeyboard(This,hSoftKbdWnd) \ + (This)->lpVtbl -> DestroySoftKeyboard(This,hSoftKbdWnd) + +#define IActiveIMMIME_ShowSoftKeyboard(This,hSoftKbdWnd,nCmdShow) \ + (This)->lpVtbl -> ShowSoftKeyboard(This,hSoftKbdWnd,nCmdShow) + +#define IActiveIMMIME_GetCodePageA(This,hKL,uCodePage) \ + (This)->lpVtbl -> GetCodePageA(This,hKL,uCodePage) + +#define IActiveIMMIME_GetLangId(This,hKL,plid) \ + (This)->lpVtbl -> GetLangId(This,hKL,plid) + +#define IActiveIMMIME_KeybdEvent(This,lgidIME,bVk,bScan,dwFlags,dwExtraInfo) \ + (This)->lpVtbl -> KeybdEvent(This,lgidIME,bVk,bScan,dwFlags,dwExtraInfo) + +#define IActiveIMMIME_LockModal(This) \ + (This)->lpVtbl -> LockModal(This) + +#define IActiveIMMIME_UnlockModal(This) \ + (This)->lpVtbl -> UnlockModal(This) + +#define IActiveIMMIME_AssociateContextEx(This,hWnd,hIMC,dwFlags) \ + (This)->lpVtbl -> AssociateContextEx(This,hWnd,hIMC,dwFlags) + +#define IActiveIMMIME_DisableIME(This,idThread) \ + (This)->lpVtbl -> DisableIME(This,idThread) + +#define IActiveIMMIME_GetImeMenuItemsA(This,hIMC,dwFlags,dwType,pImeParentMenu,pImeMenu,dwSize,pdwResult) \ + (This)->lpVtbl -> GetImeMenuItemsA(This,hIMC,dwFlags,dwType,pImeParentMenu,pImeMenu,dwSize,pdwResult) + +#define IActiveIMMIME_GetImeMenuItemsW(This,hIMC,dwFlags,dwType,pImeParentMenu,pImeMenu,dwSize,pdwResult) \ + (This)->lpVtbl -> GetImeMenuItemsW(This,hIMC,dwFlags,dwType,pImeParentMenu,pImeMenu,dwSize,pdwResult) + +#define IActiveIMMIME_EnumInputContext(This,idThread,ppEnum) \ + (This)->lpVtbl -> EnumInputContext(This,idThread,ppEnum) + +#define IActiveIMMIME_RequestMessageA(This,hIMC,wParam,lParam,plResult) \ + (This)->lpVtbl -> RequestMessageA(This,hIMC,wParam,lParam,plResult) + +#define IActiveIMMIME_RequestMessageW(This,hIMC,wParam,lParam,plResult) \ + (This)->lpVtbl -> RequestMessageW(This,hIMC,wParam,lParam,plResult) + +#define IActiveIMMIME_SendIMCA(This,hWnd,uMsg,wParam,lParam,plResult) \ + (This)->lpVtbl -> SendIMCA(This,hWnd,uMsg,wParam,lParam,plResult) + +#define IActiveIMMIME_SendIMCW(This,hWnd,uMsg,wParam,lParam,plResult) \ + (This)->lpVtbl -> SendIMCW(This,hWnd,uMsg,wParam,lParam,plResult) + +#define IActiveIMMIME_IsSleeping(This) \ + (This)->lpVtbl -> IsSleeping(This) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_AssociateContext_Proxy( + IActiveIMMIME * This, + /* [in] */ HWND hWnd, + /* [in] */ HIMC hIME, + /* [out] */ HIMC *phPrev); + + +void __RPC_STUB IActiveIMMIME_AssociateContext_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_ConfigureIMEA_Proxy( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ HWND hWnd, + /* [in] */ DWORD dwMode, + /* [in] */ REGISTERWORDA *pData); + + +void __RPC_STUB IActiveIMMIME_ConfigureIMEA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_ConfigureIMEW_Proxy( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ HWND hWnd, + /* [in] */ DWORD dwMode, + /* [in] */ REGISTERWORDW *pData); + + +void __RPC_STUB IActiveIMMIME_ConfigureIMEW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_CreateContext_Proxy( + IActiveIMMIME * This, + /* [out] */ HIMC *phIMC); + + +void __RPC_STUB IActiveIMMIME_CreateContext_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_DestroyContext_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIME); + + +void __RPC_STUB IActiveIMMIME_DestroyContext_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_EnumRegisterWordA_Proxy( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ LPSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPSTR szRegister, + /* [in] */ LPVOID pData, + /* [out] */ IEnumRegisterWordA **pEnum); + + +void __RPC_STUB IActiveIMMIME_EnumRegisterWordA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_EnumRegisterWordW_Proxy( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szRegister, + /* [in] */ LPVOID pData, + /* [out] */ IEnumRegisterWordW **pEnum); + + +void __RPC_STUB IActiveIMMIME_EnumRegisterWordW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_EscapeA_Proxy( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ HIMC hIMC, + /* [in] */ UINT uEscape, + /* [out][in] */ LPVOID pData, + /* [out] */ LRESULT *plResult); + + +void __RPC_STUB IActiveIMMIME_EscapeA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_EscapeW_Proxy( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ HIMC hIMC, + /* [in] */ UINT uEscape, + /* [out][in] */ LPVOID pData, + /* [out] */ LRESULT *plResult); + + +void __RPC_STUB IActiveIMMIME_EscapeW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetCandidateListA_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ UINT uBufLen, + /* [out] */ CANDIDATELIST *pCandList, + /* [out] */ UINT *puCopied); + + +void __RPC_STUB IActiveIMMIME_GetCandidateListA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetCandidateListW_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ UINT uBufLen, + /* [out] */ CANDIDATELIST *pCandList, + /* [out] */ UINT *puCopied); + + +void __RPC_STUB IActiveIMMIME_GetCandidateListW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetCandidateListCountA_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [out] */ DWORD *pdwListSize, + /* [out] */ DWORD *pdwBufLen); + + +void __RPC_STUB IActiveIMMIME_GetCandidateListCountA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetCandidateListCountW_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [out] */ DWORD *pdwListSize, + /* [out] */ DWORD *pdwBufLen); + + +void __RPC_STUB IActiveIMMIME_GetCandidateListCountW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetCandidateWindow_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [out] */ CANDIDATEFORM *pCandidate); + + +void __RPC_STUB IActiveIMMIME_GetCandidateWindow_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetCompositionFontA_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [out] */ LOGFONTA *plf); + + +void __RPC_STUB IActiveIMMIME_GetCompositionFontA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetCompositionFontW_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [out] */ LOGFONTW *plf); + + +void __RPC_STUB IActiveIMMIME_GetCompositionFontW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetCompositionStringA_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwBufLen, + /* [out] */ LONG *plCopied, + /* [out] */ LPVOID pBuf); + + +void __RPC_STUB IActiveIMMIME_GetCompositionStringA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetCompositionStringW_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwBufLen, + /* [out] */ LONG *plCopied, + /* [out] */ LPVOID pBuf); + + +void __RPC_STUB IActiveIMMIME_GetCompositionStringW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetCompositionWindow_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [out] */ COMPOSITIONFORM *pCompForm); + + +void __RPC_STUB IActiveIMMIME_GetCompositionWindow_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetContext_Proxy( + IActiveIMMIME * This, + /* [in] */ HWND hWnd, + /* [out] */ HIMC *phIMC); + + +void __RPC_STUB IActiveIMMIME_GetContext_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetConversionListA_Proxy( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ HIMC hIMC, + /* [in] */ LPSTR pSrc, + /* [in] */ UINT uBufLen, + /* [in] */ UINT uFlag, + /* [out] */ CANDIDATELIST *pDst, + /* [out] */ UINT *puCopied); + + +void __RPC_STUB IActiveIMMIME_GetConversionListA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetConversionListW_Proxy( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ HIMC hIMC, + /* [in] */ LPWSTR pSrc, + /* [in] */ UINT uBufLen, + /* [in] */ UINT uFlag, + /* [out] */ CANDIDATELIST *pDst, + /* [out] */ UINT *puCopied); + + +void __RPC_STUB IActiveIMMIME_GetConversionListW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetConversionStatus_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [out] */ DWORD *pfdwConversion, + /* [out] */ DWORD *pfdwSentence); + + +void __RPC_STUB IActiveIMMIME_GetConversionStatus_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetDefaultIMEWnd_Proxy( + IActiveIMMIME * This, + /* [in] */ HWND hWnd, + /* [out] */ HWND *phDefWnd); + + +void __RPC_STUB IActiveIMMIME_GetDefaultIMEWnd_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetDescriptionA_Proxy( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ UINT uBufLen, + /* [out] */ LPSTR szDescription, + /* [out] */ UINT *puCopied); + + +void __RPC_STUB IActiveIMMIME_GetDescriptionA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetDescriptionW_Proxy( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ UINT uBufLen, + /* [out] */ LPWSTR szDescription, + /* [out] */ UINT *puCopied); + + +void __RPC_STUB IActiveIMMIME_GetDescriptionW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetGuideLineA_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwBufLen, + /* [out] */ LPSTR pBuf, + /* [out] */ DWORD *pdwResult); + + +void __RPC_STUB IActiveIMMIME_GetGuideLineA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetGuideLineW_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwBufLen, + /* [out] */ LPWSTR pBuf, + /* [out] */ DWORD *pdwResult); + + +void __RPC_STUB IActiveIMMIME_GetGuideLineW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetIMEFileNameA_Proxy( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ UINT uBufLen, + /* [out] */ LPSTR szFileName, + /* [out] */ UINT *puCopied); + + +void __RPC_STUB IActiveIMMIME_GetIMEFileNameA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetIMEFileNameW_Proxy( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ UINT uBufLen, + /* [out] */ LPWSTR szFileName, + /* [out] */ UINT *puCopied); + + +void __RPC_STUB IActiveIMMIME_GetIMEFileNameW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetOpenStatus_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC); + + +void __RPC_STUB IActiveIMMIME_GetOpenStatus_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetProperty_Proxy( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ DWORD fdwIndex, + /* [out] */ DWORD *pdwProperty); + + +void __RPC_STUB IActiveIMMIME_GetProperty_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetRegisterWordStyleA_Proxy( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ UINT nItem, + /* [out] */ STYLEBUFA *pStyleBuf, + /* [out] */ UINT *puCopied); + + +void __RPC_STUB IActiveIMMIME_GetRegisterWordStyleA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetRegisterWordStyleW_Proxy( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ UINT nItem, + /* [out] */ STYLEBUFW *pStyleBuf, + /* [out] */ UINT *puCopied); + + +void __RPC_STUB IActiveIMMIME_GetRegisterWordStyleW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetStatusWindowPos_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [out] */ POINT *pptPos); + + +void __RPC_STUB IActiveIMMIME_GetStatusWindowPos_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetVirtualKey_Proxy( + IActiveIMMIME * This, + /* [in] */ HWND hWnd, + /* [out] */ UINT *puVirtualKey); + + +void __RPC_STUB IActiveIMMIME_GetVirtualKey_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_InstallIMEA_Proxy( + IActiveIMMIME * This, + /* [in] */ LPSTR szIMEFileName, + /* [in] */ LPSTR szLayoutText, + /* [out] */ HKL *phKL); + + +void __RPC_STUB IActiveIMMIME_InstallIMEA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_InstallIMEW_Proxy( + IActiveIMMIME * This, + /* [in] */ LPWSTR szIMEFileName, + /* [in] */ LPWSTR szLayoutText, + /* [out] */ HKL *phKL); + + +void __RPC_STUB IActiveIMMIME_InstallIMEW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_IsIME_Proxy( + IActiveIMMIME * This, + /* [in] */ HKL hKL); + + +void __RPC_STUB IActiveIMMIME_IsIME_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_IsUIMessageA_Proxy( + IActiveIMMIME * This, + /* [in] */ HWND hWndIME, + /* [in] */ UINT msg, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam); + + +void __RPC_STUB IActiveIMMIME_IsUIMessageA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_IsUIMessageW_Proxy( + IActiveIMMIME * This, + /* [in] */ HWND hWndIME, + /* [in] */ UINT msg, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam); + + +void __RPC_STUB IActiveIMMIME_IsUIMessageW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_NotifyIME_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwAction, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwValue); + + +void __RPC_STUB IActiveIMMIME_NotifyIME_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_RegisterWordA_Proxy( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ LPSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPSTR szRegister); + + +void __RPC_STUB IActiveIMMIME_RegisterWordA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_RegisterWordW_Proxy( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szRegister); + + +void __RPC_STUB IActiveIMMIME_RegisterWordW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_ReleaseContext_Proxy( + IActiveIMMIME * This, + /* [in] */ HWND hWnd, + /* [in] */ HIMC hIMC); + + +void __RPC_STUB IActiveIMMIME_ReleaseContext_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_SetCandidateWindow_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ CANDIDATEFORM *pCandidate); + + +void __RPC_STUB IActiveIMMIME_SetCandidateWindow_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_SetCompositionFontA_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ LOGFONTA *plf); + + +void __RPC_STUB IActiveIMMIME_SetCompositionFontA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_SetCompositionFontW_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ LOGFONTW *plf); + + +void __RPC_STUB IActiveIMMIME_SetCompositionFontW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_SetCompositionStringA_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ LPVOID pComp, + /* [in] */ DWORD dwCompLen, + /* [in] */ LPVOID pRead, + /* [in] */ DWORD dwReadLen); + + +void __RPC_STUB IActiveIMMIME_SetCompositionStringA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_SetCompositionStringW_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ LPVOID pComp, + /* [in] */ DWORD dwCompLen, + /* [in] */ LPVOID pRead, + /* [in] */ DWORD dwReadLen); + + +void __RPC_STUB IActiveIMMIME_SetCompositionStringW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_SetCompositionWindow_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ COMPOSITIONFORM *pCompForm); + + +void __RPC_STUB IActiveIMMIME_SetCompositionWindow_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_SetConversionStatus_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD fdwConversion, + /* [in] */ DWORD fdwSentence); + + +void __RPC_STUB IActiveIMMIME_SetConversionStatus_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_SetOpenStatus_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ BOOL fOpen); + + +void __RPC_STUB IActiveIMMIME_SetOpenStatus_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_SetStatusWindowPos_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ POINT *pptPos); + + +void __RPC_STUB IActiveIMMIME_SetStatusWindowPos_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_SimulateHotKey_Proxy( + IActiveIMMIME * This, + /* [in] */ HWND hWnd, + /* [in] */ DWORD dwHotKeyID); + + +void __RPC_STUB IActiveIMMIME_SimulateHotKey_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_UnregisterWordA_Proxy( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ LPSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPSTR szUnregister); + + +void __RPC_STUB IActiveIMMIME_UnregisterWordA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_UnregisterWordW_Proxy( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szUnregister); + + +void __RPC_STUB IActiveIMMIME_UnregisterWordW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GenerateMessage_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC); + + +void __RPC_STUB IActiveIMMIME_GenerateMessage_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_LockIMC_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [out] */ INPUTCONTEXT **ppIMC); + + +void __RPC_STUB IActiveIMMIME_LockIMC_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_UnlockIMC_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC); + + +void __RPC_STUB IActiveIMMIME_UnlockIMC_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetIMCLockCount_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [out] */ DWORD *pdwLockCount); + + +void __RPC_STUB IActiveIMMIME_GetIMCLockCount_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_CreateIMCC_Proxy( + IActiveIMMIME * This, + /* [in] */ DWORD dwSize, + /* [out] */ HIMCC *phIMCC); + + +void __RPC_STUB IActiveIMMIME_CreateIMCC_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_DestroyIMCC_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMCC hIMCC); + + +void __RPC_STUB IActiveIMMIME_DestroyIMCC_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_LockIMCC_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMCC hIMCC, + /* [out] */ void **ppv); + + +void __RPC_STUB IActiveIMMIME_LockIMCC_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_UnlockIMCC_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMCC hIMCC); + + +void __RPC_STUB IActiveIMMIME_UnlockIMCC_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_ReSizeIMCC_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMCC hIMCC, + /* [in] */ DWORD dwSize, + /* [out] */ HIMCC *phIMCC); + + +void __RPC_STUB IActiveIMMIME_ReSizeIMCC_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetIMCCSize_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMCC hIMCC, + /* [out] */ DWORD *pdwSize); + + +void __RPC_STUB IActiveIMMIME_GetIMCCSize_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetIMCCLockCount_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMCC hIMCC, + /* [out] */ DWORD *pdwLockCount); + + +void __RPC_STUB IActiveIMMIME_GetIMCCLockCount_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetHotKey_Proxy( + IActiveIMMIME * This, + /* [in] */ DWORD dwHotKeyID, + /* [out] */ UINT *puModifiers, + /* [out] */ UINT *puVKey, + /* [out] */ HKL *phKL); + + +void __RPC_STUB IActiveIMMIME_GetHotKey_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_SetHotKey_Proxy( + IActiveIMMIME * This, + /* [in] */ DWORD dwHotKeyID, + /* [in] */ UINT uModifiers, + /* [in] */ UINT uVKey, + /* [in] */ HKL hKL); + + +void __RPC_STUB IActiveIMMIME_SetHotKey_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_CreateSoftKeyboard_Proxy( + IActiveIMMIME * This, + /* [in] */ UINT uType, + /* [in] */ HWND hOwner, + /* [in] */ int x, + /* [in] */ int y, + /* [out] */ HWND *phSoftKbdWnd); + + +void __RPC_STUB IActiveIMMIME_CreateSoftKeyboard_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_DestroySoftKeyboard_Proxy( + IActiveIMMIME * This, + /* [in] */ HWND hSoftKbdWnd); + + +void __RPC_STUB IActiveIMMIME_DestroySoftKeyboard_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_ShowSoftKeyboard_Proxy( + IActiveIMMIME * This, + /* [in] */ HWND hSoftKbdWnd, + /* [in] */ int nCmdShow); + + +void __RPC_STUB IActiveIMMIME_ShowSoftKeyboard_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetCodePageA_Proxy( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [out] */ UINT *uCodePage); + + +void __RPC_STUB IActiveIMMIME_GetCodePageA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetLangId_Proxy( + IActiveIMMIME * This, + /* [in] */ HKL hKL, + /* [out] */ LANGID *plid); + + +void __RPC_STUB IActiveIMMIME_GetLangId_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_KeybdEvent_Proxy( + IActiveIMMIME * This, + /* [in] */ LANGID lgidIME, + /* [in] */ BYTE bVk, + /* [in] */ BYTE bScan, + /* [in] */ DWORD dwFlags, + /* [in] */ DWORD dwExtraInfo); + + +void __RPC_STUB IActiveIMMIME_KeybdEvent_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_LockModal_Proxy( + IActiveIMMIME * This); + + +void __RPC_STUB IActiveIMMIME_LockModal_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_UnlockModal_Proxy( + IActiveIMMIME * This); + + +void __RPC_STUB IActiveIMMIME_UnlockModal_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_AssociateContextEx_Proxy( + IActiveIMMIME * This, + /* [in] */ HWND hWnd, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwFlags); + + +void __RPC_STUB IActiveIMMIME_AssociateContextEx_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_DisableIME_Proxy( + IActiveIMMIME * This, + /* [in] */ DWORD idThread); + + +void __RPC_STUB IActiveIMMIME_DisableIME_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetImeMenuItemsA_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwFlags, + /* [in] */ DWORD dwType, + /* [in] */ IMEMENUITEMINFOA *pImeParentMenu, + /* [out] */ IMEMENUITEMINFOA *pImeMenu, + /* [in] */ DWORD dwSize, + /* [out] */ DWORD *pdwResult); + + +void __RPC_STUB IActiveIMMIME_GetImeMenuItemsA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_GetImeMenuItemsW_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwFlags, + /* [in] */ DWORD dwType, + /* [in] */ IMEMENUITEMINFOW *pImeParentMenu, + /* [out] */ IMEMENUITEMINFOW *pImeMenu, + /* [in] */ DWORD dwSize, + /* [out] */ DWORD *pdwResult); + + +void __RPC_STUB IActiveIMMIME_GetImeMenuItemsW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_EnumInputContext_Proxy( + IActiveIMMIME * This, + /* [in] */ DWORD idThread, + /* [out] */ IEnumInputContext **ppEnum); + + +void __RPC_STUB IActiveIMMIME_EnumInputContext_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_RequestMessageA_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ LRESULT *plResult); + + +void __RPC_STUB IActiveIMMIME_RequestMessageA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_RequestMessageW_Proxy( + IActiveIMMIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ LRESULT *plResult); + + +void __RPC_STUB IActiveIMMIME_RequestMessageW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_SendIMCA_Proxy( + IActiveIMMIME * This, + /* [in] */ HWND hWnd, + /* [in] */ UINT uMsg, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ LRESULT *plResult); + + +void __RPC_STUB IActiveIMMIME_SendIMCA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_SendIMCW_Proxy( + IActiveIMMIME * This, + /* [in] */ HWND hWnd, + /* [in] */ UINT uMsg, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ LRESULT *plResult); + + +void __RPC_STUB IActiveIMMIME_SendIMCW_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIMMIME_IsSleeping_Proxy( + IActiveIMMIME * This); + + +void __RPC_STUB IActiveIMMIME_IsSleeping_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IActiveIMMIME_INTERFACE_DEFINED__ */ + + +#ifndef __IActiveIME_INTERFACE_DEFINED__ +#define __IActiveIME_INTERFACE_DEFINED__ + +/* interface IActiveIME */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_IActiveIME; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("6FE20962-D077-11d0-8FE7-00AA006BCC59") + IActiveIME : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Inquire( + /* [in] */ DWORD dwSystemInfoFlags, + /* [out] */ IMEINFO *pIMEInfo, + /* [out] */ LPWSTR szWndClass, + /* [out] */ DWORD *pdwPrivate) = 0; + + virtual HRESULT STDMETHODCALLTYPE ConversionList( + /* [in] */ HIMC hIMC, + /* [in] */ LPWSTR szSource, + /* [in] */ UINT uFlag, + /* [in] */ UINT uBufLen, + /* [out] */ CANDIDATELIST *pDest, + /* [out] */ UINT *puCopied) = 0; + + virtual HRESULT STDMETHODCALLTYPE Configure( + /* [in] */ HKL hKL, + /* [in] */ HWND hWnd, + /* [in] */ DWORD dwMode, + /* [in] */ REGISTERWORDW *pRegisterWord) = 0; + + virtual HRESULT STDMETHODCALLTYPE Destroy( + /* [in] */ UINT uReserved) = 0; + + virtual HRESULT STDMETHODCALLTYPE Escape( + /* [in] */ HIMC hIMC, + /* [in] */ UINT uEscape, + /* [out][in] */ void *pData, + /* [out] */ LRESULT *plResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetActiveContext( + /* [in] */ HIMC hIMC, + /* [in] */ BOOL fFlag) = 0; + + virtual HRESULT STDMETHODCALLTYPE ProcessKey( + /* [in] */ HIMC hIMC, + /* [in] */ UINT uVirKey, + /* [in] */ DWORD lParam, + /* [in] */ BYTE *pbKeyState) = 0; + + virtual HRESULT STDMETHODCALLTYPE Notify( + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwAction, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwValue) = 0; + + virtual HRESULT STDMETHODCALLTYPE Select( + /* [in] */ HIMC hIMC, + /* [in] */ BOOL fSelect) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetCompositionString( + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ void *pComp, + /* [in] */ DWORD dwCompLen, + /* [in] */ void *pRead, + /* [in] */ DWORD dwReadLen) = 0; + + virtual HRESULT STDMETHODCALLTYPE ToAsciiEx( + /* [in] */ UINT uVirKey, + /* [in] */ UINT uScanCode, + /* [in] */ BYTE *pbKeyState, + /* [in] */ UINT fuState, + /* [in] */ HIMC hIMC, + /* [out] */ DWORD *pdwTransBuf, + /* [out] */ UINT *puSize) = 0; + + virtual HRESULT STDMETHODCALLTYPE RegisterWord( + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szString) = 0; + + virtual HRESULT STDMETHODCALLTYPE UnregisterWord( + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szString) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetRegisterWordStyle( + /* [in] */ UINT nItem, + /* [out] */ STYLEBUFW *pStyleBuf, + /* [out] */ UINT *puBufSize) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnumRegisterWord( + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szRegister, + /* [in] */ LPVOID pData, + /* [out] */ IEnumRegisterWordW **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCodePageA( + /* [out] */ UINT *uCodePage) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetLangId( + /* [out] */ LANGID *plid) = 0; + + }; + +#else /* C style interface */ + + typedef struct IActiveIMEVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IActiveIME * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IActiveIME * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IActiveIME * This); + + HRESULT ( STDMETHODCALLTYPE *Inquire )( + IActiveIME * This, + /* [in] */ DWORD dwSystemInfoFlags, + /* [out] */ IMEINFO *pIMEInfo, + /* [out] */ LPWSTR szWndClass, + /* [out] */ DWORD *pdwPrivate); + + HRESULT ( STDMETHODCALLTYPE *ConversionList )( + IActiveIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ LPWSTR szSource, + /* [in] */ UINT uFlag, + /* [in] */ UINT uBufLen, + /* [out] */ CANDIDATELIST *pDest, + /* [out] */ UINT *puCopied); + + HRESULT ( STDMETHODCALLTYPE *Configure )( + IActiveIME * This, + /* [in] */ HKL hKL, + /* [in] */ HWND hWnd, + /* [in] */ DWORD dwMode, + /* [in] */ REGISTERWORDW *pRegisterWord); + + HRESULT ( STDMETHODCALLTYPE *Destroy )( + IActiveIME * This, + /* [in] */ UINT uReserved); + + HRESULT ( STDMETHODCALLTYPE *Escape )( + IActiveIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ UINT uEscape, + /* [out][in] */ void *pData, + /* [out] */ LRESULT *plResult); + + HRESULT ( STDMETHODCALLTYPE *SetActiveContext )( + IActiveIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ BOOL fFlag); + + HRESULT ( STDMETHODCALLTYPE *ProcessKey )( + IActiveIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ UINT uVirKey, + /* [in] */ DWORD lParam, + /* [in] */ BYTE *pbKeyState); + + HRESULT ( STDMETHODCALLTYPE *Notify )( + IActiveIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwAction, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwValue); + + HRESULT ( STDMETHODCALLTYPE *Select )( + IActiveIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ BOOL fSelect); + + HRESULT ( STDMETHODCALLTYPE *SetCompositionString )( + IActiveIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ void *pComp, + /* [in] */ DWORD dwCompLen, + /* [in] */ void *pRead, + /* [in] */ DWORD dwReadLen); + + HRESULT ( STDMETHODCALLTYPE *ToAsciiEx )( + IActiveIME * This, + /* [in] */ UINT uVirKey, + /* [in] */ UINT uScanCode, + /* [in] */ BYTE *pbKeyState, + /* [in] */ UINT fuState, + /* [in] */ HIMC hIMC, + /* [out] */ DWORD *pdwTransBuf, + /* [out] */ UINT *puSize); + + HRESULT ( STDMETHODCALLTYPE *RegisterWord )( + IActiveIME * This, + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szString); + + HRESULT ( STDMETHODCALLTYPE *UnregisterWord )( + IActiveIME * This, + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szString); + + HRESULT ( STDMETHODCALLTYPE *GetRegisterWordStyle )( + IActiveIME * This, + /* [in] */ UINT nItem, + /* [out] */ STYLEBUFW *pStyleBuf, + /* [out] */ UINT *puBufSize); + + HRESULT ( STDMETHODCALLTYPE *EnumRegisterWord )( + IActiveIME * This, + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szRegister, + /* [in] */ LPVOID pData, + /* [out] */ IEnumRegisterWordW **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *GetCodePageA )( + IActiveIME * This, + /* [out] */ UINT *uCodePage); + + HRESULT ( STDMETHODCALLTYPE *GetLangId )( + IActiveIME * This, + /* [out] */ LANGID *plid); + + END_INTERFACE + } IActiveIMEVtbl; + + interface IActiveIME + { + CONST_VTBL struct IActiveIMEVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IActiveIME_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define IActiveIME_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define IActiveIME_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define IActiveIME_Inquire(This,dwSystemInfoFlags,pIMEInfo,szWndClass,pdwPrivate) \ + (This)->lpVtbl -> Inquire(This,dwSystemInfoFlags,pIMEInfo,szWndClass,pdwPrivate) + +#define IActiveIME_ConversionList(This,hIMC,szSource,uFlag,uBufLen,pDest,puCopied) \ + (This)->lpVtbl -> ConversionList(This,hIMC,szSource,uFlag,uBufLen,pDest,puCopied) + +#define IActiveIME_Configure(This,hKL,hWnd,dwMode,pRegisterWord) \ + (This)->lpVtbl -> Configure(This,hKL,hWnd,dwMode,pRegisterWord) + +#define IActiveIME_Destroy(This,uReserved) \ + (This)->lpVtbl -> Destroy(This,uReserved) + +#define IActiveIME_Escape(This,hIMC,uEscape,pData,plResult) \ + (This)->lpVtbl -> Escape(This,hIMC,uEscape,pData,plResult) + +#define IActiveIME_SetActiveContext(This,hIMC,fFlag) \ + (This)->lpVtbl -> SetActiveContext(This,hIMC,fFlag) + +#define IActiveIME_ProcessKey(This,hIMC,uVirKey,lParam,pbKeyState) \ + (This)->lpVtbl -> ProcessKey(This,hIMC,uVirKey,lParam,pbKeyState) + +#define IActiveIME_Notify(This,hIMC,dwAction,dwIndex,dwValue) \ + (This)->lpVtbl -> Notify(This,hIMC,dwAction,dwIndex,dwValue) + +#define IActiveIME_Select(This,hIMC,fSelect) \ + (This)->lpVtbl -> Select(This,hIMC,fSelect) + +#define IActiveIME_SetCompositionString(This,hIMC,dwIndex,pComp,dwCompLen,pRead,dwReadLen) \ + (This)->lpVtbl -> SetCompositionString(This,hIMC,dwIndex,pComp,dwCompLen,pRead,dwReadLen) + +#define IActiveIME_ToAsciiEx(This,uVirKey,uScanCode,pbKeyState,fuState,hIMC,pdwTransBuf,puSize) \ + (This)->lpVtbl -> ToAsciiEx(This,uVirKey,uScanCode,pbKeyState,fuState,hIMC,pdwTransBuf,puSize) + +#define IActiveIME_RegisterWord(This,szReading,dwStyle,szString) \ + (This)->lpVtbl -> RegisterWord(This,szReading,dwStyle,szString) + +#define IActiveIME_UnregisterWord(This,szReading,dwStyle,szString) \ + (This)->lpVtbl -> UnregisterWord(This,szReading,dwStyle,szString) + +#define IActiveIME_GetRegisterWordStyle(This,nItem,pStyleBuf,puBufSize) \ + (This)->lpVtbl -> GetRegisterWordStyle(This,nItem,pStyleBuf,puBufSize) + +#define IActiveIME_EnumRegisterWord(This,szReading,dwStyle,szRegister,pData,ppEnum) \ + (This)->lpVtbl -> EnumRegisterWord(This,szReading,dwStyle,szRegister,pData,ppEnum) + +#define IActiveIME_GetCodePageA(This,uCodePage) \ + (This)->lpVtbl -> GetCodePageA(This,uCodePage) + +#define IActiveIME_GetLangId(This,plid) \ + (This)->lpVtbl -> GetLangId(This,plid) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +HRESULT STDMETHODCALLTYPE IActiveIME_Inquire_Proxy( + IActiveIME * This, + /* [in] */ DWORD dwSystemInfoFlags, + /* [out] */ IMEINFO *pIMEInfo, + /* [out] */ LPWSTR szWndClass, + /* [out] */ DWORD *pdwPrivate); + + +void __RPC_STUB IActiveIME_Inquire_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIME_ConversionList_Proxy( + IActiveIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ LPWSTR szSource, + /* [in] */ UINT uFlag, + /* [in] */ UINT uBufLen, + /* [out] */ CANDIDATELIST *pDest, + /* [out] */ UINT *puCopied); + + +void __RPC_STUB IActiveIME_ConversionList_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIME_Configure_Proxy( + IActiveIME * This, + /* [in] */ HKL hKL, + /* [in] */ HWND hWnd, + /* [in] */ DWORD dwMode, + /* [in] */ REGISTERWORDW *pRegisterWord); + + +void __RPC_STUB IActiveIME_Configure_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIME_Destroy_Proxy( + IActiveIME * This, + /* [in] */ UINT uReserved); + + +void __RPC_STUB IActiveIME_Destroy_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIME_Escape_Proxy( + IActiveIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ UINT uEscape, + /* [out][in] */ void *pData, + /* [out] */ LRESULT *plResult); + + +void __RPC_STUB IActiveIME_Escape_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIME_SetActiveContext_Proxy( + IActiveIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ BOOL fFlag); + + +void __RPC_STUB IActiveIME_SetActiveContext_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIME_ProcessKey_Proxy( + IActiveIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ UINT uVirKey, + /* [in] */ DWORD lParam, + /* [in] */ BYTE *pbKeyState); + + +void __RPC_STUB IActiveIME_ProcessKey_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIME_Notify_Proxy( + IActiveIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwAction, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwValue); + + +void __RPC_STUB IActiveIME_Notify_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIME_Select_Proxy( + IActiveIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ BOOL fSelect); + + +void __RPC_STUB IActiveIME_Select_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIME_SetCompositionString_Proxy( + IActiveIME * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ void *pComp, + /* [in] */ DWORD dwCompLen, + /* [in] */ void *pRead, + /* [in] */ DWORD dwReadLen); + + +void __RPC_STUB IActiveIME_SetCompositionString_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIME_ToAsciiEx_Proxy( + IActiveIME * This, + /* [in] */ UINT uVirKey, + /* [in] */ UINT uScanCode, + /* [in] */ BYTE *pbKeyState, + /* [in] */ UINT fuState, + /* [in] */ HIMC hIMC, + /* [out] */ DWORD *pdwTransBuf, + /* [out] */ UINT *puSize); + + +void __RPC_STUB IActiveIME_ToAsciiEx_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIME_RegisterWord_Proxy( + IActiveIME * This, + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szString); + + +void __RPC_STUB IActiveIME_RegisterWord_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIME_UnregisterWord_Proxy( + IActiveIME * This, + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szString); + + +void __RPC_STUB IActiveIME_UnregisterWord_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIME_GetRegisterWordStyle_Proxy( + IActiveIME * This, + /* [in] */ UINT nItem, + /* [out] */ STYLEBUFW *pStyleBuf, + /* [out] */ UINT *puBufSize); + + +void __RPC_STUB IActiveIME_GetRegisterWordStyle_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIME_EnumRegisterWord_Proxy( + IActiveIME * This, + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szRegister, + /* [in] */ LPVOID pData, + /* [out] */ IEnumRegisterWordW **ppEnum); + + +void __RPC_STUB IActiveIME_EnumRegisterWord_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIME_GetCodePageA_Proxy( + IActiveIME * This, + /* [out] */ UINT *uCodePage); + + +void __RPC_STUB IActiveIME_GetCodePageA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIME_GetLangId_Proxy( + IActiveIME * This, + /* [out] */ LANGID *plid); + + +void __RPC_STUB IActiveIME_GetLangId_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IActiveIME_INTERFACE_DEFINED__ */ + + +#ifndef __IActiveIME2_INTERFACE_DEFINED__ +#define __IActiveIME2_INTERFACE_DEFINED__ + +/* interface IActiveIME2 */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_IActiveIME2; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("e1c4bf0e-2d53-11d2-93e1-0060b067b86e") + IActiveIME2 : public IActiveIME + { + public: + virtual HRESULT STDMETHODCALLTYPE Sleep( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Unsleep( + /* [in] */ BOOL fDead) = 0; + + }; + +#else /* C style interface */ + + typedef struct IActiveIME2Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IActiveIME2 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IActiveIME2 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IActiveIME2 * This); + + HRESULT ( STDMETHODCALLTYPE *Inquire )( + IActiveIME2 * This, + /* [in] */ DWORD dwSystemInfoFlags, + /* [out] */ IMEINFO *pIMEInfo, + /* [out] */ LPWSTR szWndClass, + /* [out] */ DWORD *pdwPrivate); + + HRESULT ( STDMETHODCALLTYPE *ConversionList )( + IActiveIME2 * This, + /* [in] */ HIMC hIMC, + /* [in] */ LPWSTR szSource, + /* [in] */ UINT uFlag, + /* [in] */ UINT uBufLen, + /* [out] */ CANDIDATELIST *pDest, + /* [out] */ UINT *puCopied); + + HRESULT ( STDMETHODCALLTYPE *Configure )( + IActiveIME2 * This, + /* [in] */ HKL hKL, + /* [in] */ HWND hWnd, + /* [in] */ DWORD dwMode, + /* [in] */ REGISTERWORDW *pRegisterWord); + + HRESULT ( STDMETHODCALLTYPE *Destroy )( + IActiveIME2 * This, + /* [in] */ UINT uReserved); + + HRESULT ( STDMETHODCALLTYPE *Escape )( + IActiveIME2 * This, + /* [in] */ HIMC hIMC, + /* [in] */ UINT uEscape, + /* [out][in] */ void *pData, + /* [out] */ LRESULT *plResult); + + HRESULT ( STDMETHODCALLTYPE *SetActiveContext )( + IActiveIME2 * This, + /* [in] */ HIMC hIMC, + /* [in] */ BOOL fFlag); + + HRESULT ( STDMETHODCALLTYPE *ProcessKey )( + IActiveIME2 * This, + /* [in] */ HIMC hIMC, + /* [in] */ UINT uVirKey, + /* [in] */ DWORD lParam, + /* [in] */ BYTE *pbKeyState); + + HRESULT ( STDMETHODCALLTYPE *Notify )( + IActiveIME2 * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwAction, + /* [in] */ DWORD dwIndex, + /* [in] */ DWORD dwValue); + + HRESULT ( STDMETHODCALLTYPE *Select )( + IActiveIME2 * This, + /* [in] */ HIMC hIMC, + /* [in] */ BOOL fSelect); + + HRESULT ( STDMETHODCALLTYPE *SetCompositionString )( + IActiveIME2 * This, + /* [in] */ HIMC hIMC, + /* [in] */ DWORD dwIndex, + /* [in] */ void *pComp, + /* [in] */ DWORD dwCompLen, + /* [in] */ void *pRead, + /* [in] */ DWORD dwReadLen); + + HRESULT ( STDMETHODCALLTYPE *ToAsciiEx )( + IActiveIME2 * This, + /* [in] */ UINT uVirKey, + /* [in] */ UINT uScanCode, + /* [in] */ BYTE *pbKeyState, + /* [in] */ UINT fuState, + /* [in] */ HIMC hIMC, + /* [out] */ DWORD *pdwTransBuf, + /* [out] */ UINT *puSize); + + HRESULT ( STDMETHODCALLTYPE *RegisterWord )( + IActiveIME2 * This, + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szString); + + HRESULT ( STDMETHODCALLTYPE *UnregisterWord )( + IActiveIME2 * This, + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szString); + + HRESULT ( STDMETHODCALLTYPE *GetRegisterWordStyle )( + IActiveIME2 * This, + /* [in] */ UINT nItem, + /* [out] */ STYLEBUFW *pStyleBuf, + /* [out] */ UINT *puBufSize); + + HRESULT ( STDMETHODCALLTYPE *EnumRegisterWord )( + IActiveIME2 * This, + /* [in] */ LPWSTR szReading, + /* [in] */ DWORD dwStyle, + /* [in] */ LPWSTR szRegister, + /* [in] */ LPVOID pData, + /* [out] */ IEnumRegisterWordW **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *GetCodePageA )( + IActiveIME2 * This, + /* [out] */ UINT *uCodePage); + + HRESULT ( STDMETHODCALLTYPE *GetLangId )( + IActiveIME2 * This, + /* [out] */ LANGID *plid); + + HRESULT ( STDMETHODCALLTYPE *Sleep )( + IActiveIME2 * This); + + HRESULT ( STDMETHODCALLTYPE *Unsleep )( + IActiveIME2 * This, + /* [in] */ BOOL fDead); + + END_INTERFACE + } IActiveIME2Vtbl; + + interface IActiveIME2 + { + CONST_VTBL struct IActiveIME2Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IActiveIME2_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define IActiveIME2_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define IActiveIME2_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define IActiveIME2_Inquire(This,dwSystemInfoFlags,pIMEInfo,szWndClass,pdwPrivate) \ + (This)->lpVtbl -> Inquire(This,dwSystemInfoFlags,pIMEInfo,szWndClass,pdwPrivate) + +#define IActiveIME2_ConversionList(This,hIMC,szSource,uFlag,uBufLen,pDest,puCopied) \ + (This)->lpVtbl -> ConversionList(This,hIMC,szSource,uFlag,uBufLen,pDest,puCopied) + +#define IActiveIME2_Configure(This,hKL,hWnd,dwMode,pRegisterWord) \ + (This)->lpVtbl -> Configure(This,hKL,hWnd,dwMode,pRegisterWord) + +#define IActiveIME2_Destroy(This,uReserved) \ + (This)->lpVtbl -> Destroy(This,uReserved) + +#define IActiveIME2_Escape(This,hIMC,uEscape,pData,plResult) \ + (This)->lpVtbl -> Escape(This,hIMC,uEscape,pData,plResult) + +#define IActiveIME2_SetActiveContext(This,hIMC,fFlag) \ + (This)->lpVtbl -> SetActiveContext(This,hIMC,fFlag) + +#define IActiveIME2_ProcessKey(This,hIMC,uVirKey,lParam,pbKeyState) \ + (This)->lpVtbl -> ProcessKey(This,hIMC,uVirKey,lParam,pbKeyState) + +#define IActiveIME2_Notify(This,hIMC,dwAction,dwIndex,dwValue) \ + (This)->lpVtbl -> Notify(This,hIMC,dwAction,dwIndex,dwValue) + +#define IActiveIME2_Select(This,hIMC,fSelect) \ + (This)->lpVtbl -> Select(This,hIMC,fSelect) + +#define IActiveIME2_SetCompositionString(This,hIMC,dwIndex,pComp,dwCompLen,pRead,dwReadLen) \ + (This)->lpVtbl -> SetCompositionString(This,hIMC,dwIndex,pComp,dwCompLen,pRead,dwReadLen) + +#define IActiveIME2_ToAsciiEx(This,uVirKey,uScanCode,pbKeyState,fuState,hIMC,pdwTransBuf,puSize) \ + (This)->lpVtbl -> ToAsciiEx(This,uVirKey,uScanCode,pbKeyState,fuState,hIMC,pdwTransBuf,puSize) + +#define IActiveIME2_RegisterWord(This,szReading,dwStyle,szString) \ + (This)->lpVtbl -> RegisterWord(This,szReading,dwStyle,szString) + +#define IActiveIME2_UnregisterWord(This,szReading,dwStyle,szString) \ + (This)->lpVtbl -> UnregisterWord(This,szReading,dwStyle,szString) + +#define IActiveIME2_GetRegisterWordStyle(This,nItem,pStyleBuf,puBufSize) \ + (This)->lpVtbl -> GetRegisterWordStyle(This,nItem,pStyleBuf,puBufSize) + +#define IActiveIME2_EnumRegisterWord(This,szReading,dwStyle,szRegister,pData,ppEnum) \ + (This)->lpVtbl -> EnumRegisterWord(This,szReading,dwStyle,szRegister,pData,ppEnum) + +#define IActiveIME2_GetCodePageA(This,uCodePage) \ + (This)->lpVtbl -> GetCodePageA(This,uCodePage) + +#define IActiveIME2_GetLangId(This,plid) \ + (This)->lpVtbl -> GetLangId(This,plid) + + +#define IActiveIME2_Sleep(This) \ + (This)->lpVtbl -> Sleep(This) + +#define IActiveIME2_Unsleep(This,fDead) \ + (This)->lpVtbl -> Unsleep(This,fDead) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +HRESULT STDMETHODCALLTYPE IActiveIME2_Sleep_Proxy( + IActiveIME2 * This); + + +void __RPC_STUB IActiveIME2_Sleep_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IActiveIME2_Unsleep_Proxy( + IActiveIME2 * This, + /* [in] */ BOOL fDead); + + +void __RPC_STUB IActiveIME2_Unsleep_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IActiveIME2_INTERFACE_DEFINED__ */ + + +EXTERN_C const CLSID CLSID_CActiveIMM; + +#ifdef __cplusplus + +class DECLSPEC_UUID("4955DD33-B159-11d0-8FCF-00AA006BCC59") +CActiveIMM; +#endif +#endif /* __ActiveIMM_LIBRARY_DEFINED__ */ + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/source/EterLib/Dynamic.h b/source/EterLib/Dynamic.h new file mode 100644 index 0000000..048ca7f --- /dev/null +++ b/source/EterLib/Dynamic.h @@ -0,0 +1,75 @@ +#pragma once + +template +class CDynamic +{ + public: + struct FClear + { + void operator() (CDynamic& rDynamic) + { + rDynamic.Clear(); + } + }; + + public: + CDynamic() + { + Initialize(); + } + + ~CDynamic() + { + Clear(); + } + + void Clear() + { + if (m_pObject) + ms_objectPool.Free(m_pObject); + + Initialize(); + } + + T* GetUsablePointer() + { + if (!m_pObject) + m_pObject = ms_objectPool.Alloc(); + + return m_pObject; + } + + bool IsNull() const + { + if (m_pObject) + return false; + return true; + } + + T* GetPointer() const + { + assert(m_pObject != NULL); + return m_pObject; + } + + T* operator->() const + { + assert(m_pObject != NULL); + return m_pObject; + } + + private: + T* m_pObject; + + private: + void Initialize() + { + m_pObject = NULL; + } + + private: + static CDynamicPool ms_objectPool; +}; + +template +CDynamicPool CDynamic::ms_objectPool; diff --git a/source/EterLib/EnvironmentMap.cpp b/source/EterLib/EnvironmentMap.cpp new file mode 100644 index 0000000..64bb0e3 --- /dev/null +++ b/source/EterLib/EnvironmentMap.cpp @@ -0,0 +1,20 @@ +// EnvironmentMap.cpp: implementation of the CEnvironmentMap class. +// +////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "EnvironmentMap.h" + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CEnvironmentMap::CEnvironmentMap() +{ + +} + +CEnvironmentMap::~CEnvironmentMap() +{ + +} diff --git a/source/EterLib/EnvironmentMap.h b/source/EterLib/EnvironmentMap.h new file mode 100644 index 0000000..c7c95c5 --- /dev/null +++ b/source/EterLib/EnvironmentMap.h @@ -0,0 +1,22 @@ +// EnvironmentMap.h: interface for the CEnvironmentMap class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_ENVIRONMENTMAP_H__FD56B8B7_5B98_4E55_B86E_A2293BE9F4F8__INCLUDED_) +#define AFX_ENVIRONMENTMAP_H__FD56B8B7_5B98_4E55_B86E_A2293BE9F4F8__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "GrpScreen.h" + +class CEnvironmentMap : public CScreen +{ +public: + CEnvironmentMap(); + virtual ~CEnvironmentMap(); + +}; + +#endif // !defined(AFX_ENVIRONMENTMAP_H__FD56B8B7_5B98_4E55_B86E_A2293BE9F4F8__INCLUDED_) diff --git a/source/EterLib/Event.h b/source/EterLib/Event.h new file mode 100644 index 0000000..1fa4d76 --- /dev/null +++ b/source/EterLib/Event.h @@ -0,0 +1,69 @@ +#pragma once + +class IEvent +{ + public: + IEvent(); + ~IEvent(); + + virtual void Run() = 0; + + void SetStartTime(float fTime) { m_fStartTime = fTime; } + float GetStartTime() { return m_fStartTime; } + + protected: + float m_fStartTime; +}; + +class CEventManager : public CSingleton +{ + public: + CEventManager(); + virtual ~CEventManager() + { + Destroy(); + } + + void Destroy() + { + while (!m_eventQueue.empty()) + { + IEvent * pEvent = m_eventQueue.top(); + m_eventQueue.pop(); + delete pEvent; + } + } + + void Register(IEvent * pEvent) + { + m_eventQueue.push(pEvent); + } + + void Update(float fCurrentTime) + { + while (!m_eventQueue.empty()) + { + IEvent * pEvent = m_eventQueue.top(); + + if (pEvent->GetStartTime() < fCurrentTime) + break; + + m_eventQueue.pop(); + float fTime = pEvent->GetStartTime(); + pEvent->Run(); + delete pEvent; + } + } + + protected: + struct EventComparisonFunc + { + bool operator () (IEvent * left, IEvent * right) const + { + return left->GetStartTime() > right->GetStartTime(); + } + }; + + typedef std::priority_queue, EventComparisonFunc> TEventQueue; + TEventQueue m_eventQueue; +}; diff --git a/source/EterLib/FileLoaderThread.cpp b/source/EterLib/FileLoaderThread.cpp new file mode 100644 index 0000000..3b5c067 --- /dev/null +++ b/source/EterLib/FileLoaderThread.cpp @@ -0,0 +1,180 @@ +#include "StdAfx.h" +#include "../EterPack/EterPackManager.h" +#include "FileLoaderThread.h" +#include "ResourceManager.h" + +CFileLoaderThread::CFileLoaderThread() : m_bShutdowned(false), m_pArg(NULL), m_hThread(NULL), m_uThreadID(0) +{ +} + +CFileLoaderThread::~CFileLoaderThread() +{ + Destroy(); +} + +int CFileLoaderThread::Create(void * arg) +{ + Arg(arg); + m_hThread = (HANDLE) _beginthreadex(NULL, 0, EntryPoint, this, 0, &m_uThreadID); + + if (!m_hThread) + return false; + + SetThreadPriority(m_hThread, THREAD_PRIORITY_NORMAL); + return true; +} + +UINT CFileLoaderThread::Run(void * arg) +{ + if (!Setup()) + return 0; + + return (Execute(arg)); +} + +/* Static */ +UINT CALLBACK CFileLoaderThread::EntryPoint(void * pThis) +{ + CFileLoaderThread * pThread = (CFileLoaderThread *) pThis; + return pThread->Run(pThread->Arg()); +} + +////////////////////////////////////////////////////////////////////////// +void CFileLoaderThread::Destroy() +{ + if (m_hSemaphore) + { + CloseHandle(m_hSemaphore); + m_hSemaphore = NULL; + } + + stl_wipe(m_pRequestDeque); + stl_wipe(m_pCompleteDeque); +} + +UINT CFileLoaderThread::Setup() +{ + m_hSemaphore = CreateSemaphore(NULL, // no security attributes + 0, // initial count + 65535, // maximum count + NULL); // unnamed semaphore + if (!m_hSemaphore) + return 0; + + return 1; +} + +void CFileLoaderThread::Shutdown() +{ + if (!m_hSemaphore) + return; + + BOOL bRet; + + m_bShutdowned = true; + + do + { + bRet = ReleaseSemaphore(m_hSemaphore, 1, NULL); + } + while (!bRet); + + WaitForSingleObject(m_hThread, 10000); // 尡 DZ⸦ 10 ٸ +} + +UINT CFileLoaderThread::Execute(void * /*pvArg*/) +{ + while (!m_bShutdowned) + { + DWORD dwWaitResult; + + dwWaitResult = WaitForSingleObject(m_hSemaphore, INFINITE); + + if (m_bShutdowned) + break; + + switch (dwWaitResult) + { + case WAIT_OBJECT_0: + { + Process(); + } + break; + + case WAIT_TIMEOUT: + TraceError("CFileLoaderThread::Execute: Timeout occured while time-out interval is INIFITE"); + break; + } + } + + Destroy(); + return 1; +} + +void CFileLoaderThread::Request(std::string & c_rstFileName) // called in main thread +{ + TData * pData = new TData; + + pData->dwSize = 0; + pData->pvBuf = NULL; + pData->stFileName = c_rstFileName; + + m_RequestMutex.Lock(); + m_pRequestDeque.push_back(pData); + m_RequestMutex.Unlock(); + + ++m_iRestSemCount; + + if (!ReleaseSemaphore(m_hSemaphore, m_iRestSemCount, NULL)) + TraceError("CFileLoaderThread::Request: ReleaseSemaphore error"); + + --m_iRestSemCount; +} + +bool CFileLoaderThread::Fetch(TData ** ppData) // called in main thread +{ + m_CompleteMutex.Lock(); + + if (m_pCompleteDeque.empty()) + { + m_CompleteMutex.Unlock(); + return false; + } + + *ppData = m_pCompleteDeque.front(); + m_pCompleteDeque.pop_front(); + + m_CompleteMutex.Unlock(); + return true; +} + +void CFileLoaderThread::Process() // called in loader thread +{ + m_RequestMutex.Lock(); + + if (m_pRequestDeque.empty()) + { + m_RequestMutex.Unlock(); + return; + } + + TData * pData = m_pRequestDeque.front(); + m_pRequestDeque.pop_front(); + + m_RequestMutex.Unlock(); + + LPCVOID pvBuf; + + if (CEterPackManager::Instance().Get(pData->File, pData->stFileName.c_str(), &pvBuf)) + { + pData->dwSize = pData->File.Size(); + pData->pvBuf = new char [pData->dwSize]; + memcpy(pData->pvBuf, pvBuf, pData->dwSize); + } + + m_CompleteMutex.Lock(); + m_pCompleteDeque.push_back(pData); + m_CompleteMutex.Unlock(); + + Sleep(g_iLoadingDelayTime); +} diff --git a/source/EterLib/FileLoaderThread.h b/source/EterLib/FileLoaderThread.h new file mode 100644 index 0000000..e8f095b --- /dev/null +++ b/source/EterLib/FileLoaderThread.h @@ -0,0 +1,63 @@ +#ifndef __INC_YMIR_ETERLIB_FILELOADERTHREAD_H__ +#define __INC_YMIR_ETERLIB_FILELOADERTHREAD_H__ + +#include +#include "Thread.h" +#include "Mutex.h" +#include "../eterBase/MappedFile.h" + +class CFileLoaderThread +{ + public: + typedef struct SData + { + std::string stFileName; + + CMappedFile File; + LPVOID pvBuf; + DWORD dwSize; + } TData; + + public: + CFileLoaderThread(); + ~CFileLoaderThread(); + + int Create(void * arg); + + public: + void Request(std::string & c_rstFileName); + bool Fetch(TData ** ppData); + void Shutdown(); + + protected: + static UINT CALLBACK EntryPoint(void * pThis); + UINT Run(void * arg); + + void * Arg() const { return m_pArg; } + void Arg(void * arg) { m_pArg = arg; } + + HANDLE m_hThread; + + private: + void * m_pArg; + unsigned m_uThreadID; + + protected: + UINT Setup(); + UINT Execute(void * pvArg); + void Destroy(); + void Process(); + + private: + std::deque m_pRequestDeque; + Mutex m_RequestMutex; + + std::deque m_pCompleteDeque; + Mutex m_CompleteMutex; + + HANDLE m_hSemaphore; + int m_iRestSemCount; + bool m_bShutdowned; +}; + +#endif \ No newline at end of file diff --git a/source/EterLib/FuncObject.h b/source/EterLib/FuncObject.h new file mode 100644 index 0000000..24bf459 --- /dev/null +++ b/source/EterLib/FuncObject.h @@ -0,0 +1,49 @@ +#pragma once + +template +class CFuncObject +{ + public: + CFuncObject() + { + Clear(); + } + + virtual ~CFuncObject() + { + } + + void Clear() + { + m_pSelfObject = NULL; + m_pFuncObject = NULL; + } + + void Set(T* pSelfObject, void (T::*pFuncObject)()) + { + m_pSelfObject = pSelfObject; + m_pFuncObject = pFuncObject; + } + + bool IsEmpty() + { + if (m_pSelfObject != NULL) + return false; + + if (m_pFuncObject != NULL) + return false; + + return true; + } + + void Run() + { + if (m_pSelfObject) + if (m_pFuncObject) + (m_pSelfObject->*m_pFuncObject)(); + } + + protected: + T * m_pSelfObject; + void (T::*m_pFuncObject) (); +}; diff --git a/source/EterLib/GrpBase.cpp b/source/EterLib/GrpBase.cpp new file mode 100644 index 0000000..b843e37 --- /dev/null +++ b/source/EterLib/GrpBase.cpp @@ -0,0 +1,512 @@ +#include "StdAfx.h" +#include "../eterBase/Utils.h" +#include "../eterBase/Timer.h" +#include "GrpBase.h" +#include "Camera.h" +#include "StateManager.h" + +void PixelPositionToD3DXVECTOR3(const D3DXVECTOR3& c_rkPPosSrc, D3DXVECTOR3* pv3Dst) +{ + pv3Dst->x=+c_rkPPosSrc.x; + pv3Dst->y=-c_rkPPosSrc.y; + pv3Dst->z=+c_rkPPosSrc.z; +} + +void D3DXVECTOR3ToPixelPosition(const D3DXVECTOR3& c_rv3Src, D3DXVECTOR3* pv3Dst) +{ + pv3Dst->x=+c_rv3Src.x; + pv3Dst->y=-c_rv3Src.y; + pv3Dst->z=+c_rv3Src.z; +} + +UINT CGraphicBase::ms_iD3DAdapterInfo=0; +UINT CGraphicBase::ms_iD3DDevInfo=0; +UINT CGraphicBase::ms_iD3DModeInfo=0; +D3D_CDisplayModeAutoDetector CGraphicBase::ms_kD3DDetector; + +HWND CGraphicBase::ms_hWnd; +HDC CGraphicBase::ms_hDC; + +LPDIRECT3D8 CGraphicBase::ms_lpd3d = NULL; +LPDIRECT3DDEVICE8 CGraphicBase::ms_lpd3dDevice = NULL; +ID3DXMatrixStack * CGraphicBase::ms_lpd3dMatStack = NULL; +D3DPRESENT_PARAMETERS CGraphicBase::ms_d3dPresentParameter; +D3DVIEWPORT8 CGraphicBase::ms_Viewport; + +HRESULT CGraphicBase::ms_hLastResult = NULL; + +int CGraphicBase::ms_iWidth; +int CGraphicBase::ms_iHeight; + +DWORD CGraphicBase::ms_faceCount = 0; + +D3DCAPS8 CGraphicBase::ms_d3dCaps; + +DWORD CGraphicBase::ms_dwD3DBehavior = 0; + +DWORD CGraphicBase::ms_ptVS = 0; +DWORD CGraphicBase::ms_pntVS = 0; +DWORD CGraphicBase::ms_pnt2VS = 0; + +D3DXMATRIX CGraphicBase::ms_matIdentity; + +D3DXMATRIX CGraphicBase::ms_matView; +D3DXMATRIX CGraphicBase::ms_matProj; +D3DXMATRIX CGraphicBase::ms_matInverseView; +D3DXMATRIX CGraphicBase::ms_matInverseViewYAxis; + +D3DXMATRIX CGraphicBase::ms_matWorld; +D3DXMATRIX CGraphicBase::ms_matWorldView; + +D3DXMATRIX CGraphicBase::ms_matScreen0; +D3DXMATRIX CGraphicBase::ms_matScreen1; +D3DXMATRIX CGraphicBase::ms_matScreen2; + +D3DXVECTOR3 CGraphicBase::ms_vtPickRayOrig; +D3DXVECTOR3 CGraphicBase::ms_vtPickRayDir; + +float CGraphicBase::ms_fFieldOfView; +float CGraphicBase::ms_fNearY; +float CGraphicBase::ms_fFarY; +float CGraphicBase::ms_fAspect; + +DWORD CGraphicBase::ms_dwWavingEndTime; +int CGraphicBase::ms_iWavingPower; +DWORD CGraphicBase::ms_dwFlashingEndTime; +D3DXCOLOR CGraphicBase::ms_FlashingColor; + +// Terrain picking Ray... CCamera ̿ϴ .. Ray ʿ... +CRay CGraphicBase::ms_Ray; +bool CGraphicBase::ms_bSupportDXT = true; +bool CGraphicBase::ms_isLowTextureMemory = false; +bool CGraphicBase::ms_isHighTextureMemory = false; + +// 2004.11.18.myevan.DynamicVertexBuffer ü +/* +std::vector CGraphicBase::ms_lineIdxVector; +std::vector CGraphicBase::ms_lineTriIdxVector; +std::vector CGraphicBase::ms_lineRectIdxVector; +std::vector CGraphicBase::ms_lineCubeIdxVector; + +std::vector CGraphicBase::ms_fillTriIdxVector; +std::vector CGraphicBase::ms_fillRectIdxVector; +std::vector CGraphicBase::ms_fillCubeIdxVector; +*/ + +LPD3DXMESH CGraphicBase::ms_lpSphereMesh = NULL; +LPD3DXMESH CGraphicBase::ms_lpCylinderMesh = NULL; + +LPDIRECT3DVERTEXBUFFER8 CGraphicBase::ms_alpd3dPDTVB[PDT_VERTEXBUFFER_NUM]; + +LPDIRECT3DINDEXBUFFER8 CGraphicBase::ms_alpd3dDefIB[DEFAULT_IB_NUM]; + +bool CGraphicBase::IsLowTextureMemory() +{ + return ms_isLowTextureMemory; +} + +bool CGraphicBase::IsHighTextureMemory() +{ + return ms_isHighTextureMemory; +} + +bool CGraphicBase::IsFastTNL() +{ + if (ms_dwD3DBehavior & D3DCREATE_HARDWARE_VERTEXPROCESSING || + ms_dwD3DBehavior & D3DCREATE_MIXED_VERTEXPROCESSING) + { + if (ms_d3dCaps.VertexShaderVersion>D3DVS_VERSION(1,0)) + return true; + } + return false; +} + +bool CGraphicBase::IsTLVertexClipping() +{ + if (ms_d3dCaps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS) + return true; + + return false; +} + +void CGraphicBase::GetBackBufferSize(UINT* puWidth, UINT* puHeight) +{ + *puWidth=ms_d3dPresentParameter.BackBufferWidth; + *puHeight=ms_d3dPresentParameter.BackBufferHeight; +} + +void CGraphicBase::SetDefaultIndexBuffer(UINT eDefIB) +{ + if (eDefIB>=DEFAULT_IB_NUM) + return; + + STATEMANAGER.SetIndices(ms_alpd3dDefIB[eDefIB], 0); +} + +bool CGraphicBase::SetPDTStream(SPDTVertex* pVertices, UINT uVtxCount) +{ + return SetPDTStream((SPDTVertexRaw*)pVertices, uVtxCount); +} + +bool CGraphicBase::SetPDTStream(SPDTVertexRaw* pSrcVertices, UINT uVtxCount) +{ + if (!uVtxCount) + return false; + + static DWORD s_dwVBPos=0; + + if (s_dwVBPos>=PDT_VERTEXBUFFER_NUM) + s_dwVBPos=0; + + IDirect3DVertexBuffer8* plpd3dFillRectVB=ms_alpd3dPDTVB[s_dwVBPos]; + ++s_dwVBPos; + + assert(PDT_VERTEX_NUM>=uVtxCount); + if (uVtxCount >= PDT_VERTEX_NUM) + return false; + + TPDTVertex* pDstVertices; + if (FAILED( + plpd3dFillRectVB->Lock(0, sizeof(TPDTVertex)*uVtxCount, (BYTE**)&pDstVertices, D3DLOCK_DISCARD) + )) + { + STATEMANAGER.SetStreamSource(0, NULL, 0); + return false; + } + + + memcpy(pDstVertices, pSrcVertices, sizeof(TPDTVertex)*uVtxCount); + + plpd3dFillRectVB->Unlock(); + + STATEMANAGER.SetStreamSource(0, plpd3dFillRectVB, sizeof(TPDTVertex)); + + return true; +} + +DWORD CGraphicBase::GetAvailableTextureMemory() +{ + assert(ms_lpd3dDevice!=NULL && "CGraphicBase::GetAvailableTextureMemory - D3DDevice is EMPTY"); + + static DWORD s_dwNextUpdateTime=0; + static DWORD s_dwTexMemSize=0;//ms_lpd3dDevice->GetAvailableTextureMem(); + + DWORD dwCurTime=ELTimer_GetMSec(); + if (s_dwNextUpdateTimeGetAvailableTextureMem(); + } + + return s_dwTexMemSize; +} + +const D3DXMATRIX& CGraphicBase::GetViewMatrix() +{ + return ms_matView; +} + +const D3DXMATRIX & CGraphicBase::GetIdentityMatrix() +{ + return ms_matIdentity; +} + +void CGraphicBase::SetEyeCamera(float xEye, float yEye, float zEye, + float xCenter, float yCenter, float zCenter, + float xUp, float yUp, float zUp) +{ + D3DXVECTOR3 vectorEye(xEye, yEye, zEye); + D3DXVECTOR3 vectorCenter(xCenter, yCenter, zCenter); + D3DXVECTOR3 vectorUp(xUp, yUp, zUp); + +// CCameraManager::Instance().SetCurrentCamera(CCameraManager::DEFAULT_PERSPECTIVE_CAMERA); + CCameraManager::Instance().GetCurrentCamera()->SetViewParams(vectorEye, vectorCenter, vectorUp); + UpdateViewMatrix(); +} + +void CGraphicBase::SetSimpleCamera(float x, float y, float z, float pitch, float roll) +{ + CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera(); + D3DXVECTOR3 vectorEye(x, y, z); + + pCamera->SetViewParams(D3DXVECTOR3(0.0f, y, 0.0f), D3DXVECTOR3(0.0f, 0.0f, 0.0f), D3DXVECTOR3(0.0f, 0.0f, 1.0f)); + pCamera->RotateEyeAroundTarget(pitch, roll); + pCamera->Move(vectorEye); + + UpdateViewMatrix(); + + // This is levites's virtual(?) code which you should not trust. + ms_lpd3dDevice->GetTransform(D3DTS_WORLD, &ms_matWorld); + D3DXMatrixMultiply(&ms_matWorldView, &ms_matWorld, &ms_matView); +} + +void CGraphicBase::SetAroundCamera(float distance, float pitch, float roll, float lookAtZ) +{ + CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera(); + pCamera->SetViewParams(D3DXVECTOR3(0.0f, -distance, 0.0f), D3DXVECTOR3(0.0f, 0.0f, 0.0f), D3DXVECTOR3(0.0f, 0.0f, 1.0f)); + pCamera->RotateEyeAroundTarget(pitch, roll); + D3DXVECTOR3 v3Target = pCamera->GetTarget(); + v3Target.z = lookAtZ; + pCamera->SetTarget(v3Target); +// pCamera->Move(v3Target); + + UpdateViewMatrix(); + + // This is levites's virtual(?) code which you should not trust. + ms_lpd3dDevice->GetTransform(D3DTS_WORLD, &ms_matWorld); + D3DXMatrixMultiply(&ms_matWorldView, &ms_matWorld, &ms_matView); +} + +void CGraphicBase::SetPositionCamera(float fx, float fy, float fz, float distance, float pitch, float roll) +{ + // I wanna downward this code to the game control level. - [levites] + if (ms_dwWavingEndTime > CTimer::Instance().GetCurrentMillisecond()) + { + if (ms_iWavingPower>0) + { + fx += float(rand() % ms_iWavingPower) / 10.0f; + fy += float(rand() % ms_iWavingPower) / 10.0f; + fz += float(rand() % ms_iWavingPower) / 10.0f; + } + } + + CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera(); + if (!pCamera) + return; + + pCamera->SetViewParams(D3DXVECTOR3(0.0f, -distance, 0.0f), D3DXVECTOR3(0.0f, 0.0f, 0.0f), D3DXVECTOR3(0.0f, 0.0f, 1.0f)); + pitch = fMIN(80.0f, fMAX(-80.0f, pitch) ); +// Tracef("SetPosition Camera : %f, %f\n", pitch, roll); + pCamera->RotateEyeAroundTarget(pitch, roll); + pCamera->Move(D3DXVECTOR3(fx, fy, fz)); + + UpdateViewMatrix(); + + // This is levites's virtual(?) code which you should not trust. + STATEMANAGER.GetTransform(D3DTS_WORLD, &ms_matWorld); + D3DXMatrixMultiply(&ms_matWorldView, &ms_matWorld, &ms_matView); +} + +void CGraphicBase::SetOrtho2D(float hres, float vres, float zres) +{ + //CCameraManager::Instance().SetCurrentCamera(CCameraManager::DEFAULT_ORTHO_CAMERA); + D3DXMatrixOrthoOffCenterRH(&ms_matProj, 0, hres, vres, 0, 0, zres); + //UpdatePipeLineMatrix(); + UpdateProjMatrix(); +} + +void CGraphicBase::SetOrtho3D(float hres, float vres, float zmin, float zmax) +{ + //CCameraManager::Instance().SetCurrentCamera(CCameraManager::DEFAULT_PERSPECTIVE_CAMERA); + D3DXMatrixOrthoRH(&ms_matProj, hres, vres, zmin, zmax); + //UpdatePipeLineMatrix(); + UpdateProjMatrix(); +} + +void CGraphicBase::SetPerspective(float fov, float aspect, float nearz, float farz) +{ + ms_fFieldOfView = fov; + + + //if (ms_d3dPresentParameter.BackBufferWidth>0 && ms_d3dPresentParameter.BackBufferHeight>0) + // ms_fAspect = float(ms_d3dPresentParameter.BackBufferWidth)/float(ms_d3dPresentParameter.BackBufferHeight); + //else + ms_fAspect = aspect; + + ms_fNearY = nearz; + ms_fFarY = farz; + + //CCameraManager::Instance().SetCurrentCamera(CCameraManager::DEFAULT_PERSPECTIVE_CAMERA); + D3DXMatrixPerspectiveFovRH(&ms_matProj, D3DXToRadian(fov), ms_fAspect, nearz, farz); + //UpdatePipeLineMatrix(); + UpdateProjMatrix(); +} + +void CGraphicBase::UpdateProjMatrix() +{ + STATEMANAGER.SetTransform(D3DTS_PROJECTION, &ms_matProj); +} + +void CGraphicBase::UpdateViewMatrix() +{ + CCamera* pkCamera=CCameraManager::Instance().GetCurrentCamera(); + if (!pkCamera) + return; + + ms_matView = pkCamera->GetViewMatrix(); + STATEMANAGER.SetTransform(D3DTS_VIEW, &ms_matView); + + D3DXMatrixInverse(&ms_matInverseView, NULL, &ms_matView); + ms_matInverseViewYAxis._11 = ms_matInverseView._11; + ms_matInverseViewYAxis._12 = ms_matInverseView._12; + ms_matInverseViewYAxis._21 = ms_matInverseView._21; + ms_matInverseViewYAxis._22 = ms_matInverseView._22; +} + +void CGraphicBase::UpdatePipeLineMatrix() +{ + UpdateProjMatrix(); + UpdateViewMatrix(); +} + +void CGraphicBase::SetViewport(DWORD dwX, DWORD dwY, DWORD dwWidth, DWORD dwHeight, float fMinZ, float fMaxZ) +{ + ms_Viewport.X = dwX; + ms_Viewport.Y = dwY; + ms_Viewport.Width = dwWidth; + ms_Viewport.Height = dwHeight; + ms_Viewport.MinZ = fMinZ; + ms_Viewport.MaxZ = fMaxZ; +} + +void CGraphicBase::GetTargetPosition(float * px, float * py, float * pz) +{ + *px = CCameraManager::Instance().GetCurrentCamera()->GetTarget().x; + *py = CCameraManager::Instance().GetCurrentCamera()->GetTarget().y; + *pz = CCameraManager::Instance().GetCurrentCamera()->GetTarget().z; +} + +void CGraphicBase::GetCameraPosition(float * px, float * py, float * pz) +{ + *px = CCameraManager::Instance().GetCurrentCamera()->GetEye().x; + *py = CCameraManager::Instance().GetCurrentCamera()->GetEye().y; + *pz = CCameraManager::Instance().GetCurrentCamera()->GetEye().z; +} + +void CGraphicBase::GetMatrix(D3DXMATRIX* pRetMatrix) const +{ + assert(ms_lpd3dMatStack != NULL); + *pRetMatrix = *ms_lpd3dMatStack->GetTop(); +} + +const D3DXMATRIX* CGraphicBase::GetMatrixPointer() const +{ + assert(ms_lpd3dMatStack!=NULL); + return ms_lpd3dMatStack->GetTop(); +} + +void CGraphicBase::GetSphereMatrix(D3DXMATRIX * pMatrix, float fValue) +{ + D3DXMatrixIdentity(pMatrix); + pMatrix->_11 = fValue * ms_matWorldView._11; + pMatrix->_21 = fValue * ms_matWorldView._21; + pMatrix->_31 = fValue * ms_matWorldView._31; + pMatrix->_41 = fValue; + pMatrix->_12 = -fValue * ms_matWorldView._12; + pMatrix->_22 = -fValue * ms_matWorldView._22; + pMatrix->_32 = -fValue * ms_matWorldView._32; + pMatrix->_42 = -fValue; +} + +float CGraphicBase::GetFOV() +{ + return ms_fFieldOfView; +} + +void CGraphicBase::PushMatrix() +{ + ms_lpd3dMatStack->Push(); +} + +void CGraphicBase::Scale(float x, float y, float z) +{ + ms_lpd3dMatStack->Scale(x, y, z); +} + +void CGraphicBase::Rotate(float degree, float x, float y, float z) +{ + D3DXVECTOR3 vec(x, y, z); + ms_lpd3dMatStack->RotateAxis(&vec, D3DXToRadian(degree)); +} + +void CGraphicBase::RotateLocal(float degree, float x, float y, float z) +{ + D3DXVECTOR3 vec(x, y, z); + ms_lpd3dMatStack->RotateAxisLocal(&vec, D3DXToRadian(degree)); +} + +void CGraphicBase::MultMatrix( const D3DXMATRIX* pMat) +{ + ms_lpd3dMatStack->MultMatrix(pMat); +} + +void CGraphicBase::MultMatrixLocal( const D3DXMATRIX* pMat) +{ + ms_lpd3dMatStack->MultMatrixLocal(pMat); +} + +void CGraphicBase::RotateYawPitchRollLocal(float fYaw, float fPitch, float fRoll) +{ + ms_lpd3dMatStack->RotateYawPitchRollLocal(D3DXToRadian(fYaw), D3DXToRadian(fPitch), D3DXToRadian(fRoll)); +} + +void CGraphicBase::Translate(float x, float y, float z) +{ + ms_lpd3dMatStack->Translate(x, y, z); +} + +void CGraphicBase::LoadMatrix(const D3DXMATRIX& c_rSrcMatrix) +{ + ms_lpd3dMatStack->LoadMatrix(&c_rSrcMatrix); +} + +void CGraphicBase::PopMatrix() +{ + ms_lpd3dMatStack->Pop(); +} + +DWORD CGraphicBase::GetColor(float r, float g, float b, float a) +{ + BYTE argb[4] = + { + (BYTE) (255.0f * b), + (BYTE) (255.0f * g), + (BYTE) (255.0f * r), + (BYTE) (255.0f * a) + }; + + return *((DWORD *) argb); +} + +void CGraphicBase::InitScreenEffect() +{ + ms_dwWavingEndTime = 0; + ms_dwFlashingEndTime = 0; + ms_iWavingPower = 0; + ms_FlashingColor = D3DXCOLOR(0.0f, 0.0f, 0.0f, 0.0f); +} + +void CGraphicBase::SetScreenEffectWaving(float fDuringTime, int iPower) +{ + ms_dwWavingEndTime = CTimer::Instance().GetCurrentMillisecond() + long(fDuringTime * 1000.0f); + ms_iWavingPower = iPower; +} + +void CGraphicBase::SetScreenEffectFlashing(float fDuringTime, const D3DXCOLOR & c_rColor) +{ + ms_dwFlashingEndTime = CTimer::Instance().GetCurrentMillisecond() + long(fDuringTime * 1000.0f); + ms_FlashingColor = c_rColor; +} + +DWORD CGraphicBase::GetFaceCount() +{ + return ms_faceCount; +} + +void CGraphicBase::ResetFaceCount() +{ + ms_faceCount = 0; +} + +HRESULT CGraphicBase::GetLastResult() +{ + return ms_hLastResult; +} + +CGraphicBase::CGraphicBase() +{ +} + +CGraphicBase::~CGraphicBase() +{ +} diff --git a/source/EterLib/GrpBase.h b/source/EterLib/GrpBase.h new file mode 100644 index 0000000..543ca5c --- /dev/null +++ b/source/EterLib/GrpBase.h @@ -0,0 +1,312 @@ +#pragma once + +#include "GrpDetector.h" +#include "Ray.h" +#include + +void PixelPositionToD3DXVECTOR3(const D3DXVECTOR3& c_rkPPosSrc, D3DXVECTOR3* pv3Dst); +void D3DXVECTOR3ToPixelPosition(const D3DXVECTOR3& c_rv3Src, D3DXVECTOR3* pv3Dst); + +class CGraphicTexture; + +typedef WORD TIndex; + +typedef struct SFace +{ + TIndex indices[3]; +} TFace; + +typedef D3DXVECTOR3 TPosition; + +typedef D3DXVECTOR3 TNormal; + +typedef D3DXVECTOR2 TTextureCoordinate; + +typedef DWORD TDiffuse; +typedef DWORD TAmbient; +typedef DWORD TSpecular; + +typedef union UDepth +{ + float f; + long l; + DWORD dw; +} TDepth; + +typedef struct SVertex +{ + float x, y, z; + DWORD color; + float u, v; +} TVertex; + +struct STVertex +{ + float x, y, z, rhw; +}; + +struct SPVertex +{ + float x, y, z; +}; + +typedef struct SPDVertex +{ + float x, y, z; + DWORD color; +} TPDVertex; + +struct SPDTVertexRaw +{ + float px, py, pz; + DWORD diffuse; + float u, v; +}; + +typedef struct SPTVertex +{ + TPosition position; + TTextureCoordinate texCoord; +} TPTVertex; + +typedef struct SPDTVertex +{ + TPosition position; + TDiffuse diffuse; + TTextureCoordinate texCoord; +} TPDTVertex; + +typedef struct SPNTVertex +{ + TPosition position; + TNormal normal; + TTextureCoordinate texCoord; +} TPNTVertex; + +typedef struct SPNT2Vertex +{ + TPosition position; + TNormal normal; + TTextureCoordinate texCoord; + TTextureCoordinate texCoord2; +} TPNT2Vertex; + +typedef struct SPDT2Vertex +{ + TPosition position; + DWORD diffuse; + TTextureCoordinate texCoord; + TTextureCoordinate texCoord2; +} TPDT2Vertex; + +typedef struct SNameInfo +{ + DWORD name; + TDepth depth; +} TNameInfo; + +typedef struct SBoundBox +{ + float sx, sy, sz; + float ex, ey, ez; + int meshIndex; + int boneIndex; +} TBoundBox; + +const WORD c_FillRectIndices[6] = { 0, 2, 1, 2, 3, 1 }; + +/* +enum EIndexCount +{ + LINE_INDEX_COUNT = 2, + TRIANGLE_INDEX_COUNT = 2*3, + RECTANGLE_INDEX_COUNT = 2*4, + CUBE_INDEX_COUNT = 2*4*3, + FILLED_TRIANGLE_INDEX_COUNT = 3, + FILLED_RECTANGLE_INDEX_COUNT = 3*2, + FILLED_CUBE_INDEX_COUNT = 3*2*6, +}; +*/ + +class CGraphicBase +{ + public: + static DWORD GetAvailableTextureMemory(); + static const D3DXMATRIX& GetViewMatrix(); + static const D3DXMATRIX & GetIdentityMatrix(); + + enum + { + DEFAULT_IB_LINE, + DEFAULT_IB_LINE_TRI, + DEFAULT_IB_LINE_RECT, + DEFAULT_IB_LINE_CUBE, + DEFAULT_IB_FILL_TRI, + DEFAULT_IB_FILL_RECT, + DEFAULT_IB_FILL_CUBE, + DEFAULT_IB_NUM, + }; + + public: + CGraphicBase(); + virtual ~CGraphicBase(); + + void SetSimpleCamera(float x, float y, float z, float pitch, float roll); + void SetEyeCamera(float xEye, float yEye, float zEye, float xCenter, float yCenter, float zCenter, float xUp, float yUp, float zUp); + void SetAroundCamera(float distance, float pitch, float roll, float lookAtZ = 0.0f); + void SetPositionCamera(float fx, float fy, float fz, float fDistance, float fPitch, float fRotation); + void MoveCamera(float fdeltax, float fdeltay, float fdeltaz); + + void GetTargetPosition(float * px, float * py, float * pz); + void GetCameraPosition(float * px, float * py, float * pz); + void SetOrtho2D(float hres, float vres, float zres); + void SetOrtho3D(float hres, float vres, float zmin, float zmax); + void SetPerspective(float fov, float aspect, float nearz, float farz); + float GetFOV(); + void GetClipPlane(float * fNearY, float * fFarY) + { + *fNearY = ms_fNearY; + *fFarY = ms_fFarY; + } + + //////////////////////////////////////////////////////////////////////// + void PushMatrix(); + + void MultMatrix( const D3DXMATRIX* pMat ); + void MultMatrixLocal( const D3DXMATRIX* pMat ); + + void Translate(float x, float y, float z); + void Rotate(float degree, float x, float y, float z); + void RotateLocal(float degree, float x, float y, float z); + void RotateYawPitchRollLocal(float fYaw, float fPitch, float fRoll); + void Scale(float x, float y, float z); + void PopMatrix(); + void LoadMatrix(const D3DXMATRIX & c_rSrcMatrix); + void GetMatrix(D3DXMATRIX * pRetMatrix) const; + const D3DXMATRIX * GetMatrixPointer() const; + + // Special Routine + void GetSphereMatrix(D3DXMATRIX * pMatrix, float fValue = 0.1f); + + //////////////////////////////////////////////////////////////////////// + void InitScreenEffect(); + void SetScreenEffectWaving(float fDuringTime, int iPower); + void SetScreenEffectFlashing(float fDuringTime, const D3DXCOLOR & c_rColor); + + //////////////////////////////////////////////////////////////////////// + DWORD GetColor(float r, float g, float b, float a = 1.0f); + + DWORD GetFaceCount(); + void ResetFaceCount(); + HRESULT GetLastResult(); + + void UpdateProjMatrix(); + void UpdateViewMatrix(); + + void SetViewport(DWORD dwX, DWORD dwY, DWORD dwWidth, DWORD dwHeight, float fMinZ, float fMaxZ); + static void GetBackBufferSize(UINT* puWidth, UINT* puHeight); + static bool IsTLVertexClipping(); + static bool IsFastTNL(); + static bool IsLowTextureMemory(); + static bool IsHighTextureMemory(); + + static void SetDefaultIndexBuffer(UINT eDefIB); + static bool SetPDTStream(SPDTVertexRaw* pVertices, UINT uVtxCount); + static bool SetPDTStream(SPDTVertex* pVertices, UINT uVtxCount); + + protected: + static D3DXMATRIX ms_matIdentity; + + static D3DXMATRIX ms_matView; + static D3DXMATRIX ms_matProj; + static D3DXMATRIX ms_matInverseView; + static D3DXMATRIX ms_matInverseViewYAxis; + + static D3DXMATRIX ms_matWorld; + static D3DXMATRIX ms_matWorldView; + + protected: + //void UpdatePrePipeLineMatrix(); + void UpdatePipeLineMatrix(); + + protected: + // D3DX Mesh (÷ ǥȰ ) + static LPD3DXMESH ms_lpSphereMesh; + static LPD3DXMESH ms_lpCylinderMesh; + + protected: + static HRESULT ms_hLastResult; + + static int ms_iWidth; + static int ms_iHeight; + + static UINT ms_iD3DAdapterInfo; + static UINT ms_iD3DDevInfo; + static UINT ms_iD3DModeInfo; + static D3D_CDisplayModeAutoDetector ms_kD3DDetector; + + static HWND ms_hWnd; + static HDC ms_hDC; + static LPDIRECT3D8 ms_lpd3d; + static LPDIRECT3DDEVICE8 ms_lpd3dDevice; + static ID3DXMatrixStack* ms_lpd3dMatStack; + static D3DVIEWPORT8 ms_Viewport; + + static DWORD ms_faceCount; + static D3DCAPS8 ms_d3dCaps; + static D3DPRESENT_PARAMETERS ms_d3dPresentParameter; + + static DWORD ms_dwD3DBehavior; + static DWORD ms_ptVS; + static DWORD ms_pntVS; + static DWORD ms_pnt2VS; + + static D3DXMATRIX ms_matScreen0; + static D3DXMATRIX ms_matScreen1; + static D3DXMATRIX ms_matScreen2; + //static D3DXMATRIX ms_matPrePipeLine; + + static D3DXVECTOR3 ms_vtPickRayOrig; + static D3DXVECTOR3 ms_vtPickRayDir; + + static float ms_fFieldOfView; + static float ms_fAspect; + static float ms_fNearY; + static float ms_fFarY; + + // 2004.11.18.myevan.DynamicVertexBuffer ü + /* + static std::vector ms_lineIdxVector; + static std::vector ms_lineTriIdxVector; + static std::vector ms_lineRectIdxVector; + static std::vector ms_lineCubeIdxVector; + + static std::vector ms_fillTriIdxVector; + static std::vector ms_fillRectIdxVector; + static std::vector ms_fillCubeIdxVector; + */ + + // Screen Effect - Waving, Flashing and so on.. + static DWORD ms_dwWavingEndTime; + static int ms_iWavingPower; + static DWORD ms_dwFlashingEndTime; + static D3DXCOLOR ms_FlashingColor; + + // Terrain picking Ray... CCamera ̿ϴ .. Ray ʿ... + static CRay ms_Ray; + + // + static bool ms_bSupportDXT; + static bool ms_isLowTextureMemory; + static bool ms_isHighTextureMemory; + + enum + { + PDT_VERTEX_NUM = 16, + PDT_VERTEXBUFFER_NUM = 100, + }; + + + static LPDIRECT3DVERTEXBUFFER8 ms_alpd3dPDTVB[PDT_VERTEXBUFFER_NUM]; + static LPDIRECT3DINDEXBUFFER8 ms_alpd3dDefIB[DEFAULT_IB_NUM]; +}; diff --git a/source/EterLib/GrpCollisionObject.cpp b/source/EterLib/GrpCollisionObject.cpp new file mode 100644 index 0000000..57ae637 --- /dev/null +++ b/source/EterLib/GrpCollisionObject.cpp @@ -0,0 +1,240 @@ +#include "StdAfx.h" +#include "GrpCollisionObject.h" + +bool CGraphicCollisionObject::IntersectBoundBox(const D3DXMATRIX* c_pmatWorld, const TBoundBox& c_rboundBox, float* pu, float* pv, float* pt) +{ + return IntersectCube(c_pmatWorld, c_rboundBox.sx, c_rboundBox.sy, c_rboundBox.sz, c_rboundBox.ex, c_rboundBox.ey, c_rboundBox.ez, ms_vtPickRayOrig, ms_vtPickRayDir, pu, pv, pt); +} + +bool CGraphicCollisionObject::IntersectCube(const D3DXMATRIX* c_pmatWorld, float sx, float sy, float sz, float ex, float ey, float ez, + D3DXVECTOR3 & RayOriginal, D3DXVECTOR3 & RayDirection, float* pu, float* pv, float* pt) +{ + TPosition posVertices[8]; + + posVertices[0] = TPosition(sx, sy, sz); + posVertices[1] = TPosition(ex, sy, sz); + posVertices[2] = TPosition(sx, ey, sz); + posVertices[3] = TPosition(ex, ey, sz); + posVertices[4] = TPosition(sx, sy, ez); + posVertices[5] = TPosition(ex, sy, ez); + posVertices[6] = TPosition(sx, ey, ez); + posVertices[7] = TPosition(ex, ey, ez); + + static const WORD c_awFillCubeIndices[36] = { + 0, 1, 2, 1, 3, 2, + 2, 0, 6, 0, 4, 6, + 0, 1, 4, 1, 5, 4, + 1, 3, 5, 3, 7, 5, + 3, 2, 7, 2, 6, 7, + 4, 5, 6, 5, 7, 6, + }; + + return IntersectIndexedMesh( + c_pmatWorld, + posVertices, + sizeof(TPosition), + 8, + c_awFillCubeIndices, + 36, + RayOriginal, + RayDirection, + pu, + pv, + pt + ); +} + +const int c_iLimitVertexCount = 1024; + +bool CGraphicCollisionObject::IntersectIndexedMesh(const D3DXMATRIX* c_pmatWorld, const void* vertices, int step, int vtxCount, const void* indices, int idxCount, + D3DXVECTOR3 & RayOriginal, D3DXVECTOR3 & RayDirection, float* pu, float* pv, float* pt) +{ + static D3DXVECTOR3 s_v3PositionArray[c_iLimitVertexCount]; + static DWORD s_dwPositionCount; + + if (vtxCount > c_iLimitVertexCount) + { + Tracef("The vertex count of mesh which is worked collision detection is too much : %d / %d", vtxCount, c_iLimitVertexCount); + return false; + } + + s_dwPositionCount = 0; + + char* pcurVtx = (char*)vertices; + + while (vtxCount--) + { + float* pos = (float*)pcurVtx; + + D3DXVec3TransformCoord(&s_v3PositionArray[s_dwPositionCount++], (D3DXVECTOR3*)pos, c_pmatWorld); + + pcurVtx += step; + } + + WORD* pcurIdx = (WORD*)indices; + + int triCount = idxCount / 3; + while (triCount--) + { + if (IntersectTriangle(RayOriginal, RayDirection, + s_v3PositionArray[pcurIdx[0]], + s_v3PositionArray[pcurIdx[1]], + s_v3PositionArray[pcurIdx[2]], + pu, pv, pt)) + { + return true; + } + + pcurIdx += 3; + } + + return false; +} + +bool CGraphicCollisionObject::IntersectMesh(const D3DXMATRIX * c_pmatWorld, const void * vertices, DWORD dwStep, DWORD dwvtxCount, D3DXVECTOR3 & RayOriginal, D3DXVECTOR3 & RayDirection, float* pu, float* pv, float* pt) +{ + char * pcurVtx = (char *) vertices; + + D3DXVECTOR3 v3Vertex[3]; + + for (DWORD i = 0; i < dwvtxCount; i += 3) + { + D3DXVec3TransformCoord(&v3Vertex[0], (D3DXVECTOR3*)pcurVtx, c_pmatWorld); + pcurVtx += dwStep; + + D3DXVec3TransformCoord(&v3Vertex[1], (D3DXVECTOR3*)pcurVtx, c_pmatWorld); + pcurVtx += dwStep; + + D3DXVec3TransformCoord(&v3Vertex[2], (D3DXVECTOR3*)pcurVtx, c_pmatWorld); + pcurVtx += dwStep; + + if (IntersectTriangle(RayOriginal, RayDirection, + v3Vertex[0], v3Vertex[1], v3Vertex[2], + pu, pv, pt)) + { + return true; + } + } + + return false; +} + +bool CGraphicCollisionObject::IntersectTriangle(const D3DXVECTOR3& c_orig, + const D3DXVECTOR3& c_dir, + const D3DXVECTOR3& c_v0, + const D3DXVECTOR3& c_v1, + const D3DXVECTOR3& c_v2, + float * pu, + float * pv, + float * pt) +{ + D3DXVECTOR3 edge1 = c_v1 - c_v0; + D3DXVECTOR3 edge2 = c_v2 - c_v0; + D3DXVECTOR3 pvec; + D3DXVec3Cross(&pvec, &c_dir, &edge2); + + FLOAT det = D3DXVec3Dot(&edge1, &pvec); + D3DXVECTOR3 tvec; + + if (det > 0) + { + tvec = c_orig - c_v0; + } + else + { + tvec = c_v0 - c_orig; + det = -det; + } + + if (det < 0.0001f) + return false; + + float u, v, t; + u = D3DXVec3Dot(&tvec, &pvec); + if (u < 0.0f || u > det) + return false; + + D3DXVECTOR3 qvec; + D3DXVec3Cross(&qvec, &tvec, &edge1); + + v = D3DXVec3Dot(&c_dir, &qvec); + if (v < 0.0f || u + v > det) + return false; + + t = D3DXVec3Dot(&edge2, &qvec); + FLOAT fInvDet = 1.0f / det; + t *= fInvDet; + u *= fInvDet; + v *= fInvDet; + + D3DXVECTOR3 spot = edge1 * u + edge2 * v; + spot += c_v0; + + *pu = spot.x; + *pv = spot.y; + *pt = t; + + return true; +} + +bool CGraphicCollisionObject::IntersectSphere(const D3DXVECTOR3 & c_rv3Position, float fRadius, const D3DXVECTOR3 & c_rv3RayOriginal, const D3DXVECTOR3 & c_rv3RayDirection) +{ + D3DXVECTOR3 v3RayOriginal = c_rv3RayOriginal - c_rv3Position; + + float a = D3DXVec3Dot(&c_rv3RayDirection, &c_rv3RayDirection); + float b = 2 * D3DXVec3Dot(&v3RayOriginal, &c_rv3RayDirection); + float c = D3DXVec3Dot(&v3RayOriginal, &v3RayOriginal) - fRadius * fRadius; + + float D = b * b - 4 * a * c; + + if (D >= 0) + return true; + + return false; +} + +bool CGraphicCollisionObject::IntersectCylinder(const D3DXVECTOR3 & c_rv3Position, float fRadius, float fHeight, const D3DXVECTOR3 & c_rv3RayOriginal, const D3DXVECTOR3 & c_rv3RayDirection) +{ + D3DXVECTOR3 v3RayOriginal = c_rv3RayOriginal - c_rv3Position; + + float a = c_rv3RayDirection.x * c_rv3RayDirection.x + c_rv3RayDirection.y * c_rv3RayDirection.y; + float b = 2 * (v3RayOriginal.x * c_rv3RayDirection.x + v3RayOriginal.y * c_rv3RayDirection.y); + float c = v3RayOriginal.x * v3RayOriginal.x + v3RayOriginal.y * v3RayOriginal.y - fRadius*fRadius; + + float D = b * b - 4 * a * c; + if (D > 0) + if (0.0f != a) + { + float tPlus = (-b + sqrtf(D)) / (2 * a); + float tMinus = (-b - sqrtf(D)) / (2 * a); + float fzPlus = v3RayOriginal.z + tPlus * c_rv3RayDirection.z; + float fzMinus = v3RayOriginal.z + tMinus * c_rv3RayDirection.z; + + if (fzPlus > 0.0f && fzPlus <= fHeight) + return true; + if (fzMinus > 0.0f && fzMinus <= fHeight) + return true; + if (fzMinus * fzPlus < 0.0f) + return true; + } + + return false; +} + +bool CGraphicCollisionObject::IntersectSphere(const D3DXVECTOR3 & c_rv3Position, float fRadius) +{ + return CGraphicCollisionObject::IntersectSphere(c_rv3Position, fRadius, ms_vtPickRayOrig, ms_vtPickRayDir); +} + +bool CGraphicCollisionObject::IntersectCylinder(const D3DXVECTOR3 & c_rv3Position, float fRadius, float fHeight) +{ + return CGraphicCollisionObject::IntersectCylinder(c_rv3Position, fRadius, fHeight, ms_vtPickRayOrig, ms_vtPickRayDir); +} + +CGraphicCollisionObject::CGraphicCollisionObject() +{ +} + +CGraphicCollisionObject::~CGraphicCollisionObject() +{ +} \ No newline at end of file diff --git a/source/EterLib/GrpCollisionObject.h b/source/EterLib/GrpCollisionObject.h new file mode 100644 index 0000000..94f9018 --- /dev/null +++ b/source/EterLib/GrpCollisionObject.h @@ -0,0 +1,25 @@ +#pragma once + +#include "GrpBase.h" + +class CGraphicCollisionObject : public CGraphicBase +{ + public: + CGraphicCollisionObject(); + virtual ~CGraphicCollisionObject(); + + protected: + bool IntersectTriangle(const D3DXVECTOR3& c_orig, const D3DXVECTOR3& c_dir, const D3DXVECTOR3& c_v0, const D3DXVECTOR3& c_v1, const D3DXVECTOR3& c_v2, float* pu, float* pv, float* pt); + bool IntersectBoundBox(const D3DXMATRIX* c_pmatWorld, const TBoundBox& c_rboundBox, float* pu, float* pv, float* pt); + bool IntersectCube(const D3DXMATRIX* c_pmatWorld, float sx, float sy, float sz, float ex, float ey, float ez, D3DXVECTOR3 & RayOriginal, D3DXVECTOR3 & RayDirection, float* pu, float* pv, float* pt); + bool IntersectIndexedMesh(const D3DXMATRIX* c_pmatWorld, const void* vertices, int step, int vtxCount, const void* indices, int idxCount, D3DXVECTOR3 & RayOriginal, D3DXVECTOR3 & RayDirection, float* pu, float* pv, float* pt); + bool IntersectMesh(const D3DXMATRIX * c_pmatWorld, const void * vertices, DWORD dwStep, DWORD dwvtxCount, D3DXVECTOR3 & RayOriginal, D3DXVECTOR3 & RayDirection, float* pu, float* pv, float* pt); + + bool IntersectSphere(const D3DXVECTOR3 & c_rv3Position, float fRadius, const D3DXVECTOR3 & c_rv3RayOriginal, const D3DXVECTOR3 & c_rv3RayDirection); + bool IntersectCylinder(const D3DXVECTOR3 & c_rv3Position, float fRadius, float fHeight, const D3DXVECTOR3 & c_rv3RayOriginal, const D3DXVECTOR3 & c_rv3RayDirection); + + // NOTE : ms_vtPickRayOrig ms_vtPickRayDir CGraphicBGase ִµ + // ڷ ־ ϴ ִ°? Customize ؼ? - [levites] + bool IntersectSphere(const D3DXVECTOR3 & c_rv3Position, float fRadius); + bool IntersectCylinder(const D3DXVECTOR3 & c_rv3Position, float fRadius, float fHeight); +}; diff --git a/source/EterLib/GrpColor.cpp b/source/EterLib/GrpColor.cpp new file mode 100644 index 0000000..83cf2f5 --- /dev/null +++ b/source/EterLib/GrpColor.cpp @@ -0,0 +1,77 @@ +#include "StdAfx.h" +#include "GrpColor.h" + +CGraphicColor::CGraphicColor() +{ + Clear(); +} + +CGraphicColor::CGraphicColor(const CGraphicColor& c_rSrcColor) +{ + Set(c_rSrcColor); +} + +CGraphicColor::CGraphicColor(float r, float g, float b, float a) +{ + Set(r, g, b, a); +} + +CGraphicColor::CGraphicColor(DWORD color) +{ + Set(color); +} + +CGraphicColor::~CGraphicColor() +{ +} + +void CGraphicColor::Clear() +{ + Set(1.0f, 1.0f, 1.0f, 1.0f); +} + +void CGraphicColor::Set(float r, float g, float b, float a) +{ + m_r=r; + m_g=g; + m_b=b; + m_a=a; +} + +void CGraphicColor::Set(const CGraphicColor& c_rSrcColor) +{ + m_r=c_rSrcColor.m_r; + m_g=c_rSrcColor.m_g; + m_b=c_rSrcColor.m_b; + m_a=c_rSrcColor.m_a; +} + +void CGraphicColor::Blend(float p, const CGraphicColor& c_rSrcColor, const CGraphicColor& c_rDstColor) +{ + float q=1.0f-p; + m_r=c_rSrcColor.m_r*q+c_rDstColor.m_r*p; + m_g=c_rSrcColor.m_g*q+c_rDstColor.m_g*p; + m_b=c_rSrcColor.m_b*q+c_rDstColor.m_b*p; + m_a=c_rSrcColor.m_a*q+c_rDstColor.m_a*p; +} + +void CGraphicColor::Set(DWORD pack) +{ + m_b = (pack & 0xff) / 255.0f; pack >>= 8; + m_g = (pack & 0xff) / 255.0f; pack >>= 8; + m_r = (pack & 0xff) / 255.0f; pack >>= 8; + m_a = (pack) / 255.0f; +} + +DWORD CGraphicColor::GetPackValue() const +{ + DWORD packValue=0; + + packValue = int(255.0f * m_a);packValue <<= 8; + packValue |= int(255.0f * m_r);packValue <<= 8; + packValue |= int(255.0f * m_g);packValue <<= 8; + packValue |= int(255.0f * m_b); + + return packValue; +} + diff --git a/source/EterLib/GrpColor.h b/source/EterLib/GrpColor.h new file mode 100644 index 0000000..08d5324 --- /dev/null +++ b/source/EterLib/GrpColor.h @@ -0,0 +1,28 @@ +#pragma once + +class CGraphicColor +{ + public: + CGraphicColor(const CGraphicColor& c_rSrcColor); + CGraphicColor(float r, float g, float b, float a); + CGraphicColor(DWORD color); + + CGraphicColor(); + ~CGraphicColor(); + + void Clear(); + + void Set(float r, float g, float b, float a); + void Set(const CGraphicColor& c_rSrcColor); + void Set(DWORD color); + + void Blend(float p, const CGraphicColor& c_rSrcColor, const CGraphicColor& c_rDstColor); + + DWORD GetPackValue() const; + + protected: + float m_r; + float m_g; + float m_b; + float m_a; +}; diff --git a/source/EterLib/GrpColorInstance.cpp b/source/EterLib/GrpColorInstance.cpp new file mode 100644 index 0000000..f2a9026 --- /dev/null +++ b/source/EterLib/GrpColorInstance.cpp @@ -0,0 +1,65 @@ +#include "StdAfx.h" +#include "GrpColorInstance.h" +#include "../eterBase/Timer.h" + +CGraphicColorInstance::CGraphicColorInstance() +{ + m_baseTime=0; + m_blendTime=0; +} + +CGraphicColorInstance::~CGraphicColorInstance() +{ +} + +void CGraphicColorInstance::Clear() +{ + m_srcColor.Clear(); + m_dstColor.Clear(); + m_curColor.Clear(); + + m_baseTime=0; + m_blendTime=0; +} + +void CGraphicColorInstance::SetColorReference(const CGraphicColor & c_rSrcColor) +{ + m_srcColor = c_rSrcColor; + m_dstColor = c_rSrcColor; + m_curColor = c_rSrcColor; +} + +void CGraphicColorInstance::BlendColorReference(DWORD blendTime, const CGraphicColor& c_rDstColor) +{ + m_baseTime = GetCurrentTime(); + m_blendTime = blendTime; + + m_srcColor = m_curColor; + m_dstColor = c_rDstColor; +} + +void CGraphicColorInstance::Update() +{ + DWORD curTime = GetCurrentTime(); + DWORD elapsedTime = curTime - m_baseTime; + + if (elapsedTime < m_blendTime) + { + m_curColor.Blend(elapsedTime/float(m_blendTime), m_srcColor, m_dstColor); + } + else + { + m_curColor=m_dstColor; + } +} + +DWORD CGraphicColorInstance::GetCurrentTime() +{ + return CTimer::Instance().GetCurrentMillisecond(); +} + +const CGraphicColor& CGraphicColorInstance::GetCurrentColorReference() const +{ + return m_curColor; +} + diff --git a/source/EterLib/GrpColorInstance.h b/source/EterLib/GrpColorInstance.h new file mode 100644 index 0000000..0a28a7c --- /dev/null +++ b/source/EterLib/GrpColorInstance.h @@ -0,0 +1,33 @@ +#pragma once + +#include "GrpColor.h" +#include "Pool.h" + +class CGraphicColorInstance +{ + public: + CGraphicColorInstance(); + virtual ~CGraphicColorInstance(); + + void Clear(); + + void SetColorReference(const CGraphicColor& c_rSrcColor); + void BlendColorReference(DWORD blendTime, const CGraphicColor& c_rDstColor); + + void Update(); + + const CGraphicColor& GetCurrentColorReference() const; + + protected: + DWORD GetCurrentTime(); + + protected: + CGraphicColor m_srcColor; + CGraphicColor m_dstColor; + CGraphicColor m_curColor; + + DWORD m_baseTime; + DWORD m_blendTime; +}; + +typedef CDynamicPool TGraphicColorInstancePool; diff --git a/source/EterLib/GrpD3DXBuffer.cpp b/source/EterLib/GrpD3DXBuffer.cpp new file mode 100644 index 0000000..8abf31e --- /dev/null +++ b/source/EterLib/GrpD3DXBuffer.cpp @@ -0,0 +1,41 @@ +#include "StdAfx.h" +#include "GrpD3DXBuffer.h" +#include "../eterBase/Stl.h" + +CDirect3DXBuffer::CDirect3DXBuffer() +{ + m_lpd3dxBuffer=NULL; +} + +CDirect3DXBuffer::CDirect3DXBuffer(LPD3DXBUFFER lpd3dxBuffer) +{ + m_lpd3dxBuffer=lpd3dxBuffer; +} + +CDirect3DXBuffer::~CDirect3DXBuffer() +{ + Destroy(); +} + +void CDirect3DXBuffer::Destroy() +{ + safe_release(m_lpd3dxBuffer); +} + +void CDirect3DXBuffer::Create(LPD3DXBUFFER lpd3dxBuffer) +{ + Destroy(); + m_lpd3dxBuffer=lpd3dxBuffer; +} + +void*CDirect3DXBuffer::GetPointer() +{ + assert(m_lpd3dxBuffer!=NULL); + return m_lpd3dxBuffer->GetBufferPointer(); +} + +int CDirect3DXBuffer::GetSize() +{ + assert(m_lpd3dxBuffer!=NULL); + return m_lpd3dxBuffer->GetBufferSize(); +} diff --git a/source/EterLib/GrpD3DXBuffer.h b/source/EterLib/GrpD3DXBuffer.h new file mode 100644 index 0000000..5b26c64 --- /dev/null +++ b/source/EterLib/GrpD3DXBuffer.h @@ -0,0 +1,18 @@ +#pragma once + +class CDirect3DXBuffer +{ + public: + CDirect3DXBuffer(); + CDirect3DXBuffer(LPD3DXBUFFER lpd3dxBuffer); + virtual ~CDirect3DXBuffer(); + + void Destroy(); + void Create(LPD3DXBUFFER lpd3dxBuffer); + + void*GetPointer(); + int GetSize(); + + protected: + LPD3DXBUFFER m_lpd3dxBuffer; +}; diff --git a/source/EterLib/GrpDIB.cpp b/source/EterLib/GrpDIB.cpp new file mode 100644 index 0000000..c1b57b3 --- /dev/null +++ b/source/EterLib/GrpDIB.cpp @@ -0,0 +1,114 @@ +#include "StdAfx.h" +#include "GrpDIB.h" + +CGraphicDib::CGraphicDib() +{ + Initialize(); +} + +CGraphicDib::~CGraphicDib() +{ + Destroy(); +} + +void CGraphicDib::Initialize() +{ + m_hDC=NULL; + m_hBmp=NULL; + m_pvBuf=NULL; + m_width=0; + m_height=0; +} + +void CGraphicDib::Destroy() +{ + if (m_hBmp) DeleteObject(m_hBmp); + if (m_hDC) DeleteDC(m_hDC); + + Initialize(); +} + +bool CGraphicDib::Create(HDC hDC, int width, int height) +{ + Destroy(); + + m_width = width; + m_height = height; + + ZeroMemory(&m_bmi.bmiHeader, sizeof(BITMAPINFOHEADER)); + m_bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + m_bmi.bmiHeader.biWidth = m_width; + m_bmi.bmiHeader.biHeight = -m_height; + m_bmi.bmiHeader.biPlanes = 1; + m_bmi.bmiHeader.biBitCount = 32; + m_bmi.bmiHeader.biCompression = BI_RGB; + + m_hDC=CreateCompatibleDC(hDC); + if (!m_hDC) + { + assert(!"CGraphicDib::Create CreateCompatibleDC Error"); + return false; + } + + m_hBmp=CreateDIBSection(m_hDC, &m_bmi, DIB_RGB_COLORS, &m_pvBuf, NULL, 0); + if (!m_hBmp) + { + assert(!"CGraphicDib::Create CreateDIBSection Error"); + return false; + } + + SelectObject(m_hDC, m_hBmp); + + ::SetTextColor(m_hDC, RGB(255, 255, 255)); + + return true; +} + +HDC CGraphicDib::GetDCHandle() +{ + return m_hDC; +} + +void CGraphicDib::SetBkMode(int iBkMode) +{ + ::SetBkMode(m_hDC, iBkMode); +} + +void CGraphicDib::TextOut(int ix, int iy, const char * c_szText) +{ + ::SetBkColor(m_hDC, 0); + ::TextOut(m_hDC, ix, iy, c_szText, strlen(c_szText)); +} + +void CGraphicDib::Put(HDC hDC, int x, int y) +{ + SetDIBitsToDevice( + hDC, + x, + y, + m_width, + m_height, + 0, + 0, + 0, + m_height, + m_pvBuf, + &m_bmi, + DIB_RGB_COLORS + ); +} + +void* CGraphicDib::GetPointer() +{ + return m_pvBuf; +} + +int CGraphicDib::GetWidth() +{ + return m_width; +} + +int CGraphicDib::GetHeight() +{ + return m_height; +} \ No newline at end of file diff --git a/source/EterLib/GrpDIB.h b/source/EterLib/GrpDIB.h new file mode 100644 index 0000000..a0407ae --- /dev/null +++ b/source/EterLib/GrpDIB.h @@ -0,0 +1,35 @@ +#pragma once + +class CGraphicDib +{ + public: + CGraphicDib(); + virtual ~CGraphicDib(); + + void Destroy(); + bool Create(HDC hDC, int width, int height); + + void SetBkMode(int iBkMode); + void TextOut(int ix, int iy, const char * c_szText); + void Put(HDC hDC, int x, int y); + + int GetWidth(); + int GetHeight(); + + void* GetPointer(); + + HDC GetDCHandle(); + + protected: + void Initialize(); + + protected: + HDC m_hDC; + HBITMAP m_hBmp; + BITMAPINFO m_bmi; + + int m_width; + int m_height; + + void * m_pvBuf; +}; diff --git a/source/EterLib/GrpDetector.cpp b/source/EterLib/GrpDetector.cpp new file mode 100644 index 0000000..878dc3e --- /dev/null +++ b/source/EterLib/GrpDetector.cpp @@ -0,0 +1,647 @@ +#include "StdAfx.h" +#include "../eterBase/Stl.h" +#include "GrpDetector.h" + +struct FIsEqualD3DDisplayMode +{ + FIsEqualD3DDisplayMode(D3DDISPLAYMODE* pkD3DDMChk) + { + m_pkD3DDMChk=pkD3DDMChk; + } + BOOL operator() (D3DDISPLAYMODE& rkD3DDMTest) + { + if (rkD3DDMTest.Width!=m_pkD3DDMChk->Width) + return FALSE; + + if (rkD3DDMTest.Height!=m_pkD3DDMChk->Height) + return FALSE; + + if (rkD3DDMTest.Format!=m_pkD3DDMChk->Format) + return FALSE; + + return TRUE; + } + + D3DDISPLAYMODE* m_pkD3DDMChk; +}; + +static int CompareD3DDisplayModeOrder( const VOID* arg1, const VOID* arg2 ) +{ + D3DDISPLAYMODE* p1 = (D3DDISPLAYMODE*)arg1; + D3DDISPLAYMODE* p2 = (D3DDISPLAYMODE*)arg2; + + if( p1->Format > p2->Format ) return -1; + if( p1->Format < p2->Format ) return +1; + if( p1->Width < p2->Width ) return -1; + if( p1->Width > p2->Width ) return +1; + if( p1->Height < p2->Height ) return -1; + if( p1->Height > p2->Height ) return +1; + + return 0; +} + + + +///////////////////////////////////////////////////////////////////////////////// + +UINT D3D_CAdapterDisplayModeList::GetDisplayModeNum() +{ + return m_uD3DDMNum; +} + +UINT D3D_CAdapterDisplayModeList::GetPixelFormatNum() +{ + return m_uD3DFmtNum; +} + + +const D3DDISPLAYMODE& D3D_CAdapterDisplayModeList::GetDisplayModer(UINT iD3DDM) +{ + assert(iD3DDMappend(szText); +} + +///////////////////////////////////////////////////////////////////////////////// + +const CHAR* D3D_CDeviceInfo::msc_aszD3DDevDesc[D3DDEVICETYPE_NUM] = {"HAL", "REF"}; +const D3DDEVTYPE D3D_CDeviceInfo::msc_aeD3DDevType[D3DDEVICETYPE_NUM]={D3DDEVTYPE_HAL, D3DDEVTYPE_REF}; + + +UINT D3D_CDeviceInfo::GetD3DModeInfoNum() +{ + return m_uD3DModeInfoNum; +} + +D3D_SModeInfo* D3D_CDeviceInfo::GetD3DModeInfop(UINT iD3D_SModeInfo) +{ + if (iD3D_SModeInfo >= m_uD3DModeInfoNum) + return NULL; + + return &m_akD3DModeInfo[iD3D_SModeInfo]; +} + +BOOL D3D_CDeviceInfo::FindDepthStencilFormat(IDirect3D8& rkD3D, UINT iD3DAdapterInfo, D3DDEVTYPE DeviceType, D3DFORMAT TargetFormat, D3DFORMAT* pDepthStencilFormat ) +{ + UINT m_dwMinDepthBits = 16; + UINT m_dwMinStencilBits = 0; + + if( m_dwMinDepthBits <= 16 && m_dwMinStencilBits == 0 ) + { + if( SUCCEEDED( rkD3D.CheckDeviceFormat( iD3DAdapterInfo, DeviceType, + TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D16 ) ) ) + { + if( SUCCEEDED( rkD3D.CheckDepthStencilMatch( iD3DAdapterInfo, DeviceType, + TargetFormat, TargetFormat, D3DFMT_D16 ) ) ) + { + *pDepthStencilFormat = D3DFMT_D16; + return TRUE; + } + } + } + + if( m_dwMinDepthBits <= 15 && m_dwMinStencilBits <= 1 ) + { + if( SUCCEEDED( rkD3D.CheckDeviceFormat( iD3DAdapterInfo, DeviceType, + TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D15S1 ) ) ) + { + if( SUCCEEDED( rkD3D.CheckDepthStencilMatch( iD3DAdapterInfo, DeviceType, + TargetFormat, TargetFormat, D3DFMT_D15S1 ) ) ) + { + *pDepthStencilFormat = D3DFMT_D15S1; + return TRUE; + } + } + } + + if( m_dwMinDepthBits <= 24 && m_dwMinStencilBits == 0 ) + { + if( SUCCEEDED( rkD3D.CheckDeviceFormat( iD3DAdapterInfo, DeviceType, + TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24X8 ) ) ) + { + if( SUCCEEDED( rkD3D.CheckDepthStencilMatch( iD3DAdapterInfo, DeviceType, + TargetFormat, TargetFormat, D3DFMT_D24X8 ) ) ) + { + *pDepthStencilFormat = D3DFMT_D24X8; + return TRUE; + } + } + } + + if( m_dwMinDepthBits <= 24 && m_dwMinStencilBits <= 8 ) + { + if( SUCCEEDED( rkD3D.CheckDeviceFormat( iD3DAdapterInfo, DeviceType, + TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24S8 ) ) ) + { + if( SUCCEEDED( rkD3D.CheckDepthStencilMatch( iD3DAdapterInfo, DeviceType, + TargetFormat, TargetFormat, D3DFMT_D24S8 ) ) ) + { + *pDepthStencilFormat = D3DFMT_D24S8; + return TRUE; + } + } + } + + if( m_dwMinDepthBits <= 24 && m_dwMinStencilBits <= 4 ) + { + if( SUCCEEDED( rkD3D.CheckDeviceFormat( iD3DAdapterInfo, DeviceType, + TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24X4S4 ) ) ) + { + if( SUCCEEDED( rkD3D.CheckDepthStencilMatch( iD3DAdapterInfo, DeviceType, + TargetFormat, TargetFormat, D3DFMT_D24X4S4 ) ) ) + { + *pDepthStencilFormat = D3DFMT_D24X4S4; + return TRUE; + } + } + } + + if( m_dwMinDepthBits <= 32 && m_dwMinStencilBits == 0 ) + { + if( SUCCEEDED( rkD3D.CheckDeviceFormat( iD3DAdapterInfo, DeviceType, + TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D32 ) ) ) + { + if( SUCCEEDED( rkD3D.CheckDepthStencilMatch( iD3DAdapterInfo, DeviceType, + TargetFormat, TargetFormat, D3DFMT_D32 ) ) ) + { + *pDepthStencilFormat = D3DFMT_D32; + return TRUE; + } + } + } + + return FALSE; +} + +BOOL D3D_CDeviceInfo::Build(IDirect3D8& rkD3D, UINT iD3DAdapterInfo, UINT iDevType, D3D_CAdapterDisplayModeList& rkD3DADMList, BOOL (*pfnConfirmDevice)(D3DCAPS8& rkD3DCaps, UINT uBehavior, D3DFORMAT eD3DFmt)) +{ + assert(pfnConfirmDevice!=NULL && "D3D_CDeviceInfo::Build"); + + const D3DDEVTYPE c_eD3DDevType=msc_aeD3DDevType[iDevType]; + const TCHAR* c_szD3DDevDesc=msc_aszD3DDevDesc[iDevType]; + + m_eD3DDevType = c_eD3DDevType; + rkD3D.GetDeviceCaps(iD3DAdapterInfo, c_eD3DDevType, &m_kD3DCaps); + + m_szDevDesc = c_szD3DDevDesc; + m_uD3DModeInfoNum=0; + m_canDoWindowed = FALSE; + m_isWindowed = FALSE; + m_eD3DMSTFullscreen = D3DMULTISAMPLE_NONE; + m_eD3DMSTWindowed = D3DMULTISAMPLE_NONE; + + BOOL aisFormatConfirmed[20]; + DWORD adwD3DBehavior[20]; + D3DFORMAT aeD3DFmtDepthStencil[20]; + + BOOL isHALExists = FALSE; + BOOL isHALWindowedCompatible = FALSE; + BOOL isHALDesktopCompatible = FALSE; + BOOL isHALSampleCompatible = FALSE; + + // GetFlagInfo + { + UINT uD3DFmtNum=rkD3DADMList.GetPixelFormatNum(); + + for (DWORD iFmt=0; iFmt0) + return TRUE; + + return FALSE; +} + +BOOL D3D_CDeviceInfo::Find(UINT uScrWidth, UINT uScrHeight, UINT uScrDepthBits, BOOL isWindowed, UINT* piD3DModeInfo) +{ + if (isWindowed) + if (!m_isWindowed) + return FALSE; + + for (UINT iD3D_SModeInfo=0; iD3D_SModeInfoappend(szText); + + for (UINT iD3D_SModeInfo=0; iD3D_SModeInfoappend(szText); + + D3D_SModeInfo& rkModeInfo=m_akD3DModeInfo[iD3D_SModeInfo]; + rkModeInfo.GetString(pstEnumList); + } + + pstEnumList->append("\r\n"); +} + +///////////////////////////////////////////////////////////////////////////// + +D3DDISPLAYMODE& D3D_CAdapterInfo::GetDesktopD3DDisplayModer() +{ + return m_kD3DDMDesktop; +} + +D3DDISPLAYMODE* D3D_CAdapterInfo::GetDesktopD3DDisplayModep() +{ + return &m_kD3DDMDesktop; +} + +D3D_CDeviceInfo* D3D_CAdapterInfo::GetD3DDeviceInfop(UINT iD3DDevInfo) +{ + if (iD3DDevInfo >= m_uD3DDevInfoNum) + return NULL; + + return &m_akD3DDevInfo[iD3DDevInfo]; +} + +D3D_SModeInfo* D3D_CAdapterInfo::GetD3DModeInfop(UINT iD3DDevInfo, UINT iD3D_SModeInfo) +{ + D3D_CDeviceInfo* pkD3DDevInfo=GetD3DDeviceInfop(iD3DDevInfo); + if (pkD3DDevInfo) + { + D3D_SModeInfo* pkD3DModeInfo=pkD3DDevInfo->GetD3DModeInfop(iD3D_SModeInfo); + if (pkD3DModeInfo) + return pkD3DModeInfo; + } + return NULL; +} + +BOOL D3D_CAdapterInfo::Find(UINT uScrWidth, UINT uScrHeight, UINT uScrDepthBits, BOOL isWindowed, UINT* piD3DModeInfo, UINT* piD3DDevInfo) +{ + for (UINT iDevInfo=0; iDevInfo0) + return TRUE; + + return FALSE; +} + +VOID D3D_CAdapterInfo::GetString(std::string* pstEnumList) +{ + for (UINT iDevInfo=0; iDevInfoappend(szText); + + D3D_CDeviceInfo& rkD3DDevInfo=m_akD3DDevInfo[iDevInfo]; + rkD3DDevInfo.GetString(pstEnumList); + } +} + +///////////////////////////////////////////////////////////////////////////// + +D3D_CDisplayModeAutoDetector::D3D_CDisplayModeAutoDetector() +{ + m_uD3DAdapterInfoCount=0; +} + +D3D_CDisplayModeAutoDetector::~D3D_CDisplayModeAutoDetector() +{ +} + +D3D_CAdapterInfo* D3D_CDisplayModeAutoDetector::GetD3DAdapterInfop(UINT iD3DAdapterInfo) +{ + if (iD3DAdapterInfo >= m_uD3DAdapterInfoCount) + return NULL; + + return &m_akD3DAdapterInfo[iD3DAdapterInfo]; +} + +D3D_SModeInfo* D3D_CDisplayModeAutoDetector::GetD3DModeInfop(UINT iD3DAdapterInfo, UINT iD3DDevInfo, UINT iD3D_SModeInfo) +{ + D3D_CAdapterInfo* pkD3DAdapterInfo=GetD3DAdapterInfop(iD3DAdapterInfo); + if (pkD3DAdapterInfo) + { + D3D_CDeviceInfo* pkD3DDevInfo=pkD3DAdapterInfo->GetD3DDeviceInfop(iD3DDevInfo); + if (pkD3DDevInfo) + { + D3D_SModeInfo* pkD3D_SModeInfo=pkD3DDevInfo->GetD3DModeInfop(iD3D_SModeInfo); + if (pkD3D_SModeInfo) + return pkD3D_SModeInfo; + } + } + return NULL; +} + +BOOL D3D_CDisplayModeAutoDetector::Find(UINT uScrWidth, UINT uScrHeight, UINT uScrDepthBits, BOOL isWindowed, UINT* piD3DModeInfo, UINT* piD3DDevInfo, UINT* piD3DAdapterInfo) +{ + for (UINT iD3DAdapterInfo=0; iD3DAdapterInfo0) + return TRUE; + + return FALSE; +} + +VOID D3D_CDisplayModeAutoDetector::GetString(std::string* pstEnumList) +{ + for (UINT iD3DAdapterInfo=0; iD3DAdapterInfoappend(szText); + + D3D_CAdapterInfo& rkAdapterInfo=m_akD3DAdapterInfo[iD3DAdapterInfo]; + rkAdapterInfo.GetString(pstEnumList); + } +} \ No newline at end of file diff --git a/source/EterLib/GrpDetector.h b/source/EterLib/GrpDetector.h new file mode 100644 index 0000000..e265dfb --- /dev/null +++ b/source/EterLib/GrpDetector.h @@ -0,0 +1,166 @@ +#pragma once + +#include +#include +typedef BOOL (*PFNCONFIRMDEVICE) (D3DCAPS8& rkD3DCaps, UINT uBehavior, D3DFORMAT eD3DFmt); + +enum +{ + D3DDEVICETYPE_HAL, + D3DDEVICETYPE_REF, + D3DDEVICETYPE_NUM, +}; + +struct D3D_SModeInfo +{ + UINT m_uScrWidth; + UINT m_uScrHeight; + UINT m_uScrDepthBit; + UINT m_dwD3DBehavior; + D3DFORMAT m_eD3DFmtPixel; + D3DFORMAT m_eD3DFmtDepthStencil; + + VOID GetString(std::string* pstEnumList); +}; + +class D3D_CAdapterDisplayModeList +{ + public: + D3D_CAdapterDisplayModeList() {} + ~D3D_CAdapterDisplayModeList() {} + VOID Build(IDirect3D8& rkD3D, D3DFORMAT eD3DFmtDefault, UINT iAdapter); + + UINT GetDisplayModeNum(); + UINT GetPixelFormatNum(); + + const D3DDISPLAYMODE& GetDisplayModer(UINT iD3DDM); + const D3DFORMAT& GetPixelFormatr(UINT iD3DFmt); + + protected: + enum + { + D3DDISPLAYMODE_MAX = 100, + D3DFORMAT_MAX = 20, + + FILTEROUT_LOWRESOLUTION_WIDTH = 640, + FILTEROUT_LOWRESOLUTION_HEIGHT = 480, + }; + + protected: + D3DDISPLAYMODE m_akD3DDM[D3DDISPLAYMODE_MAX]; + D3DFORMAT m_aeD3DFmt[D3DFORMAT_MAX]; + + UINT m_uD3DDMNum; + UINT m_uD3DFmtNum; + +}; + +class D3D_CDeviceInfo +{ + public: + D3D_CDeviceInfo() {} + ~D3D_CDeviceInfo() {} + BOOL Build(IDirect3D8& rkD3D, UINT iAdapter, UINT iDevType, D3D_CAdapterDisplayModeList& rkD3DADMList, PFNCONFIRMDEVICE pfnConfirmDevice); + BOOL Find(UINT uScrWidth, UINT uScrHeight, UINT uScrDepthBits, BOOL isWindowed, UINT* piD3DModeInfo); + + UINT GetD3DModeInfoNum(); + + VOID GetString(std::string* pstEnumList); + + BOOL FindDepthStencilFormat(IDirect3D8& rkD3D, UINT iAdapter, D3DDEVTYPE DeviceType, D3DFORMAT TargetFormat, D3DFORMAT* pDepthStencilFormat); + + D3D_SModeInfo& GetD3DModeInfor(UINT iD3DModeInfo); + D3D_SModeInfo* GetD3DModeInfop(UINT iD3DModeInfo); + + protected: + enum + { + D3DMODEINFO_NUM = 150, + }; + + + protected: + const TCHAR* m_szDevDesc; + + D3DDEVTYPE m_eD3DDevType; + D3DCAPS8 m_kD3DCaps; + BOOL m_canDoWindowed; + + UINT m_iCurD3DModeInfo; + UINT m_uD3DModeInfoNum; + D3D_SModeInfo m_akD3DModeInfo[D3DMODEINFO_NUM]; + + + BOOL m_isWindowed; + + D3DMULTISAMPLE_TYPE m_eD3DMSTWindowed; + D3DMULTISAMPLE_TYPE m_eD3DMSTFullscreen; + + + protected: + static const CHAR* msc_aszD3DDevDesc[D3DDEVICETYPE_NUM]; + static const D3DDEVTYPE msc_aeD3DDevType[D3DDEVICETYPE_NUM]; +}; + +class D3D_CAdapterInfo +{ + public: + D3D_CAdapterInfo() {} + ~D3D_CAdapterInfo() {} + BOOL Find(UINT uScrWidth, UINT uScrHeight, UINT uScrDepthBits, BOOL isWindowed, UINT* piD3DModeInfo, UINT* piD3DDevInfo); + + BOOL Build(IDirect3D8& rkD3D, UINT iAdapter, PFNCONFIRMDEVICE pfnConfirmDevice); + VOID GetString(std::string* pstEnumList); + + D3DADAPTER_IDENTIFIER8& GetIdentifier() + { + return m_kD3DAdapterIdentifier; + } + + D3DDISPLAYMODE& GetDesktopD3DDisplayModer(); + D3DDISPLAYMODE* GetDesktopD3DDisplayModep(); + + D3D_CDeviceInfo* GetD3DDeviceInfop(UINT iD3DDevInfo); + D3D_SModeInfo* GetD3DModeInfop(UINT iD3DDevInfo, UINT iD3DModeInfo); + + protected: + enum + { + D3DDEVICEINFO_NUM = 5, + }; + + + protected: + D3DADAPTER_IDENTIFIER8 m_kD3DAdapterIdentifier; + D3DDISPLAYMODE m_kD3DDMDesktop; + + UINT m_iCurD3DDevInfo; + UINT m_uD3DDevInfoNum; + D3D_CDeviceInfo m_akD3DDevInfo[D3DDEVICEINFO_NUM]; + +}; + +class D3D_CDisplayModeAutoDetector +{ + public: + D3D_CDisplayModeAutoDetector(); + ~D3D_CDisplayModeAutoDetector(); + + BOOL Find(UINT uScrWidth, UINT uScrHeight, UINT uScrDepthBits, BOOL isWindowed, UINT* piD3DModeInfo, UINT* piD3DDevInfo, UINT* piD3DAdapterInfo); + BOOL Build(IDirect3D8& rkD3D, PFNCONFIRMDEVICE pfnConfirmDevice); + + D3D_CAdapterInfo* GetD3DAdapterInfop(UINT iD3DAdapterInfo); + D3D_SModeInfo* GetD3DModeInfop(UINT iD3DAdapterInfo, UINT iD3DDevInfo, UINT iD3DModeInfo); + + VOID GetString(std::string* pstEnumList); + + protected: + enum + { + D3DADAPTERINFO_NUM = 10, + }; + + protected: + D3D_CAdapterInfo m_akD3DAdapterInfo[D3DADAPTERINFO_NUM]; + UINT m_uD3DAdapterInfoCount; +}; \ No newline at end of file diff --git a/source/EterLib/GrpDevice.cpp b/source/EterLib/GrpDevice.cpp new file mode 100644 index 0000000..22ef0b4 --- /dev/null +++ b/source/EterLib/GrpDevice.cpp @@ -0,0 +1,764 @@ +#include "StdAfx.h" +#include "GrpDevice.h" +#include "../eterBase/Stl.h" +#include "../eterBase/Debug.h" + +bool GRAPHICS_CAPS_CAN_NOT_DRAW_LINE = false; +bool GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW = false; +bool GRAPHICS_CAPS_HALF_SIZE_IMAGE = false; +bool GRAPHICS_CAPS_CAN_NOT_TEXTURE_ADDRESS_BORDER = false; +bool GRAPHICS_CAPS_SOFTWARE_TILING = false; + +D3DPRESENT_PARAMETERS g_kD3DPP; +bool g_isBrowserMode=false; +RECT g_rcBrowser; + +CGraphicDevice::CGraphicDevice() +: m_uBackBufferCount(0) +{ + __Initialize(); +} + +CGraphicDevice::~CGraphicDevice() +{ + Destroy(); +} + +void CGraphicDevice::__Initialize() +{ + ms_iD3DAdapterInfo=D3DADAPTER_DEFAULT; + ms_iD3DDevInfo=D3DADAPTER_DEFAULT; + ms_iD3DModeInfo=D3DADAPTER_DEFAULT; + + ms_lpd3d = NULL; + ms_lpd3dDevice = NULL; + ms_lpd3dMatStack = NULL; + + ms_dwWavingEndTime = 0; + ms_dwFlashingEndTime = 0; + + m_pStateManager = NULL; + + __InitializeDefaultIndexBufferList(); + __InitializePDTVertexBufferList(); +} + +void CGraphicDevice::RegisterWarningString(UINT uiMsg, const char * c_szString) +{ + m_kMap_strWarningMessage[uiMsg] = c_szString; +} + +void CGraphicDevice::__WarningMessage(HWND hWnd, UINT uiMsg) +{ + if (m_kMap_strWarningMessage.end() == m_kMap_strWarningMessage.find(uiMsg)) + return; + MessageBox(hWnd, m_kMap_strWarningMessage[uiMsg].c_str(), "Warning", MB_OK|MB_TOPMOST); +} + +void CGraphicDevice::MoveWebBrowserRect(const RECT& c_rcWebPage) +{ + g_rcBrowser=c_rcWebPage; +} + +void CGraphicDevice::EnableWebBrowserMode(const RECT& c_rcWebPage) +{ + if (!ms_lpd3dDevice) + return; + + D3DPRESENT_PARAMETERS& rkD3DPP=ms_d3dPresentParameter; + + g_isBrowserMode=true; + + if (D3DSWAPEFFECT_COPY==rkD3DPP.SwapEffect) + return; + + g_kD3DPP=rkD3DPP; + g_rcBrowser=c_rcWebPage; + + //rkD3DPP.Windowed=TRUE; + rkD3DPP.SwapEffect=D3DSWAPEFFECT_COPY; + rkD3DPP.BackBufferCount = 1; + rkD3DPP.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + + IDirect3DDevice8& rkD3DDev=*ms_lpd3dDevice; + HRESULT hr=rkD3DDev.Reset(&rkD3DPP); + if (FAILED(hr)) + return; + + STATEMANAGER.SetDefaultState(); +} + +void CGraphicDevice::DisableWebBrowserMode() +{ + if (!ms_lpd3dDevice) + return; + + D3DPRESENT_PARAMETERS& rkD3DPP=ms_d3dPresentParameter; + + g_isBrowserMode=false; + + rkD3DPP=g_kD3DPP; + + IDirect3DDevice8& rkD3DDev=*ms_lpd3dDevice; + HRESULT hr=rkD3DDev.Reset(&rkD3DPP); + if (FAILED(hr)) + return; + + STATEMANAGER.SetDefaultState(); +} + +bool CGraphicDevice::ResizeBackBuffer(UINT uWidth, UINT uHeight) +{ + if (!ms_lpd3dDevice) + return false; + + D3DPRESENT_PARAMETERS& rkD3DPP=ms_d3dPresentParameter; + if (rkD3DPP.Windowed) + { + if (rkD3DPP.BackBufferWidth!=uWidth || rkD3DPP.BackBufferHeight!=uHeight) + { + rkD3DPP.BackBufferWidth=uWidth; + rkD3DPP.BackBufferHeight=uHeight; + + IDirect3DDevice8& rkD3DDev=*ms_lpd3dDevice; + + HRESULT hr=rkD3DDev.Reset(&rkD3DPP); + if (FAILED(hr)) + { + return false; + } + + STATEMANAGER.SetDefaultState(); + } + } + + return true; +} + +DWORD CGraphicDevice::CreatePNTStreamVertexShader() +{ + assert(ms_lpd3dDevice != NULL); + + DWORD declVector[] = + { + D3DVSD_STREAM(0), + D3DVSD_REG(0, D3DVSDT_FLOAT3), + D3DVSD_REG(3, D3DVSDT_FLOAT3), + D3DVSD_REG(7, D3DVSDT_FLOAT2), + D3DVSD_END() + }; + + DWORD ret; + + if (FAILED(ms_lpd3dDevice->CreateVertexShader(&declVector[0], NULL, &ret, 0))) + return 0; + + return ret; +} + +DWORD CGraphicDevice::CreatePNT2StreamVertexShader() +{ + assert(ms_lpd3dDevice != NULL); + + DWORD declVector[] = + { + D3DVSD_STREAM(0), + D3DVSD_REG(0, D3DVSDT_FLOAT3), + D3DVSD_REG(3, D3DVSDT_FLOAT3), + D3DVSD_REG(7, D3DVSDT_FLOAT2), + D3DVSD_REG(D3DVSDE_TEXCOORD1, D3DVSDT_FLOAT2), +// D3DVSD_STREAM(1), + D3DVSD_END() + }; + + DWORD ret; + + if (FAILED(ms_lpd3dDevice->CreateVertexShader(&declVector[0], NULL, &ret, 0))) + return 0; + + return ret; +} + +DWORD CGraphicDevice::CreatePTStreamVertexShader() +{ + assert(ms_lpd3dDevice != NULL); + + DWORD declVector[] = + { + D3DVSD_STREAM(0), + D3DVSD_REG(0, D3DVSDT_FLOAT3), + D3DVSD_STREAM(1), + D3DVSD_REG(7, D3DVSDT_FLOAT2), + D3DVSD_END() + }; + + DWORD ret; + + if (FAILED(ms_lpd3dDevice->CreateVertexShader(&declVector[0], NULL, &ret, 0))) + return 0; + + return (ret); +} + +DWORD CGraphicDevice::CreateDoublePNTStreamVertexShader() +{ + assert(ms_lpd3dDevice != NULL); + + DWORD declVector[] = + { + D3DVSD_STREAM(0), + D3DVSD_REG(0, D3DVSDT_FLOAT3), + D3DVSD_REG(3, D3DVSDT_FLOAT3), + D3DVSD_REG(7, D3DVSDT_FLOAT2), + D3DVSD_STREAM(1), + D3DVSD_REG(D3DVSDE_POSITION2, D3DVSDT_FLOAT3), + D3DVSD_REG(D3DVSDE_NORMAL2, D3DVSDT_FLOAT3), + D3DVSD_REG(D3DVSDE_TEXCOORD1, D3DVSDT_FLOAT2), + D3DVSD_END() + }; + + DWORD ret; + + if (FAILED(ms_lpd3dDevice->CreateVertexShader(&declVector[0], NULL, &ret, 0))) + return 0; + + return ret; +} + +CGraphicDevice::EDeviceState CGraphicDevice::GetDeviceState() +{ + if (!ms_lpd3dDevice) + return DEVICESTATE_NULL; + + HRESULT hr; + + if (FAILED(hr = ms_lpd3dDevice->TestCooperativeLevel())) + { + if (D3DERR_DEVICELOST == hr) + return DEVICESTATE_BROKEN; + + if (D3DERR_DEVICENOTRESET == hr) + return DEVICESTATE_NEEDS_RESET; + + return DEVICESTATE_BROKEN; + } + + return DEVICESTATE_OK; +} + +bool CGraphicDevice::Reset() +{ + HRESULT hr; + + if (FAILED(hr = ms_lpd3dDevice->Reset(&ms_d3dPresentParameter))) + return false; + + return true; +} + +static LPDIRECT3DSURFACE8 s_lpStencil; +static DWORD s_MaxTextureWidth, s_MaxTextureHeight; + +BOOL EL3D_ConfirmDevice(D3DCAPS8& rkD3DCaps, UINT uBehavior, D3DFORMAT /*eD3DFmt*/) +{ + // PUREDEVICE GetTransform / GetViewport ʴ´. + if (uBehavior & D3DCREATE_PUREDEVICE) + return FALSE; + + if (uBehavior & D3DCREATE_HARDWARE_VERTEXPROCESSING) + { + // DirectionalLight + if (!(rkD3DCaps.VertexProcessingCaps & D3DVTXPCAPS_DIRECTIONALLIGHTS)) + return FALSE; + + // PositionalLight + if (!(rkD3DCaps.VertexProcessingCaps & D3DVTXPCAPS_POSITIONALLIGHTS)) + return FALSE; + + // Software T&L Support - ATI NOT SUPPORT CLIP, USE DIRECTX SOFTWARE PROCESSING CLIPPING + if (GRAPHICS_CAPS_SOFTWARE_TILING) + { + if (!(rkD3DCaps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)) + return FALSE; + } + else + { + // Shadow/Terrain + if (!(rkD3DCaps.VertexProcessingCaps & D3DVTXPCAPS_TEXGEN)) + return FALSE; + } + } + + s_MaxTextureWidth = rkD3DCaps.MaxTextureWidth; + s_MaxTextureHeight = rkD3DCaps.MaxTextureHeight; + + return TRUE; +} + +DWORD GetMaxTextureWidth() +{ + return s_MaxTextureWidth; +} + +DWORD GetMaxTextureHeight() +{ + return s_MaxTextureHeight; +} + +bool CGraphicDevice::__IsInDriverBlackList(D3D_CAdapterInfo& rkD3DAdapterInfo) +{ + D3DADAPTER_IDENTIFIER8& rkD3DAdapterIdentifier=rkD3DAdapterInfo.GetIdentifier(); + + char szSrcDriver[256]; + strncpy(szSrcDriver, rkD3DAdapterIdentifier.Driver, sizeof(szSrcDriver)-1); + DWORD dwSrcHighVersion=rkD3DAdapterIdentifier.DriverVersion.QuadPart>>32; + DWORD dwSrcLowVersion=rkD3DAdapterIdentifier.DriverVersion.QuadPart&0xffffffff; + + bool ret=false; + + FILE* fp=fopen("grpblk.txt", "r"); + if (fp) + { + DWORD dwChkHighVersion; + DWORD dwChkLowVersion; + + char szChkDriver[256]; + + char szLine[256]; + while (fgets(szLine, sizeof(szLine)-1, fp)) + { + sscanf(szLine, "%s %x %x", szChkDriver, &dwChkHighVersion, &dwChkLowVersion); + + if (strcmp(szSrcDriver, szChkDriver)==0) + if (dwSrcHighVersion==dwChkHighVersion) + if (dwSrcLowVersion==dwChkLowVersion) + { + ret=true; + break; + } + + szLine[0]='\0'; + } + fclose(fp); + } + + return ret; +} + +int CGraphicDevice::Create(HWND hWnd, int iHres, int iVres, bool Windowed, int /*iBit*/, int iReflashRate) +{ + int iRet = CREATE_OK; + + Destroy(); + + ms_iWidth = iHres; + ms_iHeight = iVres; + + ms_hWnd = hWnd; + ms_hDC = GetDC(hWnd); + ms_lpd3d = Direct3DCreate8(D3D_SDK_VERSION); + + if (!ms_lpd3d) + return CREATE_NO_DIRECTX; + + if (!ms_kD3DDetector.Build(*ms_lpd3d, EL3D_ConfirmDevice)) + return CREATE_ENUM; + + if (!ms_kD3DDetector.Find(800, 600, 32, TRUE, &ms_iD3DModeInfo, &ms_iD3DDevInfo, &ms_iD3DAdapterInfo)) + return CREATE_DETECT; + + std::string stDevList; + ms_kD3DDetector.GetString(&stDevList); + + //Tracen(stDevList.c_str()); + //Tracenf("adapter %d, device %d, mode %d", ms_iD3DAdapterInfo, ms_iD3DDevInfo, ms_iD3DModeInfo); + + D3D_CAdapterInfo * pkD3DAdapterInfo = ms_kD3DDetector.GetD3DAdapterInfop(ms_iD3DAdapterInfo); + if (!pkD3DAdapterInfo) + { + Tracenf("adapter %d is EMPTY", ms_iD3DAdapterInfo); + return CREATE_DETECT; + } + + if (__IsInDriverBlackList(*pkD3DAdapterInfo)) + { + iRet |= CREATE_BAD_DRIVER; + __WarningMessage(hWnd, CREATE_BAD_DRIVER); + } + + D3D_SModeInfo * pkD3DModeInfo = pkD3DAdapterInfo->GetD3DModeInfop(ms_iD3DDevInfo, ms_iD3DModeInfo); + if (!pkD3DModeInfo) + { + Tracenf("device %d, mode %d is EMPTY", ms_iD3DDevInfo, ms_iD3DModeInfo); + return CREATE_DETECT; + } + + D3DADAPTER_IDENTIFIER8& rkD3DAdapterId=pkD3DAdapterInfo->GetIdentifier(); + if (Windowed && + strnicmp(rkD3DAdapterId.Driver, "3dfx", 4)==0 && + 22 == pkD3DAdapterInfo->GetDesktopD3DDisplayModer().Format) + { + return CREATE_FORMAT; + } + + if (pkD3DModeInfo->m_dwD3DBehavior==D3DCREATE_SOFTWARE_VERTEXPROCESSING) + { + iRet |= CREATE_NO_TNL; + + // DISABLE_NOTIFY_NOT_SUPPORT_TNL_MESSAGE + //__WarningMessage(hWnd, CREATE_NO_TNL); + // END_OF_DISABLE_NOTIFY_NOT_SUPPORT_TNL_MESSAGE + } + + std::string stModeInfo; + pkD3DModeInfo->GetString(&stModeInfo); + + //Tracen(stModeInfo.c_str()); + + int ErrorCorrection = 0; + +RETRY: + ZeroMemory(&ms_d3dPresentParameter, sizeof(ms_d3dPresentParameter)); + + ms_d3dPresentParameter.Windowed = Windowed; + ms_d3dPresentParameter.BackBufferWidth = iHres; + ms_d3dPresentParameter.BackBufferHeight = iVres; + ms_d3dPresentParameter.hDeviceWindow = hWnd; + ms_d3dPresentParameter.BackBufferCount = m_uBackBufferCount; + ms_d3dPresentParameter.SwapEffect = D3DSWAPEFFECT_DISCARD; + + if (Windowed) + { + ms_d3dPresentParameter.BackBufferFormat = pkD3DAdapterInfo->GetDesktopD3DDisplayModer().Format; + } + else + { + ms_d3dPresentParameter.BackBufferFormat = pkD3DModeInfo->m_eD3DFmtPixel; + ms_d3dPresentParameter.FullScreen_RefreshRateInHz = iReflashRate; + } + + ms_d3dPresentParameter.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; + ms_d3dPresentParameter.EnableAutoDepthStencil = TRUE; + ms_d3dPresentParameter.AutoDepthStencilFormat = pkD3DModeInfo->m_eD3DFmtDepthStencil; + + ms_dwD3DBehavior = pkD3DModeInfo->m_dwD3DBehavior; + + if (FAILED(ms_hLastResult = ms_lpd3d->CreateDevice( + ms_iD3DAdapterInfo, + D3DDEVTYPE_HAL, + hWnd, + // 2004. 1. 9 myevan ؽ μ ڵ ߰ + pkD3DModeInfo->m_dwD3DBehavior, + &ms_d3dPresentParameter, + &ms_lpd3dDevice))) + { + switch (ms_hLastResult) + { + case D3DERR_INVALIDCALL: + Tracen("IDirect3DDevice.CreateDevice - ERROR D3DERR_INVALIDCALL\nThe method call is invalid. For example, a method's parameter may have an invalid value."); + break; + case D3DERR_NOTAVAILABLE: + Tracen("IDirect3DDevice.CreateDevice - ERROR D3DERR_NOTAVAILABLE\nThis device does not support the queried technique. "); + break; + case D3DERR_OUTOFVIDEOMEMORY: + Tracen("IDirect3DDevice.CreateDevice - ERROR D3DERR_OUTOFVIDEOMEMORY\nDirect3D does not have enough display memory to perform the operation"); + break; + default: + Tracenf("IDirect3DDevice.CreateDevice - ERROR %d", ms_hLastResult); + break; + } + + if (ErrorCorrection) + return CREATE_DEVICE; + + // 2004. 1. 9 myevan ūǹ ڵε.. ǥϰ + iReflashRate = 0; + ++ErrorCorrection; + iRet = CREATE_REFRESHRATE; + goto RETRY; + } + + // Check DXT Support Info + if(ms_lpd3d->CheckDeviceFormat( + ms_iD3DAdapterInfo, + D3DDEVTYPE_HAL, + ms_d3dPresentParameter.BackBufferFormat, + 0, + D3DRTYPE_TEXTURE, + D3DFMT_DXT1) == D3DERR_NOTAVAILABLE) + { + ms_bSupportDXT = false; + } + + if(ms_lpd3d->CheckDeviceFormat( + ms_iD3DAdapterInfo, + D3DDEVTYPE_HAL, + ms_d3dPresentParameter.BackBufferFormat, + 0, + D3DRTYPE_TEXTURE, + D3DFMT_DXT3) == D3DERR_NOTAVAILABLE) + { + ms_bSupportDXT = false; + } + + if(ms_lpd3d->CheckDeviceFormat( + ms_iD3DAdapterInfo, + D3DDEVTYPE_HAL, + ms_d3dPresentParameter.BackBufferFormat, + 0, + D3DRTYPE_TEXTURE, + D3DFMT_DXT5) == D3DERR_NOTAVAILABLE) + { + ms_bSupportDXT = false; + } + + if (FAILED((ms_hLastResult = ms_lpd3dDevice->GetDeviceCaps(&ms_d3dCaps)))) + { + Tracenf("IDirect3DDevice.GetDeviceCaps - ERROR %d", ms_hLastResult); + return CREATE_GET_DEVICE_CAPS2; + } + + if (!Windowed) + SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, iHres, iVres, SWP_SHOWWINDOW); + + //Tracef("vertex shader version : %X\n",(DWORD)ms_d3dCaps.VertexShaderVersion); + + ms_lpd3dDevice->GetViewport(&ms_Viewport); + + m_pStateManager = new CStateManager(ms_lpd3dDevice); + + D3DXCreateMatrixStack(0, &ms_lpd3dMatStack); + ms_lpd3dMatStack->LoadIdentity(); + + ms_ptVS = CreatePTStreamVertexShader(); + ms_pntVS = CreatePNTStreamVertexShader(); + ms_pnt2VS = CreatePNT2StreamVertexShader(); + + D3DXMatrixIdentity(&ms_matIdentity); + D3DXMatrixIdentity(&ms_matView); + D3DXMatrixIdentity(&ms_matProj); + D3DXMatrixIdentity(&ms_matInverseView); + D3DXMatrixIdentity(&ms_matInverseViewYAxis); + D3DXMatrixIdentity(&ms_matScreen0); + D3DXMatrixIdentity(&ms_matScreen1); + D3DXMatrixIdentity(&ms_matScreen2); + + ms_matScreen0._11 = 1; + ms_matScreen0._22 = -1; + + ms_matScreen1._41 = 1; + ms_matScreen1._42 = 1; + + ms_matScreen2._11 = (float) iHres / 2; + ms_matScreen2._22 = (float) iVres / 2; + + D3DXCreateSphere(ms_lpd3dDevice, 1.0f, 32, 32, &ms_lpSphereMesh, NULL); + D3DXCreateCylinder(ms_lpd3dDevice, 1.0f, 1.0f, 1.0f, 8, 8, &ms_lpCylinderMesh, NULL); + + ms_lpd3dDevice->Clear(0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0); + + if (!__CreateDefaultIndexBufferList()) + return false; + + if (!__CreatePDTVertexBufferList()) + return false; + + DWORD dwTexMemSize = GetAvailableTextureMemory(); + + if (dwTexMemSize < 64 * 1024 * 1024) + ms_isLowTextureMemory = true; + else + ms_isLowTextureMemory = false; + + if (dwTexMemSize > 100 * 1024 * 1024) + ms_isHighTextureMemory = true; + else + ms_isHighTextureMemory = false; + + if (ms_d3dCaps.TextureAddressCaps & D3DPTADDRESSCAPS_BORDER) + GRAPHICS_CAPS_CAN_NOT_TEXTURE_ADDRESS_BORDER=false; + else + GRAPHICS_CAPS_CAN_NOT_TEXTURE_ADDRESS_BORDER=true; + + //D3DADAPTER_IDENTIFIER8& rkD3DAdapterId=pkD3DAdapterInfo->GetIdentifier(); + if (strnicmp(rkD3DAdapterId.Driver, "SIS", 3) == 0) + { + GRAPHICS_CAPS_CAN_NOT_DRAW_LINE = true; + GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW = true; + GRAPHICS_CAPS_HALF_SIZE_IMAGE = true; + ms_isLowTextureMemory = true; + } + else if (strnicmp(rkD3DAdapterId.Driver, "3dfx", 4) == 0) + { + GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW = true; + GRAPHICS_CAPS_HALF_SIZE_IMAGE = true; + ms_isLowTextureMemory = true; + } + + return (iRet); +} + +void CGraphicDevice::__InitializePDTVertexBufferList() +{ + for (UINT i=0; iRelease(); + ms_alpd3dPDTVB[i]=NULL; + } + } +} + +bool CGraphicDevice::__CreatePDTVertexBufferList() +{ + for (UINT i=0; iCreateVertexBuffer( + sizeof(TPDTVertex)*PDT_VERTEX_NUM, + D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY, + D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, + D3DPOOL_SYSTEMMEM, + &ms_alpd3dPDTVB[i]) + )) + return false; + } + return true; +} + +void CGraphicDevice::__InitializeDefaultIndexBufferList() +{ + for (UINT i=0; iRelease(); + ms_alpd3dDefIB[i]=NULL; + } +} + +bool CGraphicDevice::__CreateDefaultIndexBuffer(UINT eDefIB, UINT uIdxCount, const WORD* c_awIndices) +{ + assert(ms_alpd3dDefIB[eDefIB]==NULL); + + if (FAILED( + ms_lpd3dDevice->CreateIndexBuffer( + sizeof(WORD)*uIdxCount, + D3DUSAGE_WRITEONLY, + D3DFMT_INDEX16, + D3DPOOL_MANAGED, + &ms_alpd3dDefIB[eDefIB]) + )) return false; + + WORD* dstIndices; + if (FAILED( + ms_alpd3dDefIB[eDefIB]->Lock(0, 0, (BYTE**)&dstIndices, 0) + )) return false; + + memcpy(dstIndices, c_awIndices, sizeof(WORD)*uIdxCount); + + ms_alpd3dDefIB[eDefIB]->Unlock(); + + return true; +} + +bool CGraphicDevice::__CreateDefaultIndexBufferList() +{ + static const WORD c_awLineIndices[2] = { 0, 1, }; + static const WORD c_awLineTriIndices[6] = { 0, 1, 0, 2, 1, 2, }; + static const WORD c_awLineRectIndices[8] = { 0, 1, 0, 2, 1, 3, 2, 3,}; + static const WORD c_awLineCubeIndices[24] = { + 0, 1, 0, 2, 1, 3, 2, 3, + 0, 4, 1, 5, 2, 6, 3, 7, + 4, 5, 4, 6, 5, 7, 6, 7, + }; + static const WORD c_awFillTriIndices[3]= { 0, 1, 2, }; + static const WORD c_awFillRectIndices[6] = { 0, 2, 1, 2, 3, 1, }; + static const WORD c_awFillCubeIndices[36] = { + 0, 1, 2, 1, 3, 2, + 2, 0, 6, 0, 4, 6, + 0, 1, 4, 1, 5, 4, + 1, 3, 5, 3, 7, 5, + 3, 2, 7, 2, 6, 7, + 4, 5, 6, 5, 7, 6, + }; + + if (!__CreateDefaultIndexBuffer(DEFAULT_IB_LINE, 2, c_awLineIndices)) + return false; + if (!__CreateDefaultIndexBuffer(DEFAULT_IB_LINE_TRI, 6, c_awLineTriIndices)) + return false; + if (!__CreateDefaultIndexBuffer(DEFAULT_IB_LINE_RECT, 8, c_awLineRectIndices)) + return false; + if (!__CreateDefaultIndexBuffer(DEFAULT_IB_LINE_CUBE, 24, c_awLineCubeIndices)) + return false; + if (!__CreateDefaultIndexBuffer(DEFAULT_IB_FILL_TRI, 3, c_awFillTriIndices)) + return false; + if (!__CreateDefaultIndexBuffer(DEFAULT_IB_FILL_RECT, 6, c_awFillRectIndices)) + return false; + if (!__CreateDefaultIndexBuffer(DEFAULT_IB_FILL_CUBE, 36, c_awFillCubeIndices)) + return false; + + return true; +} + +void CGraphicDevice::InitBackBufferCount(UINT uBackBufferCount) +{ + m_uBackBufferCount=uBackBufferCount; +} + +void CGraphicDevice::Destroy() +{ + __DestroyPDTVertexBufferList(); + __DestroyDefaultIndexBufferList(); + + if (ms_hDC) + { + ReleaseDC(ms_hWnd, ms_hDC); + ms_hDC = NULL; + } + + if (ms_ptVS) + { + ms_lpd3dDevice->DeleteVertexShader(ms_ptVS); + ms_ptVS = 0;; + } + + if (ms_pntVS) + { + ms_lpd3dDevice->DeleteVertexShader(ms_pntVS); + ms_pntVS = 0; + } + + if (ms_pnt2VS) + { + ms_lpd3dDevice->DeleteVertexShader(ms_pnt2VS); + ms_pnt2VS = 0; + } + + safe_release(ms_lpSphereMesh); + safe_release(ms_lpCylinderMesh); + + safe_release(ms_lpd3dMatStack); + safe_release(ms_lpd3dDevice); + safe_release(ms_lpd3d); + + if (m_pStateManager) + { + delete m_pStateManager; + m_pStateManager = NULL; + } + + __Initialize(); +} diff --git a/source/EterLib/GrpDevice.h b/source/EterLib/GrpDevice.h new file mode 100644 index 0000000..7015274 --- /dev/null +++ b/source/EterLib/GrpDevice.h @@ -0,0 +1,74 @@ +#pragma once + +#include "GrpBase.h" +#include "GrpDetector.h" +#include "StateManager.h" + +class CGraphicDevice : public CGraphicBase +{ +public: + enum EDeviceState + { + DEVICESTATE_OK, + DEVICESTATE_BROKEN, + DEVICESTATE_NEEDS_RESET, + DEVICESTATE_NULL + }; + + enum ECreateReturnValues + { + CREATE_OK = (1 << 0), + CREATE_NO_DIRECTX = (1 << 1), + CREATE_GET_DEVICE_CAPS = (1 << 2), + CREATE_GET_DEVICE_CAPS2 = (1 << 3), + CREATE_DEVICE = (1 << 4), + CREATE_REFRESHRATE = (1 << 5), + CREATE_ENUM = (1 << 6), // 2003. 01. 09. myevan Ʈ + CREATE_DETECT = (1 << 7), // 2003. 01. 09. myevan + CREATE_NO_TNL = (1 << 8), + CREATE_BAD_DRIVER = (1 << 9), + CREATE_FORMAT = (1 << 10), + }; + + CGraphicDevice(); + virtual ~CGraphicDevice(); + + void InitBackBufferCount(UINT uBackBufferCount); + + void Destroy(); + int Create(HWND hWnd, int hres, int vres, bool Windowed = true, int bit = 32, int ReflashRate = 0); + + EDeviceState GetDeviceState(); + bool Reset(); + + void EnableWebBrowserMode(const RECT& c_rcWebPage); + void DisableWebBrowserMode(); + void MoveWebBrowserRect(const RECT& c_rcWebPage); + + bool ResizeBackBuffer(UINT uWidth, UINT uHeight); + void RegisterWarningString(UINT uiMsg, const char * c_szString); + +protected: + void __Initialize(); + bool __IsInDriverBlackList(D3D_CAdapterInfo& rkD3DAdapterInfo); + void __WarningMessage(HWND hWnd, UINT uiMsg); + + void __InitializeDefaultIndexBufferList(); + void __DestroyDefaultIndexBufferList(); + bool __CreateDefaultIndexBufferList(); + bool __CreateDefaultIndexBuffer(UINT eDefIB, UINT uIdxCount, const WORD* c_awIndices); + + void __InitializePDTVertexBufferList(); + void __DestroyPDTVertexBufferList(); + bool __CreatePDTVertexBufferList(); + + DWORD CreatePTStreamVertexShader(); + DWORD CreatePNTStreamVertexShader(); + DWORD CreatePNT2StreamVertexShader(); + DWORD CreateDoublePNTStreamVertexShader(); + +protected: + DWORD m_uBackBufferCount; + std::map m_kMap_strWarningMessage; + CStateManager* m_pStateManager; +}; diff --git a/source/EterLib/GrpExpandedImageInstance.cpp b/source/EterLib/GrpExpandedImageInstance.cpp new file mode 100644 index 0000000..1398b86 --- /dev/null +++ b/source/EterLib/GrpExpandedImageInstance.cpp @@ -0,0 +1,236 @@ +#include "StdAfx.h" +#include "../eterBase/CRC32.h" +#include "GrpExpandedImageInstance.h" +#include "StateManager.h" + +CDynamicPool CGraphicExpandedImageInstance::ms_kPool; + +void CGraphicExpandedImageInstance::CreateSystem(UINT uCapacity) +{ + ms_kPool.Create(uCapacity); +} + +void CGraphicExpandedImageInstance::DestroySystem() +{ + ms_kPool.Destroy(); +} + +CGraphicExpandedImageInstance* CGraphicExpandedImageInstance::New() +{ + return ms_kPool.Alloc(); +} + +void CGraphicExpandedImageInstance::Delete(CGraphicExpandedImageInstance* pkImgInst) +{ + pkImgInst->Destroy(); + ms_kPool.Free(pkImgInst); +} + +void CGraphicExpandedImageInstance::OnRender() +{ + CGraphicImage * pImage = m_roImage.GetPointer(); + CGraphicTexture * pTexture = pImage->GetTexturePointer(); + + const RECT& c_rRect = pImage->GetRectReference(); + float texReverseWidth = 1.0f / float(pTexture->GetWidth()); + float texReverseHeight = 1.0f / float(pTexture->GetHeight()); + float su = (c_rRect.left - m_RenderingRect.left) * texReverseWidth; + float sv = (c_rRect.top - m_RenderingRect.top) * texReverseHeight; + float eu = (c_rRect.left + m_RenderingRect.right + (c_rRect.right-c_rRect.left)) * texReverseWidth; + float ev = (c_rRect.top + m_RenderingRect.bottom + (c_rRect.bottom-c_rRect.top)) * texReverseHeight; + + TPDTVertex vertices[4]; + vertices[0].position.x = m_v2Position.x-0.5f; + vertices[0].position.y = m_v2Position.y-0.5f; + vertices[0].position.z = m_fDepth; + vertices[0].texCoord = TTextureCoordinate(su, sv); + vertices[0].diffuse = m_DiffuseColor; + + vertices[1].position.x = m_v2Position.x-0.5f; + vertices[1].position.y = m_v2Position.y-0.5f; + vertices[1].position.z = m_fDepth; + vertices[1].texCoord = TTextureCoordinate(eu, sv); + vertices[1].diffuse = m_DiffuseColor; + + vertices[2].position.x = m_v2Position.x-0.5f; + vertices[2].position.y = m_v2Position.y-0.5f; + vertices[2].position.z = m_fDepth; + vertices[2].texCoord = TTextureCoordinate(su, ev); + vertices[2].diffuse = m_DiffuseColor; + + vertices[3].position.x = m_v2Position.x-0.5f; + vertices[3].position.y = m_v2Position.y-0.5f; + vertices[3].position.z = m_fDepth; + vertices[3].texCoord = TTextureCoordinate(eu, ev); + vertices[3].diffuse = m_DiffuseColor; + + if (0.0f == m_fRotation) + { + float fimgWidth = float(pImage->GetWidth()) * m_v2Scale.x; + float fimgHeight = float(pImage->GetHeight()) * m_v2Scale.y; + + vertices[0].position.x -= m_RenderingRect.left; + vertices[0].position.y -= m_RenderingRect.top; + vertices[1].position.x += fimgWidth + m_RenderingRect.right; + vertices[1].position.y -= m_RenderingRect.top; + vertices[2].position.x -= m_RenderingRect.left; + vertices[2].position.y += fimgHeight + m_RenderingRect.bottom; + vertices[3].position.x += fimgWidth + m_RenderingRect.right; + vertices[3].position.y += fimgHeight + m_RenderingRect.bottom; + if ((0.0f < m_v2Scale.x && 0.0f > m_v2Scale.y) || (0.0f > m_v2Scale.x && 0.0f < m_v2Scale.y)) { + STATEMANAGER.SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); + } + } + else + { + float fimgHalfWidth = float(pImage->GetWidth())/2.0f * m_v2Scale.x; + float fimgHalfHeight = float(pImage->GetHeight())/2.0f * m_v2Scale.y; + + for (int i = 0; i < 4; ++i) + { + vertices[i].position.x += m_v2Origin.x; + vertices[i].position.y += m_v2Origin.y; + } + + float fRadian = D3DXToRadian(m_fRotation); + vertices[0].position.x += (-fimgHalfWidth*cosf(fRadian)) - (-fimgHalfHeight*sinf(fRadian)); + vertices[0].position.y += (-fimgHalfWidth*sinf(fRadian)) + (-fimgHalfHeight*cosf(fRadian)); + vertices[1].position.x += (+fimgHalfWidth*cosf(fRadian)) - (-fimgHalfHeight*sinf(fRadian)); + vertices[1].position.y += (+fimgHalfWidth*sinf(fRadian)) + (-fimgHalfHeight*cosf(fRadian)); + vertices[2].position.x += (-fimgHalfWidth*cosf(fRadian)) - (+fimgHalfHeight*sinf(fRadian)); + vertices[2].position.y += (-fimgHalfWidth*sinf(fRadian)) + (+fimgHalfHeight*cosf(fRadian)); + vertices[3].position.x += (+fimgHalfWidth*cosf(fRadian)) - (+fimgHalfHeight*sinf(fRadian)); + vertices[3].position.y += (+fimgHalfWidth*sinf(fRadian)) + (+fimgHalfHeight*cosf(fRadian)); + } + + switch (m_iRenderingMode) + { + case RENDERING_MODE_SCREEN: + case RENDERING_MODE_COLOR_DODGE: + STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_INVDESTCOLOR); + STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); + break; + case RENDERING_MODE_MODULATE: + STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); + STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR); + break; + } + + // 2004.11.18.myevan.ctrl+alt+del ݺ ƨ + if (CGraphicBase::SetPDTStream(vertices, 4)) + { + CGraphicBase::SetDefaultIndexBuffer(CGraphicBase::DEFAULT_IB_FILL_RECT); + + STATEMANAGER.SetTexture(0, pTexture->GetD3DTexture()); + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 4, 0, 2); + } + //STATEMANAGER.DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, c_FillRectIndices, D3DFMT_INDEX16, vertices, sizeof(TPDTVertex)); + ///////////////////////////////////////////////////////////// + + switch (m_iRenderingMode) + { + case RENDERING_MODE_SCREEN: + case RENDERING_MODE_COLOR_DODGE: + case RENDERING_MODE_MODULATE: + STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND); + STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND); + break; + } + STATEMANAGER.SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); +} + +void CGraphicExpandedImageInstance::SetDepth(float fDepth) +{ + m_fDepth = fDepth; +} + +void CGraphicExpandedImageInstance::SetOrigin() +{ + SetOrigin(float(GetWidth()) / 2.0f, float(GetHeight()) / 2.0f); +} + +void CGraphicExpandedImageInstance::SetOrigin(float fx, float fy) +{ + m_v2Origin.x = fx; + m_v2Origin.y = fy; +} + +void CGraphicExpandedImageInstance::SetRotation(float fRotation) +{ + m_fRotation = fRotation; +} + +void CGraphicExpandedImageInstance::SetScale(float fx, float fy) +{ + m_v2Scale.x = fx; + m_v2Scale.y = fy; +} + +void CGraphicExpandedImageInstance::SetRenderingRect(float fLeft, float fTop, float fRight, float fBottom) +{ + if (IsEmpty()) + return; + + float fWidth = float(GetWidth()); + float fHeight = float(GetHeight()); + + m_RenderingRect.left = fWidth * fLeft; + m_RenderingRect.top = fHeight * fTop; + m_RenderingRect.right = fWidth * fRight; + m_RenderingRect.bottom = fHeight * fBottom; +} + +void CGraphicExpandedImageInstance::SetRenderingMode(int iMode) +{ + m_iRenderingMode = iMode; +} + +DWORD CGraphicExpandedImageInstance::Type() +{ + static DWORD s_dwType = GetCRC32("CGraphicExpandedImageInstance", strlen("CGraphicExpandedImageInstance")); + return (s_dwType); +} + +void CGraphicExpandedImageInstance::OnSetImagePointer() +{ + if (IsEmpty()) + return; + + SetOrigin(float(GetWidth()) / 2.0f, float(GetHeight()) / 2.0f); +} + +BOOL CGraphicExpandedImageInstance::OnIsType(DWORD dwType) +{ + if (CGraphicExpandedImageInstance::Type() == dwType) + return TRUE; + + return CGraphicImageInstance::IsType(dwType); +} + +void CGraphicExpandedImageInstance::Initialize() +{ + m_iRenderingMode = RENDERING_MODE_NORMAL; + m_fDepth = 0.0f; + m_v2Origin.x = m_v2Origin.y = 0.0f; + m_v2Scale.x = m_v2Scale.y = 1.0f; + m_fRotation = 0.0f; + memset(&m_RenderingRect, 0, sizeof(RECT)); +} + +void CGraphicExpandedImageInstance::Destroy() +{ + CGraphicImageInstance::Destroy(); + Initialize(); +} + +CGraphicExpandedImageInstance::CGraphicExpandedImageInstance() +{ + Initialize(); +} + +CGraphicExpandedImageInstance::~CGraphicExpandedImageInstance() +{ + Destroy(); +} diff --git a/source/EterLib/GrpExpandedImageInstance.h b/source/EterLib/GrpExpandedImageInstance.h new file mode 100644 index 0000000..b22ff00 --- /dev/null +++ b/source/EterLib/GrpExpandedImageInstance.h @@ -0,0 +1,61 @@ +#pragma once + +#include "GrpImageInstance.h" + +class CGraphicExpandedImageInstance : public CGraphicImageInstance +{ + public: + static DWORD Type(); + static void DeleteExpandedImageInstance(CGraphicExpandedImageInstance * pkInstance) + { + pkInstance->Destroy(); + ms_kPool.Free(pkInstance); + } + + enum ERenderingMode + { + RENDERING_MODE_NORMAL, + RENDERING_MODE_SCREEN, + RENDERING_MODE_COLOR_DODGE, + RENDERING_MODE_MODULATE, + }; + + public: + CGraphicExpandedImageInstance(); + virtual ~CGraphicExpandedImageInstance(); + + void Destroy(); + + void SetDepth(float fDepth); + void SetOrigin(); + void SetOrigin(float fx, float fy); + void SetRotation(float fRotation); + void SetScale(float fx, float fy); + void SetRenderingRect(float fLeft, float fTop, float fRight, float fBottom); + void SetRenderingMode(int iMode); + + protected: + void Initialize(); + + void OnRender(); + void OnSetImagePointer(); + + BOOL OnIsType(DWORD dwType); + + protected: + float m_fDepth; + D3DXVECTOR2 m_v2Origin; + D3DXVECTOR2 m_v2Scale; + float m_fRotation; + RECT m_RenderingRect; + int m_iRenderingMode; + + public: + static void CreateSystem(UINT uCapacity); + static void DestroySystem(); + + static CGraphicExpandedImageInstance* New(); + static void Delete(CGraphicExpandedImageInstance* pkImgInst); + + static CDynamicPool ms_kPool; +}; diff --git a/source/EterLib/GrpFontTexture.cpp b/source/EterLib/GrpFontTexture.cpp new file mode 100644 index 0000000..b5a3782 --- /dev/null +++ b/source/EterLib/GrpFontTexture.cpp @@ -0,0 +1,314 @@ +#include "StdAfx.h" +#include "GrpText.h" +#include "../eterBase/Stl.h" + +#include "Util.h" + +CGraphicFontTexture::CGraphicFontTexture() +{ + Initialize(); +} + +CGraphicFontTexture::~CGraphicFontTexture() +{ + Destroy(); +} + +void CGraphicFontTexture::Initialize() +{ + CGraphicTexture::Initialize(); + m_hFontOld = NULL; + m_hFont = NULL; + m_isDirty = false; + m_bItalic = false; +} + +bool CGraphicFontTexture::IsEmpty() const +{ + return m_fontMap.size() == 0; +} + +void CGraphicFontTexture::Destroy() +{ + HDC hDC = m_dib.GetDCHandle(); + if (hDC) + SelectObject(hDC, m_hFontOld); + + m_dib.Destroy(); + + m_lpd3dTexture = NULL; + CGraphicTexture::Destroy(); + stl_wipe(m_pFontTextureVector); + m_charInfoMap.clear(); + + if (m_fontMap.size()) + { + TFontMap::iterator i = m_fontMap.begin(); + + while(i != m_fontMap.end()) + { + DeleteObject((HGDIOBJ)i->second); + ++i; + } + + m_fontMap.clear(); + } + + Initialize(); +} + +bool CGraphicFontTexture::CreateDeviceObjects() +{ + return true; +} + +void CGraphicFontTexture::DestroyDeviceObjects() +{ +} + +bool CGraphicFontTexture::Create(const char* c_szFontName, int fontSize, bool bItalic) +{ + Destroy(); + + strncpy(m_fontName, c_szFontName, sizeof(m_fontName)-1); + m_fontSize = fontSize; + m_bItalic = bItalic; + + m_x = 0; + m_y = 0; + m_step = 0; + + DWORD width = 256,height = 256; + if (GetMaxTextureWidth() > 512) + width = 512; + if (GetMaxTextureHeight() > 512) + height = 512; + + if (!m_dib.Create(ms_hDC, width, height)) + return false; + + HDC hDC = m_dib.GetDCHandle(); + + m_hFont = GetFont(GetDefaultCodePage()); + + m_hFontOld=(HFONT)SelectObject(hDC, m_hFont); + SetTextColor(hDC, RGB(255, 255, 255)); + SetBkColor(hDC, 0); + + if (!AppendTexture()) + return false; + + return true; +} + + + +HFONT CGraphicFontTexture::GetFont(WORD codePage) +{ + HFONT hFont = NULL; + TFontMap::iterator i = m_fontMap.find(codePage); + + if(i != m_fontMap.end()) + { + hFont = i->second; + } + else + { + LOGFONT logFont; + + memset(&logFont, 0, sizeof(LOGFONT)); + + logFont.lfHeight = m_fontSize; + logFont.lfEscapement = 0; + logFont.lfOrientation = 0; + logFont.lfWeight = FW_NORMAL; + logFont.lfItalic = (BYTE) m_bItalic; + logFont.lfUnderline = FALSE; + logFont.lfStrikeOut = FALSE; + logFont.lfCharSet = GetCharsetFromCodePage(codePage); + logFont.lfOutPrecision = OUT_DEFAULT_PRECIS; + logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; + logFont.lfQuality = ANTIALIASED_QUALITY; + logFont.lfPitchAndFamily = DEFAULT_PITCH; + //Tracenf("font: %s", GetFontFaceFromCodePage(codePage)); + strcpy(logFont.lfFaceName, m_fontName); //GetFontFaceFromCodePage(codePage)); + //strcpy(logFont.lfFaceName, GetFontFaceFromCodePage(codePage)); + + hFont = CreateFontIndirect(&logFont); + + m_fontMap.insert(TFontMap::value_type(codePage, hFont)); + } + + return hFont; +} + +bool CGraphicFontTexture::AppendTexture() +{ + CGraphicImageTexture * pNewTexture = new CGraphicImageTexture; + + if (!pNewTexture->Create(m_dib.GetWidth(), m_dib.GetHeight(), D3DFMT_A4R4G4B4)) + { + delete pNewTexture; + return false; + } + + m_pFontTextureVector.push_back(pNewTexture); + return true; +} + +bool CGraphicFontTexture::UpdateTexture() +{ + if(!m_isDirty) + return true; + + m_isDirty = false; + + CGraphicImageTexture * pFontTexture = m_pFontTextureVector.back(); + + if (!pFontTexture) + return false; + + WORD* pwDst; + int pitch; + + if (!pFontTexture->Lock(&pitch, (void**)&pwDst)) + return false; + + pitch /= 2; + + int width = m_dib.GetWidth(); + int height = m_dib.GetHeight(); + + DWORD * pdwSrc = (DWORD*)m_dib.GetPointer(); + + for (int y = 0; y < height; ++y, pwDst += pitch, pdwSrc += width) + for (int x = 0; x < width; ++x) + pwDst[x]=pdwSrc[x]; + + pFontTexture->Unlock(); + return true; +} + +CGraphicFontTexture::TCharacterInfomation* CGraphicFontTexture::GetCharacterInfomation(WORD codePage, wchar_t keyValue) +{ + TCharacterKey code(codePage, keyValue); + + TCharacterInfomationMap::iterator f = m_charInfoMap.find(code); + + if (m_charInfoMap.end() == f) + { + return UpdateCharacterInfomation(code); + } + else + { + return &f->second; + } +} + +CGraphicFontTexture::TCharacterInfomation* CGraphicFontTexture::UpdateCharacterInfomation(TCharacterKey code) +{ + HDC hDC = m_dib.GetDCHandle(); + SelectObject(hDC, GetFont(code.first)); + + wchar_t keyValue = code.second; + + if (keyValue == 0x08) + keyValue = L' '; // ٲ۴ (ƶ ½ : NAME:\tTEXT -> TEXT\t:NAME ȯ ) + + ABCFLOAT stABC; + SIZE size; + + if (!GetTextExtentPoint32W(hDC, &keyValue, 1, &size) || !GetCharABCWidthsFloatW(hDC, keyValue, keyValue, &stABC)) + return NULL; + + size.cx = stABC.abcfB; + if( stABC.abcfA > 0.0f ) + size.cx += ceilf(stABC.abcfA); + if( stABC.abcfC > 0.0f ) + size.cx += ceilf(stABC.abcfC); + size.cx++; + + LONG lAdvance = ceilf( stABC.abcfA + stABC.abcfB + stABC.abcfC ); + + int width = m_dib.GetWidth(); + int height = m_dib.GetHeight(); + + if (m_x + size.cx >= (width - 1)) + { + m_y += (m_step + 1); + m_step = 0; + m_x = 0; + + if (m_y + size.cy >= (height - 1)) + { + if (!UpdateTexture()) + { + return NULL; + } + + if (!AppendTexture()) + return NULL; + + m_y = 0; + } + } + + TextOutW(hDC, m_x, m_y, &keyValue, 1); + + int nChrX; + int nChrY; + int nChrWidth = size.cx; + int nChrHeight = size.cy; + int nDIBWidth = m_dib.GetWidth(); + + + DWORD*pdwDIBData=(DWORD*)m_dib.GetPointer(); + DWORD*pdwDIBBase=pdwDIBData+nDIBWidth*m_y+m_x; + DWORD*pdwDIBRow; + + pdwDIBRow=pdwDIBBase; + for (nChrY=0; nChrY(m_pFontTextureVector.size() - 1); + rNewCharInfo.width = size.cx; + rNewCharInfo.height = size.cy; + rNewCharInfo.left = float(m_x) * rhwidth; + rNewCharInfo.top = float(m_y) * rhheight; + rNewCharInfo.right = float(m_x+size.cx) * rhwidth; + rNewCharInfo.bottom = float(m_y+size.cy) * rhheight; + rNewCharInfo.advance = (float) lAdvance; + + m_x += size.cx; + + if (m_step < size.cy) + m_step = size.cy; + + m_isDirty = true; + + return &rNewCharInfo; +} + +bool CGraphicFontTexture::CheckTextureIndex(DWORD dwTexture) +{ + if (dwTexture >= m_pFontTextureVector.size()) + return false; + + return true; +} + +void CGraphicFontTexture::SelectTexture(DWORD dwTexture) +{ + assert(CheckTextureIndex(dwTexture)); + m_lpd3dTexture = m_pFontTextureVector[dwTexture]->GetD3DTexture(); +} diff --git a/source/EterLib/GrpFontTexture.h b/source/EterLib/GrpFontTexture.h new file mode 100644 index 0000000..56ae068 --- /dev/null +++ b/source/EterLib/GrpFontTexture.h @@ -0,0 +1,81 @@ +#pragma once + +#include "GrpTexture.h" +#include "GrpImageTexture.h" +#include "GrpDIB.h" + +#include +#include + +class CGraphicFontTexture : public CGraphicTexture +{ +public: + typedef std::pair TCharacterKey; + + typedef struct SCharacterInfomation + { + short index; + short width; + short height; + float left; + float top; + float right; + float bottom; + float advance; + } TCharacterInfomation; + + typedef std::vector TPCharacterInfomationVector; + +public: + CGraphicFontTexture(); + virtual ~CGraphicFontTexture(); + + void Destroy(); + bool Create(const char* c_szFontName, int fontSize, bool bItalic); + + bool CreateDeviceObjects(); + void DestroyDeviceObjects(); + + bool CheckTextureIndex(DWORD dwTexture); + void SelectTexture(DWORD dwTexture); + + bool UpdateTexture(); + + TCharacterInfomation* GetCharacterInfomation(WORD codePage, wchar_t keyValue); + TCharacterInfomation* UpdateCharacterInfomation(TCharacterKey code); + + bool IsEmpty() const; + +protected: + void Initialize(); + + bool AppendTexture(); + + HFONT GetFont(WORD codePage); + +protected: + typedef std::vector TGraphicImageTexturePointerVector; + typedef std::map TCharacterInfomationMap; + typedef std::map TFontMap; + +protected: + CGraphicDib m_dib; + + HFONT m_hFontOld; + HFONT m_hFont; + + TGraphicImageTexturePointerVector m_pFontTextureVector; + + TCharacterInfomationMap m_charInfoMap; + + TFontMap m_fontMap; + + int m_x; + int m_y; + int m_step; + bool m_isDirty; + + TCHAR m_fontName[LF_FACESIZE]; + LONG m_fontSize; + bool m_bItalic; +}; diff --git a/source/EterLib/GrpImage.cpp b/source/EterLib/GrpImage.cpp new file mode 100644 index 0000000..13d0fff --- /dev/null +++ b/source/EterLib/GrpImage.cpp @@ -0,0 +1,92 @@ +#include "StdAfx.h" +#include "GrpImage.h" + +CGraphicImage::CGraphicImage(const char * c_szFileName, DWORD dwFilter) : +CResource(c_szFileName), +m_dwFilter(dwFilter) +{ + m_rect.bottom = m_rect.right = m_rect.top = m_rect.left = 0; +} + +CGraphicImage::~CGraphicImage() +{ +} + +bool CGraphicImage::CreateDeviceObjects() +{ + return m_imageTexture.CreateDeviceObjects(); +} + +void CGraphicImage::DestroyDeviceObjects() +{ + m_imageTexture.DestroyDeviceObjects(); +} + +CGraphicImage::TType CGraphicImage::Type() +{ + static TType s_type = StringToType("CGraphicImage"); + return s_type; +} + +bool CGraphicImage::OnIsType(TType type) +{ + if (CGraphicImage::Type() == type) + return true; + + return CResource::OnIsType(type); +} + +int CGraphicImage::GetWidth() const +{ + return m_rect.right - m_rect.left; +} + +int CGraphicImage::GetHeight() const +{ + return m_rect.bottom - m_rect.top; +} + +const CGraphicTexture& CGraphicImage::GetTextureReference() const +{ + return m_imageTexture; +} + +CGraphicTexture* CGraphicImage::GetTexturePointer() +{ + return &m_imageTexture; +} + +const RECT& CGraphicImage::GetRectReference() const +{ + return m_rect; +} + +bool CGraphicImage::OnLoad(int iSize, const void * c_pvBuf) +{ + if (!c_pvBuf) + return false; + + m_imageTexture.SetFileName(CResource::GetFileName()); + + // Ư ǻͿ Unknown ''ϸ ƨ -_-; - + if (!m_imageTexture.CreateFromMemoryFile(iSize, c_pvBuf, D3DFMT_UNKNOWN, m_dwFilter)) + return false; + + m_rect.left = 0; + m_rect.top = 0; + m_rect.right = m_imageTexture.GetWidth(); + m_rect.bottom = m_imageTexture.GetHeight(); + return true; +} + +void CGraphicImage::OnClear() +{ +// Tracef("Image Destroy : %s\n", m_pszFileName); + m_imageTexture.Destroy(); + memset(&m_rect, 0, sizeof(m_rect)); +} + +bool CGraphicImage::OnIsEmpty() const +{ + return m_imageTexture.IsEmpty(); +} diff --git a/source/EterLib/GrpImage.h b/source/EterLib/GrpImage.h new file mode 100644 index 0000000..65d94f9 --- /dev/null +++ b/source/EterLib/GrpImage.h @@ -0,0 +1,44 @@ +#ifndef __INC_GRPIMAGE_H__ +#define __INC_GRPIMAGE_H__ + +#include "Ref.h" +#include "Resource.h" +#include "GrpImageTexture.h" + +class CGraphicImage : public CResource +{ + public: + typedef CRef TRef; + + public: + static TType Type(); + + public: + CGraphicImage(const char* c_szFileName, DWORD dwFilter = D3DX_FILTER_LINEAR); + virtual ~CGraphicImage(); + + virtual bool CreateDeviceObjects(); + virtual void DestroyDeviceObjects(); + + int GetWidth() const; + int GetHeight() const; + + const RECT & GetRectReference() const; + + const CGraphicTexture & GetTextureReference() const; + CGraphicTexture * GetTexturePointer(); + + protected: + bool OnLoad(int iSize, const void * c_pvBuf); + + void OnClear(); + bool OnIsEmpty() const; + bool OnIsType(TType type); + + protected: + CGraphicImageTexture m_imageTexture; + RECT m_rect; + DWORD m_dwFilter; +}; + +#endif diff --git a/source/EterLib/GrpImageInstance.cpp b/source/EterLib/GrpImageInstance.cpp new file mode 100644 index 0000000..31a903f --- /dev/null +++ b/source/EterLib/GrpImageInstance.cpp @@ -0,0 +1,222 @@ +#include "StdAfx.h" +#include "GrpImageInstance.h" +#include "StateManager.h" + +#include "../eterBase/CRC32.h" +//STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_INVDESTCOLOR); +//STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); +//STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND); +//STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND); + +CDynamicPool CGraphicImageInstance::ms_kPool; + +void CGraphicImageInstance::CreateSystem(UINT uCapacity) +{ + ms_kPool.Create(uCapacity); +} + +void CGraphicImageInstance::DestroySystem() +{ + ms_kPool.Destroy(); +} + +CGraphicImageInstance* CGraphicImageInstance::New() +{ + return ms_kPool.Alloc(); +} + +void CGraphicImageInstance::Delete(CGraphicImageInstance* pkImgInst) +{ + pkImgInst->Destroy(); + ms_kPool.Free(pkImgInst); +} + +void CGraphicImageInstance::Render() +{ + if (IsEmpty()) + return; + + assert(!IsEmpty()); + + OnRender(); +} + +void CGraphicImageInstance::OnRender() +{ + CGraphicImage * pImage = m_roImage.GetPointer(); + CGraphicTexture * pTexture = pImage->GetTexturePointer(); + + float fimgWidth = pImage->GetWidth(); + float fimgHeight = pImage->GetHeight(); + + const RECT& c_rRect = pImage->GetRectReference(); + float texReverseWidth = 1.0f / float(pTexture->GetWidth()); + float texReverseHeight = 1.0f / float(pTexture->GetHeight()); + float su = c_rRect.left * texReverseWidth; + float sv = c_rRect.top * texReverseHeight; + float eu = (c_rRect.left + (c_rRect.right-c_rRect.left)) * texReverseWidth; + float ev = (c_rRect.top + (c_rRect.bottom-c_rRect.top)) * texReverseHeight; + + + TPDTVertex vertices[4]; + vertices[0].position.x = m_v2Position.x-0.5f; + vertices[0].position.y = m_v2Position.y-0.5f; + vertices[0].position.z = 0.0f; + vertices[0].texCoord = TTextureCoordinate(su, sv); + vertices[0].diffuse = m_DiffuseColor; + + vertices[1].position.x = m_v2Position.x + fimgWidth-0.5f; + vertices[1].position.y = m_v2Position.y-0.5f; + vertices[1].position.z = 0.0f; + vertices[1].texCoord = TTextureCoordinate(eu, sv); + vertices[1].diffuse = m_DiffuseColor; + + vertices[2].position.x = m_v2Position.x-0.5f; + vertices[2].position.y = m_v2Position.y + fimgHeight-0.5f; + vertices[2].position.z = 0.0f; + vertices[2].texCoord = TTextureCoordinate(su, ev); + vertices[2].diffuse = m_DiffuseColor; + + vertices[3].position.x = m_v2Position.x + fimgWidth-0.5f; + vertices[3].position.y = m_v2Position.y + fimgHeight-0.5f; + vertices[3].position.z = 0.0f; + vertices[3].texCoord = TTextureCoordinate(eu, ev); + vertices[3].diffuse = m_DiffuseColor; + + // 2004.11.18.myevan.ctrl+alt+del ݺ ƨ + if (CGraphicBase::SetPDTStream(vertices, 4)) + { + CGraphicBase::SetDefaultIndexBuffer(CGraphicBase::DEFAULT_IB_FILL_RECT); + + STATEMANAGER.SetTexture(0, pTexture->GetD3DTexture()); + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 4, 0, 2); + } + //OLD: STATEMANAGER.DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, c_FillRectIndices, D3DFMT_INDEX16, vertices, sizeof(TPDTVertex)); + //////////////////////////////////////////////////////////// +} + +const CGraphicTexture & CGraphicImageInstance::GetTextureReference() const +{ + return m_roImage->GetTextureReference(); +} + +CGraphicTexture * CGraphicImageInstance::GetTexturePointer() +{ + CGraphicImage* pkImage = m_roImage.GetPointer(); + return pkImage ? pkImage->GetTexturePointer() : NULL; +} + +CGraphicImage * CGraphicImageInstance::GetGraphicImagePointer() +{ + return m_roImage.GetPointer(); +} + +int CGraphicImageInstance::GetWidth() +{ + if (IsEmpty()) + return 0; + + return m_roImage->GetWidth(); +} + +int CGraphicImageInstance::GetHeight() +{ + if (IsEmpty()) + return 0; + + return m_roImage->GetHeight(); +} + +void CGraphicImageInstance::SetDiffuseColor(float fr, float fg, float fb, float fa) +{ + m_DiffuseColor.r = fr; + m_DiffuseColor.g = fg; + m_DiffuseColor.b = fb; + m_DiffuseColor.a = fa; +} +void CGraphicImageInstance::SetPosition(float fx, float fy) +{ + m_v2Position.x = fx; + m_v2Position.y = fy; +} + +void CGraphicImageInstance::SetImagePointer(CGraphicImage * pImage) +{ + m_roImage.SetPointer(pImage); + + OnSetImagePointer(); +} + +void CGraphicImageInstance::ReloadImagePointer(CGraphicImage * pImage) +{ + if (m_roImage.IsNull()) + { + SetImagePointer(pImage); + return; + } + + CGraphicImage * pkImage = m_roImage.GetPointer(); + + if (pkImage) + pkImage->Reload(); +} + +bool CGraphicImageInstance::IsEmpty() const +{ + if (!m_roImage.IsNull() && !m_roImage->IsEmpty()) + return false; + + return true; +} + +bool CGraphicImageInstance::operator == (const CGraphicImageInstance & rhs) const +{ + return (m_roImage.GetPointer() == rhs.m_roImage.GetPointer()); +} + +DWORD CGraphicImageInstance::Type() +{ + static DWORD s_dwType = GetCRC32("CGraphicImageInstance", strlen("CGraphicImageInstance")); + return (s_dwType); +} + +BOOL CGraphicImageInstance::IsType(DWORD dwType) +{ + return OnIsType(dwType); +} + +BOOL CGraphicImageInstance::OnIsType(DWORD dwType) +{ + if (CGraphicImageInstance::Type() == dwType) + return TRUE; + + return FALSE; +} + +void CGraphicImageInstance::OnSetImagePointer() +{ +} + +void CGraphicImageInstance::Initialize() +{ + m_DiffuseColor.r = m_DiffuseColor.g = m_DiffuseColor.b = m_DiffuseColor.a = 1.0f; + m_v2Position.x = m_v2Position.y = 0.0f; +} + +void CGraphicImageInstance::Destroy() +{ + m_roImage.SetPointer(NULL); // CRef ۷ īƮ . + Initialize(); +} + +CGraphicImageInstance::CGraphicImageInstance() +{ + Initialize(); +} + +CGraphicImageInstance::~CGraphicImageInstance() +{ + Destroy(); +} diff --git a/source/EterLib/GrpImageInstance.h b/source/EterLib/GrpImageInstance.h new file mode 100644 index 0000000..4826d58 --- /dev/null +++ b/source/EterLib/GrpImageInstance.h @@ -0,0 +1,60 @@ +#pragma once + +#include "GrpImage.h" +#include "GrpIndexBuffer.h" +#include "GrpVertexBufferDynamic.h" +#include "Pool.h" + +class CGraphicImageInstance +{ + public: + static DWORD Type(); + BOOL IsType(DWORD dwType); + + public: + CGraphicImageInstance(); + virtual ~CGraphicImageInstance(); + + void Destroy(); + + void Render(); + + void SetDiffuseColor(float fr, float fg, float fb, float fa); + void SetPosition(float fx, float fy); + + void SetImagePointer(CGraphicImage* pImage); + void ReloadImagePointer(CGraphicImage* pImage); + bool IsEmpty() const; + + int GetWidth(); + int GetHeight(); + + CGraphicTexture * GetTexturePointer(); + const CGraphicTexture & GetTextureReference() const; + CGraphicImage * GetGraphicImagePointer(); + + bool operator == (const CGraphicImageInstance & rhs) const; + + protected: + void Initialize(); + + virtual void OnRender(); + virtual void OnSetImagePointer(); + + virtual BOOL OnIsType(DWORD dwType); + + protected: + D3DXCOLOR m_DiffuseColor; + D3DXVECTOR2 m_v2Position; + + CGraphicImage::TRef m_roImage; + + public: + static void CreateSystem(UINT uCapacity); + static void DestroySystem(); + + static CGraphicImageInstance* New(); + static void Delete(CGraphicImageInstance* pkImgInst); + + static CDynamicPool ms_kPool; +}; diff --git a/source/EterLib/GrpImageTexture.cpp b/source/EterLib/GrpImageTexture.cpp new file mode 100644 index 0000000..488fa5e --- /dev/null +++ b/source/EterLib/GrpImageTexture.cpp @@ -0,0 +1,329 @@ +#include "StdAfx.h" +#include "../eterBase/MappedFile.h" +#include "../eterPack/EterPackManager.h" +#include "GrpImageTexture.h" + +bool CGraphicImageTexture::Lock(int* pRetPitch, void** ppRetPixels, int level) +{ + D3DLOCKED_RECT lockedRect; + if (FAILED(m_lpd3dTexture->LockRect(level, &lockedRect, NULL, 0))) + return false; + + *pRetPitch = lockedRect.Pitch; + *ppRetPixels = (void*)lockedRect.pBits; + return true; +} + +void CGraphicImageTexture::Unlock(int level) +{ + assert(m_lpd3dTexture != NULL); + m_lpd3dTexture->UnlockRect(level); +} + +void CGraphicImageTexture::Initialize() +{ + CGraphicTexture::Initialize(); + + m_stFileName = ""; + + m_d3dFmt=D3DFMT_UNKNOWN; + m_dwFilter=0; +} + +void CGraphicImageTexture::Destroy() +{ + CGraphicTexture::Destroy(); + + Initialize(); +} + +bool CGraphicImageTexture::CreateDeviceObjects() +{ + assert(ms_lpd3dDevice != NULL); + assert(m_lpd3dTexture == NULL); + + if (m_stFileName.empty()) + { + // Ʈ ؽ + if (FAILED(ms_lpd3dDevice->CreateTexture(m_width, m_height, 1, 0, m_d3dFmt, D3DPOOL_MANAGED, &m_lpd3dTexture))) + return false; + } + else + { + CMappedFile mappedFile; + LPCVOID c_pvMap; + + if (!CEterPackManager::Instance().Get(mappedFile, m_stFileName.c_str(), &c_pvMap)) + return false; + + return CreateFromMemoryFile(mappedFile.Size(), c_pvMap, m_d3dFmt, m_dwFilter); + } + + m_bEmpty = false; + return true; +} + +bool CGraphicImageTexture::Create(UINT width, UINT height, D3DFORMAT d3dFmt, DWORD dwFilter) +{ + assert(ms_lpd3dDevice != NULL); + Destroy(); + + m_width = width; + m_height = height; + m_d3dFmt = d3dFmt; + m_dwFilter = dwFilter; + + return CreateDeviceObjects(); +} + +void CGraphicImageTexture::CreateFromTexturePointer(const CGraphicTexture * c_pSrcTexture) +{ + if (m_lpd3dTexture) + m_lpd3dTexture->Release(); + + m_width = c_pSrcTexture->GetWidth(); + m_height = c_pSrcTexture->GetHeight(); + m_lpd3dTexture = c_pSrcTexture->GetD3DTexture(); + + if (m_lpd3dTexture) + m_lpd3dTexture->AddRef(); + + m_bEmpty = false; +} + +bool CGraphicImageTexture::CreateDDSTexture(CDXTCImage & image, const BYTE * /*c_pbBuf*/) +{ + int mipmapCount = image.m_dwMipMapCount == 0 ? 1 : image.m_dwMipMapCount; + + D3DFORMAT format; + LPDIRECT3DTEXTURE8 lpd3dTexture; + D3DPOOL pool = ms_bSupportDXT ? D3DPOOL_MANAGED : D3DPOOL_SCRATCH;; + + if(image.m_CompFormat == PF_DXT5) + format = D3DFMT_DXT5; + else if(image.m_CompFormat == PF_DXT3) + format = D3DFMT_DXT3; + else + format = D3DFMT_DXT1; + + UINT uTexBias=0; + if (IsLowTextureMemory()) + uTexBias=1; + + UINT uMinMipMapIndex=0; + if (uTexBias>0) + { + if (mipmapCount>uTexBias) + { + uMinMipMapIndex=uTexBias; + image.m_nWidth>>=uTexBias; + image.m_nHeight>>=uTexBias; + mipmapCount-=uTexBias; + } + } + + if (FAILED(D3DXCreateTexture( ms_lpd3dDevice, image.m_nWidth, image.m_nHeight, + mipmapCount, 0, format, pool, &lpd3dTexture))) + { + TraceError("CreateDDSTexture: Cannot creatre texture"); + return false; + } + + for (DWORD i = 0; i < mipmapCount; ++i) + { + D3DLOCKED_RECT lockedRect; + + if (FAILED(lpd3dTexture->LockRect(i, &lockedRect, NULL, 0))) + { + TraceError("CreateDDSTexture: Cannot lock texture"); + } + else + { + image.Copy(i+uMinMipMapIndex, (BYTE*)lockedRect.pBits, lockedRect.Pitch); + lpd3dTexture->UnlockRect(i); + } + } + + if(ms_bSupportDXT) + { + m_lpd3dTexture = lpd3dTexture; + } + else + { + if(image.m_CompFormat == PF_DXT3 || image.m_CompFormat == PF_DXT5) + format = D3DFMT_A4R4G4B4; + else + format = D3DFMT_A1R5G5B5; + + UINT imgWidth=image.m_nWidth; + UINT imgHeight=image.m_nHeight; + + extern bool GRAPHICS_CAPS_HALF_SIZE_IMAGE; + + if (GRAPHICS_CAPS_HALF_SIZE_IMAGE && uTexBias>0 && mipmapCount==0) + { + imgWidth>>=uTexBias; + imgHeight>>=uTexBias; + } + + if (FAILED(D3DXCreateTexture( ms_lpd3dDevice, imgWidth, imgHeight, + mipmapCount, 0, format, D3DPOOL_MANAGED, &m_lpd3dTexture))) + { + TraceError("CreateDDSTexture: Cannot creatre texture"); + return false; + } + + IDirect3DTexture8* pkTexSrc=lpd3dTexture; + IDirect3DTexture8* pkTexDst=m_lpd3dTexture; + + for(int i=0; iGetSurfaceLevel(i, &ppsSrc))) + { + if (SUCCEEDED(pkTexDst->GetSurfaceLevel(i, &ppsDst))) + { + D3DXLoadSurfaceFromSurface(ppsDst, NULL, NULL, ppsSrc, NULL, NULL, D3DX_FILTER_NONE, 0); + ppsDst->Release(); + } + ppsSrc->Release(); + } + } + + lpd3dTexture->Release(); + } + + m_width = image.m_nWidth; + m_height = image.m_nHeight; + m_bEmpty = false; + + return true; +} + +bool CGraphicImageTexture::CreateFromMemoryFile(UINT bufSize, const void * c_pvBuf, D3DFORMAT d3dFmt, DWORD dwFilter) +{ + assert(ms_lpd3dDevice != NULL); + assert(m_lpd3dTexture == NULL); + + static CDXTCImage image; + + if (image.LoadHeaderFromMemory((const BYTE *) c_pvBuf)) // DDSΰ Ȯ + { + return (CreateDDSTexture(image, (const BYTE *) c_pvBuf)); + } + else + { + D3DXIMAGE_INFO imageInfo; + if (FAILED(D3DXCreateTextureFromFileInMemoryEx( + ms_lpd3dDevice, + c_pvBuf, + bufSize, + D3DX_DEFAULT, + D3DX_DEFAULT, + D3DX_DEFAULT, + 0, + d3dFmt, + D3DPOOL_MANAGED, + dwFilter, + dwFilter, + 0xffff00ff, + &imageInfo, + NULL, + &m_lpd3dTexture))) + { + TraceError("CreateFromMemoryFile: Cannot create texture"); + return false; + } + + m_width = imageInfo.Width; + m_height = imageInfo.Height; + + D3DFORMAT format=imageInfo.Format; + switch(imageInfo.Format) { + case D3DFMT_A8R8G8B8: + format = D3DFMT_A4R4G4B4; + break; + + case D3DFMT_X8R8G8B8: + case D3DFMT_R8G8B8: + format = D3DFMT_A1R5G5B5; + break; + } + + UINT uTexBias=0; + + extern bool GRAPHICS_CAPS_HALF_SIZE_IMAGE; + if (GRAPHICS_CAPS_HALF_SIZE_IMAGE) + uTexBias=1; + + if (IsLowTextureMemory()) + if (uTexBias || format!=imageInfo.Format) + { + IDirect3DTexture8* pkTexSrc=m_lpd3dTexture; + IDirect3DTexture8* pkTexDst; + + + if (SUCCEEDED(D3DXCreateTexture( + ms_lpd3dDevice, + imageInfo.Width>>uTexBias, + imageInfo.Height>>uTexBias, + imageInfo.MipLevels, + 0, + format, + D3DPOOL_MANAGED, + &pkTexDst))) + { + m_lpd3dTexture=pkTexDst; + + for(int i=0; iGetSurfaceLevel(i, &ppsSrc))) + { + if (SUCCEEDED(pkTexDst->GetSurfaceLevel(i, &ppsDst))) + { + D3DXLoadSurfaceFromSurface(ppsDst, NULL, NULL, ppsSrc, NULL, NULL, D3DX_FILTER_LINEAR, 0); + ppsDst->Release(); + } + ppsSrc->Release(); + } + } + + pkTexSrc->Release(); + } + } + } + + m_bEmpty = false; + return true; +} + +void CGraphicImageTexture::SetFileName(const char * c_szFileName) +{ + m_stFileName=c_szFileName; +} + +bool CGraphicImageTexture::CreateFromDiskFile(const char * c_szFileName, D3DFORMAT d3dFmt, DWORD dwFilter) +{ + Destroy(); + + SetFileName(c_szFileName); + + m_d3dFmt = d3dFmt; + m_dwFilter = dwFilter; + return CreateDeviceObjects(); +} + +CGraphicImageTexture::CGraphicImageTexture() +{ + Initialize(); +} + +CGraphicImageTexture::~CGraphicImageTexture() +{ + Destroy(); +} diff --git a/source/EterLib/GrpImageTexture.h b/source/EterLib/GrpImageTexture.h new file mode 100644 index 0000000..18f4588 --- /dev/null +++ b/source/EterLib/GrpImageTexture.h @@ -0,0 +1,34 @@ +#pragma once + +#include "GrpTexture.h" +#include "../eterImageLib/DXTCImage.h" + +class CGraphicImageTexture : public CGraphicTexture +{ + public: + CGraphicImageTexture(); + virtual ~CGraphicImageTexture(); + + void Destroy(); + + bool Create(UINT width, UINT height, D3DFORMAT d3dFmt, DWORD dwFilter = D3DX_FILTER_LINEAR); + bool CreateDeviceObjects(); + + void CreateFromTexturePointer(const CGraphicTexture* c_pSrcTexture); + bool CreateFromDiskFile(const char* c_szFileName, D3DFORMAT d3dFmt, DWORD dwFilter = D3DX_FILTER_LINEAR); + bool CreateFromMemoryFile(UINT bufSize, const void* c_pvBuf, D3DFORMAT d3dFmt, DWORD dwFilter = D3DX_FILTER_LINEAR); + bool CreateDDSTexture(CDXTCImage & image, const BYTE * c_pbBuf); + + void SetFileName(const char * c_szFileName); + + bool Lock(int* pRetPitch, void** ppRetPixels, int level=0); + void Unlock(int level=0); + + protected: + void Initialize(); + + D3DFORMAT m_d3dFmt; + DWORD m_dwFilter; + + std::string m_stFileName; +}; diff --git a/source/EterLib/GrpIndexBuffer.cpp b/source/EterLib/GrpIndexBuffer.cpp new file mode 100644 index 0000000..dcdfa2b --- /dev/null +++ b/source/EterLib/GrpIndexBuffer.cpp @@ -0,0 +1,139 @@ +#include "StdAfx.h" +#include "../eterBase/Stl.h" +#include "GrpIndexBuffer.h" +#include "StateManager.h" + +LPDIRECT3DINDEXBUFFER8 CGraphicIndexBuffer::GetD3DIndexBuffer() const +{ + assert(m_lpd3dIdxBuf!=NULL); + return m_lpd3dIdxBuf; +} + +void CGraphicIndexBuffer::SetIndices(int startIndex) const +{ + assert(ms_lpd3dDevice!=NULL); + STATEMANAGER.SetIndices(m_lpd3dIdxBuf, startIndex); +} + + +bool CGraphicIndexBuffer::Lock(void** pretIndices) const +{ + assert(m_lpd3dIdxBuf!=NULL); + + if (FAILED(m_lpd3dIdxBuf->Lock(0, 0, (BYTE**)pretIndices, 0))) + return false; + + return true; +} + +void CGraphicIndexBuffer::Unlock() const +{ + assert(m_lpd3dIdxBuf!=NULL); + + m_lpd3dIdxBuf->Unlock(); +} + +bool CGraphicIndexBuffer::Lock(void** pretIndices) +{ + assert(m_lpd3dIdxBuf!=NULL); + + if (FAILED(m_lpd3dIdxBuf->Lock(0, 0, (BYTE**)pretIndices, 0))) + return false; + + return true; +} + +void CGraphicIndexBuffer::Unlock() +{ + assert(m_lpd3dIdxBuf!=NULL); + + m_lpd3dIdxBuf->Unlock(); +} + +bool CGraphicIndexBuffer::Copy(int bufSize, const void* srcIndices) +{ + assert(m_lpd3dIdxBuf!=NULL); + + BYTE* dstIndices; + if (FAILED(m_lpd3dIdxBuf->Lock(0, 0, &dstIndices, 0))) + return false; + + memcpy(dstIndices, srcIndices, bufSize); + + m_lpd3dIdxBuf->Unlock(); + + return true; +} + +bool CGraphicIndexBuffer::Create(int faceCount, TFace* faces) +{ + int idxCount = faceCount * 3; + m_iidxCount = idxCount; + if (!Create(idxCount, D3DFMT_INDEX16)) + return false; + + WORD* dstIndices; + if (FAILED(m_lpd3dIdxBuf->Lock(0, 0, (BYTE**)&dstIndices, 0))) + return false; + + for (int i = 0; iindices[0]; + dstIndices[1]=curFace->indices[1]; + dstIndices[2]=curFace->indices[2]; + } + + m_lpd3dIdxBuf->Unlock(); + return true; +} + +bool CGraphicIndexBuffer::CreateDeviceObjects() +{ + if (FAILED(ms_lpd3dDevice->CreateIndexBuffer( + m_dwBufferSize, + D3DUSAGE_WRITEONLY, + m_d3dFmt, + D3DPOOL_MANAGED, + &m_lpd3dIdxBuf) + )) + return false; + + return true; +} + +void CGraphicIndexBuffer::DestroyDeviceObjects() +{ + safe_release(m_lpd3dIdxBuf); +} + +bool CGraphicIndexBuffer::Create(int idxCount, D3DFORMAT d3dFmt) +{ + Destroy(); + + m_iidxCount = idxCount; + m_dwBufferSize = sizeof(WORD) * idxCount; + m_d3dFmt = d3dFmt; + + return CreateDeviceObjects(); +} + +void CGraphicIndexBuffer::Destroy() +{ + DestroyDeviceObjects(); +} + +void CGraphicIndexBuffer::Initialize() +{ + m_lpd3dIdxBuf=NULL; +} + +CGraphicIndexBuffer::CGraphicIndexBuffer() +{ + Initialize(); +} + +CGraphicIndexBuffer::~CGraphicIndexBuffer() +{ + Destroy(); +} diff --git a/source/EterLib/GrpIndexBuffer.h b/source/EterLib/GrpIndexBuffer.h new file mode 100644 index 0000000..ba7cabb --- /dev/null +++ b/source/EterLib/GrpIndexBuffer.h @@ -0,0 +1,40 @@ +#pragma once + +#include "GrpBase.h" + +class CGraphicIndexBuffer : public CGraphicBase +{ + public: + CGraphicIndexBuffer(); + virtual ~CGraphicIndexBuffer(); + + void Destroy(); + bool Create(int idxCount, D3DFORMAT d3dFmt); + bool Create(int faceCount, TFace* faces); + + bool CreateDeviceObjects(); + void DestroyDeviceObjects(); + + bool Copy(int bufSize, const void* srcIndices); + + bool Lock(void** pretIndices) const; + void Unlock() const; + + bool Lock(void** pretIndices); + void Unlock(); + + void SetIndices(int startIndex=0) const; + + LPDIRECT3DINDEXBUFFER8 GetD3DIndexBuffer() const; + + int GetIndexCount() const {return m_iidxCount;} + + protected: + void Initialize(); + + protected: + LPDIRECT3DINDEXBUFFER8 m_lpd3dIdxBuf; + DWORD m_dwBufferSize; + D3DFORMAT m_d3dFmt; + int m_iidxCount; +}; diff --git a/source/EterLib/GrpLightManager.cpp b/source/EterLib/GrpLightManager.cpp new file mode 100644 index 0000000..f404ed0 --- /dev/null +++ b/source/EterLib/GrpLightManager.cpp @@ -0,0 +1,345 @@ +#include "StdAfx.h" +#include +#include "../eterBase/Timer.h" + +#include "GrpLightManager.h" +#include "StateManager.h" + +float CLightBase::ms_fCurTime = 0.0f; + +CLightManager::CLightManager() +{ + m_v3CenterPosition = D3DXVECTOR3(0.0f, 0.0f, 0.0f); + m_dwLimitLightCount = LIGHT_LIMIT_DEFAULT; +} + +CLightManager::~CLightManager() +{ +} + +void CLightManager::Destroy() +{ + m_LightPool.Destroy(); +} + +void CLightManager::Initialize() +{ + SetSkipIndex(1); + + m_NonUsingLightIDDeque.clear(); + + m_LightMap.clear(); + m_LightPool.FreeAll(); +} + +void CLightManager::RegisterLight(ELightType /*LightType*/, TLightID * poutLightID, D3DLIGHT8 & LightData) +{ + CLight * pLight = m_LightPool.Alloc(); + TLightID ID = NewLightID(); + pLight->SetParameter(ID, LightData); + m_LightMap[ID] = pLight; + *poutLightID = ID; +} + +void CLightManager::DeleteLight(TLightID LightID) +{ + TLightMap::iterator itor = m_LightMap.find(LightID); + + if (m_LightMap.end() == itor) + { + assert(!"CLightManager::DeleteLight - Failed to find light ID!"); + return; + } + + CLight * pLight = itor->second; + + pLight->Clear(); + m_LightPool.Free(pLight); + + m_LightMap.erase(itor); + + ReleaseLightID(LightID); +} + +CLight * CLightManager::GetLight(TLightID LightID) +{ + TLightMap::iterator itor = m_LightMap.find(LightID); + + if (m_LightMap.end() == itor) + { + assert(!"CLightManager::SetLightData - Failed to find light ID!"); + return NULL; + } + + return itor->second; +} + +void CLightManager::SetCenterPosition(const D3DXVECTOR3 & c_rv3Position) +{ + m_v3CenterPosition = c_rv3Position; +} + +void CLightManager::SetLimitLightCount(DWORD dwLightCount) +{ + m_dwLimitLightCount = dwLightCount; +} + +void CLightManager::SetSkipIndex(DWORD dwSkipIndex) +{ + m_dwSkipIndex = dwSkipIndex; +} + +struct LightComp +{ + bool operator () (const CLight * l, const CLight * r) const + { + return l->GetDistance() < r->GetDistance(); + } +}; + +// NOTE : FlushLight +// ݵ RestoreLight ߸ Ѵ. +void CLightManager::FlushLight() +{ + Update(); + + m_LightSortVector.clear(); + + // NOTE: Dynamic Static и Ű CenterPosition ٲ𶧸 Static + // ٽ Flush ϴ ȭ ִ. - [levites] + + // light Ÿ Ѵ. + TLightMap::iterator itor = m_LightMap.begin(); + + for (; itor != m_LightMap.end(); ++itor) + { + CLight * pLight = itor->second; + + D3DXVECTOR3 v3LightPos(pLight->GetPosition()); + D3DXVECTOR3 v3Distance(v3LightPos - m_v3CenterPosition); + pLight->SetDistance(D3DXVec3Length(&v3Distance)); + m_LightSortVector.push_back(pLight); + } + + // quick sort lights + std::sort(m_LightSortVector.begin(), m_LightSortVector.end(), LightComp()); + + // NOTE - Ÿ ĵ Ʈ Limit ŭ ؼ ش. + STATEMANAGER.SaveRenderState(D3DRS_LIGHTING, TRUE); + + for (DWORD k = 0; k < min(m_dwLimitLightCount, m_LightSortVector.size()); ++k) + { + m_LightSortVector[k]->Update(); + m_LightSortVector[k]->SetDeviceLight(TRUE); + + } +} + +void CLightManager::RestoreLight() +{ + STATEMANAGER.RestoreRenderState(D3DRS_LIGHTING); + + for (DWORD k = 0; k < min(m_dwLimitLightCount, m_LightSortVector.size()); ++k) + m_LightSortVector[k]->SetDeviceLight(FALSE); +} + +TLightID CLightManager::NewLightID() +{ + if (!m_NonUsingLightIDDeque.empty()) + { + TLightID id = m_NonUsingLightIDDeque.back(); + m_NonUsingLightIDDeque.pop_back(); + return (id); + } + + return m_dwSkipIndex + m_LightMap.size(); +} + +void CLightManager::ReleaseLightID(TLightID LightID) +{ + m_NonUsingLightIDDeque.push_back(LightID); +} + +void CLightManager::Update() +{ + //static DWORD s_dwStartTime = ELTimer_GetMSec(); + //ms_fCurTime = float(ELTimer_GetMSec() - s_dwStartTime) / 1000.0f; + ms_fCurTime = CTimer::Instance().GetCurrentSecond(); +} + +////////////////////////////////////////////////////////////////////////// +CLight::CLight() +{ + Initialize(); +} + +CLight::~CLight() +{ + Clear(); +} + +void CLight::Initialize() +{ + m_LightID = 0; + m_isEdited = TRUE; + m_fDistance = 0.0f; + + memset(&m_d3dLight, 0, sizeof(m_d3dLight)); + + m_d3dLight.Type = D3DLIGHT_POINT; + m_d3dLight.Attenuation0 = 0.0f; + m_d3dLight.Attenuation1 = 1.0f; + m_d3dLight.Attenuation2 = 0.0f; +} + +void CLight::Clear() +{ + if (m_LightID) + SetDeviceLight(FALSE); + Initialize(); +} + +void CLight::SetDeviceLight(BOOL bActive) +{ + if (bActive && m_isEdited) + { + if (ms_lpd3dDevice) + ms_lpd3dDevice->SetLight(m_LightID, &m_d3dLight); + } + if (ms_lpd3dDevice) + { + ms_lpd3dDevice->LightEnable(m_LightID, bActive); + } +} + +void CLight::SetParameter(TLightID id, const D3DLIGHT8 & c_rLight) +{ + m_LightID = id; + m_d3dLight = c_rLight; +} + +void CLight::SetDiffuseColor(float fr, float fg, float fb, float fa) +{ + if (m_d3dLight.Diffuse.r == fr + && m_d3dLight.Diffuse.g == fg + && m_d3dLight.Diffuse.b == fb + && m_d3dLight.Diffuse.a == fa + ) + return; + m_d3dLight.Diffuse.r = fr; + m_d3dLight.Diffuse.g = fg; + m_d3dLight.Diffuse.b = fb; + m_d3dLight.Diffuse.a = fa; + m_isEdited = TRUE; +} + +void CLight::SetAmbientColor(float fr, float fg, float fb, float fa) +{ + if (m_d3dLight.Ambient.r == fr + && m_d3dLight.Ambient.g == fg + && m_d3dLight.Ambient.b == fb + && m_d3dLight.Ambient.a == fa + ) + return; + m_d3dLight.Ambient.r = fr; + m_d3dLight.Ambient.g = fg; + m_d3dLight.Ambient.b = fb; + m_d3dLight.Ambient.a = fa; + m_isEdited = TRUE; +} + +void CLight::SetRange(float fRange) +{ + if (m_d3dLight.Range == fRange) + return; + + m_d3dLight.Range = fRange; + m_isEdited = TRUE; +} + +const D3DVECTOR & CLight::GetPosition() const +{ + return m_d3dLight.Position; +} + +void CLight::SetPosition(float fx, float fy, float fz) +{ + if (m_d3dLight.Position.x == fx && m_d3dLight.Position.y == fy && m_d3dLight.Position.z == fz) + return; + + m_d3dLight.Position.x = fx; + m_d3dLight.Position.y = fy; + m_d3dLight.Position.z = fz; + m_isEdited = TRUE; +} + +void CLight::SetDistance(float fDistance) +{ + m_fDistance = fDistance; +} + +void CLight::BlendDiffuseColor(const D3DXCOLOR & c_rColor, float fBlendTime, float fDelayTime) +{ + D3DXCOLOR Color(m_d3dLight.Diffuse); + m_DiffuseColorTransitor.SetTransition(Color, c_rColor, ms_fCurTime + fDelayTime, fBlendTime); +} + +void CLight::BlendAmbientColor(const D3DXCOLOR & c_rColor, float fBlendTime, float fDelayTime) +{ + D3DXCOLOR Color(m_d3dLight.Ambient); + m_AmbientColorTransitor.SetTransition(Color, c_rColor, ms_fCurTime + fDelayTime, fBlendTime); +} + +void CLight::BlendRange(float fRange, float fBlendTime, float fDelayTime) +{ + m_RangeTransitor.SetTransition(m_d3dLight.Range, fRange, ms_fCurTime + fDelayTime, fBlendTime); +} + +void CLight::Update() +{ + if (m_AmbientColorTransitor.isActiveTime(ms_fCurTime)) + { + if (!m_AmbientColorTransitor.isActive()) + { + m_AmbientColorTransitor.SetActive(); + m_AmbientColorTransitor.SetSourceValue(m_d3dLight.Ambient); + } + else + { + D3DXCOLOR Color; + + m_AmbientColorTransitor.GetValue(ms_fCurTime, &Color); + SetAmbientColor(Color.r, Color.g, Color.b, Color.a); + } + } + + if (m_DiffuseColorTransitor.isActiveTime(ms_fCurTime)) + { + if (!m_DiffuseColorTransitor.isActive()) + { + m_DiffuseColorTransitor.SetActive(); + m_DiffuseColorTransitor.SetSourceValue(m_d3dLight.Diffuse); + } + else + { + D3DXCOLOR Color; + m_DiffuseColorTransitor.GetValue(ms_fCurTime, &Color); + SetDiffuseColor(Color.r, Color.g, Color.b, Color.a); + } + } + + if (m_RangeTransitor.isActiveTime(ms_fCurTime)) + { + if (!m_RangeTransitor.isActive()) + { + m_RangeTransitor.SetActive(); + m_RangeTransitor.SetSourceValue(m_d3dLight.Range); + } + else + { + float fRange; + m_RangeTransitor.GetValue(ms_fCurTime, &fRange); + SetRange(fRange); + } + } +} diff --git a/source/EterLib/GrpLightManager.h b/source/EterLib/GrpLightManager.h new file mode 100644 index 0000000..7000678 --- /dev/null +++ b/source/EterLib/GrpLightManager.h @@ -0,0 +1,127 @@ +#pragma once + +#include "../eterBase/Singleton.h" + +#include "GrpBase.h" +#include "Util.h" +#include "Pool.h" + +#include + +typedef DWORD TLightID; + +enum ELightType +{ + LIGHT_TYPE_STATIC, // Continuously turning on light + LIGHT_TYPE_DYNAMIC, // Immediately turning off light +}; + +class CLightBase +{ + public: + CLightBase() {}; + virtual ~CLightBase() {}; + + void SetCurrentTime(); + + protected: + static float ms_fCurTime; +}; + +class CLight : public CGraphicBase, public CLightBase +{ + public: + CLight(); + virtual ~CLight(); + + void Initialize(); + void Clear(); + + void Update(); + + void SetParameter(TLightID id, const D3DLIGHT8 & c_rLight); + + void SetDistance(float fDistance); + float GetDistance() const { return m_fDistance; } + + TLightID GetLightID() { return m_LightID; } + + BOOL isEdited() { return m_isEdited; } + void SetDeviceLight(BOOL bActive); + + void SetDiffuseColor(float fr, float fg, float fb, float fa = 1.0f); + void SetAmbientColor(float fr, float fg, float fb, float fa = 1.0f); + void SetRange(float fRange); + void SetPosition(float fx, float fy, float fz); + + const D3DVECTOR & GetPosition() const; + + void BlendDiffuseColor(const D3DXCOLOR & c_rColor, float fBlendTime, float fDelayTime = 0.0f); + void BlendAmbientColor(const D3DXCOLOR & c_rColor, float fBlendTime, float fDelayTime = 0.0f); + void BlendRange(float fRange, float fBlendTime, float fDelayTime = 0.0f); + + private: + TLightID m_LightID; // Light ID. equal to D3D light index + + D3DLIGHT8 m_d3dLight; + BOOL m_isEdited; + float m_fDistance; + + TTransitorColor m_DiffuseColorTransitor; + TTransitorColor m_AmbientColorTransitor; + TTransitorFloat m_RangeTransitor; +}; + +class CLightManager : public CGraphicBase, public CLightBase, public CSingleton +{ + public: + enum + { + LIGHT_LIMIT_DEFAULT = 3, +// LIGHT_MAX_NUM = 32, + }; + + typedef std::deque TLightIDDeque; + typedef std::map TLightMap; + typedef std::vector TLightSortVector; + + public: + CLightManager(); + virtual ~CLightManager(); + + void Destroy(); + + void Initialize(); + + // NOTE : FlushLight + // ݵ RestoreLight ߸ Ѵ. + void Update(); + void FlushLight(); + void RestoreLight(); + + ///// + void RegisterLight(ELightType LightType, TLightID * poutLightID, D3DLIGHT8 & LightData); + CLight * GetLight(TLightID LightID); + void DeleteLight(TLightID LightID); + ///// + + void SetCenterPosition(const D3DXVECTOR3 & c_rv3Position); + void SetLimitLightCount(DWORD dwLightCount); + void SetSkipIndex(DWORD dwSkipIndex); + + protected: + TLightIDDeque m_NonUsingLightIDDeque; + + TLightMap m_LightMap; + TLightSortVector m_LightSortVector; + + D3DXVECTOR3 m_v3CenterPosition; + DWORD m_dwLimitLightCount; + DWORD m_dwSkipIndex; + + protected: + TLightID NewLightID(); + void ReleaseLightID(TLightID LightID); + + CDynamicPool m_LightPool; +}; diff --git a/source/EterLib/GrpMarkInstance.cpp b/source/EterLib/GrpMarkInstance.cpp new file mode 100644 index 0000000..1a64cec --- /dev/null +++ b/source/EterLib/GrpMarkInstance.cpp @@ -0,0 +1,256 @@ +#include "StdAfx.h" +#include "GrpMarkInstance.h" +#include "StateManager.h" +#include "ResourceManager.h" + +#include "../eterBase/CRC32.h" + +CDynamicPool CGraphicMarkInstance::ms_kPool; + +void CGraphicMarkInstance::SetImageFileName(const char* c_szFileName) +{ + m_stImageFileName = c_szFileName; +} + +const std::string& CGraphicMarkInstance::GetImageFileName() +{ + return m_stImageFileName; +} + +void CGraphicMarkInstance::CreateSystem(UINT uCapacity) +{ + ms_kPool.Create(uCapacity); +} + +void CGraphicMarkInstance::DestroySystem() +{ + ms_kPool.Destroy(); +} + +CGraphicMarkInstance* CGraphicMarkInstance::New() +{ + return ms_kPool.Alloc(); +} + +void CGraphicMarkInstance::Delete(CGraphicMarkInstance* pkImgInst) +{ + pkImgInst->Destroy(); + ms_kPool.Free(pkImgInst); +} + +void CGraphicMarkInstance::Render() +{ + if (IsEmpty()) + return; + + assert(!IsEmpty()); + + OnRender(); +} + +void CGraphicMarkInstance::OnRender() +{ + CGraphicImage * pImage = m_roImage.GetPointer(); + CGraphicTexture * pTexture = pImage->GetTexturePointer(); + + UINT uColCount = pImage->GetWidth() / MARK_WIDTH; + + if (uColCount == 0) + return; + + UINT uCol = m_uIndex % uColCount; + UINT uRow = m_uIndex / uColCount; + + RECT kRect; + kRect.left=uCol*MARK_WIDTH; + kRect.top=uRow*MARK_HEIGHT; + kRect.right=kRect.left+MARK_WIDTH; + kRect.bottom=kRect.top+MARK_HEIGHT; + + float texReverseWidth = 1.0f / float(pTexture->GetWidth()); + float texReverseHeight = 1.0f / float(pTexture->GetHeight()); + float su = kRect.left * texReverseWidth; + float sv = kRect.top * texReverseHeight; + float eu = kRect.right * texReverseWidth; + float ev = kRect.bottom * texReverseHeight; + + float fRenderWidth=static_cast(MARK_WIDTH)*m_fScale; + float fRenderHeight= static_cast(MARK_HEIGHT)*m_fScale; + + TPDTVertex vertices[4]; + vertices[0].position.x = m_v2Position.x-0.5f; + vertices[0].position.y = m_v2Position.y-0.5f; + vertices[0].position.z = 0.0f; + vertices[0].texCoord = TTextureCoordinate(su, sv); + vertices[0].diffuse = m_DiffuseColor; + + vertices[1].position.x = m_v2Position.x + fRenderWidth -0.5f; + vertices[1].position.y = m_v2Position.y-0.5f; + vertices[1].position.z = 0.0f; + vertices[1].texCoord = TTextureCoordinate(eu, sv); + vertices[1].diffuse = m_DiffuseColor; + + vertices[2].position.x = m_v2Position.x-0.5f; + vertices[2].position.y = m_v2Position.y + fRenderHeight -0.5f; + vertices[2].position.z = 0.0f; + vertices[2].texCoord = TTextureCoordinate(su, ev); + vertices[2].diffuse = m_DiffuseColor; + + vertices[3].position.x = m_v2Position.x + fRenderWidth -0.5f; + vertices[3].position.y = m_v2Position.y + fRenderHeight -0.5f; + vertices[3].position.z = 0.0f; + vertices[3].texCoord = TTextureCoordinate(eu, ev); + vertices[3].diffuse = m_DiffuseColor; + + if (CGraphicBase::SetPDTStream(vertices, 4)) + { + CGraphicBase::SetDefaultIndexBuffer(CGraphicBase::DEFAULT_IB_FILL_RECT); + + STATEMANAGER.SetTexture(0, pTexture->GetD3DTexture()); + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 4, 0, 2); + //OLD: STATEMANAGER.DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, c_FillRectIndices, D3DFMT_INDEX16, vertices, sizeof(TPDTVertex)); + } +} + +const CGraphicTexture & CGraphicMarkInstance::GetTextureReference() const +{ + return m_roImage->GetTextureReference(); +} + +CGraphicTexture * CGraphicMarkInstance::GetTexturePointer() +{ + return m_roImage->GetTexturePointer(); +} + +CGraphicImage * CGraphicMarkInstance::GetGraphicImagePointer() +{ + return m_roImage.GetPointer(); +} + +void CGraphicMarkInstance::SetScale(float fScale) +{ + m_fScale=fScale; +} + +void CGraphicMarkInstance::SetIndex(UINT uIndex) +{ + m_uIndex=uIndex; +} + +int CGraphicMarkInstance::GetWidth() +{ + if (IsEmpty()) + return 0; + + //return m_roImage->GetWidth(); + return 16; +} + +int CGraphicMarkInstance::GetHeight() +{ + if (IsEmpty()) + return 0; + + //return m_roImage->GetHeight(); + return 12; +} + +void CGraphicMarkInstance::SetDiffuseColor(float fr, float fg, float fb, float fa) +{ + m_DiffuseColor.r = fr; + m_DiffuseColor.g = fg; + m_DiffuseColor.b = fb; + m_DiffuseColor.a = fa; +} + +void CGraphicMarkInstance::SetPosition(float fx, float fy) +{ + m_v2Position.x = fx; + m_v2Position.y = fy; +} + +void CGraphicMarkInstance::Load() +{ + if (GetImageFileName().empty()) + return; + + CResource * pResource = CResourceManager::Instance().GetResourcePointer(GetImageFileName().c_str()); + + if (!pResource) + { + TraceError("CGraphicMarkinstance::Load - [%s] NOT EXIST", GetImageFileName().c_str()); + return; + } + + if (pResource->IsType(CGraphicImage::Type())) + SetImagePointer(static_cast(pResource)); +} + +void CGraphicMarkInstance::SetImagePointer(CGraphicImage * pImage) +{ + m_roImage.SetPointer(pImage); + + OnSetImagePointer(); +} + +bool CGraphicMarkInstance::IsEmpty() const +{ + if (!m_roImage.IsNull() && !m_roImage->IsEmpty()) + return false; + + return true; +} + +bool CGraphicMarkInstance::operator == (const CGraphicMarkInstance & rhs) const +{ + return (m_roImage.GetPointer() == rhs.m_roImage.GetPointer()); +} + +DWORD CGraphicMarkInstance::Type() +{ + static DWORD s_dwType = GetCRC32("CGraphicMarkInstance", strlen("CGraphicMarkInstance")); + return (s_dwType); +} + +BOOL CGraphicMarkInstance::IsType(DWORD dwType) +{ + return OnIsType(dwType); +} + +BOOL CGraphicMarkInstance::OnIsType(DWORD dwType) +{ + if (CGraphicMarkInstance::Type() == dwType) + return TRUE; + + return FALSE; +} + +void CGraphicMarkInstance::OnSetImagePointer() +{ +} + +void CGraphicMarkInstance::Initialize() +{ + m_DiffuseColor.r = m_DiffuseColor.g = m_DiffuseColor.b = m_DiffuseColor.a = 1.0f; + m_v2Position.x = m_v2Position.y = 0.0f; + m_uIndex = 0; + m_fScale = 1.0f; +} + +void CGraphicMarkInstance::Destroy() +{ + m_roImage.SetPointer(NULL); // CRef ۷ īƮ . + Initialize(); +} + +CGraphicMarkInstance::CGraphicMarkInstance() +{ + Initialize(); +} + +CGraphicMarkInstance::~CGraphicMarkInstance() +{ + Destroy(); +} diff --git a/source/EterLib/GrpMarkInstance.h b/source/EterLib/GrpMarkInstance.h new file mode 100644 index 0000000..192a36f --- /dev/null +++ b/source/EterLib/GrpMarkInstance.h @@ -0,0 +1,77 @@ +#pragma once + +#include "GrpImage.h" +#include "Pool.h" + +class CGraphicMarkInstance +{ + public: + static DWORD Type(); + BOOL IsType(DWORD dwType); + + void SetImageFileName(const char* c_szFileName); + const std::string& GetImageFileName(); + + public: + CGraphicMarkInstance(); + virtual ~CGraphicMarkInstance(); + + void Destroy(); + + void Render(); + + void SetDepth(float fDepth); + void SetDiffuseColor(float fr, float fg, float fb, float fa); + void SetPosition(float fx, float fy); + void SetIndex(UINT uIndex); + void SetScale(float fScale); + + void Load(); + bool IsEmpty() const; + + int GetWidth(); + int GetHeight(); + + CGraphicTexture * GetTexturePointer(); + const CGraphicTexture & GetTextureReference() const; + CGraphicImage * GetGraphicImagePointer(); + + bool operator == (const CGraphicMarkInstance & rhs) const; + + protected: + enum + { + MARK_WIDTH = 16, + MARK_HEIGHT = 12, + }; + + void Initialize(); + + virtual void OnRender(); + virtual void OnSetImagePointer(); + + virtual BOOL OnIsType(DWORD dwType); + + void SetImagePointer(CGraphicImage * pImage); + + protected: + D3DXCOLOR m_DiffuseColor; + D3DXVECTOR2 m_v2Position; + + UINT m_uIndex; + + FLOAT m_fScale; + FLOAT m_fDepth; + + CGraphicImage::TRef m_roImage; + std::string m_stImageFileName; + + public: + static void CreateSystem(UINT uCapacity); + static void DestroySystem(); + + static CGraphicMarkInstance* New(); + static void Delete(CGraphicMarkInstance* pkImgInst); + + static CDynamicPool ms_kPool; +}; diff --git a/source/EterLib/GrpMath.cpp b/source/EterLib/GrpMath.cpp new file mode 100644 index 0000000..302be29 --- /dev/null +++ b/source/EterLib/GrpMath.cpp @@ -0,0 +1,136 @@ +#include "StdAfx.h" +#include "GrpMath.h" + +float CrossProduct2D(float x1, float y1, float x2, float y2) +{ + return x1*y2-y1*x2; +} + +bool IsInTriangle2D(float ax, float ay, float bx, float by, float cx, float cy, float tx, float ty) +{ + float c1 = CrossProduct2D(bx-ax, by-ay, tx-ax, ty-ay); + float c2 = CrossProduct2D(cx-bx, cy-by, tx-bx, ty-by); + float c3 = CrossProduct2D(ax-cx, ay-cy, tx-cx, ty-cy); + + if (c1 * c2 > 0.0f && c1 * c3 > 0.0f) + return true; + + if (c1 * c2 * c3 == 0.0f) + { + if (tx < ax) + if (tx < bx) + if (tx < cx) + return false; + + if (tx > ax) + if (tx > bx) + if (tx > cx) + return false; + + if (ty < ay) + if (ty < by) + if (ty < cy) + return false; + + if (ty > ay) + if (ty > by) + if (ty > cy) + return false; + + return true; + } + + return false; +} + +D3DXVECTOR3* D3DXVec3Rotation(D3DXVECTOR3* pvtOut, const D3DXVECTOR3* c_pvtSrc, const D3DXQUATERNION* c_pqtRot) +{ + D3DXQUATERNION qtSrc(c_pvtSrc->x, c_pvtSrc->y, c_pvtSrc->z, 0); + D3DXQUATERNION qtRet; + D3DXQuaternionConjugate(&qtRet, c_pqtRot); + D3DXQuaternionMultiply(&qtRet, &qtSrc, &qtRet); + D3DXQuaternionMultiply(&qtRet, c_pqtRot, &qtRet); + + pvtOut->x=qtRet.x; + pvtOut->y=qtRet.y; + pvtOut->z=qtRet.z; + + return pvtOut; +} + + + +void GetRotationFromMatrix(D3DXVECTOR3 * pRotation, const D3DXMATRIX * c_pMatrix) +{ + float sx = c_pMatrix->_32; + float cx = sqrtf(1.0f - sx * sx); + + if (cx < 0.00001f) + { + if (sx > 0) + pRotation->x = D3DX_PI / 2; + else + pRotation->x = -D3DX_PI / 2; + + pRotation->y = atan2f(c_pMatrix->_31, c_pMatrix->_11); + pRotation->z = 0.0f; + } + else + { + pRotation->x = atan2f(sx, cx); + pRotation->y = atan2f(-c_pMatrix->_31, c_pMatrix->_33); + pRotation->z = atan2f(-c_pMatrix->_12, c_pMatrix->_22); + } +} + +void GetPivotAndRotationFromMatrix(D3DXMATRIX * pMatrix, D3DXVECTOR3 * pPivot, D3DXVECTOR3 * pRotation) +{ + float sx = pMatrix->_32; + float cx = sqrtf(1.0f - sx * sx); + float x, y, z; + + if (cx < 0.00001f) + { + if (sx > 0) + x = D3DX_PI / 2; + else + x = -D3DX_PI / 2; + + y = atan2f(pMatrix->_31, pMatrix->_11); + z = 0.0f; + } + else + { + x = atan2f(sx, cx); + y = atan2f(-pMatrix->_31, pMatrix->_33); + z = atan2f(-pMatrix->_12, pMatrix->_22); + } + + pRotation->x = x; + pRotation->y = y; + pRotation->z = z; + + pPivot->x = pMatrix->_41; + pPivot->y = pMatrix->_42; + pPivot->z = pMatrix->_43; +} + +// NOTE : must be optimized! +void ExtractMovement(D3DXMATRIX * pTargetMatrix, D3DXMATRIX * pSourceMatrix) +{ + D3DXVECTOR3 v3Pivot; + D3DXVECTOR3 v3Rotation; + GetPivotAndRotationFromMatrix(pSourceMatrix, &v3Pivot, &v3Rotation); + + D3DXMATRIX matRotationX; + D3DXMatrixRotationX(&matRotationX, v3Rotation.x); + D3DXMATRIX matRotationY; + D3DXMatrixRotationY(&matRotationY, v3Rotation.y); + D3DXMATRIX matRotationZ; + D3DXMatrixRotationZ(&matRotationZ, v3Rotation.z); + + D3DXMATRIX matTranslation; + D3DXMatrixTranslation(&matTranslation, v3Pivot.x, v3Pivot.y, v3Pivot.z); + + *pTargetMatrix = matRotationX * matRotationY * matRotationZ * matTranslation; +} \ No newline at end of file diff --git a/source/EterLib/GrpMath.h b/source/EterLib/GrpMath.h new file mode 100644 index 0000000..d2dd743 --- /dev/null +++ b/source/EterLib/GrpMath.h @@ -0,0 +1,122 @@ +#pragma once + +float CrossProduct2D(float x1, float y1, float x2, float y2); + +bool IsInTriangle2D(float ax, float ay, float bx, float by, float cx, float cy, float tx, float ty); + +D3DXVECTOR3* D3DXVec3Rotation(D3DXVECTOR3* pvtOut, const D3DXVECTOR3* c_pvtSrc, const D3DXQUATERNION* c_pqtRot); +D3DXVECTOR3* D3DXVec3Translation(D3DXVECTOR3* pvtOut, const D3DXVECTOR3* c_pvtSrc, const D3DXVECTOR3* c_pvtTrans); + +void GetRotationFromMatrix(D3DXVECTOR3 * pRotation, const D3DXMATRIX * c_pMatrix); +void GetPivotAndRotationFromMatrix(D3DXMATRIX * pMatrix, D3DXVECTOR3 * pPivot, D3DXVECTOR3 * pRotation); +void ExtractMovement(D3DXMATRIX * pTargetMatrix, D3DXMATRIX * pSourceMatrix); + +inline D3DXVECTOR3* D3DXVec3Blend(D3DXVECTOR3* pvtOut, const D3DXVECTOR3* c_pvtSrc1, const D3DXVECTOR3* c_pvtSrc2, float d) +{ + pvtOut->x=c_pvtSrc1->x+d*(c_pvtSrc2->x-c_pvtSrc1->x); + pvtOut->y=c_pvtSrc1->y+d*(c_pvtSrc2->y-c_pvtSrc1->y); + pvtOut->z=c_pvtSrc1->z+d*(c_pvtSrc2->z-c_pvtSrc1->z); + + return pvtOut; +} + +inline D3DXQUATERNION* D3DXQuaternionBlend(D3DXQUATERNION* pqtOut, const D3DXQUATERNION* c_pqtSrc1, const D3DXQUATERNION* c_pqtSrc2, float d) +{ + pqtOut->x=c_pqtSrc1->x+d*(c_pqtSrc2->x-c_pqtSrc1->x); + pqtOut->y=c_pqtSrc1->y+d*(c_pqtSrc2->y-c_pqtSrc1->y); + pqtOut->z=c_pqtSrc1->z+d*(c_pqtSrc2->z-c_pqtSrc1->z); + pqtOut->w=c_pqtSrc1->w+d*(c_pqtSrc2->w-c_pqtSrc1->w); + return pqtOut; +} + +inline float ClampDegree(float fDegree) +{ + if (fDegree >= 360.0f) + fDegree -= 360.0f; + if (fDegree < 0.0f) + fDegree += 360.0f; + + return fDegree; +} + +inline float GetVector3Distance(const D3DXVECTOR3 & c_rv3Source, const D3DXVECTOR3 & c_rv3Target) +{ + return (c_rv3Source.x-c_rv3Target.x)*(c_rv3Source.x-c_rv3Target.x) + (c_rv3Source.y-c_rv3Target.y)*(c_rv3Source.y-c_rv3Target.y); +} + +inline D3DXQUATERNION SafeRotationNormalizedArc(const D3DXVECTOR3 & vFrom , const D3DXVECTOR3 & vTo) +{ + if (vFrom == vTo) + return D3DXQUATERNION(0.0f,0.0f,0.0f,1.0f); + if (vFrom == -vTo) + return D3DXQUATERNION(0.0f,0.0f,1.0f,0.0f); + D3DXVECTOR3 c; + D3DXVec3Cross(&c, &vFrom, &vTo); + float d = D3DXVec3Dot(&vFrom, &vTo); + float s = sqrtf((1+d)*2); + + return D3DXQUATERNION(c.x/s,c.y/s,c.z/s,s*0.5f); +} + +inline D3DXQUATERNION RotationNormalizedArc(const D3DXVECTOR3 & vFrom , const D3DXVECTOR3 & vTo) + +{ + D3DXVECTOR3 c; + D3DXVec3Cross(&c, &vFrom, &vTo); + float d = D3DXVec3Dot(&vFrom, &vTo); + float s = sqrtf((1+d)*2); + + return D3DXQUATERNION(c.x/s,c.y/s,c.z/s,s*0.5f); +} + +inline D3DXQUATERNION RotationArc(const D3DXVECTOR3 & vFrom , const D3DXVECTOR3 & vTo) +{ + D3DXVECTOR3 vnFrom, vnTo; + D3DXVec3Normalize(&vnFrom, &vFrom); + D3DXVec3Normalize(&vnTo, &vTo); + return RotationNormalizedArc(vnFrom, vnTo); +} + +inline float square_distance_between_linesegment_and_point(const D3DXVECTOR3& p1,const D3DXVECTOR3& p2,const D3DXVECTOR3& x) +{ + const auto v1 = p2 - p1; + float l = D3DXVec3LengthSq(&v1); + const auto v2 = x - p1; + const auto v3 = p2 - p1; + float d = D3DXVec3Dot(&(v2),&(v3)); + if (d<=0.0f) + { + return D3DXVec3LengthSq(&(v2)); + } + else if (d>=l) + { + const auto v4 = x - p2; + return D3DXVec3LengthSq(&(v4)); + } + else + { + D3DXVECTOR3 c; + return D3DXVec3LengthSq(D3DXVec3Cross(&c,&(v2),&(v3)))/l; + } +} + +inline D3DXVECTOR3 * Vec3TransformQuaternionSafe(D3DXVECTOR3* pvout, const D3DXVECTOR3* pv, const D3DXQUATERNION* pq) +{ + D3DXVECTOR3 v; + D3DXVec3Cross(&v,pv,(D3DXVECTOR3*)pq); + v *= -2*pq->w; + v += (pq->w*pq->w - D3DXVec3LengthSq((D3DXVECTOR3*)pq))*(*pv); + v += 2*D3DXVec3Dot((D3DXVECTOR3*)pq,pv)*(*(D3DXVECTOR3*)pq); + *pvout = v; + return pvout; +} + +inline D3DXVECTOR3 * Vec3TransformQuaternion(D3DXVECTOR3* pvout, const D3DXVECTOR3* pv, const D3DXQUATERNION* pq) +{ + D3DXVec3Cross(pvout,pv,(D3DXVECTOR3*)pq); + *pvout *= -2*pq->w; + *pvout += (pq->w*pq->w - D3DXVec3LengthSq((D3DXVECTOR3*)pq))*(*pv); + *pvout += 2*D3DXVec3Dot((D3DXVECTOR3*)pq,pv)*(*(D3DXVECTOR3*)pq); + + return pvout; +} diff --git a/source/EterLib/GrpObjectInstance.cpp b/source/EterLib/GrpObjectInstance.cpp new file mode 100644 index 0000000..8485598 --- /dev/null +++ b/source/EterLib/GrpObjectInstance.cpp @@ -0,0 +1,441 @@ +#include "StdAfx.h" +#include "GrpObjectInstance.h" +#include "../eterBase/Timer.h" + +void CGraphicObjectInstance::OnInitialize() +{ + ZeroMemory(m_abyPortalID, sizeof(m_abyPortalID)); +} + +void CGraphicObjectInstance::Clear() +{ + if (m_CullingHandle) + { + CCullingManager::Instance().Unregister(m_CullingHandle); + m_CullingHandle = NULL; + } + + ClearHeightInstance(); + + m_isVisible = TRUE; + + m_v3Position.x = m_v3Position.y = m_v3Position.z = 0.0f; + m_v3Scale.x = m_v3Scale.y = m_v3Scale.z = 0.0f; + //m_fRotation = 0.0f; + m_fYaw = m_fPitch = m_fRoll = 0.0f; + D3DXMatrixIdentity(&m_worldMatrix); + + ZeroMemory(m_abyPortalID, sizeof(m_abyPortalID)); + + OnClear(); +} + +bool CGraphicObjectInstance::Render() +{ + /* + if (m_CullingHandle) + { + SpherePack * ps = m_CullingHandle->GetParent(); + CScreen s; + s.SetColorOperation(); + //s.SetDiffuseColor(1,isShow()?1:0,0); + //s.RenderCircle2d(m_CullingHandle->GetCenter().x,m_CullingHandle->GetCenter().y,m_CullingHandle->GetCenter().z,m_CullingHandle->GetRadius()); + s.SetDiffuseColor(1,isShow()?1:0,ps->HasSpherePackFlag(SPF_PARTIAL)?1:0); + s.RenderCircle2d(ps->GetCenter().x,ps->GetCenter().y,ps->GetCenter().z,ps->GetRadius()); + } + //*/ + if (!isShow()) + return false; + + OnRender(); + return true; +} + +void CGraphicObjectInstance::BlendRender() +{ + if (!isShow()) + return; + + OnBlendRender(); +} + +void CGraphicObjectInstance::RenderToShadowMap() +{ + if (!isShow()) + return; + + OnRenderToShadowMap(); +} + +void CGraphicObjectInstance::RenderShadow() +{ + if (!isShow()) + return; + + OnRenderShadow(); +} + +void CGraphicObjectInstance::RenderPCBlocker() +{ + if (!isShow()) + return; + + OnRenderPCBlocker(); +} + +void CGraphicObjectInstance::Update() +{ + OnUpdate(); + + UpdateBoundingSphere(); +} + +void CGraphicObjectInstance::Deform() +{ + if (!isShow()) + return; + + OnDeform(); +} + + +void CGraphicObjectInstance::Transform() +{ + m_worldMatrix = m_mRotation; + + m_worldMatrix._41 += m_v3Position.x; + m_worldMatrix._42 += m_v3Position.y; + m_worldMatrix._43 += m_v3Position.z; +} + +const D3DXVECTOR3 & CGraphicObjectInstance::GetPosition() const +{ + return m_v3Position; +} + +const D3DXVECTOR3 & CGraphicObjectInstance::GetScale() const +{ + return m_v3Scale; +} + +float CGraphicObjectInstance::GetRotation() +{ + return GetRoll(); +} + +float CGraphicObjectInstance::GetYaw() +{ + return m_fYaw; +} + +float CGraphicObjectInstance::GetPitch() +{ + return m_fPitch; +} + +float CGraphicObjectInstance::GetRoll() +{ + return m_fRoll; +} + +D3DXMATRIX & CGraphicObjectInstance::GetTransform() +{ + return m_worldMatrix; +} + +void CGraphicObjectInstance::SetRotationQuaternion(const D3DXQUATERNION &q) +{ + D3DXMatrixRotationQuaternion(&m_mRotation, &q); +} + +void CGraphicObjectInstance::SetRotationMatrix(const D3DXMATRIX & m) +{ + m_mRotation = m; +} + +void CGraphicObjectInstance::SetRotation(float fRotation) +{ + m_fYaw = 0; + m_fPitch = 0; + m_fRoll = fRotation; + + D3DXMatrixRotationZ(&m_mRotation, D3DXToRadian(fRotation)); +} + +void CGraphicObjectInstance::SetRotation(float fYaw, float fPitch, float fRoll) +{ + //m_fRotation = fRotation; + m_fYaw = fYaw; + m_fPitch = fPitch; + m_fRoll = fRoll; + + D3DXMatrixRotationYawPitchRoll(&m_mRotation, D3DXToRadian(fYaw), D3DXToRadian(fPitch), D3DXToRadian(fRoll)); +} + +void CGraphicObjectInstance::SetPosition(float x, float y, float z) +{ + m_v3Position.x = x; + m_v3Position.y = y; + m_v3Position.z = z; +} + +void CGraphicObjectInstance::SetPosition(const D3DXVECTOR3 & newposition) +{ + m_v3Position = newposition; +} + +void CGraphicObjectInstance::SetScale(float x, float y, float z) +{ + m_v3Scale.x = x; + m_v3Scale.y = y; + m_v3Scale.z = z; +} + +void CGraphicObjectInstance::Show() +{ + m_isVisible = true; +} + +void CGraphicObjectInstance::Hide() +{ + m_isVisible = false; +} +bool CGraphicObjectInstance::isShow() +{ + return m_isVisible; +} + +// + +////////////////////////////////////////////////////////////////////////// + +D3DXVECTOR4 & CGraphicObjectInstance::GetWTBBoxVertex(const unsigned char & c_rucNumTBBoxVertex) +{ + return m_v4TBBox[c_rucNumTBBoxVertex]; +} + +bool CGraphicObjectInstance::isIntersect(const CRay & c_rRay, float * pu, float * pv, float * pt) +{ + D3DXVECTOR3 v3Start, v3Dir; + float fRayRange; + c_rRay.GetStartPoint(&v3Start); + c_rRay.GetDirection(&v3Dir, &fRayRange); + + TPosition posVertices[8]; + + posVertices[0] = TPosition(m_v3TBBoxMin.x, m_v3TBBoxMin.y, m_v3TBBoxMin.z); + posVertices[1] = TPosition(m_v3TBBoxMax.x, m_v3TBBoxMin.y, m_v3TBBoxMin.z); + posVertices[2] = TPosition(m_v3TBBoxMin.x, m_v3TBBoxMax.y, m_v3TBBoxMin.z); + posVertices[3] = TPosition(m_v3TBBoxMax.x, m_v3TBBoxMax.y, m_v3TBBoxMin.z); + posVertices[4] = TPosition(m_v3TBBoxMin.x, m_v3TBBoxMin.y, m_v3TBBoxMax.z); + posVertices[5] = TPosition(m_v3TBBoxMax.x, m_v3TBBoxMin.y, m_v3TBBoxMax.z); + posVertices[6] = TPosition(m_v3TBBoxMin.x, m_v3TBBoxMax.y, m_v3TBBoxMax.z); + posVertices[7] = TPosition(m_v3TBBoxMax.x, m_v3TBBoxMax.y, m_v3TBBoxMax.z); + + TIndex Indices[36] = {0, 1, 2, 1, 3, 2, + 2, 0, 6, 0, 4, 6, + 0, 1, 4, 1, 5, 4, + 1, 3, 5, 3, 7, 5, + 3, 2, 7, 2, 6, 7, + 4, 5, 6, 5, 7, 6}; + + int triCount = 12; + WORD* pcurIdx = (WORD*)Indices; + + while (triCount--) + { + if (IntersectTriangle(v3Start, v3Dir, + posVertices[pcurIdx[0]], + posVertices[pcurIdx[1]], + posVertices[pcurIdx[2]], + pu, pv, pt)) + { + return true; + } + + pcurIdx += 3; + } + + return false; +} + +CGraphicObjectInstance::CGraphicObjectInstance() +{ + m_CullingHandle = 0; + Initialize(); +} + +void CGraphicObjectInstance::Initialize() +{ + if (m_CullingHandle) + CCullingManager::Instance().Unregister(m_CullingHandle); + m_CullingHandle = 0; + + m_pHeightAttributeInstance = NULL; + + m_isVisible = TRUE; + + m_BlockCamera = false; + + m_v3Position.x = m_v3Position.y = m_v3Position.z = 0.0f; + m_v3Scale.x = m_v3Scale.y = m_v3Scale.z = 0.0f; + m_fYaw = m_fPitch = m_fRoll = 0.0f; + + D3DXMatrixIdentity(&m_worldMatrix); + D3DXMatrixIdentity(&m_mRotation); + + OnInitialize(); +} + +CGraphicObjectInstance::~CGraphicObjectInstance() +{ + Initialize(); +} + +void CGraphicObjectInstance::UpdateBoundingSphere() +{ + if (m_CullingHandle) + { + Vector3d center; + float radius; + GetBoundingSphere(center,radius); + if (radius != m_CullingHandle->GetRadius()) + m_CullingHandle->NewPosRadius(center,radius); + else + m_CullingHandle->NewPos(center); + } +} + +void CGraphicObjectInstance::RegisterBoundingSphere() +{ + if (m_CullingHandle) + CCullingManager::Instance().Unregister(m_CullingHandle); + + m_CullingHandle = CCullingManager::Instance().Register(this); +} + +void CGraphicObjectInstance::AddCollision(const CStaticCollisionData * pscd, const D3DXMATRIX* pMat) +{ + m_StaticCollisionInstanceVector.push_back(CBaseCollisionInstance::BuildCollisionInstance(pscd, pMat)); +} + +void CGraphicObjectInstance::ClearCollision() +{ + CCollisionInstanceVector::iterator it; + for(it = m_StaticCollisionInstanceVector.begin();it!=m_StaticCollisionInstanceVector.end();++it) + { + (*it)->Destroy(); + } + m_StaticCollisionInstanceVector.clear(); +} + +bool CGraphicObjectInstance::CollisionDynamicSphere(const CDynamicSphereInstance & s) const +{ + CCollisionInstanceVector::const_iterator it; + for(it = m_StaticCollisionInstanceVector.begin();it!=m_StaticCollisionInstanceVector.end();++it) + { + if ((*it)->CollisionDynamicSphere(s)) + return true; + } + return false; +} + +bool CGraphicObjectInstance::MovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const +{ + CCollisionInstanceVector::const_iterator it; + for(it = m_StaticCollisionInstanceVector.begin();it!=m_StaticCollisionInstanceVector.end();++it) + { + if ((*it)->MovementCollisionDynamicSphere(s)) + return true; + } + return false; +} + +D3DXVECTOR3 CGraphicObjectInstance::GetCollisionMovementAdjust(const CDynamicSphereInstance & s) const +{ + CCollisionInstanceVector::const_iterator it; + for(it = m_StaticCollisionInstanceVector.begin();it!=m_StaticCollisionInstanceVector.end();++it) + { + if ((*it)->MovementCollisionDynamicSphere(s)) + return (*it)->GetCollisionMovementAdjust(s); + } + + return D3DXVECTOR3(0.0f,0.0f,0.0f); +} + +void CGraphicObjectInstance::UpdateCollisionData(const CStaticCollisionDataVector * pscdVector) +{ + ClearCollision(); + OnUpdateCollisionData(pscdVector); +} + +DWORD CGraphicObjectInstance::GetCollisionInstanceCount() +{ + return m_StaticCollisionInstanceVector.size(); +} + +CBaseCollisionInstance * CGraphicObjectInstance::GetCollisionInstanceData(DWORD dwIndex) +{ + if (dwIndex>m_StaticCollisionInstanceVector.size()) + { + return 0; + } + return m_StaticCollisionInstanceVector[dwIndex]; +} + +////////////////////////////////////////////////////////////////////////// +// Height + +void CGraphicObjectInstance::SetHeightInstance(CAttributeInstance * pAttributeInstance) +{ + m_pHeightAttributeInstance = pAttributeInstance; +} + +void CGraphicObjectInstance::ClearHeightInstance() +{ + m_pHeightAttributeInstance = NULL; +} + +void CGraphicObjectInstance::UpdateHeightInstance(CAttributeInstance * pAttributeInstance) +{ + ClearHeightInstance(); + OnUpdateHeighInstance(pAttributeInstance); +} + +bool CGraphicObjectInstance::IsObjectHeight() +{ + if (m_pHeightAttributeInstance) + return true; + + return false; +} + +bool CGraphicObjectInstance::GetObjectHeight(float fX, float fY, float * pfHeight) +{ + if (!m_pHeightAttributeInstance) + return false; + + return OnGetObjectHeight(fX, fY, pfHeight); +} + +void CGraphicObjectInstance::SetPortal(DWORD dwIndex, int iID) +{ + if (dwIndex >= PORTAL_ID_MAX_NUM) + { + assert(dwIndex < PORTAL_ID_MAX_NUM); + return; + } + + m_abyPortalID[dwIndex] = iID; +} + +int CGraphicObjectInstance::GetPortal(DWORD dwIndex) +{ + if (dwIndex >= PORTAL_ID_MAX_NUM) + { + assert(dwIndex < PORTAL_ID_MAX_NUM); + return 0; + } + + return m_abyPortalID[dwIndex]; +} diff --git a/source/EterLib/GrpObjectInstance.h b/source/EterLib/GrpObjectInstance.h new file mode 100644 index 0000000..707af30 --- /dev/null +++ b/source/EterLib/GrpObjectInstance.h @@ -0,0 +1,161 @@ +#pragma once + +#include "GrpColorInstance.h" +#include "GrpScreen.h" +#include "CullingManager.h" +#include "CollisionData.h" +#include "AttributeInstance.h" + +enum +{ + THING_OBJECT = 0xadf21f13, + TREE_OBJECT = 0x8ac9f7a6, + ACTOR_OBJECT = 0x29a76c24, + EFFECT_OBJECT = 0x1cfa97c6, + DUNGEON_OBJECT = 0x18326035, +}; + +enum +{ + PORTAL_ID_MAX_NUM = 8, +}; + +class CGraphicObjectInstance : public CGraphicCollisionObject +{ + public: + CGraphicObjectInstance(); + virtual ~CGraphicObjectInstance(); + virtual int GetType() const = 0; + + public: + const D3DXVECTOR3 & GetPosition() const; + const D3DXVECTOR3 & GetScale() const; + float GetRotation(); + float GetYaw(); + float GetPitch(); + float GetRoll(); + + void SetPosition(float x, float y, float z); + void SetPosition(const D3DXVECTOR3 & newposition); + void SetScale(float x, float y, float z); + void SetRotation(float fRotation); + void SetRotation(float fYaw, float fPitch, float fRoll); + void SetRotationQuaternion(const D3DXQUATERNION &q); + void SetRotationMatrix(const D3DXMATRIX & m); + + void Clear(); + void Update(); + bool Render(); + void BlendRender(); + void RenderToShadowMap(); + void RenderShadow(); + void RenderPCBlocker(); + void Deform(); + void Transform(); + + void Show(); + void Hide(); + bool isShow(); + + // Camera Block + void BlockCamera(bool bBlock) {m_BlockCamera = bBlock;} + bool BlockCamera() { return m_BlockCamera; } + + // Ray Test + bool isIntersect(const CRay & c_rRay, float * pu, float * pv, float * pt); + + // Bounding Box + D3DXVECTOR4 & GetWTBBoxVertex(const unsigned char & c_rucNumTBBoxVertex); + D3DXVECTOR3 & GetTBBoxMin() { return m_v3TBBoxMin; } + D3DXVECTOR3 & GetTBBoxMax() { return m_v3TBBoxMax; } + D3DXVECTOR3 & GetBBoxMin() { return m_v3BBoxMin; } + D3DXVECTOR3 & GetBBoxMax() { return m_v3BBoxMax; } + + // Matrix + D3DXMATRIX & GetTransform(); + const D3DXMATRIX& GetWorldMatrix() { return m_worldMatrix; } + + // Portal + void SetPortal(DWORD dwIndex, int iID); + int GetPortal(DWORD dwIndex); + + // Initialize + void Initialize(); + virtual void OnInitialize(); + + // Bounding Sphere + public: + void UpdateBoundingSphere(); + void RegisterBoundingSphere(); + virtual bool GetBoundingSphere(D3DXVECTOR3 & v3Center, float & fRadius) = 0; + + virtual void OnRender() = 0; + virtual void OnBlendRender() = 0; + virtual void OnRenderToShadowMap() = 0; + virtual void OnRenderShadow() = 0; + virtual void OnRenderPCBlocker() = 0; + virtual void OnClear(){} + virtual void OnUpdate(){} + virtual void OnDeform(){} + + protected: + D3DXVECTOR3 m_v3Position; + D3DXVECTOR3 m_v3Scale; + + float m_fYaw; + float m_fPitch; + float m_fRoll; + + D3DXMATRIX m_mRotation; + + bool m_isVisible; + D3DXMATRIX m_worldMatrix; + + // Camera Block + bool m_BlockCamera; + + // Bounding Box + D3DXVECTOR4 m_v4TBBox[8]; + D3DXVECTOR3 m_v3TBBoxMin, m_v3TBBoxMax; + D3DXVECTOR3 m_v3BBoxMin, m_v3BBoxMax; + + // Portal + BYTE m_abyPortalID[PORTAL_ID_MAX_NUM]; + + // Culling + CCullingManager::CullingHandle m_CullingHandle; + + // Static Collision Data + public: + void AddCollision(const CStaticCollisionData * pscd, const D3DXMATRIX * pMat); + void ClearCollision(); + bool CollisionDynamicSphere(const CDynamicSphereInstance & s) const; + bool MovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const; + D3DXVECTOR3 GetCollisionMovementAdjust(const CDynamicSphereInstance & s) const; + + void UpdateCollisionData(const CStaticCollisionDataVector * pscdVector = 0); + + protected: + CCollisionInstanceVector m_StaticCollisionInstanceVector; + virtual void OnUpdateCollisionData(const CStaticCollisionDataVector * pscdVector) = 0; + + // using in WorldEditor + public: + DWORD GetCollisionInstanceCount(); + CBaseCollisionInstance * GetCollisionInstanceData(DWORD dwIndex); + + // Height Data + public: + void SetHeightInstance(CAttributeInstance * pAttributeInstance); + void ClearHeightInstance(); + + void UpdateHeightInstance(CAttributeInstance * pAttributeInstance = 0); + + bool IsObjectHeight(); + bool GetObjectHeight(float fX, float fY, float * pfHeight); + + protected: + CAttributeInstance * m_pHeightAttributeInstance; + virtual void OnUpdateHeighInstance(CAttributeInstance * pAttributeInstance) = 0; + virtual bool OnGetObjectHeight(float fX, float fY, float * pfHeight) = 0; +}; diff --git a/source/EterLib/GrpPixelShader.cpp b/source/EterLib/GrpPixelShader.cpp new file mode 100644 index 0000000..0b1ffbe --- /dev/null +++ b/source/EterLib/GrpPixelShader.cpp @@ -0,0 +1,55 @@ +#include "StdAfx.h" +#include "GrpPixelShader.h" +#include "GrpD3DXBuffer.h" +#include "StateManager.h" + +CPixelShader::CPixelShader() +{ + Initialize(); +} + +CPixelShader::~CPixelShader() +{ + Destroy(); +} + +void CPixelShader::Initialize() +{ + m_handle=0; +} + +void CPixelShader::Destroy() +{ + if (m_handle) + { + if (ms_lpd3dDevice) + ms_lpd3dDevice->DeletePixelShader(m_handle); + m_handle=0; + } +} + +bool CPixelShader::CreateFromDiskFile(const char* c_szFileName) +{ + Destroy(); + + LPD3DXBUFFER lpd3dxShaderBuffer; + LPD3DXBUFFER lpd3dxErrorBuffer; + + if (FAILED( + D3DXAssembleShaderFromFile(c_szFileName, 0, NULL, &lpd3dxShaderBuffer, &lpd3dxErrorBuffer) + )) + return false; + + CDirect3DXBuffer shaderBuffer(lpd3dxShaderBuffer); + CDirect3DXBuffer errorBuffer(lpd3dxErrorBuffer); + + if (FAILED(ms_lpd3dDevice->CreatePixelShader((DWORD*)shaderBuffer.GetPointer(), &m_handle))) + return false; + + return true; +} + +void CPixelShader::Set() +{ + STATEMANAGER.SetPixelShader(m_handle); +} diff --git a/source/EterLib/GrpPixelShader.h b/source/EterLib/GrpPixelShader.h new file mode 100644 index 0000000..2fb860a --- /dev/null +++ b/source/EterLib/GrpPixelShader.h @@ -0,0 +1,21 @@ +#pragma once + +#include "GrpBase.h" + +class CPixelShader : public CGraphicBase +{ + public: + CPixelShader(); + virtual ~CPixelShader(); + + void Destroy(); + bool CreateFromDiskFile(const char* c_szFileName); + + void Set(); + + protected: + void Initialize(); + + protected: + DWORD m_handle; +}; diff --git a/source/EterLib/GrpRatioInstance.cpp b/source/EterLib/GrpRatioInstance.cpp new file mode 100644 index 0000000..5249467 --- /dev/null +++ b/source/EterLib/GrpRatioInstance.cpp @@ -0,0 +1,67 @@ +#include "StdAfx.h" +#include "GrpRatioInstance.h" +#include "../eterBase/Timer.h" + +CGraphicRatioInstance::CGraphicRatioInstance() +{ + m_baseTime = 0; + m_blendTime = 0; +} + +CGraphicRatioInstance::~CGraphicRatioInstance() +{ +} + +void CGraphicRatioInstance::Clear() +{ + m_curRatio = 0.0f; + m_srcRatio = 0.0f; + m_dstRatio = 0.0f; + + m_baseTime = 0; + m_blendTime = 0; +} + +void CGraphicRatioInstance::SetRatioReference(const float& c_rRatio) +{ + m_curRatio = c_rRatio; + m_srcRatio = m_curRatio; + m_dstRatio = m_curRatio; +} + +void CGraphicRatioInstance::BlendRatioReference(DWORD blendTime, const float& c_rDstRatio) +{ + m_baseTime = GetTime(); + m_blendTime = blendTime; + + m_srcRatio = m_curRatio; + m_dstRatio = c_rDstRatio; +} + +void CGraphicRatioInstance::Update() +{ + DWORD curTime = GetTime(); + DWORD elapsedTime = curTime - m_baseTime; + + if (elapsedTime < m_blendTime) + { + float diff = m_dstRatio - m_srcRatio; + float rate = elapsedTime / float(m_blendTime); + m_curRatio = diff * rate + m_srcRatio; + } + else + { + m_curRatio = m_dstRatio; + } +} + +DWORD CGraphicRatioInstance::GetTime() +{ + return CTimer::Instance().GetCurrentMillisecond(); +} + +const float& CGraphicRatioInstance::GetCurrentRatioReference() const +{ + return m_curRatio; +} + diff --git a/source/EterLib/GrpRatioInstance.h b/source/EterLib/GrpRatioInstance.h new file mode 100644 index 0000000..40c27a8 --- /dev/null +++ b/source/EterLib/GrpRatioInstance.h @@ -0,0 +1,28 @@ +#pragma once + +class CGraphicRatioInstance +{ + public: + CGraphicRatioInstance(); + virtual ~CGraphicRatioInstance(); + + void Clear(); + + void SetRatioReference(const float& ratio); + void BlendRatioReference(DWORD blendTime, const float& ratio); + + void Update(); + + const float& GetCurrentRatioReference() const; + + protected: + DWORD GetTime(); + + protected: + float m_curRatio; + float m_srcRatio; + float m_dstRatio; + + DWORD m_baseTime; + DWORD m_blendTime; +}; diff --git a/source/EterLib/GrpScreen.cpp b/source/EterLib/GrpScreen.cpp new file mode 100644 index 0000000..cae80bd --- /dev/null +++ b/source/EterLib/GrpScreen.cpp @@ -0,0 +1,859 @@ +#include "StdAfx.h" +#include "GrpScreen.h" +#include "Camera.h" +#include "StateManager.h" + +DWORD CScreen::ms_diffuseColor = 0xffffffff; +DWORD CScreen::ms_clearColor = 0L; +DWORD CScreen::ms_clearStencil = 0L; +float CScreen::ms_clearDepth = 1.0f; +Frustum CScreen::ms_frustum; + +extern bool GRAPHICS_CAPS_CAN_NOT_DRAW_LINE; + +void CScreen::RenderLine3d(float sx, float sy, float sz, float ex, float ey, float ez) +{ + if (GRAPHICS_CAPS_CAN_NOT_DRAW_LINE) + return; + + assert(ms_lpd3dDevice != NULL); + + SPDTVertexRaw vertices[2] = + { + { sx, sy, sz, ms_diffuseColor, 0.0f, 0.0f }, + { ex, ey, ez, ms_diffuseColor, 0.0f, 0.0f } + }; + + // 2004.11.18.myevan.DrawIndexPrimitiveUP -> DynamicVertexBuffer + if (SetPDTStream(vertices, 2)) + { + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + STATEMANAGER.DrawPrimitive(D3DPT_LINELIST, 0, 1); + } +} + +void CScreen::RenderBox3d(float sx, float sy, float sz, float ex, float ey, float ez) +{ + if (GRAPHICS_CAPS_CAN_NOT_DRAW_LINE) + return; + + assert(ms_lpd3dDevice != NULL); + + SPDTVertexRaw vertices[8] = + { + { sx, sy, sz, ms_diffuseColor, 0.0f, 0.0f }, // 0 + { ex, sy, sz, ms_diffuseColor, 0.0f, 0.0f }, // 1 + + { sx, sy, sz, ms_diffuseColor, 0.0f, 0.0f }, // 0 + { sx, ey, ez, ms_diffuseColor, 0.0f, 0.0f }, // 2 + + { ex, sy, sz, ms_diffuseColor, 0.0f, 0.0f }, // 1 + { ex, ey, ez, ms_diffuseColor, 0.0f, 0.0f }, // 3 + + { sx, ey, ez, ms_diffuseColor, 0.0f, 0.0f }, // 2 + { ex+1.0f, ey, ez, ms_diffuseColor, 0.0f, 0.0f } // 3, (x 1 3) + }; + + // 2004.11.18.myevan.DrawIndexPrimitiveUP -> DynamicVertexBuffer + if (SetPDTStream(vertices, 8)) + { + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + STATEMANAGER.DrawPrimitive(D3DPT_LINELIST, 0, 4); + } +} + +void CScreen::RenderBar3d(float sx, float sy, float sz, float ex, float ey, float ez) +{ + assert(ms_lpd3dDevice != NULL); + + SPDTVertexRaw vertices[4] = + { + { sx, sy, sz, ms_diffuseColor, 0.0f, 0.0f }, + { sx, ey, ez, ms_diffuseColor, 0.0f, 0.0f }, + { ex, sy, sz, ms_diffuseColor, 0.0f, 0.0f }, + { ex, ey, ez, ms_diffuseColor, 0.0f, 0.0f }, + }; + + + + if (SetPDTStream(vertices, 4)) + { + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + STATEMANAGER.DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); + } +} + +void CScreen::RenderBar3d(const D3DXVECTOR3 * c_pv3Positions) +{ + assert(ms_lpd3dDevice != NULL); + + SPDTVertexRaw vertices[4] = + { + { c_pv3Positions[0].x, c_pv3Positions[0].y, c_pv3Positions[0].z, ms_diffuseColor, 0.0f, 0.0f }, + { c_pv3Positions[2].x, c_pv3Positions[2].y, c_pv3Positions[2].z, ms_diffuseColor, 0.0f, 0.0f }, + { c_pv3Positions[1].x, c_pv3Positions[1].y, c_pv3Positions[1].z, ms_diffuseColor, 0.0f, 0.0f }, + { c_pv3Positions[3].x, c_pv3Positions[3].y, c_pv3Positions[3].z, ms_diffuseColor, 0.0f, 0.0f }, + }; + + + if (SetPDTStream(vertices, 4)) + { + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + STATEMANAGER.DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); + } +} + +void CScreen::RenderGradationBar3d(float sx, float sy, float sz, float ex, float ey, float ez, DWORD dwStartColor, DWORD dwEndColor) +{ + assert(ms_lpd3dDevice != NULL); + if (sx==ex) return; + if (sy==ey) return; + + SPDTVertexRaw vertices[4] = + { + { sx, sy, sz, dwStartColor, 0.0f, 0.0f }, + { sx, ey, ez, dwEndColor, 0.0f, 0.0f }, + { ex, sy, sz, dwStartColor, 0.0f, 0.0f }, + { ex, ey, ez, dwEndColor, 0.0f, 0.0f }, + }; + + if (SetPDTStream(vertices, 4)) + { + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + STATEMANAGER.DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); + } +} + +void CScreen::RenderLineCube(float sx, float sy, float sz, float ex, float ey, float ez) +{ + SPDTVertexRaw vertices[8] = + { + { sx, sy, sz, ms_diffuseColor, 0.0f, 0.0f }, + { ex, sy, sz, ms_diffuseColor, 0.0f, 0.0f }, + { sx, ey, sz, ms_diffuseColor, 0.0f, 0.0f }, + { ex, ey, sz, ms_diffuseColor, 0.0f, 0.0f }, + { sx, sy, ez, ms_diffuseColor, 0.0f, 0.0f }, + { ex, sy, ez, ms_diffuseColor, 0.0f, 0.0f }, + { sx, ey, ez, ms_diffuseColor, 0.0f, 0.0f }, + { ex, ey, ez, ms_diffuseColor, 0.0f, 0.0f }, + }; + + + if (SetPDTStream(vertices, 8)) + { + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + STATEMANAGER.SetTransform(D3DTS_WORLD, ms_lpd3dMatStack->GetTop()); + SetDefaultIndexBuffer(DEFAULT_IB_LINE_CUBE); + + STATEMANAGER.DrawIndexedPrimitive(D3DPT_LINELIST, 0, 8, 0, 4*3); + } +} + +void CScreen::RenderCube(float sx, float sy, float sz, float ex, float ey, float ez) +{ + SPDTVertexRaw vertices[8] = + { + { sx, sy, sz, ms_diffuseColor, 0.0f, 0.0f }, + { ex, sy, sz, ms_diffuseColor, 0.0f, 0.0f }, + { sx, ey, sz, ms_diffuseColor, 0.0f, 0.0f }, + { ex, ey, sz, ms_diffuseColor, 0.0f, 0.0f }, + { sx, sy, ez, ms_diffuseColor, 0.0f, 0.0f }, + { ex, sy, ez, ms_diffuseColor, 0.0f, 0.0f }, + { sx, ey, ez, ms_diffuseColor, 0.0f, 0.0f }, + { ex, ey, ez, ms_diffuseColor, 0.0f, 0.0f }, + }; + + + if (SetPDTStream(vertices, 8)) + { + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + STATEMANAGER.SetTransform(D3DTS_WORLD, ms_lpd3dMatStack->GetTop()); + + SetDefaultIndexBuffer(DEFAULT_IB_FILL_CUBE); + STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 8, 0, 4*3); + } +} + +void CScreen::RenderCube(float sx, float sy, float sz, float ex, float ey, float ez, D3DXMATRIX matRotation) +{ + D3DXVECTOR3 v3Center = D3DXVECTOR3((sx + ex) * 0.5f, (sy + ey) * 0.5f, (sz + ez) * 0.5f); + D3DXVECTOR3 v3Vertex[8] = + { + D3DXVECTOR3(sx, sy, sz), + D3DXVECTOR3(ex, sy, sz), + D3DXVECTOR3(sx, ey, sz), + D3DXVECTOR3(ex, ey, sz), + D3DXVECTOR3(sx, sy, ez), + D3DXVECTOR3(ex, sy, ez), + D3DXVECTOR3(sx, ey, ez), + D3DXVECTOR3(ex, ey, ez), + }; + SPDTVertexRaw vertices[8]; + + for(int i = 0; i < 8; i++) + { + v3Vertex[i] = v3Vertex[i] - v3Center; + D3DXVec3TransformCoord(&v3Vertex[i], &v3Vertex[i], &matRotation); + v3Vertex[i] = v3Vertex[i] + v3Center; + vertices[i].px = v3Vertex[i].x; + vertices[i].py = v3Vertex[i].y; + vertices[i].pz = v3Vertex[i].z; + vertices[i].diffuse = ms_diffuseColor; + vertices[i].u = 0.0f; vertices[i].v = 0.0f; + } + + if (SetPDTStream(vertices, 8)) + { + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + STATEMANAGER.SetTransform(D3DTS_WORLD, ms_lpd3dMatStack->GetTop()); + + SetDefaultIndexBuffer(DEFAULT_IB_FILL_CUBE); + STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 8, 0, 4*3); + } +} + +void CScreen::RenderLine2d(float sx, float sy, float ex, float ey, float z) +{ + RenderLine3d(sx, sy, z, ex, ey, z); +} + +void CScreen::RenderBox2d(float sx, float sy, float ex, float ey, float z) +{ + RenderBox3d(sx, sy, z, ex, ey, z); +} + +void CScreen::RenderBar2d(float sx, float sy, float ex, float ey, float z) +{ + RenderBar3d(sx, sy, z, ex, ey, z); +} + +void CScreen::RenderGradationBar2d(float sx, float sy, float ex, float ey, DWORD dwStartColor, DWORD dwEndColor, float ez) +{ + RenderGradationBar3d(sx, sy, ez, ex, ey, ez, dwStartColor, dwEndColor); +} + +void CScreen::RenderCircle2d(float fx, float fy, float fz, float fRadius, int iStep) +{ + int count; + float theta, delta; + float x, y, z; + std::vector pts; + + pts.clear(); + pts.resize(iStep); + + theta = 0.0; + delta = 2 * D3DX_PI / float(iStep); + + for (count=0; count pts; + + pts.clear(); + pts.resize(iStep); + + theta = 0.0; + delta = 2 * D3DX_PI / float(iStep); + + const D3DXMATRIX & c_rmatInvView = CCameraManager::Instance().GetCurrentCamera()->GetBillboardMatrix(); + + for (count=0; countGetVertexShader(&m_dwVS); + + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + STATEMANAGER.SetRenderState(D3DRS_FILLMODE, d3dFillMode); + STATEMANAGER.SaveTransform(D3DTS_WORLD, &c_rmatWorld); + + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SetTexture(1, NULL); + } + + virtual ~CD3DXMeshRenderingOption() + { + ms_lpd3dDevice->SetVertexShader(m_dwVS); + + STATEMANAGER.RestoreTransform(D3DTS_WORLD); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAOP); + STATEMANAGER.SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + } +}; + +void CScreen::RenderD3DXMesh(LPD3DXMESH lpMesh, const D3DXMATRIX * c_pmatWorld, float fx, float fy, float fz, float fRadius, D3DFILLMODE d3dFillMode) +{ + D3DXMATRIX matTranslation; + D3DXMATRIX matScaling; + + D3DXMatrixTranslation(&matTranslation, fx, fy, fz); + D3DXMatrixScaling(&matScaling, fRadius, fRadius, fRadius); + + D3DXMATRIX matWorld; + matWorld = matScaling * matTranslation; + + if (c_pmatWorld) + { + matWorld *= *c_pmatWorld; + } + + CD3DXMeshRenderingOption SetRenderingOption(d3dFillMode, matWorld); + LPDIRECT3DINDEXBUFFER8 lpIndexBuffer; + LPDIRECT3DVERTEXBUFFER8 lpVertexBuffer; + lpMesh->GetIndexBuffer(&lpIndexBuffer); + lpMesh->GetVertexBuffer(&lpVertexBuffer); + STATEMANAGER.SetVertexShader(lpMesh->GetFVF()); + STATEMANAGER.SetIndices(lpIndexBuffer, 0); + STATEMANAGER.SetStreamSource(0, lpVertexBuffer, 24); + STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, lpMesh->GetNumVertices(), 0, lpMesh->GetNumFaces()); +} + +void CScreen::RenderSphere(const D3DXMATRIX * c_pmatWorld, float fx, float fy, float fz, float fRadius, D3DFILLMODE d3dFillMode) +{ + RenderD3DXMesh(ms_lpSphereMesh, c_pmatWorld, fx, fy, fz, fRadius, d3dFillMode); +} + +void CScreen::RenderCylinder(const D3DXMATRIX * c_pmatWorld, float fx, float fy, float fz, float fRadius, float /*fLength*/, D3DFILLMODE d3dFillMode) +{ + RenderD3DXMesh(ms_lpCylinderMesh, c_pmatWorld, fx, fy, fz, fRadius, d3dFillMode); +} + +void CScreen::RenderTextureBox(float sx, float sy, float ex, float ey, float z, float su, float sv, float eu, float ev) +{ + assert(ms_lpd3dDevice != NULL); + + TPDTVertex vertices[4]; + + vertices[0].position = TPosition(sx, sy, z); + vertices[0].diffuse = ms_diffuseColor; + vertices[0].texCoord = TTextureCoordinate(su, sv); + + vertices[1].position = TPosition(ex, sy, z); + vertices[1].diffuse = ms_diffuseColor; + vertices[1].texCoord = TTextureCoordinate(eu, sv); + + vertices[2].position = TPosition(sx, ey, z); + vertices[2].diffuse = ms_diffuseColor; + vertices[2].texCoord = TTextureCoordinate(su, ev); + + vertices[3].position = TPosition(ex, ey, z); + vertices[3].diffuse = ms_diffuseColor; + vertices[3].texCoord = TTextureCoordinate(eu, ev); + +#ifdef WORLD_EDITOR + STATEMANAGER.SetTransform(D3DTS_WORLD, ms_lpd3dMatStack->GetTop()); +#endif + STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + + // 2004.11.18.myevan.DrawIndexPrimitiveUP -> DynamicVertexBuffer + SetDefaultIndexBuffer(DEFAULT_IB_FILL_RECT); + if (SetPDTStream(vertices, 4)) + STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 4, 0, 2); + //OLD: STATEMANAGER.DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &ms_fillRectIdxVector[0], D3DFMT_INDEX16, vertices, sizeof(TPDTVertex)); +} + + +void CScreen::RenderBillboard(D3DXVECTOR3 * Position, D3DXCOLOR & Color) +{ + assert(ms_lpd3dDevice != NULL); + + TPDTVertex vertices[4]; + vertices[0].position = TPosition(Position[0].x, Position[0].y, Position[0].z); + vertices[0].diffuse = Color; + vertices[0].texCoord = TTextureCoordinate(0, 0); + + vertices[1].position = TPosition(Position[1].x, Position[1].y, Position[1].z); + vertices[1].diffuse = Color; + vertices[1].texCoord = TTextureCoordinate(1, 0); + + vertices[2].position = TPosition(Position[2].x, Position[2].y, Position[2].z); + vertices[2].diffuse = Color; + vertices[2].texCoord = TTextureCoordinate(0, 1); + + vertices[3].position = TPosition(Position[3].x, Position[3].y, Position[3].z); + vertices[3].diffuse = Color; + vertices[3].texCoord = TTextureCoordinate(1, 1); + + STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + + // 2004.11.18.myevan.DrawIndexPrimitiveUP -> DynamicVertexBuffer + SetDefaultIndexBuffer(DEFAULT_IB_FILL_RECT); + if (SetPDTStream(vertices, 4)) + STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 4, 0, 2); + //OLD: STATEMANAGER.DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &ms_fillRectIdxVector[0], D3DFMT_INDEX16, vertices, sizeof(TPDTVertex)); +} + +void CScreen::DrawMinorGrid(float xMin, float yMin, float xMax, float yMax, float xminorStep, float yminorStep, float zPos) +{ + float x, y; + + for (y = yMin; y <= yMax; y += yminorStep) + RenderLine2d(xMin, y, xMax, y, zPos); + + for (x = xMin; x <= xMax; x += xminorStep) + RenderLine2d(x, yMin, x, yMax, zPos); +} + +void CScreen::DrawGrid(float xMin, float yMin, float xMax, float yMax, float xmajorStep, float ymajorStep, float xminorStep, float yminorStep, float zPos) +{ + xMin*=xminorStep; + xMax*=xminorStep; + yMin*=yminorStep; + yMax*=yminorStep; + xmajorStep*=xminorStep; + ymajorStep*=yminorStep; + + float x, y; + + SetDiffuseColor(0.5f, 0.5f, 0.5f); + DrawMinorGrid(xMin, yMin, xMax, yMax, xminorStep, yminorStep, zPos); + + SetDiffuseColor(0.7f, 0.7f, 0.7f); + for (y = 0.0f; y >= yMin; y -= ymajorStep) + RenderLine2d(xMin, y, xMax, y, zPos); + + for (y = 0.0f; y <= yMax; y += ymajorStep) + RenderLine2d(xMin, y, xMax, y, zPos); + + for (x = 0.0f; x >= xMin; x -= xmajorStep) + RenderLine2d(x, yMin, x, yMax, zPos); + + for (x = 0.0f; x <= yMax; x += xmajorStep) + RenderLine2d(x, yMin, x, yMax, zPos); + + SetDiffuseColor(1.0f, 1.0f, 1.0f); + RenderLine2d(xMin, 0.0f, xMax, 0.0f, zPos); + RenderLine2d(0.0f, yMin, 0.0f, yMax, zPos); +} + +void CScreen::SetCursorPosition(int x, int y, int hres, int vres) +{ + D3DXVECTOR3 v; + v.x = -(((2.0f * x) / hres) - 1) / ms_matProj._11; + v.y = (((2.0f * y) / vres) - 1) / ms_matProj._22; + v.z = 1.0f; + + D3DXMATRIX matViewInverse=ms_matInverseView; + //D3DXMatrixInverse(&matViewInverse, NULL, &ms_matView); + + ms_vtPickRayDir.x = v.x * matViewInverse._11 + + v.y * matViewInverse._21 + + v.z * matViewInverse._31; + + ms_vtPickRayDir.y = v.x * matViewInverse._12 + + v.y * matViewInverse._22 + + v.z * matViewInverse._32; + + ms_vtPickRayDir.z = v.x * matViewInverse._13 + + v.y * matViewInverse._23 + + v.z * matViewInverse._33; + + ms_vtPickRayOrig.x = matViewInverse._41; + ms_vtPickRayOrig.y = matViewInverse._42; + ms_vtPickRayOrig.z = matViewInverse._43; + +// // 2003. 9. 9 ߰ +// // picking ... Ѥ; Ͱ ʿ... + ms_Ray.SetStartPoint(ms_vtPickRayOrig); + ms_Ray.SetDirection(-ms_vtPickRayDir, 51200.0f); +// // 2003. 9. 9 ߰ +} + +bool CScreen::GetCursorPosition(float* px, float* py, float* pz) +{ + if (!GetCursorXYPosition(px, py)) return false; + if (!GetCursorZPosition(pz)) return false; + + return true; +} + +bool CScreen::GetCursorXYPosition(float* px, float* py) +{ + D3DXVECTOR3 v3Eye = CCameraManager::Instance().GetCurrentCamera()->GetEye(); + + TPosition posVertices[4]; + posVertices[0] = TPosition(v3Eye.x-90000000.0f, v3Eye.y+90000000.0f, 0.0f); + posVertices[1] = TPosition(v3Eye.x-90000000.0f, v3Eye.y-90000000.0f, 0.0f); + posVertices[2] = TPosition(v3Eye.x+90000000.0f, v3Eye.y+90000000.0f, 0.0f); + posVertices[3] = TPosition(v3Eye.x+90000000.0f, v3Eye.y-90000000.0f, 0.0f); + + static const WORD sc_awFillRectIndices[6] = { 0, 2, 1, 2, 3, 1, }; + + float u, v, t; + for (int i = 0; i < 2; ++i) + { + if (IntersectTriangle(ms_vtPickRayOrig, ms_vtPickRayDir, + posVertices[sc_awFillRectIndices[i*3+0]], + posVertices[sc_awFillRectIndices[i*3+1]], + posVertices[sc_awFillRectIndices[i*3+2]], + &u, &v, &t)) + { + *px = ms_vtPickRayOrig.x + ms_vtPickRayDir.x * t; + *py = ms_vtPickRayOrig.y + ms_vtPickRayDir.y * t; + return true; + } + } + return false; +} + +bool CScreen::GetCursorZPosition(float* pz) +{ + D3DXVECTOR3 v3Eye = CCameraManager::Instance().GetCurrentCamera()->GetEye(); + + TPosition posVertices[4]; + posVertices[0] = TPosition(v3Eye.x-90000000.0f, 0.0f, v3Eye.z+90000000.0f); + posVertices[1] = TPosition(v3Eye.x-90000000.0f, 0.0f, v3Eye.z-90000000.0f); + posVertices[2] = TPosition(v3Eye.x+90000000.0f, 0.0f, v3Eye.z+90000000.0f); + posVertices[3] = TPosition(v3Eye.x+90000000.0f, 0.0f, v3Eye.z-90000000.0f); + + static const WORD sc_awFillRectIndices[6] = { 0, 2, 1, 2, 3, 1, }; + + float u, v, t; + for (int i = 0; i < 2; ++i) + { + if (IntersectTriangle(ms_vtPickRayOrig, ms_vtPickRayDir, + posVertices[sc_awFillRectIndices[i*3+0]], + posVertices[sc_awFillRectIndices[i*3+1]], + posVertices[sc_awFillRectIndices[i*3+2]], + &u, &v, &t)) + { + *pz = ms_vtPickRayOrig.z + ms_vtPickRayDir.z * t; + return true; + } + } + return false; +} + +void CScreen::GetPickingPosition(float t, float* x, float* y, float* z) +{ + *x = ms_vtPickRayOrig.x + ms_vtPickRayDir.x * t; + *y = ms_vtPickRayOrig.y + ms_vtPickRayDir.y * t; + *z = ms_vtPickRayOrig.z + ms_vtPickRayDir.z * t; +} + +void CScreen::SetDiffuseColor(DWORD diffuseColor) +{ + ms_diffuseColor = diffuseColor; +} + +void CScreen::SetDiffuseColor(float r, float g, float b, float a) +{ + ms_diffuseColor = GetColor(r, g, b, a); +} + +void CScreen::SetClearColor(float r, float g, float b, float a) +{ + ms_clearColor = GetColor(r, g, b, a); +} + +void CScreen::SetClearDepth(float depth) +{ + ms_clearDepth = depth; +} + +void CScreen::SetClearStencil(DWORD stencil) +{ + ms_clearStencil = stencil; +} + +void CScreen::ClearDepthBuffer() +{ + assert(ms_lpd3dDevice != NULL); + ms_lpd3dDevice->Clear(0L, NULL, D3DCLEAR_ZBUFFER, ms_clearColor, ms_clearDepth, ms_clearStencil); +} + +void CScreen::Clear() +{ + assert(ms_lpd3dDevice != NULL); + ms_lpd3dDevice->Clear(0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, ms_clearColor, ms_clearDepth, ms_clearStencil); +} + +BOOL CScreen::IsLostDevice() +{ + if (!ms_lpd3dDevice) + return TRUE; + + IDirect3DDevice8 & rkD3DDev = *ms_lpd3dDevice; + HRESULT hrTestCooperativeLevel = rkD3DDev.TestCooperativeLevel(); + if (FAILED(hrTestCooperativeLevel)) + return TRUE; + + return FALSE; +} + +BOOL CScreen::RestoreDevice() +{ + if (!ms_lpd3dDevice) + return FALSE; + + UINT iD3DAdapterInfo = ms_iD3DAdapterInfo; + IDirect3D8 & rkD3D = *ms_lpd3d; + IDirect3DDevice8 & rkD3DDev = *ms_lpd3dDevice; + D3DPRESENT_PARAMETERS & rkD3DPP = ms_d3dPresentParameter; + D3D_CDisplayModeAutoDetector & rkD3DDetector = ms_kD3DDetector; + + HRESULT hrTestCooperativeLevel = rkD3DDev.TestCooperativeLevel(); + + if (FAILED(hrTestCooperativeLevel)) + { + if (D3DERR_DEVICELOST == hrTestCooperativeLevel) + { + return FALSE; + } + + if (D3DERR_DEVICENOTRESET == hrTestCooperativeLevel) + { + D3D_CAdapterInfo* pkD3DAdapterInfo = rkD3DDetector.GetD3DAdapterInfop(ms_iD3DAdapterInfo); + + if (!pkD3DAdapterInfo) + return FALSE; + + D3DDISPLAYMODE & rkD3DDMDesktop = pkD3DAdapterInfo->GetDesktopD3DDisplayModer(); + + if (FAILED(rkD3D.GetAdapterDisplayMode(iD3DAdapterInfo, &rkD3DDMDesktop))) + return FALSE; + + rkD3DPP.BackBufferFormat = rkD3DDMDesktop.Format; + + HRESULT hrReset = rkD3DDev.Reset(&rkD3DPP); + + if (FAILED(hrReset)) + { + return FALSE; + } + + STATEMANAGER.SetDefaultState(); + } + } + + return TRUE; + +} + +bool CScreen::Begin() +{ + assert(ms_lpd3dDevice != NULL); + ResetFaceCount(); + + if (!STATEMANAGER.BeginScene()) + { + Tracenf("BeginScene FAILED\n"); + return false; + } + + return true; +} + +void CScreen::End() +{ + STATEMANAGER.EndScene(); +} + +extern bool g_isBrowserMode; +extern RECT g_rcBrowser; + +void CScreen::Show(HWND hWnd) +{ + assert(ms_lpd3dDevice != NULL); + + if (g_isBrowserMode) + { + RECT rcTop={ static_cast(0), static_cast(0), static_cast(ms_d3dPresentParameter.BackBufferWidth), static_cast(g_rcBrowser.top)}; + RECT rcBottom={0, g_rcBrowser.bottom, static_cast(ms_d3dPresentParameter.BackBufferWidth), static_cast(ms_d3dPresentParameter.BackBufferHeight)}; + RECT rcLeft={0, g_rcBrowser.top, g_rcBrowser.left, g_rcBrowser.bottom}; + RECT rcRight={g_rcBrowser.right, g_rcBrowser.top, static_cast(ms_d3dPresentParameter.BackBufferWidth), g_rcBrowser.bottom}; + + ms_lpd3dDevice->Present(&rcTop, &rcTop, hWnd, NULL); + ms_lpd3dDevice->Present(&rcBottom, &rcBottom, hWnd, NULL); + ms_lpd3dDevice->Present(&rcLeft, &rcLeft, hWnd, NULL); + ms_lpd3dDevice->Present(&rcRight, &rcRight, hWnd, NULL); + } + else + { + HRESULT hr=ms_lpd3dDevice->Present(NULL, NULL, hWnd, NULL); + if (D3DERR_DEVICELOST == hr) + RestoreDevice(); + } +} + +void CScreen::Show(RECT * pSrcRect) +{ + assert(ms_lpd3dDevice != NULL); + ms_lpd3dDevice->Present(pSrcRect, NULL, NULL, NULL); +} + +void CScreen::Show(RECT * pSrcRect, HWND hWnd) +{ + assert(ms_lpd3dDevice != NULL); + ms_lpd3dDevice->Present(pSrcRect, NULL, hWnd, NULL); +} + +void CScreen::ProjectPosition(float x, float y, float z, float * pfX, float * pfY) +{ + D3DXVECTOR3 Input(x, y, z); + D3DXVECTOR3 Output; + D3DXVec3Project(&Output, &Input, &ms_Viewport, &ms_matProj, &ms_matView, &ms_matWorld); + + *pfX = Output.x; + *pfY = Output.y; +} + +void CScreen::ProjectPosition(float x, float y, float z, float * pfX, float * pfY, float * pfZ) +{ + D3DXVECTOR3 Input(x, y, z); + D3DXVECTOR3 Output; + D3DXVec3Project(&Output, &Input, &ms_Viewport, &ms_matProj, &ms_matView, &ms_matWorld); + + *pfX = Output.x; + *pfY = Output.y; + *pfZ = Output.z; +} + +void CScreen::UnprojectPosition(float x, float y, float z, float * pfX, float * pfY, float * pfZ) +{ + D3DXVECTOR3 Input(x, y, z); + D3DXVECTOR3 Output; + D3DXVec3Unproject(&Output, &Input, &ms_Viewport, &ms_matProj, &ms_matView, &ms_matWorld); + + *pfX = Output.x; + *pfY = Output.y; + *pfZ = Output.z; +} + +void CScreen::SetColorOperation() +{ + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); +} + +void CScreen::SetDiffuseOperation() +{ + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); +} + +void CScreen::SetBlendOperation() +{ + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); +} + +void CScreen::SetOneColorOperation(D3DXCOLOR & rColor) +{ + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SetTexture(1, NULL); + + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, rColor); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); +} + +void CScreen::SetAddColorOperation(D3DXCOLOR & rColor) +{ + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, rColor); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_ADD); +} + +void CScreen::Identity() +{ + STATEMANAGER.SetTransform(D3DTS_WORLD, &ms_matIdentity); +} + +CScreen::CScreen() +{ +} + +CScreen::~CScreen() +{ +} +//void BuildViewFrustum() { ms_frustum.BuildViewFrustum(ms_matView*ms_matProj); } + +void CScreen::BuildViewFrustum() +{ + const D3DXVECTOR3& c_rv3Eye=CCameraManager::Instance().GetCurrentCamera()->GetEye(); + const D3DXVECTOR3& c_rv3View=CCameraManager::Instance().GetCurrentCamera()->GetView(); + auto vv = ms_matView * ms_matProj; + ms_frustum.BuildViewFrustum2( + vv, + ms_fNearY, + ms_fFarY, + ms_fFieldOfView, + ms_fAspect, + c_rv3Eye, c_rv3View); +} \ No newline at end of file diff --git a/source/EterLib/GrpScreen.h b/source/EterLib/GrpScreen.h new file mode 100644 index 0000000..61c4c19 --- /dev/null +++ b/source/EterLib/GrpScreen.h @@ -0,0 +1,82 @@ +#pragma once + +#include "GrpCollisionObject.h" +#include "../SphereLib/frustum.h" + + +class CScreen : public CGraphicCollisionObject +{ +public: + CScreen(); + virtual ~CScreen(); + + void ClearDepthBuffer(); + void Clear(); + bool Begin(); + void End(); + void Show(HWND hWnd = NULL); + void Show(RECT * pSrcRect); + void Show(RECT * pSrcRect, HWND hWnd); + + void RenderLine2d(float sx, float sy, float ex, float ey, float z=0.0f); + void RenderBox2d(float sx, float sy, float ex, float ey, float z=0.0f); + void RenderBar2d(float sx, float sy, float ex, float ey, float z=0.0f); + void RenderGradationBar2d(float sx, float sy, float ex, float ey, DWORD dwStartColor, DWORD dwEndColor, float ez=0.0f); + void RenderCircle2d(float fx, float fy, float fz, float fRadius, int iStep = 50); + void RenderCircle3d(float fx, float fy, float fz, float fRadius, int iStep = 50); + + void RenderLine3d(float sx, float sy, float sz, float ex, float ey, float ez); + void RenderBox3d(float sx, float sy, float sz, float ex, float ey, float ez); + void RenderBar3d(float sx, float sy, float sz, float ex, float ey, float ez); + void RenderBar3d(const D3DXVECTOR3 * c_pv3Positions); + void RenderGradationBar3d(float sx, float sy, float sz, float ex, float ey, float ez, DWORD dwStartColor, DWORD dwEndColor); + + void RenderLineCube(float sx, float sy, float sz, float ex, float ey, float ez); + void RenderCube(float sx, float sy, float sz, float ex, float ey, float ez); + void RenderCube(float sx, float sy, float sz, float ex, float ey, float ez, D3DXMATRIX matRotation); + void RenderTextureBox(float sx, float sy, float ex, float ey, float z=0.0f, float su=0.0f, float sv=0.0f, float eu=1.0f, float ev=1.0f); + void RenderBillboard(D3DXVECTOR3 * Position, D3DXCOLOR & Color); + + void DrawMinorGrid(float xMin, float yMin, float xMax, float yMax, float xminorStep, float yminorStep, float zPos=0); + void DrawGrid(float xMin, float yMin, float xMax, float yMax, float xmajorStep, float ymajorStep, float xminorStep, float yminorStep, float zPos=0); + + void RenderD3DXMesh(LPD3DXMESH lpMesh, const D3DXMATRIX * c_pmatWorld, float fx, float fy, float fz, float fRadius, D3DFILLMODE d3dFillMode); + void RenderSphere(const D3DXMATRIX * c_pmatWorld, float fx, float fy, float fz, float fRadius, D3DFILLMODE d3dFillMode = D3DFILL_SOLID); + void RenderCylinder(const D3DXMATRIX * c_pmatWorld, float fx, float fy, float fz, float fRadius, float fLength, D3DFILLMODE d3dFillMode = D3DFILL_SOLID); + + void SetColorOperation(); + void SetDiffuseOperation(); + void SetBlendOperation(); + void SetOneColorOperation(D3DXCOLOR & rColor); + void SetAddColorOperation(D3DXCOLOR & rColor); + void SetDiffuseColor(DWORD diffuseColor); + void SetDiffuseColor(float r, float g, float b, float a=1.0f); + void SetClearColor(float r, float g, float b, float a=1.0f); + void SetClearDepth(float depth); + void SetClearStencil(DWORD stencil); + + void SetCursorPosition(int x, int y, int hres, int vres); // creates picking ray + bool GetCursorPosition(float* px, float* py, float* pz); + bool GetCursorXYPosition(float* px, float* py); + bool GetCursorZPosition(float* pz); + void GetPickingPosition(float t, float* x, float* y, float* z); + void ProjectPosition(float x, float y, float z, float * pfX, float * pfY); + void ProjectPosition(float x, float y, float z, float * pfX, float * pfY, float * pfZ); + void UnprojectPosition(float x, float y, float z, float * pfX, float * pfY, float * pfZ); + + BOOL IsLostDevice(); + BOOL RestoreDevice(); + + void BuildViewFrustum(); + + static void Identity(); + static Frustum & GetFrustum() { return ms_frustum; } + +protected: + static DWORD ms_diffuseColor; + static DWORD ms_clearColor; + static DWORD ms_clearStencil; + static float ms_clearDepth; + + static Frustum ms_frustum; +}; diff --git a/source/EterLib/GrpShadowTexture.cpp b/source/EterLib/GrpShadowTexture.cpp new file mode 100644 index 0000000..1e02e78 --- /dev/null +++ b/source/EterLib/GrpShadowTexture.cpp @@ -0,0 +1,191 @@ +#include "StdAfx.h" +#include "GrpShadowTexture.h" +#include "StateManager.h" + +////////////////////////////////////////////////////////////////////////// +void CGraphicShadowTexture::Destroy() +{ + CGraphicTexture::Destroy(); + + if (m_lpd3dShadowSurface) + { + m_lpd3dShadowSurface->Release(); + m_lpd3dShadowSurface = NULL; + } + + if (m_lpd3dDepthSurface) + { + m_lpd3dDepthSurface->Release(); + m_lpd3dDepthSurface = NULL; + } + + if (m_lpd3dShadowTexture) + { + m_lpd3dShadowTexture->Release(); + m_lpd3dShadowTexture = NULL; + } + + Initialize(); +} + +bool CGraphicShadowTexture::Create(int width, int height) +{ + Destroy(); + + m_width = width; + m_height = height; + + if (FAILED(ms_lpd3dDevice->CreateTexture(m_width, m_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_lpd3dShadowTexture))) + return false; + + if (FAILED(m_lpd3dShadowTexture->GetSurfaceLevel(0, &m_lpd3dShadowSurface))) + return false; + + if (FAILED(ms_lpd3dDevice->CreateDepthStencilSurface(m_width, m_height, D3DFMT_D16, D3DMULTISAMPLE_NONE, &m_lpd3dDepthSurface))) + return false; + + return true; +} + +void CGraphicShadowTexture::Set(int stage) const +{ + STATEMANAGER.SetTexture(stage, m_lpd3dShadowTexture); +} + +const D3DXMATRIX& CGraphicShadowTexture::GetLightVPMatrixReference() const +{ + return m_d3dLightVPMatrix; +} + +LPDIRECT3DTEXTURE8 CGraphicShadowTexture::GetD3DTexture() const +{ + return m_lpd3dShadowTexture; +} + +void CGraphicShadowTexture::Begin() +{ + D3DXMatrixMultiply(&m_d3dLightVPMatrix, &ms_matView, &ms_matProj); + + ms_lpd3dDevice->GetRenderTarget(&m_lpd3dOldBackBufferSurface); + ms_lpd3dDevice->GetDepthStencilSurface(&m_lpd3dOldDepthBufferSurface); + ms_lpd3dDevice->GetViewport(&m_d3dOldViewport); + + ms_lpd3dDevice->SetRenderTarget(m_lpd3dShadowSurface, m_lpd3dDepthSurface); + + D3DVIEWPORT8 d3dViewport; + d3dViewport.MinZ = 0.0f; + d3dViewport.MaxZ = 1.0f; + d3dViewport.X = 0; + d3dViewport.Y = 0; + d3dViewport.Width = m_width; + d3dViewport.Height = m_height; + + ms_lpd3dDevice->SetViewport(&d3dViewport); + ms_lpd3dDevice->BeginScene(); + + ms_lpd3dDevice->Clear(0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L); + + STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + STATEMANAGER.SaveRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, true); + STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, true); + STATEMANAGER.SaveRenderState(D3DRS_TEXTUREFACTOR, 0xbb000000); + + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + + STATEMANAGER.SaveTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_POINT); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_POINT); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_POINT); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); + + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + + STATEMANAGER.SaveTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_POINT); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_POINT); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_POINT); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); +} + +void CGraphicShadowTexture::End() +{ + assert(m_lpd3dOldBackBufferSurface != NULL); + assert(m_lpd3dOldDepthBufferSurface != NULL); + + ms_lpd3dDevice->EndScene(); + + ms_lpd3dDevice->SetRenderTarget(m_lpd3dOldBackBufferSurface, m_lpd3dOldDepthBufferSurface); + ms_lpd3dDevice->SetViewport(&m_d3dOldViewport); + + m_lpd3dOldBackBufferSurface->Release(); + m_lpd3dOldDepthBufferSurface->Release(); + + m_lpd3dOldBackBufferSurface = NULL; + m_lpd3dOldDepthBufferSurface = NULL; + + STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE); + STATEMANAGER.RestoreRenderState(D3DRS_ZFUNC); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_TEXTUREFACTOR); + + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG2); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAARG1); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAARG2); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAOP); + + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MINFILTER); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MAGFILTER); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MIPFILTER); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSU); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSV); + + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_COLORARG1); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_COLORARG2); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_COLOROP); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ALPHAARG1); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ALPHAARG2); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ALPHAOP); + + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_MINFILTER); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_MAGFILTER); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_MIPFILTER); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSU); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSV); +} + +void CGraphicShadowTexture::Initialize() +{ + CGraphicTexture::Initialize(); + + m_lpd3dShadowSurface = NULL; + m_lpd3dDepthSurface = NULL; + m_lpd3dOldBackBufferSurface = NULL; + m_lpd3dOldDepthBufferSurface = NULL; + m_lpd3dShadowTexture = NULL; +} + +CGraphicShadowTexture::CGraphicShadowTexture() +{ + Initialize(); +} + +CGraphicShadowTexture::~CGraphicShadowTexture() +{ + Destroy(); +} \ No newline at end of file diff --git a/source/EterLib/GrpShadowTexture.h b/source/EterLib/GrpShadowTexture.h new file mode 100644 index 0000000..e6b2882 --- /dev/null +++ b/source/EterLib/GrpShadowTexture.h @@ -0,0 +1,35 @@ +#pragma once + +#include "GrpTexture.h" + +class CGraphicShadowTexture : public CGraphicTexture +{ + public: + CGraphicShadowTexture(); + virtual ~CGraphicShadowTexture(); + + void Destroy(); + + bool Create(int width, int height); + + void Begin(); + void End(); + void Set(int stage = 0) const; + + const D3DXMATRIX& GetLightVPMatrixReference() const; + LPDIRECT3DTEXTURE8 GetD3DTexture() const; + + protected: + void Initialize(); + + protected: + D3DXMATRIX m_d3dLightVPMatrix; + D3DVIEWPORT8 m_d3dOldViewport; + + LPDIRECT3DTEXTURE8 m_lpd3dShadowTexture; + LPDIRECT3DSURFACE8 m_lpd3dShadowSurface; + LPDIRECT3DSURFACE8 m_lpd3dDepthSurface; + + LPDIRECT3DSURFACE8 m_lpd3dOldBackBufferSurface; + LPDIRECT3DSURFACE8 m_lpd3dOldDepthBufferSurface; +}; diff --git a/source/EterLib/GrpSubImage.cpp b/source/EterLib/GrpSubImage.cpp new file mode 100644 index 0000000..1e01eda --- /dev/null +++ b/source/EterLib/GrpSubImage.cpp @@ -0,0 +1,156 @@ +#include "StdAfx.h" +#include "../eterBase/Stl.h" +#include "../eterBase/FileLoader.h" +#include "GrpSubImage.h" +#include "ResourceManager.h" + +char CGraphicSubImage::m_SearchPath[256] = "D:/Ymir Work/UI/"; + +CGraphicSubImage::TType CGraphicSubImage::Type() +{ + static TType s_type = StringToType("CGraphicSubImage"); + return s_type; +} + +CGraphicSubImage::CGraphicSubImage(const char* c_szFileName) : CGraphicImage(c_szFileName) +{ +} + +CGraphicSubImage::~CGraphicSubImage() +{ + m_roImage = NULL; +} + +bool CGraphicSubImage::CreateDeviceObjects() +{ + m_imageTexture.CreateFromTexturePointer(m_roImage->GetTexturePointer()); + return true; +} + +void CGraphicSubImage::SetImagePointer(CGraphicImage* pImage) +{ + m_roImage = pImage; + CreateDeviceObjects(); +} + +bool CGraphicSubImage::SetImageFileName(const char* c_szFileName) +{ + CResource* pResource = CResourceManager::Instance().GetResourcePointer(c_szFileName); + + if (!pResource->IsType(CGraphicImage::Type())) + return false; + + SetImagePointer(static_cast(pResource)); + return true; +} + +void CGraphicSubImage::SetRectPosition(int left, int top, int right, int bottom) +{ + m_rect.left = left; + m_rect.top = top; + m_rect.right = right; + m_rect.bottom = bottom; +} + +void CGraphicSubImage::SetRectReference(const RECT& c_rRect) +{ + m_rect = c_rRect; +} + +void CGraphicSubImage::SetSearchPath(const char * c_szFileName) +{ + strncpy(m_SearchPath, c_szFileName, sizeof(m_SearchPath)-1); +} + +bool CGraphicSubImage::OnLoad(int iSize, const void* c_pvBuf) +{ + if (!c_pvBuf) + return false; + + CTokenVector stTokenVector; + std::map stTokenMap; + + CMemoryTextFileLoader textFileLoader; + + textFileLoader.Bind(iSize, c_pvBuf); + + for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i) + { + if (!textFileLoader.SplitLine(i, &stTokenVector)) + continue; + + if (stTokenVector.size() != 2) + return false; + + stl_lowers(stTokenVector[0]); + stl_lowers(stTokenVector[1]); + + stTokenMap[stTokenVector[0]] = stTokenVector[1]; + } + + const std::string& c_rstTitle = stTokenMap["title"]; + const std::string& c_rstVersion = stTokenMap["version"]; + const std::string& c_rstImage = stTokenMap["image"]; + const std::string& c_rstLeft = stTokenMap["left"]; + const std::string& c_rstTop = stTokenMap["top"]; + const std::string& c_rstRight = stTokenMap["right"]; + const std::string& c_rstBottom = stTokenMap["bottom"]; + + if (c_rstTitle != "subimage") + return false; + + char szFileName[256]; + if ("2.0"==c_rstVersion) + { + const std::string& c_rstSubFileName=GetFileNameString(); + int nPos=c_rstSubFileName.find_last_of('\\', -1); + if (nPos>=0) + { + nPos++; + memcpy(szFileName, c_rstSubFileName.c_str(), nPos); + szFileName[nPos]='\0'; + memcpy(szFileName+nPos, c_rstImage.c_str(), c_rstImage.length()); + szFileName[nPos+c_rstImage.length()]='\0'; + } + else + { + memcpy(szFileName, c_rstImage.c_str(), c_rstImage.length()); + } + } + else + { + _snprintf(szFileName, sizeof(szFileName), "%s%s", m_SearchPath, c_rstImage.c_str()); + } + + SetImageFileName(szFileName); + + SetRectPosition(atoi(c_rstLeft.c_str()), + atoi(c_rstTop.c_str()), + atoi(c_rstRight.c_str()), + atoi(c_rstBottom.c_str())); + + return true; +} + +void CGraphicSubImage::OnClear() +{ + m_roImage = NULL; + memset(&m_rect, 0, sizeof(m_rect)); +} + +bool CGraphicSubImage::OnIsEmpty() const +{ + if (!m_roImage.IsNull()) + if (!m_roImage->IsEmpty()) + return false; + + return true; +} + +bool CGraphicSubImage::OnIsType(TType type) +{ + if (CGraphicSubImage::Type() == type) + return true; + + return CGraphicImage::OnIsType(type); +} \ No newline at end of file diff --git a/source/EterLib/GrpSubImage.h b/source/EterLib/GrpSubImage.h new file mode 100644 index 0000000..d47d9f4 --- /dev/null +++ b/source/EterLib/GrpSubImage.h @@ -0,0 +1,38 @@ +#pragma once + +#include "GrpImage.h" + +class CGraphicSubImage : public CGraphicImage +{ + public: + typedef CRef TRef; + + public: + static TType Type(); + static char m_SearchPath[256]; + + public: + CGraphicSubImage(const char* c_szFileName); + virtual ~CGraphicSubImage(); + + bool CreateDeviceObjects(); + + bool SetImageFileName(const char* c_szFileName); + + void SetRectPosition(int left, int top, int right, int bottom); + + void SetRectReference(const RECT& c_rRect); + + static void SetSearchPath(const char * c_szFileName); + + protected: + void SetImagePointer(CGraphicImage* pImage); + + bool OnLoad(int iSize, const void* c_pvBuf); + void OnClear(); + bool OnIsEmpty() const; + bool OnIsType(TType type); + + protected: + CGraphicImage::TRef m_roImage; +}; diff --git a/source/EterLib/GrpText.cpp b/source/EterLib/GrpText.cpp new file mode 100644 index 0000000..a47d64f --- /dev/null +++ b/source/EterLib/GrpText.cpp @@ -0,0 +1,101 @@ +#include "StdAfx.h" +#include "../eterBase/Utils.h" +#include "GrpText.h" + +CGraphicText::CGraphicText(const char* c_szFileName) : CResource(c_szFileName) +{ +} + +CGraphicText::~CGraphicText() +{ +} + +bool CGraphicText::CreateDeviceObjects() +{ + return m_fontTexture.CreateDeviceObjects(); +} + +void CGraphicText::DestroyDeviceObjects() +{ + m_fontTexture.DestroyDeviceObjects(); +} + +CGraphicFontTexture* CGraphicText::GetFontTexturePointer() +{ + return &m_fontTexture; +} + +CGraphicText::TType CGraphicText::Type() +{ + static TType s_type = StringToType("CGraphicText"); + return s_type; +} + +bool CGraphicText::OnLoad(int /*iSize*/, const void* /*c_pvBuf*/) +{ + static char strName[32]; + int size; + bool bItalic = false; + + // format + // .fnt "" Ʈ ⺻ 12 ε + // :18.fnt "" Ʈ 18 ε + // :14i.fnt "" Ʈ 14 & Ÿ ε + const char * p = strrchr(GetFileName(), ':'); + + if (p) + { + strncpy(strName, GetFileName(), MIN(31, p - GetFileName())); + ++p; + + static char num[8]; + + int i = 0; + while (*p && isdigit(*p)) + { + num[i++] = *(p++); + } + + num[i] = '\0'; + if(*p == 'i') + bItalic = true; + size = atoi(num); + } + else + { + p = strrchr(GetFileName(), '.'); + + if (!p) + { + assert(!"CGraphicText::OnLoadFromFile there is no extension (ie: .fnt)"); + strName[0] = '\0'; + } + else + strncpy(strName, GetFileName(), MIN(31, p - GetFileName())); + + size = 12; + } + + if (!m_fontTexture.Create(strName, size, bItalic)) + return false; + + return true; +} + +void CGraphicText::OnClear() +{ + m_fontTexture.Destroy(); +} + +bool CGraphicText::OnIsEmpty() const +{ + return m_fontTexture.IsEmpty(); +} + +bool CGraphicText::OnIsType(TType type) +{ + if (CGraphicText::Type() == type) + return true; + + return CResource::OnIsType(type); +} diff --git a/source/EterLib/GrpText.h b/source/EterLib/GrpText.h new file mode 100644 index 0000000..17885cd --- /dev/null +++ b/source/EterLib/GrpText.h @@ -0,0 +1,32 @@ +#pragma once + +#include "Resource.h" +#include "Ref.h" +#include "GrpFontTexture.h" + +class CGraphicText : public CResource +{ + public: + typedef CRef TRef; + + public: + static TType Type(); + + public: + CGraphicText(const char* c_szFileName); + virtual ~CGraphicText(); + + virtual bool CreateDeviceObjects(); + virtual void DestroyDeviceObjects(); + + CGraphicFontTexture * GetFontTexturePointer(); + + protected: + bool OnLoad(int iSize, const void * c_pvBuf); + void OnClear(); + bool OnIsEmpty() const; + bool OnIsType(TType type); + + protected: + CGraphicFontTexture m_fontTexture; +}; diff --git a/source/EterLib/GrpTextInstance.cpp b/source/EterLib/GrpTextInstance.cpp new file mode 100644 index 0000000..1e08bff --- /dev/null +++ b/source/EterLib/GrpTextInstance.cpp @@ -0,0 +1,1150 @@ +#include "StdAfx.h" +#include "GrpTextInstance.h" +#include "StateManager.h" +#include "IME.h" +#include "TextTag.h" +#include "../EterLocale/StringCodec.h" +#include "../EterBase/Utils.h" +#include "../EterLocale/Arabic.h" + +extern DWORD GetDefaultCodePage(); + +const float c_fFontFeather = 0.5f; + +CDynamicPool CGraphicTextInstance::ms_kPool; + +static int gs_mx = 0; +static int gs_my = 0; + +static std::wstring gs_hyperlinkText; + +void CGraphicTextInstance::Hyperlink_UpdateMousePos(int x, int y) +{ + gs_mx = x; + gs_my = y; + gs_hyperlinkText = L""; +} + +int CGraphicTextInstance::Hyperlink_GetText(char* buf, int len) +{ + if (gs_hyperlinkText.empty()) + return 0; + + int codePage = GetDefaultCodePage(); + + return Ymir_WideCharToMultiByte(codePage, 0, gs_hyperlinkText.c_str(), gs_hyperlinkText.length(), buf, len, NULL, NULL); +} + +int CGraphicTextInstance::__DrawCharacter(CGraphicFontTexture * pFontTexture, WORD codePage, wchar_t text, DWORD dwColor) +{ + CGraphicFontTexture::TCharacterInfomation* pInsCharInfo = pFontTexture->GetCharacterInfomation(codePage, text); + + if (pInsCharInfo) + { + m_dwColorInfoVector.push_back(dwColor); + m_pCharInfoVector.push_back(pInsCharInfo); + + m_textWidth += pInsCharInfo->advance; + m_textHeight = max(pInsCharInfo->height, m_textHeight); + return pInsCharInfo->advance; + } + + return 0; +} + +void CGraphicTextInstance::__GetTextPos(DWORD index, float* x, float* y) +{ + index = min(index, m_pCharInfoVector.size()); + + float sx = 0; + float sy = 0; + float fFontMaxHeight = 0; + + for(DWORD i=0; iwidth) > m_fLimitWidth) + { + sx = 0; + sy += fFontMaxHeight; + } + + sx += float(m_pCharInfoVector[i]->advance); + fFontMaxHeight = max(float(m_pCharInfoVector[i]->height), fFontMaxHeight); + } + + *x = sx; + *y = sy; +} + +bool isNumberic(const char chr) +{ + if (chr >= '0' && chr <= '9') + return true; + return false; +} + +bool IsValidToken(const char* iter) +{ + return iter[0]=='@' && + isNumberic(iter[1]) && + isNumberic(iter[2]) && + isNumberic(iter[3]) && + isNumberic(iter[4]); +} + +const char* FindToken(const char* begin, const char* end) +{ + while(begin < end) + { + begin = std::find(begin, end, '@'); + + if(end-begin>5 && IsValidToken(begin)) + { + return begin; + } + else + { + ++begin; + } + } + + return end; +} + +int ReadToken(const char* token) +{ + int nRet = (token[1]-'0')*1000 + (token[2]-'0')*100 + (token[3]-'0')*10 + (token[4]-'0'); + if (nRet == 9999) + return CP_UTF8; + return nRet; +} + +void CGraphicTextInstance::Update() +{ + if (m_isUpdate) // ڿ ٲ Ʈ Ѵ. + return; + + if (m_roText.IsNull()) + { + Tracef("CGraphicTextInstance::Update - Ʈ ʾҽϴ\n"); + return; + } + + if (m_roText->IsEmpty()) + return; + + CGraphicFontTexture* pFontTexture = m_roText->GetFontTexturePointer(); + if (!pFontTexture) + return; + + UINT defCodePage = GetDefaultCodePage(); + + UINT dataCodePage = defCodePage; // ƶ Ʈ ͸ UTF8 Ϸ + + CGraphicFontTexture::TCharacterInfomation* pSpaceInfo = pFontTexture->GetCharacterInfomation(dataCodePage, ' '); + + int spaceHeight = pSpaceInfo ? pSpaceInfo->height : 12; + + m_pCharInfoVector.clear(); + m_dwColorInfoVector.clear(); + m_hyperlinkVector.clear(); + + m_textWidth = 0; + m_textHeight = spaceHeight; + + /* wstring begin */ + + const char* begin = m_stText.c_str(); + const char* end = begin + m_stText.length(); + + int wTextMax = (end - begin) * 2; + wchar_t* wText = (wchar_t*)_alloca(sizeof(wchar_t)*wTextMax); + + DWORD dwColor = m_dwTextColor; + + /* wstring end */ + while (begin < end) + { + const char * token = FindToken(begin, end); + + int wTextLen = Ymir_MultiByteToWideChar(dataCodePage, 0, begin, token - begin, wText, wTextMax); + + if (m_isSecret) + { + for(int i=0; i> + int x = 0; + + int len; + int hyperlinkStep = 0; + SHyperlink kHyperlink; + std::wstring hyperlinkBuffer; + int no_hyperlink = 0; + + // ɺ ƶ ؾѴ + if (Arabic_IsInSymbol(wArabicText[wArabicTextLen - 1])) + { + isEnglish = false; + } + + int i = 0; + for (i = wArabicTextLen - 1 ; i >= 0; --i) + { + wchar_t wArabicChar = wArabicText[i]; + + if (isEnglish) + { + + // <<ɺ (ex. ȣ, )>> -> . + // <<(ɺ ƴ ͵ : , , ƶ)>> + // (1) ɺ or + // (2) + // 1) ڰ ƶ ƴ && + // 2) ڰ ƶ ƴ && + // 3) ڰ ɺ'|' ƴ && + // or + // (3) ɺ '|' + // <<ƶ Ѿ : ɺ.>> + // 1) ձ ƶ + // 2) ޱ ƶ + // + // + if (Arabic_IsInSymbol(wArabicChar) && ( + (i == 0) || + (i > 0 && + !(Arabic_HasPresentation(wArabicText, i - 1) || Arabic_IsInPresentation(wArabicText[i + 1])) && //ձ, ޱڰ ƶ ƴ. + wArabicText[i+1] != '|' + ) || + wArabicText[i] == '|' + ))//if end. + { + // pass + int temptest = 1; + } + // (1)ƶ̰ų (2)ƶ ɺ̶ ƶ ȯ + else if (Arabic_IsInPresentation(wArabicChar) || Arabic_IsInSymbol(wArabicChar)) + { + //  ׸. + for (int e = i + 1; e <= nEnglishBase;) { + int ret = GetTextTag(&wArabicText[e], wArabicTextLen - e, len, hyperlinkBuffer); + + if (ret == TEXT_TAG_PLAIN || ret == TEXT_TAG_TAG) + { + if (hyperlinkStep == 1) + hyperlinkBuffer.append(1, wArabicText[e]); + else + { + int charWidth = __DrawCharacter(pFontTexture, dataCodePage, wArabicText[e], dwColor); + kHyperlink.ex += charWidth; + //x += charWidth; + + // ߰ ۸ũ ǥ . + for (int j = 1; j <= no_hyperlink; j++) + { + if(m_hyperlinkVector.size() < j) + break; + + SHyperlink & tempLink = m_hyperlinkVector[m_hyperlinkVector.size() - j]; + tempLink.ex += charWidth; + tempLink.sx += charWidth; + } + } + } + else + { + if (ret == TEXT_TAG_COLOR) + dwColor = htoi(hyperlinkBuffer.c_str(), 8); + else if (ret == TEXT_TAG_RESTORE_COLOR) + dwColor = m_dwTextColor; + else if (ret == TEXT_TAG_HYPERLINK_START) + { + hyperlinkStep = 1; + hyperlinkBuffer = L""; + } + else if (ret == TEXT_TAG_HYPERLINK_END) + { + if (hyperlinkStep == 1) + { + ++hyperlinkStep; + kHyperlink.ex = kHyperlink.sx = 0; // ؽƮ ۵Ǵ ġ + } + else + { + kHyperlink.text = hyperlinkBuffer; + m_hyperlinkVector.push_back(kHyperlink); + no_hyperlink++; + + + hyperlinkStep = 0; + hyperlinkBuffer = L""; + } + } + } + e += len; + } + + int charWidth = __DrawCharacter(pFontTexture, dataCodePage, Arabic_ConvSymbol(wArabicText[i]), dwColor); + kHyperlink.ex += charWidth; + + // ߰ ۸ũ ǥ . + for (int j = 1; j <= no_hyperlink; j++) + { + if(m_hyperlinkVector.size() < j) + break; + + SHyperlink & tempLink = m_hyperlinkVector[m_hyperlinkVector.size() - j]; + tempLink.ex += charWidth; + tempLink.sx += charWidth; + } + + isEnglish = false; + } + } + else //[[[ƶ ]]] + { + // ƶ̰ų ƶ ɺ̶ + if (Arabic_IsInPresentation(wArabicChar) || Arabic_IsInSymbol(wArabicChar)) + { + int charWidth = __DrawCharacter(pFontTexture, dataCodePage, Arabic_ConvSymbol(wArabicText[i]), dwColor); + kHyperlink.ex += charWidth; + x += charWidth; + + // ߰ ۸ũ ǥ . + for (int j = 1; j <= no_hyperlink; j++) + { + if(m_hyperlinkVector.size() < j) + break; + + SHyperlink & tempLink = m_hyperlinkVector[m_hyperlinkVector.size() - j]; + tempLink.ex += charWidth; + tempLink.sx += charWidth; + } + } + else //̰ų, ɺ̶, + { + nEnglishBase = i; + isEnglish = true; + } + } + } + + if (isEnglish) + { + for (int e = i + 1; e <= nEnglishBase;) { + int ret = GetTextTag(&wArabicText[e], wArabicTextLen - e, len, hyperlinkBuffer); + + if (ret == TEXT_TAG_PLAIN || ret == TEXT_TAG_TAG) + { + if (hyperlinkStep == 1) + hyperlinkBuffer.append(1, wArabicText[e]); + else + { + int charWidth = __DrawCharacter(pFontTexture, dataCodePage, wArabicText[e], dwColor); + kHyperlink.ex += charWidth; + + // ߰ ۸ũ ǥ . + for (int j = 1; j <= no_hyperlink; j++) + { + if(m_hyperlinkVector.size() < j) + break; + + SHyperlink & tempLink = m_hyperlinkVector[m_hyperlinkVector.size() - j]; + tempLink.ex += charWidth; + tempLink.sx += charWidth; + } + } + } + else + { + if (ret == TEXT_TAG_COLOR) + dwColor = htoi(hyperlinkBuffer.c_str(), 8); + else if (ret == TEXT_TAG_RESTORE_COLOR) + dwColor = m_dwTextColor; + else if (ret == TEXT_TAG_HYPERLINK_START) + { + hyperlinkStep = 1; + hyperlinkBuffer = L""; + } + else if (ret == TEXT_TAG_HYPERLINK_END) + { + if (hyperlinkStep == 1) + { + ++hyperlinkStep; + kHyperlink.ex = kHyperlink.sx = 0; // ؽƮ ۵Ǵ ġ + } + else + { + kHyperlink.text = hyperlinkBuffer; + m_hyperlinkVector.push_back(kHyperlink); + no_hyperlink++; + + hyperlinkStep = 0; + hyperlinkBuffer = L""; + } + } + } + e += len; + } + + } + } + else // ƶ ٸ . + { + int x = 0; + int len; + int hyperlinkStep = 0; + SHyperlink kHyperlink; + std::wstring hyperlinkBuffer; + + for (int i = 0; i < wTextLen; ) + { + int ret = GetTextTag(&wText[i], wTextLen - i, len, hyperlinkBuffer); + + if (ret == TEXT_TAG_PLAIN || ret == TEXT_TAG_TAG) + { + if (hyperlinkStep == 1) + hyperlinkBuffer.append(1, wText[i]); + else + { + int charWidth = __DrawCharacter(pFontTexture, dataCodePage, wText[i], dwColor); + kHyperlink.ex += charWidth; + x += charWidth; + } + } + else + { + if (ret == TEXT_TAG_COLOR) + dwColor = htoi(hyperlinkBuffer.c_str(), 8); + else if (ret == TEXT_TAG_RESTORE_COLOR) + dwColor = m_dwTextColor; + else if (ret == TEXT_TAG_HYPERLINK_START) + { + hyperlinkStep = 1; + hyperlinkBuffer = L""; + } + else if (ret == TEXT_TAG_HYPERLINK_END) + { + if (hyperlinkStep == 1) + { + ++hyperlinkStep; + kHyperlink.ex = kHyperlink.sx = x; // ؽƮ ۵Ǵ ġ + } + else + { + kHyperlink.text = hyperlinkBuffer; + m_hyperlinkVector.push_back(kHyperlink); + + hyperlinkStep = 0; + hyperlinkBuffer = L""; + } + } + } + i += len; + } + } + } + + if (token < end) + { + int newCodePage = ReadToken(token); + dataCodePage = newCodePage; // ƶ Ʈ ͸ UTF8 Ϸ + begin = token + 5; + } + else + { + begin = token; + } + } + + pFontTexture->UpdateTexture(); + + m_isUpdate = true; +} + +void CGraphicTextInstance::Render(RECT * pClipRect) +{ + if (!m_isUpdate) + return; + + CGraphicText* pkText=m_roText.GetPointer(); + if (!pkText) + return; + + CGraphicFontTexture* pFontTexture = pkText->GetFontTexturePointer(); + if (!pFontTexture) + return; + + float fStanX = m_v3Position.x; + float fStanY = m_v3Position.y + 1.0f; + + UINT defCodePage = GetDefaultCodePage(); + + if (defCodePage == CP_ARABIC) + { + switch (m_hAlign) + { + case HORIZONTAL_ALIGN_LEFT: + fStanX -= m_textWidth; + break; + + case HORIZONTAL_ALIGN_CENTER: + fStanX -= float(m_textWidth / 2); + break; + } + } + else + { + switch (m_hAlign) + { + case HORIZONTAL_ALIGN_RIGHT: + fStanX -= m_textWidth; + break; + + case HORIZONTAL_ALIGN_CENTER: + fStanX -= float(m_textWidth / 2); + break; + } + } + + switch (m_vAlign) + { + case VERTICAL_ALIGN_BOTTOM: + fStanY -= m_textHeight; + break; + + case VERTICAL_ALIGN_CENTER: + fStanY -= float(m_textHeight) / 2.0f; + break; + } + + //WORD FillRectIndices[6] = { 0, 2, 1, 2, 3, 1 }; + + STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + DWORD dwFogEnable = STATEMANAGER.GetRenderState(D3DRS_FOGENABLE); + DWORD dwLighting = STATEMANAGER.GetRenderState(D3DRS_LIGHTING); + STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, FALSE); + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); + + STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + + { + const float fFontHalfWeight=1.0f; + + float fCurX; + float fCurY; + + float fFontSx; + float fFontSy; + float fFontEx; + float fFontEy; + float fFontWidth; + float fFontHeight; + float fFontMaxHeight; + float fFontAdvance; + + SVertex akVertex[4]; + akVertex[0].z=m_v3Position.z; + akVertex[1].z=m_v3Position.z; + akVertex[2].z=m_v3Position.z; + akVertex[3].z=m_v3Position.z; + + CGraphicFontTexture::TCharacterInfomation* pCurCharInfo; + + // ׵θ + if (m_isOutline) + { + fCurX=fStanX; + fCurY=fStanY; + fFontMaxHeight=0.0f; + + CGraphicFontTexture::TPCharacterInfomationVector::iterator i; + for (i=m_pCharInfoVector.begin(); i!=m_pCharInfoVector.end(); ++i) + { + pCurCharInfo = *i; + + fFontWidth=float(pCurCharInfo->width); + fFontHeight=float(pCurCharInfo->height); + fFontAdvance=float(pCurCharInfo->advance); + + // NOTE : Ʈ ¿ Width Ӵϴ. - [levites] + if ((fCurX+fFontWidth)-m_v3Position.x > m_fLimitWidth) + { + if (m_isMultiLine) + { + fCurX=fStanX; + fCurY+=fFontMaxHeight; + } + else + { + break; + } + } + + if (pClipRect) + { + if (fCurY <= pClipRect->top) + { + fCurX += fFontAdvance; + continue; + } + } + + fFontSx = fCurX - 0.5f; + fFontSy = fCurY - 0.5f; + fFontEx = fFontSx + fFontWidth; + fFontEy = fFontSy + fFontHeight; + + pFontTexture->SelectTexture(pCurCharInfo->index); + STATEMANAGER.SetTexture(0, pFontTexture->GetD3DTexture()); + + akVertex[0].u=pCurCharInfo->left; + akVertex[0].v=pCurCharInfo->top; + akVertex[1].u=pCurCharInfo->left; + akVertex[1].v=pCurCharInfo->bottom; + akVertex[2].u=pCurCharInfo->right; + akVertex[2].v=pCurCharInfo->top; + akVertex[3].u=pCurCharInfo->right; + akVertex[3].v=pCurCharInfo->bottom; + + akVertex[3].color = akVertex[2].color = akVertex[1].color = akVertex[0].color = m_dwOutLineColor; + + + float feather = 0.0f; // m_fFontFeather + + akVertex[0].y=fFontSy-feather; + akVertex[1].y=fFontEy+feather; + akVertex[2].y=fFontSy-feather; + akVertex[3].y=fFontEy+feather; + + // + akVertex[0].x=fFontSx-fFontHalfWeight-feather; + akVertex[1].x=fFontSx-fFontHalfWeight-feather; + akVertex[2].x=fFontEx-fFontHalfWeight+feather; + akVertex[3].x=fFontEx-fFontHalfWeight+feather; + + if (CGraphicBase::SetPDTStream((SPDTVertex*)akVertex, 4)) + STATEMANAGER.DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); + + + // + akVertex[0].x=fFontSx+fFontHalfWeight-feather; + akVertex[1].x=fFontSx+fFontHalfWeight-feather; + akVertex[2].x=fFontEx+fFontHalfWeight+feather; + akVertex[3].x=fFontEx+fFontHalfWeight+feather; + + if (CGraphicBase::SetPDTStream((SPDTVertex*)akVertex, 4)) + STATEMANAGER.DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); + + akVertex[0].x=fFontSx-feather; + akVertex[1].x=fFontSx-feather; + akVertex[2].x=fFontEx+feather; + akVertex[3].x=fFontEx+feather; + + // + akVertex[0].y=fFontSy-fFontHalfWeight-feather; + akVertex[1].y=fFontEy-fFontHalfWeight+feather; + akVertex[2].y=fFontSy-fFontHalfWeight-feather; + akVertex[3].y=fFontEy-fFontHalfWeight+feather; + + // 20041216.myevan.DrawPrimitiveUP + if (CGraphicBase::SetPDTStream((SPDTVertex*)akVertex, 4)) + STATEMANAGER.DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); + + // Ʒ + akVertex[0].y=fFontSy+fFontHalfWeight-feather; + akVertex[1].y=fFontEy+fFontHalfWeight+feather; + akVertex[2].y=fFontSy+fFontHalfWeight-feather; + akVertex[3].y=fFontEy+fFontHalfWeight+feather; + + // 20041216.myevan.DrawPrimitiveUP + if (CGraphicBase::SetPDTStream((SPDTVertex*)akVertex, 4)) + STATEMANAGER.DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); + + fCurX += fFontAdvance; + } + } + + // Ʈ + fCurX=fStanX; + fCurY=fStanY; + fFontMaxHeight=0.0f; + + for (int i = 0; i < m_pCharInfoVector.size(); ++i) + { + pCurCharInfo = m_pCharInfoVector[i]; + + fFontWidth=float(pCurCharInfo->width); + fFontHeight=float(pCurCharInfo->height); + fFontMaxHeight=max(fFontHeight, pCurCharInfo->height); + fFontAdvance=float(pCurCharInfo->advance); + + // NOTE : Ʈ ¿ Width Ӵϴ. - [levites] + if ((fCurX+fFontWidth)-m_v3Position.x > m_fLimitWidth) + { + if (m_isMultiLine) + { + fCurX=fStanX; + fCurY+=fFontMaxHeight; + } + else + { + break; + } + } + + if (pClipRect) + { + if (fCurY <= pClipRect->top) + { + fCurX += fFontAdvance; + continue; + } + } + + fFontSx = fCurX-0.5f; + fFontSy = fCurY-0.5f; + fFontEx = fFontSx + fFontWidth; + fFontEy = fFontSy + fFontHeight; + + pFontTexture->SelectTexture(pCurCharInfo->index); + STATEMANAGER.SetTexture(0, pFontTexture->GetD3DTexture()); + + akVertex[0].x=fFontSx; + akVertex[0].y=fFontSy; + akVertex[0].u=pCurCharInfo->left; + akVertex[0].v=pCurCharInfo->top; + + akVertex[1].x=fFontSx; + akVertex[1].y=fFontEy; + akVertex[1].u=pCurCharInfo->left; + akVertex[1].v=pCurCharInfo->bottom; + + akVertex[2].x=fFontEx; + akVertex[2].y=fFontSy; + akVertex[2].u=pCurCharInfo->right; + akVertex[2].v=pCurCharInfo->top; + + akVertex[3].x=fFontEx; + akVertex[3].y=fFontEy; + akVertex[3].u=pCurCharInfo->right; + akVertex[3].v=pCurCharInfo->bottom; + + //m_dwColorInfoVector[i]; + //m_dwTextColor; + akVertex[0].color = akVertex[1].color = akVertex[2].color = akVertex[3].color = m_dwColorInfoVector[i]; + + // 20041216.myevan.DrawPrimitiveUP + if (CGraphicBase::SetPDTStream((SPDTVertex*)akVertex, 4)) + STATEMANAGER.DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); + //STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, akVertex, sizeof(SVertex)); + + fCurX += fFontAdvance; + } + } + + if (m_isCursor) + { + // Draw Cursor + float sx, sy, ex, ey; + TDiffuse diffuse; + + int curpos = CIME::GetCurPos(); + int compend = curpos + CIME::GetCompLen(); + + __GetTextPos(curpos, &sx, &sy); + + // If Composition + if(curpos DynamicVertexBuffer + CGraphicBase::SetDefaultIndexBuffer(CGraphicBase::DEFAULT_IB_FILL_RECT); + if (CGraphicBase::SetPDTStream(vertices, 4)) + STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 4, 0, 2); + + int ulbegin = CIME::GetULBegin(); + int ulend = CIME::GetULEnd(); + + if(ulbegin < ulend) + { + __GetTextPos(curpos+ulbegin, &sx, &sy); + __GetTextPos(curpos+ulend, &ex, &sy); + + sx += m_v3Position.x; + sy += m_v3Position.y + m_textHeight; + ex += m_v3Position.x; + ey = sy + 2; + + vertices[0].diffuse = 0xFFFF0000; + vertices[1].diffuse = 0xFFFF0000; + vertices[2].diffuse = 0xFFFF0000; + vertices[3].diffuse = 0xFFFF0000; + vertices[0].position = TPosition(sx, sy, 0.0f); + vertices[1].position = TPosition(ex, sy, 0.0f); + vertices[2].position = TPosition(sx, ey, 0.0f); + vertices[3].position = TPosition(ex, ey, 0.0f); + + STATEMANAGER.DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, c_FillRectIndices, D3DFMT_INDEX16, vertices, sizeof(TPDTVertex)); + } + } + + STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND); + STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND); + + STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, dwFogEnable); + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, dwLighting); + + //ݰ ũ ִ κ. + if (m_hyperlinkVector.size() != 0) + { + int lx = gs_mx - m_v3Position.x; + int ly = gs_my - m_v3Position.y; + + //ƶ ǥ ȣ ٲش. + if (GetDefaultCodePage() == CP_ARABIC) { + lx = -lx; + ly = -ly + m_textHeight; + } + + if (lx >= 0 && ly >= 0 && lx < m_textWidth && ly < m_textHeight) + { + std::vector::iterator it = m_hyperlinkVector.begin(); + + while (it != m_hyperlinkVector.end()) + { + SHyperlink & link = *it++; + if (lx >= link.sx && lx < link.ex) + { + gs_hyperlinkText = link.text; + /* + OutputDebugStringW(link.text.c_str()); + OutputDebugStringW(L"\n"); + */ + break; + } + } + } + } +} + +void CGraphicTextInstance::CreateSystem(UINT uCapacity) +{ + ms_kPool.Create(uCapacity); +} + +void CGraphicTextInstance::DestroySystem() +{ + ms_kPool.Destroy(); +} + +CGraphicTextInstance* CGraphicTextInstance::New() +{ + return ms_kPool.Alloc(); +} + +void CGraphicTextInstance::Delete(CGraphicTextInstance* pkInst) +{ + pkInst->Destroy(); + ms_kPool.Free(pkInst); +} + +void CGraphicTextInstance::ShowCursor() +{ + m_isCursor = true; +} + +void CGraphicTextInstance::HideCursor() +{ + m_isCursor = false; +} + +void CGraphicTextInstance::ShowOutLine() +{ + m_isOutline = true; +} + +void CGraphicTextInstance::HideOutLine() +{ + m_isOutline = false; +} + +void CGraphicTextInstance::SetColor(DWORD color) +{ + if (m_dwTextColor != color) + { + for (int i = 0; i < m_pCharInfoVector.size(); ++i) + if (m_dwColorInfoVector[i] == m_dwTextColor) + m_dwColorInfoVector[i] = color; + + m_dwTextColor = color; + } +} + +void CGraphicTextInstance::SetColor(float r, float g, float b, float a) +{ + SetColor(D3DXCOLOR(r, g, b, a)); +} + +void CGraphicTextInstance::SetOutLineColor(DWORD color) +{ + m_dwOutLineColor=color; +} + +void CGraphicTextInstance::SetOutLineColor(float r, float g, float b, float a) +{ + m_dwOutLineColor=D3DXCOLOR(r, g, b, a); +} + +void CGraphicTextInstance::SetSecret(bool Value) +{ + m_isSecret = Value; +} + +void CGraphicTextInstance::SetOutline(bool Value) +{ + m_isOutline = Value; +} + +void CGraphicTextInstance::SetFeather(bool Value) +{ + if (Value) + { + m_fFontFeather = c_fFontFeather; + } + else + { + m_fFontFeather = 0.0f; + } +} + +void CGraphicTextInstance::SetMultiLine(bool Value) +{ + m_isMultiLine = Value; +} + +void CGraphicTextInstance::SetHorizonalAlign(int hAlign) +{ + m_hAlign = hAlign; +} + +void CGraphicTextInstance::SetVerticalAlign(int vAlign) +{ + m_vAlign = vAlign; +} + +void CGraphicTextInstance::SetMax(int iMax) +{ + m_iMax = iMax; +} + +void CGraphicTextInstance::SetLimitWidth(float fWidth) +{ + m_fLimitWidth = fWidth; +} + +void CGraphicTextInstance::SetValueString(const std::string& c_stValue) +{ + if (0 == m_stText.compare(c_stValue)) + return; + + m_stText = c_stValue; + m_isUpdate = false; +} + +void CGraphicTextInstance::SetValue(const char* c_szText, size_t len) +{ + if (0 == m_stText.compare(c_szText)) + return; + + m_stText = c_szText; + m_isUpdate = false; +} + +void CGraphicTextInstance::SetPosition(float fx, float fy, float fz) +{ + m_v3Position.x = fx; + m_v3Position.y = fy; + m_v3Position.z = fz; +} + +void CGraphicTextInstance::SetTextPointer(CGraphicText* pText) +{ + m_roText = pText; +} + +const std::string & CGraphicTextInstance::GetValueStringReference() +{ + return m_stText; +} + +WORD CGraphicTextInstance::GetTextLineCount() +{ + CGraphicFontTexture::TCharacterInfomation* pCurCharInfo; + CGraphicFontTexture::TPCharacterInfomationVector::iterator itor; + + float fx = 0.0f; + WORD wLineCount = 1; + for (itor=m_pCharInfoVector.begin(); itor!=m_pCharInfoVector.end(); ++itor) + { + pCurCharInfo = *itor; + + float fFontWidth=float(pCurCharInfo->width); + float fFontAdvance=float(pCurCharInfo->advance); + //float fFontHeight=float(pCurCharInfo->height); + + // NOTE : Ʈ ¿ Width Ӵϴ. - [levites] + if (fx+fFontWidth > m_fLimitWidth) + { + fx = 0.0f; + ++wLineCount; + } + + fx += fFontAdvance; + } + + return wLineCount; +} + +void CGraphicTextInstance::GetTextSize(int* pRetWidth, int* pRetHeight) +{ + *pRetWidth = m_textWidth; + *pRetHeight = m_textHeight; +} + +int CGraphicTextInstance::PixelPositionToCharacterPosition(int iPixelPosition) +{ + int icurPosition = 0; + for (int i = 0; i < (int)m_pCharInfoVector.size(); ++i) + { + CGraphicFontTexture::TCharacterInfomation* pCurCharInfo = m_pCharInfoVector[i]; + icurPosition += pCurCharInfo->width; + + if (iPixelPosition < icurPosition) + return i; + } + + return -1; +} + +int CGraphicTextInstance::GetHorizontalAlign() +{ + return m_hAlign; +} + +void CGraphicTextInstance::__Initialize() +{ + m_roText = NULL; + + m_hAlign = HORIZONTAL_ALIGN_LEFT; + m_vAlign = VERTICAL_ALIGN_TOP; + + m_iMax = 0; + m_fLimitWidth = 1600.0f; // NOTE : ػ ִġ. ̺ ? - [levites] + + m_isCursor = false; + m_isSecret = false; + m_isMultiLine = false; + + m_isOutline = false; + m_fFontFeather = c_fFontFeather; + + m_isUpdate = false; + + m_textWidth = 0; + m_textHeight = 0; + + m_v3Position.x = m_v3Position.y = m_v3Position.z = 0.0f; + + m_dwOutLineColor=0xff000000; +} + +void CGraphicTextInstance::Destroy() +{ + m_stText=""; + m_pCharInfoVector.clear(); + m_dwColorInfoVector.clear(); + m_hyperlinkVector.clear(); + + __Initialize(); +} + +CGraphicTextInstance::CGraphicTextInstance() +{ + __Initialize(); +} + +CGraphicTextInstance::~CGraphicTextInstance() +{ + Destroy(); +} diff --git a/source/EterLib/GrpTextInstance.h b/source/EterLib/GrpTextInstance.h new file mode 100644 index 0000000..a87fa33 --- /dev/null +++ b/source/EterLib/GrpTextInstance.h @@ -0,0 +1,134 @@ +#ifndef __INC_ETERLIB_GRPTEXTINSTANCE_H__ +#define __INC_ETERLIB_GRPTEXTINSTANCE_H__ + +#include "Pool.h" +#include "GrpText.h" + +class CGraphicTextInstance +{ + public: + typedef CDynamicPool TPool; + + public: + enum EHorizontalAlign + { + HORIZONTAL_ALIGN_LEFT = 0x01, + HORIZONTAL_ALIGN_CENTER = 0x02, + HORIZONTAL_ALIGN_RIGHT = 0x03, + }; + enum EVerticalAlign + { + VERTICAL_ALIGN_TOP = 0x10, + VERTICAL_ALIGN_CENTER = 0x20, + VERTICAL_ALIGN_BOTTOM = 0x30 + }; + + public: + static void Hyperlink_UpdateMousePos(int x, int y); + static int Hyperlink_GetText(char* buf, int len); + + public: + CGraphicTextInstance(); + virtual ~CGraphicTextInstance(); + + void Destroy(); + + void Update(); + void Render(RECT * pClipRect = NULL); + + void ShowCursor(); + void HideCursor(); + + void ShowOutLine(); + void HideOutLine(); + + void SetColor(DWORD color); + void SetColor(float r, float g, float b, float a = 1.0f); + + void SetOutLineColor(DWORD color); + void SetOutLineColor(float r, float g, float b, float a = 1.0f); + + void SetHorizonalAlign(int hAlign); + void SetVerticalAlign(int vAlign); + void SetMax(int iMax); + void SetTextPointer(CGraphicText* pText); + void SetValueString(const std::string& c_stValue); + void SetValue(const char* c_szValue, size_t len = -1); + void SetPosition(float fx, float fy, float fz = 0.0f); + void SetSecret(bool Value); + void SetOutline(bool Value); + void SetFeather(bool Value); + void SetMultiLine(bool Value); + void SetLimitWidth(float fWidth); + + void GetTextSize(int* pRetWidth, int* pRetHeight); + const std::string& GetValueStringReference(); + WORD GetTextLineCount(); + + int PixelPositionToCharacterPosition(int iPixelPosition); + int GetHorizontalAlign(); + + protected: + void __Initialize(); + int __DrawCharacter(CGraphicFontTexture * pFontTexture, WORD codePage, wchar_t text, DWORD dwColor); + void __GetTextPos(DWORD index, float* x, float* y); + int __GetTextTag(const wchar_t * src, int maxLen, int & tagLen, std::wstring & extraInfo); + + protected: + struct SHyperlink + { + short sx; + short ex; + std::wstring text; + + SHyperlink() : sx(0), ex(0) { } + }; + + protected: + DWORD m_dwTextColor; + DWORD m_dwOutLineColor; + + WORD m_textWidth; + WORD m_textHeight; + + BYTE m_hAlign; + BYTE m_vAlign; + + WORD m_iMax; + float m_fLimitWidth; + + bool m_isCursor; + bool m_isSecret; + bool m_isMultiLine; + + bool m_isOutline; + float m_fFontFeather; + + ///// + + std::string m_stText; + D3DXVECTOR3 m_v3Position; + + private: + bool m_isUpdate; + bool m_isUpdateFontTexture; + + CGraphicText::TRef m_roText; + CGraphicFontTexture::TPCharacterInfomationVector m_pCharInfoVector; + std::vector m_dwColorInfoVector; + std::vector m_hyperlinkVector; + + public: + static void CreateSystem(UINT uCapacity); + static void DestroySystem(); + + static CGraphicTextInstance* New(); + static void Delete(CGraphicTextInstance* pkInst); + + static CDynamicPool ms_kPool; +}; + +extern const char* FindToken(const char* begin, const char* end); +extern int ReadToken(const char* token); + +#endif \ No newline at end of file diff --git a/source/EterLib/GrpTexture.cpp b/source/EterLib/GrpTexture.cpp new file mode 100644 index 0000000..f1168e6 --- /dev/null +++ b/source/EterLib/GrpTexture.cpp @@ -0,0 +1,59 @@ +#include "StdAfx.h" +#include "../eterBase/Stl.h" +#include "GrpTexture.h" +#include "StateManager.h" + +void CGraphicTexture::DestroyDeviceObjects() +{ + safe_release(m_lpd3dTexture); +} + +void CGraphicTexture::Destroy() +{ + DestroyDeviceObjects(); + + Initialize(); +} + +void CGraphicTexture::Initialize() +{ + m_lpd3dTexture = NULL; + m_width = 0; + m_height = 0; + m_bEmpty = true; +} + +bool CGraphicTexture::IsEmpty() const +{ + return m_bEmpty; +} + +void CGraphicTexture::SetTextureStage(int stage) const +{ + assert(ms_lpd3dDevice != NULL); + STATEMANAGER.SetTexture(stage, m_lpd3dTexture); +} + +LPDIRECT3DTEXTURE8 CGraphicTexture::GetD3DTexture() const +{ + return m_lpd3dTexture; +} + +int CGraphicTexture::GetWidth() const +{ + return m_width; +} + +int CGraphicTexture::GetHeight() const +{ + return m_height; +} + +CGraphicTexture::CGraphicTexture() +{ + Initialize(); +} + +CGraphicTexture::~CGraphicTexture() +{ +} diff --git a/source/EterLib/GrpTexture.h b/source/EterLib/GrpTexture.h new file mode 100644 index 0000000..d56b134 --- /dev/null +++ b/source/EterLib/GrpTexture.h @@ -0,0 +1,32 @@ +#pragma once + +#include "GrpBase.h" + +class CGraphicTexture : public CGraphicBase +{ + public: + virtual bool IsEmpty() const; + + int GetWidth() const; + int GetHeight() const; + + void SetTextureStage(int stage) const; + LPDIRECT3DTEXTURE8 GetD3DTexture() const; + + void DestroyDeviceObjects(); + + protected: + CGraphicTexture(); + virtual ~CGraphicTexture(); + + void Destroy(); + void Initialize(); + + protected: + bool m_bEmpty; + + int m_width; + int m_height; + + LPDIRECT3DTEXTURE8 m_lpd3dTexture; +}; diff --git a/source/EterLib/GrpVertexBuffer.cpp b/source/EterLib/GrpVertexBuffer.cpp new file mode 100644 index 0000000..ef7b6c1 --- /dev/null +++ b/source/EterLib/GrpVertexBuffer.cpp @@ -0,0 +1,179 @@ +#include "StdAfx.h" +#include "../eterBase/Stl.h" +#include "GrpVertexBuffer.h" +#include "StateManager.h" + +int CGraphicVertexBuffer::GetVertexStride() const +{ + int retSize = D3DXGetFVFVertexSize(m_dwFVF); + return retSize; +} + +DWORD CGraphicVertexBuffer::GetFlexibleVertexFormat() const +{ + return m_dwFVF; +} + +int CGraphicVertexBuffer::GetVertexCount() const +{ + return m_vtxCount; +} + +void CGraphicVertexBuffer::SetStream(int stride, int layer) const +{ + assert(ms_lpd3dDevice != NULL); + STATEMANAGER.SetStreamSource(layer, m_lpd3dVB, stride); +} + +bool CGraphicVertexBuffer::LockRange(unsigned count, void** pretVertices) const +{ + if (!m_lpd3dVB) + return false; + + DWORD dwLockSize=GetVertexStride() * count; + if (FAILED(m_lpd3dVB->Lock(0, dwLockSize, (BYTE **) pretVertices, m_dwLockFlag))) + return false; + + return true; +} + +bool CGraphicVertexBuffer::Lock(void ** pretVertices) const +{ + if (!m_lpd3dVB) + return false; + + DWORD dwLockSize=GetVertexStride()*GetVertexCount(); + if (FAILED(m_lpd3dVB->Lock(0, dwLockSize, (BYTE **) pretVertices, m_dwLockFlag))) + return false; + + return true; +} + +bool CGraphicVertexBuffer::Unlock() const +{ + if (!m_lpd3dVB) + return false; + + if ( FAILED(m_lpd3dVB->Unlock()) ) + return false; + return true; +} + +bool CGraphicVertexBuffer::IsEmpty() const +{ + if (m_lpd3dVB) + return true; + else + return false; +} + +bool CGraphicVertexBuffer::LockDynamic(void** pretVertices) +{ + if (!m_lpd3dVB) + return false; + + if (FAILED(m_lpd3dVB->Lock(0, 0, (BYTE**)pretVertices, 0))) + return false; + + return true; +} + +bool CGraphicVertexBuffer::Lock(void ** pretVertices) +{ + if (!m_lpd3dVB) + return false; + + if (FAILED(m_lpd3dVB->Lock(0, 0, (BYTE**)pretVertices, m_dwLockFlag))) + return false; + + return true; +} + +bool CGraphicVertexBuffer::Unlock() +{ + if (!m_lpd3dVB) + return false; + + if ( FAILED(m_lpd3dVB->Unlock()) ) + return false; + return true; +} + +bool CGraphicVertexBuffer::Copy(int bufSize, const void* srcVertices) +{ + void * dstVertices; + + if (!Lock(&dstVertices)) + return false; + + memcpy(dstVertices, srcVertices, bufSize); + + Unlock(); + return true; +} + +bool CGraphicVertexBuffer::CreateDeviceObjects() +{ + assert(ms_lpd3dDevice != NULL); + assert(m_lpd3dVB == NULL); + + if (FAILED( + ms_lpd3dDevice->CreateVertexBuffer( + m_dwBufferSize, + m_dwUsage, + m_dwFVF, + m_d3dPool, + &m_lpd3dVB) + )) + return false; + + return true; +} + +void CGraphicVertexBuffer::DestroyDeviceObjects() +{ + safe_release(m_lpd3dVB); +} + +bool CGraphicVertexBuffer::Create(int vtxCount, DWORD fvf, DWORD usage, D3DPOOL d3dPool) +{ + assert(ms_lpd3dDevice != NULL); + assert(vtxCount > 0); + + Destroy(); + + m_vtxCount = vtxCount; + m_dwBufferSize = D3DXGetFVFVertexSize(fvf) * m_vtxCount; + m_d3dPool = d3dPool; + m_dwUsage = usage; + m_dwFVF = fvf; + + if (usage == D3DUSAGE_WRITEONLY || usage == D3DUSAGE_DYNAMIC) + m_dwLockFlag = 0; + else + m_dwLockFlag = D3DLOCK_READONLY; + + return CreateDeviceObjects(); +} + +void CGraphicVertexBuffer::Destroy() +{ + DestroyDeviceObjects(); +} + +void CGraphicVertexBuffer::Initialize() +{ + m_lpd3dVB = NULL; + m_vtxCount = 0; + m_dwBufferSize = 0; +} + +CGraphicVertexBuffer::CGraphicVertexBuffer() +{ + Initialize(); +} + +CGraphicVertexBuffer::~CGraphicVertexBuffer() +{ + Destroy(); +} diff --git a/source/EterLib/GrpVertexBuffer.h b/source/EterLib/GrpVertexBuffer.h new file mode 100644 index 0000000..5bba8d7 --- /dev/null +++ b/source/EterLib/GrpVertexBuffer.h @@ -0,0 +1,50 @@ +#pragma once + +#include "GrpBase.h" + +class CGraphicVertexBuffer : public CGraphicBase +{ + public: + CGraphicVertexBuffer(); + virtual ~CGraphicVertexBuffer(); + + void Destroy(); + virtual bool Create(int vtxCount, DWORD fvf, DWORD usage, D3DPOOL d3dPool); + + bool CreateDeviceObjects(); + void DestroyDeviceObjects(); + + bool Copy(int bufSize, const void* srcVertices); + + bool LockRange(unsigned count, void** pretVertices) const; + bool Lock(void** pretVertices) const; + bool Unlock() const; + + bool LockDynamic(void** pretVertices); + virtual bool Lock(void** pretVertices); + bool Unlock(); + + void SetStream(int stride, int layer=0) const; + + int GetVertexCount() const; + int GetVertexStride() const; + DWORD GetFlexibleVertexFormat() const; + + inline LPDIRECT3DVERTEXBUFFER8 GetD3DVertexBuffer() const { return m_lpd3dVB; } + inline DWORD GetBufferSize() const { return m_dwBufferSize; } + + bool IsEmpty() const; + + protected: + void Initialize(); + + protected: + LPDIRECT3DVERTEXBUFFER8 m_lpd3dVB; + + DWORD m_dwBufferSize; + DWORD m_dwFVF; + DWORD m_dwUsage; + D3DPOOL m_d3dPool; + int m_vtxCount; + DWORD m_dwLockFlag; +}; diff --git a/source/EterLib/GrpVertexBufferDynamic.cpp b/source/EterLib/GrpVertexBufferDynamic.cpp new file mode 100644 index 0000000..1b2a28d --- /dev/null +++ b/source/EterLib/GrpVertexBufferDynamic.cpp @@ -0,0 +1,29 @@ +#include "StdAfx.h" +#include "GrpVertexBufferDynamic.h" + +bool CDynamicVertexBuffer::Create(int vtxCount, int fvf) +{ + if (m_lpd3dVB) + { + if (m_fvf == fvf) + { + if (m_vtxCount >= vtxCount) + return true; + } + } + + m_vtxCount = vtxCount; + m_fvf = fvf; + + return CGraphicVertexBuffer::Create(m_vtxCount, m_fvf, D3DUSAGE_DYNAMIC, D3DPOOL_SYSTEMMEM); +} + +CDynamicVertexBuffer::CDynamicVertexBuffer() +{ + m_vtxCount = 0; + m_fvf = 0; +} + +CDynamicVertexBuffer::~CDynamicVertexBuffer() +{ +} diff --git a/source/EterLib/GrpVertexBufferDynamic.h b/source/EterLib/GrpVertexBufferDynamic.h new file mode 100644 index 0000000..952aa88 --- /dev/null +++ b/source/EterLib/GrpVertexBufferDynamic.h @@ -0,0 +1,19 @@ +#pragma once + +#include "GrpVertexBuffer.h" + +class CDynamicVertexBuffer : public CGraphicVertexBuffer +{ + public: + CDynamicVertexBuffer(); + virtual ~CDynamicVertexBuffer(); + + bool Create(int vtxCount, int fvf); + + + + protected: + int m_vtxCount; + int m_fvf; +}; + diff --git a/source/EterLib/GrpVertexBufferStatic.cpp b/source/EterLib/GrpVertexBufferStatic.cpp new file mode 100644 index 0000000..780450f --- /dev/null +++ b/source/EterLib/GrpVertexBufferStatic.cpp @@ -0,0 +1,16 @@ +#include "StdAfx.h" +#include "GrpVertexBufferStatic.h" + +bool CStaticVertexBuffer::Create(int vtxCount, DWORD fvf, bool /*isManaged*/) +{ + // MANAGED + return CGraphicVertexBuffer::Create(vtxCount, fvf, D3DUSAGE_WRITEONLY, D3DPOOL_MANAGED); +} + +CStaticVertexBuffer::CStaticVertexBuffer() +{ +} + +CStaticVertexBuffer::~CStaticVertexBuffer() +{ +} diff --git a/source/EterLib/GrpVertexBufferStatic.h b/source/EterLib/GrpVertexBufferStatic.h new file mode 100644 index 0000000..e2dfc41 --- /dev/null +++ b/source/EterLib/GrpVertexBufferStatic.h @@ -0,0 +1,13 @@ +#pragma once + +#include "GrpVertexBuffer.h" + +class CStaticVertexBuffer : public CGraphicVertexBuffer +{ + public: + CStaticVertexBuffer(); + virtual ~CStaticVertexBuffer(); + + bool Create(int vtxCount, DWORD fvf, bool isManaged=true); +}; + diff --git a/source/EterLib/GrpVertexShader.cpp b/source/EterLib/GrpVertexShader.cpp new file mode 100644 index 0000000..1592b41 --- /dev/null +++ b/source/EterLib/GrpVertexShader.cpp @@ -0,0 +1,57 @@ +#include "StdAfx.h" +#include "GrpVertexShader.h" +#include "GrpD3DXBuffer.h" +#include "StateManager.h" + +CVertexShader::CVertexShader() +{ + Initialize(); +} + +CVertexShader::~CVertexShader() +{ + Destroy(); +} + +void CVertexShader::Initialize() +{ + m_handle=0; +} + +void CVertexShader::Destroy() +{ + if (m_handle) + { + if (ms_lpd3dDevice) + ms_lpd3dDevice->DeleteVertexShader(m_handle); + + m_handle = 0; + } +} + +bool CVertexShader::CreateFromDiskFile(const char* c_szFileName, const DWORD* c_pdwVertexDecl) +{ + Destroy(); + + LPD3DXBUFFER lpd3dxShaderBuffer; + LPD3DXBUFFER lpd3dxErrorBuffer; + + if (FAILED( + D3DXAssembleShaderFromFile(c_szFileName, 0, NULL, &lpd3dxShaderBuffer, &lpd3dxErrorBuffer) + )) return false; + + CDirect3DXBuffer shaderBuffer(lpd3dxShaderBuffer); + CDirect3DXBuffer errorBuffer(lpd3dxErrorBuffer); + + if (FAILED( + ms_lpd3dDevice->CreateVertexShader(c_pdwVertexDecl, (DWORD*)shaderBuffer.GetPointer(), &m_handle, 0 ) + )) + return false; + + return true; +} + +void CVertexShader::Set() +{ + STATEMANAGER.SetVertexShader(m_handle); +} diff --git a/source/EterLib/GrpVertexShader.h b/source/EterLib/GrpVertexShader.h new file mode 100644 index 0000000..00da267 --- /dev/null +++ b/source/EterLib/GrpVertexShader.h @@ -0,0 +1,21 @@ +#pragma once + +#include "GrpBase.h" + +class CVertexShader : public CGraphicBase +{ + public: + CVertexShader(); + virtual ~CVertexShader(); + + void Destroy(); + bool CreateFromDiskFile(const char* c_szFileName, const DWORD* c_pdwVertexDecl); + + void Set(); + + protected: + void Initialize(); + + protected: + DWORD m_handle; +}; diff --git a/source/EterLib/IME.cpp b/source/EterLib/IME.cpp new file mode 100644 index 0000000..6de5120 --- /dev/null +++ b/source/EterLib/IME.cpp @@ -0,0 +1,2302 @@ +#include "StdAfx.h" +#include "IME.h" +#include "TextTag.h" +#include "../eterBase/Utils.h" +#include "msctf.h" +#include + +#define COUNTOF(a) ( sizeof( a ) / sizeof( ( a )[0] ) ) + +int CIME::ms_compLen; +int CIME::ms_curpos; +int CIME::ms_lastpos; +wchar_t CIME::m_wText[IMESTR_MAXLEN]; + +#define MAKEIMEVERSION(major, minor) ((DWORD)(((BYTE)(major) << 24) | ((BYTE)(minor) << 16))) +#define IMEID_VER(dwId) ((dwId) & 0xffff0000) +#define IMEID_LANG(dwId) ((dwId) & 0x0000ffff) + +#define GETLANG() LOWORD(CIME::ms_hklCurrent) +#define GETPRIMLANG() ((WORD)PRIMARYLANGID(GETLANG())) +#define GETSUBLANG() SUBLANGID(GETLANG()) + +#define LANG_CHT MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL) +#define LANG_CHS MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED) + +// Chinese Traditional +#define _CHT_HKL_DAYI ((HKL)0xE0060404) // DaYi +#define _CHT_HKL_NEW_PHONETIC ((HKL)0xE0080404) // New Phonetic +#define _CHT_HKL_NEW_CHANG_JIE ((HKL)0xE0090404) // New Chang Jie +#define _CHT_HKL_NEW_QUICK ((HKL)0xE00A0404) // New Quick +#define _CHT_HKL_HK_CANTONESE ((HKL)0xE00B0404) // Hong Kong Cantonese + +#define CHT_IMEFILENAME1 "TINTLGNT.IME" // New Phonetic +#define CHT_IMEFILENAME2 "CINTLGNT.IME" // New Chang Jie +#define CHT_IMEFILENAME3 "MSTCIPHA.IME" // Phonetic 5.1 + +#define IMEID_CHT_VER42 (LANG_CHT | MAKEIMEVERSION(4, 2)) // New(Phonetic/ChanJie)IME98 : 4.2.x.x // Win98 +#define IMEID_CHT_VER43 (LANG_CHT | MAKEIMEVERSION(4, 3)) // New(Phonetic/ChanJie)IME98a : 4.3.x.x // Win2k +#define IMEID_CHT_VER44 (LANG_CHT | MAKEIMEVERSION(4, 4)) // New ChanJie IME98b : 4.4.x.x // WinXP +#define IMEID_CHT_VER50 (LANG_CHT | MAKEIMEVERSION(5, 0)) // New(Phonetic/ChanJie)IME5.0 : 5.0.x.x // WinME +#define IMEID_CHT_VER51 (LANG_CHT | MAKEIMEVERSION(5, 1)) // New(Phonetic/ChanJie)IME5.1 : 5.1.x.x // IME2002(w/OfficeXP) +#define IMEID_CHT_VER52 (LANG_CHT | MAKEIMEVERSION(5, 2)) // New(Phonetic/ChanJie)IME5.2 : 5.2.x.x // IME2002a(w/Whistler) +#define IMEID_CHT_VER60 (LANG_CHT | MAKEIMEVERSION(6, 0)) // New(Phonetic/ChanJie)IME6.0 : 6.0.x.x // IME XP(w/WinXP SP1) +#define IMEID_CHT_VER_VISTA (LANG_CHT | MAKEIMEVERSION(7, 0)) // All TSF TIP under Cicero UI-less mode: a hack to make GetImeId() return non-zero value + +// Chinese Simplized +#define _CHS_HKL ((HKL)0xE00E0804) // MSPY +#define _CHS_HKL_QQPINYIN ((HKL)0xE0210804) // QQ PinYin +#define _CHS_HKL_SOGOU ((HKL)0xE0220804) // Sougou PinYin +#define _CHS_HKL_GOOGLEPINYIN ((HKL)0xE0230804) // Google PinYin + +#define CHS_IMEFILENAME1 "PINTLGNT.IME" // MSPY1.5/2/3 +#define CHS_IMEFILENAME2 "MSSCIPYA.IME" // MSPY3 for OfficeXP +#define CHS_IMEFILENAME_QQPINYIN "QQPINYIN.IME" // QQ PinYin +#define CHS_IMEFILENAME_SOGOUPY "SOGOUPY.IME" // Sougou PinYin +#define CHS_IMEFILENAME_GOOGLEPINYIN2 "GOOGLEPINYIN2.IME" // Google PinYin 2 + +#define IMEID_CHS_VER41 (LANG_CHS | MAKEIMEVERSION(4, 1)) // MSPY1.5 // SCIME97 or MSPY1.5 (w/Win98, Office97) +#define IMEID_CHS_VER42 (LANG_CHS | MAKEIMEVERSION(4, 2)) // MSPY2 // Win2k/WinME +#define IMEID_CHS_VER53 (LANG_CHS | MAKEIMEVERSION(5, 3)) // MSPY3 // WinXP + +enum { INDICATOR_NON_IME, INDICATOR_CHS, INDICATOR_CHT, INDICATOR_KOREAN, INDICATOR_JAPANESE }; +enum { IMEUI_STATE_OFF, IMEUI_STATE_ON, IMEUI_STATE_ENGLISH }; + +#define LCID_INVARIANT MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT) + +wchar_t s_aszIndicator[5][3] = +{ + L"En", + L"\x7B80", + L"\x7E41", + L"\xAC00", + L"\x3042", +}; + +INPUTCONTEXT* (WINAPI * CIME::_ImmLockIMC)( HIMC ); +BOOL (WINAPI * CIME::_ImmUnlockIMC)( HIMC ); +LPVOID (WINAPI * CIME::_ImmLockIMCC)( HIMCC ); +BOOL (WINAPI * CIME::_ImmUnlockIMCC)( HIMCC ); + +UINT (WINAPI * CIME::_GetReadingString)( HIMC, UINT, LPWSTR, PINT, BOOL*, PUINT ); +BOOL (WINAPI * CIME::_ShowReadingWindow)( HIMC, BOOL ); + +bool CIME::ms_bInitialized = false; +bool CIME::ms_bDisableIMECompletely = false; +bool CIME::ms_bImeEnabled = false; +bool CIME::ms_bUILessMode = false; +bool CIME::ms_bCaptureInput = false; +bool CIME::ms_bChineseIME = false; +bool CIME::ms_bUseIMMCandidate = false; + +HWND CIME::ms_hWnd; +HKL CIME::ms_hklCurrent; +char CIME::ms_szKeyboardLayout[KL_NAMELENGTH+1]; +OSVERSIONINFOA CIME::ms_stOSVI; + +HINSTANCE CIME::ms_hImm32Dll; +HINSTANCE CIME::ms_hCurrentImeDll; +DWORD CIME::ms_dwImeState; + +DWORD CIME::ms_adwId[2] = { 0, 0 }; + +// IME Level +DWORD CIME::ms_dwIMELevel; +DWORD CIME::ms_dwIMELevelSaved; + +// Candidate List +bool CIME::ms_bCandidateList; +DWORD CIME::ms_dwCandidateCount; +bool CIME::ms_bVerticalCandidate; +int CIME::ms_iCandListIndexBase; +WCHAR CIME::ms_wszCandidate[CIME::MAX_CANDLIST][MAX_CANDIDATE_LENGTH]; +DWORD CIME::ms_dwCandidateSelection; +DWORD CIME::ms_dwCandidatePageSize; + +// Reading Window +bool CIME::ms_bReadingInformation; +int CIME::ms_iReadingError = 0; +bool CIME::ms_bHorizontalReading; +std::vector CIME::ms_wstrReading; + +// Indicator +wchar_t* CIME::ms_wszCurrentIndicator; + +IIMEEventSink* CIME::ms_pEvent; + +int CIME::ms_ulbegin; +int CIME::ms_ulend; + +UINT CIME::ms_uOutputCodePage = 0; +UINT CIME::ms_uInputCodePage = 0; + +extern DWORD gs_codePage=0; +extern DWORD GetDefaultCodePage(); +extern int ReadToken(const char* token); +extern const char* FindToken(const char* begin, const char* end); + +/////////////////////////////////////////////////////////////////////////////// +// +// CTsfUiLessMode +// Handles IME events using Text Service Framework (TSF). Before Vista, +// IMM (Input Method Manager) API has been used to handle IME events and +// inqueries. Some IMM functions lose backward compatibility due to design +// of TSF, so we have to use new TSF interfaces. +// +/////////////////////////////////////////////////////////////////////////////// +class CTsfUiLessMode +{ +protected: + // Sink receives event notifications + class CUIElementSink : public ITfUIElementSink, public ITfInputProcessorProfileActivationSink, public ITfCompartmentEventSink + { + public: + CUIElementSink(); + ~CUIElementSink(); + + // IUnknown + STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj); + STDMETHODIMP_(ULONG) AddRef(void); + STDMETHODIMP_(ULONG) Release(void); + + // ITfUIElementSink + // Notifications for Reading Window events. We could process candidate as well, but we'll use IMM for simplicity sake. + STDMETHODIMP BeginUIElement(DWORD dwUIElementId, BOOL *pbShow); + STDMETHODIMP UpdateUIElement(DWORD dwUIElementId); + STDMETHODIMP EndUIElement(DWORD dwUIElementId); + + // ITfInputProcessorProfileActivationSink + // Notification for keyboard input locale change + STDMETHODIMP OnActivated(DWORD dwProfileType, LANGID langid, REFCLSID clsid, REFGUID catid, + REFGUID guidProfile, HKL hkl, DWORD dwFlags); + + // ITfCompartmentEventSink + // Notification for open mode (toggle state) change + STDMETHODIMP OnChange(REFGUID rguid); + + private: + LONG _cRef; + }; + + static void MakeReadingInformationString(ITfReadingInformationUIElement* preading); + static void MakeCandidateStrings(ITfCandidateListUIElement* pcandidate); + static ITfUIElement* GetUIElement(DWORD dwUIElementId); + static BOOL GetCompartments( ITfCompartmentMgr** ppcm, ITfCompartment** ppTfOpenMode, ITfCompartment** ppTfConvMode ); + static BOOL SetupCompartmentSinks( BOOL bResetOnly = FALSE, ITfCompartment* pTfOpenMode = NULL, ITfCompartment* ppTfConvMode = NULL ); + + static ITfThreadMgrEx* m_tm; + static DWORD m_dwUIElementSinkCookie; + static DWORD m_dwAlpnSinkCookie; + static DWORD m_dwOpenModeSinkCookie; + static DWORD m_dwConvModeSinkCookie; + static CUIElementSink *m_TsfSink; + static int m_nCandidateRefCount; // Some IME shows multiple candidate lists but the Library doesn't support multiple candidate list. + // So track open / close events to make sure the candidate list opened last is shown. + CTsfUiLessMode() {} // this class can't be instanciated + +public: + static BOOL SetupSinks(); + static void ReleaseSinks(); + static BOOL CurrentInputLocaleIsIme(); + static void UpdateImeState(BOOL bResetCompartmentEventSink = FALSE); + static void EnableUiUpdates(bool bEnable); +}; + +ITfThreadMgrEx* CTsfUiLessMode::m_tm; +DWORD CTsfUiLessMode::m_dwUIElementSinkCookie = TF_INVALID_COOKIE; +DWORD CTsfUiLessMode::m_dwAlpnSinkCookie = TF_INVALID_COOKIE; +DWORD CTsfUiLessMode::m_dwOpenModeSinkCookie = TF_INVALID_COOKIE; +DWORD CTsfUiLessMode::m_dwConvModeSinkCookie = TF_INVALID_COOKIE; +CTsfUiLessMode::CUIElementSink* CTsfUiLessMode::m_TsfSink = NULL; +int CTsfUiLessMode::m_nCandidateRefCount = NULL; + +// Class to disable Cicero in case ImmDisableTextFrameService() doesn't disable it completely +class CDisableCicero +{ +public: + CDisableCicero() : m_ptim( NULL ), m_bComInit( false ) + { + } + ~CDisableCicero() + { + Uninitialize(); + } + void Initialize() + { + if ( m_bComInit ) + { + return; + } + HRESULT hr; + hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED ); + if ( SUCCEEDED( hr ) ) + { + m_bComInit = true; + hr = CoCreateInstance( CLSID_TF_ThreadMgr, + NULL, + CLSCTX_INPROC_SERVER, + __uuidof(ITfThreadMgr), + (void**)&m_ptim ); + } + } + void Uninitialize() + { + if ( m_ptim ) + { + m_ptim->Release(); + m_ptim = NULL; + } + if ( m_bComInit ) + CoUninitialize(); + m_bComInit = false; + } + + void DisableCiceroOnThisWnd( HWND hwnd ) + { + if ( m_ptim == NULL ) + return; + ITfDocumentMgr* pdimPrev; // the dim that is associated previously. + // Associate NULL dim to the window. + // When this window gets the focus, Cicero does not work and IMM32 IME + // will be activated. + if ( SUCCEEDED( m_ptim->AssociateFocus( hwnd, NULL, &pdimPrev ) ) ) + { + if ( pdimPrev ) + pdimPrev->Release(); + } + } +private: + ITfThreadMgr* m_ptim; + bool m_bComInit; +}; +static CDisableCicero g_disableCicero; + +/*---------------------------------------------------------------------------*/ /* Public */ +CIME::CIME() +{ + ms_hWnd = NULL; + + ms_bCandidateList = false; + ms_bReadingInformation = false; + + Clear(); + + m_max = 0; + m_userMax = 0; + + m_bOnlyNumberMode = FALSE; + m_hOrgIMC = NULL; + + m_bEnablePaste = false; + m_bUseDefaultIME = false; +} + +CIME::~CIME() +{ + SAFE_FREE_LIBRARY(ms_hCurrentImeDll); + SAFE_FREE_LIBRARY(ms_hImm32Dll); +} +#pragma warning(disable : 4996) +bool CIME::Initialize(HWND hWnd) +{ + if(ms_bInitialized) + return true; + ms_hWnd = hWnd; + + g_disableCicero.Initialize(); + + ms_stOSVI.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); + GetVersionExA(&ms_stOSVI); + + bool bUnicodeImm = false; + // IMM in NT or Win98 supports Unicode + if ( ms_stOSVI.dwPlatformId == VER_PLATFORM_WIN32_NT || + ( ms_stOSVI.dwMajorVersion > 4 ) || + ( ms_stOSVI.dwMajorVersion == 4 ) && ( ms_stOSVI.dwMinorVersion > 0 ) ) { + bUnicodeImm = true; + } + + // Load ImmLock/ImmUnlock Function Proc + CHAR szPath[MAX_PATH+1]; + ms_bDisableIMECompletely = false; + + if(GetSystemDirectoryA(szPath, MAX_PATH+1)) { + strcat(szPath, "\\imm32.dll"); + ms_hImm32Dll = LoadLibraryA(szPath); + if(ms_hImm32Dll) + { + _ImmLockIMC = (INPUTCONTEXT*(WINAPI *)(HIMC)) GetProcAddress(ms_hImm32Dll, "ImmLockIMC"); + _ImmUnlockIMC = (BOOL(WINAPI *)(HIMC)) GetProcAddress(ms_hImm32Dll, "ImmUnlockIMC"); + _ImmLockIMCC = (LPVOID(WINAPI *)(HIMCC)) GetProcAddress(ms_hImm32Dll, "ImmLockIMCC"); + _ImmUnlockIMCC = (BOOL(WINAPI *)(HIMCC)) GetProcAddress(ms_hImm32Dll, "ImmUnlockIMCC"); + BOOL (WINAPI* _ImmDisableTextFrameService)(DWORD) = (BOOL (WINAPI*)(DWORD))GetProcAddress(ms_hImm32Dll, "ImmDisableTextFrameService"); + if ( _ImmDisableTextFrameService ) + _ImmDisableTextFrameService( (DWORD)-1 ); + } else { + ms_bDisableIMECompletely = true; + } + } + + ms_bInitialized = true; + + m_hOrgIMC = ImmGetContext( ms_hWnd ); + ImmReleaseContext( ms_hWnd, m_hOrgIMC ); + + CheckInputLocale(); + ChangeInputLanguageWorker(); + SetSupportLevel(2); + + ms_bUILessMode = CTsfUiLessMode::SetupSinks() != FALSE; + CheckToggleState(); + if ( ms_bUILessMode ) + { + ms_bChineseIME = ( GETPRIMLANG() == LANG_CHINESE ) && CTsfUiLessMode::CurrentInputLocaleIsIme(); + CTsfUiLessMode::UpdateImeState(); + } + + return true; +} + +void CIME::Uninitialize() +{ + if ( !ms_bInitialized ) + return; + CTsfUiLessMode::ReleaseSinks(); + if ( ms_hWnd ) + ImmAssociateContext(ms_hWnd, m_hOrgIMC); + ms_hWnd = NULL; + m_hOrgIMC = NULL; + SAFE_FREE_LIBRARY(ms_hCurrentImeDll); + SAFE_FREE_LIBRARY(ms_hImm32Dll); + g_disableCicero.Uninitialize(); + ms_bInitialized = false; +} + +void CIME::UseDefaultIME() +{ + m_bUseDefaultIME = true; +} + +bool CIME::IsIMEEnabled() +{ + return ms_bImeEnabled; +} + +void CIME::EnableIME(bool bEnable) +{ + if (!ms_bInitialized || !ms_hWnd) + return; + if (ms_bDisableIMECompletely) + bEnable = false; + ImmAssociateContext(ms_hWnd, bEnable ? m_hOrgIMC : NULL); + ms_bImeEnabled = bEnable; + if (bEnable) + CheckToggleState(); + CTsfUiLessMode::EnableUiUpdates(bEnable); +} + +void CIME::DisableIME() +{ + EnableIME(false); +} + +void CIME::EnableCaptureInput() +{ + ms_bCaptureInput = true; +} + +void CIME::DisableCaptureInput() +{ + ms_bCaptureInput = false; +} + +bool CIME::IsCaptureEnabled() +{ + return ms_bCaptureInput; +} + +void CIME::Clear() +{ + ms_lastpos = 0; + ms_curpos = 0; + + ms_compLen = 0; + ms_ulbegin = 0; + ms_ulend = 0; +} + +int CIME::GetReading(std::string & rstrText) +{ + char reading[IMEREADING_MAXLEN]; + + if(ms_wstrReading.size() == 0) + return 0; + int readingLen = WideCharToMultiByte(ms_uOutputCodePage, 0, &ms_wstrReading[0], ms_wstrReading.size(), reading, sizeof(reading), NULL, NULL); + + rstrText.append(GetCodePageText()); + rstrText.append(reading, reading + readingLen); + + return rstrText.size(); +} + +int CIME::GetReadingError() +{ + return ms_iReadingError; +} + +void CIME::SetMax(int iMax) +{ + m_max = iMax; +} + +void CIME::SetUserMax(int iMax) +{ + m_userMax = iMax; +} + +void CIME::SetText(const char* szText, int len) +{ + ms_compLen = 0; + ms_ulbegin = 0; + ms_ulend = 0; + + const char* begin = szText; + const char* end = begin + len; + const char* iter = FindToken(begin, end); + + int m_wTextLen = sizeof(m_wText)/sizeof(wchar_t); + + ms_lastpos = MultiByteToWideChar(ms_uInputCodePage, 0, begin, iter-begin, m_wText, m_wTextLen); + + if (iter < end) + ms_lastpos += MultiByteToWideChar(ReadToken(iter), 0, (iter+5), end-(iter+5), m_wText+ms_lastpos, m_wTextLen-ms_lastpos); + + ms_curpos = min(ms_curpos, ms_lastpos); +} + +int CIME::GetText(std::string & rstrText, bool addCodePage) +{ + int outCodePage = ms_uOutputCodePage; + int dataCodePage; + switch (outCodePage) + { + //case 1256: // ARABIC + case 1268: // VIETNAM + dataCodePage = CP_UTF8; + break; + default: + dataCodePage = outCodePage; + } + + int len = 0; + char text[IMESTR_MAXLEN]; + + len += WideCharToMultiByte(dataCodePage, 0, m_wText, ms_curpos, text, sizeof(text)-len, NULL, NULL); + len += WideCharToMultiByte(dataCodePage, 0, m_wszComposition, ms_compLen, text+len, sizeof(text)-len, NULL, NULL); + len += WideCharToMultiByte(dataCodePage, 0, m_wText+ms_curpos, ms_lastpos-ms_curpos, text+len, sizeof(text)-len, NULL, NULL); + + int i; + for(i=0; i 0x7F) break; + + if(i == len) + { + rstrText.append(text, text+len); + } + else + { + rstrText.append(text, text+i); + + //if (addCodePage) + // rstrText.append(GetCodePageText()); + + rstrText.append(text+i, text+len); + } + + return rstrText.size(); +} + +const char* CIME::GetCodePageText() +{ + static char szCodePage[16]; + + const int defCodePage = GetDefaultCodePage(); + const int outCodePage = ms_uOutputCodePage; + + if (outCodePage != defCodePage) + { + sprintf(szCodePage, "@%04d", outCodePage); + } + else + { + szCodePage[0] = 0; + } + + return szCodePage; +} + +int CIME::GetCodePage() +{ + return ms_uOutputCodePage; +} + +int CIME::GetCandidatePageCount() +{ + return ms_dwCandidatePageSize; +} + +int CIME::GetCandidateCount() +{ + return ms_dwCandidateCount; +} + +int CIME::GetCandidate(DWORD index, std::string & rstrText) +{ + if(index >= MAX_CANDLIST) + return 0; + + LPCWSTR wszText = ms_wszCandidate[index]; + if(wszText == NULL) + return 0; + + int wTextLen = wcslen(wszText); + if(wTextLen == 0) + return 0; + + char text[IMESTR_MAXLEN]; + int len = ::WideCharToMultiByte(CP_UTF8, 0, wszText, wTextLen, text, sizeof(text), 0, 0); + + rstrText.append("@9999"); + rstrText.append(text, text+len); + + return wTextLen; +} + +int CIME::GetCandidateSelection() +{ + return ms_dwCandidateSelection; +} + +void CIME::SetInputMode(DWORD dwMode) +{ + HIMC hImc = ImmGetContext(ms_hWnd); + + ImmSetConversionStatus(hImc, dwMode, IME_SMODE_AUTOMATIC); + + ImmReleaseContext(ms_hWnd, hImc); +} + +DWORD CIME::GetInputMode() +{ + DWORD dwCMode, dwSMode; + + HIMC hImc = ImmGetContext(ms_hWnd); + + ImmGetConversionStatus(hImc, &dwCMode, &dwSMode); + + ImmReleaseContext(ms_hWnd, hImc); + + return dwCMode; +} + +void CIME::SetNumberMode() +{ + m_bOnlyNumberMode = TRUE; +} + +void CIME::SetStringMode() +{ + m_bOnlyNumberMode = FALSE; +} + +void CIME::AddExceptKey(wchar_t key) +{ + m_exceptKey.push_back(key); +} + +void CIME::ClearExceptKey() +{ + m_exceptKey.clear(); +} + +bool CIME::__IsWritable(wchar_t key) +{ + if ( m_exceptKey.end() == std::find(m_exceptKey.begin(),m_exceptKey.end(),key) ) + return true; + else + return false; +} + +void CIME::EnablePaste(bool bFlag) +{ + m_bEnablePaste = bFlag; +} + +void CIME::PasteTextFromClipBoard() +{ + if (!m_bEnablePaste) + return; + + if (!OpenClipboard(NULL)) + return; + + HANDLE handle = GetClipboardData(CF_TEXT); + char * buffer = (char*)GlobalLock(handle); + std::string strClipboard = buffer; + GlobalUnlock(handle); + CloseClipboard(); + + if (strClipboard.empty()) + return; + + const char* begin = strClipboard.c_str(); + const char* end = begin + strClipboard.length(); + wchar_t m_wText[IMESTR_MAXLEN]; + int wstrLen = MultiByteToWideChar(ms_uInputCodePage, 0, begin, end-begin, m_wText, IMESTR_MAXLEN); + + InsertString(m_wText, wstrLen); + if(ms_pEvent) + ms_pEvent->OnUpdate(); +} + +void CIME::FinalizeString(bool bSend) +{ + HIMC himc; + static bool s_bProcessing = false; // to avoid infinite recursion + if ( !ms_bInitialized || s_bProcessing || NULL == ( himc = ImmGetContext( ms_hWnd ) ) ) + return; + s_bProcessing = true; + + if (ms_dwIMELevel == 2 && bSend) + { + //// Send composition string to app. + //LONG lRet = lstrlenW( m_wszComposition ); + ////assert( lRet >= 2); + //// In case of CHT IME, don't send the trailing double byte space, if it exists. + //if ( GETLANG() == LANG_CHT && (lRet >= 1) + // && m_wszComposition[lRet - 1] == 0x3000 ) + //{ + // lRet--; + //} + //SendCompString(); + } + + //InitCompStringData(); + // clear composition string in IME + ImmNotifyIME(himc, NI_COMPOSITIONSTR, CPS_CANCEL, 0); + if (ms_bUILessMode) + { + // For some reason ImmNotifyIME doesn't work on DaYi and Array CHT IMEs. Cancel composition string by setting zero-length string. + ImmSetCompositionStringW(himc, SCS_SETSTR, NULL, 0, NULL, 0); + } + // the following line is necessary as Korean IME doesn't close cand list when comp string is cancelled. + ImmNotifyIME( himc, NI_CLOSECANDIDATE, 0, 0 ); + ImmReleaseContext(ms_hWnd, himc); + // Zooty2 RAID #4759: Sometimes application doesn't receive IMN_CLOSECANDIDATE on Alt+Tab + // So the same code for IMN_CLOSECANDIDATE is replicated here. + CloseCandidateList(); + s_bProcessing = false; +} + +int CIME::GetCompLen() +{ + return ms_compLen; +} + +int CIME::GetULBegin() +{ + return ms_ulbegin; +} + +int CIME::GetULEnd() +{ + return ms_ulend; +} + +void CIME::CloseCandidateList() +{ + ms_bCandidateList = false; + ms_dwCandidateCount = 0; + memset(&ms_wszCandidate, 0, sizeof(ms_wszCandidate)); + if(ms_pEvent) + ms_pEvent->OnCloseCandidateList(); +} + +void CIME::CloseReadingInformation() +{ + CIME::ms_bReadingInformation = false; + if(CIME::ms_pEvent) + CIME::ms_pEvent->OnCloseReadingWnd(); +} + +void CIME::ChangeInputLanguage() +{ + UINT uLanguage = (UINT) GETLANG(); + CheckToggleState(); + ChangeInputLanguageWorker(); + if (uLanguage != GETLANG()) + { + // Korean IME always uses level 3 support. + // Other languages use the level that is specified by ImeUi_SetSupportLevel() + SetSupportLevel( ( GETPRIMLANG() == LANG_KOREAN ) ? 3 : ms_dwIMELevelSaved ); + } + + if(ms_pEvent) + ms_pEvent->OnChangeCodePage(); + + //HWND hwndImeDef = ImmGetDefaultIMEWnd(ms_hWnd); + //if ( hwndImeDef ) + //{ + // // Fix for Zooty #3995: prevent CHT IME toobar from showing up + // SendMessageA(hwndImeDef, WM_IME_CONTROL, IMC_OPENSTATUSWINDOW, 0); + // SendMessageA(hwndImeDef, WM_IME_CONTROL, IMC_CLOSESTATUSWINDOW, 0); + //} +} + +void CIME::ChangeInputLanguageWorker() +{ + if ( !ms_bUILessMode ) + ms_iCandListIndexBase = ( ms_hklCurrent == _CHT_HKL_DAYI ) ? 0 : 1; + SetupImeApi(); +} + +void CIME::SetSupportLevel( DWORD dwImeLevel ) +{ + if ( dwImeLevel < 2 || 3 < dwImeLevel ) + return; + if ( GETPRIMLANG() == LANG_KOREAN ) + { + dwImeLevel = 3; + } + ms_dwIMELevel = dwImeLevel; + // cancel current composition string. + FinalizeString(); + //SetCompStringColor(); +} + +/*---------------------------------------------------------------------------*/ /* Protected */ +void CIME::IncCurPos() +{ + if (ms_curpos < ms_lastpos) + { + int pos = FindColorTagEndPosition(m_wText + ms_curpos, ms_lastpos - ms_curpos); + + if (pos > 0) + ms_curpos = min(ms_lastpos, max(0, ms_curpos + (pos + 1))); + else + ++ms_curpos; + //++ms_curpos; + } +} + +void CIME::DecCurPos() +{ + if (ms_curpos > 0) + { + int pos = FindColorTagStartPosition(m_wText + ms_curpos - 1, ms_curpos); + + if (pos > 0) + ms_curpos = min(ms_lastpos, max(0, ms_curpos - (pos + 1))); + else + --ms_curpos; + //--ms_curpos; + } +} + +int CIME::GetCurPos() +{ + int pos = GetTextTagOutputLen(m_wText, ms_curpos); + return pos; + //return ms_curpos; +} + +void CIME::SetCurPos(int offset) +{ + if (offset < 0 || offset > ms_lastpos) + { + ms_curpos = ms_lastpos; + return; + } + else + { + // offset ؽƮ ġ ´. ؾ. + //ms_curpos = min(ms_lastpos, offset); + ms_curpos = min(ms_lastpos, GetTextTagInternalPosFromRenderPos(m_wText, ms_lastpos, offset)); + } +} + +void CIME::DelCurPos() +{ + if (ms_curpos < ms_lastpos) + { + int eraseCount = FindColorTagEndPosition(m_wText + ms_curpos, ms_lastpos - ms_curpos) + 1; + wcscpy(m_wText + ms_curpos, m_wText + ms_curpos + eraseCount); + ms_lastpos -= eraseCount; + ms_curpos = min(ms_lastpos, ms_curpos); + } +} + +void CIME::PasteString(const char * str) +{ + const char * begin = str; + const char * end = str + strlen(str); + wchar_t m_wText[IMESTR_MAXLEN]; + int wstrLen = MultiByteToWideChar(ms_uInputCodePage, 0, begin, end - begin, m_wText, IMESTR_MAXLEN); + InsertString(m_wText, wstrLen); + if(ms_pEvent) + ms_pEvent->OnUpdate(); +} + +/*---------------------------------------------------------------------------*/ /* Private */ +void CIME::InsertString(wchar_t* wString, int iSize) +{ + if (IsMax(wString, iSize)) + return; + + if (ms_curpos < ms_lastpos) + memmove(m_wText+ms_curpos+iSize, m_wText+ms_curpos, sizeof(wchar_t)*(ms_lastpos-ms_curpos)); + + memcpy(m_wText+ms_curpos, wString, sizeof(wchar_t)*iSize); + + ms_curpos += iSize; + ms_lastpos += iSize; +} + +void CIME::OnChar(wchar_t c) +{ + if (m_bOnlyNumberMode) + if (!iswdigit(c)) + return; + + if (!__IsWritable(c)) + return; + + InsertString(&c, 1); +} + +UINT CIME::GetCodePageFromLang(LANGID langid) +{ + unsigned pri_langid = PRIMARYLANGID(langid); + switch (pri_langid) + { + case LANG_JAPANESE: + //setlocale(LC_ALL, ".932"); + return 932; + case LANG_KOREAN: + //setlocale(LC_ALL, ".949"); + return 949; + case LANG_CHINESE: + { + switch (SUBLANGID(langid)) + { + case SUBLANG_CHINESE_SIMPLIFIED: + case SUBLANG_CHINESE_SINGAPORE: + //setlocale(LC_ALL, ".936"); + return 936; + case SUBLANG_CHINESE_TRADITIONAL: + case SUBLANG_CHINESE_MACAU: + case SUBLANG_CHINESE_HONGKONG: + //setlocale(LC_ALL, ".950"); + return 950; + } + } + //setlocale(LC_ALL, ".936"); + return 936; + case LANG_ARABIC: + return 1256; + case LANG_GREEK: + //setlocale(LC_ALL, ".1253"); + return 1253; + case LANG_TURKISH: + //setlocale(LC_ALL, ".1254"); + return 1254; + case LANG_HEBREW: + //setlocale(LC_ALL, ".1255"); + return 1255; + case LANG_ESTONIAN: + case LANG_LATVIAN: + case LANG_LITHUANIAN: + //setlocale(LC_ALL, ".1257"); + return 1257; + case LANG_VIETNAMESE: + return 1258; + case LANG_THAI: + //setlocale(LC_ALL, ".874"); + return 874; + case LANG_CZECH: + case LANG_HUNGARIAN: + case LANG_POLISH: + case LANG_CROATIAN: + case LANG_MACEDONIAN: + case LANG_ROMANIAN: + case LANG_SLOVAK: + case LANG_SLOVENIAN: + //setlocale(LC_ALL, ".1250"); + return 1250; + case LANG_RUSSIAN: + case LANG_BELARUSIAN: + case LANG_BULGARIAN: + case LANG_UKRAINIAN: + return 1251; + case LANG_GERMAN: + //_wsetlocale(LC_ALL, ".1252"); + return 1252; + default: + //TraceError("UNKNOWN IME[%d]\n", langid); + //setlocale(LC_ALL, ".949"); + return 1252; + } +} + +void CIME::CompositionProcess(HIMC hImc) +{ + ms_compLen = ImmGetCompositionStringW(hImc, GCS_COMPSTR, m_wszComposition, sizeof(m_wszComposition))/sizeof(wchar_t); + + //OutputDebugStringW( L"Composition: " ); + //OutputDebugStringW( m_wszComposition ); + //for( int i=0; i < (int) ms_compLen * 2; i++ ) { + // LPBYTE pbyData = (LPBYTE) m_wszComposition; + // pbyData += i; + // WCHAR tszName[32]; + + // swprintf_s( tszName, L"%02X ", (unsigned int) *pbyData ); + // OutputDebugStringW( tszName ); + //} + //OutputDebugStringW( L"\n" ); + + if (IsMax(m_wszComposition, ms_compLen)) + { + ImmNotifyIME(hImc, NI_COMPOSITIONSTR, CPS_CANCEL, 0); + ms_compLen = 0; + } +} + +void CIME::CompositionProcessBuilding(HIMC hImc) +{ + int textLen = WideCharToMultiByte(ms_uOutputCodePage, 0, m_wText, ms_lastpos, 0, 0, NULL, NULL); + + if (textLen >= m_max) + { + ImmNotifyIME(hImc, NI_COMPOSITIONSTR, CPS_CANCEL, 0); + ms_compLen = 0; + return; + } + + ms_compLen = ImmGetCompositionStringW(hImc, GCS_COMPSTR, m_wszComposition, sizeof(m_wszComposition))/sizeof(wchar_t); + + //OutputDebugStringW( L"Composition: " ); + //OutputDebugStringW( m_wszComposition ); + //for( int i=0; i < (int) ms_compLen * 2; i++ ) { + // LPBYTE pbyData = (LPBYTE) m_wszComposition; + // pbyData += i; + // WCHAR tszName[32]; + + // swprintf_s( tszName, L"%02X ", (unsigned int) *pbyData ); + // OutputDebugStringW( tszName ); + //} + //OutputDebugStringW( L"\n" ); +} + +void CIME::ResultProcess(HIMC hImc) +{ + wchar_t temp[IMESTR_MAXLEN]; + + int len = ImmGetCompositionStringW(hImc, GCS_RESULTSTR, temp, sizeof(temp))/sizeof(wchar_t); + + if (len <= 0) + return; + + InsertString(temp, len); +} + +void CIME::AttributeProcess(HIMC hImc) +{ + BYTE attribute[IMESTR_MAXLEN]; + LONG attributeLen = ImmGetCompositionStringW(hImc, GCS_COMPATTR, &attribute, sizeof(attribute)) / sizeof(BYTE); + + int start,end; + for(start=0; start abyCandidate; + DWORD dwCandidateLen = ImmGetCandidateListW(hImc, 0, NULL, 0); + abyCandidate.resize(dwCandidateLen); + if(dwCandidateLen > 0) { + ms_bCandidateList = true; + + CANDIDATELIST* lpCandidateList = (CANDIDATELIST*)(&abyCandidate[0]); + dwCandidateLen = ImmGetCandidateListW(hImc, 0, lpCandidateList, dwCandidateLen); + + ms_dwCandidateSelection = lpCandidateList->dwSelection; + ms_dwCandidateCount = lpCandidateList->dwCount; + + int iStartOfPage = 0; + + if( GETLANG() == LANG_CHS ) { + // MSPY (CHS IME) has variable number of candidates in candidate window find where current page starts, and the size of current page + const int maxCandChar = 18 * (3 - sizeof(TCHAR)); + UINT cChars = 0; + UINT i; + for (i = 0; i < ms_dwCandidateCount; i++) + { + UINT uLen = lstrlenW((LPWSTR)((DWORD)lpCandidateList + lpCandidateList->dwOffset[i])) + (3 - sizeof(WCHAR)); + if (uLen + cChars > maxCandChar) + { + if (i > ms_dwCandidateSelection) + { + break; + } + iStartOfPage = i; + cChars = uLen; + } + else + { + cChars += uLen; + } + } + ms_dwCandidatePageSize = i - iStartOfPage; + } else { + ms_dwCandidatePageSize = MIN( lpCandidateList->dwPageSize, MAX_CANDLIST ); + iStartOfPage = ms_bUILessMode ? lpCandidateList->dwPageStart : (ms_dwCandidateSelection / (MAX_CANDLIST - 1)) * (MAX_CANDLIST - 1); + } + + ms_dwCandidateSelection = ( GETLANG() == LANG_CHS && !GetImeId() ) ? (DWORD)-1 : ms_dwCandidateSelection - iStartOfPage; + + //printf( "SEL: %d, START: %d, PAGED: %d\n", ms_dwCandidateSelection, iStartOfPage, ms_dwCandidatePageSize ); + memset(&ms_wszCandidate, 0, sizeof(ms_wszCandidate)); + for(UINT i = iStartOfPage, j = 0; (DWORD)i < lpCandidateList->dwCount && j < ms_dwCandidatePageSize; i++, j++) { + wcscpy( ms_wszCandidate[j], (LPWSTR)( (DWORD)lpCandidateList + lpCandidateList->dwOffset[i] ) ); + } + + // don't display selection in candidate list in case of Korean and old Chinese IME. + if ( GETPRIMLANG() == LANG_KOREAN || GETLANG() == LANG_CHT && !GetImeId() ) + ms_dwCandidateSelection = (DWORD) -1; + } +} + +void CIME::ReadingProcess(HIMC hImc) +{ + if (!ms_adwId[0]) + { + return; + } + + DWORD dwErr = 0; + + if (_GetReadingString) + { + UINT uMaxUiLen; + BOOL bVertical; + // Obtain the reading string size + int wstrLen = _GetReadingString(hImc, 0, NULL, (PINT)&dwErr, &bVertical, &uMaxUiLen); + + if(wstrLen == 0) { + ms_wstrReading.resize(0); + } else { + wchar_t *wstr = (wchar_t*)alloca(sizeof(wchar_t) * wstrLen); + _GetReadingString(hImc, wstrLen, wstr, (PINT)&dwErr, &bVertical, &uMaxUiLen); + ms_wstrReading.assign(wstr, wstr+wstrLen); + } + + ms_bHorizontalReading = (bVertical == 0); + + } else { + + // IMEs that doesn't implement Reading String API + wchar_t* temp = NULL; + DWORD tempLen = 0; + bool bUnicodeIme = false; + INPUTCONTEXT *lpIC = _ImmLockIMC(hImc); + + if (lpIC == NULL) + { + temp = NULL; + tempLen = 0; + } + else + { + LPBYTE p = 0; + switch(ms_adwId[0]) + { + case IMEID_CHT_VER42: // New(Phonetic/ChanJie)IME98 : 4.2.x.x // Win98 + case IMEID_CHT_VER43: // New(Phonetic/ChanJie)IME98a : 4.3.x.x // WinMe, Win2k + case IMEID_CHT_VER44: // New ChanJie IME98b : 4.4.x.x // WinXP + p = *(LPBYTE *)((LPBYTE)_ImmLockIMCC(lpIC->hPrivate) + 24); + if (!p) break; + tempLen = *(DWORD *)(p + 7 * 4 + 32 * 4); + dwErr = *(DWORD *)(p + 8 * 4 + 32 * 4); + temp = (wchar_t *)(p + 56); + bUnicodeIme = true; + break; + + case IMEID_CHT_VER50: // 5.0.x.x // WinME + p = *(LPBYTE *)((LPBYTE)_ImmLockIMCC(lpIC->hPrivate) + 3 * 4); + if(!p) break; + p = *(LPBYTE *)((LPBYTE)p + 1*4 + 5*4 + 4*2); + if(!p) break; + tempLen = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16); + dwErr = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16 + 1*4); + temp = (wchar_t *)(p + 1*4 + (16*2+2*4) + 5*4); + bUnicodeIme = false; + break; + + case IMEID_CHT_VER51: // 5.1.x.x // IME2002(w/OfficeXP) + case IMEID_CHT_VER52: // 5.2.x.x // (w/whistler) + case IMEID_CHS_VER53: // 5.3.x.x // SCIME2k or MSPY3 (w/OfficeXP and Whistler) + p = *(LPBYTE *)((LPBYTE)_ImmLockIMCC(lpIC->hPrivate) + 4); + if(!p) break; + p = *(LPBYTE *)((LPBYTE)p + 1*4 + 5*4); + if(!p) break; + tempLen = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16 * 2); + dwErr = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16 * 2 + 1*4); + temp = (wchar_t *) (p + 1*4 + (16*2+2*4) + 5*4); + bUnicodeIme = true; + break; + + // the code tested only with Win 98 SE (MSPY 1.5/ ver 4.1.0.21) + case IMEID_CHS_VER41: + { + int nOffset; + nOffset = (ms_adwId[1] >= 0x00000002) ? 8 : 7; + + p = *(LPBYTE *)((LPBYTE)_ImmLockIMCC(lpIC->hPrivate) + nOffset * 4); + if(!p) break; + tempLen = *(DWORD *)(p + 7*4 + 16*2*4); + dwErr = *(DWORD *)(p + 8*4 + 16*2*4); + dwErr = min(dwErr, tempLen); + temp = (wchar_t *)(p + 6*4 + 16*2*1); + bUnicodeIme = true; + } + break; + + case IMEID_CHS_VER42: // 4.2.x.x // SCIME98 or MSPY2 (w/Office2k, Win2k, WinME, etc) + { + OSVERSIONINFOA osi; + osi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); + GetVersionExA(&osi); + + int nTcharSize = (osi.dwPlatformId == VER_PLATFORM_WIN32_NT) ? sizeof(wchar_t) : sizeof(char); + p = *(LPBYTE *)((LPBYTE)_ImmLockIMCC(lpIC->hPrivate) + 1*4 + 1*4 + 6*4); + if(!p) break; + tempLen = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16 * nTcharSize); + dwErr = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16 * nTcharSize + 1*4); + temp = (wchar_t *) (p + 1*4 + (16*2+2*4) + 5*4); + bUnicodeIme = (osi.dwPlatformId == VER_PLATFORM_WIN32_NT) ? true : false; + } + break; + + default: + temp = NULL; + tempLen = 0; + break; + } + } + + if(tempLen == 0) { + ms_wstrReading.resize(0); + } else { + if(bUnicodeIme) { + ms_wstrReading.assign(temp, temp+tempLen); + } else { + int wstrLen = MultiByteToWideChar(ms_uInputCodePage, 0, (char*)temp, tempLen, NULL, 0); + wchar_t* wstr = (wchar_t*)alloca(sizeof(wchar_t)*wstrLen); + MultiByteToWideChar(ms_uInputCodePage, 0, (char*)temp, tempLen, wstr, wstrLen); + ms_wstrReading.assign(wstr, wstr+wstrLen); + } + } + + _ImmUnlockIMCC(lpIC->hPrivate); + _ImmUnlockIMC(hImc); + + ms_bHorizontalReading = GetReadingWindowOrientation(); + } + if (ms_wstrReading.size()) { + ms_bReadingInformation = true; + if(ms_pEvent) + ms_pEvent->OnOpenReadingWnd(); + } else { + CloseReadingInformation(); + } +} + +bool CIME::IsMax(const wchar_t* wInput, int len) +{ + if (ms_lastpos + len > IMESTR_MAXLEN) + return true; + + int textLen = WideCharToMultiByte(ms_uOutputCodePage, 0, m_wText, ms_lastpos, 0, 0, NULL, NULL); + int inputLen = WideCharToMultiByte(ms_uOutputCodePage, 0, wInput, len, 0, 0, NULL, NULL); + //return textLen + inputLen > m_max; + + if (textLen + inputLen > m_max) + return true; + else if (m_userMax != 0 && m_max != m_userMax) + { + std::wstring str = GetTextTagOutputString(m_wText, ms_lastpos); + std::wstring input = GetTextTagOutputString(wInput, len); + int textLen = WideCharToMultiByte(ms_uOutputCodePage, 0, str.c_str(), str.length(), 0, 0, NULL, NULL); + int inputLen = WideCharToMultiByte(ms_uOutputCodePage, 0, input.c_str(), input.length(), 0, 0, NULL, NULL); + return textLen + inputLen > m_userMax; + } + return false; +} + +DWORD CIME::GetImeId( UINT uIndex ) +{ + static HKL hklPrev = 0; + char szTmp[1024]; + + if (uIndex >= COUNTOF(ms_adwId)) + return 0; + HKL hkl = ms_hklCurrent; + if(hklPrev == hkl) + return ms_adwId[uIndex]; + hklPrev = hkl; + + DWORD dwLang = ((DWORD)hkl & 0xffff); + + if ( ms_bUILessMode && GETLANG() == LANG_CHT ) { + // In case of Vista, artifitial value is returned so that it's not considered as older IME. + ms_adwId[0] = IMEID_CHT_VER_VISTA; + ms_adwId[1] = 0; + return ms_adwId[0]; + } + + if (!((ms_hklCurrent == _CHT_HKL_NEW_PHONETIC) || (ms_hklCurrent == _CHT_HKL_NEW_CHANG_JIE) || (ms_hklCurrent == _CHT_HKL_NEW_QUICK) || (ms_hklCurrent == _CHT_HKL_HK_CANTONESE) || (ms_hklCurrent == _CHS_HKL))) { + ms_adwId[0] = ms_adwId[1] = 0; + return 0; + } + + if (!ImmGetIMEFileNameA(ms_hklCurrent, szTmp, (sizeof(szTmp) / sizeof(szTmp[0])) - 1)) { + ms_adwId[0] = ms_adwId[1] = 0; + return 0; + } + + if (!_GetReadingString) + { + if ((CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTmp, -1, CHT_IMEFILENAME1, -1) != CSTR_EQUAL) && + (CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTmp, -1, CHT_IMEFILENAME2, -1) != CSTR_EQUAL) && + (CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTmp, -1, CHT_IMEFILENAME3, -1) != CSTR_EQUAL) && + (CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTmp, -1, CHS_IMEFILENAME1, -1) != CSTR_EQUAL) && + (CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTmp, -1, CHS_IMEFILENAME2, -1) != CSTR_EQUAL)) + { + ms_adwId[0] = ms_adwId[1] = 0; + return 0; + } + } + + DWORD dwVerHandle; + DWORD dwVerSize = GetFileVersionInfoSize(szTmp, &dwVerHandle); + LANGID langId = LOWORD(ms_hklCurrent); + + if (dwVerSize) + { + LPVOID lpVerBuffer = alloca(dwVerSize); + + if (GetFileVersionInfo(szTmp, dwVerHandle, dwVerSize, lpVerBuffer)) + { + LPVOID lpVerData; + UINT cbVerData; + + if(VerQueryValue(lpVerBuffer, "\\", &lpVerData, &cbVerData)) + { + DWORD dwVer = ((VS_FIXEDFILEINFO*) lpVerData)->dwFileVersionMS; + dwVer = (dwVer & 0x00ff0000) << 8 | (dwVer & 0x000000ff) << 16; + + if (_GetReadingString + || + (langId == LANG_CHT && + (dwVer == MAKEIMEVERSION(4, 2) || + dwVer == MAKEIMEVERSION(4, 3) || + dwVer == MAKEIMEVERSION(4, 4) || + dwVer == MAKEIMEVERSION(5, 0) || + dwVer == MAKEIMEVERSION(5, 1) || + dwVer == MAKEIMEVERSION(5, 2) || + dwVer == MAKEIMEVERSION(6, 0))) + || + (langId == LANG_CHS && + (dwVer == MAKEIMEVERSION(4, 1) || + dwVer == MAKEIMEVERSION(4, 2) || + dwVer == MAKEIMEVERSION(5, 3)))) + { + ms_adwId[0] = dwVer | langId; + ms_adwId[1] = ((VS_FIXEDFILEINFO*)lpVerData)->dwFileVersionLS; + return ms_adwId[uIndex]; + } + } + } + } + ms_adwId[0] = ms_adwId[1] = 0; + return ms_adwId[0]; +} + +bool CIME::GetReadingWindowOrientation() +{ + bool bHorizontalReading = (ms_hklCurrent == _CHS_HKL) || (ms_hklCurrent == _CHT_HKL_NEW_CHANG_JIE) || (ms_adwId[0] == 0); + if(!bHorizontalReading && (GETLANG() == LANG_CHT)) + { + char szRegPath[MAX_PATH]; + HKEY hKey; + DWORD dwVer = ms_adwId[0] & 0xFFFF0000; + strcpy(szRegPath, "software\\microsoft\\windows\\currentversion\\"); + strcat(szRegPath, (dwVer >= MAKEIMEVERSION(5, 1)) ? "MSTCIPH" : "TINTLGNT"); + LONG lRc = RegOpenKeyExA(HKEY_CURRENT_USER, szRegPath, 0, KEY_READ, &hKey); + if (lRc == ERROR_SUCCESS) + { + DWORD dwSize = sizeof(DWORD), dwMapping, dwType; + lRc = RegQueryValueExA(hKey, "Keyboard Mapping", NULL, &dwType, (PBYTE)&dwMapping, &dwSize); + if (lRc == ERROR_SUCCESS) + { + if ((dwVer <= MAKEIMEVERSION(5, 0) && + ((BYTE)dwMapping == 0x22 || (BYTE)dwMapping == 0x23)) + || + ((dwVer == MAKEIMEVERSION(5, 1) || dwVer == MAKEIMEVERSION(5, 2)) && + (BYTE)dwMapping >= 0x22 && (BYTE)dwMapping <= 0x24) + ) + { + bHorizontalReading = true; + } + } + RegCloseKey(hKey); + } + } + + return bHorizontalReading; +} + +void CIME::SetupImeApi() +{ + char szImeFile[MAX_PATH + 1]; + + _GetReadingString = NULL; + _ShowReadingWindow = NULL; + ms_bUseIMMCandidate = false; + + if(ImmGetIMEFileNameA(ms_hklCurrent, szImeFile, COUNTOF(szImeFile) - 1) == 0) + return; + if(stricmp(szImeFile, CHS_IMEFILENAME_QQPINYIN) == 0 || stricmp(szImeFile, CHS_IMEFILENAME_SOGOUPY) == 0 || stricmp(szImeFile, CHS_IMEFILENAME_GOOGLEPINYIN2) == 0) + ms_bUseIMMCandidate = true; + if (ms_bUILessMode) + return; + SAFE_FREE_LIBRARY(ms_hCurrentImeDll); + ms_hCurrentImeDll = LoadLibraryA(szImeFile); + + if (ms_hCurrentImeDll) { + _GetReadingString = (UINT (WINAPI*)(HIMC, UINT, LPWSTR, PINT, BOOL*, PUINT)) (GetProcAddress(ms_hCurrentImeDll, "GetReadingString")); + _ShowReadingWindow =(BOOL (WINAPI*)(HIMC, BOOL)) (GetProcAddress(ms_hCurrentImeDll, "ShowReadingWindow")); + + if(_ShowReadingWindow) { + HIMC hImc = ImmGetContext(ms_hWnd); + if(hImc) { + _ShowReadingWindow(hImc, false); + ImmReleaseContext(ms_hWnd, hImc); + } + } + } +} + +static unsigned long _strtoul( LPCSTR psz, LPTSTR*, int ) +{ + if ( !psz ) + return 0; + + ULONG ulRet = 0; + if ( psz[0] == '0' && ( psz[1] == 'x' || psz[1] == 'X' ) ) + { + psz += 2; + ULONG ul = 0; + while ( *psz ) + { + if ( '0' <= *psz && *psz <= '9' ) + ul = *psz - '0'; + else if ( 'A' <= *psz && *psz <= 'F' ) + ul = *psz - 'A' + 10; + else if ( 'a' <= *psz && *psz <= 'f' ) + ul = *psz - 'a' + 10; + else + break; + ulRet = ulRet * 16 + ul; + psz++; + } + } + else { + while ( *psz && ( '0' <= *psz && *psz <= '9' ) ) + { + ulRet = ulRet * 10 + ( *psz - '0' ); + psz++; + } + } + return ulRet; +} + +void CIME::CheckInputLocale() +{ + static UINT s_uPrevCodePage = 0xFFFF; + static HKL s_hklPrev = NULL; + + ms_hklCurrent = GetKeyboardLayout( 0 ); + if ( s_hklPrev == ms_hklCurrent ) + return; + s_hklPrev = ms_hklCurrent; + + char szCodePage[8]; + int iRc = GetLocaleInfoA( MAKELCID( GETLANG(), SORT_DEFAULT ), LOCALE_IDEFAULTANSICODEPAGE, szCodePage, COUNTOF( szCodePage ) ); iRc; + ms_uInputCodePage = _strtoul( szCodePage, NULL, 0 ); + if ( s_uPrevCodePage == ms_uInputCodePage ) + return; + s_uPrevCodePage = ms_uInputCodePage; + + GetKeyboardLayoutName(ms_szKeyboardLayout); + + switch (GETPRIMLANG()) + { + case LANG_KOREAN: + ms_bVerticalCandidate = false; + ms_wszCurrentIndicator = s_aszIndicator[INDICATOR_KOREAN]; + break; + + case LANG_JAPANESE: + ms_bVerticalCandidate = true; + ms_wszCurrentIndicator = s_aszIndicator[INDICATOR_JAPANESE]; + break; + + case LANG_CHINESE: + ms_bVerticalCandidate = true; + + switch(GETSUBLANG()) + { + case SUBLANG_CHINESE_SIMPLIFIED: + case SUBLANG_CHINESE_SINGAPORE: + //ms_bVerticalCandidate = (GetImeId() == 0); + ms_bVerticalCandidate = false; + ms_wszCurrentIndicator = s_aszIndicator[INDICATOR_CHS]; + break; + + case SUBLANG_CHINESE_TRADITIONAL: + case SUBLANG_CHINESE_HONGKONG: + case SUBLANG_CHINESE_MACAU: + ms_wszCurrentIndicator = s_aszIndicator[INDICATOR_CHT]; + break; + + default: // unsupported sub-language + ms_wszCurrentIndicator = s_aszIndicator[INDICATOR_NON_IME]; + break; + } + break; + + default: + ms_wszCurrentIndicator = s_aszIndicator[INDICATOR_NON_IME]; + break; + } + + if (ms_wszCurrentIndicator == s_aszIndicator[INDICATOR_NON_IME]) + { + char szLang[10]; + GetLocaleInfoA(MAKELCID(GETLANG(), SORT_DEFAULT), LOCALE_SABBREVLANGNAME, szLang, sizeof(szLang)); + ms_wszCurrentIndicator[0] = szLang[0]; + ms_wszCurrentIndicator[1] = towlower(szLang[1]); + } + + // ƶ ڵ ٲ ʴ´ + // 뵵 ʴ´. + if(ms_uOutputCodePage != 1256) { + ms_uOutputCodePage = ms_uInputCodePage; + Clear(); + } + + //for ( int i = 0; i < 256; i++ ) + //{ + // LeadByteTable[i] = (BYTE)IsDBCSLeadByteEx( g_uCodePage, (BYTE)i ); + //} +} + +void CIME::CheckToggleState() +{ + CheckInputLocale(); + + // In Vista, we have to use TSF since few IMM functions don't work as expected. + // WARNING: Because of timing, g_dwState and g_bChineseIME may not be updated + // immediately after the change on IME states by user. + if ( ms_bUILessMode ) + return; + + /* Check Toggle State */ + bool bIme = ImmIsIME( ms_hklCurrent ) != 0 + && ( ( 0xF0000000 & (DWORD)ms_hklCurrent ) == 0xE0000000 ); // Hack to detect IME correctly. When IME is running as TIP, ImmIsIME() returns true for CHT US keyboard. + ms_bChineseIME = ( GETPRIMLANG() == LANG_CHINESE ) && bIme; + + HIMC himc; + if (NULL != (himc = ImmGetContext(ms_hWnd))) { + if (ms_bChineseIME) { + DWORD dwConvMode, dwSentMode; + ImmGetConversionStatus(himc, &dwConvMode, &dwSentMode); + ms_dwImeState = ( dwConvMode & IME_CMODE_NATIVE ) ? IMEUI_STATE_ON : IMEUI_STATE_ENGLISH; + } + else + { + ms_dwImeState = ( bIme && ImmGetOpenStatus( himc ) != 0 ) ? IMEUI_STATE_ON : IMEUI_STATE_OFF; + } + ImmReleaseContext(ms_hWnd, himc); + } + else + ms_dwImeState = IMEUI_STATE_OFF; +} + +/////////////////////////////////////////////////////////////////////////////// +// +// CTsfUiLessMode methods +// +/////////////////////////////////////////////////////////////////////////////// + +// +// SetupSinks() +// Set up sinks. A sink is used to receive a Text Service Framework event. +// CUIElementSink implements multiple sink interfaces to receive few different TSF events. +// +BOOL CTsfUiLessMode::SetupSinks() +{ + // ITfThreadMgrEx is available on Vista or later. + HRESULT hr; + hr = CoCreateInstance(CLSID_TF_ThreadMgr, + NULL, + CLSCTX_INPROC_SERVER, + __uuidof(ITfThreadMgrEx), + (void**)&m_tm); + + if (hr != S_OK) + { + return FALSE; + } + + // ready to start interacting + TfClientId cid; // not used + if (FAILED(m_tm->ActivateEx(&cid, TF_TMAE_UIELEMENTENABLEDONLY))) + { + return FALSE; + } + + // Setup sinks + BOOL bRc = FALSE; + m_TsfSink = new CUIElementSink(); + if (m_TsfSink) + { + ITfSource *srcTm; + if (SUCCEEDED(hr = m_tm->QueryInterface(__uuidof(ITfSource), (void **)&srcTm))) + { + // Sink for reading window change + if (SUCCEEDED(hr = srcTm->AdviseSink(__uuidof(ITfUIElementSink), (ITfUIElementSink*)m_TsfSink, &m_dwUIElementSinkCookie))) + { + // Sink for input locale change + if (SUCCEEDED(hr = srcTm->AdviseSink(__uuidof(ITfInputProcessorProfileActivationSink), (ITfInputProcessorProfileActivationSink*)m_TsfSink, &m_dwAlpnSinkCookie))) + { + if (SetupCompartmentSinks()) // Setup compartment sinks for the first time + { + bRc = TRUE; + } + } + } + srcTm->Release(); + } + } + return bRc; +} + +void CTsfUiLessMode::ReleaseSinks() +{ + HRESULT hr; + ITfSource *source; + + // Remove all sinks + if ( m_tm && SUCCEEDED(m_tm->QueryInterface(__uuidof(ITfSource), (void **)&source))) + { + hr = source->UnadviseSink(m_dwUIElementSinkCookie); + hr = source->UnadviseSink(m_dwAlpnSinkCookie); + source->Release(); + SetupCompartmentSinks(TRUE); // Remove all compartment sinks + m_tm->Deactivate(); + SAFE_RELEASE(m_tm); + SAFE_RELEASE(m_TsfSink); + } +} + +CTsfUiLessMode::CUIElementSink::CUIElementSink() +{ + _cRef = 1; +} + + +CTsfUiLessMode::CUIElementSink::~CUIElementSink() +{ +} + +STDAPI CTsfUiLessMode::CUIElementSink::QueryInterface(REFIID riid, void **ppvObj) +{ + if (ppvObj == NULL) + return E_INVALIDARG; + + *ppvObj = NULL; + + if (IsEqualIID(riid, IID_IUnknown)) + { + *ppvObj = reinterpret_cast(this); + } + else if (IsEqualIID(riid, __uuidof(ITfUIElementSink))) + { + *ppvObj = (ITfUIElementSink *)this; + } + else if (IsEqualIID(riid, __uuidof(ITfInputProcessorProfileActivationSink))) + { + *ppvObj = (ITfInputProcessorProfileActivationSink*)this; + } + else if (IsEqualIID(riid, __uuidof(ITfCompartmentEventSink))) + { + *ppvObj = (ITfCompartmentEventSink*)this; + } + + if (*ppvObj) + { + AddRef(); + return S_OK; + } + + return E_NOINTERFACE; +} + +STDAPI_(ULONG) CTsfUiLessMode::CUIElementSink::AddRef() +{ + return ++_cRef; +} + +STDAPI_(ULONG) CTsfUiLessMode::CUIElementSink::Release() +{ + LONG cr = --_cRef; + + if (_cRef == 0) + { + delete this; + } + + return cr; +} + +STDAPI CTsfUiLessMode::CUIElementSink::BeginUIElement(DWORD dwUIElementId, BOOL *pbShow) +{ + ITfUIElement *pElement = GetUIElement(dwUIElementId); + if (!pElement) + return E_INVALIDARG; + + ITfReadingInformationUIElement *preading = NULL; + ITfCandidateListUIElement *pcandidate = NULL; + *pbShow = FALSE; + + //BSTR bstrDesc; + //OutputDebugStringW(L"BEGINUI: "); + //pElement->GetDescription(&bstrDesc); + //OutputDebugStringW(bstrDesc); + //OutputDebugStringW(L"\n"); + + if (SUCCEEDED(pElement->QueryInterface(__uuidof(ITfReadingInformationUIElement), (void **)&preading))) + { + MakeReadingInformationString(preading); + if(CIME::ms_pEvent) + CIME::ms_pEvent->OnOpenReadingWnd(); + preading->Release(); + } + else if (SUCCEEDED(pElement->QueryInterface(__uuidof(ITfCandidateListUIElement), (void **)&pcandidate))) + { + m_nCandidateRefCount++; + MakeCandidateStrings(pcandidate); + if(CIME::ms_pEvent) + CIME::ms_pEvent->OnOpenCandidateList(); + pcandidate->Release(); + } + + pElement->Release(); + return S_OK; +} + +STDAPI CTsfUiLessMode::CUIElementSink::UpdateUIElement(DWORD dwUIElementId) +{ + ITfUIElement *pElement = GetUIElement(dwUIElementId); + if (!pElement) + return E_INVALIDARG; + + ITfReadingInformationUIElement *preading = NULL; + ITfCandidateListUIElement *pcandidate = NULL; + + //BSTR bstrDesc; + //pElement->GetDescription(&bstrDesc); + //OutputDebugStringW(L"UPDATEUI: "); + //OutputDebugStringW(bstrDesc); + //OutputDebugStringW(L"\n"); + + if (SUCCEEDED(pElement->QueryInterface(__uuidof(ITfReadingInformationUIElement), (void **)&preading))) + { + MakeReadingInformationString(preading); + if(CIME::ms_pEvent) + CIME::ms_pEvent->OnOpenReadingWnd(); + preading->Release(); + } + else if (SUCCEEDED(pElement->QueryInterface(__uuidof(ITfCandidateListUIElement), (void **)&pcandidate))) + { + MakeCandidateStrings(pcandidate); + if(CIME::ms_pEvent) + CIME::ms_pEvent->OnOpenCandidateList(); + pcandidate->Release(); + } + + pElement->Release(); + return S_OK; +} + +STDAPI CTsfUiLessMode::CUIElementSink::EndUIElement(DWORD dwUIElementId) +{ + ITfUIElement *pElement = GetUIElement(dwUIElementId); + if (!pElement) + return E_INVALIDARG; + + //BSTR bstrDesc; + //OutputDebugStringW(L"ENDUI: "); + //pElement->GetDescription(&bstrDesc); + //OutputDebugStringW(bstrDesc); + //OutputDebugStringW(L"\n"); + + ITfReadingInformationUIElement *preading = NULL; + if (SUCCEEDED(pElement->QueryInterface(__uuidof(ITfReadingInformationUIElement), (void **)&preading))) + { + CIME::CloseReadingInformation(); + preading->Release(); + } + + ITfCandidateListUIElement *pcandidate = NULL; + if (SUCCEEDED(pElement->QueryInterface(__uuidof(ITfCandidateListUIElement), (void **)&pcandidate))) + { + m_nCandidateRefCount--; + if (m_nCandidateRefCount == 0) + CIME::CloseCandidateList(); + pcandidate->Release(); + } + + pElement->Release(); + return S_OK; +} + +void CTsfUiLessMode::UpdateImeState(BOOL bResetCompartmentEventSink) +{ + ITfCompartmentMgr* pcm; + ITfCompartment* pTfOpenMode = NULL; + ITfCompartment* pTfConvMode = NULL; + if ( GetCompartments( &pcm, &pTfOpenMode, &pTfConvMode ) ) + { + VARIANT valOpenMode; + VARIANT valConvMode; + pTfOpenMode->GetValue( &valOpenMode ); + pTfConvMode->GetValue( &valConvMode ); + if ( valOpenMode.vt == VT_I4 ) + { + if ( CIME::ms_bChineseIME ) + { + CIME::ms_dwImeState = valOpenMode.lVal != 0 && valConvMode.lVal != 0 ? IMEUI_STATE_ON : IMEUI_STATE_ENGLISH; + } + else + { + CIME::ms_dwImeState = valOpenMode.lVal != 0 ? IMEUI_STATE_ON : IMEUI_STATE_OFF; + } + } + VariantClear( &valOpenMode ); + VariantClear( &valConvMode ); + + if ( bResetCompartmentEventSink ) + { + SetupCompartmentSinks( FALSE, pTfOpenMode, pTfConvMode ); // Reset compartment sinks + } + pTfOpenMode->Release(); + pTfConvMode->Release(); + pcm->Release(); + } +} + +STDAPI CTsfUiLessMode::CUIElementSink::OnActivated(DWORD dwProfileType, LANGID langid, REFCLSID clsid, REFGUID catid, + REFGUID guidProfile, HKL hkl, DWORD dwFlags) +{ + static GUID TF_PROFILE_DAYI = { 0x037B2C25, 0x480C, 0x4D7F, 0xB0, 0x27, 0xD6, 0xCA, 0x6B, 0x69, 0x78, 0x8A }; + CIME::ms_iCandListIndexBase = IsEqualGUID( TF_PROFILE_DAYI, guidProfile ) ? 0 : 1; + if ( IsEqualIID( catid, GUID_TFCAT_TIP_KEYBOARD ) && ( dwFlags & TF_IPSINK_FLAG_ACTIVE ) ) + { + CIME::ms_bChineseIME = ( dwProfileType & TF_PROFILETYPE_INPUTPROCESSOR ) && langid == LANG_CHT; + if ( dwProfileType & TF_PROFILETYPE_INPUTPROCESSOR ) + { + UpdateImeState(TRUE); + } + else + CIME::ms_dwImeState = IMEUI_STATE_OFF; + CIME::ChangeInputLanguage(); + } + return S_OK; +} + +STDAPI CTsfUiLessMode::CUIElementSink::OnChange(REFGUID rguid) +{ + UpdateImeState(); + return S_OK; +} + +void CTsfUiLessMode::MakeReadingInformationString(ITfReadingInformationUIElement* preading) +{ + UINT cchMax; + UINT uErrorIndex = 0; + BOOL fVertical; + DWORD dwFlags; + + CIME::ms_wstrReading.resize(0); + preading->GetUpdatedFlags(&dwFlags); + preading->GetMaxReadingStringLength(&cchMax); + preading->GetErrorIndex(&uErrorIndex); // errorIndex is zero-based + preading->IsVerticalOrderPreferred(&fVertical); + CIME::ms_iReadingError = (int)uErrorIndex; + CIME::ms_bHorizontalReading = !fVertical; + CIME::ms_bReadingInformation = true; + BSTR bstr; + if (SUCCEEDED(preading->GetString(&bstr))) + { + if (bstr) + { + CIME::ms_wstrReading.assign( (wchar_t *) bstr, (wchar_t *) bstr+lstrlenW(bstr) ); + LPCWSTR pszSource = &(CIME::ms_wstrReading[0]); + if ( fVertical ) + { + CIME::ms_dwCandidatePageSize = CIME::MAX_CANDLIST; + // ms_iReadingError is used only in horizontal window, and has to be -1 if there's no error. + CIME::ms_dwCandidateSelection = CIME::ms_iReadingError ? CIME::ms_iReadingError - 1 : (DWORD)-1; + CIME::ms_dwCandidateCount = cchMax; + // for vertical reading window, copy each character to g_szCandidate array. + for ( UINT i = 0; i < cchMax; i++ ) + { + LPWSTR pszDest = CIME::ms_wszCandidate[i]; + if ( *pszSource ) + { + LPWSTR pszNextSrc = CharNextW(pszSource); + SIZE_T size = (LPSTR)pszNextSrc - (LPSTR)pszSource; + CopyMemory( pszDest, pszSource, size ); + pszSource = pszNextSrc; + pszDest += size; + } + *pszDest = 0; + } + } + //else + //{ + // CIME::ms_wszCandidate[0][0] = L' '; // hack to make rendering happen + //} + SysFreeString(bstr); + } + } +} + +void CTsfUiLessMode::MakeCandidateStrings(ITfCandidateListUIElement* pcandidate) +{ + UINT uIndex = 0; + UINT uCount = 0; + UINT uCurrentPage = 0; + UINT *IndexList = NULL; + UINT uPageCnt = 0; + DWORD dwPageStart = 0; + DWORD dwPageSize = 0; + BSTR bstr; + + pcandidate->GetSelection(&uIndex); + pcandidate->GetCount(&uCount); + pcandidate->GetCurrentPage(&uCurrentPage); + CIME::ms_dwCandidateSelection = (DWORD)uIndex; + CIME::ms_dwCandidateCount = (DWORD)uCount; + CIME::ms_bCandidateList = true; + + pcandidate->GetPageIndex(NULL, 0, &uPageCnt); + if(uPageCnt > 0) + { + IndexList = (UINT *) malloc(sizeof(UINT)*uPageCnt); + if(IndexList) + { + pcandidate->GetPageIndex(IndexList, uPageCnt, &uPageCnt); + dwPageStart = IndexList[uCurrentPage]; + dwPageSize = (uCurrentPage < uPageCnt-1) ? + min(uCount, IndexList[uCurrentPage+1]) - dwPageStart: + uCount - dwPageStart; + } + } + + CIME::ms_dwCandidatePageSize = min(dwPageSize, CIME::MAX_CANDLIST); + CIME::ms_dwCandidateSelection = CIME::ms_dwCandidateSelection - dwPageStart; + + memset(&CIME::ms_wszCandidate, 0, sizeof(CIME::ms_wszCandidate)); + for (UINT i = dwPageStart, j = 0; (DWORD)i < CIME::ms_dwCandidateCount && j < CIME::ms_dwCandidatePageSize; i++, j++) + { + if (SUCCEEDED(pcandidate->GetString( i, &bstr ))) + { + if(bstr) + { + wcscpy( CIME::ms_wszCandidate[j], bstr ); + SysFreeString(bstr); + } + } + } + //OutputDebugStringW( L"\n" ); + + if (GETPRIMLANG() == LANG_KOREAN) + { + CIME::ms_dwCandidateSelection = (DWORD)-1; + } + + if(IndexList) + { + free(IndexList); + } +} + +ITfUIElement* CTsfUiLessMode::GetUIElement(DWORD dwUIElementId) +{ + ITfUIElementMgr *puiem; + ITfUIElement *pElement = NULL; + + if (SUCCEEDED(m_tm->QueryInterface(__uuidof(ITfUIElementMgr), (void **)&puiem))) + { + puiem->GetUIElement(dwUIElementId, &pElement); + puiem->Release(); + } + + return pElement; +} + +BOOL CTsfUiLessMode::CurrentInputLocaleIsIme() +{ + BOOL ret = FALSE; + HRESULT hr; + + ITfInputProcessorProfiles *pProfiles; + hr = CoCreateInstance(CLSID_TF_InputProcessorProfiles, NULL, CLSCTX_INPROC_SERVER, __uuidof(ITfInputProcessorProfiles), (LPVOID*)&pProfiles); + if (SUCCEEDED(hr)) + { + ITfInputProcessorProfileMgr *pProfileMgr; + hr = pProfiles->QueryInterface(__uuidof(ITfInputProcessorProfileMgr), (LPVOID*)&pProfileMgr); + if (SUCCEEDED(hr)) + { + TF_INPUTPROCESSORPROFILE tip; + hr = pProfileMgr->GetActiveProfile( GUID_TFCAT_TIP_KEYBOARD, &tip ); + if (SUCCEEDED(hr)) + { + ret = ( tip.dwProfileType & TF_PROFILETYPE_INPUTPROCESSOR ) != 0; + } + pProfileMgr->Release(); + } + pProfiles->Release(); + } + return ret; +} + +// Sets up or removes sink for UI element. +// UI element sink should be removed when IME is disabled, +// otherwise the sink can be triggered when a game has multiple instances of IME UI library. +void CTsfUiLessMode::EnableUiUpdates(bool bEnable) +{ + if ( m_tm == NULL || + ( bEnable && m_dwUIElementSinkCookie != TF_INVALID_COOKIE ) || + ( !bEnable && m_dwUIElementSinkCookie == TF_INVALID_COOKIE ) ) + { + return; + } + ITfSource *srcTm = NULL; + HRESULT hr = E_FAIL; + if (SUCCEEDED(hr = m_tm->QueryInterface(__uuidof(ITfSource), (void **)&srcTm))) + { + if ( bEnable ) + { + hr = srcTm->AdviseSink(__uuidof(ITfUIElementSink), (ITfUIElementSink*)m_TsfSink, &m_dwUIElementSinkCookie); + } + else + { + hr = srcTm->UnadviseSink(m_dwUIElementSinkCookie); + m_dwUIElementSinkCookie = TF_INVALID_COOKIE; + } + srcTm->Release(); + } +} + +// Returns open mode compartments and compartment manager. +// Function fails if it fails to acquire any of the objects to be returned. +BOOL CTsfUiLessMode::GetCompartments( ITfCompartmentMgr** ppcm, ITfCompartment** ppTfOpenMode, ITfCompartment** ppTfConvMode ) +{ + ITfCompartmentMgr* pcm = NULL; + ITfCompartment* pTfOpenMode = NULL; + ITfCompartment* pTfConvMode = NULL; + + static GUID _GUID_COMPARTMENT_KEYBOARD_INPUTMODE_CONVERSION = { 0xCCF05DD8, 0x4A87, 0x11D7, 0xA6, 0xE2, 0x00, 0x06, 0x5B, 0x84, 0x43, 0x5C }; + + HRESULT hr; + if (SUCCEEDED(hr = m_tm->QueryInterface( IID_ITfCompartmentMgr, (void**)&pcm ))) + { + if (SUCCEEDED(hr = pcm->GetCompartment( GUID_COMPARTMENT_KEYBOARD_OPENCLOSE, &pTfOpenMode ))) + { + if (SUCCEEDED(hr = pcm->GetCompartment( _GUID_COMPARTMENT_KEYBOARD_INPUTMODE_CONVERSION, &pTfConvMode ))) + { + *ppcm = pcm; + *ppTfOpenMode = pTfOpenMode; + *ppTfConvMode = pTfConvMode; + return TRUE; + } + pTfOpenMode->Release(); + } + pcm->Release(); + } + return FALSE; +} + +// There are three ways to call this function: +// SetupCompartmentSinks() : initialization +// SetupCompartmentSinks(FALSE, openmode, convmode) : Resetting sinks. This is necessary as DaYi and Array IME resets compartment on switching input locale +// SetupCompartmentSinks(TRUE) : clean up sinks +BOOL CTsfUiLessMode::SetupCompartmentSinks( BOOL bRemoveOnly, ITfCompartment* pTfOpenMode, ITfCompartment* pTfConvMode ) +{ + bool bLocalCompartments = false; + ITfCompartmentMgr* pcm = NULL; + BOOL bRc = FALSE; + HRESULT hr = E_FAIL; + + if ( !pTfOpenMode && !pTfConvMode ) + { + bLocalCompartments = true; + GetCompartments( &pcm, &pTfOpenMode, &pTfConvMode ); + } + if ( !( pTfOpenMode && pTfConvMode ) ) + { + // Invalid parameters or GetCompartments() has failed. + return FALSE; + } + ITfSource *srcOpenMode = NULL; + if (SUCCEEDED(hr = pTfOpenMode->QueryInterface( IID_ITfSource, (void**)&srcOpenMode ))) + { + // Remove existing sink for open mode + if ( m_dwOpenModeSinkCookie != TF_INVALID_COOKIE ) + { + srcOpenMode->UnadviseSink( m_dwOpenModeSinkCookie ); + m_dwOpenModeSinkCookie = TF_INVALID_COOKIE; + } + // Setup sink for open mode (toggle state) change + if ( bRemoveOnly || SUCCEEDED(hr = srcOpenMode->AdviseSink( IID_ITfCompartmentEventSink, (ITfCompartmentEventSink*)m_TsfSink, &m_dwOpenModeSinkCookie ))) + { + ITfSource *srcConvMode = NULL; + if (SUCCEEDED(hr = pTfConvMode->QueryInterface( IID_ITfSource, (void**)&srcConvMode ))) + { + // Remove existing sink for open mode + if ( m_dwConvModeSinkCookie != TF_INVALID_COOKIE ) + { + srcConvMode->UnadviseSink( m_dwConvModeSinkCookie ); + m_dwConvModeSinkCookie = TF_INVALID_COOKIE; + } + // Setup sink for open mode (toggle state) change + if ( bRemoveOnly || SUCCEEDED(hr = srcConvMode->AdviseSink( IID_ITfCompartmentEventSink, (ITfCompartmentEventSink*)m_TsfSink, &m_dwConvModeSinkCookie ))) + { + bRc = TRUE; + } + srcConvMode->Release(); + } + } + srcOpenMode->Release(); + } + if ( bLocalCompartments ) + { + pTfOpenMode->Release(); + pTfConvMode->Release(); + pcm->Release(); + } + return bRc; +} + +/* IME Message Handler */ +LRESULT CIME::WMInputLanguage(HWND hWnd, UINT /*uiMsg*/, WPARAM /*wParam*/, LPARAM lParam) +{ + ChangeInputLanguage(); + return 0; +} + +LRESULT CIME::WMStartComposition(HWND /*hWnd*/, UINT /*uiMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/) +{ + return 1L; +} + +LRESULT CIME::WMComposition(HWND hWnd, UINT /*uiMsg*/, WPARAM /*wParam*/, LPARAM lParam) +{ + LRESULT result = 0; + + if(ms_bCaptureInput == false) + return 0; + + HIMC hImc = ImmGetContext(hWnd); + + if(hImc == NULL) + return 0; + + if(lParam&GCS_RESULTSTR) + ResultProcess(hImc); + if(lParam&GCS_COMPATTR) + AttributeProcess(hImc); + if(lParam&GCS_COMPSTR) + { + if (ms_uOutputCodePage == 950) // 븸 Է ó + { + if (lParam&GCS_COMPATTR) + CompositionProcessBuilding(hImc); + else + CompositionProcess(hImc); + } + else + { + CompositionProcess(hImc); + } + } + + ImmReleaseContext(hWnd, hImc); + + if(ms_pEvent) + ms_pEvent->OnUpdate(); + + return (result); +} + +LRESULT CIME::WMEndComposition(HWND /*hWnd*/, UINT /*uiMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/) +{ + ms_compLen = 0; + ms_ulbegin = 0; + ms_ulend = 0; + + if(ms_pEvent) + ms_pEvent->OnUpdate(); + + return 0L; +} + +LRESULT CIME::WMNotify(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam) +{ + LRESULT result = 0; + + if(ms_bCaptureInput == false) + return 0; + switch (wParam) { + + case IMN_OPENCANDIDATE: + case IMN_CHANGECANDIDATE: { + if (ms_bUILessMode && !ms_bUseIMMCandidate) + break; + HIMC hImc = ImmGetContext(hWnd); + if (hImc == NULL) + break; + CandidateProcess(hImc); + if (!m_bUseDefaultIME) { + if(ms_pEvent) + ms_pEvent->OnOpenCandidateList(); + } else + result = ::DefWindowProc(hWnd, uiMsg, wParam, lParam); + ImmReleaseContext(hWnd, hImc); + break; + } + case IMN_CLOSECANDIDATE: + if (ms_bUILessMode && !ms_bUseIMMCandidate) + break; + if (!m_bUseDefaultIME) + CloseCandidateList(); + else + result = DefWindowProc(hWnd, uiMsg, wParam, lParam); + break; + + case IMN_SETCONVERSIONMODE: + case IMN_SETOPENSTATUS: + if (ms_bUILessMode) + break; + CheckToggleState(); + break; + + case IMN_PRIVATE: { + if (ms_bUILessMode) + break; + HIMC hImc = ImmGetContext(hWnd); + if (hImc == NULL) + break; + ReadingProcess(hImc); + + // Trap some messages to hide reading window + switch(ms_adwId[0]) + { + case IMEID_CHT_VER42: + case IMEID_CHT_VER43: + case IMEID_CHT_VER44: + case IMEID_CHS_VER41: + case IMEID_CHS_VER42: + if ((lParam == 1)||(lParam == 2)) + return true; + break; + + case IMEID_CHT_VER50: + case IMEID_CHT_VER51: + case IMEID_CHT_VER52: + case IMEID_CHT_VER60: + case IMEID_CHS_VER53: + if ((lParam == 16)||(lParam == 17)||(lParam == 26)||(lParam == 27)||(lParam == 28)) + return true; + break; + } + ImmReleaseContext(hWnd, hImc); + break; + } + } + + if(ms_pEvent) + ms_pEvent->OnUpdate(); + + return result; +} + +LRESULT CIME::WMChar(HWND /*hWnd*/, UINT /*uiMsg*/, WPARAM wParam, LPARAM lParam) +{ + unsigned char c = unsigned char(wParam & 0xff); + + switch (c) + { + case 8: + if(ms_bCaptureInput == false) + return 0; + if (ms_curpos > 0) + { + DecCurPos(); + DelCurPos(); + } + if(ms_pEvent) + ms_pEvent->OnUpdate(); + return 0; + break; + + default: + if(ms_pEvent) { + if (ms_pEvent->OnWM_CHAR(wParam, lParam)) + break; + } + if(ms_bCaptureInput == false) + return 0; + wchar_t w[10]; + MultiByteToWideChar(ms_uInputCodePage, 0, (char*)&c, 1, w, 1); + + OnChar(w[0]); + if (w[0] == L'|') + OnChar(w[0]); + if(ms_pEvent) + ms_pEvent->OnUpdate(); + break; + } + + return 0; +} + diff --git a/source/EterLib/IME.h b/source/EterLib/IME.h new file mode 100644 index 0000000..58e90a1 --- /dev/null +++ b/source/EterLib/IME.h @@ -0,0 +1,208 @@ +#pragma once + +#include + +#pragma comment(lib, "imm32.lib") + +#include "DIMM.h" + +class IIMEEventSink +{ +public: + virtual bool OnWM_CHAR( WPARAM wParam, LPARAM lParam ) = 0; + virtual void OnUpdate() = 0; + + virtual void OnChangeCodePage() = 0; + + virtual void OnOpenCandidateList() = 0; + virtual void OnCloseCandidateList() = 0; + + virtual void OnOpenReadingWnd() = 0; + virtual void OnCloseReadingWnd() = 0; +}; + +class CIME +{ +public: + enum + { + IMEREADING_MAXLEN = 128, + IMESTR_MAXLEN = 1024, + IMECANDIDATE_MAXLEN = 32768, + MAX_CANDLIST = 10, + MAX_CANDIDATE_LENGTH = 256 + }; + +public: + CIME(); + virtual ~CIME(); + + bool Initialize(HWND hWnd); + void Uninitialize(void); + + static void Clear(); + + void SetMax(int iMax); + void SetUserMax(int iMax); + void SetText(const char* c_szText, int len); + int GetText(std::string & rstrText, bool addCodePage=false); + const char* GetCodePageText(); + int GetCodePage(); + + // Candidate List + int GetCandidateCount(); + int GetCandidatePageCount(); + int GetCandidate(DWORD index, std::string & rstrText); + int GetCandidateSelection(); + + // Reading Information + int GetReading(std::string & rstrText); + int GetReadingError(); + + void SetInputMode(DWORD dwMode); + DWORD GetInputMode(); + + bool IsIMEEnabled(); + void EnableIME(bool bEnable=true); + void DisableIME(); + + void EnableCaptureInput(); + void DisableCaptureInput(); + bool IsCaptureEnabled(); + + void SetNumberMode(); + void SetStringMode(); + bool __IsWritable(wchar_t key); + void AddExceptKey(wchar_t key); + void ClearExceptKey(); + + void PasteTextFromClipBoard(); + void EnablePaste(bool bFlag); + void PasteString(const char * str); + static void FinalizeString(bool bSend = false); + + void UseDefaultIME(); + + static int GetCurPos(); + static int GetCompLen(); + static int GetULBegin(); + static int GetULEnd(); + + static void CloseCandidateList(); + static void CloseReadingInformation(); + static void ChangeInputLanguage(); + static void ChangeInputLanguageWorker(); + + LRESULT WMInputLanguage(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam); + LRESULT WMStartComposition(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam); + LRESULT WMComposition(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam); + LRESULT WMEndComposition(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam); + LRESULT WMNotify(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam); + LRESULT WMChar(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam); + +protected: + void IncCurPos(); + void DecCurPos(); + void SetCurPos(int offset); + void DelCurPos(); + +protected: + static void CheckInputLocale(); + static void CheckToggleState(); + static void SetSupportLevel( DWORD dwImeLevel ); + + void InsertString(wchar_t* szString, int iSize); + + void OnChar(wchar_t c); + + UINT GetCodePageFromLang( LANGID langid ); + void ResultProcess(HIMC hImc); + void CompositionProcessBuilding(HIMC hImc); + void CompositionProcess(HIMC hImc); + void AttributeProcess(HIMC hImc); + void CandidateProcess(HIMC hImc); + void ReadingProcess(HIMC hImc); + + bool IsMax(const wchar_t* wInput, int len); + + DWORD GetImeId(UINT uIndex = 0); + bool GetReadingWindowOrientation(); + static void SetupImeApi(); + + static INPUTCONTEXT* (WINAPI * _ImmLockIMC)( HIMC ); + static BOOL (WINAPI * _ImmUnlockIMC)( HIMC ); + static LPVOID (WINAPI * _ImmLockIMCC)( HIMCC ); + static BOOL (WINAPI * _ImmUnlockIMCC)( HIMCC ); + + static UINT (WINAPI * _GetReadingString)( HIMC, UINT, LPWSTR, PINT, BOOL*, PUINT ); + static BOOL (WINAPI * _ShowReadingWindow)( HIMC, BOOL ); + +protected: + HIMC m_hOrgIMC; + int m_max; + int m_userMax; + + BOOL m_bOnlyNumberMode; + + std::vector m_exceptKey; + + bool m_bEnablePaste; + bool m_bUseDefaultIME; + + +public: + static bool ms_bInitialized; + static bool ms_bDisableIMECompletely; + static bool ms_bUILessMode; + static bool ms_bImeEnabled; + static bool ms_bCaptureInput; + static bool ms_bChineseIME; + static bool ms_bUseIMMCandidate; + + static HWND ms_hWnd; + static HKL ms_hklCurrent; + static char ms_szKeyboardLayout[KL_NAMELENGTH+1]; + static OSVERSIONINFOA ms_stOSVI; + + static HINSTANCE ms_hImm32Dll; + static HINSTANCE ms_hCurrentImeDll; + static DWORD ms_dwImeState; + + static DWORD ms_adwId[2]; + + // IME Level + static DWORD ms_dwIMELevel; + static DWORD ms_dwIMELevelSaved; + + // Candidate List + static bool ms_bCandidateList; + static DWORD ms_dwCandidateCount; + static bool ms_bVerticalCandidate; + static int ms_iCandListIndexBase; + static WCHAR ms_wszCandidate[CIME::MAX_CANDLIST][MAX_CANDIDATE_LENGTH]; + static DWORD ms_dwCandidateSelection; + static DWORD ms_dwCandidatePageSize; + + // Reading Information + static bool ms_bReadingInformation; + static int ms_iReadingError; + static bool ms_bHorizontalReading; + static std::vector ms_wstrReading; + + // Indicator + static wchar_t* ms_wszCurrentIndicator; + + static IIMEEventSink* ms_pEvent; + + wchar_t m_wszComposition[IMESTR_MAXLEN]; + static wchar_t m_wText[IMESTR_MAXLEN]; + + static int ms_compLen; + static int ms_curpos; + static int ms_lastpos; + static int ms_ulbegin; + static int ms_ulend; + + static UINT ms_uOutputCodePage; + static UINT ms_uInputCodePage; +}; diff --git a/source/EterLib/Input.cpp b/source/EterLib/Input.cpp new file mode 100644 index 0000000..07decf1 --- /dev/null +++ b/source/EterLib/Input.cpp @@ -0,0 +1,134 @@ +#include "StdAfx.h" +#include "Input.h" + +LPDIRECTINPUT8 CInputDevice::ms_lpDI = NULL; +LPDIRECTINPUTDEVICE8 CInputKeyboard::ms_lpKeyboard = NULL; +bool CInputKeyboard::ms_bPressedKey[256]; +char CInputKeyboard::ms_diks[256]; + +CInputDevice::CInputDevice() +{ +} + +CInputDevice::~CInputDevice() +{ + SAFE_RELEASE(ms_lpDI); +} + +HRESULT CInputDevice::CreateDevice(HWND /*hWnd*/) +{ + if (ms_lpDI) + { + ms_lpDI->AddRef(); + return S_OK; + } + + HRESULT hr; + + // Create a DInput object + if (FAILED(hr = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, + IID_IDirectInput8, (VOID**) &ms_lpDI, NULL))) + return hr; + + return S_OK; +} + + +CInputKeyboard::CInputKeyboard() +{ + ResetKeyboard(); +} + +CInputKeyboard::~CInputKeyboard() +{ + if (ms_lpKeyboard) + ms_lpKeyboard->Unacquire(); + + SAFE_RELEASE(ms_lpKeyboard); +} + +void CInputKeyboard::ResetKeyboard() +{ + memset(ms_diks, 0, sizeof(ms_diks)); + memset(ms_bPressedKey, 0, sizeof(ms_bPressedKey)); +} + +bool CInputKeyboard::InitializeKeyboard(HWND hWnd) +{ + NANOBEGIN + + if (ms_lpKeyboard) + return true; + + if (FAILED(CreateDevice(hWnd))) + return false; + + HRESULT hr; + + // Obtain an interface to the system keyboard device. + if (FAILED(hr = ms_lpDI->CreateDevice(GUID_SysKeyboard, &ms_lpKeyboard, NULL))) + return false; + + if (FAILED(hr = ms_lpKeyboard->SetDataFormat(&c_dfDIKeyboard))) + return false; + +// Alt + F4 - [levites] +// DWORD dwCoopFlags = DISCL_FOREGROUND | DISCL_EXCLUSIVE; +// DWORD dwCoopFlags = DISCL_NONEXCLUSIVE | DISCL_BACKGROUND; + DWORD dwCoopFlags = DISCL_FOREGROUND | DISCL_NONEXCLUSIVE; + + if (FAILED(hr = ms_lpKeyboard->SetCooperativeLevel(hWnd, dwCoopFlags))) + return false; + + ms_lpKeyboard->Acquire(); + + NANOEND + return true; +} + +void CInputKeyboard::UpdateKeyboard() +{ + if (!ms_lpKeyboard) + return; + + HRESULT hr; + + hr = ms_lpKeyboard->GetDeviceState(sizeof(ms_diks), &ms_diks); + + if (FAILED(hr)) + { + hr = ms_lpKeyboard->Acquire(); + + // ø̼ Ȱȭ Ǿ ־ Է . + //if (hr == DIERR_OTHERAPPHASPRIO || hr == DIERR_NOTACQUIRED); + return; + } + + for (int i = 0; i < 256; ++i) + { + if (ms_diks[i] & 0x80) + { + if (!IsPressed(i)) + KeyDown(i); + } + else if (IsPressed(i)) + KeyUp(i); + } +} + +void CInputKeyboard::KeyDown(int iIndex) +{ + ms_bPressedKey[iIndex] = true; + OnKeyDown(iIndex); +} + +void CInputKeyboard::KeyUp(int iIndex) +{ + ms_bPressedKey[iIndex] = false; + OnKeyUp(iIndex); +} + +bool CInputKeyboard::IsPressed(int iIndex) +{ + return ms_bPressedKey[iIndex]; +} diff --git a/source/EterLib/Input.h b/source/EterLib/Input.h new file mode 100644 index 0000000..197d2b7 --- /dev/null +++ b/source/EterLib/Input.h @@ -0,0 +1,41 @@ +#pragma once + +#ifndef SAFE_RELEASE +#define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=NULL; } } +#endif + +class CInputDevice +{ + public: + CInputDevice(); + virtual ~CInputDevice(); + + HRESULT CreateDevice(HWND hWnd); + + protected: + static LPDIRECTINPUT8 ms_lpDI; +}; + +class CInputKeyboard : public CInputDevice +{ + public: + CInputKeyboard(); + virtual ~CInputKeyboard(); + + bool InitializeKeyboard(HWND hWnd); + void UpdateKeyboard(); + void ResetKeyboard(); + + bool IsPressed(int iIndex); + void KeyDown(int iIndex); + void KeyUp(int iIndex); + + protected: + virtual void OnKeyDown(int iIndex) = 0; + virtual void OnKeyUp(int iIndex) = 0; + + protected: + static LPDIRECTINPUTDEVICE8 ms_lpKeyboard; + static bool ms_bPressedKey[256]; + static char ms_diks[256]; +}; \ No newline at end of file diff --git a/source/EterLib/JpegFile.cpp b/source/EterLib/JpegFile.cpp new file mode 100644 index 0000000..ec696a9 --- /dev/null +++ b/source/EterLib/JpegFile.cpp @@ -0,0 +1,312 @@ +#include "StdAfx.h" +#include "JpegFile.h" +#include +#include +#include +#include +#include +#define OUTBUFFER_SIZE 0x8000 +static FILE*fi; +static JOCTET * buffer; +static unsigned char*dest; +static int len; +static int destlen; +static unsigned char*data_d; +static int pos; +static int size_d; +static void file_init_destination(j_compress_ptr cinfo) +{ + struct jpeg_destination_mgr*dmgr = + (struct jpeg_destination_mgr*)(cinfo->dest); + buffer = (JOCTET*)malloc(OUTBUFFER_SIZE); + if(!buffer) { + perror("malloc"); + printf("Out of memory!\n"); + exit(1); + } + dmgr->next_output_byte = buffer; + dmgr->free_in_buffer = OUTBUFFER_SIZE; +} +static unsigned char file_empty_output_buffer(j_compress_ptr cinfo) +{ + struct jpeg_destination_mgr*dmgr = + (struct jpeg_destination_mgr*)(cinfo->dest); + if(fi) + fwrite(buffer, OUTBUFFER_SIZE, 1, fi); + dmgr->next_output_byte = buffer; + dmgr->free_in_buffer = OUTBUFFER_SIZE; + return 1; +} +static void file_term_destination(j_compress_ptr cinfo) +{ struct jpeg_destination_mgr*dmgr = + (struct jpeg_destination_mgr*)(cinfo->dest); + if(fi) + fwrite(buffer, OUTBUFFER_SIZE-dmgr->free_in_buffer, 1, fi); + free(buffer); + buffer = 0; + dmgr->free_in_buffer = 0; +} +static void mem_init_destination(j_compress_ptr cinfo) +{ + struct jpeg_destination_mgr*dmgr = + (struct jpeg_destination_mgr*)(cinfo->dest); + dmgr->next_output_byte = dest; + dmgr->free_in_buffer = destlen; +} +static unsigned char mem_empty_output_buffer(j_compress_ptr cinfo) +{ + printf("jpeg mem overflow!\n"); + exit(1); +} +static void mem_term_destination(j_compress_ptr cinfo) +{ + struct jpeg_destination_mgr*dmgr = + (struct jpeg_destination_mgr*)(cinfo->dest); + len = destlen - dmgr->free_in_buffer; + dmgr->free_in_buffer = 0; +} +int jpeg_save(unsigned char*data_d, int width, int height, int quality, const char*filename) +{ + struct jpeg_destination_mgr mgr; + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + int t; + if(filename) { + fi = fopen(filename, "wb"); + if(fi == NULL) + return 0; + } else + fi = NULL; + memset(&cinfo, 0, sizeof(cinfo)); + memset(&jerr, 0, sizeof(jerr)); + memset(&mgr, 0, sizeof(mgr)); + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_compress(&cinfo); + mgr.init_destination = file_init_destination; + mgr.empty_output_buffer = file_empty_output_buffer; + mgr.term_destination = file_term_destination; + cinfo.dest = &mgr; + // init compression + cinfo.image_width = width; + cinfo.image_height = height; + cinfo.input_components = 3; + cinfo.in_color_space = JCS_RGB; + jpeg_set_defaults(&cinfo); + jpeg_set_quality(&cinfo,quality,TRUE); + //jpeg_write_tables(&cinfo); + //jpeg_suppress_tables(&cinfo, TRUE); + jpeg_start_compress(&cinfo, FALSE); + for(t=0;tsrc; + mgr->next_input_byte = data_d; + mgr->bytes_in_buffer = size_d; + //printf("init %d\n", size - mgr->bytes_in_buffer); +} +unsigned char mem_fill_input_buffer (j_decompress_ptr cinfo) +{ + struct jpeg_source_mgr* mgr = cinfo->src; + printf("fill %d\n", size_d - mgr->bytes_in_buffer); + return 0; +} +void mem_skip_input_data (j_decompress_ptr cinfo, long num_bytes) +{ + struct jpeg_source_mgr* mgr = cinfo->src; + printf("skip %d +%d\n", size_d - mgr->bytes_in_buffer, num_bytes); + if(num_bytes<=0) + return; + mgr->next_input_byte += num_bytes; + mgr->bytes_in_buffer -= num_bytes; +} +unsigned char mem_resync_to_restart (j_decompress_ptr cinfo, int desired) +{ + struct jpeg_source_mgr* mgr = cinfo->src; + printf("resync %d\n", size_d - mgr->bytes_in_buffer); + mgr->next_input_byte = data_d; + mgr->bytes_in_buffer = size_d; + return 1; +} +void mem_term_source (j_decompress_ptr cinfo) +{ + struct jpeg_source_mgr* mgr = cinfo->src; + //printf("term %d\n", size - mgr->bytes_in_buffer); +} +int jpeg_load_from_mem(unsigned char*_data, int _size, unsigned char*dest, int width, int height) +{ + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + struct jpeg_source_mgr mgr; + int y; + //int x; + data_d = _data; + size_d = _size; + jpeg_create_decompress(&cinfo); + mgr.next_input_byte = data_d; + mgr.bytes_in_buffer = size_d; + mgr.init_source =mem_init_source ; + mgr.fill_input_buffer =mem_fill_input_buffer ; + mgr.skip_input_data =mem_skip_input_data ; + mgr.resync_to_restart =mem_resync_to_restart ; + mgr.term_source =mem_term_source ; + cinfo.err = jpeg_std_error(&jerr); + cinfo.src = &mgr; + jpeg_read_header(&cinfo, TRUE); + jpeg_start_decompress(&cinfo); + for(y=0;y= 0; x--) { + line[x].a = 255; + line[x].r = js[x*3+0]; + line[x].g = js[x*3+1]; + line[x].b = js[x*3+2]; + } + } else if (cinfo.out_color_space == JCS_YCCK) { + fprintf(stderr, "Error: Can't convert YCCK to RGB.\n"); + return 0; + } else if (cinfo.out_color_space == JCS_YCbCr) { + for (x = 0; x < width; x++) { + int y = js[x * 3 + 0]; + int u = js[x * 3 + 1]; + int v = js[x * 3 + 1]; + line[x].a = 255; + line[x].r = y + ((360 * (v - 128)) >> 8); + line[x].g = y - ((88 * (u - 128) + 183 * (v - 128)) >> 8); + line[x].b = y + ((455 * (u - 128)) >> 8); + } + } else if (cinfo.out_color_space == JCS_CMYK) { + for (x = 0; x < width; x++) { + int white = 255 - js[x * 4 + 3]; + line[x].a = 255; + line[x].r = white - ((js[x * 4] * white) >> 8); + line[x].g = white - ((js[x * 4 + 1] * white) >> 8); + line[x].b = white - ((js[x * 4 + 2] * white) >> 8); + } + } + } + free(scanline); + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + fclose(fi); + return 1; +} \ No newline at end of file diff --git a/source/EterLib/JpegFile.h b/source/EterLib/JpegFile.h new file mode 100644 index 0000000..fd1176a --- /dev/null +++ b/source/EterLib/JpegFile.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +int jpeg_save(unsigned char*data_d, int width, int height, int quality, const char*filename); +int jpeg_save_to_file(unsigned char*data_d, int width, int height, int quality, FILE*fi); +int jpeg_save_to_mem(unsigned char*data_d, int width, int height, int quality, unsigned char*dest, int destsize); +int jpeg_load(const char*filename, unsigned char**dest, int*width, int*height); +int jpeg_load_from_mem(unsigned char*_data, int size_d, unsigned char*dest, int width, int height); \ No newline at end of file diff --git a/source/EterLib/LensFlare.cpp b/source/EterLib/LensFlare.cpp new file mode 100644 index 0000000..c9e5d0b --- /dev/null +++ b/source/EterLib/LensFlare.cpp @@ -0,0 +1,599 @@ +/////////////////////////////////////////////////////////////////////// +// CLensFlare Class +// +// (c) 2003 IDV, Inc. +// +// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION *** +// +// This software is supplied under the terms of a license agreement or +// nondisclosure agreement with Interactive Data Visualization and may +// not be copied or disclosed except in accordance with the terms of +// that agreement. +// +// Copyright (c) 2001-2003 IDV, Inc. +// All Rights Reserved. +// +// IDV, Inc. +// 1233 Washington St. Suite 610 +// Columbia, SC 29201 +// Voice: (803) 799-1699 +// Fax: (803) 931-0320 +// Web: http://www.idvinc.com +// + + +/////////////////////////////////////////////////////////////////////// +// Preprocessor +#include "StdAfx.h" +#include "LensFlare.h" +#include "Camera.h" +#include "StateManager.h" +#include "ResourceManager.h" + +#include +using namespace std; + +/////////////////////////////////////////////////////////////////////// +// Variables + +static string g_strFiles[] = +{ + "flare2.dds", + "flare1.dds", + "flare2.dds", + "flare1.dds", + "flare6.dds", + "flare4.dds", + "flare2.dds", + "flare3.dds", + "" +}; +static float g_fPosition[] = +{ + -0.55f, + -0.5f, + -0.45f, + 0.2f, + 0.3f, + 0.95f, + 0.9f, + 1.0f +}; +static float g_fWidth[] = +{ + 20.0f, + 32.0f, + 20.0f, + 32.0f, + 100.0f, + 32.0f, + 20.0f, + 250.0f +}; + +static float g_afColors[ ][4] = +{ + { 1.0f, 1.0f, 0.0f, 1.0f }, + { 1.0f, 1.0f, 1.0f, 1.0f }, + { 0.0f, 1.0f, 0.0f, 0.8f }, + { 0.3f, 0.5f, 1.0f, 0.9f }, + { 0.3f, 0.5f, 1.0f, 0.6f }, + { 1.0f, 0.6f, 0.9f, 0.4f }, + { 1.0f, 0.0f, 0.0f, 0.5f }, + { 1.0f, 0.6f, 0.3f, 0.4f } +}; + + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::CLensFlare + +CLensFlare::CLensFlare() : + m_fSunSize(0), + m_fBeforeBright(0.0f), + m_fAfterBright(0.0f), + m_bFlareVisible(false), + m_bDrawFlare(true), + m_bDrawBrightScreen(true), + m_bEnabled(true), + m_bShowMainFlare(true), + m_fMaxBrightness(1.0f) +{ + m_pControlPixels = new float[c_nDepthTestDimension * c_nDepthTestDimension]; + m_pTestPixels = new float[c_nDepthTestDimension * c_nDepthTestDimension]; + m_afColor[0] = m_afColor[1] = m_afColor[2] = 1.0f; +} + + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::~CLensFlare + +CLensFlare::~CLensFlare() +{ + delete[] m_pControlPixels; + delete[] m_pTestPixels; +} + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::Interpolate + +float CLensFlare::Interpolate(float fStart, float fEnd, float fPercent) +{ + return fStart + (fEnd - fStart) * fPercent; +} + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::DrawBeforeFlare + +void CLensFlare::Compute(const D3DXVECTOR3 & c_rv3LightDirection) +{ + float afSunPos[3]; + + D3DXVECTOR3 v3Target = CCameraManager::Instance().GetCurrentCamera()->GetTarget(); + + afSunPos[0] = v3Target.x - c_rv3LightDirection.x * 99999999.0f; + afSunPos[1] = v3Target.y - c_rv3LightDirection.y * 99999999.0f; + afSunPos[2] = v3Target.z - c_rv3LightDirection.z * 99999999.0f; + + float fX, fY; + ProjectPosition(afSunPos[0], afSunPos[1], afSunPos[2], &fX, &fY); + + // set flare location + SetFlareLocation(fX, fY); + + // determine visibility + float fSunVectorMagnitude = sqrtf(afSunPos[0] * afSunPos[0] + + afSunPos[1] * afSunPos[1] + + afSunPos[2] * afSunPos[2]); + float afSunVector[3]; + afSunVector[0] = -afSunPos[0] / fSunVectorMagnitude; + afSunVector[1] = -afSunPos[1] / fSunVectorMagnitude; + afSunVector[2] = -afSunPos[2] / fSunVectorMagnitude; + + float afCameraDirection[3]; + afCameraDirection[0] = ms_matView._13; + afCameraDirection[1] = ms_matView._23; + afCameraDirection[2] = ms_matView._33; + + + float fDotProduct = + (afSunVector[0] * afCameraDirection[0]) + + (afSunVector[1] * afCameraDirection[1]) + + (afSunVector[2] * afCameraDirection[2]); + + if (acosf(fDotProduct) < 0.5f * D3DX_PI) + SetVisible(true); + else + SetVisible(false); + + // set flare brightness + fX /= ms_Viewport.Width; + fY /= ms_Viewport.Height; + + float fDistance = sqrtf(((0.5f - fX) * (0.5f - fX)) + ((0.5f - fY) * (0.5f - fY))); + float fBeforeBright = Interpolate(0.0f, c_fHalfMaxBright, 1.0f - (fDistance * c_fDistanceScale)); + float fAfterBright = Interpolate(0.0f, 1.0f, 1.0f - (fDistance * c_fDistanceScale)); + + SetBrightnesses(fBeforeBright, fAfterBright); +} + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::DrawBeforeFlare + +void CLensFlare::DrawBeforeFlare() +{ + if (!m_bFlareVisible || !m_bEnabled || !m_bShowMainFlare) + return; + + if (m_SunFlareImageInstance.IsEmpty()) + return; + + D3DXMATRIX matProj; + D3DXMatrixOrthoOffCenterRH(&matProj, 0.0f, 1.0f, 1.0f, 0.0f, -1.0f, 1.0f); + STATEMANAGER.SaveTransform(D3DTS_PROJECTION, &matProj); + STATEMANAGER.SaveTransform(D3DTS_VIEW, &ms_matIdentity); + + D3DXMATRIX matWorld; + D3DXMatrixTranslation(&matWorld, m_afFlarePos[0], m_afFlarePos[1], 0.0f); + STATEMANAGER.SetTransform(D3DTS_WORLD, &matWorld); + + STATEMANAGER.SaveRenderState(D3DRS_LIGHTING, FALSE); + STATEMANAGER.SaveRenderState(D3DRS_ZENABLE, FALSE); // glDisable(GL_DEPTH_TEST); + STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, FALSE); + STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE); // glDisable(GL_CULL_FACE); + STATEMANAGER.SaveRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); // glShadeModel(GL_FLAT); + STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, FALSE); // glDisable(GL_ALPHA_TEST); + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE); // glEnable(GL_BLEND); + STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + /* + if (m_fBeforeBright != 0.0f && m_bDrawFlare && m_bDrawBrightScreen && false) // false? + { + glColor4f(1.0f, 1.0f, 1.0f, m_fBeforeBright); + glDisable(GL_TEXTURE_2D); + glBegin(GL_TRIANGLE_STRIP); + glVertex2f(0.0f, 0.0f); + glVertex2f(0.0f, 1.0f); + glVertex2f(1.0f, 0.0f); + glVertex2f(1.0f, 1.0f); + glEnd(); + } + */ + float fAspectRatio = ms_Viewport.Width / float(ms_Viewport.Height); + float fHeight = m_fSunSize * fAspectRatio; + D3DXCOLOR color(1.0f, 1.0f, 1.0f, 1.0f); + + SVertex vertices[4]; + vertices[0].x = -m_fSunSize; + vertices[0].y = -fHeight; + vertices[0].z = 0.0f; + vertices[0].color = color; + vertices[0].u = 0.0f; + vertices[0].v = 0.0f; + + vertices[1].x = -m_fSunSize; + vertices[1].y = fHeight; + vertices[1].z = 0.0f; + vertices[1].color = color; + vertices[1].u = 0.0f; + vertices[1].v = 1.0f; + + vertices[2].x = m_fSunSize; + vertices[2].y = -fHeight; + vertices[2].z = 0.0f; + vertices[2].color = color; + vertices[2].u = 1.0f; + vertices[2].v = 0.0f; + + vertices[3].x = m_fSunSize; + vertices[3].y = fHeight; + vertices[3].z = 0.0f; + vertices[3].color = color; + vertices[3].u = 1.0f; + vertices[3].v = 1.0f; + + STATEMANAGER.SetTexture(0, m_SunFlareImageInstance.GetTexturePointer()->GetD3DTexture()); + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + + STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, vertices, sizeof(SVertex)); + + STATEMANAGER.RestoreRenderState(D3DRS_LIGHTING); + STATEMANAGER.RestoreRenderState(D3DRS_ZENABLE); // glDisable(GL_DEPTH_TEST); + STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE); // glDisable(GL_CULL_FACE); + STATEMANAGER.RestoreRenderState(D3DRS_SHADEMODE); // glShadeModel(GL_FLAT); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE); // glDisable(GL_ALPHA_TEST); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); // glEnable(GL_BLEND); + STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND); + STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND); + + STATEMANAGER.RestoreTransform(D3DTS_VIEW); + STATEMANAGER.RestoreTransform(D3DTS_PROJECTION); +} + + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::DrawAfterFlare + +void CLensFlare::DrawAfterFlare() +{ + if (m_bEnabled && m_fAfterBright != 0.0f && m_bDrawBrightScreen) + { + SetDiffuseColor(m_afColor[0], m_afColor[1], m_afColor[2], m_fAfterBright); + RenderBar2d(0.0f, 0.0f, 1024.0f, 1024.0f); + } +} + + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::SetMainFlare + +void CLensFlare::SetMainFlare(string strSunFile, float fSunSize) +{ + if (m_bEnabled && m_bShowMainFlare) + { + m_fSunSize = fSunSize; + CResource * pResource = CResourceManager::Instance().GetResourcePointer(strSunFile.c_str()); + + if (!pResource->IsType(CGraphicImage::Type())) + assert(false); + + m_SunFlareImageInstance.SetImagePointer(static_cast (pResource)); + } +} + + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::DrawFlare + +void CLensFlare::DrawFlare() +{ + if (m_bEnabled && m_bFlareVisible && m_bDrawFlare && m_fAfterBright != 0.0f) + { + //glPushAttrib(GL_ENABLE_BIT); + STATEMANAGER.SaveRenderState(D3DRS_LIGHTING, FALSE); // glDisable(GL_LIGHTING); + STATEMANAGER.SaveRenderState(D3DRS_ZENABLE, FALSE); // glDisable(GL_DEPTH_TEST); + STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE); // glDisable(GL_CULL_FACE); + STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, FALSE); // glDisable(GL_ALPHA_TEST); + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE); // glEnable(GL_BLEND); + + D3DXMATRIX matProj; + D3DXMatrixOrthoOffCenterRH(&matProj, 0.0f, ms_Viewport.Width, ms_Viewport.Height, 0.0f, -1.0f, 1.0f); + STATEMANAGER.SaveTransform(D3DTS_PROJECTION, &matProj); + STATEMANAGER.SaveTransform(D3DTS_VIEW, &ms_matIdentity); + + STATEMANAGER.SetTransform(D3DTS_WORLD, &ms_matIdentity); + //glMatrixMode(GL_MODELVIEW); + //glLoadIdentity(); + + //glDisable(GL_TEXTURE_2D); + DrawAfterFlare(); + + //glEnable(GL_TEXTURE_2D); + m_cFlare.Draw(m_fAfterBright, + ms_Viewport.Width, + ms_Viewport.Height, + static_cast(m_afFlareWinPos[0]), + static_cast(m_afFlareWinPos[1])); + + STATEMANAGER.RestoreRenderState(D3DRS_LIGHTING); // glDisable(GL_LIGHTING); + STATEMANAGER.RestoreRenderState(D3DRS_ZENABLE); // glDisable(GL_DEPTH_TEST); + STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE); // glDisable(GL_CULL_FACE); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); // glEnable(GL_BLEND); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE); // glDisable(GL_ALPHA_TEST); + + STATEMANAGER.RestoreTransform(D3DTS_PROJECTION); + STATEMANAGER.RestoreTransform(D3DTS_VIEW); + //glDisable(GL_TEXTURE_2D); + //glPopAttrib(); + } +} + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::CharacterizeFlare +void CLensFlare::CharacterizeFlare(bool bEnabled, bool bShowMainFlare, float fMaxBrightness, const D3DXCOLOR & c_rColor) +{ + m_bEnabled = bEnabled; + m_bShowMainFlare = bShowMainFlare; + m_fMaxBrightness = fMaxBrightness; + + m_afColor[0] = c_rColor.r; + m_afColor[1] = c_rColor.g; + m_afColor[2] = c_rColor.b; +} + + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::Initialize +void CLensFlare::Initialize(std::string strPath) +{ + if (m_bEnabled) + m_cFlare.Init(strPath); +} + + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::SetFlareLocation +void CLensFlare::SetFlareLocation(double dX, double dY) +{ + if (m_bEnabled) + { + m_afFlareWinPos[0] = float(dX); + m_afFlareWinPos[1] = float(dY); + + m_afFlarePos[0] = float(dX) / ms_Viewport.Width; + m_afFlarePos[1] = float(dY) / ms_Viewport.Height; + } +} + + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::SetBrightnesses + +void CLensFlare::SetBrightnesses(float fBeforeBright, float fAfterBright) +{ + if (m_bEnabled) + { + m_fBeforeBright = fBeforeBright; + m_fAfterBright = fAfterBright; + + ClampBrightness(); + } +} + + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::ReadControlPixels + +void CLensFlare::ReadControlPixels() +{ + if (m_bEnabled) + ReadDepthPixels(m_pControlPixels); +} + + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::AdjustBrightness + +void CLensFlare::AdjustBrightness() +{ + if (m_bEnabled) + { + ReadDepthPixels(m_pTestPixels); + + int nDifferent = 0; + + for (int i = 0; i < c_nDepthTestDimension * c_nDepthTestDimension; ++i) + if (m_pTestPixels[i] != m_pControlPixels[i]) + ++nDifferent; + + float fAdjust = (static_cast(nDifferent) / (c_nDepthTestDimension * c_nDepthTestDimension)); + fAdjust = sqrtf(fAdjust) * 0.85f; + m_fAfterBright *= 1.0f - fAdjust; + } +} + + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::ReadDepthPixels + +void CLensFlare::ReadDepthPixels(float * /*pPixels*/) +{ + /* + LPDIRECT3DSURFACE8 lpSurface; + if (FAILED(ms_lpd3dDevice->GetDepthStencilSurface(&lpSurface))) + assert(false); + + D3DLOCKED_RECT rect; + lpSurface->LockRect(&rect, NULL, D3DLOCK_READONLY | D3DLOCK_NO_DIRTY_UPDATE); + + lpSurface->UnlockRect(); + */ + /* + glReadPixels(GLint(m_afFlareWinPos[0] - c_nDepthTestDimension / 2), + GLint(m_afFlareWinPos[1] - c_nDepthTestDimension / 2), + c_nDepthTestDimension, c_nDepthTestDimension, + GL_DEPTH_COMPONENT, GL_FLOAT, pPixels); + */ +} + +/////////////////////////////////////////////////////////////////////// +// CLensFlare::ClampBrightness + +void CLensFlare::ClampBrightness() +{ + // before + if (m_fBeforeBright < 0.0f) + m_fBeforeBright = 0.0f; + else if (m_fBeforeBright > 1.0f) + m_fBeforeBright = 1.0f; + + m_fBeforeBright *= m_fMaxBrightness; + + if (m_fAfterBright < 0.0f) + m_fAfterBright = 0.0f; + else if (m_fAfterBright > 1.0f) + m_fAfterBright = 1.0f; + + m_fAfterBright *= m_fMaxBrightness; +} + +/////////////////////////////////////////////////////////////////////// +// CFlare implementation +/////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////// +// CFlare::CFlare + +CFlare::CFlare() +{ +} + + +/////////////////////////////////////////////////////////////////////// +// CFlare::~CFlare + +CFlare::~CFlare() +{ +} + + +/////////////////////////////////////////////////////////////////////// +// CFlare::Init + +void CFlare::Init(std::string strPath) +{ + int i = 0; + + while (g_strFiles[i] != "") + { + CResource * pResource = CResourceManager::Instance().GetResourcePointer((strPath + "/" + string(g_strFiles[i])).c_str()); + + if (!pResource->IsType(CGraphicImage::Type())) + assert(false); + + SFlarePiece * pPiece = new SFlarePiece; + + pPiece->m_imageInstance.SetImagePointer(static_cast (pResource)); + pPiece->m_fPosition = g_fPosition[i]; + pPiece->m_fWidth = g_fWidth[i]; + pPiece->m_pColor = g_afColors[i]; + + m_vFlares.push_back(pPiece); + i++; + } +} + + +/////////////////////////////////////////////////////////////////////// +// CFlare::Draw +void CFlare::Draw(float fBrightScale, int nWidth, int nHeight, int nX, int nY) +{ + STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); + + float fDX = float(nX) - float(nWidth) / 2.0f; + float fDY = float(nY) - float(nHeight) / 2.0f; + + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + + for (unsigned int i = 0; i < m_vFlares.size(); i++) + { + float fCenterX = float(nX) - (m_vFlares[i]->m_fPosition + 1.0f) * fDX; + float fCenterY = float(nY) - (m_vFlares[i]->m_fPosition + 1.0f) * fDY; + float fW = m_vFlares[i]->m_fWidth; + + D3DXCOLOR d3dColor(m_vFlares[i]->m_pColor[0] * fBrightScale, + m_vFlares[i]->m_pColor[1] * fBrightScale, + m_vFlares[i]->m_pColor[2] * fBrightScale, + m_vFlares[i]->m_pColor[3] * fBrightScale); + + STATEMANAGER.SetTexture(0, m_vFlares[i]->m_imageInstance.GetTexturePointer()->GetD3DTexture()); + + TVertex vertices[4]; + + vertices[0].u = 0.0f; + vertices[0].v = 0.0f; + vertices[0].x = fCenterX - fW; + vertices[0].y = fCenterY - fW; + vertices[0].z = 0.0f; + vertices[0].color = d3dColor; + + vertices[1].u = 0.0f; + vertices[1].v = 1.0f; + vertices[1].x = fCenterX - fW; + vertices[1].y = fCenterY + fW; + vertices[1].z = 0.0f; + vertices[1].color = d3dColor; + + vertices[2].u = 1.0f; + vertices[2].v = 0.0f; + vertices[2].x = fCenterX + fW; + vertices[2].y = fCenterY - fW; + vertices[2].z = 0.0f; + vertices[2].color = d3dColor; + + vertices[3].u = 1.0f; + vertices[3].v = 1.0f; + vertices[3].x = fCenterX + fW; + vertices[3].y = fCenterY + fW; + vertices[3].z = 0.0f; + vertices[3].color = d3dColor; + + STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, vertices, sizeof(TVertex)); + } + + STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND); +} diff --git a/source/EterLib/LensFlare.h b/source/EterLib/LensFlare.h new file mode 100644 index 0000000..7522cbf --- /dev/null +++ b/source/EterLib/LensFlare.h @@ -0,0 +1,125 @@ +/////////////////////////////////////////////////////////////////////// +// CLensFlare Class +// +// (c) 2003 IDV, Inc. +// +// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION *** +// +// This software is supplied under the terms of a license agreement or +// nondisclosure agreement with Interactive Data Visualization and may +// not be copied or disclosed except in accordance with the terms of +// that agreement. +// +// Copyright (c) 2001-2003 IDV, Inc. +// All Rights Reserved. +// +// IDV, Inc. +// 1233 Washington St. Suite 610 +// Columbia, SC 29201 +// Voice: (803) 799-1699 +// Fax: (803) 931-0320 +// Web: http://www.idvinc.com +// + + +/////////////////////////////////////////////////////////////////////// +// Preprocessor + +#pragma once + +#include "GrpImageInstance.h" +#include "GrpScreen.h" + +#include +#include +#include + + +/////////////////////////////////////////////////////////////////////// +// Constants + +const float c_fHalfMaxBright = 0.45f; +const float c_fDistanceScale = 1.0f; +const int c_nDepthTestDimension = 15; + + +/////////////////////////////////////////////////////////////////////// +// CFlare + +class CFlare +{ +public: + void Draw(float fBrightScale, int nWidth, int nHeight, int nX, int nY); + void Init(std::string strPath); + + CFlare(); + virtual ~CFlare(); + +private: + struct SFlarePiece + { + SFlarePiece() : + m_fPosition(0.0f), + m_fWidth(0.0f), + m_pColor(NULL) + { + } + CGraphicImageInstance m_imageInstance; + float m_fPosition; // -1.0 = light location, 0.0 = center, 1.0 = far end of flare + float m_fWidth; // height = width + float * m_pColor; + }; + + std::vector m_vFlares; +}; + +/////////////////////////////////////////////////////////////////////// +// CLensFlare +class CLensFlare : public CScreen +{ +public: + CLensFlare(); + virtual ~CLensFlare(); + + void Compute(const D3DXVECTOR3 & c_rv3LightDirection); // D3DTS_VIEW ī޶ Ƿ, ī޶ ڿ ؾ . + + void DrawBeforeFlare(); + void DrawAfterFlare(); + void DrawFlare(); + + void SetMainFlare(std::string strSunFile, float fSunSize); + void Initialize(std::string strPath); + + void SetFlareLocation(double dX, double dY); + + void SetVisible(bool bState) { m_bFlareVisible = bState; } + bool IsVisible() { return m_bFlareVisible; } + + void SetBrightnesses(float fBeforeBright, float fAfterBright); + + void ReadControlPixels(); + void AdjustBrightness(); + + void CharacterizeFlare(bool bEnabled, bool bShowMainFlare, float fMaxBrightness, const D3DXCOLOR & c_rColor); + +protected: + float Interpolate(float fStart, float fEnd, float fPercent); + +private: + float m_afFlarePos[2], m_afFlareWinPos[2]; + float m_fBeforeBright, m_fAfterBright; + bool m_bFlareVisible, m_bDrawFlare, m_bDrawBrightScreen; + float m_fSunSize; + CFlare m_cFlare; + float * m_pControlPixels; + float * m_pTestPixels; + bool m_bEnabled; + bool m_bShowMainFlare; + float m_fMaxBrightness; + float m_afColor[4]; + + CGraphicImageInstance m_SunFlareImageInstance; + + void ReadDepthPixels(float * pPixels); + void ClampBrightness(); +}; diff --git a/source/EterLib/MSApplication.cpp b/source/EterLib/MSApplication.cpp new file mode 100644 index 0000000..81e5fb4 --- /dev/null +++ b/source/EterLib/MSApplication.cpp @@ -0,0 +1,56 @@ +#include "StdAfx.h" +#include "MsApplication.h" + +CMSApplication::CMSApplication() +{ +} + +CMSApplication::~CMSApplication() +{ +// for (TWindowClassSet::iterator i=ms_stWCSet.begin(); i!=ms_stWCSet.end(); ++i) +// UnregisterClass(*i, ms_hInstance); +} + +void CMSApplication::Initialize(HINSTANCE hInstance) +{ + ms_hInstance = hInstance; +} + +void CMSApplication::MessageLoop() +{ + while (MessageProcess()); +} + +bool CMSApplication::IsMessage() +{ + MSG msg; + + if (!PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) + return false; + + return true; +} + +bool CMSApplication::MessageProcess() +{ + MSG msg; + + if (!GetMessage(&msg, NULL, 0, 0)) + return false; + + TranslateMessage(&msg); + DispatchMessage(&msg); + return true; +} + +LRESULT CMSApplication::WindowProcedure(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uiMsg) + { + case WM_CLOSE: + PostQuitMessage(0); + break; + } + + return CMSWindow::WindowProcedure(hWnd, uiMsg, wParam, lParam); +} \ No newline at end of file diff --git a/source/EterLib/MSApplication.h b/source/EterLib/MSApplication.h new file mode 100644 index 0000000..874cd8e --- /dev/null +++ b/source/EterLib/MSApplication.h @@ -0,0 +1,22 @@ +#pragma once + +#include "MSWindow.h" + +class CMSApplication : public CMSWindow +{ + public: + CMSApplication(); + virtual ~CMSApplication(); + + void Initialize(HINSTANCE hInstance); + + void MessageLoop(); + + bool IsMessage(); + bool MessageProcess(); + + protected: + void ClearWindowClass(); + + LRESULT WindowProcedure(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam); +}; diff --git a/source/EterLib/MSWindow.cpp b/source/EterLib/MSWindow.cpp new file mode 100644 index 0000000..c93e202 --- /dev/null +++ b/source/EterLib/MSWindow.cpp @@ -0,0 +1,249 @@ +#include "StdAfx.h" +#include "MsWindow.h" + +#include + +CMSWindow::TWindowClassSet CMSWindow::ms_stWCSet; +HINSTANCE CMSWindow::ms_hInstance = NULL; + +LRESULT CALLBACK MSWindowProcedure(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam) +{ + CMSWindow * pWnd = (CMSWindow *) GetWindowLong(hWnd, GWL_USERDATA); + + if (pWnd) + return pWnd->WindowProcedure(hWnd, uiMsg, wParam, lParam); + + return DefWindowProc(hWnd, uiMsg, wParam, lParam); +} + +LRESULT CMSWindow::WindowProcedure(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uiMsg) + { + case WM_SIZE: + OnSize(wParam, lParam); + break; + + case WM_ACTIVATEAPP: + m_isActive = (wParam == WA_ACTIVE) || (wParam == WA_CLICKACTIVE); + break; + } + + return DefWindowProc(hWnd, uiMsg, wParam, lParam); +} + +void CMSWindow::OnSize(WPARAM wParam, LPARAM /*lParam*/) +{ + if (wParam == SIZE_MINIMIZED) + { + InvalidateRect(m_hWnd, NULL, true); + m_isActive = false; + m_isVisible = false; + } + else + { + m_isActive = true; + m_isVisible = true; + } +} + +void CMSWindow::Destroy() +{ + if (!m_hWnd) + return; + + if (IsWindow(m_hWnd)) + DestroyWindow(m_hWnd); + + m_hWnd = NULL; + m_isVisible = false; +} + +bool CMSWindow::Create(const char* c_szName, int brush, DWORD cs, DWORD ws, HICON hIcon, int iCursorResource) +{ + //assert(ms_hInstance != NULL); + Destroy(); + + const char* c_szClassName = RegisterWindowClass(cs, brush, MSWindowProcedure, hIcon, iCursorResource); + + m_hWnd = CreateWindow( + c_szClassName, + c_szName, + ws, + 0, 0, 0, 0, + NULL, + NULL, + ms_hInstance, + NULL); + + if (!m_hWnd) + return false; + + SetWindowLong(m_hWnd, GWL_USERDATA, (DWORD) this); + //DestroyWindow(ImmGetDefaultIMEWnd(m_hWnd)); + + return true; +} + +void CMSWindow::SetVisibleMode(bool isVisible) +{ + m_isVisible = isVisible; + + if (m_isVisible) + { + ShowWindow(m_hWnd, SW_SHOW); + } + else + { + ShowWindow(m_hWnd, SW_HIDE); + } +} + +void CMSWindow::Show() +{ + m_isVisible = true; + ShowWindow(m_hWnd, SW_SHOW); +} + +void CMSWindow::Hide() +{ + m_isVisible = false; + ShowWindow(m_hWnd, SW_HIDE); +} + +bool CMSWindow::IsVisible() +{ + return m_isVisible; +} + +bool CMSWindow::IsActive() +{ + return m_isActive; +} + +HINSTANCE CMSWindow::GetInstance() +{ + return ms_hInstance; +} + +HWND CMSWindow::GetWindowHandle() +{ + return m_hWnd; +} + +int CMSWindow::GetScreenWidth() +{ + return GetSystemMetrics(SM_CXSCREEN); +} + +int CMSWindow::GetScreenHeight() +{ + return GetSystemMetrics(SM_CYSCREEN); +} + +void CMSWindow::GetWindowRect(RECT* prc) +{ + ::GetWindowRect(m_hWnd, prc); +} + + +void CMSWindow::GetClientRect(RECT* prc) +{ + ::GetClientRect(m_hWnd, prc); +} + +void CMSWindow::GetMousePosition(POINT* ppt) +{ + GetCursorPos(ppt); + ScreenToClient(m_hWnd, ppt); +} + +void CMSWindow::SetPosition(int x, int y) +{ + SetWindowPos(m_hWnd, NULL, x, y, 0, 0, SWP_NOZORDER|SWP_NOSIZE); +} + +void CMSWindow::SetCenterPosition() +{ + RECT rc; + + GetClientRect(&rc); + + int windowWidth = rc.right - rc.left; + int windowHeight = rc.bottom - rc.top; + + SetPosition((GetScreenWidth()-windowWidth)/2, (GetScreenHeight()-windowHeight)/2); +} + +void CMSWindow::AdjustSize(int width, int height) +{ + SetRect(&m_rect, 0, 0, width, height); + + AdjustWindowRectEx(&m_rect, + GetWindowStyle(m_hWnd), + GetMenu(m_hWnd ) != NULL, + GetWindowExStyle(m_hWnd ) ); + + MoveWindow + ( + m_hWnd, + 0, + 0, + m_rect.right - m_rect.left, + m_rect.bottom - m_rect.top, + FALSE + ); +} + +void CMSWindow::SetText(const char* c_szText) +{ + SetWindowText(m_hWnd, c_szText); +} + +void CMSWindow::SetSize(int width, int height) +{ + SetWindowPos(m_hWnd, NULL, 0, 0, width, height, SWP_NOZORDER|SWP_NOMOVE); +} + +const char * CMSWindow::RegisterWindowClass(DWORD style, int brush, WNDPROC pfnWndProc, HICON hIcon, int iCursorResource) +{ + char szClassName[1024]; + sprintf(szClassName, "eter - s%x:b%x:p:%x", style, brush, (DWORD) pfnWndProc); + + TWindowClassSet::iterator f = ms_stWCSet.find((char*) szClassName); + + if (f != ms_stWCSet.end()) + return *f; + + const char* c_szStaticClassName = stl_static_string(szClassName).c_str(); + + ms_stWCSet.insert((char * const) c_szStaticClassName); + + WNDCLASS wc; + + wc.style = 0; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.lpfnWndProc = pfnWndProc; + wc.hCursor = LoadCursor(ms_hInstance, MAKEINTRESOURCE(iCursorResource)); + wc.hIcon = hIcon ? hIcon : LoadIcon(ms_hInstance, IDI_APPLICATION); + wc.hbrBackground = (HBRUSH) GetStockObject(brush); + wc.hInstance = ms_hInstance; + wc.lpszClassName = c_szStaticClassName; + wc.lpszMenuName = ""; + + if (!RegisterClass(&wc)) + return ""; + + return c_szStaticClassName; +} + +CMSWindow::CMSWindow() +{ + m_hWnd=NULL; + m_isVisible=false; +} + +CMSWindow::~CMSWindow() +{ +} \ No newline at end of file diff --git a/source/EterLib/MSWindow.h b/source/EterLib/MSWindow.h new file mode 100644 index 0000000..9298af2 --- /dev/null +++ b/source/EterLib/MSWindow.h @@ -0,0 +1,59 @@ +#pragma once + +#include "../eterBase/Stl.h" + +class CMSWindow +{ + public: + CMSWindow(); + + virtual ~CMSWindow(); + + void Destroy(); + bool Create(const char* c_szName, int brush=BLACK_BRUSH, DWORD cs=0, DWORD ws=WS_OVERLAPPEDWINDOW, HICON hIcon=NULL, int iCursorResource=32512); + + void Show(); + void Hide(); + + void SetVisibleMode(bool isVisible); + + void SetPosition(int x, int y); + void SetCenterPosition(); + + void SetText(const char* c_szText); + + void AdjustSize(int width, int height); + void SetSize(int width, int height); + + bool IsVisible(); + bool IsActive(); + + void GetMousePosition(POINT* ppt); + void GetClientRect(RECT* prc); + void GetWindowRect(RECT* prc); + + int GetScreenWidth(); + int GetScreenHeight(); + + HWND GetWindowHandle(); + HINSTANCE GetInstance(); + + virtual LRESULT WindowProcedure(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam); + virtual void OnSize(WPARAM wParam, LPARAM lParam); + + protected: + const char* RegisterWindowClass(DWORD style, int brush, WNDPROC pfnWndProc, HICON hIcon=NULL, int iCursorResource=32512); + + protected: + typedef std::set TWindowClassSet; + + protected: + HWND m_hWnd; + RECT m_rect; + bool m_isActive; + bool m_isVisible; + + protected: + static TWindowClassSet ms_stWCSet; + static HINSTANCE ms_hInstance; +}; diff --git a/source/EterLib/Mutex.cpp b/source/EterLib/Mutex.cpp new file mode 100644 index 0000000..3ba3741 --- /dev/null +++ b/source/EterLib/Mutex.cpp @@ -0,0 +1,22 @@ +#include "StdAfx.h" +#include "Mutex.h" + +Mutex::Mutex() +{ + InitializeCriticalSection(&lock); +} + +Mutex::~Mutex() +{ + DeleteCriticalSection(&lock); +} + +void Mutex::Lock() +{ + EnterCriticalSection(&lock); +} + +void Mutex::Unlock() +{ + LeaveCriticalSection(&lock); +} \ No newline at end of file diff --git a/source/EterLib/Mutex.h b/source/EterLib/Mutex.h new file mode 100644 index 0000000..169fdf5 --- /dev/null +++ b/source/EterLib/Mutex.h @@ -0,0 +1,18 @@ +#ifndef __INC_ETERLIB_MUTEX_H__ +#define __INC_ETERLIB_MUTEX_H__ + +class Mutex +{ + public: + Mutex(); + ~Mutex(); + + void Lock(); + void Unlock(); + bool Trylock(); + + private: + CRITICAL_SECTION lock; +}; + +#endif diff --git a/source/EterLib/NetAddress.cpp b/source/EterLib/NetAddress.cpp new file mode 100644 index 0000000..b657090 --- /dev/null +++ b/source/EterLib/NetAddress.cpp @@ -0,0 +1,107 @@ +#include "StdAfx.h" +#include "NetAddress.h" + +#ifndef VC_EXTRALEAN + +bool CNetworkAddress::GetHostName(char* szName, int size) +{ + if (gethostname(szName, size)==SOCKET_ERROR) + return false; + return true; +} + +CNetworkAddress::CNetworkAddress() +{ + Clear(); +} + +CNetworkAddress::~CNetworkAddress() +{ +} + +CNetworkAddress::operator const SOCKADDR_IN&() const +{ + return m_sockAddrIn; +} + +void CNetworkAddress::Clear() +{ + memset(&m_sockAddrIn, 0, sizeof(m_sockAddrIn)); + m_sockAddrIn.sin_family=AF_INET; +} + +bool CNetworkAddress::IsIP(const char* c_szAddr) +{ + if (c_szAddr[0]<'0' || c_szAddr[0]>'9') + return false; + return true; +} + +bool CNetworkAddress::Set(const char* c_szAddr, int port) +{ + if (IsIP(c_szAddr)) + { + SetIP(c_szAddr); + } + else + { + if (!SetDNS(c_szAddr)) + return false; + } + + SetPort(port); + return true; +} + +void CNetworkAddress::SetLocalIP() +{ + SetIP(INADDR_ANY); +} + +void CNetworkAddress::SetIP(DWORD ip) +{ + m_sockAddrIn.sin_addr.s_addr=htonl(ip); +} + +void CNetworkAddress::SetIP(const char* c_szIP) +{ + m_sockAddrIn.sin_addr.s_addr=inet_addr(c_szIP); +} + +bool CNetworkAddress::SetDNS(const char* c_szDNS) +{ + HOSTENT* pHostent=gethostbyname(c_szDNS); + if (!pHostent) return false; + memcpy(&m_sockAddrIn.sin_addr, pHostent->h_addr, sizeof(m_sockAddrIn.sin_addr)); + return true; +} + +void CNetworkAddress::SetPort(int port) +{ + m_sockAddrIn.sin_port = htons(port); +} + +int CNetworkAddress::GetSize() +{ + return sizeof(m_sockAddrIn); +} + +DWORD CNetworkAddress::GetIP() +{ + return ntohl(m_sockAddrIn.sin_addr.s_addr); +} + +void CNetworkAddress::GetIP(char* szIP, int len) +{ + BYTE IPs[4]; + *((DWORD*)IPs)=m_sockAddrIn.sin_addr.s_addr; + + _snprintf(szIP, len, "%d.%d.%d.%d", IPs[0], IPs[1], IPs[2], IPs[3]); +} + +int CNetworkAddress::GetPort() +{ + return ntohs(m_sockAddrIn.sin_port); +} + +#endif \ No newline at end of file diff --git a/source/EterLib/NetAddress.h b/source/EterLib/NetAddress.h new file mode 100644 index 0000000..643b0a7 --- /dev/null +++ b/source/EterLib/NetAddress.h @@ -0,0 +1,42 @@ +#pragma once + +#ifndef VC_EXTRALEAN + +class CNetworkAddress +{ + public: + static bool GetHostName(char* szName, int size); + + public: + CNetworkAddress(); + ~CNetworkAddress(); + + void Clear(); + + bool Set(const char* c_szAddr, int port); + + void SetLocalIP(); + void SetIP(DWORD ip); + void SetIP(const char* c_szIP); + bool SetDNS(const char* c_szDNS); + + void SetPort(int port); + + int GetPort(); + int GetSize(); + + void GetIP(char* szIP, int len); + + DWORD GetIP(); + + operator const SOCKADDR_IN&() const; + + + private: + bool IsIP(const char* c_szAddr); + + private: + SOCKADDR_IN m_sockAddrIn; +}; + +#endif \ No newline at end of file diff --git a/source/EterLib/NetDatagram.cpp b/source/EterLib/NetDatagram.cpp new file mode 100644 index 0000000..2020d98 --- /dev/null +++ b/source/EterLib/NetDatagram.cpp @@ -0,0 +1,99 @@ +#include "StdAfx.h" +#include "NetDatagram.h" + +CNetworkDatagram::CNetworkDatagram() +{ + __Initialize(); +} + +CNetworkDatagram::~CNetworkDatagram() +{ + Destroy(); +} + +void CNetworkDatagram::Destroy() +{ + if (INVALID_SOCKET==m_sock) + return; + + closesocket(m_sock); + + __Initialize(); +} + +bool CNetworkDatagram::Create(UINT uPort) +{ + assert(INVALID_SOCKET==m_sock); + m_sock = socket(AF_INET, SOCK_DGRAM, 0); + + DWORD arg = 1; + ioctlsocket(m_sock, FIONBIO, &arg); // Non-blocking mode + + SOCKADDR_IN sockAddrIn; + memset(&sockAddrIn, 0, sizeof(SOCKADDR_IN)); + sockAddrIn.sin_family = AF_INET; + sockAddrIn.sin_addr.s_addr = INADDR_ANY; + sockAddrIn.sin_port = htons(uPort); + + if (SOCKET_ERROR == bind(m_sock, (PSOCKADDR)&sockAddrIn, sizeof(SOCKADDR_IN))) + { + return false; + } + + return true; +} + +#pragma warning(push) +#pragma warning(disable:4127) +void CNetworkDatagram::Update() +{ + if (m_sock == INVALID_SOCKET) + return; + + FD_ZERO(&m_fdsRecv); + FD_ZERO(&m_fdsSend); + + FD_SET(m_sock, &m_fdsRecv); + FD_SET(m_sock, &m_fdsSend); + + TIMEVAL delay; + + delay.tv_sec = 0; + delay.tv_usec = 0; + + if (select(0, &m_fdsRecv, &m_fdsSend, NULL, &delay) == SOCKET_ERROR) + return; +} +#pragma warning(pop) + +bool CNetworkDatagram::CanRecv() +{ + if (FD_ISSET(m_sock, &m_fdsRecv)) + return true; + + return false; +} + + +int CNetworkDatagram::PeekRecvFrom(UINT uBufLen, void* pvBuf, SOCKADDR_IN* pkSockAddrIn) +{ + int nSockAddrInLen=sizeof(SOCKADDR_IN); + return recvfrom(m_sock, (char*)pvBuf, uBufLen, MSG_PEEK, (PSOCKADDR)pkSockAddrIn, &nSockAddrInLen); +} + +int CNetworkDatagram::RecvFrom(UINT uBufLen, void* pvBuf, SOCKADDR_IN* pkSockAddrIn) +{ + int nSockAddrInLen=sizeof(SOCKADDR_IN); + return recvfrom(m_sock, (char*)pvBuf, uBufLen, 0, (PSOCKADDR)pkSockAddrIn, &nSockAddrInLen); +} + +int CNetworkDatagram::SendTo(UINT uBufLen, const void* c_pvBuf, const SOCKADDR_IN& c_rkSockAddrIn) +{ + return sendto(m_sock, (const char *)c_pvBuf, uBufLen, 0, (PSOCKADDR)&c_rkSockAddrIn, sizeof(SOCKADDR_IN)); +} + + +void CNetworkDatagram::__Initialize() +{ + m_sock=INVALID_SOCKET; +} \ No newline at end of file diff --git a/source/EterLib/NetDatagram.h b/source/EterLib/NetDatagram.h new file mode 100644 index 0000000..7a0b4ee --- /dev/null +++ b/source/EterLib/NetDatagram.h @@ -0,0 +1,28 @@ +#pragma once + +class CNetworkDatagram +{ + public: + CNetworkDatagram(); + virtual ~CNetworkDatagram(); + + void Destroy(); + bool Create(UINT uPort); + + void Update(); + + bool CanRecv(); + + int PeekRecvFrom(UINT uBufLen, void* pvBuf, SOCKADDR_IN* pkSockAddrIn); + int RecvFrom(UINT uBufLen, void* pvBuf, SOCKADDR_IN* pkSockAddrIn); + int SendTo(UINT uBufLen, const void* c_pvBuf, const SOCKADDR_IN& c_rkSockAddrIn); + + private: + void __Initialize(); + + private: + SOCKET m_sock; + + fd_set m_fdsRecv; + fd_set m_fdsSend; +}; \ No newline at end of file diff --git a/source/EterLib/NetDatagramReceiver.cpp b/source/EterLib/NetDatagramReceiver.cpp new file mode 100644 index 0000000..144faca --- /dev/null +++ b/source/EterLib/NetDatagramReceiver.cpp @@ -0,0 +1,105 @@ +#include "StdAfx.h" +#include "NetDatagramReceiver.h" + +BOOL CNetDatagramReceiver::Process() +{ + m_recvBufCurrentPos = 0; + m_recvBufCurrentSize = 0; + + int irecvAddrLength = sizeof(SOCKADDR_IN); + m_recvBufCurrentSize = recvfrom(m_Socket, (char *)m_recvBuf, m_recvBufSize, 0, (PSOCKADDR)&m_SockAddr, &irecvAddrLength); + + if (m_recvBufCurrentSize <= 0) + { + return FALSE; + } + + return TRUE; +} + +BOOL CNetDatagramReceiver::Recv(void * pBuffer, int iSize) +{ + if (!Peek(pBuffer, iSize)) + return FALSE; + + m_recvBufCurrentPos += iSize; + return TRUE; +} + +BOOL CNetDatagramReceiver::Peek(void * pBuffer, int iSize) +{ + if (m_recvBufCurrentSize < m_recvBufCurrentPos+iSize) + return FALSE; + + memcpy(pBuffer, m_recvBuf + m_recvBufCurrentPos, iSize); + return TRUE; +} + +BOOL CNetDatagramReceiver::isBind() +{ + return m_isBind; +} + +BOOL CNetDatagramReceiver::Bind(DWORD /*dwAddress*/, WORD wPortIndex) +{ + m_Socket = socket(AF_INET, SOCK_DGRAM, 0); + + DWORD arg = 1; + ioctlsocket(m_Socket, FIONBIO, &arg); // Non-blocking mode + + memset(&m_SockAddr, 0, sizeof(SOCKADDR_IN)); + m_SockAddr.sin_family = AF_INET; +// m_SockAddr.sin_addr.s_addr = dwAddress; + m_SockAddr.sin_addr.s_addr = INADDR_ANY; + m_SockAddr.sin_port = htons(wPortIndex); + + if (bind(m_Socket, (PSOCKADDR)&m_SockAddr, sizeof(SOCKADDR_IN)) < 0) + { + Tracef("Failed binding socket\n"); + return FALSE; + } + + m_isBind = TRUE; + + return TRUE; +} + +void CNetDatagramReceiver::SetRecvBufferSize(int recvBufSize) +{ + if (m_recvBuf) + { + if (m_recvBufSize>recvBufSize) + return; + + delete [] m_recvBuf; + } + m_recvBufSize=recvBufSize; + m_recvBuf=new char[m_recvBufSize]; +} + +void CNetDatagramReceiver::Clear() +{ + + m_isBind = FALSE; + + m_dwPortIndex = 1000; + + m_Socket = 0; + memset(&m_SockAddr, 0, sizeof(SOCKADDR_IN)); + + m_recvBufCurrentPos = 0; + m_recvBufCurrentSize = 0; +} + +CNetDatagramReceiver::CNetDatagramReceiver() +{ + m_recvBuf = NULL; + m_recvBufSize = 0; + + Clear(); +} +CNetDatagramReceiver::~CNetDatagramReceiver() +{ + if (m_recvBuf) + delete [] m_recvBuf; +} \ No newline at end of file diff --git a/source/EterLib/NetDatagramReceiver.h b/source/EterLib/NetDatagramReceiver.h new file mode 100644 index 0000000..d8615e5 --- /dev/null +++ b/source/EterLib/NetDatagramReceiver.h @@ -0,0 +1,36 @@ +#pragma once + +#ifndef VC_EXTRALEAN + +class CNetDatagramReceiver +{ + public: + CNetDatagramReceiver(); + virtual ~CNetDatagramReceiver(); + + void Clear(); + BOOL Bind(DWORD dwAddress, WORD wPortIndex); + BOOL isBind(); + + BOOL Process(); + BOOL Recv(void * pBuffer, int iSize); + BOOL Peek(void * pBuffer, int iSize); + + void SetRecvBufferSize(int recvBufSize); + + protected: + BOOL m_isBind; + + DWORD m_dwPortIndex; + + SOCKET m_Socket; + SOCKADDR_IN m_SockAddr; + + int m_recvBufCurrentPos; + int m_recvBufCurrentSize; + + char* m_recvBuf; + int m_recvBufSize; +}; + +#endif \ No newline at end of file diff --git a/source/EterLib/NetDatagramSender.cpp b/source/EterLib/NetDatagramSender.cpp new file mode 100644 index 0000000..72497ee --- /dev/null +++ b/source/EterLib/NetDatagramSender.cpp @@ -0,0 +1,58 @@ +#include "StdAfx.h" +#include "NetDatagramSender.h" + +BOOL CNetDatagramSender::SetSocket(const char * c_szIP, WORD wPortIndex) +{ + return SetSocket(inet_addr(c_szIP), wPortIndex); +} + +BOOL CNetDatagramSender::SetSocket(DWORD dwAddress, WORD wPortIndex) +{ + m_isSocket = TRUE; + + m_dwAddress = dwAddress; + m_wPortIndex = wPortIndex; + + m_Socket = socket(AF_INET, SOCK_DGRAM, 0); + + memset(&m_SockAddr, 0, sizeof(SOCKADDR_IN)); + m_SockAddr.sin_family = AF_INET; + m_SockAddr.sin_addr.s_addr = dwAddress; + m_SockAddr.sin_port = htons(wPortIndex); + + return TRUE; +} + +BOOL CNetDatagramSender::Send(const void * pBuffer, int iSize) +{ + assert(isSocket()); + + int iSendingLength = sendto(m_Socket, (const char *)pBuffer, iSize, 0, (PSOCKADDR)&m_SockAddr, sizeof(SOCKADDR_IN)); + if (iSendingLength < 0) + { + Tracef("Failed sending packet\n"); + return FALSE; + } + + return TRUE; +} + +BOOL CNetDatagramSender::isSocket() +{ + return m_isSocket; +} + +CNetDatagramSender::CNetDatagramSender() +{ + m_isSocket = FALSE; + + m_dwAddress = 0; + m_wPortIndex = 1000; + + m_Socket = 0; + memset(&m_SockAddr, 0, sizeof(SOCKADDR_IN)); +} + +CNetDatagramSender::~CNetDatagramSender() +{ +} \ No newline at end of file diff --git a/source/EterLib/NetDatagramSender.h b/source/EterLib/NetDatagramSender.h new file mode 100644 index 0000000..8fb96f0 --- /dev/null +++ b/source/EterLib/NetDatagramSender.h @@ -0,0 +1,27 @@ +#pragma once + +#ifndef VC_EXTRALEAN + +class CNetDatagramSender +{ + public: + CNetDatagramSender(); + virtual ~CNetDatagramSender(); + + BOOL isSocket(); + + BOOL SetSocket(const char * c_szIP, WORD wPortIndex); + BOOL SetSocket(DWORD dwAddress, WORD wPortIndex); + BOOL Send(const void * pBuffer, int iSize); + + protected: + BOOL m_isSocket; + + WORD m_dwAddress; + WORD m_wPortIndex; + + SOCKET m_Socket; + SOCKADDR_IN m_SockAddr; +}; + +#endif diff --git a/source/EterLib/NetDevice.cpp b/source/EterLib/NetDevice.cpp new file mode 100644 index 0000000..555a216 --- /dev/null +++ b/source/EterLib/NetDevice.cpp @@ -0,0 +1,41 @@ +#include "StdAfx.h" +#include "NetDevice.h" + +CNetworkDevice::CNetworkDevice() +{ + Initialize(); +} + +CNetworkDevice::~CNetworkDevice() +{ + Destroy(); +} + +void CNetworkDevice::Initialize() +{ + m_isWSA=false; +} + +void CNetworkDevice::Destroy() +{ + if (m_isWSA) + { + WSACleanup(); + m_isWSA=false; + } +} + +bool CNetworkDevice::Create() +{ + Destroy(); + + Initialize(); + + WSADATA wsaData; + if (WSAStartup(MAKEWORD(1, 1), &wsaData)!=0) + return false; + + m_isWSA=true; + + return true; +} \ No newline at end of file diff --git a/source/EterLib/NetDevice.h b/source/EterLib/NetDevice.h new file mode 100644 index 0000000..d05a985 --- /dev/null +++ b/source/EterLib/NetDevice.h @@ -0,0 +1,17 @@ +#pragma once + +class CNetworkDevice +{ + public: + CNetworkDevice(); + virtual ~CNetworkDevice(); + + void Destroy(); + bool Create(); + + protected: + void Initialize(); + + protected: + bool m_isWSA; +}; diff --git a/source/EterLib/NetPacketHeaderMap.cpp b/source/EterLib/NetPacketHeaderMap.cpp new file mode 100644 index 0000000..fd37193 --- /dev/null +++ b/source/EterLib/NetPacketHeaderMap.cpp @@ -0,0 +1,26 @@ +#include "StdAfx.h" +#include "NetPacketHeaderMap.h" + +void CNetworkPacketHeaderMap::Set(int header, TPacketType rPacketType) +{ + m_headerMap[header] = rPacketType; +} +bool CNetworkPacketHeaderMap::Get(int header, TPacketType * pPacketType) +{ + std::map::iterator f=m_headerMap.find(header); + + if (m_headerMap.end()==f) + return false; + + *pPacketType = f->second; + + return true; +} + +CNetworkPacketHeaderMap::CNetworkPacketHeaderMap() +{ +} + +CNetworkPacketHeaderMap::~CNetworkPacketHeaderMap() +{ +} diff --git a/source/EterLib/NetPacketHeaderMap.h b/source/EterLib/NetPacketHeaderMap.h new file mode 100644 index 0000000..6da0ec1 --- /dev/null +++ b/source/EterLib/NetPacketHeaderMap.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +class CNetworkPacketHeaderMap +{ + public: + typedef struct SPacketType + { + SPacketType(int iSize = 0, bool bFlag = false) + { + iPacketSize = iSize; + isDynamicSizePacket = bFlag; + } + + int iPacketSize; + bool isDynamicSizePacket; + } TPacketType; + + public: + CNetworkPacketHeaderMap(); + virtual ~CNetworkPacketHeaderMap(); + + void Set(int header, TPacketType rPacketType); + bool Get(int header, TPacketType * pPacketType); + + protected: + std::map m_headerMap; +}; diff --git a/source/EterLib/NetStream.cpp b/source/EterLib/NetStream.cpp new file mode 100644 index 0000000..1936343 --- /dev/null +++ b/source/EterLib/NetStream.cpp @@ -0,0 +1,3011 @@ +#include "StdAfx.h" +#include "NetStream.h" +//#include "eterCrypt.h" + +#ifndef _IMPROVED_PACKET_ENCRYPTION_ +#include "../eterBase/tea.h" +#endif + +//#define _PACKETDUMP + +#ifndef _IMPROVED_PACKET_ENCRYPTION_ +void CNetworkStream::SetSecurityMode(bool isSecurityMode, const char* c_szTeaKey) +{ + m_isSecurityMode = isSecurityMode; + memcpy(m_szEncryptKey, c_szTeaKey, TEA_KEY_LENGTH); + memcpy(m_szDecryptKey, c_szTeaKey, TEA_KEY_LENGTH); +} + +void CNetworkStream::SetSecurityMode(bool isSecurityMode, const char* c_szTeaEncryptKey, const char* c_szTeaDecryptKey) +{ + m_isSecurityMode = isSecurityMode; + memcpy(m_szEncryptKey, c_szTeaEncryptKey, TEA_KEY_LENGTH); + memcpy(m_szDecryptKey, c_szTeaDecryptKey, TEA_KEY_LENGTH); +} +#endif // _IMPROVED_PACKET_ENCRYPTION_ +#define SEQUENCE_TABLE_SIZE 32768 + +bool CNetworkStream::IsSecurityMode() +{ +#ifdef _IMPROVED_PACKET_ENCRYPTION_ + return m_cipher.activated(); +#else + return m_isSecurityMode; +#endif +} + +void CNetworkStream::SetRecvBufferSize(int recvBufSize) +{ + if (m_recvBuf) + { + if (m_recvBufSize>recvBufSize) + return; + + delete [] m_recvBuf; + + if (m_recvTEABuf) + delete [] m_recvTEABuf; + } + m_recvBufSize = recvBufSize; + m_recvBuf = new char[m_recvBufSize]; + m_recvTEABufSize = ((m_recvBufSize>>3)+1)<<3; + m_recvTEABuf = new char[m_recvTEABufSize]; +} + +void CNetworkStream::SetSendBufferSize(int sendBufSize) +{ + if (m_sendBuf) + { + if (m_sendBufSize > sendBufSize) + return; + + delete [] m_sendBuf; + + if (m_sendTEABuf) + delete [] m_sendTEABuf; + } + + m_sendBufSize = sendBufSize; + m_sendBuf = new char[m_sendBufSize]; + m_sendTEABufSize = ((m_sendBufSize>>3)+1)<<3; + m_sendTEABuf = new char[m_sendTEABufSize]; +} + +bool CNetworkStream::__RecvInternalBuffer() +{ + if (m_recvBufOutputPos>0) + { + int recvBufDataSize = m_recvBufInputPos - m_recvBufOutputPos; + if (recvBufDataSize>0) + { + memmove(m_recvBuf, m_recvBuf + m_recvBufOutputPos, recvBufDataSize); + } + + m_recvBufInputPos -= m_recvBufOutputPos; + m_recvBufOutputPos = 0; + } + +#ifdef _IMPROVED_PACKET_ENCRYPTION_ + int restSize = m_recvBufSize - m_recvBufInputPos; + if (restSize>0) + { + int recvSize = recv(m_sock, m_recvBuf + m_recvBufInputPos, m_recvBufSize - m_recvBufInputPos, 0); + //Tracenf("RECV %d %d(%d, %d)", recvSize, restSize, m_recvTEABufSize - m_recvTEABufInputPos, m_recvBufSize - m_recvBufInputPos); + + if (recvSize < 0) + { + int error = WSAGetLastError(); + + if (error != WSAEWOULDBLOCK) + { + return false; + } + } + else if (recvSize == 0) + { + return false; + } + + if (IsSecurityMode()) { + m_cipher.Decrypt(m_recvBuf + m_recvBufInputPos, recvSize); + } + + m_recvBufInputPos += recvSize; + } +#else + if (IsSecurityMode()) + { + int restSize = min(m_recvTEABufSize - m_recvTEABufInputPos, m_recvBufSize - m_recvBufInputPos); + + if (restSize > 0) + { + int recvSize = recv(m_sock, m_recvTEABuf + m_recvTEABufInputPos, restSize, 0); + //Tracenf("RECV %d %d(%d, %d)", recvSize, restSize, m_recvTEABufSize - m_recvTEABufInputPos, m_recvBufSize - m_recvBufInputPos); + + if (recvSize < 0) + { + int error = WSAGetLastError(); + + if (error != WSAEWOULDBLOCK) + { + return false; + } + } + else if (recvSize == 0) + { + return false; + } + + m_recvTEABufInputPos += recvSize; + + int decodeSize = m_recvTEABufInputPos; + + if (decodeSize >= 8) + { + decodeSize >>= 3; + decodeSize <<= 3; + + /*int decodeDstSize = tea_decrypt((DWORD *) (m_recvBuf + m_recvBufInputPos), + (DWORD *) m_recvTEABuf, + (const DWORD *) m_szDecryptKey, + decodeSize); + */ + int decodeDstSize = tea_decrypt((DWORD *) (m_recvBuf + m_recvBufInputPos), + (DWORD *) m_recvTEABuf, + (const DWORD *) m_szDecryptKey, + decodeSize); + + m_recvBufInputPos += decodeDstSize; + + if (m_recvTEABufInputPos>decodeSize) + memmove(m_recvTEABuf, m_recvTEABuf+decodeSize, m_recvTEABufInputPos-decodeSize); + + m_recvTEABufInputPos -= decodeSize; + + + //Tracenf("!!!!!! decrypt decodeSrcSize %d -> decodeDstSize %d (recvOutputPos %d, recvInputPos %d, teaInputPos %d)", + // decodeSize, decodeDstSize, m_recvBufOutputPos, m_recvBufInputPos, m_recvTEABufInputPos); + } + } + } + else + { + int restSize = m_recvBufSize - m_recvBufInputPos; + if (restSize>0) + { + int recvSize = recv(m_sock, m_recvBuf + m_recvBufInputPos, m_recvBufSize - m_recvBufInputPos, 0); + //Tracenf("RECV %d %d(%d, %d)", recvSize, restSize, m_recvTEABufSize - m_recvTEABufInputPos, m_recvBufSize - m_recvBufInputPos); + + if (recvSize < 0) + { + int error = WSAGetLastError(); + + if (error != WSAEWOULDBLOCK) + { + return false; + } + } + else if (recvSize == 0) + { + return false; + } + + m_recvBufInputPos += recvSize; + } + } +#endif // _IMPROVED_PACKET_ENCRYPTION_ + + //Tracef("recvSize: %d input pos %d output pos %d\n", recvSize, m_recvBufInputPos, m_recvBufOutputPos); + + return true; +} + + +bool CNetworkStream::__SendInternalBuffer() +{ +#ifdef _IMPROVED_PACKET_ENCRYPTION_ + int dataSize=__GetSendBufferSize(); + if (dataSize<=0) + return true; + + if (IsSecurityMode()) { + m_cipher.Encrypt(m_sendBuf + m_sendBufOutputPos, dataSize); + } + + int sendSize = send(m_sock, m_sendBuf+m_sendBufOutputPos, dataSize, 0); + if (sendSize < 0) + return false; + + m_sendBufOutputPos+=sendSize; + + __PopSendBuffer(); +#else + if (IsSecurityMode()) + { + int encodeSize=__GetSendBufferSize(); + if (encodeSize<=0) + return true; + + m_sendTEABufInputPos += tea_encrypt((DWORD *) (m_sendTEABuf + m_sendTEABufInputPos), + (DWORD *) (m_sendBuf + m_sendBufOutputPos), + (const DWORD *) m_szEncryptKey, + encodeSize); + m_sendBufOutputPos += encodeSize; + + if (m_sendTEABufInputPos>0) + { + int sendSize = send(m_sock, m_sendTEABuf, m_sendTEABufInputPos, 0); + if (sendSize < 0) + return false; + + if (m_sendTEABufInputPos>sendSize) + memmove(m_sendTEABuf, m_sendTEABuf+sendSize, m_sendTEABufInputPos-sendSize); + + m_sendTEABufInputPos-=sendSize; + } + + __PopSendBuffer(); + } + else + { + int dataSize=__GetSendBufferSize(); + if (dataSize<=0) + return true; + + int sendSize = send(m_sock, m_sendBuf+m_sendBufOutputPos, dataSize, 0); + if (sendSize < 0) + return false; + + m_sendBufOutputPos+=sendSize; + + __PopSendBuffer(); + } +#endif // _IMPROVED_PACKET_ENCRYPTION_ + + return true; +} + +void CNetworkStream::__PopSendBuffer() +{ + if (m_sendBufOutputPos<=0) + return; + + int sendBufDataSize = m_sendBufInputPos - m_sendBufOutputPos; + + if (sendBufDataSize>0) + { + memmove(m_sendBuf, m_sendBuf+m_sendBufOutputPos, sendBufDataSize); + } + + m_sendBufInputPos = sendBufDataSize; + m_sendBufOutputPos = 0; +} + +#pragma warning(push) +#pragma warning(disable:4127) +void CNetworkStream::Process() +{ + if (m_sock == INVALID_SOCKET) + return; + + fd_set fdsRecv; + fd_set fdsSend; + + FD_ZERO(&fdsRecv); + FD_ZERO(&fdsSend); + + FD_SET(m_sock, &fdsRecv); + FD_SET(m_sock, &fdsSend); + + TIMEVAL delay; + + delay.tv_sec = 0; + delay.tv_usec = 0; + + if (select(0, &fdsRecv, &fdsSend, NULL, &delay) == SOCKET_ERROR) + return; + + if (!m_isOnline) + { + if (FD_ISSET(m_sock, &fdsSend)) + { + m_isOnline = true; + OnConnectSuccess(); + } + else if (time(NULL) > m_connectLimitTime) + { + Clear(); + OnConnectFailure(); + } + + return; + } + + if (FD_ISSET(m_sock, &fdsSend) && (m_sendBufInputPos > m_sendBufOutputPos)) + { + if (!__SendInternalBuffer()) + { + int error = WSAGetLastError(); + + if (error != WSAEWOULDBLOCK) + { + OnRemoteDisconnect(); + Clear(); + return; + } + } + } + + if (FD_ISSET(m_sock, &fdsRecv)) + { + if (!__RecvInternalBuffer()) + { + OnRemoteDisconnect(); + Clear(); + return; + } + } + + if (!OnProcess()) + { + OnRemoteDisconnect(); + Clear(); + } +} +#pragma warning(pop) + +void CNetworkStream::Disconnect() +{ + if (m_sock == INVALID_SOCKET) + return; + + //OnDisconnect(); + + Clear(); +} + +void CNetworkStream::Clear() +{ + if (m_sock == INVALID_SOCKET) + return; + +#ifdef _IMPROVED_PACKET_ENCRYPTION_ + m_cipher.CleanUp(); +#endif + + closesocket(m_sock); + m_sock = INVALID_SOCKET; + +#ifndef _IMPROVED_PACKET_ENCRYPTION_ + memset(m_szEncryptKey, 0, sizeof(m_szEncryptKey)); + memset(m_szDecryptKey, 0, sizeof(m_szDecryptKey)); + + m_isSecurityMode = false; +#endif + + m_isOnline = false; + m_connectLimitTime = 0; + + m_recvTEABufInputPos = 0; + m_sendTEABufInputPos = 0; + + m_recvBufInputPos = 0; + m_recvBufOutputPos = 0; + + m_sendBufInputPos = 0; + m_sendBufOutputPos = 0; + + m_iSequence = 0; +} + +bool CNetworkStream::Connect(const CNetworkAddress& c_rkNetAddr, int limitSec) +{ + Clear(); + + m_addr = c_rkNetAddr; + + m_sock = socket(AF_INET, SOCK_STREAM, 0); + + if (m_sock == INVALID_SOCKET) + { + Clear(); + OnConnectFailure(); + return false; + } + + DWORD arg = 1; + ioctlsocket(m_sock, FIONBIO, &arg); // Non-blocking mode + + if (connect(m_sock, (PSOCKADDR)&m_addr, m_addr.GetSize()) == SOCKET_ERROR) + { + int error = WSAGetLastError(); + + if (error != WSAEWOULDBLOCK) + { + Tracen("error != WSAEWOULDBLOCK"); + Clear(); + OnConnectFailure(); + return false; + } + } + + m_connectLimitTime = time(NULL) + limitSec; + return true; +} + +bool CNetworkStream::Connect(DWORD dwAddr, int port, int limitSec) +{ + char szAddr[256]; + { + BYTE ip[4]; + ip[0]=dwAddr&0xff;dwAddr>>=8; + ip[1]=dwAddr&0xff;dwAddr>>=8; + ip[2]=dwAddr&0xff;dwAddr>>=8; + ip[3]=dwAddr&0xff;dwAddr>>=8; + + sprintf(szAddr, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); + } + + return Connect(szAddr, port, limitSec); +} + +bool CNetworkStream::Connect(const char* c_szAddr, int port, int /*limitSec*/) +{ + CNetworkAddress kNetAddr; + kNetAddr.Set(c_szAddr, port); + + return Connect(kNetAddr); +} + +void CNetworkStream::ClearRecvBuffer() +{ + m_recvBufOutputPos = m_recvBufInputPos = 0; +} + +int CNetworkStream::GetRecvBufferSize() +{ + return m_recvBufInputPos - m_recvBufOutputPos; +} + +bool CNetworkStream::Peek(int size) +{ + if (GetRecvBufferSize() < size) + return false; + + return true; +} + +bool CNetworkStream::Peek(int size, char * pDestBuf) +{ + if (GetRecvBufferSize() < size) + return false; + + memcpy(pDestBuf, m_recvBuf + m_recvBufOutputPos, size); + return true; +} + + +#ifdef _PACKETDUMP +const char * GetSendHeaderName(BYTE header) +{ + static bool b = false; + static std::string stringList[UCHAR_MAX+1]; + if (b==false) + { + for (DWORD i = 0; i < UCHAR_MAX+1; i++) + { + char buf[10]; + sprintf(buf,"%d",i); + stringList[i] = buf; + } + stringList[1] = "HEADER_CG_LOGIN"; + stringList[2] = "HEADER_CG_ATTACK"; + stringList[3] = "HEADER_CG_CHAT"; + stringList[4] = "HEADER_CG_PLAYER_CREATE"; + stringList[5] = "HEADER_CG_PLAYER_DESTROY"; + stringList[6] = "HEADER_CG_PLAYER_SELECT"; + stringList[7] = "HEADER_CG_CHARACTER_MOVE"; + stringList[8] = "HEADER_CG_SYNC_POSITION"; + stringList[9] = "HEADER_CG_DIRECT_ENTER"; + stringList[10] = "HEADER_CG_ENTERGAME"; + stringList[11] = "HEADER_CG_ITEM_USE"; + stringList[12] = "HEADER_CG_ITEM_DROP"; + stringList[13] = "HEADER_CG_ITEM_MOVE"; + stringList[15] = "HEADER_CG_ITEM_PICKUP"; + stringList[16] = "HEADER_CG_QUICKSLOT_ADD"; + stringList[17] = "HEADER_CG_QUICKSLOT_DEL"; + stringList[18] = "HEADER_CG_QUICKSLOT_SWAP"; + stringList[19] = "HEADER_CG_WHISPER"; + stringList[20] = "HEADER_CG_ITEM_DROP2"; + stringList[26] = "HEADER_CG_ON_CLICK"; + stringList[27] = "HEADER_CG_EXCHANGE"; + stringList[28] = "HEADER_CG_CHARACTER_POSITION"; + stringList[29] = "HEADER_CG_SCRIPT_ANSWER"; + stringList[30] = "HEADER_CG_QUEST_INPUT_STRING"; + stringList[31] = "HEADER_CG_QUEST_CONFIRM"; + stringList[41] = "HEADER_CG_PVP"; + stringList[50] = "HEADER_CG_SHOP"; + stringList[51] = "HEADER_CG_FLY_TARGETING"; + stringList[52] = "HEADER_CG_USE_SKILL"; + stringList[53] = "HEADER_CG_ADD_FLY_TARGETING"; + stringList[54] = "HEADER_CG_SHOOT"; + stringList[55] = "HEADER_CG_MYSHOP"; + stringList[60] = "HEADER_CG_ITEM_USE_TO_ITEM"; + stringList[61] = "HEADER_CG_TARGET"; + stringList[65] = "HEADER_CG_WARP"; + stringList[66] = "HEADER_CG_SCRIPT_BUTTON"; + stringList[67] = "HEADER_CG_MESSENGER"; + stringList[69] = "HEADER_CG_MALL_CHECKOUT"; + stringList[70] = "HEADER_CG_SAFEBOX_CHECKIN"; + stringList[71] = "HEADER_CG_SAFEBOX_CHECKOUT"; + stringList[72] = "HEADER_CG_PARTY_INVITE"; + stringList[73] = "HEADER_CG_PARTY_INVITE_ANSWER"; + stringList[74] = "HEADER_CG_PARTY_REMOVE"; + stringList[75] = "HEADER_CG_PARTY_SET_STATE"; + stringList[76] = "HEADER_CG_PARTY_USE_SKILL"; + stringList[77] = "HEADER_CG_SAFEBOX_ITEM_MOVE"; + stringList[78] = "HEADER_CG_PARTY_PARAMETER"; + stringList[80] = "HEADER_CG_GUILD"; + stringList[81] = "HEADER_CG_ANSWER_MAKE_GUILD"; + stringList[82] = "HEADER_CG_FISHING"; + stringList[83] = "HEADER_CG_GIVE_ITEM"; + stringList[90] = "HEADER_CG_EMPIRE"; + stringList[96] = "HEADER_CG_REFINE"; + stringList[100] = "HEADER_CG_MARK_LOGIN"; + stringList[101] = "HEADER_CG_MARK_CRCLIST"; + stringList[102] = "HEADER_CG_MARK_UPLOAD"; + stringList[103] = "HEADER_CG_CRC_REPORT"; + stringList[105] = "HEADER_CG_HACK"; + stringList[106] = "HEADER_CG_CHANGE_NAME"; + stringList[107] = "HEADER_CG_SMS"; + stringList[108] = "HEADER_CG_MATRIX_CARD"; + stringList[109] = "HEADER_CG_LOGIN2"; + stringList[110] = "HEADER_CG_DUNGEON"; + stringList[111] = "HEADER_CG_LOGIN3"; + stringList[112] = "HEADER_CG_GUILD_SYMBOL_UPLOAD"; + stringList[113] = "HEADER_CG_GUILD_SYMBOL_CRC"; + stringList[114] = "HEADER_CG_SCRIPT_SELECT_ITEM"; +#ifdef _IMPROVED_PACKET_ENCRYPTION_ + stringList[0xfb] = "HEADER_CG_KEY_AGREEMENT"; +#endif + stringList[0xfc] = "HEADER_CG_TIME_SYNC"; + stringList[0xfd] = "HEADER_CG_CLIENT_VERSION"; + stringList[0xfe] = "HEADER_CG_PONG"; + stringList[0xff] = "HEADER_CG_HANDSHAKE"; + } + return stringList[header].c_str(); +} + +const char * GetRecvHeaderName(BYTE header) +{ + static bool b = false; + static std::string stringList[UCHAR_MAX+1]; + if (b==false) + { + for (DWORD i = 0; i < UCHAR_MAX+1; i++) + { + char buf[10]; + sprintf(buf,"%d",i); + stringList[i] = buf; + } + stringList[1] = "HEADER_GC_CHARACTER_ADD"; + stringList[2] = "HEADER_GC_CHARACTER_DEL"; + stringList[3] = "HEADER_GC_CHARACTER_MOVE"; + stringList[4] = "HEADER_GC_CHAT"; + stringList[5] = "HEADER_GC_SYNC_POSITION"; + stringList[6] = "HEADER_GC_LOGIN_SUCCESS"; + stringList[7] = "HEADER_GC_LOGIN_FAILURE"; + stringList[8] = "HEADER_GC_PLAYER_CREATE_SUCCESS"; + stringList[9] = "HEADER_GC_PLAYER_CREATE_FAILURE"; + stringList[10] = "HEADER_GC_PLAYER_DELETE_SUCCESS"; + stringList[11] = "HEADER_GC_PLAYER_DELETE_WRONG_SOCIAL_ID"; + + stringList[13] = "HEADER_GC_STUN"; + stringList[14] = "HEADER_GC_DEAD"; + stringList[15] = "HEADER_GC_MAIN_CHARACTER"; + stringList[16] = "HEADER_GC_PLAYER_POINTS"; + stringList[17] = "HEADER_GC_PLAYER_POINT_CHANGE"; + stringList[18] = "HEADER_GC_CHANGE_SPEED"; + stringList[19] = "HEADER_GC_CHARACTER_UPDATE"; + stringList[20] = "HEADER_GC_ITEM_SET"; + stringList[22] = "HEADER_GC_ITEM_USE"; + stringList[23] = "HEADER_GC_ITEM_DROP"; + stringList[25] = "HEADER_GC_ITEM_UPDATE"; + stringList[26] = "HEADER_GC_ITEM_GROUND_ADD"; + stringList[27] = "HEADER_GC_ITEM_GROUND_DEL"; + stringList[28] = "HEADER_GC_QUICKSLOT_ADD"; + stringList[29] = "HEADER_GC_QUICKSLOT_DEL"; + stringList[30] = "HEADER_GC_QUICKSLOT_SWAP"; + stringList[31] = "HEADER_GC_ITEM_OWNERSHIP"; + stringList[33] = "HEADER_GC_ITEM_UNBIND_TIME"; + stringList[34] = "HEADER_GC_WHISPER "; + stringList[35] = "HEADER_GC_ALERT"; + stringList[36] = "HEADER_GC_MOTION"; + stringList[38] = "HEADER_GC_SHOP"; + stringList[39] = "HEADER_GC_SHOP_SIGN"; + stringList[41] = "HEADER_GC_PVP"; + stringList[42] = "HEADER_GC_EXCHANGE"; + stringList[43] = "HEADER_GC_CHARACTER_POSITION"; + stringList[44] = "HEADER_GC_PING"; + stringList[45] = "HEADER_GC_SCRIPT"; + stringList[46] = "HEADER_GC_QUEST_CONFIRM"; + + stringList[61] = "HEADER_GC_MOUNT"; + stringList[62] = "HEADER_GC_OWNERSHIP"; + stringList[63] = "HEADER_GC_TARGET"; + stringList[65] = "HEADER_GC_WARP"; + stringList[69] = "HEADER_GC_ADD_FLY_TARGETING"; + + stringList[70] = "HEADER_GC_CREATE_FLY"; + stringList[71] = "HEADER_GC_FLY_TARGETING"; + stringList[72] = "HEADER_GC_SKILL_LEVEL"; + stringList[73] = "HEADER_GC_SKILL_COOLTIME_END"; + stringList[74] = "HEADER_GC_MESSENGER"; + stringList[75] = "HEADER_GC_GUILD"; + stringList[76] = "HEADER_GC_SKILL_LEVEL_NEW"; + stringList[77] = "HEADER_GC_PARTY_INVITE"; + stringList[78] = "HEADER_GC_PARTY_ADD"; + stringList[79] = "HEADER_GC_PARTY_UPDATE"; + stringList[80] = "HEADER_GC_PARTY_REMOVE"; + stringList[81] = "HEADER_GC_QUEST_INFO"; + stringList[82] = "HEADER_GC_REQUEST_MAKE_GUILD"; + stringList[83] = "HEADER_GC_PARTY_PARAMETER"; + stringList[84] = "HEADER_GC_SAFEBOX_MONEY_CHANGE"; + stringList[85] = "HEADER_GC_SAFEBOX_SET"; + stringList[86] = "HEADER_GC_SAFEBOX_DEL"; + stringList[87] = "HEADER_GC_SAFEBOX_WRONG_PASSWORD"; + stringList[88] = "HEADER_GC_SAFEBOX_SIZE"; + stringList[89] = "HEADER_GC_FISHING"; + stringList[90] = "HEADER_GC_EMPIRE"; + stringList[91] = "HEADER_GC_PARTY_LINK"; + stringList[92] = "HEADER_GC_PARTY_UNLINK"; + + stringList[95] = "HEADER_GC_REFINE_INFORMATION"; + stringList[96] = "HEADER_GC_OBSERVER_ADD"; + stringList[97] = "HEADER_GC_OBSERVER_REMOVE"; + stringList[98] = "HEADER_GC_OBSERVER_MOVE"; + stringList[99] = "HEADER_GC_VIEW_EQUIP"; + stringList[100] = "HEADER_GC_MARK_BLOCK"; + stringList[101] = "HEADER_GC_MARK_DIFF_DATA"; + + stringList[106] = "HEADER_GC_TIME"; + stringList[107] = "HEADER_GC_CHANGE_NAME"; + stringList[110] = "HEADER_GC_DUNGEON"; + stringList[111] = "HEADER_GC_WALK_MODE"; + stringList[112] = "HEADER_GC_CHANGE_SKILL_GROUP"; + stringList[113] = "HEADER_GC_MAIN_CHARACTER_NEW"; + stringList[114] = "HEADER_GC_USE_POTION"; + stringList[115] = "HEADER_GC_NPC_POSITION"; + stringList[116] = "HEADER_GC_MATRIX_CARD"; + stringList[117] = "HEADER_GC_CHARACTER_UPDATE2"; + stringList[118] = "HEADER_GC_LOGIN_KEY"; + stringList[119] = "HEADER_GC_REFINE_INFORMATION_NEW"; + stringList[120] = "HEADER_GC_CHARACTER_ADD2"; + stringList[121] = "HEADER_GC_CHANNEL"; + stringList[122] = "HEADER_GC_MALL_OPEN"; + stringList[123] = "HEADER_GC_TARGET_UPDATE"; + stringList[124] = "HEADER_GC_TARGET_DELETE"; + stringList[125] = "HEADER_GC_TARGET_CREATE_NEW"; + stringList[126] = "HEADER_GC_AFFECT_ADD"; + stringList[127] = "HEADER_GC_AFFECT_REMOVE"; + stringList[128] = "HEADER_GC_MALL_SET"; + stringList[129] = "HEADER_GC_MALL_DEL"; + stringList[130] = "HEADER_GC_LAND_LIST"; + stringList[131] = "HEADER_GC_LOVER_INFO"; + stringList[132] = "HEADER_GC_LOVE_POINT_UPDATE"; + stringList[133] = "HEADER_GC_GUILD_SYMBOL_DATA"; + stringList[134] = "HEADER_GC_DIG_MOTION"; + stringList[135] = "HEADER_GC_DAMAGE_INFO"; + stringList[136] = "HEADER_GC_CHAR_ADDITIONAL_INFO"; + stringList[150] = "HEADER_GC_AUTH_SUCCESS"; + stringList[154] = "HEADER_GC_AUTH_SUCCESS_OPENID"; +#ifdef _IMPROVED_PACKET_ENCRYPTION_ + stringList[0xfa] = "HEADER_GC_KEY_AGREEMENT_COMPLETED"; + stringList[0xfb] = "HEADER_GC_KEY_AGREEMENT"; +#endif + stringList[0xfc] = "HEADER_GC_HANDSHAKE_OK"; + stringList[0xfd] = "HEADER_GC_PHASE"; + stringList[0xfe] = "HEADER_GC_BINDUDP"; + stringList[0xff] = "HEADER_GC_HANDSHAKE"; + } + return stringList[header].c_str(); +} + +#endif + +bool CNetworkStream::Recv(int size) +{ + if (!Peek(size)) + return false; + + m_recvBufOutputPos += size; + return true; +} + +bool CNetworkStream::Recv(int size, char * pDestBuf) +{ + if (!Peek(size, pDestBuf)) + return false; + +#ifdef _PACKETDUMP + if (*pDestBuf != 0 ) + { + TraceError("RECV< %s (%d)", GetRecvHeaderName(*pDestBuf), size); + std::string contents; + char buf[10]; + for(int i = 1; i < size; i++) + { + sprintf(buf," %02x", (unsigned char)(pDestBuf[i])); + contents.append(buf); + } + TraceError(contents.c_str()); + } + +#endif + + m_recvBufOutputPos += size; + return true; +} + +int CNetworkStream::__GetSendBufferSize() +{ + return m_sendBufInputPos-m_sendBufOutputPos; +} + + +bool CNetworkStream::Send(int size, const char * pSrcBuf) +{ + int sendBufRestSize = m_sendBufSize - m_sendBufInputPos; + if ((size + 1) > sendBufRestSize) + return false; + + memcpy(m_sendBuf + m_sendBufInputPos, pSrcBuf, size); + m_sendBufInputPos += size; + +#ifdef _PACKETDUMP + if (*pSrcBuf != 0 ) + { + TraceError("SEND> %s (%d)", GetSendHeaderName(*pSrcBuf), size); + std::string contents; + char buf[10]; + for(int i = 1; i < size; i++) + { + sprintf(buf," %02x", (unsigned char)(pSrcBuf[i])); + contents.append(buf); + } + TraceError(contents.c_str()); + + } +#endif + + return true; + /* + if (size > 0) + { + if (IsSecurityMode()) + { + m_sendBufInputPos += TEA_Encrypt((DWORD *) (m_sendBuf + m_sendBufInputPos), + (DWORD *) (m_sendBuf + m_sendBufInputPos), + (const DWORD *) gs_szTeaKey, + size); + } + else + { + } + } + + return __SendInternalBuffer(); + */ +} + +bool CNetworkStream::Peek(int len, void* pDestBuf) +{ + return Peek(len, (char*)pDestBuf); +} + +bool CNetworkStream::Recv(int len, void* pDestBuf) +{ + return Recv(len, (char*)pDestBuf); +} + +bool CNetworkStream::SendFlush(int len, const void* pSrcBuf) +{ + if (!Send(len, pSrcBuf)) + return false; + + return __SendInternalBuffer(); +} + +bool CNetworkStream::Send(int len, const void* pSrcBuf) +{ + return Send(len, (const char*)pSrcBuf); +} + +bool CNetworkStream::IsOnline() +{ + return m_isOnline; +} + +void CNetworkStream::SetPacketSequenceMode(bool isOn) +{ + m_bUseSequence = isOn; +} + +bool CNetworkStream::SendSequence() +{ + if (!m_bUseSequence) + return true; + + BYTE bSeq = m_kVec_bSequenceTable[m_iSequence++]; + + bool bRet = Send(sizeof(BYTE), &bSeq); + if (m_iSequence == SEQUENCE_TABLE_SIZE) + m_iSequence = 0; + + return bRet; +} + +bool CNetworkStream::OnProcess() +{ + return true; +} + +void CNetworkStream::OnRemoteDisconnect() +{ +} + +void CNetworkStream::OnDisconnect() +{ +} + +void CNetworkStream::OnConnectSuccess() +{ + Tracen("Succeed connecting."); +} + +void CNetworkStream::OnConnectFailure() +{ + Tracen("Failed to connect."); +} + +//void CNetworkStream::OnCheckinSuccess() +//{ +//} + +//void CNetworkStream::OnCheckinFailure() +//{ +//} + +#define SEQUENCE_TABLE_SIZE 32768 + +static BYTE s_bSequenceTable[SEQUENCE_TABLE_SIZE] = +{ + 0xaf,0xca,0x8a,0xcf,0x48,0xa7,0x54,0xc7,0xd7,0xdf,0x1,0x25,0x72,0xf7,0x6f,0x84, + 0xbc,0x37,0x46,0xe3,0x24,0xda,0xa1,0xc8,0xee,0x36,0x7c,0x33,0x2f,0x98,0x76,0x5e, + 0xe2,0x1,0x2e,0xab,0x29,0x3,0xf2,0x1,0xe2,0xf3,0xa5,0x56,0x6b,0x15,0x5a,0xa7, + 0xcc,0x21,0x8b,0x70,0xfb,0xac,0x3a,0x6b,0xe3,0x36,0x9e,0x92,0x4e,0x16,0xf1,0x31, + 0x96,0x9f,0x5c,0x3f,0xa2,0x50,0xbf,0x6,0xc3,0x66,0xdb,0x30,0xfa,0xb5,0xd7,0x47, + 0xd6,0xe3,0xb8,0x53,0x90,0x72,0xbe,0xf3,0xa8,0xdc,0x7,0x76,0x72,0x78,0xa7,0xa, + 0x18,0x84,0xc8,0x3b,0xd4,0x89,0x41,0x18,0xef,0x9c,0x48,0x6a,0x52,0xa0,0xb2,0xa9, + 0x4,0xea,0x7c,0x94,0xdc,0x3b,0x9,0x85,0x97,0x10,0x7b,0xb,0x88,0x23,0x94,0x20, + 0x27,0x5d,0xda,0xfb,0xe6,0x1c,0x15,0x56,0x38,0xdc,0xc1,0xb,0xfc,0xf3,0xb4,0x1, + 0xde,0x31,0x16,0xbb,0xeb,0x9e,0xc0,0x83,0x2e,0x3c,0xe,0x36,0xde,0xa2,0x56,0x86, + 0x80,0x32,0x82,0xe6,0xcd,0x17,0x3e,0x86,0x74,0x7f,0x91,0xf0,0x73,0x46,0xf2,0xd1, + 0xf6,0x88,0xd,0x62,0x27,0x4d,0x65,0x55,0x9,0x74,0xb,0x67,0x96,0x61,0xed,0x17, + 0x13,0xf0,0xfe,0xe1,0x87,0xbc,0xe7,0xfb,0x3c,0x79,0x6d,0xaf,0x3f,0x60,0x1,0x36, + 0x68,0xe,0x18,0xf,0x5b,0x7d,0xe3,0x64,0x71,0xee,0xcb,0x9,0xcf,0x3a,0x9f,0xe3, + 0x2b,0x1e,0x45,0xb2,0xda,0x2d,0x2f,0x96,0xa6,0x9c,0x46,0xe5,0x7c,0xc6,0x9b,0xe4, + 0xd4,0xb3,0x73,0xaf,0xb0,0x57,0x93,0x23,0x46,0xdf,0xab,0x16,0x1a,0x4b,0x79,0x45, + 0x6a,0xbe,0xf7,0xc4,0xeb,0xa6,0x5c,0x12,0x43,0x22,0x77,0xbf,0xe9,0x92,0x24,0x3e, + 0x46,0x97,0xee,0x77,0xee,0x82,0x9a,0xb4,0x62,0xc5,0x4b,0xfb,0x11,0xc4,0x41,0xfa, + 0x84,0xb9,0x40,0xef,0x60,0x9c,0x82,0xa4,0x3e,0xf9,0x64,0xa7,0x8d,0x89,0xe6,0x53, + 0xa0,0x55,0x4a,0x90,0x57,0x64,0x45,0x3a,0x2a,0x90,0x36,0x3c,0xd5,0x78,0xb6,0xd9, + 0x32,0xf6,0x49,0x12,0x13,0xcb,0xb6,0xd1,0x46,0x9b,0x79,0x53,0xa4,0xdf,0x26,0x45, + 0xb4,0x71,0x55,0xd,0xd5,0x9b,0x47,0x80,0xab,0x7d,0x3c,0x81,0x75,0xf2,0xda,0x27, + 0x6a,0x25,0x3a,0x7d,0xf0,0xf0,0xce,0xb6,0xc,0x49,0xa,0xb0,0xa8,0xb0,0x76,0x5e, + 0x22,0xcb,0x6b,0x77,0xe6,0x32,0x77,0x13,0x2f,0xb3,0x94,0xa5,0xa7,0xef,0x4c,0x12, + 0x15,0x86,0xf,0x85,0xf7,0xde,0x3d,0x83,0xa7,0x47,0x35,0x50,0x77,0x2b,0xae,0x99, + 0xf6,0x99,0x91,0xde,0xcb,0x9,0xf1,0x7b,0xbd,0x6,0x21,0xe4,0xf5,0x6d,0xf6,0x8a, + 0x74,0x85,0x11,0xeb,0x64,0x4e,0x6f,0xc,0x15,0xa4,0xdc,0x8d,0x4f,0xb,0xa6,0x47, + 0xa5,0xb7,0xa5,0xf0,0x41,0x17,0x6c,0xfe,0x9c,0xd,0x63,0x93,0x7b,0xd9,0x9d,0x6f, + 0x5f,0xae,0x5b,0x44,0xfc,0xca,0xcf,0x13,0xef,0xac,0x20,0x3f,0xb8,0xc6,0x6,0xdd, + 0xfe,0xab,0xce,0x40,0x42,0x3c,0x3f,0xdf,0x49,0x22,0xf2,0x44,0xfb,0x90,0xb3,0xda, + 0x40,0x8e,0x1f,0x3d,0xd9,0xef,0xcf,0xc9,0x1c,0xef,0x88,0xd4,0x37,0x8f,0xb2,0x36, + 0xba,0x82,0xf5,0xfd,0x3e,0xb4,0xdd,0x7,0xd6,0xd0,0x4c,0xd2,0x61,0x7f,0xad,0xa1, + 0xf,0x4d,0x5f,0xe8,0x3d,0x2f,0x32,0x59,0x9f,0xba,0xae,0x56,0xc9,0x61,0xc,0x85, + 0x63,0x2,0x3,0x21,0xb6,0xe0,0x29,0xd,0xb1,0xf4,0xdf,0x92,0x74,0xd,0xb4,0x3, + 0x5a,0x14,0x6b,0x17,0xc2,0x1d,0xf0,0xe1,0x58,0x9f,0x38,0x22,0x80,0xc3,0xa7,0x64, + 0x45,0xaa,0x85,0xfb,0xb,0x2e,0x88,0x3c,0x23,0x68,0xcf,0x18,0xf5,0x84,0x1b,0xcf, + 0x18,0x7,0xe7,0xda,0x24,0xd8,0xbd,0x7c,0xf7,0xf5,0x1f,0xf7,0x3a,0x46,0x5c,0x7f, + 0x71,0x62,0xfb,0x7c,0x90,0x84,0xb9,0x34,0x6d,0x9,0x4c,0x63,0xd,0xe6,0xb2,0x25, + 0x6d,0x1a,0x0,0x12,0x72,0x3d,0xe,0x6a,0xb3,0x2d,0x63,0xed,0x74,0x3f,0x6d,0xe5, + 0xa1,0x69,0xe1,0xb2,0x6e,0x1b,0xe6,0xdb,0x24,0x33,0xbe,0xb0,0x99,0x71,0xd5,0x8, + 0x8c,0x56,0x1a,0xfe,0x93,0x28,0xe9,0x47,0x56,0xcc,0xb4,0x4a,0xc,0x23,0xaf,0xae, + 0xc,0x91,0xe0,0x7a,0xad,0xc7,0xd5,0x51,0x7a,0x94,0x82,0x14,0x86,0x58,0x9b,0x13, + 0x2e,0xb5,0x91,0x42,0x5e,0xfa,0x9,0x34,0xc7,0xbe,0x7e,0xd4,0xe1,0x2e,0x3,0x6d, + 0x3f,0xe3,0x68,0x6c,0x2b,0x3e,0xbe,0xa5,0xd3,0x41,0x39,0x5a,0x19,0xd5,0xec,0xc7, + 0xb,0xfd,0xa,0x69,0xf9,0x92,0x9d,0xc1,0x51,0x9b,0x16,0xb2,0x49,0x98,0x21,0x9, + 0x7c,0x89,0x75,0xa7,0xc7,0x34,0xcc,0x1b,0xf4,0x7,0xf4,0x8e,0xdc,0xe1,0x56,0xe7, + 0x60,0xdf,0xd1,0x5a,0x72,0xee,0x9b,0x44,0xb,0x32,0xf6,0x54,0xca,0x18,0x5d,0xc7, + 0x21,0x53,0xee,0x69,0x7,0xbc,0x4,0xfc,0x43,0xf9,0xb,0x9f,0x5b,0xe0,0x7,0xbb, + 0x40,0xd8,0x16,0xb2,0x48,0x32,0xf6,0x53,0x64,0x6e,0x27,0xae,0x6,0x5,0x76,0x28, + 0x58,0xe5,0x11,0x5f,0x22,0x15,0xdb,0x65,0x8e,0xe6,0x5,0xea,0xc7,0x8b,0xa6,0x8, + 0x65,0x3d,0x3b,0xad,0x6f,0xb1,0x80,0x53,0x20,0xa7,0x2,0x27,0xac,0xf8,0xce,0x5, + 0xde,0x5f,0xe4,0x80,0xf3,0xc0,0xe5,0x83,0xa8,0x6a,0x6e,0xef,0xf5,0x94,0x78,0xda, + 0xd1,0x33,0x8,0xc0,0xe4,0x88,0x14,0x85,0xb0,0x96,0x2c,0x5d,0x8f,0xfa,0xe2,0xed, + 0xd9,0xc7,0x6e,0xcd,0x8,0x54,0x51,0x30,0x3e,0x3f,0x21,0xb3,0xd4,0x19,0x8f,0x26, + 0x4c,0x17,0x67,0xb0,0xa0,0x7b,0x36,0xd0,0x12,0x62,0x2e,0x21,0xdc,0x90,0xf,0xb6, + 0x58,0x7d,0x85,0xe0,0x51,0x56,0x11,0x8f,0x96,0x32,0xc3,0xea,0xca,0xd2,0x90,0x96, + 0xe9,0xf7,0x48,0xa,0xf3,0xfd,0xda,0x6,0x61,0x89,0xa7,0xbd,0x1a,0xb6,0xf4,0xf2, + 0x35,0x7a,0xd3,0x6,0x50,0xe4,0x16,0xe6,0x97,0xd9,0x51,0xe1,0xac,0xe2,0x79,0x16, + 0xda,0xc1,0x21,0xce,0xbf,0x7b,0x55,0xa0,0x5,0xfc,0xde,0x9f,0x33,0xd3,0x92,0xe7, + 0xcd,0xe5,0xee,0x1e,0x4a,0x5,0x6,0x61,0x5e,0xd6,0x44,0xb,0xb9,0xbd,0xa0,0x15, + 0xfe,0xc1,0x63,0xbe,0xbd,0xb8,0xdf,0x42,0x35,0xbe,0xe1,0xe8,0x92,0xf3,0xd0,0x60, + 0x59,0x3f,0x7e,0xa4,0x44,0x4,0x6,0x22,0xdb,0x4a,0x2d,0x15,0x87,0xce,0x2a,0x86, + 0x10,0x8e,0xc5,0x4d,0xc6,0xa5,0x90,0x7c,0x64,0xf1,0x65,0x76,0xe6,0xb5,0x56,0x40, + 0xf5,0x54,0xe4,0xb9,0xd8,0x6b,0xdc,0x34,0x35,0x89,0x49,0xbd,0xd7,0xf3,0xc3,0x68, + 0x2,0x89,0xb5,0xc8,0x2f,0x46,0xc4,0x13,0xb8,0xa9,0x9,0x9f,0x60,0x5f,0x5f,0xd5, + 0x34,0x45,0xf,0xd,0x30,0xeb,0x41,0x65,0x76,0x8a,0xa2,0xcd,0xfd,0x67,0x36,0x0, + 0xf0,0x6c,0x49,0xa0,0x32,0xe,0x33,0xea,0x38,0x3d,0x8a,0x18,0x1c,0xea,0xed,0x50, + 0xaf,0xfc,0x5d,0xdf,0x69,0x9e,0xc4,0x5f,0xa9,0xe7,0x2d,0xa7,0x4f,0x64,0xa8,0xbf, + 0x50,0xf1,0xdf,0x82,0x7f,0x14,0x6e,0xb7,0xd0,0xf8,0xcf,0xec,0x63,0x3d,0xbd,0x13, + 0xba,0x1b,0x72,0x24,0x3a,0xb7,0x83,0xe3,0x9f,0x30,0xb,0x6e,0x94,0x33,0xad,0x64, + 0xa4,0x8e,0xe7,0x25,0x22,0x56,0x5c,0x72,0x4f,0xac,0xde,0xb3,0x69,0x9c,0x46,0x24, + 0xb8,0x39,0x48,0x72,0xf0,0x4b,0xd5,0x10,0x7c,0xe0,0x7e,0x90,0x15,0x2c,0xf5,0xb9, + 0x3a,0xdd,0x5e,0xdb,0x34,0x3b,0x4e,0x3,0xe7,0x2e,0x36,0x51,0xca,0x7d,0x76,0x3, + 0x36,0x3e,0xf4,0x27,0x8a,0xca,0x37,0x7,0x2c,0x35,0x17,0xc0,0xe0,0xd,0x7a,0x1c, + 0xea,0x59,0xf7,0x9e,0x94,0xc6,0xa2,0x7c,0x74,0xd8,0x4d,0x3f,0xd5,0x43,0xc2,0xc, + 0x82,0x37,0xb2,0x8c,0x3,0x69,0x13,0x2f,0x9e,0x2a,0xef,0x80,0xb7,0xe9,0x1c,0x22, + 0xc2,0x93,0xc1,0x57,0x5a,0x64,0x53,0xce,0xbc,0xa1,0x8e,0x13,0x64,0xd0,0x9e,0x66, + 0x8,0x52,0x72,0xb,0xbb,0x85,0xb9,0xda,0x30,0x29,0x5b,0xe7,0x93,0xf6,0xa,0x56, + 0x8a,0x4b,0x2e,0x65,0x2f,0x81,0x34,0xec,0xa2,0x42,0x0,0x8,0x13,0x1e,0xed,0x9b, + 0x70,0x61,0x26,0xac,0xe6,0x60,0x87,0x96,0x89,0x62,0xfd,0x9c,0xd8,0x88,0xf3,0x63, + 0xd3,0xa1,0xc8,0x4,0x23,0x7d,0x70,0x46,0x3f,0xef,0xcd,0xd2,0xe,0xbb,0x6e,0x7f, + 0x1d,0x94,0xab,0x84,0xf4,0xb2,0x1b,0xfe,0x94,0x99,0x9b,0x6d,0x22,0xf,0xd0,0xf5, + 0xb0,0x1a,0x79,0x54,0x17,0x69,0x9a,0x56,0x59,0x68,0x29,0x68,0x24,0x97,0x67,0xc1, + 0xac,0x92,0x46,0xa1,0x45,0x61,0xa0,0xd9,0xfa,0xbc,0x47,0x9c,0xcb,0x97,0x13,0xfc, + 0x31,0xc,0x51,0x48,0x76,0x6b,0x1f,0xcf,0xd3,0xc7,0x38,0x77,0xdf,0x1f,0x39,0x8c, + 0xb1,0xfe,0xad,0xf6,0x61,0xce,0x50,0xdb,0x8b,0x17,0xf8,0xd6,0x2f,0xc,0xd3,0x60, + 0x18,0xa4,0x29,0x8e,0x10,0xc7,0xde,0x63,0x8f,0x96,0xdb,0x6f,0xb6,0x94,0x7b,0xe7, + 0x94,0x2a,0x5f,0x75,0xf8,0xaf,0xd0,0x4,0xc7,0xc9,0xda,0x76,0x55,0xaf,0xd6,0xed, + 0x54,0x7f,0x7c,0x65,0x47,0x5b,0xc8,0xd7,0xf2,0x24,0xc6,0x29,0xb9,0xc2,0x11,0xcd, + 0xec,0x70,0x43,0x65,0xa0,0x93,0x69,0xe7,0xdd,0xc3,0x5e,0x33,0x73,0xb4,0x21,0x48, + 0x35,0x1e,0xad,0x7c,0xf8,0xf5,0xd3,0x6b,0x9a,0x9b,0x94,0xd3,0x5e,0x26,0xa1,0xca, + 0x96,0x64,0xaf,0xb6,0xf7,0x98,0x9e,0xd5,0x5c,0x7c,0x89,0x50,0x32,0xaa,0x98,0x67, + 0x48,0x46,0xe3,0x42,0xbb,0xb8,0xad,0x56,0xd3,0x43,0x2a,0xb1,0xe8,0x4b,0xfb,0x7f, + 0xaf,0xab,0xb6,0x28,0xc3,0xd4,0x7d,0x9f,0x52,0x7,0xef,0x4,0x32,0x88,0xea,0x7a, + 0x4e,0xce,0xbc,0xb,0x7,0xea,0xe0,0x5a,0xad,0x8b,0xc,0x96,0x56,0x87,0x95,0x7, + 0xb2,0x4c,0xae,0x76,0xa1,0x2c,0x17,0x73,0xb3,0x7,0x77,0xe5,0x10,0x62,0xdf,0x5e, + 0xb0,0x1d,0xe8,0x38,0x8,0x4a,0x92,0xb5,0xd5,0x1f,0xcb,0x2c,0xa6,0x61,0xb2,0x5a, + 0x2e,0x61,0x50,0xcf,0xe,0x67,0x43,0xc1,0xee,0xba,0x27,0xfe,0x9c,0x7,0x5d,0x4d, + 0x24,0xc6,0x5,0x2c,0x11,0x98,0x61,0xe6,0x37,0x2d,0x92,0xdd,0xf,0xc5,0x38,0x3d, + 0xa6,0x89,0xd,0xb4,0x70,0xcf,0xf5,0x5f,0x8a,0x1d,0xdd,0xa6,0x25,0x3c,0x73,0xc8, + 0x3,0x79,0x75,0x14,0x91,0x56,0x7a,0xc8,0x84,0x8c,0xa6,0x13,0x52,0x5f,0x50,0xf9, + 0x68,0xdc,0x2e,0x58,0xac,0x25,0x38,0xb6,0xc1,0x16,0x5d,0x66,0x52,0x50,0x30,0xd4, + 0xc9,0xa5,0x68,0x5b,0xfb,0x62,0xa3,0x0,0xef,0x4b,0x13,0x42,0x2a,0xe2,0xbb,0x12, + 0xbf,0xea,0x6a,0x6c,0x10,0xa2,0xa2,0xd1,0xb9,0x0,0x39,0x8b,0x51,0xe8,0xe0,0x9a, + 0xe,0x49,0x76,0xa,0xac,0x1a,0x8a,0x1c,0x65,0x1d,0x5e,0xf,0x1,0x1b,0x21,0x40, + 0x85,0xc,0x2d,0x95,0xae,0xcf,0xe6,0xe7,0x50,0x9f,0x74,0xa1,0x88,0x55,0xbb,0x96, + 0x1e,0x32,0x21,0x4a,0x4d,0x2b,0x66,0x32,0x48,0xc5,0x42,0xc8,0x60,0xe2,0x89,0xe5, + 0xee,0xb6,0xfa,0x1e,0x6,0x61,0x6,0x56,0x2,0xf9,0x77,0xa,0xce,0x34,0xa1,0xed, + 0x66,0x42,0x38,0xb3,0x6d,0x9f,0xe6,0xb5,0xe4,0xa8,0xfe,0xc4,0x8b,0x88,0x2a,0xfa, + 0xbe,0x25,0x19,0xc4,0x6,0x9e,0x9b,0x8,0x99,0x13,0x13,0xe7,0x47,0x34,0xd5,0xae, + 0x76,0x8e,0x62,0xe3,0xad,0xc8,0x19,0x92,0x71,0x97,0x57,0xfd,0x9f,0x81,0xf8,0x5e, + 0x26,0x91,0xa3,0x2c,0x30,0x3f,0xb4,0x49,0xd1,0x47,0x32,0x1a,0x7b,0x87,0x48,0x71, + 0x16,0x2a,0x55,0xc3,0xf3,0xed,0xd5,0x65,0x6,0xac,0xe2,0xa5,0xad,0x5b,0x84,0xd3, + 0x6c,0x28,0x80,0x1d,0xe6,0x35,0x66,0xb8,0x7c,0x18,0xd2,0x77,0xa0,0x9a,0xe8,0x36, + 0xc5,0xbd,0x7a,0xb9,0x2b,0x50,0x9e,0x31,0x7d,0x2,0xd7,0x2b,0xdc,0x5c,0x7f,0x4a, + 0x4,0x0,0x67,0xea,0xb4,0x4d,0x23,0xb0,0x66,0x76,0x28,0x7,0x11,0x90,0xbc,0xd6, + 0x4e,0x37,0x10,0x79,0x8,0xaf,0x2b,0x85,0x31,0x3,0xb0,0xe,0xde,0x30,0xd7,0x62, + 0xaf,0xbe,0xcc,0xe3,0xd,0xef,0x14,0x73,0x66,0xbb,0xf9,0xf7,0x4c,0xb6,0xce,0x1a, + 0xee,0xdf,0x94,0x76,0xf,0xbf,0xfb,0xbf,0x42,0xac,0xcd,0xa0,0x5d,0x26,0x3,0x8c, + 0xe4,0xcf,0xf0,0xf1,0xbf,0x5,0xe4,0xa6,0xc1,0x5e,0x9e,0xe,0x16,0xec,0xa8,0x84, + 0xcc,0x3d,0xfa,0x5b,0x7c,0x76,0x1b,0x3e,0x23,0x69,0xde,0x0,0x8f,0xe1,0xd,0xf3, + 0xb1,0xfd,0x66,0xf0,0x82,0x4b,0x97,0x44,0x2a,0xb5,0xd2,0x40,0xa3,0x7b,0x44,0x70, + 0x38,0xbe,0x4c,0x34,0x35,0xe6,0x72,0xd7,0x50,0xd0,0xd8,0x5f,0xb2,0x65,0xd3,0xe3, + 0xe2,0x3a,0xd4,0x65,0x5,0xec,0x2a,0x2f,0xa2,0xfc,0xee,0x46,0xf7,0x33,0x37,0xaf, + 0x71,0x3,0xe3,0xa6,0xe9,0xd5,0x7f,0x3b,0xa6,0xd7,0x1a,0x59,0xbc,0xed,0x3d,0x9f, + 0xa7,0x91,0x5,0xad,0x7e,0x2f,0x5c,0xa1,0xab,0x4c,0x67,0xa3,0xfe,0x9e,0x53,0x71, + 0xa1,0xb6,0x97,0x8c,0x8c,0x17,0x47,0x33,0x6e,0xe0,0xc,0x2b,0x4f,0x49,0xca,0xf6, + 0x5b,0x50,0x24,0x59,0x7f,0x81,0xfa,0xab,0x4d,0xe2,0xce,0xcb,0x81,0xa2,0xbc,0xa3, + 0x59,0x55,0xaf,0xe6,0xeb,0xf6,0x99,0xda,0xd7,0xa6,0x6,0xa6,0x6f,0x51,0x9e,0xca, + 0xa1,0xc2,0xa4,0xa0,0xc3,0x1f,0xcb,0x11,0x2,0x9b,0xdd,0x84,0x3e,0x9a,0xa7,0x17, + 0x6f,0x57,0xfd,0x5c,0x4e,0x18,0x37,0xa5,0xbe,0xbc,0x4d,0x2e,0x8d,0x6b,0x79,0xae, + 0x2e,0x1e,0x50,0xf2,0x3d,0x9b,0x83,0xbf,0x37,0xe0,0x44,0xf4,0xfb,0x6b,0xd,0x6b, + 0xc2,0x8a,0x47,0x90,0xa2,0xfd,0x36,0x61,0xbb,0x3,0x90,0x49,0x6e,0xa,0x78,0x1d, + 0xa7,0xc8,0x8f,0x64,0xe3,0x13,0x24,0x1c,0x74,0xe7,0x90,0x70,0x53,0x9d,0x5b,0x16, + 0x29,0xa3,0xa6,0xcb,0xa1,0x5d,0xad,0xdc,0xdf,0xbd,0xa6,0x4f,0x47,0x1f,0xeb,0xee, + 0x67,0xfa,0x53,0x4b,0xe,0xf7,0xe6,0x2,0xdf,0x78,0x72,0x34,0x95,0x4e,0x4a,0xbe, + 0xf1,0x71,0xb,0x13,0xce,0xb8,0x70,0xae,0xf5,0x96,0x7d,0x3d,0xb5,0xe8,0x2c,0x9c, + 0xe3,0xfe,0x67,0x72,0xf6,0xce,0x74,0xd7,0x47,0x67,0x8b,0x5c,0xb5,0x55,0x1c,0x27, + 0xc6,0xa6,0x3a,0x15,0xde,0x2a,0x44,0xd4,0xc0,0x41,0x12,0xf5,0x2b,0xbd,0x92,0x8e, + 0xbc,0x7a,0x1,0x34,0x49,0xf5,0x8b,0x10,0xdc,0x17,0x6c,0x92,0xeb,0x88,0xb9,0xb3, + 0x2f,0x73,0x48,0x8d,0x9e,0x8c,0x62,0xde,0x4e,0x74,0xd5,0x79,0xb1,0x68,0x8,0x6f, + 0xe2,0x89,0x23,0x2c,0xfe,0x2e,0x3c,0xdb,0xc4,0x29,0xed,0xb0,0xb1,0xa7,0xe3,0x61, + 0x9a,0x2d,0xee,0xb8,0x39,0xd1,0x98,0x87,0x46,0xed,0x80,0xf8,0x56,0x9,0xe7,0xb9, + 0x12,0x8a,0x65,0x11,0xb8,0x22,0xec,0x7d,0x4b,0xda,0xad,0x7c,0x2,0x92,0x5d,0x1c, + 0x3f,0x4d,0xd5,0xf7,0x1f,0xed,0x80,0xe4,0xdb,0x80,0x5d,0xb1,0x89,0xc4,0xea,0x9b, + 0x4f,0x51,0x2c,0x87,0xf2,0x19,0x84,0xbd,0x73,0x33,0x3a,0x75,0x45,0x98,0x12,0x84, + 0x65,0x67,0x7c,0x4,0xd4,0x7c,0xe8,0xb0,0xfd,0xc6,0xe1,0x87,0x8b,0x4d,0xa3,0x5b, + 0x1e,0xcf,0x62,0x11,0x69,0xe7,0xce,0x5c,0x1b,0x88,0x52,0x60,0x21,0x64,0x64,0x86, + 0xcb,0xe0,0xa,0xa0,0x5e,0xf3,0xd0,0xdb,0x3a,0x32,0xe2,0x45,0x7f,0x86,0xa0,0x9d, + 0xd6,0x4,0x2e,0xbf,0x6b,0xfc,0x1c,0x86,0x86,0x6e,0x66,0x27,0xd2,0xca,0x2e,0x1e, + 0x2b,0x38,0x3e,0x89,0xab,0xf,0xe4,0x65,0xc1,0xc8,0xab,0x41,0x4f,0x4c,0x5f,0xa5, + 0xcf,0x8d,0xe4,0x3b,0xb,0x2,0x41,0x11,0x70,0xa7,0x38,0xc3,0xf1,0xe5,0x61,0x1e, + 0x1f,0xa0,0x27,0x4a,0x2f,0xd,0xb0,0xf0,0xd5,0x5c,0xb2,0xa4,0x28,0x12,0xca,0xf8, + 0x1f,0xaf,0xb3,0x2a,0xb1,0xf5,0x3b,0xa2,0x1d,0xf3,0xe5,0x8f,0xd9,0x47,0xad,0x78, + 0x67,0x54,0xc3,0x97,0xe0,0xf3,0x8,0x36,0x50,0x3a,0x5b,0xf7,0xcb,0xa5,0x70,0xeb, + 0x55,0x25,0x16,0x87,0x9a,0xd1,0xa9,0xb7,0xc5,0xf,0x47,0x9f,0xd5,0x74,0x98,0x3e, + 0x49,0xdb,0x55,0xa9,0xcf,0xdc,0x60,0x9f,0x18,0xbb,0x97,0xe3,0x61,0x9,0x4f,0x36, + 0xad,0xe5,0x3d,0x48,0xb7,0xe6,0x7f,0xfc,0xf5,0x47,0x1c,0x4c,0x3b,0xb4,0x8a,0x84, + 0x90,0x5f,0xae,0x60,0x3c,0xf,0x0,0xd3,0xca,0x18,0x38,0xab,0x21,0x87,0xe1,0x4e, + 0x6d,0x20,0x96,0x25,0x86,0x95,0xa1,0xfc,0xdc,0xbe,0x49,0x19,0x73,0x53,0x1d,0x5, + 0xb2,0xcb,0xe4,0x6e,0xda,0x65,0x43,0x25,0x7d,0x7b,0x50,0x1e,0x3,0x33,0x6c,0xf0, + 0xd2,0x82,0x95,0xd8,0x18,0x38,0xd5,0xf5,0xf6,0x1f,0x8e,0x6a,0xf1,0x2b,0xee,0xa4, + 0xf7,0xd4,0x14,0x52,0x3a,0xd6,0xf7,0xb7,0x52,0x48,0xd5,0xd4,0xfa,0xc1,0xc5,0xcd, + 0x44,0x5c,0x27,0x5c,0x94,0xfc,0xd1,0x8b,0x9c,0xdf,0x75,0x8e,0xc,0x65,0xb3,0x83, + 0x3a,0xc7,0x55,0xf3,0x1e,0x4d,0x2b,0x70,0x16,0x80,0x45,0x11,0x42,0x8b,0x5f,0x6, + 0xe7,0x86,0x62,0xfb,0x83,0xb4,0x7,0x9f,0x94,0x7c,0x2f,0x20,0xe1,0xe2,0xa3,0x9b, + 0x2a,0xf9,0xf,0x48,0xc6,0x3a,0x38,0xdc,0x3a,0xfc,0xee,0x7c,0x88,0x4e,0x82,0xef, + 0x54,0x65,0xeb,0xd7,0x99,0x72,0xf7,0x2e,0xef,0x27,0x4f,0x51,0x89,0x72,0x6d,0xb3, + 0xeb,0x7c,0x7b,0xb3,0x37,0xb3,0x90,0x71,0xb0,0xfe,0xee,0xb9,0xcc,0xf0,0xa9,0x21, + 0xd5,0x16,0x79,0x6f,0x88,0x71,0x1e,0xf7,0x18,0xec,0x4a,0xa1,0x5f,0xb7,0xd4,0x4c, + 0xb3,0xcf,0x7f,0xea,0x83,0x8f,0x5d,0xb3,0x8f,0xcb,0xec,0x5c,0x3c,0x97,0xfd,0x13, + 0x2d,0x77,0x82,0xb5,0x68,0xa0,0x2e,0x80,0xd,0x78,0xa1,0x6d,0xaf,0xf5,0x39,0x63, + 0xc5,0xb8,0x4f,0xc8,0xc7,0x2c,0xfb,0x57,0xf7,0xe9,0x34,0x34,0x1,0x32,0xc6,0x2e, + 0x29,0x4a,0x63,0x91,0x6a,0x91,0x91,0x78,0xa,0x33,0x65,0xb9,0xa8,0x1e,0x9d,0x6e, + 0x56,0x6c,0xb6,0x1e,0x98,0xb2,0x76,0x10,0x9c,0x2a,0xc3,0x9d,0xdb,0x8b,0x4b,0x5, + 0x55,0xaf,0x16,0x3f,0x41,0xa7,0x37,0xcb,0x5a,0x9c,0x5,0x3,0x3a,0xa2,0x71,0x90, + 0xf,0xa7,0xaf,0x27,0x5a,0x26,0x37,0x77,0xcf,0xfb,0x94,0xab,0x87,0xe0,0xb0,0x5c, + 0x10,0xc6,0x9b,0x51,0xed,0xd3,0x1d,0x48,0xef,0x23,0x4b,0x2b,0xc5,0x3c,0xbb,0x55, + 0xe3,0x6b,0x7c,0xbd,0x11,0x34,0x35,0xe0,0x30,0x4a,0x8c,0x37,0xaa,0xbc,0x93,0xba, + 0x3,0xae,0xc,0xf0,0x82,0xa9,0x39,0xf2,0xcc,0x84,0x1e,0x12,0x40,0x59,0xe6,0x24, + 0x45,0x64,0x62,0x56,0x18,0x97,0xb7,0x48,0x61,0xc3,0xfe,0xc,0x81,0x12,0xc6,0x84, + 0xc0,0xd3,0x76,0xc3,0x7d,0x2f,0xb6,0xc9,0x34,0x54,0xdb,0x74,0x2d,0xc3,0x19,0x72, + 0xa7,0x7b,0x49,0xbf,0x92,0x80,0x87,0xf4,0x44,0x6,0x1,0x45,0x18,0xc8,0xca,0xd8, + 0x1c,0xc0,0x1c,0x19,0x6f,0x52,0xe2,0xa3,0x26,0x3e,0x98,0x54,0x81,0x31,0x46,0xa8, + 0xac,0x8f,0xe7,0xbe,0x10,0xee,0xb3,0xd4,0xf4,0x35,0x1a,0xd,0x7d,0x64,0x66,0x19, + 0xa4,0x82,0x32,0x15,0xd5,0x94,0x38,0x7b,0x52,0xd0,0xcf,0x54,0x2,0x17,0x7c,0x2e, + 0x26,0x65,0xed,0xb6,0x54,0x21,0x8b,0xc9,0xd5,0xa5,0xd6,0x53,0xb,0xbc,0xeb,0xaf, + 0xbf,0x1e,0x44,0x15,0x32,0x7d,0x90,0x5,0xcd,0x61,0x59,0x50,0xf7,0xd5,0x7e,0x9d, + 0xba,0xeb,0x54,0x8f,0x8d,0xdf,0x59,0x63,0x6,0xaf,0x37,0x11,0xec,0x23,0x40,0xac, + 0xc1,0x85,0x41,0x73,0x82,0xd1,0x78,0x50,0xb2,0x51,0xa0,0x2a,0xa7,0x9f,0xc8,0x62, + 0xb,0x1d,0x71,0x18,0x7d,0x4a,0xfb,0x83,0x7a,0x33,0x14,0x67,0xd5,0x54,0x93,0x97, + 0x59,0xd4,0xc,0xdb,0x26,0x4,0xac,0xd9,0x56,0xcc,0x4,0xfd,0x6c,0xcc,0xdf,0xf7, + 0x6a,0x52,0x10,0xe7,0x1c,0x8b,0xea,0x96,0xbe,0xfe,0x7d,0x95,0x53,0x90,0xac,0x2d, + 0x65,0x38,0x88,0xc,0x3d,0x35,0xe5,0x13,0x3,0x69,0x90,0xee,0x37,0x70,0x66,0x21, + 0x42,0xf6,0x9,0xde,0x82,0xf3,0x75,0xc1,0x72,0x73,0xd6,0xc5,0x4,0x83,0x72,0xe9, + 0x3c,0xfb,0xf5,0xf8,0xb0,0x5b,0xc,0xb3,0xc4,0x1c,0x23,0x7b,0x8c,0x89,0x9c,0x4f, + 0x0,0x25,0x2e,0x83,0x98,0x23,0x45,0xb,0x16,0x1c,0x51,0x9a,0x1f,0xc3,0x84,0x5b, + 0x3f,0xf9,0xd3,0xf0,0x55,0x5f,0x24,0x99,0x7b,0x47,0x16,0x9,0x51,0x32,0xd7,0x51, + 0x58,0x85,0x54,0x70,0x28,0x19,0x7c,0x3f,0x35,0x4d,0xd9,0xd4,0x90,0xdd,0xaf,0xd0, + 0xd7,0x84,0x41,0xac,0xe3,0x65,0x46,0x60,0x2d,0x5c,0xe8,0x7e,0x8f,0x40,0x4f,0x67, + 0xc5,0x24,0xd7,0xed,0x3d,0xd3,0x2d,0xf2,0x21,0x86,0x47,0x32,0x64,0xf6,0x82,0x3c, + 0xfa,0xc3,0x68,0xdf,0x29,0xaf,0xbf,0xd5,0x8b,0x28,0xd3,0x9a,0x68,0xa3,0x81,0xad, + 0xc7,0x5a,0x9b,0x84,0xad,0x49,0x77,0x4f,0x4f,0xbe,0x81,0xb4,0x36,0x4,0x70,0x31, + 0xc7,0xd9,0x90,0x70,0x9,0x50,0x47,0x14,0x78,0x1b,0xaf,0x60,0x3e,0x31,0xe,0x6, + 0xb,0x2a,0x8b,0x39,0xf2,0x82,0x88,0x42,0xc1,0xa,0xf6,0xf7,0x8d,0xe7,0xa8,0x55, + 0xc1,0x3a,0x45,0x4a,0x8a,0xc,0x5e,0x83,0xa7,0xe,0xe3,0xe5,0xbf,0x72,0xec,0x4a, + 0x9c,0xf7,0x83,0xf,0x7a,0x8b,0x51,0x3c,0x95,0xc8,0xb3,0x23,0x30,0x5d,0xf7,0xf1, + 0x97,0xbd,0x3c,0xa1,0xc9,0x1a,0xa4,0x71,0x29,0x9,0xd7,0x68,0x7b,0x44,0x32,0x97, + 0x3c,0x36,0xa6,0x36,0xc1,0x77,0xf2,0xd7,0xbf,0xa6,0x7a,0xef,0x83,0xf2,0x61,0x9a, + 0xb0,0x1d,0xbc,0x7a,0x38,0x61,0x6c,0xe0,0x6a,0xc3,0xc8,0x65,0x8,0xfa,0x7c,0x44, + 0x31,0xa2,0xf9,0x73,0x1b,0xec,0x4b,0x5a,0x14,0x45,0x4b,0x97,0x38,0x2c,0xb2,0xe8, + 0x4a,0x6f,0xe3,0x82,0xd0,0xcf,0xe2,0xbb,0x93,0xab,0xa0,0x1b,0xa6,0x1e,0xde,0x58, + 0xc0,0xd8,0xcb,0x5b,0xc6,0x96,0xb6,0xda,0xdb,0x81,0xf1,0x94,0xad,0x24,0x7d,0xf7, + 0x93,0xe0,0xf9,0xe4,0xb0,0xdc,0xa0,0xc3,0x88,0x41,0xde,0xaf,0xde,0xbd,0x8,0xa0, + 0x97,0x53,0xfb,0xdd,0xe9,0x32,0x38,0x45,0xb3,0x2a,0xd9,0x62,0x4f,0xd7,0xd9,0x62, + 0xb8,0xd4,0x47,0x6a,0xb1,0x67,0xad,0xba,0x29,0x8d,0x6a,0x8,0x4b,0x72,0x28,0xe2, + 0x45,0x25,0xc0,0x2f,0x57,0xf8,0xf3,0xc,0xa3,0x4e,0xed,0x72,0x26,0xc7,0xd4,0xde, + 0x1c,0x9c,0xc8,0x4e,0x4,0x77,0x9,0xac,0x5,0x73,0xb5,0xcf,0x65,0x5d,0x33,0xaa, + 0x82,0x73,0x59,0x5a,0xec,0xcc,0xe5,0x90,0x1b,0xd3,0x82,0xc0,0x1b,0xd6,0x20,0x38, + 0x73,0xe8,0x86,0xf7,0xdf,0xf,0xa4,0x64,0x2,0xd9,0xb4,0xe6,0x38,0xe7,0x91,0x3a, + 0x5b,0x6a,0x14,0x48,0xb6,0xf9,0x58,0xd2,0x4d,0xda,0x93,0xe8,0x32,0xb3,0x21,0xa5, + 0x1d,0x27,0x1d,0x7c,0xb5,0x42,0x61,0xb7,0x1c,0x16,0x9e,0xd3,0xfd,0xaf,0x8e,0x59, + 0x1a,0xa2,0x22,0xd0,0x1d,0x7a,0x23,0x6a,0xd5,0x37,0x53,0x8,0x6a,0xf3,0xad,0x7, + 0x9a,0x4b,0x84,0x50,0x8d,0xe5,0x8,0x29,0xfb,0x26,0x7d,0xf9,0xd5,0xc,0xd2,0x6f, + 0x2e,0xf4,0xc0,0x4b,0xef,0x63,0xb6,0xc5,0x9a,0x89,0xcd,0x6,0xfd,0xfa,0x8c,0x98, + 0xc5,0x11,0x69,0x53,0x76,0xf0,0x7d,0x72,0x18,0xfa,0xeb,0x6d,0x86,0x3f,0xdd,0xb4, + 0xb3,0x1e,0x1,0xa3,0x81,0x37,0xe8,0x1d,0x40,0x36,0xa2,0x3e,0xb1,0xae,0x57,0x77, + 0xc0,0x40,0xcb,0x37,0x31,0xc8,0x2a,0xc8,0x43,0x95,0x37,0xc9,0xd4,0x94,0xfd,0x89, + 0xb2,0x7e,0xac,0x34,0x35,0x96,0xd0,0x76,0xcc,0xf2,0x34,0x7e,0xa2,0xb,0xf6,0xe2, + 0x4b,0x42,0x99,0xfc,0xb,0xc3,0xc5,0xcd,0xd9,0xfc,0x97,0xae,0x91,0x15,0xb7,0x44, + 0x94,0xe4,0xf8,0x49,0x7b,0x49,0xbf,0xc7,0x3d,0x74,0x47,0x5f,0xfe,0xbd,0xc1,0x4b, + 0x0,0x5b,0x48,0x8a,0x9f,0xe,0x58,0x79,0x8b,0x6f,0xa7,0x1d,0x4,0xdf,0xe1,0x18, + 0xc4,0x5a,0x62,0xbf,0xa3,0xa1,0x87,0x60,0x16,0x4e,0x3f,0x16,0xc,0x1,0xe0,0x8b, + 0x5d,0xa8,0x16,0xfc,0xb6,0xed,0xf5,0xc1,0xdc,0x1d,0xdf,0xe1,0xfc,0x41,0xf9,0x41, + 0x9b,0x5c,0x1,0x3f,0xfe,0x89,0x20,0x94,0xd7,0x5f,0x2a,0x64,0x61,0x8a,0xef,0xbe, + 0x33,0x86,0x3b,0x6a,0xf3,0xb0,0x2c,0xd1,0xcd,0x8b,0xb3,0x4b,0xcc,0x2d,0x8c,0xe7, + 0x8a,0x8e,0x28,0x9,0x97,0x48,0x1d,0xee,0x27,0xc7,0x53,0x88,0x52,0xc3,0xc6,0x6, + 0xc9,0x2,0x70,0xbd,0x32,0x1c,0x8f,0x1,0xa8,0xc2,0x4c,0xf4,0xf0,0x58,0xdd,0xfa, + 0x66,0x85,0x83,0xfd,0x4d,0xa0,0x6d,0x74,0xe7,0x40,0xfd,0xba,0x4,0xc4,0xc0,0xcd, + 0x47,0xb0,0xc,0x79,0x4c,0x9b,0xf9,0xf4,0xde,0xc5,0x6a,0xcf,0x1f,0x48,0xca,0x5, + 0xcd,0x4e,0x83,0x1b,0x6e,0xf0,0xf,0x57,0x31,0xd,0x12,0xb5,0x52,0x52,0x83,0x19, + 0x82,0xf,0x12,0xce,0xab,0xd,0x44,0x8a,0x52,0xae,0xd9,0xf0,0xf6,0x24,0xf6,0x44, + 0x72,0x7a,0xde,0x60,0x6b,0xed,0x37,0x1c,0x7b,0xc8,0xd1,0x4d,0x1b,0xd5,0xe5,0x1d, + 0xe4,0xf7,0xec,0x10,0x84,0x31,0x1a,0xd7,0x5f,0xf3,0xc8,0xd5,0x97,0x3f,0x1a,0xa, + 0xb9,0x78,0xea,0x25,0xe5,0x22,0xc1,0x61,0xeb,0x93,0x2e,0x86,0x69,0x14,0xa4,0xce, + 0xd,0x91,0xde,0x11,0x42,0xf9,0xe8,0x21,0x6d,0x32,0xf6,0x6,0x71,0x90,0x8f,0xab, + 0x9,0x7a,0x50,0xee,0x1d,0x12,0xd0,0x9,0xa6,0x7e,0x8f,0x8f,0x93,0xb3,0x5e,0x20, + 0x45,0x3e,0x31,0x7,0xb7,0x9a,0x28,0xa4,0x4c,0x1f,0xaa,0x3d,0x2f,0xba,0xe8,0x38, + 0xb4,0x3a,0xa7,0xd1,0x4c,0xf7,0x5a,0xf2,0xf5,0x6a,0x3,0x89,0x1e,0x61,0x29,0xe3, + 0x1f,0x5b,0xea,0x56,0x75,0x93,0xfb,0xc1,0x32,0x26,0xfe,0x62,0xe0,0xe8,0x1a,0x16, + 0xa2,0x41,0xe7,0xee,0xb8,0xc2,0x62,0xaf,0x2d,0x65,0x39,0xca,0x46,0xe2,0xae,0xe5, + 0xbd,0x1a,0x3c,0x33,0xad,0x38,0x74,0x5f,0x5f,0xf2,0xc1,0xbf,0x5b,0xdc,0xd5,0xfd, + 0x9d,0x3e,0xed,0x57,0x1,0xcf,0x7,0xad,0xb4,0xbf,0x78,0x7a,0xa2,0xa7,0x60,0x60, + 0xc1,0x9d,0x93,0xee,0xd5,0x87,0x4e,0xb4,0x7b,0x90,0xf4,0xd6,0x6d,0xca,0xd5,0x8a, + 0x88,0x43,0xe1,0x9,0x92,0xe8,0xb6,0x47,0x29,0xaf,0xc1,0xcb,0x57,0x23,0x2d,0x19, + 0x40,0x40,0x87,0x95,0x48,0xd5,0x4b,0xc3,0x66,0xbf,0x9a,0x53,0xa,0xef,0xde,0x93, + 0xb2,0x40,0x9c,0x45,0xa9,0xd3,0xc,0xd2,0x83,0x4e,0x9e,0xda,0x71,0x4b,0xf3,0x31, + 0xc,0xfa,0xc6,0x54,0xd0,0x91,0x97,0xb7,0x51,0x32,0x8a,0x5c,0xa2,0x69,0x6f,0x55, + 0x2a,0x8b,0x9b,0xd3,0x5f,0xa7,0xa6,0xe2,0xf5,0xc4,0xbd,0xe6,0x90,0x31,0x18,0x1c, + 0x2c,0x5f,0xef,0x7d,0xf0,0x87,0x35,0xc2,0xb9,0xbf,0x9e,0xdb,0xa9,0xe,0x32,0xd3, + 0x99,0xcd,0xa7,0xf9,0xf4,0xcd,0xdc,0x6b,0x12,0x1b,0xd1,0x22,0x4c,0x6a,0x3e,0xf8, + 0xc9,0x2e,0x76,0x3a,0xb5,0x2b,0xfc,0xef,0xea,0x9b,0xcb,0x14,0x29,0x7d,0xe7,0xc3, + 0xca,0xf,0x3d,0xc0,0x5c,0x99,0xab,0xee,0xb4,0x7d,0x11,0x81,0x67,0x50,0x7a,0xb0, + 0xfd,0x70,0xeb,0x34,0x9b,0x68,0xa3,0x6,0x5,0xee,0x1b,0x2e,0x6d,0x82,0x71,0x38, + 0x92,0x2e,0x78,0x6e,0xc8,0x24,0x5d,0xfc,0x22,0x6f,0xfd,0x89,0x3f,0xf7,0xba,0xbc, + 0xe7,0xa6,0xf0,0x83,0xf,0x94,0x8a,0x93,0x84,0x25,0x42,0x71,0xa7,0x33,0xa9,0xb9, + 0x62,0x23,0x29,0xaa,0x47,0x86,0x27,0xe8,0x75,0xa5,0xf2,0x34,0x9d,0xad,0xf1,0x86, + 0x54,0xe2,0x89,0xe2,0xf7,0x93,0xf6,0xfb,0xb8,0x39,0x6d,0x61,0x6c,0x17,0x9a,0x4e, + 0x3a,0xc3,0xf8,0x2,0xca,0xa0,0xea,0xbf,0x46,0xdd,0xf4,0xe3,0xb,0xe6,0xe9,0xde, + 0x49,0xf3,0xc2,0x41,0x87,0x39,0x3d,0x41,0xf1,0x2a,0x22,0x5e,0x42,0x3c,0x2d,0xfb, + 0x1,0xa5,0xfd,0x4b,0x46,0x69,0x8a,0xc,0xc6,0x7f,0x70,0xd2,0xe5,0x5a,0xb1,0xaf, + 0xcd,0xf3,0x70,0x56,0xac,0x2e,0x17,0x9e,0x58,0xb8,0x7d,0x9a,0xf4,0xaa,0x97,0x75, + 0xcf,0x15,0x40,0x17,0xfd,0xcb,0x23,0xc5,0xca,0x13,0x18,0x31,0xed,0x49,0xe0,0xbb, + 0xbd,0x51,0x12,0x6a,0x7f,0x29,0xa,0xd8,0x61,0x87,0xf2,0x57,0xb1,0xa,0x4c,0x81, + 0x9f,0x8d,0x18,0x9d,0xd8,0xbb,0x63,0xa3,0xce,0xfa,0xd4,0xbc,0x45,0x35,0x79,0x82, + 0x87,0x8b,0xec,0x86,0x35,0xf6,0xde,0x96,0xfd,0xd2,0x6d,0xaf,0x5c,0xba,0x32,0xfb, + 0xc7,0x4a,0x9a,0xa0,0x6,0x7d,0xc3,0xd5,0xf8,0x19,0x92,0x3e,0xcd,0x8b,0xc0,0xd4, + 0x18,0x2d,0x5c,0xcc,0x25,0xba,0x63,0xa2,0x8d,0x51,0x53,0x6a,0x8b,0x5,0x66,0x53, + 0x4f,0x80,0x73,0xd5,0xfe,0xb6,0x2b,0xf7,0x4f,0x3d,0xb5,0x1e,0xc9,0xf5,0xf2,0x61, + 0x23,0xce,0x2e,0xc7,0x8a,0x11,0xea,0x97,0x62,0x3e,0x2,0x6d,0xc2,0xe8,0x40,0x91, + 0x69,0x33,0x67,0xe7,0xea,0x92,0x5f,0xb9,0x50,0x15,0xd7,0x1a,0x8a,0x4b,0x7b,0x2e, + 0x1a,0xa9,0x75,0x24,0x3a,0x60,0xbc,0x1d,0x1e,0x3e,0x8a,0xe0,0x27,0xcb,0x73,0x91, + 0xfe,0x5a,0xf8,0x69,0xed,0x59,0x24,0xbd,0x6e,0x7b,0xd7,0x79,0x46,0xd2,0xa7,0x61, + 0xfb,0x1d,0x5,0x36,0x7e,0x41,0x53,0x1c,0x80,0xde,0xfd,0xa7,0x2a,0xf0,0xb8,0xa8, + 0x4b,0xb2,0x13,0xb8,0xc,0xb6,0x76,0xf9,0x32,0x4e,0x73,0xf8,0x21,0x9a,0x5a,0x1d, + 0x38,0xde,0xd3,0x36,0x21,0x27,0x52,0xa1,0x85,0x50,0xc8,0x2f,0x41,0x2,0xd8,0xd, + 0x34,0xeb,0xc5,0xbf,0x22,0x3d,0x39,0xd3,0xb,0x2d,0xcc,0xac,0xc7,0xa6,0xc9,0x0, + 0x86,0x1d,0xb5,0x27,0xc4,0x9,0xc8,0x4a,0xd8,0x11,0x7a,0x9a,0x92,0xd2,0xa7,0x46, + 0x3e,0x6d,0x6,0x60,0xaa,0x40,0x34,0x36,0xec,0x81,0xe2,0x34,0x28,0x2c,0xb4,0xae, + 0x4a,0x6a,0x55,0xf,0x73,0x1e,0xd8,0x4d,0xaf,0xd2,0xe7,0xc1,0xa5,0xf,0x9,0xe3, + 0x7c,0xf,0x44,0xa7,0xce,0xf8,0xdd,0x3b,0x7a,0xc0,0x70,0xa2,0x6c,0x25,0xd1,0xb6, + 0x8f,0x27,0x45,0x4,0xc5,0x1f,0xd0,0xf4,0xf1,0x38,0xb6,0x18,0x47,0x3f,0xfb,0xc3, + 0x4f,0xc0,0xea,0x9d,0x39,0x48,0xd9,0xb3,0x9,0xc9,0xd5,0xf5,0xee,0x27,0xac,0xfd, + 0xce,0xf2,0x81,0x14,0x91,0x52,0x88,0x3,0xa,0x3f,0x1b,0x51,0x7f,0x97,0x95,0x4e, + 0xd7,0x80,0x6b,0x11,0xc9,0xc4,0x44,0x52,0x8e,0x99,0x48,0xfc,0x41,0x75,0xfb,0x10, + 0xe7,0x7d,0xa3,0x79,0x50,0x2c,0xfb,0x5a,0xea,0x97,0x2c,0xe9,0xae,0xc1,0xb7,0x86, + 0xc1,0x24,0x17,0xb,0x68,0xda,0xdd,0xf7,0x74,0xa5,0x74,0xb5,0x1b,0x70,0x45,0x82, + 0x6e,0xe8,0x7b,0xbe,0x15,0x78,0x19,0x80,0x8f,0xc4,0x6a,0x3e,0x86,0xa2,0xc4,0xc8, + 0xc6,0x5b,0xd3,0xae,0x36,0x31,0x26,0xaa,0xd7,0x9b,0xe0,0x72,0xc,0x26,0x75,0x7a, + 0x10,0xf0,0xb8,0xa4,0xe8,0x52,0x25,0x78,0x17,0x10,0xb6,0x1e,0xb2,0xfa,0xe6,0xf8, + 0x56,0x3a,0x27,0x8c,0x6c,0x4e,0xb7,0xc3,0xe9,0x98,0xb5,0x75,0xbe,0x2b,0x70,0x4e, + 0x1d,0x29,0xf3,0x6,0x7b,0x98,0x7f,0x13,0x28,0x36,0x31,0x5a,0x32,0x97,0xd2,0x8, + 0xd1,0xfa,0x95,0xbd,0xc8,0xcc,0x81,0xb2,0x65,0x38,0x28,0x24,0x63,0x18,0xf2,0x0, + 0x42,0x66,0x7,0x3d,0x7e,0x6,0xcf,0xa7,0xbb,0x1,0x81,0x6d,0x98,0xd4,0x76,0xea, + 0x4f,0x8b,0xa8,0x18,0x58,0x2b,0xca,0xbd,0xe2,0x72,0x61,0xc5,0x8b,0x54,0xc6,0x4d, + 0x3a,0xcd,0x8a,0xb9,0x53,0x5b,0xe0,0xf,0xdb,0xe1,0x7d,0xf4,0xb6,0x73,0xdf,0x6, + 0xfe,0x88,0x1e,0x57,0xb3,0x68,0x94,0x16,0xdb,0xf5,0xdc,0x67,0xca,0xa3,0x34,0x5, + 0xf0,0xbe,0x3e,0x44,0x99,0x1f,0xd2,0xf5,0x2,0x50,0xea,0x38,0xc3,0xca,0x3f,0xc2, + 0xd2,0x5d,0x99,0x87,0xc6,0x2e,0x9d,0x22,0xa4,0xf9,0x9,0x6f,0x9d,0x3d,0xf3,0x8e, + 0x7b,0x33,0x52,0x95,0xd1,0x26,0x8b,0xd3,0x76,0xf5,0x8c,0xba,0xc0,0xcb,0xfc,0x93, + 0xa8,0x97,0x9a,0xee,0x45,0xb8,0x11,0xe9,0xb2,0x99,0xd8,0xd0,0xd6,0xcd,0x5f,0x53, + 0x80,0x32,0x68,0x52,0x58,0xf3,0xa6,0x4e,0xe9,0x33,0x9,0x2a,0x7e,0x86,0x3d,0x27, + 0x9d,0x58,0x96,0xe2,0x90,0x27,0x4d,0xc2,0xc1,0xa5,0x93,0x98,0xf2,0x73,0x6b,0x73, + 0xa5,0xd3,0x46,0xfd,0x47,0x6c,0x4c,0xb0,0x1f,0xd5,0x5a,0x9d,0xdb,0x18,0x44,0x79, + 0x70,0xda,0xdb,0x80,0x82,0x29,0x43,0x44,0xcf,0xd7,0x5c,0xc2,0x4b,0xc8,0xb6,0xf0, + 0x1c,0x7c,0x6e,0xe3,0xe8,0x3a,0x94,0x8,0x8f,0x6f,0x25,0x6b,0x87,0xe8,0xe4,0x77, + 0x44,0x41,0xf7,0xc6,0x6a,0x3b,0xb,0xb9,0x92,0x67,0xfc,0x5d,0xaf,0x33,0xcd,0x4c, + 0xaf,0x3c,0x30,0x18,0x77,0x44,0x9f,0x7,0xb3,0xc4,0xf2,0xba,0x2d,0xd7,0x32,0x71, + 0x19,0xa9,0x38,0x4,0x65,0x43,0x3d,0xf7,0x2b,0xb9,0xd5,0xda,0xec,0xa3,0x27,0x1c, + 0xe0,0xd6,0x34,0xd7,0x1c,0x53,0x5e,0x4f,0x97,0x51,0xb,0xc5,0xa9,0xbc,0x37,0x42, + 0xe6,0xef,0xc5,0x4c,0x33,0x4,0xc3,0xdd,0x3d,0x99,0x39,0xaa,0x3e,0xdf,0xc6,0x9e, + 0xb7,0x7b,0x76,0x53,0xce,0x54,0xa2,0x67,0xa6,0x2d,0x2d,0xcf,0x6a,0xe3,0x12,0x51, + 0xd3,0xd8,0x1d,0x87,0x5c,0x60,0x65,0x99,0x7a,0x1e,0x44,0xb8,0xfe,0x8b,0xd6,0xb6, + 0x7,0xcc,0xa,0x55,0x21,0x2c,0xbc,0x47,0xd9,0x69,0x17,0x44,0xcd,0xa9,0x15,0xa1, + 0x2,0x32,0x29,0xdd,0x92,0xf,0x77,0xd,0x2d,0x3c,0x45,0x2c,0x47,0x9b,0x62,0x4e, + 0x68,0xeb,0x23,0xa,0x98,0xe0,0x51,0x72,0xc9,0xe8,0xb6,0x97,0x12,0xcb,0xb9,0x14, + 0x7d,0x62,0xf1,0x8f,0xf0,0xe8,0x1d,0x9e,0xa4,0x62,0x4a,0xeb,0x7e,0xad,0xb9,0xe6, + 0x19,0xdd,0xf0,0xb1,0xbe,0xc2,0xa3,0x8,0x2b,0x5a,0x20,0x3d,0xa5,0x59,0xd0,0xa2, + 0xbb,0x42,0x33,0xad,0x2b,0x50,0x4c,0xd0,0x32,0x96,0x3c,0xb0,0xc3,0xf6,0x18,0xdd, + 0xd4,0x88,0xf,0x13,0x4b,0xb3,0x1b,0xf5,0x8d,0xba,0xb2,0xb3,0x14,0x83,0x56,0xd0, + 0xc5,0x9,0xfd,0x71,0xd8,0xc9,0xc1,0x8b,0x60,0xfd,0x3c,0xa4,0xf4,0xd3,0x2,0xc9, + 0x5d,0x11,0xdc,0x28,0x44,0x78,0x1f,0xd2,0x33,0xd1,0x6,0x48,0xd5,0x5c,0x98,0x9b, + 0xe5,0x16,0x8c,0x3e,0xdf,0x4e,0xc9,0xbf,0x4d,0x86,0x64,0x42,0x5a,0x66,0xd,0xb7, + 0xf7,0x69,0x60,0x3c,0xe1,0x7f,0xf,0x16,0xd0,0x15,0xdd,0xa6,0xf1,0x76,0xc2,0x57, + 0x8c,0x4f,0x95,0xeb,0x9e,0xdf,0xab,0xeb,0x66,0x11,0xad,0xc0,0xf6,0xba,0xf8,0xee, + 0xa4,0x59,0x2c,0x86,0x58,0xba,0x9c,0x29,0x50,0xf9,0x50,0xc1,0xef,0x13,0x19,0xfb, + 0xe1,0x2e,0xe7,0x80,0xe,0x94,0xeb,0x74,0x25,0x1a,0xb5,0x1c,0x54,0x2e,0x8b,0xf8, + 0x7,0xb7,0x80,0x5f,0xf1,0x9c,0x8,0x42,0x97,0x58,0x83,0x7,0xea,0x9c,0x4,0xcd, + 0x4b,0xeb,0xcd,0x59,0x0,0x3a,0x4e,0xa4,0x54,0x83,0x41,0xa8,0xb1,0xcc,0x22,0xb8, + 0x4,0xa2,0x18,0xf5,0x3f,0x9f,0xb8,0x56,0xf8,0x3c,0x5e,0xe3,0x59,0xe1,0x31,0xa4, + 0x4d,0x7f,0x7d,0x4e,0xb9,0xcb,0x72,0x8d,0x4f,0xb3,0xb5,0x80,0x80,0xd7,0x39,0x84, + 0x7a,0xd0,0xfa,0x3a,0x71,0x33,0x10,0xe9,0x6f,0xed,0x4d,0x48,0xcf,0x7f,0x6c,0x1e, + 0x7e,0xea,0xeb,0x38,0x36,0x5e,0x45,0x6,0x13,0xfa,0x86,0x13,0xd3,0x40,0x18,0xcd, + 0x90,0x13,0x8,0x81,0x46,0x19,0x6b,0x35,0x7,0x39,0xfd,0x57,0x38,0x6a,0x75,0xb6, + 0xd4,0x61,0xee,0xc,0x3f,0x34,0x12,0xd1,0xae,0x18,0xe5,0x82,0x58,0xfd,0x51,0xe9, + 0x90,0xd8,0xea,0x56,0x71,0xd6,0xb,0xf8,0x10,0x88,0x50,0x48,0xf3,0x45,0xfe,0xc8, + 0xa6,0x6d,0x54,0x65,0x21,0xe5,0x38,0xcf,0xfe,0x9d,0xd2,0x57,0x1b,0x24,0xc0,0xab, + 0x7c,0x2c,0x81,0xee,0x3,0xc,0xe7,0x13,0x95,0xb7,0x5b,0x89,0xfc,0xd9,0xd1,0x23, + 0xc6,0xa6,0x88,0xe7,0x8c,0xc0,0x37,0xb,0xdd,0xa,0x63,0xf8,0xad,0xa3,0x24,0x2b, + 0xcf,0xa5,0x1a,0xd2,0x32,0x81,0x65,0xc7,0x39,0x40,0xd0,0x36,0x1a,0x22,0x59,0xe0, + 0xc8,0xe1,0x48,0xd5,0x23,0x80,0xe0,0x80,0x8a,0xc3,0x7a,0xb8,0xe7,0x9e,0xe3,0x37, + 0xc4,0xfd,0x8a,0xf6,0x7f,0xef,0x3e,0x38,0x31,0xf,0x6e,0xca,0x31,0xc7,0x2c,0x7a, + 0x29,0x74,0x50,0xcb,0xf4,0xb0,0x4d,0x0,0x75,0x47,0x38,0x5d,0x65,0x1c,0x14,0x2a, + 0x99,0x9e,0xa0,0x19,0x8f,0xde,0xd0,0x40,0x6d,0x3f,0xb,0x9f,0x86,0x37,0x99,0x2f, + 0x2c,0xe9,0x7b,0xa0,0x1a,0xc8,0x20,0x8f,0x8f,0x58,0x6c,0xf4,0x74,0x1,0x9f,0xe, + 0x9f,0xbf,0xa6,0xae,0x9f,0x77,0xee,0xd,0xb6,0x7a,0x2c,0xbc,0x31,0xc5,0xec,0x5d, + 0x2f,0x68,0xfe,0x4a,0xb0,0x1f,0x59,0x40,0x78,0x46,0xb4,0xec,0x47,0x54,0x7b,0x66, + 0x94,0x22,0x16,0x34,0x9a,0x5,0xc0,0xd0,0xfe,0x6d,0xe,0x31,0x33,0xfa,0x8e,0xe2, + 0xe2,0x8d,0xac,0x93,0x2d,0x85,0x53,0xa5,0x4b,0x8,0x12,0x12,0xdc,0x8d,0x79,0xf0, + 0xb0,0x8f,0xa4,0xca,0x14,0x65,0x1b,0x14,0x52,0x29,0xc4,0x86,0xa3,0x53,0xe8,0x86, + 0x61,0x95,0x99,0x8e,0x9a,0xec,0xb3,0xe6,0x75,0xc5,0xf8,0xd1,0x54,0xf1,0xc2,0x84, + 0x1,0x67,0xce,0x16,0x4c,0x69,0xa9,0x9f,0x93,0x6e,0xa5,0xb6,0x41,0x8e,0x3e,0x22, + 0xa3,0xd7,0xb0,0xbd,0x45,0xe3,0xa4,0xba,0xaa,0x1e,0xc,0x7e,0x8f,0xce,0x3,0x91, + 0xb5,0x51,0xa7,0x2,0xba,0xd0,0x21,0xcd,0xbe,0xc6,0x5,0x0,0xd4,0x43,0x23,0x78, + 0x9a,0x53,0x37,0x5f,0x38,0x5b,0x99,0x62,0xf8,0xa5,0xe0,0x89,0xf3,0x63,0x1b,0xa9, + 0xb4,0x42,0x2c,0xee,0x13,0x4d,0x3d,0xd1,0x15,0x42,0x51,0xe9,0x5,0x74,0xe2,0x9f, + 0x48,0x99,0x7f,0x0,0x74,0x19,0x62,0x6e,0xbf,0x43,0x77,0x33,0x26,0x92,0x5d,0xda, + 0x54,0x89,0x49,0x67,0x56,0x86,0xb8,0xea,0x48,0xa,0x55,0x4d,0xfe,0x38,0x6d,0xc6, + 0x51,0xec,0xc6,0xc5,0x6,0x29,0xb3,0x45,0xeb,0x2b,0x79,0x12,0x3d,0xd6,0x6c,0x91, + 0x60,0xb5,0x78,0x36,0xbc,0x31,0x22,0x5,0xbb,0x77,0x53,0x3a,0x2f,0x40,0x1,0x0, + 0x2d,0xc7,0xc5,0x33,0x70,0xf9,0x79,0x5c,0xa4,0xf2,0x6e,0x62,0x49,0x5a,0x73,0x29, + 0x10,0xec,0x5f,0x4c,0x9d,0x1,0xd1,0xd8,0x78,0x25,0x13,0x27,0xe4,0x93,0x27,0x12, + 0x5b,0x6d,0xc4,0x4b,0x67,0x3e,0xa7,0x8b,0xb0,0x95,0xed,0x79,0xef,0x62,0xa2,0x80, + 0xce,0x3,0x4c,0xeb,0x4,0x1e,0x45,0xfc,0xc2,0xd7,0x24,0xa7,0x6c,0xcb,0xb9,0x47, + 0x39,0x7f,0x93,0x20,0x3d,0xba,0xab,0x6e,0x51,0x1a,0xe7,0xc0,0xfb,0xb,0xc0,0xca, + 0xe,0xe,0x36,0x91,0x2c,0xfa,0xe,0x6f,0xd3,0xb2,0x17,0xbf,0x7e,0x51,0x7,0x37, + 0x50,0x9a,0x57,0x8d,0x56,0x3,0x7b,0x27,0x1d,0x64,0xe7,0x19,0x6f,0x29,0x63,0xfc, + 0xb6,0x1a,0xe,0xe2,0x94,0x9c,0xd1,0x68,0x4f,0xe9,0x28,0x4d,0x3b,0x30,0x84,0xb, + 0x4a,0xdb,0x98,0x20,0x5e,0x94,0x47,0xfb,0xf8,0xaf,0x94,0xe7,0xd8,0x78,0x64,0x8f, + 0x12,0xf1,0xf1,0xa6,0x8e,0xc4,0x8f,0xdd,0x2e,0xb7,0x2b,0xe8,0x67,0x2f,0xf3,0x32, + 0x8a,0xc,0x52,0xe9,0xa0,0x9a,0x65,0x99,0x4a,0xf9,0x1,0xa2,0xf1,0xe4,0xb1,0x4, + 0xd7,0xa3,0x2b,0x66,0xe7,0xba,0xc4,0x16,0xf1,0x6f,0x7e,0xd9,0x9f,0x72,0xc,0x2a, + 0x7f,0x5e,0x93,0x20,0x78,0xf8,0x3a,0x42,0x73,0xba,0xe4,0xe4,0xa0,0x96,0x69,0xf7, + 0xba,0x94,0xdd,0xa2,0x4f,0xa2,0x39,0x41,0x92,0xb7,0x1b,0x32,0x2b,0xa6,0xdb,0x2a, + 0x6,0xef,0xc9,0xfd,0x68,0x4,0x41,0x5b,0x3f,0xa5,0x41,0x5f,0x3d,0xaa,0x57,0x77, + 0xbe,0x35,0x1a,0xe,0x58,0xd2,0xce,0xea,0x8b,0x6a,0x9c,0x36,0x11,0xf7,0xdf,0x96, + 0xe7,0xa9,0x95,0x51,0x2e,0xd6,0xac,0x6d,0xfb,0x6d,0xcc,0xb8,0x97,0x24,0x30,0x56, + 0xd8,0xca,0xe3,0x31,0x9d,0xb3,0x9b,0xa8,0x1e,0x38,0x5e,0xae,0xb0,0x3e,0x46,0x98, + 0xe8,0xdb,0x69,0x17,0x32,0x96,0x4,0x2e,0x4,0xd0,0x67,0x1c,0x74,0x97,0x72,0xcc, + 0x62,0x57,0x7e,0x80,0x8a,0x1a,0x29,0x28,0xd2,0x88,0xd6,0x83,0xc6,0x1d,0x9b,0x2f, + 0x78,0x6,0xc5,0x2a,0x9c,0xc9,0xd8,0x20,0x1a,0x40,0x3c,0xe,0xd7,0x2f,0xdb,0xba, + 0x6,0x5a,0x3b,0x10,0x74,0x64,0x38,0xc6,0x6c,0x8e,0xc9,0xb3,0xac,0x66,0x62,0xa4, + 0xeb,0x29,0x4f,0x88,0x72,0x28,0x28,0xd,0xe7,0xe4,0x1b,0xbf,0x14,0x76,0xf9,0x99, + 0xd0,0x35,0xa9,0xc5,0x1a,0x61,0x8c,0x6,0xef,0xd6,0xb9,0x1c,0x3d,0x9c,0xc1,0x29, + 0xc5,0x11,0x31,0xb7,0xb8,0xd8,0x44,0xa0,0xbd,0xdf,0xdf,0x51,0x56,0xda,0xea,0x28, + 0x8f,0x14,0xed,0xa9,0xf4,0xf9,0x30,0xe5,0x50,0xe9,0x2,0x8d,0x6,0x43,0x36,0xcb, + 0x54,0xe6,0x4,0x8c,0xc0,0xc7,0x2d,0xfd,0xa7,0xe,0x50,0xfe,0xe8,0xba,0xa6,0xf7, + 0x4f,0x14,0x22,0x44,0x8d,0x52,0x2a,0xde,0xbb,0xac,0xeb,0xc2,0xef,0x23,0xe,0x45, + 0x89,0x91,0x51,0x4a,0x5a,0x7f,0x49,0x81,0x8d,0x19,0x0,0xf5,0x53,0xa6,0x6d,0xa2, + 0x3a,0x8f,0xe7,0xc8,0xe1,0x91,0x27,0x9e,0x3e,0x13,0xe0,0x2f,0xb5,0xee,0xf3,0x40, + 0x81,0x45,0xa,0x5b,0xc4,0xd2,0xdc,0xd1,0xeb,0x5d,0x47,0x40,0x83,0xb5,0x62,0xbe, + 0x45,0xc9,0x7,0xa7,0x5c,0x2e,0xc5,0x9a,0xc0,0xa6,0x49,0x77,0x15,0x3d,0xb7,0x96, + 0x3,0xc1,0x71,0x47,0x15,0xce,0x1a,0x1,0x2c,0xe0,0xc0,0xaf,0x96,0xa3,0xed,0x5c, + 0x6d,0x74,0x83,0xc9,0xa2,0x49,0xe4,0x64,0xef,0xad,0x5b,0x5,0xeb,0x13,0x1c,0x6e, + 0x54,0xd,0xb5,0x69,0xdb,0x4f,0xea,0x87,0x31,0x2b,0xb7,0x47,0xce,0x25,0x23,0xbc, + 0x9a,0xa6,0x6,0x3d,0xef,0xea,0x21,0x5f,0x99,0x7c,0xe4,0x5,0xf,0x80,0x73,0x64, + 0x8d,0x29,0x4d,0xe9,0x79,0xb7,0xf0,0x2a,0xe3,0x28,0x71,0x32,0x4e,0x95,0xee,0xe8, + 0xbb,0x75,0xa5,0xac,0x60,0x47,0x8b,0x79,0xc3,0x70,0x7e,0x53,0xf0,0x71,0x37,0xfe, + 0x1b,0x84,0x68,0x14,0xbc,0x59,0x3e,0x20,0x82,0xaf,0x52,0x50,0xc4,0xc1,0x39,0x81, + 0x37,0xde,0xad,0x17,0x26,0x39,0x11,0x6a,0x2a,0xf,0x3d,0x9a,0x81,0x74,0x19,0x1c, + 0x78,0x81,0x30,0x35,0x5b,0x6e,0x55,0x5d,0x9d,0x28,0xad,0xe2,0x69,0x66,0xe3,0x20, + 0xc4,0x91,0xb6,0x6b,0x4a,0xc7,0xd5,0xf3,0xd7,0x13,0xf,0xd8,0x7,0x28,0xf4,0x7f, + 0xaa,0x25,0x35,0x85,0x93,0x8a,0x62,0xb0,0x32,0x8f,0x93,0x1b,0xf5,0x77,0x3b,0xba, + 0x88,0xf2,0x26,0x53,0x3a,0x7b,0xc6,0x12,0xe,0xd5,0xea,0x15,0xfe,0xdf,0x15,0x29, + 0x5,0x4a,0x2e,0x18,0x54,0x90,0xc9,0x87,0x20,0xdc,0xa2,0x16,0xd4,0x5e,0x50,0x5d, + 0xd0,0xf6,0x30,0xb,0x72,0xf7,0x1e,0x1,0xcd,0x88,0x16,0x4c,0x69,0xaa,0x75,0xed, + 0xf4,0xa3,0x86,0x4a,0xb3,0xcf,0xd1,0xd3,0xac,0xf3,0x69,0x81,0xd1,0x3a,0x5f,0xa2, + 0x31,0xf,0xae,0x23,0x7,0x4c,0x24,0x55,0xd4,0xba,0xa1,0xbd,0x65,0x97,0x2c,0x5b, + 0xba,0xb2,0x25,0x6f,0x2,0xf6,0x43,0xae,0x6a,0x2d,0xb0,0xbc,0x67,0x8f,0x5f,0x98, + 0x9e,0x8d,0x3b,0x26,0x59,0x60,0xfa,0xae,0x9a,0x1c,0x6c,0x7f,0xb3,0x18,0xda,0x6f, + 0x4a,0x0,0x5e,0x4c,0x76,0x21,0x7b,0x61,0x4e,0x2c,0x1e,0x35,0xbb,0xfc,0x4d,0xd9, + 0x8b,0x89,0x0,0xe4,0x69,0xfa,0x93,0x4,0x18,0x80,0x83,0x4b,0x18,0xde,0x3a,0x63, + 0x5e,0x98,0xaf,0x55,0xba,0x2b,0xb6,0x88,0xd6,0xd4,0xbe,0x12,0x51,0xc,0xec,0xdc, + 0x95,0x6c,0x42,0x7e,0xe7,0x55,0x82,0x0,0xd5,0x86,0xca,0x6e,0xe4,0x6,0xd1,0x43, + 0x1e,0x1,0x98,0xd8,0xac,0xce,0xe1,0x3,0x23,0xa0,0x16,0x75,0x2c,0x82,0x52,0xc2, + 0xee,0x94,0x41,0xd6,0x6a,0x44,0x56,0xbf,0x4a,0x22,0x2e,0x2f,0xa7,0x0,0x72,0xc5, + 0x81,0x8b,0x1f,0x2e,0x5a,0x1,0x31,0x7e,0xa1,0xc6,0xf3,0xcd,0x49,0xc5,0x10,0xb8, + 0xda,0xd1,0x8f,0x45,0x16,0x66,0x5,0xdf,0x8,0x34,0xf,0xaf,0xb3,0x1,0x75,0x35, + 0x8c,0x94,0xe2,0x67,0x95,0x15,0x65,0xb6,0xdb,0x59,0x5,0xa5,0x9e,0x15,0x5e,0x79, + 0x66,0x6d,0x3e,0x7c,0xd3,0x44,0xdb,0xdb,0xf7,0xea,0x8b,0x2b,0x6c,0x81,0x61,0xf8, + 0x16,0xc3,0xdf,0x2c,0xd8,0x45,0xe2,0x35,0x1e,0xe7,0x5a,0xbd,0x7d,0xb8,0x37,0xe3, + 0x26,0xf5,0xe0,0x7a,0x3a,0xbc,0x56,0xb1,0xa8,0x62,0xdc,0x15,0xe3,0xbd,0x8d,0x79, + 0x82,0xed,0xa5,0xda,0x33,0x89,0x8f,0x52,0xf0,0xe9,0x10,0x6e,0xa2,0xc6,0x53,0x49, + 0xbc,0x34,0xc3,0x76,0xf0,0x99,0xa7,0x19,0x7b,0x85,0xad,0xde,0xc2,0xbb,0x59,0xc4, + 0xa9,0xfe,0xa0,0x5c,0x8,0xaf,0xae,0xf9,0x9a,0x3e,0x68,0xbc,0x6,0x3b,0x6,0x42, + 0x6f,0x49,0x39,0xe0,0x63,0xe0,0x79,0xde,0xe5,0x28,0xbe,0x29,0x63,0x97,0xed,0xd, + 0x16,0xe,0x69,0x1f,0xbe,0x98,0x98,0xd8,0xd6,0x80,0x95,0x5c,0xbc,0x1c,0x1f,0xab, + 0xe4,0x58,0x8c,0x48,0xb8,0x7,0x28,0x1f,0xae,0x66,0x48,0x12,0xfd,0x36,0x9e,0x14, + 0xc4,0x87,0xb2,0x83,0x20,0x4b,0x5c,0x77,0xcc,0x71,0x53,0x9,0x8d,0x72,0xb4,0x73, + 0x4a,0xc1,0x3b,0x83,0x48,0x63,0xa2,0xf6,0x49,0x6a,0x88,0xc6,0x20,0xa6,0x5b,0xe4, + 0x2e,0xe,0x68,0xce,0xd9,0x44,0x46,0x26,0xb6,0x19,0x2f,0x44,0xc,0x63,0x37,0x56, + 0xa4,0x73,0x59,0xec,0x56,0x7b,0x63,0x20,0xe5,0x6b,0xe6,0x7,0x12,0x42,0xeb,0x41, + 0xd0,0xd4,0x8f,0x2a,0x98,0xd5,0x50,0x4f,0x6e,0xfe,0x14,0x7a,0xe1,0xca,0x51,0x87, + 0x3e,0xaa,0xf3,0x15,0x27,0xd7,0x35,0x8c,0xc2,0x9b,0x93,0xd5,0x5e,0x0,0x96,0x2f, + 0x54,0x26,0x59,0xec,0x7b,0x29,0xbc,0xe9,0x28,0x50,0x65,0x89,0x1b,0x36,0x90,0xd9, + 0xe0,0x85,0xee,0x87,0xdc,0x24,0x15,0x9f,0x3f,0x28,0xf4,0x9d,0xa7,0x8b,0xcc,0xfb, + 0x31,0xa5,0x69,0xac,0xce,0x26,0x17,0x76,0xf5,0xfb,0x1,0x11,0x32,0x91,0xea,0x13, + 0x96,0xd9,0x1b,0xf2,0x7d,0xaf,0x93,0xbd,0xd7,0x8,0x5b,0x0,0x14,0xa8,0x7b,0x45, + 0xcd,0xe4,0x72,0x1d,0x8a,0x9,0x93,0x80,0x5,0x14,0x92,0x37,0x26,0xfc,0xc9,0x3c, + 0x57,0x64,0x30,0xd4,0x14,0x43,0x12,0x6c,0x4b,0xed,0x6c,0x5f,0x16,0xe7,0x25,0xe3, + 0x4d,0x17,0x80,0xd7,0x20,0x15,0xd8,0x25,0xa8,0xea,0xdb,0x4e,0xe7,0xa5,0x8b,0x3f, + 0xb,0xbb,0x94,0x9e,0x7e,0x26,0xb,0xc9,0x93,0x77,0xa9,0xa9,0xdf,0x4e,0xe,0x2d, + 0x65,0x8e,0x84,0x85,0x23,0x5d,0x2a,0x4c,0x48,0x6,0x9a,0x31,0x2b,0x26,0xef,0xb5, + 0x61,0x84,0x55,0xdf,0x2b,0x60,0x2a,0xbe,0x58,0x53,0xe8,0x38,0xa1,0x76,0xe4,0x86, + 0x84,0x69,0xc,0x28,0xc7,0xb5,0x74,0x10,0xbb,0xf,0xc0,0xe6,0xb5,0xb1,0x9d,0x96, + 0xb5,0xf2,0x77,0x60,0xd2,0x21,0x20,0xaa,0x74,0x88,0x62,0x16,0xfe,0x47,0x9c,0x3, + 0xb1,0x28,0x2b,0xf8,0xdd,0x9f,0x88,0x19,0x2f,0xc9,0x7f,0x64,0xfa,0x9c,0xfa,0x30, + 0xf,0x72,0x91,0xe2,0x93,0xb1,0x8d,0x87,0xb9,0x70,0x1d,0xb8,0xb7,0x39,0xbb,0xe8, + 0x61,0x67,0x61,0xbe,0x7,0xea,0x57,0xb5,0x34,0xd7,0x1a,0x2f,0x74,0x16,0x5f,0x84, + 0x8,0xf0,0xe6,0x1c,0x22,0xf3,0xa3,0xdb,0x64,0xc1,0x14,0x1d,0x7a,0xd0,0x85,0xdc, + 0x38,0xe7,0x1b,0xbe,0x52,0x73,0x75,0x86,0xca,0xf,0xb5,0x3f,0xa4,0x15,0xc3,0xad, + 0x86,0x2a,0x49,0xa8,0x1f,0xec,0x85,0x83,0x2e,0x99,0xa0,0xa9,0xe9,0xa6,0x6,0xa1, + 0x8e,0xa0,0x61,0xe0,0x14,0x56,0xe6,0xde,0xe4,0x9c,0x9e,0x8a,0x31,0xe1,0xb7,0xb7, + 0xd,0x1,0xe0,0x2c,0x6d,0x66,0xaf,0x1c,0x7f,0xd0,0x45,0x6a,0xf6,0x4b,0xc,0x85, + 0x6b,0xec,0xe5,0x0,0xc2,0x4c,0x5e,0x28,0xe8,0xfc,0xb2,0x99,0xdf,0x6a,0xd1,0x6c, + 0xea,0xb2,0x18,0x58,0x98,0x47,0x74,0x18,0x97,0xb9,0x2,0x8e,0x84,0x8e,0x14,0xf0, + 0xfa,0x79,0xf0,0xbe,0xc5,0x4f,0xe6,0x2e,0xcc,0x19,0x48,0x2c,0x3,0x1a,0x98,0xed, + 0x4c,0x30,0x46,0x64,0x77,0x3b,0x7c,0x10,0xf4,0xfe,0x9e,0xf9,0x8d,0x33,0x6a,0x88, + 0x2c,0x5b,0xc6,0x72,0x2a,0x2d,0xa0,0xf6,0xc5,0x68,0xa2,0xc8,0x82,0x3b,0xb6,0x4e, + 0xea,0xfd,0xb2,0x63,0x39,0xaf,0x73,0xad,0xae,0x91,0x27,0xbb,0x44,0x91,0xc3,0x71, + 0x6c,0xb,0xe3,0x17,0x38,0x4,0xe,0xfe,0x6d,0x31,0xc7,0x6f,0xeb,0xfe,0xbe,0xd7, + 0x7c,0xf0,0x3b,0x35,0x20,0x2e,0xe2,0xce,0xbf,0x8a,0xa,0x5,0x1c,0xce,0xf5,0x9, + 0xd9,0x59,0x20,0x91,0x5d,0xad,0x10,0xca,0xde,0x58,0xba,0xcb,0x57,0xf8,0xa3,0xd3, + 0xe9,0xde,0x9,0xb,0x8c,0x6b,0x59,0xcb,0xf5,0xe3,0x50,0x92,0xb2,0x46,0x9b,0xc, + 0x9f,0xbb,0x9d,0x7d,0xe8,0x2e,0x48,0xc8,0x86,0x82,0x94,0xdd,0x7b,0xb7,0x31,0xe5, + 0x16,0xb9,0x70,0xa2,0x25,0x49,0x6e,0x9b,0x2d,0xbf,0xad,0x5f,0x85,0xc8,0x6b,0x26, + 0x4,0x89,0xa3,0xec,0xb7,0x6b,0xb5,0xbd,0xee,0xc9,0x1b,0xe9,0x81,0x4c,0xcf,0x97, + 0x6,0x40,0xb9,0xaa,0x8a,0x29,0xc5,0x37,0x68,0x73,0x97,0xed,0x3c,0x3,0x93,0x40, + 0xc,0xb6,0xad,0x43,0xa2,0x63,0x1,0x11,0x2e,0x1c,0xfa,0x2f,0xe7,0x4b,0x47,0xed, + 0x8b,0x1,0x19,0x95,0xa9,0xde,0xcd,0x91,0xd2,0xe4,0x80,0x8e,0xe7,0x93,0x4f,0x74, + 0x4b,0xfc,0xb7,0x6d,0xdf,0x39,0x7e,0x8d,0xd4,0xf8,0xbd,0xbd,0x44,0x84,0x2b,0x50, + 0x85,0xc3,0xe5,0xaf,0xa3,0x33,0x41,0xf5,0x18,0x41,0x84,0x80,0xd5,0x53,0x74,0xa0, + 0x50,0xab,0xe,0x31,0x64,0x8c,0xbe,0x3a,0x85,0xfb,0x77,0x4a,0x80,0x22,0x9a,0x86, + 0xe6,0x0,0x36,0xa,0xb3,0x77,0x0,0xcb,0xb9,0x4,0xcb,0xf,0x58,0xbf,0xaf,0xa8, + 0x6c,0xbd,0x59,0xd0,0xc9,0x98,0xb,0xce,0x94,0x2,0x19,0x95,0x25,0x33,0x1c,0xc, + 0x34,0x52,0x95,0xe7,0x49,0x95,0x33,0x82,0x19,0x7f,0x91,0x71,0x3f,0x41,0x9a,0xab, + 0x7e,0x73,0xfc,0xc7,0xc,0x87,0x17,0x21,0x8a,0x30,0xb6,0x2f,0xe3,0x52,0x3b,0x18, + 0xa4,0xd0,0x7f,0x6d,0xe5,0x32,0xf0,0x7e,0xb1,0x2,0xf0,0xf1,0xc3,0xb,0x1d,0xc1, + 0x7e,0x99,0x8a,0xb,0x22,0xa1,0x2c,0x2c,0x51,0x62,0x5b,0x35,0xb4,0x96,0xcc,0xd8, + 0xe6,0x4c,0x46,0x4c,0x7f,0xb6,0xca,0xb0,0x39,0x3b,0x22,0xfc,0xc5,0xbf,0x3e,0xc4, + 0x59,0x48,0xcf,0x7b,0xe9,0x7b,0xa7,0xbb,0xdd,0x82,0x70,0x92,0x19,0x3e,0xea,0x7f, + 0xa,0xb0,0x4b,0x9,0x68,0x17,0x3a,0x21,0xd1,0x5c,0x9d,0x98,0x1c,0xdb,0x5d,0xf5, + 0x25,0xac,0xf0,0x8e,0x28,0x19,0x4a,0x85,0x9b,0xbb,0x18,0x35,0x79,0x82,0xb4,0x3, + 0x33,0x80,0xd,0x1b,0x17,0x47,0x3c,0xe8,0x23,0xd9,0x1,0xbf,0xb6,0xdd,0xb5,0x5b, + 0x8a,0xa6,0xe9,0xb2,0x3f,0xb4,0x38,0xdb,0xef,0xcf,0x11,0x69,0x52,0x45,0x6c,0x6, + 0xc5,0xf8,0x21,0xdc,0x40,0x5e,0x46,0x64,0xb7,0x47,0x24,0xed,0x26,0x59,0x49,0xb0, + 0x7f,0x34,0xe3,0xbf,0xe8,0x9b,0x9b,0xd8,0xeb,0x2c,0xc1,0x3e,0x71,0xad,0xc3,0xb7, + 0xa7,0xe5,0x94,0xe7,0xc3,0xda,0xcb,0x7b,0xa2,0x6f,0x6a,0xc8,0x48,0xb3,0xf8,0xc8, + 0x67,0x5c,0x88,0xcf,0xf8,0x24,0x28,0xe4,0xcf,0xe9,0xa2,0x41,0x98,0x67,0xf8,0x40, + 0xcc,0xe,0xa7,0x90,0x68,0xf3,0xc,0xb,0xe2,0x76,0x53,0xab,0xaa,0x4d,0x74,0x12, + 0xa9,0x7c,0xe2,0x22,0xa0,0xb,0x7,0xef,0x75,0x2a,0x31,0xe,0x91,0xaa,0xcd,0x5e, + 0xb8,0xf4,0xee,0x21,0x68,0x7a,0x2d,0x4c,0xf1,0x80,0xf7,0x9c,0x4d,0xeb,0x2e,0x77, + 0x68,0x11,0x99,0x88,0x9c,0x21,0x78,0x12,0x4b,0xa9,0x9f,0x5c,0x54,0x6d,0xba,0x8c, + 0xe1,0x29,0xae,0x4b,0xa3,0xdb,0x17,0x15,0xdb,0x8e,0x31,0x2a,0x7a,0x60,0x21,0xe2, + 0x71,0xba,0xea,0x8d,0xdb,0x63,0x9f,0xa6,0x8c,0x3f,0x3,0x61,0x2c,0x3d,0xed,0x8e, + 0x66,0x9c,0xd9,0x8a,0xf7,0xf0,0x9f,0xd4,0x7f,0xd1,0x7e,0x79,0x32,0x9f,0x5c,0x23, + 0xd9,0x47,0xb1,0x36,0x2a,0xd0,0xdc,0xb6,0x90,0xe0,0x18,0x3c,0x1e,0x86,0xca,0x5, + 0x23,0xa4,0x8f,0x9b,0x15,0xae,0xef,0x14,0x0,0x6e,0x8d,0x32,0x8d,0x69,0xd5,0xe6, + 0x30,0x87,0x1d,0x5a,0x58,0x7a,0x91,0x68,0xda,0x29,0xa5,0x78,0xaf,0x70,0xfc,0x53, + 0x95,0x8c,0xee,0x2a,0xbb,0xde,0x3f,0xbb,0xcc,0x4c,0x6e,0xd9,0xb6,0x44,0x40,0x66, + 0x4b,0x5e,0x41,0x23,0x58,0x52,0x8c,0xb2,0x7b,0x32,0x2b,0xab,0xa2,0x29,0x7e,0xb7, + 0x35,0xec,0xe2,0xf0,0x4b,0x22,0x2d,0x18,0xed,0x9b,0x71,0x24,0xdf,0xb1,0x8b,0x2b, + 0x8f,0xcc,0xcd,0x67,0x1f,0x5a,0x1a,0x1a,0x8c,0x46,0x45,0xaf,0xee,0xc3,0x67,0x24, + 0xb0,0xc9,0x95,0xfb,0x6b,0xc2,0x93,0x5a,0x5e,0x84,0x7e,0xbd,0x37,0xa,0x68,0x46, + 0x56,0x36,0xae,0xf4,0x91,0xc8,0x8f,0x9d,0x8e,0xd4,0xcc,0xfc,0x19,0xb4,0x22,0xc9, + 0x7e,0x37,0x46,0xea,0x79,0x59,0xc4,0x57,0xde,0x43,0x15,0x95,0xcd,0xfc,0x5b,0x24, + 0x33,0xa,0x1a,0x44,0x53,0x29,0x62,0x61,0xfd,0xae,0x5f,0x17,0x63,0x1,0x61,0x62, + 0xb7,0x27,0xcc,0x31,0x80,0x91,0x88,0xde,0xd4,0x1d,0x74,0xa2,0x1a,0xd0,0x47,0xcc, + 0x5a,0xe0,0x91,0x2d,0xa,0x73,0x8f,0x8,0x22,0x6e,0x9f,0x86,0x6f,0x1,0x68,0x27, + 0x28,0x35,0xd7,0x28,0xc6,0xdf,0x8,0x1b,0xfc,0xfb,0x3e,0x96,0xcc,0x85,0xe2,0xa7, + 0xe5,0x74,0xd4,0xef,0xe7,0x64,0x77,0x8a,0xd2,0x17,0x90,0xc1,0x97,0xf8,0xe8,0x3f, + 0xad,0x40,0x68,0xf3,0x20,0xef,0xf,0x1d,0xeb,0xcc,0x33,0x39,0xd1,0x17,0xe0,0xb7, + 0xb,0xb5,0xa7,0x73,0x1b,0x9f,0xfd,0x6d,0x36,0x8e,0x30,0xce,0x87,0x98,0x8d,0x35, + 0xd9,0xf5,0x29,0xf9,0x65,0xb7,0x97,0x52,0x85,0x4a,0x8b,0xd6,0x61,0x6c,0x8f,0xec, + 0xa1,0xb6,0x60,0xbc,0x56,0x5e,0xaa,0x8d,0xec,0xda,0xdb,0xf3,0xf2,0x69,0xa8,0xcc, + 0xdf,0x51,0x47,0x45,0x9,0x5e,0x97,0xe,0xa8,0xa2,0xe5,0x8a,0x8e,0xf4,0x77,0x31, + 0xab,0xd7,0x6d,0x82,0x36,0x18,0x8f,0xa2,0x72,0x6b,0x96,0x66,0xd4,0x3f,0xb2,0x34, + 0x90,0x79,0x7a,0x19,0xd7,0x91,0xa7,0x1,0x35,0x8d,0x8b,0x43,0x2,0x3,0x74,0xad, + 0xda,0x62,0x30,0x90,0xf9,0xbf,0x33,0xec,0xaa,0xc9,0xd2,0x0,0x88,0x85,0x34,0x98, + 0x7f,0x2e,0x31,0x57,0xc0,0xd8,0xd7,0x75,0xe5,0x63,0xb8,0xe7,0x66,0xad,0x16,0xc0, + 0x8f,0x46,0x51,0x89,0x86,0x84,0x76,0x31,0xcd,0x49,0x31,0x56,0x4f,0xe5,0x6e,0xce, + 0x14,0xa0,0xa5,0x54,0xf8,0x7e,0xc9,0xdf,0xe1,0x3,0xc7,0xc8,0x30,0xdd,0x89,0xbf, + 0xa4,0xdb,0x49,0xaa,0xdf,0x40,0xdb,0xae,0x89,0x8d,0x84,0x58,0x73,0x73,0x27,0x7, + 0x14,0xcd,0x5c,0xd,0xcb,0x26,0x6c,0xad,0xa8,0x35,0xf5,0xd8,0x92,0x80,0x98,0xb6, + 0xdb,0x62,0x61,0xbb,0xa2,0xbd,0xe9,0xab,0x4b,0x6f,0x5,0x3e,0xe2,0x2c,0x45,0x76, + 0x79,0x21,0x83,0xc4,0xc7,0xf0,0xf2,0x70,0xa5,0xe8,0x4a,0xb7,0x69,0x62,0xee,0x45, + 0xc4,0x50,0x81,0xe6,0x8d,0x6b,0x93,0xd8,0x5a,0x18,0x96,0x3d,0xc3,0x5c,0x33,0x3e, + 0x7d,0x37,0x3,0x45,0xa7,0xf5,0xb6,0x4d,0x5f,0x80,0x84,0xc8,0xe2,0xf2,0x8e,0x28, + 0x44,0x8f,0x8e,0xd1,0xfa,0x22,0x2b,0x56,0xb9,0xc1,0x13,0x7e,0x1e,0xc6,0xbc,0x1c, + 0xfd,0x3f,0x61,0xa5,0xb5,0x18,0x72,0x15,0x18,0x76,0x5d,0xfb,0x6a,0x6b,0xa3,0xae, + 0xfa,0x32,0x0,0x76,0xd4,0xaa,0x4c,0x8e,0xec,0xde,0xd,0x8a,0xa5,0x49,0xa6,0xa3, + 0x9,0x9,0x49,0xbe,0xa0,0x3b,0x53,0xb9,0xb2,0x30,0x35,0x1d,0x9c,0xd8,0x4b,0x17, + 0x8a,0xca,0xd,0x5f,0x76,0x59,0x6e,0xe2,0x39,0x7b,0x6d,0x5e,0xc5,0x15,0x82,0xce, + 0x9d,0xcb,0xd,0x3e,0x87,0xdf,0x77,0x3a,0x10,0xac,0xd6,0x2c,0x5,0x22,0x44,0x90, + 0xec,0x51,0x6f,0xe2,0x2b,0xdd,0x45,0xe3,0xd9,0xb3,0x42,0x1f,0x48,0xc4,0xed,0xe5, + 0x11,0x7a,0xa3,0x18,0x5a,0x1c,0x52,0x6a,0x48,0x29,0x17,0xcd,0xca,0x5b,0xdd,0x37, + 0x2c,0x4d,0x9a,0xd6,0xab,0xdf,0xba,0x85,0x93,0x7d,0xa4,0xdb,0xc1,0x12,0x41,0x52, + 0x8c,0xe5,0x6a,0x66,0x81,0xbc,0x50,0xc9,0x65,0x67,0x17,0xaf,0x42,0xf4,0xe7,0xee, + 0x43,0x2,0xc5,0x6e,0xe1,0x1,0xf3,0xf5,0x7e,0x18,0x51,0xbf,0x2a,0x93,0x13,0x36, + 0xf8,0x7d,0x1c,0x7a,0xba,0x6c,0xc3,0x9f,0xd4,0xdb,0x50,0x96,0xd0,0xb7,0x85,0x93, + 0xb9,0x4c,0x2,0x9b,0xcc,0x75,0x91,0x4b,0xd,0xe3,0x8a,0x37,0xf6,0x9d,0xec,0xef, + 0x1c,0x9,0x6a,0xd6,0xf5,0xad,0x76,0x4a,0x89,0x46,0xe0,0xda,0xfd,0xe6,0xed,0xb7, + 0xb2,0x70,0xd3,0x7f,0xe5,0x65,0x4a,0x73,0xc8,0xd4,0xaa,0x3f,0x73,0x18,0x2f,0xf, + 0xa0,0x19,0xe5,0x96,0xc7,0xdb,0xe0,0xd0,0x23,0x42,0x2b,0xa0,0x29,0x1a,0x59,0xdb, + 0x8a,0x2d,0xda,0xef,0x12,0x25,0x63,0x5b,0xf9,0x8e,0x9a,0xec,0x26,0x4a,0xfb,0xc6, + 0xe2,0x61,0xdd,0x2a,0xbd,0x3e,0x7b,0xe0,0x0,0xa6,0x1,0xa8,0x40,0x5a,0x84,0x4a, + 0x7,0xde,0xba,0x99,0x4,0x9d,0xf4,0x7e,0xab,0xf,0xea,0xd1,0xd8,0xe7,0x19,0xbc, + 0xc8,0x76,0xe6,0x86,0xb4,0x62,0xe6,0xb5,0x89,0xe8,0x5e,0xc9,0x43,0x63,0x94,0xca, + 0xc1,0x4f,0x64,0xc6,0xec,0xd8,0xc4,0x99,0xe7,0xaf,0xea,0xc1,0x17,0x4,0xfd,0x60, + 0xf9,0xe4,0xe6,0xaf,0xc7,0xce,0xe4,0x51,0x37,0xc2,0x9a,0xf9,0xa5,0x2f,0xc4,0x68, + 0x7e,0x29,0xae,0xeb,0x2,0xf2,0x5,0x6a,0x22,0xef,0xab,0xb9,0x74,0xa9,0x1a,0x6e, + 0xe,0x1,0x9d,0xd5,0x4f,0x2,0xa6,0x86,0x45,0x42,0x81,0xea,0xf0,0x46,0xd2,0xef, + 0xef,0x1,0x5b,0x71,0xf3,0x60,0x5b,0x17,0xcf,0x7,0xd0,0x44,0x30,0xea,0x33,0x3f, + 0x6b,0x50,0x94,0xbb,0x53,0x3c,0x42,0x98,0xfd,0x43,0x3,0x6e,0xa,0xd6,0x5e,0xf9, + 0xd7,0xb9,0xea,0x4c,0x99,0x47,0xe2,0x6a,0xcd,0x33,0x2e,0xfe,0x9d,0x61,0xbd,0x9, + 0x32,0x52,0x44,0x85,0xe,0x87,0x1e,0x8b,0x4a,0xa0,0xfa,0x54,0x77,0xd8,0xcd,0xcf, + 0x13,0xb9,0x9b,0xac,0x80,0x7e,0x96,0xcd,0x31,0xc5,0x4c,0xce,0xa6,0xa,0x57,0xd8, + 0x5d,0x9c,0xdd,0xea,0xa3,0x7b,0x77,0xed,0x1d,0xf1,0x43,0x14,0xca,0x11,0xe3,0x5d, + 0x4a,0xfe,0xb,0x4a,0xfc,0x21,0x19,0x2e,0x66,0x65,0xfc,0xe,0x70,0x55,0x66,0x4d, + 0xf1,0xc4,0x38,0x95,0x40,0x2f,0x3,0x5d,0x21,0x46,0x72,0x6c,0xd7,0xd5,0xc9,0x22, + 0xd5,0x54,0x6d,0xd2,0x76,0x6,0x81,0xdc,0x6b,0xfd,0x6a,0x5b,0x53,0x51,0x28,0xc4, + 0x16,0xe0,0xd9,0x56,0x10,0xdd,0x34,0xb1,0xa3,0xa6,0x1e,0x7b,0xfb,0xe7,0x9e,0x51, + 0x3d,0x8b,0xa4,0x33,0x11,0x26,0x10,0x7c,0x24,0xfa,0x58,0xf7,0x4c,0x80,0x3c,0xe1, + 0x61,0x96,0x38,0xf1,0x74,0x6c,0xa3,0x97,0x92,0xc1,0x14,0xf,0x29,0x32,0x60,0xe5, + 0x3d,0x84,0x98,0x4e,0xaa,0x29,0x4a,0x4f,0x24,0xa2,0xc6,0xef,0xa3,0x3,0xd1,0x5, + 0x99,0xa,0x76,0x8d,0xf6,0x1a,0x26,0x9,0x5b,0x3a,0x97,0x5,0xeb,0xf8,0xea,0x29, + 0x7d,0x4,0x77,0xa8,0x2d,0x41,0x77,0x51,0xe4,0x3e,0x41,0x88,0x41,0x92,0xd,0xdb, + 0x1c,0x84,0xe8,0x13,0x1e,0xf,0x9c,0x7a,0xc8,0x34,0xfe,0xb4,0xac,0x69,0x5d,0xaa, + 0x6d,0x54,0xd2,0x9a,0x96,0x4a,0xeb,0x7b,0x88,0xac,0x83,0x49,0x3f,0x10,0x25,0x5c, + 0x14,0x8e,0xee,0x33,0x9d,0xb,0x2d,0xe6,0x40,0x2c,0x1b,0x6c,0x95,0x79,0x17,0x4, + 0x4d,0xe9,0x9e,0xe3,0x34,0xb,0xde,0x3c,0x37,0xe1,0x86,0xf6,0xf2,0x2b,0xd2,0x7, + 0xb9,0xc1,0x3a,0xd7,0xcd,0xe6,0xbe,0x8d,0x13,0x59,0xf9,0x29,0xd2,0x91,0xac,0xa0, + 0x7b,0x4b,0x84,0x30,0xd5,0xe3,0xeb,0xe,0xc5,0x72,0x84,0xb8,0x9e,0x57,0x40,0xd7, + 0x98,0xf9,0xaf,0xe5,0xe1,0xed,0x73,0x74,0xc7,0xed,0x9d,0x9a,0x7f,0x4a,0xba,0x7a, + 0x16,0x40,0x2a,0xeb,0x24,0x17,0x79,0x69,0x9,0x7d,0x23,0x27,0xd4,0x63,0x0,0x6e, + 0xdc,0x2f,0x54,0xbe,0x9d,0x48,0x34,0x65,0x36,0x51,0x7f,0x35,0x9c,0x3b,0x2f,0x32, + 0xfa,0xd9,0x9d,0x9e,0x70,0x18,0x8,0x79,0x15,0xaa,0xa1,0xea,0x8d,0xa1,0x59,0x6b, + 0x50,0x2d,0x2a,0xed,0x75,0xdd,0x53,0x2b,0x30,0x53,0xdf,0xcc,0x8e,0x10,0xfe,0x89, + 0x69,0x9c,0x28,0xd9,0x34,0xaf,0x53,0x4a,0x5b,0x74,0xb4,0xe8,0x95,0x8d,0x54,0xe6, + 0xba,0x7f,0x54,0xb0,0xdc,0xa8,0xdb,0xd,0x7b,0xbc,0xd9,0xa,0x4c,0x58,0x13,0x35, + 0x75,0xba,0xf,0x29,0x6a,0xe1,0xf2,0xc5,0x57,0xa7,0xaf,0xec,0x35,0x4,0xd3,0x70, + 0x3,0x29,0x21,0x60,0x51,0x7c,0x6d,0xcc,0xb8,0xc7,0x56,0x84,0x20,0x69,0xb9,0x15, + 0x24,0x48,0x3f,0x8e,0x2b,0xb1,0xd4,0x82,0x5a,0x84,0xee,0xf,0x8,0xc3,0xfe,0x8b, + 0x6c,0x9f,0xeb,0x3d,0x1d,0x59,0x89,0x55,0x21,0xdf,0x5a,0xc1,0x49,0x14,0x56,0xec, + 0xdc,0x15,0xfa,0x8,0xc7,0xcf,0xa,0x22,0x54,0x78,0xb0,0xdc,0xbb,0xb0,0x68,0x28, + 0xcf,0xd3,0xe4,0x6c,0x2d,0x6e,0xc2,0xce,0x4e,0x1d,0x10,0x17,0xb0,0xe5,0x4,0xd, + 0xfb,0x0,0x15,0xc3,0x4f,0x9e,0x65,0xa4,0x18,0x95,0x1,0xd3,0xc5,0x69,0x7c,0x96, + 0x3d,0x61,0x3,0xe9,0xd0,0x45,0x38,0x9e,0xe1,0xc7,0xb6,0x13,0xae,0xba,0x20,0x2a, + 0x3a,0x36,0xed,0x8a,0x54,0xd2,0xae,0xeb,0x68,0xaf,0xc0,0xae,0x98,0xbc,0x45,0x55, + 0x1e,0xc7,0xbe,0x6e,0xe,0x77,0xe,0xef,0x3f,0xc4,0x3,0x6d,0xfe,0x24,0x97,0xb9, + 0xd9,0x5,0xc3,0xad,0x57,0x72,0x9a,0xc0,0xa1,0xda,0xee,0x3a,0x97,0x34,0xf,0x35, + 0xfb,0xcd,0xa4,0x89,0x45,0x32,0xf9,0x5,0xf6,0x7c,0x72,0x75,0x20,0x8a,0x2f,0x79, + 0x8f,0xf2,0x28,0xe7,0xe4,0xc2,0x28,0x86,0x1d,0x17,0x40,0xb4,0xca,0x4f,0x69,0x46, + 0x1e,0xe,0x50,0x63,0x40,0x4a,0x68,0xb6,0xc6,0x5b,0x2d,0xe7,0xe5,0xdb,0x61,0xf4, + 0xcf,0x9,0xdc,0xb4,0x4b,0x84,0xbb,0x68,0x1b,0xfb,0x9c,0x65,0x4c,0x7,0xac,0x6a, + 0x15,0xfc,0x4d,0xd5,0xc6,0xb6,0xc,0x8d,0x91,0xb8,0xf4,0x77,0x95,0xd6,0x6c,0xe4, + 0xdf,0xc9,0x19,0xab,0xcd,0xd4,0x14,0xe9,0xd1,0xb1,0x4f,0x1e,0xb8,0x7b,0x8,0x4d, + 0x78,0x55,0xa2,0x3f,0x8b,0xaf,0x4d,0x1d,0xe7,0xc1,0x14,0x7d,0x98,0x81,0x62,0xf8, + 0xca,0x7c,0x24,0x98,0x51,0x38,0x2,0xa2,0x69,0x52,0x40,0x22,0x4d,0x48,0xef,0xc6, + 0x9e,0x92,0x85,0xa9,0xc1,0xd2,0xc7,0xaa,0x15,0xdb,0xa7,0xad,0xdc,0xb,0x26,0xa7, + 0x7,0x4a,0xc0,0xd7,0x3,0xc2,0x7b,0x6c,0x94,0xbb,0xf,0xe2,0x84,0xfe,0x29,0x23, + 0x11,0xae,0xcc,0x53,0x2,0x14,0x7d,0x17,0x70,0x25,0x44,0x4d,0xaf,0xea,0x75,0x36, + 0xb4,0xb5,0xf,0xb7,0x78,0xa,0xa4,0x8d,0x45,0xb3,0x70,0xc9,0xb2,0x99,0x6c,0x43, + 0xc7,0xb9,0x96,0xc9,0x4d,0x14,0x60,0xbd,0xb9,0x25,0x8b,0x69,0x10,0x80,0x20,0x44, + 0x36,0x2f,0xfc,0x2e,0xb8,0xa1,0xbb,0xfd,0xd4,0xab,0x48,0x7,0x45,0x34,0x4a,0x8d, + 0xed,0x61,0xd6,0xbb,0xf4,0x38,0x79,0xae,0xdc,0x84,0x98,0xec,0x5,0xb8,0x31,0x3b, + 0x67,0xad,0xe9,0x20,0xce,0xa5,0x9d,0xa3,0x52,0x65,0xaa,0x17,0x9a,0xf5,0xa4,0x8, + 0xd6,0xfb,0x43,0xcb,0x34,0xbd,0x7b,0x11,0xc1,0x93,0x7d,0xc7,0x4c,0x2e,0x82,0x33, + 0x5c,0x6c,0x53,0x2b,0x13,0x70,0x4f,0xe4,0x56,0xf9,0xfb,0x70,0x6f,0x21,0xf7,0x46, + 0x1d,0x3c,0x13,0xd0,0x79,0xe,0x61,0x3b,0xa1,0x5e,0x3,0x6d,0x8c,0x86,0xa0,0xe8, + 0x72,0xf3,0x94,0x5,0xe3,0xe3,0xe9,0x3a,0x5d,0x66,0x2a,0xcd,0x7,0x23,0x93,0xa3, + 0x5f,0xa6,0x74,0xd8,0x34,0x55,0x14,0xd5,0xb3,0x18,0x43,0xbf,0x1e,0xe3,0x29,0x90, + 0x57,0xbd,0x96,0xbb,0x21,0x0,0x75,0x7e,0x66,0xa0,0x4c,0xec,0xc3,0xe0,0x90,0x23, + 0x7,0x84,0x7b,0xbb,0xd9,0x8f,0x11,0x8d,0x27,0x55,0xcd,0xc4,0xb8,0xf6,0x56,0x90, + 0xb4,0x6c,0x4c,0x55,0xeb,0x41,0xd3,0xd2,0xe1,0x21,0xbf,0xa5,0x81,0x51,0x48,0x8, + 0xd5,0xc3,0x43,0xb0,0xd3,0x55,0xbd,0xfa,0xaa,0x8b,0xc0,0xe2,0x2,0x96,0xf2,0x36, + 0x82,0xbe,0x8b,0x6e,0x1,0x60,0x41,0x62,0x1,0x2,0x9,0x2,0xd2,0xd0,0x89,0xa8, + 0x15,0xcd,0xd8,0xe8,0x23,0x17,0x63,0x4d,0x22,0xa3,0xaf,0x25,0xb9,0xa3,0x5b,0xbb, + 0x62,0xe7,0x2b,0xe2,0x48,0xeb,0x46,0xc8,0x6d,0xce,0xca,0x40,0x9f,0x54,0x69,0x34, + 0xa1,0xc1,0x9c,0xc4,0xd8,0x80,0x12,0xfb,0x24,0xc2,0xa0,0x5e,0xe5,0xfb,0x1a,0x48, + 0xe3,0xc4,0x2c,0xab,0x31,0xf1,0xf3,0x9e,0xc0,0x3e,0x5f,0xdf,0x93,0xc8,0x15,0xb4, + 0xa,0xb1,0x7a,0xe3,0x32,0x8c,0x5f,0xd6,0xce,0x0,0xb4,0xb4,0x7b,0x4e,0x7d,0xdf, + 0x14,0x29,0xb,0x45,0x1b,0x0,0x63,0xdb,0x3e,0xc2,0xbb,0x51,0x8b,0x50,0x7,0x16, + 0x82,0x81,0x79,0xb4,0x8d,0xd8,0xb,0xdc,0x58,0x3f,0x11,0x53,0x8e,0x8e,0x33,0xa2, + 0xb7,0xbe,0x67,0x52,0xbe,0xca,0xad,0x7c,0x8e,0xe9,0x4e,0x99,0x3a,0x55,0xaf,0xbc, + 0x56,0x29,0xf1,0x63,0x81,0x7c,0xbf,0x59,0xbc,0xd1,0x2d,0x4b,0xdf,0x60,0x6d,0x98, + 0x9e,0xd4,0x6a,0x5d,0x1f,0x19,0x5a,0x2d,0x3,0xa8,0xc7,0x3d,0xfd,0xf6,0x7a,0xd3, + 0xa0,0x6c,0xb6,0xa1,0xe8,0x77,0x7b,0xa5,0xc8,0xa8,0x70,0xa8,0x88,0xdd,0xc0,0x28, + 0xb2,0x2c,0x5,0x52,0x45,0x5f,0x7f,0x48,0x87,0xc6,0x5,0x85,0x3e,0x7f,0xd8,0xde, + 0x6b,0x90,0x0,0xd4,0x87,0xfa,0x7a,0x50,0x23,0xeb,0xf8,0xac,0xc9,0x3a,0x54,0xfc, + 0x66,0xd8,0x4f,0x2b,0x39,0xce,0xf2,0xc0,0x96,0xf7,0xc6,0x54,0xf7,0x1f,0x33,0x63, + 0x2f,0xb2,0x38,0x36,0xae,0x33,0x86,0xd1,0x9e,0x0,0xfd,0xe7,0x3a,0xd1,0xe4,0x20, + 0xab,0xb3,0x4b,0x64,0x3,0x3e,0x25,0x19,0xb5,0x6b,0x6d,0xad,0xb,0x20,0x91,0x3a, + 0xd2,0xc9,0x71,0x1,0x7c,0x77,0xd3,0x1b,0xf6,0x51,0x4,0xb0,0x24,0x68,0xd0,0xcf, + 0x1d,0x9b,0x34,0x20,0xd9,0xd8,0xb8,0x10,0xc4,0x26,0xbd,0xcf,0x46,0x4f,0x89,0x19, + 0x99,0x7a,0x9a,0x16,0x72,0xed,0x32,0x69,0x3f,0xb5,0x1b,0x63,0x1e,0x6b,0xb2,0xba, + 0x8,0xe6,0xda,0x61,0x40,0x93,0x71,0x5,0x39,0xaf,0x54,0x7f,0x7e,0x5d,0x19,0x18, + 0xd8,0xb3,0xae,0x4b,0xa1,0x60,0x34,0xe0,0x16,0x4f,0xc4,0x34,0x3b,0x77,0xef,0x43, + 0xde,0x4a,0x24,0x1f,0x5e,0x16,0xa3,0x97,0xc5,0x77,0x97,0x44,0xd4,0xb0,0xdc,0xad, + 0xe3,0x8b,0x78,0x85,0xeb,0xad,0xe5,0x2,0x7c,0x2a,0xb5,0xb7,0x22,0x25,0x7a,0x1, + 0xef,0x9f,0x9f,0x4e,0xb5,0xc2,0x65,0x7b,0x3a,0x7c,0x3f,0xf,0xac,0x1c,0x3d,0x90, + 0x27,0x35,0x95,0x92,0xe2,0xfb,0x94,0x60,0x26,0xca,0x97,0xc7,0x6f,0x13,0x48,0x5f, + 0x32,0x67,0x2d,0xe7,0x2a,0x13,0xe2,0xe3,0x8f,0xa1,0xf3,0x3d,0x3e,0xb0,0xcd,0x65, + 0xe5,0xe3,0xf8,0x49,0xdf,0xd,0x29,0x85,0x57,0xc0,0x4e,0xc7,0x53,0x96,0x27,0x85, + 0x7e,0xd4,0x6d,0xa8,0xe7,0xcf,0x8d,0xf6,0x72,0x1,0x34,0xb0,0xb1,0x82,0x95,0x17, + 0xe5,0xe,0x60,0xc5,0x1c,0x89,0xca,0x73,0xca,0x98,0xba,0x1e,0xaf,0xe2,0xa4,0x2e, + 0x37,0x91,0xd6,0x1f,0x62,0xe3,0x95,0x54,0xe4,0xca,0x84,0x16,0xcc,0x1a,0xad,0xb2, + 0x29,0xe,0xf7,0xc4,0x18,0xc2,0xb7,0xe2,0x5c,0x73,0x1,0x8b,0xd5,0x25,0xb9,0xd, + 0xb7,0x90,0xab,0x99,0xf4,0x41,0xed,0xd9,0x8b,0x72,0x70,0xd7,0xc,0x1e,0x8a,0xb4, + 0xab,0x2,0x79,0x43,0x45,0x32,0x26,0xa1,0xa5,0xa7,0x2d,0xfa,0x4c,0x66,0x8,0x4, + 0xf6,0x33,0x1d,0xeb,0xf3,0xb,0x46,0x80,0xfc,0x36,0x58,0x89,0x54,0x63,0x3e,0x7f, + 0xe4,0xb8,0xc3,0x2a,0x6a,0x69,0xcb,0x8f,0x90,0x78,0x8a,0xdd,0xde,0x12,0x61,0x56, + 0x45,0x7f,0xc1,0x39,0xa,0x87,0x39,0x87,0xbd,0x12,0x11,0x91,0xf4,0x4f,0x12,0xd9, + 0x87,0x55,0x5,0x71,0x3e,0x50,0x1,0xcf,0x49,0xb,0x2d,0xa7,0x1d,0x8e,0x7d,0xe1, + 0x8d,0x40,0x9b,0x18,0xc7,0xd4,0x9f,0x6,0x66,0x30,0x97,0x5b,0xfe,0x29,0xb5,0x87, + 0xfd,0xba,0x78,0x3d,0x8a,0x7a,0x8c,0xd3,0x85,0xb9,0xfb,0x23,0xc7,0x79,0x5,0xd5, + 0xb9,0xa0,0xed,0x2,0xf5,0xd,0x8,0xdb,0x3d,0x1f,0xb7,0x3c,0x49,0x6d,0x43,0x47, + 0xa7,0xbc,0x84,0x32,0xb6,0x90,0x86,0xbb,0x4a,0x82,0xde,0x92,0xfb,0xe4,0x68,0x36, + 0x5,0xd5,0xb7,0x7a,0xe2,0xbf,0x57,0x9f,0xde,0xf,0xdb,0xa7,0xfb,0x9f,0xef,0xa3, + 0xdb,0xf3,0x55,0x92,0x85,0xdb,0x4e,0x4f,0xdd,0xad,0x61,0x5a,0x12,0xc9,0x90,0x17, + 0x9f,0x48,0x92,0x82,0x87,0x69,0x22,0xe5,0x78,0x7e,0x8e,0x74,0x9d,0xfd,0x97,0xf8, + 0x71,0xec,0xb,0xf6,0x49,0xd8,0xc6,0xa6,0x86,0x28,0x1,0x98,0x72,0x11,0xb0,0x91, + 0xd8,0xc2,0x15,0x60,0x2c,0xb6,0xc6,0x24,0xb4,0xd4,0x18,0xd1,0xd2,0xaf,0xca,0x44, + 0x1c,0xd5,0xbb,0x65,0xaf,0x2,0xd,0xb5,0x2a,0xe,0x4f,0x1c,0x9f,0x7f,0xae,0x78, + 0xc1,0x43,0x59,0xed,0x79,0x20,0x91,0x2f,0xf4,0xa9,0x80,0x47,0x59,0x4c,0x8b,0x75, + 0xa1,0x47,0x5b,0xd0,0x49,0x68,0x87,0xf3,0xf5,0xd6,0x10,0x15,0x56,0x3e,0x8e,0x18, + 0x81,0xe7,0x85,0xfb,0x87,0x96,0xaa,0xfb,0x40,0x2b,0x43,0x19,0x77,0x4e,0xe,0x99, + 0x16,0x69,0x6a,0x5f,0x51,0xf1,0xd2,0xc7,0x48,0x63,0xdc,0x1e,0xa1,0xea,0xb5,0x24, + 0x52,0x3b,0x9f,0x59,0x51,0x4a,0x55,0x91,0x75,0x18,0xaa,0x6d,0x67,0x39,0x7,0xfc, + 0x22,0x71,0xdb,0x74,0xe3,0xaf,0xbb,0x2c,0x92,0x18,0x4b,0x34,0x4,0x80,0xd7,0x56, + 0x3c,0x77,0xb0,0x8d,0xc1,0x85,0x20,0xb7,0x1e,0x4a,0x25,0x5,0x83,0xab,0x2,0xa6, + 0x9c,0xdd,0x9a,0x80,0x8d,0x56,0x2d,0x20,0xed,0xf7,0xd4,0xf1,0x78,0x2c,0xc8,0xb4, + 0xa4,0xf8,0x43,0xe5,0xfd,0x63,0x9d,0x1c,0x2d,0x42,0x21,0xb1,0xed,0xa2,0xd7,0x8b, + 0x81,0xf1,0x8b,0x8e,0xc7,0xb8,0x2f,0xb5,0xb0,0x83,0xa8,0x2a,0xaf,0xf0,0x5e,0x54, + 0x69,0xa1,0x3b,0x67,0x84,0x58,0x4,0xb2,0x9b,0xa4,0xe3,0x89,0x48,0xbb,0x94,0xc9, + 0x2d,0x21,0xd7,0xf4,0xd9,0x7,0xaa,0xb,0x8a,0xd2,0xb4,0x3b,0xc3,0x13,0xf,0x2d, + 0x35,0xc9,0x95,0xb9,0x23,0x19,0xeb,0x3e,0xbd,0xcf,0xc7,0x6,0xb,0x5d,0x4f,0x38, + 0xfd,0x28,0x2d,0xd7,0x2f,0xd8,0x62,0x3a,0xab,0x17,0xf4,0xef,0xaa,0x4,0x1d,0xdf, + 0xce,0x32,0x19,0x71,0x4b,0x6,0xaf,0xa,0x55,0xf6,0x8f,0x61,0xd3,0xdf,0x19,0xd1, + 0x8,0xc6,0x2a,0xb6,0x9f,0xc,0x70,0xca,0x24,0x65,0xba,0x4e,0xe9,0x58,0xad,0x38, + 0xa,0x46,0xa9,0xd5,0xcb,0xd8,0x5f,0x22,0xcf,0xee,0x3,0x24,0xce,0x1c,0xf5,0x56, + 0xe2,0x9f,0xe,0x2,0xac,0x7e,0x4d,0x50,0x64,0x8,0x9e,0x4e,0xdf,0xcb,0x86,0x6a, + 0x12,0xaf,0x40,0xde,0x88,0x1f,0x1,0x58,0x8d,0x83,0x7c,0xdc,0x9f,0xf2,0x33,0x3, + 0x92,0xc0,0x84,0x3f,0xbf,0xd1,0x8f,0x24,0x5a,0xad,0xf1,0x3a,0x79,0x78,0x24,0xc, + 0xa7,0xe3,0xea,0x30,0x3,0x6b,0x8,0x11,0xee,0x5,0xed,0xe,0xf7,0x21,0x90,0xa, + 0x62,0x16,0xc9,0x22,0x67,0xd8,0xc5,0xc1,0x7,0xb7,0x7c,0x0,0xaf,0xa0,0xc,0x57, + 0x5,0x76,0x7,0x8,0x61,0xf,0x19,0xcf,0x14,0x86,0x5e,0x8b,0xa8,0xee,0x16,0xb, + 0x84,0x5f,0xac,0xec,0x38,0x72,0x2e,0x3f,0xa9,0xaa,0x40,0x59,0xcb,0xcb,0x30,0xd0, + 0x43,0x37,0x58,0x24,0xc5,0x72,0xf4,0xda,0xf8,0x53,0xe5,0x21,0xc1,0x7b,0xab,0xc6, + 0xda,0x58,0x33,0x14,0x4a,0x61,0xd2,0xf3,0xd,0x92,0xcc,0x58,0x5f,0x7c,0x29,0x22, + 0xb3,0x81,0xc5,0xf9,0x73,0xba,0xd4,0xec,0x8d,0x3a,0x8d,0x50,0xb6,0x3a,0x96,0x91, + 0x12,0xc9,0x25,0x5d,0x2b,0xf8,0xd0,0xb7,0x8b,0x1e,0x8f,0x6a,0x9a,0xb8,0xc,0xce, + 0xba,0xd2,0xc8,0x2e,0xd,0x1d,0x9a,0x9b,0x57,0x29,0x6b,0x8d,0x63,0x2,0x20,0xf4, + 0x4b,0x45,0x52,0x76,0xbd,0xa3,0xae,0xc9,0xc1,0x3e,0xb3,0x5c,0x77,0xc0,0x2b,0x32, + 0x13,0x73,0xdf,0x20,0x90,0x7b,0xbb,0x68,0xa4,0xa6,0xf5,0x87,0x28,0x95,0x7c,0x73, + 0xdb,0x4f,0x6a,0x19,0xf2,0x98,0xe2,0x34,0x56,0x97,0x90,0xcd,0xd7,0x3c,0x7f,0xea, + 0xaf,0x60,0x8a,0xc0,0xdb,0xc6,0x29,0x0,0x6d,0x1f,0x7,0x96,0xb5,0x83,0x89,0x11, + 0x52,0xf3,0xa9,0xc4,0x8c,0xd,0xf8,0xe3,0x24,0xa,0xb1,0xfb,0x46,0xb1,0x66,0x75, + 0x12,0xf0,0xb5,0x6d,0xb7,0xde,0x6d,0xa5,0x7e,0x74,0xbb,0xb3,0x77,0x45,0x44,0xca, + 0x3a,0xed,0xf,0xc6,0xfa,0x9,0x2a,0x1f,0x92,0x5c,0x9a,0xd8,0xe,0x1,0xcd,0x20, + 0x72,0x4,0xd,0xa9,0xe2,0x7a,0x4f,0xe0,0x6e,0xb,0x14,0x65,0xd0,0x58,0xaf,0xb, + 0xc6,0xbf,0x51,0xc1,0x48,0x7c,0x61,0xda,0x58,0x7b,0x33,0x66,0xfc,0x1,0x6,0x6f, + 0x84,0x13,0x19,0x68,0xd,0xe8,0xc8,0xfa,0x73,0xdd,0x60,0x44,0x36,0x11,0xce,0x7c, + 0x50,0x21,0xbe,0x98,0x1d,0x20,0x73,0xf4,0x1b,0xa6,0x5b,0x18,0x27,0xe0,0x87,0xac, + 0x73,0x21,0x94,0x0,0x89,0x5d,0xfa,0xfc,0xba,0xda,0xc1,0x71,0x6b,0x90,0xed,0xbb, + 0x31,0xac,0x54,0xcd,0x4c,0x47,0xc2,0x68,0xed,0x1e,0x80,0x95,0x7e,0x88,0x42,0xf1, + 0x29,0x56,0x71,0xb2,0x33,0xeb,0x2f,0xee,0xc7,0xf0,0x60,0x33,0x82,0xcd,0x6f,0xb3, + 0x7b,0x43,0x82,0xc7,0x8b,0x45,0xaf,0xf8,0xe3,0xb0,0x8e,0xe1,0xb8,0x50,0x54,0xe1, + 0xa6,0xc5,0x14,0x5a,0xb2,0x43,0x49,0xf9,0x35,0x29,0xac,0xb7,0xf6,0x1c,0xea,0x72, + 0x60,0xec,0xba,0x6b,0xb2,0xe9,0x64,0x16,0x9a,0xf3,0xf7,0xd2,0xc3,0x4c,0xb4,0x6b, + 0x92,0xc8,0xc5,0xc4,0x8c,0x8e,0xbe,0xc1,0xb7,0xea,0xf8,0x2e,0x8,0xe3,0x21,0xe7, + 0x51,0x5b,0x53,0x4,0x45,0xb7,0x99,0x60,0x2b,0x91,0x33,0xef,0x5e,0x68,0xda,0x70, + 0xb0,0x20,0x35,0x3d,0x2e,0xf3,0x7e,0xe5,0xde,0x77,0x93,0x66,0xdb,0xb4,0xcd,0x2d, + 0x10,0xa0,0xb0,0xd5,0xd8,0x4a,0x36,0x4,0x5b,0xe8,0x73,0x39,0xd0,0x4e,0xa9,0x82, + 0xed,0xde,0x3f,0x1c,0x52,0xbe,0x81,0xb1,0xb5,0x16,0x18,0x91,0xca,0x66,0x3e,0xdb, + 0x7,0xee,0x31,0xdf,0xb8,0x67,0x64,0x94,0xcf,0xd7,0xcd,0xa1,0xa6,0x78,0xa3,0x14, + 0x57,0x62,0x31,0xaa,0x21,0xb2,0x5c,0x57,0x48,0xf3,0xe8,0x14,0xd9,0x28,0x6f,0xe1, + 0x96,0xa0,0x41,0xcf,0x87,0xa5,0x64,0x57,0xfd,0x32,0x78,0xa4,0xaa,0x1c,0xb8,0x3, + 0x7f,0x69,0x2d,0x20,0x9c,0x89,0x77,0xe4,0xfc,0x61,0xf8,0xd7,0x9,0xe7,0x39,0x1f, + 0x88,0x7a,0xee,0x8f,0xa0,0x53,0xe7,0x1e,0x6,0x60,0x42,0xb0,0xfc,0x7a,0x33,0x7c, + 0xe4,0x60,0x9c,0x81,0x69,0x94,0xe5,0x67,0xf5,0xdf,0xbe,0x7e,0x47,0x77,0x9d,0x50, + 0xf1,0xd,0xdf,0x12,0xdf,0x47,0x30,0xe5,0xa8,0x72,0x97,0x25,0xed,0xca,0xa1,0x52, + 0x2c,0xbd,0x53,0x15,0x52,0x39,0xfb,0xc7,0x19,0xba,0xc5,0xe0,0x32,0xe3,0x31,0xa4, + 0xf0,0x90,0x36,0xd0,0xd8,0x67,0xb7,0x1,0x59,0x4f,0x26,0xc6,0x99,0x47,0x19,0x45, + 0x5,0x6c,0x5b,0xd7,0xa6,0x57,0x1f,0x3f,0x92,0xe5,0x20,0xc4,0xc9,0xd0,0xe8,0xba, + 0x62,0x20,0xb,0x3b,0x7,0xc2,0x3c,0x60,0x91,0xe1,0x28,0x2c,0x29,0xc0,0xf0,0xad, + 0x2e,0x4c,0x85,0x54,0x24,0xa5,0x93,0xb6,0xb,0x34,0x7b,0xd4,0x84,0xe4,0xf,0xe6, + 0x5,0x1a,0xa1,0xc,0x5d,0x5d,0xeb,0xee,0x3f,0x14,0x9a,0x68,0x55,0x8c,0x96,0x3, + 0x58,0x1c,0x57,0x7c,0x41,0x6a,0x33,0xcb,0x1e,0x2f,0x20,0xa3,0x14,0x2f,0x8a,0x19, + 0xc9,0x2d,0xa4,0xa6,0x8a,0x90,0x15,0x4a,0x25,0xb0,0x32,0x7a,0xbc,0xc8,0x7d,0x15, + 0x65,0x54,0x12,0xa6,0xbe,0x45,0x73,0xdd,0x74,0x13,0x1,0x8,0x43,0x8b,0xa0,0x8c, + 0x38,0x45,0xb2,0x43,0xd6,0xc7,0x8d,0xfb,0xf7,0xbf,0xf5,0xb4,0x9,0xf2,0x4a,0x6e, + 0x47,0x5c,0x94,0x6,0x21,0x87,0x63,0x16,0x9b,0x64,0x1e,0x5e,0x70,0xbf,0x6a,0xa8, + 0x84,0x1d,0x6b,0x5b,0xe4,0xf8,0xd6,0x5d,0x39,0x4c,0x91,0x42,0x3f,0xdb,0x30,0x86, + 0xb7,0xc4,0xd,0x59,0x4d,0xef,0x6f,0xe8,0xd4,0xd,0xc6,0x45,0x4c,0x31,0x6d,0xd1, + 0x4e,0xd9,0xac,0xb2,0x52,0x4,0x8f,0x8b,0x50,0x22,0x4d,0x10,0x7d,0x7d,0x16,0x36, + 0xc2,0x23,0xf,0x8f,0x93,0x7e,0x78,0x68,0xb,0xbe,0xad,0x58,0xef,0x9a,0x2a,0xbd, + 0x74,0x56,0xef,0xc7,0x5a,0x80,0xd2,0x2b,0xa2,0xa0,0x3b,0x20,0x9d,0x51,0xd5,0xdf, + 0xf4,0xe4,0x6f,0x88,0xe2,0x67,0x70,0xee,0x26,0x1e,0xc6,0x16,0x38,0xf0,0x53,0xad, + 0xc6,0x44,0xf4,0xa1,0xc4,0x47,0xcc,0xe6,0x67,0x87,0x86,0x6,0x58,0x5d,0xe5,0xcc, + 0xc1,0x56,0xd4,0x25,0xbd,0x45,0x93,0x64,0x63,0x5a,0x7a,0x1c,0xca,0x4e,0xc9,0x91, + 0x92,0x3e,0x33,0xd6,0x5,0x7f,0xbd,0x6d,0x7,0x44,0xf2,0xdf,0x21,0x58,0xac,0xe3, + 0x2e,0x82,0x88,0x6c,0xc7,0x1c,0xd0,0xab,0xf5,0xca,0xc7,0xc0,0x19,0x11,0xd1,0xab, + 0x4f,0x6,0x2,0xd3,0x5,0xbf,0x41,0x8c,0x5,0x34,0x6c,0x26,0xd,0x19,0x89,0x3b, + 0x1b,0x91,0xa7,0x63,0xad,0xf7,0xf,0x23,0xc3,0x56,0xe3,0x5c,0x67,0xb6,0x88,0x36, + 0x3c,0x8a,0xa,0x41,0x4b,0xcb,0xcd,0xcf,0x7f,0xb9,0xf5,0x8c,0x53,0x0,0xc8,0x6e, + 0x91,0xef,0xd1,0xbf,0xe8,0x60,0xe2,0x2c,0xb6,0xc7,0x88,0x9d,0xfd,0x11,0x53,0xb9, + 0x9c,0xdd,0x7a,0xe7,0xa9,0xc8,0xb7,0x29,0x82,0x2d,0x36,0xd5,0xac,0xfe,0xc4,0x3f, + 0x6e,0x16,0xfe,0xd6,0x77,0x61,0x3,0xad,0xa8,0x8c,0xcb,0x26,0x1d,0x1f,0xdf,0xb9, + 0xfc,0x5b,0x21,0xa6,0xa3,0x58,0x50,0x26,0x6,0x86,0x7c,0xb2,0x5,0x41,0xf1,0xf2, + 0xd6,0x70,0xca,0x4e,0xd2,0x4d,0x7c,0xfa,0x59,0x48,0x22,0x77,0xe6,0x2,0x31,0xe4, + 0xdc,0xd2,0xb,0x80,0x2b,0x5b,0x27,0x31,0x61,0xa3,0xe4,0x66,0x64,0x56,0x5a,0x3b, + 0x47,0xa4,0xa,0x1a,0xf1,0x86,0x94,0x4c,0x4e,0xb6,0xc3,0x35,0x39,0x74,0x1a,0x16, + 0xc6,0xa5,0x17,0x72,0x80,0x3e,0x23,0xe2,0x61,0x87,0xc8,0x45,0xde,0xa2,0x80,0x26, + 0x47,0xa,0xbf,0x3a,0x10,0x54,0x6,0x5e,0xc,0x49,0x94,0x45,0x3d,0x2e,0xda,0x5, + 0x53,0x71,0x77,0xd4,0x2f,0x9a,0xb7,0x90,0x23,0x80,0x55,0x81,0x24,0x56,0xa7,0xea, + 0x60,0xe6,0xa4,0x71,0xba,0xaa,0x4f,0x46,0xf3,0x63,0x8b,0x32,0x12,0xe6,0xb6,0x65, + 0x58,0x2e,0x3a,0x8,0x48,0xf1,0x98,0x6b,0xf2,0x6e,0x6c,0x96,0xc4,0x93,0x81,0x25, + 0x7a,0x27,0x16,0x36,0x51,0x66,0x7c,0x46,0xc9,0x88,0xf7,0xdb,0xee,0xae,0xc1,0xc6, + 0x5c,0xfb,0xce,0xa4,0x6e,0xe7,0x90,0x61,0x56,0xfc,0x77,0x1b,0x91,0x78,0xbf,0x8b, + 0x9f,0x56,0x41,0x71,0xbc,0x3e,0x37,0x6,0xc6,0x2f,0x62,0x35,0x5d,0x24,0xfb,0x39, + 0x9f,0xcb,0xdd,0xe,0x33,0xed,0xee,0x89,0x6b,0x66,0x24,0xfc,0xdf,0x63,0x8,0xfe, + 0xb9,0x4a,0x70,0xf5,0x88,0xa7,0xfc,0xce,0x56,0xde,0x4,0x33,0x3,0x7f,0x6c,0xa2, + 0x4b,0xca,0x31,0xfd,0xb8,0x20,0x87,0x24,0x7,0x2b,0xa0,0x66,0x8f,0xa9,0xe4,0xc8, + 0x73,0x56,0xbf,0xfb,0x7d,0xbc,0x4a,0x54,0x1b,0x4e,0x87,0x9d,0xcd,0x74,0xbf,0x99, + 0x3f,0xf0,0x97,0xf7,0x91,0x9f,0x9c,0x98,0x4a,0x3d,0xfe,0x59,0x66,0x63,0x23,0xd9, + 0x39,0xe2,0x55,0xb7,0x1f,0x9f,0x8b,0x3a,0x6d,0x92,0xd7,0x3c,0x7,0x97,0x55,0xc5, + 0x89,0x6c,0x3e,0x1b,0x8b,0xda,0x33,0xd6,0x97,0xb1,0x30,0xfe,0x15,0x53,0x58,0x4f, + 0x36,0xae,0x86,0xd4,0xcd,0x91,0xf,0x3c,0x24,0x66,0xf7,0xab,0xfe,0x4d,0x71,0x8, + 0x39,0xaf,0xa2,0xc5,0xa,0x55,0x9c,0xa2,0x7,0x4c,0x21,0x9b,0x20,0xf8,0xea,0x56, + 0xa7,0xf0,0x2c,0x76,0x82,0xba,0x32,0x27,0x22,0x2a,0xd2,0xa0,0xf6,0x44,0x28,0x30, + 0x74,0xca,0xf5,0xfd,0x20,0x12,0xa0,0xa6,0xde,0x41,0x42,0xfe,0x3b,0xad,0xd4,0x62, + 0x1e,0x80,0x58,0xa1,0x3c,0x8a,0x48,0xdd,0xb4,0x1b,0x7e,0xab,0xde,0xa6,0x5c,0x53, + 0xf0,0xd1,0x52,0x90,0xe4,0x72,0x37,0x43,0x34,0xf8,0x42,0xee,0x26,0x17,0x51,0x45, + 0x98,0xaa,0x66,0x54,0x35,0xae,0x32,0x6a,0x49,0x30,0x95,0x28,0xd6,0xf1,0xfb,0x47, + 0xc4,0xcd,0xd7,0x29,0xbf,0x8e,0x6c,0xf3,0x7,0x2e,0x62,0xad,0x45,0xb4,0xf2,0xdd, + 0xde,0xd8,0x32,0x93,0x7,0xe3,0xfd,0xcf,0x14,0x14,0xf7,0x6a,0x6,0x73,0xb1,0x4a, + 0x41,0x9,0xf2,0x81,0x97,0xde,0xf4,0x1f,0xd,0x58,0xcc,0x53,0xd,0x3f,0xb0,0x6b, + 0x97,0x63,0xfe,0x1e,0x47,0x7d,0xed,0x5c,0x91,0x65,0xc6,0x17,0xd9,0xf8,0xe1,0x9a, + 0x2,0xd4,0x9b,0x1a,0xb4,0x91,0x39,0xc1,0xe9,0x85,0x94,0x76,0x44,0x46,0xe1,0xdb, + 0x29,0x60,0xf9,0x70,0xdd,0x67,0x4c,0xee,0xcc,0x14,0x7,0x26,0xd,0xe8,0x41,0x8e, + 0x3d,0xdc,0xa8,0x71,0xed,0x61,0xb3,0xd7,0xe6,0x48,0xcd,0x2b,0xe,0x2f,0x86,0x37, + 0x90,0x0,0xa8,0x6e,0x67,0x74,0x5e,0xb4,0x88,0xe4,0x5a,0x15,0x4d,0x9b,0xa4,0x8a, + 0xf8,0xcc,0x7c,0xe6,0x2f,0x30,0x3f,0x95,0x78,0xd,0xc1,0x7,0x3d,0xc7,0x3e,0x4d, + 0xc8,0x66,0xbb,0xaf,0xdb,0x99,0x64,0xe3,0xfd,0xbf,0x79,0x4b,0xda,0x1e,0x56,0x53, + 0xea,0xd2,0x3b,0x99,0x3,0xf9,0x30,0xfa,0x86,0x71,0x2,0xc3,0x39,0xc0,0x90,0x81, + 0xa6,0xcc,0x32,0x2,0x66,0x16,0x66,0x65,0x55,0xdf,0x30,0x31,0x7d,0x86,0x4,0xe7, + 0x59,0xbe,0x82,0xdb,0xb8,0x32,0xd7,0x40,0xa3,0x59,0x83,0x5c,0x99,0x15,0xde,0xc0, + 0xe1,0x90,0x42,0xc7,0xa6,0x28,0xac,0xfc,0x8,0xdd,0xad,0x5,0xe3,0xb1,0xed,0xbd, + 0x71,0xef,0x99,0xa9,0xa1,0xf0,0x69,0x45,0xca,0xed,0x21,0xe3,0x82,0x0,0x24,0x64, + 0x90,0xe6,0xab,0x38,0xf,0x59,0xb4,0x97,0xb6,0x62,0x9c,0x9a,0x14,0xa,0xd7,0x5, + 0xf9,0x72,0xaf,0x9b,0xe2,0x19,0x60,0xad,0x86,0x82,0x12,0x9,0x2,0x36,0xec,0x13, + 0x1d,0x19,0xca,0x2d,0xf1,0x7f,0x44,0xa8,0xe1,0xe0,0xc2,0x75,0xeb,0x9b,0xfa,0x65, + 0x8d,0xaa,0x81,0x70,0x43,0xe1,0x9e,0x4a,0xe3,0xb0,0xd2,0x66,0x66,0x40,0x79,0x84, + 0x59,0x44,0x31,0x4b,0x43,0x75,0x73,0x25,0xd5,0x36,0x1a,0xc1,0x51,0x15,0xa7,0xde, + 0x3f,0x29,0x50,0x3,0x8a,0xee,0x4d,0x6f,0x1f,0x9f,0x55,0x85,0xdf,0xce,0x89,0xb8, + 0x92,0x3a,0x83,0xd5,0x2f,0xf6,0x7a,0x6,0xad,0x94,0x47,0xfe,0xaa,0xee,0xde,0xe9, + 0x18,0xae,0x6c,0x23,0x1d,0x39,0x12,0x3c,0xd9,0x67,0xc1,0x39,0x36,0x4c,0x72,0xc8, + 0x6,0xf5,0x1e,0x36,0x6d,0x98,0x3c,0x9a,0x2d,0x83,0x99,0x57,0xf2,0xf7,0xc1,0x8a, + 0x26,0x2e,0xad,0x43,0x68,0xbf,0x7f,0xc1,0x27,0xc1,0x7a,0xdc,0x8d,0xec,0x25,0x93, + 0x63,0x43,0xc9,0x50,0x5b,0x85,0xea,0x89,0xa,0x84,0xe0,0x7c,0xfc,0x22,0x7,0x23, + 0x51,0xb5,0xe6,0x39,0xf4,0x66,0xfa,0x9c,0xa7,0xf4,0xf8,0x35,0x62,0x1f,0xc9,0xc5, + 0xe1,0x93,0x16,0x3e,0x1a,0x1,0x47,0xa3,0x5,0xa7,0x9f,0x81,0xca,0xa6,0x25,0x1c, + 0xdb,0xc,0xd4,0x51,0xf1,0x4f,0xed,0x9a,0x44,0xe6,0x4f,0xa6,0x85,0x19,0x6c,0xe7, + 0x2d,0x2,0x26,0xc6,0x82,0x6d,0xe9,0x8,0x15,0x89,0x89,0x5f,0xaf,0xae,0x7b,0x8c, + 0x3a,0x50,0xdd,0x2d,0x1f,0x4b,0x47,0x64,0xb1,0x96,0xb,0x38,0x30,0xf7,0x9f,0x5d, + 0x79,0xc5,0xa3,0x7c,0xb2,0x8d,0x84,0x47,0x96,0xe,0xa7,0x46,0x3d,0xa2,0xd2,0xf6, + 0x73,0x30,0x24,0x92,0x7b,0xea,0x76,0xad,0x82,0x82,0x65,0x32,0xf9,0x5,0x8f,0xf2, + 0x4a,0xb2,0x6f,0xfc,0xbf,0xf3,0xc3,0x56,0x82,0xea,0x9c,0x3f,0x8e,0xef,0x36,0x81, + 0x9f,0xda,0x14,0x9b,0xc5,0x8b,0x49,0xc7,0x8d,0xae,0xf9,0x7,0xb3,0x9,0x79,0x7d, + 0xbb,0xe9,0x7a,0x7b,0x5d,0xbd,0x51,0xdf,0xa9,0x6e,0x9e,0xb7,0x5e,0xd5,0xb8,0x7d, + 0xb0,0x4c,0x19,0xf5,0xd7,0x62,0xbe,0xe4,0x90,0x38,0x6b,0xc3,0x42,0xe5,0x41,0x7d, + 0x4f,0x3b,0x79,0xac,0xf9,0xca,0xd,0x23,0x39,0x2b,0x5a,0x17,0x1,0x13,0x95,0x31, + 0x5f,0xae,0x28,0xb7,0x91,0x66,0x1c,0x22,0x9e,0x88,0x66,0x60,0xed,0xa7,0xde,0xbc, + 0x63,0x58,0xe8,0xdc,0xa2,0xf5,0x0,0xdc,0x22,0xd9,0xf3,0xa2,0xec,0x89,0x54,0xcb, + 0xb8,0x7c,0x83,0x4a,0x62,0xa0,0xeb,0x80,0xa8,0x52,0xe1,0x16,0x7a,0x40,0xd2,0x5d, + 0x18,0xbb,0x3a,0x3a,0x32,0xb9,0x17,0xd3,0x93,0x8b,0x76,0x0,0x94,0xca,0xcb,0x4d, + 0xc6,0x50,0x17,0xa8,0x70,0x4,0x2a,0x98,0xd5,0x8b,0xae,0xcf,0x4b,0x1,0xac,0x63, + 0xbc,0xe6,0x9d,0x6e,0xa0,0x35,0x42,0xb3,0x40,0x39,0xb3,0xd4,0x83,0x80,0x23,0x4b, + 0x50,0xb9,0x73,0x40,0x3d,0x9d,0xd8,0x93,0x29,0x7,0x63,0x74,0x8,0x90,0x57,0x44, + 0x77,0x75,0xb3,0x98,0x2a,0xf5,0x4c,0x6a,0x2f,0x1,0x3f,0x33,0x1,0xe1,0xfd,0x51, + 0x1c,0x71,0x11,0x59,0x10,0xe9,0xec,0xb8,0xf0,0xd0,0xad,0xf8,0x61,0x84,0x3d,0x58, + 0xf9,0xf0,0xf0,0xa3,0x67,0x3e,0xe,0x16,0xbe,0xcd,0x49,0x3f,0x2f,0x47,0x90,0x4b, + 0x39,0xa1,0x25,0x49,0xb,0x12,0x81,0xfb,0x62,0x2f,0x74,0x43,0xb4,0x31,0x9c,0x2e, + 0xa2,0x8d,0xd2,0x89,0x4b,0x60,0x9f,0x89,0x2e,0x69,0xc8,0xdd,0xb0,0xd8,0xa8,0x69, + 0xf9,0xcd,0xb2,0x5,0x60,0x35,0x80,0xc2,0xe3,0x74,0x86,0x18,0xa6,0x23,0x47,0xc8, + 0x30,0x1a,0x52,0xfb,0x7a,0x71,0x85,0x29,0xda,0x4f,0x86,0xc,0xa7,0x2f,0x75,0xa2, + 0xfd,0xa8,0x27,0x5e,0x5d,0xa8,0xa0,0x41,0x9c,0x27,0x5a,0xc2,0x4a,0xa1,0x8b,0xfa, + 0x3b,0x5d,0xf6,0x35,0xcf,0x7c,0xdd,0xaa,0x4b,0x64,0xb6,0xf3,0x94,0xac,0x16,0x12, + 0x55,0x3d,0x70,0xb2,0xe5,0x90,0xf3,0x3,0xb8,0xcd,0xc5,0x82,0xee,0x52,0xfc,0x2a, + 0xaf,0xf3,0xdf,0xfe,0xf0,0xbd,0xaa,0x3c,0xa2,0xe0,0xaf,0xb6,0x8d,0xc5,0xc8,0xe2, + 0x4,0xb8,0x15,0x69,0x49,0x89,0x6c,0x81,0x57,0x33,0x84,0x47,0x5,0x81,0xf0,0x34, + 0x76,0x50,0x34,0x67,0x8e,0x5e,0x23,0x31,0x3f,0xd3,0xe7,0x4d,0x99,0xb0,0x30,0x9d, + 0x69,0xc5,0x87,0x32,0x4f,0xf3,0xb4,0xa6,0xa6,0x39,0x6d,0x2b,0xba,0xde,0x60,0xb0, + 0x2f,0x14,0x18,0xbd,0x72,0x3c,0x6e,0xb1,0x8f,0x56,0x7e,0x29,0x86,0x2f,0x47,0x6f, + 0xf4,0xce,0xa2,0x44,0x42,0xd6,0xea,0x69,0x8f,0xd8,0x94,0x4a,0xb7,0x74,0x7b,0x66, + 0x88,0x13,0x25,0xfa,0xce,0x93,0x2d,0x5e,0x6a,0xab,0x8,0x70,0xda,0x4f,0x60,0x4f, + 0x9d,0x82,0x93,0x5f,0x59,0xfe,0xc8,0xe8,0xd7,0xdd,0xb2,0xf,0x52,0xad,0x75,0xdb, + 0xc1,0x9a,0x56,0x90,0xae,0x83,0xef,0x98,0xaf,0xf7,0x88,0xa,0xc6,0xe8,0x5a,0x64, + 0x6b,0x6d,0x43,0x44,0x6c,0xd,0x2d,0x44,0x6a,0x60,0x53,0xbc,0xe,0x49,0x18,0xcf, + 0xe3,0x6f,0xe0,0x12,0x72,0xd0,0x2a,0xa1,0x48,0xb3,0xac,0xf,0x1c,0x86,0xf2,0x88, + 0xf3,0x36,0xcc,0xe0,0xc2,0x7a,0x25,0x2d,0xda,0xf8,0x6a,0x68,0xc1,0x82,0xb8,0xa5, + 0x71,0x99,0x38,0xe4,0xe9,0xe1,0x6,0x32,0x95,0xb2,0xc0,0xb2,0xb8,0xb3,0xba,0x2d, + 0x69,0x87,0xe,0x2d,0x2,0xb2,0xd9,0x5c,0x2b,0xc3,0x45,0xec,0x47,0x7d,0x13,0xb8, + 0x17,0xca,0x1d,0x80,0xac,0x24,0xb2,0xc2,0x56,0x73,0xf4,0x8f,0xa6,0xaf,0xbc,0x10, + 0xb6,0x4a,0xbc,0x39,0xfc,0x17,0x95,0x29,0xda,0x5a,0x95,0x22,0xd7,0xa8,0x5b,0x6e, + 0x73,0xf7,0xee,0xa0,0x9b,0x21,0x63,0xf2,0x14,0x58,0x2,0xba,0x87,0xbe,0x4b,0x3e, + 0x9,0x87,0x77,0x85,0x9e,0x8d,0x2e,0x7a,0xe7,0xc4,0x1c,0x40,0xec,0xf6,0xae,0xe0, + 0x6f,0x9e,0x81,0xb,0xbf,0x64,0x7d,0x54,0xbc,0x7f,0xf,0xc3,0x3e,0xd9,0x2,0xc6, + 0x62,0x7a,0x4d,0x1,0x8,0x7b,0xfa,0x6f,0xbf,0x97,0xaf,0xad,0xe,0x5f,0x8e,0x7d, + 0x7d,0x10,0x89,0xbc,0xf3,0x7,0x11,0x30,0x87,0xa0,0xf3,0x45,0x7a,0xf5,0x8c,0x5c, + 0xef,0xd9,0xdd,0x77,0xd4,0xd8,0xe7,0x95,0xef,0x97,0x43,0xfe,0x76,0x51,0x7c,0xf3, + 0x61,0x6,0x31,0xd4,0x8d,0x42,0x5,0x94,0xe2,0xf8,0xd9,0xdd,0xee,0x66,0x3a,0x5f, + 0xbf,0x18,0xd6,0x95,0x71,0xbe,0xaa,0x61,0xd6,0x6d,0x60,0x4d,0xbe,0x5d,0xc1,0x9f, + 0xe2,0x72,0x74,0x70,0xb4,0x79,0x5,0x18,0x72,0x5f,0x75,0xe0,0x45,0xaf,0x40,0x6, + 0x48,0x18,0x1b,0xb9,0xd6,0x45,0x9a,0x2d,0xb2,0x7b,0xfa,0x71,0xd8,0xbc,0x11,0xbb, + 0xae,0x85,0xac,0x63,0xfe,0xb1,0xfa,0xf0,0x90,0x70,0xd1,0xd6,0xa0,0x13,0x5c,0x68, + 0xaa,0xf6,0x22,0x1,0x3c,0x3c,0x2f,0xee,0xb7,0x2a,0xdf,0x90,0x66,0xf0,0xcc,0x15, + 0x76,0x79,0xf7,0xf4,0xaa,0x73,0xe5,0x3c,0x63,0x37,0x92,0x4,0x4a,0x6e,0x6c,0x74, + 0xe4,0xe,0x76,0x21,0xca,0xa5,0x8f,0x82,0x4f,0x6f,0x93,0xb5,0xdf,0x60,0x4a,0xd5, + 0xd9,0x42,0xca,0x84,0xb5,0x30,0x40,0x1a,0x67,0xd2,0x9d,0x32,0xc0,0x8a,0xa6,0xa5, + 0x18,0x1d,0x46,0xe2,0x42,0x55,0xe5,0x91,0xc4,0x79,0xc6,0x24,0xd9,0x11,0xf9,0xb3, + 0xd3,0xc4,0xb7,0x89,0xf4,0xf8,0x23,0x5d,0x4b,0xc1,0xf,0x8c,0xcb,0xb5,0xb1,0xe3, + 0xd3,0xf8,0xc7,0x95,0x4e,0xad,0x28,0x93,0xa6,0x6e,0xb7,0x80,0x80,0x32,0xb3,0x54, + 0xf6,0xea,0x5d,0x6c,0xe3,0x81,0x49,0xaf,0xc2,0x58,0xbb,0x8e,0xe,0x6d,0xf1,0x61, + 0x66,0xb9,0xf7,0x35,0xe6,0x9f,0x48,0x8d,0x8d,0x0,0x8d,0xe,0xb1,0xc0,0xe1,0xa9, + 0xac,0xbf,0x95,0x10,0xc0,0x5e,0xbf,0x3,0xb6,0xfa,0x91,0x44,0x69,0x83,0x26,0xcf, + 0xbd,0x9d,0x84,0x24,0x3d,0xcc,0x32,0x4a,0x4d,0x3f,0xd8,0xfe,0x1,0xba,0x28,0xad, + 0xf9,0xbd,0xbd,0xba,0x1c,0xfd,0x3d,0x52,0xf8,0xce,0x17,0x62,0xd2,0x3d,0xb2,0x10, + 0xda,0x37,0xb3,0x97,0x5,0x65,0xe1,0x52,0xa5,0xba,0x51,0x26,0xf5,0x7a,0xd3,0x6f, + 0xb7,0x11,0x2b,0x54,0x8e,0x68,0xa6,0x8,0xb7,0xbd,0xe9,0xa,0x7a,0x1c,0x99,0x55, + 0x54,0x4d,0xec,0xd8,0x33,0x4f,0xaa,0xd8,0x89,0x7b,0xfe,0x7f,0x75,0x52,0xef,0x2e, + 0xe2,0x9a,0x82,0xf1,0x82,0xa8,0xf9,0xb9,0xe6,0x63,0x43,0x61,0x80,0xdc,0x37,0xd4, + 0xaa,0xa3,0x2d,0xdd,0xf2,0xd7,0xb6,0x7d,0x53,0x35,0x7c,0xc9,0x7,0x6c,0x77,0x69, + 0x86,0x79,0x5b,0xa,0xa1,0xd4,0x43,0x88,0x39,0x87,0x6a,0xb9,0x64,0x21,0xe,0xf, + 0xc4,0x3b,0x6c,0xb8,0x92,0x23,0xb5,0x65,0xd7,0x32,0xae,0x5e,0x1f,0x26,0xc8,0x25, + 0x1f,0xa3,0x2f,0xc1,0x79,0xf2,0xc9,0xb2,0x7a,0xb3,0xeb,0x5e,0xd4,0xf9,0xed,0x9a, + 0xb4,0x5a,0xd2,0xc6,0xfd,0x88,0x2c,0x55,0x3a,0xdb,0xb4,0xd8,0x81,0xfc,0xfe,0xa1, + 0xa0,0xad,0x63,0x1a,0xa0,0xac,0x4c,0x9a,0x61,0x38,0xf9,0x36,0xb1,0x67,0xd0,0xe5, + 0xc1,0xa3,0xac,0xbf,0xab,0x59,0x16,0x66,0x35,0xca,0x3f,0xb6,0x47,0xbd,0x58,0xe7, + 0x6c,0x3b,0x3,0x8c,0xe8,0xce,0x28,0x4a,0x8,0xa1,0x0,0x39,0x9,0x51,0x9f,0x4a, + 0x74,0x4c,0xb,0x21,0xa5,0xa0,0x7,0x5a,0xea,0xc5,0x91,0x32,0x84,0x69,0x1a,0x70, + 0xa5,0x9c,0xfc,0xe,0x6c,0xa4,0xd7,0x74,0xc5,0xd7,0x2d,0x4e,0x29,0xcc,0x99,0x9e, + 0x99,0xa4,0x3f,0xbe,0xc4,0xc5,0x1a,0xaf,0x8b,0xab,0xe1,0x10,0x15,0xfb,0x0,0x3a, + 0x99,0x7d,0xc7,0x6,0x22,0x9f,0xf9,0xe8,0xf7,0xa6,0xb6,0xa0,0x74,0x50,0x3f,0xe, + 0x74,0xfd,0xcc,0x39,0xc3,0x66,0xe8,0x50,0x91,0xca,0xdf,0x27,0x47,0x60,0x61,0xe0, + 0xdd,0x2a,0x66,0x0,0x49,0xdf,0x68,0x41,0x86,0x20,0xe2,0xfa,0x70,0xa1,0x88,0x65, + 0xa0,0xd5,0x9e,0xe3,0x3c,0x88,0xb3,0xce,0x53,0x94,0xf5,0x1a,0xf4,0xd6,0xfa,0x52, + 0x80,0xe0,0x52,0xca,0xc0,0x3b,0x8b,0x48,0xda,0x6e,0xc2,0xca,0x90,0x4c,0x30,0xb0, + 0xa1,0xcf,0x94,0xdd,0x58,0x49,0x2c,0x2b,0x5d,0x22,0x46,0xd1,0x79,0xc0,0x24,0xf9, + 0xa2,0xf5,0xc4,0xe2,0x31,0xd0,0xaa,0xc,0xbe,0x6e,0x57,0x4f,0x3a,0x87,0x0,0x5b, + 0x57,0x15,0x39,0x2f,0x5e,0x66,0x5b,0x3b,0x8,0xa1,0x8c,0x81,0x62,0xb0,0x7c,0x84, + 0xa6,0xc0,0xe7,0x58,0x11,0x92,0xe3,0xd0,0x80,0x3b,0x20,0x3a,0x43,0xa0,0x95,0x9a, + 0x35,0x4f,0xca,0x13,0xb5,0x26,0x4e,0xbd,0x47,0xda,0xbf,0x29,0xb,0xbb,0x2e,0x31, + 0xfb,0x16,0x89,0xe,0xa8,0xed,0xde,0xa9,0xa8,0x7e,0xe3,0xeb,0x9e,0xf9,0x87,0xd3, + 0x49,0xd1,0xe6,0xfe,0x77,0xb4,0x3c,0x3e,0x8f,0x7b,0x67,0x1a,0x37,0x15,0x4c,0x34, + 0x2b,0x55,0x42,0x54,0x43,0xa0,0x7d,0xec,0x1f,0xe0,0x58,0xbe,0xda,0x5f,0x12,0x24, + 0x31,0xf9,0xa2,0x28,0x2e,0x5f,0x66,0x3e,0x5a,0x4e,0x58,0x92,0x63,0xa4,0x46,0xf, + 0x7a,0x8,0xe2,0xbd,0xa8,0x60,0x2a,0x47,0x41,0x83,0x85,0x1d,0x62,0x98,0xc0,0x14, + 0x12,0xe3,0x3c,0x40,0xc2,0x23,0xfd,0x1d,0x71,0x57,0x2f,0x54,0x7b,0x75,0xe2,0xf5, + 0x7d,0xc5,0x34,0xa5,0x26,0x5e,0xed,0xe7,0x61,0x73,0x84,0xc4,0x8b,0xc4,0xd8,0x1d, + 0xa8,0x94,0x5e,0x6b,0xb7,0x5c,0x9,0xa8,0x33,0x38,0xfd,0xaf,0xae,0xe0,0x25,0xab, + 0x27,0x59,0xd1,0xcc,0x38,0xbf,0xb4,0x99,0xb2,0xb8,0xdd,0xbe,0x7e,0x36,0xdb,0xa6, + 0xcb,0xb9,0x92,0x3,0x96,0x9b,0xac,0xc9,0xd3,0x2a,0xf8,0x2,0x8a,0x1f,0xae,0xb1, + 0xf7,0x0,0xfe,0x30,0xbf,0x33,0xca,0xf1,0xec,0x28,0x30,0xea,0xde,0xd,0x91,0x2a, + 0x46,0x24,0x2d,0xdc,0xbf,0x59,0x27,0x14,0x83,0x9f,0x16,0x8e,0x3e,0x44,0xbf,0x37, + 0x44,0xbe,0x67,0x83,0xf2,0xb1,0x76,0x5f,0x5a,0xa6,0x4a,0x39,0x33,0xdb,0x63,0x7a, + 0x1,0x90,0xd6,0x40,0x6a,0xfd,0x54,0xed,0x9e,0x6b,0x7c,0x5c,0xaf,0x3d,0x93,0x74, + 0x7b,0x7b,0xf7,0x6e,0xac,0xed,0x4d,0x7,0x95,0x97,0xbf,0x48,0x74,0x23,0xc2,0xf4, + 0x34,0x9a,0xb4,0x9e,0x18,0xa,0xc,0x36,0xf4,0x9,0x93,0xa4,0xc5,0xa6,0x98,0x41, + 0xa1,0x91,0x30,0x4f,0x7f,0x7d,0xd5,0x94,0x95,0x96,0xdd,0x89,0xb9,0x20,0x7e,0x6d, + 0x3a,0x33,0xc,0x53,0xbc,0x98,0x9,0xb1,0xa1,0x1c,0xd6,0x67,0xc3,0x6f,0x28,0x65, + 0x1,0xd7,0x34,0x1,0x56,0xb,0x95,0x6b,0xa1,0xf2,0xf4,0xda,0x93,0xf2,0x49,0xcd, + 0x26,0xd4,0xa0,0x63,0xec,0xaa,0x15,0x8e,0xc6,0xeb,0x75,0xa,0xdb,0x1e,0xef,0xdc, + 0xf5,0x24,0x5d,0xcb,0xae,0x73,0x37,0xcf,0x66,0x2c,0xab,0xf9,0x1f,0x74,0x48,0xc5, + 0xc8,0xe8,0xa8,0xb6,0x93,0xbd,0xc4,0xda,0x2a,0xba,0xe4,0x6,0xd8,0xd4,0x62,0x4e, + 0xf9,0x40,0x1b,0x28,0xb3,0xd1,0xf8,0x99,0x7e,0x24,0x94,0x9d,0x18,0x5c,0xe2,0xe0, + 0x45,0xb,0x17,0x59,0xc9,0x5c,0x34,0x73,0x17,0x19,0xf8,0x6f,0xee,0x5b,0xbd,0x68, + 0x1b,0xd8,0x90,0xce,0xab,0x9,0x69,0xa9,0x2d,0x7d,0xc6,0x45,0xd9,0xaa,0xa6,0x1f, + 0xb5,0x3d,0x78,0xfe,0x99,0xac,0xf1,0x30,0x46,0xea,0x9f,0xb4,0xc6,0x5e,0x1d,0xe1, + 0xb6,0x2d,0xb1,0xe1,0xb6,0x9a,0x8b,0xe3,0x18,0x53,0xa9,0xf1,0x7d,0xcf,0x90,0xb2, + 0xd,0xa,0xb2,0x27,0x36,0x24,0x57,0x7c,0x10,0xf7,0xb0,0xd6,0xd5,0xcd,0x38,0x8c, + 0x7b,0x69,0x6f,0x32,0x4,0xfa,0x95,0x1c,0xcd,0xbe,0x8d,0x4b,0x8e,0x1f,0xfe,0x1c, + 0xa8,0xb1,0x43,0x5e,0x55,0x1a,0x5b,0x65,0x91,0xc,0xbb,0x67,0x5a,0x74,0xf4,0xd5, + 0xdd,0xe3,0x87,0xe2,0x5e,0x9c,0x7e,0x2d,0x5c,0x8c,0x78,0x6a,0xab,0x77,0x6,0xd3, + 0xa8,0x49,0x32,0xfe,0xe3,0x8d,0xe3,0x75,0x9a,0xa0,0x5d,0xf4,0x15,0xd1,0x4a,0x72, + 0xb5,0x51,0xd4,0x93,0xed,0x54,0xc0,0xc9,0xe0,0xb9,0xb4,0xc,0xb0,0xba,0x5f,0x5a, + 0x84,0x91,0xd8,0x68,0x9f,0xbc,0x5d,0x3a,0xdc,0xba,0xae,0x71,0x8c,0xf8,0x64,0xc1, + 0xc9,0x39,0x56,0x37,0x8d,0x96,0x81,0xed,0x50,0x36,0x79,0x2,0x70,0xd8,0xdb,0xf4, + 0x6b,0x34,0xdc,0xb,0xf0,0xba,0xc4,0x4e,0x75,0x73,0x3f,0x82,0xeb,0xa3,0xc3,0xb5, + 0xdd,0x99,0xec,0xea,0x31,0x6e,0xd9,0x1,0x24,0x53,0x82,0x95,0xac,0xdd,0xa,0x18, + 0x12,0xe7,0xa2,0x83,0xa2,0x67,0x51,0x97,0x5a,0x90,0x99,0x46,0xb4,0xdd,0xfb,0x92, + 0x77,0x68,0x7d,0x28,0xd7,0xd6,0xa9,0xfb,0xaa,0xab,0x11,0x57,0x8a,0x1c,0xee,0x1c, + 0x83,0x11,0x9f,0x26,0x78,0xf0,0x3d,0x52,0x2,0x57,0x98,0xb6,0x35,0x14,0xc8,0xac, + 0xfb,0xc5,0x55,0xd3,0x9d,0xfe,0x50,0xc7,0xaa,0x61,0x9e,0xb4,0xfc,0xd,0xd1,0x80, + 0x1e,0xf0,0x26,0x16,0xe2,0xe3,0x68,0x64,0x3b,0x80,0x1b,0xef,0x14,0x63,0x9c,0x10, + 0x29,0x71,0x64,0x46,0xef,0x34,0x8d,0x1b,0x15,0x2c,0xcf,0x13,0xb8,0x21,0x93,0xd6, + 0x13,0x3a,0x6c,0x75,0x1e,0xd4,0xd9,0x59,0xd4,0x74,0x49,0x68,0xd7,0x65,0xf8,0x1, + 0x57,0x5d,0xc7,0x47,0x11,0x55,0x62,0x26,0x82,0x33,0xb8,0x3b,0x54,0xcc,0x92,0xe6, + 0x7,0xfe,0x5c,0x25,0x54,0x36,0xfd,0xa8,0x2a,0xc6,0x12,0x2,0xab,0xb,0x83,0x3, + 0xe7,0x4b,0x4b,0xf8,0xa0,0xad,0x9e,0xa2,0x60,0x58,0x5e,0x35,0xa4,0xf0,0x1c,0xab, + 0x6f,0x79,0x50,0xc3,0x2f,0xcd,0x6d,0x5a,0x94,0xfe,0xdb,0x40,0xa,0x5f,0x44,0x71, + 0x2a,0xf,0x6a,0xcb,0x3c,0x88,0x6e,0x9d,0x60,0xcc,0x52,0x5,0x3d,0x6e,0x30,0xad, + 0x67,0x80,0xf0,0x17,0xcd,0x5e,0xf0,0x62,0x5d,0xcc,0x23,0xe6,0xac,0xe6,0x58,0xd6, + 0xf5,0x42,0xa2,0x32,0x4b,0x91,0x4f,0xab,0xdd,0xa1,0x31,0x9b,0x90,0x61,0x49,0x77, + 0x62,0x3a,0x8e,0x30,0x19,0xfe,0x13,0xf5,0xcc,0x36,0x5d,0x79,0x1d,0xb5,0x50,0x13, + 0x78,0x73,0xc4,0xc3,0x84,0x94,0xee,0x62,0x36,0x20,0xfd,0x46,0x2,0xc6,0xbe,0x64, + 0x2,0xcc,0x14,0x9a,0x4c,0x27,0x90,0x19,0x5d,0xed,0x12,0xf9,0x24,0xe1,0x8c,0x1c, + 0xd4,0x52,0x5f,0x59,0xe6,0x4e,0xbc,0x9c,0xee,0x3a,0xe3,0xf0,0x2,0x22,0xd4,0x83, + 0x6e,0xe8,0x9d,0xba,0x90,0x2e,0x53,0x6d,0x9c,0xe4,0x68,0x40,0xc7,0xf4,0x5c,0x9c, + 0xc6,0xbb,0xf6,0xad,0x89,0x33,0xca,0x78,0x6d,0x2e,0x69,0xee,0xcf,0x3e,0xf1,0x3e, + 0xa7,0x8f,0x79,0x38,0x3e,0x4c,0xa5,0xda,0x32,0xe,0x1b,0xf9,0x83,0xf6,0x16,0x4a, + 0xb2,0xd,0x78,0xbb,0xbf,0x43,0x35,0xad,0x71,0x9e,0x1c,0x41,0x5d,0xf,0xfe,0x84, + 0x9e,0xf7,0x3c,0x5c,0x45,0xe1,0x37,0x77,0x70,0xd1,0xf0,0x73,0x48,0x7,0xbd,0x7a, + 0x94,0x36,0x37,0xd3,0xf8,0x6c,0x81,0x6a,0x8a,0x9e,0xab,0x67,0xad,0x2b,0xeb,0xcb, + 0x23,0x28,0x29,0x68,0x8a,0xdf,0x5f,0x7a,0x32,0x50,0xed,0x7a,0xd7,0x2b,0xf5,0xeb, + 0xe1,0x2d,0xbf,0xda,0x19,0x42,0x46,0xa3,0x60,0x71,0xc,0x8d,0x9c,0x77,0x59,0x40, + 0x20,0x2,0xa8,0x2a,0x62,0x88,0x24,0x94,0xd8,0x91,0x8e,0x30,0xbc,0x4,0x1c,0x1e, + 0x31,0xdc,0xf9,0xc9,0x9e,0xbf,0x6e,0xfe,0xb0,0xf9,0x8c,0xcd,0xf0,0x65,0xe,0x90, + 0xe7,0x36,0xba,0x4a,0xbe,0xde,0x5e,0x18,0xef,0xec,0x48,0x2d,0x71,0xe4,0x4b,0x22, + 0xc1,0xc4,0xec,0xdf,0x84,0x5b,0xde,0xb5,0xd4,0x6b,0x83,0xc5,0x50,0x91,0x57,0x38, + 0xc7,0x91,0x2,0x87,0xf0,0x60,0x9f,0xe0,0xcd,0x67,0xe,0x3f,0x4c,0xd9,0x61,0x8d, + 0x9e,0x4e,0x6d,0xa3,0x29,0x4c,0x59,0x7d,0x37,0xdc,0xc3,0x88,0xed,0x1b,0xc0,0x35, + 0x2c,0x43,0x3c,0x1d,0xa3,0xdb,0x7e,0xf0,0xc3,0xc,0xaf,0x10,0xe5,0x12,0x9e,0x5, + 0xdf,0xc,0xa8,0x89,0x59,0x81,0x7,0x10,0xdd,0xca,0x98,0xcb,0x65,0xd9,0x80,0x12, + 0x1d,0xbd,0xae,0x40,0x99,0x2d,0x32,0xdc,0xb9,0xe1,0xed,0x1f,0x73,0x8c,0x24,0xd3, + 0x18,0x4c,0xdc,0xf0,0xcd,0xe3,0x2,0xab,0x2f,0x9a,0xf6,0x14,0xf3,0x78,0x26,0x90, + 0x36,0x55,0xd1,0x4f,0x2,0x83,0x2d,0xbb,0xe4,0x1b,0xdb,0xd8,0x27,0x7f,0x2c,0x3f, + 0xcc,0x9,0x31,0x9a,0x6c,0xb2,0xc6,0x9b,0xcc,0xbd,0x30,0xc1,0x36,0xd5,0x52,0x6c, + 0x2b,0xa3,0xbc,0x2e,0xa6,0x69,0x69,0x8c,0x84,0xc4,0xe4,0xab,0x45,0x11,0x6a,0x91, + 0x1a,0x1b,0x2c,0x86,0xcd,0xf2,0xa2,0x9b,0x31,0x52,0xdc,0x67,0x28,0xae,0x54,0xd3, + 0xd2,0x90,0x81,0x79,0xf9,0xea,0x85,0x7e,0xb0,0x6a,0xa9,0x75,0xfa,0x93,0x7,0x15, + 0xaf,0xb2,0x1c,0xfc,0x26,0x3e,0x18,0x57,0x90,0xf4,0x3e,0x38,0x24,0x92,0x8b,0xf6, + 0xa2,0xd,0x70,0x9c,0x78,0xf6,0x9a,0xa8,0xe0,0xc3,0x1e,0xdc,0xd7,0xa4,0x71,0x7, + 0x57,0x8d,0x4,0x7d,0x4b,0x1d,0x54,0x5b,0x91,0x93,0x94,0xb5,0xa5,0x20,0x2c,0xc8, + 0xad,0x9d,0x65,0x26,0x14,0x80,0xce,0x74,0xc3,0xec,0x51,0x9b,0x11,0xc3,0xa2,0x68, + 0xd0,0x27,0x66,0x9c,0xc3,0xba,0xf7,0x55,0xcd,0xc,0x8b,0xf3,0x2d,0xb7,0xbc,0x5a, + 0xd4,0xa1,0x80,0x68,0x22,0x4f,0xdd,0x66,0xbb,0x2f,0x2,0xcc,0x72,0x25,0xb4,0xc3, + 0x4c,0x1b,0x60,0x8f,0xd6,0x58,0x64,0x24,0x65,0xef,0x18,0x12,0x28,0xd4,0x6c,0xfc, + 0x77,0x6c,0x66,0x19,0x3b,0xc3,0x7f,0xf6,0xf2,0x2,0x43,0xe5,0xa6,0xf7,0x29,0xf2, + 0x14,0x89,0x2,0x6a,0x61,0x66,0xe,0x46,0xd6,0x27,0xd7,0xfe,0xfb,0xc3,0x7b,0xf2, + 0x30,0x61,0x8c,0x6b,0x25,0x8b,0xe1,0x98,0x8d,0x25,0xfd,0x34,0x9d,0x27,0xa6,0xb1, + 0x30,0xa8,0x9b,0x91,0x8f,0xa9,0x58,0x66,0x50,0x30,0x65,0xcc,0xf4,0x60,0xbf,0x25, + 0xc2,0xcb,0x11,0xe7,0x58,0xf2,0x0,0xe5,0x98,0xfd,0x9a,0x36,0x25,0xc0,0x67,0x55, + 0xe9,0x3,0x67,0x79,0x2c,0xbf,0xdf,0xfc,0xef,0xc4,0xc9,0xe4,0x25,0x9,0x8a,0xe7, + 0xd5,0x1b,0x50,0x2e,0xe,0xcf,0x93,0xa6,0xce,0xad,0x5c,0x73,0x6f,0xc3,0xc9,0xd8, + 0x46,0xb0,0x52,0x73,0x70,0xb1,0x70,0xdf,0xf5,0xb9,0xc5,0x1b,0xc2,0xcf,0x83,0x98, + 0x6a,0x53,0x46,0x78,0x23,0xda,0x9f,0x71,0x8,0xfb,0xe5,0x77,0xc0,0x2f,0xcf,0x7, + 0xdf,0xa1,0xf9,0xcf,0x53,0xe9,0xaf,0x49,0xa3,0xf4,0xe4,0x67,0xc4,0x68,0x7f,0xae, + 0x3b,0xc6,0x28,0xdd,0x21,0x47,0x50,0x29,0xc2,0x36,0x21,0x3,0xe4,0xf0,0xb,0xc4, + 0x93,0x84,0x14,0x66,0xee,0xc3,0x30,0x92,0xb9,0x15,0x79,0xfd,0xfc,0xf9,0xad,0xb7, + 0x40,0x55,0x95,0x61,0x9c,0xe5,0xa,0xde,0x9b,0x2b,0xe2,0x80,0x9c,0x6d,0xc4,0xaf, + 0xf1,0xd8,0x95,0xe0,0x9d,0xc5,0xf3,0xd6,0x5a,0x6d,0xd4,0x57,0xe6,0x2,0x8e,0x27, + 0x57,0x25,0x8,0x73,0xb,0x13,0x53,0x27,0xbd,0x36,0xa7,0xd9,0x23,0xec,0x89,0x15, + 0xc5,0x9f,0x76,0xe2,0x65,0xe9,0x39,0xc0,0xd6,0x8e,0x97,0xbe,0x90,0x27,0x65,0xe8, + 0xcb,0x6e,0xdb,0x56,0x1,0xae,0x7d,0xbe,0x64,0xa5,0x19,0x87,0x92,0xa2,0x1d,0xd7, + 0x42,0x13,0x3b,0x28,0xfc,0x74,0x68,0xd3,0x3,0x0,0x92,0x14,0xa6,0xf8,0x7c,0x72, + 0xe6,0x58,0x49,0xe7,0x8,0xc6,0x26,0x6c,0xeb,0x3f,0xf4,0x7e,0x62,0x91,0xd6,0xa4, + 0xa4,0x91,0x4c,0xa1,0x6,0xb4,0xf4,0x89,0x35,0x88,0x9d,0x5b,0x1,0x1a,0xce,0x67, + 0xf1,0x18,0x4f,0x79,0x5e,0x75,0x66,0x4b,0xb5,0xda,0x49,0x18,0x6c,0x9f,0x3c,0x11, + 0x31,0x89,0xb2,0xb7,0xbd,0x27,0xc0,0xf2,0xaf,0x5e,0xce,0x30,0xf7,0x9d,0x97,0x69, + 0x35,0x66,0xe3,0x13,0xdc,0x4a,0xdd,0x12,0x25,0x28,0x2a,0x91,0xc7,0xe5,0x22,0xf9, + 0xee,0x54,0x31,0xad,0x7b,0xf1,0x20,0xab,0xcf,0xee,0x5b,0xc7,0xc,0xf3,0xb0,0xc0, + 0x5a,0x14,0x54,0xb6,0x5e,0x32,0xc8,0x3,0xd9,0x72,0x14,0xa2,0x59,0x36,0x1c,0x48, + 0xa,0xcc,0x75,0x86,0xbe,0x16,0x32,0x8e,0x84,0x8d,0xd5,0x91,0x1,0x86,0xd1,0xdb, + 0x9b,0x26,0x12,0x79,0xd8,0xdb,0xfc,0xb2,0xcd,0x11,0xd4,0xa6,0xc7,0xf0,0xef,0x51, + 0xbd,0xe4,0xd7,0xfb,0xfa,0x89,0x8a,0x0,0x97,0x60,0x11,0x98,0x67,0xe2,0xf3,0x82, + 0x89,0x7,0xfb,0x62,0x62,0x78,0x94,0xaf,0x8a,0x6a,0x57,0xd1,0xda,0xc6,0x23,0x19, + 0xab,0x7b,0x15,0x27,0x5,0x20,0x27,0x1c,0x0,0x38,0xb5,0x67,0x9a,0x29,0xe9,0xa3, + 0xaf,0x66,0x6,0x91,0xde,0x9b,0x42,0xe8,0x85,0x99,0x3a,0x60,0x60,0x5e,0x79,0x8b, + 0x59,0xf,0x32,0xdd,0x2f,0xd8,0xfa,0x2f,0x90,0x30,0x97,0x2c,0x59,0x1,0xcf,0xa, + 0xe6,0x56,0x1b,0x46,0x71,0x5d,0x2f,0xf6,0xf6,0x6a,0xd6,0xd6,0x48,0xd0,0xe2,0x21, + 0xdf,0x15,0xfe,0xf,0xee,0xf9,0x3e,0xfe,0x2a,0x55,0x2b,0x84,0xd6,0x7b,0xe,0xbd, + 0x51,0x29,0x4,0x42,0x7,0xb3,0xb8,0x7d,0x9d,0x8f,0x55,0x65,0x60,0xb7,0x86,0x40, + 0xcc,0x85,0xce,0x3b,0x80,0x8d,0x3b,0xaa,0xe2,0xe5,0xae,0x39,0xe0,0x3c,0xf7,0x32, + 0xe5,0x7b,0x74,0xec,0x2f,0x2d,0x6a,0x4c,0x3d,0x3f,0xb1,0x9d,0xf6,0x38,0x5e,0x44, + 0xbe,0x2d,0x7f,0xbe,0xba,0x3a,0xe8,0x1e,0x21,0x98,0x57,0x2,0x54,0xce,0xb4,0x3a, + 0xca,0xa8,0x27,0xf9,0xd6,0x12,0xc6,0x14,0x51,0x78,0x31,0x49,0xb1,0xf,0xd,0xef, + 0xbc,0x8c,0x2e,0x77,0xc7,0x17,0x15,0x68,0x2f,0xec,0xe9,0x84,0xbb,0x9e,0x3e,0x86, + 0x48,0xe5,0x1,0x9e,0x77,0x47,0x32,0xc8,0xbf,0xe2,0x91,0xf0,0xf2,0x9e,0x60,0xaf, + 0xab,0x8e,0xa6,0xf2,0x26,0xbc,0x5b,0x55,0x29,0xc4,0x59,0x64,0xe3,0x18,0x6b,0x2c, + 0xfd,0x6c,0x4a,0x75,0xb3,0xfb,0xbd,0xf2,0xde,0x50,0xe4,0xd1,0x6e,0xc4,0x1,0x1a, + 0x54,0xa8,0x8c,0x7a,0xe4,0xe7,0x4f,0x8d,0x2d,0xa9,0xf1,0x11,0x41,0x5d,0xbc,0x3f, + 0x49,0x7,0x34,0x7c,0x3,0x71,0x70,0x61,0x41,0xd4,0xb3,0xb0,0x99,0xb4,0x4a,0x6d, + 0xdc,0xd7,0x67,0x41,0x3f,0xb7,0xce,0x6c,0xe0,0xc1,0x7d,0xa1,0x1f,0xb9,0xe0,0x69, + 0xc0,0x94,0xe5,0x43,0x6,0x56,0x25,0x48,0xaa,0xd8,0x78,0xc4,0x8d,0xc2,0x32,0xea, + 0x1a,0x1a,0x2c,0x5a,0xd1,0xfb,0xc6,0x32,0xbd,0xc4,0xd3,0xdc,0x7e,0x34,0xc5,0xbf, + 0x48,0xac,0x82,0xcd,0x82,0xa7,0x95,0x2e,0x80,0xe,0xf2,0x8e,0x51,0xa4,0xf8,0x6b, + 0xbe,0x25,0xc5,0x10,0x21,0xd,0xc1,0x5e,0xd1,0x15,0xbb,0xcf,0xc8,0x81,0x8f,0x11, + 0xad,0x92,0xdf,0x31,0x3a,0xf4,0xde,0x3b,0x4,0x51,0x49,0x55,0x75,0x42,0xc0,0x35, + 0x67,0x7,0xc4,0x9,0x14,0x87,0xe6,0x65,0x1c,0xa2,0x35,0xe5,0xa4,0x45,0x76,0x52, + 0xd7,0xd5,0x3,0x12,0xcb,0x61,0xcc,0xcf,0xb2,0x16,0xa4,0x29,0x58,0xe4,0xdd,0x40, + 0xeb,0x22,0xc8,0x0,0xa9,0xaf,0x65,0x46,0xd2,0x1b,0x2c,0xf6,0x60,0xa2,0x49,0x38, + 0x79,0xcc,0x4a,0x45,0x2e,0x18,0x94,0x61,0xad,0x39,0xa,0x7,0x1e,0xe7,0xc6,0x8a, + 0xa,0xf,0x8a,0x34,0x3e,0x70,0x7a,0x11,0x8b,0x26,0x87,0x6b,0x48,0xd1,0xa3,0xc1, + 0x1e,0xed,0x86,0x4c,0x85,0x9a,0x2d,0x34,0xd3,0x37,0xba,0x72,0x1f,0x1,0xfc,0xa9, + 0x10,0x7,0x5d,0x4e,0xf6,0x57,0xdf,0x2,0x7d,0x67,0x6d,0x45,0xb8,0x11,0x8,0xd6, + 0x7f,0xe,0xa3,0x84,0xa9,0xd0,0x38,0xfc,0x9,0xf2,0xee,0xa7,0xf3,0x6b,0xd0,0x83, + 0xf2,0x2e,0xd2,0xe9,0x85,0x32,0x6c,0x82,0x99,0xd9,0xc8,0xd2,0x6b,0x50,0xa9,0x6a, + 0xdd,0xcc,0xee,0x7,0x9e,0x28,0x5,0x27,0x9a,0x73,0x4e,0xf,0xdf,0x20,0x92,0xd2, + 0x4e,0xe4,0x3c,0x54,0x17,0xa8,0x56,0x31,0x3,0x9e,0x4,0xed,0x6e,0x2d,0x58,0x4d, + 0x7a,0xc6,0x54,0x98,0x6e,0xd8,0xbf,0xa,0x4d,0xe,0x98,0x2d,0xad,0xaa,0x7f,0xfc, + 0x90,0xbb,0xd0,0x27,0xe4,0x27,0x58,0x67,0x46,0xdb,0x55,0xb4,0x89,0x2d,0x81,0x4, + 0xf3,0xd6,0x9c,0xe2,0x2f,0xdb,0xec,0x7c,0x69,0x5,0x29,0x18,0xaf,0xa8,0x94,0xbf, + 0xe4,0x65,0xe7,0xc9,0xc,0xbf,0x31,0xd1,0x1c,0x6,0x87,0xa5,0x33,0x9,0x29,0xa6, + 0x5f,0x45,0x89,0x8f,0x21,0xf5,0xc,0xa,0xfa,0xb5,0x22,0x2b,0x5e,0x36,0xea,0xc2, + 0x9b,0x52,0x8c,0x28,0x13,0x3d,0xf9,0xae,0x43,0x1,0xd3,0xf5,0xb,0xfc,0x9d,0xe9, + 0x42,0x27,0x79,0xe2,0x1e,0x6,0x6c,0x98,0xbb,0xf,0xc3,0x99,0x45,0xaf,0x5d,0x61, + 0x81,0x69,0x9,0x94,0x27,0x3,0xc2,0x6a,0x5,0x96,0xe0,0x8f,0x93,0x7e,0xf8,0x55, + 0xa5,0x73,0xb7,0x43,0xf8,0x25,0xdc,0x34,0xb3,0x20,0x4d,0xf8,0xcf,0x2a,0x5a,0x52, + 0x94,0x63,0x66,0xbb,0xe6,0xa9,0xa5,0x6b,0x40,0x86,0x7a,0x54,0x84,0x73,0xa9,0xaa, + 0x66,0xe1,0xed,0xde,0x86,0x4a,0x13,0x3a,0x6b,0x61,0x33,0xba,0xb,0xe,0x8c,0x9f, + 0xf0,0x73,0xda,0x57,0x1d,0x1,0xc2,0x5d,0x7,0xbc,0xb1,0x8c,0x31,0xdb,0x37,0x17, + 0x3d,0xa4,0xf6,0xc3,0x6f,0x89,0x7d,0x5a,0x6a,0x30,0x15,0x76,0x3e,0x22,0x16,0xaf, + 0x95,0x71,0x86,0xb2,0x72,0xc9,0x8f,0x79,0x86,0xc1,0x85,0x37,0x1d,0x3c,0x4f,0x5a, + 0xe1,0xc5,0x9d,0xd0,0x4f,0x1b,0x2b,0xba,0x4b,0xbf,0x31,0xa,0xe1,0xc6,0x39,0xf6, + 0xb7,0xbf,0x29,0x2a,0x89,0xb9,0x24,0x90,0xfa,0xa9,0xc7,0x18,0xe6,0x96,0xf1,0x48, + 0xdb,0xf,0x98,0x2c,0xa9,0xc3,0x66,0xf4,0x83,0x17,0x7e,0xe5,0x5d,0xb7,0xdc,0x16, + 0xf7,0x7,0x40,0x1,0x40,0xe3,0x91,0x3b,0x8e,0xd9,0xd2,0xf4,0xef,0x44,0x3d,0xcc, + 0x53,0xd5,0x78,0x7c,0x19,0x5e,0x71,0x1c,0x75,0x70,0x2,0xd2,0xa7,0x5f,0xe8,0x9f, + 0x66,0xa9,0x21,0xa6,0x8d,0x32,0x61,0x9b,0xc,0x34,0x90,0x7c,0xf7,0x4d,0xc8,0xca, + 0xa2,0x41,0x47,0xbb,0x9f,0x38,0x58,0x15,0xa8,0x5a,0x67,0x51,0x39,0xd0,0x70,0x9f, + 0x7a,0x91,0xc5,0x87,0xc4,0x27,0x24,0x50,0xda,0xb4,0xcc,0xd2,0x82,0x95,0x9d,0x25, + 0x56,0xe4,0x61,0xf5,0x1e,0xb9,0x8a,0x46,0x93,0x72,0x97,0xcd,0x43,0x88,0xec,0xbd, + 0x1a,0xb3,0xc4,0x5e,0xda,0xe8,0x2f,0xb6,0x1e,0x7b,0x9,0x20,0x91,0xa7,0x45,0xe7, + 0xc,0x26,0x5e,0xa9,0x5f,0x68,0xf0,0x73,0xda,0x8,0xc0,0x9d,0x90,0xad,0x5b,0x2b, + 0xe0,0xa0,0x9,0x3c,0x89,0x38,0x72,0x27,0xb4,0x7b,0x47,0x46,0xa2,0xd,0xad,0xaf, + 0x33,0xc,0xd8,0x13,0xf4,0xc9,0x86,0xcf,0xd2,0x47,0x6e,0xe2,0x74,0x49,0xe,0xd5, + 0xe9,0x97,0x12,0xf3,0xcf,0x84,0x1b,0x4,0x0,0xe2,0xc9,0xa3,0xef,0x78,0xd2,0x23, + 0x4,0xab,0x36,0xf8,0xf5,0x3c,0x49,0x48,0x3,0x37,0x2b,0x78,0x0,0xb9,0xcd,0x6a, + 0x51,0xdf,0x5e,0xa0,0x64,0xf8,0xa5,0xe3,0xdb,0x6f,0x7,0xcb,0x67,0xd9,0x6f,0x6c, + 0x6,0xa5,0xe4,0xfb,0x62,0x2e,0x44,0x65,0xe4,0xee,0x5d,0xe5,0xa8,0x2b,0x50,0xf9, + 0xb,0x2e,0x1b,0xee,0x27,0xc0,0x53,0x4,0xaf,0x5a,0x4f,0x18,0xb4,0xbe,0x4,0xba, + 0xe4,0xe8,0x36,0x47,0x97,0x7a,0xac,0xfb,0xe8,0x8a,0xe1,0x92,0xb5,0xb1,0xc,0x41, + 0xdf,0x27,0x30,0x8,0xe7,0x83,0x8b,0x18,0x5e,0xda,0x30,0x13,0x9a,0xb3,0x4d,0x7f, + 0x1c,0x83,0x46,0xb3,0x7d,0x72,0x30,0x66,0xfc,0x12,0x78,0xb3,0x44,0x85,0xf4,0x24, + 0xac,0xa4,0x2c,0x15,0xa8,0xb7,0x2d,0x7,0x13,0xdc,0x1a,0xad,0x90,0xe6,0xac,0x2c, + 0x6a,0xf2,0xe0,0x67,0x65,0x90,0xcd,0x63,0x22,0x47,0x96,0x66,0x4c,0xb,0x8b,0x78, + 0x2f,0x37,0x8d,0xd7,0xef,0x3a,0x5e,0x82,0x96,0xf7,0x30,0xa6,0xde,0xdc,0xd3,0x49, + 0x4f,0x34,0x30,0x34,0xc4,0xfe,0x97,0xe6,0xc5,0xad,0x4e,0x91,0xb8,0x59,0xa,0xe8, + 0x90,0x18,0x40,0x0,0x52,0x9f,0x82,0x69,0x97,0xb2,0x10,0x77,0xf,0xe3,0x40,0xdd, + 0x97,0x71,0x13,0x5c,0xef,0x2a,0xc3,0x35,0xd8,0x91,0xc6,0x11,0xea,0xd0,0xf9,0x7b, + 0xe8,0x3b,0xfb,0xbb,0x5a,0x7e,0x25,0xf1,0xb1,0xb4,0x69,0xc0,0x99,0x2a,0x1f,0xb0, + 0x9b,0x32,0xe,0x8b,0x5c,0x51,0x40,0xb4,0xe2,0x7,0xc6,0xcd,0xd7,0xc0,0xc8,0x41, + 0x7b,0xc4,0xfc,0xd5,0xc3,0xa1,0x48,0x75,0x56,0x31,0xb5,0xef,0x5b,0xd4,0x21,0xf6, + 0x86,0x2f,0x2,0xe3,0x0,0x42,0x98,0xe2,0xc8,0x5f,0x30,0xa1,0xa0,0x78,0x62,0x9b, + 0xbd,0x5f,0xf1,0x81,0x1,0x3a,0xf6,0x57,0xea,0xac,0xc7,0x47,0x2,0xe8,0xbd,0x88, + 0x97,0x40,0xeb,0x17,0x2,0x85,0xf9,0xcb,0x64,0xa9,0xec,0x84,0xa1,0x4f,0x21,0x5f, + 0x2e,0x13,0xe0,0x2f,0xcc,0x57,0x6,0xb7,0x84,0x4d,0x7e,0x86,0x36,0x3d,0x8e,0x4d, + 0xfc,0x7b,0x64,0xfe,0x1,0xdd,0xca,0xe4,0x7,0x37,0x6a,0xa9,0x86,0x8b,0x9,0xb4, + 0x1e,0x6a,0x63,0x6a,0x41,0xe9,0xa1,0xc5,0x37,0x21,0xcb,0xed,0xdd,0x5b,0x3b,0xda, + 0xd6,0x20,0x59,0xd7,0x7d,0xa4,0x3c,0x85,0xdb,0xa6,0x2f,0xe2,0xb1,0xb7,0x97,0x4f, + 0x22,0x7b,0xb9,0x64,0x65,0x5c,0xa9,0x1c,0xfc,0x76,0xa,0x5a,0xd1,0x46,0x35,0xa8, + 0xe5,0x8e,0x0,0x63,0x33,0x3c,0xe8,0x8f,0x63,0x97,0x72,0x15,0x50,0x89,0x65,0xf1, + 0x5,0x9e,0xd5,0xe9,0xfa,0x80,0x7,0x77,0xf6,0x11,0xd1,0x48,0xd6,0x86,0x70,0x3c, + 0x95,0x70,0xa0,0xc8,0x2c,0x9,0xd7,0x8f,0x21,0x4a,0x25,0x71,0xd4,0x8a,0xe2,0x59, + 0x29,0xb9,0x44,0xa4,0x3a,0xca,0x9b,0xb0,0x5b,0x6e,0x78,0xb2,0x74,0xe8,0xee,0xa, + 0x59,0xf,0x53,0x5,0x98,0x2b,0x95,0xb9,0x76,0xba,0x2b,0x4b,0xc4,0xe,0x24,0x6d, + 0x47,0x68,0x91,0x81,0xb2,0x2e,0xb1,0xf,0x1c,0x2a,0xc1,0x90,0x13,0x30,0x9b,0xeb, + 0x40,0x6e,0xf1,0xd8,0x99,0x7,0x12,0x10,0x41,0xbc,0xda,0x6,0x4a,0x0,0x73,0x92, + 0xe7,0x6,0x93,0x1b,0xb3,0xc5,0x2a,0xcf,0xef,0x6b,0xdf,0x83,0x1b,0x7b,0xee,0x5b, + 0xe9,0xe0,0xb3,0x4,0x67,0x45,0x93,0xa8,0x2,0xee,0x2e,0x4d,0x6e,0xa2,0x5f,0xd5, + 0x28,0xf2,0xf0,0x5b,0xb8,0x9a,0x2b,0x29,0x85,0xb,0x2c,0xa1,0x7,0x1b,0xfc,0x70, + 0xfc,0x31,0xf3,0x64,0x76,0x88,0x8d,0xf8,0x77,0xbb,0x46,0x65,0xdd,0xa5,0x3b,0x85, + 0x18,0x2d,0xe0,0x51,0x47,0x8b,0x7a,0xcd,0x17,0xa6,0x6f,0x1e,0xc1,0x6c,0xe,0x3e, + 0x1d,0x3,0x23,0x14,0xb,0xb0,0xd,0x2,0xeb,0x53,0x67,0xca,0x78,0xa2,0x50,0x10, + 0x4f,0xb1,0x61,0x97,0x3d,0xdb,0x65,0x54,0x2,0xd4,0xf1,0x44,0xc0,0x80,0x82,0x5e, + 0x83,0x25,0x72,0xe,0xd5,0x7f,0x10,0xc2,0x52,0xf6,0xd,0xca,0x99,0x5d,0xda,0x69, + 0xf,0xbc,0x80,0xcc,0x98,0xe5,0x21,0x1b,0x3a,0x93,0x5f,0x7a,0x14,0xe1,0xd8,0x17, + 0x8,0x4b,0x25,0x5d,0x4a,0xb4,0x9f,0x9c,0xab,0xac,0xe6,0xc4,0x8a,0x42,0x2e,0x19, + 0xfe,0xae,0xe5,0x17,0x14,0x87,0x32,0xcd,0x1b,0x91,0x49,0x2f,0xf3,0x22,0x46,0x7b, + 0xed,0xea,0x58,0xb7,0x9f,0xf8,0xd4,0xca,0x25,0xbb,0x8f,0xaf,0x7d,0x3e,0xc9,0xfb, + 0xec,0x2f,0x14,0x81,0xb6,0xc5,0x4f,0xd1,0xd7,0x98,0x80,0x4b,0x3b,0x46,0x46,0xa8, + 0xb0,0x9e,0x60,0x50,0x97,0xb4,0x9a,0xbd,0xf0,0x2b,0xec,0x6e,0x69,0x36,0xea,0xd5, + 0x66,0x7e,0xd6,0x1d,0xc3,0x27,0x6f,0x9b,0x3f,0x6f,0x66,0x7a,0x36,0xac,0xa2,0xe6, + 0x4c,0x83,0xb7,0xe3,0x38,0x52,0x21,0x29,0xfc,0xf,0x18,0xe5,0x45,0x3,0xbc,0x2b, + 0x1,0x13,0xc8,0xc4,0x3a,0x38,0x61,0x7a,0x27,0x47,0x74,0x5d,0xf4,0x97,0x45,0x41, + 0x1b,0xfc,0xa4,0xd2,0xce,0x46,0xfc,0xcc,0xd4,0x94,0xb2,0x1a,0x17,0xee,0x46,0x18, + 0x3,0xf,0xdc,0x3d,0xc6,0xbd,0x37,0x6d,0x6,0x2c,0xcb,0x7a,0xc3,0x90,0x3b,0xde, + 0xd,0x5f,0xb1,0xdb,0xa5,0x2e,0xa8,0x7a,0x42,0xdb,0x15,0x59,0xca,0x5b,0xf0,0xcd, + 0xe9,0x4e,0x8b,0x30,0xc,0x42,0x9d,0x91,0x6e,0xe8,0x8b,0x32,0xf8,0xc6,0x90,0x6, + 0x27,0xc2,0x62,0x4c,0xf0,0x8a,0xc7,0xb3,0x66,0xdc,0xd,0xb1,0xb7,0x7e,0x7f,0x21, + 0xcc,0x8a,0xd0,0x58,0xcd,0xed,0x6a,0x3c,0xd7,0xf5,0xee,0x50,0x3d,0x7f,0x57,0xe3, + 0x42,0x39,0x30,0xb3,0xc3,0xf7,0x67,0xaa,0x54,0xf3,0x5c,0x8b,0x72,0x5b,0xac,0xbe, + 0xe6,0x7d,0x18,0x34,0x6c,0x82,0xef,0xc3,0xf7,0xde,0x14,0x35,0x5f,0xea,0x19,0xa1, + 0x24,0xc9,0xd4,0x68,0xc1,0x3c,0x13,0x96,0x31,0x6f,0x22,0x23,0x4a,0x4f,0xe2,0xb0, + 0xcc,0x7a,0xe4,0xb8,0x7c,0xd5,0xfb,0x74,0xb4,0x11,0x2a,0x14,0x7b,0xc2,0x36,0x20, + 0x8c,0xb,0x88,0xce,0xc7,0x9b,0x65,0x78,0x8a,0x7,0x9b,0xd4,0x56,0xfd,0x86,0x24, + 0x78,0xea,0x5c,0x74,0xc0,0x59,0x69,0xf5,0xe9,0x13,0x89,0xe4,0xd5,0xbf,0x5,0xe2, + 0x4b,0x8d,0xb1,0x13,0x29,0x96,0x8b,0x33,0x9d,0xa6,0x9,0xf4,0xa5,0xf,0x98,0x9d, + 0xf9,0xf4,0x92,0x3b,0xcd,0xfb,0x31,0x37,0xf,0xba,0x1d,0x64,0xfa,0x22,0x47,0xc5, + 0xb0,0x78,0xd8,0x59,0x8e,0xe3,0xd,0xac,0xa,0x16,0xa1,0x2f,0xa4,0xb9,0x4d,0x1e, + 0x2e,0xdf,0x59,0xfc,0xdb,0xa,0xb3,0x6a,0xc5,0xd0,0xce,0x40,0xf3,0x96,0x6,0x24, + 0x8e,0x5e,0xfc,0x1e,0xc1,0xa,0xca,0xcb,0x9f,0xeb,0xfb,0xc3,0xa5,0x49,0xe2,0x53, + 0x29,0xbb,0xcf,0x84,0xc6,0x84,0xee,0xc,0x55,0x3d,0x4c,0xc8,0x53,0x52,0x6c,0xe2, + 0x30,0x6a,0x80,0xf1,0xf3,0xca,0xbd,0x94,0x36,0xb9,0x58,0x5b,0x82,0xba,0xae,0x2b, + 0x77,0x7f,0xaf,0x3e,0x4,0x1e,0x4a,0xd8,0x5c,0x16,0xa2,0x2f,0x68,0x8e,0x91,0x98, + 0xf8,0x12,0xa,0x6d,0x5c,0xc7,0x2,0x92,0x2,0xd9,0xed,0x84,0x95,0x1d,0xb0,0x8c, + 0x9c,0xdf,0xca,0x20,0xfe,0x94,0xf8,0xda,0xaa,0x1b,0x89,0x92,0xaa,0x1c,0xaa,0x23, + 0x2e,0xb4,0x90,0xb,0xfb,0x12,0x9d,0xfd,0xec,0xc,0x3,0x2,0xa8,0x33,0xe,0x45, + 0x13,0xd8,0xe4,0x91,0xec,0xdd,0xeb,0x97,0x79,0x76,0xa9,0x24,0x92,0x54,0x47,0xc0, + 0x88,0xd8,0x4b,0x84,0xea,0x69,0x83,0x57,0x75,0x86,0xd8,0x9d,0xb9,0xe6,0x62,0x4c, + 0x3f,0x47,0xde,0xab,0xa4,0xca,0xc2,0x1e,0x41,0x6c,0x42,0x53,0xc0,0xa,0x94,0x49, + 0x62,0xdf,0xce,0x4d,0x49,0xd1,0x25,0x3e,0xd7,0x7d,0xdb,0x11,0xe4,0x3e,0x5d,0xa3, + 0x85,0xbb,0x50,0xaa,0x7,0x13,0xc8,0xc7,0x80,0x8b,0x1c,0xc0,0x95,0xb0,0x8a,0xf7, + 0x90,0xd8,0xc4,0xda,0x2a,0x69,0x19,0x2,0x67,0x75,0x13,0x4c,0xb3,0xef,0x6f,0xb9, + 0x2c,0xbf,0x64,0x33,0x53,0x2d,0xfa,0x53,0x38,0x17,0x93,0xcd,0x47,0x1e,0x45,0xd8, + 0x76,0x8a,0x33,0xa0,0xf3,0xcb,0xa2,0x5b,0x41,0x35,0x27,0xf5,0xa5,0x97,0xaf,0xd1, + 0xd6,0x93,0x5,0x2a,0xc0,0x7f,0xfc,0x79,0x17,0x91,0x47,0x5e,0xaf,0xd,0x37,0x27, + 0x97,0xe9,0x47,0xb,0xb6,0xea,0x67,0xf7,0x9f,0xe,0x6d,0x45,0x25,0x9c,0x17,0xfc, + 0x30,0x9b,0xa6,0x71,0x1c,0xa4,0xea,0x33,0xb5,0xb1,0x11,0x65,0xbe,0xc8,0xc,0x56, + 0xb2,0xd3,0x62,0x69,0x3e,0x49,0xe1,0xdd,0xd6,0x4f,0xa3,0xfc,0x6c,0xba,0xf9,0x9c, + 0xd6,0x20,0x8d,0xf2,0x44,0x78,0xa5,0xf9,0x2b,0xb6,0x60,0x69,0x7f,0xeb,0x40,0x33, + 0x3f,0x22,0x1c,0x7d,0x6b,0x7d,0x5c,0xc1,0x4d,0x0,0xbe,0xb9,0x3a,0x38,0xd5,0x11, + 0x59,0x64,0x83,0x9d,0xdc,0x29,0x98,0x87,0x60,0x78,0x71,0xdf,0xe3,0xb1,0x92,0x24, + 0xd3,0x2f,0xa1,0xbe,0x2c,0xfd,0x80,0x79,0x7d,0x40,0xb2,0xb8,0x78,0x89,0x49,0x51, + 0xed,0xcd,0xef,0x4a,0x76,0x88,0x52,0xd6,0x80,0xc3,0x37,0x64,0x75,0xc9,0x88,0xc8, + 0x78,0x2b,0x87,0xa5,0xa8,0x87,0x9e,0xa6,0x47,0x52,0x5f,0x40,0x5b,0x28,0x91,0x49, + 0xf5,0x1,0x13,0x6d,0x9,0xe4,0x44,0x89,0xa8,0xfa,0xee,0x9d,0xc5,0xf6,0x66,0xbd, + 0xa1,0x6d,0x63,0xca,0x75,0x82,0x71,0xbc,0xd4,0x50,0xfc,0x30,0x78,0xf,0xf8,0xee, + 0x10,0x8b,0x5c,0x1a,0x71,0x20,0x23,0x99,0x1c,0x12,0xb7,0x61,0x89,0x1e,0x9e,0xaa, + 0xc,0x82,0x75,0x81,0x5,0x66,0xbd,0xd9,0xb6,0x3b,0xa,0xaf,0x4a,0x82,0x9e,0xd9, + 0xe,0x7a,0x73,0xfe,0x1a,0x97,0x99,0xb5,0x29,0x51,0x17,0xb2,0xee,0x36,0xdd,0x7a, + 0xb8,0x53,0x7b,0xbd,0xba,0x3a,0x97,0xf0,0x75,0x21,0xa0,0x3f,0xa3,0x3f,0x98,0x31, + 0xb9,0xd,0x31,0x54,0xa4,0x4a,0xa,0xcd,0x9b,0xa1,0x1,0xa,0xd7,0xde,0x85,0x90, + 0xb1,0x1,0x4e,0x6c,0xba,0x65,0x5e,0x30,0x86,0x7e,0xee,0xa9,0xbe,0x88,0x5a,0xf7, + 0x95,0x8b,0x4c,0xb9,0x55,0xd6,0x7,0xf0,0x78,0x8,0xfb,0x50,0x66,0x1,0xe0,0x19, + 0x2,0xae,0x5,0x3d,0x14,0xe2,0xec,0x1a,0x62,0xdc,0x43,0xa0,0xe4,0x1d,0x18,0xf9, + 0x29,0xe4,0xb3,0x7e,0xbb,0xba,0x70,0x34,0x43,0xeb,0x84,0xa9,0x6c,0xe4,0x42,0xed, + 0x13,0xc7,0x2b,0xa6,0xaa,0x19,0x40,0x8c,0xf5,0x3,0xac,0x5a,0x20,0xc5,0x54,0x49, + 0xaa,0x8,0xc8,0xe5,0xc2,0xb8,0x1a,0x6,0x24,0x1e,0x30,0x90,0x82,0x72,0x7e,0x95, + 0x3a,0xaa,0xbb,0x65,0xc3,0xfb,0x71,0x39,0xfe,0x1f,0x93,0x1f,0xe4,0xe7,0xe8,0xf, + 0xef,0xb1,0xf4,0x32,0x6a,0x8e,0xb8,0xe,0xac,0x68,0x9e,0xae,0xda,0x1d,0x44,0x95, + 0xc7,0x7f,0x7a,0xb,0x7b,0xeb,0x44,0x7a,0xb,0x57,0x19,0x6f,0x3f,0x2,0xfd,0xae, + 0x33,0x72,0xe1,0x1d,0x1,0x1a,0x2b,0x2d,0x82,0xc9,0xdb,0xdc,0xe7,0x9f,0xf1,0x2f, + 0x1f,0x6c,0x3b,0x9a,0xd8,0xfe,0x94,0x63,0x57,0x2e,0xd3,0x16,0x30,0x51,0xc5,0x64, + 0xc4,0x27,0x81,0xc5,0x41,0x2d,0xf3,0x43,0xf6,0x4f,0x20,0x5e,0xef,0x92,0x8e,0xf, + 0x7e,0x49,0x2a,0x57,0xc7,0xbe,0x3b,0x1f,0x6c,0x8e,0xb5,0x9d,0xdf,0x7b,0x81,0xa4, + 0x22,0x82,0x6b,0xe2,0xaf,0xde,0x26,0xa7,0x2e,0xc5,0x85,0x9d,0x58,0x14,0xad,0xd7, + 0xdc,0x57,0xae,0xa5,0x95,0xe9,0x44,0x3,0x78,0xf9,0xa0,0x59,0xf4,0xa1,0x7d,0x17, + 0xa3,0x68,0xf9,0x54,0x47,0x9f,0x7b,0xf5,0x66,0x1,0x93,0x3e,0x95,0xc0,0x95,0xf1, + 0x97,0x45,0x17,0x2e,0xae,0x5c,0x31,0x28,0xd5,0x51,0x1,0x4b,0x72,0x7e,0xe1,0x16, + 0xe7,0xdc,0x6a,0xae,0xfb,0x65,0x24,0xe1,0xe6,0x38,0x21,0x7c,0xf8,0xb6,0x6e,0x11, + 0xfb,0x86,0x3f,0xab,0x62,0xef,0x53,0xb7,0xc0,0x54,0x3,0x33,0x52,0xe5,0x49,0xb9, + 0x42,0x34,0x69,0xbd,0x19,0x8d,0xa0,0x0,0xc5,0xc1,0x7c,0x3f,0x78,0x6b,0x50,0xf4, + 0x71,0xf,0x20,0x53,0xfe,0x73,0xb,0xbf,0x47,0x8e,0xf2,0x99,0xf3,0xbb,0x54,0xb5, + 0x6f,0x3d,0x73,0x89,0xca,0x14,0x89,0x11,0x55,0x86,0x50,0xce,0x71,0x20,0x43,0x62, + 0x2f,0x63,0xb5,0x2e,0x56,0x40,0x6d,0x9d,0xce,0x60,0xb6,0x42,0x9b,0xb,0xf7,0xc, + 0xc7,0xeb,0x15,0x93,0x0,0x9e,0x24,0xd5,0xa4,0xf3,0xa4,0x95,0x14,0x67,0xf7,0xc2, + 0xca,0xad,0x70,0xa0,0x6e,0xdd,0x3e,0x3d,0xbd,0xf4,0x0,0x59,0x80,0xf7,0xe4,0x48, + 0x63,0xf9,0x5b,0x64,0x19,0x7f,0xb9,0x3d,0xf2,0xdd,0xd3,0x7,0x45,0xcb,0x49,0x8f, + 0xf9,0xb9,0x30,0x68,0x97,0xed,0x25,0x55,0xe2,0xa4,0x2f,0xe2,0x9d,0x14,0xab,0x1, + 0x8e,0x7,0xe4,0x27,0x7,0x9e,0x64,0xf9,0x7c,0xb7,0x81,0x41,0x4,0xca,0xd0,0xfd, + 0x85,0x80,0xe5,0x9c,0x6e,0x8a,0xf2,0xd1,0x30,0x22,0xb4,0x4d,0xb5,0x60,0xcd,0xc3, + 0xe7,0x33,0xea,0x6e,0x51,0x50,0x68,0x4e,0x8,0x69,0x8f,0xc,0xb4,0xe0,0x89,0x3a, + 0x61,0xee,0xd6,0xd0,0xf9,0x49,0xa2,0xa9,0xea,0xd6,0xf6,0x21,0x38,0x44,0xe4,0x9f, + 0x77,0xd0,0xe,0x49,0x21,0xf5,0x97,0xa8,0x60,0xa6,0x35,0x94,0x7,0x3e,0xce,0x69, + 0xad,0x25,0xb9,0xa7,0xee,0x5c,0x51,0xd9,0x33,0xc7,0xfa,0xea,0xc,0xe0,0xa,0x4, + 0x31,0x18,0xcc,0xd1,0x8e,0xe3,0x7a,0x6e,0x8a,0x2f,0x3,0x12,0xed,0x51,0x7b,0x9b, + 0xf5,0x35,0x43,0xe4,0x11,0x14,0x3f,0x44,0xdb,0xb9,0xaf,0x67,0x1a,0xb9,0xea,0x4b, + 0x52,0xb7,0x1d,0xe0,0x9b,0x18,0xce,0xa6,0x47,0xd1,0xb8,0xb4,0xa2,0xb3,0x50,0x98, + 0x68,0x13,0x7e,0x79,0x27,0xbd,0x3d,0x82,0xf6,0x6c,0xea,0x12,0x27,0x55,0x5d,0xf8, + 0xe,0x7b,0x59,0x29,0x13,0x28,0x4f,0x5a,0x79,0x87,0x10,0x1c,0xba,0xdf,0xb4,0x23, + 0xf3,0xb2,0x9c,0x1b,0xef,0x5a,0x1e,0xe7,0xc6,0x88,0xf9,0x6d,0xdd,0x57,0x66,0x6b, + 0x52,0xbf,0x95,0x65,0x67,0x64,0x40,0xe0,0x6c,0xcf,0x7c,0x27,0xaf,0xb1,0x4b,0x23, + 0x64,0x67,0xbe,0xd4,0xc1,0xdc,0xbc,0x89,0x65,0x36,0xf6,0x43,0xd,0xdd,0xaf,0x60, + 0x1d,0xc4,0x45,0x85,0xa8,0x5,0xe5,0x15,0xd4,0x63,0x3d,0x5,0x94,0x88,0x28,0x78, + 0xef,0xe6,0x4d,0x32,0x43,0x89,0x3b,0xa8,0xbf,0xb1,0x6c,0xcd,0x8f,0x1c,0xad,0xad, + 0x60,0xf2,0xb2,0x9,0xf8,0x98,0x9e,0x4d,0x7b,0xdb,0x52,0x8f,0xe3,0xfa,0x9,0x53, + 0x61,0x56,0x85,0xa5,0xe0,0x40,0x4e,0xa0,0xf2,0xba,0xed,0x2,0x56,0x9b,0x2f,0x36, + 0xf,0xe1,0xbf,0x87,0xfa,0x5e,0x54,0xf5,0x3a,0x27,0x86,0x9d,0xa1,0x8f,0xf0,0x3, + 0xe5,0xf6,0xa8,0x46,0xb6,0x77,0x67,0xa9,0x32,0x55,0x2c,0x9,0x71,0x5b,0x3f,0x0, + 0xbd,0xfe,0x7,0xb8,0xdc,0xda,0xae,0x96,0x2,0xb4,0x34,0xa3,0x44,0xa5,0xa7,0xaa, + 0x9c,0xcf,0x70,0x53,0x47,0xd7,0x7d,0xf9,0xad,0xa9,0x82,0x9e,0x84,0xc1,0x9e,0x42, + 0x41,0x25,0xfa,0x1e,0x0,0x2a,0xb5,0x82,0xde,0x69,0x26,0x24,0xf,0x4d,0x4e,0x2b, + 0x9d,0xbe,0xfe,0x64,0x97,0xfb,0xdd,0xc4,0xa5,0x60,0x63,0xa9,0xa2,0x81,0xec,0xe3, + 0xa6,0xe7,0x81,0x26,0x91,0xb6,0xa8,0x71,0x21,0x4f,0x15,0x30,0x1c,0x63,0xdb,0xb9, + 0xa1,0xda,0x9e,0xb8,0xd6,0x7c,0x7d,0xfb,0xdd,0x60,0xa5,0x80,0xe1,0x92,0xe3,0x8, + 0xfa,0xe4,0xae,0x8c,0x9c,0x57,0x7d,0x3d,0x26,0x92,0xec,0xc2,0x75,0xc8,0xfb,0x18, + 0x23,0x9a,0x50,0x79,0x18,0x4e,0xf4,0xf5,0xae,0x1b,0xf5,0x91,0x2d,0x59,0x19,0x28, + 0x3e,0xc7,0x35,0x5a,0x9f,0xb2,0x97,0x45,0xc5,0x85,0x8,0x3b,0xcd,0x5,0xd2,0xf1, + 0x9f,0x24,0xea,0xb7,0xf1,0xe0,0x2d,0xa0,0xfb,0xa2,0xb1,0x29,0xfb,0xcb,0xd1,0xba, + 0x13,0x86,0x15,0xb2,0x39,0xad,0x78,0x7e,0xb2,0x80,0xba,0x80,0x5,0xd,0xf1,0xa5, + 0xb0,0xdd,0xdc,0xa2,0x3e,0x8a,0x44,0xb9,0x2d,0x75,0xe2,0x2a,0x41,0x34,0xe4,0xd4, + 0xba,0x79,0x7,0x74,0xa6,0x7f,0xf2,0x59,0x80,0x2d,0x5a,0x85,0xba,0xcb,0xaa,0xea, + 0x29,0x8,0x8e,0x67,0x92,0x52,0xa0,0xbf,0xc7,0x4,0x69,0x89,0x38,0xcd,0x5e,0x73, + 0x48,0xe4,0x67,0xee,0x65,0x5a,0xc8,0x65,0x8,0xa2,0xea,0x42,0x6e,0x16,0x2d,0x18, + 0x1e,0x3b,0xfe,0xb0,0x8d,0xa0,0xef,0xd5,0xa4,0x5a,0xde,0x5c,0x28,0xbc,0xcf,0xef, + 0xa1,0x37,0x5f,0x86,0x12,0x28,0xeb,0x99,0xca,0xd7,0xdb,0xb8,0xed,0x88,0xd0,0x8b, + 0xc4,0x50,0x3c,0x52,0xf0,0x2c,0xa7,0x15,0x6,0x86,0x71,0x2f,0x43,0xc1,0x9e,0x65, + 0xf8,0xfd,0xeb,0x8a,0x26,0xd8,0x24,0x70,0x30,0x7f,0xa9,0x9d,0x88,0xf9,0x29,0x4d, + 0x4a,0xe4,0x1f,0xba,0x90,0xc7,0xcf,0x97,0xcd,0x42,0x46,0x91,0x4,0xe4,0xf6,0x7c, + 0xe3,0x62,0x8,0x89,0xba,0xab,0x7a,0x6a,0xab,0x24,0x87,0x34,0x1e,0x30,0x1,0xe8, + 0x15,0x20,0xa3,0xa6,0x67,0x74,0xbd,0x36,0x36,0x4,0x47,0xb9,0x68,0x3e,0x36,0x4c, + 0x20,0xbd,0x56,0xdb,0xe9,0xd0,0xc5,0x15,0xf4,0x4e,0xc8,0x92,0x7e,0xc9,0x7b,0x94, + 0xe9,0x9f,0xba,0x52,0x14,0x78,0x8,0xc9,0xfb,0x4f,0x83,0x64,0xd,0x39,0x31,0x2d, + 0x77,0x7,0x88,0xe0,0xd7,0x4f,0xf5,0x4c,0x9d,0x3e,0x5e,0x9b,0x8,0xda,0x30,0xf1, + 0xf9,0x6a,0xc3,0xe,0x62,0xcb,0x57,0xdd,0x9a,0x5a,0x43,0xa7,0x93,0xf3,0x55,0x8a, + 0xfa,0x5d,0xea,0x52,0x2c,0xe0,0x9e,0xc9,0x1f,0xfc,0xe5,0xa6,0x57,0x16,0x19,0x51, + 0x1,0xdc,0xde,0x63,0x29,0x36,0x42,0xc3,0x10,0x5,0xeb,0x24,0x78,0x41,0xae,0x73, + 0x1e,0x9a,0xc5,0x4b,0xfa,0xe3,0x94,0x9a,0xe0,0x7a,0x41,0xb8,0x11,0x5a,0xa,0x12, + 0xb7,0x69,0xf4,0xe0,0x1f,0xb6,0x24,0x30,0x3b,0x10,0x54,0xb3,0xd0,0x82,0x27,0x6f, + 0x9c,0x6c,0xba,0x98,0x50,0x4f,0xb2,0xb1,0x4a,0x73,0x6a,0x5b,0x4e,0xf3,0xec,0x6, + 0x5d,0xe1,0x66,0x7d,0x19,0xa,0x2d,0x54,0x9a,0x1,0x9,0x6b,0x83,0xaf,0xda,0x21, + 0x9c,0x15,0x39,0xec,0xe4,0x6b,0x1e,0x2f,0x5e,0x88,0x8a,0xac,0x7d,0x77,0x32,0x5a, + 0xd8,0x18,0x57,0xf1,0x23,0x84,0x47,0xbd,0x5,0xcf,0xa8,0x89,0x7f,0x4,0x2a,0x1c, + 0x19,0xe2,0x89,0xfd,0x4e,0xa7,0x2d,0x2c,0xb0,0x37,0xd9,0xad,0xae,0x8b,0x8,0x88, + 0xa4,0xdf,0x7a,0x47,0xe3,0x41,0x5,0xe9,0x11,0x2d,0xf2,0x11,0xb0,0x1d,0xac,0xca, + 0x7f,0x36,0x48,0x4d,0x5e,0xf5,0x79,0xf,0xac,0x53,0xbc,0xdb,0x5f,0x44,0xe3,0x4, + 0x24,0xdd,0xca,0x88,0x20,0x4f,0x72,0x31,0x7c,0x65,0xc1,0x2e,0x2,0x6f,0x78,0x81, + 0xa5,0x40,0xce,0x83,0xb5,0xc7,0x92,0x63,0x9b,0xce,0x3f,0xfa,0x14,0x23,0x7e,0xb7, + 0x1,0x49,0xbf,0xa0,0x98,0x32,0xd2,0x15,0x17,0x14,0xc2,0x98,0x83,0xba,0x99,0xa9, + 0xfb,0xe7,0x2d,0xb1,0xb0,0xc0,0x94,0x4c,0x8f,0x53,0x47,0x23,0x76,0x45,0x5b,0xf7, + 0x8e,0x1b,0x98,0x27,0xcd,0xea,0xbb,0x64,0x0,0x7f,0xfd,0x83,0x3a,0x17,0x2d,0xb5, + 0x0,0x5b,0xe7,0xb0,0x9b,0x7c,0x7c,0xaa,0xd0,0x43,0x4e,0xc6,0x88,0xa9,0x3e,0x17, + 0x44,0xd7,0xbd,0x91,0xc2,0x79,0xf6,0x42,0xf8,0x74,0x46,0xb3,0xb,0x73,0x69,0xb, + 0x4e,0xd0,0x3b,0x69,0xcd,0x37,0x15,0x1e,0x7a,0x63,0xe4,0x82,0x8c,0x24,0x19,0x50, + 0x7b,0xd6,0xe2,0xbd,0x51,0x59,0x1,0x4a,0x4d,0x47,0x7d,0x58,0x3a,0x67,0xe3,0x9, + 0x38,0x1f,0x72,0x6,0x57,0x87,0x24,0x51,0x6a,0x89,0x54,0x76,0x2d,0x6d,0x47,0xa8, + 0x45,0xa9,0x66,0x96,0x3,0x67,0x60,0xcf,0x2e,0xde,0xa7,0x69,0x46,0x8b,0xf1,0xfd, + 0x2b,0x64,0x84,0x2,0x6c,0xa8,0x53,0x56,0xb1,0xa7,0xcd,0xde,0x16,0x15,0x87,0xda, + 0xbe,0x6e,0x71,0x41,0xd5,0xd1,0x90,0x84,0x30,0x38,0xed,0x76,0xc4,0xdf,0xf4,0x6f, + 0xc3,0x79,0x71,0x30,0xa1,0x44,0x87,0x54,0xec,0xd4,0x33,0x82,0x69,0x3b,0x5d,0xa7, + 0xa9,0x4e,0x68,0xfe,0x20,0xf8,0x83,0x51,0xb0,0xf0,0x47,0xf4,0x50,0x3c,0x64,0x15, + 0x35,0xd5,0xc4,0xd7,0x1b,0xcb,0x2c,0x87,0xa0,0xde,0x89,0x89,0x1a,0xe6,0x31,0x43, + 0xb4,0x99,0x43,0xd4,0x12,0xc6,0xa5,0xc3,0x38,0x6d,0xb8,0x88,0x29,0x1e,0x9d,0x5f, + 0x73,0xe2,0x37,0x8e,0xae,0xe2,0x95,0x50,0xc1,0x1f,0xd9,0x5c,0x85,0x8b,0x9f,0x3a, + 0xa4,0xe2,0x10,0xb7,0x2a,0x35,0x7b,0x62,0xa2,0xb3,0x6a,0xcc,0xd1,0x88,0x2c,0xc5, + 0x6b,0xe2,0x54,0x1a,0xc5,0xea,0xe9,0x87,0xa,0x44,0xe3,0x10,0xcf,0x84,0x4a,0x74, + 0xe6,0xd9,0xab,0x11,0x10,0x27,0xf2,0x32,0x5b,0x5e,0xfe,0xac,0xe6,0xaa,0x72,0x52, + 0xd,0xc7,0xeb,0xd2,0x32,0xd6,0xda,0xbb,0x1b,0xbe,0xcb,0x6a,0xc2,0x96,0x5e,0x2a, + 0x70,0xb,0xba,0x0,0xb1,0xae,0x33,0xd,0x8c,0xb1,0xba,0xf2,0x5d,0xac,0xc4,0x6a, + 0xf3,0xb0,0xbd,0x26,0x7,0x98,0x62,0x22,0xd6,0xad,0xc,0x1a,0x44,0x6b,0x44,0x35, + 0xf5,0x7e,0x35,0xa7,0xac,0x68,0x35,0x39,0x1b,0x6f,0x2c,0xf7,0x1c,0x70,0xe1,0x11, + 0x22,0x9f,0xb6,0x29,0xb7,0x98,0xcb,0x8f,0x47,0xd7,0x29,0xb,0xc2,0x6d,0x40,0xb8, + 0x6b,0x76,0xe0,0x19,0x5e,0x16,0x52,0xf8,0x85,0xfe,0xf0,0x21,0x6f,0x53,0x32,0x11, + 0x72,0x69,0x3b,0x2b,0x2,0x7,0x3a,0x49,0x5e,0x63,0x55,0xa1,0x50,0x15,0x5a,0xbb, + 0x8b,0x3b,0xd4,0x6a,0xd0,0xa7,0x63,0xd5,0x26,0xd4,0xf7,0x15,0x28,0x2a,0x27,0x9a, + 0x93,0xe1,0x45,0x16,0x68,0xfe,0x5f,0x46,0x62,0x34,0xe7,0x32,0x4a,0xc2,0xee,0x55, + 0xfd,0x43,0xbf,0x4f,0x6a,0x24,0x25,0x10,0xf8,0x1d,0x26,0xa0,0xc7,0xcc,0xba,0xda, + 0x2e,0x1,0xf0,0x96,0x0,0x51,0x5c,0xe2,0x5,0x45,0x15,0x4f,0x8,0x83,0xa5,0x85, + 0x47,0xe4,0xd4,0xb1,0x9,0xfa,0xc2,0x81,0x97,0x68,0x22,0x5f,0xb4,0x5d,0x3b,0xe2, + 0xdd,0x2c,0xf8,0x5d,0xfc,0x55,0x40,0x3,0x9a,0xd5,0xd1,0x22,0xd8,0xf6,0xa8,0x20, + 0xdc,0xfc,0x52,0x65,0x77,0x15,0xe7,0x10,0xfc,0x89,0x6f,0xb1,0xe6,0xaa,0x94,0xc4, + 0x57,0x8d,0x23,0xd3,0x62,0xe2,0x56,0xfd,0xb8,0x29,0x9f,0x12,0x9f,0xc7,0x32,0x7c, + 0xc5,0x84,0xe2,0x3d,0x19,0x4a,0x4d,0x16,0xd3,0xbd,0x47,0xbb,0xe7,0xdb,0x0,0xbe, + 0xe8,0xa2,0x93,0xcb,0x86,0x69,0x49,0xbe,0x92,0xe8,0xd0,0x33,0xb1,0x83,0x2f,0x77, + 0x87,0x91,0x34,0xa1,0xdb,0x82,0x37,0xb0,0xbf,0xfe,0xeb,0x27,0x5a,0x6b,0xe6,0x44, + 0xf,0xf9,0x10,0x15,0x63,0x59,0xd3,0x76,0xc1,0x25,0x29,0x73,0xa8,0xd7,0x6a,0x30, + 0x6a,0x9f,0x51,0x46,0xa1,0x9,0x76,0x61,0x8,0xe1,0x88,0x62,0x4e,0xee,0x26,0xdc, + 0x68,0xb5,0xf1,0xcc,0x8e,0x45,0xc2,0x51,0xe9,0xeb,0xc4,0x92,0xc3,0xaf,0x43,0xad, + 0x4f,0x14,0xf4,0xf0,0x9c,0xea,0xd1,0xa4,0x4d,0xd9,0x87,0x1b,0xc9,0xad,0xf7,0x32, + 0x64,0x69,0x7e,0xf2,0x2e,0x41,0xc3,0x19,0x2d,0x9,0x2b,0x71,0xb8,0xed,0x1f,0x87, + 0x3,0x93,0xf7,0x9f,0xfe,0xc9,0xc4,0x4c,0xa3,0x4c,0x67,0x6d,0xf9,0xde,0x20,0xdd, + 0x48,0x9e,0x51,0xf5,0xe0,0x15,0xf,0x8d,0x1e,0x3b,0x7e,0x56,0x29,0x1e,0xdd,0xab, + 0xb1,0xd5,0x4c,0xb0,0x1f,0x90,0x7c,0xc3,0xdc,0xe3,0xb0,0x56,0x42,0x50,0xb4,0xa, + 0xef,0x6,0x1,0x50,0x9a,0x10,0x5d,0xb9,0xca,0xdc,0x10,0xf4,0xfa,0x6e,0xa0,0x2c, + 0xc3,0x6c,0x5d,0xe3,0x7c,0xd9,0xa7,0x59,0x3e,0xd7,0x30,0x80,0x29,0x64,0x8b,0x98, + 0x6a,0xc,0x68,0x84,0x1c,0xc5,0xbd,0x67,0x22,0x4e,0x5c,0x9c,0xbc,0x7c,0xc9,0x80, + 0x69,0xa6,0x64,0xe5,0x80,0x8b,0xbf,0x3e,0xe3,0x6f,0xbf,0x8c,0xd3,0xca,0x25,0xbd, + 0xd6,0xd,0x42,0x72,0xd2,0x80,0xd9,0x75,0xce,0xb5,0x12,0xb,0xb2,0x5b,0x8b,0x9b, + 0x2,0x70,0x81,0x3,0x7b,0xc0,0x41,0x5f,0xaf,0x80,0x6b,0x83,0xca,0x90,0xc0,0x21, + 0x1d,0x83,0x14,0xf0,0x4,0x6d,0xe5,0x52,0x24,0xf7,0x5d,0x56,0x54,0x68,0xf1,0xd5, + 0xd8,0xf2,0xd8,0xd4,0x34,0x9a,0x34,0xe3,0x9a,0xa0,0xe7,0x66,0xb0,0xa8,0x7,0x4e, + 0xab,0x1b,0x3f,0xaf,0x89,0x25,0x2,0x2d,0x9c,0xde,0x83,0x70,0x48,0xf4,0x47,0x21, + 0xe7,0x9f,0xf5,0x1c,0xb9,0xaa,0x1,0x55,0xca,0x68,0x3b,0xfa,0x11,0x42,0x49,0xbd, + 0x5e,0x8,0xec,0xe7,0xac,0x6f,0x15,0x4a,0x4e,0x18,0xba,0x96,0xd,0x81,0x38,0xf4, + 0xa1,0xad,0x91,0x5b,0x58,0x12,0xb0,0xa2,0x7a,0xeb,0x9e,0x8b,0xae,0x67,0xc8,0xd, + 0x70,0x36,0x74,0x1d,0xa5,0x89,0xe6,0x73,0xa1,0xa2,0xb,0x2e,0xa3,0xc2,0x23,0x45, + 0x70,0x34,0xa1,0xc9,0x46,0xd1,0xeb,0xc0,0x3e,0x8a,0xcc,0xec,0x72,0x15,0x79,0xe2, + 0x4b,0xed,0x7f,0x70,0x77,0x67,0xe4,0x98,0x89,0x6f,0x46,0x2d,0x32,0x69,0xf2,0xa2, + 0x9e,0x14,0xeb,0xe4,0xe5,0xd8,0x26,0x24,0xe2,0xf2,0x90,0x55,0x8,0xa,0x38,0xd3, + 0xf7,0x38,0x44,0xee,0x9f,0x29,0x7,0xa8,0x18,0x4d,0x55,0x4a,0x37,0x48,0xed,0x55, + 0x5c,0xd9,0xb9,0xc2,0x32,0xdf,0xe6,0x16,0x52,0xf7,0x6b,0xda,0x2,0x24,0xae,0x7a, + 0xdb,0xf2,0xe8,0x7b,0x9c,0xf0,0xa3,0xb4,0xbd,0xf8,0x7f,0xf4,0x42,0x6d,0xc9,0x1e, + 0xc6,0x84,0xe0,0xf9,0xe3,0x48,0x8f,0x37,0x40,0x7a,0x12,0xc1,0x1e,0x40,0xbb,0xf9, + 0xb2,0xa5,0xf4,0x4f,0x16,0x98,0x84,0xd3,0x12,0x4,0x49,0xd3,0xf0,0x13,0xf1,0x37, + 0x97,0x53,0xb0,0x7c,0x1b,0x40,0x33,0xda,0x3b,0x45,0x9c,0x59,0x5,0xd8,0xd3,0xb7, + 0x7e,0x48,0x87,0x94,0xe1,0xc,0xe7,0x73,0x8f,0x31,0x47,0x0,0xc4,0xb8,0xb6,0x5c, + 0x8b,0x68,0x58,0xa6,0x28,0xb,0x81,0x63,0x50,0x9e,0x3d,0x55,0x77,0x11,0x8d,0x75, + 0x59,0x15,0x89,0xba,0xa0,0x71,0xad,0xaf,0x23,0xf4,0xaf,0xe7,0x2e,0x66,0xc3,0xb9, + 0x4e,0x9c,0x61,0x77,0xa7,0x62,0xda,0x78,0x1,0x97,0x4d,0xf7,0xa8,0xda,0x6d,0x82, + 0xef,0xf6,0xbc,0x90,0xe8,0x6b,0x40,0x8b,0x60,0x6f,0x73,0xe,0x56,0xb6,0xc8,0xa4, + 0x53,0xa9,0x9b,0xfb,0xc,0xf6,0x74,0x8d,0x8e,0xc1,0x85,0x38,0x1d,0x73,0x3a,0xd, + 0xe9,0xf6,0x1e,0xd2,0x62,0x5e,0x5e,0x43,0x4e,0x51,0x51,0xa4,0x9,0x99,0xc8,0x5c, + 0x43,0x65,0xd7,0xcf,0x5c,0xcb,0xdc,0xea,0xe,0x62,0xa2,0x2b,0xd5,0xdc,0x38,0xc0, + 0x54,0xd5,0x13,0xb6,0x35,0xf1,0xf9,0x3,0x43,0xcb,0xa7,0xcb,0x65,0xef,0xa8,0x29, + 0xd4,0x80,0x78,0x31,0xcc,0x55,0x9c,0xda,0xb7,0xbe,0x6,0xe,0x1c,0xbd,0x4e,0x70, + 0x94,0xe0,0xa6,0x49,0xd2,0x21,0x4c,0x96,0xec,0x73,0x62,0x52,0x63,0x8a,0xfa,0xb8, + 0xc,0x73,0xe9,0xd8,0xc8,0x6,0x33,0x1,0xc5,0x39,0x8e,0x61,0x76,0x5c,0xd1,0x8a, + 0x3d,0x78,0xd3,0x90,0x99,0x9f,0xa6,0x6,0x13,0x9,0xd8,0xf6,0x14,0xd3,0xaf,0x9f, + 0x48,0x19,0xf7,0x90,0x9f,0x2b,0x11,0xe4,0xe3,0x9f,0x46,0x5a,0xfb,0x97,0x65,0xb9, + 0x10,0x39,0xc9,0x2a,0xd9,0x70,0x30,0x6c,0xf8,0x88,0xe2,0xd,0x5d,0x92,0xac,0x25, + 0x2c,0xa4,0x35,0xcb,0xcf,0x47,0xb0,0xb3,0x66,0xf6,0x8e,0x63,0x8e,0xf3,0x9c,0x1e, + 0xac,0x66,0xc7,0x6,0xd6,0x78,0x73,0xcf,0x1,0x56,0x5d,0xdd,0x69,0xa,0x3,0x95, + 0xaf,0xb8,0xe0,0xfe,0x0,0x91,0x33,0x66,0x8,0xc1,0x49,0x16,0x35,0x65,0x34,0x61, + 0x4b,0x7c,0x68,0x22,0xf4,0x5b,0x72,0x75,0x31,0x4f,0x54,0x1a,0x59,0xd6,0xaf,0x88, + 0x8f,0x10,0x88,0xf,0xa1,0xbb,0xf5,0x29,0xfc,0xbe,0x3f,0xb1,0xa4,0xf3,0x13,0xef, + 0x70,0x7b,0x92,0xe4,0x56,0x5,0xd9,0x88,0x54,0xad,0xa2,0x2d,0x85,0xd2,0xb6,0x94, + 0xe2,0x3f,0x24,0x5,0x7a,0x99,0xad,0x77,0x58,0xed,0x29,0xfc,0x61,0x3c,0xed,0x51, + 0x38,0x80,0xb5,0x8e,0x5,0x8f,0x96,0xd8,0x3e,0xb9,0x6,0x43,0x8c,0x3c,0xd7,0xee, + 0x7b,0x7b,0x73,0x75,0x15,0x22,0xec,0x6e,0x8f,0x95,0xea,0xf0,0x52,0x58,0x42,0x8a, + 0x58,0xf7,0x98,0x5d,0x87,0x30,0xb5,0x45,0x69,0x3c,0x88,0xf5,0x78,0xe0,0x64,0x74, + 0x5c,0xd8,0xe9,0x72,0x7a,0x57,0x60,0xa,0xec,0xca,0xfa,0x3f,0x24,0xbc,0xc9,0xfb, + 0xb4,0xe2,0x5a,0xbb,0x92,0x8f,0x81,0xfb,0xcb,0xa,0x71,0x45,0xea,0xd5,0x39,0x48, + 0x2e,0x23,0x3a,0x28,0x7a,0x1a,0x32,0x68,0xe4,0xac,0x27,0x88,0x69,0xf1,0x85,0x9d, + 0x54,0x5f,0xd9,0xe6,0xee,0x5b,0xe2,0x3b,0x65,0xd3,0x80,0xd0,0xa9,0x39,0x98,0x58, + 0x5c,0xd2,0x80,0x57,0x6c,0x33,0xbf,0x51,0x5f,0xe6,0x5a,0x49,0x58,0xdf,0xe6,0xac, + 0x3f,0x40,0x13,0xad,0x1b,0x75,0xe8,0x1,0x49,0xe8,0xd1,0xf3,0x22,0x6a,0xcb,0xfe, + 0xbc,0xcb,0x56,0xa8,0x7e,0x16,0xf9,0xde,0x7c,0xd3,0x28,0x55,0xb3,0x8e,0x81,0x72, + 0xcf,0x95,0x21,0x6a,0xb,0x89,0x6b,0x55,0xf2,0x3d,0xc8,0x15,0x27,0x94,0x14,0x63, + 0xdf,0xe9,0xc,0x5f,0x7f,0x86,0x3e,0xfc,0x5a,0xe5,0xd1,0xf,0x74,0x53,0x1,0xc3, + 0x68,0xa1,0x2f,0x74,0x2c,0x9a,0x49,0x1f,0x58,0x12,0xb3,0x7f,0x26,0x48,0x63,0x85, + 0x32,0x6f,0xe4,0xb2,0xf5,0xa2,0x2f,0xd0,0x88,0x1,0xdf,0x7d,0xd3,0x60,0x41,0x3d, + 0x3,0xef,0xb1,0x2f,0x8b,0x7a,0xcd,0x63,0x8c,0x1,0xe2,0x32,0x49,0x46,0xb7,0x7c, + 0x36,0x9d,0xae,0x2c,0xbf,0x5d,0x7c,0x49,0x5e,0xdb,0xc6,0xb1,0x3d,0x87,0xee,0x40, + 0x78,0x20,0xee,0x83,0x9a,0x3c,0xe6,0xa6,0x3d,0xc9,0xd8,0x87,0x90,0x11,0x83,0xc6, + 0x2e,0xb1,0x72,0xed,0xf,0xef,0x37,0xec,0xcb,0x7d,0x9e,0x88,0x6,0x8e,0xc8,0x7e, + 0xae,0x37,0x2,0xc9,0x73,0xe8,0x70,0x31,0x32,0xc9,0xb8,0x42,0xda,0xbb,0x88,0x9, + 0x6d,0x7b,0xf6,0x7c,0xea,0xae,0x69,0x36,0x2c,0x8,0xbf,0x32,0x16,0x8,0xb0,0x45, + 0x40,0x32,0xf,0x33,0x9a,0xfe,0x64,0xcd,0x48,0x9c,0x8f,0x23,0x58,0x19,0xab,0x45, + 0x14,0x23,0xc1,0xfe,0xd1,0xaa,0x35,0x7d,0x33,0x74,0xb0,0xc8,0x7d,0xe0,0xe,0x3d, + 0x93,0x9c,0x70,0x2e,0x1c,0x55,0x7b,0x64,0xf1,0xc,0x8,0xca,0xa4,0xb3,0x10,0xb8, + 0x56,0x52,0x37,0xa7,0xfc,0xeb,0x26,0xaf,0x61,0x56,0x79,0x5e,0xb6,0x7,0x9b,0x4a, + 0xa4,0x8b,0x79,0xc0,0xe0,0xf4,0xa4,0x53,0x80,0xac,0x1e,0x25,0xe0,0x2e,0x5d,0x37, + 0x0,0x14,0xdf,0x7d,0x1,0x85,0x2d,0xe1,0xdb,0x26,0x40,0x92,0x2e,0x5b,0x5d,0xd2, + 0xe6,0xd6,0x13,0x48,0x4b,0xb7,0x1b,0xcc,0x65,0x39,0x71,0x46,0xe6,0x4f,0xfc,0xe7, + 0x63,0xdc,0x65,0xe3,0x62,0x92,0xc5,0xbd,0x39,0x85,0x51,0x67,0xe0,0xae,0xb9,0x48, + 0x5,0xcc,0x10,0xcf,0x4,0x2b,0x9c,0x69,0x64,0x8e,0x2f,0xca,0x5d,0x2d,0xb2,0x40, + 0x89,0x18,0x25,0x6c,0x2b,0x6a,0x2a,0x64,0xf0,0xfa,0x4b,0x51,0x29,0x5,0x19,0xad, + 0xd1,0x29,0x7e,0xd5,0xd3,0x9a,0xbf,0xb7,0x29,0x6e,0x83,0x6,0x1b,0x36,0x47,0x25, + 0xce,0xeb,0x91,0x79,0x56,0xbb,0x5d,0xc6,0x37,0xa8,0x98,0x60,0xad,0xb1,0xf,0xfe, + 0x5b,0x8d,0x54,0x2f,0xa7,0x93,0xe7,0xd1,0x3,0x6b,0xd7,0x9d,0x21,0x9e,0xc2,0x6f, + 0x8a,0x54,0x68,0xe1,0x90,0xc5,0x28,0x47,0xed,0xc0,0x27,0x1b,0x73,0xb5,0x1a,0x4e, + 0xc2,0xee,0x7d,0x6b,0x82,0xe4,0x3d,0x5,0xcf,0x94,0xa3,0x71,0x34,0xe5,0xe0,0x3e, + 0x3b,0xc9,0x20,0x4b,0xf,0xc8,0x12,0xfd,0x89,0x39,0x19,0x7c,0xef,0xb3,0x4a,0xb2, + 0xa2,0xc8,0x1e,0x25,0x2d,0xda,0x2b,0xfd,0x70,0x4e,0x6f,0x24,0x34,0xcf,0x62,0xee, + 0x99,0x3,0xb9,0x29,0xcb,0xcb,0x27,0xd4,0x6,0xbf,0xd1,0xf5,0x73,0x1c,0x28,0x95, + 0x64,0x47,0x3b,0x92,0x22,0x66,0x90,0x92,0x34,0x7f,0x36,0x68,0x4f,0x99,0xd7,0x69, + 0x1c,0x91,0x92,0x67,0x5e,0x39,0xbb,0xe3,0xf8,0x8d,0x59,0xec,0x2a,0x81,0x82,0x8e, + 0xc8,0xbd,0x21,0xeb,0xa3,0x31,0xfd,0xd7,0xb0,0xb4,0xc0,0x1,0xcd,0x98,0xe9,0xe9, + 0xa9,0xfb,0x51,0x8,0x35,0x8c,0xeb,0x2e,0x1b,0xc4,0x9a,0x45,0x47,0x9d,0xd3,0x10, + 0x5b,0x75,0x7b,0x7f,0xa6,0x7a,0xd6,0x58,0xae,0x17,0xd8,0x7c,0xaf,0x42,0x66,0x5a, + 0x3e,0x37,0xe1,0x73,0xc3,0x4e,0x21,0x5e,0x13,0xbc,0xa3,0x5a,0x5a,0xf7,0xea,0x35, + 0x6d,0x66,0x34,0x93,0x60,0xc,0xeb,0xf,0x23,0x44,0x8b,0x53,0x86,0x71,0x2d,0xc4, + 0xa8,0xf,0xb7,0xec,0xdc,0xd9,0x4b,0xf0,0x16,0xef,0xca,0xef,0x67,0xb5,0xa4,0xd4, + 0x9c,0xd9,0x68,0xfc,0x65,0xd4,0xd,0x8,0x19,0x18,0x5b,0x20,0x8a,0x88,0xe4,0xb2, + 0x18,0x9d,0x9f,0x74,0xf6,0xeb,0xe4,0xd,0x5b,0xb0,0x7c,0xc2,0xe5,0x21,0x17,0x82, + 0xfa,0xfe,0x0,0x60,0xd3,0x8c,0x69,0x6d,0xa4,0x44,0x8d,0x2f,0x4d,0xf1,0xe2,0xe4, + 0xf,0x2,0x59,0x6,0xed,0x3f,0x92,0x49,0x6f,0xf,0x8b,0x55,0x31,0xa2,0x58,0xab, + 0x22,0x58,0xd,0xf5,0xe4,0xf5,0xe2,0x89,0x3a,0xef,0x39,0x7,0xe2,0x9b,0xeb,0x71, + 0x9d,0x46,0x78,0xc,0x5,0x8a,0xd4,0x74,0x9a,0x61,0xc9,0xcb,0x83,0x22,0x77,0xa5, + 0x7a,0x4,0x1c,0x5f,0x79,0xfe,0x69,0x34,0x6f,0x22,0x3b,0x52,0xbd,0x28,0x43,0xda, + 0xed,0xbb,0xe6,0xf2,0x47,0xbc,0x67,0x61,0x9d,0xb0,0x2d,0x21,0xd3,0x24,0xc7,0xcd, + 0xa8,0x63,0xad,0x22,0x62,0x17,0x56,0x51,0xb8,0x12,0x23,0x76,0xb9,0x67,0x51,0xa7, + 0x23,0xb8,0x1a,0xe9,0xf4,0x1,0x4b,0x92,0xb1,0xf7,0x33,0x5,0x9c,0x7a,0x53,0x45, + 0xdd,0x1,0xe6,0xc0,0x97,0x3e,0x12,0x50,0xcf,0x36,0x46,0x89,0x9d,0x17,0xb0,0x40, + 0xcf,0xca,0xaa,0x44,0x4b,0xf5,0xd6,0xfc,0x6e,0x8a,0x82,0xb,0x5,0xd5,0x50,0x63, + 0xd6,0x37,0x24,0xed,0xf4,0xb5,0x3e,0x44,0x6b,0x84,0xcd,0x9,0x9b,0xfd,0xc9,0xeb, + 0x48,0x74,0x30,0x93,0xe9,0x87,0x91,0x58,0x12,0x93,0xe2,0x96,0x69,0xb2,0xf9,0xbf, + 0x6a,0x9d,0xad,0xde,0x54,0xeb,0x24,0x3f,0xef,0xf1,0x49,0xb,0xf0,0x92,0xf6,0x39, + 0x7,0x28,0x4d,0x70,0x2f,0x5e,0x49,0xc0,0xf1,0x2c,0x57,0x5b,0xdf,0xd1,0x1b,0x4a, + 0xee,0xc8,0x29,0xc2,0x34,0xcc,0x3,0xa3,0xbf,0x4c,0xae,0x30,0x5e,0xa6,0xe8,0xe4, + 0x4e,0x36,0x55,0xfc,0x94,0x9e,0xbd,0x86,0xcb,0x15,0x61,0x2b,0x66,0x7c,0xf4,0x56, + 0xc4,0x9d,0x19,0x78,0x6b,0x1c,0x1c,0xaa,0xe7,0xcb,0xda,0x46,0xf1,0x43,0x2b,0x40, + 0xf9,0x1,0x3d,0x8e,0x1f,0x7a,0x95,0x6a,0x8f,0xf6,0x95,0x76,0xf3,0xa,0xcc,0x38, + 0xa8,0x65,0xb1,0x14,0x82,0xcd,0x3e,0xe9,0x19,0x19,0xb0,0xb,0xdb,0x5b,0xca,0xd5, + 0x5c,0x87,0xe4,0x7c,0x2,0x7a,0x66,0x12,0xf0,0xfc,0x88,0xe4,0x7,0xd4,0x1e,0x2f, + 0x3a,0x4f,0xc2,0x3c,0x9c,0x1,0xa6,0xb6,0x99,0x57,0xc1,0x76,0x32,0xd,0xcb,0xf, + 0x94,0xb0,0xb,0x17,0x2b,0x71,0xa8,0x1d,0x6e,0x31,0x81,0xf5,0x85,0x1f,0xa4,0x3f, + 0x6e,0x68,0xfb,0xc,0x69,0xa2,0xc2,0x83,0x79,0x4,0xf9,0xab,0x90,0x45,0xba,0xa5, + 0xf6,0x45,0xbc,0x22,0xb7,0x65,0xbe,0x26,0x16,0xc0,0x9b,0x1b,0xdf,0x41,0x5a,0x4f, + 0x29,0x56,0xda,0x92,0x78,0x9d,0x95,0x71,0x21,0x8f,0x9d,0xb2,0x55,0xd7,0xd7,0x4c, + 0x1e,0x14,0xed,0xd5,0x79,0x2d,0x7b,0xf,0xed,0x18,0x2a,0xcd,0xd8,0x4,0x1d,0x2, + 0xda,0xf7,0x14,0x53,0x15,0xaa,0x45,0xb6,0xb9,0xe2,0xe8,0xf,0x3a,0xc0,0x5b,0x58, + 0xd4,0xc9,0x2e,0xcd,0xf6,0xaa,0x5c,0xe4,0x42,0x6,0xb2,0x9a,0xa,0x50,0x9c,0xe4, + 0xc7,0xb0,0xb8,0x5d,0x5b,0x7d,0x14,0x95,0x60,0xfc,0xa4,0x9a,0x3d,0x80,0x73,0x91, + 0x4a,0xa1,0xde,0x41,0xcb,0x3b,0x26,0x8d,0xc0,0xd8,0x28,0xca,0xa8,0x44,0x30,0x71, + 0xf5,0x68,0xce,0xd0,0xe5,0x62,0x66,0xc5,0xde,0x8b,0xdf,0x1c,0xc,0x53,0x2d,0x56, + 0x75,0xc,0x97,0xc0,0xc6,0x3d,0x4f,0x87,0x16,0xf6,0xd1,0x3f,0x3c,0x2,0xb0,0x32, + 0x6a,0xfe,0x82,0xcf,0x61,0x69,0x95,0x40,0xf4,0x76,0xdb,0x1,0x49,0x9,0x57,0xbe, + 0x94,0x6e,0x80,0x5b,0xab,0xcf,0x62,0x41,0x46,0x34,0x80,0x82,0xb6,0xb0,0xb4,0xa0, + 0xaf,0xb7,0x71,0x90,0x21,0x86,0x50,0x16,0xfc,0x2c,0x96,0x47,0x35,0x6d,0x85,0x49, + 0xdb,0x6,0xa4,0x7,0x55,0x86,0x48,0x9c,0xbb,0x49,0x1f,0x72,0xf9,0x54,0x13,0x2a, + 0xc,0x4,0xba,0xac,0x8b,0x8b,0x42,0x8,0xb7,0xd8,0xce,0x6d,0x46,0x55,0xb6,0xa1, + 0xda,0xdb,0xa8,0x31,0x62,0x70,0x4d,0x9d,0xb9,0xeb,0x10,0x34,0x40,0xa3,0x5e,0xcb, + 0x27,0x98,0xf7,0xb2,0x24,0x3a,0xbb,0x5c,0x92,0x8a,0xc9,0x58,0x5f,0x0,0xf9,0x3b, + 0xdb,0x22,0x6c,0xbe,0x93,0x39,0x5c,0xcc,0x25,0xec,0x1,0xe5,0x90,0xde,0x31,0x37, + 0xf7,0x2a,0xea,0x9b,0xe3,0x26,0xf7,0xf6,0xb0,0x41,0x4f,0x11,0xc1,0x4a,0xcb,0x9d, + 0xeb,0x38,0xdb,0xfe,0xf0,0x39,0x4c,0x16,0x26,0x4d,0x7b,0x36,0xac,0x2d,0x6d,0x24, + 0xd6,0xd7,0x3f,0xba,0xfd,0xb7,0xb1,0x2f,0xf8,0x81,0xbf,0xba,0x4b,0x8b,0xd8,0x37, + 0x43,0xb4,0x37,0x34,0x6d,0x83,0xc9,0x93,0x50,0x46,0x49,0x7c,0x73,0xb7,0x20,0x4a, + 0x8f,0x60,0x84,0xe,0x18,0xb6,0x3d,0x11,0x38,0xfc,0x4c,0x83,0x8,0xa4,0x3a,0x4b, + 0xd8,0xf0,0x7f,0x47,0xf3,0xc8,0xda,0x45,0x8e,0x25,0x41,0x81,0x5c,0x62,0x4b,0x6b, + 0xc2,0xd0,0x79,0xda,0x7,0x36,0x6b,0x3f,0xb2,0x37,0x42,0xba,0x5b,0x7c,0x85,0x35, + 0x6e,0x84,0x7c,0x62,0x4e,0xd6,0x27,0xdc,0x7b,0x69,0x5f,0xd7,0x4b,0xaa,0xc3,0x8d, + 0xfa,0xbc,0xe7,0x2,0xf3,0xd2,0xc0,0x26,0xb,0x3,0x61,0x66,0x80,0xe6,0x1b,0xee, + 0x6c,0x97,0xd0,0xba,0x6f,0xf8,0x17,0x6a,0xe1,0xf5,0x43,0x2d,0xa1,0x7,0x3a,0x1c, + 0x43,0x22,0x1f,0x37,0xf4,0x5f,0xdd,0x7f,0x63,0x3f,0x66,0xe3,0x26,0x81,0x52,0x92, + 0x99,0x23,0xcc,0x88,0x9b,0xe4,0xf2,0x7d,0xda,0xb5,0x2a,0xfb,0xbc,0x64,0x19,0x80, + 0x6,0xb7,0xb7,0xfb,0x17,0x15,0xfa,0x7a,0x54,0xe0,0xdd,0x7b,0x63,0xaf,0x8d,0x7c, + 0x53,0x5b,0x5,0xee,0x40,0xf7,0xec,0x9a,0xae,0x17,0x17,0xea,0xfb,0x30,0x6b,0x2, + 0x67,0xa3,0x7d,0x7e,0x38,0x79,0x79,0x8d,0x5a,0xd6,0x9,0x3d,0x7,0x96,0xb9,0xd9, + 0x71,0x3e,0x48,0x31,0xb6,0x35,0x4c,0x65,0xcc,0x63,0xcf,0xc8,0x93,0xbb,0x4a,0xfa, + 0xde,0xc8,0xf8,0x17,0xc1,0xf1,0x24,0x9b,0x49,0x2d,0x59,0x50,0x44,0x92,0x2a,0x35, + 0xd1,0x72,0x67,0x88,0x28,0xb3,0x6d,0x74,0x17,0xbc,0xbc,0x2a,0xf7,0x7,0xa4,0x56, + 0x4f,0x1d,0x6e,0x90,0x10,0x12,0xac,0x59,0xbf,0x6,0xa9,0x83,0x98,0x53,0xb8,0xe9, + 0x45,0x9f,0x72,0x6d,0x53,0x5f,0xe1,0xe9,0x9c,0x1e,0x93,0x94,0x26,0x38,0xeb,0xf4, + 0x56,0xd9,0x86,0xe5,0xeb,0x33,0x3f,0xab,0xb8,0x68,0x2f,0xd0,0xbb,0xe8,0xbb,0x80, + 0x88,0xad,0x6e,0x5c,0xe,0x50,0xc5,0x2a,0xee,0x5a,0xbe,0x15,0x12,0xaa,0xa,0xe7, + 0x4,0x10,0xcd,0xf0,0xc2,0xd,0x1c,0x7b,0x75,0x4c,0x4d,0xb0,0xb4,0x88,0x32,0xbc, + 0x36,0xa0,0x19,0xc3,0x70,0x5f,0xed,0x5f,0x39,0x2d,0xf3,0x4b,0xd7,0x7e,0x34,0x5c, + 0xe,0x2,0x4d,0xd1,0x10,0x69,0xcc,0x5,0x35,0x99,0x36,0xe9,0xa1,0xe7,0xa7,0xd8, + 0x8,0x40,0x1c,0x78,0x9f,0xb,0x58,0xd8,0x38,0xcb,0xa4,0x8f,0x4a,0xd8,0x6b,0xd8, + 0xda,0xb8,0xaa,0x6a,0xa2,0xf6,0xef,0x57,0x11,0xa5,0x42,0xb2,0x8d,0x69,0x8b,0x95, + 0xa9,0x28,0x8d,0xc9,0xb2,0x65,0x22,0x6a,0x32,0xc6,0x79,0xfb,0x1f,0xe5,0xd4,0x7a, + 0x1e,0xfe,0xe4,0xc0,0x76,0x54,0x19,0x87,0xf9,0xda,0x3a,0x87,0x44,0x46,0x9c,0x6d, + 0xed,0x2b,0x37,0xa0,0x90,0xd9,0xb,0x42,0x20,0x84,0x3f,0x40,0x6a,0x93,0xba,0x89, + 0x93,0x1f,0xc9,0xa,0x74,0x62,0x11,0xed,0xbc,0xca,0xf5,0x1,0x90,0x92,0xee,0x7e, + 0x3d,0xa5,0x1f,0xce,0x7f,0x2a,0x11,0xa0,0x2f,0xcf,0xe0,0x19,0x64,0x1b,0xa2,0xf7, + 0x3a,0xec,0x81,0xae,0xce,0x92,0x1d,0x8c,0xdc,0x13,0xd,0x6e,0x25,0xfb,0xec,0x63, + 0xa2,0xd,0xb1,0xa1,0xb6,0xc2,0x42,0x65,0x93,0xa2,0x7f,0x77,0xbd,0xa1,0x6f,0x78, + 0xe,0x70,0xa6,0xdd,0x82,0xc3,0x6a,0x5f,0x56,0x77,0xcd,0x7c,0xf3,0x3b,0xdf,0x96, + 0xc7,0x91,0x38,0x7e,0xd3,0xfa,0x64,0xe6,0x1d,0xe3,0x5e,0x5b,0x85,0x4d,0xd3,0x94, + 0x3d,0x7a,0xf1,0xbf,0xbe,0x5c,0x9f,0x15,0x53,0xec,0x11,0x47,0x28,0xf0,0x5d,0x6f, + 0x2,0x96,0xee,0x56,0x11,0xd2,0xbc,0xad,0xb6,0x9b,0x88,0xbb,0xe8,0x5c,0xcf,0xa6, + 0x57,0xc1,0xe5,0x95,0x9d,0x85,0xaa,0xf1,0xf2,0xbc,0xb8,0x9a,0x2d,0x17,0xb,0xaf, + 0x2d,0x79,0x85,0xbd,0x4c,0x42,0x6b,0x82,0xdd,0xf4,0x3e,0x47,0xd0,0x8e,0xed,0xa7, + 0x50,0xd3,0x3d,0x6e,0xd9,0xe8,0xdf,0xcc,0x25,0x98,0xe6,0xd1,0xaf,0xf1,0x1,0x5c, + 0x6b,0x6,0x1a,0x37,0x49,0x86,0xb9,0xa6,0xfa,0xf8,0x6d,0xcb,0x87,0x5b,0x74,0x57, + 0xaf,0xb1,0xc5,0x9,0x1a,0xa5,0xd5,0xbe,0xbe,0xbc,0x11,0x6e,0x2f,0x91,0x4b,0x9a, + 0x98,0x65,0xd2,0x61,0x6b,0x8c,0x8,0x66,0x5,0x76,0xb2,0xc,0x51,0xa6,0x64,0x80, + 0x58,0xa9,0x89,0xf2,0xcf,0xde,0x31,0x8e,0x9c,0xc1,0x7c,0x4b,0x54,0xc7,0x65,0x6c, + 0x2e,0xb7,0xcd,0x19,0x45,0x55,0x80,0xc9,0xcb,0xb2,0xd6,0x9d,0x59,0xba,0x1e,0x31, + 0x64,0xa8,0xa3,0x34,0x87,0xd5,0x42,0xa3,0x17,0xbf,0xee,0x6b,0x7,0x55,0x57,0xb4, + 0xd,0x25,0xce,0xd1,0x7b,0x4f,0x1c,0xc6,0x81,0xf2,0x64,0xda,0x2d,0x3,0xc,0x91, + 0xab,0xb0,0x46,0x33,0x6,0x8,0x57,0x1d,0x47,0x46,0x9,0x4f,0x1b,0x60,0x4,0xa8, + 0x86,0xd2,0xf9,0x81,0xa1,0x16,0xc7,0x23,0x9,0xac,0xfd,0xb5,0xaf,0x8a,0xc7,0x5b, + 0x3b,0x8d,0xe,0x41,0x95,0xe4,0xdd,0xdd,0x2c,0xe6,0x2d,0xc6,0x48,0xb0,0xee,0x4e, + 0x4,0xe9,0x4f,0xa5,0x0,0x17,0x49,0x89,0xc3,0xc6,0x3f,0xf2,0x51,0x7,0xcd,0xc, + 0x94,0xdc,0xcc,0xaa,0x41,0xab,0x88,0xec,0x92,0x35,0xb4,0xda,0x65,0xa3,0xa8,0x69, + 0x8d,0xf7,0x8f,0xe,0x10,0xd8,0x97,0x53,0x1f,0xd6,0x47,0x71,0x5e,0x15,0xfc,0x72, + 0x71,0x4a,0x1d,0x33,0xf5,0xa5,0x20,0x8,0x5a,0xd4,0x63,0xc0,0xf8,0xc,0xa9,0x6, + 0x5,0x39,0x14,0x94,0x12,0xab,0x67,0x32,0x3,0xae,0x23,0x61,0x44,0x9f,0xd3,0x35, + 0xe9,0x71,0x68,0x5f,0x17,0x89,0xe7,0xf1,0xdd,0x4b,0x32,0x56,0xd6,0xdb,0x5d,0xdb, + 0x16,0x71,0xef,0xa7,0x9d,0x58,0x59,0xa0,0x86,0xfb,0x81,0x4a,0x9c,0x55,0x0,0x6, + 0x46,0xe7,0xe5,0x5e,0xf0,0xcd,0xcf,0xcf,0x19,0x81,0x26,0xef,0x5d,0x83,0x4c,0xf2, + 0x75,0xbb,0x9b,0x13,0x14,0x74,0xb3,0x1b,0x71,0xb4,0x65,0x8d,0x89,0xe4,0x13,0xd0, + 0xcd,0xf8,0xae,0xbe,0xc6,0x7e,0x8e,0x5f,0x0,0x35,0xcf,0xdc,0x38,0x9b,0xd0,0x2d, + 0x57,0xeb,0x40,0xeb,0x60,0x73,0x7,0xd1,0x28,0xeb,0xde,0xb2,0xd1,0xf2,0x83,0x9f, + 0xeb,0xb1,0xdd,0x33,0x30,0xec,0x92,0xaf,0x22,0xe1,0x8c,0xd9,0x7d,0xdc,0x8,0xd5, + 0xc8,0xc7,0xc1,0xa9,0xbb,0x48,0x7b,0xe3,0x34,0xda,0x16,0x85,0xcd,0x19,0xa4,0x39, + 0xca,0x83,0x6c,0x7a,0x70,0x7f,0x2a,0x12,0x61,0x37,0xeb,0xdf,0x14,0x73,0x35,0x5d, + 0x3c,0xf6,0x7,0xf7,0xbe,0x2,0x5b,0x72,0xdc,0xf1,0xf8,0x2a,0xb,0x1d,0x64,0xd6, + 0xa0,0xd0,0xd0,0x11,0x50,0xfb,0x23,0x32,0xb2,0x8f,0x12,0x46,0x3,0x47,0xa3,0xbe, + 0xbd,0x2a,0x36,0x7c,0x2d,0x12,0x6e,0x89,0x4,0xe6,0xb4,0xf,0x5,0x98,0x65,0xa5, + 0x69,0x37,0x37,0x3a,0xb2,0xd9,0x6c,0x65,0xe8,0xfd,0xab,0xec,0xc4,0xcf,0x2b,0x82, + 0xf9,0xe1,0x7e,0xa6,0xf3,0x6c,0xb0,0xf7,0x54,0xe4,0x7,0x59,0x7d,0xec,0x7e,0x66, + 0x24,0x35,0xa0,0x56,0x10,0x8c,0x3b,0xf8,0xa,0x66,0x65,0xce,0x36,0x11,0xd0,0xb0, + 0xf2,0xce,0xd6,0xe6,0x3c,0x87,0xde,0x10,0x6c,0x65,0x69,0x69,0x52,0x67,0xd0,0xf5, + 0x9d,0xf0,0xcb,0xad,0x7e,0x7,0x26,0x8,0x6e,0x8c,0x57,0xa4,0x9d,0xa7,0xd4,0x10, + 0x77,0x2c,0xf6,0x33,0xb3,0x55,0x43,0xa0,0xba,0x2c,0x89,0x8d,0x93,0x5a,0x83,0x31, + 0x4c,0xcf,0x5e,0x4a,0xd6,0x85,0x52,0x45,0x91,0x29,0x6a,0xae,0xd1,0x3f,0xbe,0x49, + 0xea,0xb5,0xfb,0x9f,0xb,0x3f,0xbf,0x45,0x6b,0x49,0xd2,0x7e,0x24,0xd6,0x30,0x70, + 0xa6,0x8e,0x3a,0x7d,0x93,0x8c,0x43,0xa4,0xb6,0xad,0x53,0x88,0x6c,0x12,0x51,0x58, + 0x47,0x4d,0x77,0xd1,0xc,0xb6,0x18,0xf6,0x7f,0xea,0x75,0xa3,0x41,0xa5,0x93,0xe7, + 0xb4,0xcd,0xe5,0x48,0xda,0x29,0xed,0x91,0x56,0xc0,0x99,0x42,0xd3,0x6a,0x9a,0x9a, + 0xb7,0x91,0x6d,0x43,0x48,0x85,0x3a,0xc8,0xef,0x2f,0xeb,0xb1,0xd5,0x80,0x19,0xa, + 0x4e,0x7e,0xd1,0x29,0x27,0x3f,0x3a,0x7d,0x1,0x53,0xc0,0x54,0xbd,0xda,0xee,0xf4, + 0x6d,0xdb,0x38,0x35,0xe0,0xf1,0x7d,0x51,0x22,0x6a,0x3,0x77,0x6a,0x1c,0x1,0x38, + 0x9b,0xd2,0x62,0xc2,0x13,0x1c,0xc0,0x93,0x70,0x1,0xe7,0xad,0xdb,0x56,0xa3,0xc8, + 0x33,0x5b,0x7e,0x14,0xcd,0xfb,0xe4,0xef,0xe5,0xe7,0xe6,0x50,0x84,0xe7,0x89,0x9f, + 0xba,0x6b,0xe1,0x4d,0x87,0xa2,0xe0,0x77,0xa3,0x48,0x26,0x0,0x9f,0x49,0x48,0x52, + 0x24,0xc6,0x66,0xf1,0xc3,0xcb,0x61,0xa9,0xb3,0x48,0x7a,0xb7,0xaf,0x4,0x57,0x6b, + 0x6f,0x3a,0x38,0x76,0x5c,0x1a,0xee,0x80,0x62,0x94,0x80,0x81,0xdd,0xc8,0xd3,0x81, + 0x10,0xba,0x74,0x53,0x86,0xd5,0xfc,0x3a,0x9e,0xf6,0x72,0x4e,0xfa,0xc9,0x39,0xe9, + 0x83,0xf1,0x61,0xe0,0x8b,0xcf,0x61,0xed,0x64,0xe1,0xef,0xc1,0x2a,0xc3,0x43,0xb9, + 0xfd,0x37,0xd,0x84,0x8d,0xb,0x3f,0x2c,0x2,0xb1,0xf9,0x7d,0x7b,0xb3,0x67,0x7f, + 0xa5,0x48,0x60,0x31,0x18,0xc1,0x9e,0xfb,0x23,0x8e,0xbd,0xcc,0xd2,0x81,0x87,0xd0, + 0xb8,0x94,0x56,0x46,0x1f,0x95,0x72,0xa1,0xc6,0xec,0x1f,0xc1,0xa0,0x6,0x41,0x46, + 0x4f,0xa1,0x77,0xe6,0xe2,0x16,0xe3,0x6,0x25,0xa1,0xd3,0xf7,0x23,0xda,0x48,0xdc, + 0x6f,0x9e,0xa2,0xf,0xb3,0x16,0xb0,0xf9,0x82,0x4f,0xbc,0x23,0x55,0xfd,0x69,0x24, + 0x20,0x60,0xc,0x3,0xf5,0x6f,0x89,0x1b,0x11,0xdc,0x92,0xb4,0xb7,0xdb,0x11,0xa6, + 0xf9,0xb3,0xb5,0xae,0x49,0x66,0xa8,0xcb,0xb5,0xe4,0xee,0x8b,0xe3,0xd7,0xaf,0x83, + 0x38,0x3b,0x86,0xae,0xaa,0x8f,0xc9,0x3c,0x6c,0xdc,0x70,0x24,0xb8,0x81,0xcb,0xb2, + 0xb4,0x1,0xe0,0xfe,0x68,0x8a,0x4a,0x9d,0xee,0xb9,0xa8,0xd2,0x91,0xd8,0xd5,0x4a, + 0x14,0xdc,0xf8,0x3f,0x6c,0x42,0x7b,0xd9,0x1f,0x6b,0x7d,0xd7,0xec,0xc8,0xb,0x21, + 0xca,0xeb,0x20,0xb2,0xf5,0xea,0xcf,0xe5,0xa4,0x79,0x38,0xb5,0x52,0xf,0x7f,0xe5, + 0x6b,0xf7,0x25,0xd7,0x3b,0x20,0x31,0xd9,0x8b,0xaf,0x32,0xf7,0xf7,0x3d,0x1a,0x42, + 0xa8,0xb9,0xf4,0x9f,0xa4,0x45,0x5,0xc8,0xbe,0x3d,0xfe,0x90,0xcb,0x7e,0x76,0x37, + 0xf6,0x1c,0x8f,0xb1,0x3c,0xc0,0x8b,0x48,0x70,0xbd,0xbf,0xe8,0x7a,0xd9,0x2b,0x24, + 0x94,0xa0,0x43,0xb8,0xe5,0x48,0x2,0xa4,0x5,0x1,0xb4,0x51,0xfe,0x2b,0x8,0xf5, + 0x47,0x97,0xa7,0x4,0x59,0xb3,0xcb,0x49,0xf0,0x8b,0x32,0x6c,0x66,0xdd,0x10,0x7a, + 0x7e,0xd2,0xb2,0x64,0x9a,0xb4,0x88,0x9f,0x35,0x3d,0x70,0xb4,0xe7,0x79,0xaa,0x30, + 0x90,0xd2,0xb3,0xe9,0x6,0xfe,0xb3,0xf6,0x8a,0x65,0xe2,0x70,0x43,0xf2,0x6a,0xc1, + 0xc5,0x1e,0xa5,0x60,0x52,0x2e,0x80,0x8,0xea,0x70,0xbc,0xd3,0x69,0xe6,0x83,0xfa, + 0x39,0xb6,0x64,0x3f,0xb5,0x18,0x37,0x40,0x7e,0x1a,0x31,0x41,0x8d,0x9b,0x4,0x53, + 0x39,0x29,0x34,0x8c,0xd7,0x34,0x14,0xc2,0x24,0xd0,0x96,0x8e,0xb7,0x99,0x89,0x71, + 0x50,0xed,0xb0,0x6,0x86,0xe7,0xc6,0x84,0x82,0xf7,0xc5,0x10,0x13,0x49,0xe2,0x4d, + 0x73,0x17,0x59,0x4b,0xca,0x6d,0xe,0xef,0xbd,0x25,0x7e,0xf4,0x3e,0x87,0x66,0x8f, + 0xf4,0x18,0x15,0x7b,0x7f,0x5b,0x0,0x2,0xd2,0xc6,0x12,0xe6,0x8f,0x75,0xb3,0x3, + 0xc,0xd,0x4e,0xd7,0xf9,0xdc,0x47,0xb7,0x81,0x45,0xac,0xbf,0xcc,0x93,0xce,0x41, + 0xab,0x64,0xbd,0x2b,0x3f,0x3d,0xad,0x13,0x83,0x3f,0x79,0x14,0xb4,0x2d,0x17,0xc1, + 0x3a,0xe5,0x19,0xb3,0x42,0x60,0xea,0x43,0xa5,0x17,0x82,0xf1,0xaa,0xd1,0x33,0xd5, + 0x36,0x70,0x2,0x75,0x2e,0x2f,0x8,0xb1,0x6e,0x81,0x45,0xa3,0xae,0xdc,0x65,0x68, + 0xc2,0x7e,0x9b,0x84,0x5e,0x86,0xc7,0x4,0x9e,0x4a,0x75,0x49,0x1c,0xa8,0x20,0xd1, + 0x99,0xa1,0xc7,0xc7,0xd0,0xcf,0xf8,0xbe,0xd1,0x3f,0x62,0x0,0x1c,0x47,0x69,0x5e, + 0xc5,0x5,0x62,0x24,0x8c,0x2a,0xa7,0xaa,0xf3,0x9c,0xf3,0x90,0xc5,0x93,0x62,0x5f, + 0xb4,0x2a,0xa6,0x5,0x7a,0x9f,0xc4,0xcb,0xde,0xa6,0xcb,0x7a,0xee,0x35,0x58,0x34, + 0xba,0xba,0xd8,0xc6,0xe4,0x0,0x71,0x59,0x9d,0xe4,0xe9,0x63,0xf8,0x4c,0xc2,0xad, + 0xf6,0x69,0x33,0xf0,0x88,0x77,0xbc,0x68,0x1e,0x88,0x62,0x8c,0x3e,0xbb,0xc1,0xf8, + 0x76,0x1a,0xbf,0xdb,0x1a,0xb0,0x35,0xb7,0x15,0x1f,0x1b,0xe,0xea,0x5d,0x3c,0x61, + 0xc6,0x6f,0x52,0x50,0xe6,0xf,0x38,0x5,0x18,0x9a,0x12,0x56,0x56,0xd3,0x4f,0x4d, + 0xed,0x8e,0x29,0x87,0x3f,0xdd,0x40,0xd3,0x7c,0x5b,0xe2,0x67,0xb9,0x9e,0x49,0x0, + 0xe,0x9b,0xcf,0xf4,0x2b,0x8,0x79,0x43,0x23,0x8b,0x99,0xf8,0xde,0xe8,0xc5,0x4c, + 0xf6,0xee,0xd4,0xb5,0x4c,0x94,0x89,0xc8,0xef,0xeb,0xb0,0x29,0x8a,0xf9,0xa9,0x98, + 0x15,0x79,0xd,0x40,0x2,0x87,0x3,0xa4,0x92,0x9c,0x9d,0xf1,0x5,0x64,0x3e,0xfb, + 0xd2,0x92,0xb1,0x20,0x27,0xbb,0x68,0x97,0xa7,0x98,0xc0,0x33,0x92,0xe9,0x4b,0x28, + 0x64,0x59,0x68,0xe5,0x60,0xeb,0x8a,0xf2,0x88,0xa7,0xe4,0x8e,0xc,0xa3,0xa,0x5f, + 0xb5,0x3c,0xfe,0xdd,0xf7,0xe6,0x75,0x1f,0x80,0xb5,0xd1,0x13,0xa0,0x1e,0xba,0x84, + 0x77,0xa3,0x6a,0xd7,0x8f,0xf4,0x4a,0x18,0x9c,0x30,0x26,0x29,0x53,0xb0,0x8,0x9, + 0xec,0x86,0x66,0x64,0x6d,0xdb,0x3,0xed,0x12,0xd5,0x81,0x32,0xf3,0x3c,0xb6,0xea, + 0xdf,0xa0,0xc2,0x6f,0x95,0x8c,0x8,0xb1,0x3c,0x2e,0x5a,0x8f,0x5e,0xe1,0x99,0xca, + 0x68,0x7f,0x2f,0xd6,0xdb,0x33,0xc4,0xed,0x9,0x46,0x9f,0x7c,0x83,0x56,0x67,0x63, + 0x76,0xa9,0x53,0xc,0x36,0x5b,0x3d,0x73,0x9,0x18,0x3,0x68,0xf9,0x1c,0x33,0xe2, + 0x9c,0xe2,0xb9,0x78,0x95,0x7e,0xe5,0x1e,0x45,0x85,0x9a,0x48,0x5b,0x2,0xab,0xd1, + 0xab,0x7e,0x5d,0x61,0xd9,0x1a,0xd4,0xe3,0x32,0x58,0xcb,0xac,0x74,0xfe,0x8f,0x90, + 0xe1,0x49,0x88,0xf6,0x47,0x6e,0x15,0x8c,0x73,0xaf,0xd4,0xce,0x31,0x1,0xa0,0x5c, + 0x7f,0x7d,0xbe,0xd9,0x98,0x93,0x3d,0x4a,0xeb,0x9,0xf6,0xe0,0x87,0x86,0xf0,0xe9, + 0x4f,0x7a,0xe0,0x17,0x68,0xf6,0x23,0xdc,0xa6,0xf8,0xab,0x58,0x79,0xcc,0xb4,0x78, + 0xc9,0x73,0xd1,0x62,0x87,0xf,0xad,0xf2,0x97,0x24,0x53,0x20,0xab,0x45,0xa,0x7a, + 0xbf,0xea,0x91,0xa7,0x61,0xb5,0x84,0x88,0x2e,0xb0,0xe0,0x27,0x7d,0x95,0x1f,0x47, + 0x89,0xf1,0x2a,0x90,0x1,0x57,0x83,0x99,0x7b,0x57,0x39,0xa6,0x9c,0x43,0x22,0xdb, + 0xad,0x33,0x83,0x10,0xe8,0x88,0x98,0x96,0x39,0xf8,0x3d,0x36,0x8e,0x5d,0x7d,0x97, + 0x4f,0x27,0x28,0xcf,0x7e,0x2c,0xe8,0xfa,0x83,0x22,0xa1,0x9f,0x65,0x43,0xfa,0x93, + 0x77,0xfd,0x23,0xdf,0x86,0x3b,0xf6,0xbf,0x34,0x34,0xf5,0xc2,0x91,0xf3,0x5b,0x60, + 0x9a,0x3,0x31,0x1a,0x2f,0x1a,0x94,0x32,0x3d,0x36,0x51,0x22,0xf9,0x4c,0x35,0x71, + 0xca,0x58,0xd0,0x51,0x93,0xc7,0x91,0xc7,0xfc,0x7,0xb,0xe,0x7a,0xe5,0x6f,0x16, + 0x68,0xa0,0x30,0x18,0x3a,0xc4,0x4a,0xf6,0x7a,0x1c,0x1a,0x74,0xe7,0xce,0x65,0xb2, + 0x28,0x37,0x84,0x3b,0x7e,0x95,0x83,0xfa,0x9c,0x8e,0xa,0x18,0xf3,0x79,0xad,0x5c, + 0x99,0x5d,0x74,0xd3,0x22,0x3f,0xcb,0x1c,0x5b,0x65,0x11,0x43,0x34,0xf5,0x76,0x5c, + 0xac,0xfa,0x18,0x2c,0x90,0x9b,0x27,0xac,0xa9,0xb0,0x44,0x1d,0x2a,0xf1,0xf8,0xc3, + 0x4f,0x6e,0x98,0xf0,0x2d,0xe3,0x8d,0x8,0x49,0x9e,0x4b,0x7d,0x94,0x41,0x5a,0xc1, + 0x3c,0x72,0xed,0x4c,0xe,0x94,0xf9,0x37,0x46,0x3e,0x54,0x70,0xb0,0x4d,0xb4,0x7f, + 0x3b,0xcc,0x71,0xe7,0xb0,0xfe,0xef,0xf9,0x1d,0xbb,0x77,0x31,0xfc,0xd1,0xf2,0xb9, + 0xc3,0x60,0x6,0x51,0xf5,0x7f,0x88,0xbb,0x3e,0x5c,0xab,0xee,0x2a,0x60,0x6e,0xe4, + 0xac,0x5f,0xcd,0x5d,0xdd,0x3d,0x57,0x7a,0x78,0x4f,0xac,0x76,0xa0,0x1f,0x30,0x65, + 0x0,0xb5,0xb6,0x75,0x36,0xbf,0x31,0x74,0x1c,0xdc,0x63,0xc5,0xbd,0x51,0xab,0x6a, + 0xb1,0xf8,0x48,0xf,0xb5,0x9f,0x8a,0x2f,0x6e,0xb6,0xa5,0x10,0x55,0x55,0x75,0x55, + 0xb,0xab,0xca,0xc0,0x6b,0x7b,0x35,0x8,0xd8,0x18,0x4d,0x96,0x6a,0xf8,0x80,0x9b, + 0x71,0xc8,0xaa,0x28,0xe8,0xb4,0xd6,0x57,0xea,0xfb,0xe6,0x41,0x51,0xdb,0x16,0xdb, + 0x88,0x61,0x9d,0x73,0xdc,0x52,0x7b,0x35,0x6b,0xc9,0x4b,0xd5,0x42,0xcc,0xf0,0x34, + 0x15,0x1b,0xdb,0xfd,0xd0,0xb2,0xd5,0x3b,0xae,0xbc,0x7c,0x0,0x19,0x13,0x5b,0xa1, + 0x74,0x78,0x15,0xd0,0xcb,0x11,0x7,0x37,0x5a,0x52,0x8c,0x1c,0x9e,0x7d,0x50,0xb4, + 0x98,0x2c,0x32,0xe8,0xde,0x87,0x25,0x8d,0xc4,0x21,0xd,0xdd,0xb3,0xe8,0x7f,0x28, + 0x61,0x14,0x79,0xac,0xa4,0x80,0x63,0x7e,0x52,0xef,0x9b,0xf1,0xec,0xeb,0x26,0x86, + 0x98,0x58,0xee,0xf6,0xe0,0x93,0x5,0x25,0xb5,0x12,0x3,0x69,0x7a,0x2,0x12,0x5c, + 0x16,0x8b,0x9,0x3b,0x8b,0x6d,0xb9,0xdd,0xdc,0x55,0x4f,0xca,0xc1,0x75,0x51,0x5a, + 0x4e,0xbf,0xd0,0xae,0x54,0xd5,0xd3,0x89,0x68,0xd6,0xf2,0xe2,0xd8,0x84,0x3f,0x6e, + 0x8f,0x49,0xa9,0x1b,0x36,0x64,0x79,0x13,0x39,0x48,0xdd,0xfa,0xbe,0xae,0xd4,0x8c, + 0x6f,0xa6,0x3b,0xc3,0x7c,0xf,0x4d,0xe4,0x65,0xbf,0x48,0xbd,0xc4,0x87,0x2c,0x54, + 0x50,0x56,0xef,0x86,0xba,0xe8,0x9a,0xf3,0x31,0xf7,0x6f,0x6f,0xa7,0x44,0xfb,0x17, + 0x6a,0xb6,0xda,0x67,0xc5,0xa7,0xcb,0xaa,0x67,0x14,0x68,0xab,0x9c,0x95,0x1,0x6c, + 0xeb,0xf0,0xf3,0x26,0x59,0xe,0x99,0x8a,0x6,0x9,0x7a,0xad,0xcd,0x76,0xc4,0xb7, + 0x2e,0x1f,0x9e,0x73,0x46,0x6b,0x1f,0x2e,0xfe,0x7,0xd9,0x1b,0x1c,0xda,0x88,0x87, + 0x4b,0x7c,0xad,0x24,0x8a,0xc7,0xaf,0x90,0x50,0x2a,0xbe,0x1e,0x20,0x3,0x56,0xcd, + 0x23,0xf4,0x42,0xe8,0xdf,0xe0,0x17,0xdf,0x67,0x71,0x7a,0x84,0xcb,0x3,0xc,0x18, + 0xfe,0x3a,0x3c,0x89,0x2,0x6b,0x9a,0x52,0x15,0x59,0xf0,0x36,0xdb,0xc6,0x4,0xfe, + 0xbb,0xc5,0x68,0x1c,0x26,0xfe,0x7b,0x8e,0x70,0xf5,0x13,0x3d,0xf9,0x1f,0xd4,0xf8, + 0xd8,0x90,0x3,0xda,0xfc,0x1d,0xad,0x12,0xf5,0x9e,0xc7,0xd1,0x65,0xcc,0x51,0xa0, + 0x12,0xb9,0xbc,0x39,0xb8,0xb7,0xc7,0x2a,0xae,0xda,0xe6,0x28,0x79,0xbb,0xa0,0x53, + 0x4c,0xa3,0xad,0x49,0x40,0x5b,0xdb,0x36,0x79,0xa3,0x88,0xde,0xef,0xd9,0x0,0x3, + 0x13,0x3c,0xbb,0xcb,0xf4,0x83,0x75,0x23,0xdd,0x5c,0x4b,0x57,0x18,0xeb,0x2a,0xe4, + 0x10,0x58,0x2e,0x50,0xb3,0x89,0x7,0x2e,0xad,0x8f,0x8c,0x1d,0xe8,0xc,0x9f,0xfb, + 0x49,0x5b,0x47,0xbd,0xde,0xbd,0xe0,0xbc,0x99,0x2c,0x94,0x32,0x97,0x3e,0x17,0xa7, + 0x96,0xc4,0x78,0xca,0x4f,0xfe,0x78,0x7c,0xe,0x84,0x99,0xf6,0x91,0x3a,0xf2,0x5a, + 0x95,0xb9,0x18,0xf4,0x77,0xf8,0xb1,0x91,0xa4,0xc5,0xc3,0x3c,0x84,0x5a,0x64,0x1b, + 0x1f,0x5c,0x65,0xed,0xda,0xdd,0xe9,0xe8,0x63,0x84,0x5f,0x74,0xbe,0xd1,0xce,0xd3, + 0x8b,0xe6,0xc8,0x4,0x5f,0xfa,0x15,0x4,0x40,0x58,0xbf,0xc4,0xb2,0xa3,0xe0,0x51, + 0x0,0xc5,0xbf,0xda,0xa4,0xa9,0x43,0x87,0x2e,0xa2,0xfb,0x6c,0x74,0xca,0xc0,0x1, + 0x31,0x89,0x84,0x90,0x4,0x99,0x14,0x45,0xf1,0x53,0x89,0x24,0xf7,0xe9,0x75,0xf7, + 0xb0,0x35,0x53,0x55,0xdf,0x96,0x5c,0x8d,0x3a,0x58,0xfa,0x2e,0xa2,0xbb,0x2f,0x53, + 0xc4,0xb3,0x63,0x49,0xcc,0x77,0xe,0x3e,0xca,0x97,0x62,0xc2,0x82,0xd8,0x3b,0x33, + 0xe,0xe,0x8,0x6d,0xa4,0x64,0xfb,0x5e,0x3c,0x76,0xd,0x5e,0xb1,0x3c,0xb1,0xf5, + 0x70,0x15,0x3f,0x3d,0xc,0x4d,0xfb,0x56,0xe5,0x5e,0x99,0x68,0x37,0xd4,0x1b,0xc5, + 0xe2,0xa2,0xb2,0x7,0x7,0x2e,0xe5,0xc2,0xa4,0xf2,0x21,0xd5,0xae,0xd2,0xcc,0x1f, + 0x67,0x8b,0xdc,0x73,0xd9,0xd8,0xc9,0x3f,0x37,0x63,0xa7,0xee,0xb7,0x42,0x34,0x1a, + 0xe4,0xe6,0xa1,0x6b,0x16,0x87,0x2e,0x3a,0xf9,0x4f,0x90,0xa8,0xa1,0xdc,0xc8,0x9, + 0x68,0x25,0xfb,0x42,0xfd,0xc5,0x81,0xb4,0xa9,0xa8,0x23,0xe0,0x6a,0x57,0xfb,0xce, + 0xbe,0x1d,0x3a,0x54,0xa4,0xe7,0xe,0x9e,0x37,0x9e,0x47,0x58,0x7b,0x8f,0xe0,0xe4, + 0xb4,0xdc,0xa6,0x32,0x23,0xa8,0x67,0xcc,0xd0,0x8a,0x2d,0x3c,0x62,0xa8,0xb,0x21, + 0xc5,0xc5,0x75,0xe9,0xad,0x83,0x88,0x65,0x23,0x50,0xbd,0x1e,0x5f,0x9f,0x82,0x15, + 0x7c,0xa9,0xc6,0x1f,0x52,0x2e,0x6b,0x23,0x39,0x99,0xde,0x9b,0x42,0xea,0x3c,0x88, + 0xb0,0xb1,0x72,0x5e,0xb4,0x7b,0x43,0x57,0xcb,0x2,0x76,0x2b,0x21,0x78,0xbf,0x1d, + 0x22,0x7,0x3d,0x74,0xb4,0xa8,0x18,0xed,0x42,0xf6,0x9,0x5,0xe1,0x45,0x8d,0x12, + 0xf6,0x0,0xf0,0xac,0x7b,0x34,0x4,0xc6,0xb5,0xf9,0x72,0xd6,0x73,0xb1,0xf4,0x95, + 0xb8,0x32,0x8a,0x6e,0x5a,0xa2,0xdb,0x1d,0x19,0xe5,0xa1,0x7b,0x2b,0x2f,0x8d,0xa2, + 0xae,0x7e,0x4f,0xaa,0x33,0xd2,0xf0,0xe8,0x4d,0x63,0xc0,0xc0,0x95,0x35,0xd5,0x4e, + 0xe6,0xdf,0x3c,0x41,0x2,0x19,0xdd,0x1c,0xfe,0x7f,0x97,0xa9,0xae,0x25,0x4c,0xdd, + 0x24,0x1b,0x8,0xd6,0xee,0xf8,0xbf,0xbb,0xdc,0x0,0xfb,0x72,0x35,0x51,0x40,0x9b, + 0x32,0x7d,0xdd,0x34,0x16,0xbb,0x50,0x94,0xbb,0x67,0x3e,0xe9,0xd,0x8b,0xc7,0x31, + 0xa6,0x4f,0x87,0x15,0xc8,0x47,0x50,0x25,0xc7,0x4c,0x17,0x7c,0x9e,0x57,0x19,0xd0, + 0x54,0x76,0x84,0xe9,0xb1,0x55,0x7e,0x6d,0xbc,0xbd,0x58,0xc9,0xc8,0x9f,0x7a,0x6f, + 0xef,0x2,0x5,0xb8,0xc9,0x55,0xdd,0x91,0xa2,0xf4,0xe,0xc0,0xcb,0xa6,0x11,0xa0, + 0x1d,0x95,0x8a,0xcf,0xea,0xa,0x3d,0x28,0xc7,0x15,0xf1,0x10,0xb5,0x6d,0xfe,0xa5, + 0xee,0x4,0xdd,0xb8,0xd9,0x3b,0xc9,0xfb,0x30,0x58,0xbc,0x7b,0xfe,0xcd,0x1c,0x9c, + 0xe2,0xa7,0x6c,0xce,0xb1,0x29,0xf6,0xf8,0x3f,0x68,0x9,0x74,0x55,0x87,0x1a,0x45, + 0x8c,0x77,0x7d,0xe5,0xb2,0xc7,0xe1,0x62,0x9f,0x1e,0xdd,0x9e,0xeb,0xfa,0xba,0x4e, + 0x22,0x27,0x1d,0x53,0xd0,0x93,0xcb,0x10,0x7c,0x54,0x4,0xd1,0xdb,0x1e,0x96,0x68, + 0x15,0x15,0xcd,0xc7,0x5c,0xaf,0xa9,0xfb,0x4d,0x87,0x1a,0xb8,0x2,0xd5,0x8,0xa3, + 0x7c,0x25,0xf6,0x4d,0x39,0xc2,0xdc,0xb5,0x17,0xe0,0x7,0xf3,0x7e,0x9e,0xdb,0x93, + 0x33,0xaa,0xda,0x8f,0xd9,0x84,0xb,0x28,0x8c,0x25,0xe0,0x8e,0xfa,0xe8,0xb2,0x78, + 0x8e,0xa9,0x45,0x47,0xec,0x23,0xfc,0x4,0x83,0x83,0x77,0x3,0x22,0x54,0x96,0x55, + 0x7e,0xf1,0x64,0x58,0x76,0x6f,0x0,0x3,0x95,0xe1,0x12,0x10,0x4a,0xc4,0x8,0xd8, + 0x6e,0x4e,0x20,0x5b,0x71,0x9c,0xdf,0x74,0x21,0x57,0x77,0xc2,0x2b,0x8e,0x19,0xa9, + 0x80,0xfc,0x82,0xf6,0x6d,0x82,0xfa,0x82,0xe3,0xd,0x92,0x2f,0x51,0x9b,0x87,0xbf, + 0x69,0xa8,0x9b,0x5a,0xc4,0x7b,0xce,0x65,0x52,0x47,0x29,0x7e,0xd5,0xc1,0xa7,0x56, + 0xbe,0xa9,0xcc,0xab,0x2d,0x47,0x2e,0x90,0xd3,0x41,0xbf,0x25,0x5c,0x48,0x65,0xc5, + 0x70,0x1,0x20,0xb4,0xfb,0xee,0x1b,0xcd,0x36,0xc3,0x4c,0x8b,0x85,0x74,0x61,0xc3, + 0x1e,0x2f,0x70,0xca,0xf5,0x1e,0x5c,0xca,0x5f,0x9b,0x6f,0xbb,0x63,0xd4,0x81,0xd3, + 0x55,0xa1,0x9,0x51,0x11,0x24,0x20,0x47,0xe7,0xeb,0x53,0xec,0xdf,0xb4,0x30,0xfe, + 0x63,0xa0,0x49,0x5a,0x3f,0xa5,0x25,0x9e,0xc1,0x94,0xda,0x25,0xe9,0xdb,0x79,0x3f, + 0xfd,0x82,0x11,0xf,0xa6,0xb0,0xd5,0xe,0x9c,0x29,0x7a,0xfc,0xde,0xaa,0xfb,0xc1, + 0xcb,0xc4,0x1c,0xb,0x6b,0xc0,0xa9,0xac,0xd5,0x4,0xd1,0xbf,0xe0,0x4b,0x7e,0xde, + 0x4d,0x8f,0x6d,0xf3,0x40,0x43,0x81,0x5d,0xec,0x7b,0x5a,0xcb,0x27,0xd5,0xd,0xf2, + 0x9a,0x2a,0x7d,0x85,0x6a,0xa6,0x32,0xbf,0xab,0x84,0xfe,0xc,0x4f,0x7e,0x6a,0x9d, + 0x8d,0xd7,0x11,0xce,0x9a,0x13,0xab,0x87,0x8e,0x6,0xd2,0x35,0x5b,0xe0,0x28,0xf5, + 0x8a,0x25,0xfb,0xf4,0xcc,0x2e,0xb5,0x78,0x32,0xb4,0x84,0x82,0xb2,0x6e,0x20,0x41, + 0x46,0x31,0x8f,0xe0,0xc3,0x3b,0x69,0x53,0xc0,0x3c,0x88,0x1c,0x1d,0x31,0x91,0xa7, + 0x56,0x8d,0x1d,0x23,0x3c,0x52,0x1b,0x6e,0x7,0x1f,0x70,0x3a,0x8d,0x10,0x7b,0x53, + 0x42,0xb,0x35,0x6,0xc5,0x1e,0xd8,0x86,0xd9,0x62,0x22,0xf7,0x13,0x33,0x1f,0x69, + 0x41,0xbb,0xd,0x7d,0xe,0x28,0x6b,0x95,0xc7,0x5c,0xcf,0x55,0x6c,0x4b,0xa9,0x2e, + 0xd5,0x5e,0xb4,0x9b,0x7c,0x8d,0xa1,0x56,0x6f,0xc3,0xcd,0x82,0x76,0x6d,0xec,0xb7, + 0xa8,0x79,0xb4,0xb7,0x21,0xa0,0x4d,0xe8,0xfc,0x9c,0xbe,0x69,0x67,0xe7,0x98,0x3d, + 0x46,0x4d,0x58,0x42,0xda,0xf9,0x18,0xca,0x3d,0x66,0x4d,0x33,0x53,0xb9,0xeb,0xfb, + 0x33,0xa0,0xb3,0x55,0xc0,0x80,0xbd,0xbd,0x1d,0x7c,0x28,0x4,0xe3,0x40,0x41,0x2a, + 0xd,0x19,0xeb,0x67,0x92,0x84,0x32,0xcf,0xea,0x80,0x4,0x3e,0xb9,0x6f,0x3a,0xed, + 0x8f,0x6e,0xc2,0x51,0x6e,0x0,0x8e,0x8c,0x7d,0x36,0x10,0xe0,0x76,0xd1,0xc,0x83, + 0xea,0x77,0xeb,0x7e,0xfb,0x1e,0xcd,0x66,0x1e,0x51,0x24,0xd8,0xc0,0xde,0x46,0x51, + 0x4d,0x88,0x22,0xbb,0x88,0xb0,0xc7,0x85,0xe7,0xd8,0x67,0x5e,0x2a,0xf2,0x62,0x15, + 0x6a,0xcd,0x13,0xe6,0x6b,0xe1,0xcc,0x8a,0x33,0xf1,0xe2,0x74,0xd0,0xa8,0xc5,0x9d, + 0x31,0x67,0x59,0x39,0x18,0xa1,0xbf,0x0,0xf9,0xa6,0xde,0x24,0x99,0x41,0xb8,0x83, + 0x8e,0xcc,0xe9,0xf9,0xae,0xb7,0x84,0x61,0x29,0xe6,0xd5,0xf9,0x8f,0x1b,0x97,0x40, + 0x82,0x70,0x7a,0x1b,0x91,0xb9,0x1b,0x8b,0x60,0x79,0xaf,0xf9,0xba,0x69,0xfc,0x49, + 0xb5,0xe7,0xc3,0x64,0x1f,0xc7,0x45,0x48,0xaf,0x9b,0x42,0xbe,0xb6,0x59,0x0,0xb9, + 0x49,0xf9,0xd4,0xdb,0xb3,0x6f,0x67,0x14,0xe9,0x97,0x8d,0x24,0x80,0x8a,0xed,0x36, + 0xf1,0xb1,0x1a,0x11,0x79,0x5f,0x59,0xa8,0xfa,0x1b,0x68,0x32,0x74,0xe7,0x6b,0xbe, + 0x61,0x40,0x9a,0x15,0x2f,0x81,0xa8,0x19,0x19,0x36,0xbd,0x99,0xc0,0xab,0xcf,0x33, + 0xdc,0xe9,0x44,0x56,0xc9,0x9e,0x7f,0x44,0xb9,0x67,0x76,0xae,0xce,0x61,0x6d,0x30, + 0x21,0x87,0x45,0x51,0x88,0xed,0xe9,0xa2,0xa3,0xa7,0xbb,0xe3,0xd2,0xc,0x17,0xaf, + 0x75,0x5c,0x86,0x3f,0xfa,0x85,0x4,0x34,0xec,0xf9,0xe2,0xbb,0x5c,0xcf,0x6b,0x7d, + 0xd6,0xb0,0x4e,0x60,0x1e,0x39,0x82,0x41,0x60,0xbd,0x25,0x34,0xc9,0x3d,0x63,0x40, + 0x99,0xe9,0xfe,0x14,0xee,0x3,0xc7,0xdb,0x7d,0x2b,0x17,0xd9,0xfa,0x82,0xd6,0x52, + 0xb2,0x26,0x32,0x50,0xde,0x34,0x91,0x3f,0xf1,0xb7,0xf2,0x3c,0xf4,0x57,0xfb,0xe, + 0xc0,0xfa,0x22,0xb0,0x7e,0x69,0xc,0xfb,0x94,0x24,0x55,0x10,0x26,0x2c,0x62,0xd9, + 0x52,0x14,0xa9,0x31,0x48,0x3c,0xf0,0xb9,0xf3,0xe3,0xf5,0x68,0xba,0xf1,0x76,0xfb, + 0x6d,0x18,0xac,0x6b,0x81,0x38,0xe6,0x96,0xdb,0x3c,0xa6,0x3,0x68,0x88,0x5c,0x3b, + 0x9c,0x6,0xeb,0x64,0x42,0xdc,0x9d,0xb5,0x41,0x94,0x1e,0xfb,0x6,0x14,0xf7,0xf2, + 0xab,0x24,0x5e,0xad,0x5d,0xc4,0x44,0x39,0x1,0x6a,0xbb,0xe9,0xf2,0x18,0xa4,0xf, + 0x1f,0x90,0xf2,0xe0,0xed,0x90,0x97,0x2f,0xa4,0x35,0x2b,0x2b,0xc9,0xa3,0x1e,0x75, + 0x47,0xfc,0xa2,0x24,0x41,0x66,0x5e,0xc2,0xd0,0x99,0xac,0xc3,0xb2,0xd0,0x52,0x51, + 0x61,0x45,0x32,0xce,0x56,0x49,0xfd,0x7a,0x7f,0xa9,0xa5,0xc8,0x4d,0x44,0xbd,0x14, + 0xc0,0x61,0x39,0x81,0xc7,0x17,0x44,0x99,0xb0,0x70,0xdc,0xe2,0x41,0xaf,0x34,0x23, + 0xf4,0xe6,0xf1,0xca,0x30,0x70,0x46,0x2f,0x1a,0x6b,0xf7,0xe6,0x2f,0xb6,0xfa,0x6f, + 0x18,0x34,0xf1,0x5f,0x4b,0x36,0x78,0xfc,0xa7,0xd5,0xdf,0x68,0x85,0x94,0x8b,0xf9, + 0x7b,0xfd,0xc5,0x2b,0x6e,0x8b,0x5b,0x8,0x76,0xd2,0xee,0x26,0x89,0x69,0x95,0x21, + 0x9e,0x7,0x1,0x69,0xbd,0x79,0xe5,0x65,0x4f,0x46,0x4d,0x54,0xda,0x59,0x4f,0xd5, + 0x57,0x94,0x1,0x45,0x9f,0xdb,0x4d,0x16,0xaf,0xbb,0x3c,0xb8,0x25,0x52,0xda,0xc3, + 0xd8,0x5b,0x2e,0x96,0x54,0x14,0x7b,0xa4,0x5a,0xc9,0x78,0xb4,0x23,0xc7,0x8a,0xf9, + 0xdb,0xc,0x3f,0x7b,0xe7,0xc,0x12,0x97,0xc7,0xcd,0xd0,0xec,0x20,0x2b,0x31,0xf9, + 0x86,0x5f,0x90,0xda,0xf2,0x8c,0xfe,0xcd,0x56,0x78,0x82,0xf8,0xbf,0x8d,0xf2,0x9c, + 0x99,0xb1,0x97,0x81,0xbd,0xa9,0x99,0x5,0x78,0x6a,0xf1,0x18,0x95,0x23,0x12,0x9b, + 0x2,0x23,0x76,0xf5,0xaf,0x76,0x43,0x85,0x6e,0xc5,0x7e,0x2e,0x53,0xf0,0x4a,0xec, + 0xa2,0xe2,0xee,0xdf,0xc,0x8,0xe4,0x84,0x72,0x56,0x9d,0x87,0xf9,0x2f,0x23,0xfb, + 0xd1,0x99,0x71,0x1,0x8f,0xb4,0x86,0xfd,0xfa,0x84,0xac,0x4e,0x75,0x76,0xbb,0x97, + 0x59,0x2a,0x77,0xe5,0x32,0xdb,0x6a,0xa4,0xb2,0x87,0xab,0xac,0x37,0xce,0xa8,0x88, + 0xe7,0x9a,0x8a,0x78,0x4f,0x90,0xf5,0x4a,0x16,0xa2,0x19,0xb,0x1a,0x54,0xa3,0xf2, + 0x7e,0x9a,0xd8,0xb0,0xf6,0xc3,0x55,0xa9,0x4b,0x1,0x56,0x2,0x4f,0x7e,0x8b,0x37, + 0x19,0x16,0xaf,0xe8,0x26,0x26,0xb2,0xbb,0xc8,0xcb,0xc7,0x62,0x20,0xea,0x56,0x1e, + 0x5,0xae,0xce,0xfb,0x72,0x24,0x25,0x3e,0xa4,0xfa,0x40,0x73,0x7a,0x4b,0xab,0x13, + 0xe0,0xda,0x7b,0x8,0x1,0x2f,0xc3,0x4a,0x7a,0x8b,0xac,0x1b,0xf5,0x3,0x39,0xfb, + 0x32,0x9,0xf7,0xa4,0xac,0x1e,0x62,0xd1,0x98,0x23,0x45,0x13,0x6e,0x70,0xa6,0x50, + 0x4c,0x22,0xd7,0x4d,0xd0,0x9b,0x97,0x4c,0xa7,0xc4,0xe6,0x9d,0x47,0x20,0x19,0x79, + 0xa8,0x12,0x1f,0xd5,0xaf,0x1,0xa7,0x48,0x24,0x6c,0xdb,0x93,0xdd,0x2,0x63,0x2a, + 0x24,0x3b,0xf6,0xf5,0x56,0xf,0xc1,0xfd,0xd3,0xa8,0x1c,0x1b,0x48,0x35,0x15,0x71, + 0xc6,0x34,0x47,0xf5,0xb4,0x6e,0xbe,0xd9,0xda,0x9a,0xec,0x38,0x9c,0xcf,0xe1,0x40, + 0xb,0xd9,0xb5,0xe0,0x68,0xf6,0xdf,0xbb,0x9f,0x7b,0x56,0x68,0xb0,0x6b,0xd9,0xf7, + 0x1f,0xa0,0xed,0xd4,0xf,0xac,0x2e,0xe9,0xc6,0x1b,0xa2,0xe2,0xea,0x84,0x24,0x75, + 0xdd,0x59,0x56,0x46,0x51,0xb5,0x81,0x70,0x31,0x58,0xd8,0x62,0xc3,0x32,0xd9,0x63, + 0xd2,0xc7,0x38,0xe1,0xf4,0xe5,0x4c,0x3b,0x1,0xee,0x1f,0x6b,0x73,0xc2,0x60,0xd1, + 0x1c,0xb6,0x97,0x6d,0xec,0x1a,0x5e,0x1e,0x72,0x37,0x0,0xb5,0xe9,0xd9,0x19,0xbc, + 0x22,0xd0,0x1f,0x96,0x36,0xea,0xd1,0x37,0xd9,0xf0,0x22,0xcc,0x33,0x82,0x9e,0x50, + 0xb9,0xb6,0x3d,0xa6,0xd0,0x9b,0x44,0xc2,0x53,0x45,0xf7,0x3d,0x9e,0x91,0x79,0x40, + 0xe1,0x98,0xd6,0x19,0x83,0x29,0x50,0xdc,0x99,0xf2,0x2a,0xcd,0x75,0x48,0x9d,0x2f, + 0xfe,0xda,0xd5,0x4f,0xf6,0x9a,0x91,0xc9,0x5f,0x8a,0x86,0xfd,0x1c,0x0,0xbe,0xfd, + 0x19,0x15,0x17,0x9c,0x3e,0xe7,0xf9,0xd8,0x5a,0x24,0xa6,0x4f,0xeb,0x44,0x7f,0xeb, + 0x9e,0xd4,0x3b,0x15,0x6f,0xcd,0xde,0xce,0xd7,0x65,0x4d,0xf3,0xe5,0x8b,0x71,0xfe, + 0x20,0x9,0x1b,0x5f,0x70,0x94,0xb7,0xca,0xb8,0xdd,0x99,0xa5,0xa1,0x19,0x11,0xbf, + 0x6e,0xcb,0xd5,0x5d,0x99,0x34,0xac,0xf0,0x1a,0x79,0x64,0x0,0x84,0xd6,0x7e,0xa4, + 0x5f,0x99,0x4,0x4f,0x2f,0x3b,0x99,0x67,0x98,0x33,0x8c,0x3a,0xcc,0x9d,0xfa,0x3b, + 0xe9,0x50,0x18,0x83,0x84,0x44,0xf4,0x9e,0xbd,0x59,0x1e,0x42,0x30,0x9c,0xe7,0xf, + 0x37,0x6b,0x5e,0xe5,0x27,0xf7,0xcc,0xbf,0xab,0x5a,0xfa,0x78,0x77,0x75,0x33,0x61, + 0xc5,0x4b,0x65,0xc9,0x90,0x5a,0xe8,0xcd,0xb3,0x7,0x90,0x64,0xa4,0xf7,0xf2,0x5b, + 0xe2,0x52,0xc0,0xa,0xc9,0x8d,0xca,0x75,0x67,0x45,0xed,0x5f,0x3a,0x21,0x40,0x7f, + 0xec,0x25,0x49,0xfc,0xfe,0xb1,0xca,0x33,0xb9,0x5b,0x97,0xdd,0xd2,0xa,0x39,0xb6, + 0xdb,0xf9,0xc0,0xa6,0x7,0xb,0x9b,0x6f,0xcf,0xa,0x4e,0x89,0xaa,0x8e,0x9,0x97, + 0xb4,0xd2,0x14,0xb3,0x84,0xdf,0x66,0x3e,0xba,0xfd,0x9b,0x8e,0x88,0xd4,0x45,0x64, + 0x4e,0x85,0xb,0x56,0x11,0x27,0x45,0x60,0x31,0x13,0xea,0xdb,0xa1,0xf3,0xf3,0xd5, + 0x46,0x8,0xa,0xcb,0x67,0x70,0x89,0xa2,0xee,0x26,0x31,0x77,0x7a,0xf5,0xdb,0xc9, + 0xfa,0x67,0x9f,0x8b,0x8e,0x64,0xec,0x3f,0x77,0xd7,0x9a,0x19,0x4b,0xe,0x6f,0x92, + 0x96,0x79,0xdd,0xfd,0x69,0xe6,0x20,0x58,0x8c,0x51,0x4f,0x8,0xc6,0x2c,0x51,0x42, + 0x13,0x70,0xcd,0xa1,0xd4,0xba,0x60,0xcb,0x12,0xfa,0x64,0x5e,0xa,0xd3,0x70,0xa0, + 0xcc,0xcd,0x1e,0x37,0xb4,0x3f,0xf,0xc1,0x10,0x5f,0x49,0x57,0xb,0x1a,0x99,0x1e, + 0x8a,0xe6,0x3f,0xde,0x22,0x9f,0xaa,0x34,0x9a,0xf,0x12,0x24,0x63,0x82,0xc4,0x30, + 0xcf,0x63,0xe6,0x5,0xa2,0x76,0xc6,0xb2,0xd5,0x10,0xa,0x60,0x2a,0x23,0xfd,0x34, + 0xb,0x3d,0x13,0x2d,0x5c,0xbd,0x61,0x76,0x4c,0xf3,0x9b,0xaf,0xf5,0xdf,0x60,0xc6, + 0x43,0x47,0xcb,0xe5,0x3d,0x92,0x99,0x13,0x22,0x23,0xf2,0x4c,0x47,0xf0,0x80,0xd1, + 0xad,0x13,0xfe,0xa,0xd0,0xdf,0x81,0x9c,0xd3,0x1d,0x4d,0xca,0xfc,0xad,0x11,0xc0, + 0x74,0xdc,0xa6,0xb2,0xee,0xbf,0x45,0x11,0xe3,0xb8,0xdc,0xaa,0xa9,0xdc,0x7c,0x58, + 0xef,0xfa,0xe1,0x40,0xda,0x63,0xdc,0x2f,0x0,0xa9,0x79,0x7d,0xd6,0x8a,0x3e,0xcb, + 0xe6,0xe4,0x7e,0xd5,0x25,0x43,0x66,0x88,0xfb,0x43,0x33,0x26,0x20,0x2f,0xfd,0x8f, + 0xa9,0xdf,0xcf,0x4,0x44,0x2c,0x33,0x44,0xd6,0x2c,0xc1,0x2d,0x36,0x7f,0xf8,0x1d, + 0xe4,0xf6,0x72,0xa,0x3b,0xd8,0x92,0xb6,0x9b,0x45,0xdc,0x3b,0xf3,0xda,0xca,0x9d, + 0xbb,0x1a,0xa1,0x7f,0xc6,0x55,0x43,0x9d,0x1,0x85,0x4a,0x38,0x5,0x44,0xd4,0xe9, + 0x3b,0x48,0x73,0xf5,0xa0,0x6,0xad,0x3d,0xca,0x8a,0xf7,0xbe,0xe5,0xc3,0xdb,0x21, + 0x5d,0xfd,0xa0,0x24,0xd2,0xe3,0x41,0xd3,0x69,0x8c,0x8b,0xee,0x50,0x61,0xd8,0x8b, + 0x29,0x4d,0x82,0xc9,0xd2,0x30,0x86,0x9e,0x3a,0x7f,0xdc,0x9f,0xc2,0x39,0xc0,0x9f, + 0x37,0xe0,0x44,0xa,0xc5,0x85,0x5d,0xae,0x91,0xe9,0x9d,0xe1,0x4b,0xf6,0x6e,0xf3, + 0xc3,0x70,0xbd,0x96,0x20,0xc4,0xb4,0x5a,0xc3,0x12,0x7a,0x6,0x4b,0x3b,0xa5,0x2, + 0x1d,0xe9,0x8b,0x62,0xef,0xe8,0x11,0x81,0xd2,0x2f,0xe3,0x9d,0x26,0xd1,0x91,0xe9, + 0x42,0xcf,0x0,0x62,0x94,0xb5,0x3c,0xd7,0x47,0xb6,0xdd,0x92,0x72,0x3,0x14,0x8f, + 0xed,0x9f,0x71,0x5d,0x88,0x2,0x5e,0xdb,0x31,0x42,0x79,0xd6,0x14,0xc,0x40,0xd5, + 0xdb,0x41,0xb7,0xef,0x76,0xf4,0xc7,0xbd,0x2b,0x25,0xcf,0x9d,0x28,0xe3,0xac,0x95, + 0x3,0x1e,0xf2,0x8b,0x21,0x52,0x67,0xd1,0x94,0x61,0x29,0x29,0x6d,0x69,0xfe,0xc8, + 0x2a,0xb7,0x38,0x20,0x2c,0x7f,0x5d,0x57,0xa4,0xac,0xf5,0xcc,0x90,0x22,0x63,0x93, + 0x41,0x56,0x9f,0x62,0x28,0x86,0xb3,0xbd,0xe7,0xdc,0x66,0xd4,0x47,0xe4,0x9d,0xf0, + 0x1c,0xd5,0x12,0x48,0x55,0xee,0x20,0x79,0x9c,0x16,0x47,0xac,0xb7,0x2a,0xc0,0xf8, + 0x0,0x60,0xda,0x29,0x66,0x8f,0x66,0x4f,0x6c,0x4c,0x24,0x33,0x31,0xc2,0xa4,0x4e, + 0x18,0x36,0x96,0xed,0x25,0xb6,0xe6,0xc1,0x4c,0xad,0x6f,0x5,0xd7,0x30,0x7d,0x58, + 0x10,0x59,0x1,0x76,0x68,0xe6,0xc5,0x54,0x33,0x6a,0x8,0x64,0xac,0xac,0x32,0x44, + 0xe2,0x49,0x32,0x87,0x7f,0x99,0x4a,0x4c,0x47,0x39,0xd0,0x9f,0xe8,0x4e,0xf7,0xf8, + 0x27,0xf8,0xee,0x8f,0x5f,0x35,0x64,0x92,0x9f,0x6c,0x76,0x4c,0x98,0x29,0x10,0xfa, + 0x72,0xc2,0x82,0xf1,0x5c,0xcc,0x3e,0xa3,0x85,0x8e,0x43,0x6e,0xdd,0xba,0xe6,0x84, + 0xb3,0xd6,0x15,0x92,0x8b,0xf8,0xa4,0x2b,0x65,0x1c,0xf6,0x7d,0x45,0x7,0x78,0x37, + 0x49,0xfa,0x29,0xa5,0x48,0xe7,0x4a,0xcd,0x76,0xd,0xbc,0xd3,0xc8,0xa3,0x59,0xfb, + 0xf9,0xed,0x8f,0x85,0xe6,0x34,0x30,0xcb,0xcf,0xa6,0x49,0x94,0x2e,0x41,0xcb,0x77, + 0x3c,0x75,0x9d,0x4,0x5d,0xe7,0x52,0x53,0x74,0xf,0x28,0x3d,0x32,0x1,0x3a,0xac, + 0xee,0x49,0xb1,0xd5,0xfc,0xe2,0x21,0xcd,0x9,0x6a,0x62,0xb6,0x2b,0x2f,0xae,0xe6, + 0x24,0x4c,0xeb,0x81,0xb3,0x3e,0x54,0x28,0xcc,0xfb,0xe5,0xfe,0xfc,0x9f,0xab,0xeb, + 0xe8,0xdd,0x41,0xe5,0xc0,0x62,0xb3,0x49,0x4c,0x96,0x80,0x77,0x45,0x2f,0x5f,0x69, + 0x7b,0xca,0x6a,0xae,0x9,0xbe,0xd6,0x55,0xbb,0xbc,0xd3,0x38,0xdb,0x0,0x25,0xc4, + 0xdd,0x66,0x2b,0x1e,0x49,0x5e,0x67,0x95,0xf4,0xe7,0x8d,0xb9,0x17,0xec,0x23,0x12, + 0xb7,0x8d,0xc0,0x40,0xcc,0x18,0x95,0x8,0x54,0x69,0x40,0x31,0x69,0x65,0x75,0x47, + 0x4c,0xa0,0x65,0x95,0x0,0x4d,0xaa,0x74,0xb4,0x38,0x2f,0x4c,0xa4,0x52,0x5e,0x5c, + 0x60,0x9f,0x1c,0xac,0x37,0x31,0xb4,0x8b,0x9b,0xf4,0x3c,0x84,0xda,0xb2,0x4c,0xa6, + 0x53,0x31,0xbb,0x53,0x7e,0x66,0x48,0xb3,0x1f,0x77,0x0,0xc3,0x49,0xdd,0xa0,0xa9, + 0xfc,0xbc,0x56,0x34,0xee,0x8a,0x40,0xa,0x0,0x7c,0xe,0xda,0x2f,0x5a,0x1,0x83, + 0x8c,0xbc,0x56,0x8a,0xa2,0x9e,0x3e,0xc1,0x95,0xbd,0x86,0xdf,0x9c,0xa6,0x9,0x19, + 0xe2,0xdf,0x4e,0x51,0x6a,0x8e,0x5b,0x6a,0xb,0xe9,0xc4,0x3b,0x44,0xc5,0x3e,0x50, + 0x82,0x94,0x5b,0x26,0xb3,0x99,0x67,0x49,0xd7,0x6d,0xa8,0x74,0x14,0xb2,0xd,0x77, + 0x92,0x5b,0xc8,0xfc,0x69,0xa4,0xe7,0x75,0x8e,0xac,0x30,0xd2,0x73,0x6e,0xa3,0x75, + 0x82,0xfe,0x1b,0x36,0x98,0x83,0x0,0xef,0x70,0xa8,0xe3,0x85,0x5b,0xf1,0xfc,0x6d, + 0x4d,0x45,0xea,0xb7,0xe9,0xd2,0xac,0x78,0x7f,0xdc,0xcb,0x72,0xca,0x6f,0x68,0xcc, + 0x6e,0x83,0x4,0x86,0x86,0x83,0x77,0xf7,0x2c,0x5b,0xfc,0x8,0x4d,0x79,0x75,0x9b, + 0xbe,0x60,0xd2,0x29,0xb2,0x7f,0xa1,0xb2,0xdb,0x6d,0x25,0xa6,0xdc,0x8d,0x73,0xca, + 0x91,0xf6,0x52,0x97,0xf9,0xc9,0xf,0xa6,0x25,0x8b,0x2e,0x73,0x5,0x23,0x8e,0x44, + 0x4,0x61,0xec,0xb6,0x60,0x8e,0x69,0xbb,0x7c,0xf,0x62,0xd8,0x9c,0x55,0xa4,0xad, + 0xcc,0xf6,0xc5,0x46,0xc0,0xd4,0xec,0xe5,0x61,0x1b,0xd8,0xe5,0x3f,0x67,0x2a,0x43, + 0x48,0x17,0x79,0xa8,0x26,0xe3,0x64,0x22,0xf2,0x46,0xfa,0xf,0x1c,0x1f,0x3d,0x68, + 0x16,0x3,0xae,0xd6,0xd7,0x1c,0x3d,0x39,0xb6,0x16,0x20,0xf5,0xfd,0xc9,0xb8,0x46, + 0x61,0x33,0x6f,0x7,0x17,0x53,0x29,0x89,0x1a,0xa3,0x98,0x36,0xc3,0xd5,0x1e,0xd9, + 0xd8,0x4c,0x31,0x31,0x68,0xed,0x6a,0x20,0x83,0xa,0x95,0x81,0x54,0x4f,0x48,0x35, + 0x2,0xb7,0x3c,0x19,0x8a,0xe4,0x22,0xa4,0x88,0xba,0x5a,0xcb,0x11,0x78,0xa6,0x69, + 0xc5,0x57,0x9a,0xad,0xc4,0x85,0xcd,0x48,0xf,0xe3,0x4a,0x63,0x33,0x92,0x18,0x35, + 0xc9,0x54,0xcd,0x54,0xb8,0xef,0x79,0x42,0x2a,0xd3,0xe,0x3b,0x4d,0x34,0x25,0x13, + 0xb,0xbf,0x40,0xcf,0xc4,0xf,0x19,0xd4,0xf2,0x63,0xb7,0xa5,0x75,0xd0,0x5a,0xbe, + 0xa4,0x28,0x13,0x5e,0x97,0x8c,0xa0,0xc1,0x61,0x2e,0x7d,0x2e,0xe2,0xa2,0xc0,0xed, + 0x62,0x1,0x3e,0xa7,0x8f,0xd6,0x7c,0x82,0x3a,0xb3,0xa7,0x2f,0x84,0x2,0xed,0x2a, + 0x2a,0x80,0x88,0x41,0x8d,0xa8,0x4,0x6e,0x56,0x81,0x9c,0xb8,0x24,0xdc,0x27,0x6, + 0xdd,0x65,0xad,0x6e,0x3c,0xa9,0x70,0xf5,0x5e,0x19,0xa4,0xe2,0x9a,0x92,0x8c,0x45, + 0x92,0x94,0x86,0x20,0x3d,0x8a,0xe,0x14,0xc,0xaa,0xcc,0xaf,0x87,0xf3,0xb6,0xe5, + 0x59,0xe3,0xd3,0x15,0x8e,0x44,0xb,0x6c,0xdc,0x2f,0xce,0x78,0xc1,0x5c,0xbd,0x55, + 0xf0,0x44,0xf4,0xae,0x4f,0x4,0xc2,0xda,0x2e,0x8f,0x8b,0x36,0x4,0xc1,0x1c,0xdc, + 0xa5,0xef,0xf2,0xb3,0xb3,0x7d,0x20,0x91,0xad,0xef,0x89,0xee,0xcb,0x47,0xc3,0xbc, + 0xb,0xb9,0x6b,0xd9,0x3d,0xad,0xb5,0x6b,0x3e,0xc0,0xa1,0xc1,0x82,0x3d,0x9e,0xa7, + 0xac,0x91,0xdb,0xe0,0x8f,0x7b,0x72,0x3d,0xea,0x7b,0xab,0xb6,0x42,0x70,0xf3,0x4d, + 0x2a,0x5f,0x28,0x67,0x8d,0x5d,0x52,0x4b,0x1e,0x74,0xd,0xa0,0xb1,0xab,0xc7,0xde, + 0xbd,0xa3,0xbf,0x4d,0x20,0xb1,0xa,0xb,0xac,0xb5,0x42,0xee,0x26,0x36,0xbb,0x50, + 0x15,0xe3,0x37,0xa2,0xc0,0x8a,0xed,0xde,0xfe,0xfa,0x7f,0x30,0xa7,0xc7,0x8e,0x65, + 0x6b,0xcd,0x32,0xb,0xfe,0x3c,0x96,0xab,0xf1,0xd8,0x9a,0x19,0xf,0x57,0xe8,0x24, + 0xba,0x21,0x47,0x7c,0x2b,0x35,0x5b,0xa9,0xb0,0x5b,0xd9,0xd7,0x23,0xe8,0x3d,0xe, + 0xb6,0xee,0x1a,0xb6,0x2b,0xb0,0x62,0x1d,0x9,0x7d,0xb5,0x18,0xd4,0x1f,0xbb,0xf, + 0xbf,0x82,0xb,0xea,0xb8,0x67,0x94,0xe8,0x42,0xed,0xc0,0xe4,0xd6,0x7d,0xf2,0x8e, + 0x6c,0x8c,0xc4,0x97,0xbc,0xa6,0x34,0xc5,0x24,0x6a,0x5d,0x78,0x89,0x99,0x88,0x49, + 0x1c,0x93,0xb3,0x54,0x7a,0x48,0x3d,0x3c,0xb5,0xfd,0x21,0xd,0x7b,0x94,0x1b,0x67, + 0x21,0xdf,0x7e,0x5e,0x86,0xb3,0x24,0xab,0x9d,0x82,0xa3,0x27,0x9b,0x2c,0xef,0xb7, + 0x40,0xa3,0xd,0x3a,0xeb,0xc9,0xf6,0x21,0xc8,0x18,0x2e,0xc3,0x2c,0x49,0xab,0xcd, + 0x29,0x2a,0x2c,0x30,0x5d,0x50,0xdb,0xfa,0x52,0xfe,0x22,0xed,0x2c,0x12,0x26,0xeb, + 0xb5,0x33,0xa5,0x21,0xfc,0x9c,0xc2,0x45,0x35,0xf0,0x89,0x61,0x3b,0x35,0x2f,0xe3, + 0xde,0x5b,0x14,0x3d,0x2c,0x6f,0x38,0xfd,0x6f,0xda,0xec,0x1b,0x6c,0x13,0x86,0xa2, + 0xc5,0xab,0x43,0x42,0xc8,0x6,0x8,0xfd,0x77,0x91,0xde,0x32,0x46,0x8e,0x16,0x25, + 0xe9,0xaa,0xe1,0x95,0x99,0x1b,0x94,0x88,0x75,0x81,0x23,0xe1,0x14,0x29,0x4,0x59, + 0xd5,0x48,0x9b,0x9e,0x4e,0x23,0x1c,0xc5,0xb4,0xfa,0xf7,0x7a,0x89,0x8e,0x20,0xf3, + 0xb8,0x2,0x89,0x52,0x9c,0x9d,0x5b,0x12,0x9e,0x7e,0x74,0xb2,0x28,0x78,0x8b,0xfd, + 0x40,0x28,0x1c,0x8f,0x4b,0xb7,0xd4,0x80,0xb2,0x4d,0x7a,0xbc,0x5b,0x9a,0x30,0x14, + 0x1d,0xb9,0xe5,0xb9,0xd7,0x41,0x4c,0x76,0x40,0x40,0x2a,0x68,0x38,0xb5,0xe5,0x79, + 0x5d,0x81,0x88,0x29,0x39,0xdc,0x29,0x6b,0x2a,0xa3,0x28,0x5,0xbe,0x58,0x98,0xdb, + 0x92,0x7f,0x15,0x6a,0x40,0xe0,0xe0,0x80,0x21,0x8a,0x68,0xd9,0xc0,0xcd,0x53,0x9d, + 0x4f,0xdb,0xc6,0x88,0xb8,0xef,0xf4,0x63,0x14,0x9c,0x68,0xd2,0xf5,0x2,0x2e,0x8, + 0x1,0xc2,0xf1,0x41,0xa4,0xd2,0x42,0x45,0xdd,0x2a,0x1f,0x9e,0xf8,0xf1,0x3c,0x48, + 0xcd,0x83,0x51,0x7,0xf2,0x46,0xe9,0x86,0xe2,0x52,0x59,0x58,0xd3,0x7,0x60,0x54, + 0xca,0x52,0x16,0xee,0xa5,0x58,0xb3,0x83,0x2,0x53,0xa1,0xfa,0x45,0x5d,0xc3,0x93, + 0x60,0x15,0x9a,0x54,0x5b,0x4,0xda,0xbd,0x56,0xb4,0x17,0xaa,0x3b,0x77,0x7e,0x6, + 0x4a,0x94,0x74,0x6f,0x6c,0xa8,0xf2,0x6f,0xfb,0x14,0x6a,0xc0,0xf0,0xad,0x54,0x52, + 0xc2,0x6e,0x26,0x1e,0x72,0x80,0xdc,0x49,0x35,0x73,0x73,0xf0,0x6a,0xf1,0xf6,0xb4, + 0x87,0xeb,0x24,0x73,0x94,0x96,0xe2,0x10,0x2a,0xcd,0xd0,0x1c,0x7b,0x26,0xed,0x3f, + 0x14,0x14,0xdc,0x87,0x94,0x39,0xd0,0x4a,0xac,0xc3,0x3b,0x97,0xb5,0xb1,0x4c,0xbc, + 0x1d,0xf0,0x31,0xb1,0x87,0x93,0xc1,0x32,0x61,0x13,0x4e,0x5d,0x39,0x3c,0x1c,0x4d, + 0xcf,0xf8,0x54,0x64,0xb2,0xa4,0x2e,0xde,0x68,0x69,0x76,0x9e,0x9b,0xc3,0x5b,0xb8, + 0x34,0xc,0xea,0x3b,0xa0,0x2c,0x6d,0x81,0x3f,0x3b,0xde,0xf7,0x77,0x7a,0xc5,0x47, + 0x74,0x1a,0x2c,0x27,0xbf,0xd9,0x85,0xa7,0x44,0xfc,0x46,0x5f,0x40,0x22,0x97,0x74, + 0xad,0x82,0xaf,0xcd,0x2f,0x9d,0x50,0xed,0xd8,0xae,0xe6,0x51,0x2a,0xac,0x18,0x1e, + 0xc6,0xc3,0xc4,0x6,0x9e,0x4a,0x2e,0x62,0x47,0x74,0xc1,0x87,0x16,0xd8,0x7b,0xc4, + 0xdb,0x2c,0x12,0xb,0x49,0x62,0xf8,0x22,0x91,0x5f,0xf2,0x3b,0xc,0xc,0xd8,0x53, + 0x4f,0x9d,0xd8,0xed,0x67,0x7,0xcf,0xaf,0xfb,0x11,0xb6,0x12,0xea,0x33,0x56,0xc6, + 0xde,0x69,0x51,0x28,0x4b,0xc9,0xc9,0x5c,0x2a,0xbd,0x17,0xb5,0x49,0xef,0x9,0x98, + 0x8d,0x62,0x7,0xf5,0x69,0x56,0x25,0xe4,0x68,0x5b,0x77,0xd2,0xe,0xcd,0x99,0xec, + 0xb6,0x6a,0x94,0x82,0x34,0xde,0x5e,0xdd,0x9c,0x76,0x94,0xe5,0x66,0x1d,0xfd,0xf4, + 0x7f,0x84,0x6a,0xe9,0xdb,0xf,0xce,0x44,0x6a,0x46,0x17,0x79,0x94,0x30,0xe5,0xca, + 0x1a,0xfa,0x4d,0xcd,0xd9,0xac,0xac,0x76,0xa2,0x41,0xdb,0x9,0x5e,0x59,0x7d,0xde, + 0xde,0x67,0x48,0xba,0x76,0x96,0x7e,0xe1,0xdd,0x15,0x5b,0xf1,0x45,0xc0,0xbc,0xde, + 0xbb,0x8a,0xac,0x15,0xb6,0x59,0xb,0x59,0x1a,0xe6,0x62,0x79,0x41,0x60,0xd7,0x9f, + 0xc7,0x20,0xd9,0x3f,0xb6,0x58,0xa0,0x14,0x6d,0x7b,0x6,0x32,0x3c,0x43,0x11,0x78, + 0xcd,0x3d,0x8d,0x4,0x97,0x99,0x5d,0xb1,0x0,0x3f,0xaa,0x41,0x9f,0x82,0x60,0x68, + 0x22,0x3a,0x27,0x59,0x92,0xc7,0x6d,0x7f,0x43,0xf3,0x31,0xfe,0xb6,0xc1,0x77,0x4, + 0x0,0x6,0x8,0x97,0x9f,0xe4,0xc8,0x9f,0x24,0xf3,0x61,0x44,0xf5,0x41,0x2c,0x19, + 0x7c,0xd2,0xf1,0x8e,0x9a,0xde,0x8e,0x5d,0xd2,0xbf,0x5c,0x9,0x82,0xd4,0xd,0x82, + 0x5a,0x94,0x99,0x79,0x79,0xe1,0x19,0x1e,0xd5,0xf9,0xe1,0xcc,0x3c,0xe,0x65,0xb8, + 0xe0,0x57,0xc6,0xfa,0x36,0x55,0xd7,0x89,0x16,0x34,0x12,0x18,0x88,0x20,0x1a,0x62, + 0x34,0xb3,0xdb,0x2e,0x15,0xf5,0x4c,0x6b,0x6f,0xad,0x38,0xab,0xbb,0x1d,0xe3,0x1c, + 0xf3,0xab,0x96,0xa9,0x1,0x6e,0x33,0x96,0x22,0xc5,0xae,0x2b,0x65,0xc8,0x8d,0x99, + 0xfb,0x6a,0xc7,0x12,0xdf,0x93,0xfc,0x4f,0x41,0x35,0xfb,0x7c,0xd1,0x5f,0x18,0xc5, + 0xb,0xae,0x6f,0x8c,0x9c,0x23,0xa2,0xbf,0xe8,0x52,0x6a,0x4e,0x9a,0xf7,0x67,0x97, + 0xe1,0x30,0x29,0xc1,0x43,0x26,0x12,0x85,0xda,0x8d,0x2,0xac,0xec,0x1b,0xf1,0x78, + 0x49,0xe0,0x84,0xe6,0x4,0x27,0x26,0x6c,0x79,0x90,0x3a,0x15,0x8,0xa2,0x2c,0xea, + 0x52,0x55,0xac,0x95,0xfa,0x3e,0x9a,0xd5,0xcb,0x9d,0x2,0x39,0x38,0x73,0x31,0x1, + 0x54,0xb5,0xe7,0xd8,0xdc,0x8d,0xc4,0xd6,0x9d,0x0,0x6b,0x26,0x22,0x97,0x11,0x74, + 0x6c,0x3d,0xa,0x67,0xfb,0xa5,0xbc,0x47,0xc2,0xbe,0x80,0x7a,0xb1,0xb1,0x7b,0x6, + 0x67,0xe3,0xde,0xc4,0x71,0xa4,0x9b,0x8f,0x24,0x7,0xb5,0x46,0x1e,0x46,0xba,0x8a, + 0x83,0x44,0x71,0x7f,0x69,0x2e,0xc7,0xab,0x6c,0xc7,0x26,0x1e,0xf9,0x22,0x24,0xe0, + 0x6,0x83,0xa5,0x77,0xa7,0xc0,0x7,0xcb,0xc7,0x3c,0x91,0xe5,0x82,0xcb,0xef,0x7, + 0x10,0x61,0x6,0xf9,0x8f,0x4d,0xa5,0xfb,0x95,0x4c,0x99,0x8f,0x6e,0xbe,0x70,0x74, + 0xc1,0x17,0x6b,0x69,0xd7,0xf2,0xb4,0x20,0x2f,0xc5,0x85,0xb2,0x91,0x76,0x39,0xa1, + 0xd7,0xbe,0x1b,0xe7,0x8c,0x41,0x63,0x22,0x8d,0xfd,0xb1,0x7b,0x3c,0x22,0xef,0xfd, + 0xb8,0xda,0xe6,0x11,0xcd,0x1b,0x31,0xfd,0xe0,0xb6,0x30,0x72,0xac,0xe8,0x93,0x5, + 0xa7,0x2f,0xec,0x34,0x70,0xcf,0x56,0xfd,0xcd,0x87,0x79,0x89,0x2a,0xe8,0x7,0xe2, + 0xc3,0xed,0xf3,0x12,0x88,0xa4,0x10,0x69,0xdb,0xbf,0x5b,0x88,0xa8,0x6f,0x8d,0xcf, + 0x9e,0xf9,0x5,0xf,0xca,0xda,0x8c,0x18,0xe2,0x85,0xa2,0xd,0x6e,0xa9,0xef,0xb1, + 0x18,0x64,0xc3,0xa0,0x88,0x53,0x8a,0x64,0x13,0x65,0xed,0x3b,0xd4,0xfa,0xc,0x73, + 0xf5,0x90,0x2,0x40,0xea,0x8e,0x58,0xcd,0x14,0x7a,0xda,0x2,0xa4,0x4b,0xb4,0xbc, + 0x2f,0x78,0xdc,0xb7,0xcc,0x67,0x1d,0x5f,0x4d,0x8a,0x9b,0x22,0x5,0x27,0x16,0x7a, + 0xb7,0x18,0xba,0x22,0xa7,0x93,0xf0,0x3b,0x8d,0x4b,0x3e,0x32,0x96,0xf2,0xee,0x45, + 0x6b,0xcc,0xfd,0xb7,0xb3,0x9a,0x18,0x1,0x25,0x33,0xa3,0x2a,0x5a,0xb9,0xa5,0x91, + 0xd1,0xdf,0xb3,0xf8,0xf2,0x24,0x35,0x81,0x70,0xf2,0xb3,0x86,0xe5,0xa3,0xcc,0xd0, + 0xef,0xca,0x89,0x23,0x65,0x21,0xa4,0xa,0xd3,0x48,0xb3,0xad,0x2,0xd8,0xbe,0x53, + 0xb9,0x72,0xcc,0xac,0x17,0x2,0xad,0x87,0xf4,0x62,0xe,0x5a,0x85,0xda,0x2b,0xf4, + 0x25,0x34,0x18,0xa,0xd4,0xbc,0x14,0xa8,0x84,0xc8,0xd5,0x86,0xa1,0x94,0x5a,0xda, + 0x87,0x27,0x8,0x9e,0xa8,0xb5,0xa5,0x1d,0x18,0xb3,0xf6,0x1d,0xf,0x22,0x12,0x34, + 0xd6,0xaa,0x3f,0xab,0xe6,0xd2,0xd4,0x6c,0x1b,0x2a,0x72,0xbd,0xbf,0xcc,0x18,0xc6, + 0x73,0x20,0xe4,0x9b,0xd6,0x8a,0xb8,0x6e,0xbd,0xaf,0xc,0xcc,0x52,0x1e,0x81,0xa8, + 0xc8,0x40,0x54,0xb0,0x13,0xa8,0x9c,0xae,0x53,0xf,0x6c,0x92,0x5c,0x84,0x59,0xcf, + 0x25,0x3e,0x6c,0x7b,0xc8,0xa4,0xe9,0x86,0xd4,0xf5,0xd3,0x27,0x94,0xd4,0xcf,0xdc, + 0x15,0xa3,0xd,0xa7,0xcc,0xa9,0x56,0x20,0xb9,0x42,0x32,0x16,0x47,0x8b,0x65,0x6c, + 0xc9,0xd1,0xe7,0x12,0xf6,0x51,0x18,0xcb,0xc7,0x6b,0x72,0xdb,0x40,0xc1,0xb8,0xd4, + 0xe4,0xc6,0xfc,0xb1,0x70,0x53,0x51,0xa9,0x16,0x83,0x3f,0xdc,0x8e,0xa5,0x49,0xd7, + 0xf6,0xb0,0xe9,0xed,0x81,0x82,0x39,0xc8,0xed,0xab,0xa4,0xae,0xec,0x5e,0x83,0xd2, + 0xa4,0x80,0x4,0x15,0x54,0xd5,0x3f,0x6a,0xd8,0x7e,0xc6,0x68,0xa3,0x10,0xbf,0x9b, + 0x40,0x2a,0x9,0x41,0xac,0x43,0xb,0x1a,0x6e,0xaf,0xc8,0x5c,0x8d,0x4d,0xae,0x32, + 0x4d,0xb2,0xc7,0xa1,0x8,0x7,0x8b,0xe1,0x5,0x52,0xc9,0xa9,0xe1,0x89,0x45,0xa1, + 0xb3,0xcd,0xe3,0xdf,0x11,0x6e,0xfa,0x0,0x9d,0xc3,0x5c,0x2c,0x90,0xb,0x5e,0xde, + 0x3d,0xa5,0x0,0x46,0xac,0x8c,0xa7,0x32,0x5e,0x71,0xdb,0xc0,0xfa,0xa0,0x62,0x2f, + 0xed,0xc5,0xf,0x0,0x34,0xa,0x0,0xd2,0x4e,0xdb,0x7e,0x5e,0x66,0xdc,0x3d,0xa3, + 0x3,0xbd,0x69,0x2f,0x4a,0x11,0x61,0x28,0x82,0xbc,0xe8,0xfd,0xdc,0xcb,0x2d,0xcb, + 0x91,0xbb,0x4b,0x46,0xc6,0x4b,0x98,0x94,0xa6,0x17,0xf2,0xd,0x73,0x31,0x30,0x76, + 0xee,0x1a,0xa6,0xb8,0x2b,0x8,0x60,0x2e,0x45,0x4a,0xab,0x22,0x95,0x58,0xed,0x27, + 0x14,0x39,0x6d,0x5a,0x4,0x85,0xee,0xaa,0x9c,0xe2,0x37,0x11,0x93,0xe7,0x87,0x2, + 0x2,0x2e,0x3a,0xac,0xb6,0x9a,0x5a,0xfb,0x64,0x85,0x9d,0xf9,0xdd,0x8c,0xa1,0xf2, + 0x45,0x8e,0xcc,0xc9,0x15,0xbc,0xf3,0xb1,0x1f,0x2c,0x42,0xb2,0x93,0xca,0x34,0x95, + 0x78,0x6e,0xc1,0xae,0x88,0x1d,0x2a,0x6d,0x22,0xc8,0xe6,0x1,0xd4,0x88,0x73,0x99, + 0x97,0x40,0x63,0x2c,0x7c,0x58,0x5d,0x9b,0x4,0xa0,0x4e,0x97,0xea,0x82,0xac,0xe2, + 0x70,0x6e,0x92,0x79,0xb,0xbc,0xe6,0x2e,0x85,0xcd,0xae,0xd9,0xd6,0x22,0x74,0xed, + 0xe1,0xd7,0x1a,0x5f,0xaf,0x77,0xfa,0xb3,0x97,0xc9,0xca,0x2,0xcb,0x77,0xe5,0xbc, + 0x66,0x78,0x36,0x71,0xb4,0x1d,0x1f,0xba,0xea,0x4d,0x94,0x41,0xee,0x88,0x2f,0xd1, + 0x61,0xc8,0xb0,0x90,0xc0,0x2b,0x45,0x58,0xf4,0x8f,0x5b,0x41,0x8,0xc0,0xfd,0x6e, + 0x39,0x34,0x5f,0x6d,0x51,0xfe,0x28,0xbb,0x4c,0x3d,0x7d,0x3c,0xc5,0xac,0xe,0xa6, + 0xf5,0xbe,0x38,0xb6,0x69,0xfc,0x8e,0x5f,0x8c,0xe9,0xa0,0x14,0x2a,0x1e,0x82,0x63, + 0x52,0x62,0x51,0x23,0x61,0x79,0x5e,0xad,0x36,0x5b,0xe9,0xfc,0x9,0x77,0x23,0x7e, + 0xb5,0x5b,0x35,0x20,0xd7,0xc3,0x7f,0x65,0x2e,0x9f,0x79,0x58,0x3d,0x7c,0x3c,0xf, + 0xde,0x8d,0x32,0x40,0x86,0x10,0x6d,0xbd,0x6c,0x58,0x3a,0xf4,0xcf,0x5d,0x73,0x6, + 0xb9,0x28,0x26,0x91,0xeb,0x25,0x76,0x1a,0x44,0x70,0x73,0x81,0xec,0xaf,0x90,0x4b, + 0xbc,0x42,0xb,0x43,0xd1,0x78,0x1,0xbd,0xd0,0x3b,0x32,0x21,0x19,0xa5,0x27,0xd2, + 0xcd,0xcc,0xe3,0x3a,0xf1,0xda,0x54,0x36,0x4b,0x47,0x37,0xb7,0x76,0xc7,0x3,0x33, + 0x89,0x8d,0xf6,0x5b,0x6,0x77,0x99,0x57,0x33,0xcb,0xf7,0x4c,0x72,0x1f,0x9e,0xbf, + 0x6b,0x2,0x79,0x5d,0xdc,0x4e,0x13,0xa7,0x95,0x4a,0x5f,0x8c,0x91,0xe1,0x3f,0x9a, + 0x6f,0x36,0xf5,0xf5,0xae,0xf,0x4d,0xe1,0xdb,0x45,0x2e,0xcd,0xe3,0x4c,0x8d,0x4f, + 0x4e,0x87,0x2c,0x2c,0xd5,0x3f,0xd3,0xea,0x9,0xb3,0x77,0x9a,0x15,0xb7,0x35,0x5, + 0x6d,0xaa,0xfa,0x9b,0xba,0x48,0x7d,0x96,0x8d,0x2b,0xe3,0xf0,0x77,0x71,0x40,0xc6, + 0x78,0x6c,0x72,0x4e,0x2b,0xc5,0x3a,0x34,0xf8,0x31,0xce,0xf,0x68,0x83,0x14,0xd6, + 0xad,0x8e,0x72,0xe7,0xd6,0x70,0xfd,0xe3,0x9b,0xe1,0xd4,0x93,0xd3,0x94,0xd9,0x4c, + 0x1,0x4c,0x9b,0xab,0x91,0x55,0xdf,0x8b,0x6,0x2e,0x9a,0x6f,0xb1,0x2e,0x46,0xde, + 0xbc,0x38,0xc7,0x13,0x28,0xc5,0x76,0x44,0x28,0x4b,0xd7,0xfb,0x5f,0x31,0x48,0xdf, + 0x7d,0x63,0x8b,0xf,0x38,0x6b,0x1a,0x3f,0x99,0x34,0xae,0xca,0x62,0x74,0xa9,0x9e, + 0x2c,0xf0,0x31,0x55,0xb7,0xa7,0x99,0xdf,0xf2,0xf0,0x5b,0xd1,0x22,0x23,0xb1,0x9f, + 0x87,0x3d,0x2e,0x3f,0xa8,0x49,0x7e,0x42,0xfc,0xac,0x8c,0x60,0xa0,0x37,0x7e,0xcd, + 0x28,0xb0,0x23,0x5f,0x58,0x3c,0xbe,0xcb,0x2d,0x1a,0x9d,0x4f,0x3e,0x50,0x6e,0x45, + 0x8d,0x9c,0x84,0xb6,0x65,0x83,0x78,0x63,0x30,0x6,0x43,0x51,0x3d,0x41,0x1f,0xe4, + 0xf1,0xc1,0x45,0xca,0xfd,0x83,0x96,0x2b,0x9e,0xb3,0x7a,0x5c,0x83,0xe8,0x21,0x91, + 0x5,0xa5,0x48,0xea,0xa8,0x40,0x4e,0x59,0x46,0x11,0xaa,0x3,0x52,0x49,0xe8,0xc4, + 0xb,0xad,0x8f,0x9,0x31,0xa5,0x34,0x4f,0xd8,0x2e,0xab,0x5d,0x96,0xcc,0x6e,0x9b, + 0xf2,0xb6,0x86,0x1b,0x76,0x54,0x74,0xbd,0xe4,0x9e,0xc0,0xb7,0xe7,0x29,0x7c,0xf2, + 0xd6,0x8b,0xfb,0x9,0x31,0xaf,0xd7,0x89,0xdd,0x84,0xe6,0xf3,0xd0,0xd4,0x90,0x43, + 0xb,0x96,0x5f,0x82,0x6b,0xd3,0x40,0x50,0xf2,0x80,0x8,0xda,0x2a,0x84,0xce,0x1, + 0x8f,0x4a,0x89,0xc0,0x7a,0x62,0xca,0xd7,0x66,0x31,0xcc,0x37,0x7,0x5d,0xfa,0x12, + 0x73,0x5a,0x94,0xde,0xad,0x54,0x30,0xa0,0x55,0xb7,0x7c,0x7f,0x3d,0xca,0x0,0xcc, + 0x94,0x8a,0xe,0xf,0x6c,0xd8,0xe7,0x52,0x89,0xb4,0x9,0x90,0x91,0x4,0xa3,0x5, + 0x5e,0xb7,0xe4,0xd,0xd,0x94,0x2d,0xe1,0x4c,0xa9,0x61,0x9,0xf3,0x61,0x56,0x89, + 0x6b,0xe3,0x18,0xd7,0x3c,0x0,0xa9,0xc5,0x34,0xb3,0x57,0xc5,0xb7,0x7a,0x4b,0x96, + 0x32,0xaf,0xa3,0xbe,0xc3,0xd0,0xa0,0x10,0xfa,0x81,0x99,0x6e,0xe3,0xef,0x77,0xce, + 0xd3,0x90,0x27,0x10,0x90,0xd0,0x55,0xc5,0x84,0x2c,0xb,0xbc,0xa6,0xd5,0x53,0x59, + 0x85,0xf6,0x97,0x49,0x47,0xb8,0xd9,0xc1,0x3a,0x73,0xb0,0x9d,0x63,0x28,0x6d,0xb6, + 0xb8,0x94,0x46,0xc9,0x65,0x9b,0x8f,0x6a,0xc8,0x1a,0x27,0xee,0xf0,0x7a,0xc7,0xf5, + 0xf0,0x60,0xbf,0x38,0x19,0x99,0x7a,0xd2,0xd,0xaa,0x71,0xef,0xd2,0x5e,0x26,0x8c, + 0xf2,0x6c,0x56,0xd7,0x87,0x65,0x42,0xcf,0xfe,0x69,0xbf,0x6f,0xe3,0x87,0x66,0xd4, + 0x67,0x26,0x8d,0x0,0x3f,0x87,0xd3,0x4c,0x32,0xc4,0xbb,0x5,0x23,0xe1,0x11,0x16, + 0x4e,0xe6,0x6d,0x55,0xcb,0xb0,0x26,0xcb,0x1a,0x65,0x3b,0x7e,0x6c,0x21,0xd2,0xd4, + 0xc6,0x60,0xd4,0x6,0x67,0x28,0xd1,0x99,0xec,0x8d,0x1f,0x10,0x6f,0xaf,0xa5,0x3d, + 0x97,0x14,0x93,0x63,0xc4,0x39,0xae,0x5e,0x9e,0x6a,0xdc,0x8a,0x8b,0xb0,0xde,0xd2, + 0x90,0xb4,0xd8,0xf8,0xdc,0xab,0x12,0xca,0x39,0xb0,0xda,0x29,0x61,0x81,0x66,0xf8, + 0x15,0x79,0x5c,0xd9,0x32,0x8b,0xb7,0x50,0xf5,0x15,0xdb,0x81,0x45,0xba,0x54,0xd5, + 0xee,0xad,0x4e,0xcc,0x59,0xe0,0x17,0x12,0x91,0x71,0xba,0xf2,0x72,0xa1,0xeb,0x87, + 0x1b,0xc8,0xe0,0xcd,0x54,0x99,0x1e,0x4a,0xae,0xf9,0x4b,0xf3,0x35,0x20,0x49,0x24, + 0xcd,0x98,0x70,0xa6,0xf8,0x87,0x38,0x8a,0x79,0xf3,0x7e,0xeb,0x95,0xe9,0xf3,0x30, + 0x32,0xd4,0xfd,0x6,0xed,0x9c,0x50,0x9c,0x96,0x1c,0x10,0xcb,0xbb,0x5a,0xf0,0x9, + 0x72,0xe0,0xaf,0xea,0x69,0xe7,0x75,0xe2,0x5b,0x73,0x4e,0x70,0x5e,0x42,0xa1,0x90, + 0x97,0x1f,0x97,0x85,0xbb,0x67,0xa2,0xd2,0x3,0xb2,0x1e,0xbe,0x8c,0x8e,0x47,0x7e, + 0x70,0xf6,0x69,0xd9,0x5f,0x5f,0x3c,0x3a,0xd2,0x8a,0xab,0xb0,0x4d,0xcc,0x42,0xe4, + 0xeb,0x59,0x6a,0x28,0x40,0xd,0xfa,0xc3,0x40,0x19,0x2,0xcc,0x28,0x4a,0xcb,0x98, + 0xc0,0x35,0x72,0x20,0x94,0x2e,0xda,0xe7,0xb8,0x86,0x98,0x85,0x53,0x5a,0x6a,0xbe, + 0xb3,0xd5,0x66,0x74,0x62,0xe0,0xb7,0xa2,0x7a,0xb9,0xef,0xa2,0x83,0xbb,0x3b,0x45, + 0x70,0x2d,0xe4,0x85,0x5b,0xbf,0x6d,0x93,0xc5,0x6,0x1a,0x19,0x61,0x84,0x58,0x94, + 0xd9,0xbe,0x88,0xbc,0xa0,0x40,0x5f,0x1b,0x7a,0xce,0xbd,0xfd,0xa,0x78,0x43,0xfa, + 0xa5,0xa8,0x80,0x80,0x68,0x6d,0x14,0x2f,0xf2,0xad,0xc7,0xd3,0x33,0x9f,0xe8,0x8c, + 0x5f,0x71,0x49,0x7f,0x32,0x29,0x1a,0x2c,0xf7,0x57,0x2a,0x82,0xcf,0xed,0x7d,0xf4, + 0x96,0x7d,0x75,0x7e,0xea,0x9,0x2d,0x5d,0xb7,0x75,0x32,0x6a,0x15,0x1b,0xf6,0xf3, + 0xc,0xc0,0xf2,0xbd,0xe9,0x8c,0xe9,0x61,0xe3,0x15,0x63,0x33,0x82,0xe0,0xa7,0x98, + 0x5e,0x1d,0x96,0xc8,0x27,0xc4,0x27,0x5e,0xb9,0x59,0xc8,0x4e,0xf3,0x3f,0x43,0x7f, + 0x0,0xb5,0x3e,0x69,0x43,0x28,0xcb,0xa6,0xbc,0xae,0xda,0x3f,0x90,0x82,0xd7,0x6e, + 0x20,0xee,0x38,0xc6,0xb3,0xde,0x25,0xec,0xb7,0xed,0x3b,0xab,0x2d,0xfd,0x2b,0xad, + 0xb4,0x69,0x17,0x77,0x12,0x62,0x1e,0xce,0x12,0x78,0x8e,0x22,0xfb,0xe5,0x90,0x9b, + 0xd4,0x48,0x62,0x88,0x27,0x87,0xf4,0xde,0xf4,0x31,0xa,0xa1,0x2f,0x36,0x4f,0x63, + 0x1f,0x67,0xda,0x31,0x49,0xf9,0x80,0xda,0x72,0xf,0xfc,0xed,0xf4,0x8e,0x89,0xca, + 0xd6,0xeb,0xd2,0xfe,0xf2,0xc8,0x5d,0xe7,0x79,0x68,0x8a,0xa8,0x9e,0xd9,0xd,0x3d, + 0xc0,0xe7,0xee,0x8a,0x61,0x6f,0x65,0xd4,0xfd,0x63,0x42,0xf2,0xf1,0xcc,0x3d,0x48, + 0x38,0x90,0xc6,0x2c,0xd8,0x25,0x14,0x52,0x8d,0x1e,0x7a,0xab,0x78,0x7,0xe8,0x39, + 0x6f,0x57,0xc3,0xd0,0x46,0xa9,0x25,0x44,0xd,0x68,0xb7,0x7e,0xb4,0xf4,0xc6,0xec, + 0x5,0x8e,0x19,0xdd,0x33,0xad,0xaf,0xc0,0xcb,0x2b,0x6c,0x44,0x32,0xd4,0xfd,0xa1, + 0x2d,0x41,0xf2,0x73,0xea,0x18,0x38,0xf7,0x0,0xef,0x76,0xb4,0x64,0xbd,0xa2,0x6a, + 0xcb,0xbb,0xc7,0xfe,0xe8,0x78,0xbf,0xb5,0xa3,0xab,0x79,0x55,0x0,0x77,0x77,0x2d, + 0xb9,0x6a,0x21,0xa4,0x2,0xd8,0x1d,0x3,0xc8,0x13,0xb7,0x2d,0x50,0x5a,0x17,0x1c, + 0x96,0xdf,0x1b,0x7f,0xd7,0x5a,0xb4,0xfa,0x85,0x2f,0x50,0x86,0x26,0xc7,0x33,0xdf, + 0xb1,0x54,0x5,0xb4,0x2d,0xa1,0xb7,0x75,0xb4,0xee,0x23,0x6,0xc9,0xb9,0xa1,0x60, + 0x19,0x3d,0x5f,0xf0,0x97,0x94,0xeb,0x1e,0x43,0xbc,0xa4,0x69,0x4,0xd7,0xc9,0xb6, + 0xac,0xce,0xea,0x59,0xef,0xa2,0x4f,0x24,0x91,0x72,0x2a,0xda,0x2c,0x4c,0xba,0x46, + 0x89,0x1b,0xb6,0xa0,0x2f,0xa3,0xbe,0x72,0xdf,0xe2,0xdb,0xe3,0x3b,0x25,0x1a,0x67, + 0x73,0x5,0xc0,0x63,0x27,0x10,0x88,0x39,0x2,0x32,0x14,0x2f,0x7e,0xcf,0xf4,0x87, + 0x6a,0xab,0x29,0x99,0xce,0x67,0x8b,0x2e,0x4b,0xe6,0x92,0x6,0xd,0xac,0x6d,0x80, + 0x32,0x2e,0xe4,0xd8,0xbe,0xec,0x12,0x40,0x1f,0x27,0x6f,0x1e,0x76,0xe3,0xa5,0xe0, + 0x10,0x4e,0xf9,0x5e,0xb6,0x85,0x8d,0x2,0x6c,0x20,0x87,0x79,0x4c,0xf4,0x7a,0xfd, + 0xa2,0xde,0xd7,0x61,0xcb,0xe9,0xa2,0x6a,0x90,0x91,0x8,0x7,0xf5,0x2e,0x67,0x6, + 0x7c,0xe0,0x64,0x33,0x66,0x71,0xb4,0x53,0x91,0x3c,0x4c,0x5e,0x31,0xc6,0x5c,0xd4, + 0xa5,0x34,0xb5,0xf0,0x1f,0xd7,0x5c,0x2f,0xe9,0x64,0xb6,0xdf,0x92,0x1e,0x65,0x10, + 0x0,0x49,0xc2,0xe5,0xbb,0x78,0x39,0xcc,0x34,0x86,0x2b,0xe5,0xcc,0x88,0x3a,0x73, + 0xbc,0x6f,0x64,0x5b,0x48,0x40,0x8b,0xb1,0xa5,0x42,0x11,0xb7,0xdf,0xf5,0x47,0x5f, + 0x3f,0xb,0xc5,0x7a,0x3,0xfe,0x48,0xb6,0x5,0xf2,0x9c,0x52,0x7b,0xd6,0xc5,0xb8, + 0x47,0xa9,0x14,0xf,0x6a,0x1f,0x40,0x8f,0xe0,0x51,0x47,0xc1,0x47,0xf,0xa0,0x6, + 0x99,0x66,0x81,0x9c,0xe5,0xc9,0xd2,0x6a,0xbc,0x70,0xbc,0xb8,0xc6,0x2,0x71,0x8d, + 0x2c,0x5,0x1c,0x96,0x25,0x5c,0x26,0x6,0xad,0xec,0x47,0x74,0xfb,0xe8,0x7b,0x95, + 0xce,0xfc,0xb1,0x34,0x46,0x5,0x9f,0x82,0x75,0xdb,0xba,0xbb,0xde,0x2c,0xc9,0x8a, + 0xb1,0xe5,0x21,0xd6,0xc2,0xc6,0x5c,0xef,0x33,0xa4,0x65,0xaf,0xd,0x60,0xc4,0x5b, + 0x5d,0xf6,0x90,0x23,0xfb,0x30,0x25,0xf0,0xc,0xe0,0xac,0x6a,0x8c,0xf5,0xf4,0x3e, + 0x5c,0x16,0x94,0x1f,0x5c,0xf1,0xf,0x90,0x16,0xf3,0xbf,0xa2,0x54,0x84,0xfd,0x31, + 0x7b,0x8e,0xd3,0x77,0x3e,0xf9,0x68,0x4b,0x5a,0x95,0xb5,0x66,0x8b,0x2b,0x25,0x67, + 0xc0,0xb9,0x86,0x1e,0x2b,0x16,0x2e,0xc0,0xa,0xed,0x63,0xde,0x72,0xe1,0x8f,0x6e, + 0x70,0x64,0xe5,0xaf,0xdd,0xce,0x7a,0x38,0xe3,0xaf,0x1e,0xee,0xda,0x43,0x57,0x9c, + 0x7d,0xdd,0x3a,0xa8,0x73,0xe7,0xe9,0xfd,0xd5,0x4d,0x5c,0xc7,0xae,0xeb,0x36,0x20, + 0x50,0x9c,0x4f,0x2e,0xea,0x49,0xe5,0xce,0xf8,0x5,0xbd,0x54,0xc7,0x15,0x70,0x45, + 0x73,0x2a,0x6e,0x66,0x12,0x58,0x64,0xe7,0x25,0xc0,0x2f,0xd4,0x2d,0xe5,0xf4,0x7d, + 0x2,0xc3,0x2c,0xec,0xd,0x91,0x3b,0x85,0x16,0xf8,0x59,0xde,0x8e,0x49,0x24,0x81, +}; + +CNetworkStream::CNetworkStream() +{ + m_sock = INVALID_SOCKET; + +#ifndef _IMPROVED_PACKET_ENCRYPTION_ + m_isSecurityMode = false; +#endif + m_isOnline = false; + m_connectLimitTime = 0; + + m_recvTEABuf = NULL; + m_recvTEABufSize = 0; + m_recvTEABufInputPos = 0; + + m_recvBuf = NULL; + m_recvBufSize = 0; + m_recvBufOutputPos = 0; + m_recvBufInputPos = 0; + + m_sendTEABuf = NULL; + m_sendTEABuf = 0; + m_sendTEABufInputPos = 0; + + m_sendBuf = NULL; + m_sendBufSize = 0; + m_sendBufOutputPos = 0; + m_sendBufInputPos = 0; + + m_iSequence = 0; + m_bUseSequence = false; + m_kVec_bSequenceTable.resize(SEQUENCE_TABLE_SIZE); + memcpy(&m_kVec_bSequenceTable[0], s_bSequenceTable, sizeof(BYTE) * SEQUENCE_TABLE_SIZE); +} + +CNetworkStream::~CNetworkStream() +{ + Clear(); + + if (m_sendTEABuf) + { + delete [] m_sendTEABuf; + m_sendTEABuf=NULL; + } + + if (m_recvTEABuf) + { + delete [] m_recvTEABuf; + m_recvTEABuf=NULL; + } + + if (m_recvBuf) + { + delete [] m_recvBuf; + m_recvBuf=NULL; + } + + if (m_sendBuf) + { + delete [] m_sendBuf; + m_sendBuf=NULL; + } +} + +#ifdef _IMPROVED_PACKET_ENCRYPTION_ +size_t CNetworkStream::Prepare(void* buffer, size_t* length) +{ + return m_cipher.Prepare(buffer, length); +} + +bool CNetworkStream::Activate(size_t agreed_length, const void* buffer, size_t length) +{ + return m_cipher.Activate(true, agreed_length, buffer, length); +} + +void CNetworkStream::ActivateCipher() +{ + return m_cipher.set_activated(true); +} +#endif // _IMPROVED_PACKET_ENCRYPTION_ diff --git a/source/EterLib/NetStream.h b/source/EterLib/NetStream.h new file mode 100644 index 0000000..e15efcd --- /dev/null +++ b/source/EterLib/NetStream.h @@ -0,0 +1,113 @@ +#pragma once + +#ifdef _IMPROVED_PACKET_ENCRYPTION_ +#include "../eterBase/cipher.h" +#endif +#include "../eterBase/tea.h" +#include "NetAddress.h" + +class CNetworkStream +{ + public: + CNetworkStream(); + virtual ~CNetworkStream(); + + void SetRecvBufferSize(int recvBufSize); + void SetSendBufferSize(int sendBufSize); + +#ifndef _IMPROVED_PACKET_ENCRYPTION_ + void SetSecurityMode(bool isSecurityMode, const char* c_szTeaKey); + void SetSecurityMode(bool isSecurityMode, const char* c_szTeaEncryptKey, const char* c_szTeaDecryptKey); +#endif + bool IsSecurityMode(); + + int GetRecvBufferSize(); + + void Clear(); + void ClearRecvBuffer(); + + void Process(); + + bool Connect(const CNetworkAddress& c_rkNetAddr, int limitSec = 3); + bool Connect(const char* c_szAddr, int port, int limitSec = 3); + bool Connect(DWORD dwAddr, int port, int limitSec = 3); + void Disconnect(); + + bool Peek(int len); + bool Peek(int len, char* pDestBuf); + bool Recv(int len); + bool Recv(int len, char* pDestBuf); + bool Send(int len, const char* pSrcBuf); + + bool Peek(int len, void* pDestBuf); + bool Recv(int len, void* pDestBuf); + + bool Send(int len, const void* pSrcBuf); + bool SendFlush(int len, const void* pSrcBuf); + + bool IsOnline(); + + void SetPacketSequenceMode(bool isOn); + bool SendSequence(); + + protected: + virtual void OnConnectSuccess(); + virtual void OnConnectFailure(); + virtual void OnRemoteDisconnect(); + virtual void OnDisconnect(); + virtual bool OnProcess(); + + bool __SendInternalBuffer(); + bool __RecvInternalBuffer(); + + void __PopSendBuffer(); + + int __GetSendBufferSize(); + +#ifdef _IMPROVED_PACKET_ENCRYPTION_ + size_t Prepare(void* buffer, size_t* length); + bool Activate(size_t agreed_length, const void* buffer, size_t length); + void ActivateCipher(); +#endif + + private: + time_t m_connectLimitTime; + + char* m_recvTEABuf; + int m_recvTEABufInputPos; + int m_recvTEABufSize; + + char* m_recvBuf; + int m_recvBufSize; + int m_recvBufInputPos; + int m_recvBufOutputPos; + + char* m_sendBuf; + int m_sendBufSize; + int m_sendBufInputPos; + int m_sendBufOutputPos; + + char* m_sendTEABuf; + int m_sendTEABufSize; + int m_sendTEABufInputPos; + + bool m_isOnline; + +#ifdef _IMPROVED_PACKET_ENCRYPTION_ + Cipher m_cipher; +#else + // Obsolete encryption stuff here + bool m_isSecurityMode; + char m_szEncryptKey[TEA_KEY_LENGTH]; // Client Ŷ Encrypt Ҷ ϴ Key + char m_szDecryptKey[TEA_KEY_LENGTH]; // Server ۵ Ŷ Decrypt Ҷ ϴ Key +#endif + + SOCKET m_sock; + + CNetworkAddress m_addr; + + // Sequence + DWORD m_iSequence; + bool m_bUseSequence; + std::vector m_kVec_bSequenceTable; +}; diff --git a/source/EterLib/PathStack.cpp b/source/EterLib/PathStack.cpp new file mode 100644 index 0000000..e3b6d78 --- /dev/null +++ b/source/EterLib/PathStack.cpp @@ -0,0 +1,59 @@ +#include "StdAfx.h" +#include "PathStack.h" + +CPathStack::CPathStack() +{ + SetBase(); +} + +CPathStack::~CPathStack() +{ + MoveBase(); +} + +void CPathStack::GetCurrentPathName(std::string* pstCurPathName) +{ + assert(pstCurPathName!=NULL); + + char szPathName[MAX_PATH+1]; + _getcwd(szPathName, MAX_PATH); + + *pstCurPathName = szPathName; +} + +void CPathStack::Push() +{ + char szPathName[MAX_PATH+1]; + _getcwd(szPathName, MAX_PATH); + + m_stPathNameDeque.push_front(szPathName); +} + +bool CPathStack::Pop() +{ + if (m_stPathNameDeque.empty()) + { + assert(!"CPathStack::Pop Empty Stack"); + return false; + } + + _chdir(m_stPathNameDeque.front().c_str()); + m_stPathNameDeque.pop_front(); + return true; +} + + +void CPathStack::MoveBase() +{ + _chdir(m_stBasePathName.c_str()); +} + +void CPathStack::SetBase() +{ + GetCurrentPathName(&m_stBasePathName); +} + +void CPathStack::Move(const char* c_szPathName) +{ + _chdir(c_szPathName); +} diff --git a/source/EterLib/PathStack.h b/source/EterLib/PathStack.h new file mode 100644 index 0000000..899e95a --- /dev/null +++ b/source/EterLib/PathStack.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include + +class CPathStack +{ + public: + CPathStack(); + virtual ~CPathStack(); + + void SetBase(); + + void MoveBase(); + + void Push(); + + bool Pop(); + + void Move(const char* c_szPathName); + void GetCurrentPathName(std::string* pstCurPathName); + + protected: + std::string m_stBasePathName; + std::deque m_stPathNameDeque; +}; diff --git a/source/EterLib/Pool.h b/source/EterLib/Pool.h new file mode 100644 index 0000000..e54e675 --- /dev/null +++ b/source/EterLib/Pool.h @@ -0,0 +1,684 @@ +#pragma once + +#include "../eterBase/Debug.h" + +//#define DYNAMIC_POOL_STRICT + +template +class CDynamicPool +{ + public: + CDynamicPool() + { + //Tracen(typeid(T).name()); + m_uInitCapacity=0; + m_uUsedCapacity=0; + } + virtual ~CDynamicPool() + { + assert(m_kVct_pkData.empty()); +//#ifdef _DEBUG +// char szText[256]; +// sprintf(szText, "--------------------------------------------------------------------- %s Pool Capacity %d\n", typeid(T).name(), m_uUsedCapacity); +// OutputDebugString(szText); +// printf(szText); +//#endif + } + + void SetName(const char* c_szName) + { + } + + void Clear() + { + Destroy(); + } + + void Destroy() + { +/* +#ifdef _DEBUG + if (!m_kVct_pkData.empty()) + { + char szText[256]; + sprintf(szText, "--------------------------------------------------------------------- %s Pool Destroy\n", typeid(T).name()); + OutputDebugString(szText); + printf(szText); + } +#endif +*/ + for (auto v : m_kVct_pkData) + Delete(v); + m_kVct_pkData.clear(); + m_kVct_pkFree.clear(); + } + + void Create(UINT uCapacity) + { + m_uInitCapacity=uCapacity; + m_kVct_pkData.reserve(uCapacity); + m_kVct_pkFree.reserve(uCapacity); + } + T* Alloc() + { + if (m_kVct_pkFree.empty()) + { + T* pkNewData=new T; + m_kVct_pkData.push_back(pkNewData); + ++m_uUsedCapacity; + return pkNewData; + } + + T* pkFreeData=m_kVct_pkFree.back(); + m_kVct_pkFree.pop_back(); + return pkFreeData; + } + void Free(T* pkData) + { +#ifdef DYNAMIC_POOL_STRICT + assert(__IsValidData(pkData)); + assert(!__IsFreeData(pkData)); +#endif + m_kVct_pkFree.push_back(pkData); + } + void FreeAll() + { + m_kVct_pkFree=m_kVct_pkData; + } + + DWORD GetCapacity() + { + return m_kVct_pkData.size(); + } + + protected: + bool __IsValidData(T* pkData) + { + if (m_kVct_pkData.end()==std::find(m_kVct_pkData.begin(), m_kVct_pkData.end(), pkData)) + return false; + return true; + } + bool __IsFreeData(T* pkData) + { + if (m_kVct_pkFree.end()==std::find(m_kVct_pkFree.begin(), m_kVct_pkFree.end(), pkData)) + return false; + + return true; + } + + static void Delete(T* pkData) + { + delete pkData; + } + + protected: + std::vector m_kVct_pkData; + std::vector m_kVct_pkFree; + + UINT m_uInitCapacity; + UINT m_uUsedCapacity; +}; + + +template +class CDynamicPoolEx +{ + public: + CDynamicPoolEx() + { + m_uInitCapacity=0; + m_uUsedCapacity=0; + } + virtual ~CDynamicPoolEx() + { + assert(m_kVct_pkFree.size()==m_kVct_pkData.size()); + Destroy(); + +#ifdef _DEBUG + char szText[256]; + sprintf(szText, "--------------------------------------------------------------------- %s Pool Capacity %d\n", typeid(T).name(), m_uUsedCapacity); + OutputDebugString(szText); + printf(szText); +#endif + } + + void Clear() + { + Destroy(); + } + + void Destroy() + { +#ifdef _DEBUG + if (!m_kVct_pkData.empty()) + { + char szText[256]; + sprintf(szText, "--------------------------------------------------------------------- %s Pool Destroy\n", typeid(T).name()); + OutputDebugString(szText); + printf(szText); + } +#endif + for (auto v : m_kVct_pkData) + Delete(v); + m_kVct_pkData.clear(); + m_kVct_pkFree.clear(); + } + + void Create(UINT uCapacity) + { + m_uInitCapacity=uCapacity; + m_kVct_pkData.reserve(uCapacity); + m_kVct_pkFree.reserve(uCapacity); + } + T* Alloc() + { + if (m_kVct_pkFree.empty()) + { + T* pkNewData=New(); + m_kVct_pkData.push_back(pkNewData); + ++m_uUsedCapacity; + return pkNewData; + } + + T* pkFreeData=m_kVct_pkFree.back(); + m_kVct_pkFree.pop_back(); + return pkFreeData; + } + void Free(T* pkData) + { +#ifdef DYNAMIC_POOL_STRICT + assert(__IsValidData(pkData)); + assert(!__IsFreeData(pkData)); +#endif + m_kVct_pkFree.push_back(pkData); + } + void FreeAll() + { + m_kVct_pkFree=m_kVct_pkData; + } + + DWORD GetCapacity() + { + return m_kVct_pkData.size(); + } + + protected: + bool __IsValidData(T* pkData) + { + if (m_kVct_pkData.end()==std::find(m_kVct_pkData.begin(), m_kVct_pkData.end(), pkData)) + return false; + return true; + } + bool __IsFreeData(T* pkData) + { + if (m_kVct_pkFree.end()==std::find(m_kVct_pkFree.begin(), m_kVct_pkFree.end(), pkData)) + return false; + + return true; + } + + static T* New() + { + return (T*)::operator new(sizeof(T)); + } + static void Delete(T* pkData) + { + ::operator delete(pkData); + } + + protected: + std::vector m_kVct_pkData; + std::vector m_kVct_pkFree; + + UINT m_uInitCapacity; + UINT m_uUsedCapacity; + +}; + +template +class CPooledObject +{ + public: + CPooledObject() + { + } + virtual ~CPooledObject() + { + } + + void * operator new(unsigned int /*mem_size*/) + { + return ms_kPool.Alloc(); + } + + void operator delete(void* pT) + { + ms_kPool.Free((T*)pT); + } + + + static void DestroySystem() + { + ms_kPool.Destroy(); + } + + static void DeleteAll() + { + ms_kPool.FreeAll(); + } + + protected: + static CDynamicPoolEx ms_kPool; +}; + +template CDynamicPoolEx CPooledObject::ms_kPool; + +/* + +template +class CDynamicSizePool +{ +#define GETPREVP(p) *(T**)((char*)p+sizeof(T)) +#define GETNEXTP(p) *(T**)((char*)p+sizeof(T)+sizeof(T*)) + public: + CDynamicSizePool() + { + Initialize(); + } + + virtual ~CDynamicSizePool() + { + Clear(); + } + + void Initialize() + { + m_nodes = NULL; + m_nodeCount = 0; + + m_pFreeList = NULL; + m_pUsedList = NULL; + } + + void SetName(const char* c_szName) + { + m_stName = c_szName; + } + + T* Alloc() + { + void* pnewNode; + + if (m_pFreeList) + { + pnewNode = m_pFreeList; + m_pFreeList = GETNEXTP(m_pFreeList); + } + else + { + pnewNode = AllocNode(); + } + + if (!pnewNode) + return NULL; + + if (!m_pUsedList) + { + m_pUsedList = pnewNode; + GETPREVP(m_pUsedList) = NULL; + GETNEXTP(m_pUsedList) = NULL; + } + else + { + GETPREVP(m_pUsedList) = (T*) pnewNode; + GETNEXTP(pnewNode) = (T*) m_pUsedList; + GETPREVP(pnewNode) = NULL; + m_pUsedList = pnewNode; + } + //Tracef("%s Pool Alloc %p\n", m_stName.c_str(), pnewNode); + return (T*) pnewNode; + } + + void Free(T * pdata) + { + void* pfreeNode = (void*) pdata; + + if (pfreeNode == m_pUsedList) + { + if (NULL != (m_pUsedList = GETNEXTP(m_pUsedList))) + GETPREVP(m_pUsedList) = NULL; + } + else + { + if (GETNEXTP(pfreeNode)) + GETPREVP(GETNEXTP(pfreeNode)) = GETPREVP(pfreeNode); + + if (GETPREVP(pfreeNode)) + GETNEXTP(GETPREVP(pfreeNode)) = GETNEXTP(pfreeNode); + } + + GETPREVP(pfreeNode) = NULL; + GETNEXTP(pfreeNode) = (T*)m_pFreeList; + m_pFreeList = pfreeNode; + //Tracef("%s Pool Free\n", m_stName.c_str()); + } + + void FreeAll() + { + void * pcurNode; + void * pnextNode; + + pcurNode = m_pUsedList; + + while (pcurNode) + { + pnextNode = GETNEXTP(pcurNode); + Free(pcurNode); + pcurNode = pnextNode; + } + } + + void Clear() + { + void* pcurNode; + void* pnextNode; + int count = 0; + + pcurNode = m_pFreeList; + while (pcurNode) + { + pnextNode = GETNEXTP(pcurNode); + ((T*)pcurNode)->~T(); + ::operator delete(pcurNode); + pcurNode = pnextNode; + ++count; + } + m_pFreeList = NULL; + + pcurNode = m_pUsedList; + while (pcurNode) + { + pnextNode = GETNEXTP(pcurNode); + ((T*)pcurNode)->~T(); + ::operator delete(pcurNode); + pcurNode = pnextNode; + ++count; + } + m_pUsedList = NULL; + //Tracef("%s Pool Clear %d\n", m_stName.c_str(), count); + } + + protected: + void* AllocNode() + { + return ::operator new(sizeof(T)+sizeof(T*)*2); + } + + protected: + void * m_nodes; + void * m_pFreeList; + void * m_pUsedList; + + int m_nodeCount; + std::string m_stName; +#undef GETNEXTP +#undef GETPREVP + +}; + +template +class CPooledObject +{ + public: + CPooledObject() + { + } + virtual ~CPooledObject() + { + } + + void * operator new(unsigned int mem_size) + { + return ms_DynamicSizePool.Alloc(); + } + + void operator delete(void* pT) + { + ms_DynamicSizePool.Free((T*)pT); + } + + static void SetPoolName(const char* szPoolName) + { + ms_DynamicSizePool.SetName(szPoolName); + } + + static void ClearPool() + { + ms_DynamicSizePool.Clear(); + } + + static void FreePool() + { + ms_DynamicSizePool.FreeAll(); + } + + protected: + static CDynamicSizePool ms_DynamicSizePool; +}; + +template CDynamicSizePool CPooledObject::ms_DynamicSizePool; +*/ + +/* +template +class CPoolNode : public T +{ + public: + CPoolNode() + { + m_pNext = NULL; + m_pPrev = NULL; + } + + virtual ~CPoolNode() + { + } + + public: + CPoolNode * m_pNext; + CPoolNode * m_pPrev; +}; + +template +class CDynamicPool +{ + public: + typedef CPoolNode TNode; + + public: + CDynamicPool() + { + Initialize(); + } + + virtual ~CDynamicPool() + { + assert(m_pFreeList==NULL && "CDynamicPool::~CDynamicPool() - NOT Clear"); + assert(m_pUsedList==NULL && "CDynamicPool::~CDynamicPool() - NOT Clear"); + Clear(); + } + + void Initialize() + { + m_nodes = NULL; + m_nodeCount = 0; + + m_pFreeList = NULL; + m_pUsedList = NULL; + } + + void SetName(const char* c_szName) + { + m_stName = c_szName; + } + + DWORD GetCapacity() + { + return m_nodeCount; + } + + T* Alloc() + { + TNode* pnewNode; + + if (m_pFreeList) + { + pnewNode = m_pFreeList; + m_pFreeList = m_pFreeList->m_pNext; + } + else + { + pnewNode = AllocNode(); + } + + if (!pnewNode) + return NULL; + + if (!m_pUsedList) + { + m_pUsedList = pnewNode; + m_pUsedList->m_pPrev = m_pUsedList->m_pNext = NULL; + } + else + { + m_pUsedList->m_pPrev = pnewNode; + pnewNode->m_pNext = m_pUsedList; + pnewNode->m_pPrev = NULL; + m_pUsedList = pnewNode; + } + //Tracef("%s Pool Alloc %p\n", m_stName.c_str(), pnewNode); + return (T*) pnewNode; + } + + bool IsUsedData(T* pdata) + { + TNode* pchkNode=(TNode*)pdata; + TNode* pcurNode = m_pUsedList; + while (pcurNode) + { + if (pcurNode==pdata) + return true; + + pcurNode = pcurNode->m_pNext; + } + return false; + } + + bool IsFreeData(T* pdata) + { + TNode* pchkNode=(TNode*)pdata; + TNode* pcurNode = m_pFreeList; + while (pcurNode) + { + if (pcurNode==pdata) + return true; + + pcurNode = pcurNode->m_pNext; + } + return false; + } + + void Free(T * pdata) + { + assert(IsUsedData(pdata)); + assert(!IsFreeData(pdata)); + + TNode* pfreeNode = (TNode*) pdata; + + if (pfreeNode == m_pUsedList) + { + m_pUsedList = m_pUsedList->m_pNext; + if (NULL != m_pUsedList) + m_pUsedList->m_pPrev = NULL; + } + else + { + if (pfreeNode->m_pNext) + pfreeNode->m_pNext->m_pPrev = pfreeNode->m_pPrev; + + if (pfreeNode->m_pPrev) + pfreeNode->m_pPrev->m_pNext = pfreeNode->m_pNext; + } + + pfreeNode->m_pPrev = NULL; + pfreeNode->m_pNext = m_pFreeList; + m_pFreeList = pfreeNode; + //Tracef("%s Pool Free\n", m_stName.c_str()); + } + + void FreeAll() + { + TNode * pcurNode; + TNode * pnextNode; + + pcurNode = m_pUsedList; + + while (pcurNode) + { + pnextNode = pcurNode->m_pNext; + Free(pcurNode); + pcurNode = pnextNode; + } + + assert(NULL==m_pUsedList); + } + + void Clear() + { + TNode* pcurNode; + TNode* pnextNode; + + DWORD count = 0; + + pcurNode = m_pFreeList; + while (pcurNode) + { + pnextNode = pcurNode->m_pNext; + delete pcurNode; + pcurNode = pnextNode; + ++count; + } + m_pFreeList = NULL; + + pcurNode = m_pUsedList; + while (pcurNode) + { + pnextNode = pcurNode->m_pNext; + delete pcurNode; + pcurNode = pnextNode; + ++count; + } + + m_pUsedList = NULL; + + assert(count==m_nodeCount && "CDynamicPool::Clear()"); + + m_nodeCount=0; + } + + protected: + TNode* AllocNode() + { + ++m_nodeCount; + return new TNode; + } + + protected: + TNode * m_nodes; + TNode * m_pFreeList; + TNode * m_pUsedList; + + DWORD m_nodeCount; + std::string m_stName; +}; +*/ \ No newline at end of file diff --git a/source/EterLib/Profiler.h b/source/EterLib/Profiler.h new file mode 100644 index 0000000..a9cc7a7 --- /dev/null +++ b/source/EterLib/Profiler.h @@ -0,0 +1,264 @@ +#pragma once + +#include "../eterBase/Timer.h" +#include "../eterBase/Debug.h" + +/* +class CProfiler : public CSingleton +{ + public: + enum + { + STACK_DATA_MAX_NUM = 64, + }; + + public: + typedef struct SProfileStackData + { + int iCallStep; + long iStartTime; + long iEndTime; + + std::string strName; + } TProfileStackData; + typedef struct SProfileAccumulationData + { + int iStartTime; + int iCallingCount; + int iCollapsedTime; + + std::string strName; + } TProfileAccumulationData; + + typedef std::map TGraphicTextInstanceMap; + typedef std::map TProfileAccumulationDataMap; + + public: + CProfiler() + { + Clear(); + m_ProfileAccumulationDataMap.clear(); + } + virtual ~CProfiler() + { + } + + void Clear() + { + m_ProfileStackDataCount = 0; + m_iCallStep = 0; + + TProfileAccumulationDataMap::iterator itor = m_ProfileAccumulationDataMap.begin(); + for (; itor != m_ProfileAccumulationDataMap.end(); ++itor) + { + TProfileAccumulationData & rData = itor->second; + rData.iCallingCount = 0; + rData.iCollapsedTime = 0; + } + } + + void Push(const char * c_szName) + { + assert(m_ProfileStackDataCount < STACK_DATA_MAX_NUM); + TProfileStackData & rProfileStackData = m_ProfileStackDatas[m_ProfileStackDataCount++]; + + rProfileStackData.iCallStep = m_iCallStep; + rProfileStackData.iStartTime = ELTimer_GetMSec(); + rProfileStackData.strName = c_szName; + + ++m_iCallStep; + + TGraphicTextInstanceMap::iterator itor = m_GraphicTextInstanceMap.find(c_szName); + + if (m_GraphicTextInstanceMap.end() == itor) + { + CGraphicTextInstance * pGraphicTextInstance = CGraphicTextInstance::New(); + + CResource * pResource = CResourceManager::Instance().GetResourcePointer("ü.fnt"); + pGraphicTextInstance->Clear(); + pGraphicTextInstance->SetTextPointer(static_cast(pResource)); + + m_GraphicTextInstanceMap.insert(TGraphicTextInstanceMap::value_type(c_szName, pGraphicTextInstance)); + } + } + void Pop(const char * c_szName) + { + TProfileStackData * pProfileStackData; + + if (!GetProfileStackDataPointer(c_szName, &pProfileStackData)) + { + assert(!"The name doesn't exist"); + return; + } + + pProfileStackData->iEndTime = ELTimer_GetMSec(); + + --m_iCallStep; + } + + void PushAccumulation(const char * c_szName) + { + TProfileAccumulationDataMap::iterator itor = m_ProfileAccumulationDataMap.find(c_szName); + + if (itor == m_ProfileAccumulationDataMap.end()) + { + TProfileAccumulationData ProfileAccumulationData; + ProfileAccumulationData.iCollapsedTime = 0; + ProfileAccumulationData.iCallingCount = 0; + ProfileAccumulationData.strName = c_szName; + m_ProfileAccumulationDataMap.insert(TProfileAccumulationDataMap::value_type(c_szName, ProfileAccumulationData)); + + itor = m_ProfileAccumulationDataMap.find(c_szName); + + ///// + + CGraphicTextInstance * pGraphicTextInstance = m_GraphicTextInstancePool.Alloc(); + + CResource * pResource = CResourceManager::Instance().GetResourcePointer("ü.fnt"); + pGraphicTextInstance->Clear(); + pGraphicTextInstance->SetTextPointer(static_cast(pResource)); + + m_GraphicTextInstanceMap.insert(TGraphicTextInstanceMap::value_type(c_szName, pGraphicTextInstance)); + } + + TProfileAccumulationData & rData = itor->second; + rData.iStartTime = ELTimer_GetMSec(); + } + + void PopAccumulation(const char * c_szName) + { + TProfileAccumulationDataMap::iterator itor = m_ProfileAccumulationDataMap.find(c_szName); + + if (itor == m_ProfileAccumulationDataMap.end()) + return; + + TProfileAccumulationData & rData = itor->second; + rData.iCollapsedTime += ELTimer_GetMSec() - rData.iStartTime; + ++rData.iCallingCount; + } + + void ProfileByConsole() + { + for (int i = 0; i < m_ProfileStackDataCount; ++i) + { + TProfileStackData & rProfileStackData = m_ProfileStackDatas[i]; + +// for (int i = 0; i < rProfileStackData.iCallStep; ++i) +// Tracef("\t"); + + Tracef("%-10s: %2d\t", rProfileStackData.strName.c_str(), rProfileStackData.iEndTime - rProfileStackData.iStartTime); + } + Tracef("\n"); + } + + void ProfileOneStackDataByConsole(const char * c_szName) + { + TProfileStackData * pProfileStackData; + + if (!GetProfileStackDataPointer(c_szName, &pProfileStackData)) + { + return; + } + + Tracef("%-10s: %3d\n", pProfileStackData->strName.c_str(), pProfileStackData->iEndTime - pProfileStackData->iStartTime); + } + + void ProfileOneAccumulationDataByConsole(const char * c_szName) + { + TProfileAccumulationDataMap::iterator itor = m_ProfileAccumulationDataMap.find(c_szName); + if (itor == m_ProfileAccumulationDataMap.end()) + return; + + TProfileAccumulationData & rData = itor->second; + Tracef("%-10s : [CollapsedTime : %3d] / [CallingCount : %3d]\n", rData.strName.c_str(), + rData.iCollapsedTime, + rData.iCallingCount); + } + + void ProfileByScreen() + { + float fxPosition = 0; + float fyPosition = 10; + + char szText[128]; + + for (int i = 0; i < m_ProfileStackDataCount; ++i) + { + TProfileStackData & rProfileStackData = m_ProfileStackDatas[i]; + + TGraphicTextInstanceMap::iterator itor = m_GraphicTextInstanceMap.find(rProfileStackData.strName); + + if (m_GraphicTextInstanceMap.end() != itor) + { + CGraphicTextInstance * pGraphicTextInstance = itor->second; + + fxPosition = 10 + (float) rProfileStackData.iCallStep * 10 * 4; + + sprintf(szText, "%-10s : %3d", rProfileStackData.strName.c_str(), rProfileStackData.iEndTime - rProfileStackData.iStartTime); + + pGraphicTextInstance->SetColor(0.7f, 0.7f, 0.7f); + pGraphicTextInstance->SetValue(szText, strlen(szText)); + pGraphicTextInstance->SetPosition(fxPosition, fyPosition); + pGraphicTextInstance->Update(); + pGraphicTextInstance->Render(); + + fyPosition += 17; + } + } + + fxPosition = 10; + fyPosition += 10; + TProfileAccumulationDataMap::iterator itor = m_ProfileAccumulationDataMap.begin(); + for (; itor != m_ProfileAccumulationDataMap.end(); ++itor) + { + TProfileAccumulationData & rData = itor->second; + TGraphicTextInstanceMap::iterator itor = m_GraphicTextInstanceMap.find(rData.strName); + + if (m_GraphicTextInstanceMap.end() != itor) + { + CGraphicTextInstance * pGraphicTextInstance = itor->second; + + sprintf(szText, "%-10s : [CollapsedTime : %3d] / [CallingCount : %3d]", rData.strName.c_str(), + rData.iCollapsedTime, + rData.iCallingCount); + + pGraphicTextInstance->SetColor(0.7f, 0.7f, 0.7f); + pGraphicTextInstance->SetValue(szText, strlen(szText)); + pGraphicTextInstance->SetPosition(fxPosition, fyPosition); + pGraphicTextInstance->Update(); + pGraphicTextInstance->Render(); + + fyPosition += 17; + } + } + } + + protected: + bool GetProfileStackDataPointer(const char * c_szName, TProfileStackData ** ppProfileStackData) + { + for (int i = 0; i < m_ProfileStackDataCount; ++i) + { + if (0 == m_ProfileStackDatas[i].strName.compare(c_szName)) + { + *ppProfileStackData = &m_ProfileStackDatas[i]; + + return true; + } + } + + return false; + } + + protected: + // Profile Stack Data + int m_ProfileStackDataCount; + TProfileStackData m_ProfileStackDatas[STACK_DATA_MAX_NUM]; + + // Profile Increase Data + TProfileAccumulationDataMap m_ProfileAccumulationDataMap; + + int m_iCallStep; + + TGraphicTextInstanceMap m_GraphicTextInstanceMap; +}; +*/ \ No newline at end of file diff --git a/source/EterLib/Ray.h b/source/EterLib/Ray.h new file mode 100644 index 0000000..6319b42 --- /dev/null +++ b/source/EterLib/Ray.h @@ -0,0 +1,65 @@ +#pragma once + +#include + +class CRay +{ + public: + CRay(const D3DXVECTOR3 & v3Start, const D3DXVECTOR3 & v3Dir, float fRayRange) : m_v3Start(v3Start), m_v3Direction(v3Dir) + { + assert(fRayRange >= 0); + m_fRayRange = fRayRange; + D3DXVec3Normalize(&m_v3Direction, &m_v3Direction); + m_v3End = m_v3Start + fRayRange * m_v3Direction; + } + + CRay() + { + } + + void SetStartPoint(const D3DXVECTOR3 & v3Start) + { + m_v3Start = v3Start; + } + + void SetDirection(const D3DXVECTOR3 & v3Dir, float fRayRange) + { + assert(fRayRange >= 0); + m_v3Direction = v3Dir; + D3DXVec3Normalize(&m_v3Direction, &m_v3Direction); + m_fRayRange = fRayRange; + m_v3End = m_v3Start + m_fRayRange * m_v3Direction; + } + + void GetStartPoint(D3DXVECTOR3 * pv3Start) const + { + *pv3Start = m_v3Start; + } + + void GetDirection(D3DXVECTOR3 * pv3Dir, float * pfRayRange) const + { + *pv3Dir = m_v3Direction; + *pfRayRange = m_fRayRange; + } + + void GetEndPoint(D3DXVECTOR3 * pv3End) const + { + *pv3End = m_v3End; + } + + const CRay & operator = (const CRay & rhs) + { + assert(rhs.m_fRayRange >= 0); + m_v3Start = rhs.m_v3Start; + m_v3Direction = rhs.m_v3Direction; + m_fRayRange = rhs.m_fRayRange; + D3DXVec3Normalize(&m_v3Direction, &m_v3Direction); + m_v3End = m_v3Start + m_fRayRange * m_v3Direction; + } + + private: + D3DXVECTOR3 m_v3Start; + D3DXVECTOR3 m_v3End; + D3DXVECTOR3 m_v3Direction; + float m_fRayRange; +}; diff --git a/source/EterLib/Ref.h b/source/EterLib/Ref.h new file mode 100644 index 0000000..01d0ecc --- /dev/null +++ b/source/EterLib/Ref.h @@ -0,0 +1,104 @@ +#ifndef __INC_REF_H__ +#define __INC_REF_H__ + +#include "ReferenceObject.h" + +#include + +template class CRef +{ + public: + struct FClear + { + void operator() (CRef& rRef) + { + rRef.Clear(); + } + }; + + public: + CRef() : m_pObject(NULL) + { + } + + CRef(CReferenceObject* pObject) + { + m_pObject = NULL; + Initialize(pObject); + } + + CRef(const CRef& c_rRef) + { + m_pObject = NULL; + Initialize(c_rRef.m_pObject); + } + + ~CRef() + { + Clear(); + } + + void operator = (CReferenceObject* pObject) + { + SetPointer(pObject); + } + + void operator = (const CRef& c_rRef) + { + SetPointer(c_rRef.m_pObject); + } + + void Clear() + { + if (m_pObject) + { + m_pObject->Release(); + m_pObject = NULL; + } + } + + bool IsNull() const + { + return m_pObject == NULL ? true : false; + } + + void SetPointer(CReferenceObject* pObject) + { + CReferenceObject* pOldObject = m_pObject; + + m_pObject = pObject; + + if (m_pObject) + m_pObject->AddReference(); + + if (pOldObject) + pOldObject->Release(); + } + + T* GetPointer() const + { + return static_cast(m_pObject); + } + + T* operator->() const + { + assert(m_pObject != NULL); + return static_cast(m_pObject); + } + + private: + void Initialize(CReferenceObject* pObject) + { + assert(m_pObject == NULL); + + m_pObject = pObject; + + if (m_pObject) + m_pObject->AddReference(); + } + + private: + CReferenceObject* m_pObject; +}; + +#endif diff --git a/source/EterLib/ReferenceObject.cpp b/source/EterLib/ReferenceObject.cpp new file mode 100644 index 0000000..356819a --- /dev/null +++ b/source/EterLib/ReferenceObject.cpp @@ -0,0 +1,61 @@ +#include "StdAfx.h" +#include "ReferenceObject.h" + +CReferenceObject::CReferenceObject() : m_refCount(0), m_destructed(false) +{ +} + +CReferenceObject::~CReferenceObject() +{ +} + +void CReferenceObject::AddReference() +{ + if (m_refCount == 0) + OnConstruct(); + + ++m_refCount; +} + +int CReferenceObject::GetReferenceCount() +{ + return m_refCount; +} + +void CReferenceObject::AddReferenceOnly() +{ + ++m_refCount; +} + +void CReferenceObject::Release() +{ + if (m_refCount > 1) + { + --m_refCount; + return; + } + + assert(m_destructed == false); + assert(m_refCount >= 0); + m_refCount = 0; + OnSelfDestruct(); +} + +void CReferenceObject::OnConstruct() +{ + m_destructed = false; +} + +void CReferenceObject::OnSelfDestruct() +{ + m_destructed = true; + delete this; +} + +bool CReferenceObject::canDestroy() +{ + if (m_refCount > 0) + return false; + + return true; +} diff --git a/source/EterLib/ReferenceObject.h b/source/EterLib/ReferenceObject.h new file mode 100644 index 0000000..0e25353 --- /dev/null +++ b/source/EterLib/ReferenceObject.h @@ -0,0 +1,24 @@ +#pragma once + +class CReferenceObject +{ + public: + CReferenceObject(); + virtual ~CReferenceObject(); + + void AddReference(); + void AddReferenceOnly(); + void Release(); + + int GetReferenceCount(); + + bool canDestroy(); + + protected: + virtual void OnConstruct(); + virtual void OnSelfDestruct(); + + private: + int m_refCount; + bool m_destructed; +}; diff --git a/source/EterLib/Resource.cpp b/source/EterLib/Resource.cpp new file mode 100644 index 0000000..1dbe7d0 --- /dev/null +++ b/source/EterLib/Resource.cpp @@ -0,0 +1,181 @@ +#include "StdAfx.h" +#include "../eterPack/EterPackManager.h" +#include "../eterBase/CRC32.h" +#include "../eterBase/Timer.h" + +#include "Resource.h" +#include "ResourceManager.h" + +bool CResource::ms_bDeleteImmediately = false; + +CResource::CResource(const char* c_szFileName) : me_state(STATE_EMPTY) +{ + SetFileName(c_szFileName); +} + +CResource::~CResource() +{ +} + +void CResource::SetDeleteImmediately(bool isSet) +{ + ms_bDeleteImmediately = isSet; +} + +void CResource::OnConstruct() +{ + Load(); +} + +void CResource::OnSelfDestruct() +{ + if (ms_bDeleteImmediately) + Clear(); + else + CResourceManager::Instance().ReserveDeletingResource(this); +} + +void CResource::Load() +{ + if (me_state != STATE_EMPTY) + return; + + const char * c_szFileName = GetFileName(); + + DWORD dwStart = ELTimer_GetMSec(); + CMappedFile file; + LPCVOID fileData; + + //Tracenf("Load %s", c_szFileName); + + if (CEterPackManager::Instance().Get(file, c_szFileName, &fileData)) + { + m_dwLoadCostMiliiSecond = ELTimer_GetMSec() - dwStart; + //Tracef("CResource::Load %s (%d bytes) in %d ms\n", c_szFileName, file.Size(), m_dwLoadCostMiliiSecond); + + if (OnLoad(file.Size(), fileData)) + { + me_state = STATE_EXIST; + } + else + { + Tracef("CResource::Load Error %s\n", c_szFileName); + me_state = STATE_ERROR; + return; + } + } + else + { + if (OnLoad(0, NULL)) + me_state = STATE_EXIST; + else + { + Tracef("CResource::Load file not exist %s\n", c_szFileName); + me_state = STATE_ERROR; + } + } +} + +void CResource::Reload() +{ + Clear(); + Tracef("CResource::Reload %s\n", GetFileName()); + + CMappedFile file; + LPCVOID fileData; + + if (CEterPackManager::Instance().Get(file, GetFileName(), &fileData)) + { + if (OnLoad(file.Size(), fileData)) + { + me_state = STATE_EXIST; + } + else + { + me_state = STATE_ERROR; + return; + } + } + else + { + if (OnLoad(0, NULL)) + me_state = STATE_EXIST; + else + { + me_state = STATE_ERROR; + } + } +} + +CResource::TType CResource::StringToType(const char* c_szType) +{ + return GetCRC32(c_szType, strlen(c_szType)); +} + +int CResource::ConvertPathName(const char * c_szPathName, char * pszRetPathName, int retLen) +{ + const char * pc; + int len = 0; + + for (pc = c_szPathName; *pc && len < retLen; ++pc, ++len) + { + if (*pc == '/') + *(pszRetPathName++) = '\\'; + else + *(pszRetPathName++) = (char) korean_tolower(*pc); + } + + *pszRetPathName = '\0'; + return len; +} + +void CResource::SetFileName(const char* c_szFileName) +{ + // 2004. 2. 1. myevan. 尡 Ǵ Ȳ static ʴ° . + // 2004. 2. 1. myevan. ̸ ó std::string + m_stFileName=c_szFileName; +} + +void CResource::Clear() +{ + OnClear(); + me_state = STATE_EMPTY; +} + +bool CResource::IsType(TType type) +{ + return OnIsType(type); +} + +CResource::TType CResource::Type() +{ + static TType s_type = StringToType("CResource"); + return s_type; +} + +bool CResource::OnIsType(TType type) +{ + if (CResource::Type() == type) + return true; + + return false; +} + +bool CResource::IsData() const +{ + return me_state != STATE_EMPTY; +} + +bool CResource::IsEmpty() const +{ + return OnIsEmpty(); +} + +bool CResource::CreateDeviceObjects() +{ + return true; +} + +void CResource::DestroyDeviceObjects() +{ +} diff --git a/source/EterLib/Resource.h b/source/EterLib/Resource.h new file mode 100644 index 0000000..4a055ce --- /dev/null +++ b/source/EterLib/Resource.h @@ -0,0 +1,69 @@ +#pragma once + +#include "ReferenceObject.h" +#include + +class CResource : public CReferenceObject +{ + public: + typedef DWORD TType; + + enum EState + { + STATE_EMPTY, + STATE_ERROR, + STATE_EXIST, + STATE_LOAD, + STATE_FREE + }; + + public: + void Clear(); + + static TType StringToType(const char* c_szType); + static TType Type(); + + void Load(); + void Reload(); + int ConvertPathName(const char * c_szPathName, char * pszRetPathName, int retLen); + + virtual bool CreateDeviceObjects(); + virtual void DestroyDeviceObjects(); + + public: + CResource(const char* c_szFileName); + virtual ~CResource(); + + static void SetDeleteImmediately(bool isSet = false); + + // is loaded? + bool IsData() const; + bool IsEmpty() const; + bool IsType(TType type); + + DWORD GetLoadCostMilliSecond() { return m_dwLoadCostMiliiSecond; } + //const char * GetFileName() const { return m_pszFileName; } + const char * GetFileName() const { return m_stFileName.c_str(); } + const std::string& GetFileNameString() const { return m_stFileName; } + + virtual bool OnLoad(int iSize, const void * c_pvBuf) = 0; + + protected: + void SetFileName(const char* c_szFileName); + + virtual void OnClear() = 0; + virtual bool OnIsEmpty() const = 0; + virtual bool OnIsType(TType type) = 0; + + virtual void OnConstruct(); + virtual void OnSelfDestruct(); + + protected: + std::string m_stFileName; + //char * m_pszFileName; + DWORD m_dwLoadCostMiliiSecond; + EState me_state; + + protected: + static bool ms_bDeleteImmediately; +}; diff --git a/source/EterLib/ResourceManager.cpp b/source/EterLib/ResourceManager.cpp new file mode 100644 index 0000000..d40dfa9 --- /dev/null +++ b/source/EterLib/ResourceManager.cpp @@ -0,0 +1,525 @@ +#include "StdAfx.h" +#include +#include "../eterBase/CRC32.h" +#include "../eterBase/Timer.h" +#include "../eterBase/Stl.h" +#include "../eterPack/EterPackManager.h" + +#include "ResourceManager.h" +#include "GrpImage.h" + +int g_iLoadingDelayTime = 20; + +const long c_Deleting_Wait_Time = 30000; // ð (30) +const long c_DeletingCountPerFrame = 30; // Ӵ üũ ҽ +const long c_Reference_Decrease_Wait_Time = 30000; // ε ҽ ð (30) + +CFileLoaderThread CResourceManager::ms_loadingThread; + +void CResourceManager::LoadStaticCache(const char* c_szFileName) +{ + CResource* pkRes=GetResourcePointer(c_szFileName); + if (!pkRes) + { + Lognf(1, "CResourceManager::LoadStaticCache %s - FAILED", c_szFileName); + return; + } + + DWORD dwCacheKey=GetCRC32(c_szFileName, strlen(c_szFileName)); + TResourcePointerMap::iterator f=m_pCacheMap.find(dwCacheKey); + if (m_pCacheMap.end()!=f) + return; + + pkRes->AddReference(); + m_pCacheMap.insert(TResourcePointerMap::value_type(dwCacheKey, pkRes)); + +} + +void CResourceManager::ProcessBackgroundLoading() +{ + TResourceRequestMap::iterator itor = m_RequestMap.begin(); + + while (itor != m_RequestMap.end()) + { + DWORD dwFileCRC = itor->first; + std::string & stFileName = itor->second; + + if (isResourcePointerData(dwFileCRC) || + (m_WaitingMap.end() != m_WaitingMap.find(dwFileCRC))) + { + //printf("SKP %s\n", stFileName.c_str()); + itor = m_RequestMap.erase(itor); + continue; + } + + //printf("REQ %s\n", stFileName.c_str()); + ms_loadingThread.Request(stFileName); + m_WaitingMap.insert(TResourceRequestMap::value_type(dwFileCRC, stFileName)); + itor = m_RequestMap.erase(itor); + //break; // NOTE: ⼭ break ϸ õõ ε ȴ. + } + + DWORD dwCurrentTime = ELTimer_GetMSec(); + + CFileLoaderThread::TData * pData; + while (ms_loadingThread.Fetch(&pData)) + { + //printf("LOD %s\n", pData->stFileName.c_str()); + CResource * pResource = GetResourcePointer(pData->stFileName.c_str()); + + if (pResource) + { + if (pResource->IsEmpty()) + { + pResource->OnLoad(pData->dwSize, pData->pvBuf); + pResource->AddReferenceOnly(); + + // ⼭ ö ۷ īƮ ð ڿ Ǯֱ Ͽ + m_pResRefDecreaseWaitingMap.insert(TResourceRefDecreaseWaitingMap::value_type(dwCurrentTime, pResource)); + } + } + + m_WaitingMap.erase(GetCRC32(pData->stFileName.c_str(), pData->stFileName.size())); + + delete [] ((char *) pData->pvBuf); + delete pData; + } + + // DO : ð ̸ ε ξ ҽ ۷ īƮ Ų - [levites] + long lCurrentTime = ELTimer_GetMSec(); + + TResourceRefDecreaseWaitingMap::iterator itorRef = m_pResRefDecreaseWaitingMap.begin(); + + while (itorRef != m_pResRefDecreaseWaitingMap.end()) + { + const long & rCreatingTime = itorRef->first; + + if (lCurrentTime - rCreatingTime > c_Reference_Decrease_Wait_Time) + { + CResource * pResource = itorRef->second; + + // Decrease Reference Count + pResource->Release(); + itorRef = m_pResRefDecreaseWaitingMap.erase(itorRef); + //Tracef("Decrease Pre Loading Resource\n", rCreatingTime); + } + else + ++itorRef; + } +} + +void CResourceManager::PushBackgroundLoadingSet(std::set & LoadingSet) +{ + std::set::iterator itor = LoadingSet.begin(); + + while (itor != LoadingSet.end()) + { + DWORD dwFileCRC = __GetFileCRC(itor->c_str()); + + if (NULL != isResourcePointerData(dwFileCRC)) + { + ++itor; + continue; + } + + m_RequestMap.insert(TResourceRequestMap::value_type(dwFileCRC, itor->c_str())); + ++itor; + } +} + +void CResourceManager::__DestroyCacheMap() +{ + TResourcePointerMap::iterator i; + for (i = m_pCacheMap.begin(); i != m_pCacheMap.end(); ++i) + { + CResource* pResource = i->second; + pResource->Release(); + } + + m_pCacheMap.clear(); +} + +void CResourceManager::__DestroyDeletingResourceMap() +{ + Tracenf("CResourceManager::__DestroyDeletingResourceMap %d", m_ResourceDeletingMap.size()); + for (TResourceDeletingMap::iterator i = m_ResourceDeletingMap.begin(); i != m_ResourceDeletingMap.end(); ++i) + (i->first)->Clear(); + + m_ResourceDeletingMap.clear(); +} + +void CResourceManager::__DestroyResourceMap() +{ + Tracenf("CResourceManager::__DestroyResourceMap %d", m_pResMap.size()); + + TResourcePointerMap::iterator i; + for (i = m_pResMap.begin(); i != m_pResMap.end(); ++i) + { + CResource* pResource = i->second; + pResource->Clear(); + } + + stl_wipe_second(m_pResMap); +} + +void CResourceManager::DestroyDeletingList() +{ + CResource::SetDeleteImmediately(true); + + __DestroyCacheMap(); + __DestroyDeletingResourceMap(); +} + +void CResourceManager::Destroy() +{ + assert(m_ResourceDeletingMap.empty() && "CResourceManager::Destroy - YOU MUST CALL DestroyDeletingList"); + __DestroyResourceMap(); +} + +void CResourceManager::RegisterResourceNewFunctionPointer(const char* c_szFileExt, CResource* (*pNewFunc)(const char* c_szFileName)) +{ + m_pResNewFuncMap[c_szFileExt] = pNewFunc; +} + +void CResourceManager::RegisterResourceNewFunctionByTypePointer(int iType, CResource* (*pNewFunc) (const char* c_szFileName)) +{ + assert(iType >= 0); + m_pResNewFuncByTypeMap[iType] = pNewFunc; +} + +CResource * CResourceManager::InsertResourcePointer(DWORD dwFileCRC, CResource* pResource) +{ + TResourcePointerMap::iterator itor = m_pResMap.find(dwFileCRC); + + if (m_pResMap.end() != itor) + { + TraceError("CResource::InsertResourcePointer: %s is already registered\n", pResource->GetFileName()); + assert(!"CResource::InsertResourcePointer: Resource already resistered"); + delete pResource; + return itor->second; + } + + m_pResMap.insert(TResourcePointerMap::value_type(dwFileCRC, pResource)); + return pResource; +} + + +int __ConvertPathName(const char * c_szPathName, char * pszRetPathName, int retLen) +{ + const char * pc; + int len = 0; + + for (pc = c_szPathName; *pc && len < retLen; ++pc, ++len) + { + if (*pc == '/') + *(pszRetPathName++) = '\\'; + else + *(pszRetPathName++) = (char) korean_tolower(*pc); + } + + *pszRetPathName = '\0'; + return len; +} + +CResource * CResourceManager::GetTypeResourcePointer(const char * c_szFileName, int iType) +{ + if (!c_szFileName || !*c_szFileName) + { + assert(c_szFileName != NULL && *c_szFileName != '\0'); + return NULL; + } + + const char * c_pszFile; + DWORD dwFileCRC = __GetFileCRC(c_szFileName, &c_pszFile); + CResource * pResource = FindResourcePointer(dwFileCRC); + + if (pResource) // ̹ ҽ Ѵ. + return pResource; + + CResource * (*newFunc) (const char *) = NULL; + + if (iType != -1) + { + TResourceNewFunctionByTypePointerMap::iterator f = m_pResNewFuncByTypeMap.find(iType); + + if (m_pResNewFuncByTypeMap.end() != f) + newFunc = f->second; + } + else + { + const char * pcFileExt = strrchr(c_pszFile, '.'); + + if (pcFileExt) + { + static char s_szFileExt[8 + 1]; + strncpy(s_szFileExt, pcFileExt + 1, 8); + + TResourceNewFunctionPointerMap::iterator f = m_pResNewFuncMap.find(s_szFileExt); + + if (m_pResNewFuncMap.end() != f) + newFunc = f->second; + } + } + + if (!newFunc) + { + TraceError("ResourceManager::GetResourcePointer: NOT SUPPORT FILE %s", c_pszFile); + return NULL; + } + + pResource = InsertResourcePointer(dwFileCRC, newFunc(c_pszFile)); + return pResource; +} + +CResource * CResourceManager::GetResourcePointer(const char * c_szFileName) +{ + if (!c_szFileName || !*c_szFileName) + { + TraceError("CResourceManager::GetResourcePointer: filename error!"); + return NULL; + } + + const char * c_pszFile; + DWORD dwFileCRC = __GetFileCRC(c_szFileName, &c_pszFile); + CResource * pResource = FindResourcePointer(dwFileCRC); + + if (pResource) // ̹ ҽ Ѵ. + return pResource; + + const char * pcFileExt = strrchr(c_pszFile, '.'); + +#ifdef _DEBUG + if (!IsFileExist(c_szFileName) ) + { + if( pcFileExt == NULL || (stricmp( pcFileExt, ".fnt" ) != 0) ) { + TraceError("CResourceManager::GetResourcePointer: File not exist %s", c_szFileName); + } + } +#endif + + CResource * (*newFunc) (const char *) = NULL; + + if (pcFileExt) + { + static char s_szFileExt[8 + 1]; + strncpy(s_szFileExt, pcFileExt + 1, 8); + + TResourceNewFunctionPointerMap::iterator f = m_pResNewFuncMap.find(s_szFileExt); + + if (m_pResNewFuncMap.end() != f) + newFunc = f->second; + } + + if (!newFunc) + { + TraceError("ResourceManager::GetResourcePointer: NOT SUPPORT FILE %s", c_pszFile); + return NULL; + } + + pResource = InsertResourcePointer(dwFileCRC, newFunc(c_pszFile)); + return pResource; +} + +CResource * CResourceManager::FindResourcePointer(DWORD dwFileCRC) +{ + TResourcePointerMap::iterator itor = m_pResMap.find(dwFileCRC); + + if (m_pResMap.end() == itor) + return NULL; + + return itor->second; +} + +bool CResourceManager::isResourcePointerData(DWORD dwFileCRC) +{ + TResourcePointerMap::iterator itor = m_pResMap.find(dwFileCRC); + + if (m_pResMap.end() == itor) + return NULL; + + return (itor->second)->IsData(); +} + +DWORD CResourceManager::__GetFileCRC(const char * c_szFileName, const char ** c_ppszLowerFileName) +{ + static char s_szFullPathFileName[MAX_PATH]; + const char * src = c_szFileName; + char * dst = s_szFullPathFileName; + int len = 0; + + while (src[len]) + { + if (src[len]=='/') + dst[len] = '\\'; + else + dst[len] = (char) korean_tolower(src[len]); + + ++len; + } + + dst[len] = '\0'; + + if (c_ppszLowerFileName) + *c_ppszLowerFileName = &s_szFullPathFileName[0]; + + return (GetCRC32(s_szFullPathFileName, len)); +} + +typedef struct SDumpData +{ + const char * filename; + float KB; + DWORD cost; +} TDumpData; + +bool DumpKBCompare(const TDumpData& lhs, const TDumpData& rhs) +{ + return (lhs.KB > rhs.KB) ? true : false; +} + +bool DumpCostCompare(const TDumpData& lhs, const TDumpData& rhs) +{ + return (lhs.cost > rhs.cost) ? true : false; +} + +struct FDumpPrint +{ + FILE * m_fp; + static float m_totalKB; + + void operator () (TDumpData & data) + { + m_totalKB += data.KB; + fprintf(m_fp, "%6.1f %s\n", data.KB, data.filename); + } +}; + +float FDumpPrint::m_totalKB; + +struct FDumpCostPrint +{ + FILE * m_fp; + + void operator() (TDumpData & data) + { + fprintf(m_fp, "%-4d %s\n", data.cost, data.filename); + } +}; + +void CResourceManager::DumpFileListToTextFile(const char* c_szFileName) +{ + std::vector dumpVector; + + for (TResourcePointerMap::iterator i = m_pResMap.begin(); i != m_pResMap.end(); ++i) + { + CResource* pResource = i->second; + TDumpData data; + + if (pResource->IsEmpty()) + continue; + + data.filename = pResource->GetFileName(); + + int filesize; + + const char * ext = strrchr(data.filename, '.'); + + if (pResource->IsType(CGraphicImage::Type()) && strnicmp(ext, ".sub", 4)) + filesize = ((CGraphicImage*) pResource)->GetWidth() * ((CGraphicImage*) pResource)->GetHeight() * 4; + else + { + FILE * fp2 = fopen(data.filename, "rb"); + + if (fp2) + { + fseek(fp2, 0L, SEEK_END); + filesize = ftell(fp2); + fclose(fp2); + } + else + filesize = 0; + } + + data.KB = (float) filesize / (float) 1024; + data.cost = pResource->GetLoadCostMilliSecond(); + + dumpVector.push_back(data); + } + + FILE * fp = fopen(c_szFileName, "w"); + + if (fp) + { + std::sort(dumpVector.begin(), dumpVector.end(), DumpKBCompare); + + FDumpPrint DumpPrint; + DumpPrint.m_fp = fp; + DumpPrint.m_totalKB = 0; + + std::for_each(dumpVector.begin(), dumpVector.end(), DumpPrint); + fprintf(fp, "total: %.2fmb", DumpPrint.m_totalKB / 1024.0f); + + FDumpCostPrint DumpCostPrint; + DumpCostPrint.m_fp = fp; + + std::sort(dumpVector.begin(), dumpVector.end(), DumpCostCompare); + std::for_each(dumpVector.begin(), dumpVector.end(), DumpCostPrint); + fprintf(fp, "total: %.2fmb", DumpPrint.m_totalKB / 1024.0f); + + fclose(fp); + } +} + +bool CResourceManager::IsFileExist(const char * c_szFileName) +{ + return CEterPackManager::Instance().isExist(c_szFileName); +} + +void CResourceManager::Update() +{ + DWORD CurrentTime = ELTimer_GetMSec(); + CResource * pResource; + int Count = 0; + + TResourceDeletingMap::iterator itor = m_ResourceDeletingMap.begin(); + + while (itor != m_ResourceDeletingMap.end()) + { + pResource = itor->first; + + if (CurrentTime >= itor->second) + { + if (pResource->canDestroy()) + { + //Tracef("Resource Clear %s\n", pResource->GetFileName()); + pResource->Clear(); + } + + itor = m_ResourceDeletingMap.erase(itor); + + if (++Count >= c_DeletingCountPerFrame) + break; + } + else + ++itor; + } + + ProcessBackgroundLoading(); +} + +void CResourceManager::ReserveDeletingResource(CResource * pResource) +{ + DWORD dwCurrentTime = ELTimer_GetMSec(); + m_ResourceDeletingMap.insert(TResourceDeletingMap::value_type(pResource, dwCurrentTime + c_Deleting_Wait_Time)); +} + +CResourceManager::CResourceManager() +{ + //ms_loadingThread.Create(0); +} + +CResourceManager::~CResourceManager() +{ + Destroy(); + //ms_loadingThread.Shutdown(); +} diff --git a/source/EterLib/ResourceManager.h b/source/EterLib/ResourceManager.h new file mode 100644 index 0000000..143cff1 --- /dev/null +++ b/source/EterLib/ResourceManager.h @@ -0,0 +1,73 @@ +#pragma once + +#include "Resource.h" +#include "FileLoaderThread.h" + +#include +#include +#include + +class CResourceManager : public CSingleton +{ + public: + CResourceManager(); + virtual ~CResourceManager(); + + void LoadStaticCache(const char* c_szFileName); + + void DestroyDeletingList(); + void Destroy(); + + void BeginThreadLoading(); + void EndThreadLoading(); + + CResource * InsertResourcePointer(DWORD dwFileCRC, CResource* pResource); + CResource * FindResourcePointer(DWORD dwFileCRC); + CResource * GetResourcePointer(const char * c_szFileName); + CResource * GetTypeResourcePointer(const char * c_szFileName, int iType=-1); + + // ߰ + bool isResourcePointerData(DWORD dwFileCRC); + + void RegisterResourceNewFunctionPointer(const char* c_szFileExt, CResource* (*pResNewFunc)(const char* c_szFileName)); + void RegisterResourceNewFunctionByTypePointer(int iType, CResource* (*pNewFunc) (const char* c_szFileName)); + + void DumpFileListToTextFile(const char* c_szFileName); + bool IsFileExist(const char * c_szFileName); + + void Update(); + void ReserveDeletingResource(CResource * pResource); + + public: + void ProcessBackgroundLoading(); + void PushBackgroundLoadingSet(std::set & LoadingSet); + + protected: + void __DestroyDeletingResourceMap(); + void __DestroyResourceMap(); + void __DestroyCacheMap(); + + DWORD __GetFileCRC(const char * c_szFileName, const char ** c_pszLowerFile = NULL); + + protected: + typedef std::map TResourcePointerMap; + typedef std::map TResourceNewFunctionPointerMap; + typedef std::map TResourceNewFunctionByTypePointerMap; + typedef std::map TResourceDeletingMap; + typedef std::map TResourceRequestMap; + typedef std::map TResourceRefDecreaseWaitingMap; + + protected: + TResourcePointerMap m_pCacheMap; + TResourcePointerMap m_pResMap; + TResourceNewFunctionPointerMap m_pResNewFuncMap; + TResourceNewFunctionByTypePointerMap m_pResNewFuncByTypeMap; + TResourceDeletingMap m_ResourceDeletingMap; + TResourceRequestMap m_RequestMap; // ε û Ʈ + TResourceRequestMap m_WaitingMap; + TResourceRefDecreaseWaitingMap m_pResRefDecreaseWaitingMap; + + static CFileLoaderThread ms_loadingThread; +}; + +extern int g_iLoadingDelayTime; \ No newline at end of file diff --git a/source/EterLib/ScreenFilter.cpp b/source/EterLib/ScreenFilter.cpp new file mode 100644 index 0000000..52ee9e1 --- /dev/null +++ b/source/EterLib/ScreenFilter.cpp @@ -0,0 +1,52 @@ +#include "StdAfx.h" +#include "ScreenFilter.h" +#include "StateManager.h" + +void CScreenFilter::Render() +{ + if (!m_bEnable) + return; + + STATEMANAGER.SaveTransform(D3DTS_PROJECTION, &ms_matIdentity); + STATEMANAGER.SaveTransform(D3DTS_VIEW, &ms_matIdentity); + STATEMANAGER.SetTransform(D3DTS_WORLD, &ms_matIdentity); + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, m_bySrcType); + STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, m_byDestType); + + SetOrtho2D(CScreen::ms_iWidth, CScreen::ms_iHeight, 400.0f); + SetDiffuseColor(m_Color.r, m_Color.g, m_Color.b, m_Color.a); + RenderBar2d(0, 0, CScreen::ms_iWidth, CScreen::ms_iHeight); + + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND); + STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND); + STATEMANAGER.RestoreTransform(D3DTS_VIEW); + STATEMANAGER.RestoreTransform(D3DTS_PROJECTION); +} + +void CScreenFilter::SetEnable(BOOL /*bFlag*/) +{ + m_bEnable = FALSE; +} + +void CScreenFilter::SetBlendType(BYTE bySrcType, BYTE byDestType) +{ + m_bySrcType = bySrcType; + m_byDestType = byDestType; +} +void CScreenFilter::SetColor(const D3DXCOLOR & c_rColor) +{ + m_Color = c_rColor; +} + +CScreenFilter::CScreenFilter() +{ + m_bEnable = FALSE; + m_bySrcType = D3DBLEND_SRCALPHA; + m_byDestType = D3DBLEND_INVSRCALPHA; + m_Color = D3DXCOLOR(0.0f, 0.0f, 0.0f, 0.0f); +} +CScreenFilter::~CScreenFilter() +{ +} diff --git a/source/EterLib/ScreenFilter.h b/source/EterLib/ScreenFilter.h new file mode 100644 index 0000000..577d1fa --- /dev/null +++ b/source/EterLib/ScreenFilter.h @@ -0,0 +1,22 @@ +#pragma once + +#include "GrpScreen.h" + +class CScreenFilter : public CScreen +{ + public: + CScreenFilter(); + virtual ~CScreenFilter(); + + void SetEnable(BOOL bFlag); + void SetBlendType(BYTE bySrcType, BYTE byDestType); + void SetColor(const D3DXCOLOR & c_rColor); + + void Render(); + + protected: + BOOL m_bEnable; + BYTE m_bySrcType; + BYTE m_byDestType; + D3DXCOLOR m_Color; +}; \ No newline at end of file diff --git a/source/EterLib/SkyBox.cpp b/source/EterLib/SkyBox.cpp new file mode 100644 index 0000000..b80994b --- /dev/null +++ b/source/EterLib/SkyBox.cpp @@ -0,0 +1,927 @@ +#include "stdafx.h" +#include "SkyBox.h" +#include "Camera.h" +#include "StateManager.h" +#include "ResourceManager.h" + +#include "../eterBase/Timer.h" + +////////////////////////////////////////////////////////////////////////// +// CSkyObjectQuad +////////////////////////////////////////////////////////////////////////// + +CSkyObjectQuad::CSkyObjectQuad() +{ + // Index buffer + m_Indices[0] = 0; + m_Indices[1] = 2; + m_Indices[2] = 1; + m_Indices[3] = 3; + + for (unsigned char uci = 0; uci < 4; ++uci) + { + memset(&m_Vertex[uci], 0, sizeof(TPDTVertex)); + } +} + +CSkyObjectQuad::~CSkyObjectQuad() +{ +} + +void CSkyObjectQuad::Clear(const unsigned char & c_rucNumVertex, + const float & c_rfRed, + const float & c_rfGreen, + const float & c_rfBlue, + const float & c_rfAlpha) +{ + if (c_rucNumVertex > 3) + return; + m_Helper[c_rucNumVertex].Clear(c_rfRed, c_rfGreen, c_rfBlue, c_rfAlpha); +} + +void CSkyObjectQuad::SetSrcColor(const unsigned char & c_rucNumVertex, + const float & c_rfRed, + const float & c_rfGreen, + const float & c_rfBlue, + const float & c_rfAlpha) +{ + if (c_rucNumVertex > 3) + return; + m_Helper[c_rucNumVertex].SetSrcColor(c_rfRed, c_rfGreen, c_rfBlue, c_rfAlpha); +} + +void CSkyObjectQuad::SetTransition(const unsigned char & c_rucNumVertex, + const float & c_rfRed, + const float & c_rfGreen, + const float & c_rfBlue, + const float & c_rfAlpha, + DWORD dwDuration) +{ + if (c_rucNumVertex > 3) + return; + m_Helper[c_rucNumVertex].SetTransition(c_rfRed, c_rfGreen, c_rfBlue, c_rfAlpha, dwDuration); +} + +void CSkyObjectQuad::SetVertex(const unsigned char & c_rucNumVertex, const TPDTVertex & c_rPDTVertex) +{ + if (c_rucNumVertex > 3) + return; + memcpy (&m_Vertex[m_Indices[c_rucNumVertex]], &c_rPDTVertex, sizeof(TPDTVertex)); +} + +void CSkyObjectQuad::StartTransition() +{ + for (unsigned char uci = 0; uci < 4; ++uci) + { + m_Helper[uci].StartTransition(); + } +} + +bool CSkyObjectQuad::Update() +{ + bool bResult = false; + for (unsigned char uci = 0; uci < 4; ++uci) + { + bResult = m_Helper[uci].Update() || bResult; + m_Vertex[m_Indices[uci]].diffuse = m_Helper[uci].GetCurColor(); + } + return bResult; +} + +void CSkyObjectQuad::Render() +{ + if (CGraphicBase::SetPDTStream(m_Vertex, 4)) + STATEMANAGER.DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); + //STATEMANAGER.DrawIndexedPrimitiveUP(D3DPT_TRIANGLESTRIP, 0, 4, 2, m_Indices, D3DFMT_INDEX16, &m_Vertex, sizeof(TPDTVertex)); +} + +////////////////////////////////////////////////////////////////////////// +// CSkyObject +///////////////////////////////////////////////////////////////////////// +CSkyObject::CSkyObject() : + m_v3Position(0.0f, 0.0f, 0.0f), + m_fScaleX(1.0f), + m_fScaleY(1.0f), + m_fScaleZ(1.0f) +{ + D3DXMatrixIdentity(&m_matWorld); + D3DXMatrixIdentity(&m_matTranslation); + D3DXMatrixIdentity(&m_matTextureCloud); + + m_dwlastTime = CTimer::Instance().GetCurrentMillisecond(); + + m_fCloudPositionU = 0.0f; + m_fCloudPositionV = 0.0f; + + m_bTransitionStarted = false; + m_bSkyMatrixUpdated = false; +} + +CSkyObject::~CSkyObject() +{ + Destroy(); +} + +void CSkyObject::Destroy() +{ +} + +void CSkyObject::Update() +{ + D3DXVECTOR3 v3Eye = CCameraManager::Instance().GetCurrentCamera()->GetEye(); + + if (m_v3Position == v3Eye) + if (m_bSkyMatrixUpdated == false) + return; + + m_v3Position = v3Eye; + + m_matWorld._41 = m_v3Position.x; + m_matWorld._42 = m_v3Position.y; + m_matWorld._43 = m_v3Position.z; + + m_matWorldCloud._41 = m_v3Position.x; + m_matWorldCloud._42 = m_v3Position.y; + m_matWorldCloud._43 = m_v3Position.z + m_fCloudHeight; + + if (m_bSkyMatrixUpdated) + m_bSkyMatrixUpdated = false; +} + +void CSkyObject::Render() +{ +} + +CGraphicImageInstance * CSkyObject::GenerateTexture(const char * szfilename) +{ + assert(szfilename != NULL); + + if (strlen(szfilename) <= 0) + assert(false); + + CResource * pResource = CResourceManager::Instance().GetResourcePointer(szfilename); + + if (!pResource->IsType(CGraphicImage::Type())) + { + assert(false); + return NULL; + } + + CGraphicImageInstance * pImageInstance = CGraphicImageInstance::New(); + pImageInstance->SetImagePointer(static_cast(pResource)); + return (pImageInstance); +} + +void CSkyObject::DeleteTexture(CGraphicImageInstance * pImageInstance) +{ + if (pImageInstance) + CGraphicImageInstance::Delete(pImageInstance); +} + +void CSkyObject::StartTransition() +{ +} + +////////////////////////////////////////////////////////////////////////// +// CSkyObject::TSkyObjectFace +////////////////////////////////////////////////////////////////////////// + +void CSkyObject::TSkyObjectFace::StartTransition() +{ + for (unsigned char uci = 0; uci < m_SkyObjectQuadVector.size(); ++uci) + { + m_SkyObjectQuadVector[uci].StartTransition(); + } +} + +bool CSkyObject::TSkyObjectFace::Update() +{ + bool bResult = false; + for (DWORD dwi = 0; dwi < m_SkyObjectQuadVector.size(); ++dwi) + bResult = m_SkyObjectQuadVector[dwi].Update() || bResult; + return bResult; +} + +void CSkyObject::TSkyObjectFace::Render() +{ + for (unsigned char uci = 0; uci < m_SkyObjectQuadVector.size(); ++uci) + { + m_SkyObjectQuadVector[uci].Render(); + } +} + +////////////////////////////////////////////////////////////////////////// +// CSkyBox +////////////////////////////////////////////////////////////////////////// + +CSkyBox::CSkyBox() +{ + m_ucVirticalGradientLevelUpper = 0; + m_ucVirticalGradientLevelLower = 0; +} + +CSkyBox::~CSkyBox() +{ + Destroy(); +} + +void CSkyBox::Destroy() +{ + Unload(); +} + +void CSkyBox::SetSkyBoxScale(const D3DXVECTOR3 & c_rv3Scale) +{ + m_fScaleX = c_rv3Scale.x; + m_fScaleY = c_rv3Scale.y; + m_fScaleZ = c_rv3Scale.z; + + m_bSkyMatrixUpdated = true; + D3DXMatrixScaling(&m_matWorld, m_fScaleX, m_fScaleY, m_fScaleZ); +} + +void CSkyBox::SetGradientLevel(BYTE byUpper, BYTE byLower) +{ + m_ucVirticalGradientLevelUpper = byUpper; + m_ucVirticalGradientLevelLower = byLower; +} + +void CSkyBox::SetFaceTexture( const char* c_szFileName, int iFaceIndex ) +{ + if( iFaceIndex < 0 || iFaceIndex > 5 ) + return; + + TGraphicImageInstanceMap::iterator itor = m_GraphicImageInstanceMap.find(c_szFileName); + if (m_GraphicImageInstanceMap.end() != itor) + return; + + m_Faces[iFaceIndex].m_strFaceTextureFileName = c_szFileName; + + CGraphicImageInstance * pGraphicImageInstance = GenerateTexture(c_szFileName); + m_GraphicImageInstanceMap.insert(TGraphicImageInstanceMap::value_type(c_szFileName, pGraphicImageInstance)); +} + + +void CSkyBox::SetCloudTexture(const char * c_szFileName) +{ + TGraphicImageInstanceMap::iterator itor = m_GraphicImageInstanceMap.find(c_szFileName); + if (m_GraphicImageInstanceMap.end() != itor) + return; + + m_FaceCloud.m_strfacename = c_szFileName; + CGraphicImageInstance * pGraphicImageInstance = GenerateTexture(c_szFileName); + m_GraphicImageInstanceMap.insert(TGraphicImageInstanceMap::value_type(m_FaceCloud.m_strfacename, pGraphicImageInstance)); + + // ̰ Ⱦ° ? [cronan] +// CGraphicImage * pImage = (CGraphicImage *) CResourceManager::Instance().GetResourcePointer("D:\\Ymir Work\\special/cloudalpha.tga"); +// m_CloudAlphaImageInstance.SetImagePointer(pImage); +} + +void CSkyBox::SetCloudScale(const D3DXVECTOR2 & c_rv2CloudScale) +{ + m_fCloudScaleX = c_rv2CloudScale.x; + m_fCloudScaleY = c_rv2CloudScale.y; + + D3DXMatrixScaling(&m_matWorldCloud, m_fCloudScaleX, m_fCloudScaleY, 1.0f); +} + +void CSkyBox::SetCloudHeight(float fHeight) +{ + m_fCloudHeight = fHeight; +} + +void CSkyBox::SetCloudTextureScale(const D3DXVECTOR2 & c_rv2CloudTextureScale) +{ + m_fCloudTextureScaleX = c_rv2CloudTextureScale.x; + m_fCloudTextureScaleY = c_rv2CloudTextureScale.y; + + m_matTextureCloud._11 = m_fCloudTextureScaleX; + m_matTextureCloud._22 = m_fCloudTextureScaleY; +} + +void CSkyBox::SetCloudScrollSpeed(const D3DXVECTOR2 & c_rv2CloudScrollSpeed) +{ + m_fCloudScrollSpeedU = c_rv2CloudScrollSpeed.x; + m_fCloudScrollSpeedV = c_rv2CloudScrollSpeed.y; +} + +void CSkyBox::Unload() +{ + TGraphicImageInstanceMap::iterator itor = m_GraphicImageInstanceMap.begin(); + + while (itor != m_GraphicImageInstanceMap.end()) + { + DeleteTexture(itor->second); + ++itor; + } + + m_GraphicImageInstanceMap.clear(); +} + +void CSkyBox::SetSkyObjectQuadVertical(TSkyObjectQuadVector * pSkyObjectQuadVector, const D3DXVECTOR2 * c_pv2QuadPoints) +{ + TPDTVertex aPDTVertex; + + DWORD dwIndex = 0; + + pSkyObjectQuadVector->clear(); + pSkyObjectQuadVector->resize(m_ucVirticalGradientLevelUpper + m_ucVirticalGradientLevelLower); + + unsigned char ucY; + for (ucY = 0; ucY < m_ucVirticalGradientLevelUpper; ++ucY) + { + CSkyObjectQuad & rSkyObjectQuad = pSkyObjectQuadVector->at(dwIndex++); + + aPDTVertex.position.x = c_pv2QuadPoints[0].x; + aPDTVertex.position.y = c_pv2QuadPoints[0].y; + aPDTVertex.position.z = 1.0f - (float)(ucY + 1)/ (float)(m_ucVirticalGradientLevelUpper); + aPDTVertex.texCoord.x = 0.0f; + aPDTVertex.texCoord.y = (float)(ucY + 1)/ (float)(m_ucVirticalGradientLevelUpper) * 0.5f; + rSkyObjectQuad.SetVertex(0 , aPDTVertex); + aPDTVertex.position.x = c_pv2QuadPoints[0].x; + aPDTVertex.position.y = c_pv2QuadPoints[0].y; + aPDTVertex.position.z = 1.0f - (float)(ucY) / (float)(m_ucVirticalGradientLevelUpper); + aPDTVertex.texCoord.x = 0.0f; + aPDTVertex.texCoord.y = (float)(ucY)/ (float)(m_ucVirticalGradientLevelUpper) * 0.5f; + rSkyObjectQuad.SetVertex(1, aPDTVertex); + aPDTVertex.position.x = c_pv2QuadPoints[1].x; + aPDTVertex.position.y = c_pv2QuadPoints[1].y; + aPDTVertex.position.z = 1.0f - (float)(ucY + 1) / (float)(m_ucVirticalGradientLevelUpper); + aPDTVertex.texCoord.x = 1.0f; + aPDTVertex.texCoord.y = (float)(ucY + 1)/ (float)(m_ucVirticalGradientLevelUpper) * 0.5f; + rSkyObjectQuad.SetVertex(2, aPDTVertex); + aPDTVertex.position.x = c_pv2QuadPoints[1].x; + aPDTVertex.position.y = c_pv2QuadPoints[1].y; + aPDTVertex.position.z = 1.0f - (float)(ucY) / (float)(m_ucVirticalGradientLevelUpper); + aPDTVertex.texCoord.x = 1.0f; + aPDTVertex.texCoord.y = (float)(ucY)/ (float)(m_ucVirticalGradientLevelUpper) * 0.5f; + rSkyObjectQuad.SetVertex(3, aPDTVertex); + } + for (ucY = 0; ucY < m_ucVirticalGradientLevelLower; ++ucY) + { + CSkyObjectQuad & rSkyObjectQuad = pSkyObjectQuadVector->at(dwIndex++); + + aPDTVertex.position.x = c_pv2QuadPoints[0].x; + aPDTVertex.position.y = c_pv2QuadPoints[0].y; + aPDTVertex.position.z = -(float)(ucY + 1)/ (float)(m_ucVirticalGradientLevelLower); + aPDTVertex.texCoord.x = 0.0f; + aPDTVertex.texCoord.y = 0.5f + (float)(ucY + 1)/ (float)(m_ucVirticalGradientLevelUpper) * 0.5f; + rSkyObjectQuad.SetVertex(0, aPDTVertex); + aPDTVertex.position.x = c_pv2QuadPoints[0].x; + aPDTVertex.position.y = c_pv2QuadPoints[0].y; + aPDTVertex.position.z = -(float)(ucY) / (float)(m_ucVirticalGradientLevelLower); + aPDTVertex.texCoord.x = 0.0f; + aPDTVertex.texCoord.y = 0.5f + (float)(ucY)/ (float)(m_ucVirticalGradientLevelUpper) * 0.5f; + rSkyObjectQuad.SetVertex(1, aPDTVertex); + aPDTVertex.position.x = c_pv2QuadPoints[1].x; + aPDTVertex.position.y = c_pv2QuadPoints[1].y; + aPDTVertex.position.z = -(float)(ucY + 1) / (float)(m_ucVirticalGradientLevelLower); + aPDTVertex.texCoord.x = 1.0f; + aPDTVertex.texCoord.y = 0.5f + (float)(ucY + 1)/ (float)(m_ucVirticalGradientLevelUpper) * 0.5f; + rSkyObjectQuad.SetVertex(2, aPDTVertex); + aPDTVertex.position.x = c_pv2QuadPoints[1].x; + aPDTVertex.position.y = c_pv2QuadPoints[1].y; + aPDTVertex.position.z = -(float)(ucY) / (float)(m_ucVirticalGradientLevelLower); + aPDTVertex.texCoord.x = 1.0f; + aPDTVertex.texCoord.y = 0.5f + (float)(ucY)/ (float)(m_ucVirticalGradientLevelUpper) * 0.5f; + rSkyObjectQuad.SetVertex(3, aPDTVertex); + } +} + +//void CSkyBox::UpdateSkyFaceQuadTransform(D3DXVECTOR3 * c_pv3QuadPoints) +//{ +// for( int i = 0; i < 4; ++i ) +// { +// c_pv3QuadPoints[i].x *= m_fScaleX; +// c_pv3QuadPoints[i].y *= m_fScaleY; +// c_pv3QuadPoints[i].z *= m_fScaleZ; +// +// c_pv3QuadPoints[i] += m_v3Position; +// } +//} + +void CSkyBox::SetSkyObjectQuadHorizon(TSkyObjectQuadVector * pSkyObjectQuadVector, const D3DXVECTOR3 * c_pv3QuadPoints) +{ + pSkyObjectQuadVector->clear(); + pSkyObjectQuadVector->resize(1); + CSkyObjectQuad & rSkyObjectQuad = pSkyObjectQuadVector->at(0); + + TPDTVertex aPDTVertex; + aPDTVertex.position = c_pv3QuadPoints[0]; + aPDTVertex.texCoord.x = 0.0f; + aPDTVertex.texCoord.y = 1.0f; + rSkyObjectQuad.SetVertex(0, aPDTVertex); + + aPDTVertex.position = c_pv3QuadPoints[1]; + aPDTVertex.texCoord.x = 0.0f; + aPDTVertex.texCoord.y = 0.0f; + rSkyObjectQuad.SetVertex(1, aPDTVertex); + + aPDTVertex.position = c_pv3QuadPoints[2]; + aPDTVertex.texCoord.x = 1.0f; + aPDTVertex.texCoord.y = 1.0f; + rSkyObjectQuad.SetVertex(2, aPDTVertex); + + aPDTVertex.position = c_pv3QuadPoints[3]; + aPDTVertex.texCoord.x = 1.0f; + aPDTVertex.texCoord.y = 0.0f; + rSkyObjectQuad.SetVertex(3, aPDTVertex); +} + +void CSkyBox::Refresh() +{ + D3DXVECTOR3 v3QuadPoints[4]; + + if( m_ucRenderMode == CSkyObject::SKY_RENDER_MODE_DEFAULT || m_ucRenderMode == CSkyObject::SKY_RENDER_MODE_DIFFUSE ) + { + if (m_ucVirticalGradientLevelUpper + m_ucVirticalGradientLevelLower <= 0) + return; + + D3DXVECTOR2 v2QuadPoints[2]; + + //// Face 0: FRONT + v2QuadPoints[0] = D3DXVECTOR2(1.0f, -1.0f); + v2QuadPoints[1] = D3DXVECTOR2(-1.0f, -1.0f); + SetSkyObjectQuadVertical(&m_Faces[0].m_SkyObjectQuadVector, v2QuadPoints); + m_Faces[0].m_strfacename = "front"; + + //// Face 1: BACK + v2QuadPoints[0] = D3DXVECTOR2(-1.0f, 1.0f); + v2QuadPoints[1] = D3DXVECTOR2(1.0f, 1.0f); + SetSkyObjectQuadVertical(&m_Faces[1].m_SkyObjectQuadVector, v2QuadPoints); + m_Faces[1].m_strfacename = "back"; + + //// Face 2: LEFT + v2QuadPoints[0] = D3DXVECTOR2(-1.0f, -1.0f); + v2QuadPoints[1] = D3DXVECTOR2(-1.0f, 1.0f); + SetSkyObjectQuadVertical(&m_Faces[2].m_SkyObjectQuadVector, v2QuadPoints); + m_Faces[2].m_strfacename = "left"; + + //// Face 3: RIGHT + v2QuadPoints[0] = D3DXVECTOR2(1.0f, 1.0f); + v2QuadPoints[1] = D3DXVECTOR2(1.0f, -1.0f); + SetSkyObjectQuadVertical(&m_Faces[3].m_SkyObjectQuadVector, v2QuadPoints); + m_Faces[3].m_strfacename = "right"; + + //// Face 4: TOP + v3QuadPoints[0] = D3DXVECTOR3(1.0f, 1.0f, 1.0f); + v3QuadPoints[1] = D3DXVECTOR3(-1.0f, 1.0f, 1.0f); + v3QuadPoints[2] = D3DXVECTOR3(1.0f, -1.0f, 1.0f); + v3QuadPoints[3] = D3DXVECTOR3(-1.0f, -1.0f, 1.0f); + SetSkyObjectQuadHorizon(&m_Faces[4].m_SkyObjectQuadVector, v3QuadPoints); + m_Faces[4].m_strfacename = "top"; + + //// Face 5: BOTTOM + v3QuadPoints[0] = D3DXVECTOR3(-1.0f, 1.0f, -1.0f); + v3QuadPoints[1] = D3DXVECTOR3(1.0f, 1.0f, -1.0f); + v3QuadPoints[2] = D3DXVECTOR3(-1.0f, -1.0f, -1.0f); + v3QuadPoints[3] = D3DXVECTOR3(1.0f, -1.0f, -1.0f); + SetSkyObjectQuadHorizon(&m_Faces[5].m_SkyObjectQuadVector, v3QuadPoints); + m_Faces[5].m_strfacename = "bottom"; + + } + else if( m_ucRenderMode == CSkyObject::SKY_RENDER_MODE_TEXTURE ) + { + // Face 0: FRONT + v3QuadPoints[0] = D3DXVECTOR3(1.0f, -1.0f, -1.0f); + v3QuadPoints[1] = D3DXVECTOR3(1.0f, -1.0f, 1.0f); + v3QuadPoints[2] = D3DXVECTOR3(-1.0f, -1.0f, -1.0f); + v3QuadPoints[3] = D3DXVECTOR3(-1.0f, -1.0f, 1.0f); + + //UpdateSkyFaceQuadTransform(v3QuadPoints); + + SetSkyObjectQuadHorizon(&m_Faces[0].m_SkyObjectQuadVector, v3QuadPoints); + m_Faces[0].m_strfacename = "front"; + + //// Face 1: BACK + v3QuadPoints[0] = D3DXVECTOR3(-1.0f, 1.0f, -1.0f); + v3QuadPoints[1] = D3DXVECTOR3(-1.0f, 1.0f, 1.0f); + v3QuadPoints[2] = D3DXVECTOR3(1.0f, 1.0f, -1.0f); + v3QuadPoints[3] = D3DXVECTOR3(1.0f, 1.0f, 1.0f); + + //UpdateSkyFaceQuadTransform(v3QuadPoints); + + SetSkyObjectQuadHorizon(&m_Faces[1].m_SkyObjectQuadVector, v3QuadPoints); + m_Faces[1].m_strfacename = "back"; + + // Face 2: LEFT + v3QuadPoints[0] = D3DXVECTOR3(1.0f, 1.0f, -1.0f); + v3QuadPoints[1] = D3DXVECTOR3(1.0f, 1.0f, 1.0f); + v3QuadPoints[2] = D3DXVECTOR3(1.0f, -1.0f, -1.0f); + v3QuadPoints[3] = D3DXVECTOR3(1.0f, -1.0f, 1.0f); + + //UpdateSkyFaceQuadTransform(v3QuadPoints); + + SetSkyObjectQuadHorizon(&m_Faces[2].m_SkyObjectQuadVector, v3QuadPoints); + m_Faces[2].m_strfacename = "left"; + + // Face 3: RIGHT + v3QuadPoints[0] = D3DXVECTOR3(-1.0f, -1.0f, -1.0f); + v3QuadPoints[1] = D3DXVECTOR3(-1.0f, -1.0f, 1.0f); + v3QuadPoints[2] = D3DXVECTOR3(-1.0f, 1.0f, -1.0f); + v3QuadPoints[3] = D3DXVECTOR3(-1.0f, 1.0f, 1.0f); + + //UpdateSkyFaceQuadTransform(v3QuadPoints); + + SetSkyObjectQuadHorizon(&m_Faces[3].m_SkyObjectQuadVector, v3QuadPoints); + m_Faces[3].m_strfacename = "right"; + + // Face 4: TOP + v3QuadPoints[0] = D3DXVECTOR3(1.0f, -1.0f, 1.0f); + v3QuadPoints[1] = D3DXVECTOR3(1.0f, 1.0f, 1.0f); + v3QuadPoints[2] = D3DXVECTOR3(-1.0f, -1.0f, 1.0f); + v3QuadPoints[3] = D3DXVECTOR3(-1.0f, 1.0f, 1.0f); + + //UpdateSkyFaceQuadTransform(v3QuadPoints); + + SetSkyObjectQuadHorizon(&m_Faces[4].m_SkyObjectQuadVector, v3QuadPoints); + m_Faces[4].m_strfacename = "top"; + + ////// Face 5: BOTTOM + v3QuadPoints[0] = D3DXVECTOR3(1.0f, -1.0f, -1.0f); + v3QuadPoints[1] = D3DXVECTOR3(1.0f, 1.0f, -1.0f); + v3QuadPoints[2] = D3DXVECTOR3(-1.0f, -1.0f, -1.0f); + v3QuadPoints[3] = D3DXVECTOR3(-1.0f, 1.0f, -1.0f); + + //UpdateSkyFaceQuadTransform(v3QuadPoints); + + SetSkyObjectQuadHorizon(&m_Faces[5].m_SkyObjectQuadVector, v3QuadPoints); + m_Faces[5].m_strfacename = "bottom"; + } + + //// Clouds.. + v3QuadPoints[0] = D3DXVECTOR3(1.0f, 1.0f, 0.0f); + v3QuadPoints[1] = D3DXVECTOR3(-1.0f, 1.0f, 0.0f); + v3QuadPoints[2] = D3DXVECTOR3(1.0f, -1.0f, 0.0f); + v3QuadPoints[3] = D3DXVECTOR3(-1.0f, -1.0f, 0.0f); + SetSkyObjectQuadHorizon(&m_FaceCloud.m_SkyObjectQuadVector, v3QuadPoints); +} + +void CSkyBox::SetCloudColor(const TGradientColor & c_rColor, const TGradientColor & c_rNextColor, const DWORD & dwTransitionTime) +{ + TSkyObjectFace & aFaceCloud = m_FaceCloud; + for (DWORD dwk = 0; dwk < aFaceCloud.m_SkyObjectQuadVector.size(); ++dwk) + { + CSkyObjectQuad & aSkyObjectQuad = aFaceCloud.m_SkyObjectQuadVector[dwk]; + + aSkyObjectQuad.SetSrcColor(0, + c_rColor.m_FirstColor.r, + c_rColor.m_FirstColor.g, + c_rColor.m_FirstColor.b, + c_rColor.m_FirstColor.a); + aSkyObjectQuad.SetTransition(0, + c_rNextColor.m_FirstColor.r, + c_rNextColor.m_FirstColor.g, + c_rNextColor.m_FirstColor.b, + c_rNextColor.m_FirstColor.a, + dwTransitionTime); + aSkyObjectQuad.SetSrcColor(1, + c_rColor.m_FirstColor.r, + c_rColor.m_FirstColor.g, + c_rColor.m_FirstColor.b, + c_rColor.m_FirstColor.a); + aSkyObjectQuad.SetTransition(1, + c_rNextColor.m_FirstColor.r, + c_rNextColor.m_FirstColor.g, + c_rNextColor.m_FirstColor.b, + c_rNextColor.m_FirstColor.a, + dwTransitionTime); + aSkyObjectQuad.SetSrcColor(2, + c_rColor.m_FirstColor.r, + c_rColor.m_FirstColor.g, + c_rColor.m_FirstColor.b, + c_rColor.m_FirstColor.a); + aSkyObjectQuad.SetTransition(2, + c_rNextColor.m_FirstColor.r, + c_rNextColor.m_FirstColor.g, + c_rNextColor.m_FirstColor.b, + c_rNextColor.m_FirstColor.a, + dwTransitionTime); + aSkyObjectQuad.SetSrcColor(3, + c_rColor.m_FirstColor.r, + c_rColor.m_FirstColor.g, + c_rColor.m_FirstColor.b, + c_rColor.m_FirstColor.a); + aSkyObjectQuad.SetTransition(3, + c_rNextColor.m_FirstColor.r, + c_rNextColor.m_FirstColor.g, + c_rNextColor.m_FirstColor.b, + c_rNextColor.m_FirstColor.a, + dwTransitionTime); + } +} + +void CSkyBox::SetSkyColor(const TVectorGradientColor & c_rColorVector, const TVectorGradientColor & c_rNextColorVector, long lTransitionTime) +{ + unsigned long ulVectorGradientColornum = 0; + unsigned long uck; + for (unsigned char ucj = 0; ucj < 4; ++ucj) + { + TSkyObjectFace & aFace = m_Faces[ucj]; + ulVectorGradientColornum = 0; + for (uck = 0; uck < aFace.m_SkyObjectQuadVector.size(); ++uck) + { + CSkyObjectQuad & aSkyObjectQuad = aFace.m_SkyObjectQuadVector[uck]; + + aSkyObjectQuad.SetSrcColor(0, + c_rColorVector[ulVectorGradientColornum].m_SecondColor.r, + c_rColorVector[ulVectorGradientColornum].m_SecondColor.g, + c_rColorVector[ulVectorGradientColornum].m_SecondColor.b, + c_rColorVector[ulVectorGradientColornum].m_SecondColor.a); + aSkyObjectQuad.SetTransition(0, + c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.r, + c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.g, + c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.b, + c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.a, + lTransitionTime); + aSkyObjectQuad.SetSrcColor(1, + c_rColorVector[ulVectorGradientColornum].m_FirstColor.r, + c_rColorVector[ulVectorGradientColornum].m_FirstColor.g, + c_rColorVector[ulVectorGradientColornum].m_FirstColor.b, + c_rColorVector[ulVectorGradientColornum].m_FirstColor.a); + aSkyObjectQuad.SetTransition(1, + c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.r, + c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.g, + c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.b, + c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.a, + lTransitionTime); + aSkyObjectQuad.SetSrcColor(2, + c_rColorVector[ulVectorGradientColornum].m_SecondColor.r, + c_rColorVector[ulVectorGradientColornum].m_SecondColor.g, + c_rColorVector[ulVectorGradientColornum].m_SecondColor.b, + c_rColorVector[ulVectorGradientColornum].m_SecondColor.a); + aSkyObjectQuad.SetTransition(2, + c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.r, + c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.g, + c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.b, + c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.a, + lTransitionTime); + aSkyObjectQuad.SetSrcColor(3, + c_rColorVector[ulVectorGradientColornum].m_FirstColor.r, + c_rColorVector[ulVectorGradientColornum].m_FirstColor.g, + c_rColorVector[ulVectorGradientColornum].m_FirstColor.b, + c_rColorVector[ulVectorGradientColornum].m_FirstColor.a); + aSkyObjectQuad.SetTransition(3, + c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.r, + c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.g, + c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.b, + c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.a, + lTransitionTime); + + ulVectorGradientColornum++; + } + } + + ///// + + TSkyObjectFace & aFaceTop = m_Faces[4]; + ulVectorGradientColornum = 0; + for (uck = 0; uck < aFaceTop.m_SkyObjectQuadVector.size(); ++uck) + { + CSkyObjectQuad & aSkyObjectQuad = aFaceTop.m_SkyObjectQuadVector[uck]; + + aSkyObjectQuad.SetSrcColor(0, + c_rColorVector[ulVectorGradientColornum].m_FirstColor.r, + c_rColorVector[ulVectorGradientColornum].m_FirstColor.g, + c_rColorVector[ulVectorGradientColornum].m_FirstColor.b, + c_rColorVector[ulVectorGradientColornum].m_FirstColor.a); + aSkyObjectQuad.SetTransition(0, + c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.r, + c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.g, + c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.b, + c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.a, + lTransitionTime); + aSkyObjectQuad.SetSrcColor(1, + c_rColorVector[ulVectorGradientColornum].m_FirstColor.r, + c_rColorVector[ulVectorGradientColornum].m_FirstColor.g, + c_rColorVector[ulVectorGradientColornum].m_FirstColor.b, + c_rColorVector[ulVectorGradientColornum].m_FirstColor.a); + aSkyObjectQuad.SetTransition(1, + c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.r, + c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.g, + c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.b, + c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.a, + lTransitionTime); + aSkyObjectQuad.SetSrcColor(2, + c_rColorVector[ulVectorGradientColornum].m_FirstColor.r, + c_rColorVector[ulVectorGradientColornum].m_FirstColor.g, + c_rColorVector[ulVectorGradientColornum].m_FirstColor.b, + c_rColorVector[ulVectorGradientColornum].m_FirstColor.a); + aSkyObjectQuad.SetTransition(2, + c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.r, + c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.g, + c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.b, + c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.a, + lTransitionTime); + aSkyObjectQuad.SetSrcColor(3, + c_rColorVector[ulVectorGradientColornum].m_FirstColor.r, + c_rColorVector[ulVectorGradientColornum].m_FirstColor.g, + c_rColorVector[ulVectorGradientColornum].m_FirstColor.b, + c_rColorVector[ulVectorGradientColornum].m_FirstColor.a); + aSkyObjectQuad.SetTransition(3, + c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.r, + c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.g, + c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.b, + c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.a, + lTransitionTime); + } + TSkyObjectFace & aFaceBottom = m_Faces[5]; + ulVectorGradientColornum = c_rColorVector.size() - 1; + for (uck = 0; uck < aFaceBottom.m_SkyObjectQuadVector.size(); ++uck) + { + CSkyObjectQuad & aSkyObjectQuad = aFaceBottom.m_SkyObjectQuadVector[uck]; + + aSkyObjectQuad.SetSrcColor(0, + c_rColorVector[ulVectorGradientColornum].m_SecondColor.r, + c_rColorVector[ulVectorGradientColornum].m_SecondColor.g, + c_rColorVector[ulVectorGradientColornum].m_SecondColor.b, + c_rColorVector[ulVectorGradientColornum].m_SecondColor.a); + aSkyObjectQuad.SetTransition(0, + c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.r, + c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.g, + c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.b, + c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.a, + lTransitionTime); + aSkyObjectQuad.SetSrcColor(1, + c_rColorVector[ulVectorGradientColornum].m_SecondColor.r, + c_rColorVector[ulVectorGradientColornum].m_SecondColor.g, + c_rColorVector[ulVectorGradientColornum].m_SecondColor.b, + c_rColorVector[ulVectorGradientColornum].m_SecondColor.a); + aSkyObjectQuad.SetTransition(1, + c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.r, + c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.g, + c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.b, + c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.a, + lTransitionTime); + aSkyObjectQuad.SetSrcColor(2, + c_rColorVector[ulVectorGradientColornum].m_SecondColor.r, + c_rColorVector[ulVectorGradientColornum].m_SecondColor.g, + c_rColorVector[ulVectorGradientColornum].m_SecondColor.b, + c_rColorVector[ulVectorGradientColornum].m_SecondColor.a); + aSkyObjectQuad.SetTransition(2, + c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.r, + c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.g, + c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.b, + c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.a, + lTransitionTime); + aSkyObjectQuad.SetSrcColor(3, + c_rColorVector[ulVectorGradientColornum].m_SecondColor.r, + c_rColorVector[ulVectorGradientColornum].m_SecondColor.g, + c_rColorVector[ulVectorGradientColornum].m_SecondColor.b, + c_rColorVector[ulVectorGradientColornum].m_SecondColor.a); + aSkyObjectQuad.SetTransition(3, + c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.r, + c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.g, + c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.b, + c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.a, + lTransitionTime); + } +} + +void CSkyBox::StartTransition() +{ + m_bTransitionStarted = true; + for (unsigned char ucj = 0; ucj < 6; ++ucj) + m_Faces[ucj].StartTransition(); + m_FaceCloud.StartTransition(); +} + +void CSkyBox::Update() +{ + CSkyObject::Update(); + + if (!m_bTransitionStarted) + return; + + bool bResult = false; + for (unsigned char uci = 0; uci < 6; ++uci) + bResult = m_Faces[uci].Update() || bResult; + bResult = m_FaceCloud.Update() || bResult; + + m_bTransitionStarted = bResult; +} + +void CSkyBox::Render() +{ + // 2004.01.25 myevan ó Ĺ ű, DepthTest ó + STATEMANAGER.SaveRenderState(D3DRS_ZENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, FALSE); + STATEMANAGER.SaveRenderState(D3DRS_LIGHTING, FALSE); + STATEMANAGER.SaveRenderState(D3DRS_FOGENABLE, FALSE); + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + + STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matWorld); + + //Render Face + if( m_ucRenderMode == CSkyObject::SKY_RENDER_MODE_TEXTURE ) + { + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); + + for (unsigned int i = 0; i < 6; ++i) + { + CGraphicImageInstance * pFaceImageInstance = m_GraphicImageInstanceMap[m_Faces[i].m_strFaceTextureFileName]; + if (!pFaceImageInstance) + break; + + STATEMANAGER.SetTexture( 0, pFaceImageInstance->GetTextureReference().GetD3DTexture() ); + + m_Faces[i].Render(); + } + + //STATEMANAGER.SetTexture( 0, NULL ); + + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSU); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSV); + } + else + { + for (unsigned int i = 0; i < 6; ++i) + { + m_Faces[i].Render(); + } + } + + STATEMANAGER.RestoreRenderState(D3DRS_LIGHTING); + STATEMANAGER.RestoreRenderState(D3DRS_ZENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_FOGENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); + + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG2); +} + +void CSkyBox::RenderCloud() +{ + CGraphicImageInstance * pCloudGraphicImageInstance = m_GraphicImageInstanceMap[m_FaceCloud.m_strfacename]; + if (!pCloudGraphicImageInstance) + return; + + // 2004.01.25 myevan ó Ĺ ű, DepthTest ó + STATEMANAGER.SaveRenderState(D3DRS_ZENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, FALSE); + STATEMANAGER.SaveRenderState(D3DRS_LIGHTING, FALSE); + STATEMANAGER.SaveRenderState(D3DRS_FOGENABLE, FALSE); + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); + STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR); + + STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); + + m_matTextureCloud._31 = m_fCloudPositionU; + m_matTextureCloud._32 = m_fCloudPositionV; + + DWORD dwCurTime = CTimer::Instance().GetCurrentMillisecond(); + + m_fCloudPositionU += m_fCloudScrollSpeedU * (float)( dwCurTime - m_dwlastTime ) * 0.001f; + if (m_fCloudPositionU >= 1.0f) + m_fCloudPositionU = 0.0f; + + m_fCloudPositionV += m_fCloudScrollSpeedV * (float)( dwCurTime - m_dwlastTime ) * 0.001f; + if (m_fCloudPositionV >= 1.0f) + m_fCloudPositionV = 0.0f; + + m_dwlastTime = dwCurTime; + + STATEMANAGER.SaveTransform(D3DTS_TEXTURE0, &m_matTextureCloud); + + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATEINVALPHA_ADDCOLOR); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + + D3DXMATRIX matProjCloud; + D3DXMatrixPerspectiveFovRH(&matProjCloud, D3DX_PI * 0.25f, 1.33333f, 50.0f, 999999.0f); + STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matWorldCloud); + STATEMANAGER.SaveTransform(D3DTS_PROJECTION, &matProjCloud); + STATEMANAGER.SetTexture(0, pCloudGraphicImageInstance->GetTexturePointer()->GetD3DTexture()); + m_FaceCloud.Render(); + STATEMANAGER.RestoreTransform(D3DTS_PROJECTION); + + STATEMANAGER.RestoreTransform(D3DTS_TEXTURE0); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS); + + STATEMANAGER.RestoreRenderState(D3DRS_LIGHTING); + STATEMANAGER.RestoreRenderState(D3DRS_ZENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_FOGENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND); + STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND); +} diff --git a/source/EterLib/SkyBox.h b/source/EterLib/SkyBox.h new file mode 100644 index 0000000..8707968 --- /dev/null +++ b/source/EterLib/SkyBox.h @@ -0,0 +1,188 @@ +// SkyBox.h: interface for the CSkyBox class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_SKYBOX_H__AB5049E1_8F1C_4C35_9406_45EC7EF4AD1B__INCLUDED_) +#define AFX_SKYBOX_H__AB5049E1_8F1C_4C35_9406_45EC7EF4AD1B__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "GrpBase.h" +#include "GrpScreen.h" +#include "GrpImageInstance.h" +#include "ColorTransitionHelper.h" + +#include +#include + +typedef struct SColor +{ + SColor(float _r = 0.0f, float _g = 0.0f, float _b = 0.0f, float _a = 0.0f) : r(_r), g(_g), b(_b), a(_a){} + float r, g, b, a; +} TColor; + +typedef struct +{ + TColor m_FirstColor; + TColor m_SecondColor; +}TGradientColor; + +typedef std::vector TVectorGradientColor; +typedef TVectorGradientColor::iterator TVectorGradientIterator; + +class CSkyObjectQuad +{ +public: + CSkyObjectQuad(); + virtual ~CSkyObjectQuad(); + + void Clear(const unsigned char & c_rucNumVertex, + const float & c_rfRed, + const float & c_rfGreen, + const float & c_rfBlue, + const float & c_rfAlpha); + void SetSrcColor(const unsigned char & c_rucNumVertex, + const float & c_rfRed, + const float & c_rfGreen, + const float & c_rfBlue, + const float & c_rfAlpha); + void SetTransition(const unsigned char & c_rucNumVertex, + const float & c_rfRed, + const float & c_rfGreen, + const float & c_rfBlue, + const float & c_rfAlpha, + DWORD dwDuration); + + void SetVertex(const unsigned char & c_rucNumVertex, const TPDTVertex & c_rPDTVertex); + + void StartTransition(); + bool Update(); + void Render(); + +private: + TPDTVertex m_Vertex[4]; + TIndex m_Indices[4]; // ε ... + CColorTransitionHelper m_Helper[4]; +}; + +class CSkyObject : public CScreen +{ +public: + enum + { + SKY_RENDER_MODE_DEFAULT, // = SKY_RENDER_MODE_TEXTURE + SKY_RENDER_MODE_DIFFUSE, + SKY_RENDER_MODE_TEXTURE, + SKY_RENDER_MODE_MODULATE, + SKY_RENDER_MODE_MODULATE2X, + SKY_RENDER_MODE_MODULATE4X, + }; + + CSkyObject(); + virtual ~CSkyObject(); + + virtual void Destroy() = 0; + + virtual void Render() = 0; + virtual void Update() = 0; + virtual void StartTransition(); + + void SetRenderMode(unsigned char ucRenderMode) { m_ucRenderMode = ucRenderMode; } + + const bool & isTransitionStarted() { return m_bTransitionStarted; } + +protected: + CGraphicImageInstance * GenerateTexture(const char * szfilename); + void DeleteTexture(CGraphicImageInstance * pGraphicImageInstance); + +protected: + ////////////////////////////////////////////////////////////////////////// + // Ÿ + + typedef std::vector TSkyObjectQuadVector; + typedef TSkyObjectQuadVector::iterator TSkyObjectQuadIterator; + + typedef struct CSkyBox + { + void StartTransition(); + bool Update(); + void Render(); + std::string m_strfacename; + std::string m_strFaceTextureFileName; + TSkyObjectQuadVector m_SkyObjectQuadVector; + }TSkyObjectFace; + + typedef std::map TGraphicImageInstanceMap; + + ////////////////////////////////////////////////////////////////////////// + + // ... + TSkyObjectFace m_FaceCloud; // ϴ ... + D3DXMATRIX m_matWorldCloud, m_matTranslationCloud, m_matTextureCloud; + D3DXVECTOR3 m_v3PositionCloud; + float m_fCloudScaleX, m_fCloudScaleY, m_fCloudHeight; + float m_fCloudTextureScaleX, m_fCloudTextureScaleY; + float m_fCloudScrollSpeedU, m_fCloudScrollSpeedV; + float m_fCloudPositionU, m_fCloudPositionV; + + DWORD m_dwlastTime; + + // ī ڽ ̹... + TGraphicImageInstanceMap m_GraphicImageInstanceMap; + + // Transform... + D3DXMATRIX m_matWorld, m_matTranslation; + D3DXVECTOR3 m_v3Position; + float m_fScaleX, m_fScaleY, m_fScaleZ; + + // ... ӽ .. + unsigned char m_ucRenderMode; + + std::string m_strCurTime; + bool m_bTransitionStarted; + bool m_bSkyMatrixUpdated; + + CGraphicImageInstance m_CloudAlphaImageInstance; +}; + +class CSkyBox : public CSkyObject +{ +public: + CSkyBox(); + virtual ~CSkyBox(); + + void Update(); + void Render(); + void RenderCloud(); + + void Destroy(); + void Unload(); + + void SetSkyBoxScale(const D3DXVECTOR3 & c_rv3Scale); + void SetGradientLevel(BYTE byUpper, BYTE byLower); + void SetFaceTexture( const char* c_szFileName, int iFaceIndex ); + void SetCloudTexture(const char * c_szFileName); + void SetCloudScale(const D3DXVECTOR2 & c_rv2CloudScale); + void SetCloudHeight(float fHeight); + void SetCloudTextureScale(const D3DXVECTOR2 & c_rv2CloudTextureScale); + void SetCloudScrollSpeed(const D3DXVECTOR2 & c_rv2CloudScrollSpeed); + void SetCloudColor(const TGradientColor & c_rColor, const TGradientColor & c_rNextColor, const DWORD & dwTransitionTime); + void Refresh(); + void SetSkyColor(const TVectorGradientColor & c_rColorVector, const TVectorGradientColor & c_rNextColorVector, long lTransitionTime); + void StartTransition(); + +protected: + void SetSkyObjectQuadVertical(TSkyObjectQuadVector * pSkyObjectQuadVector, const D3DXVECTOR2 * c_pv2QuadPoints); + void SetSkyObjectQuadHorizon(TSkyObjectQuadVector * pSkyObjectQuadVector, const D3DXVECTOR3 * c_pv3QuadPoints); + + //void UpdateSkyFaceQuadTransform(D3DXVECTOR3 * c_pv3QuadPoints); + +protected: + unsigned char m_ucVirticalGradientLevelUpper; + unsigned char m_ucVirticalGradientLevelLower; + TSkyObjectFace m_Faces[6]; +}; + +#endif // !defined(AFX_SKYBOX_H__AB5049E1_8F1C_4C35_9406_45EC7EF4AD1B__INCLUDED_) diff --git a/source/EterLib/StateManager.cpp b/source/EterLib/StateManager.cpp new file mode 100644 index 0000000..5f3724a --- /dev/null +++ b/source/EterLib/StateManager.cpp @@ -0,0 +1,769 @@ +#include "StdAfx.h" +#include "StateManager.h" + +//#define StateManager_Assert(a) if (!(a)) puts("assert"#a) +#define StateManager_Assert(a) assert(a) + +struct SLightData +{ + enum + { + LIGHT_NUM = 8, + }; + D3DLIGHT8 m_akD3DLight[LIGHT_NUM]; +} m_kLightData; + + + +void CStateManager::SetLight(DWORD index, CONST D3DLIGHT8* pLight) +{ + assert(indexSetLight(index, pLight); +} + +void CStateManager::GetLight(DWORD index, D3DLIGHT8* pLight) +{ + assert(index<8); + *pLight=m_kLightData.m_akD3DLight[index]; +} + +bool CStateManager::BeginScene() +{ + m_bScene=true; + + D3DXMATRIX m4Proj; + D3DXMATRIX m4View; + D3DXMATRIX m4World; + GetTransform(D3DTS_WORLD, &m4World); + GetTransform(D3DTS_PROJECTION, &m4Proj); + GetTransform(D3DTS_VIEW, &m4View); + SetTransform(D3DTS_WORLD, &m4World); + SetTransform(D3DTS_PROJECTION, &m4Proj); + SetTransform(D3DTS_VIEW, &m4View); + + if (FAILED(m_lpD3DDev->BeginScene())) + return false; + return true; +} + +void CStateManager::EndScene() +{ + m_lpD3DDev->EndScene(); + m_bScene=false; +} + +CStateManager::CStateManager(LPDIRECT3DDEVICE8 lpDevice) : m_lpD3DDev(NULL) +{ + m_bScene = false; + m_dwBestMinFilter = D3DTEXF_LINEAR; + m_dwBestMagFilter = D3DTEXF_LINEAR; + SetDevice(lpDevice); +} + +CStateManager::~CStateManager() +{ + if (m_lpD3DDev) + { + m_lpD3DDev->Release(); + m_lpD3DDev = NULL; + } +} + +void CStateManager::SetDevice(LPDIRECT3DDEVICE8 lpDevice) +{ + StateManager_Assert(lpDevice); + lpDevice->AddRef(); + + if (m_lpD3DDev) + { + m_lpD3DDev->Release(); + m_lpD3DDev = NULL; + } + + m_lpD3DDev = lpDevice; + + D3DCAPS8 d3dCaps; + m_lpD3DDev->GetDeviceCaps(&d3dCaps); + + if (d3dCaps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC) + m_dwBestMagFilter = D3DTEXF_ANISOTROPIC; + else + m_dwBestMagFilter = D3DTEXF_LINEAR; + + if (d3dCaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC) + m_dwBestMinFilter = D3DTEXF_ANISOTROPIC; + else + m_dwBestMinFilter = D3DTEXF_LINEAR; + + DWORD dwMax = d3dCaps.MaxAnisotropy; + dwMax = dwMax < 4 ? dwMax : 4; + + for (int i = 0; i < 8; ++i) + m_lpD3DDev->SetTextureStageState(i, D3DTSS_MAXANISOTROPY, dwMax); + + SetDefaultState(); +} + +void CStateManager::SetBestFiltering(DWORD dwStage) +{ + SetTextureStageState(dwStage, D3DTSS_MINFILTER, m_dwBestMinFilter); + SetTextureStageState(dwStage, D3DTSS_MAGFILTER, m_dwBestMagFilter); + SetTextureStageState(dwStage, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); +} + +void CStateManager::Restore() +{ + int i, j; + + m_bForce = true; + + for (i = 0; i < STATEMANAGER_MAX_RENDERSTATES; ++i) + SetRenderState(D3DRENDERSTATETYPE(i), m_CurrentState.m_RenderStates[i]); + + for (i = 0; i < STATEMANAGER_MAX_STAGES; ++i) + for (j = 0; j < STATEMANAGER_MAX_TEXTURESTATES; ++j) + SetTextureStageState(i, D3DTEXTURESTAGESTATETYPE(j), m_CurrentState.m_TextureStates[i][j]); + + for (i = 0; i < STATEMANAGER_MAX_STAGES; ++i) + SetTexture(i, m_CurrentState.m_Textures[i]); + + m_bForce = false; +} + +void CStateManager::SetDefaultState() +{ + m_CurrentState.ResetState(); + m_CopyState.ResetState(); + m_ChipState.ResetState(); + + m_bScene = false; + m_bForce = true; + + D3DXMATRIX Identity; + D3DXMatrixIdentity(&Identity); + + SetTransform(D3DTS_WORLD, &Identity); + SetTransform(D3DTS_VIEW, &Identity); + SetTransform(D3DTS_PROJECTION, &Identity); + + D3DMATERIAL8 DefaultMat; + ZeroMemory(&DefaultMat, sizeof(D3DMATERIAL8)); + + DefaultMat.Diffuse.r = 1.0f; + DefaultMat.Diffuse.g = 1.0f; + DefaultMat.Diffuse.b = 1.0f; + DefaultMat.Diffuse.a = 1.0f; + DefaultMat.Ambient.r = 1.0f; + DefaultMat.Ambient.g = 1.0f; + DefaultMat.Ambient.b = 1.0f; + DefaultMat.Ambient.a = 1.0f; + DefaultMat.Emissive.r = 0.0f; + DefaultMat.Emissive.g = 0.0f; + DefaultMat.Emissive.b = 0.0f; + DefaultMat.Emissive.a = 0.0f; + DefaultMat.Specular.r = 0.0f; + DefaultMat.Specular.g = 0.0f; + DefaultMat.Specular.b = 0.0f; + DefaultMat.Specular.a = 0.0f; + DefaultMat.Power = 0.0f; + + SetMaterial(&DefaultMat); + + SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL); + SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL); + SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL); + SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL); + + SetRenderState(D3DRS_LINEPATTERN, 0xFFFFFFFF); + SetRenderState(D3DRS_LASTPIXEL, FALSE); + SetRenderState(D3DRS_ALPHAREF, 1); + SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); + SetRenderState(D3DRS_ZVISIBLE, FALSE); + SetRenderState(D3DRS_FOGSTART, 0); + SetRenderState(D3DRS_FOGEND, 0); + SetRenderState(D3DRS_FOGDENSITY, 0); + SetRenderState(D3DRS_EDGEANTIALIAS, FALSE); + SetRenderState(D3DRS_ZBIAS, 0); + SetRenderState(D3DRS_STENCILWRITEMASK, 0xFFFFFFFF); + SetRenderState(D3DRS_AMBIENT, 0x00000000); + SetRenderState(D3DRS_LOCALVIEWER, FALSE); + SetRenderState(D3DRS_NORMALIZENORMALS, FALSE); + SetRenderState(D3DRS_VERTEXBLEND, D3DVBF_DISABLE); + SetRenderState(D3DRS_CLIPPLANEENABLE, 0); + SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING, FALSE); + SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, FALSE); + SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF); + SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE); + SetRenderState(D3DRS_COLORWRITEENABLE, 0xFFFFFFFF); + SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); + SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); + SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); + SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + SetRenderState(D3DRS_FOGENABLE, FALSE); + SetRenderState(D3DRS_FOGCOLOR, 0xFF000000); + SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_NONE); + SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR); + SetRenderState(D3DRS_RANGEFOGENABLE, FALSE); + SetRenderState(D3DRS_ZENABLE, TRUE); + SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); + SetRenderState(D3DRS_ZWRITEENABLE, TRUE); + SetRenderState(D3DRS_DITHERENABLE, TRUE); + SetRenderState(D3DRS_STENCILENABLE, FALSE); + SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + SetRenderState(D3DRS_CLIPPING, TRUE); + SetRenderState(D3DRS_LIGHTING, FALSE); + SetRenderState(D3DRS_SPECULARENABLE, FALSE); + SetRenderState(D3DRS_COLORVERTEX, FALSE); + SetRenderState(D3DRS_WRAP0, 0); + SetRenderState(D3DRS_WRAP1, 0); + SetRenderState(D3DRS_WRAP2, 0); + SetRenderState(D3DRS_WRAP3, 0); + SetRenderState(D3DRS_WRAP4, 0); + SetRenderState(D3DRS_WRAP5, 0); + SetRenderState(D3DRS_WRAP6, 0); + SetRenderState(D3DRS_WRAP7, 0); + + SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT); + SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_CURRENT); + SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + + SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); + SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + + SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE); + SetTextureStageState(2, D3DTSS_COLORARG1, D3DTA_TEXTURE); + SetTextureStageState(2, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + SetTextureStageState(2, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + SetTextureStageState(2, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + + SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE); + SetTextureStageState(3, D3DTSS_COLORARG1, D3DTA_TEXTURE); + SetTextureStageState(3, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + SetTextureStageState(3, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + SetTextureStageState(3, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + + SetTextureStageState(4, D3DTSS_COLOROP, D3DTOP_DISABLE); + SetTextureStageState(4, D3DTSS_COLORARG1, D3DTA_TEXTURE); + SetTextureStageState(4, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + SetTextureStageState(4, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + SetTextureStageState(4, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + SetTextureStageState(4, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + + SetTextureStageState(5, D3DTSS_COLOROP, D3DTOP_DISABLE); + SetTextureStageState(5, D3DTSS_COLORARG1, D3DTA_TEXTURE); + SetTextureStageState(5, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + SetTextureStageState(5, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + SetTextureStageState(5, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + SetTextureStageState(5, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + + SetTextureStageState(6, D3DTSS_COLOROP, D3DTOP_DISABLE); + SetTextureStageState(6, D3DTSS_COLORARG1, D3DTA_TEXTURE); + SetTextureStageState(6, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + SetTextureStageState(6, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + SetTextureStageState(6, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + SetTextureStageState(6, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + + SetTextureStageState(7, D3DTSS_COLOROP, D3DTOP_DISABLE); + SetTextureStageState(7, D3DTSS_COLORARG1, D3DTA_TEXTURE); + SetTextureStageState(7, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + SetTextureStageState(7, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + SetTextureStageState(7, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + SetTextureStageState(7, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + + SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0); + SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); + SetTextureStageState(2, D3DTSS_TEXCOORDINDEX, 2); + SetTextureStageState(3, D3DTSS_TEXCOORDINDEX, 3); + SetTextureStageState(4, D3DTSS_TEXCOORDINDEX, 4); + SetTextureStageState(5, D3DTSS_TEXCOORDINDEX, 5); + SetTextureStageState(6, D3DTSS_TEXCOORDINDEX, 6); + SetTextureStageState(7, D3DTSS_TEXCOORDINDEX, 7); + + SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); + + SetTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + SetTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); + + SetTextureStageState(2, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + SetTextureStageState(2, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + SetTextureStageState(2, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); + + SetTextureStageState(3, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + SetTextureStageState(3, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + SetTextureStageState(3, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); + + SetTextureStageState(4, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + SetTextureStageState(4, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + SetTextureStageState(4, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); + + SetTextureStageState(5, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + SetTextureStageState(5, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + SetTextureStageState(5, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); + + SetTextureStageState(6, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + SetTextureStageState(6, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + SetTextureStageState(6, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); + + SetTextureStageState(7, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + SetTextureStageState(7, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + SetTextureStageState(7, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); + + SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); + SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); + SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); + SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); + SetTextureStageState(2, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); + SetTextureStageState(2, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); + SetTextureStageState(3, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); + SetTextureStageState(3, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); + SetTextureStageState(4, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); + SetTextureStageState(4, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); + SetTextureStageState(5, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); + SetTextureStageState(5, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); + SetTextureStageState(6, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); + SetTextureStageState(6, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); + SetTextureStageState(7, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); + SetTextureStageState(7, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); + + SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, 0); + SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, 0); + SetTextureStageState(2, D3DTSS_TEXTURETRANSFORMFLAGS, 0); + SetTextureStageState(3, D3DTSS_TEXTURETRANSFORMFLAGS, 0); + SetTextureStageState(4, D3DTSS_TEXTURETRANSFORMFLAGS, 0); + SetTextureStageState(5, D3DTSS_TEXTURETRANSFORMFLAGS, 0); + SetTextureStageState(6, D3DTSS_TEXTURETRANSFORMFLAGS, 0); + SetTextureStageState(7, D3DTSS_TEXTURETRANSFORMFLAGS, 0); + + SetTexture(0, NULL); + SetTexture(1, NULL); + SetTexture(2, NULL); + SetTexture(3, NULL); + SetTexture(4, NULL); + SetTexture(5, NULL); + SetTexture(6, NULL); + SetTexture(7, NULL); + + SetPixelShader(0); + SetVertexShader(D3DFVF_XYZ); + + D3DXVECTOR4 av4Null[STATEMANAGER_MAX_VCONSTANTS]; + memset(av4Null, 0, sizeof(av4Null)); + SetVertexShaderConstant(0, av4Null, STATEMANAGER_MAX_VCONSTANTS); + SetPixelShaderConstant(0, av4Null, STATEMANAGER_MAX_PCONSTANTS); + + m_bForce = false; + +#ifdef _DEBUG + int i, j; + for (i = 0; i < STATEMANAGER_MAX_RENDERSTATES; i++) + m_bRenderStateSavingFlag[i] = FALSE; + + for (j = 0; j < STATEMANAGER_MAX_TRANSFORMSTATES; j++) + m_bTransformSavingFlag[j] = FALSE; + + for (j = 0; j < STATEMANAGER_MAX_STAGES; ++j) + for (i = 0; i < STATEMANAGER_MAX_TEXTURESTATES; ++i) + m_bTextureStageStateSavingFlag[j][i] = FALSE; +#endif _DEBUG +} + +// Material +void CStateManager::SaveMaterial() +{ + m_CopyState.m_D3DMaterial = m_CurrentState.m_D3DMaterial; +} + +void CStateManager::SaveMaterial(const D3DMATERIAL8 * pMaterial) +{ + // Check that we have set this up before, if not, the default is this. + m_CopyState.m_D3DMaterial = m_CurrentState.m_D3DMaterial; + SetMaterial(pMaterial); +} + +void CStateManager::RestoreMaterial() +{ + SetMaterial(&m_CopyState.m_D3DMaterial); +} + +void CStateManager::SetMaterial(const D3DMATERIAL8 * pMaterial) +{ + m_lpD3DDev->SetMaterial(pMaterial); + m_CurrentState.m_D3DMaterial = *pMaterial; +} + +void CStateManager::GetMaterial(D3DMATERIAL8 * pMaterial) +{ + // Set the renderstate and remember it. + *pMaterial = m_CurrentState.m_D3DMaterial; +} + +// Renderstates +DWORD CStateManager::GetRenderState(D3DRENDERSTATETYPE Type) +{ + return m_CurrentState.m_RenderStates[Type]; +} + +void CStateManager::SaveRenderState(D3DRENDERSTATETYPE Type, DWORD dwValue) +{ +#ifdef _DEBUG + if (m_bRenderStateSavingFlag[Type]) + { + Tracef(" CStateManager::SaveRenderState - This render state is already saved [%d, %d]\n", Type, dwValue); + StateManager_Assert(!" This render state is already saved!"); + } + m_bRenderStateSavingFlag[Type] = TRUE; +#endif _DEBUG + + // Check that we have set this up before, if not, the default is this. + m_CopyState.m_RenderStates[Type] = m_CurrentState.m_RenderStates[Type]; + SetRenderState(Type, dwValue); +} + +void CStateManager::RestoreRenderState(D3DRENDERSTATETYPE Type) +{ +#ifdef _DEBUG + if (!m_bRenderStateSavingFlag[Type]) + { + Tracef(" CStateManager::SaveRenderState - This render state was not saved [%d, %d]\n", Type); + StateManager_Assert(!" This render state was not saved!"); + } + m_bRenderStateSavingFlag[Type] = FALSE; +#endif _DEBUG + + SetRenderState(Type, m_CopyState.m_RenderStates[Type]); +} + +void CStateManager::SetRenderState(D3DRENDERSTATETYPE Type, DWORD Value) +{ + if (m_CurrentState.m_RenderStates[Type] == Value) + return; + + m_lpD3DDev->SetRenderState(Type, Value); + m_CurrentState.m_RenderStates[Type] = Value; +} + +void CStateManager::GetRenderState(D3DRENDERSTATETYPE Type, DWORD * pdwValue) +{ + *pdwValue = m_CurrentState.m_RenderStates[Type]; +} + +// Textures +void CStateManager::SaveTexture(DWORD dwStage, LPDIRECT3DBASETEXTURE8 pTexture) +{ + // Check that we have set this up before, if not, the default is this. + m_CopyState.m_Textures[dwStage] = m_CurrentState.m_Textures[dwStage]; + SetTexture(dwStage, pTexture); +} + +void CStateManager::RestoreTexture(DWORD dwStage) +{ + SetTexture(dwStage, m_CopyState.m_Textures[dwStage]); +} + +void CStateManager::SetTexture(DWORD dwStage, LPDIRECT3DBASETEXTURE8 pTexture) +{ + if (pTexture == m_CurrentState.m_Textures[dwStage]) + return; + + m_lpD3DDev->SetTexture(dwStage, pTexture); + m_CurrentState.m_Textures[dwStage] = pTexture; +} + +void CStateManager::GetTexture(DWORD dwStage, LPDIRECT3DBASETEXTURE8 * ppTexture) +{ + *ppTexture = m_CurrentState.m_Textures[dwStage]; +} + +// Texture stage states +void CStateManager::SaveTextureStageState(DWORD dwStage,D3DTEXTURESTAGESTATETYPE Type, DWORD dwValue) +{ + // Check that we have set this up before, if not, the default is this. +#ifdef _DEBUG + if (m_bTextureStageStateSavingFlag[dwStage][Type]) + { + Tracef(" CStateManager::SaveTextureStageState - This texture stage state is already saved [%d, %d]\n", dwStage, Type); + StateManager_Assert(!" This texture stage state is already saved!"); + } + m_bTextureStageStateSavingFlag[dwStage][Type] = TRUE; +#endif _DEBUG + m_CopyState.m_TextureStates[dwStage][Type] = m_CurrentState.m_TextureStates[dwStage][Type]; + SetTextureStageState(dwStage, Type, dwValue); +} + +void CStateManager::RestoreTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type) +{ +#ifdef _DEBUG + if (!m_bTextureStageStateSavingFlag[dwStage][Type]) + { + Tracef(" CStateManager::RestoreTextureStageState - This texture stage state was not saved [%d, %d]\n", dwStage, Type); + StateManager_Assert(!" This texture stage state was not saved!"); + } + m_bTextureStageStateSavingFlag[dwStage][Type] = FALSE; +#endif _DEBUG + SetTextureStageState(dwStage, Type, m_CopyState.m_TextureStates[dwStage][Type]); +} + +void CStateManager::SetTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type, DWORD dwValue) +{ + if (m_CurrentState.m_TextureStates[dwStage][Type] == dwValue) + return; + + m_lpD3DDev->SetTextureStageState(dwStage, Type, dwValue); + m_CurrentState.m_TextureStates[dwStage][Type] = dwValue; +} + +void CStateManager::GetTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type, DWORD * pdwValue) +{ + *pdwValue = m_CurrentState.m_TextureStates[dwStage][Type]; +} + +// Vertex Shader +void CStateManager::SaveVertexShader(DWORD dwShader) +{ + m_CopyState.m_dwVertexShader = m_CurrentState.m_dwVertexShader; + SetVertexShader(dwShader); +} + +void CStateManager::RestoreVertexShader() +{ + SetVertexShader(m_CopyState.m_dwVertexShader); +} + +void CStateManager::SetVertexShader(DWORD dwShader) +{ + if (m_CurrentState.m_dwVertexShader == dwShader) + return; + + m_lpD3DDev->SetVertexShader(dwShader); + m_CurrentState.m_dwVertexShader = dwShader; +} + +void CStateManager::GetVertexShader(DWORD * pdwShader) +{ + *pdwShader = m_CurrentState.m_dwVertexShader; +} + +// Pixel Shader +void CStateManager::SavePixelShader(DWORD dwShader) +{ + m_CopyState.m_dwPixelShader = m_CurrentState.m_dwPixelShader; + SetPixelShader(dwShader); +} + +void CStateManager::RestorePixelShader() +{ + SetPixelShader(m_CopyState.m_dwPixelShader); +} + +void CStateManager::SetPixelShader(DWORD dwShader) +{ + if (m_CurrentState.m_dwPixelShader == dwShader) + return; + + m_lpD3DDev->SetPixelShader(dwShader); + m_CurrentState.m_dwPixelShader = dwShader; +} + +void CStateManager::GetPixelShader(DWORD * pdwShader) +{ + *pdwShader = m_CurrentState.m_dwPixelShader; +} + +// *** These states are cached, but not protected from multiple sends of the same value. +// Transform +void CStateManager::SaveTransform(D3DTRANSFORMSTATETYPE Type, const D3DMATRIX* pMatrix) +{ +#ifdef _DEBUG + if (m_bTransformSavingFlag[Type]) + { + Tracef(" CStateManager::SaveTransform - This transform is already saved [%d]\n", Type); + StateManager_Assert(!" This trasform is already saved!"); + } + m_bTransformSavingFlag[Type] = TRUE; +#endif _DEBUG + + m_CopyState.m_Matrices[Type] = m_CurrentState.m_Matrices[Type]; + SetTransform(Type, (D3DXMATRIX *)pMatrix); +} + +void CStateManager::RestoreTransform(D3DTRANSFORMSTATETYPE Type) +{ +#ifdef _DEBUG + if (!m_bTransformSavingFlag[Type]) + { + Tracef(" CStateManager::RestoreTransform - This transform was not saved [%d]\n", Type); + StateManager_Assert(!" This render state was not saved!"); + } + m_bTransformSavingFlag[Type] = FALSE; +#endif _DEBUG + + SetTransform(Type, &m_CopyState.m_Matrices[Type]); +} + +// Don't cache-check the transform. To much to do +void CStateManager::SetTransform(D3DTRANSFORMSTATETYPE Type, const D3DMATRIX* pMatrix) +{ + if (m_bScene) + { + m_lpD3DDev->SetTransform(Type, pMatrix); + } + else + { + assert(D3DTS_VIEW==Type || D3DTS_PROJECTION==Type || D3DTS_WORLD==Type); + } + + m_CurrentState.m_Matrices[Type] = *pMatrix; +} + +void CStateManager::GetTransform(D3DTRANSFORMSTATETYPE Type, D3DMATRIX * pMatrix) +{ + *pMatrix = m_CurrentState.m_Matrices[Type]; +} + +// SetVertexShaderConstant +void CStateManager::SaveVertexShaderConstant(DWORD dwRegister,CONST void* pConstantData,DWORD dwConstantCount) +{ + DWORD i; + + for (i = 0; i < dwConstantCount; i++) + { + StateManager_Assert((dwRegister + i) < STATEMANAGER_MAX_VCONSTANTS); + m_CopyState.m_VertexShaderConstants[dwRegister + i] = m_CurrentState.m_VertexShaderConstants[dwRegister + i]; + } + + SetVertexShaderConstant(dwRegister, pConstantData, dwConstantCount); +} + +void CStateManager::RestoreVertexShaderConstant(DWORD dwRegister, DWORD dwConstantCount) +{ + SetVertexShaderConstant(dwRegister, &m_CopyState.m_VertexShaderConstants[dwRegister], dwConstantCount); +} + +void CStateManager::SetVertexShaderConstant(DWORD dwRegister,CONST void* pConstantData,DWORD dwConstantCount) +{ + m_lpD3DDev->SetVertexShaderConstant(dwRegister, pConstantData, dwConstantCount); + + // Set the renderstate and remember it. + for (DWORD i = 0; i < dwConstantCount; i++) + { + StateManager_Assert((dwRegister + i) < STATEMANAGER_MAX_VCONSTANTS); + m_CurrentState.m_VertexShaderConstants[dwRegister + i] = *(((D3DXVECTOR4*)pConstantData) + i); + } +} + +// SetPixelShaderConstant +void CStateManager::SavePixelShaderConstant(DWORD dwRegister,CONST void* pConstantData,DWORD dwConstantCount) +{ + DWORD i; + + for (i = 0; i < dwConstantCount; i++) + { + StateManager_Assert((dwRegister + i) < STATEMANAGER_MAX_VCONSTANTS); + m_CopyState.m_PixelShaderConstants[dwRegister + i] = *(((D3DXVECTOR4*)pConstantData) + i); + } + + SetPixelShaderConstant(dwRegister, pConstantData, dwConstantCount); +} + +void CStateManager::RestorePixelShaderConstant(DWORD dwRegister, DWORD dwConstantCount) +{ + SetPixelShaderConstant(dwRegister, &m_CopyState.m_PixelShaderConstants[dwRegister], dwConstantCount); +} + +void CStateManager::SetPixelShaderConstant(DWORD dwRegister,CONST void* pConstantData,DWORD dwConstantCount) +{ + m_lpD3DDev->SetPixelShaderConstant(dwRegister, pConstantData, dwConstantCount); + + // Set the renderstate and remember it. + for (DWORD i = 0; i < dwConstantCount; i++) + { + StateManager_Assert((dwRegister + i) < STATEMANAGER_MAX_VCONSTANTS); + m_CurrentState.m_PixelShaderConstants[dwRegister + i] = *(((D3DXVECTOR4*)pConstantData) + i); + } +} + +void CStateManager::SaveStreamSource(UINT StreamNumber, LPDIRECT3DVERTEXBUFFER8 pStreamData,UINT Stride) +{ + // Check that we have set this up before, if not, the default is this. + m_CopyState.m_StreamData[StreamNumber] = m_CurrentState.m_StreamData[StreamNumber]; + SetStreamSource(StreamNumber, pStreamData, Stride); +} + +void CStateManager::RestoreStreamSource(UINT StreamNumber) +{ + SetStreamSource(StreamNumber, + m_CopyState.m_StreamData[StreamNumber].m_lpStreamData, + m_CopyState.m_StreamData[StreamNumber].m_Stride); +} + +void CStateManager::SetStreamSource(UINT StreamNumber, LPDIRECT3DVERTEXBUFFER8 pStreamData, UINT Stride) +{ + CStreamData kStreamData(pStreamData, Stride); + if (m_CurrentState.m_StreamData[StreamNumber] == kStreamData) + return; + + m_lpD3DDev->SetStreamSource(StreamNumber, pStreamData, Stride); + m_CurrentState.m_StreamData[StreamNumber] = kStreamData; +} + +void CStateManager::SaveIndices(LPDIRECT3DINDEXBUFFER8 pIndexData, UINT BaseVertexIndex) +{ + m_CopyState.m_IndexData = m_CurrentState.m_IndexData; + SetIndices(pIndexData, BaseVertexIndex); +} + +void CStateManager::RestoreIndices() +{ + SetIndices(m_CopyState.m_IndexData.m_lpIndexData, m_CopyState.m_IndexData.m_BaseVertexIndex); +} + +void CStateManager::SetIndices(LPDIRECT3DINDEXBUFFER8 pIndexData, UINT BaseVertexIndex) +{ + CIndexData kIndexData(pIndexData, BaseVertexIndex); + + if (m_CurrentState.m_IndexData == kIndexData) + return; + + m_lpD3DDev->SetIndices(pIndexData, BaseVertexIndex); + m_CurrentState.m_IndexData = kIndexData; +} + +HRESULT CStateManager::DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) +{ + return (m_lpD3DDev->DrawPrimitive(PrimitiveType, StartVertex, PrimitiveCount)); +} + +HRESULT CStateManager::DrawPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, const void* pVertexStreamZeroData, UINT VertexStreamZeroStride) +{ + m_CurrentState.m_StreamData[0] = NULL; + return (m_lpD3DDev->DrawPrimitiveUP(PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride)); +} + +HRESULT CStateManager::DrawIndexedPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT minIndex, UINT NumVertices, UINT startIndex, UINT primCount) +{ + return (m_lpD3DDev->DrawIndexedPrimitive(PrimitiveType, minIndex, NumVertices, startIndex, primCount)); +} + +HRESULT CStateManager::DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertexIndices, UINT PrimitiveCount, CONST void * pIndexData, D3DFORMAT IndexDataFormat, CONST void * pVertexStreamZeroData, UINT VertexStreamZeroStride) +{ + m_CurrentState.m_IndexData = NULL; + m_CurrentState.m_StreamData[0] = NULL; + return (m_lpD3DDev->DrawIndexedPrimitiveUP(PrimitiveType, MinVertexIndex, NumVertexIndices, PrimitiveCount, pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride)); +} diff --git a/source/EterLib/StateManager.h b/source/EterLib/StateManager.h new file mode 100644 index 0000000..01dd9b4 --- /dev/null +++ b/source/EterLib/StateManager.h @@ -0,0 +1,341 @@ +/****************************************************************************** + + Copyright (C) 1999, 2000 NVIDIA Corporation + + This file is provided without support, instruction, or implied warranty of any + kind. NVIDIA makes no guarantee of its fitness for a particular purpose and is + not liable under any circumstances for any damages or loss whatsoever arising + from the use or inability to use this file or items derived from it. + + Comments: + + A simple class to manage rendering state. Created as a singleton. + Create it as a static global, or with new. It doesn't matter as long as it is created + before you use the CStateManager::GetSingleton() API to get a reference to it. + + Call it with STATEMANAGER.SetRenderState(...) + Call it with STATEMANAGER.SetTextureStageState(...), etc. + + Call the 'Save' versions of the function if you want to deviate from the current state. + Call the 'Restore' version to retrieve the last Save. + + There are two levels of caching: + - All Sets/Saves/Restores are tracked for redundancy. This reduces the size of the batch to + be flushed + - The flush function is called before rendering, and only copies state that is + different from the current chip state. + + If you get an assert it is probably because an API call failed. + + See NVLink for a good example of how this class is used. + + Don't be afraid of the vector being used to track the flush batch. It will grow as big as + it needs to be and then stop, so it shouldn't be reallocated. + + The state manager holds a reference to the d3d device. + + - cmaughan@nvidia.com + +******************************************************************************/ + +#ifndef __CSTATEMANAGER_H +#define __CSTATEMANAGER_H + +#include +#include + +#include + +#include "../eterBase/Singleton.h" + +#define CHECK_D3DAPI(a) \ +{ \ + HRESULT hr = (a); \ + \ + if (hr != S_OK) \ + assert(!#a); \ +} + +static const DWORD STATEMANAGER_MAX_RENDERSTATES = 256; +static const DWORD STATEMANAGER_MAX_TEXTURESTATES = 128; +static const DWORD STATEMANAGER_MAX_STAGES = 8; +static const DWORD STATEMANAGER_MAX_VCONSTANTS = 96; +static const DWORD STATEMANAGER_MAX_PCONSTANTS = 8; +static const DWORD STATEMANAGER_MAX_TRANSFORMSTATES = 300; // World1 lives way up there... +static const DWORD STATEMANAGER_MAX_STREAMS = 16; + +class CStreamData +{ + public: + CStreamData(LPDIRECT3DVERTEXBUFFER8 pStreamData = NULL, UINT Stride = 0) : m_lpStreamData(pStreamData), m_Stride(Stride) + { + } + + bool operator == (const CStreamData& rhs) const + { + return ((m_lpStreamData == rhs.m_lpStreamData) && (m_Stride == rhs.m_Stride)); + } + + LPDIRECT3DVERTEXBUFFER8 m_lpStreamData; + UINT m_Stride; +}; + +class CIndexData +{ + public: + CIndexData(LPDIRECT3DINDEXBUFFER8 pIndexData = NULL, UINT BaseVertexIndex = 0) + : m_lpIndexData(pIndexData), + m_BaseVertexIndex(BaseVertexIndex) + { + } + + bool operator == (const CIndexData& rhs) const + { + return ((m_lpIndexData == rhs.m_lpIndexData) && (m_BaseVertexIndex == rhs.m_BaseVertexIndex)); + } + + LPDIRECT3DINDEXBUFFER8 m_lpIndexData; + UINT m_BaseVertexIndex; +}; + +// State types managed by the class +typedef enum eStateType +{ + STATE_MATERIAL = 0, + STATE_RENDER, + STATE_TEXTURE, + STATE_TEXTURESTAGE, + STATE_VSHADER, + STATE_PSHADER, + STATE_TRANSFORM, + STATE_VCONSTANT, + STATE_PCONSTANT, + STATE_STREAM, + STATE_INDEX +} eStateType; + +class CStateID +{ + public: + CStateID(eStateType Type, DWORD dwValue0 = 0, DWORD dwValue1 = 0) + : m_Type(Type), + m_dwValue0(dwValue0), + m_dwValue1(dwValue1) + { + } + + CStateID(eStateType Type, DWORD dwStage, D3DTEXTURESTAGESTATETYPE StageType) + : m_Type(Type), + m_dwStage(dwStage), + m_TextureStageStateType(StageType) + { + } + + CStateID(eStateType Type, D3DRENDERSTATETYPE RenderType) + : m_Type(Type), + m_RenderStateType(RenderType) + { + } + + eStateType m_Type; + + union + { + DWORD m_dwValue0; + DWORD m_dwStage; + D3DRENDERSTATETYPE m_RenderStateType; + D3DTRANSFORMSTATETYPE m_TransformStateType; + }; + + union + { + DWORD m_dwValue1; + D3DTEXTURESTAGESTATETYPE m_TextureStageStateType; + }; +}; + +typedef std::vector TStateID; + +class CStateManagerState +{ + public: + CStateManagerState() + { + } + + void ResetState() + { + DWORD i, y; + + for (i = 0; i < STATEMANAGER_MAX_RENDERSTATES; i++) + m_RenderStates[i] = 0x7FFFFFFF; + + for (i = 0; i < STATEMANAGER_MAX_STAGES; i++) + for (y = 0; y < STATEMANAGER_MAX_TEXTURESTATES; y++) + m_TextureStates[i][y] = 0x7FFFFFFF; + + for (i = 0; i < STATEMANAGER_MAX_STREAMS; i++) + m_StreamData[i] = CStreamData(); + + m_IndexData = CIndexData(); + + for (i = 0; i < STATEMANAGER_MAX_STAGES; i++) + m_Textures[i] = NULL; + + // Matrices and constants are not cached, just restored. It's silly to check all the + // data elements (by which time the driver could have been sent them). + for (i = 0; i < STATEMANAGER_MAX_TRANSFORMSTATES; i++) + D3DXMatrixIdentity(&m_Matrices[i]); + + for (i = 0; i < STATEMANAGER_MAX_VCONSTANTS; i++) + m_VertexShaderConstants[i] = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f); + + for (i = 0; i < STATEMANAGER_MAX_PCONSTANTS; i++) + m_PixelShaderConstants[i] = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f); + + m_dwPixelShader = 0; + m_dwVertexShader = D3DFVF_XYZ; + + ZeroMemory(&m_Matrices, sizeof(D3DXMATRIX) * STATEMANAGER_MAX_TRANSFORMSTATES); + } + + // Renderstates + DWORD m_RenderStates[STATEMANAGER_MAX_RENDERSTATES]; + + // Texture stage states + DWORD m_TextureStates[STATEMANAGER_MAX_STAGES][STATEMANAGER_MAX_TEXTURESTATES]; + + // Vertex shader constants + D3DXVECTOR4 m_VertexShaderConstants[STATEMANAGER_MAX_VCONSTANTS]; + + // Pixel shader constants + D3DXVECTOR4 m_PixelShaderConstants[STATEMANAGER_MAX_PCONSTANTS]; + + // Textures + LPDIRECT3DBASETEXTURE8 m_Textures[STATEMANAGER_MAX_STAGES]; + + // Shaders + DWORD m_dwPixelShader; + DWORD m_dwVertexShader; + + D3DXMATRIX m_Matrices[STATEMANAGER_MAX_TRANSFORMSTATES]; + + D3DMATERIAL8 m_D3DMaterial; + + CStreamData m_StreamData[STATEMANAGER_MAX_STREAMS]; + CIndexData m_IndexData; +}; + +class CStateManager : public CSingleton +{ + public: + CStateManager(LPDIRECT3DDEVICE8 lpDevice); + virtual ~CStateManager(); + + void SetDefaultState(); + void Restore(); + + bool BeginScene(); + void EndScene(); + + // Material + void SaveMaterial(); + void SaveMaterial(const D3DMATERIAL8 * pMaterial); + void RestoreMaterial(); + void SetMaterial(const D3DMATERIAL8 * pMaterial); + void GetMaterial(D3DMATERIAL8 * pMaterial); + + void SetLight(DWORD index, CONST D3DLIGHT8* pLight); + void GetLight(DWORD index, D3DLIGHT8* pLight); + + // Renderstates + void SaveRenderState(D3DRENDERSTATETYPE Type, DWORD dwValue); + void RestoreRenderState(D3DRENDERSTATETYPE Type); + void SetRenderState(D3DRENDERSTATETYPE Type, DWORD Value); + void GetRenderState(D3DRENDERSTATETYPE Type, DWORD * pdwValue); + + // Textures + void SaveTexture(DWORD dwStage, LPDIRECT3DBASETEXTURE8 pTexture); + void RestoreTexture(DWORD dwStage); + void SetTexture(DWORD dwStage, LPDIRECT3DBASETEXTURE8 pTexture); + void GetTexture(DWORD dwStage, LPDIRECT3DBASETEXTURE8 * ppTexture); + + // Texture stage states + void SaveTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type, DWORD dwValue); + void RestoreTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type); + void SetTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type, DWORD dwValue); + void GetTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type, DWORD * pdwValue); + void SetBestFiltering(DWORD dwStage); // if possible set anisotropy filtering, or use trilinear + + // Vertex Shader + void SaveVertexShader(DWORD dwShader); + void RestoreVertexShader(); + void SetVertexShader(DWORD dwShader); + void GetVertexShader(DWORD * pdwShader); + + // Pixel Shader + void SavePixelShader(DWORD dwShader); + void RestorePixelShader(); + void SetPixelShader(DWORD dwShader); + void GetPixelShader(DWORD * pdwShader); + + // *** These states are cached, but not protected from multiple sends of the same value. + // Transform + void SaveTransform(D3DTRANSFORMSTATETYPE Transform, const D3DMATRIX* pMatrix); + void RestoreTransform(D3DTRANSFORMSTATETYPE Transform); + + // Don't cache-check the transform. To much to do + void SetTransform(D3DTRANSFORMSTATETYPE Type, const D3DMATRIX* pMatrix); + void GetTransform(D3DTRANSFORMSTATETYPE Type, D3DMATRIX * pMatrix); + + // SetVertexShaderConstant + void SaveVertexShaderConstant(DWORD dwRegister, CONST void* pConstantData, DWORD dwConstantCount); + void RestoreVertexShaderConstant(DWORD dwRegister, DWORD dwConstantCount); + void SetVertexShaderConstant(DWORD dwRegister, CONST void* pConstantData, DWORD dwConstantCount); + + // SetPixelShaderConstant + void SavePixelShaderConstant(DWORD dwRegister, CONST void* pConstantData, DWORD dwConstantCount); + void RestorePixelShaderConstant(DWORD dwRegister, DWORD dwConstantCount); + void SetPixelShaderConstant(DWORD dwRegister, CONST void* pConstantData, DWORD dwConstantCount); + + void SaveStreamSource(UINT StreamNumber, LPDIRECT3DVERTEXBUFFER8 pStreamData, UINT Stride); + void RestoreStreamSource(UINT StreamNumber); + void SetStreamSource(UINT StreamNumber, LPDIRECT3DVERTEXBUFFER8 pStreamData, UINT Stride); + + void SaveIndices(LPDIRECT3DINDEXBUFFER8 pIndexData, UINT BaseVertexIndex); + void RestoreIndices(); + void SetIndices(LPDIRECT3DINDEXBUFFER8 pIndexData,UINT BaseVertexIndex); + + HRESULT DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount); + HRESULT DrawPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, const void* pVertexStreamZeroData, UINT VertexStreamZeroStride); + HRESULT DrawIndexedPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT minIndex, UINT NumVertices, UINT startIndex, UINT primCount); + HRESULT DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertexIndices, UINT PrimitiveCount, CONST void * pIndexData, D3DFORMAT IndexDataFormat, CONST void * pVertexStreamZeroData, UINT VertexStreamZeroStride); + + // Codes For Debug + DWORD GetRenderState(D3DRENDERSTATETYPE Type); + + private: + void SetDevice(LPDIRECT3DDEVICE8 lpDevice); + + private: + CStateManagerState m_ChipState; + CStateManagerState m_CurrentState; + CStateManagerState m_CopyState; + TStateID m_DirtyStates; + bool m_bForce; + bool m_bScene; + DWORD m_dwBestMinFilter; + DWORD m_dwBestMagFilter; + LPDIRECT3DDEVICE8 m_lpD3DDev; + +#ifdef _DEBUG + // Saving Flag + BOOL m_bRenderStateSavingFlag[STATEMANAGER_MAX_RENDERSTATES]; + BOOL m_bTextureStageStateSavingFlag[STATEMANAGER_MAX_STAGES][STATEMANAGER_MAX_TEXTURESTATES]; + BOOL m_bTransformSavingFlag[STATEMANAGER_MAX_TRANSFORMSTATES]; +#endif _DEBUG +}; + +#define STATEMANAGER (CStateManager::Instance()) + +#endif __CSTATEMANAGER_H diff --git a/source/EterLib/StdAfx.cpp b/source/EterLib/StdAfx.cpp new file mode 100644 index 0000000..6c4631c --- /dev/null +++ b/source/EterLib/StdAfx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// Model.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/source/EterLib/StdAfx.h b/source/EterLib/StdAfx.h new file mode 100644 index 0000000..99dcc2a --- /dev/null +++ b/source/EterLib/StdAfx.h @@ -0,0 +1,142 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif + +#define _WIN32_DCOM + +#pragma warning(disable:4710) // not inlined +#pragma warning(disable:4786) // character 255 Ѿ° +#pragma warning(disable:4244) // type conversion possible lose of data + +#pragma warning(disable:4018) +#pragma warning(disable:4245) +#pragma warning(disable:4512) +#pragma warning(disable:4201) + +#if _MSC_VER >= 1400 +#pragma warning(disable:4201 4512 4238 4239) +#endif + +#include +#include + +#define DIRECTINPUT_VERSION 0x0800 + +#include + +#pragma warning ( disable : 4201 ) +#include +#pragma warning ( default : 4201 ) +#include +#include +#include +#include +#include +#include + +#pragma comment(lib, "winmm.lib") +#pragma comment(lib, "d3d8.lib") +#pragma comment(lib, "d3dx8.lib") + +#include "../eterBase/StdAfx.h" +#include "../eterBase/Debug.h" +#include "../eterLocale/CodePageId.h" + +#ifndef VC_EXTRALEAN +#include +#endif + + +/* +#include "Pool.h" +#include "Dynamic.h" +#include "Event.h" +#include "FuncObject.h" +#include "ReferenceObject.h" +#include "Ref.h" + +#include "Util.h" +#include "TextFileLoader.h" +#include "Parser.h" + +#include "Resource.h" +#include "ResourceManager.h" + +#include "MSWindow.h" +#include "MSApplication.h" +#include "Mutex.h" +#include "Thread.h" + +#include "GrpBase.h" + +#include "GrpDib.h" +#include "GrpMath.h" +#include "GrpDevice.h" + +#include "CollisionData.h" +#include "GrpCollisionObject.h" +#include "GrpScreen.h" +#include "CullingManager.h" + +// Attribute +#include "AttributeData.h" +#include "AttributeInstance.h" + +#include "GrpObjectInstance.h" +#include "GrpRatioInstance.h" + +#include "GrpD3DXBuffer.h" + +#include "GrpTexture.h" +#include "GrpImageTexture.h" +#include "GrpFontTexture.h" + +#include "GrpText.h" +#include "GrpImage.h" +#include "GrpSubImage.h" + +#include "GrpIndexBuffer.h" +#include "GrpVertexBuffer.h" +#include "GrpVertexBufferStatic.h" +#include "GrpVertexBufferDynamic.h" +#include "GrpVertexShader.h" +#include "GrpPixelShader.h" + + +#include "GrpShadowTexture.h" +#include "GrpImageInstance.h" +#include "GrpExpandedImageInstance.h" +#include "GrpTextInstance.h" +#include "GrpLightManager.h" + +#include "TargaResource.h" + +#include "NetDevice.h" +#include "NetAddress.h" +// #include "NetStream.h" +#include "NetPacketHeaderMap.h" +#include "NetDatagramSender.h" +#include "NetDatagramReceiver.h" + +#include "Input.h" +#include "IME.h" + +#include "PathStack.h" +//#include "Property.h" + +#include "Profiler.h" + +#include "StateManager.h" + +#include "ColorTransitionHelper.h" +#include "LensFlare.h" +#include "ScreenFilter.h" +#include "EnvironmentMap.h" + +#include "lineintersect_utils.h" + +#include "Decal.h" +*/ diff --git a/source/EterLib/TargaResource.cpp b/source/EterLib/TargaResource.cpp new file mode 100644 index 0000000..bbe978c --- /dev/null +++ b/source/EterLib/TargaResource.cpp @@ -0,0 +1,55 @@ +#include "StdAfx.h" +#include "TargaResource.h" + +CTargaResource::CTargaResource(const char * c_pszFileName) : CResource(c_pszFileName) +{ +} + +CTargaResource::~CTargaResource() +{ +} + +CTargaResource::TType CTargaResource::Type() +{ + static TType s_type = StringToType("CTargaResource"); + return s_type; +} + +bool CTargaResource::OnIsType(TType type) +{ + if (CTargaResource::Type() == type) + return true; + + return CResource::OnIsType(type); +} + +bool CTargaResource::OnLoad(int iSize, const void * c_pvBuf) +{ + return image.LoadFromMemory(iSize, static_cast(c_pvBuf)); +} + +void CTargaResource::OnClear() +{ + image.Clear(); +} + +bool CTargaResource::OnIsEmpty() const +{ + return image.IsEmpty(); +} + +void CTargaResource::GetRect(DWORD & w, DWORD & h) +{ + w = image.GetWidth(); + h = image.GetHeight(); +} + +DWORD * CTargaResource::GetMemPtr() +{ + return image.GetBasePointer(); +} + +TGA_HEADER & CTargaResource::GetTgaHeader() +{ + return image.GetHeader(); +} diff --git a/source/EterLib/TargaResource.h b/source/EterLib/TargaResource.h new file mode 100644 index 0000000..833e7a6 --- /dev/null +++ b/source/EterLib/TargaResource.h @@ -0,0 +1,32 @@ +#pragma once + +#include "Ref.h" +#include "Resource.h" +#include "../eterImageLib/TGAImage.h" + +class CTargaResource : public CResource +{ + public: + typedef CRef TRef; + + public: + static TType Type(); + + public: + CTargaResource(const char * c_pszFileName); + virtual ~CTargaResource(); + + DWORD * GetMemPtr(); + void GetRect(DWORD & w, DWORD & h); + + TGA_HEADER & GetTgaHeader(); + + protected: + virtual bool OnLoad(int iSize, const void * c_pvBuf); + virtual void OnClear(); + virtual bool OnIsEmpty() const; + virtual bool OnIsType(TType type); + + protected: + CTGAImage image; +}; diff --git a/source/EterLib/TextBar.cpp b/source/EterLib/TextBar.cpp new file mode 100644 index 0000000..1b4839f --- /dev/null +++ b/source/EterLib/TextBar.cpp @@ -0,0 +1,76 @@ +#include "StdAfx.h" +#include "TextBar.h" +#include "../eterlib/Util.h" + +void CTextBar::__SetFont(int fontSize, bool isBold) +{ + int iCodePage = GetDefaultCodePage(); + + LOGFONT logFont; + + memset(&logFont, 0, sizeof(LOGFONT)); + + logFont.lfHeight = fontSize; + logFont.lfEscapement = 0; + logFont.lfOrientation = 0; + + if (isBold) + logFont.lfWeight = FW_BOLD; + else + logFont.lfWeight = FW_NORMAL; + + logFont.lfItalic = FALSE; + logFont.lfUnderline = FALSE; + logFont.lfStrikeOut = FALSE; + logFont.lfCharSet = GetCharsetFromCodePage(iCodePage); + logFont.lfOutPrecision = OUT_DEFAULT_PRECIS; + logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; + logFont.lfQuality = ANTIALIASED_QUALITY; + logFont.lfPitchAndFamily = DEFAULT_PITCH; + strcpy(logFont.lfFaceName, GetFontFaceFromCodePage(iCodePage)); + m_hFont = CreateFontIndirect(&logFont); + + + HDC hdc = m_dib.GetDCHandle(); + m_hOldFont = (HFONT)SelectObject(hdc, m_hFont); + +} + +void CTextBar::SetTextColor(int r, int g, int b) +{ + HDC hDC = m_dib.GetDCHandle(); + ::SetTextColor(hDC, RGB(r, g, b)); +} + +void CTextBar::GetTextExtent(const char * c_szText, SIZE* p_size) +{ + HDC hDC = m_dib.GetDCHandle(); + GetTextExtentPoint32(hDC, c_szText, strlen(c_szText), p_size); +} + +void CTextBar::TextOut(int ix, int iy, const char * c_szText) +{ + m_dib.TextOut(ix, iy, c_szText); + Invalidate(); +} + +void CTextBar::OnCreate() +{ + m_dib.SetBkMode(TRANSPARENT); + + __SetFont(m_fontSize, m_isBold); +} + +CTextBar::CTextBar(int fontSize, bool isBold) +{ + m_hOldFont = NULL; + m_fontSize = fontSize; + m_isBold = isBold; + +} + +CTextBar::~CTextBar() +{ + HDC hdc = m_dib.GetDCHandle(); + SelectObject(hdc, m_hOldFont); +} diff --git a/source/EterLib/TextBar.h b/source/EterLib/TextBar.h new file mode 100644 index 0000000..6aec660 --- /dev/null +++ b/source/EterLib/TextBar.h @@ -0,0 +1,26 @@ +#pragma once + +#include "DibBar.h" + +class CTextBar : public CDibBar +{ + public: + CTextBar(int fontSize, bool isBold); + virtual ~CTextBar(); + + void TextOut(int ix, int iy, const char * c_szText); + void SetTextColor(int r, int g, int b); + void GetTextExtent(const char * c_szText, SIZE* p_size); + + protected: + void __SetFont(int fontSize, bool isBold); + + void OnCreate(); + + protected: + HFONT m_hFont; + HFONT m_hOldFont; + + int m_fontSize; + bool m_isBold; +}; diff --git a/source/EterLib/TextFileLoader.cpp b/source/EterLib/TextFileLoader.cpp new file mode 100644 index 0000000..d663901 --- /dev/null +++ b/source/EterLib/TextFileLoader.cpp @@ -0,0 +1,696 @@ +#include "StdAfx.h" +#include "../eterBase/CRC32.h" +#include +#include "../eterPack/EterPackManager.h" + +#include "Pool.h" +#include "TextFileLoader.h" + +std::map CTextFileLoader::ms_kMap_dwNameKey_pkTextFileLoader; +bool CTextFileLoader::ms_isCacheMode=false; + +CDynamicPool CTextFileLoader::SGroupNode::ms_kPool; + +CTokenVector* CTextFileLoader::SGroupNode::GetTokenVector(const std::string& c_rstGroupName) +{ + DWORD dwGroupNameKey=GenNameKey(c_rstGroupName.c_str(), c_rstGroupName.length()); + + std::map::iterator f=m_kMap_dwKey_kVct_stToken.find(dwGroupNameKey); + if (m_kMap_dwKey_kVct_stToken.end()==f) + return NULL; + + return &f->second; +} + +bool CTextFileLoader::SGroupNode::IsExistTokenVector(const std::string& c_rstGroupName) +{ + DWORD dwGroupNameKey=GenNameKey(c_rstGroupName.c_str(), c_rstGroupName.length()); + + if (m_kMap_dwKey_kVct_stToken.end()==m_kMap_dwKey_kVct_stToken.find(dwGroupNameKey)) + return false; + + return true; +} + +void CTextFileLoader::SGroupNode::InsertTokenVector(const std::string& c_rstGroupName, const CTokenVector& c_rkVct_stToken) +{ + DWORD dwGroupNameKey=GenNameKey(c_rstGroupName.c_str(), c_rstGroupName.length()); + + m_kMap_dwKey_kVct_stToken.insert(std::map::value_type(dwGroupNameKey, c_rkVct_stToken)); +} + +DWORD CTextFileLoader::SGroupNode::GenNameKey(const char* c_szGroupName, UINT uGroupNameLen) +{ + return GetCRC32(c_szGroupName, uGroupNameLen); +} + +const std::string& CTextFileLoader::SGroupNode::GetGroupName() +{ + return m_strGroupName; +} + +bool CTextFileLoader::SGroupNode::IsGroupNameKey(DWORD dwGroupNameKey) +{ + if (dwGroupNameKey==m_dwGroupNameKey) + return true; + + return false; +} + +void CTextFileLoader::SGroupNode::SetGroupName(const std::string& c_rstGroupName) +{ + m_strGroupName=c_rstGroupName; + stl_lowers(m_strGroupName); + + m_dwGroupNameKey=GenNameKey(m_strGroupName.c_str(), m_strGroupName.length()); +} + + +CTextFileLoader::SGroupNode* CTextFileLoader::SGroupNode::New() +{ + return ms_kPool.Alloc(); +} + +void CTextFileLoader::SGroupNode::Delete(SGroupNode* pkNode) +{ + pkNode->m_kMap_dwKey_kVct_stToken.clear(); + pkNode->ChildNodeVector.clear(); + pkNode->m_strGroupName=""; + pkNode->m_dwGroupNameKey=0; + ms_kPool.Free(pkNode); +} + + + +void CTextFileLoader::SGroupNode::DestroySystem() +{ + ms_kPool.Destroy(); +} + + +CTextFileLoader* CTextFileLoader::Cache(const char* c_szFileName) +{ + DWORD dwNameKey=GetCRC32(c_szFileName, strlen(c_szFileName)); + std::map::iterator f=ms_kMap_dwNameKey_pkTextFileLoader.find(dwNameKey); + if (ms_kMap_dwNameKey_pkTextFileLoader.end()!=f) + { + if (!ms_isCacheMode) + { + delete f->second; + + CTextFileLoader* pkNewTextFileLoader=new CTextFileLoader; + pkNewTextFileLoader->Load(c_szFileName); + f->second=pkNewTextFileLoader; + } + f->second->SetTop(); + return f->second; + } + + CTextFileLoader* pkNewTextFileLoader=new CTextFileLoader; + pkNewTextFileLoader->Load(c_szFileName); + + ms_kMap_dwNameKey_pkTextFileLoader.insert(std::map::value_type(dwNameKey, pkNewTextFileLoader)); + return pkNewTextFileLoader; +} + +void CTextFileLoader::SetCacheMode() +{ + ms_isCacheMode=true; +} + +void CTextFileLoader::DestroySystem() +{ + { + std::map::iterator i; + for (i=ms_kMap_dwNameKey_pkTextFileLoader.begin(); i!=ms_kMap_dwNameKey_pkTextFileLoader.end(); ++i) + delete i->second; + ms_kMap_dwNameKey_pkTextFileLoader.clear(); + } + + SGroupNode::DestroySystem(); +} + +void CTextFileLoader::Destroy() +{ + __DestroyGroupNodeVector(); +} + +CTextFileLoader::CTextFileLoader() +{ + SetTop(); + + m_acBufData=NULL; + m_dwBufSize=0; + m_dwBufCapacity=0; + + m_GlobalNode.m_strGroupName = "global"; + m_GlobalNode.pParentNode = NULL; + + m_kVct_pkNode.reserve(128); +} + +CTextFileLoader::~CTextFileLoader() +{ + Destroy(); + + if (m_acBufData) + delete [] m_acBufData; +} + +void CTextFileLoader::__DestroyGroupNodeVector() +{ + std::vector::iterator i; + for (i=m_kVct_pkNode.begin(); i!=m_kVct_pkNode.end(); ++i) + SGroupNode::Delete(*i); + m_kVct_pkNode.clear(); +} + +const char * CTextFileLoader::GetFileName() +{ + return m_strFileName.c_str(); +} + +bool CTextFileLoader::IsEmpty() +{ + return m_strFileName.empty(); +} + +bool CTextFileLoader::Load(const char * c_szFileName) +{ + m_strFileName = ""; + + const VOID* pvData; + CMappedFile kFile; + if (!CEterPackManager::Instance().Get(kFile, c_szFileName, &pvData)) + return false; + + if (m_dwBufCapacitypParentNode = pGroupNode; + pNewNode->SetGroupName(stTokenVector[1]); + pGroupNode->ChildNodeVector.push_back(pNewNode); + + ++m_dwcurLineIndex; + + if( false == LoadGroup(pNewNode) ) + return false; + } + // List + else if (0 == stTokenVector[0].compare("list")) + { + if (2 != stTokenVector.size()) + { + assert(!"There is no list name!"); + continue; + } + + CTokenVector stSubTokenVector; + + stl_lowers(stTokenVector[1]); + std::string key = stTokenVector[1]; + + stTokenVector.clear(); + + ++m_dwcurLineIndex; + for (; m_dwcurLineIndex < m_textFileLoader.GetLineCount(); ++m_dwcurLineIndex) + { + if (!m_textFileLoader.SplitLine(m_dwcurLineIndex, &stSubTokenVector)) + continue; + + if ('{' == stSubTokenVector[0][0]) + continue; + + if ('}' == stSubTokenVector[0][0]) + break; + + for (DWORD j = 0; j < stSubTokenVector.size(); ++j) + { + stTokenVector.push_back(stSubTokenVector[j]); + } + } + + pGroupNode->InsertTokenVector(key, stTokenVector); + //pGroupNode->LocalTokenVectorMap.insert(std::make_pair(key, stTokenVector)); + } + else + { + std::string key = stTokenVector[0]; + + if (1 == stTokenVector.size()) + { + TraceError("CTextFileLoader::LoadGroup : must have a value (filename: %s line: %d key: %s)", + m_strFileName.c_str(), + m_dwcurLineIndex, + key.c_str()); + break; + } + + stTokenVector.erase(stTokenVector.begin()); + pGroupNode->InsertTokenVector(key, stTokenVector); + //pGroupNode->LocalTokenVectorMap.insert(std::make_pair(key, stTokenVector)); + } + } + + return (nLocalGroupDepth == 0); +} + +void CTextFileLoader::SetTop() +{ + m_pcurNode = &m_GlobalNode; +} + +DWORD CTextFileLoader::GetChildNodeCount() +{ + if (!m_pcurNode) + { + assert(!"Node to access has not set!"); + return 0; + } + + return m_pcurNode->ChildNodeVector.size(); +} + +BOOL CTextFileLoader::SetChildNode(const char * c_szKey) +{ + if (!m_pcurNode) + { + assert(!"Node to access has not set!"); + return FALSE; + } + + DWORD dwKey=SGroupNode::GenNameKey(c_szKey, strlen(c_szKey)); + + for (DWORD i = 0; i < m_pcurNode->ChildNodeVector.size(); ++i) + { + TGroupNode * pGroupNode = m_pcurNode->ChildNodeVector[i]; + if (pGroupNode->IsGroupNameKey(dwKey)) + { + m_pcurNode = pGroupNode; + return TRUE; + } + } + + return FALSE; +} +BOOL CTextFileLoader::SetChildNode(const std::string & c_rstrKeyHead, DWORD dwIndex) +{ + char szKey[32+1]; + _snprintf(szKey, sizeof(szKey), "%s%02u", c_rstrKeyHead.c_str(), dwIndex); + + return SetChildNode(szKey); +} +BOOL CTextFileLoader::SetChildNode(DWORD dwIndex) +{ + if (!m_pcurNode) + { + assert(!"Node to access has not set!"); + return FALSE; + } + + if (dwIndex >= m_pcurNode->ChildNodeVector.size()) + { + assert(!"Node index to set is too large to access!"); + return FALSE; + } + + m_pcurNode = m_pcurNode->ChildNodeVector[dwIndex]; + + return TRUE; +} + +BOOL CTextFileLoader::SetParentNode() +{ + if (!m_pcurNode) + { + assert(!"Node to access has not set!"); + return FALSE; + } + + if (NULL == m_pcurNode->pParentNode) + { + assert(!"Current group node is already top!"); + return FALSE; + } + + m_pcurNode = m_pcurNode->pParentNode; + + return TRUE; +} + +BOOL CTextFileLoader::GetCurrentNodeName(std::string * pstrName) +{ + if (!m_pcurNode) + return FALSE; + if (NULL == m_pcurNode->pParentNode) + return FALSE; + + *pstrName = m_pcurNode->GetGroupName(); + + return TRUE; +} + +BOOL CTextFileLoader::IsToken(const std::string & c_rstrKey) +{ + if (!m_pcurNode) + { + assert(!"Node to access has not set!"); + return FALSE; + } + + return m_pcurNode->IsExistTokenVector(c_rstrKey); + //return m_pcurNode->LocalTokenVectorMap.end() != m_pcurNode->LocalTokenVectorMap.find(c_rstrKey); +} + +BOOL CTextFileLoader::GetTokenVector(const std::string & c_rstrKey, CTokenVector ** ppTokenVector) +{ + if (!m_pcurNode) + { + assert(!"Node to access has not set!"); + return FALSE; + } + + CTokenVector* pkRetTokenVector=m_pcurNode->GetTokenVector(c_rstrKey); + if (!pkRetTokenVector) + return FALSE; + + *ppTokenVector = pkRetTokenVector; + + //CTokenVectorMap::iterator itor = m_pcurNode->LocalTokenVectorMap.find(c_rstrKey); + //if (m_pcurNode->LocalTokenVectorMap.end() == itor) + //{ + //Tracef(" CTextFileLoader::GetTokenVector - Failed to find the key %s [%s :: %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str()); + // return FALSE; + //} + + //*ppTokenVector = &itor->second; + + return TRUE; +} + +BOOL CTextFileLoader::GetTokenBoolean(const std::string & c_rstrKey, BOOL * pData) +{ + CTokenVector * pTokenVector; + if (!GetTokenVector(c_rstrKey, &pTokenVector)) + return FALSE; + + if (pTokenVector->empty()) + { + //Tracef(" CTextFileLoader::GetTokenBoolean - Failed to find the value %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str()); + return FALSE; + } + + *pData = BOOL(atoi(pTokenVector->at(0).c_str())); + + return TRUE; +} + +BOOL CTextFileLoader::GetTokenByte(const std::string & c_rstrKey, BYTE * pData) +{ + CTokenVector * pTokenVector; + if (!GetTokenVector(c_rstrKey, &pTokenVector)) + return FALSE; + + if (pTokenVector->empty()) + { + //Tracef(" CTextFileLoader::GetTokenByte - Failed to find the value %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str()); + return FALSE; + } + + *pData = BYTE(atoi(pTokenVector->at(0).c_str())); + + return TRUE; +} + +BOOL CTextFileLoader::GetTokenWord(const std::string & c_rstrKey, WORD * pData) +{ + CTokenVector * pTokenVector; + if (!GetTokenVector(c_rstrKey, &pTokenVector)) + return FALSE; + + if (pTokenVector->empty()) + { + //Tracef(" CTextFileLoader::GetTokenWord - Failed to find the value %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str()); + return FALSE; + } + + *pData = WORD(atoi(pTokenVector->at(0).c_str())); + + return TRUE; +} + +BOOL CTextFileLoader::GetTokenInteger(const std::string & c_rstrKey, int * pData) +{ + CTokenVector * pTokenVector; + if (!GetTokenVector(c_rstrKey, &pTokenVector)) + return FALSE; + + if (pTokenVector->empty()) + { + //Tracef(" CTextFileLoader::GetTokenInteger - Failed to find the value %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str()); + return FALSE; + } + + *pData = atoi(pTokenVector->at(0).c_str()); + + return TRUE; +} + +BOOL CTextFileLoader::GetTokenDoubleWord(const std::string & c_rstrKey, DWORD * pData) +{ + return GetTokenInteger(c_rstrKey, *(int **)(&pData)); +} + +BOOL CTextFileLoader::GetTokenFloat(const std::string & c_rstrKey, float * pData) +{ + CTokenVector * pTokenVector; + if (!GetTokenVector(c_rstrKey, &pTokenVector)) + return FALSE; + + if (pTokenVector->empty()) + { + //Tracef(" CTextFileLoader::GetTokenFloat - Failed to find the value %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str()); + return FALSE; + } + + *pData = atof(pTokenVector->at(0).c_str()); + + return TRUE; +} + +BOOL CTextFileLoader::GetTokenVector2(const std::string & c_rstrKey, D3DXVECTOR2 * pVector2) +{ + CTokenVector * pTokenVector; + if (!GetTokenVector(c_rstrKey, &pTokenVector)) + return FALSE; + + if (pTokenVector->size() != 2) + { + //Tracef(" CTextFileLoader::GetTokenVector2 - This key should have 2 values %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str()); + return FALSE; + } + + pVector2->x = atof(pTokenVector->at(0).c_str()); + pVector2->y = atof(pTokenVector->at(1).c_str()); + + return TRUE; +} + +BOOL CTextFileLoader::GetTokenVector3(const std::string & c_rstrKey, D3DXVECTOR3 * pVector3) +{ + CTokenVector * pTokenVector; + if (!GetTokenVector(c_rstrKey, &pTokenVector)) + return FALSE; + + if (pTokenVector->size() != 3) + { + //Tracef(" CTextFileLoader::GetTokenVector3 - This key should have 3 values %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str()); + return FALSE; + } + + pVector3->x = atof(pTokenVector->at(0).c_str()); + pVector3->y = atof(pTokenVector->at(1).c_str()); + pVector3->z = atof(pTokenVector->at(2).c_str()); + + return TRUE; +} + +BOOL CTextFileLoader::GetTokenVector4(const std::string & c_rstrKey, D3DXVECTOR4 * pVector4) +{ + CTokenVector * pTokenVector; + if (!GetTokenVector(c_rstrKey, &pTokenVector)) + return FALSE; + + if (pTokenVector->size() != 4) + { + //Tracef(" CTextFileLoader::GetTokenVector3 - This key should have 3 values %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str()); + return FALSE; + } + + pVector4->x = atof(pTokenVector->at(0).c_str()); + pVector4->y = atof(pTokenVector->at(1).c_str()); + pVector4->z = atof(pTokenVector->at(2).c_str()); + pVector4->w = atof(pTokenVector->at(3).c_str()); + + return TRUE; +} + + +BOOL CTextFileLoader::GetTokenPosition(const std::string & c_rstrKey, D3DXVECTOR3 * pVector) +{ + return GetTokenVector3(c_rstrKey, pVector); +} + +BOOL CTextFileLoader::GetTokenQuaternion(const std::string & c_rstrKey, D3DXQUATERNION * pQ) +{ + CTokenVector * pTokenVector; + if (!GetTokenVector(c_rstrKey, &pTokenVector)) + return FALSE; + + if (pTokenVector->size() != 4) + { + //Tracef(" CTextFileLoader::GetTokenVector3 - This key should have 3 values %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str()); + return FALSE; + } + + pQ->x = atof(pTokenVector->at(0).c_str()); + pQ->y = atof(pTokenVector->at(1).c_str()); + pQ->z = atof(pTokenVector->at(2).c_str()); + pQ->w = atof(pTokenVector->at(3).c_str()); + + return TRUE; +} + +BOOL CTextFileLoader::GetTokenDirection(const std::string & c_rstrKey, D3DVECTOR * pVector) +{ + CTokenVector * pTokenVector; + if (!GetTokenVector(c_rstrKey, &pTokenVector)) + return FALSE; + + if (pTokenVector->size() != 3) + { + //Tracef(" CTextFileLoader::GetTokenDirection - This key should have 3 values %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str()); + return FALSE; + } + + pVector->x = atof(pTokenVector->at(0).c_str()); + pVector->y = atof(pTokenVector->at(1).c_str()); + pVector->z = atof(pTokenVector->at(2).c_str()); + + return TRUE; +} + +BOOL CTextFileLoader::GetTokenColor(const std::string & c_rstrKey, D3DXCOLOR * pColor) +{ + CTokenVector * pTokenVector; + if (!GetTokenVector(c_rstrKey, &pTokenVector)) + return FALSE; + + if (pTokenVector->size() != 4) + { + //Tracef(" CTextFileLoader::GetTokenColor - This key should have 4 values %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str()); + return FALSE; + } + + pColor->r = atof(pTokenVector->at(0).c_str()); + pColor->g = atof(pTokenVector->at(1).c_str()); + pColor->b = atof(pTokenVector->at(2).c_str()); + pColor->a = atof(pTokenVector->at(3).c_str()); + + return TRUE; +} + +BOOL CTextFileLoader::GetTokenColor(const std::string & c_rstrKey, D3DCOLORVALUE * pColor) +{ + CTokenVector * pTokenVector; + if (!GetTokenVector(c_rstrKey, &pTokenVector)) + return FALSE; + + if (pTokenVector->size() != 4) + { + //Tracef(" CTextFileLoader::GetTokenColor - This key should have 4 values %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str()); + return FALSE; + } + + pColor->r = atof(pTokenVector->at(0).c_str()); + pColor->g = atof(pTokenVector->at(1).c_str()); + pColor->b = atof(pTokenVector->at(2).c_str()); + pColor->a = atof(pTokenVector->at(3).c_str()); + + return TRUE; +} + +BOOL CTextFileLoader::GetTokenString(const std::string & c_rstrKey, std::string * pString) +{ + CTokenVector * pTokenVector; + if (!GetTokenVector(c_rstrKey, &pTokenVector)) + return FALSE; + + if (pTokenVector->empty()) + { + //Tracef(" CTextFileLoader::GetTokenString - Failed to find the value %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str()); + return FALSE; + } + + *pString = pTokenVector->at(0); + + return TRUE; +} diff --git a/source/EterLib/TextFileLoader.h b/source/EterLib/TextFileLoader.h new file mode 100644 index 0000000..6854e37 --- /dev/null +++ b/source/EterLib/TextFileLoader.h @@ -0,0 +1,132 @@ +#ifndef __INC_METIN_II_TEXTFILELOADER_H__ +#define __INC_METIN_II_TEXTFILELOADER_H__ + +#include "../eterBase/FileLoader.h" +#include "../eterBase/MappedFile.h" +#include "../eterLib/Util.h" +#include "../eterLib/Pool.h" + +class CTextFileLoader +{ + public: + typedef struct SGroupNode + { + static DWORD GenNameKey(const char* c_szGroupName, UINT uGroupNameLen); + + void SetGroupName(const std::string& c_rstGroupName); + bool IsGroupNameKey(DWORD dwGroupNameKey); + + const std::string& GetGroupName(); + + CTokenVector* GetTokenVector(const std::string& c_rstGroupName); + bool IsExistTokenVector(const std::string& c_rstGroupName); + void InsertTokenVector(const std::string& c_rstGroupName, const CTokenVector& c_rkVct_stToken); + + DWORD m_dwGroupNameKey; + std::string m_strGroupName; + + std::map m_kMap_dwKey_kVct_stToken; + + SGroupNode * pParentNode; + std::vector ChildNodeVector; + + static SGroupNode* New(); + static void Delete(SGroupNode* pkNode); + + static void DestroySystem(); + static CDynamicPool ms_kPool; + } TGroupNode; + + typedef std::vector TGroupNodeVector; + + class CGotoChild + { + public: + CGotoChild(CTextFileLoader * pOwner, const char * c_szKey) : m_pOwner(pOwner) + { + m_pOwner->SetChildNode(c_szKey); + } + CGotoChild(CTextFileLoader * pOwner, DWORD dwIndex) : m_pOwner(pOwner) + { + m_pOwner->SetChildNode(dwIndex); + } + ~CGotoChild() + { + m_pOwner->SetParentNode(); + } + + CTextFileLoader * m_pOwner; + }; + + public: + static void DestroySystem(); + + static void SetCacheMode(); + + static CTextFileLoader* Cache(const char* c_szFileName); + + public: + CTextFileLoader(); + virtual ~CTextFileLoader(); + + void Destroy(); + + bool Load(const char * c_szFileName); + const char * GetFileName(); + + bool IsEmpty(); + + void SetTop(); + DWORD GetChildNodeCount(); + BOOL SetChildNode(const char * c_szKey); + BOOL SetChildNode(const std::string & c_rstrKeyHead, DWORD dwIndex); + BOOL SetChildNode(DWORD dwIndex); + BOOL SetParentNode(); + BOOL GetCurrentNodeName(std::string * pstrName); + + BOOL IsToken(const std::string & c_rstrKey); + BOOL GetTokenVector(const std::string & c_rstrKey, CTokenVector ** ppTokenVector); + BOOL GetTokenBoolean(const std::string & c_rstrKey, BOOL * pData); + BOOL GetTokenByte(const std::string & c_rstrKey, BYTE * pData); + BOOL GetTokenWord(const std::string & c_rstrKey, WORD * pData); + BOOL GetTokenInteger(const std::string & c_rstrKey, int * pData); + BOOL GetTokenDoubleWord(const std::string & c_rstrKey, DWORD * pData); + BOOL GetTokenFloat(const std::string & c_rstrKey, float * pData); + BOOL GetTokenVector2(const std::string & c_rstrKey, D3DXVECTOR2 * pVector2); + BOOL GetTokenVector3(const std::string & c_rstrKey, D3DXVECTOR3 * pVector3); + BOOL GetTokenVector4(const std::string & c_rstrKey, D3DXVECTOR4 * pVector4); + + BOOL GetTokenPosition(const std::string & c_rstrKey, D3DXVECTOR3 * pVector); + BOOL GetTokenQuaternion(const std::string & c_rstrKey, D3DXQUATERNION * pQ); + BOOL GetTokenDirection(const std::string & c_rstrKey, D3DVECTOR * pVector); + BOOL GetTokenColor(const std::string & c_rstrKey, D3DXCOLOR * pColor); + BOOL GetTokenColor(const std::string & c_rstrKey, D3DCOLORVALUE * pColor); + BOOL GetTokenString(const std::string & c_rstrKey, std::string * pString); + + protected: + void __DestroyGroupNodeVector(); + + bool LoadGroup(TGroupNode * pGroupNode); + + protected: + std::string m_strFileName; + + char* m_acBufData; + DWORD m_dwBufSize; + DWORD m_dwBufCapacity; + + DWORD m_dwcurLineIndex; + + CMemoryTextFileLoader m_textFileLoader; + + TGroupNode m_GlobalNode; + TGroupNode * m_pcurNode; + + std::vector m_kVct_pkNode; + + protected: + static std::map ms_kMap_dwNameKey_pkTextFileLoader; + static bool ms_isCacheMode; +}; + +#endif \ No newline at end of file diff --git a/source/EterLib/TextTag.cpp b/source/EterLib/TextTag.cpp new file mode 100644 index 0000000..ca6311d --- /dev/null +++ b/source/EterLib/TextTag.cpp @@ -0,0 +1,209 @@ +#include "stdafx.h" +#include "TextTag.h" + +int GetTextTag(const wchar_t * src, int maxLen, int & tagLen, std::wstring & extraInfo) +{ + tagLen = 1; + + if (maxLen < 2 || *src != L'|') + return TEXT_TAG_PLAIN; + + const wchar_t * cur = ++src; + + if (*cur == L'c') // color + { + if (maxLen < 10) + return TEXT_TAG_PLAIN; + + tagLen = 10; + extraInfo.assign(++cur, 8); + return TEXT_TAG_COLOR; + } + else if (*cur == L'|') // || | ǥѴ. + { + tagLen = 2; + return TEXT_TAG_TAG; + } + else if (*cur == L'r') // restore color + { + tagLen = 2; + return TEXT_TAG_RESTORE_COLOR; + } + else if (*cur == L'H') // hyperlink |Hitem:10000:0:0:0:0|h[̸]|h + { + tagLen = 2; + return TEXT_TAG_HYPERLINK_START; + } + else if (*cur == L'h') // end of hyperlink + { + tagLen = 2; + return TEXT_TAG_HYPERLINK_END; + } + + return TEXT_TAG_PLAIN; +} + +std::wstring GetTextTagOutputString(const wchar_t * src, int src_len) +{ + int len; + std::wstring dst; + std::wstring extraInfo; + int output_len = 0; + int hyperlinkStep = 0; + + for (int i = 0; i < src_len; ) + { + int tag = GetTextTag(&src[i], src_len - i, len, extraInfo); + + if (tag == TEXT_TAG_PLAIN || tag == TEXT_TAG_TAG) + { + if (hyperlinkStep == 0) + { + ++output_len; + dst += src[i]; + } + } + else if (tag == TEXT_TAG_HYPERLINK_START) + hyperlinkStep = 1; + else if (tag == TEXT_TAG_HYPERLINK_END) + hyperlinkStep = 0; + + i += len; + } + return dst; +} + +int GetTextTagInternalPosFromRenderPos(const wchar_t * src, int src_len, int offset) +{ + int len; + std::wstring dst; + std::wstring extraInfo; + int output_len = 0; + int hyperlinkStep = 0; + bool color_tag = false; + int internal_offset = 0; + + for (int i = 0; i < src_len; ) + { + int tag = GetTextTag(&src[i], src_len - i, len, extraInfo); + + if (tag == TEXT_TAG_COLOR) + { + color_tag = true; + internal_offset = i; + } + else if (tag == TEXT_TAG_RESTORE_COLOR) + { + color_tag = false; + } + else if (tag == TEXT_TAG_PLAIN || tag == TEXT_TAG_TAG) + { + if (hyperlinkStep == 0) + { + if (!color_tag) + internal_offset = i; + + if (offset <= output_len) + return internal_offset; + + ++output_len; + dst += src[i]; + } + } + else if (tag == TEXT_TAG_HYPERLINK_START) + hyperlinkStep = 1; + else if (tag == TEXT_TAG_HYPERLINK_END) + hyperlinkStep = 0; + + i += len; + } + + return internal_offset; +} + +int GetTextTagOutputLen(const wchar_t * src, int src_len) +{ + int len; + std::wstring extraInfo; + int output_len = 0; + int hyperlinkStep = 0; + + for (int i = 0; i < src_len; ) + { + int tag = GetTextTag(&src[i], src_len - i, len, extraInfo); + + if (tag == TEXT_TAG_PLAIN || tag == TEXT_TAG_TAG) + { + if (hyperlinkStep == 0) + ++output_len; + } + else if (tag == TEXT_TAG_HYPERLINK_START) + hyperlinkStep = 1; + else if (tag == TEXT_TAG_HYPERLINK_END) + hyperlinkStep = 0; + + i += len; + } + return output_len; +} + +int FindColorTagStartPosition(const wchar_t * src, int src_len) +{ + if (src_len < 2) + return 0; + + const wchar_t * cur = src; + + // |r + if (*cur == L'r' && *(cur - 1) == L'|') + { + int len = src_len; + + // ||r + if (len >= 2 && *(cur - 2) == L'|') + return 1; + + cur -= 2; + len -= 2; + + // |c ãƼ |ġ Ѵ. + while (len > 1) // ּ 2ڸ ˻ؾ ȴ. + { + if (*cur == L'c' && *(cur - 1) == L'|') + return (src - cur) + 1; + + --cur; + --len; + } + return (src_len); // ã ;; + } + // || + else if (*cur == L'|' && *(cur - 1) == L'|') + return 1; + + return 0; +} + +int FindColorTagEndPosition(const wchar_t * src, int src_len) +{ + const wchar_t * cur = src; + + if (src_len >= 4 && *cur == L'|' && *(cur + 1) == L'c') + { + int left = src_len - 2; + cur += 2; + + while (left > 1) + { + if (*cur == L'|' && *(cur + 1) == L'r') + return (cur - src) + 1; + + --left; + ++cur; + } + } + else if (src_len >= 2 && *cur == L'|' && *(cur + 1) == L'|') + return 1; + + return 0; +} diff --git a/source/EterLib/TextTag.h b/source/EterLib/TextTag.h new file mode 100644 index 0000000..5d60d11 --- /dev/null +++ b/source/EterLib/TextTag.h @@ -0,0 +1,16 @@ +enum +{ + TEXT_TAG_PLAIN, + TEXT_TAG_TAG, // || + TEXT_TAG_COLOR, // |cffffffff + TEXT_TAG_HYPERLINK_START, // |H + TEXT_TAG_HYPERLINK_END, // |h ex) |Hitem:1234:1:1:1|h + TEXT_TAG_RESTORE_COLOR, +}; + +extern int GetTextTag(const wchar_t * src, int maxLen, int & tagLen, std::wstring & extraInfo); +extern std::wstring GetTextTagOutputString(const wchar_t * src, int src_len); +extern int GetTextTagOutputLen(const wchar_t * src, int len); +extern int FindColorTagEndPosition(const wchar_t * src, int src_len); +extern int FindColorTagStartPosition(const wchar_t * src, int src_len); +extern int GetTextTagInternalPosFromRenderPos(const wchar_t * src, int src_len, int offset); diff --git a/source/EterLib/Thread.cpp b/source/EterLib/Thread.cpp new file mode 100644 index 0000000..ddaafed --- /dev/null +++ b/source/EterLib/Thread.cpp @@ -0,0 +1,33 @@ +#include "StdAfx.h" +#include "Thread.h" + +CThread::CThread() : m_pArg(NULL), m_hThread(NULL), m_uThreadID(0) +{ +} + +int CThread::Create(void * arg) +{ + Arg(arg); + m_hThread = (HANDLE) _beginthreadex(NULL, 0, EntryPoint, this, 0, &m_uThreadID); + + if (!m_hThread) + return false; + + SetThreadPriority(m_hThread, THREAD_PRIORITY_NORMAL); + return true; +} + +UINT CThread::Run(void * arg) +{ + if (!Setup()) + return 0; + + return (Execute(arg)); +} + +/* Static */ +UINT CALLBACK CThread::EntryPoint(void * pThis) +{ + CThread * pThread = (CThread *) pThis; + return pThread->Run(pThread->Arg()); +} \ No newline at end of file diff --git a/source/EterLib/Thread.h b/source/EterLib/Thread.h new file mode 100644 index 0000000..ce09698 --- /dev/null +++ b/source/EterLib/Thread.h @@ -0,0 +1,28 @@ +#ifndef __INC_ETERLIB_THREAD_H__ +#define __INC_ETERLIB_THREAD_H__ + +class CThread +{ + public: + CThread(); + int Create(void * arg); + + protected: + static UINT CALLBACK EntryPoint(void * pThis); + + virtual UINT Setup() = 0; // Execute ҷ ҷ. + virtual UINT Execute(void * arg) = 0; // 尡 ϴ  + + UINT Run(void * arg); + + void * Arg() const { return m_pArg; } + void Arg(void * arg) { m_pArg = arg; } + + HANDLE m_hThread; + + private: + void * m_pArg; + unsigned m_uThreadID; +}; + +#endif diff --git a/source/EterLib/Util.cpp b/source/EterLib/Util.cpp new file mode 100644 index 0000000..73b5247 --- /dev/null +++ b/source/EterLib/Util.cpp @@ -0,0 +1,390 @@ +#include "StdAfx.h" +#include "../eterPack/EterPackManager.h" + +#include "TextFileLoader.h" + +void PrintfTabs(FILE * File, int iTabCount, const char * c_szString, ...) +{ + va_list args; + va_start(args, c_szString); + + static char szBuf[1024]; + _vsnprintf(szBuf, sizeof(szBuf), c_szString, args); + va_end(args); + + for (int i = 0; i < iTabCount; ++i) + fprintf(File, " "); + + fprintf(File, szBuf); +} + +bool LoadTextData(const char * c_szFileName, CTokenMap & rstTokenMap) +{ + LPCVOID pMotionData; + CMappedFile File; + + if (!CEterPackManager::Instance().Get(File, c_szFileName, &pMotionData)) + return false; + + CMemoryTextFileLoader textFileLoader; + CTokenVector stTokenVector; + + textFileLoader.Bind(File.Size(), pMotionData); + + for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i) + { + if (!textFileLoader.SplitLine(i, &stTokenVector)) + continue; + + if (2 != stTokenVector.size()) + return false; + + stl_lowers(stTokenVector[0]); + stl_lowers(stTokenVector[1]); + + rstTokenMap[stTokenVector[0]] = stTokenVector[1]; + } + + return true; +} + +bool LoadMultipleTextData(const char * c_szFileName, CTokenVectorMap & rstTokenVectorMap) +{ + LPCVOID pModelData; + CMappedFile File; + + if (!CEterPackManager::Instance().Get(File, c_szFileName, &pModelData)) + return false; + + DWORD i; + + CMemoryTextFileLoader textFileLoader; + CTokenVector stTokenVector; + + textFileLoader.Bind(File.Size(), pModelData); + + for (i = 0; i < textFileLoader.GetLineCount(); ++i) + { + if (!textFileLoader.SplitLine(i, &stTokenVector)) + continue; + + stl_lowers(stTokenVector[0]); + + // Start or End + if (0 == stTokenVector[0].compare("start")) + { + CTokenVector stSubTokenVector; + + stl_lowers(stTokenVector[1]); + std::string key = stTokenVector[1]; + stTokenVector.clear(); + + for (i=i+1; i < textFileLoader.GetLineCount(); ++i) + { + if (!textFileLoader.SplitLine(i, &stSubTokenVector)) + continue; + + stl_lowers(stSubTokenVector[0]); + + if (0 == stSubTokenVector[0].compare("end")) + { + break; + } + + for (DWORD j = 0; j < stSubTokenVector.size(); ++j) + { + stTokenVector.push_back(stSubTokenVector[j]); + } + } + + rstTokenVectorMap.insert(CTokenVectorMap::value_type(key, stTokenVector)); + } + else + { + std::string key = stTokenVector[0]; + stTokenVector.erase(stTokenVector.begin()); + rstTokenVectorMap.insert(CTokenVectorMap::value_type(key, stTokenVector)); + } + } + + return true; +} + +D3DXVECTOR3 TokenToVector(CTokenVector & rVector) +{ + if (3 != rVector.size()) + { + assert(!"Size of token vector which will be converted to vector is not 3"); + return D3DXVECTOR3(0.0f, 0.0f, 0.0f); + } + + return D3DXVECTOR3(atof(rVector[0].c_str()), + atof(rVector[1].c_str()), + atof(rVector[2].c_str())); +} + +D3DXCOLOR TokenToColor(CTokenVector & rVector) +{ + if (4 != rVector.size()) + { + assert(!"Size of token vector which will be converted to color is not 4"); + return D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); + } + + return D3DXCOLOR(atof(rVector[0].c_str()), + atof(rVector[1].c_str()), + atof(rVector[2].c_str()), + atof(rVector[3].c_str())); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +static std::string gs_fontFace=""; +static DWORD gs_codePage=0; + +int CALLBACK EnumFontFamExProc(CONST LOGFONT* plogFont, CONST TEXTMETRIC* /*textMetric*/, DWORD /*dwWord*/, LPARAM lParam) +{ + return stricmp((const char*)lParam, plogFont->lfFaceName); +} + +int GetCharsetFromCodePage(WORD codePage) +{ + switch( codePage ) + { + case CP_932: + return SHIFTJIS_CHARSET; + case CP_949: + return HANGUL_CHARSET; + case CP_936: + return GB2312_CHARSET; + case CP_950: + return CHINESEBIG5_CHARSET; + case CP_1253: + return GREEK_CHARSET; + case CP_1254: + return TURKISH_CHARSET; + case CP_1255: + return HEBREW_CHARSET; + case CP_1256: + return ARABIC_CHARSET; + case CP_1257: + return BALTIC_CHARSET; + case CP_1258: + return VIETNAMESE_CHARSET; + case CP_874: + return THAI_CHARSET; + case CP_1250: + return EASTEUROPE_CHARSET; + case CP_1251: + return RUSSIAN_CHARSET; + default: + return DEFAULT_CHARSET; + } +} + + +const char* GetFontFaceFromCodePageNT(WORD codePage) +{ + switch( codePage ) + { + case CP_932: + return "MS PGothic"; + case CP_949: + return "GulimChe"; + case CP_936: + return "SimSun"; + case CP_950: + return "MingLiU"; + case CP_874: + return "Tahoma"; + case CP_1252: + return "Arial"; + case CP_1256: + return "Tahoma"; + case CP_1258: + return "Tahoma"; + case CP_65001: + return "Arial"; + default: + return "Arial"; + } +} +const char* GetFontFaceFromCodePage9x(WORD codePage) +{ + switch( codePage ) + { + case CP_932: + return "lr oSVbN"; + case CP_949: + return "ü"; + case CP_936: + return ""; + case CP_950: + return "ө"; + case CP_874: + return "Tahoma"; + case CP_1252: + return "Arial"; + case CP_1256: + return "Tahoma"; + case CP_1258: + return "Tahoma"; + case CP_65001: + return "Arial"; + default: + return "Arial"; + } +} + +DWORD GetDefaultCodePage() +{ + return gs_codePage; +} + +const char * GetDefaultFontFace() +{ + return gs_fontFace.c_str(); +} + +const char* GetFontFaceFromCodePage(WORD codePage) +{ + LOGFONT logFont; + + memset(&logFont, 0, sizeof(logFont)); + + logFont.lfCharSet = GetCharsetFromCodePage(codePage); + + const char* fontFace = GetFontFaceFromCodePage9x(codePage); + + HDC hDC=GetDC(NULL); + + if(EnumFontFamiliesEx(hDC, &logFont, (FONTENUMPROC)EnumFontFamExProc, (LONG)fontFace, 0) == 0) + { + ReleaseDC(NULL, hDC); + return fontFace; + } + + fontFace = GetFontFaceFromCodePageNT(codePage); + + if(EnumFontFamiliesEx(hDC, &logFont, (FONTENUMPROC)EnumFontFamExProc, (LONG)fontFace, 0) == 0) + { + ReleaseDC(NULL, hDC); + return fontFace; + } + + ReleaseDC(NULL, hDC); + + return GetDefaultFontFace(); +} + +void SetDefaultFontFace(const char* fontFace) +{ + gs_fontFace=fontFace; +} + +bool SetDefaultCodePage(DWORD codePage) +{ + gs_codePage=codePage; + + std::string fontFace=GetFontFaceFromCodePage(codePage); + if (fontFace.empty()) + return false; + + SetDefaultFontFace(fontFace.c_str()); + + return true; +} + + +int __base64_get( const int c ) +{ + if( 'A' <= c && c <= 'Z' ) + return c-'A'; + if( 'a' <= c && c <= 'z' ) + return c - 'a' + 26; + if( '0' <= c && c <= '9' ) + return c - '0' + 52; + if( c == '+' ) + return 62; + if( c == '/' ) + return 63; + if( c == '=' ) // end of line + return -1; + return -2; // non value; +} + +void __strcat1(char * str,int i) +{ + char result[2]; + result[0] = i; + result[1] = NULL; + strcat(str,result); +} + +void base64_decode(const char * str,char * resultStr) +{ + int nCount=0, i=0, r, result; + int length = strlen(str); + char szDest[5]=""; + + strcpy(resultStr,""); + while(nCount < length) + { + i=0; + strcpy(szDest, ""); + while(nCount= length ) // ߴ. + { + if( szDest[1] == '@' ) + { + __strcat1(resultStr,(szDest[0]<<2)); + break; + }// exit while loop + else + __strcat1(resultStr,(szDest[0]<<2 | szDest[1]>>4)); // 1 Byte + if( szDest[2] == '@' ) + { + __strcat1(resultStr,(szDest[1]<<4)); + break; + } + else + __strcat1(resultStr,(szDest[1]<<4 | szDest[2]>>2)); // 2 Byte + if( szDest[3] == '@' ) + { + __strcat1(resultStr,(szDest[2]<<6)); + break; + } + else + __strcat1(resultStr,(szDest[2]<<6 | szDest[3])); // 3 Byte + } + else + { + __strcat1(resultStr,(szDest[0]<<2 | szDest[1]>>4)); // 1 Byte + __strcat1(resultStr,(szDest[1]<<4 | szDest[2]>>2)); // 2 Byte + __strcat1(resultStr,(szDest[2]<<6 | szDest[3])); // 3 Byte + } + } + + }// end of while + + for (i = 0; i < strlen(resultStr); i++) + { + char c = resultStr[i]; + int xx = i + 5; + resultStr[i] = char(c ^ xx); + } + // E +} diff --git a/source/EterLib/Util.h b/source/EterLib/Util.h new file mode 100644 index 0000000..dc13a91 --- /dev/null +++ b/source/EterLib/Util.h @@ -0,0 +1,113 @@ +#pragma once + + +#include "../eterBase/FileLoader.h" + +#include +#include + +#include + +template +class CTransitor +{ + public: + CTransitor() {} + ~CTransitor() {} + + void SetActive(BOOL bActive = TRUE) + { + m_bActivated = bActive; + } + + BOOL isActive() + { + return m_bActivated; + } + + BOOL isActiveTime(float fcurTime) + { + if (fcurTime >= m_fEndTime) + return FALSE; + + return TRUE; + } + + DWORD GetID() + { + return m_dwID; + } + + void SetID(DWORD dwID) + { + m_dwID = dwID; + } + + void SetSourceValue(const T & c_rSourceValue) + { + m_SourceValue = c_rSourceValue; + } + + void SetTransition(const T & c_rSourceValue, const T & c_rTargetValue, float fStartTime, float fBlendTime) + { + m_SourceValue = c_rSourceValue; + m_TargetValue = c_rTargetValue; + m_fStartTime = fStartTime; + m_fEndTime = fStartTime + fBlendTime; + } + + BOOL GetValue(float fcurTime, T * pValue) + { + if (fcurTime <= m_fStartTime) + return FALSE; + + float fPercentage = (fcurTime - m_fStartTime) / (m_fEndTime - m_fStartTime); + *pValue = m_SourceValue + (m_TargetValue - m_SourceValue) * fPercentage; + return TRUE; + } + + protected: + DWORD m_dwID; // Public Transitor ID + + BOOL m_bActivated; // Have been started to blend? + float m_fStartTime; + float m_fEndTime; + + T m_SourceValue; + T m_TargetValue; +}; + +typedef CTransitor TTransitorFloat; +typedef CTransitor TTransitorVector3; +typedef CTransitor TTransitorColor; + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +void PrintfTabs(FILE * File, int iTabCount, const char * c_szString, ...); + + +//typedef CTokenVector TTokenVector; + +extern bool LoadTextData(const char * c_szFileName, CTokenMap & rstTokenMap); +extern bool LoadMultipleTextData(const char * c_szFileName, CTokenVectorMap & rstTokenVectorMap); + +extern D3DXVECTOR3 TokenToVector(CTokenVector & rVector); +extern D3DXCOLOR TokenToColor(CTokenVector & rVector); + +#define GOTO_CHILD_NODE(TextFileLoader, Index) CTextFileLoader::CGotoChild Child(TextFileLoader, Index); + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +extern int CALLBACK EnumFontFamExProc(CONST LOGFONT* plogFont, CONST TEXTMETRIC* textMetric, DWORD dwWord, LPARAM lParam); +extern int GetCharsetFromCodePage(WORD codePage); +extern const char* GetFontFaceFromCodePageNT(WORD codePage); +extern const char* GetFontFaceFromCodePage9x(WORD codePage); +extern DWORD GetDefaultCodePage(); +extern const char * GetDefaultFontFace(); +extern const char* GetFontFaceFromCodePage(WORD codePage); +extern void SetDefaultFontFace(const char* fontFace); +extern bool SetDefaultCodePage(DWORD codePage); +extern void base64_decode(const char * str,char * resultStr); + +extern DWORD GetMaxTextureWidth(); +extern DWORD GetMaxTextureHeight(); \ No newline at end of file diff --git a/source/EterLib/lineintersect_utils.cpp b/source/EterLib/lineintersect_utils.cpp new file mode 100644 index 0000000..2bcb1e6 --- /dev/null +++ b/source/EterLib/lineintersect_utils.cpp @@ -0,0 +1,849 @@ +/************************************************************************************** + | File: lineintersect_utils.cpp + | Purpose: Implementation of line segment intersection utility functions + | Book Title: Game Programming Gems II + | Chapter Title: Fast, Robust Intersection of 3D Line Segments + | Author: Graham Rhodes + | Revisions: 05-Apr-2001 - GSR. Original. + **************************************************************************************/ +#include "Stdafx.h" +#include +#include "lineintersect_utils.h" +#include + +// uncomment the following line to have the code check intermediate results +//#define CHECK_ANSWERS + +// uncomment the following line to use Cramer's rule instead of Gaussian elimination +//#define USE_CRAMERS_RULE + +#define FMAX(a,b) ((a) > (b) ? (a) : (b)) +#define FMIN(a,b) ((a) > (b) ? (b) : (a)) +#define FABS(a) ((a) < 0.0f ? -(a) : (a)) +#define OUT_OF_RANGE(a) ((a) < 0.0f || (a) > 1.f) + +#define MY_EPSILON 0.1f + +__forceinline void FindNearestPointOnLineSegment(const D3DXVECTOR3 & A1, + const D3DXVECTOR3 & L, + const D3DXVECTOR3 & B, + D3DXVECTOR3 & Nearest, + float ¶meter) +{ + // Line/Segment is degenerate --- special case #1 + float D = D3DXVec3LengthSq(&L); + if (D < MY_EPSILON*MY_EPSILON) + { + Nearest = A1; + return; + } + + D3DXVECTOR3 AB = B-A1; + + // parameter is computed from Equation (20). + parameter = (D3DXVec3Dot(&AB,&L)) / D; + + //if (false == infinite_line) + parameter = FMAX(0.0f, FMIN(1.0f, parameter)); + + Nearest = A1 + parameter * L; + return; +} + +/************************************************************************** +| +| Method: FindNearestPointOfParallelLineSegments +| +| Purpose: Given two lines (segments) that are known to be parallel, find +| a representative point on each that is nearest to the other. If +| the lines are considered to be finite then it is possible that there +| is one true point on each line that is nearest to the other. This +| code properly handles this case. +| +| This is the most difficult line intersection case to handle, since +| there is potentially a family, or locus of points on each line/segment +| that are nearest to the other. +| Parameters: Input: +| ------ +| A1x, A1y, A1z - Coordinates of first defining point of line/segment A +| A2x, A2y, A2z - Coordinates of second defining point of line/segment A +| Lax, Lay, Laz - Vector from (A1x, A1y, A1z) to the (A2x, A2y, A2z). +| B1x, B1y, B1z - Coordinates of first defining point of line/segment B +| B2x, B2y, B2z - Coordinates of second defining point of line/segment B +| Lbx, Lby, Lbz - Vector from (B1x, B1y, B1z) to the (B2x, B2y, B2z). +| infinite_lines - set to true if lines are to be treated as infinite +| epsilon_squared - tolerance value to be used to check for degenerate +| and parallel lines, and to check for true intersection. +| +| Output: +| ------- +| PointOnSegAx, - Coordinates of the point on segment A that are nearest +| PointOnSegAy, to segment B. This corresponds to point C in the text. +| PointOnSegAz +| PointOnSegBx, - Coordinates of the point on segment B that are nearest +| PointOnSegBy, to segment A. This corresponds to point D in the text. +| PointOnSegBz + +**************************************************************************/ +__forceinline void FindNearestPointOfParallelLineSegments(const D3DXVECTOR3 & A1, + const D3DXVECTOR3 & A2, + const D3DXVECTOR3 & La, + const D3DXVECTOR3 & B1, + const D3DXVECTOR3 & B2, + const D3DXVECTOR3 & Lb, + //bool infinite_lines, float epsilon_squared, + D3DXVECTOR3 & OutA, + D3DXVECTOR3 & OutB) +{ + float s[2], temp; + FindNearestPointOnLineSegment(A1, La, B1, OutA, s[0]); + /*if (true == infinite_lines) + { + PointOnSegBx = B1x; + PointOnSegBy = B1y; + PointOnSegBz = B1z; + } + else*/ + { + //float tp[3]; + D3DXVECTOR3 tp; + FindNearestPointOnLineSegment(A1, La, B2, + tp, s[1]); + if (s[0] < 0.f && s[1] < 0.f) + { + OutA = A1; + if (s[0] < s[1]) + { + OutB =B2; + } + else + { + OutB = B1; + } + } + else if (s[0] > 1.f && s[1] > 1.f) + { + OutA = A2; + if (s[0] < s[1]) + { + OutB = B1; + } + else + { + OutB = B2; + } + } + else + { + temp = 0.5f*(FMAX(0.0f, FMIN(1.0f, s[0])) + FMAX(0.0f, FMIN(1.0f, s[1]))); + OutA = A1 + temp * La; + FindNearestPointOnLineSegment(B1, Lb, + OutA, OutB, temp); + } + } +} + +/************************************************************************** +| +| Method: AdjustNearestPoints +| +| Purpose: Given nearest point information for two infinite lines, adjust +| to model finite line segments. +| +| Parameters: Input: +| ------ +| A1x, A1y, A1z - Coordinates of first defining point of line/segment A +| Lax, Lay, Laz - Vector from (A1x, A1y, A1z) to the (A2x, A2y, A2z). +| B1x, B1y, B1z - Coordinates of first defining point of line/segment B +| Lbx, Lby, Lbz - Vector from (B1x, B1y, B1z) to the (B2x, B2y, B2z). +| epsilon_squared - tolerance value to be used to check for degenerate +| and parallel lines, and to check for true intersection. +| s - parameter representing nearest point on infinite line A +| t - parameter representing nearest point on infinite line B +| +| Output: +| ------- +| PointOnSegAx, - Coordinates of the point on segment A that are nearest +| PointOnSegAy, to segment B. This corresponds to point C in the text. +| PointOnSegAz +| PointOnSegBx, - Coordinates of the point on segment B that are nearest +| PointOnSegBy, to segment A. This corresponds to point D in the text. +| PointOnSegBz +**************************************************************************/ +__forceinline void AdjustNearestPoints(const D3DXVECTOR3 & A1, + const D3DXVECTOR3 & La, + const D3DXVECTOR3 & B1, + const D3DXVECTOR3 & Lb, + float s, float t, + D3DXVECTOR3 & OutA, + D3DXVECTOR3 & OutB) +{ + // handle the case where both parameter s and t are out of range + if (OUT_OF_RANGE(s) && OUT_OF_RANGE(t)) + { + s = FMAX(0.0f, FMIN(1.0f, s)); + OutA = A1 + s*La; + FindNearestPointOnLineSegment(B1, Lb, + OutA, + OutB, t); + if (OUT_OF_RANGE(t)) + { + t = FMAX(0.0f, FMIN(1.0f, t)); + OutB = B1 + t*Lb; + FindNearestPointOnLineSegment(A1, La, OutB, + OutA, s); + FindNearestPointOnLineSegment(B1, Lb, OutA, + OutB, t); + } + } + // otherwise, handle the case where the parameter for only one segment is + // out of range + else if (OUT_OF_RANGE(s)) + { + s = FMAX(0.0f, FMIN(1.0f, s)); + OutA = A1 + s*La; + FindNearestPointOnLineSegment(B1, Lb, + OutA, + OutB, t); + } + else if (OUT_OF_RANGE(t)) + { + t = FMAX(0.0f, FMIN(1.0f, t)); + OutB = B1 + t*Lb; + FindNearestPointOnLineSegment(A1, La, OutB, + OutA, s); + } + else + { + assert(0); + } +} + +void IntersectLineSegments(const D3DXVECTOR3 & A1, + const D3DXVECTOR3 & A2, + const D3DXVECTOR3 & B1, + const D3DXVECTOR3 & B2, + //bool infinite_lines, /*float epsilon,*/ + D3DXVECTOR3 & OutA, + D3DXVECTOR3 & OutB) +{ + float temp = 0.f; + const float epsilon = MY_EPSILON; + const float epsilon_squared = MY_EPSILON*MY_EPSILON; + + // Compute parameters from Equations (1) and (2) in the text + D3DXVECTOR3 La = A2-A1; + D3DXVECTOR3 Lb = B2-B1; + // From Equation (15) + float L11 = D3DXVec3LengthSq(&La); + float L22 = D3DXVec3LengthSq(&Lb); + + // Line/Segment A is degenerate ---- Special Case #1 + if (L11 < epsilon_squared) + { + OutA = A1; + FindNearestPointOnLineSegment(B1, Lb, A1, + OutB, temp); + } + // Line/Segment B is degenerate ---- Special Case #1 + else if (L22 < epsilon_squared) + { + OutB = B1; + FindNearestPointOnLineSegment(A1, La, B1, + OutA, temp); + } + // Neither line/segment is degenerate + else + { + // Compute more parameters from Equation (3) in the text. + D3DXVECTOR3 AB = B1 - A1; + + // and from Equation (15). + float L12 = -D3DXVec3Dot(&La, &Lb); + + float DetL = L11 * L22 - L12 * L12; + // Lines/Segments A and B are parallel ---- special case #2. + if (FABS(DetL) < epsilon) + { + FindNearestPointOfParallelLineSegments(A1, A2, + La, + B1, B2, + Lb, + OutA, OutB); + } + // The general case + else + { + // from Equation (15) + float ra = D3DXVec3Dot(&La, &AB);//Lax * ABx + Lay * ABy + Laz * ABz; + float rb = D3DXVec3Dot(&Lb, &AB);//-Lbx * ABx - Lby * ABy - Lbz * ABz; + + float t = (L11 * rb - ra * L12)/DetL; // Equation (12) + +#ifdef USE_CRAMERS_RULE + float s = (L22 * ra - rb * L12)/DetL; +#else + float s = (ra-L12*t)/L11; // Equation (13) +#endif // USE_CRAMERS_RULE + +#ifdef CHECK_ANSWERS + float check_ra = s*L11 + t*L12; + float check_rb = s*L12 + t*L22; + assert(FABS(check_ra-ra) < epsilon); + assert(FABS(check_rb-rb) < epsilon); +#endif // CHECK_ANSWERS + + // if we are dealing with infinite lines or if parameters s and t both + // lie in the range [0,1] then just compute the points using Equations + // (1) and (2) from the text. + OutA = (A1 + s * La); + OutB = (B1 + t * Lb); + // otherwise, at least one of s and t is outside of [0,1] and we have to + // handle this case. + if ((OUT_OF_RANGE(s) || OUT_OF_RANGE(t))) + { + AdjustNearestPoints(A1,La,B1,Lb, + s, t, + OutA, + OutB); + } + } + } +} + +void IntersectLineSegments(const float A1x, const float A1y, const float A1z, + const float A2x, const float A2y, const float A2z, + const float B1x, const float B1y, const float B1z, + const float B2x, const float B2y, const float B2z, + bool infinite_lines, float epsilon, float &PointOnSegAx, + float &PointOnSegAy, float &PointOnSegAz, float &PointOnSegBx, + float &PointOnSegBy, float &PointOnSegBz) +{ + float temp = 0.f; + float epsilon_squared = epsilon * epsilon; + + // Compute parameters from Equations (1) and (2) in the text + float Lax = A2x - A1x; + float Lay = A2y - A1y; + float Laz = A2z - A1z; + float Lbx = B2x - B1x; + float Lby = B2y - B1y; + float Lbz = B2z - B1z; + // From Equation (15) + float L11 = (Lax * Lax) + (Lay * Lay) + (Laz * Laz); + float L22 = (Lbx * Lbx) + (Lby * Lby) + (Lbz * Lbz); + + // Line/Segment A is degenerate ---- Special Case #1 + if (L11 < epsilon_squared) + { + PointOnSegAx = A1x; + PointOnSegAy = A1y; + PointOnSegAz = A1z; + FindNearestPointOnLineSegment(B1x, B1y, B1z, Lbx, Lby, Lbz, A1x, A1y, A1z, + infinite_lines, epsilon, PointOnSegBx, PointOnSegBy, + PointOnSegBz, temp); + } + // Line/Segment B is degenerate ---- Special Case #1 + else if (L22 < epsilon_squared) + { + PointOnSegBx = B1x; + PointOnSegBy = B1y; + PointOnSegBz = B1z; + FindNearestPointOnLineSegment(A1x, A1y, A1z, Lax, Lay, Laz, B1x, B1y, B1z, + infinite_lines, epsilon, PointOnSegAx, PointOnSegAy, + PointOnSegAz, temp); + } + // Neither line/segment is degenerate + else + { + // Compute more parameters from Equation (3) in the text. + float ABx = B1x - A1x; + float ABy = B1y - A1y; + float ABz = B1z - A1z; + + // and from Equation (15). + float L12 = -(Lax * Lbx) - (Lay * Lby) - (Laz * Lbz); + + float DetL = L11 * L22 - L12 * L12; + // Lines/Segments A and B are parallel ---- special case #2. + if (FABS(DetL) < epsilon) + { + FindNearestPointOfParallelLineSegments(A1x, A1y, A1z, A2x, A2y, A2z, + Lax, Lay, Laz, + B1x, B1y, B1z, B2x, B2y, B2z, + Lbx, Lby, Lbz, + infinite_lines, epsilon, + PointOnSegAx, PointOnSegAy, PointOnSegAz, + PointOnSegBx, PointOnSegBy, PointOnSegBz); + } + // The general case + else + { + // from Equation (15) + float ra = Lax * ABx + Lay * ABy + Laz * ABz; + float rb = -Lbx * ABx - Lby * ABy - Lbz * ABz; + + float t = (L11 * rb - ra * L12)/DetL; // Equation (12) + +#ifdef USE_CRAMERS_RULE + float s = (L22 * ra - rb * L12)/DetL; +#else + float s = (ra-L12*t)/L11; // Equation (13) +#endif // USE_CRAMERS_RULE + +#ifdef CHECK_ANSWERS + float check_ra = s*L11 + t*L12; + float check_rb = s*L12 + t*L22; + assert(FABS(check_ra-ra) < epsilon); + assert(FABS(check_rb-rb) < epsilon); +#endif // CHECK_ANSWERS + + // if we are dealing with infinite lines or if parameters s and t both + // lie in the range [0,1] then just compute the points using Equations + // (1) and (2) from the text. + PointOnSegAx = (A1x + s * Lax); + PointOnSegAy = (A1y + s * Lay); + PointOnSegAz = (A1z + s * Laz); + PointOnSegBx = (B1x + t * Lbx); + PointOnSegBy = (B1y + t * Lby); + PointOnSegBz = (B1z + t * Lbz); + // otherwise, at least one of s and t is outside of [0,1] and we have to + // handle this case. + if (false == infinite_lines && (OUT_OF_RANGE(s) || OUT_OF_RANGE(t))) + { + AdjustNearestPoints(A1x, A1y, A1z, Lax, Lay, Laz, + B1x, B1y, B1z, Lbx, Lby, Lbz, + epsilon, s, t, + PointOnSegAx, PointOnSegAy, PointOnSegAz, + PointOnSegBx, PointOnSegBy, PointOnSegBz); + } + } + } + +} + + +// pragma to get rid of math.h inline function removal warnings. +#pragma warning(disable:4514) + +/************************************************************************** +| +| Method: IntersectLineSegments +| +| Purpose: Find the nearest point between two finite length line segments +| or two infinite lines in 3-dimensional space. The function calculates +| the point on each line/line segment that is closest to the other +| line/line segment, the midpoint between the nearest points, and +| the vector between these two points. If the two nearest points +| are close within a tolerance, a flag is set indicating the lines +| have a "true" intersection. +| +| Parameters: Input: +| ------ +| A1x, A1y, A1z - Coordinates of first defining point of line/segment A +| A2x, A2y, A2z - Coordinates of second defining point of line/segment A +| B1x, B1y, B1z - Coordinates of first defining point of line/segment B +| B2x, B2y, B2z - Coordinates of second defining point of line/segment B +| infinite_lines - set to true if lines are to be treated as infinite +| epsilon - tolerance value to be used to check for degenerate +| and parallel lines, and to check for true intersection. +| +| Output: +| ------- +| PointOnSegAx, - Coordinates of the point on segment A that are nearest +| PointOnSegAy, to segment B. This corresponds to point C in the text. +| PointOnSegAz +| PointOnSegBx, - Coordinates of the point on segment B that are nearest +| PointOnSegBy, to segment A. This corresponds to point D in the text. +| PointOnSegBz +| NearestPointX, - Midpoint between the two nearest points. This can be +| NearestPointY, treated as *the* intersection point if nearest points +| NearestPointZ are sufficiently close. This corresponds to point P +| in the text. +| NearestVectorX, - Vector between the nearest point on A to the nearest +| point on segment B. This vector is normal to both +| lines if the lines are infinite, but is not guaranteed +| to be normal to both lines if both lines are finite +| length. +| true_intersection - true if the nearest points are close within a small +| tolerance. +**************************************************************************/ +void IntersectLineSegments(const float A1x, const float A1y, const float A1z, + const float A2x, const float A2y, const float A2z, + const float B1x, const float B1y, const float B1z, + const float B2x, const float B2y, const float B2z, + bool infinite_lines, float epsilon, float &PointOnSegAx, + float &PointOnSegAy, float &PointOnSegAz, float &PointOnSegBx, + float &PointOnSegBy, float &PointOnSegBz, float &NearestPointX, + float &NearestPointY, float &NearestPointZ, float &NearestVectorX, + float &NearestVectorY, float &NearestVectorZ, bool &true_intersection) +{ + float temp = 0.f; + float epsilon_squared = epsilon * epsilon; + + // Compute parameters from Equations (1) and (2) in the text + float Lax = A2x - A1x; + float Lay = A2y - A1y; + float Laz = A2z - A1z; + float Lbx = B2x - B1x; + float Lby = B2y - B1y; + float Lbz = B2z - B1z; + // From Equation (15) + float L11 = (Lax * Lax) + (Lay * Lay) + (Laz * Laz); + float L22 = (Lbx * Lbx) + (Lby * Lby) + (Lbz * Lbz); + + // Line/Segment A is degenerate ---- Special Case #1 + if (L11 < epsilon_squared) + { + PointOnSegAx = A1x; + PointOnSegAy = A1y; + PointOnSegAz = A1z; + FindNearestPointOnLineSegment(B1x, B1y, B1z, Lbx, Lby, Lbz, A1x, A1y, A1z, + infinite_lines, epsilon, PointOnSegBx, PointOnSegBy, + PointOnSegBz, temp); + } + // Line/Segment B is degenerate ---- Special Case #1 + else if (L22 < epsilon_squared) + { + PointOnSegBx = B1x; + PointOnSegBy = B1y; + PointOnSegBz = B1z; + FindNearestPointOnLineSegment(A1x, A1y, A1z, Lax, Lay, Laz, B1x, B1y, B1z, + infinite_lines, epsilon, PointOnSegAx, PointOnSegAy, + PointOnSegAz, temp); + } + // Neither line/segment is degenerate + else + { + // Compute more parameters from Equation (3) in the text. + float ABx = B1x - A1x; + float ABy = B1y - A1y; + float ABz = B1z - A1z; + + // and from Equation (15). + float L12 = -(Lax * Lbx) - (Lay * Lby) - (Laz * Lbz); + + float DetL = L11 * L22 - L12 * L12; + // Lines/Segments A and B are parallel ---- special case #2. + if (FABS(DetL) < epsilon) + { + FindNearestPointOfParallelLineSegments(A1x, A1y, A1z, A2x, A2y, A2z, + Lax, Lay, Laz, + B1x, B1y, B1z, B2x, B2y, B2z, + Lbx, Lby, Lbz, + infinite_lines, epsilon, + PointOnSegAx, PointOnSegAy, PointOnSegAz, + PointOnSegBx, PointOnSegBy, PointOnSegBz); + } + // The general case + else + { + // from Equation (15) + float ra = Lax * ABx + Lay * ABy + Laz * ABz; + float rb = -Lbx * ABx - Lby * ABy - Lbz * ABz; + + float t = (L11 * rb - ra * L12)/DetL; // Equation (12) + +#ifdef USE_CRAMERS_RULE + float s = (L22 * ra - rb * L12)/DetL; +#else + float s = (ra-L12*t)/L11; // Equation (13) +#endif // USE_CRAMERS_RULE + +#ifdef CHECK_ANSWERS + float check_ra = s*L11 + t*L12; + float check_rb = s*L12 + t*L22; + assert(FABS(check_ra-ra) < epsilon); + assert(FABS(check_rb-rb) < epsilon); +#endif // CHECK_ANSWERS + + // if we are dealing with infinite lines or if parameters s and t both + // lie in the range [0,1] then just compute the points using Equations + // (1) and (2) from the text. + PointOnSegAx = (A1x + s * Lax); + PointOnSegAy = (A1y + s * Lay); + PointOnSegAz = (A1z + s * Laz); + PointOnSegBx = (B1x + t * Lbx); + PointOnSegBy = (B1y + t * Lby); + PointOnSegBz = (B1z + t * Lbz); + // otherwise, at least one of s and t is outside of [0,1] and we have to + // handle this case. + if (false == infinite_lines && (OUT_OF_RANGE(s) || OUT_OF_RANGE(t))) + { + AdjustNearestPoints(A1x, A1y, A1z, Lax, Lay, Laz, + B1x, B1y, B1z, Lbx, Lby, Lbz, + epsilon, s, t, + PointOnSegAx, PointOnSegAy, PointOnSegAz, + PointOnSegBx, PointOnSegBy, PointOnSegBz); + } + } + } + + NearestPointX = 0.5f * (PointOnSegAx + PointOnSegBx); + NearestPointY = 0.5f * (PointOnSegAy + PointOnSegBy); + NearestPointZ = 0.5f * (PointOnSegAz + PointOnSegBz); + + NearestVectorX = PointOnSegBx - PointOnSegAx; + NearestVectorY = PointOnSegBy - PointOnSegAy; + NearestVectorZ = PointOnSegBz - PointOnSegAz; + + // optional check to indicate if the lines truly intersect + true_intersection = (FABS(NearestVectorX) + + FABS(NearestVectorY) + + FABS(NearestVectorZ)) < epsilon ? true : false; +} + +/************************************************************************** +| +| Method: FindNearestPointOnLineSegment +| +| Purpose: Given a line (segment) and a point in 3-dimensional space, +| find the point on the line (segment) that is closest to the +| point. +| +| Parameters: Input: +| ------ +| A1x, A1y, A1z - Coordinates of first defining point of the line/segment +| Lx, Ly, Lz - Vector from (A1x, A1y, A1z) to the second defining point +| of the line/segment. +| Bx, By, Bz - Coordinates of the point +| infinite_lines - set to true if lines are to be treated as infinite +| epsilon_squared - tolerance value to be used to check for degenerate +| and parallel lines, and to check for true intersection. +| +| Output: +| ------- +| NearestPointX, - Point on line/segment that is closest to (Bx, By, Bz) +| NearestPointY, +| NearestPointZ +| parameter - Parametric coordinate of the nearest point along the +| line/segment. parameter = 0 at (A1x, A1y, A1z) and +| parameter = 1 at the second defining point of the line/ +| segmetn +**************************************************************************/ +void FindNearestPointOnLineSegment(const float A1x, const float A1y, const float A1z, + const float Lx, const float Ly, const float Lz, + const float Bx, const float By, const float Bz, + bool infinite_line, float epsilon_squared, float &NearestPointX, + float &NearestPointY, float &NearestPointZ, + float ¶meter) +{ + // Line/Segment is degenerate --- special case #1 + float D = Lx * Lx + Ly * Ly + Lz * Lz; + if (D < epsilon_squared) + { + NearestPointX = A1x; + NearestPointY = A1y; + NearestPointZ = A1z; + return; + } + + float ABx = Bx - A1x; + float ABy = By - A1y; + float ABz = Bz - A1z; + + // parameter is computed from Equation (20). + parameter = (Lx * ABx + Ly * ABy + Lz * ABz) / D; + + if (false == infinite_line) parameter = FMAX(0.0f, FMIN(1.0f, parameter)); + + NearestPointX = A1x + parameter * Lx; + NearestPointY = A1y + parameter * Ly; + NearestPointZ = A1z + parameter * Lz; + return; +} + +/************************************************************************** +| +| Method: FindNearestPointOfParallelLineSegments +| +| Purpose: Given two lines (segments) that are known to be parallel, find +| a representative point on each that is nearest to the other. If +| the lines are considered to be finite then it is possible that there +| is one true point on each line that is nearest to the other. This +| code properly handles this case. +| +| This is the most difficult line intersection case to handle, since +| there is potentially a family, or locus of points on each line/segment +| that are nearest to the other. +| Parameters: Input: +| ------ +| A1x, A1y, A1z - Coordinates of first defining point of line/segment A +| A2x, A2y, A2z - Coordinates of second defining point of line/segment A +| Lax, Lay, Laz - Vector from (A1x, A1y, A1z) to the (A2x, A2y, A2z). +| B1x, B1y, B1z - Coordinates of first defining point of line/segment B +| B2x, B2y, B2z - Coordinates of second defining point of line/segment B +| Lbx, Lby, Lbz - Vector from (B1x, B1y, B1z) to the (B2x, B2y, B2z). +| infinite_lines - set to true if lines are to be treated as infinite +| epsilon_squared - tolerance value to be used to check for degenerate +| and parallel lines, and to check for true intersection. +| +| Output: +| ------- +| PointOnSegAx, - Coordinates of the point on segment A that are nearest +| PointOnSegAy, to segment B. This corresponds to point C in the text. +| PointOnSegAz +| PointOnSegBx, - Coordinates of the point on segment B that are nearest +| PointOnSegBy, to segment A. This corresponds to point D in the text. +| PointOnSegBz + +**************************************************************************/ +void FindNearestPointOfParallelLineSegments(float A1x, float A1y, float A1z, + float A2x, float A2y, float A2z, + float Lax, float Lay, float Laz, + float B1x, float B1y, float B1z, + float B2x, float B2y, float B2z, + float Lbx, float Lby, float Lbz, + bool infinite_lines, float epsilon_squared, + float &PointOnSegAx, float &PointOnSegAy, float &PointOnSegAz, + float &PointOnSegBx, float &PointOnSegBy, float &PointOnSegBz) +{ + float s[2], temp; + FindNearestPointOnLineSegment(A1x, A1y, A1z, Lax, Lay, Laz, B1x, B1y, B1z, + true, epsilon_squared, PointOnSegAx, PointOnSegAy, PointOnSegAz, s[0]); + if (true == infinite_lines) + { + PointOnSegBx = B1x; + PointOnSegBy = B1y; + PointOnSegBz = B1z; + } + else + { + float tp[3]; + FindNearestPointOnLineSegment(A1x, A1y, A1z, Lax, Lay, Laz, B2x, B2y, B2z, + true, epsilon_squared, tp[0], tp[1], tp[2], s[1]); + if (s[0] < 0.f && s[1] < 0.f) + { + PointOnSegAx = A1x; + PointOnSegAy = A1y; + PointOnSegAz = A1z; + if (s[0] < s[1]) + { + PointOnSegBx = B2x; + PointOnSegBy = B2y; + PointOnSegBz = B2z; + } + else + { + PointOnSegBx = B1x; + PointOnSegBy = B1y; + PointOnSegBz = B1z; + } + } + else if (s[0] > 1.f && s[1] > 1.f) + { + PointOnSegAx = A2x; + PointOnSegAy = A2y; + PointOnSegAz = A2z; + if (s[0] < s[1]) + { + PointOnSegBx = B1x; + PointOnSegBy = B1y; + PointOnSegBz = B1z; + } + else + { + PointOnSegBx = B2x; + PointOnSegBy = B2y; + PointOnSegBz = B2z; + } + } + else + { + temp = 0.5f*(FMAX(0.0f, FMIN(1.0f, s[0])) + FMAX(0.0f, FMIN(1.0f, s[1]))); + PointOnSegAx = (A1x + temp * Lax); + PointOnSegAy = (A1y + temp * Lay); + PointOnSegAz = (A1z + temp * Laz); + FindNearestPointOnLineSegment(B1x, B1y, B1z, Lbx, Lby, Lbz, + PointOnSegAx, PointOnSegAy, PointOnSegAz, true, + epsilon_squared, PointOnSegBx, PointOnSegBy, PointOnSegBz, temp); + } + } +} + +/************************************************************************** +| +| Method: AdjustNearestPoints +| +| Purpose: Given nearest point information for two infinite lines, adjust +| to model finite line segments. +| +| Parameters: Input: +| ------ +| A1x, A1y, A1z - Coordinates of first defining point of line/segment A +| Lax, Lay, Laz - Vector from (A1x, A1y, A1z) to the (A2x, A2y, A2z). +| B1x, B1y, B1z - Coordinates of first defining point of line/segment B +| Lbx, Lby, Lbz - Vector from (B1x, B1y, B1z) to the (B2x, B2y, B2z). +| epsilon_squared - tolerance value to be used to check for degenerate +| and parallel lines, and to check for true intersection. +| s - parameter representing nearest point on infinite line A +| t - parameter representing nearest point on infinite line B +| +| Output: +| ------- +| PointOnSegAx, - Coordinates of the point on segment A that are nearest +| PointOnSegAy, to segment B. This corresponds to point C in the text. +| PointOnSegAz +| PointOnSegBx, - Coordinates of the point on segment B that are nearest +| PointOnSegBy, to segment A. This corresponds to point D in the text. +| PointOnSegBz +**************************************************************************/ +void AdjustNearestPoints(float A1x, float A1y, float A1z, + float Lax, float Lay, float Laz, + float B1x, float B1y, float B1z, + float Lbx, float Lby, float Lbz, + float epsilon_squared, float s, float t, + float &PointOnSegAx, float &PointOnSegAy, float &PointOnSegAz, + float &PointOnSegBx, float &PointOnSegBy, float &PointOnSegBz) +{ + // handle the case where both parameter s and t are out of range + if (OUT_OF_RANGE(s) && OUT_OF_RANGE(t)) + { + s = FMAX(0.0f, FMIN(1.0f, s)); + PointOnSegAx = (A1x + s * Lax); + PointOnSegAy = (A1y + s * Lay); + PointOnSegAz = (A1z + s * Laz); + FindNearestPointOnLineSegment(B1x, B1y, B1z, Lbx, Lby, Lbz, PointOnSegAx, + PointOnSegAy, PointOnSegAz, true, epsilon_squared, + PointOnSegBx, PointOnSegBy, PointOnSegBz, t); + if (OUT_OF_RANGE(t)) + { + t = FMAX(0.0f, FMIN(1.0f, t)); + PointOnSegBx = (B1x + t * Lbx); + PointOnSegBy = (B1y + t * Lby); + PointOnSegBz = (B1z + t * Lbz); + FindNearestPointOnLineSegment(A1x, A1y, A1z, Lax, Lay, Laz, PointOnSegBx, + PointOnSegBy, PointOnSegBz, false, epsilon_squared, + PointOnSegAx, PointOnSegAy, PointOnSegAz, s); + FindNearestPointOnLineSegment(B1x, B1y, B1z, Lbx, Lby, Lbz, PointOnSegAx, + PointOnSegAy, PointOnSegAz, false, epsilon_squared, + PointOnSegBx, PointOnSegBy, PointOnSegBz, t); + } + } + // otherwise, handle the case where the parameter for only one segment is + // out of range + else if (OUT_OF_RANGE(s)) + { + s = FMAX(0.0f, FMIN(1.0f, s)); + PointOnSegAx = (A1x + s * Lax); + PointOnSegAy = (A1y + s * Lay); + PointOnSegAz = (A1z + s * Laz); + FindNearestPointOnLineSegment(B1x, B1y, B1z, Lbx, Lby, Lbz, PointOnSegAx, + PointOnSegAy, PointOnSegAz, false, epsilon_squared, + PointOnSegBx, PointOnSegBy, PointOnSegBz, t); + } + else if (OUT_OF_RANGE(t)) + { + t = FMAX(0.0f, FMIN(1.0f, t)); + PointOnSegBx = (B1x + t * Lbx); + PointOnSegBy = (B1y + t * Lby); + PointOnSegBz = (B1z + t * Lbz); + FindNearestPointOnLineSegment(A1x, A1y, A1z, Lax, Lay, Laz, PointOnSegBx, + PointOnSegBy, PointOnSegBz, false, epsilon_squared, + PointOnSegAx, PointOnSegAy, PointOnSegAz, s); + } + else + { + assert(0); + } +} diff --git a/source/EterLib/lineintersect_utils.h b/source/EterLib/lineintersect_utils.h new file mode 100644 index 0000000..f8b107c --- /dev/null +++ b/source/EterLib/lineintersect_utils.h @@ -0,0 +1,80 @@ +/* Copyright (C) Graham Rhodes, 2001. + * All rights reserved worldwide. + * + * This software is provided "as is" without express or implied + * warranties. You may freely copy and compile this source into + * applications you distribute provided that the copyright text + * below is included in the resulting source code, for example: + * "Portions Copyright (C) Graham Rhodes, 2001" + */ +/************************************************************************************** +| +| File: lineintersect_utils.h +| +| Purpose: Function prototypes for line segment intersection utility functions +| +| Book Title: Game Programming Gems II +| +| Chapter Title: Fast, Robust Intersection of 3D Line Segments +| +| Author: Graham Rhodes +| +| Revisions: 05-Apr-2001 - GSR. Original. +| +**************************************************************************************/ +#ifndef _lineintersect_utils_h +#define _lineintersect_utils_h + +void IntersectLineSegments(const D3DXVECTOR3 & A1, + const D3DXVECTOR3 & A2, + const D3DXVECTOR3 & B1, + const D3DXVECTOR3 & B2, + //bool infinite_lines, /*float epsilon,*/ + D3DXVECTOR3 & OutA, + D3DXVECTOR3 & OutB); + + +void IntersectLineSegments(const float A1x, const float A1y, const float A1z, + const float A2x, const float A2y, const float A2z, + const float B1x, const float B1y, const float B1z, + const float B2x, const float B2y, const float B2z, + bool infinite_lines, float epsilon, float &PointOnSegAx, + float &PointOnSegAy, float &PointOnSegAz, float &PointOnSegBx, + float &PointOnSegBy, float &PointOnSegBz, float &NearestPointX, + float &NearestPointY, float &NearestPointZ, float &NearestVectorX, + float &NearestVectorY, float &NearestVectorZ, bool &true_intersection); + +void IntersectLineSegments(const float A1x, const float A1y, const float A1z, + const float A2x, const float A2y, const float A2z, + const float B1x, const float B1y, const float B1z, + const float B2x, const float B2y, const float B2z, + bool infinite_lines, float epsilon, float &PointOnSegAx, + float &PointOnSegAy, float &PointOnSegAz, float &PointOnSegBx, + float &PointOnSegBy, float &PointOnSegBz); + +void FindNearestPointOnLineSegment(const float A1x, const float A1y, const float A1z, + const float Lx, const float Ly, const float Lz, + const float Bx, const float By, const float Bz, + bool infinite_line, float epsilon_squared, float &NearestPointX, + float &NearestPointY, float &NearestPointZ, + float ¶meter); + +void FindNearestPointOfParallelLineSegments(float A1x, float A1y, float A1z, + float A2x, float A2y, float A2z, + float Lax, float Lay, float Laz, + float B1x, float B1y, float B1z, + float B2x, float B2y, float B2z, + float Lbx, float Lby, float Lbz, + bool infinite_lines, float epsilon_squared, + float &PointOnSegAx, float &PointOnSegAy, float &PointOnSegAz, + float &PointOnSegBx, float &PointOnSegBy, float &PointOnSegBz); + +void AdjustNearestPoints(float A1x, float A1y, float A1z, + float Lax, float Lay, float Laz, + float B1x, float B1y, float B1z, + float Lbx, float Lby, float Lbz, + float epsilon_squared, float s, float t, + float &PointOnSegAx, float &PointOnSegAy, float &PointOnSegAz, + float &PointOnSegBx, float &PointOnSegBy, float &PointOnSegBz); + +#endif // _lineintersect_utils_h \ No newline at end of file diff --git a/source/EterLib/msctf.h b/source/EterLib/msctf.h new file mode 100644 index 0000000..b71a121 --- /dev/null +++ b/source/EterLib/msctf.h @@ -0,0 +1,12206 @@ + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 7.00.0555 */ +/* Compiler settings for msctf.idl: + Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 7.00.0555 + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +/* @@MIDL_FILE_HEADING( ) */ + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 500 +#endif + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCSAL_H_VERSION__ +#define __REQUIRED_RPCSAL_H_VERSION__ 100 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif // __RPCNDR_H_VERSION__ + +#ifndef COM_NO_WINDOWS_H +#include "windows.h" +#include "ole2.h" +#endif /*COM_NO_WINDOWS_H*/ + +#ifndef __msctf_h__ +#define __msctf_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef __ITfThreadMgr_FWD_DEFINED__ +#define __ITfThreadMgr_FWD_DEFINED__ +typedef interface ITfThreadMgr ITfThreadMgr; +#endif /* __ITfThreadMgr_FWD_DEFINED__ */ + + +#ifndef __ITfThreadMgrEx_FWD_DEFINED__ +#define __ITfThreadMgrEx_FWD_DEFINED__ +typedef interface ITfThreadMgrEx ITfThreadMgrEx; +#endif /* __ITfThreadMgrEx_FWD_DEFINED__ */ + + +#ifndef __ITfThreadMgrEventSink_FWD_DEFINED__ +#define __ITfThreadMgrEventSink_FWD_DEFINED__ +typedef interface ITfThreadMgrEventSink ITfThreadMgrEventSink; +#endif /* __ITfThreadMgrEventSink_FWD_DEFINED__ */ + + +#ifndef __ITfConfigureSystemKeystrokeFeed_FWD_DEFINED__ +#define __ITfConfigureSystemKeystrokeFeed_FWD_DEFINED__ +typedef interface ITfConfigureSystemKeystrokeFeed ITfConfigureSystemKeystrokeFeed; +#endif /* __ITfConfigureSystemKeystrokeFeed_FWD_DEFINED__ */ + + +#ifndef __IEnumTfDocumentMgrs_FWD_DEFINED__ +#define __IEnumTfDocumentMgrs_FWD_DEFINED__ +typedef interface IEnumTfDocumentMgrs IEnumTfDocumentMgrs; +#endif /* __IEnumTfDocumentMgrs_FWD_DEFINED__ */ + + +#ifndef __ITfDocumentMgr_FWD_DEFINED__ +#define __ITfDocumentMgr_FWD_DEFINED__ +typedef interface ITfDocumentMgr ITfDocumentMgr; +#endif /* __ITfDocumentMgr_FWD_DEFINED__ */ + + +#ifndef __IEnumTfContexts_FWD_DEFINED__ +#define __IEnumTfContexts_FWD_DEFINED__ +typedef interface IEnumTfContexts IEnumTfContexts; +#endif /* __IEnumTfContexts_FWD_DEFINED__ */ + + +#ifndef __ITfCompositionView_FWD_DEFINED__ +#define __ITfCompositionView_FWD_DEFINED__ +typedef interface ITfCompositionView ITfCompositionView; +#endif /* __ITfCompositionView_FWD_DEFINED__ */ + + +#ifndef __IEnumITfCompositionView_FWD_DEFINED__ +#define __IEnumITfCompositionView_FWD_DEFINED__ +typedef interface IEnumITfCompositionView IEnumITfCompositionView; +#endif /* __IEnumITfCompositionView_FWD_DEFINED__ */ + + +#ifndef __ITfComposition_FWD_DEFINED__ +#define __ITfComposition_FWD_DEFINED__ +typedef interface ITfComposition ITfComposition; +#endif /* __ITfComposition_FWD_DEFINED__ */ + + +#ifndef __ITfCompositionSink_FWD_DEFINED__ +#define __ITfCompositionSink_FWD_DEFINED__ +typedef interface ITfCompositionSink ITfCompositionSink; +#endif /* __ITfCompositionSink_FWD_DEFINED__ */ + + +#ifndef __ITfContextComposition_FWD_DEFINED__ +#define __ITfContextComposition_FWD_DEFINED__ +typedef interface ITfContextComposition ITfContextComposition; +#endif /* __ITfContextComposition_FWD_DEFINED__ */ + + +#ifndef __ITfContextOwnerCompositionServices_FWD_DEFINED__ +#define __ITfContextOwnerCompositionServices_FWD_DEFINED__ +typedef interface ITfContextOwnerCompositionServices ITfContextOwnerCompositionServices; +#endif /* __ITfContextOwnerCompositionServices_FWD_DEFINED__ */ + + +#ifndef __ITfContextOwnerCompositionSink_FWD_DEFINED__ +#define __ITfContextOwnerCompositionSink_FWD_DEFINED__ +typedef interface ITfContextOwnerCompositionSink ITfContextOwnerCompositionSink; +#endif /* __ITfContextOwnerCompositionSink_FWD_DEFINED__ */ + + +#ifndef __ITfContextView_FWD_DEFINED__ +#define __ITfContextView_FWD_DEFINED__ +typedef interface ITfContextView ITfContextView; +#endif /* __ITfContextView_FWD_DEFINED__ */ + + +#ifndef __IEnumTfContextViews_FWD_DEFINED__ +#define __IEnumTfContextViews_FWD_DEFINED__ +typedef interface IEnumTfContextViews IEnumTfContextViews; +#endif /* __IEnumTfContextViews_FWD_DEFINED__ */ + + +#ifndef __ITfContext_FWD_DEFINED__ +#define __ITfContext_FWD_DEFINED__ +typedef interface ITfContext ITfContext; +#endif /* __ITfContext_FWD_DEFINED__ */ + + +#ifndef __ITfQueryEmbedded_FWD_DEFINED__ +#define __ITfQueryEmbedded_FWD_DEFINED__ +typedef interface ITfQueryEmbedded ITfQueryEmbedded; +#endif /* __ITfQueryEmbedded_FWD_DEFINED__ */ + + +#ifndef __ITfInsertAtSelection_FWD_DEFINED__ +#define __ITfInsertAtSelection_FWD_DEFINED__ +typedef interface ITfInsertAtSelection ITfInsertAtSelection; +#endif /* __ITfInsertAtSelection_FWD_DEFINED__ */ + + +#ifndef __ITfCleanupContextSink_FWD_DEFINED__ +#define __ITfCleanupContextSink_FWD_DEFINED__ +typedef interface ITfCleanupContextSink ITfCleanupContextSink; +#endif /* __ITfCleanupContextSink_FWD_DEFINED__ */ + + +#ifndef __ITfCleanupContextDurationSink_FWD_DEFINED__ +#define __ITfCleanupContextDurationSink_FWD_DEFINED__ +typedef interface ITfCleanupContextDurationSink ITfCleanupContextDurationSink; +#endif /* __ITfCleanupContextDurationSink_FWD_DEFINED__ */ + + +#ifndef __ITfReadOnlyProperty_FWD_DEFINED__ +#define __ITfReadOnlyProperty_FWD_DEFINED__ +typedef interface ITfReadOnlyProperty ITfReadOnlyProperty; +#endif /* __ITfReadOnlyProperty_FWD_DEFINED__ */ + + +#ifndef __IEnumTfPropertyValue_FWD_DEFINED__ +#define __IEnumTfPropertyValue_FWD_DEFINED__ +typedef interface IEnumTfPropertyValue IEnumTfPropertyValue; +#endif /* __IEnumTfPropertyValue_FWD_DEFINED__ */ + + +#ifndef __ITfMouseTracker_FWD_DEFINED__ +#define __ITfMouseTracker_FWD_DEFINED__ +typedef interface ITfMouseTracker ITfMouseTracker; +#endif /* __ITfMouseTracker_FWD_DEFINED__ */ + + +#ifndef __ITfMouseTrackerACP_FWD_DEFINED__ +#define __ITfMouseTrackerACP_FWD_DEFINED__ +typedef interface ITfMouseTrackerACP ITfMouseTrackerACP; +#endif /* __ITfMouseTrackerACP_FWD_DEFINED__ */ + + +#ifndef __ITfMouseSink_FWD_DEFINED__ +#define __ITfMouseSink_FWD_DEFINED__ +typedef interface ITfMouseSink ITfMouseSink; +#endif /* __ITfMouseSink_FWD_DEFINED__ */ + + +#ifndef __ITfEditRecord_FWD_DEFINED__ +#define __ITfEditRecord_FWD_DEFINED__ +typedef interface ITfEditRecord ITfEditRecord; +#endif /* __ITfEditRecord_FWD_DEFINED__ */ + + +#ifndef __ITfTextEditSink_FWD_DEFINED__ +#define __ITfTextEditSink_FWD_DEFINED__ +typedef interface ITfTextEditSink ITfTextEditSink; +#endif /* __ITfTextEditSink_FWD_DEFINED__ */ + + +#ifndef __ITfTextLayoutSink_FWD_DEFINED__ +#define __ITfTextLayoutSink_FWD_DEFINED__ +typedef interface ITfTextLayoutSink ITfTextLayoutSink; +#endif /* __ITfTextLayoutSink_FWD_DEFINED__ */ + + +#ifndef __ITfStatusSink_FWD_DEFINED__ +#define __ITfStatusSink_FWD_DEFINED__ +typedef interface ITfStatusSink ITfStatusSink; +#endif /* __ITfStatusSink_FWD_DEFINED__ */ + + +#ifndef __ITfEditTransactionSink_FWD_DEFINED__ +#define __ITfEditTransactionSink_FWD_DEFINED__ +typedef interface ITfEditTransactionSink ITfEditTransactionSink; +#endif /* __ITfEditTransactionSink_FWD_DEFINED__ */ + + +#ifndef __ITfContextOwner_FWD_DEFINED__ +#define __ITfContextOwner_FWD_DEFINED__ +typedef interface ITfContextOwner ITfContextOwner; +#endif /* __ITfContextOwner_FWD_DEFINED__ */ + + +#ifndef __ITfContextOwnerServices_FWD_DEFINED__ +#define __ITfContextOwnerServices_FWD_DEFINED__ +typedef interface ITfContextOwnerServices ITfContextOwnerServices; +#endif /* __ITfContextOwnerServices_FWD_DEFINED__ */ + + +#ifndef __ITfContextKeyEventSink_FWD_DEFINED__ +#define __ITfContextKeyEventSink_FWD_DEFINED__ +typedef interface ITfContextKeyEventSink ITfContextKeyEventSink; +#endif /* __ITfContextKeyEventSink_FWD_DEFINED__ */ + + +#ifndef __ITfEditSession_FWD_DEFINED__ +#define __ITfEditSession_FWD_DEFINED__ +typedef interface ITfEditSession ITfEditSession; +#endif /* __ITfEditSession_FWD_DEFINED__ */ + + +#ifndef __ITfRange_FWD_DEFINED__ +#define __ITfRange_FWD_DEFINED__ +typedef interface ITfRange ITfRange; +#endif /* __ITfRange_FWD_DEFINED__ */ + + +#ifndef __ITfRangeACP_FWD_DEFINED__ +#define __ITfRangeACP_FWD_DEFINED__ +typedef interface ITfRangeACP ITfRangeACP; +#endif /* __ITfRangeACP_FWD_DEFINED__ */ + + +#ifndef __ITextStoreACPServices_FWD_DEFINED__ +#define __ITextStoreACPServices_FWD_DEFINED__ +typedef interface ITextStoreACPServices ITextStoreACPServices; +#endif /* __ITextStoreACPServices_FWD_DEFINED__ */ + + +#ifndef __ITfRangeBackup_FWD_DEFINED__ +#define __ITfRangeBackup_FWD_DEFINED__ +typedef interface ITfRangeBackup ITfRangeBackup; +#endif /* __ITfRangeBackup_FWD_DEFINED__ */ + + +#ifndef __ITfPropertyStore_FWD_DEFINED__ +#define __ITfPropertyStore_FWD_DEFINED__ +typedef interface ITfPropertyStore ITfPropertyStore; +#endif /* __ITfPropertyStore_FWD_DEFINED__ */ + + +#ifndef __IEnumTfRanges_FWD_DEFINED__ +#define __IEnumTfRanges_FWD_DEFINED__ +typedef interface IEnumTfRanges IEnumTfRanges; +#endif /* __IEnumTfRanges_FWD_DEFINED__ */ + + +#ifndef __ITfCreatePropertyStore_FWD_DEFINED__ +#define __ITfCreatePropertyStore_FWD_DEFINED__ +typedef interface ITfCreatePropertyStore ITfCreatePropertyStore; +#endif /* __ITfCreatePropertyStore_FWD_DEFINED__ */ + + +#ifndef __ITfPersistentPropertyLoaderACP_FWD_DEFINED__ +#define __ITfPersistentPropertyLoaderACP_FWD_DEFINED__ +typedef interface ITfPersistentPropertyLoaderACP ITfPersistentPropertyLoaderACP; +#endif /* __ITfPersistentPropertyLoaderACP_FWD_DEFINED__ */ + + +#ifndef __ITfProperty_FWD_DEFINED__ +#define __ITfProperty_FWD_DEFINED__ +typedef interface ITfProperty ITfProperty; +#endif /* __ITfProperty_FWD_DEFINED__ */ + + +#ifndef __IEnumTfProperties_FWD_DEFINED__ +#define __IEnumTfProperties_FWD_DEFINED__ +typedef interface IEnumTfProperties IEnumTfProperties; +#endif /* __IEnumTfProperties_FWD_DEFINED__ */ + + +#ifndef __ITfCompartment_FWD_DEFINED__ +#define __ITfCompartment_FWD_DEFINED__ +typedef interface ITfCompartment ITfCompartment; +#endif /* __ITfCompartment_FWD_DEFINED__ */ + + +#ifndef __ITfCompartmentEventSink_FWD_DEFINED__ +#define __ITfCompartmentEventSink_FWD_DEFINED__ +typedef interface ITfCompartmentEventSink ITfCompartmentEventSink; +#endif /* __ITfCompartmentEventSink_FWD_DEFINED__ */ + + +#ifndef __ITfCompartmentMgr_FWD_DEFINED__ +#define __ITfCompartmentMgr_FWD_DEFINED__ +typedef interface ITfCompartmentMgr ITfCompartmentMgr; +#endif /* __ITfCompartmentMgr_FWD_DEFINED__ */ + + +#ifndef __ITfFunction_FWD_DEFINED__ +#define __ITfFunction_FWD_DEFINED__ +typedef interface ITfFunction ITfFunction; +#endif /* __ITfFunction_FWD_DEFINED__ */ + + +#ifndef __ITfFunctionProvider_FWD_DEFINED__ +#define __ITfFunctionProvider_FWD_DEFINED__ +typedef interface ITfFunctionProvider ITfFunctionProvider; +#endif /* __ITfFunctionProvider_FWD_DEFINED__ */ + + +#ifndef __IEnumTfFunctionProviders_FWD_DEFINED__ +#define __IEnumTfFunctionProviders_FWD_DEFINED__ +typedef interface IEnumTfFunctionProviders IEnumTfFunctionProviders; +#endif /* __IEnumTfFunctionProviders_FWD_DEFINED__ */ + + +#ifndef __ITfInputProcessorProfiles_FWD_DEFINED__ +#define __ITfInputProcessorProfiles_FWD_DEFINED__ +typedef interface ITfInputProcessorProfiles ITfInputProcessorProfiles; +#endif /* __ITfInputProcessorProfiles_FWD_DEFINED__ */ + + +#ifndef __ITfInputProcessorProfilesEx_FWD_DEFINED__ +#define __ITfInputProcessorProfilesEx_FWD_DEFINED__ +typedef interface ITfInputProcessorProfilesEx ITfInputProcessorProfilesEx; +#endif /* __ITfInputProcessorProfilesEx_FWD_DEFINED__ */ + + +#ifndef __ITfInputProcessorProfileSubstituteLayout_FWD_DEFINED__ +#define __ITfInputProcessorProfileSubstituteLayout_FWD_DEFINED__ +typedef interface ITfInputProcessorProfileSubstituteLayout ITfInputProcessorProfileSubstituteLayout; +#endif /* __ITfInputProcessorProfileSubstituteLayout_FWD_DEFINED__ */ + + +#ifndef __ITfActiveLanguageProfileNotifySink_FWD_DEFINED__ +#define __ITfActiveLanguageProfileNotifySink_FWD_DEFINED__ +typedef interface ITfActiveLanguageProfileNotifySink ITfActiveLanguageProfileNotifySink; +#endif /* __ITfActiveLanguageProfileNotifySink_FWD_DEFINED__ */ + + +#ifndef __IEnumTfLanguageProfiles_FWD_DEFINED__ +#define __IEnumTfLanguageProfiles_FWD_DEFINED__ +typedef interface IEnumTfLanguageProfiles IEnumTfLanguageProfiles; +#endif /* __IEnumTfLanguageProfiles_FWD_DEFINED__ */ + + +#ifndef __ITfLanguageProfileNotifySink_FWD_DEFINED__ +#define __ITfLanguageProfileNotifySink_FWD_DEFINED__ +typedef interface ITfLanguageProfileNotifySink ITfLanguageProfileNotifySink; +#endif /* __ITfLanguageProfileNotifySink_FWD_DEFINED__ */ + + +#ifndef __ITfInputProcessorProfileMgr_FWD_DEFINED__ +#define __ITfInputProcessorProfileMgr_FWD_DEFINED__ +typedef interface ITfInputProcessorProfileMgr ITfInputProcessorProfileMgr; +#endif /* __ITfInputProcessorProfileMgr_FWD_DEFINED__ */ + + +#ifndef __IEnumTfInputProcessorProfiles_FWD_DEFINED__ +#define __IEnumTfInputProcessorProfiles_FWD_DEFINED__ +typedef interface IEnumTfInputProcessorProfiles IEnumTfInputProcessorProfiles; +#endif /* __IEnumTfInputProcessorProfiles_FWD_DEFINED__ */ + + +#ifndef __ITfInputProcessorProfileActivationSink_FWD_DEFINED__ +#define __ITfInputProcessorProfileActivationSink_FWD_DEFINED__ +typedef interface ITfInputProcessorProfileActivationSink ITfInputProcessorProfileActivationSink; +#endif /* __ITfInputProcessorProfileActivationSink_FWD_DEFINED__ */ + + +#ifndef __ITfKeystrokeMgr_FWD_DEFINED__ +#define __ITfKeystrokeMgr_FWD_DEFINED__ +typedef interface ITfKeystrokeMgr ITfKeystrokeMgr; +#endif /* __ITfKeystrokeMgr_FWD_DEFINED__ */ + + +#ifndef __ITfKeyEventSink_FWD_DEFINED__ +#define __ITfKeyEventSink_FWD_DEFINED__ +typedef interface ITfKeyEventSink ITfKeyEventSink; +#endif /* __ITfKeyEventSink_FWD_DEFINED__ */ + + +#ifndef __ITfKeyTraceEventSink_FWD_DEFINED__ +#define __ITfKeyTraceEventSink_FWD_DEFINED__ +typedef interface ITfKeyTraceEventSink ITfKeyTraceEventSink; +#endif /* __ITfKeyTraceEventSink_FWD_DEFINED__ */ + + +#ifndef __ITfPreservedKeyNotifySink_FWD_DEFINED__ +#define __ITfPreservedKeyNotifySink_FWD_DEFINED__ +typedef interface ITfPreservedKeyNotifySink ITfPreservedKeyNotifySink; +#endif /* __ITfPreservedKeyNotifySink_FWD_DEFINED__ */ + + +#ifndef __ITfMessagePump_FWD_DEFINED__ +#define __ITfMessagePump_FWD_DEFINED__ +typedef interface ITfMessagePump ITfMessagePump; +#endif /* __ITfMessagePump_FWD_DEFINED__ */ + + +#ifndef __ITfThreadFocusSink_FWD_DEFINED__ +#define __ITfThreadFocusSink_FWD_DEFINED__ +typedef interface ITfThreadFocusSink ITfThreadFocusSink; +#endif /* __ITfThreadFocusSink_FWD_DEFINED__ */ + + +#ifndef __ITfTextInputProcessor_FWD_DEFINED__ +#define __ITfTextInputProcessor_FWD_DEFINED__ +typedef interface ITfTextInputProcessor ITfTextInputProcessor; +#endif /* __ITfTextInputProcessor_FWD_DEFINED__ */ + + +#ifndef __ITfTextInputProcessorEx_FWD_DEFINED__ +#define __ITfTextInputProcessorEx_FWD_DEFINED__ +typedef interface ITfTextInputProcessorEx ITfTextInputProcessorEx; +#endif /* __ITfTextInputProcessorEx_FWD_DEFINED__ */ + + +#ifndef __ITfClientId_FWD_DEFINED__ +#define __ITfClientId_FWD_DEFINED__ +typedef interface ITfClientId ITfClientId; +#endif /* __ITfClientId_FWD_DEFINED__ */ + + +#ifndef __ITfDisplayAttributeInfo_FWD_DEFINED__ +#define __ITfDisplayAttributeInfo_FWD_DEFINED__ +typedef interface ITfDisplayAttributeInfo ITfDisplayAttributeInfo; +#endif /* __ITfDisplayAttributeInfo_FWD_DEFINED__ */ + + +#ifndef __IEnumTfDisplayAttributeInfo_FWD_DEFINED__ +#define __IEnumTfDisplayAttributeInfo_FWD_DEFINED__ +typedef interface IEnumTfDisplayAttributeInfo IEnumTfDisplayAttributeInfo; +#endif /* __IEnumTfDisplayAttributeInfo_FWD_DEFINED__ */ + + +#ifndef __ITfDisplayAttributeProvider_FWD_DEFINED__ +#define __ITfDisplayAttributeProvider_FWD_DEFINED__ +typedef interface ITfDisplayAttributeProvider ITfDisplayAttributeProvider; +#endif /* __ITfDisplayAttributeProvider_FWD_DEFINED__ */ + + +#ifndef __ITfDisplayAttributeMgr_FWD_DEFINED__ +#define __ITfDisplayAttributeMgr_FWD_DEFINED__ +typedef interface ITfDisplayAttributeMgr ITfDisplayAttributeMgr; +#endif /* __ITfDisplayAttributeMgr_FWD_DEFINED__ */ + + +#ifndef __ITfDisplayAttributeNotifySink_FWD_DEFINED__ +#define __ITfDisplayAttributeNotifySink_FWD_DEFINED__ +typedef interface ITfDisplayAttributeNotifySink ITfDisplayAttributeNotifySink; +#endif /* __ITfDisplayAttributeNotifySink_FWD_DEFINED__ */ + + +#ifndef __ITfCategoryMgr_FWD_DEFINED__ +#define __ITfCategoryMgr_FWD_DEFINED__ +typedef interface ITfCategoryMgr ITfCategoryMgr; +#endif /* __ITfCategoryMgr_FWD_DEFINED__ */ + + +#ifndef __ITfSource_FWD_DEFINED__ +#define __ITfSource_FWD_DEFINED__ +typedef interface ITfSource ITfSource; +#endif /* __ITfSource_FWD_DEFINED__ */ + + +#ifndef __ITfSourceSingle_FWD_DEFINED__ +#define __ITfSourceSingle_FWD_DEFINED__ +typedef interface ITfSourceSingle ITfSourceSingle; +#endif /* __ITfSourceSingle_FWD_DEFINED__ */ + + +#ifndef __ITfUIElementMgr_FWD_DEFINED__ +#define __ITfUIElementMgr_FWD_DEFINED__ +typedef interface ITfUIElementMgr ITfUIElementMgr; +#endif /* __ITfUIElementMgr_FWD_DEFINED__ */ + + +#ifndef __IEnumTfUIElements_FWD_DEFINED__ +#define __IEnumTfUIElements_FWD_DEFINED__ +typedef interface IEnumTfUIElements IEnumTfUIElements; +#endif /* __IEnumTfUIElements_FWD_DEFINED__ */ + + +#ifndef __ITfUIElementSink_FWD_DEFINED__ +#define __ITfUIElementSink_FWD_DEFINED__ +typedef interface ITfUIElementSink ITfUIElementSink; +#endif /* __ITfUIElementSink_FWD_DEFINED__ */ + + +#ifndef __ITfUIElement_FWD_DEFINED__ +#define __ITfUIElement_FWD_DEFINED__ +typedef interface ITfUIElement ITfUIElement; +#endif /* __ITfUIElement_FWD_DEFINED__ */ + + +#ifndef __ITfCandidateListUIElement_FWD_DEFINED__ +#define __ITfCandidateListUIElement_FWD_DEFINED__ +typedef interface ITfCandidateListUIElement ITfCandidateListUIElement; +#endif /* __ITfCandidateListUIElement_FWD_DEFINED__ */ + + +#ifndef __ITfCandidateListUIElementBehavior_FWD_DEFINED__ +#define __ITfCandidateListUIElementBehavior_FWD_DEFINED__ +typedef interface ITfCandidateListUIElementBehavior ITfCandidateListUIElementBehavior; +#endif /* __ITfCandidateListUIElementBehavior_FWD_DEFINED__ */ + + +#ifndef __ITfReadingInformationUIElement_FWD_DEFINED__ +#define __ITfReadingInformationUIElement_FWD_DEFINED__ +typedef interface ITfReadingInformationUIElement ITfReadingInformationUIElement; +#endif /* __ITfReadingInformationUIElement_FWD_DEFINED__ */ + + +#ifndef __ITfTransitoryExtensionUIElement_FWD_DEFINED__ +#define __ITfTransitoryExtensionUIElement_FWD_DEFINED__ +typedef interface ITfTransitoryExtensionUIElement ITfTransitoryExtensionUIElement; +#endif /* __ITfTransitoryExtensionUIElement_FWD_DEFINED__ */ + + +#ifndef __ITfTransitoryExtensionSink_FWD_DEFINED__ +#define __ITfTransitoryExtensionSink_FWD_DEFINED__ +typedef interface ITfTransitoryExtensionSink ITfTransitoryExtensionSink; +#endif /* __ITfTransitoryExtensionSink_FWD_DEFINED__ */ + + +#ifndef __ITfToolTipUIElement_FWD_DEFINED__ +#define __ITfToolTipUIElement_FWD_DEFINED__ +typedef interface ITfToolTipUIElement ITfToolTipUIElement; +#endif /* __ITfToolTipUIElement_FWD_DEFINED__ */ + + +#ifndef __ITfReverseConversionList_FWD_DEFINED__ +#define __ITfReverseConversionList_FWD_DEFINED__ +typedef interface ITfReverseConversionList ITfReverseConversionList; +#endif /* __ITfReverseConversionList_FWD_DEFINED__ */ + + +#ifndef __ITfReverseConversion_FWD_DEFINED__ +#define __ITfReverseConversion_FWD_DEFINED__ +typedef interface ITfReverseConversion ITfReverseConversion; +#endif /* __ITfReverseConversion_FWD_DEFINED__ */ + + +#ifndef __ITfReverseConversionMgr_FWD_DEFINED__ +#define __ITfReverseConversionMgr_FWD_DEFINED__ +typedef interface ITfReverseConversionMgr ITfReverseConversionMgr; +#endif /* __ITfReverseConversionMgr_FWD_DEFINED__ */ + + +/* header files for imported files */ +#include "oaidl.h" +#include "comcat.h" +#include "textstor.h" +#include "ctfutb.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + +/* interface __MIDL_itf_msctf_0000_0000 */ +/* [local] */ + +//=--------------------------------------------------------------------------= +// msctf.h + + +// Text Framework declarations. + +//=--------------------------------------------------------------------------= +// (C) Copyright 1995-2001 Microsoft Corporation. All Rights Reserved. +// +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A +// PARTICULAR PURPOSE. +//=--------------------------------------------------------------------------= + +#ifndef MSCTF_DEFINED +#define MSCTF_DEFINED + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define TF_E_LOCKED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0500) +#define TF_E_STACKFULL MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0501) +#define TF_E_NOTOWNEDRANGE MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0502) +#define TF_E_NOPROVIDER MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0503) +#define TF_E_DISCONNECTED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0504) +#define TF_E_INVALIDVIEW MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0505) +#define TF_E_ALREADY_EXISTS MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0506) +#define TF_E_RANGE_NOT_COVERED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0507) +#define TF_E_COMPOSITION_REJECTED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0508) +#define TF_E_EMPTYCONTEXT MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0509) +#define TF_E_INVALIDPOS MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0200) +#define TF_E_NOLOCK MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0201) +#define TF_E_NOOBJECT MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0202) +#define TF_E_NOSERVICE MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0203) +#define TF_E_NOINTERFACE MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0204) +#define TF_E_NOSELECTION MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0205) +#define TF_E_NOLAYOUT MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0206) +#define TF_E_INVALIDPOINT MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0207) +#define TF_E_SYNCHRONOUS MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0208) +#define TF_E_READONLY MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0209) +#define TF_E_FORMAT MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x020a) +#define TF_S_ASYNC MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_ITF, 0x0300) +#define TF_RCM_COMLESS 0x00000001 +#define TF_RCM_VKEY 0x00000002 +#define TF_RCM_HINT_READING_LENGTH 0x00000004 +#define TF_RCM_HINT_COLLISION 0x00000008 + +HRESULT WINAPI TF_CreateThreadMgr(ITfThreadMgr **pptim); +HRESULT WINAPI TF_GetThreadMgr(ITfThreadMgr **pptim); +HRESULT WINAPI TF_CreateInputProcessorProfiles(ITfInputProcessorProfiles **ppipr); +HRESULT WINAPI TF_CreateDisplayAttributeMgr(ITfDisplayAttributeMgr **ppdam); +HRESULT WINAPI TF_CreateLangBarMgr(ITfLangBarMgr **pppbm); +HRESULT WINAPI TF_CreateLangBarItemMgr(ITfLangBarItemMgr **pplbim); +HRESULT WINAPI TF_CreateCategoryMgr(ITfCategoryMgr **ppcat); + +EXTERN_C const GUID GUID_PROP_TEXTOWNER; +EXTERN_C const GUID GUID_PROP_ATTRIBUTE; +EXTERN_C const GUID GUID_PROP_LANGID; +EXTERN_C const GUID GUID_PROP_READING; +EXTERN_C const GUID GUID_PROP_COMPOSING; + +EXTERN_C const CLSID CLSID_TF_ThreadMgr; +EXTERN_C const CLSID CLSID_TF_InputProcessorProfiles; +EXTERN_C const CLSID CLSID_TF_LangBarMgr; +EXTERN_C const CLSID CLSID_TF_DisplayAttributeMgr; +EXTERN_C const CLSID CLSID_TF_CategoryMgr; +EXTERN_C const CLSID CLSID_TF_LangBarItemMgr; +EXTERN_C const GUID GUID_SYSTEM_FUNCTIONPROVIDER; +EXTERN_C const GUID GUID_APP_FUNCTIONPROVIDER; + + +EXTERN_C const GUID GUID_COMPARTMENT_KEYBOARD_DISABLED; +EXTERN_C const GUID GUID_COMPARTMENT_KEYBOARD_OPENCLOSE; +EXTERN_C const GUID GUID_COMPARTMENT_HANDWRITING_OPENCLOSE; +EXTERN_C const GUID GUID_COMPARTMENT_SPEECH_DISABLED; +EXTERN_C const GUID GUID_COMPARTMENT_SPEECH_OPENCLOSE; +EXTERN_C const GUID GUID_COMPARTMENT_SPEECH_GLOBALSTATE; +EXTERN_C const GUID GUID_COMPARTMENT_PERSISTMENUENABLED; +EXTERN_C const GUID GUID_COMPARTMENT_EMPTYCONTEXT; +EXTERN_C const GUID GUID_COMPARTMENT_TIPUISTATUS; +EXTERN_C const GUID GUID_COMPARTMENT_KEYBOARD_INPUTMODE_CONVERSION; +EXTERN_C const GUID GUID_COMPARTMENT_KEYBOARD_INPUTMODE_SENTENCE; +EXTERN_C const GUID GUID_COMPARTMENT_TRANSITORYEXTENSION; +EXTERN_C const GUID GUID_COMPARTMENT_TRANSITORYEXTENSION_DOCUMENTMANAGER; +EXTERN_C const GUID GUID_COMPARTMENT_TRANSITORYEXTENSION_PARENT; + +EXTERN_C const GUID GUID_PROP_MODEBIAS; + +EXTERN_C const GUID GUID_MODEBIAS_NONE; +EXTERN_C const GUID GUID_MODEBIAS_URLHISTORY; +EXTERN_C const GUID GUID_MODEBIAS_FILENAME; +EXTERN_C const GUID GUID_MODEBIAS_READING; +EXTERN_C const GUID GUID_MODEBIAS_DATETIME; +EXTERN_C const GUID GUID_MODEBIAS_NAME; +EXTERN_C const GUID GUID_MODEBIAS_CONVERSATION; +EXTERN_C const GUID GUID_MODEBIAS_NUMERIC; +EXTERN_C const GUID GUID_MODEBIAS_HIRAGANA; +EXTERN_C const GUID GUID_MODEBIAS_KATAKANA; +EXTERN_C const GUID GUID_MODEBIAS_HANGUL; +EXTERN_C const GUID GUID_MODEBIAS_CHINESE; +EXTERN_C const GUID GUID_MODEBIAS_HALFWIDTHKATAKANA; +EXTERN_C const GUID GUID_MODEBIAS_FULLWIDTHALPHANUMERIC; +EXTERN_C const GUID GUID_MODEBIAS_HALFWIDTHALPHANUMERIC; +EXTERN_C const GUID GUID_MODEBIAS_FULLWIDTHHANGUL; +EXTERN_C const GUID GUID_TFCAT_CATEGORY_OF_TIP; +EXTERN_C const GUID GUID_TFCAT_TIP_KEYBOARD; +EXTERN_C const GUID GUID_TFCAT_TIP_SPEECH; +EXTERN_C const GUID GUID_TFCAT_TIP_HANDWRITING; +EXTERN_C const GUID GUID_TFCAT_TIPCAP_SECUREMODE; +EXTERN_C const GUID GUID_TFCAT_TIPCAP_UIELEMENTENABLED; +EXTERN_C const GUID GUID_TFCAT_TIPCAP_INPUTMODECOMPARTMENT; +EXTERN_C const GUID GUID_TFCAT_TIPCAP_COMLESS; +EXTERN_C const GUID GUID_TFCAT_TIPCAP_WOW16; + +EXTERN_C const GUID GUID_TFCAT_PROP_AUDIODATA; +EXTERN_C const GUID GUID_TFCAT_PROP_INKDATA; + +EXTERN_C const GUID GUID_TFCAT_PROPSTYLE_CUSTOM; +EXTERN_C const GUID GUID_TFCAT_PROPSTYLE_STATIC; +EXTERN_C const GUID GUID_TFCAT_PROPSTYLE_STATICCOMPACT; + +EXTERN_C const GUID GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER; +EXTERN_C const GUID GUID_TFCAT_DISPLAYATTRIBUTEPROPERTY; + +#define TF_INVALID_GUIDATOM ((TfGuidAtom)0) +#define TF_CLIENTID_NULL ((TfClientId)0) + +#define TF_TMAE_NOACTIVATETIP 0x00000001 +#define TF_TMAE_SECUREMODE 0x00000002 +#define TF_TMAE_UIELEMENTENABLEDONLY 0x00000004 +#define TF_TMAE_COMLESS 0x00000008 +#define TF_TMAE_WOW16 0x00000010 +#define TF_TMAE_NOACTIVATEKEYBOARDLAYOUT 0x00000020 +#define TF_TMAE_CONSOLE 0x00000040 + +#define TF_TMF_NOACTIVATETIP TF_TMAE_NOACTIVATETIP +#define TF_TMF_SECUREMODE TF_TMAE_SECUREMODE +#define TF_TMF_UIELEMENTENABLEDONLY TF_TMAE_UIELEMENTENABLEDONLY +#define TF_TMF_COMLESS TF_TMAE_COMLESS +#define TF_TMF_WOW16 TF_TMAE_WOW16 +#define TF_TMF_CONSOLE TF_TMAE_CONSOLE +#define TF_TMF_ACTIVATED 0x80000000 + +#define TF_MOD_ALT 0x0001 +#define TF_MOD_CONTROL 0x0002 +#define TF_MOD_SHIFT 0x0004 +#define TF_MOD_RALT 0x0008 +#define TF_MOD_RCONTROL 0x0010 +#define TF_MOD_RSHIFT 0x0020 +#define TF_MOD_LALT 0x0040 +#define TF_MOD_LCONTROL 0x0080 +#define TF_MOD_LSHIFT 0x0100 +#define TF_MOD_ON_KEYUP 0x0200 +#define TF_MOD_IGNORE_ALL_MODIFIER 0x0400 + +#define TF_US_HIDETIPUI 0x00000001 + +#define TF_DISABLE_SPEECH 0x00000001 +#define TF_DISABLE_DICTATION 0x00000002 +#define TF_DISABLE_COMMANDING 0x00000004 + +#define TF_PROCESS_ATOM TEXT("_CTF_PROCESS_ATOM_") +#define TF_ENABLE_PROCESS_ATOM TEXT("_CTF_ENABLE_PROCESS_ATOM_") +#define TF_INVALID_UIELEMENTID DWORD(-1) +#define TF_CLUIE_DOCUMENTMGR 0x00000001 +#define TF_CLUIE_COUNT 0x00000002 +#define TF_CLUIE_SELECTION 0x00000004 +#define TF_CLUIE_STRING 0x00000008 +#define TF_CLUIE_PAGEINDEX 0x00000010 +#define TF_CLUIE_CURRENTPAGE 0x00000020 +#define TF_RIUIE_CONTEXT 0x00000001 +#define TF_RIUIE_STRING 0x00000002 +#define TF_RIUIE_MAXREADINGSTRINGLENGTH 0x00000004 +#define TF_RIUIE_ERRORINDEX 0x00000008 +#define TF_RIUIE_VERTICALORDER 0x00000010 +#define TF_CONVERSIONMODE_ALPHANUMERIC 0x0000 +#define TF_CONVERSIONMODE_NATIVE 0x0001 +#define TF_CONVERSIONMODE_KATAKANA 0x0002 +#define TF_CONVERSIONMODE_FULLSHAPE 0x0008 +#define TF_CONVERSIONMODE_ROMAN 0x0010 +#define TF_CONVERSIONMODE_CHARCODE 0x0020 +#define TF_CONVERSIONMODE_SOFTKEYBOARD 0x0080 +#define TF_CONVERSIONMODE_NOCONVERSION 0x0100 +#define TF_CONVERSIONMODE_EUDC 0x0200 +#define TF_CONVERSIONMODE_SYMBOL 0x0400 +#define TF_CONVERSIONMODE_FIXED 0x0800 +#define TF_SENTENCEMODE_NONE 0x0000 +#define TF_SENTENCEMODE_PLAURALCLAUSE 0x0001 +#define TF_SENTENCEMODE_SINGLECONVERT 0x0002 +#define TF_SENTENCEMODE_AUTOMATIC 0x0004 +#define TF_SENTENCEMODE_PHRASEPREDICT 0x0008 +#define TF_SENTENCEMODE_CONVERSATION 0x0010 + +#define TF_TRANSITORYEXTENSION_NONE 0x0000 +#define TF_TRANSITORYEXTENSION_FLOATING 0x0001 +#define TF_TRANSITORYEXTENSION_ATSELECTION 0x0002 + +#define TF_PROFILETYPE_INPUTPROCESSOR 0x0001 +#define TF_PROFILETYPE_KEYBOARDLAYOUT 0x0002 +#define TF_RIP_FLAG_FREEUNUSEDLIBRARIES 0x00000001 +#define TF_IPP_FLAG_ACTIVE 0x00000001 +#define TF_IPP_FLAG_ENABLED 0x00000002 +#define TF_IPP_FLAG_SUBSTITUTEDBYINPUTPROCESSOR 0x00000004 +#define TF_IPP_CAPS_DISABLEONTRANSITORY 0x00000001 +#define TF_IPP_CAPS_SECUREMODESUPPORT 0x00000002 +#define TF_IPP_CAPS_UIELEMENTENABLED 0x00000004 +#define TF_IPP_CAPS_COMLESSSUPPORT 0x00000008 +#define TF_IPP_CAPS_WOW16SUPPORT 0x00000010 +#define TF_IPPMF_FORPROCESS 0x10000000 +#define TF_IPPMF_FORSESSION 0x20000000 +#define TF_IPPMF_FORSYSTEMALL 0x40000000 +#define TF_IPPMF_ENABLEPROFILE 0x00000001 +#define TF_IPPMF_DISABLEPROFILE 0x00000002 +#define TF_IPPMF_DONTCARECURRENTINPUTLANGUAGE 0x00000004 +#define TF_RP_HIDDENINSETTINGUI 0x00000002 +#define TF_RP_LOCALPROCESS 0x00000004 +#define TF_RP_LOCALTHREAD 0x00000008 +#define TF_RP_SUBITEMINSETTINGUI 0x00000010 +#define TF_URP_ALLPROFILES 0x00000002 +#define TF_URP_LOCALPROCESS 0x00000004 +#define TF_URP_LOCALTHREAD 0x00000008 +#define TF_IPSINK_FLAG_ACTIVE 0x0001 +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#if 0 +typedef /* [uuid] */ DECLSPEC_UUID("4f5d560f-5ab5-4dde-8c4d-404592857ab0") UINT_PTR HKL; + +#endif + + + + + + + + + + + + + + + + + + + + + + + + + + + +typedef /* [uuid] */ DECLSPEC_UUID("7213778c-7bb0-4270-b050-6189ee594e97") DWORD TfEditCookie; + +#define TF_INVALID_EDIT_COOKIE ( 0 ) + +typedef /* [uuid] */ DECLSPEC_UUID("88a9c478-f3ec-4763-8345-cd9250443f8d") DWORD TfGuidAtom; + +typedef /* [uuid] */ DECLSPEC_UUID("de403c21-89fd-4f85-8b87-64584d063fbc") DWORD TfClientId; + +typedef /* [uuid] */ DECLSPEC_UUID("e26d9e1d-691e-4f29-90d7-338dcf1f8cef") struct TF_PERSISTENT_PROPERTY_HEADER_ACP + { + GUID guidType; + LONG ichStart; + LONG cch; + ULONG cb; + DWORD dwPrivate; + CLSID clsidTIP; + } TF_PERSISTENT_PROPERTY_HEADER_ACP; + +typedef /* [uuid] */ DECLSPEC_UUID("e1b5808d-1e46-4c19-84dc-68c5f5978cc8") struct TF_LANGUAGEPROFILE + { + CLSID clsid; + LANGID langid; + GUID catid; + BOOL fActive; + GUID guidProfile; + } TF_LANGUAGEPROFILE; + +typedef /* [public][public][public][public][public][public][public][public][public][public][public][uuid] */ DECLSPEC_UUID("5a886226-ae9a-489b-b991-2b1e25ee59a9") +enum __MIDL___MIDL_itf_msctf_0000_0000_0001 + { TF_ANCHOR_START = 0, + TF_ANCHOR_END = 1 + } TfAnchor; + + + +extern RPC_IF_HANDLE __MIDL_itf_msctf_0000_0000_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_msctf_0000_0000_v0_0_s_ifspec; + +#ifndef __ITfThreadMgr_INTERFACE_DEFINED__ +#define __ITfThreadMgr_INTERFACE_DEFINED__ + +/* interface ITfThreadMgr */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfThreadMgr; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("aa80e801-2021-11d2-93e0-0060b067b86e") + ITfThreadMgr : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Activate( + /* [out] */ TfClientId *ptid) = 0; + + virtual HRESULT STDMETHODCALLTYPE Deactivate( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateDocumentMgr( + /* [out] */ ITfDocumentMgr **ppdim) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnumDocumentMgrs( + /* [out] */ IEnumTfDocumentMgrs **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetFocus( + /* [out] */ ITfDocumentMgr **ppdimFocus) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetFocus( + /* [in] */ ITfDocumentMgr *pdimFocus) = 0; + + virtual HRESULT STDMETHODCALLTYPE AssociateFocus( + /* [in] */ HWND hwnd, + /* [unique][in] */ ITfDocumentMgr *pdimNew, + /* [out] */ ITfDocumentMgr **ppdimPrev) = 0; + + virtual HRESULT STDMETHODCALLTYPE IsThreadFocus( + /* [out] */ BOOL *pfThreadFocus) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetFunctionProvider( + /* [in] */ REFCLSID clsid, + /* [out] */ ITfFunctionProvider **ppFuncProv) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnumFunctionProviders( + /* [out] */ IEnumTfFunctionProviders **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetGlobalCompartment( + /* [out] */ ITfCompartmentMgr **ppCompMgr) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfThreadMgrVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfThreadMgr * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfThreadMgr * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfThreadMgr * This); + + HRESULT ( STDMETHODCALLTYPE *Activate )( + ITfThreadMgr * This, + /* [out] */ TfClientId *ptid); + + HRESULT ( STDMETHODCALLTYPE *Deactivate )( + ITfThreadMgr * This); + + HRESULT ( STDMETHODCALLTYPE *CreateDocumentMgr )( + ITfThreadMgr * This, + /* [out] */ ITfDocumentMgr **ppdim); + + HRESULT ( STDMETHODCALLTYPE *EnumDocumentMgrs )( + ITfThreadMgr * This, + /* [out] */ IEnumTfDocumentMgrs **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *GetFocus )( + ITfThreadMgr * This, + /* [out] */ ITfDocumentMgr **ppdimFocus); + + HRESULT ( STDMETHODCALLTYPE *SetFocus )( + ITfThreadMgr * This, + /* [in] */ ITfDocumentMgr *pdimFocus); + + HRESULT ( STDMETHODCALLTYPE *AssociateFocus )( + ITfThreadMgr * This, + /* [in] */ HWND hwnd, + /* [unique][in] */ ITfDocumentMgr *pdimNew, + /* [out] */ ITfDocumentMgr **ppdimPrev); + + HRESULT ( STDMETHODCALLTYPE *IsThreadFocus )( + ITfThreadMgr * This, + /* [out] */ BOOL *pfThreadFocus); + + HRESULT ( STDMETHODCALLTYPE *GetFunctionProvider )( + ITfThreadMgr * This, + /* [in] */ REFCLSID clsid, + /* [out] */ ITfFunctionProvider **ppFuncProv); + + HRESULT ( STDMETHODCALLTYPE *EnumFunctionProviders )( + ITfThreadMgr * This, + /* [out] */ IEnumTfFunctionProviders **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *GetGlobalCompartment )( + ITfThreadMgr * This, + /* [out] */ ITfCompartmentMgr **ppCompMgr); + + END_INTERFACE + } ITfThreadMgrVtbl; + + interface ITfThreadMgr + { + CONST_VTBL struct ITfThreadMgrVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfThreadMgr_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfThreadMgr_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfThreadMgr_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfThreadMgr_Activate(This,ptid) \ + ( (This)->lpVtbl -> Activate(This,ptid) ) + +#define ITfThreadMgr_Deactivate(This) \ + ( (This)->lpVtbl -> Deactivate(This) ) + +#define ITfThreadMgr_CreateDocumentMgr(This,ppdim) \ + ( (This)->lpVtbl -> CreateDocumentMgr(This,ppdim) ) + +#define ITfThreadMgr_EnumDocumentMgrs(This,ppEnum) \ + ( (This)->lpVtbl -> EnumDocumentMgrs(This,ppEnum) ) + +#define ITfThreadMgr_GetFocus(This,ppdimFocus) \ + ( (This)->lpVtbl -> GetFocus(This,ppdimFocus) ) + +#define ITfThreadMgr_SetFocus(This,pdimFocus) \ + ( (This)->lpVtbl -> SetFocus(This,pdimFocus) ) + +#define ITfThreadMgr_AssociateFocus(This,hwnd,pdimNew,ppdimPrev) \ + ( (This)->lpVtbl -> AssociateFocus(This,hwnd,pdimNew,ppdimPrev) ) + +#define ITfThreadMgr_IsThreadFocus(This,pfThreadFocus) \ + ( (This)->lpVtbl -> IsThreadFocus(This,pfThreadFocus) ) + +#define ITfThreadMgr_GetFunctionProvider(This,clsid,ppFuncProv) \ + ( (This)->lpVtbl -> GetFunctionProvider(This,clsid,ppFuncProv) ) + +#define ITfThreadMgr_EnumFunctionProviders(This,ppEnum) \ + ( (This)->lpVtbl -> EnumFunctionProviders(This,ppEnum) ) + +#define ITfThreadMgr_GetGlobalCompartment(This,ppCompMgr) \ + ( (This)->lpVtbl -> GetGlobalCompartment(This,ppCompMgr) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfThreadMgr_INTERFACE_DEFINED__ */ + + +#ifndef __ITfThreadMgrEx_INTERFACE_DEFINED__ +#define __ITfThreadMgrEx_INTERFACE_DEFINED__ + +/* interface ITfThreadMgrEx */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfThreadMgrEx; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("3e90ade3-7594-4cb0-bb58-69628f5f458c") + ITfThreadMgrEx : public ITfThreadMgr + { + public: + virtual HRESULT STDMETHODCALLTYPE ActivateEx( + /* [out] */ TfClientId *ptid, + /* [in] */ DWORD dwFlags) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetActiveFlags( + /* [out] */ DWORD *lpdwFlags) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfThreadMgrExVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfThreadMgrEx * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfThreadMgrEx * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfThreadMgrEx * This); + + HRESULT ( STDMETHODCALLTYPE *Activate )( + ITfThreadMgrEx * This, + /* [out] */ TfClientId *ptid); + + HRESULT ( STDMETHODCALLTYPE *Deactivate )( + ITfThreadMgrEx * This); + + HRESULT ( STDMETHODCALLTYPE *CreateDocumentMgr )( + ITfThreadMgrEx * This, + /* [out] */ ITfDocumentMgr **ppdim); + + HRESULT ( STDMETHODCALLTYPE *EnumDocumentMgrs )( + ITfThreadMgrEx * This, + /* [out] */ IEnumTfDocumentMgrs **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *GetFocus )( + ITfThreadMgrEx * This, + /* [out] */ ITfDocumentMgr **ppdimFocus); + + HRESULT ( STDMETHODCALLTYPE *SetFocus )( + ITfThreadMgrEx * This, + /* [in] */ ITfDocumentMgr *pdimFocus); + + HRESULT ( STDMETHODCALLTYPE *AssociateFocus )( + ITfThreadMgrEx * This, + /* [in] */ HWND hwnd, + /* [unique][in] */ ITfDocumentMgr *pdimNew, + /* [out] */ ITfDocumentMgr **ppdimPrev); + + HRESULT ( STDMETHODCALLTYPE *IsThreadFocus )( + ITfThreadMgrEx * This, + /* [out] */ BOOL *pfThreadFocus); + + HRESULT ( STDMETHODCALLTYPE *GetFunctionProvider )( + ITfThreadMgrEx * This, + /* [in] */ REFCLSID clsid, + /* [out] */ ITfFunctionProvider **ppFuncProv); + + HRESULT ( STDMETHODCALLTYPE *EnumFunctionProviders )( + ITfThreadMgrEx * This, + /* [out] */ IEnumTfFunctionProviders **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *GetGlobalCompartment )( + ITfThreadMgrEx * This, + /* [out] */ ITfCompartmentMgr **ppCompMgr); + + HRESULT ( STDMETHODCALLTYPE *ActivateEx )( + ITfThreadMgrEx * This, + /* [out] */ TfClientId *ptid, + /* [in] */ DWORD dwFlags); + + HRESULT ( STDMETHODCALLTYPE *GetActiveFlags )( + ITfThreadMgrEx * This, + /* [out] */ DWORD *lpdwFlags); + + END_INTERFACE + } ITfThreadMgrExVtbl; + + interface ITfThreadMgrEx + { + CONST_VTBL struct ITfThreadMgrExVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfThreadMgrEx_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfThreadMgrEx_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfThreadMgrEx_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfThreadMgrEx_Activate(This,ptid) \ + ( (This)->lpVtbl -> Activate(This,ptid) ) + +#define ITfThreadMgrEx_Deactivate(This) \ + ( (This)->lpVtbl -> Deactivate(This) ) + +#define ITfThreadMgrEx_CreateDocumentMgr(This,ppdim) \ + ( (This)->lpVtbl -> CreateDocumentMgr(This,ppdim) ) + +#define ITfThreadMgrEx_EnumDocumentMgrs(This,ppEnum) \ + ( (This)->lpVtbl -> EnumDocumentMgrs(This,ppEnum) ) + +#define ITfThreadMgrEx_GetFocus(This,ppdimFocus) \ + ( (This)->lpVtbl -> GetFocus(This,ppdimFocus) ) + +#define ITfThreadMgrEx_SetFocus(This,pdimFocus) \ + ( (This)->lpVtbl -> SetFocus(This,pdimFocus) ) + +#define ITfThreadMgrEx_AssociateFocus(This,hwnd,pdimNew,ppdimPrev) \ + ( (This)->lpVtbl -> AssociateFocus(This,hwnd,pdimNew,ppdimPrev) ) + +#define ITfThreadMgrEx_IsThreadFocus(This,pfThreadFocus) \ + ( (This)->lpVtbl -> IsThreadFocus(This,pfThreadFocus) ) + +#define ITfThreadMgrEx_GetFunctionProvider(This,clsid,ppFuncProv) \ + ( (This)->lpVtbl -> GetFunctionProvider(This,clsid,ppFuncProv) ) + +#define ITfThreadMgrEx_EnumFunctionProviders(This,ppEnum) \ + ( (This)->lpVtbl -> EnumFunctionProviders(This,ppEnum) ) + +#define ITfThreadMgrEx_GetGlobalCompartment(This,ppCompMgr) \ + ( (This)->lpVtbl -> GetGlobalCompartment(This,ppCompMgr) ) + + +#define ITfThreadMgrEx_ActivateEx(This,ptid,dwFlags) \ + ( (This)->lpVtbl -> ActivateEx(This,ptid,dwFlags) ) + +#define ITfThreadMgrEx_GetActiveFlags(This,lpdwFlags) \ + ( (This)->lpVtbl -> GetActiveFlags(This,lpdwFlags) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfThreadMgrEx_INTERFACE_DEFINED__ */ + + +#ifndef __ITfThreadMgrEventSink_INTERFACE_DEFINED__ +#define __ITfThreadMgrEventSink_INTERFACE_DEFINED__ + +/* interface ITfThreadMgrEventSink */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfThreadMgrEventSink; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("aa80e80e-2021-11d2-93e0-0060b067b86e") + ITfThreadMgrEventSink : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE OnInitDocumentMgr( + /* [in] */ ITfDocumentMgr *pdim) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnUninitDocumentMgr( + /* [in] */ ITfDocumentMgr *pdim) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnSetFocus( + /* [in] */ ITfDocumentMgr *pdimFocus, + /* [in] */ ITfDocumentMgr *pdimPrevFocus) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnPushContext( + /* [in] */ ITfContext *pic) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnPopContext( + /* [in] */ ITfContext *pic) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfThreadMgrEventSinkVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfThreadMgrEventSink * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfThreadMgrEventSink * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfThreadMgrEventSink * This); + + HRESULT ( STDMETHODCALLTYPE *OnInitDocumentMgr )( + ITfThreadMgrEventSink * This, + /* [in] */ ITfDocumentMgr *pdim); + + HRESULT ( STDMETHODCALLTYPE *OnUninitDocumentMgr )( + ITfThreadMgrEventSink * This, + /* [in] */ ITfDocumentMgr *pdim); + + HRESULT ( STDMETHODCALLTYPE *OnSetFocus )( + ITfThreadMgrEventSink * This, + /* [in] */ ITfDocumentMgr *pdimFocus, + /* [in] */ ITfDocumentMgr *pdimPrevFocus); + + HRESULT ( STDMETHODCALLTYPE *OnPushContext )( + ITfThreadMgrEventSink * This, + /* [in] */ ITfContext *pic); + + HRESULT ( STDMETHODCALLTYPE *OnPopContext )( + ITfThreadMgrEventSink * This, + /* [in] */ ITfContext *pic); + + END_INTERFACE + } ITfThreadMgrEventSinkVtbl; + + interface ITfThreadMgrEventSink + { + CONST_VTBL struct ITfThreadMgrEventSinkVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfThreadMgrEventSink_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfThreadMgrEventSink_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfThreadMgrEventSink_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfThreadMgrEventSink_OnInitDocumentMgr(This,pdim) \ + ( (This)->lpVtbl -> OnInitDocumentMgr(This,pdim) ) + +#define ITfThreadMgrEventSink_OnUninitDocumentMgr(This,pdim) \ + ( (This)->lpVtbl -> OnUninitDocumentMgr(This,pdim) ) + +#define ITfThreadMgrEventSink_OnSetFocus(This,pdimFocus,pdimPrevFocus) \ + ( (This)->lpVtbl -> OnSetFocus(This,pdimFocus,pdimPrevFocus) ) + +#define ITfThreadMgrEventSink_OnPushContext(This,pic) \ + ( (This)->lpVtbl -> OnPushContext(This,pic) ) + +#define ITfThreadMgrEventSink_OnPopContext(This,pic) \ + ( (This)->lpVtbl -> OnPopContext(This,pic) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfThreadMgrEventSink_INTERFACE_DEFINED__ */ + + +#ifndef __ITfConfigureSystemKeystrokeFeed_INTERFACE_DEFINED__ +#define __ITfConfigureSystemKeystrokeFeed_INTERFACE_DEFINED__ + +/* interface ITfConfigureSystemKeystrokeFeed */ +/* [unique][uuid][local][object] */ + + +EXTERN_C const IID IID_ITfConfigureSystemKeystrokeFeed; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("0d2c969a-bc9c-437c-84ee-951c49b1a764") + ITfConfigureSystemKeystrokeFeed : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE DisableSystemKeystrokeFeed( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnableSystemKeystrokeFeed( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfConfigureSystemKeystrokeFeedVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfConfigureSystemKeystrokeFeed * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfConfigureSystemKeystrokeFeed * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfConfigureSystemKeystrokeFeed * This); + + HRESULT ( STDMETHODCALLTYPE *DisableSystemKeystrokeFeed )( + ITfConfigureSystemKeystrokeFeed * This); + + HRESULT ( STDMETHODCALLTYPE *EnableSystemKeystrokeFeed )( + ITfConfigureSystemKeystrokeFeed * This); + + END_INTERFACE + } ITfConfigureSystemKeystrokeFeedVtbl; + + interface ITfConfigureSystemKeystrokeFeed + { + CONST_VTBL struct ITfConfigureSystemKeystrokeFeedVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfConfigureSystemKeystrokeFeed_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfConfigureSystemKeystrokeFeed_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfConfigureSystemKeystrokeFeed_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfConfigureSystemKeystrokeFeed_DisableSystemKeystrokeFeed(This) \ + ( (This)->lpVtbl -> DisableSystemKeystrokeFeed(This) ) + +#define ITfConfigureSystemKeystrokeFeed_EnableSystemKeystrokeFeed(This) \ + ( (This)->lpVtbl -> EnableSystemKeystrokeFeed(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfConfigureSystemKeystrokeFeed_INTERFACE_DEFINED__ */ + + +#ifndef __IEnumTfDocumentMgrs_INTERFACE_DEFINED__ +#define __IEnumTfDocumentMgrs_INTERFACE_DEFINED__ + +/* interface IEnumTfDocumentMgrs */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_IEnumTfDocumentMgrs; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("aa80e808-2021-11d2-93e0-0060b067b86e") + IEnumTfDocumentMgrs : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ IEnumTfDocumentMgrs **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ ITfDocumentMgr **rgDocumentMgr, + /* [out] */ ULONG *pcFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG ulCount) = 0; + + }; + +#else /* C style interface */ + + typedef struct IEnumTfDocumentMgrsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IEnumTfDocumentMgrs * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IEnumTfDocumentMgrs * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IEnumTfDocumentMgrs * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IEnumTfDocumentMgrs * This, + /* [out] */ IEnumTfDocumentMgrs **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IEnumTfDocumentMgrs * This, + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ ITfDocumentMgr **rgDocumentMgr, + /* [out] */ ULONG *pcFetched); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IEnumTfDocumentMgrs * This); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + IEnumTfDocumentMgrs * This, + /* [in] */ ULONG ulCount); + + END_INTERFACE + } IEnumTfDocumentMgrsVtbl; + + interface IEnumTfDocumentMgrs + { + CONST_VTBL struct IEnumTfDocumentMgrsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IEnumTfDocumentMgrs_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IEnumTfDocumentMgrs_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IEnumTfDocumentMgrs_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IEnumTfDocumentMgrs_Clone(This,ppEnum) \ + ( (This)->lpVtbl -> Clone(This,ppEnum) ) + +#define IEnumTfDocumentMgrs_Next(This,ulCount,rgDocumentMgr,pcFetched) \ + ( (This)->lpVtbl -> Next(This,ulCount,rgDocumentMgr,pcFetched) ) + +#define IEnumTfDocumentMgrs_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define IEnumTfDocumentMgrs_Skip(This,ulCount) \ + ( (This)->lpVtbl -> Skip(This,ulCount) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IEnumTfDocumentMgrs_INTERFACE_DEFINED__ */ + + +#ifndef __ITfDocumentMgr_INTERFACE_DEFINED__ +#define __ITfDocumentMgr_INTERFACE_DEFINED__ + +/* interface ITfDocumentMgr */ +/* [unique][uuid][object] */ + +#define TF_POPF_ALL ( 0x1 ) + + +EXTERN_C const IID IID_ITfDocumentMgr; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("aa80e7f4-2021-11d2-93e0-0060b067b86e") + ITfDocumentMgr : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE CreateContext( + /* [in] */ TfClientId tidOwner, + /* [in] */ DWORD dwFlags, + /* [unique][in] */ IUnknown *punk, + /* [out] */ ITfContext **ppic, + /* [out] */ TfEditCookie *pecTextStore) = 0; + + virtual HRESULT STDMETHODCALLTYPE Push( + /* [in] */ ITfContext *pic) = 0; + + virtual HRESULT STDMETHODCALLTYPE Pop( + /* [in] */ DWORD dwFlags) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetTop( + /* [out] */ ITfContext **ppic) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetBase( + /* [out] */ ITfContext **ppic) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnumContexts( + /* [out] */ IEnumTfContexts **ppEnum) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfDocumentMgrVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfDocumentMgr * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfDocumentMgr * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfDocumentMgr * This); + + HRESULT ( STDMETHODCALLTYPE *CreateContext )( + ITfDocumentMgr * This, + /* [in] */ TfClientId tidOwner, + /* [in] */ DWORD dwFlags, + /* [unique][in] */ IUnknown *punk, + /* [out] */ ITfContext **ppic, + /* [out] */ TfEditCookie *pecTextStore); + + HRESULT ( STDMETHODCALLTYPE *Push )( + ITfDocumentMgr * This, + /* [in] */ ITfContext *pic); + + HRESULT ( STDMETHODCALLTYPE *Pop )( + ITfDocumentMgr * This, + /* [in] */ DWORD dwFlags); + + HRESULT ( STDMETHODCALLTYPE *GetTop )( + ITfDocumentMgr * This, + /* [out] */ ITfContext **ppic); + + HRESULT ( STDMETHODCALLTYPE *GetBase )( + ITfDocumentMgr * This, + /* [out] */ ITfContext **ppic); + + HRESULT ( STDMETHODCALLTYPE *EnumContexts )( + ITfDocumentMgr * This, + /* [out] */ IEnumTfContexts **ppEnum); + + END_INTERFACE + } ITfDocumentMgrVtbl; + + interface ITfDocumentMgr + { + CONST_VTBL struct ITfDocumentMgrVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfDocumentMgr_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfDocumentMgr_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfDocumentMgr_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfDocumentMgr_CreateContext(This,tidOwner,dwFlags,punk,ppic,pecTextStore) \ + ( (This)->lpVtbl -> CreateContext(This,tidOwner,dwFlags,punk,ppic,pecTextStore) ) + +#define ITfDocumentMgr_Push(This,pic) \ + ( (This)->lpVtbl -> Push(This,pic) ) + +#define ITfDocumentMgr_Pop(This,dwFlags) \ + ( (This)->lpVtbl -> Pop(This,dwFlags) ) + +#define ITfDocumentMgr_GetTop(This,ppic) \ + ( (This)->lpVtbl -> GetTop(This,ppic) ) + +#define ITfDocumentMgr_GetBase(This,ppic) \ + ( (This)->lpVtbl -> GetBase(This,ppic) ) + +#define ITfDocumentMgr_EnumContexts(This,ppEnum) \ + ( (This)->lpVtbl -> EnumContexts(This,ppEnum) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfDocumentMgr_INTERFACE_DEFINED__ */ + + +#ifndef __IEnumTfContexts_INTERFACE_DEFINED__ +#define __IEnumTfContexts_INTERFACE_DEFINED__ + +/* interface IEnumTfContexts */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_IEnumTfContexts; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("8f1a7ea6-1654-4502-a86e-b2902344d507") + IEnumTfContexts : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ IEnumTfContexts **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ ITfContext **rgContext, + /* [out] */ ULONG *pcFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG ulCount) = 0; + + }; + +#else /* C style interface */ + + typedef struct IEnumTfContextsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IEnumTfContexts * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IEnumTfContexts * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IEnumTfContexts * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IEnumTfContexts * This, + /* [out] */ IEnumTfContexts **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IEnumTfContexts * This, + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ ITfContext **rgContext, + /* [out] */ ULONG *pcFetched); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IEnumTfContexts * This); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + IEnumTfContexts * This, + /* [in] */ ULONG ulCount); + + END_INTERFACE + } IEnumTfContextsVtbl; + + interface IEnumTfContexts + { + CONST_VTBL struct IEnumTfContextsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IEnumTfContexts_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IEnumTfContexts_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IEnumTfContexts_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IEnumTfContexts_Clone(This,ppEnum) \ + ( (This)->lpVtbl -> Clone(This,ppEnum) ) + +#define IEnumTfContexts_Next(This,ulCount,rgContext,pcFetched) \ + ( (This)->lpVtbl -> Next(This,ulCount,rgContext,pcFetched) ) + +#define IEnumTfContexts_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define IEnumTfContexts_Skip(This,ulCount) \ + ( (This)->lpVtbl -> Skip(This,ulCount) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IEnumTfContexts_INTERFACE_DEFINED__ */ + + +#ifndef __ITfCompositionView_INTERFACE_DEFINED__ +#define __ITfCompositionView_INTERFACE_DEFINED__ + +/* interface ITfCompositionView */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfCompositionView; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("D7540241-F9A1-4364-BEFC-DBCD2C4395B7") + ITfCompositionView : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetOwnerClsid( + /* [out] */ CLSID *pclsid) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetRange( + /* [out] */ ITfRange **ppRange) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfCompositionViewVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfCompositionView * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfCompositionView * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfCompositionView * This); + + HRESULT ( STDMETHODCALLTYPE *GetOwnerClsid )( + ITfCompositionView * This, + /* [out] */ CLSID *pclsid); + + HRESULT ( STDMETHODCALLTYPE *GetRange )( + ITfCompositionView * This, + /* [out] */ ITfRange **ppRange); + + END_INTERFACE + } ITfCompositionViewVtbl; + + interface ITfCompositionView + { + CONST_VTBL struct ITfCompositionViewVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfCompositionView_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfCompositionView_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfCompositionView_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfCompositionView_GetOwnerClsid(This,pclsid) \ + ( (This)->lpVtbl -> GetOwnerClsid(This,pclsid) ) + +#define ITfCompositionView_GetRange(This,ppRange) \ + ( (This)->lpVtbl -> GetRange(This,ppRange) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfCompositionView_INTERFACE_DEFINED__ */ + + +#ifndef __IEnumITfCompositionView_INTERFACE_DEFINED__ +#define __IEnumITfCompositionView_INTERFACE_DEFINED__ + +/* interface IEnumITfCompositionView */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_IEnumITfCompositionView; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("5EFD22BA-7838-46CB-88E2-CADB14124F8F") + IEnumITfCompositionView : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ IEnumITfCompositionView **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ ITfCompositionView **rgCompositionView, + /* [out] */ ULONG *pcFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG ulCount) = 0; + + }; + +#else /* C style interface */ + + typedef struct IEnumITfCompositionViewVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IEnumITfCompositionView * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IEnumITfCompositionView * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IEnumITfCompositionView * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IEnumITfCompositionView * This, + /* [out] */ IEnumITfCompositionView **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IEnumITfCompositionView * This, + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ ITfCompositionView **rgCompositionView, + /* [out] */ ULONG *pcFetched); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IEnumITfCompositionView * This); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + IEnumITfCompositionView * This, + /* [in] */ ULONG ulCount); + + END_INTERFACE + } IEnumITfCompositionViewVtbl; + + interface IEnumITfCompositionView + { + CONST_VTBL struct IEnumITfCompositionViewVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IEnumITfCompositionView_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IEnumITfCompositionView_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IEnumITfCompositionView_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IEnumITfCompositionView_Clone(This,ppEnum) \ + ( (This)->lpVtbl -> Clone(This,ppEnum) ) + +#define IEnumITfCompositionView_Next(This,ulCount,rgCompositionView,pcFetched) \ + ( (This)->lpVtbl -> Next(This,ulCount,rgCompositionView,pcFetched) ) + +#define IEnumITfCompositionView_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define IEnumITfCompositionView_Skip(This,ulCount) \ + ( (This)->lpVtbl -> Skip(This,ulCount) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IEnumITfCompositionView_INTERFACE_DEFINED__ */ + + +#ifndef __ITfComposition_INTERFACE_DEFINED__ +#define __ITfComposition_INTERFACE_DEFINED__ + +/* interface ITfComposition */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfComposition; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("20168D64-5A8F-4A5A-B7BD-CFA29F4D0FD9") + ITfComposition : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetRange( + /* [out] */ ITfRange **ppRange) = 0; + + virtual HRESULT STDMETHODCALLTYPE ShiftStart( + /* [in] */ TfEditCookie ecWrite, + /* [in] */ ITfRange *pNewStart) = 0; + + virtual HRESULT STDMETHODCALLTYPE ShiftEnd( + /* [in] */ TfEditCookie ecWrite, + /* [in] */ ITfRange *pNewEnd) = 0; + + virtual HRESULT STDMETHODCALLTYPE EndComposition( + /* [in] */ TfEditCookie ecWrite) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfCompositionVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfComposition * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfComposition * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfComposition * This); + + HRESULT ( STDMETHODCALLTYPE *GetRange )( + ITfComposition * This, + /* [out] */ ITfRange **ppRange); + + HRESULT ( STDMETHODCALLTYPE *ShiftStart )( + ITfComposition * This, + /* [in] */ TfEditCookie ecWrite, + /* [in] */ ITfRange *pNewStart); + + HRESULT ( STDMETHODCALLTYPE *ShiftEnd )( + ITfComposition * This, + /* [in] */ TfEditCookie ecWrite, + /* [in] */ ITfRange *pNewEnd); + + HRESULT ( STDMETHODCALLTYPE *EndComposition )( + ITfComposition * This, + /* [in] */ TfEditCookie ecWrite); + + END_INTERFACE + } ITfCompositionVtbl; + + interface ITfComposition + { + CONST_VTBL struct ITfCompositionVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfComposition_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfComposition_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfComposition_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfComposition_GetRange(This,ppRange) \ + ( (This)->lpVtbl -> GetRange(This,ppRange) ) + +#define ITfComposition_ShiftStart(This,ecWrite,pNewStart) \ + ( (This)->lpVtbl -> ShiftStart(This,ecWrite,pNewStart) ) + +#define ITfComposition_ShiftEnd(This,ecWrite,pNewEnd) \ + ( (This)->lpVtbl -> ShiftEnd(This,ecWrite,pNewEnd) ) + +#define ITfComposition_EndComposition(This,ecWrite) \ + ( (This)->lpVtbl -> EndComposition(This,ecWrite) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfComposition_INTERFACE_DEFINED__ */ + + +#ifndef __ITfCompositionSink_INTERFACE_DEFINED__ +#define __ITfCompositionSink_INTERFACE_DEFINED__ + +/* interface ITfCompositionSink */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfCompositionSink; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("A781718C-579A-4B15-A280-32B8577ACC5E") + ITfCompositionSink : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE OnCompositionTerminated( + /* [in] */ TfEditCookie ecWrite, + /* [in] */ ITfComposition *pComposition) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfCompositionSinkVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfCompositionSink * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfCompositionSink * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfCompositionSink * This); + + HRESULT ( STDMETHODCALLTYPE *OnCompositionTerminated )( + ITfCompositionSink * This, + /* [in] */ TfEditCookie ecWrite, + /* [in] */ ITfComposition *pComposition); + + END_INTERFACE + } ITfCompositionSinkVtbl; + + interface ITfCompositionSink + { + CONST_VTBL struct ITfCompositionSinkVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfCompositionSink_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfCompositionSink_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfCompositionSink_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfCompositionSink_OnCompositionTerminated(This,ecWrite,pComposition) \ + ( (This)->lpVtbl -> OnCompositionTerminated(This,ecWrite,pComposition) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfCompositionSink_INTERFACE_DEFINED__ */ + + +#ifndef __ITfContextComposition_INTERFACE_DEFINED__ +#define __ITfContextComposition_INTERFACE_DEFINED__ + +/* interface ITfContextComposition */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfContextComposition; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("D40C8AAE-AC92-4FC7-9A11-0EE0E23AA39B") + ITfContextComposition : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE StartComposition( + /* [in] */ TfEditCookie ecWrite, + /* [in] */ ITfRange *pCompositionRange, + /* [in] */ ITfCompositionSink *pSink, + /* [out] */ ITfComposition **ppComposition) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnumCompositions( + /* [out] */ IEnumITfCompositionView **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE FindComposition( + /* [in] */ TfEditCookie ecRead, + /* [in] */ ITfRange *pTestRange, + /* [out] */ IEnumITfCompositionView **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE TakeOwnership( + /* [in] */ TfEditCookie ecWrite, + /* [in] */ ITfCompositionView *pComposition, + /* [in] */ ITfCompositionSink *pSink, + /* [out] */ ITfComposition **ppComposition) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfContextCompositionVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfContextComposition * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfContextComposition * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfContextComposition * This); + + HRESULT ( STDMETHODCALLTYPE *StartComposition )( + ITfContextComposition * This, + /* [in] */ TfEditCookie ecWrite, + /* [in] */ ITfRange *pCompositionRange, + /* [in] */ ITfCompositionSink *pSink, + /* [out] */ ITfComposition **ppComposition); + + HRESULT ( STDMETHODCALLTYPE *EnumCompositions )( + ITfContextComposition * This, + /* [out] */ IEnumITfCompositionView **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *FindComposition )( + ITfContextComposition * This, + /* [in] */ TfEditCookie ecRead, + /* [in] */ ITfRange *pTestRange, + /* [out] */ IEnumITfCompositionView **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *TakeOwnership )( + ITfContextComposition * This, + /* [in] */ TfEditCookie ecWrite, + /* [in] */ ITfCompositionView *pComposition, + /* [in] */ ITfCompositionSink *pSink, + /* [out] */ ITfComposition **ppComposition); + + END_INTERFACE + } ITfContextCompositionVtbl; + + interface ITfContextComposition + { + CONST_VTBL struct ITfContextCompositionVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfContextComposition_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfContextComposition_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfContextComposition_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfContextComposition_StartComposition(This,ecWrite,pCompositionRange,pSink,ppComposition) \ + ( (This)->lpVtbl -> StartComposition(This,ecWrite,pCompositionRange,pSink,ppComposition) ) + +#define ITfContextComposition_EnumCompositions(This,ppEnum) \ + ( (This)->lpVtbl -> EnumCompositions(This,ppEnum) ) + +#define ITfContextComposition_FindComposition(This,ecRead,pTestRange,ppEnum) \ + ( (This)->lpVtbl -> FindComposition(This,ecRead,pTestRange,ppEnum) ) + +#define ITfContextComposition_TakeOwnership(This,ecWrite,pComposition,pSink,ppComposition) \ + ( (This)->lpVtbl -> TakeOwnership(This,ecWrite,pComposition,pSink,ppComposition) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfContextComposition_INTERFACE_DEFINED__ */ + + +#ifndef __ITfContextOwnerCompositionServices_INTERFACE_DEFINED__ +#define __ITfContextOwnerCompositionServices_INTERFACE_DEFINED__ + +/* interface ITfContextOwnerCompositionServices */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfContextOwnerCompositionServices; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("86462810-593B-4916-9764-19C08E9CE110") + ITfContextOwnerCompositionServices : public ITfContextComposition + { + public: + virtual HRESULT STDMETHODCALLTYPE TerminateComposition( + /* [in] */ ITfCompositionView *pComposition) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfContextOwnerCompositionServicesVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfContextOwnerCompositionServices * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfContextOwnerCompositionServices * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfContextOwnerCompositionServices * This); + + HRESULT ( STDMETHODCALLTYPE *StartComposition )( + ITfContextOwnerCompositionServices * This, + /* [in] */ TfEditCookie ecWrite, + /* [in] */ ITfRange *pCompositionRange, + /* [in] */ ITfCompositionSink *pSink, + /* [out] */ ITfComposition **ppComposition); + + HRESULT ( STDMETHODCALLTYPE *EnumCompositions )( + ITfContextOwnerCompositionServices * This, + /* [out] */ IEnumITfCompositionView **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *FindComposition )( + ITfContextOwnerCompositionServices * This, + /* [in] */ TfEditCookie ecRead, + /* [in] */ ITfRange *pTestRange, + /* [out] */ IEnumITfCompositionView **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *TakeOwnership )( + ITfContextOwnerCompositionServices * This, + /* [in] */ TfEditCookie ecWrite, + /* [in] */ ITfCompositionView *pComposition, + /* [in] */ ITfCompositionSink *pSink, + /* [out] */ ITfComposition **ppComposition); + + HRESULT ( STDMETHODCALLTYPE *TerminateComposition )( + ITfContextOwnerCompositionServices * This, + /* [in] */ ITfCompositionView *pComposition); + + END_INTERFACE + } ITfContextOwnerCompositionServicesVtbl; + + interface ITfContextOwnerCompositionServices + { + CONST_VTBL struct ITfContextOwnerCompositionServicesVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfContextOwnerCompositionServices_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfContextOwnerCompositionServices_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfContextOwnerCompositionServices_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfContextOwnerCompositionServices_StartComposition(This,ecWrite,pCompositionRange,pSink,ppComposition) \ + ( (This)->lpVtbl -> StartComposition(This,ecWrite,pCompositionRange,pSink,ppComposition) ) + +#define ITfContextOwnerCompositionServices_EnumCompositions(This,ppEnum) \ + ( (This)->lpVtbl -> EnumCompositions(This,ppEnum) ) + +#define ITfContextOwnerCompositionServices_FindComposition(This,ecRead,pTestRange,ppEnum) \ + ( (This)->lpVtbl -> FindComposition(This,ecRead,pTestRange,ppEnum) ) + +#define ITfContextOwnerCompositionServices_TakeOwnership(This,ecWrite,pComposition,pSink,ppComposition) \ + ( (This)->lpVtbl -> TakeOwnership(This,ecWrite,pComposition,pSink,ppComposition) ) + + +#define ITfContextOwnerCompositionServices_TerminateComposition(This,pComposition) \ + ( (This)->lpVtbl -> TerminateComposition(This,pComposition) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfContextOwnerCompositionServices_INTERFACE_DEFINED__ */ + + +#ifndef __ITfContextOwnerCompositionSink_INTERFACE_DEFINED__ +#define __ITfContextOwnerCompositionSink_INTERFACE_DEFINED__ + +/* interface ITfContextOwnerCompositionSink */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfContextOwnerCompositionSink; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("5F20AA40-B57A-4F34-96AB-3576F377CC79") + ITfContextOwnerCompositionSink : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE OnStartComposition( + /* [in] */ ITfCompositionView *pComposition, + /* [out] */ BOOL *pfOk) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnUpdateComposition( + /* [in] */ ITfCompositionView *pComposition, + /* [in] */ ITfRange *pRangeNew) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnEndComposition( + /* [in] */ ITfCompositionView *pComposition) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfContextOwnerCompositionSinkVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfContextOwnerCompositionSink * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfContextOwnerCompositionSink * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfContextOwnerCompositionSink * This); + + HRESULT ( STDMETHODCALLTYPE *OnStartComposition )( + ITfContextOwnerCompositionSink * This, + /* [in] */ ITfCompositionView *pComposition, + /* [out] */ BOOL *pfOk); + + HRESULT ( STDMETHODCALLTYPE *OnUpdateComposition )( + ITfContextOwnerCompositionSink * This, + /* [in] */ ITfCompositionView *pComposition, + /* [in] */ ITfRange *pRangeNew); + + HRESULT ( STDMETHODCALLTYPE *OnEndComposition )( + ITfContextOwnerCompositionSink * This, + /* [in] */ ITfCompositionView *pComposition); + + END_INTERFACE + } ITfContextOwnerCompositionSinkVtbl; + + interface ITfContextOwnerCompositionSink + { + CONST_VTBL struct ITfContextOwnerCompositionSinkVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfContextOwnerCompositionSink_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfContextOwnerCompositionSink_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfContextOwnerCompositionSink_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfContextOwnerCompositionSink_OnStartComposition(This,pComposition,pfOk) \ + ( (This)->lpVtbl -> OnStartComposition(This,pComposition,pfOk) ) + +#define ITfContextOwnerCompositionSink_OnUpdateComposition(This,pComposition,pRangeNew) \ + ( (This)->lpVtbl -> OnUpdateComposition(This,pComposition,pRangeNew) ) + +#define ITfContextOwnerCompositionSink_OnEndComposition(This,pComposition) \ + ( (This)->lpVtbl -> OnEndComposition(This,pComposition) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfContextOwnerCompositionSink_INTERFACE_DEFINED__ */ + + +#ifndef __ITfContextView_INTERFACE_DEFINED__ +#define __ITfContextView_INTERFACE_DEFINED__ + +/* interface ITfContextView */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfContextView; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("2433bf8e-0f9b-435c-ba2c-180611978c30") + ITfContextView : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetRangeFromPoint( + /* [in] */ TfEditCookie ec, + /* [in] */ const POINT *ppt, + /* [in] */ DWORD dwFlags, + /* [out] */ ITfRange **ppRange) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetTextExt( + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pRange, + /* [out] */ RECT *prc, + /* [out] */ BOOL *pfClipped) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetScreenExt( + /* [out] */ RECT *prc) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetWnd( + /* [out] */ HWND *phwnd) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfContextViewVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfContextView * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfContextView * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfContextView * This); + + HRESULT ( STDMETHODCALLTYPE *GetRangeFromPoint )( + ITfContextView * This, + /* [in] */ TfEditCookie ec, + /* [in] */ const POINT *ppt, + /* [in] */ DWORD dwFlags, + /* [out] */ ITfRange **ppRange); + + HRESULT ( STDMETHODCALLTYPE *GetTextExt )( + ITfContextView * This, + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pRange, + /* [out] */ RECT *prc, + /* [out] */ BOOL *pfClipped); + + HRESULT ( STDMETHODCALLTYPE *GetScreenExt )( + ITfContextView * This, + /* [out] */ RECT *prc); + + HRESULT ( STDMETHODCALLTYPE *GetWnd )( + ITfContextView * This, + /* [out] */ HWND *phwnd); + + END_INTERFACE + } ITfContextViewVtbl; + + interface ITfContextView + { + CONST_VTBL struct ITfContextViewVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfContextView_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfContextView_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfContextView_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfContextView_GetRangeFromPoint(This,ec,ppt,dwFlags,ppRange) \ + ( (This)->lpVtbl -> GetRangeFromPoint(This,ec,ppt,dwFlags,ppRange) ) + +#define ITfContextView_GetTextExt(This,ec,pRange,prc,pfClipped) \ + ( (This)->lpVtbl -> GetTextExt(This,ec,pRange,prc,pfClipped) ) + +#define ITfContextView_GetScreenExt(This,prc) \ + ( (This)->lpVtbl -> GetScreenExt(This,prc) ) + +#define ITfContextView_GetWnd(This,phwnd) \ + ( (This)->lpVtbl -> GetWnd(This,phwnd) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfContextView_INTERFACE_DEFINED__ */ + + +#ifndef __IEnumTfContextViews_INTERFACE_DEFINED__ +#define __IEnumTfContextViews_INTERFACE_DEFINED__ + +/* interface IEnumTfContextViews */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_IEnumTfContextViews; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("F0C0F8DD-CF38-44E1-BB0F-68CF0D551C78") + IEnumTfContextViews : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ IEnumTfContextViews **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ ITfContextView **rgViews, + /* [out] */ ULONG *pcFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG ulCount) = 0; + + }; + +#else /* C style interface */ + + typedef struct IEnumTfContextViewsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IEnumTfContextViews * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IEnumTfContextViews * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IEnumTfContextViews * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IEnumTfContextViews * This, + /* [out] */ IEnumTfContextViews **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IEnumTfContextViews * This, + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ ITfContextView **rgViews, + /* [out] */ ULONG *pcFetched); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IEnumTfContextViews * This); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + IEnumTfContextViews * This, + /* [in] */ ULONG ulCount); + + END_INTERFACE + } IEnumTfContextViewsVtbl; + + interface IEnumTfContextViews + { + CONST_VTBL struct IEnumTfContextViewsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IEnumTfContextViews_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IEnumTfContextViews_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IEnumTfContextViews_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IEnumTfContextViews_Clone(This,ppEnum) \ + ( (This)->lpVtbl -> Clone(This,ppEnum) ) + +#define IEnumTfContextViews_Next(This,ulCount,rgViews,pcFetched) \ + ( (This)->lpVtbl -> Next(This,ulCount,rgViews,pcFetched) ) + +#define IEnumTfContextViews_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define IEnumTfContextViews_Skip(This,ulCount) \ + ( (This)->lpVtbl -> Skip(This,ulCount) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IEnumTfContextViews_INTERFACE_DEFINED__ */ + + +#ifndef __ITfContext_INTERFACE_DEFINED__ +#define __ITfContext_INTERFACE_DEFINED__ + +/* interface ITfContext */ +/* [unique][uuid][object] */ + +#define TF_ES_ASYNCDONTCARE ( 0 ) + +#define TF_ES_SYNC ( 0x1 ) + +#define TF_ES_READ ( 0x2 ) + +#define TF_ES_READWRITE ( 0x6 ) + +#define TF_ES_ASYNC ( 0x8 ) + +typedef /* [public][public][public][public][public][uuid] */ DECLSPEC_UUID("1690be9b-d3e9-49f6-8d8b-51b905af4c43") +enum __MIDL_ITfContext_0001 + { TF_AE_NONE = 0, + TF_AE_START = 1, + TF_AE_END = 2 + } TfActiveSelEnd; + +typedef /* [uuid] */ DECLSPEC_UUID("36ae42a4-6989-4bdc-b48a-6137b7bf2e42") struct TF_SELECTIONSTYLE + { + TfActiveSelEnd ase; + BOOL fInterimChar; + } TF_SELECTIONSTYLE; + +typedef /* [uuid] */ DECLSPEC_UUID("75eb22f2-b0bf-46a8-8006-975a3b6efcf1") struct TF_SELECTION + { + ITfRange *range; + TF_SELECTIONSTYLE style; + } TF_SELECTION; + +#define TF_DEFAULT_SELECTION ( TS_DEFAULT_SELECTION ) + +#define TF_SD_READONLY ( TS_SD_READONLY ) + +#define TF_SD_LOADING ( TS_SD_LOADING ) + +#define TF_SS_DISJOINTSEL ( TS_SS_DISJOINTSEL ) + +#define TF_SS_REGIONS ( TS_SS_REGIONS ) + +#define TF_SS_TRANSITORY ( TS_SS_TRANSITORY ) + +typedef /* [uuid] */ DECLSPEC_UUID("bc7d979a-846a-444d-afef-0a9bfa82b961") TS_STATUS TF_STATUS; + + +EXTERN_C const IID IID_ITfContext; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("aa80e7fd-2021-11d2-93e0-0060b067b86e") + ITfContext : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE RequestEditSession( + /* [in] */ TfClientId tid, + /* [in] */ ITfEditSession *pes, + /* [in] */ DWORD dwFlags, + /* [out] */ HRESULT *phrSession) = 0; + + virtual HRESULT STDMETHODCALLTYPE InWriteSession( + /* [in] */ TfClientId tid, + /* [out] */ BOOL *pfWriteSession) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetSelection( + /* [in] */ TfEditCookie ec, + /* [in] */ ULONG ulIndex, + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ TF_SELECTION *pSelection, + /* [out] */ ULONG *pcFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetSelection( + /* [in] */ TfEditCookie ec, + /* [in] */ ULONG ulCount, + /* [size_is][in] */ const TF_SELECTION *pSelection) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetStart( + /* [in] */ TfEditCookie ec, + /* [out] */ ITfRange **ppStart) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetEnd( + /* [in] */ TfEditCookie ec, + /* [out] */ ITfRange **ppEnd) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetActiveView( + /* [out] */ ITfContextView **ppView) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnumViews( + /* [out] */ IEnumTfContextViews **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetStatus( + /* [out] */ TF_STATUS *pdcs) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetProperty( + /* [in] */ REFGUID guidProp, + /* [out] */ ITfProperty **ppProp) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetAppProperty( + /* [in] */ REFGUID guidProp, + /* [out] */ ITfReadOnlyProperty **ppProp) = 0; + + virtual HRESULT STDMETHODCALLTYPE TrackProperties( + /* [size_is][in] */ const GUID **prgProp, + /* [in] */ ULONG cProp, + /* [size_is][in] */ const GUID **prgAppProp, + /* [in] */ ULONG cAppProp, + /* [out] */ ITfReadOnlyProperty **ppProperty) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnumProperties( + /* [out] */ IEnumTfProperties **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDocumentMgr( + /* [out] */ ITfDocumentMgr **ppDm) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateRangeBackup( + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pRange, + /* [out] */ ITfRangeBackup **ppBackup) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfContextVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfContext * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfContext * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfContext * This); + + HRESULT ( STDMETHODCALLTYPE *RequestEditSession )( + ITfContext * This, + /* [in] */ TfClientId tid, + /* [in] */ ITfEditSession *pes, + /* [in] */ DWORD dwFlags, + /* [out] */ HRESULT *phrSession); + + HRESULT ( STDMETHODCALLTYPE *InWriteSession )( + ITfContext * This, + /* [in] */ TfClientId tid, + /* [out] */ BOOL *pfWriteSession); + + HRESULT ( STDMETHODCALLTYPE *GetSelection )( + ITfContext * This, + /* [in] */ TfEditCookie ec, + /* [in] */ ULONG ulIndex, + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ TF_SELECTION *pSelection, + /* [out] */ ULONG *pcFetched); + + HRESULT ( STDMETHODCALLTYPE *SetSelection )( + ITfContext * This, + /* [in] */ TfEditCookie ec, + /* [in] */ ULONG ulCount, + /* [size_is][in] */ const TF_SELECTION *pSelection); + + HRESULT ( STDMETHODCALLTYPE *GetStart )( + ITfContext * This, + /* [in] */ TfEditCookie ec, + /* [out] */ ITfRange **ppStart); + + HRESULT ( STDMETHODCALLTYPE *GetEnd )( + ITfContext * This, + /* [in] */ TfEditCookie ec, + /* [out] */ ITfRange **ppEnd); + + HRESULT ( STDMETHODCALLTYPE *GetActiveView )( + ITfContext * This, + /* [out] */ ITfContextView **ppView); + + HRESULT ( STDMETHODCALLTYPE *EnumViews )( + ITfContext * This, + /* [out] */ IEnumTfContextViews **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *GetStatus )( + ITfContext * This, + /* [out] */ TF_STATUS *pdcs); + + HRESULT ( STDMETHODCALLTYPE *GetProperty )( + ITfContext * This, + /* [in] */ REFGUID guidProp, + /* [out] */ ITfProperty **ppProp); + + HRESULT ( STDMETHODCALLTYPE *GetAppProperty )( + ITfContext * This, + /* [in] */ REFGUID guidProp, + /* [out] */ ITfReadOnlyProperty **ppProp); + + HRESULT ( STDMETHODCALLTYPE *TrackProperties )( + ITfContext * This, + /* [size_is][in] */ const GUID **prgProp, + /* [in] */ ULONG cProp, + /* [size_is][in] */ const GUID **prgAppProp, + /* [in] */ ULONG cAppProp, + /* [out] */ ITfReadOnlyProperty **ppProperty); + + HRESULT ( STDMETHODCALLTYPE *EnumProperties )( + ITfContext * This, + /* [out] */ IEnumTfProperties **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *GetDocumentMgr )( + ITfContext * This, + /* [out] */ ITfDocumentMgr **ppDm); + + HRESULT ( STDMETHODCALLTYPE *CreateRangeBackup )( + ITfContext * This, + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pRange, + /* [out] */ ITfRangeBackup **ppBackup); + + END_INTERFACE + } ITfContextVtbl; + + interface ITfContext + { + CONST_VTBL struct ITfContextVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfContext_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfContext_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfContext_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfContext_RequestEditSession(This,tid,pes,dwFlags,phrSession) \ + ( (This)->lpVtbl -> RequestEditSession(This,tid,pes,dwFlags,phrSession) ) + +#define ITfContext_InWriteSession(This,tid,pfWriteSession) \ + ( (This)->lpVtbl -> InWriteSession(This,tid,pfWriteSession) ) + +#define ITfContext_GetSelection(This,ec,ulIndex,ulCount,pSelection,pcFetched) \ + ( (This)->lpVtbl -> GetSelection(This,ec,ulIndex,ulCount,pSelection,pcFetched) ) + +#define ITfContext_SetSelection(This,ec,ulCount,pSelection) \ + ( (This)->lpVtbl -> SetSelection(This,ec,ulCount,pSelection) ) + +#define ITfContext_GetStart(This,ec,ppStart) \ + ( (This)->lpVtbl -> GetStart(This,ec,ppStart) ) + +#define ITfContext_GetEnd(This,ec,ppEnd) \ + ( (This)->lpVtbl -> GetEnd(This,ec,ppEnd) ) + +#define ITfContext_GetActiveView(This,ppView) \ + ( (This)->lpVtbl -> GetActiveView(This,ppView) ) + +#define ITfContext_EnumViews(This,ppEnum) \ + ( (This)->lpVtbl -> EnumViews(This,ppEnum) ) + +#define ITfContext_GetStatus(This,pdcs) \ + ( (This)->lpVtbl -> GetStatus(This,pdcs) ) + +#define ITfContext_GetProperty(This,guidProp,ppProp) \ + ( (This)->lpVtbl -> GetProperty(This,guidProp,ppProp) ) + +#define ITfContext_GetAppProperty(This,guidProp,ppProp) \ + ( (This)->lpVtbl -> GetAppProperty(This,guidProp,ppProp) ) + +#define ITfContext_TrackProperties(This,prgProp,cProp,prgAppProp,cAppProp,ppProperty) \ + ( (This)->lpVtbl -> TrackProperties(This,prgProp,cProp,prgAppProp,cAppProp,ppProperty) ) + +#define ITfContext_EnumProperties(This,ppEnum) \ + ( (This)->lpVtbl -> EnumProperties(This,ppEnum) ) + +#define ITfContext_GetDocumentMgr(This,ppDm) \ + ( (This)->lpVtbl -> GetDocumentMgr(This,ppDm) ) + +#define ITfContext_CreateRangeBackup(This,ec,pRange,ppBackup) \ + ( (This)->lpVtbl -> CreateRangeBackup(This,ec,pRange,ppBackup) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfContext_INTERFACE_DEFINED__ */ + + +#ifndef __ITfQueryEmbedded_INTERFACE_DEFINED__ +#define __ITfQueryEmbedded_INTERFACE_DEFINED__ + +/* interface ITfQueryEmbedded */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfQueryEmbedded; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("0fab9bdb-d250-4169-84e5-6be118fdd7a8") + ITfQueryEmbedded : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE QueryInsertEmbedded( + /* [in] */ const GUID *pguidService, + /* [in] */ const FORMATETC *pFormatEtc, + /* [out] */ BOOL *pfInsertable) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfQueryEmbeddedVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfQueryEmbedded * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfQueryEmbedded * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfQueryEmbedded * This); + + HRESULT ( STDMETHODCALLTYPE *QueryInsertEmbedded )( + ITfQueryEmbedded * This, + /* [in] */ const GUID *pguidService, + /* [in] */ const FORMATETC *pFormatEtc, + /* [out] */ BOOL *pfInsertable); + + END_INTERFACE + } ITfQueryEmbeddedVtbl; + + interface ITfQueryEmbedded + { + CONST_VTBL struct ITfQueryEmbeddedVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfQueryEmbedded_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfQueryEmbedded_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfQueryEmbedded_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfQueryEmbedded_QueryInsertEmbedded(This,pguidService,pFormatEtc,pfInsertable) \ + ( (This)->lpVtbl -> QueryInsertEmbedded(This,pguidService,pFormatEtc,pfInsertable) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfQueryEmbedded_INTERFACE_DEFINED__ */ + + +#ifndef __ITfInsertAtSelection_INTERFACE_DEFINED__ +#define __ITfInsertAtSelection_INTERFACE_DEFINED__ + +/* interface ITfInsertAtSelection */ +/* [unique][uuid][object] */ + +#define TF_IAS_NOQUERY ( 0x1 ) + +#define TF_IAS_QUERYONLY ( 0x2 ) + +#define TF_IAS_NO_DEFAULT_COMPOSITION ( 0x80000000 ) + + +EXTERN_C const IID IID_ITfInsertAtSelection; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("55ce16ba-3014-41c1-9ceb-fade1446ac6c") + ITfInsertAtSelection : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE InsertTextAtSelection( + /* [in] */ TfEditCookie ec, + /* [in] */ DWORD dwFlags, + /* [size_is][in] */ const WCHAR *pchText, + /* [in] */ LONG cch, + /* [out] */ ITfRange **ppRange) = 0; + + virtual HRESULT STDMETHODCALLTYPE InsertEmbeddedAtSelection( + /* [in] */ TfEditCookie ec, + /* [in] */ DWORD dwFlags, + /* [in] */ IDataObject *pDataObject, + /* [out] */ ITfRange **ppRange) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfInsertAtSelectionVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfInsertAtSelection * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfInsertAtSelection * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfInsertAtSelection * This); + + HRESULT ( STDMETHODCALLTYPE *InsertTextAtSelection )( + ITfInsertAtSelection * This, + /* [in] */ TfEditCookie ec, + /* [in] */ DWORD dwFlags, + /* [size_is][in] */ const WCHAR *pchText, + /* [in] */ LONG cch, + /* [out] */ ITfRange **ppRange); + + HRESULT ( STDMETHODCALLTYPE *InsertEmbeddedAtSelection )( + ITfInsertAtSelection * This, + /* [in] */ TfEditCookie ec, + /* [in] */ DWORD dwFlags, + /* [in] */ IDataObject *pDataObject, + /* [out] */ ITfRange **ppRange); + + END_INTERFACE + } ITfInsertAtSelectionVtbl; + + interface ITfInsertAtSelection + { + CONST_VTBL struct ITfInsertAtSelectionVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfInsertAtSelection_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfInsertAtSelection_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfInsertAtSelection_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfInsertAtSelection_InsertTextAtSelection(This,ec,dwFlags,pchText,cch,ppRange) \ + ( (This)->lpVtbl -> InsertTextAtSelection(This,ec,dwFlags,pchText,cch,ppRange) ) + +#define ITfInsertAtSelection_InsertEmbeddedAtSelection(This,ec,dwFlags,pDataObject,ppRange) \ + ( (This)->lpVtbl -> InsertEmbeddedAtSelection(This,ec,dwFlags,pDataObject,ppRange) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfInsertAtSelection_INTERFACE_DEFINED__ */ + + +#ifndef __ITfCleanupContextSink_INTERFACE_DEFINED__ +#define __ITfCleanupContextSink_INTERFACE_DEFINED__ + +/* interface ITfCleanupContextSink */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfCleanupContextSink; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("01689689-7acb-4e9b-ab7c-7ea46b12b522") + ITfCleanupContextSink : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE OnCleanupContext( + /* [in] */ TfEditCookie ecWrite, + /* [in] */ ITfContext *pic) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfCleanupContextSinkVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfCleanupContextSink * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfCleanupContextSink * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfCleanupContextSink * This); + + HRESULT ( STDMETHODCALLTYPE *OnCleanupContext )( + ITfCleanupContextSink * This, + /* [in] */ TfEditCookie ecWrite, + /* [in] */ ITfContext *pic); + + END_INTERFACE + } ITfCleanupContextSinkVtbl; + + interface ITfCleanupContextSink + { + CONST_VTBL struct ITfCleanupContextSinkVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfCleanupContextSink_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfCleanupContextSink_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfCleanupContextSink_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfCleanupContextSink_OnCleanupContext(This,ecWrite,pic) \ + ( (This)->lpVtbl -> OnCleanupContext(This,ecWrite,pic) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfCleanupContextSink_INTERFACE_DEFINED__ */ + + +#ifndef __ITfCleanupContextDurationSink_INTERFACE_DEFINED__ +#define __ITfCleanupContextDurationSink_INTERFACE_DEFINED__ + +/* interface ITfCleanupContextDurationSink */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfCleanupContextDurationSink; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("45c35144-154e-4797-bed8-d33ae7bf8794") + ITfCleanupContextDurationSink : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE OnStartCleanupContext( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnEndCleanupContext( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfCleanupContextDurationSinkVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfCleanupContextDurationSink * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfCleanupContextDurationSink * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfCleanupContextDurationSink * This); + + HRESULT ( STDMETHODCALLTYPE *OnStartCleanupContext )( + ITfCleanupContextDurationSink * This); + + HRESULT ( STDMETHODCALLTYPE *OnEndCleanupContext )( + ITfCleanupContextDurationSink * This); + + END_INTERFACE + } ITfCleanupContextDurationSinkVtbl; + + interface ITfCleanupContextDurationSink + { + CONST_VTBL struct ITfCleanupContextDurationSinkVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfCleanupContextDurationSink_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfCleanupContextDurationSink_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfCleanupContextDurationSink_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfCleanupContextDurationSink_OnStartCleanupContext(This) \ + ( (This)->lpVtbl -> OnStartCleanupContext(This) ) + +#define ITfCleanupContextDurationSink_OnEndCleanupContext(This) \ + ( (This)->lpVtbl -> OnEndCleanupContext(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfCleanupContextDurationSink_INTERFACE_DEFINED__ */ + + +#ifndef __ITfReadOnlyProperty_INTERFACE_DEFINED__ +#define __ITfReadOnlyProperty_INTERFACE_DEFINED__ + +/* interface ITfReadOnlyProperty */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfReadOnlyProperty; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("17d49a3d-f8b8-4b2f-b254-52319dd64c53") + ITfReadOnlyProperty : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetType( + /* [out] */ GUID *pguid) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnumRanges( + /* [in] */ TfEditCookie ec, + /* [out] */ IEnumTfRanges **ppEnum, + /* [in] */ ITfRange *pTargetRange) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetValue( + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pRange, + /* [out] */ VARIANT *pvarValue) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetContext( + /* [out] */ ITfContext **ppContext) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfReadOnlyPropertyVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfReadOnlyProperty * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfReadOnlyProperty * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfReadOnlyProperty * This); + + HRESULT ( STDMETHODCALLTYPE *GetType )( + ITfReadOnlyProperty * This, + /* [out] */ GUID *pguid); + + HRESULT ( STDMETHODCALLTYPE *EnumRanges )( + ITfReadOnlyProperty * This, + /* [in] */ TfEditCookie ec, + /* [out] */ IEnumTfRanges **ppEnum, + /* [in] */ ITfRange *pTargetRange); + + HRESULT ( STDMETHODCALLTYPE *GetValue )( + ITfReadOnlyProperty * This, + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pRange, + /* [out] */ VARIANT *pvarValue); + + HRESULT ( STDMETHODCALLTYPE *GetContext )( + ITfReadOnlyProperty * This, + /* [out] */ ITfContext **ppContext); + + END_INTERFACE + } ITfReadOnlyPropertyVtbl; + + interface ITfReadOnlyProperty + { + CONST_VTBL struct ITfReadOnlyPropertyVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfReadOnlyProperty_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfReadOnlyProperty_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfReadOnlyProperty_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfReadOnlyProperty_GetType(This,pguid) \ + ( (This)->lpVtbl -> GetType(This,pguid) ) + +#define ITfReadOnlyProperty_EnumRanges(This,ec,ppEnum,pTargetRange) \ + ( (This)->lpVtbl -> EnumRanges(This,ec,ppEnum,pTargetRange) ) + +#define ITfReadOnlyProperty_GetValue(This,ec,pRange,pvarValue) \ + ( (This)->lpVtbl -> GetValue(This,ec,pRange,pvarValue) ) + +#define ITfReadOnlyProperty_GetContext(This,ppContext) \ + ( (This)->lpVtbl -> GetContext(This,ppContext) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfReadOnlyProperty_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_msctf_0000_0022 */ +/* [local] */ + +typedef /* [uuid] */ DECLSPEC_UUID("d678c645-eb6a-45c9-b4ee-0f3e3a991348") struct TF_PROPERTYVAL + { + GUID guidId; + VARIANT varValue; + } TF_PROPERTYVAL; + + + +extern RPC_IF_HANDLE __MIDL_itf_msctf_0000_0022_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_msctf_0000_0022_v0_0_s_ifspec; + +#ifndef __IEnumTfPropertyValue_INTERFACE_DEFINED__ +#define __IEnumTfPropertyValue_INTERFACE_DEFINED__ + +/* interface IEnumTfPropertyValue */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_IEnumTfPropertyValue; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("8ed8981b-7c10-4d7d-9fb3-ab72e9c75f72") + IEnumTfPropertyValue : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ IEnumTfPropertyValue **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ TF_PROPERTYVAL *rgValues, + /* [out] */ ULONG *pcFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG ulCount) = 0; + + }; + +#else /* C style interface */ + + typedef struct IEnumTfPropertyValueVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IEnumTfPropertyValue * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IEnumTfPropertyValue * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IEnumTfPropertyValue * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IEnumTfPropertyValue * This, + /* [out] */ IEnumTfPropertyValue **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IEnumTfPropertyValue * This, + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ TF_PROPERTYVAL *rgValues, + /* [out] */ ULONG *pcFetched); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IEnumTfPropertyValue * This); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + IEnumTfPropertyValue * This, + /* [in] */ ULONG ulCount); + + END_INTERFACE + } IEnumTfPropertyValueVtbl; + + interface IEnumTfPropertyValue + { + CONST_VTBL struct IEnumTfPropertyValueVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IEnumTfPropertyValue_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IEnumTfPropertyValue_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IEnumTfPropertyValue_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IEnumTfPropertyValue_Clone(This,ppEnum) \ + ( (This)->lpVtbl -> Clone(This,ppEnum) ) + +#define IEnumTfPropertyValue_Next(This,ulCount,rgValues,pcFetched) \ + ( (This)->lpVtbl -> Next(This,ulCount,rgValues,pcFetched) ) + +#define IEnumTfPropertyValue_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define IEnumTfPropertyValue_Skip(This,ulCount) \ + ( (This)->lpVtbl -> Skip(This,ulCount) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IEnumTfPropertyValue_INTERFACE_DEFINED__ */ + + +#ifndef __ITfMouseTracker_INTERFACE_DEFINED__ +#define __ITfMouseTracker_INTERFACE_DEFINED__ + +/* interface ITfMouseTracker */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfMouseTracker; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("09d146cd-a544-4132-925b-7afa8ef322d0") + ITfMouseTracker : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE AdviseMouseSink( + /* [in] */ ITfRange *range, + /* [in] */ ITfMouseSink *pSink, + /* [out] */ DWORD *pdwCookie) = 0; + + virtual HRESULT STDMETHODCALLTYPE UnadviseMouseSink( + /* [in] */ DWORD dwCookie) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfMouseTrackerVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfMouseTracker * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfMouseTracker * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfMouseTracker * This); + + HRESULT ( STDMETHODCALLTYPE *AdviseMouseSink )( + ITfMouseTracker * This, + /* [in] */ ITfRange *range, + /* [in] */ ITfMouseSink *pSink, + /* [out] */ DWORD *pdwCookie); + + HRESULT ( STDMETHODCALLTYPE *UnadviseMouseSink )( + ITfMouseTracker * This, + /* [in] */ DWORD dwCookie); + + END_INTERFACE + } ITfMouseTrackerVtbl; + + interface ITfMouseTracker + { + CONST_VTBL struct ITfMouseTrackerVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfMouseTracker_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfMouseTracker_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfMouseTracker_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfMouseTracker_AdviseMouseSink(This,range,pSink,pdwCookie) \ + ( (This)->lpVtbl -> AdviseMouseSink(This,range,pSink,pdwCookie) ) + +#define ITfMouseTracker_UnadviseMouseSink(This,dwCookie) \ + ( (This)->lpVtbl -> UnadviseMouseSink(This,dwCookie) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfMouseTracker_INTERFACE_DEFINED__ */ + + +#ifndef __ITfMouseTrackerACP_INTERFACE_DEFINED__ +#define __ITfMouseTrackerACP_INTERFACE_DEFINED__ + +/* interface ITfMouseTrackerACP */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfMouseTrackerACP; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("3bdd78e2-c16e-47fd-b883-ce6facc1a208") + ITfMouseTrackerACP : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE AdviseMouseSink( + /* [in] */ ITfRangeACP *range, + /* [in] */ ITfMouseSink *pSink, + /* [out] */ DWORD *pdwCookie) = 0; + + virtual HRESULT STDMETHODCALLTYPE UnadviseMouseSink( + /* [in] */ DWORD dwCookie) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfMouseTrackerACPVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfMouseTrackerACP * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfMouseTrackerACP * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfMouseTrackerACP * This); + + HRESULT ( STDMETHODCALLTYPE *AdviseMouseSink )( + ITfMouseTrackerACP * This, + /* [in] */ ITfRangeACP *range, + /* [in] */ ITfMouseSink *pSink, + /* [out] */ DWORD *pdwCookie); + + HRESULT ( STDMETHODCALLTYPE *UnadviseMouseSink )( + ITfMouseTrackerACP * This, + /* [in] */ DWORD dwCookie); + + END_INTERFACE + } ITfMouseTrackerACPVtbl; + + interface ITfMouseTrackerACP + { + CONST_VTBL struct ITfMouseTrackerACPVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfMouseTrackerACP_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfMouseTrackerACP_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfMouseTrackerACP_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfMouseTrackerACP_AdviseMouseSink(This,range,pSink,pdwCookie) \ + ( (This)->lpVtbl -> AdviseMouseSink(This,range,pSink,pdwCookie) ) + +#define ITfMouseTrackerACP_UnadviseMouseSink(This,dwCookie) \ + ( (This)->lpVtbl -> UnadviseMouseSink(This,dwCookie) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfMouseTrackerACP_INTERFACE_DEFINED__ */ + + +#ifndef __ITfMouseSink_INTERFACE_DEFINED__ +#define __ITfMouseSink_INTERFACE_DEFINED__ + +/* interface ITfMouseSink */ +/* [unique][uuid][local][object] */ + + +EXTERN_C const IID IID_ITfMouseSink; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("a1adaaa2-3a24-449d-ac96-5183e7f5c217") + ITfMouseSink : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE OnMouseEvent( + /* [in] */ ULONG uEdge, + /* [in] */ ULONG uQuadrant, + /* [in] */ DWORD dwBtnStatus, + /* [out] */ BOOL *pfEaten) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfMouseSinkVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfMouseSink * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfMouseSink * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfMouseSink * This); + + HRESULT ( STDMETHODCALLTYPE *OnMouseEvent )( + ITfMouseSink * This, + /* [in] */ ULONG uEdge, + /* [in] */ ULONG uQuadrant, + /* [in] */ DWORD dwBtnStatus, + /* [out] */ BOOL *pfEaten); + + END_INTERFACE + } ITfMouseSinkVtbl; + + interface ITfMouseSink + { + CONST_VTBL struct ITfMouseSinkVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfMouseSink_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfMouseSink_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfMouseSink_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfMouseSink_OnMouseEvent(This,uEdge,uQuadrant,dwBtnStatus,pfEaten) \ + ( (This)->lpVtbl -> OnMouseEvent(This,uEdge,uQuadrant,dwBtnStatus,pfEaten) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfMouseSink_INTERFACE_DEFINED__ */ + + +#ifndef __ITfEditRecord_INTERFACE_DEFINED__ +#define __ITfEditRecord_INTERFACE_DEFINED__ + +/* interface ITfEditRecord */ +/* [unique][uuid][object] */ + +#define TF_GTP_INCL_TEXT ( 0x1 ) + + +EXTERN_C const IID IID_ITfEditRecord; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("42d4d099-7c1a-4a89-b836-6c6f22160df0") + ITfEditRecord : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetSelectionStatus( + /* [out] */ BOOL *pfChanged) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetTextAndPropertyUpdates( + /* [in] */ DWORD dwFlags, + /* [size_is][in] */ const GUID **prgProperties, + /* [in] */ ULONG cProperties, + /* [out] */ IEnumTfRanges **ppEnum) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfEditRecordVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfEditRecord * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfEditRecord * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfEditRecord * This); + + HRESULT ( STDMETHODCALLTYPE *GetSelectionStatus )( + ITfEditRecord * This, + /* [out] */ BOOL *pfChanged); + + HRESULT ( STDMETHODCALLTYPE *GetTextAndPropertyUpdates )( + ITfEditRecord * This, + /* [in] */ DWORD dwFlags, + /* [size_is][in] */ const GUID **prgProperties, + /* [in] */ ULONG cProperties, + /* [out] */ IEnumTfRanges **ppEnum); + + END_INTERFACE + } ITfEditRecordVtbl; + + interface ITfEditRecord + { + CONST_VTBL struct ITfEditRecordVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfEditRecord_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfEditRecord_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfEditRecord_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfEditRecord_GetSelectionStatus(This,pfChanged) \ + ( (This)->lpVtbl -> GetSelectionStatus(This,pfChanged) ) + +#define ITfEditRecord_GetTextAndPropertyUpdates(This,dwFlags,prgProperties,cProperties,ppEnum) \ + ( (This)->lpVtbl -> GetTextAndPropertyUpdates(This,dwFlags,prgProperties,cProperties,ppEnum) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfEditRecord_INTERFACE_DEFINED__ */ + + +#ifndef __ITfTextEditSink_INTERFACE_DEFINED__ +#define __ITfTextEditSink_INTERFACE_DEFINED__ + +/* interface ITfTextEditSink */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfTextEditSink; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("8127d409-ccd3-4683-967a-b43d5b482bf7") + ITfTextEditSink : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE OnEndEdit( + /* [in] */ ITfContext *pic, + /* [in] */ TfEditCookie ecReadOnly, + /* [in] */ ITfEditRecord *pEditRecord) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfTextEditSinkVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfTextEditSink * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfTextEditSink * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfTextEditSink * This); + + HRESULT ( STDMETHODCALLTYPE *OnEndEdit )( + ITfTextEditSink * This, + /* [in] */ ITfContext *pic, + /* [in] */ TfEditCookie ecReadOnly, + /* [in] */ ITfEditRecord *pEditRecord); + + END_INTERFACE + } ITfTextEditSinkVtbl; + + interface ITfTextEditSink + { + CONST_VTBL struct ITfTextEditSinkVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfTextEditSink_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfTextEditSink_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfTextEditSink_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfTextEditSink_OnEndEdit(This,pic,ecReadOnly,pEditRecord) \ + ( (This)->lpVtbl -> OnEndEdit(This,pic,ecReadOnly,pEditRecord) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfTextEditSink_INTERFACE_DEFINED__ */ + + +#ifndef __ITfTextLayoutSink_INTERFACE_DEFINED__ +#define __ITfTextLayoutSink_INTERFACE_DEFINED__ + +/* interface ITfTextLayoutSink */ +/* [unique][uuid][object] */ + +typedef /* [public][public][uuid] */ DECLSPEC_UUID("603553cf-9edd-4cc1-9ecc-069e4a427734") +enum __MIDL_ITfTextLayoutSink_0001 + { TF_LC_CREATE = 0, + TF_LC_CHANGE = 1, + TF_LC_DESTROY = 2 + } TfLayoutCode; + + +EXTERN_C const IID IID_ITfTextLayoutSink; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("2af2d06a-dd5b-4927-a0b4-54f19c91fade") + ITfTextLayoutSink : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE OnLayoutChange( + /* [in] */ ITfContext *pic, + /* [in] */ TfLayoutCode lcode, + /* [in] */ ITfContextView *pView) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfTextLayoutSinkVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfTextLayoutSink * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfTextLayoutSink * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfTextLayoutSink * This); + + HRESULT ( STDMETHODCALLTYPE *OnLayoutChange )( + ITfTextLayoutSink * This, + /* [in] */ ITfContext *pic, + /* [in] */ TfLayoutCode lcode, + /* [in] */ ITfContextView *pView); + + END_INTERFACE + } ITfTextLayoutSinkVtbl; + + interface ITfTextLayoutSink + { + CONST_VTBL struct ITfTextLayoutSinkVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfTextLayoutSink_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfTextLayoutSink_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfTextLayoutSink_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfTextLayoutSink_OnLayoutChange(This,pic,lcode,pView) \ + ( (This)->lpVtbl -> OnLayoutChange(This,pic,lcode,pView) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfTextLayoutSink_INTERFACE_DEFINED__ */ + + +#ifndef __ITfStatusSink_INTERFACE_DEFINED__ +#define __ITfStatusSink_INTERFACE_DEFINED__ + +/* interface ITfStatusSink */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfStatusSink; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("6b7d8d73-b267-4f69-b32e-1ca321ce4f45") + ITfStatusSink : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE OnStatusChange( + /* [in] */ ITfContext *pic, + /* [in] */ DWORD dwFlags) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfStatusSinkVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfStatusSink * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfStatusSink * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfStatusSink * This); + + HRESULT ( STDMETHODCALLTYPE *OnStatusChange )( + ITfStatusSink * This, + /* [in] */ ITfContext *pic, + /* [in] */ DWORD dwFlags); + + END_INTERFACE + } ITfStatusSinkVtbl; + + interface ITfStatusSink + { + CONST_VTBL struct ITfStatusSinkVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfStatusSink_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfStatusSink_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfStatusSink_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfStatusSink_OnStatusChange(This,pic,dwFlags) \ + ( (This)->lpVtbl -> OnStatusChange(This,pic,dwFlags) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfStatusSink_INTERFACE_DEFINED__ */ + + +#ifndef __ITfEditTransactionSink_INTERFACE_DEFINED__ +#define __ITfEditTransactionSink_INTERFACE_DEFINED__ + +/* interface ITfEditTransactionSink */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfEditTransactionSink; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("708fbf70-b520-416b-b06c-2c41ab44f8ba") + ITfEditTransactionSink : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE OnStartEditTransaction( + /* [in] */ ITfContext *pic) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnEndEditTransaction( + /* [in] */ ITfContext *pic) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfEditTransactionSinkVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfEditTransactionSink * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfEditTransactionSink * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfEditTransactionSink * This); + + HRESULT ( STDMETHODCALLTYPE *OnStartEditTransaction )( + ITfEditTransactionSink * This, + /* [in] */ ITfContext *pic); + + HRESULT ( STDMETHODCALLTYPE *OnEndEditTransaction )( + ITfEditTransactionSink * This, + /* [in] */ ITfContext *pic); + + END_INTERFACE + } ITfEditTransactionSinkVtbl; + + interface ITfEditTransactionSink + { + CONST_VTBL struct ITfEditTransactionSinkVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfEditTransactionSink_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfEditTransactionSink_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfEditTransactionSink_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfEditTransactionSink_OnStartEditTransaction(This,pic) \ + ( (This)->lpVtbl -> OnStartEditTransaction(This,pic) ) + +#define ITfEditTransactionSink_OnEndEditTransaction(This,pic) \ + ( (This)->lpVtbl -> OnEndEditTransaction(This,pic) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfEditTransactionSink_INTERFACE_DEFINED__ */ + + +#ifndef __ITfContextOwner_INTERFACE_DEFINED__ +#define __ITfContextOwner_INTERFACE_DEFINED__ + +/* interface ITfContextOwner */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfContextOwner; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("aa80e80c-2021-11d2-93e0-0060b067b86e") + ITfContextOwner : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetACPFromPoint( + /* [in] */ const POINT *ptScreen, + /* [in] */ DWORD dwFlags, + /* [out] */ LONG *pacp) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetTextExt( + /* [in] */ LONG acpStart, + /* [in] */ LONG acpEnd, + /* [out] */ RECT *prc, + /* [out] */ BOOL *pfClipped) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetScreenExt( + /* [out] */ RECT *prc) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetStatus( + /* [out] */ TF_STATUS *pdcs) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetWnd( + /* [out] */ HWND *phwnd) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetAttribute( + /* [in] */ REFGUID rguidAttribute, + /* [out] */ VARIANT *pvarValue) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfContextOwnerVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfContextOwner * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfContextOwner * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfContextOwner * This); + + HRESULT ( STDMETHODCALLTYPE *GetACPFromPoint )( + ITfContextOwner * This, + /* [in] */ const POINT *ptScreen, + /* [in] */ DWORD dwFlags, + /* [out] */ LONG *pacp); + + HRESULT ( STDMETHODCALLTYPE *GetTextExt )( + ITfContextOwner * This, + /* [in] */ LONG acpStart, + /* [in] */ LONG acpEnd, + /* [out] */ RECT *prc, + /* [out] */ BOOL *pfClipped); + + HRESULT ( STDMETHODCALLTYPE *GetScreenExt )( + ITfContextOwner * This, + /* [out] */ RECT *prc); + + HRESULT ( STDMETHODCALLTYPE *GetStatus )( + ITfContextOwner * This, + /* [out] */ TF_STATUS *pdcs); + + HRESULT ( STDMETHODCALLTYPE *GetWnd )( + ITfContextOwner * This, + /* [out] */ HWND *phwnd); + + HRESULT ( STDMETHODCALLTYPE *GetAttribute )( + ITfContextOwner * This, + /* [in] */ REFGUID rguidAttribute, + /* [out] */ VARIANT *pvarValue); + + END_INTERFACE + } ITfContextOwnerVtbl; + + interface ITfContextOwner + { + CONST_VTBL struct ITfContextOwnerVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfContextOwner_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfContextOwner_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfContextOwner_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfContextOwner_GetACPFromPoint(This,ptScreen,dwFlags,pacp) \ + ( (This)->lpVtbl -> GetACPFromPoint(This,ptScreen,dwFlags,pacp) ) + +#define ITfContextOwner_GetTextExt(This,acpStart,acpEnd,prc,pfClipped) \ + ( (This)->lpVtbl -> GetTextExt(This,acpStart,acpEnd,prc,pfClipped) ) + +#define ITfContextOwner_GetScreenExt(This,prc) \ + ( (This)->lpVtbl -> GetScreenExt(This,prc) ) + +#define ITfContextOwner_GetStatus(This,pdcs) \ + ( (This)->lpVtbl -> GetStatus(This,pdcs) ) + +#define ITfContextOwner_GetWnd(This,phwnd) \ + ( (This)->lpVtbl -> GetWnd(This,phwnd) ) + +#define ITfContextOwner_GetAttribute(This,rguidAttribute,pvarValue) \ + ( (This)->lpVtbl -> GetAttribute(This,rguidAttribute,pvarValue) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfContextOwner_INTERFACE_DEFINED__ */ + + +#ifndef __ITfContextOwnerServices_INTERFACE_DEFINED__ +#define __ITfContextOwnerServices_INTERFACE_DEFINED__ + +/* interface ITfContextOwnerServices */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfContextOwnerServices; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("b23eb630-3e1c-11d3-a745-0050040ab407") + ITfContextOwnerServices : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE OnLayoutChange( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnStatusChange( + /* [in] */ DWORD dwFlags) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnAttributeChange( + /* [in] */ REFGUID rguidAttribute) = 0; + + virtual HRESULT STDMETHODCALLTYPE Serialize( + /* [in] */ ITfProperty *pProp, + /* [in] */ ITfRange *pRange, + /* [out] */ TF_PERSISTENT_PROPERTY_HEADER_ACP *pHdr, + /* [in] */ IStream *pStream) = 0; + + virtual HRESULT STDMETHODCALLTYPE Unserialize( + /* [in] */ ITfProperty *pProp, + /* [in] */ const TF_PERSISTENT_PROPERTY_HEADER_ACP *pHdr, + /* [in] */ IStream *pStream, + /* [in] */ ITfPersistentPropertyLoaderACP *pLoader) = 0; + + virtual HRESULT STDMETHODCALLTYPE ForceLoadProperty( + /* [in] */ ITfProperty *pProp) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateRange( + /* [in] */ LONG acpStart, + /* [in] */ LONG acpEnd, + /* [out] */ ITfRangeACP **ppRange) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfContextOwnerServicesVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfContextOwnerServices * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfContextOwnerServices * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfContextOwnerServices * This); + + HRESULT ( STDMETHODCALLTYPE *OnLayoutChange )( + ITfContextOwnerServices * This); + + HRESULT ( STDMETHODCALLTYPE *OnStatusChange )( + ITfContextOwnerServices * This, + /* [in] */ DWORD dwFlags); + + HRESULT ( STDMETHODCALLTYPE *OnAttributeChange )( + ITfContextOwnerServices * This, + /* [in] */ REFGUID rguidAttribute); + + HRESULT ( STDMETHODCALLTYPE *Serialize )( + ITfContextOwnerServices * This, + /* [in] */ ITfProperty *pProp, + /* [in] */ ITfRange *pRange, + /* [out] */ TF_PERSISTENT_PROPERTY_HEADER_ACP *pHdr, + /* [in] */ IStream *pStream); + + HRESULT ( STDMETHODCALLTYPE *Unserialize )( + ITfContextOwnerServices * This, + /* [in] */ ITfProperty *pProp, + /* [in] */ const TF_PERSISTENT_PROPERTY_HEADER_ACP *pHdr, + /* [in] */ IStream *pStream, + /* [in] */ ITfPersistentPropertyLoaderACP *pLoader); + + HRESULT ( STDMETHODCALLTYPE *ForceLoadProperty )( + ITfContextOwnerServices * This, + /* [in] */ ITfProperty *pProp); + + HRESULT ( STDMETHODCALLTYPE *CreateRange )( + ITfContextOwnerServices * This, + /* [in] */ LONG acpStart, + /* [in] */ LONG acpEnd, + /* [out] */ ITfRangeACP **ppRange); + + END_INTERFACE + } ITfContextOwnerServicesVtbl; + + interface ITfContextOwnerServices + { + CONST_VTBL struct ITfContextOwnerServicesVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfContextOwnerServices_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfContextOwnerServices_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfContextOwnerServices_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfContextOwnerServices_OnLayoutChange(This) \ + ( (This)->lpVtbl -> OnLayoutChange(This) ) + +#define ITfContextOwnerServices_OnStatusChange(This,dwFlags) \ + ( (This)->lpVtbl -> OnStatusChange(This,dwFlags) ) + +#define ITfContextOwnerServices_OnAttributeChange(This,rguidAttribute) \ + ( (This)->lpVtbl -> OnAttributeChange(This,rguidAttribute) ) + +#define ITfContextOwnerServices_Serialize(This,pProp,pRange,pHdr,pStream) \ + ( (This)->lpVtbl -> Serialize(This,pProp,pRange,pHdr,pStream) ) + +#define ITfContextOwnerServices_Unserialize(This,pProp,pHdr,pStream,pLoader) \ + ( (This)->lpVtbl -> Unserialize(This,pProp,pHdr,pStream,pLoader) ) + +#define ITfContextOwnerServices_ForceLoadProperty(This,pProp) \ + ( (This)->lpVtbl -> ForceLoadProperty(This,pProp) ) + +#define ITfContextOwnerServices_CreateRange(This,acpStart,acpEnd,ppRange) \ + ( (This)->lpVtbl -> CreateRange(This,acpStart,acpEnd,ppRange) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfContextOwnerServices_INTERFACE_DEFINED__ */ + + +#ifndef __ITfContextKeyEventSink_INTERFACE_DEFINED__ +#define __ITfContextKeyEventSink_INTERFACE_DEFINED__ + +/* interface ITfContextKeyEventSink */ +/* [unique][uuid][local][object] */ + + +EXTERN_C const IID IID_ITfContextKeyEventSink; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("0552ba5d-c835-4934-bf50-846aaa67432f") + ITfContextKeyEventSink : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE OnKeyDown( + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ BOOL *pfEaten) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnKeyUp( + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ BOOL *pfEaten) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnTestKeyDown( + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ BOOL *pfEaten) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnTestKeyUp( + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ BOOL *pfEaten) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfContextKeyEventSinkVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfContextKeyEventSink * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfContextKeyEventSink * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfContextKeyEventSink * This); + + HRESULT ( STDMETHODCALLTYPE *OnKeyDown )( + ITfContextKeyEventSink * This, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ BOOL *pfEaten); + + HRESULT ( STDMETHODCALLTYPE *OnKeyUp )( + ITfContextKeyEventSink * This, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ BOOL *pfEaten); + + HRESULT ( STDMETHODCALLTYPE *OnTestKeyDown )( + ITfContextKeyEventSink * This, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ BOOL *pfEaten); + + HRESULT ( STDMETHODCALLTYPE *OnTestKeyUp )( + ITfContextKeyEventSink * This, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ BOOL *pfEaten); + + END_INTERFACE + } ITfContextKeyEventSinkVtbl; + + interface ITfContextKeyEventSink + { + CONST_VTBL struct ITfContextKeyEventSinkVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfContextKeyEventSink_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfContextKeyEventSink_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfContextKeyEventSink_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfContextKeyEventSink_OnKeyDown(This,wParam,lParam,pfEaten) \ + ( (This)->lpVtbl -> OnKeyDown(This,wParam,lParam,pfEaten) ) + +#define ITfContextKeyEventSink_OnKeyUp(This,wParam,lParam,pfEaten) \ + ( (This)->lpVtbl -> OnKeyUp(This,wParam,lParam,pfEaten) ) + +#define ITfContextKeyEventSink_OnTestKeyDown(This,wParam,lParam,pfEaten) \ + ( (This)->lpVtbl -> OnTestKeyDown(This,wParam,lParam,pfEaten) ) + +#define ITfContextKeyEventSink_OnTestKeyUp(This,wParam,lParam,pfEaten) \ + ( (This)->lpVtbl -> OnTestKeyUp(This,wParam,lParam,pfEaten) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfContextKeyEventSink_INTERFACE_DEFINED__ */ + + +#ifndef __ITfEditSession_INTERFACE_DEFINED__ +#define __ITfEditSession_INTERFACE_DEFINED__ + +/* interface ITfEditSession */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfEditSession; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("aa80e803-2021-11d2-93e0-0060b067b86e") + ITfEditSession : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE DoEditSession( + /* [in] */ TfEditCookie ec) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfEditSessionVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfEditSession * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfEditSession * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfEditSession * This); + + HRESULT ( STDMETHODCALLTYPE *DoEditSession )( + ITfEditSession * This, + /* [in] */ TfEditCookie ec); + + END_INTERFACE + } ITfEditSessionVtbl; + + interface ITfEditSession + { + CONST_VTBL struct ITfEditSessionVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfEditSession_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfEditSession_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfEditSession_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfEditSession_DoEditSession(This,ec) \ + ( (This)->lpVtbl -> DoEditSession(This,ec) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfEditSession_INTERFACE_DEFINED__ */ + + +#ifndef __ITfRange_INTERFACE_DEFINED__ +#define __ITfRange_INTERFACE_DEFINED__ + +/* interface ITfRange */ +/* [unique][uuid][object] */ + +#define TF_CHAR_EMBEDDED ( TS_CHAR_EMBEDDED ) + +typedef /* [public][public][public][public][public][uuid] */ DECLSPEC_UUID("cf610f06-2882-46f6-abe5-298568b664c4") +enum __MIDL_ITfRange_0001 + { TF_GRAVITY_BACKWARD = 0, + TF_GRAVITY_FORWARD = 1 + } TfGravity; + +typedef /* [public][public][public][uuid] */ DECLSPEC_UUID("1e512533-bbdc-4530-9a8e-a1dc0af67468") +enum __MIDL_ITfRange_0002 + { TF_SD_BACKWARD = 0, + TF_SD_FORWARD = 1 + } TfShiftDir; + +#define TF_HF_OBJECT ( 1 ) + +#define TF_TF_MOVESTART ( 1 ) + +#define TF_TF_IGNOREEND ( 2 ) + +#define TF_ST_CORRECTION ( 1 ) + +#define TF_IE_CORRECTION ( 1 ) + +typedef /* [uuid] */ DECLSPEC_UUID("49930d51-7d93-448c-a48c-fea5dac192b1") struct TF_HALTCOND + { + ITfRange *pHaltRange; + TfAnchor aHaltPos; + DWORD dwFlags; + } TF_HALTCOND; + + +EXTERN_C const IID IID_ITfRange; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("aa80e7ff-2021-11d2-93e0-0060b067b86e") + ITfRange : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetText( + /* [in] */ TfEditCookie ec, + /* [in] */ DWORD dwFlags, + /* [length_is][size_is][out] */ WCHAR *pchText, + /* [in] */ ULONG cchMax, + /* [out] */ ULONG *pcch) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetText( + /* [in] */ TfEditCookie ec, + /* [in] */ DWORD dwFlags, + /* [unique][size_is][in] */ const WCHAR *pchText, + /* [in] */ LONG cch) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetFormattedText( + /* [in] */ TfEditCookie ec, + /* [out] */ IDataObject **ppDataObject) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetEmbedded( + /* [in] */ TfEditCookie ec, + /* [in] */ REFGUID rguidService, + /* [in] */ REFIID riid, + /* [iid_is][out] */ IUnknown **ppunk) = 0; + + virtual HRESULT STDMETHODCALLTYPE InsertEmbedded( + /* [in] */ TfEditCookie ec, + /* [in] */ DWORD dwFlags, + /* [in] */ IDataObject *pDataObject) = 0; + + virtual HRESULT STDMETHODCALLTYPE ShiftStart( + /* [in] */ TfEditCookie ec, + /* [in] */ LONG cchReq, + /* [out] */ LONG *pcch, + /* [unique][in] */ const TF_HALTCOND *pHalt) = 0; + + virtual HRESULT STDMETHODCALLTYPE ShiftEnd( + /* [in] */ TfEditCookie ec, + /* [in] */ LONG cchReq, + /* [out] */ LONG *pcch, + /* [unique][in] */ const TF_HALTCOND *pHalt) = 0; + + virtual HRESULT STDMETHODCALLTYPE ShiftStartToRange( + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pRange, + /* [in] */ TfAnchor aPos) = 0; + + virtual HRESULT STDMETHODCALLTYPE ShiftEndToRange( + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pRange, + /* [in] */ TfAnchor aPos) = 0; + + virtual HRESULT STDMETHODCALLTYPE ShiftStartRegion( + /* [in] */ TfEditCookie ec, + /* [in] */ TfShiftDir dir, + /* [out] */ BOOL *pfNoRegion) = 0; + + virtual HRESULT STDMETHODCALLTYPE ShiftEndRegion( + /* [in] */ TfEditCookie ec, + /* [in] */ TfShiftDir dir, + /* [out] */ BOOL *pfNoRegion) = 0; + + virtual HRESULT STDMETHODCALLTYPE IsEmpty( + /* [in] */ TfEditCookie ec, + /* [out] */ BOOL *pfEmpty) = 0; + + virtual HRESULT STDMETHODCALLTYPE Collapse( + /* [in] */ TfEditCookie ec, + /* [in] */ TfAnchor aPos) = 0; + + virtual HRESULT STDMETHODCALLTYPE IsEqualStart( + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pWith, + /* [in] */ TfAnchor aPos, + /* [out] */ BOOL *pfEqual) = 0; + + virtual HRESULT STDMETHODCALLTYPE IsEqualEnd( + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pWith, + /* [in] */ TfAnchor aPos, + /* [out] */ BOOL *pfEqual) = 0; + + virtual HRESULT STDMETHODCALLTYPE CompareStart( + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pWith, + /* [in] */ TfAnchor aPos, + /* [out] */ LONG *plResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE CompareEnd( + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pWith, + /* [in] */ TfAnchor aPos, + /* [out] */ LONG *plResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE AdjustForInsert( + /* [in] */ TfEditCookie ec, + /* [in] */ ULONG cchInsert, + /* [out] */ BOOL *pfInsertOk) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetGravity( + /* [out] */ TfGravity *pgStart, + /* [out] */ TfGravity *pgEnd) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetGravity( + /* [in] */ TfEditCookie ec, + /* [in] */ TfGravity gStart, + /* [in] */ TfGravity gEnd) = 0; + + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ ITfRange **ppClone) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetContext( + /* [out] */ ITfContext **ppContext) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfRangeVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfRange * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfRange * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfRange * This); + + HRESULT ( STDMETHODCALLTYPE *GetText )( + ITfRange * This, + /* [in] */ TfEditCookie ec, + /* [in] */ DWORD dwFlags, + /* [length_is][size_is][out] */ __RPC__out_ecount_part(cchMax, *pcch) WCHAR *pchText, + /* [in] */ ULONG cchMax, + /* [out] */ ULONG *pcch); + + HRESULT ( STDMETHODCALLTYPE *SetText )( + ITfRange * This, + /* [in] */ TfEditCookie ec, + /* [in] */ DWORD dwFlags, + /* [unique][size_is][in] */ const WCHAR *pchText, + /* [in] */ LONG cch); + + HRESULT ( STDMETHODCALLTYPE *GetFormattedText )( + ITfRange * This, + /* [in] */ TfEditCookie ec, + /* [out] */ IDataObject **ppDataObject); + + HRESULT ( STDMETHODCALLTYPE *GetEmbedded )( + ITfRange * This, + /* [in] */ TfEditCookie ec, + /* [in] */ REFGUID rguidService, + /* [in] */ REFIID riid, + /* [iid_is][out] */ IUnknown **ppunk); + + HRESULT ( STDMETHODCALLTYPE *InsertEmbedded )( + ITfRange * This, + /* [in] */ TfEditCookie ec, + /* [in] */ DWORD dwFlags, + /* [in] */ IDataObject *pDataObject); + + HRESULT ( STDMETHODCALLTYPE *ShiftStart )( + ITfRange * This, + /* [in] */ TfEditCookie ec, + /* [in] */ LONG cchReq, + /* [out] */ LONG *pcch, + /* [unique][in] */ const TF_HALTCOND *pHalt); + + HRESULT ( STDMETHODCALLTYPE *ShiftEnd )( + ITfRange * This, + /* [in] */ TfEditCookie ec, + /* [in] */ LONG cchReq, + /* [out] */ LONG *pcch, + /* [unique][in] */ const TF_HALTCOND *pHalt); + + HRESULT ( STDMETHODCALLTYPE *ShiftStartToRange )( + ITfRange * This, + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pRange, + /* [in] */ TfAnchor aPos); + + HRESULT ( STDMETHODCALLTYPE *ShiftEndToRange )( + ITfRange * This, + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pRange, + /* [in] */ TfAnchor aPos); + + HRESULT ( STDMETHODCALLTYPE *ShiftStartRegion )( + ITfRange * This, + /* [in] */ TfEditCookie ec, + /* [in] */ TfShiftDir dir, + /* [out] */ BOOL *pfNoRegion); + + HRESULT ( STDMETHODCALLTYPE *ShiftEndRegion )( + ITfRange * This, + /* [in] */ TfEditCookie ec, + /* [in] */ TfShiftDir dir, + /* [out] */ BOOL *pfNoRegion); + + HRESULT ( STDMETHODCALLTYPE *IsEmpty )( + ITfRange * This, + /* [in] */ TfEditCookie ec, + /* [out] */ BOOL *pfEmpty); + + HRESULT ( STDMETHODCALLTYPE *Collapse )( + ITfRange * This, + /* [in] */ TfEditCookie ec, + /* [in] */ TfAnchor aPos); + + HRESULT ( STDMETHODCALLTYPE *IsEqualStart )( + ITfRange * This, + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pWith, + /* [in] */ TfAnchor aPos, + /* [out] */ BOOL *pfEqual); + + HRESULT ( STDMETHODCALLTYPE *IsEqualEnd )( + ITfRange * This, + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pWith, + /* [in] */ TfAnchor aPos, + /* [out] */ BOOL *pfEqual); + + HRESULT ( STDMETHODCALLTYPE *CompareStart )( + ITfRange * This, + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pWith, + /* [in] */ TfAnchor aPos, + /* [out] */ LONG *plResult); + + HRESULT ( STDMETHODCALLTYPE *CompareEnd )( + ITfRange * This, + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pWith, + /* [in] */ TfAnchor aPos, + /* [out] */ LONG *plResult); + + HRESULT ( STDMETHODCALLTYPE *AdjustForInsert )( + ITfRange * This, + /* [in] */ TfEditCookie ec, + /* [in] */ ULONG cchInsert, + /* [out] */ BOOL *pfInsertOk); + + HRESULT ( STDMETHODCALLTYPE *GetGravity )( + ITfRange * This, + /* [out] */ TfGravity *pgStart, + /* [out] */ TfGravity *pgEnd); + + HRESULT ( STDMETHODCALLTYPE *SetGravity )( + ITfRange * This, + /* [in] */ TfEditCookie ec, + /* [in] */ TfGravity gStart, + /* [in] */ TfGravity gEnd); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + ITfRange * This, + /* [out] */ ITfRange **ppClone); + + HRESULT ( STDMETHODCALLTYPE *GetContext )( + ITfRange * This, + /* [out] */ ITfContext **ppContext); + + END_INTERFACE + } ITfRangeVtbl; + + interface ITfRange + { + CONST_VTBL struct ITfRangeVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfRange_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfRange_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfRange_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfRange_GetText(This,ec,dwFlags,pchText,cchMax,pcch) \ + ( (This)->lpVtbl -> GetText(This,ec,dwFlags,pchText,cchMax,pcch) ) + +#define ITfRange_SetText(This,ec,dwFlags,pchText,cch) \ + ( (This)->lpVtbl -> SetText(This,ec,dwFlags,pchText,cch) ) + +#define ITfRange_GetFormattedText(This,ec,ppDataObject) \ + ( (This)->lpVtbl -> GetFormattedText(This,ec,ppDataObject) ) + +#define ITfRange_GetEmbedded(This,ec,rguidService,riid,ppunk) \ + ( (This)->lpVtbl -> GetEmbedded(This,ec,rguidService,riid,ppunk) ) + +#define ITfRange_InsertEmbedded(This,ec,dwFlags,pDataObject) \ + ( (This)->lpVtbl -> InsertEmbedded(This,ec,dwFlags,pDataObject) ) + +#define ITfRange_ShiftStart(This,ec,cchReq,pcch,pHalt) \ + ( (This)->lpVtbl -> ShiftStart(This,ec,cchReq,pcch,pHalt) ) + +#define ITfRange_ShiftEnd(This,ec,cchReq,pcch,pHalt) \ + ( (This)->lpVtbl -> ShiftEnd(This,ec,cchReq,pcch,pHalt) ) + +#define ITfRange_ShiftStartToRange(This,ec,pRange,aPos) \ + ( (This)->lpVtbl -> ShiftStartToRange(This,ec,pRange,aPos) ) + +#define ITfRange_ShiftEndToRange(This,ec,pRange,aPos) \ + ( (This)->lpVtbl -> ShiftEndToRange(This,ec,pRange,aPos) ) + +#define ITfRange_ShiftStartRegion(This,ec,dir,pfNoRegion) \ + ( (This)->lpVtbl -> ShiftStartRegion(This,ec,dir,pfNoRegion) ) + +#define ITfRange_ShiftEndRegion(This,ec,dir,pfNoRegion) \ + ( (This)->lpVtbl -> ShiftEndRegion(This,ec,dir,pfNoRegion) ) + +#define ITfRange_IsEmpty(This,ec,pfEmpty) \ + ( (This)->lpVtbl -> IsEmpty(This,ec,pfEmpty) ) + +#define ITfRange_Collapse(This,ec,aPos) \ + ( (This)->lpVtbl -> Collapse(This,ec,aPos) ) + +#define ITfRange_IsEqualStart(This,ec,pWith,aPos,pfEqual) \ + ( (This)->lpVtbl -> IsEqualStart(This,ec,pWith,aPos,pfEqual) ) + +#define ITfRange_IsEqualEnd(This,ec,pWith,aPos,pfEqual) \ + ( (This)->lpVtbl -> IsEqualEnd(This,ec,pWith,aPos,pfEqual) ) + +#define ITfRange_CompareStart(This,ec,pWith,aPos,plResult) \ + ( (This)->lpVtbl -> CompareStart(This,ec,pWith,aPos,plResult) ) + +#define ITfRange_CompareEnd(This,ec,pWith,aPos,plResult) \ + ( (This)->lpVtbl -> CompareEnd(This,ec,pWith,aPos,plResult) ) + +#define ITfRange_AdjustForInsert(This,ec,cchInsert,pfInsertOk) \ + ( (This)->lpVtbl -> AdjustForInsert(This,ec,cchInsert,pfInsertOk) ) + +#define ITfRange_GetGravity(This,pgStart,pgEnd) \ + ( (This)->lpVtbl -> GetGravity(This,pgStart,pgEnd) ) + +#define ITfRange_SetGravity(This,ec,gStart,gEnd) \ + ( (This)->lpVtbl -> SetGravity(This,ec,gStart,gEnd) ) + +#define ITfRange_Clone(This,ppClone) \ + ( (This)->lpVtbl -> Clone(This,ppClone) ) + +#define ITfRange_GetContext(This,ppContext) \ + ( (This)->lpVtbl -> GetContext(This,ppContext) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfRange_INTERFACE_DEFINED__ */ + + +#ifndef __ITfRangeACP_INTERFACE_DEFINED__ +#define __ITfRangeACP_INTERFACE_DEFINED__ + +/* interface ITfRangeACP */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfRangeACP; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("057a6296-029b-4154-b79a-0d461d4ea94c") + ITfRangeACP : public ITfRange + { + public: + virtual HRESULT STDMETHODCALLTYPE GetExtent( + /* [out] */ LONG *pacpAnchor, + /* [out] */ LONG *pcch) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetExtent( + /* [in] */ LONG acpAnchor, + /* [in] */ LONG cch) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfRangeACPVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfRangeACP * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfRangeACP * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfRangeACP * This); + + HRESULT ( STDMETHODCALLTYPE *GetText )( + ITfRangeACP * This, + /* [in] */ TfEditCookie ec, + /* [in] */ DWORD dwFlags, + /* [length_is][size_is][out] */ __RPC__out_ecount_part(cchMax, *pcch) WCHAR *pchText, + /* [in] */ ULONG cchMax, + /* [out] */ ULONG *pcch); + + HRESULT ( STDMETHODCALLTYPE *SetText )( + ITfRangeACP * This, + /* [in] */ TfEditCookie ec, + /* [in] */ DWORD dwFlags, + /* [unique][size_is][in] */ const WCHAR *pchText, + /* [in] */ LONG cch); + + HRESULT ( STDMETHODCALLTYPE *GetFormattedText )( + ITfRangeACP * This, + /* [in] */ TfEditCookie ec, + /* [out] */ IDataObject **ppDataObject); + + HRESULT ( STDMETHODCALLTYPE *GetEmbedded )( + ITfRangeACP * This, + /* [in] */ TfEditCookie ec, + /* [in] */ REFGUID rguidService, + /* [in] */ REFIID riid, + /* [iid_is][out] */ IUnknown **ppunk); + + HRESULT ( STDMETHODCALLTYPE *InsertEmbedded )( + ITfRangeACP * This, + /* [in] */ TfEditCookie ec, + /* [in] */ DWORD dwFlags, + /* [in] */ IDataObject *pDataObject); + + HRESULT ( STDMETHODCALLTYPE *ShiftStart )( + ITfRangeACP * This, + /* [in] */ TfEditCookie ec, + /* [in] */ LONG cchReq, + /* [out] */ LONG *pcch, + /* [unique][in] */ const TF_HALTCOND *pHalt); + + HRESULT ( STDMETHODCALLTYPE *ShiftEnd )( + ITfRangeACP * This, + /* [in] */ TfEditCookie ec, + /* [in] */ LONG cchReq, + /* [out] */ LONG *pcch, + /* [unique][in] */ const TF_HALTCOND *pHalt); + + HRESULT ( STDMETHODCALLTYPE *ShiftStartToRange )( + ITfRangeACP * This, + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pRange, + /* [in] */ TfAnchor aPos); + + HRESULT ( STDMETHODCALLTYPE *ShiftEndToRange )( + ITfRangeACP * This, + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pRange, + /* [in] */ TfAnchor aPos); + + HRESULT ( STDMETHODCALLTYPE *ShiftStartRegion )( + ITfRangeACP * This, + /* [in] */ TfEditCookie ec, + /* [in] */ TfShiftDir dir, + /* [out] */ BOOL *pfNoRegion); + + HRESULT ( STDMETHODCALLTYPE *ShiftEndRegion )( + ITfRangeACP * This, + /* [in] */ TfEditCookie ec, + /* [in] */ TfShiftDir dir, + /* [out] */ BOOL *pfNoRegion); + + HRESULT ( STDMETHODCALLTYPE *IsEmpty )( + ITfRangeACP * This, + /* [in] */ TfEditCookie ec, + /* [out] */ BOOL *pfEmpty); + + HRESULT ( STDMETHODCALLTYPE *Collapse )( + ITfRangeACP * This, + /* [in] */ TfEditCookie ec, + /* [in] */ TfAnchor aPos); + + HRESULT ( STDMETHODCALLTYPE *IsEqualStart )( + ITfRangeACP * This, + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pWith, + /* [in] */ TfAnchor aPos, + /* [out] */ BOOL *pfEqual); + + HRESULT ( STDMETHODCALLTYPE *IsEqualEnd )( + ITfRangeACP * This, + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pWith, + /* [in] */ TfAnchor aPos, + /* [out] */ BOOL *pfEqual); + + HRESULT ( STDMETHODCALLTYPE *CompareStart )( + ITfRangeACP * This, + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pWith, + /* [in] */ TfAnchor aPos, + /* [out] */ LONG *plResult); + + HRESULT ( STDMETHODCALLTYPE *CompareEnd )( + ITfRangeACP * This, + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pWith, + /* [in] */ TfAnchor aPos, + /* [out] */ LONG *plResult); + + HRESULT ( STDMETHODCALLTYPE *AdjustForInsert )( + ITfRangeACP * This, + /* [in] */ TfEditCookie ec, + /* [in] */ ULONG cchInsert, + /* [out] */ BOOL *pfInsertOk); + + HRESULT ( STDMETHODCALLTYPE *GetGravity )( + ITfRangeACP * This, + /* [out] */ TfGravity *pgStart, + /* [out] */ TfGravity *pgEnd); + + HRESULT ( STDMETHODCALLTYPE *SetGravity )( + ITfRangeACP * This, + /* [in] */ TfEditCookie ec, + /* [in] */ TfGravity gStart, + /* [in] */ TfGravity gEnd); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + ITfRangeACP * This, + /* [out] */ ITfRange **ppClone); + + HRESULT ( STDMETHODCALLTYPE *GetContext )( + ITfRangeACP * This, + /* [out] */ ITfContext **ppContext); + + HRESULT ( STDMETHODCALLTYPE *GetExtent )( + ITfRangeACP * This, + /* [out] */ LONG *pacpAnchor, + /* [out] */ LONG *pcch); + + HRESULT ( STDMETHODCALLTYPE *SetExtent )( + ITfRangeACP * This, + /* [in] */ LONG acpAnchor, + /* [in] */ LONG cch); + + END_INTERFACE + } ITfRangeACPVtbl; + + interface ITfRangeACP + { + CONST_VTBL struct ITfRangeACPVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfRangeACP_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfRangeACP_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfRangeACP_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfRangeACP_GetText(This,ec,dwFlags,pchText,cchMax,pcch) \ + ( (This)->lpVtbl -> GetText(This,ec,dwFlags,pchText,cchMax,pcch) ) + +#define ITfRangeACP_SetText(This,ec,dwFlags,pchText,cch) \ + ( (This)->lpVtbl -> SetText(This,ec,dwFlags,pchText,cch) ) + +#define ITfRangeACP_GetFormattedText(This,ec,ppDataObject) \ + ( (This)->lpVtbl -> GetFormattedText(This,ec,ppDataObject) ) + +#define ITfRangeACP_GetEmbedded(This,ec,rguidService,riid,ppunk) \ + ( (This)->lpVtbl -> GetEmbedded(This,ec,rguidService,riid,ppunk) ) + +#define ITfRangeACP_InsertEmbedded(This,ec,dwFlags,pDataObject) \ + ( (This)->lpVtbl -> InsertEmbedded(This,ec,dwFlags,pDataObject) ) + +#define ITfRangeACP_ShiftStart(This,ec,cchReq,pcch,pHalt) \ + ( (This)->lpVtbl -> ShiftStart(This,ec,cchReq,pcch,pHalt) ) + +#define ITfRangeACP_ShiftEnd(This,ec,cchReq,pcch,pHalt) \ + ( (This)->lpVtbl -> ShiftEnd(This,ec,cchReq,pcch,pHalt) ) + +#define ITfRangeACP_ShiftStartToRange(This,ec,pRange,aPos) \ + ( (This)->lpVtbl -> ShiftStartToRange(This,ec,pRange,aPos) ) + +#define ITfRangeACP_ShiftEndToRange(This,ec,pRange,aPos) \ + ( (This)->lpVtbl -> ShiftEndToRange(This,ec,pRange,aPos) ) + +#define ITfRangeACP_ShiftStartRegion(This,ec,dir,pfNoRegion) \ + ( (This)->lpVtbl -> ShiftStartRegion(This,ec,dir,pfNoRegion) ) + +#define ITfRangeACP_ShiftEndRegion(This,ec,dir,pfNoRegion) \ + ( (This)->lpVtbl -> ShiftEndRegion(This,ec,dir,pfNoRegion) ) + +#define ITfRangeACP_IsEmpty(This,ec,pfEmpty) \ + ( (This)->lpVtbl -> IsEmpty(This,ec,pfEmpty) ) + +#define ITfRangeACP_Collapse(This,ec,aPos) \ + ( (This)->lpVtbl -> Collapse(This,ec,aPos) ) + +#define ITfRangeACP_IsEqualStart(This,ec,pWith,aPos,pfEqual) \ + ( (This)->lpVtbl -> IsEqualStart(This,ec,pWith,aPos,pfEqual) ) + +#define ITfRangeACP_IsEqualEnd(This,ec,pWith,aPos,pfEqual) \ + ( (This)->lpVtbl -> IsEqualEnd(This,ec,pWith,aPos,pfEqual) ) + +#define ITfRangeACP_CompareStart(This,ec,pWith,aPos,plResult) \ + ( (This)->lpVtbl -> CompareStart(This,ec,pWith,aPos,plResult) ) + +#define ITfRangeACP_CompareEnd(This,ec,pWith,aPos,plResult) \ + ( (This)->lpVtbl -> CompareEnd(This,ec,pWith,aPos,plResult) ) + +#define ITfRangeACP_AdjustForInsert(This,ec,cchInsert,pfInsertOk) \ + ( (This)->lpVtbl -> AdjustForInsert(This,ec,cchInsert,pfInsertOk) ) + +#define ITfRangeACP_GetGravity(This,pgStart,pgEnd) \ + ( (This)->lpVtbl -> GetGravity(This,pgStart,pgEnd) ) + +#define ITfRangeACP_SetGravity(This,ec,gStart,gEnd) \ + ( (This)->lpVtbl -> SetGravity(This,ec,gStart,gEnd) ) + +#define ITfRangeACP_Clone(This,ppClone) \ + ( (This)->lpVtbl -> Clone(This,ppClone) ) + +#define ITfRangeACP_GetContext(This,ppContext) \ + ( (This)->lpVtbl -> GetContext(This,ppContext) ) + + +#define ITfRangeACP_GetExtent(This,pacpAnchor,pcch) \ + ( (This)->lpVtbl -> GetExtent(This,pacpAnchor,pcch) ) + +#define ITfRangeACP_SetExtent(This,acpAnchor,cch) \ + ( (This)->lpVtbl -> SetExtent(This,acpAnchor,cch) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfRangeACP_INTERFACE_DEFINED__ */ + + +#ifndef __ITextStoreACPServices_INTERFACE_DEFINED__ +#define __ITextStoreACPServices_INTERFACE_DEFINED__ + +/* interface ITextStoreACPServices */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITextStoreACPServices; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("aa80e901-2021-11d2-93e0-0060b067b86e") + ITextStoreACPServices : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Serialize( + /* [in] */ ITfProperty *pProp, + /* [in] */ ITfRange *pRange, + /* [out] */ TF_PERSISTENT_PROPERTY_HEADER_ACP *pHdr, + /* [in] */ IStream *pStream) = 0; + + virtual HRESULT STDMETHODCALLTYPE Unserialize( + /* [in] */ ITfProperty *pProp, + /* [in] */ const TF_PERSISTENT_PROPERTY_HEADER_ACP *pHdr, + /* [in] */ IStream *pStream, + /* [in] */ ITfPersistentPropertyLoaderACP *pLoader) = 0; + + virtual HRESULT STDMETHODCALLTYPE ForceLoadProperty( + /* [in] */ ITfProperty *pProp) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateRange( + /* [in] */ LONG acpStart, + /* [in] */ LONG acpEnd, + /* [out] */ ITfRangeACP **ppRange) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITextStoreACPServicesVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITextStoreACPServices * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITextStoreACPServices * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITextStoreACPServices * This); + + HRESULT ( STDMETHODCALLTYPE *Serialize )( + ITextStoreACPServices * This, + /* [in] */ ITfProperty *pProp, + /* [in] */ ITfRange *pRange, + /* [out] */ TF_PERSISTENT_PROPERTY_HEADER_ACP *pHdr, + /* [in] */ IStream *pStream); + + HRESULT ( STDMETHODCALLTYPE *Unserialize )( + ITextStoreACPServices * This, + /* [in] */ ITfProperty *pProp, + /* [in] */ const TF_PERSISTENT_PROPERTY_HEADER_ACP *pHdr, + /* [in] */ IStream *pStream, + /* [in] */ ITfPersistentPropertyLoaderACP *pLoader); + + HRESULT ( STDMETHODCALLTYPE *ForceLoadProperty )( + ITextStoreACPServices * This, + /* [in] */ ITfProperty *pProp); + + HRESULT ( STDMETHODCALLTYPE *CreateRange )( + ITextStoreACPServices * This, + /* [in] */ LONG acpStart, + /* [in] */ LONG acpEnd, + /* [out] */ ITfRangeACP **ppRange); + + END_INTERFACE + } ITextStoreACPServicesVtbl; + + interface ITextStoreACPServices + { + CONST_VTBL struct ITextStoreACPServicesVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITextStoreACPServices_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITextStoreACPServices_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITextStoreACPServices_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITextStoreACPServices_Serialize(This,pProp,pRange,pHdr,pStream) \ + ( (This)->lpVtbl -> Serialize(This,pProp,pRange,pHdr,pStream) ) + +#define ITextStoreACPServices_Unserialize(This,pProp,pHdr,pStream,pLoader) \ + ( (This)->lpVtbl -> Unserialize(This,pProp,pHdr,pStream,pLoader) ) + +#define ITextStoreACPServices_ForceLoadProperty(This,pProp) \ + ( (This)->lpVtbl -> ForceLoadProperty(This,pProp) ) + +#define ITextStoreACPServices_CreateRange(This,acpStart,acpEnd,ppRange) \ + ( (This)->lpVtbl -> CreateRange(This,acpStart,acpEnd,ppRange) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITextStoreACPServices_INTERFACE_DEFINED__ */ + + +#ifndef __ITfRangeBackup_INTERFACE_DEFINED__ +#define __ITfRangeBackup_INTERFACE_DEFINED__ + +/* interface ITfRangeBackup */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfRangeBackup; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("463a506d-6992-49d2-9b88-93d55e70bb16") + ITfRangeBackup : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Restore( + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pRange) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfRangeBackupVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfRangeBackup * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfRangeBackup * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfRangeBackup * This); + + HRESULT ( STDMETHODCALLTYPE *Restore )( + ITfRangeBackup * This, + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pRange); + + END_INTERFACE + } ITfRangeBackupVtbl; + + interface ITfRangeBackup + { + CONST_VTBL struct ITfRangeBackupVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfRangeBackup_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfRangeBackup_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfRangeBackup_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfRangeBackup_Restore(This,ec,pRange) \ + ( (This)->lpVtbl -> Restore(This,ec,pRange) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfRangeBackup_INTERFACE_DEFINED__ */ + + +#ifndef __ITfPropertyStore_INTERFACE_DEFINED__ +#define __ITfPropertyStore_INTERFACE_DEFINED__ + +/* interface ITfPropertyStore */ +/* [unique][uuid][object] */ + +#define TF_TU_CORRECTION ( 0x1 ) + + +EXTERN_C const IID IID_ITfPropertyStore; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("6834b120-88cb-11d2-bf45-00105a2799b5") + ITfPropertyStore : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetType( + /* [out] */ GUID *pguid) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDataType( + /* [out] */ DWORD *pdwReserved) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetData( + /* [out] */ VARIANT *pvarValue) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnTextUpdated( + /* [in] */ DWORD dwFlags, + /* [in] */ ITfRange *pRangeNew, + /* [out] */ BOOL *pfAccept) = 0; + + virtual HRESULT STDMETHODCALLTYPE Shrink( + /* [in] */ ITfRange *pRangeNew, + /* [out] */ BOOL *pfFree) = 0; + + virtual HRESULT STDMETHODCALLTYPE Divide( + /* [in] */ ITfRange *pRangeThis, + /* [in] */ ITfRange *pRangeNew, + /* [out] */ ITfPropertyStore **ppPropStore) = 0; + + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ ITfPropertyStore **pPropStore) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetPropertyRangeCreator( + /* [out] */ CLSID *pclsid) = 0; + + virtual HRESULT STDMETHODCALLTYPE Serialize( + /* [in] */ IStream *pStream, + /* [out] */ ULONG *pcb) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfPropertyStoreVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfPropertyStore * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfPropertyStore * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfPropertyStore * This); + + HRESULT ( STDMETHODCALLTYPE *GetType )( + ITfPropertyStore * This, + /* [out] */ GUID *pguid); + + HRESULT ( STDMETHODCALLTYPE *GetDataType )( + ITfPropertyStore * This, + /* [out] */ DWORD *pdwReserved); + + HRESULT ( STDMETHODCALLTYPE *GetData )( + ITfPropertyStore * This, + /* [out] */ VARIANT *pvarValue); + + HRESULT ( STDMETHODCALLTYPE *OnTextUpdated )( + ITfPropertyStore * This, + /* [in] */ DWORD dwFlags, + /* [in] */ ITfRange *pRangeNew, + /* [out] */ BOOL *pfAccept); + + HRESULT ( STDMETHODCALLTYPE *Shrink )( + ITfPropertyStore * This, + /* [in] */ ITfRange *pRangeNew, + /* [out] */ BOOL *pfFree); + + HRESULT ( STDMETHODCALLTYPE *Divide )( + ITfPropertyStore * This, + /* [in] */ ITfRange *pRangeThis, + /* [in] */ ITfRange *pRangeNew, + /* [out] */ ITfPropertyStore **ppPropStore); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + ITfPropertyStore * This, + /* [out] */ ITfPropertyStore **pPropStore); + + HRESULT ( STDMETHODCALLTYPE *GetPropertyRangeCreator )( + ITfPropertyStore * This, + /* [out] */ CLSID *pclsid); + + HRESULT ( STDMETHODCALLTYPE *Serialize )( + ITfPropertyStore * This, + /* [in] */ IStream *pStream, + /* [out] */ ULONG *pcb); + + END_INTERFACE + } ITfPropertyStoreVtbl; + + interface ITfPropertyStore + { + CONST_VTBL struct ITfPropertyStoreVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfPropertyStore_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfPropertyStore_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfPropertyStore_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfPropertyStore_GetType(This,pguid) \ + ( (This)->lpVtbl -> GetType(This,pguid) ) + +#define ITfPropertyStore_GetDataType(This,pdwReserved) \ + ( (This)->lpVtbl -> GetDataType(This,pdwReserved) ) + +#define ITfPropertyStore_GetData(This,pvarValue) \ + ( (This)->lpVtbl -> GetData(This,pvarValue) ) + +#define ITfPropertyStore_OnTextUpdated(This,dwFlags,pRangeNew,pfAccept) \ + ( (This)->lpVtbl -> OnTextUpdated(This,dwFlags,pRangeNew,pfAccept) ) + +#define ITfPropertyStore_Shrink(This,pRangeNew,pfFree) \ + ( (This)->lpVtbl -> Shrink(This,pRangeNew,pfFree) ) + +#define ITfPropertyStore_Divide(This,pRangeThis,pRangeNew,ppPropStore) \ + ( (This)->lpVtbl -> Divide(This,pRangeThis,pRangeNew,ppPropStore) ) + +#define ITfPropertyStore_Clone(This,pPropStore) \ + ( (This)->lpVtbl -> Clone(This,pPropStore) ) + +#define ITfPropertyStore_GetPropertyRangeCreator(This,pclsid) \ + ( (This)->lpVtbl -> GetPropertyRangeCreator(This,pclsid) ) + +#define ITfPropertyStore_Serialize(This,pStream,pcb) \ + ( (This)->lpVtbl -> Serialize(This,pStream,pcb) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfPropertyStore_INTERFACE_DEFINED__ */ + + +#ifndef __IEnumTfRanges_INTERFACE_DEFINED__ +#define __IEnumTfRanges_INTERFACE_DEFINED__ + +/* interface IEnumTfRanges */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_IEnumTfRanges; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("f99d3f40-8e32-11d2-bf46-00105a2799b5") + IEnumTfRanges : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ IEnumTfRanges **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ ITfRange **ppRange, + /* [out] */ ULONG *pcFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + ULONG ulCount) = 0; + + }; + +#else /* C style interface */ + + typedef struct IEnumTfRangesVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IEnumTfRanges * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IEnumTfRanges * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IEnumTfRanges * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IEnumTfRanges * This, + /* [out] */ IEnumTfRanges **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IEnumTfRanges * This, + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ ITfRange **ppRange, + /* [out] */ ULONG *pcFetched); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IEnumTfRanges * This); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + IEnumTfRanges * This, + ULONG ulCount); + + END_INTERFACE + } IEnumTfRangesVtbl; + + interface IEnumTfRanges + { + CONST_VTBL struct IEnumTfRangesVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IEnumTfRanges_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IEnumTfRanges_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IEnumTfRanges_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IEnumTfRanges_Clone(This,ppEnum) \ + ( (This)->lpVtbl -> Clone(This,ppEnum) ) + +#define IEnumTfRanges_Next(This,ulCount,ppRange,pcFetched) \ + ( (This)->lpVtbl -> Next(This,ulCount,ppRange,pcFetched) ) + +#define IEnumTfRanges_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define IEnumTfRanges_Skip(This,ulCount) \ + ( (This)->lpVtbl -> Skip(This,ulCount) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IEnumTfRanges_INTERFACE_DEFINED__ */ + + +#ifndef __ITfCreatePropertyStore_INTERFACE_DEFINED__ +#define __ITfCreatePropertyStore_INTERFACE_DEFINED__ + +/* interface ITfCreatePropertyStore */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfCreatePropertyStore; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("2463fbf0-b0af-11d2-afc5-00105a2799b5") + ITfCreatePropertyStore : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE IsStoreSerializable( + /* [in] */ REFGUID guidProp, + /* [in] */ ITfRange *pRange, + /* [in] */ ITfPropertyStore *pPropStore, + /* [out] */ BOOL *pfSerializable) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreatePropertyStore( + /* [in] */ REFGUID guidProp, + /* [in] */ ITfRange *pRange, + /* [in] */ ULONG cb, + /* [in] */ IStream *pStream, + /* [out] */ ITfPropertyStore **ppStore) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfCreatePropertyStoreVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfCreatePropertyStore * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfCreatePropertyStore * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfCreatePropertyStore * This); + + HRESULT ( STDMETHODCALLTYPE *IsStoreSerializable )( + ITfCreatePropertyStore * This, + /* [in] */ REFGUID guidProp, + /* [in] */ ITfRange *pRange, + /* [in] */ ITfPropertyStore *pPropStore, + /* [out] */ BOOL *pfSerializable); + + HRESULT ( STDMETHODCALLTYPE *CreatePropertyStore )( + ITfCreatePropertyStore * This, + /* [in] */ REFGUID guidProp, + /* [in] */ ITfRange *pRange, + /* [in] */ ULONG cb, + /* [in] */ IStream *pStream, + /* [out] */ ITfPropertyStore **ppStore); + + END_INTERFACE + } ITfCreatePropertyStoreVtbl; + + interface ITfCreatePropertyStore + { + CONST_VTBL struct ITfCreatePropertyStoreVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfCreatePropertyStore_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfCreatePropertyStore_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfCreatePropertyStore_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfCreatePropertyStore_IsStoreSerializable(This,guidProp,pRange,pPropStore,pfSerializable) \ + ( (This)->lpVtbl -> IsStoreSerializable(This,guidProp,pRange,pPropStore,pfSerializable) ) + +#define ITfCreatePropertyStore_CreatePropertyStore(This,guidProp,pRange,cb,pStream,ppStore) \ + ( (This)->lpVtbl -> CreatePropertyStore(This,guidProp,pRange,cb,pStream,ppStore) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfCreatePropertyStore_INTERFACE_DEFINED__ */ + + +#ifndef __ITfPersistentPropertyLoaderACP_INTERFACE_DEFINED__ +#define __ITfPersistentPropertyLoaderACP_INTERFACE_DEFINED__ + +/* interface ITfPersistentPropertyLoaderACP */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfPersistentPropertyLoaderACP; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("4ef89150-0807-11d3-8df0-00105a2799b5") + ITfPersistentPropertyLoaderACP : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE LoadProperty( + /* [in] */ const TF_PERSISTENT_PROPERTY_HEADER_ACP *pHdr, + /* [out] */ IStream **ppStream) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfPersistentPropertyLoaderACPVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfPersistentPropertyLoaderACP * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfPersistentPropertyLoaderACP * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfPersistentPropertyLoaderACP * This); + + HRESULT ( STDMETHODCALLTYPE *LoadProperty )( + ITfPersistentPropertyLoaderACP * This, + /* [in] */ const TF_PERSISTENT_PROPERTY_HEADER_ACP *pHdr, + /* [out] */ IStream **ppStream); + + END_INTERFACE + } ITfPersistentPropertyLoaderACPVtbl; + + interface ITfPersistentPropertyLoaderACP + { + CONST_VTBL struct ITfPersistentPropertyLoaderACPVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfPersistentPropertyLoaderACP_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfPersistentPropertyLoaderACP_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfPersistentPropertyLoaderACP_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfPersistentPropertyLoaderACP_LoadProperty(This,pHdr,ppStream) \ + ( (This)->lpVtbl -> LoadProperty(This,pHdr,ppStream) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfPersistentPropertyLoaderACP_INTERFACE_DEFINED__ */ + + +#ifndef __ITfProperty_INTERFACE_DEFINED__ +#define __ITfProperty_INTERFACE_DEFINED__ + +/* interface ITfProperty */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfProperty; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("e2449660-9542-11d2-bf46-00105a2799b5") + ITfProperty : public ITfReadOnlyProperty + { + public: + virtual HRESULT STDMETHODCALLTYPE FindRange( + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pRange, + /* [out] */ ITfRange **ppRange, + /* [in] */ TfAnchor aPos) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetValueStore( + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pRange, + /* [in] */ ITfPropertyStore *pPropStore) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetValue( + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pRange, + /* [in] */ const VARIANT *pvarValue) = 0; + + virtual HRESULT STDMETHODCALLTYPE Clear( + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pRange) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfPropertyVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfProperty * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfProperty * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfProperty * This); + + HRESULT ( STDMETHODCALLTYPE *GetType )( + ITfProperty * This, + /* [out] */ GUID *pguid); + + HRESULT ( STDMETHODCALLTYPE *EnumRanges )( + ITfProperty * This, + /* [in] */ TfEditCookie ec, + /* [out] */ IEnumTfRanges **ppEnum, + /* [in] */ ITfRange *pTargetRange); + + HRESULT ( STDMETHODCALLTYPE *GetValue )( + ITfProperty * This, + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pRange, + /* [out] */ VARIANT *pvarValue); + + HRESULT ( STDMETHODCALLTYPE *GetContext )( + ITfProperty * This, + /* [out] */ ITfContext **ppContext); + + HRESULT ( STDMETHODCALLTYPE *FindRange )( + ITfProperty * This, + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pRange, + /* [out] */ ITfRange **ppRange, + /* [in] */ TfAnchor aPos); + + HRESULT ( STDMETHODCALLTYPE *SetValueStore )( + ITfProperty * This, + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pRange, + /* [in] */ ITfPropertyStore *pPropStore); + + HRESULT ( STDMETHODCALLTYPE *SetValue )( + ITfProperty * This, + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pRange, + /* [in] */ const VARIANT *pvarValue); + + HRESULT ( STDMETHODCALLTYPE *Clear )( + ITfProperty * This, + /* [in] */ TfEditCookie ec, + /* [in] */ ITfRange *pRange); + + END_INTERFACE + } ITfPropertyVtbl; + + interface ITfProperty + { + CONST_VTBL struct ITfPropertyVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfProperty_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfProperty_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfProperty_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfProperty_GetType(This,pguid) \ + ( (This)->lpVtbl -> GetType(This,pguid) ) + +#define ITfProperty_EnumRanges(This,ec,ppEnum,pTargetRange) \ + ( (This)->lpVtbl -> EnumRanges(This,ec,ppEnum,pTargetRange) ) + +#define ITfProperty_GetValue(This,ec,pRange,pvarValue) \ + ( (This)->lpVtbl -> GetValue(This,ec,pRange,pvarValue) ) + +#define ITfProperty_GetContext(This,ppContext) \ + ( (This)->lpVtbl -> GetContext(This,ppContext) ) + + +#define ITfProperty_FindRange(This,ec,pRange,ppRange,aPos) \ + ( (This)->lpVtbl -> FindRange(This,ec,pRange,ppRange,aPos) ) + +#define ITfProperty_SetValueStore(This,ec,pRange,pPropStore) \ + ( (This)->lpVtbl -> SetValueStore(This,ec,pRange,pPropStore) ) + +#define ITfProperty_SetValue(This,ec,pRange,pvarValue) \ + ( (This)->lpVtbl -> SetValue(This,ec,pRange,pvarValue) ) + +#define ITfProperty_Clear(This,ec,pRange) \ + ( (This)->lpVtbl -> Clear(This,ec,pRange) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfProperty_INTERFACE_DEFINED__ */ + + +#ifndef __IEnumTfProperties_INTERFACE_DEFINED__ +#define __IEnumTfProperties_INTERFACE_DEFINED__ + +/* interface IEnumTfProperties */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_IEnumTfProperties; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("19188cb0-aca9-11d2-afc5-00105a2799b5") + IEnumTfProperties : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ IEnumTfProperties **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ ITfProperty **ppProp, + /* [out] */ ULONG *pcFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG ulCount) = 0; + + }; + +#else /* C style interface */ + + typedef struct IEnumTfPropertiesVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IEnumTfProperties * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IEnumTfProperties * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IEnumTfProperties * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IEnumTfProperties * This, + /* [out] */ IEnumTfProperties **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IEnumTfProperties * This, + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ ITfProperty **ppProp, + /* [out] */ ULONG *pcFetched); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IEnumTfProperties * This); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + IEnumTfProperties * This, + /* [in] */ ULONG ulCount); + + END_INTERFACE + } IEnumTfPropertiesVtbl; + + interface IEnumTfProperties + { + CONST_VTBL struct IEnumTfPropertiesVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IEnumTfProperties_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IEnumTfProperties_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IEnumTfProperties_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IEnumTfProperties_Clone(This,ppEnum) \ + ( (This)->lpVtbl -> Clone(This,ppEnum) ) + +#define IEnumTfProperties_Next(This,ulCount,ppProp,pcFetched) \ + ( (This)->lpVtbl -> Next(This,ulCount,ppProp,pcFetched) ) + +#define IEnumTfProperties_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define IEnumTfProperties_Skip(This,ulCount) \ + ( (This)->lpVtbl -> Skip(This,ulCount) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IEnumTfProperties_INTERFACE_DEFINED__ */ + + +#ifndef __ITfCompartment_INTERFACE_DEFINED__ +#define __ITfCompartment_INTERFACE_DEFINED__ + +/* interface ITfCompartment */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfCompartment; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("bb08f7a9-607a-4384-8623-056892b64371") + ITfCompartment : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE SetValue( + /* [in] */ TfClientId tid, + /* [in] */ const VARIANT *pvarValue) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetValue( + /* [out] */ VARIANT *pvarValue) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfCompartmentVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfCompartment * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfCompartment * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfCompartment * This); + + HRESULT ( STDMETHODCALLTYPE *SetValue )( + ITfCompartment * This, + /* [in] */ TfClientId tid, + /* [in] */ const VARIANT *pvarValue); + + HRESULT ( STDMETHODCALLTYPE *GetValue )( + ITfCompartment * This, + /* [out] */ VARIANT *pvarValue); + + END_INTERFACE + } ITfCompartmentVtbl; + + interface ITfCompartment + { + CONST_VTBL struct ITfCompartmentVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfCompartment_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfCompartment_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfCompartment_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfCompartment_SetValue(This,tid,pvarValue) \ + ( (This)->lpVtbl -> SetValue(This,tid,pvarValue) ) + +#define ITfCompartment_GetValue(This,pvarValue) \ + ( (This)->lpVtbl -> GetValue(This,pvarValue) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfCompartment_INTERFACE_DEFINED__ */ + + +#ifndef __ITfCompartmentEventSink_INTERFACE_DEFINED__ +#define __ITfCompartmentEventSink_INTERFACE_DEFINED__ + +/* interface ITfCompartmentEventSink */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfCompartmentEventSink; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("743abd5f-f26d-48df-8cc5-238492419b64") + ITfCompartmentEventSink : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE OnChange( + /* [in] */ REFGUID rguid) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfCompartmentEventSinkVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfCompartmentEventSink * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfCompartmentEventSink * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfCompartmentEventSink * This); + + HRESULT ( STDMETHODCALLTYPE *OnChange )( + ITfCompartmentEventSink * This, + /* [in] */ REFGUID rguid); + + END_INTERFACE + } ITfCompartmentEventSinkVtbl; + + interface ITfCompartmentEventSink + { + CONST_VTBL struct ITfCompartmentEventSinkVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfCompartmentEventSink_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfCompartmentEventSink_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfCompartmentEventSink_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfCompartmentEventSink_OnChange(This,rguid) \ + ( (This)->lpVtbl -> OnChange(This,rguid) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfCompartmentEventSink_INTERFACE_DEFINED__ */ + + +#ifndef __ITfCompartmentMgr_INTERFACE_DEFINED__ +#define __ITfCompartmentMgr_INTERFACE_DEFINED__ + +/* interface ITfCompartmentMgr */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfCompartmentMgr; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("7dcf57ac-18ad-438b-824d-979bffb74b7c") + ITfCompartmentMgr : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetCompartment( + /* [in] */ REFGUID rguid, + /* [out] */ ITfCompartment **ppcomp) = 0; + + virtual HRESULT STDMETHODCALLTYPE ClearCompartment( + /* [in] */ TfClientId tid, + /* [in] */ REFGUID rguid) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnumCompartments( + /* [out] */ IEnumGUID **ppEnum) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfCompartmentMgrVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfCompartmentMgr * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfCompartmentMgr * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfCompartmentMgr * This); + + HRESULT ( STDMETHODCALLTYPE *GetCompartment )( + ITfCompartmentMgr * This, + /* [in] */ REFGUID rguid, + /* [out] */ ITfCompartment **ppcomp); + + HRESULT ( STDMETHODCALLTYPE *ClearCompartment )( + ITfCompartmentMgr * This, + /* [in] */ TfClientId tid, + /* [in] */ REFGUID rguid); + + HRESULT ( STDMETHODCALLTYPE *EnumCompartments )( + ITfCompartmentMgr * This, + /* [out] */ IEnumGUID **ppEnum); + + END_INTERFACE + } ITfCompartmentMgrVtbl; + + interface ITfCompartmentMgr + { + CONST_VTBL struct ITfCompartmentMgrVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfCompartmentMgr_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfCompartmentMgr_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfCompartmentMgr_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfCompartmentMgr_GetCompartment(This,rguid,ppcomp) \ + ( (This)->lpVtbl -> GetCompartment(This,rguid,ppcomp) ) + +#define ITfCompartmentMgr_ClearCompartment(This,tid,rguid) \ + ( (This)->lpVtbl -> ClearCompartment(This,tid,rguid) ) + +#define ITfCompartmentMgr_EnumCompartments(This,ppEnum) \ + ( (This)->lpVtbl -> EnumCompartments(This,ppEnum) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfCompartmentMgr_INTERFACE_DEFINED__ */ + + +#ifndef __ITfFunction_INTERFACE_DEFINED__ +#define __ITfFunction_INTERFACE_DEFINED__ + +/* interface ITfFunction */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfFunction; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("db593490-098f-11d3-8df0-00105a2799b5") + ITfFunction : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetDisplayName( + /* [out] */ BSTR *pbstrName) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfFunctionVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfFunction * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfFunction * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfFunction * This); + + HRESULT ( STDMETHODCALLTYPE *GetDisplayName )( + ITfFunction * This, + /* [out] */ BSTR *pbstrName); + + END_INTERFACE + } ITfFunctionVtbl; + + interface ITfFunction + { + CONST_VTBL struct ITfFunctionVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfFunction_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfFunction_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfFunction_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfFunction_GetDisplayName(This,pbstrName) \ + ( (This)->lpVtbl -> GetDisplayName(This,pbstrName) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfFunction_INTERFACE_DEFINED__ */ + + +#ifndef __ITfFunctionProvider_INTERFACE_DEFINED__ +#define __ITfFunctionProvider_INTERFACE_DEFINED__ + +/* interface ITfFunctionProvider */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfFunctionProvider; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("101d6610-0990-11d3-8df0-00105a2799b5") + ITfFunctionProvider : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetType( + /* [out] */ GUID *pguid) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDescription( + /* [out] */ BSTR *pbstrDesc) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetFunction( + /* [in] */ REFGUID rguid, + /* [in] */ REFIID riid, + /* [iid_is][out] */ IUnknown **ppunk) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfFunctionProviderVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfFunctionProvider * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfFunctionProvider * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfFunctionProvider * This); + + HRESULT ( STDMETHODCALLTYPE *GetType )( + ITfFunctionProvider * This, + /* [out] */ GUID *pguid); + + HRESULT ( STDMETHODCALLTYPE *GetDescription )( + ITfFunctionProvider * This, + /* [out] */ BSTR *pbstrDesc); + + HRESULT ( STDMETHODCALLTYPE *GetFunction )( + ITfFunctionProvider * This, + /* [in] */ REFGUID rguid, + /* [in] */ REFIID riid, + /* [iid_is][out] */ IUnknown **ppunk); + + END_INTERFACE + } ITfFunctionProviderVtbl; + + interface ITfFunctionProvider + { + CONST_VTBL struct ITfFunctionProviderVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfFunctionProvider_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfFunctionProvider_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfFunctionProvider_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfFunctionProvider_GetType(This,pguid) \ + ( (This)->lpVtbl -> GetType(This,pguid) ) + +#define ITfFunctionProvider_GetDescription(This,pbstrDesc) \ + ( (This)->lpVtbl -> GetDescription(This,pbstrDesc) ) + +#define ITfFunctionProvider_GetFunction(This,rguid,riid,ppunk) \ + ( (This)->lpVtbl -> GetFunction(This,rguid,riid,ppunk) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfFunctionProvider_INTERFACE_DEFINED__ */ + + +#ifndef __IEnumTfFunctionProviders_INTERFACE_DEFINED__ +#define __IEnumTfFunctionProviders_INTERFACE_DEFINED__ + +/* interface IEnumTfFunctionProviders */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_IEnumTfFunctionProviders; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("e4b24db0-0990-11d3-8df0-00105a2799b5") + IEnumTfFunctionProviders : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ IEnumTfFunctionProviders **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ ITfFunctionProvider **ppCmdobj, + /* [out] */ ULONG *pcFetch) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG ulCount) = 0; + + }; + +#else /* C style interface */ + + typedef struct IEnumTfFunctionProvidersVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IEnumTfFunctionProviders * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IEnumTfFunctionProviders * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IEnumTfFunctionProviders * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IEnumTfFunctionProviders * This, + /* [out] */ IEnumTfFunctionProviders **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IEnumTfFunctionProviders * This, + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ ITfFunctionProvider **ppCmdobj, + /* [out] */ ULONG *pcFetch); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IEnumTfFunctionProviders * This); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + IEnumTfFunctionProviders * This, + /* [in] */ ULONG ulCount); + + END_INTERFACE + } IEnumTfFunctionProvidersVtbl; + + interface IEnumTfFunctionProviders + { + CONST_VTBL struct IEnumTfFunctionProvidersVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IEnumTfFunctionProviders_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IEnumTfFunctionProviders_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IEnumTfFunctionProviders_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IEnumTfFunctionProviders_Clone(This,ppEnum) \ + ( (This)->lpVtbl -> Clone(This,ppEnum) ) + +#define IEnumTfFunctionProviders_Next(This,ulCount,ppCmdobj,pcFetch) \ + ( (This)->lpVtbl -> Next(This,ulCount,ppCmdobj,pcFetch) ) + +#define IEnumTfFunctionProviders_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define IEnumTfFunctionProviders_Skip(This,ulCount) \ + ( (This)->lpVtbl -> Skip(This,ulCount) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IEnumTfFunctionProviders_INTERFACE_DEFINED__ */ + + +#ifndef __ITfInputProcessorProfiles_INTERFACE_DEFINED__ +#define __ITfInputProcessorProfiles_INTERFACE_DEFINED__ + +/* interface ITfInputProcessorProfiles */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfInputProcessorProfiles; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("1F02B6C5-7842-4EE6-8A0B-9A24183A95CA") + ITfInputProcessorProfiles : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Register( + /* [in] */ REFCLSID rclsid) = 0; + + virtual HRESULT STDMETHODCALLTYPE Unregister( + /* [in] */ REFCLSID rclsid) = 0; + + virtual HRESULT STDMETHODCALLTYPE AddLanguageProfile( + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile, + /* [size_is][in] */ const WCHAR *pchDesc, + /* [in] */ ULONG cchDesc, + /* [size_is][in] */ const WCHAR *pchIconFile, + /* [in] */ ULONG cchFile, + /* [in] */ ULONG uIconIndex) = 0; + + virtual HRESULT STDMETHODCALLTYPE RemoveLanguageProfile( + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnumInputProcessorInfo( + /* [out] */ IEnumGUID **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDefaultLanguageProfile( + /* [in] */ LANGID langid, + /* [in] */ REFGUID catid, + /* [out] */ CLSID *pclsid, + /* [out] */ GUID *pguidProfile) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetDefaultLanguageProfile( + /* [in] */ LANGID langid, + /* [in] */ REFCLSID rclsid, + /* [in] */ REFGUID guidProfiles) = 0; + + virtual HRESULT STDMETHODCALLTYPE ActivateLanguageProfile( + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfiles) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetActiveLanguageProfile( + /* [in] */ REFCLSID rclsid, + /* [out] */ LANGID *plangid, + /* [out] */ GUID *pguidProfile) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetLanguageProfileDescription( + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile, + /* [out] */ BSTR *pbstrProfile) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCurrentLanguage( + /* [out] */ LANGID *plangid) = 0; + + virtual HRESULT STDMETHODCALLTYPE ChangeCurrentLanguage( + /* [in] */ LANGID langid) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetLanguageList( + /* [size_is][size_is][out] */ LANGID **ppLangId, + /* [out] */ ULONG *pulCount) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnumLanguageProfiles( + /* [in] */ LANGID langid, + /* [out] */ IEnumTfLanguageProfiles **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnableLanguageProfile( + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile, + /* [in] */ BOOL fEnable) = 0; + + virtual HRESULT STDMETHODCALLTYPE IsEnabledLanguageProfile( + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile, + /* [out] */ BOOL *pfEnable) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnableLanguageProfileByDefault( + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile, + /* [in] */ BOOL fEnable) = 0; + + virtual HRESULT STDMETHODCALLTYPE SubstituteKeyboardLayout( + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile, + /* [in] */ HKL hKL) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfInputProcessorProfilesVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfInputProcessorProfiles * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfInputProcessorProfiles * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfInputProcessorProfiles * This); + + HRESULT ( STDMETHODCALLTYPE *Register )( + ITfInputProcessorProfiles * This, + /* [in] */ REFCLSID rclsid); + + HRESULT ( STDMETHODCALLTYPE *Unregister )( + ITfInputProcessorProfiles * This, + /* [in] */ REFCLSID rclsid); + + HRESULT ( STDMETHODCALLTYPE *AddLanguageProfile )( + ITfInputProcessorProfiles * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile, + /* [size_is][in] */ const WCHAR *pchDesc, + /* [in] */ ULONG cchDesc, + /* [size_is][in] */ const WCHAR *pchIconFile, + /* [in] */ ULONG cchFile, + /* [in] */ ULONG uIconIndex); + + HRESULT ( STDMETHODCALLTYPE *RemoveLanguageProfile )( + ITfInputProcessorProfiles * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile); + + HRESULT ( STDMETHODCALLTYPE *EnumInputProcessorInfo )( + ITfInputProcessorProfiles * This, + /* [out] */ IEnumGUID **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *GetDefaultLanguageProfile )( + ITfInputProcessorProfiles * This, + /* [in] */ LANGID langid, + /* [in] */ REFGUID catid, + /* [out] */ CLSID *pclsid, + /* [out] */ GUID *pguidProfile); + + HRESULT ( STDMETHODCALLTYPE *SetDefaultLanguageProfile )( + ITfInputProcessorProfiles * This, + /* [in] */ LANGID langid, + /* [in] */ REFCLSID rclsid, + /* [in] */ REFGUID guidProfiles); + + HRESULT ( STDMETHODCALLTYPE *ActivateLanguageProfile )( + ITfInputProcessorProfiles * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfiles); + + HRESULT ( STDMETHODCALLTYPE *GetActiveLanguageProfile )( + ITfInputProcessorProfiles * This, + /* [in] */ REFCLSID rclsid, + /* [out] */ LANGID *plangid, + /* [out] */ GUID *pguidProfile); + + HRESULT ( STDMETHODCALLTYPE *GetLanguageProfileDescription )( + ITfInputProcessorProfiles * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile, + /* [out] */ BSTR *pbstrProfile); + + HRESULT ( STDMETHODCALLTYPE *GetCurrentLanguage )( + ITfInputProcessorProfiles * This, + /* [out] */ LANGID *plangid); + + HRESULT ( STDMETHODCALLTYPE *ChangeCurrentLanguage )( + ITfInputProcessorProfiles * This, + /* [in] */ LANGID langid); + + HRESULT ( STDMETHODCALLTYPE *GetLanguageList )( + ITfInputProcessorProfiles * This, + /* [size_is][size_is][out] */ LANGID **ppLangId, + /* [out] */ ULONG *pulCount); + + HRESULT ( STDMETHODCALLTYPE *EnumLanguageProfiles )( + ITfInputProcessorProfiles * This, + /* [in] */ LANGID langid, + /* [out] */ IEnumTfLanguageProfiles **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *EnableLanguageProfile )( + ITfInputProcessorProfiles * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile, + /* [in] */ BOOL fEnable); + + HRESULT ( STDMETHODCALLTYPE *IsEnabledLanguageProfile )( + ITfInputProcessorProfiles * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile, + /* [out] */ BOOL *pfEnable); + + HRESULT ( STDMETHODCALLTYPE *EnableLanguageProfileByDefault )( + ITfInputProcessorProfiles * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile, + /* [in] */ BOOL fEnable); + + HRESULT ( STDMETHODCALLTYPE *SubstituteKeyboardLayout )( + ITfInputProcessorProfiles * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile, + /* [in] */ HKL hKL); + + END_INTERFACE + } ITfInputProcessorProfilesVtbl; + + interface ITfInputProcessorProfiles + { + CONST_VTBL struct ITfInputProcessorProfilesVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfInputProcessorProfiles_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfInputProcessorProfiles_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfInputProcessorProfiles_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfInputProcessorProfiles_Register(This,rclsid) \ + ( (This)->lpVtbl -> Register(This,rclsid) ) + +#define ITfInputProcessorProfiles_Unregister(This,rclsid) \ + ( (This)->lpVtbl -> Unregister(This,rclsid) ) + +#define ITfInputProcessorProfiles_AddLanguageProfile(This,rclsid,langid,guidProfile,pchDesc,cchDesc,pchIconFile,cchFile,uIconIndex) \ + ( (This)->lpVtbl -> AddLanguageProfile(This,rclsid,langid,guidProfile,pchDesc,cchDesc,pchIconFile,cchFile,uIconIndex) ) + +#define ITfInputProcessorProfiles_RemoveLanguageProfile(This,rclsid,langid,guidProfile) \ + ( (This)->lpVtbl -> RemoveLanguageProfile(This,rclsid,langid,guidProfile) ) + +#define ITfInputProcessorProfiles_EnumInputProcessorInfo(This,ppEnum) \ + ( (This)->lpVtbl -> EnumInputProcessorInfo(This,ppEnum) ) + +#define ITfInputProcessorProfiles_GetDefaultLanguageProfile(This,langid,catid,pclsid,pguidProfile) \ + ( (This)->lpVtbl -> GetDefaultLanguageProfile(This,langid,catid,pclsid,pguidProfile) ) + +#define ITfInputProcessorProfiles_SetDefaultLanguageProfile(This,langid,rclsid,guidProfiles) \ + ( (This)->lpVtbl -> SetDefaultLanguageProfile(This,langid,rclsid,guidProfiles) ) + +#define ITfInputProcessorProfiles_ActivateLanguageProfile(This,rclsid,langid,guidProfiles) \ + ( (This)->lpVtbl -> ActivateLanguageProfile(This,rclsid,langid,guidProfiles) ) + +#define ITfInputProcessorProfiles_GetActiveLanguageProfile(This,rclsid,plangid,pguidProfile) \ + ( (This)->lpVtbl -> GetActiveLanguageProfile(This,rclsid,plangid,pguidProfile) ) + +#define ITfInputProcessorProfiles_GetLanguageProfileDescription(This,rclsid,langid,guidProfile,pbstrProfile) \ + ( (This)->lpVtbl -> GetLanguageProfileDescription(This,rclsid,langid,guidProfile,pbstrProfile) ) + +#define ITfInputProcessorProfiles_GetCurrentLanguage(This,plangid) \ + ( (This)->lpVtbl -> GetCurrentLanguage(This,plangid) ) + +#define ITfInputProcessorProfiles_ChangeCurrentLanguage(This,langid) \ + ( (This)->lpVtbl -> ChangeCurrentLanguage(This,langid) ) + +#define ITfInputProcessorProfiles_GetLanguageList(This,ppLangId,pulCount) \ + ( (This)->lpVtbl -> GetLanguageList(This,ppLangId,pulCount) ) + +#define ITfInputProcessorProfiles_EnumLanguageProfiles(This,langid,ppEnum) \ + ( (This)->lpVtbl -> EnumLanguageProfiles(This,langid,ppEnum) ) + +#define ITfInputProcessorProfiles_EnableLanguageProfile(This,rclsid,langid,guidProfile,fEnable) \ + ( (This)->lpVtbl -> EnableLanguageProfile(This,rclsid,langid,guidProfile,fEnable) ) + +#define ITfInputProcessorProfiles_IsEnabledLanguageProfile(This,rclsid,langid,guidProfile,pfEnable) \ + ( (This)->lpVtbl -> IsEnabledLanguageProfile(This,rclsid,langid,guidProfile,pfEnable) ) + +#define ITfInputProcessorProfiles_EnableLanguageProfileByDefault(This,rclsid,langid,guidProfile,fEnable) \ + ( (This)->lpVtbl -> EnableLanguageProfileByDefault(This,rclsid,langid,guidProfile,fEnable) ) + +#define ITfInputProcessorProfiles_SubstituteKeyboardLayout(This,rclsid,langid,guidProfile,hKL) \ + ( (This)->lpVtbl -> SubstituteKeyboardLayout(This,rclsid,langid,guidProfile,hKL) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfInputProcessorProfiles_INTERFACE_DEFINED__ */ + + +#ifndef __ITfInputProcessorProfilesEx_INTERFACE_DEFINED__ +#define __ITfInputProcessorProfilesEx_INTERFACE_DEFINED__ + +/* interface ITfInputProcessorProfilesEx */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfInputProcessorProfilesEx; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("892f230f-fe00-4a41-a98e-fcd6de0d35ef") + ITfInputProcessorProfilesEx : public ITfInputProcessorProfiles + { + public: + virtual HRESULT STDMETHODCALLTYPE SetLanguageProfileDisplayName( + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile, + /* [size_is][in] */ const WCHAR *pchFile, + /* [in] */ ULONG cchFile, + /* [in] */ ULONG uResId) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfInputProcessorProfilesExVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfInputProcessorProfilesEx * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfInputProcessorProfilesEx * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfInputProcessorProfilesEx * This); + + HRESULT ( STDMETHODCALLTYPE *Register )( + ITfInputProcessorProfilesEx * This, + /* [in] */ REFCLSID rclsid); + + HRESULT ( STDMETHODCALLTYPE *Unregister )( + ITfInputProcessorProfilesEx * This, + /* [in] */ REFCLSID rclsid); + + HRESULT ( STDMETHODCALLTYPE *AddLanguageProfile )( + ITfInputProcessorProfilesEx * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile, + /* [size_is][in] */ const WCHAR *pchDesc, + /* [in] */ ULONG cchDesc, + /* [size_is][in] */ const WCHAR *pchIconFile, + /* [in] */ ULONG cchFile, + /* [in] */ ULONG uIconIndex); + + HRESULT ( STDMETHODCALLTYPE *RemoveLanguageProfile )( + ITfInputProcessorProfilesEx * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile); + + HRESULT ( STDMETHODCALLTYPE *EnumInputProcessorInfo )( + ITfInputProcessorProfilesEx * This, + /* [out] */ IEnumGUID **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *GetDefaultLanguageProfile )( + ITfInputProcessorProfilesEx * This, + /* [in] */ LANGID langid, + /* [in] */ REFGUID catid, + /* [out] */ CLSID *pclsid, + /* [out] */ GUID *pguidProfile); + + HRESULT ( STDMETHODCALLTYPE *SetDefaultLanguageProfile )( + ITfInputProcessorProfilesEx * This, + /* [in] */ LANGID langid, + /* [in] */ REFCLSID rclsid, + /* [in] */ REFGUID guidProfiles); + + HRESULT ( STDMETHODCALLTYPE *ActivateLanguageProfile )( + ITfInputProcessorProfilesEx * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfiles); + + HRESULT ( STDMETHODCALLTYPE *GetActiveLanguageProfile )( + ITfInputProcessorProfilesEx * This, + /* [in] */ REFCLSID rclsid, + /* [out] */ LANGID *plangid, + /* [out] */ GUID *pguidProfile); + + HRESULT ( STDMETHODCALLTYPE *GetLanguageProfileDescription )( + ITfInputProcessorProfilesEx * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile, + /* [out] */ BSTR *pbstrProfile); + + HRESULT ( STDMETHODCALLTYPE *GetCurrentLanguage )( + ITfInputProcessorProfilesEx * This, + /* [out] */ LANGID *plangid); + + HRESULT ( STDMETHODCALLTYPE *ChangeCurrentLanguage )( + ITfInputProcessorProfilesEx * This, + /* [in] */ LANGID langid); + + HRESULT ( STDMETHODCALLTYPE *GetLanguageList )( + ITfInputProcessorProfilesEx * This, + /* [size_is][size_is][out] */ LANGID **ppLangId, + /* [out] */ ULONG *pulCount); + + HRESULT ( STDMETHODCALLTYPE *EnumLanguageProfiles )( + ITfInputProcessorProfilesEx * This, + /* [in] */ LANGID langid, + /* [out] */ IEnumTfLanguageProfiles **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *EnableLanguageProfile )( + ITfInputProcessorProfilesEx * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile, + /* [in] */ BOOL fEnable); + + HRESULT ( STDMETHODCALLTYPE *IsEnabledLanguageProfile )( + ITfInputProcessorProfilesEx * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile, + /* [out] */ BOOL *pfEnable); + + HRESULT ( STDMETHODCALLTYPE *EnableLanguageProfileByDefault )( + ITfInputProcessorProfilesEx * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile, + /* [in] */ BOOL fEnable); + + HRESULT ( STDMETHODCALLTYPE *SubstituteKeyboardLayout )( + ITfInputProcessorProfilesEx * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile, + /* [in] */ HKL hKL); + + HRESULT ( STDMETHODCALLTYPE *SetLanguageProfileDisplayName )( + ITfInputProcessorProfilesEx * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile, + /* [size_is][in] */ const WCHAR *pchFile, + /* [in] */ ULONG cchFile, + /* [in] */ ULONG uResId); + + END_INTERFACE + } ITfInputProcessorProfilesExVtbl; + + interface ITfInputProcessorProfilesEx + { + CONST_VTBL struct ITfInputProcessorProfilesExVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfInputProcessorProfilesEx_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfInputProcessorProfilesEx_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfInputProcessorProfilesEx_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfInputProcessorProfilesEx_Register(This,rclsid) \ + ( (This)->lpVtbl -> Register(This,rclsid) ) + +#define ITfInputProcessorProfilesEx_Unregister(This,rclsid) \ + ( (This)->lpVtbl -> Unregister(This,rclsid) ) + +#define ITfInputProcessorProfilesEx_AddLanguageProfile(This,rclsid,langid,guidProfile,pchDesc,cchDesc,pchIconFile,cchFile,uIconIndex) \ + ( (This)->lpVtbl -> AddLanguageProfile(This,rclsid,langid,guidProfile,pchDesc,cchDesc,pchIconFile,cchFile,uIconIndex) ) + +#define ITfInputProcessorProfilesEx_RemoveLanguageProfile(This,rclsid,langid,guidProfile) \ + ( (This)->lpVtbl -> RemoveLanguageProfile(This,rclsid,langid,guidProfile) ) + +#define ITfInputProcessorProfilesEx_EnumInputProcessorInfo(This,ppEnum) \ + ( (This)->lpVtbl -> EnumInputProcessorInfo(This,ppEnum) ) + +#define ITfInputProcessorProfilesEx_GetDefaultLanguageProfile(This,langid,catid,pclsid,pguidProfile) \ + ( (This)->lpVtbl -> GetDefaultLanguageProfile(This,langid,catid,pclsid,pguidProfile) ) + +#define ITfInputProcessorProfilesEx_SetDefaultLanguageProfile(This,langid,rclsid,guidProfiles) \ + ( (This)->lpVtbl -> SetDefaultLanguageProfile(This,langid,rclsid,guidProfiles) ) + +#define ITfInputProcessorProfilesEx_ActivateLanguageProfile(This,rclsid,langid,guidProfiles) \ + ( (This)->lpVtbl -> ActivateLanguageProfile(This,rclsid,langid,guidProfiles) ) + +#define ITfInputProcessorProfilesEx_GetActiveLanguageProfile(This,rclsid,plangid,pguidProfile) \ + ( (This)->lpVtbl -> GetActiveLanguageProfile(This,rclsid,plangid,pguidProfile) ) + +#define ITfInputProcessorProfilesEx_GetLanguageProfileDescription(This,rclsid,langid,guidProfile,pbstrProfile) \ + ( (This)->lpVtbl -> GetLanguageProfileDescription(This,rclsid,langid,guidProfile,pbstrProfile) ) + +#define ITfInputProcessorProfilesEx_GetCurrentLanguage(This,plangid) \ + ( (This)->lpVtbl -> GetCurrentLanguage(This,plangid) ) + +#define ITfInputProcessorProfilesEx_ChangeCurrentLanguage(This,langid) \ + ( (This)->lpVtbl -> ChangeCurrentLanguage(This,langid) ) + +#define ITfInputProcessorProfilesEx_GetLanguageList(This,ppLangId,pulCount) \ + ( (This)->lpVtbl -> GetLanguageList(This,ppLangId,pulCount) ) + +#define ITfInputProcessorProfilesEx_EnumLanguageProfiles(This,langid,ppEnum) \ + ( (This)->lpVtbl -> EnumLanguageProfiles(This,langid,ppEnum) ) + +#define ITfInputProcessorProfilesEx_EnableLanguageProfile(This,rclsid,langid,guidProfile,fEnable) \ + ( (This)->lpVtbl -> EnableLanguageProfile(This,rclsid,langid,guidProfile,fEnable) ) + +#define ITfInputProcessorProfilesEx_IsEnabledLanguageProfile(This,rclsid,langid,guidProfile,pfEnable) \ + ( (This)->lpVtbl -> IsEnabledLanguageProfile(This,rclsid,langid,guidProfile,pfEnable) ) + +#define ITfInputProcessorProfilesEx_EnableLanguageProfileByDefault(This,rclsid,langid,guidProfile,fEnable) \ + ( (This)->lpVtbl -> EnableLanguageProfileByDefault(This,rclsid,langid,guidProfile,fEnable) ) + +#define ITfInputProcessorProfilesEx_SubstituteKeyboardLayout(This,rclsid,langid,guidProfile,hKL) \ + ( (This)->lpVtbl -> SubstituteKeyboardLayout(This,rclsid,langid,guidProfile,hKL) ) + + +#define ITfInputProcessorProfilesEx_SetLanguageProfileDisplayName(This,rclsid,langid,guidProfile,pchFile,cchFile,uResId) \ + ( (This)->lpVtbl -> SetLanguageProfileDisplayName(This,rclsid,langid,guidProfile,pchFile,cchFile,uResId) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfInputProcessorProfilesEx_INTERFACE_DEFINED__ */ + + +#ifndef __ITfInputProcessorProfileSubstituteLayout_INTERFACE_DEFINED__ +#define __ITfInputProcessorProfileSubstituteLayout_INTERFACE_DEFINED__ + +/* interface ITfInputProcessorProfileSubstituteLayout */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfInputProcessorProfileSubstituteLayout; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("4fd67194-1002-4513-bff2-c0ddf6258552") + ITfInputProcessorProfileSubstituteLayout : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetSubstituteKeyboardLayout( + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile, + /* [out] */ HKL *phKL) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfInputProcessorProfileSubstituteLayoutVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfInputProcessorProfileSubstituteLayout * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfInputProcessorProfileSubstituteLayout * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfInputProcessorProfileSubstituteLayout * This); + + HRESULT ( STDMETHODCALLTYPE *GetSubstituteKeyboardLayout )( + ITfInputProcessorProfileSubstituteLayout * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile, + /* [out] */ HKL *phKL); + + END_INTERFACE + } ITfInputProcessorProfileSubstituteLayoutVtbl; + + interface ITfInputProcessorProfileSubstituteLayout + { + CONST_VTBL struct ITfInputProcessorProfileSubstituteLayoutVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfInputProcessorProfileSubstituteLayout_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfInputProcessorProfileSubstituteLayout_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfInputProcessorProfileSubstituteLayout_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfInputProcessorProfileSubstituteLayout_GetSubstituteKeyboardLayout(This,rclsid,langid,guidProfile,phKL) \ + ( (This)->lpVtbl -> GetSubstituteKeyboardLayout(This,rclsid,langid,guidProfile,phKL) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfInputProcessorProfileSubstituteLayout_INTERFACE_DEFINED__ */ + + +#ifndef __ITfActiveLanguageProfileNotifySink_INTERFACE_DEFINED__ +#define __ITfActiveLanguageProfileNotifySink_INTERFACE_DEFINED__ + +/* interface ITfActiveLanguageProfileNotifySink */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfActiveLanguageProfileNotifySink; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("b246cb75-a93e-4652-bf8c-b3fe0cfd7e57") + ITfActiveLanguageProfileNotifySink : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE OnActivated( + /* [in] */ REFCLSID clsid, + /* [in] */ REFGUID guidProfile, + /* [in] */ BOOL fActivated) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfActiveLanguageProfileNotifySinkVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfActiveLanguageProfileNotifySink * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfActiveLanguageProfileNotifySink * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfActiveLanguageProfileNotifySink * This); + + HRESULT ( STDMETHODCALLTYPE *OnActivated )( + ITfActiveLanguageProfileNotifySink * This, + /* [in] */ REFCLSID clsid, + /* [in] */ REFGUID guidProfile, + /* [in] */ BOOL fActivated); + + END_INTERFACE + } ITfActiveLanguageProfileNotifySinkVtbl; + + interface ITfActiveLanguageProfileNotifySink + { + CONST_VTBL struct ITfActiveLanguageProfileNotifySinkVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfActiveLanguageProfileNotifySink_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfActiveLanguageProfileNotifySink_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfActiveLanguageProfileNotifySink_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfActiveLanguageProfileNotifySink_OnActivated(This,clsid,guidProfile,fActivated) \ + ( (This)->lpVtbl -> OnActivated(This,clsid,guidProfile,fActivated) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfActiveLanguageProfileNotifySink_INTERFACE_DEFINED__ */ + + +#ifndef __IEnumTfLanguageProfiles_INTERFACE_DEFINED__ +#define __IEnumTfLanguageProfiles_INTERFACE_DEFINED__ + +/* interface IEnumTfLanguageProfiles */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_IEnumTfLanguageProfiles; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("3d61bf11-ac5f-42c8-a4cb-931bcc28c744") + IEnumTfLanguageProfiles : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ IEnumTfLanguageProfiles **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ TF_LANGUAGEPROFILE *pProfile, + /* [out] */ ULONG *pcFetch) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG ulCount) = 0; + + }; + +#else /* C style interface */ + + typedef struct IEnumTfLanguageProfilesVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IEnumTfLanguageProfiles * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IEnumTfLanguageProfiles * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IEnumTfLanguageProfiles * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IEnumTfLanguageProfiles * This, + /* [out] */ IEnumTfLanguageProfiles **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IEnumTfLanguageProfiles * This, + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ TF_LANGUAGEPROFILE *pProfile, + /* [out] */ ULONG *pcFetch); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IEnumTfLanguageProfiles * This); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + IEnumTfLanguageProfiles * This, + /* [in] */ ULONG ulCount); + + END_INTERFACE + } IEnumTfLanguageProfilesVtbl; + + interface IEnumTfLanguageProfiles + { + CONST_VTBL struct IEnumTfLanguageProfilesVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IEnumTfLanguageProfiles_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IEnumTfLanguageProfiles_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IEnumTfLanguageProfiles_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IEnumTfLanguageProfiles_Clone(This,ppEnum) \ + ( (This)->lpVtbl -> Clone(This,ppEnum) ) + +#define IEnumTfLanguageProfiles_Next(This,ulCount,pProfile,pcFetch) \ + ( (This)->lpVtbl -> Next(This,ulCount,pProfile,pcFetch) ) + +#define IEnumTfLanguageProfiles_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define IEnumTfLanguageProfiles_Skip(This,ulCount) \ + ( (This)->lpVtbl -> Skip(This,ulCount) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IEnumTfLanguageProfiles_INTERFACE_DEFINED__ */ + + +#ifndef __ITfLanguageProfileNotifySink_INTERFACE_DEFINED__ +#define __ITfLanguageProfileNotifySink_INTERFACE_DEFINED__ + +/* interface ITfLanguageProfileNotifySink */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfLanguageProfileNotifySink; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("43c9fe15-f494-4c17-9de2-b8a4ac350aa8") + ITfLanguageProfileNotifySink : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE OnLanguageChange( + /* [in] */ LANGID langid, + /* [out] */ BOOL *pfAccept) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnLanguageChanged( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfLanguageProfileNotifySinkVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfLanguageProfileNotifySink * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfLanguageProfileNotifySink * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfLanguageProfileNotifySink * This); + + HRESULT ( STDMETHODCALLTYPE *OnLanguageChange )( + ITfLanguageProfileNotifySink * This, + /* [in] */ LANGID langid, + /* [out] */ BOOL *pfAccept); + + HRESULT ( STDMETHODCALLTYPE *OnLanguageChanged )( + ITfLanguageProfileNotifySink * This); + + END_INTERFACE + } ITfLanguageProfileNotifySinkVtbl; + + interface ITfLanguageProfileNotifySink + { + CONST_VTBL struct ITfLanguageProfileNotifySinkVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfLanguageProfileNotifySink_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfLanguageProfileNotifySink_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfLanguageProfileNotifySink_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfLanguageProfileNotifySink_OnLanguageChange(This,langid,pfAccept) \ + ( (This)->lpVtbl -> OnLanguageChange(This,langid,pfAccept) ) + +#define ITfLanguageProfileNotifySink_OnLanguageChanged(This) \ + ( (This)->lpVtbl -> OnLanguageChanged(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfLanguageProfileNotifySink_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_msctf_0000_0057 */ +/* [local] */ + +typedef /* [uuid] */ DECLSPEC_UUID("44d2825a-10e5-43b2-877f-6cb2f43b7e7e") struct TF_INPUTPROCESSORPROFILE + { + DWORD dwProfileType; + LANGID langid; + CLSID clsid; + GUID guidProfile; + GUID catid; + HKL hklSubstitute; + DWORD dwCaps; + HKL hkl; + DWORD dwFlags; + } TF_INPUTPROCESSORPROFILE; + + + +extern RPC_IF_HANDLE __MIDL_itf_msctf_0000_0057_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_msctf_0000_0057_v0_0_s_ifspec; + +#ifndef __ITfInputProcessorProfileMgr_INTERFACE_DEFINED__ +#define __ITfInputProcessorProfileMgr_INTERFACE_DEFINED__ + +/* interface ITfInputProcessorProfileMgr */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfInputProcessorProfileMgr; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("71c6e74c-0f28-11d8-a82a-00065b84435c") + ITfInputProcessorProfileMgr : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE ActivateProfile( + /* [in] */ DWORD dwProfileType, + /* [in] */ LANGID langid, + /* [in] */ REFCLSID clsid, + /* [in] */ REFGUID guidProfile, + /* [in] */ HKL hkl, + /* [in] */ DWORD dwFlags) = 0; + + virtual HRESULT STDMETHODCALLTYPE DeactivateProfile( + /* [in] */ DWORD dwProfileType, + /* [in] */ LANGID langid, + /* [in] */ REFCLSID clsid, + /* [in] */ REFGUID guidProfile, + /* [in] */ HKL hkl, + /* [in] */ DWORD dwFlags) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetProfile( + /* [in] */ DWORD dwProfileType, + /* [in] */ LANGID langid, + /* [in] */ REFCLSID clsid, + /* [in] */ REFGUID guidProfile, + /* [in] */ HKL hkl, + /* [out] */ TF_INPUTPROCESSORPROFILE *pProfile) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnumProfiles( + /* [in] */ LANGID langid, + /* [out] */ IEnumTfInputProcessorProfiles **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE ReleaseInputProcessor( + /* [in] */ REFCLSID rclsid, + /* [in] */ DWORD dwFlags) = 0; + + virtual HRESULT STDMETHODCALLTYPE RegisterProfile( + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile, + /* [size_is][in] */ const WCHAR *pchDesc, + /* [in] */ ULONG cchDesc, + /* [size_is][in] */ const WCHAR *pchIconFile, + /* [in] */ ULONG cchFile, + /* [in] */ ULONG uIconIndex, + /* [in] */ HKL hklsubstitute, + /* [in] */ DWORD dwPreferredLayout, + /* [in] */ BOOL bEnabledByDefault, + /* [in] */ DWORD dwFlags) = 0; + + virtual HRESULT STDMETHODCALLTYPE UnregisterProfile( + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile, + /* [in] */ DWORD dwFlags) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetActiveProfile( + /* [in] */ REFGUID catid, + /* [out] */ TF_INPUTPROCESSORPROFILE *pProfile) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfInputProcessorProfileMgrVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfInputProcessorProfileMgr * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfInputProcessorProfileMgr * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfInputProcessorProfileMgr * This); + + HRESULT ( STDMETHODCALLTYPE *ActivateProfile )( + ITfInputProcessorProfileMgr * This, + /* [in] */ DWORD dwProfileType, + /* [in] */ LANGID langid, + /* [in] */ REFCLSID clsid, + /* [in] */ REFGUID guidProfile, + /* [in] */ HKL hkl, + /* [in] */ DWORD dwFlags); + + HRESULT ( STDMETHODCALLTYPE *DeactivateProfile )( + ITfInputProcessorProfileMgr * This, + /* [in] */ DWORD dwProfileType, + /* [in] */ LANGID langid, + /* [in] */ REFCLSID clsid, + /* [in] */ REFGUID guidProfile, + /* [in] */ HKL hkl, + /* [in] */ DWORD dwFlags); + + HRESULT ( STDMETHODCALLTYPE *GetProfile )( + ITfInputProcessorProfileMgr * This, + /* [in] */ DWORD dwProfileType, + /* [in] */ LANGID langid, + /* [in] */ REFCLSID clsid, + /* [in] */ REFGUID guidProfile, + /* [in] */ HKL hkl, + /* [out] */ TF_INPUTPROCESSORPROFILE *pProfile); + + HRESULT ( STDMETHODCALLTYPE *EnumProfiles )( + ITfInputProcessorProfileMgr * This, + /* [in] */ LANGID langid, + /* [out] */ IEnumTfInputProcessorProfiles **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *ReleaseInputProcessor )( + ITfInputProcessorProfileMgr * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ DWORD dwFlags); + + HRESULT ( STDMETHODCALLTYPE *RegisterProfile )( + ITfInputProcessorProfileMgr * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile, + /* [size_is][in] */ const WCHAR *pchDesc, + /* [in] */ ULONG cchDesc, + /* [size_is][in] */ const WCHAR *pchIconFile, + /* [in] */ ULONG cchFile, + /* [in] */ ULONG uIconIndex, + /* [in] */ HKL hklsubstitute, + /* [in] */ DWORD dwPreferredLayout, + /* [in] */ BOOL bEnabledByDefault, + /* [in] */ DWORD dwFlags); + + HRESULT ( STDMETHODCALLTYPE *UnregisterProfile )( + ITfInputProcessorProfileMgr * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile, + /* [in] */ DWORD dwFlags); + + HRESULT ( STDMETHODCALLTYPE *GetActiveProfile )( + ITfInputProcessorProfileMgr * This, + /* [in] */ REFGUID catid, + /* [out] */ TF_INPUTPROCESSORPROFILE *pProfile); + + END_INTERFACE + } ITfInputProcessorProfileMgrVtbl; + + interface ITfInputProcessorProfileMgr + { + CONST_VTBL struct ITfInputProcessorProfileMgrVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfInputProcessorProfileMgr_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfInputProcessorProfileMgr_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfInputProcessorProfileMgr_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfInputProcessorProfileMgr_ActivateProfile(This,dwProfileType,langid,clsid,guidProfile,hkl,dwFlags) \ + ( (This)->lpVtbl -> ActivateProfile(This,dwProfileType,langid,clsid,guidProfile,hkl,dwFlags) ) + +#define ITfInputProcessorProfileMgr_DeactivateProfile(This,dwProfileType,langid,clsid,guidProfile,hkl,dwFlags) \ + ( (This)->lpVtbl -> DeactivateProfile(This,dwProfileType,langid,clsid,guidProfile,hkl,dwFlags) ) + +#define ITfInputProcessorProfileMgr_GetProfile(This,dwProfileType,langid,clsid,guidProfile,hkl,pProfile) \ + ( (This)->lpVtbl -> GetProfile(This,dwProfileType,langid,clsid,guidProfile,hkl,pProfile) ) + +#define ITfInputProcessorProfileMgr_EnumProfiles(This,langid,ppEnum) \ + ( (This)->lpVtbl -> EnumProfiles(This,langid,ppEnum) ) + +#define ITfInputProcessorProfileMgr_ReleaseInputProcessor(This,rclsid,dwFlags) \ + ( (This)->lpVtbl -> ReleaseInputProcessor(This,rclsid,dwFlags) ) + +#define ITfInputProcessorProfileMgr_RegisterProfile(This,rclsid,langid,guidProfile,pchDesc,cchDesc,pchIconFile,cchFile,uIconIndex,hklsubstitute,dwPreferredLayout,bEnabledByDefault,dwFlags) \ + ( (This)->lpVtbl -> RegisterProfile(This,rclsid,langid,guidProfile,pchDesc,cchDesc,pchIconFile,cchFile,uIconIndex,hklsubstitute,dwPreferredLayout,bEnabledByDefault,dwFlags) ) + +#define ITfInputProcessorProfileMgr_UnregisterProfile(This,rclsid,langid,guidProfile,dwFlags) \ + ( (This)->lpVtbl -> UnregisterProfile(This,rclsid,langid,guidProfile,dwFlags) ) + +#define ITfInputProcessorProfileMgr_GetActiveProfile(This,catid,pProfile) \ + ( (This)->lpVtbl -> GetActiveProfile(This,catid,pProfile) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfInputProcessorProfileMgr_INTERFACE_DEFINED__ */ + + +#ifndef __IEnumTfInputProcessorProfiles_INTERFACE_DEFINED__ +#define __IEnumTfInputProcessorProfiles_INTERFACE_DEFINED__ + +/* interface IEnumTfInputProcessorProfiles */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_IEnumTfInputProcessorProfiles; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("71c6e74d-0f28-11d8-a82a-00065b84435c") + IEnumTfInputProcessorProfiles : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ IEnumTfInputProcessorProfiles **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ TF_INPUTPROCESSORPROFILE *pProfile, + /* [out] */ ULONG *pcFetch) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG ulCount) = 0; + + }; + +#else /* C style interface */ + + typedef struct IEnumTfInputProcessorProfilesVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IEnumTfInputProcessorProfiles * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IEnumTfInputProcessorProfiles * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IEnumTfInputProcessorProfiles * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IEnumTfInputProcessorProfiles * This, + /* [out] */ IEnumTfInputProcessorProfiles **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IEnumTfInputProcessorProfiles * This, + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ TF_INPUTPROCESSORPROFILE *pProfile, + /* [out] */ ULONG *pcFetch); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IEnumTfInputProcessorProfiles * This); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + IEnumTfInputProcessorProfiles * This, + /* [in] */ ULONG ulCount); + + END_INTERFACE + } IEnumTfInputProcessorProfilesVtbl; + + interface IEnumTfInputProcessorProfiles + { + CONST_VTBL struct IEnumTfInputProcessorProfilesVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IEnumTfInputProcessorProfiles_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IEnumTfInputProcessorProfiles_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IEnumTfInputProcessorProfiles_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IEnumTfInputProcessorProfiles_Clone(This,ppEnum) \ + ( (This)->lpVtbl -> Clone(This,ppEnum) ) + +#define IEnumTfInputProcessorProfiles_Next(This,ulCount,pProfile,pcFetch) \ + ( (This)->lpVtbl -> Next(This,ulCount,pProfile,pcFetch) ) + +#define IEnumTfInputProcessorProfiles_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define IEnumTfInputProcessorProfiles_Skip(This,ulCount) \ + ( (This)->lpVtbl -> Skip(This,ulCount) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IEnumTfInputProcessorProfiles_INTERFACE_DEFINED__ */ + + +#ifndef __ITfInputProcessorProfileActivationSink_INTERFACE_DEFINED__ +#define __ITfInputProcessorProfileActivationSink_INTERFACE_DEFINED__ + +/* interface ITfInputProcessorProfileActivationSink */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfInputProcessorProfileActivationSink; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("71c6e74e-0f28-11d8-a82a-00065b84435c") + ITfInputProcessorProfileActivationSink : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE OnActivated( + /* [in] */ DWORD dwProfileType, + /* [in] */ LANGID langid, + /* [in] */ REFCLSID clsid, + /* [in] */ REFGUID catid, + /* [in] */ REFGUID guidProfile, + /* [in] */ HKL hkl, + /* [in] */ DWORD dwFlags) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfInputProcessorProfileActivationSinkVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfInputProcessorProfileActivationSink * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfInputProcessorProfileActivationSink * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfInputProcessorProfileActivationSink * This); + + HRESULT ( STDMETHODCALLTYPE *OnActivated )( + ITfInputProcessorProfileActivationSink * This, + /* [in] */ DWORD dwProfileType, + /* [in] */ LANGID langid, + /* [in] */ REFCLSID clsid, + /* [in] */ REFGUID catid, + /* [in] */ REFGUID guidProfile, + /* [in] */ HKL hkl, + /* [in] */ DWORD dwFlags); + + END_INTERFACE + } ITfInputProcessorProfileActivationSinkVtbl; + + interface ITfInputProcessorProfileActivationSink + { + CONST_VTBL struct ITfInputProcessorProfileActivationSinkVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfInputProcessorProfileActivationSink_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfInputProcessorProfileActivationSink_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfInputProcessorProfileActivationSink_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfInputProcessorProfileActivationSink_OnActivated(This,dwProfileType,langid,clsid,catid,guidProfile,hkl,dwFlags) \ + ( (This)->lpVtbl -> OnActivated(This,dwProfileType,langid,clsid,catid,guidProfile,hkl,dwFlags) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfInputProcessorProfileActivationSink_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_msctf_0000_0060 */ +/* [local] */ + +typedef /* [uuid] */ DECLSPEC_UUID("77c12f95-b783-450d-879f-1cd2362c6521") struct TF_PRESERVEDKEY + { + UINT uVKey; + UINT uModifiers; + } TF_PRESERVEDKEY; + + + +extern RPC_IF_HANDLE __MIDL_itf_msctf_0000_0060_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_msctf_0000_0060_v0_0_s_ifspec; + +#ifndef __ITfKeystrokeMgr_INTERFACE_DEFINED__ +#define __ITfKeystrokeMgr_INTERFACE_DEFINED__ + +/* interface ITfKeystrokeMgr */ +/* [unique][uuid][local][object] */ + + +EXTERN_C const IID IID_ITfKeystrokeMgr; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("aa80e7f0-2021-11d2-93e0-0060b067b86e") + ITfKeystrokeMgr : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE AdviseKeyEventSink( + /* [in] */ TfClientId tid, + /* [in] */ ITfKeyEventSink *pSink, + /* [in] */ BOOL fForeground) = 0; + + virtual HRESULT STDMETHODCALLTYPE UnadviseKeyEventSink( + /* [in] */ TfClientId tid) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetForeground( + /* [out] */ CLSID *pclsid) = 0; + + virtual HRESULT STDMETHODCALLTYPE TestKeyDown( + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ BOOL *pfEaten) = 0; + + virtual HRESULT STDMETHODCALLTYPE TestKeyUp( + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ BOOL *pfEaten) = 0; + + virtual HRESULT STDMETHODCALLTYPE KeyDown( + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ BOOL *pfEaten) = 0; + + virtual HRESULT STDMETHODCALLTYPE KeyUp( + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ BOOL *pfEaten) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetPreservedKey( + /* [in] */ ITfContext *pic, + /* [in] */ const TF_PRESERVEDKEY *pprekey, + /* [out] */ GUID *pguid) = 0; + + virtual HRESULT STDMETHODCALLTYPE IsPreservedKey( + /* [in] */ REFGUID rguid, + /* [in] */ const TF_PRESERVEDKEY *pprekey, + /* [out] */ BOOL *pfRegistered) = 0; + + virtual HRESULT STDMETHODCALLTYPE PreserveKey( + /* [in] */ TfClientId tid, + /* [in] */ REFGUID rguid, + /* [in] */ const TF_PRESERVEDKEY *prekey, + /* [size_is][in] */ const WCHAR *pchDesc, + /* [in] */ ULONG cchDesc) = 0; + + virtual HRESULT STDMETHODCALLTYPE UnpreserveKey( + /* [in] */ REFGUID rguid, + /* [in] */ const TF_PRESERVEDKEY *pprekey) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetPreservedKeyDescription( + /* [in] */ REFGUID rguid, + /* [size_is][in] */ const WCHAR *pchDesc, + /* [in] */ ULONG cchDesc) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetPreservedKeyDescription( + /* [in] */ REFGUID rguid, + /* [out] */ BSTR *pbstrDesc) = 0; + + virtual HRESULT STDMETHODCALLTYPE SimulatePreservedKey( + /* [in] */ ITfContext *pic, + /* [in] */ REFGUID rguid, + /* [out] */ BOOL *pfEaten) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfKeystrokeMgrVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfKeystrokeMgr * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfKeystrokeMgr * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfKeystrokeMgr * This); + + HRESULT ( STDMETHODCALLTYPE *AdviseKeyEventSink )( + ITfKeystrokeMgr * This, + /* [in] */ TfClientId tid, + /* [in] */ ITfKeyEventSink *pSink, + /* [in] */ BOOL fForeground); + + HRESULT ( STDMETHODCALLTYPE *UnadviseKeyEventSink )( + ITfKeystrokeMgr * This, + /* [in] */ TfClientId tid); + + HRESULT ( STDMETHODCALLTYPE *GetForeground )( + ITfKeystrokeMgr * This, + /* [out] */ CLSID *pclsid); + + HRESULT ( STDMETHODCALLTYPE *TestKeyDown )( + ITfKeystrokeMgr * This, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ BOOL *pfEaten); + + HRESULT ( STDMETHODCALLTYPE *TestKeyUp )( + ITfKeystrokeMgr * This, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ BOOL *pfEaten); + + HRESULT ( STDMETHODCALLTYPE *KeyDown )( + ITfKeystrokeMgr * This, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ BOOL *pfEaten); + + HRESULT ( STDMETHODCALLTYPE *KeyUp )( + ITfKeystrokeMgr * This, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ BOOL *pfEaten); + + HRESULT ( STDMETHODCALLTYPE *GetPreservedKey )( + ITfKeystrokeMgr * This, + /* [in] */ ITfContext *pic, + /* [in] */ const TF_PRESERVEDKEY *pprekey, + /* [out] */ GUID *pguid); + + HRESULT ( STDMETHODCALLTYPE *IsPreservedKey )( + ITfKeystrokeMgr * This, + /* [in] */ REFGUID rguid, + /* [in] */ const TF_PRESERVEDKEY *pprekey, + /* [out] */ BOOL *pfRegistered); + + HRESULT ( STDMETHODCALLTYPE *PreserveKey )( + ITfKeystrokeMgr * This, + /* [in] */ TfClientId tid, + /* [in] */ REFGUID rguid, + /* [in] */ const TF_PRESERVEDKEY *prekey, + /* [size_is][in] */ const WCHAR *pchDesc, + /* [in] */ ULONG cchDesc); + + HRESULT ( STDMETHODCALLTYPE *UnpreserveKey )( + ITfKeystrokeMgr * This, + /* [in] */ REFGUID rguid, + /* [in] */ const TF_PRESERVEDKEY *pprekey); + + HRESULT ( STDMETHODCALLTYPE *SetPreservedKeyDescription )( + ITfKeystrokeMgr * This, + /* [in] */ REFGUID rguid, + /* [size_is][in] */ const WCHAR *pchDesc, + /* [in] */ ULONG cchDesc); + + HRESULT ( STDMETHODCALLTYPE *GetPreservedKeyDescription )( + ITfKeystrokeMgr * This, + /* [in] */ REFGUID rguid, + /* [out] */ BSTR *pbstrDesc); + + HRESULT ( STDMETHODCALLTYPE *SimulatePreservedKey )( + ITfKeystrokeMgr * This, + /* [in] */ ITfContext *pic, + /* [in] */ REFGUID rguid, + /* [out] */ BOOL *pfEaten); + + END_INTERFACE + } ITfKeystrokeMgrVtbl; + + interface ITfKeystrokeMgr + { + CONST_VTBL struct ITfKeystrokeMgrVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfKeystrokeMgr_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfKeystrokeMgr_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfKeystrokeMgr_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfKeystrokeMgr_AdviseKeyEventSink(This,tid,pSink,fForeground) \ + ( (This)->lpVtbl -> AdviseKeyEventSink(This,tid,pSink,fForeground) ) + +#define ITfKeystrokeMgr_UnadviseKeyEventSink(This,tid) \ + ( (This)->lpVtbl -> UnadviseKeyEventSink(This,tid) ) + +#define ITfKeystrokeMgr_GetForeground(This,pclsid) \ + ( (This)->lpVtbl -> GetForeground(This,pclsid) ) + +#define ITfKeystrokeMgr_TestKeyDown(This,wParam,lParam,pfEaten) \ + ( (This)->lpVtbl -> TestKeyDown(This,wParam,lParam,pfEaten) ) + +#define ITfKeystrokeMgr_TestKeyUp(This,wParam,lParam,pfEaten) \ + ( (This)->lpVtbl -> TestKeyUp(This,wParam,lParam,pfEaten) ) + +#define ITfKeystrokeMgr_KeyDown(This,wParam,lParam,pfEaten) \ + ( (This)->lpVtbl -> KeyDown(This,wParam,lParam,pfEaten) ) + +#define ITfKeystrokeMgr_KeyUp(This,wParam,lParam,pfEaten) \ + ( (This)->lpVtbl -> KeyUp(This,wParam,lParam,pfEaten) ) + +#define ITfKeystrokeMgr_GetPreservedKey(This,pic,pprekey,pguid) \ + ( (This)->lpVtbl -> GetPreservedKey(This,pic,pprekey,pguid) ) + +#define ITfKeystrokeMgr_IsPreservedKey(This,rguid,pprekey,pfRegistered) \ + ( (This)->lpVtbl -> IsPreservedKey(This,rguid,pprekey,pfRegistered) ) + +#define ITfKeystrokeMgr_PreserveKey(This,tid,rguid,prekey,pchDesc,cchDesc) \ + ( (This)->lpVtbl -> PreserveKey(This,tid,rguid,prekey,pchDesc,cchDesc) ) + +#define ITfKeystrokeMgr_UnpreserveKey(This,rguid,pprekey) \ + ( (This)->lpVtbl -> UnpreserveKey(This,rguid,pprekey) ) + +#define ITfKeystrokeMgr_SetPreservedKeyDescription(This,rguid,pchDesc,cchDesc) \ + ( (This)->lpVtbl -> SetPreservedKeyDescription(This,rguid,pchDesc,cchDesc) ) + +#define ITfKeystrokeMgr_GetPreservedKeyDescription(This,rguid,pbstrDesc) \ + ( (This)->lpVtbl -> GetPreservedKeyDescription(This,rguid,pbstrDesc) ) + +#define ITfKeystrokeMgr_SimulatePreservedKey(This,pic,rguid,pfEaten) \ + ( (This)->lpVtbl -> SimulatePreservedKey(This,pic,rguid,pfEaten) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfKeystrokeMgr_INTERFACE_DEFINED__ */ + + +#ifndef __ITfKeyEventSink_INTERFACE_DEFINED__ +#define __ITfKeyEventSink_INTERFACE_DEFINED__ + +/* interface ITfKeyEventSink */ +/* [unique][uuid][local][object] */ + + +EXTERN_C const IID IID_ITfKeyEventSink; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("aa80e7f5-2021-11d2-93e0-0060b067b86e") + ITfKeyEventSink : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE OnSetFocus( + /* [in] */ BOOL fForeground) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnTestKeyDown( + /* [in] */ ITfContext *pic, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ BOOL *pfEaten) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnTestKeyUp( + /* [in] */ ITfContext *pic, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ BOOL *pfEaten) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnKeyDown( + /* [in] */ ITfContext *pic, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ BOOL *pfEaten) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnKeyUp( + /* [in] */ ITfContext *pic, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ BOOL *pfEaten) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnPreservedKey( + /* [in] */ ITfContext *pic, + /* [in] */ REFGUID rguid, + /* [out] */ BOOL *pfEaten) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfKeyEventSinkVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfKeyEventSink * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfKeyEventSink * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfKeyEventSink * This); + + HRESULT ( STDMETHODCALLTYPE *OnSetFocus )( + ITfKeyEventSink * This, + /* [in] */ BOOL fForeground); + + HRESULT ( STDMETHODCALLTYPE *OnTestKeyDown )( + ITfKeyEventSink * This, + /* [in] */ ITfContext *pic, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ BOOL *pfEaten); + + HRESULT ( STDMETHODCALLTYPE *OnTestKeyUp )( + ITfKeyEventSink * This, + /* [in] */ ITfContext *pic, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ BOOL *pfEaten); + + HRESULT ( STDMETHODCALLTYPE *OnKeyDown )( + ITfKeyEventSink * This, + /* [in] */ ITfContext *pic, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ BOOL *pfEaten); + + HRESULT ( STDMETHODCALLTYPE *OnKeyUp )( + ITfKeyEventSink * This, + /* [in] */ ITfContext *pic, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam, + /* [out] */ BOOL *pfEaten); + + HRESULT ( STDMETHODCALLTYPE *OnPreservedKey )( + ITfKeyEventSink * This, + /* [in] */ ITfContext *pic, + /* [in] */ REFGUID rguid, + /* [out] */ BOOL *pfEaten); + + END_INTERFACE + } ITfKeyEventSinkVtbl; + + interface ITfKeyEventSink + { + CONST_VTBL struct ITfKeyEventSinkVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfKeyEventSink_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfKeyEventSink_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfKeyEventSink_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfKeyEventSink_OnSetFocus(This,fForeground) \ + ( (This)->lpVtbl -> OnSetFocus(This,fForeground) ) + +#define ITfKeyEventSink_OnTestKeyDown(This,pic,wParam,lParam,pfEaten) \ + ( (This)->lpVtbl -> OnTestKeyDown(This,pic,wParam,lParam,pfEaten) ) + +#define ITfKeyEventSink_OnTestKeyUp(This,pic,wParam,lParam,pfEaten) \ + ( (This)->lpVtbl -> OnTestKeyUp(This,pic,wParam,lParam,pfEaten) ) + +#define ITfKeyEventSink_OnKeyDown(This,pic,wParam,lParam,pfEaten) \ + ( (This)->lpVtbl -> OnKeyDown(This,pic,wParam,lParam,pfEaten) ) + +#define ITfKeyEventSink_OnKeyUp(This,pic,wParam,lParam,pfEaten) \ + ( (This)->lpVtbl -> OnKeyUp(This,pic,wParam,lParam,pfEaten) ) + +#define ITfKeyEventSink_OnPreservedKey(This,pic,rguid,pfEaten) \ + ( (This)->lpVtbl -> OnPreservedKey(This,pic,rguid,pfEaten) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfKeyEventSink_INTERFACE_DEFINED__ */ + + +#ifndef __ITfKeyTraceEventSink_INTERFACE_DEFINED__ +#define __ITfKeyTraceEventSink_INTERFACE_DEFINED__ + +/* interface ITfKeyTraceEventSink */ +/* [unique][uuid][local][object] */ + + +EXTERN_C const IID IID_ITfKeyTraceEventSink; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("1cd4c13b-1c36-4191-a70a-7f3e611f367d") + ITfKeyTraceEventSink : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE OnKeyTraceDown( + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnKeyTraceUp( + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfKeyTraceEventSinkVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfKeyTraceEventSink * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfKeyTraceEventSink * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfKeyTraceEventSink * This); + + HRESULT ( STDMETHODCALLTYPE *OnKeyTraceDown )( + ITfKeyTraceEventSink * This, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam); + + HRESULT ( STDMETHODCALLTYPE *OnKeyTraceUp )( + ITfKeyTraceEventSink * This, + /* [in] */ WPARAM wParam, + /* [in] */ LPARAM lParam); + + END_INTERFACE + } ITfKeyTraceEventSinkVtbl; + + interface ITfKeyTraceEventSink + { + CONST_VTBL struct ITfKeyTraceEventSinkVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfKeyTraceEventSink_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfKeyTraceEventSink_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfKeyTraceEventSink_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfKeyTraceEventSink_OnKeyTraceDown(This,wParam,lParam) \ + ( (This)->lpVtbl -> OnKeyTraceDown(This,wParam,lParam) ) + +#define ITfKeyTraceEventSink_OnKeyTraceUp(This,wParam,lParam) \ + ( (This)->lpVtbl -> OnKeyTraceUp(This,wParam,lParam) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfKeyTraceEventSink_INTERFACE_DEFINED__ */ + + +#ifndef __ITfPreservedKeyNotifySink_INTERFACE_DEFINED__ +#define __ITfPreservedKeyNotifySink_INTERFACE_DEFINED__ + +/* interface ITfPreservedKeyNotifySink */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfPreservedKeyNotifySink; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("6f77c993-d2b1-446e-853e-5912efc8a286") + ITfPreservedKeyNotifySink : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE OnUpdated( + /* [in] */ const TF_PRESERVEDKEY *pprekey) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfPreservedKeyNotifySinkVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfPreservedKeyNotifySink * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfPreservedKeyNotifySink * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfPreservedKeyNotifySink * This); + + HRESULT ( STDMETHODCALLTYPE *OnUpdated )( + ITfPreservedKeyNotifySink * This, + /* [in] */ const TF_PRESERVEDKEY *pprekey); + + END_INTERFACE + } ITfPreservedKeyNotifySinkVtbl; + + interface ITfPreservedKeyNotifySink + { + CONST_VTBL struct ITfPreservedKeyNotifySinkVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfPreservedKeyNotifySink_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfPreservedKeyNotifySink_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfPreservedKeyNotifySink_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfPreservedKeyNotifySink_OnUpdated(This,pprekey) \ + ( (This)->lpVtbl -> OnUpdated(This,pprekey) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfPreservedKeyNotifySink_INTERFACE_DEFINED__ */ + + +#ifndef __ITfMessagePump_INTERFACE_DEFINED__ +#define __ITfMessagePump_INTERFACE_DEFINED__ + +/* interface ITfMessagePump */ +/* [unique][uuid][local][object] */ + + +EXTERN_C const IID IID_ITfMessagePump; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("8f1b8ad8-0b6b-4874-90c5-bd76011e8f7c") + ITfMessagePump : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE PeekMessageA( + /* [out] */ LPMSG pMsg, + /* [in] */ HWND hwnd, + /* [in] */ UINT wMsgFilterMin, + /* [in] */ UINT wMsgFilterMax, + /* [in] */ UINT wRemoveMsg, + /* [out] */ BOOL *pfResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetMessageA( + /* [out] */ LPMSG pMsg, + /* [in] */ HWND hwnd, + /* [in] */ UINT wMsgFilterMin, + /* [in] */ UINT wMsgFilterMax, + /* [out] */ BOOL *pfResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE PeekMessageW( + /* [out] */ LPMSG pMsg, + /* [in] */ HWND hwnd, + /* [in] */ UINT wMsgFilterMin, + /* [in] */ UINT wMsgFilterMax, + /* [in] */ UINT wRemoveMsg, + /* [out] */ BOOL *pfResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetMessageW( + /* [out] */ LPMSG pMsg, + /* [in] */ HWND hwnd, + /* [in] */ UINT wMsgFilterMin, + /* [in] */ UINT wMsgFilterMax, + /* [out] */ BOOL *pfResult) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfMessagePumpVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfMessagePump * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfMessagePump * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfMessagePump * This); + + HRESULT ( STDMETHODCALLTYPE *PeekMessageA )( + ITfMessagePump * This, + /* [out] */ LPMSG pMsg, + /* [in] */ HWND hwnd, + /* [in] */ UINT wMsgFilterMin, + /* [in] */ UINT wMsgFilterMax, + /* [in] */ UINT wRemoveMsg, + /* [out] */ BOOL *pfResult); + + HRESULT ( STDMETHODCALLTYPE *GetMessageA )( + ITfMessagePump * This, + /* [out] */ LPMSG pMsg, + /* [in] */ HWND hwnd, + /* [in] */ UINT wMsgFilterMin, + /* [in] */ UINT wMsgFilterMax, + /* [out] */ BOOL *pfResult); + + HRESULT ( STDMETHODCALLTYPE *PeekMessageW )( + ITfMessagePump * This, + /* [out] */ LPMSG pMsg, + /* [in] */ HWND hwnd, + /* [in] */ UINT wMsgFilterMin, + /* [in] */ UINT wMsgFilterMax, + /* [in] */ UINT wRemoveMsg, + /* [out] */ BOOL *pfResult); + + HRESULT ( STDMETHODCALLTYPE *GetMessageW )( + ITfMessagePump * This, + /* [out] */ LPMSG pMsg, + /* [in] */ HWND hwnd, + /* [in] */ UINT wMsgFilterMin, + /* [in] */ UINT wMsgFilterMax, + /* [out] */ BOOL *pfResult); + + END_INTERFACE + } ITfMessagePumpVtbl; + + interface ITfMessagePump + { + CONST_VTBL struct ITfMessagePumpVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfMessagePump_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfMessagePump_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfMessagePump_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfMessagePump_PeekMessageA(This,pMsg,hwnd,wMsgFilterMin,wMsgFilterMax,wRemoveMsg,pfResult) \ + ( (This)->lpVtbl -> PeekMessageA(This,pMsg,hwnd,wMsgFilterMin,wMsgFilterMax,wRemoveMsg,pfResult) ) + +#define ITfMessagePump_GetMessageA(This,pMsg,hwnd,wMsgFilterMin,wMsgFilterMax,pfResult) \ + ( (This)->lpVtbl -> GetMessageA(This,pMsg,hwnd,wMsgFilterMin,wMsgFilterMax,pfResult) ) + +#define ITfMessagePump_PeekMessageW(This,pMsg,hwnd,wMsgFilterMin,wMsgFilterMax,wRemoveMsg,pfResult) \ + ( (This)->lpVtbl -> PeekMessageW(This,pMsg,hwnd,wMsgFilterMin,wMsgFilterMax,wRemoveMsg,pfResult) ) + +#define ITfMessagePump_GetMessageW(This,pMsg,hwnd,wMsgFilterMin,wMsgFilterMax,pfResult) \ + ( (This)->lpVtbl -> GetMessageW(This,pMsg,hwnd,wMsgFilterMin,wMsgFilterMax,pfResult) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfMessagePump_INTERFACE_DEFINED__ */ + + +#ifndef __ITfThreadFocusSink_INTERFACE_DEFINED__ +#define __ITfThreadFocusSink_INTERFACE_DEFINED__ + +/* interface ITfThreadFocusSink */ +/* [unique][uuid][local][object] */ + + +EXTERN_C const IID IID_ITfThreadFocusSink; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("c0f1db0c-3a20-405c-a303-96b6010a885f") + ITfThreadFocusSink : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE OnSetThreadFocus( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnKillThreadFocus( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfThreadFocusSinkVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfThreadFocusSink * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfThreadFocusSink * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfThreadFocusSink * This); + + HRESULT ( STDMETHODCALLTYPE *OnSetThreadFocus )( + ITfThreadFocusSink * This); + + HRESULT ( STDMETHODCALLTYPE *OnKillThreadFocus )( + ITfThreadFocusSink * This); + + END_INTERFACE + } ITfThreadFocusSinkVtbl; + + interface ITfThreadFocusSink + { + CONST_VTBL struct ITfThreadFocusSinkVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfThreadFocusSink_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfThreadFocusSink_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfThreadFocusSink_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfThreadFocusSink_OnSetThreadFocus(This) \ + ( (This)->lpVtbl -> OnSetThreadFocus(This) ) + +#define ITfThreadFocusSink_OnKillThreadFocus(This) \ + ( (This)->lpVtbl -> OnKillThreadFocus(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfThreadFocusSink_INTERFACE_DEFINED__ */ + + +#ifndef __ITfTextInputProcessor_INTERFACE_DEFINED__ +#define __ITfTextInputProcessor_INTERFACE_DEFINED__ + +/* interface ITfTextInputProcessor */ +/* [unique][uuid][local][object] */ + + +EXTERN_C const IID IID_ITfTextInputProcessor; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("aa80e7f7-2021-11d2-93e0-0060b067b86e") + ITfTextInputProcessor : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Activate( + /* [in] */ ITfThreadMgr *ptim, + /* [in] */ TfClientId tid) = 0; + + virtual HRESULT STDMETHODCALLTYPE Deactivate( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfTextInputProcessorVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfTextInputProcessor * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfTextInputProcessor * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfTextInputProcessor * This); + + HRESULT ( STDMETHODCALLTYPE *Activate )( + ITfTextInputProcessor * This, + /* [in] */ ITfThreadMgr *ptim, + /* [in] */ TfClientId tid); + + HRESULT ( STDMETHODCALLTYPE *Deactivate )( + ITfTextInputProcessor * This); + + END_INTERFACE + } ITfTextInputProcessorVtbl; + + interface ITfTextInputProcessor + { + CONST_VTBL struct ITfTextInputProcessorVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfTextInputProcessor_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfTextInputProcessor_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfTextInputProcessor_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfTextInputProcessor_Activate(This,ptim,tid) \ + ( (This)->lpVtbl -> Activate(This,ptim,tid) ) + +#define ITfTextInputProcessor_Deactivate(This) \ + ( (This)->lpVtbl -> Deactivate(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfTextInputProcessor_INTERFACE_DEFINED__ */ + + +#ifndef __ITfTextInputProcessorEx_INTERFACE_DEFINED__ +#define __ITfTextInputProcessorEx_INTERFACE_DEFINED__ + +/* interface ITfTextInputProcessorEx */ +/* [unique][uuid][local][object] */ + + +EXTERN_C const IID IID_ITfTextInputProcessorEx; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("6e4e2102-f9cd-433d-b496-303ce03a6507") + ITfTextInputProcessorEx : public ITfTextInputProcessor + { + public: + virtual HRESULT STDMETHODCALLTYPE ActivateEx( + /* [in] */ ITfThreadMgr *ptim, + /* [in] */ TfClientId tid, + /* [in] */ DWORD dwFlags) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfTextInputProcessorExVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfTextInputProcessorEx * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfTextInputProcessorEx * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfTextInputProcessorEx * This); + + HRESULT ( STDMETHODCALLTYPE *Activate )( + ITfTextInputProcessorEx * This, + /* [in] */ ITfThreadMgr *ptim, + /* [in] */ TfClientId tid); + + HRESULT ( STDMETHODCALLTYPE *Deactivate )( + ITfTextInputProcessorEx * This); + + HRESULT ( STDMETHODCALLTYPE *ActivateEx )( + ITfTextInputProcessorEx * This, + /* [in] */ ITfThreadMgr *ptim, + /* [in] */ TfClientId tid, + /* [in] */ DWORD dwFlags); + + END_INTERFACE + } ITfTextInputProcessorExVtbl; + + interface ITfTextInputProcessorEx + { + CONST_VTBL struct ITfTextInputProcessorExVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfTextInputProcessorEx_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfTextInputProcessorEx_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfTextInputProcessorEx_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfTextInputProcessorEx_Activate(This,ptim,tid) \ + ( (This)->lpVtbl -> Activate(This,ptim,tid) ) + +#define ITfTextInputProcessorEx_Deactivate(This) \ + ( (This)->lpVtbl -> Deactivate(This) ) + + +#define ITfTextInputProcessorEx_ActivateEx(This,ptim,tid,dwFlags) \ + ( (This)->lpVtbl -> ActivateEx(This,ptim,tid,dwFlags) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfTextInputProcessorEx_INTERFACE_DEFINED__ */ + + +#ifndef __ITfClientId_INTERFACE_DEFINED__ +#define __ITfClientId_INTERFACE_DEFINED__ + +/* interface ITfClientId */ +/* [unique][uuid][local][object] */ + + +EXTERN_C const IID IID_ITfClientId; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("d60a7b49-1b9f-4be2-b702-47e9dc05dec3") + ITfClientId : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetClientId( + /* [in] */ REFCLSID rclsid, + /* [out] */ TfClientId *ptid) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfClientIdVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfClientId * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfClientId * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfClientId * This); + + HRESULT ( STDMETHODCALLTYPE *GetClientId )( + ITfClientId * This, + /* [in] */ REFCLSID rclsid, + /* [out] */ TfClientId *ptid); + + END_INTERFACE + } ITfClientIdVtbl; + + interface ITfClientId + { + CONST_VTBL struct ITfClientIdVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfClientId_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfClientId_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfClientId_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfClientId_GetClientId(This,rclsid,ptid) \ + ( (This)->lpVtbl -> GetClientId(This,rclsid,ptid) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfClientId_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_msctf_0000_0069 */ +/* [local] */ + +typedef /* [public][public][public][public][uuid] */ DECLSPEC_UUID("c4cc07f1-80cc-4a7b-bc54-98512782cbe3") +enum __MIDL___MIDL_itf_msctf_0000_0069_0001 + { TF_LS_NONE = 0, + TF_LS_SOLID = 1, + TF_LS_DOT = 2, + TF_LS_DASH = 3, + TF_LS_SQUIGGLE = 4 + } TF_DA_LINESTYLE; + +typedef /* [public][public][public][public][public][uuid] */ DECLSPEC_UUID("d9b92e21-084a-401b-9c64-1e6dad91a1ab") +enum __MIDL___MIDL_itf_msctf_0000_0069_0002 + { TF_CT_NONE = 0, + TF_CT_SYSCOLOR = 1, + TF_CT_COLORREF = 2 + } TF_DA_COLORTYPE; + +typedef /* [uuid] */ DECLSPEC_UUID("90d0cb5e-6520-4a0f-b47c-c39bd955f0d6") struct TF_DA_COLOR + { + TF_DA_COLORTYPE type; + union + { + int nIndex; + COLORREF cr; + } ; + } TF_DA_COLOR; + +typedef /* [public][public][public][public][uuid] */ DECLSPEC_UUID("33d2fe4b-6c24-4f67-8d75-3bc1819e4126") +enum __MIDL___MIDL_itf_msctf_0000_0069_0004 + { TF_ATTR_INPUT = 0, + TF_ATTR_TARGET_CONVERTED = 1, + TF_ATTR_CONVERTED = 2, + TF_ATTR_TARGET_NOTCONVERTED = 3, + TF_ATTR_INPUT_ERROR = 4, + TF_ATTR_FIXEDCONVERTED = 5, + TF_ATTR_OTHER = -1 + } TF_DA_ATTR_INFO; + +typedef /* [uuid] */ DECLSPEC_UUID("1bf1c305-419b-4182-a4d2-9bfadc3f021f") struct TF_DISPLAYATTRIBUTE + { + TF_DA_COLOR crText; + TF_DA_COLOR crBk; + TF_DA_LINESTYLE lsStyle; + BOOL fBoldLine; + TF_DA_COLOR crLine; + TF_DA_ATTR_INFO bAttr; + } TF_DISPLAYATTRIBUTE; + + + +extern RPC_IF_HANDLE __MIDL_itf_msctf_0000_0069_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_msctf_0000_0069_v0_0_s_ifspec; + +#ifndef __ITfDisplayAttributeInfo_INTERFACE_DEFINED__ +#define __ITfDisplayAttributeInfo_INTERFACE_DEFINED__ + +/* interface ITfDisplayAttributeInfo */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfDisplayAttributeInfo; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("70528852-2f26-4aea-8c96-215150578932") + ITfDisplayAttributeInfo : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetGUID( + /* [out] */ GUID *pguid) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDescription( + /* [out] */ BSTR *pbstrDesc) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetAttributeInfo( + /* [out] */ TF_DISPLAYATTRIBUTE *pda) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetAttributeInfo( + /* [in] */ const TF_DISPLAYATTRIBUTE *pda) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfDisplayAttributeInfoVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfDisplayAttributeInfo * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfDisplayAttributeInfo * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfDisplayAttributeInfo * This); + + HRESULT ( STDMETHODCALLTYPE *GetGUID )( + ITfDisplayAttributeInfo * This, + /* [out] */ GUID *pguid); + + HRESULT ( STDMETHODCALLTYPE *GetDescription )( + ITfDisplayAttributeInfo * This, + /* [out] */ BSTR *pbstrDesc); + + HRESULT ( STDMETHODCALLTYPE *GetAttributeInfo )( + ITfDisplayAttributeInfo * This, + /* [out] */ TF_DISPLAYATTRIBUTE *pda); + + HRESULT ( STDMETHODCALLTYPE *SetAttributeInfo )( + ITfDisplayAttributeInfo * This, + /* [in] */ const TF_DISPLAYATTRIBUTE *pda); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + ITfDisplayAttributeInfo * This); + + END_INTERFACE + } ITfDisplayAttributeInfoVtbl; + + interface ITfDisplayAttributeInfo + { + CONST_VTBL struct ITfDisplayAttributeInfoVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfDisplayAttributeInfo_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfDisplayAttributeInfo_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfDisplayAttributeInfo_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfDisplayAttributeInfo_GetGUID(This,pguid) \ + ( (This)->lpVtbl -> GetGUID(This,pguid) ) + +#define ITfDisplayAttributeInfo_GetDescription(This,pbstrDesc) \ + ( (This)->lpVtbl -> GetDescription(This,pbstrDesc) ) + +#define ITfDisplayAttributeInfo_GetAttributeInfo(This,pda) \ + ( (This)->lpVtbl -> GetAttributeInfo(This,pda) ) + +#define ITfDisplayAttributeInfo_SetAttributeInfo(This,pda) \ + ( (This)->lpVtbl -> SetAttributeInfo(This,pda) ) + +#define ITfDisplayAttributeInfo_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfDisplayAttributeInfo_INTERFACE_DEFINED__ */ + + +#ifndef __IEnumTfDisplayAttributeInfo_INTERFACE_DEFINED__ +#define __IEnumTfDisplayAttributeInfo_INTERFACE_DEFINED__ + +/* interface IEnumTfDisplayAttributeInfo */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_IEnumTfDisplayAttributeInfo; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("7cef04d7-cb75-4e80-a7ab-5f5bc7d332de") + IEnumTfDisplayAttributeInfo : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ IEnumTfDisplayAttributeInfo **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ ITfDisplayAttributeInfo **rgInfo, + /* [out] */ ULONG *pcFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG ulCount) = 0; + + }; + +#else /* C style interface */ + + typedef struct IEnumTfDisplayAttributeInfoVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IEnumTfDisplayAttributeInfo * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IEnumTfDisplayAttributeInfo * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IEnumTfDisplayAttributeInfo * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IEnumTfDisplayAttributeInfo * This, + /* [out] */ IEnumTfDisplayAttributeInfo **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IEnumTfDisplayAttributeInfo * This, + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ ITfDisplayAttributeInfo **rgInfo, + /* [out] */ ULONG *pcFetched); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IEnumTfDisplayAttributeInfo * This); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + IEnumTfDisplayAttributeInfo * This, + /* [in] */ ULONG ulCount); + + END_INTERFACE + } IEnumTfDisplayAttributeInfoVtbl; + + interface IEnumTfDisplayAttributeInfo + { + CONST_VTBL struct IEnumTfDisplayAttributeInfoVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IEnumTfDisplayAttributeInfo_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IEnumTfDisplayAttributeInfo_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IEnumTfDisplayAttributeInfo_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IEnumTfDisplayAttributeInfo_Clone(This,ppEnum) \ + ( (This)->lpVtbl -> Clone(This,ppEnum) ) + +#define IEnumTfDisplayAttributeInfo_Next(This,ulCount,rgInfo,pcFetched) \ + ( (This)->lpVtbl -> Next(This,ulCount,rgInfo,pcFetched) ) + +#define IEnumTfDisplayAttributeInfo_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define IEnumTfDisplayAttributeInfo_Skip(This,ulCount) \ + ( (This)->lpVtbl -> Skip(This,ulCount) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IEnumTfDisplayAttributeInfo_INTERFACE_DEFINED__ */ + + +#ifndef __ITfDisplayAttributeProvider_INTERFACE_DEFINED__ +#define __ITfDisplayAttributeProvider_INTERFACE_DEFINED__ + +/* interface ITfDisplayAttributeProvider */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfDisplayAttributeProvider; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("fee47777-163c-4769-996a-6e9c50ad8f54") + ITfDisplayAttributeProvider : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE EnumDisplayAttributeInfo( + /* [out] */ IEnumTfDisplayAttributeInfo **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDisplayAttributeInfo( + /* [in] */ REFGUID guid, + /* [out] */ ITfDisplayAttributeInfo **ppInfo) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfDisplayAttributeProviderVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfDisplayAttributeProvider * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfDisplayAttributeProvider * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfDisplayAttributeProvider * This); + + HRESULT ( STDMETHODCALLTYPE *EnumDisplayAttributeInfo )( + ITfDisplayAttributeProvider * This, + /* [out] */ IEnumTfDisplayAttributeInfo **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *GetDisplayAttributeInfo )( + ITfDisplayAttributeProvider * This, + /* [in] */ REFGUID guid, + /* [out] */ ITfDisplayAttributeInfo **ppInfo); + + END_INTERFACE + } ITfDisplayAttributeProviderVtbl; + + interface ITfDisplayAttributeProvider + { + CONST_VTBL struct ITfDisplayAttributeProviderVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfDisplayAttributeProvider_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfDisplayAttributeProvider_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfDisplayAttributeProvider_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfDisplayAttributeProvider_EnumDisplayAttributeInfo(This,ppEnum) \ + ( (This)->lpVtbl -> EnumDisplayAttributeInfo(This,ppEnum) ) + +#define ITfDisplayAttributeProvider_GetDisplayAttributeInfo(This,guid,ppInfo) \ + ( (This)->lpVtbl -> GetDisplayAttributeInfo(This,guid,ppInfo) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfDisplayAttributeProvider_INTERFACE_DEFINED__ */ + + +#ifndef __ITfDisplayAttributeMgr_INTERFACE_DEFINED__ +#define __ITfDisplayAttributeMgr_INTERFACE_DEFINED__ + +/* interface ITfDisplayAttributeMgr */ +/* [unique][uuid][local][object] */ + + +EXTERN_C const IID IID_ITfDisplayAttributeMgr; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("8ded7393-5db1-475c-9e71-a39111b0ff67") + ITfDisplayAttributeMgr : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE OnUpdateInfo( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnumDisplayAttributeInfo( + /* [out] */ IEnumTfDisplayAttributeInfo **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDisplayAttributeInfo( + /* [in] */ REFGUID guid, + /* [out] */ ITfDisplayAttributeInfo **ppInfo, + /* [out] */ CLSID *pclsidOwner) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfDisplayAttributeMgrVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfDisplayAttributeMgr * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfDisplayAttributeMgr * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfDisplayAttributeMgr * This); + + HRESULT ( STDMETHODCALLTYPE *OnUpdateInfo )( + ITfDisplayAttributeMgr * This); + + HRESULT ( STDMETHODCALLTYPE *EnumDisplayAttributeInfo )( + ITfDisplayAttributeMgr * This, + /* [out] */ IEnumTfDisplayAttributeInfo **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *GetDisplayAttributeInfo )( + ITfDisplayAttributeMgr * This, + /* [in] */ REFGUID guid, + /* [out] */ ITfDisplayAttributeInfo **ppInfo, + /* [out] */ CLSID *pclsidOwner); + + END_INTERFACE + } ITfDisplayAttributeMgrVtbl; + + interface ITfDisplayAttributeMgr + { + CONST_VTBL struct ITfDisplayAttributeMgrVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfDisplayAttributeMgr_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfDisplayAttributeMgr_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfDisplayAttributeMgr_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfDisplayAttributeMgr_OnUpdateInfo(This) \ + ( (This)->lpVtbl -> OnUpdateInfo(This) ) + +#define ITfDisplayAttributeMgr_EnumDisplayAttributeInfo(This,ppEnum) \ + ( (This)->lpVtbl -> EnumDisplayAttributeInfo(This,ppEnum) ) + +#define ITfDisplayAttributeMgr_GetDisplayAttributeInfo(This,guid,ppInfo,pclsidOwner) \ + ( (This)->lpVtbl -> GetDisplayAttributeInfo(This,guid,ppInfo,pclsidOwner) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfDisplayAttributeMgr_INTERFACE_DEFINED__ */ + + +#ifndef __ITfDisplayAttributeNotifySink_INTERFACE_DEFINED__ +#define __ITfDisplayAttributeNotifySink_INTERFACE_DEFINED__ + +/* interface ITfDisplayAttributeNotifySink */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfDisplayAttributeNotifySink; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("ad56f402-e162-4f25-908f-7d577cf9bda9") + ITfDisplayAttributeNotifySink : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE OnUpdateInfo( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfDisplayAttributeNotifySinkVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfDisplayAttributeNotifySink * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfDisplayAttributeNotifySink * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfDisplayAttributeNotifySink * This); + + HRESULT ( STDMETHODCALLTYPE *OnUpdateInfo )( + ITfDisplayAttributeNotifySink * This); + + END_INTERFACE + } ITfDisplayAttributeNotifySinkVtbl; + + interface ITfDisplayAttributeNotifySink + { + CONST_VTBL struct ITfDisplayAttributeNotifySinkVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfDisplayAttributeNotifySink_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfDisplayAttributeNotifySink_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfDisplayAttributeNotifySink_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfDisplayAttributeNotifySink_OnUpdateInfo(This) \ + ( (This)->lpVtbl -> OnUpdateInfo(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfDisplayAttributeNotifySink_INTERFACE_DEFINED__ */ + + +#ifndef __ITfCategoryMgr_INTERFACE_DEFINED__ +#define __ITfCategoryMgr_INTERFACE_DEFINED__ + +/* interface ITfCategoryMgr */ +/* [unique][uuid][local][object] */ + + +EXTERN_C const IID IID_ITfCategoryMgr; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("c3acefb5-f69d-4905-938f-fcadcf4be830") + ITfCategoryMgr : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE RegisterCategory( + /* [in] */ REFCLSID rclsid, + /* [in] */ REFGUID rcatid, + /* [in] */ REFGUID rguid) = 0; + + virtual HRESULT STDMETHODCALLTYPE UnregisterCategory( + /* [in] */ REFCLSID rclsid, + /* [in] */ REFGUID rcatid, + /* [in] */ REFGUID rguid) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnumCategoriesInItem( + /* [in] */ REFGUID rguid, + /* [out] */ IEnumGUID **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnumItemsInCategory( + /* [in] */ REFGUID rcatid, + /* [out] */ IEnumGUID **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE FindClosestCategory( + /* [in] */ REFGUID rguid, + /* [out] */ GUID *pcatid, + /* [size_is][in] */ const GUID **ppcatidList, + /* [in] */ ULONG ulCount) = 0; + + virtual HRESULT STDMETHODCALLTYPE RegisterGUIDDescription( + /* [in] */ REFCLSID rclsid, + /* [in] */ REFGUID rguid, + /* [size_is][in] */ const WCHAR *pchDesc, + /* [in] */ ULONG cch) = 0; + + virtual HRESULT STDMETHODCALLTYPE UnregisterGUIDDescription( + /* [in] */ REFCLSID rclsid, + /* [in] */ REFGUID rguid) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetGUIDDescription( + /* [in] */ REFGUID rguid, + /* [out] */ BSTR *pbstrDesc) = 0; + + virtual HRESULT STDMETHODCALLTYPE RegisterGUIDDWORD( + /* [in] */ REFCLSID rclsid, + /* [in] */ REFGUID rguid, + /* [in] */ DWORD dw) = 0; + + virtual HRESULT STDMETHODCALLTYPE UnregisterGUIDDWORD( + /* [in] */ REFCLSID rclsid, + /* [in] */ REFGUID rguid) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetGUIDDWORD( + /* [in] */ REFGUID rguid, + /* [out] */ DWORD *pdw) = 0; + + virtual HRESULT STDMETHODCALLTYPE RegisterGUID( + /* [in] */ REFGUID rguid, + /* [out] */ TfGuidAtom *pguidatom) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetGUID( + /* [in] */ TfGuidAtom guidatom, + /* [out] */ GUID *pguid) = 0; + + virtual HRESULT STDMETHODCALLTYPE IsEqualTfGuidAtom( + /* [in] */ TfGuidAtom guidatom, + /* [in] */ REFGUID rguid, + /* [out] */ BOOL *pfEqual) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfCategoryMgrVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfCategoryMgr * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfCategoryMgr * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfCategoryMgr * This); + + HRESULT ( STDMETHODCALLTYPE *RegisterCategory )( + ITfCategoryMgr * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ REFGUID rcatid, + /* [in] */ REFGUID rguid); + + HRESULT ( STDMETHODCALLTYPE *UnregisterCategory )( + ITfCategoryMgr * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ REFGUID rcatid, + /* [in] */ REFGUID rguid); + + HRESULT ( STDMETHODCALLTYPE *EnumCategoriesInItem )( + ITfCategoryMgr * This, + /* [in] */ REFGUID rguid, + /* [out] */ IEnumGUID **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *EnumItemsInCategory )( + ITfCategoryMgr * This, + /* [in] */ REFGUID rcatid, + /* [out] */ IEnumGUID **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *FindClosestCategory )( + ITfCategoryMgr * This, + /* [in] */ REFGUID rguid, + /* [out] */ GUID *pcatid, + /* [size_is][in] */ const GUID **ppcatidList, + /* [in] */ ULONG ulCount); + + HRESULT ( STDMETHODCALLTYPE *RegisterGUIDDescription )( + ITfCategoryMgr * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ REFGUID rguid, + /* [size_is][in] */ const WCHAR *pchDesc, + /* [in] */ ULONG cch); + + HRESULT ( STDMETHODCALLTYPE *UnregisterGUIDDescription )( + ITfCategoryMgr * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ REFGUID rguid); + + HRESULT ( STDMETHODCALLTYPE *GetGUIDDescription )( + ITfCategoryMgr * This, + /* [in] */ REFGUID rguid, + /* [out] */ BSTR *pbstrDesc); + + HRESULT ( STDMETHODCALLTYPE *RegisterGUIDDWORD )( + ITfCategoryMgr * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ REFGUID rguid, + /* [in] */ DWORD dw); + + HRESULT ( STDMETHODCALLTYPE *UnregisterGUIDDWORD )( + ITfCategoryMgr * This, + /* [in] */ REFCLSID rclsid, + /* [in] */ REFGUID rguid); + + HRESULT ( STDMETHODCALLTYPE *GetGUIDDWORD )( + ITfCategoryMgr * This, + /* [in] */ REFGUID rguid, + /* [out] */ DWORD *pdw); + + HRESULT ( STDMETHODCALLTYPE *RegisterGUID )( + ITfCategoryMgr * This, + /* [in] */ REFGUID rguid, + /* [out] */ TfGuidAtom *pguidatom); + + HRESULT ( STDMETHODCALLTYPE *GetGUID )( + ITfCategoryMgr * This, + /* [in] */ TfGuidAtom guidatom, + /* [out] */ GUID *pguid); + + HRESULT ( STDMETHODCALLTYPE *IsEqualTfGuidAtom )( + ITfCategoryMgr * This, + /* [in] */ TfGuidAtom guidatom, + /* [in] */ REFGUID rguid, + /* [out] */ BOOL *pfEqual); + + END_INTERFACE + } ITfCategoryMgrVtbl; + + interface ITfCategoryMgr + { + CONST_VTBL struct ITfCategoryMgrVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfCategoryMgr_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfCategoryMgr_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfCategoryMgr_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfCategoryMgr_RegisterCategory(This,rclsid,rcatid,rguid) \ + ( (This)->lpVtbl -> RegisterCategory(This,rclsid,rcatid,rguid) ) + +#define ITfCategoryMgr_UnregisterCategory(This,rclsid,rcatid,rguid) \ + ( (This)->lpVtbl -> UnregisterCategory(This,rclsid,rcatid,rguid) ) + +#define ITfCategoryMgr_EnumCategoriesInItem(This,rguid,ppEnum) \ + ( (This)->lpVtbl -> EnumCategoriesInItem(This,rguid,ppEnum) ) + +#define ITfCategoryMgr_EnumItemsInCategory(This,rcatid,ppEnum) \ + ( (This)->lpVtbl -> EnumItemsInCategory(This,rcatid,ppEnum) ) + +#define ITfCategoryMgr_FindClosestCategory(This,rguid,pcatid,ppcatidList,ulCount) \ + ( (This)->lpVtbl -> FindClosestCategory(This,rguid,pcatid,ppcatidList,ulCount) ) + +#define ITfCategoryMgr_RegisterGUIDDescription(This,rclsid,rguid,pchDesc,cch) \ + ( (This)->lpVtbl -> RegisterGUIDDescription(This,rclsid,rguid,pchDesc,cch) ) + +#define ITfCategoryMgr_UnregisterGUIDDescription(This,rclsid,rguid) \ + ( (This)->lpVtbl -> UnregisterGUIDDescription(This,rclsid,rguid) ) + +#define ITfCategoryMgr_GetGUIDDescription(This,rguid,pbstrDesc) \ + ( (This)->lpVtbl -> GetGUIDDescription(This,rguid,pbstrDesc) ) + +#define ITfCategoryMgr_RegisterGUIDDWORD(This,rclsid,rguid,dw) \ + ( (This)->lpVtbl -> RegisterGUIDDWORD(This,rclsid,rguid,dw) ) + +#define ITfCategoryMgr_UnregisterGUIDDWORD(This,rclsid,rguid) \ + ( (This)->lpVtbl -> UnregisterGUIDDWORD(This,rclsid,rguid) ) + +#define ITfCategoryMgr_GetGUIDDWORD(This,rguid,pdw) \ + ( (This)->lpVtbl -> GetGUIDDWORD(This,rguid,pdw) ) + +#define ITfCategoryMgr_RegisterGUID(This,rguid,pguidatom) \ + ( (This)->lpVtbl -> RegisterGUID(This,rguid,pguidatom) ) + +#define ITfCategoryMgr_GetGUID(This,guidatom,pguid) \ + ( (This)->lpVtbl -> GetGUID(This,guidatom,pguid) ) + +#define ITfCategoryMgr_IsEqualTfGuidAtom(This,guidatom,rguid,pfEqual) \ + ( (This)->lpVtbl -> IsEqualTfGuidAtom(This,guidatom,rguid,pfEqual) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfCategoryMgr_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_msctf_0000_0075 */ +/* [local] */ + +#define TF_INVALID_COOKIE ( 0xffffffff ) + + + +extern RPC_IF_HANDLE __MIDL_itf_msctf_0000_0075_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_msctf_0000_0075_v0_0_s_ifspec; + +#ifndef __ITfSource_INTERFACE_DEFINED__ +#define __ITfSource_INTERFACE_DEFINED__ + +/* interface ITfSource */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfSource; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("4ea48a35-60ae-446f-8fd6-e6a8d82459f7") + ITfSource : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE AdviseSink( + /* [in] */ REFIID riid, + /* [iid_is][in] */ IUnknown *punk, + /* [out] */ DWORD *pdwCookie) = 0; + + virtual HRESULT STDMETHODCALLTYPE UnadviseSink( + /* [in] */ DWORD dwCookie) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfSourceVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfSource * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfSource * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfSource * This); + + HRESULT ( STDMETHODCALLTYPE *AdviseSink )( + ITfSource * This, + /* [in] */ REFIID riid, + /* [iid_is][in] */ IUnknown *punk, + /* [out] */ DWORD *pdwCookie); + + HRESULT ( STDMETHODCALLTYPE *UnadviseSink )( + ITfSource * This, + /* [in] */ DWORD dwCookie); + + END_INTERFACE + } ITfSourceVtbl; + + interface ITfSource + { + CONST_VTBL struct ITfSourceVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfSource_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfSource_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfSource_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfSource_AdviseSink(This,riid,punk,pdwCookie) \ + ( (This)->lpVtbl -> AdviseSink(This,riid,punk,pdwCookie) ) + +#define ITfSource_UnadviseSink(This,dwCookie) \ + ( (This)->lpVtbl -> UnadviseSink(This,dwCookie) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfSource_INTERFACE_DEFINED__ */ + + +#ifndef __ITfSourceSingle_INTERFACE_DEFINED__ +#define __ITfSourceSingle_INTERFACE_DEFINED__ + +/* interface ITfSourceSingle */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfSourceSingle; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("73131f9c-56a9-49dd-b0ee-d046633f7528") + ITfSourceSingle : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE AdviseSingleSink( + /* [in] */ TfClientId tid, + /* [in] */ REFIID riid, + /* [iid_is][in] */ IUnknown *punk) = 0; + + virtual HRESULT STDMETHODCALLTYPE UnadviseSingleSink( + /* [in] */ TfClientId tid, + /* [in] */ REFIID riid) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfSourceSingleVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfSourceSingle * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfSourceSingle * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfSourceSingle * This); + + HRESULT ( STDMETHODCALLTYPE *AdviseSingleSink )( + ITfSourceSingle * This, + /* [in] */ TfClientId tid, + /* [in] */ REFIID riid, + /* [iid_is][in] */ IUnknown *punk); + + HRESULT ( STDMETHODCALLTYPE *UnadviseSingleSink )( + ITfSourceSingle * This, + /* [in] */ TfClientId tid, + /* [in] */ REFIID riid); + + END_INTERFACE + } ITfSourceSingleVtbl; + + interface ITfSourceSingle + { + CONST_VTBL struct ITfSourceSingleVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfSourceSingle_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfSourceSingle_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfSourceSingle_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfSourceSingle_AdviseSingleSink(This,tid,riid,punk) \ + ( (This)->lpVtbl -> AdviseSingleSink(This,tid,riid,punk) ) + +#define ITfSourceSingle_UnadviseSingleSink(This,tid,riid) \ + ( (This)->lpVtbl -> UnadviseSingleSink(This,tid,riid) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfSourceSingle_INTERFACE_DEFINED__ */ + + +#ifndef __ITfUIElementMgr_INTERFACE_DEFINED__ +#define __ITfUIElementMgr_INTERFACE_DEFINED__ + +/* interface ITfUIElementMgr */ +/* [unique][uuid][local][object] */ + + +EXTERN_C const IID IID_ITfUIElementMgr; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("ea1ea135-19df-11d7-a6d2-00065b84435c") + ITfUIElementMgr : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE BeginUIElement( + /* [in] */ ITfUIElement *pElement, + /* [out][in] */ BOOL *pbShow, + /* [out] */ DWORD *pdwUIElementId) = 0; + + virtual HRESULT STDMETHODCALLTYPE UpdateUIElement( + /* [in] */ DWORD dwUIElementId) = 0; + + virtual HRESULT STDMETHODCALLTYPE EndUIElement( + /* [in] */ DWORD dwUIElementId) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetUIElement( + /* [in] */ DWORD dwUIELementId, + /* [out] */ ITfUIElement **ppElement) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnumUIElements( + /* [out] */ IEnumTfUIElements **ppEnum) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfUIElementMgrVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfUIElementMgr * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfUIElementMgr * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfUIElementMgr * This); + + HRESULT ( STDMETHODCALLTYPE *BeginUIElement )( + ITfUIElementMgr * This, + /* [in] */ ITfUIElement *pElement, + /* [out][in] */ BOOL *pbShow, + /* [out] */ DWORD *pdwUIElementId); + + HRESULT ( STDMETHODCALLTYPE *UpdateUIElement )( + ITfUIElementMgr * This, + /* [in] */ DWORD dwUIElementId); + + HRESULT ( STDMETHODCALLTYPE *EndUIElement )( + ITfUIElementMgr * This, + /* [in] */ DWORD dwUIElementId); + + HRESULT ( STDMETHODCALLTYPE *GetUIElement )( + ITfUIElementMgr * This, + /* [in] */ DWORD dwUIELementId, + /* [out] */ ITfUIElement **ppElement); + + HRESULT ( STDMETHODCALLTYPE *EnumUIElements )( + ITfUIElementMgr * This, + /* [out] */ IEnumTfUIElements **ppEnum); + + END_INTERFACE + } ITfUIElementMgrVtbl; + + interface ITfUIElementMgr + { + CONST_VTBL struct ITfUIElementMgrVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfUIElementMgr_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfUIElementMgr_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfUIElementMgr_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfUIElementMgr_BeginUIElement(This,pElement,pbShow,pdwUIElementId) \ + ( (This)->lpVtbl -> BeginUIElement(This,pElement,pbShow,pdwUIElementId) ) + +#define ITfUIElementMgr_UpdateUIElement(This,dwUIElementId) \ + ( (This)->lpVtbl -> UpdateUIElement(This,dwUIElementId) ) + +#define ITfUIElementMgr_EndUIElement(This,dwUIElementId) \ + ( (This)->lpVtbl -> EndUIElement(This,dwUIElementId) ) + +#define ITfUIElementMgr_GetUIElement(This,dwUIELementId,ppElement) \ + ( (This)->lpVtbl -> GetUIElement(This,dwUIELementId,ppElement) ) + +#define ITfUIElementMgr_EnumUIElements(This,ppEnum) \ + ( (This)->lpVtbl -> EnumUIElements(This,ppEnum) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfUIElementMgr_INTERFACE_DEFINED__ */ + + +#ifndef __IEnumTfUIElements_INTERFACE_DEFINED__ +#define __IEnumTfUIElements_INTERFACE_DEFINED__ + +/* interface IEnumTfUIElements */ +/* [unique][uuid][local][object] */ + + +EXTERN_C const IID IID_IEnumTfUIElements; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("887aa91e-acba-4931-84da-3c5208cf543f") + IEnumTfUIElements : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ IEnumTfUIElements **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ ITfUIElement **ppElement, + /* [out] */ ULONG *pcFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG ulCount) = 0; + + }; + +#else /* C style interface */ + + typedef struct IEnumTfUIElementsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IEnumTfUIElements * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IEnumTfUIElements * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IEnumTfUIElements * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IEnumTfUIElements * This, + /* [out] */ IEnumTfUIElements **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IEnumTfUIElements * This, + /* [in] */ ULONG ulCount, + /* [length_is][size_is][out] */ ITfUIElement **ppElement, + /* [out] */ ULONG *pcFetched); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IEnumTfUIElements * This); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + IEnumTfUIElements * This, + /* [in] */ ULONG ulCount); + + END_INTERFACE + } IEnumTfUIElementsVtbl; + + interface IEnumTfUIElements + { + CONST_VTBL struct IEnumTfUIElementsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IEnumTfUIElements_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IEnumTfUIElements_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IEnumTfUIElements_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IEnumTfUIElements_Clone(This,ppEnum) \ + ( (This)->lpVtbl -> Clone(This,ppEnum) ) + +#define IEnumTfUIElements_Next(This,ulCount,ppElement,pcFetched) \ + ( (This)->lpVtbl -> Next(This,ulCount,ppElement,pcFetched) ) + +#define IEnumTfUIElements_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define IEnumTfUIElements_Skip(This,ulCount) \ + ( (This)->lpVtbl -> Skip(This,ulCount) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IEnumTfUIElements_INTERFACE_DEFINED__ */ + + +#ifndef __ITfUIElementSink_INTERFACE_DEFINED__ +#define __ITfUIElementSink_INTERFACE_DEFINED__ + +/* interface ITfUIElementSink */ +/* [unique][uuid][local][object] */ + + +EXTERN_C const IID IID_ITfUIElementSink; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("ea1ea136-19df-11d7-a6d2-00065b84435c") + ITfUIElementSink : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE BeginUIElement( + /* [in] */ DWORD dwUIElementId, + /* [out][in] */ BOOL *pbShow) = 0; + + virtual HRESULT STDMETHODCALLTYPE UpdateUIElement( + /* [in] */ DWORD dwUIElementId) = 0; + + virtual HRESULT STDMETHODCALLTYPE EndUIElement( + /* [in] */ DWORD dwUIElementId) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfUIElementSinkVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfUIElementSink * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfUIElementSink * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfUIElementSink * This); + + HRESULT ( STDMETHODCALLTYPE *BeginUIElement )( + ITfUIElementSink * This, + /* [in] */ DWORD dwUIElementId, + /* [out][in] */ BOOL *pbShow); + + HRESULT ( STDMETHODCALLTYPE *UpdateUIElement )( + ITfUIElementSink * This, + /* [in] */ DWORD dwUIElementId); + + HRESULT ( STDMETHODCALLTYPE *EndUIElement )( + ITfUIElementSink * This, + /* [in] */ DWORD dwUIElementId); + + END_INTERFACE + } ITfUIElementSinkVtbl; + + interface ITfUIElementSink + { + CONST_VTBL struct ITfUIElementSinkVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfUIElementSink_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfUIElementSink_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfUIElementSink_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfUIElementSink_BeginUIElement(This,dwUIElementId,pbShow) \ + ( (This)->lpVtbl -> BeginUIElement(This,dwUIElementId,pbShow) ) + +#define ITfUIElementSink_UpdateUIElement(This,dwUIElementId) \ + ( (This)->lpVtbl -> UpdateUIElement(This,dwUIElementId) ) + +#define ITfUIElementSink_EndUIElement(This,dwUIElementId) \ + ( (This)->lpVtbl -> EndUIElement(This,dwUIElementId) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfUIElementSink_INTERFACE_DEFINED__ */ + + +#ifndef __ITfUIElement_INTERFACE_DEFINED__ +#define __ITfUIElement_INTERFACE_DEFINED__ + +/* interface ITfUIElement */ +/* [unique][uuid][local][object] */ + + +EXTERN_C const IID IID_ITfUIElement; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("ea1ea137-19df-11d7-a6d2-00065b84435c") + ITfUIElement : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetDescription( + /* [out] */ BSTR *pbstrDescription) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetGUID( + /* [out] */ GUID *pguid) = 0; + + virtual HRESULT STDMETHODCALLTYPE Show( + /* [in] */ BOOL bShow) = 0; + + virtual HRESULT STDMETHODCALLTYPE IsShown( + /* [out] */ BOOL *pbShow) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfUIElementVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfUIElement * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfUIElement * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfUIElement * This); + + HRESULT ( STDMETHODCALLTYPE *GetDescription )( + ITfUIElement * This, + /* [out] */ BSTR *pbstrDescription); + + HRESULT ( STDMETHODCALLTYPE *GetGUID )( + ITfUIElement * This, + /* [out] */ GUID *pguid); + + HRESULT ( STDMETHODCALLTYPE *Show )( + ITfUIElement * This, + /* [in] */ BOOL bShow); + + HRESULT ( STDMETHODCALLTYPE *IsShown )( + ITfUIElement * This, + /* [out] */ BOOL *pbShow); + + END_INTERFACE + } ITfUIElementVtbl; + + interface ITfUIElement + { + CONST_VTBL struct ITfUIElementVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfUIElement_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfUIElement_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfUIElement_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfUIElement_GetDescription(This,pbstrDescription) \ + ( (This)->lpVtbl -> GetDescription(This,pbstrDescription) ) + +#define ITfUIElement_GetGUID(This,pguid) \ + ( (This)->lpVtbl -> GetGUID(This,pguid) ) + +#define ITfUIElement_Show(This,bShow) \ + ( (This)->lpVtbl -> Show(This,bShow) ) + +#define ITfUIElement_IsShown(This,pbShow) \ + ( (This)->lpVtbl -> IsShown(This,pbShow) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfUIElement_INTERFACE_DEFINED__ */ + + +#ifndef __ITfCandidateListUIElement_INTERFACE_DEFINED__ +#define __ITfCandidateListUIElement_INTERFACE_DEFINED__ + +/* interface ITfCandidateListUIElement */ +/* [unique][uuid][local][object] */ + + +EXTERN_C const IID IID_ITfCandidateListUIElement; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("ea1ea138-19df-11d7-a6d2-00065b84435c") + ITfCandidateListUIElement : public ITfUIElement + { + public: + virtual HRESULT STDMETHODCALLTYPE GetUpdatedFlags( + /* [out] */ DWORD *pdwFlags) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDocumentMgr( + /* [out] */ ITfDocumentMgr **ppdim) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCount( + /* [out] */ UINT *puCount) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetSelection( + /* [out] */ UINT *puIndex) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetString( + /* [in] */ UINT uIndex, + /* [out] */ BSTR *pstr) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetPageIndex( + /* [length_is][size_is][out] */ UINT *pIndex, + /* [in] */ UINT uSize, + /* [out] */ UINT *puPageCnt) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetPageIndex( + /* [size_is][in] */ UINT *pIndex, + /* [in] */ UINT uPageCnt) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCurrentPage( + /* [out] */ UINT *puPage) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfCandidateListUIElementVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfCandidateListUIElement * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfCandidateListUIElement * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfCandidateListUIElement * This); + + HRESULT ( STDMETHODCALLTYPE *GetDescription )( + ITfCandidateListUIElement * This, + /* [out] */ BSTR *pbstrDescription); + + HRESULT ( STDMETHODCALLTYPE *GetGUID )( + ITfCandidateListUIElement * This, + /* [out] */ GUID *pguid); + + HRESULT ( STDMETHODCALLTYPE *Show )( + ITfCandidateListUIElement * This, + /* [in] */ BOOL bShow); + + HRESULT ( STDMETHODCALLTYPE *IsShown )( + ITfCandidateListUIElement * This, + /* [out] */ BOOL *pbShow); + + HRESULT ( STDMETHODCALLTYPE *GetUpdatedFlags )( + ITfCandidateListUIElement * This, + /* [out] */ DWORD *pdwFlags); + + HRESULT ( STDMETHODCALLTYPE *GetDocumentMgr )( + ITfCandidateListUIElement * This, + /* [out] */ ITfDocumentMgr **ppdim); + + HRESULT ( STDMETHODCALLTYPE *GetCount )( + ITfCandidateListUIElement * This, + /* [out] */ UINT *puCount); + + HRESULT ( STDMETHODCALLTYPE *GetSelection )( + ITfCandidateListUIElement * This, + /* [out] */ UINT *puIndex); + + HRESULT ( STDMETHODCALLTYPE *GetString )( + ITfCandidateListUIElement * This, + /* [in] */ UINT uIndex, + /* [out] */ BSTR *pstr); + + HRESULT ( STDMETHODCALLTYPE *GetPageIndex )( + ITfCandidateListUIElement * This, + /* [length_is][size_is][out] */ UINT *pIndex, + /* [in] */ UINT uSize, + /* [out] */ UINT *puPageCnt); + + HRESULT ( STDMETHODCALLTYPE *SetPageIndex )( + ITfCandidateListUIElement * This, + /* [size_is][in] */ UINT *pIndex, + /* [in] */ UINT uPageCnt); + + HRESULT ( STDMETHODCALLTYPE *GetCurrentPage )( + ITfCandidateListUIElement * This, + /* [out] */ UINT *puPage); + + END_INTERFACE + } ITfCandidateListUIElementVtbl; + + interface ITfCandidateListUIElement + { + CONST_VTBL struct ITfCandidateListUIElementVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfCandidateListUIElement_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfCandidateListUIElement_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfCandidateListUIElement_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfCandidateListUIElement_GetDescription(This,pbstrDescription) \ + ( (This)->lpVtbl -> GetDescription(This,pbstrDescription) ) + +#define ITfCandidateListUIElement_GetGUID(This,pguid) \ + ( (This)->lpVtbl -> GetGUID(This,pguid) ) + +#define ITfCandidateListUIElement_Show(This,bShow) \ + ( (This)->lpVtbl -> Show(This,bShow) ) + +#define ITfCandidateListUIElement_IsShown(This,pbShow) \ + ( (This)->lpVtbl -> IsShown(This,pbShow) ) + + +#define ITfCandidateListUIElement_GetUpdatedFlags(This,pdwFlags) \ + ( (This)->lpVtbl -> GetUpdatedFlags(This,pdwFlags) ) + +#define ITfCandidateListUIElement_GetDocumentMgr(This,ppdim) \ + ( (This)->lpVtbl -> GetDocumentMgr(This,ppdim) ) + +#define ITfCandidateListUIElement_GetCount(This,puCount) \ + ( (This)->lpVtbl -> GetCount(This,puCount) ) + +#define ITfCandidateListUIElement_GetSelection(This,puIndex) \ + ( (This)->lpVtbl -> GetSelection(This,puIndex) ) + +#define ITfCandidateListUIElement_GetString(This,uIndex,pstr) \ + ( (This)->lpVtbl -> GetString(This,uIndex,pstr) ) + +#define ITfCandidateListUIElement_GetPageIndex(This,pIndex,uSize,puPageCnt) \ + ( (This)->lpVtbl -> GetPageIndex(This,pIndex,uSize,puPageCnt) ) + +#define ITfCandidateListUIElement_SetPageIndex(This,pIndex,uPageCnt) \ + ( (This)->lpVtbl -> SetPageIndex(This,pIndex,uPageCnt) ) + +#define ITfCandidateListUIElement_GetCurrentPage(This,puPage) \ + ( (This)->lpVtbl -> GetCurrentPage(This,puPage) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfCandidateListUIElement_INTERFACE_DEFINED__ */ + + +#ifndef __ITfCandidateListUIElementBehavior_INTERFACE_DEFINED__ +#define __ITfCandidateListUIElementBehavior_INTERFACE_DEFINED__ + +/* interface ITfCandidateListUIElementBehavior */ +/* [unique][uuid][local][object] */ + + +EXTERN_C const IID IID_ITfCandidateListUIElementBehavior; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("85fad185-58ce-497a-9460-355366b64b9a") + ITfCandidateListUIElementBehavior : public ITfCandidateListUIElement + { + public: + virtual HRESULT STDMETHODCALLTYPE SetSelection( + /* [in] */ UINT nIndex) = 0; + + virtual HRESULT STDMETHODCALLTYPE Finalize( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Abort( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfCandidateListUIElementBehaviorVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfCandidateListUIElementBehavior * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfCandidateListUIElementBehavior * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfCandidateListUIElementBehavior * This); + + HRESULT ( STDMETHODCALLTYPE *GetDescription )( + ITfCandidateListUIElementBehavior * This, + /* [out] */ BSTR *pbstrDescription); + + HRESULT ( STDMETHODCALLTYPE *GetGUID )( + ITfCandidateListUIElementBehavior * This, + /* [out] */ GUID *pguid); + + HRESULT ( STDMETHODCALLTYPE *Show )( + ITfCandidateListUIElementBehavior * This, + /* [in] */ BOOL bShow); + + HRESULT ( STDMETHODCALLTYPE *IsShown )( + ITfCandidateListUIElementBehavior * This, + /* [out] */ BOOL *pbShow); + + HRESULT ( STDMETHODCALLTYPE *GetUpdatedFlags )( + ITfCandidateListUIElementBehavior * This, + /* [out] */ DWORD *pdwFlags); + + HRESULT ( STDMETHODCALLTYPE *GetDocumentMgr )( + ITfCandidateListUIElementBehavior * This, + /* [out] */ ITfDocumentMgr **ppdim); + + HRESULT ( STDMETHODCALLTYPE *GetCount )( + ITfCandidateListUIElementBehavior * This, + /* [out] */ UINT *puCount); + + HRESULT ( STDMETHODCALLTYPE *GetSelection )( + ITfCandidateListUIElementBehavior * This, + /* [out] */ UINT *puIndex); + + HRESULT ( STDMETHODCALLTYPE *GetString )( + ITfCandidateListUIElementBehavior * This, + /* [in] */ UINT uIndex, + /* [out] */ BSTR *pstr); + + HRESULT ( STDMETHODCALLTYPE *GetPageIndex )( + ITfCandidateListUIElementBehavior * This, + /* [length_is][size_is][out] */ UINT *pIndex, + /* [in] */ UINT uSize, + /* [out] */ UINT *puPageCnt); + + HRESULT ( STDMETHODCALLTYPE *SetPageIndex )( + ITfCandidateListUIElementBehavior * This, + /* [size_is][in] */ UINT *pIndex, + /* [in] */ UINT uPageCnt); + + HRESULT ( STDMETHODCALLTYPE *GetCurrentPage )( + ITfCandidateListUIElementBehavior * This, + /* [out] */ UINT *puPage); + + HRESULT ( STDMETHODCALLTYPE *SetSelection )( + ITfCandidateListUIElementBehavior * This, + /* [in] */ UINT nIndex); + + HRESULT ( STDMETHODCALLTYPE *Finalize )( + ITfCandidateListUIElementBehavior * This); + + HRESULT ( STDMETHODCALLTYPE *Abort )( + ITfCandidateListUIElementBehavior * This); + + END_INTERFACE + } ITfCandidateListUIElementBehaviorVtbl; + + interface ITfCandidateListUIElementBehavior + { + CONST_VTBL struct ITfCandidateListUIElementBehaviorVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfCandidateListUIElementBehavior_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfCandidateListUIElementBehavior_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfCandidateListUIElementBehavior_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfCandidateListUIElementBehavior_GetDescription(This,pbstrDescription) \ + ( (This)->lpVtbl -> GetDescription(This,pbstrDescription) ) + +#define ITfCandidateListUIElementBehavior_GetGUID(This,pguid) \ + ( (This)->lpVtbl -> GetGUID(This,pguid) ) + +#define ITfCandidateListUIElementBehavior_Show(This,bShow) \ + ( (This)->lpVtbl -> Show(This,bShow) ) + +#define ITfCandidateListUIElementBehavior_IsShown(This,pbShow) \ + ( (This)->lpVtbl -> IsShown(This,pbShow) ) + + +#define ITfCandidateListUIElementBehavior_GetUpdatedFlags(This,pdwFlags) \ + ( (This)->lpVtbl -> GetUpdatedFlags(This,pdwFlags) ) + +#define ITfCandidateListUIElementBehavior_GetDocumentMgr(This,ppdim) \ + ( (This)->lpVtbl -> GetDocumentMgr(This,ppdim) ) + +#define ITfCandidateListUIElementBehavior_GetCount(This,puCount) \ + ( (This)->lpVtbl -> GetCount(This,puCount) ) + +#define ITfCandidateListUIElementBehavior_GetSelection(This,puIndex) \ + ( (This)->lpVtbl -> GetSelection(This,puIndex) ) + +#define ITfCandidateListUIElementBehavior_GetString(This,uIndex,pstr) \ + ( (This)->lpVtbl -> GetString(This,uIndex,pstr) ) + +#define ITfCandidateListUIElementBehavior_GetPageIndex(This,pIndex,uSize,puPageCnt) \ + ( (This)->lpVtbl -> GetPageIndex(This,pIndex,uSize,puPageCnt) ) + +#define ITfCandidateListUIElementBehavior_SetPageIndex(This,pIndex,uPageCnt) \ + ( (This)->lpVtbl -> SetPageIndex(This,pIndex,uPageCnt) ) + +#define ITfCandidateListUIElementBehavior_GetCurrentPage(This,puPage) \ + ( (This)->lpVtbl -> GetCurrentPage(This,puPage) ) + + +#define ITfCandidateListUIElementBehavior_SetSelection(This,nIndex) \ + ( (This)->lpVtbl -> SetSelection(This,nIndex) ) + +#define ITfCandidateListUIElementBehavior_Finalize(This) \ + ( (This)->lpVtbl -> Finalize(This) ) + +#define ITfCandidateListUIElementBehavior_Abort(This) \ + ( (This)->lpVtbl -> Abort(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfCandidateListUIElementBehavior_INTERFACE_DEFINED__ */ + + +#ifndef __ITfReadingInformationUIElement_INTERFACE_DEFINED__ +#define __ITfReadingInformationUIElement_INTERFACE_DEFINED__ + +/* interface ITfReadingInformationUIElement */ +/* [unique][uuid][local][object] */ + + +EXTERN_C const IID IID_ITfReadingInformationUIElement; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("ea1ea139-19df-11d7-a6d2-00065b84435c") + ITfReadingInformationUIElement : public ITfUIElement + { + public: + virtual HRESULT STDMETHODCALLTYPE GetUpdatedFlags( + /* [out] */ DWORD *pdwFlags) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetContext( + /* [out] */ ITfContext **ppic) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetString( + /* [out] */ BSTR *pstr) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetMaxReadingStringLength( + /* [out] */ UINT *pcchMax) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetErrorIndex( + /* [out] */ UINT *pErrorIndex) = 0; + + virtual HRESULT STDMETHODCALLTYPE IsVerticalOrderPreferred( + /* [out] */ BOOL *pfVertical) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfReadingInformationUIElementVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfReadingInformationUIElement * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfReadingInformationUIElement * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfReadingInformationUIElement * This); + + HRESULT ( STDMETHODCALLTYPE *GetDescription )( + ITfReadingInformationUIElement * This, + /* [out] */ BSTR *pbstrDescription); + + HRESULT ( STDMETHODCALLTYPE *GetGUID )( + ITfReadingInformationUIElement * This, + /* [out] */ GUID *pguid); + + HRESULT ( STDMETHODCALLTYPE *Show )( + ITfReadingInformationUIElement * This, + /* [in] */ BOOL bShow); + + HRESULT ( STDMETHODCALLTYPE *IsShown )( + ITfReadingInformationUIElement * This, + /* [out] */ BOOL *pbShow); + + HRESULT ( STDMETHODCALLTYPE *GetUpdatedFlags )( + ITfReadingInformationUIElement * This, + /* [out] */ DWORD *pdwFlags); + + HRESULT ( STDMETHODCALLTYPE *GetContext )( + ITfReadingInformationUIElement * This, + /* [out] */ ITfContext **ppic); + + HRESULT ( STDMETHODCALLTYPE *GetString )( + ITfReadingInformationUIElement * This, + /* [out] */ BSTR *pstr); + + HRESULT ( STDMETHODCALLTYPE *GetMaxReadingStringLength )( + ITfReadingInformationUIElement * This, + /* [out] */ UINT *pcchMax); + + HRESULT ( STDMETHODCALLTYPE *GetErrorIndex )( + ITfReadingInformationUIElement * This, + /* [out] */ UINT *pErrorIndex); + + HRESULT ( STDMETHODCALLTYPE *IsVerticalOrderPreferred )( + ITfReadingInformationUIElement * This, + /* [out] */ BOOL *pfVertical); + + END_INTERFACE + } ITfReadingInformationUIElementVtbl; + + interface ITfReadingInformationUIElement + { + CONST_VTBL struct ITfReadingInformationUIElementVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfReadingInformationUIElement_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfReadingInformationUIElement_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfReadingInformationUIElement_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfReadingInformationUIElement_GetDescription(This,pbstrDescription) \ + ( (This)->lpVtbl -> GetDescription(This,pbstrDescription) ) + +#define ITfReadingInformationUIElement_GetGUID(This,pguid) \ + ( (This)->lpVtbl -> GetGUID(This,pguid) ) + +#define ITfReadingInformationUIElement_Show(This,bShow) \ + ( (This)->lpVtbl -> Show(This,bShow) ) + +#define ITfReadingInformationUIElement_IsShown(This,pbShow) \ + ( (This)->lpVtbl -> IsShown(This,pbShow) ) + + +#define ITfReadingInformationUIElement_GetUpdatedFlags(This,pdwFlags) \ + ( (This)->lpVtbl -> GetUpdatedFlags(This,pdwFlags) ) + +#define ITfReadingInformationUIElement_GetContext(This,ppic) \ + ( (This)->lpVtbl -> GetContext(This,ppic) ) + +#define ITfReadingInformationUIElement_GetString(This,pstr) \ + ( (This)->lpVtbl -> GetString(This,pstr) ) + +#define ITfReadingInformationUIElement_GetMaxReadingStringLength(This,pcchMax) \ + ( (This)->lpVtbl -> GetMaxReadingStringLength(This,pcchMax) ) + +#define ITfReadingInformationUIElement_GetErrorIndex(This,pErrorIndex) \ + ( (This)->lpVtbl -> GetErrorIndex(This,pErrorIndex) ) + +#define ITfReadingInformationUIElement_IsVerticalOrderPreferred(This,pfVertical) \ + ( (This)->lpVtbl -> IsVerticalOrderPreferred(This,pfVertical) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfReadingInformationUIElement_INTERFACE_DEFINED__ */ + + +#ifndef __ITfTransitoryExtensionUIElement_INTERFACE_DEFINED__ +#define __ITfTransitoryExtensionUIElement_INTERFACE_DEFINED__ + +/* interface ITfTransitoryExtensionUIElement */ +/* [unique][uuid][local][object] */ + + +EXTERN_C const IID IID_ITfTransitoryExtensionUIElement; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("858f956a-972f-42a2-a2f2-0321e1abe209") + ITfTransitoryExtensionUIElement : public ITfUIElement + { + public: + virtual HRESULT STDMETHODCALLTYPE GetDocumentMgr( + /* [out] */ ITfDocumentMgr **ppdim) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfTransitoryExtensionUIElementVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfTransitoryExtensionUIElement * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfTransitoryExtensionUIElement * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfTransitoryExtensionUIElement * This); + + HRESULT ( STDMETHODCALLTYPE *GetDescription )( + ITfTransitoryExtensionUIElement * This, + /* [out] */ BSTR *pbstrDescription); + + HRESULT ( STDMETHODCALLTYPE *GetGUID )( + ITfTransitoryExtensionUIElement * This, + /* [out] */ GUID *pguid); + + HRESULT ( STDMETHODCALLTYPE *Show )( + ITfTransitoryExtensionUIElement * This, + /* [in] */ BOOL bShow); + + HRESULT ( STDMETHODCALLTYPE *IsShown )( + ITfTransitoryExtensionUIElement * This, + /* [out] */ BOOL *pbShow); + + HRESULT ( STDMETHODCALLTYPE *GetDocumentMgr )( + ITfTransitoryExtensionUIElement * This, + /* [out] */ ITfDocumentMgr **ppdim); + + END_INTERFACE + } ITfTransitoryExtensionUIElementVtbl; + + interface ITfTransitoryExtensionUIElement + { + CONST_VTBL struct ITfTransitoryExtensionUIElementVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfTransitoryExtensionUIElement_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfTransitoryExtensionUIElement_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfTransitoryExtensionUIElement_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfTransitoryExtensionUIElement_GetDescription(This,pbstrDescription) \ + ( (This)->lpVtbl -> GetDescription(This,pbstrDescription) ) + +#define ITfTransitoryExtensionUIElement_GetGUID(This,pguid) \ + ( (This)->lpVtbl -> GetGUID(This,pguid) ) + +#define ITfTransitoryExtensionUIElement_Show(This,bShow) \ + ( (This)->lpVtbl -> Show(This,bShow) ) + +#define ITfTransitoryExtensionUIElement_IsShown(This,pbShow) \ + ( (This)->lpVtbl -> IsShown(This,pbShow) ) + + +#define ITfTransitoryExtensionUIElement_GetDocumentMgr(This,ppdim) \ + ( (This)->lpVtbl -> GetDocumentMgr(This,ppdim) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfTransitoryExtensionUIElement_INTERFACE_DEFINED__ */ + + +#ifndef __ITfTransitoryExtensionSink_INTERFACE_DEFINED__ +#define __ITfTransitoryExtensionSink_INTERFACE_DEFINED__ + +/* interface ITfTransitoryExtensionSink */ +/* [unique][uuid][local][object] */ + + +EXTERN_C const IID IID_ITfTransitoryExtensionSink; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("a615096f-1c57-4813-8a15-55ee6e5a839c") + ITfTransitoryExtensionSink : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE OnTransitoryExtensionUpdated( + /* [in] */ ITfContext *pic, + /* [in] */ TfEditCookie ecReadOnly, + /* [in] */ ITfRange *pResultRange, + /* [in] */ ITfRange *pCompositionRange, + /* [out] */ BOOL *pfDeleteResultRange) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfTransitoryExtensionSinkVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfTransitoryExtensionSink * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfTransitoryExtensionSink * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfTransitoryExtensionSink * This); + + HRESULT ( STDMETHODCALLTYPE *OnTransitoryExtensionUpdated )( + ITfTransitoryExtensionSink * This, + /* [in] */ ITfContext *pic, + /* [in] */ TfEditCookie ecReadOnly, + /* [in] */ ITfRange *pResultRange, + /* [in] */ ITfRange *pCompositionRange, + /* [out] */ BOOL *pfDeleteResultRange); + + END_INTERFACE + } ITfTransitoryExtensionSinkVtbl; + + interface ITfTransitoryExtensionSink + { + CONST_VTBL struct ITfTransitoryExtensionSinkVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfTransitoryExtensionSink_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfTransitoryExtensionSink_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfTransitoryExtensionSink_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfTransitoryExtensionSink_OnTransitoryExtensionUpdated(This,pic,ecReadOnly,pResultRange,pCompositionRange,pfDeleteResultRange) \ + ( (This)->lpVtbl -> OnTransitoryExtensionUpdated(This,pic,ecReadOnly,pResultRange,pCompositionRange,pfDeleteResultRange) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfTransitoryExtensionSink_INTERFACE_DEFINED__ */ + + +#ifndef __ITfToolTipUIElement_INTERFACE_DEFINED__ +#define __ITfToolTipUIElement_INTERFACE_DEFINED__ + +/* interface ITfToolTipUIElement */ +/* [unique][uuid][local][object] */ + + +EXTERN_C const IID IID_ITfToolTipUIElement; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("52b18b5c-555d-46b2-b00a-fa680144fbdb") + ITfToolTipUIElement : public ITfUIElement + { + public: + virtual HRESULT STDMETHODCALLTYPE GetString( + /* [out] */ BSTR *pstr) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfToolTipUIElementVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfToolTipUIElement * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfToolTipUIElement * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfToolTipUIElement * This); + + HRESULT ( STDMETHODCALLTYPE *GetDescription )( + ITfToolTipUIElement * This, + /* [out] */ BSTR *pbstrDescription); + + HRESULT ( STDMETHODCALLTYPE *GetGUID )( + ITfToolTipUIElement * This, + /* [out] */ GUID *pguid); + + HRESULT ( STDMETHODCALLTYPE *Show )( + ITfToolTipUIElement * This, + /* [in] */ BOOL bShow); + + HRESULT ( STDMETHODCALLTYPE *IsShown )( + ITfToolTipUIElement * This, + /* [out] */ BOOL *pbShow); + + HRESULT ( STDMETHODCALLTYPE *GetString )( + ITfToolTipUIElement * This, + /* [out] */ BSTR *pstr); + + END_INTERFACE + } ITfToolTipUIElementVtbl; + + interface ITfToolTipUIElement + { + CONST_VTBL struct ITfToolTipUIElementVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfToolTipUIElement_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfToolTipUIElement_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfToolTipUIElement_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfToolTipUIElement_GetDescription(This,pbstrDescription) \ + ( (This)->lpVtbl -> GetDescription(This,pbstrDescription) ) + +#define ITfToolTipUIElement_GetGUID(This,pguid) \ + ( (This)->lpVtbl -> GetGUID(This,pguid) ) + +#define ITfToolTipUIElement_Show(This,bShow) \ + ( (This)->lpVtbl -> Show(This,bShow) ) + +#define ITfToolTipUIElement_IsShown(This,pbShow) \ + ( (This)->lpVtbl -> IsShown(This,pbShow) ) + + +#define ITfToolTipUIElement_GetString(This,pstr) \ + ( (This)->lpVtbl -> GetString(This,pstr) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfToolTipUIElement_INTERFACE_DEFINED__ */ + + +#ifndef __ITfReverseConversionList_INTERFACE_DEFINED__ +#define __ITfReverseConversionList_INTERFACE_DEFINED__ + +/* interface ITfReverseConversionList */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfReverseConversionList; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("151d69f0-86f4-4674-b721-56911e797f47") + ITfReverseConversionList : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetLength( + /* [out] */ UINT *puIndex) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetString( + /* [in] */ UINT uIndex, + /* [out] */ BSTR *pbstr) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfReverseConversionListVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfReverseConversionList * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfReverseConversionList * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfReverseConversionList * This); + + HRESULT ( STDMETHODCALLTYPE *GetLength )( + ITfReverseConversionList * This, + /* [out] */ UINT *puIndex); + + HRESULT ( STDMETHODCALLTYPE *GetString )( + ITfReverseConversionList * This, + /* [in] */ UINT uIndex, + /* [out] */ BSTR *pbstr); + + END_INTERFACE + } ITfReverseConversionListVtbl; + + interface ITfReverseConversionList + { + CONST_VTBL struct ITfReverseConversionListVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfReverseConversionList_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfReverseConversionList_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfReverseConversionList_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfReverseConversionList_GetLength(This,puIndex) \ + ( (This)->lpVtbl -> GetLength(This,puIndex) ) + +#define ITfReverseConversionList_GetString(This,uIndex,pbstr) \ + ( (This)->lpVtbl -> GetString(This,uIndex,pbstr) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfReverseConversionList_INTERFACE_DEFINED__ */ + + +#ifndef __ITfReverseConversion_INTERFACE_DEFINED__ +#define __ITfReverseConversion_INTERFACE_DEFINED__ + +/* interface ITfReverseConversion */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfReverseConversion; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("a415e162-157d-417d-8a8c-0ab26c7d2781") + ITfReverseConversion : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE DoReverseConversion( + /* [in] */ LPCWSTR lpstr, + /* [out] */ ITfReverseConversionList **ppList) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfReverseConversionVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfReverseConversion * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfReverseConversion * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfReverseConversion * This); + + HRESULT ( STDMETHODCALLTYPE *DoReverseConversion )( + ITfReverseConversion * This, + /* [in] */ LPCWSTR lpstr, + /* [out] */ ITfReverseConversionList **ppList); + + END_INTERFACE + } ITfReverseConversionVtbl; + + interface ITfReverseConversion + { + CONST_VTBL struct ITfReverseConversionVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfReverseConversion_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfReverseConversion_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfReverseConversion_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfReverseConversion_DoReverseConversion(This,lpstr,ppList) \ + ( (This)->lpVtbl -> DoReverseConversion(This,lpstr,ppList) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfReverseConversion_INTERFACE_DEFINED__ */ + + +#ifndef __ITfReverseConversionMgr_INTERFACE_DEFINED__ +#define __ITfReverseConversionMgr_INTERFACE_DEFINED__ + +/* interface ITfReverseConversionMgr */ +/* [unique][uuid][object] */ + + +EXTERN_C const IID IID_ITfReverseConversionMgr; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("b643c236-c493-41b6-abb3-692412775cc4") + ITfReverseConversionMgr : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetReverseConversion( + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile, + /* [in] */ DWORD dwflag, + /* [out] */ ITfReverseConversion **ppReverseConversion) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITfReverseConversionMgrVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ITfReverseConversionMgr * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ITfReverseConversionMgr * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ITfReverseConversionMgr * This); + + HRESULT ( STDMETHODCALLTYPE *GetReverseConversion )( + ITfReverseConversionMgr * This, + /* [in] */ LANGID langid, + /* [in] */ REFGUID guidProfile, + /* [in] */ DWORD dwflag, + /* [out] */ ITfReverseConversion **ppReverseConversion); + + END_INTERFACE + } ITfReverseConversionMgrVtbl; + + interface ITfReverseConversionMgr + { + CONST_VTBL struct ITfReverseConversionMgrVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITfReverseConversionMgr_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ITfReverseConversionMgr_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ITfReverseConversionMgr_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ITfReverseConversionMgr_GetReverseConversion(This,langid,guidProfile,dwflag,ppReverseConversion) \ + ( (This)->lpVtbl -> GetReverseConversion(This,langid,guidProfile,dwflag,ppReverseConversion) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ITfReverseConversionMgr_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_msctf_0000_0090 */ +/* [local] */ + + +DEFINE_GUID( TF_PROFILE_NEWPHONETIC, 0xB2F9C502, 0x1742, 0x11D4, 0x97, 0x90, 0x00, 0x80, 0xC8, 0x82, 0x68, 0x7E); +DEFINE_GUID( TF_PROFILE_PHONETIC, 0x761309DE, 0x317A, 0x11D4, 0x9B, 0x5D, 0x00, 0x80, 0xC8, 0x82, 0x68, 0x7E); +DEFINE_GUID( TF_PROFILE_NEWCHANGJIE, 0xF3BA907A, 0x6C7E, 0x11D4, 0x97, 0xFA, 0x00, 0x80, 0xC8, 0x82, 0x68, 0x7E); +DEFINE_GUID( TF_PROFILE_CHANGJIE, 0x4BDF9F03, 0xC7D3, 0x11D4, 0xB2, 0xAB, 0x00, 0x80, 0xC8, 0x82, 0x68, 0x7E); +DEFINE_GUID( TF_PROFILE_NEWQUICK, 0x0B883BA0, 0xC1C7, 0x11D4, 0x87, 0xF9, 0x00, 0x80, 0xC8, 0x82, 0x68, 0x7E); +DEFINE_GUID( TF_PROFILE_QUICK, 0x6024B45F, 0x5C54, 0x11D4, 0xB9, 0x21, 0x00, 0x80, 0xC8, 0x82, 0x68, 0x7E); +DEFINE_GUID( TF_PROFILE_CANTONESE, 0x0AEC109C, 0x7E96, 0x11D4, 0xB2, 0xEF, 0x00, 0x80, 0xC8, 0x82, 0x68, 0x7E); +DEFINE_GUID( TF_PROFILE_PINYIN, 0xF3BA9077, 0x6C7E, 0x11D4, 0x97, 0xFA, 0x00, 0x80, 0xC8, 0x82, 0x68, 0x7E); +DEFINE_GUID( TF_PROFILE_DAYI, 0x037B2C25, 0x480C, 0x4D7F, 0xB0, 0x27, 0xD6, 0xCA, 0x6B, 0x69, 0x78, 0x8A); +DEFINE_GUID( TF_PROFILE_ARRAY, 0xD38EFF65, 0xAA46, 0x4FD5, 0x91, 0xA7, 0x67, 0x84, 0x5F, 0xB0, 0x2F, 0x5B); +DEFINE_GUID( TF_PROFILE_QUANPIN, 0x54FC610E, 0x6ABD, 0x4685, 0x9D, 0xDD, 0xA1, 0x30, 0xBD, 0xF1, 0xB1, 0x70); +DEFINE_GUID( TF_PROFILE_ZHENGMA, 0x733B4D81, 0x3BC3, 0x4132, 0xB9, 0x1A, 0xE9, 0xCD, 0xD5, 0xE2, 0xBF, 0xC9); +DEFINE_GUID( TF_PROFILE_SHUANGPIN, 0xEF63706D, 0x31C4, 0x490E, 0x9D, 0xBB, 0xBD, 0x15, 0x0A, 0xDC, 0x45, 0x4B); +DEFINE_GUID( TF_PROFILE_YI, 0x409C8376, 0x007B, 0x4357, 0xAE, 0x8E, 0x26, 0x31, 0x6E, 0xE3, 0xFB, 0x0D); +#endif // MSCTF_DEFINED + + +extern RPC_IF_HANDLE __MIDL_itf_msctf_0000_0090_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_msctf_0000_0090_v0_0_s_ifspec; + +/* Additional Prototypes for ALL interfaces */ + +unsigned long __RPC_USER BSTR_UserSize( unsigned long *, unsigned long , BSTR * ); +unsigned char * __RPC_USER BSTR_UserMarshal( unsigned long *, unsigned char *, BSTR * ); +unsigned char * __RPC_USER BSTR_UserUnmarshal( unsigned long *, unsigned char *, BSTR * ); +void __RPC_USER BSTR_UserFree( unsigned long *, BSTR * ); + +unsigned long __RPC_USER CLIPFORMAT_UserSize( unsigned long *, unsigned long , CLIPFORMAT * ); +unsigned char * __RPC_USER CLIPFORMAT_UserMarshal( unsigned long *, unsigned char *, CLIPFORMAT * ); +unsigned char * __RPC_USER CLIPFORMAT_UserUnmarshal( unsigned long *, unsigned char *, CLIPFORMAT * ); +void __RPC_USER CLIPFORMAT_UserFree( unsigned long *, CLIPFORMAT * ); + +unsigned long __RPC_USER HWND_UserSize( unsigned long *, unsigned long , HWND * ); +unsigned char * __RPC_USER HWND_UserMarshal( unsigned long *, unsigned char *, HWND * ); +unsigned char * __RPC_USER HWND_UserUnmarshal( unsigned long *, unsigned char *, HWND * ); +void __RPC_USER HWND_UserFree( unsigned long *, HWND * ); + +unsigned long __RPC_USER VARIANT_UserSize( unsigned long *, unsigned long , VARIANT * ); +unsigned char * __RPC_USER VARIANT_UserMarshal( unsigned long *, unsigned char *, VARIANT * ); +unsigned char * __RPC_USER VARIANT_UserUnmarshal( unsigned long *, unsigned char *, VARIANT * ); +void __RPC_USER VARIANT_UserFree( unsigned long *, VARIANT * ); + +unsigned long __RPC_USER BSTR_UserSize64( unsigned long *, unsigned long , BSTR * ); +unsigned char * __RPC_USER BSTR_UserMarshal64( unsigned long *, unsigned char *, BSTR * ); +unsigned char * __RPC_USER BSTR_UserUnmarshal64( unsigned long *, unsigned char *, BSTR * ); +void __RPC_USER BSTR_UserFree64( unsigned long *, BSTR * ); + +unsigned long __RPC_USER CLIPFORMAT_UserSize64( unsigned long *, unsigned long , CLIPFORMAT * ); +unsigned char * __RPC_USER CLIPFORMAT_UserMarshal64( unsigned long *, unsigned char *, CLIPFORMAT * ); +unsigned char * __RPC_USER CLIPFORMAT_UserUnmarshal64( unsigned long *, unsigned char *, CLIPFORMAT * ); +void __RPC_USER CLIPFORMAT_UserFree64( unsigned long *, CLIPFORMAT * ); + +unsigned long __RPC_USER HWND_UserSize64( unsigned long *, unsigned long , HWND * ); +unsigned char * __RPC_USER HWND_UserMarshal64( unsigned long *, unsigned char *, HWND * ); +unsigned char * __RPC_USER HWND_UserUnmarshal64( unsigned long *, unsigned char *, HWND * ); +void __RPC_USER HWND_UserFree64( unsigned long *, HWND * ); + +unsigned long __RPC_USER VARIANT_UserSize64( unsigned long *, unsigned long , VARIANT * ); +unsigned char * __RPC_USER VARIANT_UserMarshal64( unsigned long *, unsigned char *, VARIANT * ); +unsigned char * __RPC_USER VARIANT_UserUnmarshal64( unsigned long *, unsigned char *, VARIANT * ); +void __RPC_USER VARIANT_UserFree64( unsigned long *, VARIANT * ); + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + + diff --git a/source/EterLib/parser.cpp b/source/EterLib/parser.cpp new file mode 100644 index 0000000..2e86c37 --- /dev/null +++ b/source/EterLib/parser.cpp @@ -0,0 +1,443 @@ +#include "StdAfx.h" +#include "parser.h" + +using namespace script; + +#define ishan(ch) (((ch) & 0xE0) > 0x90) +#define isnhspace(ch) (!ishan(ch) && isspace(ch)) + + +extern DWORD GetDefaultCodePage(); + +const char* LocaleString_FindChar(const char* base, int len, char test) +{ + if (!base) + return NULL; + + DWORD codePage = GetDefaultCodePage(); + + int pos = 0; + while (pos < len) + { + const char* cur = base + pos; + const char* next = CharNextExA(codePage, cur, 0); + int cur_len = next - cur; + if (cur_len > 1) + { + pos += cur_len; + } + else if (1 == cur_len) + { + if (*cur == test) + return cur; + + ++pos; + } + else + { + break; + } + } + return NULL; +} + +int LocaleString_RightTrim(char* base, int len) +{ + DWORD codePage = GetDefaultCodePage(); + + int pos = len; + + while (pos > 0) + { + char* cur = base + pos; + char* prev = CharPrevExA(codePage, base, cur , 0); + + int prev_len = cur - prev; + if (prev_len != 1) + break; + + if (!isspace((unsigned char) *prev) && *prev != '\n' && *prev != '\r') + break; + + *prev = '\0'; + + pos -= prev_len; + } + + if (pos > 0) + return pos; + + return 0; +} + +void LocaleString_RightTrim(char* base) +{ + LocaleString_RightTrim(base, strlen(base)); +} + +void OLD_rtrim(char* base) +{ + if (!base) + return; + + DWORD codePage = GetDefaultCodePage(); + + if (949 == codePage || 936 == codePage) + { + char* end = base + strlen(base) - 1; + + while (end != base) + { + if (!isnhspace((unsigned char) *end) && *end != '\n' && *end != '\r' || (end!=base && *((unsigned char*)end-1)>0xa0)) + break; + + *end = '\0'; + + end = CharPrevExA(codePage, base, end, 0); + } + } + else + { + char* end = base + strlen(base); + + while (end != base) + { + char* prev = CharPrevExA(codePage, base, end, 0); + + int prev_len = end - prev; + if (prev_len != 1) + break; + + if (!isspace((unsigned char) *prev) && *prev != '\n' && *prev != '\r') + break; + + *prev = '\0'; + + end = prev; + } + } +} + +const char* LocaleString_Skip(DWORD codePage, const char* cur) +{ + int loopCount = 0; + + while (*cur) + { + if (++loopCount > 9216) + { + TraceError("Infinite loop in LocaleString_Skip [%s]", cur); + break; + } + + const char* next = CharNextExA(codePage, cur, 0); + int cur_len = next - cur; + if (cur_len > 1) + { + cur = next; + } + else if (1 == cur_len) + { + if (!isspace((unsigned char) *cur) && *cur != '\n' && *cur != '\r') + return cur; + } + else + { + break; + } + } + return cur; +} + +bool Group::GetArg(const char *c_arg_base, int arg_len, TArgList & argList) +{ + char szName[32 + 1]; + char szValue[64 + 1]; + + int iNameLen = 0; + int iValueLen = 0; + int iCharLen = 0; + + int pos = 0; + + bool isValue = false; + + DWORD codePage = GetDefaultCodePage(); + + while (pos < arg_len) + { + const char* cur = c_arg_base + pos; + const char* next = CharNextExA(codePage, cur, 0); + iCharLen = next - cur; + + if (iCharLen > 1) + { + if (isValue) + { + if (iValueLen >= 64) + { + TraceError("argument value overflow: must be shorter than 64 letters"); + return false; + } + + memcpy(szValue+iValueLen, cur, iCharLen); + iValueLen += iCharLen; + szValue[iValueLen] = '\0'; + } + else + { + if (iNameLen >= 32) + { + TraceError("argument name overflow: must be shorter than 32 letters"); + return false; + } + memcpy(szName+iNameLen, cur, iCharLen); + iNameLen += iCharLen; + szName[iNameLen] = '\0'; + } + } + else if (iCharLen == 1) + { + const char c = *cur; + if (c == '|') + { + if (iNameLen == 0) + { + TraceError("no argument name"); + return false; + } + + isValue = false; + + iNameLen = LocaleString_RightTrim(szName, iNameLen); + iValueLen = LocaleString_RightTrim(szValue, iValueLen); + argList.push_back(TArg(szName, szValue)); + + iNameLen = 0; + iValueLen = 0; + } + else if (c == ';') + { + isValue = true; + } + // ƴϰ, ̸ ۵ ʾ ĭ dz ڴ. + else if (!isValue && iNameLen == 0 && isspace((unsigned char) c)) + { + } + // ʹ dz ڴ + else if (c == '\r' || c == '\n') + { + } + else + { + if (isValue) + { + if (iValueLen >= 64) + { + TraceError("argument value overflow: must be shorter than 64 letters"); + return false; + } + + memcpy(szValue+iValueLen, cur, iCharLen); + iValueLen += iCharLen; + szValue[iValueLen] = '\0'; + } + else + { + if (iNameLen >= 32) + { + TraceError("argument name overflow: must be shorter than 32 letters"); + return false; + } + memcpy(szName+iNameLen, cur, iCharLen); + iNameLen += iCharLen; + szName[iNameLen] = '\0'; + } + } + } + else + { + break; + } + + pos += iCharLen; + } + + if (iNameLen != 0 && iValueLen != 0) + { + iNameLen = LocaleString_RightTrim(szName, iNameLen); + iValueLen = LocaleString_RightTrim(szValue, iValueLen); + argList.push_back(TArg(szName, szValue)); + } + + return true; +} + + +bool Group::Create(const std::string & stSource) +{ + m_cmdList.clear(); + + if (stSource.empty()) + return false; + + const char *str_base = stSource.c_str(); + if (!str_base || !*str_base) + { + TraceError("Source file has no content"); + return false; + } + int str_len = stSource.length(); + int str_pos = 0; + + DWORD codePage = GetDefaultCodePage(); + + char box_data[1024 + 1]; + + static std::string stLetter; + + while (str_pos < str_len) + { + TCmd cmd; + + const char* word = str_base + str_pos; + const char* word_next = CharNextExA(codePage, word, 0); + + int word_len = word_next - word; + + if (word_len > 1) + { + str_pos += word_len; + + { + stLetter.assign(word, word_next); + + cmd.name.assign("LETTER"); + cmd.argList.push_back(TArg("value", stLetter)); + + m_cmdList.push_back(cmd); + } + + } + else if (word_len == 1) + { + const char cur = *word; + + if ('[' == cur) + { + ++str_pos; + + const char* box_begin = str_base + str_pos; + const char* box_end = LocaleString_FindChar(box_begin, str_len - str_pos, ']'); + if (!box_end) + { + TraceError(" !! PARSING ERROR - Syntax Error : %s\n", box_begin); + return false; + } + str_pos += box_end - box_begin + 1; + + + int data_len = 0; + { + const char* data_begin = LocaleString_Skip(codePage, box_begin); + const char* data_end = box_end; + data_len = data_end - data_begin; + if (data_len >= 1024) + { + TraceError(" !! PARSING ERROR - Buffer Overflow : %d, %s\n", data_len, str_base); + return false; + } + memcpy(box_data, data_begin, data_len); + box_data[data_len] = '\0'; + + data_len = LocaleString_RightTrim(box_data, data_len); // ĭ ڸ + } + + { + const char* space = LocaleString_FindChar(box_data, data_len, ' '); + if (space) // ڰ + { + int name_len = space - box_data; + cmd.name.assign(box_data, name_len); + + const char* space_next = CharNextExA(codePage, space, 0); + const char* arg = LocaleString_Skip(codePage, space_next); + + int arg_len = data_len - (arg - box_data); + + if (!GetArg(arg, arg_len, cmd.argList)) + { + TraceError(" !! PARSING ERROR - Unknown Arguments : %d, %s\n", arg_len, arg); + return false; + } + } + else // ڰ Ƿ Ʈ ɾ. + { + cmd.name.assign(box_data); + cmd.argList.clear(); + } + + m_cmdList.push_back(cmd); + } + } + else if (cur == '\r' || cur == '\n') + { + ++str_pos; + } + else + { + ++str_pos; + + { + stLetter.assign(1, cur); + cmd.name.assign("LETTER"); + cmd.argList.push_back(TArg("value", stLetter)); + m_cmdList.push_back(cmd); + } + } + } + else + { + break; + } + } + + return true; +} + +bool Group::GetCmd(TCmd & cmd) +{ + if (m_cmdList.empty()) + return false; + + cmd = m_cmdList.front(); + m_cmdList.pop_front(); + return true; +} + +bool Group::ReadCmd(TCmd & cmd) +{ + if (m_cmdList.empty()) + return false; + + cmd = m_cmdList.front(); + return true; +} + +std::string & Group::GetError() +{ + return m_stError; +} + +void Group::SetError(const char * c_pszError) +{ + m_stError.assign(c_pszError); +} + +Group::Group() +{ +} + +Group::~Group() +{ +} diff --git a/source/EterLib/parser.h b/source/EterLib/parser.h new file mode 100644 index 0000000..2952f6b --- /dev/null +++ b/source/EterLib/parser.h @@ -0,0 +1,94 @@ +#ifndef __INC_SCRIPT_PARSER_H__ +#define __INC_SCRIPT_PARSER_H__ + +#include +#include + +namespace script +{ + typedef struct SArgumet + { + SArgumet(const std::string& c_stName, const std::string& c_stValue) + { + strName = c_stName; + strValue = c_stValue; + } + SArgumet(const SArgumet& c_arg) + { + strName = c_arg.strName; + strValue = c_arg.strValue; + } + void operator=(const SArgumet& c_arg) + { + strName = c_arg.strName; + strValue = c_arg.strValue; + } + std::string strName; + std::string strValue; + } TArg; + + typedef std::list TArgList; + + typedef struct SCmd + { + std::string name; + TArgList argList; + + SCmd() + {} + SCmd(const SCmd& c_cmd) + { + name = c_cmd.name; + argList = c_cmd.argList; + } + void operator=(const SCmd& c_cmd) + { + name = c_cmd.name; + argList = c_cmd.argList; + } + } TCmd; + + class Group + { + public: + Group(); + ~Group(); + + public: + /** Ʈ ũƮ ׷ . + * + * ϸ GetError ޼ҵ Ȯ ִ. + * + * @param stSource Ʈ ׷ . + * @return true, ϸ false + */ + bool Create(const std::string & stSource); + + /** ɾ ޴ ޼ҵ + * + * @param cmd ÿ ü ɾ ȴ. + * @return ɾ ִٸ true, ٸ false + */ + bool GetCmd(TCmd & cmd); + + /* + ɾ ʴ´. + */ + bool ReadCmd(TCmd & cmd); + + /** ޴ ޼ҵ + * + * @return stError ȴ. + */ + std::string & GetError(); + + private: + void SetError(const char *str); + bool GetArg(const char * c_atr_base, int arg_len, TArgList & argList); + + std::string m_stError; + std::list m_cmdList; + }; +} + +#endif diff --git a/source/EterLocale/Arabic.cpp b/source/EterLocale/Arabic.cpp new file mode 100644 index 0000000..1cd08df --- /dev/null +++ b/source/EterLocale/Arabic.cpp @@ -0,0 +1,366 @@ +#include "StdAfx.h" +#include "Arabic.h" +#include + +enum ARABIC_CODE +{ + ARABIC_CODE_BASE = 0x0621, + ARABIC_CODE_LAST = 0x064a, + ARABIC_CODE_COUNT = ARABIC_CODE_LAST - ARABIC_CODE_BASE + 1, +}; + +enum ARABIC_FORM_TYPE +{ + DEBUG_CODE, + ISOLATED, + INITIAL, + MEDIAL, + FINAL, + ARABIC_FORM_TYPE_NUM, +}; + +bool Arabic_IsInSpace(wchar_t code) +{ + switch (code) + { + case ' ': + case '\t': + return true; + default: + return false; + } +} + +bool Arabic_IsInSymbol(wchar_t code) +{ + return (code >= 0x20 && code <= 0x2f) || + (code >= 0x3a && code <= 0x40) || + (code >= 0x5b && code <= 0x60) || + (code >= 0x7b && code <= 0x7e); +} + + +bool Arabic_IsInPresentation(wchar_t code) +{ + return (code >= 0xfb50 && code <= 0xfdff) || (code >= 0xfe70 && code <= 0xfeff) || (code == 0x08); +} + +bool Arabic_HasPresentation(wchar_t* codes, int last) +{ + while (last > 0) + { + if (Arabic_IsInSpace(codes[last])) + { + last--; + } + else + { + if (Arabic_IsInPresentation(codes[last])) + return true; + else + break; + } + } + return false; +} + +wchar_t Arabic_GetComposition(wchar_t cur, wchar_t next, ARABIC_FORM_TYPE pos) +{ + static wchar_t LAM_ALEF_MADDA[ARABIC_FORM_TYPE_NUM] = {0x0622, 0xFEF5, 0, 0, 0xFEF6}; + static wchar_t LAM_ALEF_HAMZA_ABOVE[ARABIC_FORM_TYPE_NUM] = {0x0623, 0xFEF7, 0, 0, 0xFEF8}; + static wchar_t LAM_ALEF_HAMZA_BELOW[ARABIC_FORM_TYPE_NUM] = {0x0625, 0xFEF9, 0, 0, 0xFEFA}; + static wchar_t LAM_ALEF[ARABIC_FORM_TYPE_NUM] = {0x0627, 0xFEFB, 0, 0, 0xFEFC}; + + switch (cur) + { + case 0x0644: + switch (next) + { + case 0x0622:return LAM_ALEF_MADDA[pos];break; + case 0x0623:return LAM_ALEF_HAMZA_ABOVE[pos];break; + case 0x0625:return LAM_ALEF_HAMZA_BELOW[pos];break; + case 0x0627:return LAM_ALEF[pos];break; + } + break; + } + return 0; +} + +wchar_t Arabic_GetMap(wchar_t code, ARABIC_FORM_TYPE pos) +{ + static wchar_t HAMZA[ARABIC_FORM_TYPE_NUM] = {0x0621 , 0xFE80, 0, 0, 0}; + static wchar_t ALEF_MADDA[ARABIC_FORM_TYPE_NUM] = {0x0622 , 0xFE81, 0, 0, 0xFE82}; + static wchar_t ALEF_HAMZA_ABOVE[ARABIC_FORM_TYPE_NUM] = {0x0623 , 0xFE83, 0, 0, 0xFE84}; + static wchar_t WAW_HAMZA[ARABIC_FORM_TYPE_NUM] = {0x0624 , 0xFE85, 0, 0, 0xFE86}; + static wchar_t ALEF_HAMZA_BELOW[ARABIC_FORM_TYPE_NUM] = {0x0625 , 0xFE87, 0, 0, 0xFE88}; + static wchar_t YEH_HAMZA[ARABIC_FORM_TYPE_NUM] = {0x0626 , 0xFE89, 0xFE8B, 0xFE8C, 0xFE8A}; + static wchar_t ALEF[ARABIC_FORM_TYPE_NUM] = {0x0627 , 0xFE8D, 0, 0, 0xFE8E}; + static wchar_t BEH[ARABIC_FORM_TYPE_NUM] = {0x0628 , 0xFE8F, 0xFE91, 0xFE92, 0xFE90}; + static wchar_t TEH_MARBUTA[ARABIC_FORM_TYPE_NUM] = {0x0629 , 0xFE93, 0, 0, 0xFE94}; + static wchar_t TEH[ARABIC_FORM_TYPE_NUM] = {0x062A , 0xFE95, 0xFE97, 0xFE98, 0xFE96}; + static wchar_t THEH[ARABIC_FORM_TYPE_NUM] = {0x062B , 0xFE99, 0xFE9B, 0xFE9C, 0xFE9A}; + static wchar_t JEEM[ARABIC_FORM_TYPE_NUM] = {0x062C , 0xFE9D, 0xFE9F, 0xFEA0, 0xFE9E}; + static wchar_t HAH[ARABIC_FORM_TYPE_NUM] = {0x062D , 0xFEA1, 0xFEA3, 0xFEA4, 0xFEA2}; + static wchar_t KHAH[ARABIC_FORM_TYPE_NUM] = {0x062E , 0xFEA5, 0xFEA7, 0xFEA8, 0xFEA6}; + static wchar_t DAL[ARABIC_FORM_TYPE_NUM] = {0x062F , 0xFEA9, 0, 0, 0xFEAA}; + static wchar_t THAL[ARABIC_FORM_TYPE_NUM] = {0x0630 , 0xFEAB, 0, 0, 0xFEAC}; + static wchar_t REH[ARABIC_FORM_TYPE_NUM] = {0x0631 , 0xFEAD, 0, 0, 0xFEAE}; + static wchar_t ZAIN[ARABIC_FORM_TYPE_NUM] = {0x0632 , 0xFEAF, 0, 0, 0xFEB0}; + static wchar_t SEEN[ARABIC_FORM_TYPE_NUM] = {0x0633 , 0xFEB1, 0xFEB3, 0xFEB4, 0xFEB2}; + static wchar_t SHEEN[ARABIC_FORM_TYPE_NUM] = {0x0634 , 0xFEB5, 0xFEB7, 0xFEB8, 0xFEB6}; + static wchar_t SAD[ARABIC_FORM_TYPE_NUM] = {0x0635 , 0xFEB9, 0xFEBB, 0xFEBC, 0xFEBA}; + static wchar_t DAD[ARABIC_FORM_TYPE_NUM] = {0x0636 , 0xFEBD, 0xFEBF, 0xFEC0, 0xFEBE}; + static wchar_t TAH[ARABIC_FORM_TYPE_NUM] = {0x0637 , 0xFEC1, 0xFEC3, 0xFEC4, 0xFEC2}; + static wchar_t ZAH[ARABIC_FORM_TYPE_NUM] = {0x0638 , 0xFEC5, 0xFEC7, 0xFEC8, 0xFEC6}; + static wchar_t AIN[ARABIC_FORM_TYPE_NUM] = {0x0639 , 0xFEC9, 0xFECB, 0xFECC, 0xFECA}; + static wchar_t GHAIN[ARABIC_FORM_TYPE_NUM] = {0x063A , 0xFECD, 0xFECF, 0xFED0, 0xFECE}; + static wchar_t TATWEEL[ARABIC_FORM_TYPE_NUM] = {0x0640 , 0x0640, 0, 0, 0}; + static wchar_t OX_FEH[ARABIC_FORM_TYPE_NUM] = {0x0641 , 0xFED1, 0xFED3, 0xFED4, 0xFED2}; + static wchar_t QAF[ARABIC_FORM_TYPE_NUM] = {0x0642 , 0xFED5, 0xFED7, 0xFED8, 0xFED6}; + static wchar_t KAF[ARABIC_FORM_TYPE_NUM] = {0x0643 , 0xFED9, 0xFEDB, 0xFEDC, 0xFEDA}; + static wchar_t LAM[ARABIC_FORM_TYPE_NUM] = {0x0644 , 0xFEDD, 0xFEDF, 0xFEE0, 0xFEDE}; + static wchar_t MEEM[ARABIC_FORM_TYPE_NUM] = {0x0645 , 0xFEE1, 0xFEE3, 0xFEE4, 0xFEE2}; + static wchar_t NOON[ARABIC_FORM_TYPE_NUM] = {0x0646 , 0xFEE5, 0xFEE7, 0xFEE8, 0xFEE6}; + static wchar_t HEH[ARABIC_FORM_TYPE_NUM] = {0x0647 , 0xFEE9, 0xFEEB, 0xFEEC, 0xFEEA}; + static wchar_t WAW[ARABIC_FORM_TYPE_NUM] = {0x0648 , 0xFEED, 0, 0, 0xFEEE}; + static wchar_t ALEF_MAKSURA[ARABIC_FORM_TYPE_NUM] = {0x0649 , 0xFEEF, 0, 0, 0xFEF0}; + static wchar_t YEH[ARABIC_FORM_TYPE_NUM] = {0x064A , 0xFEF1, 0xFEF3, 0xFEF4, 0xFEF2}; + + switch (code) + { + case 0x0621: return HAMZA[pos];break; + case 0x0622: return ALEF_MADDA[pos];break; + case 0x0623: return ALEF_HAMZA_ABOVE[pos];break; + case 0x0624: return WAW_HAMZA[pos];break; + case 0x0625: return ALEF_HAMZA_BELOW[pos];break; + case 0x0626: return YEH_HAMZA[pos];break; + case 0x0627: return ALEF[pos];break; + case 0x0628: return BEH[pos];break; + case 0x0629: return TEH_MARBUTA[pos];break; + case 0x062A: return TEH[pos];break; + case 0x062B: return THEH[pos];break; + case 0x062C: return JEEM[pos];break; + case 0x062D: return HAH[pos];break; + case 0x062E: return KHAH[pos];break; + case 0x062F: return DAL[pos];break; + case 0x0630: return THAL[pos];break; + case 0x0631: return REH[pos];break; + case 0x0632: return ZAIN[pos];break; + case 0x0633: return SEEN[pos];break; + case 0x0634: return SHEEN[pos];break; + case 0x0635: return SAD[pos];break; + case 0x0636: return DAD[pos];break; + case 0x0637: return TAH[pos];break; + case 0x0638: return ZAH[pos];break; + case 0x0639: return AIN[pos];break; + case 0x063A: return GHAIN[pos];break; + case 0x0640: return TATWEEL[pos];break; + case 0x0641: return OX_FEH[pos];break; + case 0x0642: return QAF[pos];break; + case 0x0643: return KAF[pos];break; + case 0x0644: return LAM[pos];break; + case 0x0645: return MEEM[pos];break; + case 0x0646: return NOON[pos];break; + case 0x0647: return HEH[pos];break; + case 0x0648: return WAW[pos];break; + case 0x0649: return ALEF_MAKSURA[pos];break; + case 0x064A: return YEH[pos];break; + } + return 0; +} + +bool Arabic_IsInMap(wchar_t code) +{ + return (code >= ARABIC_CODE_BASE && code <= ARABIC_CODE_LAST); +} + +bool Arabic_IsInComposing(wchar_t code) +{ + switch (code) + { + case 0x064B: // FATHATAN + case 0x064C: // DAMMATAN + case 0x064D: // KASRATAN + case 0x064E: // FATHA + case 0x064F: // DAMMA + case 0x0650: // KASRA + case 0x0651: // SHADDA + case 0x0652: // SUKUN + case 0x0653: // MADDAH ABOVE + case 0x0654: // HAMZA ABOVE + case 0x0655: // HAMZA BELOW + case 0x0670: // SUPERSCRIPT ALEF + case 0x06D6: // HIGH LIG. SAD WITH LAM WITH ALEF MAKSURA + case 0x06D7: // HIGH LIG. QAF WITH LAM WITH ALEF MAKSURA + case 0x06D8: // HIGH MEEM INITIAL FORM + case 0x06D9: // HIGH LAM ALEF + case 0x06DA: // HIGH JEEM + case 0x06DB: // HIGH THREE DOTS + case 0x06DC: // HIGH SEEN + + // The 2 entires below should not be here - contact unicode.org !! + // case 0x06DD: // END OF AYAH + // case 0x06DE: // START OF RUB EL HIZB + + case 0x06DF: // HIGH ROUNDED ZERO + case 0x06E0: // HIGH UPRIGHT RECTANGULAR ZERO + case 0x06E1: // HIGH DOTLESS HEAD OF KHAH + case 0x06E2: // HIGH MEEM ISOLATED FORM + case 0x06E3: // LOW SEEN + case 0x06E4: // HIGH MADDA + case 0x06E7: // HIGH YEH + case 0x06E8: // HIGH NOON + case 0x06EA: // EMPTY CENTRE LOW STOP + case 0x06EB: // EMPTY CENTRE HIGH STOP + case 0x06EC: // HIGH STOP WITH FILLED CENTRE + case 0x06ED: // LOW MEEM + return true; + } + return false; +} + +bool Arabic_IsNext(wchar_t code) +{ + return (code == 0x0640); +} + +bool Arabic_IsComb1(wchar_t code) +{ + return (code == 0x0644); +} + +bool Arabic_IsComb2(wchar_t code) +{ + switch (code) + { + case 0x0622: + case 0x0623: + case 0x0625: + case 0x0627: + return true; + } + + return false; +} + +size_t Arabic_MakeShape(wchar_t* src, size_t srcLen, wchar_t* dst, size_t dstLen) +{ + assert(dstLen >= srcLen); + + const size_t srcLastIndex = srcLen - 1; + + unsigned dstIndex = 0; + for (size_t srcIndex = 0; srcIndex < srcLen; ++srcIndex) + { + wchar_t cur = src[srcIndex]; + + //printf("now %x\n", cur); + + if (Arabic_IsInMap(cur)) + { + //  + wchar_t prev = 0; + { + size_t prevIndex = srcIndex; + while (prevIndex > 0) + { + prevIndex--; + prev = src[prevIndex]; + //printf("\tprev %d:%x\n", prevIndex, cur); + if (Arabic_IsInComposing(prev)) + continue; + else + break; + } + + if ((srcIndex == 0) || + (!Arabic_IsInMap(prev)) || + (!Arabic_GetMap(prev, INITIAL) && !Arabic_GetMap(prev, MEDIAL))) + { + //printf("\tprev not defined\n"); + prev = 0; + } + } + + //  + wchar_t next = 0; + { + size_t nextIndex = srcIndex; + while (nextIndex < srcLastIndex) + { + nextIndex++; + next = src[nextIndex]; + if (Arabic_IsInComposing(next)) + continue; + else + break; + } + + if ((nextIndex == srcLen) || + (!Arabic_IsInMap(next)) || + (!Arabic_GetMap(next, MEDIAL) && !Arabic_GetMap(next, FINAL) && !Arabic_IsNext(next))) + { + //printf("\tnext not defined\n"); + next = 0; + } + } + + if (Arabic_IsComb1(cur) && Arabic_IsComb2(next)) + { + if (prev) + dst[dstIndex] = Arabic_GetComposition(cur, next, FINAL); + else + dst[dstIndex] = Arabic_GetComposition(cur, next, ISOLATED); + + //printf("\tGot me a complex:%x\n", dst[dstIndex]); + + srcIndex++; + dstIndex++; + } + else if (prev && next && (dst[dstIndex] = Arabic_GetMap(cur, MEDIAL))) + { + //printf("\tGot prev & next:%x\n", dst[dstIndex]); + dstIndex++; + } + else if (prev && (dst[dstIndex] = Arabic_GetMap(cur, FINAL))) + { + //printf("\tGot prev:%x\n", dst[dstIndex]); + dstIndex++; + } + else if (next && (dst[dstIndex] = Arabic_GetMap(cur, INITIAL))) + { + //printf("\tGot next:%x\n", dst[dstIndex]); + dstIndex++; + } + else + { + dst[dstIndex] = Arabic_GetMap(cur, ISOLATED); + //printf("\tGot nothing:%x\n", dst[dstIndex]); + dstIndex++; + } + } + else + { + dst[dstIndex] = cur; + dstIndex++; + } + } + return dstIndex; +} + +wchar_t Arabic_ConvSymbol(wchar_t c) +{ + switch (c) + { + case '(': return')';break; + case ')': return'(';break; + case '<': return'>';break; + case '>': return'<';break; + case '{': return'}';break; + case '}': return'{';break; + case '[': return']';break; + case ']': return '[';break; + default: + return c; + } +} diff --git a/source/EterLocale/Arabic.h b/source/EterLocale/Arabic.h new file mode 100644 index 0000000..6229ce0 --- /dev/null +++ b/source/EterLocale/Arabic.h @@ -0,0 +1,11 @@ +#pragma once + +wchar_t Arabic_ConvSymbol(wchar_t c); + +bool Arabic_IsInSpace(wchar_t code); +bool Arabic_IsInSymbol(wchar_t code); +bool Arabic_IsInPresentation(wchar_t code); +bool Arabic_HasPresentation(wchar_t* codes, int last); +size_t Arabic_MakeShape(wchar_t* src, size_t srcLen, wchar_t* dst, size_t dstLen); +wchar_t Arabic_ConvEnglishModeSymbol(wchar_t code); + diff --git a/source/EterLocale/CodePageId.h b/source/EterLocale/CodePageId.h new file mode 100644 index 0000000..fec6697 --- /dev/null +++ b/source/EterLocale/CodePageId.h @@ -0,0 +1,46 @@ +#pragma once + +#define CP_874 874 // Thai +#define CP_THAI CP_874 + +#define CP_932 932 // Japanese +#define CP_JAPANESE CP_932 + +#define CP_936 936 // Chinese(Simplefied) +#define CP_CHINESE_SIMPLE CP_936 + +#define CP_949 949 // Hangeul +#define CP_HANGUL CP_949 + +#define CP_950 950 // Chinese(Traditional) +#define CP_CHINESE_TRAD CP_950 + +#define CP_1250 1250 // Middle and East Europe +#define CP_EASTEUROPE CP_1250 + +#define CP_1251 1251 // Cyrillic +#define CP_CYRILLIC CP_1251 + +#define CP_1252 1252 // Latin +#define CP_LATIN CP_1252 + +#define CP_1253 1253 // Greek +#define CP_GREEK CP_1253 + +#define CP_1254 1254 // Turkish +#define CP_TURKISH CP_1254 + +#define CP_1255 1255 // Hebrew +#define CP_HEBREW CP_1255 + +#define CP_1256 1256 // Aralic +#define CP_ARABIC CP_1256 + +#define CP_1257 1257 // Baltic +#define CP_BALTIC CP_1257 + +#define CP_1258 1258 // Vietnamese +#define CP_VIETNAMESE CP_1258 + +#define CP_65001 65001 // UTF-8 +//#define CP_UTF8 65001 // UTF-8 translation diff --git a/source/EterLocale/Japanese.cpp b/source/EterLocale/Japanese.cpp new file mode 100644 index 0000000..b2f21b1 --- /dev/null +++ b/source/EterLocale/Japanese.cpp @@ -0,0 +1,71 @@ +#include "StdAfx.h" +#include "Japanese.h" + +// +// CP932: Shift-JIS (Japan Industry Standard) +// + +#define MACRO_IsLeadByte(c) ((0x81 <= (c) && (c) <= 0x9f) || ((0xe0 <= (c)) && (c) <= 0xfc)) +#define MACRO_IsTailByte(c) ((0x40 <= (c) && (c) <= 0x7e) || (0x80 <= (c) && (c) <= 0xfc)) + +BOOL ShiftJIS_IsLeadByte( const char chByte ) +{ + const unsigned char byByte = (const unsigned char) chByte; + + return MACRO_IsLeadByte( byByte ); +} + +BOOL ShiftJIS_IsTrailByte( const char chByte ) +{ + const unsigned char byByte = (const unsigned char) chByte; + + return MACRO_IsTailByte( byByte ); +} + +int ShiftJIS_StringCompareCI( LPCSTR szStringLeft, LPCSTR szStringRight, size_t sizeLength ) +{ + const unsigned char* uszString1 = (const unsigned char*) szStringLeft; + const unsigned char* uszString2 = (const unsigned char*) szStringRight; + unsigned short c1, c2; + + if( sizeLength == 0 ) + return 0; + while( sizeLength-- ) { + c1 = *uszString1++; + if( MACRO_IsLeadByte(c1) ) { + if( sizeLength == 0 ) { + c1 = 0; + c2 = MACRO_IsLeadByte( *uszString2 ) ? 0 : *uszString2; + goto test; + } + if( *uszString1 == '\0' ) + c1 = 0; + else { + c1 = ((c1 << 8) | *uszString1++); + } + } else + c1 = tolower(c1); + + c2 = *uszString2++; + if( MACRO_IsLeadByte(c2) ) { + if( sizeLength == 0 ) { + c2 = 0; + goto test; + } + sizeLength--; + if( *uszString2 == '\0' ) + c2 = 0; + else { + c2 = ((c2 << 8) | *uszString2++); + } + } else + c2 = tolower(c2); +test: + if (c1 != c2) + return( (c1 > c2) ? 1 : -1); + + if (c1 == 0) + return(0); + } + return 0; +} diff --git a/source/EterLocale/Japanese.h b/source/EterLocale/Japanese.h new file mode 100644 index 0000000..05c0b28 --- /dev/null +++ b/source/EterLocale/Japanese.h @@ -0,0 +1,5 @@ +#pragma once + +BOOL ShiftJIS_IsLeadByte( const char chByte ); +BOOL ShiftJIS_IsTrailByte( const char chByte ); +int ShiftJIS_StringCompareCI( LPCSTR szStringLeft, LPCSTR szStringRight, size_t sizeLength ); diff --git a/source/EterLocale/StdAfx.cpp b/source/EterLocale/StdAfx.cpp new file mode 100644 index 0000000..a710b46 --- /dev/null +++ b/source/EterLocale/StdAfx.cpp @@ -0,0 +1,6 @@ +// stdafx.cpp : source file that includes just the standard includes +// eterImageLib.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + diff --git a/source/EterLocale/StdAfx.h b/source/EterLocale/StdAfx.h new file mode 100644 index 0000000..cbc4d1f --- /dev/null +++ b/source/EterLocale/StdAfx.h @@ -0,0 +1,13 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +#include +#include + +#include "CodePageId.h" diff --git a/source/EterLocale/StringCodec.cpp b/source/EterLocale/StringCodec.cpp new file mode 100644 index 0000000..a16724d --- /dev/null +++ b/source/EterLocale/StringCodec.cpp @@ -0,0 +1,43 @@ +#include "stdafx.h" +#include "StringCodec.h" +#include "StringCodec_Vietnamese.h" + +int Ymir_WideCharToMultiByte( + UINT CodePage, + DWORD dwFlags, + LPCWSTR lpWideCharStr, + int cchWideChar, + LPSTR lpMultiByteStr, + int cbMultiByte, + LPCSTR lpDefaultChar, + LPBOOL lpUsedDefaultChar +) +{ + if (CodePage == CP_1258) + { + return EL_String_Encode_Vietnamese(lpWideCharStr, cchWideChar, lpMultiByteStr, cbMultiByte); + } + else + { + return WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, lpMultiByteStr, cbMultiByte, lpDefaultChar, lpUsedDefaultChar); + } +} + +int Ymir_MultiByteToWideChar( + UINT CodePage, + DWORD dwFlags, + LPCSTR lpMultiByteStr, + int cbMultiByte, + LPWSTR lpWideCharStr, + int cchWideChar +) +{ + if (CodePage == CP_1258) + { + return EL_String_Decode_Vietnamese(lpMultiByteStr, cbMultiByte, lpWideCharStr, cchWideChar); + } + else + { + return MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, lpWideCharStr, cchWideChar); + } +} \ No newline at end of file diff --git a/source/EterLocale/StringCodec.h b/source/EterLocale/StringCodec.h new file mode 100644 index 0000000..a937f57 --- /dev/null +++ b/source/EterLocale/StringCodec.h @@ -0,0 +1,21 @@ +#pragma once + +int Ymir_WideCharToMultiByte( + UINT CodePage, + DWORD dwFlags, + LPCWSTR lpWideCharStr, + int cchWideChar, + LPSTR lpMultiByteStr, + int cbMultiByte, + LPCSTR lpDefaultChar, + LPBOOL lpUsedDefaultChar +); + +int Ymir_MultiByteToWideChar( + UINT CodePage, + DWORD dwFlags, + LPCSTR lpMultiByteStr, + int cbMultiByte, + LPWSTR lpWideCharStr, + int cchWideChar +); \ No newline at end of file diff --git a/source/EterLocale/StringCodec_Vietnamese.cpp b/source/EterLocale/StringCodec_Vietnamese.cpp new file mode 100644 index 0000000..eab8978 --- /dev/null +++ b/source/EterLocale/StringCodec_Vietnamese.cpp @@ -0,0 +1,554 @@ +#include "stdafx.h" +#include "StringCodec_Vietnamese.h" + +#pragma warning(disable: 4310) // char 짤림 경고 무시 + +static wchar_t cp1258_to_unicode[256] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x20ac, 0x0081, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, //0x80 + 0x02c6, 0x2030, 0x008a, 0x2039, 0x0152, 0x008d, 0x008e, 0x008f, // + 0x0090, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, //0x90 + 0x02dc, 0x2122, 0x009a, 0x203a, 0x0153, 0x009d, 0x009e, 0x0178, // + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, //0xa0 + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, // + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, //0xb0 + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, // + 0x00c0, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x00c5, 0x00c6, 0x00c7, //0xc0 + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x0300, 0x00cd, 0x00ce, 0x00cf, // + 0x0110, 0x00d1, 0x0309, 0x00d3, 0x00d4, 0x01a0, 0x00d6, 0x00d7, //0xd0 + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x01af, 0x0303, 0x00df, // + 0x00e0, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x00e5, 0x00e6, 0x00e7, //0xe0 + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x0301, 0x00ed, 0x00ee, 0x00ef, // + 0x0111, 0x00f1, 0x0323, 0x00f3, 0x00f4, 0x01a1, 0x00f6, 0x00f7, //0xf0 + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x01b0, 0x20ab, 0x00ff, // +}; + +static wchar_t cp1258_composed_table[][5] = { + { 0x00c1, 0x00c0, 0x1ea2, 0x00c3, 0x1ea0 }, + { 0x00e1, 0x00e0, 0x1ea3, 0x00e3, 0x1ea1 }, + { 0x1eae, 0x1eb0, 0x1eb2, 0x1eb4, 0x1eb6 }, + { 0x1eaf, 0x1eb1, 0x1eb3, 0x1eb5, 0x1eb7 }, + { 0x1ea4, 0x1ea6, 0x1ea8, 0x1eaa, 0x1eac }, + { 0x1ea5, 0x1ea7, 0x1ea9, 0x1eab, 0x1ead }, + { 0x00c9, 0x00c8, 0x1eba, 0x1ebc, 0x1eb8 }, + { 0x00e9, 0x00e8, 0x1ebb, 0x1ebd, 0x1eb9 }, + { 0x1ebe, 0x1ec0, 0x1ec2, 0x1ec4, 0x1ec6 }, + { 0x1ebf, 0x1ec1, 0x1ec3, 0x1ec5, 0x1ec7 }, + { 0x00cd, 0x00cc, 0x1ec8, 0x0128, 0x1eca }, + { 0x00ed, 0x00ec, 0x1ec9, 0x0129, 0x1ecb }, + { 0x00d3, 0x00d2, 0x1ece, 0x00d5, 0x1ecc }, + { 0x00f3, 0x00f2, 0x1ecf, 0x00f5, 0x1ecd }, + { 0x1ed0, 0x1ed2, 0x1ed4, 0x1ed6, 0x1ed8 }, + { 0x1ed1, 0x1ed3, 0x1ed5, 0x1ed7, 0x1ed9 }, + { 0x1eda, 0x1edc, 0x1ede, 0x1ee0, 0x1ee2 }, + { 0x1edb, 0x1edd, 0x1edf, 0x1ee1, 0x1ee3 }, + { 0x00da, 0x00d9, 0x1ee6, 0x0168, 0x1ee4 }, + { 0x00fa, 0x00f9, 0x1ee7, 0x0169, 0x1ee5 }, + { 0x1ee8, 0x1eea, 0x1eec, 0x1eee, 0x1ef0 }, + { 0x1ee9, 0x1eeb, 0x1eed, 0x1eef, 0x1ef1 }, + { 0x00dd, 0x1ef2, 0x1ef6, 0x1ef8, 0x1ef4 }, + { 0x00fd, 0x1ef3, 0x1ef7, 0x1ef9, 0x1ef5 }, +}; + +static bool IsTone(wchar_t tone) +{ + switch(tone) + { + case 0x0300: + case 0x0301: + case 0x0309: + case 0x0303: + case 0x0323: + return true; + default: + return false; + } +} + +static wchar_t ComposeTone(wchar_t prev, wchar_t tone) +{ + int col, row; + + switch(tone) + { + case 0x0301: col = 0; break; + case 0x0300: col = 1; break; + case 0x0309: col = 2; break; + case 0x0303: col = 3; break; + case 0x0323: col = 4; break; + default: + return prev; + } + + switch(prev) + { + case 0x0041: row = 0; break; + case 0x0061: row = 1; break; + case 0x0102: row = 2; break; + case 0x0103: row = 3; break; + case 0x00C2: row = 4; break; + case 0x00E2: row = 5; break; + case 0x0045: row = 6; break; + case 0x0065: row = 7; break; + case 0x00CA: row = 8; break; + case 0x00EA: row = 9; break; + case 0x0049: row = 10; break; + case 0x0069: row = 11; break; + case 0x004F: row = 12; break; + case 0x006F: row = 13; break; + case 0x00D4: row = 14; break; + case 0x00F4: row = 15; break; + case 0x01A0: row = 16; break; + case 0x01A1: row = 17; break; + case 0x0055: row = 18; break; + case 0x0075: row = 19; break; + case 0x01AF: row = 20; break; + case 0x01B0: row = 21; break; + case 0x0059: row = 22; break; + case 0x0079: row = 23; break; + default: + return prev; + } + + return cp1258_composed_table[row][col]; +} + +int EL_String_Decode_Vietnamese(const char* multi, int multiLen, wchar_t* wide, int wideLen) +{ + if(multiLen < 0) + multiLen = (int)strlen(multi) + 1; + + int src = 0; + int dest = 0; + + if(multiLen > 0) + { + /* 첫글자는 무조건 변경 */ + wchar_t prev = cp1258_to_unicode[(BYTE)multi[src++]]; + + while(src < multiLen) + { + wchar_t unicode = cp1258_to_unicode[(BYTE)multi[src]]; + + /* 다음 문자가 Tone 인가? */ + if(IsTone(unicode)) + { + /* 앞의 문자와 합하자. */ + prev = ComposeTone(prev, unicode); + } + else + { + /* 일반 문자가 왔다. 앞 문자를 변환 */ + if(dest < wideLen) + wide[dest++] = prev; + prev = unicode; + } + ++src; + } + + if(dest < wideLen) + wide[dest++] = prev; + } + + return dest; +} + +static bool DecomposeLetter(wchar_t input, char* letter) +{ + switch(input) + { + case 0x00c1: // L'Á' + case 0x00c0: // L'À' + case 0x1ea2: // L'Ả' + case 0x00c3: // L'Ã' + case 0x1ea0: // L'Ạ' + *letter = 'A'; + return true; + case 0x00e1: // L'á' + case 0x00e0: // L'à' + case 0x1ea3: // L'ả' + case 0x00e3: // L'ã' + case 0x1ea1: // L'ạ' + *letter = 'a'; + return true; + case 0x1eae: // L'Ắ' + case 0x1eb0: // L'Ằ' + case 0x1eb2: // L'Ẳ' + case 0x1eb4: // L'Ẵ' + case 0x1eb6: // L'Ặ' + *letter = (char)0xc3; + return true; + case 0x1eaf: // L'ắ' + case 0x1eb1: // L'ằ' + case 0x1eb3: // L'ẳ' + case 0x1eb5: // L'ẵ' + case 0x1eb7: // L'ặ' + *letter = (char)0xe3; + return true; + case 0x1ea4: // L'Ấ' + case 0x1ea6: // L'Ầ' + case 0x1ea8: // L'Ẩ' + case 0x1eaa: // L'Ẫ' + case 0x1eac: // L'Ậ' + *letter = (char)0xc2; + return true; + case 0x1ea5: // L'ấ' + case 0x1ea7: // L'ầ' + case 0x1ea9: // L'ẩ' + case 0x1eab: // L'ẫ' + case 0x1ead: // L'ậ' + *letter = (char)0xe2; + return true; + case 0x00c9: // L'É' + case 0x00c8: // L'È' + case 0x1eba: // L'Ẻ' + case 0x1ebc: // L'Ẽ' + case 0x1eb8: // L'Ẹ' + *letter = (char)'E'; + return true; + case 0x00e9: // L'é' + case 0x00e8: // L'è' + case 0x1ebb: // L'ẻ' + case 0x1ebd: // L'ẽ' + case 0x1eb9: // L'ẹ' + *letter = (char)'e'; + return true; + case 0x1ebe: // L'Ế' + case 0x1ec0: // L'Ề' + case 0x1ec2: // L'Ể' + case 0x1ec4: // L'Ễ' + case 0x1ec6: // L'Ệ' + *letter = (char)0xca; + return true; + case 0x1ebf: // L'ế' + case 0x1ec1: // L'ề' + case 0x1ec3: // L'ể' + case 0x1ec5: // L'ễ' + case 0x1ec7: // L'ệ' + *letter = (char)0xea; + return true; + case 0x00cd: // L'Í' + case 0x00cc: // L'Ì' + case 0x1ec8: // L'Ỉ' + case 0x0128: // L'Ĩ' + case 0x1eca: // L'Ị' + *letter = (char)'I'; + return true; + case 0x00ed: // L'í' + case 0x00ec: // L'ì' + case 0x1ec9: // L'ỉ' + case 0x0129: // L'ĩ' + case 0x1ecb: // L'ị' + *letter = (char)'i'; + return true; + case 0x00d3: // L'Ó' + case 0x00d2: // L'Ò' + case 0x1ece: // L'Ỏ' + case 0x00d5: // L'Õ' + case 0x1ecc: // L'Ọ' + *letter = (char)'O'; + return true; + case 0x00f3: // L'ó' + case 0x00f2: // L'ò' + case 0x1ecf: // L'ỏ' + case 0x00f5: // L'õ' + case 0x1ecd: // L'ọ' + *letter = (char)'o'; + return true; + case 0x1ed0: // L'Ố' + case 0x1ed2: // L'Ồ' + case 0x1ed4: // L'Ổ' + case 0x1ed6: // L'Ỗ' + case 0x1ed8: // L'Ộ' + *letter = (char)0xd4; + return true; + case 0x1ed1: // L'ố' + case 0x1ed3: // L'ồ' + case 0x1ed5: // L'ổ' + case 0x1ed7: // L'ỗ' + case 0x1ed9: // L'ộ' + *letter = (char)0xf4; + return true; + case 0x1eda: // L'Ớ' + case 0x1edc: // L'Ờ' + case 0x1ede: // L'Ở' + case 0x1ee0: // L'Ỡ' + case 0x1ee2: // L'Ợ' + *letter = (char)0xd5; + return true; + case 0x1edb: // L'ớ' + case 0x1edd: // L'ờ' + case 0x1edf: // L'ở' + case 0x1ee1: // L'ỡ' + case 0x1ee3: // L'ợ' + *letter = (char)0xf5; + return true; + case 0x00da: // L'Ú' + case 0x00d9: // L'Ù' + case 0x1ee6: // L'Ủ' + case 0x0168: // L'Ũ' + case 0x1ee4: // L'Ụ' + *letter = (char)'U'; + return true; + case 0x00fa: // L'ú' + case 0x00f9: // L'ù' + case 0x1ee7: // L'ủ' + case 0x0169: // L'ũ' + case 0x1ee5: // L'ụ' + *letter = (char)'u'; + return true; + case 0x1ee8: // L'Ứ' + case 0x1eea: // L'Ừ' + case 0x1eec: // L'Ử' + case 0x1eee: // L'Ữ' + case 0x1ef0: // L'Ự' + *letter = (char)0xdd; + return true; + case 0x1ee9: // L'ứ' + case 0x1eeb: // L'ừ' + case 0x1eed: // L'ử' + case 0x1eef: // L'ữ' + case 0x1ef1: // L'ự' + *letter = (char)0xfd; + return true; + case 0x1ef2: // L'Ỳ' + case 0x00dd: // L'Ý' + case 0x1ef6: // L'Ỷ' + case 0x1ef8: // L'Ỹ' + case 0x1ef4: // L'Ỵ' + *letter = (char)'Y'; + return true; + case 0x1ef3: // L'ỳ' + case 0x00fd: // L'ý' + case 0x1ef7: // L'ỷ' + case 0x1ef9: // L'ỹ' + case 0x1ef5: // L'ỵ' + *letter = (char)'y'; + return true; + case 0x0102: // L'Ă' + *letter = (char)0xc3; + return true; + case 0x0103: // L'ă' + *letter = (char)0xe3; + return true; + case 0x0110: // L'Đ' + *letter = (char)0xd0; + return true; + case 0x0111: // L'đ' + *letter = (char)0xf0; + return true; + case 0x01a0: // L'Ơ' + *letter = (char)0xd5; + return true; + case 0x01a1: // L'ơ' + *letter = (char)0xf5; + return true; + case 0x01af: // L'Ư' + *letter = (char)0xdd; + return true; + case 0x01b0: // L'ư' + *letter = (char)0xfd; + return true; + case 0x20ab: // L'₫' + *letter = (char)0xfe; + return true; + case 0x201c: // L'“' + *letter = (char)'"'; + return true; + case 0x201d: // L'”' + *letter = (char)'"'; + return true; + } + + if(input < 256) + { + *letter = (char)input; + return true; + } + return false; +} + +static bool DecomposeTone(wchar_t input, char* tone) +{ + switch(input) + { + case 0x00c1: // L'Á' + case 0x00e1: // L'á' + case 0x1eae: // L'Ắ' + case 0x1eaf: // L'ắ' + case 0x1ea4: // L'Ấ' + case 0x1ea5: // L'ấ' + case 0x00c9: // L'É' + case 0x00e9: // L'é' + case 0x1ebe: // L'Ế' + case 0x1ebf: // L'ế' + case 0x00cd: // L'Í' + case 0x00ed: // L'í' + case 0x00d3: // L'Ó' + case 0x00f3: // L'ó' + case 0x1ed0: // L'Ố' + case 0x1ed1: // L'ố' + case 0x1eda: // L'Ớ' + case 0x1edb: // L'ớ' + case 0x00da: // L'Ú' + case 0x00fa: // L'ú' + case 0x1ee8: // L'Ứ' + case 0x1ee9: // L'ứ' + case 0x00dd: // L'Ý' + case 0x00fd: // L'ý' + *tone = (char)0xec; + return true; + case 0x00c0: // L'À' + case 0x00e0: // L'à' + case 0x1eb0: // L'Ằ' + case 0x1eb1: // L'ằ' + case 0x1ea6: // L'Ầ' + case 0x1ea7: // L'ầ' + case 0x00c8: // L'È' + case 0x00e8: // L'è' + case 0x1ec0: // L'Ề' + case 0x1ec1: // L'ề' + case 0x00cc: // L'Ì' + case 0x00ec: // L'ì' + case 0x00d2: // L'Ò' + case 0x00f2: // L'ò' + case 0x1ed2: // L'Ồ' + case 0x1ed3: // L'ồ' + case 0x1edc: // L'Ờ' + case 0x1edd: // L'ờ' + case 0x00d9: // L'Ù' + case 0x00f9: // L'ù' + case 0x1eea: // L'Ừ' + case 0x1eeb: // L'ừ' + case 0x1ef2: // L'Ỳ' + case 0x1ef3: // L'ỳ' + *tone = (char)0xcc; + return true; + case 0x1ea2: // L'Ả' + case 0x1ea3: // L'ả' + case 0x1eb2: // L'Ẳ' + case 0x1eb3: // L'ẳ' + case 0x1ea8: // L'Ẩ' + case 0x1ea9: // L'ẩ' + case 0x1eba: // L'Ẻ' + case 0x1ebb: // L'ẻ' + case 0x1ec2: // L'Ể' + case 0x1ec3: // L'ể' + case 0x1ec8: // L'Ỉ' + case 0x1ec9: // L'ỉ' + case 0x1ece: // L'Ỏ' + case 0x1ecf: // L'ỏ' + case 0x1ed4: // L'Ổ' + case 0x1ed5: // L'ổ' + case 0x1ede: // L'Ở' + case 0x1edf: // L'ở' + case 0x1ee6: // L'Ủ' + case 0x1ee7: // L'ủ' + case 0x1eec: // L'Ử' + case 0x1eed: // L'ử' + case 0x1ef6: // L'Ỷ' + case 0x1ef7: // L'ỷ' + *tone = (char)0xd2; + return true; + case 0x00c3: // L'Ã' + case 0x00e3: // L'ã' + case 0x1eb4: // L'Ẵ' + case 0x1eb5: // L'ẵ' + case 0x1eaa: // L'Ẫ' + case 0x1eab: // L'ẫ' + case 0x1ebc: // L'Ẽ' + case 0x1ebd: // L'ẽ' + case 0x1ec4: // L'Ễ' + case 0x1ec5: // L'ễ' + case 0x0128: // L'Ĩ' + case 0x0129: // L'ĩ' + case 0x00d5: // L'Õ' + case 0x00f5: // L'õ' + case 0x1ed6: // L'Ỗ' + case 0x1ed7: // L'ỗ' + case 0x1ee0: // L'Ỡ' + case 0x1ee1: // L'ỡ' + case 0x0169: // L'ũ' + case 0x0168: // L'Ũ' + case 0x1eee: // L'Ữ' + case 0x1eef: // L'ữ' + case 0x1ef8: // L'Ỹ' + case 0x1ef9: // L'ỹ' + *tone = (char)0xde; + return true; + case 0x1ea0: // L'Ạ' + case 0x1ea1: // L'ạ' + case 0x1eb6: // L'Ặ' + case 0x1eb7: // L'ặ' + case 0x1eac: // L'Ậ' + case 0x1ead: // L'ậ' + case 0x1eb8: // L'Ẹ' + case 0x1eb9: // L'ẹ' + case 0x1ec6: // L'Ệ' + case 0x1ec7: // L'ệ' + case 0x1eca: // L'Ị' + case 0x1ecb: // L'ị' + case 0x1ecc: // L'Ọ' + case 0x1ecd: // L'ọ' + case 0x1ed8: // L'Ộ' + case 0x1ed9: // L'ộ' + case 0x1ee2: // L'Ợ' + case 0x1ee3: // L'ợ' + case 0x1ee4: // L'Ụ' + case 0x1ee5: // L'ụ' + case 0x1ef0: // L'Ự' + case 0x1ef1: // L'ự' + case 0x1ef4: // L'Ỵ' + case 0x1ef5: // L'ỵ' + *tone = (char)0xf2; + return true; + } + + return false; +} + +int EL_String_Encode_Vietnamese(const wchar_t* wide, int wideLen, char* multi, int multiLen) +{ + if(wideLen < 0) + wideLen = (int)wcslen(wide) + 1; + + int src = 0; + int dest = 0; + + if(wideLen > 0) + { + while(src < wideLen && dest < multiLen) + { + char letter; + if(DecomposeLetter(wide[src], &letter)) + { + multi[dest++] = letter; + } + + char tone; + if(DecomposeTone(wide[src], &tone) && dest < multiLen) + { + multi[dest++] = tone; + } + + ++src; + } + } + + return dest; +} \ No newline at end of file diff --git a/source/EterLocale/StringCodec_Vietnamese.h b/source/EterLocale/StringCodec_Vietnamese.h new file mode 100644 index 0000000..d1856e0 --- /dev/null +++ b/source/EterLocale/StringCodec_Vietnamese.h @@ -0,0 +1,4 @@ +#pragma once + +int EL_String_Decode_Vietnamese(const char* multi, int multiLen, wchar_t* wide, int wideLen); +int EL_String_Encode_Vietnamese(const wchar_t* wide, int wideLen, char* multi, int multiLen); \ No newline at end of file diff --git a/source/EterPack/EterPack.cpp b/source/EterPack/EterPack.cpp new file mode 100644 index 0000000..d5ae752 --- /dev/null +++ b/source/EterPack/EterPack.cpp @@ -0,0 +1,1615 @@ +#include "StdAfx.h" + +#include +#include +#include +#include + +#include "EterPack.h" +#include "Inline.h" +#include "EterPackPolicy_CSHybridCrypt.h" + +#pragma warning(push, 3) +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#pragma warning(pop) + +#include "../EterBase/utils.h" +#include "../EterBase/Debug.h" +#include "../EterBase/CRC32.h" + +#ifdef __THEMIDA__ +#include +#endif + +#include +#include + +void CMakePackLog::SetFileName(const char* c_szFileName) +{ + m_stFileName=c_szFileName; + m_stFileName +=".log"; + m_stErrorFileName = c_szFileName; + m_stErrorFileName += ".err"; +} + +CMakePackLog& CMakePackLog::GetSingleton() +{ + static CMakePackLog s_kMakePackLog; + return s_kMakePackLog; +} + +CMakePackLog::CMakePackLog() +{ + m_fp=NULL; + m_fp_err = NULL; +} + +CMakePackLog::~CMakePackLog() +{ + if (NULL!=m_fp) + { + fclose(m_fp); + m_fp=NULL; + } + if (NULL != m_fp_err) + { + fclose(m_fp_err); + m_fp_err = NULL; + } +} + +bool CMakePackLog::__IsLogMode() +{ + if (m_stFileName.empty()) + return false; + + return true; +} + +void CMakePackLog::Writef(const char* c_szFormat, ...) +{ + if (!__IsLogMode()) + return; + + va_list args; + va_start(args, c_szFormat); + + char szBuf[1024]; + int nBufLen = _vsnprintf(szBuf, sizeof(szBuf), c_szFormat, args); + szBuf[nBufLen++] = '\0'; + __Write(szBuf, nBufLen); +} + +void CMakePackLog::Writenf(const char* c_szFormat, ...) +{ + if (!__IsLogMode()) + return; + + va_list args; + va_start(args, c_szFormat); + + char szBuf[1024+1]; + int nBufLen = _vsnprintf(szBuf, sizeof(szBuf)-1, c_szFormat, args); + if (nBufLen > 0) + { + szBuf[nBufLen++] = '\n'; + szBuf[nBufLen++] = '\0'; + } + __Write(szBuf, nBufLen); +} + +void CMakePackLog::Write(const char* c_szBuf) +{ + if (!__IsLogMode()) + return; + + __Write(c_szBuf, strlen(c_szBuf)+1); +} + +void CMakePackLog::__Write(const char* c_szBuf, int nBufLen) +{ + if (!__IsLogMode()) + return; + + if (NULL==m_fp) + m_fp=fopen(m_stFileName.c_str(), "w"); + + fwrite(c_szBuf, nBufLen, 1, m_fp); + + printf("%s", c_szBuf); +} + + + +void CMakePackLog::WriteErrorf(const char* c_szFormat, ...) +{ + if (!__IsLogMode()) + return; + + va_list args; + va_start(args, c_szFormat); + + char szBuf[1024]; + int nBufLen = _vsnprintf(szBuf, sizeof(szBuf), c_szFormat, args); + szBuf[nBufLen++] = '\0'; + __WriteError(szBuf, nBufLen); +} + +void CMakePackLog::WriteErrornf(const char* c_szFormat, ...) +{ + if (!__IsLogMode()) + return; + + va_list args; + va_start(args, c_szFormat); + + char szBuf[1024+1]; + int nBufLen = _vsnprintf(szBuf, sizeof(szBuf)-1, c_szFormat, args); + if (nBufLen > 0) + { + szBuf[nBufLen++] = '\n'; + szBuf[nBufLen++] = '\0'; + } + __WriteError(szBuf, nBufLen); +} + +void CMakePackLog::WriteError(const char* c_szBuf) +{ + if (!__IsLogMode()) + return; + + __WriteError(c_szBuf, strlen(c_szBuf)+1); +} + +void CMakePackLog::__WriteError(const char* c_szBuf, int nBufLen) +{ + if (!__IsLogMode()) + return; + + if (NULL==m_fp_err) + m_fp_err=fopen(m_stErrorFileName.c_str(), "w"); + + fwrite(c_szBuf, nBufLen, 1, m_fp_err); + + printf("Error: %s", c_szBuf); +} + +void CMakePackLog::FlushError() +{ + std::wifstream iFile(m_stErrorFileName.c_str()); + std::istream_iterator iit(iFile); + std::istream_iterator eos; + + std::vector vText; + + std::copy (iit, eos, std::back_inserter(vText)); + + std::ostream_iterator > oit(std::wcout); + + std::sort (vText.begin(), vText.end()); + std::copy (vText.begin(), vText.end(), oit); +} +#ifdef __MAKE_PACK__ +FILE * CEterPack::ms_PackLogFile = NULL; +#endif +/////////////////////////////////////////////////////////////////////////////// +CEterPack::CEterPack() : m_indexCount(0), m_indexData(NULL), m_FragmentSize(0), m_bEncrypted(false), m_bReadOnly(false), m_bDecrypedIV(false) +{ + m_pCSHybridCryptPolicy = new EterPackPolicy_CSHybridCrypt; + +} + +CEterPack::~CEterPack() +{ + Destroy(); + + delete m_pCSHybridCryptPolicy; + m_pCSHybridCryptPolicy = NULL; +} + +void CEterPack::Destroy() +{ + m_bReadOnly = false; + m_bEncrypted = false; + m_indexCount = 0; + m_DataPositionMap.clear(); + + for (int i = 0; i < FREE_INDEX_MAX_SIZE + 1; ++i) + m_FreeIndexList[i].clear(); + + SAFE_DELETE_ARRAY(m_indexData); + + m_FragmentSize = 0; + + memset(m_dbName, 0, sizeof(m_dbName)); + memset(m_indexFileName, 0, sizeof(m_indexFileName)); +} + +const std::string& CEterPack::GetPathName() +{ + return m_stPathName; +} + +bool CEterPack::Create(CEterFileDict& rkFileDict, const char * dbname, const char* pathName, bool bReadOnly, const BYTE* iv) +{ + if (iv) + { + m_stIV_Panama.assign((const char*) iv, 32); + m_bDecrypedIV = false; + } + + m_stPathName = pathName; + + strncpy(m_dbName, dbname, DBNAME_MAX_LEN); + + strncpy(m_indexFileName, dbname, MAX_PATH); + strcat(m_indexFileName, ".eix"); + + m_stDataFileName = dbname; + m_stDataFileName += ".epk"; + + m_bReadOnly = bReadOnly; + + // bReadOnly 尡 ƴϰ ̽ ٸ + if (!CreateIndexFile()) + return false; + + if (!CreateDataFile()) + return false; + + bool bOverwrite = (iv != NULL); + __BuildIndex(rkFileDict, bOverwrite); + + if (m_bReadOnly) + { + //m_bIsDataLoaded = true; + //if (!m_file.Create(m_stDataFileName.c_str(), (const void**)&m_file_data, 0, 0)) + // return false; + } + else + { + DecryptIndexFile(); + } + + return true; +} + +bool CEterPack::DecryptIV(DWORD dwPanamaKey) +{ + if (m_stIV_Panama.length() != 32) + return false; + + if (m_bDecrypedIV) // ̹ ȣȭ Ǯ ٽ ó + return true; + + DWORD* ivs = (DWORD*)&m_stIV_Panama[0]; + for (int i = 0; i != m_stIV_Panama.length() / sizeof(DWORD); ++i) + { + ivs[i] ^= dwPanamaKey + i * 16777619; + } + + m_bDecrypedIV = true; + return true; +} + +bool CEterPack::DecryptIndexFile() +{ + if (!m_bEncrypted) + return true; + + CFileBase file; + + if (!file.Create(m_indexFileName, CFileBase::FILEMODE_WRITE)) + return false; + + file.Write(&eterpack::c_IndexCC, sizeof(DWORD)); + file.Write(&eterpack::c_Version, sizeof(DWORD)); + file.Write(&m_indexCount, sizeof(long)); + file.Write(m_indexData, sizeof(TEterPackIndex) * m_indexCount); + + file.Close(); + + m_bEncrypted = false; + return true; +} + +static DWORD s_adwEterPackKey[] = +{ + 45129401, + 92367215, + 681285731, + 1710201, +}; + +static DWORD s_adwEterPackSecurityKey[] = +{ + 78952482, + 527348324, + 1632942, + 486274726, +}; + +bool CEterPack::EncryptIndexFile() +{ + CMappedFile file; + LPCVOID pvData; + + if (NULL == file.Create(m_indexFileName, &pvData, 0, 0)) + { + TraceError("EncryptIndex: Cannot open pack index file! %s", m_dbName); + return false; + } + + BYTE * pbData = new BYTE[file.Size()]; + memcpy(pbData, pvData, file.Size()); + + CLZObject zObj; + + if (!CLZO::Instance().CompressEncryptedMemory(zObj, pbData, file.Size(), s_adwEterPackKey)) + { + TraceError("EncryptIndex: Cannot encrypt! %s", m_dbName); + SAFE_DELETE_ARRAY(pbData); + return false; + } + + file.Destroy(); + + while (!DeleteFile(m_indexFileName)); + + FILE * fp; + + fp = fopen(m_indexFileName, "wb"); + + if (!fp) + { + TraceError("EncryptIndex: Cannot open file for writing! %s", m_dbName); + SAFE_DELETE_ARRAY(pbData); + return false; + } + + if (1 != fwrite(zObj.GetBuffer(), zObj.GetSize(), 1, fp)) + { + TraceError("Encryptindex: Cannot write to file! %s", m_indexFileName); + SAFE_DELETE_ARRAY(pbData); + fclose(fp); + return false; + } + + fclose(fp); + + m_bEncrypted = true; + delete [] pbData; + return true; +} + +bool CEterPack::__BuildIndex(CEterFileDict& rkFileDict, bool bOverwrite) +{ + //DWORD dwBeginTime = ELTimer_GetMSec(); + CMappedFile file; + LPCVOID pvData; + CLZObject zObj; + + if (NULL == file.Create(m_indexFileName, &pvData, 0, 0)) + { + TraceError("Cannot open pack index file! %s", m_dbName); + return false; + } + + if (file.Size() < eterpack::c_HeaderSize) + { + TraceError("Pack index file header error! %s", m_dbName); + return false; + } + + DWORD fourcc = *(DWORD *) pvData; + + BYTE * pbData; + UINT uiFileSize; + + if (fourcc == eterpack::c_IndexCC) + { + pbData = (BYTE *) pvData; + uiFileSize = file.Size(); + } + else if (fourcc == CLZObject::ms_dwFourCC) + { + m_bEncrypted = true; + + if (!CLZO::Instance().Decompress(zObj, (const BYTE *) pvData, s_adwEterPackKey)) + return false; + + if (zObj.GetSize() < eterpack::c_HeaderSize) + return false; + + pbData = zObj.GetBuffer(); + uiFileSize = zObj.GetSize(); + } + else + { + TraceError("Pack index file fourcc error! %s", m_dbName); + return false; + } + + pbData += sizeof(DWORD); + + DWORD ver = *(DWORD *) pbData; + pbData += sizeof(DWORD); + + if (ver != eterpack::c_Version) + { + TraceError("Pack index file version error! %s", m_dbName); + return false; + } + + m_indexCount = *(long *) pbData; + pbData += sizeof(long); + + if (uiFileSize < eterpack::c_HeaderSize + sizeof(TEterPackIndex) * m_indexCount) + { + TraceError("Pack index file size error! %s, indexCount %d", m_dbName, m_indexCount); + return false; + } + + //Tracef("Loading Pack file %s elements: %d ... ", m_dbName, m_indexCount); + + m_indexData = new TEterPackIndex[m_indexCount]; + memcpy(m_indexData, pbData, sizeof(TEterPackIndex) * m_indexCount); + + TEterPackIndex * index = m_indexData; + + for (int i = 0; i < m_indexCount; ++i, ++index) + { + if (!index->filename_crc) + { + PushFreeIndex(index); + } + else + { + if (index->real_data_size > index->data_size) + m_FragmentSize += index->real_data_size - index->data_size; + + m_DataPositionMap.insert(TDataPositionMap::value_type(index->filename_crc, index)); + + if (bOverwrite) // ŷ ߿ ֻ ؾѴ + rkFileDict.UpdateItem(this, index); + else + rkFileDict.InsertItem(this, index); + } + } + + //Tracef("Done. (spent %dms)\n", ELTimer_GetMSec() - dwBeginTime); + return true; +} +// +//void CEterPack::UpdateLastAccessTime() +//{ +// m_tLastAccessTime = time(NULL); +//} +// +//void CEterPack::ClearDataMemoryMap() +//{ +// // m_file data file̴... +// m_file.Destroy(); +// m_tLastAccessTime = 0; +// m_bIsDataLoaded = false; +//} + +bool CEterPack::Get(CMappedFile& out_file, const char * filename, LPCVOID * data) +{ + TEterPackIndex * index = FindIndex(filename); + + if (!index) + { + return false; + } + + //UpdateLastAccessTime(); + //if (!m_bIsDataLoaded) + //{ + // if (!m_file.Create(m_stDataFileName.c_str(), (const void**)&m_file_data, 0, 0)) + // return false; + // + // m_bIsDataLoaded = true; + //} + + // CEterPack epk memory map ÷, û κ ũؼ Ѱ µ, + // û , ʿ κи memory map ø, û ϰ . + out_file.Create(m_stDataFileName.c_str(), data, index->data_position, index->data_size); + + bool bIsSecurityCheckRequired = ( index->compressed_type == COMPRESSED_TYPE_SECURITY || + index->compressed_type == COMPRESSED_TYPE_PANAMA ); + + if( bIsSecurityCheckRequired ) + { +#ifdef CHECKSUM_CHECK_MD5 + MD5_CTX context; + GenerateMD5Hash( (BYTE*)(*data), index->data_size, context ); + + if( memcmp( index->MD5Digest, context.digest, 16 ) != 0 ) + { + return false; + } +#else + DWORD dwCrc32 = GetCRC32((const char*)(*data), index->data_size); + + if( index->data_crc != dwCrc32 ) + { + return false; + } +#endif + } + + + if (COMPRESSED_TYPE_COMPRESS == index->compressed_type) + { + CLZObject * zObj = new CLZObject; + + if (!CLZO::Instance().Decompress(*zObj, static_cast(*data))) + { + TraceError("Failed to decompress : %s", filename); + delete zObj; + return false; + } + + out_file.BindLZObject(zObj); + *data = zObj->GetBuffer(); + } + else if (COMPRESSED_TYPE_SECURITY == index->compressed_type) + { + CLZObject * zObj = new CLZObject; + + if (!CLZO::Instance().Decompress(*zObj, static_cast(*data), s_adwEterPackSecurityKey)) + { + TraceError("Failed to encrypt : %s", filename); + delete zObj; + return false; + } + + out_file.BindLZObject(zObj); + *data = zObj->GetBuffer(); + } + else if (COMPRESSED_TYPE_PANAMA == index->compressed_type) + { + CLZObject* zObj = new CLZObject; + if (!__Decrypt_Panama(filename, static_cast(*data), index->data_size, *zObj)) + { + delete zObj; + return false; + } + + out_file.BindLZObjectWithBufferedSize(zObj); + *data = zObj->GetBuffer(); + } + else if (COMPRESSED_TYPE_HYBRIDCRYPT == index->compressed_type || COMPRESSED_TYPE_HYBRIDCRYPT_WITHSDB == index->compressed_type) + { +#ifdef __THEMIDA__ + VM_START +#endif + + CLZObject * zObj = new CLZObject; + auto ssvv = std::string(filename); + if (!m_pCSHybridCryptPolicy->DecryptMemory(ssvv, static_cast(*data), index->data_size, *zObj)) + { + delete zObj; + return false; + } + + out_file.BindLZObjectWithBufferedSize(zObj); + if( COMPRESSED_TYPE_HYBRIDCRYPT_WITHSDB == index->compressed_type) + { + BYTE* pSDBData; + int iSDBSize; + + if (!m_pCSHybridCryptPolicy->GetSupplementaryDataBlock(ssvv, pSDBData, iSDBSize)) + { + delete zObj; + return false; + } + + *data = out_file.AppendDataBlock( pSDBData, iSDBSize ); + } + else + { + *data = zObj->GetBuffer(); + } +#ifdef __THEMIDA__ + VM_END +#endif + } + return true; +} + +bool CEterPack::Get2(CMappedFile& out_file, const char * filename, TEterPackIndex * index, LPCVOID * data) +{ + if (!index) + { + return false; + } + + //UpdateLastAccessTime(); + //if (!m_bIsDataLoaded) + //{ + // if (!m_file.Create(m_stDataFileName.c_str(), (const void**)&m_file_data, 0, 0)) + // return false; + // + // m_bIsDataLoaded = true; + //} + out_file.Create(m_stDataFileName.c_str(), data, index->data_position, index->data_size); + + bool bIsSecurityCheckRequired = ( index->compressed_type == COMPRESSED_TYPE_SECURITY || + index->compressed_type == COMPRESSED_TYPE_PANAMA ); + + if( bIsSecurityCheckRequired ) + { +#ifdef CHECKSUM_CHECK_MD5 + MD5_CTX context; + GenerateMD5Hash( (BYTE*)(*data), index->data_size, context ); + + if( memcmp( index->MD5Digest, context.digest, 16 ) != 0 ) + { + return false; + } +#else + DWORD dwCrc32 = GetCRC32((const char*)(*data), index->data_size); + + if( index->data_crc != dwCrc32 ) + { + return false; + } +#endif + } + + + if (COMPRESSED_TYPE_COMPRESS == index->compressed_type) + { + CLZObject * zObj = new CLZObject; + + if (!CLZO::Instance().Decompress(*zObj, static_cast(*data))) + { + TraceError("Failed to decompress : %s", filename); + delete zObj; + return false; + } + + out_file.BindLZObject(zObj); + *data = zObj->GetBuffer(); + } + else if (COMPRESSED_TYPE_SECURITY == index->compressed_type) + { + CLZObject * zObj = new CLZObject; + + if (!CLZO::Instance().Decompress(*zObj, static_cast(*data), s_adwEterPackSecurityKey)) + { + TraceError("Failed to encrypt : %s", filename); + delete zObj; + return false; + } + + out_file.BindLZObject(zObj); + *data = zObj->GetBuffer(); + } + else if (COMPRESSED_TYPE_PANAMA == index->compressed_type) + { + CLZObject * zObj = new CLZObject; + __Decrypt_Panama(filename, static_cast(*data), index->data_size, *zObj); + out_file.BindLZObjectWithBufferedSize(zObj); + *data = zObj->GetBuffer(); + } + else if (COMPRESSED_TYPE_HYBRIDCRYPT == index->compressed_type || COMPRESSED_TYPE_HYBRIDCRYPT_WITHSDB == index->compressed_type) + { +#ifdef __THEMIDA__ + VM_START +#endif + + CLZObject * zObj = new CLZObject; + auto ssvv = std::string(filename); + if( !m_pCSHybridCryptPolicy->DecryptMemory(ssvv, static_cast(*data), index->data_size, *zObj) ) + { + delete zObj; + return false; + } + + out_file.BindLZObjectWithBufferedSize(zObj); + + if( COMPRESSED_TYPE_HYBRIDCRYPT_WITHSDB == index->compressed_type) + { + BYTE* pSDBData; + int iSDBSize; + + if( !m_pCSHybridCryptPolicy->GetSupplementaryDataBlock(ssvv, pSDBData, iSDBSize) ) + { + return false; + } + + *data = out_file.AppendDataBlock( pSDBData, iSDBSize ); + } + else + { + *data = zObj->GetBuffer(); + } +#ifdef __THEMIDA__ + VM_END +#endif + } + + return true; +} + + +bool CEterPack::Delete(TEterPackIndex * pIndex) +{ + CFileBase fileIndex; + + if (!fileIndex.Create(m_indexFileName, CFileBase::FILEMODE_WRITE)) + return false; + + PushFreeIndex(pIndex); + WriteIndex(fileIndex, pIndex); + return true; +} + +bool CEterPack::Delete(const char * filename) +{ + TEterPackIndex * pIndex = FindIndex(filename); + + if (!pIndex) + return false; + + return Delete(pIndex); +} + +bool CEterPack::Extract() +{ + CMappedFile dataMapFile; + LPCVOID data; + + if (!dataMapFile.Create(m_stDataFileName.c_str(), &data, 0, 0)) + return false; + + CLZObject zObj; + + for (TDataPositionMap::iterator i = m_DataPositionMap.begin(); + i != m_DataPositionMap.end(); + ++i) + { + TEterPackIndex* index = i->second; + CFileBase writeFile; + + inlinePathCreate(index->filename); + printf("%s\n", index->filename); + + writeFile.Create(index->filename, CFileBase::FILEMODE_WRITE); + + if (COMPRESSED_TYPE_COMPRESS == index->compressed_type) + { + if (!CLZO::Instance().Decompress(zObj, (const BYTE *) data + index->data_position)) + { + printf("cannot decompress"); + return false; + } + + writeFile.Write(zObj.GetBuffer(), zObj.GetSize()); + zObj.Clear(); + } + else if (COMPRESSED_TYPE_SECURITY == index->compressed_type) + { + if (!CLZO::Instance().Decompress(zObj, (const BYTE *) data + index->data_position, s_adwEterPackSecurityKey)) + { + printf("cannot decompress"); + return false; + } + + writeFile.Write(zObj.GetBuffer(), zObj.GetSize()); + zObj.Clear(); + } + else if (COMPRESSED_TYPE_PANAMA == index->compressed_type) + { + __Decrypt_Panama(index->filename, (const BYTE *) data + index->data_position, index->data_size, zObj); + writeFile.Write(zObj.GetBuffer(), zObj.GetBufferSize()); + zObj.Clear(); + } + else if (COMPRESSED_TYPE_HYBRIDCRYPT == index->compressed_type || COMPRESSED_TYPE_HYBRIDCRYPT_WITHSDB == index->compressed_type) + { +#ifdef __THEMIDA__ + VM_START +#endif + auto ssvv = std::string(index->filename); + if( !m_pCSHybridCryptPolicy->DecryptMemory(ssvv, (const BYTE *) data + index->data_position, index->data_size, zObj) ) + return false; + + if( COMPRESSED_TYPE_HYBRIDCRYPT_WITHSDB == index->compressed_type) + { + dataMapFile.BindLZObjectWithBufferedSize(&zObj); + + BYTE* pSDBData; + int iSDBSize; + + if( !m_pCSHybridCryptPolicy->GetSupplementaryDataBlock(ssvv, pSDBData, iSDBSize) ) + return false; + + dataMapFile.AppendDataBlock( pSDBData, iSDBSize ); + writeFile.Write(dataMapFile.AppendDataBlock( pSDBData, iSDBSize ),dataMapFile.Size()); + } + else + { + writeFile.Write(zObj.GetBuffer(), zObj.GetBufferSize()); + } + zObj.Clear(); +#ifdef __THEMIDA__ + VM_END +#endif + } + else if (COMPRESSED_TYPE_NONE == index->compressed_type) + writeFile.Write((const char *) data + index->data_position, index->data_size); + + writeFile.Destroy(); + } + return true; +} + +bool CEterPack::GetNames(std::vector* retNames) +{ + CMappedFile dataMapFile; + LPCVOID data; + + if (!dataMapFile.Create(m_stDataFileName.c_str(), &data, 0, 0)) + return false; + + CLZObject zObj; + + for (TDataPositionMap::iterator i = m_DataPositionMap.begin(); + i != m_DataPositionMap.end(); + ++i) + { + TEterPackIndex* index = i->second; + + inlinePathCreate(index->filename); + + retNames->push_back(index->filename); + } + return true; +} + +bool CEterPack::Put(const char * filename, const char * sourceFilename, BYTE packType, const std::string& strRelateMapName ) +{ + CMappedFile mapFile; + LPCVOID data; + + if (sourceFilename) + { + if (!mapFile.Create(sourceFilename, &data, 0, 0)) + { + return false; + } + } + else if (!mapFile.Create(filename, &data, 0, 0)) + { + return false; + } + + BYTE* pMappedData = (BYTE*)data; + int iMappedDataSize = mapFile.Size(); + + if( packType == COMPRESSED_TYPE_HYBRIDCRYPT || packType == COMPRESSED_TYPE_HYBRIDCRYPT_WITHSDB ) + { +#ifdef __THEMIDA__ + VM_START +#endif + auto ssvvv = std::string(filename); + m_pCSHybridCryptPolicy->GenerateCryptKey(ssvvv); + + if( packType == COMPRESSED_TYPE_HYBRIDCRYPT_WITHSDB ) + { + if( !m_pCSHybridCryptPolicy->GenerateSupplementaryDataBlock(ssvvv, strRelateMapName, (const BYTE*)data, mapFile.Size(), pMappedData, iMappedDataSize )) + { + return false; + } + } +#ifdef __THEMIDA__ + VM_END +#endif + } + + return Put(filename, pMappedData, iMappedDataSize, packType); +} + +#ifdef CHECKSUM_CHECK_MD5 +void CEterPack::GenerateMD5Hash( BYTE* pData, int nLength, IN OUT MD5_CTX& mdContext ) +{ + MD5Init (&mdContext); + + const int nBlockSize = 1024; + + int nLoopCnt = nLength / nBlockSize; + int nRemainder = nLength % nBlockSize; + int i; + + for(i = 0; i < nLoopCnt; ++i ) + { + MD5Update (&mdContext, reinterpret_cast(pData + i*nBlockSize), nBlockSize); + } + + if( nRemainder > 0 ) + MD5Update (&mdContext, reinterpret_cast(pData + i*nBlockSize), nRemainder); + + MD5Final (&mdContext); +} +#endif +bool CEterPack::Put(const char * filename, LPCVOID data, long len, BYTE packType) +{ + if (m_bEncrypted) + { + TraceError("EterPack::Put : Cannot put to encrypted pack (filename: %s, DB: %s)", filename, m_dbName); + return false; + } + + CFileBase fileIndex; + + if (!fileIndex.Create(m_indexFileName, CFileBase::FILEMODE_WRITE)) + { + return false; + } + + CFileBase fileData; + + if (!fileData.Create(m_stDataFileName.c_str(), CFileBase::FILEMODE_WRITE)) + { + return false; + } + + TEterPackIndex * pIndex; + pIndex = FindIndex(filename); + + CLZObject zObj; + std::string encryptStr; + + if (packType == COMPRESSED_TYPE_SECURITY || + packType == COMPRESSED_TYPE_COMPRESS) + { + if (packType == COMPRESSED_TYPE_SECURITY) + { + if (!CLZO::Instance().CompressEncryptedMemory(zObj, data, len, s_adwEterPackSecurityKey)) + { + return false; + } + } + else + { + if (!CLZO::Instance().CompressMemory(zObj, data, len)) + { + return false; + } + } + + data = zObj.GetBuffer(); + len = zObj.GetSize(); + } + else if (packType == COMPRESSED_TYPE_PANAMA) + { + if (!__Encrypt_Panama(filename, (const BYTE *) data, len, zObj)) + { + return false; + } + + data = zObj.GetBuffer(); + len = zObj.GetBufferSize(); + } + else if (packType == COMPRESSED_TYPE_HYBRIDCRYPT || packType == COMPRESSED_TYPE_HYBRIDCRYPT_WITHSDB) + { +#ifdef __THEMIDA__ + VM_START +#endif + + auto ssvv = std::string(filename); + if (!m_pCSHybridCryptPolicy->EncryptMemory(ssvv, (const BYTE*)data, len, zObj)) + { + return false; + } + + data = zObj.GetBuffer(); + len = zObj.GetBufferSize(); +#ifdef __THEMIDA__ + VM_END +#endif + + } + + +#ifdef CHECKSUM_CHECK_MD5 + MD5_CTX context; + GenerateMD5Hash( (BYTE*)(data), len, context ); +#else + DWORD data_crc; + data_crc = GetCRC32((const char *) data, len); +#endif + + // Ͱ .. + if (pIndex) + { + // data ũⰡ ũ⸦ ִٸ + if (pIndex->real_data_size >= len) + { + ++m_map_indexRefCount[pIndex->id]; + + // ̰ Ʋų, checksum Ʋ Ѵ. + if ( (pIndex->data_size != len) || +#ifdef CHECKSUM_CHECK_MD5 + (memcmp( pIndex->MD5Digest, context.digest, 16 ) != 0) ) +#else + (pIndex->data_crc != data_crc) ) +#endif + { +#ifdef __MAKE_PACK__ + if (ms_PackLogFile) + fprintf(ms_PackLogFile, "Overwrite[%d/%d] %s\n", bCompress, bSecurity, pIndex->filename); + printf("Overwrite[%d/%d] %s\n", bCompress, bSecurity, pIndex->filename); +#endif + pIndex->data_size = len; +#ifdef CHECKSUM_CHECK_MD5 + memcpy( pIndex->MD5Digest, context.digest, 16 ); + +#else + pIndex->data_crc = data_crc; +#endif + + pIndex->compressed_type = packType; + + CMakePackLog::GetSingleton().Writef("Overwrite[type:%u] %s\n", pIndex->compressed_type, pIndex->filename); + + WriteIndex(fileIndex, pIndex); + WriteData(fileData, pIndex, data); + } + + return true; + } + + // ũⰡ  ٸ, ε Ҵ + // ־ Ѵ. ִ ε д. + PushFreeIndex(pIndex); + WriteIndex(fileIndex, pIndex); + } + + // + pIndex = NewIndex(fileIndex, filename, len); + pIndex->data_size = len; + +#ifdef CHECKSUM_CHECK_MD5 + memcpy( pIndex->MD5Digest, context.digest, 16 ); +#else + pIndex->data_crc = data_crc; +#endif + + + pIndex->data_position = GetNewDataPosition(fileData); + pIndex->compressed_type = packType; + + WriteIndex(fileIndex, pIndex); + WriteNewData(fileData, pIndex, data); + + ++m_map_indexRefCount[pIndex->id]; + +#ifdef __MAKE_PACK__ + if (ms_PackLogFile) + fprintf(ms_PackLogFile, "Write[%d/%d] %s\n", bCompress, bSecurity, pIndex->filename); + printf("Write[%d/%d] %s, position %ld realsize %ld size %ld\n", + bCompress, bSecurity, pIndex->filename, pIndex->data_position, pIndex->real_data_size, pIndex->data_size); +#endif + CMakePackLog::GetSingleton().Writef("Write[type:%u] %s\n", pIndex->compressed_type, pIndex->filename); + + return true; +} + +long CEterPack::GetFragmentSize() +{ + return m_FragmentSize; +} + +// Private methods +bool CEterPack::CreateIndexFile() +{ + FILE * fp; + + if (NULL != (fp = fopen(m_indexFileName, "rb"))) + { + fclose(fp); + return true; + } + else if (m_bReadOnly) + return false; + + // + // Ƿ . + // + fp = fopen(m_indexFileName, "wb"); + + if (!fp) + return false; + + fwrite(&eterpack::c_IndexCC, sizeof(DWORD), 1, fp); + fwrite(&eterpack::c_Version, sizeof(DWORD), 1, fp); + fwrite(&m_indexCount, sizeof(long), 1, fp); + + fclose(fp); + return true; +} + + +void CEterPack::WriteIndex(CFileBase & file, TEterPackIndex * index) +{ + file.Seek(sizeof(DWORD) + sizeof(DWORD)); + file.Write(&m_indexCount, sizeof(long)); + file.Seek(eterpack::c_HeaderSize + (index->id * sizeof(TEterPackIndex))); + + if (!file.Write(index, sizeof(TEterPackIndex))) + { + assert(!"WriteIndex: fwrite failed"); + return; + } +} + +/* + * Free Block ̶ Ϳ κ Ѵ. + * Free Block FREE_INDEX_BLOCK_SIZE (32768) + * Ʈ ȴ. + * + * 128k ʹ + * 128 * 1024 / FREE_INDEX_BLOCK_SIZE = 4 ̹Ƿ + * δ m_FreeIndexList[4] . + * + * FREE_INDEX_BLOCK_SIZE ִ FREE_INDEX_MAX_SIZE(512) ̴. + * 16MB ̻ ʹ 迭 512 ġ . + */ +int CEterPack::GetFreeBlockIndex(long size) +{ + return min(FREE_INDEX_MAX_SIZE, size / FREE_INDEX_BLOCK_SIZE); +} + +void CEterPack::PushFreeIndex(TEterPackIndex* index) +{ + if (index->filename_crc != 0) + { + TDataPositionMap::iterator i = m_DataPositionMap.find(index->filename_crc); + + if (i != m_DataPositionMap.end()) + m_DataPositionMap.erase(i); + + index->filename_crc = 0; + memset(index->filename, 0, sizeof(index->filename)); + } + + int blockidx = GetFreeBlockIndex(index->real_data_size); + m_FreeIndexList[blockidx].push_back(index); + m_FragmentSize += index->real_data_size; + //printf("FreeIndex: size %d: blockidx: %d\n", index->real_data_size, blockidx); +} + +long CEterPack::GetNewIndexPosition(CFileBase & file) +{ + long pos = (file.Size() - eterpack::c_HeaderSize) / sizeof(TEterPackIndex); + ++m_indexCount; + return (pos); +} + +TEterPackIndex* CEterPack::NewIndex(CFileBase& file, const char* filename, long size) +{ + TEterPackIndex* index = NULL; + int block_size = size + (DATA_BLOCK_SIZE - (size % DATA_BLOCK_SIZE)); +// if ((index = FindIndex(filename))) // ̹ ε ϴ Ȯ +// return index; + + int blockidx = GetFreeBlockIndex(block_size); + + for (TFreeIndexList::iterator i = m_FreeIndexList[blockidx].begin(); + i != m_FreeIndexList[blockidx].end(); + ++i) + { + if ((*i)->real_data_size >= size) + { + index = *i; + m_FreeIndexList[blockidx].erase(i); + + assert(index->filename_crc == 0); + break; + } + } + + if (!index) + { + index = new TEterPackIndex; + index->real_data_size = block_size; + index->id = GetNewIndexPosition(file); + } + + strncpy(index->filename, filename, FILENAME_MAX_LEN); + index->filename[FILENAME_MAX_LEN] = '\0'; + inlineConvertPackFilename(index->filename); + + index->filename_crc = GetCRC32(index->filename, strlen(index->filename)); + + m_DataPositionMap.insert(TDataPositionMap::value_type(index->filename_crc, index)); + return index; +} + +TEterPackIndex* CEterPack::FindIndex(const char * filename) +{ + static char tmpFilename[MAX_PATH + 1]; + strncpy(tmpFilename, filename, MAX_PATH); + inlineConvertPackFilename(tmpFilename); + + DWORD filename_crc = GetCRC32(tmpFilename, strlen(tmpFilename)); + TDataPositionMap::iterator i = m_DataPositionMap.find(filename_crc); + + if (i == m_DataPositionMap.end()) + return NULL; + + return (i->second); +} + +bool CEterPack::IsExist(const char * filename) +{ + return FindIndex(filename) ? true : false; +} + +bool CEterPack::CreateDataFile() +{ + FILE * fp; + + if (NULL != (fp = fopen(m_stDataFileName.c_str(), "rb"))) + { + fclose(fp); + return true; + } + else if (m_bReadOnly) + return false; + + fp = fopen(m_stDataFileName.c_str(), "wb"); + + if (!fp) + return false; + + fclose(fp); + return true; +} + +long CEterPack::GetNewDataPosition(CFileBase& file) +{ + return file.Size(); +} + +bool CEterPack::ReadData(CFileBase & file, TEterPackIndex* index, LPVOID data, long maxsize) +{ + if (index->data_size > maxsize) + return false; + + file.Seek(index->data_position); + file.Read(data, index->data_size); + return true; +} + +bool CEterPack::WriteData(CFileBase & file, TEterPackIndex* index, LPCVOID data) +{ + file.Seek(index->data_position); + + if (!file.Write(data, index->data_size)) + { + assert(!"WriteData: fwrite data failed"); + return false; + } + + return true; +} + +bool CEterPack::WriteNewData(CFileBase& file, TEterPackIndex* index, LPCVOID data) +{ + file.Seek(index->data_position); + + if (!file.Write(data, index->data_size)) + { + assert(!"WriteData: fwrite data failed"); + return false; + } + + int empty_size = index->real_data_size - index->data_size; + + if (empty_size < 0) + { + printf("SYSERR: WriteNewData(): CRITICAL ERROR: empty_size lower than 0!\n"); + exit(1); + } + + if (empty_size == 0) + return true; + + char * empty_buf = (char *) calloc(empty_size, sizeof(char)); + + if (!file.Write(empty_buf, empty_size)) + { + assert(!"WriteData: fwrite empty data failed"); + return false; + } + + free(empty_buf); + return true; +} + +TDataPositionMap & CEterPack::GetIndexMap() +{ + return m_DataPositionMap; +} + +DWORD CEterPack::DeleteUnreferencedData() +{ + TDataPositionMap::iterator i = m_DataPositionMap.begin(); + DWORD dwCount = 0; + + while (i != m_DataPositionMap.end()) + { + TEterPackIndex * pIndex = (i++)->second; + + if (0 == m_map_indexRefCount[pIndex->id]) + { + printf("Unref File %s\n", pIndex->filename); + Delete(pIndex); + ++dwCount; + } + } + + return dwCount; +} + +const char * CEterPack::GetDBName() +{ + return m_dbName; +} + +void CEterPack::__CreateFileNameKey_Panama(const char * filename, BYTE * key, unsigned int keySize) +{ + // Ű ȣȭ + if (keySize != 32) + return; + + std::string SrcStringForKey(filename); + unsigned int idx = GetCRC32(SrcStringForKey.c_str(), SrcStringForKey.length()) & 3; + + CryptoPP::HashTransformation* hm1 = NULL; + CryptoPP::HashTransformation* hm2 = NULL; + + static CryptoPP::Tiger tiger; + static CryptoPP::SHA1 sha1; + static CryptoPP::RIPEMD128 ripemd128; + static CryptoPP::Whirlpool whirlpool; + + switch (idx & 3) + { + case 0: + hm1 = &whirlpool; + break; + + case 1: + hm1 = &tiger; + break; + + case 2: + hm1 = &sha1; + break; + + case 3: + hm1 = &ripemd128; + break; + } + + CryptoPP::StringSource(SrcStringForKey, true, + new CryptoPP::HashFilter(*hm1, + //new CryptoPP::HexEncoder( + new CryptoPP::ArraySink(key, 16) + //) // HexEncoder + ) // HashFilter + ); // StringSource + + // Ű ù° 4Ʈ 16Ʈ Ű ˰ + unsigned int idx2 = *(unsigned int*) key; + + switch (idx2 & 3) + { + case 0: + hm2 = &sha1; + break; + + case 1: + hm2 = &ripemd128; + break; + + case 2: + hm2 = &whirlpool; + break; + + case 3: + hm2 = &tiger; + break; + } + + CryptoPP::StringSource(SrcStringForKey, true, + new CryptoPP::HashFilter(*hm2, + //new CryptoPP::HexEncoder( + new CryptoPP::ArraySink(key + 16, 16) + //) // HexEncoder + ) // HashFilter + ); // StringSource + // Ű Ϸ +} + +bool CEterPack::__Encrypt_Panama(const char* filename, const BYTE* data, SIZE_T dataSize, CLZObject& zObj) +{ + if (32 != m_stIV_Panama.length()) + { + // Ŀ ޼ Ʈ ׿ +#ifdef _DEBUG + TraceError("IV not set (filename: %s)", filename); +#endif + return false; + } + + CryptoPP::PanamaCipher::Encryption Encryptor; + + if (dataSize < Encryptor.MandatoryBlockSize()) + { +#ifdef _DEBUG + TraceError("Type 3 pack file must be bigger than %u bytes (filename: %s)", Encryptor.MandatoryBlockSize(), filename); +#endif + return false; + } + + BYTE key[32]; + + __CreateFileNameKey_Panama(filename, key, sizeof(key)); + Encryptor.SetKeyWithIV(key, sizeof(key), (const BYTE*) m_stIV_Panama.c_str(), 32); + + // MandatoryBlockSize ִ 2048 Ʈ + DWORD cryptSize = dataSize - (dataSize % Encryptor.MandatoryBlockSize()); + cryptSize = cryptSize > 2048 ? 2048 : cryptSize; + + std::string tmp; + + tmp.reserve(cryptSize); + + CryptoPP::ArraySource(data, cryptSize, true, + new CryptoPP::StreamTransformationFilter(Encryptor, + new CryptoPP::StringSink(tmp) + ) + ); + + if (tmp.length() != cryptSize) + { +#ifdef _DEBUG + TraceError("Type 3 pack crypt buffer size error (out %u should be %u)", tmp.length(), cryptSize); +#endif + return false; + } + + zObj.AllocBuffer(dataSize); + memcpy(zObj.GetBuffer(), tmp.c_str(), cryptSize); + + if (dataSize - cryptSize > 0) + memcpy(zObj.GetBuffer() + cryptSize, data + cryptSize, dataSize - cryptSize); + + return true; +} + +bool CEterPack::__Decrypt_Panama(const char* filename, const BYTE* data, SIZE_T dataSize, CLZObject& zObj) +{ + if (32 != m_stIV_Panama.length()) + { + // Ŀ ޼ Ʈ ׿ +#ifdef _DEBUG + TraceError("IV not set (filename: %s)", filename); +#endif + return false; + } + + CryptoPP::PanamaCipher::Decryption Decryptor; + + BYTE key[32]; + + __CreateFileNameKey_Panama(filename, key, sizeof(key)); + Decryptor.SetKeyWithIV(key, sizeof(key), (const BYTE*) m_stIV_Panama.c_str(), 32); + + // MandatoryBlockSize ִ 2048 Ʈ + DWORD cryptSize = dataSize - (dataSize % Decryptor.MandatoryBlockSize()); + cryptSize = cryptSize > 2048 ? 2048 : cryptSize; + + std::string tmp; + + tmp.reserve(cryptSize); + + CryptoPP::ArraySource(data, cryptSize, true, + new CryptoPP::StreamTransformationFilter(Decryptor, + new CryptoPP::StringSink(tmp) + ) + ); + + if (tmp.length() != cryptSize) + { +#ifdef _DEBUG + TraceError("Type 3 pack crypt buffer size error (out %u should be %u)", tmp.length(), cryptSize); +#endif + return false; + } + + zObj.AllocBuffer(dataSize); + memcpy(zObj.GetBuffer(), tmp.c_str(), cryptSize); + + if (dataSize - cryptSize > 0) + memcpy(zObj.GetBuffer() + cryptSize, data + cryptSize, dataSize - cryptSize); + + return true; +} + +EterPackPolicy_CSHybridCrypt* CEterPack::GetPackPolicy_HybridCrypt() const +{ + return m_pCSHybridCryptPolicy; +} + + +///////////////////////// + +void CEterFileDict::InsertItem(CEterPack* pkPack, TEterPackIndex* pkInfo) +{ + Item item; + + item.pkPack = pkPack; + item.pkInfo = pkInfo; + + m_dict.insert(TDict::value_type(pkInfo->filename_crc, item)); +} + +void CEterFileDict::UpdateItem(CEterPack* pkPack, TEterPackIndex* pkInfo) +{ + Item item; + + item.pkPack = pkPack; + item.pkInfo = pkInfo; + + TDict::iterator f = m_dict.find(pkInfo->filename_crc); + if (f == m_dict.end()) + m_dict.insert(TDict::value_type(pkInfo->filename_crc, item)); + else + { + if (strcmp(f->second.pkInfo->filename, item.pkInfo->filename) == 0) + { + f->second = item; + } + else + { + TraceError("NAME_COLLISION: OLD: %s NEW: %s", f->second.pkInfo->filename, item.pkInfo->filename); + } + + } +} + +CEterFileDict::Item* CEterFileDict::GetItem(DWORD dwFileNameHash, const char * c_pszFileName) +{ + std::pair iter_pair = m_dict.equal_range(dwFileNameHash); + + TDict::iterator iter = iter_pair.first; + + while (iter != iter_pair.second) + { + Item& item = iter->second; + + if (0 == strcmp(c_pszFileName, item.pkInfo->filename)) + return &item; + + ++iter; + } + + return NULL; +} diff --git a/source/EterPack/EterPack.h b/source/EterPack/EterPack.h new file mode 100644 index 0000000..6664f03 --- /dev/null +++ b/source/EterPack/EterPack.h @@ -0,0 +1,248 @@ +#ifndef __INC_ETERPACKLIB_ETERPACK_H__ +#define __INC_ETERPACKLIB_ETERPACK_H__ + +#include +#include + +#include "../EterBase/MappedFile.h" + +#ifndef MAKEFOURCC +#define MAKEFOURCC(ch0, ch1, ch2, ch3) \ + ((DWORD)(BYTE) (ch0 ) | ((DWORD)(BYTE) (ch1) << 8) | \ + ((DWORD)(BYTE) (ch2) << 16) | ((DWORD)(BYTE) (ch3) << 24)) +#endif + + +//#define CHECKSUM_CHECK_MD5 + +#include "md5.h" + +namespace eterpack +{ + const DWORD c_PackCC = MAKEFOURCC('E', 'P', 'K', 'D'); + const DWORD c_IndexCC = MAKEFOURCC('E', 'P', 'K', 'D'); + const DWORD c_Version = 2; + // FourCC + Version + m_indexCount + const DWORD c_HeaderSize = sizeof(DWORD) + sizeof(DWORD) + sizeof(long); +}; + +enum EEterPackTypes +{ + DBNAME_MAX_LEN = 255, + FILENAME_MAX_LEN = 160, + FREE_INDEX_BLOCK_SIZE = 32768, + FREE_INDEX_MAX_SIZE = 512, + DATA_BLOCK_SIZE = 256, + + COMPRESSED_TYPE_NONE = 0, + COMPRESSED_TYPE_COMPRESS = 1, + COMPRESSED_TYPE_SECURITY = 2, + COMPRESSED_TYPE_PANAMA = 3, + COMPRESSED_TYPE_HYBRIDCRYPT = 4, + COMPRESSED_TYPE_HYBRIDCRYPT_WITHSDB = 5, + COMPRESSED_TYPE_COUNT = 6, +}; + +#pragma pack(push, 4) +typedef struct SEterPackIndex +{ + long id; + char filename[FILENAME_MAX_LEN + 1]; + DWORD filename_crc; + long real_data_size; + long data_size; +#ifdef CHECKSUM_CHECK_MD5 + BYTE MD5Digest[16]; +#else + DWORD data_crc; +#endif + long data_position; + char compressed_type; +} TEterPackIndex; +#pragma pack(pop) + +typedef std::unordered_map TDataPositionMap; +typedef std::list TFreeIndexList; + + +class CEterPack; + +class CEterFileDict +{ +public: + struct Item + { + Item() : pkPack(NULL), pkInfo(NULL) {} + + CEterPack* pkPack; + TEterPackIndex* pkInfo; + }; + + enum + { + BUCKET_SIZE = 16, + }; + + typedef std::unordered_multimap TDict; + +public: + void InsertItem(CEterPack* pkPack, TEterPackIndex* pkInfo); + void UpdateItem(CEterPack* pkPack, TEterPackIndex* pkInfo); + + Item* GetItem(DWORD dwFileNameHash, const char* c_pszFileName); + + const TDict& GetDict() const + { + return m_dict; + } + +private: + TDict m_dict; +}; + +class EterPackPolicy_CSHybridCrypt; + +class CEterPack +{ + public: + CEterPack(); + virtual ~CEterPack(); + + void Destroy(); + bool Create(CEterFileDict& rkFileDict, const char * dbname, const char * pathName, bool bReadOnly = true, const BYTE* iv = NULL); + bool DecryptIV(DWORD dwPanamaKey); + + const std::string& GetPathName(); + const char * GetDBName(); + + //THEMIDA + bool Get(CMappedFile & mappedFile, const char * filename, LPCVOID * data); + //THEMIDA + bool Get2(CMappedFile & mappedFile, const char * filename, TEterPackIndex* index, LPCVOID * data); + + + //THEMIDA + bool Put(const char * filename, const char * sourceFilename, BYTE packType, const std::string& strRelateMapName); + //THEMIDA + bool Put(const char * filename, LPCVOID data, long len, BYTE packType); + + bool Delete(const char * filename); + + bool Extract(); + + long GetFragmentSize(); + + bool IsExist(const char * filename); + + TDataPositionMap & GetIndexMap(); + + bool EncryptIndexFile(); + bool DecryptIndexFile(); + + DWORD DeleteUnreferencedData(); //  Ǿ Ѵ. + + bool GetNames(std::vector* retNames); + + EterPackPolicy_CSHybridCrypt* GetPackPolicy_HybridCrypt() const; + + private: + bool __BuildIndex(CEterFileDict& rkFileDict, bool bOverwirte=false); + + bool CreateIndexFile(); + TEterPackIndex * FindIndex(const char * filename); + long GetNewIndexPosition(CFileBase& file); + TEterPackIndex * NewIndex(CFileBase& file, const char * filename, long size); + void WriteIndex(CFileBase& file, TEterPackIndex * index); + int GetFreeBlockIndex(long size); + void PushFreeIndex(TEterPackIndex * index); + + bool CreateDataFile(); + long GetNewDataPosition(CFileBase& file); + bool ReadData(CFileBase& file, TEterPackIndex * index, LPVOID data, long maxsize); + bool WriteData(CFileBase& file, TEterPackIndex * index, LPCVOID data); + bool WriteNewData(CFileBase& file, TEterPackIndex * index, LPCVOID data); + + bool Delete(TEterPackIndex * pIndex); + + protected: + CMappedFile m_file; + + char* m_file_data; + unsigned m_file_size; + + long m_indexCount; + bool m_bEncrypted; + + char m_dbName[DBNAME_MAX_LEN+1]; + char m_indexFileName[MAX_PATH+1]; + TEterPackIndex * m_indexData; + long m_FragmentSize; + bool m_bReadOnly; + bool m_bDecrypedIV; + + std::unordered_map m_map_indexRefCount; + TDataPositionMap m_DataPositionMap; + TFreeIndexList m_FreeIndexList[FREE_INDEX_MAX_SIZE + 1]; // MAX \ ϹǷ + 1 ũ⸸ŭ . + + std::string m_stDataFileName; + std::string m_stPathName; + + + EterPackPolicy_CSHybridCrypt* m_pCSHybridCryptPolicy; + + private: + void __CreateFileNameKey_Panama(const char * filename, BYTE * key, unsigned int keySize); + bool __Decrypt_Panama(const char* filename, const BYTE* data, SIZE_T dataSize, CLZObject& zObj); + bool __Encrypt_Panama(const char* filename, const BYTE* data, SIZE_T dataSize, CLZObject& zObj); + std::string m_stIV_Panama; + + //private: + // bool m_bIsDataLoaded; + // // ׳ time_t , 32bit time_t ϴ ҽ, + // // CEterPack size size - 4 νϱ ߻ ִ. + // __time64_t m_tLastAccessTime; + //public: + // __time64_t GetLastAccessTime() { return m_tLastAccessTime; } + // void UpdateLastAccessTime(); + // void ClearDataMemoryMap(); + +#ifdef CHECKSUM_CHECK_MD5 + void GenerateMD5Hash( BYTE* pData, int nLength, IN OUT MD5_CTX& context ); +#endif +}; + +class CMakePackLog +{ + public: + static CMakePackLog& GetSingleton(); + + public: + CMakePackLog(); + ~CMakePackLog(); + + void SetFileName(const char* c_szFileName); + + void Writef(const char* c_szFormat, ...); + void Writenf(const char* c_szFormat, ...); + void Write(const char* c_szBuf); + + void WriteErrorf(const char* c_szFormat, ...); + void WriteErrornf(const char* c_szFormat, ...); + void WriteError(const char* c_szBuf); + + void FlushError(); + + private: + void __Write(const char* c_szBuf, int nBufLen); + void __WriteError(const char* c_szBuf, int nBufLen); + bool __IsLogMode(); + + private: + FILE* m_fp; + FILE* m_fp_err; + + std::string m_stFileName; + std::string m_stErrorFileName; +}; + +#endif diff --git a/source/EterPack/EterPackCursor.cpp b/source/EterPack/EterPackCursor.cpp new file mode 100644 index 0000000..288a90c --- /dev/null +++ b/source/EterPack/EterPackCursor.cpp @@ -0,0 +1,59 @@ +#include "StdAfx.h" +#include "EterPackCursor.h" +#include "Inline.h" + +CEterPackCursor::CEterPackCursor(CEterPack* pack) : m_pPack(pack), m_pData(NULL), m_ReadPoint(0) +{ +} + +CEterPackCursor::~CEterPackCursor() +{ + Close(); +} + +bool CEterPackCursor::Open(const char* filename) +{ + assert(m_pPack != NULL); + + char tmpFilename[MAX_PATH + 1]; + strncpy(tmpFilename, filename, MAX_PATH); + inlineConvertPackFilename(tmpFilename); + + if (!m_pPack->Get(m_file, tmpFilename, &m_pData)) + return false; + + return true; +} + +void CEterPackCursor::Close() +{ + m_file.Destroy(); + m_pData = NULL; + m_ReadPoint = 0; +} + +void CEterPackCursor::Seek(long offset) +{ + m_ReadPoint = max(0, min(Size(), offset)); +} + +bool CEterPackCursor::Read(LPVOID data, long size) +{ + if (m_file.IsNull()) + return false; + + if (m_ReadPoint + size > Size()) + return false; + + memcpy(data, (char*) m_pData + m_ReadPoint, size); + m_ReadPoint += size; + return true; +} + +long CEterPackCursor::Size() +{ + if (m_file.IsNull()) + return 0; + + return m_file.Size(); +} diff --git a/source/EterPack/EterPackCursor.h b/source/EterPack/EterPackCursor.h new file mode 100644 index 0000000..5ba802a --- /dev/null +++ b/source/EterPack/EterPackCursor.h @@ -0,0 +1,25 @@ +#ifndef __INC_ETERPACKCURSOR_H__ +#define __INC_ETERPACKCURSOR_H__ + +#include "EterPack.h" + +class CEterPackCursor +{ + public: + CEterPackCursor(CEterPack * pack); + ~CEterPackCursor(); + + bool Open(const char* filename); + void Close(); + void Seek(long offset); + bool Read(LPVOID data, long size); + long Size(); + + private: + CEterPack * m_pPack; + CMappedFile m_file; + LPCVOID m_pData; + long m_ReadPoint; +}; + +#endif diff --git a/source/EterPack/EterPackManager.cpp b/source/EterPack/EterPackManager.cpp new file mode 100644 index 0000000..48fdc4f --- /dev/null +++ b/source/EterPack/EterPackManager.cpp @@ -0,0 +1,621 @@ +#include "StdAfx.h" + +#include +#include + +#include "EterPackManager.h" +#include "EterPackPolicy_CSHybridCrypt.h" + +#include "../eterBase/Debug.h" +#include "../eterBase/CRC32.h" + +#define PATH_ABSOLUTE_YMIRWORK1 "d:/ymir work/" +#define PATH_ABSOLUTE_YMIRWORK2 "d:\\ymir work\\" + +#ifdef __THEMIDA__ +#include +#endif + + +CEterPack* CEterPackManager::FindPack(const char* c_szPathName) +{ + std::string strFileName; + + if (0 == ConvertFileName(c_szPathName, strFileName)) + { + return &m_RootPack; + } + else + { + for (TEterPackMap::iterator itor = m_DirPackMap.begin(); itor != m_DirPackMap.end(); ++itor) + { + const std::string & c_rstrName = itor->first; + CEterPack * pEterPack = itor->second; + + if (CompareName(c_rstrName.c_str(), c_rstrName.length(), strFileName.c_str())) + { + return pEterPack; + } + } + } + + return NULL; +} + +void CEterPackManager::SetCacheMode() +{ + m_isCacheMode=true; +} + +void CEterPackManager::SetRelativePathMode() +{ + m_bTryRelativePath = true; +} + + +// StringPath std::string +int CEterPackManager::ConvertFileName(const char * c_szFileName, std::string & rstrFileName) +{ + rstrFileName = c_szFileName; + stl_lowers(rstrFileName); + + int iCount = 0; + + for (DWORD i = 0; i < rstrFileName.length(); ++i) + { + if (rstrFileName[i] == '/') + ++iCount; + else if (rstrFileName[i] == '\\') + { + rstrFileName[i] = '/'; + ++iCount; + } + } + + return iCount; +} + +bool CEterPackManager::CompareName(const char * c_szDirectoryName, DWORD /*dwLength*/, const char * c_szFileName) +{ + const char * c_pszSrc = c_szDirectoryName; + const char * c_pszCmp = c_szFileName; + + while (*c_pszSrc) + { + if (*(c_pszSrc++) != *(c_pszCmp++)) + return false; + + if (!*c_pszCmp) + return false; + } + + return true; +} + +void CEterPackManager::LoadStaticCache(const char* c_szFileName) +{ + if (!m_isCacheMode) + return; + + std::string strFileName; + if (0 == ConvertFileName(c_szFileName, strFileName)) + { + return; + } + + DWORD dwFileNameHash = GetCRC32(strFileName.c_str(), strFileName.length()); + + std::unordered_map::iterator f = m_kMap_dwNameKey_kCache.find(dwFileNameHash); + if (m_kMap_dwNameKey_kCache.end() != f) + return; + + CMappedFile kMapFile; + const void* c_pvData; + if (!Get(kMapFile, c_szFileName, &c_pvData)) + return; + + SCache kNewCache; + kNewCache.m_dwBufSize = kMapFile.Size(); + kNewCache.m_abBufData = new BYTE[kNewCache.m_dwBufSize]; + memcpy(kNewCache.m_abBufData, c_pvData, kNewCache.m_dwBufSize); + m_kMap_dwNameKey_kCache.insert(std::unordered_map::value_type(dwFileNameHash, kNewCache)); +} + +CEterPackManager::SCache* CEterPackManager::__FindCache(DWORD dwFileNameHash) +{ + std::unordered_map::iterator f=m_kMap_dwNameKey_kCache.find(dwFileNameHash); + if (m_kMap_dwNameKey_kCache.end()==f) + return NULL; + + return &f->second; +} + +void CEterPackManager::__ClearCacheMap() +{ + std::unordered_map::iterator i; + + for (i = m_kMap_dwNameKey_kCache.begin(); i != m_kMap_dwNameKey_kCache.end(); ++i) + delete [] i->second.m_abBufData; + + m_kMap_dwNameKey_kCache.clear(); +} + +struct TimeChecker +{ + TimeChecker(const char* name) : name(name) + { + baseTime = timeGetTime(); + } + ~TimeChecker() + { + printf("load %s (%d)\n", name, timeGetTime() - baseTime); + } + + const char* name; + DWORD baseTime; +}; + +bool CEterPackManager::Get(CMappedFile & rMappedFile, const char * c_szFileName, LPCVOID * pData) +{ + //TimeChecker timeChecker(c_szFileName); + //Logf(1, "Load %s\n", c_szFileName); + + if (m_iSearchMode == SEARCH_FILE_FIRST) + { + if (GetFromFile(rMappedFile, c_szFileName, pData)) + { + return true; + } + + return GetFromPack(rMappedFile, c_szFileName, pData); + } + + if (GetFromPack(rMappedFile, c_szFileName, pData)) + { + return true; + } + + return GetFromFile(rMappedFile, c_szFileName, pData); +} + +struct FinderLock +{ + FinderLock(CRITICAL_SECTION& cs) : p_cs(&cs) + { + EnterCriticalSection(p_cs); + } + + ~FinderLock() + { + LeaveCriticalSection(p_cs); + } + + CRITICAL_SECTION* p_cs; +}; + +bool CEterPackManager::GetFromPack(CMappedFile & rMappedFile, const char * c_szFileName, LPCVOID * pData) +{ + FinderLock lock(m_csFinder); + + static std::string strFileName; + + if (0 == ConvertFileName(c_szFileName, strFileName)) + { + return m_RootPack.Get(rMappedFile, strFileName.c_str(), pData); + } + else + { + DWORD dwFileNameHash = GetCRC32(strFileName.c_str(), strFileName.length()); + SCache* pkCache = __FindCache(dwFileNameHash); + + if (pkCache) + { + rMappedFile.Link(pkCache->m_dwBufSize, pkCache->m_abBufData); + return true; + } + + CEterFileDict::Item* pkFileItem = m_FileDict.GetItem(dwFileNameHash, strFileName.c_str()); + + if (pkFileItem) + if (pkFileItem->pkPack) + { + bool r = pkFileItem->pkPack->Get2(rMappedFile, strFileName.c_str(), pkFileItem->pkInfo, pData); + //pkFileItem->pkPack->ClearDataMemoryMap(); + return r; + } + } +#ifdef _DEBUG + TraceError("CANNOT_FIND_PACK_FILE [%s]", strFileName.c_str()); +#endif + + return false; +} + +const time_t g_tCachingInterval = 10; // 10 +void CEterPackManager::ArrangeMemoryMappedPack() +{ + //time_t curTime = time(NULL); + //CEterFileDict::TDict dict = m_FileDict.GetDict(); + //for (CEterFileDict::TDict::iterator it = dict.begin(); it != dict.end(); ++it) + //{ + // CEterFileDict::Item &rFileItem = it->second; + // CEterPack* pkPack = rFileItem.pkPack; + // if (pkPack) + // { + // if (curTime - pkPack->GetLastAccessTime() > g_tCachingInterval) + // { + // pkPack->ClearDataMemoryMap(); + // } + // } + //} +} + +bool CEterPackManager::GetFromFile(CMappedFile & rMappedFile, const char * c_szFileName, LPCVOID * pData) +{ +#ifndef _DEBUG + //const char *pcExt = strchr(c_szFileName, '.'); + //if (pcExt && + // _strnicmp(pcExt, ".py", 3) == 0 && // python ũƮ + // stricmp(c_szFileName, "logininfo.py") != 0 && // α ƴϰ + // strnicmp(c_szFileName, "locale", 6) != 0 + // ) + //{ + // return false; + //} +#endif + + //if(m_bTryRelativePath) { + // if (strnicmp(c_szFileName, PATH_ABSOLUTE_YMIRWORK1, strlen(PATH_ABSOLUTE_YMIRWORK1)) == 0 || strnicmp(c_szFileName, PATH_ABSOLUTE_YMIRWORK2, strlen(PATH_ABSOLUTE_YMIRWORK2)) == 0) { + // if(rMappedFile.Create(c_szFileName+strlen(PATH_ABSOLUTE_YMIRWORK1), pData, 0, 0)) + // { + // return true; + // } + // } + //} + + return rMappedFile.Create(c_szFileName, pData, 0, 0) ? true : false; +} + +bool CEterPackManager::isExistInPack(const char * c_szFileName) +{ + std::string strFileName; + + if (0 == ConvertFileName(c_szFileName, strFileName)) + { + return m_RootPack.IsExist(strFileName.c_str()); + } + else + { + DWORD dwFileNameHash = GetCRC32(strFileName.c_str(), strFileName.length()); + CEterFileDict::Item* pkFileItem = m_FileDict.GetItem(dwFileNameHash, strFileName.c_str()); + + if (pkFileItem) + if (pkFileItem->pkPack) + return pkFileItem->pkPack->IsExist(strFileName.c_str()); + } + + // NOTE : ġ Ǵ ٸ false - [levites] + return false; +} + +bool CEterPackManager::isExist(const char * c_szFileName) +{ + if (m_iSearchMode == SEARCH_PACK_FIRST) + { + if (isExistInPack(c_szFileName)) + return true; + + return _access(c_szFileName, 0) == 0 ? true : false; + } + + //if(m_bTryRelativePath) { + // if (strnicmp(c_szFileName, PATH_ABSOLUTE_YMIRWORK1, strlen(PATH_ABSOLUTE_YMIRWORK1)) == 0 || strnicmp(c_szFileName, PATH_ABSOLUTE_YMIRWORK2, strlen(PATH_ABSOLUTE_YMIRWORK2)) == 0) { + // if(access(c_szFileName+strlen(PATH_ABSOLUTE_YMIRWORK1), 0) == 0) + // return true; + // } + //} + + if (_access(c_szFileName, 0) == 0) + return true; + + return isExistInPack(c_szFileName); +} + + +void CEterPackManager::RegisterRootPack(const char * c_szName) +{ + if (!m_RootPack.Create(m_FileDict, c_szName, "")) + { + TraceError("%s: Pack file does not exist", c_szName); + } +} + +const char * CEterPackManager::GetRootPackFileName() +{ + return m_RootPack.GetDBName(); +} + +bool CEterPackManager::DecryptPackIV(DWORD dwPanamaKey) +{ + TEterPackMap::iterator itor = m_PackMap.begin(); + while (itor != m_PackMap.end()) + { + itor->second->DecryptIV(dwPanamaKey); + itor++; + } + return true; +} + +bool CEterPackManager::RegisterPackWhenPackMaking(const char * c_szName, const char * c_szDirectory, CEterPack* pPack) +{ + m_PackMap.insert(TEterPackMap::value_type(c_szName, pPack)); + m_PackList.push_front(pPack); + + m_DirPackMap.insert(TEterPackMap::value_type(c_szDirectory, pPack)); + return true; +} + + +bool CEterPackManager::RegisterPack(const char * c_szName, const char * c_szDirectory, const BYTE* c_pbIV) +{ + CEterPack * pEterPack = NULL; + { + TEterPackMap::iterator itor = m_PackMap.find(c_szName); + + if (m_PackMap.end() == itor) + { + bool bReadOnly = true; + + pEterPack = new CEterPack; + if (pEterPack->Create(m_FileDict, c_szName, c_szDirectory, bReadOnly, c_pbIV)) + { + m_PackMap.insert(TEterPackMap::value_type(c_szName, pEterPack)); + } + else + { +#ifdef _DEBUG + Tracef("The eterpack doesn't exist [%s]\n", c_szName); +#endif + delete pEterPack; + pEterPack = NULL; + return false; + } + } + else + { + pEterPack = itor->second; + } + } + + if (c_szDirectory && c_szDirectory[0] != '*') + { + TEterPackMap::iterator itor = m_DirPackMap.find(c_szDirectory); + if (m_DirPackMap.end() == itor) + { + m_PackList.push_front(pEterPack); + m_DirPackMap.insert(TEterPackMap::value_type(c_szDirectory, pEterPack)); + } + } + + return true; +} + +void CEterPackManager::SetSearchMode(bool bPackFirst) +{ + m_iSearchMode = bPackFirst ? SEARCH_PACK_FIRST : SEARCH_FILE_FIRST; +} + +int CEterPackManager::GetSearchMode() +{ + return m_iSearchMode; +} + +CEterPackManager::CEterPackManager() : m_bTryRelativePath(false), m_iSearchMode(SEARCH_FILE_FIRST), m_isCacheMode(false) +{ + InitializeCriticalSection(&m_csFinder); +} + +CEterPackManager::~CEterPackManager() +{ + __ClearCacheMap(); + + TEterPackMap::iterator i = m_PackMap.begin(); + TEterPackMap::iterator e = m_PackMap.end(); + while (i != e) + { + delete i->second; + i++; + } + DeleteCriticalSection(&m_csFinder); +} + +void CEterPackManager::RetrieveHybridCryptPackKeys(const BYTE *pStream) +{ + ////dump file format + //total packagecnt (4byte) + // for packagecntpackage + // db name hash ( stl.h stringhash ) + // extension cnt( 4byte) + // for extension cnt + // ext hash ( stl.h stringhash ) + // key-16byte + // iv-16byte + int iMemOffset = 0; + + int iPackageCnt; + DWORD dwPackageNameHash; + + memcpy( &iPackageCnt, pStream + iMemOffset, sizeof(int) ); + iMemOffset += sizeof(iPackageCnt); + + for( int i = 0; i < iPackageCnt; ++i ) + { + int iRecvedCryptKeySize = 0; + memcpy( &iRecvedCryptKeySize, pStream + iMemOffset, sizeof(iRecvedCryptKeySize) ); + iRecvedCryptKeySize -= sizeof(dwPackageNameHash); // key stream filename hash ԵǾ Ƿ, hash ŭ . + iMemOffset += sizeof(iRecvedCryptKeySize); + + memcpy( &dwPackageNameHash, pStream + iMemOffset, sizeof(dwPackageNameHash) ); + iMemOffset += sizeof(dwPackageNameHash); + + TEterPackMap::const_iterator cit; + for( cit = m_PackMap.begin(); cit != m_PackMap.end(); ++cit ) + { + auto ssvv = std::string(cit->first); + std::string noPathName = CFileNameHelper::NoPath(ssvv); + if( dwPackageNameHash == stringhash().GetHash(noPathName) ) + { + EterPackPolicy_CSHybridCrypt* pCryptPolicy = cit->second->GetPackPolicy_HybridCrypt(); + int iHavedCryptKeySize = pCryptPolicy->ReadCryptKeyInfoFromStream( pStream + iMemOffset ); + if (iRecvedCryptKeySize != iHavedCryptKeySize) + { + TraceError("CEterPackManager::RetrieveHybridCryptPackKeys cryptokey length of file(%s) is not matched. received(%d) != haved(%d)", noPathName.c_str(), iRecvedCryptKeySize, iHavedCryptKeySize); + } + break; + } + } + iMemOffset += iRecvedCryptKeySize; + } +} + +void CEterPackManager::RetrieveHybridCryptPackSDB( const BYTE* pStream ) +{ + //cnt + //for cnt + //DWORD dwPackageIdentifier; + //DWORD dwFileIdentifier; + //std::vector vecSDBStream; + int iReadOffset = 0; + int iSDBInfoCount = 0; + + memcpy( &iSDBInfoCount, pStream+iReadOffset, sizeof(int) ); + iReadOffset += sizeof(int); + + for( int i = 0; i < iSDBInfoCount; ++i ) + { + DWORD dwPackgeIdentifier; + memcpy( &dwPackgeIdentifier, pStream+iReadOffset, sizeof(DWORD) ); + iReadOffset += sizeof(DWORD); + + TEterPackMap::const_iterator cit; + for( cit = m_PackMap.begin(); cit != m_PackMap.end(); ++cit ) + { + auto ssvv = std::string(cit->first); + std::string noPathName = CFileNameHelper::NoPath(ssvv); + if( dwPackgeIdentifier == stringhash().GetHash(noPathName) ) + { + EterPackPolicy_CSHybridCrypt* pCryptPolicy = cit->second->GetPackPolicy_HybridCrypt(); + iReadOffset += pCryptPolicy->ReadSupplementatyDataBlockFromStream( pStream+iReadOffset ); + break; + } + } + } +} + + +void CEterPackManager::WriteHybridCryptPackInfo(const char* pFileName) +{ + //NOTE : this file format contains a little bit of redundant data. + //however it`s better for seperating cryptkey & supplementary data block. + + //dump file format + + //SDB data offset(4) + + // about cryptkey + //total packagecnt (4byte) + // for packagecnt + // db name hash 4byte( stl.h stringhash ) + // extension cnt( 4byte) + // for extension cnt + // ext hash ( stl.h stringhash ) + // key-16byte + // iv-16byte + + //about SDB data + //total packagecnt (4byte) + // for packagecnt + // db name hash 4byte( stl.h stringhash ) +child node size(4byte) + // sdb file cnt( 4byte ) + // for sdb file cnt + // filename hash ( stl.h stringhash ) + // related map name size(4), relate map name + // sdb block size( 1byte ) + // sdb blocks + + CFileBase keyFile; + + if( !keyFile.Create( pFileName, CFileBase::FILEMODE_WRITE) ) + { + //TODO : write log + return; + } + + int iKeyPackageCount = 0; + + //write later ( SDB Offset & PackageCnt for Key ) + keyFile.SeekCur(2*sizeof(int)); + + TEterPackMap::const_iterator cit; + for( cit = m_PackMap.begin(); cit != m_PackMap.end(); ++cit ) + { + EterPackPolicy_CSHybridCrypt* pPolicy = cit->second->GetPackPolicy_HybridCrypt(); + if( !pPolicy || !pPolicy->IsContainingCryptKey() ) + continue; + + iKeyPackageCount++; + auto ssvv = std::string(cit->first); + std::string noPathName = CFileNameHelper::NoPath(ssvv); + + DWORD dwPackNamehash = stringhash().GetHash(noPathName); + + CMakePackLog::GetSingleton().Writef("CEterPackManager::WriteHybridCryptPackInfo PackName : %s, Hash : %x", noPathName.c_str(), dwPackNamehash); + keyFile.Write( &dwPackNamehash, sizeof(DWORD) ); + + pPolicy->WriteCryptKeyToFile( keyFile ); + } + + //Write SDB Data + int iSDBDataOffset = keyFile.GetPosition(); + int iSDBPackageCnt = 0; + + //Write SDB PackageCnt Later + keyFile.SeekCur(sizeof(int)); + for( cit = m_PackMap.begin(); cit != m_PackMap.end(); ++cit ) + { + EterPackPolicy_CSHybridCrypt* pPolicy = cit->second->GetPackPolicy_HybridCrypt(); + if( !pPolicy || !pPolicy->IsContainingSDBFile() ) + continue; + + iSDBPackageCnt++; + + auto ssvv1 = std::string(cit->first); + auto noPathName = CFileNameHelper::NoPath(ssvv1); + + DWORD dwPackNamehash = stringhash().GetHash(noPathName); + keyFile.Write( &dwPackNamehash, sizeof(DWORD) ); + + int iSDBSizeWriteOffset = keyFile.GetPosition(); + keyFile.SeekCur(sizeof(int)); + + pPolicy->WriteSupplementaryDataBlockToFile( keyFile ); + int iSDBSizeAfterWrite = keyFile.GetPosition(); + + keyFile.Seek(iSDBSizeWriteOffset); + + int iSDBSize = iSDBSizeAfterWrite-(iSDBSizeWriteOffset+4); + keyFile.Write( &iSDBSize, sizeof(int) ); + + keyFile.Seek(iSDBSizeAfterWrite); + } + + //write sdb data start offset & package cnt + keyFile.Seek(0); + keyFile.Write( &iSDBDataOffset, sizeof(int)); + keyFile.Write( &iKeyPackageCount, sizeof(int)); + + keyFile.Seek(iSDBDataOffset); + keyFile.Write( &iSDBPackageCnt, sizeof(int)); + + keyFile.Close(); +} diff --git a/source/EterPack/EterPackManager.h b/source/EterPack/EterPackManager.h new file mode 100644 index 0000000..dbc813a --- /dev/null +++ b/source/EterPack/EterPackManager.h @@ -0,0 +1,96 @@ +#pragma once + +#include +#include +#include "../eterBase/Singleton.h" +#include "../eterBase/Stl.h" + +#include "EterPack.h" + +class CEterPackManager : public CSingleton +{ + public: + struct SCache + { + BYTE* m_abBufData; + DWORD m_dwBufSize; + }; + public: + enum ESearchModes + { + SEARCH_FILE_FIRST, + SEARCH_PACK_FIRST + }; + + typedef std::list TEterPackList; + typedef std::unordered_map TEterPackMap; + + public: + CEterPackManager(); + virtual ~CEterPackManager(); + + void SetCacheMode(); + void SetRelativePathMode(); + + void LoadStaticCache(const char* c_szFileName); + + void SetSearchMode(bool bPackFirst); + int GetSearchMode(); + + //THEMIDA + bool Get(CMappedFile & rMappedFile, const char * c_szFileName, LPCVOID * pData); + + //THEMIDA + bool GetFromPack(CMappedFile & rMappedFile, const char * c_szFileName, LPCVOID * pData); + + //THEMIDA + bool GetFromFile(CMappedFile & rMappedFile, const char * c_szFileName, LPCVOID * pData); + bool isExist(const char * c_szFileName); + bool isExistInPack(const char * c_szFileName); + + bool RegisterPack(const char * c_szName, const char * c_szDirectory, const BYTE* c_pbIV = NULL); + void RegisterRootPack(const char * c_szName); + bool RegisterPackWhenPackMaking(const char * c_szName, const char * c_szDirectory, CEterPack* pPack); + + + bool DecryptPackIV(DWORD key); + + const char * GetRootPackFileName(); + + //for hybridcrypt + //THEMIDA + void WriteHybridCryptPackInfo(const char* pFileName); + + //THEMIDA + void RetrieveHybridCryptPackKeys( const BYTE* pStream ); + //THEMIDA + void RetrieveHybridCryptPackSDB( const BYTE* pStream ); + + // ޸𸮿 ε ѵ , ؾ ͵ . + public: + void ArrangeMemoryMappedPack(); + + protected: + int ConvertFileName(const char * c_szFileName, std::string & rstrFileName); // StringPath std::string + bool CompareName(const char * c_szDirectoryName, DWORD iLength, const char * c_szFileName); + + CEterPack* FindPack(const char* c_szPathName); + + SCache* __FindCache(DWORD dwFileNameHash); + void __ClearCacheMap(); + + protected: + bool m_bTryRelativePath; + bool m_isCacheMode; + int m_iSearchMode; + + CEterFileDict m_FileDict; + CEterPack m_RootPack; + TEterPackList m_PackList; + TEterPackMap m_PackMap; + TEterPackMap m_DirPackMap; + + std::unordered_map m_kMap_dwNameKey_kCache; + + CRITICAL_SECTION m_csFinder; +}; diff --git a/source/EterPack/EterPackPolicy_CSHybridCrypt.cpp b/source/EterPack/EterPackPolicy_CSHybridCrypt.cpp new file mode 100644 index 0000000..4cb11ae --- /dev/null +++ b/source/EterPack/EterPackPolicy_CSHybridCrypt.cpp @@ -0,0 +1,503 @@ +#include "Stdafx.h" +#include "EterPackPolicy_CSHybridCrypt.h" +#include "../EterBase/Stl.h" +#include "../EterBase/FileName.h" +#include "../EterBase/FileBase.h" +#include "../EterBase/Crc32.h" +#include "../EterBase/lzo.h" +#include "../EterBase/Random.h" +#include +#include + +using namespace CryptoPP; + +#define CIPHER_MODE CTR_Mode + +#ifdef __THEMIDA__ +#include +#endif +//Cipher +//Block Size +//Key Length +// +//Default Minimum Maximum +//AES(Rijndael) 16 16 16 32 +//Blowfish 8 16 0 56 +//Camellia 16 16 16 32 +//CAST-128 8 16 5 16 +//CAST-256 16 16 16 32 +//DES 8 8 8 8 +//DES-EDE2 8 16 16 16 +//DES-EDE3 8 24 24 24 +//DES-XEX3 8 24 24 24 +//GOST 8 32 32 32 +//IDEA 8 16 16 16 +//MARS 16 16 16 56 +//RC2 8 16 1 128 +//RC5 8 16 0 255 +//RC6 16 16 0 255 +//SAFER-K 8 16 8 16 +//SAFER-SK 8 16 8 16 +//Serpent 16 16 1 32 +//SHACAL-2 32 16 1 64 +//SHARK-E 8 16 1 16 +//SKIPJACK 8 10 1 10 +//3-Way 12 12 1 12 +//Twofish 16 16 0 32 +//XTEA 8 16 1 16 + +inline std::string GetFileExt( std::string& rfileName ) +{ + stl_lowers(rfileName); + return CFileNameHelper::GetExtension(rfileName); +} + +EterPackPolicy_CSHybridCrypt::~EterPackPolicy_CSHybridCrypt() +{ + m_mapHybridCryptKey.clear(); + m_mapSDBMap.clear(); +} + +bool EterPackPolicy_CSHybridCrypt::IsContainingCryptKey() const +{ + return (m_mapHybridCryptKey.size() > 0) ? true : false; +} + + +bool EterPackPolicy_CSHybridCrypt::GenerateCryptKey( std::string& rfileName ) +{ +#ifdef __THEMIDA__ + VM_START +#endif + + //make lower & extract ext + std::string extName = GetFileExt(rfileName); + stl_lowers(extName); + + DWORD dwExtHash = stringhash().GetHash(extName); + + TCSHybridCryptKeyMap::const_iterator cit = m_mapHybridCryptKey.find( dwExtHash ); + + if( cit != m_mapHybridCryptKey.end() ) + { + //TODO : log already registered + return false; + } + + static AutoSeededRandomPool rnd; + + TCSHybridCryptKey info; + { + rnd.GenerateBlock( &(info.uEncryptKey.key[0]), sizeof(info.uEncryptKey) ); + rnd.GenerateBlock( &(info.uEncryptIV.iv[0]), sizeof(info.uEncryptIV) ); + + //for test + /* memset( &info.uEncryptKey.key, 0x10, sizeof(info.uEncryptKey) ); + memset( &info.uEncryptIV.iv, 0x10, sizeof(info.uEncryptIV) ); */ + } + m_mapHybridCryptKey[dwExtHash] = info; + +#ifdef __THEMIDA__ + VM_END +#endif + + return true; +} + +bool EterPackPolicy_CSHybridCrypt::GetPerFileCryptKey( std::string& rfileName, eHybridCipherAlgorithm& eAlgorithm, TEncryptKey& key, TEncryptIV& iv ) +{ +#ifdef __THEMIDA__ + VM_START +#endif + + std::string fileNamelower = rfileName; + stl_lowers(fileNamelower); + + std::string extName = GetFileExt(fileNamelower); + + TCSHybridCryptKeyMap::const_iterator cit = m_mapHybridCryptKey.find( stringhash().GetHash(extName)); + + if( cit == m_mapHybridCryptKey.end() ) + { + //TODO : log no file ext info + return false; + } + + DWORD dwfileNameCrc = GetCRC32(fileNamelower.c_str(), fileNamelower.size()); + + //make file specific algorithm & key & iv + eAlgorithm = (eHybridCipherAlgorithm)(dwfileNameCrc % Num_Of_Ciphers); + + ::memcpy(key.key, cit->second.uEncryptKey.key, sizeof(key) ); + ::memcpy(iv.iv, cit->second.uEncryptIV.iv, sizeof(iv) ); + + + //Themida Warning + for( int i = 0; i < (sizeof(key)/sizeof(dwfileNameCrc)); ++i) + { + *((DWORD*)key.key + i) ^= dwfileNameCrc; + } + for( int i = 0; i < (sizeof(iv)/sizeof(dwfileNameCrc)); ++i) + { + *((DWORD*)iv.iv + i) ^= dwfileNameCrc; + } +#ifdef __THEMIDA__ + VM_END +#endif + + return true; +} + + +bool EterPackPolicy_CSHybridCrypt::EncryptMemory( std::string& rfileName, IN const BYTE* pSrcData, IN int iSrcLen, OUT CLZObject& zObj ) +{ +#ifdef __THEMIDA__ + VM_START +#endif + + eHybridCipherAlgorithm eAlgorithm; + TEncryptKey key; + TEncryptIV iv; + + if( !GetPerFileCryptKey( rfileName, eAlgorithm, key, iv ) ) + { + return false; + } + + // start cipher + std::string strCipher; + //NOTE : ciphered stream size could be different from original size if you choose diffrent cipher mode & algorithm + //( i.e ECB or CBC mode ) + strCipher.reserve(iSrcLen); + + if( eAlgorithm == e_Cipher_Camellia ) + { + // Encryptor + CIPHER_MODE::Encryption Encryptor; + Encryptor.SetKeyWithIV(key.keyCamellia, sizeof(key.keyCamellia), iv.ivCamellia, sizeof(iv.ivCamellia)); + + ArraySource(pSrcData, iSrcLen, true, + new StreamTransformationFilter(Encryptor, new CryptoPP::StringSink(strCipher))); + } + else if( eAlgorithm == e_Cipher_Twofish ) + { + // Encryptor + CIPHER_MODE::Encryption Encryptor; + Encryptor.SetKeyWithIV(key.keyTwofish, sizeof(key.keyTwofish), iv.ivTwofish, sizeof(iv.ivTwofish)); + + ArraySource(pSrcData, iSrcLen, true, + new StreamTransformationFilter(Encryptor, new CryptoPP::StringSink(strCipher))); + } + else if( eAlgorithm == e_Cipher_XTEA ) + { + // Encryptor + CIPHER_MODE::Encryption Encryptor; + Encryptor.SetKeyWithIV(key.keyXTEA, sizeof(key.keyXTEA), iv.ivXTEA, sizeof(iv.ivXTEA)); + + ArraySource(pSrcData, iSrcLen, true, + new StreamTransformationFilter(Encryptor, new CryptoPP::StringSink(strCipher))); + } + + if (strCipher.length() != iSrcLen) + { + //TODO: size error log + return false; + } + + zObj.AllocBuffer(iSrcLen); + memcpy(zObj.GetBuffer(), strCipher.c_str(), strCipher.length() ); + +#ifdef __THEMIDA__ + VM_END +#endif + + return true; +} + +bool EterPackPolicy_CSHybridCrypt::DecryptMemory( std::string& rfilename, IN const BYTE* pEncryptedData, IN int iEncryptedLen, OUT CLZObject& zObj ) +{ +#ifdef __THEMIDA__ + VM_START +#endif + + eHybridCipherAlgorithm eAlgorithm; + TEncryptKey key; + TEncryptIV iv; + + if( !GetPerFileCryptKey( rfilename, eAlgorithm, key, iv ) ) + { + return false; + } + + // start decipher + std::string strDecipher; + //NOTE : ciphered stream size could be different from original size if you choose diffrent cipher mode & algorithm + //( i.e ECB or CBC mode ) + strDecipher.reserve(iEncryptedLen); + + if( eAlgorithm == e_Cipher_Camellia ) + { + // Decryptor + CIPHER_MODE::Decryption Decryptor; + Decryptor.SetKeyWithIV(key.keyCamellia, sizeof(key.keyCamellia), iv.ivCamellia, sizeof(iv.ivCamellia)); + + ArraySource(pEncryptedData, iEncryptedLen, true, + new StreamTransformationFilter(Decryptor, new CryptoPP::StringSink(strDecipher))); + } + else if( eAlgorithm == e_Cipher_Twofish ) + { + // Decryptor + CIPHER_MODE::Decryption Decryptor; + Decryptor.SetKeyWithIV(key.keyTwofish, sizeof(key.keyTwofish), iv.ivTwofish, sizeof(iv.ivTwofish)); + + ArraySource(pEncryptedData, iEncryptedLen, true, + new StreamTransformationFilter(Decryptor, new CryptoPP::StringSink(strDecipher))); + } + else if( eAlgorithm == e_Cipher_XTEA ) + { + // Decryptor + CIPHER_MODE::Decryption Decryptor; + Decryptor.SetKeyWithIV(key.keyXTEA, sizeof(key.keyXTEA), iv.ivXTEA, sizeof(iv.ivXTEA)); + + ArraySource(pEncryptedData, iEncryptedLen, true, + new StreamTransformationFilter(Decryptor, new CryptoPP::StringSink(strDecipher))); + } + + + if (strDecipher.length() != iEncryptedLen) + { + //TODO: size error log + return false; + } + + zObj.AllocBuffer(iEncryptedLen); + memcpy(zObj.GetBuffer(), strDecipher.c_str(), strDecipher.length() ); + +#ifdef __THEMIDA__ + VM_END +#endif + + return true; +} + +void EterPackPolicy_CSHybridCrypt::WriteCryptKeyToFile( CFileBase& rFile ) +{ + // ext cnt 4byte + // for ext hash ( crc32 ) + // key-16byte + // iv-16byte + + DWORD dwCryptKeySize = m_mapHybridCryptKey.size(); + rFile.Write( &dwCryptKeySize, sizeof(DWORD) ); + + TCSHybridCryptKeyMap::const_iterator cit; + for( cit = m_mapHybridCryptKey.begin(); cit != m_mapHybridCryptKey.end(); ++cit ) + { + DWORD extNamehash = cit->first; + const TCSHybridCryptKey& CryptKey = cit->second; + + rFile.Write( &extNamehash, sizeof(DWORD) ); + rFile.Write( CryptKey.uEncryptKey.key, sizeof(TEncryptKey) ); + rFile.Write( CryptKey.uEncryptIV.iv, sizeof(TEncryptIV) ); + } +} + +int EterPackPolicy_CSHybridCrypt::ReadCryptKeyInfoFromStream( IN const BYTE* pStream ) +{ + int iStreamOffset = 0; + + DWORD dwCryptoInfoSize; + memcpy(&dwCryptoInfoSize, pStream, sizeof(DWORD) ); + iStreamOffset += sizeof(DWORD); + + DWORD dwExtHash; + + m_mapHybridCryptKey.clear(); + + for( int i = 0; i < dwCryptoInfoSize; ++i ) + { + memcpy(&dwExtHash, pStream + iStreamOffset, sizeof(DWORD) ); + iStreamOffset += sizeof(DWORD); + + TCSHybridCryptKey info; + { + memcpy(info.uEncryptKey.key, pStream + iStreamOffset, sizeof(TEncryptKey) ); + iStreamOffset += sizeof(TEncryptKey); + + memcpy(info.uEncryptIV.iv, pStream + iStreamOffset, sizeof(TEncryptIV) ); + iStreamOffset += sizeof(TEncryptIV); + } + + m_mapHybridCryptKey[dwExtHash] = info; + } + + return iStreamOffset; +} + +bool EterPackPolicy_CSHybridCrypt::GenerateSupplementaryDataBlock(std::string& rfilename, const std::string& strMapName, IN const BYTE* pSrcData, IN int iSrcLen, OUT LPBYTE& pDestData, OUT int& iDestLen ) +{ +#ifdef __THEMIDA__ + VM_START +#endif + + std::string fileNamelower = rfilename; + stl_lowers( fileNamelower ); + + DWORD dwFileNameHash = stringhash().GetHash(fileNamelower); + TSupplementaryDataBlockMap::const_iterator cit = m_mapSDBMap.find( dwFileNameHash ); + + if( cit != m_mapSDBMap.end() ) + { + //TODO : log already registered + return false; + } + + //TODO : Find Better Method for deciding SDB Postion & Size + + //prevent stream copy duplication + TSupplementaryDataBlockInfo info; + m_mapSDBMap[dwFileNameHash] = info; + + std::string& strRelatedMapName = m_mapSDBMap[dwFileNameHash].strRelatedMapName; + std::vector& sdbVector = m_mapSDBMap[dwFileNameHash].vecStream; + + + //fill the data!! + { + strRelatedMapName = strMapName; + + int iSDBSize = random_range( 64, 128 ); + + if( iSrcLen < iSDBSize ) + { + iSDBSize = iSrcLen - 1; + if( iSDBSize <= 0 ) + { + //TODO : is there 1byte file exist??? + return false; + } + } + + sdbVector.resize( iSDBSize ); + + iDestLen = iSrcLen - iSDBSize; + pDestData = (LPBYTE)pSrcData; + + memcpy( &sdbVector[0], pDestData + iDestLen, iSDBSize ); + } +#ifdef __THEMIDA__ + VM_END +#endif + return true; +} + + +bool EterPackPolicy_CSHybridCrypt::GetSupplementaryDataBlock( std::string& rfilename, OUT LPBYTE& pSDB, OUT int& iSDBSize ) +{ +#ifdef __THEMIDA__ + VM_START +#endif + + std::string fileNamelower = rfilename; + stl_lowers( fileNamelower ); + + DWORD dwFileNameHash = stringhash().GetHash(fileNamelower); + TSupplementaryDataBlockMap::const_iterator cit = m_mapSDBMap.find( dwFileNameHash ); + + if( cit == m_mapSDBMap.end() ) + { + //TODO : log already registered + return false; + } + + const std::vector& vecSDB = cit->second.vecStream; + + iSDBSize = vecSDB.size(); + + if(iSDBSize <= 0) + { + pSDB = NULL; + return false; + } + + pSDB = (BYTE*)&vecSDB[0]; +#ifdef __THEMIDA__ + VM_END +#endif + + return true; +} + +bool EterPackPolicy_CSHybridCrypt::IsContainingSDBFile() const +{ + return m_mapSDBMap.size() > 0 ? true : false; +} + +void EterPackPolicy_CSHybridCrypt::WriteSupplementaryDataBlockToFile( CFileBase& rFile ) +{ + //about SDB data + // sdb file cnt( 4byte ) + // for sdb file cnt + // filename hash ( stl.h stringhash ) + // related map name size(4), relate map name + // sdb block size( 1byte ) + // sdb blocks + + DWORD dwSDBMapSize = m_mapSDBMap.size(); + rFile.Write( &dwSDBMapSize, sizeof(DWORD) ); + + TSupplementaryDataBlockMap::const_iterator cit; + for( cit = m_mapSDBMap.begin(); cit != m_mapSDBMap.end(); ++cit ) + { + DWORD dwFileNamehash = cit->first; + rFile.Write( &dwFileNamehash, sizeof(DWORD) ); + + const std::string strRelatedMapName = cit->second.strRelatedMapName; + DWORD dwMapNameSize = strRelatedMapName.size(); + rFile.Write( &dwMapNameSize, sizeof(DWORD) ); + rFile.Write( strRelatedMapName.c_str(), dwMapNameSize ); + + const std::vector& sdbVector = cit->second.vecStream; + BYTE bSDBSize = (BYTE)(sdbVector.size()); + + rFile.Write( &bSDBSize, sizeof(bSDBSize) ); + if( bSDBSize > 0 ) + rFile.Write( &sdbVector[0], bSDBSize ); + } +} + +int EterPackPolicy_CSHybridCrypt::ReadSupplementatyDataBlockFromStream( IN const BYTE* pStream ) +{ +#ifdef __THEMIDA__ + VM_START +#endif + + //DWORD dwFileIdentifier; + //std::vector vecSDBStream; + + DWORD dwFileNameHash; + BYTE bSDBSize; + int iStreamOffset = 0; + + memcpy(&dwFileNameHash, pStream + iStreamOffset, sizeof(DWORD) ); + iStreamOffset += sizeof(DWORD); + + memcpy(&bSDBSize, pStream + iStreamOffset, sizeof(BYTE) ); + iStreamOffset += sizeof(BYTE); + + // NOTE : related map name isn`t required in client. so we don`t recv it from stream to reduce packet size. + TSupplementaryDataBlockInfo info; + { + info.vecStream.resize( bSDBSize ); + memcpy(&info.vecStream[0], pStream + iStreamOffset, bSDBSize ); + iStreamOffset += bSDBSize; + + m_mapSDBMap[dwFileNameHash] = info; + } + +#ifdef __THEMIDA__ + VM_END +#endif + + return iStreamOffset; +} diff --git a/source/EterPack/EterPackPolicy_CSHybridCrypt.h b/source/EterPack/EterPackPolicy_CSHybridCrypt.h new file mode 100644 index 0000000..63f76ab --- /dev/null +++ b/source/EterPack/EterPackPolicy_CSHybridCrypt.h @@ -0,0 +1,94 @@ +#ifndef __INC_ETERPACKLIB_ETERPACKPOLICY_CSHYBRIDCRYPT_H__ +#define __INC_ETERPACKLIB_ETERPACKPOLICY_CSHYBRIDCRYPT_H__ + +#include +#include +#include +#include +#include + +enum eHybridCipherAlgorithm +{ + e_Cipher_Camellia, + e_Cipher_Twofish, + e_Cipher_XTEA, + Num_Of_Ciphers +}; + + +class CFileBase; +class CLZObject; + +//THEMIDA +class EterPackPolicy_CSHybridCrypt +{ +public: + ~EterPackPolicy_CSHybridCrypt(); + + bool GenerateCryptKey( std::string& rfileName ); + bool EncryptMemory( std::string& rfilename, IN const BYTE* pSrcData, IN int iSrcLen, OUT CLZObject& zObj ); + bool DecryptMemory( std::string& rfilename, IN const BYTE* pSrcData, IN int iSrcLen, OUT CLZObject& zObj ); + bool IsContainingCryptKey() const; + + //Supplementary Data Block (SDB) + bool GenerateSupplementaryDataBlock(std::string& rfilename, const std::string& strMapName, IN const BYTE* pSrcData, IN int iSrcLen, OUT LPBYTE& pDestData, OUT int& iDestLen ); + bool GetSupplementaryDataBlock( std::string& rfilename, OUT LPBYTE& pSDB, OUT int& iSDBSize ); + bool IsContainingSDBFile() const; + + // Read/Write IO + void WriteCryptKeyToFile( CFileBase& rFile ); + int ReadCryptKeyInfoFromStream( IN const BYTE* pStream ); + + void WriteSupplementaryDataBlockToFile( CFileBase& rFile ); + int ReadSupplementatyDataBlockFromStream( IN const BYTE* pStream ); + +protected: + + typedef union UEncryptKey + { + BYTE key[16]; + BYTE keyCamellia[ CryptoPP::Camellia::DEFAULT_KEYLENGTH]; + BYTE keyTwofish [ CryptoPP::Twofish::DEFAULT_KEYLENGTH]; + BYTE keyXTEA [ CryptoPP::XTEA::DEFAULT_KEYLENGTH]; + + } TEncryptKey; + + typedef union UEncryptIV + { + BYTE iv[16]; + BYTE ivCamellia [ CryptoPP::Camellia::BLOCKSIZE]; + BYTE ivTwofish [ CryptoPP::Twofish::BLOCKSIZE]; + BYTE ivXTEA [ CryptoPP::XTEA::BLOCKSIZE]; + + } TEncryptIV; + + + typedef struct SCSHybridCryptKey + { + TEncryptKey uEncryptKey; + TEncryptIV uEncryptIV; + + } TCSHybridCryptKey; + + typedef std::unordered_map TCSHybridCryptKeyMap; + TCSHybridCryptKeyMap m_mapHybridCryptKey; + + typedef struct SSupplementaryDataBlockInfo + { + std::string strRelatedMapName; + std::vector vecStream; + + } TSupplementaryDataBlockInfo; + + typedef std::unordered_map TSupplementaryDataBlockMap; //key filename hash + TSupplementaryDataBlockMap m_mapSDBMap; + +private: + bool GetPerFileCryptKey( std::string& rfileName, eHybridCipherAlgorithm& eAlgorithm, TEncryptKey& key, TEncryptIV& iv ); + + +}; + + + +#endif // __INC_ETERPACKLIB_ETERPACKPOLICY_CSHYBRIDCRYPT_H__ diff --git a/source/EterPack/Inline.h b/source/EterPack/Inline.h new file mode 100644 index 0000000..92dbb49 --- /dev/null +++ b/source/EterPack/Inline.h @@ -0,0 +1,34 @@ +#ifndef __INC_ETERPACK_INLINE_H__ +#define __INC_ETERPACK_INLINE_H__ + +inline void inlinePathCreate(const char* path) +{ + char dir[64]; + const char* p, *k; + + p = path + 3; + + while (NULL != (k = strchr(p, '/'))) + { + memset(dir, 0, sizeof(dir)); + strncpy(dir, path, k - path); + CreateDirectory(dir, NULL); + p = k + 1; + } +} + +inline void inlineConvertPackFilename(char* name) +{ + char * p = name; + + while (*p) + { + if (*p == '\\') + *p = '/'; + else + *p = (int) tolower(*p); + p++; + } +} + +#endif diff --git a/source/EterPack/StdAfx.cpp b/source/EterPack/StdAfx.cpp new file mode 100644 index 0000000..804d088 --- /dev/null +++ b/source/EterPack/StdAfx.cpp @@ -0,0 +1,2 @@ +#include "stdafx.h" + diff --git a/source/EterPack/StdAfx.h b/source/EterPack/StdAfx.h new file mode 100644 index 0000000..eea9bac --- /dev/null +++ b/source/EterPack/StdAfx.h @@ -0,0 +1,9 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +//#include +#include +#include + +#include "../eterBase/StdAfx.h" \ No newline at end of file diff --git a/source/EterPack/md5.c b/source/EterPack/md5.c new file mode 100644 index 0000000..2fe2f4e --- /dev/null +++ b/source/EterPack/md5.c @@ -0,0 +1,1033 @@ +/* + + *********************************************************************** + + ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** + + ** ** + + ** License to copy and use this software is granted provided that ** + + ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** + + ** Digest Algorithm" in all material mentioning or referencing this ** + + ** software or this function. ** + + ** ** + + ** License is also granted to make and use derivative works ** + + ** provided that such works are identified as "derived from the RSA ** + + ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** + + ** material mentioning or referencing the derived work. ** + + ** ** + + ** RSA Data Security, Inc. makes no representations concerning ** + + ** either the merchantability of this software or the suitability ** + + ** of this software for any particular purpose. It is provided "as ** + + ** is" without express or implied warranty of any kind. ** + + ** ** + + ** These notices must be retained in any copies of any part of this ** + + ** documentation and/or software. ** + + *********************************************************************** + + */ + + +#include "md5.h" + + + +/* + + *********************************************************************** + + ** Message-digest routines: ** + + ** To form the message digest for a message M ** + + ** (1) Initialize a context buffer mdContext using MD5Init ** + + ** (2) Call MD5Update on mdContext and M ** + + ** (3) Call MD5Final on mdContext ** + + ** The message digest is now in mdContext->digest[0...15] ** + + *********************************************************************** + + */ + + + +static unsigned char PADDING[64] = { + + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +}; + + + +#ifndef CPU386 /* Alternate defs exist for 386 assembler version */ + +/* F, G, H and I are basic MD5 functions */ + +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) + +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) + +#define H(x, y, z) ((x) ^ (y) ^ (z)) + +#define I(x, y, z) ((y) ^ ((x) | (~z))) + + + +/* ROTATE_LEFT rotates x left n bits */ + +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + + + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */ + +/* Rotation is separate from addition to prevent recomputation */ + +#define FF(a, b, c, d, x, s, ac) \ + (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + +#define GG(a, b, c, d, x, s, ac) \ + (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + +#define HH(a, b, c, d, x, s, ac) \ + (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + +#define II(a, b, c, d, x, s, ac) \ + (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + +#endif /* CPU386 */ + + + +/* The routine MD5Init initializes the message-digest context + + mdContext. All fields are set to zero. + + */ + +void MD5Init (MD5_CTX *mdContext) +{ + + mdContext->i[0] = mdContext->i[1] = (UINT4)0; + + + + /* Load magic initialization constants. + + */ + + mdContext->buf[0] = (UINT4)0x67452301; + + mdContext->buf[1] = (UINT4)0xefcdab89; + + mdContext->buf[2] = (UINT4)0x98badcfe; + + mdContext->buf[3] = (UINT4)0x10325476; + +} + + + +/* The routine MD5Update updates the message-digest context to + + account for the presence of each of the characters inBuf[0..inLen-1] + + in the message whose digest is being computed. + + */ + +void MD5Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen) +{ + + UINT4 in[16]; + + int mdi; + + unsigned int i, ii; + + + + /* compute number of bytes mod 64 */ + + mdi = (int)((mdContext->i[0] >> 3) & 0x3F); + + + + /* update number of bits */ + + if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0]) + + mdContext->i[1]++; + + mdContext->i[0] += ((UINT4)inLen << 3); + + mdContext->i[1] += ((UINT4)inLen >> 29); + + + +#ifdef LITTLE_ENDIAN + + /* Speedup for little-endian machines suggested in MD5 report --P Karn */ + + if(mdi == 0 && ((int)inBuf & 3) == 0){ + + while(inLen >= 64){ + + MD5Transform(mdContext->buf,(UINT4 *)inBuf); + + inLen -= 64; + + inBuf += 64; + + } + + } + +#endif /* LITTLE_ENDIAN */ + + while (inLen--) { + + /* add new character to buffer, increment mdi */ + + mdContext->in[mdi++] = *inBuf++; + + + + /* transform if necessary */ + + if (mdi == 0x40) { + + for (i = 0, ii = 0; i < 16; i++, ii += 4) + + in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | + + (((UINT4)mdContext->in[ii+2]) << 16) | + + (((UINT4)mdContext->in[ii+1]) << 8) | + + ((UINT4)mdContext->in[ii]); + + MD5Transform (mdContext->buf, in); + + mdi = 0; + + } + + } + +} + + + +/* The routine MD5Final terminates the message-digest computation and + + ends with the desired message digest in mdContext->digest[0...15]. + + */ + +void MD5Final (MD5_CTX *mdContext) +{ + + UINT4 in[16]; + + int mdi; + + unsigned int i, ii; + + unsigned int padLen; + + + + /* save number of bits */ + + in[14] = mdContext->i[0]; + + in[15] = mdContext->i[1]; + + + + /* compute number of bytes mod 64 */ + + mdi = (int)((mdContext->i[0] >> 3) & 0x3F); + + + + /* pad out to 56 mod 64 */ + + padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); + + MD5Update (mdContext, PADDING, padLen); + + + + /* append length in bits and transform */ + + for (i = 0, ii = 0; i < 14; i++, ii += 4) + + in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | + + (((UINT4)mdContext->in[ii+2]) << 16) | + + (((UINT4)mdContext->in[ii+1]) << 8) | + + ((UINT4)mdContext->in[ii]); + + MD5Transform (mdContext->buf, in); + + + + /* store buffer in digest */ + + for (i = 0, ii = 0; i < 4; i++, ii += 4) { + + mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF); + + mdContext->digest[ii+1] = + + (unsigned char)((mdContext->buf[i] >> 8) & 0xFF); + + mdContext->digest[ii+2] = + + (unsigned char)((mdContext->buf[i] >> 16) & 0xFF); + + mdContext->digest[ii+3] = + + (unsigned char)((mdContext->buf[i] >> 24) & 0xFF); + + } + +} + + + +#ifndef CPU386 /* Fast assembler version exists for 386/486 */ + + + +/* Basic MD5 step. Transforms buf based on in. + + */ + +void MD5Transform (buf, in) + +UINT4 *buf; + +UINT4 *in; + +{ + + UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; + + + + /* Round 1 */ + +#define S11 7 + +#define S12 12 + +#define S13 17 + +#define S14 22 + + FF ( a, b, c, d, in[ 0], S11, 3614090360); /* 1 */ + + FF ( d, a, b, c, in[ 1], S12, 3905402710); /* 2 */ + + FF ( c, d, a, b, in[ 2], S13, 606105819); /* 3 */ + + FF ( b, c, d, a, in[ 3], S14, 3250441966); /* 4 */ + + FF ( a, b, c, d, in[ 4], S11, 4118548399); /* 5 */ + + FF ( d, a, b, c, in[ 5], S12, 1200080426); /* 6 */ + + FF ( c, d, a, b, in[ 6], S13, 2821735955); /* 7 */ + + FF ( b, c, d, a, in[ 7], S14, 4249261313); /* 8 */ + + FF ( a, b, c, d, in[ 8], S11, 1770035416); /* 9 */ + + FF ( d, a, b, c, in[ 9], S12, 2336552879); /* 10 */ + + FF ( c, d, a, b, in[10], S13, 4294925233); /* 11 */ + + FF ( b, c, d, a, in[11], S14, 2304563134); /* 12 */ + + FF ( a, b, c, d, in[12], S11, 1804603682); /* 13 */ + + FF ( d, a, b, c, in[13], S12, 4254626195); /* 14 */ + + FF ( c, d, a, b, in[14], S13, 2792965006); /* 15 */ + + FF ( b, c, d, a, in[15], S14, 1236535329); /* 16 */ + + + + /* Round 2 */ + +#define S21 5 + +#define S22 9 + +#define S23 14 + +#define S24 20 + + GG ( a, b, c, d, in[ 1], S21, 4129170786); /* 17 */ + + GG ( d, a, b, c, in[ 6], S22, 3225465664); /* 18 */ + + GG ( c, d, a, b, in[11], S23, 643717713); /* 19 */ + + GG ( b, c, d, a, in[ 0], S24, 3921069994); /* 20 */ + + GG ( a, b, c, d, in[ 5], S21, 3593408605); /* 21 */ + + GG ( d, a, b, c, in[10], S22, 38016083); /* 22 */ + + GG ( c, d, a, b, in[15], S23, 3634488961); /* 23 */ + + GG ( b, c, d, a, in[ 4], S24, 3889429448); /* 24 */ + + GG ( a, b, c, d, in[ 9], S21, 568446438); /* 25 */ + + GG ( d, a, b, c, in[14], S22, 3275163606); /* 26 */ + + GG ( c, d, a, b, in[ 3], S23, 4107603335); /* 27 */ + + GG ( b, c, d, a, in[ 8], S24, 1163531501); /* 28 */ + + GG ( a, b, c, d, in[13], S21, 2850285829); /* 29 */ + + GG ( d, a, b, c, in[ 2], S22, 4243563512); /* 30 */ + + GG ( c, d, a, b, in[ 7], S23, 1735328473); /* 31 */ + + GG ( b, c, d, a, in[12], S24, 2368359562); /* 32 */ + + + + /* Round 3 */ + +#define S31 4 + +#define S32 11 + +#define S33 16 + +#define S34 23 + + HH ( a, b, c, d, in[ 5], S31, 4294588738); /* 33 */ + + HH ( d, a, b, c, in[ 8], S32, 2272392833); /* 34 */ + + HH ( c, d, a, b, in[11], S33, 1839030562); /* 35 */ + + HH ( b, c, d, a, in[14], S34, 4259657740); /* 36 */ + + HH ( a, b, c, d, in[ 1], S31, 2763975236); /* 37 */ + + HH ( d, a, b, c, in[ 4], S32, 1272893353); /* 38 */ + + HH ( c, d, a, b, in[ 7], S33, 4139469664); /* 39 */ + + HH ( b, c, d, a, in[10], S34, 3200236656); /* 40 */ + + HH ( a, b, c, d, in[13], S31, 681279174); /* 41 */ + + HH ( d, a, b, c, in[ 0], S32, 3936430074); /* 42 */ + + HH ( c, d, a, b, in[ 3], S33, 3572445317); /* 43 */ + + HH ( b, c, d, a, in[ 6], S34, 76029189); /* 44 */ + + HH ( a, b, c, d, in[ 9], S31, 3654602809); /* 45 */ + + HH ( d, a, b, c, in[12], S32, 3873151461); /* 46 */ + + HH ( c, d, a, b, in[15], S33, 530742520); /* 47 */ + + HH ( b, c, d, a, in[ 2], S34, 3299628645); /* 48 */ + + + + /* Round 4 */ + +#define S41 6 + +#define S42 10 + +#define S43 15 + +#define S44 21 + + II ( a, b, c, d, in[ 0], S41, 4096336452); /* 49 */ + + II ( d, a, b, c, in[ 7], S42, 1126891415); /* 50 */ + + II ( c, d, a, b, in[14], S43, 2878612391); /* 51 */ + + II ( b, c, d, a, in[ 5], S44, 4237533241); /* 52 */ + + II ( a, b, c, d, in[12], S41, 1700485571); /* 53 */ + + II ( d, a, b, c, in[ 3], S42, 2399980690); /* 54 */ + + II ( c, d, a, b, in[10], S43, 4293915773); /* 55 */ + + II ( b, c, d, a, in[ 1], S44, 2240044497); /* 56 */ + + II ( a, b, c, d, in[ 8], S41, 1873313359); /* 57 */ + + II ( d, a, b, c, in[15], S42, 4264355552); /* 58 */ + + II ( c, d, a, b, in[ 6], S43, 2734768916); /* 59 */ + + II ( b, c, d, a, in[13], S44, 1309151649); /* 60 */ + + II ( a, b, c, d, in[ 4], S41, 4149444226); /* 61 */ + + II ( d, a, b, c, in[11], S42, 3174756917); /* 62 */ + + II ( c, d, a, b, in[ 2], S43, 718787259); /* 63 */ + + II ( b, c, d, a, in[ 9], S44, 3951481745); /* 64 */ + + + + buf[0] += a; + + buf[1] += b; + + buf[2] += c; + + buf[3] += d; + +} + +#else /* CPU386 */ + +/* Fast 386 Borland C inline assembler version of the MD5Transform() function + + * from the RSA Data Security, Inc, MD5 Message Digest Algorithm. + + * + + * This version uses native 32 bit registers, so it needs a 386 or 486 CPU. + + * + + * Because this function does *lots* of 32-bit operations, this version is + + * MUCH faster than the reference C version compiled with a garden- + + * variety 16-bit MS-DOS C compiler. + + * + + * Written and placed into the public domain on + + * 22 February 1992 by Phil Karn, KA9Q + + */ + +/* I really shouldn't have to do this explicitly... */ + +#ifdef __COMPACT__ + + asm .MODEL COMPACT + +#elif __HUGE__ + + asm .MODEL HUGE + +#elif __LARGE__ + + asm .MODEL LARGE + +#elif __MEDIUM__ + + asm .MODEL MEDIUM + +#elif __SMALL__ + + asm .MODEL SMALL + +#elif __TINY__ + + asm .MODEL TINY + +#endif + + + +/* Code sequence common to all four rounds. + + * evaluates a = b + (a + edi + x + t) <<< s + + * Assumes a,b are registers, s,t are immediate constants + + * The 'lea' instruction is just a fast way to compute "a = a+t+edi" + + */ + +#define COM(a,b,x,s,t)\ + + asm lea a,t[a+edi];\ + + asm add a,x;\ + + asm rol a,s;\ + + asm add a,b; + + + +/* Round 1 functions */ + +/* edi = F(x,y,z) = (x & y) | (~x & z) */ + +#define F(x,y,z)\ + + asm mov edi,x;\ + + asm and edi,y;\ + + asm mov esi,x;\ + + asm not esi;\ + + asm and esi,z;\ + + asm or edi,esi + + + +/* a = b + ((a + F(x,y,z) + x + t) <<< s); */ + +#define FF(a,b,c,d,x,s,t)\ + + F(b,c,d);\ + + COM(a,b,x,s,t) + + + +/* Round 2 functions */ + +/* edi = G(x,y,z) = F(z,x,y) = (x & z) | (y & ~z) */ + +#define G(x,y,z) F(z,x,y) + + + +/* a = b + ((a + G(b,c,d) + x + t) <<< s) */ + +#define GG(a,b,c,d,x,s,t)\ + + G(b,c,d);\ + + COM(a,b,x,s,t) + + + +/* Round 3 functions */ + +/* edi = H(x,y,z) = x ^ y ^ z */ + +#define H(x,y,z)\ + + asm mov edi,x;\ + + asm xor edi,y;\ + + asm xor edi,z + + + +/* a = b + ((a + H(b,c,d) + x + t) <<< s) */ + +#define HH(a,b,c,d,x,s,t)\ + + H(b,c,d);\ + + COM(a,b,x,s,t) + + + +/* Round 4 functions */ + +/* edi = I(x,y,z) = y ^ (x | ~z) */ + +#define I(x,y,z)\ + + asm mov edi,z;\ + + asm not edi;\ + + asm or edi,x;\ + + asm xor edi,y + + + +/* a = b + ((a + I(b,c,d) + x + t) <<< s) */ + +#define II(a,b,c,d,x,s,t)\ + + I(b,c,d);\ + + COM(a,b,x,s,t) + + + +#define A eax + +#define B ebx + +#define C ecx + +#define D edx + + + +void + +MD5Transform(buf,input) + +UINT4 *buf; + +UINT4 *input; + +{ + + asm .386; /* Allow use of 32-bit general registers */ + + + + /* Save caller's registers */ + + asm push si; + + asm push di; + + asm push es; + + asm if @DataSize NE 0 + + asm push ds; + + asm endif + + + + /* Get buf argument */ + + asm if @DataSize NE 0 + + asm lds si,buf; + + asm else + + asm mov si,buf; + + asm endif + + asm mov A,dword ptr si[0*4]; /* A = buf[0] */ + + asm mov B,dword ptr si[1*4]; /* B = buf[1] */ + + asm mov C,dword ptr si[2*4]; /* C = buf[2] */ + + asm mov D,dword ptr si[3*4]; /* D = buf[3] */ + + + + /* Warning: This makes our other args inaccessible until bp + + * is restored! + + */ + + asm push bp; + + asm les bp,input + + + +/* Round 1. The *4 factors in the subscripts to bp account for the + + * byte offsets of each long element in the input array. + + */ + +#define S11 7 + +#define S12 12 + +#define S13 17 + +#define S14 22 + + FF(A,B,C,D,es:bp[ 0*4],S11,3614090360); /* 1 */ + + FF(D,A,B,C,es:bp[ 1*4],S12,3905402710); /* 2 */ + + FF(C,D,A,B,es:bp[ 2*4],S13, 606105819); /* 3 */ + + FF(B,C,D,A,es:bp[ 3*4],S14,3250441966); /* 4 */ + + FF(A,B,C,D,es:bp[ 4*4],S11,4118548399); /* 5 */ + + FF(D,A,B,C,es:bp[ 5*4],S12,1200080426); /* 6 */ + + FF(C,D,A,B,es:bp[ 6*4],S13,2821735955); /* 7 */ + + FF(B,C,D,A,es:bp[ 7*4],S14,4249261313); /* 8 */ + + FF(A,B,C,D,es:bp[ 8*4],S11,1770035416); /* 9 */ + + FF(D,A,B,C,es:bp[ 9*4],S12,2336552879); /* 10 */ + + FF(C,D,A,B,es:bp[10*4],S13,4294925233); /* 11 */ + + FF(B,C,D,A,es:bp[11*4],S14,2304563134); /* 12 */ + + FF(A,B,C,D,es:bp[12*4],S11,1804603682); /* 13 */ + + FF(D,A,B,C,es:bp[13*4],S12,4254626195); /* 14 */ + + FF(C,D,A,B,es:bp[14*4],S13,2792965006); /* 15 */ + + FF(B,C,D,A,es:bp[15*4],S14,1236535329); /* 16 */ + + + +/* Round 2 */ + +#define S21 5 + +#define S22 9 + +#define S23 14 + +#define S24 20 + + GG(A,B,C,D,es:bp[ 1*4],S21,4129170786); /* 17 */ + + GG(D,A,B,C,es:bp[ 6*4],S22,3225465664); /* 18 */ + + GG(C,D,A,B,es:bp[11*4],S23, 643717713); /* 19 */ + + GG(B,C,D,A,es:bp[ 0*4],S24,3921069994); /* 20 */ + + GG(A,B,C,D,es:bp[ 5*4],S21,3593408605); /* 21 */ + + GG(D,A,B,C,es:bp[10*4],S22, 38016083); /* 22 */ + + GG(C,D,A,B,es:bp[15*4],S23,3634488961); /* 23 */ + + GG(B,C,D,A,es:bp[ 4*4],S24,3889429448); /* 24 */ + + GG(A,B,C,D,es:bp[ 9*4],S21, 568446438); /* 25 */ + + GG(D,A,B,C,es:bp[14*4],S22,3275163606); /* 26 */ + + GG(C,D,A,B,es:bp[ 3*4],S23,4107603335); /* 27 */ + + GG(B,C,D,A,es:bp[ 8*4],S24,1163531501); /* 28 */ + + GG(A,B,C,D,es:bp[13*4],S21,2850285829); /* 29 */ + + GG(D,A,B,C,es:bp[ 2*4],S22,4243563512); /* 30 */ + + GG(C,D,A,B,es:bp[ 7*4],S23,1735328473); /* 31 */ + + GG(B,C,D,A,es:bp[12*4],S24,2368359562); /* 32 */ + + + +/* Round 3 */ + +#define S31 4 + +#define S32 11 + +#define S33 16 + +#define S34 23 + + HH(A,B,C,D,es:bp[ 5*4],S31,4294588738); /* 33 */ + + HH(D,A,B,C,es:bp[ 8*4],S32,2272392833); /* 34 */ + + HH(C,D,A,B,es:bp[11*4],S33,1839030562); /* 35 */ + + HH(B,C,D,A,es:bp[14*4],S34,4259657740); /* 36 */ + + HH(A,B,C,D,es:bp[ 1*4],S31,2763975236); /* 37 */ + + HH(D,A,B,C,es:bp[ 4*4],S32,1272893353); /* 38 */ + + HH(C,D,A,B,es:bp[ 7*4],S33,4139469664); /* 39 */ + + HH(B,C,D,A,es:bp[10*4],S34,3200236656); /* 40 */ + + HH(A,B,C,D,es:bp[13*4],S31, 681279174); /* 41 */ + + HH(D,A,B,C,es:bp[ 0*4],S32,3936430074); /* 42 */ + + HH(C,D,A,B,es:bp[ 3*4],S33,3572445317); /* 43 */ + + HH(B,C,D,A,es:bp[ 6*4],S34, 76029189); /* 44 */ + + HH(A,B,C,D,es:bp[ 9*4],S31,3654602809); /* 45 */ + + HH(D,A,B,C,es:bp[12*4],S32,3873151461); /* 46 */ + + HH(C,D,A,B,es:bp[15*4],S33, 530742520); /* 47 */ + + HH(B,C,D,A,es:bp[ 2*4],S34,3299628645); /* 48 */ + + + +/* Round 4 */ + +#define S41 6 + +#define S42 10 + +#define S43 15 + +#define S44 21 + + II(A,B,C,D,es:bp[ 0*4],S41,4096336452); /* 49 */ + + II(D,A,B,C,es:bp[ 7*4],S42,1126891415); /* 50 */ + + II(C,D,A,B,es:bp[14*4],S43,2878612391); /* 51 */ + + II(B,C,D,A,es:bp[ 5*4],S44,4237533241); /* 52 */ + + II(A,B,C,D,es:bp[12*4],S41,1700485571); /* 53 */ + + II(D,A,B,C,es:bp[ 3*4],S42,2399980690); /* 54 */ + + II(C,D,A,B,es:bp[10*4],S43,4293915773); /* 55 */ + + II(B,C,D,A,es:bp[ 1*4],S44,2240044497); /* 56 */ + + II(A,B,C,D,es:bp[ 8*4],S41,1873313359); /* 57 */ + + II(D,A,B,C,es:bp[15*4],S42,4264355552); /* 58 */ + + II(C,D,A,B,es:bp[ 6*4],S43,2734768916); /* 59 */ + + II(B,C,D,A,es:bp[13*4],S44,1309151649); /* 60 */ + + II(A,B,C,D,es:bp[ 4*4],S41,4149444226); /* 61 */ + + II(D,A,B,C,es:bp[11*4],S42,3174756917); /* 62 */ + + II(C,D,A,B,es:bp[ 2*4],S43, 718787259); /* 63 */ + + II(B,C,D,A,es:bp[ 9*4],S44,3951481745); /* 64 */ + + + + asm pop bp; /* We can address our args again */ + + asm if @DataSize NE 0 + + asm lds si,buf + + asm else + + asm mov si,buf; + + asm endif + + asm add dword ptr si[0*4],A; /* buf[0] += A */ + + asm add dword ptr si[1*4],B; /* buf[1] += B */ + + asm add dword ptr si[2*4],C; /* buf[2] += C */ + + asm add dword ptr si[3*4],D; /* buf[3] += D */ + + + + /* Restore caller's registers */ + + asm if @DataSize NE 0 + + asm pop ds + + asm endif + + + + asm pop es; + + asm pop di; + + asm pop si; + +} + +#endif /* CPU386 */ + + + +/* + + *********************************************************************** + + ** End of md5.c ** + + ******************************** (cut) ******************************** + + */ \ No newline at end of file diff --git a/source/EterPack/md5.h b/source/EterPack/md5.h new file mode 100644 index 0000000..9ed936f --- /dev/null +++ b/source/EterPack/md5.h @@ -0,0 +1,128 @@ +#ifndef __INC_ETERPACKLIB_MD5_H__ +#define __INC_ETERPACKLIB_MD5_H__ + +/* + + *********************************************************************** + + ** md5.h -- header file for implementation of MD5 ** + + ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** + + ** Created: 2/17/90 RLR ** + + ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** + + ** Revised (for MD5): RLR 4/27/91 ** + + ** -- G modified to have y&~z instead of y&z ** + + ** -- FF, GG, HH modified to add in last register done ** + + ** -- Access pattern: round 2 works mod 5, round 3 works mod 3 ** + + ** -- distinct additive constant for each step ** + + ** -- round 4 added, working mod 7 ** + + *********************************************************************** + + */ + +/* + + *********************************************************************** + + ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** + + ** ** + + ** License to copy and use this software is granted provided that ** + + ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** + + ** Digest Algorithm" in all material mentioning or referencing this ** + + ** software or this function. ** + + ** ** + + ** License is also granted to make and use derivative works ** + + ** provided that such works are identified as "derived from the RSA ** + + ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** + + ** material mentioning or referencing the derived work. ** + + ** ** + + ** RSA Data Security, Inc. makes no representations concerning ** + + ** either the merchantability of this software or the suitability ** + + ** of this software for any particular purpose. It is provided "as ** + + ** is" without express or implied warranty of any kind. ** + + ** ** + + ** These notices must be retained in any copies of any part of this ** + + ** documentation and/or software. ** + + *********************************************************************** + + */ + + + +/* typedef a 32-bit type */ + +typedef unsigned long int UINT4; + + + +/* Data structure for MD5 (Message-Digest) computation */ + +typedef struct { + + UINT4 i[2]; /* number of _bits_ handled mod 2^64 */ + + UINT4 buf[4]; /* scratch buffer */ + + unsigned char in[64]; /* input buffer */ + + unsigned char digest[16]; /* actual digest after MD5Final call */ + +} MD5_CTX; + + +#if defined (__cplusplus) +extern "C" { +#endif + +void MD5Init (MD5_CTX *); + +void MD5Update (MD5_CTX *,unsigned char *,unsigned int); + +void MD5Final (MD5_CTX *); + +void MD5Transform(UINT4 *,UINT4 *); + +#if defined (__cplusplus) +}; +#endif + +/* + + *********************************************************************** + + ** End of md5.h ** + + ******************************** (cut) ******************************** + + */ + + +#endif \ No newline at end of file diff --git a/source/EterPythonLib/PythonGraphic.cpp b/source/EterPythonLib/PythonGraphic.cpp new file mode 100644 index 0000000..01f40af --- /dev/null +++ b/source/EterPythonLib/PythonGraphic.cpp @@ -0,0 +1,624 @@ +#include "StdAfx.h" +#include "../eterLib/StateManager.h" +#include "../eterLib/JpegFile.h" +#include "PythonGraphic.h" + +bool g_isScreenShotKey = false; + +void CPythonGraphic::Destroy() +{ +} + +LPDIRECT3D8 CPythonGraphic::GetD3D() +{ + return ms_lpd3d; +} + +float CPythonGraphic::GetOrthoDepth() +{ + return m_fOrthoDepth; +} + +void CPythonGraphic::SetInterfaceRenderState() +{ + STATEMANAGER.SetTransform(D3DTS_PROJECTION, &ms_matIdentity); + STATEMANAGER.SetTransform(D3DTS_VIEW, &ms_matIdentity); + STATEMANAGER.SetTransform(D3DTS_WORLD, &ms_matIdentity); + + STATEMANAGER.SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_NONE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_NONE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_NONE); + + STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + + CPythonGraphic::Instance().SetBlendOperation(); + CPythonGraphic::Instance().SetOrtho2D(ms_iWidth, ms_iHeight, GetOrthoDepth()); + + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); +} + +void CPythonGraphic::SetGameRenderState() +{ + STATEMANAGER.SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + STATEMANAGER.SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + STATEMANAGER.SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); + + STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, TRUE); +} + +void CPythonGraphic::SetCursorPosition(int x, int y) +{ + CScreen::SetCursorPosition(x, y, ms_iWidth, ms_iHeight); +} + +void CPythonGraphic::SetOmniLight() +{ + // Set up a material + D3DMATERIAL8 Material; + Material.Ambient = D3DXCOLOR(0.3f, 0.3f, 0.3f, 1.0f); + Material.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); + Material.Emissive = D3DXCOLOR(0.1f, 0.1f, 0.1f, 1.0f); + STATEMANAGER.SetMaterial(&Material); + + D3DLIGHT8 Light; + Light.Type = D3DLIGHT_SPOT; + Light.Position = D3DXVECTOR3(50.0f, 150.0f, 350.0f); + Light.Direction = D3DXVECTOR3(-0.15f, -0.3f, -0.9f); + Light.Theta = D3DXToRadian(30.0f); + Light.Phi = D3DXToRadian(45.0f); + Light.Falloff = 1.0f; + Light.Attenuation0 = 0.0f; + Light.Attenuation1 = 0.005f; + Light.Attenuation2 = 0.0f; + Light.Diffuse.r = 1.0f; + Light.Diffuse.g = 1.0f; + Light.Diffuse.b = 1.0f; + Light.Diffuse.a = 1.0f; + Light.Ambient.r = 1.0f; + Light.Ambient.g = 1.0f; + Light.Ambient.b = 1.0f; + Light.Ambient.a = 1.0f; + Light.Range = 500.0f; + ms_lpd3dDevice->SetLight(0, &Light); + ms_lpd3dDevice->LightEnable(0, TRUE); + + Light.Type = D3DLIGHT_POINT; + Light.Position = D3DXVECTOR3(0.0f, 200.0f, 200.0f); + Light.Attenuation0 = 0.1f; + Light.Attenuation1 = 0.01f; + Light.Attenuation2 = 0.0f; + ms_lpd3dDevice->SetLight(1, &Light); + ms_lpd3dDevice->LightEnable(1, TRUE); +} + +void CPythonGraphic::SetViewport(float fx, float fy, float fWidth, float fHeight) +{ + ms_lpd3dDevice->GetViewport(&m_backupViewport); + + D3DVIEWPORT8 ViewPort; + ViewPort.X = fx; + ViewPort.Y = fy; + ViewPort.Width = fWidth; + ViewPort.Height = fHeight; + ViewPort.MinZ = 0.0f; + ViewPort.MaxZ = 1.0f; + if (FAILED( + ms_lpd3dDevice->SetViewport(&ViewPort) + )) + { + Tracef("CPythonGraphic::SetViewport(%d, %d, %d, %d) - Error", + ViewPort.X, ViewPort.Y, + ViewPort.Width, ViewPort.Height + ); + } +} + +void CPythonGraphic::RestoreViewport() +{ + ms_lpd3dDevice->SetViewport(&m_backupViewport); +} + +void CPythonGraphic::SetGamma(float fGammaFactor) +{ + D3DCAPS8 d3dCaps; + D3DGAMMARAMP NewRamp; + int ui, val; + + ms_lpd3dDevice->GetDeviceCaps(&d3dCaps); + + if (D3DCAPS2_FULLSCREENGAMMA != (d3dCaps.Caps2 & D3DCAPS2_FULLSCREENGAMMA)) + return; + + for (int i = 0; i < 256; ++i) + { + val = (int) (i * fGammaFactor * 255.0f); + ui = 0; + + if (val > 32767) + { + val = val - 32767; + ui = 1; + } + + if (val > 32767) + val = 32767; + + NewRamp.red[i] = (WORD) (val | (32768 * ui)); + NewRamp.green[i] = (WORD) (val | (32768 * ui)); + NewRamp.blue[i] = (WORD) (val | (32768 * ui)); + } + + ms_lpd3dDevice->SetGammaRamp(D3DSGR_NO_CALIBRATION, &NewRamp); +} + +void GenScreenShotTag(const char* src, DWORD crc32, char* leaf, size_t leafLen) +{ + const char* p = src; + const char* n = p; + while (n = strchr(p, '\\')) + p = n + 1; + + _snprintf(leaf, leafLen, "YMIR_METIN2:%s:0x%.8x", p, crc32); +} + +bool CPythonGraphic::SaveJPEG(const char * pszFileName, LPBYTE pbyBuffer, UINT uWidth, UINT uHeight) +{ + return jpeg_save(pbyBuffer, uWidth, uHeight, 100, pszFileName) != 0; +} + +bool CPythonGraphic::SaveScreenShot(const char * c_pszFileName) +{ + HRESULT hr; + LPDIRECT3DSURFACE8 lpSurface; + D3DSURFACE_DESC stSurfaceDesc; + + if (FAILED(hr = ms_lpd3dDevice->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &lpSurface))) + { + TraceError("Failed to get back buffer (0x%08x)", hr); + return false; + } + + if (FAILED(hr = lpSurface->GetDesc(&stSurfaceDesc))) + { + TraceError("Failed to get surface desc (0x%08x)", hr); + SAFE_RELEASE(lpSurface); + return false; + } + + UINT uWidth = stSurfaceDesc.Width; + UINT uHeight = stSurfaceDesc.Height; + + switch( stSurfaceDesc.Format ) { + case D3DFMT_R8G8B8 : + case D3DFMT_A8R8G8B8 : + case D3DFMT_X8R8G8B8 : + case D3DFMT_R5G6B5 : + case D3DFMT_X1R5G5B5 : + case D3DFMT_A1R5G5B5 : + break; + case D3DFMT_A4R4G4B4 : + case D3DFMT_R3G3B2 : + case D3DFMT_A8R3G3B2 : + case D3DFMT_X4R4G4B4 : + case D3DFMT_A2B10G10R10 : + TraceError("Unsupported BackBuffer Format(%d). Please contact Metin 2 Administrator.", stSurfaceDesc.Format); + SAFE_RELEASE(lpSurface); + return false; + } + + D3DLOCKED_RECT lockRect; + if (FAILED(hr = lpSurface->LockRect(&lockRect, NULL, D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK))) + { + TraceError("Failed to lock the surface (0x%08x)", hr); + SAFE_RELEASE(lpSurface); + return false; + } + + BYTE* pbyBuffer = new BYTE[uWidth * uHeight * 3]; + if (pbyBuffer == NULL) { + lpSurface->UnlockRect(); + lpSurface->Release(); + lpSurface = NULL; + TraceError("Failed to allocate screenshot buffer"); + return false; + } + BYTE* pbySource = (BYTE*) lockRect.pBits; + BYTE* pbyDestination = (BYTE*) pbyBuffer; + for(UINT y = 0; y < uHeight; ++y) { + BYTE *pRow = pbySource; + + switch( stSurfaceDesc.Format ) { + case D3DFMT_R8G8B8 : + for(UINT x = 0; x < uWidth; ++x) { + *pbyDestination++ = pRow[2]; // Blue + *pbyDestination++ = pRow[1]; // Green + *pbyDestination++ = pRow[0]; // Red + pRow += 3; + } + break; + case D3DFMT_A8R8G8B8 : + case D3DFMT_X8R8G8B8 : + for(UINT x = 0; x < uWidth; ++x) { + *pbyDestination++ = pRow[2]; // Blue + *pbyDestination++ = pRow[1]; // Green + *pbyDestination++ = pRow[0]; // Red + pRow += 4; + } + break; + case D3DFMT_R5G6B5 : + { + for(UINT x = 0; x < uWidth; ++x) { + UINT uColor = *((UINT *) pRow); + BYTE byBlue = (uColor >> 11) & 0x1F; + BYTE byGreen = (uColor >> 5) & 0x3F; + BYTE byRed = uColor & 0x1F; + + *pbyDestination++ = (byBlue << 3) | (byBlue >> 2); // Blue + *pbyDestination++ = (byGreen << 2) | (byGreen >> 2); // Green + *pbyDestination++ = (byRed << 3) | (byRed >> 2); // Red + pRow += 2; + } + } + break; + case D3DFMT_X1R5G5B5 : + case D3DFMT_A1R5G5B5 : + { + for(UINT x = 0; x < uWidth; ++x) { + UINT uColor = *((UINT *) pRow); + BYTE byBlue = (uColor >> 10) & 0x1F; + BYTE byGreen = (uColor >> 5) & 0x1F; + BYTE byRed = uColor & 0x1F; + + *pbyDestination++ = (byBlue << 3) | (byBlue >> 2); // Blue + *pbyDestination++ = (byGreen << 3) | (byGreen >> 2); // Green + *pbyDestination++ = (byRed << 3) | (byRed >> 2); // Red + pRow += 2; + } + } + break; + } + + // increase by one line + pbySource += lockRect.Pitch; + } + + if(lpSurface) { + lpSurface->UnlockRect(); + lpSurface->Release(); + lpSurface = NULL; + } + + bool bSaved = SaveJPEG(c_pszFileName, pbyBuffer, uWidth, uHeight); + + if(pbyBuffer) { + delete [] pbyBuffer; + pbyBuffer = NULL; + } + + if(bSaved == false) { + TraceError("Failed to save JPEG file. (%s, %d, %d)", c_pszFileName, uWidth, uHeight); + return false; + } + + if (g_isScreenShotKey) + { + FILE* srcFilePtr = fopen(c_pszFileName, "rb"); + if (srcFilePtr) + { + fseek(srcFilePtr, 0, SEEK_END); + size_t fileSize = ftell(srcFilePtr); + fseek(srcFilePtr, 0, SEEK_SET); + + char head[21]; + size_t tailSize = fileSize - sizeof(head); + char* tail = (char*)malloc(tailSize); + + fread(head, sizeof(head), 1, srcFilePtr); + fread(tail, tailSize, 1, srcFilePtr); + fclose(srcFilePtr); + + char imgDesc[64]; + GenScreenShotTag(c_pszFileName, GetCRC32(tail, tailSize), imgDesc, sizeof(imgDesc)); + + int imgDescLen = strlen(imgDesc) + 1; + + unsigned char exifHeader[] = { + 0xe1, + 0, // blockLen[1], + 0, // blockLen[0], + 0x45, + 0x78, + 0x69, + 0x66, + 0x0, + 0x0, + 0x49, + 0x49, + 0x2a, + 0x0, + 0x8, + 0x0, + 0x0, + 0x0, + 0x1, + 0x0, + 0xe, + 0x1, + 0x2, + 0x0, + static_cast(imgDescLen), // textLen[0], + 0, // textLen[1], + 0, // textLen[2], + 0, // textLen[3], + 0x1a, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + }; + + exifHeader[2] = sizeof(exifHeader) + imgDescLen; + + FILE* dstFilePtr = fopen(c_pszFileName, "wb"); + //FILE* dstFilePtr = fopen("temp.jpg", "wb"); + if (dstFilePtr) + { + fwrite(head, sizeof(head), 1, dstFilePtr); + fwrite(exifHeader, sizeof(exifHeader), 1, dstFilePtr); + fwrite(imgDesc, imgDescLen, 1, dstFilePtr); + fputc(0x00, dstFilePtr); + fputc(0xff, dstFilePtr); + fwrite(tail, tailSize, 1, dstFilePtr); + fclose(dstFilePtr); + } + + free(tail); + } + } + return true; +} + +void CPythonGraphic::PushState() +{ + TState curState; + + curState.matProj = ms_matProj; + curState.matView = ms_matView; + //STATEMANAGER.SaveTransform(D3DTS_WORLD, &m_SaveWorldMatrix); + + m_stateStack.push(curState); + //CCamera::Instance().PushParams(); +} + +void CPythonGraphic::PopState() +{ + if (m_stateStack.empty()) + { + assert(!"PythonGraphic::PopState StateStack is EMPTY"); + return; + } + + TState & rState = m_stateStack.top(); + + //STATEMANAGER.RestoreTransform(D3DTS_WORLD); + ms_matProj = rState.matProj; + ms_matView = rState.matView; + + UpdatePipeLineMatrix(); + + m_stateStack.pop(); + //CCamera::Instance().PopParams(); +} + +void CPythonGraphic::RenderImage(CGraphicImageInstance* pImageInstance, float x, float y) +{ + assert(pImageInstance != NULL); + + //SetColorRenderState(); + const CGraphicTexture * c_pTexture = pImageInstance->GetTexturePointer(); + + float width = (float) pImageInstance->GetWidth(); + float height = (float) pImageInstance->GetHeight(); + + c_pTexture->SetTextureStage(0); + + RenderTextureBox(x, + y, + x + width, + y + height, + 0.0f, + 0.5f / width, + 0.5f / height, + (width + 0.5f) / width, + (height + 0.5f) / height); +} + +void CPythonGraphic::RenderAlphaImage(CGraphicImageInstance* pImageInstance, float x, float y, float aLeft, float aRight) +{ + assert(pImageInstance != NULL); + + D3DXCOLOR DiffuseColor1 = D3DXCOLOR(1.0f, 1.0f, 1.0f, aLeft); + D3DXCOLOR DiffuseColor2 = D3DXCOLOR(1.0f, 1.0f, 1.0f, aRight); + + const CGraphicTexture * c_pTexture = pImageInstance->GetTexturePointer(); + + float width = (float) pImageInstance->GetWidth(); + float height = (float) pImageInstance->GetHeight(); + + c_pTexture->SetTextureStage(0); + + float sx = x; + float sy = y; + float ex = x + width; + float ey = y + height; + float z = 0.0f; + + float su = 0.0f; + float sv = 0.0f; + float eu = 1.0f; + float ev = 1.0f; + + TPDTVertex vertices[4]; + vertices[0].position = TPosition(sx, sy, z); + vertices[0].diffuse = DiffuseColor1; + vertices[0].texCoord = TTextureCoordinate(su, sv); + + vertices[1].position = TPosition(ex, sy, z); + vertices[1].diffuse = DiffuseColor2; + vertices[1].texCoord = TTextureCoordinate(eu, sv); + + vertices[2].position = TPosition(sx, ey, z); + vertices[2].diffuse = DiffuseColor1; + vertices[2].texCoord = TTextureCoordinate(su, ev); + + vertices[3].position = TPosition(ex, ey, z); + vertices[3].diffuse = DiffuseColor2; + vertices[3].texCoord = TTextureCoordinate(eu, ev); + + STATEMANAGER.SetVertexShader(ms_pntVS); + // 2004.11.18.myevan.DrawIndexPrimitiveUP -> DynamicVertexBuffer + CGraphicBase::SetDefaultIndexBuffer(DEFAULT_IB_FILL_RECT); + if (CGraphicBase::SetPDTStream(vertices, 4)) + STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 4, 0, 2); +} + +void CPythonGraphic::RenderCoolTimeBox(float fxCenter, float fyCenter, float fRadius, float fTime) +{ + if (fTime >= 1.0f) + return; + + fTime = max(0.0f, fTime); + + static D3DXCOLOR color = D3DXCOLOR(0.0f, 0.0f, 0.0f, 0.5f); + static WORD s_wBoxIndicies[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + static D3DXVECTOR2 s_v2BoxPos[8] = + { + D3DXVECTOR2( -1.0f, -1.0f ), + D3DXVECTOR2( -1.0f, 0.0f ), + D3DXVECTOR2( -1.0f, +1.0f ), + D3DXVECTOR2( 0.0f, +1.0f ), + D3DXVECTOR2( +1.0f, +1.0f ), + D3DXVECTOR2( +1.0f, 0.0f ), + D3DXVECTOR2( +1.0f, -1.0f ), + D3DXVECTOR2( 0.0f, -1.0f ), + }; + + int iTriCount = int(8 - 8.0f * fTime); + float fLastPercentage = (8 - 8.0f * fTime) - iTriCount; + + std::vector vertices; + TPDTVertex vertex; + vertex.position.x = fxCenter; + vertex.position.y = fyCenter; + vertex.position.z = 0.0f; + vertex.diffuse = color; + vertex.texCoord.x = 0.0f; + vertex.texCoord.x = 0.0f; + vertices.push_back(vertex); + vertex.position.x = fxCenter; + vertex.position.y = fyCenter - fRadius; + vertex.position.z = 0.0f; + vertex.diffuse = color; + vertex.texCoord.x = 0.0f; + vertex.texCoord.x = 0.0f; + vertices.push_back(vertex); + + for (int j = 0; j < iTriCount; ++j) + { + vertex.position.x = fxCenter + s_v2BoxPos[j].x * fRadius; + vertex.position.y = fyCenter + s_v2BoxPos[j].y * fRadius; + vertices.push_back(vertex); + } + + if (fLastPercentage > 0.0f) + { + D3DXVECTOR2 * pv2Pos; + D3DXVECTOR2 * pv2LastPos; + + assert((iTriCount-1+8)%8 >= 0 && (iTriCount-1+8)%8 < 8); + assert((iTriCount+8)%8 >= 0 && (iTriCount+8)%8 < 8); + pv2LastPos = &s_v2BoxPos[(iTriCount-1+8)%8]; + pv2Pos = &s_v2BoxPos[(iTriCount+8)%8]; + + vertex.position.x = fxCenter + ((pv2Pos->x-pv2LastPos->x) * fLastPercentage + pv2LastPos->x) * fRadius; + vertex.position.y = fyCenter + ((pv2Pos->y-pv2LastPos->y) * fLastPercentage + pv2LastPos->y) * fRadius; + vertices.push_back(vertex); + ++iTriCount; + } + + if (vertices.empty()) + return; + + if (SetPDTStream(&vertices[0], vertices.size())) + { + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + STATEMANAGER.DrawPrimitive(D3DPT_TRIANGLEFAN, 0, iTriCount); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAARG1); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAOP); + } +} + +long CPythonGraphic::GenerateColor(float r, float g, float b, float a) +{ + return GetColor(r, g, b, a); +} + +void CPythonGraphic::RenderDownButton(float sx, float sy, float ex, float ey) +{ + RenderBox2d(sx, sy, ex, ey); + + SetDiffuseColor(m_darkColor); + RenderLine2d(sx, sy, ex, sy); + RenderLine2d(sx, sy, sx, ey); + + SetDiffuseColor(m_lightColor); + RenderLine2d(sx, ey, ex, ey); + RenderLine2d(ex, sy, ex, ey); +} + +void CPythonGraphic::RenderUpButton(float sx, float sy, float ex, float ey) +{ + RenderBox2d(sx, sy, ex, ey); + + SetDiffuseColor(m_lightColor); + RenderLine2d(sx, sy, ex, sy); + RenderLine2d(sx, sy, sx, ey); + + SetDiffuseColor(m_darkColor); + RenderLine2d(sx, ey, ex, ey); + RenderLine2d(ex, sy, ex, ey); +} + +DWORD CPythonGraphic::GetAvailableMemory() +{ + return ms_lpd3dDevice->GetAvailableTextureMem(); +} + +CPythonGraphic::CPythonGraphic() +{ + m_lightColor = GetColor(1.0f, 1.0f, 1.0f); + m_darkColor = GetColor(0.0f, 0.0f, 0.0f); + + memset(&m_backupViewport, 0, sizeof(D3DVIEWPORT8)); + + m_fOrthoDepth = 1000.0f; +} + +CPythonGraphic::~CPythonGraphic() +{ + Tracef("Python Graphic Clear\n"); +} diff --git a/source/EterPythonLib/PythonGraphic.h b/source/EterPythonLib/PythonGraphic.h new file mode 100644 index 0000000..ae48ae7 --- /dev/null +++ b/source/EterPythonLib/PythonGraphic.h @@ -0,0 +1,68 @@ +#pragma once + +#include "../eterlib/GrpTextInstance.h" +#include "../eterlib/GrpMarkInstance.h" +#include "../eterlib/GrpImageInstance.h" +#include "../eterlib/GrpExpandedImageInstance.h" + +#include "../eterGrnLib/ThingInstance.h" + +class CPythonGraphic : public CScreen, public CSingleton +{ + public: + CPythonGraphic(); + virtual ~CPythonGraphic(); + + void Destroy(); + + void PushState(); + void PopState(); + + LPDIRECT3D8 GetD3D(); + + float GetOrthoDepth(); + void SetInterfaceRenderState(); + void SetGameRenderState(); + + void SetCursorPosition(int x, int y); + + void SetOmniLight(); + + void SetViewport(float fx, float fy, float fWidth, float fHeight); + void RestoreViewport(); + + long GenerateColor(float r, float g, float b, float a); + void RenderDownButton(float sx, float sy, float ex, float ey); + void RenderUpButton(float sx, float sy, float ex, float ey); + + void RenderImage(CGraphicImageInstance* pImageInstance, float x, float y); + void RenderAlphaImage(CGraphicImageInstance* pImageInstance, float x, float y, float aLeft, float aRight); + void RenderCoolTimeBox(float fxCenter, float fyCenter, float fRadius, float fTime); + + bool SaveJPEG(const char * pszFileName, LPBYTE pbyBuffer, UINT uWidth, UINT uHeight); + bool SaveScreenShot(const char *szFileName); + + DWORD GetAvailableMemory(); + void SetGamma(float fGammaFactor = 1.0f); + + protected: + typedef struct SState + { + D3DXMATRIX matView; + D3DXMATRIX matProj; + } TState; + + DWORD m_lightColor; + DWORD m_darkColor; + + protected: + std::stack m_stateStack; + + D3DXMATRIX m_SaveWorldMatrix; + + CCullingManager m_CullingManager; + + D3DVIEWPORT8 m_backupViewport; + + float m_fOrthoDepth; +}; \ No newline at end of file diff --git a/source/EterPythonLib/PythonGraphicImageModule.cpp b/source/EterPythonLib/PythonGraphicImageModule.cpp new file mode 100644 index 0000000..369fd89 --- /dev/null +++ b/source/EterPythonLib/PythonGraphicImageModule.cpp @@ -0,0 +1,310 @@ +#include "StdAfx.h" + +bool PyTuple_GetImageInstance(PyObject* poArgs, int pos, CGraphicImageInstance** ppRetImageInstance) +{ + int handle; + + if (!PyTuple_GetInteger(poArgs, pos, &handle)) + return false; + + if (!handle) + return false; + + *ppRetImageInstance = (CGraphicImageInstance*)handle; + return true; +} + +bool PyTuple_GetExpandedImageInstance(PyObject* poArgs, int pos, CGraphicExpandedImageInstance ** ppRetImageInstance) +{ + int handle; + + if (!PyTuple_GetInteger(poArgs, pos, &handle)) + return false; + + if (!handle) + return false; + + if (!((CGraphicImageInstance*)handle)->IsType(CGraphicExpandedImageInstance::Type())) + return false; + + *ppRetImageInstance = (CGraphicExpandedImageInstance*)handle; + + return true; +} + +PyObject* grpImageGenerate(PyObject * poSelf, PyObject* poArgs) +{ + char * szFileName; + + if (!PyTuple_GetString(poArgs, 0, &szFileName)) + return Py_BadArgument(); + + if (!*szFileName) + return Py_BuildValue("i", 0); + + CResource * pResource = CResourceManager::Instance().GetResourcePointer(szFileName); + + if (!pResource->IsType(CGraphicImage::Type())) + return Py_BuildException("Resource is not an image (filename: %s)", szFileName); + + CGraphicImageInstance * pImageInstance = CGraphicImageInstance::New(); + pImageInstance->SetImagePointer(static_cast(pResource)); + + if (pImageInstance->IsEmpty()) + return Py_BuildException("Cannot load image (filename: %s)", szFileName); + + return Py_BuildValue("i", pImageInstance); +} + +PyObject* grpImageGenerateExpanded(PyObject* poSelf, PyObject* poArgs) +{ + char * szFileName; + + if (!PyTuple_GetString(poArgs, 0, &szFileName)) + return Py_BadArgument(); + + if (strlen(szFileName) <= 0) + return Py_BuildValue("i", 0); + + CResource* pResource = CResourceManager::Instance().GetResourcePointer(szFileName); + + if (!pResource->IsType(CGraphicImage::Type())) + return Py_BuildException("Resource is not an image (filename: %s)", szFileName); + + CGraphicExpandedImageInstance * pImageInstance = CGraphicExpandedImageInstance::New(); + pImageInstance->SetImagePointer(static_cast(pResource)); + + if (pImageInstance->IsEmpty()) + return Py_BuildException("Cannot load image (filename: %s)", szFileName); + + return Py_BuildValue("i", pImageInstance); +} + +PyObject* grpImageGenerateFromHandle(PyObject * poSelf, PyObject* poArgs) +{ + int iHandle; + if (!PyTuple_GetInteger(poArgs, 0, &iHandle)) + return Py_BadArgument(); + + CGraphicImageInstance * pImageInstance = CGraphicImageInstance::New(); + pImageInstance->SetImagePointer((CGraphicImage *)iHandle); + + return Py_BuildValue("i", pImageInstance); +} + +PyObject* grpImageDelete(PyObject* poSelf, PyObject* poArgs) +{ + CGraphicImageInstance * pImageInstance; + + if (!PyTuple_GetImageInstance(poArgs, 0, &pImageInstance)) + return Py_BadArgument(); + + if (!pImageInstance) + return Py_BuildNone(); + + CGraphicImageInstance::Delete(pImageInstance); + + return Py_BuildNone(); +} + +PyObject* grpImageDeleteExpanded(PyObject* poSelf, PyObject* poArgs) +{ + CGraphicExpandedImageInstance * pExpandedImageInstance; + if (!PyTuple_GetExpandedImageInstance(poArgs, 0, &pExpandedImageInstance)) + return Py_BadArgument(); + + CGraphicExpandedImageInstance::Delete(pExpandedImageInstance); + return Py_BuildNone(); +} + +PyObject* grpImageSetFileName(PyObject* poSelf, PyObject* poArgs) +{ + CGraphicImageInstance * pImageInstance; + if (!PyTuple_GetImageInstance(poArgs, 0, &pImageInstance)) + return Py_BadArgument(); + + char * szFileName; + if (!PyTuple_GetString(poArgs, 1, &szFileName)) + return Py_BadArgument(); + + CResource * pResource = CResourceManager::Instance().GetResourcePointer(szFileName); + + if (!pResource->IsType(CGraphicImage::Type())) + return Py_BuildException("Resource is not an image (filename: %s)", szFileName); + + pImageInstance->SetImagePointer(static_cast(pResource)); + return Py_BuildNone(); +} + +PyObject* grpImageRender(PyObject* poSelf, PyObject* poArgs) +{ + CGraphicImageInstance* pImageInstance; + if (!PyTuple_GetImageInstance(poArgs, 0, &pImageInstance)) + return Py_BadArgument(); + + pImageInstance->Render(); + return Py_BuildNone(); +} + +PyObject * grpSetImagePosition(PyObject * poSelf, PyObject * poArgs) +{ + CGraphicImageInstance* pImageInstance; + if (!PyTuple_GetImageInstance(poArgs, 0, &pImageInstance)) + return Py_BadArgument(); + + float x; + if (!PyTuple_GetFloat(poArgs, 1, &x)) + return Py_BadArgument(); + + float y; + if (!PyTuple_GetFloat(poArgs, 2, &y)) + return Py_BadArgument(); + + pImageInstance->SetPosition(x, y); + return Py_BuildNone(); +} + +PyObject * grpSetImageOrigin(PyObject * poSelf, PyObject * poArgs) +{ + CGraphicExpandedImageInstance * pImageInstance; + if (!PyTuple_GetExpandedImageInstance(poArgs, 0, &pImageInstance)) + return Py_BadArgument(); + + float x; + if (!PyTuple_GetFloat(poArgs, 1, &x)) + return Py_BadArgument(); + float y; + if (!PyTuple_GetFloat(poArgs, 2, &y)) + return Py_BadArgument(); + + pImageInstance->SetOrigin(x, y); + return Py_BuildNone(); +} + +PyObject * grpSetImageRotation(PyObject * poSelf, PyObject * poArgs) +{ + CGraphicExpandedImageInstance * pImageInstance; + if (!PyTuple_GetExpandedImageInstance(poArgs, 0, &pImageInstance)) + return Py_BadArgument(); + + float Degree; + if (!PyTuple_GetFloat(poArgs, 1, &Degree)) + return Py_BadArgument(); + + pImageInstance->SetRotation(Degree); + return Py_BuildNone(); +} + +PyObject * grpSetImageScale(PyObject * poSelf, PyObject * poArgs) +{ + CGraphicExpandedImageInstance * pImageInstance; + if (!PyTuple_GetExpandedImageInstance(poArgs, 0, &pImageInstance)) + return Py_BadArgument(); + + float x; + if (!PyTuple_GetFloat(poArgs, 1, &x)) + return Py_BadArgument(); + float y; + if (!PyTuple_GetFloat(poArgs, 2, &y)) + return Py_BadArgument(); + + pImageInstance->SetScale(x, y); + return Py_BuildNone(); +} + +PyObject * grpSetRenderingRect(PyObject * poSelf, PyObject * poArgs) +{ + CGraphicExpandedImageInstance * pImageInstance; + if (!PyTuple_GetExpandedImageInstance(poArgs, 0, &pImageInstance)) + return Py_BadArgument(); + + float fLeft; + if (!PyTuple_GetFloat(poArgs, 1, &fLeft)) + return Py_BadArgument(); + float fTop; + if (!PyTuple_GetFloat(poArgs, 2, &fTop)) + return Py_BadArgument(); + float fRight; + if (!PyTuple_GetFloat(poArgs, 3, &fRight)) + return Py_BadArgument(); + float fBottom; + if (!PyTuple_GetFloat(poArgs, 4, &fBottom)) + return Py_BadArgument(); + + pImageInstance->SetRenderingRect(fLeft, fTop, fRight, fBottom); + return Py_BuildNone(); +} + +PyObject * grpSetImageDiffuseColor(PyObject * poSelf, PyObject * poArgs) +{ + CGraphicImageInstance* pImageInstance; + if (!PyTuple_GetImageInstance(poArgs, 0, &pImageInstance)) + return Py_BadArgument(); + + float r; + if (!PyTuple_GetFloat(poArgs, 1, &r)) + return Py_BadArgument(); + float g; + if (!PyTuple_GetFloat(poArgs, 2, &g)) + return Py_BadArgument(); + float b; + if (!PyTuple_GetFloat(poArgs, 3, &b)) + return Py_BadArgument(); + float a; + if (!PyTuple_GetFloat(poArgs, 4, &a)) + return Py_BadArgument(); + + pImageInstance->SetDiffuseColor(r, g, b, a); + return Py_BuildNone(); +} + +PyObject * grpGetWidth(PyObject * poSelf, PyObject * poArgs) +{ + CGraphicImageInstance * pImageInstance; + + if (!PyTuple_GetImageInstance(poArgs, 0, &pImageInstance)) + return Py_BadArgument(); + + if (pImageInstance->IsEmpty()) + return Py_BuildException("Image is empty"); + + return Py_BuildValue("i", pImageInstance->GetWidth()); +} + +PyObject * grpGetHeight(PyObject * poSelf, PyObject * poArgs) +{ + CGraphicImageInstance * pImageInstance; + + if (!PyTuple_GetImageInstance(poArgs, 0, &pImageInstance)) + return Py_BadArgument(); + + if (pImageInstance->IsEmpty()) + return Py_BuildException("Image is empty"); + + return Py_BuildValue("i", pImageInstance->GetHeight()); +} + +void initgrpImage() +{ + static PyMethodDef s_methods[] = + { + { "Render", grpImageRender, METH_VARARGS }, + { "SetPosition", grpSetImagePosition, METH_VARARGS }, + { "Generate", grpImageGenerate, METH_VARARGS }, + { "GenerateExpanded", grpImageGenerateExpanded, METH_VARARGS }, + { "GenerateFromHandle", grpImageGenerateFromHandle, METH_VARARGS }, + { "Delete", grpImageDelete, METH_VARARGS }, + { "DeleteExpanded", grpImageDeleteExpanded, METH_VARARGS }, + { "SetFileName", grpImageSetFileName, METH_VARARGS }, + { "SetOrigin", grpSetImageOrigin, METH_VARARGS }, + { "SetRotation", grpSetImageRotation, METH_VARARGS }, + { "SetScale", grpSetImageScale, METH_VARARGS }, + { "SetRenderingRect", grpSetRenderingRect, METH_VARARGS }, + { "SetDiffuseColor", grpSetImageDiffuseColor, METH_VARARGS }, + { "GetWidth", grpGetWidth, METH_VARARGS }, + { "GetHeight", grpGetHeight, METH_VARARGS }, + { NULL, NULL, NULL }, + }; + + Py_InitModule("grpImage", s_methods); +} diff --git a/source/EterPythonLib/PythonGraphicModule.cpp b/source/EterPythonLib/PythonGraphicModule.cpp new file mode 100644 index 0000000..ce62f66 --- /dev/null +++ b/source/EterPythonLib/PythonGraphicModule.cpp @@ -0,0 +1,1005 @@ +#include "StdAfx.h" +#include "../eterlib/Camera.h" +#include "../EterLib/TextBar.h" + +#include + +PyObject* grpCreateTextBar(PyObject* poSelf, PyObject* poArgs) +{ + int iWidth; + if (!PyTuple_GetInteger(poArgs, 0, &iWidth)) + return Py_BuildException(); + int iHeight; + if (!PyTuple_GetInteger(poArgs, 1, &iHeight)) + return Py_BuildException(); + + CTextBar * pTextBar = new CTextBar(12, false); + if (!pTextBar->Create(NULL, iWidth, iHeight)) + { + delete pTextBar; + return Py_BuildValue("i", NULL); + } + + return Py_BuildValue("i", pTextBar); +} + +PyObject* grpCreateBigTextBar(PyObject* poSelf, PyObject* poArgs) +{ + int iWidth; + if (!PyTuple_GetInteger(poArgs, 0, &iWidth)) + return Py_BuildException(); + int iHeight; + if (!PyTuple_GetInteger(poArgs, 1, &iHeight)) + return Py_BuildException(); + + int iFontSize; + if (!PyTuple_GetInteger(poArgs, 2, &iFontSize)) + return Py_BuildException(); + + CTextBar * pTextBar = new CTextBar(iFontSize, true); + if (!pTextBar->Create(NULL, iWidth, iHeight)) + { + delete pTextBar; + return Py_BuildValue("i", NULL); + } + + return Py_BuildValue("i", pTextBar); +} + +PyObject* grpDestroyTextBar(PyObject* poSelf, PyObject* poArgs) +{ + int iHandle; + if (!PyTuple_GetInteger(poArgs, 0, &iHandle)) + return Py_BuildException(); + + CTextBar * pTextBar = (CTextBar *)iHandle; + delete pTextBar; + + return Py_BuildNone(); +} + +PyObject* grpRenderTextBar(PyObject* poSelf, PyObject* poArgs) +{ + int iHandle; + if (!PyTuple_GetInteger(poArgs, 0, &iHandle)) + return Py_BuildException(); + int ix; + if (!PyTuple_GetInteger(poArgs, 1, &ix)) + return Py_BuildException(); + int iy; + if (!PyTuple_GetInteger(poArgs, 2, &iy)) + return Py_BuildException(); + + CTextBar * pTextBar = (CTextBar *)iHandle; + if (pTextBar) + pTextBar->Render(ix, iy); + + return Py_BuildNone(); +} + +PyObject* grpTextBarSetTextColor(PyObject* poSelf, PyObject* poArgs) +{ + int iHandle; + if (!PyTuple_GetInteger(poArgs, 0, &iHandle)) + return Py_BuildException(); + int r; + if (!PyTuple_GetInteger(poArgs, 1, &r)) + return Py_BuildException(); + int g; + if (!PyTuple_GetInteger(poArgs, 2, &g)) + return Py_BuildException(); + int b; + if (!PyTuple_GetInteger(poArgs, 3, &b)) + return Py_BuildException(); + + CTextBar * pTextBar = (CTextBar *)iHandle; + if (pTextBar) + pTextBar->SetTextColor(r, g, b); + + return Py_BuildNone(); +} + +PyObject* grpTextBarGetTextExtent(PyObject* poSelf, PyObject* poArgs) +{ + int iHandle; + if (!PyTuple_GetInteger(poArgs, 0, &iHandle)) + return Py_BuildException(); + char * szText; + if (!PyTuple_GetString(poArgs, 1, &szText)) + return Py_BuildException(); + + SIZE size = {0, 0}; + CTextBar * pTextBar = (CTextBar *)iHandle; + if (pTextBar) + pTextBar->GetTextExtent(szText, &size); + + return Py_BuildValue("ii", size.cx, size.cy); +} + +PyObject* grpTextBarTextOut(PyObject* poSelf, PyObject* poArgs) +{ + int iHandle; + if (!PyTuple_GetInteger(poArgs, 0, &iHandle)) + return Py_BuildException(); + int ix; + if (!PyTuple_GetInteger(poArgs, 1, &ix)) + return Py_BuildException(); + int iy; + if (!PyTuple_GetInteger(poArgs, 2, &iy)) + return Py_BuildException(); + char * szText; + if (!PyTuple_GetString(poArgs, 3, &szText)) + return Py_BuildException(); + + CTextBar * pTextBar = (CTextBar *)iHandle; + if (pTextBar) + pTextBar->TextOut(ix, iy, szText); + + return Py_BuildNone(); +} + +PyObject* grpClearTextBar(PyObject* poSelf, PyObject* poArgs) +{ + int iHandle; + if (!PyTuple_GetInteger(poArgs, 0, &iHandle)) + return Py_BuildException(); + + CTextBar * pTextBar = (CTextBar *)iHandle; + if (pTextBar) + pTextBar->ClearBar(); + + return Py_BuildNone(); +} + +PyObject* grpSetTextBarClipRect(PyObject* poSelf, PyObject* poArgs) +{ + int iHandle; + if (!PyTuple_GetInteger(poArgs, 0, &iHandle)) + return Py_BuildException(); + int isx; + if (!PyTuple_GetInteger(poArgs, 1, &isx)) + return Py_BuildException(); + int isy; + if (!PyTuple_GetInteger(poArgs, 2, &isy)) + return Py_BuildException(); + int iex; + if (!PyTuple_GetInteger(poArgs, 3, &iex)) + return Py_BuildException(); + int iey; + if (!PyTuple_GetInteger(poArgs, 4, &iey)) + return Py_BuildException(); + + CTextBar * pTextBar = (CTextBar *)iHandle; + if (pTextBar) + { + RECT rect; + rect.left = isx; + rect.top = isy; + rect.right = iex; + rect.bottom = iey; + + pTextBar->SetClipRect(rect); + } + + return Py_BuildNone(); +} + +PyObject* grpCulling(PyObject* poSelf, PyObject* poArgs) +{ + CCullingManager::Instance().Process(); + return Py_BuildNone(); +} + +PyObject* grpInitScreenEffect(PyObject* poSelf, PyObject* poArgs) +{ + CPythonGraphic::Instance().InitScreenEffect(); + return Py_BuildNone(); +} + +PyObject* grpClearDepthBuffer(PyObject* poSelf, PyObject* poArgs) +{ + CPythonGraphic::Instance().ClearDepthBuffer(); + return Py_BuildNone(); +} + +PyObject* grpPushState(PyObject* poSelf, PyObject* poArgs) +{ + CPythonGraphic::Instance().PushState(); + return Py_BuildNone(); +} + +PyObject* grpPopState(PyObject* poSelf, PyObject* poArgs) +{ + CPythonGraphic::Instance().PopState(); + return Py_BuildNone(); +} + +PyObject* grpPushMatrix(PyObject* poSelf, PyObject* poArgs) +{ + CPythonGraphic::Instance().PushMatrix(); + return Py_BuildNone(); +} + +PyObject* grpPopMatrix(PyObject* poSelf, PyObject* poArgs) +{ + CPythonGraphic::Instance().PopMatrix(); + return Py_BuildNone(); +} + +PyObject* grpTranslate(PyObject* poSelf, PyObject* poArgs) +{ + float x; + if (!PyTuple_GetFloat(poArgs, 0, &x)) + return Py_BuildException("grp.Translate:Wrong X"); + + float y; + if (!PyTuple_GetFloat(poArgs, 1, &y)) + return Py_BuildException("grp.Translate:Wrong Y"); + + float z; + if (!PyTuple_GetFloat(poArgs, 2, &z)) + return Py_BuildException("grp.Translate:Wrong Z"); + + CPythonGraphic::Instance().Translate(x, y, z); + + return Py_BuildNone(); +} + +PyObject* grpRotate(PyObject* poSelf, PyObject* poArgs) +{ + float Degree; + if (!PyTuple_GetFloat(poArgs, 0, &Degree)) + return Py_BuildException(); + + float x; + if (!PyTuple_GetFloat(poArgs, 1, &x)) + return Py_BuildException(); + + float y; + if (!PyTuple_GetFloat(poArgs, 2, &y)) + return Py_BuildException(); + + float z; + if (!PyTuple_GetFloat(poArgs, 3, &z)) + return Py_BuildException(); + + CPythonGraphic::Instance().Rotate(Degree, x, y, z); + + return Py_BuildNone(); +} + +PyObject * grpSetColorRenderState(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildNone(); +} + +PyObject* grpSetAroundCamera(PyObject* poSelf, PyObject* poArgs) +{ + float distance; + if (!PyTuple_GetFloat(poArgs, 0, &distance)) + return Py_BuildException(); + + float pitch; + if (!PyTuple_GetFloat(poArgs, 1, &pitch)) + return Py_BuildException(); + + float roll; + if (!PyTuple_GetFloat(poArgs, 2, &roll)) + return Py_BuildException(); + + float lookAtZ; + if (!PyTuple_GetFloat(poArgs, 3, &lookAtZ)) + return Py_BuildException(); + + CPythonGraphic::Instance().SetAroundCamera(distance, pitch, roll, lookAtZ); + return Py_BuildNone(); +} + +PyObject* grpSetPositionCamera(PyObject* poSelf, PyObject* poArgs) +{ + float fx; + if (!PyTuple_GetFloat(poArgs, 0, &fx)) + return Py_BuildException(); + + float fy; + if (!PyTuple_GetFloat(poArgs, 1, &fy)) + return Py_BuildException(); + + float fz; + if (!PyTuple_GetFloat(poArgs, 2, &fz)) + return Py_BuildException(); + + float distance; + if (!PyTuple_GetFloat(poArgs, 3, &distance)) + return Py_BuildException(); + + float pitch; + if (!PyTuple_GetFloat(poArgs, 4, &pitch)) + return Py_BuildException(); + + float roll; + if (!PyTuple_GetFloat(poArgs, 5, &roll)) + return Py_BuildException(); + + CPythonGraphic::Instance().SetPositionCamera(fx, fy, fz, distance, pitch, roll); + return Py_BuildNone(); +} + +PyObject* grpSetEyeCamera(PyObject* poSelf, PyObject* poArgs) +{ + float xEye; + if (!PyTuple_GetFloat(poArgs, 0, &xEye)) + return Py_BuildException(); + + float yEye; + if (!PyTuple_GetFloat(poArgs, 1, &yEye)) + return Py_BuildException(); + + float zEye; + if (!PyTuple_GetFloat(poArgs, 2, &zEye)) + return Py_BuildException(); + + float xCenter; + if (!PyTuple_GetFloat(poArgs, 3, &xCenter)) + return Py_BuildException(); + + float yCenter; + if (!PyTuple_GetFloat(poArgs, 4, &yCenter)) + return Py_BuildException(); + + float zCenter; + if (!PyTuple_GetFloat(poArgs, 5, &zCenter)) + return Py_BuildException(); + + float xUp; + if (!PyTuple_GetFloat(poArgs, 6, &xUp)) + return Py_BuildException(); + + float yUp; + if (!PyTuple_GetFloat(poArgs, 7, &yUp)) + return Py_BuildException(); + + float zUp; + if (!PyTuple_GetFloat(poArgs, 8, &zUp)) + return Py_BuildException(); + + CPythonGraphic::Instance().SetEyeCamera(xEye, yEye, zEye, xCenter, yCenter, zCenter, xUp, yUp, zUp); + return Py_BuildNone(); +} + + +PyObject* grpSetPerspective(PyObject* poSelf, PyObject* poArgs) +{ + float fov; + if (!PyTuple_GetFloat(poArgs, 0, &fov)) + return Py_BuildException(); + + float aspect; + if (!PyTuple_GetFloat(poArgs, 1, &aspect)) + return Py_BuildException(); + + float zNear; + if (!PyTuple_GetFloat(poArgs, 2, &zNear)) + return Py_BuildException(); + + float zFar; + if (!PyTuple_GetFloat(poArgs, 3, &zFar)) + return Py_BuildException(); + + CPythonGraphic::Instance().SetPerspective(fov, aspect, zNear, zFar); + return Py_BuildNone(); +} + + +PyObject* grpSetOrtho2D(PyObject* poSelf, PyObject* poArgs) +{ + float width; + if (!PyTuple_GetFloat(poArgs, 0, &width)) + return Py_BuildException(); + + float height; + if (!PyTuple_GetFloat(poArgs, 1, &height)) + return Py_BuildException(); + + float length; + if (!PyTuple_GetFloat(poArgs, 2, &length)) + return Py_BuildException(); + + CPythonGraphic::Instance().SetOrtho2D(width, height, length); + return Py_BuildNone(); +} + + +PyObject* grpSetOrtho3D(PyObject* poSelf, PyObject* poArgs) +{ + float width; + if (!PyTuple_GetFloat(poArgs, 0, &width)) + return Py_BuildException(); + + float height; + if (!PyTuple_GetFloat(poArgs, 1, &height)) + return Py_BuildException(); + + float zmin; + if (!PyTuple_GetFloat(poArgs, 2, &zmin)) + return Py_BuildException(); + + float zmax; + if (!PyTuple_GetFloat(poArgs, 3, &zmax)) + return Py_BuildException(); + + CPythonGraphic::Instance().SetOrtho3D(width, height, zmin, zmax); + return Py_BuildNone(); +} + + +PyObject* grpGenerateColor(PyObject* poSelf, PyObject* poArgs) +{ + float r; + if (!PyTuple_GetFloat(poArgs, 0, &r)) + return Py_BuildException(); + + float g; + if (!PyTuple_GetFloat(poArgs, 1, &g)) + return Py_BuildException(); + + float b; + if (!PyTuple_GetFloat(poArgs, 2, &b)) + return Py_BuildException(); + + float a; + if (!PyTuple_GetFloat(poArgs, 3, &a)) + return Py_BuildException(); + + return Py_BuildValue("l", CPythonGraphic::Instance().GenerateColor(r, g, b, a)); +} + +PyObject* grpSetColor(PyObject* poSelf, PyObject* poArgs) +{ + int color; + if (!PyTuple_GetInteger(poArgs, 0, &color)) + return Py_BuildException(); + + CPythonGraphic::Instance().SetDiffuseColor(DWORD(color)); + return Py_BuildNone(); +} + +PyObject* grpSetAlpha(PyObject* poSelf, PyObject* poArgs) +{ + float Alpha; + if (!PyTuple_GetFloat(poArgs, 0, &Alpha)) + return Py_BuildException(); + + //CPythonGraphic::Instance().SetAlpha(Alpha); + return Py_BuildNone(); +} + +PyObject* grpGetCursorPosition3d(PyObject * poSelf, PyObject * poArgs) +{ + float x, y, z; + CPythonGraphic::Instance().GetCursorPosition(&x, &y, &z); + return Py_BuildValue("(fff)", x, y, z); +} + +PyObject* grpSetCursorPosition(PyObject * poSelf, PyObject * poArgs) +{ + int ix; + if (!PyTuple_GetInteger(poArgs, 0, &ix)) + return Py_BuildException(); + int iy; + if (!PyTuple_GetInteger(poArgs, 1, &iy)) + return Py_BuildException(); + + CPythonGraphic::Instance().SetCursorPosition(ix, iy); + return Py_BuildNone(); +} + +PyObject* grpRenderLine(PyObject* poSelf, PyObject* poArgs) +{ + int x; + if (!PyTuple_GetInteger(poArgs, 0, &x)) + return Py_BuildException(); + + int y; + if (!PyTuple_GetInteger(poArgs, 1, &y)) + return Py_BuildException(); + + int width; + if (!PyTuple_GetInteger(poArgs, 2, &width)) + return Py_BuildException(); + + int height; + if (!PyTuple_GetInteger(poArgs, 3, &height)) + return Py_BuildException(); + + CPythonGraphic::Instance().RenderLine2d((float) x, (float) y, (float) x+width, (float) y+height); + return Py_BuildNone(); +} + +PyObject* grpRenderRoundBox(PyObject* poSelf, PyObject* poArgs) +{ + int x; + if (!PyTuple_GetInteger(poArgs, 0, &x)) + return Py_BuildException(); + + int y; + if (!PyTuple_GetInteger(poArgs, 1, &y)) + return Py_BuildException(); + + int width; + if (!PyTuple_GetInteger(poArgs, 2, &width)) + return Py_BuildException(); + + int height; + if (!PyTuple_GetInteger(poArgs, 3, &height)) + return Py_BuildException(); + + float fx = float(x); + float fy = float(y); + float fWidth = float(width); + float fHeight = float(height); + + CPythonGraphic::Instance().RenderLine2d(fx+2.0f, fy, fx+2.0f + (fWidth-3.0f), fy); + CPythonGraphic::Instance().RenderLine2d(fx+2.0f, fy+fHeight, fx+2.0f + (fWidth-3.0f), fy+fHeight); + CPythonGraphic::Instance().RenderLine2d(fx, fy+2.0f, fx, fy+2.0f + fHeight-4.0f); + CPythonGraphic::Instance().RenderLine2d(fx+fWidth, fy+1.0f, fx+fWidth, fy+1.0f + fHeight-3.0f); + CPythonGraphic::Instance().RenderLine2d(fx, fy+2.0f, fx+2.0f, fy); + CPythonGraphic::Instance().RenderLine2d(fx, fy+fHeight-2.0f, fx+2.0f, fy+fHeight); + CPythonGraphic::Instance().RenderLine2d(fx+fWidth-2.0f, fy, fx+fWidth, fy+2.0f); + CPythonGraphic::Instance().RenderLine2d(fx+fWidth-2.0f, fy+fHeight, fx+fWidth, fy+fHeight-2.0f); + return Py_BuildNone(); +} + +PyObject* grpRenderBox(PyObject* poSelf, PyObject* poArgs) +{ + int x; + if (!PyTuple_GetInteger(poArgs, 0, &x)) + return Py_BuildException(); + + int y; + if (!PyTuple_GetInteger(poArgs, 1, &y)) + return Py_BuildException(); + + int width; + if (!PyTuple_GetInteger(poArgs, 2, &width)) + return Py_BuildException(); + + int height; + if (!PyTuple_GetInteger(poArgs, 3, &height)) + return Py_BuildException(); + + CPythonGraphic::Instance().RenderBox2d((float) x, (float) y, (float) x+width, (float) y+height); + return Py_BuildNone(); +} + +PyObject* grpRenderBar(PyObject* poSelf, PyObject* poArgs) +{ + int x; + if (!PyTuple_GetInteger(poArgs, 0, &x)) + return Py_BuildException(); + + int y; + if (!PyTuple_GetInteger(poArgs, 1, &y)) + return Py_BuildException(); + + int width; + if (!PyTuple_GetInteger(poArgs, 2, &width)) + return Py_BuildException(); + + int height; + if (!PyTuple_GetInteger(poArgs, 3, &height)) + return Py_BuildException(); + + CPythonGraphic::Instance().RenderBar2d((float) x, (float) y, (float) x+width, (float) y+height); + return Py_BuildNone(); +} + +PyObject* grpRenderCube(PyObject* poSelf, PyObject* poArgs) +{ + float sx; + if (!PyTuple_GetFloat(poArgs, 0, &sx)) + return Py_BuildException(); + + float sy; + if (!PyTuple_GetFloat(poArgs, 1, &sy)) + return Py_BuildException(); + + float sz; + if (!PyTuple_GetFloat(poArgs, 2, &sz)) + return Py_BuildException(); + + float ex; + if (!PyTuple_GetFloat(poArgs, 3, &ex)) + return Py_BuildException(); + + float ey; + if (!PyTuple_GetFloat(poArgs, 4, &ey)) + return Py_BuildException(); + + float ez; + if (!PyTuple_GetFloat(poArgs, 5, &ez)) + return Py_BuildException(); + + CPythonGraphic::Instance().RenderCube(sx, sy, sz, ex, ey, ez); + return Py_BuildNone(); +} + +PyObject* grpRenderBar3d(PyObject* poSelf, PyObject* poArgs) +{ + int sx; + if (!PyTuple_GetInteger(poArgs, 0, &sx)) + return Py_BuildException(); + + int sy; + if (!PyTuple_GetInteger(poArgs, 1, &sy)) + return Py_BuildException(); + + int sz; + if (!PyTuple_GetInteger(poArgs, 2, &sz)) + return Py_BuildException(); + + int ex; + if (!PyTuple_GetInteger(poArgs, 3, &ex)) + return Py_BuildException(); + + int ey; + if (!PyTuple_GetInteger(poArgs, 4, &ey)) + return Py_BuildException(); + + int ez; + if (!PyTuple_GetInteger(poArgs, 5, &ez)) + return Py_BuildException(); + + CPythonGraphic::Instance().RenderBar3d(sx, sy, sz, ex, ey, ez); + return Py_BuildNone(); +} + +PyObject * grpRenderGradationBar(PyObject* poSelf, PyObject* poArgs) +{ + int x; + if (!PyTuple_GetInteger(poArgs, 0, &x)) + return Py_BadArgument(); + + int y; + if (!PyTuple_GetInteger(poArgs, 1, &y)) + return Py_BadArgument(); + + int width; + if (!PyTuple_GetInteger(poArgs, 2, &width)) + return Py_BadArgument(); + + int height; + if (!PyTuple_GetInteger(poArgs, 3, &height)) + return Py_BadArgument(); + + int iStartColor; + if (!PyTuple_GetInteger(poArgs, 4, &iStartColor)) + return Py_BadArgument(); + + int iEndColor; + if (!PyTuple_GetInteger(poArgs, 5, &iEndColor)) + return Py_BadArgument(); + + CPythonGraphic::Instance().RenderGradationBar2d((float)x, (float)y, (float)x+width, (float)y+height, iStartColor, iEndColor); + return Py_BuildNone(); +} + +PyObject* grpRenderDownButton(PyObject* poSelf, PyObject* poArgs) +{ + int x; + if (!PyTuple_GetInteger(poArgs, 0, &x)) + return Py_BuildException(); + + int y; + if (!PyTuple_GetInteger(poArgs, 1, &y)) + return Py_BuildException(); + + int width; + if (!PyTuple_GetInteger(poArgs, 2, &width)) + return Py_BuildException(); + + int height; + if (!PyTuple_GetInteger(poArgs, 3, &height)) + return Py_BuildException(); + + CPythonGraphic::Instance().RenderDownButton((float) x, (float) y, (float) x+width, (float) y+height); + return Py_BuildNone(); +} + +PyObject* grpRenderUpButton(PyObject* poSelf, PyObject* poArgs) +{ + int x; + if (!PyTuple_GetInteger(poArgs, 0, &x)) + return Py_BuildException(); + + int y; + if (!PyTuple_GetInteger(poArgs, 1, &y)) + return Py_BuildException(); + + int width; + if (!PyTuple_GetInteger(poArgs, 2, &width)) + return Py_BuildException(); + + int height; + if (!PyTuple_GetInteger(poArgs, 3, &height)) + return Py_BuildException(); + + CPythonGraphic::Instance().RenderUpButton((float) x, (float) y, (float) x+width, (float) y+height); + return Py_BuildNone(); +} + +PyObject* grpRenderBox3d(PyObject* poSelf, PyObject* poArgs) +{ + float sx; + if (!PyTuple_GetFloat(poArgs, 0, &sx)) + return Py_BuildException(); + + float sy; + if (!PyTuple_GetFloat(poArgs, 1, &sy)) + return Py_BuildException(); + + float sz; + if (!PyTuple_GetFloat(poArgs, 2, &sz)) + return Py_BuildException(); + + float ex; + if (!PyTuple_GetFloat(poArgs, 3, &ex)) + return Py_BuildException(); + + float ey; + if (!PyTuple_GetFloat(poArgs, 4, &ey)) + return Py_BuildException(); + + float ez; + if (!PyTuple_GetFloat(poArgs, 5, &ez)) + return Py_BuildException(); + + CPythonGraphic::Instance().RenderBox3d((float) sx, (float) sy, (float) sz, (float) ex, (float) ey, (float) ez); + return Py_BuildNone(); +} + +PyObject * grpSetClearColor(PyObject * poSelf, PyObject * poArgs) +{ + float fr; + if (!PyTuple_GetFloat(poArgs, 0, &fr)) + return Py_BuildException(); + + float fg; + if (!PyTuple_GetFloat(poArgs, 1, &fg)) + return Py_BuildException(); + + float fb; + if (!PyTuple_GetFloat(poArgs, 2, &fb)) + return Py_BuildException(); + + CPythonGraphic::Instance().SetClearColor(fr, fg, fb, 1.0f); + return Py_BuildNone(); +} + +PyObject * grpSetDiffuseColor(PyObject * poSelf, PyObject * poArgs) +{ + float r; + if (!PyTuple_GetFloat(poArgs, 0, &r)) + return Py_BuildException(); + + float g; + if (!PyTuple_GetFloat(poArgs, 1, &g)) + return Py_BuildException(); + + float b; + if (!PyTuple_GetFloat(poArgs, 2, &b)) + return Py_BuildException(); + + float a; + if (!PyTuple_GetFloat(poArgs, 3, &a)) + return Py_BuildException(); + + CPythonGraphic::Instance().SetDiffuseColor(r, g, b, a); + return Py_BuildNone(); +} + +PyObject * grpIdentity(PyObject * poSelf, PyObject * poArgs) +{ + CPythonGraphic::Instance().Identity(); + return Py_BuildNone(); +} + +PyObject * grpGetAvailableMemory(PyObject * poSelf, PyObject * poArgs) +{ + int iValue = CPythonGraphic::Instance().GetAvailableMemory(); + return Py_BuildValue("i", iValue); +} + +// SCREENSHOT_CWDSAVE +PyObject * grpSaveScreenShotToPath(PyObject * poSelf, PyObject * poArgs) +{ + char * szBasePath; + if (!PyTuple_GetString(poArgs, 0, &szBasePath)) + return Py_BuildException(); + + struct tm * tmNow; + time_t ct; + + ct = time(0); + tmNow = localtime(&ct); + + char szPath[MAX_PATH + 256]; + snprintf(szPath, sizeof(szPath), "%s%02d%02d_%02d%02d%02d.jpg", + szBasePath, + tmNow->tm_mon + 1, + tmNow->tm_mday, + tmNow->tm_hour, + tmNow->tm_min, + tmNow->tm_sec); + + BOOL bResult = CPythonGraphic::Instance().SaveScreenShot(szPath); + return Py_BuildValue("(is)", bResult, szPath); +} +// END_OF_SCREENSHOT_CWDSAVE + +PyObject * grpSaveScreenShot(PyObject * poSelf, PyObject * poArgs) +{ + struct tm * tmNow; + time_t ct; + + ct = time(0); + tmNow = localtime(&ct); + + char szPath[MAX_PATH + 256]; + SHGetSpecialFolderPath(NULL, szPath, CSIDL_PERSONAL, TRUE); + //GetTempPath(); + strcat(szPath, "\\METIN2\\"); + + if (-1 == _access(szPath, 0)) + if (!CreateDirectory(szPath, NULL)) + { + TraceError("Failed to create directory [%s]\n", szPath); + return Py_BuildValue("(is)", FALSE, ""); + } + + sprintf(szPath + strlen(szPath), "%02d%02d_%02d%02d%02d.jpg", + tmNow->tm_mon + 1, + tmNow->tm_mday, + tmNow->tm_hour, + tmNow->tm_min, + tmNow->tm_sec); + + BOOL bResult = CPythonGraphic::Instance().SaveScreenShot(szPath); + return Py_BuildValue("(is)", bResult, szPath); +} + +PyObject * grpSetGamma(PyObject * poSelf, PyObject * poArgs) +{ + float gamma; + + if (!PyTuple_GetFloat(poArgs, 0, &gamma)) + return Py_BuildException(); + + CPythonGraphic::Instance().SetGamma(gamma); + return Py_BuildNone(); +} + +PyObject * grpSetInterfaceRenderState(PyObject * poSelf, PyObject * poArgs) +{ + CPythonGraphic::Instance().SetInterfaceRenderState(); + return Py_BuildNone(); +} + +PyObject * grpSetGameRenderState(PyObject * poSelf, PyObject * poArgs) +{ + CPythonGraphic::Instance().SetGameRenderState(); + return Py_BuildNone(); +} + +PyObject * grpSetViewport(PyObject * poSelf, PyObject * poArgs) +{ + float fx; + if (!PyTuple_GetFloat(poArgs, 0, &fx)) + return Py_BuildException(); + float fy; + if (!PyTuple_GetFloat(poArgs, 1, &fy)) + return Py_BuildException(); + + float fWidth; + if (!PyTuple_GetFloat(poArgs, 2, &fWidth)) + return Py_BuildException(); + float fHeight; + if (!PyTuple_GetFloat(poArgs, 3, &fHeight)) + return Py_BuildException(); + + UINT uWidth; + UINT uHeight; + CPythonGraphic::Instance().GetBackBufferSize(&uWidth, &uHeight); + CPythonGraphic::Instance().SetViewport(fx*uWidth, fy*uHeight, fWidth*uWidth, fHeight*uHeight); + return Py_BuildNone(); +} + +PyObject * grpRestoreViewport(PyObject * poSelf, PyObject * poArgs) +{ + CPythonGraphic::Instance().RestoreViewport(); + return Py_BuildNone(); +} + +PyObject * grpSetOmniLight(PyObject * poSelf, PyObject * poArgs) +{ + CPythonGraphic::Instance().SetOmniLight(); + return Py_BuildNone(); +} + +PyObject * grpGetCameraPosition(PyObject * poSelf, PyObject * poArgs) +{ + D3DXVECTOR3 v3Eye = CCameraManager::Instance().GetCurrentCamera()->GetEye(); + return Py_BuildValue("fff", v3Eye.x, v3Eye.y, v3Eye.z); +} + +PyObject * grpGetTargetPosition(PyObject * poSelf, PyObject * poArgs) +{ + D3DXVECTOR3 v3Target = CCameraManager::Instance().GetCurrentCamera()->GetTarget(); + return Py_BuildValue("fff", v3Target.x, v3Target.y, v3Target.z); +} + +void initgrp() +{ + static PyMethodDef s_methods[] = + { + { "InitScreenEffect", grpInitScreenEffect, METH_VARARGS }, + { "Culling", grpCulling, METH_VARARGS }, + { "ClearDepthBuffer", grpClearDepthBuffer, METH_VARARGS }, + { "Identity", grpIdentity, METH_VARARGS }, + { "GenerateColor", grpGenerateColor, METH_VARARGS }, + { "PopState", grpPopState, METH_VARARGS }, + { "PushState", grpPushState, METH_VARARGS }, + { "PushMatrix", grpPushMatrix, METH_VARARGS }, + { "PopMatrix", grpPopMatrix, METH_VARARGS }, + { "Translate", grpTranslate, METH_VARARGS }, + { "Rotate", grpRotate, METH_VARARGS }, + { "SetColorRenderState", grpSetColorRenderState, METH_VARARGS }, + { "SetAroundCamera", grpSetAroundCamera, METH_VARARGS }, + { "SetPositionCamera", grpSetPositionCamera, METH_VARARGS }, + { "SetEyeCamera", grpSetEyeCamera, METH_VARARGS }, + { "SetPerspective", grpSetPerspective, METH_VARARGS }, + { "SetOrtho2d", grpSetOrtho2D, METH_VARARGS }, + { "SetOrtho3d", grpSetOrtho3D, METH_VARARGS }, + { "SetColor", grpSetColor, METH_VARARGS }, + { "SetAlpha", grpSetAlpha, METH_VARARGS }, + { "SetDiffuseColor", grpSetDiffuseColor, METH_VARARGS }, + { "SetClearColor", grpSetClearColor, METH_VARARGS }, + { "GetCursorPosition3d", grpGetCursorPosition3d, METH_VARARGS }, + { "SetCursorPosition", grpSetCursorPosition, METH_VARARGS }, + { "RenderLine", grpRenderLine, METH_VARARGS }, + { "RenderBox", grpRenderBox, METH_VARARGS }, + { "RenderRoundBox", grpRenderRoundBox, METH_VARARGS }, + { "RenderBox3d", grpRenderBox3d, METH_VARARGS }, + { "RenderBar", grpRenderBar, METH_VARARGS }, + { "RenderBar3d", grpRenderBar3d, METH_VARARGS }, + { "RenderGradationBar", grpRenderGradationBar, METH_VARARGS }, + { "RenderCube", grpRenderCube, METH_VARARGS }, + { "RenderDownButton", grpRenderDownButton, METH_VARARGS }, + { "RenderUpButton", grpRenderUpButton, METH_VARARGS }, + { "GetAvailableMemory", grpGetAvailableMemory, METH_VARARGS }, + { "SaveScreenShot", grpSaveScreenShot, METH_VARARGS }, + { "SaveScreenShotToPath", grpSaveScreenShotToPath, METH_VARARGS }, + { "SetGamma", grpSetGamma, METH_VARARGS }, + { "SetInterfaceRenderState", grpSetInterfaceRenderState, METH_VARARGS }, + { "SetGameRenderState", grpSetGameRenderState, METH_VARARGS }, + { "SetViewport", grpSetViewport, METH_VARARGS }, + { "RestoreViewport", grpRestoreViewport, METH_VARARGS }, + { "SetOmniLight", grpSetOmniLight, METH_VARARGS }, + { "GetCameraPosition", grpGetCameraPosition, METH_VARARGS }, + { "GetTargetPosition", grpGetTargetPosition, METH_VARARGS }, + + { "CreateTextBar", grpCreateTextBar, METH_VARARGS }, + { "CreateBigTextBar", grpCreateBigTextBar, METH_VARARGS }, + { "DestroyTextBar", grpDestroyTextBar, METH_VARARGS }, + { "RenderTextBar", grpRenderTextBar, METH_VARARGS }, + { "TextBarTextOut", grpTextBarTextOut, METH_VARARGS }, + { "TextBarSetTextColor", grpTextBarSetTextColor, METH_VARARGS }, + { "TextBarGetTextExtent", grpTextBarGetTextExtent, METH_VARARGS }, + { "ClearTextBar", grpClearTextBar, METH_VARARGS }, + { "SetTextBarClipRect", grpSetTextBarClipRect, METH_VARARGS }, + + { NULL, NULL, NULL }, + }; + + Py_InitModule("grp", s_methods); +} diff --git a/source/EterPythonLib/PythonGraphicTextModule.cpp b/source/EterPythonLib/PythonGraphicTextModule.cpp new file mode 100644 index 0000000..060bf0c --- /dev/null +++ b/source/EterPythonLib/PythonGraphicTextModule.cpp @@ -0,0 +1,426 @@ +#include "StdAfx.h" + +bool PyTuple_GetTextInstance(PyObject* poArgs, int pos, CGraphicTextInstance** ppTextInstance) +{ + int handle; + if (!PyTuple_GetInteger(poArgs, pos, &handle)) + return false; + + if (!handle) + return false; + + *ppTextInstance=(CGraphicTextInstance*)handle; + + return true; +} + +PyObject* grpTextGenerate(PyObject* poSelf, PyObject* poArgs) +{ + CGraphicTextInstance * pTextInstance = CGraphicTextInstance::New(); + return Py_BuildValue("i", pTextInstance); +} + +PyObject* grpTextDestroy(PyObject* poSelf, PyObject* poArgs) +{ + CGraphicTextInstance* pTextInstance; + if (!PyTuple_GetTextInstance(poArgs, 0, &pTextInstance)) + return Py_BuildException(); + + CGraphicTextInstance::Delete(pTextInstance); + return Py_BuildNone(); +} + +PyObject* grpTextGetSize(PyObject* poSelf, PyObject* poArgs) +{ + CGraphicTextInstance* pTextInstance; + if (!PyTuple_GetTextInstance(poArgs, 0, &pTextInstance)) + return Py_BuildException(); + + int width, height; + pTextInstance->GetTextSize(&width, &height); + return Py_BuildValue("(i, i)", width, height); +} + +PyObject* grpTextSetPosition(PyObject* poSelf, PyObject* poArgs) +{ + CGraphicTextInstance* pTextInstance; + if (!PyTuple_GetTextInstance(poArgs, 0, &pTextInstance)) + return Py_BuildException(); + + int ix; + if (!PyTuple_GetInteger(poArgs, 1, &ix)) + return Py_BuildException(); + int iy; + if (!PyTuple_GetInteger(poArgs, 2, &iy)) + return Py_BuildException(); + + pTextInstance->SetPosition((float) ix, (float) iy); + return Py_BuildNone(); +} + +PyObject* grpTextSetText(PyObject* poSelf, PyObject* poArgs) +{ + CGraphicTextInstance* pTextInstance; + if (!PyTuple_GetTextInstance(poArgs, 0, &pTextInstance)) + return Py_BuildException(); + + char* szText; + if (!PyTuple_GetString(poArgs, 1, &szText)) + return Py_BuildException(); + + pTextInstance->SetValue(szText); + return Py_BuildNone(); +} + +PyObject* grpTextSetSecret(PyObject* poSelf, PyObject* poArgs) +{ + CGraphicTextInstance* pTextInstance; + if (!PyTuple_GetTextInstance(poArgs, 0, &pTextInstance)) + return Py_BuildException(); + + bool bValue; + if (!PyTuple_GetBoolean(poArgs, 1, &bValue)) + return Py_BuildException(); + + pTextInstance->SetSecret(bValue); + return Py_BuildNone(); +} + +PyObject* grpTextOutline(PyObject* poSelf, PyObject* poArgs) +{ + CGraphicTextInstance* pTextInstance; + if (!PyTuple_GetTextInstance(poArgs, 0, &pTextInstance)) + return Py_BuildException(); + + bool bValue; + if (!PyTuple_GetBoolean(poArgs, 1, &bValue)) + return Py_BuildException(); + + pTextInstance->SetOutline(bValue); + return Py_BuildNone(); +} + +PyObject* grpTextGetText(PyObject* poSelf, PyObject* poArgs) +{ + CGraphicTextInstance* pTextInstance; + if (!PyTuple_GetTextInstance(poArgs, 0, &pTextInstance)) + return Py_BuildException(); + + return Py_BuildValue("s", pTextInstance->GetValueStringReference().c_str()); +} + +PyObject* grpTextSetFontName(PyObject* poSelf, PyObject* poArgs) +{ + CGraphicTextInstance* pTextInstance; + if (!PyTuple_GetTextInstance(poArgs, 0, &pTextInstance)) + return Py_BuildException(); + + char* szFontName; + if (!PyTuple_GetString(poArgs, 1, &szFontName)) + return Py_BuildException(); + + std::string stFontName = szFontName; + stFontName += ".fnt"; + + CResource* pResource = CResourceManager::Instance().GetResourcePointer(stFontName.c_str()); + pTextInstance->SetTextPointer(static_cast(pResource)); + return Py_BuildNone(); +} + +PyObject* grpTextSetFontColor(PyObject* poSelf, PyObject* poArgs) +{ + CGraphicTextInstance* pTextInstance; + if (!PyTuple_GetTextInstance(poArgs, 0, &pTextInstance)) + return Py_BuildException(); + + if (2 == PyTuple_Size(poArgs)) + { + int iColor; + if (!PyTuple_GetInteger(poArgs, 1, &iColor)) + return Py_BuildException(); + pTextInstance->SetColor(DWORD(iColor)); + } + else if (4 == PyTuple_Size(poArgs)) + { + float fRed; + if (!PyTuple_GetFloat(poArgs, 1, &fRed)) + return Py_BuildException(); + float fGreen; + if (!PyTuple_GetFloat(poArgs, 2, &fGreen)) + return Py_BuildException(); + float fBlue; + if (!PyTuple_GetFloat(poArgs, 3, &fBlue)) + return Py_BuildException(); + pTextInstance->SetColor(fRed, fGreen, fBlue); + } + else + { + return Py_BuildException(); + } + + return Py_BuildNone(); +} + +PyObject* grpTextSetOutLineColor(PyObject* poSelf, PyObject* poArgs) +{ + CGraphicTextInstance* pTextInstance; + if (!PyTuple_GetTextInstance(poArgs, 0, &pTextInstance)) + return Py_BuildException(); + + float fRed; + if (!PyTuple_GetFloat(poArgs, 1, &fRed)) + return Py_BuildException(); + float fGreen; + if (!PyTuple_GetFloat(poArgs, 2, &fGreen)) + return Py_BuildException(); + float fBlue; + if (!PyTuple_GetFloat(poArgs, 3, &fBlue)) + return Py_BuildException(); + + float fAlpha; + if (!PyTuple_GetFloat(poArgs, 4, &fAlpha)) + return Py_BuildException(); + + pTextInstance->SetOutLineColor(fRed, fGreen, fBlue, fAlpha); + return Py_BuildNone(); +} + + +PyObject* grpTextRender(PyObject* poSelf, PyObject* poArgs) +{ + CGraphicTextInstance* pTextInstance; + if (!PyTuple_GetTextInstance(poArgs, 0, &pTextInstance)) + return Py_BuildException(); + + pTextInstance->Render(); + return Py_BuildNone(); +} + +PyObject* grpTextUpdate(PyObject* poSelf, PyObject* poArgs) +{ + CGraphicTextInstance* pTextInstance; + if (!PyTuple_GetTextInstance(poArgs, 0, &pTextInstance)) + return Py_BuildException(); + + pTextInstance->Update(); + return Py_BuildNone(); +} + +PyObject* grpTextShowCursor(PyObject* poSelf, PyObject* poArgs) +{ + CGraphicTextInstance* pTextInstance; + if (!PyTuple_GetTextInstance(poArgs, 0, &pTextInstance)) + return Py_BuildException(); + + pTextInstance->ShowCursor(); + return Py_BuildNone(); +} + +PyObject* grpTextHideCursor(PyObject* poSelf, PyObject* poArgs) +{ + CGraphicTextInstance* pTextInstance; + if (!PyTuple_GetTextInstance(poArgs, 0, &pTextInstance)) + return Py_BuildException(); + + pTextInstance->HideCursor(); + return Py_BuildNone(); +} + +PyObject* grpSetHorizontalAlign(PyObject* poSelf, PyObject* poArgs) +{ + CGraphicTextInstance* pTextInstance; + if (!PyTuple_GetTextInstance(poArgs, 0, &pTextInstance)) + return Py_BuildException(); + + int iAlign; + if (!PyTuple_GetInteger(poArgs, 1, &iAlign)) + return Py_BuildException(); + + pTextInstance->SetHorizonalAlign(iAlign); + return Py_BuildNone(); +} + +PyObject* grpSetVerticalAlign(PyObject* poSelf, PyObject* poArgs) +{ + CGraphicTextInstance* pTextInstance; + if (!PyTuple_GetTextInstance(poArgs, 0, &pTextInstance)) + return Py_BuildException(); + + int iAlign; + if (!PyTuple_GetInteger(poArgs, 1, &iAlign)) + return Py_BuildException(); + + pTextInstance->SetVerticalAlign(iAlign); + return Py_BuildNone(); +} + +PyObject* grpSetMax(PyObject* poSelf, PyObject* poArgs) +{ + CGraphicTextInstance* pTextInstance; + if (!PyTuple_GetTextInstance(poArgs, 0, &pTextInstance)) + return Py_BuildException(); + + int iValue; + if (!PyTuple_GetInteger(poArgs, 1, &iValue)) + return Py_BuildException(); + + pTextInstance->SetMax(iValue); + return Py_BuildNone(); +} + +PyObject* grpGetSplitingTextLineCount(PyObject* poSelf, PyObject* poArgs) +{ + char * szText; + if (!PyTuple_GetString(poArgs, 0, &szText)) + return Py_BuildException(); + + int iLineLimitation; + if (!PyTuple_GetInteger(poArgs, 1, &iLineLimitation)) + return Py_BuildException(); + + int iPosition = 0; + int iLineCount = 0; + + for (DWORD i = 0; i < strlen(szText);) + { + if ('|' == szText[i]) + { + i += 1; + + // ڵ ٲ޵ǰ ٷ | + if (iPosition>0) + ++iLineCount; + + iPosition = 0; + continue; + } + + if (szText[i] & 0x80) + { + i += 2; + iPosition += 2; + } + else + { + i += 1; + iPosition += 1; + } + + if (iPosition >= iLineLimitation) + { + ++iLineCount; + iPosition = 0; + } + } + + if (iPosition > 0) + ++iLineCount; + + return Py_BuildValue("i", iLineCount); +} + +PyObject* grpGetSplitingTextLine(PyObject* poSelf, PyObject* poArgs) +{ + char * szText; + if (!PyTuple_GetString(poArgs, 0, &szText)) + return Py_BuildException(); + + int iLineLimitation; + if (!PyTuple_GetInteger(poArgs, 1, &iLineLimitation)) + return Py_BuildException(); + + int iGettingLine; + if (!PyTuple_GetInteger(poArgs, 2, &iGettingLine)) + return Py_BuildException(); + + std::string strLine = ""; + int iPosition = 0; + int iLineCount = 0; + + // 1 : ϰ ȵɱ -_-a + // 2 : .. +_+ + for (DWORD i = 0; i < strlen(szText);) + { + if ('|' == szText[i]) + { + i += 1; + + // ڵ ٲ޵ǰ ٷ | + if (iPosition>0) + ++iLineCount; + iPosition = 0; + continue; + } + + if (szText[i] & 0x80) + { + if (iLineCount == iGettingLine) + strLine.append(szText+i, 2); + + i += 2; + iPosition += 2; + } + else + { + if (iLineCount == iGettingLine) + strLine += szText[i]; + + i += 1; + iPosition += 1; + } + + if (iPosition >= iLineLimitation) + { + ++iLineCount; + iPosition = 0; + } + } + + return Py_BuildValue("s", strLine.c_str()); +} + +PyObject* grpTextPixelPositionToCharacterPosition(PyObject* poSelf, PyObject* poArgs) +{ + CGraphicTextInstance * pTextInstance; + if (!PyTuple_GetTextInstance(poArgs, 0, &pTextInstance)) + return Py_BuildException(); + + int iPixelPosition; + if (!PyTuple_GetInteger(poArgs, 1, &iPixelPosition)) + return Py_BuildException(); + + int iCharacterPosition = pTextInstance->PixelPositionToCharacterPosition(iPixelPosition); + + return Py_BuildValue("i", iCharacterPosition); +} + +void initgrpText() +{ + static PyMethodDef s_methods[] = + { + { "Update", grpTextUpdate, METH_VARARGS }, + { "Render", grpTextRender, METH_VARARGS }, + { "Generate", grpTextGenerate, METH_VARARGS }, + { "Destroy", grpTextDestroy, METH_VARARGS }, + { "SetFontName", grpTextSetFontName, METH_VARARGS }, + { "SetFontColor", grpTextSetFontColor, METH_VARARGS }, + { "SetOutLineColor", grpTextSetOutLineColor, METH_VARARGS }, + { "SetSecret", grpTextSetSecret, METH_VARARGS }, + { "SetOutline", grpTextOutline, METH_VARARGS }, + { "SetText", grpTextSetText, METH_VARARGS }, + { "GetText", grpTextGetText, METH_VARARGS }, + { "GetSize", grpTextGetSize, METH_VARARGS }, + { "SetPosition", grpTextSetPosition, METH_VARARGS }, + { "ShowCursor", grpTextShowCursor, METH_VARARGS }, + { "HideCursor", grpTextHideCursor, METH_VARARGS }, + { "SetHorizontalAlign", grpSetHorizontalAlign, METH_VARARGS }, + { "SetVerticalAlign", grpSetVerticalAlign, METH_VARARGS }, + { "SetMax", grpSetMax, METH_VARARGS }, + { "GetSplitingTextLineCount", grpGetSplitingTextLineCount, METH_VARARGS }, + { "GetSplitingTextLine", grpGetSplitingTextLine, METH_VARARGS }, + { "PixelPositionToCharacterPosition", grpTextPixelPositionToCharacterPosition, METH_VARARGS }, + { NULL, NULL, NULL }, + }; + + Py_InitModule("grpText", s_methods); +} diff --git a/source/EterPythonLib/PythonGraphicThingModule.cpp b/source/EterPythonLib/PythonGraphicThingModule.cpp new file mode 100644 index 0000000..805aa93 --- /dev/null +++ b/source/EterPythonLib/PythonGraphicThingModule.cpp @@ -0,0 +1,164 @@ +#include "StdAfx.h" + +bool PyTuple_GetThingInstance(PyObject* poArgs, int pos, CGraphicThingInstance** ppRetThingInstance) +{ + int handle; + if (!PyTuple_GetInteger(poArgs, pos, &handle)) + return false; + + if (!handle) + return false; + + *ppRetThingInstance = (CGraphicThingInstance*)handle; + return true; +} + +PyObject* grpThingGenerate(PyObject* poSelf, PyObject* poArgs) +{ + char * szFileName; + if (!PyTuple_GetString(poArgs, 0, &szFileName)) + return Py_BuildException(); + + if (strlen(szFileName) <= 0) + return Py_BuildValue("i", 0); + + CResource* pResource = CResourceManager::Instance().GetResourcePointer(szFileName); + + if (!pResource->IsType(CGraphicThing::Type())) + return Py_BuildException(); + + CGraphicThingInstance * pThingInstance = CGraphicThingInstance::New(); + pThingInstance->ReserveModelThing(1); + pThingInstance->ReserveModelInstance(1); + pThingInstance->RegisterModelThing(0, static_cast(pResource)); + pThingInstance->SetModelInstance(0, 0, 0); + return Py_BuildValue("i", pThingInstance); +} + +PyObject* grpThingDelete(PyObject* poSelf, PyObject* poArgs) +{ + CGraphicThingInstance * pThingInstance; + if (!PyTuple_GetThingInstance(poArgs, 0, &pThingInstance)) + return Py_BuildException(); + + CGraphicThingInstance::Delete(pThingInstance); + return Py_BuildNone(); +} + +PyObject* grpThingSetFileName(PyObject* poSelf, PyObject* poArgs) +{ + CGraphicThingInstance * pThingInstance; + if (!PyTuple_GetThingInstance(poArgs, 0, &pThingInstance)) + return Py_BuildException(); + + char* szFileName; + if (!PyTuple_GetString(poArgs, 1, &szFileName)) + return Py_BuildException(); + + CResource* pResource = CResourceManager::Instance().GetResourcePointer(szFileName); + + if (!pResource->IsType(CGraphicThing::Type())) + return Py_BuildException(); + + pThingInstance->Clear(); + pThingInstance->ReserveModelThing(1); + pThingInstance->ReserveModelInstance(1); + pThingInstance->RegisterModelThing(0, static_cast(pResource)); + pThingInstance->SetModelInstance(0, 0, 0); + return Py_BuildNone(); +} + +PyObject* grpThingRender(PyObject* poSelf, PyObject* poArgs) +{ + CGraphicThingInstance* pThingInstance; + if (!PyTuple_GetThingInstance(poArgs, 0, &pThingInstance)) + return Py_BuildException(); + + pThingInstance->Render(); + return Py_BuildNone(); +} + +PyObject* grpThingUpdate(PyObject* poSelf, PyObject* poArgs) +{ + CGraphicThingInstance* pThingInstance; + if (!PyTuple_GetThingInstance(poArgs, 0, &pThingInstance)) + return Py_BuildException(); + + pThingInstance->Update(); + pThingInstance->Deform(); + return Py_BuildNone(); +} + +PyObject * grpSetThingPosition(PyObject * poSelf, PyObject * poArgs) +{ + CGraphicThingInstance* pThingInstance; + if (!PyTuple_GetThingInstance(poArgs, 0, &pThingInstance)) + return Py_BuildException(); + + float x; + if (!PyTuple_GetFloat(poArgs, 1, &x)) + return Py_BuildException(); + + float y; + if (!PyTuple_GetFloat(poArgs, 2, &y)) + return Py_BuildException(); + + float z; + if (!PyTuple_GetFloat(poArgs, 3, &z)) + return Py_BuildException(); + + pThingInstance->SetPosition(x, y, z); + return Py_BuildNone(); +} + +PyObject * grpSetThingRotation(PyObject * poSelf, PyObject * poArgs) +{ + CGraphicThingInstance* pThingInstance; + if (!PyTuple_GetThingInstance(poArgs, 0, &pThingInstance)) + return Py_BuildException(); + + float fDegree; + if (!PyTuple_GetFloat(poArgs, 1, &fDegree)) + return Py_BuildException(); + + pThingInstance->SetRotation(fDegree); + return Py_BuildNone(); +} + +PyObject * grpSetThingScale(PyObject * poSelf, PyObject * poArgs) +{ + CGraphicThingInstance* pThingInstance; + if (!PyTuple_GetThingInstance(poArgs, 0, &pThingInstance)) + return Py_BuildException(); + + float x; + if (!PyTuple_GetFloat(poArgs, 1, &x)) + return Py_BuildException(); + float y; + if (!PyTuple_GetFloat(poArgs, 2, &y)) + return Py_BuildException(); + float z; + if (!PyTuple_GetFloat(poArgs, 3, &z)) + return Py_BuildException(); + + pThingInstance->SetScale(x, y, z); + return Py_BuildNone(); +} + +void initgrpThing() +{ + static PyMethodDef s_methods[] = + { + { "Update", grpThingUpdate, METH_VARARGS }, + { "Render", grpThingRender, METH_VARARGS }, + { "SetPosition", grpSetThingPosition, METH_VARARGS }, + { "Generate", grpThingGenerate, METH_VARARGS }, + { "Delete", grpThingDelete, METH_VARARGS }, + { "SetFileName", grpThingSetFileName, METH_VARARGS }, + { "SetRotation", grpSetThingRotation, METH_VARARGS }, + { "SetScale", grpSetThingScale, METH_VARARGS }, + { NULL, NULL, NULL }, + }; + + Py_InitModule("grpThing", s_methods); +} diff --git a/source/EterPythonLib/PythonGridSlotWindow.cpp b/source/EterPythonLib/PythonGridSlotWindow.cpp new file mode 100644 index 0000000..936aec1 --- /dev/null +++ b/source/EterPythonLib/PythonGridSlotWindow.cpp @@ -0,0 +1,400 @@ +#include "StdAfx.h" +#include "../eterBase/CRC32.h" +#include "PythonGridSlotWindow.h" + +using namespace UI; + +void CGridSlotWindow::OnRenderPickingSlot() +{ + if (!UI::CWindowManager::Instance().IsAttaching()) + return; + + BYTE byWidth, byHeight; + UI::CWindowManager::Instance().GetAttachingIconSize(&byWidth, &byHeight); + + std::list SlotList; + if (GetPickedSlotList(byWidth, byHeight, &SlotList)) + { + DWORD dwSlotNumber = UI::CWindowManager::Instance().GetAttachingSlotNumber(); + DWORD dwItemIndex = UI::CWindowManager::Instance().GetAttachingIndex(); + + // UseMode ̰.. + if (m_isUseMode) + { + // Pick .. + TSlot * pSlot = *SlotList.begin(); + TSlot * pCenterSlot; + if (GetSlotPointer(pSlot->dwCenterSlotNumber, &pCenterSlot)) + if (pCenterSlot->isItem) + { + if (m_isUsableItem) + CPythonGraphic::Instance().SetDiffuseColor(1.0f, 1.0f, 0.0f, 0.5f); + else + CPythonGraphic::Instance().SetDiffuseColor(1.0f, 0.0f, 0.0f, 0.5f); + + CPythonGraphic::Instance().RenderBar2d( m_rect.left + pCenterSlot->ixPosition, + m_rect.top + pCenterSlot->iyPosition, + m_rect.left + pCenterSlot->ixPosition + pCenterSlot->byxPlacedItemSize * ITEM_WIDTH, + m_rect.top + pCenterSlot->iyPosition + pCenterSlot->byyPlacedItemSize * ITEM_HEIGHT); + return; + } + } + + // ƴϸ ׳ ű + if (CheckMoving(dwSlotNumber, dwItemIndex, SlotList)) + CPythonGraphic::Instance().SetDiffuseColor(1.0f, 1.0f, 1.0f, 0.5f); + else + CPythonGraphic::Instance().SetDiffuseColor(1.0f, 0.0f, 0.0f, 0.5f); + + RECT Rect; + Rect.left = m_rect.right; + Rect.top = m_rect.bottom; + Rect.right = 0; + Rect.bottom = 0; + + for (std::list::iterator itor = SlotList.begin(); itor != SlotList.end(); ++itor) + { + TSlot * pSlot = *itor; + Rect.left = min(Rect.left, m_rect.left + pSlot->ixPosition); + Rect.top = min(Rect.top, m_rect.top + pSlot->iyPosition); + Rect.right = max(Rect.right, m_rect.left + pSlot->ixPosition + pSlot->byxPlacedItemSize*ITEM_WIDTH); + Rect.bottom = max(Rect.bottom, m_rect.top + pSlot->iyPosition + pSlot->byxPlacedItemSize*ITEM_HEIGHT); + } + + CPythonGraphic::Instance().RenderBar2d(Rect.left, Rect.top, Rect.right, Rect.bottom); + } +} + +BOOL CGridSlotWindow::GetPickedSlotPointer(TSlot ** ppSlot) +{ + if (!UI::CWindowManager::Instance().IsAttaching()) + return CSlotWindow::GetPickedSlotPointer(ppSlot); + + BYTE byWidth, byHeight; + UI::CWindowManager::Instance().GetAttachingIconSize(&byWidth, &byHeight); + + std::list SlotList; + if (!GetPickedSlotList(byWidth, byHeight, &SlotList)) + return FALSE; + + TSlot * pMinSlot = NULL; + //DWORD dwSlotNumber = UI::CWindowManager::Instance().GetAttachingSlotNumber(); + //DWORD dwAttachingItemIndex = UI::CWindowManager::Instance().GetAttachingIndex(); + + for (std::list::iterator itor = SlotList.begin(); itor != SlotList.end(); ++itor) + { + TSlot * pSlot = *itor; + + // NOTE : ̻ ͸ Ѵ. + // ڵ.. °? - [levites] + if (!pMinSlot) + { + pMinSlot = pSlot; + } + else + { + if (pSlot->dwSlotNumber < pMinSlot->dwSlotNumber) + { + pMinSlot = pSlot; + } + else + { + if (!pMinSlot->isItem && pSlot->isItem) + { + pMinSlot = pSlot; + } + } + } + } + + if (!pMinSlot) + { + return FALSE; + } + else + { + TSlot * pCenterSlot; + if (!GetSlotPointer(pMinSlot->dwCenterSlotNumber, &pCenterSlot)) + return FALSE; + + *ppSlot = pCenterSlot; + + // ִ ̰.. + if (UI::CWindowManager::Instance().IsAttaching()) + { + DWORD dwSlotNumber = UI::CWindowManager::Instance().GetAttachingSlotNumber(); + + if (dwSlotNumber == pCenterSlot->dwSlotNumber) + { + *ppSlot = pMinSlot; + } + } + } + + return TRUE; +} + +BOOL CGridSlotWindow::GetPickedSlotList(int iWidth, int iHeight, std::list * pSlotPointerList) +{ + long lx, ly; + GetMouseLocalPosition(lx, ly); + + if (lx < 0) + return FALSE; + if (ly < 0) + return FALSE; + if (lx >= GetWidth()) + return FALSE; + if (ly >= GetHeight()) + return FALSE; + + pSlotPointerList->clear(); + + int ix, iy; + if (GetPickedGridSlotPosition(lx, ly, &ix, &iy)) + { + int ixHalfStep = (iWidth / 2); + //int iyHalfStep = (iHeight / 2); + + int ixStart = int(ix) - int(ixHalfStep - (ixHalfStep % 2)); + int ixEnd = int(ix) + int(ixHalfStep); + + // FIXME : ã - [levites] + int iyStart = 0, iyEnd = 0; + + if (1 == iHeight) + { + iyStart = iy; + iyEnd = iy; + } + else if (2 == iHeight) + { + iyStart = iy; + iyEnd = iy + 1; + } + else if (3 == iHeight) + { + iyStart = iy - 1; + iyEnd = iy + 1; + } + + if (ixStart < 0) + { + ixEnd += -ixStart; + ixStart = 0; + } + + if (iyStart < 0) + { + iyEnd += -iyStart; + iyStart = 0; + } + + if (DWORD(ixEnd) >= m_dwxCount) + { + int ixTemporary = DWORD(ixEnd) - m_dwxCount + 1; + ixStart -= ixTemporary; + ixEnd -= ixTemporary; + } + + if (DWORD(iyEnd) >= m_dwyCount) + { + int iyTemporary = DWORD(iyEnd) - m_dwyCount + 1; + iyStart -= iyTemporary; + iyEnd -= iyTemporary; + } + + for (int i = ixStart; i <= ixEnd; ++i) + for (int j = iyStart; j <= iyEnd; ++j) + { + TSlot * pSlot; + if (GetGridSlotPointer(DWORD(i), DWORD(j), &pSlot)) + { + pSlotPointerList->push_back(pSlot); + } + } + + // Refine Scroll ó + if (m_isUseMode && 1 == pSlotPointerList->size()) + { + TSlot * pMainSlot = *pSlotPointerList->begin(); + + std::vector::iterator itor = m_SlotVector.begin(); + for (; itor != m_SlotVector.end(); ++itor) + { + TSlot * pSlot = *itor; + if (pSlot->dwCenterSlotNumber == pMainSlot->dwCenterSlotNumber) + if (pSlotPointerList->end() == std::find(pSlotPointerList->begin(), pSlotPointerList->end(), pSlot)) + { + pSlotPointerList->push_back(pSlot); + } + } + } + + if (!pSlotPointerList->empty()) + return TRUE; + } + + return FALSE; +} + +BOOL CGridSlotWindow::GetGridSlotPointer(int ix, int iy, TSlot ** ppSlot) +{ + DWORD dwSlotIndex = ix + iy*m_dwxCount; + if (dwSlotIndex >= m_SlotVector.size()) + return FALSE; + + *ppSlot = m_SlotVector[dwSlotIndex]; + + return TRUE; +} + +BOOL CGridSlotWindow::GetPickedGridSlotPosition(int ixLocal, int iyLocal, int * pix, int * piy) +{ + for (DWORD x = 0; x < m_dwxCount; ++x) + for (DWORD y = 0; y < m_dwyCount; ++y) + { + TSlot * pSlot; + if (!GetGridSlotPointer(x, y, &pSlot)) + continue; + + if (ixLocal >= pSlot->ixPosition) + if (iyLocal >= pSlot->iyPosition) + if (ixLocal <= pSlot->ixPosition + pSlot->ixCellSize) + if (iyLocal <= pSlot->iyPosition + pSlot->iyCellSize) + { + *pix = x; + *piy = y; + return TRUE; + } + } + + return FALSE; +} + +void CGridSlotWindow::ArrangeGridSlot(DWORD dwStartIndex, DWORD dwxCount, DWORD dwyCount, int ixSlotSize, int iySlotSize, int ixTemporarySize, int iyTemporarySize) +{ + Destroy(); + + m_dwxCount = dwxCount; + m_dwyCount = dwyCount; + + m_SlotVector.clear(); + m_SlotVector.resize(dwxCount*dwyCount); + + for (DWORD x = 0; x < dwxCount; ++x) + for (DWORD y = 0; y < dwyCount; ++y) + { + DWORD dwIndex = dwStartIndex + x + y * dwxCount; + int ixPosition = x * (ixSlotSize + ixTemporarySize); + int iyPosition = y * (iySlotSize + iyTemporarySize); + + AppendSlot(dwIndex, ixPosition, iyPosition, ixSlotSize, iySlotSize); + + m_SlotVector[x+y*dwxCount] = &(*m_SlotList.rbegin()); + } + + int iWidth = dwxCount * (ixSlotSize + ixTemporarySize); + int iHeight = dwyCount * (iySlotSize + iyTemporarySize); + SetSize(iWidth, iHeight); +} + +void CGridSlotWindow::OnRefreshSlot() +{ + DWORD x, y; + + for (x = 0; x < m_dwxCount; ++x) + for (y = 0; y < m_dwyCount; ++y) + { + TSlot * pSlot; + if (!GetGridSlotPointer(x, y, &pSlot)) + continue; + + pSlot->dwCenterSlotNumber = pSlot->dwSlotNumber; + } + + for (x = 0; x < m_dwxCount; ++x) + for (y = 0; y < m_dwyCount; ++y) + { + TSlot * pSlot; + if (!GetGridSlotPointer(x, y, &pSlot)) + continue; + + if (pSlot->isItem) + { + for (DWORD xSub = 0; xSub < pSlot->byxPlacedItemSize; ++xSub) + for (DWORD ySub = 0; ySub < pSlot->byyPlacedItemSize; ++ySub) + { + TSlot * pSubSlot; + if (!GetGridSlotPointer(x+xSub, y+ySub, &pSubSlot)) + continue; + + pSubSlot->dwCenterSlotNumber = pSlot->dwSlotNumber; + pSubSlot->dwItemIndex = pSlot->dwItemIndex; + } + } + else + { + pSlot->dwItemIndex = 0; + } + } +} + +BOOL CGridSlotWindow::CheckMoving(DWORD dwSlotNumber, DWORD dwItemIndex, const std::list & c_rSlotList) +{ + if (m_dwSlotStyle != SLOT_STYLE_PICK_UP) + return TRUE; + + for (std::list::const_iterator itor = c_rSlotList.begin(); itor != c_rSlotList.end(); ++itor) + { + TSlot * pSlot = *itor; + + if (dwSlotNumber != pSlot->dwCenterSlotNumber) // ڸ ƴ 쿡 + { + if (0 != pSlot->dwItemIndex || pSlot->dwCenterSlotNumber != pSlot->dwSlotNumber) // ְ + { + if (dwItemIndex != pSlot->dwItemIndex) // ٸ ̸ ű + return false; + } + } + } + + return true; +} + +void CGridSlotWindow::Destroy() +{ + CSlotWindow::Destroy(); + + m_SlotVector.clear(); + + __Initialize(); +} + +void CGridSlotWindow::__Initialize() +{ + m_dwxCount = 0; + m_dwyCount = 0; +} + +DWORD CGridSlotWindow::Type() +{ + static int s_Type = GetCRC32("CGridSlotWindow", strlen("CGridSlotWindow")); + return s_Type; +} + +BOOL CGridSlotWindow::OnIsType(DWORD dwType) +{ + if (CGridSlotWindow::Type() == dwType) + return TRUE; + + return CSlotWindow::OnIsType(dwType); +} + +CGridSlotWindow::CGridSlotWindow(PyObject * ppyObject) : CSlotWindow(ppyObject) +{ +} + +CGridSlotWindow::~CGridSlotWindow() +{ +} diff --git a/source/EterPythonLib/PythonGridSlotWindow.h b/source/EterPythonLib/PythonGridSlotWindow.h new file mode 100644 index 0000000..a07ba83 --- /dev/null +++ b/source/EterPythonLib/PythonGridSlotWindow.h @@ -0,0 +1,40 @@ +#pragma once + +#include "PythonSlotWindow.h" + +namespace UI +{ + class CGridSlotWindow : public CSlotWindow + { + public: + static DWORD Type(); + + public: + CGridSlotWindow(PyObject * ppyObject); + virtual ~CGridSlotWindow(); + + void Destroy(); + + void ArrangeGridSlot(DWORD dwStartIndex, DWORD dwxCount, DWORD dwyCount, int ixSlotSize, int iySlotSize, int ixTemporarySize, int iyTemporarySize); + + protected: + void __Initialize(); + + BOOL GetPickedSlotPointer(TSlot ** ppSlot); + BOOL GetPickedSlotList(int iWidth, int iHeight, std::list * pSlotPointerList); + BOOL GetGridSlotPointer(int ix, int iy, TSlot ** ppSlot); + BOOL GetPickedGridSlotPosition(int ixLocal, int iyLocal, int * pix, int * piy); + BOOL CheckMoving(DWORD dwSlotNumber, DWORD dwItemIndex, const std::list & c_rSlotList); + + BOOL OnIsType(DWORD dwType); + + void OnRefreshSlot(); + void OnRenderPickingSlot(); + + protected: + DWORD m_dwxCount; + DWORD m_dwyCount; + + std::vector m_SlotVector; + }; +}; diff --git a/source/EterPythonLib/PythonSlotWindow.cpp b/source/EterPythonLib/PythonSlotWindow.cpp new file mode 100644 index 0000000..528c2bb --- /dev/null +++ b/source/EterPythonLib/PythonSlotWindow.cpp @@ -0,0 +1,1442 @@ +#include "StdAfx.h" +#include "../eterBase/CRC32.h" +#include "../eterBase/Filename.h" +#include "PythonWindow.h" +#include "PythonSlotWindow.h" + +//#define __RENDER_SLOT_AREA__ + +using namespace UI; + +class UI::CSlotWindow::CSlotButton : public CButton +{ + public: + enum ESlotButtonType + { + SLOT_BUTTON_TYPE_PLUS, + SLOT_BUTTON_TYPE_COVER, + }; + + public: + CSlotButton(ESlotButtonType dwType, DWORD dwSlotNumber, CSlotWindow * pParent) : CButton(NULL) + { + m_dwSlotButtonType = dwType; + m_dwSlotNumber = dwSlotNumber; + m_pParent = pParent; + } + virtual ~CSlotButton() + { + } + + BOOL OnMouseLeftButtonDown() + { + if (!IsEnable()) + return TRUE; + if (UI::CWindowManager::Instance().IsAttaching()) + return TRUE; + + m_isPressed = TRUE; + Down(); + + return TRUE; + } + BOOL OnMouseLeftButtonUp() + { + if (!IsEnable()) + return TRUE; + if (!IsPressed()) + return TRUE; + + if (IsIn()) + SetCurrentVisual(&m_overVisual); + else + SetCurrentVisual(&m_upVisual); + + m_pParent->OnPressedSlotButton(m_dwSlotButtonType, m_dwSlotNumber); + + return TRUE; + } + + void OnMouseOverIn() + { + if (IsEnable()) + { + SetCurrentVisual(&m_overVisual); + } + m_pParent->OnOverInItem(m_dwSlotNumber); + } + void OnMouseOverOut() + { + if (IsEnable()) + { + SetUp(); + SetCurrentVisual(&m_upVisual); + } + m_pParent->OnOverOutItem(); + } + + protected: + ESlotButtonType m_dwSlotButtonType; + DWORD m_dwSlotNumber; + CSlotWindow * m_pParent; +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// + +class UI::CSlotWindow::CCoverButton : public CSlotButton +{ + public: + CCoverButton(ESlotButtonType dwType, DWORD dwSlotNumber, CSlotWindow * pParent) : CSlotButton(dwType, dwSlotNumber, pParent) + { + m_bLeftButtonEnable = TRUE; + m_bRightButtonEnable = TRUE; + } + virtual ~CCoverButton() + { + } + + void SetLeftButtonEnable(BOOL bEnable) + { + m_bLeftButtonEnable = bEnable; + } + void SetRightButtonEnable(BOOL bEnable) + { + m_bRightButtonEnable = bEnable; + } + + void OnRender() + { + } + + void RenderButton() + { + CButton::OnRender(); + } + + BOOL OnMouseLeftButtonDown() + { + if (!IsEnable()) + return TRUE; + if (m_bLeftButtonEnable) + { + CButton::OnMouseLeftButtonDown(); + } + else + { + m_pParent->OnMouseLeftButtonDown(); + } + return TRUE; + } + BOOL OnMouseLeftButtonUp() + { + if (!IsEnable()) + return TRUE; + if (m_bLeftButtonEnable) + { + CButton::OnMouseLeftButtonUp(); + m_pParent->OnMouseLeftButtonDown(); + } + else + { + m_pParent->OnMouseLeftButtonUp(); + } + return TRUE; + } + + BOOL OnMouseRightButtonDown() + { + if (!IsEnable()) + return TRUE; + if (m_bRightButtonEnable) + CButton::OnMouseLeftButtonDown(); + return TRUE; + } + BOOL OnMouseRightButtonUp() + { + if (!IsEnable()) + return TRUE; + m_pParent->OnMouseRightButtonDown(); + if (m_bRightButtonEnable) + CButton::OnMouseLeftButtonUp(); + return TRUE; + } + + protected: + BOOL m_bLeftButtonEnable; + BOOL m_bRightButtonEnable; +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// + +class UI::CSlotWindow::CCoolTimeFinishEffect : public CAniImageBox +{ + public: + CCoolTimeFinishEffect(CSlotWindow * pParent, DWORD dwSlotIndex) : CAniImageBox(NULL) + { + m_pParent = pParent; + m_dwSlotIndex = dwSlotIndex; + } + virtual ~CCoolTimeFinishEffect() + { + } + + void OnEndFrame() + { + ((CSlotWindow *)m_pParent)->ReserveDestroyCoolTimeFinishEffect(m_dwSlotIndex); + } + + protected: + DWORD m_dwSlotIndex; +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// + +// Set & Append + +void CSlotWindow::SetSlotType(DWORD dwType) +{ + m_dwSlotType = dwType; +} + +void CSlotWindow::SetSlotStyle(DWORD dwStyle) +{ + m_dwSlotStyle = dwStyle; +} + +void CSlotWindow::AppendSlot(DWORD dwIndex, int ixPosition, int iyPosition, int ixCellSize, int iyCellSize) +{ + TSlot Slot; + Slot.pInstance = NULL; + Slot.pNumberLine = NULL; + Slot.pCoverButton = NULL; + Slot.pSlotButton = NULL; + Slot.pSignImage = NULL; + Slot.pFinishCoolTimeEffect = NULL; + + ClearSlot(&Slot); + Slot.dwSlotNumber = dwIndex; + Slot.dwCenterSlotNumber = dwIndex; + Slot.ixPosition = ixPosition; + Slot.iyPosition = iyPosition; + Slot.ixCellSize = ixCellSize; + Slot.iyCellSize = iyCellSize; + m_SlotList.push_back(Slot); +} + +void CSlotWindow::SetCoverButton(DWORD dwIndex, const char * c_szUpImageName, const char * c_szOverImageName, const char * c_szDownImageName, const char * c_szDisableImageName, BOOL bLeftButtonEnable, BOOL bRightButtonEnable) +{ + TSlot * pSlot; + if (!GetSlotPointer(dwIndex, &pSlot)) + return; + + CCoverButton *& rpCoverButton = pSlot->pCoverButton; + + if (!rpCoverButton) + { + rpCoverButton = new CCoverButton(CSlotButton::SLOT_BUTTON_TYPE_COVER, pSlot->dwSlotNumber, this); + CWindowManager::Instance().SetParent(rpCoverButton, this); + } + + rpCoverButton->SetLeftButtonEnable(bLeftButtonEnable); + rpCoverButton->SetRightButtonEnable(bRightButtonEnable); + rpCoverButton->SetUpVisual(c_szUpImageName); + rpCoverButton->SetOverVisual(c_szOverImageName); + rpCoverButton->SetDownVisual(c_szDownImageName); + rpCoverButton->SetDisableVisual(c_szDisableImageName); + rpCoverButton->Enable(); + rpCoverButton->Show(); + + // NOTE : Cover ư Plus ư ӽ ڵ带.. + if (pSlot->pSlotButton) + { + SetTop(pSlot->pSlotButton); + } +} + +void CSlotWindow::EnableCoverButton(DWORD dwIndex) +{ + TSlot * pSlot; + if (!GetSlotPointer(dwIndex, &pSlot)) + return; + + if (!pSlot->pCoverButton) + return; + + pSlot->pCoverButton->Enable(); +} + +void CSlotWindow::DisableCoverButton(DWORD dwIndex) +{ + TSlot * pSlot; + if (!GetSlotPointer(dwIndex, &pSlot)) + return; + + if (!pSlot->pCoverButton) + return; + + pSlot->pCoverButton->Disable(); +} + +void CSlotWindow::SetAlwaysRenderCoverButton(DWORD dwIndex, bool bAlwaysRender) +{ + TSlot * pSlot; + if (!GetSlotPointer(dwIndex, &pSlot)) + return; + + if (bAlwaysRender) + SET_BIT(pSlot->dwState, SLOT_STATE_ALWAYS_RENDER_COVER); + else + REMOVE_BIT(pSlot->dwState, SLOT_STATE_ALWAYS_RENDER_COVER); +} + +void CSlotWindow::ShowSlotBaseImage(DWORD dwIndex) +{ + TSlot * pSlot; + if (!GetSlotPointer(dwIndex, &pSlot)) + return; + + pSlot->bRenderBaseSlotImage = true; +} + +void CSlotWindow::HideSlotBaseImage(DWORD dwIndex) +{ + TSlot * pSlot; + if (!GetSlotPointer(dwIndex, &pSlot)) + return; + + pSlot->bRenderBaseSlotImage = false; +} + +BOOL CSlotWindow::IsDisableCoverButton(DWORD dwIndex) +{ + TSlot * pSlot; + if (!GetSlotPointer(dwIndex, &pSlot)) + return FALSE; + + if (!pSlot->pCoverButton) + return FALSE; + + return pSlot->pCoverButton->IsDisable(); +} + +void CSlotWindow::SetSlotBaseImage(const char * c_szFileName, float fr, float fg, float fb, float fa) +{ + __CreateBaseImage(c_szFileName, fr, fg, fb, fa); +} + +void CSlotWindow::AppendSlotButton(const char * c_szUpImageName, const char * c_szOverImageName, const char * c_szDownImageName) +{ + for (TSlotListIterator itor = m_SlotList.begin(); itor != m_SlotList.end(); ++itor) + { + TSlot & rSlot = *itor; + CSlotButton *& rpSlotButton = rSlot.pSlotButton; + + if (!rpSlotButton) + { + rpSlotButton = new CSlotButton(CSlotButton::SLOT_BUTTON_TYPE_PLUS, rSlot.dwSlotNumber, this); + rpSlotButton->AddFlag(FLAG_FLOAT); + CWindowManager::Instance().SetParent(rpSlotButton, this); + } + + rpSlotButton->SetUpVisual(c_szUpImageName); + rpSlotButton->SetOverVisual(c_szOverImageName); + rpSlotButton->SetDownVisual(c_szDownImageName); + rpSlotButton->SetPosition(rSlot.ixPosition + 1, rSlot.iyPosition + 19); + rpSlotButton->Hide(); + } +} + +void CSlotWindow::AppendRequirementSignImage(const char * c_szImageName) +{ + for (TSlotListIterator itor = m_SlotList.begin(); itor != m_SlotList.end(); ++itor) + { + TSlot & rSlot = *itor; + CImageBox *& rpSignImage = rSlot.pSignImage; + + if (!rpSignImage) + { + rpSignImage = new CImageBox(NULL); + CWindowManager::Instance().SetParent(rpSignImage, this); + } + + rpSignImage->LoadImage(c_szImageName); + rpSignImage->Hide(); + } +} + +BOOL CSlotWindow::HasSlot(DWORD dwIndex) +{ + TSlot * pSlot; + if (!GetSlotPointer(dwIndex, &pSlot)) + return FALSE; + + return TRUE; +} + +void CSlotWindow::SetSlot(DWORD dwIndex, DWORD dwVirtualNumber, BYTE byWidth, BYTE byHeight, CGraphicImage * pImage, D3DXCOLOR& diffuseColor) +{ + TSlot * pSlot; + if (!GetSlotPointer(dwIndex, &pSlot)) + return; + + if (pSlot->isItem) + if (pSlot->dwItemIndex == dwVirtualNumber) + { + pSlot->dwState = 0; + pSlot->isItem = TRUE; + if (pImage && pSlot->pInstance) + { + pSlot->pInstance->SetImagePointer(pImage); + } + return; + } + + ClearSlot(pSlot); + pSlot->dwState = 0; + pSlot->isItem = TRUE; + pSlot->dwItemIndex = dwVirtualNumber; + + if (pImage) + { + assert(NULL == pSlot->pInstance); + pSlot->pInstance = CGraphicImageInstance::New(); + pSlot->pInstance->SetDiffuseColor(diffuseColor.r, diffuseColor.g, diffuseColor.b, diffuseColor.a); + pSlot->pInstance->SetImagePointer(pImage); + } + + pSlot->byxPlacedItemSize = byWidth; + pSlot->byyPlacedItemSize = byHeight; + + if (pSlot->pCoverButton) + { + pSlot->pCoverButton->Show(); + } +} + +void CSlotWindow::SetSlotCount(DWORD dwIndex, DWORD dwCount) +{ + TSlot * pSlot; + if (!GetSlotPointer(dwIndex, &pSlot)) + return; + + if (dwCount <= 0) + { + if (pSlot->pNumberLine) + { + delete pSlot->pNumberLine; + pSlot->pNumberLine = NULL; + } + } + else + { + char szCount[16+1]; + _snprintf(szCount, sizeof(szCount), "%d", dwCount); + + if (!pSlot->pNumberLine) + { + CNumberLine * pNumberLine = new UI::CNumberLine(this); + pNumberLine->SetHorizontalAlign(CNumberLine::HORIZONTAL_ALIGN_RIGHT); + pNumberLine->Show(); + pSlot->pNumberLine = pNumberLine; + } + + pSlot->pNumberLine->SetNumber(szCount); + } +} + +void CSlotWindow::SetSlotCountNew(DWORD dwIndex, DWORD dwGrade, DWORD dwCount) +{ + TSlot * pSlot; + if (!GetSlotPointer(dwIndex, &pSlot)) + return; + + if (dwCount <= 0) + { + if (pSlot->pNumberLine) + { + delete pSlot->pNumberLine; + pSlot->pNumberLine = NULL; + } + } + else + { + char szCount[16+1]; + + switch (dwGrade) + { + case 0: + _snprintf(szCount, sizeof(szCount), "%d", dwCount); + break; + case 1: + _snprintf(szCount, sizeof(szCount), "m%d", dwCount); + break; + case 2: + _snprintf(szCount, sizeof(szCount), "g%d", dwCount); + break; + case 3: + _snprintf(szCount, sizeof(szCount), "p"); + break; + } + + if (!pSlot->pNumberLine) + { + CNumberLine * pNumberLine = new UI::CNumberLine(this); + pNumberLine->SetHorizontalAlign(CNumberLine::HORIZONTAL_ALIGN_RIGHT); + pNumberLine->Show(); + pSlot->pNumberLine = pNumberLine; + } + + pSlot->pNumberLine->SetNumber(szCount); + } +} + +void CSlotWindow::SetSlotCoolTime(DWORD dwIndex, float fCoolTime, float fElapsedTime) +{ + TSlot * pSlot; + if (!GetSlotPointer(dwIndex, &pSlot)) + return; + + pSlot->fCoolTime = fCoolTime; + pSlot->fStartCoolTime = CTimer::Instance().GetCurrentSecond() - fElapsedTime; +} + +void CSlotWindow::ActivateSlot(DWORD dwIndex) +{ + TSlot * pSlot; + if (!GetSlotPointer(dwIndex, &pSlot)) + return; + + pSlot->bActive = TRUE; + + if (!m_pSlotActiveEffect) + { + __CreateSlotEnableEffect(); + } +} + +void CSlotWindow::DeactivateSlot(DWORD dwIndex) +{ + TSlot * pSlot; + if (!GetSlotPointer(dwIndex, &pSlot)) + return; + + pSlot->bActive = FALSE; +} + +void CSlotWindow::ClearSlot(DWORD dwIndex) +{ + TSlot * pSlot; + if (!GetSlotPointer(dwIndex, &pSlot)) + return; + + ClearSlot(pSlot); +} + +void CSlotWindow::ClearSlot(TSlot * pSlot) +{ + pSlot->bActive = FALSE; + pSlot->byxPlacedItemSize = 1; + pSlot->byyPlacedItemSize = 1; + + pSlot->isItem = FALSE; + pSlot->dwState = 0; + pSlot->fCoolTime = 0.0f; + pSlot->fStartCoolTime = 0.0f; + pSlot->dwCenterSlotNumber = 0xffffffff; + + pSlot->dwItemIndex = 0; + pSlot->bRenderBaseSlotImage = true; + + if (pSlot->pInstance) + { + CGraphicImageInstance::Delete(pSlot->pInstance); + pSlot->pInstance = NULL; + } + if (pSlot->pCoverButton) + { + pSlot->pCoverButton->Hide(); + } + if (pSlot->pSlotButton) + { + pSlot->pSlotButton->Hide(); + } + if (pSlot->pSignImage) + { + pSlot->pSignImage->Hide(); + } + if (pSlot->pFinishCoolTimeEffect) + { + pSlot->pFinishCoolTimeEffect->Hide(); + } +} + +void CSlotWindow::ClearAllSlot() +{ + Destroy(); +} + +void CSlotWindow::RefreshSlot() +{ + OnRefreshSlot(); + + // NOTE : Refresh ɶ ToolTip մϴ - [levites] + if (IsRendering()) + { + TSlot * pSlot; + if (GetPickedSlotPointer(&pSlot)) + { + OnOverOutItem(); + OnOverInItem(pSlot->dwSlotNumber); + } + } +} + +void CSlotWindow::OnRefreshSlot() +{ +} + +DWORD CSlotWindow::GetSlotCount() +{ + return m_SlotList.size(); +} + +void CSlotWindow::LockSlot(DWORD dwIndex) +{ + TSlot * pSlot; + if (!GetSlotPointer(dwIndex, &pSlot)) + return; + + pSlot->dwState |= SLOT_STATE_LOCK; +} +void CSlotWindow::UnlockSlot(DWORD dwIndex) +{ + TSlot * pSlot; + if (!GetSlotPointer(dwIndex, &pSlot)) + return; + + pSlot->dwState ^= SLOT_STATE_LOCK; +} +void CSlotWindow::SetCantUseSlot(DWORD dwIndex) +{ + TSlot * pSlot; + if (!GetSlotPointer(dwIndex, &pSlot)) + return; + + pSlot->dwState |= SLOT_STATE_CANT_USE; +} +void CSlotWindow::SetUseSlot(DWORD dwIndex) +{ + TSlot * pSlot; + if (!GetSlotPointer(dwIndex, &pSlot)) + return; + + pSlot->dwState ^= SLOT_STATE_CANT_USE; +} +void CSlotWindow::EnableSlot(DWORD dwIndex) +{ + TSlot * pSlot; + if (!GetSlotPointer(dwIndex, &pSlot)) + return; + + REMOVE_BIT(pSlot->dwState, SLOT_STATE_DISABLE); + //pSlot->dwState |= SLOT_STATE_DISABLE; +} +void CSlotWindow::DisableSlot(DWORD dwIndex) +{ + TSlot * pSlot; + if (!GetSlotPointer(dwIndex, &pSlot)) + return; + SET_BIT(pSlot->dwState, SLOT_STATE_DISABLE); + //pSlot->dwState ^= SLOT_STATE_DISABLE; +} + +// Select + +void CSlotWindow::SelectSlot(DWORD dwSelectingIndex) +{ + std::list::iterator itor = m_dwSelectedSlotIndexList.begin(); + for (; itor != m_dwSelectedSlotIndexList.end();) + { + if (dwSelectingIndex == *itor) + { + itor = m_dwSelectedSlotIndexList.erase(itor); + return; + } + else + { + ++itor; + } + } + + TSlot * pSlot; + if (GetSlotPointer(dwSelectingIndex, &pSlot)) + { + if (!pSlot->isItem) + return; + + m_dwSelectedSlotIndexList.push_back(dwSelectingIndex); + } +} + +BOOL CSlotWindow::isSelectedSlot(DWORD dwIndex) +{ + std::list::iterator itor = m_dwSelectedSlotIndexList.begin(); + for (; itor != m_dwSelectedSlotIndexList.end(); ++itor) + { + if (dwIndex == *itor) + return TRUE; + } + + return FALSE; +} + +void CSlotWindow::ClearSelected() +{ + m_dwSelectedSlotIndexList.clear(); +} + +DWORD CSlotWindow::GetSelectedSlotCount() +{ + return m_dwSelectedSlotIndexList.size(); +} + +DWORD CSlotWindow::GetSelectedSlotNumber(DWORD dwIndex) +{ + if (dwIndex >= m_dwSelectedSlotIndexList.size()) + return DWORD(-1); + + DWORD dwCount = 0; + std::list::iterator itor = m_dwSelectedSlotIndexList.begin(); + for (; itor != m_dwSelectedSlotIndexList.end(); ++itor) + { + if (dwIndex == dwCount) + break; + + ++dwCount; + } + + return *itor; +} + +void CSlotWindow::ShowSlotButton(DWORD dwSlotNumber) +{ + TSlot * pSlot; + if (!GetSlotPointer(dwSlotNumber, &pSlot)) + return; + + if (pSlot->pSlotButton) + { + pSlot->pSlotButton->Show(); + } +} + +void CSlotWindow::HideAllSlotButton() +{ + for (TSlotListIterator itor = m_SlotList.begin(); itor != m_SlotList.end(); ++itor) + { + TSlot & rSlot = *itor; + + if (rSlot.pSlotButton) + { + rSlot.pSlotButton->Hide(); + } + } +} + +void CSlotWindow::ShowRequirementSign(DWORD dwSlotNumber) +{ + TSlot * pSlot; + if (!GetSlotPointer(dwSlotNumber, &pSlot)) + return; + + if (!pSlot->pSignImage) + return; + + pSlot->pSignImage->Show(); +} + +void CSlotWindow::HideRequirementSign(DWORD dwSlotNumber) +{ + TSlot * pSlot; + if (!GetSlotPointer(dwSlotNumber, &pSlot)) + return; + + if (!pSlot->pSignImage) + return; + + pSlot->pSignImage->Hide(); +} + +// Event + +BOOL CSlotWindow::OnMouseLeftButtonDown() +{ + TSlot * pSlot; + if (!GetPickedSlotPointer(&pSlot)) + { + UI::CWindowManager::Instance().DeattachIcon(); + return TRUE; + } + + if (pSlot->isItem && !(pSlot->dwState & SLOT_STATE_LOCK)) + { + OnSelectItemSlot(pSlot->dwSlotNumber); + } + else + { + OnSelectEmptySlot(pSlot->dwSlotNumber); + } + + return TRUE; +} + +BOOL CSlotWindow::OnMouseLeftButtonUp() +{ + if (UI::CWindowManager::Instance().IsAttaching()) + if (UI::CWindowManager::Instance().IsDragging()) + if (IsIn()) + { + UI::CWindow * pWin = UI::CWindowManager::Instance().GetPointWindow(); + + if (pWin) + if (pWin->IsType(UI::CSlotWindow::Type())) + { + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + + TSlot * pSlot; + if (!pSlotWin->GetPickedSlotPointer(&pSlot)) + { + UI::CWindowManager::Instance().DeattachIcon(); + return TRUE; + } + + if (pSlot->isItem) + pSlotWin->OnSelectItemSlot(pSlot->dwSlotNumber); + else + pSlotWin->OnSelectEmptySlot(pSlot->dwSlotNumber); + + return TRUE; + } + + return FALSE; + } + + return FALSE; +} + +BOOL CSlotWindow::OnMouseRightButtonDown() +{ + TSlot * pSlot; + if (!GetPickedSlotPointer(&pSlot)) + return TRUE; + + if (pSlot->isItem) + { + OnUnselectItemSlot(pSlot->dwSlotNumber); + } + else + { + OnUnselectEmptySlot(pSlot->dwSlotNumber); + } + + return TRUE; +} + +BOOL CSlotWindow::OnMouseLeftButtonDoubleClick() +{ + OnUseSlot(); + + return TRUE; +} + +void CSlotWindow::OnMouseOverOut() +{ + OnOverOutItem(); +} + +void CSlotWindow::OnMouseOver() +{ + // FIXME : 츦 巡 ϴ ߿ SetTop Ǿ Capture Ǯ . װ ڵ. + // ٺ ذå ãƾ - [levites] +// if (UI::CWindowManager::Instance().IsCapture()) +// if (!UI::CWindowManager::Instance().IsAttaching()) +// return; + + CWindow * pPointWindow = UI::CWindowManager::Instance().GetPointWindow(); + if (this == pPointWindow) + { + TSlot * pSlot; + if (GetPickedSlotPointer(&pSlot)) + { + if (OnOverInItem(pSlot->dwSlotNumber)) + return; + } + } + + OnOverOutItem(); +} + +void CSlotWindow::OnSelectEmptySlot(int iSlotNumber) +{ + PyCallClassMemberFunc(m_poHandler, "OnSelectEmptySlot", Py_BuildValue("(i)", iSlotNumber)); +} +void CSlotWindow::OnSelectItemSlot(int iSlotNumber) +{ +// OnOverOutItem(); + PyCallClassMemberFunc(m_poHandler, "OnSelectItemSlot", Py_BuildValue("(i)", iSlotNumber)); + + if (UI::CWindowManager::Instance().IsAttaching()) + OnOverOutItem(); +} +void CSlotWindow::OnUnselectEmptySlot(int iSlotNumber) +{ + PyCallClassMemberFunc(m_poHandler, "OnUnselectEmptySlot", Py_BuildValue("(i)", iSlotNumber)); +} +void CSlotWindow::OnUnselectItemSlot(int iSlotNumber) +{ + PyCallClassMemberFunc(m_poHandler, "OnUnselectItemSlot", Py_BuildValue("(i)", iSlotNumber)); +} +void CSlotWindow::OnUseSlot() +{ + TSlot * pSlot; + if (GetPickedSlotPointer(&pSlot)) + if (pSlot->isItem) + { + PyCallClassMemberFunc(m_poHandler, "OnUseSlot", Py_BuildValue("(i)", pSlot->dwSlotNumber)); + } +} + +BOOL CSlotWindow::OnOverInItem(DWORD dwSlotNumber) +{ + TSlot * pSlot; + if (!GetSlotPointer(dwSlotNumber, &pSlot)) + return FALSE; + + if (!pSlot->isItem) + return FALSE; + + if (pSlot->dwSlotNumber == m_dwToolTipSlotNumber) + return TRUE; + + m_dwToolTipSlotNumber = dwSlotNumber; + PyCallClassMemberFunc(m_poHandler, "OnOverInItem", Py_BuildValue("(i)", dwSlotNumber)); + + return TRUE; +} + +void CSlotWindow::OnOverOutItem() +{ + if (SLOT_NUMBER_NONE == m_dwToolTipSlotNumber) + return; + + m_dwToolTipSlotNumber = SLOT_NUMBER_NONE; + PyCallClassMemberFunc(m_poHandler, "OnOverOutItem", Py_BuildValue("()")); +} + +void CSlotWindow::OnPressedSlotButton(DWORD dwType, DWORD dwSlotNumber, BOOL isLeft) +{ + if (CSlotButton::SLOT_BUTTON_TYPE_PLUS == dwType) + { + PyCallClassMemberFunc(m_poHandler, "OnPressedSlotButton", Py_BuildValue("(i)", dwSlotNumber)); + } + else if (CSlotButton::SLOT_BUTTON_TYPE_COVER == dwType) + { + if (isLeft) + { + OnMouseLeftButtonDown(); + } + } +} + +void CSlotWindow::OnUpdate() +{ + for (std::deque::iterator itor = m_ReserveDestroyEffectDeque.begin(); itor != m_ReserveDestroyEffectDeque.end(); ++itor) + { + DWORD dwSlotIndex = *itor; + + TSlot * pSlot; + if (!GetSlotPointer(dwSlotIndex, &pSlot)) + continue; + + __DestroyFinishCoolTimeEffect(pSlot); + } + m_ReserveDestroyEffectDeque.clear(); + + if (m_pSlotActiveEffect) + m_pSlotActiveEffect->Update(); +} + +void CSlotWindow::OnRender() +{ + RenderSlotBaseImage(); + + switch (m_dwSlotStyle) + { + case SLOT_STYLE_PICK_UP: + OnRenderPickingSlot(); + break; + case SLOT_STYLE_SELECT: + OnRenderSelectedSlot(); + break; + } + + std::for_each(m_pChildList.begin(), m_pChildList.end(), std::mem_fn(&CWindow::OnRender)); + + TSlotListIterator itor; + + // + // ׸ + ////////////////////////////////////////////////////////////////////////// +#ifdef __RENDER_SLOT_AREA__ + CPythonGraphic::Instance().SetDiffuseColor(0.5f, 0.5f, 0.5f); + for (itor = m_SlotList.begin(); itor != m_SlotList.end(); ++itor) + { + TSlot & rSlot = *itor; + CPythonGraphic::Instance().RenderBox2d(m_rect.left + rSlot.ixPosition, + m_rect.top + rSlot.iyPosition, + m_rect.left + rSlot.ixPosition + rSlot.ixCellSize, + m_rect.top + rSlot.iyPosition + rSlot.iyCellSize); + } + CPythonGraphic::Instance().SetDiffuseColor(1.0f, 0.0f, 0.0f, 1.0f); + CPythonGraphic::Instance().RenderBox2d(m_rect.left, m_rect.top, m_rect.right, m_rect.bottom); +#endif + ////////////////////////////////////////////////////////////////////////// + + for (itor = m_SlotList.begin(); itor != m_SlotList.end(); ++itor) + { + TSlot & rSlot = *itor; + + if (rSlot.pSlotButton) + { + rSlot.pSlotButton->SetPosition(rSlot.ixPosition + 1, rSlot.iyPosition + 19); + } + if (rSlot.pSignImage) + { + rSlot.pSignImage->SetPosition(rSlot.ixPosition - 7, rSlot.iyPosition + 10); + } + + if (rSlot.pInstance) + { + rSlot.pInstance->SetPosition(m_rect.left + rSlot.ixPosition, m_rect.top + rSlot.iyPosition); + rSlot.pInstance->Render(); + } + + if (!rSlot.isItem) + { + if (IS_SET(rSlot.dwState, SLOT_STATE_ALWAYS_RENDER_COVER)) + { + rSlot.pCoverButton->Show(); + rSlot.pCoverButton->SetPosition(rSlot.ixPosition, rSlot.iyPosition); + rSlot.pCoverButton->RenderButton(); + } + + continue; + } + + if (IS_SET(rSlot.dwState, SLOT_STATE_DISABLE)) + { + CPythonGraphic::Instance().SetDiffuseColor(1.0f, 0.0f, 0.0f, 0.3f); + CPythonGraphic::Instance().RenderBar2d(m_rect.left + rSlot.ixPosition, + m_rect.top + rSlot.iyPosition, + m_rect.left + rSlot.ixPosition + rSlot.ixCellSize, + m_rect.top + rSlot.iyPosition + rSlot.iyCellSize); + } + + if (rSlot.fCoolTime != 0.0f) + { + float fcurTime = CTimer::Instance().GetCurrentSecond(); + float fPercentage = (fcurTime - rSlot.fStartCoolTime) / rSlot.fCoolTime; + CPythonGraphic::Instance().RenderCoolTimeBox(m_rect.left + rSlot.ixPosition + 16.0f, m_rect.top + rSlot.iyPosition + 16.0f, 16.0f, fPercentage); + + if (fcurTime - rSlot.fStartCoolTime >= rSlot.fCoolTime) + { + // Ÿ 1 ̳.. + if ((fcurTime - rSlot.fStartCoolTime) - rSlot.fCoolTime < 1.0f) + __CreateFinishCoolTimeEffect(&rSlot); + + rSlot.fCoolTime = 0.0f; + rSlot.fStartCoolTime = 0.0f; + } + } + + if (rSlot.pCoverButton) + { + rSlot.pCoverButton->SetPosition(rSlot.ixPosition, rSlot.iyPosition); + rSlot.pCoverButton->RenderButton(); + } + + if (rSlot.pNumberLine) + { + int ix = rSlot.byxPlacedItemSize*ITEM_WIDTH + rSlot.ixPosition - 4; + int iy = rSlot.iyPosition + rSlot.byyPlacedItemSize*ITEM_HEIGHT - 12 + 2; + rSlot.pNumberLine->SetPosition(ix, iy); + rSlot.pNumberLine->Update(); + rSlot.pNumberLine->Render(); + } + + if (rSlot.pFinishCoolTimeEffect) + { + rSlot.pFinishCoolTimeEffect->SetPosition(rSlot.ixPosition, rSlot.iyPosition); + rSlot.pFinishCoolTimeEffect->Update(); + rSlot.pFinishCoolTimeEffect->Render(); + } + + if (rSlot.bActive) + if (m_pSlotActiveEffect) + { + int ix = m_rect.left + rSlot.ixPosition; + int iy = m_rect.top + rSlot.iyPosition; + m_pSlotActiveEffect->SetPosition(ix, iy); + m_pSlotActiveEffect->Render(); + } + } + + RenderLockedSlot(); +} + +void CSlotWindow::RenderSlotBaseImage() +{ + if (!m_pBaseImageInstance) + return; + + for (TSlotListIterator itor = m_SlotList.begin(); itor != m_SlotList.end(); ++itor) + { + TSlot & rSlot = *itor; + + if (!rSlot.bRenderBaseSlotImage) + continue; + + m_pBaseImageInstance->SetPosition(m_rect.left + rSlot.ixPosition, m_rect.top + rSlot.iyPosition); + m_pBaseImageInstance->Render(); + } +} + +void CSlotWindow::OnRenderPickingSlot() +{ + if (!UI::CWindowManager::Instance().IsAttaching()) + return; + + TSlot * pSlot; + if (!GetSelectedSlotPointer(&pSlot)) + return; + + CPythonGraphic::Instance().SetDiffuseColor(1.0f, 1.0f, 1.0f, 0.5f); + CPythonGraphic::Instance().RenderBar2d(m_rect.left + pSlot->ixPosition, + m_rect.top + pSlot->iyPosition, + m_rect.left + pSlot->ixPosition + pSlot->ixCellSize, + m_rect.top + pSlot->iyPosition + pSlot->iyCellSize); +} + +void CSlotWindow::OnRenderSelectedSlot() +{ + std::list::iterator itor = m_dwSelectedSlotIndexList.begin(); + for (; itor != m_dwSelectedSlotIndexList.end(); ++itor) + { + TSlot * pSlot; + if (!GetSlotPointer(*itor, &pSlot)) + continue; + + CPythonGraphic::Instance().SetDiffuseColor(1.0f, 1.0f, 1.0f, 0.5f); + CPythonGraphic::Instance().RenderBar2d(m_rect.left + pSlot->ixPosition, + m_rect.top + pSlot->iyPosition, + m_rect.left + pSlot->ixPosition + pSlot->ixCellSize, + m_rect.top + pSlot->iyPosition + pSlot->iyCellSize); + } +} + +void CSlotWindow::RenderLockedSlot() +{ + CPythonGraphic::Instance().SetDiffuseColor(0.0f, 0.0f, 0.0f, 0.5f); + for (TSlotListIterator itor = m_SlotList.begin(); itor != m_SlotList.end(); ++itor) + { + TSlot & rSlot = *itor; + + if (!rSlot.isItem) + continue; + + if (rSlot.dwState & SLOT_STATE_LOCK) + { + CPythonGraphic::Instance().RenderBar2d(m_rect.left + rSlot.ixPosition, + m_rect.top + rSlot.iyPosition, + m_rect.left + rSlot.ixPosition + rSlot.ixCellSize, + m_rect.top + rSlot.iyPosition + rSlot.iyCellSize); + } + } +} + +// Check Slot + +BOOL CSlotWindow::GetSlotPointer(DWORD dwIndex, TSlot ** ppSlot) +{ + for (TSlotListIterator itor = m_SlotList.begin(); itor != m_SlotList.end(); ++itor) + { + TSlot & rSlot = *itor; + + if (dwIndex == rSlot.dwSlotNumber) + { + *ppSlot = &rSlot; + return TRUE; + } + } + + return FALSE; +} + +BOOL CSlotWindow::GetSelectedSlotPointer(TSlot ** ppSlot) +{ + long lx, ly; + GetMouseLocalPosition(lx, ly); + + for (TSlotListIterator itor = m_SlotList.begin(); itor != m_SlotList.end(); ++itor) + { + TSlot & rSlot = *itor; + + if (lx >= rSlot.ixPosition) + if (ly >= rSlot.iyPosition) + if (lx <= rSlot.ixPosition + rSlot.ixCellSize) + if (ly <= rSlot.iyPosition + rSlot.iyCellSize) + { + *ppSlot = &rSlot; + return TRUE; + } + } + + return FALSE; +} + +BOOL CSlotWindow::GetPickedSlotPointer(TSlot ** ppSlot) +{ + long lx, ly; + CWindowManager::Instance().GetMousePosition(lx, ly); + + int ixLocal = lx - m_rect.left; + int iyLocal = ly - m_rect.top; + + // NOTE : Ѱ ̶ ̿ Ʒ + // ʷ ˻ ν ִ Slot ڵ ȴٴ Ư ̿Ѵ. - [levites] + for (TSlotListIterator itor = m_SlotList.begin(); itor != m_SlotList.end(); ++itor) + { + TSlot & rSlot = *itor; + + int ixCellSize = rSlot.ixCellSize; + int iyCellSize = rSlot.iyCellSize; + + // NOTE : Item Hide Ǿ 츦 .. + if (rSlot.isItem) + { + ixCellSize = max(rSlot.ixCellSize, int(rSlot.byxPlacedItemSize * ITEM_WIDTH)); + iyCellSize = max(rSlot.iyCellSize, int(rSlot.byyPlacedItemSize * ITEM_HEIGHT)); + } + + if (ixLocal >= rSlot.ixPosition) + if (iyLocal >= rSlot.iyPosition) + if (ixLocal <= rSlot.ixPosition + ixCellSize) + if (iyLocal <= rSlot.iyPosition + iyCellSize) + { + *ppSlot = &rSlot; + return TRUE; + } + } + + return FALSE; +} + +void CSlotWindow::SetUseMode(BOOL bFlag) +{ + m_isUseMode = bFlag; +} + +void CSlotWindow::SetUsableItem(BOOL bFlag) +{ + m_isUsableItem = bFlag; +} + +void CSlotWindow::ReserveDestroyCoolTimeFinishEffect(DWORD dwSlotIndex) +{ + m_ReserveDestroyEffectDeque.push_back(dwSlotIndex); +} + +DWORD CSlotWindow::Type() +{ + static int s_Type = GetCRC32("CSlotWindow", strlen("CSlotWindow")); + return s_Type; +} + +BOOL CSlotWindow::OnIsType(DWORD dwType) +{ + if (CSlotWindow::Type() == dwType) + return TRUE; + + return CWindow::OnIsType(dwType); +} + +void CSlotWindow::__CreateToggleSlotImage() +{ + __DestroyToggleSlotImage(); + + m_pToggleSlotImage = new CImageBox(NULL); + m_pToggleSlotImage->LoadImage("d:/ymir work/ui/public/slot_toggle.sub"); + m_pToggleSlotImage->Show(); +} + +void CSlotWindow::__CreateSlotEnableEffect() +{ + __DestroySlotEnableEffect(); + + m_pSlotActiveEffect = new CAniImageBox(NULL); + m_pSlotActiveEffect->AppendImage("d:/ymir work/ui/public/slotactiveeffect/00.sub"); + m_pSlotActiveEffect->AppendImage("d:/ymir work/ui/public/slotactiveeffect/01.sub"); + m_pSlotActiveEffect->AppendImage("d:/ymir work/ui/public/slotactiveeffect/02.sub"); + m_pSlotActiveEffect->AppendImage("d:/ymir work/ui/public/slotactiveeffect/03.sub"); + m_pSlotActiveEffect->AppendImage("d:/ymir work/ui/public/slotactiveeffect/04.sub"); + m_pSlotActiveEffect->AppendImage("d:/ymir work/ui/public/slotactiveeffect/05.sub"); + m_pSlotActiveEffect->AppendImage("d:/ymir work/ui/public/slotactiveeffect/06.sub"); + m_pSlotActiveEffect->AppendImage("d:/ymir work/ui/public/slotactiveeffect/07.sub"); + m_pSlotActiveEffect->AppendImage("d:/ymir work/ui/public/slotactiveeffect/08.sub"); + m_pSlotActiveEffect->AppendImage("d:/ymir work/ui/public/slotactiveeffect/09.sub"); + m_pSlotActiveEffect->AppendImage("d:/ymir work/ui/public/slotactiveeffect/10.sub"); + m_pSlotActiveEffect->AppendImage("d:/ymir work/ui/public/slotactiveeffect/11.sub"); + m_pSlotActiveEffect->AppendImage("d:/ymir work/ui/public/slotactiveeffect/12.sub"); + m_pSlotActiveEffect->SetRenderingMode(CGraphicExpandedImageInstance::RENDERING_MODE_SCREEN); + m_pSlotActiveEffect->Show(); +} + +void CSlotWindow::__CreateFinishCoolTimeEffect(TSlot * pSlot) +{ + __DestroyFinishCoolTimeEffect(pSlot); + + CAniImageBox * pFinishCoolTimeEffect = new CCoolTimeFinishEffect(this, pSlot->dwSlotNumber); + pFinishCoolTimeEffect->AppendImage("d:/ymir work/ui/public/slotfinishcooltimeeffect/00.sub"); + pFinishCoolTimeEffect->AppendImage("d:/ymir work/ui/public/slotfinishcooltimeeffect/01.sub"); + pFinishCoolTimeEffect->AppendImage("d:/ymir work/ui/public/slotfinishcooltimeeffect/02.sub"); + pFinishCoolTimeEffect->AppendImage("d:/ymir work/ui/public/slotfinishcooltimeeffect/03.sub"); + pFinishCoolTimeEffect->AppendImage("d:/ymir work/ui/public/slotfinishcooltimeeffect/04.sub"); + pFinishCoolTimeEffect->AppendImage("d:/ymir work/ui/public/slotfinishcooltimeeffect/05.sub"); + pFinishCoolTimeEffect->AppendImage("d:/ymir work/ui/public/slotfinishcooltimeeffect/06.sub"); + pFinishCoolTimeEffect->AppendImage("d:/ymir work/ui/public/slotfinishcooltimeeffect/07.sub"); + pFinishCoolTimeEffect->AppendImage("d:/ymir work/ui/public/slotfinishcooltimeeffect/08.sub"); + pFinishCoolTimeEffect->AppendImage("d:/ymir work/ui/public/slotfinishcooltimeeffect/09.sub"); + pFinishCoolTimeEffect->AppendImage("d:/ymir work/ui/public/slotfinishcooltimeeffect/10.sub"); + pFinishCoolTimeEffect->SetRenderingMode(CGraphicExpandedImageInstance::RENDERING_MODE_SCREEN); + pFinishCoolTimeEffect->ResetFrame(); + pFinishCoolTimeEffect->SetDelay(2); + pFinishCoolTimeEffect->Show(); + + pSlot->pFinishCoolTimeEffect = pFinishCoolTimeEffect; +} + +void CSlotWindow::__CreateBaseImage(const char * c_szFileName, float fr, float fg, float fb, float fa) +{ + __DestroyBaseImage(); + + CGraphicImage * pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer(c_szFileName); + m_pBaseImageInstance = CGraphicImageInstance::New(); + m_pBaseImageInstance->SetImagePointer(pImage); + m_pBaseImageInstance->SetDiffuseColor(fr, fg, fb, fa); +} + +void CSlotWindow::__DestroyToggleSlotImage() +{ + if (m_pToggleSlotImage) + { + delete m_pToggleSlotImage; + m_pToggleSlotImage = NULL; + } +} + +void CSlotWindow::__DestroySlotEnableEffect() +{ + if (m_pSlotActiveEffect) + { + delete m_pSlotActiveEffect; + m_pSlotActiveEffect = NULL; + } +} + +void CSlotWindow::__DestroyFinishCoolTimeEffect(TSlot * pSlot) +{ + if (pSlot->pFinishCoolTimeEffect) + { + delete pSlot->pFinishCoolTimeEffect; + pSlot->pFinishCoolTimeEffect = NULL; + } +} + +void CSlotWindow::__DestroyBaseImage() +{ + if (m_pBaseImageInstance) + { + CGraphicImageInstance::Delete(m_pBaseImageInstance); + m_pBaseImageInstance = NULL; + } +} + +void CSlotWindow::__Initialize() +{ + m_dwSlotType = 0; + m_dwSlotStyle = SLOT_STYLE_PICK_UP; + m_dwToolTipSlotNumber = SLOT_NUMBER_NONE; + + m_isUseMode = FALSE; + m_isUsableItem = FALSE; + + m_pToggleSlotImage = NULL; + m_pSlotActiveEffect = NULL; + m_pBaseImageInstance = NULL; +} + +void CSlotWindow::Destroy() +{ + for (TSlotListIterator itor = m_SlotList.begin(); itor != m_SlotList.end(); ++itor) + { + TSlot & rSlot = *itor; + + ClearSlot(&rSlot); + + if (rSlot.pNumberLine) + { + delete rSlot.pNumberLine; + rSlot.pNumberLine = NULL; + } + if (rSlot.pCoverButton) + { + CWindowManager::Instance().DestroyWindow(rSlot.pCoverButton); + } + if (rSlot.pSlotButton) + { + CWindowManager::Instance().DestroyWindow(rSlot.pSlotButton); + } + if (rSlot.pSignImage) + { + CWindowManager::Instance().DestroyWindow(rSlot.pSignImage); + } + if (rSlot.pFinishCoolTimeEffect) + { + CWindowManager::Instance().DestroyWindow(rSlot.pFinishCoolTimeEffect); + } + } + + m_SlotList.clear(); + + __DestroyToggleSlotImage(); + __DestroySlotEnableEffect(); + __DestroyBaseImage(); + + __Initialize(); +} + +CSlotWindow::CSlotWindow(PyObject * ppyObject) : CWindow(ppyObject) +{ + __Initialize(); +} + +CSlotWindow::~CSlotWindow() +{ + Destroy(); +} diff --git a/source/EterPythonLib/PythonSlotWindow.h b/source/EterPythonLib/PythonSlotWindow.h new file mode 100644 index 0000000..4c7e82e --- /dev/null +++ b/source/EterPythonLib/PythonSlotWindow.h @@ -0,0 +1,211 @@ +#pragma once + +#include "PythonWindow.h" + +namespace UI +{ + enum + { + ITEM_WIDTH = 32, + ITEM_HEIGHT = 32, + + SLOT_NUMBER_NONE = 0xffffffff, + }; + + enum ESlotStyle + { + SLOT_STYLE_NONE, + SLOT_STYLE_PICK_UP, + SLOT_STYLE_SELECT, + }; + + enum ESlotState + { + SLOT_STATE_LOCK = (1 << 0), + SLOT_STATE_CANT_USE = (1 << 1), + SLOT_STATE_DISABLE = (1 << 2), + SLOT_STATE_ALWAYS_RENDER_COVER = (1 << 3), // Cover ư Կ ϴµ, flag ̾ Ŀ + }; + + class CSlotWindow : public CWindow + { + public: + static DWORD Type(); + + public: + class CSlotButton; + class CCoverButton; + class CCoolTimeFinishEffect; + + friend class CSlotButton; + friend class CCoverButton; + + typedef struct SSlot + { + DWORD dwState; + DWORD dwSlotNumber; + DWORD dwCenterSlotNumber; // NOTE :  ū ġ ȣ + DWORD dwItemIndex; // NOTE : ⼭ Ǵ Item̶ ܾ ƴ, + BOOL isItem; // " 빰"̶ . ? - [levites] + + // CoolTime + float fCoolTime; + float fStartCoolTime; + + // Toggle + BOOL bActive; + + int ixPosition; + int iyPosition; + + int ixCellSize; + int iyCellSize; + + BYTE byxPlacedItemSize; + BYTE byyPlacedItemSize; + + CGraphicImageInstance * pInstance; + CNumberLine * pNumberLine; + + bool bRenderBaseSlotImage; + CCoverButton * pCoverButton; + CSlotButton * pSlotButton; + CImageBox * pSignImage; + CAniImageBox * pFinishCoolTimeEffect; + } TSlot; + typedef std::list TSlotList; + typedef TSlotList::iterator TSlotListIterator; + + public: + CSlotWindow(PyObject * ppyObject); + virtual ~CSlotWindow(); + + void Destroy(); + + // Manage Slot + void SetSlotType(DWORD dwType); + void SetSlotStyle(DWORD dwStyle); + + void AppendSlot(DWORD dwIndex, int ixPosition, int iyPosition, int ixCellSize, int iyCellSize); + void SetCoverButton(DWORD dwIndex, const char * c_szUpImageName, const char * c_szOverImageName, const char * c_szDownImageName, const char * c_szDisableImageName, BOOL bLeftButtonEnable, BOOL bRightButtonEnable); + void SetSlotBaseImage(const char * c_szFileName, float fr, float fg, float fb, float fa); + void AppendSlotButton(const char * c_szUpImageName, const char * c_szOverImageName, const char * c_szDownImageName); + void AppendRequirementSignImage(const char * c_szImageName); + + void EnableCoverButton(DWORD dwIndex); + void DisableCoverButton(DWORD dwIndex); + void SetAlwaysRenderCoverButton(DWORD dwIndex, bool bAlwaysRender = false); + + void ShowSlotBaseImage(DWORD dwIndex); + void HideSlotBaseImage(DWORD dwIndex); + BOOL IsDisableCoverButton(DWORD dwIndex); + BOOL HasSlot(DWORD dwIndex); + + void ClearAllSlot(); + void ClearSlot(DWORD dwIndex); + void SetSlot(DWORD dwIndex, DWORD dwVirtualNumber, BYTE byWidth, BYTE byHeight, CGraphicImage * pImage, D3DXCOLOR& diffuseColor); + void SetSlotCount(DWORD dwIndex, DWORD dwCount); + void SetSlotCountNew(DWORD dwIndex, DWORD dwGrade, DWORD dwCount); + void SetSlotCoolTime(DWORD dwIndex, float fCoolTime, float fElapsedTime = 0.0f); + void ActivateSlot(DWORD dwIndex); + void DeactivateSlot(DWORD dwIndex); + void RefreshSlot(); + + DWORD GetSlotCount(); + + void LockSlot(DWORD dwIndex); + void UnlockSlot(DWORD dwIndex); + BOOL IsLockSlot(DWORD dwIndex); + void SetCantUseSlot(DWORD dwIndex); + void SetUseSlot(DWORD dwIndex); + BOOL IsCantUseSlot(DWORD dwIndex); + void EnableSlot(DWORD dwIndex); + void DisableSlot(DWORD dwIndex); + BOOL IsEnableSlot(DWORD dwIndex); + + // Select + void ClearSelected(); + void SelectSlot(DWORD dwSelectingIndex); + BOOL isSelectedSlot(DWORD dwIndex); + DWORD GetSelectedSlotCount(); + DWORD GetSelectedSlotNumber(DWORD dwIndex); + + // Slot Button + void ShowSlotButton(DWORD dwSlotNumber); + void HideAllSlotButton(); + void OnPressedSlotButton(DWORD dwType, DWORD dwSlotNumber, BOOL isLeft = TRUE); + + // Requirement Sign + void ShowRequirementSign(DWORD dwSlotNumber); + void HideRequirementSign(DWORD dwSlotNumber); + + // ToolTip + BOOL OnOverInItem(DWORD dwSlotNumber); + void OnOverOutItem(); + + // For Usable Item + void SetUseMode(BOOL bFlag); + void SetUsableItem(BOOL bFlag); + + // CallBack + void ReserveDestroyCoolTimeFinishEffect(DWORD dwSlotIndex); + + protected: + void __Initialize(); + void __CreateToggleSlotImage(); + void __CreateSlotEnableEffect(); + void __CreateFinishCoolTimeEffect(TSlot * pSlot); + void __CreateBaseImage(const char * c_szFileName, float fr, float fg, float fb, float fa); + + void __DestroyToggleSlotImage(); + void __DestroySlotEnableEffect(); + void __DestroyFinishCoolTimeEffect(TSlot * pSlot); + void __DestroyBaseImage(); + + // Event + void OnUpdate(); + void OnRender(); + BOOL OnMouseLeftButtonDown(); + BOOL OnMouseLeftButtonUp(); + BOOL OnMouseRightButtonDown(); + BOOL OnMouseLeftButtonDoubleClick(); + void OnMouseOverOut(); + void OnMouseOver(); + void RenderSlotBaseImage(); + void RenderLockedSlot(); + virtual void OnRenderPickingSlot(); + virtual void OnRenderSelectedSlot(); + + // Select + void OnSelectEmptySlot(int iSlotNumber); + void OnSelectItemSlot(int iSlotNumber); + void OnUnselectEmptySlot(int iSlotNumber); + void OnUnselectItemSlot(int iSlotNumber); + void OnUseSlot(); + + // Manage Slot + BOOL GetSlotPointer(DWORD dwIndex, TSlot ** ppSlot); + BOOL GetSelectedSlotPointer(TSlot ** ppSlot); + virtual BOOL GetPickedSlotPointer(TSlot ** ppSlot); + void ClearSlot(TSlot * pSlot); + virtual void OnRefreshSlot(); + + // ETC + BOOL OnIsType(DWORD dwType); + + protected: + DWORD m_dwSlotType; + DWORD m_dwSlotStyle; + std::list m_dwSelectedSlotIndexList; + TSlotList m_SlotList; + DWORD m_dwToolTipSlotNumber; + + BOOL m_isUseMode; + BOOL m_isUsableItem; + + CGraphicImageInstance * m_pBaseImageInstance; + CImageBox * m_pToggleSlotImage; + CAniImageBox * m_pSlotActiveEffect; + std::deque m_ReserveDestroyEffectDeque; + }; +}; \ No newline at end of file diff --git a/source/EterPythonLib/PythonWindow.cpp b/source/EterPythonLib/PythonWindow.cpp new file mode 100644 index 0000000..4970302 --- /dev/null +++ b/source/EterPythonLib/PythonWindow.cpp @@ -0,0 +1,2024 @@ +#include "StdAfx.h" +#include "../eterBase/CRC32.h" +#include "PythonWindow.h" +#include "PythonSlotWindow.h" +#include "PythonWindowManager.h" + +BOOL g_bOutlineBoxEnable = FALSE; + +namespace UI +{ + + CWindow::CWindow(PyObject * ppyObject) : + m_x(0), + m_y(0), + m_lWidth(0), + m_lHeight(0), + m_poHandler(ppyObject), + m_bShow(false), + m_pParent(NULL), + m_dwFlag(0), + m_isUpdatingChildren(FALSE) + { +#ifdef _DEBUG + static DWORD DEBUG_dwGlobalCounter=0; + DEBUG_dwCounter=DEBUG_dwGlobalCounter++; + + m_strName = "!!debug"; +#endif + //assert(m_poHandler != NULL); + m_HorizontalAlign = HORIZONTAL_ALIGN_LEFT; + m_VerticalAlign = VERTICAL_ALIGN_TOP; + m_rect.bottom = m_rect.left = m_rect.right = m_rect.top = 0; + m_limitBiasRect.bottom = m_limitBiasRect.left = m_limitBiasRect.right = m_limitBiasRect.top = 0; + } + + CWindow::~CWindow() + { + } + + DWORD CWindow::Type() + { + static DWORD s_dwType = GetCRC32("CWindow", strlen("CWindow")); + return (s_dwType); + } + + BOOL CWindow::IsType(DWORD dwType) + { + return OnIsType(dwType); + } + + BOOL CWindow::OnIsType(DWORD dwType) + { + if (CWindow::Type() == dwType) + return TRUE; + + return FALSE; + } + + struct FClear + { + void operator () (CWindow * pWin) + { + pWin->Clear(); + } + }; + + void CWindow::Clear() + { + // FIXME : Children Delete ʴ´. + // Pythonʿ Destroy ϳ ٽ ȣ ̹Ƿ.. + // ũ ´. + // ´ ִ°? - [levites] + std::for_each(m_pChildList.begin(), m_pChildList.end(), FClear()); + m_pChildList.clear(); + + m_pParent = NULL; + DestroyHandle(); + Hide(); + } + + void CWindow::DestroyHandle() + { + m_poHandler = NULL; + } + + void CWindow::Show() + { + m_bShow = true; + } + + void CWindow::Hide() + { + m_bShow = false; + } + + // NOTE : IsShow "ڽ ̴°?" , __IsShowing "ڽ ׷ ִ°?" üũѴ + // ڽ Show Tree Parent ϳ Hide Ƿ.. - [levites] + bool CWindow::IsRendering() + { + if (!IsShow()) + return false; + + if (!m_pParent) + return true; + + return m_pParent->IsRendering(); + } + + void CWindow::__RemoveReserveChildren() + { + if (m_pReserveChildList.empty()) + return; + + TWindowContainer::iterator it; + for(it = m_pReserveChildList.begin(); it != m_pReserveChildList.end(); ++it) + { + m_pChildList.remove(*it); + } + m_pReserveChildList.clear(); + } + + void CWindow::Update() + { + if (!IsShow()) + return; + + __RemoveReserveChildren(); + + OnUpdate(); + + m_isUpdatingChildren = TRUE; + TWindowContainer::iterator it; + for(it = m_pChildList.begin(); it != m_pChildList.end();) + { + TWindowContainer::iterator it_next = it; + ++it_next; + (*it)->Update(); + it = it_next; + } + m_isUpdatingChildren = FALSE; + } + + void CWindow::Render() + { + if (!IsShow()) + return; + + OnRender(); + + if (g_bOutlineBoxEnable) + { + CPythonGraphic::Instance().SetDiffuseColor(1.0f, 1.0f, 1.0f); + CPythonGraphic::Instance().RenderBox2d(m_rect.left, m_rect.top, m_rect.right, m_rect.bottom); + } + + std::for_each(m_pChildList.begin(), m_pChildList.end(), std::mem_fn(&CWindow::Render)); + } + + void CWindow::OnUpdate() + { + if (!m_poHandler) + return; + + if (!IsShow()) + return; + + static PyObject* poFuncName_OnUpdate = PyString_InternFromString("OnUpdate"); + + //PyCallClassMemberFunc(m_poHandler, "OnUpdate", BuildEmptyTuple()); + PyCallClassMemberFunc_ByPyString(m_poHandler, poFuncName_OnUpdate, BuildEmptyTuple()); + + } + + void CWindow::OnRender() + { + if (!m_poHandler) + return; + + if (!IsShow()) + return; + + //PyCallClassMemberFunc(m_poHandler, "OnRender", BuildEmptyTuple()); + PyCallClassMemberFunc(m_poHandler, "OnRender", BuildEmptyTuple()); + } + + void CWindow::SetName(const char * c_szName) + { + m_strName = c_szName; + } + + void CWindow::SetSize(long width, long height) + { + m_lWidth = width; + m_lHeight = height; + + m_rect.right = m_rect.left + m_lWidth; + m_rect.bottom = m_rect.top + m_lHeight; + } + + void CWindow::SetHorizontalAlign(DWORD dwAlign) + { + m_HorizontalAlign = (EHorizontalAlign)dwAlign; + UpdateRect(); + } + + void CWindow::SetVerticalAlign(DWORD dwAlign) + { + m_VerticalAlign = (EVerticalAlign)dwAlign; + UpdateRect(); + } + + void CWindow::SetPosition(long x, long y) + { + m_x = x; + m_y = y; + + UpdateRect(); + } + + void CWindow::GetPosition(long * plx, long * ply) + { + *plx = m_x; + *ply = m_y; + } + + long CWindow::UpdateRect() + { + m_rect.top = m_y; + if (m_pParent) + { + switch (m_VerticalAlign) + { + case VERTICAL_ALIGN_BOTTOM: + m_rect.top = m_pParent->GetHeight() - m_rect.top; + break; + case VERTICAL_ALIGN_CENTER: + m_rect.top = (m_pParent->GetHeight() - GetHeight()) / 2 + m_rect.top; + break; + } + m_rect.top += m_pParent->m_rect.top; + } + m_rect.bottom = m_rect.top + m_lHeight; + +#if defined( _USE_CPP_RTL_FLIP ) + if( m_pParent == NULL ) { + m_rect.left = m_x; + m_rect.right = m_rect.left + m_lWidth; + } else { + if( m_pParent->IsFlag(UI::CWindow::FLAG_RTL) == true ) { + m_rect.left = m_pParent->GetWidth() - m_lWidth - m_x; + switch (m_HorizontalAlign) + { + case HORIZONTAL_ALIGN_RIGHT: + m_rect.left = - m_x; + break; + case HORIZONTAL_ALIGN_CENTER: + m_rect.left = m_pParent->GetWidth() / 2 - GetWidth() - m_x; + break; + } + m_rect.left += m_pParent->m_rect.left; + m_rect.right = m_rect.left + m_lWidth; + } else { + m_rect.left = m_x; + switch (m_HorizontalAlign) + { + case HORIZONTAL_ALIGN_RIGHT: + m_rect.left = m_pParent->GetWidth() - m_rect.left; + break; + case HORIZONTAL_ALIGN_CENTER: + m_rect.left = (m_pParent->GetWidth() - GetWidth()) / 2 + m_rect.left; + break; + } + m_rect.left += m_pParent->m_rect.left; + m_rect.right = m_rect.left + m_lWidth; + } + } +#else + m_rect.left = m_x; + if (m_pParent) + { + switch (m_HorizontalAlign) + { + case HORIZONTAL_ALIGN_RIGHT: + m_rect.left = ::abs(m_pParent->GetWidth()) - m_rect.left; + break; + case HORIZONTAL_ALIGN_CENTER: + m_rect.left = m_pParent->GetWidth() / 2 - GetWidth() / 2 + m_rect.left; + break; + } + m_rect.left += 0L < m_pParent->GetWidth() ? m_pParent->m_rect.left : m_pParent->m_rect.right + ::abs(m_pParent->GetWidth()); + } + m_rect.right = m_rect.left + m_lWidth; +#endif + std::for_each(m_pChildList.begin(), m_pChildList.end(), std::mem_fn(&CWindow::UpdateRect)); + + OnChangePosition(); + + return 1; + } + + void CWindow::GetLocalPosition(long & rlx, long & rly) + { + rlx = rlx - m_rect.left; + rly = rly - m_rect.top; + } + + void CWindow::GetMouseLocalPosition(long & rlx, long & rly) + { + CWindowManager::Instance().GetMousePosition(rlx, rly); + rlx = rlx - m_rect.left; + rly = rly - m_rect.top; + } + + void CWindow::AddChild(CWindow * pWin) + { + m_pChildList.push_back(pWin); + pWin->m_pParent = this; + } + + CWindow * CWindow::GetRoot() + { + if (m_pParent) + if (m_pParent->IsWindow()) + return m_pParent->GetRoot(); + + return this; + } + + CWindow * CWindow::GetParent() + { + return m_pParent; + } + + bool CWindow::IsChild(CWindow * pWin) + { + std::list::iterator itor = m_pChildList.begin(); + + while (itor != m_pChildList.end()) + { + if (*itor == pWin) + return true; + + ++itor; + } + + return false; + } + + void CWindow::DeleteChild(CWindow * pWin) + { + if (m_isUpdatingChildren) + { + m_pReserveChildList.push_back(pWin); + } + else + { + m_pChildList.remove(pWin); + } + } + + void CWindow::SetTop(CWindow * pWin) + { + if (!pWin->IsFlag(CWindow::FLAG_FLOAT)) + return; + + TWindowContainer::iterator itor = std::find(m_pChildList.begin(), m_pChildList.end(), pWin); + if (m_pChildList.end() != itor) + { + m_pChildList.push_back(*itor); + m_pChildList.erase(itor); + + pWin->OnTop(); + } + else + { + TraceError(" CWindow::SetTop - Failed to find child window\n"); + } + } + + void CWindow::OnMouseDrag(long lx, long ly) + { + PyCallClassMemberFunc(m_poHandler, "OnMouseDrag", Py_BuildValue("(ii)", lx, ly)); + } + + void CWindow::OnMoveWindow(long lx, long ly) + { + PyCallClassMemberFunc(m_poHandler, "OnMoveWindow", Py_BuildValue("(ii)", lx, ly)); + } + + void CWindow::OnSetFocus() + { + //PyCallClassMemberFunc(m_poHandler, "OnSetFocus", BuildEmptyTuple()); + PyCallClassMemberFunc(m_poHandler, "OnSetFocus", BuildEmptyTuple()); + } + + void CWindow::OnKillFocus() + { + PyCallClassMemberFunc(m_poHandler, "OnKillFocus", BuildEmptyTuple()); + } + + void CWindow::OnMouseOverIn() + { + PyCallClassMemberFunc(m_poHandler, "OnMouseOverIn", BuildEmptyTuple()); + } + + void CWindow::OnMouseOverOut() + { + PyCallClassMemberFunc(m_poHandler, "OnMouseOverOut", BuildEmptyTuple()); + } + + void CWindow::OnMouseOver() + { + } + + void CWindow::OnDrop() + { + PyCallClassMemberFunc(m_poHandler, "OnDrop", BuildEmptyTuple()); + } + + void CWindow::OnTop() + { + PyCallClassMemberFunc(m_poHandler, "OnTop", BuildEmptyTuple()); + } + + void CWindow::OnIMEUpdate() + { + PyCallClassMemberFunc(m_poHandler, "OnIMEUpdate", BuildEmptyTuple()); + } + + BOOL CWindow::RunIMETabEvent() + { + if (!IsRendering()) + return FALSE; + + if (OnIMETabEvent()) + return TRUE; + + TWindowContainer::reverse_iterator itor; + for (itor = m_pChildList.rbegin(); itor != m_pChildList.rend(); ++itor) + { + CWindow * pWindow = *itor; + + if (pWindow->RunIMETabEvent()) + return TRUE; + } + + return FALSE; + } + + BOOL CWindow::RunIMEReturnEvent() + { + if (!IsRendering()) + return FALSE; + + if (OnIMEReturnEvent()) + return TRUE; + + TWindowContainer::reverse_iterator itor; + for (itor = m_pChildList.rbegin(); itor != m_pChildList.rend(); ++itor) + { + CWindow * pWindow = *itor; + + if (pWindow->RunIMEReturnEvent()) + return TRUE; + } + + return FALSE; + } + + BOOL CWindow::RunIMEKeyDownEvent(int ikey) + { + if (!IsRendering()) + return FALSE; + + if (OnIMEKeyDownEvent(ikey)) + return TRUE; + + TWindowContainer::reverse_iterator itor; + for (itor = m_pChildList.rbegin(); itor != m_pChildList.rend(); ++itor) + { + CWindow * pWindow = *itor; + + if (pWindow->RunIMEKeyDownEvent(ikey)) + return TRUE; + } + + return FALSE; + } + + CWindow * CWindow::RunKeyDownEvent(int ikey) + { + if (OnKeyDown(ikey)) + return this; + + TWindowContainer::reverse_iterator itor; + for (itor = m_pChildList.rbegin(); itor != m_pChildList.rend(); ++itor) + { + CWindow * pWindow = *itor; + + if (pWindow->IsShow()) + { + CWindow * pProcessedWindow = pWindow->RunKeyDownEvent(ikey); + if (NULL != pProcessedWindow) + { + return pProcessedWindow; + } + } + } + + return NULL; + } + + BOOL CWindow::RunKeyUpEvent(int ikey) + { + if (OnKeyUp(ikey)) + return TRUE; + + TWindowContainer::reverse_iterator itor; + for (itor = m_pChildList.rbegin(); itor != m_pChildList.rend(); ++itor) + { + CWindow * pWindow = *itor; + + if (pWindow->IsShow()) + if (pWindow->RunKeyUpEvent(ikey)) + return TRUE; + } + + return FALSE; + } + + BOOL CWindow::RunPressEscapeKeyEvent() + { + TWindowContainer::reverse_iterator itor; + for (itor = m_pChildList.rbegin(); itor != m_pChildList.rend(); ++itor) + { + CWindow * pWindow = *itor; + + if (pWindow->IsShow()) + if (pWindow->RunPressEscapeKeyEvent()) + return TRUE; + } + + if (OnPressEscapeKey()) + return TRUE; + + return FALSE; + } + + BOOL CWindow::RunPressExitKeyEvent() + { + TWindowContainer::reverse_iterator itor; + for (itor = m_pChildList.rbegin(); itor != m_pChildList.rend(); ++itor) + { + CWindow * pWindow = *itor; + + if (pWindow->RunPressExitKeyEvent()) + return TRUE; + + if (pWindow->IsShow()) + if (pWindow->OnPressExitKey()) + return TRUE; + } + + return FALSE; + } + + BOOL CWindow::OnMouseLeftButtonDown() + { + long lValue; + if (PyCallClassMemberFunc(m_poHandler, "OnMouseLeftButtonDown", BuildEmptyTuple(), &lValue)) + if (0 != lValue) + return TRUE; + + return FALSE; + } + + BOOL CWindow::OnMouseLeftButtonUp() + { + PyCallClassMemberFunc(m_poHandler, "OnMouseLeftButtonUp", BuildEmptyTuple()); + return TRUE; // NOTE : ButtonUp ܷ TRUE + } + + BOOL CWindow::OnMouseLeftButtonDoubleClick() + { + long lValue; + if (PyCallClassMemberFunc(m_poHandler, "OnMouseLeftButtonDoubleClick", BuildEmptyTuple(), &lValue)) + if (0 != lValue) + return TRUE; + + return FALSE; + } + + BOOL CWindow::OnMouseRightButtonDown() + { + long lValue; + if (PyCallClassMemberFunc(m_poHandler, "OnMouseRightButtonDown", BuildEmptyTuple(), &lValue)) + if (0 != lValue) + return TRUE; + + return FALSE; + } + + BOOL CWindow::OnMouseRightButtonUp() + { + long lValue; + if (PyCallClassMemberFunc(m_poHandler, "OnMouseRightButtonUp", BuildEmptyTuple(), &lValue)) + if (0 != lValue) + return TRUE; + + return FALSE; + } + + BOOL CWindow::OnMouseRightButtonDoubleClick() + { + long lValue; + if (PyCallClassMemberFunc(m_poHandler, "OnMouseRightButtonDoubleClick", BuildEmptyTuple(), &lValue)) + if (0 != lValue) + return TRUE; + + return FALSE; + } + + BOOL CWindow::OnMouseMiddleButtonDown() + { + long lValue; + if (PyCallClassMemberFunc(m_poHandler, "OnMouseMiddleButtonDown", BuildEmptyTuple(), &lValue)) + if (0 != lValue) + return TRUE; + + return FALSE; + } + + BOOL CWindow::OnMouseMiddleButtonUp() + { + long lValue; + if (PyCallClassMemberFunc(m_poHandler, "OnMouseMiddleButtonUp", BuildEmptyTuple(), &lValue)) + if (0 != lValue) + return TRUE; + + return FALSE; + } + + BOOL CWindow::OnIMETabEvent() + { + long lValue; + if (PyCallClassMemberFunc(m_poHandler, "OnIMETab", BuildEmptyTuple(), &lValue)) + if (0 != lValue) + return TRUE; + + return FALSE; + } + + BOOL CWindow::OnIMEReturnEvent() + { + long lValue; + if (PyCallClassMemberFunc(m_poHandler, "OnIMEReturn", BuildEmptyTuple(), &lValue)) + if (0 != lValue) + return TRUE; + + return FALSE; + } + + BOOL CWindow::OnIMEKeyDownEvent(int ikey) + { + long lValue; + if (PyCallClassMemberFunc(m_poHandler, "OnIMEKeyDown", Py_BuildValue("(i)", ikey), &lValue)) + if (0 != lValue) + return TRUE; + + return FALSE; + } + + BOOL CWindow::OnIMEChangeCodePage() + { + long lValue; + if (PyCallClassMemberFunc(m_poHandler, "OnIMEChangeCodePage", BuildEmptyTuple(), &lValue)) + if (0 != lValue) + return TRUE; + + return FALSE; + } + + BOOL CWindow::OnIMEOpenCandidateListEvent() + { + long lValue; + if (PyCallClassMemberFunc(m_poHandler, "OnIMEOpenCandidateList", BuildEmptyTuple(), &lValue)) + if (0 != lValue) + return TRUE; + + return FALSE; + } + + BOOL CWindow::OnIMECloseCandidateListEvent() + { + long lValue; + if (PyCallClassMemberFunc(m_poHandler, "OnIMECloseCandidateList", BuildEmptyTuple(), &lValue)) + if (0 != lValue) + return TRUE; + + return FALSE; + } + + BOOL CWindow::OnIMEOpenReadingWndEvent() + { + long lValue; + if (PyCallClassMemberFunc(m_poHandler, "OnIMEOpenReadingWnd", BuildEmptyTuple(), &lValue)) + if (0 != lValue) + return TRUE; + + return FALSE; + } + + BOOL CWindow::OnIMECloseReadingWndEvent() + { + long lValue; + if (PyCallClassMemberFunc(m_poHandler, "OnIMECloseReadingWnd", BuildEmptyTuple(), &lValue)) + if (0 != lValue) + return TRUE; + + return FALSE; + } + + BOOL CWindow::OnKeyDown(int ikey) + { + long lValue; + if (PyCallClassMemberFunc(m_poHandler, "OnKeyDown", Py_BuildValue("(i)", ikey), &lValue)) + if (0 != lValue) + return TRUE; + + return FALSE; + } + + BOOL CWindow::OnKeyUp(int ikey) + { + long lValue; + if (PyCallClassMemberFunc(m_poHandler, "OnKeyUp", Py_BuildValue("(i)", ikey), &lValue)) + if (0 != lValue) + return TRUE; + + return FALSE; + } + + BOOL CWindow::OnPressEscapeKey() + { + long lValue; + if (PyCallClassMemberFunc(m_poHandler, "OnPressEscapeKey", BuildEmptyTuple(), &lValue)) + if (0 != lValue) + return TRUE; + + return FALSE; + } + + BOOL CWindow::OnPressExitKey() + { + long lValue; + if (PyCallClassMemberFunc(m_poHandler, "OnPressExitKey", BuildEmptyTuple(), &lValue)) + if (0 != lValue) + return TRUE; + + return FALSE; + } + + ///// + + bool CWindow::IsIn(long x, long y) + { + if (x >= m_rect.left && x <= m_rect.right) + if (y >= m_rect.top && y <= m_rect.bottom) + return true; + + return false; + } + + bool CWindow::IsIn() + { + long lx, ly; + UI::CWindowManager::Instance().GetMousePosition(lx, ly); + + return IsIn(lx, ly); + } + + CWindow * CWindow::PickWindow(long x, long y) + { + std::list::reverse_iterator ritor = m_pChildList.rbegin(); + for (; ritor != m_pChildList.rend(); ++ritor) + { + CWindow * pWin = *ritor; + if (pWin->IsShow()) + { + if (!pWin->IsFlag(CWindow::FLAG_IGNORE_SIZE)) + { + if (!pWin->IsIn(x, y)) { + if (0L <= pWin->GetWidth()) { + continue; + } + } + } + + CWindow * pResult = pWin->PickWindow(x, y); + if (pResult) + return pResult; + } + } + + if (IsFlag(CWindow::FLAG_NOT_PICK)) + return NULL; + + return (this); + } + + CWindow * CWindow::PickTopWindow(long x, long y) + { + std::list::reverse_iterator ritor = m_pChildList.rbegin(); + for (; ritor != m_pChildList.rend(); ++ritor) + { + CWindow * pWin = *ritor; + if (pWin->IsShow()) + if (pWin->IsIn(x, y)) + if (!pWin->IsFlag(CWindow::FLAG_NOT_PICK)) + return pWin; + } + + return NULL; + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// + + CBox::CBox(PyObject * ppyObject) : CWindow(ppyObject), m_dwColor(0xff000000) + { + } + CBox::~CBox() + { + } + + void CBox::SetColor(DWORD dwColor) + { + m_dwColor = dwColor; + } + + void CBox::OnRender() + { + CPythonGraphic::Instance().SetDiffuseColor(m_dwColor); + CPythonGraphic::Instance().RenderBox2d(m_rect.left, m_rect.top, m_rect.right, m_rect.bottom); + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// + + CBar::CBar(PyObject * ppyObject) : CWindow(ppyObject), m_dwColor(0xff000000) + { + } + CBar::~CBar() + { + } + + void CBar::SetColor(DWORD dwColor) + { + m_dwColor = dwColor; + } + + void CBar::OnRender() + { + CPythonGraphic::Instance().SetDiffuseColor(m_dwColor); + CPythonGraphic::Instance().RenderBar2d(m_rect.left, m_rect.top, m_rect.right, m_rect.bottom); + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// + + CLine::CLine(PyObject * ppyObject) : CWindow(ppyObject), m_dwColor(0xff000000) + { + } + CLine::~CLine() + { + } + + void CLine::SetColor(DWORD dwColor) + { + m_dwColor = dwColor; + } + + void CLine::OnRender() + { + CPythonGraphic & rkpyGraphic = CPythonGraphic::Instance(); + rkpyGraphic.SetDiffuseColor(m_dwColor); + rkpyGraphic.RenderLine2d(m_rect.left, m_rect.top, m_rect.right, m_rect.bottom); + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// + + DWORD CBar3D::Type() + { + static DWORD s_dwType = GetCRC32("CBar3D", strlen("CBar3D")); + return (s_dwType); + } + + CBar3D::CBar3D(PyObject * ppyObject) : CWindow(ppyObject) + { + m_dwLeftColor = D3DXCOLOR(0.2f, 0.2f, 0.2f, 1.0f); + m_dwRightColor = D3DXCOLOR(0.7f, 0.7f, 0.7f, 1.0f); + m_dwCenterColor = D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f); + } + CBar3D::~CBar3D() + { + } + + void CBar3D::SetColor(DWORD dwLeft, DWORD dwRight, DWORD dwCenter) + { + m_dwLeftColor = dwLeft; + m_dwRightColor = dwRight; + m_dwCenterColor = dwCenter; + } + + void CBar3D::OnRender() + { + CPythonGraphic & rkpyGraphic = CPythonGraphic::Instance(); + + rkpyGraphic.SetDiffuseColor(m_dwCenterColor); + rkpyGraphic.RenderBar2d(m_rect.left, m_rect.top, m_rect.right, m_rect.bottom); + + rkpyGraphic.SetDiffuseColor(m_dwLeftColor); + rkpyGraphic.RenderLine2d(m_rect.left, m_rect.top, m_rect.right, m_rect.top); + rkpyGraphic.RenderLine2d(m_rect.left, m_rect.top, m_rect.left, m_rect.bottom); + + rkpyGraphic.SetDiffuseColor(m_dwRightColor); + rkpyGraphic.RenderLine2d(m_rect.left, m_rect.bottom, m_rect.right, m_rect.bottom); + rkpyGraphic.RenderLine2d(m_rect.right, m_rect.top, m_rect.right, m_rect.bottom); + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// + + CTextLine::CTextLine(PyObject * ppyObject) : CWindow(ppyObject) + { + m_TextInstance.SetColor(0.78f, 0.78f, 0.78f); + m_TextInstance.SetHorizonalAlign(CGraphicTextInstance::HORIZONTAL_ALIGN_LEFT); + m_TextInstance.SetVerticalAlign(CGraphicTextInstance::VERTICAL_ALIGN_TOP); + } + CTextLine::~CTextLine() + { + m_TextInstance.Destroy(); + } + + void CTextLine::SetMax(int iMax) + { + m_TextInstance.SetMax(iMax); + } + void CTextLine::SetHorizontalAlign(int iType) + { + m_TextInstance.SetHorizonalAlign(iType); + } + void CTextLine::SetVerticalAlign(int iType) + { + m_TextInstance.SetVerticalAlign(iType); + } + void CTextLine::SetSecret(BOOL bFlag) + { + m_TextInstance.SetSecret(bFlag ? true : false); + } + void CTextLine::SetOutline(BOOL bFlag) + { + m_TextInstance.SetOutline(bFlag ? true : false); + } + void CTextLine::SetFeather(BOOL bFlag) + { + m_TextInstance.SetFeather(bFlag ? true : false); + } + void CTextLine::SetMultiLine(BOOL bFlag) + { + m_TextInstance.SetMultiLine(bFlag ? true : false); + } + void CTextLine::SetFontName(const char * c_szFontName) + { + std::string stFontName = c_szFontName; + stFontName += ".fnt"; + + CResourceManager& rkResMgr=CResourceManager::Instance(); + CResource* pkRes = rkResMgr.GetTypeResourcePointer(stFontName.c_str()); + CGraphicText* pkResFont=static_cast(pkRes); + m_TextInstance.SetTextPointer(pkResFont); + } + void CTextLine::SetFontColor(DWORD dwColor) + { + m_TextInstance.SetColor(dwColor); + } + void CTextLine::SetLimitWidth(float fWidth) + { + m_TextInstance.SetLimitWidth(fWidth); + } + void CTextLine::SetText(const char * c_szText) + { + OnSetText(c_szText); + } + void CTextLine::GetTextSize(int* pnWidth, int* pnHeight) + { + m_TextInstance.GetTextSize(pnWidth, pnHeight); + } + const char * CTextLine::GetText() + { + return m_TextInstance.GetValueStringReference().c_str(); + } + void CTextLine::ShowCursor() + { + m_TextInstance.ShowCursor(); + } + void CTextLine::HideCursor() + { + m_TextInstance.HideCursor(); + } + int CTextLine::GetCursorPosition() + { + long lx, ly; + CWindow::GetMouseLocalPosition(lx, ly); + return m_TextInstance.PixelPositionToCharacterPosition(lx); + } + + void CTextLine::OnSetText(const char * c_szText) + { + m_TextInstance.SetValue(c_szText); + m_TextInstance.Update(); + } + + void CTextLine::OnUpdate() + { + if (IsShow()) + m_TextInstance.Update(); + } + void CTextLine::OnRender() + { + if (IsShow()) + m_TextInstance.Render(); + } + + void CTextLine::OnChangePosition() + { + // FOR_ARABIC_ALIGN + //if (m_TextInstance.GetHorizontalAlign() == CGraphicTextInstance::HORIZONTAL_ALIGN_ARABIC) + if( GetDefaultCodePage() == CP_ARABIC ) + { + m_TextInstance.SetPosition(m_rect.right, m_rect.top); + } + else + { + m_TextInstance.SetPosition(m_rect.left, m_rect.top); + } + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// + + CNumberLine::CNumberLine(PyObject * ppyObject) : CWindow(ppyObject) + { + m_strPath = "d:/ymir work/ui/game/taskbar/"; + m_iHorizontalAlign = HORIZONTAL_ALIGN_LEFT; + m_dwWidthSummary = 0; + } + CNumberLine::CNumberLine(CWindow * pParent) : CWindow(NULL) + { + m_strPath = "d:/ymir work/ui/game/taskbar/"; + m_iHorizontalAlign = HORIZONTAL_ALIGN_LEFT; + m_dwWidthSummary = 0; + + m_pParent = pParent; + } + CNumberLine::~CNumberLine() + { + ClearNumber(); + } + + void CNumberLine::SetPath(const char * c_szPath) + { + m_strPath = c_szPath; + } + void CNumberLine::SetHorizontalAlign(int iType) + { + m_iHorizontalAlign = iType; + } + void CNumberLine::SetNumber(const char * c_szNumber) + { + if (0 == m_strNumber.compare(c_szNumber)) + return; + + ClearNumber(); + + m_strNumber = c_szNumber; + + for (DWORD i = 0; i < m_strNumber.size(); ++i) + { + char cChar = m_strNumber[i]; + std::string strImageFileName; + + if (':' == cChar) + { + strImageFileName = m_strPath + "colon.sub"; + } + else if ('?' == cChar) + { + strImageFileName = m_strPath + "questionmark.sub"; + } + else if ('/' == cChar) + { + strImageFileName = m_strPath + "slash.sub"; + } + else if ('%' == cChar) + { + strImageFileName = m_strPath + "percent.sub"; + } + else if ('+' == cChar) + { + strImageFileName = m_strPath + "plus.sub"; + } + else if ('m' == cChar) + { + strImageFileName = m_strPath + "m.sub"; + } + else if ('g' == cChar) + { + strImageFileName = m_strPath + "g.sub"; + } + else if ('p' == cChar) + { + strImageFileName = m_strPath + "p.sub"; + } + else if (cChar >= '0' && cChar <= '9') + { + strImageFileName = m_strPath; + strImageFileName += cChar; + strImageFileName += ".sub"; + } + else + continue; + + if (!CResourceManager::Instance().IsFileExist(strImageFileName.c_str())) + continue; + + CGraphicImage * pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer(strImageFileName.c_str()); + + CGraphicImageInstance * pInstance = CGraphicImageInstance::New(); + pInstance->SetImagePointer(pImage); + m_ImageInstanceVector.push_back(pInstance); + + m_dwWidthSummary += pInstance->GetWidth(); + } + } + + void CNumberLine::ClearNumber() + { + m_ImageInstanceVector.clear(); + m_dwWidthSummary = 0; + m_strNumber = ""; + } + + void CNumberLine::OnRender() + { + for (DWORD i = 0; i < m_ImageInstanceVector.size(); ++i) + { + m_ImageInstanceVector[i]->Render(); + } + } + + void CNumberLine::OnChangePosition() + { + int ix = m_x; + int iy = m_y; + + if (m_pParent) + { + ix = m_rect.left; + iy = m_rect.top; + } + + switch (m_iHorizontalAlign) + { + case HORIZONTAL_ALIGN_LEFT: + break; + case HORIZONTAL_ALIGN_CENTER: + ix -= int(m_dwWidthSummary) / 2; + break; + case HORIZONTAL_ALIGN_RIGHT: + ix -= int(m_dwWidthSummary); + break; + } + + for (DWORD i = 0; i < m_ImageInstanceVector.size(); ++i) + { + m_ImageInstanceVector[i]->SetPosition(ix, iy); + ix += m_ImageInstanceVector[i]->GetWidth(); + } + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// + + CImageBox::CImageBox(PyObject * ppyObject) : CWindow(ppyObject) + { + m_pImageInstance = NULL; + } + CImageBox::~CImageBox() + { + OnDestroyInstance(); + } + + void CImageBox::OnCreateInstance() + { + OnDestroyInstance(); + + m_pImageInstance = CGraphicImageInstance::New(); + } + void CImageBox::OnDestroyInstance() + { + if (m_pImageInstance) + { + CGraphicImageInstance::Delete(m_pImageInstance); + m_pImageInstance=NULL; + } + } + + BOOL CImageBox::LoadImage(const char * c_szFileName) + { + if (!c_szFileName[0]) + return FALSE; + + OnCreateInstance(); + + CResource * pResource = CResourceManager::Instance().GetResourcePointer(c_szFileName); + if (!pResource) + return FALSE; + if (!pResource->IsType(CGraphicImage::Type())) + return FALSE; + + m_pImageInstance->SetImagePointer(static_cast(pResource)); + if (m_pImageInstance->IsEmpty()) + return FALSE; + + SetSize(m_pImageInstance->GetWidth(), m_pImageInstance->GetHeight()); + UpdateRect(); + + return TRUE; + } + + void CImageBox::SetDiffuseColor(float fr, float fg, float fb, float fa) + { + if (!m_pImageInstance) + return; + + m_pImageInstance->SetDiffuseColor(fr, fg, fb, fa); + } + + int CImageBox::GetWidth() + { + if (!m_pImageInstance) + return 0; + + return m_pImageInstance->GetWidth(); + } + + int CImageBox::GetHeight() + { + if (!m_pImageInstance) + return 0; + + return m_pImageInstance->GetHeight(); + } + + void CImageBox::OnUpdate() + { + } + void CImageBox::OnRender() + { + if (!m_pImageInstance) + return; + + if (IsShow()) + m_pImageInstance->Render(); + } + void CImageBox::OnChangePosition() + { + if (!m_pImageInstance) + return; + + m_pImageInstance->SetPosition(m_rect.left, m_rect.top); + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + // MarkBox - ũ ¿ UI + /////////////////////////////////////////////////////////////////////////////////////////////// + CMarkBox::CMarkBox(PyObject * ppyObject) : CWindow(ppyObject) + { + m_pMarkInstance = NULL; + } + + CMarkBox::~CMarkBox() + { + OnDestroyInstance(); + } + + void CMarkBox::OnCreateInstance() + { + OnDestroyInstance(); + m_pMarkInstance = CGraphicMarkInstance::New(); + } + + void CMarkBox::OnDestroyInstance() + { + if (m_pMarkInstance) + { + CGraphicMarkInstance::Delete(m_pMarkInstance); + m_pMarkInstance=NULL; + } + } + + void CMarkBox::LoadImage(const char * c_szFilename) + { + OnCreateInstance(); + + m_pMarkInstance->SetImageFileName(c_szFilename); + m_pMarkInstance->Load(); + SetSize(m_pMarkInstance->GetWidth(), m_pMarkInstance->GetHeight()); + + UpdateRect(); + } + + void CMarkBox::SetScale(FLOAT fScale) + { + if (!m_pMarkInstance) + return; + + m_pMarkInstance->SetScale(fScale); + } + + void CMarkBox::SetIndex(UINT uIndex) + { + if (!m_pMarkInstance) + return; + + m_pMarkInstance->SetIndex(uIndex); + } + + void CMarkBox::SetDiffuseColor(float fr, float fg, float fb, float fa) + { + if (!m_pMarkInstance) + return; + + m_pMarkInstance->SetDiffuseColor(fr, fg, fb, fa); + } + + void CMarkBox::OnUpdate() + { + } + + void CMarkBox::OnRender() + { + if (!m_pMarkInstance) + return; + + if (IsShow()) + m_pMarkInstance->Render(); + } + + void CMarkBox::OnChangePosition() + { + if (!m_pMarkInstance) + return; + + m_pMarkInstance->SetPosition(m_rect.left, m_rect.top); + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// + + DWORD CExpandedImageBox::Type() + { + static DWORD s_dwType = GetCRC32("CExpandedImageBox", strlen("CExpandedImageBox")); + return (s_dwType); + } + + BOOL CExpandedImageBox::OnIsType(DWORD dwType) + { + if (CExpandedImageBox::Type() == dwType) + return TRUE; + + return FALSE; + } + + CExpandedImageBox::CExpandedImageBox(PyObject * ppyObject) : CImageBox(ppyObject) + { + } + CExpandedImageBox::~CExpandedImageBox() + { + OnDestroyInstance(); + } + + void CExpandedImageBox::OnCreateInstance() + { + OnDestroyInstance(); + + m_pImageInstance = CGraphicExpandedImageInstance::New(); + } + void CExpandedImageBox::OnDestroyInstance() + { + if (m_pImageInstance) + { + CGraphicExpandedImageInstance::Delete((CGraphicExpandedImageInstance*)m_pImageInstance); + m_pImageInstance=NULL; + } + } + + void CExpandedImageBox::SetScale(float fx, float fy) + { + if (!m_pImageInstance) + return; + + ((CGraphicExpandedImageInstance*)m_pImageInstance)->SetScale(fx, fy); + CWindow::SetSize(long(float(GetWidth())*fx), long(float(GetHeight())*fy)); + } + void CExpandedImageBox::SetOrigin(float fx, float fy) + { + if (!m_pImageInstance) + return; + + ((CGraphicExpandedImageInstance*)m_pImageInstance)->SetOrigin(fx, fy); + } + void CExpandedImageBox::SetRotation(float fRotation) + { + if (!m_pImageInstance) + return; + + ((CGraphicExpandedImageInstance*)m_pImageInstance)->SetRotation(fRotation); + } + void CExpandedImageBox::SetRenderingRect(float fLeft, float fTop, float fRight, float fBottom) + { + if (!m_pImageInstance) + return; + + ((CGraphicExpandedImageInstance*)m_pImageInstance)->SetRenderingRect(fLeft, fTop, fRight, fBottom); + } + + void CExpandedImageBox::SetRenderingMode(int iMode) + { + ((CGraphicExpandedImageInstance*)m_pImageInstance)->SetRenderingMode(iMode); + } + + void CExpandedImageBox::OnUpdate() + { + } + void CExpandedImageBox::OnRender() + { + if (!m_pImageInstance) + return; + + if (IsShow()) + m_pImageInstance->Render(); + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// + + DWORD CAniImageBox::Type() + { + static DWORD s_dwType = GetCRC32("CAniImageBox", strlen("CAniImageBox")); + return (s_dwType); + } + + BOOL CAniImageBox::OnIsType(DWORD dwType) + { + if (CAniImageBox::Type() == dwType) + return TRUE; + + return FALSE; + } + + CAniImageBox::CAniImageBox(PyObject * ppyObject) + : CWindow(ppyObject), + m_bycurDelay(0), + m_byDelay(4), + m_bycurIndex(0) + { + m_ImageVector.clear(); + } + CAniImageBox::~CAniImageBox() + { + for_each(m_ImageVector.begin(), m_ImageVector.end(), CGraphicExpandedImageInstance::DeleteExpandedImageInstance); + } + + void CAniImageBox::SetDelay(int iDelay) + { + m_byDelay = iDelay; + } + void CAniImageBox::AppendImage(const char * c_szFileName) + { + CResource * pResource = CResourceManager::Instance().GetResourcePointer(c_szFileName); + if (!pResource->IsType(CGraphicImage::Type())) + return; + + CGraphicExpandedImageInstance * pImageInstance = CGraphicExpandedImageInstance::New(); + + pImageInstance->SetImagePointer(static_cast(pResource)); + if (pImageInstance->IsEmpty()) + { + CGraphicExpandedImageInstance::Delete(pImageInstance); + return; + } + + m_ImageVector.push_back(pImageInstance); + + m_bycurIndex = static_cast(rand() % m_ImageVector.size()); +// SetSize(pImageInstance->GetWidth(), pImageInstance->GetHeight()); +// UpdateRect(); + } + + struct FSetRenderingRect + { + float fLeft, fTop, fRight, fBottom; + void operator () (CGraphicExpandedImageInstance * pInstance) + { + pInstance->SetRenderingRect(fLeft, fTop, fRight, fBottom); + } + }; + void CAniImageBox::SetRenderingRect(float fLeft, float fTop, float fRight, float fBottom) + { + FSetRenderingRect setRenderingRect; + setRenderingRect.fLeft = fLeft; + setRenderingRect.fTop = fTop; + setRenderingRect.fRight = fRight; + setRenderingRect.fBottom = fBottom; + for_each(m_ImageVector.begin(), m_ImageVector.end(), setRenderingRect); + } + + struct FSetRenderingMode + { + int iMode; + void operator () (CGraphicExpandedImageInstance * pInstance) + { + pInstance->SetRenderingMode(iMode); + } + }; + void CAniImageBox::SetRenderingMode(int iMode) + { + FSetRenderingMode setRenderingMode; + setRenderingMode.iMode = iMode; + for_each(m_ImageVector.begin(), m_ImageVector.end(), setRenderingMode); + } + + void CAniImageBox::ResetFrame() + { + m_bycurIndex = 0; + } + + void CAniImageBox::OnUpdate() + { + ++m_bycurDelay; + if (m_bycurDelay < m_byDelay) + return; + + m_bycurDelay = 0; + + ++m_bycurIndex; + if (m_bycurIndex >= m_ImageVector.size()) + { + m_bycurIndex = 0; + + OnEndFrame(); + } + } + void CAniImageBox::OnRender() + { + if (m_bycurIndex < m_ImageVector.size()) + { + CGraphicExpandedImageInstance * pImage = m_ImageVector[m_bycurIndex]; + pImage->Render(); + } + } + + struct FChangePosition + { + float fx, fy; + void operator () (CGraphicExpandedImageInstance * pInstance) + { + pInstance->SetPosition(fx, fy); + } + }; + + void CAniImageBox::OnChangePosition() + { + FChangePosition changePosition; + changePosition.fx = m_rect.left; + changePosition.fy = m_rect.top; + for_each(m_ImageVector.begin(), m_ImageVector.end(), changePosition); + } + + void CAniImageBox::OnEndFrame() + { + PyCallClassMemberFunc(m_poHandler, "OnEndFrame", BuildEmptyTuple()); + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// + + CButton::CButton(PyObject * ppyObject) + : CWindow(ppyObject), + m_pcurVisual(NULL), + m_bEnable(TRUE), + m_isPressed(FALSE), + m_isFlash(FALSE) + { + CWindow::AddFlag(CWindow::FLAG_NOT_CAPTURE); + } + CButton::~CButton() + { + } + + BOOL CButton::SetUpVisual(const char * c_szFileName) + { + CResource * pResource = CResourceManager::Instance().GetResourcePointer(c_szFileName); + if (!pResource->IsType(CGraphicImage::Type())) + return FALSE; + + m_upVisual.SetImagePointer(static_cast(pResource)); + if (m_upVisual.IsEmpty()) + return FALSE; + + SetSize(m_upVisual.GetWidth(), m_upVisual.GetHeight()); + // + SetCurrentVisual(&m_upVisual); + // + + return TRUE; + } + BOOL CButton::SetOverVisual(const char * c_szFileName) + { + CResource * pResource = CResourceManager::Instance().GetResourcePointer(c_szFileName); + if (!pResource->IsType(CGraphicImage::Type())) + return FALSE; + + m_overVisual.SetImagePointer(static_cast(pResource)); + if (m_overVisual.IsEmpty()) + return FALSE; + + SetSize(m_overVisual.GetWidth(), m_overVisual.GetHeight()); + + return TRUE; + } + BOOL CButton::SetDownVisual(const char * c_szFileName) + { + CResource * pResource = CResourceManager::Instance().GetResourcePointer(c_szFileName); + if (!pResource->IsType(CGraphicImage::Type())) + return FALSE; + + m_downVisual.SetImagePointer(static_cast(pResource)); + if (m_downVisual.IsEmpty()) + return FALSE; + + SetSize(m_downVisual.GetWidth(), m_downVisual.GetHeight()); + + return TRUE; + } + BOOL CButton::SetDisableVisual(const char * c_szFileName) + { + CResource * pResource = CResourceManager::Instance().GetResourcePointer(c_szFileName); + if (!pResource->IsType(CGraphicImage::Type())) + return FALSE; + + m_disableVisual.SetImagePointer(static_cast(pResource)); + if (m_downVisual.IsEmpty()) + return FALSE; + + SetSize(m_disableVisual.GetWidth(), m_disableVisual.GetHeight()); + + return TRUE; + } + + const char * CButton::GetUpVisualFileName() + { + return m_upVisual.GetGraphicImagePointer()->GetFileName(); + } + const char * CButton::GetOverVisualFileName() + { + return m_overVisual.GetGraphicImagePointer()->GetFileName(); + } + const char * CButton::GetDownVisualFileName() + { + return m_downVisual.GetGraphicImagePointer()->GetFileName(); + } + + void CButton::Flash() + { + m_isFlash = TRUE; + } + + void CButton::Enable() + { + SetUp(); + m_bEnable = TRUE; + } + + void CButton::Disable() + { + m_bEnable = FALSE; + if (!m_disableVisual.IsEmpty()) + SetCurrentVisual(&m_disableVisual); + } + + BOOL CButton::IsDisable() + { + return m_bEnable; + } + + void CButton::SetUp() + { + SetCurrentVisual(&m_upVisual); + m_isPressed = FALSE; + } + void CButton::Up() + { + if (IsIn()) + SetCurrentVisual(&m_overVisual); + else + SetCurrentVisual(&m_upVisual); + + PyCallClassMemberFunc(m_poHandler, "CallEvent", BuildEmptyTuple()); + } + void CButton::Over() + { + SetCurrentVisual(&m_overVisual); + } + void CButton::Down() + { + m_isPressed = TRUE; + SetCurrentVisual(&m_downVisual); + PyCallClassMemberFunc(m_poHandler, "DownEvent", BuildEmptyTuple()); + } + + void CButton::OnUpdate() + { + } + void CButton::OnRender() + { + if (!IsShow()) + return; + + if (m_pcurVisual) + { + if (m_isFlash) + if (!IsIn()) + if (int(timeGetTime() / 500)%2) + { + return; + } + + m_pcurVisual->Render(); + } + + PyCallClassMemberFunc(m_poHandler, "OnRender", BuildEmptyTuple()); + } + void CButton::OnChangePosition() + { + if (m_pcurVisual) + m_pcurVisual->SetPosition(m_rect.left, m_rect.top); + } + + BOOL CButton::OnMouseLeftButtonDown() + { + if (!IsEnable()) + return TRUE; + + m_isPressed = TRUE; + Down(); + + return TRUE; + } + BOOL CButton::OnMouseLeftButtonDoubleClick() + { + if (!IsEnable()) + return TRUE; + + OnMouseLeftButtonDown(); + + return TRUE; + } + BOOL CButton::OnMouseLeftButtonUp() + { + if (!IsEnable()) + return TRUE; + if (!IsPressed()) + return TRUE; + + m_isPressed = FALSE; + Up(); + + return TRUE; + } + void CButton::OnMouseOverIn() + { + if (!IsEnable()) + return; + + Over(); + PyCallClassMemberFunc(m_poHandler, "ShowToolTip", BuildEmptyTuple()); + } + void CButton::OnMouseOverOut() + { + if (!IsEnable()) + return; + + SetUp(); + PyCallClassMemberFunc(m_poHandler, "HideToolTip", BuildEmptyTuple()); + } + + void CButton::SetCurrentVisual(CGraphicImageInstance * pVisual) + { + m_pcurVisual = pVisual; + m_pcurVisual->SetPosition(m_rect.left, m_rect.top); + } + + BOOL CButton::IsEnable() + { + return m_bEnable; + } + + BOOL CButton::IsPressed() + { + return m_isPressed; + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// + + CRadioButton::CRadioButton(PyObject * ppyObject) : CButton(ppyObject) + { + } + CRadioButton::~CRadioButton() + { + } + + BOOL CRadioButton::OnMouseLeftButtonDown() + { + if (!IsEnable()) + return TRUE; + + if (!m_isPressed) + { + Down(); + PyCallClassMemberFunc(m_poHandler, "CallEvent", BuildEmptyTuple()); + } + + return TRUE; + } + BOOL CRadioButton::OnMouseLeftButtonUp() + { + return TRUE; + } + void CRadioButton::OnMouseOverIn() + { + if (!IsEnable()) + return; + + if (!m_isPressed) + { + SetCurrentVisual(&m_overVisual); + } + + PyCallClassMemberFunc(m_poHandler, "ShowToolTip", BuildEmptyTuple()); + } + void CRadioButton::OnMouseOverOut() + { + if (!IsEnable()) + return; + + if (!m_isPressed) + { + SetCurrentVisual(&m_upVisual); + } + + PyCallClassMemberFunc(m_poHandler, "HideToolTip", BuildEmptyTuple()); + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// + + CToggleButton::CToggleButton(PyObject * ppyObject) : CButton(ppyObject) + { + } + CToggleButton::~CToggleButton() + { + } + + BOOL CToggleButton::OnMouseLeftButtonDown() + { + if (!IsEnable()) + return TRUE; + + if (m_isPressed) + { + SetUp(); + if (IsIn()) + SetCurrentVisual(&m_overVisual); + else + SetCurrentVisual(&m_upVisual); + PyCallClassMemberFunc(m_poHandler, "OnToggleUp", BuildEmptyTuple()); + } + else + { + Down(); + PyCallClassMemberFunc(m_poHandler, "OnToggleDown", BuildEmptyTuple()); + } + + return TRUE; + } + BOOL CToggleButton::OnMouseLeftButtonUp() + { + return TRUE; + } + + void CToggleButton::OnMouseOverIn() + { + if (!IsEnable()) + return; + + if (!m_isPressed) + { + SetCurrentVisual(&m_overVisual); + } + + PyCallClassMemberFunc(m_poHandler, "ShowToolTip", BuildEmptyTuple()); + } + void CToggleButton::OnMouseOverOut() + { + if (!IsEnable()) + return; + + if (!m_isPressed) + { + SetCurrentVisual(&m_upVisual); + } + + PyCallClassMemberFunc(m_poHandler, "HideToolTip", BuildEmptyTuple()); + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// + + CDragButton::CDragButton(PyObject * ppyObject) : CButton(ppyObject) + { + CWindow::RemoveFlag(CWindow::FLAG_NOT_CAPTURE); + m_restrictArea.left = 0; + m_restrictArea.top = 0; + m_restrictArea.right = CWindowManager::Instance().GetScreenWidth(); + m_restrictArea.bottom = CWindowManager::Instance().GetScreenHeight(); + } + CDragButton::~CDragButton() + { + } + + void CDragButton::SetRestrictMovementArea(int ix, int iy, int iwidth, int iheight) + { + m_restrictArea.left = ix; + m_restrictArea.top = iy; + m_restrictArea.right = ix + iwidth; + m_restrictArea.bottom = iy + iheight; + } + + void CDragButton::OnChangePosition() + { + m_x = max(m_x, m_restrictArea.left); + m_y = max(m_y, m_restrictArea.top); + m_x = min(m_x, max(0, m_restrictArea.right - m_lWidth)); + m_y = min(m_y, max(0, m_restrictArea.bottom - m_lHeight)); + + m_rect.left = m_x; + m_rect.top = m_y; + + if (m_pParent) + { + const RECT & c_rRect = m_pParent->GetRect(); + m_rect.left += c_rRect.left; + m_rect.top += c_rRect.top; + } + + m_rect.right = m_rect.left + m_lWidth; + m_rect.bottom = m_rect.top + m_lHeight; + + std::for_each(m_pChildList.begin(), m_pChildList.end(), std::mem_fn(&CWindow::UpdateRect)); + + if (m_pcurVisual) + m_pcurVisual->SetPosition(m_rect.left, m_rect.top); + + if (IsPressed()) + PyCallClassMemberFunc(m_poHandler, "OnMove", BuildEmptyTuple()); + } + + void CDragButton::OnMouseOverIn() + { + if (!IsEnable()) + + return; + + CButton::OnMouseOverIn(); + PyCallClassMemberFunc(m_poHandler, "OnMouseOverIn", BuildEmptyTuple()); + } + + void CDragButton::OnMouseOverOut() + { + if (!IsEnable()) + return; + + CButton::OnMouseOverIn(); + PyCallClassMemberFunc(m_poHandler, "OnMouseOverOut", BuildEmptyTuple()); + } +}; diff --git a/source/EterPythonLib/PythonWindow.h b/source/EterPythonLib/PythonWindow.h new file mode 100644 index 0000000..ef8cb8a --- /dev/null +++ b/source/EterPythonLib/PythonWindow.h @@ -0,0 +1,525 @@ +#pragma once + +#include "../eterBase/Utils.h" + +namespace UI +{ + class CWindow + { + public: + typedef std::list TWindowContainer; + + static DWORD Type(); + BOOL IsType(DWORD dwType); + + enum EHorizontalAlign + { + HORIZONTAL_ALIGN_LEFT = 0, + HORIZONTAL_ALIGN_CENTER = 1, + HORIZONTAL_ALIGN_RIGHT = 2, + }; + + enum EVerticalAlign + { + VERTICAL_ALIGN_TOP = 0, + VERTICAL_ALIGN_CENTER = 1, + VERTICAL_ALIGN_BOTTOM = 2, + }; + + enum EFlags + { + FLAG_MOVABLE = (1 << 0), // ִ â + FLAG_LIMIT = (1 << 1), // â ȭ  + FLAG_SNAP = (1 << 2), // ִ â + FLAG_DRAGABLE = (1 << 3), + FLAG_ATTACH = (1 << 4), // θ پ ִ â (For Drag / ex. ScriptWindow) + FLAG_RESTRICT_X = (1 << 5), // ¿ ̵ + FLAG_RESTRICT_Y = (1 << 6), // ̵ + FLAG_NOT_CAPTURE = (1 << 7), + FLAG_FLOAT = (1 << 8), // ߿ ־ ġ Ǵ â + FLAG_NOT_PICK = (1 << 9), // 콺 Pick ʴ â + FLAG_IGNORE_SIZE = (1 << 10), + FLAG_RTL = (1 << 11), // Right-to-left + }; + + public: + CWindow(PyObject * ppyObject); + virtual ~CWindow(); + + void AddChild(CWindow * pWin); + + void Clear(); + void DestroyHandle(); + void Update(); + void Render(); + + void SetName(const char * c_szName); + const char * GetName() { return m_strName.c_str(); } + void SetSize(long width, long height); + long GetWidth() { return m_lWidth; } + long GetHeight() { return m_lHeight; } + + void SetHorizontalAlign(DWORD dwAlign); + void SetVerticalAlign(DWORD dwAlign); + void SetPosition(long x, long y); + void GetPosition(long * plx, long * ply); + long GetPositionX( void ) const { return m_x; } + long GetPositionY( void ) const { return m_y; } + RECT & GetRect() { return m_rect; } + void GetLocalPosition(long & rlx, long & rly); + void GetMouseLocalPosition(long & rlx, long & rly); + long UpdateRect(); + + RECT & GetLimitBias() { return m_limitBiasRect; } + void SetLimitBias(long l, long r, long t, long b) { m_limitBiasRect.left = l, m_limitBiasRect.right = r, m_limitBiasRect.top = t, m_limitBiasRect.bottom = b; } + + void Show(); + void Hide(); + bool IsShow() { return m_bShow; } + bool IsRendering(); + + bool HasParent() { return m_pParent ? true : false; } + bool HasChild() { return m_pChildList.empty() ? false : true; } + int GetChildCount() { return m_pChildList.size(); } + + CWindow * GetRoot(); + CWindow * GetParent(); + bool IsChild(CWindow * pWin); + void DeleteChild(CWindow * pWin); + void SetTop(CWindow * pWin); + + bool IsIn(long x, long y); + bool IsIn(); + CWindow * PickWindow(long x, long y); + CWindow * PickTopWindow(long x, long y); // NOTE : Children ʰ + // üũ ϴ Ưȭ Լ + + void __RemoveReserveChildren(); + + void AddFlag(DWORD flag) { SET_BIT(m_dwFlag, flag); } + void RemoveFlag(DWORD flag) { REMOVE_BIT(m_dwFlag, flag); } + bool IsFlag(DWORD flag) { return (m_dwFlag & flag) ? true : false; } + ///////////////////////////////////// + + virtual void OnRender(); + virtual void OnUpdate(); + virtual void OnChangePosition(){} + + virtual void OnSetFocus(); + virtual void OnKillFocus(); + + virtual void OnMouseDrag(long lx, long ly); + virtual void OnMouseOverIn(); + virtual void OnMouseOverOut(); + virtual void OnMouseOver(); + virtual void OnDrop(); + virtual void OnTop(); + virtual void OnIMEUpdate(); + + virtual void OnMoveWindow(long x, long y); + + /////////////////////////////////////// + + BOOL RunIMETabEvent(); + BOOL RunIMEReturnEvent(); + BOOL RunIMEKeyDownEvent(int ikey); + + CWindow * RunKeyDownEvent(int ikey); + BOOL RunKeyUpEvent(int ikey); + BOOL RunPressEscapeKeyEvent(); + BOOL RunPressExitKeyEvent(); + + virtual BOOL OnIMETabEvent(); + virtual BOOL OnIMEReturnEvent(); + virtual BOOL OnIMEKeyDownEvent(int ikey); + + virtual BOOL OnIMEChangeCodePage(); + virtual BOOL OnIMEOpenCandidateListEvent(); + virtual BOOL OnIMECloseCandidateListEvent(); + virtual BOOL OnIMEOpenReadingWndEvent(); + virtual BOOL OnIMECloseReadingWndEvent(); + + virtual BOOL OnMouseLeftButtonDown(); + virtual BOOL OnMouseLeftButtonUp(); + virtual BOOL OnMouseLeftButtonDoubleClick(); + virtual BOOL OnMouseRightButtonDown(); + virtual BOOL OnMouseRightButtonUp(); + virtual BOOL OnMouseRightButtonDoubleClick(); + virtual BOOL OnMouseMiddleButtonDown(); + virtual BOOL OnMouseMiddleButtonUp(); + + virtual BOOL OnKeyDown(int ikey); + virtual BOOL OnKeyUp(int ikey); + virtual BOOL OnPressEscapeKey(); + virtual BOOL OnPressExitKey(); + /////////////////////////////////////// + + virtual void SetColor(DWORD dwColor){} + virtual BOOL OnIsType(DWORD dwType); + ///////////////////////////////////// + + virtual BOOL IsWindow() { return TRUE; } + ///////////////////////////////////// + + protected: + std::string m_strName; + + EHorizontalAlign m_HorizontalAlign; + EVerticalAlign m_VerticalAlign; + long m_x, m_y; // X,Y ǥ + long m_lWidth, m_lHeight; // ũ + RECT m_rect; // Global ǥ + RECT m_limitBiasRect; // limit bias + + bool m_bMovable; + bool m_bShow; + + DWORD m_dwFlag; + + PyObject * m_poHandler; + + CWindow * m_pParent; + TWindowContainer m_pChildList; + + BOOL m_isUpdatingChildren; + TWindowContainer m_pReserveChildList; + +#ifdef _DEBUG + public: + DWORD DEBUG_dwCounter; +#endif + }; + + class CLayer : public CWindow + { + public: + CLayer(PyObject * ppyObject) : CWindow(ppyObject) {} + virtual ~CLayer() {} + + BOOL IsWindow() { return FALSE; } + }; + + class CBox : public CWindow + { + public: + CBox(PyObject * ppyObject); + virtual ~CBox(); + + void SetColor(DWORD dwColor); + + protected: + void OnRender(); + + protected: + DWORD m_dwColor; + }; + + class CBar : public CWindow + { + public: + CBar(PyObject * ppyObject); + virtual ~CBar(); + + void SetColor(DWORD dwColor); + + protected: + void OnRender(); + + protected: + DWORD m_dwColor; + }; + + class CLine : public CWindow + { + public: + CLine(PyObject * ppyObject); + virtual ~CLine(); + + void SetColor(DWORD dwColor); + + protected: + void OnRender(); + + protected: + DWORD m_dwColor; + }; + + class CBar3D : public CWindow + { + public: + static DWORD Type(); + + public: + CBar3D(PyObject * ppyObject); + virtual ~CBar3D(); + + void SetColor(DWORD dwLeft, DWORD dwRight, DWORD dwCenter); + + protected: + void OnRender(); + + protected: + DWORD m_dwLeftColor; + DWORD m_dwRightColor; + DWORD m_dwCenterColor; + }; + + // Text + class CTextLine : public CWindow + { + public: + CTextLine(PyObject * ppyObject); + virtual ~CTextLine(); + + void SetMax(int iMax); + void SetHorizontalAlign(int iType); + void SetVerticalAlign(int iType); + void SetSecret(BOOL bFlag); + void SetOutline(BOOL bFlag); + void SetFeather(BOOL bFlag); + void SetMultiLine(BOOL bFlag); + void SetFontName(const char * c_szFontName); + void SetFontColor(DWORD dwColor); + void SetLimitWidth(float fWidth); + + void ShowCursor(); + void HideCursor(); + int GetCursorPosition(); + + void SetText(const char * c_szText); + const char * GetText(); + + void GetTextSize(int* pnWidth, int* pnHeight); + + protected: + void OnUpdate(); + void OnRender(); + void OnChangePosition(); + + virtual void OnSetText(const char * c_szText); + + protected: + CGraphicTextInstance m_TextInstance; + }; + + class CNumberLine : public CWindow + { + public: + CNumberLine(PyObject * ppyObject); + CNumberLine(CWindow * pParent); + virtual ~CNumberLine(); + + void SetPath(const char * c_szPath); + void SetHorizontalAlign(int iType); + void SetNumber(const char * c_szNumber); + + protected: + void ClearNumber(); + void OnRender(); + void OnChangePosition(); + + protected: + std::string m_strPath; + std::string m_strNumber; + std::vector m_ImageInstanceVector; + + int m_iHorizontalAlign; + DWORD m_dwWidthSummary; + }; + + // Image + class CImageBox : public CWindow + { + public: + CImageBox(PyObject * ppyObject); + virtual ~CImageBox(); + + BOOL LoadImage(const char * c_szFileName); + void SetDiffuseColor(float fr, float fg, float fb, float fa); + + int GetWidth(); + int GetHeight(); + + protected: + virtual void OnCreateInstance(); + virtual void OnDestroyInstance(); + + virtual void OnUpdate(); + virtual void OnRender(); + void OnChangePosition(); + + protected: + CGraphicImageInstance * m_pImageInstance; + }; + class CMarkBox : public CWindow + { + public: + CMarkBox(PyObject * ppyObject); + virtual ~CMarkBox(); + + void LoadImage(const char * c_szFilename); + void SetDiffuseColor(float fr, float fg, float fb, float fa); + void SetIndex(UINT uIndex); + void SetScale(FLOAT fScale); + + protected: + virtual void OnCreateInstance(); + virtual void OnDestroyInstance(); + + virtual void OnUpdate(); + virtual void OnRender(); + void OnChangePosition(); + protected: + CGraphicMarkInstance * m_pMarkInstance; + }; + class CExpandedImageBox : public CImageBox + { + public: + static DWORD Type(); + + public: + CExpandedImageBox(PyObject * ppyObject); + virtual ~CExpandedImageBox(); + + void SetScale(float fx, float fy); + void SetOrigin(float fx, float fy); + void SetRotation(float fRotation); + void SetRenderingRect(float fLeft, float fTop, float fRight, float fBottom); + void SetRenderingMode(int iMode); + + protected: + void OnCreateInstance(); + void OnDestroyInstance(); + + virtual void OnUpdate(); + virtual void OnRender(); + + BOOL OnIsType(DWORD dwType); + }; + class CAniImageBox : public CWindow + { + public: + static DWORD Type(); + + public: + CAniImageBox(PyObject * ppyObject); + virtual ~CAniImageBox(); + + void SetDelay(int iDelay); + void AppendImage(const char * c_szFileName); + void SetRenderingRect(float fLeft, float fTop, float fRight, float fBottom); + void SetRenderingMode(int iMode); + + void ResetFrame(); + + protected: + void OnUpdate(); + void OnRender(); + void OnChangePosition(); + virtual void OnEndFrame(); + + BOOL OnIsType(DWORD dwType); + + protected: + BYTE m_bycurDelay; + BYTE m_byDelay; + BYTE m_bycurIndex; + std::vector m_ImageVector; + }; + + // Button + class CButton : public CWindow + { + public: + CButton(PyObject * ppyObject); + virtual ~CButton(); + + BOOL SetUpVisual(const char * c_szFileName); + BOOL SetOverVisual(const char * c_szFileName); + BOOL SetDownVisual(const char * c_szFileName); + BOOL SetDisableVisual(const char * c_szFileName); + + const char * GetUpVisualFileName(); + const char * GetOverVisualFileName(); + const char * GetDownVisualFileName(); + + void Flash(); + void Enable(); + void Disable(); + + void SetUp(); + void Up(); + void Over(); + void Down(); + + BOOL IsDisable(); + BOOL IsPressed(); + + protected: + void OnUpdate(); + void OnRender(); + void OnChangePosition(); + + BOOL OnMouseLeftButtonDown(); + BOOL OnMouseLeftButtonDoubleClick(); + BOOL OnMouseLeftButtonUp(); + void OnMouseOverIn(); + void OnMouseOverOut(); + + BOOL IsEnable(); + + void SetCurrentVisual(CGraphicImageInstance * pVisual); + + protected: + BOOL m_bEnable; + BOOL m_isPressed; + BOOL m_isFlash; + CGraphicImageInstance * m_pcurVisual; + CGraphicImageInstance m_upVisual; + CGraphicImageInstance m_overVisual; + CGraphicImageInstance m_downVisual; + CGraphicImageInstance m_disableVisual; + }; + class CRadioButton : public CButton + { + public: + CRadioButton(PyObject * ppyObject); + virtual ~CRadioButton(); + + protected: + BOOL OnMouseLeftButtonDown(); + BOOL OnMouseLeftButtonUp(); + void OnMouseOverIn(); + void OnMouseOverOut(); + }; + class CToggleButton : public CButton + { + public: + CToggleButton(PyObject * ppyObject); + virtual ~CToggleButton(); + + protected: + BOOL OnMouseLeftButtonDown(); + BOOL OnMouseLeftButtonUp(); + void OnMouseOverIn(); + void OnMouseOverOut(); + }; + class CDragButton : public CButton + { + public: + CDragButton(PyObject * ppyObject); + virtual ~CDragButton(); + + void SetRestrictMovementArea(int ix, int iy, int iwidth, int iheight); + + protected: + void OnChangePosition(); + void OnMouseOverIn(); + void OnMouseOverOut(); + + protected: + RECT m_restrictArea; + }; +}; + +extern BOOL g_bOutlineBoxEnable; diff --git a/source/EterPythonLib/PythonWindowManager.cpp b/source/EterPythonLib/PythonWindowManager.cpp new file mode 100644 index 0000000..1b48e84 --- /dev/null +++ b/source/EterPythonLib/PythonWindowManager.cpp @@ -0,0 +1,1255 @@ +#include "StdAfx.h" +#include "PythonWindow.h" +#include "PythonSlotWindow.h" +#include "PythonGridSlotWindow.h" +#include "PythonWindowManager.h" + +//#define __WINDOW_LEAK_CHECK__ + +BOOL g_bShowOverInWindowName = FALSE; + +namespace UI +{ + static PyObject* gs_poEmptyTuple = NULL; + + PyObject * BuildEmptyTuple() + { + Py_INCREF(gs_poEmptyTuple); + return gs_poEmptyTuple; + } + + std::set gs_kSet_pkWnd; + + CWindowManager::CWindowManager() + : + m_pActiveWindow(NULL), + m_pPointWindow(NULL), + m_pLeftCaptureWindow(NULL), + m_pMiddleCaptureWindow(NULL), + m_pRightCaptureWindow(NULL), + m_pLockWindow(NULL), + m_bAttachingFlag(FALSE), + m_dwAttachingType(0), + m_dwAttachingIndex(0), + m_dwAttachingSlotNumber(0), + m_poMouseHandler(NULL), + m_iHres(0), + m_iVres(0), + m_bOnceIgnoreMouseLeftButtonUpEventFlag(FALSE) + { + m_pRootWindow = new CWindow(NULL); + m_pRootWindow->SetName("root"); + m_pRootWindow->Show(); + + const char * layerTbl[] = {"GAME","UI_BOTTOM","UI","TOP_MOST","CURTAIN"}; + + for(DWORD layer = 0; layer < sizeof(layerTbl)/sizeof(layerTbl[0]); layer++) + { + CWindow * pLayer = new CLayer(NULL); + pLayer->SetName(layerTbl[layer]); + pLayer->Show(); + m_LayerWindowMap.insert(TLayerContainer::value_type(layerTbl[layer], pLayer)); + m_pRootWindow->AddChild(pLayer); + m_LayerWindowList.push_back(pLayer); + } + + m_ActiveWindowList.clear(); + m_LockWindowList.clear(); + + gs_poEmptyTuple = Py_BuildValue("()"); + } + + CWindowManager::~CWindowManager() + { + Py_DECREF(gs_poEmptyTuple); + + stl_wipe_second(m_LayerWindowMap); + m_LayerWindowMap.clear(); + m_LayerWindowList.clear(); + m_KeyCaptureWindowMap.clear(); + + delete m_pRootWindow; + m_pRootWindow = NULL; + } + + void CWindowManager::Destroy() + { + __ClearReserveDeleteWindowList(); +#ifdef __WINDOW_LEAK_CHECK__ + std::set::iterator i; + for (i=gs_kSet_pkWnd.begin(); i!=gs_kSet_pkWnd.end(); ++i) + { + CWindow* pkWnd=*i; + Logf(1, "CWindowManager::Destroy LOST WINDOW %s\n", pkWnd->GetName()); + } +#endif + + } + + void CWindowManager::SetMouseHandler(PyObject * poMouseHandler) + { + m_poMouseHandler = poMouseHandler; + } + + CWindow * CWindowManager::RegisterWindow(PyObject * po, const char * c_szLayer) + { + assert(m_LayerWindowMap.end() != m_LayerWindowMap.find(c_szLayer)); + + CWindow * pWin = new CWindow(po); + m_LayerWindowMap[c_szLayer]->AddChild(pWin); +#ifdef __WINDOW_LEAK_CHECK__ + gs_kSet_pkWnd.insert(pWin); +#endif + return (pWin); + } + + CWindow * CWindowManager::__NewWindow(PyObject * po, DWORD dwWndType) + { + switch(dwWndType) + { + case WT_SLOT: + return new CSlotWindow(po); + break; + case WT_GRIDSLOT: + return new CGridSlotWindow(po); + break; + case WT_TEXTLINE: + return new CTextLine(po); + break; + case WT_MARKBOX: + return new CMarkBox(po); + break; + case WT_IMAGEBOX: + return new CImageBox(po); + break; + case WT_EXP_IMAGEBOX: + return new CExpandedImageBox(po); + break; + case WT_ANI_IMAGEBOX: + return new CAniImageBox(po); + break; + case WT_BUTTON: + return new CButton(po); + break; + case WT_RATIOBUTTON: + return new CRadioButton(po); + break; + case WT_TOGGLEBUTTON: + return new CToggleButton(po); + break; + case WT_DRAGBUTTON: + return new CDragButton(po); + break; + case WT_BOX: + return new CBox(po); + break; + case WT_BAR: + return new CBar(po); + break; + case WT_LINE: + return new CLine(po); + break; + case WT_BAR3D: + return new CBar3D(po); + break; + case WT_NUMLINE: + return new CNumberLine(po); + break; + default: + assert(!"CWindowManager::__NewWindow"); + break; + } + return new CWindow(po); + } + + CWindow * CWindowManager::RegisterTypeWindow(PyObject * po, DWORD dwWndType, const char * c_szLayer) + { + assert(m_LayerWindowMap.end() != m_LayerWindowMap.find(c_szLayer)); + + CWindow * pWin = __NewWindow(po, dwWndType); + m_LayerWindowMap[c_szLayer]->AddChild(pWin); + +#ifdef __WINDOW_LEAK_CHECK__ + gs_kSet_pkWnd.insert(pWin); +#endif + return pWin; + } + + CWindow * CWindowManager::RegisterSlotWindow(PyObject * po, const char * c_szLayer) + { + assert(m_LayerWindowMap.end() != m_LayerWindowMap.find(c_szLayer)); + + CWindow * pWin = new CSlotWindow(po); + m_LayerWindowMap[c_szLayer]->AddChild(pWin); + +#ifdef __WINDOW_LEAK_CHECK__ + gs_kSet_pkWnd.insert(pWin); +#endif + return pWin; + } + + CWindow * CWindowManager::RegisterGridSlotWindow(PyObject * po, const char * c_szLayer) + { + assert(m_LayerWindowMap.end() != m_LayerWindowMap.find(c_szLayer)); + + CWindow * pWin = new CGridSlotWindow(po); + m_LayerWindowMap[c_szLayer]->AddChild(pWin); + +#ifdef __WINDOW_LEAK_CHECK__ + gs_kSet_pkWnd.insert(pWin); +#endif + return pWin; + } + + CWindow * CWindowManager::RegisterTextLine(PyObject * po, const char * c_szLayer) + { + assert(m_LayerWindowMap.end() != m_LayerWindowMap.find(c_szLayer)); + + CWindow * pWin = new CTextLine(po); + m_LayerWindowMap[c_szLayer]->AddChild(pWin); + +#ifdef __WINDOW_LEAK_CHECK__ + gs_kSet_pkWnd.insert(pWin); +#endif + return pWin; + } + + CWindow * CWindowManager::RegisterImageBox(PyObject * po, const char * c_szLayer) + { + assert(m_LayerWindowMap.end() != m_LayerWindowMap.find(c_szLayer)); + + CWindow * pWin = new CImageBox(po); + m_LayerWindowMap[c_szLayer]->AddChild(pWin); + +#ifdef __WINDOW_LEAK_CHECK__ + gs_kSet_pkWnd.insert(pWin); +#endif + return pWin; + } + + CWindow * CWindowManager::RegisterMarkBox(PyObject * po, const char * c_szLayer) + { + assert(m_LayerWindowMap.end() != m_LayerWindowMap.find(c_szLayer)); + + CWindow * pWin = new CMarkBox(po); + m_LayerWindowMap[c_szLayer]->AddChild(pWin); + +#ifdef __WINDOW_LEAK_CHECK__ + gs_kSet_pkWnd.insert(pWin); +#endif + return pWin; + } + + CWindow * CWindowManager::RegisterExpandedImageBox(PyObject * po, const char * c_szLayer) + { + assert(m_LayerWindowMap.end() != m_LayerWindowMap.find(c_szLayer)); + + CWindow * pWin = new CExpandedImageBox(po); + m_LayerWindowMap[c_szLayer]->AddChild(pWin); + +#ifdef __WINDOW_LEAK_CHECK__ + gs_kSet_pkWnd.insert(pWin); +#endif + return pWin; + } + + CWindow * CWindowManager::RegisterAniImageBox(PyObject * po, const char * c_szLayer) + { + assert(m_LayerWindowMap.end() != m_LayerWindowMap.find(c_szLayer)); + + CWindow * pWin = new CAniImageBox(po); + m_LayerWindowMap[c_szLayer]->AddChild(pWin); + +#ifdef __WINDOW_LEAK_CHECK__ + gs_kSet_pkWnd.insert(pWin); +#endif + return pWin; + } + + CWindow * CWindowManager::RegisterButton(PyObject * po, const char * c_szLayer) + { + assert(m_LayerWindowMap.end() != m_LayerWindowMap.find(c_szLayer)); + + CWindow * pWin = new CButton(po); + m_LayerWindowMap[c_szLayer]->AddChild(pWin); + +#ifdef __WINDOW_LEAK_CHECK__ + gs_kSet_pkWnd.insert(pWin); +#endif + return pWin; + } + + CWindow * CWindowManager::RegisterRadioButton(PyObject * po, const char * c_szLayer) + { + assert(m_LayerWindowMap.end() != m_LayerWindowMap.find(c_szLayer)); + + CWindow * pWin = new CRadioButton(po); + m_LayerWindowMap[c_szLayer]->AddChild(pWin); + +#ifdef __WINDOW_LEAK_CHECK__ + gs_kSet_pkWnd.insert(pWin); +#endif + return pWin; + } + + CWindow * CWindowManager::RegisterToggleButton(PyObject * po, const char * c_szLayer) + { + assert(m_LayerWindowMap.end() != m_LayerWindowMap.find(c_szLayer)); + + CWindow * pWin = new CToggleButton(po); + m_LayerWindowMap[c_szLayer]->AddChild(pWin); + +#ifdef __WINDOW_LEAK_CHECK__ + gs_kSet_pkWnd.insert(pWin); +#endif + return pWin; + } + + CWindow * CWindowManager::RegisterDragButton(PyObject * po, const char * c_szLayer) + { + assert(m_LayerWindowMap.end() != m_LayerWindowMap.find(c_szLayer)); + + CWindow * pWin = new CDragButton(po); + m_LayerWindowMap[c_szLayer]->AddChild(pWin); + +#ifdef __WINDOW_LEAK_CHECK__ + gs_kSet_pkWnd.insert(pWin); +#endif + return pWin; + } + + CWindow * CWindowManager::RegisterBox(PyObject * po, const char * c_szLayer) + { + assert(m_LayerWindowMap.end() != m_LayerWindowMap.find(c_szLayer)); + + CWindow * pWin = new CBox(po); + m_LayerWindowMap[c_szLayer]->AddChild(pWin); + +#ifdef __WINDOW_LEAK_CHECK__ + gs_kSet_pkWnd.insert(pWin); +#endif + return pWin; + } + + CWindow * CWindowManager::RegisterBar(PyObject * po, const char * c_szLayer) + { + assert(m_LayerWindowMap.end() != m_LayerWindowMap.find(c_szLayer)); + + CWindow * pWin = new CBar(po); + m_LayerWindowMap[c_szLayer]->AddChild(pWin); + +#ifdef __WINDOW_LEAK_CHECK__ + gs_kSet_pkWnd.insert(pWin); +#endif + return pWin; + } + + CWindow * CWindowManager::RegisterLine(PyObject * po, const char * c_szLayer) + { + assert(m_LayerWindowMap.end() != m_LayerWindowMap.find(c_szLayer)); + + CWindow * pWin = new CLine(po); + m_LayerWindowMap[c_szLayer]->AddChild(pWin); + +#ifdef __WINDOW_LEAK_CHECK__ + gs_kSet_pkWnd.insert(pWin); +#endif + return pWin; + } + + CWindow * CWindowManager::RegisterBar3D(PyObject * po, const char * c_szLayer) + { + assert(m_LayerWindowMap.end() != m_LayerWindowMap.find(c_szLayer)); + + CWindow * pWin = new CBar3D(po); + m_LayerWindowMap[c_szLayer]->AddChild(pWin); + +#ifdef __WINDOW_LEAK_CHECK__ + gs_kSet_pkWnd.insert(pWin); +#endif + return pWin; + } + + CWindow * CWindowManager::RegisterNumberLine(PyObject * po, const char * c_szLayer) + { + assert(m_LayerWindowMap.end() != m_LayerWindowMap.find(c_szLayer)); + + CWindow * pWin = new CNumberLine(po); + m_LayerWindowMap[c_szLayer]->AddChild(pWin); + +#ifdef __WINDOW_LEAK_CHECK__ + gs_kSet_pkWnd.insert(pWin); +#endif + return pWin; + } + + void CWindowManager::NotifyDestroyWindow(CWindow * pWindow) + { + if (pWindow == m_pActiveWindow) + m_pActiveWindow = NULL; + + if (pWindow == m_pPointWindow) + m_pPointWindow = NULL; + + if (pWindow == m_pLeftCaptureWindow) + m_pLeftCaptureWindow = NULL; + + if (pWindow == m_pMiddleCaptureWindow) + m_pMiddleCaptureWindow = NULL; + + if (pWindow == m_pRightCaptureWindow) + m_pRightCaptureWindow = NULL; + + if (pWindow == m_pLockWindow) + m_pLockWindow = NULL; + + m_LockWindowList.remove(pWindow); + m_ActiveWindowList.remove(pWindow); + m_PickAlwaysWindowList.remove(pWindow); + + TKeyCaptureWindowMap::iterator itor = m_KeyCaptureWindowMap.begin(); + for (; itor != m_KeyCaptureWindowMap.end();) + { + if (pWindow == itor->second) + { + itor = m_KeyCaptureWindowMap.erase(itor); + } + else + { + ++itor; + } + } + } + + void CWindowManager::DestroyWindow(CWindow * pWin) + { + NotifyDestroyWindow(pWin); + if (pWin->HasParent()) + { + CWindow * pParentWin = pWin->GetParent(); + pParentWin->DeleteChild(pWin); + } + pWin->Clear(); + m_ReserveDeleteWindowList.push_back(pWin); + } + + BOOL CWindowManager::IsDragging() + { + long ldx = abs(m_lMouseX - m_lPickedX); + long ldy = abs(m_lMouseY - m_lPickedY); + if (ldx+ldy < 10) + return FALSE; + + return TRUE; + } + + BOOL CWindowManager::IsAttaching() + { + return m_bAttachingFlag; + } + + DWORD CWindowManager::GetAttachingType() + { + return m_dwAttachingType; + } + + DWORD CWindowManager::GetAttachingIndex() + { + return m_dwAttachingIndex; + } + + DWORD CWindowManager::GetAttachingSlotNumber() + { + return m_dwAttachingSlotNumber; + } + + void CWindowManager::GetAttachingIconSize(BYTE * pbyWidth, BYTE * pbyHeight) + { + *pbyWidth = m_byAttachingIconWidth; + *pbyHeight = m_byAttachingIconHeight; + } + + void CWindowManager::AttachIcon(DWORD dwType, DWORD dwIndex, DWORD dwSlotNumber, BYTE byWidth, BYTE byHeight) + { + m_bAttachingFlag = TRUE; + m_dwAttachingType = dwType; + m_dwAttachingIndex = dwIndex; + m_dwAttachingSlotNumber = dwSlotNumber; + + m_byAttachingIconWidth = byWidth; + m_byAttachingIconHeight = byHeight; + } + + void CWindowManager::SetAttachingFlag(BOOL bFlag) + { + m_bAttachingFlag = bFlag; + } + + void CWindowManager::DeattachIcon() + { + SetAttachingFlag(FALSE); + if (m_poMouseHandler) + PyCallClassMemberFunc(m_poMouseHandler, "DeattachObject", BuildEmptyTuple()); + } + + void CWindowManager::SetParent(CWindow * pWindow, CWindow * pParentWindow) + { + if (!pWindow) + { + assert(!"CWindowManager::SetParent - There is no self window!"); + return; + } + if (!pParentWindow) + { + assert(!"There is no parent window"); + return; + } + + if (pWindow->HasParent()) + { + CWindow * pOldParentWindow = pWindow->GetParent(); + + if (pParentWindow == pOldParentWindow) + return; + + pOldParentWindow->DeleteChild(pWindow); + } + + pParentWindow->AddChild(pWindow); + } + + void CWindowManager::SetPickAlways(CWindow * pWindow) + { + m_PickAlwaysWindowList.push_back(pWindow); + } + + void CWindowManager::OnceIgnoreMouseLeftButtonUpEvent() + { + m_bOnceIgnoreMouseLeftButtonUpEventFlag = TRUE; + m_iIgnoreEndTime = timeGetTime() + 500; + } + + void CWindowManager::LockWindow(CWindow * pWin) + { + if (m_pActiveWindow) + m_pActiveWindow->OnKillFocus(); + + // ̹ 츮Ʈȿ ִٸ Ѵ.. + m_LockWindowList.remove(pWin); + + if (m_pLockWindow) + { + if (m_pLockWindow==pWin) + return; + + m_LockWindowList.push_back(m_pLockWindow); + } + + m_pLockWindow = pWin; + } + + void CWindowManager::UnlockWindow() + { + if (m_pLockWindow) + { + if (m_LockWindowList.empty()) + { + m_pLockWindow = NULL; + if (m_pActiveWindow) + m_pActiveWindow->OnSetFocus(); + } + else + { + m_pLockWindow = m_LockWindowList.back(); + m_LockWindowList.pop_back(); + } + } + } + + void CWindowManager::ActivateWindow(CWindow * pWin) + { + m_ActiveWindowList.remove(pWin); + + if (pWin == m_pActiveWindow) + return; + + if (m_pActiveWindow) + { + // NOTE : Window Clear ұ? + // ϴ ߺ ȵǸ Ŀ Ǵ ü 5 ̸̴ ʿ .. - [levites] + m_ActiveWindowList.push_back(m_pActiveWindow); + m_pActiveWindow->OnKillFocus(); + } + + m_pActiveWindow = pWin; + + if (m_pActiveWindow) + { + m_pActiveWindow->OnSetFocus(); + } + } + + void CWindowManager::DeactivateWindow() + { + if (m_pActiveWindow) + { + if (m_ActiveWindowList.empty()) + { + m_pActiveWindow->OnKillFocus(); + m_pActiveWindow = NULL; + } + else + { + m_pActiveWindow->OnKillFocus(); + + m_pActiveWindow = m_ActiveWindowList.back(); + m_ActiveWindowList.pop_back(); + + m_pActiveWindow->OnSetFocus(); + } + } + } + + void CWindowManager::SetTop(CWindow * pWin) + { + if (!pWin->HasParent()) + return; + + CWindow * pParentWindow = pWin->GetParent(); + pParentWindow->SetTop(pWin); + + // NOTE : Capture µȴ..? - [levites] + // NOTE : κ丮 巡 ؼ ۿ ĸ簡 Ƽ â ư ι ϴ ׸ ߰ +// ResetCapture(); + } + + void CWindowManager::SetTopUIWindow() + { + if (m_pLockWindow) + return; + + // GameLayer ִ 찡 ŷ ƴٸ SetTop ش. + TLayerContainer::iterator itor = m_LayerWindowMap.find("UI"); + if (itor == m_LayerWindowMap.end()) + return; + CWindow * pGameLayer = itor->second; + CWindow * pTopWindow = pGameLayer->PickTopWindow(m_lMouseX, m_lMouseY); + if (pTopWindow) + { + SetTop(pTopWindow); + } + } + + CWindow * CWindowManager::GetActivateWindow() + { + return m_pActiveWindow; + } + + void CWindowManager::ResetCapture() + { + m_pLeftCaptureWindow = NULL; + m_pMiddleCaptureWindow = NULL; + m_pRightCaptureWindow = NULL; + } + + void CWindowManager::SetResolution(int hres, int vres) + { + if (hres<=0 || vres<=0) + return; + + m_iHres = hres; + m_iVres = vres; + } + + float CWindowManager::GetAspect() + { + return (m_iHres)/float(m_iVres); + } + + void CWindowManager::SetScreenSize(long lWidth, long lHeight) + { + m_lWidth = lWidth; + m_lHeight = lHeight; + + for (TLayerContainer::iterator itor = m_LayerWindowMap.begin(); itor != m_LayerWindowMap.end(); ++itor) + { + itor->second->SetSize(lWidth, lHeight); + } + } + + void CWindowManager::__ClearReserveDeleteWindowList() + { + for (TWindowContainer::iterator itor = m_ReserveDeleteWindowList.begin(); itor != m_ReserveDeleteWindowList.end(); ++itor) + { + CWindow * pWin = *itor; +#ifdef __WINDOW_LEAK_CHECK__ + gs_kSet_pkWnd.erase(pWin); +#endif + delete pWin; + } + m_ReserveDeleteWindowList.clear(); + + } + + void CWindowManager::Update() + { + __ClearReserveDeleteWindowList(); + + m_pRootWindow->Update(); + } + + void CWindowManager::Render() + { + m_pRootWindow->Render(); + } + + CWindow * CWindowManager::__PickWindow(long x, long y) + { + if (m_pLockWindow) + { + return m_pLockWindow->PickWindow(x, y); + } + + for (TWindowContainer::iterator itor = m_PickAlwaysWindowList.begin(); itor != m_PickAlwaysWindowList.end(); ++itor) + { + CWindow * pWindow = *itor; + if (pWindow->IsRendering()) + if (pWindow->IsIn(x, y)) + return pWindow; + } + + for (TWindowContainer::reverse_iterator ritor = m_LayerWindowList.rbegin(); ritor != m_LayerWindowList.rend(); ++ritor) + { + CWindow * pLayer = *ritor; + CWindow * pPickedWindow = pLayer->PickWindow(x, y); + + if (pPickedWindow != pLayer) + return pPickedWindow; + } + + return NULL; + } + + void CWindowManager::SetMousePosition(long x, long y) + { + if (m_iHres==0) + return; + + if (m_iVres==0) + return; + + m_lMouseX = m_lWidth * x / m_iHres; + m_lMouseY = m_lHeight * y / m_iVres; + } + + void CWindowManager::GetMousePosition(long & rx, long & ry) + { + rx = m_lMouseX; + ry = m_lMouseY; + } + + void CWindowManager::RunMouseMove(long x, long y) + { + if (IsAttaching()) + { + if (x > m_lWidth) + x = m_lWidth; + if (y > m_lHeight) + y = m_lHeight; + } + + SetMousePosition(x, y); + CWindow * pPointWindow = __PickWindow(m_lMouseX, m_lMouseY); + + if (g_bShowOverInWindowName) + { + if (pPointWindow) + { + static std::string strPickWindowName = ""; + if (0 != strPickWindowName.compare(pPointWindow->GetName())) + { + Tracef(" OverInWindowName [%s]\n", pPointWindow->GetName()); + strPickWindowName = pPointWindow->GetName(); + } + } + } + + if (m_pLeftCaptureWindow) + { + CWindow * pWin = m_pLeftCaptureWindow; + + if (pWin->IsFlag(CWindow::FLAG_MOVABLE)) + { + long x = m_lMouseX - m_lDragX; + long y = m_lMouseY - m_lDragY; + if (pWin->HasParent()) + { + x -= pWin->GetParent()->GetRect().left; + y -= pWin->GetParent()->GetRect().top; + } + + long lx, ly; + pWin->GetPosition(&lx, &ly); + if (pWin->IsFlag(CWindow::FLAG_RESTRICT_X)) + { + x = lx; + } + if (pWin->IsFlag(CWindow::FLAG_RESTRICT_Y)) + { + y = ly; + } + + if (pWin->IsFlag(CWindow::FLAG_LIMIT)) + { + RECT limitRect = pWin->GetLimitBias(); + + limitRect.right = m_lWidth - limitRect.right; + limitRect.bottom = m_lHeight - limitRect.bottom; + + if (x < limitRect.left) + x = limitRect.left; + else if (x + pWin->GetWidth() >= limitRect.right) + x = limitRect.right - pWin->GetWidth(); + + if (y < limitRect.top) + y = limitRect.top; + else if (y + pWin->GetHeight() >= limitRect.bottom) + y = limitRect.bottom - pWin->GetHeight(); + } + + pWin->SetPosition(x, y); + pWin->OnMoveWindow(x, y); + } + else if (m_pLeftCaptureWindow->IsFlag(CWindow::FLAG_DRAGABLE)) + { + long x = m_lMouseX - m_lDragX; + long y = m_lMouseY - m_lDragY; + m_pLeftCaptureWindow->OnMouseDrag(x, y); + } + } + + if (m_pPointWindow != pPointWindow) + { +#ifdef _DEBUG + if (pPointWindow && pPointWindow->GetName()) + Tracenf("PointWindow: %s", pPointWindow->GetName()); +#endif + if (m_pPointWindow) + m_pPointWindow->OnMouseOverOut(); + + m_pPointWindow = pPointWindow; + + if (m_pPointWindow) + m_pPointWindow->OnMouseOverIn(); + } + + if (m_pPointWindow) + { + m_pPointWindow->OnMouseOver(); + } + } + + void CWindowManager::RunMouseLeftButtonDown(long x, long y) + { + SetTopUIWindow(); + + ///// + + SetMousePosition(x, y); + CWindow * pWin = GetPointWindow(); + + if (!pWin) + return; + + // Attach + if (pWin->IsFlag(CWindow::FLAG_ATTACH)) + pWin = pWin->GetRoot(); + + // Drag + if (!pWin->IsFlag(CWindow::FLAG_NOT_CAPTURE)) + m_pLeftCaptureWindow = pWin; + + m_lDragX = m_lMouseX - pWin->GetRect().left; + m_lDragY = m_lMouseY - pWin->GetRect().top; + m_lPickedX = m_lMouseX; + m_lPickedY = m_lMouseY; + + // Event + pWin->OnMouseLeftButtonDown(); + } + + void CWindowManager::RunMouseLeftButtonUp(long x, long y) + { + if (m_bOnceIgnoreMouseLeftButtonUpEventFlag) + { + m_bOnceIgnoreMouseLeftButtonUpEventFlag = FALSE; + + if (timeGetTime() < m_iIgnoreEndTime) + { + return; + } + } + + SetMousePosition(x, y); + + if (m_pLeftCaptureWindow) + { + if (m_pLeftCaptureWindow->OnMouseLeftButtonUp()) + { + // NOTE : ⼭ m_pLeftCaptureWindow NULL ֽϴ!! - [levites] + m_pLeftCaptureWindow = NULL; + return; + } + } + + CWindow * pWin = GetPointWindow(); + if (pWin) + pWin->OnMouseLeftButtonUp(); + + m_pLeftCaptureWindow = NULL; + } + + void CWindowManager::RunMouseLeftButtonDoubleClick(long x, long y) + { + SetMousePosition(x, y); + + CWindow * pWin = GetPointWindow(); + if (!pWin) + return; + + pWin->OnMouseLeftButtonDoubleClick(); + } + + void CWindowManager::RunMouseRightButtonDown(long x, long y) + { + SetTopUIWindow(); + + /////////////////////////////////////////////////////////////////////////////////////////// + + SetMousePosition(x, y); + CWindow * pWin = GetPointWindow(); + if (!pWin) + return; + + // Attach + if (pWin->IsFlag(CWindow::FLAG_ATTACH)) + pWin = pWin->GetRoot(); + + // Drag + if (!pWin->IsFlag(CWindow::FLAG_NOT_CAPTURE)) + m_pRightCaptureWindow = pWin; + + pWin->OnMouseRightButtonDown(); + } + + void CWindowManager::RunMouseRightButtonUp(long x, long y) + { + if (m_pRightCaptureWindow) + { + if (m_pRightCaptureWindow->OnMouseRightButtonUp()) + { + m_pRightCaptureWindow = NULL; + return; + } + } + + CWindow * pWin = GetPointWindow(); + if (pWin) + pWin->OnMouseRightButtonUp(); + + m_pRightCaptureWindow = NULL; + DeattachIcon(); + } + + void CWindowManager::RunMouseRightButtonDoubleClick(long x, long y) + { + SetMousePosition(x, y); + + CWindow * pWin = GetPointWindow(); + if (pWin) + { + pWin->OnMouseRightButtonDoubleClick(); + } + } + + void CWindowManager::RunMouseMiddleButtonDown(long x, long y) + { + SetMousePosition(x, y); + + CWindow * pWin = GetPointWindow(); + if (!pWin) + return; + + m_pMiddleCaptureWindow = pWin; + + pWin->OnMouseMiddleButtonDown(); + } + + void CWindowManager::RunMouseMiddleButtonUp(long x, long y) + { + SetMousePosition(x, y); + + if (m_pMiddleCaptureWindow) + { + if (m_pMiddleCaptureWindow->OnMouseMiddleButtonUp()) + { + m_pMiddleCaptureWindow = NULL; + return; + } + } + + CWindow * pWin = GetPointWindow(); + if (!pWin) + return; + + pWin->OnMouseMiddleButtonUp(); + m_pMiddleCaptureWindow = NULL; + } + + // IME + void CWindowManager::RunIMEUpdate() + { + if (m_pLockWindow) + { + m_pLockWindow->OnIMEUpdate(); + return; + } + + if (!m_pActiveWindow) + return; + if (!m_pActiveWindow->IsRendering()) + return; + + m_pActiveWindow->OnIMEUpdate(); + } + + void CWindowManager::RunIMETabEvent() + { + if (m_pLockWindow) + { + m_pLockWindow->OnIMETabEvent(); + return; + } + if (m_pActiveWindow) + if (m_pActiveWindow->IsRendering()) + { + if (m_pActiveWindow->OnIMETabEvent()) + return; + } + + if (!m_pRootWindow->RunIMETabEvent()) + { + if (!m_ActiveWindowList.empty()) + { + CWindow * pWindow = *(m_ActiveWindowList.begin()); + ActivateWindow(pWindow); + + ///////////////////////////////////////////// + + CWindow * pParentWindow = pWindow; + CWindow * pCurrentWindow = pWindow->GetParent(); + + DWORD dwMaxLoopCount = 20; + for (DWORD i = 0; i < dwMaxLoopCount; ++i) + { + if (!pParentWindow) + break; + + if (pParentWindow == m_LayerWindowMap["GAME"]) + { + SetTop(pCurrentWindow); + break; + } + + pCurrentWindow = pParentWindow; + pParentWindow = pCurrentWindow->GetParent(); + } + } + } + } + + void CWindowManager::RunIMEReturnEvent() + { + if (m_pLockWindow) + { + m_pLockWindow->OnIMEReturnEvent(); + return; + } + if (m_pActiveWindow) + if (m_pActiveWindow->IsRendering()) + { + if (m_pActiveWindow->OnIMEReturnEvent()) + return; + } + + m_pRootWindow->RunIMEReturnEvent(); + } + + void CWindowManager::RunIMEKeyDown(int vkey) + { + if (m_pLockWindow) + { + m_pLockWindow->OnKeyDown(vkey); + return; + } + if (m_pActiveWindow) + if (m_pActiveWindow->IsRendering()) + { + if (m_pActiveWindow->OnIMEKeyDownEvent(vkey)) + return; + } + + // NOTE : ü ʰ ActivateǾִ EditLine ̺Ʈ + } + + void CWindowManager::RunChangeCodePage() + { + if (m_pActiveWindow) + if (m_pActiveWindow->IsRendering()) + { + if (m_pActiveWindow->OnIMEChangeCodePage()) + return; + } + } + void CWindowManager::RunOpenCandidate() + { + if (m_pLockWindow) + { + m_pLockWindow->OnIMEOpenCandidateListEvent(); + return; + } + if (m_pActiveWindow) + if (m_pActiveWindow->IsRendering()) + { + if (m_pActiveWindow->OnIMEOpenCandidateListEvent()) + return; + } + } + + void CWindowManager::RunCloseCandidate() + { + if (m_pLockWindow) + { + m_pLockWindow->OnIMECloseCandidateListEvent(); + return; + } + if (m_pActiveWindow) + if (m_pActiveWindow->IsRendering()) + { + if (m_pActiveWindow->OnIMECloseCandidateListEvent()) + return; + } + } + + void CWindowManager::RunOpenReading() + { + if (m_pLockWindow) + { + m_pLockWindow->OnIMEOpenReadingWndEvent(); + return; + } + if (m_pActiveWindow) + if (m_pActiveWindow->IsRendering()) + { + if (m_pActiveWindow->OnIMEOpenReadingWndEvent()) + return; + } + } + + void CWindowManager::RunCloseReading() + { + if (m_pLockWindow) + { + m_pLockWindow->OnIMECloseReadingWndEvent(); + return; + } + if (m_pActiveWindow) + if (m_pActiveWindow->IsRendering()) + { + if (m_pActiveWindow->OnIMECloseReadingWndEvent()) + return; + } + } + // IME + + void CWindowManager::RunKeyDown(int vkey) + { + if (m_pLockWindow) + { + m_pLockWindow->OnKeyDown(vkey); + m_KeyCaptureWindowMap.insert(std::make_pair(vkey, m_pLockWindow)); + return; + } + if (m_pActiveWindow) + if (m_pActiveWindow->IsShow()) + { + if (m_pActiveWindow->OnKeyDown(vkey)) + { + m_KeyCaptureWindowMap.insert(std::make_pair(vkey, m_pActiveWindow)); + return; + } + } + + CWindow * pKeyCaptureWindow = m_pRootWindow->RunKeyDownEvent(vkey); + if (pKeyCaptureWindow) + if (m_ReserveDeleteWindowList.end() == std::find(m_ReserveDeleteWindowList.begin(), m_ReserveDeleteWindowList.end(), pKeyCaptureWindow)) + { + m_KeyCaptureWindowMap.insert(TKeyCaptureWindowMap::value_type(vkey, pKeyCaptureWindow)); + } + } + + void CWindowManager::RunKeyUp(int vkey) + { + TKeyCaptureWindowMap::iterator itor = m_KeyCaptureWindowMap.find(vkey); + if (m_KeyCaptureWindowMap.end() != itor) + { + CWindow * pKeyCaptureWindow = itor->second; + if (pKeyCaptureWindow) + pKeyCaptureWindow->OnKeyUp(vkey); + + m_KeyCaptureWindowMap.erase(itor); + return; + } + + if (m_pLockWindow) + { + m_pLockWindow->OnKeyUp(vkey); + return; + } + + if (m_pActiveWindow) + { + if (m_pActiveWindow->OnKeyUp(vkey)) + return; + } + + m_pRootWindow->RunKeyUpEvent(vkey); + } + + void CWindowManager::RunPressEscapeKey() + { + if (m_pLockWindow) + { + m_pLockWindow->OnPressEscapeKey(); + return; + } + + m_pRootWindow->RunPressEscapeKeyEvent(); + } + + void CWindowManager::RunPressExitKey() + { + if (m_pLockWindow) + { + m_pLockWindow->OnPressExitKey(); + return; + } + if (m_pActiveWindow) + { + if (m_pActiveWindow->OnPressExitKey()) + return; + } + + m_pRootWindow->RunPressExitKeyEvent(); + } +} diff --git a/source/EterPythonLib/PythonWindowManager.h b/source/EterPythonLib/PythonWindowManager.h new file mode 100644 index 0000000..d7681a2 --- /dev/null +++ b/source/EterPythonLib/PythonWindowManager.h @@ -0,0 +1,187 @@ +#pragma once + +namespace UI +{ + class CWindow; + + class CWindowManager : public CSingleton + { + public: + typedef std::map TLayerContainer; + typedef std::list TWindowContainer; + typedef std::map TKeyCaptureWindowMap; + + public: + CWindowManager(); + virtual ~CWindowManager(); + + void Destroy(); + + float GetAspect(); + void SetScreenSize(long lWidth, long lHeight); + void SetResolution(int hres, int vres); + + void GetResolution(long & rx, long & ry) + { + rx=m_iHres; + ry=m_iVres; + } + + void SetMouseHandler(PyObject * poMouseHandler); + long GetScreenWidth() { return m_lWidth; } + long GetScreenHeight() { return m_lHeight; } + void GetMousePosition(long & rx, long & ry); + BOOL IsDragging(); + + CWindow * GetLockWindow() { return m_pLockWindow; } + CWindow * GetPointWindow() { return m_pPointWindow; } + bool IsFocus() { return (m_pActiveWindow || m_pLockWindow); } + bool IsFocusWindow(CWindow * pWindow) { return pWindow == m_pActiveWindow; } + + void SetParent(CWindow * pWindow, CWindow * pParentWindow); + void SetPickAlways(CWindow * pWindow); + + enum + { + WT_NORMAL, + WT_SLOT, + WT_GRIDSLOT, + WT_TEXTLINE, + WT_MARKBOX, + WT_IMAGEBOX, + WT_EXP_IMAGEBOX, + WT_ANI_IMAGEBOX, + WT_BUTTON, + WT_RATIOBUTTON, + WT_TOGGLEBUTTON, + WT_DRAGBUTTON, + WT_BOX, + WT_BAR, + WT_LINE, + WT_BAR3D, + WT_NUMLINE, + }; + + CWindow * RegisterWindow(PyObject * po, const char * c_szLayer); + CWindow * RegisterTypeWindow(PyObject * po, DWORD dwWndType, const char * c_szLayer); + + CWindow * RegisterSlotWindow(PyObject * po, const char * c_szLayer); + CWindow * RegisterGridSlotWindow(PyObject * po, const char * c_szLayer); + CWindow * RegisterTextLine(PyObject * po, const char * c_szLayer); + CWindow * RegisterMarkBox(PyObject * po, const char * c_szLayer); + CWindow * RegisterImageBox(PyObject * po, const char * c_szLayer); + CWindow * RegisterExpandedImageBox(PyObject * po, const char * c_szLayer); + CWindow * RegisterAniImageBox(PyObject * po, const char * c_szLayer); + CWindow * RegisterButton(PyObject * po, const char * c_szLayer); + CWindow * RegisterRadioButton(PyObject * po, const char * c_szLayer); + CWindow * RegisterToggleButton(PyObject * po, const char * c_szLayer); + CWindow * RegisterDragButton(PyObject * po, const char * c_szLayer); + CWindow * RegisterBox(PyObject * po, const char * c_szLayer); + CWindow * RegisterBar(PyObject * po, const char * c_szLayer); + CWindow * RegisterLine(PyObject * po, const char * c_szLayer); + CWindow * RegisterBar3D(PyObject * po, const char * c_szLayer); + CWindow * RegisterNumberLine(PyObject * po, const char * c_szLayer); + + void DestroyWindow(CWindow * pWin); + void NotifyDestroyWindow(CWindow * pWindow); + + // Attaching Icon + BOOL IsAttaching(); + DWORD GetAttachingType(); + DWORD GetAttachingIndex(); + DWORD GetAttachingSlotNumber(); + void GetAttachingIconSize(BYTE * pbyWidth, BYTE * pbyHeight); + void AttachIcon(DWORD dwType, DWORD dwIndex, DWORD dwSlotNumber, BYTE byWidth, BYTE byHeight); + void DeattachIcon(); + void SetAttachingFlag(BOOL bFlag); + // Attaching Icon + + void OnceIgnoreMouseLeftButtonUpEvent(); + void LockWindow(CWindow * pWin); + void UnlockWindow(); + + void ActivateWindow(CWindow * pWin); + void DeactivateWindow(); + CWindow * GetActivateWindow(); + void SetTop(CWindow * pWin); + void SetTopUIWindow(); + void ResetCapture(); + + void Update(); + void Render(); + + void RunMouseMove(long x, long y); + void RunMouseLeftButtonDown(long x, long y); + void RunMouseLeftButtonUp(long x, long y); + void RunMouseLeftButtonDoubleClick(long x, long y); + void RunMouseRightButtonDown(long x, long y); + void RunMouseRightButtonUp(long x, long y); + void RunMouseRightButtonDoubleClick(long x, long y); + void RunMouseMiddleButtonDown(long x, long y); + void RunMouseMiddleButtonUp(long x, long y); + + void RunIMEUpdate(); + void RunIMETabEvent(); + void RunIMEReturnEvent(); + void RunIMEKeyDown(int vkey); + void RunChangeCodePage(); + void RunOpenCandidate(); + void RunCloseCandidate(); + void RunOpenReading(); + void RunCloseReading(); + + void RunKeyDown(int vkey); + void RunKeyUp(int vkey); + void RunPressEscapeKey(); + void RunPressExitKey(); + + private: + void SetMousePosition(long x, long y); + CWindow * __PickWindow(long x, long y); + + CWindow * __NewWindow(PyObject * po, DWORD dwWndType); + void __ClearReserveDeleteWindowList(); + + private: + long m_lWidth; + long m_lHeight; + + int m_iVres; + int m_iHres; + + long m_lMouseX, m_lMouseY; + long m_lDragX, m_lDragY; + long m_lPickedX, m_lPickedY; + + BOOL m_bOnceIgnoreMouseLeftButtonUpEventFlag; + int m_iIgnoreEndTime; + + // Attaching Icon + PyObject * m_poMouseHandler; + BOOL m_bAttachingFlag; + DWORD m_dwAttachingType; + DWORD m_dwAttachingIndex; + DWORD m_dwAttachingSlotNumber; + BYTE m_byAttachingIconWidth; + BYTE m_byAttachingIconHeight; + // Attaching Icon + + CWindow * m_pActiveWindow; + TWindowContainer m_ActiveWindowList; + CWindow * m_pLockWindow; + TWindowContainer m_LockWindowList; + CWindow * m_pPointWindow; + CWindow * m_pLeftCaptureWindow; + CWindow * m_pRightCaptureWindow; + CWindow * m_pMiddleCaptureWindow; + TKeyCaptureWindowMap m_KeyCaptureWindowMap; + TWindowContainer m_ReserveDeleteWindowList; + TWindowContainer m_PickAlwaysWindowList; + + CWindow * m_pRootWindow; + TWindowContainer m_LayerWindowList; + TLayerContainer m_LayerWindowMap; + }; + + PyObject * BuildEmptyTuple(); +}; diff --git a/source/EterPythonLib/PythonWindowManagerModule.cpp b/source/EterPythonLib/PythonWindowManagerModule.cpp new file mode 100644 index 0000000..4e9fb4d --- /dev/null +++ b/source/EterPythonLib/PythonWindowManagerModule.cpp @@ -0,0 +1,2522 @@ +#include "StdAfx.h" +#include "PythonWindow.h" +#include "PythonSlotWindow.h" +#include "PythonGridSlotWindow.h" + +bool PyTuple_GetWindow(PyObject* poArgs, int pos, UI::CWindow ** ppRetWindow) +{ + int iHandle; + if (!PyTuple_GetInteger(poArgs, pos, &iHandle)) + return false; + if (!iHandle) + return false; + + *ppRetWindow = (UI::CWindow*)iHandle; + return true; +} + +PyObject * wndMgrGetAspect(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("f", UI::CWindowManager::Instance().GetAspect()); +} + +PyObject * wndMgrOnceIgnoreMouseLeftButtonUpEvent(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindowManager::Instance().OnceIgnoreMouseLeftButtonUpEvent(); + return Py_BuildNone(); +} + +PyObject * wndMgrSetMouseHandler(PyObject * poSelf, PyObject * poArgs) +{ + PyObject * poHandler; + if (!PyTuple_GetObject(poArgs, 0, &poHandler)) + return Py_BuildException(); + + UI::CWindowManager::Instance().SetMouseHandler(poHandler); + return Py_BuildNone(); +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +///// Register ///// +// Window +PyObject * wndMgrRegister(PyObject * poSelf, PyObject * poArgs) +{ + PyObject * po; + if (!PyTuple_GetObject(poArgs, 0, &po)) + return Py_BuildException(); + char * szLayer; + if (!PyTuple_GetString(poArgs, 1, &szLayer)) + return Py_BuildException(); + + UI::CWindowManager& kWndMgr=UI::CWindowManager::Instance(); + UI::CWindow * pWindow = kWndMgr.RegisterWindow(po, szLayer); + if (!pWindow) + return Py_BuildException(); + + return Py_BuildValue("i", pWindow); +} + +// SlotWindow +PyObject * wndMgrRegisterSlotWindow(PyObject * poSelf, PyObject * poArgs) +{ + PyObject * po; + if (!PyTuple_GetObject(poArgs, 0, &po)) + return Py_BuildException(); + char * szLayer; + if (!PyTuple_GetString(poArgs, 1, &szLayer)) + return Py_BuildException(); + + UI::CWindow * pWindow = UI::CWindowManager::Instance().RegisterSlotWindow(po, szLayer); + return Py_BuildValue("i", pWindow); +} + +// GridSlotWindow +PyObject * wndMgrRegisterGridSlotWindow(PyObject * poSelf, PyObject * poArgs) +{ + PyObject * po; + if (!PyTuple_GetObject(poArgs, 0, &po)) + return Py_BuildException(); + char * szLayer; + if (!PyTuple_GetString(poArgs, 1, &szLayer)) + return Py_BuildException(); + + UI::CWindow * pWindow = UI::CWindowManager::Instance().RegisterGridSlotWindow(po, szLayer); + return Py_BuildValue("i", pWindow); +} + +// TextLine +PyObject * wndMgrRegisterTextLine(PyObject * poSelf, PyObject * poArgs) +{ + PyObject * po; + if (!PyTuple_GetObject(poArgs, 0, &po)) + return Py_BuildException(); + char * szLayer; + if (!PyTuple_GetString(poArgs, 1, &szLayer)) + return Py_BuildException(); + + UI::CWindow * pWindow = UI::CWindowManager::Instance().RegisterTextLine(po, szLayer); + return Py_BuildValue("i", pWindow); +} + +// MarkBox +PyObject * wndMgrRegisterMarkBox(PyObject * poSelf, PyObject * poArgs) +{ + PyObject * po; + if (!PyTuple_GetObject(poArgs, 0, &po)) + return Py_BuildException(); + char * szLayer; + if (!PyTuple_GetString(poArgs, 1, &szLayer)) + return Py_BuildException(); + + UI::CWindow * pWindow = UI::CWindowManager::Instance().RegisterMarkBox(po, szLayer); + return Py_BuildValue("i", pWindow); +} + +// ImageBox +PyObject * wndMgrRegisterImageBox(PyObject * poSelf, PyObject * poArgs) +{ + PyObject * po; + if (!PyTuple_GetObject(poArgs, 0, &po)) + return Py_BuildException(); + char * szLayer; + if (!PyTuple_GetString(poArgs, 1, &szLayer)) + return Py_BuildException(); + + UI::CWindow * pWindow = UI::CWindowManager::Instance().RegisterImageBox(po, szLayer); + return Py_BuildValue("i", pWindow); +} + +// ExpandedImageBox +PyObject * wndMgrRegisterExpandedImageBox(PyObject * poSelf, PyObject * poArgs) +{ + PyObject * po; + if (!PyTuple_GetObject(poArgs, 0, &po)) + return Py_BuildException(); + char * szLayer; + if (!PyTuple_GetString(poArgs, 1, &szLayer)) + return Py_BuildException(); + + UI::CWindow * pWindow = UI::CWindowManager::Instance().RegisterExpandedImageBox(po, szLayer); + return Py_BuildValue("i", pWindow); +} + +// AniImageBox +PyObject * wndMgrRegisterAniImageBox(PyObject * poSelf, PyObject * poArgs) +{ + PyObject * po; + if (!PyTuple_GetObject(poArgs, 0, &po)) + return Py_BuildException(); + char * szLayer; + if (!PyTuple_GetString(poArgs, 1, &szLayer)) + return Py_BuildException(); + + UI::CWindow * pWindow = UI::CWindowManager::Instance().RegisterAniImageBox(po, szLayer); + return Py_BuildValue("i", pWindow); +} + +// RegisterButton +PyObject * wndMgrRegisterButton(PyObject * poSelf, PyObject * poArgs) +{ + PyObject * po; + if (!PyTuple_GetObject(poArgs, 0, &po)) + return Py_BuildException(); + char * szLayer; + if (!PyTuple_GetString(poArgs, 1, &szLayer)) + return Py_BuildException(); + + UI::CWindow * pWindow = UI::CWindowManager::Instance().RegisterButton(po, szLayer); + return Py_BuildValue("i", pWindow); +} + +// RadioButton +PyObject * wndMgrRegisterRadioButton(PyObject * poSelf, PyObject * poArgs) +{ + PyObject * po; + if (!PyTuple_GetObject(poArgs, 0, &po)) + return Py_BuildException(); + char * szLayer; + if (!PyTuple_GetString(poArgs, 1, &szLayer)) + return Py_BuildException(); + + UI::CWindow * pWindow = UI::CWindowManager::Instance().RegisterRadioButton(po, szLayer); + return Py_BuildValue("i", pWindow); +} + +// ToggleButton +PyObject * wndMgrRegisterToggleButton(PyObject * poSelf, PyObject * poArgs) +{ + PyObject * po; + if (!PyTuple_GetObject(poArgs, 0, &po)) + return Py_BuildException(); + char * szLayer; + if (!PyTuple_GetString(poArgs, 1, &szLayer)) + return Py_BuildException(); + + UI::CWindow * pWindow = UI::CWindowManager::Instance().RegisterToggleButton(po, szLayer); + return Py_BuildValue("i", pWindow); +} + +// DragButton +PyObject * wndMgrRegisterDragButton(PyObject * poSelf, PyObject * poArgs) +{ + PyObject * po; + if (!PyTuple_GetObject(poArgs, 0, &po)) + return Py_BuildException(); + char * szLayer; + if (!PyTuple_GetString(poArgs, 1, &szLayer)) + return Py_BuildException(); + + UI::CWindow * pWindow = UI::CWindowManager::Instance().RegisterDragButton(po, szLayer); + return Py_BuildValue("i", pWindow); +} + +// Box +PyObject * wndMgrRegisterBox(PyObject * poSelf, PyObject * poArgs) +{ + PyObject * po; + if (!PyTuple_GetObject(poArgs, 0, &po)) + return Py_BuildException(); + char * szLayer; + if (!PyTuple_GetString(poArgs, 1, &szLayer)) + return Py_BuildException(); + + UI::CWindow * pWindow = UI::CWindowManager::Instance().RegisterBox(po, szLayer); + return Py_BuildValue("i", pWindow); +} + +// Bar +PyObject * wndMgrRegisterBar(PyObject * poSelf, PyObject * poArgs) +{ + PyObject * po; + if (!PyTuple_GetObject(poArgs, 0, &po)) + return Py_BuildException(); + char * szLayer; + if (!PyTuple_GetString(poArgs, 1, &szLayer)) + return Py_BuildException(); + + UI::CWindow * pWindow = UI::CWindowManager::Instance().RegisterBar(po, szLayer); + return Py_BuildValue("i", pWindow); +} + +// Line +PyObject * wndMgrRegisterLine(PyObject * poSelf, PyObject * poArgs) +{ + PyObject * po; + if (!PyTuple_GetObject(poArgs, 0, &po)) + return Py_BuildException(); + char * szLayer; + if (!PyTuple_GetString(poArgs, 1, &szLayer)) + return Py_BuildException(); + + UI::CWindow * pWindow = UI::CWindowManager::Instance().RegisterLine(po, szLayer); + return Py_BuildValue("i", pWindow); +} + +// Slot +PyObject * wndMgrRegisterBar3D(PyObject * poSelf, PyObject * poArgs) +{ + PyObject * po; + if (!PyTuple_GetObject(poArgs, 0, &po)) + return Py_BuildException(); + char * szLayer; + if (!PyTuple_GetString(poArgs, 1, &szLayer)) + return Py_BuildException(); + + UI::CWindow * pWindow = UI::CWindowManager::Instance().RegisterBar3D(po, szLayer); + return Py_BuildValue("i", pWindow); +} + +// NumberLine +PyObject * wndMgrRegisterNumberLine(PyObject * poSelf, PyObject * poArgs) +{ + PyObject * po; + if (!PyTuple_GetObject(poArgs, 0, &po)) + return Py_BuildException(); + char * szLayer; + if (!PyTuple_GetString(poArgs, 1, &szLayer)) + return Py_BuildException(); + + UI::CWindow * pWindow = UI::CWindowManager::Instance().RegisterNumberLine(po, szLayer); + return Py_BuildValue("i", pWindow); +} +///// Register ///// +///////////////////////////////////////////////////////////////////////////////////////////////// + +PyObject * wndMgrDestroy(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + UI::CWindowManager::Instance().DestroyWindow(pWin); + return Py_BuildNone(); +} + +PyObject * wndMgrIsFocus(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + return Py_BuildValue("i", pWindow == UI::CWindowManager::Instance().GetActivateWindow()); +} + +PyObject * wndMgrSetFocus(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + UI::CWindowManager::Instance().ActivateWindow(pWin); + return Py_BuildNone(); +} + +PyObject * wndMgrKillFocus(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (PyTuple_GetWindow(poArgs, 0, &pWin)) + { + if (pWin == UI::CWindowManager::Instance().GetActivateWindow()) + { + UI::CWindowManager::Instance().DeactivateWindow(); + } + } + else + { + UI::CWindowManager::Instance().DeactivateWindow(); + } + + return Py_BuildNone(); +} + +PyObject * wndMgrLock(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + UI::CWindowManager::Instance().LockWindow(pWin); + return Py_BuildNone(); +} + +PyObject * wndMgrUnlock(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindowManager::Instance().UnlockWindow(); + return Py_BuildNone(); +} + +PyObject * wndMgrSetName(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + char * szName; + if (!PyTuple_GetString(poArgs, 1, &szName)) + return Py_BuildException(); + + pWin->SetName(szName); + return Py_BuildNone(); +} + +PyObject * wndMgrSetTop(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + UI::CWindowManager::Instance().SetTop(pWin); + return Py_BuildNone(); +} + +PyObject * wndMgrShow(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + pWin->Show(); + return Py_BuildNone(); +} + +PyObject * wndMgrHide(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + pWin->Hide(); + return Py_BuildNone(); +} + +PyObject * wndMgrIsShow(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + return Py_BuildValue("i", pWin->IsShow()); +} + +PyObject * wndMgrIsRTL(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + return Py_BuildValue("i", pWin->IsFlag(UI::CWindow::FLAG_RTL)); +} + +PyObject * wndMgrSetScreenSize(PyObject * poSelf, PyObject * poArgs) +{ + int width; + if (!PyTuple_GetInteger(poArgs, 0, &width)) + return Py_BuildException(); + int height; + if (!PyTuple_GetInteger(poArgs, 1, &height)) + return Py_BuildException(); + + UI::CWindowManager::Instance().SetScreenSize(width, height); + return Py_BuildNone(); +} + +PyObject * wndMgrSetParent(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + UI::CWindow * pParentWin; + if (!PyTuple_GetWindow(poArgs, 1, &pParentWin)) + return Py_BuildException(); + + UI::CWindowManager::Instance().SetParent(pWin, pParentWin); + return Py_BuildNone(); +} + +PyObject * wndMgrSetPickAlways(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + UI::CWindowManager::Instance().SetPickAlways(pWin); + return Py_BuildNone(); +} + +PyObject * wndMgrSetWndSize(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + int width; + if (!PyTuple_GetInteger(poArgs, 1, &width)) + return Py_BuildException(); + int height; + if (!PyTuple_GetInteger(poArgs, 2, &height)) + return Py_BuildException(); + + pWin->SetSize(width, height); + return Py_BuildNone(); +} + +PyObject * wndMgrSetWndPosition(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + int x; + if (!PyTuple_GetInteger(poArgs, 1, &x)) + return Py_BuildException(); + int y; + if (!PyTuple_GetInteger(poArgs, 2, &y)) + return Py_BuildException(); + + pWin->SetPosition(x, y); + return Py_BuildNone(); +} + +PyObject * wndMgrGetName(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + return Py_BuildValue("s", pWin->GetName()); +} + +PyObject * wndMgrGetWndWidth(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + return Py_BuildValue("i", pWin->GetWidth()); +} + +PyObject * wndMgrGetWndHeight(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + return Py_BuildValue("i", pWin->GetHeight()); +} + +PyObject * wndMgrGetWndLocalPosition(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + long lx, ly; + pWin->GetPosition(&lx, &ly); + + return Py_BuildValue("ii", lx, ly); +} + +PyObject * wndMgrGetWndGlobalPosition(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + RECT & rRect = pWindow->GetRect(); + return Py_BuildValue("ii", rRect.left, rRect.top); +} + +PyObject * wndMgrGetWindowRect(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + RECT & rRect = pWin->GetRect(); + return Py_BuildValue("iiii", rRect.left, rRect.top, rRect.right - rRect.left, rRect.bottom - rRect.top); +} + +PyObject * wndMgrSetWindowHorizontalAlign(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + int iAlign; + if (!PyTuple_GetInteger(poArgs, 1, &iAlign)) + return Py_BuildException(); + + pWin->SetHorizontalAlign(iAlign); + + return Py_BuildNone(); +} + +PyObject * wndMgrSetWindowVerticalAlign(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + int iAlign; + if (!PyTuple_GetInteger(poArgs, 1, &iAlign)) + return Py_BuildException(); + + pWin->SetVerticalAlign(iAlign); + + return Py_BuildNone(); +} + +PyObject * wndMgrIsIn(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + return Py_BuildValue("i", pWin == UI::CWindowManager::Instance().GetPointWindow()); +} + +PyObject * wndMgrGetMouseLocalPosition(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + long lx, ly; + pWin->GetMouseLocalPosition(lx, ly); + return Py_BuildValue("ii", lx, ly); +} + +PyObject * wndMgrGetHyperlink(PyObject * poSelf, PyObject * poArgs) +{ + char retBuf[1024]; + int retLen = CGraphicTextInstance::Hyperlink_GetText(retBuf, sizeof(retBuf)-1); + retBuf[retLen] = '\0'; + + return Py_BuildValue("s#", retBuf, retLen); +} + +PyObject * wndMgrGetScreenWidth(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", UI::CWindowManager::Instance().GetScreenWidth()); +} + +PyObject * wndMgrGetScreenHeight(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", UI::CWindowManager::Instance().GetScreenHeight()); +} + +PyObject * wndMgrGetMousePosition(PyObject * poSelf, PyObject * poArgs) +{ + long lx, ly; + UI::CWindowManager::Instance().GetMousePosition(lx, ly); + return Py_BuildValue("ii", lx, ly); +} + +PyObject * wndMgrIsDragging(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", UI::CWindowManager::Instance().IsDragging()); +} + +PyObject * wndMgrIsPickedWindow(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + UI::CWindow * pPickedWin = UI::CWindowManager::Instance().GetPointWindow(); + return Py_BuildValue("i", pWin == pPickedWin ? 1 : 0); +} + +PyObject * wndMgrGetChildCount(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + return Py_BuildValue("i", pWin->GetChildCount()); +} + +PyObject * wndMgrAddFlag(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + char * pszFlag; + if (!PyTuple_GetString(poArgs, 1, &pszFlag)) + return Py_BuildException(); + + if (pszFlag && *pszFlag) + { + if (!stricmp(pszFlag, "movable")) + pWin->AddFlag(UI::CWindow::FLAG_MOVABLE); + else if (!stricmp(pszFlag, "limit")) + pWin->AddFlag(UI::CWindow::FLAG_LIMIT); + else if (!stricmp(pszFlag, "dragable")) + pWin->AddFlag(UI::CWindow::FLAG_DRAGABLE); + else if (!stricmp(pszFlag, "attach")) + pWin->AddFlag(UI::CWindow::FLAG_ATTACH); + else if (!stricmp(pszFlag, "restrict_x")) + pWin->AddFlag(UI::CWindow::FLAG_RESTRICT_X); + else if (!stricmp(pszFlag, "restrict_y")) + pWin->AddFlag(UI::CWindow::FLAG_RESTRICT_Y); + else if (!stricmp(pszFlag, "float")) + pWin->AddFlag(UI::CWindow::FLAG_FLOAT); + else if (!stricmp(pszFlag, "not_pick")) + pWin->AddFlag(UI::CWindow::FLAG_NOT_PICK); + else if (!stricmp(pszFlag, "ignore_size")) + pWin->AddFlag(UI::CWindow::FLAG_IGNORE_SIZE); + else if (!stricmp(pszFlag, "rtl")) + pWin->AddFlag(UI::CWindow::FLAG_RTL); + else if (!stricmp(pszFlag, "ltr")) + pWin->RemoveFlag(UI::CWindow::FLAG_RTL); + else + TraceError("Unknown window flag %s", pszFlag); + } + + return Py_BuildNone(); +} + +PyObject * wndMgrSetLimitBias(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + int l; + if (!PyTuple_GetInteger(poArgs, 1, &l)) + return Py_BuildException(); + int r; + if (!PyTuple_GetInteger(poArgs, 2, &r)) + return Py_BuildException(); + int t; + if (!PyTuple_GetInteger(poArgs, 3, &t)) + return Py_BuildException(); + int b; + if (!PyTuple_GetInteger(poArgs, 4, &b)) + return Py_BuildException(); + + pWin->SetLimitBias(l, r, t, b); + return Py_BuildNone(); +} + +PyObject * wndMgrUpdateRect(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + pWin->UpdateRect(); + return Py_BuildNone(); +} + +PyObject * wndMgrAppendSlot(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + int iIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iIndex)) + return Py_BuildException(); + + int ixPosition; + if (!PyTuple_GetInteger(poArgs, 2, &ixPosition)) + return Py_BuildException(); + + int iyPosition; + if (!PyTuple_GetInteger(poArgs, 3, &iyPosition)) + return Py_BuildException(); + + int ixCellSize; + if (!PyTuple_GetInteger(poArgs, 4, &ixCellSize)) + return Py_BuildException(); + + int iyCellSize; + if (!PyTuple_GetInteger(poArgs, 5, &iyCellSize)) + return Py_BuildException(); + + if (!pWin->IsType(UI::CSlotWindow::Type())) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + pSlotWin->AppendSlot(iIndex, ixPosition, iyPosition, ixCellSize, iyCellSize); + + return Py_BuildNone(); +} + +PyObject * wndMgrArrangeSlot(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + int iStartIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iStartIndex)) + return Py_BuildException(); + + int ixCellCount; + if (!PyTuple_GetInteger(poArgs, 2, &ixCellCount)) + return Py_BuildException(); + + int iyCellCount; + if (!PyTuple_GetInteger(poArgs, 3, &iyCellCount)) + return Py_BuildException(); + + int ixCellSize; + if (!PyTuple_GetInteger(poArgs, 4, &ixCellSize)) + return Py_BuildException(); + + int iyCellSize; + if (!PyTuple_GetInteger(poArgs, 5, &iyCellSize)) + return Py_BuildException(); + + int ixBlank; + if (!PyTuple_GetInteger(poArgs, 6, &ixBlank)) + return Py_BuildException(); + + int iyBlank; + if (!PyTuple_GetInteger(poArgs, 7, &iyBlank)) + return Py_BuildException(); + + if (!pWin->IsType(UI::CGridSlotWindow::Type())) + { + TraceError("wndMgr.ArrangeSlot : not a grid window"); + return Py_BuildException(); + } + + UI::CGridSlotWindow * pGridSlotWin = (UI::CGridSlotWindow *)pWin; + pGridSlotWin->ArrangeGridSlot(iStartIndex, ixCellCount, iyCellCount, ixCellSize, iyCellSize, ixBlank, iyBlank); + + return Py_BuildNone(); +} + +PyObject * wndMgrSetSlotBaseImage(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + char * szFileName; + if (!PyTuple_GetString(poArgs, 1, &szFileName)) + return Py_BuildException(); + + float fr; + if (!PyTuple_GetFloat(poArgs, 2, &fr)) + return Py_BuildException(); + float fg; + if (!PyTuple_GetFloat(poArgs, 3, &fg)) + return Py_BuildException(); + float fb; + if (!PyTuple_GetFloat(poArgs, 4, &fb)) + return Py_BuildException(); + float fa; + if (!PyTuple_GetFloat(poArgs, 5, &fa)) + return Py_BuildException(); + + if (!pWin->IsType(UI::CSlotWindow::Type())) + { + TraceError("wndMgr.ArrangeSlot : not a slot window"); + return Py_BuildException(); + } + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + pSlotWin->SetSlotBaseImage(szFileName, fr, fg, fb, fa); + + return Py_BuildNone(); +} + +PyObject * wndMgrSetCoverButton(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iSlotIndex)) + return Py_BuildException(); + + char * szUpImageName; + if (!PyTuple_GetString(poArgs, 2, &szUpImageName)) + return Py_BuildException(); + char * szOverImageName; + if (!PyTuple_GetString(poArgs, 3, &szOverImageName)) + return Py_BuildException(); + char * szDownImageName; + if (!PyTuple_GetString(poArgs, 4, &szDownImageName)) + return Py_BuildException(); + char * szDisableImageName; + if (!PyTuple_GetString(poArgs, 5, &szDisableImageName)) + return Py_BuildException(); + + int iLeftButtonEnable; + if (!PyTuple_GetInteger(poArgs, 6, &iLeftButtonEnable)) + return Py_BuildException(); + int iRightButtonEnable; + if (!PyTuple_GetInteger(poArgs, 7, &iRightButtonEnable)) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWindow; + pSlotWin->SetCoverButton(iSlotIndex, szUpImageName, szOverImageName, szDownImageName, szDisableImageName, iLeftButtonEnable, iRightButtonEnable); + + return Py_BuildNone(); +} + +PyObject * wndMgrEnableCoverButton(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iSlotIndex)) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWindow; + pSlotWin->EnableCoverButton(iSlotIndex); + + return Py_BuildNone(); +} + +PyObject * wndMgrDisableCoverButton(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iSlotIndex)) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWindow; + pSlotWin->DisableCoverButton(iSlotIndex); + + return Py_BuildNone(); +} + +PyObject * wndMgrIsDisableCoverButton(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iSlotIndex)) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWindow; + return Py_BuildValue("i", pSlotWin->IsDisableCoverButton(iSlotIndex)); +} + +PyObject * wndMgrSetAlwaysRenderCoverButton(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + int iSlotIndex; + bool bAlwaysRender = false; + + if (!PyTuple_GetInteger(poArgs, 1, &iSlotIndex)) + return Py_BuildException(); + + if (!PyTuple_GetBoolean(poArgs, 2, &bAlwaysRender)) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWindow; + pSlotWin->SetAlwaysRenderCoverButton(iSlotIndex, bAlwaysRender); + + return Py_BuildNone(); +} + +PyObject * wndMgrAppendSlotButton(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + char * szUpImageName; + if (!PyTuple_GetString(poArgs, 1, &szUpImageName)) + return Py_BuildException(); + char * szOverImageName; + if (!PyTuple_GetString(poArgs, 2, &szOverImageName)) + return Py_BuildException(); + char * szDownImageName; + if (!PyTuple_GetString(poArgs, 3, &szDownImageName)) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWindow; + pSlotWin->AppendSlotButton(szUpImageName, szOverImageName, szDownImageName); + + return Py_BuildNone(); +} + +PyObject * wndMgrAppendRequirementSignImage(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + char * szImageName; + if (!PyTuple_GetString(poArgs, 1, &szImageName)) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWindow; + pSlotWin->AppendRequirementSignImage(szImageName); + + return Py_BuildNone(); +} + +PyObject * wndMgrShowSlotButton(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + int iSlotNumber; + if (!PyTuple_GetInteger(poArgs, 1, &iSlotNumber)) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWindow; + pSlotWin->ShowSlotButton(iSlotNumber); + + return Py_BuildNone(); +} + +PyObject * wndMgrHideAllSlotButton(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWindow; + pSlotWin->HideAllSlotButton(); + + return Py_BuildNone(); +} + +PyObject * wndMgrShowRequirementSign(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + int iSlotNumber; + if (!PyTuple_GetInteger(poArgs, 1, &iSlotNumber)) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWindow; + pSlotWin->ShowRequirementSign(iSlotNumber); + + return Py_BuildNone(); +} + +PyObject * wndMgrHideRequirementSign(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + int iSlotNumber; + if (!PyTuple_GetInteger(poArgs, 1, &iSlotNumber)) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWindow; + pSlotWin->HideRequirementSign(iSlotNumber); + + return Py_BuildNone(); +} + +PyObject * wndMgrRefreshSlot(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + if (!pWin->IsType(UI::CSlotWindow::Type())) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + pSlotWin->RefreshSlot(); + + return Py_BuildNone(); +} + +PyObject * wndMgrSetUseMode(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + int iFlag; + if (!PyTuple_GetInteger(poArgs, 1, &iFlag)) + return Py_BuildException(); + + if (!pWin->IsType(UI::CSlotWindow::Type())) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + pSlotWin->SetUseMode(iFlag); + + return Py_BuildNone(); +} + +PyObject * wndMgrSetUsableItem(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + int iFlag; + if (!PyTuple_GetInteger(poArgs, 1, &iFlag)) + return Py_BuildException(); + + if (!pWin->IsType(UI::CSlotWindow::Type())) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + pSlotWin->SetUsableItem(iFlag); + + return Py_BuildNone(); +} + +PyObject * wndMgrClearSlot(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iSlotIndex)) + return Py_BuildException(); + + if (!pWin->IsType(UI::CSlotWindow::Type())) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + pSlotWin->ClearSlot(iSlotIndex); + + return Py_BuildNone(); +} + +PyObject * wndMgrClearAllSlot(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + if (!pWin->IsType(UI::CSlotWindow::Type())) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + pSlotWin->ClearAllSlot(); + + return Py_BuildNone(); +} + +PyObject * wndMgrHasSlot(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iSlotIndex)) + return Py_BuildException(); + + if (!pWin->IsType(UI::CSlotWindow::Type())) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + + return Py_BuildValue("i", pSlotWin->HasSlot(iSlotIndex)); +} + +PyObject * wndMgrSetSlot(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iSlotIndex)) + return Py_BuildException(); + + int iItemIndex; + if (!PyTuple_GetInteger(poArgs, 2, &iItemIndex)) + return Py_BuildException(); + + int iWidth; + if (!PyTuple_GetInteger(poArgs, 3, &iWidth)) + return Py_BuildException(); + + int iHeight; + if (!PyTuple_GetInteger(poArgs, 4, &iHeight)) + return Py_BuildException(); + + int iImageHandle; + if (!PyTuple_GetInteger(poArgs, 5, &iImageHandle)) + return Py_BuildException(); + + D3DXCOLOR diffuseColor; + PyObject* pTuple; + if (!PyTuple_GetObject(poArgs, 6, &pTuple)) + { + diffuseColor = D3DXCOLOR(1.0, 1.0, 1.0, 1.0); + //return Py_BuildException(); + } + else + // get diffuse color from pTuple + { + if (PyTuple_Size(pTuple) != 4) + return Py_BuildException(); + if (!PyTuple_GetFloat(pTuple, 0, &diffuseColor.r)) + return Py_BuildException(); + if (!PyTuple_GetFloat(pTuple, 1, &diffuseColor.g)) + return Py_BuildException(); + if (!PyTuple_GetFloat(pTuple, 2, &diffuseColor.b)) + return Py_BuildException(); + if (!PyTuple_GetFloat(pTuple, 3, &diffuseColor.a)) + return Py_BuildException(); + } + + if (!pWin->IsType(UI::CSlotWindow::Type())) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + pSlotWin->SetSlot(iSlotIndex, iItemIndex, iWidth, iHeight, (CGraphicImage *)iImageHandle, diffuseColor); + + return Py_BuildNone(); +} + +PyObject * wndMgrSetSlotCount(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iSlotIndex)) + return Py_BuildException(); + + int iCount; + if (!PyTuple_GetInteger(poArgs, 2, &iCount)) + return Py_BuildException(); + + if (!pWin->IsType(UI::CSlotWindow::Type())) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + pSlotWin->SetSlotCount(iSlotIndex, iCount); + + return Py_BuildNone(); +} + +PyObject * wndMgrSetSlotCountNew(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iSlotIndex)) + return Py_BuildException(); + + int iGrade; + if (!PyTuple_GetInteger(poArgs, 2, &iGrade)) + return Py_BuildException(); + + int iCount; + if (!PyTuple_GetInteger(poArgs, 3, &iCount)) + return Py_BuildException(); + + if (!pWin->IsType(UI::CSlotWindow::Type())) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + pSlotWin->SetSlotCountNew(iSlotIndex, iGrade, iCount); + + return Py_BuildNone(); +} + +PyObject * wndMgrSetSlotCoolTime(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iSlotIndex)) + return Py_BuildException(); + + float fCoolTime; + if (!PyTuple_GetFloat(poArgs, 2, &fCoolTime)) + return Py_BuildException(); + + float fElapsedTime = 0.0f; + PyTuple_GetFloat(poArgs, 3, &fElapsedTime); + + if (!pWin->IsType(UI::CSlotWindow::Type())) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + pSlotWin->SetSlotCoolTime(iSlotIndex, fCoolTime, fElapsedTime); + + return Py_BuildNone(); +} + +PyObject * wndMgrSetToggleSlot(PyObject * poSelf, PyObject * poArgs) +{ + assert(!"wndMgrSetToggleSlot - ʴ Լ"); + return Py_BuildNone(); +} + +PyObject * wndMgrActivateSlot(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iSlotIndex)) + return Py_BuildException(); + + if (!pWin->IsType(UI::CSlotWindow::Type())) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + pSlotWin->ActivateSlot(iSlotIndex); + return Py_BuildNone(); +} + +PyObject * wndMgrDeactivateSlot(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iSlotIndex)) + return Py_BuildException(); + + if (!pWin->IsType(UI::CSlotWindow::Type())) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + pSlotWin->DeactivateSlot(iSlotIndex); + return Py_BuildNone(); +} + +PyObject * wndMgrEnableSlot(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iSlotIndex)) + return Py_BuildException(); + + if (!pWin->IsType(UI::CSlotWindow::Type())) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + pSlotWin->EnableSlot(iSlotIndex); + return Py_BuildNone(); +} + +PyObject * wndMgrDisableSlot(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iSlotIndex)) + return Py_BuildException(); + + if (!pWin->IsType(UI::CSlotWindow::Type())) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + pSlotWin->DisableSlot(iSlotIndex); + return Py_BuildNone(); +} + +PyObject * wndMgrShowSlotBaseImage(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iSlotIndex)) + return Py_BuildException(); + + if (!pWin->IsType(UI::CSlotWindow::Type())) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + pSlotWin->ShowSlotBaseImage(iSlotIndex); + return Py_BuildNone(); +} + +PyObject * wndMgrHideSlotBaseImage(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iSlotIndex)) + return Py_BuildException(); + + if (!pWin->IsType(UI::CSlotWindow::Type())) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + pSlotWin->HideSlotBaseImage(iSlotIndex); + return Py_BuildNone(); +} + +PyObject * wndMgrSetSlotType(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + int iType; + if (!PyTuple_GetInteger(poArgs, 1, &iType)) + return Py_BuildException(); + + if (!pWin->IsType(UI::CSlotWindow::Type())) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + pSlotWin->SetSlotType(iType); + + return Py_BuildNone(); +} + +PyObject * wndMgrSetSlotStyle(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + int iStyle; + if (!PyTuple_GetInteger(poArgs, 1, &iStyle)) + return Py_BuildException(); + + if (!pWin->IsType(UI::CSlotWindow::Type())) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + pSlotWin->SetSlotStyle(iStyle); + + return Py_BuildNone(); +} + +PyObject * wndMgrSelectSlot(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + int iIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iIndex)) + return Py_BuildException(); + + if (!pWin->IsType(UI::CSlotWindow::Type())) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + pSlotWin->SelectSlot(iIndex); + + return Py_BuildNone(); +} + +PyObject * wndMgrClearSelected(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + if (!pWin->IsType(UI::CSlotWindow::Type())) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + pSlotWin->ClearSelected(); + + return Py_BuildNone(); +} + +PyObject * wndMgrGetSelectedSlotCount(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + if (!pWin->IsType(UI::CSlotWindow::Type())) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + return Py_BuildValue("i", pSlotWin->GetSelectedSlotCount()); +} + +PyObject * wndMgrGetSelectedSlotNumber(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + int iSlotNumber; + if (!PyTuple_GetInteger(poArgs, 1, &iSlotNumber)) + return Py_BuildException(); + + if (!pWin->IsType(UI::CSlotWindow::Type())) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + return Py_BuildValue("i", pSlotWin->GetSelectedSlotNumber(iSlotNumber)); +} + +PyObject * wndMgrIsSelectedSlot(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + int iSlotNumber; + if (!PyTuple_GetInteger(poArgs, 1, &iSlotNumber)) + return Py_BuildException(); + + if (!pWin->IsType(UI::CSlotWindow::Type())) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + return Py_BuildValue("i", pSlotWin->isSelectedSlot(iSlotNumber)); +} + +PyObject * wndMgrGetSlotCount(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + + if (!pWin->IsType(UI::CSlotWindow::Type())) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + return Py_BuildValue("i", pSlotWin->GetSlotCount()); +} + +PyObject * wndMgrLockSlot(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iSlotIndex)) + return Py_BuildException(); + + if (!pWin->IsType(UI::CSlotWindow::Type())) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + pSlotWin->LockSlot(iSlotIndex); + return Py_BuildNone(); +} + +PyObject * wndMgrUnlockSlot(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWin; + if (!PyTuple_GetWindow(poArgs, 0, &pWin)) + return Py_BuildException(); + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iSlotIndex)) + return Py_BuildException(); + + if (!pWin->IsType(UI::CSlotWindow::Type())) + return Py_BuildException(); + + UI::CSlotWindow * pSlotWin = (UI::CSlotWindow *)pWin; + pSlotWin->UnlockSlot(iSlotIndex); + return Py_BuildNone(); +} + +PyObject * wndBarSetColor(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + int iColor; + if (!PyTuple_GetInteger(poArgs, 1, &iColor)) + return Py_BuildException(); + + if (pWindow->IsType(UI::CBar3D::Type())) + { + int iLeftColor = iColor; + + int iRightColor; + if (!PyTuple_GetInteger(poArgs, 2, &iRightColor)) + return Py_BuildException(); + int iCenterColor; + if (!PyTuple_GetInteger(poArgs, 3, &iCenterColor)) + return Py_BuildException(); + + ((UI::CBar3D *)pWindow)->SetColor(iLeftColor, iRightColor, iCenterColor); + } + else + { + ((UI::CWindow *)pWindow)->SetColor(iColor); + } + return Py_BuildNone(); +} + +PyObject * wndMgrAttachIcon(PyObject * poSelf, PyObject * poArgs) +{ + int iType; + if (!PyTuple_GetInteger(poArgs, 0, &iType)) + return Py_BuildException(); + int iIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iIndex)) + return Py_BuildException(); + int iSlotNumber; + if (!PyTuple_GetInteger(poArgs, 2, &iSlotNumber)) + return Py_BuildException(); + int iWidth; + if (!PyTuple_GetInteger(poArgs, 3, &iWidth)) + return Py_BuildException(); + int iHeight; + if (!PyTuple_GetInteger(poArgs, 4, &iHeight)) + return Py_BuildException(); + + UI::CWindowManager::Instance().AttachIcon(iType, iIndex, iSlotNumber, iWidth, iHeight); + return Py_BuildNone(); +} + +PyObject * wndMgrDeattachIcon(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindowManager::Instance().DeattachIcon(); + return Py_BuildNone(); +} + +PyObject * wndMgrSetAttachingFlag(PyObject * poSelf, PyObject * poArgs) +{ + BOOL bFlag; + if (!PyTuple_GetInteger(poArgs, 0, &bFlag)) + return Py_BuildException(); + + UI::CWindowManager::Instance().SetAttachingFlag(bFlag); + return Py_BuildNone(); +} + +// Text +PyObject * wndTextSetMax(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + int iMax; + if (!PyTuple_GetInteger(poArgs, 1, &iMax)) + return Py_BuildException(); + + ((UI::CTextLine*)pWindow)->SetMax(iMax); + return Py_BuildNone(); +} +PyObject * wndTextSetHorizontalAlign(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + int iType; + if (!PyTuple_GetInteger(poArgs, 1, &iType)) + return Py_BuildException(); + + ((UI::CTextLine*)pWindow)->SetHorizontalAlign(iType); + return Py_BuildNone(); +} +PyObject * wndTextSetVerticalAlign(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + int iType; + if (!PyTuple_GetInteger(poArgs, 1, &iType)) + return Py_BuildException(); + + ((UI::CTextLine*)pWindow)->SetVerticalAlign(iType); + return Py_BuildNone(); +} +PyObject * wndTextSetSecret(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + int iFlag; + if (!PyTuple_GetInteger(poArgs, 1, &iFlag)) + return Py_BuildException(); + + ((UI::CTextLine*)pWindow)->SetSecret(iFlag); + return Py_BuildNone(); +} +PyObject * wndTextSetOutline(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + int iFlag; + if (!PyTuple_GetInteger(poArgs, 1, &iFlag)) + return Py_BuildException(); + + ((UI::CTextLine*)pWindow)->SetOutline(iFlag); + return Py_BuildNone(); +} +PyObject * wndTextSetFeather(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + int iFlag; + if (!PyTuple_GetInteger(poArgs, 1, &iFlag)) + return Py_BuildException(); + + ((UI::CTextLine*)pWindow)->SetFeather(iFlag); + return Py_BuildNone(); +} +PyObject * wndTextSetMultiLine(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + int iFlag; + if (!PyTuple_GetInteger(poArgs, 1, &iFlag)) + return Py_BuildException(); + + ((UI::CTextLine*)pWindow)->SetMultiLine(iFlag); + return Py_BuildNone(); +} +PyObject * wndTextSetFontName(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + char * szFontName; + if (!PyTuple_GetString(poArgs, 1, &szFontName)) + return Py_BuildException(); + + ((UI::CTextLine*)pWindow)->SetFontName(szFontName); + return Py_BuildNone(); +} +PyObject * wndTextSetFontColor(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + if (2 == PyTuple_Size(poArgs)) + { + int iColor; + if (!PyTuple_GetInteger(poArgs, 1, &iColor)) + return Py_BuildException(); + ((UI::CTextLine*)pWindow)->SetFontColor(iColor); + } + else if (4 == PyTuple_Size(poArgs)) + { + float fr; + if (!PyTuple_GetFloat(poArgs, 1, &fr)) + return Py_BuildException(); + float fg; + if (!PyTuple_GetFloat(poArgs, 2, &fg)) + return Py_BuildException(); + float fb; + if (!PyTuple_GetFloat(poArgs, 3, &fb)) + return Py_BuildException(); + float fa = 1.0f; + + BYTE argb[4] = + { + (BYTE) (255.0f * fb), + (BYTE) (255.0f * fg), + (BYTE) (255.0f * fr), + (BYTE) (255.0f * fa) + }; + ((UI::CTextLine*)pWindow)->SetFontColor(*((DWORD *) argb)); + } + else + { + return Py_BuildException(); + } + + return Py_BuildNone(); +} +PyObject * wndTextSetLimitWidth(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + float fWidth; + if (!PyTuple_GetFloat(poArgs, 1, &fWidth)) + return Py_BuildException(); + + ((UI::CTextLine*)pWindow)->SetLimitWidth(fWidth); + return Py_BuildNone(); +} +PyObject * wndTextSetText(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + char * szText; + if (!PyTuple_GetString(poArgs, 1, &szText)) + return Py_BuildException(); + + ((UI::CTextLine*)pWindow)->SetText(szText); + return Py_BuildNone(); +} +PyObject * wndTextGetText(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + return Py_BuildValue("s", ((UI::CTextLine*)pWindow)->GetText()); +} + +PyObject * wndTextGetTextSize(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + int nWidth; + int nHeight; + + UI::CTextLine* pkTextLine=(UI::CTextLine*)pWindow; + pkTextLine->GetTextSize(&nWidth, &nHeight); + + return Py_BuildValue("(ii)", nWidth, nHeight); +} + + +PyObject * wndTextShowCursor(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + ((UI::CTextLine*)pWindow)->ShowCursor(); + return Py_BuildNone(); +} +PyObject * wndTextHideCursor(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + ((UI::CTextLine*)pWindow)->HideCursor(); + return Py_BuildNone(); +} +PyObject * wndTextGetCursorPosition(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + return Py_BuildValue("i", ((UI::CTextLine*)pWindow)->GetCursorPosition()); +} + +PyObject * wndNumberSetNumber(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + char * szNumber; + if (!PyTuple_GetString(poArgs, 1, &szNumber)) + return Py_BuildException(); + + ((UI::CNumberLine*)pWindow)->SetNumber(szNumber); + + return Py_BuildNone(); +} + +PyObject * wndNumberSetNumberHorizontalAlignCenter(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + ((UI::CNumberLine*)pWindow)->SetHorizontalAlign(UI::CWindow::HORIZONTAL_ALIGN_CENTER); + + return Py_BuildNone(); +} + +PyObject * wndNumberSetNumberHorizontalAlignRight(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + ((UI::CNumberLine*)pWindow)->SetHorizontalAlign(UI::CWindow::HORIZONTAL_ALIGN_RIGHT); + + return Py_BuildNone(); +} + +PyObject * wndNumberSetPath(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + char * szPath; + if (!PyTuple_GetString(poArgs, 1, &szPath)) + return Py_BuildException(); + + ((UI::CNumberLine*)pWindow)->SetPath(szPath); + + return Py_BuildNone(); +} + +PyObject * wndMarkBox_SetImageFilename(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + char * szFileName; + if (!PyTuple_GetString(poArgs, 1, &szFileName)) + return Py_BuildException(); + + ((UI::CMarkBox*)pWindow)->LoadImage(szFileName); + return Py_BuildNone(); +} + +PyObject * wndMarkBox_SetImage(PyObject * poSelf, PyObject * poArgs) +{ + // ƹ͵ + return Py_BuildNone(); +} + +PyObject * wndMarkBox_Load(PyObject * poSelf, PyObject * poArgs) +{ + // ƹ͵ + return Py_BuildNone(); +} + +PyObject * wndMarkBox_SetIndex(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + int nIndex; + if (!PyTuple_GetInteger(poArgs, 1, &nIndex)) + return Py_BuildException(); + + ((UI::CMarkBox*)pWindow)->SetIndex(nIndex); + return Py_BuildNone(); +} + +PyObject * wndMarkBox_SetScale(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + float fScale; + if (!PyTuple_GetFloat(poArgs, 1, &fScale)) + return Py_BuildException(); + + ((UI::CMarkBox*)pWindow)->SetScale(fScale); + return Py_BuildNone(); +} + + +PyObject * wndMarkBox_SetDiffuseColor(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + float fr; + if (!PyTuple_GetFloat(poArgs, 1, &fr)) + return Py_BuildException(); + float fg; + if (!PyTuple_GetFloat(poArgs, 2, &fg)) + return Py_BuildException(); + float fb; + if (!PyTuple_GetFloat(poArgs, 3, &fb)) + return Py_BuildException(); + float fa; + if (!PyTuple_GetFloat(poArgs, 4, &fa)) + return Py_BuildException(); + + ((UI::CMarkBox*)pWindow)->SetDiffuseColor(fr, fg, fb, fa); + + return Py_BuildNone(); +} + + +PyObject * wndImageLoadImage(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + char * szFileName; + if (!PyTuple_GetString(poArgs, 1, &szFileName)) + return Py_BuildException(); + + if (!((UI::CImageBox*)pWindow)->LoadImage(szFileName)) + return Py_BuildException("Failed to load image (filename: %s)", szFileName); + + return Py_BuildNone(); +} + +PyObject * wndImageSetDiffuseColor(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + float fr; + if (!PyTuple_GetFloat(poArgs, 1, &fr)) + return Py_BuildException(); + float fg; + if (!PyTuple_GetFloat(poArgs, 2, &fg)) + return Py_BuildException(); + float fb; + if (!PyTuple_GetFloat(poArgs, 3, &fb)) + return Py_BuildException(); + float fa; + if (!PyTuple_GetFloat(poArgs, 4, &fa)) + return Py_BuildException(); + + ((UI::CImageBox*)pWindow)->SetDiffuseColor(fr, fg, fb, fa); + + return Py_BuildNone(); +} + +PyObject * wndImageGetWidth(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + return Py_BuildValue("i", ((UI::CImageBox*)pWindow)->GetWidth()); +} + +PyObject * wndImageGetHeight(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + return Py_BuildValue("i", ((UI::CImageBox*)pWindow)->GetHeight()); +} + +PyObject * wndImageSetScale(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + float fx; + if (!PyTuple_GetFloat(poArgs, 1, &fx)) + return Py_BuildException(); + float fy; + if (!PyTuple_GetFloat(poArgs, 2, &fy)) + return Py_BuildException(); + + ((UI::CExpandedImageBox*)pWindow)->SetScale(fx, fy); + + return Py_BuildNone(); +} +PyObject * wndImageSetOrigin(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + float fx; + if (!PyTuple_GetFloat(poArgs, 1, &fx)) + return Py_BuildException(); + float fy; + if (!PyTuple_GetFloat(poArgs, 2, &fy)) + return Py_BuildException(); + + ((UI::CExpandedImageBox*)pWindow)->SetOrigin(fx, fy); + + return Py_BuildNone(); +} +PyObject * wndImageSetRotation(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + float fRotation; + if (!PyTuple_GetFloat(poArgs, 1, &fRotation)) + return Py_BuildException(); + + ((UI::CExpandedImageBox*)pWindow)->SetRotation(fRotation); + + return Py_BuildNone(); +} +PyObject * wndImageSetRenderingRect(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + float fLeft; + if (!PyTuple_GetFloat(poArgs, 1, &fLeft)) + return Py_BuildException(); + float fTop; + if (!PyTuple_GetFloat(poArgs, 2, &fTop)) + return Py_BuildException(); + float fRight; + if (!PyTuple_GetFloat(poArgs, 3, &fRight)) + return Py_BuildException(); + float fBottom; + if (!PyTuple_GetFloat(poArgs, 4, &fBottom)) + return Py_BuildException(); + + if (pWindow->IsType(UI::CExpandedImageBox::Type())) + ((UI::CExpandedImageBox*)pWindow)->SetRenderingRect(fLeft, fTop, fRight, fBottom); + else if (pWindow->IsType(UI::CAniImageBox::Type())) + ((UI::CAniImageBox*)pWindow)->SetRenderingRect(fLeft, fTop, fRight, fBottom); + + return Py_BuildNone(); +} +PyObject * wndImageSetRenderingMode(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + int iMode; + if (!PyTuple_GetInteger(poArgs, 1, &iMode)) + return Py_BuildException(); + + if (pWindow->IsType(UI::CExpandedImageBox::Type())) + ((UI::CExpandedImageBox*)pWindow)->SetRenderingMode(iMode); + + return Py_BuildNone(); +} +PyObject * wndImageSetDelay(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + float fDelay; + if (!PyTuple_GetFloat(poArgs, 1, &fDelay)) + return Py_BuildException(); + + ((UI::CAniImageBox*)pWindow)->SetDelay(fDelay); + + return Py_BuildNone(); +} +PyObject * wndImageAppendImage(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + char * szFileName; + if (!PyTuple_GetString(poArgs, 1, &szFileName)) + return Py_BuildException(); + + ((UI::CAniImageBox*)pWindow)->AppendImage(szFileName); + + return Py_BuildNone(); +} + +PyObject * wndButtonSetUpVisual(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + char * szFileName; + if (!PyTuple_GetString(poArgs, 1, &szFileName)) + return Py_BuildException(); + + ((UI::CButton*)pWindow)->SetUpVisual(szFileName); + + return Py_BuildNone(); +} +PyObject * wndButtonSetOverVisual(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + char * szFileName; + if (!PyTuple_GetString(poArgs, 1, &szFileName)) + return Py_BuildException(); + + ((UI::CButton*)pWindow)->SetOverVisual(szFileName); + + return Py_BuildNone(); +} +PyObject * wndButtonSetDownVisual(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + char * szFileName; + if (!PyTuple_GetString(poArgs, 1, &szFileName)) + return Py_BuildException(); + + ((UI::CButton*)pWindow)->SetDownVisual(szFileName); + + return Py_BuildNone(); +} +PyObject * wndButtonSetDisableVisual(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + char * szFileName; + if (!PyTuple_GetString(poArgs, 1, &szFileName)) + return Py_BuildException(); + + ((UI::CButton*)pWindow)->SetDisableVisual(szFileName); + + return Py_BuildNone(); +} +PyObject * wndButtonGetUpVisualFileName(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + return Py_BuildValue("s", ((UI::CButton*)pWindow)->GetUpVisualFileName()); +} +PyObject * wndButtonGetOverVisualFileName(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + return Py_BuildValue("s", ((UI::CButton*)pWindow)->GetOverVisualFileName()); +} +PyObject * wndButtonGetDownVisualFileName(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + return Py_BuildValue("s", ((UI::CButton*)pWindow)->GetDownVisualFileName()); +} +PyObject * wndButtonFlash(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + ((UI::CButton*)pWindow)->Flash(); + + return Py_BuildNone(); +} +PyObject * wndButtonEnable(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + ((UI::CButton*)pWindow)->Enable(); + + return Py_BuildNone(); +} +PyObject * wndButtonDisable(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + ((UI::CButton*)pWindow)->Disable(); + + return Py_BuildNone(); +} +PyObject * wndButtonDown(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + ((UI::CButton*)pWindow)->Down(); + + return Py_BuildNone(); +} +PyObject * wndButtonSetUp(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + ((UI::CButton*)pWindow)->SetUp(); + + return Py_BuildNone(); +} +PyObject * wndButtonSetRestrictMovementArea(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + int ix; + if (!PyTuple_GetInteger(poArgs, 1, &ix)) + return Py_BuildException(); + int iy; + if (!PyTuple_GetInteger(poArgs, 2, &iy)) + return Py_BuildException(); + int iwidth; + if (!PyTuple_GetInteger(poArgs, 3, &iwidth)) + return Py_BuildException(); + int iheight; + if (!PyTuple_GetInteger(poArgs, 4, &iheight)) + return Py_BuildException(); + + ((UI::CDragButton*)pWindow)->SetRestrictMovementArea(ix, iy, iwidth, iheight); + + return Py_BuildNone(); +} + +PyObject * wndButtonIsDown(PyObject * poSelf, PyObject * poArgs) +{ + UI::CWindow * pWindow; + if (!PyTuple_GetWindow(poArgs, 0, &pWindow)) + return Py_BuildException(); + + return Py_BuildValue("i", ((UI::CButton*)pWindow)->IsPressed()); +} + +extern BOOL g_bOutlineBoxEnable; +extern BOOL g_bShowOverInWindowName; + +PyObject * wndMgrSetOutlineFlag(PyObject * poSelf, PyObject * poArgs) +{ + int iFlag; + if (!PyTuple_GetInteger(poArgs, 0, &iFlag)) + return Py_BuildException(); + + g_bOutlineBoxEnable = iFlag; + + return Py_BuildNone(); +} + +PyObject * wndMgrShowOverInWindowName(PyObject * poSelf, PyObject * poArgs) +{ + int iFlag; + if (!PyTuple_GetInteger(poArgs, 0, &iFlag)) + return Py_BuildException(); + + g_bShowOverInWindowName = iFlag; + + return Py_BuildNone(); +} + +void initwndMgr() +{ + static PyMethodDef s_methods[] = + { + // WindowManager + { "SetMouseHandler", wndMgrSetMouseHandler, METH_VARARGS }, + { "SetScreenSize", wndMgrSetScreenSize, METH_VARARGS }, + { "GetScreenWidth", wndMgrGetScreenWidth, METH_VARARGS }, + { "GetScreenHeight", wndMgrGetScreenHeight, METH_VARARGS }, + { "AttachIcon", wndMgrAttachIcon, METH_VARARGS }, + { "DeattachIcon", wndMgrDeattachIcon, METH_VARARGS }, + { "SetAttachingFlag", wndMgrSetAttachingFlag, METH_VARARGS }, + { "GetAspect", wndMgrGetAspect, METH_VARARGS }, + { "GetHyperlink", wndMgrGetHyperlink, METH_VARARGS }, + { "OnceIgnoreMouseLeftButtonUpEvent", wndMgrOnceIgnoreMouseLeftButtonUpEvent, METH_VARARGS }, + + // Window + { "Register", wndMgrRegister, METH_VARARGS }, + { "RegisterSlotWindow", wndMgrRegisterSlotWindow, METH_VARARGS }, + { "RegisterGridSlotWindow", wndMgrRegisterGridSlotWindow, METH_VARARGS }, + { "RegisterTextLine", wndMgrRegisterTextLine, METH_VARARGS }, + { "RegisterMarkBox", wndMgrRegisterMarkBox, METH_VARARGS }, + { "RegisterImageBox", wndMgrRegisterImageBox, METH_VARARGS }, + { "RegisterExpandedImageBox", wndMgrRegisterExpandedImageBox, METH_VARARGS }, + { "RegisterAniImageBox", wndMgrRegisterAniImageBox, METH_VARARGS }, + { "RegisterButton", wndMgrRegisterButton, METH_VARARGS }, + { "RegisterRadioButton", wndMgrRegisterRadioButton, METH_VARARGS }, + { "RegisterToggleButton", wndMgrRegisterToggleButton, METH_VARARGS }, + { "RegisterDragButton", wndMgrRegisterDragButton, METH_VARARGS }, + { "RegisterBox", wndMgrRegisterBox, METH_VARARGS }, + { "RegisterBar", wndMgrRegisterBar, METH_VARARGS }, + { "RegisterLine", wndMgrRegisterLine, METH_VARARGS }, + { "RegisterBar3D", wndMgrRegisterBar3D, METH_VARARGS }, + { "RegisterNumberLine", wndMgrRegisterNumberLine, METH_VARARGS }, + { "Destroy", wndMgrDestroy, METH_VARARGS }, + { "AddFlag", wndMgrAddFlag, METH_VARARGS }, + { "IsRTL", wndMgrIsRTL, METH_VARARGS }, + + // Base Window + { "SetName", wndMgrSetName, METH_VARARGS }, + { "GetName", wndMgrGetName, METH_VARARGS }, + + { "SetTop", wndMgrSetTop, METH_VARARGS }, + { "Show", wndMgrShow, METH_VARARGS }, + { "Hide", wndMgrHide, METH_VARARGS }, + { "IsShow", wndMgrIsShow, METH_VARARGS }, + { "SetParent", wndMgrSetParent, METH_VARARGS }, + { "SetPickAlways", wndMgrSetPickAlways, METH_VARARGS }, + + { "IsFocus", wndMgrIsFocus, METH_VARARGS }, + { "SetFocus", wndMgrSetFocus, METH_VARARGS }, + { "KillFocus", wndMgrKillFocus, METH_VARARGS }, + { "Lock", wndMgrLock, METH_VARARGS }, + { "Unlock", wndMgrUnlock, METH_VARARGS }, + + { "SetWindowSize", wndMgrSetWndSize, METH_VARARGS }, + { "SetWindowPosition", wndMgrSetWndPosition, METH_VARARGS }, + { "GetWindowWidth", wndMgrGetWndWidth, METH_VARARGS }, + { "GetWindowHeight", wndMgrGetWndHeight, METH_VARARGS }, + { "GetWindowLocalPosition", wndMgrGetWndLocalPosition, METH_VARARGS }, + { "GetWindowGlobalPosition", wndMgrGetWndGlobalPosition, METH_VARARGS }, + { "GetWindowRect", wndMgrGetWindowRect, METH_VARARGS }, + { "SetWindowHorizontalAlign", wndMgrSetWindowHorizontalAlign, METH_VARARGS }, + { "SetWindowVerticalAlign", wndMgrSetWindowVerticalAlign, METH_VARARGS }, + + { "GetChildCount", wndMgrGetChildCount, METH_VARARGS }, + + { "IsPickedWindow", wndMgrIsPickedWindow, METH_VARARGS }, + { "IsIn", wndMgrIsIn, METH_VARARGS }, + { "GetMouseLocalPosition", wndMgrGetMouseLocalPosition, METH_VARARGS }, + { "GetMousePosition", wndMgrGetMousePosition, METH_VARARGS }, + { "IsDragging", wndMgrIsDragging, METH_VARARGS }, + + { "SetLimitBias", wndMgrSetLimitBias, METH_VARARGS }, + + { "UpdateRect", wndMgrUpdateRect, METH_VARARGS }, + + // Slot Window + { "AppendSlot", wndMgrAppendSlot, METH_VARARGS }, + { "ArrangeSlot", wndMgrArrangeSlot, METH_VARARGS }, + { "ClearSlot", wndMgrClearSlot, METH_VARARGS }, + { "ClearAllSlot", wndMgrClearAllSlot, METH_VARARGS }, + { "HasSlot", wndMgrHasSlot, METH_VARARGS }, + { "SetSlot", wndMgrSetSlot, METH_VARARGS }, + { "SetSlotCount", wndMgrSetSlotCount, METH_VARARGS }, + { "SetSlotCountNew", wndMgrSetSlotCountNew, METH_VARARGS }, + { "SetSlotCoolTime", wndMgrSetSlotCoolTime, METH_VARARGS }, + { "SetToggleSlot", wndMgrSetToggleSlot, METH_VARARGS }, + { "ActivateSlot", wndMgrActivateSlot, METH_VARARGS }, + { "DeactivateSlot", wndMgrDeactivateSlot, METH_VARARGS }, + { "EnableSlot", wndMgrEnableSlot, METH_VARARGS }, + { "DisableSlot", wndMgrDisableSlot, METH_VARARGS }, + { "ShowSlotBaseImage", wndMgrShowSlotBaseImage, METH_VARARGS }, + { "HideSlotBaseImage", wndMgrHideSlotBaseImage, METH_VARARGS }, + { "SetSlotType", wndMgrSetSlotType, METH_VARARGS }, + { "SetSlotStyle", wndMgrSetSlotStyle, METH_VARARGS }, + { "SetSlotBaseImage", wndMgrSetSlotBaseImage, METH_VARARGS }, + + { "SetCoverButton", wndMgrSetCoverButton, METH_VARARGS }, + { "EnableCoverButton", wndMgrEnableCoverButton, METH_VARARGS }, + { "DisableCoverButton", wndMgrDisableCoverButton, METH_VARARGS }, + { "IsDisableCoverButton", wndMgrIsDisableCoverButton, METH_VARARGS }, + { "SetAlwaysRenderCoverButton", wndMgrSetAlwaysRenderCoverButton, METH_VARARGS }, + + { "AppendSlotButton", wndMgrAppendSlotButton, METH_VARARGS }, + { "AppendRequirementSignImage", wndMgrAppendRequirementSignImage, METH_VARARGS }, + { "ShowSlotButton", wndMgrShowSlotButton, METH_VARARGS }, + { "HideAllSlotButton", wndMgrHideAllSlotButton, METH_VARARGS }, + { "ShowRequirementSign", wndMgrShowRequirementSign, METH_VARARGS }, + { "HideRequirementSign", wndMgrHideRequirementSign, METH_VARARGS }, + { "RefreshSlot", wndMgrRefreshSlot, METH_VARARGS }, + { "SetUseMode", wndMgrSetUseMode, METH_VARARGS }, + { "SetUsableItem", wndMgrSetUsableItem, METH_VARARGS }, + + { "SelectSlot", wndMgrSelectSlot, METH_VARARGS }, + { "ClearSelected", wndMgrClearSelected, METH_VARARGS }, + { "GetSelectedSlotCount", wndMgrGetSelectedSlotCount, METH_VARARGS }, + { "GetSelectedSlotNumber", wndMgrGetSelectedSlotNumber, METH_VARARGS }, + { "IsSelectedSlot", wndMgrIsSelectedSlot, METH_VARARGS }, + { "GetSlotCount", wndMgrGetSlotCount, METH_VARARGS }, + { "LockSlot", wndMgrLockSlot, METH_VARARGS }, + { "UnlockSlot", wndMgrUnlockSlot, METH_VARARGS }, + + // Bar + { "SetColor", wndBarSetColor, METH_VARARGS }, + + // TextLine + { "SetMax", wndTextSetMax, METH_VARARGS }, + { "SetHorizontalAlign", wndTextSetHorizontalAlign, METH_VARARGS }, + { "SetVerticalAlign", wndTextSetVerticalAlign, METH_VARARGS }, + { "SetSecret", wndTextSetSecret, METH_VARARGS }, + { "SetOutline", wndTextSetOutline, METH_VARARGS }, + { "SetFeather", wndTextSetFeather, METH_VARARGS }, + { "SetMultiLine", wndTextSetMultiLine, METH_VARARGS }, + { "SetText", wndTextSetText, METH_VARARGS }, + { "SetFontName", wndTextSetFontName, METH_VARARGS }, + { "SetFontColor", wndTextSetFontColor, METH_VARARGS }, + { "SetLimitWidth", wndTextSetLimitWidth, METH_VARARGS }, + { "GetText", wndTextGetText, METH_VARARGS }, + { "GetTextSize", wndTextGetTextSize, METH_VARARGS }, + { "ShowCursor", wndTextShowCursor, METH_VARARGS }, + { "HideCursor", wndTextHideCursor, METH_VARARGS }, + { "GetCursorPosition", wndTextGetCursorPosition, METH_VARARGS }, + // NumberLine + { "SetNumber", wndNumberSetNumber, METH_VARARGS }, + { "SetNumberHorizontalAlignCenter", wndNumberSetNumberHorizontalAlignCenter, METH_VARARGS }, + { "SetNumberHorizontalAlignRight", wndNumberSetNumberHorizontalAlignRight, METH_VARARGS }, + { "SetPath", wndNumberSetPath, METH_VARARGS }, + + // ImageBox + { "MarkBox_SetImage", wndMarkBox_SetImage, METH_VARARGS }, + { "MarkBox_SetImageFilename", wndMarkBox_SetImageFilename, METH_VARARGS }, + { "MarkBox_Load", wndMarkBox_Load, METH_VARARGS }, + { "MarkBox_SetIndex", wndMarkBox_SetIndex, METH_VARARGS }, + { "MarkBox_SetScale", wndMarkBox_SetScale, METH_VARARGS }, + { "MarkBox_SetDiffuseColor", wndMarkBox_SetDiffuseColor, METH_VARARGS }, + + // ImageBox + { "LoadImage", wndImageLoadImage, METH_VARARGS }, + { "SetDiffuseColor", wndImageSetDiffuseColor, METH_VARARGS }, + { "GetWidth", wndImageGetWidth, METH_VARARGS }, + { "GetHeight", wndImageGetHeight, METH_VARARGS }, + // ExpandedImageBox + { "SetScale", wndImageSetScale, METH_VARARGS }, + { "SetOrigin", wndImageSetOrigin, METH_VARARGS }, + { "SetRotation", wndImageSetRotation, METH_VARARGS }, + { "SetRenderingRect", wndImageSetRenderingRect, METH_VARARGS }, + { "SetRenderingMode", wndImageSetRenderingMode, METH_VARARGS }, + // AniImageBox + { "SetDelay", wndImageSetDelay, METH_VARARGS }, + { "AppendImage", wndImageAppendImage, METH_VARARGS }, + + // Button + { "SetUpVisual", wndButtonSetUpVisual, METH_VARARGS }, + { "SetOverVisual", wndButtonSetOverVisual, METH_VARARGS }, + { "SetDownVisual", wndButtonSetDownVisual, METH_VARARGS }, + { "SetDisableVisual", wndButtonSetDisableVisual, METH_VARARGS }, + { "GetUpVisualFileName", wndButtonGetUpVisualFileName, METH_VARARGS }, + { "GetOverVisualFileName", wndButtonGetOverVisualFileName, METH_VARARGS }, + { "GetDownVisualFileName", wndButtonGetDownVisualFileName, METH_VARARGS }, + { "Flash", wndButtonFlash, METH_VARARGS }, + { "Enable", wndButtonEnable, METH_VARARGS }, + { "Disable", wndButtonDisable, METH_VARARGS }, + { "Down", wndButtonDown, METH_VARARGS }, + { "SetUp", wndButtonSetUp, METH_VARARGS }, + { "IsDown", wndButtonIsDown, METH_VARARGS }, + + // DragButton + { "SetRestrictMovementArea", wndButtonSetRestrictMovementArea, METH_VARARGS }, + + // For Debug + { "SetOutlineFlag", wndMgrSetOutlineFlag, METH_VARARGS }, + { "ShowOverInWindowName", wndMgrShowOverInWindowName, METH_VARARGS }, + + { NULL, NULL, NULL }, + }; + + PyObject * poModule = Py_InitModule("wndMgr", s_methods); + +// ϳ ųʸ ʹ Function Ǵ ̷ ųʸ - [levites] +// PyObject * poMgrModule = Py_InitModule("wndMgr", s_methods); +// PyObject * poTextModule = Py_InitModule("wndText", s_methods); +// PyObject * poSlotModule = Py_InitModule("wndSlot", s_methods); + + PyModule_AddIntConstant(poModule, "SLOT_STYLE_NONE", UI::SLOT_STYLE_NONE); + PyModule_AddIntConstant(poModule, "SLOT_STYLE_PICK_UP", UI::SLOT_STYLE_PICK_UP); + PyModule_AddIntConstant(poModule, "SLOT_STYLE_SELECT", UI::SLOT_STYLE_SELECT); + + PyModule_AddIntConstant(poModule, "TEXT_HORIZONTAL_ALIGN_LEFT", CGraphicTextInstance::HORIZONTAL_ALIGN_LEFT); + PyModule_AddIntConstant(poModule, "TEXT_HORIZONTAL_ALIGN_RIGHT", CGraphicTextInstance::HORIZONTAL_ALIGN_RIGHT); + PyModule_AddIntConstant(poModule, "TEXT_HORIZONTAL_ALIGN_CENTER", CGraphicTextInstance::HORIZONTAL_ALIGN_CENTER); + PyModule_AddIntConstant(poModule, "TEXT_VERTICAL_ALIGN_TOP", CGraphicTextInstance::VERTICAL_ALIGN_TOP); + PyModule_AddIntConstant(poModule, "TEXT_VERTICAL_ALIGN_BOTTOM", CGraphicTextInstance::VERTICAL_ALIGN_BOTTOM); + PyModule_AddIntConstant(poModule, "TEXT_VERTICAL_ALIGN_CENTER", CGraphicTextInstance::VERTICAL_ALIGN_CENTER); + + PyModule_AddIntConstant(poModule, "HORIZONTAL_ALIGN_LEFT", UI::CWindow::HORIZONTAL_ALIGN_LEFT); + PyModule_AddIntConstant(poModule, "HORIZONTAL_ALIGN_CENTER", UI::CWindow::HORIZONTAL_ALIGN_CENTER); + PyModule_AddIntConstant(poModule, "HORIZONTAL_ALIGN_RIGHT", UI::CWindow::HORIZONTAL_ALIGN_RIGHT); + PyModule_AddIntConstant(poModule, "VERTICAL_ALIGN_TOP", UI::CWindow::VERTICAL_ALIGN_TOP); + PyModule_AddIntConstant(poModule, "VERTICAL_ALIGN_CENTER", UI::CWindow::VERTICAL_ALIGN_CENTER); + PyModule_AddIntConstant(poModule, "VERTICAL_ALIGN_BOTTOM", UI::CWindow::VERTICAL_ALIGN_BOTTOM); + + PyModule_AddIntConstant(poModule, "RENDERING_MODE_MODULATE", CGraphicExpandedImageInstance::RENDERING_MODE_MODULATE); +} diff --git a/source/EterPythonLib/StdAfx.cpp b/source/EterPythonLib/StdAfx.cpp new file mode 100644 index 0000000..b33845b --- /dev/null +++ b/source/EterPythonLib/StdAfx.cpp @@ -0,0 +1,6 @@ +// stdafx.cpp : source file that includes just the standard includes +// eterPythonLib.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + diff --git a/source/EterPythonLib/StdAfx.h b/source/EterPythonLib/StdAfx.h new file mode 100644 index 0000000..6b9274d --- /dev/null +++ b/source/EterPythonLib/StdAfx.h @@ -0,0 +1,17 @@ +#pragma once + +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif +#include "../EterLib/StdAfx.h" +#include "../ScriptLib/StdAfx.h" + +#include "PythonGraphic.h" +#include "PythonWindowManager.h" + +void initgrp(); +void initgrpImage(); +void initgrpText(); +void initgrpThing(); +void initscriptWindow(); +void initwndMgr(); \ No newline at end of file diff --git a/source/GameLib/ActorInstance.cpp b/source/GameLib/ActorInstance.cpp new file mode 100644 index 0000000..e9f0f02 --- /dev/null +++ b/source/GameLib/ActorInstance.cpp @@ -0,0 +1,979 @@ +#include "StdAfx.h" +#include "ActorInstance.h" +#include "AreaTerrain.h" +#include "RaceData.h" +#include "../SpeedTreeLib/SpeedTreeForestDirectX8.h" +#include "../SpeedTreeLib/SpeedTreeWrapper.h" + +enum +{ + MAIN_RACE_MAX_NUM = 8, +}; + +void CActorInstance::INSTANCEBASE_Deform() +{ + Deform(); + TraceProcess(); +} + +void CActorInstance::INSTANCEBASE_Transform() +{ + if (m_pkHorse) + { + m_pkHorse->INSTANCEBASE_Transform(); + + m_x = m_pkHorse->NEW_GetCurPixelPositionRef().x; + m_y = -m_pkHorse->NEW_GetCurPixelPositionRef().y; + m_z = m_pkHorse->NEW_GetCurPixelPositionRef().z; + m_bNeedUpdateCollision = TRUE; + } + + //DWORD t2=ELTimer_GetMSec(); + Update(); + //DWORD t3=ELTimer_GetMSec(); + TransformProcess(); + //DWORD t4=ELTimer_GetMSec(); + Transform(); + //DWORD t5=ELTimer_GetMSec(); + UpdatePointInstance(); + //DWORD t6=ELTimer_GetMSec(); + ShakeProcess(); + //DWORD t7=ELTimer_GetMSec(); + UpdateBoundingSphere(); + //DWORD t8=ELTimer_GetMSec(); + UpdateAttribute(); +} + +/* +void CActorInstance::TEMP_Update() +{ + //DWORD t1=ELTimer_GetMSec(); + OnUpdate(); + //DWORD t2=ELTimer_GetMSec(); + UpdateBoundingSphere(); + //DWORD t3=ELTimer_GetMSec(); + +#ifdef __PERFORMANCE_CHECKER__ + { + static FILE* fp=fopen("perf_actor_update.txt", "w"); + + if (t3-t1>3) + { + fprintf(fp, "AIU.Total %d (Time %f)\n", + t3-t1, ELTimer_GetMSec()/1000.0f); + fprintf(fp, "AIU.UP %d\n", t2-t1); + fprintf(fp, "AIU.UBS %d\n", t3-t2); + fprintf(fp, "-------------------------------- \n"); + fflush(fp); + } + fflush(fp); + } +#endif +} +*/ + +void CActorInstance::OnUpdate() +{ +#ifdef __PERFORMANCE_CHECKER__ + DWORD t1=ELTimer_GetMSec(); +#endif + if (!IsParalysis()) + CGraphicThingInstance::OnUpdate(); +#ifdef __PERFORMANCE_CHECKER__ + DWORD t2=ELTimer_GetMSec(); +#endif + + UpdateAttachingInstances(); + +#ifdef __PERFORMANCE_CHECKER__ + DWORD t3=ELTimer_GetMSec(); +#endif + + __BlendAlpha_Update(); + +#ifdef __PERFORMANCE_CHECKER__ + DWORD t4=ELTimer_GetMSec(); + { + static FILE* fp=fopen("perf_actor_update2.txt", "w"); + + if (t4-t1>3) + { + fprintf(fp, "AIU2.Total %d (Time %f)\n", + t4-t1, ELTimer_GetMSec()/1000.0f); + fprintf(fp, "AIU2.GU %d\n", t2-t1); + fprintf(fp, "AIU2.UAI %d\n", t3-t2); + fprintf(fp, "AIU2.BAU %d\n", t4-t3); + fprintf(fp, "-------------------------------- \n"); + fflush(fp); + } + fflush(fp); + } +#endif +} + + +// 2004.07.05.myevan. ýź ʿ ̴ ذ +IBackground& CActorInstance::GetBackground() +{ + return IBackground::Instance(); +} + + +void CActorInstance::SetMainInstance() +{ + m_isMain=true; +} + +void CActorInstance::SetParalysis(bool isParalysis) +{ + m_isParalysis=isParalysis; +} + +void CActorInstance::SetFaint(bool isFaint) +{ + m_isFaint=isFaint; +} + +void CActorInstance::SetSleep(bool isSleep) +{ + m_isSleep=isSleep; + + Stop(); +} + +void CActorInstance::SetResistFallen(bool isResistFallen) +{ + m_isResistFallen=isResistFallen; +} + +void CActorInstance::SetReachScale(float fScale) +{ + m_fReachScale=fScale; +} + +float CActorInstance::__GetReachScale() +{ + return m_fReachScale; +} + +float CActorInstance::__GetAttackSpeed() +{ + return m_fAtkSpd; +} + +WORD CActorInstance::__GetCurrentComboType() +{ + if (IsBowMode()) + return 0; + if (IsHandMode()) + return 0; + if (__IsMountingHorse()) + return 0; + + return m_wcurComboType; +} + +void CActorInstance::SetComboType(WORD wComboType) +{ + m_wcurComboType = wComboType; +} + +void CActorInstance::SetAttackSpeed(float fAtkSpd) +{ + m_fAtkSpd=fAtkSpd; +} + +void CActorInstance::SetMoveSpeed(float fMovSpd) +{ + if (m_fMovSpd==fMovSpd) + return; + + m_fMovSpd=fMovSpd; + + if (__IsMoveMotion()) + { + Stop(); + Move(); + } +} + +void CActorInstance::SetFishingPosition(D3DXVECTOR3 & rv3Position) +{ + m_v3FishingPosition = rv3Position; +} + +// ActorInstanceMotion.cpp ֵ +void CActorInstance::Move() +{ + if (m_isWalking) + { + SetLoopMotion(CRaceMotionData::NAME_WALK, 0.15f, m_fMovSpd); + } + else + { + SetLoopMotion(CRaceMotionData::NAME_RUN, 0.15f, m_fMovSpd); + } +} + +void CActorInstance::Stop(float fBlendingTime) +{ + __ClearMotion(); + SetLoopMotion(CRaceMotionData::NAME_WAIT, fBlendingTime); +} + +void CActorInstance::SetOwner(DWORD dwOwnerVID) +{ + m_fOwnerBaseTime=GetLocalTime(); + m_dwOwnerVID=dwOwnerVID; +} + +void CActorInstance::SetActorType(UINT eType) +{ + m_eActorType=eType; +} + +UINT CActorInstance::GetActorType() const +{ + return m_eActorType; +} + +bool CActorInstance::IsHandMode() +{ + if (CRaceMotionData::MODE_GENERAL==GetMotionMode()) + return true; + + if (CRaceMotionData::MODE_HORSE==GetMotionMode()) + return true; + + return false; +} + +bool CActorInstance::IsTwoHandMode() +{ + if (CRaceMotionData::MODE_TWOHAND_SWORD==GetMotionMode()) + return true; + + return false; +} + +bool CActorInstance::IsBowMode() +{ + if (CRaceMotionData::MODE_BOW==GetMotionMode()) + return true; + + if (CRaceMotionData::MODE_HORSE_BOW==GetMotionMode()) + return true; + + return false; +} + +bool CActorInstance::IsPoly() +{ + if (TYPE_POLY==m_eActorType) + return true; + + if (TYPE_PC==m_eActorType) + if (m_eRace >= MAIN_RACE_MAX_NUM) + return TRUE; + + return false; +} + +bool CActorInstance::IsPC() +{ + if (TYPE_PC==m_eActorType) + return true; + + return false; +} + +bool CActorInstance::IsNPC() +{ + if (TYPE_NPC==m_eActorType) + return true; + + return false; +} + +bool CActorInstance::IsEnemy() +{ + if (TYPE_ENEMY==m_eActorType) + return true; + + return false; +} + +bool CActorInstance::IsStone() +{ + if (TYPE_STONE==m_eActorType) + return true; + + return false; +} + +bool CActorInstance::IsWarp() +{ + if (TYPE_WARP==m_eActorType) + return true; + + return false; +} + +bool CActorInstance::IsGoto() +{ + if (TYPE_GOTO==m_eActorType) + return true; + + return false; +} + +bool CActorInstance::IsBuilding() +{ + if (TYPE_BUILDING==m_eActorType) + return true; + + return false; +} + +bool CActorInstance::IsDoor() +{ + if (TYPE_DOOR==m_eActorType) + return true; + + return false; +} + +bool CActorInstance::IsObject() +{ + if (TYPE_OBJECT==m_eActorType) + return true; + + return false; +} + +void CActorInstance::DestroySystem() +{ +} + +void CActorInstance::DieEnd() +{ + Die(); + + CGraphicThingInstance::SetMotionAtEnd(); +} + +void CActorInstance::Die() +{ + if (m_isRealDead) + return; + + if (__IsMoveMotion()) + Stop(); + + SetAdvancingRotation(GetRotation()); + + if (IsStone()) + { + InterceptOnceMotion(CRaceMotionData::NAME_DEAD); + } + else + { + if (!__IsDieMotion()) + { + InterceptOnceMotion(CRaceMotionData::NAME_DEAD); + } + } + + m_isRealDead = TRUE; +} + +BOOL CActorInstance::IsSleep() +{ + return m_isSleep; +} + +BOOL CActorInstance::IsParalysis() +{ + return m_isParalysis; +} + +BOOL CActorInstance::IsFaint() +{ + return m_isFaint; +} + +BOOL CActorInstance::IsResistFallen() +{ + return m_isResistFallen; +} + +BOOL CActorInstance::IsMoving() +{ + return __IsMoveMotion(); +} + +BOOL CActorInstance::IsWaiting() +{ + return __IsWaitMotion(); +} + +BOOL CActorInstance::IsDead() +{ + return m_isRealDead; +} + +BOOL CActorInstance::IsKnockDown() +{ + return __IsKnockDownMotion(); +} + +BOOL CActorInstance::IsDamage() +{ + return __IsDamageMotion(); +} + +BOOL CActorInstance::IsAttacked() +{ + if (IsPushing()) + return TRUE; + + if (__IsDamageMotion()) + return TRUE; + + if (__IsKnockDownMotion()) + return TRUE; + + if (__IsDieMotion()) + return TRUE; + + return FALSE; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Process +void CActorInstance::PhysicsProcess() +{ + m_PhysicsObject.Update(m_fSecondElapsed); + AddMovement(m_PhysicsObject.GetXMovement(), m_PhysicsObject.GetYMovement(), 0.0f); +} + +void CActorInstance::__AccumulationMovement(float fRot) +{ + // NOTE - ϴ WAIT ̲ + // Ŀ RaceMotionData ̵Ǵ Flag ְԲ Ѵ. - [levites] + if (CRaceMotionData::NAME_WAIT == __GetCurrentMotionIndex()) + return; + + D3DXMATRIX s_matRotationZ; + D3DXMatrixRotationZ(&s_matRotationZ, D3DXToRadian(fRot)); + UpdateTransform(&s_matRotationZ, GetAverageSecondElapsed()); + + AddMovement(s_matRotationZ._41, s_matRotationZ._42, s_matRotationZ._43); +} + +void CActorInstance::AccumulationMovement() +{ + if (m_pkTree) + return; + + if (m_pkHorse) + { + m_pkHorse->__AccumulationMovement(m_fcurRotation); + return; + } + + __AccumulationMovement(m_fAdvancingRotation); +} + +void CActorInstance::TransformProcess() +{ + if (!IsParalysis()) + { + m_x += m_v3Movement.x; + m_y += m_v3Movement.y; + m_z += m_v3Movement.z; + } + + __InitializeMovement(); + + SetPosition(m_x, m_y, m_z); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Process + +void CActorInstance::OnUpdateCollisionData(const CStaticCollisionDataVector * pscdVector) +{ + assert(pscdVector); + CStaticCollisionDataVector::const_iterator it; + for(it = pscdVector->begin();it!=pscdVector->end();++it) + { + const CStaticCollisionData & c_rColliData = *it; + const D3DXMATRIX & c_rMatrix = GetTransform(); + AddCollision(&c_rColliData, &c_rMatrix); + } +} + +void CActorInstance::OnUpdateHeighInstance(CAttributeInstance * pAttributeInstance) +{ + assert(pAttributeInstance); + SetHeightInstance(pAttributeInstance); +} + +bool CActorInstance::OnGetObjectHeight(float fX, float fY, float * pfHeight) +{ + if (!m_pHeightAttributeInstance) + return false; + + if (TYPE_BUILDING != GetType()) + return false; + + return m_pHeightAttributeInstance->GetHeight(fX, fY, pfHeight) == 1 ? true : false; +} + +////////////////////////////////////////////////////////////////// +// Battle +void CActorInstance::Revive() +{ + m_isSleep = FALSE; + m_isParalysis = FALSE; + m_isFaint = FALSE; + m_isRealDead = FALSE; + m_isStun = FALSE; + m_isWalking = FALSE; + m_isMain = FALSE; + m_isResistFallen = FALSE; + + __InitializeCollisionData(); +} + +BOOL CActorInstance::IsStun() +{ + return m_isStun; +} + +void CActorInstance::Stun() +{ + m_isStun = TRUE; +} + +void CActorInstance::SetWalkMode() +{ + m_isWalking = TRUE; + if (CRaceMotionData::NAME_RUN == GET_MOTION_INDEX(m_kCurMotNode.dwMotionKey)) + SetLoopMotion(CRaceMotionData::NAME_WALK, 0.15f, m_fMovSpd); +} + +void CActorInstance::SetRunMode() +{ + m_isWalking = FALSE; + if (CRaceMotionData::NAME_WALK == GET_MOTION_INDEX(m_kCurMotNode.dwMotionKey)) + SetLoopMotion(CRaceMotionData::NAME_RUN, 0.15f, m_fMovSpd); +} + +MOTION_KEY CActorInstance::GetNormalAttackIndex() +{ + WORD wMotionIndex; + m_pkCurRaceData->GetNormalAttackIndex(GetMotionMode(), &wMotionIndex); + + return MAKE_MOTION_KEY(GetMotionMode(), wMotionIndex); +} + +////////////////////////////////////////////////////////////////// +// Movement +void CActorInstance::__InitializeMovement() +{ + m_v3Movement.x = 0.0f; + m_v3Movement.y = 0.0f; + m_v3Movement.z = 0.0f; +} + +void CActorInstance::AddMovement(float fx, float fy, float fz) +{ + m_v3Movement.x += fx; + m_v3Movement.y += fy; + m_v3Movement.z += fz; +} + +const float gc_fActorSlideMoveSpeed = 5.0f; + +void CActorInstance::AdjustDynamicCollisionMovement(const CActorInstance * c_pActorInstance) +{ + if (m_pkHorse) + { + m_pkHorse->AdjustDynamicCollisionMovement(c_pActorInstance); + return; + } + + // NOTE : Sphere Overlap ó ⸦ ϸ Penetration Ƽ ( ε ԰ --) + // Sphere Collision ġ RollBackϴ ٲ. + // BGObject ؼ. + + if (isAttacking() ) + return; + + UINT uActorType = c_pActorInstance->GetActorType(); + if( (uActorType == TYPE_BUILDING) || (uActorType == TYPE_OBJECT) || (uActorType == TYPE_DOOR) || (uActorType == TYPE_STONE)) + { + BlockMovement(); + + //Movementʱȭ + /* m_v3Movement = D3DXVECTOR3(0.f,0.f,0.f); + + TCollisionPointInstanceListIterator itMain = m_BodyPointInstanceList.begin(); + for (; itMain != m_BodyPointInstanceList.end(); ++itMain) + { + CDynamicSphereInstanceVector & c_rMainSphereVector = (*itMain).SphereInstanceVector; + for (DWORD i = 0; i < c_rMainSphereVector.size(); ++i) + { + CDynamicSphereInstance & c_rMainSphere = c_rMainSphereVector[i]; + c_rMainSphere.v3Position =c_rMainSphere.v3LastPosition; + } + }*/ + } + else + { + + float move_length = D3DXVec3Length(&m_v3Movement); + if (move_length>gc_fActorSlideMoveSpeed) + m_v3Movement*=gc_fActorSlideMoveSpeed/move_length; + + TCollisionPointInstanceListIterator itMain = m_BodyPointInstanceList.begin(); + for (; itMain != m_BodyPointInstanceList.end(); ++itMain) + { + CDynamicSphereInstanceVector & c_rMainSphereVector = (*itMain).SphereInstanceVector; + for (DWORD i = 0; i < c_rMainSphereVector.size(); ++i) + { + CDynamicSphereInstance & c_rMainSphere = c_rMainSphereVector[i]; + + TCollisionPointInstanceList::const_iterator itOpp = c_pActorInstance->m_BodyPointInstanceList.begin(); + for(;itOpp != c_pActorInstance->m_BodyPointInstanceList.end();++itOpp) + { + CSphereCollisionInstance s; + s.GetAttribute().fRadius=itOpp->SphereInstanceVector[0].fRadius; + s.GetAttribute().v3Position=itOpp->SphereInstanceVector[0].v3Position; + D3DXVECTOR3 v3Delta = s.GetCollisionMovementAdjust(c_rMainSphere); + m_v3Movement+=v3Delta; + c_rMainSphere.v3Position+=v3Delta; + + if (v3Delta.x !=0.0f || v3Delta.y !=0.0f || v3Delta.z !=0.0f ) + { + move_length = D3DXVec3Length(&m_v3Movement); + if (move_length>gc_fActorSlideMoveSpeed) + { + m_v3Movement*=gc_fActorSlideMoveSpeed/move_length; + c_rMainSphere.v3Position = c_rMainSphere.v3LastPosition; + c_rMainSphere.v3Position+=m_v3Movement; + } + } + } + } + } + } +} + + +void CActorInstance::__AdjustCollisionMovement(const CGraphicObjectInstance * c_pGraphicObjectInstance) +{ + if (m_pkHorse) + { + m_pkHorse->__AdjustCollisionMovement(c_pGraphicObjectInstance); + return; + } + + // Body ϳ մϴ. + + if (m_v3Movement.x == 0.0f && m_v3Movement.y == 0.0f && m_v3Movement.z == 0.0f) + return; + + float move_length = D3DXVec3Length(&m_v3Movement); + if (move_length>gc_fActorSlideMoveSpeed) + m_v3Movement*=gc_fActorSlideMoveSpeed/move_length; + + TCollisionPointInstanceListIterator itMain = m_BodyPointInstanceList.begin(); + for (; itMain != m_BodyPointInstanceList.end(); ++itMain) + { + CDynamicSphereInstanceVector & c_rMainSphereVector = (*itMain).SphereInstanceVector; + for (DWORD i = 0; i < c_rMainSphereVector.size(); ++i) + { + CDynamicSphereInstance & c_rMainSphere = c_rMainSphereVector[i]; + + D3DXVECTOR3 v3Delta = c_pGraphicObjectInstance->GetCollisionMovementAdjust(c_rMainSphere); + m_v3Movement+=v3Delta; + c_rMainSphere.v3Position+=v3Delta; + + if (v3Delta.x !=0.0f || v3Delta.y !=0.0f || v3Delta.z !=0.0f ) + { + move_length = D3DXVec3Length(&m_v3Movement); + if (move_length>gc_fActorSlideMoveSpeed) + { + m_v3Movement*=gc_fActorSlideMoveSpeed/move_length; + c_rMainSphere.v3Position = c_rMainSphere.v3LastPosition; + c_rMainSphere.v3Position+=m_v3Movement; + } + } + + /*if (c_pObjectInstance->CollisionDynamicSphere(c_rMainSphere)) + { + const D3DXVECTOR3 & c_rv3Position = c_pObjectInstance->GetPosition(); + //if (GetVector3Distance(c_rMainSphere.v3Position, c_rv3Position) < + // GetVector3Distance(c_rMainSphere.v3LastPosition, c_rv3Position)) + { + return TRUE; + } + + return FALSE; + }*/ + } + } +} + +BOOL CActorInstance::IsMovement() +{ + if (m_pkHorse) + if (m_pkHorse->IsMovement()) + return TRUE; + + if (0.0f != m_v3Movement.x) + return TRUE; + if (0.0f != m_v3Movement.y) + return TRUE; + if (0.0f != m_v3Movement.z) + return TRUE; + + return FALSE; +} + +float CActorInstance::GetHeight() +{ + return CGraphicThingInstance::GetHeight(); +} + +bool CActorInstance::IntersectDefendingSphere() +{ + for (TCollisionPointInstanceList::iterator it = m_DefendingPointInstanceList.begin(); it != m_DefendingPointInstanceList.end(); ++it) + { + CDynamicSphereInstanceVector & rSphereInstanceVector = (*it).SphereInstanceVector; + + CDynamicSphereInstanceVector::iterator it2 = rSphereInstanceVector.begin(); + for (; it2 != rSphereInstanceVector.end(); ++it2) + { + CDynamicSphereInstance & rInstance = *it2; + D3DXVECTOR3 v3SpherePosition = rInstance.v3Position; + float fRadius = rInstance.fRadius; + + D3DXVECTOR3 v3Orig; + D3DXVECTOR3 v3Dir; + float fRange; + ms_Ray.GetStartPoint(&v3Orig); + ms_Ray.GetDirection(&v3Dir, &fRange); + + D3DXVECTOR3 v3Distance = v3Orig - v3SpherePosition; + float b = D3DXVec3Dot(&v3Dir, &v3Distance); + float c = D3DXVec3Dot(&v3Distance, &v3Distance) - fRadius*fRadius; + + if (b*b - c >= 0) + return true; + } + } + return false; +} + +bool CActorInstance::__IsMountingHorse() +{ + return NULL != m_pkHorse; +} + +void CActorInstance::MountHorse(CActorInstance * pkHorse) +{ + m_pkHorse = pkHorse; + + if (m_pkHorse) + { + m_pkHorse->SetCurPixelPosition(NEW_GetCurPixelPositionRef()); + m_pkHorse->SetRotation(GetRotation()); + m_pkHorse->SetAdvancingRotation(GetRotation()); + } +} + +void CActorInstance::__CreateTree(const char * c_szFileName) +{ + __DestroyTree(); + + CSpeedTreeForestDirectX8& rkForest=CSpeedTreeForestDirectX8::Instance(); + m_pkTree=rkForest.CreateInstance(m_x, m_y, m_z, GetCaseCRC32(c_szFileName, strlen(c_szFileName)), c_szFileName); + m_pkTree->SetPosition(m_x, m_y, m_z); + m_pkTree->UpdateBoundingSphere(); + m_pkTree->UpdateCollisionData(); +} + +void CActorInstance::__DestroyTree() +{ + if (!m_pkTree) + return; + + CSpeedTreeForestDirectX8::Instance().DeleteInstance(m_pkTree); +} + +void CActorInstance::__SetTreePosition(float fx, float fy, float fz) +{ + if (!m_pkTree) + return; + if (m_x == fx && m_y == fy && m_z == fz) + return; + + m_pkTree->SetPosition(fx, fy, fz); + m_pkTree->UpdateBoundingSphere(); + m_pkTree->UpdateCollisionData(); +} + +void CActorInstance::ClearAttachingEffect() +{ + __ClearAttachingEffect(); +} + +void CActorInstance::Destroy() +{ + ClearFlyTargeter(); + + m_HitDataMap.clear(); + m_MotionDeque.clear(); + + if (m_pAttributeInstance) + { + m_pAttributeInstance->Clear(); + CAttributeInstance::Delete(m_pAttributeInstance); + m_pAttributeInstance = NULL; + } + + __ClearAttachingEffect(); + + CGraphicThingInstance::Clear(); + + __DestroyWeaponTrace(); + __DestroyTree(); + //m_PhysicsObject.SetActorInstance(NULL); + + + __Initialize(); +} + +void CActorInstance::__InitializeRotationData() +{ + m_fAtkDirRot = 0.0f; + m_fcurRotation = 0.0f; + m_rotBegin = 0.0f; + m_rotEnd = 0.0f; + m_rotEndTime = 0.0f; + m_rotBeginTime = 0.0f; + m_rotBlendTime = 0.0f; + m_fAdvancingRotation = 0.0f; + m_rotX = 0.0f; + m_rotY = 0.0f; +} + + +void CActorInstance::__InitializeStateData() +{ + m_bEffectInitialized = false; + + m_isPreInput = FALSE; + m_isNextPreInput = FALSE; + + m_isSleep = FALSE; + m_isParalysis = FALSE; + m_isFaint = FALSE; + m_isRealDead = FALSE; + m_isWalking = FALSE; + m_isMain = FALSE; + m_isStun = FALSE; + m_isHiding = FALSE; + m_isResistFallen = FALSE; + + m_iRenderMode = RENDER_MODE_NORMAL; + m_fAlphaValue = 0.0f; + m_AddColor = D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f); + + m_dwMtrlColor=0xffffffff; + m_dwMtrlAlpha=0xff000000; + + m_dwBattleHitEffectID = 0; + m_dwBattleAttachEffectID = 0; +} + +void CActorInstance::__InitializeMotionData() +{ + m_wcurMotionMode = CRaceMotionData::MODE_GENERAL; + m_wcurComboType = 0; + + m_fReachScale=1.0f; + m_fMovSpd=1.0f; + m_fAtkSpd=1.0f; + + m_fInvisibleTime = 0.0f; + + m_kSplashArea.isEnableHitProcess=TRUE; + m_kSplashArea.uSkill=0; + m_kSplashArea.MotionKey=0; + m_kSplashArea.fDisappearingTime = 0.0f; + m_kSplashArea.SphereInstanceVector.clear(); + m_kSplashArea.HittedInstanceMap.clear(); + + memset(&m_kCurMotNode, 0, sizeof(m_kCurMotNode)); + + __ClearCombo(); +} + +void CActorInstance::__Initialize() +{ + m_pkCurRaceMotionData=NULL; + m_pkCurRaceData=NULL; + m_pkHorse=NULL; + m_pkTree=NULL; + + m_fOwnerBaseTime=0.0f; + + m_eActorType = TYPE_PC; + m_eRace = 0; + + m_eShape = 0; + m_eHair = 0; + + m_dwSelfVID = 0; + m_dwOwnerVID = 0; + + m_pkEventHandler = NULL; + + m_PhysicsObject.Initialize(); + + m_pAttributeInstance = NULL; + + m_pFlyEventHandler = 0; + + m_v3FishingPosition = D3DXVECTOR3(0.0f, 0.0f, 0.0f); + m_iFishingEffectID = -1; + + m_pkHorse = NULL; + + __InitializePositionData(); + __InitializeRotationData(); + __InitializeMotionData(); + __InitializeStateData(); + __InitializeCollisionData(); + + __BlendAlpha_Initialize(); + + ClearFlyTargeter(); +} + +CActorInstance::CActorInstance() +{ + __Initialize(); + m_PhysicsObject.SetActorInstance(this); +} + +CActorInstance::~CActorInstance() +{ + Destroy(); +} diff --git a/source/GameLib/ActorInstance.h b/source/GameLib/ActorInstance.h new file mode 100644 index 0000000..0011a58 --- /dev/null +++ b/source/GameLib/ActorInstance.h @@ -0,0 +1,889 @@ +#pragma once + +// class CActorInstance + +// Note : ij Lighting, Local Point Light, Weapon Trace ȿ ޺ Ÿ, Ÿ, +// Ÿ ߻, ü ϴ Ŵ ̴. + +#include "FlyTarget.h" +#include "RaceData.h" +#include "RaceMotionData.h" +#include "PhysicsObject.h" +#include "ActorInstanceInterface.h" +#include "Interface.h" +//#include "../eterGrnLib/ThingInstance.h" + +class CItemData; +class CWeaponTrace; +class IFlyEventHandler; +class CSpeedTreeWrapper; + +class IMobProto : public CSingleton +{ + public: + IMobProto() {} + virtual ~IMobProto() {} + + virtual bool FindRaceType(UINT eRace, UINT* puType); +}; + +class CActorInstance : public IActorInstance, public IFlyTargetableObject +{ + public: + class IEventHandler + { + public: + static IEventHandler* GetEmptyPtr(); + + public: + struct SState + { + TPixelPosition kPPosSelf; + FLOAT fAdvRotSelf; + }; + + public: + IEventHandler() {} + virtual ~IEventHandler() {} + + virtual void OnSyncing(const SState& c_rkState) = 0; + virtual void OnWaiting(const SState& c_rkState) = 0; + virtual void OnMoving(const SState& c_rkState) = 0; + virtual void OnMove(const SState& c_rkState) = 0; + virtual void OnStop(const SState& c_rkState) = 0; + virtual void OnWarp(const SState& c_rkState) = 0; + virtual void OnSetAffect(UINT uAffect) = 0; + virtual void OnResetAffect(UINT uAffect) = 0; + virtual void OnClearAffects() = 0; + + virtual void OnAttack(const SState& c_rkState, WORD wMotionIndex) = 0; + virtual void OnUseSkill(const SState& c_rkState, UINT uMotSkill, UINT uMotLoopCount) = 0; + + virtual void OnHit(UINT uSkill, CActorInstance& rkActorVictim, BOOL isSendPacket) = 0; + + virtual void OnChangeShape() = 0; + }; + + // 2004.07.05.myevan.ýź ʿ ̴ ذ + private: + static IBackground& GetBackground(); + + public: + static bool IsDirLine(); + + public: + + enum EType + { + TYPE_ENEMY, + TYPE_NPC, + TYPE_STONE, + TYPE_WARP, + TYPE_DOOR, + TYPE_BUILDING, + TYPE_PC, + TYPE_POLY, + TYPE_HORSE, + TYPE_GOTO, + + TYPE_OBJECT, // Only For Client + }; + + enum ERenderMode + { + RENDER_MODE_NORMAL, + RENDER_MODE_BLEND, + RENDER_MODE_ADD, + RENDER_MODE_MODULATE, + }; + + ///////////////////////////////////////////////////////////////////////////////////// + // Motion Queueing System + enum EMotionPushType + { + MOTION_TYPE_NONE, + MOTION_TYPE_ONCE, + MOTION_TYPE_LOOP, + }; + + typedef struct SReservingMotionNode + { + EMotionPushType iMotionType; + + float fStartTime; + float fBlendTime; + float fDuration; + float fSpeedRatio; + + DWORD dwMotionKey; + } TReservingMotionNode; + + struct SCurrentMotionNode + { + EMotionPushType iMotionType; + DWORD dwMotionKey; + + DWORD dwcurFrame; + DWORD dwFrameCount; + + float fStartTime; + float fEndTime; + float fSpeedRatio; + + int iLoopCount; + UINT uSkill; + }; + + typedef std::deque TMotionDeque; + ///////////////////////////////////////////////////////////////////////////////////// + + ///////////////////////////////////////////////////////////////////////////////////// + // Motion Event + typedef struct SMotionEventInstance + { + int iType; + int iMotionEventIndex; + float fStartingTime; + + const CRaceMotionData::TMotionEventData * c_pMotionData; + } TMotionEventInstance; + + typedef std::list TMotionEventInstanceList; + typedef TMotionEventInstanceList::iterator TMotionEventInstanceListIterator; + ///////////////////////////////////////////////////////////////////////////////////// + + ///////////////////////////////////////////////////////////////////////////////////// + // For Collision Detection + typedef struct SCollisionPointInstance + { + const NRaceData::TCollisionData * c_pCollisionData; + BOOL isAttached; + DWORD dwModelIndex; + DWORD dwBoneIndex; + CDynamicSphereInstanceVector SphereInstanceVector; + } TCollisionPointInstance; + typedef std::list TCollisionPointInstanceList; + typedef TCollisionPointInstanceList::iterator TCollisionPointInstanceListIterator; + + typedef std::map THittedInstanceMap; + typedef std::map THitDataMap; + struct SSplashArea + { + BOOL isEnableHitProcess; + UINT uSkill; + MOTION_KEY MotionKey; + float fDisappearingTime; + const CRaceMotionData::TMotionAttackingEventData * c_pAttackingEvent; + CDynamicSphereInstanceVector SphereInstanceVector; + + THittedInstanceMap HittedInstanceMap; + }; + + typedef struct SHittingData + { + BYTE byAttackingType; + DWORD dwMotionKey; + BYTE byEventIndex; + } THittingData; + ///////////////////////////////////////////////////////////////////////////////////// + + ///////////////////////////////////////////////////////////////////////////////////// + // For Attaching + enum EAttachEffect + { + EFFECT_LIFE_NORMAL, + EFFECT_LIFE_INFINITE, + EFFECT_LIFE_WITH_MOTION, + }; + + struct TAttachingEffect + { + DWORD dwEffectIndex; + int iBoneIndex; + DWORD dwModelIndex; + D3DXMATRIX matTranslation; + BOOL isAttaching; + + int iLifeType; + DWORD dwEndTime; + }; + ///////////////////////////////////////////////////////////////////////////////////// + + public: + static void ShowDirectionLine(bool isVisible); + static void DestroySystem(); + + public: + CActorInstance(); + virtual ~CActorInstance(); + + // 20041201.myevan.νϽ̽ Լ + void INSTANCEBASE_Transform(); + void INSTANCEBASE_Deform(); + + void Destroy(); + + void Move(); + void Stop(float fBlendingTime=0.15f); + + void SetMainInstance(); + + void SetParalysis(bool isParalysis); + void SetFaint(bool isFaint); + void SetSleep(bool isSleep); + void SetResistFallen(bool isResistFallen); + + void SetAttackSpeed(float fAtkSpd); + void SetMoveSpeed(float fMovSpd); + + void SetMaterialAlpha(DWORD dwAlpha); + void SetMaterialColor(DWORD dwColor); + + void SetEventHandler(IEventHandler* pkEventHandler); + + bool SetRace(DWORD eRace); + void SetHair(DWORD eHair); + void SetVirtualID(DWORD dwVID); + + void SetShape(DWORD eShape, float fSpecular=0.0f); + void ChangeMaterial(const char * c_szFileName); + + public: + void SetComboType(WORD wComboType); + + DWORD GetRace(); + DWORD GetVirtualID(); + + UINT GetActorType() const; + void SetActorType(UINT eType); + + bool CanAct(); + bool CanMove(); + bool CanAttack(); + bool CanUseSkill(); + + bool IsPC(); + bool IsNPC(); + bool IsEnemy(); + bool IsStone(); + bool IsWarp(); + bool IsGoto(); + bool IsObject(); + bool IsDoor(); + bool IsPoly(); + + bool IsBuilding(); + + bool IsHandMode(); + bool IsBowMode(); + bool IsTwoHandMode(); + + void AttachWeapon(DWORD dwItemIndex,DWORD dwParentPartIndex = CRaceData::PART_MAIN, DWORD dwPartIndex = CRaceData::PART_WEAPON); + void AttachWeapon(DWORD dwParentPartIndex, DWORD dwPartIndex, CItemData * pItemData); + + void RefreshActorInstance(); + DWORD GetPartItemID(DWORD dwPartIndex); + + // Attach Effect + BOOL GetAttachingBoneName(DWORD dwPartIndex, const char ** c_szBoneName); + void UpdateAttachingInstances(); + void DettachEffect(DWORD dwEID); + DWORD AttachEffectByName(DWORD dwParentPartIndex, const char * c_pszBoneName, const char * c_pszEffectFileName); + DWORD AttachEffectByID(DWORD dwParentPartIndex, const char * c_pszBoneName, DWORD dwEffectID, const D3DXVECTOR3 * c_pv3Position = NULL); + DWORD AttachSmokeEffect(DWORD eSmoke); + + ///////////////////////////////////////////////////////////////////////////////////// + // Motion Queueing System + void SetMotionMode(int iMotionMode); // FIXME : ð ϰԲ Ѵ. + int GetMotionMode(); + void SetLoopMotion(DWORD dwMotion, float fBlendTime = 0.1f, float fSpeedRatio=1.0f); + bool InterceptOnceMotion(DWORD dwMotion, float fBlendTime = 0.1f, UINT uSkill=0, float fSpeedRatio=1.0f); + bool InterceptLoopMotion(DWORD dwMotion, float fBlendTime = 0.1f); + bool PushOnceMotion(DWORD dwMotion, float fBlendTime = 0.1f, float fSpeedRatio=1.0f); // FIXME : ð ϰԲ Ѵ. + bool PushLoopMotion(DWORD dwMotion, float fBlendTime = 0.1f, float fSpeedRatio=1.0f); // FIXME : ð ϰԲ Ѵ. + void SetMotionLoopCount(int iCount); + + bool IsPushing(); + + BOOL isLock(); + BOOL IsUsingSkill(); + BOOL CanCheckAttacking(); + BOOL CanCancelSkill(); + ///////////////////////////////////////////////////////////////////////////////////// + + ///////////////////////////////////////////////////////////////////////////////////// + // Collison Detection + bool CreateCollisionInstancePiece(DWORD dwAttachingModelIndex, const NRaceData::TAttachingData * c_pAttachingData, TCollisionPointInstance * pPointInstance); + + void UpdatePointInstance(); + void UpdatePointInstance(TCollisionPointInstance * pPointInstance); + bool CheckCollisionDetection(const CDynamicSphereInstanceVector * c_pAttackingSphereVector, D3DXVECTOR3 * pv3Position); + + // Collision Detection Checking + virtual bool TestCollisionWithDynamicSphere(const CDynamicSphereInstance & dsi); + + void UpdateAdvancingPointInstance(); + + BOOL IsClickableDistanceDestInstance(CActorInstance & rkInstDst, float fDistance); + + bool AvoidObject(const CGraphicObjectInstance& c_rkBGObj); + bool IsBlockObject(const CGraphicObjectInstance& c_rkBGObj); + void BlockMovement(); + ///////////////////////////////////////////////////////////////////////////////////// + + protected: + BOOL __TestObjectCollision(const CGraphicObjectInstance * c_pObjectInstance); + + public: + BOOL TestActorCollision(CActorInstance & rVictim ); + BOOL TestPhysicsBlendingCollision(CActorInstance & rVictim); + + BOOL AttackingProcess(CActorInstance & rVictim); + + void PreAttack(); + ///////////////////////////////////////////////////////////////////////////////////// + + ///////////////////////////////////////////////////////////////////////////////////// + // Battle + // Input + // ű ɼ ִ ڵ + // Ʈ ÷̾ ϰ ܼ Showing Type̱ + // ˻簡 ʿ . + void InputNormalAttackCommand(float fDirRot); // Process input - Only used by player's character + bool InputComboAttackCommand(float fDirRot); // Process input - Only used by player's character + + // Command + BOOL isAttacking(); + BOOL isNormalAttacking(); + BOOL isComboAttacking(); + BOOL IsSplashAttacking(); + BOOL IsUsingMovingSkill(); + BOOL IsActEmotion(); + DWORD GetComboIndex(); + float GetAttackingElapsedTime(); + void SetBlendingPosition(const TPixelPosition & c_rPosition, float fBlendingTime = 1.0f); + void ResetBlendingPosition(); + void GetBlendingPosition(TPixelPosition * pPosition); + + BOOL NormalAttack(float fDirRot, float fBlendTime = 0.1f); + BOOL ComboAttack(DWORD wMotionIndex, float fDirRot, float fBlendTime = 0.1f); + + void Revive(); + + BOOL IsSleep(); + BOOL IsParalysis(); + BOOL IsFaint(); + BOOL IsResistFallen(); + BOOL IsWaiting(); + BOOL IsMoving(); + BOOL IsDead(); + BOOL IsStun(); + BOOL IsAttacked(); + BOOL IsDamage(); + BOOL IsKnockDown(); + void SetWalkMode(); + void SetRunMode(); + void Stun(); + void Die(); + void DieEnd(); + + void SetBattleHitEffect(DWORD dwID); + void SetBattleAttachEffect(DWORD dwID); + + MOTION_KEY GetNormalAttackIndex(); + ///////////////////////////////////////////////////////////////////////////////////// + + ///////////////////////////////////////////////////////////////////////////////////// + // Position + const D3DXVECTOR3& GetMovementVectorRef(); + const D3DXVECTOR3& GetPositionVectorRef(); + + void SetCurPixelPosition(const TPixelPosition& c_rkPPosCur); + void NEW_SetAtkPixelPosition(const TPixelPosition& c_rkPPosAtk); + void NEW_SetSrcPixelPosition(const TPixelPosition& c_rkPPosSrc); + void NEW_SetDstPixelPosition(const TPixelPosition& c_rkPPosDst); + void NEW_SetDstPixelPositionZ(float z); + + const TPixelPosition& NEW_GetAtkPixelPositionRef(); + const TPixelPosition& NEW_GetCurPixelPositionRef(); + const TPixelPosition& NEW_GetSrcPixelPositionRef(); + const TPixelPosition& NEW_GetDstPixelPositionRef(); + + const TPixelPosition& NEW_GetLastPixelPositionRef(); + + void GetPixelPosition(TPixelPosition * pPixelPosition); + void SetPixelPosition(const TPixelPosition& c_rPixelPos); + + // Rotation Command + void LookAt(float fDirRot); + void LookAt(float fx, float fy); + void LookAt(CActorInstance * pInstance); + void LookWith(CActorInstance * pInstance); + void LookAtFromXY(float x, float y, CActorInstance * pDestInstance); + + + void SetReachScale(float fScale); + void SetOwner(DWORD dwOwnerVID); + + float GetRotation(); + float GetTargetRotation(); + + float GetAdvancingRotation(); + + float GetRotatingTime(); + void SetRotation(float fRot); + void SetXYRotation(float fRotX, float fRotY); + void BlendRotation(float fRot, float fBlendTime); + void SetAdvancingRotation(float fRot); + ///////////////////////////////////////////////////////////////////////////////////// + + ///////////////////////////////////////////////////////////////////////////////////// + void MotionEventProcess(); + void MotionEventProcess(DWORD dwcurTime, int iIndex, const CRaceMotionData::TMotionEventData * c_pData); + void SoundEventProcess(BOOL bCheckFrequency); + ///////////////////////////////////////////////////////////////////////////////////// + + //// + // Rendering Functions - Temporary Place + BOOL IsMovement(); + + void RestoreRenderMode(); + + void BeginDiffuseRender(); + void EndDiffuseRender(); + void BeginOpacityRender(); + void EndOpacityRender(); + + void BeginBlendRender(); + void EndBlendRender(); + void SetBlendRenderMode(); + void SetAlphaValue(float fAlpha); + float GetAlphaValue(); + void BlendAlphaValue(float fDstAlpha, float fDuration); + void SetSpecularInfo(BOOL bEnable, int iPart, float fAlpha); + void SetSpecularInfoForce(BOOL bEnable, int iPart, float fAlpha); + + void BeginAddRender(); + void EndAddRender(); + void SetAddRenderMode(); + void SetAddColor(const D3DXCOLOR & c_rColor); + + void BeginModulateRender(); + void EndModulateRender(); + void SetModulateRenderMode(); + + void SetRenderMode(int iRenderMode); + + void RenderTrace(); + void RenderCollisionData(); + void RenderToShadowMap(); + + + protected: + void __AdjustCollisionMovement(const CGraphicObjectInstance * c_pGraphicObjectInstance); + + public: + void AdjustDynamicCollisionMovement(const CActorInstance * c_pActorInstance); + + // Weapon Trace + void SetWeaponTraceTexture(const char * szTextureName); + void UseTextureWeaponTrace(); + void UseAlphaWeaponTrace(); + + // ETC + void UpdateAttribute(); + bool IntersectDefendingSphere(); + float GetHeight(); + void ShowAllAttachingEffect(); + void HideAllAttachingEffect(); + void ClearAttachingEffect(); + + // Fishing + bool CanFishing(); + BOOL IsFishing(); + void SetFishingPosition(D3DXVECTOR3 & rv3Position); + + // Flying Methods + // As a Flying Target + public: + virtual D3DXVECTOR3 OnGetFlyTargetPosition(); + + void OnShootDamage(); + + // As a Shooter + // NOTE : target and target position are exclusive + public: + void ClearFlyTarget(); + bool IsFlyTargetObject(); + void AddFlyTarget(const CFlyTarget & cr_FlyTarget); + void SetFlyTarget(const CFlyTarget & cr_FlyTarget); + void LookAtFlyTarget(); + + float GetFlyTargetDistance(); + + void ClearFlyEventHandler(); + void SetFlyEventHandler(IFlyEventHandler * pHandler); + + // 2004. 07. 07. [levites] - ų Ÿ ٲ ذ ڵ + bool CanChangeTarget(); + + protected: + IFlyEventHandler * m_pFlyEventHandler; + + public: + void MountHorse(CActorInstance * pkHorse); + void HORSE_MotionProcess(BOOL isPC); + void MotionProcess(BOOL isPC); + void RotationProcess(); + void PhysicsProcess(); + void ComboProcess(); + void TransformProcess(); + void AccumulationMovement(); + void ShakeProcess(); + void TraceProcess(); + void __MotionEventProcess(BOOL isPC); + void __AccumulationMovement(float fRot); + BOOL __SplashAttackProcess(CActorInstance & rVictim); + BOOL __NormalAttackProcess(CActorInstance & rVictim); + bool __CanInputNormalAttackCommand(); + + private: + void __Shake(DWORD dwDuration); + + protected: + CFlyTarget m_kFlyTarget; + CFlyTarget m_kBackupFlyTarget; + std::deque m_kQue_kFlyTarget; + + protected: + bool __IsInSplashTime(); + + void OnUpdate(); + void OnRender(); + + BOOL isValidAttacking(); + + void ReservingMotionProcess(); + void CurrentMotionProcess(); + MOTION_KEY GetRandomMotionKey(MOTION_KEY dwMotionKey); + + float GetLastMotionTime(float fBlendTime); // NOTE : ڵ BlendTimeŭ մ ð + float GetMotionDuration(DWORD dwMotionKey); + + bool InterceptMotion(EMotionPushType iMotionType, WORD wMotion, float fBlendTime = 0.1f, UINT uSkill=0, float fSpeedRatio=1.0f); + void PushMotion(EMotionPushType iMotionType, DWORD dwMotionKey, float fBlendTime, float fSpeedRatio=1.0f); + void ProcessMotionEventEffectEvent(const CRaceMotionData::TMotionEventData * c_pData); + void ProcessMotionEventEffectToTargetEvent(const CRaceMotionData::TMotionEventData * c_pData); + void ProcessMotionEventSpecialAttacking(int iMotionEventIndex, const CRaceMotionData::TMotionEventData * c_pData); + void ProcessMotionEventSound(const CRaceMotionData::TMotionEventData * c_pData); + void ProcessMotionEventFly(const CRaceMotionData::TMotionEventData * c_pData); + void ProcessMotionEventWarp(const CRaceMotionData::TMotionEventData * c_pData); + + void AddMovement(float fx, float fy, float fz); + + bool __IsLeftHandWeapon(DWORD type); + bool __IsRightHandWeapon(DWORD type); + bool __IsWeaponTrace(DWORD weaponType); + + protected: + void __InitializeMovement(); + + protected: + void __Initialize(); + + void __ClearAttachingEffect(); + + float __GetOwnerTime(); + DWORD __GetOwnerVID(); + bool __CanPushDestActor(CActorInstance& rkActorDst); + + protected: + void __RunNextCombo(); + void __ClearCombo(); + void __OnEndCombo(); + + void __ProcessDataAttackSuccess(const NRaceData::TAttackData & c_rAttackData, CActorInstance & rVictim, const D3DXVECTOR3 & c_rv3Position, UINT uiSkill = 0, BOOL isSendPacket = TRUE); + void __ProcessMotionEventAttackSuccess(DWORD dwMotionKey, BYTE byEventIndex, CActorInstance & rVictim); + void __ProcessMotionAttackSuccess(DWORD dwMotionKey, CActorInstance & rVictim); + + + void __HitStone(CActorInstance& rVictim); + void __HitGood(CActorInstance& rVictim); + void __HitGreate(CActorInstance& rVictim); + + void __PushDirect(CActorInstance & rVictim); + void __PushCircle(CActorInstance & rVictim); + bool __isInvisible(); + void __SetFallingDirection(float fx, float fy); + + protected: + struct SSetMotionData + { + MOTION_KEY dwMotKey; + float fSpeedRatio; + float fBlendTime; + int iLoopCount; + UINT uSkill; + + SSetMotionData() + { + iLoopCount=0; + dwMotKey=0; + fSpeedRatio=1.0f; + fBlendTime=0.0f; + uSkill=0; + } + }; + + protected: + float __GetAttackSpeed(); + DWORD __SetMotion(const SSetMotionData& c_rkSetMotData, DWORD dwRandMotKey=0); // + void __ClearMotion(); + + bool __BindMotionData(DWORD dwMotionKey); // ͸ ε + void __ClearHittedActorInstanceMap(); // νϽ + + UINT __GetMotionType(); // Ÿ + + bool __IsNeedFlyTargetMotion(); // FlyTarget ʿ ΰ? + bool __HasMotionFlyEvent(); // 𰡸 °? + bool __IsWaitMotion(); // ΰ? + bool __IsMoveMotion(); // ̵ ΰ? + bool __IsAttackMotion(); // ΰ? + bool __IsComboAttackMotion(); // ޺ ΰ? + bool __IsDamageMotion(); // ΰ? + bool __IsKnockDownMotion(); // ˴ٿ ΰ? + bool __IsDieMotion(); // ΰ? + bool __IsStandUpMotion(); // Ͼ ΰ? + bool __IsMountingHorse(); + + bool __CanAttack(); // Ҽ ִ°? + bool __CanNextComboAttack(); // ޺ Ѱ? + + bool __IsComboAttacking(); // ޺ ΰ? + void __CancelComboAttack(); // ޺ + + WORD __GetCurrentMotionIndex(); + DWORD __GetCurrentMotionKey(); + + int __GetLoopCount(); + WORD __GetCurrentComboType(); + + void __ShowEvent(); + void __HideEvent(); + BOOL __IsHiding(); + BOOL __IsMovingSkill(WORD wSkillNumber); + + float __GetReachScale(); + + void __CreateAttributeInstance(CAttributeData * pData); + + bool __IsFlyTargetPC(); + bool __IsSameFlyTarget(CActorInstance * pInstance); + D3DXVECTOR3 __GetFlyTargetPosition(); + + protected: + void __DestroyWeaponTrace(); // ܻ Ѵ + void __ShowWeaponTrace(); // ܻ δ + void __HideWeaponTrace(); // ܻ + + protected: + // collision data + void OnUpdateCollisionData(const CStaticCollisionDataVector * pscdVector); + void OnUpdateHeighInstance(CAttributeInstance * pAttributeInstance); + bool OnGetObjectHeight(float fX, float fY, float * pfHeight); + + protected: + ///////////////////////////////////////////////////////////////////////////////////// + // Motion Queueing System + TMotionDeque m_MotionDeque; + SCurrentMotionNode m_kCurMotNode; + WORD m_wcurMotionMode; + ///////////////////////////////////////////////////////////////////////////////////// + + ///////////////////////////////////////////////////////////////////////////////////// + // For Collision Detection + TCollisionPointInstanceList m_BodyPointInstanceList; + TCollisionPointInstanceList m_DefendingPointInstanceList; + SSplashArea m_kSplashArea; // TODO : ؾѴ - [levites] + CAttributeInstance * m_pAttributeInstance; + ///////////////////////////////////////////////////////////////////////////////////// + + ///////////////////////////////////////////////////////////////////////////////////// + // For Battle System + std::vector m_WeaponTraceVector; + CPhysicsObject m_PhysicsObject; + + DWORD m_dwcurComboIndex; + + DWORD m_eActorType; + + DWORD m_eRace; + DWORD m_eShape; + DWORD m_eHair; + BOOL m_isPreInput; + BOOL m_isNextPreInput; + DWORD m_dwcurComboBackMotionIndex; + + WORD m_wcurComboType; + + float m_fAtkDirRot; + + CRaceData* m_pkCurRaceData; + CRaceMotionData* m_pkCurRaceMotionData; + + // Defender + float m_fInvisibleTime; + BOOL m_isHiding; + + // TODO : State ų ִ + BOOL m_isResistFallen; + BOOL m_isSleep; + BOOL m_isFaint; + BOOL m_isParalysis; + BOOL m_isStun; + BOOL m_isRealDead; + BOOL m_isWalking; + BOOL m_isMain; + + // Effect + DWORD m_dwBattleHitEffectID; + DWORD m_dwBattleAttachEffectID; + ///////////////////////////////////////////////////////////////////////////////////// + + // Fishing + D3DXVECTOR3 m_v3FishingPosition; + int m_iFishingEffectID; + + // Position + float m_x; + float m_y; + float m_z; + D3DXVECTOR3 m_v3Pos; + D3DXVECTOR3 m_v3Movement; + BOOL m_bNeedUpdateCollision; + + DWORD m_dwShakeTime; + + float m_fReachScale; + float m_fMovSpd; + float m_fAtkSpd; + + // Rotation + float m_fcurRotation; + float m_rotBegin; + float m_rotEnd; + float m_rotEndTime; + float m_rotBeginTime; + float m_rotBlendTime; + float m_fAdvancingRotation; + float m_rotX; + float m_rotY; + + float m_fOwnerBaseTime; + + // Rendering + int m_iRenderMode; + D3DXCOLOR m_AddColor; + float m_fAlphaValue; + + // Part + DWORD m_adwPartItemID[CRaceData::PART_MAX_NUM]; + + // Attached Effect + std::list m_AttachingEffectList; + bool m_bEffectInitialized; + + // material color + DWORD m_dwMtrlColor; + DWORD m_dwMtrlAlpha; + + TPixelPosition m_kPPosCur; + TPixelPosition m_kPPosSrc; + TPixelPosition m_kPPosDst; + TPixelPosition m_kPPosAtk; + + TPixelPosition m_kPPosLast; + + THitDataMap m_HitDataMap; + + CActorInstance * m_pkHorse; + CSpeedTreeWrapper * m_pkTree; + + + protected: + DWORD m_dwSelfVID; + DWORD m_dwOwnerVID; + + + protected: + void __InitializeStateData(); + void __InitializeMotionData(); + void __InitializeRotationData(); + void __InitializePositionData(); + + public: // InstanceBase ӽ÷ public + IEventHandler* __GetEventHandlerPtr(); + IEventHandler& __GetEventHandlerRef(); + + void __OnSyncing(); + void __OnWaiting(); + void __OnMoving(); + void __OnMove(); + void __OnStop(); + void __OnWarp(); + void __OnClearAffects(); + void __OnSetAffect(UINT uAffect); + void __OnResetAffect(UINT uAffect); + void __OnAttack(WORD wMotionIndex); + void __OnUseSkill(UINT uMotSkill, UINT uLoopCount, bool isMoving); + + protected: + void __OnHit(UINT uSkill, CActorInstance& rkInstVictm, BOOL isSendPacket); + + public: + void EnableSkipCollision(); + void DisableSkipCollision(); + bool CanSkipCollision(); + + protected: + void __InitializeCollisionData(); + + bool m_canSkipCollision; + + protected: + struct SBlendAlpha + { + float m_fBaseTime; + float m_fBaseAlpha; + float m_fDuration; + float m_fDstAlpha; + + DWORD m_iOldRenderMode; + bool m_isBlending; + } m_kBlendAlpha; + + void __BlendAlpha_Initialize(); + void __BlendAlpha_Apply(float fDstAlpha, float fDuration); + void __BlendAlpha_Update(); + void __BlendAlpha_UpdateFadeIn(); + void __BlendAlpha_UpdateFadeOut(); + void __BlendAlpha_UpdateComplete(); + float __BlendAlpha_GetElapsedTime(); + + void __Push(int x, int y); + + public: + void TEMP_Push(int x, int y); + bool __IsSyncing(); + + void __CreateTree(const char * c_szFileName); + void __DestroyTree(); + void __SetTreePosition(float fx, float fy, float fz); + + protected: + IEventHandler* m_pkEventHandler; + + protected: + static bool ms_isDirLine; +}; diff --git a/source/GameLib/ActorInstanceAttach.cpp b/source/GameLib/ActorInstanceAttach.cpp new file mode 100644 index 0000000..23ed42e --- /dev/null +++ b/source/GameLib/ActorInstanceAttach.cpp @@ -0,0 +1,606 @@ +#include "StdAfx.h" +#include "../EffectLib/EffectManager.h" + +#include "ActorInstance.h" +#include "ItemData.h" +#include "ItemManager.h" +#include "RaceData.h" +#include "WeaponTrace.h" + +BOOL USE_WEAPON_SPECULAR = TRUE; + +BOOL USE_VIETNAM_CONVERT_WEAPON_VNUM = FALSE; + +DWORD Vietnam_ConvertWeaponVnum(DWORD vnum) +{ + DWORD base = vnum / 10 * 10; + DWORD rest = vnum % 10; + switch (base) + { + case 10:base = 5000;break; + case 20:base = 5010;break; + case 30:base = 5020;break; + case 40:base = 5030;break; + case 50:base = 5030;break; + case 60:base = 5040;break; + case 70:base = 5040;break; + case 80:base = 5050;break; + case 90:base = 5050;break; + case 100:base = 5060;break; + case 110:base = 5060;break; + case 120:base = 5070;break; + case 130:base = 5070;break; + case 140:base = 5080;break; + case 150:base = 5080;break; + case 160:base = 5090;break; + case 170:base = 5090;break; + case 180:base = 5100;break; + case 190:base = 5100;break; + case 200:base = 5110;break; + case 210:base = 5110;break; + case 220:base = 5120;break; + case 230:base = 5120;break; + case 240:base = 5130;break; + case 250:base = 5130;break; + case 260:base = 5140;break; + case 270:base = 5140;break; + case 280:base = 5150;break; + case 290:base = 5150;break; + case 1000:base = 5000;break; + case 1010:base = 5010;break; + case 1020:base = 5020;break; + case 1030:base = 5030;break; + case 1040:base = 5040;break; + case 1050:base = 5050;break; + case 1060:base = 5060;break; + case 1070:base = 5070;break; + case 1080:base = 5080;break; + case 1090:base = 5090;break; + case 1100:base = 5100;break; + case 1110:base = 5110;break; + case 1120:base = 5120;break; + case 1130:base = 5130;break; + case 1140:base = 5140;break; + case 1150:base = 5150;break; + case 1160:base = 5150;break; + case 1170:base = 5150;break; + case 3000:base = 5000;break; + case 3010:base = 5010;break; + case 3020:base = 5020;break; + case 3030:base = 5030;break; + case 3040:base = 5040;break; + case 3050:base = 5050;break; + case 3060:base = 5060;break; + case 3070:base = 5070;break; + case 3080:base = 5080;break; + case 3090:base = 5090;break; + case 3100:base = 5100;break; + case 3110:base = 5100;break; + case 3120:base = 5110;break; + case 3130:base = 5110;break; + case 3140:base = 5120;break; + case 3150:base = 5120;break; + case 3160:base = 5130;break; + case 3170:base = 5130;break; + case 3180:base = 5140;break; + case 3190:base = 5140;break; + case 3200:base = 5150;break; + case 3210:base = 5150;break; + } + return base + rest; +} + + +DWORD CActorInstance::AttachSmokeEffect(DWORD eSmoke) +{ + if (!m_pkCurRaceData) + return 0; + + DWORD dwSmokeEffectID=m_pkCurRaceData->GetSmokeEffectID(eSmoke); + + return AttachEffectByID(0, m_pkCurRaceData->GetSmokeBone().c_str(), dwSmokeEffectID); +} + +bool CActorInstance::__IsLeftHandWeapon(DWORD type) +{ + if (CItemData::WEAPON_DAGGER == type || (CItemData::WEAPON_FAN == type && __IsMountingHorse())) + return true; + else if (CItemData::WEAPON_BOW == type) + return true; + else + return false; +} + +bool CActorInstance::__IsRightHandWeapon(DWORD type) +{ + if (CItemData::WEAPON_DAGGER == type || (CItemData::WEAPON_FAN == type && __IsMountingHorse())) + return true; + else if (CItemData::WEAPON_BOW == type) + return false; + else + return true; +} + +bool CActorInstance::__IsWeaponTrace(DWORD weaponType) +{ + switch(weaponType) + { + case CItemData::WEAPON_BELL: + case CItemData::WEAPON_FAN: + case CItemData::WEAPON_BOW: + return false; + default: + return true; + + } +} + +void CActorInstance::AttachWeapon(DWORD dwItemIndex,DWORD dwParentPartIndex, DWORD dwPartIndex) +{ + if (dwPartIndex>=CRaceData::PART_MAX_NUM) + return; + + m_adwPartItemID[dwPartIndex]=dwItemIndex; + + if (USE_VIETNAM_CONVERT_WEAPON_VNUM) + dwItemIndex = Vietnam_ConvertWeaponVnum(dwItemIndex); + + CItemData * pItemData; + if (!CItemManager::Instance().GetItemDataPointer(dwItemIndex, &pItemData)) + { + RegisterModelThing(dwPartIndex, NULL); + SetModelInstance(dwPartIndex, dwPartIndex, 0); + + RegisterModelThing(CRaceData::PART_WEAPON_LEFT, NULL); + SetModelInstance(CRaceData::PART_WEAPON_LEFT, CRaceData::PART_WEAPON_LEFT, 0); + + RefreshActorInstance(); + return; + } + + __DestroyWeaponTrace(); + //չ(ڰ ̵) ޼, ο . + if (__IsRightHandWeapon(pItemData->GetWeaponType())) + AttachWeapon(dwParentPartIndex, CRaceData::PART_WEAPON, pItemData); + if (__IsLeftHandWeapon(pItemData->GetWeaponType())) + AttachWeapon(dwParentPartIndex, CRaceData::PART_WEAPON_LEFT, pItemData); +} + +BOOL CActorInstance::GetAttachingBoneName(DWORD dwPartIndex, const char ** c_pszBoneName) +{ + return m_pkCurRaceData->GetAttachingBoneName(dwPartIndex, c_pszBoneName); +} + + +void CActorInstance::AttachWeapon(DWORD dwParentPartIndex, DWORD dwPartIndex, CItemData * pItemData) +{ +// assert(m_pkCurRaceData); + if (!pItemData) + return; + + const char * szBoneName; + if (!GetAttachingBoneName(dwPartIndex, &szBoneName)) + return; + + // NOTE : (̵ó)ܵ ° ٸ ´. Ʈ + if (CRaceData::PART_WEAPON_LEFT == dwPartIndex) + { + RegisterModelThing(dwPartIndex, pItemData->GetSubModelThing()); + } + else + { + RegisterModelThing(dwPartIndex, pItemData->GetModelThing()); + } + + for (DWORD i = 0; i < pItemData->GetLODModelThingCount(); ++i) + { + CGraphicThing * pThing; + + if (!pItemData->GetLODModelThingPointer(i, &pThing)) + continue; + + RegisterLODThing(dwPartIndex, pThing); + } + + SetModelInstance(dwPartIndex, dwPartIndex, 0); + AttachModelInstance(dwParentPartIndex, szBoneName, dwPartIndex); + + // 20041208.myevan.⽺ŧ( SetShape ش.) + if (USE_WEAPON_SPECULAR) + { + SMaterialData kMaterialData; + kMaterialData.pImage = NULL; + kMaterialData.isSpecularEnable = TRUE; + kMaterialData.fSpecularPower = pItemData->GetSpecularPowerf(); + kMaterialData.bSphereMapIndex = 1; + SetMaterialData(dwPartIndex, NULL, kMaterialData); + } + + // Weapon Trace + if (__IsWeaponTrace(pItemData->GetWeaponType())) + { + CWeaponTrace * pWeaponTrace = CWeaponTrace::New(); + pWeaponTrace->SetWeaponInstance(this, dwPartIndex, szBoneName); + m_WeaponTraceVector.push_back(pWeaponTrace); + } +} + +void CActorInstance::DettachEffect(DWORD dwEID) +{ + std::list::iterator i = m_AttachingEffectList.begin(); + + while (i != m_AttachingEffectList.end()) + { + TAttachingEffect & rkAttEft = (*i); + + if (rkAttEft.dwEffectIndex == dwEID) + { + i = m_AttachingEffectList.erase(i); + CEffectManager::Instance().DestroyEffectInstance(dwEID); + } + else + { + ++i; + } + } +} + +DWORD CActorInstance::AttachEffectByName(DWORD dwParentPartIndex, const char * c_pszBoneName, const char * c_pszEffectName) +{ + std::string str; + DWORD dwCRC; + StringPath(c_pszEffectName, str); + dwCRC = GetCaseCRC32(str.c_str(), str.length()); + + return AttachEffectByID(dwParentPartIndex, c_pszBoneName, dwCRC); +} + +DWORD CActorInstance::AttachEffectByID(DWORD dwParentPartIndex, const char * c_pszBoneName, DWORD dwEffectID, const D3DXVECTOR3 * c_pv3Position) +{ + TAttachingEffect ae; + ae.iLifeType = EFFECT_LIFE_INFINITE; + ae.dwEndTime = 0; + ae.dwModelIndex = dwParentPartIndex; + ae.dwEffectIndex = CEffectManager::Instance().GetEmptyIndex(); + ae.isAttaching = TRUE; + if (c_pv3Position) + { + D3DXMatrixTranslation(&ae.matTranslation, c_pv3Position->x, c_pv3Position->y, c_pv3Position->z); + } + else + { + D3DXMatrixIdentity(&ae.matTranslation); + } + CEffectManager& rkEftMgr=CEffectManager::Instance(); + rkEftMgr.CreateEffectInstance(ae.dwEffectIndex, dwEffectID); + + if (c_pszBoneName) + { + int iBoneIndex; + + if (!FindBoneIndex(dwParentPartIndex,c_pszBoneName, &iBoneIndex)) + { + ae.iBoneIndex = -1; + //Tracef("Cannot get Bone Index\n"); + //assert(false && "Cannot get Bone Index"); + } + else + { + ae.iBoneIndex = iBoneIndex; + } + } + else + { + ae.iBoneIndex = -1; + } + + m_AttachingEffectList.push_back(ae); + + return ae.dwEffectIndex; +} + +void CActorInstance::RefreshActorInstance() +{ + if (!m_pkCurRaceData) + { + TraceError("void CActorInstance::RefreshActorInstance() - m_pkCurRaceData=NULL"); + return; + } + + // This is Temporary place before making the weapon detection system + // Setup Collison Detection Data + m_BodyPointInstanceList.clear(); + //m_AttackingPointInstanceList.clear(); + m_DefendingPointInstanceList.clear(); + + // Base + for (DWORD i = 0; i < m_pkCurRaceData->GetAttachingDataCount(); ++i) + { + const NRaceData::TAttachingData * c_pAttachingData; + + if (!m_pkCurRaceData->GetAttachingDataPointer(i, &c_pAttachingData)) + continue; + + switch (c_pAttachingData->dwType) + { + case NRaceData::ATTACHING_DATA_TYPE_COLLISION_DATA: + { + const NRaceData::TCollisionData * c_pCollisionData = c_pAttachingData->pCollisionData; + + TCollisionPointInstance PointInstance; + if (NRaceData::COLLISION_TYPE_ATTACKING == c_pCollisionData->iCollisionType) + continue; + + if (!CreateCollisionInstancePiece(CRaceData::PART_MAIN, c_pAttachingData, &PointInstance)) + continue; + + switch (c_pCollisionData->iCollisionType) + { + case NRaceData::COLLISION_TYPE_ATTACKING: + //m_AttackingPointInstanceList.push_back(PointInstance); + break; + case NRaceData::COLLISION_TYPE_DEFENDING: + m_DefendingPointInstanceList.push_back(PointInstance); + break; + case NRaceData::COLLISION_TYPE_BODY: + m_BodyPointInstanceList.push_back(PointInstance); + break; + } + } + break; + + case NRaceData::ATTACHING_DATA_TYPE_EFFECT: +// if (!m_bEffectInitialized) +// { +// DWORD dwCRC; +// StringPath(c_pAttachingData->pEffectData->strFileName); +// dwCRC = GetCaseCRC32(c_pAttachingData->pEffectData->strFileName.c_str(),c_pAttachingData->pEffectData->strFileName.length()); +// +// TAttachingEffect ae; +// ae.iLifeType = EFFECT_LIFE_INFINITE; +// ae.dwEndTime = 0; +// ae.dwModelIndex = 0; +// ae.dwEffectIndex = CEffectManager::Instance().GetEmptyIndex(); +// ae.isAttaching = TRUE; +// CEffectManager::Instance().CreateEffectInstance(ae.dwEffectIndex, dwCRC); +// +// if (c_pAttachingData->isAttaching) +// { +// int iBoneIndex; +// if (!FindBoneIndex(0,c_pAttachingData->strAttachingBoneName.c_str(), &iBoneIndex)) +// { +// Tracef("Cannot get Bone Index\n"); +// assert(false/*Cannot get Bone Index*/); +// } +// +// ae.iBoneIndex = iBoneIndex; +// } +// else +// { +// ae.iBoneIndex = -1; +// } +// +// m_AttachingEffectList.push_back(ae); +// } + + if (c_pAttachingData->isAttaching) + { + AttachEffectByName(0, c_pAttachingData->strAttachingBoneName.c_str(), c_pAttachingData->pEffectData->strFileName.c_str()); + } + else + { + AttachEffectByName(0, 0, c_pAttachingData->pEffectData->strFileName.c_str()); + } + break; + + case NRaceData::ATTACHING_DATA_TYPE_OBJECT: + break; + + default: + assert(false/*NOT_IMPLEMENTED*/); + break; + } + } + + for (DWORD j = 0; j < CRaceData::PART_MAX_NUM; ++j) + { + if (0 == m_adwPartItemID[j]) + continue; + + CItemData * pItemData; + if (!CItemManager::Instance().GetItemDataPointer(m_adwPartItemID[j], &pItemData)) + return; + + for (DWORD k = 0; k < pItemData->GetAttachingDataCount(); ++k) + { + const NRaceData::TAttachingData * c_pAttachingData; + + if (!pItemData->GetAttachingDataPointer(k, &c_pAttachingData)) + continue; + + switch(c_pAttachingData->dwType) + { + case NRaceData::ATTACHING_DATA_TYPE_COLLISION_DATA: + { + const NRaceData::TCollisionData * c_pCollisionData = c_pAttachingData->pCollisionData; + + // FIXME : ù° ڴ Part ȣ. + // Base 0ΰ? - [levites] + TCollisionPointInstance PointInstance; + if (NRaceData::COLLISION_TYPE_ATTACKING == c_pCollisionData->iCollisionType) + continue; + if (!CreateCollisionInstancePiece(j, c_pAttachingData, &PointInstance)) + continue; + + switch (c_pCollisionData->iCollisionType) + { + case NRaceData::COLLISION_TYPE_ATTACKING: + //m_AttackingPointInstanceList.push_back(PointInstance); + break; + case NRaceData::COLLISION_TYPE_DEFENDING: + m_DefendingPointInstanceList.push_back(PointInstance); + break; + case NRaceData::COLLISION_TYPE_BODY: + m_BodyPointInstanceList.push_back(PointInstance); + break; + } + } + break; + + case NRaceData::ATTACHING_DATA_TYPE_EFFECT: + if (!m_bEffectInitialized) + { + DWORD dwCRC; + StringPath(c_pAttachingData->pEffectData->strFileName); + dwCRC = GetCaseCRC32(c_pAttachingData->pEffectData->strFileName.c_str(),c_pAttachingData->pEffectData->strFileName.length()); + + TAttachingEffect ae; + ae.iLifeType = EFFECT_LIFE_INFINITE; + ae.dwEndTime = 0; + ae.dwModelIndex = j; + ae.dwEffectIndex = CEffectManager::Instance().GetEmptyIndex(); + ae.isAttaching = TRUE; + CEffectManager::Instance().CreateEffectInstance(ae.dwEffectIndex, dwCRC); + + int iBoneIndex; + if (!FindBoneIndex(j,c_pAttachingData->strAttachingBoneName.c_str(), &iBoneIndex)) + { + Tracef("Cannot get Bone Index\n"); + assert(false/*Cannot get Bone Index*/); + } + Tracef("Creating %p %d %d\n", this, j,k); + + ae.iBoneIndex = iBoneIndex; + + m_AttachingEffectList.push_back(ae); + } + break; + + case NRaceData::ATTACHING_DATA_TYPE_OBJECT: + break; + + default: + assert(false/*NOT_IMPLEMENTED*/); + break; + } + } + } + + m_bEffectInitialized = true; +} + +void CActorInstance::SetWeaponTraceTexture(const char * szTextureName) +{ + std::vector::iterator it; + for (it = m_WeaponTraceVector.begin(); it != m_WeaponTraceVector.end(); ++it) + { + (*it)->SetTexture(szTextureName); + } +} + +void CActorInstance::UseTextureWeaponTrace() +{ + for_each( + m_WeaponTraceVector.begin(), + m_WeaponTraceVector.end(), + std::mem_fn(&CWeaponTrace::UseTexture) + ); +} + +void CActorInstance::UseAlphaWeaponTrace() +{ + for_each( + m_WeaponTraceVector.begin(), + m_WeaponTraceVector.end(), + std::mem_fn(&CWeaponTrace::UseAlpha) + ); +} + +void CActorInstance::UpdateAttachingInstances() +{ + CEffectManager& rkEftMgr=CEffectManager::Instance(); + + std::list::iterator it; + DWORD dwCurrentTime = CTimer::Instance().GetCurrentMillisecond(); + for (it = m_AttachingEffectList.begin(); it!= m_AttachingEffectList.end();) + { + if (EFFECT_LIFE_WITH_MOTION == it->iLifeType) + { + ++it; + continue; + } + + if ((EFFECT_LIFE_NORMAL == it->iLifeType && it->dwEndTime < dwCurrentTime) || + !rkEftMgr.IsAliveEffect(it->dwEffectIndex)) + { + rkEftMgr.DestroyEffectInstance(it->dwEffectIndex); + it = m_AttachingEffectList.erase(it); + } + else + { + if (it->isAttaching) + { + rkEftMgr.SelectEffectInstance(it->dwEffectIndex); + + if (it->iBoneIndex == -1) + { + D3DXMATRIX matTransform; + matTransform = it->matTranslation; + matTransform *= m_worldMatrix; + rkEftMgr.SetEffectInstanceGlobalMatrix(matTransform); + } + else + { + D3DXMATRIX * pBoneMat; + if (GetBoneMatrix(it->dwModelIndex, it->iBoneIndex, &pBoneMat)) + { + D3DXMATRIX matTransform; + matTransform = *pBoneMat; + matTransform *= it->matTranslation; + matTransform *= m_worldMatrix; + rkEftMgr.SetEffectInstanceGlobalMatrix(matTransform); + } + else + { + //TraceError("GetBoneMatrix(modelIndex(%d), boneIndex(%d)).NOT_FOUND_BONE", + // it->dwModelIndex, it->iBoneIndex); + } + } + } + + ++it; + } + } +} + +void CActorInstance::ShowAllAttachingEffect() +{ + std::list::iterator it; + for(it = m_AttachingEffectList.begin(); it!= m_AttachingEffectList.end();++it) + { + CEffectManager::Instance().SelectEffectInstance(it->dwEffectIndex); + CEffectManager::Instance().ShowEffect(); + } +} + +void CActorInstance::HideAllAttachingEffect() +{ + std::list::iterator it; + for(it = m_AttachingEffectList.begin(); it!= m_AttachingEffectList.end();++it) + { + CEffectManager::Instance().SelectEffectInstance(it->dwEffectIndex); + CEffectManager::Instance().HideEffect(); + } +} + +void CActorInstance::__ClearAttachingEffect() +{ + m_bEffectInitialized = false; + + std::list::iterator it; + for(it = m_AttachingEffectList.begin(); it!= m_AttachingEffectList.end();++it) + { + CEffectManager::Instance().DestroyEffectInstance(it->dwEffectIndex); + } + m_AttachingEffectList.clear(); +} diff --git a/source/GameLib/ActorInstanceBattle.cpp b/source/GameLib/ActorInstanceBattle.cpp new file mode 100644 index 0000000..5fc0062 --- /dev/null +++ b/source/GameLib/ActorInstanceBattle.cpp @@ -0,0 +1,967 @@ +#include "StdAfx.h" +#include "../effectLib/EffectManager.h" +#include "../milesLib/SoundManager.h" + +#include "ActorInstance.h" +#include "RaceData.h" + +void CActorInstance::SetBattleHitEffect(DWORD dwID) +{ + m_dwBattleHitEffectID = dwID; +} + +void CActorInstance::SetBattleAttachEffect(DWORD dwID) +{ + m_dwBattleAttachEffectID = dwID; +} + +bool CActorInstance::CanAct() +{ + if (IsDead()) + return false; + + if (IsStun()) + return false; + + if (IsParalysis()) + return false; + + if (IsFaint()) + return false; + + if (IsSleep()) + return false; + + return true; +} + +bool CActorInstance::CanUseSkill() +{ + if (!CanAct()) + return false; + + DWORD dwCurMotionIndex=__GetCurrentMotionIndex(); + + // Locked during attack + switch (dwCurMotionIndex) + { + case CRaceMotionData::NAME_FISHING_THROW: + case CRaceMotionData::NAME_FISHING_WAIT: + case CRaceMotionData::NAME_FISHING_STOP: + case CRaceMotionData::NAME_FISHING_REACT: + case CRaceMotionData::NAME_FISHING_CATCH: + case CRaceMotionData::NAME_FISHING_FAIL: + return TRUE; + break; + } + + // Locked during using skill + if (IsUsingSkill()) + { + if (m_pkCurRaceMotionData->IsCancelEnableSkill()) + return TRUE; + + return FALSE; + } + + return true; +} + +bool CActorInstance::CanMove() +{ + if (!CanAct()) + return false; + + if (isLock()) + return false; + + return true; +} + +bool CActorInstance::CanAttack() +{ + if (!CanAct()) + return false; + + if (IsUsingSkill()) + { + if (!CanCancelSkill()) + return false; + } + + return true; +} + +bool CActorInstance::CanFishing() +{ + if (!CanAct()) + return false; + + if (IsUsingSkill()) + return false; + + switch (__GetCurrentMotionIndex()) + { + case CRaceMotionData::NAME_WAIT: + case CRaceMotionData::NAME_WALK: + case CRaceMotionData::NAME_RUN: + break; + default: + return false; + break; + } + + return true; +} + +BOOL CActorInstance::IsClickableDistanceDestInstance(CActorInstance & rkInstDst, float fDistance) +{ + TPixelPosition kPPosSrc; + GetPixelPosition(&kPPosSrc); + + D3DXVECTOR3 kD3DVct3Src(kPPosSrc); + + TCollisionPointInstanceList& rkLstkDefPtInst=rkInstDst.m_DefendingPointInstanceList; + TCollisionPointInstanceList::iterator i; + + for (i=rkLstkDefPtInst.begin(); i!=rkLstkDefPtInst.end(); ++i) + { + CDynamicSphereInstanceVector& rkVctkDefSphere = (*i).SphereInstanceVector; + + CDynamicSphereInstanceVector::iterator j; + for (j=rkVctkDefSphere.begin(); j!=rkVctkDefSphere.end(); ++j) + { + CDynamicSphereInstance& rkSphere=(*j); + + const auto vv = D3DXVECTOR3(rkSphere.v3Position - kD3DVct3Src); + float fMovDistance=D3DXVec3Length(&vv); + float fAtkDistance=rkSphere.fRadius+fDistance; + + if (fAtkDistance>fMovDistance) + return TRUE; + } + } + + return FALSE; +} + +void CActorInstance::InputNormalAttackCommand(float fDirRot) +{ + if (!__CanInputNormalAttackCommand()) + return; + + m_fAtkDirRot=fDirRot; + NormalAttack(m_fAtkDirRot); +} + +bool CActorInstance::InputComboAttackCommand(float fDirRot) +{ + m_fAtkDirRot=fDirRot; + + if (m_isPreInput) + return false; + + ///////////////////////////////////////////////////////////////////////////////// + + // Process Input + if (0 == m_dwcurComboIndex) + { + __RunNextCombo(); + return true; + } + else if (m_pkCurRaceMotionData->IsComboInputTimeData()) + { + // ð + float fElapsedTime = GetAttackingElapsedTime(); + + // ̹ Է Ѱ ð ٸ.. + if (fElapsedTime > m_pkCurRaceMotionData->GetComboInputEndTime()) + { + //Tracen("Է Ѱ ð "); + if (IsBowMode()) + m_isNextPreInput = TRUE; + return false; + } + + if (fElapsedTime > m_pkCurRaceMotionData->GetNextComboTime()) // ޺ ߵ ð Ķ + { + //Tracen(" ޺ "); + // args : BlendingTime + __RunNextCombo(); + return true; + } + else if (fElapsedTime > m_pkCurRaceMotionData->GetComboInputStartTime()) // Է ð .. + { + //Tracen(" Է "); + m_isPreInput = TRUE; + return false; + } + } + else + { + float fElapsedTime = GetAttackingElapsedTime(); + if (fElapsedTime > m_pkCurRaceMotionData->GetMotionDuration()*0.9f) // ޺ ߵ ð Ķ + { + //Tracen(" ޺ "); + // args : BlendingTime + __RunNextCombo(); + return true; + } + } + // Process Input + + return false; +} + +void CActorInstance::ComboProcess() +{ + // If combo is on action + if (0 != m_dwcurComboIndex) + { + if (!m_pkCurRaceMotionData) + { + Tracef("Attacking motion data is NULL! : %d\n", m_dwcurComboIndex); + __ClearCombo(); + return; + } + + float fElapsedTime = GetAttackingElapsedTime(); + + // Process PreInput + if (m_isPreInput) + { + //Tracenf("Է %f ޺ð %f", fElapsedTime, m_pkCurRaceMotionData->GetNextComboTime()); + if (fElapsedTime > m_pkCurRaceMotionData->GetNextComboTime()) + { + __RunNextCombo(); + m_isPreInput = FALSE; + + return; + } + } + } + else + { + m_isPreInput = FALSE; + + if (!IsUsingSkill()) // m_isNextPreInput Ȱ ϶ ϴ + if (m_isNextPreInput) // Ȱ϶ ų ĵ Ǵ° ̰ + { + __RunNextCombo(); + m_isNextPreInput = FALSE; + } + } +} + +void CActorInstance::__RunNextCombo() +{ + ++m_dwcurComboIndex; + /////////////////////////// + + WORD wComboIndex = m_dwcurComboIndex; + WORD wComboType = __GetCurrentComboType(); + + if (wComboIndex==0) + { + TraceError("CActorInstance::__RunNextCombo(wComboType=%d, wComboIndex=%d)", wComboType, wComboIndex); + return; + } + + DWORD dwComboArrayIndex = wComboIndex - 1; + + CRaceData::TComboData * pComboData; + + if (!m_pkCurRaceData->GetComboDataPointer(m_wcurMotionMode, wComboType, &pComboData)) + { + TraceError("CActorInstance::__RunNextCombo(wComboType=%d, wComboIndex=%d) - m_pkCurRaceData->GetComboDataPointer(m_wcurMotionMode=%d, &pComboData) == NULL", + wComboType, wComboIndex, m_wcurMotionMode); + return; + } + + if (dwComboArrayIndex >= pComboData->ComboIndexVector.size()) + { + TraceError("CActorInstance::__RunNextCombo(wComboType=%d, wComboIndex=%d) - (dwComboArrayIndex=%d) >= (pComboData->ComboIndexVector.size()=%d)", + wComboType, wComboIndex, dwComboArrayIndex, pComboData->ComboIndexVector.size()); + return; + } + + WORD wcurComboMotionIndex = pComboData->ComboIndexVector[dwComboArrayIndex]; + ComboAttack(wcurComboMotionIndex, m_fAtkDirRot, 0.1f); + + //////////////////////////////// + // ޺ ٸ + if (m_dwcurComboIndex == pComboData->ComboIndexVector.size()) + { + __OnEndCombo(); + } +} + +void CActorInstance::__OnEndCombo() +{ + if (__IsMountingHorse()) + { + m_dwcurComboIndex = 1; + } + + // ⼭ ޺ ʱȭ ؼ ȵȴ. + // ޺ ʱȭ Ǵ ޺ Motion ڵ Wait ư ̴. +} + +void CActorInstance::__ClearCombo() +{ + m_dwcurComboIndex = 0; + m_isPreInput = FALSE; + m_pkCurRaceMotionData = NULL; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +BOOL CActorInstance::isAttacking() +{ + if (isNormalAttacking()) + return TRUE; + + if (isComboAttacking()) + return TRUE; + + if (IsSplashAttacking()) + return TRUE; + + return FALSE; +} + +BOOL CActorInstance::isValidAttacking() +{ + if (!m_pkCurRaceMotionData) + return FALSE; + + if (!m_pkCurRaceMotionData->isAttackingMotion()) + return FALSE; + + const NRaceData::TMotionAttackData * c_pData = m_pkCurRaceMotionData->GetMotionAttackDataPointer(); + float fElapsedTime = GetAttackingElapsedTime(); + NRaceData::THitDataContainer::const_iterator itor = c_pData->HitDataContainer.begin(); + for (; itor != c_pData->HitDataContainer.end(); ++itor) + { + const NRaceData::THitData & c_rHitData = *itor; + if (fElapsedTime > c_rHitData.fAttackStartTime && + fElapsedTime < c_rHitData.fAttackEndTime) + return TRUE; + } + + return TRUE; +} + +BOOL CActorInstance::CanCheckAttacking() +{ + if (isAttacking()) + return true; + + return false; +} + +bool CActorInstance::__IsInSplashTime() +{ + if (m_kSplashArea.fDisappearingTime>GetLocalTime()) + return true; + + return false; +} + +BOOL CActorInstance::isNormalAttacking() +{ + if (!m_pkCurRaceMotionData) + return FALSE; + + if (!m_pkCurRaceMotionData->isAttackingMotion()) + return FALSE; + + const NRaceData::TMotionAttackData * c_pData = m_pkCurRaceMotionData->GetMotionAttackDataPointer(); + if (NRaceData::MOTION_TYPE_NORMAL != c_pData->iMotionType) + return FALSE; + + return TRUE; +} + +BOOL CActorInstance::isComboAttacking() +{ + if (!m_pkCurRaceMotionData) + return FALSE; + + if (!m_pkCurRaceMotionData->isAttackingMotion()) + return FALSE; + + const NRaceData::TMotionAttackData * c_pData = m_pkCurRaceMotionData->GetMotionAttackDataPointer(); + if (NRaceData::MOTION_TYPE_COMBO != c_pData->iMotionType) + return FALSE; + + return TRUE; +} + +BOOL CActorInstance::IsSplashAttacking() +{ + if (!m_pkCurRaceMotionData) + return FALSE; + + if (m_pkCurRaceMotionData->HasSplashMotionEvent()) + return TRUE; + + return FALSE; +} + +BOOL CActorInstance::__IsMovingSkill(WORD wSkillNumber) +{ + enum + { + HORSE_DASH_SKILL_NUMBER = 137, + }; + + return HORSE_DASH_SKILL_NUMBER == wSkillNumber; +} + +BOOL CActorInstance::IsActEmotion() +{ + DWORD dwCurMotionIndex=__GetCurrentMotionIndex(); + switch (dwCurMotionIndex) + { + case CRaceMotionData::NAME_FRENCH_KISS_START+0: + case CRaceMotionData::NAME_FRENCH_KISS_START+1: + case CRaceMotionData::NAME_FRENCH_KISS_START+2: + case CRaceMotionData::NAME_FRENCH_KISS_START+3: + case CRaceMotionData::NAME_KISS_START+0: + case CRaceMotionData::NAME_KISS_START+1: + case CRaceMotionData::NAME_KISS_START+2: + case CRaceMotionData::NAME_KISS_START+3: + return TRUE; + break; + } + + return FALSE; +} + +BOOL CActorInstance::IsUsingMovingSkill() +{ + return __IsMovingSkill(m_kCurMotNode.uSkill); +} + +DWORD CActorInstance::GetComboIndex() +{ + return m_dwcurComboIndex; +} + +float CActorInstance::GetAttackingElapsedTime() +{ + return (GetLocalTime() - m_kCurMotNode.fStartTime) * m_kCurMotNode.fSpeedRatio; +// return (GetLocalTime() - m_kCurMotNode.fStartTime) * __GetAttackSpeed(); +} + +bool CActorInstance::__CanInputNormalAttackCommand() +{ + if (IsWaiting()) + return true; + + if (isNormalAttacking()) + { + float fElapsedTime = GetAttackingElapsedTime(); + + if (fElapsedTime > m_pkCurRaceMotionData->GetMotionDuration()*0.9f) + return true; + } + + return false; +} + +BOOL CActorInstance::NormalAttack(float fDirRot, float fBlendTime) +{ + WORD wMotionIndex; + if (!m_pkCurRaceData->GetNormalAttackIndex(m_wcurMotionMode, &wMotionIndex)) + return FALSE; + + BlendRotation(fDirRot, fBlendTime); + SetAdvancingRotation(fDirRot); + InterceptOnceMotion(wMotionIndex, 0.1f, 0, __GetAttackSpeed()); + + __OnAttack(wMotionIndex); + + NEW_SetAtkPixelPosition(NEW_GetCurPixelPositionRef()); + + return TRUE; +} + +BOOL CActorInstance::ComboAttack(DWORD dwMotionIndex, float fDirRot, float fBlendTime) +{ + BlendRotation(fDirRot, fBlendTime); + SetAdvancingRotation(fDirRot); + + InterceptOnceMotion(dwMotionIndex, fBlendTime, 0, __GetAttackSpeed()); + + __OnAttack(dwMotionIndex); + + NEW_SetAtkPixelPosition(NEW_GetCurPixelPositionRef()); + + return TRUE; +} + +void CActorInstance::__ProcessMotionEventAttackSuccess(DWORD dwMotionKey, BYTE byEventIndex, CActorInstance & rVictim) +{ + CRaceMotionData * pMotionData; + + if (!m_pkCurRaceData->GetMotionDataPointer(dwMotionKey, &pMotionData)) + return; + + if (byEventIndex >= pMotionData->GetMotionEventDataCount()) + return; + + const CRaceMotionData::TMotionAttackingEventData * pMotionEventData; + if (!pMotionData->GetMotionAttackingEventDataPointer(byEventIndex, &pMotionEventData)) + return; + + const D3DXVECTOR3& c_rv3VictimPos=rVictim.GetPositionVectorRef(); + __ProcessDataAttackSuccess(pMotionEventData->AttackData, rVictim, c_rv3VictimPos); +} + + +void CActorInstance::__ProcessMotionAttackSuccess(DWORD dwMotionKey, CActorInstance & rVictim) +{ + CRaceMotionData * c_pMotionData; + + if (!m_pkCurRaceData->GetMotionDataPointer(dwMotionKey, &c_pMotionData)) + return; + + const D3DXVECTOR3& c_rv3VictimPos=rVictim.GetPositionVectorRef(); + __ProcessDataAttackSuccess(c_pMotionData->GetMotionAttackDataReference(), rVictim, c_rv3VictimPos); +} + + +DWORD CActorInstance::__GetOwnerVID() +{ + return m_dwOwnerVID; +} + +float CActorInstance::__GetOwnerTime() +{ + return GetLocalTime()-m_fOwnerBaseTime; +} + +bool IS_HUGE_RACE(unsigned int vnum) +{ + switch (vnum) + { + case 2493: + return true; + } + return false; +} + +bool CActorInstance::__CanPushDestActor(CActorInstance& rkActorDst) +{ + if (rkActorDst.IsBuilding()) + return false; + + if (rkActorDst.IsDoor()) + return false; + + if (rkActorDst.IsStone()) + return false; + + if (rkActorDst.IsNPC()) + return false; + + // Ŵ и + extern bool IS_HUGE_RACE(unsigned int vnum); + if (IS_HUGE_RACE(rkActorDst.GetRace())) + return false; + + if (rkActorDst.IsStun()) + return true; + + if (rkActorDst.__GetOwnerVID()!=GetVirtualID()) + return false; + + if (rkActorDst.__GetOwnerTime()>3.0f) + return false; + + return true; +} + +bool IS_PARTY_HUNTING_RACE(unsigned int vnum) +{ + return true; + + // Ƽ + /* + if (vnum < 8) // ÷̾ + return true; + + if (vnum >= 8000 && vnum <= 8112) // ƾ + return true; + + if (vnum >= 2400 && vnum < 5000) // õ + return true; + + return false; + */ +} + +void CActorInstance::__ProcessDataAttackSuccess(const NRaceData::TAttackData & c_rAttackData, CActorInstance & rVictim, const D3DXVECTOR3 & c_rv3Position, UINT uiSkill, BOOL isSendPacket) +{ + if (NRaceData::HIT_TYPE_NONE == c_rAttackData.iHittingType) + return; + + InsertDelay(c_rAttackData.fStiffenTime); + + if (__CanPushDestActor(rVictim) && c_rAttackData.fExternalForce > 0.0f) + { + __PushCircle(rVictim); + + // VICTIM_COLLISION_TEST + const D3DXVECTOR3& kVictimPos = rVictim.GetPosition(); + rVictim.m_PhysicsObject.IncreaseExternalForce(kVictimPos, c_rAttackData.fExternalForce); //*nForceRatio/100.0f); + + // VICTIM_COLLISION_TEST_END + } + + // Invisible Time + if (IS_PARTY_HUNTING_RACE(rVictim.GetRace())) + { + if (uiSkill) // Ƽ Ͷ ų̸ ð + rVictim.m_fInvisibleTime = CTimer::Instance().GetCurrentSecond() + c_rAttackData.fInvisibleTime; + + if (m_isMain) // #0000794: [M2KR] - 뷱 Ÿ ݿ Ÿ ʰ ڽ ݿ Ѱ͸ üũѴ + rVictim.m_fInvisibleTime = CTimer::Instance().GetCurrentSecond() + c_rAttackData.fInvisibleTime; + } + else // Ƽ Ͱ ƴ 츸 + { + rVictim.m_fInvisibleTime = CTimer::Instance().GetCurrentSecond() + c_rAttackData.fInvisibleTime; + } + + // Stiffen Time + rVictim.InsertDelay(c_rAttackData.fStiffenTime); + + // Hit Effect + D3DXVECTOR3 vec3Effect(rVictim.m_x, rVictim.m_y, rVictim.m_z); + + // #0000780: [M2KR] Ÿݱ + extern bool IS_HUGE_RACE(unsigned int vnum); + if (IS_HUGE_RACE(rVictim.GetRace())) + { + vec3Effect = c_rv3Position; + } + + const D3DXVECTOR3 & v3Pos = GetPosition(); + + float fHeight = D3DXToDegree(atan2(-vec3Effect.x + v3Pos.x,+vec3Effect.y - v3Pos.y)); + + // 2004.08.03.myevan.̳ Ÿ ȿ ʴ´ + if (rVictim.IsBuilding()||rVictim.IsDoor()) + { + D3DXVECTOR3 vec3Delta=vec3Effect-v3Pos; + D3DXVec3Normalize(&vec3Delta, &vec3Delta); + vec3Delta*=30.0f; + + CEffectManager& rkEftMgr=CEffectManager::Instance(); + if (m_dwBattleHitEffectID) + rkEftMgr.CreateEffect(m_dwBattleHitEffectID, v3Pos+vec3Delta, D3DXVECTOR3(0.0f, 0.0f, 0.0f)); + } + else + { + CEffectManager& rkEftMgr=CEffectManager::Instance(); + if (m_dwBattleHitEffectID) + rkEftMgr.CreateEffect(m_dwBattleHitEffectID, vec3Effect, D3DXVECTOR3(0.0f, 0.0f, fHeight)); + if (m_dwBattleAttachEffectID) + rVictim.AttachEffectByID(0, NULL, m_dwBattleAttachEffectID); + } + + if (rVictim.IsBuilding()) + { + // 2004.08.03. 鸮 ̻ϴ + } + else if (rVictim.IsStone() || rVictim.IsDoor()) + { + __HitStone(rVictim); + } + else + { + /////////// + // Motion + if (NRaceData::HIT_TYPE_GOOD == c_rAttackData.iHittingType || rVictim.IsResistFallen()) + { + __HitGood(rVictim); + } + else if (NRaceData::HIT_TYPE_GREAT == c_rAttackData.iHittingType) + { + __HitGreate(rVictim); + } + else + { + TraceError("ProcessSucceedingAttacking: Unknown AttackingData.iHittingType %d", c_rAttackData.iHittingType); + } + } + + __OnHit(uiSkill, rVictim, isSendPacket); +} + +void CActorInstance::OnShootDamage() +{ + if (IsStun()) + { + Die(); + } + else + { + __Shake(100); + + if (!isLock() && !__IsKnockDownMotion() && !__IsStandUpMotion()) + { + if (InterceptOnceMotion(CRaceMotionData::NAME_DAMAGE)) + PushLoopMotion(CRaceMotionData::NAME_WAIT); + } + } +} + +void CActorInstance::__Shake(DWORD dwDuration) +{ + DWORD dwCurTime=ELTimer_GetMSec(); + m_dwShakeTime=dwCurTime+dwDuration; +} + +void CActorInstance::ShakeProcess() +{ + if (m_dwShakeTime) + { + D3DXVECTOR3 v3Pos(0.0f, 0.0f, 0.0f); + + DWORD dwCurTime=ELTimer_GetMSec(); + + if (m_dwShakeTimex += m_x; + pPosition->y += m_y; + pPosition->z += m_z; + } + else + { + pPosition->x = m_x; + pPosition->y = m_y; + pPosition->z = m_z; + } +} + +void CActorInstance::__PushCircle(CActorInstance & rVictim) +{ + const TPixelPosition& c_rkPPosAtk=NEW_GetAtkPixelPositionRef(); + + D3DXVECTOR3 v3SrcPos(c_rkPPosAtk.x, -c_rkPPosAtk.y, c_rkPPosAtk.z); + + const D3DXVECTOR3& c_rv3SrcPos = v3SrcPos; + const D3DXVECTOR3& c_rv3DstPos = rVictim.GetPosition(); + + D3DXVECTOR3 v3Direction; + v3Direction.x = c_rv3DstPos.x - c_rv3SrcPos.x; + v3Direction.y = c_rv3DstPos.y - c_rv3SrcPos.y; + v3Direction.z = 0.0f; + D3DXVec3Normalize(&v3Direction, &v3Direction); + + rVictim.__SetFallingDirection(v3Direction.x, v3Direction.y); +} + +void CActorInstance::__PushDirect(CActorInstance & rVictim) +{ + D3DXVECTOR3 v3Direction; + v3Direction.x = cosf(D3DXToRadian(m_fcurRotation + 270.0f)); + v3Direction.y = sinf(D3DXToRadian(m_fcurRotation + 270.0f)); + v3Direction.z = 0.0f; + + rVictim.__SetFallingDirection(v3Direction.x, v3Direction.y); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +bool CActorInstance::__isInvisible() +{ + if (IsDead()) + return true; + + if (CTimer::Instance().GetCurrentSecond() >= m_fInvisibleTime) + return false; + + return true; +} + +void CActorInstance::__SetFallingDirection(float fx, float fy) +{ + m_PhysicsObject.SetDirection(D3DXVECTOR3(fx, fy, 0.0f)); +} diff --git a/source/GameLib/ActorInstanceBlend.cpp b/source/GameLib/ActorInstanceBlend.cpp new file mode 100644 index 0000000..9543608 --- /dev/null +++ b/source/GameLib/ActorInstanceBlend.cpp @@ -0,0 +1,83 @@ +#include "StdAfx.h" +#include "ActorInstance.h" + +void CActorInstance::BlendAlphaValue(float fDstAlpha, float fDuration) +{ + __BlendAlpha_Apply(fDstAlpha, fDuration); +} + +void CActorInstance::SetBlendRenderMode() +{ + m_iRenderMode = RENDER_MODE_BLEND; +} + +void CActorInstance::SetAlphaValue(float fAlpha) +{ + m_fAlphaValue = fAlpha; +} + +float CActorInstance::GetAlphaValue() +{ + return m_fAlphaValue; +} + +void CActorInstance::__BlendAlpha_Initialize() +{ + m_kBlendAlpha.m_isBlending=false; + m_kBlendAlpha.m_fBaseTime=0.0f; + m_kBlendAlpha.m_fDuration=0.0f; + m_kBlendAlpha.m_fBaseAlpha=0.0f; + m_kBlendAlpha.m_fDstAlpha=0.0f; + m_kBlendAlpha.m_iOldRenderMode=RENDER_MODE_NORMAL; +} + +void CActorInstance::__BlendAlpha_Apply(float fDstAlpha, float fDuration) +{ + m_kBlendAlpha.m_isBlending=true; + m_kBlendAlpha.m_fBaseAlpha=GetAlphaValue(); + m_kBlendAlpha.m_fBaseTime=GetLocalTime(); + m_kBlendAlpha.m_fDuration=fDuration; + m_kBlendAlpha.m_fDstAlpha=fDstAlpha; + m_kBlendAlpha.m_iOldRenderMode=m_iRenderMode; +} + +void CActorInstance::__BlendAlpha_Update() +{ + if (!m_kBlendAlpha.m_isBlending) + return; + + float fElapsedTime=__BlendAlpha_GetElapsedTime(); + + if (fElapsedTimem_kBlendAlpha.m_fDstAlpha) + { + SetBlendRenderMode(); + } + else + { + m_iRenderMode=m_kBlendAlpha.m_iOldRenderMode; + } + + SetAlphaValue(m_kBlendAlpha.m_fDstAlpha); + + __BlendAlpha_UpdateComplete(); + } +} + +void CActorInstance::__BlendAlpha_UpdateComplete() +{ + m_kBlendAlpha.m_isBlending=false; +} + +float CActorInstance::__BlendAlpha_GetElapsedTime() +{ + float fCurTime=GetLocalTime(); + return fCurTime-m_kBlendAlpha.m_fBaseTime; +} diff --git a/source/GameLib/ActorInstanceCollisionDetection.cpp b/source/GameLib/ActorInstanceCollisionDetection.cpp new file mode 100644 index 0000000..59791a0 --- /dev/null +++ b/source/GameLib/ActorInstanceCollisionDetection.cpp @@ -0,0 +1,744 @@ +#include "StdAfx.h" +#include "../eterLib/GrpMath.h" + +#include "ActorInstance.h" + +void CActorInstance::__InitializeCollisionData() +{ + m_canSkipCollision=false; +} + +void CActorInstance::EnableSkipCollision() +{ + m_canSkipCollision=true; +} + +void CActorInstance::DisableSkipCollision() +{ + m_canSkipCollision=false; +} + +bool CActorInstance::CanSkipCollision() +{ + return m_canSkipCollision; +} + +void CActorInstance::UpdatePointInstance() +{ + TCollisionPointInstanceListIterator itor; + for (itor = m_DefendingPointInstanceList.begin(); itor != m_DefendingPointInstanceList.end(); ++itor) + UpdatePointInstance(&(*itor)); +} + +void CActorInstance::UpdatePointInstance(TCollisionPointInstance * pPointInstance) +{ + if (!pPointInstance) + { + assert(!"CActorInstance::UpdatePointInstance - pPointInstance is NULL"); // ۷ üϽÿ + return; + } + + D3DXMATRIX matBone; + + if (pPointInstance->isAttached) + { + if (pPointInstance->dwModelIndex>=m_LODControllerVector.size()) + { + //Tracenf("CActorInstance::UpdatePointInstance - rInstance.dwModelIndex=%d >= m_LODControllerVector.size()=%d", + // pPointInstance->dwModelIndex>m_LODControllerVector.size()); + return; + } + + CGrannyLODController* pGrnLODController=m_LODControllerVector[pPointInstance->dwModelIndex]; + if (!pGrnLODController) + { + //Tracenf("CActorInstance::UpdatePointInstance - m_LODControllerVector[pPointInstance->dwModelIndex=%d] is NULL", pPointInstance->dwModelIndex); + return; + } + + CGrannyModelInstance * pModelInstance = pGrnLODController->GetModelInstance(); + if (!pModelInstance) + { + //Tracenf("CActorInstance::UpdatePointInstance - pGrnLODController->GetModelInstance() is NULL"); + return; + } + + D3DXMATRIX * pmatBone = (D3DXMATRIX *)pModelInstance->GetBoneMatrixPointer(pPointInstance->dwBoneIndex); + matBone = *(D3DXMATRIX *)pModelInstance->GetCompositeBoneMatrixPointer(pPointInstance->dwBoneIndex); + matBone._41 = pmatBone->_41; + matBone._42 = pmatBone->_42; + matBone._43 = pmatBone->_43; + matBone *= m_worldMatrix; + } + else + { + matBone = m_worldMatrix; + } + + // Update Collsion Sphere + CSphereCollisionInstanceVector::const_iterator sit = pPointInstance->c_pCollisionData->SphereDataVector.begin(); + CDynamicSphereInstanceVector::iterator dit=pPointInstance->SphereInstanceVector.begin(); + for (;sit!=pPointInstance->c_pCollisionData->SphereDataVector.end();++sit,++dit) + { + const TSphereData & c = sit->GetAttribute();//c_pCollisionData->SphereDataVector[j].GetAttribute(); + + D3DXMATRIX matPoint; + D3DXMatrixTranslation(&matPoint, c.v3Position.x, c.v3Position.y, c.v3Position.z); + matPoint = matPoint * matBone; + + dit->v3LastPosition = dit->v3Position; + dit->v3Position.x = matPoint._41; + dit->v3Position.y = matPoint._42; + dit->v3Position.z = matPoint._43; + } +} + +void CActorInstance::UpdateAdvancingPointInstance() +{ + // ̵ ʱ ; Ѵ - [levites] + D3DXVECTOR3 v3Movement = m_v3Movement; + if (m_pkHorse) + v3Movement = m_pkHorse->m_v3Movement; + + // Ʈ ʾƵ ȴ - [levites] + if (m_pkHorse) + m_pkHorse->UpdateAdvancingPointInstance(); + + D3DXMATRIX matPoint; + D3DXMATRIX matCenter; + + TCollisionPointInstanceListIterator itor = m_BodyPointInstanceList.begin(); + for (; itor != m_BodyPointInstanceList.end(); ++itor) + { + TCollisionPointInstance & rInstance = *itor; + + if (rInstance.isAttached) + { + if (rInstance.dwModelIndex>=m_LODControllerVector.size()) + { + Tracenf("CActorInstance::UpdateAdvancingPointInstance - rInstance.dwModelIndex=%d >= m_LODControllerVector.size()=%d", + rInstance.dwModelIndex, m_LODControllerVector.size()); + continue; + } + + CGrannyLODController* pGrnLODController=m_LODControllerVector[rInstance.dwModelIndex]; + if (!pGrnLODController) + { + Tracenf("CActorInstance::UpdateAdvancingPointInstance - m_LODControllerVector[rInstance.dwModelIndex=%d] is NULL", rInstance.dwModelIndex); + continue; + } + + CGrannyModelInstance * pModelInstance = pGrnLODController->GetModelInstance(); + if (!pModelInstance) + { + //Tracenf("CActorInstance::UpdateAdvancingPointInstance - pGrnLODController->GetModelInstance() is NULL"); + continue; + } + + matCenter = *(D3DXMATRIX *)pModelInstance->GetBoneMatrixPointer(rInstance.dwBoneIndex); + matCenter *= m_worldMatrix; + } + else + { + matCenter = m_worldMatrix; + } + + // Update Collision Sphere + const NRaceData::TCollisionData * c_pCollisionData = rInstance.c_pCollisionData; + if (c_pCollisionData) + { + for (DWORD j = 0; j < c_pCollisionData->SphereDataVector.size(); ++j) + { + const TSphereData & c = c_pCollisionData->SphereDataVector[j].GetAttribute(); + CDynamicSphereInstance & rSphereInstance = rInstance.SphereInstanceVector[j]; + + D3DXMatrixTranslation(&matPoint, c.v3Position.x, c.v3Position.y, c.v3Position.z); + matPoint = matPoint * matCenter; + + rSphereInstance.v3LastPosition.x = matPoint._41; + rSphereInstance.v3LastPosition.y = matPoint._42; + rSphereInstance.v3LastPosition.z = matPoint._43; + rSphereInstance.v3Position = rSphereInstance.v3LastPosition; + rSphereInstance.v3Position += v3Movement; + } + } + } +} + +bool CActorInstance::CheckCollisionDetection(const CDynamicSphereInstanceVector * c_pAttackingSphereVector, D3DXVECTOR3 * pv3Position) +{ + if (!c_pAttackingSphereVector) + { + assert(!"CActorInstance::CheckCollisionDetection - c_pAttackingSphereVector is NULL"); // ۷ üϽÿ + return false; + } + + TCollisionPointInstanceListIterator itor; + for (itor = m_DefendingPointInstanceList.begin(); itor != m_DefendingPointInstanceList.end(); ++itor) + { + const CDynamicSphereInstanceVector * c_pDefendingSphereVector = &(*itor).SphereInstanceVector; + + for (DWORD i = 0; i < c_pAttackingSphereVector->size(); ++i) + for (DWORD j = 0; j < c_pDefendingSphereVector->size(); ++j) + { + const CDynamicSphereInstance & c_rAttackingSphere = c_pAttackingSphereVector->at(i); + const CDynamicSphereInstance & c_rDefendingSphere = c_pDefendingSphereVector->at(j); + + if (DetectCollisionDynamicSphereVSDynamicSphere(c_rAttackingSphere, c_rDefendingSphere)) + { + // FIXME : ãƳ ٲ Ѵ. + *pv3Position = (c_rAttackingSphere.v3Position + c_rDefendingSphere.v3Position) / 2.0f; + return true; + } + } + } + + return false; +} + +bool CActorInstance::CreateCollisionInstancePiece(DWORD dwAttachingModelIndex, const NRaceData::TAttachingData * c_pAttachingData, TCollisionPointInstance * pPointInstance) +{ + if (!c_pAttachingData) + { + assert(!"CActorInstance::CreateCollisionInstancePiece - c_pAttachingData is NULL"); // ۷ üϽÿ + return false; + } + + if (!c_pAttachingData->pCollisionData) + { + assert(!"CActorInstance::CreateCollisionInstancePiece - c_pAttachingData->pCollisionData is NULL"); // ۷ üϽÿ + return false; + } + + if (!pPointInstance) + { + assert(!"CActorInstance::CreateCollisionInstancePiece - pPointInstance is NULL"); // ۷ üϽÿ + return false; + } + + pPointInstance->dwModelIndex = dwAttachingModelIndex; + pPointInstance->isAttached = FALSE; + pPointInstance->dwBoneIndex = 0; + pPointInstance->c_pCollisionData = c_pAttachingData->pCollisionData; + + if (c_pAttachingData->isAttaching) + { + int iAttachingBoneIndex; + + CGrannyModelInstance * pModelInstance = m_LODControllerVector[dwAttachingModelIndex]->GetModelInstance(); + + if (pModelInstance && pModelInstance->GetBoneIndexByName(c_pAttachingData->strAttachingBoneName.c_str(), + &iAttachingBoneIndex)) + { + pPointInstance->isAttached = TRUE; + pPointInstance->dwBoneIndex = iAttachingBoneIndex; + } + else + { + //TraceError("CActorInstance::CreateCollisionInstancePiece: Cannot get matrix of bone %s ModelInstance 0x%p", c_pAttachingData->strAttachingBoneName.c_str(), pModelInstance); + pPointInstance->isAttached = TRUE; + pPointInstance->dwBoneIndex = 0; + } + } + + + const CSphereCollisionInstanceVector & c_rSphereDataVector = c_pAttachingData->pCollisionData->SphereDataVector; + + pPointInstance->SphereInstanceVector.clear(); + pPointInstance->SphereInstanceVector.reserve(c_rSphereDataVector.size()); + + CSphereCollisionInstanceVector::const_iterator it; + CDynamicSphereInstance dsi; + + dsi.v3LastPosition = D3DXVECTOR3(0.0f,0.0f,0.0f); + dsi.v3Position = D3DXVECTOR3(0.0f,0.0f,0.0f); + for (it = c_rSphereDataVector.begin(); it!=c_rSphereDataVector.end(); ++it) + { + const TSphereData & c_rSphereData = it->GetAttribute(); + dsi.fRadius = c_rSphereData.fRadius; + pPointInstance->SphereInstanceVector.push_back(dsi); + } + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +BOOL CActorInstance::__SplashAttackProcess(CActorInstance & rVictim) +{ + D3DXVECTOR3 v3Distance(rVictim.m_x - m_x, rVictim.m_z - m_z, rVictim.m_z - m_z); + float fDistance = D3DXVec3LengthSq(&v3Distance); + if (fDistance >= 1000.0f*1000.0f) + return FALSE; + + // Check Distance + if (!__IsInSplashTime()) + return FALSE; + + const CRaceMotionData::TMotionAttackingEventData * c_pAttackingEvent = m_kSplashArea.c_pAttackingEvent; + const NRaceData::TAttackData & c_rAttackData = c_pAttackingEvent->AttackData; + THittedInstanceMap & rHittedInstanceMap = m_kSplashArea.HittedInstanceMap; + + // NOTE : ̹ ȴٸ + if (rHittedInstanceMap.end() != rHittedInstanceMap.find(&rVictim)) + { + return FALSE; + } + + // NOTE : Snipe ̰.. + if (NRaceData::ATTACK_TYPE_SNIPE == c_rAttackData.iAttackType) + { + // Target PC .. + if (__IsFlyTargetPC()) + // ٸ ü + if (!__IsSameFlyTarget(&rVictim)) + return FALSE; + +/* + if (IsFlyTargetObject()) + { + CActorInstance * pActorInstance = (CActorInstance *)m_kFlyTarget.GetFlyTarget(); + + // NOTE : Target PC ϶ Ѹ ִ. + if (pActorInstance->IsPC()) + if (&rVictim != pActorInstance) + return FALSE; + } +*/ + } + + D3DXVECTOR3 v3HitPosition; + if (rVictim.CheckCollisionDetection(&m_kSplashArea.SphereInstanceVector, &v3HitPosition)) + { + rHittedInstanceMap.insert(std::make_pair(&rVictim, GetLocalTime()+c_rAttackData.fInvisibleTime)); + + int iCurrentHitCount = rHittedInstanceMap.size(); + int iMaxHitCount = (0 == c_rAttackData.iHitLimitCount ? 16 : c_rAttackData.iHitLimitCount); + //Tracef(" ------------------- Splash Hit : %d\n", iCurrentHitCount); + + if (iCurrentHitCount > iMaxHitCount) + { + //Tracef(" ------------------- OVER FLOW :: Splash Hit Count : %d\n", iCurrentHitCount); + return FALSE; + } + + NEW_SetAtkPixelPosition(NEW_GetCurPixelPositionRef()); + __ProcessDataAttackSuccess(c_rAttackData, rVictim, v3HitPosition, m_kSplashArea.uSkill, m_kSplashArea.isEnableHitProcess); + return TRUE; + } + + return FALSE; +} + +BOOL CActorInstance::__NormalAttackProcess(CActorInstance & rVictim) +{ + // Check Distance + // NOTE - ϴ üũ ϰ + D3DXVECTOR3 v3Distance(rVictim.m_x - m_x, rVictim.m_z - m_z, rVictim.m_z - m_z); + float fDistance = D3DXVec3LengthSq(&v3Distance); + + extern bool IS_HUGE_RACE(unsigned int vnum); + if (IS_HUGE_RACE(rVictim.GetRace())) + { + if (fDistance >= 500.0f*500.0f) + return FALSE; + } + else + { + if (fDistance >= 300.0f*300.0f) + return FALSE; + } + + if (!isValidAttacking()) + return FALSE; + + const float c_fAttackRadius = 20.0f; + const NRaceData::TMotionAttackData * pad = m_pkCurRaceMotionData->GetMotionAttackDataPointer(); + + const float motiontime = GetAttackingElapsedTime(); + + NRaceData::THitDataContainer::const_iterator itorHitData = pad->HitDataContainer.begin(); + for (; itorHitData != pad->HitDataContainer.end(); ++itorHitData) + { + const NRaceData::THitData & c_rHitData = *itorHitData; + + // NOTE : ̹ ¾Ҵ üũ + THitDataMap::iterator itHitData = m_HitDataMap.find(&c_rHitData); + if (itHitData != m_HitDataMap.end()) + { + THittedInstanceMap & rHittedInstanceMap = itHitData->second; + + THittedInstanceMap::iterator itInstance; + if ((itInstance=rHittedInstanceMap.find(&rVictim)) != rHittedInstanceMap.end()) + { + if (pad->iMotionType==NRaceData::MOTION_TYPE_COMBO || itInstance->second > GetLocalTime()) + continue; + } + } + + NRaceData::THitTimePositionMap::const_iterator range_start, range_end; + range_start = c_rHitData.mapHitPosition.lower_bound(motiontime-CTimer::Instance().GetElapsedSecond()); + range_end = c_rHitData.mapHitPosition.upper_bound(motiontime); + float c = cosf(D3DXToRadian(GetRotation())); + float s = sinf(D3DXToRadian(GetRotation())); + + for(;range_start!=range_end;++range_start) + { + const CDynamicSphereInstance& dsiSrc=range_start->second; + + CDynamicSphereInstance dsi; + dsi = dsiSrc; + dsi.fRadius = c_fAttackRadius; + { + D3DXVECTOR3 v3SrcDir=dsiSrc.v3Position-dsiSrc.v3LastPosition; + v3SrcDir*=__GetReachScale(); + + const D3DXVECTOR3& v3Src = dsiSrc.v3LastPosition+v3SrcDir; + D3DXVECTOR3& v3Dst = dsi.v3Position; + v3Dst.x = v3Src.x * c - v3Src.y * s; + v3Dst.y = v3Src.x * s + v3Src.y * c; + v3Dst += GetPosition(); + } + { + const D3DXVECTOR3& v3Src = dsiSrc.v3LastPosition; + D3DXVECTOR3& v3Dst = dsi.v3LastPosition; + v3Dst.x = v3Src.x * c - v3Src.y * s; + v3Dst.y = v3Src.x * s + v3Src.y * c; + v3Dst += GetPosition(); + } + + + TCollisionPointInstanceList::iterator cpit; + for(cpit = rVictim.m_DefendingPointInstanceList.begin(); cpit!=rVictim.m_DefendingPointInstanceList.end();++cpit) + { + int index = 0; + const CDynamicSphereInstanceVector & c_DefendingSphereVector = cpit->SphereInstanceVector; + CDynamicSphereInstanceVector::const_iterator dsit; + for(dsit = c_DefendingSphereVector.begin(); dsit!= c_DefendingSphereVector.end();++dsit, ++index) + { + const CDynamicSphereInstance& sub = *dsit; + if (DetectCollisionDynamicZCylinderVSDynamicZCylinder(dsi, sub)) + { + THitDataMap::iterator itHitData = m_HitDataMap.find(&c_rHitData); + if (itHitData == m_HitDataMap.end()) + { + THittedInstanceMap HittedInstanceMap; + HittedInstanceMap.insert(std::make_pair(&rVictim, GetLocalTime()+pad->fInvisibleTime)); + //HittedInstanceMap.insert(std::make_pair(&rVictim, GetLocalTime()+HIT_COOL_TIME)); + m_HitDataMap.insert(std::make_pair(&c_rHitData, HittedInstanceMap)); + + //Tracef(" ----------- First Hit\n"); + } + else + { + itHitData->second.insert(std::make_pair(&rVictim, GetLocalTime()+pad->fInvisibleTime)); + //itHitData->second.insert(std::make_pair(&rVictim, GetLocalTime()+HIT_COOL_TIME)); + + //Tracef(" ----------- Next Hit : %d\n", itHitData->second.size()); + + int iCurrentHitCount = itHitData->second.size(); + // NOTE : 16 Ѱ + if (NRaceData::MOTION_TYPE_COMBO == pad->iMotionType || NRaceData::MOTION_TYPE_NORMAL == pad->iMotionType) + { + if (iCurrentHitCount > 16) + { + //Tracef(" Type NORMAL :: Overflow - Can't process, skip\n"); + return FALSE; + } + } + else + { + if (iCurrentHitCount > pad->iHitLimitCount) + { + //Tracef(" Type SKILL :: Overflow - Can't process, skip\n"); + return FALSE; + } + } + } + + D3DXVECTOR3 v3HitPosition = (GetPosition() + rVictim.GetPosition()) *0.5f; + + // #0000780: [M2KR] Ÿݱ + extern bool IS_HUGE_RACE(unsigned int vnum); + if (IS_HUGE_RACE(rVictim.GetRace())) + { + v3HitPosition = (GetPosition() + sub.v3Position) * 0.5f; + } + + __ProcessDataAttackSuccess(*pad, rVictim, v3HitPosition, m_kCurMotNode.uSkill); + return TRUE; + } + } + } + } + } + + return FALSE; +} + +BOOL CActorInstance::AttackingProcess(CActorInstance & rVictim) +{ + if (rVictim.__isInvisible()) + return FALSE; + + if (__SplashAttackProcess(rVictim)) + return TRUE; + + if (__NormalAttackProcess(rVictim)) + return TRUE; + + return FALSE; +} + +BOOL CActorInstance::TestPhysicsBlendingCollision(CActorInstance & rVictim) +{ + if (rVictim.IsDead()) + return FALSE; + + TPixelPosition kPPosLast; + GetBlendingPosition( &kPPosLast ); + + D3DXVECTOR3 v3Distance = D3DXVECTOR3(rVictim.m_x - kPPosLast.x, rVictim.m_y - kPPosLast.y, rVictim.m_z - kPPosLast.z); + float fDistance = D3DXVec3LengthSq(&v3Distance); + if (fDistance > 800.0f*800.0f) + return FALSE; + + // NOTE : ϶ Defending Sphere Collision Check մϴ. + // NOTE : Wait Ǵ ߿ հ  ־.. - [levites] + TCollisionPointInstanceList * pMainList; + TCollisionPointInstanceList * pVictimList; + if (isAttacking() || IsWaiting()) + { + pMainList = &m_DefendingPointInstanceList; + pVictimList = &rVictim.m_DefendingPointInstanceList; + } + else + { + pMainList = &m_BodyPointInstanceList; + pVictimList = &rVictim.m_BodyPointInstanceList; + } + + TPixelPosition kPDelta; + m_PhysicsObject.GetLastPosition(&kPDelta); + + D3DXVECTOR3 prevLastPosition, prevPosition; + const int nSubCheckCount = 50; + + TCollisionPointInstanceListIterator itorMain = pMainList->begin(); + TCollisionPointInstanceListIterator itorVictim = pVictimList->begin(); + for (; itorMain != pMainList->end(); ++itorMain) + { + for (; itorVictim != pVictimList->end(); ++itorVictim) + { + CDynamicSphereInstanceVector & c_rMainSphereVector = (*itorMain).SphereInstanceVector; + CDynamicSphereInstanceVector & c_rVictimSphereVector = (*itorVictim).SphereInstanceVector; + + for (DWORD i = 0; i < c_rMainSphereVector.size(); ++i) + { + CDynamicSphereInstance & c_rMainSphere = c_rMainSphereVector[i]; + //adjust main sphere center + prevLastPosition = c_rMainSphere.v3LastPosition; + prevPosition = c_rMainSphere.v3Position; + + c_rMainSphere.v3LastPosition = prevPosition; + + for( int i = 1; i <= nSubCheckCount; ++ i ) + { + c_rMainSphere.v3Position = prevPosition + (float)(i/(float)nSubCheckCount) * kPDelta; + + for (DWORD j = 0; j < c_rVictimSphereVector.size(); ++j) + { + CDynamicSphereInstance & c_rVictimSphere = c_rVictimSphereVector[j]; + + if (DetectCollisionDynamicSphereVSDynamicSphere(c_rMainSphere, c_rVictimSphere)) + { + BOOL bResult = GetVector3Distance(c_rMainSphere.v3Position, c_rVictimSphere.v3Position) <= GetVector3Distance(c_rMainSphere.v3LastPosition, c_rVictimSphere.v3Position); + + c_rMainSphere.v3LastPosition = prevLastPosition; + c_rMainSphere.v3Position = prevPosition; + + return bResult; + } + } + } + + //restore + c_rMainSphere.v3LastPosition = prevLastPosition; + c_rMainSphere.v3Position = prevPosition; + } + } + } + + return FALSE; +} + + +BOOL CActorInstance::TestActorCollision(CActorInstance & rVictim) +{ +/* + if (m_pkHorse) + { + if (m_pkHorse->TestActorCollision(rVictim)) + return TRUE; + + return FALSE; + } +*/ + + if (rVictim.IsDead()) + return FALSE; + + // Check Distance + // NOTE : ָ üũ + // ŵó Ʈ ũⰡ Ŭ + // ijͰ ڽ Body Sphere Radius ũ ̵ߴ üũϰ, + // ׷ ʴٸ Ÿ üũؼ ɷش. + D3DXVECTOR3 v3Distance = D3DXVECTOR3(rVictim.m_x - m_x, rVictim.m_y - m_y, rVictim.m_z - m_z); + float fDistance = D3DXVec3LengthSq(&v3Distance); + if (fDistance > 800.0f*800.0f) + return FALSE; + + // NOTE : ϶ Defending Sphere Collision Check մϴ. + // NOTE : Wait Ǵ ߿ հ  ־.. - [levites] + TCollisionPointInstanceList * pMainList; + TCollisionPointInstanceList * pVictimList; + if (isAttacking() || IsWaiting()) + { + pMainList = &m_DefendingPointInstanceList; + pVictimList = &rVictim.m_DefendingPointInstanceList; + } + else + { + pMainList = &m_BodyPointInstanceList; + pVictimList = &rVictim.m_BodyPointInstanceList; + } + + TCollisionPointInstanceListIterator itorMain = pMainList->begin(); + TCollisionPointInstanceListIterator itorVictim = pVictimList->begin(); + for (; itorMain != pMainList->end(); ++itorMain) + for (; itorVictim != pVictimList->end(); ++itorVictim) + { + const CDynamicSphereInstanceVector & c_rMainSphereVector = (*itorMain).SphereInstanceVector; + const CDynamicSphereInstanceVector & c_rVictimSphereVector = (*itorVictim).SphereInstanceVector; + + for (DWORD i = 0; i < c_rMainSphereVector.size(); ++i) + for (DWORD j = 0; j < c_rVictimSphereVector.size(); ++j) + { + const CDynamicSphereInstance & c_rMainSphere = c_rMainSphereVector[i]; + const CDynamicSphereInstance & c_rVictimSphere = c_rVictimSphereVector[j]; + + if (DetectCollisionDynamicSphereVSDynamicSphere(c_rMainSphere, c_rVictimSphere)) + { + if (GetVector3Distance(c_rMainSphere.v3Position, c_rVictimSphere.v3Position) <= + GetVector3Distance(c_rMainSphere.v3LastPosition, c_rVictimSphere.v3Position)) + { + return TRUE; + } + return FALSE; + } + } + } + + return FALSE; +} + +bool CActorInstance::AvoidObject(const CGraphicObjectInstance& c_rkBGObj) +{ +#ifdef __MOVIE_MODE__ + if (IsMovieMode()) + return false; +#endif + + if (this==&c_rkBGObj) + return false; + + if (!__TestObjectCollision(&c_rkBGObj)) + return false; + + __AdjustCollisionMovement(&c_rkBGObj); + return true; +} + +bool CActorInstance::IsBlockObject(const CGraphicObjectInstance& c_rkBGObj) +{ + if (this==&c_rkBGObj) + return false; + + if (!__TestObjectCollision(&c_rkBGObj)) + return false; + + return true; +} + +void CActorInstance::BlockMovement() +{ + if (m_pkHorse) + { + m_pkHorse->__InitializeMovement(); + return; + } + + __InitializeMovement(); +} + +BOOL CActorInstance::__TestObjectCollision(const CGraphicObjectInstance * c_pObjectInstance) +{ + if (m_pkHorse) + { + if (m_pkHorse->__TestObjectCollision(c_pObjectInstance)) + return TRUE; + + return FALSE; + } + + if (m_canSkipCollision) + return FALSE; + + if (m_v3Movement.x == 0.0f && m_v3Movement.y == 0.0f && m_v3Movement.z == 0.0f) + return FALSE; + + TCollisionPointInstanceListIterator itorMain = m_BodyPointInstanceList.begin(); + for (; itorMain != m_BodyPointInstanceList.end(); ++itorMain) + { + const CDynamicSphereInstanceVector & c_rMainSphereVector = (*itorMain).SphereInstanceVector; + for (DWORD i = 0; i < c_rMainSphereVector.size(); ++i) + { + const CDynamicSphereInstance & c_rMainSphere = c_rMainSphereVector[i]; + + if (c_pObjectInstance->MovementCollisionDynamicSphere(c_rMainSphere)) + { + //const D3DXVECTOR3 & c_rv3Position = c_pObjectInstance->GetPosition(); + //if (GetVector3Distance(c_rMainSphere.v3Position, c_rv3Position) < + // GetVector3Distance(c_rMainSphere.v3LastPosition, c_rv3Position)) + { + return TRUE; + } + + //return FALSE; + } + } + } + + return FALSE; +} + + +bool CActorInstance::TestCollisionWithDynamicSphere(const CDynamicSphereInstance & dsi) +{ + TCollisionPointInstanceListIterator itorMain = m_BodyPointInstanceList.begin(); + for (; itorMain != m_BodyPointInstanceList.end(); ++itorMain) + { + const CDynamicSphereInstanceVector & c_rMainSphereVector = (*itorMain).SphereInstanceVector; + for (DWORD i = 0; i < c_rMainSphereVector.size(); ++i) + { + const CDynamicSphereInstance & c_rMainSphere = c_rMainSphereVector[i]; + + if (DetectCollisionDynamicSphereVSDynamicSphere(c_rMainSphere, dsi)) + { + return true; + } + } + } + + return false; +} diff --git a/source/GameLib/ActorInstanceData.cpp b/source/GameLib/ActorInstanceData.cpp new file mode 100644 index 0000000..0eb7069 --- /dev/null +++ b/source/GameLib/ActorInstanceData.cpp @@ -0,0 +1,358 @@ +#include "StdAfx.h" +#include "ActorInstance.h" +#include "RaceManager.h" +#include "ItemManager.h" +#include "RaceData.h" + +#include "../eterlib/ResourceManager.h" +#include "../etergrnlib/util.h" + +DWORD CActorInstance::GetVirtualID() +{ + return m_dwSelfVID; +} + +void CActorInstance::SetVirtualID(DWORD dwVID) +{ + m_dwSelfVID=dwVID; +} + +void CActorInstance::UpdateAttribute() +{ + if (!m_pAttributeInstance) + return; + + if (!m_bNeedUpdateCollision) + return; + + m_bNeedUpdateCollision = FALSE; + + const CStaticCollisionDataVector & c_rkVec_ColliData = m_pAttributeInstance->GetObjectPointer()->GetCollisionDataVector(); + UpdateCollisionData(&c_rkVec_ColliData); + + m_pAttributeInstance->RefreshObject(GetTransform()); + UpdateHeightInstance(m_pAttributeInstance); + + //BOOL isHeightData = m_pAttributeInstance->IsEmpty(); +} + +void CActorInstance::__CreateAttributeInstance(CAttributeData * pData) +{ + m_pAttributeInstance = CAttributeInstance::New(); + m_pAttributeInstance->Clear(); + m_pAttributeInstance->SetObjectPointer(pData); + if (pData->IsEmpty()) + { + m_pAttributeInstance->Clear(); + CAttributeInstance::Delete(m_pAttributeInstance); + } +} + +DWORD CActorInstance::GetRace() +{ + return m_eRace; +} + +bool CActorInstance::SetRace(DWORD eRace) +{ + CRaceData * pRaceData; + if (!CRaceManager::Instance().GetRaceDataPointer(eRace, &pRaceData)) + { + m_eRace=0; + m_pkCurRaceData=NULL; + return false; + } + + m_eRace=eRace; + m_pkCurRaceData = pRaceData; + + CAttributeData * pAttributeData = pRaceData->GetAttributeDataPtr(); + if (pAttributeData) + { + __CreateAttributeInstance(pAttributeData); + } + + memset(m_adwPartItemID, 0, sizeof(m_adwPartItemID)); + + // Setup Graphic ResourceData + __ClearAttachingEffect(); + + CGraphicThingInstance::Clear(); + + //NOTE : PC Part ϰ ش. + if( IsPC()) + { + CGraphicThingInstance::ReserveModelThing(CRaceData::PART_MAX_NUM); + CGraphicThingInstance::ReserveModelInstance(CRaceData::PART_MAX_NUM); + } + else + { + CGraphicThingInstance::ReserveModelThing(1); + CGraphicThingInstance::ReserveModelInstance(1); + } + + + CRaceData::TMotionModeDataIterator itor; + + if (pRaceData->CreateMotionModeIterator(itor)) + { + do + { + WORD wMotionMode = itor->first; + CRaceData::TMotionModeData * pMotionModeData = itor->second; + + CRaceData::TMotionVectorMap::iterator itorMotion = pMotionModeData->MotionVectorMap.begin(); + for (; itorMotion != pMotionModeData->MotionVectorMap.end(); ++itorMotion) + { + WORD wMotionIndex = itorMotion->first; + const CRaceData::TMotionVector & c_rMotionVector = itorMotion->second; + CRaceData::TMotionVector::const_iterator it; + DWORD i; + for (i = 0, it = c_rMotionVector.begin(); it != c_rMotionVector.end(); ++i, ++it) + { + DWORD dwMotionKey = MAKE_RANDOM_MOTION_KEY(wMotionMode, wMotionIndex, i); + CGraphicThingInstance::RegisterMotionThing(dwMotionKey, it->pMotion); + } + } + } + while (pRaceData->NextMotionModeIterator(itor)); + } + + return true; +} + +void CActorInstance::SetHair(DWORD eHair) +{ + m_eHair = eHair; + + CRaceData * pRaceData; + + if (!CRaceManager::Instance().GetRaceDataPointer(m_eRace, &pRaceData)) + return; + + CRaceData::SHair* pkHair=pRaceData->FindHair(eHair); + if (pkHair) + { + if (!pkHair->m_stModelFileName.empty()) + { + CGraphicThing * pkHairThing = (CGraphicThing *)CResourceManager::Instance().GetResourcePointer(pkHair->m_stModelFileName.c_str()); + RegisterModelThing(CRaceData::PART_HAIR, pkHairThing); + SetModelInstance(CRaceData::PART_HAIR, CRaceData::PART_HAIR, 0, CRaceData::PART_MAIN); + } + + const std::vector& c_rkVct_kSkin = pkHair->m_kVct_kSkin; + std::vector::const_iterator i; + for (i = c_rkVct_kSkin.begin(); i != c_rkVct_kSkin.end(); ++i) + { + const CRaceData::SSkin& c_rkSkinItem = *i; + + CResource * pkRes = CResourceManager::Instance().GetResourcePointer(c_rkSkinItem.m_stDstFileName.c_str()); + + if (pkRes) + SetMaterialImagePointer(CRaceData::PART_HAIR, c_rkSkinItem.m_stSrcFileName.c_str(), static_cast(pkRes)); + } + } +} + + + +void CActorInstance::SetShape(DWORD eShape, float fSpecular) +{ + m_eShape = eShape; + + CRaceData * pRaceData; + if (!CRaceManager::Instance().GetRaceDataPointer(m_eRace, &pRaceData)) + return; + + CRaceData::SShape* pkShape=pRaceData->FindShape(eShape); + if (pkShape) + { + CResourceManager& rkResMgr=CResourceManager::Instance(); + + if (pkShape->m_stModelFileName.empty()) + { + CGraphicThing* pModelThing = pRaceData->GetBaseModelThing(); + RegisterModelThing(0, pModelThing); + } + else + { + CGraphicThing* pModelThing = (CGraphicThing *)rkResMgr.GetResourcePointer(pkShape->m_stModelFileName.c_str()); + RegisterModelThing(0, pModelThing); + } + + { + std::string stLODModelFileName; + + char szLODModelFileNameEnd[256]; + for (UINT uLODIndex=1; uLODIndex<=3; ++uLODIndex) + { + sprintf(szLODModelFileNameEnd, "_lod_%.2d.gr2", uLODIndex); + stLODModelFileName = CFileNameHelper::NoExtension(pkShape->m_stModelFileName) + szLODModelFileNameEnd; + if (!rkResMgr.IsFileExist(stLODModelFileName.c_str())) + break; + + CGraphicThing* pLODModelThing = (CGraphicThing *)rkResMgr.GetResourcePointer(stLODModelFileName.c_str()); + if (!pLODModelThing) + break; + + RegisterLODThing(0, pLODModelThing); + } + } + + SetModelInstance(0, 0, 0); + + const std::vector& c_rkVct_kSkin = pkShape->m_kVct_kSkin; + std::vector::const_iterator i; + for (i = c_rkVct_kSkin.begin(); i != c_rkVct_kSkin.end(); ++i) + { + const CRaceData::SSkin& c_rkSkinItem = *i; + + CResource * pkRes = CResourceManager::Instance().GetResourcePointer(c_rkSkinItem.m_stDstFileName.c_str()); + + if (pkRes) + { + if (fSpecular > 0.0f) + { + SMaterialData kMaterialData; + kMaterialData.pImage = static_cast(pkRes); + kMaterialData.isSpecularEnable = TRUE; + kMaterialData.fSpecularPower = fSpecular; + kMaterialData.bSphereMapIndex = 0; + SetMaterialData(c_rkSkinItem.m_ePart, c_rkSkinItem.m_stSrcFileName.c_str(), kMaterialData); + } + else + { + SetMaterialImagePointer(c_rkSkinItem.m_ePart, c_rkSkinItem.m_stSrcFileName.c_str(), static_cast(pkRes)); + } + } + } + } + else + { + if (pRaceData->IsTree()) + { + __CreateTree(pRaceData->GetTreeFileName()); + } + else + { + CGraphicThing* pModelThing = pRaceData->GetBaseModelThing(); + RegisterModelThing(0, pModelThing); + + CGraphicThing* pLODModelThing = pRaceData->GetLODModelThing(); + RegisterLODThing(0, pLODModelThing); + + SetModelInstance(0, 0, 0); + } + } + + // Attaching Objects + for (DWORD i = 0; i < pRaceData->GetAttachingDataCount(); ++i) + { + const NRaceData::TAttachingData * c_pAttachingData; + if (!pRaceData->GetAttachingDataPointer(i, &c_pAttachingData)) + continue; + + switch (c_pAttachingData->dwType) + { + case NRaceData::ATTACHING_DATA_TYPE_EFFECT: + if (c_pAttachingData->isAttaching) + { + AttachEffectByName(0, c_pAttachingData->strAttachingBoneName.c_str(), c_pAttachingData->pEffectData->strFileName.c_str()); + } + else + { + AttachEffectByName(0, 0, c_pAttachingData->pEffectData->strFileName.c_str()); + } + break; + } + } +} + +void CActorInstance::ChangeMaterial(const char * c_szFileName) +{ + CRaceData * pRaceData; + if (!CRaceManager::Instance().GetRaceDataPointer(m_eRace, &pRaceData)) + return; + + CRaceData::SShape* pkShape=pRaceData->FindShape(m_eShape); + if (!pkShape) + return; + + const std::vector& c_rkVct_kSkin = pkShape->m_kVct_kSkin; + if (c_rkVct_kSkin.empty()) + return; + + std::vector::const_iterator i = c_rkVct_kSkin.begin(); + const CRaceData::SSkin& c_rkSkinItem = *i; + + std::string dstFileName = "d:/ymir work/npc/guild_symbol/guild_symbol.dds"; + dstFileName = c_szFileName; + + CResource * pkRes = CResourceManager::Instance().GetResourcePointer(dstFileName.c_str()); + if (!pkRes) + return; + + SetMaterialImagePointer(c_rkSkinItem.m_ePart, c_rkSkinItem.m_stSrcFileName.c_str(), static_cast(pkRes)); +} +/* +void CActorInstance::SetPart(DWORD dwPartIndex, DWORD dwItemID) +{ + if (dwPartIndex>=CRaceData::PART_MAX_NUM) + return; + + if (!m_pkCurRaceData) + { + assert(m_pkCurRaceData); + return; + } + + CItemData * pItemData; + if (!CItemManager::Instance().GetItemDataPointer(dwItemID, &pItemData)) + return; + + RegisterModelThing(dwPartIndex, pItemData->GetModelThing()); + for (DWORD i = 0; i < pItemData->GetLODModelThingCount(); ++i) + { + CGraphicThing * pThing; + if (!pItemData->GetLODModelThingPointer(i, &pThing)) + continue; + + RegisterLODThing(dwPartIndex, pThing); + } + SetModelInstance(dwPartIndex, dwPartIndex, 0); + + m_adwPartItemID[dwPartIndex] = dwItemID; +} +*/ + +DWORD CActorInstance::GetPartItemID(DWORD dwPartIndex) +{ + if (dwPartIndex>=CRaceData::PART_MAX_NUM) + { + TraceError("CActorInstance::GetPartIndex(dwPartIndex=%d/CRaceData::PART_MAX_NUM=%d)", dwPartIndex, CRaceData::PART_MAX_NUM); + return 0; + } + + return m_adwPartItemID[dwPartIndex]; +} + +void CActorInstance::SetSpecularInfo(BOOL bEnable, int iPart, float fAlpha) +{ + CRaceData * pkRaceData; + if (!CRaceManager::Instance().GetRaceDataPointer(m_eRace, &pkRaceData)) + return; + + CRaceData::SShape * pkShape = pkRaceData->FindShape(m_eShape); + if (pkShape->m_kVct_kSkin.empty()) + return; + + std::string filename = pkShape->m_kVct_kSkin[0].m_stSrcFileName.c_str(); + CFileNameHelper::ChangeDosPath(filename); + + CGraphicThingInstance::SetSpecularInfo(iPart, filename.c_str(), bEnable, fAlpha); +} + +void CActorInstance::SetSpecularInfoForce(BOOL bEnable, int iPart, float fAlpha) +{ + CGraphicThingInstance::SetSpecularInfo(iPart, NULL, bEnable, fAlpha); +} diff --git a/source/GameLib/ActorInstanceEvent.cpp b/source/GameLib/ActorInstanceEvent.cpp new file mode 100644 index 0000000..d3639db --- /dev/null +++ b/source/GameLib/ActorInstanceEvent.cpp @@ -0,0 +1,180 @@ +#include "StdAfx.h" +#include "ActorInstance.h" + +void CActorInstance::__OnSyncing() +{ + IEventHandler& rkEventHandler=__GetEventHandlerRef(); + + IEventHandler::SState kState; + kState.kPPosSelf=NEW_GetCurPixelPositionRef(); + kState.fAdvRotSelf=GetAdvancingRotation(); + rkEventHandler.OnSyncing(kState); +} + +void CActorInstance::__OnWaiting() +{ + assert(!IsPushing()); + + IEventHandler& rkEventHandler=__GetEventHandlerRef(); + + IEventHandler::SState kState; + kState.kPPosSelf=NEW_GetCurPixelPositionRef(); + kState.fAdvRotSelf=GetAdvancingRotation(); + rkEventHandler.OnWaiting(kState); +} + +void CActorInstance::__OnMoving() +{ + assert(!IsPushing()); + + IEventHandler& rkEventHandler=__GetEventHandlerRef(); + + const TPixelPosition& c_rkPPosCur=NEW_GetCurPixelPositionRef(); + const TPixelPosition& c_rkPPosDst=NEW_GetDstPixelPositionRef(); + + TPixelPosition kPPosDir=c_rkPPosDst-c_rkPPosCur; + float distance=sqrt(kPPosDir.x*kPPosDir.x+kPPosDir.y*kPPosDir.y); + + IEventHandler::SState kState; + + if (distance>1000.0f) + { + D3DXVec3Normalize(&kPPosDir, &kPPosDir); + D3DXVec3Scale(&kPPosDir, &kPPosDir, 1000.0f); + D3DXVec3Add(&kState.kPPosSelf, &kPPosDir, &c_rkPPosCur); + } + else + { + kState.kPPosSelf=c_rkPPosDst; + } + kState.fAdvRotSelf=GetAdvancingRotation(); + rkEventHandler.OnMoving(kState); +} + + +void CActorInstance::__OnMove() +{ + IEventHandler& rkEventHandler=__GetEventHandlerRef(); + + IEventHandler::SState kState; + kState.kPPosSelf=NEW_GetCurPixelPositionRef(); + kState.fAdvRotSelf=GetAdvancingRotation(); + rkEventHandler.OnMove(kState); +} + +void CActorInstance::__OnStop() +{ + IEventHandler& rkEventHandler=__GetEventHandlerRef(); + + IEventHandler::SState kState; + kState.kPPosSelf=NEW_GetCurPixelPositionRef(); + kState.fAdvRotSelf=GetAdvancingRotation(); + rkEventHandler.OnStop(kState); +} + +void CActorInstance::__OnWarp() +{ + IEventHandler& rkEventHandler=__GetEventHandlerRef(); + + IEventHandler::SState kState; + kState.kPPosSelf=NEW_GetCurPixelPositionRef(); + kState.fAdvRotSelf=GetAdvancingRotation(); + rkEventHandler.OnWarp(kState); +} + +void CActorInstance::__OnAttack(WORD wMotionIndex) +{ + IEventHandler& rkEventHandler=__GetEventHandlerRef(); + + IEventHandler::SState kState; + kState.kPPosSelf=NEW_GetCurPixelPositionRef(); + kState.fAdvRotSelf=GetTargetRotation(); + rkEventHandler.OnAttack(kState, wMotionIndex); +} + +void CActorInstance::__OnUseSkill(UINT uMotSkill, UINT uLoopCount, bool isMovingSkill) +{ + IEventHandler& rkEventHandler=__GetEventHandlerRef(); + + IEventHandler::SState kState; + kState.kPPosSelf=NEW_GetCurPixelPositionRef(); + kState.fAdvRotSelf=GetAdvancingRotation(); + + UINT uArg=uLoopCount; + if (isMovingSkill) + uArg|=1<<4; + + rkEventHandler.OnUseSkill(kState, uMotSkill, uArg); +} + +void CActorInstance::__OnHit(UINT uSkill, CActorInstance& rkActorVictm, BOOL isSendPacket) +{ + IEventHandler& rkEventHandler=__GetEventHandlerRef(); + rkEventHandler.OnHit(uSkill, rkActorVictm, isSendPacket); +} + +void CActorInstance::__OnClearAffects() +{ + IEventHandler& rkEventHandler=__GetEventHandlerRef(); + rkEventHandler.OnClearAffects(); +} + +void CActorInstance::__OnSetAffect(UINT uAffect) +{ + IEventHandler& rkEventHandler=__GetEventHandlerRef(); + rkEventHandler.OnSetAffect(uAffect); +} + +void CActorInstance::__OnResetAffect(UINT uAffect) +{ + IEventHandler& rkEventHandler=__GetEventHandlerRef(); + rkEventHandler.OnResetAffect(uAffect); +} + + +CActorInstance::IEventHandler& CActorInstance::__GetEventHandlerRef() +{ + assert(m_pkEventHandler!=NULL && "CActorInstance::GetEventHandlerRef"); + return *m_pkEventHandler; +} + +CActorInstance::IEventHandler* CActorInstance::__GetEventHandlerPtr() +{ + return m_pkEventHandler; +} + +void CActorInstance::SetEventHandler(IEventHandler* pkEventHandler) +{ + m_pkEventHandler=pkEventHandler; +} + +CActorInstance::IEventHandler* CActorInstance::IEventHandler::GetEmptyPtr() +{ + static class CEmptyEventHandler : public IEventHandler + { + public: + CEmptyEventHandler() {} + virtual ~CEmptyEventHandler() {} + + virtual void OnSyncing(const SState& c_rkState) {} + virtual void OnWaiting(const SState& c_rkState) {} + virtual void OnMoving(const SState& c_rkState) {} + virtual void OnMove(const SState& c_rkState) {} + virtual void OnStop(const SState& c_rkState) {} + virtual void OnWarp(const SState& c_rkState) {} + + virtual void OnClearAffects() {} + virtual void OnSetAffect(UINT uAffect) {} + virtual void OnResetAffect(UINT uAffect) {} + + virtual void OnAttack(const SState& c_rkState, WORD wMotionIndex) {} + virtual void OnUseSkill(const SState& c_rkState, UINT uMotSkill, UINT uMotLoopCount) {} + + virtual void OnHit(UINT uMotAttack, CActorInstance& rkActorVictim, BOOL isSendPacket) {} + + virtual void OnChangeShape() {} + + } s_kEmptyEventHandler; + + return &s_kEmptyEventHandler; +} diff --git a/source/GameLib/ActorInstanceFly.cpp b/source/GameLib/ActorInstanceFly.cpp new file mode 100644 index 0000000..44d2643 --- /dev/null +++ b/source/GameLib/ActorInstanceFly.cpp @@ -0,0 +1,117 @@ +#include "StdAfx.h" +#include "ActorInstance.h" + +D3DXVECTOR3 CActorInstance::OnGetFlyTargetPosition() +{ + D3DXVECTOR3 v3Center; + if (m_fRadius<=0) + { + BuildBoundingSphere(); + v3Center = m_v3Center; + } + else + { + v3Center = m_v3Center; + } + + D3DXVec3TransformCoord(&v3Center, &v3Center, &GetTransform()); + return v3Center; +} + +void CActorInstance::ClearFlyTarget() +{ + m_kFlyTarget.Clear(); + m_kBackupFlyTarget.Clear(); + m_kQue_kFlyTarget.clear(); +} + +bool CActorInstance::IsFlyTargetObject() +{ + return m_kFlyTarget.IsObject(); +} + +bool CActorInstance::__IsFlyTargetPC() +{ + if (!IsFlyTargetObject()) + return false; + + CActorInstance * pFlyInstance = (CActorInstance *)m_kFlyTarget.GetFlyTarget(); + if (pFlyInstance->IsPC()) + return true; + + return true; +} + +bool CActorInstance::__IsSameFlyTarget(CActorInstance * pInstance) +{ + if (!IsFlyTargetObject()) + return false; + + CActorInstance * pFlyInstance = (CActorInstance *)m_kFlyTarget.GetFlyTarget(); + if (pInstance == pFlyInstance) + return true; + + return true; +} + +D3DXVECTOR3 CActorInstance::__GetFlyTargetPosition() +{ + if (!m_kFlyTarget.IsValidTarget()) + { + return D3DXVECTOR3(0.0f, 0.0f, 0.0f); + } + + return m_kFlyTarget.GetFlyTargetPosition(); +} + +float CActorInstance::GetFlyTargetDistance() +{ + const D3DXVECTOR3& c_rv3FlyTargetPos=m_kFlyTarget.GetFlyTargetPosition(); + const D3DXVECTOR3& c_rkPosSrc=GetPosition(); + + D3DXVECTOR3 kPPosDelta=c_rv3FlyTargetPos-c_rkPosSrc; + kPPosDelta.z=0; + + return D3DXVec3Length(&kPPosDelta); +} + +void CActorInstance::LookAtFlyTarget() +{ + if (!IsFlyTargetObject()) + return; + + const D3DXVECTOR3& c_rv3FlyTargetPos=m_kFlyTarget.GetFlyTargetPosition(); + LookAt(c_rv3FlyTargetPos.x, c_rv3FlyTargetPos.y); +} + +void CActorInstance::AddFlyTarget(const CFlyTarget & cr_FlyTarget) +{ + if (m_kFlyTarget.IsValidTarget()) + m_kQue_kFlyTarget.push_back(cr_FlyTarget); + else + SetFlyTarget(cr_FlyTarget); +} + +void CActorInstance::SetFlyTarget(const CFlyTarget & cr_FlyTarget) +{ + m_kFlyTarget = cr_FlyTarget; +} + +void CActorInstance::ClearFlyEventHandler() +{ + m_pFlyEventHandler = 0; +} + +void CActorInstance::SetFlyEventHandler(IFlyEventHandler * pHandler) +{ + m_pFlyEventHandler = pHandler; +} + +// 2004. 07. 07. [levites] - ų Ÿ ٲ ذ ڵ +bool CActorInstance::CanChangeTarget() +{ + if (__IsNeedFlyTargetMotion()) + return false; + + return true; +} diff --git a/source/GameLib/ActorInstanceInterface.h b/source/GameLib/ActorInstanceInterface.h new file mode 100644 index 0000000..1187c1d --- /dev/null +++ b/source/GameLib/ActorInstanceInterface.h @@ -0,0 +1,18 @@ +#pragma once + +#include "../eterGrnLib/ThingInstance.h" + +class IActorInstance : public CGraphicThingInstance +{ +public: + enum + { + ID = ACTOR_OBJECT + }; + int GetType() const { return ID; } + + IActorInstance() {} + virtual ~IActorInstance() {} + virtual bool TestCollisionWithDynamicSphere(const CDynamicSphereInstance & dsi) = 0; + virtual DWORD GetVirtualID() = 0; +}; \ No newline at end of file diff --git a/source/GameLib/ActorInstanceMotion.cpp b/source/GameLib/ActorInstanceMotion.cpp new file mode 100644 index 0000000..338c7ff --- /dev/null +++ b/source/GameLib/ActorInstanceMotion.cpp @@ -0,0 +1,911 @@ +#include "StdAfx.h" +#include "ActorInstance.h" +#include "RaceData.h" +#include "FlyHandler.h" + +UINT CActorInstance::__GetMotionType() +{ + if (!m_pkCurRaceMotionData) + return CRaceMotionData::TYPE_NONE; + + return m_pkCurRaceMotionData->GetType(); +} + +void CActorInstance::__MotionEventProcess(BOOL isPC) +{ + if (isAttacking()) + { + DWORD dwNextFrame = DWORD(GetAttackingElapsedTime() * g_fGameFPS); + for (; m_kCurMotNode.dwcurFrame < dwNextFrame; ++m_kCurMotNode.dwcurFrame) + { + MotionEventProcess(); + SoundEventProcess(!isPC); + } + } + else + { + MotionEventProcess(); + SoundEventProcess(!isPC); + + ++m_kCurMotNode.dwcurFrame; + } +} + +void CActorInstance::MotionProcess(BOOL isPC) +{ + __MotionEventProcess(isPC); + CurrentMotionProcess(); + ReservingMotionProcess(); +} + +void CActorInstance::HORSE_MotionProcess(BOOL isPC) +{ + __MotionEventProcess(isPC); + + if (MOTION_TYPE_LOOP == m_kCurMotNode.iMotionType) + if (m_kCurMotNode.dwcurFrame >= m_kCurMotNode.dwFrameCount) + m_kCurMotNode.dwcurFrame = 0; +} + +void CActorInstance::ReservingMotionProcess() +{ + if (m_MotionDeque.empty()) + return; + + TReservingMotionNode & rReservingMotionNode = m_MotionDeque.front(); + + float fCurrentTime = GetLocalTime(); + if (rReservingMotionNode.fStartTime > fCurrentTime) + return; + + DWORD dwNextMotionIndex = GET_MOTION_INDEX(rReservingMotionNode.dwMotionKey); + switch (dwNextMotionIndex) + { + case CRaceMotionData::NAME_STAND_UP: + case CRaceMotionData::NAME_STAND_UP_BACK: + if (IsFaint()) + { + //Tracenf("Ͼ "); + + SetEndStopMotion(); + + // 1ʾ + TMotionDeque::iterator itor = m_MotionDeque.begin(); + for (; itor != m_MotionDeque.end(); ++itor) + { + TReservingMotionNode & rNode = *itor; + rNode.fStartTime += 1.0f; + } + return; + } + break; + } + + SCurrentMotionNode kPrevMotionNode=m_kCurMotNode; + + EMotionPushType iMotionType=rReservingMotionNode.iMotionType; + float fSpeedRatio=rReservingMotionNode.fSpeedRatio; + float fBlendTime=rReservingMotionNode.fBlendTime; + + DWORD dwMotionKey=rReservingMotionNode.dwMotionKey; + + m_MotionDeque.pop_front(); + + DWORD dwCurrentMotionIndex=GET_MOTION_INDEX(dwMotionKey); + switch (dwCurrentMotionIndex) + { + case CRaceMotionData::NAME_STAND_UP: + case CRaceMotionData::NAME_STAND_UP_BACK: + if (IsDead()) + { + //Tracenf("Ͼ "); + // ͷ + m_kCurMotNode=kPrevMotionNode; + __ClearMotion(); + + // + SetEndStopMotion(); + return; + } + break; + } + + //Tracenf("MOTION %d", GET_MOTION_INDEX(dwMotionKey)); + + int iLoopCount; + if (MOTION_TYPE_ONCE == iMotionType) + iLoopCount=1; + else + iLoopCount=0; + + SSetMotionData kSetMotData; + kSetMotData.dwMotKey=dwMotionKey; + kSetMotData.fBlendTime=fBlendTime; + kSetMotData.fSpeedRatio=fSpeedRatio; + kSetMotData.iLoopCount=iLoopCount; + + DWORD dwRealMotionKey = __SetMotion(kSetMotData); + + if (0 == dwRealMotionKey) + return; + + // FIX: ȣ __SetMotion Լ ȿ ٸ ɼ Ƿ duration ' ' duration ؾ . + //float fDurationTime=rReservingMotionNode.fDuration; + float fDurationTime = GetMotionDuration(dwRealMotionKey) / fSpeedRatio; + float fStartTime = rReservingMotionNode.fStartTime; + float fEndTime = fStartTime + fDurationTime; + + if (dwRealMotionKey == 16777473) + { + int bp = 0; + bp++; + } + + m_kCurMotNode.uSkill = 0; + m_kCurMotNode.iMotionType = iMotionType; + m_kCurMotNode.fSpeedRatio = fSpeedRatio; + m_kCurMotNode.fStartTime = fStartTime; + m_kCurMotNode.fEndTime = fEndTime; + m_kCurMotNode.dwMotionKey = dwRealMotionKey; + m_kCurMotNode.dwcurFrame = 0; + m_kCurMotNode.dwFrameCount = fDurationTime / (1.0f / g_fGameFPS); +} + +void CActorInstance::CurrentMotionProcess() +{ + if (MOTION_TYPE_LOOP == m_kCurMotNode.iMotionType) // ӽô. ǥ Once Ѿ ȵȴ. - [levites] + if (m_kCurMotNode.dwcurFrame >= m_kCurMotNode.dwFrameCount) + m_kCurMotNode.dwcurFrame = 0; + + if (IsDead()) + return; + + if (!m_MotionDeque.empty()) + return; + + float fCurrentTime = GetLocalTime(); + + DWORD dwMotionIndex=GET_MOTION_INDEX(m_kCurMotNode.dwMotionKey); + + bool isLooping=false; + + // ٸ Playing Flag + if (m_pkCurRaceMotionData && m_pkCurRaceMotionData->IsLoopMotion()) + { + if (m_kCurMotNode.iLoopCount > 1 || m_kCurMotNode.iLoopCount == -1) + { + if (fCurrentTime - m_kCurMotNode.fStartTime > m_pkCurRaceMotionData->GetLoopEndTime()) + { + m_kCurMotNode.dwcurFrame = DWORD(m_pkCurRaceMotionData->GetLoopStartTime() * g_fGameFPS); + __SetLocalTime(m_kCurMotNode.fStartTime + m_pkCurRaceMotionData->GetLoopStartTime()); + if (-1 != m_kCurMotNode.iLoopCount) + --m_kCurMotNode.iLoopCount; + + isLooping=true; + } + } + else if (!m_kQue_kFlyTarget.empty()) + { + if (!m_kBackupFlyTarget.IsObject()) + { + m_kBackupFlyTarget = m_kFlyTarget; + } + + if (fCurrentTime - m_kCurMotNode.fStartTime > m_pkCurRaceMotionData->GetLoopEndTime()) + { + m_kCurMotNode.dwcurFrame = DWORD(m_pkCurRaceMotionData->GetLoopStartTime() * g_fGameFPS); + __SetLocalTime(m_kCurMotNode.fStartTime + m_pkCurRaceMotionData->GetLoopStartTime()); + + SetFlyTarget(m_kQue_kFlyTarget.front()); + m_kQue_kFlyTarget.pop_front(); + + isLooping=true; + } + } + } + + if (!isLooping) + { + if (fCurrentTime > m_kCurMotNode.fEndTime) + { + if (m_kBackupFlyTarget.IsValidTarget()) + { + m_kFlyTarget = m_kBackupFlyTarget; + m_kBackupFlyTarget.Clear(); + } + + //////////////////////////////////////////// + + if (MOTION_TYPE_ONCE == m_kCurMotNode.iMotionType) + { + switch (dwMotionIndex) + { + case CRaceMotionData::NAME_DAMAGE_FLYING: + case CRaceMotionData::NAME_DAMAGE_FLYING_BACK: + case CRaceMotionData::NAME_DEAD: + case CRaceMotionData::NAME_INTRO_SELECTED: + case CRaceMotionData::NAME_INTRO_NOT_SELECTED: + m_kCurMotNode.fEndTime+=3.0f; + SetEndStopMotion(); + break; + default: + InterceptLoopMotion(CRaceMotionData::NAME_WAIT); + break; + } + } + else if (MOTION_TYPE_LOOP == m_kCurMotNode.iMotionType) + { + if (CRaceMotionData::NAME_WAIT == dwMotionIndex) + { + PushLoopMotion(CRaceMotionData::NAME_WAIT, 0.5f); + } + } + } + } +} + +void CActorInstance::SetMotionMode(int iMotionMode) +{ + if (IsPoly()) + iMotionMode=CRaceMotionData::MODE_GENERAL; + + m_wcurMotionMode = iMotionMode; +} + +int CActorInstance::GetMotionMode() +{ + return m_wcurMotionMode; +} + +void CActorInstance::SetMotionLoopCount(int iCount) +{ + assert(iCount >= -1 && iCount < 100); + m_kCurMotNode.iLoopCount = iCount; +} + +void CActorInstance::PushMotion(EMotionPushType iMotionType, DWORD dwMotionKey, float fBlendTime, float fSpeedRatio) +{ + if (!CheckMotionThingIndex(dwMotionKey)) + { + Tracef(" Error - Not found want to using motion : %d\n", GET_MOTION_INDEX(dwMotionKey)); + return; + } + + TReservingMotionNode MotionNode; + + MotionNode.iMotionType = iMotionType; + MotionNode.dwMotionKey = dwMotionKey; + MotionNode.fStartTime = GetLastMotionTime(fBlendTime); + MotionNode.fBlendTime = fBlendTime; + MotionNode.fSpeedRatio = fSpeedRatio; + MotionNode.fDuration = GetMotionDuration(dwMotionKey); + + m_MotionDeque.push_back(MotionNode); +} + +bool CActorInstance::InterceptOnceMotion(DWORD dwMotion, float fBlendTime, UINT uSkill, float fSpeedRatio) +{ + return InterceptMotion(MOTION_TYPE_ONCE, dwMotion, fBlendTime, uSkill, fSpeedRatio); +} + +bool CActorInstance::InterceptLoopMotion(DWORD dwMotion, float fBlendTime) +{ + return InterceptMotion(MOTION_TYPE_LOOP, dwMotion, fBlendTime); +} + +void CActorInstance::SetLoopMotion(DWORD dwMotion, float fBlendTime, float fSpeedRatio) +{ + if (!m_pkCurRaceData) + { + Tracenf("CActorInstance::SetLoopMotion(dwMotion=%d, fBlendTime=%f, fSpeedRatio=%f)", + dwMotion, fBlendTime, fSpeedRatio); + return; + } + + MOTION_KEY dwMotionKey; + if (!m_pkCurRaceData->GetMotionKey(m_wcurMotionMode, dwMotion, &dwMotionKey)) + { + Tracenf("CActorInstance::SetLoopMotion(dwMotion=%d, fBlendTime=%f, fSpeedRatio=%f) - GetMotionKey(m_wcurMotionMode=%d, dwMotion=%d, &MotionKey) ERROR", + dwMotion, fBlendTime, fSpeedRatio, m_wcurMotionMode, dwMotion); + return; + } + + __ClearMotion(); + + SSetMotionData kSetMotData; + kSetMotData.dwMotKey=dwMotionKey; + kSetMotData.fBlendTime=fBlendTime; + kSetMotData.fSpeedRatio=fSpeedRatio; + + DWORD dwRealMotionKey = __SetMotion(kSetMotData); + + if (0 == dwRealMotionKey) + return; + + m_kCurMotNode.iMotionType = MOTION_TYPE_LOOP; + m_kCurMotNode.fStartTime = GetLocalTime(); + m_kCurMotNode.dwMotionKey = dwRealMotionKey; + m_kCurMotNode.fEndTime = 0.0f; + m_kCurMotNode.fSpeedRatio = fSpeedRatio; + m_kCurMotNode.dwcurFrame = 0; + m_kCurMotNode.dwFrameCount = GetMotionDuration(dwRealMotionKey) / (1.0f / g_fGameFPS); + m_kCurMotNode.uSkill = 0; +} + +// ϰ == SetMotion ϰ == ִϸ̼ ͸ ÷ ߴ? +bool CActorInstance::InterceptMotion(EMotionPushType iMotionType, WORD wMotion, float fBlendTime, UINT uSkill, float fSpeedRatio) +{ + if (!m_pkCurRaceData) + { + Tracef("CActorInstance::InterceptMotion(iMotionType=%d, wMotion=%d, fBlendTime=%f) - m_pkCurRaceData=NULL", iMotionType, wMotion, fBlendTime); + return false; + } + + MOTION_KEY dwMotionKey; + if (!m_pkCurRaceData->GetMotionKey(m_wcurMotionMode, wMotion, &dwMotionKey)) + { + Tracenf("CActorInstance::InterceptMotion(iLoopType=%d, wMotionMode=%d, wMotion=%d, fBlendTime=%f) - GetMotionKey(m_wcurMotionMode=%d, wMotion=%d, &MotionKey) ERROR", + iMotionType, m_wcurMotionMode, wMotion, fBlendTime, m_wcurMotionMode, wMotion); + return false; + } + + __ClearMotion(); + + int iLoopCount; + if (MOTION_TYPE_ONCE == iMotionType) + iLoopCount=1; + else + iLoopCount=0; + + SSetMotionData kSetMotData; + kSetMotData.dwMotKey=dwMotionKey; + kSetMotData.fBlendTime=fBlendTime; + kSetMotData.iLoopCount=iLoopCount; + kSetMotData.fSpeedRatio=fSpeedRatio; + kSetMotData.uSkill=uSkill; + + DWORD dwRealMotionKey = __SetMotion(kSetMotData); + + if (0 == dwRealMotionKey) + return false; + + if (m_pFlyEventHandler) + { + if (__IsNeedFlyTargetMotion()) + { + m_pFlyEventHandler->OnSetFlyTarget(); + } + } + + assert(NULL != m_pkCurRaceMotionData); + + // FIX : ȣ __SetMotion Լ ٸ ֱ dwMotionKey ȿ ʰ + // ش Ű duration ȿ . 翬 play ð ؾ .. -_-;; + // float fDuration=GetMotionDuration(dwMotionKey)/fSpeedRatio; + float fDuration = GetMotionDuration(dwRealMotionKey) / fSpeedRatio; + + m_kCurMotNode.iMotionType = iMotionType; + m_kCurMotNode.fStartTime = GetLocalTime(); + m_kCurMotNode.fEndTime = m_kCurMotNode.fStartTime + fDuration; + m_kCurMotNode.dwMotionKey = dwRealMotionKey; + m_kCurMotNode.dwcurFrame = 0; + m_kCurMotNode.dwFrameCount = fDuration / (1.0f / g_fGameFPS); + m_kCurMotNode.uSkill = uSkill; + m_kCurMotNode.fSpeedRatio = fSpeedRatio; + + return true; +} + +bool CActorInstance::PushOnceMotion(DWORD dwMotion, float fBlendTime, float fSpeedRatio) +{ + assert(m_pkCurRaceData); + + MOTION_KEY MotionKey; + if (!m_pkCurRaceData->GetMotionKey(m_wcurMotionMode, dwMotion, &MotionKey)) + return false; + + PushMotion(MOTION_TYPE_ONCE, MotionKey, fBlendTime, fSpeedRatio); + return true; +} + +bool CActorInstance::PushLoopMotion(DWORD dwMotion, float fBlendTime, float fSpeedRatio) +{ + assert(m_pkCurRaceData); + + MOTION_KEY MotionKey; + if (!m_pkCurRaceData->GetMotionKey(m_wcurMotionMode, dwMotion, &MotionKey)) + return false; + + PushMotion(MOTION_TYPE_LOOP, MotionKey, fBlendTime, fSpeedRatio); + return true; +} + +WORD CActorInstance::__GetCurrentMotionIndex() +{ + return GET_MOTION_INDEX(m_kCurMotNode.dwMotionKey); +} + +DWORD CActorInstance::__GetCurrentMotionKey() +{ + return m_kCurMotNode.dwMotionKey; +} + +BOOL CActorInstance::IsUsingSkill() +{ + DWORD dwCurMotionIndex=__GetCurrentMotionIndex(); + + if (dwCurMotionIndex>=CRaceMotionData::NAME_SKILL && dwCurMotionIndexIsCancelEnableSkill(); +} + +BOOL CActorInstance::isLock() +{ + DWORD dwCurMotionIndex=__GetCurrentMotionIndex(); + + // Locked during attack + switch (dwCurMotionIndex) + { + case CRaceMotionData::NAME_NORMAL_ATTACK: + case CRaceMotionData::NAME_COMBO_ATTACK_1: + case CRaceMotionData::NAME_COMBO_ATTACK_2: + case CRaceMotionData::NAME_COMBO_ATTACK_3: + case CRaceMotionData::NAME_COMBO_ATTACK_4: + case CRaceMotionData::NAME_COMBO_ATTACK_5: + case CRaceMotionData::NAME_COMBO_ATTACK_6: + case CRaceMotionData::NAME_COMBO_ATTACK_7: + case CRaceMotionData::NAME_COMBO_ATTACK_8: + case CRaceMotionData::NAME_SPECIAL_1: + case CRaceMotionData::NAME_SPECIAL_2: + case CRaceMotionData::NAME_SPECIAL_3: + case CRaceMotionData::NAME_SPECIAL_4: + case CRaceMotionData::NAME_SPECIAL_5: + case CRaceMotionData::NAME_SPECIAL_6: + case CRaceMotionData::NAME_FISHING_THROW: + case CRaceMotionData::NAME_FISHING_WAIT: + case CRaceMotionData::NAME_FISHING_STOP: + case CRaceMotionData::NAME_FISHING_REACT: + case CRaceMotionData::NAME_FISHING_CATCH: + case CRaceMotionData::NAME_FISHING_FAIL: + case CRaceMotionData::NAME_CLAP: + case CRaceMotionData::NAME_DANCE_1: + case CRaceMotionData::NAME_DANCE_2: + case CRaceMotionData::NAME_DANCE_3: + case CRaceMotionData::NAME_DANCE_4: + case CRaceMotionData::NAME_DANCE_5: + case CRaceMotionData::NAME_DANCE_6: + case CRaceMotionData::NAME_CONGRATULATION: + case CRaceMotionData::NAME_FORGIVE: + case CRaceMotionData::NAME_ANGRY: + case CRaceMotionData::NAME_ATTRACTIVE: + case CRaceMotionData::NAME_SAD: + case CRaceMotionData::NAME_SHY: + case CRaceMotionData::NAME_CHEERUP: + case CRaceMotionData::NAME_BANTER: + case CRaceMotionData::NAME_JOY: + case CRaceMotionData::NAME_CHEERS_1: + case CRaceMotionData::NAME_CHEERS_2: + case CRaceMotionData::NAME_KISS_WITH_WARRIOR: + case CRaceMotionData::NAME_KISS_WITH_ASSASSIN: + case CRaceMotionData::NAME_KISS_WITH_SURA: + case CRaceMotionData::NAME_KISS_WITH_SHAMAN: + case CRaceMotionData::NAME_FRENCH_KISS_WITH_WARRIOR: + case CRaceMotionData::NAME_FRENCH_KISS_WITH_ASSASSIN: + case CRaceMotionData::NAME_FRENCH_KISS_WITH_SURA: + case CRaceMotionData::NAME_FRENCH_KISS_WITH_SHAMAN: + case CRaceMotionData::NAME_SLAP_HIT_WITH_WARRIOR: + case CRaceMotionData::NAME_SLAP_HIT_WITH_ASSASSIN: + case CRaceMotionData::NAME_SLAP_HIT_WITH_SURA: + case CRaceMotionData::NAME_SLAP_HIT_WITH_SHAMAN: + case CRaceMotionData::NAME_SLAP_HURT_WITH_WARRIOR: + case CRaceMotionData::NAME_SLAP_HURT_WITH_ASSASSIN: + case CRaceMotionData::NAME_SLAP_HURT_WITH_SURA: + case CRaceMotionData::NAME_SLAP_HURT_WITH_SHAMAN: + return TRUE; + break; + } + + // Locked during using skill + if (IsUsingSkill()) + { + if (m_pkCurRaceMotionData->IsCancelEnableSkill()) + return FALSE; + + return TRUE; + } + + return FALSE; +} + +float CActorInstance::GetLastMotionTime(float fBlendTime) +{ + if (m_MotionDeque.empty()) + { + if (MOTION_TYPE_ONCE == m_kCurMotNode.iMotionType) + return (m_kCurMotNode.fEndTime - fBlendTime); + + return GetLocalTime(); + } + + TReservingMotionNode & rMotionNode = m_MotionDeque[m_MotionDeque.size()-1]; + + return rMotionNode.fStartTime + rMotionNode.fDuration - fBlendTime; +} + +float CActorInstance::GetMotionDuration(DWORD dwMotionKey) +{ + CGraphicThing * pMotion; + + if (!GetMotionThingPointer(dwMotionKey, &pMotion)) + { + Tracenf("CActorInstance::GetMotionDuration - Cannot get motion: %d / %d", + GET_MOTION_MODE(dwMotionKey), GET_MOTION_INDEX(dwMotionKey)); + return 0.0f; + } + + if (0 == pMotion->GetMotionCount()) + { +#ifdef _DEBUG + Tracenf("CActorInstance::GetMotionDuration - Invalid Motion Key : %d, %d, %d", + GET_MOTION_MODE(dwMotionKey), GET_MOTION_INDEX(dwMotionKey), GET_MOTION_SUB_INDEX(dwMotionKey)); +#endif + return 0.0f; + } + + CGrannyMotion * pGrannyMotion = pMotion->GetMotionPointer(0); + return pGrannyMotion->GetDuration(); +} + +MOTION_KEY CActorInstance::GetRandomMotionKey(MOTION_KEY dwMotionKey) +{ + // NOTE : ȣ Ǵ κ ƴ ȭ - [levites] + // FIXME : ó õ Ϳ ó Ǿ ʴ. + WORD wMode = GET_MOTION_MODE(dwMotionKey); + WORD wIndex = GET_MOTION_INDEX(dwMotionKey); + + const CRaceData::TMotionVector * c_pMotionVector; + if (m_pkCurRaceData->GetMotionVectorPointer(wMode, wIndex, &c_pMotionVector)) + if (c_pMotionVector->size() > 1) + { + int iPercentage = random() % 100; + for (DWORD i = 0; i < c_pMotionVector->size(); ++i) + { + const CRaceData::TMotion & c_rMotion = c_pMotionVector->at(i); + iPercentage -= c_rMotion.byPercentage; + + if (iPercentage < 0) + { + dwMotionKey = MAKE_RANDOM_MOTION_KEY(wMode, wIndex, i); + + // Temporary + // NOTE: μ ⼭ غ ǹ̾. ü Ȯΰ Ʒ ڵ ٸ ذؾ ϹǷ ϴ ּó. ߿ ä .. + // m_kCurMotNode.fEndTime = m_kCurMotNode.fStartTime + GetMotionDuration(dwMotionKey); + // Temporary + + return dwMotionKey; + } + } + } + + return dwMotionKey; +} + +void CActorInstance::PreAttack() +{ +} + +void CActorInstance::__ClearMotion() +{ + __HideWeaponTrace(); + + m_MotionDeque.clear(); + m_kCurMotNode.dwcurFrame=0; + m_kCurMotNode.dwFrameCount=0; + m_kCurMotNode.uSkill=0; + m_kCurMotNode.iLoopCount=0; + m_kCurMotNode.iMotionType=MOTION_TYPE_NONE; +} + + +DWORD CActorInstance::__SetMotion(const SSetMotionData& c_rkSetMotData, DWORD dwRandMotKey) +{ + DWORD dwMotKey = dwRandMotKey; + + if (dwMotKey == 0) + dwMotKey = GetRandomMotionKey(c_rkSetMotData.dwMotKey); + + UINT uNextMot = GET_MOTION_INDEX(c_rkSetMotData.dwMotKey); + + if (IsDead()) + { + if (uNextMot!=CRaceMotionData::NAME_DAMAGE_FLYING && uNextMot!=CRaceMotionData::NAME_DAMAGE_FLYING_BACK && uNextMot!=CRaceMotionData::NAME_DEAD && uNextMot!=CRaceMotionData::NAME_DEAD_BACK) + return 0; + } + if (IsUsingSkill()) + { + __OnStop(); + } + + if (__IsStandUpMotion()) + { + __OnStop(); + } + + + if (__IsMoveMotion()) + { + if (uNextMot==CRaceMotionData::NAME_DAMAGE || uNextMot==CRaceMotionData::NAME_DAMAGE_BACK || uNextMot==CRaceMotionData::NAME_DAMAGE_FLYING || uNextMot==CRaceMotionData::NAME_DAMAGE_FLYING_BACK) + { + if (!m_isMain) + { + Logn(0, "ΰ ƴ϶ ̵̶ "); + return false; + } + } + + if (uNextMot!=CRaceMotionData::NAME_RUN && + uNextMot!=CRaceMotionData::NAME_WALK && + !__IsMovingSkill(c_rkSetMotData.uSkill)) + { + __OnStop(); + } + } + else + { + if (uNextMot==CRaceMotionData::NAME_RUN || __IsMovingSkill(c_rkSetMotData.uSkill)) + { + __OnMove(); + } + } + + + // NOTE : ų ġ - [levites] + if (__IsHiding()) + { + __ShowEvent(); + } + + + if (-1 != m_iFishingEffectID) + { + CEffectManager& rkEftMgr=CEffectManager::Instance(); + rkEftMgr.DeactiveEffectInstance(m_iFishingEffectID); + + m_iFishingEffectID = -1; + } + + if (m_pkHorse) + { + WORD wMotionIndex = GET_MOTION_INDEX(dwMotKey); + WORD wMotionSubIndex = GET_MOTION_SUB_INDEX(dwMotKey); + DWORD dwChildMotKey = MAKE_RANDOM_MOTION_KEY(m_pkHorse->m_wcurMotionMode, wMotionIndex, wMotionSubIndex); + + if (CRaceMotionData::NAME_DEAD == wMotionIndex) + CGraphicThingInstance::ChangeMotion(dwMotKey, c_rkSetMotData.iLoopCount, c_rkSetMotData.fSpeedRatio); + else + CGraphicThingInstance::SetMotion(dwMotKey, c_rkSetMotData.fBlendTime, c_rkSetMotData.iLoopCount, c_rkSetMotData.fSpeedRatio); + + m_pkHorse->SetMotion(dwChildMotKey, c_rkSetMotData.fBlendTime, c_rkSetMotData.iLoopCount, c_rkSetMotData.fSpeedRatio); + m_pkHorse->__BindMotionData(dwChildMotKey); + + if (c_rkSetMotData.iLoopCount) + m_pkHorse->m_kCurMotNode.iMotionType = MOTION_TYPE_ONCE; // Ÿ ǰ ־ + else + m_pkHorse->m_kCurMotNode.iMotionType = MOTION_TYPE_LOOP; + + m_pkHorse->m_kCurMotNode.dwFrameCount = m_pkHorse->GetMotionDuration(dwChildMotKey) / (1.0f / g_fGameFPS); + m_pkHorse->m_kCurMotNode.dwcurFrame = 0; + m_pkHorse->m_kCurMotNode.dwMotionKey = dwChildMotKey; + } + else + { + CGraphicThingInstance::SetMotion(dwMotKey, c_rkSetMotData.fBlendTime, c_rkSetMotData.iLoopCount, c_rkSetMotData.fSpeedRatio); + } + + __HideWeaponTrace(); + + if (__BindMotionData(dwMotKey)) + { + int iLoopCount = __GetLoopCount(); + SetMotionLoopCount(iLoopCount); + + if (__CanAttack()) + { + // ⼭ ó մϴ - [levites] + __ShowWeaponTrace(); + + m_HitDataMap.clear(); + //PreAttack(); + } + + if (__IsComboAttacking()) + { + if (!__CanNextComboAttack()) + { + // 2004.11.19.myevan. Ž ̺κп ٷ µǾ ȳ´ + m_dwcurComboIndex = 0; // ޺ - [levites] + + // NOTE : ClearCombo() ؼ ȵȴ. + // ޺ ų ̾ m_pkCurRaceMotionData ʱȭ Ǿ . + //Tracef("MotionData ޺ Ÿ ʽϴ.\n"); + } + } + } + + return dwMotKey; +} + +bool CActorInstance::__BindMotionData(DWORD dwMotionKey) +{ + if (!m_pkCurRaceData->GetMotionDataPointer(dwMotionKey, &m_pkCurRaceMotionData)) + { + Tracen("Failed to bind motion."); + m_pkCurRaceMotionData=NULL; + m_dwcurComboIndex=0; + return false; + } + + return true; +} + +int CActorInstance::__GetLoopCount() +{ + if (!m_pkCurRaceMotionData) + { + TraceError("CActorInstance::__GetLoopCount() - m_pkCurRaceMotionData==NULL"); + return -1; + } + + return m_pkCurRaceMotionData->GetLoopCount(); +} + +bool CActorInstance::__CanAttack() +{ + if (!m_pkCurRaceMotionData) + { + TraceError("CActorInstance::__CanAttack() - m_pkCurRaceMotionData==NULL"); + return false; + } + + if (!m_pkCurRaceMotionData->isAttackingMotion()) + return false; + + return true; +} + +bool CActorInstance::__CanNextComboAttack() +{ + if (!m_pkCurRaceMotionData) + { + TraceError("CActorInstance::__CanNextComboAttack() - m_pkCurRaceMotionData==NULL"); + return false; + } + + if (!m_pkCurRaceMotionData->IsComboInputTimeData()) + return false; + + return true; +} + +bool CActorInstance::__IsComboAttacking() +{ + if (0 == m_dwcurComboIndex) + return false; + + return true; +} + +bool CActorInstance::__IsNeedFlyTargetMotion() +{ + if (!m_pkCurRaceMotionData) + return true; + + for (DWORD i = 0; i < m_pkCurRaceMotionData->GetMotionEventDataCount(); ++i) + { + const CRaceMotionData::TMotionEventData * c_pData; + if (!m_pkCurRaceMotionData->GetMotionEventDataPointer(i, &c_pData)) + continue; + + if (c_pData->iType == CRaceMotionData::MOTION_EVENT_TYPE_WARP) + return true; + + if (c_pData->iType == CRaceMotionData::MOTION_EVENT_TYPE_FLY) + return true; + + if (c_pData->iType == CRaceMotionData::MOTION_EVENT_TYPE_EFFECT_TO_TARGET) + return true; + } + + return false; +} + +bool CActorInstance::__HasMotionFlyEvent() +{ + if (!m_pkCurRaceMotionData) + return true; + + for (DWORD i = 0; i < m_pkCurRaceMotionData->GetMotionEventDataCount(); ++i) + { + const CRaceMotionData::TMotionEventData * c_pData; + if (!m_pkCurRaceMotionData->GetMotionEventDataPointer(i, &c_pData)) + continue; + + if (c_pData->iType == CRaceMotionData::MOTION_EVENT_TYPE_FLY) + return true; + } + return false; +} + +bool CActorInstance::__IsWaitMotion() +{ + return (__GetMotionType()==CRaceMotionData::TYPE_WAIT); +} + +bool CActorInstance::__IsMoveMotion() +{ + return (__GetMotionType()==CRaceMotionData::TYPE_MOVE); +} + +bool CActorInstance::__IsAttackMotion() +{ + return (__GetMotionType()==CRaceMotionData::TYPE_ATTACK); +} + +bool CActorInstance::__IsComboAttackMotion() +{ + return (__GetMotionType()==CRaceMotionData::TYPE_COMBO); +} + + +bool CActorInstance::__IsDamageMotion() +{ + return (__GetMotionType()==CRaceMotionData::TYPE_DAMAGE); +} + +bool CActorInstance::__IsKnockDownMotion() +{ + return (__GetMotionType()==CRaceMotionData::TYPE_KNOCKDOWN); +} + +bool CActorInstance::__IsDieMotion() +{ + if (__IsKnockDownMotion()) + return true; + + return (__GetMotionType()==CRaceMotionData::TYPE_DIE); +} + +bool CActorInstance::__IsStandUpMotion() +{ + return (__GetMotionType()==CRaceMotionData::TYPE_STANDUP); +} diff --git a/source/GameLib/ActorInstanceMotionEvent.cpp b/source/GameLib/ActorInstanceMotionEvent.cpp new file mode 100644 index 0000000..c6d4b40 --- /dev/null +++ b/source/GameLib/ActorInstanceMotionEvent.cpp @@ -0,0 +1,331 @@ +#include "StdAfx.h" +#include "../EffectLib/EffectManager.h" +#include "../milesLib/SoundManager.h" + +#include "ActorInstance.h" +#include "FlyingObjectManager.h" +#include "FlyingInstance.h" +#include "GameEventManager.h" + +#include "FlyHandler.h" + +void CActorInstance::MotionEventProcess() +{ + if (!m_pkCurRaceMotionData) + return; + + for (DWORD i = 0; i < m_pkCurRaceMotionData->GetMotionEventDataCount(); ++i) + { + const CRaceMotionData::TMotionEventData * c_pData; + if (!m_pkCurRaceMotionData->GetMotionEventDataPointer(i, &c_pData)) + continue; + + MotionEventProcess(m_kCurMotNode.dwcurFrame, i, c_pData); + } +} + +void CActorInstance::SoundEventProcess(BOOL bCheckFrequency) +{ + if (!m_pkCurRaceMotionData) + return; + + CSoundManager& rkSndMgr=CSoundManager::Instance(); + const NSound::TSoundInstanceVector* c_pkVct_kSndInst=m_pkCurRaceMotionData->GetSoundInstanceVectorPointer(); + rkSndMgr.UpdateSoundInstance(m_x, m_y, m_z, m_kCurMotNode.dwcurFrame, c_pkVct_kSndInst, bCheckFrequency); +} + +void CActorInstance::MotionEventProcess(DWORD dwcurFrame, int iIndex, const CRaceMotionData::TMotionEventData * c_pData) +{ + if (c_pData->dwFrame != dwcurFrame) + return; + + switch (c_pData->iType) + { + case CRaceMotionData::MOTION_EVENT_TYPE_EFFECT: + ProcessMotionEventEffectEvent(c_pData); + break; + + case CRaceMotionData::MOTION_EVENT_TYPE_EFFECT_TO_TARGET: + ProcessMotionEventEffectToTargetEvent(c_pData); + break; + + case CRaceMotionData::MOTION_EVENT_TYPE_SCREEN_WAVING: + CGameEventManager::Instance().ProcessEventScreenWaving(this, (const CRaceMotionData::TScreenWavingEventData *)c_pData); + break; + + case CRaceMotionData::MOTION_EVENT_TYPE_SPECIAL_ATTACKING: + ProcessMotionEventSpecialAttacking(iIndex, c_pData); + break; + + case CRaceMotionData::MOTION_EVENT_TYPE_SOUND: + ProcessMotionEventSound(c_pData); + break; + + case CRaceMotionData::MOTION_EVENT_TYPE_FLY: + ProcessMotionEventFly(c_pData); + break; + + case CRaceMotionData::MOTION_EVENT_TYPE_CHARACTER_SHOW: + __ShowEvent(); + break; + + case CRaceMotionData::MOTION_EVENT_TYPE_CHARACTER_HIDE: + __HideEvent(); + break; + + case CRaceMotionData::MOTION_EVENT_TYPE_WARP: +#ifndef WORLD_EDITOR + ProcessMotionEventWarp(c_pData); +#endif + break; + } +} + +void CActorInstance::__ShowEvent() +{ + m_isHiding = FALSE; + RestoreRenderMode(); + SetAlphaValue(1.0f); +} + +void CActorInstance::__HideEvent() +{ + m_isHiding = TRUE; + SetBlendRenderMode(); + SetAlphaValue(0.0f); +} + +BOOL CActorInstance::__IsHiding() +{ + return m_isHiding; +} + +void CActorInstance::ProcessMotionEventEffectEvent(const CRaceMotionData::TMotionEventData * c_pData) +{ + if (CRaceMotionData::MOTION_EVENT_TYPE_EFFECT != c_pData->iType) + return; + + const CRaceMotionData::TMotionEffectEventData * c_pEffectData = (const CRaceMotionData::TMotionEffectEventData *)c_pData; + + if (c_pEffectData->isIndependent) + { + int iIndex = CEffectManager::Instance().CreateEffect(c_pEffectData->dwEffectIndex, D3DXVECTOR3(0.0f, 0.0f, 0.0f), D3DXVECTOR3(0.0f, 0.0f, 0.0f)); + + D3DXMATRIX matLocalPosition; + D3DXMatrixTranslation(&matLocalPosition, c_pEffectData->v3EffectPosition.x, c_pEffectData->v3EffectPosition.y, c_pEffectData->v3EffectPosition.z); + + D3DXMATRIX matWorld; + matWorld = matLocalPosition; + matWorld *= m_worldMatrix; + + CEffectManager::Instance().SelectEffectInstance(iIndex); + CEffectManager::Instance().SetEffectInstanceGlobalMatrix(matWorld); + return; + } + + if (c_pEffectData->isAttaching) + { + if (c_pEffectData->isFollowing) + { + AttachEffectByID(0, + c_pEffectData->strAttachingBoneName.c_str(), + c_pEffectData->dwEffectIndex, + &c_pEffectData->v3EffectPosition); + } + else + { + int iBoneIndex; + DWORD dwPartIndex = 0; + if (FindBoneIndex(dwPartIndex, c_pEffectData->strAttachingBoneName.c_str(), &iBoneIndex)) + { + D3DXMATRIX * pBoneMat; + GetBoneMatrix(dwPartIndex, iBoneIndex, &pBoneMat); + + D3DXMATRIX matLocalPosition; + D3DXMatrixTranslation(&matLocalPosition, c_pEffectData->v3EffectPosition.x, c_pEffectData->v3EffectPosition.y, c_pEffectData->v3EffectPosition.z); + + ///////////////////////////////////////////////////////////////////// + D3DXMATRIX matWorld; + matWorld = *pBoneMat; + matWorld *= matLocalPosition; + matWorld *= m_worldMatrix; + ///////////////////////////////////////////////////////////////////// + + int iIndex = CEffectManager::Instance().CreateEffect(c_pEffectData->dwEffectIndex, + c_pEffectData->v3EffectPosition, + D3DXVECTOR3(0.0f, 0.0f, 0.0f)); + CEffectManager::Instance().SelectEffectInstance(iIndex); + CEffectManager::Instance().SetEffectInstanceGlobalMatrix(matWorld); + } + } + } + else + { + AttachEffectByID(0, NULL, c_pEffectData->dwEffectIndex, &c_pEffectData->v3EffectPosition); + } +} + +void CActorInstance::ProcessMotionEventEffectToTargetEvent(const CRaceMotionData::TMotionEventData * c_pData) +{ + if (CRaceMotionData::MOTION_EVENT_TYPE_EFFECT_TO_TARGET != c_pData->iType) + return; + + const CRaceMotionData::TMotionEffectToTargetEventData * c_pEffectToTargetData = (const CRaceMotionData::TMotionEffectToTargetEventData *)c_pData; + + if (c_pEffectToTargetData->isFishingEffect) + { + CEffectManager& rkEftMgr=CEffectManager::Instance(); + + if (-1 != m_iFishingEffectID) + { + rkEftMgr.DeactiveEffectInstance(m_iFishingEffectID); + } + + m_iFishingEffectID = rkEftMgr.CreateEffect(c_pEffectToTargetData->dwEffectIndex, m_v3FishingPosition, D3DXVECTOR3(0.0f, 0.0f, 0.0f)); + } + else + { + if (!m_kFlyTarget.IsValidTarget()) + return; + + if (c_pEffectToTargetData->isFollowing && IsFlyTargetObject()) + { + CActorInstance * pTargetInstance = (CActorInstance *)m_kFlyTarget.GetFlyTarget(); + D3DXVECTOR3 v3Position( c_pEffectToTargetData->v3EffectPosition.x, + c_pEffectToTargetData->v3EffectPosition.y, + c_pEffectToTargetData->v3EffectPosition.z); + pTargetInstance->AttachEffectByID(0, NULL, c_pEffectToTargetData->dwEffectIndex, &v3Position); + } + else + { + const D3DXVECTOR3 & c_rv3FlyTarget = m_kFlyTarget.GetFlyTargetPosition(); + D3DXVECTOR3 v3Position( c_rv3FlyTarget.x + c_pEffectToTargetData->v3EffectPosition.x, + c_rv3FlyTarget.y + c_pEffectToTargetData->v3EffectPosition.y, + c_rv3FlyTarget.z + c_pEffectToTargetData->v3EffectPosition.z); + CEffectManager::Instance().CreateEffect(c_pEffectToTargetData->dwEffectIndex, v3Position, D3DXVECTOR3(0.0f, 0.0f, 0.0f)); + } + } +} + +void CActorInstance::ProcessMotionEventSpecialAttacking(int iMotionEventIndex, const CRaceMotionData::TMotionEventData * c_pData) +{ + if (CRaceMotionData::MOTION_EVENT_TYPE_SPECIAL_ATTACKING != c_pData->iType) + return; + + const CRaceMotionData::TMotionAttackingEventData * c_pAttackingData = (const CRaceMotionData::TMotionAttackingEventData *)c_pData; + + float fRadian = D3DXToRadian(270.0f + 360.0f - GetRotation()); + m_kSplashArea.isEnableHitProcess=c_pAttackingData->isEnableHitProcess; + m_kSplashArea.uSkill=m_kCurMotNode.uSkill; + m_kSplashArea.MotionKey = m_kCurMotNode.dwMotionKey; + m_kSplashArea.fDisappearingTime = GetLocalTime() + c_pAttackingData->fDurationTime; + m_kSplashArea.c_pAttackingEvent = c_pAttackingData; + m_kSplashArea.HittedInstanceMap.clear(); + + m_kSplashArea.SphereInstanceVector.clear(); + m_kSplashArea.SphereInstanceVector.resize(c_pAttackingData->CollisionData.SphereDataVector.size()); + for (DWORD i = 0; i < c_pAttackingData->CollisionData.SphereDataVector.size(); ++i) + { + const TSphereData & c_rSphereData = c_pAttackingData->CollisionData.SphereDataVector[i].GetAttribute(); + CDynamicSphereInstance & rSphereInstance = m_kSplashArea.SphereInstanceVector[i]; + + rSphereInstance.fRadius = c_rSphereData.fRadius; + //rSphereInstance.v3Advance = D3DXVECTOR3(0.0f, 0.0f, 0.0f); + + rSphereInstance.v3Position.x = m_x + c_rSphereData.v3Position.x*sinf(fRadian) + c_rSphereData.v3Position.y*cosf(fRadian); + rSphereInstance.v3Position.y = m_y + c_rSphereData.v3Position.x*cosf(fRadian) - c_rSphereData.v3Position.y*sinf(fRadian); + rSphereInstance.v3Position.z = m_z + c_rSphereData.v3Position.z; + rSphereInstance.v3LastPosition = rSphereInstance.v3Position; + } +} + +void CActorInstance::ProcessMotionEventSound(const CRaceMotionData::TMotionEventData * c_pData) +{ + if (CRaceMotionData::MOTION_EVENT_TYPE_SOUND != c_pData->iType) + return; + + const CRaceMotionData::TMotionSoundEventData * c_pSoundData = (const CRaceMotionData::TMotionSoundEventData *)c_pData; + + Tracenf("PLAY SOUND: %s", c_pSoundData->strSoundFileName.c_str()); + CSoundManager::Instance().PlaySound3D(m_x, m_y, m_z, c_pSoundData->strSoundFileName.c_str()); +} + +void CActorInstance::ProcessMotionEventFly(const CRaceMotionData::TMotionEventData * c_pData) +{ + if (CRaceMotionData::MOTION_EVENT_TYPE_FLY != c_pData->iType) + return; + + const CRaceMotionData::TMotionFlyEventData * c_pFlyData = (const CRaceMotionData::TMotionFlyEventData *)c_pData; + + if (m_kFlyTarget.IsValidTarget()) + { + CFlyingManager & rfm = CFlyingManager::Instance(); + + D3DXVECTOR3 v3Start(c_pFlyData->v3FlyPosition); + v3Start += m_v3Position; + + if (c_pFlyData->isAttaching) + { + D3DXMATRIX * pBoneMat; + int iBoneIndex; + DWORD dwPartIndex = 0; + + if (FindBoneIndex(dwPartIndex, c_pFlyData->strAttachingBoneName.c_str(), &iBoneIndex)) + if (GetBoneMatrix(dwPartIndex,iBoneIndex,&pBoneMat)) + { + v3Start.x += pBoneMat->_41; + v3Start.y += pBoneMat->_42; + v3Start.z += pBoneMat->_43; + } + } + + CFlyingInstance * pInstance = rfm.CreateFlyingInstanceFlyTarget(c_pFlyData->dwFlyIndex,v3Start,m_kFlyTarget,true); + if (pInstance) + { + pInstance->SetEventHandler(m_pFlyEventHandler); + pInstance->SetOwner(this); + pInstance->SetSkillIndex(m_kCurMotNode.uSkill); + } + + if (m_pFlyEventHandler) + { + m_pFlyEventHandler->OnShoot(m_kCurMotNode.uSkill); + } + } + else + { + //TraceError("ActorInstance::ProcessMotionEventFly No Target"); + } +} + +void CActorInstance::ProcessMotionEventWarp(const CRaceMotionData::TMotionEventData * c_pData) +{ + if (CRaceMotionData::MOTION_EVENT_TYPE_WARP != c_pData->iType) + return; + + // FIXME : TMotionWarpEventData - [levites] + static const float sc_fDistanceFromTarget = 270.0f; + + if (m_kFlyTarget.IsValidTarget()) + { + D3DXVECTOR3 v3MainPosition(m_x, m_y, m_z); + const D3DXVECTOR3 & c_rv3TargetPosition = __GetFlyTargetPosition(); + + D3DXVECTOR3 v3Distance = c_rv3TargetPosition - v3MainPosition; + D3DXVec3Normalize(&v3Distance, &v3Distance); + TPixelPosition DestPixelPosition = c_rv3TargetPosition - (v3Distance * sc_fDistanceFromTarget); + + // 2004.07.05.myevan.ýź ʿ ̴ ذ. ǥġ ̵ ϴ ̵ ʴ´ + IBackground& rkBG=GetBackground(); + if (!rkBG.IsBlock(DestPixelPosition.x, -DestPixelPosition.y)) + SetPixelPosition(DestPixelPosition); + + LookAt(c_rv3TargetPosition.x, c_rv3TargetPosition.y); + + __OnWarp(); + } + else + { + //TraceError("ActorInstance::ProcessMotionEventFly No Target"); + } +} diff --git a/source/GameLib/ActorInstancePosition.cpp b/source/GameLib/ActorInstancePosition.cpp new file mode 100644 index 0000000..0602364 --- /dev/null +++ b/source/GameLib/ActorInstancePosition.cpp @@ -0,0 +1,119 @@ +#include "StdAfx.h" +#include "ActorInstance.h" + +const TPixelPosition& CActorInstance::NEW_GetLastPixelPositionRef() +{ + GetBlendingPosition(&m_kPPosLast); + m_kPPosLast.y=-m_kPPosLast.y; + + return m_kPPosLast; +} + +const D3DXVECTOR3& CActorInstance::GetPositionVectorRef() +{ + m_v3Pos.x=m_x; + m_v3Pos.y=m_y; + m_v3Pos.z=m_z; + return m_v3Pos; +} + +const D3DXVECTOR3& CActorInstance::GetMovementVectorRef() +{ + if (m_pkHorse) + return m_pkHorse->GetMovementVectorRef(); + + return m_v3Movement; +} + +void CActorInstance::NEW_SetAtkPixelPosition(const TPixelPosition& c_rkPPosAtk) +{ + m_kPPosAtk=c_rkPPosAtk; +} + +void CActorInstance::SetCurPixelPosition(const TPixelPosition& c_rkPPosCur) +{ + D3DXVECTOR3 v3PosCur; + v3PosCur.x=+c_rkPPosCur.x; + v3PosCur.y=-c_rkPPosCur.y; + v3PosCur.z=+c_rkPPosCur.z; + + SetPixelPosition(v3PosCur); +} + +void CActorInstance::NEW_SetSrcPixelPosition(const TPixelPosition& c_rkPPosSrc) +{ + m_kPPosSrc=c_rkPPosSrc; +} + +void CActorInstance::NEW_SetDstPixelPositionZ(float z) +{ + m_kPPosDst.z=z; +} + +void CActorInstance::NEW_SetDstPixelPosition(const TPixelPosition& c_rkPPosDst) +{ + m_kPPosDst=c_rkPPosDst; +} + +const TPixelPosition& CActorInstance::NEW_GetAtkPixelPositionRef() +{ + return m_kPPosAtk; +} + +const TPixelPosition& CActorInstance::NEW_GetSrcPixelPositionRef() +{ + return m_kPPosSrc; +} + + +const TPixelPosition& CActorInstance::NEW_GetDstPixelPositionRef() +{ + return m_kPPosDst; +} + +const TPixelPosition& CActorInstance::NEW_GetCurPixelPositionRef() +{ + m_kPPosCur.x=+m_x; + m_kPPosCur.y=-m_y; + m_kPPosCur.z=+m_z; + + return m_kPPosCur; +} + +void CActorInstance::GetPixelPosition(TPixelPosition * pPixelPosition) +{ + pPixelPosition->x = m_x; + pPixelPosition->y = m_y; + pPixelPosition->z = m_z; +} + +void CActorInstance::SetPixelPosition(const TPixelPosition& c_rPixelPos) +{ + if (m_pkTree) + { + __SetTreePosition(c_rPixelPos.x, c_rPixelPos.y, c_rPixelPos.z); + } + + if (m_pkHorse) + m_pkHorse->SetPixelPosition(c_rPixelPos); + + m_x = c_rPixelPos.x; + m_y = c_rPixelPos.y; + m_z = c_rPixelPos.z; + m_bNeedUpdateCollision = TRUE; +} + + +void CActorInstance::__InitializePositionData() +{ + m_dwShakeTime = 0; + + m_x = 0.0f; + m_y = 0.0f; + m_z = 0.0f; + m_bNeedUpdateCollision = FALSE; + + m_kPPosAtk=m_kPPosLast=m_kPPosDst=m_kPPosCur=m_kPPosSrc=TPixelPosition(0.0f, 0.0f, 0.0f); + + __InitializeMovement(); +} diff --git a/source/GameLib/ActorInstanceRender.cpp b/source/GameLib/ActorInstanceRender.cpp new file mode 100644 index 0000000..ff588a3 --- /dev/null +++ b/source/GameLib/ActorInstanceRender.cpp @@ -0,0 +1,385 @@ +#include "StdAfx.h" +#include "../eterLib/StateManager.h" + +#include "ActorInstance.h" + +bool CActorInstance::ms_isDirLine=false; + +bool CActorInstance::IsDirLine() +{ + return ms_isDirLine; +} + +void CActorInstance::ShowDirectionLine(bool isVisible) +{ + ms_isDirLine=isVisible; +} + +void CActorInstance::SetMaterialColor(DWORD dwColor) +{ + if (m_pkHorse) + m_pkHorse->SetMaterialColor(dwColor); + + m_dwMtrlColor&=0xff000000; + m_dwMtrlColor|=(dwColor&0x00ffffff); +} + +void CActorInstance::SetMaterialAlpha(DWORD dwAlpha) +{ + m_dwMtrlAlpha=dwAlpha; +} + + +void CActorInstance::OnRender() +{ + D3DMATERIAL8 kMtrl; + STATEMANAGER.GetMaterial(&kMtrl); + + kMtrl.Diffuse=D3DXCOLOR(m_dwMtrlColor); + STATEMANAGER.SetMaterial(&kMtrl); + + // ̷.. ´ Diffuse Blend и.. + // ƴϸ ̷ · Texture & State Sorting .. - [levites] + STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + + switch(m_iRenderMode) + { + case RENDER_MODE_NORMAL: + BeginDiffuseRender(); + RenderWithOneTexture(); + EndDiffuseRender(); + BeginOpacityRender(); + BlendRenderWithOneTexture(); + EndOpacityRender(); + break; + case RENDER_MODE_BLEND: + if (m_fAlphaValue == 1.0f) + { + BeginDiffuseRender(); + RenderWithOneTexture(); + EndDiffuseRender(); + BeginOpacityRender(); + BlendRenderWithOneTexture(); + EndOpacityRender(); + } + else if (m_fAlphaValue > 0.0f) + { + BeginBlendRender(); + RenderWithOneTexture(); + BlendRenderWithOneTexture(); + EndBlendRender(); + } + break; + case RENDER_MODE_ADD: + BeginAddRender(); + RenderWithOneTexture(); + BlendRenderWithOneTexture(); + EndAddRender(); + break; + case RENDER_MODE_MODULATE: + BeginModulateRender(); + RenderWithOneTexture(); + BlendRenderWithOneTexture(); + EndModulateRender(); + break; + } + + STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE); + + kMtrl.Diffuse=D3DXCOLOR(0xffffffff); + STATEMANAGER.SetMaterial(&kMtrl); + + if (ms_isDirLine) + { + D3DXVECTOR3 kD3DVt3Cur(m_x, m_y, m_z); + + D3DXVECTOR3 kD3DVt3LookDir(0.0f, -1.0f, 0.0f); + D3DXMATRIX kD3DMatLook; + D3DXMatrixRotationZ(&kD3DMatLook, D3DXToRadian(GetRotation())); + D3DXVec3TransformCoord(&kD3DVt3LookDir, &kD3DVt3LookDir, &kD3DMatLook); + D3DXVec3Scale(&kD3DVt3LookDir, &kD3DVt3LookDir, 200.0f); + D3DXVec3Add(&kD3DVt3LookDir, &kD3DVt3LookDir, &kD3DVt3Cur); + + D3DXVECTOR3 kD3DVt3AdvDir(0.0f, -1.0f, 0.0f); + D3DXMATRIX kD3DMatAdv; + D3DXMatrixRotationZ(&kD3DMatAdv, D3DXToRadian(GetAdvancingRotation())); + D3DXVec3TransformCoord(&kD3DVt3AdvDir, &kD3DVt3AdvDir, &kD3DMatAdv); + D3DXVec3Scale(&kD3DVt3AdvDir, &kD3DVt3AdvDir, 200.0f); + D3DXVec3Add(&kD3DVt3AdvDir, &kD3DVt3AdvDir, &kD3DVt3Cur); + + static CScreen s_kScreen; + + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + STATEMANAGER.SaveRenderState(D3DRS_ZENABLE, FALSE); + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); + + s_kScreen.SetDiffuseColor(1.0f, 1.0f, 0.0f); + s_kScreen.RenderLine3d(kD3DVt3Cur.x, kD3DVt3Cur.y, kD3DVt3Cur.z, kD3DVt3AdvDir.x, kD3DVt3AdvDir.y, kD3DVt3AdvDir.z); + + s_kScreen.SetDiffuseColor(0.0f, 1.0f, 1.0f); + s_kScreen.RenderLine3d(kD3DVt3Cur.x, kD3DVt3Cur.y, kD3DVt3Cur.z, kD3DVt3LookDir.x, kD3DVt3LookDir.y, kD3DVt3LookDir.z); + + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, TRUE); + STATEMANAGER.RestoreRenderState(D3DRS_ZENABLE); + + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAOP); + STATEMANAGER.RestoreVertexShader(); + } +} + +void CActorInstance::BeginDiffuseRender() +{ + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, FALSE); +} + +void CActorInstance::EndDiffuseRender() +{ + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); +} + +void CActorInstance::BeginOpacityRender() +{ + STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_ALPHAREF, 0); + STATEMANAGER.SaveRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER); + + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); +} + +void CActorInstance::EndOpacityRender() +{ + STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHAREF); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHAFUNC); +} + +void CActorInstance::BeginBlendRender() +{ + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, D3DXCOLOR(1.0f, 1.0f, 1.0f, m_fAlphaValue)); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); +} + +void CActorInstance::EndBlendRender() +{ + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND); + STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND); +} + +void CActorInstance::BeginAddRender() +{ + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, m_AddColor); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TFACTOR); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADD); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, FALSE); +} + +void CActorInstance::EndAddRender() +{ + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); +} + +void CActorInstance::RestoreRenderMode() +{ + // NOTE : This is temporary code. I wanna convert this code to that restore the mode to + // model's default setting which had has as like specular or normal. - [levites] + m_iRenderMode = RENDER_MODE_NORMAL; + if (m_kBlendAlpha.m_isBlending) + { + m_kBlendAlpha.m_iOldRenderMode = m_iRenderMode; + } +} + + +void CActorInstance::SetAddRenderMode() +{ + m_iRenderMode = RENDER_MODE_ADD; + if (m_kBlendAlpha.m_isBlending) + { + m_kBlendAlpha.m_iOldRenderMode = m_iRenderMode; + } +} + +void CActorInstance::SetRenderMode(int iRenderMode) +{ + m_iRenderMode = iRenderMode; + if (m_kBlendAlpha.m_isBlending) + { + m_kBlendAlpha.m_iOldRenderMode = iRenderMode; + } +} + +void CActorInstance::SetAddColor(const D3DXCOLOR & c_rColor) +{ + m_AddColor = c_rColor; + m_AddColor.a = 1.0f; +} + +void CActorInstance::BeginModulateRender() +{ + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, m_AddColor); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TFACTOR); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, FALSE); +} + +void CActorInstance::EndModulateRender() +{ + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); +} + +void CActorInstance::SetModulateRenderMode() +{ + m_iRenderMode = RENDER_MODE_MODULATE; + if (m_kBlendAlpha.m_isBlending) + { + m_kBlendAlpha.m_iOldRenderMode = m_iRenderMode; + } +} + +void CActorInstance::RenderCollisionData() +{ + static CScreen s_Screen; + + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); + STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + if (m_pAttributeInstance) + { + for (DWORD col=0; col < GetCollisionInstanceCount(); ++col) + { + CBaseCollisionInstance * pInstance = GetCollisionInstanceData(col); + pInstance->Render(); + } + } + + STATEMANAGER.SetRenderState(D3DRS_ZENABLE, FALSE); + s_Screen.SetColorOperation(); + s_Screen.SetDiffuseColor(1.0f, 0.0f, 0.0f); + TCollisionPointInstanceList::iterator itor; + /*itor = m_AttackingPointInstanceList.begin(); + for (; itor != m_AttackingPointInstanceList.end(); ++itor) + { + const TCollisionPointInstance & c_rInstance = *itor; + for (DWORD i = 0; i < c_rInstance.SphereInstanceVector.size(); ++i) + { + const CDynamicSphereInstance & c_rSphereInstance = c_rInstance.SphereInstanceVector[i]; + s_Screen.RenderCircle3d(c_rSphereInstance.v3Position.x, + c_rSphereInstance.v3Position.y, + c_rSphereInstance.v3Position.z, + c_rSphereInstance.fRadius); + } + }*/ + s_Screen.SetDiffuseColor(1.0f, (isShow())?1.0f:0.0f, 0.0f); + D3DXVECTOR3 center; + float r; + GetBoundingSphere(center,r); + s_Screen.RenderCircle3d(center.x,center.y,center.z,r); + + s_Screen.SetDiffuseColor(0.0f, 0.0f, 1.0f); + itor = m_DefendingPointInstanceList.begin(); + for (; itor != m_DefendingPointInstanceList.end(); ++itor) + { + const TCollisionPointInstance & c_rInstance = *itor; + for (DWORD i = 0; i < c_rInstance.SphereInstanceVector.size(); ++i) + { + const CDynamicSphereInstance & c_rSphereInstance = c_rInstance.SphereInstanceVector[i]; + s_Screen.RenderCircle3d(c_rSphereInstance.v3Position.x, + c_rSphereInstance.v3Position.y, + c_rSphereInstance.v3Position.z, + c_rSphereInstance.fRadius); + } + } + + s_Screen.SetDiffuseColor(0.0f, 1.0f, 0.0f); + itor = m_BodyPointInstanceList.begin(); + for (; itor != m_BodyPointInstanceList.end(); ++itor) + { + const TCollisionPointInstance & c_rInstance = *itor; + for (DWORD i = 0; i < c_rInstance.SphereInstanceVector.size(); ++i) + { + const CDynamicSphereInstance & c_rSphereInstance = c_rInstance.SphereInstanceVector[i]; + s_Screen.RenderCircle3d(c_rSphereInstance.v3Position.x, + c_rSphereInstance.v3Position.y, + c_rSphereInstance.v3Position.z, + c_rSphereInstance.fRadius); + } + } + + s_Screen.SetDiffuseColor(1.0f, 0.0f, 0.0f); +// if (m_SplashArea.fDisappearingTime > GetLocalTime()) + { + CDynamicSphereInstanceVector::iterator itor = m_kSplashArea.SphereInstanceVector.begin(); + for (; itor != m_kSplashArea.SphereInstanceVector.end(); ++itor) + { + const CDynamicSphereInstance & c_rInstance = *itor; + s_Screen.RenderCircle3d(c_rInstance.v3Position.x, + c_rInstance.v3Position.y, + c_rInstance.v3Position.z, + c_rInstance.fRadius); + } + } + + STATEMANAGER.SetRenderState(D3DRS_ZENABLE, TRUE); + STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE); + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, TRUE); +} + + +void CActorInstance::RenderToShadowMap() +{ + if (RENDER_MODE_BLEND == m_iRenderMode) + if (GetAlphaValue() < 0.5f) + return; + + CGraphicThingInstance::RenderToShadowMap(); + + if (m_pkHorse) + m_pkHorse->RenderToShadowMap(); +} diff --git a/source/GameLib/ActorInstanceRotation.cpp b/source/GameLib/ActorInstanceRotation.cpp new file mode 100644 index 0000000..3d052ee --- /dev/null +++ b/source/GameLib/ActorInstanceRotation.cpp @@ -0,0 +1,128 @@ +#include "StdAfx.h" +#include "ActorInstance.h" + +void CActorInstance::SetXYRotation(float fRotX, float fRotY) +{ + m_rotX = fRotX; + m_rotY = fRotY; +} + +void CActorInstance::SetRotation(float fRot) +{ + if (m_pkHorse) + m_pkHorse->SetRotation(fRot); + + m_fcurRotation = fRot; + m_rotBegin = m_fcurRotation; + m_rotEnd = m_fcurRotation; + + m_rotBlendTime = 0.0f; + m_rotBeginTime = 0.0f; + m_rotEndTime = 0.0f; + + m_bNeedUpdateCollision = TRUE; +} + +void CActorInstance::BlendRotation(float fRot, float fBlendTime) +{ + if (m_pkHorse) + m_pkHorse->BlendRotation(fRot, fBlendTime); + + if (m_fcurRotation == fRot) + return; + + m_rotBegin = fmod(m_fcurRotation, 360.0f); + m_rotEnd = fRot; + + m_rotBlendTime = fBlendTime; + m_rotBeginTime = GetLocalTime(); + m_rotEndTime = m_rotBeginTime + m_rotBlendTime; +} + +void CActorInstance::SetAdvancingRotation(float fRot) +{ + if (m_pkHorse) + m_pkHorse->SetAdvancingRotation(fRot); + + m_fAdvancingRotation = fRot; +} + +void CActorInstance::RotationProcess() +{ + if (m_pkHorse) + m_pkHorse->RotationProcess(); + + if (GetLocalTime() < m_rotEndTime) + { + m_fcurRotation = GetInterpolatedRotation(m_rotBegin, m_rotEnd, (GetLocalTime() - m_rotBeginTime) / m_rotBlendTime); + SetAdvancingRotation(m_fcurRotation); + } + else + { + m_fcurRotation = m_rotEnd; + } + + // FIXME : "ǹ϶ üũ" ٲ۴. - [levites] + if (0.0f != m_rotX || 0.0f != m_rotY) + { + CGraphicObjectInstance::SetRotation(m_rotX, m_rotY, m_fcurRotation); + } + else + { + CGraphicObjectInstance::SetRotation(m_fcurRotation); + } +} + +void CActorInstance::LookAtFromXY(float x, float y, CActorInstance * pDestInstance) +{ + float rot = GetDegreeFromPosition2(pDestInstance->m_x, + pDestInstance->m_y, + x, + y); + + LookAt(rot); +} + +void CActorInstance::LookAt(float fDirRot) +{ + BlendRotation(fDirRot, 0.3f); +} + +void CActorInstance::LookAt(float fx, float fy) +{ + float rot = GetDegreeFromPosition2(m_x, m_y, fx, fy); + + LookAt(rot); +} + +void CActorInstance::LookAt(CActorInstance * pInstance) +{ + TPixelPosition PixelPosition; + pInstance->GetPixelPosition(&PixelPosition); + LookAt(PixelPosition.x, PixelPosition.y); +} + +void CActorInstance::LookWith(CActorInstance * pInstance) +{ + BlendRotation(pInstance->m_rotEnd, 0.3f); +} + +float CActorInstance::GetRotation() +{ + return m_fcurRotation; +} + +float CActorInstance::GetTargetRotation() +{ + return m_rotEnd; +} + +float CActorInstance::GetRotatingTime() +{ + return m_rotEndTime; +} + +float CActorInstance::GetAdvancingRotation() +{ + return m_fAdvancingRotation; +} diff --git a/source/GameLib/ActorInstanceSync.cpp b/source/GameLib/ActorInstanceSync.cpp new file mode 100644 index 0000000..828877d --- /dev/null +++ b/source/GameLib/ActorInstanceSync.cpp @@ -0,0 +1,76 @@ +#include "StdAfx.h" +#include "ActorInstance.h" +#include "RaceData.h" + + + +void CActorInstance::__Push(int x, int y) +{ + if (IsResistFallen()) + return; + + //DWORD dwVID=GetVirtualID(); + //Tracenf("VID %d SyncPixelPosition %d %d", dwVID, x, y); + + const D3DXVECTOR3& c_rv3Src=GetPosition(); + const D3DXVECTOR3 c_v3Dst=D3DXVECTOR3(x, -y, c_rv3Src.z); + const D3DXVECTOR3 c_v3Delta=c_v3Dst-c_rv3Src; + + const int LoopValue = 100; + const D3DXVECTOR3 inc=c_v3Delta / LoopValue; + + D3DXVECTOR3 v3Movement(0.0f, 0.0f, 0.0f); + + IPhysicsWorld* pWorld = IPhysicsWorld::GetPhysicsWorld(); + + if (!pWorld) + { + return; + } + + for(int i = 0; i < LoopValue; ++i) + { + if (pWorld->isPhysicalCollision(c_rv3Src + v3Movement)) + { + ResetBlendingPosition(); + return; + } + v3Movement += inc; + } + + SetBlendingPosition(c_v3Dst); + + if (!IsUsingSkill()) + { + int len=sqrt(c_v3Delta.x*c_v3Delta.x+c_v3Delta.y*c_v3Delta.y); + if (len>150.0f) + { + InterceptOnceMotion(CRaceMotionData::NAME_DAMAGE_FLYING); + PushOnceMotion(CRaceMotionData::NAME_STAND_UP); + } + } +} + +void CActorInstance::TEMP_Push(int x, int y) +{ + __Push(x, y); +} + +bool CActorInstance::__IsSyncing() +{ + if (IsDead()) + return TRUE; + + if (IsStun()) + return TRUE; + + if (IsPushing()) + return TRUE; + + return FALSE; +} + +bool CActorInstance::IsPushing() +{ + return m_PhysicsObject.isBlending(); +} \ No newline at end of file diff --git a/source/GameLib/ActorInstanceWeaponTrace.cpp b/source/GameLib/ActorInstanceWeaponTrace.cpp new file mode 100644 index 0000000..a09c400 --- /dev/null +++ b/source/GameLib/ActorInstanceWeaponTrace.cpp @@ -0,0 +1,40 @@ +#include "StdAfx.h" +#include "ActorInstance.h" +#include "WeaponTrace.h" + +void CActorInstance::TraceProcess() +{ + if (!m_WeaponTraceVector.empty()) + { + std::vector::iterator it; + for(it = m_WeaponTraceVector.begin(); it != m_WeaponTraceVector.end(); ++it) + { + CWeaponTrace * pWeaponTrace = (*it); + pWeaponTrace->SetPosition(m_x, m_y, m_z); + pWeaponTrace->SetRotation(m_fcurRotation); + pWeaponTrace->Update(__GetReachScale()); + } + } +} + +void CActorInstance::RenderTrace() +{ + for_each(m_WeaponTraceVector.begin(), m_WeaponTraceVector.end(), std::mem_fn(&CWeaponTrace::Render)); +} + +void CActorInstance::__DestroyWeaponTrace() +{ + std::for_each(m_WeaponTraceVector.begin(), m_WeaponTraceVector.end(), CWeaponTrace::Delete); + m_WeaponTraceVector.clear(); +} + +void CActorInstance::__ShowWeaponTrace() +{ + for_each(m_WeaponTraceVector.begin(), m_WeaponTraceVector.end(), std::mem_fn(&CWeaponTrace::TurnOn)); +} + +void CActorInstance::__HideWeaponTrace() +{ + for_each(m_WeaponTraceVector.begin(), m_WeaponTraceVector.end(), std::mem_fn(&CWeaponTrace::TurnOff)); +} + diff --git a/source/GameLib/Area.cpp b/source/GameLib/Area.cpp new file mode 100644 index 0000000..8a748ae --- /dev/null +++ b/source/GameLib/Area.cpp @@ -0,0 +1,1446 @@ +#include "StdAfx.h" + +#include "../eterLib/ResourceManager.h" +#include "../eterLib/StateManager.h" +#include "../effectLib/EffectManager.h" +#include "../SpeedTreeLib/SpeedTreeForestDirectX8.h" +#include "../eterBase/Timer.h" + +#include "Area.h" +#include "PropertyManager.h" +#include "Property.h" + +CDynamicPool CArea::ms_ObjectInstancePool; +CDynamicPool CArea::ms_AttributeInstancePool; +CDynamicPool CArea::ms_AmbienceInstancePool; +CDynamicPool CArea::ms_DungeonBlockInstancePool; +CDynamicPool CArea::ms_kPool; + +void CArea::TObjectData::InitializeRotation() +{ + m_fYaw=m_fPitch=m_fRoll=0.0f; +} + +CArea* CArea::New() +{ + return ms_kPool.Alloc(); +} + +void CArea::Delete(CArea* pkArea) +{ + pkArea->Clear(); + ms_kPool.Free(pkArea); +} + +void CArea::DestroySystem() +{ + ms_kPool.Destroy(); + + ms_ObjectInstancePool.Destroy(); + ms_AttributeInstancePool.Destroy(); + ms_AmbienceInstancePool.Destroy(); + ms_DungeonBlockInstancePool.Destroy(); +} + +void CArea::__UpdateAniThingList() +{ + { + CGraphicThingInstance* pkThingInst; + + TThingInstanceVector::iterator i=m_ThingCloneInstaceVector.begin(); + while (i!=m_ThingCloneInstaceVector.end()) + { + pkThingInst=*i++; + if (pkThingInst->isShow()) + { + pkThingInst->UpdateLODLevel(); + } + } + } + + { + CGraphicThingInstance* pkThingInst; + + TThingInstanceVector::iterator i=m_AniThingCloneInstanceVector.begin(); + while (i!=m_AniThingCloneInstanceVector.end()) + { + pkThingInst=*i++; + pkThingInst->Update(); + } + } +} + +void CArea::__UpdateEffectList() +{ + //if (!CEffectManager::InstancePtr()) + // return; + + CEffectManager& rkEftMgr=CEffectManager::Instance(); + + // Effect + TEffectInstanceIterator i; + for (i = m_EffectInstanceMap.begin(); i != m_EffectInstanceMap.end();) + { + CEffectInstance * pEffectInstance = i->second; + + pEffectInstance->Update(); + + if (!pEffectInstance->isAlive()) + { + i = m_EffectInstanceMap.erase(i); + rkEftMgr.DestroyUnsafeEffectInstance(pEffectInstance); + } + else + ++i; + } +} + +void CArea::Update() +{ + __UpdateAniThingList(); +} + +void CArea::UpdateAroundAmbience(float fX, float fY, float fZ) +{ + // Ambience + TAmbienceInstanceVector::iterator i; + for (i = m_AmbienceCloneInstanceVector.begin(); i != m_AmbienceCloneInstanceVector.end(); ++i) + { + TAmbienceInstance * pInstance = *i; + pInstance->__Update(fX, fY, fZ); + } +} + +struct CArea_LessEffectInstancePtrRenderOrder +{ + bool operator() (CEffectInstance* pkLeft, CEffectInstance* pkRight) + { + return pkLeft->LessRenderOrder(pkRight); + } +}; + +struct CArea_FEffectInstanceRender +{ + inline void operator () (CEffectInstance * pkEftInst) + { + pkEftInst->Render(); + } +}; + +void CArea::RenderEffect() +{ + __UpdateEffectList(); + + // Effect + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SetTexture(1, NULL); + + bool m_isDisableSortRendering=false; + + if (m_isDisableSortRendering) + { + TEffectInstanceIterator i; + for (i = m_EffectInstanceMap.begin(); i != m_EffectInstanceMap.end();) + { + CEffectInstance * pEffectInstance = i->second; + pEffectInstance->Render(); + ++i; + } + } + else + { + static std::vector s_kVct_pkEftInstSort; + s_kVct_pkEftInstSort.clear(); + + TEffectInstanceMap& rkMap_pkEftInstSrc=m_EffectInstanceMap; + TEffectInstanceMap::iterator i; + for (i=rkMap_pkEftInstSrc.begin(); i!=rkMap_pkEftInstSrc.end(); ++i) + s_kVct_pkEftInstSort.push_back(i->second); + + std::sort(s_kVct_pkEftInstSort.begin(), s_kVct_pkEftInstSort.end(), CArea_LessEffectInstancePtrRenderOrder()); + std::for_each(s_kVct_pkEftInstSort.begin(), s_kVct_pkEftInstSort.end(), CArea_FEffectInstanceRender()); + + } +} + +DWORD CArea::DEBUG_GetRenderedCRCNum() +{ return m_kRenderedThingInstanceCRCWithNumberVector.size(); } + +CArea::TCRCWithNumberVector & CArea::DEBUG_GetRenderedCRCWithNumVector() +{ return m_kRenderedThingInstanceCRCWithNumberVector; } + +DWORD CArea::DEBUG_GetRenderedGrapphicThingInstanceNum() +{ return m_kRenderedGrapphicThingInstanceVector.size(); } + +void CArea::CollectRenderingObject(std::vector& rkVct_pkOpaqueThingInst) +{ + TThingInstanceVector::iterator i; + for (i=m_ThingCloneInstaceVector.begin(); i!=m_ThingCloneInstaceVector.end(); ++i) + { + CGraphicThingInstance* pkThingInst=*i; + if (pkThingInst->isShow()) + { + if (!pkThingInst->HaveBlendThing()) + rkVct_pkOpaqueThingInst.push_back(*i); + } + } +} + +void CArea::CollectBlendRenderingObject(std::vector& rkVct_pkBlendThingInst) +{ + TThingInstanceVector::iterator i; + for (i=m_ThingCloneInstaceVector.begin(); i!=m_ThingCloneInstaceVector.end(); ++i) + { + CGraphicThingInstance* pkThingInst=*i; + if (pkThingInst->isShow()) + { + if (pkThingInst->HaveBlendThing()) + rkVct_pkBlendThingInst.push_back(*i); + } + } +} + +void CArea::Render() +{ + { + CGraphicThingInstance* pkThingInst; + + TThingInstanceVector::iterator i=m_AniThingCloneInstanceVector.begin(); + while (i!=m_AniThingCloneInstanceVector.end()) + { + pkThingInst=*i++; + pkThingInst->Deform(); + } + } + + CGraphicThingInstance* pkThingInst; + + TThingInstanceVector::iterator i=m_ThingCloneInstaceVector.begin(); + + m_kRenderedThingInstanceCRCWithNumberVector.clear(); + m_kRenderedGrapphicThingInstanceVector.clear(); + TGraphicThingInstanceCRCMap::iterator aGraphicThingInstanceCRCMapIterator; + + while (i!=m_ThingCloneInstaceVector.end()) + { + pkThingInst=*i++; + if (pkThingInst->Render()) + { + aGraphicThingInstanceCRCMapIterator = m_GraphicThingInstanceCRCMap.find(pkThingInst); + DWORD dwCRC = (*aGraphicThingInstanceCRCMapIterator).second; + + m_kRenderedGrapphicThingInstanceVector.push_back(pkThingInst); + + TCRCWithNumberVector::iterator aCRCWithNumberVectorIterator = std::find_if(m_kRenderedThingInstanceCRCWithNumberVector.begin(), m_kRenderedThingInstanceCRCWithNumberVector.end(), FFindIfCRC(dwCRC)); + + if ( m_kRenderedThingInstanceCRCWithNumberVector.end() == aCRCWithNumberVectorIterator) + { + TCRCWithNumber aCRCWithNumber; + aCRCWithNumber.dwCRC = dwCRC; + aCRCWithNumber.dwNumber = 1; + m_kRenderedThingInstanceCRCWithNumberVector.push_back(aCRCWithNumber); + } + else + { + TCRCWithNumber & rCRCWithNumber = *aCRCWithNumberVectorIterator; + rCRCWithNumber.dwNumber += 1; + } + } + } + std::sort(m_kRenderedThingInstanceCRCWithNumberVector.begin(), m_kRenderedThingInstanceCRCWithNumberVector.end(), CRCNumComp()); +} + + +void CArea::RenderCollision() +{ + DWORD i; + + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SetTexture(1, NULL); + + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xff000000); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + for(i=0;ipTree && po->pTree->isShow()) + { + DWORD j; + for(j=0;jpTree->GetCollisionInstanceCount();j++) + { + po->pTree->GetCollisionInstanceData(j)->Render(); + } + } + if (po->pThingInstance && po->pThingInstance->isShow()) + { + DWORD j; + for(j=0;jpThingInstance->GetCollisionInstanceCount();j++) + { + po->pThingInstance->GetCollisionInstanceData(j)->Render(); + } + } + if (po->pDungeonBlock && po->pDungeonBlock->isShow()) + { + DWORD j; + for(j=0;jpDungeonBlock->GetCollisionInstanceCount();j++) + { + po->pDungeonBlock->GetCollisionInstanceData(j)->Render(); + } + } + } + } + + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE); + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, TRUE); +} + +void CArea::RenderAmbience() +{ + DWORD dwColorArg1, dwColorOp; + STATEMANAGER.GetTextureStageState(0, D3DTSS_COLORARG1, &dwColorArg1); + STATEMANAGER.GetTextureStageState(0, D3DTSS_COLOROP, &dwColorOp); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + TAmbienceInstanceVector::iterator itor = m_AmbienceCloneInstanceVector.begin(); + for (; itor != m_AmbienceCloneInstanceVector.end(); ++itor) + { + TAmbienceInstance * pInstance = *itor; + pInstance->Render(); + } + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, dwColorArg1); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, dwColorOp); +} + +void CArea::RenderDungeon() +{ + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + +#ifdef WORLD_EDITOR + bool bRenderTransparent = false; + + DWORD oldAlphaBlendState = 0; + DWORD oldZWriteenableState = 0; + + if (GetAsyncKeyState(VK_LSHIFT) & 0x8001) + { + bRenderTransparent = true; + + oldAlphaBlendState = STATEMANAGER.GetRenderState(D3DRS_ALPHABLENDENABLE); + oldZWriteenableState = STATEMANAGER.GetRenderState(D3DRS_ZWRITEENABLE); + + STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + STATEMANAGER.SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); + + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, D3DCOLOR_ARGB( 128, 255, 0, 0) ); + } +#endif + + TDungeonBlockInstanceVector::iterator itor = m_DungeonBlockCloneInstanceVector.begin(); + for (; itor != m_DungeonBlockCloneInstanceVector.end(); ++itor) + { + (*itor)->Render(); + } + +#ifdef WORLD_EDITOR + if (bRenderTransparent) + { + STATEMANAGER.SetRenderState(D3DRS_ZWRITEENABLE, oldZWriteenableState); + STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, oldAlphaBlendState); + } +#endif + + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); +} + +void CArea::Refresh() +{ + m_TreeCloneInstaceVector.clear(); + m_ThingCloneInstaceVector.clear(); + m_DungeonBlockCloneInstanceVector.clear(); + m_AniThingCloneInstanceVector.clear(); + m_ShadowThingCloneInstaceVector.clear(); + m_AmbienceCloneInstanceVector.clear(); + + TObjectInstanceVector::iterator it; + + for(it = m_ObjectInstanceVector.begin();it!=m_ObjectInstanceVector.end();++it) + { + TObjectInstance * pObjectInstance = *it; + + if (prt::PROPERTY_TYPE_TREE == pObjectInstance->dwType) + { + if (pObjectInstance->pTree) + { + m_TreeCloneInstaceVector.push_back(pObjectInstance->pTree); + + const float * pfPosition; + pfPosition = pObjectInstance->pTree->GetPosition(); + pObjectInstance->pTree->UpdateBoundingSphere(); + pObjectInstance->pTree->UpdateCollisionData(); + } + } + else if (prt::PROPERTY_TYPE_BUILDING == pObjectInstance->dwType) + { + pObjectInstance->pThingInstance->Update(); + pObjectInstance->pThingInstance->Transform(); + pObjectInstance->pThingInstance->Show(); + pObjectInstance->pThingInstance->DeformAll(); + m_ThingCloneInstaceVector.push_back(pObjectInstance->pThingInstance); + + pObjectInstance->pThingInstance->BuildBoundingSphere(); + pObjectInstance->pThingInstance->UpdateBoundingSphere(); + + if (pObjectInstance->pThingInstance->IsMotionThing()) + { + m_AniThingCloneInstanceVector.push_back(pObjectInstance->pThingInstance); + pObjectInstance->pThingInstance->SetMotion(0); + } + + if (pObjectInstance->isShadowFlag) + { + m_ShadowThingCloneInstaceVector.push_back(pObjectInstance->pThingInstance); + } + + if (pObjectInstance->pAttributeInstance) + { + pObjectInstance->pThingInstance->UpdateCollisionData(&pObjectInstance->pAttributeInstance->GetObjectPointer()->GetCollisionDataVector()); + pObjectInstance->pAttributeInstance->RefreshObject(pObjectInstance->pThingInstance->GetTransform()); + pObjectInstance->pThingInstance->UpdateHeightInstance(pObjectInstance->pAttributeInstance); + } + } + else if (prt::PROPERTY_TYPE_EFFECT == pObjectInstance->dwType) + { + } + else if (prt::PROPERTY_TYPE_AMBIENCE == pObjectInstance->dwType) + { + m_AmbienceCloneInstanceVector.push_back(pObjectInstance->pAmbienceInstance); + } + else if (prt::PROPERTY_TYPE_DUNGEON_BLOCK == pObjectInstance->dwType) + { + pObjectInstance->pDungeonBlock->Update(); + pObjectInstance->pDungeonBlock->Deform(); + pObjectInstance->pDungeonBlock->UpdateBoundingSphere(); + m_DungeonBlockCloneInstanceVector.push_back(pObjectInstance->pDungeonBlock); + + if (pObjectInstance->pAttributeInstance) + { + pObjectInstance->pDungeonBlock->UpdateCollisionData(&pObjectInstance->pAttributeInstance->GetObjectPointer()->GetCollisionDataVector()); + pObjectInstance->pAttributeInstance->RefreshObject(pObjectInstance->pDungeonBlock->GetTransform()); + pObjectInstance->pDungeonBlock->UpdateHeightInstance(pObjectInstance->pAttributeInstance); + } + } + } +} + +void CArea::__Load_BuildObjectInstances() +{ + m_ObjectInstanceVector.clear(); + m_ObjectInstanceVector.resize(GetObjectDataCount()); + + m_GraphicThingInstanceCRCMap.clear(); + + std::sort(m_ObjectDataVector.begin(), m_ObjectDataVector.end(), ObjectDataComp()); + + DWORD i=0; + TObjectInstanceVector::iterator it; + for (it = m_ObjectInstanceVector.begin(); it!=m_ObjectInstanceVector.end();++it,++i) + { + *it = ms_ObjectInstancePool.Alloc(); + (*it)->Clear(); + + const TObjectData * c_pObjectData; + + if (!GetObjectDataPointer(i, &c_pObjectData)) + continue; + + __SetObjectInstance(*it, c_pObjectData); + + // ȭ + if ((*it)->dwType == prt::PROPERTY_TYPE_BUILDING) + m_GraphicThingInstanceCRCMap.insert(TGraphicThingInstanceCRCMap::value_type( (*it)->pThingInstance, c_pObjectData->dwCRC ) ); + } + + ////////// + Refresh(); + ////////// +} + +void CArea::__SetObjectInstance(TObjectInstance * pObjectInstance, const TObjectData * c_pData) +{ + CProperty * pProperty; + if (!CPropertyManager::Instance().Get(c_pData->dwCRC, &pProperty)) + return; + + const char * c_szPropertyType; + + if (!pProperty->GetString("PropertyType", &c_szPropertyType)) + return; + + switch (prt::GetPropertyType(c_szPropertyType)) + { + case prt::PROPERTY_TYPE_TREE: + __SetObjectInstance_SetTree(pObjectInstance, c_pData, pProperty); + break; + + case prt::PROPERTY_TYPE_BUILDING: + __SetObjectInstance_SetBuilding(pObjectInstance, c_pData, pProperty); + break; + + case prt::PROPERTY_TYPE_EFFECT: + __SetObjectInstance_SetEffect(pObjectInstance, c_pData, pProperty); + break; + + case prt::PROPERTY_TYPE_AMBIENCE: + __SetObjectInstance_SetAmbience(pObjectInstance, c_pData, pProperty); + break; + + case prt::PROPERTY_TYPE_DUNGEON_BLOCK: + __SetObjectInstance_SetDungeonBlock(pObjectInstance, c_pData, pProperty); + break; + } +} + +void CArea::__SetObjectInstance_SetEffect(TObjectInstance * pObjectInstance, const TObjectData * c_pData, CProperty * pProperty) +{ + prt::TPropertyEffect Data; + if (!prt::PropertyEffectStringToData(pProperty, &Data)) + return; + + pObjectInstance->dwType = prt::PROPERTY_TYPE_EFFECT; + pObjectInstance->dwEffectID = GetCaseCRC32(Data.strFileName.c_str(),Data.strFileName.size()); + CEffectManager & rem = CEffectManager::Instance(); + CEffectData * pData; + if (!rem.GetEffectData(pObjectInstance->dwEffectID,&pData)) + { + if (!rem.RegisterEffect(Data.strFileName.c_str())) + { + pObjectInstance->dwEffectID = 0xffffffff; + TraceError("CArea::SetEffect effect register error %s\n",Data.strFileName.c_str()); + return; + } + } + + CEffectInstance * pEffectInstance; + rem.CreateUnsafeEffectInstance(pObjectInstance->dwEffectID, &pEffectInstance); + + D3DXMATRIX mat; + D3DXMatrixRotationYawPitchRoll(&mat, + D3DXToRadian(c_pData->m_fYaw), + D3DXToRadian(c_pData->m_fPitch), + D3DXToRadian(c_pData->m_fRoll) + ); + + mat._41 = c_pData->Position.x; + mat._42 = c_pData->Position.y; + mat._43 = c_pData->Position.z + c_pData->m_fHeightBias; + + pEffectInstance->SetGlobalMatrix(mat); + + pObjectInstance->dwEffectInstanceIndex = m_EffectInstanceMap.size(); + m_EffectInstanceMap.insert(TEffectInstanceMap::value_type(pObjectInstance->dwEffectInstanceIndex, pEffectInstance)); +} + +void CArea::__SetObjectInstance_SetTree(TObjectInstance * pObjectInstance, const TObjectData * c_pData, CProperty * pProperty) +{ + const char * c_szTreeName; + if (!pProperty->GetString("TreeFile", &c_szTreeName)) + return; + + pObjectInstance->SetTree( + c_pData->Position.x, + c_pData->Position.y, + c_pData->Position.z + c_pData->m_fHeightBias, + c_pData->dwCRC, + c_szTreeName + ); +} + +void CArea::TObjectInstance::SetTree(float x, float y, float z, DWORD dwTreeCRC, const char* c_szTreeName) +{ + CSpeedTreeForestDirectX8& rkForest=CSpeedTreeForestDirectX8::Instance(); + pTree=rkForest.CreateInstance(x, y, z, dwTreeCRC, c_szTreeName); + dwType = prt::PROPERTY_TYPE_TREE; +} + +void CArea::__SetObjectInstance_SetBuilding(TObjectInstance * pObjectInstance, const TObjectData * c_pData, CProperty * pProperty) +{ + prt::TPropertyBuilding Data; + if (!prt::PropertyBuildingStringToData(pProperty, &Data)) + return; + + CResourceManager& rkResMgr=CResourceManager::Instance(); + + CGraphicThing * pThing = (CGraphicThing *)rkResMgr.GetResourcePointer(Data.strFileName.c_str()); + pThing->AddReference(); + + if (pThing->IsEmpty()) + { +#ifdef _DEBUG + TraceError("CArea::SetBuilding: There is no data: %s", Data.strFileName.c_str()); +#endif + return; + } + + int iModelCount = pThing->GetModelCount(); + int iMotionCount = pThing->GetMotionCount(); + + pObjectInstance->dwType = prt::PROPERTY_TYPE_BUILDING; + pObjectInstance->pThingInstance = CGraphicThingInstance::New(); + pObjectInstance->pThingInstance->Initialize(); + pObjectInstance->pThingInstance->ReserveModelThing(iModelCount); + pObjectInstance->pThingInstance->ReserveModelInstance(iModelCount); + pObjectInstance->pThingInstance->RegisterModelThing(0, pThing); + for (int j = 0; j < PORTAL_ID_MAX_NUM; ++j) + if (0 != c_pData->abyPortalID[j]) + pObjectInstance->pThingInstance->SetPortal(j, c_pData->abyPortalID[j]); + + { + std::string stSrcModelFileName=Data.strFileName; + std::string stLODModelFileName; + + char szLODModelFileNameEnd[256]; + for (UINT uLODIndex=1; uLODIndex<=3; ++uLODIndex) + { + sprintf(szLODModelFileNameEnd, "_lod_%.2d.gr2", uLODIndex); + stLODModelFileName = CFileNameHelper::NoExtension(stSrcModelFileName) + szLODModelFileNameEnd; + if (!rkResMgr.IsFileExist(stLODModelFileName.c_str())) + break; + + CGraphicThing* pLODModelThing = (CGraphicThing *)rkResMgr.GetResourcePointer(stLODModelFileName.c_str()); + if (!pLODModelThing) + break; + + pObjectInstance->pThingInstance->RegisterLODThing(0, pLODModelThing); + } + } + + for (int i = 0; i < iModelCount; ++i) + pObjectInstance->pThingInstance->SetModelInstance(i, 0, i); + + if (iMotionCount) + { + pObjectInstance->pThingInstance->RegisterMotionThing(0, pThing); + } + + pObjectInstance->pThingInstance->SetPosition(c_pData->Position.x, c_pData->Position.y, c_pData->Position.z + c_pData->m_fHeightBias); + pObjectInstance->pThingInstance->SetRotation( + c_pData->m_fYaw, + c_pData->m_fPitch, + c_pData->m_fRoll + ); + pObjectInstance->isShadowFlag = Data.isShadowFlag; + pObjectInstance->pThingInstance->RegisterBoundingSphere(); + __LoadAttribute(pObjectInstance, Data.strAttributeDataFileName.c_str()); + pThing->Release(); +} + +void CArea::__SetObjectInstance_SetAmbience(TObjectInstance * pObjectInstance, const TObjectData * c_pData, CProperty * pProperty) +{ + pObjectInstance->pAmbienceInstance = ms_AmbienceInstancePool.Alloc(); + if (!prt::PropertyAmbienceStringToData(pProperty, &pObjectInstance->pAmbienceInstance->AmbienceData)) + return; + + pObjectInstance->dwType = prt::PROPERTY_TYPE_AMBIENCE; + + TAmbienceInstance * pAmbienceInstance = pObjectInstance->pAmbienceInstance; + pAmbienceInstance->fx = c_pData->Position.x; + pAmbienceInstance->fy = c_pData->Position.y; + pAmbienceInstance->fz = c_pData->Position.z + c_pData->m_fHeightBias; + pAmbienceInstance->dwRange = c_pData->dwRange; + pAmbienceInstance->fMaxVolumeAreaPercentage = c_pData->fMaxVolumeAreaPercentage; + + if (0 == pAmbienceInstance->AmbienceData.strPlayType.compare("ONCE")) + { + pAmbienceInstance->Update = &TAmbienceInstance::UpdateOnceSound; + } + else if (0 == pAmbienceInstance->AmbienceData.strPlayType.compare("STEP")) + { + pAmbienceInstance->Update = &TAmbienceInstance::UpdateStepSound; + } + else if (0 == pAmbienceInstance->AmbienceData.strPlayType.compare("LOOP")) + { + pAmbienceInstance->Update = &TAmbienceInstance::UpdateLoopSound; + } +} + +void CArea::__SetObjectInstance_SetDungeonBlock(TObjectInstance * pObjectInstance, const TObjectData * c_pData, CProperty * pProperty) +{ + prt::TPropertyDungeonBlock Data; + if (!prt::PropertyDungeonBlockStringToData(pProperty, &Data)) + return; + + pObjectInstance->dwType = prt::PROPERTY_TYPE_DUNGEON_BLOCK; + pObjectInstance->pDungeonBlock = ms_DungeonBlockInstancePool.Alloc(); + pObjectInstance->pDungeonBlock->Load(Data.strFileName.c_str()); + pObjectInstance->pDungeonBlock->SetPosition(c_pData->Position.x, c_pData->Position.y, c_pData->Position.z + c_pData->m_fHeightBias); + pObjectInstance->pDungeonBlock->SetRotation( + c_pData->m_fYaw, + c_pData->m_fPitch, + c_pData->m_fRoll + ); + pObjectInstance->pDungeonBlock->Update(); + pObjectInstance->pDungeonBlock->BuildBoundingSphere(); + pObjectInstance->pDungeonBlock->RegisterBoundingSphere(); + for (int j = 0; j < PORTAL_ID_MAX_NUM; ++j) + if (0 != c_pData->abyPortalID[j]) + pObjectInstance->pDungeonBlock->SetPortal(j, c_pData->abyPortalID[j]); + __LoadAttribute(pObjectInstance, Data.strAttributeDataFileName.c_str()); +} + + +void CArea::__LoadAttribute(TObjectInstance * pObjectInstance, const char * c_szAttributeFileName) +{ + // OBB 浹 ڵ . + const bool bFileExist = CResourceManager::Instance().IsFileExist(c_szAttributeFileName); + + CAttributeData * pAttributeData = (CAttributeData *) CResourceManager::Instance().GetResourcePointer(c_szAttributeFileName); + + CAttributeInstance * pAttrInstance = ms_AttributeInstancePool.Alloc(); + pAttrInstance->Clear(); + pAttrInstance->SetObjectPointer(pAttributeData); + + if (false == bFileExist) + { + std::string attrFileName(c_szAttributeFileName); + std::transform(attrFileName.begin(), attrFileName.end(), attrFileName.begin(), [](unsigned char c) { return std::tolower(c); }); + const bool bIsDungeonObject = (std::string::npos != attrFileName.find("/dungeon/")) || (std::string::npos != attrFileName.find("\\dungeon\\")); + + // NOTE: dungeon Ʈ Dummy Collision ڵ ʵ ( ø 찡 ־. ̷ ϱ ׷ Ϸ) + if (pAttributeData->IsEmpty() && false == bIsDungeonObject) + { + if (NULL != pObjectInstance && NULL != pObjectInstance->pThingInstance) + { + CGraphicThingInstance* object = pObjectInstance->pThingInstance; + + D3DXVECTOR3 v3Min, v3Max; + + object->GetBoundingAABB(v3Min, v3Max); + + CStaticCollisionData collision; + collision.dwType = COLLISION_TYPE_OBB; + D3DXQuaternionRotationYawPitchRoll(&collision.quatRotation, object->GetYaw(), object->GetPitch(), object->GetRoll()); + strcpy(collision.szName, "DummyCollisionOBB"); + collision.v3Position = (v3Min + v3Max) * 0.5f; + + D3DXVECTOR3 vDelta = (v3Max - v3Min); + collision.fDimensions[0] = vDelta.x * 0.5f; + collision.fDimensions[1] = vDelta.y * 0.5f; + collision.fDimensions[2] = vDelta.z * 0.5f; + + pAttributeData->AddCollisionData(collision); + } + } + } + + if (!pAttributeData->IsEmpty()) + { + pObjectInstance->pAttributeInstance = pAttrInstance; + } + else + { + pAttrInstance->Clear(); + ms_AttributeInstancePool.Free(pAttrInstance); + } +} + + +/* +void CArea::__LoadAttribute(TObjectInstance * pObjectInstance, const char * c_szAttributeFileName) +{ + // AABB 浹 ڵ . + const bool bFileExist = CResourceManager::Instance().IsFileExist(c_szAttributeFileName); + + CAttributeData * pAttributeData = (CAttributeData *) CResourceManager::Instance().GetResourcePointer(c_szAttributeFileName); + + CAttributeInstance * pAttrInstance = ms_AttributeInstancePool.Alloc(); + pAttrInstance->Clear(); + pAttrInstance->SetObjectPointer(pAttributeData); + + if (false == bFileExist) + { + if (pAttributeData->IsEmpty()) + { + if (NULL != pObjectInstance && NULL != pObjectInstance->pThingInstance) + { + CGraphicThingInstance* object = pObjectInstance->pThingInstance; + + D3DXVECTOR3 v3Min, v3Max; + + object->GetBoundingAABB(v3Min, v3Max); + + CStaticCollisionData collision; + collision.dwType = COLLISION_TYPE_AABB; + collision.quatRotation = D3DXQUATERNION(0.0f, 0.0f, 0.0f, 1.0f); + strcpy(collision.szName, "DummyCollisionAABB"); + collision.v3Position = (v3Min + v3Max) * 0.5f; + + D3DXVECTOR3 vDelta = (v3Max - v3Min); + collision.fDimensions[0] = vDelta.x * 0.5f; // v3Min, v3Max ϱ , , ݰ + collision.fDimensions[1] = vDelta.y * 0.5f; + collision.fDimensions[2] = vDelta.z * 0.5f; + + + pAttributeData->AddCollisionData(collision); + } + } + } + + if (!pAttributeData->IsEmpty()) + { + pObjectInstance->pAttributeInstance = pAttrInstance; + } + else + { + pAttrInstance->Clear(); + ms_AttributeInstancePool.Free(pAttrInstance); + } +} +*/ +/* +void CArea::__LoadAttribute(TObjectInstance * pObjectInstance, const char * c_szAttributeFileName) +{ + // Sphere 浹 ڵ . + const bool bFileExist = CResourceManager::Instance().IsFileExist(c_szAttributeFileName); + + CAttributeData * pAttributeData = (CAttributeData *) CResourceManager::Instance().GetResourcePointer(c_szAttributeFileName); + + CAttributeInstance * pAttrInstance = ms_AttributeInstancePool.Alloc(); + pAttrInstance->Clear(); + pAttrInstance->SetObjectPointer(pAttributeData); + + if (false == bFileExist) + { + if (pAttributeData->IsEmpty()) + { + if (NULL != pObjectInstance && NULL != pObjectInstance->pThingInstance) + { + CGraphicThingInstance* object = pObjectInstance->pThingInstance; + + D3DXVECTOR3 v3Center; + float fRadius = 0.0f; + + object->GetBoundingSphere(v3Center, fRadius); + + CStaticCollisionData collision; + collision.dwType = COLLISION_TYPE_SPHERE; + collision.quatRotation = D3DXQUATERNION(0.0f, 0.0f, 0.0f, 1.0f); + strcpy(collision.szName, "DummyCollisionSphere"); + collision.fDimensions[0] = fRadius * 0.25; + collision.v3Position = v3Center; + + pAttributeData->AddCollisionData(collision); + } + } + } + + if (!pAttributeData->IsEmpty()) + { + pObjectInstance->pAttributeInstance = pAttrInstance; + } + else + { + pAttrInstance->Clear(); + ms_AttributeInstancePool.Free(pAttrInstance); + } +} + +*/ + +bool CArea::Load(const char * c_szPathName) +{ + Clear(); + + std::string strObjectDataFileName = c_szPathName + std::string("AreaData.txt"); + std::string strAmbienceDataFileName = c_szPathName + std::string("AreaAmbienceData.txt"); + + __Load_LoadObject(strObjectDataFileName.c_str()); + __Load_LoadAmbience(strAmbienceDataFileName.c_str()); + __Load_BuildObjectInstances(); + + return true; +} + +bool CArea::__Load_LoadObject(const char * c_szFileName) +{ + CTokenVectorMap stTokenVectorMap; + + if (!LoadMultipleTextData(c_szFileName, stTokenVectorMap)) + { + TraceError(" CArea::Load File Load %s ERROR", c_szFileName); + return false; + } + + if (stTokenVectorMap.end() == stTokenVectorMap.find("areadatafile")) + { + TraceError(" CArea::__LoadObject File Format %s ERROR 1", c_szFileName); + return false; + } + + if (stTokenVectorMap.end() == stTokenVectorMap.find("objectcount")) + { + TraceError(" CArea::__LoadObject File Format %s ERROR 2", c_szFileName); + return false; + } + + const std::string & c_rstrCount = stTokenVectorMap["objectcount"][0]; + + DWORD dwCount = atoi(c_rstrCount.c_str()); + + char szObjectName[32+1]; + + for (DWORD i = 0; i < dwCount; ++i) + { + _snprintf(szObjectName, sizeof(szObjectName), "object%03d", i); + + if (stTokenVectorMap.end() == stTokenVectorMap.find(szObjectName)) + continue; + + const CTokenVector & rVector = stTokenVectorMap[szObjectName]; + + const std::string & c_rstrxPosition = rVector[0].c_str(); + const std::string & c_rstryPosition = rVector[1].c_str(); + const std::string & c_rstrzPosition = rVector[2].c_str(); + const std::string & c_rstrCRC = rVector[3].c_str(); + + TObjectData ObjectData; + ZeroMemory(&ObjectData, sizeof(ObjectData)); + ObjectData.Position.x = atof(c_rstrxPosition.c_str()); + ObjectData.Position.y = atof(c_rstryPosition.c_str()); + ObjectData.Position.z = atof(c_rstrzPosition.c_str()); + ObjectData.dwCRC = atoi (c_rstrCRC.c_str()); + + // 20041217.myevan.̼ + ObjectData.InitializeRotation(); //ObjectData.m_fYaw = ObjectData.m_fPitch = ObjectData.m_fRoll = 0; + if (rVector.size() > 4) + { + std::string::size_type s=rVector[4].find('#'); + if (s!=rVector[4].npos) + { + ObjectData.m_fYaw = atoi(rVector[4].substr(0,s-1).c_str()); + int p = s+1; + s = rVector[4].find('#',p); + ObjectData.m_fPitch = atoi(rVector[4].substr(p,s-1-p+1).c_str()); + ObjectData.m_fRoll = atoi(rVector[4].substr(s+1).c_str()); + } + else + { + ObjectData.m_fYaw = 0.0f; + ObjectData.m_fPitch = 0.0f; + ObjectData.m_fRoll = atoi(rVector[4].c_str()); + } + } + + ObjectData.m_fHeightBias = 0.0f; + if (rVector.size() > 5) + { + ObjectData.m_fHeightBias = atof(rVector[5].c_str()); + } + + if (rVector.size() > 6) + { + for (int portalIdx = 0; portalIdx < min(rVector.size()-6, PORTAL_ID_MAX_NUM); ++portalIdx) + { + ObjectData.abyPortalID[portalIdx] = atoi(rVector[6+portalIdx].c_str()); + } + } + + // If data is not inside property, then delete it. + CProperty * pProperty; + if (!CPropertyManager::Instance().Get(ObjectData.dwCRC, &pProperty)) + { + TraceError(" CArea::LoadObject Property(%u) Load ERROR", ObjectData.dwCRC); + continue; + } + + m_ObjectDataVector.push_back(ObjectData); + } + + return true; +} + +bool CArea::__Load_LoadAmbience(const char * c_szFileName) +{ + CTokenVectorMap stTokenVectorMap; + + if (!LoadMultipleTextData(c_szFileName, stTokenVectorMap)) + { + TraceError(" CArea::Load File Load %s ERROR", c_szFileName); + return false; + } + + if (stTokenVectorMap.end() == stTokenVectorMap.find("areaambiencedatafile")) + { + TraceError(" CArea::__LoadAmbience File Format %s ERROR 1", c_szFileName); + return false; + } + + if (stTokenVectorMap.end() == stTokenVectorMap.find("objectcount")) + { + TraceError(" CArea::__LoadAmbience File Format %s ERROR 2", c_szFileName); + return false; + } + + const std::string & c_rstrCount = stTokenVectorMap["objectcount"][0]; + + DWORD dwCount = atoi(c_rstrCount.c_str()); + + char szObjectName[32+1]; + + for (DWORD i = 0; i < dwCount; ++i) + { + _snprintf(szObjectName, sizeof(szObjectName), "object%03d", i); + + if (stTokenVectorMap.end() == stTokenVectorMap.find(szObjectName)) + continue; + + const CTokenVector & rVector = stTokenVectorMap[szObjectName]; + + const std::string & c_rstrxPosition = rVector[0].c_str(); + const std::string & c_rstryPosition = rVector[1].c_str(); + const std::string & c_rstrzPosition = rVector[2].c_str(); + const std::string & c_rstrCRC = rVector[3].c_str(); + const std::string & c_rstrRange = rVector[4].c_str(); + + TObjectData ObjectData; + ZeroMemory(&ObjectData, sizeof(ObjectData)); + ObjectData.Position.x = atof(c_rstrxPosition.c_str()); + ObjectData.Position.y = atof(c_rstryPosition.c_str()); + ObjectData.Position.z = atof(c_rstrzPosition.c_str()); + ObjectData.dwCRC = atoi (c_rstrCRC.c_str()); + ObjectData.dwRange = atoi(c_rstrRange.c_str()); + + // 20041217.myevan.̼ ʱȭ + ObjectData.InitializeRotation(); + ObjectData.m_fHeightBias = 0.0f; + ObjectData.fMaxVolumeAreaPercentage = 0.0f; + + if (rVector.size() >= 6) + { + const std::string & c_rstrPercentage = rVector[5].c_str(); + ObjectData.fMaxVolumeAreaPercentage = atof(c_rstrPercentage.c_str()); + } + + // If data is not inside property, then delete it. + CProperty * pProperty; + if (!CPropertyManager::Instance().Get(ObjectData.dwCRC, &pProperty)) + { + TraceError(" CArea::LoadAmbience Property(%d) Load ERROR", ObjectData.dwCRC); + continue; + } + + m_ObjectDataVector.push_back(ObjectData); + } + + return true; +} + +////////////////////////////////////////////////////////////////////////// + +bool CArea::CheckObjectIndex(DWORD dwIndex) const +{ + if (dwIndex >= m_ObjectDataVector.size()) + return false; + + return true; +} + +DWORD CArea::GetObjectDataCount() +{ + return m_ObjectDataVector.size(); +} + +bool CArea::GetObjectDataPointer(DWORD dwIndex, const TObjectData ** ppObjectData) const +{ + if (!CheckObjectIndex(dwIndex)) + { + assert(!"Setting Object Index is corrupted!"); + return false; + } + + *ppObjectData = &m_ObjectDataVector[dwIndex]; + return true; +} + +const DWORD CArea::GetObjectInstanceCount() const +{ + return m_ObjectInstanceVector.size(); +} + +const bool CArea::GetObjectInstancePointer(const DWORD & dwIndex, const TObjectInstance ** ppObjectInstance) const +{ + if (dwIndex >= m_ObjectInstanceVector.size()) + return false; + + *ppObjectInstance = m_ObjectInstanceVector[dwIndex]; + return true; +} + +void CArea::EnablePortal(BOOL bFlag) +{ + if (m_bPortalEnable == bFlag) + return; + + m_bPortalEnable = bFlag; +} + +void CArea::ClearPortal() +{ + m_kSet_ShowingPortalID.clear(); +} + +void CArea::AddShowingPortalID(int iNum) +{ + m_kSet_ShowingPortalID.insert(iNum); +} + +void CArea::RefreshPortal() +{ + std::set kSet_ShowingObjectInstance; + kSet_ShowingObjectInstance.clear(); + for (DWORD i = 0; i < m_ObjectDataVector.size(); ++i) + { + TObjectData & rData = m_ObjectDataVector[i]; + TObjectInstance * pInstance = m_ObjectInstanceVector[i]; + + for (int j = 0; j < PORTAL_ID_MAX_NUM; ++j) + { + BYTE byPortalID = rData.abyPortalID[j]; + if (0 == byPortalID) + break; + + if (m_kSet_ShowingPortalID.end() == m_kSet_ShowingPortalID.find(byPortalID)) + continue; + + kSet_ShowingObjectInstance.insert(pInstance); + break; + } + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + + m_TreeCloneInstaceVector.clear(); + m_ThingCloneInstaceVector.clear(); + m_DungeonBlockCloneInstanceVector.clear(); + + TObjectInstanceVector::iterator it; + for(it = m_ObjectInstanceVector.begin(); it != m_ObjectInstanceVector.end(); ++it) + { + TObjectInstance * pObjectInstance = *it; + + if (m_bPortalEnable) + { + if (kSet_ShowingObjectInstance.end() == kSet_ShowingObjectInstance.find(pObjectInstance)) + continue; + } + + if (prt::PROPERTY_TYPE_TREE == pObjectInstance->dwType) + { + assert(pObjectInstance->pTree); + m_TreeCloneInstaceVector.push_back(pObjectInstance->pTree); + } + else if (prt::PROPERTY_TYPE_BUILDING == pObjectInstance->dwType) + { + assert(pObjectInstance->pThingInstance); + m_ThingCloneInstaceVector.push_back(pObjectInstance->pThingInstance); + } + else if (prt::PROPERTY_TYPE_DUNGEON_BLOCK == pObjectInstance->dwType) + { + assert(pObjectInstance->pDungeonBlock); + m_DungeonBlockCloneInstanceVector.push_back(pObjectInstance->pDungeonBlock); + } + } +} + +////////////////////////////////////////////////////////////////////////// + +void CArea::Clear() +{ + // Real Instances + TObjectInstanceVector::iterator it; + for (it = m_ObjectInstanceVector.begin();it!=m_ObjectInstanceVector.end();++it) + __Clear_DestroyObjectInstance(*it); + + m_ObjectDataVector.clear(); + m_ObjectInstanceVector.clear(); + + // Clones + m_TreeCloneInstaceVector.clear(); + m_ThingCloneInstaceVector.clear(); + m_DungeonBlockCloneInstanceVector.clear(); + m_AniThingCloneInstanceVector.clear(); + m_ShadowThingCloneInstaceVector.clear(); + m_AmbienceCloneInstanceVector.clear(); + m_GraphicThingInstanceCRCMap.clear(); + m_kRenderedThingInstanceCRCWithNumberVector.clear(); + m_kRenderedGrapphicThingInstanceVector.clear(); + + m_bPortalEnable = FALSE; + ClearPortal(); + + CEffectManager& rkEftMgr=CEffectManager::Instance(); + + TEffectInstanceIterator i; + for (i = m_EffectInstanceMap.begin(); i != m_EffectInstanceMap.end(); ++i) + { + CEffectInstance * pEffectInstance = i->second; + rkEftMgr.DestroyUnsafeEffectInstance(pEffectInstance); + } + m_EffectInstanceMap.clear(); +} + +void CArea::__Clear_DestroyObjectInstance(TObjectInstance * pObjectInstance) +{ + if (pObjectInstance->dwEffectInstanceIndex!=0xffffffff) + { + TEffectInstanceIterator f= m_EffectInstanceMap.find(pObjectInstance->dwEffectInstanceIndex); + if (m_EffectInstanceMap.end()!=f) + { + CEffectInstance * pEffectInstance = f->second; + m_EffectInstanceMap.erase(f); + + if (CEffectManager::InstancePtr()) + CEffectManager::Instance().DestroyUnsafeEffectInstance(pEffectInstance); + } + pObjectInstance->dwEffectInstanceIndex = 0xffffffff; + } + + if (pObjectInstance->pAttributeInstance) + { + pObjectInstance->pAttributeInstance->Clear(); + ms_AttributeInstancePool.Free(pObjectInstance->pAttributeInstance); + pObjectInstance->pAttributeInstance = NULL; + } + + if (pObjectInstance->pTree) + { + pObjectInstance->pTree->Clear(); + CSpeedTreeForestDirectX8::Instance().DeleteInstance(pObjectInstance->pTree); + pObjectInstance->pTree = NULL; + } + + if (pObjectInstance->pThingInstance) + { + CGraphicThingInstance::Delete(pObjectInstance->pThingInstance); + pObjectInstance->pThingInstance = NULL; + } + + if (pObjectInstance->pAmbienceInstance) + { + ms_AmbienceInstancePool.Free(pObjectInstance->pAmbienceInstance); + pObjectInstance->pAmbienceInstance = NULL; + } + + if (pObjectInstance->pDungeonBlock) + { + ms_DungeonBlockInstancePool.Free(pObjectInstance->pDungeonBlock); + pObjectInstance->pDungeonBlock = NULL; + } + + pObjectInstance->Clear(); + + ms_ObjectInstancePool.Free(pObjectInstance); +} + + +////////////////////////////////////////////////////////////////////////// +// Coordination +void CArea::GetCoordinate(unsigned short * usCoordX, unsigned short * usCoordY) +{ + *usCoordX = m_wX; + *usCoordY = m_wY; +} + +void CArea::SetCoordinate(const unsigned short & usCoordX, const unsigned short & usCoordY) +{ + m_wX = usCoordX; + m_wY = usCoordY; +} + +////////////////////////////////////////////////////////////////////////// + +void CArea::SetMapOutDoor(CMapOutdoor * pOwnerOutdoorMap) +{ + m_pOwnerOutdoorMap=pOwnerOutdoorMap; +} + +CArea::CArea() +{ + m_wX = m_wY = 0xFF; +} + +CArea::~CArea() +{ + Clear(); +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +void CArea::TAmbienceInstance::__Update(float fxCenter, float fyCenter, float fzCenter) +{ + if (0 == dwRange) + return; + + (this->*Update)(fxCenter, fyCenter, fzCenter); +} + +void CArea::TAmbienceInstance::UpdateOnceSound(float fxCenter, float fyCenter, float fzCenter) +{ + float fDistance = sqrtf((fx - fxCenter)*(fx - fxCenter) + (fy - fyCenter)*(fy - fyCenter) + (fz - fzCenter)*(fz - fzCenter)); + if (DWORD(fDistance) < dwRange) + { + if (-1 == iPlaySoundIndex) + { + if (AmbienceData.AmbienceSoundVector.empty()) + return; + + const char * c_szFileName = AmbienceData.AmbienceSoundVector[0].c_str(); + iPlaySoundIndex = CSoundManager::Instance().PlayAmbienceSound3D(fx, fy, fz, c_szFileName); +// Tracef(" %d : OncePlay [%f] : %s\n", iPlaySoundIndex, fDistance, c_szFileName); + } + } + else + { + iPlaySoundIndex = -1; + } +} + +void CArea::TAmbienceInstance::UpdateStepSound(float fxCenter, float fyCenter, float fzCenter) +{ + float fDistance = sqrtf((fx - fxCenter)*(fx - fxCenter) + (fy - fyCenter)*(fy - fyCenter) + (fz - fzCenter)*(fz - fzCenter)); + if (DWORD(fDistance) < dwRange) + { + float fcurTime = CTimer::Instance().GetCurrentSecond(); + + if (fcurTime > fNextPlayTime) + { + if (AmbienceData.AmbienceSoundVector.empty()) + return; + + const char * c_szFileName = AmbienceData.AmbienceSoundVector[0].c_str(); + iPlaySoundIndex = CSoundManager::Instance().PlayAmbienceSound3D(fx, fy, fz, c_szFileName); +// Tracef(" %d : StepPlay [%f] : %s\n", iPlaySoundIndex, fDistance, c_szFileName); + + fNextPlayTime = CTimer::Instance().GetCurrentSecond(); + fNextPlayTime += AmbienceData.fPlayInterval + frandom(0.0f, AmbienceData.fPlayIntervalVariation); + } + } + else + { + iPlaySoundIndex = -1; + fNextPlayTime = 0.0f; + } +} + +void CArea::TAmbienceInstance::UpdateLoopSound(float fxCenter, float fyCenter, float fzCenter) +{ + float fDistance = sqrtf((fx - fxCenter)*(fx - fxCenter) + (fy - fyCenter)*(fy - fyCenter) + (fz - fzCenter)*(fz - fzCenter)); + if (DWORD(fDistance) < dwRange) + { + if (-1 == iPlaySoundIndex) + { + if (AmbienceData.AmbienceSoundVector.empty()) + return; + + const char * c_szFileName = AmbienceData.AmbienceSoundVector[0].c_str(); + iPlaySoundIndex = CSoundManager::Instance().PlayAmbienceSound3D(fx, fy, fz, c_szFileName, 0); +// Tracef(" %d : LoopPlay [%f] : %s\n", iPlaySoundIndex, fDistance, c_szFileName); + } + + if (-1 != iPlaySoundIndex) + { +// Tracef("%d : %f\n", iPlaySoundIndex, __GetVolumeFromDistance(fDistance)); + CSoundManager::Instance().SetSoundVolume3D(iPlaySoundIndex, __GetVolumeFromDistance(fDistance)); + } + } + else + { + if (-1 != iPlaySoundIndex) + { +// Tracef(" %d : LoopStop\n", iPlaySoundIndex); + CSoundManager::Instance().StopSound3D(iPlaySoundIndex); + iPlaySoundIndex = -1; + } + } +} + +float CArea::TAmbienceInstance::__GetVolumeFromDistance(float fDistance) +{ + float fMaxVolumeAreaRadius = float(dwRange) * fMaxVolumeAreaPercentage; + if (fMaxVolumeAreaRadius <= 0.0f) + return 1.0f; + if (fDistance <= fMaxVolumeAreaRadius) + return 1.0f; + + return 1.0f - ((fDistance - fMaxVolumeAreaRadius) / (dwRange - fMaxVolumeAreaRadius)); +} + +void CArea::TAmbienceInstance::Render() +{ + float fBoxSize = 10.0f; + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xff00ff00); + RenderCube(fx-fBoxSize, fy-fBoxSize, fz-fBoxSize, fx+fBoxSize, fy+fBoxSize, fz+fBoxSize); + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xffffffff); + RenderSphere(NULL, fx, fy, fz, float(dwRange) * fMaxVolumeAreaPercentage, D3DFILL_POINT); + RenderSphere(NULL, fx, fy, fz, float(dwRange), D3DFILL_POINT); + RenderCircle2d(fx, fy, fz, float(dwRange) * fMaxVolumeAreaPercentage); + RenderCircle2d(fx, fy, fz, float(dwRange)); + + for (int i = 0; i < 4; ++i) + { + float fxAdd = cosf(float(i) * D3DX_PI/4.0f) * float(dwRange) / 2.0f; + float fyAdd = sinf(float(i) * D3DX_PI/4.0f) * float(dwRange) / 2.0f; + + if (i%2) + { + fxAdd /= 2.0f; + fyAdd /= 2.0f; + } + + RenderLine2d(fx + fxAdd, fy + fyAdd, fx - fxAdd, fy - fyAdd, fz); + } +} + +bool CArea::SAmbienceInstance::Picking() +{ + return CGraphicCollisionObject::IntersectSphere(D3DXVECTOR3(fx, fy, fz), dwRange); +} + +CArea::SAmbienceInstance::SAmbienceInstance() +{ + fx = 0.0f; + fy = 0.0f; + fz = 0.0f; + dwRange = 0; + iPlaySoundIndex = -1; + fNextPlayTime = 0.0f; +} diff --git a/source/GameLib/Area.h b/source/GameLib/Area.h new file mode 100644 index 0000000..1fae3c7 --- /dev/null +++ b/source/GameLib/Area.h @@ -0,0 +1,310 @@ +#pragma once + +#include "../SpeedTreeLib/SpeedTreeWrapper.h" +#include "../eterGrnLib/ThingInstance.h" +#include "MapType.h" +#include "DungeonBlock.h" + +class CMapOutdoor; +class CEffectInstance; + +class CArea +{ + public: + enum + { + ROTATION_STEP_COUNT = 24, + ROTATION_STEP_AMOUNT = 360 / ROTATION_STEP_COUNT, + YAW_STEP_COUNT = 24, + YAW_STEP_AMOUNT = 360 / YAW_STEP_COUNT, + PITCH_STEP_COUNT = YAW_STEP_COUNT, + PITCH_STEP_AMOUNT = YAW_STEP_AMOUNT, + }; + + typedef D3DXVECTOR3 TObjectPosition; + + /////////////////////////////////////////////////////////////////////////////////// + // Object Static Data + typedef struct SObjectData + { + TObjectPosition Position; + DWORD dwCRC; + BYTE abyPortalID[PORTAL_ID_MAX_NUM]; + + // For Tree + // - Nothing + + // For Granny Thing + float m_fYaw; + float m_fPitch; + float m_fRoll; + float m_fHeightBias; + + // For Effect + // - Nothing + + // For Ambience + DWORD dwRange; + float fMaxVolumeAreaPercentage; + + void InitializeRotation(); + } TObjectData; + + struct ObjectDataComp + { + bool operator () (TObjectData & lhs, TObjectData & rhs) const + { + return lhs.dwCRC < rhs.dwCRC; + } + }; + + typedef std::vector TObjectDataVector; + typedef TObjectDataVector::iterator TObjectDataIterator; + + /////////////////////////////////////////////////////////////////////////////////// + // Object Dynamic Data + typedef struct SAmbienceInstance : public CScreen + { + float fx, fy, fz; + DWORD dwRange; + float fMaxVolumeAreaPercentage; + int iPlaySoundIndex; + float fNextPlayTime; + prt::TPropertyAmbience AmbienceData; + + SAmbienceInstance(); + virtual ~SAmbienceInstance() {} + void __Update(float fxCenter, float fyCenter, float fzCenter); + void (SAmbienceInstance::*Update)(float fxCenter, float fyCenter, float fzCenter); + void UpdateOnceSound(float fxCenter, float fyCenter, float fzCenter); + void UpdateStepSound(float fxCenter, float fyCenter, float fzCenter); + void UpdateLoopSound(float fxCenter, float fyCenter, float fzCenter); + void Render(); + bool Picking(); + float __GetVolumeFromDistance(float fDistance); + } TAmbienceInstance; + + typedef struct SObjectInstance + { + DWORD dwType; + CAttributeInstance * pAttributeInstance; + + // Data For Tree + CSpeedTreeWrapper * pTree; + + // Data For Normal Object or Building + BOOL isShadowFlag; + CGraphicThingInstance * pThingInstance; + + // Data for Effect + DWORD dwEffectID; + DWORD dwEffectInstanceIndex; + + // Data For Ambience + TAmbienceInstance * pAmbienceInstance; + + // Dungeon + CDungeonBlock * pDungeonBlock; + + void Clear() + { + if (pTree) + pTree->Clear(); + + if (pThingInstance) + pThingInstance->Clear(); + + if (pAttributeInstance) + pAttributeInstance->Clear(); + + if (pAmbienceInstance) + pAmbienceInstance->Clear(); + + if (pDungeonBlock) + pDungeonBlock->Clear(); + + __Initialize(); + } + + void SetTree(float x, float y, float z, DWORD dwTreeCRC, const char* c_szTreeName); + + void __Initialize() + { + dwType = prt::PROPERTY_TYPE_NONE; + + dwEffectID = 0xffffffff; + dwEffectInstanceIndex = 0xffffffff; + isShadowFlag = false; + + pTree=NULL; + pThingInstance=NULL; + pAttributeInstance=NULL; + pAmbienceInstance=NULL; + pDungeonBlock=NULL; + } + + SObjectInstance() + { + __Initialize(); + } + virtual ~SObjectInstance() + { + } + } TObjectInstance; + + typedef std::vector TTreeInstanceVector; + typedef std::vector TThingInstanceVector; + typedef std::vector TDungeonBlockInstanceVector; + typedef std::vector TObjectInstanceVector; + typedef std::vector TAmbienceInstanceVector; + typedef std::map TGraphicThingInstanceCRCMap; // ȭ by + typedef std::set TShowingPortalIDSet; + + typedef struct SCRCWithNumber + { + DWORD dwCRC; + DWORD dwNumber; + } TCRCWithNumber; + + typedef std::vector TCRCWithNumberVector; + + struct FFindIfCRC + { + + FFindIfCRC(DWORD dwCRC) { m_dwCRC = dwCRC; } + + bool operator() (TCRCWithNumber & rCRCWithNumber) + { + if (rCRCWithNumber.dwCRC == m_dwCRC) + return true; + return false; + } + + DWORD m_dwCRC; + }; + + struct CRCNumComp + { + bool operator () (TCRCWithNumber & lhs, TCRCWithNumber & rhs) const + { + return lhs.dwNumber > rhs.dwNumber; + } + }; + + public: + CArea(); + virtual ~CArea(); + + void CollectRenderingObject(std::vector& rkVct_pkOpaqueThingInst); + void CollectBlendRenderingObject(std::vector& rkVct_pkBlendThingInst); + + void SetMapOutDoor(CMapOutdoor * pOwnerOutdoorMap); + void Clear(); + + bool Load(const char * c_szPathName); + + DWORD GetObjectDataCount(); + bool GetObjectDataPointer(DWORD dwIndex, const TObjectData ** ppObjectData) const; + + const DWORD GetObjectInstanceCount() const; + const bool GetObjectInstancePointer(const DWORD & dwIndex, const TObjectInstance ** ppObjectInstance) const; + + void EnablePortal(BOOL bFlag=TRUE); + void ClearPortal(); + void AddShowingPortalID(int iNum); + void RefreshPortal(); + + ////////////////////////////////////////////////////////////////////////// + + void Update(); + void UpdateAroundAmbience(float fX, float fY, float fZ); + + void Render(); + void RenderEffect(); + void RenderCollision(); + void RenderAmbience(); + void RenderDungeon(); + void Refresh(); + + ////////////////////////////////////////////////////////////////////////// + + void SetCoordinate(const WORD & c_usCoordX, const WORD & c_usCoordY); + void GetCoordinate(WORD * usCoordX, WORD * usCoordY); + + ////////////////////////////////////////////////////////////////////////// + + DWORD DEBUG_GetRenderedCRCNum(); + TCRCWithNumberVector & DEBUG_GetRenderedCRCWithNumVector(); + DWORD DEBUG_GetRenderedGrapphicThingInstanceNum(); + + CMapOutdoor * GetOwner() { return m_pOwnerOutdoorMap; } + + protected: + + bool CheckObjectIndex(DWORD dwIndex) const; + + bool __Load_LoadObject(const char * c_szFileName); + bool __Load_LoadAmbience(const char * c_szFileName); + void __Load_BuildObjectInstances(); + + void __UpdateAniThingList(); + void __UpdateEffectList(); + + void __LoadAttribute(TObjectInstance * pObjectInstance, const char * c_szAttributeFileName); + + protected: + void __Clear_DestroyObjectInstance(TObjectInstance * pObjectInstance); + + void __SetObjectInstance(TObjectInstance * pObjectInstance, const TObjectData * c_pData); + void __SetObjectInstance_SetTree(TObjectInstance * pObjectInstance, const TObjectData * c_pData, CProperty * pProperty); + void __SetObjectInstance_SetBuilding(TObjectInstance * pObjectInstance, const TObjectData * c_pData, CProperty * pProperty); + void __SetObjectInstance_SetEffect(TObjectInstance * pObjectInstance, const TObjectData * c_pData, CProperty * pProperty); + void __SetObjectInstance_SetAmbience(TObjectInstance * pObjectInstance, const TObjectData * c_pData, CProperty * pProperty); + void __SetObjectInstance_SetDungeonBlock(TObjectInstance * pObjectInstance, const TObjectData * c_pData, CProperty * pProperty); + + protected: + // Static Data + TObjectDataVector m_ObjectDataVector; // Area ִ Ʈ + + // Rendering Instances + TObjectInstanceVector m_ObjectInstanceVector; + + // Clone Instance Vector + TTreeInstanceVector m_TreeCloneInstaceVector; + TThingInstanceVector m_ThingCloneInstaceVector; + TDungeonBlockInstanceVector m_DungeonBlockCloneInstanceVector; + TThingInstanceVector m_AniThingCloneInstanceVector; + TThingInstanceVector m_ShadowThingCloneInstaceVector; + TAmbienceInstanceVector m_AmbienceCloneInstanceVector; + TGraphicThingInstanceCRCMap m_GraphicThingInstanceCRCMap; + TCRCWithNumberVector m_kRenderedThingInstanceCRCWithNumberVector; + TThingInstanceVector m_kRenderedGrapphicThingInstanceVector; + + // ǥ : ɸ ü ߿ ǥ... Ѵ 0~999 + WORD m_wX; + WORD m_wY; + + // Owner COutdoorMap poineter + CMapOutdoor * m_pOwnerOutdoorMap; + + protected: + static CDynamicPool ms_ObjectInstancePool; + static CDynamicPool ms_AttributeInstancePool; + static CDynamicPool ms_AmbienceInstancePool; + static CDynamicPool ms_DungeonBlockInstancePool; + + typedef std::map TEffectInstanceMap; + typedef TEffectInstanceMap::iterator TEffectInstanceIterator; + TEffectInstanceMap m_EffectInstanceMap; + + BOOL m_bPortalEnable; + TShowingPortalIDSet m_kSet_ShowingPortalID; + + public: + static void DestroySystem(); + + static CArea* New(); + static void Delete(CArea* pkArea); + + static CDynamicPool ms_kPool; +}; diff --git a/source/GameLib/AreaLoaderThread.cpp b/source/GameLib/AreaLoaderThread.cpp new file mode 100644 index 0000000..4b21d82 --- /dev/null +++ b/source/GameLib/AreaLoaderThread.cpp @@ -0,0 +1,340 @@ +// AreaLoaderThread.cpp: implementation of the CAreaLoaderThread class. +// +////////////////////////////////////////////////////////////////////// + +#include "StdAfx.h" + +#include "../eterLib/ResourceManager.h" + +#include "AreaLoaderThread.h" +#include "AreaTerrain.h" +#include "MapOutdoor.h" + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +TEMP_CAreaLoaderThread::TEMP_CAreaLoaderThread() : m_bShutdowned(false), m_pArg(NULL), m_hThread(NULL), m_uThreadID(0) +{ + +} + +TEMP_CAreaLoaderThread::~TEMP_CAreaLoaderThread() +{ + Destroy(); +} + +bool TEMP_CAreaLoaderThread::Create(void * arg) +{ + Arg(arg); + m_hThread = (HANDLE) _beginthreadex(NULL, 0, EntryPoint, this, 0, &m_uThreadID); + + if (!m_hThread) + return false; + + SetThreadPriority(m_hThread, THREAD_PRIORITY_NORMAL); + return true; +} + +UINT TEMP_CAreaLoaderThread::Run(void * arg) +{ + if (!Setup()) + return 0; + + return (Execute(arg)); +} + +/* Static */ +UINT CALLBACK TEMP_CAreaLoaderThread::EntryPoint(void * pThis) +{ + TEMP_CAreaLoaderThread * pThread = (TEMP_CAreaLoaderThread *) pThis; + return pThread->Run(pThread->Arg()); +} + +////////////////////////////////////////////////////////////////////////// +void TEMP_CAreaLoaderThread::Destroy() +{ + if (m_hSemaphore) + { + CloseHandle(m_hSemaphore); + m_hSemaphore = NULL; + } + +/* + while(!m_pTerrainRequestDeque.empty()) + { + CTerrain * pTerrain = m_pTerrainRequestDeque.front(); + delete pTerrain; + pTerrain = NULL; + m_pTerrainRequestDeque.pop_front(); + } + + while(!m_pTerrainCompleteDeque.empty()) + { + CTerrain * pTerrain = m_pTerrainCompleteDeque.front(); + delete pTerrain; + pTerrain = NULL; + m_pTerrainCompleteDeque.pop_front(); + } +*/ + + /*stl_wipe(m_pTerrainRequestDeque); + stl_wipe(m_pTerrainCompleteDeque); + stl_wipe(m_pAreaRequestDeque); + stl_wipe(m_pAreaCompleteDeque);*/ +} + +UINT TEMP_CAreaLoaderThread::Setup() +{ + m_hSemaphore = CreateSemaphore(NULL, // no security attributes + 0, // initial count + 65535, // maximum count + NULL); // unnamed semaphore + if (!m_hSemaphore) + return 0; + + return 1; +} + +void TEMP_CAreaLoaderThread::Shutdown() +{ + if (!m_hSemaphore) + return; + + BOOL bRet; + + m_bShutdowned = true; + + do + { + bRet = ReleaseSemaphore(m_hSemaphore, 1, NULL); + } + while (!bRet); + + WaitForSingleObject(m_hThread, 10000); // 尡 DZ⸦ 10 ٸ +} + +UINT TEMP_CAreaLoaderThread::Execute(void * pvArg) +{ + bool bProcessTerrain = true; + while (!m_bShutdowned) + { + DWORD dwWaitResult; + + dwWaitResult = WaitForSingleObject(m_hSemaphore, INFINITE); + + if (m_bShutdowned) + break; + + switch (dwWaitResult) + { + case WAIT_OBJECT_0: + if (bProcessTerrain) + ProcessTerrain(); + else + ProcessArea(); + break; + case WAIT_TIMEOUT: + TraceError("TEMP_CAreaLoaderThread::Execute: Timeout occured while time-out interval is INIFITE"); + break; + } + } + + Destroy(); + return 1; +} + +void TEMP_CAreaLoaderThread::Request(CTerrain * pTerrain) // called in main thread +{ + m_TerrainRequestMutex.Lock(); + m_pTerrainRequestDeque.push_back(pTerrain); + m_TerrainRequestMutex.Unlock(); + + ++m_iRestSemCount; + + if (!ReleaseSemaphore(m_hSemaphore, m_iRestSemCount, NULL)) + TraceError("TEMP_CAreaLoaderThread::Request: ReleaseSemaphore error"); + + --m_iRestSemCount; +} + +bool TEMP_CAreaLoaderThread::Fetch(CTerrain ** ppTerrain) // called in main thread +{ + m_TerrainCompleteMutex.Lock(); + + if (m_pTerrainCompleteDeque.empty()) + { + m_TerrainCompleteMutex.Unlock(); + return false; + } + + *ppTerrain = m_pTerrainCompleteDeque.front(); + m_pTerrainCompleteDeque.pop_front(); + + m_TerrainCompleteMutex.Unlock(); + return true; +} + +void TEMP_CAreaLoaderThread::Request(CArea * pArea) // called in main thread +{ + m_AreaRequestMutex.Lock(); + m_pAreaRequestDeque.push_back(pArea); + m_AreaRequestMutex.Unlock(); + + ++m_iRestSemCount; + + if (!ReleaseSemaphore(m_hSemaphore, m_iRestSemCount, NULL)) + TraceError("TEMP_CAreaLoaderThread::Request: ReleaseSemaphore error"); + + --m_iRestSemCount; +} + +bool TEMP_CAreaLoaderThread::Fetch(CArea ** ppArea) // called in main thread +{ + m_AreaCompleteMutex.Lock(); + + if (m_pAreaCompleteDeque.empty()) + { + m_AreaCompleteMutex.Unlock(); + return false; + } + + *ppArea = m_pAreaCompleteDeque.front(); + m_pAreaCompleteDeque.pop_front(); + + m_AreaCompleteMutex.Unlock(); + return true; +} + +void TEMP_CAreaLoaderThread::ProcessArea() // called in loader thread +{ + m_AreaRequestMutex.Lock(); + + if (m_pAreaRequestDeque.empty()) + { + m_AreaRequestMutex.Unlock(); + return; + } + + CArea * pArea = m_pAreaRequestDeque.front(); + m_pAreaRequestDeque.pop_front(); + + Tracef("TEMP_CAreaLoaderThread::ProcessArea() RequestDeque Size : %d\n", m_pAreaRequestDeque.size()); + m_AreaRequestMutex.Unlock(); + + DWORD dwStartTime = ELTimer_GetMSec(); + + // Area Load + WORD wAreaCoordX, wAreaCoordY; + pArea->GetCoordinate(&wAreaCoordX, &wAreaCoordY); + DWORD dwID = (DWORD) (wAreaCoordX) * 1000L + (DWORD) (wAreaCoordY); + + const std::string & c_rStrMapName = pArea->GetOwner()->GetName(); + + char szAreaPathName[64+1]; + _snprintf(szAreaPathName, sizeof(szAreaPathName), "%s\\%06u\\", c_rStrMapName.c_str(), dwID); + + pArea->Load(szAreaPathName); + + Tracef("TEMP_CAreaLoaderThread::ProcessArea LoadArea : %d ms elapsed\n", ELTimer_GetMSec() - dwStartTime); + + m_AreaCompleteMutex.Lock(); + m_pAreaCompleteDeque.push_back(pArea); + m_AreaCompleteMutex.Unlock(); + + Sleep(g_iLoadingDelayTime); +} + +void TEMP_CAreaLoaderThread::ProcessTerrain() // called in loader thread +{ + m_TerrainRequestMutex.Lock(); + + if (m_pTerrainRequestDeque.empty()) + { + m_TerrainRequestMutex.Unlock(); + return; + } + + CTerrain * pTerrain = m_pTerrainRequestDeque.front(); + m_pTerrainRequestDeque.pop_front(); + + Tracef("TEMP_CAreaLoaderThread::ProcessTerrain() RequestDeque Size : %d\n", m_pTerrainRequestDeque.size()); + m_TerrainRequestMutex.Unlock(); + + DWORD dwStartTime = ELTimer_GetMSec(); + + // Terrain Load + WORD wCoordX, wCoordY; + pTerrain->GetCoordinate(&wCoordX, &wCoordY); + DWORD dwID = (DWORD) (wCoordX) * 1000L + (DWORD) (wCoordY); + + const std::string & c_rStrMapName = pTerrain->GetOwner()->GetName(); + char filename[256]; + sprintf(filename, "%s\\%06u\\AreaProperty.txt", c_rStrMapName.c_str(), dwID); + + CTokenVectorMap stTokenVectorMap; + + if (!LoadMultipleTextData(filename, stTokenVectorMap)) + return; + + Sleep(g_iLoadingDelayTime); + + if (stTokenVectorMap.end() == stTokenVectorMap.find("scripttype")) + return; + + if (stTokenVectorMap.end() == stTokenVectorMap.find("areaname")) + return; + + const std::string & c_rstrType = stTokenVectorMap["scripttype"][0]; + const std::string & c_rstrAreaName = stTokenVectorMap["areaname"][0]; + + if (c_rstrType != "AreaProperty") + return; + + char szRawHeightFieldname[64+1]; + char szWaterMapName[64+1]; + char szAttrMapName[64+1]; + char szShadowTexName[64+1]; + char szShadowMapName[64+1]; + char szMiniMapTexName[64+1]; + char szSplatName[64+1]; + + _snprintf(szRawHeightFieldname, sizeof(szRawHeightFieldname), "%s\\%06u\\height.raw", c_rStrMapName.c_str(), dwID); + _snprintf(szSplatName, sizeof(szSplatName), "%s\\%06u\\tile.raw", c_rStrMapName.c_str(), dwID); + _snprintf(szAttrMapName, sizeof(szAttrMapName), "%s\\%06u\\attr.atr", c_rStrMapName.c_str(), dwID); + _snprintf(szWaterMapName, sizeof(szWaterMapName), "%s\\%06u\\water.wtr", c_rStrMapName.c_str(), dwID); + _snprintf(szShadowTexName, sizeof(szShadowTexName), "%s\\%06u\\shadowmap.dds", c_rStrMapName.c_str(), dwID); + _snprintf(szShadowMapName, sizeof(szShadowMapName), "%s\\%06u\\shadowmap.raw", c_rStrMapName.c_str(), dwID); + _snprintf(szMiniMapTexName, sizeof(szMiniMapTexName), "%s\\%06u\\minimap.dds", c_rStrMapName.c_str(), dwID); + + pTerrain->CopySettingFromGlobalSetting(); + + pTerrain->LoadWaterMap(szWaterMapName); + Sleep(g_iLoadingDelayTime); + pTerrain->LoadHeightMap(szRawHeightFieldname); + Sleep(g_iLoadingDelayTime); + pTerrain->LoadAttrMap(szAttrMapName); + Sleep(g_iLoadingDelayTime); + pTerrain->RAW_LoadTileMap(szSplatName, true); + Sleep(g_iLoadingDelayTime); + pTerrain->LoadShadowTexture(szShadowTexName); + Sleep(g_iLoadingDelayTime); + pTerrain->LoadShadowMap(szShadowMapName); + Sleep(g_iLoadingDelayTime); + pTerrain->LoadMiniMapTexture(szMiniMapTexName); + Sleep(g_iLoadingDelayTime); + pTerrain->SetName(c_rstrAreaName.c_str()); + Sleep(g_iLoadingDelayTime); + pTerrain->CalculateTerrainPatch(); + Sleep(g_iLoadingDelayTime); + + pTerrain->SetReady(); + + Tracef("TEMP_CAreaLoaderThread::ProcessTerrain LoadTerrain : %d ms elapsed\n", ELTimer_GetMSec() - dwStartTime); + + m_TerrainCompleteMutex.Lock(); + m_pTerrainCompleteDeque.push_back(pTerrain); + m_TerrainCompleteMutex.Unlock(); + + Sleep(g_iLoadingDelayTime); +} diff --git a/source/GameLib/AreaLoaderThread.h b/source/GameLib/AreaLoaderThread.h new file mode 100644 index 0000000..e47e924 --- /dev/null +++ b/source/GameLib/AreaLoaderThread.h @@ -0,0 +1,73 @@ +// AreaLoaderThread.h: interface for the CAreaLoaderThread class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_AREALOADERTHREAD_H__E43FBE42_42F4_4F0E_B9DA_D7B7C5EA0753__INCLUDED_) +#define AFX_AREALOADERTHREAD_H__E43FBE42_42F4_4F0E_B9DA_D7B7C5EA0753__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "../eterLib/Mutex.h" + +class CTerrain; +class CArea; + +class TEMP_CAreaLoaderThread +{ +public: + TEMP_CAreaLoaderThread(); + virtual ~TEMP_CAreaLoaderThread(); + + bool Create(void * arg); + void Shutdown(); + + void Request(CTerrain * pTerrain); + + bool Fetch(CTerrain ** ppTerrian); + + void Request(CArea * pArea); + + bool Fetch(CArea ** ppArea); + +protected: + static UINT CALLBACK EntryPoint(void * pThis); + UINT Run(void * arg); + + void * Arg() const { return m_pArg; } + void Arg(void * arg) { m_pArg = arg; } + + HANDLE m_hThread; + +private: + void * m_pArg; + unsigned m_uThreadID; + +protected: + UINT Setup(); + UINT Execute(void * pvArg); + void Destroy(); + void ProcessTerrain(); + void ProcessArea(); + +private: + std::deque m_pTerrainRequestDeque; + Mutex m_TerrainRequestMutex; + + std::deque m_pTerrainCompleteDeque; + Mutex m_TerrainCompleteMutex; + + std::deque m_pAreaRequestDeque; + Mutex m_AreaRequestMutex; + + std::deque m_pAreaCompleteDeque; + Mutex m_AreaCompleteMutex; + + HANDLE m_hSemaphore; + int m_iRestSemCount; + bool m_bShutdowned; + +}; + +#endif // !defined(AFX_AREALOADERTHREAD_H__E43FBE42_42F4_4F0E_B9DA_D7B7C5EA0753__INCLUDED_) diff --git a/source/GameLib/AreaTerrain.cpp b/source/GameLib/AreaTerrain.cpp new file mode 100644 index 0000000..22f5af1 --- /dev/null +++ b/source/GameLib/AreaTerrain.cpp @@ -0,0 +1,1193 @@ +#include "StdAfx.h" +#include "../PRTerrainLib/StdAfx.h" + +#include "../eterLib/ResourceManager.h" +#include "../eterlib/StateManager.h" +#include "../EterPack/EterPackManager.h" + +#include "AreaTerrain.h" +#include "MapOutdoor.h" + +CDynamicPool CTerrain::ms_kPool; + +void CTerrain::DestroySystem() +{ + ms_kPool.Destroy(); +} + +CTerrain* CTerrain::New() +{ + return ms_kPool.Alloc(); +} + +void CTerrain::Delete(CTerrain* pkTerrain) +{ + pkTerrain->Clear(); + ms_kPool.Free(pkTerrain); +} + +CTerrain::CTerrain() +{ + memset(&m_lpAlphaTexture, 0, sizeof(m_lpAlphaTexture)); + memset(&m_lpMarkedTexture, 0, sizeof(m_lpMarkedTexture)); + Initialize(); +} + +CTerrain::~CTerrain() +{ + DeallocateMarkedSplats(); + RAW_DeallocateSplats(); + Clear(); +} + +void CTerrain::SetMapOutDoor(CMapOutdoor * pOwnerOutdoorMap) +{ + m_pOwnerOutdoorMap=pOwnerOutdoorMap; +} + +void CTerrain::Clear() +{ + DeallocateMarkedSplats(); + CTerrainImpl::Clear(); + Initialize(); +} + +bool CTerrain::Initialize() +{ + SetReady(false); + m_strName = ""; + m_wX = m_wY = 0xFFFF; + m_bReady = false; + m_bMarked = false; + + for (BYTE byY = 0; byY < PATCH_YCOUNT; ++byY) + for (BYTE byX = 0; byX < PATCH_XCOUNT; ++byX) + m_TerrainPatchList[byY * PATCH_XCOUNT + byX].Clear(); + + return true; +} + +void CTerrain::LoadMiniMapTexture(const char * c_pchMiniMapFileName) +{ + DWORD dwStart = ELTimer_GetMSec(); + CGraphicImage * pImage = (CGraphicImage *) CResourceManager::Instance().GetResourcePointer(c_pchMiniMapFileName); + m_MiniMapGraphicImageInstance.SetImagePointer(pImage); + + if (!m_MiniMapGraphicImageInstance.GetTexturePointer()->IsEmpty()) + { + m_lpMiniMapTexture = m_MiniMapGraphicImageInstance.GetTexturePointer()->GetD3DTexture(); + Tracef("CTerrain::LoadMiniMapTexture %d ms\n", ELTimer_GetMSec() - dwStart); + } + else + { + Tracef(" CTerrain::LoadMiniMapTexture - MiniMapTexture Error"); + m_lpMiniMapTexture = NULL; + } +} + +void CTerrain::LoadShadowTexture(const char * ShadowFileName) +{ + DWORD dwStart = ELTimer_GetMSec(); + CGraphicImage * pImage = (CGraphicImage *) CResourceManager::Instance().GetResourcePointer(ShadowFileName); + m_ShadowGraphicImageInstance.SetImagePointer(pImage); + + if (!m_ShadowGraphicImageInstance.GetTexturePointer()->IsEmpty()) + m_lpShadowTexture = m_ShadowGraphicImageInstance.GetTexturePointer()->GetD3DTexture(); + else + { + TraceError(" CTerrain::LoadShadowTexture - ShadowTexture is Empty"); + m_lpShadowTexture = NULL; + } + Tracef("CTerrain::LoadShadowTexture %d ms\n", ELTimer_GetMSec() - dwStart); +} + +bool CTerrain::LoadShadowMap(const char * c_pszFileName) +{ + DWORD dwStart = ELTimer_GetMSec(); + Tracef("LoadShadowMap %s ", c_pszFileName); + + CMappedFile file; + LPCVOID c_pvData; + + if (!CEterPackManager::Instance().Get(file, c_pszFileName, &c_pvData)) + { + TraceError(" CTerrain::LoadShadowMap - %s OPEN ERROR", c_pszFileName); + return false; + } + + DWORD dwShadowMapSize = sizeof(WORD) * 256 * 256; + + if (file.Size() != dwShadowMapSize) + { + TraceError(" CTerrain::LoadShadowMap - %s SIZE ERROR", c_pszFileName); + return false; + } + + memcpy(m_awShadowMap, c_pvData, dwShadowMapSize); + + Tracef("%d ms\n", ELTimer_GetMSec() - dwStart); + return true; +} + +////////////////////////////////////////////////////////////////////////// +// Seamless ο Լ... +////////////////////////////////////////////////////////////////////////// + +void CTerrain::CopySettingFromGlobalSetting() +{ + m_lViewRadius = m_pOwnerOutdoorMap->GetViewRadius(); + m_fHeightScale = m_pOwnerOutdoorMap->GetHeightScale(); +} + +WORD CTerrain::WE_GetHeightMapValue(short sX, short sY) +{ + if (sX>=-1 && sY>=-1 && sXGetTerrainNumFromCoord(m_wX, m_wY, &byTerrainNum) ) + { + Tracef("CTerrain::WE_GetHeightMapValue : Can't Get TerrainNum from Coord %d, %d", m_wX, m_wY); + byTerrainNum = 4; + } + + short sTerrainCouuntX, sTerrainCouuntY; + m_pOwnerOutdoorMap->GetTerrainCount(&sTerrainCouuntX, &sTerrainCouuntY); + + CTerrain * pTerrain = NULL; + + if (sY < -1) + { + if (m_wY <= 0) + { + if ( sX < -1) + { + if (m_wX <= 0) + return GetHeightMapValue(-1, -1); + else + { + if (!m_pOwnerOutdoorMap->GetTerrainPointer(byTerrainNum - 1, &pTerrain)) + return GetHeightMapValue(-1, -1); + else + return pTerrain->GetHeightMapValue(sX + XSIZE, -1); + } + } + else if (sX >= HEIGHTMAP_RAW_XSIZE - 1) + { + if (m_wX >= sTerrainCouuntX - 1) + return GetHeightMapValue(HEIGHTMAP_RAW_XSIZE - 1, -1); + else + { + if (!m_pOwnerOutdoorMap->GetTerrainPointer(byTerrainNum + 1, &pTerrain)) + return GetHeightMapValue(HEIGHTMAP_RAW_XSIZE - 1, -1); + else + return pTerrain->GetHeightMapValue(sX - XSIZE, -1); + } + } + else + return GetHeightMapValue(sX, -1); + } + else + { + if (sX < -1) + { + if (m_wX <= 0) + { + if (!m_pOwnerOutdoorMap->GetTerrainPointer(byTerrainNum - 3, &pTerrain)) + return GetHeightMapValue(-1, -1); + else + return pTerrain->GetHeightMapValue(-1, sY + YSIZE); + } + else + { + if (!m_pOwnerOutdoorMap->GetTerrainPointer(byTerrainNum - 4, &pTerrain)) + return GetHeightMapValue(-1, -1); + else + return pTerrain->GetHeightMapValue(sX + XSIZE, sY + YSIZE); + } + } + else if (sX >= HEIGHTMAP_RAW_XSIZE - 1) + { + if (m_wX >= sTerrainCouuntX) + { + if (!m_pOwnerOutdoorMap->GetTerrainPointer(byTerrainNum - 3, &pTerrain)) + return GetHeightMapValue(HEIGHTMAP_RAW_XSIZE - 1, -1); + else + return pTerrain->GetHeightMapValue(HEIGHTMAP_RAW_XSIZE - 1, sY + YSIZE); + } + else + { + if (!m_pOwnerOutdoorMap->GetTerrainPointer(byTerrainNum - 2, &pTerrain)) + return GetHeightMapValue(HEIGHTMAP_RAW_XSIZE - 1, -1); + else + return pTerrain->GetHeightMapValue(sX - XSIZE, sY + YSIZE); + } + } + else + { + if (!m_pOwnerOutdoorMap->GetTerrainPointer(byTerrainNum - 3, &pTerrain)) + return GetHeightMapValue(sX, -1); + else + return pTerrain->GetHeightMapValue(sX, sY + YSIZE); + } + } + } + else if (sY >= HEIGHTMAP_RAW_YSIZE - 1) + { + if (m_wY >= sTerrainCouuntY - 1) + { + if (sX < -1) + { + if (m_wX <= 0) + return GetHeightMapValue(-1, HEIGHTMAP_RAW_XSIZE - 1); + else + { + if (!m_pOwnerOutdoorMap->GetTerrainPointer(byTerrainNum - 1, &pTerrain)) + return GetHeightMapValue(-1, HEIGHTMAP_RAW_XSIZE - 1); + else + return pTerrain->GetHeightMapValue(sX + XSIZE, HEIGHTMAP_RAW_YSIZE - 1); + } + } + else if (sX >= HEIGHTMAP_RAW_XSIZE - 1) + { + if (m_wX >= sTerrainCouuntX - 1) + return GetHeightMapValue(HEIGHTMAP_RAW_XSIZE - 1, HEIGHTMAP_RAW_YSIZE - 1); + else + { + if (!m_pOwnerOutdoorMap->GetTerrainPointer(byTerrainNum + 1, &pTerrain)) + return GetHeightMapValue(HEIGHTMAP_RAW_XSIZE - 1, HEIGHTMAP_RAW_YSIZE - 1); + else + return pTerrain->GetHeightMapValue(sX - XSIZE, HEIGHTMAP_RAW_YSIZE - 1); + } + } + else + return GetHeightMapValue(sX, HEIGHTMAP_RAW_YSIZE - 1); + } + else + { + if (sX < -1) + { + if (m_wX <= 0) + { + if (!m_pOwnerOutdoorMap->GetTerrainPointer(byTerrainNum + 3, &pTerrain)) + return GetHeightMapValue(-1, HEIGHTMAP_RAW_YSIZE - 1); + else + return pTerrain->GetHeightMapValue(-1, sY - YSIZE); + } + else + { + if (!m_pOwnerOutdoorMap->GetTerrainPointer(byTerrainNum + 2, &pTerrain)) + return GetHeightMapValue(-1, HEIGHTMAP_RAW_XSIZE - 1); + else + return pTerrain->GetHeightMapValue(sX + XSIZE, sY - YSIZE); + } + } + else if (sX >= HEIGHTMAP_RAW_XSIZE - 1) + { + if (m_wX >= sTerrainCouuntX - 1) + { + if (!m_pOwnerOutdoorMap->GetTerrainPointer(byTerrainNum + 3, &pTerrain)) + return GetHeightMapValue(HEIGHTMAP_RAW_XSIZE - 1, HEIGHTMAP_RAW_YSIZE - 1); + else + return pTerrain->GetHeightMapValue(HEIGHTMAP_RAW_XSIZE - 1, sY - YSIZE); + } + else + { + if (!m_pOwnerOutdoorMap->GetTerrainPointer(byTerrainNum + 4, &pTerrain)) + return GetHeightMapValue(HEIGHTMAP_RAW_XSIZE - 1, HEIGHTMAP_RAW_YSIZE - 1); + else + return pTerrain->GetHeightMapValue(sX - XSIZE, sY - YSIZE); + } + } + else + { + if (!m_pOwnerOutdoorMap->GetTerrainPointer(byTerrainNum + 3, &pTerrain)) + return GetHeightMapValue(sX, HEIGHTMAP_RAW_YSIZE - 1); + else + return pTerrain->GetHeightMapValue(sX, sY - YSIZE); + } + } + } + else + { + if (sX < -1) + { + if (m_wX <= 0) + return GetHeightMapValue(-1, sY); + else + { + if (!m_pOwnerOutdoorMap->GetTerrainPointer(byTerrainNum - 1, &pTerrain)) + return GetHeightMapValue(-1, sY); + else + return pTerrain->GetHeightMapValue(sX + XSIZE, sY); + } + } + else if (sX >= HEIGHTMAP_RAW_XSIZE - 1) + { + if (m_wX >= sTerrainCouuntX - 1) + return GetHeightMapValue(HEIGHTMAP_RAW_XSIZE - 1, sY); + else + { + if (!m_pOwnerOutdoorMap->GetTerrainPointer(byTerrainNum + 1, &pTerrain)) + return GetHeightMapValue(HEIGHTMAP_RAW_XSIZE - 1, sY); + else + return pTerrain->GetHeightMapValue(sX - XSIZE, sY); + } + } + else + return GetHeightMapValue(sX, sY); + } +} + +bool CTerrain::GetNormal(int ix, int iy, D3DXVECTOR3 * pv3Normal) +{ + long lMapWidth = XSIZE * CELLSCALE; + long lMapHeight = YSIZE * CELLSCALE; + while (ix < 0) + ix += lMapWidth; + + while (iy < 0) + iy += lMapHeight; + + while (ix > lMapWidth) + ix -= lMapWidth; + + while (iy > lMapHeight) + iy -= lMapHeight; + + ix /= CELLSCALE; + iy /= CELLSCALE; + + D3DXVECTOR3 v3Noraml; + char * n = (char*) &m_acNormalMap[(iy * NORMALMAP_XSIZE + ix)*3]; + pv3Normal->x = -((float)*n++) * 0.007874016f; + pv3Normal->y = ((float)*n++) * 0.007874016f; + pv3Normal->z = ((float)*n++) * 0.007874016f; + + return true; +} +// Returns the height of the terrain at the given world coordinate +float CTerrain::GetHeight(int x, int y) +{ + //if (0 == CELLSCALE) + //return 0.0f; + + x -= m_wX * XSIZE * CELLSCALE; + y -= m_wY * YSIZE * CELLSCALE; + + if (x < 0 || y < 0 || x > XSIZE * CELLSCALE || y > XSIZE * CELLSCALE) + return 0.0f; + + long xdist; /* x mod size of tile */ + long ydist; /* y mod size of tile */ + float xslope, yslope; /* slopes of heights between vertices */ + + float h1, h2, h3; + long x2, y2; + float ooscale; + + /* Find out the distance relative to the top left vertex of a tile */ + xdist = x % CELLSCALE; + ydist = y % CELLSCALE; + + /* Convert into pixel coordinates */ + ooscale = 1.0f / ((float)CELLSCALE); + x /= CELLSCALE; + y /= CELLSCALE; + + x2 = x; y2 = y; + /* Get the height and color of the pixel at the top left corner */ + h1 = (float) GetHeightMapValue(x2, y2) * m_fHeightScale; + + /* Get the height and color of the pixel at the bottom right corner */ + x2 = x + 1; + y2 = y + 1; + + h2 = (float) GetHeightMapValue(x2, y2) * m_fHeightScale; + + /* Left triangle */ + if (xdist <= ydist) + { + x2 = x; + y2 = y + 1; + + h3 = (float) GetHeightMapValue(x2, y2) * m_fHeightScale; + + /* Get the height of the pixel at the bottom left corner */ + xslope = (h2 - h3) * ooscale; + yslope = (h3 - h1) * ooscale; + + return (h1 + (xdist * xslope + ydist * yslope)); + } + + /* Right triangle */ + x2 = x + 1; + y2 = y; + + h3 = (float) GetHeightMapValue(x2, y2) * m_fHeightScale; + + /* Get the height of the pixel at the top right corner */ + xslope = (h3 - h1) * ooscale; + yslope = (h2 - h3) * ooscale; + + return (h1 + (xdist * xslope + ydist * yslope)); +} + +////////////////////////////////////////////////////////////////////////// +// HeightMapCoord -> TileMapCoord + +void CTerrain::CalculateNormal(long x, long y) +{ + D3DXVECTOR3 normal; + + normal.x = -m_fHeightScale * ((float)GetHeightMapValue((x-1),y)-(float)GetHeightMapValue((x+1),y)); + normal.y = -m_fHeightScale * ((float)GetHeightMapValue(x,(y-1))-(float)GetHeightMapValue(x,(y+1))); + + normal.z = 2.0f * static_cast(CELLSCALE); + normal *= 127.0f / D3DXVec3Length(&normal); + + int ix, iy, iz; + PR_FLOAT_TO_INT(normal.x, ix); + PR_FLOAT_TO_INT(normal.y, iy); + PR_FLOAT_TO_INT(normal.z, iz); + + char * n = (char*) &m_acNormalMap[(y * NORMALMAP_XSIZE + x)*3]; + + *n++ = (char) ix; + *n++ = (char) iy; + *n++ = (char) iz; +} + +bool CTerrain::RAW_LoadTileMap(const char * c_pszFileName, bool bBGLoading) +{ + CTerrainImpl::RAW_LoadTileMap(c_pszFileName); + DWORD dwStart = ELTimer_GetMSec(); + RAW_AllocateSplats(bBGLoading); + Tracef("CTerrain::RAW_AllocateSplats %d\n", ELTimer_GetMSec() - dwStart); + return true; +} + +bool CTerrain::LoadHeightMap(const char * c_pszFileName) +{ + CTerrainImpl::LoadHeightMap(c_pszFileName); + DWORD dwStart = ELTimer_GetMSec(); + for (WORD y = 0; y < NORMALMAP_YSIZE; ++y) + for (WORD x = 0; x < NORMALMAP_XSIZE; ++x) + CalculateNormal(x, y); + + Tracef("LoadHeightMap::CalculateNormal %d ms\n", ELTimer_GetMSec() - dwStart); + return true; +} + +bool CTerrain::LoadAttrMap(const char *c_pszFileName) +{ + return CTerrainImpl::LoadAttrMap(c_pszFileName); +} + +bool CTerrain::isAttrOn(WORD wCoordX, WORD wCoordY, BYTE byAttrFlag) +{ + if (wCoordX >= ATTRMAP_XSIZE || wCoordY >= ATTRMAP_YSIZE) + { + Tracef("CTerrain::isAttrOn Coordiante Error! Return false... Input Coord - X : %d, Y : %d ( Limit X : %d, Y : %d)", wCoordX, wCoordY, ATTRMAP_XSIZE, ATTRMAP_YSIZE); + return false; + } + + BYTE byMapAttr = m_abyAttrMap[wCoordY * ATTRMAP_XSIZE + wCoordX]; + + if ( byAttrFlag < 16 ) + return (byMapAttr & byAttrFlag) ? true : false; + else + { + if ( byAttrFlag/16 == byMapAttr/16) + return true; + else + return false; + } +} + +BYTE CTerrain::GetAttr(WORD wCoordX, WORD wCoordY) +{ + if (wCoordX >= ATTRMAP_XSIZE || wCoordY >= ATTRMAP_YSIZE) + { + Tracef("CTerrain::GetAttr Coordiante Error! Return 0... Input Coord - X : %d, Y : %d ( Limit X : %d, Y : %d)", wCoordX, wCoordY, ATTRMAP_XSIZE, ATTRMAP_YSIZE); + return 0; + } + + return m_abyAttrMap[wCoordY * ATTRMAP_XSIZE + wCoordX]; +} + +void CTerrain::GetWaterHeight(BYTE byWaterNum, long * plWaterHeight) +{ + if (byWaterNum > m_byNumWater) + { + Tracef("CTerrain::GetWaterHeight WaterNum %d(Total Num %d) ERROR!", byWaterNum, m_byNumWater); + return; + } + *plWaterHeight = m_lWaterHeight[byWaterNum]; +} + +bool CTerrain::GetWaterHeight(WORD wCoordX, WORD wCoordY, long * plWaterHeight) +{ + BYTE byWaterNum = *(m_abyWaterMap + (wCoordY * WATERMAP_XSIZE) + wCoordX); + if (byWaterNum > m_byNumWater) + { + Tracef("CTerrain::GetWaterHeight (X %d, Y %d) ERROR!", wCoordX, wCoordY, m_byNumWater); + return false; + } + *plWaterHeight = m_lWaterHeight[byWaterNum] / 2; + + return true; +} + +void CTerrain::RAW_DeallocateSplats(bool bBGLoading) +{ + for (DWORD i = 1; i < GetTextureSet()->GetTextureCount(); ++i) + { + TTerainSplat & rSplat = m_TerrainSplatPatch.Splats[i]; + + if (m_lpAlphaTexture[i]) + { + ULONG ulRef; + do + { + ulRef = m_lpAlphaTexture[i]->Release(); + } while(ulRef > 0); + } + + rSplat.pd3dTexture = m_lpAlphaTexture[i] = NULL; + } + + memset(&m_TerrainSplatPatch, 0, sizeof(m_TerrainSplatPatch)); +} + +void CTerrain::RAW_AllocateSplats(bool bBGLoading) +{ + RAW_DeallocateSplats(bBGLoading); + DWORD dwTexCount = GetTextureSet()->GetTextureCount(); + + m_TerrainSplatPatch.m_bNeedsUpdate = true; + + for (DWORD t = 0; t < dwTexCount; ++t) + m_TerrainSplatPatch.Splats[t].NeedsUpdate = 1; + + RAW_CountTiles(); + +// if ( WAIT_OBJECT_0 == LockDataWrite() ) + RAW_GenerateSplat(bBGLoading); +// UnlockDataWrite(); + + m_TerrainSplatPatch.m_bNeedsUpdate = false; +} + +void CTerrain::RAW_CountTiles() +{ + for (long y = 0; y < TILEMAP_RAW_YSIZE; ++y) + { + long lPatchIndexY = min(max((y-1)/PATCH_TILE_YSIZE,0), PATCH_YCOUNT - 1); + for (long x = 0; x < TILEMAP_RAW_XSIZE; ++x) + { + long lPatchIndexX = min(max((x-1)/(PATCH_TILE_XSIZE), 0), PATCH_XCOUNT - 1); + BYTE tilenum = m_abyTileMap[y * TILEMAP_RAW_XSIZE + x]; + + ++m_TerrainSplatPatch.PatchTileCount[lPatchIndexY * PATCH_XCOUNT + lPatchIndexX][tilenum]; + + if ( 0 == y % PATCH_TILE_YSIZE && 0 != y && (TILEMAP_RAW_YSIZE - 2) != y) + { + ++m_TerrainSplatPatch.PatchTileCount[min(PATCH_YCOUNT - 1, lPatchIndexY + 1) * PATCH_XCOUNT + lPatchIndexX][tilenum]; + if ( 0 == x % PATCH_TILE_XSIZE && 0 != x && (TILEMAP_RAW_XSIZE - 2) != x) + { + ++m_TerrainSplatPatch.PatchTileCount[lPatchIndexY * PATCH_XCOUNT + min(PATCH_XCOUNT - 1, lPatchIndexX + 1)][tilenum]; + ++m_TerrainSplatPatch.PatchTileCount[min(PATCH_YCOUNT - 1, lPatchIndexY + 1) * PATCH_XCOUNT + min(PATCH_XCOUNT - 1, lPatchIndexX + 1)][tilenum]; + } + else if ( 1 == x % PATCH_TILE_XSIZE && (TILEMAP_RAW_XSIZE -1) != x && 1 != x) + { + ++m_TerrainSplatPatch.PatchTileCount[lPatchIndexY * PATCH_XCOUNT + max(0, lPatchIndexX - 1)][tilenum]; + ++m_TerrainSplatPatch.PatchTileCount[min(PATCH_YCOUNT - 1, lPatchIndexY + 1) * PATCH_XCOUNT + max(0, lPatchIndexX - 1)][tilenum]; + } + } + else if ( 1 == y % PATCH_TILE_YSIZE && (TILEMAP_RAW_YSIZE -1) != y && 1 != y) + { + ++m_TerrainSplatPatch.PatchTileCount[max(0, lPatchIndexY - 1) * PATCH_XCOUNT + lPatchIndexX][tilenum]; + if ( 0 == x % PATCH_TILE_XSIZE && 0 != x && (TILEMAP_RAW_XSIZE - 2) != x) + { + ++m_TerrainSplatPatch.PatchTileCount[lPatchIndexY * PATCH_XCOUNT + min(PATCH_XCOUNT - 1, lPatchIndexX + 1)][tilenum]; + ++m_TerrainSplatPatch.PatchTileCount[max(0, lPatchIndexY - 1) * PATCH_XCOUNT + min(PATCH_XCOUNT - 1, lPatchIndexX + 1)][tilenum]; + } + else if ( 1 == x % PATCH_TILE_XSIZE && (TILEMAP_RAW_XSIZE -1) != x && 1 != x) + { + ++m_TerrainSplatPatch.PatchTileCount[lPatchIndexY * PATCH_XCOUNT + max(0, lPatchIndexX - 1)][tilenum]; + ++m_TerrainSplatPatch.PatchTileCount[max(0, lPatchIndexY - 1) * PATCH_XCOUNT + max(0, lPatchIndexX - 1)][tilenum]; + } + } + else + { + if ( 0 == x % PATCH_TILE_XSIZE && 0 != x && (TILEMAP_RAW_XSIZE - 2) != x) + ++m_TerrainSplatPatch.PatchTileCount[lPatchIndexY * PATCH_XCOUNT + min(PATCH_XCOUNT - 1, lPatchIndexX + 1)][tilenum]; + else if ( 1 == x % PATCH_TILE_XSIZE && (TILEMAP_RAW_XSIZE -1) != x && 1 != x) + ++m_TerrainSplatPatch.PatchTileCount[lPatchIndexY * PATCH_XCOUNT + max(0, lPatchIndexX - 1)][tilenum]; + } + + ++m_TerrainSplatPatch.TileCount[tilenum]; + } + } +} + +void CTerrain::RAW_GenerateSplat(bool bBGLoading) +{ + if (!m_TerrainSplatPatch.m_bNeedsUpdate) + return; + + m_TerrainSplatPatch.m_bNeedsUpdate = false; + + BYTE abyAlphaMap[SPLATALPHA_RAW_XSIZE * SPLATALPHA_RAW_YSIZE]; + BYTE * aptr; + + for (DWORD i = 1; i < GetTextureSet()->GetTextureCount(); ++i) + { + TTerainSplat & rSplat = m_TerrainSplatPatch.Splats[i]; + + if (rSplat.NeedsUpdate) + { + if (m_TerrainSplatPatch.TileCount[i] > 0) + { + if (rSplat.Active) // We already have an alpha map which needs to be updated + { + if (m_lpAlphaTexture[i]) + { + ULONG ulRef; + do + { + ulRef = m_lpAlphaTexture[i]->Release(); + if (ulRef > 0) + TraceError(" CTerrain::RAW_GenerateSplat - TileCount > 0 : Alpha Texture Release(%d) ERROR", ulRef); + } while(ulRef > 0); + } + + rSplat.pd3dTexture = m_lpAlphaTexture[i] = NULL; + } + + rSplat.Active = 1; + rSplat.NeedsUpdate = 0; + + aptr = abyAlphaMap; + + for (long y = 0; y < SPLATALPHA_RAW_YSIZE; ++y) + { + for (long x = 0; x < SPLATALPHA_RAW_XSIZE; ++x) + { + long lTileMapOffset = y * TILEMAP_RAW_XSIZE + x; + + BYTE byTileNum = m_abyTileMap[lTileMapOffset]; + if (byTileNum == i) + *aptr = 0xFF; + else if (byTileNum > i) + { + BYTE byTileTL, byTileTR, byTileBL, byTileBR, byTileT, byTileB, byTileL, byTileR; + + if ( x > 0 && y > 0 ) + byTileTL = m_abyTileMap[lTileMapOffset - TILEMAP_RAW_YSIZE - 1]; + else + byTileTL = 0; + if ( x < (SPLATALPHA_RAW_XSIZE - 1) && y > 0 ) + byTileTR = m_abyTileMap[lTileMapOffset - TILEMAP_RAW_YSIZE + 1]; + else + byTileTR = 0; + if ( x > 0 && y < (SPLATALPHA_RAW_YSIZE - 1) ) + byTileBL = m_abyTileMap[lTileMapOffset + TILEMAP_RAW_YSIZE - 1]; + else + byTileBL = 0; + if ( x < (SPLATALPHA_RAW_XSIZE - 1) && y < (SPLATALPHA_RAW_YSIZE - 1) ) + byTileBR = m_abyTileMap[lTileMapOffset + TILEMAP_RAW_YSIZE + 1]; + else + byTileBR = 0; + if ( y > 0 ) + byTileT = m_abyTileMap[lTileMapOffset - TILEMAP_RAW_YSIZE]; + else + byTileT = 0; + if ( y < (SPLATALPHA_RAW_YSIZE - 1) ) + byTileB = m_abyTileMap[lTileMapOffset + TILEMAP_RAW_YSIZE]; + else + byTileB = 0; + if ( x > 0 ) + byTileL = m_abyTileMap[lTileMapOffset - 1]; + else + byTileL = 0; + if ( x < (SPLATALPHA_RAW_XSIZE - 1) ) + byTileR = m_abyTileMap[lTileMapOffset + 1]; + else + byTileR = 0; + + if (byTileTL == i || byTileTR == i || byTileBL == i || byTileBR == i || + byTileT == i || byTileB == i || byTileL == i || byTileR == i) + *aptr = 0xFF; + else + *aptr = 0x00; + } + else + *aptr = 0x00; + + ++aptr; + } + } + + + rSplat.pd3dTexture = AddTexture32(i, abyAlphaMap, SPLATALPHA_RAW_XSIZE, SPLATALPHA_RAW_YSIZE); + } + else + { + if (rSplat.Active) + { + if (m_lpAlphaTexture[i]) + { + ULONG ulRef; + do + { + ulRef = m_lpAlphaTexture[i]->Release(); + if (ulRef > 0) + TraceError(" CTerrain::RAW_GenerateSplat - TileDount 0 : Alpha Texture Release(%d) ERROR", ulRef); + } while(ulRef > 0); + } + + rSplat.pd3dTexture = m_lpAlphaTexture[i] = NULL; + } + rSplat.NeedsUpdate = 0; + rSplat.Active = 0; + } + } + } +} + +LPDIRECT3DTEXTURE8 CTerrain::AddTexture32(BYTE byImageNum, BYTE * pbyImage, long lTextureWidth, long lTextureHeight) +{ + assert(NULL==m_lpAlphaTexture[byImageNum]); + + if (m_lpAlphaTexture[byImageNum]) + m_lpAlphaTexture[byImageNum]->Release(); + + m_lpAlphaTexture[byImageNum]=NULL; + + HRESULT hr; + D3DFORMAT format; + + if(ms_bSupportDXT) + format = D3DFMT_A8R8G8B8; + else + format = D3DFMT_A4R4G4B4; + + + bool bResizedAndSuccess = false; + + IDirect3DTexture8* pkTex=NULL; + + UINT uiNewWidth = 256; + UINT uiNewHeight = 256; + hr = ms_lpd3dDevice->CreateTexture( + uiNewWidth, uiNewHeight, 5, 0, + format, D3DPOOL_MANAGED, &pkTex); + if (FAILED(hr)) + { + TraceError("CTerrain::AddTexture32 - CreateTexture Error"); + return NULL; + } + + + BYTE abResizeImage[256*256]; + { + BYTE* pbDstPixel=abResizeImage; + BYTE* pbSrcPixel; + BYTE* abCurLine=pbyImage; + for (UINT y=0; y<256; ++y, abCurLine+=258) + { + for (UINT x=0; x<256; ++x) + { + pbSrcPixel=abCurLine+x; + *pbDstPixel++= + ((( pbSrcPixel[0]+pbSrcPixel[1]+pbSrcPixel[2]+ + pbSrcPixel[258]+pbSrcPixel[260]+ + pbSrcPixel[258*2]+pbSrcPixel[258*2+1]+pbSrcPixel[258*2+2]) + >>3)+pbSrcPixel[259])>>1; + } + } + + D3DLOCKED_RECT d3dlr; + hr = pkTex->LockRect(0, &d3dlr, 0, 0); + if (FAILED(hr)) + { + pkTex->Release(); + return NULL; + } + + if(ms_bSupportDXT) + PutImage32(abResizeImage, (BYTE*) d3dlr.pBits, 256, d3dlr.Pitch, 256, 256, bResizedAndSuccess); + else + PutImage16(abResizeImage, (BYTE*) d3dlr.pBits, 256, d3dlr.Pitch, 256, 256, bResizedAndSuccess); + + pkTex->UnlockRect(0); + } + + BYTE abResizeImage2[128*128]; + + BYTE* pbSrcBuffer=abResizeImage; + BYTE* pbDstBuffer=abResizeImage2; + + UINT uSrcSize=256; + + for (UINT uMipMapLevel=1; uMipMapLevel!=pkTex->GetLevelCount(); ++uMipMapLevel) + { + UINT uDstSize=uSrcSize>>1; + + BYTE* pbDstPixel=pbDstBuffer; + BYTE* pbSrcPixel; + BYTE* abCurLine=pbSrcBuffer; + for (UINT y=0; y!=uSrcSize; y+=2, abCurLine+=uSrcSize*2) + { + for (UINT x=0; x!=uSrcSize; x+=2) + { + pbSrcPixel=abCurLine+x; + *pbDstPixel++=(pbSrcPixel[0]+pbSrcPixel[1]+pbSrcPixel[uSrcSize+0]+pbSrcPixel[uSrcSize+1])>>2; + } + } + + D3DLOCKED_RECT d3dlr; + + hr = pkTex->LockRect(uMipMapLevel, &d3dlr, 0, 0); + if (FAILED(hr)) + continue; + + if(ms_bSupportDXT) + PutImage32(pbDstBuffer, (BYTE*) d3dlr.pBits, uDstSize, d3dlr.Pitch, uDstSize, uDstSize, bResizedAndSuccess); + else + PutImage16(pbDstBuffer, (BYTE*) d3dlr.pBits, uDstSize, d3dlr.Pitch, uDstSize, uDstSize, bResizedAndSuccess); + + hr = pkTex->UnlockRect(uMipMapLevel); + + std::swap(pbSrcBuffer, pbDstBuffer); + uSrcSize=uDstSize; + } + + m_lpAlphaTexture[byImageNum]=pkTex; + + return pkTex; +} + +void CTerrain::PutImage32(BYTE *src, BYTE *dst, long src_pitch, long dst_pitch, long texturewidth, long textureheight, bool bResize) +{ + for (int y = 0; y < textureheight; ++y) + { + for (int x = 0; x < texturewidth; ++x) + { + DWORD packed_pixel = src[x] << 24; + *((DWORD*)(dst+x*4)) = packed_pixel; + + } + + dst += dst_pitch; + src += src_pitch; + } +} + +void CTerrain::PutImage16(BYTE *src, BYTE *dst, long src_pitch, long dst_pitch, long texturewidth, long textureheight, bool bResize) +{ + for (int y = 0; y < textureheight; ++y) + { + for (int x = 0; x < texturewidth; ++x) + { + WORD packed_pixel = src[x] << 8; + //& ѹ Ʊ + //WORD packed_pixel = (src[x]&0xF0) << 8; + *((WORD*)(dst+x*2)) = packed_pixel; + } + + dst += dst_pitch; + src += src_pitch; + } +} + +void CTerrain::SetCoordinate(WORD wCoordX, WORD wCoordY) +{ + m_wX = wCoordX; + m_wY = wCoordY; +} + +void CTerrain::CalculateTerrainPatch() +{ + for (BYTE byPatchNumY = 0; byPatchNumY < PATCH_YCOUNT; ++byPatchNumY) + for (BYTE byPatchNumX = 0; byPatchNumX < PATCH_XCOUNT; ++byPatchNumX) + _CalculateTerrainPatch(byPatchNumX, byPatchNumY); +} + +CTerrainPatch * CTerrain::GetTerrainPatchPtr(BYTE byPatchNumX, BYTE byPatchNumY) +{ + if (byPatchNumX < 0 || byPatchNumX >= PATCH_XCOUNT || byPatchNumY < 0 || byPatchNumY >= PATCH_YCOUNT) + return NULL; + + return &m_TerrainPatchList[byPatchNumY * PATCH_XCOUNT + byPatchNumX]; +} + + + +void CTerrain::_CalculateTerrainPatch(BYTE byPatchNumX, BYTE byPatchNumY) +{ + if (!m_awRawHeightMap || !m_acNormalMap || !m_abyWaterMap) + return; + + DWORD dwPatchNum = byPatchNumY * PATCH_XCOUNT + byPatchNumX; + + CTerrainPatch& rkTerrainPatch=m_TerrainPatchList[dwPatchNum]; + if (!rkTerrainPatch.NeedUpdate()) + return; + + const float fOpaqueWaterDepth = m_pOwnerOutdoorMap->GetOpaqueWaterDepth(); + const float fOOOpaqueWaterDepth = 1.0f/fOpaqueWaterDepth; + const float fTransparentWaterDepth = 0.8f * fOpaqueWaterDepth; + + rkTerrainPatch.Clear(); + + HardwareTransformPatch_SSourceVertex akSrcTerrainVertex[CTerrainPatch::TERRAIN_VERTEX_COUNT]; + SWaterVertex akSrcWaterVertex[PATCH_XSIZE * PATCH_YSIZE * 6]; + + DWORD dwNormalWidth = CTerrainImpl::NORMALMAP_XSIZE * 3; + DWORD dwStartX = byPatchNumX * PATCH_XSIZE; + DWORD dwStartY = byPatchNumY * PATCH_YSIZE; + + WORD * wOrigRawHeightPtr = m_awRawHeightMap + ((dwStartY+1) * HEIGHTMAP_RAW_XSIZE) + dwStartX+1; + char * chOrigNormalPtr = m_acNormalMap + (dwStartY * dwNormalWidth) + dwStartX * 3; + BYTE * byOrigWaterPtr = m_abyWaterMap + (dwStartY * WATERMAP_XSIZE) + dwStartX; + + float fX, fY, fOrigX, fOrigY; + fOrigX = fX = (float)(m_wX * XSIZE * CELLSCALE) + (float)(dwStartX * CELLSCALE); + fOrigY = fY = (float)(m_wY * YSIZE * CELLSCALE) + (float)(dwStartY * CELLSCALE); + + rkTerrainPatch.SetMinX(fX); + rkTerrainPatch.SetMaxX(fX + (float)(PATCH_XSIZE*CELLSCALE)); + rkTerrainPatch.SetMinY(fY); + rkTerrainPatch.SetMaxY(fY + (float)(PATCH_YSIZE*CELLSCALE)); + + float fMinZ = 999999.0f; + float fMaxZ = -999999.0f; + WORD wNumPlainType = 0; + WORD wNumHillType = 0; + WORD wNumCliffType = 0; + + bool bWaterExist=false; + + SWaterVertex* lpWaterVertex=akSrcWaterVertex; + UINT uWaterVertexCount=0; + + HardwareTransformPatch_SSourceVertex* lpTerrainVertex=akSrcTerrainVertex; + UINT uTerrainVertexCount=0; + + D3DXVECTOR3 kNormal; + D3DXVECTOR3 kPosition; + for (DWORD dwY = dwStartY; dwY <= dwStartY + PATCH_YSIZE; ++dwY) + { + WORD * pwRawHeight = wOrigRawHeightPtr; + char * pchNormal = chOrigNormalPtr; + BYTE * pbyWater = byOrigWaterPtr; + fX = fOrigX; + + for (DWORD dwX = dwStartX; dwX <= dwStartX + PATCH_XSIZE; ++dwX) + { + WORD hgt = (*pwRawHeight++); + + kNormal.x = -(*pchNormal++) * 0.0078740f; + kNormal.y = (*pchNormal++) * 0.0078740f; + kNormal.z = (*pchNormal++) * 0.0078740f; + + kPosition.x = +fX; + kPosition.y = -fY; + kPosition.z = (float)(hgt) * m_fHeightScale; + lpTerrainVertex->kPosition = kPosition; + lpTerrainVertex->kNormal = kNormal; + + if (0.5f > kNormal.z) // 30 ִ. Cliff type + ++wNumCliffType; + else if (0.8660254f > kNormal.z) // 60 ִ. Hill type + ++wNumHillType; + else // ̻ plain Ÿ + ++wNumPlainType; + + if (kPosition.z > fMaxZ) + fMaxZ = kPosition.z; + if (kPosition.z < fMinZ) + fMinZ = kPosition.z; + + if (0 <= dwX && 0 <= dwY && XSIZE > dwX && YSIZE > dwY && + (dwStartX + PATCH_XSIZE) != dwX && (dwStartY + PATCH_YSIZE) != dwY) + { + BYTE byNumWater = (*pbyWater++); + + if (byNumWater != 0xFF) + { + long lWaterHeight = m_lWaterHeight[byNumWater]; + if (-1 != lWaterHeight) + { + float fWaterTerrainHeightDifference0 = (float)(lWaterHeight - (long)hgt); + if (fWaterTerrainHeightDifference0 >= fTransparentWaterDepth) + fWaterTerrainHeightDifference0 = fTransparentWaterDepth; + if (fWaterTerrainHeightDifference0 <= 0.0f) + fWaterTerrainHeightDifference0 = 0.0f; + + float fWaterTerrainHeightDifference1 = (float)(lWaterHeight - (long)(*(pwRawHeight + CTerrainImpl::HEIGHTMAP_RAW_XSIZE - 1))); + if (fWaterTerrainHeightDifference1 >= fTransparentWaterDepth) + fWaterTerrainHeightDifference1 = fTransparentWaterDepth; + if (fWaterTerrainHeightDifference1 <= 0.0f) + fWaterTerrainHeightDifference1 = 0.0f; + + float fWaterTerrainHeightDifference2 = (float)(lWaterHeight - (long)(*(pwRawHeight))); + if (fWaterTerrainHeightDifference2 >= fTransparentWaterDepth) + fWaterTerrainHeightDifference2 = fTransparentWaterDepth; + if (fWaterTerrainHeightDifference2 <= 0.0f) + fWaterTerrainHeightDifference2 = 0.0f; + + float fWaterTerrainHeightDifference3 = (float)(lWaterHeight - (long)(*(pwRawHeight + CTerrainImpl::HEIGHTMAP_RAW_XSIZE))); + if (fWaterTerrainHeightDifference3 >= fTransparentWaterDepth) + fWaterTerrainHeightDifference3 = fTransparentWaterDepth; + if (fWaterTerrainHeightDifference3 <= 0.0f) + fWaterTerrainHeightDifference3 = 0.0f; + + DWORD dwAlpha0; + DWORD dwAlpha1; + DWORD dwAlpha2; + DWORD dwAlpha3; + + PR_FLOAT_TO_INT(fWaterTerrainHeightDifference0 * fOOOpaqueWaterDepth * 255.0f, dwAlpha0); + PR_FLOAT_TO_INT(fWaterTerrainHeightDifference1 * fOOOpaqueWaterDepth * 255.0f, dwAlpha1); + PR_FLOAT_TO_INT(fWaterTerrainHeightDifference2 * fOOOpaqueWaterDepth * 255.0f, dwAlpha2); + PR_FLOAT_TO_INT(fWaterTerrainHeightDifference3 * fOOOpaqueWaterDepth * 255.0f, dwAlpha3); + + DWORD dwAlphaKey=(dwAlpha0<<24)|(dwAlpha1<<16)|(dwAlpha2<<8)|dwAlpha3; + if (dwAlphaKey!=0) + { + assert(lpWaterVertexx = fX; + lpWaterVertex->y = -fY; + lpWaterVertex->z = (float)lWaterHeight * m_fHeightScale; + lpWaterVertex->dwDiffuse = ((dwAlpha0 << 24) & 0xFF000000) | 0x000000FF;// 0x000F939B + lpWaterVertex++; + + lpWaterVertex->x = fX; + lpWaterVertex->y = -fY - float(CELLSCALE); + lpWaterVertex->z = (float)lWaterHeight * m_fHeightScale; + lpWaterVertex->dwDiffuse = ((dwAlpha1 << 24) & 0xFF000000) | 0x00FFFFFF; + lpWaterVertex++; + + lpWaterVertex->x = fX + float(CELLSCALE); + lpWaterVertex->y = -fY; + lpWaterVertex->z = (float)lWaterHeight * m_fHeightScale; + lpWaterVertex->dwDiffuse = ((dwAlpha2 << 24) & 0xFF000000) | 0x00FFFFFF; + lpWaterVertex++; + + lpWaterVertex->x = fX + float(CELLSCALE); + lpWaterVertex->y = -fY; + lpWaterVertex->z = (float)lWaterHeight * m_fHeightScale; + lpWaterVertex->dwDiffuse = ((dwAlpha2 << 24) & 0xFF000000) | 0x00FFFFFF; + lpWaterVertex++; + + lpWaterVertex->x = fX; + lpWaterVertex->y = -fY - float(CELLSCALE); + lpWaterVertex->z = (float)lWaterHeight * m_fHeightScale; + lpWaterVertex->dwDiffuse = ((dwAlpha1 << 24) & 0xFF000000) | 0x00FFFFFF; + lpWaterVertex++; + + lpWaterVertex->x = fX + float(CELLSCALE); + lpWaterVertex->y = -fY - float(CELLSCALE); + lpWaterVertex->z = (float)lWaterHeight * m_fHeightScale; + lpWaterVertex->dwDiffuse = ((dwAlpha3 << 24) & 0xFF0000FF) | 0x00FFFFFF; + lpWaterVertex++; + + uWaterVertexCount+=6; + bWaterExist = true; + } + } + + } + } + + ++lpTerrainVertex; + ++uTerrainVertexCount; + fX += float(CELLSCALE); + } + + wOrigRawHeightPtr += CTerrainImpl::HEIGHTMAP_RAW_XSIZE; + chOrigNormalPtr += dwNormalWidth; + byOrigWaterPtr += CTerrainImpl::XSIZE; + fY += float(CELLSCALE); + } + + if (wNumPlainType <= max(wNumHillType, wNumCliffType)) + { + if (wNumCliffType <= wNumHillType) + rkTerrainPatch.SetType(CTerrainPatch::PATCH_TYPE_HILL); + else + rkTerrainPatch.SetType(CTerrainPatch::PATCH_TYPE_CLIFF); + } + + rkTerrainPatch.SetWaterExist(bWaterExist); + + rkTerrainPatch.SetMinZ(fMinZ); + rkTerrainPatch.SetMaxZ(fMaxZ); + + assert((PATCH_XSIZE+1)*(PATCH_YSIZE+1)==uTerrainVertexCount); + rkTerrainPatch.BuildTerrainVertexBuffer(akSrcTerrainVertex); + + if (bWaterExist) + rkTerrainPatch.BuildWaterVertexBuffer(akSrcWaterVertex, uWaterVertexCount); + + rkTerrainPatch.NeedUpdate(false); +} + +void CTerrain::AllocateMarkedSplats(BYTE * pbyAlphaMap) +{ + TTerainSplat & rAttrSplat = m_MarkedSplatPatch.Splats[0]; + HRESULT hr; + + if (m_lpMarkedTexture) + { + ULONG ulRef; + do + { + ulRef = m_lpMarkedTexture->Release(); + } while(ulRef > 0); + } + + do + { + hr = ms_lpd3dDevice->CreateTexture(ATTRMAP_XSIZE, ATTRMAP_YSIZE, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &m_lpMarkedTexture); + } while(FAILED(hr)); + + D3DLOCKED_RECT d3dlr; + do + { + hr = m_lpMarkedTexture->LockRect(0, &d3dlr, 0, 0); + } while(FAILED(hr)); + + PutImage32(pbyAlphaMap, (BYTE*) d3dlr.pBits, ATTRMAP_XSIZE, d3dlr.Pitch, ATTRMAP_XSIZE, ATTRMAP_YSIZE); + + do + { + hr = m_lpMarkedTexture->UnlockRect(0); + } while(FAILED(hr)); + + rAttrSplat.pd3dTexture = m_lpMarkedTexture; + m_bMarked = true; +} + +void CTerrain::DeallocateMarkedSplats() +{ + TTerainSplat & rSplat = m_MarkedSplatPatch.Splats[0]; + if (m_lpMarkedTexture) + { + ULONG ulRef; + do + { + ulRef = m_lpMarkedTexture->Release(); + } while(ulRef > 0); + } + + rSplat.pd3dTexture = NULL; + m_lpMarkedTexture = NULL; + m_bMarked = FALSE; + + memset(&m_MarkedSplatPatch, 0, sizeof(m_MarkedSplatPatch)); +} diff --git a/source/GameLib/AreaTerrain.h b/source/GameLib/AreaTerrain.h new file mode 100644 index 0000000..1d3d9b3 --- /dev/null +++ b/source/GameLib/AreaTerrain.h @@ -0,0 +1,160 @@ +#pragma once + +class CMapOutdoor; + +#include "../PRTerrainLib/Terrain.h" +#include "TerrainPatch.h" + +class CTerrain : public CTerrainImpl, public CGraphicBase +{ + public: + + enum EBoundaryLoadPart + { + LOAD_INVALID, + LOAD_NOBOUNDARY, + LOAD_TOPLEFT, + LOAD_TOP, + LOAD_TOPRIGHT, + LOAD_LEFT, + LOAD_RIGHT, + LOAD_BOTTOMLEFT, + LOAD_BOTTOM, + LOAD_BOTTOMRIGHT, + LOAD_ALLBOUNDARY, + }; + + CTerrain(); + virtual ~CTerrain(); + + virtual void Clear(); + + void SetMapOutDoor(CMapOutdoor * pOwnerOutdoorMap); + + ////////////////////////////////////////////////////////////////////////// + // Loading + bool RAW_LoadTileMap(const char * c_pszFileName, bool bBGLoading = false); + + bool LoadHeightMap(const char * c_pszFileName); + + void CalculateTerrainPatch(); + ////////////////////////////////////////////////////////////////////////// + + void CopySettingFromGlobalSetting(); + + WORD WE_GetHeightMapValue(short sX, short sY); + + bool IsReady() { return m_bReady; } + void SetReady(bool bReady = true) { m_bReady = bReady; } + + // Height Map + WORD * GetHeightMap() { return m_awRawHeightMap; } + float GetHeight(int x, int y); + + // Normal Map + bool GetNormal(int ix, int iy, D3DXVECTOR3 * pv3Normal); + + // TileMap + BYTE * RAW_GetTileMap() { return m_abyTileMap; } + char * GetNormalMap() { return m_acNormalMap; } + + // Attr + bool LoadAttrMap(const char * c_pszFileName); + BYTE * GetAttrMap() { return m_abyAttrMap; } + BYTE GetAttr(WORD wCoordX, WORD wCoordY); + bool isAttrOn(WORD wCoordX, WORD wCoordY, BYTE byAttrFlag); + + ////////////////////////////////////////////////////////////////////////// + // Water + BYTE * GetWaterMap() { return m_abyWaterMap; } + void GetWaterHeight(BYTE byWaterNum, long * plWaterHeight); + bool GetWaterHeight(WORD wCoordX, WORD wCoordY, long * plWaterHeight); + + // Shadow Texture + void LoadShadowTexture(const char * c_pszFileName); + + // Shadow Map + bool LoadShadowMap(const char * c_pszFileName); + + // MiniMap + void LoadMiniMapTexture(const char * c_pszFileName); + inline LPDIRECT3DTEXTURE8 GetMiniMapTexture() { return m_lpMiniMapTexture; } + + // Marked Area + BOOL IsMarked() { return m_bMarked; } + void AllocateMarkedSplats(BYTE * pbyAlphaMap); + void DeallocateMarkedSplats(); + TTerrainSplatPatch & GetMarkedSplatPatch() { return m_MarkedSplatPatch; } + + // Coordinate + void GetCoordinate(WORD * usCoordX, WORD * usCoordY) + { + *usCoordX = m_wX; + *usCoordY = m_wY; + } + + void SetCoordinate(WORD wCoordX, WORD wCoordY); + + std::string & GetName() { return m_strName; } + void SetName(const std::string c_strName) { m_strName = c_strName; } + + CMapOutdoor * GetOwner() { return m_pOwnerOutdoorMap; } + void RAW_GenerateSplat(bool bBGLoading = false); + + protected: + bool Initialize(); + void RAW_AllocateSplats(bool bBGLoading = false); + void RAW_DeallocateSplats(bool bBGLoading = false); + virtual void RAW_CountTiles(); + + LPDIRECT3DTEXTURE8 AddTexture32(BYTE byImageNum, BYTE * pbyImage, long lTextureWidth, long lTextureHeight); + void PutImage32(BYTE * pbySrc, BYTE * pbyDst, long src_pitch, long dst_pitch, long lTextureWidth, long lTextureHeight, bool bResize = false); + void PutImage16(BYTE * pbySrc, BYTE * pbyDst, long src_pitch, long dst_pitch, long lTextureWidth, long lTextureHeight, bool bResize = false); + + protected: + void CalculateNormal(long x, long y); + + protected: + std::string m_strName; + WORD m_wX; + WORD m_wY; + + protected: + bool m_bReady; + + CGraphicImageInstance m_ShadowGraphicImageInstance; + + //MiniMap + CGraphicImageInstance m_MiniMapGraphicImageInstance; + LPDIRECT3DTEXTURE8 m_lpMiniMapTexture; + + + // Owner COutdoorMap poineter + CMapOutdoor * m_pOwnerOutdoorMap; + + // Picking + D3DXVECTOR3 m_v3Pick; + + DWORD m_dwNumTexturesShow; + std::vector m_VectorNumShowTexture; + + CTerrainPatch m_TerrainPatchList[PATCH_XCOUNT * PATCH_YCOUNT]; + + BOOL m_bMarked; + TTerrainSplatPatch m_MarkedSplatPatch; + LPDIRECT3DTEXTURE8 m_lpMarkedTexture; + + public: + CTerrainPatch * GetTerrainPatchPtr(BYTE byPatchNumX, BYTE byPatchNumY); + + protected: + void _CalculateTerrainPatch(BYTE byPatchNumX, BYTE byPatchNumY); + + public: + static void DestroySystem(); + + static CTerrain* New(); + static void Delete(CTerrain* pkTerrain); + + static CDynamicPool ms_kPool; +}; diff --git a/source/GameLib/DungeonBlock.cpp b/source/GameLib/DungeonBlock.cpp new file mode 100644 index 0000000..f0dbcf4 --- /dev/null +++ b/source/GameLib/DungeonBlock.cpp @@ -0,0 +1,265 @@ +#include "StdAfx.h" +#include "DungeonBlock.h" + +#include "../eterlib/StateManager.h" + +class CDungeonModelInstance : public CGrannyModelInstance +{ + public: + CDungeonModelInstance() {} + virtual ~CDungeonModelInstance() {} + + void RenderDungeonBlock() + { + if (IsEmpty()) + return; + + STATEMANAGER.SetVertexShader(ms_pnt2VS); + LPDIRECT3DVERTEXBUFFER8 lpd3dRigidPNTVtxBuf = m_pModel->GetPNTD3DVertexBuffer(); + if (lpd3dRigidPNTVtxBuf) + { + STATEMANAGER.SetStreamSource(0, lpd3dRigidPNTVtxBuf, sizeof(TPNT2Vertex)); + RenderMeshNodeListWithTwoTexture(CGrannyMesh::TYPE_RIGID, CGrannyMaterial::TYPE_BLEND_PNT); + } + } + + void RenderDungeonBlockShadow() + { + if (IsEmpty()) + return; + + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xffffffff); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); + STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR); + + STATEMANAGER.SetVertexShader(ms_pnt2VS); + LPDIRECT3DVERTEXBUFFER8 lpd3dRigidPNTVtxBuf = m_pModel->GetPNTD3DVertexBuffer(); + if (lpd3dRigidPNTVtxBuf) + { + STATEMANAGER.SetStreamSource(0, lpd3dRigidPNTVtxBuf, sizeof(TPNT2Vertex)); + RenderMeshNodeListWithoutTexture(CGrannyMesh::TYPE_RIGID, CGrannyMaterial::TYPE_BLEND_PNT); + } + + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAOP); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND); + STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND); + } +}; + + +struct FUpdate +{ + float fElapsedTime; + D3DXMATRIX * pmatWorld; + void operator() (CGrannyModelInstance * pInstance) + { + pInstance->Update(CGrannyModelInstance::ANIFPS_MIN); + pInstance->UpdateLocalTime(fElapsedTime); + pInstance->Deform(pmatWorld); + } +}; + +void CDungeonBlock::Update() +{ + Transform(); + + FUpdate Update; + Update.fElapsedTime = 0.0f; + Update.pmatWorld = &m_worldMatrix; + for_each(m_ModelInstanceContainer.begin(), m_ModelInstanceContainer.end(), Update); +} + +struct FRender +{ + void operator() (CDungeonModelInstance * pInstance) + { + pInstance->RenderDungeonBlock(); + } +}; + +void CDungeonBlock::Render() +{ +// if (!isShow()) +// return; + + for_each(m_ModelInstanceContainer.begin(), m_ModelInstanceContainer.end(), FRender()); +} + +struct FRenderShadow +{ + void operator() (CDungeonModelInstance * pInstance) + { + pInstance->RenderDungeonBlockShadow(); + } +}; + +void CDungeonBlock::OnRenderShadow() +{ + for_each(m_ModelInstanceContainer.begin(), m_ModelInstanceContainer.end(), FRenderShadow()); +} + +struct FBoundBox +{ + D3DXVECTOR3 * m_pv3Min; + D3DXVECTOR3 * m_pv3Max; + + FBoundBox(D3DXVECTOR3 * pv3Min, D3DXVECTOR3 * pv3Max) + { + m_pv3Min = pv3Min; + m_pv3Max = pv3Max; + } + void operator() (CGrannyModelInstance * pInstance) + { + pInstance->GetBoundBox(m_pv3Min, m_pv3Max); + } +}; + +bool CDungeonBlock::GetBoundingSphere(D3DXVECTOR3 & v3Center, float & fRadius) +{ + v3Center = m_v3Center; + fRadius = m_fRadius; + D3DXVec3TransformCoord(&v3Center, &v3Center, &GetTransform()); + return true; +} + +void CDungeonBlock::OnUpdateCollisionData(const CStaticCollisionDataVector * pscdVector) +{ + assert(pscdVector); + CStaticCollisionDataVector::const_iterator it; + for(it = pscdVector->begin();it!=pscdVector->end();++it) + { + AddCollision(&(*it),&GetTransform()); + } +} + +void CDungeonBlock::OnUpdateHeighInstance(CAttributeInstance * pAttributeInstance) +{ + assert(pAttributeInstance); + SetHeightInstance(pAttributeInstance); +} + +bool CDungeonBlock::OnGetObjectHeight(float fX, float fY, float * pfHeight) +{ + if (m_pHeightAttributeInstance && m_pHeightAttributeInstance->GetHeight(fX, fY, pfHeight)) + return true; + return false; +} + +void CDungeonBlock::BuildBoundingSphere() +{ + D3DXVECTOR3 v3Min, v3Max; + for_each(m_ModelInstanceContainer.begin(), m_ModelInstanceContainer.end(), FBoundBox(&v3Min, &v3Max)); + + m_v3Center = (v3Min+v3Max) * 0.5f; + const auto vv = (v3Max - v3Min); + m_fRadius = D3DXVec3Length(&vv)*0.5f + 150.0f; // extra length for attached objects +} + +bool CDungeonBlock::Intersect(float * pfu, float * pfv, float * pft) +{ + TModelInstanceContainer::iterator itor = m_ModelInstanceContainer.begin(); + for (; itor != m_ModelInstanceContainer.end(); ++itor) + { + CDungeonModelInstance * pInstance = *itor; + if (pInstance->Intersect(&CGraphicObjectInstance::GetTransform(), pfu, pfv, pft)) + return true; + } + + return false; +} + +void CDungeonBlock::GetBoundBox(D3DXVECTOR3 * pv3Min, D3DXVECTOR3 * pv3Max) +{ + pv3Min->x = +10000000.0f; + pv3Min->y = +10000000.0f; + pv3Min->z = +10000000.0f; + pv3Max->x = -10000000.0f; + pv3Max->y = -10000000.0f; + pv3Max->z = -10000000.0f; + + TModelInstanceContainer::iterator itor = m_ModelInstanceContainer.begin(); + for (; itor != m_ModelInstanceContainer.end(); ++itor) + { + CDungeonModelInstance * pInstance = *itor; + + D3DXVECTOR3 v3Min; + D3DXVECTOR3 v3Max; + pInstance->GetBoundBox(&v3Min, &v3Max); + + pv3Min->x = min(v3Min.x, pv3Min->x); + pv3Min->y = min(v3Min.x, pv3Min->y); + pv3Min->z = min(v3Min.x, pv3Min->z); + pv3Max->x = max(v3Max.x, pv3Max->x); + pv3Max->y = max(v3Max.x, pv3Max->y); + pv3Max->z = max(v3Max.x, pv3Max->z); + } +} + +bool CDungeonBlock::Load(const char * c_szFileName) +{ + Destroy(); + + m_pThing = (CGraphicThing *)CResourceManager::Instance().GetResourcePointer(c_szFileName); + + m_pThing->AddReference(); + if (m_pThing->GetModelCount() <= 0) + { + TraceError("CDungeonBlock::Load(filename=%s) - model count is %d\n", c_szFileName, m_pThing->GetModelCount()); + return false; + } + + m_ModelInstanceContainer.reserve(m_pThing->GetModelCount()); + + for (int i = 0; i < m_pThing->GetModelCount(); ++i) + { + CDungeonModelInstance * pModelInstance = new CDungeonModelInstance; + pModelInstance->SetMainModelPointer(m_pThing->GetModelPointer(i), &m_kDeformableVertexBuffer); + DWORD dwVertexCount = pModelInstance->GetVertexCount(); + m_kDeformableVertexBuffer.Destroy(); + m_kDeformableVertexBuffer.Create( + dwVertexCount, + D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1, + D3DUSAGE_WRITEONLY, + D3DPOOL_MANAGED); + m_ModelInstanceContainer.push_back(pModelInstance); + } + + return true; +} + +void CDungeonBlock::__Initialize() +{ + m_v3Center = D3DXVECTOR3(0.0f, 0.0f, 0.0f); + m_fRadius = 0.0f; + + m_pThing = NULL; +} + +void CDungeonBlock::Destroy() +{ + if (m_pThing) + { + m_pThing->Release(); + m_pThing = NULL; + } + + stl_wipe(m_ModelInstanceContainer); + + __Initialize(); +} + +CDungeonBlock::CDungeonBlock() +{ + __Initialize(); +} +CDungeonBlock::~CDungeonBlock() +{ + Destroy(); +} diff --git a/source/GameLib/DungeonBlock.h b/source/GameLib/DungeonBlock.h new file mode 100644 index 0000000..c9aa962 --- /dev/null +++ b/source/GameLib/DungeonBlock.h @@ -0,0 +1,56 @@ +#pragma once + +#include "../EterLib/ResourceManager.h" +#include "../EterLib/GrpObjectInstance.h" +#include "../EterGrnLib/ModelInstance.h" +#include "../EterGrnLib/Thing.h" + +class CDungeonModelInstance; + +class CDungeonBlock : public CGraphicObjectInstance +{ + public: + typedef std::vector TModelInstanceContainer; + enum + { + ID = THING_OBJECT + }; + int GetType() const { return ID; } + + public: + CDungeonBlock(); + virtual ~CDungeonBlock(); + + void Destroy(); + + void BuildBoundingSphere(); + bool Load(const char * c_szFileName); + + bool Intersect(float * pfu, float * pfv, float * pft); + void GetBoundBox(D3DXVECTOR3 * pv3Min, D3DXVECTOR3 * pv3Max); + + void Update(); + void Render(); + + bool GetBoundingSphere(D3DXVECTOR3 & v3Center, float & fRadius); + void OnUpdateCollisionData(const CStaticCollisionDataVector * pscdVector); + void OnUpdateHeighInstance(CAttributeInstance * pAttributeInstance); + bool OnGetObjectHeight(float fX, float fY, float * pfHeight); + + void OnRender() {} + void OnBlendRender() {} + void OnRenderToShadowMap() {} + void OnRenderShadow(); + void OnRenderPCBlocker() {} + + protected: + void __Initialize(); + + protected: + D3DXVECTOR3 m_v3Center; + float m_fRadius; + + CGraphicThing * m_pThing; + TModelInstanceContainer m_ModelInstanceContainer; + CGraphicVertexBuffer m_kDeformableVertexBuffer; +}; diff --git a/source/GameLib/FlyHandler.h b/source/GameLib/FlyHandler.h new file mode 100644 index 0000000..65c024f --- /dev/null +++ b/source/GameLib/FlyHandler.h @@ -0,0 +1,21 @@ +#pragma once + +class IFlyEventHandler +{ +public: + IFlyEventHandler() {} + virtual ~IFlyEventHandler() {} + + // Call by ActorInstance + virtual void OnSetFlyTarget() {} + virtual void OnShoot(DWORD dwSkillIndex) {} + + virtual void OnNoTarget() {} + virtual void OnNoArrow() {} + + // Call by FlyingInstance + virtual void OnExplodingOutOfRange() {} + virtual void OnExplodingAtBackground() {} + virtual void OnExplodingAtAnotherTarget(DWORD dwSkillIndex, DWORD dwVID) {} + virtual void OnExplodingAtTarget(DWORD dwSkillIndex) {} +}; \ No newline at end of file diff --git a/source/GameLib/FlyTarget.cpp b/source/GameLib/FlyTarget.cpp new file mode 100644 index 0000000..74d3048 --- /dev/null +++ b/source/GameLib/FlyTarget.cpp @@ -0,0 +1,114 @@ +#include "StdAfx.h" +#include "FlyTarget.h" + +CFlyTarget::CFlyTarget() +{ + __Initialize(); +} + +CFlyTarget::CFlyTarget(IFlyTargetableObject * pFlyTarget) +{ + __Initialize(); + + m_eType=TYPE_OBJECT; + m_pFlyTarget=pFlyTarget; + m_pFlyTarget->AddFlyTargeter(this); +} +CFlyTarget::CFlyTarget(const D3DXVECTOR3& v3FlyTargetPosition) +{ + __Initialize(); + + m_eType=TYPE_POSITION; + m_v3FlyTargetPosition=v3FlyTargetPosition; +} + +CFlyTarget::CFlyTarget(const CFlyTarget& rhs) +{ + __Initialize(); + + *this = rhs; +} + +CFlyTarget::~CFlyTarget() +{ + if (m_pFlyTarget) + m_pFlyTarget->RemoveFlyTargeter(this); +} + +void CFlyTarget::__Initialize() +{ + m_v3FlyTargetPosition=D3DXVECTOR3(0.0f,0.0f,0.0f); + m_pFlyTarget=NULL; + m_eType=TYPE_NONE; +} + +void CFlyTarget::Clear() +{ + m_eType = TYPE_NONE; + m_pFlyTarget = 0; +} + +bool CFlyTarget::IsObject() +{ + return (TYPE_OBJECT==GetType()); +} + +bool CFlyTarget::IsPosition() +{ + return (TYPE_POSITION==GetType()); +} + +bool CFlyTarget::IsValidTarget() +{ + return (TYPE_NONE!=GetType()); +} + +void CFlyTarget::NotifyTargetClear() +{ + //if (m_eType == FLY_TARGET_TYPE_OBJECT) + m_eType = TYPE_POSITION; + m_pFlyTarget = 0; +} + +CFlyTarget::EType CFlyTarget::GetType() +{ + return m_eType; +} + +IFlyTargetableObject* CFlyTarget::GetFlyTarget() +{ + assert(TYPE_OBJECT==GetType() && "CFly::GetFlyTarget"); + return m_pFlyTarget; +} + +const D3DXVECTOR3 & CFlyTarget::GetFlyTargetPosition() const +{ + if (m_eType == TYPE_OBJECT) + { + m_v3FlyTargetPosition = m_pFlyTarget->OnGetFlyTargetPosition(); + } + return m_v3FlyTargetPosition; +} + +CFlyTarget & CFlyTarget::operator = (const CFlyTarget & rhs) +{ + if (m_pFlyTarget) + { + m_pFlyTarget->RemoveFlyTargeter(this); + } + m_eType = rhs.m_eType; + m_v3FlyTargetPosition = rhs.m_v3FlyTargetPosition; + m_pFlyTarget = rhs.m_pFlyTarget; + if (m_pFlyTarget) + { + m_pFlyTarget->AddFlyTargeter(this); + } + return *this; +} + +void CFlyTarget::GetFlyTargetData(CFlyTarget * pFlyTarget) +{ + pFlyTarget->m_eType = m_eType; + pFlyTarget->m_v3FlyTargetPosition = m_v3FlyTargetPosition; + pFlyTarget->m_pFlyTarget = m_pFlyTarget; +} diff --git a/source/GameLib/FlyTarget.h b/source/GameLib/FlyTarget.h new file mode 100644 index 0000000..c1d80cf --- /dev/null +++ b/source/GameLib/FlyTarget.h @@ -0,0 +1,80 @@ +#pragma once + + +class IFlyTargetableObject +{ + friend class CFlyTarget; +public: + IFlyTargetableObject() {} + virtual ~IFlyTargetableObject() {} + + virtual D3DXVECTOR3 OnGetFlyTargetPosition() = 0; + virtual void OnShootDamage() = 0; + +protected: + inline void ClearFlyTargeter(); +private: + std::set m_FlyTargeterSet; + inline void AddFlyTargeter(CFlyTarget* pTargeter) + { + //if (m_FlyTargeterSet.find(pTargeter)!=m_FlyTargeterSet.end()) + m_FlyTargeterSet.insert(pTargeter); + } + inline void RemoveFlyTargeter(CFlyTarget* pTargeter) + { + //if (m_FlyTargeterSet.find(pTargeter)!=m_FlyTargeterSet.end()) + m_FlyTargeterSet.erase(pTargeter); + } +}; + +class CFlyTarget // final +{ +public: + enum EType + { + TYPE_NONE, + TYPE_OBJECT, + TYPE_POSITION, + }; + +public: + CFlyTarget(); + CFlyTarget(IFlyTargetableObject * pFlyTarget); + CFlyTarget(const D3DXVECTOR3& v3FlyTargetPosition); + CFlyTarget(const CFlyTarget& rhs); + virtual ~CFlyTarget(); + + void Clear(); + bool IsObject(); + bool IsPosition(); + bool IsValidTarget(); + void NotifyTargetClear(); + + const D3DXVECTOR3 & GetFlyTargetPosition() const; + EType GetType(); + + IFlyTargetableObject * GetFlyTarget(); + + CFlyTarget & operator = (const CFlyTarget & rhs); + void GetFlyTargetData(CFlyTarget * pFlyTarget); + +private: + void __Initialize(); + +private: + mutable D3DXVECTOR3 m_v3FlyTargetPosition; + IFlyTargetableObject * m_pFlyTarget; + + EType m_eType; +}; + +inline void IFlyTargetableObject::ClearFlyTargeter() +{ + std::set::iterator it; + for(it = m_FlyTargeterSet.begin();it!=m_FlyTargeterSet.end();++it) + { + (*it)->NotifyTargetClear(); + } + m_FlyTargeterSet.clear(); +} + diff --git a/source/GameLib/FlyTrace.cpp b/source/GameLib/FlyTrace.cpp new file mode 100644 index 0000000..8062045 --- /dev/null +++ b/source/GameLib/FlyTrace.cpp @@ -0,0 +1,291 @@ +#include "stdafx.h" +#include "../eterLib/StateManager.h" +#include "../eterLib/Camera.h" + +#include "FlyingData.h" +#include "FlyTrace.h" + +CDynamicPool CFlyTrace::ms_kPool; + +void CFlyTrace::DestroySystem() +{ + ms_kPool.Destroy(); +} + +CFlyTrace* CFlyTrace::New() +{ + return ms_kPool.Alloc(); +} + +void CFlyTrace::Delete(CFlyTrace* pkInst) +{ + pkInst->Destroy(); + ms_kPool.Free(pkInst); +} + +CFlyTrace::CFlyTrace() +{ + __Initialize(); + + /* + // Code for texture + CGraphicImage * pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer("d:/ray.jpg"); + m_ImageInstance.SetImagePointer(pImage); + + CGraphicTexture * pTexture = m_ImageInstance.GetTexturePointer(); + m_lpTexture = pTexture->GetD3DTexture(); + */ +} + +CFlyTrace::~CFlyTrace() +{ + Destroy(); +} + + +void CFlyTrace::__Initialize() +{ + m_bRectShape=false; + m_dwColor=0; + m_fSize=0.0f; + m_fTailLength=0.0f; +} + +void CFlyTrace::Destroy() +{ + m_TimePositionDeque.clear(); + + __Initialize(); +} + +void CFlyTrace::UpdateNewPosition(const D3DXVECTOR3 & v3Position) +{ + m_TimePositionDeque.push_front(TTimePosition(CTimer::Instance().GetCurrentSecond(),v3Position)); + //Tracenf("%f %f",m_TimePositionDeque.back().first, CTimer::Instance().GetCurrentSecond()); + while(!m_TimePositionDeque.empty() && m_TimePositionDeque.back().first+m_fTailLength > TFlyVertexSetVector; + +void CFlyTrace::Render() +{ + if (m_TimePositionDeque.size()<=1) + return; + TFlyVertexSetVector VSVector; + + //STATEMANAGER.SaveRenderState(D3DRS_ZFUNC,D3DCMP_LESS); + STATEMANAGER.SaveRenderState(D3DRS_ZFUNC,D3DCMP_LESS); + //STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE,FALSE); + + D3DXMATRIX matWorld; + D3DXMatrixIdentity(&matWorld); + + STATEMANAGER.SaveTransform(D3DTS_WORLD, &matWorld); + STATEMANAGER.SaveVertexShader(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1); + STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); + + STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER); + STATEMANAGER.SaveRenderState(D3DRS_ALPHAREF, 0x00000000); + + STATEMANAGER.SaveRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD ); + //STATEMANAGER.SaveRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD ); + + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE); + //STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, /*(m_bUseTexture)?D3DTOP_SELECTARG2:*/D3DTOP_SELECTARG2); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); + //STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, /*(m_bUseTexture)?D3DTOP_SELECTARG2:*/D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SetTexture(1, NULL); + + + D3DXMATRIX m; + CScreen s;s.UpdateViewMatrix(); + CCamera * pCurrentCamera = CCameraManager::Instance().GetCurrentCamera(); + if (!pCurrentCamera) + return; + + const D3DXMATRIX & M = pCurrentCamera->GetViewMatrix(); + D3DXMatrixIdentity(&m); + D3DXVECTOR3 F(pCurrentCamera->GetView()); + m._31 = F.x; + m._32 = F.y; + m._33 = F.z; + + Frustum & frustum = s.GetFrustum(); + //frustum.BuildViewFrustum(ms_matView * ms_matProj); + + TTimePositionDeque::iterator it1, it2; + it2 = it1 = m_TimePositionDeque.begin(); + ++it2; + for(;it2!=m_TimePositionDeque.end();++it2,++it1) + { + const D3DXVECTOR3& rkOld=it1->second; + const D3DXVECTOR3& rkNew=it2->second; + D3DXVECTOR3 B = rkNew - rkOld; + + float radius = max(fabs(B.x),max(fabs(B.y),fabs(B.z)))/2; + Vector3d c(it1->second.x+B.x*0.5f, + it1->second.y+B.y*0.5f, + it1->second.z+B.z*0.5f + ); + if (frustum.ViewVolumeTest(c, radius)==VS_OUTSIDE) + continue; + + float rate1 = (1-(CTimer::Instance().GetCurrentSecond()-it1->first)/m_fTailLength); + float rate2 = (1-(CTimer::Instance().GetCurrentSecond()-it2->first)/m_fTailLength); + float size1 = m_fSize; + float size2 = m_fSize; + if (!m_bRectShape) + { + size1 *= rate1; + size2 *= rate2; + } + TFlyVertex v[6] = + { + TFlyVertex(D3DXVECTOR3(0.0f,size1,0.0f), m_dwColor,D3DXVECTOR2(0.0f,0.0f)), + TFlyVertex(D3DXVECTOR3(-size1,0.0f,0.0f),m_dwColor,D3DXVECTOR2(0.0f,0.5f)), + TFlyVertex(D3DXVECTOR3(size1,0.0f,0.0f), m_dwColor,D3DXVECTOR2(0.5f,0.0f)), + TFlyVertex(D3DXVECTOR3(-size2,0.0f,0.0f),m_dwColor,D3DXVECTOR2(0.5f,1.0f)), + TFlyVertex(D3DXVECTOR3(size2,0.0f,0.0f), m_dwColor,D3DXVECTOR2(1.0f,0.5f)), + TFlyVertex(D3DXVECTOR3(0.0f,-size2,0.0f),m_dwColor,D3DXVECTOR2(1.0f,1.0f)), + + /*TVertex(D3DXVECTOR3(0.0f,size1,0.0f), ((DWORD)(0x40*rate1)<<24) + 0x0000ff,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(-size1,0.0f,0.0f),((DWORD)(0x40*rate1)<<24) + 0x0000ff,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(size1,0.0f,0.0f), ((DWORD)(0x40*rate1)<<24) + 0x0000ff,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(-size2,0.0f,0.0f),((DWORD)(0x40*rate2)<<24) + 0x0000ff,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(size2,0.0f,0.0f), ((DWORD)(0x40*rate2)<<24) + 0x0000ff,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(0.0f,-size2,0.0f),((DWORD)(0x40*rate2)<<24) + 0x0000ff,D3DXVECTOR2(0.0f,0.0f)),*/ + + /*TVertex(D3DXVECTOR3(0.0f,size1,0.0f),0x20ff0000,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(-size1,0.0f,0.0f),0x20ff0000,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(size1,0.0f,0.0f),0x20ff0000,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(-size2,0.0f,0.0f),0x20ff0000,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(size2,0.0f,0.0f),0x20ff0000,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(0.0f,-size2,0.0f),0x20ff0000,D3DXVECTOR2(0.0f,0.0f)),*/ + + /*TVertex(D3DXVECTOR3(0.0f,size1,0.0f),0xffff0000,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(-size1,0.0f,0.0f),0xffff0000,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(size1,0.0f,0.0f),0xffff0000,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(-size2,0.0f,0.0f),0xff0000ff,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(size2,0.0f,0.0f),0xff0000ff,D3DXVECTOR2(0.0f,0.0f)), + TVertex(D3DXVECTOR3(0.0f,-size2,0.0f),0xff0000ff,D3DXVECTOR2(0.0f,0.0f)),*/ + }; + + + D3DXVECTOR3 E(M._41,M._42,M._43); + E = pCurrentCamera->GetEye(); + E-=it1->second; + + D3DXVECTOR3 P; + D3DXVec3Cross(&P, &B,&E); + + D3DXVECTOR3 U; + D3DXVec3Cross(&U,&F,&P); + D3DXVec3Normalize(&U,&U); + D3DXVECTOR3 R; + D3DXVec3Cross(&R,&F,&U); + //D3DXMatrixIdentity(&m); + m._21 = U.x; + m._22 = U.y; + m._23 = U.z; + m._11 = R.x; + m._12 = R.y; + m._13 = R.z; + int i; + for(i=0;i<6;i++) + D3DXVec3TransformNormal(&v[i].p,&v[i].p,&m); + for(i=0;i<3;i++) + v[i].p += it1->second; + for(;i<6;i++) + v[i].p += it2->second; + //for(i=0;i<6;i++) + // Tracenf("#%d:%f %f %f", i, v[i].p.x,v[i].p.y,v[i].p.z); + + VSVector.push_back(std::make_pair(-D3DXVec3Dot(&E,&pCurrentCamera->GetView()),TFlyVertexSet(v))); + //OLD: STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 4, v, sizeof(TVertex)); + //OLD: STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v+1, sizeof(TVertex)); + } + + std::sort(VSVector.begin(),VSVector.end()); + + for(TFlyVertexSetVector::iterator it = VSVector.begin();it!=VSVector.end();++it) + { + STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 4, it->second.v, sizeof(TVertex)); + } + STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND); + STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE); + STATEMANAGER.RestoreVertexShader(); + STATEMANAGER.RestoreTransform(D3DTS_WORLD); + //STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_ZFUNC); + STATEMANAGER.RestoreRenderState(D3DRS_BLENDOP); + + STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHAFUNC); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHAREF); + +} \ No newline at end of file diff --git a/source/GameLib/FlyTrace.h b/source/GameLib/FlyTrace.h new file mode 100644 index 0000000..6adbc51 --- /dev/null +++ b/source/GameLib/FlyTrace.h @@ -0,0 +1,42 @@ +#pragma once + +class CFlyTrace : public CScreen +{ + public: + CFlyTrace(); + virtual ~CFlyTrace(); + + void Destroy(); + + void Create(const CFlyingData::TFlyingAttachData & rFlyingAttachData); + + void UpdateNewPosition(const D3DXVECTOR3 & v3Position); + + void Update(); + void Render(); + + protected: + void __Initialize(); + + protected: + typedef std::pair TTimePosition; + typedef std::deque TTimePositionDeque; + + //CGraphicImageInstance m_ImageInstance; + //LPDIRECT3DTEXTURE8 m_lpTexture; + + bool m_bRectShape; + DWORD m_dwColor; + float m_fSize; + float m_fTailLength; + + TTimePositionDeque m_TimePositionDeque; + + public: + static void DestroySystem(); + + static CFlyTrace* New(); + static void Delete(CFlyTrace* pkInst); + + static CDynamicPool ms_kPool; +}; \ No newline at end of file diff --git a/source/GameLib/FlyingData.cpp b/source/GameLib/FlyingData.cpp new file mode 100644 index 0000000..40524d1 --- /dev/null +++ b/source/GameLib/FlyingData.cpp @@ -0,0 +1,353 @@ +#include "Stdafx.h" +#include "../effectLib/EffectManager.h" + +#include "FlyingData.h" + +CDynamicPool CFlyingData::ms_kPool; + +CFlyingData::CFlyingData() +{ + __Initialize(); +} + +void CFlyingData::__Initialize() +{ + m_v3AngVel = D3DXVECTOR3(0.0f,0.0f,0.0f); + m_bIsHoming = false; + m_fInitVel = 200.0f; + m_fConeAngle = (0.0f); + m_fRollAngle = 0.0f; + m_fRange = 500.0f; + m_v3Accel = D3DXVECTOR3(0,0,0.0f);// gravity direction :-z + m_fHomingMaxAngle = 3.0f; + m_fHomingStartTime = 0.0f; + m_fGravity = 0; + m_bSpreading = false; + m_bMaintainParallel = false; + + m_bHitOnBackground = false; + m_bHitOnAnotherMonster = false; + m_iPierceCount = 0; + m_fCollisionSphereRadius = 0.0f; + + m_fBombRange = 10.0f; + SetBombEffect(""); +} + +void CFlyingData::Destroy() +{ + m_AttachDataVector.clear(); + + __Initialize(); +} + +CFlyingData::~CFlyingData() +{ + Destroy(); +} + +void CFlyingData::SetBombEffect(const char* szEffectName) +{ + m_strBombEffectName = szEffectName; + if (m_strBombEffectName.empty()) + { + m_dwBombEffectID = 0; + return; + } + StringPath(m_strBombEffectName); + if (CEffectManager::Instance().RegisterEffect(m_strBombEffectName.c_str()),true) + { + m_dwBombEffectID = GetCaseCRC32(m_strBombEffectName.c_str(),m_strBombEffectName.size()); + } + else + { + m_dwBombEffectID = 0; + } + +} + +CFlyingData::TFlyingAttachData & CFlyingData::GetAttachDataReference(int iIndex) +{ + return m_AttachDataVector[iIndex]; +} + +DWORD CFlyingData::AttachFlyEffect(int iType, const std::string & strFilename, float fRoll, float fArg1, float fArg2) +{ + TFlyingAttachData fad; + memset(&fad,0, sizeof(fad)); + fad.iType = FLY_ATTACH_EFFECT; + fad.iFlyType = iType; + fad.fPeriod = 1.0f; + fad.strFilename = strFilename; + fad.fRoll = fRoll; + fad.dwTailColor = 0xffffffff; + fad.fTailLength = 1.0f; + fad.fTailSize = 10.0f; + + switch(iType) + { + case FLY_ATTACH_TYPE_MULTI_LINE: + fad.fDistance = fArg1; + break; + case FLY_ATTACH_TYPE_SINE: + case FLY_ATTACH_TYPE_EXP: + fad.fPeriod=fArg1; + fad.fAmplitude=fArg2; + break; + case FLY_ATTACH_TYPE_NONE: + case FLY_ATTACH_TYPE_LINE: + default: + // Do nothing + break; + } + + m_AttachDataVector.push_back(fad); + return m_AttachDataVector.size()-1; +} + +void CFlyingData::RemoveAttach(int iIndex) +{ + assert(0<=iIndex && iIndex<(int)m_AttachDataVector.size()); + m_AttachDataVector.erase(m_AttachDataVector.begin()+iIndex); +} + +void CFlyingData::RemoveAllAttach() +{ + m_AttachDataVector.clear(); +} + +void CFlyingData::DuplicateAttach(int iIndex) +{ + assert(0<=iIndex && iIndex<(int)m_AttachDataVector.size()); + m_AttachDataVector.push_back(m_AttachDataVector[iIndex]); +} + +bool CFlyingData::LoadScriptFile(const char* c_szFilename) +{ + NANOBEGIN + Destroy(); + + m_strFilename = c_szFilename; + StringPath(m_strFilename); + CTextFileLoader TextFileLoader; + if (!TextFileLoader.Load(m_strFilename.c_str())) + return false; + + TextFileLoader.SetTop(); + int temp; + + if (!TextFileLoader.GetTokenInteger("spreadingflag",&temp)) + { + m_bSpreading = false; + } + else + { + m_bSpreading = temp?true:false; + } + + if (!TextFileLoader.GetTokenInteger("maintainparallelflag", &temp)) + { + m_bMaintainParallel = false; + } + else + { + m_bMaintainParallel = temp?true:false; + } + + if (!TextFileLoader.GetTokenFloat("initialvelocity",&m_fInitVel)) + { + return false; + } + + TextFileLoader.GetTokenFloat("coneangle", &m_fConeAngle); + //if (!TextFileLoader.GetTokenFloat("coneangle", &m_fConeAngle)) + // m_fConeAngle = 0.0f; + + TextFileLoader.GetTokenFloat("rollangle", &m_fRollAngle); + //if (!TextFileLoader.GetTokenFloat("rollangle", &m_fRollAngle)) + // m_fRollAngle = 0.0f; + + TextFileLoader.GetTokenVector3("angularvelocity",&m_v3AngVel); + //if (!TextFileLoader.GetTokenVector3("angularvelocity",&m_v3AngVel)) + // m_v3AngVel = D3DXVECTOR3(0.0f,0.0f,0.0f); + + TextFileLoader.GetTokenFloat("gravity",&m_fGravity); + //if (!TextFileLoader.GetTokenFloat("gravity",&m_fGravity)) + //m_fGravity = 0.0f; + + if (TextFileLoader.GetTokenInteger("hitonbackground",&temp)) + m_bHitOnBackground = temp?true:false; + else + m_bHitOnBackground = false; + + if (TextFileLoader.GetTokenInteger("hitonanothermonster",&temp)) + m_bHitOnAnotherMonster = temp?true:false; + else + m_bHitOnAnotherMonster = false; + + if (!TextFileLoader.GetTokenInteger("piercecount",&m_iPierceCount)) + m_iPierceCount = 0; + +// if (!TextFileLoader.GetTokenFloat("collisionsphereradius",&m_fCollisionSphereRadius)) +// m_fCollisionSphereRadius = 0.0f; + + TextFileLoader.GetTokenFloat("bombrange",&m_fBombRange); + //if (!TextFileLoader.GetTokenFloat("bombrange",&m_fBombRange)) + // m_fBombRange = 10.0f; + + if (!TextFileLoader.GetTokenString("bombeffect",&m_strBombEffectName)) + { + m_strBombEffectName = ""; + } + else if (!m_strBombEffectName.empty()) + { + if (!IsGlobalFileName(m_strBombEffectName.c_str())) + m_strBombEffectName = GetOnlyPathName(TextFileLoader.GetFileName()) + m_strBombEffectName; + CEffectManager::Instance().RegisterEffect2(m_strBombEffectName.c_str(),&m_dwBombEffectID); + } + + if (!TextFileLoader.GetTokenInteger("homingflag", &temp)) + m_bIsHoming = false; + else + m_bIsHoming = temp?true:false; + + if (!TextFileLoader.GetTokenFloat("homingstarttime",&m_fHomingStartTime)) + m_fHomingStartTime = 0.0f; + + if (!TextFileLoader.GetTokenFloat("homingmaxangle",&m_fHomingMaxAngle)) + m_fHomingMaxAngle = 0.0f; + + if (!TextFileLoader.GetTokenFloat("range",&m_fRange)) + return false; + + if (!TextFileLoader.GetTokenVector3("acceleration",&m_v3Accel)) + m_v3Accel = D3DXVECTOR3(0.0f,0.0f,0.0f); + + DWORD i; + for(i=0;i::iterator it; + for(it = m_AttachDataVector.begin();it!=m_AttachDataVector.end();++it) + { + PrintfTabs(fp, 0, "Group AttachData\n"); + PrintfTabs(fp, 0, "{\n"); + PrintfTabs(fp, 1, "Type %d\n", it->iType); + PrintfTabs(fp, 1, "FlyType %d\n", it->iFlyType); + if (GetLocalFileName(strGlobalPathName.c_str(), it->strFilename.c_str(), &strLocalFileName)) + PrintfTabs(fp, 1, "AttachFile \"%s\"\n", strLocalFileName.c_str()); + else + PrintfTabs(fp, 1, "AttachFile \"%s\"\n", it->strFilename.c_str()); + //PrintfTabs(fp, 1, "AttachFile \"%s\"\n", it->strFilename); + + PrintfTabs(fp, 1, "TailFlag %d\n", it->bHasTail?1:0); + if (it->bHasTail) + { + PrintfTabs(fp, 1, "TailColor %ud\n", it->dwTailColor); + PrintfTabs(fp, 1, "TailLength %f\n", it->fTailLength); + PrintfTabs(fp, 1, "TailSize %f\n", it->fTailSize); + PrintfTabs(fp, 1, "TailShapeRect %d\n", it->bRectShape?1:0); + } + + PrintfTabs(fp, 1, "Roll %f\n",it->fRoll ); + PrintfTabs(fp, 1, "Distance %f\n",it->fDistance ); + PrintfTabs(fp, 1, "Period %f\n",it->fPeriod ); + PrintfTabs(fp, 1, "Amplitude %f\n",it->fAmplitude ); + + PrintfTabs(fp, 0, "}\n"); + } + + fclose(fp); + return true; +} \ No newline at end of file diff --git a/source/GameLib/FlyingData.h b/source/GameLib/FlyingData.h new file mode 100644 index 0000000..6e3c638 --- /dev/null +++ b/source/GameLib/FlyingData.h @@ -0,0 +1,111 @@ +#pragma once + +class CFlyingData //: public CPooledObject +{ +public: + + enum + { + FLY_ATTACH_NONE, + FLY_ATTACH_EFFECT, + FLY_ATTACH_OBJECT, // NOT IMPLEMENTED + }; + + enum + { + FLY_ATTACH_TYPE_NONE, + FLY_ATTACH_TYPE_LINE, + FLY_ATTACH_TYPE_MULTI_LINE, + FLY_ATTACH_TYPE_SINE, + FLY_ATTACH_TYPE_EXP, + }; + + struct TFlyingAttachData + { + int iType; + int iFlyType; + std::string strFilename; + + bool bHasTail; + DWORD dwTailColor; + float fTailLength; + float fTailSize; + bool bRectShape; + + float fRoll; + // nothing for LINE + // for MULTI_LINE + float fDistance; + // for SINE, EXP + float fPeriod; + float fAmplitude; + }; + + friend class CFlyingInstance; + + friend class CSceneFly; + friend class CFlyTabPage; + + CFlyingData(); + virtual ~CFlyingData(); + + void Destroy(); + + bool LoadScriptFile(const char* c_szFilename); + bool SaveScriptFile(const char* c_szFilename); + + const D3DXVECTOR3 & GetAcceleration() { return m_v3Accel; } + + void SetBombEffect(const char* szEffectName); + + DWORD AttachFlyEffect(int iType, const std::string & strFilename, float fRoll, float fArg1, float fArg2); + + TFlyingAttachData & GetAttachDataReference(int iIndex); + int GetAttachDataCount() { return m_AttachDataVector.size(); } + + void DuplicateAttach(int iIndex); + void RemoveAttach(int iIndex); + void RemoveAllAttach(); + +protected: + void __Initialize(); + + std::string m_strFilename; + + bool m_bSpreading; + bool m_bMaintainParallel; + + float m_fInitVel; + float m_fConeAngle; + float m_fRollAngle; + + D3DXVECTOR3 m_v3AngVel; + + float m_fGravity; + + float m_fBombRange; + std::string m_strBombEffectName; + DWORD m_dwBombEffectID; + + bool m_bIsHoming; + float m_fHomingMaxAngle; + float m_fHomingStartTime; + + bool m_bHitOnBackground; + bool m_bHitOnAnotherMonster; + int m_iPierceCount; + float m_fCollisionSphereRadius; + + float m_fRange; + D3DXVECTOR3 m_v3Accel; + + std::vector m_AttachDataVector; + +public: + static CFlyingData * New() { return ms_kPool.Alloc(); } + static void Delete(CFlyingData * pData) { pData->Destroy(); ms_kPool.Free(pData); } + + static void DestroySystem() { ms_kPool.Destroy(); } + + static CDynamicPool ms_kPool; +}; \ No newline at end of file diff --git a/source/GameLib/FlyingInstance.cpp b/source/GameLib/FlyingInstance.cpp new file mode 100644 index 0000000..e8e1e06 --- /dev/null +++ b/source/GameLib/FlyingInstance.cpp @@ -0,0 +1,598 @@ +#include "Stdafx.h" +#include "../eterLib/GrpMath.h" +#include "../effectLib/EffectManager.h" + +#include "MapManager.h" + +#include "FlyingData.h" +#include "FlyTrace.h" +#include "FlyingInstance.h" +#include "FlyingObjectManager.h" +#include "FlyTarget.h" +#include "FlyHandler.h" + +CDynamicPool CFlyingInstance::ms_kPool; + +CFlyingInstance::CFlyingInstance() +{ + __Initialize(); +} + +CFlyingInstance::~CFlyingInstance() +{ + Destroy(); +} + +void CFlyingInstance::__Initialize() +{ + m_qAttachRotation=m_qRot=D3DXQUATERNION(0.0f, 0.0f, 0.0f, 0.0f); + m_v3Accel=m_v3LocalVelocity=m_v3Velocity=m_v3Position=D3DXVECTOR3(0.0f, 0.0f, 0.0f); + + m_pHandler=NULL; + m_pData=NULL; + m_pOwner=NULL; + + m_bAlive=false; + m_canAttack=false; + + m_dwSkillIndex = 0; + + m_iPierceCount=0; + + m_fStartTime=0.0f; + m_fRemainRange=0.0f; + + m_bTargetHitted = FALSE; + m_HittedObjectSet.clear(); +} + +void CFlyingInstance::Clear() +{ + Destroy(); +} + +void CFlyingInstance::Destroy() +{ + m_FlyTarget.Clear(); + + ClearAttachInstance(); + + __Initialize(); +} + + +void CFlyingInstance::BuildAttachInstance() +{ + for(int i=0;iGetAttachDataCount();i++) + { + CFlyingData::TFlyingAttachData & rfad = m_pData->GetAttachDataReference(i); + + switch(rfad.iType) + { + case CFlyingData::FLY_ATTACH_OBJECT: + // NOT Implemented + assert(!"FlyingInstance.cpp:BuildAttachInstance Not implemented FLY_ATTACH_OBJECT"); + break; + case CFlyingData::FLY_ATTACH_EFFECT: + { + CEffectManager & rem = CEffectManager::Instance(); + TAttachEffectInstance aei; + + DWORD dwCRC = GetCaseCRC32(rfad.strFilename.c_str(),rfad.strFilename.size()); + + aei.iAttachIndex = i; + aei.dwEffectInstanceIndex = rem.GetEmptyIndex(); + + aei.pFlyTrace = NULL; + if (rfad.bHasTail) + { + aei.pFlyTrace = CFlyTrace::New(); + aei.pFlyTrace->Create(rfad); + } + rem.CreateEffectInstance(aei.dwEffectInstanceIndex,dwCRC); + + m_vecAttachEffectInstance.push_back(aei); + } + break; + } + } +} + +void CFlyingInstance::Create(CFlyingData* pData, const D3DXVECTOR3& c_rv3StartPos, const CFlyTarget & c_rkTarget, bool canAttack) +{ + m_FlyTarget = c_rkTarget; + m_canAttack = canAttack; + + __SetDataPointer(pData, c_rv3StartPos); + __SetTargetDirection(m_FlyTarget); +} + +void CFlyingInstance::__SetTargetDirection(const CFlyTarget& c_rkTarget) +{ + D3DXVECTOR3 v3TargetPos=c_rkTarget.GetFlyTargetPosition(); + + // ӽ ڵ + if (m_pData->m_bMaintainParallel) + { + v3TargetPos.z += 50.0f; + } + + D3DXVECTOR3 v3TargetDir=v3TargetPos-m_v3Position; + + D3DXVec3Normalize(&v3TargetDir, &v3TargetDir); + __SetTargetNormalizedDirection(v3TargetDir); +} + +void CFlyingInstance::__SetTargetNormalizedDirection(const D3DXVECTOR3 & v3NomalizedDirection) +{ + D3DXQUATERNION q = SafeRotationNormalizedArc(D3DXVECTOR3(0.0f,-1.0f,0.0f),v3NomalizedDirection); + D3DXQuaternionMultiply(&m_qRot,&m_qRot,&q); + Vec3TransformQuaternion(&m_v3Velocity,&m_v3LocalVelocity,&m_qRot); + Vec3TransformQuaternion(&m_v3Accel, &m_pData->m_v3Accel, &m_qRot); +} + +// 2004. 3. 26. myevan. ϴ ּ ó. ̹ ʿ. ӿ ʴ´ٸ ӹ޾ 鵵 +void CFlyingInstance::SetFlyTarget(const CFlyTarget & cr_Target) +{ + //m_pFlyTarget = pTarget; + m_FlyTarget = cr_Target; + //SetStartTargetPosition(m_FlyTarget.GetFlyTargetPosition()); + + __SetTargetDirection(m_FlyTarget); +} + +void CFlyingInstance::AdjustDirectionForHoming(const D3DXVECTOR3 & v3TargetPosition) +{ + D3DXVECTOR3 vTargetDir(v3TargetPosition); + vTargetDir -= m_v3Position; + D3DXVec3Normalize(&vTargetDir,&vTargetDir); + D3DXVECTOR3 vVel; + D3DXVec3Normalize(&vVel, &m_v3Velocity); + + const auto vv1 = (vVel - vTargetDir); + if (D3DXVec3LengthSq(&vv1) < 0.001f) + return; + + D3DXQUATERNION q = SafeRotationNormalizedArc(vVel,vTargetDir); + + if (m_pData->m_fHomingMaxAngle > 180) + { + Vec3TransformQuaternionSafe(&m_v3Velocity, &m_v3Velocity, &q); + Vec3TransformQuaternionSafe(&m_v3Accel, &m_v3Accel, &q); + D3DXQuaternionMultiply(&m_qRot, &q, &m_qRot); + return; + } + + float c = cosf(D3DXToRadian(m_pData->m_fHomingMaxAngle)); + float s = sinf(D3DXToRadian(m_pData->m_fHomingMaxAngle)); + + if (q.w <= -1.0f + 0.0001f) + { + q.x = 0; + q.y = 0; + q.z = s; + q.w = c; + } + else if (q.w <= c && q.w <= 1.0f - 0.0001f) + { + float factor = s / sqrtf(1.0f - q.w * q.w); + q.x *= factor; + q.y *= factor; + q.z *= factor; + q.w = c; + } + /*else + { + }*/ + Vec3TransformQuaternionSafe(&m_v3Velocity, &m_v3Velocity, &q); + Vec3TransformQuaternionSafe(&m_v3Accel, &m_v3Accel, &q); + D3DXQuaternionMultiply(&m_qRot, &m_qRot, &q); +} + +void CFlyingInstance::UpdateAttachInstance() +{ + // Update Attach Rotation + D3DXQUATERNION q; + D3DXQuaternionRotationYawPitchRoll(&q, + D3DXToRadian(m_pData->m_v3AngVel.y)*CTimer::Instance().GetElapsedSecond(), + D3DXToRadian(m_pData->m_v3AngVel.x)*CTimer::Instance().GetElapsedSecond(), + D3DXToRadian(m_pData->m_v3AngVel.z)*CTimer::Instance().GetElapsedSecond()); + + D3DXQuaternionMultiply(&m_qAttachRotation, &m_qAttachRotation, &q); + D3DXQuaternionMultiply(&q, &m_qAttachRotation, &m_qRot); + + CEffectManager & rem = CEffectManager::Instance(); + TAttachEffectInstanceVector::iterator it; + for(it = m_vecAttachEffectInstance.begin();it!=m_vecAttachEffectInstance.end();++it) + { + CFlyingData::TFlyingAttachData & rfad = m_pData->GetAttachDataReference(it->iAttachIndex); + assert(rfad.iType == CFlyingData::FLY_ATTACH_EFFECT); + rem.SelectEffectInstance(it->dwEffectInstanceIndex); + D3DXMATRIX m; + switch(rfad.iFlyType) + { + case CFlyingData::FLY_ATTACH_TYPE_LINE: + D3DXMatrixRotationQuaternion(&m,&m_qRot); + //D3DXMatrixRotationQuaternion(&m,&q); + m._41=m_v3Position.x; + m._42=m_v3Position.y; + m._43=m_v3Position.z; + break; + case CFlyingData::FLY_ATTACH_TYPE_MULTI_LINE: + { + D3DXVECTOR3 p( + -sinf(D3DXToRadian(rfad.fRoll))*rfad.fDistance, + 0.0f, + -cosf(D3DXToRadian(rfad.fRoll))*rfad.fDistance); + //Vec3TransformQuaternionSafe(&p,&p,&m_qRot); + Vec3TransformQuaternionSafe(&p,&p,&q); + p+=m_v3Position; + //D3DXMatrixRotationQuaternion(&m,&m_qRot); + D3DXMatrixRotationQuaternion(&m,&q); + m._41=p.x; + m._42=p.y; + m._43=p.z; + } + break; + case CFlyingData::FLY_ATTACH_TYPE_SINE: + { + //Tracenf("%f",CTimer::Instance().GetCurrentSecond()); + float angle = (CTimer::Instance().GetCurrentSecond() - m_fStartTime)*2*3.1415926535897931f/rfad.fPeriod; + D3DXVECTOR3 p( + -sinf(D3DXToRadian(rfad.fRoll))*rfad.fAmplitude*sinf(angle), + 0.0f, + -cosf(D3DXToRadian(rfad.fRoll))*rfad.fAmplitude*sinf(angle)); + Vec3TransformQuaternionSafe(&p,&p,&q); + //Vec3TransformQuaternionSafe(&p,&p,&m_qRot); + p+=m_v3Position; + D3DXMatrixRotationQuaternion(&m,&q); + //D3DXMatrixRotationQuaternion(&m,&m_qRot); + m._41=p.x; + m._42=p.y; + m._43=p.z; + //assert(!"NOT IMPLEMENTED"); + } + break; + case CFlyingData::FLY_ATTACH_TYPE_EXP: + { + float dt = CTimer::Instance().GetCurrentSecond() - m_fStartTime; + float angle = dt/rfad.fPeriod; + D3DXVECTOR3 p( + -sinf(D3DXToRadian(rfad.fRoll))*rfad.fAmplitude*exp(-angle)*angle, + 0.0f, + -cosf(D3DXToRadian(rfad.fRoll))*rfad.fAmplitude*exp(-angle)*angle); + //Vec3TransformQuaternionSafe(&p,&p,&m_qRot); + Vec3TransformQuaternionSafe(&p,&p,&q); + p+=m_v3Position; + D3DXMatrixRotationQuaternion(&m,&q); + //D3DXMatrixRotationQuaternion(&m,&m_qRot); + m._41=p.x; + m._42=p.y; + m._43=p.z; + //assert(!"NOT IMPLEMENTED"); + } + break; + } + rem.SetEffectInstanceGlobalMatrix(m); + if (it->pFlyTrace) + it->pFlyTrace->UpdateNewPosition(D3DXVECTOR3(m._41,m._42,m._43)); + } +} +struct FCheckBackgroundDuringFlying { + CDynamicSphereInstance s; + bool bHit; + FCheckBackgroundDuringFlying(const D3DXVECTOR3 & v1, const D3DXVECTOR3 & v2) + { + s.fRadius = 1.0f; + s.v3LastPosition = v1; + s.v3Position = v2; + bHit = false; + } + void operator () (CGraphicObjectInstance * p) + { + if (!p) + return; + + if (!bHit && p->GetType() != ACTOR_OBJECT) + { + if (p->CollisionDynamicSphere(s)) + { + bHit = true; + } + } + } + bool IsHitted() + { + return bHit; + } +}; + +struct FCheckAnotherMonsterDuringFlying { + CDynamicSphereInstance s; + CGraphicObjectInstance * pInst; + const IActorInstance * pOwner; + FCheckAnotherMonsterDuringFlying(const IActorInstance * pOwner, const D3DXVECTOR3 & v1, const D3DXVECTOR3 & v2) + : pOwner(pOwner) + { + s.fRadius = 10.0f; + s.v3LastPosition = v1; + s.v3Position = v2; + pInst = 0; + } + void operator () (CGraphicObjectInstance * p) + { + if (!p) + return; + + if (!pInst && p->GetType() == ACTOR_OBJECT) + { + IActorInstance * pa = (IActorInstance*) p; + if (pa != pOwner && pa->TestCollisionWithDynamicSphere(s)) + { + pInst = p; + } + } + } + bool IsHitted() + { + return pInst!=0; + } + CGraphicObjectInstance * GetHittedObject() + { + return pInst; + } +}; + + +bool CFlyingInstance::Update() +{ + if (!m_bAlive) + return false; + + if (m_pData->m_bIsHoming && + m_pData->m_fHomingStartTime + m_fStartTime < CTimer::Instance().GetCurrentSecond()) + { + if (m_FlyTarget.IsObject()) + AdjustDirectionForHoming(m_FlyTarget.GetFlyTargetPosition()); + } + + D3DXVECTOR3 v3LastPosition = m_v3Position; + + m_v3Velocity += m_v3Accel*CTimer::Instance().GetElapsedSecond(); + m_v3Velocity.z+=m_pData->m_fGravity * CTimer::Instance().GetElapsedSecond(); + D3DXVECTOR3 v3Movement = m_v3Velocity * CTimer::Instance().GetElapsedSecond(); + float _fMoveDistance = D3DXVec3Length(&v3Movement); + float fCollisionSphereRadius = max(_fMoveDistance*2, m_pData->m_fCollisionSphereRadius); + m_fRemainRange -= _fMoveDistance; + m_v3Position += v3Movement; + + UpdateAttachInstance(); + + if (m_fRemainRange<0) + { + if (m_pHandler) + m_pHandler->OnExplodingOutOfRange(); + + __Explode(false); + return false; + } + + if (m_FlyTarget.IsObject()) + { + if (!m_bTargetHitted) + { + if (square_distance_between_linesegment_and_point(m_v3Position,v3LastPosition,m_FlyTarget.GetFlyTargetPosition())m_fBombRange*m_pData->m_fBombRange) + { + m_bTargetHitted = TRUE; + + if (m_canAttack) + { + IFlyTargetableObject* pVictim=m_FlyTarget.GetFlyTarget(); + if (pVictim) + { + pVictim->OnShootDamage(); + } + } + + if (m_pHandler) + { + m_pHandler->OnExplodingAtTarget(m_dwSkillIndex); + } + + if (m_iPierceCount) + { + m_iPierceCount--; + __Bomb(); + } + else + { + __Explode(); + return false; + } + + return true; + } + } + } + else if (m_FlyTarget.IsPosition()) + { + if (square_distance_between_linesegment_and_point(m_v3Position,v3LastPosition,m_FlyTarget.GetFlyTargetPosition())m_fBombRange*m_pData->m_fBombRange) + { + __Explode(); + return false; + } + } + + Vector3d vecStart, vecDir; + vecStart.Set(v3LastPosition.x,v3LastPosition.y,v3LastPosition.z); + vecDir.Set(v3Movement.x,v3Movement.y,v3Movement.z); + + CCullingManager & rkCullingMgr = CCullingManager::Instance(); + + if (m_pData->m_bHitOnAnotherMonster) + { + FCheckAnotherMonsterDuringFlying kCheckAnotherMonsterDuringFlying(m_pOwner, v3LastPosition,m_v3Position); + rkCullingMgr.ForInRange(vecStart,fCollisionSphereRadius, &kCheckAnotherMonsterDuringFlying); + if (kCheckAnotherMonsterDuringFlying.IsHitted()) + { + IActorInstance * pHittedInstance = (IActorInstance*)kCheckAnotherMonsterDuringFlying.GetHittedObject(); + if (m_HittedObjectSet.end() == m_HittedObjectSet.find(pHittedInstance)) + { + m_HittedObjectSet.insert(pHittedInstance); + + if (m_pHandler) + { + m_pHandler->OnExplodingAtAnotherTarget(m_dwSkillIndex, pHittedInstance->GetVirtualID()); + } + + if (m_iPierceCount) + { + m_iPierceCount--; + __Bomb(); + } + else + { + __Explode(); + return false; + } + + return true; + } + } + } + + if (m_pData->m_bHitOnBackground) + { + // 浹 + + if (CFlyingManager::Instance().GetMapManagerPtr()) + { + float fGroundHeight = CFlyingManager::Instance().GetMapManagerPtr()->GetTerrainHeight(m_v3Position.x,-m_v3Position.y); + if (fGroundHeight>m_v3Position.z) + { + if (m_pHandler) + m_pHandler->OnExplodingAtBackground(); + + __Explode(); + return false; + } + } + + // ǹ+ 浹 + + FCheckBackgroundDuringFlying kCheckBackgroundDuringFlying(v3LastPosition,m_v3Position); + rkCullingMgr.ForInRange(vecStart,fCollisionSphereRadius, &kCheckBackgroundDuringFlying); + + if (kCheckBackgroundDuringFlying.IsHitted()) + { + if (m_pHandler) + m_pHandler->OnExplodingAtBackground(); + + __Explode(); + return false; + } + } + + return true; +} + +void CFlyingInstance::ClearAttachInstance() +{ + CEffectManager & rkEftMgr = CEffectManager::Instance(); + + TAttachEffectInstanceVector::iterator i; + for(i = m_vecAttachEffectInstance.begin();i!=m_vecAttachEffectInstance.end();++i) + { + rkEftMgr.DestroyEffectInstance(i->dwEffectInstanceIndex); + + if (i->pFlyTrace) + CFlyTrace::Delete(i->pFlyTrace); + + i->iAttachIndex=0; + i->dwEffectInstanceIndex=0; + i->pFlyTrace=NULL; + } + m_vecAttachEffectInstance.clear(); +} + +void CFlyingInstance::__Explode(bool bBomb) +{ + if (!m_bAlive) + return; + + m_bAlive = false; + + if (bBomb) + __Bomb(); +} + +void CFlyingInstance::__Bomb() +{ + CEffectManager & rkEftMgr = CEffectManager::Instance(); + if (!m_pData->m_dwBombEffectID) + return; + + DWORD dwEmptyIndex = rkEftMgr.GetEmptyIndex(); + rkEftMgr.CreateEffectInstance(dwEmptyIndex,m_pData->m_dwBombEffectID); + + D3DXMATRIX m; +// D3DXMatrixRotationQuaternion(&m,&m_qRot); + D3DXMatrixIdentity(&m); + m._41 = m_v3Position.x; + m._42 = m_v3Position.y; + m._43 = m_v3Position.z; + rkEftMgr.SelectEffectInstance(dwEmptyIndex); + rkEftMgr.SetEffectInstanceGlobalMatrix(m); +} + +void CFlyingInstance::Render() +{ + if (!m_bAlive) + return; + RenderAttachInstance(); +} + +void CFlyingInstance::RenderAttachInstance() +{ + TAttachEffectInstanceVector::iterator it; + for(it = m_vecAttachEffectInstance.begin();it!=m_vecAttachEffectInstance.end();++it) + { + if (it->pFlyTrace) + it->pFlyTrace->Render(); + } +} + +void CFlyingInstance::SetDataPointer(CFlyingData * pData, const D3DXVECTOR3 & v3StartPosition) +{ + __SetDataPointer(pData, v3StartPosition); +} + +void CFlyingInstance::__SetDataPointer(CFlyingData * pData, const D3DXVECTOR3 & v3StartPosition) +{ + m_pData = pData; + m_qRot = D3DXQUATERNION(0.0f,0.0f,0.0f,1.0f), + m_v3Position = (v3StartPosition); + m_bAlive = (true); + + m_fStartTime = CTimer::Instance().GetCurrentSecond(); + + D3DXQuaternionRotationYawPitchRoll(&m_qRot,D3DXToRadian(pData->m_fRollAngle-90.0f),0.0f,D3DXToRadian(pData->m_fConeAngle)); + if (pData->m_bSpreading) + { + D3DXQUATERNION q1, q2; + const auto vv1 = D3DXVECTOR3(0.0f, 0.0f, 1.0f), vv2 = D3DXVECTOR3(0.0f, -1.0f, 0.0f); + D3DXQuaternionRotationAxis(&q2, &vv1,(frandom(-3.141592f/3,+3.141592f/3)+frandom(-3.141592f/3,+3.141592f/3))/2); + D3DXQuaternionRotationAxis(&q1, &vv2, frandom(0,2*3.1415926535897931f)); + D3DXQuaternionMultiply(&q1,&q2,&q1); + D3DXQuaternionMultiply(&m_qRot,&q1,&m_qRot); + } + m_v3Velocity = m_v3LocalVelocity = D3DXVECTOR3(0.0f,-pData->m_fInitVel,0.0f); + m_v3Accel = pData->m_v3Accel; + m_fRemainRange = pData->m_fRange; + m_qAttachRotation = D3DXQUATERNION(0.0f,0.0f,0.0f,1.0f); + + BuildAttachInstance(); + UpdateAttachInstance(); + + m_iPierceCount = pData->m_iPierceCount; +} diff --git a/source/GameLib/FlyingInstance.h b/source/GameLib/FlyingInstance.h new file mode 100644 index 0000000..33db165 --- /dev/null +++ b/source/GameLib/FlyingInstance.h @@ -0,0 +1,111 @@ +#pragma once + +#include "FlyTarget.h" +#include "ActorInstanceInterface.h" + +class CFlyingData; +class CFlyTrace; +class IFlyEventHandler; +class CActorInstance; + +class CFlyingInstance +{ +public: + // 2004. 3. 26. myevan. ̹ ʿ. ӿ ʴ´ٸ ӹ޾ 鵵 + void Clear(); // Destroy + void SetDataPointer(CFlyingData * pData, const D3DXVECTOR3 & v3StartPosition); + void SetFlyTarget(const CFlyTarget & cr_Target); // Shot at Target + +public: + friend class CSceneFly; + + struct TAttachEffectInstance + { + int iAttachIndex; + DWORD dwEffectInstanceIndex; + + CFlyTrace * pFlyTrace; + }; + + CFlyingInstance(); + virtual ~CFlyingInstance(); + + void Destroy(); + void Create(CFlyingData* pData, const D3DXVECTOR3& c_rv3StartPos, const CFlyTarget & c_rkTarget, bool canAttack); + + bool Update(); + void Render(); + + bool IsAlive() { return m_bAlive; } + + const D3DXVECTOR3 & GetPosition() { return m_v3Position; } + + void AdjustDirectionForHoming(const D3DXVECTOR3 & v3TargetPosition); + + typedef std::vector TAttachEffectInstanceVector; + + void BuildAttachInstance(); + void UpdateAttachInstance(); + void RenderAttachInstance(); + void ClearAttachInstance(); + + void SetEventHandler(IFlyEventHandler * pHandler) { m_pHandler = pHandler; } + void ClearEventHandler() { m_pHandler = 0; } + + void SetPierceCount(int iCount) { m_iPierceCount = iCount; } + void SetOwner(IActorInstance * pOwner) { m_pOwner = pOwner; } + void SetSkillIndex(DWORD dwIndex) { m_dwSkillIndex = dwIndex; } + + // FIXME : ϰ ֽϴ. ӽ÷ .. - [levites] + void __Explode(bool bBomb=true); + void __Bomb(); + + DWORD ID; + +protected: + void __Initialize(); + + void __SetDataPointer(CFlyingData * pData, const D3DXVECTOR3 & v3StartPosition); + void __SetTargetDirection(const CFlyTarget& c_rkTarget); + void __SetTargetNormalizedDirection(const D3DXVECTOR3 & v3NormalizedDirection ); // Ÿ + +protected: + + CFlyingData * m_pData; + D3DXQUATERNION m_qRot; + + float m_fStartTime; + + bool m_bAlive; + bool m_canAttack; + + int m_iPierceCount; + DWORD m_dwSkillIndex; + + D3DXVECTOR3 m_v3Position; + D3DXVECTOR3 m_v3Velocity; + D3DXVECTOR3 m_v3LocalVelocity; + D3DXVECTOR3 m_v3Accel; + + float m_fRemainRange; + + CFlyTarget m_FlyTarget; + + D3DXQUATERNION m_qAttachRotation; + TAttachEffectInstanceVector m_vecAttachEffectInstance; + + IFlyEventHandler * m_pHandler; + + IActorInstance * m_pOwner; + + BOOL m_bTargetHitted; + std::set m_HittedObjectSet; + +public: + static CFlyingInstance * New() { return ms_kPool.Alloc(); } + static void Delete(CFlyingInstance * pInstance) { pInstance->Destroy(); ms_kPool.Free(pInstance); } + + static void DestroySystem() { ms_kPool.Destroy(); } + + static CDynamicPool ms_kPool; +}; diff --git a/source/GameLib/FlyingObjectManager.cpp b/source/GameLib/FlyingObjectManager.cpp new file mode 100644 index 0000000..afe063e --- /dev/null +++ b/source/GameLib/FlyingObjectManager.cpp @@ -0,0 +1,214 @@ +#include "Stdafx.h" + +#include "FlyingData.h" +#include "FlyingInstance.h" +#include "FlyingObjectManager.h" + +#include "ActorInstance.h" + +CFlyingManager::CFlyingManager() +{ + m_pMapManager = 0; +} + +CFlyingManager::~CFlyingManager() +{ + Destroy(); +} + +void CFlyingManager::__DestroyFlyingInstanceList() +{ + TFlyingInstanceList::iterator i; + for(i = m_kLst_pkFlyInst.begin(); i!=m_kLst_pkFlyInst.end(); ++i) + { + CFlyingInstance* pkFlyInst=*i; + CFlyingInstance::Delete(pkFlyInst); + } + m_kLst_pkFlyInst.clear(); +} + +void CFlyingManager::__DestroyFlyingDataMap() +{ + TFlyingDataMap::iterator i; + for(i = m_kMap_pkFlyData.begin(); i != m_kMap_pkFlyData.end(); ++i) + { + CFlyingData* pkFlyData=i->second; + CFlyingData::Delete(pkFlyData); + } + m_kMap_pkFlyData.clear(); +} + + +void CFlyingManager::DeleteAllInstances() +{ + __DestroyFlyingInstanceList(); +} + +void CFlyingManager::Destroy() +{ + __DestroyFlyingInstanceList(); + __DestroyFlyingDataMap(); + + m_pMapManager = 0; +} + +bool CFlyingManager::RegisterFlyingData(const char* c_szFilename) +{ + std::string s; + StringPath(c_szFilename,s); + DWORD dwRetCRC = GetCaseCRC32(s.c_str(),s.size()); + + if (m_kMap_pkFlyData.find(dwRetCRC) != m_kMap_pkFlyData.end()) + { + return false; + } + + CFlyingData * pFlyingData = CFlyingData::New(); + if (!pFlyingData->LoadScriptFile(c_szFilename)) + { + Tracenf("CEffectManager::RegisterFlyingData %s - Failed to load flying data file", c_szFilename); + CFlyingData::Delete(pFlyingData); + return false; + } + + m_kMap_pkFlyData.insert(std::make_pair(dwRetCRC,pFlyingData)); + return true; +} + +bool CFlyingManager::RegisterFlyingData(const char* c_szFilename, DWORD & r_dwRetCRC) +{ + std::string s; + StringPath(c_szFilename,s); + r_dwRetCRC = GetCaseCRC32(s.c_str(),s.size()); + + if (m_kMap_pkFlyData.find(r_dwRetCRC) != m_kMap_pkFlyData.end()) + { + TraceError("CFlyingManager::RegisterFlyingData - Already exists flying data named [%s]", c_szFilename); + return false; + } + + CFlyingData * pFlyingData = CFlyingData::New(); + if (!pFlyingData->LoadScriptFile(c_szFilename)) + { + TraceError("CEffectManager::RegisterFlyingData %s - Failed to load flying data file", c_szFilename); + CFlyingData::Delete(pFlyingData); + return false; + + } + + m_kMap_pkFlyData.insert(std::make_pair(r_dwRetCRC,pFlyingData)); + return true; +} + +CFlyingInstance * CFlyingManager::CreateFlyingInstanceFlyTarget(const DWORD dwID, + const D3DXVECTOR3 & v3StartPosition, + const CFlyTarget & cr_FlyTarget, + bool canAttack) +{ + if (m_kMap_pkFlyData.find(dwID) == m_kMap_pkFlyData.end()) + { + //TraceError("CFlyingManager::CreateFlyingInstanceFlyTarget - No data with CRC [%d]", dwID); + return NULL; + } + + CFlyingInstance * pFlyingInstance = CFlyingInstance::New(); + pFlyingInstance->Create(m_kMap_pkFlyData[dwID], v3StartPosition, cr_FlyTarget, canAttack); + + m_kLst_pkFlyInst.push_back(pFlyingInstance); + + pFlyingInstance->ID = m_IDCounter++; + return pFlyingInstance; +} + +void CFlyingManager::Update() +{ + TFlyingInstanceList::iterator i=m_kLst_pkFlyInst.begin(); + + while (i!=m_kLst_pkFlyInst.end()) + { + CFlyingInstance* pkFlyInst=*i; + if (!pkFlyInst->Update()) + { + CFlyingInstance::Delete(pkFlyInst); + i=m_kLst_pkFlyInst.erase(i); + } + else + { + ++i; + } + } +} + +void CFlyingManager::Render() +{ + std::for_each(m_kLst_pkFlyInst.begin(), m_kLst_pkFlyInst.end(), std::mem_fn(&CFlyingInstance::Render)); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// + +bool CFlyingManager::RegisterIndexedFlyData(DWORD dwIndex, BYTE byType, const char * c_szFileName) +{ + DWORD dwCRC; + if (!RegisterFlyingData(c_szFileName, dwCRC)) + { + TraceError("CFlyingManager::RegisterIndexFlyData(dwIndex=%d, c_szFileName=%s) - Failed to load flying data file", dwIndex, c_szFileName); + return false; + } + + TIndexFlyData IndexFlyData; + IndexFlyData.byType = byType; + IndexFlyData.dwCRC = dwCRC; + m_kMap_dwIndexFlyData.insert(std::make_pair(dwIndex, IndexFlyData)); + + return true; +} + +void CFlyingManager::CreateIndexedFly(DWORD dwIndex, CActorInstance * pStartActor, CActorInstance * pEndActor) +{ + if (m_kMap_dwIndexFlyData.end() == m_kMap_dwIndexFlyData.find(dwIndex)) + { + TraceError("CFlyingManager::CreateIndexedFly(dwIndex=%d) - Not registered index", dwIndex); + return; + } + + TPixelPosition posStart; + pStartActor->GetPixelPosition(&posStart); + + TIndexFlyData & rIndexFlyData = m_kMap_dwIndexFlyData[dwIndex]; + switch (rIndexFlyData.byType) + { + case INDEX_FLY_TYPE_NORMAL: + { + CreateFlyingInstanceFlyTarget(rIndexFlyData.dwCRC, + D3DXVECTOR3(posStart.x, posStart.y, posStart.z), + pEndActor, + false); + break; + } + case INDEX_FLY_TYPE_FIRE_CRACKER: + { + float fRot = fmod(pStartActor->GetRotation() - 90.0f + 360.0f, 360.0f) + frandom(-30.0f, 30.0f); + + float fDistance = frandom(2000.0f, 5000.0f); + float fxRand = fDistance * cosf(D3DXToRadian(fRot)); + float fyRand = fDistance * sinf(D3DXToRadian(fRot)); + float fzRand = frandom(1000.0f, 2500.0f); + + CreateFlyingInstanceFlyTarget(rIndexFlyData.dwCRC, + D3DXVECTOR3(posStart.x, posStart.y, posStart.z+200), + D3DXVECTOR3(posStart.x + fxRand, posStart.y + fyRand, posStart.z + fzRand), + false); + break; + } + case INDEX_FLY_TYPE_AUTO_FIRE: + { + CreateFlyingInstanceFlyTarget(rIndexFlyData.dwCRC, + D3DXVECTOR3(posStart.x, posStart.y, posStart.z+100.0f), + pEndActor, + false); + break; + } + } +} diff --git a/source/GameLib/FlyingObjectManager.h b/source/GameLib/FlyingObjectManager.h new file mode 100644 index 0000000..548eb20 --- /dev/null +++ b/source/GameLib/FlyingObjectManager.h @@ -0,0 +1,66 @@ +#pragma once + +#include "FlyTarget.h" + +#include + +class CFlyingInstance; +class CFlyingData; +class CMapManager; +class CActorInstance; + +class CFlyingManager : public CSingleton +{ +public: + enum EIndexFlyType + { + INDEX_FLY_TYPE_NORMAL, + INDEX_FLY_TYPE_FIRE_CRACKER, + INDEX_FLY_TYPE_AUTO_FIRE, + }; + +public: + CFlyingManager(); + virtual ~CFlyingManager(); + + void Destroy(); + + void DeleteAllInstances(); + + bool RegisterFlyingData(const char* c_szFilename); + bool RegisterFlyingData(const char* c_szFilename, DWORD & r_dwRetCRC); + + CFlyingInstance * CreateFlyingInstanceFlyTarget(const DWORD dwID, const D3DXVECTOR3 & v3StartPosition, const CFlyTarget & cr_FlyTarget, bool canAttack); + + void Update(); + void Render(); + + void SetMapManagerPtr(CMapManager * pMapManager) { m_pMapManager = pMapManager; } + CMapManager * GetMapManagerPtr() { return m_pMapManager; } + +public: // Controlled by Server + bool RegisterIndexedFlyData(DWORD dwIndex, BYTE byType, const char * c_szFileName); + void CreateIndexedFly(DWORD dwIndex, CActorInstance * pStartActor, CActorInstance * pEndActor); + +private: + void __DestroyFlyingInstanceList(); + void __DestroyFlyingDataMap(); + + typedef std::map TFlyingDataMap; + typedef std::list TFlyingInstanceList; + + typedef struct SIndexFlyData + { + BYTE byType; + DWORD dwCRC; + } TIndexFlyData; + typedef std::map TIndexFlyDataMap; + + TFlyingDataMap m_kMap_pkFlyData; + TFlyingInstanceList m_kLst_pkFlyInst; + TIndexFlyDataMap m_kMap_dwIndexFlyData; + + CMapManager * m_pMapManager; + + DWORD m_IDCounter; +}; diff --git a/source/GameLib/GameEventManager.cpp b/source/GameLib/GameEventManager.cpp new file mode 100644 index 0000000..8af24ed --- /dev/null +++ b/source/GameLib/GameEventManager.cpp @@ -0,0 +1,36 @@ +#include "StdAfx.h" +#include "GameEventManager.h" + +void CGameEventManager::SetCenterPosition(float fx, float fy, float fz) +{ + m_CenterPosition.x = +fx; + m_CenterPosition.y = -fy; + m_CenterPosition.z = +fz; +} + +void CGameEventManager::Update() +{ +} + +void CGameEventManager::ProcessEventScreenWaving(CActorInstance * pActorInstance, const CRaceMotionData::TScreenWavingEventData * c_pData) +{ + TPixelPosition PixelPosition; + pActorInstance->GetPixelPosition(&PixelPosition); + + float fdx = PixelPosition.x - m_CenterPosition.x; + float fdy = PixelPosition.y - m_CenterPosition.y; + float fdz = PixelPosition.z - m_CenterPosition.z; + + if (fdx * fdx + fdy * fdy + fdz * fdz > c_pData->iAffectingRange * c_pData->iAffectingRange) + return; + + SetScreenEffectWaving(c_pData->fDurationTime, c_pData->iPower); +} + +CGameEventManager::CGameEventManager() : m_CenterPosition(0.0f, 0.0f, 0.0f) +{ +} + +CGameEventManager::~CGameEventManager() +{ +} diff --git a/source/GameLib/GameEventManager.h b/source/GameLib/GameEventManager.h new file mode 100644 index 0000000..8fe95a7 --- /dev/null +++ b/source/GameLib/GameEventManager.h @@ -0,0 +1,28 @@ +#pragma once + +#include "ActorInstance.h" + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// CGameEventManager +// +// Note : Game󿡼 Ͼ , ȭ 鸲, Range Ӱ Ÿ Event +// ϴ Ŭ. - [levites] +// +// Note : ӻ Cinematic Event Ʈϴ Ŵ Ѵ. 2004.07.19 - [levites] +// + +class CGameEventManager : public CSingleton, public CScreen +{ + public: + CGameEventManager(); + virtual ~CGameEventManager(); + + void SetCenterPosition(float fx, float fy, float fz); + void Update(); + + void ProcessEventScreenWaving(CActorInstance * pActorInstance, const CRaceMotionData::TScreenWavingEventData * c_pData); + + protected: + TPixelPosition m_CenterPosition; +}; diff --git a/source/GameLib/GameType.cpp b/source/GameLib/GameType.cpp new file mode 100644 index 0000000..4ffc3d5 --- /dev/null +++ b/source/GameLib/GameType.cpp @@ -0,0 +1,362 @@ +#include "StdAfx.h" +#include "GameType.h" +#include "../effectLib/EffectManager.h" + +extern float g_fGameFPS = 60.0f; + +CDynamicPool NRaceData::g_CollisionDataPool; +CDynamicPool NRaceData::g_EffectDataPool; +CDynamicPool NRaceData::g_ObjectDataPool; + +void NRaceData::DestroySystem() +{ + g_CollisionDataPool.Destroy(); + g_EffectDataPool.Destroy(); + g_ObjectDataPool.Destroy(); +} + +///////////////////////////////////////////////////////////////////////////////// +// Character Attaching Collision Data +BOOL NRaceData::LoadAttackData(CTextFileLoader & rTextFileLoader, TAttackData * pData) +{ + if (!rTextFileLoader.GetTokenInteger("attacktype", &pData->iAttackType)) + { + pData->iAttackType = ATTACK_TYPE_SPLASH; + } + if (!rTextFileLoader.GetTokenInteger("hittingtype", &pData->iHittingType)) + return false; + if (!rTextFileLoader.GetTokenFloat("stiffentime", &pData->fStiffenTime)) + return false; + if (!rTextFileLoader.GetTokenFloat("invisibletime", &pData->fInvisibleTime)) + return false; + if (!rTextFileLoader.GetTokenFloat("externalforce", &pData->fExternalForce)) + return false; + if (!rTextFileLoader.GetTokenInteger("hitlimitcount", &pData->iHitLimitCount)) + { + pData->iHitLimitCount = 0; + } + + return true; +} + +bool NRaceData::THitData::Load(CTextFileLoader & rTextFileLoader) +{ + if (!rTextFileLoader.GetTokenFloat("attackingstarttime", &fAttackStartTime)) + return false; + if (!rTextFileLoader.GetTokenFloat("attackingendtime", &fAttackEndTime)) + return false; + + if (!rTextFileLoader.GetTokenString("attackingbone", &strBoneName)) + strBoneName = ""; + if (!rTextFileLoader.GetTokenFloat("weaponlength",&fWeaponLength)) + fWeaponLength = 0.0f; + + mapHitPosition.clear(); + + CTokenVector * tv; + if (rTextFileLoader.GetTokenVector("hitposition",&tv)) + { + CTokenVector::iterator it=tv->begin(); + + while(it!=tv->end()) + { + float time; + NRaceData::THitTimePosition hp; + time = atof(it++->c_str()); + hp.v3LastPosition.x = atof(it++->c_str()); + hp.v3LastPosition.y = atof(it++->c_str()); + hp.v3LastPosition.z = atof(it++->c_str()); + hp.v3Position.x = atof(it++->c_str()); + hp.v3Position.y = atof(it++->c_str()); + hp.v3Position.z = atof(it++->c_str()); + + mapHitPosition[time] = hp; + } + } + + return true; +} + +BOOL NRaceData::LoadMotionAttackData(CTextFileLoader & rTextFileLoader, TMotionAttackData * pData) +{ + if (!LoadAttackData(rTextFileLoader, pData)) + return FALSE; + + // NOTE : AttackingType MotionType ٲ + // Ÿ аԲ.. + if (!rTextFileLoader.GetTokenInteger("motiontype", &pData->iMotionType)) + { + if (!rTextFileLoader.GetTokenInteger("attackingtype", &pData->iMotionType)) + return FALSE; + } + + pData->HitDataContainer.clear(); + + DWORD dwHitDataCount; + if (!rTextFileLoader.GetTokenDoubleWord("hitdatacount", &dwHitDataCount)) + { + pData->HitDataContainer.push_back(SHitData()); + THitData & rHitData = *(pData->HitDataContainer.rbegin()); + if (!rHitData.Load(rTextFileLoader)) + return FALSE; + } + else + { + for (DWORD i = 0; i < dwHitDataCount; ++i) + { + if (!rTextFileLoader.SetChildNode(i)) + return FALSE; + + pData->HitDataContainer.push_back(SHitData()); + THitData & rHitData = *(pData->HitDataContainer.rbegin()); + if (!rHitData.Load(rTextFileLoader)) + return FALSE; + + rTextFileLoader.SetParentNode(); + } + } + + return TRUE; +} + +BOOL NRaceData::LoadCollisionData(CTextFileLoader & rTextFileLoader, TCollisionData * pCollisionData) +{ + if (!rTextFileLoader.GetTokenInteger("collisiontype", &pCollisionData->iCollisionType)) + return false; + + DWORD dwSphereDataCount; + if (!rTextFileLoader.GetTokenDoubleWord("spheredatacount", &dwSphereDataCount)) + return false; + + pCollisionData->SphereDataVector.clear(); + pCollisionData->SphereDataVector.resize(dwSphereDataCount); + for (DWORD i = 0; i < dwSphereDataCount; ++i) + { + TSphereData & r = pCollisionData->SphereDataVector[i].GetAttribute(); + + if (!rTextFileLoader.SetChildNode("spheredata", i)) + return false; + + if (!rTextFileLoader.GetTokenFloat("radius", &r.fRadius)) + return false; + if (!rTextFileLoader.GetTokenPosition("position", &r.v3Position)) + return false; + + rTextFileLoader.SetParentNode(); + } + + return true; +} + +void NRaceData::SaveEffectData(FILE * File, int iTabCount, const TAttachingEffectData & c_rEffectData) +{ + PrintfTabs(File, iTabCount, "EffectScriptName \"%s\"\n", c_rEffectData.strFileName.c_str()); + + PrintfTabs(File, iTabCount, "EffectPosition %f %f %f\n", c_rEffectData.v3Position.x, c_rEffectData.v3Position.y, c_rEffectData.v3Position.z); + PrintfTabs(File, iTabCount, "EffectRotation %f %f %f\n", c_rEffectData.v3Rotation.x, c_rEffectData.v3Rotation.y, c_rEffectData.v3Rotation.z); +} + +void NRaceData::SaveObjectData(FILE * File, int iTabCount, const TAttachingObjectData & c_rObjectData) +{ + PrintfTabs(File, iTabCount, "ObjectScriptName \"%s\"\n", c_rObjectData.strFileName.c_str()); +} + +BOOL NRaceData::LoadEffectData(CTextFileLoader & rTextFileLoader, TAttachingEffectData * pEffectData) +{ + if (!rTextFileLoader.GetTokenString("effectscriptname",&pEffectData->strFileName)) + return false; + + if (!rTextFileLoader.GetTokenPosition("effectposition",&pEffectData->v3Position)) + { + pEffectData->v3Position = D3DXVECTOR3(0.0f,0.0f,0.0f); + } + + if (!rTextFileLoader.GetTokenPosition("effectrotation",&pEffectData->v3Rotation)) + { + //pEffectData->qRotation = D3DXQUATERNION(0.0f,0.0f,0.0f,1.0f); + pEffectData->v3Rotation = D3DXVECTOR3(0.0f,0.0f,0.0f); + } + + /*if (!*/ + // TODO DELETEME FIXME + CEffectManager::Instance().RegisterEffect(pEffectData->strFileName.c_str()); + /*) return false;*/ + + return true; +} + +BOOL NRaceData::LoadObjectData(CTextFileLoader & rTextFileLoader, TAttachingObjectData * pObjectData) +{ + if (!rTextFileLoader.GetTokenString("objectscriptname",&pObjectData->strFileName)) + return false; + + return true; +} + +void NRaceData::SaveAttackData(FILE * File, int iTabCount, const TAttackData & c_rData) +{ + PrintfTabs(File, iTabCount, "AttackType %d\n", c_rData.iAttackType); + PrintfTabs(File, iTabCount, "HittingType %d\n", c_rData.iHittingType); + PrintfTabs(File, iTabCount, "StiffenTime %f\n", c_rData.fStiffenTime); + PrintfTabs(File, iTabCount, "InvisibleTime %f\n", c_rData.fInvisibleTime); + PrintfTabs(File, iTabCount, "ExternalForce %f\n", c_rData.fExternalForce); + PrintfTabs(File, iTabCount, "HitLimitCount %d\n", c_rData.iHitLimitCount); +} + +void NRaceData::SaveMotionAttackData(FILE * File, int iTabCount, const TMotionAttackData & c_rData) +{ + SaveAttackData(File, iTabCount, c_rData); + + PrintfTabs(File, iTabCount, "\n"); + PrintfTabs(File, iTabCount, "MotionType %d\n", c_rData.iMotionType); + PrintfTabs(File, iTabCount, "HitDataCount %d\n", c_rData.HitDataContainer.size()); + + DWORD dwHitDataNumber = 0; + THitDataContainer::const_iterator itor = c_rData.HitDataContainer.begin(); + for (; itor != c_rData.HitDataContainer.end(); ++itor, ++dwHitDataNumber) + { + const THitData & c_rHitData = *itor; + + PrintfTabs(File, iTabCount, "Group HitData%02d\n", dwHitDataNumber); + PrintfTabs(File, iTabCount, "{\n"); + PrintfTabs(File, iTabCount+1, "AttackingStartTime %f\n", c_rHitData.fAttackStartTime); + PrintfTabs(File, iTabCount+1, "AttackingEndTime %f\n", c_rHitData.fAttackEndTime); + + PrintfTabs(File, iTabCount+1, "AttackingBone \"%s\"\n", c_rHitData.strBoneName.c_str()); + PrintfTabs(File, iTabCount+1, "WeaponLength %f\n", c_rHitData.fWeaponLength); + PrintfTabs(File, iTabCount+1, "List HitPosition\n"); + PrintfTabs(File, iTabCount+1, "{\n"); + + NRaceData::THitTimePositionMap::const_iterator it; + for(it = c_rHitData.mapHitPosition.begin(); it!= c_rHitData.mapHitPosition.end();++it) + { + PrintfTabs(File, iTabCount+2, "%f %f %f %f %f %f %f\n", it->first, + it->second.v3LastPosition.x, it->second.v3LastPosition.y, it->second.v3LastPosition.z, + it->second.v3Position.x, it->second.v3Position.y, it->second.v3Position.z); + } + PrintfTabs(File, iTabCount+1, "}\n"); + PrintfTabs(File, iTabCount, "}\n"); + } +} + +void NRaceData::SaveCollisionData(FILE * File, int iTabCount, const TCollisionData & c_rCollisionData) +{ + PrintfTabs(File, iTabCount, "CollisionType %d\n", c_rCollisionData.iCollisionType); + PrintfTabs(File, iTabCount, "\n"); + + const CSphereCollisionInstanceVector & c_rSphereDataVector = c_rCollisionData.SphereDataVector; + + PrintfTabs(File, iTabCount, "SphereDataCount %d\n", c_rSphereDataVector.size()); + + for (DWORD i = 0; i < c_rSphereDataVector.size(); ++i) + { + const TSphereData & c_rAttr = c_rSphereDataVector[i].GetAttribute(); + + PrintfTabs(File, iTabCount, "Group SphereData%02d\n", i); + + PrintfTabs(File, iTabCount, "{\n"); + + PrintfTabs(File, iTabCount+1, "Radius %f\n", + c_rAttr.fRadius); + + PrintfTabs(File, iTabCount+1, "Position %f %f %f\n", + c_rAttr.v3Position.x, + c_rAttr.v3Position.y, + c_rAttr.v3Position.z); + + PrintfTabs(File, iTabCount, "}\n"); + } +} + +///////////////////////////////////////////////////////////////////////////////// +// Attaching Data +void NRaceData::SaveAttachingData(FILE * File, int iTabCount, const TAttachingDataVector & c_rAttachingDataVector) +{ + DWORD dwAttachingDataCount = c_rAttachingDataVector.size(); + + PrintfTabs(File, iTabCount, "AttachingDataCount %d\n", dwAttachingDataCount); + PrintfTabs(File, iTabCount, "\n"); + + for (DWORD i = 0; i < dwAttachingDataCount; ++i) + { + const NRaceData::TAttachingData & c_rAttachingData = c_rAttachingDataVector[i]; + + PrintfTabs(File, iTabCount, "Group AttachingData%02d\n", i); + PrintfTabs(File, iTabCount, "{\n", i); + + PrintfTabs(File, iTabCount+1, "AttachingDataType %d\n", c_rAttachingData.dwType); + PrintfTabs(File, iTabCount+1, "\n", i); + + PrintfTabs(File, iTabCount+1, "isAttaching %d\n", c_rAttachingData.isAttaching); + PrintfTabs(File, iTabCount+1, "AttachingModelIndex %d\n", c_rAttachingData.dwAttachingModelIndex); + PrintfTabs(File, iTabCount+1, "AttachingBoneName \"%s\"\n", c_rAttachingData.strAttachingBoneName.c_str()); + PrintfTabs(File, iTabCount+1, "\n"); + + switch (c_rAttachingData.dwType) + { + case NRaceData::ATTACHING_DATA_TYPE_COLLISION_DATA: + NRaceData::SaveCollisionData(File, iTabCount+1, *c_rAttachingData.pCollisionData); + break; + case NRaceData::ATTACHING_DATA_TYPE_EFFECT: + NRaceData::SaveEffectData(File, iTabCount+1, *c_rAttachingData.pEffectData); + break; + case NRaceData::ATTACHING_DATA_TYPE_OBJECT: + NRaceData::SaveObjectData(File, iTabCount+1, *c_rAttachingData.pObjectData); + break; + } + + PrintfTabs(File, iTabCount, "}\n"); + + if (i != dwAttachingDataCount-1) + PrintfTabs(File, iTabCount, "\n"); + } +} + +BOOL NRaceData::LoadAttachingData(CTextFileLoader & rTextFileLoader, TAttachingDataVector * pAttachingDataVector) +{ + DWORD dwDataCount; + if (!rTextFileLoader.GetTokenDoubleWord("attachingdatacount", &dwDataCount)) + return false; + + pAttachingDataVector->clear(); + pAttachingDataVector->resize(dwDataCount); + + for (DWORD i = 0; i < dwDataCount; ++i) + { + NRaceData::TAttachingData & rAttachingData = pAttachingDataVector->at(i); + if (!rTextFileLoader.SetChildNode("attachingdata", i)) + return false; + + if (!rTextFileLoader.GetTokenDoubleWord("attachingdatatype", &rAttachingData.dwType)) + return false; + + if (!rTextFileLoader.GetTokenInteger("isattaching", &rAttachingData.isAttaching)) + return false; + if (!rTextFileLoader.GetTokenDoubleWord("attachingmodelindex", &rAttachingData.dwAttachingModelIndex)) + return false; + if (!rTextFileLoader.GetTokenString("attachingbonename", &rAttachingData.strAttachingBoneName)) + return false; + + switch (rAttachingData.dwType) + { + case NRaceData::ATTACHING_DATA_TYPE_COLLISION_DATA: + rAttachingData.pCollisionData = g_CollisionDataPool.Alloc(); + if (!NRaceData::LoadCollisionData(rTextFileLoader, rAttachingData.pCollisionData)) + return false; + break; + case NRaceData::ATTACHING_DATA_TYPE_EFFECT: + rAttachingData.pEffectData = g_EffectDataPool.Alloc(); + if (!NRaceData::LoadEffectData(rTextFileLoader, rAttachingData.pEffectData)) + return false; + break; + case NRaceData::ATTACHING_DATA_TYPE_OBJECT: + rAttachingData.pObjectData = g_ObjectDataPool.Alloc(); + if (!NRaceData::LoadObjectData(rTextFileLoader, rAttachingData.pObjectData)) + return false; + break; + } + + rTextFileLoader.SetParentNode(); + } + return TRUE; +} diff --git a/source/GameLib/GameType.h b/source/GameLib/GameType.h new file mode 100644 index 0000000..4919b5b --- /dev/null +++ b/source/GameLib/GameType.h @@ -0,0 +1,195 @@ +#pragma once + +#include + +#include "../eterLib/TextFileLoader.h" +#include "../eterLib/CollisionData.h" + +extern float g_fGameFPS; + +extern std::string g_strResourcePath; +extern std::string g_strImagePath; + +// Motion Key +#define MOTION_KEY DWORD +#define MAKE_MOTION_KEY(mode, index) (((DWORD)(((BYTE)(mode)) << 24) | ((DWORD)((WORD)(index))) << 8) | ((DWORD)((BYTE)(0)))) +#define MAKE_RANDOM_MOTION_KEY(mode, index, type) (((DWORD)(((BYTE)(mode)) << 24) | ((DWORD)((WORD)(index))) << 8) | ((DWORD)((BYTE)(type)))) +#define GET_MOTION_MODE(key) ((BYTE)(((DWORD)(key) >> 24) & 0xFF)) +#define GET_MOTION_INDEX(key) ((WORD)(((DWORD)(key) >> 8) & 0xFFFF)) +#define GET_MOTION_SUB_INDEX(key) ((BYTE)(((DWORD)(key)) & 0xFF)) +/* +#define MAKE_MOTION_KEY(mode, index) MAKELONG(index, mode) +#define GET_MOTION_MODE(key) HIWORD(key) +#define GET_MOTION_INDEX(key) LOWORD(key) +*/ + +// Race Data +namespace NRaceData +{ + enum EJobs + { + JOB_WARRIOR, + JOB_ASSASSIN, + JOB_SURA, + JOB_SHAMAN, + JOB_MAX_NUM + }; + + // Character Attacking Data + enum EAttackType + { + ATTACK_TYPE_SPLASH, + ATTACK_TYPE_SNIPE, + }; + enum EHitType + { + HIT_TYPE_NONE, + HIT_TYPE_GREAT, + HIT_TYPE_GOOD, + }; + enum EMotionType + { + MOTION_TYPE_NONE, + MOTION_TYPE_NORMAL, + MOTION_TYPE_COMBO, + MOTION_TYPE_SKILL, + }; + + typedef CDynamicSphereInstance THitTimePosition; + typedef std::map THitTimePositionMap; + + typedef struct SAttackData + { + int iAttackType; + int iHittingType; + float fInvisibleTime; + float fExternalForce; + float fStiffenTime; + int iHitLimitCount; + } TAttackData; + + typedef struct SHitData + { + float fAttackStartTime; + float fAttackEndTime; + + float fWeaponLength; + std::string strBoneName; + + THitTimePositionMap mapHitPosition; + + bool Load(CTextFileLoader & rTextFileLoader); + } THitData; + + typedef std::vector THitDataContainer; + + typedef struct SMotionAttackData : public SAttackData + { + int iMotionType; + + THitDataContainer HitDataContainer; + } TMotionAttackData; + + ///////////////////////////////////////////////////////////////////////////////// + // Character Attaching Collision Data + enum ECollisionType + { + COLLISION_TYPE_NONE, + + COLLISION_TYPE_BODY, + COLLISION_TYPE_ATTACKING, + COLLISION_TYPE_DEFENDING, + COLLISION_TYPE_SPLASH, + }; + enum ECollisionShape + { + COLLISION_SHAPE_SPHERE, + COLLISION_SHAPE_CYLINDER, + }; + + typedef struct SCollisionData + { + int iCollisionType; + CSphereCollisionInstanceVector SphereDataVector; + + SCollisionData() {} + virtual ~SCollisionData() {} + } TCollisionData; + + typedef struct SAttachingEffectData + { + std::string strFileName; + D3DXVECTOR3 v3Position; + D3DXVECTOR3 v3Rotation; + + SAttachingEffectData() {} + virtual ~SAttachingEffectData() {} + } TAttachingEffectData; + + typedef struct SAttachingObjectData + { + std::string strFileName; + + SAttachingObjectData() {} + virtual ~SAttachingObjectData() {} + } TAttachingObjectData; + + typedef std::vector TCollisionDataVector; + + void DestroySystem(); + + void SaveAttackData(FILE * File, int iTabCount, const TAttackData & c_rData); + void SaveMotionAttackData(FILE * File, int iTabCount, const TMotionAttackData & c_rData); + void SaveCollisionData(FILE * File, int iTabCount, const TCollisionData & c_rCollisionData); + void SaveEffectData(FILE * File, int iTabCount, const TAttachingEffectData & c_rEffectData); + void SaveObjectData(FILE * File, int iTabCount, const TAttachingObjectData & c_rObjectData); + + BOOL LoadAttackData(CTextFileLoader & rTextFileLoader, TAttackData * pData); + BOOL LoadMotionAttackData(CTextFileLoader & rTextFileLoader, TMotionAttackData * pData); + BOOL LoadCollisionData(CTextFileLoader & rTextFileLoader, TCollisionData * pCollisionData); + BOOL LoadEffectData(CTextFileLoader & rTextFileLoader, TAttachingEffectData * pEffectData); + BOOL LoadObjectData(CTextFileLoader & rTextFileLoader, TAttachingObjectData * pObjectData); + + ///////////////////////////////////////////////////////////////////////////////// + // Attaching Data + enum EAttachingDataType + { + ATTACHING_DATA_TYPE_NONE, + + ATTACHING_DATA_TYPE_COLLISION_DATA, + ATTACHING_DATA_TYPE_EFFECT, + ATTACHING_DATA_TYPE_OBJECT, + + ATTACHING_DATA_TYPE_MAX_NUM, + }; + + typedef struct SAttachingData + { + SAttachingData() + : dwType(0) + , isAttaching(false) + , dwAttachingModelIndex(0) + , pCollisionData(NULL) + , pEffectData(NULL) + , pObjectData(NULL) + {} + DWORD dwType; + + BOOL isAttaching; + DWORD dwAttachingModelIndex; + std::string strAttachingBoneName; + + TCollisionData * pCollisionData; + TAttachingEffectData * pEffectData; + TAttachingObjectData * pObjectData; + } TAttachingData; + + typedef std::vector TAttachingDataVector; + + void SaveAttachingData(FILE * File, int iTabCount, const TAttachingDataVector & c_rAttachingDataVector); + BOOL LoadAttachingData(CTextFileLoader & rTextFileLoader, TAttachingDataVector * pAttachingDataVector); + + extern CDynamicPool g_CollisionDataPool; + extern CDynamicPool g_EffectDataPool; + extern CDynamicPool g_ObjectDataPool; +}; diff --git a/source/GameLib/GameUtil.cpp b/source/GameLib/GameUtil.cpp new file mode 100644 index 0000000..3e0eea9 --- /dev/null +++ b/source/GameLib/GameUtil.cpp @@ -0,0 +1,434 @@ +#include "StdAfx.h" +#include "../eterLib/lineintersect_utils.h" + +#include "GameUtil.h" + +bool DetectCollisionDynamicZCylinderVSDynamicZCylinder(const CDynamicSphereInstance & c_rSphere1, const CDynamicSphereInstance & c_rSphere2) +{ + CDynamicSphereInstance c_rCylinder1=c_rSphere1; + CDynamicSphereInstance c_rCylinder2=c_rSphere2; + + c_rCylinder1.v3Position.z=0; + c_rCylinder1.v3LastPosition.z=0; + + c_rCylinder2.v3Position.z=0; + c_rCylinder2.v3LastPosition.z=0; + + float r = c_rCylinder1.fRadius+c_rCylinder2.fRadius; + float rsq = r*r; + + // AABB check + D3DXVECTOR3 mi1=c_rCylinder1.v3LastPosition, mi2 = c_rCylinder1.v3Position; + D3DXVECTOR3 mi3=c_rCylinder2.v3LastPosition, mi4 = c_rCylinder2.v3Position; + if (mi1.x>mi2.x) std::swap(mi1.x,mi2.x); + if (mi1.y>mi2.y) std::swap(mi1.y,mi2.y); + if (mi1.z>mi2.z) std::swap(mi1.z,mi2.z); + if (mi3.x>mi4.x) std::swap(mi3.x,mi4.x); + if (mi3.y>mi4.y) std::swap(mi3.y,mi4.y); + if (mi3.z>mi4.z) std::swap(mi3.z,mi4.z); + mi1.x -= c_rCylinder1.fRadius; mi1.y -= c_rCylinder1.fRadius; mi1.z -= c_rCylinder1.fRadius; + mi2.x += c_rCylinder1.fRadius; mi2.y += c_rCylinder1.fRadius; mi2.z += c_rCylinder1.fRadius; + mi3.x -= c_rCylinder2.fRadius; mi3.y -= c_rCylinder2.fRadius; mi3.z -= c_rCylinder2.fRadius; + mi4.x += c_rCylinder2.fRadius; mi4.y += c_rCylinder2.fRadius; mi4.z += c_rCylinder2.fRadius; + if (mi4.xr || from_plane<-r) + return false; + p-=(from_plane/la/lb)*n; + float ta = D3DXVec3Dot(&p,&da)/la/la; + float tb = D3DXVec3Dot(&p,&db)/lb/lb; + + // FIXME üũ ƴϴ + + if (ta<0) + return false; + if (tb<0) + return false; + if (ta>1) + return false; + if (tb>1) + return false; + return true; + + */ + //*/ + // using gpg line-collision + + // AABB check + + D3DXVECTOR3 mi1=c_rSphere1.v3LastPosition, mi2 = c_rSphere1.v3Position; + D3DXVECTOR3 mi3=c_rSphere2.v3LastPosition, mi4 = c_rSphere2.v3Position; + if (mi1.x>mi2.x) std::swap(mi1.x,mi2.x); + if (mi1.y>mi2.y) std::swap(mi1.y,mi2.y); + if (mi1.z>mi2.z) std::swap(mi1.z,mi2.z); + if (mi3.x>mi4.x) std::swap(mi3.x,mi4.x); + if (mi3.y>mi4.y) std::swap(mi3.y,mi4.y); + if (mi3.z>mi4.z) std::swap(mi3.z,mi4.z); + mi1.x -= c_rSphere1.fRadius; mi1.y -= c_rSphere1.fRadius; mi1.z -= c_rSphere1.fRadius; + mi2.x += c_rSphere1.fRadius; mi2.y += c_rSphere1.fRadius; mi2.z += c_rSphere1.fRadius; + mi3.x -= c_rSphere2.fRadius; mi3.y -= c_rSphere2.fRadius; mi3.z -= c_rSphere2.fRadius; + mi4.x += c_rSphere2.fRadius; mi4.y += c_rSphere2.fRadius; mi4.z += c_rSphere2.fRadius; + if (mi4.x= 1.0f) + return false; + + return true;*/ +} + +/* +// Dynamic VS Static +bool DetectCollisionDynamicSphereVSStaticPlane(const CDynamicSphereInstance & c_rSphere, const TPlaneData & c_rPlane) +{ + D3DXVECTOR3 v3SpherePosition = c_rSphere.v3Position - c_rPlane.v3Position; + D3DXVECTOR3 v3SphereLastPosition = c_rSphere.v3LastPosition - c_rPlane.v3Position; + + float fPosition1 = D3DXVec3Dot(&c_rPlane.v3Normal, &v3SpherePosition); + float fPosition2 = D3DXVec3Dot(&c_rPlane.v3Normal, &v3SphereLastPosition); + + if (fPosition1 >0.0f && fPosition2 < 0.0f || fPosition1 <0.0f && fPosition2 >0.0f || (fPosition1) <= c_rSphere.fRadius && fPosition1 >= -c_rSphere.fRadius) + { + D3DXVECTOR3 v3QuadPosition1 = c_rSphere.v3Position - c_rPlane.v3QuadPosition[0]; + D3DXVECTOR3 v3QuadPosition2 = c_rSphere.v3Position - c_rPlane.v3QuadPosition[3]; + if (D3DXVec3Dot(&v3QuadPosition1, &c_rPlane.v3InsideVector[0]) < c_rSphere.fRadius) + if (D3DXVec3Dot(&v3QuadPosition1, &c_rPlane.v3InsideVector[1]) < c_rSphere.fRadius) + if (D3DXVec3Dot(&v3QuadPosition2, &c_rPlane.v3InsideVector[2]) < c_rSphere.fRadius) + if (D3DXVec3Dot(&v3QuadPosition2, &c_rPlane.v3InsideVector[3]) < c_rSphere.fRadius) + return true; + + } + + return false; +} + +bool DetectCollisionDynamicSphereVSStaticSphere(const CDynamicSphereInstance & c_rSphere, const TSphereData & c_rSphereData) +{ + D3DXVECTOR3 v3Distance = c_rSphere.v3Position - c_rSphereData.v3Position; + float fDistanceSq = D3DXVec3LengthSq(&v3Distance); + float fRadiusSummary = c_rSphere.fRadius + c_rSphereData.fRadius; + if (fDistanceSq < fRadiusSummary*fRadiusSummary) + return true; + + //D3DXVECTOR3 v3LastDistance = c_rSphere.v3LastPosition - c_rSphereData.v3Position; + //if (D3DXVec3Dot(&v3LastDistance, &v3Distance) < 0.0f) + // return true; + + return false; +} + +bool DetectCollisionDynamicSphereVSStaticCylinder(const CDynamicSphereInstance & c_rSphere, const TCylinderData & c_rCylinderData) +{ + if (c_rSphere.v3Position.z + c_rSphere.fRadius < c_rCylinderData.v3Position.z) + return false; + + if (c_rSphere.v3Position.z - c_rSphere.fRadius > c_rCylinderData.v3Position.z + c_rCylinderData.fHeight) + return false; + + D3DXVECTOR3 v3curDistance = c_rSphere.v3Position - c_rCylinderData.v3Position; + float fDistance = D3DXVec3Length(&v3curDistance); + + if (fDistance <= c_rSphere.fRadius + c_rCylinderData.fRadius) + return true; + + //D3DXVECTOR3 v3lastDistance = c_rSphere.v3LastPosition - c_rCylinderData.v3Position; + + //if (D3DXVec3Dot(&v3curDistance, &v3lastDistance) < 0.0f) + // return true; + + return false; +} +*/ +/* +bool DetectCollisionDynamicSphereVSStaticBox(const TSphereInstance & c_rSphere, const TBoxData & c_rBoxData) +{ + return false; +} +*/ +// Static VS Static +/* +bool DetectCollisionStaticSphereVSStaticSphere(const TSphereData & c_rSphere1, const TSphereData & c_rSphere2) +{ + D3DXVECTOR3 v3Distance = c_rSphere1.v3Position - c_rSphere2.v3Position; + float fDistance = D3DXVec3Length(&v3Distance); + + if (fDistance < c_rSphere1.fRadius + c_rSphere2.fRadius) + return true; + + return false; +} + +bool DetectCollisionStaticSphereVSStaticCylinder(const TSphereData & c_rSphere, const TCylinderData & c_rCylinder) +{ + return false; +} +*/ +/*bool DetectCollisionStaticSphereVSStaticBox(const TSphereData & c_rSphere, const TBoxData & c_rBox) +{ + return false; +} +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////// + +bool IsCWAcuteAngle(float begin, float end) +{ + // 360 - src + dest // ð ݴ + // src - dest // ð + return ((360.0f - begin + end) > (begin - end)); +} + +bool IsCCWAcuteAngle(float begin, float end) +{ + // abs(360 - dest + src) // ð + // dest - src // ð ݴ + int fValue = abs((int) (360.0f - end + begin)); + return fValue >= (end - begin) ? true : false; +} + +bool IsCWRotation(float begin, float end) +{ + return !IsCCWRotation(begin, end); +} + +bool IsCCWRotation(float begin, float end) +{ + // 180 + // 270 90 + // 0 + // + // ð ݴ + return (begin - end < 0); +} + +float GetInterpolatedRotation(float begin, float end, float curRate) +{ + if (IsCCWRotation(begin, end)) + { + if (IsCCWAcuteAngle(begin, end)) + return GetLinearInterpolation(begin, end, curRate); + + return (360.0f + GetLinearInterpolation(begin, end - 360.0f, curRate)); + } + + if (IsCWAcuteAngle(begin, end)) + return GetLinearInterpolation(begin, end, curRate); + + return GetLinearInterpolation(begin, end + 360.0f, curRate); +} + +float GetDegreeFromPosition(float x, float y) +{ + D3DXVECTOR3 vtDir(floor(x), floor(y), 0.0f); + D3DXVec3Normalize(&vtDir, &vtDir); + + D3DXVECTOR3 vtStan(0, -1, 0); + float ret = D3DXToDegree(acosf(D3DXVec3Dot(&vtDir, &vtStan))); + + if (vtDir.x < 0.0f) + ret = 360.0f - ret; + + return ret; +} + +float GetDegreeFromPosition2(float sx, float sy, float ex, float ey) +{ + return GetDegreeFromPosition(ex - sx, ey - sy); +} + +float GetDegreeDifference(float fSource, float fTarget) +{ + if (fSource < 180.0f) + { + if (fTarget < fSource) + return fSource - fTarget; + + else if(fTarget - fSource > 180.0f) + return (360.0f - (fTarget - fSource)); + + return fTarget - fSource; + } + else + { + if (fTarget > fSource) + return fTarget - fSource; + + else if (fSource - fTarget > 180.0f) + { + return (360.0f - (fSource - fTarget)); + } + + return fSource - fTarget; + } +} +int GetRotatingDirection(float fSource, float fTarget) +{ + if (fSource < 180.0f) + { + if (fTarget < fSource) + return DEGREE_DIRECTION_RIGHT; + + else if((360.0f - fTarget) + fSource < 180.0f) + return DEGREE_DIRECTION_RIGHT; + + return DEGREE_DIRECTION_LEFT; + } + else + { + if (fTarget > fSource) + { + return DEGREE_DIRECTION_LEFT; + } + else if ((360.0f - fSource) + fTarget < 180.0f) + { + return DEGREE_DIRECTION_LEFT; + } + + return DEGREE_DIRECTION_RIGHT; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +float CameraRotationToCharacterRotation(float fCameraRotation) +{ + return fmod((540.0f - fCameraRotation), 360.0f); +} + +float CharacterRotationToCameraRotation(float fCharacterRotation) +{ + return fmod((540.0f - fCharacterRotation), 360.0f); +} + +/* +bool DetectCollisionDynamicSphereVSStaticPlane(const TSphereInstance & c_rSphere, const TPlaneData & c_rPlane) +{ + D3DXVECTOR3 v3SpherePosition = c_rSphere.v3Position - c_rPlane.v3Position; + D3DXVECTOR3 v3SphereLastPosition = c_rSphere.v3LastPosition - c_rPlane.v3Position; + + float fPosition1 = D3DXVec3Dot(&c_rPlane.v3Normal, &v3SpherePosition); + float fPosition2 = D3DXVec3Dot(&c_rPlane.v3Normal, &v3SphereLastPosition); + + if (fPosition1 * fPosition2 < 0.0f || fabs(fPosition1) <= c_rSphere.fRadius) + { + float fT = -fPosition1 / D3DXVec3Dot(&c_rPlane.v3Normal, &c_rSphere.v3Advance); + D3DXVECTOR3 v3CollisionPosition = c_rSphere.v3LastPosition + c_rSphere.v3Advance * fT; + D3DXVECTOR3 v3QuadPosition1 = v3CollisionPosition - c_rPlane.v3BeginPosition; + D3DXVECTOR3 v3QuadPosition2 = v3CollisionPosition - c_rPlane.v3EndPosition; + D3DXVec3Normalize(&v3QuadPosition1, &v3QuadPosition1); + D3DXVec3Normalize(&v3QuadPosition2, &v3QuadPosition2); + + if (D3DXVec3Dot(&v3QuadPosition1, &c_rPlane.v3InsideVector[0]) < 0.0f) + if (D3DXVec3Dot(&v3QuadPosition1, &c_rPlane.v3InsideVector[1]) < 0.0f) + if (D3DXVec3Dot(&v3QuadPosition2, &c_rPlane.v3InsideVector[2]) < 0.0f) + if (D3DXVec3Dot(&v3QuadPosition2, &c_rPlane.v3InsideVector[3]) < 0.0f) + { + return true; + } + } + + return false; +} +*/ diff --git a/source/GameLib/GameUtil.h b/source/GameLib/GameUtil.h new file mode 100644 index 0000000..81a8e70 --- /dev/null +++ b/source/GameLib/GameUtil.h @@ -0,0 +1,41 @@ +#pragma once + +// Collision Detection +// Dynamic VS Dynamic +bool DetectCollisionDynamicSphereVSDynamicSphere(const CDynamicSphereInstance & c_rSphere1, const CDynamicSphereInstance & c_rSphere2); +bool DetectCollisionDynamicZCylinderVSDynamicZCylinder(const CDynamicSphereInstance & c_rSphere1, const CDynamicSphereInstance & c_rSphere2); +// Dynamic VS Static +//bool DetectCollisionDynamicSphereVSStaticPlane(const CDynamicSphereInstance & c_rSphere, const TPlaneData & c_rPlaneData); +//bool DetectCollisionDynamicSphereVSStaticSphere(const CDynamicSphereInstance & c_rSphere, const TSphereData & c_rSphereData); +//bool DetectCollisionDynamicSphereVSStaticCylinder(const CDynamicSphereInstance & c_rSphere, const TCylinderData & c_rCylinderData); +//bool DetectCollisionDynamicSphereVSStaticBox(const TSphereInstance & c_rSphere, const TBoxData & c_rBoxData); +// Static VS Static +//bool DetectCollisionStaticSphereVSStaticSphere(const CDynamicSphereInstance & c_rSphere1, const TSphereData & c_rSphere2); +//bool DetectCollisionStaticSphereVSStaticCylinder(const CDynamicSphereInstance & c_rSphere, const TCylinderData & c_rCylinder); +//bool DetectCollisionStaticSphereVSStaticBox(const TSphereData & c_rSphere, const TBoxData & c_rBox); + +// Rotation +float GetDegreeFromPosition(float x, float y); +float GetDegreeFromPosition2(float sx, float sy, float ex, float ey); + +float GetInterpolatedRotation(float begin, float end, float curRate); +bool IsSameDirectionRotation(); +bool IsCWRotation(float begin, float end); +bool IsCCWRotation(float begin, float end); + +bool IsCWAcuteAngle(float begin, float end); +bool IsCCWAcuteAngle(float begin, float end); + +// NOTE - Finally, this code is same with upper rotating direction code. +enum EDegree_Direction +{ + DEGREE_DIRECTION_SAME = 0, + DEGREE_DIRECTION_RIGHT = 1, + DEGREE_DIRECTION_LEFT = 2, +}; +float GetDegreeDifference(float fSource, float fTarget); +int GetRotatingDirection(float fSource, float fTarget); + +// Converting Rotation +float CameraRotationToCharacterRotation(float fCameraRotation); +float CharacterRotationToCameraRotation(float fCharacterRotation); diff --git a/source/GameLib/Interface.h b/source/GameLib/Interface.h new file mode 100644 index 0000000..78cf53c --- /dev/null +++ b/source/GameLib/Interface.h @@ -0,0 +1,11 @@ +#pragma once + +// 2004.07.05.myevan.ýź ʿ ̴ ذ +class IBackground : public CSingleton +{ + public: + IBackground() {} + virtual ~IBackground() {} + + virtual bool IsBlock(int x, int y) = 0; +}; \ No newline at end of file diff --git a/source/GameLib/ItemData.cpp b/source/GameLib/ItemData.cpp new file mode 100644 index 0000000..c0afb27 --- /dev/null +++ b/source/GameLib/ItemData.cpp @@ -0,0 +1,464 @@ +#include "StdAfx.h" +#include "../eterLib/ResourceManager.h" + +#include "ItemData.h" + +CDynamicPool CItemData::ms_kPool; + +extern DWORD GetDefaultCodePage(); + +CItemData* CItemData::New() +{ + return ms_kPool.Alloc(); +} + +void CItemData::Delete(CItemData* pkItemData) +{ + pkItemData->Clear(); + ms_kPool.Free(pkItemData); +} + +void CItemData::DestroySystem() +{ + ms_kPool.Destroy(); +} + +CGraphicThing * CItemData::GetModelThing() +{ + return m_pModelThing; +} + +CGraphicThing * CItemData::GetSubModelThing() +{ + if (m_pSubModelThing) + return m_pSubModelThing; + else + return m_pModelThing; +} + +CGraphicThing * CItemData::GetDropModelThing() +{ + return m_pDropModelThing; +} + +CGraphicSubImage * CItemData::GetIconImage() +{ + if(m_pIconImage == NULL && m_strIconFileName.empty() == false) + __SetIconImage(m_strIconFileName.c_str()); + return m_pIconImage; +} + +DWORD CItemData::GetLODModelThingCount() +{ + return m_pLODModelThingVector.size(); +} + +BOOL CItemData::GetLODModelThingPointer(DWORD dwIndex, CGraphicThing ** ppModelThing) +{ + if (dwIndex >= m_pLODModelThingVector.size()) + return FALSE; + + *ppModelThing = m_pLODModelThingVector[dwIndex]; + + return TRUE; +} + +DWORD CItemData::GetAttachingDataCount() +{ + return m_AttachingDataVector.size(); +} + +BOOL CItemData::GetCollisionDataPointer(DWORD dwIndex, const NRaceData::TAttachingData ** c_ppAttachingData) +{ + if (dwIndex >= GetAttachingDataCount()) + return FALSE; + + if (NRaceData::ATTACHING_DATA_TYPE_COLLISION_DATA != m_AttachingDataVector[dwIndex].dwType) + return FALSE; + + *c_ppAttachingData = &m_AttachingDataVector[dwIndex]; + return TRUE; +} + +BOOL CItemData::GetAttachingDataPointer(DWORD dwIndex, const NRaceData::TAttachingData ** c_ppAttachingData) +{ + if (dwIndex >= GetAttachingDataCount()) + return FALSE; + + *c_ppAttachingData = &m_AttachingDataVector[dwIndex]; + return TRUE; +} + +void CItemData::SetSummary(const std::string& c_rstSumm) +{ + m_strSummary=c_rstSumm; +} + +void CItemData::SetDescription(const std::string& c_rstDesc) +{ + m_strDescription=c_rstDesc; +} +/* +BOOL CItemData::LoadItemData(const char * c_szFileName) +{ + CTextFileLoader TextFileLoader; + + if (!TextFileLoader.Load(c_szFileName)) + { + //Lognf(1, "CItemData::LoadItemData(c_szFileName=%s) - FAILED", c_szFileName); + return FALSE; + } + + TextFileLoader.SetTop(); + + TextFileLoader.GetTokenString("modelfilename", &m_strModelFileName); + TextFileLoader.GetTokenString("submodelfilename", &m_strSubModelFileName); + TextFileLoader.GetTokenString("dropmodelfilename", &m_strDropModelFileName); + TextFileLoader.GetTokenString("iconimagefilename", &m_strIconFileName); + + char szDescriptionKey[32+1]; + _snprintf(szDescriptionKey, 32, "%ddescription", GetDefaultCodePage()); + if (!TextFileLoader.GetTokenString(szDescriptionKey, &m_strDescription)) + { + TextFileLoader.GetTokenString("description", &m_strDescription); + } + + // LOD Model File Name List + CTokenVector * pLODModelList; + if (TextFileLoader.GetTokenVector("lodmodellist", &pLODModelList)) + { + m_strLODModelFileNameVector.clear(); + m_strLODModelFileNameVector.resize(pLODModelList->size()); + + for (DWORD i = 0; i < pLODModelList->size(); ++i) + { + m_strLODModelFileNameVector[i] = pLODModelList->at(0); + } + } + + // Attaching Data + // Item Attaching Data ϴ . +// if (TextFileLoader.SetChildNode("attachingdata")) +// { +// if (!NRaceData::LoadAttachingData(TextFileLoader, &m_AttachingDataVector)) +// return FALSE; +// +// TextFileLoader.SetParentNode(); +// } + + __LoadFiles(); + + return TRUE; +} +*/ +void CItemData::SetDefaultItemData(const char * c_szIconFileName, const char * c_szModelFileName) +{ + if(c_szModelFileName) + { + m_strModelFileName = c_szModelFileName; + m_strDropModelFileName = c_szModelFileName; + } + else + { + m_strModelFileName = ""; + m_strDropModelFileName = "d:/ymir work/item/etc/item_bag.gr2"; + } + m_strIconFileName = c_szIconFileName; + + m_strSubModelFileName = ""; + m_strDescription = ""; + m_strSummary = ""; + memset(m_ItemTable.alSockets, 0, sizeof(m_ItemTable.alSockets)); + + __LoadFiles(); +} + +void CItemData::__LoadFiles() +{ + // Model File Name + if (!m_strModelFileName.empty()) + m_pModelThing = (CGraphicThing *)CResourceManager::Instance().GetResourcePointer(m_strModelFileName.c_str()); + + if (!m_strSubModelFileName.empty()) + m_pSubModelThing = (CGraphicThing *)CResourceManager::Instance().GetResourcePointer(m_strSubModelFileName.c_str()); + + if (!m_strDropModelFileName.empty()) + m_pDropModelThing = (CGraphicThing *)CResourceManager::Instance().GetResourcePointer(m_strDropModelFileName.c_str()); + + + if (!m_strLODModelFileNameVector.empty()) + { + m_pLODModelThingVector.clear(); + m_pLODModelThingVector.resize(m_strLODModelFileNameVector.size()); + + for (DWORD i = 0; i < m_strLODModelFileNameVector.size(); ++i) + { + const std::string & c_rstrLODModelFileName = m_strLODModelFileNameVector[i]; + m_pLODModelThingVector[i] = (CGraphicThing *)CResourceManager::Instance().GetResourcePointer(c_rstrLODModelFileName.c_str()); + } + } +} + +void CItemData::__SetIconImage(const char * c_szFileName) +{ + if (!CResourceManager::Instance().IsFileExist(c_szFileName)) + { + TraceError("%s ϴ.CItemData::__SetIconImage",c_szFileName); + m_pIconImage = NULL; + } + else if (m_pIconImage == NULL) + m_pIconImage = (CGraphicSubImage *)CResourceManager::Instance().GetResourcePointer(c_szFileName); +} + +void CItemData::SetItemTableData(TItemTable * pItemTable) +{ + memcpy(&m_ItemTable, pItemTable, sizeof(TItemTable)); +} + +const CItemData::TItemTable* CItemData::GetTable() const +{ + return &m_ItemTable; +} + +DWORD CItemData::GetIndex() const +{ + return m_ItemTable.dwVnum; +} + +const char * CItemData::GetName() const +{ + return m_ItemTable.szLocaleName; +} + +const char * CItemData::GetDescription() const +{ + return m_strDescription.c_str(); +} + +const char * CItemData::GetSummary() const +{ + return m_strSummary.c_str(); +} + + +BYTE CItemData::GetType() const +{ + return m_ItemTable.bType; +} + +BYTE CItemData::GetSubType() const +{ + return m_ItemTable.bSubType; +} + +#define DEF_STR(x) #x + +const char* CItemData::GetUseTypeString() const +{ + if (GetType() != CItemData::ITEM_TYPE_USE) + return "NOT_USE_TYPE"; + + switch (GetSubType()) + { + case USE_TUNING: + return DEF_STR(USE_TUNING); + case USE_DETACHMENT: + return DEF_STR(USE_DETACHMENT); + case USE_CLEAN_SOCKET: + return DEF_STR(USE_CLEAN_SOCKET); + case USE_CHANGE_ATTRIBUTE: + return DEF_STR(USE_CHANGE_ATTRIBUTE); + case USE_ADD_ATTRIBUTE: + return DEF_STR(USE_ADD_ATTRIBUTE); + case USE_ADD_ATTRIBUTE2: + return DEF_STR(USE_ADD_ATTRIBUTE2); + case USE_ADD_ACCESSORY_SOCKET: + return DEF_STR(USE_ADD_ACCESSORY_SOCKET); + case USE_PUT_INTO_ACCESSORY_SOCKET: + return DEF_STR(USE_PUT_INTO_ACCESSORY_SOCKET); + case USE_PUT_INTO_BELT_SOCKET: + return DEF_STR(USE_PUT_INTO_BELT_SOCKET); + case USE_PUT_INTO_RING_SOCKET: + return DEF_STR(USE_PUT_INTO_RING_SOCKET); + } + return "USE_UNKNOWN_TYPE"; +} + + +DWORD CItemData::GetWeaponType() const +{ + return m_ItemTable.bSubType; +} + +BYTE CItemData::GetSize() const +{ + return m_ItemTable.bSize; +} + +BOOL CItemData::IsAntiFlag(DWORD dwFlag) const +{ + return (dwFlag & m_ItemTable.dwAntiFlags) != 0; +} + +BOOL CItemData::IsFlag(DWORD dwFlag) const +{ + return (dwFlag & m_ItemTable.dwFlags) != 0; +} + +BOOL CItemData::IsWearableFlag(DWORD dwFlag) const +{ + return (dwFlag & m_ItemTable.dwWearFlags) != 0; +} + +BOOL CItemData::HasNextGrade() const +{ + return 0 != m_ItemTable.dwRefinedVnum; +} + +DWORD CItemData::GetWearFlags() const +{ + return m_ItemTable.dwWearFlags; +} + +DWORD CItemData::GetIBuyItemPrice() const +{ + return m_ItemTable.dwIBuyItemPrice; +} + +DWORD CItemData::GetISellItemPrice() const +{ + return m_ItemTable.dwISellItemPrice; +} + + +BOOL CItemData::GetLimit(BYTE byIndex, TItemLimit * pItemLimit) const +{ + if (byIndex >= ITEM_LIMIT_MAX_NUM) + { + assert(byIndex < ITEM_LIMIT_MAX_NUM); + return FALSE; + } + + *pItemLimit = m_ItemTable.aLimits[byIndex]; + + return TRUE; +} + +BOOL CItemData::GetApply(BYTE byIndex, TItemApply * pItemApply) const +{ + if (byIndex >= ITEM_APPLY_MAX_NUM) + { + assert(byIndex < ITEM_APPLY_MAX_NUM); + return FALSE; + } + + *pItemApply = m_ItemTable.aApplies[byIndex]; + return TRUE; +} + +long CItemData::GetValue(BYTE byIndex) const +{ + if (byIndex >= ITEM_VALUES_MAX_NUM) + { + assert(byIndex < ITEM_VALUES_MAX_NUM); + return 0; + } + + return m_ItemTable.alValues[byIndex]; +} + +long CItemData::SetSocket(BYTE byIndex,DWORD value) +{ + if (byIndex >= ITEM_SOCKET_MAX_NUM) + { + assert(byIndex < ITEM_SOCKET_MAX_NUM); + return -1; + } + + return m_ItemTable.alSockets[byIndex] = value; +} + +long CItemData::GetSocket(BYTE byIndex) const +{ + if (byIndex >= ITEM_SOCKET_MAX_NUM) + { + assert(byIndex < ITEM_SOCKET_MAX_NUM); + return -1; + } + + return m_ItemTable.alSockets[byIndex]; +} + +// Լ !!(Ŀ ģ) +//SocketCount = 1 ̸ ʱ޹ +//SocketCount = 2 ̸ ߱޹ +//SocketCount = 3 ̸ ޹ +int CItemData::GetSocketCount() const +{ + return m_ItemTable.bGainSocketPct; +} + +DWORD CItemData::GetIconNumber() const +{ + return m_ItemTable.dwVnum; +//!@# +// return m_ItemTable.dwIconNumber; +} + +UINT CItemData::GetSpecularPoweru() const +{ + return m_ItemTable.bSpecular; +} + +float CItemData::GetSpecularPowerf() const +{ + UINT uSpecularPower=GetSpecularPoweru(); + + return float(uSpecularPower) / 100.0f; +} + +//refine ۹ȣ ڸ ġѴ-_-(̺̿ ٲ ) +UINT CItemData::GetRefine() const +{ + return GetIndex()%10; +} + +BOOL CItemData::IsEquipment() const +{ + switch (GetType()) + { + case ITEM_TYPE_WEAPON: + case ITEM_TYPE_ARMOR: + return TRUE; + break; + } + + return FALSE; +} + +void CItemData::Clear() +{ + m_strSummary = ""; + m_strModelFileName = ""; + m_strSubModelFileName = ""; + m_strDropModelFileName = ""; + m_strIconFileName = ""; + m_strLODModelFileNameVector.clear(); + + m_pModelThing = NULL; + m_pSubModelThing = NULL; + m_pDropModelThing = NULL; + m_pIconImage = NULL; + m_pLODModelThingVector.clear(); + + memset(&m_ItemTable, 0, sizeof(m_ItemTable)); +} + +CItemData::CItemData() +{ + Clear(); +} + +CItemData::~CItemData() +{ +} diff --git a/source/GameLib/ItemData.h b/source/GameLib/ItemData.h new file mode 100644 index 0000000..a8b7b28 --- /dev/null +++ b/source/GameLib/ItemData.h @@ -0,0 +1,524 @@ +#pragma once + +// NOTE : Item Ŭ. +// Icon, Model (droped on ground), Game Data + +#include "../eterLib/GrpSubImage.h" +#include "../eterGrnLib/Thing.h" + +class CItemData +{ + public: + enum + { + ITEM_NAME_MAX_LEN = 24, + ITEM_LIMIT_MAX_NUM = 2, + ITEM_VALUES_MAX_NUM = 6, + ITEM_SMALL_DESCR_MAX_LEN = 256, + ITEM_APPLY_MAX_NUM = 3, + ITEM_SOCKET_MAX_NUM = 3, + }; + + enum EItemType + { + ITEM_TYPE_NONE, //0 + ITEM_TYPE_WEAPON, //1// + ITEM_TYPE_ARMOR, //2// + ITEM_TYPE_USE, //3// + ITEM_TYPE_AUTOUSE, //4 + ITEM_TYPE_MATERIAL, //5 + ITEM_TYPE_SPECIAL, //6 // + ITEM_TYPE_TOOL, //7 + ITEM_TYPE_LOTTERY, //8// + ITEM_TYPE_ELK, //9// + ITEM_TYPE_METIN, //10 + ITEM_TYPE_CONTAINER, //11 + ITEM_TYPE_FISH, //12// + ITEM_TYPE_ROD, //13 + ITEM_TYPE_RESOURCE, //14 + ITEM_TYPE_CAMPFIRE, //15 + ITEM_TYPE_UNIQUE, //16 + ITEM_TYPE_SKILLBOOK, //17 + ITEM_TYPE_QUEST, //18 + ITEM_TYPE_POLYMORPH, //19 + ITEM_TYPE_TREASURE_BOX, //20// + ITEM_TYPE_TREASURE_KEY, //21// + ITEM_TYPE_SKILLFORGET, //22 + ITEM_TYPE_GIFTBOX, //23 + ITEM_TYPE_PICK, //24 + ITEM_TYPE_HAIR, //25//Ӹ + ITEM_TYPE_TOTEM, //26// + ITEM_TYPE_BLEND, //27//ɶ ϰ Ӽ ٴ ๰ + ITEM_TYPE_COSTUME, //28//ڽ (2011 8 ߰ ڽ ýۿ ) + ITEM_TYPE_DS, //29 //ȥ + ITEM_TYPE_SPECIAL_DS, //30 // Ư ȥ (DS_SLOT ϴ UNIQUE ̶ ϸ ) + ITEM_TYPE_EXTRACT, //31 ⵵. + ITEM_TYPE_SECONDARY_COIN, //32 . + ITEM_TYPE_RING, //33 (ũ ƴ ) + ITEM_TYPE_BELT, //34 Ʈ + + ITEM_TYPE_MAX_NUM, + }; + + enum EWeaponSubTypes + { + WEAPON_SWORD, + WEAPON_DAGGER, //̵ + WEAPON_BOW, + WEAPON_TWO_HANDED, + WEAPON_BELL, + WEAPON_FAN, + WEAPON_ARROW, + WEAPON_NUM_TYPES, + + WEAPON_NONE = WEAPON_NUM_TYPES+1, + }; + + enum EMaterialSubTypes + { + MATERIAL_LEATHER, + MATERIAL_BLOOD, + MATERIAL_ROOT, + MATERIAL_NEEDLE, + MATERIAL_JEWEL, + MATERIAL_DS_REFINE_NORMAL, + MATERIAL_DS_REFINE_BLESSED, + MATERIAL_DS_REFINE_HOLLY, + }; + + enum EArmorSubTypes + { + ARMOR_BODY, + ARMOR_HEAD, + ARMOR_SHIELD, + ARMOR_WRIST, + ARMOR_FOOTS, + ARMOR_NECK, + ARMOR_EAR, + ARMOR_NUM_TYPES + }; + + enum ECostumeSubTypes + { + COSTUME_BODY, //0 (main look) + COSTUME_HAIR, //1 (Ż) + COSTUME_NUM_TYPES, + }; + + enum EUseSubTypes + { + USE_POTION, // 0 + USE_TALISMAN, + USE_TUNING, + USE_MOVE, + USE_TREASURE_BOX, + USE_MONEYBAG, + USE_BAIT, + USE_ABILITY_UP, + USE_AFFECT, + USE_CREATE_STONE, + USE_SPECIAL, // 10 + USE_POTION_NODELAY, + USE_CLEAR, + USE_INVISIBILITY, + USE_DETACHMENT, + USE_BUCKET, + USE_POTION_CONTINUE, + USE_CLEAN_SOCKET, + USE_CHANGE_ATTRIBUTE, + USE_ADD_ATTRIBUTE, + USE_ADD_ACCESSORY_SOCKET, // 20 + USE_PUT_INTO_ACCESSORY_SOCKET, + USE_ADD_ATTRIBUTE2, + USE_RECIPE, + USE_CHANGE_ATTRIBUTE2, + USE_BIND, + USE_UNBIND, + USE_TIME_CHARGE_PER, + USE_TIME_CHARGE_FIX, // 28 + USE_PUT_INTO_BELT_SOCKET, // 29 Ʈ Ͽ ִ + USE_PUT_INTO_RING_SOCKET, // 30 Ͽ ִ (ũ , ߰ ) + }; + + enum EDragonSoulSubType + { + DS_SLOT1, + DS_SLOT2, + DS_SLOT3, + DS_SLOT4, + DS_SLOT5, + DS_SLOT6, + DS_SLOT_NUM_TYPES = 6, + }; + + enum EMetinSubTypes + { + METIN_NORMAL, + METIN_GOLD, + }; + + enum ELimitTypes + { + LIMIT_NONE, + + LIMIT_LEVEL, + LIMIT_STR, + LIMIT_DEX, + LIMIT_INT, + LIMIT_CON, + LIMIT_PCBANG, + + /// ο ǽð ð (socket0 Ҹ ð : unix_timestamp Ÿ) + LIMIT_REAL_TIME, + + /// ó (Ȥ ) Ÿ Ÿ̸ + /// socket0 밡ɽð(ʴ, 0̸ limit value ) ִٰ + /// socket1 Ƚ socket0 unix_timestamp Ÿ Ҹð . + LIMIT_REAL_TIME_START_FIRST_USE, + + /// ð Ǵ + /// socket0 ð ʴ . ( ش 0̸ limit value socket0 ) + LIMIT_TIMER_BASED_ON_WEAR, + + LIMIT_MAX_NUM + }; + + enum EItemAntiFlag + { + ITEM_ANTIFLAG_FEMALE = (1 << 0), // Ұ + ITEM_ANTIFLAG_MALE = (1 << 1), // Ұ + ITEM_ANTIFLAG_WARRIOR = (1 << 2), // Ұ + ITEM_ANTIFLAG_ASSASSIN = (1 << 3), // ڰ Ұ + ITEM_ANTIFLAG_SURA = (1 << 4), // Ұ + ITEM_ANTIFLAG_SHAMAN = (1 << 5), // Ұ + ITEM_ANTIFLAG_GET = (1 << 6), // + ITEM_ANTIFLAG_DROP = (1 << 7), // + ITEM_ANTIFLAG_SELL = (1 << 8), // + ITEM_ANTIFLAG_EMPIRE_A = (1 << 9), // A Ұ + ITEM_ANTIFLAG_EMPIRE_B = (1 << 10), // B Ұ + ITEM_ANTIFLAG_EMPIRE_R = (1 << 11), // C Ұ + ITEM_ANTIFLAG_SAVE = (1 << 12), // + ITEM_ANTIFLAG_GIVE = (1 << 13), // ŷ Ұ + ITEM_ANTIFLAG_PKDROP = (1 << 14), // PK + ITEM_ANTIFLAG_STACK = (1 << 15), // ĥ + ITEM_ANTIFLAG_MYSHOP = (1 << 16), // ø + }; + + enum EItemFlag + { + ITEM_FLAG_REFINEABLE = (1 << 0), // + ITEM_FLAG_SAVE = (1 << 1), + ITEM_FLAG_STACKABLE = (1 << 2), // ĥ + ITEM_FLAG_COUNT_PER_1GOLD = (1 << 3), // / + ITEM_FLAG_SLOW_QUERY = (1 << 4), // ÿ SQL + ITEM_FLAG_RARE = (1 << 5), + ITEM_FLAG_UNIQUE = (1 << 6), + ITEM_FLAG_MAKECOUNT = (1 << 7), + ITEM_FLAG_IRREMOVABLE = (1 << 8), + ITEM_FLAG_CONFIRM_WHEN_USE = (1 << 9), + ITEM_FLAG_QUEST_USE = (1 << 10), // Ʈ ũƮ ? + ITEM_FLAG_QUEST_USE_MULTIPLE= (1 << 11), // Ʈ ũƮ ? + ITEM_FLAG_UNUSED03 = (1 << 12), // UNUSED03 + ITEM_FLAG_LOG = (1 << 13), // α׸ ΰ? + ITEM_FLAG_APPLICABLE = (1 << 14), + }; + + enum EWearPositions + { + WEAR_BODY, // 0 + WEAR_HEAD, // 1 + WEAR_FOOTS, // 2 + WEAR_WRIST, // 3 + WEAR_WEAPON, // 4 + WEAR_NECK, // 5 + WEAR_EAR, // 6 + WEAR_UNIQUE1, // 7 + WEAR_UNIQUE2, // 8 + WEAR_ARROW, // 9 + WEAR_SHIELD, // 10 + WEAR_MAX_NUM, + }; + + enum EItemWearableFlag + { + WEARABLE_BODY = (1 << 0), + WEARABLE_HEAD = (1 << 1), + WEARABLE_FOOTS = (1 << 2), + WEARABLE_WRIST = (1 << 3), + WEARABLE_WEAPON = (1 << 4), + WEARABLE_NECK = (1 << 5), + WEARABLE_EAR = (1 << 6), + WEARABLE_UNIQUE = (1 << 7), + WEARABLE_SHIELD = (1 << 8), + WEARABLE_ARROW = (1 << 9), + }; + + enum EApplyTypes + { + APPLY_NONE, // 0 + APPLY_MAX_HP, // 1 + APPLY_MAX_SP, // 2 + APPLY_CON, // 3 + APPLY_INT, // 4 + APPLY_STR, // 5 + APPLY_DEX, // 6 + APPLY_ATT_SPEED, // 7 + APPLY_MOV_SPEED, // 8 + APPLY_CAST_SPEED, // 9 + APPLY_HP_REGEN, // 10 + APPLY_SP_REGEN, // 11 + APPLY_POISON_PCT, // 12 + APPLY_STUN_PCT, // 13 + APPLY_SLOW_PCT, // 14 + APPLY_CRITICAL_PCT, // 15 + APPLY_PENETRATE_PCT, // 16 + APPLY_ATTBONUS_HUMAN, // 17 + APPLY_ATTBONUS_ANIMAL, // 18 + APPLY_ATTBONUS_ORC, // 19 + APPLY_ATTBONUS_MILGYO, // 20 + APPLY_ATTBONUS_UNDEAD, // 21 + APPLY_ATTBONUS_DEVIL, // 22 + APPLY_STEAL_HP, // 23 + APPLY_STEAL_SP, // 24 + APPLY_MANA_BURN_PCT, // 25 + APPLY_DAMAGE_SP_RECOVER, // 26 + APPLY_BLOCK, // 27 + APPLY_DODGE, // 28 + APPLY_RESIST_SWORD, // 29 + APPLY_RESIST_TWOHAND, // 30 + APPLY_RESIST_DAGGER, // 31 + APPLY_RESIST_BELL, // 32 + APPLY_RESIST_FAN, // 33 + APPLY_RESIST_BOW, // 34 + APPLY_RESIST_FIRE, // 35 + APPLY_RESIST_ELEC, // 36 + APPLY_RESIST_MAGIC, // 37 + APPLY_RESIST_WIND, // 38 + APPLY_REFLECT_MELEE, // 39 + APPLY_REFLECT_CURSE, // 40 + APPLY_POISON_REDUCE, // 41 + APPLY_KILL_SP_RECOVER, // 42 + APPLY_EXP_DOUBLE_BONUS, // 43 + APPLY_GOLD_DOUBLE_BONUS, // 44 + APPLY_ITEM_DROP_BONUS, // 45 + APPLY_POTION_BONUS, // 46 + APPLY_KILL_HP_RECOVER, // 47 + APPLY_IMMUNE_STUN, // 48 + APPLY_IMMUNE_SLOW, // 49 + APPLY_IMMUNE_FALL, // 50 + APPLY_SKILL, // 51 + APPLY_BOW_DISTANCE, // 52 + APPLY_ATT_GRADE_BONUS, // 53 + APPLY_DEF_GRADE_BONUS, // 54 + APPLY_MAGIC_ATT_GRADE, // 55 + APPLY_MAGIC_DEF_GRADE, // 56 + APPLY_CURSE_PCT, // 57 + APPLY_MAX_STAMINA, // 58 + APPLY_ATT_BONUS_TO_WARRIOR, // 59 + APPLY_ATT_BONUS_TO_ASSASSIN,// 60 + APPLY_ATT_BONUS_TO_SURA, // 61 + APPLY_ATT_BONUS_TO_SHAMAN, // 62 + APPLY_ATT_BONUS_TO_MONSTER, // 63 + APPLY_MALL_ATTBONUS, // 64 ݷ +x% + APPLY_MALL_DEFBONUS, // 65 +x% + APPLY_MALL_EXPBONUS, // 66 ġ +x% + APPLY_MALL_ITEMBONUS, // 67 x/10 + APPLY_MALL_GOLDBONUS, // 68 x/10 + APPLY_MAX_HP_PCT, // 69 ִ +x% + APPLY_MAX_SP_PCT, // 70 ִ ŷ +x% + APPLY_SKILL_DAMAGE_BONUS, // 71 ų * (100+x)% + APPLY_NORMAL_HIT_DAMAGE_BONUS, // 72 Ÿ * (100+x)% + APPLY_SKILL_DEFEND_BONUS, // 73 ų * (100-x)% + APPLY_NORMAL_HIT_DEFEND_BONUS, // 74 Ÿ * (100-x)% + APPLY_EXTRACT_HP_PCT, //75 + APPLY_PC_BANG_EXP_BONUS, //76 + APPLY_PC_BANG_DROP_BONUS, //77 + APPLY_RESIST_WARRIOR, //78 + APPLY_RESIST_ASSASSIN , //79 + APPLY_RESIST_SURA, //80 + APPLY_RESIST_SHAMAN, //81 + APPLY_ENERGY, //82 + APPLY_DEF_GRADE, // 83 . DEF_GRADE_BONUS Ŭ󿡼 ι ǵ (...) ִ. + APPLY_COSTUME_ATTR_BONUS, // 84 ڽƬ ۿ Ӽġ ʽ + APPLY_MAGIC_ATTBONUS_PER, // 85 ݷ +x% + APPLY_MELEE_MAGIC_ATTBONUS_PER, // 86 + и ݷ +x% + + APPLY_RESIST_ICE, // 87 ñ + APPLY_RESIST_EARTH, // 88 + APPLY_RESIST_DARK, // 89 + + APPLY_ANTI_CRITICAL_PCT, //90 ũƼ + APPLY_ANTI_PENETRATE_PCT, //91 Ÿ + + MAX_APPLY_NUM, // + }; + + enum EImmuneFlags + { + IMMUNE_PARA = (1 << 0), + IMMUNE_CURSE = (1 << 1), + IMMUNE_STUN = (1 << 2), + IMMUNE_SLEEP = (1 << 3), + IMMUNE_SLOW = (1 << 4), + IMMUNE_POISON = (1 << 5), + IMMUNE_TERROR = (1 << 6), + }; + +#pragma pack(push) +#pragma pack(1) + typedef struct SItemLimit + { + BYTE bType; + long lValue; + } TItemLimit; + + typedef struct SItemApply + { + BYTE bType; + long lValue; + } TItemApply; + + typedef struct SItemTable + { + DWORD dwVnum; + DWORD dwVnumRange; + char szName[ITEM_NAME_MAX_LEN + 1]; + char szLocaleName[ITEM_NAME_MAX_LEN + 1]; + BYTE bType; + BYTE bSubType; + + BYTE bWeight; + BYTE bSize; + + DWORD dwAntiFlags; + DWORD dwFlags; + DWORD dwWearFlags; + DWORD dwImmuneFlag; + + DWORD dwIBuyItemPrice; + DWORD dwISellItemPrice; + + TItemLimit aLimits[ITEM_LIMIT_MAX_NUM]; + TItemApply aApplies[ITEM_APPLY_MAX_NUM]; + long alValues[ITEM_VALUES_MAX_NUM]; + long alSockets[ITEM_SOCKET_MAX_NUM]; + DWORD dwRefinedVnum; + WORD wRefineSet; + BYTE bAlterToMagicItemPct; + BYTE bSpecular; + BYTE bGainSocketPct; + } TItemTable; + +// typedef struct SItemTable +// { +// DWORD dwVnum; +// char szItemName[ITEM_NAME_MAX_LEN + 1]; +// BYTE bType; +// BYTE bSubType; +// BYTE bSize; +// DWORD dwAntiFlags; +// DWORD dwFlags; +// DWORD dwWearFlags; +// DWORD dwIBuyItemPrice; +// DWORD dwISellItemPrice; +// TItemLimit aLimits[ITEM_LIMIT_MAX_NUM]; +// TItemApply aApplies[ITEM_APPLY_MAX_NUM]; +// long alValues[ITEM_VALUES_MAX_NUM]; +// long alSockets[ITEM_SOCKET_MAX_NUM]; +// DWORD dwRefinedVnum; +// BYTE bSpecular; +// DWORD dwIconNumber; +// } TItemTable; +#pragma pack(pop) + + public: + CItemData(); + virtual ~CItemData(); + + void Clear(); + void SetSummary(const std::string& c_rstSumm); + void SetDescription(const std::string& c_rstDesc); + + CGraphicThing * GetModelThing(); + CGraphicThing * GetSubModelThing(); + CGraphicThing * GetDropModelThing(); + CGraphicSubImage * GetIconImage(); + + DWORD GetLODModelThingCount(); + BOOL GetLODModelThingPointer(DWORD dwIndex, CGraphicThing ** ppModelThing); + + DWORD GetAttachingDataCount(); + BOOL GetCollisionDataPointer(DWORD dwIndex, const NRaceData::TAttachingData ** c_ppAttachingData); + BOOL GetAttachingDataPointer(DWORD dwIndex, const NRaceData::TAttachingData ** c_ppAttachingData); + + ///// + const TItemTable* GetTable() const; + DWORD GetIndex() const; + const char * GetName() const; + const char * GetDescription() const; + const char * GetSummary() const; + BYTE GetType() const; + BYTE GetSubType() const; + UINT GetRefine() const; + const char* GetUseTypeString() const; + DWORD GetWeaponType() const; + BYTE GetSize() const; + BOOL IsAntiFlag(DWORD dwFlag) const; + BOOL IsFlag(DWORD dwFlag) const; + BOOL IsWearableFlag(DWORD dwFlag) const; + BOOL HasNextGrade() const; + DWORD GetWearFlags() const; + DWORD GetIBuyItemPrice() const; + DWORD GetISellItemPrice() const; + BOOL GetLimit(BYTE byIndex, TItemLimit * pItemLimit) const; + BOOL GetApply(BYTE byIndex, TItemApply * pItemApply) const; + long GetValue(BYTE byIndex) const; + long GetSocket(BYTE byIndex) const; + long SetSocket(BYTE byIndex,DWORD value); + int GetSocketCount() const; + DWORD GetIconNumber() const; + + UINT GetSpecularPoweru() const; + float GetSpecularPowerf() const; + + ///// + + BOOL IsEquipment() const; + + ///// + + //BOOL LoadItemData(const char * c_szFileName); + void SetDefaultItemData(const char * c_szIconFileName, const char * c_szModelFileName = NULL); + void SetItemTableData(TItemTable * pItemTable); + + protected: + void __LoadFiles(); + void __SetIconImage(const char * c_szFileName); + + protected: + std::string m_strModelFileName; + std::string m_strSubModelFileName; + std::string m_strDropModelFileName; + std::string m_strIconFileName; + std::string m_strDescription; + std::string m_strSummary; + std::vector m_strLODModelFileNameVector; + + CGraphicThing * m_pModelThing; + CGraphicThing * m_pSubModelThing; + CGraphicThing * m_pDropModelThing; + CGraphicSubImage * m_pIconImage; + std::vector m_pLODModelThingVector; + + NRaceData::TAttachingDataVector m_AttachingDataVector; + DWORD m_dwVnum; + TItemTable m_ItemTable; + + public: + static void DestroySystem(); + + static CItemData* New(); + static void Delete(CItemData* pkItemData); + + static CDynamicPool ms_kPool; +}; diff --git a/source/GameLib/ItemManager.cpp b/source/GameLib/ItemManager.cpp new file mode 100644 index 0000000..8e96b0e --- /dev/null +++ b/source/GameLib/ItemManager.cpp @@ -0,0 +1,404 @@ +#include "StdAfx.h" +#include "../eterPack/EterPackManager.h" +#include "../eterLib/ResourceManager.h" + +#include "ItemManager.h" + +static DWORD s_adwItemProtoKey[4] = +{ + 173217, + 72619434, + 408587239, + 27973291 +}; + +BOOL CItemManager::SelectItemData(DWORD dwIndex) +{ + TItemMap::iterator f = m_ItemMap.find(dwIndex); + + if (m_ItemMap.end() == f) + { + int n = m_vec_ItemRange.size(); + for (int i = 0; i < n; i++) + { + CItemData * p = m_vec_ItemRange[i]; + const CItemData::TItemTable * pTable = p->GetTable(); + if ((pTable->dwVnum < dwIndex) && + dwIndex < (pTable->dwVnum + pTable->dwVnumRange)) + { + m_pSelectedItemData = p; + return TRUE; + } + } + Tracef(" CItemManager::SelectItemData - FIND ERROR [%d]\n", dwIndex); + return FALSE; + } + + m_pSelectedItemData = f->second; + + return TRUE; +} + +CItemData * CItemManager::GetSelectedItemDataPointer() +{ + return m_pSelectedItemData; +} + +BOOL CItemManager::GetItemDataPointer(DWORD dwItemID, CItemData ** ppItemData) +{ + if (0 == dwItemID) + return FALSE; + + TItemMap::iterator f = m_ItemMap.find(dwItemID); + + if (m_ItemMap.end() == f) + { + int n = m_vec_ItemRange.size(); + for (int i = 0; i < n; i++) + { + CItemData * p = m_vec_ItemRange[i]; + const CItemData::TItemTable * pTable = p->GetTable(); + if ((pTable->dwVnum < dwItemID) && + dwItemID < (pTable->dwVnum + pTable->dwVnumRange)) + { + *ppItemData = p; + return TRUE; + } + } + Tracef(" CItemManager::GetItemDataPointer - FIND ERROR [%d]\n", dwItemID); + return FALSE; + } + + *ppItemData = f->second; + + return TRUE; +} + +CItemData * CItemManager::MakeItemData(DWORD dwIndex) +{ + TItemMap::iterator f = m_ItemMap.find(dwIndex); + + if (m_ItemMap.end() == f) + { + CItemData * pItemData = CItemData::New(); + + m_ItemMap.insert(TItemMap::value_type(dwIndex, pItemData)); + + return pItemData; + } + + return f->second; +} + +//////////////////////////////////////////////////////////////////////////////////////// +// Load Item Table + +bool CItemManager::LoadItemList(const char * c_szFileName) +{ + CMappedFile File; + LPCVOID pData; + + if (!CEterPackManager::Instance().Get(File, c_szFileName, &pData)) + return false; + + CMemoryTextFileLoader textFileLoader; + textFileLoader.Bind(File.Size(), pData); + + CTokenVector TokenVector; + for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i) + { + if (!textFileLoader.SplitLine(i, &TokenVector, "\t")) + continue; + + if (!(TokenVector.size() == 3 || TokenVector.size() == 4)) + { + TraceError(" CItemManager::LoadItemList(%s) - StrangeLine in %d\n", c_szFileName, i); + continue; + } + + const std::string & c_rstrID = TokenVector[0]; + //const std::string & c_rstrType = TokenVector[1]; + const std::string & c_rstrIcon = TokenVector[2]; + + DWORD dwItemVNum=atoi(c_rstrID.c_str()); + + CItemData * pItemData = MakeItemData(dwItemVNum); + + extern BOOL USE_VIETNAM_CONVERT_WEAPON_VNUM; + if (USE_VIETNAM_CONVERT_WEAPON_VNUM) + { + extern DWORD Vietnam_ConvertWeaponVnum(DWORD vnum); + DWORD dwMildItemVnum = Vietnam_ConvertWeaponVnum(dwItemVNum); + if (dwMildItemVnum == dwItemVNum) + { + if (4 == TokenVector.size()) + { + const std::string & c_rstrModelFileName = TokenVector[3]; + pItemData->SetDefaultItemData(c_rstrIcon.c_str(), c_rstrModelFileName.c_str()); + } + else + { + pItemData->SetDefaultItemData(c_rstrIcon.c_str()); + } + } + else + { + DWORD dwMildBaseVnum = dwMildItemVnum / 10 * 10; + char szMildIconPath[MAX_PATH]; + sprintf(szMildIconPath, "icon/item/%.5d.tga", dwMildBaseVnum); + if (4 == TokenVector.size()) + { + char szMildModelPath[MAX_PATH]; + sprintf(szMildModelPath, "d:/ymir work/item/weapon/%.5d.gr2", dwMildBaseVnum); + pItemData->SetDefaultItemData(szMildIconPath, szMildModelPath); + } + else + { + pItemData->SetDefaultItemData(szMildIconPath); + } + } + } + else + { + if (4 == TokenVector.size()) + { + const std::string & c_rstrModelFileName = TokenVector[3]; + pItemData->SetDefaultItemData(c_rstrIcon.c_str(), c_rstrModelFileName.c_str()); + } + else + { + pItemData->SetDefaultItemData(c_rstrIcon.c_str()); + } + } + } + + return true; +} + +const std::string& __SnapString(const std::string& c_rstSrc, std::string& rstTemp) +{ + UINT uSrcLen=c_rstSrc.length(); + if (uSrcLen<2) + return c_rstSrc; + + if (c_rstSrc[0]!='"') + return c_rstSrc; + + UINT uLeftCut=1; + + UINT uRightCut=uSrcLen; + if (c_rstSrc[uSrcLen-1]=='"') + uRightCut=uSrcLen-1; + + rstTemp=c_rstSrc.substr(uLeftCut, uRightCut-uLeftCut); + return rstTemp; +} + +bool CItemManager::LoadItemDesc(const char* c_szFileName) +{ + const VOID* pvData; + CMappedFile kFile; + if (!CEterPackManager::Instance().Get(kFile, c_szFileName, &pvData)) + { + Tracenf("CItemManager::LoadItemDesc(c_szFileName=%s) - Load Error", c_szFileName); + return false; + } + + CMemoryTextFileLoader kTextFileLoader; + kTextFileLoader.Bind(kFile.Size(), pvData); + + std::string stTemp; + + CTokenVector kTokenVector; + for (DWORD i = 0; i < kTextFileLoader.GetLineCount(); ++i) + { + if (!kTextFileLoader.SplitLineByTab(i, &kTokenVector)) + continue; + + while (kTokenVector.size()second; + + pkItemDataFind->SetDescription(__SnapString(c_rstDesc, stTemp)); + pkItemDataFind->SetSummary(__SnapString(c_rstSumm, stTemp)); + } + return true; +} + +DWORD GetHashCode( const char* pString ) +{ + unsigned long i,len; + unsigned long ch; + unsigned long result; + + len = strlen( pString ); + result = 5381; + for( i=0; i itemNameMap; + + for (DWORD i = 0; i < dwElements; ++i, ++table) + { + CItemData * pItemData; + DWORD dwVnum = table->dwVnum; + + TItemMap::iterator f = m_ItemMap.find(dwVnum); + if (m_ItemMap.end() == f) + { + _snprintf(szName, sizeof(szName), "icon/item/%05d.tga", dwVnum); + + if (CResourceManager::Instance().IsFileExist(szName) == false) + { + std::map::iterator itVnum = itemNameMap.find(GetHashCode(table->szName)); + + if (itVnum != itemNameMap.end()) + _snprintf(szName, sizeof(szName), "icon/item/%05d.tga", itVnum->second); + else + _snprintf(szName, sizeof(szName), "icon/item/%05d.tga", dwVnum-dwVnum % 10); + + if (CResourceManager::Instance().IsFileExist(szName) == false) + { + #ifdef _DEBUG + TraceError("%16s(#%-5d) cannot find icon file. setting to default.", table->szName, dwVnum); + #endif + const DWORD EmptyBowl = 27995; + _snprintf(szName, sizeof(szName), "icon/item/%05d.tga", EmptyBowl); + } + } + + pItemData = CItemData::New(); + + pItemData->SetDefaultItemData(szName); + m_ItemMap.insert(TItemMap::value_type(dwVnum, pItemData)); + } + else + { + pItemData = f->second; + } + if (itemNameMap.find(GetHashCode(table->szName)) == itemNameMap.end()) + itemNameMap.insert(std::map::value_type(GetHashCode(table->szName),table->dwVnum)); + pItemData->SetItemTableData(table); + if (0 != table->dwVnumRange) + { + m_vec_ItemRange.push_back(pItemData); + } + } + +//!@# +// CItemData::TItemTable * table = (CItemData::TItemTable *) zObj.GetBuffer(); +// for (DWORD i = 0; i < dwElements; ++i, ++table) +// { +// CItemData * pItemData; +// DWORD dwVnum = table->dwVnum; +// +// TItemMap::iterator f = m_ItemMap.find(dwVnum); +// +// if (m_ItemMap.end() == f) +// { +// pItemData = CItemData::New(); +// +// pItemData->LoadItemData(_getf("d:/ymir work/item/%05d.msm", dwVnum)); +// m_ItemMap.insert(TItemMap::value_type(dwVnum, pItemData)); +// } +// else +// { +// pItemData = f->second; +// } +// pItemData->SetItemTableData(table); +// } + + delete [] pbData; + return true; +} + +void CItemManager::Destroy() +{ + TItemMap::iterator i; + for (i=m_ItemMap.begin(); i!=m_ItemMap.end(); ++i) + CItemData::Delete(i->second); + + m_ItemMap.clear(); +} + +CItemManager::CItemManager() : m_pSelectedItemData(NULL) +{ +} +CItemManager::~CItemManager() +{ + Destroy(); +} diff --git a/source/GameLib/ItemManager.h b/source/GameLib/ItemManager.h new file mode 100644 index 0000000..b7100a7 --- /dev/null +++ b/source/GameLib/ItemManager.h @@ -0,0 +1,42 @@ +#pragma once + +#include "ItemData.h" + +class CItemManager : public CSingleton +{ + public: + enum EItemDescCol + { + ITEMDESC_COL_VNUM, + ITEMDESC_COL_NAME, + ITEMDESC_COL_DESC, + ITEMDESC_COL_SUMM, + ITEMDESC_COL_NUM, + }; + + public: + typedef std::map TItemMap; + typedef std::map TItemNameMap; + + public: + CItemManager(); + virtual ~CItemManager(); + + void Destroy(); + + BOOL SelectItemData(DWORD dwIndex); + CItemData * GetSelectedItemDataPointer(); + + BOOL GetItemDataPointer(DWORD dwItemID, CItemData ** ppItemData); + + ///// + bool LoadItemDesc(const char* c_szFileName); + bool LoadItemList(const char* c_szFileName); + bool LoadItemTable(const char* c_szFileName); + CItemData * MakeItemData(DWORD dwIndex); + + protected: + TItemMap m_ItemMap; + std::vector m_vec_ItemRange; + CItemData * m_pSelectedItemData; +}; diff --git a/source/GameLib/MapBase.cpp b/source/GameLib/MapBase.cpp new file mode 100644 index 0000000..b1957f1 --- /dev/null +++ b/source/GameLib/MapBase.cpp @@ -0,0 +1,101 @@ +#include "StdAfx.h" +#include "MapBase.h" + +CMapBase::CMapBase() +{ + Clear(); +} + +CMapBase::~CMapBase() +{ + Clear(); +} + +void CMapBase::Clear() +{ + m_strName = ""; + m_eType = MAPTYPE_INVALID; + mc_pEnvironmentData = NULL; + Leave(); +} + +bool CMapBase::Enter() +{ + m_bReady = true; + return true; +} + +bool CMapBase::Leave() +{ + m_bReady = false; + return true; +} + +void CMapBase::SetEnvironmentDataPtr(const TEnvironmentData * c_pEnvironmentData) +{ + mc_pEnvironmentData = c_pEnvironmentData; + OnSetEnvironmentDataPtr(); +} + +void CMapBase::ResetEnvironmentDataPtr(const TEnvironmentData * c_pEnvironmentData) +{ + mc_pEnvironmentData = c_pEnvironmentData; + OnResetEnvironmentDataPtr(); +} + +void CMapBase::Render() +{ + if (IsReady()) + OnRender(); +} + +bool CMapBase::LoadProperty() +{ + std::string strFileName = GetName() + "\\MapProperty.txt"; + + CTokenVectorMap stTokenVectorMap; + + if (!LoadMultipleTextData(strFileName.c_str(), stTokenVectorMap)) + { + TraceError("CMapBase::LoadProperty(FileName=%s) - LoadMultipleTextData ERROR ɼ ϴ.", strFileName.c_str()); + return false; + } + + if (stTokenVectorMap.end() == stTokenVectorMap.find("scripttype")) + { + TraceError("CMapBase::LoadProperty(FileName=%s) - FIND 'scripttype' - FAILED", strFileName.c_str()); + return false; + } + + if (stTokenVectorMap.end() == stTokenVectorMap.find("maptype")) + { + TraceError("CMapBase::LoadProperty(FileName=%s) - FIND 'maptype' - FAILED", strFileName.c_str()); + return false; + } + + // NOTE: ̹ ϴ Ϳ ͸ ϴ ߰ , 뷮 ̱ ۾. + // MapProperty.txt Ͽ ParentMapName Ǿ ִٸ, ʹ ParentMap о´. + // κа(κ Ʈ?) ʿ 뼭, Parent Map ͸ о. + if (stTokenVectorMap.end() != stTokenVectorMap.find("parentmapname")) + { + m_strParentMapName = stTokenVectorMap["parentmapname"][0]; + } + + const std::string & c_rstrType = stTokenVectorMap["scripttype"][0]; + const std::string & c_rstrMapType = stTokenVectorMap["maptype"][0]; + + if (0 != c_rstrType.compare("MapProperty")) + { + TraceError("CMapBase::LoadProperty(FileName=%s) - Resourse Type ERROR", strFileName.c_str()); + return false; + } + + if (0 == c_rstrMapType.compare("Indoor")) + SetType(MAPTYPE_INDOOR); + else if (0 == c_rstrMapType.compare("Outdoor")) + SetType(MAPTYPE_OUTDOOR); + else if (0 == c_rstrMapType.compare("Invalid")) + SetType(MAPTYPE_OUTDOOR); + + return true; +} \ No newline at end of file diff --git a/source/GameLib/MapBase.h b/source/GameLib/MapBase.h new file mode 100644 index 0000000..2784efd --- /dev/null +++ b/source/GameLib/MapBase.h @@ -0,0 +1,64 @@ +#pragma once + +class CMapBase : public CScreen +{ + public: + enum EMAPTYPE + { + MAPTYPE_INVALID, + MAPTYPE_INDOOR, + MAPTYPE_OUTDOOR, + }; + + public: + CMapBase(); + virtual ~CMapBase(); + + virtual void Clear(); + virtual bool Initialize() = 0; + virtual bool Destroy() = 0; + virtual bool Load(float x, float y, float z) = 0; + + virtual bool Update(float fX, float fY, float fZ) = 0; + virtual void UpdateAroundAmbience(float fX, float fY, float fZ) = 0; + virtual float GetHeight(float fx, float fy) = 0; + virtual void OnBeginEnvironment() = 0; // ҷ ⼭ Environment ִ ͵ Ѵ. + + virtual void ApplyLight(DWORD dwVersion, const D3DLIGHT8& c_rkLight) = 0; + + protected: + virtual void OnRender() = 0; + virtual void OnSetEnvironmentDataPtr() = 0; // Environment Ͱ ҷ. + virtual void OnResetEnvironmentDataPtr() = 0; + + public: + void Render(); + void SetEnvironmentDataPtr(const TEnvironmentData * c_pEnvironmentData); + void ResetEnvironmentDataPtr(const TEnvironmentData * c_pEnvironmentData); + bool Enter(); + bool Leave(); + bool IsReady() { return m_bReady; } + + bool LoadProperty(); + + ////////////////////////////////////////////////////////////////////////// + // Setting + ////////////////////////////////////////////////////////////////////////// + EMAPTYPE GetType() const { return m_eType; } + void SetType(EMAPTYPE eType) { m_eType = eType; } + + const std::string & GetName() const { return m_strName; } + void SetName(const std::string & cr_strName) { m_strName = cr_strName; } + + bool IsCopiedMap() const { return m_strParentMapName.length() > 0; } // " ʹ ִ" ΰ? + const std::string& GetParentMapName() const { return m_strParentMapName; } // ͸ ִ ̸ ( ʼ õǾ ) + const std::string& GetMapDataDirectory() const { return IsCopiedMap() ? m_strParentMapName : m_strName; } + + protected: + EMAPTYPE m_eType; // ... Indoor Ourdoor ִ. + std::string m_strName; // ̸. ̸ ĺڰ ? + std::string m_strParentMapName; // ̸. õǾ ִٸ ʹ ParentMap/* ο о´. Ϻθ о ʿ뼭 н. + bool m_bReady; + + const TEnvironmentData * mc_pEnvironmentData; +}; diff --git a/source/GameLib/MapManager.cpp b/source/GameLib/MapManager.cpp new file mode 100644 index 0000000..6cb0110 --- /dev/null +++ b/source/GameLib/MapManager.cpp @@ -0,0 +1,638 @@ +#include "StdAfx.h" +#include "../eterLib/StateManager.h" +#include "../EterPack/EterPackManager.h" + +#include "MapManager.h" +#include "MapOutdoor.h" + +#include "PropertyLoader.h" + +////////////////////////////////////////////////////////////////////////// +// ⺻ Լ +////////////////////////////////////////////////////////////////////////// + +bool CMapManager::IsMapOutdoor() +{ + if (m_pkMap) + return true; + + return false; +} + +CMapOutdoor& CMapManager::GetMapOutdoorRef() +{ + assert(NULL!=m_pkMap); + return *m_pkMap; +} + + +CMapManager::CMapManager() : mc_pcurEnvironmentData(NULL) +{ + m_pkMap = NULL; + m_isSoftwareTilingEnableReserved=false; + +// Initialize(); +} + +CMapManager::~CMapManager() +{ + Destroy(); +} + +bool CMapManager::IsSoftwareTilingEnable() +{ + return CTerrainPatch::SOFTWARE_TRANSFORM_PATCH_ENABLE; +} + +void CMapManager::ReserveSoftwareTilingEnable(bool isEnable) +{ + m_isSoftwareTilingEnableReserved=isEnable; +} + + +void CMapManager::Initialize() +{ + mc_pcurEnvironmentData = NULL; + __LoadMapInfoVector(); +} + +void CMapManager::Create() +{ + assert(NULL==m_pkMap && "CMapManager::Create"); + if (m_pkMap) + { + Clear(); + return; + } + + CTerrainPatch::SOFTWARE_TRANSFORM_PATCH_ENABLE=m_isSoftwareTilingEnableReserved; + + m_pkMap = (CMapOutdoor*)AllocMap(); + + assert(NULL!=m_pkMap && "CMapManager::Create MAP is NULL"); + +} + +void CMapManager::Destroy() +{ + stl_wipe_second(m_EnvironmentDataMap); + + if (m_pkMap) + { + m_pkMap->Clear(); + delete m_pkMap; + m_pkMap = NULL; + } +} + +void CMapManager::Clear() +{ + if (m_pkMap) + m_pkMap->Clear(); +} + +CMapBase * CMapManager::AllocMap() +{ + return new CMapOutdoor; +} + +////////////////////////////////////////////////////////////////////////// +// Map +////////////////////////////////////////////////////////////////////////// +void CMapManager::LoadProperty() +{ + CPropertyLoader PropertyLoader; + PropertyLoader.SetPropertyManager(&m_PropertyManager); + PropertyLoader.Create("*.*", "Property"); +} + +bool CMapManager::LoadMap(const std::string & c_rstrMapName, float x, float y, float z) +{ + CMapOutdoor& rkMap = GetMapOutdoorRef(); + + rkMap.Leave(); + rkMap.SetName(c_rstrMapName); + rkMap.LoadProperty(); + + if ( CMapBase::MAPTYPE_INDOOR == rkMap.GetType()) + { + TraceError("CMapManager::LoadMap() Indoor Map Load Failed"); + return false; + } + else if (CMapBase::MAPTYPE_OUTDOOR == rkMap.GetType()) + { + if (!rkMap.Load(x, y, z)) + { + TraceError("CMapManager::LoadMap() Outdoor Map Load Failed"); + return false; + } + + RegisterEnvironmentData(0, rkMap.GetEnvironmentDataName().c_str()); + + SetEnvironmentData(0); + } + else + { + TraceError("CMapManager::LoadMap() Invalid Map Type"); + return false; + } + + rkMap.Enter(); + return true; +} + +bool CMapManager::IsMapReady() +{ + if (!m_pkMap) + return false; + + return m_pkMap->IsReady(); +} + +bool CMapManager::UnloadMap(const std::string c_strMapName) +{ + CMapOutdoor& rkMap=GetMapOutdoorRef(); + if (c_strMapName != rkMap.GetName() && "" != rkMap.GetName()) + { + LogBoxf("%s: Unload Map Failed", c_strMapName.c_str()); + return false; + } + + Clear(); + return true; +} + +bool CMapManager::UpdateMap(float fx, float fy, float fz) +{ + if (!m_pkMap) + return false; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + return rkMap.Update(fx, -fy, fz); +} + +void CMapManager::UpdateAroundAmbience(float fx, float fy, float fz) +{ + if (!m_pkMap) + return; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + rkMap.UpdateAroundAmbience(fx, -fy, fz); +} + +float CMapManager::GetHeight(float fx, float fy) +{ + if (!m_pkMap) + { + TraceError("CMapManager::GetHeight(%f, %f) - ¿ ", fx, fy); + return 0.0f; + } + CMapOutdoor& rkMap=GetMapOutdoorRef(); + return rkMap.GetHeight(fx, fy); +} + +float CMapManager::GetTerrainHeight(float fx, float fy) +{ + if (!m_pkMap) + { + TraceError("CMapManager::GetTerrainHeight(%f, %f) - ¿ ", fx, fy); + return 0.0f; + } + CMapOutdoor& rkMap=GetMapOutdoorRef(); + return rkMap.GetTerrainHeight(fx, fy); +} + +bool CMapManager::GetWaterHeight(int iX, int iY, long * plWaterHeight) +{ + if (!m_pkMap) + { + TraceError("CMapManager::GetTerrainHeight(%f, %f) - ¿ ", iX, iY); + return false; + } + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + return rkMap.GetWaterHeight(iX, iY, plWaterHeight); +} + +////////////////////////////////////////////////////////////////////////// +// Environment +////////////////////////////////////////////////////////////////////////// +void CMapManager::BeginEnvironment() +{ + if (!m_pkMap) + return; + + if (!mc_pcurEnvironmentData) + return; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + + // Light always on + STATEMANAGER.SaveRenderState(D3DRS_LIGHTING, TRUE); + + // Fog + STATEMANAGER.SaveRenderState(D3DRS_FOGENABLE, mc_pcurEnvironmentData->bFogEnable); + + // Material + STATEMANAGER.SetMaterial(&mc_pcurEnvironmentData->Material); + + // Directional Light + if (mc_pcurEnvironmentData->bDirLightsEnable[ENV_DIRLIGHT_BACKGROUND]) + { + ms_lpd3dDevice->LightEnable(0, TRUE); + + rkMap.ApplyLight((DWORD)mc_pcurEnvironmentData, mc_pcurEnvironmentData->DirLights[ENV_DIRLIGHT_BACKGROUND]); + } + else + ms_lpd3dDevice->LightEnable(0, FALSE); + + if (mc_pcurEnvironmentData->bFogEnable) + { + DWORD dwFogColor = mc_pcurEnvironmentData->FogColor; + STATEMANAGER.SetRenderState(D3DRS_FOGCOLOR, dwFogColor); + + if (mc_pcurEnvironmentData->bDensityFog) + { + float fDensity = 0.00015f; + STATEMANAGER.SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_EXP); // pixel fog + STATEMANAGER.SetRenderState(D3DRS_FOGDENSITY, *((DWORD *) &fDensity)); // vertex fog + } + else + { + CSpeedTreeForestDirectX8& rkForest=CSpeedTreeForestDirectX8::Instance(); + rkForest.SetFog( + mc_pcurEnvironmentData->GetFogNearDistance(), + mc_pcurEnvironmentData->GetFogFarDistance() + ); + + float fFogNear=mc_pcurEnvironmentData->GetFogNearDistance(); + float fFogFar=mc_pcurEnvironmentData->GetFogFarDistance(); + STATEMANAGER.SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR); // vertex fox + STATEMANAGER.SetRenderState(D3DRS_RANGEFOGENABLE, TRUE); // vertex fox + STATEMANAGER.SetRenderState(D3DRS_FOGSTART, *((DWORD *) &fFogNear)); // USED BY D3DFOG_LINEAR + STATEMANAGER.SetRenderState(D3DRS_FOGEND, *((DWORD *) &fFogFar)); // USED BY D3DFOG_LINEAR + } + } + + rkMap.OnBeginEnvironment(); +} + +void CMapManager::EndEnvironment() +{ + if (!mc_pcurEnvironmentData) + return; + + STATEMANAGER.RestoreRenderState(D3DRS_LIGHTING); + STATEMANAGER.RestoreRenderState(D3DRS_FOGENABLE); +} + +void CMapManager::SetEnvironmentData(int nEnvDataIndex) +{ + const TEnvironmentData * c_pEnvironmenData; + + if (GetEnvironmentData(nEnvDataIndex, &c_pEnvironmenData)) + SetEnvironmentDataPtr(c_pEnvironmenData); +} + +void CMapManager::SetEnvironmentDataPtr(const TEnvironmentData * c_pEnvironmentData) +{ + if (!m_pkMap) + return; + + if (!c_pEnvironmentData) + { + assert(!"null environment data"); + TraceError("null environment data"); + return; + } + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + + + mc_pcurEnvironmentData = c_pEnvironmentData; + + + rkMap.SetEnvironmentDataPtr(mc_pcurEnvironmentData); +} + +void CMapManager::ResetEnvironmentDataPtr(const TEnvironmentData * c_pEnvironmentData) +{ + if (!m_pkMap) + return; + + if (!c_pEnvironmentData) + { + assert(!"null environment data"); + TraceError("null environment data"); + return; + } + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + + mc_pcurEnvironmentData = c_pEnvironmentData; + rkMap.ResetEnvironmentDataPtr(mc_pcurEnvironmentData); +} + +void CMapManager::BlendEnvironmentData(const TEnvironmentData * c_pEnvironmentData, int iTransitionTime) +{ +} + +bool CMapManager::RegisterEnvironmentData(DWORD dwIndex, const char * c_szFileName) +{ + TEnvironmentData * pEnvironmentData = AllocEnvironmentData(); + + if (!LoadEnvironmentData(c_szFileName, pEnvironmentData)) + { + DeleteEnvironmentData(pEnvironmentData); + return false; + } + + TEnvironmentDataMap::iterator f=m_EnvironmentDataMap.find(dwIndex); + if (m_EnvironmentDataMap.end()==f) + { + m_EnvironmentDataMap.insert(TEnvironmentDataMap::value_type(dwIndex, pEnvironmentData)); + } + else + { + delete f->second; + f->second=pEnvironmentData; + } + return true; +} + +void CMapManager::GetCurrentEnvironmentData(const TEnvironmentData ** c_ppEnvironmentData) +{ + *c_ppEnvironmentData = mc_pcurEnvironmentData; +} + +bool CMapManager::GetEnvironmentData(DWORD dwIndex, const TEnvironmentData ** c_ppEnvironmentData) +{ + TEnvironmentDataMap::iterator itor = m_EnvironmentDataMap.find(dwIndex); + + if (m_EnvironmentDataMap.end() == itor) + { + *c_ppEnvironmentData = NULL; + return false; + } + + *c_ppEnvironmentData = itor->second; + return true; +} + +void CMapManager::RefreshPortal() +{ + if (!IsMapReady()) + return; + + CMapOutdoor & rMap = GetMapOutdoorRef(); + for (int i = 0; i < AROUND_AREA_NUM; ++i) + { + CArea * pArea; + if (!rMap.GetAreaPointer(i, &pArea)) + continue; + + pArea->RefreshPortal(); + } +} + +void CMapManager::ClearPortal() +{ + if (!IsMapReady()) + return; + + CMapOutdoor & rMap = GetMapOutdoorRef(); + for (int i = 0; i < AROUND_AREA_NUM; ++i) + { + CArea * pArea; + if (!rMap.GetAreaPointer(i, &pArea)) + continue; + + pArea->ClearPortal(); + } +} + +void CMapManager::AddShowingPortalID(int iID) +{ + if (!IsMapReady()) + return; + + CMapOutdoor & rMap = GetMapOutdoorRef(); + for (int i = 0; i < AROUND_AREA_NUM; ++i) + { + CArea * pArea; + if (!rMap.GetAreaPointer(i, &pArea)) + continue; + + pArea->AddShowingPortalID(iID); + } +} + +TEnvironmentData * CMapManager::AllocEnvironmentData() +{ + TEnvironmentData * pEnvironmentData = new TEnvironmentData; + Environment_Init(*pEnvironmentData); + return pEnvironmentData; +} + +void CMapManager::DeleteEnvironmentData(TEnvironmentData * pEnvironmentData) +{ + delete pEnvironmentData; + pEnvironmentData = NULL; +} + +BOOL CMapManager::LoadEnvironmentData(const char * c_szFileName, TEnvironmentData * pEnvironmentData) +{ + if (!pEnvironmentData) + return FALSE; + + return (BOOL)Environment_Load(*pEnvironmentData, c_szFileName); +} + +DWORD CMapManager::GetShadowMapColor(float fx, float fy) +{ + if (!IsMapReady()) + return 0xFFFFFFFF; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + return rkMap.GetShadowMapColor(fx, fy); +} + +std::vector & CMapManager::GetRenderedSplatNum(int * piPatch, int * piSplat, float * pfSplatRatio) +{ + if (!m_pkMap) + { + static std::vector s_emptyVector; + *piPatch = 0; + *piSplat = 0; + return s_emptyVector; + } + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + return rkMap.GetRenderedSplatNum(piPatch, piSplat, pfSplatRatio); +} + +CArea::TCRCWithNumberVector & CMapManager::GetRenderedGraphicThingInstanceNum(DWORD * pdwGraphicThingInstanceNum, DWORD * pdwCRCNum) +{ + if (!m_pkMap) + { + static CArea::TCRCWithNumberVector s_emptyVector; + *pdwGraphicThingInstanceNum = 0; + *pdwCRCNum = 0; + return s_emptyVector; + } + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + return rkMap.GetRenderedGraphicThingInstanceNum(pdwGraphicThingInstanceNum, pdwCRCNum); +} + +bool CMapManager::GetNormal(int ix, int iy, D3DXVECTOR3 * pv3Normal) +{ + if (!IsMapReady()) + return false; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + return rkMap.GetNormal(ix, iy, pv3Normal); +} + +bool CMapManager::isPhysicalCollision(const D3DXVECTOR3 & c_rvCheckPosition) +{ + if (!IsMapReady()) + return false; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + return rkMap.isAttrOn(c_rvCheckPosition.x, -c_rvCheckPosition.y, CTerrainImpl::ATTRIBUTE_BLOCK); +} + +bool CMapManager::isAttrOn(float fX, float fY, BYTE byAttr) +{ + if (!IsMapReady()) + return false; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + return rkMap.isAttrOn(fX, fY, byAttr); +} + +bool CMapManager::GetAttr(float fX, float fY, BYTE * pbyAttr) +{ + if (!IsMapReady()) + return false; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + return rkMap.GetAttr(fX, fY, pbyAttr); +} + +bool CMapManager::isAttrOn(int iX, int iY, BYTE byAttr) +{ + if (!IsMapReady()) + return false; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + return rkMap.isAttrOn(iX, iY, byAttr); +} + +bool CMapManager::GetAttr(int iX, int iY, BYTE * pbyAttr) +{ + if (!IsMapReady()) + return false; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + return rkMap.GetAttr(iX, iY, pbyAttr); +} + +// 2004.10.14.myevan.TEMP_CAreaLoaderThread +/* +bool CMapManager::BGLoadingEnable() +{ + if (!IsMapReady()) + return false; + return ((CMapOutdoor*)m_pMap)->BGLoadingEnable(); +} + +void CMapManager::BGLoadingEnable(bool bBGLoadingEnable) +{ + if (!IsMapReady()) + return; + ((CMapOutdoor*)m_pMap)->BGLoadingEnable(bBGLoadingEnable); +} +*/ + +void CMapManager::SetTerrainRenderSort(CMapOutdoor::ETerrainRenderSort eTerrainRenderSort) +{ + if (!IsMapReady()) + return; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + rkMap.SetTerrainRenderSort(eTerrainRenderSort); +} + +void CMapManager::SetTransparentTree(bool bTransparenTree) +{ + if (!IsMapReady()) + return; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + rkMap.SetTransparentTree(bTransparenTree); +} + +CMapOutdoor::ETerrainRenderSort CMapManager::GetTerrainRenderSort() +{ + if (!IsMapReady()) + return CMapOutdoor::DISTANCE_SORT; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + return rkMap.GetTerrainRenderSort(); +} + +void CMapManager::GetBaseXY(DWORD * pdwBaseX, DWORD * pdwBaseY) +{ + if (!IsMapReady()) + { + *pdwBaseX = 0; + *pdwBaseY = 0; + } + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + rkMap.GetBaseXY(pdwBaseX, pdwBaseY); +} + +void CMapManager::__LoadMapInfoVector() +{ + CMappedFile kFile; + LPCVOID pData; + if (!CEterPackManager::Instance().Get(kFile, m_stAtlasInfoFileName.c_str(), &pData)) + if (!CEterPackManager::Instance().Get(kFile, "AtlasInfo.txt", &pData)) + return; + + CMemoryTextFileLoader textFileLoader; + textFileLoader.Bind(kFile.Size(), pData); + + char szMapName[256]; + int x, y; + int width, height; + for (UINT uLineIndex=0; uLineIndex & GetRenderedSplatNum(int * piPatch, int * piSplat, float * pfSplatRatio); + CArea::TCRCWithNumberVector & GetRenderedGraphicThingInstanceNum(DWORD * pdwGraphicThingInstanceNum, DWORD * pdwCRCNum); + + protected: + TEnvironmentData * AllocEnvironmentData(); + void DeleteEnvironmentData(TEnvironmentData * pEnvironmentData); + BOOL LoadEnvironmentData(const char * c_szFileName, TEnvironmentData * pEnvironmentData); + + protected: + CPropertyManager m_PropertyManager; + + ////////////////////////////////////////////////////////////////////////// + // Environment + ////////////////////////////////////////////////////////////////////////// + TEnvironmentDataMap m_EnvironmentDataMap; + const TEnvironmentData * mc_pcurEnvironmentData; + + ////////////////////////////////////////////////////////////////////////// + // Map + ////////////////////////////////////////////////////////////////////////// + CMapOutdoor * m_pkMap; + CSpeedTreeForestDirectX8 m_Forest; + + public: + // 2004.10.14.myevan.TEMP_CAreaLoaderThread + //bool BGLoadingEnable(); + //void BGLoadingEnable(bool bBGLoadingEnable); + void SetTerrainRenderSort(CMapOutdoor::ETerrainRenderSort eTerrainRenderSort); + CMapOutdoor::ETerrainRenderSort GetTerrainRenderSort(); + + void GetBaseXY(DWORD * pdwBaseX, DWORD * pdwBaseY); + + public: + void SetTransparentTree(bool bTransparenTree); + + public: + typedef struct + { + std::string m_strName; + DWORD m_dwBaseX; + DWORD m_dwBaseY; + DWORD m_dwSizeX; + DWORD m_dwSizeY; + DWORD m_dwEndX; + DWORD m_dwEndY; + } TMapInfo; + typedef std::vector TMapInfoVector; + typedef TMapInfoVector::iterator TMapInfoVectorIterator; + + protected: + TMapInfoVector m_kVct_kMapInfo; + + bool m_isSoftwareTilingEnableReserved; + + protected: + void __LoadMapInfoVector(); + + protected: + struct FFindMapName + { + std::string strNametoFind; + FFindMapName(const std::string & c_rMapName) + { + strNametoFind = c_rMapName; + stl_lowers(strNametoFind); + } + bool operator() (TMapInfo & rMapInfo) + { + if (rMapInfo.m_strName == strNametoFind) + return true; + return false; + } + }; + public: + void SetAtlasInfoFileName(const char* filename) + { + m_stAtlasInfoFileName = filename; + } + private: + std::string m_stAtlasInfoFileName; +}; diff --git a/source/GameLib/MapOutdoor.cpp b/source/GameLib/MapOutdoor.cpp new file mode 100644 index 0000000..47f69af --- /dev/null +++ b/source/GameLib/MapOutdoor.cpp @@ -0,0 +1,1595 @@ +#include "StdAfx.h" +#include "../eterlib/StateManager.h" +#include "../eterlib/Camera.h" +#include "../PRTerrainLib/StdAfx.h" +#include "../EffectLib/EffectManager.h" + +#include "MapOutdoor.h" +#include "TerrainPatch.h" +#include "AreaTerrain.h" + +//#define USE_LEVEL +// unsigned int uiNumSplat; + +struct FGetObjectHeight +{ + bool m_bHeightFound; + float m_fReturnHeight; + float m_fRequestX, m_fRequestY; + FGetObjectHeight(float fRequestX, float fRequestY) + { + m_fRequestX=fRequestX; + m_fRequestY=fRequestY; + m_bHeightFound=false; + m_fReturnHeight=0.0f; + } + void operator () (CGraphicObjectInstance * pObject) + { + if (pObject->GetObjectHeight(m_fRequestX, m_fRequestY, &m_fReturnHeight)) + { +#ifdef SPHERELIB_STRICT + printf("FIND %f\n", m_fReturnHeight); +#endif + m_bHeightFound = true; + } + } +}; + +struct FGetPickingPoint +{ + D3DXVECTOR3 m_v3Start; + D3DXVECTOR3 m_v3Dir; + D3DXVECTOR3 m_v3PickingPoint; + bool m_bPicked; + + FGetPickingPoint(D3DXVECTOR3 & v3Start, D3DXVECTOR3 & v3Dir) : m_v3Start(v3Start), m_v3Dir(v3Dir), m_bPicked(false) {} + void operator() (CGraphicObjectInstance * pInstance) + { + if( pInstance && pInstance->GetType() == CGraphicThingInstance::ID ) + { + CGraphicThingInstance * pThing = (CGraphicThingInstance *)pInstance; + if (!pThing->IsObjectHeight()) + return; + + float fX, fY, fZ; + if (pThing->Picking(m_v3Start, m_v3Dir, fX, fY)) + { + if (pThing->GetObjectHeight(fX, -fY, &fZ)) + { + m_v3PickingPoint.x = fX; + m_v3PickingPoint.y = fY; + m_v3PickingPoint.z = fZ; + m_bPicked = true; + } + } + } + } +}; + +CMapOutdoor::CMapOutdoor() +{ + CGraphicImage * pAlphaFogImage = (CGraphicImage *) CResourceManager::Instance().GetResourcePointer("D:/ymir work/special/fog.tga"); + CGraphicImage * pAttrImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer("d:/ymir work/special/white.dds"); + CGraphicImage * pBuildTransparentImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer("d:/ymir Work/special/PCBlockerAlpha.dds"); + m_AlphaFogImageInstance.SetImagePointer(pAlphaFogImage); + m_attrImageInstance.SetImagePointer(pAttrImage); + m_BuildingTransparentImageInstance.SetImagePointer(pBuildTransparentImage); + + Initialize(); + + __SoftwareTransformPatch_Initialize(); + __SoftwareTransformPatch_Create(); +} + +CMapOutdoor::~CMapOutdoor() +{ + __SoftwareTransformPatch_Destroy(); + + // 2004.10.14.myevan.TEMP_CAreaLoaderThread + //ms_AreaLoaderThread.Shutdown(); + Destroy(); +} + +bool CMapOutdoor::Initialize() +{ + BYTE i; + for (i = 0; i < AROUND_AREA_NUM; ++i) + { + m_pArea[i] = NULL; + m_pTerrain[i] = NULL; + } + + m_pTerrainPatchProxyList = NULL; + + m_lViewRadius = 0L; + m_fHeightScale = 0.0f; + + m_sTerrainCountX = m_sTerrainCountY = 0; + + m_CurCoordinate.m_sTerrainCoordX = -1; + m_CurCoordinate.m_sTerrainCoordY = -1; + m_PrevCoordinate.m_sTerrainCoordX = -1; + m_PrevCoordinate.m_sTerrainCoordY = -1; + + m_EntryPointMap.clear(); + + m_lCenterX = m_lCenterY = 0; + m_lOldReadX = m_lOldReadY = -1; + +#ifdef WORLD_EDITOR + m_pwIndices = NULL; +#else + memset(m_pwaIndices, 0, sizeof(m_pwaIndices)); + for (i = 0; i < TERRAINPATCH_LODMAX; ++i) + m_IndexBuffer[i].Destroy(); +#endif + + m_bSettingTerrainVisible = false; + m_bDrawWireFrame = false; + m_bDrawShadow = false; + m_bDrawChrShadow = false; + + m_iSplatLimit = 50000; + + m_wPatchCount = 0; + + m_pRootNode = NULL; + + ////////////////////////////////////////////////////////////////////////// + // Character Shadow + m_lpCharacterShadowMapTexture = NULL; + m_lpCharacterShadowMapRenderTargetSurface = NULL; + m_lpCharacterShadowMapDepthSurface = NULL; + + m_lpBackupRenderTargetSurface = NULL; + m_lpBackupDepthSurface = NULL; + // Character Shadow + ////////////////////////////////////////////////////////////////////////// + + m_iRenderedPatchNum = 0; + m_iRenderedSplatNum = 0; + + ////////////////////////////////////////////////////////////////////////// + m_fOpaqueWaterDepth = 400.0f; + + ////////////////////////////////////////////////////////////////////////// + m_TerrainVector.clear(); + m_TerrainDeleteVector.clear(); + m_TerrainLoadRequestVector.clear(); + m_TerrainLoadWaitVector.clear(); + + m_AreaVector.clear(); + m_AreaDeleteVector.clear(); + m_AreaLoadRequestVector.clear(); + m_AreaLoadWaitVector.clear(); + ////////////////////////////////////////////////////////////////////////// + + m_PatchVector.clear(); + + // 2004.10.14.myevan.TEMP_CAreaLoaderThread + //m_bBGLoadingEnable = false; + m_eTerrainRenderSort = DISTANCE_SORT; + + D3DXMatrixIdentity(&m_matWorldForCommonUse); + + InitializeFog(); + InitializeVisibleParts(); + + m_dwBaseX = 0; + m_dwBaseY = 0; + + m_settings_envDataName = ""; + m_bShowEntirePatchTextureCount = false; + m_bTransparentTree = true; + + CMapBase::Clear(); + + __XMasTree_Initialize(); + SpecialEffect_Destroy(); + + m_bEnableTerrainOnlyForHeight = FALSE; + m_bEnablePortal = FALSE; + + m_wShadowMapSize = 512; + return true; +} + + +bool CMapOutdoor::Destroy() +{ + m_bEnableTerrainOnlyForHeight = FALSE; + m_bEnablePortal = FALSE; + + XMasTree_Destroy(); + + DestroyTerrain(); + DestroyArea(); + DestroyTerrainPatchProxyList(); + + FreeQuadTree(); + ReleaseCharacterShadowTexture(); + + CTerrain::DestroySystem(); + CArea::DestroySystem(); + + RemoveAllMonsterAreaInfo(); + + m_rkList_kGuildArea.clear(); + m_kPool_kMonsterAreaInfo.Destroy(); + m_AlphaFogImageInstance.Destroy(); + + CSpeedTreeForestDirectX8::Instance().Clear(); + + return true; +} + +void CMapOutdoor::Clear() +{ + UnloadWaterTexture(); + Destroy(); // + Initialize(); // ʱȭ +} + +bool CMapOutdoor::SetTerrainCount(short sTerrainCountX, short sTerrainCountY) +{ + if (0 == sTerrainCountX || MAX_MAPSIZE < sTerrainCountX) + return false; + + if (0 == sTerrainCountY || MAX_MAPSIZE < sTerrainCountY) + return false; + + m_sTerrainCountX = sTerrainCountX; + m_sTerrainCountY = sTerrainCountY; + return true; +} + +void CMapOutdoor::OnBeginEnvironment() +{ + if (!mc_pEnvironmentData) + return; + + CSpeedTreeForestDirectX8& rkForest=CSpeedTreeForestDirectX8::Instance(); + rkForest.SetFog( + mc_pEnvironmentData->GetFogNearDistance(), + mc_pEnvironmentData->GetFogFarDistance() + ); + + const D3DLIGHT8& c_rkLight = mc_pEnvironmentData->DirLights[ENV_DIRLIGHT_CHARACTER]; + rkForest.SetLight( + (const float *)&c_rkLight.Direction, + (const float *)&c_rkLight.Ambient, + (const float *)&c_rkLight.Diffuse); + + rkForest.SetWindStrength(mc_pEnvironmentData->fWindStrength); +} + +void CMapOutdoor::OnSetEnvironmentDataPtr() +{ + SetEnvironmentScreenFilter(); + SetEnvironmentSkyBox(); + SetEnvironmentLensFlare(); +} + +void CMapOutdoor::OnResetEnvironmentDataPtr() +{ + m_SkyBox.Unload(); + SetEnvironmentScreenFilter(); + SetEnvironmentSkyBox(); + SetEnvironmentLensFlare(); +} + +void CMapOutdoor::SetEnvironmentScreenFilter() +{ + if (!mc_pEnvironmentData) + return; + + m_ScreenFilter.SetEnable(mc_pEnvironmentData->bFilteringEnable); + m_ScreenFilter.SetBlendType(mc_pEnvironmentData->byFilteringAlphaSrc, mc_pEnvironmentData->byFilteringAlphaDest); + m_ScreenFilter.SetColor(mc_pEnvironmentData->FilteringColor); +} + +void CMapOutdoor::SetEnvironmentSkyBox() +{ + if (!mc_pEnvironmentData) + return; + + m_SkyBox.SetSkyBoxScale(mc_pEnvironmentData->v3SkyBoxScale); + m_SkyBox.SetGradientLevel(mc_pEnvironmentData->bySkyBoxGradientLevelUpper, mc_pEnvironmentData->bySkyBoxGradientLevelLower); + m_SkyBox.SetRenderMode( (mc_pEnvironmentData->bSkyBoxTextureRenderMode == TRUE) ? CSkyObject::SKY_RENDER_MODE_TEXTURE : CSkyObject::SKY_RENDER_MODE_DIFFUSE); + + for( int i = 0; i < 6; ++i ) + { + if (!mc_pEnvironmentData->strSkyBoxFaceFileName[i].empty()) + m_SkyBox.SetFaceTexture( mc_pEnvironmentData->strSkyBoxFaceFileName[i].c_str(), i ); + } + + if (!mc_pEnvironmentData->strCloudTextureFileName.empty()) + m_SkyBox.SetCloudTexture(mc_pEnvironmentData->strCloudTextureFileName.c_str()); + + m_SkyBox.SetCloudScale(mc_pEnvironmentData->v2CloudScale); + m_SkyBox.SetCloudHeight(mc_pEnvironmentData->fCloudHeight); + m_SkyBox.SetCloudTextureScale(mc_pEnvironmentData->v2CloudTextureScale); + m_SkyBox.SetCloudScrollSpeed(mc_pEnvironmentData->v2CloudSpeed); + m_SkyBox.Refresh(); + + // Temporary + m_SkyBox.SetCloudColor(mc_pEnvironmentData->CloudGradientColor, mc_pEnvironmentData->CloudGradientColor, 1); + + if (!mc_pEnvironmentData->SkyBoxGradientColorVector.empty()) + m_SkyBox.SetSkyColor(mc_pEnvironmentData->SkyBoxGradientColorVector, mc_pEnvironmentData->SkyBoxGradientColorVector, 1); + // Temporary + + m_SkyBox.StartTransition(); +} + +void CMapOutdoor::SetEnvironmentLensFlare() +{ + if (!mc_pEnvironmentData) + return; + + m_LensFlare.CharacterizeFlare(mc_pEnvironmentData->bLensFlareEnable == 1 ? true : false, + mc_pEnvironmentData->bMainFlareEnable == 1 ? true : false, + mc_pEnvironmentData->fLensFlareMaxBrightness, + mc_pEnvironmentData->LensFlareBrightnessColor); + + m_LensFlare.Initialize("d:/ymir work/environment"); + + if (!mc_pEnvironmentData->strMainFlareTextureFileName.empty()) + m_LensFlare.SetMainFlare(mc_pEnvironmentData->strMainFlareTextureFileName.c_str(), + mc_pEnvironmentData->fMainFlareSize); +} + +void CMapOutdoor::SetWireframe(bool bWireFrame) +{ + m_bDrawWireFrame = bWireFrame; +} + +bool CMapOutdoor::IsWireframe() +{ + return m_bDrawWireFrame; +} + +////////////////////////////////////////////////////////////////////////// +// TerrainPatchList +////////////////////////////////////////////////////////////////////////// +void CMapOutdoor::CreateTerrainPatchProxyList() +{ + m_wPatchCount = ((m_lViewRadius * 2) / TERRAIN_PATCHSIZE) + 2; + + m_pTerrainPatchProxyList = new CTerrainPatchProxy[m_wPatchCount * m_wPatchCount]; + + m_iPatchTerrainVertexCount = (TERRAIN_PATCHSIZE+1)*(TERRAIN_PATCHSIZE+1); + m_iPatchWaterVertexCount = TERRAIN_PATCHSIZE * TERRAIN_PATCHSIZE * 6; + m_iPatchTerrainVertexSize = 24; + m_iPatchWaterVertexSize = 16; + + SetIndexBuffer(); +} + +void CMapOutdoor::DestroyTerrainPatchProxyList() +{ + if (m_pTerrainPatchProxyList) + { + delete [] m_pTerrainPatchProxyList; + m_pTerrainPatchProxyList = NULL; + } + +#ifdef WORLD_EDITOR + m_IndexBuffer.Destroy(); +#else + for (int i = 0; i < TERRAINPATCH_LODMAX; ++i) + m_IndexBuffer[i].Destroy(); +#endif +} + +////////////////////////////////////////////////////////////////////////// +// Area +////////////////////////////////////////////////////////////////////////// + +void CMapOutdoor::EnablePortal(bool bFlag) +{ + m_bEnablePortal = bFlag; + + for (int i = 0; i < AROUND_AREA_NUM; ++i) + if (m_pArea[i]) + m_pArea[i]->EnablePortal(bFlag); +} + +void CMapOutdoor::DestroyArea() +{ + m_AreaVector.clear(); + m_AreaDeleteVector.clear(); + + CArea::ms_kPool.FreeAll(); + + for (int i = 0; i < AROUND_AREA_NUM; ++i) + m_pArea[i] = NULL; +} + +////////////////////////////////////////////////////////////////////////// +// Terrain +////////////////////////////////////////////////////////////////////////// + +void CMapOutdoor::DestroyTerrain() +{ + m_TerrainVector.clear(); + m_TerrainDeleteVector.clear(); + + CTerrain::ms_kPool.FreeAll(); + for (int i=0; i < AROUND_AREA_NUM; ++i) + m_pTerrain[i] = NULL; +} + +////////////////////////////////////////////////////////////////////////// +// New +////////////////////////////////////////////////////////////////////////// + +bool CMapOutdoor::GetTerrainNum(float fx, float fy, BYTE * pbyTerrainNum) +{ + if (fy < 0) + fy = -fy; + + int ix, iy; + + PR_FLOAT_TO_INT(fx, ix); + PR_FLOAT_TO_INT(fy, iy); + + WORD wTerrainNumX = ix / (CTerrainImpl::TERRAIN_XSIZE); + WORD wTerrainNumY = iy / (CTerrainImpl::TERRAIN_YSIZE); + + return GetTerrainNumFromCoord(wTerrainNumX, wTerrainNumY, pbyTerrainNum); +} + +bool CMapOutdoor::GetPickingPoint(D3DXVECTOR3 * v3IntersectPt) +{ + return GetPickingPointWithRay(ms_Ray, v3IntersectPt); +} + +bool CMapOutdoor::__PickTerrainHeight(float& fPos, const D3DXVECTOR3& v3Start, const D3DXVECTOR3& v3End, float fStep, float fRayRange, float fLimitRange, D3DXVECTOR3* pv3Pick) +{ + CTerrain * pTerrain; + + D3DXVECTOR3 v3CurPos; + + float fRayRangeInv=1.0f/fRayRange; + while (fPos < fRayRange && fPosGetHeight(ix, iy); + if ( fMapHeight >= v3CurPos.z) + { + *pv3Pick = v3CurPos; + return true; + } + else + { + fMultiplier = fMAX(1.0f, 0.01f * ( v3CurPos.z - fMapHeight ) ); + } + } + } + fPos += fStep * fMultiplier; + } + + return false; +} +bool CMapOutdoor::GetPickingPointWithRay(const CRay & rRay, D3DXVECTOR3 * v3IntersectPt) +{ + bool bObjectPick = false; + bool bTerrainPick = false; + D3DXVECTOR3 v3ObjectPick, v3TerrainPick; + + D3DXVECTOR3 v3Start, v3End, v3Dir, v3CurPos; + float fRayRange; + rRay.GetStartPoint(&v3Start); + rRay.GetDirection(&v3Dir, &fRayRange); + rRay.GetEndPoint(&v3End); + + Vector3d v3dStart, v3dEnd; + v3dStart.Set(v3Start.x, v3Start.y, v3Start.z); + v3dEnd.Set(v3End.x - v3Start.x, v3End.y - v3Start.y, v3End.z - v3Start.z); + + if (!m_bEnableTerrainOnlyForHeight) + { + //DWORD baseTime = timeGetTime(); + CCullingManager & rkCullingMgr = CCullingManager::Instance(); + FGetPickingPoint kGetPickingPoint(v3Start, v3Dir); + rkCullingMgr.ForInRange2d(v3dStart, &kGetPickingPoint); + + if (kGetPickingPoint.m_bPicked) + { + bObjectPick = true; + v3ObjectPick = kGetPickingPoint.m_v3PickingPoint; + } + } + + float fPos = 0.0f; + //float fStep = 1.0f; + //float fRayRangeInv=1.0f/fRayRange; + + bTerrainPick=true; + if (!__PickTerrainHeight(fPos, v3Start, v3End, 5.0f, fRayRange, 5000.0f, &v3TerrainPick)) + if (!__PickTerrainHeight(fPos, v3Start, v3End, 10.0f, fRayRange, 10000.0f, &v3TerrainPick)) + if (!__PickTerrainHeight(fPos, v3Start, v3End, 100.0f, fRayRange, 100000.0f, &v3TerrainPick)) + bTerrainPick=false; + + + if (bObjectPick && bTerrainPick) + { + const auto vv = (v3TerrainPick - v3Start); + const auto vv2 = (v3ObjectPick - v3Start); + if ( D3DXVec3Length( &vv2) >= D3DXVec3Length( & vv) ) + *v3IntersectPt = v3TerrainPick; + else + *v3IntersectPt = v3ObjectPick; + return true; + } + else if (bObjectPick) + { + *v3IntersectPt = v3ObjectPick; + return true; + } + else if (bTerrainPick) + { + *v3IntersectPt = v3TerrainPick; + return true; + } + + return false; +} + +bool CMapOutdoor::GetPickingPointWithRayOnlyTerrain(const CRay & rRay, D3DXVECTOR3 * v3IntersectPt) +{ + bool bTerrainPick = false; + D3DXVECTOR3 v3TerrainPick; + + D3DXVECTOR3 v3Start, v3End, v3Dir, v3CurPos; + float fRayRange; + rRay.GetStartPoint(&v3Start); + rRay.GetDirection(&v3Dir, &fRayRange); + rRay.GetEndPoint(&v3End); + + Vector3d v3dStart, v3dEnd; + v3dStart.Set(v3Start.x, v3Start.y, v3Start.z); + v3dEnd.Set(v3End.x - v3Start.x, v3End.y - v3Start.y, v3End.z - v3Start.z); + + + + float fPos = 0.0f; + bTerrainPick=true; + if (!__PickTerrainHeight(fPos, v3Start, v3End, 5.0f, fRayRange, 5000.0f, &v3TerrainPick)) + if (!__PickTerrainHeight(fPos, v3Start, v3End, 10.0f, fRayRange, 10000.0f, &v3TerrainPick)) + if (!__PickTerrainHeight(fPos, v3Start, v3End, 100.0f, fRayRange, 100000.0f, &v3TerrainPick)) + bTerrainPick=false; + + if (bTerrainPick) + { + *v3IntersectPt = v3TerrainPick; + return true; + } + + return false; +} +/* +{ + bool bTerrainPick = false; + D3DXVECTOR3 v3TerrainPick; + + CTerrain * pTerrain; + + D3DXVECTOR3 v3Start, v3End, v3Dir, v3CurPos; + float fRayRange; + rRay.GetStartPoint(&v3Start); + rRay.GetDirection(&v3Dir, &fRayRange); + rRay.GetEndPoint(&v3End); + + Vector3d v3dStart, v3dEnd; + v3dStart.Set(v3Start.x, v3Start.y, v3Start.z); + v3dEnd.Set(v3End.x - v3Start.x, v3End.y - v3Start.y, v3End.z - v3Start.z); + + float fAdd = 1.0f / fRayRange; + + float ft = 0.0f; + while (ft < 1.0f) + { + D3DXVec3Lerp(&v3CurPos, &v3Start, &v3End, ft); + BYTE byTerrainNum; + float fMultiplier = 1.0f; + if (GetTerrainNum(v3CurPos.x, v3CurPos.y, &byTerrainNum)) + { + if (GetTerrainPointer(byTerrainNum, &pTerrain)) + { + int ix, iy; + PR_FLOAT_TO_INT(v3CurPos.x, ix); + PR_FLOAT_TO_INT(fabs(v3CurPos.y), iy); + float fMapHeight = pTerrain->GetHeight(ix, iy); + if ( fMapHeight >= v3CurPos.z) + { + bTerrainPick = true; + v3TerrainPick = v3CurPos; + break; + } + else + fMultiplier = fMAX(1.0f, 0.01f * ( v3CurPos.z - fMapHeight ) ); + } + } + ft += fAdd * fMultiplier; + } + + if (bTerrainPick) + { + *v3IntersectPt = v3TerrainPick; + return true; + } + + return false; +} +*/ + +void CMapOutdoor::GetHeightMap(const BYTE & c_rucTerrainNum, WORD ** pwHeightMap) +{ + if (c_rucTerrainNum < 0 || c_rucTerrainNum > AROUND_AREA_NUM - 1 || !m_pTerrain[c_rucTerrainNum]) + { + *pwHeightMap = NULL; + return; + } + + *pwHeightMap = m_pTerrain[c_rucTerrainNum]->GetHeightMap(); +} + +void CMapOutdoor::GetNormalMap(const BYTE & c_rucTerrainNum, char ** pucNormalMap) +{ + if (c_rucTerrainNum < 0 || c_rucTerrainNum > AROUND_AREA_NUM - 1 || !m_pTerrain[c_rucTerrainNum]) + { + *pucNormalMap = NULL; + return; + } + + *pucNormalMap = m_pTerrain[c_rucTerrainNum]->GetNormalMap(); +} + +void CMapOutdoor::GetWaterMap(const BYTE & c_rucTerrainNum, BYTE ** pucWaterMap) +{ + if (c_rucTerrainNum < 0 || c_rucTerrainNum > AROUND_AREA_NUM - 1 || !m_pTerrain[c_rucTerrainNum]) + { + *pucWaterMap = NULL; + return; + } + + *pucWaterMap = m_pTerrain[c_rucTerrainNum]->GetWaterMap(); +} + +void CMapOutdoor::GetWaterHeight(BYTE byTerrainNum, BYTE byWaterNum, long * plWaterHeight) +{ + if (byTerrainNum < 0 || byTerrainNum > AROUND_AREA_NUM - 1 || !m_pTerrain[byTerrainNum]) + { + *plWaterHeight = -1; + return; + } + + m_pTerrain[byTerrainNum]->GetWaterHeight(byWaterNum, plWaterHeight); +} + +bool CMapOutdoor::GetWaterHeight(int iX, int iY, long * plWaterHeight) +{ + if (iX < 0 || iY < 0 || iX > m_sTerrainCountX * CTerrainImpl::TERRAIN_XSIZE || iY > m_sTerrainCountY * CTerrainImpl::TERRAIN_YSIZE) + return false; + + WORD wTerrainCoordX, wTerrainCoordY; + wTerrainCoordX = iX / CTerrainImpl::TERRAIN_XSIZE; + wTerrainCoordY = iY / CTerrainImpl::TERRAIN_YSIZE; + + BYTE byTerrainNum; + if (!GetTerrainNumFromCoord(wTerrainCoordX, wTerrainCoordY, &byTerrainNum)) + return false; + CTerrain * pTerrain; + if (!GetTerrainPointer(byTerrainNum, &pTerrain)) + return false; + + WORD wLocalX, wLocalY; + wLocalX = (iX - wTerrainCoordX * CTerrainImpl::TERRAIN_XSIZE) / (CTerrainImpl::WATERMAP_XSIZE); + wLocalY = (iY - wTerrainCoordY * CTerrainImpl::TERRAIN_YSIZE) / (CTerrainImpl::WATERMAP_YSIZE); + + return pTerrain->GetWaterHeight(wLocalX, wLocalY, plWaterHeight); +} + +////////////////////////////////////////////////////////////////////////// +// Update +////////////////////////////////////////////////////////////////////////// + +bool CMapOutdoor::GetTerrainNumFromCoord(WORD wCoordX, WORD wCoordY, BYTE * pbyTerrainNum) +{ + *pbyTerrainNum = (wCoordY - m_CurCoordinate.m_sTerrainCoordY + LOAD_SIZE_WIDTH) * 3 + + (wCoordX - m_CurCoordinate.m_sTerrainCoordX + LOAD_SIZE_WIDTH); + + if (*pbyTerrainNum < 0 || *pbyTerrainNum > AROUND_AREA_NUM) + return false; + return true; +} + +void CMapOutdoor::BuildViewFrustum(D3DXMATRIX & mat) +{ + //m_plane[0] = D3DXPLANE(mat._14 + mat._13, mat._24 + mat._23, mat._34 + mat._33, mat._44 + mat._43); + m_plane[0] = D3DXPLANE( mat._13, mat._23, mat._33, mat._43); // Near + m_plane[1] = D3DXPLANE(mat._14 - mat._13, mat._24 - mat._23, mat._34 - mat._33, mat._44 - mat._43); // Far + m_plane[2] = D3DXPLANE(mat._14 + mat._11, mat._24 + mat._21, mat._34 + mat._31, mat._44 + mat._41); // Left + m_plane[3] = D3DXPLANE(mat._14 - mat._11, mat._24 - mat._21, mat._34 - mat._31, mat._44 - mat._41); // Right + m_plane[4] = D3DXPLANE(mat._14 + mat._12, mat._24 + mat._22, mat._34 + mat._32, mat._44 + mat._42); // Bottom + m_plane[5] = D3DXPLANE(mat._14 - mat._12, mat._24 - mat._22, mat._34 - mat._32, mat._44 - mat._42); // Top + + for (int i = 0; i < 6; ++i) + D3DXPlaneNormalize(&m_plane[i],&m_plane[i]); +} + +bool MAPOUTDOOR_GET_HEIGHT_USE2D = true; +bool MAPOUTDOOR_GET_HEIGHT_TRACE = false; + +void CMapOutdoor::__HeightCache_Update() +{ + m_kHeightCache.m_isUpdated=true; +} + +void CMapOutdoor::__HeightCache_Init() +{ + m_kHeightCache.m_isUpdated=false; + + for (UINT uIndex=0; uIndex!=SHeightCache::HASH_SIZE; ++uIndex) + m_kHeightCache.m_akVct_kItem[uIndex].clear(); +} + +float CMapOutdoor::GetHeight(float fx, float fy) +{ + float fTerrainHeight = GetTerrainHeight(fx, fy); + + if (!m_bEnableTerrainOnlyForHeight) + { + CCullingManager & rkCullingMgr = CCullingManager::Instance(); + + float CHECK_HEIGHT = 25000.0f; + float fObjectHeight = -CHECK_HEIGHT; + + Vector3d aVector3d; + aVector3d.Set(fx, -fy, fTerrainHeight); + + FGetObjectHeight kGetObjHeight(fx, fy); + + RangeTester kRangeTester_kGetObjHeight(&kGetObjHeight); + rkCullingMgr.PointTest2d(aVector3d, &kRangeTester_kGetObjHeight); + + if (kGetObjHeight.m_bHeightFound) + fObjectHeight = kGetObjHeight.m_fReturnHeight; + + return fMAX(fObjectHeight, fTerrainHeight); + } + + return fTerrainHeight; +} + +float CMapOutdoor::GetCacheHeight(float fx, float fy) +{ + unsigned int nx=int(fx); + unsigned int ny=int(fy); + + DWORD dwKey=0; + +#ifdef __HEIGHT_CACHE_TRACE__ + static DWORD s_dwTotalCount=0; + static DWORD s_dwHitCount=0; + static DWORD s_dwErrorCount=0; + + s_dwTotalCount++; +#endif + + std::vector* pkVct_kItem=NULL; + if (m_kHeightCache.m_isUpdated && nx<16*30000 && ny<16*30000) + { + nx>>=4; + ny>>=4; + //short aPos[2]={nx, ny}; + + dwKey=(ny<<16)|nx;//CalcCRC16Words(2, aPos); + pkVct_kItem=&m_kHeightCache.m_akVct_kItem[dwKey%SHeightCache::HASH_SIZE]; + std::vector::iterator i; + for (i=pkVct_kItem->begin(); i!=pkVct_kItem->end(); ++i) + { + SHeightCache::SItem& rkItem=*i; + if (rkItem.m_dwKey==dwKey) + { +#ifdef __HEIGHT_CACHE_TRACE__ + s_dwHitCount++; + + if (s_dwTotalCount>1000) + { + DWORD dwHitRate=s_dwHitCount*1000/s_dwTotalCount; + static DWORD s_dwMaxHitRate=0; + if (s_dwMaxHitRate=1000000) + { + printf("HitRate %f\n", s_dwHitCount*1000/s_dwTotalCount*0.1f); + printf("ErrRate %f\n", s_dwErrorCount*1000/s_dwTotalCount*0.1f); + s_dwHitCount=0; + s_dwTotalCount=0; + s_dwErrorCount=0; + } +#endif + + float fTerrainHeight = GetTerrainHeight(fx, fy); +#ifdef SPHERELIB_STRICT + if (MAPOUTDOOR_GET_HEIGHT_TRACE) + printf("Terrain %f\n", fTerrainHeight); +#endif + CCullingManager & rkCullingMgr = CCullingManager::Instance(); + + float CHECK_HEIGHT = 25000.0f; + float fObjectHeight = -CHECK_HEIGHT; + + if (MAPOUTDOOR_GET_HEIGHT_USE2D) + { + Vector3d aVector3d; + aVector3d.Set(fx, -fy, fTerrainHeight); + + FGetObjectHeight kGetObjHeight(fx, fy); + + RangeTester kRangeTester_kGetObjHeight(&kGetObjHeight); + rkCullingMgr.PointTest2d(aVector3d, &kRangeTester_kGetObjHeight); + + if (kGetObjHeight.m_bHeightFound) + fObjectHeight = kGetObjHeight.m_fReturnHeight; + } + else + { + Vector3d aVector3d; + aVector3d.Set(fx, -fy, fTerrainHeight); + + Vector3d toTop; + toTop.Set(0,0,CHECK_HEIGHT); + + FGetObjectHeight kGetObjHeight(fx, fy); + rkCullingMgr.ForInRay(aVector3d, toTop, &kGetObjHeight); + + if (kGetObjHeight.m_bHeightFound) + fObjectHeight = kGetObjHeight.m_fReturnHeight; + } + + float fHeight=fMAX(fObjectHeight, fTerrainHeight); + + if (pkVct_kItem) + { + if (pkVct_kItem->size()>=200) + { +#ifdef __HEIGHT_CACHE_TRACE__ + printf("ClearCacheHeight[%d]\n", dwKey%SHeightCache::HASH_SIZE); +#endif + pkVct_kItem->clear(); + } + + SHeightCache::SItem kItem; + kItem.m_dwKey=dwKey; + kItem.m_fHeight=fHeight; + pkVct_kItem->push_back(kItem); + } + + return fHeight; +} + +bool CMapOutdoor::GetNormal(int ix, int iy, D3DXVECTOR3 * pv3Normal) +{ + if (ix <= 0) + ix = 0; + else if (ix >= m_sTerrainCountX * CTerrainImpl::TERRAIN_XSIZE) + ix = m_sTerrainCountX * CTerrainImpl::TERRAIN_XSIZE; + + if (iy <= 0) + iy = 0; + else if (iy >= m_sTerrainCountY * CTerrainImpl::TERRAIN_YSIZE) + iy = m_sTerrainCountY * CTerrainImpl::TERRAIN_YSIZE; + + WORD usCoordX, usCoordY; + + usCoordX = (WORD) (ix / (CTerrainImpl::TERRAIN_XSIZE)); + usCoordY = (WORD) (iy / (CTerrainImpl::TERRAIN_YSIZE)); + + if (usCoordX >= m_sTerrainCountX - 1) + usCoordX = m_sTerrainCountX - 1; + + if (usCoordY >= m_sTerrainCountY - 1) + usCoordY = m_sTerrainCountY - 1; + + BYTE byTerrainNum; + if (!GetTerrainNumFromCoord(usCoordX, usCoordY, &byTerrainNum)) + return false; + + CTerrain * pTerrain; + + if (!GetTerrainPointer(byTerrainNum, &pTerrain)) + return false; + + while (ix >= CTerrainImpl::TERRAIN_XSIZE) + ix -= CTerrainImpl::TERRAIN_XSIZE; + + while (iy >= CTerrainImpl::TERRAIN_YSIZE) + iy -= CTerrainImpl::TERRAIN_YSIZE; + + return pTerrain->GetNormal(ix, iy, pv3Normal); +} + +float CMapOutdoor::GetTerrainHeight(float fx, float fy) +{ + if (fy < 0) + fy = -fy; + long lx, ly; + PR_FLOAT_TO_INT(fx, lx); + PR_FLOAT_TO_INT(fy, ly); + + WORD usCoordX, usCoordY; + + usCoordX = (WORD) (lx / CTerrainImpl::TERRAIN_XSIZE); + usCoordY = (WORD) (ly / CTerrainImpl::TERRAIN_YSIZE); + + BYTE byTerrainNum; + if (!GetTerrainNumFromCoord(usCoordX, usCoordY, &byTerrainNum)) + return 0.0f; + + CTerrain * pTerrain; + + if (!GetTerrainPointer(byTerrainNum, &pTerrain)) + return 0.0f; + + return pTerrain->GetHeight(lx, ly); +} + +////////////////////////////////////////////////////////////////////////// +// For Grass +float CMapOutdoor::GetHeight(float * pPos) +{ + pPos[2] = GetHeight(pPos[0], pPos[1]); + return pPos[2]; +} + +bool CMapOutdoor::GetBrushColor(float fX, float fY, float* pLowColor, float* pHighColor) +{ + bool bSuccess = false; + +// float fU, fV; +// +// GetOneToOneMappingCoordinates(fX, fY, fU, fV); +// +// if (fU >= 0.0f && fU <= 1.0f && fV >= 0.0f && fV <= 1.0f) +// { +// int nImageCol = (m_cBrushMap.GetWidth() - 1) * fU; +// int nImageRow = (m_cBrushMap.GetHeight() - 1) * fV; +// +// // low +// BYTE* pPixel = m_cBrushMap.GetPixel(nImageCol, nImageRow); +// pLowColor[0] = (pPixel[0] / 255.0f); +// pLowColor[1] = (pPixel[1] / 255.0f); +// pLowColor[2] = (pPixel[2] / 255.0f); +// pLowColor[3] = (pPixel[3] / 255.0f); +// +// // high +// pPixel = m_cBrushMap2.GetPixel(nImageCol, nImageRow); +// pHighColor[0] = (pPixel[0] / 255.0f); +// pHighColor[1] = (pPixel[1] / 255.0f); +// pHighColor[2] = (pPixel[2] / 255.0f); +// pHighColor[3] = (pPixel[3] / 255.0f); +// +// bSuccess = true; +// } + pLowColor[0] = (1.0f); + pLowColor[1] = (1.0f); + pLowColor[2] = (1.0f); + pLowColor[3] = (1.0f); + pHighColor[0] = (1.0f); + pHighColor[1] = (1.0f); + pHighColor[2] = (1.0f); + pHighColor[3] = (1.0f); + + return bSuccess; +} + +// End of for grass +////////////////////////////////////////////////////////////////////////// +BOOL CMapOutdoor::GetAreaPointer(const BYTE c_byAreaNum, CArea ** ppArea) +{ + if (c_byAreaNum >= AROUND_AREA_NUM) + { + *ppArea = NULL; + return FALSE; + } + + if (NULL == m_pArea[c_byAreaNum]) + { + *ppArea = NULL; + return FALSE; + } + + *ppArea = m_pArea[c_byAreaNum]; + return TRUE; +} + +BOOL CMapOutdoor::GetTerrainPointer(const BYTE c_byTerrainNum, CTerrain ** ppTerrain) +{ + if (c_byTerrainNum >= AROUND_AREA_NUM) + { + *ppTerrain = NULL; + return FALSE; + } + + if (NULL == m_pTerrain[c_byTerrainNum]) + { + *ppTerrain = NULL; + return FALSE; + } + + *ppTerrain = m_pTerrain[c_byTerrainNum]; + return TRUE; +} + +void CMapOutdoor::InitializeFog() +{ + memset(&m_matAlphaFogTexture, 0, sizeof(D3DXMATRIX)); + m_matAlphaFogTexture._31 = -0.001f; + m_matAlphaFogTexture._41 = -7.0f; + m_matAlphaFogTexture._42 = 0.5f; +} + +void CMapOutdoor::SaveAlphaFogOperation() +{ + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); + STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); + + STATEMANAGER.SetTransform(D3DTS_TEXTURE1, &m_matAlphaFogTexture); + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + STATEMANAGER.SetTexture(1, m_AlphaFogImageInstance.GetTexturePointer()->GetD3DTexture()); +} + +void CMapOutdoor::RestoreAlphaFogOperation() +{ + STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); +} + + +void CMapOutdoor::SetDrawShadow(bool bDrawShadow) +{ + m_bDrawShadow = bDrawShadow; +} + +void CMapOutdoor::SetDrawCharacterShadow(bool bDrawChrShadow) +{ + m_bDrawChrShadow = bDrawChrShadow; +} + +DWORD CMapOutdoor::GetShadowMapColor(float fx, float fy) +{ + if (fy < 0) + fy = -fy; + + float fTerrainSize = (float) (CTerrainImpl::TERRAIN_XSIZE); + float fXRef = fx - (float) (m_lCurCoordStartX); + float fYRef = fy - (float) (m_lCurCoordStartY); + + CTerrain * pTerrain; + + if (fYRef < -fTerrainSize) + return 0xFFFFFFFF; + else if (fYRef >= -fTerrainSize && fYRef < 0.0f) + { + if (fXRef < -fTerrainSize) + return 0xFFFFFFFF; + else if (fXRef >= -fTerrainSize && fXRef < 0.0f) + { + if (GetTerrainPointer(0, &pTerrain)) + return pTerrain->GetShadowMapColor(fXRef + fTerrainSize, fYRef + fTerrainSize); + else + return 0xFFFFFFFF; + } + else if (fXRef >= 0.0f && fXRef < fTerrainSize) + { + if (GetTerrainPointer(1, &pTerrain)) + return pTerrain->GetShadowMapColor(fXRef, fYRef + fTerrainSize); + else + return 0xFFFFFFFF; + } + else if (fXRef >= fTerrainSize && fXRef < 2.0f * fTerrainSize) + { + if (GetTerrainPointer(2, &pTerrain)) + return pTerrain->GetShadowMapColor(fXRef - fTerrainSize, fYRef + fTerrainSize); + else + return 0xFFFFFFFF; + } + else + return 0xFFFFFFFF; + } + else if (fYRef >= 0.0f && fYRef < fTerrainSize) + { + if (fXRef < -fTerrainSize) + return 0xFFFFFFFF; + else if (fXRef >= -fTerrainSize && fXRef < 0.0f) + { + if (GetTerrainPointer(3, &pTerrain)) + return pTerrain->GetShadowMapColor(fXRef + fTerrainSize, fYRef); + else + return 0xFFFFFFFF; + } + else if (fXRef >= 0.0f && fXRef < fTerrainSize) + { + if (GetTerrainPointer(4, &pTerrain)) + return pTerrain->GetShadowMapColor(fXRef, fYRef); + else + return 0xFFFFFFFF; + } + else if (fXRef >= fTerrainSize && fXRef < 2.0f * fTerrainSize) + { + if (GetTerrainPointer(5, &pTerrain)) + return pTerrain->GetShadowMapColor(fXRef - fTerrainSize, fYRef); + else + return 0xFFFFFFFF; + } + else + return 0xFFFFFFFF; + } + else if (fYRef >= fTerrainSize && fYRef < 2.0f * fTerrainSize) + { + if (fXRef < -fTerrainSize) + return 0xFFFFFFFF; + else if (fXRef >= -fTerrainSize && fXRef < 0.0f) + { + if (GetTerrainPointer(6, &pTerrain)) + return pTerrain->GetShadowMapColor(fXRef + fTerrainSize, fYRef - fTerrainSize); + else + return 0xFFFFFFFF; + } + else if (fXRef >= 0.0f && fXRef < fTerrainSize) + { + if (GetTerrainPointer(7, &pTerrain)) + return pTerrain->GetShadowMapColor(fXRef, fYRef - fTerrainSize); + else + return 0xFFFFFFFF; + } + else if (fXRef >= fTerrainSize && fXRef < 2.0f * fTerrainSize) + { + if (GetTerrainPointer(8, &pTerrain)) + return pTerrain->GetShadowMapColor(fXRef - fTerrainSize, fYRef - fTerrainSize); + else + return 0xFFFFFFFF; + } + else + return 0xFFFFFFFF; + } + else + return 0xFFFFFFFF; + + return 0xFFFFFFFF; +} + +bool CMapOutdoor::isAttrOn(float fX, float fY, BYTE byAttr) +{ + int iX, iY; + PR_FLOAT_TO_INT(fX, iX); + PR_FLOAT_TO_INT(fY, iY); + + return isAttrOn(iX, iY, byAttr); +} + +bool CMapOutdoor::GetAttr(float fX, float fY, BYTE * pbyAttr) +{ + int iX, iY; + PR_FLOAT_TO_INT(fX, iX); + PR_FLOAT_TO_INT(fY, iY); + + return GetAttr(iX, iY, pbyAttr); +} + +bool CMapOutdoor::isAttrOn(int iX, int iY, BYTE byAttr) +{ + if (iX < 0 || iY < 0 || iX > m_sTerrainCountX * CTerrainImpl::TERRAIN_XSIZE || iY > m_sTerrainCountY * CTerrainImpl::TERRAIN_YSIZE) + return false; + + WORD wTerrainCoordX, wTerrainCoordY; + wTerrainCoordX = iX / CTerrainImpl::TERRAIN_XSIZE; + wTerrainCoordY = iY / CTerrainImpl::TERRAIN_YSIZE; + + BYTE byTerrainNum; + if (!GetTerrainNumFromCoord(wTerrainCoordX, wTerrainCoordY, &byTerrainNum)) + return false; + CTerrain * pTerrain; + if (!GetTerrainPointer(byTerrainNum, &pTerrain)) + return false; + + WORD wLocalX, wLocalY; + wLocalX = (iX - wTerrainCoordX * CTerrainImpl::TERRAIN_XSIZE) / (CTerrainImpl::HALF_CELLSCALE); + wLocalY = (iY - wTerrainCoordY * CTerrainImpl::TERRAIN_YSIZE) / (CTerrainImpl::HALF_CELLSCALE); + + return pTerrain->isAttrOn(wLocalX, wLocalY, byAttr); +} + +bool CMapOutdoor::GetAttr(int iX, int iY, BYTE * pbyAttr) +{ + if (iX < 0 || iY < 0 || iX > m_sTerrainCountX * CTerrainImpl::TERRAIN_XSIZE || iY > m_sTerrainCountY * CTerrainImpl::TERRAIN_YSIZE) + return false; + + WORD wTerrainCoordX, wTerrainCoordY; + wTerrainCoordX = iX / CTerrainImpl::TERRAIN_XSIZE; + wTerrainCoordY = iY / CTerrainImpl::TERRAIN_YSIZE; + + BYTE byTerrainNum; + if (!GetTerrainNumFromCoord(wTerrainCoordX, wTerrainCoordY, &byTerrainNum)) + return false; + CTerrain * pTerrain; + if (!GetTerrainPointer(byTerrainNum, &pTerrain)) + return false; + + WORD wLocalX, wLocalY; + wLocalX = (WORD) (iX - wTerrainCoordX * CTerrainImpl::TERRAIN_XSIZE) / (CTerrainImpl::HALF_CELLSCALE); + wLocalY = (WORD) (iY - wTerrainCoordY * CTerrainImpl::TERRAIN_YSIZE) / (CTerrainImpl::HALF_CELLSCALE); + + BYTE byAttr = pTerrain->GetAttr(wLocalX, wLocalY); + + *pbyAttr = byAttr; + + return true; +} + +// MonsterAreaInfo +CMonsterAreaInfo * CMapOutdoor::AddMonsterAreaInfo(long lOriginX, long lOriginY, long lSizeX, long lSizeY) +{ + CMonsterAreaInfo * pMonsterAreaInfo = m_kPool_kMonsterAreaInfo.Alloc(); + pMonsterAreaInfo->Clear(); + pMonsterAreaInfo->SetOrigin(lOriginX, lOriginY); + pMonsterAreaInfo->SetSize(lSizeX, lSizeY); + m_MonsterAreaInfoPtrVector.push_back(pMonsterAreaInfo); + + return pMonsterAreaInfo; +} + +void CMapOutdoor::RemoveAllMonsterAreaInfo() +{ + m_MonsterAreaInfoPtrVectorIterator = m_MonsterAreaInfoPtrVector.begin(); + while (m_MonsterAreaInfoPtrVectorIterator != m_MonsterAreaInfoPtrVector.end()) + { + CMonsterAreaInfo * pMonsterAreaInfo = *m_MonsterAreaInfoPtrVectorIterator; + pMonsterAreaInfo->Clear(); + ++m_MonsterAreaInfoPtrVectorIterator; + } + m_kPool_kMonsterAreaInfo.FreeAll(); + m_MonsterAreaInfoPtrVector.clear(); +} + +bool CMapOutdoor::GetMonsterAreaInfoFromVectorIndex(DWORD dwMonsterAreaInfoVectorIndex, CMonsterAreaInfo ** ppMonsterAreaInfo) +{ + if (dwMonsterAreaInfoVectorIndex >= m_MonsterAreaInfoPtrVector.size()) + return false; + + *ppMonsterAreaInfo = m_MonsterAreaInfoPtrVector[dwMonsterAreaInfoVectorIndex]; + return true; +} + +////////////////////////////////////////////////////////////////////////// +CMonsterAreaInfo * CMapOutdoor::AddNewMonsterAreaInfo(long lOriginX, long lOriginY, long lSizeX, long lSizeY, + CMonsterAreaInfo::EMonsterAreaInfoType eMonsterAreaInfoType, + DWORD dwVID, DWORD dwCount, CMonsterAreaInfo::EMonsterDir eMonsterDir) +{ + CMonsterAreaInfo * pMonsterAreaInfo = m_kPool_kMonsterAreaInfo.Alloc(); + pMonsterAreaInfo->Clear(); + pMonsterAreaInfo->SetOrigin(lOriginX, lOriginY); + pMonsterAreaInfo->SetSize(lSizeX, lSizeY); + + pMonsterAreaInfo->SetMonsterAreaInfoType(eMonsterAreaInfoType); + + if (CMonsterAreaInfo::MONSTERAREAINFOTYPE_MONSTER == eMonsterAreaInfoType) + pMonsterAreaInfo->SetMonsterVID(dwVID); + else if (CMonsterAreaInfo::MONSTERAREAINFOTYPE_GROUP == eMonsterAreaInfoType) + pMonsterAreaInfo->SetMonsterGroupID(dwVID); + pMonsterAreaInfo->SetMonsterCount(dwCount); + pMonsterAreaInfo->SetMonsterDirection(eMonsterDir); + m_MonsterAreaInfoPtrVector.push_back(pMonsterAreaInfo); + + return pMonsterAreaInfo; +} + +////////////////////////////////////////////////////////////////////////// +void CMapOutdoor::GetBaseXY(DWORD * pdwBaseX, DWORD * pdwBaseY) +{ + *pdwBaseX = m_dwBaseX; + *pdwBaseY = m_dwBaseY; +} + +void CMapOutdoor::SetBaseXY(DWORD dwBaseX, DWORD dwBaseY) +{ + m_dwBaseX = dwBaseX; + m_dwBaseY = dwBaseY; +} + +void CMapOutdoor::SetEnvironmentDataName(const std::string& strEnvironmentDataName) +{ + m_envDataName = strEnvironmentDataName; +} + +void CMapOutdoor::__XMasTree_Initialize() +{ + m_kXMas.m_pkTree=NULL; + m_kXMas.m_iEffectID=-1; +} + +void CMapOutdoor::XMasTree_Destroy() +{ + if (m_kXMas.m_pkTree) + { + CSpeedTreeForestDirectX8& rkForest=CSpeedTreeForestDirectX8::Instance(); + m_kXMas.m_pkTree->Clear(); + rkForest.DeleteInstance(m_kXMas.m_pkTree); + m_kXMas.m_pkTree=NULL; + } + if (-1 != m_kXMas.m_iEffectID) + { + CEffectManager& rkEffMgr = CEffectManager::Instance(); + rkEffMgr.DestroyEffectInstance(m_kXMas.m_iEffectID); + m_kXMas.m_iEffectID=-1; + } +} + +void CMapOutdoor::__XMasTree_Create(float x, float y, float z, const char* c_szTreeName, const char* c_szEffName) +{ + assert(NULL==m_kXMas.m_pkTree); + assert(-1==m_kXMas.m_iEffectID); + + CSpeedTreeForestDirectX8& rkForest=CSpeedTreeForestDirectX8::Instance(); + DWORD dwCRC32 = GetCaseCRC32(c_szTreeName, strlen(c_szTreeName)); + m_kXMas.m_pkTree=rkForest.CreateInstance(x, y, z, dwCRC32, c_szTreeName); + + CEffectManager& rkEffMgr = CEffectManager::Instance(); + rkEffMgr.RegisterEffect(c_szEffName); + m_kXMas.m_iEffectID = rkEffMgr.CreateEffect(c_szEffName, + D3DXVECTOR3(x, y, z), + D3DXVECTOR3(0.0f, 0.0f, 0.0f)); +} + +void CMapOutdoor::XMasTree_Set(float x, float y, float z, const char* c_szTreeName, const char* c_szEffName) +{ + XMasTree_Destroy(); + __XMasTree_Create(x, y, z, c_szTreeName, c_szEffName); +} + +void CMapOutdoor::SpecialEffect_Create(DWORD dwID, float x, float y, float z, const char* c_szEffName) +{ + CEffectManager& rkEffMgr = CEffectManager::Instance(); + + TSpecialEffectMap::iterator itor = m_kMap_dwID_iEffectID.find(dwID); + if (m_kMap_dwID_iEffectID.end() != itor) + { + DWORD dwEffectID = itor->second; + if (rkEffMgr.SelectEffectInstance(dwEffectID)) + { + D3DXMATRIX mat; + D3DXMatrixIdentity(&mat); + mat._41 = x; + mat._42 = y; + mat._43 = z; + rkEffMgr.SetEffectInstanceGlobalMatrix(mat); + return; + } + } + + rkEffMgr.RegisterEffect(c_szEffName); + DWORD dwEffectID = rkEffMgr.CreateEffect(c_szEffName, + D3DXVECTOR3(x, y, z), + D3DXVECTOR3(0.0f, 0.0f, 0.0f)); + m_kMap_dwID_iEffectID.insert(std::make_pair(dwID, dwEffectID)); +} + +void CMapOutdoor::SpecialEffect_Delete(DWORD dwID) +{ + TSpecialEffectMap::iterator itor = m_kMap_dwID_iEffectID.find(dwID); + + if (m_kMap_dwID_iEffectID.end() == itor) + return; + + CEffectManager& rkEffMgr = CEffectManager::Instance(); + int iEffectID = itor->second; + rkEffMgr.DestroyEffectInstance(iEffectID); +} + +void CMapOutdoor::SpecialEffect_Destroy() +{ + CEffectManager& rkEffMgr = CEffectManager::Instance(); + + TSpecialEffectMap::iterator itor = m_kMap_dwID_iEffectID.begin(); + for (; itor != m_kMap_dwID_iEffectID.end(); ++itor) + { + int iEffectID = itor->second; + rkEffMgr.DestroyEffectInstance(iEffectID); + } +} + +void CMapOutdoor::ClearGuildArea() +{ + m_rkList_kGuildArea.clear(); +} + +void CMapOutdoor::RegisterGuildArea(int isx, int isy, int iex, int iey) +{ + RECT rect; + rect.left = isx; + rect.top = isy; + rect.right = iex; + rect.bottom = iey; + m_rkList_kGuildArea.push_back(rect); +} + +void CMapOutdoor::VisibleMarkedArea() +{ + std::map kMap_pbyMarkBuf; + std::set kSet_iProcessedMapIndex; + + std::list::iterator itorRect = m_rkList_kGuildArea.begin(); + for (; itorRect != m_rkList_kGuildArea.end(); ++itorRect) + { + const RECT & rkRect = *itorRect; + + int ix1Cell; + int iy1Cell; + BYTE byx1SubCell; + BYTE byy1SubCell; + WORD wx1TerrainNum; + WORD wy1TerrainNum; + + int ix2Cell; + int iy2Cell; + BYTE byx2SubCell; + BYTE byy2SubCell; + WORD wx2TerrainNum; + WORD wy2TerrainNum; + + ConvertToMapCoords(float(rkRect.left), float(rkRect.top), &ix1Cell, &iy1Cell, &byx1SubCell, &byy1SubCell, &wx1TerrainNum, &wy1TerrainNum); + ConvertToMapCoords(float(rkRect.right), float(rkRect.bottom), &ix2Cell, &iy2Cell, &byx2SubCell, &byy2SubCell, &wx2TerrainNum, &wy2TerrainNum); + + ix1Cell = ix1Cell + wx1TerrainNum*CTerrain::ATTRMAP_XSIZE; + iy1Cell = iy1Cell + wy1TerrainNum*CTerrain::ATTRMAP_YSIZE; + ix2Cell = ix2Cell + wx2TerrainNum*CTerrain::ATTRMAP_XSIZE; + iy2Cell = iy2Cell + wy2TerrainNum*CTerrain::ATTRMAP_YSIZE; + + for (int ixCell = ix1Cell; ixCell <= ix2Cell; ++ixCell) + for (int iyCell = iy1Cell; iyCell <= iy2Cell; ++iyCell) + { + int ixLocalCell = ixCell % CTerrain::ATTRMAP_XSIZE; + int iyLocalCell = iyCell % CTerrain::ATTRMAP_YSIZE; + int ixTerrain = ixCell / CTerrain::ATTRMAP_XSIZE; + int iyTerrain = iyCell / CTerrain::ATTRMAP_YSIZE; + int iTerrainNum = ixTerrain+iyTerrain*100; + + BYTE byTerrainNum; + if (!GetTerrainNumFromCoord(ixTerrain, iyTerrain, &byTerrainNum)) + continue; + CTerrain * pTerrain; + if (!GetTerrainPointer(byTerrainNum, &pTerrain)) + continue; + + if (kMap_pbyMarkBuf.end() == kMap_pbyMarkBuf.find(iTerrainNum)) + { + BYTE * pbyBuf = new BYTE [CTerrain::ATTRMAP_XSIZE*CTerrain::ATTRMAP_YSIZE]; + ZeroMemory(pbyBuf, CTerrain::ATTRMAP_XSIZE*CTerrain::ATTRMAP_YSIZE); + kMap_pbyMarkBuf[iTerrainNum] = pbyBuf; + } + + BYTE * pbyBuf = kMap_pbyMarkBuf[iTerrainNum]; + pbyBuf[ixLocalCell+iyLocalCell*CTerrain::ATTRMAP_XSIZE] = 0xff; + } + } + + std::map::iterator itorTerrain = kMap_pbyMarkBuf.begin(); + for (; itorTerrain != kMap_pbyMarkBuf.end(); ++itorTerrain) + { + int iTerrainNum = itorTerrain->first; + int ixTerrain = iTerrainNum%100; + int iyTerrain = iTerrainNum/100; + BYTE * pbyBuf = itorTerrain->second; + + BYTE byTerrainNum; + if (!GetTerrainNumFromCoord(ixTerrain, iyTerrain, &byTerrainNum)) + continue; + CTerrain * pTerrain; + if (!GetTerrainPointer(byTerrainNum, &pTerrain)) + continue; + + pTerrain->AllocateMarkedSplats(pbyBuf); + } + + stl_wipe_second(kMap_pbyMarkBuf); +} + +void CMapOutdoor::DisableMarkedArea() +{ + for (int i = 0; i < AROUND_AREA_NUM; ++i) + { + if (!m_pTerrain[i]) + continue; + + m_pTerrain[i]->DeallocateMarkedSplats(); + } +} + +void CMapOutdoor::ConvertToMapCoords(float fx, float fy, int *iCellX, int *iCellY, BYTE * pucSubCellX, BYTE * pucSubCellY, WORD * pwTerrainNumX, WORD * pwTerrainNumY) +{ + if ( fy < 0 ) + fy = -fy; + + int ix, iy; + PR_FLOAT_TO_INT(fx, ix); + PR_FLOAT_TO_INT(fy, iy); + + *pwTerrainNumX = ix / (CTerrainImpl::TERRAIN_XSIZE); + *pwTerrainNumY = iy / (CTerrainImpl::TERRAIN_YSIZE); + + float maxx = (float) CTerrainImpl::TERRAIN_XSIZE; + float maxy = (float) CTerrainImpl::TERRAIN_YSIZE; + + while (fx < 0) + fx += maxx; + + while (fy < 0) + fy += maxy; + + while (fx >= maxx) + fx -= maxx; + + while (fy >= maxy) + fy -= maxy; + + float fooscale = 1.0f / (float)(CTerrainImpl::HALF_CELLSCALE); + + float fCellX, fCellY; + + fCellX = fx * fooscale; + fCellY = fy * fooscale; + + PR_FLOAT_TO_INT(fCellX, *iCellX); + PR_FLOAT_TO_INT(fCellY, *iCellY); + + float fRatioooscale = ((float)CTerrainImpl::HEIGHT_TILE_XRATIO) * fooscale; + + float fSubcellX, fSubcellY; + fSubcellX = fx * fRatioooscale; + fSubcellY = fy * fRatioooscale; + + PR_FLOAT_TO_INT(fSubcellX, *pucSubCellX); + PR_FLOAT_TO_INT(fSubcellY, *pucSubCellY); + *pucSubCellX = (*pucSubCellX) % CTerrainImpl::HEIGHT_TILE_XRATIO; + *pucSubCellY = (*pucSubCellY) % CTerrainImpl::HEIGHT_TILE_YRATIO; +} diff --git a/source/GameLib/MapOutdoor.h b/source/GameLib/MapOutdoor.h new file mode 100644 index 0000000..2fa4508 --- /dev/null +++ b/source/GameLib/MapOutdoor.h @@ -0,0 +1,779 @@ +#pragma once + +#include "../eterLib/SkyBox.h" +#include "../eterLib/LensFlare.h" +#include "../eterLib/ScreenFilter.h" + +#include "../PRTerrainLib/TerrainType.h" +#include "../PRTerrainLib/TextureSet.h" + +#include "../SpeedTreeLib/SpeedTreeForestDirectX8.h" + +#include "MapBase.h" +#include "Area.h" +#include "AreaTerrain.h" +#include "AreaLoaderThread.h" + +#include "MonsterAreaInfo.h" + + +#define LOAD_SIZE_WIDTH 1 + +#define AROUND_AREA_NUM 1+(LOAD_SIZE_WIDTH*2)*(LOAD_SIZE_WIDTH*2)*2 +#define MAX_PREPARE_SIZE 9 +#define MAX_MAPSIZE 256 // 0 ~ 255, cellsize 200 = 64km + +#define TERRAINPATCH_LODMAX 3 + +typedef struct SOutdoorMapCoordinate +{ + short m_sTerrainCoordX; // Terrain ǥ + short m_sTerrainCoordY; +} TOutdoorMapCoordinate; + +typedef std::map TOutdoorMapCoordinateMap; + +class CTerrainPatchProxy; +class CTerrainQuadtreeNode; + +class CMapOutdoor : public CMapBase +{ + public: + enum + { + VIEW_NONE = 0, + VIEW_PART, + VIEW_ALL, + }; + + enum EPart + { + PART_TERRAIN, + PART_OBJECT, + PART_CLOUD, + PART_WATER, + PART_TREE, + PART_SKY, + PART_NUM, + }; + + enum ETerrainRenderSort + { + DISTANCE_SORT, + TEXTURE_SORT, + }; + + public: + CMapOutdoor(); + virtual ~CMapOutdoor(); + + virtual void OnBeginEnvironment(); + + protected: + bool Initialize(); + void InitializeFog(); + + virtual bool Destroy(); + virtual void OnSetEnvironmentDataPtr(); + virtual void OnResetEnvironmentDataPtr(); + + virtual void OnRender(); + + virtual void OnPreAssignTerrainPtr() {}; + + public: + void SetInverseViewAndDynamicShaodwMatrices(); + virtual bool Load(float x, float y, float z); + virtual float GetHeight(float x, float y); + virtual float GetCacheHeight(float x, float y); + + virtual bool Update(float fX, float fY, float fZ); + virtual void UpdateAroundAmbience(float fX, float fY, float fZ); + + public: + void Clear(); + + void SetVisiblePart(int ePart, bool isVisible); + void SetSplatLimit(int iSplatNum); + std::vector & GetRenderedSplatNum(int * piPatch, int * piSplat, float * pfSplatRatio); + CArea::TCRCWithNumberVector & GetRenderedGraphicThingInstanceNum(DWORD * pdwGraphicThingInstanceNum, DWORD * pdwCRCNum); + + bool LoadSetting(const char * c_szFileName); + + void ApplyLight(DWORD dwVersion, const D3DLIGHT8& c_rkLight); + void SetEnvironmentScreenFilter(); + void SetEnvironmentSkyBox(); + void SetEnvironmentLensFlare(); + + void CreateCharacterShadowTexture(); + void ReleaseCharacterShadowTexture(); + void SetShadowTextureSize(WORD size); + + bool BeginRenderCharacterShadowToTexture(); + void EndRenderCharacterShadowToTexture(); + void RenderWater(); + void RenderMarkedArea(); + void RecurseRenderAttr(CTerrainQuadtreeNode *Node, bool bCullEnable=TRUE); + void DrawPatchAttr(long patchnum); + void ClearGuildArea(); + void RegisterGuildArea(int isx, int isy, int iex, int iey); + + void VisibleMarkedArea(); + void DisableMarkedArea(); + + void UpdateSky(); + void RenderCollision(); + void RenderSky(); + void RenderCloud(); + void RenderBeforeLensFlare(); + void RenderAfterLensFlare(); + void RenderScreenFiltering(); + + void SetWireframe(bool bWireFrame); + bool IsWireframe(); + + bool GetPickingPointWithRay(const CRay & rRay, D3DXVECTOR3 * v3IntersectPt); + bool GetPickingPointWithRayOnlyTerrain(const CRay & rRay, D3DXVECTOR3 * v3IntersectPt); + bool GetPickingPoint(D3DXVECTOR3 * v3IntersectPt); + void GetTerrainCount(short * psTerrainCountX, short * psTerrainCountY) + { + *psTerrainCountX = m_sTerrainCountX; + *psTerrainCountY = m_sTerrainCountY; + } + + bool SetTerrainCount(short sTerrainCountX, short sTerrainCountY); + + // Shadow + void SetDrawShadow(bool bDrawShadow); + void SetDrawCharacterShadow(bool bDrawChrShadow); + + DWORD GetShadowMapColor(float fx, float fy); + + protected: + bool __PickTerrainHeight(float& fPos, const D3DXVECTOR3& v3Start, const D3DXVECTOR3& v3End, float fStep, float fRayRange, float fLimitRange, D3DXVECTOR3* pv3Pick); + + virtual void __ClearGarvage(); + virtual void __UpdateGarvage(); + + virtual bool LoadTerrain(WORD wTerrainCoordX, WORD wTerrainCoordY, WORD wCellCoordX, WORD wCellCoordY); + virtual bool LoadArea(WORD wAreaCoordX, WORD wAreaCoordY, WORD wCellCoordX, WORD wCellCoordY); + virtual void UpdateAreaList(long lCenterX, long lCenterY); + bool isTerrainLoaded(WORD wX, WORD wY); + bool isAreaLoaded(WORD wX, WORD wY); + + void AssignTerrainPtr(); // ǥ (ex. 3x3) ִ ͵ ͸ Ѵ. (Ʈ ҷ) + + void SaveAlphaFogOperation(); + void RestoreAlphaFogOperation(); + + ////////////////////////////////////////////////////////////////////////// + // New + ////////////////////////////////////////////////////////////////////////// + // ʵ ´. + void GetHeightMap(const BYTE & c_rucTerrainNum, WORD ** pwHeightMap); + void GetNormalMap(const BYTE & c_rucTerrainNum, char ** pucNormalMap); + + // Water + void GetWaterMap(const BYTE & c_rucTerrainNum, BYTE ** pucWaterMap); + void GetWaterHeight(BYTE byTerrainNum, BYTE byWaterNum, long * plWaterHeight); + + + ////////////////////////////////////////////////////////////////////////// + // Terrain + ////////////////////////////////////////////////////////////////////////// + protected: + // + CTerrain * m_pTerrain[AROUND_AREA_NUM]; // Terrain + CTerrainPatchProxy * m_pTerrainPatchProxyList; // CTerrain Ҷ ϴ ġ... Seamless Map CTerrainκ ... + + long m_lViewRadius; // þ Ÿ.. .. + float m_fHeightScale; // ... 1.0϶ 0~655.35ͱ ǥ . + + short m_sTerrainCountX, m_sTerrainCountY; // seamless map ȿ  Terrain + + TOutdoorMapCoordinate m_CurCoordinate; // ǥ + + long m_lCurCoordStartX, m_lCurCoordStartY; + TOutdoorMapCoordinate m_PrevCoordinate; // ǥ + TOutdoorMapCoordinateMap m_EntryPointMap; + + WORD m_wPatchCount; + + ////////////////////////////////////////////////////////////////////////// + // Index Buffer +#ifdef WORLD_EDITOR + WORD * m_pwIndices; /* temp Index buffer */ + + CGraphicIndexBuffer m_IndexBuffer; + WORD m_wNumIndices; +#else + WORD * m_pwaIndices[TERRAINPATCH_LODMAX]; + + CGraphicIndexBuffer m_IndexBuffer[TERRAINPATCH_LODMAX]; + WORD m_wNumIndices[TERRAINPATCH_LODMAX]; +#endif + virtual void DestroyTerrain(); + + void CreateTerrainPatchProxyList(); + void DestroyTerrainPatchProxyList(); + + void UpdateTerrain(float fX, float fY); + + void ConvertTerrainToTnL(long lx, long ly); + + void AssignPatch(long lPatchNum, long lx0, long ly0, long lx1, long ly1); + + ////////////////////////////////////////////////////////////////////////// + // Index Buffer + void ADDLvl1TL(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp); + void ADDLvl1T(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp); + void ADDLvl1TR(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp); + void ADDLvl1L(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp); + void ADDLvl1R(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp); + void ADDLvl1BL(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp); + void ADDLvl1B(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp); + void ADDLvl1BR(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp); + void ADDLvl1M(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp); + void ADDLvl2TL(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp); + void ADDLvl2T(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp); + void ADDLvl2TR(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp); + void ADDLvl2L(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp); + void ADDLvl2R(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp); + void ADDLvl2BL(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp); + void ADDLvl2B(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp); + void ADDLvl2BR(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp); + void ADDLvl2M(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp); + + public: + BOOL GetTerrainPointer(BYTE c_ucTerrainNum, CTerrain ** ppTerrain); + float GetTerrainHeight(float fx, float fy); + bool GetWaterHeight(int iX, int iY, long * plWaterHeight); + bool GetNormal(int ix, int iy, D3DXVECTOR3 * pv3Normal); + + void RenderTerrain(); + + const long GetViewRadius() { return m_lViewRadius; } + const float GetHeightScale() { return m_fHeightScale; } + + const TOutdoorMapCoordinate & GetEntryPoint(const std::string & c_rstrEntryPointName) const; + void SetEntryPoint(const std::string & c_rstrEntryPointName, const TOutdoorMapCoordinate & c_rOutdoorMapCoordinate); + const TOutdoorMapCoordinate & GetCurCoordinate() { return m_CurCoordinate; } + const TOutdoorMapCoordinate & GetPrevCoordinate() { return m_PrevCoordinate; } + + ////////////////////////////////////////////////////////////////////////// + // Area + ////////////////////////////////////////////////////////////////////////// + protected: + CArea * m_pArea[AROUND_AREA_NUM]; // Data + + virtual void DestroyArea(); + + void __UpdateArea(D3DXVECTOR3& v3Player); +#ifdef WORLD_EDITOR + void __NEW_WorldEditor_UpdateArea(); +#endif + void __Game_UpdateArea(D3DXVECTOR3& v3Player); + + void __BuildDynamicSphereInstanceVector(); + + void __CollectShadowReceiver(D3DXVECTOR3& v3Target, D3DXVECTOR3& v3Light); + void __CollectCollisionPCBlocker(D3DXVECTOR3& v3Eye, D3DXVECTOR3& v3Target, float fDistance); + void __CollectCollisionShadowReceiver(D3DXVECTOR3& v3Target, D3DXVECTOR3& v3Light); + void __UpdateAroundAreaList(); + bool __IsInShadowReceiverList(CGraphicObjectInstance* pkObjInstTest); + bool __IsInPCBlockerList(CGraphicObjectInstance* pkObjInstTest); + + void ConvertToMapCoords(float fx, float fy, int *iCellX, int *iCellY, BYTE * pucSubCellX, BYTE * pucSubCellY, WORD * pwTerrainNumX, WORD * pwTerrainNumY); + + public: + BOOL GetAreaPointer(const BYTE c_ucAreaNum, CArea ** ppArea); + void RenderArea(bool bRenderAmbience = true); + void RenderBlendArea(); + void RenderDungeon(); + void RenderEffect(); + void RenderPCBlocker(); + void RenderTree(); + + public: + ////////////////////////////////////////////////////////////////////////// + // For Grass + ////////////////////////////////////////////////////////////////////////// + float GetHeight(float* pPos); + bool GetBrushColor(float fX, float fY, float* pLowColor, float* pHighColor); + bool isAttrOn(float fX, float fY, BYTE byAttr); + bool GetAttr(float fX, float fY, BYTE * pbyAttr); + bool isAttrOn(int iX, int iY, BYTE byAttr); + bool GetAttr(int iX, int iY, BYTE * pbyAttr); + + void SetMaterialDiffuse(float fr, float fg, float fb); + void SetMaterialAmbient(float fr, float fg, float fb); + void SetTerrainMaterial(const PR_MATERIAL * pMaterial); + + bool GetTerrainNum(float fx, float fy, BYTE * pbyTerrainNum); + bool GetTerrainNumFromCoord(WORD wCoordX, WORD wCoordY, BYTE * pbyTerrainNum); + + protected: + ////////////////////////////////////////////////////////////////////////// + // New + ////////////////////////////////////////////////////////////////////////// + long m_lCenterX, m_lCenterY; // Terrain ǥ ǥ... + long m_lOldReadX, m_lOldReadY; /* Last center */ + + ////////////////////////////////////////////////////////////////////////// + // Octree + ////////////////////////////////////////////////////////////////////////// + CTerrainQuadtreeNode * m_pRootNode; + + void BuildQuadTree(); + CTerrainQuadtreeNode * AllocQuadTreeNode(long x0, long y0, long x1, long y1); + void SubDivideNode(CTerrainQuadtreeNode * Node); + void UpdateQuadTreeHeights(CTerrainQuadtreeNode *Node); + + + void FreeQuadTree(); + + struct TPatchDrawStruct + { + float fDistance; + BYTE byTerrainNum; + long lPatchNum; + CTerrainPatchProxy * pTerrainPatchProxy; + + bool operator<( const TPatchDrawStruct & rhs) const + { + return fDistance < rhs.fDistance; + } + }; + + public: + typedef std::vector TTerrainNumVector; + struct FSortPatchDrawStructWithTerrainNum + { + static TTerrainNumVector m_TerrainNumVector; + FSortPatchDrawStructWithTerrainNum() + { + m_TerrainNumVector.clear(); + } + + bool operator () (const TPatchDrawStruct & lhs, const TPatchDrawStruct & rhs) + { + DWORD lhsTerrainNumOrder = 0, rhsTerrainNumOrder = 0; + bool blhsOrderFound = false; + bool brhsOrderFound = false; + + TTerrainNumVector::iterator lhsIterator = std::find(m_TerrainNumVector.begin(), m_TerrainNumVector.end(), lhs.byTerrainNum); + TTerrainNumVector::iterator rhsIterator = std::find(m_TerrainNumVector.begin(), m_TerrainNumVector.end(), rhs.byTerrainNum); + + if (lhsIterator != m_TerrainNumVector.end()) + { + blhsOrderFound = true; + lhsTerrainNumOrder = lhsIterator - m_TerrainNumVector.begin(); + } + if (rhsIterator != m_TerrainNumVector.end()) + { + brhsOrderFound = true; + rhsTerrainNumOrder = rhsIterator - m_TerrainNumVector.begin(); + } + if (!brhsOrderFound) + { + m_TerrainNumVector.push_back(rhs.byTerrainNum); + rhsTerrainNumOrder = m_TerrainNumVector.size() -1; + } + if (!blhsOrderFound) + { + lhsIterator = std::find(m_TerrainNumVector.begin(), m_TerrainNumVector.end(), lhs.byTerrainNum); + if (lhsIterator != m_TerrainNumVector.end()) + { + blhsOrderFound = true; + lhsTerrainNumOrder = lhsIterator - m_TerrainNumVector.begin(); + } + if (!blhsOrderFound) + { + m_TerrainNumVector.push_back(lhs.byTerrainNum); + lhsTerrainNumOrder = m_TerrainNumVector.size() -1; + } + } + + return lhsTerrainNumOrder < rhsTerrainNumOrder; + } + }; + + protected: + + std::vector > m_PatchVector; + std::vector m_PatchDrawStructVector; + + void SetPatchDrawVector(); + + void NEW_DrawWireFrame(CTerrainPatchProxy * pTerrainPatchProxy, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType); + + void DrawWireFrame(long patchnum, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType); + void DrawWater(long patchnum); + + bool m_bDrawWireFrame; + bool m_bDrawShadow; + bool m_bDrawChrShadow; + + ////////////////////////////////////////////////////////////////////////// + // Water + D3DXMATRIX m_matBump; + void LoadWaterTexture(); + void UnloadWaterTexture(); + //Water + ////////////////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////////// + // Alpha Fog + CGraphicImageInstance m_AlphaFogImageInstance; + D3DXMATRIX m_matAlphaFogTexture; + // Alpha Fog + ////////////////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////////// + // Character Shadow + LPDIRECT3DTEXTURE8 m_lpCharacterShadowMapTexture; + LPDIRECT3DSURFACE8 m_lpCharacterShadowMapRenderTargetSurface; + LPDIRECT3DSURFACE8 m_lpCharacterShadowMapDepthSurface; + D3DVIEWPORT8 m_ShadowMapViewport; + WORD m_wShadowMapSize; + + // Backup Device Context + LPDIRECT3DSURFACE8 m_lpBackupRenderTargetSurface; + LPDIRECT3DSURFACE8 m_lpBackupDepthSurface; + D3DVIEWPORT8 m_BackupViewport; + + // Character Shadow + ////////////////////////////////////////////////////////////////////////// + + // View Frustum Culling + D3DXPLANE m_plane[6]; + + void BuildViewFrustum(D3DXMATRIX & mat); + + CTextureSet m_TextureSet; + + protected: + CSkyBox m_SkyBox; + CLensFlare m_LensFlare; + CScreenFilter m_ScreenFilter; + + protected: + void SetIndexBuffer(); + void SelectIndexBuffer(BYTE byLODLevel, WORD * pwPrimitiveCount, D3DPRIMITIVETYPE * pePrimitiveType); + + D3DXMATRIX m_matWorldForCommonUse; + D3DXMATRIX m_matViewInverse; + + D3DXMATRIX m_matSplatAlpha; + D3DXMATRIX m_matStaticShadow; + D3DXMATRIX m_matDynamicShadow; + D3DXMATRIX m_matDynamicShadowScale; + D3DXMATRIX m_matLightView; + + float m_fTerrainTexCoordBase; + float m_fWaterTexCoordBase; + + float m_fXforDistanceCaculation, m_fYforDistanceCaculation; + + protected: + typedef std::vector TTerrainPtrVector; + typedef TTerrainPtrVector::iterator TTerrainPtrVectorIterator; + typedef std::vector TAreaPtrVector; + typedef TAreaPtrVector::iterator TAreaPtrVectorIterator; + + TTerrainPtrVector m_TerrainVector; + TTerrainPtrVector m_TerrainDeleteVector; + TTerrainPtrVector m_TerrainLoadRequestVector; + TTerrainPtrVector m_TerrainLoadWaitVector; + TTerrainPtrVectorIterator m_TerrainPtrVectorIterator; + + TAreaPtrVector m_AreaVector; + TAreaPtrVector m_AreaDeleteVector; + TAreaPtrVector m_AreaLoadRequestVector; + TAreaPtrVector m_AreaLoadWaitVector; + TAreaPtrVectorIterator m_AreaPtrVectorIterator; + + struct FPushToDeleteVector + { + enum EDeleteDir + { + DELETE_LEFT, + DELETE_RIGHT, + DELETE_TOP, + DELETE_BOTTOM, + }; + + EDeleteDir m_eLRDeleteDir; + EDeleteDir m_eTBDeleteDir; + TOutdoorMapCoordinate m_CurCoordinate; + + FPushToDeleteVector(EDeleteDir eLRDeleteDir, EDeleteDir eTBDeleteDir, TOutdoorMapCoordinate CurCoord) + { + m_eLRDeleteDir = eLRDeleteDir; + m_eTBDeleteDir = eTBDeleteDir; + m_CurCoordinate = CurCoord; + } + }; + + struct FPushTerrainToDeleteVector : public FPushToDeleteVector + { + TTerrainPtrVector m_ReturnTerrainVector; + + FPushTerrainToDeleteVector(EDeleteDir eLRDeleteDir, EDeleteDir eTBDeleteDir, TOutdoorMapCoordinate CurCoord) + : FPushToDeleteVector(eLRDeleteDir, eTBDeleteDir, CurCoord) + { + m_ReturnTerrainVector.clear(); + } + + void operator() (CTerrain * pTerrain); + }; + + struct FPushAreaToDeleteVector : public FPushToDeleteVector + { + TAreaPtrVector m_ReturnAreaVector; + + FPushAreaToDeleteVector(EDeleteDir eLRDeleteDir, EDeleteDir eTBDeleteDir, TOutdoorMapCoordinate CurCoord) + : FPushToDeleteVector(eLRDeleteDir, eTBDeleteDir, CurCoord) + { + m_ReturnAreaVector.clear(); + } + + void operator() (CArea * pArea); + }; + + protected: + void InitializeVisibleParts(); + bool IsVisiblePart(int ePart); + + float __GetNoFogDistance(); + float __GetFogDistance(); + + + protected: + DWORD m_dwVisiblePartFlags; + + int m_iRenderedSplatNumSqSum; + int m_iRenderedSplatNum; + int m_iRenderedPatchNum; + std::vector m_RenderedTextureNumVector; + int m_iSplatLimit; + + protected: + int m_iPatchTerrainVertexCount; + int m_iPatchWaterVertexCount; + + int m_iPatchTerrainVertexSize; + int m_iPatchWaterVertexSize; + + DWORD m_dwRenderedCRCNum; + DWORD m_dwRenderedGraphicThingInstanceNum; + + std::list m_rkList_kGuildArea; + + protected: + void __RenderTerrain_RecurseRenderQuadTree(CTerrainQuadtreeNode *Node, bool bCullCheckNeed = true); + int __RenderTerrain_RecurseRenderQuadTree_CheckBoundingCircle(const D3DXVECTOR3 & c_v3Center, const float & c_fRadius); + + void __RenderTerrain_AppendPatch(const D3DXVECTOR3& c_rv3Center, float fDistance, long lPatchNum); + + void __RenderTerrain_RenderSoftwareTransformPatch(); + void __RenderTerrain_RenderHardwareTransformPatch(); + + protected: + void __HardwareTransformPatch_RenderPatchSplat(long patchnum, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType); + void __HardwareTransformPatch_RenderPatchNone(long patchnum, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType); + + + protected: + struct SoftwareTransformPatch_SData + { + enum + { + SPLAT_VB_NUM = 8, + NONE_VB_NUM = 8, + }; + + IDirect3DVertexBuffer8* m_pkVBSplat[SPLAT_VB_NUM]; + IDirect3DVertexBuffer8* m_pkVBNone[NONE_VB_NUM]; + DWORD m_dwSplatPos; + DWORD m_dwNonePos; + DWORD m_dwLightVersion; + } m_kSTPD; + + struct SoftwareTransformPatch_SRenderState { + D3DXMATRIX m_m4Proj; + D3DXMATRIX m_m4Frustum; + D3DXMATRIX m_m4DynamicShadow; + D3DLIGHT8 m_kLight; + D3DMATERIAL8 m_kMtrl; + D3DXVECTOR3 m_v3Player; + DWORD m_dwFogColor; + float m_fScreenHalfWidth; + float m_fScreenHalfHeight; + + float m_fFogNearDistance; + float m_fFogFarDistance; + float m_fFogNearTransZ; + float m_fFogFarTransZ; + float m_fFogLenInv; + }; + + struct SoftwareTransformPatch_STVertex + { + D3DXVECTOR4 kPosition; + }; + + struct SoftwareTransformPatch_STLVertex + { + D3DXVECTOR4 kPosition; + DWORD dwDiffuse; + DWORD dwFog; + D3DXVECTOR2 kTexTile; + D3DXVECTOR2 kTexAlpha; + D3DXVECTOR2 kTexStaticShadow; + D3DXVECTOR2 kTexDynamicShadow; + }; + + + void __SoftwareTransformPatch_ApplyRenderState(); + void __SoftwareTransformPatch_RestoreRenderState(DWORD dwFogEnable); + + void __SoftwareTransformPatch_Initialize(); + bool __SoftwareTransformPatch_Create(); + void __SoftwareTransformPatch_Destroy(); + void __SoftwareTransformPatch_BuildPipeline(SoftwareTransformPatch_SRenderState& rkTPRS); + void __SoftwareTransformPatch_BuildPipeline_BuildFogFuncTable(SoftwareTransformPatch_SRenderState& rkTPRS); + bool __SoftwareTransformPatch_SetTransform(SoftwareTransformPatch_SRenderState& rkTPRS, SoftwareTransformPatch_STLVertex* akTransVertex, CTerrainPatchProxy& rkTerrainPatchProxy, UINT uTerrainX, UINT uTerrainY, bool isFogEnable, bool isDynamicShadow); + + bool __SoftwareTransformPatch_SetSplatStream(SoftwareTransformPatch_STLVertex* akTransVertex); + bool __SoftwareTransformPatch_SetShadowStream(SoftwareTransformPatch_STLVertex* akTransVertex); + + void __SoftwareTransformPatch_ApplyStaticShadowRenderState(); + void __SoftwareTransformPatch_RestoreStaticShadowRenderState(); + + void __SoftwareTransformPatch_ApplyFogShadowRenderState(); + void __SoftwareTransformPatch_RestoreFogShadowRenderState(); + void __SoftwareTransformPatch_ApplyDynamicShadowRenderState(); + void __SoftwareTransformPatch_RestoreDynamicShadowRenderState(); + void __SoftwareTransformPatch_RenderPatchSplat(SoftwareTransformPatch_SRenderState& rkTPRS, long patchnum, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType, bool isFogEnable); + void __SoftwareTransformPatch_RenderPatchNone(SoftwareTransformPatch_SRenderState& rkTPRS, long patchnum, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType); + + + protected: + std::vector m_ShadowReceiverVector; + std::vector m_PCBlockerVector; + + protected: + float m_fOpaqueWaterDepth; + CGraphicImageInstance m_WaterInstances[30]; + + public: + float GetOpaqueWaterDepth() { return m_fOpaqueWaterDepth; } + void SetOpaqueWaterDepth(float fOpaqueWaterDepth) { m_fOpaqueWaterDepth = fOpaqueWaterDepth; } + void SetTerrainRenderSort(ETerrainRenderSort eTerrainRenderSort) { m_eTerrainRenderSort = eTerrainRenderSort;} + ETerrainRenderSort GetTerrainRenderSort() { return m_eTerrainRenderSort; } + + protected: + ETerrainRenderSort m_eTerrainRenderSort; + + protected: + CGraphicImageInstance m_attrImageInstance; + CGraphicImageInstance m_BuildingTransparentImageInstance; + D3DXMATRIX m_matBuildingTransparent; + + protected: + CDynamicPool m_kPool_kMonsterAreaInfo; + TMonsterAreaInfoPtrVector m_MonsterAreaInfoPtrVector; + TMonsterAreaInfoPtrVectorIterator m_MonsterAreaInfoPtrVectorIterator; + + public: + bool LoadMonsterAreaInfo(); + + CMonsterAreaInfo * AddMonsterAreaInfo(long lOriginX, long lOriginY, long lSizeX, long lSizeY); + void RemoveAllMonsterAreaInfo(); + + DWORD GetMonsterAreaInfoCount() { return m_MonsterAreaInfoPtrVector.size(); } + bool GetMonsterAreaInfoFromVectorIndex(DWORD dwMonsterAreaInfoVectorIndex, CMonsterAreaInfo ** ppMonsterAreaInfo); + + CMonsterAreaInfo * AddNewMonsterAreaInfo(long lOriginX, long lOriginY, long lSizeX, long lSizeY, + CMonsterAreaInfo::EMonsterAreaInfoType eMonsterAreaInfoType, + DWORD dwVID, DWORD dwCount, CMonsterAreaInfo::EMonsterDir eMonsterDir); + + public: + void GetBaseXY(DWORD * pdwBaseX, DWORD * pdwBaseY); + void SetBaseXY(DWORD dwBaseX, DWORD dwBaseY); + + void SetTransparentTree(bool bTransparentTree) { m_bTransparentTree = bTransparentTree;} + void EnableTerrainOnlyForHeight(bool bFlag) { m_bEnableTerrainOnlyForHeight = bFlag; } + void EnablePortal(bool bFlag); + bool IsEnablePortal() { return m_bEnablePortal; } + + protected: + DWORD m_dwBaseX; + DWORD m_dwBaseY; + + D3DXVECTOR3 m_v3Player; + + bool m_bShowEntirePatchTextureCount; + bool m_bTransparentTree; + bool m_bEnableTerrainOnlyForHeight; + bool m_bEnablePortal; + + // XMas + private: + struct SXMasTree + { + CSpeedTreeWrapper* m_pkTree; + int m_iEffectID; + } m_kXMas; + + void __XMasTree_Initialize(); + void __XMasTree_Create(float x, float y, float z, const char* c_szTreeName, const char* c_szEffName); + + public: + void XMasTree_Destroy(); + void XMasTree_Set(float x, float y, float z, const char* c_szTreeName, const char* c_szEffName); + + // Special Effect + private: + typedef std::map TSpecialEffectMap; + TSpecialEffectMap m_kMap_dwID_iEffectID; + + public: + void SpecialEffect_Create(DWORD dwID, float x, float y, float z, const char* c_szEffName); + void SpecialEffect_Delete(DWORD dwID); + void SpecialEffect_Destroy(); + + private: + struct SHeightCache + { + struct SItem + { + DWORD m_dwKey; + float m_fHeight; + }; + + enum + { + HASH_SIZE = 100, + }; + + std::vector m_akVct_kItem[HASH_SIZE]; + + bool m_isUpdated; + } m_kHeightCache; + + void __HeightCache_Init(); + void __HeightCache_Update(); + + public: + void SetEnvironmentDataName(const std::string& strEnvironmentDataName); + std::string& GetEnvironmentDataName(); + + protected: + std::string m_settings_envDataName; + std::string m_envDataName; + + private: + bool m_bSettingTerrainVisible; +}; diff --git a/source/GameLib/MapOutdoorCharacterShadow.cpp b/source/GameLib/MapOutdoorCharacterShadow.cpp new file mode 100644 index 0000000..1292c1b --- /dev/null +++ b/source/GameLib/MapOutdoorCharacterShadow.cpp @@ -0,0 +1,165 @@ +#include "StdAfx.h" +#include "../eterLib/StateManager.h" +#include "../eterlib/Camera.h" + +#include "MapOutdoor.h" + +static int recreate = false; + +void CMapOutdoor::SetShadowTextureSize(WORD size) +{ + if (m_wShadowMapSize != size) + { + recreate = true; + Tracenf("ShadowTextureSize changed %d -> %d", m_wShadowMapSize, size); + } + + m_wShadowMapSize = size; +} + +void CMapOutdoor::CreateCharacterShadowTexture() +{ + extern bool GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW; + + if (GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW) + return; + + ReleaseCharacterShadowTexture(); + + if (IsLowTextureMemory()) + SetShadowTextureSize(128); + + m_ShadowMapViewport.X = 1; + m_ShadowMapViewport.Y = 1; + m_ShadowMapViewport.Width = m_wShadowMapSize - 2; + m_ShadowMapViewport.Height = m_wShadowMapSize - 2; + m_ShadowMapViewport.MinZ = 0.0f; + m_ShadowMapViewport.MaxZ = 1.0f; + + if (FAILED(ms_lpd3dDevice->CreateTexture(m_wShadowMapSize, m_wShadowMapSize, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &m_lpCharacterShadowMapTexture))) + { + TraceError("CMapOutdoor Unable to create Character Shadow render target texture\n"); + return; + } + + if (FAILED(m_lpCharacterShadowMapTexture->GetSurfaceLevel(0, &m_lpCharacterShadowMapRenderTargetSurface))) + { + TraceError("CMapOutdoor Unable to GetSurfaceLevel Character Shadow render target texture\n"); + return; + } + + if (FAILED(ms_lpd3dDevice->CreateDepthStencilSurface(m_wShadowMapSize, m_wShadowMapSize, D3DFMT_D16, D3DMULTISAMPLE_NONE, &m_lpCharacterShadowMapDepthSurface))) + { + TraceError("CMapOutdoor Unable to create Character Shadow depth Surface\n"); + return; + } +} + +void CMapOutdoor::ReleaseCharacterShadowTexture() +{ + SAFE_RELEASE(m_lpCharacterShadowMapRenderTargetSurface); + SAFE_RELEASE(m_lpCharacterShadowMapDepthSurface); + SAFE_RELEASE(m_lpCharacterShadowMapTexture); +} + +DWORD dwLightEnable = FALSE; + +bool CMapOutdoor::BeginRenderCharacterShadowToTexture() +{ + D3DXMATRIX matLightView, matLightProj; + + CCamera* pCurrentCamera = CCameraManager::Instance().GetCurrentCamera(); + + if (!pCurrentCamera) + return false; + + if (recreate) + { + CreateCharacterShadowTexture(); + recreate = false; + } + + D3DXVECTOR3 v3Target = pCurrentCamera->GetTarget(); + + D3DXVECTOR3 v3Eye(v3Target.x - 1.732f * 1250.0f, + v3Target.y - 1250.0f, + v3Target.z + 2.0f * 1.732f * 1250.0f); + + const auto vv = D3DXVECTOR3(0.0f, 0.0f, 1.0f); + D3DXMatrixLookAtRH(&matLightView, + &v3Eye, + &v3Target, + &vv); + + D3DXMatrixOrthoRH(&matLightProj, 2550.0f, 2550.0f, 1.0f, 15000.0f); + + STATEMANAGER.SaveTransform(D3DTS_VIEW, &matLightView); + STATEMANAGER.SaveTransform(D3DTS_PROJECTION, &matLightProj); + + dwLightEnable = STATEMANAGER.GetRenderState(D3DRS_LIGHTING); + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); + + STATEMANAGER.SaveRenderState(D3DRS_TEXTUREFACTOR, 0xFF808080); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + + bool bSuccess = true; + + // Backup Device Context + if (FAILED(ms_lpd3dDevice->GetRenderTarget(&m_lpBackupRenderTargetSurface))) + { + TraceError("CMapOutdoor::BeginRenderCharacterShadowToTexture : Unable to Save Window Render Target\n"); + bSuccess = false; + } + + if (FAILED(ms_lpd3dDevice->GetDepthStencilSurface(&m_lpBackupDepthSurface))) + { + TraceError("CMapOutdoor::BeginRenderCharacterShadowToTexture : Unable to Save Window Depth Surface\n"); + bSuccess = false; + } + + if (FAILED(ms_lpd3dDevice->SetRenderTarget(m_lpCharacterShadowMapRenderTargetSurface, m_lpCharacterShadowMapDepthSurface))) + { + TraceError("CMapOutdoor::BeginRenderCharacterShadowToTexture : Unable to Set Shadow Map Render Target\n"); + bSuccess = false; + } + + if (FAILED(ms_lpd3dDevice->Clear(0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0xFF, 0xFF, 0xFF), 1.0f, 0))) + { + TraceError("CMapOutdoor::BeginRenderCharacterShadowToTexture : Unable to Clear Render Target"); + bSuccess = false; + } + + if (FAILED(ms_lpd3dDevice->GetViewport(&m_BackupViewport))) + { + TraceError("CMapOutdoor::BeginRenderCharacterShadowToTexture : Unable to Save Window Viewport\n"); + bSuccess = false; + } + + if (FAILED(ms_lpd3dDevice->SetViewport(&m_ShadowMapViewport))) + { + TraceError("CMapOutdoor::BeginRenderCharacterShadowToTexture : Unable to Set Shadow Map viewport\n"); + bSuccess = false; + } + + return bSuccess; +} + +void CMapOutdoor::EndRenderCharacterShadowToTexture() +{ + ms_lpd3dDevice->SetViewport(&m_BackupViewport); + + ms_lpd3dDevice->SetRenderTarget(m_lpBackupRenderTargetSurface, m_lpBackupDepthSurface); + + SAFE_RELEASE(m_lpBackupRenderTargetSurface); + SAFE_RELEASE(m_lpBackupDepthSurface); + + STATEMANAGER.RestoreTransform(D3DTS_VIEW); + STATEMANAGER.RestoreTransform(D3DTS_PROJECTION); + + // Restore Device Context + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, dwLightEnable); + STATEMANAGER.RestoreRenderState(D3DRS_TEXTUREFACTOR); +} diff --git a/source/GameLib/MapOutdoorIndexBuffer.cpp b/source/GameLib/MapOutdoorIndexBuffer.cpp new file mode 100644 index 0000000..300a7a5 --- /dev/null +++ b/source/GameLib/MapOutdoorIndexBuffer.cpp @@ -0,0 +1,529 @@ +#include "StdAfx.h" +#include "MapOutdoor.h" + +void CMapOutdoor::SetIndexBuffer() +{ + void * pIndices; + long x, y; + + DWORD dwIndexNum = TERRAIN_PATCHSIZE * TERRAIN_PATCHSIZE * 4; + +#ifdef WORLD_EDITOR + m_pwIndices = new WORD[dwIndexNum]; + if (!m_pwIndices) + TraceError("CMapOutdoor::SetIndexBuffer() IndexBuffer is NULL"); + + memset(m_pwIndices, 0, sizeof(WORD) * dwIndexNum); + if (!m_IndexBuffer.Create(dwIndexNum, D3DFMT_INDEX16)) + TraceError("CMapOutdoor::SetIndexBuffer() IndexBuffer Create Error"); + + WORD count = 0; + WORD count2 = 0; + long ry = 0; + + BYTE ucNumLineWarp = TERRAIN_PATCHSIZE + 1; + + for (y = 0; y < TERRAIN_PATCHSIZE; y++) + { + if (ry % 2 == 0) + { + m_pwIndices[count++] = count2; + m_pwIndices[count++] = count2+ucNumLineWarp; + } + else + { + m_pwIndices[count++] = count2+ucNumLineWarp; + m_pwIndices[count++] = count2; + } + + for (x = 0; x < TERRAIN_PATCHSIZE; x++) + { + if (ry % 2 == 1) + { + m_pwIndices[count++] = (WORD) (count2+ucNumLineWarp-1); + m_pwIndices[count++] = (WORD) (count2-1); + count2 -= (short) 1; + } + else + { + m_pwIndices[count++] = (WORD) (count2+1); + m_pwIndices[count++] = (WORD) (count2+ucNumLineWarp+1); + count2 += (short) 1; + } + } + + if (y < TERRAIN_PATCHSIZE-1) + { + m_pwIndices[count++] = (WORD) (count2+ucNumLineWarp); + m_pwIndices[count++] = (WORD) (count2+ucNumLineWarp); + count2 += ucNumLineWarp; + } + ry++; + } + + m_wNumIndices = count; + if (!m_IndexBuffer.Lock((void **) &pIndices)) + TraceError("CMapOutdoor::SetIndexBuffer() IndexBuffer Unlock Error"); + memcpy(pIndices, m_pwIndices, count * sizeof(WORD)); + m_IndexBuffer.Unlock(); + + delete [] m_pwIndices; + m_pwIndices = NULL; +#else + WORD count[TERRAINPATCH_LODMAX], count2[TERRAINPATCH_LODMAX]; + BYTE uci; + for (uci = 0; uci < TERRAINPATCH_LODMAX; ++uci) + { + m_pwaIndices[uci] = new WORD[dwIndexNum]; + memset(m_pwaIndices[uci], 0, sizeof(WORD) * dwIndexNum); + count[uci] = 0; + count2[uci] = 0; + if ( !m_IndexBuffer[uci].Create(dwIndexNum, D3DFMT_INDEX16) ) + TraceError("CMapOutdoor::SetIndexBuffer() IndexBuffer Create Error"); + } + + BYTE ucNumLineWarp = TERRAIN_PATCHSIZE + 1; + + for (y = 0; y < TERRAIN_PATCHSIZE; y++) + { + if (y%2 == 0) + { + m_pwaIndices[0][(count[0])++] = count2[0]; + m_pwaIndices[0][(count[0])++] = count2[0]+ucNumLineWarp; + } + else + { + m_pwaIndices[0][(count[0])++] = count2[0]+ucNumLineWarp; + m_pwaIndices[0][(count[0])++] = count2[0]; + } + + for (x = 0; x < TERRAIN_PATCHSIZE; x++) + { + if (y%2 == 0) + { + m_pwaIndices[0][(count[0])++] = (WORD) (count2[0]+1); + m_pwaIndices[0][(count[0])++] = (WORD) (count2[0]+ucNumLineWarp+1); + count2[0] += (short) 1; + } + else + { + m_pwaIndices[0][(count[0])++] = (WORD) (count2[0]+ucNumLineWarp-1); + m_pwaIndices[0][(count[0])++] = (WORD) (count2[0]-1); + count2[0] -= (short) 1; + } + + if (0 == x%2) + { + if (0 == y) + { + if (0 == x) + ADDLvl1TL(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp); + else if ((TERRAIN_PATCHSIZE - 2) == x) + ADDLvl1TR(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp); + else + ADDLvl1T(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp); + } + else if ((TERRAIN_PATCHSIZE - 2) == y) + { + if (0 == x) + ADDLvl1BL(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp); + else if ((TERRAIN_PATCHSIZE - 2) == x) + ADDLvl1BR(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp); + else + ADDLvl1B(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp); + } + else if (0 == y%2) + { + if (0 == x) + ADDLvl1L(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp); + else if ((TERRAIN_PATCHSIZE - 2) == x) + ADDLvl1R(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp); + else + ADDLvl1M(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp); + } + count2[1] += 2; + } + + if (0 == x%4) + { + if (0 == y) + { + if (0 == x) + ADDLvl2TL(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp); + else if ((TERRAIN_PATCHSIZE - 4) == x) + ADDLvl2TR(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp); + else + ADDLvl2T(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp); + } + else if ((TERRAIN_PATCHSIZE - 4) == y) + { + if (0 == x) + ADDLvl2BL(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp); + else if ((TERRAIN_PATCHSIZE - 4) == x) + ADDLvl2BR(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp); + else + ADDLvl2B(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp); + } + else if (0 == y%4) + { + if (0 == x) + ADDLvl2L(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp); + else if ((TERRAIN_PATCHSIZE - 4) == x) + ADDLvl2R(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp); + else + ADDLvl2M(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp); + } + count2[2] += 4; + } + } + + if (y < TERRAIN_PATCHSIZE-1) + { + m_pwaIndices[0][(count[0])++] = (WORD) (count2[0]+ucNumLineWarp); + m_pwaIndices[0][(count[0])++] = (WORD) (count2[0]+ucNumLineWarp); + count2[0] += ucNumLineWarp; + if (0 == y%2) + count2[1] += 2; + if (0 == y%4) + count2[2] += 4; + } + } + + for (uci = 0; uci < TERRAINPATCH_LODMAX; ++uci) + { + m_wNumIndices[uci] = count[uci]; + if( !m_IndexBuffer[uci].Lock((void **) &pIndices) ) + TraceError("CMapOutdoor::SetIndexBuffer() IndexBuffer Unlock Error"); + memcpy(pIndices, m_pwaIndices[uci], count[uci] * sizeof(WORD)); + m_IndexBuffer[uci].Unlock(); + delete [] m_pwaIndices[uci]; + m_pwaIndices[uci] = NULL; + } +#endif +} + +void CMapOutdoor::ADDLvl1TL(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp) +{ + pIndices[rwCount++] = c_rwCurCount; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; + pIndices[rwCount++] = c_rwCurCount + 2; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + pIndices[rwCount++] = c_rwCurCount + 2; + pIndices[rwCount++] = c_rwCurCount + 1; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + pIndices[rwCount++] = c_rwCurCount + 1; + pIndices[rwCount++] = c_rwCurCount; +} + +void CMapOutdoor::ADDLvl1T(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp) +{ + pIndices[rwCount++] = c_rwCurCount; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; + pIndices[rwCount++] = c_rwCurCount + 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + 2; + pIndices[rwCount++] = c_rwCurCount + 1; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + 1; + pIndices[rwCount++] = c_rwCurCount; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; +} + +void CMapOutdoor::ADDLvl1TR(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp) +{ + pIndices[rwCount++] = c_rwCurCount; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 2; + pIndices[rwCount++] = c_rwCurCount + 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + 2; + pIndices[rwCount++] = c_rwCurCount + 1; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + 1; + pIndices[rwCount++] = c_rwCurCount; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; +} + +void CMapOutdoor::ADDLvl1L(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp) +{ + pIndices[rwCount++] = c_rwCurCount; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; + pIndices[rwCount++] = c_rwCurCount + 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + 2; + pIndices[rwCount++] = c_rwCurCount; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; +} + +void CMapOutdoor::ADDLvl1R(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp) +{ + pIndices[rwCount++] = c_rwCurCount; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 2; + pIndices[rwCount++] = c_rwCurCount + 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + 2; + pIndices[rwCount++] = c_rwCurCount; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; +} + +void CMapOutdoor::ADDLvl1BL(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp) +{ + pIndices[rwCount++] = c_rwCurCount; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 1; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 1; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; + pIndices[rwCount++] = c_rwCurCount + 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + 2; + pIndices[rwCount++] = c_rwCurCount; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; +} + +void CMapOutdoor::ADDLvl1B(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp) +{ + pIndices[rwCount++] = c_rwCurCount; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 1; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 1; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; + pIndices[rwCount++] = c_rwCurCount + 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + 2; + pIndices[rwCount++] = c_rwCurCount; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; +} + +void CMapOutdoor::ADDLvl1BR(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp) +{ + pIndices[rwCount++] = c_rwCurCount; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 1; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 1; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 2; + pIndices[rwCount++] = c_rwCurCount + 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; + + pIndices[rwCount++] = c_rwCurCount + 2; + pIndices[rwCount++] = c_rwCurCount; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1; +} + +void CMapOutdoor::ADDLvl1M(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp) +{ + pIndices[rwCount++] = c_rwCurCount; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2; + pIndices[rwCount++] = c_rwCurCount + 2; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; + pIndices[rwCount++] = c_rwCurCount + 2; +} + +void CMapOutdoor::ADDLvl2TL(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp) +{ + ADDLvl1TL(pIndices, rwCount, c_rwCurCount, c_rucNumLineWarp); + ADDLvl1T(pIndices, rwCount, c_rwCurCount + 2, c_rucNumLineWarp); + ADDLvl1L(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2, c_rucNumLineWarp); + ADDLvl1M(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2 + 2, c_rucNumLineWarp); +} + +void CMapOutdoor::ADDLvl2T(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp) +{ + ADDLvl1T(pIndices, rwCount, c_rwCurCount, c_rucNumLineWarp); + ADDLvl1T(pIndices, rwCount, c_rwCurCount + 2, c_rucNumLineWarp); + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4 + 4; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4 + 4; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 4; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; +} + +void CMapOutdoor::ADDLvl2TR(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp) +{ + ADDLvl1T(pIndices, rwCount, c_rwCurCount, c_rucNumLineWarp); + ADDLvl1TR(pIndices, rwCount, c_rwCurCount + 2, c_rucNumLineWarp); + ADDLvl1M(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2, c_rucNumLineWarp); + ADDLvl1R(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2 + 2, c_rucNumLineWarp); +} + +void CMapOutdoor::ADDLvl2L(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp) +{ + ADDLvl1L(pIndices, rwCount, c_rwCurCount, c_rucNumLineWarp); + ADDLvl1L(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2, c_rucNumLineWarp); + + pIndices[rwCount++] = c_rwCurCount + 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; + pIndices[rwCount++] = c_rwCurCount + 4; + + pIndices[rwCount++] = c_rwCurCount + 4; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4 + 4; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4 + 4; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4 + 2; +} + +void CMapOutdoor::ADDLvl2R(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp) +{ + ADDLvl1R(pIndices, rwCount, c_rwCurCount + 2, c_rucNumLineWarp); + ADDLvl1R(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2 + 2, c_rucNumLineWarp); + + pIndices[rwCount++] = c_rwCurCount + 2; + pIndices[rwCount++] = c_rwCurCount; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; + + pIndices[rwCount++] = c_rwCurCount; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4 + 2; +} + +void CMapOutdoor::ADDLvl2BL(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp) +{ + ADDLvl1L(pIndices, rwCount, c_rwCurCount, c_rucNumLineWarp); + ADDLvl1M(pIndices, rwCount, c_rwCurCount + 2, c_rucNumLineWarp); + ADDLvl1BL(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2, c_rucNumLineWarp); + ADDLvl1B(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2 + 2, c_rucNumLineWarp); +} + +void CMapOutdoor::ADDLvl2B(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp) +{ + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; + pIndices[rwCount++] = c_rwCurCount; + + pIndices[rwCount++] = c_rwCurCount; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; + pIndices[rwCount++] = c_rwCurCount + 4; + + pIndices[rwCount++] = c_rwCurCount + 4; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 4; + + ADDLvl1B(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2, c_rucNumLineWarp); + ADDLvl1B(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2 + 2, c_rucNumLineWarp); +} + +void CMapOutdoor::ADDLvl2BR(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp) +{ + ADDLvl1M(pIndices, rwCount, c_rwCurCount, c_rucNumLineWarp); + ADDLvl1R(pIndices, rwCount, c_rwCurCount + 2, c_rucNumLineWarp); + ADDLvl1B(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2, c_rucNumLineWarp); + ADDLvl1BR(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2 + 2, c_rucNumLineWarp); +} + +void CMapOutdoor::ADDLvl2M(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp) +{ + pIndices[rwCount++] = c_rwCurCount; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4; + pIndices[rwCount++] = c_rwCurCount + 4; + + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4; + pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4 + 4; + pIndices[rwCount++] = c_rwCurCount + 4; +} diff --git a/source/GameLib/MapOutdoorLoad.cpp b/source/GameLib/MapOutdoorLoad.cpp new file mode 100644 index 0000000..825928a --- /dev/null +++ b/source/GameLib/MapOutdoorLoad.cpp @@ -0,0 +1,544 @@ +#include "StdAfx.h" +#include "MapOutdoor.h" +#include "AreaTerrain.h" +#include "AreaLoaderThread.h" +#include "../eterLib/ResourceManager.h" +#include "../EterPack/EterPackManager.h" + +//CAreaLoaderThread CMapOutdoor::ms_AreaLoaderThread; + +bool CMapOutdoor::Load(float x, float y, float z) +{ + Destroy(); + + CEterPackManager& rkPackMgr=CEterPackManager::Instance(); + { + static std::string s_strOldPathName=""; + + // 2004.08.09.myevan.Pack ã.. δ ׳ ϵǴ κ ִ + std::string c_rstrNewPathName=GetName()+"\\cache"; + + s_strOldPathName=c_rstrNewPathName; + } + + std::string strFileName = GetMapDataDirectory() + "\\Setting.txt"; + + if (!LoadSetting(strFileName.c_str())) + TraceError("CMapOutdoor::Load : LoadSetting(%s) Failed", strFileName.c_str()); + +#ifdef WORLD_EDITOR + if (!LoadMonsterAreaInfo()) + TraceError("CMapOutdoor::Load - LoadMonsterAreaInfo ERROR"); +#endif + + CreateTerrainPatchProxyList(); + BuildQuadTree(); + LoadWaterTexture(); + CreateCharacterShadowTexture(); + + m_lOldReadX = -1; + + // TODO: SetRenderingDevice Environment Ʈ Ӽ Ѱ ƽ Ʈ ۵Ѵ. + CSpeedTreeForestDirectX8::Instance().SetRenderingDevice(ms_lpd3dDevice); + + Update(x, y, z); + + __HeightCache_Init(); + + // LOCAL_ENVIRONMENT_DATA + std::string local_envDataName = GetMapDataDirectory() + "\\" + m_settings_envDataName; + if (rkPackMgr.isExist(local_envDataName.c_str())) + { + m_envDataName = local_envDataName; + } + else + { + const std::string& c_rstrEnvironmentRoot = "d:/ymir work/environment/"; + const std::string& c_rstrMapName = GetName(); + m_envDataName = c_rstrEnvironmentRoot + m_settings_envDataName; + + if (0 == m_envDataName.compare(c_rstrEnvironmentRoot)) + { + const std::string& strAppendName = c_rstrMapName.substr(c_rstrMapName.size() - 2, 2); + m_envDataName = c_rstrEnvironmentRoot + strAppendName + ".msenv"; + } + } + // LOCAL_ENVIRONMENT_DATA_END + return true; +} + +std::string& CMapOutdoor::GetEnvironmentDataName() +{ + return m_envDataName; +} + + +bool CMapOutdoor::isTerrainLoaded(WORD wX, WORD wY) +{ + for (DWORD i = 0; i < m_TerrainVector.size(); ++i) + { + CTerrain * pTerrain = m_TerrainVector[i]; + WORD usCoordX, usCoordY; + pTerrain->GetCoordinate(&usCoordX, &usCoordY); + + if (usCoordX == wX && usCoordY == wY) + return true; + } + return false; +} + +bool CMapOutdoor::isAreaLoaded(WORD wX, WORD wY) +{ + for (DWORD i = 0; i < m_AreaVector.size(); ++i) + { + CArea * pArea = m_AreaVector[i]; + WORD usCoordX, usCoordY; + pArea->GetCoordinate(&usCoordX, &usCoordY); + + if (usCoordX == wX && usCoordY == wY) + return true; + } + return false; +} + + +// ǥ (ex. 3x3) ִ Terrain Area͸ +// m_pTerrain m_pArea Ѵ. +void CMapOutdoor::AssignTerrainPtr() +{ + // 忡Ϳ ȭ ѱ ͷ ؾ ϱ + // virtual method ȣ Ѵ. ޼ҵ CMapOutDoor ƹ ൿ + // ʴ´. + OnPreAssignTerrainPtr(); + + short sReferenceCoordMinX, sReferenceCoordMaxX, sReferenceCoordMinY, sReferenceCoordMaxY; + sReferenceCoordMinX = max(m_CurCoordinate.m_sTerrainCoordX - LOAD_SIZE_WIDTH, 0); + sReferenceCoordMaxX = min(m_CurCoordinate.m_sTerrainCoordX + LOAD_SIZE_WIDTH, m_sTerrainCountX - 1); + sReferenceCoordMinY = max(m_CurCoordinate.m_sTerrainCoordY - LOAD_SIZE_WIDTH, 0); + sReferenceCoordMaxY = min(m_CurCoordinate.m_sTerrainCoordY + LOAD_SIZE_WIDTH, m_sTerrainCountY - 1); + + DWORD i; + for (i = 0; i < AROUND_AREA_NUM; ++i) + { + m_pArea[i] = NULL; + m_pTerrain[i] = NULL; + } + + for (i = 0; i < m_TerrainVector.size(); ++i) + { + CTerrain * pTerrain = m_TerrainVector[i]; + WORD usCoordX, usCoordY; + pTerrain->GetCoordinate(&usCoordX, &usCoordY); + + if (usCoordX >= sReferenceCoordMinX && + usCoordX <= sReferenceCoordMaxX && + usCoordY >= sReferenceCoordMinY && + usCoordY <= sReferenceCoordMaxY) + { + m_pTerrain[(usCoordY - m_CurCoordinate.m_sTerrainCoordY + LOAD_SIZE_WIDTH) * 3 + + (usCoordX - m_CurCoordinate.m_sTerrainCoordX + LOAD_SIZE_WIDTH) ] = pTerrain; + } + } + + for (i = 0; i < m_AreaVector.size(); ++i) + { + CArea * pArea = m_AreaVector[i]; + WORD usCoordX, usCoordY; + pArea->GetCoordinate(&usCoordX, &usCoordY); + + if (usCoordX >= sReferenceCoordMinX && + usCoordX <= sReferenceCoordMaxX && + usCoordY >= sReferenceCoordMinY && + usCoordY <= sReferenceCoordMaxY) + { + m_pArea[(usCoordY - m_CurCoordinate.m_sTerrainCoordY + LOAD_SIZE_WIDTH) * 3 + + (usCoordX - m_CurCoordinate.m_sTerrainCoordX + LOAD_SIZE_WIDTH) ] = pArea; + } + } +} + +bool CMapOutdoor::LoadArea(WORD wAreaCoordX, WORD wAreaCoordY, WORD wCellCoordX, WORD wCellCoordY) +{ + if (isAreaLoaded(wAreaCoordX, wAreaCoordY)) + return true; +#ifdef _DEBUG + DWORD dwStartTime = ELTimer_GetMSec(); +#endif + unsigned long ulID = (unsigned long) (wAreaCoordX) * 1000L + (unsigned long) (wAreaCoordY); + char szAreaPathName[64+1]; + _snprintf(szAreaPathName, sizeof(szAreaPathName), "%s\\%06u\\", GetMapDataDirectory().c_str(), ulID); + + CArea * pArea = CArea::New(); + pArea->SetMapOutDoor(this); +#ifdef _DEBUG + Tracef("CMapOutdoor::LoadArea1 %d\n", ELTimer_GetMSec() - dwStartTime); + dwStartTime = ELTimer_GetMSec(); +#endif + + pArea->SetCoordinate(wAreaCoordX, wAreaCoordY); + if ( !pArea->Load(szAreaPathName) ) + TraceError(" CMapOutdoor::LoadArea(%d, %d) LoadShadowMap ERROR", wAreaCoordX, wAreaCoordY); +#ifdef _DEBUG + Tracef("CMapOutdoor::LoadArea2 %d\n", ELTimer_GetMSec() - dwStartTime); + dwStartTime = ELTimer_GetMSec(); +#endif + + m_AreaVector.push_back(pArea); + + pArea->EnablePortal(m_bEnablePortal); +#ifdef _DEBUG + Tracef("CMapOutdoor::LoadArea3 %d\n", ELTimer_GetMSec() - dwStartTime); +#endif + + return true; +} + +bool CMapOutdoor::LoadTerrain(WORD wTerrainCoordX, WORD wTerrainCoordY, WORD wCellCoordX, WORD wCellCoordY) +{ + if (isTerrainLoaded(wTerrainCoordX, wTerrainCoordY)) + return true; + + ////////////////////////////////////////////////////////////////////////// + DWORD dwStartTime = ELTimer_GetMSec(); + + unsigned long ulID = (unsigned long) (wTerrainCoordX) * 1000L + (unsigned long) (wTerrainCoordY); + char filename[256]; + sprintf(filename, "%s\\%06u\\AreaProperty.txt", GetMapDataDirectory().c_str(), ulID); + + CTokenVectorMap stTokenVectorMap; + + if (!LoadMultipleTextData(filename, stTokenVectorMap)) + { + TraceError("CMapOutdoor::LoadTerrain AreaProperty Read Error\n"); + return false; + } + + if (stTokenVectorMap.end() == stTokenVectorMap.find("scripttype")) + { + TraceError("CMapOutdoor::LoadTerrain AreaProperty FileFormat Error 1\n"); + return false; + } + + if (stTokenVectorMap.end() == stTokenVectorMap.find("areaname")) + { + TraceError("CMapOutdoor::LoadTerrain AreaProperty FileFormat Error 2\n"); + return false; + } + + const std::string & c_rstrType = stTokenVectorMap["scripttype"][0]; + const std::string & c_rstrAreaName = stTokenVectorMap["areaname"][0]; + + if (c_rstrType != "AreaProperty") + { + TraceError("CMapOutdoor::LoadTerrain AreaProperty FileFormat Error 3\n"); + return false; + } + + CTerrain * pTerrain = CTerrain::New(); + + pTerrain->Clear(); + pTerrain->SetMapOutDoor(this); + + pTerrain->SetCoordinate(wTerrainCoordX, wTerrainCoordY); + + pTerrain->CopySettingFromGlobalSetting(); + + char szRawHeightFieldname[64+1]; + char szWaterMapName[64+1]; + char szAttrMapName[64+1]; + char szShadowTexName[64+1]; + char szShadowMapName[64+1]; + char szMiniMapTexName[64+1]; + char szSplatName[64+1]; + + _snprintf(szRawHeightFieldname, sizeof(szRawHeightFieldname), "%s\\%06u\\height.raw", GetMapDataDirectory().c_str(), ulID); + _snprintf(szSplatName, sizeof(szSplatName), "%s\\%06u\\tile.raw", GetMapDataDirectory().c_str(), ulID); + _snprintf(szAttrMapName, sizeof(szAttrMapName), "%s\\%06u\\attr.atr", GetMapDataDirectory().c_str(), ulID); + _snprintf(szWaterMapName, sizeof(szWaterMapName), "%s\\%06u\\water.wtr", GetMapDataDirectory().c_str(), ulID); + _snprintf(szShadowTexName, sizeof(szShadowTexName), "%s\\%06u\\shadowmap.dds", GetMapDataDirectory().c_str(), ulID); + _snprintf(szShadowMapName, sizeof(szShadowMapName), "%s\\%06u\\shadowmap.raw", GetMapDataDirectory().c_str(), ulID); + _snprintf(szMiniMapTexName, sizeof(szMiniMapTexName), "%s\\%06u\\minimap.dds", GetMapDataDirectory().c_str(), ulID); + + if(!pTerrain->LoadWaterMap(szWaterMapName)) + TraceError(" CMapOutdoor::LoadTerrain(%d, %d) LoadWaterMap ERROR", wTerrainCoordX, wTerrainCoordY); + + if (!pTerrain->LoadHeightMap(szRawHeightFieldname)) + TraceError(" CMapOutdoor::LoadTerrain(%d, %d) LoadHeightMap ERROR", wTerrainCoordX, wTerrainCoordY); + + if (!pTerrain->LoadAttrMap(szAttrMapName)) + TraceError(" CMapOutdoor::LoadTerrain(%d, %d) LoadAttrMap ERROR", wTerrainCoordX, wTerrainCoordY); + + if (!pTerrain->RAW_LoadTileMap(szSplatName)) + TraceError(" CMapOutdoor::LoadTerrain(%d, %d) RAW_LoadTileMap ERROR", wTerrainCoordX, wTerrainCoordY); + + pTerrain->LoadShadowTexture(szShadowTexName); + + if (!pTerrain->LoadShadowMap(szShadowMapName)) + TraceError(" CMapOutdoor::LoadTerrain(%d, %d) LoadShadowMap ERROR", wTerrainCoordX, wTerrainCoordY); + + pTerrain->LoadMiniMapTexture(szMiniMapTexName); + pTerrain->SetName(c_rstrAreaName.c_str()); + pTerrain->CalculateTerrainPatch(); + + pTerrain->SetReady(); + + Tracef("CMapOutdoor::LoadTerrain %d\n", ELTimer_GetMSec() - dwStartTime); + + m_TerrainVector.push_back(pTerrain); + + return true; +} + +bool CMapOutdoor::LoadSetting(const char * c_szFileName) +{ + NANOBEGIN + CTokenVectorMap stTokenVectorMap; + + if (!LoadMultipleTextData(c_szFileName, stTokenVectorMap)) + { + TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - LoadMultipleTextData", c_szFileName); + return false; + } + + if (stTokenVectorMap.end() == stTokenVectorMap.find("scripttype")) + { + TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - FIND 'scripttype' - FAILED", c_szFileName); + return false; + } + + if (stTokenVectorMap.end() == stTokenVectorMap.find("viewradius")) + { + TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - FIND 'viewradius' - FAILED", c_szFileName); + return false; + } + + if (stTokenVectorMap.end() == stTokenVectorMap.find("cellscale")) + { + TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - FIND 'cellscale' - FAILED", c_szFileName); + return false; + } + + if (stTokenVectorMap.end() == stTokenVectorMap.find("heightscale")) + { + TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - FIND 'heightscale' - FAILED", c_szFileName); + return false; + } + + if (stTokenVectorMap.end() == stTokenVectorMap.find("mapsize")) + { + TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - FIND 'mapsize' - FAILED", c_szFileName); + return false; + } + + if (stTokenVectorMap.end() == stTokenVectorMap.find("textureset")) + { + TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - FIND 'textureset' - FAILED", c_szFileName); + return false; + } + + if (stTokenVectorMap.end() != stTokenVectorMap.find("terrainvisible")) + { + m_bSettingTerrainVisible = (bool) (atoi(stTokenVectorMap["terrainvisible"][0].c_str()) != 0); + } + else + { + m_bSettingTerrainVisible = true; + } + + const std::string & c_rstrType = stTokenVectorMap["scripttype"][0]; + const std::string & c_rstrViewRadius = stTokenVectorMap["viewradius"][0]; + //const std::string & c_rstrCellScale = stTokenVectorMap["cellscale"][0]; + const std::string & c_rstrHeightScale = stTokenVectorMap["heightscale"][0]; + const std::string & c_rstrMapSizeX = stTokenVectorMap["mapsize"][0]; + const std::string & c_rstrMapSizeY = stTokenVectorMap["mapsize"][1]; + + std::string strTextureSet; + TTokenVector & rkVec_strToken = stTokenVectorMap["textureset"]; + if (!rkVec_strToken.empty()) + { + strTextureSet = rkVec_strToken[0]; + } + + if (c_rstrType != "MapSetting") + { + TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - Resourse Type ERROR", c_szFileName); + return false; + } + + m_lViewRadius = atol(c_rstrViewRadius.c_str()); + +#ifdef WORLD_EDITOR + m_lViewRadius <<= 1; +#endif + + if (0L >= m_lViewRadius) + { + TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - VIEWRADIUS IS NOT GREATER THAN 0", c_szFileName); + return false; + } + + m_fHeightScale = atof(c_rstrHeightScale.c_str()); + + SetTerrainCount(atoi(c_rstrMapSizeX.c_str()), atoi(c_rstrMapSizeY.c_str())); + + m_fTerrainTexCoordBase = 1.0f / (float) (CTerrainImpl::PATCH_XSIZE * CTerrainImpl::CELLSCALE); + + if (stTokenVectorMap.end() != stTokenVectorMap.find("baseposition")) + { + const std::string & c_rstrMapBaseX = stTokenVectorMap["baseposition"][0]; + const std::string & c_rstrMapBaseY = stTokenVectorMap["baseposition"][1]; + SetBaseXY((DWORD)atol(c_rstrMapBaseX.c_str()), (DWORD)atol(c_rstrMapBaseY.c_str())); + } + + std::string stTextureSetFileName = strTextureSet; + + // TextureSet ̹ پ Ⱥδ. + if (0 != stTextureSetFileName.find_first_of("textureset", 0)) + stTextureSetFileName = "textureset\\"+strTextureSet; + + if (!m_TextureSet.Load(stTextureSetFileName.c_str(), m_fTerrainTexCoordBase)) + { +#ifdef WORLD_EDITOR + // TextureSet Ǿ ʾƵ + LogBox("TextureSet Ǿ Դϴ.\n ؽ ۾ Ͻñ ٶϴ."); +#else + TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - LOAD TEXTURE SET(%s) ERROR", c_szFileName, stTextureSetFileName.c_str()); + return false; +#endif + } + + CTerrain::SetTextureSet(&m_TextureSet); + + if (stTokenVectorMap.end() != stTokenVectorMap.find("environment")) + { + const CTokenVector & c_rEnvironmentVector = stTokenVectorMap["environment"]; + if (!c_rEnvironmentVector.empty()) + m_settings_envDataName = c_rEnvironmentVector[0]; + else + TraceError("CMapOutdoor::LoadSetting(c_szFileName=%s) - Failed to load environment data\n", c_szFileName); + } + + m_fWaterTexCoordBase = 1.0f / (float)(CTerrainImpl::CELLSCALE * 4); + + D3DXMatrixScaling(&m_matSplatAlpha, + +m_fTerrainTexCoordBase * 2.0f * (float)(CTerrainImpl::PATCH_XSIZE) / (float)(CTerrainImpl::SPLATALPHA_RAW_XSIZE-2), + -m_fTerrainTexCoordBase * 2.0f * (float)(CTerrainImpl::PATCH_YSIZE) / (float)(CTerrainImpl::SPLATALPHA_RAW_XSIZE-2), + 0.0f); + m_matSplatAlpha._41 = m_fTerrainTexCoordBase * 4.6f; + m_matSplatAlpha._42 = m_fTerrainTexCoordBase * 4.6f; + + D3DXMatrixScaling(&m_matStaticShadow, + +m_fTerrainTexCoordBase * ((float) CTerrainImpl::PATCH_XSIZE / static_cast(CTerrainImpl::XSIZE)), + -m_fTerrainTexCoordBase * ((float) CTerrainImpl::PATCH_YSIZE / static_cast(CTerrainImpl::XSIZE)), + 0.0f); + m_matStaticShadow._41 = 0.0f; + m_matStaticShadow._42 = 0.0f; + + D3DXMatrixScaling(&m_matDynamicShadowScale, 1.0f / 2550.0f, -1.0f / 2550.0f, 1.0f); + m_matDynamicShadowScale._41 = 0.5f; + m_matDynamicShadowScale._42 = 0.5f; + + // Transform + D3DXMatrixScaling(&m_matBuildingTransparent, 1.0f / ((float)ms_iWidth), -1.0f / ((float)ms_iHeight), 1.0f); + m_matBuildingTransparent._41 = 0.5f; + m_matBuildingTransparent._42 = 0.5f; + NANOEND + return true; +} + + +bool CMapOutdoor::LoadMonsterAreaInfo() +{ + RemoveAllMonsterAreaInfo(); + + char c_szFileName[256]; + sprintf(c_szFileName, "%s\\regen.txt", GetMapDataDirectory().c_str()); + + LPCVOID pModelData; + CMappedFile File; + + if (!CEterPackManager::Instance().Get(File, c_szFileName, &pModelData)) + { + //TraceError(" CMapOutdoorAccessor::LoadMonsterAreaInfo Load File %s ERROR", c_szFileName); + return false; + } + + CMemoryTextFileLoader textFileLoader; + CTokenVector stTokenVector; + + textFileLoader.Bind(File.Size(), pModelData); + + for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i) + { + if (!textFileLoader.SplitLine(i, &stTokenVector)) + continue; + + stl_lowers(stTokenVector[0]); + + // Start or End + if (0 == stTokenVector[0].compare("m") || 0 == stTokenVector[0].compare("g")) + { + if (stTokenVector.size() < 11) + { + TraceError("CMapOutdoorAccessor::LoadMonsterAreaInfo Get MonsterInfo File Format ERROR! continue...."); + continue; + } + + CMonsterAreaInfo::EMonsterAreaInfoType eMonsterAreaInfoType; + if (0 == stTokenVector[0].compare("m")) + { + eMonsterAreaInfoType = CMonsterAreaInfo::MONSTERAREAINFOTYPE_MONSTER; + } + else if (0 == stTokenVector[0].compare("g")) + { + eMonsterAreaInfoType = CMonsterAreaInfo::MONSTERAREAINFOTYPE_GROUP; + } + else + { + TraceError("CMapOutdoorAccessor::LoadMonsterAreaInfo Get MonsterInfo Data ERROR! continue...."); + continue; + } + + const std::string & c_rstrOriginX = stTokenVector[1].c_str(); + const std::string & c_rstrOriginY = stTokenVector[2].c_str(); + const std::string & c_rstrSizeX = stTokenVector[3].c_str(); + const std::string & c_rstrSizeY = stTokenVector[4].c_str(); + const std::string & c_rstrZ = stTokenVector[5].c_str(); + const std::string & c_rstrDir = stTokenVector[6].c_str(); + const std::string & c_rstrTime = stTokenVector[7].c_str(); + const std::string & c_rstrPercent = stTokenVector[8].c_str(); + const std::string & c_rstrCount = stTokenVector[9].c_str(); + const std::string & c_rstrVID = stTokenVector[10].c_str(); + + long lOriginX, lOriginY, lSizeX, lSizeY, lZ, lTime, lPercent; + CMonsterAreaInfo::EMonsterDir eMonsterDir; + DWORD dwMonsterCount; + DWORD dwMonsterVID; + + lOriginX = atol(c_rstrOriginX.c_str()); + lOriginY = atol(c_rstrOriginY.c_str()); + lSizeX = atol(c_rstrSizeX.c_str()); + lSizeY = atol(c_rstrSizeY.c_str()); + lZ = atol(c_rstrZ.c_str()); + eMonsterDir = (CMonsterAreaInfo::EMonsterDir) atoi(c_rstrDir.c_str()); + lTime = atol(c_rstrTime.c_str()); + lPercent = atol(c_rstrPercent.c_str()); + dwMonsterCount = (DWORD) atoi(c_rstrCount.c_str()); + dwMonsterVID = (DWORD) atoi(c_rstrVID.c_str()); + +// lOriginX -= m_dwBaseX / 100; +// lOriginY -= m_dwBaseY / 100; + + CMonsterAreaInfo * pMonsterAreaInfo = AddMonsterAreaInfo(lOriginX, lOriginY, lSizeX, lSizeY); + pMonsterAreaInfo->SetMonsterAreaInfoType(eMonsterAreaInfoType); + if (CMonsterAreaInfo::MONSTERAREAINFOTYPE_MONSTER == eMonsterAreaInfoType) + pMonsterAreaInfo->SetMonsterVID(dwMonsterVID); + else if (CMonsterAreaInfo::MONSTERAREAINFOTYPE_GROUP == eMonsterAreaInfoType) + pMonsterAreaInfo->SetMonsterGroupID(dwMonsterVID); + pMonsterAreaInfo->SetMonsterCount(dwMonsterCount); + pMonsterAreaInfo->SetMonsterDirection(eMonsterDir); + } + } + + return true; +} diff --git a/source/GameLib/MapOutdoorQuadtree.cpp b/source/GameLib/MapOutdoorQuadtree.cpp new file mode 100644 index 0000000..8c35f0b --- /dev/null +++ b/source/GameLib/MapOutdoorQuadtree.cpp @@ -0,0 +1,168 @@ +#include "StdAfx.h" +#include "MapOutdoor.h" +#include "TerrainQuadtree.h" + +////////////////////////////////////////////////////////////////////////// +// QuadTree +////////////////////////////////////////////////////////////////////////// +void CMapOutdoor::BuildQuadTree() +{ + FreeQuadTree(); + + // m_wPatchCount ConvertPatchSplat Ѵ, ⼭ üũѴ. + if (0 == m_wPatchCount) + { + TraceError("MapOutdoor::BuildQuadTree : m_wPatchCount is zero, you must call ConvertPatchSplat before call this method."); + return; + } + + m_pRootNode = AllocQuadTreeNode(0, 0, m_wPatchCount - 1, m_wPatchCount - 1); + if (!m_pRootNode) + TraceError("CMapOutdoor::BuildQuadTree() RootNode is NULL"); + + if (m_pRootNode->Size > 1) + SubDivideNode(m_pRootNode); +} + +CTerrainQuadtreeNode * CMapOutdoor::AllocQuadTreeNode(long x0, long y0, long x1, long y1) +{ + CTerrainQuadtreeNode * Node; + long xsize, ysize; + + xsize = x1-x0+1; + ysize = y1-y0+1; + if ((xsize == 0) || (ysize == 0)) + return NULL; + + Node = new CTerrainQuadtreeNode; + Node->x0 = x0; + Node->y0 = y0; + Node->x1 = x1; + Node->y1 = y1; + + if (ysize > xsize) + Node->Size = ysize; + else + Node->Size = xsize; + + Node->PatchNum = y0 * m_wPatchCount + x0; + +/* + const float fTerrainMin = -(float) (m_lViewRadius * m_lCellScale); + + minx = fTerrainMin + x0 * c_byPatchSize * m_lCellScale; + maxx = fTerrainMin + (x1 + 1) * c_byPatchSize * m_lCellScale; + miny = fTerrainMin + y0 * c_byPatchSize * m_lCellScale; + maxy = fTerrainMin + (y1 + 1) * c_byPatchSize * m_lCellScale; + minz = 0.0f; + maxz = 0.0f; + + / * Set up 8 vertices that belong to the bounding box * / + Node->center.x = minx + (maxx - minx) * 0.5f; + Node->center.y = miny + (maxy - miny) * 0.5f; + Node->center.z = minz + (maxz - minz) * 0.5f; + + Node->radius = sqrtf( + (maxx-minx)*(maxx-minx)+ + (maxy-miny)*(maxy-miny)+ + (maxz-minz)*(maxz-minz) + )/2.0f; +*/ + + Node->center.x = 0.0f; + Node->center.y = 0.0f; + Node->center.z = 0.0f; + + Node->radius = 0.0f; + + return Node; +} + + +void CMapOutdoor::SubDivideNode(CTerrainQuadtreeNode * Node) +{ + long nw_size; + CTerrainQuadtreeNode * tempnode; + + nw_size = Node->Size / 2; + + Node->NW_Node = AllocQuadTreeNode (Node->x0, Node->y0, Node->x0 + nw_size-1, Node->y0 + nw_size-1); + Node->NE_Node = AllocQuadTreeNode (Node->x0 + nw_size, Node->y0, Node->x1, Node->y0 + nw_size-1); + Node->SW_Node = AllocQuadTreeNode (Node->x0, Node->y0 + nw_size, Node->x0 + nw_size-1, Node->y1); + Node->SE_Node = AllocQuadTreeNode (Node->x0 + nw_size, Node->y0 + nw_size, Node->x1, Node->y1); + + tempnode = (CTerrainQuadtreeNode *) Node->NW_Node; + if ((tempnode != NULL) && (tempnode->Size > 1)) + SubDivideNode (tempnode); + tempnode = (CTerrainQuadtreeNode *) Node->NE_Node; + if ((tempnode != NULL) && (tempnode->Size > 1)) + SubDivideNode (tempnode); + tempnode = (CTerrainQuadtreeNode *) Node->SW_Node; + if ((tempnode != NULL) && (tempnode->Size > 1)) + SubDivideNode (tempnode); + tempnode = (CTerrainQuadtreeNode *) Node->SE_Node; + if ((tempnode != NULL) && (tempnode->Size > 1)) + SubDivideNode (tempnode); +} + +/* +void CMapOutdoor::RecurseDeleteQuadTree(CTerrainQuadtreeNode *Node) +{ + if (Node == NULL) + return; + + if (Node->NW_Node != NULL) + { + RecurseDeleteQuadTree(Node->NW_Node); + Node->NW_Node = NULL; + } + if (Node->NE_Node != NULL) + { + RecurseDeleteQuadTree(Node->NE_Node); + Node->NE_Node = NULL; + } + if (Node->SW_Node != NULL) + { + RecurseDeleteQuadTree(Node->SW_Node); + Node->SW_Node = NULL; + } + if (Node->SE_Node != NULL) + { + RecurseDeleteQuadTree(Node->SE_Node); + Node->SE_Node = NULL; + } + + free(Node); +} +*/ + +void CMapOutdoor::FreeQuadTree() +{ + if (NULL == m_pRootNode) + return; + + if (m_pRootNode->NW_Node) + { + delete m_pRootNode->NW_Node; + m_pRootNode->NW_Node = NULL; + } + if (m_pRootNode->NE_Node) + { + delete m_pRootNode->NE_Node; + m_pRootNode->NE_Node = NULL; + } + if (m_pRootNode->SW_Node) + { + delete m_pRootNode->SW_Node; + m_pRootNode->SW_Node = NULL; + } + if (m_pRootNode->SE_Node) + { + delete m_pRootNode->SE_Node; + m_pRootNode->SE_Node = NULL; + } + + delete m_pRootNode; + m_pRootNode = NULL; +} + diff --git a/source/GameLib/MapOutdoorRender.cpp b/source/GameLib/MapOutdoorRender.cpp new file mode 100644 index 0000000..b13972b --- /dev/null +++ b/source/GameLib/MapOutdoorRender.cpp @@ -0,0 +1,964 @@ +#include "StdAfx.h" +#include "MapOutdoor.h" +#include "TerrainPatch.h" +#include "AreaTerrain.h" +#include "TerrainQuadtree.h" + +#include "../eterlib/Camera.h" +#include "../eterlib/StateManager.h" + + +#define MAX_RENDER_SPALT 150 + +CArea::TCRCWithNumberVector m_dwRenderedCRCWithNumberVector; + +CMapOutdoor::TTerrainNumVector CMapOutdoor::FSortPatchDrawStructWithTerrainNum::m_TerrainNumVector; + +void CMapOutdoor::RenderTerrain() +{ + if (!IsVisiblePart(PART_TERRAIN)) + return; + + if (!m_bSettingTerrainVisible) + return; + + // Inserted by levites + if (!m_pTerrainPatchProxyList) + return; + + CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera(); + if (!pCamera) + return; + + auto vv = ms_matView * ms_matProj; + BuildViewFrustum(vv); + + D3DXVECTOR3 v3Eye = pCamera->GetEye(); + m_fXforDistanceCaculation = -v3Eye.x; + m_fYforDistanceCaculation = -v3Eye.y; + + ////////////////////////////////////////////////////////////////////////// + // Push + m_PatchVector.clear(); + + __RenderTerrain_RecurseRenderQuadTree(m_pRootNode); + + // Ÿ + std::sort(m_PatchVector.begin(),m_PatchVector.end()); + + // ׸ + if (CTerrainPatch::SOFTWARE_TRANSFORM_PATCH_ENABLE) + __RenderTerrain_RenderSoftwareTransformPatch(); + else + __RenderTerrain_RenderHardwareTransformPatch(); +} + +void CMapOutdoor::__RenderTerrain_RecurseRenderQuadTree(CTerrainQuadtreeNode *Node, bool bCullCheckNeed) +{ + if (bCullCheckNeed) + { + switch (__RenderTerrain_RecurseRenderQuadTree_CheckBoundingCircle(Node->center, Node->radius)) + { + case VIEW_ALL: + // all child nodes need not cull check + bCullCheckNeed = false; + break; + case VIEW_PART: + break; + case VIEW_NONE: + // no need to render + return; + } + // if no need cull check more + // -> bCullCheckNeed = false; + } + + if (Node->Size == 1) + { + D3DXVECTOR3 v3Center = Node->center; + float fDistance = fMAX(fabs(v3Center.x + m_fXforDistanceCaculation), fabs(-v3Center.y + m_fYforDistanceCaculation)); + __RenderTerrain_AppendPatch(v3Center, fDistance, Node->PatchNum); + } + else + { + if (Node->NW_Node != NULL) + __RenderTerrain_RecurseRenderQuadTree(Node->NW_Node, bCullCheckNeed); + if (Node->NE_Node != NULL) + __RenderTerrain_RecurseRenderQuadTree(Node->NE_Node, bCullCheckNeed); + if (Node->SW_Node != NULL) + __RenderTerrain_RecurseRenderQuadTree(Node->SW_Node, bCullCheckNeed); + if (Node->SE_Node != NULL) + __RenderTerrain_RecurseRenderQuadTree(Node->SE_Node, bCullCheckNeed); + } +} + +int CMapOutdoor::__RenderTerrain_RecurseRenderQuadTree_CheckBoundingCircle(const D3DXVECTOR3 & c_v3Center, const float & c_fRadius) +{ + const int count = 6; + + D3DXVECTOR3 center = c_v3Center; + center.y = -center.y; + + int i; + + float distance[count]; + for(i = 0; i < count; ++i) + { + distance[i] = D3DXPlaneDotCoord(&m_plane[i], ¢er); + if (distance[i] <= -c_fRadius) + return VIEW_NONE; + } + + for(i = 0; i < count;++i) + { + if (distance[i] <= c_fRadius) + return VIEW_PART; + } + + return VIEW_ALL; +} + +void CMapOutdoor::__RenderTerrain_AppendPatch(const D3DXVECTOR3& c_rv3Center, float fDistance, long lPatchNum) +{ + assert(NULL!=m_pTerrainPatchProxyList && "CMapOutdoor::__RenderTerrain_AppendPatch"); + if (!m_pTerrainPatchProxyList[lPatchNum].isUsed()) + return; + + m_pTerrainPatchProxyList[lPatchNum].SetCenterPosition(c_rv3Center); + m_PatchVector.push_back(std::make_pair(fDistance, lPatchNum)); +} + +void CMapOutdoor::ApplyLight(DWORD dwVersion, const D3DLIGHT8& c_rkLight) +{ + m_kSTPD.m_dwLightVersion=dwVersion; + STATEMANAGER.SetLight(0, &c_rkLight); +} + +// 2004. 2. 17. myevan. κ ̰ ʱȭ Ѵ +void CMapOutdoor::InitializeVisibleParts() +{ + m_dwVisiblePartFlags=0xffffffff; +} + +// 2004. 2. 17. myevan. Ư κ ̰ ϰų ߴ Լ +void CMapOutdoor::SetVisiblePart(int ePart, bool isVisible) +{ + DWORD dwMask=(1< & CMapOutdoor::GetRenderedSplatNum(int * piPatch, int * piSplat, float * pfSplatRatio) +{ + *piPatch = m_iRenderedPatchNum; + *piSplat = m_iRenderedSplatNum; + *pfSplatRatio = m_iRenderedSplatNumSqSum/float(m_iRenderedPatchNum); + + return m_RenderedTextureNumVector; +} + +CArea::TCRCWithNumberVector & CMapOutdoor::GetRenderedGraphicThingInstanceNum(DWORD * pdwGraphicThingInstanceNum, DWORD * pdwCRCNum) +{ + *pdwGraphicThingInstanceNum = m_dwRenderedGraphicThingInstanceNum; + *pdwCRCNum = m_dwRenderedCRCNum; + + return m_dwRenderedCRCWithNumberVector; +} + +void CMapOutdoor::RenderBeforeLensFlare() +{ + m_LensFlare.DrawBeforeFlare(); + + if (!mc_pEnvironmentData) + { + TraceError("CMapOutdoor::RenderBeforeLensFlare mc_pEnvironmentData is NULL"); + return; + } + + m_LensFlare.Compute(mc_pEnvironmentData->DirLights[ENV_DIRLIGHT_BACKGROUND].Direction); +} + +void CMapOutdoor::RenderAfterLensFlare() +{ + m_LensFlare.AdjustBrightness(); + m_LensFlare.DrawFlare(); +} + +void CMapOutdoor::RenderCollision() +{ + for (int i = 0; i < AROUND_AREA_NUM; ++i) + { + CArea * pArea; + if (GetAreaPointer(i, &pArea)) + pArea->RenderCollision(); + } +} + +void CMapOutdoor::RenderScreenFiltering() +{ + m_ScreenFilter.Render(); +} + +void CMapOutdoor::RenderSky() +{ + if (IsVisiblePart(PART_SKY)) + m_SkyBox.Render(); +} + +void CMapOutdoor::RenderCloud() +{ + if (IsVisiblePart(PART_CLOUD)) + m_SkyBox.RenderCloud(); +} + +void CMapOutdoor::RenderTree() +{ + if (IsVisiblePart(PART_TREE)) + CSpeedTreeForestDirectX8::Instance().Render(); +} + +void CMapOutdoor::SetInverseViewAndDynamicShaodwMatrices() +{ + CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera(); + + if (!pCamera) + return; + + m_matViewInverse = pCamera->GetInverseViewMatrix(); + + D3DXVECTOR3 v3Target = pCamera->GetTarget(); + + D3DXVECTOR3 v3LightEye(v3Target.x - 1.732f * 1250.0f, + v3Target.y - 1250.0f, + v3Target.z + 2.0f * 1.732f * 1250.0f); + + const auto vv = D3DXVECTOR3(0.0f, 0.0f, 1.0f); + D3DXMatrixLookAtRH(&m_matLightView, &v3LightEye, &v3Target, &vv); + m_matDynamicShadow = m_matViewInverse * m_matLightView * m_matDynamicShadowScale; +} + +void CMapOutdoor::OnRender() +{ +#ifdef __PERFORMANCE_CHECKER__ + DWORD t1=ELTimer_GetMSec(); + SetInverseViewAndDynamicShaodwMatrices(); + + SetBlendOperation(); + DWORD t2=ELTimer_GetMSec(); + RenderArea(); + DWORD t3=ELTimer_GetMSec(); + if (!m_bEnableTerrainOnlyForHeight) + RenderTerrain(); + DWORD t4=ELTimer_GetMSec(); + RenderTree(); + DWORD t5=ELTimer_GetMSec(); + DWORD tEnd=ELTimer_GetMSec(); + + if (tEnd-t1<7) + return; + + static FILE* fp=fopen("perf_map_render.txt", "w"); + fprintf(fp, "MAP.Total %d (Time %d)\n", tEnd-t1, ELTimer_GetMSec()); + fprintf(fp, "MAP.ENV %d\n", t2-t1); + fprintf(fp, "MAP.OBJ %d\n", t3-t2); + fprintf(fp, "MAP.TRN %d\n", t4-t3); + fprintf(fp, "MAP.TRE %d\n", t5-t4); + +#else + SetInverseViewAndDynamicShaodwMatrices(); + + SetBlendOperation(); + RenderArea(); + RenderTree(); + if (!m_bEnableTerrainOnlyForHeight) + RenderTerrain(); + RenderBlendArea(); +#endif +} + +struct FAreaRenderShadow +{ + void operator () (CGraphicObjectInstance * pInstance) + { + pInstance->RenderShadow(); + pInstance->Hide(); + } +}; + +struct FPCBlockerHide +{ + void operator () (CGraphicObjectInstance * pInstance) + { + pInstance->Hide(); + } +}; + +struct FRenderPCBlocker +{ + void operator () (CGraphicObjectInstance * pInstance) + { + pInstance->Show(); + CGraphicThingInstance* pThingInstance = dynamic_cast (pInstance); + if (pThingInstance != NULL) + { + if (pThingInstance->HaveBlendThing()) + { + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + pThingInstance->BlendRender(); + return; + } + } + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + + pInstance->RenderPCBlocker(); + } +}; + +void CMapOutdoor::RenderEffect() +{ + if (!IsVisiblePart(PART_OBJECT)) + return; + for (int i = 0; i < AROUND_AREA_NUM; ++i) + { + CArea * pArea; + if (GetAreaPointer(i, &pArea)) + { + pArea->RenderEffect(); + } + } +} + +struct CMapOutdoor_LessThingInstancePtrRenderOrder +{ + bool operator() (CGraphicThingInstance* pkLeft, CGraphicThingInstance* pkRight) + { + //TODO : Cameraġ + CCamera * pCurrentCamera = CCameraManager::Instance().GetCurrentCamera(); + const D3DXVECTOR3 & c_rv3CameraPos = pCurrentCamera->GetEye(); + const D3DXVECTOR3 & c_v3LeftPos = pkLeft->GetPosition(); + const D3DXVECTOR3 & c_v3RightPos = pkRight->GetPosition(); + const auto vv = D3DXVECTOR3(c_rv3CameraPos - c_v3RightPos); + const auto vv2 = D3DXVECTOR3(c_rv3CameraPos - c_v3LeftPos); + + return D3DXVec3LengthSq(&vv2) < D3DXVec3LengthSq(&vv); + } +}; + +struct CMapOutdoor_FOpaqueThingInstanceRender +{ + inline void operator () (CGraphicThingInstance * pkThingInst) + { + pkThingInst->Render(); + } +}; +struct CMapOutdoor_FBlendThingInstanceRender +{ + inline void operator () (CGraphicThingInstance * pkThingInst) + { + pkThingInst->BlendRender(); + } +}; + +void CMapOutdoor::RenderArea(bool bRenderAmbience) +{ + if (!IsVisiblePart(PART_OBJECT)) + return; + + m_dwRenderedCRCNum = 0; + m_dwRenderedGraphicThingInstanceNum = 0; + m_dwRenderedCRCWithNumberVector.clear(); + + // NOTE - 20041201.levites. ׸ ߰ + for (int j = 0; j < AROUND_AREA_NUM; ++j) + { + CArea * pArea; + if (GetAreaPointer(j, &pArea)) + { + pArea->RenderDungeon(); + } + } + +#ifndef WORLD_EDITOR + // PCBlocker + std::for_each(m_PCBlockerVector.begin(), m_PCBlockerVector.end(), FPCBlockerHide()); + + // Shadow Receiver + if (m_bDrawShadow && m_bDrawChrShadow) + { + if (mc_pEnvironmentData != NULL) + STATEMANAGER.SetRenderState(D3DRS_FOGCOLOR, 0xFFFFFFFF); + + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); + + // Transform + STATEMANAGER.SaveTransform(D3DTS_TEXTURE1, &m_matDynamicShadow); + STATEMANAGER.SetTexture(1, m_lpCharacterShadowMapTexture); + + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_BORDER); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_BORDER); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_BORDERCOLOR, 0xFFFFFFFF); + + std::for_each(m_ShadowReceiverVector.begin(), m_ShadowReceiverVector.end(), FAreaRenderShadow()); + + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXCOORDINDEX); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSU); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSV); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_BORDERCOLOR); + + STATEMANAGER.RestoreTransform(D3DTS_TEXTURE1); + + if (mc_pEnvironmentData != NULL) + STATEMANAGER.SetRenderState(D3DRS_FOGCOLOR, mc_pEnvironmentData->FogColor); + } +#endif + + STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, TRUE); + + bool m_isDisableSortRendering=false; + + if (m_isDisableSortRendering) + { + for (int i = 0; i < AROUND_AREA_NUM; ++i) + { + CArea * pArea; + if (GetAreaPointer(i, &pArea)) + { + pArea->Render(); + + m_dwRenderedCRCNum += pArea->DEBUG_GetRenderedCRCNum(); + m_dwRenderedGraphicThingInstanceNum += pArea->DEBUG_GetRenderedGrapphicThingInstanceNum(); + + CArea::TCRCWithNumberVector & rCRCWithNumberVector = pArea->DEBUG_GetRenderedCRCWithNumVector(); + + CArea::TCRCWithNumberVector::iterator aIterator = rCRCWithNumberVector.begin(); + while (aIterator != rCRCWithNumberVector.end()) + { + DWORD dwCRC = (*aIterator++).dwCRC; + + CArea::TCRCWithNumberVector::iterator aCRCWithNumberVectorIterator = + std::find_if(m_dwRenderedCRCWithNumberVector.begin(), m_dwRenderedCRCWithNumberVector.end(), CArea::FFindIfCRC(dwCRC)); + + if ( m_dwRenderedCRCWithNumberVector.end() == aCRCWithNumberVectorIterator) + { + CArea::TCRCWithNumber aCRCWithNumber; + aCRCWithNumber.dwCRC = dwCRC; + aCRCWithNumber.dwNumber = 1; + m_dwRenderedCRCWithNumberVector.push_back(aCRCWithNumber); + } + else + { + CArea::TCRCWithNumber & rCRCWithNumber = *aCRCWithNumberVectorIterator; + rCRCWithNumber.dwNumber += 1; + } + } + #ifdef WORLD_EDITOR + if (bRenderAmbience) + pArea->RenderAmbience(); + #endif + } + } + + std::sort(m_dwRenderedCRCWithNumberVector.begin(), m_dwRenderedCRCWithNumberVector.end(), CArea::CRCNumComp()); + } + else + { + static std::vector s_kVct_pkOpaqueThingInstSort; + s_kVct_pkOpaqueThingInstSort.clear(); + + for (int i = 0; i < AROUND_AREA_NUM; ++i) + { + CArea * pArea; + if (GetAreaPointer(i, &pArea)) + { + pArea->CollectRenderingObject(s_kVct_pkOpaqueThingInstSort); +#ifdef WORLD_EDITOR + if (bRenderAmbience) + pArea->RenderAmbience(); +#endif + } + + } + + std::sort(s_kVct_pkOpaqueThingInstSort.begin(), s_kVct_pkOpaqueThingInstSort.end(), CMapOutdoor_LessThingInstancePtrRenderOrder()); + std::for_each(s_kVct_pkOpaqueThingInstSort.begin(), s_kVct_pkOpaqueThingInstSort.end(), CMapOutdoor_FOpaqueThingInstanceRender()); + } + + STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE); + +#ifndef WORLD_EDITOR + // Shadow Receiver + if (m_bDrawShadow && m_bDrawChrShadow) + { + std::for_each(m_ShadowReceiverVector.begin(), m_ShadowReceiverVector.end(), std::mem_fn(&CGraphicObjectInstance::Show)); + } +#endif +} + +void CMapOutdoor::RenderBlendArea() +{ + if (!IsVisiblePart(PART_OBJECT)) + return; + + static std::vector s_kVct_pkBlendThingInstSort; + s_kVct_pkBlendThingInstSort.clear(); + + for (int i = 0; i < AROUND_AREA_NUM; ++i) + { + CArea * pArea; + if (GetAreaPointer(i, &pArea)) + { + pArea->CollectBlendRenderingObject(s_kVct_pkBlendThingInstSort); + } + } + + if (s_kVct_pkBlendThingInstSort.size() != 0) + { + + + //STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + //STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + //STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + //STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + //STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); + //STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); + + //// Transform + //STATEMANAGER.SaveTransform(D3DTS_TEXTURE1, &m_matDynamicShadow); + //STATEMANAGER.SetTexture(1, m_lpCharacterShadowMapTexture); + + //STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); + //STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); + //STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); + //STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + //STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_BORDER); + //STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_BORDER); + //STATEMANAGER.SaveTextureStageState(1, D3DTSS_BORDERCOLOR, 0xFFFFFFFF); + + ////std::for_each(m_ShadowReceiverVector.begin(), m_ShadowReceiverVector.end(), FAreaRenderShadow()); + + //STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXCOORDINDEX); + //STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS); + //STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSU); + //STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSV); + //STATEMANAGER.RestoreTextureStageState(1, D3DTSS_BORDERCOLOR); + + //STATEMANAGER.RestoreTransform(D3DTS_TEXTURE1); + + + std::sort(s_kVct_pkBlendThingInstSort.begin(), s_kVct_pkBlendThingInstSort.end(), CMapOutdoor_LessThingInstancePtrRenderOrder()); + + STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + std::for_each(s_kVct_pkBlendThingInstSort.begin(), s_kVct_pkBlendThingInstSort.end(), CMapOutdoor_FBlendThingInstanceRender()); + + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND); + STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND); + STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE); + } +} +void CMapOutdoor::RenderDungeon() +{ + for (int i = 0; i < AROUND_AREA_NUM; ++i) + { + CArea * pArea; + if (!GetAreaPointer(i, &pArea)) + continue; + pArea->RenderDungeon(); + } +} + +void CMapOutdoor::RenderPCBlocker() +{ +#ifndef WORLD_EDITOR + // PCBlocker + if (m_PCBlockerVector.size() != 0) + { + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); + + STATEMANAGER.SaveTransform(D3DTS_TEXTURE1, &m_matBuildingTransparent); + STATEMANAGER.SetTexture(1, m_BuildingTransparentImageInstance.GetTexturePointer()->GetD3DTexture()); + + std::for_each(m_PCBlockerVector.begin(), m_PCBlockerVector.end(), FRenderPCBlocker()); + + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.RestoreTransform(D3DTS_TEXTURE1); + + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXCOORDINDEX); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSU); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSV); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); + } +#endif +} + +void CMapOutdoor::SelectIndexBuffer(BYTE byLODLevel, WORD * pwPrimitiveCount, D3DPRIMITIVETYPE * pePrimitiveType) +{ +#ifdef WORLD_EDITOR + *pwPrimitiveCount = m_wNumIndices - 2; + *pePrimitiveType = D3DPT_TRIANGLESTRIP; + STATEMANAGER.SetIndices(m_IndexBuffer.GetD3DIndexBuffer(), 0); +#else + if (0 == byLODLevel) + { + *pwPrimitiveCount = m_wNumIndices[byLODLevel] - 2; + *pePrimitiveType = D3DPT_TRIANGLESTRIP; + } + else + { + *pwPrimitiveCount = m_wNumIndices[byLODLevel]/3; + *pePrimitiveType = D3DPT_TRIANGLELIST; + } + STATEMANAGER.SetIndices(m_IndexBuffer[byLODLevel].GetD3DIndexBuffer(), 0); +#endif +} + +void CMapOutdoor::SetPatchDrawVector() +{ + assert(NULL!=m_pTerrainPatchProxyList && "CMapOutdoor::__SetPatchDrawVector"); + + m_PatchDrawStructVector.clear(); + + std::vector >::iterator aDistancePatchVectorIterator; + + TPatchDrawStruct aPatchDrawStruct; + + aDistancePatchVectorIterator = m_PatchVector.begin(); + while(aDistancePatchVectorIterator != m_PatchVector.end()) + { + std::pair adistancePatchPair = *aDistancePatchVectorIterator; + + CTerrainPatchProxy * pTerrainPatchProxy = &m_pTerrainPatchProxyList[adistancePatchPair.second]; + + if (!pTerrainPatchProxy->isUsed()) + { + ++aDistancePatchVectorIterator; + continue; + } + + long lPatchNum = pTerrainPatchProxy->GetPatchNum(); + if (lPatchNum < 0) + { + ++aDistancePatchVectorIterator; + continue; + } + + BYTE byTerrainNum = pTerrainPatchProxy->GetTerrainNum(); + if (0xFF == byTerrainNum) + { + ++aDistancePatchVectorIterator; + continue; + } + + CTerrain * pTerrain; + if (!GetTerrainPointer(byTerrainNum, &pTerrain)) + { + ++aDistancePatchVectorIterator; + continue; + } + + aPatchDrawStruct.fDistance = adistancePatchPair.first; + aPatchDrawStruct.byTerrainNum = byTerrainNum; + aPatchDrawStruct.lPatchNum = lPatchNum; + aPatchDrawStruct.pTerrainPatchProxy = pTerrainPatchProxy; + + m_PatchDrawStructVector.push_back(aPatchDrawStruct); + + ++aDistancePatchVectorIterator; + } + + std::stable_sort(m_PatchDrawStructVector.begin(), m_PatchDrawStructVector.end(), FSortPatchDrawStructWithTerrainNum()); +} + +float CMapOutdoor::__GetNoFogDistance() +{ + return (float)(CTerrainImpl::CELLSCALE * m_lViewRadius) * 0.5f; +} + +float CMapOutdoor::__GetFogDistance() +{ + return (float)(CTerrainImpl::CELLSCALE * m_lViewRadius) * 0.75f; +} + +struct FPatchNumMatch +{ + long m_lPatchNumToCheck; + FPatchNumMatch(long lPatchNum) + { + m_lPatchNumToCheck = lPatchNum; + } + bool operator() (std::pair aPair) + { + return m_lPatchNumToCheck == aPair.first; + } +}; + +void CMapOutdoor::NEW_DrawWireFrame(CTerrainPatchProxy * pTerrainPatchProxy, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType) +{ + DWORD dwFillMode = STATEMANAGER.GetRenderState(D3DRS_FILLMODE); + STATEMANAGER.SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); + + DWORD dwFogEnable = STATEMANAGER.GetRenderState(D3DRS_FOGENABLE); + STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, FALSE); + + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); + + STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); + + STATEMANAGER.SetRenderState(D3DRS_FILLMODE, dwFillMode); + STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, dwFogEnable); + + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); +} + +void CMapOutdoor::DrawWireFrame(long patchnum, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType) +{ + assert(NULL!=m_pTerrainPatchProxyList && "CMapOutdoor::DrawWireFrame"); + + CTerrainPatchProxy * pTerrainPatchProxy= &m_pTerrainPatchProxyList[patchnum]; + + if (!pTerrainPatchProxy->isUsed()) + return; + + long sPatchNum = pTerrainPatchProxy->GetPatchNum(); + if (sPatchNum < 0) + return; + BYTE ucTerrainNum = pTerrainPatchProxy->GetTerrainNum(); + if (0xFF == ucTerrainNum) + return; + + DWORD dwFillMode = STATEMANAGER.GetRenderState(D3DRS_FILLMODE); + STATEMANAGER.SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); + + DWORD dwFogEnable = STATEMANAGER.GetRenderState(D3DRS_FOGENABLE); + STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, FALSE); + + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); + + STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); + + STATEMANAGER.SetRenderState(D3DRS_FILLMODE, dwFillMode); + STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, dwFogEnable); + + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); +} + +// Attr +void CMapOutdoor::RenderMarkedArea() +{ + if (!m_pTerrainPatchProxyList) + return; + + m_matWorldForCommonUse._41 = 0.0f; + m_matWorldForCommonUse._42 = 0.0f; + STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matWorldForCommonUse); + + WORD wPrimitiveCount; + D3DPRIMITIVETYPE eType; + SelectIndexBuffer(0, &wPrimitiveCount, &eType); + + D3DXMATRIX matTexTransform, matTexTransformTemp; + + D3DXMatrixScaling(&matTexTransform, m_fTerrainTexCoordBase * 32.0f, -m_fTerrainTexCoordBase * 32.0f, 0.0f); + D3DXMatrixMultiply(&matTexTransform, &m_matViewInverse, &matTexTransform); + STATEMANAGER.SaveTransform(D3DTS_TEXTURE0, &matTexTransform); + STATEMANAGER.SaveTransform(D3DTS_TEXTURE1, &matTexTransform); + + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + + static long lStartTime = timeGetTime(); + float fTime = float((timeGetTime() - lStartTime)%3000) / 3000.0f; + float fAlpha = fabs(fTime - 0.5f) / 2.0f + 0.1f; + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, D3DXCOLOR(1.0f, 1.0f, 1.0f, fAlpha)); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); + + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_POINT); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_POINT); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_POINT); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); + + STATEMANAGER.SetTexture(0, m_attrImageInstance.GetTexturePointer()->GetD3DTexture()); + + RecurseRenderAttr(m_pRootNode); + + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXCOORDINDEX); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXCOORDINDEX); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_MINFILTER); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_MAGFILTER); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_MIPFILTER); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSU); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSV); + + STATEMANAGER.RestoreTransform(D3DTS_TEXTURE0); + STATEMANAGER.RestoreTransform(D3DTS_TEXTURE1); + + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND); + STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND); +} + +void CMapOutdoor::RecurseRenderAttr(CTerrainQuadtreeNode *Node, bool bCullEnable) +{ + if (bCullEnable) + { + if (__RenderTerrain_RecurseRenderQuadTree_CheckBoundingCircle(Node->center, Node->radius)==VIEW_NONE) + return; + } + + { + if (Node->Size == 1) + { + DrawPatchAttr(Node->PatchNum); + } + else + { + if (Node->NW_Node != NULL) + RecurseRenderAttr(Node->NW_Node, bCullEnable); + if (Node->NE_Node != NULL) + RecurseRenderAttr(Node->NE_Node, bCullEnable); + if (Node->SW_Node != NULL) + RecurseRenderAttr(Node->SW_Node, bCullEnable); + if (Node->SE_Node != NULL) + RecurseRenderAttr(Node->SE_Node, bCullEnable); + } + } +} + +void CMapOutdoor::DrawPatchAttr(long patchnum) +{ + CTerrainPatchProxy * pTerrainPatchProxy = &m_pTerrainPatchProxyList[patchnum]; + if (!pTerrainPatchProxy->isUsed()) + return; + + long sPatchNum = pTerrainPatchProxy->GetPatchNum(); + if (sPatchNum < 0) + return; + + BYTE ucTerrainNum = pTerrainPatchProxy->GetTerrainNum(); + if (0xFF == ucTerrainNum) + return; + + // Deal with this material buffer + CTerrain * pTerrain; + if (!GetTerrainPointer(ucTerrainNum, &pTerrain)) + return; + + if (!pTerrain->IsMarked()) + return; + + WORD wCoordX, wCoordY; + pTerrain->GetCoordinate(&wCoordX, &wCoordY); + + m_matWorldForCommonUse._41 = -(float) (wCoordX * CTerrainImpl::XSIZE * CTerrainImpl::CELLSCALE); + m_matWorldForCommonUse._42 = (float) (wCoordY * CTerrainImpl::YSIZE * CTerrainImpl::CELLSCALE); + + D3DXMATRIX matTexTransform, matTexTransformTemp; + D3DXMatrixMultiply(&matTexTransform, &m_matViewInverse, &m_matWorldForCommonUse); + D3DXMatrixMultiply(&matTexTransform, &matTexTransform, &m_matStaticShadow); + STATEMANAGER.SetTransform(D3DTS_TEXTURE1, &matTexTransform); + + TTerrainSplatPatch & rAttrSplatPatch = pTerrain->GetMarkedSplatPatch(); + STATEMANAGER.SetTexture(1, rAttrSplatPatch.Splats[0].pd3dTexture); + + STATEMANAGER.SetVertexShader(D3DFVF_XYZ | D3DFVF_NORMAL); + STATEMANAGER.SetStreamSource(0, pTerrainPatchProxy->HardwareTransformPatch_GetVertexBufferPtr()->GetD3DVertexBuffer(), m_iPatchTerrainVertexSize); + +#ifdef WORLD_EDITOR + STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, m_iPatchTerrainVertexCount, 0, m_wNumIndices - 2); +#else + STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, m_iPatchTerrainVertexCount, 0, m_wNumIndices[0] - 2); +#endif +} diff --git a/source/GameLib/MapOutdoorRenderHTP.cpp b/source/GameLib/MapOutdoorRenderHTP.cpp new file mode 100644 index 0000000..ffdbd37 --- /dev/null +++ b/source/GameLib/MapOutdoorRenderHTP.cpp @@ -0,0 +1,696 @@ +#include "StdAfx.h" +#include "MapOutdoor.h" + +#include "../eterlib/StateManager.h" + +void CMapOutdoor::__RenderTerrain_RenderHardwareTransformPatch() +{ + DWORD dwFogColor; + float fFogFarDistance; + float fFogNearDistance; + if (mc_pEnvironmentData) + { + dwFogColor=mc_pEnvironmentData->FogColor; + fFogNearDistance=mc_pEnvironmentData->GetFogNearDistance(); + fFogFarDistance=mc_pEnvironmentData->GetFogFarDistance(); + } + else + { + dwFogColor=0xffffffff; + fFogNearDistance=5000.0f; + fFogFarDistance=10000.0f; + } + + ////////////////////////////////////////////////////////////////////////// + // Render State & TextureStageState + + STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); + + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_ALPHAREF, 0x00000000); + STATEMANAGER.SaveRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER); + + STATEMANAGER.SaveRenderState(D3DRS_TEXTUREFACTOR, dwFogColor); + + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); + + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); + +#ifdef WORLD_EDITOR + if (GetAsyncKeyState(VK_CAPITAL)) + { + CSpeedTreeWrapper::ms_bSelfShadowOn = false; + STATEMANAGER.SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_GAUSSIANCUBIC); + STATEMANAGER.SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_GAUSSIANCUBIC); + STATEMANAGER.SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_GAUSSIANCUBIC); + STATEMANAGER.SetTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_GAUSSIANCUBIC); + STATEMANAGER.SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_GAUSSIANCUBIC); + STATEMANAGER.SetTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_GAUSSIANCUBIC); + } + else + { + CSpeedTreeWrapper::ms_bSelfShadowOn = true; + STATEMANAGER.SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + STATEMANAGER.SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + STATEMANAGER.SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); + STATEMANAGER.SetTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + STATEMANAGER.SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + STATEMANAGER.SetTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); + } +#else + CSpeedTreeWrapper::ms_bSelfShadowOn = true; + STATEMANAGER.SetBestFiltering(0); + STATEMANAGER.SetBestFiltering(1); +#endif + + m_matWorldForCommonUse._41 = 0.0f; + m_matWorldForCommonUse._42 = 0.0f; + STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matWorldForCommonUse); + + STATEMANAGER.SaveTransform(D3DTS_TEXTURE0, &m_matWorldForCommonUse); + STATEMANAGER.SaveTransform(D3DTS_TEXTURE1, &m_matWorldForCommonUse); + + // Render State & TextureStageState + ////////////////////////////////////////////////////////////////////////// + + STATEMANAGER.SetVertexShader(D3DFVF_XYZ | D3DFVF_NORMAL); + + m_iRenderedSplatNumSqSum = 0; + m_iRenderedPatchNum = 0; + m_iRenderedSplatNum = 0; + m_RenderedTextureNumVector.clear(); + + std::pair fog_far(fFogFarDistance+1600.0f, 0); + std::pair fog_near(fFogNearDistance-3200.0f, 0); + + std::vector >::iterator far_it = std::upper_bound(m_PatchVector.begin(),m_PatchVector.end(),fog_far); + std::vector >::iterator near_it = std::upper_bound(m_PatchVector.begin(),m_PatchVector.end(),fog_near); + + // NOTE: Word Editor fog far ִָ ü ؽ ׸ ۾ +#ifdef WORLD_EDITOR + near_it = m_PatchVector.begin(); + far_it = m_PatchVector.end(); +#endif + + WORD wPrimitiveCount; + D3DPRIMITIVETYPE ePrimitiveType; + + BYTE byCUrrentLODLevel = 0; + + float fLODLevel1Distance = __GetNoFogDistance(); + float fLODLevel2Distance = __GetFogDistance(); + + SelectIndexBuffer(0, &wPrimitiveCount, &ePrimitiveType); + + DWORD dwFogEnable = STATEMANAGER.GetRenderState(D3DRS_FOGENABLE); + std::vector >::iterator it = m_PatchVector.begin(); + + // NOTE: view ~ fog near fog disabled · ׸ ۾ . +#ifndef WORLD_EDITOR + STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, FALSE); + + for( ; it != near_it; ++it) + { + if (byCUrrentLODLevel == 0 && fLODLevel1Distance <= it->first) + { + byCUrrentLODLevel = 1; + SelectIndexBuffer(1, &wPrimitiveCount, &ePrimitiveType); + } + else if (byCUrrentLODLevel == 1 && fLODLevel2Distance <= it->first) + { + byCUrrentLODLevel = 2; + SelectIndexBuffer(2, &wPrimitiveCount, &ePrimitiveType); + } + + __HardwareTransformPatch_RenderPatchSplat(it->second, wPrimitiveCount, ePrimitiveType); + if (m_iRenderedSplatNum >= m_iSplatLimit) + break; + + if (m_bDrawWireFrame) + DrawWireFrame(it->second, wPrimitiveCount, ePrimitiveType); + } +#endif + + STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, dwFogEnable); + + if (m_iRenderedSplatNum < m_iSplatLimit) + { + for(it = near_it; it != far_it; ++it) + { + if (byCUrrentLODLevel == 0 && fLODLevel1Distance <= it->first) + { + byCUrrentLODLevel = 1; + SelectIndexBuffer(1, &wPrimitiveCount, &ePrimitiveType); + } + else if (byCUrrentLODLevel == 1 && fLODLevel2Distance <= it->first) + { + byCUrrentLODLevel = 2; + SelectIndexBuffer(2, &wPrimitiveCount, &ePrimitiveType); + } + + __HardwareTransformPatch_RenderPatchSplat(it->second, wPrimitiveCount, ePrimitiveType); + + if (m_iRenderedSplatNum >= m_iSplatLimit) + break; + + if (m_bDrawWireFrame) + DrawWireFrame(it->second, wPrimitiveCount, ePrimitiveType); + } + } + + STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, FALSE); + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); + + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, FALSE); + + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, FALSE); + + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + if (m_iRenderedSplatNum < m_iSplatLimit) + { + for(it = far_it; it != m_PatchVector.end(); ++it) + { + if (byCUrrentLODLevel == 0 && fLODLevel1Distance <= it->first) + { + byCUrrentLODLevel = 1; + SelectIndexBuffer(1, &wPrimitiveCount, &ePrimitiveType); + } + else if (byCUrrentLODLevel == 1 && fLODLevel2Distance <= it->first) + { + byCUrrentLODLevel = 2; + SelectIndexBuffer(2, &wPrimitiveCount, &ePrimitiveType); + } + + __HardwareTransformPatch_RenderPatchNone(it->second, wPrimitiveCount, ePrimitiveType); + + if (m_iRenderedSplatNum >= m_iSplatLimit) + break; + + if (m_bDrawWireFrame) + DrawWireFrame(it->second, wPrimitiveCount, ePrimitiveType); + } + } + + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + + STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, dwFogEnable); + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, TRUE); + + std::sort(m_RenderedTextureNumVector.begin(),m_RenderedTextureNumVector.end()); + + ////////////////////////////////////////////////////////////////////////// + // Render State & TextureStageState + + STATEMANAGER.RestoreRenderState(D3DRS_TEXTUREFACTOR); + + STATEMANAGER.RestoreTransform(D3DTS_TEXTURE0); + STATEMANAGER.RestoreTransform(D3DTS_TEXTURE1); + + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXCOORDINDEX); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXCOORDINDEX); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS); + + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHAREF); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHAFUNC); + + // Render State & TextureStageState + ////////////////////////////////////////////////////////////////////////// +} + +void CMapOutdoor::__HardwareTransformPatch_RenderPatchSplat(long patchnum, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType) +{ + assert(NULL!=m_pTerrainPatchProxyList && "__HardwareTransformPatch_RenderPatchSplat"); + CTerrainPatchProxy * pTerrainPatchProxy = &m_pTerrainPatchProxyList[patchnum]; + + if (!pTerrainPatchProxy->isUsed()) + return; + + long sPatchNum = pTerrainPatchProxy->GetPatchNum(); + if (sPatchNum < 0) + return; + + BYTE ucTerrainNum = pTerrainPatchProxy->GetTerrainNum(); + if (0xFF == ucTerrainNum) + return; + + CTerrain * pTerrain; + if (!GetTerrainPointer(ucTerrainNum, &pTerrain)) + return; + + DWORD dwFogColor; + if (mc_pEnvironmentData) + dwFogColor=mc_pEnvironmentData->FogColor; + else + dwFogColor=0xffffffff; + + WORD wCoordX, wCoordY; + pTerrain->GetCoordinate(&wCoordX, &wCoordY); + + TTerrainSplatPatch & rTerrainSplatPatch = pTerrain->GetTerrainSplatPatch(); + + D3DXMATRIX matTexTransform, matSplatAlphaTexTransform, matSplatColorTexTransform; + m_matWorldForCommonUse._41 = -(float) (wCoordX * CTerrainImpl::TERRAIN_XSIZE); + m_matWorldForCommonUse._42 = (float) (wCoordY * CTerrainImpl::TERRAIN_YSIZE); + D3DXMatrixMultiply(&matTexTransform, &m_matViewInverse, &m_matWorldForCommonUse); + D3DXMatrixMultiply(&matSplatAlphaTexTransform, &matTexTransform, &m_matSplatAlpha); + STATEMANAGER.SetTransform(D3DTS_TEXTURE1, &matSplatAlphaTexTransform); + + D3DXMATRIX matTiling; + D3DXMatrixScaling(&matTiling, 1.0f/640.0f, -1.0f/640.0f, 0.0f); + matTiling._41=0.0f; + matTiling._42=0.0f; + + D3DXMatrixMultiply(&matSplatColorTexTransform, &m_matViewInverse, &matTiling); + STATEMANAGER.SetTransform(D3DTS_TEXTURE0, &matSplatColorTexTransform); + + CGraphicVertexBuffer* pkVB=pTerrainPatchProxy->HardwareTransformPatch_GetVertexBufferPtr(); + if (!pkVB) + return; + + STATEMANAGER.SetStreamSource(0, pkVB->GetD3DVertexBuffer(), m_iPatchTerrainVertexSize); + + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); + + int iPrevRenderedSplatNum=m_iRenderedSplatNum; + +#ifdef WORLD_EDITOR + + int nRenderTextureCount = 0; + +// if (!m_bShowEntirePatchTextureCount && !(GetAsyncKeyState(VK_LCONTROL) & 0x8000) ) + if (1) + { + for (DWORD j = 1; j < pTerrain->GetNumTextures(); ++j) + { + TTerainSplat & rSplat = rTerrainSplatPatch.Splats[j]; + + if (!rSplat.Active) + continue; + + if (rTerrainSplatPatch.PatchTileCount[sPatchNum][j] == 0) + continue; + + ++nRenderTextureCount; + } + + DWORD dwTextureFactor = STATEMANAGER.GetRenderState(D3DRS_TEXTUREFACTOR); + + int TextureCountThreshold = 8; + DWORD dwTFactor = 0xFFFFFFFF; + + if (GetAsyncKeyState(VK_LSHIFT) & 0x8000) + { + if (GetAsyncKeyState(VK_1) & 0x8000) + { + TextureCountThreshold = 2; + dwTFactor = 0xFF0000FF; + } + else if (GetAsyncKeyState(VK_2) & 0x8000) + { + TextureCountThreshold = 3; + dwTFactor = 0xFF00FF00; + } + else if (GetAsyncKeyState(VK_3) & 0x8000) + { + TextureCountThreshold = 4; + dwTFactor = 0xFF00FFFF; + } + else if (GetAsyncKeyState(VK_4) & 0x8000) + { + TextureCountThreshold = 5; + dwTFactor = 0xFFFF0000; + } + else if (GetAsyncKeyState(VK_5) & 0x8000) + { + TextureCountThreshold = 6; + dwTFactor = 0xFFFFFF00; + } + else if (GetAsyncKeyState(VK_6) & 0x8000) + { + TextureCountThreshold = 7; + dwTFactor = 0xFFFF00ff; + } + + } + + if (nRenderTextureCount>=TextureCountThreshold) + { + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, dwTFactor); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, dwTextureFactor); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP); + } + else + { + // 0 ؽó + if ( 0 < rTerrainSplatPatch.PatchTileCount[sPatchNum][0] ) + { + DWORD dwTextureFactorFor0Texture = STATEMANAGER.GetRenderState(D3DRS_TEXTUREFACTOR); + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xFF88FF88); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, dwTextureFactorFor0Texture); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP); + } + + for (DWORD j = 1; j < pTerrain->GetNumTextures(); ++j) + { + TTerainSplat & rSplat = rTerrainSplatPatch.Splats[j]; + + if (!rSplat.Active) + continue; + + DWORD dwTextureCount = rTerrainSplatPatch.PatchTileCount[sPatchNum][j]; + if (dwTextureCount == 0) + continue; + + DWORD dwTextureFactorForTextureBalance = 0xFFFFFFFF; + + if (!(GetAsyncKeyState(VK_LSHIFT) & 0x8000)) + { + const TTerrainTexture & rTexture = m_TextureSet.GetTexture(j); + + D3DXMatrixMultiply(&matSplatColorTexTransform, &m_matViewInverse, &rTexture.m_matTransform); + STATEMANAGER.SetTransform(D3DTS_TEXTURE0, &matSplatColorTexTransform); + + STATEMANAGER.SetTexture(0, rTexture.pd3dTexture); + STATEMANAGER.SetTexture(1, rSplat.pd3dTexture); + STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); + } + else + { + if (dwTextureCount < 71) + { + dwTextureFactorForTextureBalance = STATEMANAGER.GetRenderState(D3DRS_TEXTUREFACTOR); + if (dwTextureCount < 51) + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xFFFF0000); + else + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xFF0000FF); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTexture(0, NULL); + } + else + { + const TTerrainTexture & rTexture = m_TextureSet.GetTexture(j); + + D3DXMatrixMultiply(&matSplatColorTexTransform, &m_matViewInverse, &rTexture.m_matTransform); + STATEMANAGER.SetTransform(D3DTS_TEXTURE0, &matSplatColorTexTransform); + + STATEMANAGER.SetTexture(0, rTexture.pd3dTexture); + } + STATEMANAGER.SetTexture(1, rSplat.pd3dTexture); + STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); + if (dwTextureCount < 71) + { + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, dwTextureFactorForTextureBalance); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP); + } + } + + std::vector::iterator aIterator = std::find(m_RenderedTextureNumVector.begin(), m_RenderedTextureNumVector.end(), (int)j); + if (aIterator == m_RenderedTextureNumVector.end()) + m_RenderedTextureNumVector.push_back(j); + ++m_iRenderedSplatNum; + if (m_iRenderedSplatNum >= m_iSplatLimit) + break; + } + } + } + else + { + int TextureCountThreshold = 6; + DWORD dwTFactor = 0xFFFF00FF; + + if (GetAsyncKeyState(VK_LSHIFT) & 0x8000) + { + if (GetAsyncKeyState(VK_1) & 0x8000) + { + TextureCountThreshold = 1; + dwTFactor = 0xFF0000FF; + } + else if (GetAsyncKeyState(VK_2) & 0x8000) + { + TextureCountThreshold = 2; + dwTFactor = 0xFF00FF00; + } + else if (GetAsyncKeyState(VK_3) & 0x8000) + { + TextureCountThreshold = 3; + dwTFactor = 0xFF00FFFF; + } + else if (GetAsyncKeyState(VK_4) & 0x8000) + { + TextureCountThreshold = 4; + dwTFactor = 0xFFFF0000; + } + else if (GetAsyncKeyState(VK_5) & 0x8000) + { + TextureCountThreshold = 5; + dwTFactor = 0xFFFFFF00; + } + } + + for (DWORD j = 1; j < pTerrain->GetNumTextures(); ++j) + { + TTerainSplat & rSplat = rTerrainSplatPatch.Splats[j]; + + if (!rSplat.Active) + continue; + + if (rTerrainSplatPatch.PatchTileCount[sPatchNum][j] == 0) + continue; + + DWORD dwTextureFactor; + + if (nRenderTextureCount>=TextureCountThreshold) + { + dwTextureFactor = STATEMANAGER.GetRenderState(D3DRS_TEXTUREFACTOR); + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, dwTFactor); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTexture(0, NULL); + } + else + { + const TTerrainTexture & rTexture = m_TextureSet.GetTexture(j); + + D3DXMatrixMultiply(&matSplatColorTexTransform, &m_matViewInverse, &rTexture.m_matTransform); + STATEMANAGER.SetTransform(D3DTS_TEXTURE0, &matSplatColorTexTransform); + + STATEMANAGER.SetTexture(0, rTexture.pd3dTexture); + } + STATEMANAGER.SetTexture(1, rSplat.pd3dTexture); + STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); + if (nRenderTextureCount>=TextureCountThreshold) + { + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, dwTextureFactor); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP); + } + + ++nRenderTextureCount; + + std::vector::iterator aIterator = std::find(m_RenderedTextureNumVector.begin(), m_RenderedTextureNumVector.end(), (int)j); + if (aIterator == m_RenderedTextureNumVector.end()) + m_RenderedTextureNumVector.push_back(j); + ++m_iRenderedSplatNum; + if (m_iRenderedSplatNum >= m_iSplatLimit) + break; + + } + } + +#else + bool isFirst=true; + for (DWORD j = 1; j < pTerrain->GetNumTextures(); ++j) + { + TTerainSplat & rSplat = rTerrainSplatPatch.Splats[j]; + + if (!rSplat.Active) + continue; + + if (rTerrainSplatPatch.PatchTileCount[sPatchNum][j] == 0) + continue; + + const TTerrainTexture & rTexture = m_TextureSet.GetTexture(j); + + D3DXMatrixMultiply(&matSplatColorTexTransform, &m_matViewInverse, &rTexture.m_matTransform); + STATEMANAGER.SetTransform(D3DTS_TEXTURE0, &matSplatColorTexTransform); + if (isFirst) + { + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + STATEMANAGER.SetTexture(0, rTexture.pd3dTexture); + STATEMANAGER.SetTexture(1, rSplat.pd3dTexture); + STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + isFirst=false; + } + else + { + STATEMANAGER.SetTexture(0, rTexture.pd3dTexture); + STATEMANAGER.SetTexture(1, rSplat.pd3dTexture); + STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); + } + + std::vector::iterator aIterator = std::find(m_RenderedTextureNumVector.begin(), m_RenderedTextureNumVector.end(), (int)j); + if (aIterator == m_RenderedTextureNumVector.end()) + m_RenderedTextureNumVector.push_back(j); + ++m_iRenderedSplatNum; + if (m_iRenderedSplatNum >= m_iSplatLimit) + break; + + } + +/* + if (GetAsyncKeyState(VK_CAPITAL) & 0x8000) + { + TTerainSplat & rSplat = rTerrainSplatPatch.Splats[200]; + + if (rSplat.Active) + { + const TTerrainTexture & rTexture = m_TextureSet.GetTexture(1); + + D3DXMatrixMultiply(&matSplatColorTexTransform, &m_matViewInverse, &rTexture.m_matTransform); + STATEMANAGER.SetTransform(D3DTS_TEXTURE0, &matSplatColorTexTransform); + + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SetTexture(1, rSplat.pd3dTexture); + STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); + } + } +*/ +#endif + + // ׸ + if (m_bDrawShadow) + { + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, TRUE); + + STATEMANAGER.SetRenderState(D3DRS_FOGCOLOR, 0xFFFFFFFF); + STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); + STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR); + + D3DXMATRIX matShadowTexTransform; + D3DXMatrixMultiply(&matShadowTexTransform, &matTexTransform, &m_matStaticShadow); + + STATEMANAGER.SetTransform(D3DTS_TEXTURE0, &matShadowTexTransform); + STATEMANAGER.SetTexture(0, pTerrain->GetShadowTexture()); + + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); + + if (m_bDrawChrShadow) + { + STATEMANAGER.SetTransform(D3DTS_TEXTURE1, &m_matDynamicShadow); + + STATEMANAGER.SetTexture(1, m_lpCharacterShadowMapTexture); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); + } + else + { + STATEMANAGER.SetTexture(1, NULL); + } + + ms_faceCount += wPrimitiveCount; + STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); + ++m_iRenderedSplatNum; + + if (m_bDrawChrShadow) + { + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + } + + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); + + + STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + STATEMANAGER.SetRenderState(D3DRS_FOGCOLOR, dwFogColor); + + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); + } + ++m_iRenderedPatchNum; + + int iCurRenderedSplatNum=m_iRenderedSplatNum-iPrevRenderedSplatNum; + + m_iRenderedSplatNumSqSum+=iCurRenderedSplatNum*iCurRenderedSplatNum; + +} + +void CMapOutdoor::__HardwareTransformPatch_RenderPatchNone(long patchnum, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType) +{ + assert(NULL!=m_pTerrainPatchProxyList && "__HardwareTransformPatch_RenderPatchNone"); + CTerrainPatchProxy * pTerrainPatchProxy = &m_pTerrainPatchProxyList[patchnum]; + + if (!pTerrainPatchProxy->isUsed()) + return; + + CGraphicVertexBuffer* pkVB=pTerrainPatchProxy->HardwareTransformPatch_GetVertexBufferPtr(); + if (!pkVB) + return; + + STATEMANAGER.SetStreamSource(0, pkVB->GetD3DVertexBuffer(), m_iPatchTerrainVertexSize); + STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); +} diff --git a/source/GameLib/MapOutdoorRenderSTP.cpp b/source/GameLib/MapOutdoorRenderSTP.cpp new file mode 100644 index 0000000..e7ad6b9 --- /dev/null +++ b/source/GameLib/MapOutdoorRenderSTP.cpp @@ -0,0 +1,806 @@ +#include "StdAfx.h" +#include "MapOutdoor.h" +#include "TerrainPatch.h" +#include "TerrainQuadtree.h" + +#include "../eterlib/Camera.h" +#include "../eterlib/StateManager.h" + +struct SoftwareTransformPatch_SSplatVertex +{ + D3DXVECTOR4 kPosition; + DWORD dwDiffuse; + DWORD dwSpecular; + D3DXVECTOR2 kTex1; + D3DXVECTOR2 kTex2; +}; + + + +void CMapOutdoor::__RenderTerrain_RenderSoftwareTransformPatch() +{ + SoftwareTransformPatch_SRenderState kTPRS; + + DWORD dwFogEnable = STATEMANAGER.GetRenderState(D3DRS_FOGENABLE); + + __SoftwareTransformPatch_ApplyRenderState(); + + __SoftwareTransformPatch_BuildPipeline(kTPRS); + + std::pair fog_far(kTPRS.m_fFogFarDistance+800.0f, 0); + std::pair fog_near(kTPRS.m_fFogNearDistance-3200.0f, 0); + + std::vector >::iterator far_it = std::upper_bound(m_PatchVector.begin(),m_PatchVector.end(),fog_far); + std::vector >::iterator near_it = std::upper_bound(m_PatchVector.begin(),m_PatchVector.end(),fog_near); + + WORD wPrimitiveCount; + D3DPRIMITIVETYPE ePrimitiveType; + + BYTE byCUrrentLODLevel = 0; + + float fLODLevel1Distance = __GetNoFogDistance(); + float fLODLevel2Distance = __GetFogDistance(); + + SelectIndexBuffer(0, &wPrimitiveCount, &ePrimitiveType); + + STATEMANAGER.SetVertexShader(D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_SPECULAR|D3DFVF_TEX2); + + std::vector >::iterator it = m_PatchVector.begin(); + + for( ; it != near_it; ++it) + { + if (byCUrrentLODLevel == 0 && fLODLevel1Distance <= it->first) + { + byCUrrentLODLevel = 1; + SelectIndexBuffer(1, &wPrimitiveCount, &ePrimitiveType); + } + else if (byCUrrentLODLevel == 1 && fLODLevel2Distance <= it->first) + { + byCUrrentLODLevel = 2; + SelectIndexBuffer(2, &wPrimitiveCount, &ePrimitiveType); + } + + __SoftwareTransformPatch_RenderPatchSplat(kTPRS, it->second, wPrimitiveCount, ePrimitiveType, false); + if (m_iRenderedSplatNum >= m_iSplatLimit) + break; + + } + + if (m_iRenderedSplatNum < m_iSplatLimit) + { + for(it = near_it; it != far_it; ++it) + { + if (byCUrrentLODLevel == 0 && fLODLevel1Distance <= it->first) + { + byCUrrentLODLevel = 1; + SelectIndexBuffer(1, &wPrimitiveCount, &ePrimitiveType); + } + else if (byCUrrentLODLevel == 1 && fLODLevel2Distance <= it->first) + { + byCUrrentLODLevel = 2; + SelectIndexBuffer(2, &wPrimitiveCount, &ePrimitiveType); + } + + __SoftwareTransformPatch_RenderPatchSplat(kTPRS, it->second, wPrimitiveCount, ePrimitiveType, true); + + if (m_iRenderedSplatNum >= m_iSplatLimit) + break; + + } + } + + + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SetTexture(1, NULL); + + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + STATEMANAGER.SetVertexShader(D3DFVF_XYZRHW); + + if (IsFastTNL()) + { + if (byCUrrentLODLevel != 2) + { + byCUrrentLODLevel = 2; + SelectIndexBuffer(2, &wPrimitiveCount, &ePrimitiveType); + } + + if (m_iRenderedSplatNum < m_iSplatLimit) + { + for(it = far_it; it != m_PatchVector.end(); ++it) + { + __SoftwareTransformPatch_RenderPatchNone(kTPRS, it->second, wPrimitiveCount, ePrimitiveType); + + if (m_iRenderedSplatNum >= m_iSplatLimit) + break; + + } + } + } + + + ////////////////////////////////////////////////////////////////////////// + // Render State & TextureStageState + __SoftwareTransformPatch_RestoreRenderState(dwFogEnable); +} + +void CMapOutdoor::__SoftwareTransformPatch_RenderPatchSplat(SoftwareTransformPatch_SRenderState& rkTPRS, long patchnum, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType, bool isFogEnable) +{ + assert(NULL!=m_pTerrainPatchProxyList && "CMapOutdoor::__SoftwareTransformPatch_RenderPatchSplat"); + + CTerrainPatchProxy * pTerrainPatchProxy = &m_pTerrainPatchProxyList[patchnum]; + + if (!pTerrainPatchProxy->isUsed()) + return; + + bool isDynamicShadow = pTerrainPatchProxy->IsIn(rkTPRS.m_v3Player, 3000.0f); + + if (!m_bDrawChrShadow) + isDynamicShadow = false; + + long sPatchNum = pTerrainPatchProxy->GetPatchNum(); + + if (sPatchNum < 0) + return; + + BYTE ucTerrainNum = pTerrainPatchProxy->GetTerrainNum(); + + if (0xFF == ucTerrainNum) + return; + + CTerrain * pTerrain; + if (!GetTerrainPointer(ucTerrainNum, &pTerrain)) + return; + + WORD wCoordX, wCoordY; + pTerrain->GetCoordinate(&wCoordX, &wCoordY); + + TTerrainSplatPatch & rTerrainSplatPatch = pTerrain->GetTerrainSplatPatch(); + + SoftwareTransformPatch_STLVertex akTransVertex[CTerrainPatch::TERRAIN_VERTEX_COUNT]; + if (!__SoftwareTransformPatch_SetTransform(rkTPRS, akTransVertex, *pTerrainPatchProxy, wCoordX, wCoordY, isFogEnable, isDynamicShadow)) + return; + + if (!__SoftwareTransformPatch_SetSplatStream(akTransVertex)) + return; + + if (isFogEnable) + { + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_BLENDDIFFUSEALPHA); + } + else + { + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + } + + int iPrevRenderedSplatNum=m_iRenderedSplatNum; + + bool isFirst=true; + for (DWORD j = 1; j < pTerrain->GetNumTextures(); ++j) + { + TTerainSplat & rSplat = rTerrainSplatPatch.Splats[j]; + + if (!rSplat.Active) + continue; + + if (rTerrainSplatPatch.PatchTileCount[sPatchNum][j] == 0) + continue; + + const TTerrainTexture & rTexture = m_TextureSet.GetTexture(j); + + if (isFirst) + { + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); + STATEMANAGER.SetTexture(0, rTexture.pd3dTexture); + STATEMANAGER.SetTexture(1, rSplat.pd3dTexture); + STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + isFirst=false; + } + else + { + STATEMANAGER.SetTexture(0, rTexture.pd3dTexture); + STATEMANAGER.SetTexture(1, rSplat.pd3dTexture); + STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); + } + + std::vector::iterator aIterator = std::find(m_RenderedTextureNumVector.begin(), m_RenderedTextureNumVector.end(), (int)j); + if (aIterator == m_RenderedTextureNumVector.end()) + m_RenderedTextureNumVector.push_back(j); + ++m_iRenderedSplatNum; + if (m_iRenderedSplatNum >= m_iSplatLimit) + break; + } + + // ׸ + if (m_bDrawShadow) + { + __SoftwareTransformPatch_SetShadowStream(akTransVertex); + __SoftwareTransformPatch_ApplyStaticShadowRenderState(); + + if (isDynamicShadow) + __SoftwareTransformPatch_ApplyDynamicShadowRenderState(); + else + __SoftwareTransformPatch_ApplyFogShadowRenderState(); + + if (isFogEnable) + { + STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, TRUE); + STATEMANAGER.SetRenderState(D3DRS_FOGCOLOR, 0xFFFFFFFF); + STATEMANAGER.SetTexture(0, pTerrain->GetShadowTexture()); + STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); + STATEMANAGER.SetRenderState(D3DRS_FOGCOLOR, rkTPRS.m_dwFogColor); + STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, FALSE); + } + else + { + STATEMANAGER.SetTexture(0, pTerrain->GetShadowTexture()); + STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); + } + + if (isDynamicShadow) + __SoftwareTransformPatch_RestoreDynamicShadowRenderState(); + else + __SoftwareTransformPatch_RestoreFogShadowRenderState(); + + ms_faceCount += wPrimitiveCount; + ++m_iRenderedSplatNum; + + + + __SoftwareTransformPatch_RestoreStaticShadowRenderState(); + } + + ++m_iRenderedPatchNum; + + int iCurRenderedSplatNum=m_iRenderedSplatNum-iPrevRenderedSplatNum; + + m_iRenderedSplatNumSqSum+=iCurRenderedSplatNum*iCurRenderedSplatNum; +} + +void CMapOutdoor::__SoftwareTransformPatch_RenderPatchNone(SoftwareTransformPatch_SRenderState& rkTPRS, long patchnum, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType) +{ + assert(NULL!=m_pTerrainPatchProxyList && "CMapOutdoor::__SoftwareTransformPatch_RenderPatchNone"); + + CTerrainPatchProxy * pTerrainPatchProxy = &m_pTerrainPatchProxyList[patchnum]; + + if (!pTerrainPatchProxy->isUsed()) + return; + + long sPatchNum = pTerrainPatchProxy->GetPatchNum(); + if (sPatchNum < 0) + return; + + BYTE ucTerrainNum = pTerrainPatchProxy->GetTerrainNum(); + if (0xFF == ucTerrainNum) + return; + + CTerrain * pTerrain; + if (!GetTerrainPointer(ucTerrainNum, &pTerrain)) + return; + + WORD wCoordX, wCoordY; + pTerrain->GetCoordinate(&wCoordX, &wCoordY); + + SoftwareTransformPatch_SSourceVertex* akSrcVertex=pTerrainPatchProxy->SoftwareTransformPatch_GetTerrainVertexDataPtr(); + if (!akSrcVertex) + return; + + float fScreenHalfWidth=rkTPRS.m_fScreenHalfWidth; + float fScreenHalfHeight=rkTPRS.m_fScreenHalfHeight; + + D3DXMATRIX m4Frustum=rkTPRS.m_m4Frustum; + + SoftwareTransformPatch_STVertex akTransVertex[CTerrainPatch::TERRAIN_VERTEX_COUNT]; + + D3DXVECTOR4* akPosition=(D3DXVECTOR4*)akTransVertex; + D3DXVECTOR4* pkPosition; + for (UINT uIndex=0; uIndex!=CTerrainPatch::TERRAIN_VERTEX_COUNT; ++uIndex) + { + pkPosition=akPosition+uIndex; + D3DXVec3Transform(pkPosition, &akSrcVertex[uIndex].kPosition, &m4Frustum); + pkPosition->w=1.0f/pkPosition->w; + pkPosition->z*=pkPosition->w; + pkPosition->y=(pkPosition->y*pkPosition->w-1.0f)*fScreenHalfHeight; + pkPosition->x=(pkPosition->x*pkPosition->w+1.0f)*fScreenHalfWidth; + } + + + IDirect3DVertexBuffer8* pkVB=m_kSTPD.m_pkVBNone[m_kSTPD.m_dwNonePos++]; + m_kSTPD.m_dwNonePos%=SoftwareTransformPatch_SData::NONE_VB_NUM; + if (!pkVB) + return; + + DWORD dwVBSize=sizeof(SoftwareTransformPatch_STVertex)*CTerrainPatch::TERRAIN_VERTEX_COUNT; + SoftwareTransformPatch_STVertex* akDstVertex; + if (FAILED( + pkVB->Lock(0, dwVBSize, (BYTE**)&akDstVertex, D3DLOCK_DISCARD) + )) return; + + memcpy(akDstVertex, akTransVertex, dwVBSize); + + pkVB->Unlock(); + + STATEMANAGER.SetStreamSource(0, pkVB, sizeof(SoftwareTransformPatch_STVertex)); + STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); + ms_faceCount += wPrimitiveCount; +} + +void CMapOutdoor::__SoftwareTransformPatch_ApplyStaticShadowRenderState() +{ + STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); + STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR); + + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); + +} + +void CMapOutdoor::__SoftwareTransformPatch_ApplyDynamicShadowRenderState() +{ + STATEMANAGER.SetTexture(1, m_lpCharacterShadowMapTexture); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + + STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); +} + +void CMapOutdoor::__SoftwareTransformPatch_ApplyFogShadowRenderState() +{ + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); +} +void CMapOutdoor::__SoftwareTransformPatch_RestoreStaticShadowRenderState() +{ + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); + + STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); +} + + + +void CMapOutdoor::__SoftwareTransformPatch_RestoreDynamicShadowRenderState() +{ + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + + STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); +} + + + +void CMapOutdoor::__SoftwareTransformPatch_RestoreFogShadowRenderState() +{ + STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, FALSE); + + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); +} + +void CMapOutdoor::__SoftwareTransformPatch_ApplyRenderState() +{ + DWORD dwFogColor=0xffffffff; + if (mc_pEnvironmentData) + dwFogColor=mc_pEnvironmentData->FogColor; + + BOOL isSoftwareVertexClipping=FALSE; + if (!IsTLVertexClipping()) + isSoftwareVertexClipping=TRUE; + + STATEMANAGER.SaveRenderState(D3DRS_SOFTWAREVERTEXPROCESSING, isSoftwareVertexClipping); + + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_ALPHAREF, 0x00000000); + STATEMANAGER.SaveRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER); + + STATEMANAGER.SaveRenderState(D3DRS_TEXTUREFACTOR, dwFogColor); + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); + STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, FALSE); + + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); + STATEMANAGER.SetBestFiltering(0); + + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); + STATEMANAGER.SetBestFiltering(1); + + CSpeedTreeWrapper::ms_bSelfShadowOn = true; + + // Render State & TextureStageState + ////////////////////////////////////////////////////////////////////////// + + m_iRenderedSplatNumSqSum = 0; + m_iRenderedPatchNum = 0; + m_iRenderedSplatNum = 0; + m_RenderedTextureNumVector.clear(); + + m_matWorldForCommonUse._41 = 0.0f; + m_matWorldForCommonUse._42 = 0.0f; + STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matWorldForCommonUse); +} + +void CMapOutdoor::__SoftwareTransformPatch_RestoreRenderState(DWORD dwFogEnable) +{ + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, TRUE); + + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + + STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, dwFogEnable); + + std::sort(m_RenderedTextureNumVector.begin(),m_RenderedTextureNumVector.end()); + + STATEMANAGER.RestoreRenderState(D3DRS_TEXTUREFACTOR); + + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHAREF); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHAFUNC); + + STATEMANAGER.RestoreRenderState(D3DRS_SOFTWAREVERTEXPROCESSING); + + // Render State & TextureStageState + ////////////////////////////////////////////////////////////////////////// +} + +void CMapOutdoor::__SoftwareTransformPatch_BuildPipeline(SoftwareTransformPatch_SRenderState& rkTPRS) +{ + memset(&rkTPRS, 0, sizeof(rkTPRS)); + + if (mc_pEnvironmentData) + { + rkTPRS.m_dwFogColor = mc_pEnvironmentData->FogColor; + rkTPRS.m_fFogNearDistance = mc_pEnvironmentData->GetFogNearDistance(); + rkTPRS.m_fFogFarDistance = mc_pEnvironmentData->GetFogFarDistance(); + } + else + { + rkTPRS.m_dwFogColor = 0xffffffff; + rkTPRS.m_fFogNearDistance = 5000.0f; + rkTPRS.m_fFogFarDistance = 10000.0f; + } + + UINT uScreenWidth; + UINT uScreenHeight; + CScreen::GetBackBufferSize(&uScreenWidth, &uScreenHeight); + + rkTPRS.m_fScreenHalfWidth = +float(uScreenWidth) / 2.0f; + rkTPRS.m_fScreenHalfHeight = -float(uScreenHeight) / 2.0f; + + STATEMANAGER.GetLight(0, &rkTPRS.m_kLight); + STATEMANAGER.GetMaterial(&rkTPRS.m_kMtrl); + + D3DXMATRIX m4View;STATEMANAGER.GetTransform(D3DTS_VIEW, &m4View); + D3DXMATRIX m4Proj;STATEMANAGER.GetTransform(D3DTS_PROJECTION, &m4Proj); + + D3DXMatrixMultiply(&rkTPRS.m_m4Frustum, &m4View, &m4Proj); + + rkTPRS.m_v3Player.x = +m_v3Player.x; + rkTPRS.m_v3Player.y = -m_v3Player.y; + rkTPRS.m_v3Player.z = +m_v3Player.z; + + rkTPRS.m_m4Proj = m4Proj; + rkTPRS.m_m4DynamicShadow = m_matLightView * m_matDynamicShadowScale; + + D3DXVECTOR3 kFogNearVector; + const auto farvv = D3DXVECTOR3(0.0f, 0.0f, -rkTPRS.m_fFogNearDistance); + D3DXVec3TransformCoord(&kFogNearVector, &farvv, &rkTPRS.m_m4Proj); + + D3DXVECTOR3 kFogFarVector; + const auto nearvv = D3DXVECTOR3(0.0f, 0.0f, -rkTPRS.m_fFogFarDistance); + D3DXVec3TransformCoord(&kFogFarVector, &nearvv, &rkTPRS.m_m4Proj); + + float fFogNear = kFogNearVector.z; + float fFogFar = kFogFarVector.z; + float fFogLenInv = 1.0f / (fFogFar-fFogNear); + + rkTPRS.m_fFogNearTransZ = fFogNear; + rkTPRS.m_fFogFarTransZ = fFogFar; + rkTPRS.m_fFogLenInv = fFogLenInv; + +} + +bool CMapOutdoor::__SoftwareTransformPatch_SetTransform(SoftwareTransformPatch_SRenderState& rkTPRS, SoftwareTransformPatch_STLVertex* akTransVertex, CTerrainPatchProxy& rkTerrainPatchProxy, UINT uTerrainX, UINT uTerrainY, bool isFogEnable, bool isDynamicShadow) +{ + SoftwareTransformPatch_SSourceVertex* akSrcVertex=rkTerrainPatchProxy.SoftwareTransformPatch_GetTerrainVertexDataPtr(); + if (!akSrcVertex) + return false; + + rkTerrainPatchProxy.SoftwareTransformPatch_UpdateTerrainLighting( + m_kSTPD.m_dwLightVersion, + rkTPRS.m_kLight, rkTPRS.m_kMtrl); + + D3DXVECTOR3* pkSrcPosition; + + float fTilePatternX=+1/640.0f; + float fTilePatternY=-1/640.0f; + + float fTerrainBaseX=-(float) (uTerrainX * CTerrainImpl::TERRAIN_XSIZE)+m_fTerrainTexCoordBase * 12.30769f; + float fTerrainBaseY=+(float) (uTerrainY * CTerrainImpl::TERRAIN_YSIZE)+m_fTerrainTexCoordBase * 12.30769f; + + float fScreenHalfWidth=rkTPRS.m_fScreenHalfWidth; + float fScreenHalfHeight=rkTPRS.m_fScreenHalfHeight; + + float fAlphaPatternX=m_matSplatAlpha._11; + float fAlphaPatternY=m_matSplatAlpha._22; + float fAlphaBiasX=m_matSplatAlpha._41; + float fAlphaBiasY=m_matSplatAlpha._42; + float fShadowPatternX=+m_fTerrainTexCoordBase * ((float) CTerrainImpl::PATCH_XSIZE / static_cast(CTerrainImpl::XSIZE)); + float fShadowPatternY=-m_fTerrainTexCoordBase * ((float) CTerrainImpl::PATCH_YSIZE / static_cast(CTerrainImpl::YSIZE)); + + D3DXMATRIX m4Frustum=rkTPRS.m_m4Frustum; + + if (isFogEnable) + { + float fFogCur; + float fFogFar=rkTPRS.m_fFogFarTransZ; + float fFogLenInv=rkTPRS.m_fFogLenInv; + + float fLocalX; + float fLocalY; + + SoftwareTransformPatch_STLVertex kWorkVertex; + for (UINT uIndex=0; uIndex!=CTerrainPatch::TERRAIN_VERTEX_COUNT; ++uIndex) + { + pkSrcPosition=&akSrcVertex[uIndex].kPosition; + D3DXVec3Transform(&kWorkVertex.kPosition, pkSrcPosition, &m4Frustum); + fLocalX=pkSrcPosition->x+fTerrainBaseX; + fLocalY=pkSrcPosition->y+fTerrainBaseY; + kWorkVertex.kPosition.w=1.0f/kWorkVertex.kPosition.w; + kWorkVertex.kPosition.x*=kWorkVertex.kPosition.w; + kWorkVertex.kPosition.y*=kWorkVertex.kPosition.w; + kWorkVertex.kPosition.z*=kWorkVertex.kPosition.w; + kWorkVertex.kPosition.x=(kWorkVertex.kPosition.x+1.0f)*fScreenHalfWidth; + kWorkVertex.kPosition.y=(kWorkVertex.kPosition.y-1.0f)*fScreenHalfHeight; + kWorkVertex.dwDiffuse=akSrcVertex[uIndex].dwDiffuse; + kWorkVertex.kTexTile.x=pkSrcPosition->x*fTilePatternX; + kWorkVertex.kTexTile.y=pkSrcPosition->y*fTilePatternY; + kWorkVertex.kTexAlpha.x=fLocalX*fAlphaPatternX+fAlphaBiasX; + kWorkVertex.kTexAlpha.y=fLocalY*fAlphaPatternY+fAlphaBiasY; + kWorkVertex.kTexStaticShadow.x=fLocalX*fShadowPatternX; + kWorkVertex.kTexStaticShadow.y=fLocalY*fShadowPatternY; + kWorkVertex.kTexDynamicShadow.x=0.0f; + kWorkVertex.kTexDynamicShadow.y=0.0f; + + fFogCur=(fFogFar-kWorkVertex.kPosition.z)*fFogLenInv; + if (fFogCur<0.0f) + kWorkVertex.dwFog=kWorkVertex.dwDiffuse=0x0000000|(kWorkVertex.dwDiffuse&0xffffff); + else if (fFogCur>1.0f) + kWorkVertex.dwFog=kWorkVertex.dwDiffuse=0xFF000000|(kWorkVertex.dwDiffuse&0xffffff); + else + kWorkVertex.dwFog=kWorkVertex.dwDiffuse=BYTE(255.0f*fFogCur)<<24|(kWorkVertex.dwDiffuse&0xffffff); + + *(akTransVertex+uIndex)=kWorkVertex; + } + } + else + { + float fLocalX; + float fLocalY; + + SoftwareTransformPatch_STLVertex kWorkVertex; + for (UINT uIndex=0; uIndex!=CTerrainPatch::TERRAIN_VERTEX_COUNT; ++uIndex) + { + pkSrcPosition=&akSrcVertex[uIndex].kPosition; + D3DXVec3Transform(&kWorkVertex.kPosition, pkSrcPosition, &m4Frustum); + fLocalX=pkSrcPosition->x+fTerrainBaseX; + fLocalY=pkSrcPosition->y+fTerrainBaseY; + kWorkVertex.kPosition.w=1.0f/kWorkVertex.kPosition.w; + kWorkVertex.kPosition.x*=kWorkVertex.kPosition.w; + kWorkVertex.kPosition.y*=kWorkVertex.kPosition.w; + kWorkVertex.kPosition.z*=kWorkVertex.kPosition.w; + kWorkVertex.kPosition.x=(kWorkVertex.kPosition.x+1.0f)*fScreenHalfWidth; + kWorkVertex.kPosition.y=(kWorkVertex.kPosition.y-1.0f)*fScreenHalfHeight; + kWorkVertex.dwDiffuse=akSrcVertex[uIndex].dwDiffuse; + kWorkVertex.dwFog=0xffffffff; + kWorkVertex.kTexTile.x=pkSrcPosition->x*fTilePatternX; + kWorkVertex.kTexTile.y=pkSrcPosition->y*fTilePatternY; + kWorkVertex.kTexAlpha.x=fLocalX*fAlphaPatternX+fAlphaBiasX; + kWorkVertex.kTexAlpha.y=fLocalY*fAlphaPatternY+fAlphaBiasY; + kWorkVertex.kTexStaticShadow.x=fLocalX*fShadowPatternX; + kWorkVertex.kTexStaticShadow.y=fLocalY*fShadowPatternY; + kWorkVertex.kTexDynamicShadow.x=0.0f; + kWorkVertex.kTexDynamicShadow.y=0.0f; + + *(akTransVertex+uIndex)=kWorkVertex; + } + } + + if (isDynamicShadow) + { + D3DXMATRIX m4DynamicShadow=rkTPRS.m_m4DynamicShadow; + + D3DXVECTOR3 v3Shadow; + for (UINT uIndex=0; uIndex!=CTerrainPatch::TERRAIN_VERTEX_COUNT; ++uIndex) + { + D3DXVec3TransformCoord(&v3Shadow, &akSrcVertex[uIndex].kPosition, &m4DynamicShadow); + akTransVertex[uIndex].kTexDynamicShadow.x=v3Shadow.x; + akTransVertex[uIndex].kTexDynamicShadow.y=v3Shadow.y; + } + } + + return true; +} + +bool CMapOutdoor::__SoftwareTransformPatch_SetSplatStream(SoftwareTransformPatch_STLVertex* akSrcVertex) +{ + IDirect3DVertexBuffer8* pkVB=m_kSTPD.m_pkVBSplat[m_kSTPD.m_dwSplatPos++]; + m_kSTPD.m_dwSplatPos%=SoftwareTransformPatch_SData::SPLAT_VB_NUM; + if (!pkVB) + return false; + + DWORD dwVBSize=sizeof(SoftwareTransformPatch_SSplatVertex)*CTerrainPatch::TERRAIN_VERTEX_COUNT; + SoftwareTransformPatch_SSplatVertex* akDstVertex; + if (FAILED( + pkVB->Lock(0, dwVBSize, (BYTE**)&akDstVertex, 0)//D3DLOCK_DISCARD) + )) return false; + + for (UINT uIndex=0; uIndex!=CTerrainPatch::TERRAIN_VERTEX_COUNT; ++uIndex) + *(akDstVertex+uIndex)=*((SoftwareTransformPatch_SSplatVertex*)(akSrcVertex+uIndex)); + + pkVB->Unlock(); + + STATEMANAGER.SetStreamSource(0, pkVB, sizeof(SoftwareTransformPatch_SSplatVertex)); + return true; +} + +bool CMapOutdoor::__SoftwareTransformPatch_SetShadowStream(SoftwareTransformPatch_STLVertex* akSrcVertex) +{ + IDirect3DVertexBuffer8* pkVB=m_kSTPD.m_pkVBSplat[m_kSTPD.m_dwSplatPos++]; + m_kSTPD.m_dwSplatPos%=SoftwareTransformPatch_SData::SPLAT_VB_NUM; + if (!pkVB) + return false; + + DWORD dwVBSize=sizeof(SoftwareTransformPatch_SSplatVertex)*CTerrainPatch::TERRAIN_VERTEX_COUNT; + SoftwareTransformPatch_SSplatVertex* akDstVertex; + if (FAILED( + pkVB->Lock(0, dwVBSize, (BYTE**)&akDstVertex, 0)//D3DLOCK_DISCARD) + )) return false; + + SoftwareTransformPatch_STLVertex* pkSrcVertex; + SoftwareTransformPatch_SSplatVertex* pkDstVertex; + for (UINT uIndex=0; uIndex!=CTerrainPatch::TERRAIN_VERTEX_COUNT; ++uIndex) + { + pkSrcVertex=akSrcVertex+uIndex; + pkDstVertex=akDstVertex+uIndex; + pkDstVertex->kPosition=pkSrcVertex->kPosition; + pkDstVertex->dwDiffuse=pkSrcVertex->dwDiffuse; + pkDstVertex->dwSpecular=pkSrcVertex->dwFog; + pkDstVertex->kTex1=pkSrcVertex->kTexStaticShadow; + pkDstVertex->kTex2=pkSrcVertex->kTexDynamicShadow; + } + pkVB->Unlock(); + + + ms_lpd3dDevice->SetStreamSource(0, pkVB, sizeof(SoftwareTransformPatch_SSplatVertex)); + return true; +} + +void CMapOutdoor::__SoftwareTransformPatch_Initialize() +{ + { + for (UINT uIndex=0; uIndex!=SoftwareTransformPatch_SData::SPLAT_VB_NUM; ++uIndex) + m_kSTPD.m_pkVBSplat[uIndex]=NULL; + m_kSTPD.m_dwSplatPos=0; + } + + { + for (UINT uIndex=0; uIndex!=SoftwareTransformPatch_SData::NONE_VB_NUM; ++uIndex) + m_kSTPD.m_pkVBNone[uIndex]=NULL; + m_kSTPD.m_dwNonePos=0; + } +} + + +bool CMapOutdoor::__SoftwareTransformPatch_Create() +{ + { + for (UINT uIndex=0; uIndex!=SoftwareTransformPatch_SData::SPLAT_VB_NUM; ++uIndex) + { + assert(NULL==m_kSTPD.m_pkVBSplat[uIndex]); + if (FAILED( + ms_lpd3dDevice->CreateVertexBuffer( + sizeof(SoftwareTransformPatch_SSplatVertex)*CTerrainPatch::TERRAIN_VERTEX_COUNT, + D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY, + D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_SPECULAR|D3DFVF_TEX2, + D3DPOOL_SYSTEMMEM, + &m_kSTPD.m_pkVBSplat[uIndex] + ) + )) return false; + } + } + + { + for (UINT uIndex=0; uIndex!=SoftwareTransformPatch_SData::NONE_VB_NUM; ++uIndex) + { + assert(NULL==m_kSTPD.m_pkVBNone[uIndex]); + if (FAILED( + ms_lpd3dDevice->CreateVertexBuffer( + sizeof(SoftwareTransformPatch_STVertex)*CTerrainPatch::TERRAIN_VERTEX_COUNT, + D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY, + D3DFVF_XYZRHW, + D3DPOOL_SYSTEMMEM, + &m_kSTPD.m_pkVBNone[uIndex] + ) + )) return false; + } + } + return true; +} + +void CMapOutdoor::__SoftwareTransformPatch_Destroy() +{ + { + for (UINT uIndex=0; uIndex!=SoftwareTransformPatch_SData::SPLAT_VB_NUM; ++uIndex) + { + if (m_kSTPD.m_pkVBSplat[uIndex]) + m_kSTPD.m_pkVBSplat[uIndex]->Release(); + } + } + + { + for (UINT uIndex=0; uIndex!=SoftwareTransformPatch_SData::NONE_VB_NUM; ++uIndex) + { + if (m_kSTPD.m_pkVBNone[uIndex]) + m_kSTPD.m_pkVBNone[uIndex]->Release(); + } + } + __SoftwareTransformPatch_Initialize(); +} + + diff --git a/source/GameLib/MapOutdoorUpdate.cpp b/source/GameLib/MapOutdoorUpdate.cpp new file mode 100644 index 0000000..6e80e53 --- /dev/null +++ b/source/GameLib/MapOutdoorUpdate.cpp @@ -0,0 +1,1133 @@ +#include "StdAfx.h" +#include "../eterlib/Camera.h" +#include "../PRTerrainLib/StdAfx.h" + +#include "MapOutdoor.h" +#include "TerrainPatch.h" +#include "AreaTerrain.h" +#include "TerrainQuadtree.h" +#include "ActorInstance.h" + +// 2004.08.17.myevan.std::vector ޸ ٿ ɷ ϵ +class PCBlocker_CDynamicSphereInstanceVector +{ + public: + typedef CDynamicSphereInstance* Iterator; + + enum + { + SIZE = 4, + }; + + public: + PCBlocker_CDynamicSphereInstanceVector() + { + } + ~PCBlocker_CDynamicSphereInstanceVector() + { + } + + Iterator Begin() + { + return m_aDSI+0; + } + Iterator End() + { + return m_aDSI+4; + } + + private: + CDynamicSphereInstance m_aDSI[4]; +}; + + + + +bool CMapOutdoor::Update(float fX, float fY, float fZ) +{ + D3DXVECTOR3 v3Player(fX, fY, fZ); + + m_v3Player=v3Player; + + + DWORD t1=ELTimer_GetMSec(); + + int ix, iy; + PR_FLOAT_TO_INT(fX, ix); + if ( fY < 0 ) + fY = -fY; + PR_FLOAT_TO_INT(fY, iy); + + short sCoordX = MINMAX(0, ix / CTerrainImpl::TERRAIN_XSIZE, m_sTerrainCountX - 1); + short sCoordY = MINMAX(0, iy / CTerrainImpl::TERRAIN_YSIZE, m_sTerrainCountY - 1); +#ifdef __PERFORMANCE_CHECKER__ + DWORD t2=ELTimer_GetMSec(); +#endif + + bool bNeedInit = (m_PrevCoordinate.m_sTerrainCoordX == -1 || m_PrevCoordinate.m_sTerrainCoordY == -1); + + if ( bNeedInit || + (m_CurCoordinate.m_sTerrainCoordX/LOAD_SIZE_WIDTH) != (sCoordX/LOAD_SIZE_WIDTH) || + (m_CurCoordinate.m_sTerrainCoordY/LOAD_SIZE_WIDTH) != (sCoordY/LOAD_SIZE_WIDTH) ) + { + if (bNeedInit) + { + m_PrevCoordinate.m_sTerrainCoordX = sCoordX; + m_PrevCoordinate.m_sTerrainCoordY = sCoordY; + } + else + { + m_PrevCoordinate.m_sTerrainCoordX = m_CurCoordinate.m_sTerrainCoordX; + m_PrevCoordinate.m_sTerrainCoordY = m_CurCoordinate.m_sTerrainCoordY; + } + + m_CurCoordinate.m_sTerrainCoordX = sCoordX; + m_CurCoordinate.m_sTerrainCoordY = sCoordY; + m_lCurCoordStartX = sCoordX * CTerrainImpl::TERRAIN_XSIZE; + m_lCurCoordStartY = sCoordY * CTerrainImpl::TERRAIN_YSIZE; + + WORD wCellCoordX = (ix % CTerrainImpl::TERRAIN_XSIZE) / CTerrainImpl::CELLSCALE; + WORD wCellCoordY = (iy % CTerrainImpl::TERRAIN_YSIZE) / CTerrainImpl::CELLSCALE; + + short sReferenceCoordMinX, sReferenceCoordMaxX, sReferenceCoordMinY, sReferenceCoordMaxY; + sReferenceCoordMinX = max(m_CurCoordinate.m_sTerrainCoordX - LOAD_SIZE_WIDTH, 0); + sReferenceCoordMaxX = min(m_CurCoordinate.m_sTerrainCoordX + LOAD_SIZE_WIDTH, m_sTerrainCountX - 1); + sReferenceCoordMinY = max(m_CurCoordinate.m_sTerrainCoordY - LOAD_SIZE_WIDTH, 0); + sReferenceCoordMaxY = min(m_CurCoordinate.m_sTerrainCoordY + LOAD_SIZE_WIDTH, m_sTerrainCountY - 1); + + for (WORD usY = sReferenceCoordMinY; usY <=sReferenceCoordMaxY; ++usY) + { + for (WORD usX = sReferenceCoordMinX; usX <= sReferenceCoordMaxX; ++usX) + { + LoadTerrain(usX, usY, wCellCoordX, wCellCoordY); + LoadArea(usX, usY, wCellCoordX, wCellCoordY); + } + } + + AssignTerrainPtr(); + m_lOldReadX = -1; + + Tracenf("Update::Load spent %d ms\n", ELTimer_GetMSec() - t1); + } +#ifdef __PERFORMANCE_CHECKER__ + DWORD t3=ELTimer_GetMSec(); +#endif + CSpeedTreeForestDirectX8::Instance().UpdateSystem(CTimer::Instance().GetCurrentSecond()); +#ifdef __PERFORMANCE_CHECKER__ + DWORD t4=ELTimer_GetMSec(); +#endif + __UpdateGarvage(); +#ifdef __PERFORMANCE_CHECKER__ + DWORD t5=ELTimer_GetMSec(); +#endif + UpdateTerrain(fX, fY); +#ifdef __PERFORMANCE_CHECKER__ + DWORD t6=ELTimer_GetMSec(); +#endif + __UpdateArea(v3Player); +#ifdef __PERFORMANCE_CHECKER__ + DWORD t7=ELTimer_GetMSec(); +#endif + UpdateSky(); +#ifdef __PERFORMANCE_CHECKER__ + DWORD t8=ELTimer_GetMSec(); +#endif + __HeightCache_Update(); + +#ifdef __PERFORMANCE_CHECKER__ + { + static FILE* fp=fopen("perf_outdoor_update.txt", "w"); + + if (t8-t1>5) + { + fprintf(fp, "OD.Total %d (Time %f)\n", t3-t1, ELTimer_GetMSec()/1000.0f); + fprintf(fp, "OD.INIT %d\n", t2-t1); + fprintf(fp, "OD.LOAD %d\n", t3-t2); + fprintf(fp, "OD.TREE %d\n", t4-t3); + fprintf(fp, "OD.GVG %d\n", t5-t4); + fprintf(fp, "OD.TRN %d\n", t6-t5); + fprintf(fp, "OD.AREA %d\n", t7-t6); + fprintf(fp, "OD.SKY %d\n", t8-t7); + fflush(fp); + } + } +#endif + + return true; +} + +void CMapOutdoor::UpdateSky() +{ + m_SkyBox.Update(); +} + +struct FGetShadowReceiverFromCollisionData +{ + bool m_bCollide; + std::vector* m_pkVct_pkShadowReceiver; + CDynamicSphereInstance * m_pdsi; + FGetShadowReceiverFromCollisionData(CDynamicSphereInstance * pdsi, std::vector* pkVct_pkShadowReceiver) : m_pdsi(pdsi), m_bCollide(false) + { + m_pkVct_pkShadowReceiver=pkVct_pkShadowReceiver; + m_pkVct_pkShadowReceiver->clear(); + } + void operator () (CGraphicObjectInstance * pInstance) + { + if (!pInstance) + return; + + if (TREE_OBJECT == pInstance->GetType() || ACTOR_OBJECT == pInstance->GetType() || EFFECT_OBJECT == pInstance->GetType()) + return; + if (pInstance->CollisionDynamicSphere(*m_pdsi)) + { + m_pkVct_pkShadowReceiver->push_back(pInstance); + m_bCollide = true; + } + } +}; + + + +struct FPCBlockerDistanceSort +{ + D3DXVECTOR3 m_v3Eye; + FPCBlockerDistanceSort(D3DXVECTOR3 & v3Eye) : m_v3Eye(v3Eye) { } + + bool operator () (CGraphicObjectInstance * plhs, CGraphicObjectInstance * prhs) const + { + const auto vv = (plhs->GetPosition() - m_v3Eye); + const auto vv2 = (prhs->GetPosition() - m_v3Eye); + return D3DXVec3LengthSq(&vv) > D3DXVec3LengthSq(&vv2); + } +}; + +void CMapOutdoor::UpdateAroundAmbience(float fX, float fY, float fZ) +{ + for (int i = 0; i < AROUND_AREA_NUM; ++i) + { + CArea * pArea; + if (GetAreaPointer(i, &pArea)) + pArea->UpdateAroundAmbience(fX, fY, fZ); + } +} + +void CMapOutdoor::__UpdateArea(D3DXVECTOR3& v3Player) +{ +#ifdef WORLD_EDITOR + __NEW_WorldEditor_UpdateArea(); +#else + __Game_UpdateArea(v3Player); +#endif +} + +void CMapOutdoor::__Game_UpdateArea(D3DXVECTOR3& v3Player) +{ +#ifdef __PERFORMANCE_CHECKER__ + DWORD t1=timeGetTime(); +#endif + m_PCBlockerVector.clear(); + m_ShadowReceiverVector.clear(); +#ifdef __PERFORMANCE_CHECKER__ + DWORD t2=timeGetTime(); +#endif + CCameraManager& rCmrMgr=CCameraManager::Instance(); + CCamera * pCamera = rCmrMgr.GetCurrentCamera(); + if (!pCamera) + return; + + float fDistance = pCamera->GetDistance(); + + D3DXVECTOR3 v3View= pCamera->GetView(); + D3DXVECTOR3 v3Target = pCamera->GetTarget(); + D3DXVECTOR3 v3Eye= pCamera->GetEye(); + + D3DXVECTOR3 v3Light = D3DXVECTOR3(1.732f, 1.0f, -3.464f); // + v3Light *= 50.0f / D3DXVec3Length(&v3Light); + + /* + if (v3Target!=v3Player) + { + printf("%.2f %.2f %.2f -> target(%.2f %.2f %.2f) player(%.2f %.2f %.2f)\n", + v3Eye.x, v3Eye.y, v3Eye.z, + v3Target.x, v3Target.y, v3Target.z, + v3Player.x, v3Player.y, v3Player.z + ); + } + */ +#ifdef __PERFORMANCE_CHECKER__ + DWORD t3=timeGetTime(); +#endif + __CollectShadowReceiver(v3Player, v3Light); +#ifdef __PERFORMANCE_CHECKER__ + DWORD t4=timeGetTime(); +#endif + __CollectCollisionPCBlocker(v3Eye, v3Player, fDistance); +#ifdef __PERFORMANCE_CHECKER__ + DWORD t5=timeGetTime(); +#endif + __CollectCollisionShadowReceiver(v3Player, v3Light); +#ifdef __PERFORMANCE_CHECKER__ + DWORD t6=timeGetTime(); +#endif + __UpdateAroundAreaList(); + +#ifdef __PERFORMANCE_CHECKER__ + DWORD t7=timeGetTime(); + { + static FILE* fp=fopen("perf_area_update.txt", "w"); + + if (t7-t1>5) + { + fprintf(fp, "UA.Total %d (Time %f)\n", t3-t1, ELTimer_GetMSec()/1000.0f); + fprintf(fp, "UA.Clear %d\n", t2-t1); + fprintf(fp, "UA.Vector %d\n", t3-t2); + fprintf(fp, "UA.Shadow %d\n", t4-t3); + fprintf(fp, "UA.Blocker %d\n", t5-t4); + fprintf(fp, "UA.ColliShadow %d\n", t6-t5); + fprintf(fp, "UA.Area %d\n", t7-t6); + fflush(fp); + } + } +#endif +} +#ifdef WORLD_EDITOR +void CMapOutdoor::__NEW_WorldEditor_UpdateArea() +{ + m_PCBlockerVector.clear(); + m_ShadowReceiverVector.clear(); + __UpdateAroundAreaList(); + +} +#endif +void CMapOutdoor::__UpdateAroundAreaList() +{ +#ifdef __PERFORMANCE_CHECKER__ + DWORD ft1=timeGetTime(); +#endif + DWORD at[AROUND_AREA_NUM]; + for (int i = 0; i < AROUND_AREA_NUM; ++i) + { + DWORD t1=timeGetTime(); + CArea * pArea; + if (GetAreaPointer(i, &pArea)) + pArea->Update(); + DWORD t2=timeGetTime(); + + at[i]=t2-t1; + } +#ifdef __PERFORMANCE_CHECKER__ + DWORD ft2=timeGetTime(); + if (ft2-ft1>5) + { + for (int i=0; i=m_dwCollectCount) + return NULL; + + return m_apkShadowReceiver[uIndex]; + } + + UINT GetCollectCount() + { + return m_dwCollectCount; + } + + void operator () (CGraphicObjectInstance * pInstance) + { + m_dwCheckCount++; + + if (!pInstance) + return; + + if (m_fFromY < 0) + m_fFromY = -m_fFromY; + if (m_fToY < 0) + m_fToY = -m_fToY; + if (pInstance->GetObjectHeight(m_fFromX, m_fFromY, &m_fReturnHeight) || + pInstance->GetObjectHeight(m_fToX, m_fToY, &m_fReturnHeight)) + { + if (m_dwCollectCount5) + { + fprintf(fp, "SC.Total %d (Time %f)\n", t3-t1, ELTimer_GetMSec()/1000.0f); + fprintf(fp, "SC.Find %d\n", t2-t1); + fprintf(fp, "SC.Push %d\n", t3-t2); + fprintf(fp, "SC.Count (Collect %d, Over %d, Check %d)\n", + kGetShadowReceiverFromHeightData.m_dwCollectCount, + kGetShadowReceiverFromHeightData.m_dwCollectOverCount, + kGetShadowReceiverFromHeightData.m_dwCheckCount); + fflush(fp); + } +#endif +} + + +struct PCBlocker_SInstanceList +{ + typedef CGraphicObjectInstance* Item; + typedef Item* Iterator; + + enum + { + CAPACITY = 512, + }; + + DWORD m_dwInstCount; + DWORD m_dwBlockerCount; + DWORD m_dwBlockerOverCount; + + Item m_apkPCBlocker[CAPACITY]; + + PCBlocker_CDynamicSphereInstanceVector* m_pkDSIVector; + + CCamera * m_pCamera; + D3DXVECTOR2 m_v2View; + D3DXVECTOR2 m_v2Target; + + PCBlocker_SInstanceList(PCBlocker_CDynamicSphereInstanceVector* pkDSIVector) + { + m_pCamera = CCameraManager::Instance().GetCurrentCamera(); + if (!m_pCamera) + return; + + D3DXVECTOR3 m_v3View = m_pCamera->GetView(); + D3DXVECTOR3 m_v3Target = m_pCamera->GetTarget(); + + m_v2View.x = m_v3View.x; + m_v2View.y = m_v3View.y; + + m_v2Target.x = m_v3Target.x; + m_v2Target.y = m_v3Target.y; + + m_pkDSIVector=pkDSIVector; + m_dwBlockerCount=0; + m_dwBlockerOverCount=0; + m_dwInstCount=0; + } + ~PCBlocker_SInstanceList() + { +#ifdef _DEBUG + __DEBUG_ShowInstanceMaxCount(); +#endif + } + void __DEBUG_ShowInstanceMaxCount() + { + static DWORD s_dwInstMaxCount=0; + if (s_dwInstMaxCount0) + return false; + + return true; + } + + void __AppendPCBlocker(CGraphicObjectInstance * pInstance) + { + if (m_dwBlockerCountGetBoundingSphere(v3Center, fRadius); + + D3DXVECTOR2 v2TargetToCenter; + v2TargetToCenter.x = v3Center.x - m_v2Target.x; + v2TargetToCenter.y = v3Center.y - m_v2Target.y; + if (D3DXVec2Dot(&m_v2View, &v2TargetToCenter) <= 0) + { + __AppendPCBlocker(pInstance); + return; + } + } + + void operator () (CGraphicObjectInstance * pInstance) + { + if (!m_pCamera) + return; + + if (!pInstance) + return; + + ++m_dwInstCount; + + PCBlocker_CDynamicSphereInstanceVector::Iterator i; + + for (i=m_pkDSIVector->Begin(); i!=m_pkDSIVector->End(); ++i) + { + CDynamicSphereInstance& rkDSI = *i; + if (pInstance->CollisionDynamicSphere(rkDSI) ) + { + if (TREE_OBJECT == pInstance->GetType()) + { + __AppendPCBlocker(pInstance); + return; + } + else if (THING_OBJECT == pInstance->GetType()) + { + __AppendObject(pInstance); + } + else if (ACTOR_OBJECT == pInstance->GetType()) + { + if (((CActorInstance *)pInstance)->IsBuilding()) + { + __AppendObject(pInstance); + } + } + } + } + } +}; + + +void CMapOutdoor::__CollectCollisionPCBlocker(D3DXVECTOR3& v3Eye, D3DXVECTOR3& v3Target, float fDistance) +{ +#ifdef __PERFORMANCE_CHECKER__ + DWORD t1=timeGetTime(); +#endif + + Vector3d v3dRayStart; + v3dRayStart.Set(v3Eye.x, v3Eye.y, v3Eye.z); +#ifdef __PERFORMANCE_CHECKER__ + DWORD t2=timeGetTime(); +#endif + + PCBlocker_CDynamicSphereInstanceVector aDynamicSphereInstanceVector; + { + CDynamicSphereInstance* pkDSI=aDynamicSphereInstanceVector.Begin(); + pkDSI->fRadius = fDistance * 0.5f; + pkDSI->v3LastPosition = v3Eye; + pkDSI->v3Position = v3Eye + 0.5f * (v3Target - v3Eye); + ++pkDSI; + + pkDSI->fRadius = fDistance * 0.5f; + pkDSI->v3LastPosition = v3Eye + 0.5f * (v3Target - v3Eye); + pkDSI->v3Position = v3Target; + ++pkDSI; + + pkDSI->fRadius = fDistance * 0.5f; + pkDSI->v3LastPosition = v3Target; + pkDSI->v3Position = v3Eye + 0.5f * (v3Target - v3Eye); + ++pkDSI; + + pkDSI->fRadius = fDistance * 0.5f; + pkDSI->v3LastPosition = v3Eye + 0.5f * (v3Target - v3Eye); + pkDSI->v3Position = v3Eye; + ++pkDSI; + } +#ifdef __PERFORMANCE_CHECKER__ + DWORD t3=timeGetTime(); +#endif + CCullingManager & rkCullingMgr = CCullingManager::Instance(); + + PCBlocker_SInstanceList kPCBlockerList(&aDynamicSphereInstanceVector); + RangeTester kPCBlockerRangeTester(&kPCBlockerList); + rkCullingMgr.RangeTest(v3dRayStart, fDistance, &kPCBlockerRangeTester); +#ifdef __PERFORMANCE_CHECKER__ + DWORD t4=timeGetTime(); +#endif + + if (!kPCBlockerList.IsEmpty()) + { + PCBlocker_SInstanceList::Iterator i; + + for (i=kPCBlockerList.Begin(); i!=kPCBlockerList.End(); ++i) + { + CGraphicObjectInstance * pObjInstEach = *i; + + if (!pObjInstEach) + continue; + + if (TREE_OBJECT == pObjInstEach->GetType() && !m_bTransparentTree) + continue; + + if (!__IsInShadowReceiverList(pObjInstEach)) + if (!__IsInPCBlockerList(pObjInstEach)) + m_PCBlockerVector.push_back(pObjInstEach); + } + } +#ifdef __PERFORMANCE_CHECKER__ + DWORD t5=timeGetTime(); +#endif + std::sort(m_PCBlockerVector.begin(), m_PCBlockerVector.end(), FPCBlockerDistanceSort(v3Eye)); + +#ifdef __PERFORMANCE_CHECKER__ + DWORD t6=timeGetTime(); + + static FILE* fp=fopen("perf_pbc_collect.txt", "w"); + + if (t3-t1>5) + { + fprintf(fp, "PBC.Total %d (Time %f)\n", t3-t1, ELTimer_GetMSec()/1000.0f); + fprintf(fp, "PBC.INIT %d\n", t2-t1); + fprintf(fp, "PBC.SET %d\n", t3-t2); + fprintf(fp, "PBC.CALC %d\n", t4-t2); + fprintf(fp, "PBC.PUSH %d\n", t5-t2); + fprintf(fp, "PBC.SORT %d (%d)\n", t6-t2, m_PCBlockerVector.size()); + fprintf(fp, "PBC.Count (Collect %d, Over %d, Check %d)\n", + kPCBlockerList.m_dwBlockerCount, + kPCBlockerList.m_dwBlockerOverCount, + kPCBlockerList.m_dwInstCount); + fflush(fp); + } +#endif +} + +void CMapOutdoor::__CollectCollisionShadowReceiver(D3DXVECTOR3& v3Target, D3DXVECTOR3& v3Light) +{ + CDynamicSphereInstance s; + s.fRadius = 50.0f; + s.v3LastPosition = v3Target + v3Light; + s.v3Position = s.v3LastPosition + v3Light; + + Vector3d aVector3d; + aVector3d.Set(v3Target.x, v3Target.y, v3Target.z); + + CCullingManager & rkCullingMgr = CCullingManager::Instance(); + + std::vector kVct_pkShadowReceiver; + FGetShadowReceiverFromCollisionData kGetShadowReceiverFromCollisionData(&s, &kVct_pkShadowReceiver); + rkCullingMgr.ForInRange(aVector3d, 100.0f, &kGetShadowReceiverFromCollisionData); + if (!kGetShadowReceiverFromCollisionData.m_bCollide) + return; + + std::vector::iterator i; + for ( i = kVct_pkShadowReceiver.begin(); i != kVct_pkShadowReceiver.end(); ++i) + { + CGraphicObjectInstance * pObjInstEach = *i; + if (!__IsInPCBlockerList(pObjInstEach)) + if (!__IsInShadowReceiverList(pObjInstEach)) + m_ShadowReceiverVector.push_back(pObjInstEach); + } +} + +bool CMapOutdoor::__IsInShadowReceiverList(CGraphicObjectInstance* pkObjInstTest) +{ + if (m_ShadowReceiverVector.end() == std::find(m_ShadowReceiverVector.begin(), m_ShadowReceiverVector.end(), pkObjInstTest)) + return false; + + return true; +} + +bool CMapOutdoor::__IsInPCBlockerList(CGraphicObjectInstance* pkObjInstTest) +{ + if (m_PCBlockerVector.end() == std::find(m_PCBlockerVector.begin(), m_PCBlockerVector.end(), pkObjInstTest)) + return false; + + return true; +} + +// Updates the position of the terrain +void CMapOutdoor::UpdateTerrain(float fX, float fY) +{ + if (fY < 0) + fY = -fY; + + int sx, sy; + PR_FLOAT_TO_INT(fX, sx); + PR_FLOAT_TO_INT(fY, sy); + + long lDivider = (CTerrainImpl::CELLSCALE * TERRAIN_PATCHSIZE); + + m_lCenterX = (sx - m_lCurCoordStartX) / lDivider; + m_lCenterY = (sy - m_lCurCoordStartY) / lDivider; + + if ((m_lCenterX != m_lOldReadX) || (m_lCenterY != m_lOldReadY)) + { + long lRealCenterX = m_lCenterX * TERRAIN_PATCHSIZE; + long lRealCenterY = m_lCenterY * TERRAIN_PATCHSIZE; + m_lOldReadX = m_lCenterX; + m_lOldReadY = m_lCenterY; + + ConvertTerrainToTnL(lRealCenterX, lRealCenterY); + UpdateAreaList(lRealCenterX, lRealCenterY); + //Tracef("ϴ Area, Terrain : (%d, %d), Area, Terrain : (%d, %d)\n", + // m_AreaVector.size(), m_TerrainVector.size(), m_AreaDeleteVector.size(), m_TerrainDeleteVector.size()); + } +} + +void CMapOutdoor::FPushTerrainToDeleteVector::operator () (CTerrain * pTerrain) +{ + TTerrainPtrVectorIterator aIterator = std::find(m_ReturnTerrainVector.begin(), m_ReturnTerrainVector.end(), pTerrain); + if (aIterator != m_ReturnTerrainVector.end()) + return; + + WORD wReferenceCoordX = m_CurCoordinate.m_sTerrainCoordX; + WORD wReferenceCoordY = m_CurCoordinate.m_sTerrainCoordY; + + WORD wCoordX, wCoordY; + pTerrain->GetCoordinate(&wCoordX, &wCoordY); + + + switch(m_eLRDeleteDir) + { + case DELETE_LEFT: + if (wCoordX < wReferenceCoordX - LOAD_SIZE_WIDTH) + m_ReturnTerrainVector.push_back(pTerrain); + break; + case DELETE_RIGHT: + if (wCoordX > wReferenceCoordX + LOAD_SIZE_WIDTH) + m_ReturnTerrainVector.push_back(pTerrain); + break; + } + + aIterator = std::find(m_ReturnTerrainVector.begin(), m_ReturnTerrainVector.end(), pTerrain); + if (aIterator != m_ReturnTerrainVector.end()) + return; + + switch(m_eTBDeleteDir) + { + case DELETE_TOP: + if (wCoordY < wReferenceCoordY - LOAD_SIZE_WIDTH) + m_ReturnTerrainVector.push_back(pTerrain); + break; + case DELETE_BOTTOM: + if (wCoordY > wReferenceCoordY + LOAD_SIZE_WIDTH) + m_ReturnTerrainVector.push_back(pTerrain); + break; + } +} + +void CMapOutdoor::FPushAreaToDeleteVector::operator () (CArea * pArea) +{ + TAreaPtrVectorIterator aIterator = std::find(m_ReturnAreaVector.begin(), m_ReturnAreaVector.end(), pArea); + if (aIterator != m_ReturnAreaVector.end()) + return; + + WORD wReferenceCoordX = m_CurCoordinate.m_sTerrainCoordX; + WORD wReferenceCoordY = m_CurCoordinate.m_sTerrainCoordY; + + WORD wCoordX, wCoordY; + pArea->GetCoordinate(&wCoordX, &wCoordY); + + switch(m_eLRDeleteDir) + { + case DELETE_LEFT: + if (wCoordX < wReferenceCoordX - LOAD_SIZE_WIDTH) + m_ReturnAreaVector.push_back(pArea); + break; + case DELETE_RIGHT: + if (wCoordX > wReferenceCoordX + LOAD_SIZE_WIDTH) + m_ReturnAreaVector.push_back(pArea); + break; + } + + aIterator = std::find(m_ReturnAreaVector.begin(), m_ReturnAreaVector.end(), pArea); + if (aIterator != m_ReturnAreaVector.end()) + return; + + switch(m_eTBDeleteDir) + { + case DELETE_TOP: + if (wCoordY < wReferenceCoordY - LOAD_SIZE_WIDTH) + m_ReturnAreaVector.push_back(pArea); + break; + case DELETE_BOTTOM: + if (wCoordY > wReferenceCoordY + LOAD_SIZE_WIDTH) + m_ReturnAreaVector.push_back(pArea); + break; + } +} + +void CMapOutdoor::__ClearGarvage() +{ + std::for_each(m_TerrainDeleteVector.begin(), m_TerrainDeleteVector.end(), CTerrain::Delete); + m_TerrainDeleteVector.clear(); + + std::for_each(m_AreaDeleteVector.begin(), m_AreaDeleteVector.end(), CArea::Delete); + m_AreaDeleteVector.clear(); +} + +void CMapOutdoor::__UpdateGarvage() +{ + const DWORD dwTerrainEraseInterval = 1000 * 60; + static DWORD dwEraseTime = ELTimer_GetMSec(); + + if (!m_TerrainDeleteVector.empty()) + { + if (ELTimer_GetMSec() - dwEraseTime <= dwTerrainEraseInterval) + return; + TTerrainPtrVectorIterator aTerrainPtrDeleteItertor = m_TerrainDeleteVector.begin(); + CTerrain * pTerrain = *aTerrainPtrDeleteItertor; + CTerrain::Delete(pTerrain); + + aTerrainPtrDeleteItertor = m_TerrainDeleteVector.erase(aTerrainPtrDeleteItertor); + dwEraseTime = ELTimer_GetMSec(); + Trace("Delete Terrain \n"); + return; + } + + if (!m_AreaDeleteVector.empty()) + { + if (ELTimer_GetMSec() - dwEraseTime <= dwTerrainEraseInterval) + return; + TAreaPtrVectorIterator aAreaPtrDeleteItertor = m_AreaDeleteVector.begin(); + + CArea * pArea = *aAreaPtrDeleteItertor; + CArea::Delete(pArea); + + aAreaPtrDeleteItertor = m_AreaDeleteVector.erase(aAreaPtrDeleteItertor); + dwEraseTime = ELTimer_GetMSec(); + Trace("Delete Area \n"); + return; + } +} + +void CMapOutdoor::UpdateAreaList(long lCenterX, long lCenterY) +{ + if (m_TerrainVector.size() <= AROUND_AREA_NUM && m_AreaVector.size() <= AROUND_AREA_NUM) + return; + + __ClearGarvage(); + + FPushToDeleteVector::EDeleteDir eDeleteLRDir, eDeleteTBDir; + + if (lCenterX > CTerrainImpl::XSIZE / 2) + eDeleteLRDir = FPushToDeleteVector::DELETE_LEFT; + else + eDeleteLRDir = FPushToDeleteVector::DELETE_RIGHT; + if (lCenterY > CTerrainImpl::YSIZE / 2) + eDeleteTBDir = FPushToDeleteVector::DELETE_TOP; + else + eDeleteTBDir = FPushToDeleteVector::DELETE_BOTTOM; + + FPushTerrainToDeleteVector rPushTerrainToDeleteVector = std::for_each(m_TerrainVector.begin(), m_TerrainVector.end(), + FPushTerrainToDeleteVector(eDeleteLRDir, eDeleteTBDir, m_CurCoordinate)); + FPushAreaToDeleteVector rPushAreaToDeleteVector = std::for_each(m_AreaVector.begin(), m_AreaVector.end(), + FPushAreaToDeleteVector(eDeleteLRDir, eDeleteTBDir, m_CurCoordinate)); + + if (!rPushTerrainToDeleteVector.m_ReturnTerrainVector.empty()) + { + m_TerrainDeleteVector.resize(rPushTerrainToDeleteVector.m_ReturnTerrainVector.size()); + std::copy(rPushTerrainToDeleteVector.m_ReturnTerrainVector.begin(), rPushTerrainToDeleteVector.m_ReturnTerrainVector.end(), m_TerrainDeleteVector.begin()); + + for (DWORD dwIndex = 0; dwIndex < rPushTerrainToDeleteVector.m_ReturnTerrainVector.size(); ++dwIndex) + { + bool isDel=false; + TTerrainPtrVectorIterator aTerrainPtrItertor = m_TerrainVector.begin(); + while(aTerrainPtrItertor != m_TerrainVector.end()) + { + CTerrain * pTerrain = *aTerrainPtrItertor; + if (pTerrain == rPushTerrainToDeleteVector.m_ReturnTerrainVector[dwIndex]) + { + aTerrainPtrItertor = m_TerrainVector.erase(aTerrainPtrItertor); + isDel=true; + } + else + ++aTerrainPtrItertor; + } + } + } + if (!rPushAreaToDeleteVector.m_ReturnAreaVector.empty()) + { + m_AreaDeleteVector.resize(rPushAreaToDeleteVector.m_ReturnAreaVector.size()); + std::copy(rPushAreaToDeleteVector.m_ReturnAreaVector.begin(), rPushAreaToDeleteVector.m_ReturnAreaVector.end(), m_AreaDeleteVector.begin()); + + for (DWORD dwIndex = 0; dwIndex < rPushAreaToDeleteVector.m_ReturnAreaVector.size(); ++dwIndex) + { + TAreaPtrVectorIterator aAreaPtrItertor = m_AreaVector.begin(); + while(aAreaPtrItertor != m_AreaVector.end()) + { + CArea * pArea = *aAreaPtrItertor; + if (pArea == rPushAreaToDeleteVector.m_ReturnAreaVector[dwIndex]) + aAreaPtrItertor = m_AreaVector.erase(aAreaPtrItertor); + else + ++aAreaPtrItertor; + } + } + } +} + +void CMapOutdoor::ConvertTerrainToTnL(long lx, long ly) +{ + assert(NULL!=m_pTerrainPatchProxyList && "CMapOutdoor::ConvertTerrainToTnL"); + + for (long i = 0; i < m_wPatchCount * m_wPatchCount; i++) + m_pTerrainPatchProxyList[i].SetUsed(false); + + lx -= m_lViewRadius; /* Move to the top left corner of the */ + ly -= m_lViewRadius; /* input rectangle */ + + long diameter = m_lViewRadius * 2; + + long x0 = lx / TERRAIN_PATCHSIZE; + long y0 = ly / TERRAIN_PATCHSIZE; + long x1 = ( lx + diameter - 1 ) / TERRAIN_PATCHSIZE; + long y1 = ( ly + diameter - 1 ) / TERRAIN_PATCHSIZE; + + long xw = x1 - x0 + 1; /* Figure out how many patches are needed */ + long yw = y1 - y0 + 1; + + long ex = lx + diameter; + long ey = ly + diameter; + + y0 = ly; + for (long yp = 0; yp < yw; yp++) + { + x0 = lx; + y1 = (y0 / TERRAIN_PATCHSIZE + 1) * TERRAIN_PATCHSIZE; + if (y1 > ey) + y1 = ey; + for (long xp = 0; xp < xw; xp++) + { + x1 = (x0 / TERRAIN_PATCHSIZE + 1) * TERRAIN_PATCHSIZE; + if (x1 > ex) + x1 = ex; + AssignPatch(yp * m_wPatchCount + xp, x0, y0, x1, y1); + x0 = x1; + } + y0 = y1; + } + UpdateQuadTreeHeights(m_pRootNode); +} + +void CMapOutdoor::AssignPatch(long lPatchNum, long x0, long y0, long x1, long y1) +{ + assert(NULL!=m_pTerrainPatchProxyList && "CMapOutdoor::AssignPatch"); + + CTerrainPatchProxy * pTerrainPatchProxy = &m_pTerrainPatchProxyList[lPatchNum]; + + if (y0 < 0 && y1 <= 0) + { + if (x0 < 0 && x1 <= 0) + { + pTerrainPatchProxy->SetTerrainNum(0); + x0 += CTerrainImpl::XSIZE; + x1 += CTerrainImpl::XSIZE; + } + else if (x0 >= CTerrainImpl::XSIZE && x1 > CTerrainImpl::XSIZE) + { + pTerrainPatchProxy->SetTerrainNum(2); + x0 -= CTerrainImpl::XSIZE; + x1 -= CTerrainImpl::XSIZE; + } + else + pTerrainPatchProxy->SetTerrainNum(1); + + y0 += CTerrainImpl::YSIZE; + y1 += CTerrainImpl::YSIZE; + } + else if (y0 >= CTerrainImpl::YSIZE && y1 > CTerrainImpl::YSIZE) + { + if (x0 < 0 && x1 <= 0) + { + pTerrainPatchProxy->SetTerrainNum(6); + x0 += CTerrainImpl::XSIZE; + x1 += CTerrainImpl::XSIZE; + } + else if (x0 >= CTerrainImpl::XSIZE && x1 > CTerrainImpl::XSIZE) + { + pTerrainPatchProxy->SetTerrainNum(8); + x0 -= CTerrainImpl::XSIZE; + x1 -= CTerrainImpl::XSIZE; + } + else + pTerrainPatchProxy->SetTerrainNum(7); + + y0 -= CTerrainImpl::YSIZE; + y1 -= CTerrainImpl::YSIZE; + } + else + { + if (x0 < 0 && x1 <= 0) + { + pTerrainPatchProxy->SetTerrainNum(3); + x0 += CTerrainImpl::XSIZE; + x1 += CTerrainImpl::XSIZE; + } + else if (x0 >= CTerrainImpl::XSIZE && x1 > CTerrainImpl::XSIZE) + { + pTerrainPatchProxy->SetTerrainNum(5); + x0 -= CTerrainImpl::XSIZE; + x1 -= CTerrainImpl::XSIZE; + } + else + pTerrainPatchProxy->SetTerrainNum(4); + } + + CTerrain * pTerrain; + if (!GetTerrainPointer(pTerrainPatchProxy->GetTerrainNum(), &pTerrain)) + return; + + BYTE byPatchNumX, byPatchNumY; + byPatchNumX = x0 / CTerrainImpl::PATCH_XSIZE; + byPatchNumY = y0 / CTerrainImpl::PATCH_YSIZE; + + CTerrainPatch * pTerrainPatch = pTerrain->GetTerrainPatchPtr(byPatchNumX, byPatchNumY); + if (!pTerrainPatch) + return; + + pTerrainPatchProxy->SetPatchNum(byPatchNumY * CTerrainImpl::PATCH_XCOUNT + byPatchNumX); + pTerrainPatchProxy->SetTerrainPatch(pTerrainPatch); + pTerrainPatchProxy->SetUsed(true); +} + +void CMapOutdoor::UpdateQuadTreeHeights(CTerrainQuadtreeNode *Node) +{ + // Inserted by levites + assert(NULL!=m_pTerrainPatchProxyList && "CMapOutdoor::UpdateQuadTreeHeights"); + if (!m_pTerrainPatchProxyList) + return; + + float minx, maxx, miny, maxy, minz, maxz; + minx = maxx = miny = maxy = minz = maxz = 0; + + if (m_pTerrainPatchProxyList[Node->PatchNum].isUsed()) + { + minx = m_pTerrainPatchProxyList[Node->PatchNum].GetMinX(); + maxx = m_pTerrainPatchProxyList[Node->PatchNum].GetMaxX(); + miny = m_pTerrainPatchProxyList[Node->PatchNum].GetMinY(); + maxy = m_pTerrainPatchProxyList[Node->PatchNum].GetMaxY(); + minz = m_pTerrainPatchProxyList[Node->PatchNum].GetMinZ(); + maxz = m_pTerrainPatchProxyList[Node->PatchNum].GetMaxZ(); + } + + for (long y = Node->y0; y <= Node->y1; y++) + { + for (long x = Node->x0; x <= Node->x1; x++) + { + long patch = y * m_wPatchCount + x; + + if (!m_pTerrainPatchProxyList[patch].isUsed()) + continue; + + if (m_pTerrainPatchProxyList[patch].GetMinX() < minx) + minx = m_pTerrainPatchProxyList[patch].GetMinX(); + if (m_pTerrainPatchProxyList[patch].GetMaxX() > maxx) + maxx = m_pTerrainPatchProxyList[patch].GetMaxX(); + + if (m_pTerrainPatchProxyList[patch].GetMinY() < miny) + miny = m_pTerrainPatchProxyList[patch].GetMinY(); + if (m_pTerrainPatchProxyList[patch].GetMaxY() > maxy) + maxy = m_pTerrainPatchProxyList[patch].GetMaxY(); + + if (m_pTerrainPatchProxyList[patch].GetMinZ() < minz) + minz = m_pTerrainPatchProxyList[patch].GetMinZ(); + if (m_pTerrainPatchProxyList[patch].GetMaxZ() > maxz) + maxz = m_pTerrainPatchProxyList[patch].GetMaxZ(); + } + } + + Node->center.x = (maxx + minx) * 0.5f; + Node->center.y = (maxy + miny) * 0.5f; + Node->center.z = (maxz + minz) * 0.5f; + + Node->radius = sqrtf((maxx-minx)*(maxx-minx) + + (maxy-miny)*(maxy-miny) + + (maxz-minz)*(maxz-minz)) / 2.0f; + + if (Node->NW_Node != NULL) + UpdateQuadTreeHeights(Node->NW_Node); + + if (Node->NE_Node != NULL) + UpdateQuadTreeHeights(Node->NE_Node); + + if (Node->SW_Node != NULL) + UpdateQuadTreeHeights(Node->SW_Node); + + if (Node->SE_Node != NULL) + UpdateQuadTreeHeights(Node->SE_Node); +} diff --git a/source/GameLib/MapOutdoorWater.cpp b/source/GameLib/MapOutdoorWater.cpp new file mode 100644 index 0000000..a56a9b9 --- /dev/null +++ b/source/GameLib/MapOutdoorWater.cpp @@ -0,0 +1,170 @@ +#include "StdAfx.h" +#include "../eterLib/StateManager.h" +#include "../eterLib/ResourceManager.h" + +#include "MapOutdoor.h" +#include "TerrainPatch.h" + +void CMapOutdoor::LoadWaterTexture() +{ + UnloadWaterTexture(); + char buf[256]; + for (int i = 0; i < 30; ++i) + { + sprintf(buf, "d:/ymir Work/special/water/%02d.dds", i+1); + m_WaterInstances[i].SetImagePointer((CGraphicImage *) CResourceManager::Instance().GetResourcePointer(buf)); + } +} + +void CMapOutdoor::UnloadWaterTexture() +{ + for (int i = 0; i < 30; ++i) + m_WaterInstances[i].Destroy(); +} + +void CMapOutdoor::RenderWater() +{ + if (m_PatchVector.empty()) + return; + + if (!IsVisiblePart(PART_WATER)) + return; + + ////////////////////////////////////////////////////////////////////////// + // RenderState + D3DXMATRIX matTexTransformWater; + + STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, FALSE); + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + STATEMANAGER.SaveRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1); + STATEMANAGER.SaveRenderState(D3DRS_COLORVERTEX, TRUE); + + STATEMANAGER.SetTexture(0, m_WaterInstances[((ELTimer_GetMSec() / 70) % 30)].GetTexturePointer()->GetD3DTexture()); + + D3DXMatrixScaling(&matTexTransformWater, m_fWaterTexCoordBase, -m_fWaterTexCoordBase, 0.0f); + D3DXMatrixMultiply(&matTexTransformWater, &m_matViewInverse, &matTexTransformWater); + + STATEMANAGER.SaveTransform(D3DTS_TEXTURE0, &matTexTransformWater); + STATEMANAGER.SaveVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE); + + STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); + + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + + + STATEMANAGER.SetTexture(1,NULL); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + // RenderState + ////////////////////////////////////////////////////////////////////////// + + // Ʒ ִϽŰ... + static float s_fWaterHeightCurrent = 0; + static float s_fWaterHeightBegin = 0; + static float s_fWaterHeightEnd = 0; + static DWORD s_dwLastHeightChangeTime = CTimer::Instance().GetCurrentMillisecond(); + static DWORD s_dwBlendtime = 300; + + // 1.5 + if ((CTimer::Instance().GetCurrentMillisecond() - s_dwLastHeightChangeTime) > s_dwBlendtime) + { + s_dwBlendtime = random_range(1000, 3000); + + if (s_fWaterHeightEnd == 0) + s_fWaterHeightEnd = -random_range(0, 15); + else + s_fWaterHeightEnd = 0; + + s_fWaterHeightBegin = s_fWaterHeightCurrent; + s_dwLastHeightChangeTime = CTimer::Instance().GetCurrentMillisecond(); + } + + s_fWaterHeightCurrent = s_fWaterHeightBegin + (s_fWaterHeightEnd - s_fWaterHeightBegin) * (float) ((CTimer::Instance().GetCurrentMillisecond() - s_dwLastHeightChangeTime) / (float) s_dwBlendtime); + m_matWorldForCommonUse._43 = s_fWaterHeightCurrent; + + m_matWorldForCommonUse._41 = 0.0f; + m_matWorldForCommonUse._42 = 0.0f; + STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matWorldForCommonUse); + + float fFogDistance = __GetFogDistance(); + + std::vector >::iterator i; + + for(i = m_PatchVector.begin();i != m_PatchVector.end(); ++i) + { + if (i->firstsecond); + } + + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + + for(i = m_PatchVector.begin();i != m_PatchVector.end(); ++i) + { + if (i->first>=fFogDistance) + DrawWater(i->second); + } + + // Ŀ z ġ + m_matWorldForCommonUse._43 = 0.0f; + + ////////////////////////////////////////////////////////////////////////// + // RenderState + STATEMANAGER.RestoreVertexShader(); + STATEMANAGER.RestoreTransform(D3DTS_TEXTURE0); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MINFILTER); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MAGFILTER); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MIPFILTER); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSU); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSV); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXCOORDINDEX); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS); + + STATEMANAGER.RestoreRenderState(D3DRS_DIFFUSEMATERIALSOURCE); + STATEMANAGER.RestoreRenderState(D3DRS_COLORVERTEX); + STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE); +} + +void CMapOutdoor::DrawWater(long patchnum) +{ + assert(NULL!=m_pTerrainPatchProxyList); + if (!m_pTerrainPatchProxyList) + return; + + CTerrainPatchProxy& rkTerrainPatchProxy = m_pTerrainPatchProxyList[patchnum]; + + if (!rkTerrainPatchProxy.isUsed()) + return; + + if (!rkTerrainPatchProxy.isWaterExists()) + return; + + CGraphicVertexBuffer* pkVB=rkTerrainPatchProxy.GetWaterVertexBufferPointer(); + if (!pkVB) + return; + + if (!pkVB->GetD3DVertexBuffer()) + return; + + UINT uPriCount=rkTerrainPatchProxy.GetWaterFaceCount(); + if (!uPriCount) + return; + + STATEMANAGER.SetStreamSource(0, pkVB->GetD3DVertexBuffer(), sizeof(SWaterVertex)); + STATEMANAGER.DrawPrimitive(D3DPT_TRIANGLELIST, 0, uPriCount); + + ms_faceCount += uPriCount; +} diff --git a/source/GameLib/MapType.cpp b/source/GameLib/MapType.cpp new file mode 100644 index 0000000..0dde68f --- /dev/null +++ b/source/GameLib/MapType.cpp @@ -0,0 +1,299 @@ +#include "StdAfx.h" +#include "../eterBase/Filename.h" +#include "Property.h" + +float SEnvironmentData::GetFogNearDistance() const +{ + return m_fFogNearDistance; +} + +float SEnvironmentData::GetFogFarDistance() const +{ + return m_fFogFarDistance; +} + +float SPixelPosition_CalculateDistanceSq3d(const TPixelPosition& c_rkPPosLeft, const TPixelPosition& c_rkPPosRight) +{ + float dx=c_rkPPosLeft.x-c_rkPPosRight.x; + float dy=c_rkPPosLeft.y-c_rkPPosRight.y; + float dz=c_rkPPosLeft.z-c_rkPPosRight.z; + + return dx*dx+dy*dy+dz*dz; +} + +namespace prt +{ + +DWORD GetPropertyType(const char * c_szTypeName) +{ + for (DWORD i = 0; i < PROPERTY_TYPE_MAX_NUM; ++i) + { + if (!strcmp(c_szPropertyTypeName[i], c_szTypeName)) + return i; + } + + return PROPERTY_TYPE_NONE; +} + +const char * GetPropertyExtension(DWORD dwType) +{ + if (dwType >= PROPERTY_TYPE_MAX_NUM) + return c_szPropertyExtension[0]; + + return c_szPropertyExtension[dwType]; +} + +const char * IntegerNumberToString(int iNumber) +{ + static char szString[16+1]; + _snprintf(szString, sizeof(szString), "%d", iNumber); + return szString; +} + +const char * FloatNumberToString(float fNumber) +{ + static char szString[16+1]; + _snprintf(szString, sizeof(szString), "%f", fNumber); + return szString; +} + +bool PropertyTreeDataToString(TPropertyTree * pData, CProperty * pProperty) +{ + pProperty->Clear(); + + pProperty->PutString("PropertyType", "Tree"); + pProperty->PutString("PropertyName", pData->strName.c_str()); + + pProperty->PutString("TreeFile", pData->strFileName.c_str()); + pProperty->PutString("TreeSize", FloatNumberToString(pData->fSize)); + pProperty->PutString("TreeVariance", FloatNumberToString(pData->fVariance)); + return true; +} + +bool PropertyTreeStringToData(CProperty * pProperty, TPropertyTree * pData) +{ + const char * c_pszPropertyType; + const char * c_pszPropertyName; + + if (!pProperty->GetString("PropertyType", &c_pszPropertyType)) + return false; + + if (!pProperty->GetString("PropertyName", &c_pszPropertyName)) + return false; + + if (strcmp(c_pszPropertyType, "Tree")) + return false; + + pData->strName = c_pszPropertyName; + + /////////////////////////////////////////////////////////////////////////////////// + + const char * c_pszTreeName; + const char * c_pszTreeSize; + const char * c_pszTreeVariance; + if (!pProperty->GetString("TreeFile", &c_pszTreeName)) + return false; + if (!pProperty->GetString("TreeSize", &c_pszTreeSize)) + return false; + if (!pProperty->GetString("TreeVariance", &c_pszTreeVariance)) + return false; + + pData->strFileName = c_pszTreeName; + pData->fSize = atof(c_pszTreeSize); + pData->fVariance = atof(c_pszTreeVariance); + + return true; +} + +bool PropertyBuildingDataToString(TPropertyBuilding * pData, CProperty * pProperty) +{ + pProperty->Clear(); + + pProperty->PutString("PropertyType", "Building"); + pProperty->PutString("PropertyName", pData->strName.c_str()); + pProperty->PutString("BuildingFile", pData->strFileName.c_str()); + pProperty->PutString("ShadowFlag", IntegerNumberToString(pData->isShadowFlag)); + return true; +} + +bool PropertyBuildingStringToData(CProperty * pProperty, TPropertyBuilding * pData) +{ + const char * c_pszPropertyType; + const char * c_pszPropertyName; + + if (!pProperty->GetString("PropertyType", &c_pszPropertyType)) + return false; + + if (!pProperty->GetString("PropertyName", &c_pszPropertyName)) + return false; + + if (strcmp(c_pszPropertyType, "Building")) + return false; + + pData->strName = c_pszPropertyName; + + /////////////////////////////////////////////////////////////////////////////////// + + const char * c_pszBuildingName; + if (!pProperty->GetString("BuildingFile", &c_pszBuildingName)) + return false; + + pData->strFileName = c_pszBuildingName; + pData->strAttributeDataFileName = CFileNameHelper::NoExtension(pData->strFileName) + ".mdatr"; + + const char * c_pszShadowFlag; + if (!pProperty->GetString("ShadowFlag", &c_pszShadowFlag)) + { + pData->isShadowFlag = FALSE; + } + else + { + pData->isShadowFlag = atoi(c_pszShadowFlag); + } + + return true; +} + + +bool PropertyEffectDataToString(TPropertyEffect * pData, CProperty * pProperty) +{ + pProperty->Clear(); + + pProperty->PutString("PropertyType", "Effect"); + pProperty->PutString("PropertyName", pData->strName.c_str()); + pProperty->PutString("EffectFile", pData->strFileName.c_str()); + return true; +} + +bool PropertyEffectStringToData(CProperty * pProperty, TPropertyEffect * pData) +{ + const char * c_pszPropertyType; + const char * c_pszPropertyName; + + if (!pProperty->GetString("PropertyType", &c_pszPropertyType)) + return false; + + if (!pProperty->GetString("PropertyName", &c_pszPropertyName)) + return false; + + if (strcmp(c_pszPropertyType, "Effect")) + return false; + + pData->strName = c_pszPropertyName; + + /////////////////////////////////////////////////////////////////////////////////// + + const char * c_pszEffectName; + if (!pProperty->GetString("EffectFile", &c_pszEffectName)) + return false; + + pData->strFileName = c_pszEffectName; + + return true; +} + +bool PropertyAmbienceDataToString(TPropertyAmbience * pData, CProperty * pProperty) +{ + pProperty->Clear(); + pProperty->PutString("PropertyType", "Ambience"); + pProperty->PutString("PropertyName", pData->strName.c_str()); + pProperty->PutString("PlayType", pData->strPlayType.c_str()); + pProperty->PutString("PlayInterval", FloatNumberToString(pData->fPlayInterval)); + pProperty->PutString("PlayIntervalVariation", FloatNumberToString(pData->fPlayIntervalVariation)); + pProperty->PutString("MaxVolumeAreaPercentage", FloatNumberToString(pData->fMaxVolumeAreaPercentage)); + + CTokenVector AmbienceSoundVector; + std::vector::iterator itor = pData->AmbienceSoundVector.begin(); + for (; itor != pData->AmbienceSoundVector.end(); ++itor) + { + std::string & rstrToken = *itor; + AmbienceSoundVector.push_back(rstrToken.c_str()); + } + pProperty->PutVector("AmbienceSoundVector", AmbienceSoundVector); + return true; +} + +bool PropertyAmbienceStringToData(CProperty * pProperty, TPropertyAmbience * pData) +{ + const char * c_pszPropertyType; + const char * c_pszPropertyName; + + if (!pProperty->GetString("PropertyType", &c_pszPropertyType)) + return false; + + if (!pProperty->GetString("PropertyName", &c_pszPropertyName)) + return false; + + if (strcmp(c_pszPropertyType, "Ambience")) + return false; + + pData->strName = c_pszPropertyName; + + /////////////////////////////////////////////////////////////////////////////////// + + const char * c_pszPlayType; + const char * c_pszPlayInterval; + const char * c_pszPlayIntervalVariation; + const char * c_pszMaxVolumeAreaPercentage = NULL; + CTokenVector AmbienceSoundVector; + if (!pProperty->GetString("PlayType", &c_pszPlayType)) + return false; + if (!pProperty->GetString("PlayInterval", &c_pszPlayInterval)) + return false; + if (!pProperty->GetString("PlayIntervalVariation", &c_pszPlayIntervalVariation)) + return false; + if (!pProperty->GetString("MaxVolumeAreaPercentage", &c_pszMaxVolumeAreaPercentage)) + { + pData->fMaxVolumeAreaPercentage = 0.0f; + } + if (!pProperty->GetVector("AmbienceSoundVector", AmbienceSoundVector)) + return false; + + pData->strPlayType = c_pszPlayType; + pData->fPlayInterval = atof(c_pszPlayInterval); + pData->fPlayIntervalVariation = atof(c_pszPlayIntervalVariation); + if (c_pszMaxVolumeAreaPercentage) + pData->fMaxVolumeAreaPercentage = atof(c_pszMaxVolumeAreaPercentage); + for (CTokenVector::iterator itor = AmbienceSoundVector.begin(); itor != AmbienceSoundVector.end(); ++itor) + pData->AmbienceSoundVector.push_back(*itor); + + return true; +} + +bool PropertyDungeonBlockDataToString(TPropertyDungeonBlock * pData, CProperty * pProperty) +{ + pProperty->Clear(); + pProperty->PutString("PropertyType", "DungeonBlock"); + pProperty->PutString("PropertyName", pData->strName.c_str()); + pProperty->PutString("DungeonBlockFile", pData->strFileName.c_str()); + return true; +} +bool PropertyDungeonBlockStringToData(CProperty * pProperty, TPropertyDungeonBlock * pData) +{ + const char * c_pszPropertyType; + const char * c_pszPropertyName; + + if (!pProperty->GetString("PropertyType", &c_pszPropertyType)) + return false; + + if (!pProperty->GetString("PropertyName", &c_pszPropertyName)) + return false; + + if (strcmp(c_pszPropertyType, "DungeonBlock")) + return false; + + pData->strName = c_pszPropertyName; + + /////////////////////////////////////////////////////////////////////////////////// + + const char * c_pszDungeonBlockFileName = NULL; + if (!pProperty->GetString("dungeonblockfile", &c_pszDungeonBlockFileName)) + return false; + + pData->strFileName = c_pszDungeonBlockFileName; + pData->strAttributeDataFileName = CFileNameHelper::NoExtension(pData->strFileName) + std::string(".mdatr"); + + return true; +} + +}; // namespace prt; diff --git a/source/GameLib/MapType.h b/source/GameLib/MapType.h new file mode 100644 index 0000000..1a1d01a --- /dev/null +++ b/source/GameLib/MapType.h @@ -0,0 +1,222 @@ +#ifndef __MapType_Header__ +#define __MapType_Header__ + +class CProperty; + +#include "../eterLib/SkyBox.h" +#include "../mileslib/SoundManager.h" + +///////////////////////////////////////////////////////////////// +// Property +namespace prt +{ + enum EPropertyType + { + PROPERTY_TYPE_NONE, + PROPERTY_TYPE_TREE, + PROPERTY_TYPE_BUILDING, + PROPERTY_TYPE_EFFECT, + PROPERTY_TYPE_AMBIENCE, + PROPERTY_TYPE_DUNGEON_BLOCK, + PROPERTY_TYPE_MAX_NUM, + }; + + const char c_szPropertyTypeName[PROPERTY_TYPE_MAX_NUM][32] = + { + "None", + "Tree", + "Building", + "Effect", + "Ambience", + "DungeonBlock" + }; + + const char c_szPropertyExtension[PROPERTY_TYPE_MAX_NUM][16] = + { + ".pr", + ".prt", + ".prb", + ".pre", + ".pra", + ".prd" + }; + + DWORD GetPropertyType(const char * c_szTypeName); + const char * GetPropertyExtension(DWORD dwType); + + struct TPropertyTree + { + std::string strName; + std::string strFileName; + + float fSize; + float fVariance; + }; + + struct TPropertyBuilding + { + std::string strName; + std::string strFileName; + std::string strAttributeDataFileName; + BOOL isShadowFlag; + }; + + struct TPropertyEffect + { + std::string strName; + std::string strFileName; + }; + + enum EAmbiencePlayType + { + AMBIENCE_PLAY_TYPE_ONCE, + AMBIENCE_PLAY_TYPE_STEP, + AMBIENCE_PLAY_TYPE_LOOP, + AMBIENCE_PLAY_TYPE_MAX_NUM, + }; + + const char c_szPlayTypeName[AMBIENCE_PLAY_TYPE_MAX_NUM][8] = + { + "ONCE", + "STEP", + "LOOP", + }; + + struct TPropertyAmbience + { + std::string strName; + std::string strPlayType; + + float fPlayInterval; + float fPlayIntervalVariation; + float fMaxVolumeAreaPercentage; + std::vector AmbienceSoundVector; + }; + + struct TPropertyDungeonBlock + { + std::string strName; + std::string strFileName; + std::string strAttributeDataFileName; + }; + + bool PropertyTreeDataToString(TPropertyTree * pData, CProperty * pProperty); + bool PropertyTreeStringToData(CProperty * pProperty, TPropertyTree * pData); + bool PropertyBuildingDataToString(TPropertyBuilding * pData, CProperty * pProperty); + bool PropertyBuildingStringToData(CProperty * pProperty, TPropertyBuilding * pData); + bool PropertyEffectDataToString(TPropertyEffect * pData, CProperty * pProperty); + bool PropertyEffectStringToData(CProperty * pProperty, TPropertyEffect * pData); + bool PropertyAmbienceDataToString(TPropertyAmbience * pData, CProperty * pProperty); + bool PropertyAmbienceStringToData(CProperty * pProperty, TPropertyAmbience * pData); + bool PropertyDungeonBlockDataToString(TPropertyDungeonBlock * pData, CProperty * pProperty); + bool PropertyDungeonBlockStringToData(CProperty * pProperty, TPropertyDungeonBlock * pData); +}; +///////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////// +// Environment +// +enum +{ + ENV_DIRLIGHT_BACKGROUND, + ENV_DIRLIGHT_CHARACTER, + ENV_DIRLIGHT_NUM +}; + +typedef struct SEnvironmentData +{ + // Light + BOOL bDirLightsEnable[ENV_DIRLIGHT_NUM]; + D3DLIGHT8 DirLights[ENV_DIRLIGHT_NUM]; + + // Material + D3DMATERIAL8 Material; + + // Fog + BOOL bFogEnable; + BOOL bDensityFog; + + float m_fFogNearDistance; + float m_fFogFarDistance; + + float GetFogNearDistance() const; + float GetFogFarDistance() const; + + D3DXCOLOR FogColor; + + // Filtering + BOOL bFilteringEnable; + D3DXCOLOR FilteringColor; + BYTE byFilteringAlphaSrc; + BYTE byFilteringAlphaDest; + + // Wind + float fWindStrength; + float fWindRandom; + + // SkyBox + D3DXVECTOR3 v3SkyBoxScale; + BOOL bSkyBoxTextureRenderMode; + + BYTE bySkyBoxGradientLevelUpper; + BYTE bySkyBoxGradientLevelLower; + + std::string strSkyBoxFaceFileName[6]; //order : front/back/left/right/top/bottom + + + D3DXVECTOR2 v2CloudScale; + float fCloudHeight; + D3DXVECTOR2 v2CloudTextureScale; + D3DXVECTOR2 v2CloudSpeed; + std::string strCloudTextureFileName; + TGradientColor CloudGradientColor; + + std::vector SkyBoxGradientColorVector; + + // LensFlare + BOOL bLensFlareEnable; + D3DXCOLOR LensFlareBrightnessColor; + float fLensFlareMaxBrightness; + + BOOL bMainFlareEnable; + std::string strMainFlareTextureFileName; + float fMainFlareSize; + + BOOL bReserve; // ܺο ġ +} TEnvironmentData; + +typedef std::map TEnvironmentDataMap; +///////////////////////////////////////////////////////////////// + +typedef struct SScreenPosition { + int x; + int y; +} TScreenPosition; + +typedef D3DXVECTOR3 TPixelPosition; + +float SPixelPosition_CalculateDistanceSq3d(const TPixelPosition& c_rkPPosLeft, const TPixelPosition& c_rkPPosRight); + +typedef struct SCellPosition +{ + SCellPosition() + { + this->x = 0; + this->y = 0; + } + + SCellPosition(int x, int y) + { + this->x = x; + this->y = y; + } + + int x, y; +} TCellPosition; + +const int c_Section_xAttributeCellSize = 50; +const int c_Section_yAttributeCellSize = 50; +const int c_Section_xCellSize = 100; +const int c_Section_yCellSize = 100; + +#endif \ No newline at end of file diff --git a/source/GameLib/MapUtil.cpp b/source/GameLib/MapUtil.cpp new file mode 100644 index 0000000..d3a9098 --- /dev/null +++ b/source/GameLib/MapUtil.cpp @@ -0,0 +1,306 @@ +#include "StdAfx.h" +#include "MapUtil.h" + +void Environment_Init(SEnvironmentData& envData) +{ + for (int i = 0; i < ENV_DIRLIGHT_NUM; ++i) + { + envData.bDirLightsEnable[i] = false; + envData.DirLights[i].Type = D3DLIGHT_DIRECTIONAL; + envData.DirLights[i].Direction = D3DXVECTOR3(0.5f, 0.5f, -0.5f); + envData.DirLights[i].Position = D3DXVECTOR3(0.0f, 0.0f, 0.0f); + envData.DirLights[i].Specular = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); + envData.DirLights[i].Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); + envData.DirLights[i].Ambient = D3DXCOLOR(0.5f, 0.5f, 0.5f, 1.0f); + envData.DirLights[i].Range = 0.0f; // Used by Point Light & Spot Light + envData.DirLights[i].Falloff = 1.0f; // Used by Spot Light + envData.DirLights[i].Theta = 0.0f; // Used by Spot Light + envData.DirLights[i].Phi = 0.0f; // Used by Spot Light + envData.DirLights[i].Attenuation0 = 0.0f; + envData.DirLights[i].Attenuation1 = 1.0f; + envData.DirLights[i].Attenuation2 = 0.0f; + } + + envData.Material.Diffuse = D3DXCOLOR(0.8f, 0.8f, 0.8f, 1.0f); + envData.Material.Ambient = D3DXCOLOR(0.8f, 0.8f, 0.8f, 1.0f); + envData.Material.Emissive = D3DXCOLOR(0.8f, 0.8f, 0.8f, 1.0f); + envData.Material.Specular = D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f); + envData.Material.Power = 0.0f; + + envData.bFogEnable = FALSE; + envData.bDensityFog = FALSE; + envData.m_fFogNearDistance = 25600.0f * 0.5f; + envData.m_fFogFarDistance = 25600.0f * 0.7f; + envData.FogColor = D3DXCOLOR(0.5f, 0.5f, 0.5f, 1.0f); + + envData.bFilteringEnable = FALSE; + envData.FilteringColor = D3DXCOLOR(0.3f, 0.1f, 0.1f, 0.0f); + envData.byFilteringAlphaSrc = D3DBLEND_ONE; + envData.byFilteringAlphaDest = D3DBLEND_ONE; + + envData.fWindStrength = 0.2f; + envData.fWindRandom = 0.0f; + + envData.v3SkyBoxScale = D3DXVECTOR3(3500.0f, 3500.0f, 3500.0f); + envData.bySkyBoxGradientLevelUpper = 0; + envData.bySkyBoxGradientLevelLower = 0; + envData.bSkyBoxTextureRenderMode = FALSE; + + envData.v2CloudScale = D3DXVECTOR2(200000.0f, 200000.0f); + envData.fCloudHeight = 30000.0f; + envData.v2CloudTextureScale = D3DXVECTOR2(4.0f, 4.0f); + envData.v2CloudSpeed = D3DXVECTOR2(0.001f, 0.001f); + envData.strCloudTextureFileName = ""; + envData.CloudGradientColor.m_FirstColor = .0f; + envData.CloudGradientColor.m_SecondColor = .0f; + + envData.SkyBoxGradientColorVector.clear(); + + envData.bLensFlareEnable = FALSE; + envData.LensFlareBrightnessColor = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); + envData.fLensFlareMaxBrightness = 1.0f; + + envData.bMainFlareEnable = FALSE; + envData.strMainFlareTextureFileName = ""; + envData.fMainFlareSize = 0.2f; + + envData.bReserve = FALSE; +} + +bool Environment_Load(SEnvironmentData& envData, const char* envFileName) +{ + CTextFileLoader textLoader; + + if (!textLoader.Load(envFileName)) + return false; + + textLoader.SetTop(); + + textLoader.GetTokenBoolean("reserved", &envData.bReserve); + + if (textLoader.SetChildNode("directionallight")) + { + D3DVECTOR v3Dir; + textLoader.GetTokenDirection("direction", &v3Dir); + + if (textLoader.SetChildNode("background")) + { + envData.DirLights[ENV_DIRLIGHT_BACKGROUND].Direction = v3Dir; + textLoader.GetTokenBoolean("enable", &envData.bDirLightsEnable[ENV_DIRLIGHT_BACKGROUND]); + textLoader.GetTokenColor("diffuse", &envData.DirLights[ENV_DIRLIGHT_BACKGROUND].Diffuse); + textLoader.GetTokenColor("ambient", &envData.DirLights[ENV_DIRLIGHT_BACKGROUND].Ambient); + textLoader.SetParentNode(); + } + + if (textLoader.SetChildNode("character")) + { + envData.DirLights[ENV_DIRLIGHT_CHARACTER].Direction = v3Dir; + textLoader.GetTokenBoolean("enable", &envData.bDirLightsEnable[ENV_DIRLIGHT_CHARACTER]); + textLoader.GetTokenColor("diffuse", &envData.DirLights[ENV_DIRLIGHT_CHARACTER].Diffuse); + textLoader.GetTokenColor("ambient", &envData.DirLights[ENV_DIRLIGHT_CHARACTER].Ambient); + textLoader.SetParentNode(); + } + + textLoader.SetParentNode(); + } + + if (textLoader.SetChildNode("material")) + { + textLoader.GetTokenColor("diffuse", &envData.Material.Diffuse); + textLoader.GetTokenColor("ambient", &envData.Material.Ambient); + textLoader.GetTokenColor("emissive", &envData.Material.Emissive); + textLoader.SetParentNode(); + } + + if (textLoader.SetChildNode("fog")) + { + textLoader.GetTokenBoolean("enable", &envData.bFogEnable); + textLoader.GetTokenBoolean("isdensity", &envData.bDensityFog); + textLoader.GetTokenFloat("neardistance", &envData.m_fFogNearDistance); + textLoader.GetTokenFloat("fardistance", &envData.m_fFogFarDistance); + textLoader.GetTokenColor("color", &envData.FogColor); + textLoader.SetParentNode(); + } + + if (textLoader.SetChildNode("filter")) + { + textLoader.GetTokenBoolean("enable", (BOOL *) &envData.bFilteringEnable); + textLoader.GetTokenColor("color", &envData.FilteringColor); + textLoader.GetTokenByte("alphasrc", &envData.byFilteringAlphaSrc); + textLoader.GetTokenByte("alphadest", &envData.byFilteringAlphaDest); + textLoader.SetParentNode(); + } + + if (textLoader.SetChildNode("skybox")) + { + textLoader.GetTokenBoolean("btexturerendermode", (BOOL *) &envData.bSkyBoxTextureRenderMode); + textLoader.GetTokenVector3("scale", &envData.v3SkyBoxScale); + textLoader.GetTokenByte("gradientlevelupper", &envData.bySkyBoxGradientLevelUpper); + textLoader.GetTokenByte("gradientlevellower", &envData.bySkyBoxGradientLevelLower); + + textLoader.GetTokenString("frontfacefilename", &envData.strSkyBoxFaceFileName[0]); + textLoader.GetTokenString("backfacefilename", &envData.strSkyBoxFaceFileName[1]); + textLoader.GetTokenString("leftfacefilename", &envData.strSkyBoxFaceFileName[2]); + textLoader.GetTokenString("rightfacefilename", &envData.strSkyBoxFaceFileName[3]); + textLoader.GetTokenString("topfacefilename", &envData.strSkyBoxFaceFileName[4]); + textLoader.GetTokenString("bottomfacefilename", &envData.strSkyBoxFaceFileName[5]); + + + textLoader.GetTokenVector2("cloudscale", &envData.v2CloudScale); + textLoader.GetTokenFloat("cloudheight", &envData.fCloudHeight); + textLoader.GetTokenVector2("cloudtexturescale", &envData.v2CloudTextureScale); + textLoader.GetTokenVector2("cloudspeed", &envData.v2CloudSpeed); + textLoader.GetTokenString("cloudtexturefilename", &envData.strCloudTextureFileName); + + CTokenVector * pTokenVectorCloudColor; + if(textLoader.GetTokenVector("cloudcolor", &pTokenVectorCloudColor)) + if ( 0 == pTokenVectorCloudColor->size()%8) + { + envData.CloudGradientColor.m_FirstColor.r = atof(pTokenVectorCloudColor->at(0).c_str()); + envData.CloudGradientColor.m_FirstColor.g = atof(pTokenVectorCloudColor->at(1).c_str()); + envData.CloudGradientColor.m_FirstColor.b = atof(pTokenVectorCloudColor->at(2).c_str()); + envData.CloudGradientColor.m_FirstColor.a = atof(pTokenVectorCloudColor->at(3).c_str()); + + envData.CloudGradientColor.m_SecondColor.r = atof(pTokenVectorCloudColor->at(4).c_str()); + envData.CloudGradientColor.m_SecondColor.g = atof(pTokenVectorCloudColor->at(5).c_str()); + envData.CloudGradientColor.m_SecondColor.b = atof(pTokenVectorCloudColor->at(6).c_str()); + envData.CloudGradientColor.m_SecondColor.a = atof(pTokenVectorCloudColor->at(7).c_str()); + } + + BYTE byGradientCount = envData.bySkyBoxGradientLevelUpper+envData.bySkyBoxGradientLevelLower; + CTokenVector * pTokenVector; + if (textLoader.GetTokenVector("gradient", &pTokenVector)) + if (0 == pTokenVector->size()%8) + if (byGradientCount == pTokenVector->size()/8) + { + envData.SkyBoxGradientColorVector.clear(); + envData.SkyBoxGradientColorVector.resize(byGradientCount); + for (DWORD i = 0; i < byGradientCount; ++i) + { + envData.SkyBoxGradientColorVector[i].m_FirstColor.r = atof(pTokenVector->at(i*8+0).c_str()); + envData.SkyBoxGradientColorVector[i].m_FirstColor.g = atof(pTokenVector->at(i*8+1).c_str()); + envData.SkyBoxGradientColorVector[i].m_FirstColor.b = atof(pTokenVector->at(i*8+2).c_str()); + envData.SkyBoxGradientColorVector[i].m_FirstColor.a = atof(pTokenVector->at(i*8+3).c_str()); + + envData.SkyBoxGradientColorVector[i].m_SecondColor.r = atof(pTokenVector->at(i*8+4).c_str()); + envData.SkyBoxGradientColorVector[i].m_SecondColor.g = atof(pTokenVector->at(i*8+5).c_str()); + envData.SkyBoxGradientColorVector[i].m_SecondColor.b = atof(pTokenVector->at(i*8+6).c_str()); + envData.SkyBoxGradientColorVector[i].m_SecondColor.a = atof(pTokenVector->at(i*8+7).c_str()); + } + } + + textLoader.SetParentNode(); + } + + if (textLoader.SetChildNode("lensflare")) + { + textLoader.GetTokenBoolean("enable", &envData.bLensFlareEnable); + textLoader.GetTokenColor("brightnesscolor", &envData.LensFlareBrightnessColor); + textLoader.GetTokenFloat("maxbrightness", &envData.fLensFlareMaxBrightness); + textLoader.GetTokenBoolean("mainflareenable", &envData.bMainFlareEnable); + textLoader.GetTokenString("mainflaretexturefilename", &envData.strMainFlareTextureFileName); + textLoader.GetTokenFloat("mainflaresize", &envData.fMainFlareSize); + + textLoader.SetParentNode(); + } + return true; +} + +void GetInterpolatedPosition(float curPositionRate, TPixelPosition * PixelPosition) +{ +} + +float GetLinearInterpolation(float begin, float end, float curRate) +{ + return (end - begin) * curRate + begin; +} + +void PixelPositionToAttributeCellPosition(TPixelPosition PixelPosition, TCellPosition * pAttrCellPosition) +{ + pAttrCellPosition->x = PixelPosition.x / c_Section_xAttributeCellSize; + pAttrCellPosition->y = PixelPosition.y / c_Section_yAttributeCellSize; +} + +void AttributeCellPositionToPixelPosition(TCellPosition AttrCellPosition, TPixelPosition * pPixelPosition) +{ + pPixelPosition->x = AttrCellPosition.x * c_Section_xAttributeCellSize; + pPixelPosition->y = AttrCellPosition.y * c_Section_yAttributeCellSize; +} + +float GetPixelPositionDistance(const TPixelPosition & c_rsrcPosition, const TPixelPosition & c_rdstPosition) +{ + int idx = c_rsrcPosition.x - c_rdstPosition.x; + int idy = c_rsrcPosition.y - c_rdstPosition.y; + + return sqrtf(float(idx*idx + idy*idy)); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +CEaseOutInterpolation::CEaseOutInterpolation() +{ + Initialize(); +} + +CEaseOutInterpolation::~CEaseOutInterpolation() +{ +} + +void CEaseOutInterpolation::Initialize() +{ + m_fRemainingTime = 0.0f; + m_fValue = 0.0f; + m_fSpeed = 0.0f; + m_fAcceleration = 0.0f; + m_fStartValue = 0.0f; + m_fLastValue = 0.0f; +} + + +BOOL CEaseOutInterpolation::Setup(float fStart, float fEnd, float fTime) +{ + //for safety + if( fabs(fTime) < FLT_EPSILON ) + { + fTime = 0.01f; + } + + m_fValue = fStart; + m_fStartValue = fStart; + m_fLastValue = fStart; + + m_fSpeed = (2.0f * (fEnd - fStart)) / fTime; + m_fAcceleration = 2.0f * (fEnd - fStart) / (fTime * fTime) - 2.0f * m_fSpeed / fTime; + m_fRemainingTime = fTime; + + return TRUE; +} + +void CEaseOutInterpolation::Interpolate(float fElapsedTime) +{ + m_fLastValue = m_fValue; + + m_fRemainingTime -= fElapsedTime; + m_fSpeed += m_fAcceleration * fElapsedTime; + m_fValue += m_fSpeed * fElapsedTime; + + if (!isPlaying()) + { + m_fValue = 0.0f; + m_fLastValue = 0.0f; + } +} + +BOOL CEaseOutInterpolation::isPlaying() +{ + return m_fRemainingTime > 0.0f; +} + +float CEaseOutInterpolation::GetValue() +{ + return m_fValue; +} + +float CEaseOutInterpolation::GetChangingValue() +{ + return m_fValue - m_fLastValue; +} \ No newline at end of file diff --git a/source/GameLib/MapUtil.h b/source/GameLib/MapUtil.h new file mode 100644 index 0000000..1204dc1 --- /dev/null +++ b/source/GameLib/MapUtil.h @@ -0,0 +1,38 @@ +#pragma once + +void Environment_Init(SEnvironmentData& envData); +bool Environment_Load(SEnvironmentData& envData, const char* envFileName); + + +void GetInterpolatedPosition(float curPositionRate, TPixelPosition * PixelPosition); +float GetLinearInterpolation(float begin, float end, float curRate); + +void PixelPositionToAttributeCellPosition(TPixelPosition PixelPosition, TCellPosition * pAttrCellPosition); +void AttributeCellPositionToPixelPosition(TCellPosition AttrCellPosition, TPixelPosition * pPixelPosition); + +float GetPixelPositionDistance(const TPixelPosition & c_rsrcPosition, const TPixelPosition & c_rdstPosition); + +class CEaseOutInterpolation +{ + public: + CEaseOutInterpolation(); + virtual ~CEaseOutInterpolation(); + + void Initialize(); + + BOOL Setup(float fStart, float fEnd, float fTime); + void Interpolate(float fElapsedTime); + BOOL isPlaying(); + + float GetValue(); + float GetChangingValue(); + + protected: + float m_fRemainingTime; + float m_fValue; + float m_fSpeed; + float m_fAcceleration; + + float m_fStartValue; + float m_fLastValue; +}; diff --git a/source/GameLib/MonsterAreaInfo.cpp b/source/GameLib/MonsterAreaInfo.cpp new file mode 100644 index 0000000..e7f0054 --- /dev/null +++ b/source/GameLib/MonsterAreaInfo.cpp @@ -0,0 +1,148 @@ +// MonsterAreaInfo.cpp: implementation of the CMonsterAreaInfo class. +// +////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "MonsterAreaInfo.h" + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CMonsterAreaInfo::CMonsterAreaInfo() +{ + Clear(); +} + +CMonsterAreaInfo::~CMonsterAreaInfo() +{ + Clear(); +} + +void CMonsterAreaInfo::Clear() +{ + SetOrigin(-1, -1); + SetSize(-1, -1); + RemoveAllMonsters(); +} + +void CMonsterAreaInfo::SetOrigin(long lOriginX, long lOriginY) +{ + m_lOriginX = lOriginX; + m_lOriginY = lOriginY; + SetLRTB(); +} + +void CMonsterAreaInfo::SetSize(long lSizeX, long lSizeY) +{ + m_lSizeX = lSizeX; + m_lSizeY = lSizeY; + SetLRTB(); +} + +void CMonsterAreaInfo::GetOrigin(long * plOriginX, long * plOriginY) +{ + *plOriginX = m_lOriginX; + *plOriginY = m_lOriginY; +} + +void CMonsterAreaInfo::GetSize(long * plSizeX, long * plSizeY) +{ + *plSizeX = m_lSizeX; + *plSizeY = m_lSizeY; +} + +void CMonsterAreaInfo::SetLRTB() +{ + m_lLeft = m_lOriginX - m_lSizeX; + m_lTop = m_lOriginY - m_lSizeY; + m_lRight = m_lOriginX + m_lSizeX; + m_lBottom = m_lOriginY + m_lSizeY; +} + +void CMonsterAreaInfo::SetMonsterCount(DWORD dwCount) +{ + m_dwMonsterCount = dwCount; + + if (m_TempMonsterPosVector.size() == dwCount) + return; + + m_TempMonsterPosVector.clear(); + m_TempMonsterPosVector.resize(dwCount); + + for (DWORD dwI = 0; dwI < dwCount; ++dwI) + { + m_TempMonsterPosVector[dwI].x = (float)random_range(m_lLeft, m_lRight); + m_TempMonsterPosVector[dwI].y = (float)random_range(m_lTop, m_lBottom); + } +} + +void CMonsterAreaInfo::SetMonsterDirection(EMonsterDir eMonsterDir) +{ + m_eMonsterDir = eMonsterDir; + D3DXMATRIX matRotation; + D3DXVECTOR3 v3Direction(0.0f, 1.0f, 0.0f); + float fDegree = 0.0f; + switch(m_eMonsterDir) + { + case DIR_RANDOM: + fDegree = (float) random_range(0, 7) * 45.0f; + break; + case DIR_NORTH: + fDegree = 0.0f; + break; + case DIR_NORTHEAST: + fDegree = 45.0f; + break; + case DIR_EAST: + fDegree = 90.0f; + break; + case DIR_SOUTHEAST: + fDegree = 135.0f; + break; + case DIR_SOUTH: + fDegree = 180.0f; + break; + case DIR_SOUTHWEST: + fDegree = 225.0f; + break; + case DIR_WEST: + fDegree = 270.0f; + break; + case DIR_NORTHWEST: + fDegree = 315.0f; + break; + } + D3DXMatrixRotationZ(&matRotation, -D3DXToRadian(fDegree)); + D3DXVec3TransformCoord(&v3Direction, &v3Direction, &matRotation); + m_v2Monsterdirection.x = v3Direction.x; + m_v2Monsterdirection.y = v3Direction.y; + D3DXVec2Normalize(&m_v2Monsterdirection, &m_v2Monsterdirection); +} + +void CMonsterAreaInfo::RemoveAllMonsters() +{ + SetMonsterAreaInfoType(MONSTERAREAINFOTYPE_INVALID); + + SetMonsterGroupID(0); + + m_strGroupName.assign("̸"); + m_strLeaderName.assign("̸"); + SetMonsterGroupFollowerCount(0); + + SetMonsterVID(0); + m_strMonsterName.assign("̸"); + + SetMonsterCount(0); + SetMonsterDirection(DIR_NORTH); + + m_TempMonsterPosVector.clear(); +} + +D3DXVECTOR2 CMonsterAreaInfo::GetTempMonsterPos(DWORD dwIndex) +{ + if (dwIndex >= m_TempMonsterPosVector.size()) + return D3DXVECTOR2(0.0f, 0.0f); + return m_TempMonsterPosVector[dwIndex]; +} + diff --git a/source/GameLib/MonsterAreaInfo.h b/source/GameLib/MonsterAreaInfo.h new file mode 100644 index 0000000..8f31472 --- /dev/null +++ b/source/GameLib/MonsterAreaInfo.h @@ -0,0 +1,125 @@ +// MonsterAreaInfo.h: interface for the CMonsterAreaInfo class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_MONSTERAREAINFO_H__B177E257_2EB2_4CE5_89D3_D06B5618BE1B__INCLUDED_) +#define AFX_MONSTERAREAINFO_H__B177E257_2EB2_4CE5_89D3_D06B5618BE1B__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +class CMonsterAreaInfo +{ +public: + enum EMonsterAreaInfoType + { + MONSTERAREAINFOTYPE_INVALID, + MONSTERAREAINFOTYPE_MONSTER, + MONSTERAREAINFOTYPE_GROUP, + }; + enum EMonsterDir + { + DIR_RANDOM = 0, + DIR_NORTH, + DIR_NORTHEAST, + DIR_EAST, + DIR_SOUTHEAST, + DIR_SOUTH, + DIR_SOUTHWEST, + DIR_WEST, + DIR_NORTHWEST + }; + + CMonsterAreaInfo(); + virtual ~CMonsterAreaInfo(); + + void SetID(DWORD dwID) { m_dwID = dwID; } + DWORD GetID() { return m_dwID; } + + void Clear(); + + // + void SetOrigin(long lOriginX, long lOriginY); + void GetOrigin(long * plOriginX, long * plOriginY); + + void SetSize(long lSizeX, long lSizeY); + void GetSize(long * plSizeX, long * plSizeY); + + long GetLeft() { return m_lLeft; } + long GetTop() { return m_lTop; } + long GetRight() { return m_lRight; } + long GetBottom() { return m_lBottom; } + +public: + void SetMonsterAreaInfoType(EMonsterAreaInfoType eMonsterAreaInfoType) { m_eMonsterAreaInfoType = eMonsterAreaInfoType; } + EMonsterAreaInfoType GetMonsterAreaInfoType() { return m_eMonsterAreaInfoType; } + +public: + void SetMonsterGroupID(DWORD dwGroupID) { m_dwGroupID = dwGroupID;} + void SetMonsterGroupName(std::string strGroupName) { m_strGroupName = strGroupName; } + void SetMonsterGroupLeaderName(std::string strGroupLeaderName) { m_strLeaderName = strGroupLeaderName; } + void SetMonsterGroupFollowerCount(DWORD dwFollowerCount) { m_dwFollowerCount = dwFollowerCount; } + + DWORD GetMonsterGroupID() { return m_dwGroupID; } + std::string GetMonsterGroupName() { return m_strGroupName; } + std::string GetMonsterGroupLeaderName() { return m_strLeaderName; } + DWORD GetMonsterGroupFollowerCount() { return m_dwFollowerCount; } + +public: + void SetMonsterName(std::string strMonsterName) { m_strMonsterName = strMonsterName; } + void SetMonsterVID(DWORD dwVID) { m_dwVID = dwVID; } + + std::string GetMonsterName() { return m_strMonsterName; } + DWORD GetMonsterVID() { return m_dwVID; } + +public: + void SetMonsterCount(DWORD dwCount); + void SetMonsterDirection(EMonsterDir eMonsterDir); + void RemoveAllMonsters(); + + DWORD GetMonsterCount() { return m_dwMonsterCount; } + EMonsterDir GetMonsterDir() { return m_eMonsterDir; } + D3DXVECTOR2 GetMonsterDirVector() { return m_v2Monsterdirection; } + D3DXVECTOR2 GetTempMonsterPos(DWORD dwIndex); + +protected: + void SetLRTB(); + +protected: + EMonsterAreaInfoType m_eMonsterAreaInfoType; + + // Group Type + DWORD m_dwGroupID; + std::string m_strGroupName; + std::string m_strLeaderName; + DWORD m_dwFollowerCount; + + // Monster Type + DWORD m_dwVID; + std::string m_strMonsterName; + + // + DWORD m_dwMonsterCount; + EMonsterDir m_eMonsterDir; + D3DXVECTOR2 m_v2Monsterdirection; + + DWORD m_dwID; + + long m_lOriginX; + long m_lOriginY; + long m_lSizeX; + long m_lSizeY; + + long m_lLeft; + long m_lRight; + long m_lTop; + long m_lBottom; + + std::vector m_TempMonsterPosVector; +}; + +typedef std::vector TMonsterAreaInfoPtrVector; +typedef TMonsterAreaInfoPtrVector::iterator TMonsterAreaInfoPtrVectorIterator; + +#endif // !defined(AFX_MONSTERAREAINFO_H__B177E257_2EB2_4CE5_89D3_D06B5618BE1B__INCLUDED_) diff --git a/source/GameLib/PhysicsObject.cpp b/source/GameLib/PhysicsObject.cpp new file mode 100644 index 0000000..2373ce3 --- /dev/null +++ b/source/GameLib/PhysicsObject.cpp @@ -0,0 +1,177 @@ +#include "StdAfx.h" +#include "PhysicsObject.h" + +const float c_fFrameTime = 0.02f; +const float EPSILON = 0.001f; + +IPhysicsWorld* IPhysicsWorld::ms_pWorld = NULL; +IObjectManager* IObjectManager::ms_ObjManager = NULL; + +void CPhysicsObject::Update(float fElapsedTime) +{ + if (m_xPushingPosition.isPlaying()) + m_xPushingPosition.Interpolate(fElapsedTime); + if (m_yPushingPosition.isPlaying()) + m_yPushingPosition.Interpolate(fElapsedTime); +} + +void CPhysicsObject::Accumulate(D3DXVECTOR3 * pv3Position) +{ + // If object is moving, give minor power to object. + float fForce = 0.0f; + + if (fabs(m_v3Velocity.x) < EPSILON || + fabs(m_v3Velocity.y) < EPSILON || + fabs(m_v3Velocity.z) < EPSILON ) + { + fForce -= (m_fMass * m_fFriction); + } + + m_v3Acceleration = m_v3Direction * (fForce / m_fMass); + m_v3Velocity += m_v3Acceleration; + if (m_v3Velocity.x * m_v3Direction.x < EPSILON) + { + m_v3Velocity.x = 0.0f; + m_v3Direction.x = 0.0f; + } + if (m_v3Velocity.y * m_v3Direction.y < EPSILON) + { + m_v3Velocity.y = 0.0f; + m_v3Direction.y = 0.0f; + } + if (m_v3Velocity.z * m_v3Direction.z < EPSILON) + { + m_v3Velocity.z = 0.0f; + m_v3Direction.z = 0.0f; + } + + pv3Position->x += m_v3Velocity.x; + pv3Position->y += m_v3Velocity.y; + pv3Position->z += m_v3Velocity.z; +} + +void CPhysicsObject::IncreaseExternalForce(const D3DXVECTOR3 & c_rvBasePosition, float fForce) +{ + // Accumulate Acceleration by External Force + m_v3Acceleration = m_v3Direction * (fForce / m_fMass); + m_v3Velocity = m_v3Acceleration; +/* + Tracenf("force %f, mass %f, accel (%f, %f, %f)", fForce, m_fMass, + m_v3Acceleration.x, + m_v3Acceleration.y, + m_v3Acceleration.z); +*/ + // NOTE : ġ صд. ٵ 100 ũٸ? ; + const int LoopValue = 100; + D3DXVECTOR3 v3Movement(0.0f, 0.0f, 0.0f); + + for(int i = 0; i < LoopValue; ++i) + { + Accumulate(&v3Movement); + + // VICTIM_COLLISION_TEST + IPhysicsWorld* pWorld = IPhysicsWorld::GetPhysicsWorld(); + if (pWorld) + { + if (pWorld->isPhysicalCollision(c_rvBasePosition + v3Movement)) + { + Initialize(); + return; + + //for (float fRatio = 0.0f; fRatio < 1.0f; fRatio += 0.1f) + //{ + // // ϰ üũѴ + // if (pWorld->isPhysicalCollision(c_rvBasePosition + v3Movement * fRatio)) + // { + // v3Movement = D3DXVECTOR3 (0.0f, 0.0f, 0.0f); + // break; + // } + //} + //break; + } + } + // VICTIM_COLLISION_TEST_END + + if (fabs(m_v3Velocity.x) < EPSILON && + fabs(m_v3Velocity.y) < EPSILON && + fabs(m_v3Velocity.z) < EPSILON ) + break; + } + + SetLastPosition(v3Movement, float(LoopValue) * c_fFrameTime); + + if( m_pActorInstance ) + { + IObjectManager* pObjectManager = IObjectManager::GetObjectManager(); + pObjectManager->AdjustCollisionWithOtherObjects( m_pActorInstance ); + } +} + +void CPhysicsObject::SetLastPosition(const TPixelPosition & c_rPosition, float fBlendingTime) +{ + m_v3LastPosition.x = float(c_rPosition.x); + m_v3LastPosition.y = float(c_rPosition.y); + m_v3LastPosition.z = float(c_rPosition.z); + m_xPushingPosition.Setup(0.0f, c_rPosition.x, fBlendingTime); + m_yPushingPosition.Setup(0.0f, c_rPosition.y, fBlendingTime); +} + +void CPhysicsObject::GetLastPosition(TPixelPosition * pPosition) +{ + pPosition->x = (m_v3LastPosition.x); + pPosition->y = (m_v3LastPosition.y); + pPosition->z = (m_v3LastPosition.z); +} + +void CPhysicsObject::SetDirection(const D3DXVECTOR3 & c_rv3Direction) +{ + m_v3Direction.x = c_rv3Direction.x; + m_v3Direction.y = c_rv3Direction.y; + m_v3Direction.z = c_rv3Direction.z; +} + +float CPhysicsObject::GetXMovement() +{ + return m_xPushingPosition.GetChangingValue(); +} + +float CPhysicsObject::GetYMovement() +{ + return m_yPushingPosition.GetChangingValue(); +} + +bool CPhysicsObject::isBlending() +{ + // NOTE : IncreaseExternalForce() и óΰ? + if (0.0f != D3DXVec3Length(&m_v3Velocity)) + return true; + + // NOTE : SetLastPosition() и óΰ? + if (m_xPushingPosition.isPlaying() || + m_yPushingPosition.isPlaying()) + return true; + + return false; +} + +void CPhysicsObject::Initialize() +{ + m_fMass = 1.0f; + m_fFriction = 0.3f; + m_v3Direction = D3DXVECTOR3(0.0f, 0.0f, 0.0f); + m_v3Acceleration = D3DXVECTOR3(0.0f, 0.0f, 0.0f); + m_v3Velocity = D3DXVECTOR3(0.0f, 0.0f, 0.0f); + m_v3LastPosition = D3DXVECTOR3(0.0f, 0.0f, 0.0f); + + m_xPushingPosition.Initialize(); + m_yPushingPosition.Initialize(); +} + +CPhysicsObject::CPhysicsObject() +{ + m_pActorInstance = NULL; +} + +CPhysicsObject::~CPhysicsObject() +{ +} diff --git a/source/GameLib/PhysicsObject.h b/source/GameLib/PhysicsObject.h new file mode 100644 index 0000000..302e51b --- /dev/null +++ b/source/GameLib/PhysicsObject.h @@ -0,0 +1,99 @@ +#pragma once + +#include "MapUtil.h" + +class IPhysicsWorld +{ +public: + IPhysicsWorld() + { + assert(ms_pWorld == NULL); + ms_pWorld = this; + } + + virtual ~IPhysicsWorld() + { + if (this == ms_pWorld) + ms_pWorld = NULL; + } + + static IPhysicsWorld* GetPhysicsWorld() + { + return ms_pWorld; + } + + virtual bool isPhysicalCollision(const D3DXVECTOR3 & c_rvCheckPosition) = 0; + +private: + static IPhysicsWorld* ms_pWorld; +}; + +class CActorInstance; +//NOTE : ȵ Dependency Inversion interface ϱ ؼ ̹Ĵ +// 踦 Ѵٸ world live object ݴ base project (gamelib̳ base project ؾ Ѵ ) +class IObjectManager +{ +public: + IObjectManager() + { + assert(ms_ObjManager == NULL); + ms_ObjManager = this; + } + + virtual ~IObjectManager() + { + if (this == ms_ObjManager) + ms_ObjManager = NULL; + } + + static IObjectManager* GetObjectManager() + { + return ms_ObjManager; + } + + virtual void AdjustCollisionWithOtherObjects(CActorInstance* pInst ) = 0; + +private: + static IObjectManager* ms_ObjManager; +}; + +class CPhysicsObject +{ + public: + CPhysicsObject(); + virtual ~CPhysicsObject(); + + void Initialize(); + + void Update(float fElapsedTime); + + bool isBlending(); + + void SetDirection(const D3DXVECTOR3 & c_rv3Direction); + void IncreaseExternalForce(const D3DXVECTOR3 & c_rvBasePosition, float fForce); + void SetLastPosition(const TPixelPosition & c_rPosition, float fBlendingTime); + void GetLastPosition(TPixelPosition * pPosition); + + float GetXMovement(); + float GetYMovement(); + void ClearSavingMovement(); + + void SetActorInstance( CActorInstance* pInst ) { m_pActorInstance = pInst; } + CActorInstance* GetActorInstance() { return m_pActorInstance; } + + protected: + void Accumulate(D3DXVECTOR3 * pv3Position); + + protected: + float m_fMass; + float m_fFriction; + D3DXVECTOR3 m_v3Direction; + D3DXVECTOR3 m_v3Acceleration; + D3DXVECTOR3 m_v3Velocity; + + D3DXVECTOR3 m_v3LastPosition; + CEaseOutInterpolation m_xPushingPosition; + CEaseOutInterpolation m_yPushingPosition; + + CActorInstance* m_pActorInstance; +}; diff --git a/source/GameLib/Property.cpp b/source/GameLib/Property.cpp new file mode 100644 index 0000000..abafe14 --- /dev/null +++ b/source/GameLib/Property.cpp @@ -0,0 +1,269 @@ +#include "StdAfx.h" +#include +#include "../eterBase/TempFile.h" + +#include "PropertyManager.h" +#include "Property.h" +/* + * CProperty + * + * 0 ~ 4 bytes: fourcc + * 5 ~ 6 bytes: \r\n + * + * Ʈ ؽƮ δ + */ +CProperty::CProperty(const char * c_pszFileName) : mc_pFileName(NULL), m_dwCRC(0) +{ + m_stFileName = c_pszFileName; + StringPath(m_stFileName); + + mc_pFileName = strrchr(m_stFileName.c_str(), '/'); + + if (!mc_pFileName) + mc_pFileName = m_stFileName.c_str(); + else + ++mc_pFileName; +} + +CProperty::~CProperty() +{ +} + +DWORD CProperty::GetCRC() +{ + return m_dwCRC; +} + +const char * CProperty::GetFileName() +{ + return (m_stFileName.c_str()); +} + +bool CProperty::GetString(const char * c_pszKey, const char ** c_ppString) +{ + std::string stTempKey = c_pszKey; + stl_lowers(stTempKey); + CTokenVectorMap::iterator it = m_stTokenMap.find(stTempKey.c_str()); + +// printf("GetString %s %d\n", stTempKey.c_str(), m_stTokenMap.size()); + + if (m_stTokenMap.end() == it) + return false; + + *c_ppString = it->second[0].c_str(); + return true; +} + +DWORD CProperty::GetSize() +{ + return m_stTokenMap.size(); +} + +bool CProperty::GetVector(const char * c_pszKey, CTokenVector & rTokenVector) +{ + std::string stTempKey = c_pszKey; + stl_lowers(stTempKey); + CTokenVectorMap::iterator it = m_stTokenMap.find(stTempKey.c_str()); + + if (m_stTokenMap.end() == it) + return false; + +// NOTE : ƨ ߰ +// std::copy(rTokenVector.begin(), it->second.begin(), it->second.end()); +// NOTE : ۷ ̷ ϰԲ Ǿ +/////////////////////////////////////////////////////////////////////////////// +// template +// OutputIterator copy(InputIterator first, InputIterator last, +// OutputIterator result); +// +// vector V(5); +// iota(V.begin(), V.end(), 1); +// list L(V.size()); +// copy(V.begin(), V.end(), L.begin()); +// assert(equal(V.begin(), V.end(), L.begin())); +/////////////////////////////////////////////////////////////////////////////// +// 嵥 ׷ ƨ. - [levites] +// std::copy(it->second.begin(), it->second.end(), rTokenVector.begin()); + +// ᱹ ̷.. - [levites] +// ϴ : WorldEditor/Dialog/MapObjectPropertyPageBuilding.cpp + CTokenVector & rSourceTokenVector = it->second; + CTokenVector::iterator itor = rSourceTokenVector.begin(); + for (; itor != rSourceTokenVector.end(); ++itor) + { + rTokenVector.push_back(*itor); + } + + return true; +} + +void CProperty::PutString(const char * c_pszKey, const char * c_pszString) +{ + std::string stTempKey = c_pszKey; + stl_lowers(stTempKey); + + // ̹ ִ° + CTokenVectorMap::iterator itor = m_stTokenMap.find(stTempKey); + + if (itor != m_stTokenMap.end()) + m_stTokenMap.erase(itor); + + CTokenVector tokenVector; + tokenVector.push_back(c_pszString); + + m_stTokenMap.insert(CTokenVectorMap::value_type(stTempKey, tokenVector)); +} + +void CProperty::PutVector(const char * c_pszKey, const CTokenVector & c_rTokenVector) +{ + std::string stTempKey = c_pszKey; + stl_lowers(stTempKey); + + m_stTokenMap.insert(CTokenVectorMap::value_type(stTempKey, c_rTokenVector)); +} + +void GetTimeString(char * str, time_t ct) +{ + struct tm tm; + tm = *localtime(&ct); + + _snprintf(str, 15, "%04d%02d%02d%02d%02d%02d", + tm.tm_year + 1900, + tm.tm_mon + 1, + tm.tm_mday, + tm.tm_hour, + tm.tm_min, + tm.tm_sec); +} + +bool CProperty::Save(const char * c_pszFileName) +{ + CTempFile file; + + DWORD fourcc = MAKEFOURCC('Y', 'P', 'R', 'T'); + file.Write(&fourcc, sizeof(DWORD)); + file.Write("\r\n", 2); + + if (0 == m_stCRC.length()) + { + char szCRC[MAX_PATH + 16 + 1]; + + GetTimeString(szCRC, time(0)); + strcpy(szCRC + strlen(szCRC), c_pszFileName); + + m_dwCRC = CPropertyManager::Instance().GetUniqueCRC(szCRC); + _snprintf(szCRC, sizeof(szCRC), "%u", m_dwCRC); + + m_stCRC.assign(szCRC); + } + + file.Write(m_stCRC.c_str(), m_stCRC.length()); + file.Write("\r\n", 2); + + CTokenVectorMap::iterator itor = m_stTokenMap.begin(); + char buf[4096 + 1]; + + while (itor != m_stTokenMap.end()) + { + CTokenVector & tokenVector = itor->second; + + int len = _snprintf(buf, sizeof(buf), "%s\t", itor->first.c_str()); + file.Write(buf, len); + + for (DWORD i = 0; i < tokenVector.size(); ++i) + { + len = _snprintf(buf, sizeof(buf), "\t\"%s\"", tokenVector[i].c_str()); + file.Write(buf, len); + } + + file.Write("\r\n", 2); + ++itor; + } + + file.Close(); + return CPropertyManager::Instance().Put(c_pszFileName, file.GetFileName()); +} + +bool CProperty::ReadFromMemory(const void * c_pvData, int iLen, const char * c_pszFileName) +{ + const char * pcData = (const char *) c_pvData; + + if (*(DWORD *) pcData != MAKEFOURCC('Y', 'P', 'R', 'T')) + return false; + + pcData += sizeof(DWORD); + + if (*pcData != '\r' || *(pcData + 1) != '\n') + { + TraceError("CProperty::ReadFromMemory: File format error after FourCC: %s\n", c_pszFileName); + return false; + } + + pcData += 2; + + CTokenVector stTokenVector; +/* + char szTimeStamp[64]; + memcpy(szTimeStamp, pcData, 14); + szTimeStamp[14] = '\0'; + pcData += 14; + + if (*pcData != '\r' || *(pcData + 1) != '\n') + { + TraceError("CProperty::ReadFromMemory: File format error after TimeStamp: %s\n", c_pszFileName); + return false; + } + + std::string m_stTimeStamp; + + m_stTimeStamp = szTimeStamp; + + int iTimeStampLen = 14 + _snprintf(szTimeStamp + 14, 64 - 14, "%s", mc_pFileName); + m_dwCRC = GetCRC32(szTimeStamp, iTimeStampLen); + + char tmp[64]; + sprintf(tmp, "%u", m_dwCRC); + m_stCRC.assign(tmp); + + CMemoryTextFileLoader textFileLoader; + textFileLoader.Bind(iLen - (sizeof(DWORD) + 2 + 14 + 2), pcData); + + for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i) + { + if (!textFileLoader.SplitLine(i, &stTokenVector)) + continue; + + stl_lowers(stTokenVector[0]); + std::string stKey = stTokenVector[0]; + + stTokenVector.erase(stTokenVector.begin()); + PutVector(stKey.c_str(), stTokenVector); + } + return true; + */ + CMemoryTextFileLoader textFileLoader; + textFileLoader.Bind(iLen - (sizeof(DWORD) + 2), pcData); + + m_stCRC = textFileLoader.GetLineString(0); + m_dwCRC = atoi(m_stCRC.c_str()); + + for (DWORD i = 1; i < textFileLoader.GetLineCount(); ++i) + { + if (!textFileLoader.SplitLine(i, &stTokenVector)) + continue; + + stl_lowers(stTokenVector[0]); + std::string stKey = stTokenVector[0]; + + stTokenVector.erase(stTokenVector.begin()); + PutVector(stKey.c_str(), stTokenVector); + } + + //Tracef("Property: %s\n", c_pszFileName); + return true; +} + +void CProperty::Clear() +{ + m_stTokenMap.clear(); +} diff --git a/source/GameLib/Property.h b/source/GameLib/Property.h new file mode 100644 index 0000000..bf20d38 --- /dev/null +++ b/source/GameLib/Property.h @@ -0,0 +1,34 @@ +#pragma once + +#include + +class CProperty +{ + public: + CProperty(const char * c_pszFileName); + ~CProperty(); + + void Clear(); + bool ReadFromMemory(const void * c_pvData, int iLen, const char * c_pszFileName); + + const char * GetFileName(); + + bool GetVector(const char * c_pszKey, CTokenVector & rTokenVector); + bool GetString(const char * c_pszKey, const char ** c_ppString); + + void PutVector(const char * c_pszKey, const CTokenVector & c_rTokenVector); + void PutString(const char * c_pszKey, const char * c_pszString); + + bool Save(const char * c_pszFileName); + + DWORD GetSize(); + DWORD GetCRC(); + + protected: + std::string m_stFileName; + std::string m_stCRC; + const char * mc_pFileName; + DWORD m_dwCRC; + + CTokenVectorMap m_stTokenMap; +}; diff --git a/source/GameLib/PropertyLoader.cpp b/source/GameLib/PropertyLoader.cpp new file mode 100644 index 0000000..4a1520e --- /dev/null +++ b/source/GameLib/PropertyLoader.cpp @@ -0,0 +1,68 @@ +#include "StdAfx.h" +#include "PropertyLoader.h" +#include "PropertyManager.h" +#include "Property.h" + +bool CPropertyLoader::OnFolder(const char* c_szFilter, const char* c_szPathName, const char* c_szFileName) +{ + std::string stPathName = ""; + stPathName += c_szPathName; + stPathName += c_szFileName; + + CPropertyLoader PropertyLoader; + PropertyLoader.SetPropertyManager(m_pPropertyManager); + PropertyLoader.Create(c_szFilter, stPathName.c_str()); + return true; +} + +bool CPropertyLoader::OnFile(const char* c_szPathName, const char* c_szFileName) +{ + RegisterFile(c_szPathName, c_szFileName); + return true; +} + +DWORD CPropertyLoader::RegisterFile(const char * c_szPathName, const char * c_szFileName) +{ + std::string strFileName = ""; + strFileName += c_szPathName; + strFileName += c_szFileName; + + std::string stExt; + GetFileExtension(strFileName.c_str(), strFileName.length(), &stExt); + + stl_lowers(stExt); + stl_lowers(strFileName); + + // н ҹڷ \\ / ٲ۴. + StringPath(strFileName); + + // CRC ó ( CRC) + if (0 == strFileName.compare("property/reserve")) + { + m_pPropertyManager->LoadReservedCRC(strFileName.c_str()); + return 1; + } + else + { + CProperty * pProperty; + + if (m_pPropertyManager->Register(strFileName.c_str(), &pProperty)) + return pProperty->GetCRC(); + else + return 0; + } +} + +void CPropertyLoader::SetPropertyManager(CPropertyManager * pPropertyManager) +{ + m_pPropertyManager = pPropertyManager; +} + +CPropertyLoader::CPropertyLoader() +{ + m_pPropertyManager = NULL; +} + +CPropertyLoader::~CPropertyLoader() +{ +} diff --git a/source/GameLib/PropertyLoader.h b/source/GameLib/PropertyLoader.h new file mode 100644 index 0000000..0aa5888 --- /dev/null +++ b/source/GameLib/PropertyLoader.h @@ -0,0 +1,21 @@ +#pragma once + +#include "../eterbase/FileDir.h" + +class CPropertyManager; + +class CPropertyLoader : public CDir +{ + public: + CPropertyLoader(); + virtual ~CPropertyLoader(); + + void SetPropertyManager(CPropertyManager * pPropertyManager); + DWORD RegisterFile(const char* c_szPathName, const char* c_szFileName); + + virtual bool OnFolder(const char* c_szFilter, const char* c_szPathName, const char* c_szFileName); + virtual bool OnFile(const char* c_szPathName, const char* c_szFileName); + + protected: + CPropertyManager * m_pPropertyManager; +}; diff --git a/source/GameLib/PropertyManager.cpp b/source/GameLib/PropertyManager.cpp new file mode 100644 index 0000000..7aa8e85 --- /dev/null +++ b/source/GameLib/PropertyManager.cpp @@ -0,0 +1,255 @@ +#include "StdAfx.h" +#include "../eterPack/EterPackManager.h" + +#include "PropertyManager.h" +#include "Property.h" + +CPropertyManager::CPropertyManager() : m_isFileMode(true) +{ +} + +CPropertyManager::~CPropertyManager() +{ + Clear(); +} + +bool CPropertyManager::Initialize(const char * c_pszPackFileName) +{ + if (c_pszPackFileName) + { + if (!m_pack.Create(m_fileDict, c_pszPackFileName, "", true)) + { + LogBoxf("Cannot open property pack file (filename %s)", c_pszPackFileName); + return false; + } + + m_isFileMode = false; + + TDataPositionMap & indexMap = m_pack.GetIndexMap(); + + TDataPositionMap::iterator itor = indexMap.begin(); + + typedef std::map TDataPositionMap; + + int i = 0; + + while (indexMap.end() != itor) + { + TEterPackIndex * pIndex = itor->second; + ++itor; + + if (!stricmp("property/reserve", pIndex->filename)) + { + LoadReservedCRC(pIndex->filename); + continue; + } + + if (!Register(pIndex->filename)) + continue; + + ++i; + } + } + else + { + m_isFileMode = true; + // NOTE : ⼭ Property ϽŰ WorldEditor ̻ ; + // , Property Tree List Ѿ DZ ٱʿ.. - [levites] + } + + return true; +} + +bool CPropertyManager::BuildPack() +{ + if (!m_pack.Create(m_fileDict, "property", "")) + return false; + + WIN32_FIND_DATA fdata; + HANDLE hFind = FindFirstFile("property\\*", &fdata); + + if (hFind == INVALID_HANDLE_VALUE) + return false; + + do + { + if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + continue; + + char szSourceFileName[256 + 1]; + _snprintf(szSourceFileName, sizeof(szSourceFileName), "property\\%s", fdata.cFileName); + + m_pack.Put(fdata.cFileName, szSourceFileName,COMPRESSED_TYPE_NONE,""); + } + while (FindNextFile(hFind, &fdata)); + + FindClose(hFind); + return true; +} + +bool CPropertyManager::LoadReservedCRC(const char * c_pszFileName) +{ + CMappedFile file; + LPCVOID c_pvData; + + if (!CEterPackManager::Instance().Get(file, c_pszFileName, &c_pvData)) + return false; + + CMemoryTextFileLoader textFileLoader; + textFileLoader.Bind(file.Size(), c_pvData); + + for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i) + { + const char * pszLine = textFileLoader.GetLineString(i).c_str(); + + if (!pszLine || !*pszLine) + continue; + + ReserveCRC(atoi(pszLine)); + } + + return true; +} + +void CPropertyManager::ReserveCRC(DWORD dwCRC) +{ + m_ReservedCRCSet.insert(dwCRC); +} + +DWORD CPropertyManager::GetUniqueCRC(const char * c_szSeed) +{ + std::string stTmp = c_szSeed; + + while (1) + { + DWORD dwCRC = GetCRC32(stTmp.c_str(), stTmp.length()); + + if (m_ReservedCRCSet.find(dwCRC) == m_ReservedCRCSet.end() && + m_PropertyByCRCMap.find(dwCRC) == m_PropertyByCRCMap.end()) + return dwCRC; + + char szAdd[2]; + _snprintf(szAdd, sizeof(szAdd), "%d", random() % 10); + stTmp += szAdd; + } +} + +bool CPropertyManager::Register(const char * c_pszFileName, CProperty ** ppProperty) +{ + CMappedFile file; + LPCVOID c_pvData; + + if (!CEterPackManager::Instance().Get(file, c_pszFileName, &c_pvData)) + return false; + + CProperty * pProperty = new CProperty(c_pszFileName); + + if (!pProperty->ReadFromMemory(c_pvData, file.Size(), c_pszFileName)) + { + delete pProperty; + return false; + } + + DWORD dwCRC = pProperty->GetCRC(); + + TPropertyCRCMap::iterator itor = m_PropertyByCRCMap.find(dwCRC); + + if (m_PropertyByCRCMap.end() != itor) + { + Tracef("Property already registered, replace %s to %s\n", + itor->second->GetFileName(), + c_pszFileName); + + delete itor->second; + itor->second = pProperty; + } + else + m_PropertyByCRCMap.insert(TPropertyCRCMap::value_type(dwCRC, pProperty)); + + if (ppProperty) + *ppProperty = pProperty; + + return true; +} + +bool CPropertyManager::Get(const char * c_pszFileName, CProperty ** ppProperty) +{ + return Register(c_pszFileName, ppProperty); +} + +bool CPropertyManager::Get(DWORD dwCRC, CProperty ** ppProperty) +{ + TPropertyCRCMap::iterator itor = m_PropertyByCRCMap.find(dwCRC); + + if (m_PropertyByCRCMap.end() == itor) + return false; + + *ppProperty = itor->second; + return true; +} + +bool CPropertyManager::Put(const char * c_pszFileName, const char * c_pszSourceFileName) +{ + if (!CopyFile(c_pszSourceFileName, c_pszFileName, FALSE)) + return false; + + if (!m_isFileMode) // Ͽ + { + if (!m_pack.Put(c_pszFileName, NULL, COMPRESSED_TYPE_NONE,"")) + { + assert(!"CPropertyManager::Put cannot write to pack file"); + return false; + } + } + + Register(c_pszFileName); + return true; +} + +bool CPropertyManager::Erase(DWORD dwCRC) +{ + TPropertyCRCMap::iterator itor = m_PropertyByCRCMap.find(dwCRC); + + if (m_PropertyByCRCMap.end() == itor) + return false; + + CProperty * pProperty = itor->second; + m_PropertyByCRCMap.erase(itor); + + DeleteFile(pProperty->GetFileName()); + ReserveCRC(pProperty->GetCRC()); + + if (!m_isFileMode) // 尡 ƴϸ ѿ + m_pack.Delete(pProperty->GetFileName()); + + FILE * fp = fopen("property/reserve", "a+"); + + if (!fp) + LogBox(" CRC ϴ."); + else + { + char szCRC[64 + 1]; + _snprintf(szCRC, sizeof(szCRC), "%u\r\n", pProperty->GetCRC()); + + fputs(szCRC, fp); + fclose(fp); + } + + delete pProperty; + return true; +} + +bool CPropertyManager::Erase(const char * c_pszFileName) +{ + CProperty * pProperty = NULL; + + if (Get(c_pszFileName, &pProperty)) + return Erase(pProperty->GetCRC()); + + return false; +} + +void CPropertyManager::Clear() +{ + stl_wipe_second(m_PropertyByCRCMap); +} diff --git a/source/GameLib/PropertyManager.h b/source/GameLib/PropertyManager.h new file mode 100644 index 0000000..0ad11c1 --- /dev/null +++ b/source/GameLib/PropertyManager.h @@ -0,0 +1,43 @@ +#pragma once + +#include "../eterPack/EterPack.h" + +class CPropertyManager : public CSingleton +{ + public: + CPropertyManager(); + virtual ~CPropertyManager(); + + void Clear(); + + void SetPack(CEterPack * pPack); + bool BuildPack(); + + bool LoadReservedCRC(const char * c_pszFileName); + void ReserveCRC(DWORD dwCRC); + DWORD GetUniqueCRC(const char * c_szSeed); + + bool Initialize(const char * c_pszPackFileName = NULL); + bool Register(const char * c_pszFileName, CProperty ** ppProperty = NULL); + + bool Get(DWORD dwCRC, CProperty ** ppProperty); + bool Get(const char * c_pszFileName, CProperty ** ppProperty); + +// bool Add(const char * c_pszFileName); +// bool Remove(DWORD dwCRC); + + bool Put(const char * c_pszFileName, const char * c_pszSourceFileName); + + bool Erase(DWORD dwCRC); + bool Erase(const char * c_pszFileName); + + protected: + typedef std::map TPropertyCRCMap; + typedef std::set TCRCSet; + + bool m_isFileMode; + TPropertyCRCMap m_PropertyByCRCMap; + TCRCSet m_ReservedCRCSet; + CEterPack m_pack; + CEterFileDict m_fileDict; +}; diff --git a/source/GameLib/RaceData.cpp b/source/GameLib/RaceData.cpp new file mode 100644 index 0000000..b321236 --- /dev/null +++ b/source/GameLib/RaceData.cpp @@ -0,0 +1,598 @@ +#include "StdAfx.h" +#include "../eterLib/ResourceManager.h" +#include "../eterLib/AttributeInstance.h" +#include "../eterBase/Utils.h" +#include "RaceData.h" +#include "RaceMotionData.h" +#include "../eterBase/Filename.h" + +CDynamicPool CRaceData::ms_kPool; +CDynamicPool CRaceData::ms_MotionModeDataPool; + +const std::string& CRaceData::GetSmokeBone() +{ + return m_strSmokeBoneName; +} + +DWORD CRaceData::GetSmokeEffectID(UINT eSmoke) +{ + if(eSmoke>=SMOKE_NUM) + { + TraceError("CRaceData::GetSmokeEffectID(eSmoke=%d)", eSmoke); + return 0; + } + + return m_adwSmokeEffectID[eSmoke]; +} + +CRaceData::SHair* CRaceData::FindHair(UINT eHair) +{ + std::map::iterator f=m_kMap_dwHairKey_kHair.find(eHair); + if (m_kMap_dwHairKey_kHair.end()==f) + { + if (eHair != 0) + TraceError("Hair number %d is not exist.",eHair); + return NULL; + } + + return &f->second; +} + +void CRaceData::SetHairSkin(UINT eHair, UINT ePart, const char * c_szModelFileName, const char* c_szSrcFileName, const char* c_szDstFileName) +{ + SSkin kSkin; + kSkin.m_ePart=ePart; + kSkin.m_stSrcFileName=c_szSrcFileName; + kSkin.m_stDstFileName=c_szDstFileName; + + CFileNameHelper::ChangeDosPath(kSkin.m_stSrcFileName); + m_kMap_dwHairKey_kHair[eHair].m_kVct_kSkin.push_back(kSkin); + m_kMap_dwHairKey_kHair[eHair].m_stModelFileName = c_szModelFileName; +} + +CRaceData::SShape* CRaceData::FindShape(UINT eShape) +{ + std::map::iterator f=m_kMap_dwShapeKey_kShape.find(eShape); + if (m_kMap_dwShapeKey_kShape.end()==f) + return NULL; + + return &f->second; +} + +void CRaceData::SetShapeModel(UINT eShape, const char* c_szModelFileName) +{ + m_kMap_dwShapeKey_kShape[eShape].m_stModelFileName=c_szModelFileName; +} + +void CRaceData::AppendShapeSkin(UINT eShape, UINT ePart, const char* c_szSrcFileName, const char* c_szDstFileName) +{ + SSkin kSkin; + kSkin.m_ePart=ePart; + kSkin.m_stSrcFileName=c_szSrcFileName; + kSkin.m_stDstFileName=c_szDstFileName; + + CFileNameHelper::ChangeDosPath(kSkin.m_stSrcFileName); + m_kMap_dwShapeKey_kShape[eShape].m_kVct_kSkin.push_back(kSkin); +} + +CRaceData* CRaceData::New() +{ + return ms_kPool.Alloc(); +} + +void CRaceData::Delete(CRaceData* pkRaceData) +{ + pkRaceData->Destroy(); + ms_kPool.Free(pkRaceData); +} + +void CRaceData::CreateSystem(UINT uCapacity, UINT uMotModeCapacity) +{ + ms_MotionModeDataPool.Create(uMotModeCapacity); + ms_kPool.Create(uCapacity); +} + +void CRaceData::DestroySystem() +{ + ms_kPool.Destroy(); + ms_MotionModeDataPool.Destroy(); +} + +BOOL CRaceData::CreateMotionModeIterator(TMotionModeDataIterator & itor) +{ + if (m_pMotionModeDataMap.empty()) + return FALSE; + + itor = m_pMotionModeDataMap.begin(); + + return TRUE; +} +BOOL CRaceData::NextMotionModeIterator(TMotionModeDataIterator & itor) +{ + ++itor; + + return m_pMotionModeDataMap.end() != itor; +} + +BOOL CRaceData::GetMotionKey(WORD wMotionModeIndex, WORD wMotionIndex, MOTION_KEY * pMotionKey) +{ + TMotionModeData * pMotionModeData; + if (!GetMotionModeDataPointer(wMotionModeIndex, &pMotionModeData)) + return FALSE; + + if (pMotionModeData->MotionVectorMap.end() == pMotionModeData->MotionVectorMap.find(wMotionIndex)) + { + WORD wGeneralMode=CRaceMotionData::MODE_GENERAL; + + switch(wMotionModeIndex) + { + case CRaceMotionData::MODE_HORSE_ONEHAND_SWORD: + case CRaceMotionData::MODE_HORSE_TWOHAND_SWORD: + case CRaceMotionData::MODE_HORSE_DUALHAND_SWORD: + case CRaceMotionData::MODE_HORSE_FAN: + case CRaceMotionData::MODE_HORSE_BELL: + case CRaceMotionData::MODE_HORSE_BOW: + wGeneralMode=CRaceMotionData::MODE_HORSE; + break; + + default: + wGeneralMode=CRaceMotionData::MODE_GENERAL; + break; + } + + TMotionModeData * pMotionModeGeneralData; + if (!GetMotionModeDataPointer(wGeneralMode, &pMotionModeGeneralData)) + return FALSE; + + if (pMotionModeGeneralData->MotionVectorMap.end() == pMotionModeGeneralData->MotionVectorMap.find(wMotionIndex)) + return FALSE; + + *pMotionKey = MAKE_MOTION_KEY(wGeneralMode, wMotionIndex); + } + else + { + *pMotionKey = MAKE_MOTION_KEY(wMotionModeIndex, wMotionIndex); + } + + return TRUE; +} + +BOOL CRaceData::GetMotionModeDataPointer(WORD wMotionMode, TMotionModeData ** ppMotionModeData) +{ + TMotionModeDataIterator itor = m_pMotionModeDataMap.find(wMotionMode); + if (itor == m_pMotionModeDataMap.end()) + return FALSE; + + *ppMotionModeData = itor->second; + + return TRUE; +} + +BOOL CRaceData::GetModelDataPointer(DWORD dwModelIndex, const TModelData ** c_ppModelData) +{ + TModelDataMapIterator itor = m_ModelDataMap.find(dwModelIndex); + if (m_ModelDataMap.end() == itor) + return false; + + *c_ppModelData = &itor->second; + + return true; +} + +BOOL CRaceData::GetMotionVectorPointer(WORD wMotionMode, WORD wMotionIndex, TMotionVector ** ppMotionVector) +{ + TMotionModeData * pMotionModeData; + if (!GetMotionModeDataPointer(wMotionMode, &pMotionModeData)) + return FALSE; + + TMotionVectorMap::iterator itor = pMotionModeData->MotionVectorMap.find(wMotionIndex); + if (pMotionModeData->MotionVectorMap.end() == itor) + return FALSE; + + *ppMotionVector = &itor->second; + + return TRUE; +} + +BOOL CRaceData::GetMotionDataPointer(WORD wMotionMode, WORD wMotionIndex, WORD wMotionSubIndex, CRaceMotionData ** c_ppMotionData) +{ + const TMotionVector * c_pMotionVector; + if (!GetMotionVectorPointer(wMotionMode, wMotionIndex, &c_pMotionVector)) + return FALSE; + + if (wMotionSubIndex >= c_pMotionVector->size()) + return FALSE; + + const TMotion & c_rMotion = c_pMotionVector->at(wMotionSubIndex); + + if (!c_rMotion.pMotionData) + return FALSE; + + *c_ppMotionData = c_rMotion.pMotionData; + + return TRUE; +} + +BOOL CRaceData::GetMotionDataPointer(DWORD dwMotionKey, CRaceMotionData ** c_ppMotionData) +{ + return GetMotionDataPointer(GET_MOTION_MODE(dwMotionKey), GET_MOTION_INDEX(dwMotionKey), GET_MOTION_SUB_INDEX(dwMotionKey), c_ppMotionData); +} + +BOOL CRaceData::GetMotionVectorPointer(WORD wMotionMode, WORD wMotionIndex, const TMotionVector ** c_ppMotionVector) +{ + TMotionVector * pMotionVector; + if (!GetMotionVectorPointer(wMotionMode, wMotionIndex, &pMotionVector)) + return FALSE; + + *c_ppMotionVector = pMotionVector; + + return TRUE; +} + +DWORD CRaceData::GetAttachingDataCount() +{ + return m_AttachingDataVector.size(); +} + +BOOL CRaceData::GetAttachingDataPointer(DWORD dwIndex, const NRaceData::TAttachingData ** c_ppAttachingData) +{ + if (dwIndex >= GetAttachingDataCount()) + return FALSE; + + *c_ppAttachingData = &m_AttachingDataVector[dwIndex]; + + return TRUE; +} + +BOOL CRaceData::GetCollisionDataPointer(DWORD dwIndex, const NRaceData::TAttachingData ** c_ppAttachingData) +{ + if (dwIndex >= GetAttachingDataCount()) + return FALSE; + + if (NRaceData::ATTACHING_DATA_TYPE_COLLISION_DATA != m_AttachingDataVector[dwIndex].dwType) + return FALSE; + + *c_ppAttachingData = &m_AttachingDataVector[dwIndex]; + + return TRUE; +} + +BOOL CRaceData::GetBodyCollisionDataPointer(const NRaceData::TAttachingData ** c_ppAttachingData) +{ + for (DWORD i = 0; i < m_AttachingDataVector.size(); ++i) + { + const NRaceData::TAttachingData * pAttachingData = &m_AttachingDataVector[i]; + + if (NRaceData::ATTACHING_DATA_TYPE_COLLISION_DATA == pAttachingData->dwType) + if (NRaceData::COLLISION_TYPE_BODY == pAttachingData->pCollisionData->iCollisionType) + { + *c_ppAttachingData = pAttachingData; + return true; + } + } + + return FALSE; +} + +void CRaceData::SetRace(DWORD dwRaceIndex) +{ + m_dwRaceIndex = dwRaceIndex; +} + +void CRaceData::RegisterAttachingBoneName(DWORD dwPartIndex, const char * c_szBoneName) +{ + m_AttachingBoneNameMap.insert(TAttachingBoneNameMap::value_type(dwPartIndex, c_szBoneName)); +} + +void CRaceData::RegisterMotionMode(WORD wMotionModeIndex) +{ + TMotionModeData * pMotionModeData = ms_MotionModeDataPool.Alloc(); + pMotionModeData->wMotionModeIndex = wMotionModeIndex; + pMotionModeData->MotionVectorMap.clear(); + m_pMotionModeDataMap.insert(TMotionModeDataMap::value_type(wMotionModeIndex, pMotionModeData)); +} + +CGraphicThing* CRaceData::NEW_RegisterMotion(CRaceMotionData* pkMotionData, WORD wMotionModeIndex, WORD wMotionIndex, const char * c_szFileName, BYTE byPercentage) +{ + CGraphicThing * pMotionThing = (CGraphicThing *)CResourceManager::Instance().GetResourcePointer(c_szFileName); + + TMotionModeData * pMotionModeData; + if (!GetMotionModeDataPointer(wMotionModeIndex, &pMotionModeData)) + { + AssertLog("Failed getting motion mode data!"); + return NULL; + } + + TMotion kMotion; + kMotion.byPercentage = byPercentage; + kMotion.pMotion = pMotionThing; + kMotion.pMotionData = pkMotionData; + pMotionModeData->MotionVectorMap[wMotionIndex].push_back(kMotion); + + return pMotionThing; +} + +CGraphicThing* CRaceData::RegisterMotionData(WORD wMotionMode, WORD wMotionIndex, const char * c_szFileName, BYTE byPercentage) +{ + CRaceMotionData * pRaceMotionData = CRaceMotionData::New(); + if (!pRaceMotionData->LoadMotionData(c_szFileName)) + { + TraceError("CRaceData::RegisterMotionData - LoadMotionData(c_szFileName=%s) ERROR", c_szFileName); + CRaceMotionData::Delete(pRaceMotionData); + pRaceMotionData = NULL; + return NULL; + } + + // 2004. 3. 15. myevan. dz ε ־ Ѵ. + pRaceMotionData->SetName(wMotionIndex); + + ///// + + // FIXME : ̹ GR2 ε Ǿ 쿡  ؾ ϴ°? + // Ȱ ϳ ߰ Ǿ . - [levites] + + return NEW_RegisterMotion(pRaceMotionData, wMotionMode, wMotionIndex, pRaceMotionData->GetMotionFileName(), byPercentage); + + // 2004.09.03.myevan.οԼ ó + //TMotion Motion; + //Motion.byPercentage = byPercentage; + //Motion.pMotion = (CGraphicThing *)CResourceManager::Instance().GetResourcePointer(pRaceMotionData->GetMotionFileName()); + //Motion.pMotionData = pRaceMotionData; + //__OLD_RegisterMotion(wMotionMode, wMotionIndex, Motion); + //return true; +} + + +void CRaceData::OLD_RegisterMotion(WORD wMotionModeIndex, WORD wMotionIndex, const char * c_szFileName, BYTE byPercentage) +{ + CGraphicThing * pThing = (CGraphicThing *)CResourceManager::Instance().GetResourcePointer(c_szFileName); + + TMotion Motion; + Motion.byPercentage = byPercentage; + Motion.pMotion = pThing; + Motion.pMotionData = NULL; + __OLD_RegisterMotion(wMotionModeIndex, wMotionIndex, Motion); +} + +void CRaceData::__OLD_RegisterMotion(WORD wMotionMode, WORD wMotionIndex, const TMotion & rMotion) +{ + TMotionModeData * pMotionModeData; + if (!GetMotionModeDataPointer(wMotionMode, &pMotionModeData)) + { + AssertLog("Failed getting motion mode data!"); + return; + } + + TMotionVectorMap::iterator itor = pMotionModeData->MotionVectorMap.find(wMotionIndex); + if (pMotionModeData->MotionVectorMap.end() == itor) + { + TMotionVector MotionVector; + MotionVector.push_back(rMotion); + + pMotionModeData->MotionVectorMap.insert(TMotionVectorMap::value_type(wMotionIndex, MotionVector)); + } + else + { + TMotionVector & rMotionVector = itor->second; + rMotionVector.push_back(rMotion); + } +} + + +bool CRaceData::SetMotionRandomWeight(WORD wMotionModeIndex, WORD wMotionIndex, WORD wMotionSubIndex, BYTE byPercentage) +{ + TMotionModeData * pMotionModeData; + + if (!GetMotionModeDataPointer(wMotionModeIndex, &pMotionModeData)) + { + //AssertLog("Failed getting motion mode data!"); + return false; + } + + TMotionVectorMap::iterator itor = pMotionModeData->MotionVectorMap.find(wMotionIndex); + + if (pMotionModeData->MotionVectorMap.end() != itor) + { + TMotionVector & rMotionVector = itor->second; + if (wMotionSubIndex < rMotionVector.size()) + { + rMotionVector[wMotionSubIndex].byPercentage = byPercentage; + } + else + { + return false; + } + } + else + { + TraceError("CRaceData::SetMotionRandomWeight(wMotionModeIndex=%d, wMotionIndex=%d, wMotionSubIndex=%d, byPercentage=%d) - Find Motion(wMotionIndex=%d) FAILED", + wMotionModeIndex, wMotionIndex, wMotionSubIndex, byPercentage, wMotionModeIndex); + + return false; + } + + return true; +} + +void CRaceData::RegisterNormalAttack(WORD wMotionModeIndex, WORD wMotionIndex) +{ + m_NormalAttackIndexMap.insert(TNormalAttackIndexMap::value_type(wMotionModeIndex, wMotionIndex)); +} +BOOL CRaceData::GetNormalAttackIndex(WORD wMotionModeIndex, WORD * pwMotionIndex) +{ + TNormalAttackIndexMap::iterator itor = m_NormalAttackIndexMap.find(wMotionModeIndex); + + if (m_NormalAttackIndexMap.end() == itor) + return FALSE; + + *pwMotionIndex = itor->second; + + return TRUE; +} + +void CRaceData::ReserveComboAttack(WORD wMotionModeIndex, WORD wComboType, DWORD dwComboCount) +{ + TComboData ComboData; + ComboData.ComboIndexVector.clear(); + ComboData.ComboIndexVector.resize(dwComboCount); + m_ComboAttackDataMap.insert(TComboAttackDataMap::value_type(MAKE_COMBO_KEY(wMotionModeIndex, wComboType), ComboData)); +} + +void CRaceData::RegisterComboAttack(WORD wMotionModeIndex, WORD wComboType, DWORD dwComboIndex, WORD wMotionIndex) +{ + TComboAttackDataIterator itor = m_ComboAttackDataMap.find(MAKE_COMBO_KEY(wMotionModeIndex, wComboType)); + if (m_ComboAttackDataMap.end() == itor) + return; + + TComboIndexVector & rComboIndexVector = itor->second.ComboIndexVector; + if (dwComboIndex >= rComboIndexVector.size()) + { + AssertLog("CRaceData::RegisterCombo - Strange combo index!"); + return; + } + + rComboIndexVector[dwComboIndex] = wMotionIndex; +} + +BOOL CRaceData::GetComboDataPointer(WORD wMotionModeIndex, WORD wComboType, TComboData ** ppComboData) +{ + TComboAttackDataIterator itor = m_ComboAttackDataMap.find(MAKE_COMBO_KEY(wMotionModeIndex, wComboType)); + + if (m_ComboAttackDataMap.end() == itor) + return FALSE; + + *ppComboData = &itor->second; + return TRUE; +} + +const char * CRaceData::GetBaseModelFileName() const +{ + return m_strBaseModelFileName.c_str(); +} + +const char * CRaceData::GetAttributeFileName() const +{ + return m_strAttributeFileName.c_str(); +} + +const char* CRaceData::GetMotionListFileName() const +{ + return m_strMotionListFileName.c_str(); +} + +CGraphicThing * CRaceData::GetBaseModelThing() +{ + if (!m_pBaseModelThing) + { + m_pBaseModelThing = (CGraphicThing *)CResourceManager::Instance().GetResourcePointer(m_strBaseModelFileName.c_str()); + } + + return m_pBaseModelThing; +} + +CGraphicThing * CRaceData::GetLODModelThing() +{ + if (!m_pLODModelThing) + { + std::string strLODFileName = CFileNameHelper::NoExtension(m_strBaseModelFileName) + "_lod_01.gr2"; + if (CResourceManager::Instance().IsFileExist(strLODFileName.c_str())) + { + m_pLODModelThing = (CGraphicThing *)CResourceManager::Instance().GetResourcePointer(strLODFileName.c_str()); + } + } + + return m_pLODModelThing; +} + +CAttributeData * CRaceData::GetAttributeDataPtr() +{ + if (m_strAttributeFileName.empty()) + return NULL; + + if (!CResourceManager::Instance().IsFileExist(m_strAttributeFileName.c_str())) + return NULL; + + return (CAttributeData *)CResourceManager::Instance().GetResourcePointer(m_strAttributeFileName.c_str()); +} + +BOOL CRaceData::GetAttachingBoneName(DWORD dwPartIndex, const char ** c_pszBoneName) +{ + TAttachingBoneNameMap::iterator itor = m_AttachingBoneNameMap.find(dwPartIndex); + if (itor == m_AttachingBoneNameMap.end()) + return FALSE; + + const std::string & c_rstrBoneName = itor->second; + + *c_pszBoneName = c_rstrBoneName.c_str(); + + return TRUE; +} + +BOOL CRaceData::IsTree() +{ + return !m_strTreeFileName.empty(); +} + +const char * CRaceData::GetTreeFileName() +{ + return m_strTreeFileName.c_str(); +} + +void CRaceData::Destroy() +{ + m_kMap_dwHairKey_kHair.clear(); + m_kMap_dwShapeKey_kShape.clear(); + + m_strBaseModelFileName = ""; + m_strTreeFileName = ""; + m_strAttributeFileName = ""; + m_strMotionListFileName = "motlist.txt"; + + m_AttachingBoneNameMap.clear(); + m_ModelDataMap.clear(); + + m_NormalAttackIndexMap.clear(); + m_ComboAttackDataMap.clear(); + + TMotionModeDataMap::iterator itorMode = m_pMotionModeDataMap.begin(); + for (; itorMode != m_pMotionModeDataMap.end(); ++itorMode) + { + TMotionModeData * pMotionModeData = itorMode->second; + + TMotionVectorMap::iterator itorMotion = pMotionModeData->MotionVectorMap.begin(); + for (; itorMotion != pMotionModeData->MotionVectorMap.end(); ++itorMotion) + { + TMotionVector & rMotionVector = itorMotion->second; + for (DWORD i = 0; i < rMotionVector.size(); ++i) + { + CRaceMotionData::Delete(rMotionVector[i].pMotionData); + } + } + + ms_MotionModeDataPool.Free(pMotionModeData); + } + m_pMotionModeDataMap.clear(); + + __Initialize(); +} + +void CRaceData::__Initialize() +{ + m_strMotionListFileName = "motlist.txt"; + + m_pBaseModelThing = NULL; + m_pLODModelThing = NULL; + + m_dwRaceIndex = 0; + + memset(m_adwSmokeEffectID, 0, sizeof(m_adwSmokeEffectID)); +} + +CRaceData::CRaceData() +{ + __Initialize(); +} +CRaceData::~CRaceData() +{ + Destroy(); +} \ No newline at end of file diff --git a/source/GameLib/RaceData.h b/source/GameLib/RaceData.h new file mode 100644 index 0000000..94d43d0 --- /dev/null +++ b/source/GameLib/RaceData.h @@ -0,0 +1,238 @@ +#pragma once + +#include "../eterGrnLib/Thing.h" + +class CRaceMotionData; +class CAttributeData; + +#define COMBO_KEY DWORD +#define MAKE_COMBO_KEY(motion_mode, combo_type) ( (DWORD(motion_mode) << 16) | (DWORD(combo_type)) ) +#define COMBO_KEY_GET_MOTION_MODE(key) ( WORD(DWORD(key) >> 16 & 0xFFFF) ) +#define COMBO_KEY_GET_COMBO_TYPE(key) ( WORD(DWORD(key) & 0xFFFF) ) + +class CRaceData +{ + public: + enum EParts + { + // Share index with server + // ECharacterEquipmentPart ּ. + //Ŷ ũⰡ մϴ ּ߰. + PART_MAIN, + PART_WEAPON, + PART_HEAD, + PART_WEAPON_LEFT, + PART_HAIR, + + PART_MAX_NUM, + }; + + enum + { + SMOKE_NUM = 4, + }; + + ///////////////////////////////////////////////////////////////////////////////// + // Graphic Resource + + // Model + typedef std::map TGraphicThingMap; + typedef std::map TAttachingBoneNameMap; + + // Motion + typedef struct SMotion + { + BYTE byPercentage; + CGraphicThing * pMotion; + CRaceMotionData * pMotionData; + } TMotion; + typedef std::vector TMotionVector; + typedef std::map TMotionVectorMap; + + typedef struct SMotionModeData + { + WORD wMotionModeIndex; + + TMotionVectorMap MotionVectorMap; + + SMotionModeData() {} + virtual ~SMotionModeData() {} + } TMotionModeData; + typedef std::map TMotionModeDataMap; + typedef TMotionModeDataMap::iterator TMotionModeDataIterator; + + ///////////////////////////////////////////////////////////////////////////////// + // Model Data + typedef struct SModelData + { + NRaceData::TAttachingDataVector AttachingDataVector; + } TModelData; + typedef std::map TModelDataMap; + typedef TModelDataMap::iterator TModelDataMapIterator; + + ///////////////////////////////////////////////////////////////////////////////// + // Motion Data + typedef std::map TMotionDataMap; + + ///////////////////////////////////////////////////////////////////////////////// + // Combo Data + typedef std::vector TComboIndexVector; + typedef struct SComboAttackData + { + TComboIndexVector ComboIndexVector; + } TComboData; + typedef std::map TNormalAttackIndexMap; + typedef std::map TComboAttackDataMap; + typedef TComboAttackDataMap::iterator TComboAttackDataIterator; + + struct SSkin + { + int m_ePart; + + std::string m_stSrcFileName; + std::string m_stDstFileName; + + SSkin() + { + m_ePart=0; + } + SSkin(const SSkin& c_rkSkin) + { + Copy(c_rkSkin); + } + void operator=(const SSkin& c_rkSkin) + { + Copy(c_rkSkin); + } + void Copy(const SSkin& c_rkSkin) + { + m_ePart=c_rkSkin.m_ePart; + m_stSrcFileName=c_rkSkin.m_stSrcFileName; + m_stDstFileName=c_rkSkin.m_stDstFileName; + } + }; + + struct SHair + { + std::string m_stModelFileName; + std::vector m_kVct_kSkin; + }; + + struct SShape + { + std::string m_stModelFileName; + std::vector m_kVct_kSkin; + }; + + public: + static CRaceData* New(); + static void Delete(CRaceData* pkRaceData); + static void CreateSystem(UINT uCapacity, UINT uMotModeCapacity); + static void DestroySystem(); + + public: + CRaceData(); + virtual ~CRaceData(); + + void Destroy(); + + // Codes For Client + const char* GetBaseModelFileName() const; + const char* GetAttributeFileName() const; + const char* GetMotionListFileName() const; + CGraphicThing * GetBaseModelThing(); + CGraphicThing * GetLODModelThing(); + CAttributeData * GetAttributeDataPtr(); + BOOL GetAttachingBoneName(DWORD dwPartIndex, const char ** c_pszBoneName); + BOOL CreateMotionModeIterator(TMotionModeDataIterator & itor); + BOOL NextMotionModeIterator(TMotionModeDataIterator & itor); + + BOOL GetMotionKey(WORD wMotionModeIndex, WORD wMotionIndex, MOTION_KEY * pMotionKey); + + BOOL GetMotionModeDataPointer(WORD wMotionMode, TMotionModeData ** ppMotionModeData); + BOOL GetModelDataPointer(DWORD dwModelIndex, const TModelData ** c_ppModelData); + BOOL GetMotionVectorPointer(WORD wMotionMode, WORD wMotionIndex, const TMotionVector ** c_ppMotionVector); + BOOL GetMotionDataPointer(WORD wMotionMode, WORD wMotionIndex, WORD wMotionSubIndex, CRaceMotionData** ppMotionData); + BOOL GetMotionDataPointer(DWORD dwMotionKey, CRaceMotionData ** ppMotionData); + + DWORD GetAttachingDataCount(); + BOOL GetAttachingDataPointer(DWORD dwIndex, const NRaceData::TAttachingData ** c_ppAttachingData); + BOOL GetCollisionDataPointer(DWORD dwIndex, const NRaceData::TAttachingData ** c_ppAttachingData); + BOOL GetBodyCollisionDataPointer(const NRaceData::TAttachingData ** c_ppAttachingData); + + BOOL IsTree(); + const char * GetTreeFileName(); + + /////////////////////////////////////////////////////////////////// + // Setup by Script + BOOL LoadRaceData(const char * c_szFileName); + + CGraphicThing* RegisterMotionData(WORD wMotionMode, WORD wMotionIndex, const char * c_szFileName, BYTE byPercentage = 100); + + /////////////////////////////////////////////////////////////////// + // Setup by Python + void SetRace(DWORD dwRaceIndex); + void RegisterAttachingBoneName(DWORD dwPartIndex, const char * c_szBoneName); + + void RegisterMotionMode(WORD wMotionModeIndex); + void SetMotionModeParent(WORD wParentMotionModeIndex, WORD wMotionModeIndex); + void OLD_RegisterMotion(WORD wMotionModeIndex, WORD wMotionIndex, const char * c_szFileName, BYTE byPercentage = 100); + CGraphicThing* NEW_RegisterMotion(CRaceMotionData* pkMotionData, WORD wMotionModeIndex, WORD wMotionIndex, const char * c_szFileName, BYTE byPercentage = 100); + bool SetMotionRandomWeight(WORD wMotionModeIndex, WORD wMotionIndex, WORD wMotionSubIndex, BYTE byPercentage); + + void RegisterNormalAttack(WORD wMotionModeIndex, WORD wMotionIndex); + BOOL GetNormalAttackIndex(WORD wMotionModeIndex, WORD * pwMotionIndex); + + void ReserveComboAttack(WORD wMotionModeIndex, WORD wComboType, DWORD dwComboCount); + void RegisterComboAttack(WORD wMotionModeIndex, WORD wComboType, DWORD dwComboIndex, WORD wMotionIndex); + BOOL GetComboDataPointer(WORD wMotionModeIndex, WORD wComboType, TComboData ** ppComboData); + + void SetShapeModel(UINT eShape, const char* c_szModelFileName); + void AppendShapeSkin(UINT eShape, UINT ePart, const char* c_szSrcFileName, const char* c_szDstFileName); + + void SetHairSkin(UINT eHair, UINT ePart, const char* c_szModelFileName, const char* c_szSrcFileName, const char* c_szDstFileName); + + ///// + + DWORD GetSmokeEffectID(UINT eSmoke); + + const std::string& GetSmokeBone(); + + SHair* FindHair(UINT eHair); + SShape* FindShape(UINT eShape); + + protected: + void __Initialize(); + + void __OLD_RegisterMotion(WORD wMotionMode, WORD wMotionIndex, const TMotion & rMotion); + + BOOL GetMotionVectorPointer(WORD wMotionMode, WORD wMotionIndex, TMotionVector ** ppMotionVector); + + protected: + DWORD m_dwRaceIndex; + DWORD m_adwSmokeEffectID[SMOKE_NUM]; + + CGraphicThing * m_pBaseModelThing; + CGraphicThing * m_pLODModelThing; + + std::string m_strBaseModelFileName; + std::string m_strTreeFileName; + std::string m_strAttributeFileName; + std::string m_strMotionListFileName; + std::string m_strSmokeBoneName; + + TModelDataMap m_ModelDataMap; + TMotionModeDataMap m_pMotionModeDataMap; + TAttachingBoneNameMap m_AttachingBoneNameMap; + TComboAttackDataMap m_ComboAttackDataMap; + TNormalAttackIndexMap m_NormalAttackIndexMap; + + std::map m_kMap_dwHairKey_kHair; + std::map m_kMap_dwShapeKey_kShape; + + NRaceData::TAttachingDataVector m_AttachingDataVector; + + protected: + static CDynamicPool ms_MotionModeDataPool; + static CDynamicPool ms_kPool; +}; diff --git a/source/GameLib/RaceDataFile.cpp b/source/GameLib/RaceDataFile.cpp new file mode 100644 index 0000000..809965e --- /dev/null +++ b/source/GameLib/RaceDataFile.cpp @@ -0,0 +1,186 @@ +#include "StdAfx.h" +#include "../eterLib/ResourceManager.h" + +#include "RaceData.h" +#include "RaceMotionData.h" + +///////////////////////////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////////////////////////// + +BOOL CRaceData::LoadRaceData(const char * c_szFileName) +{ + CTextFileLoader TextFileLoader; + if (!TextFileLoader.Load(c_szFileName)) + return FALSE; + + TextFileLoader.SetTop(); + + TextFileLoader.GetTokenString("basemodelfilename", &m_strBaseModelFileName); + TextFileLoader.GetTokenString("treefilename", &m_strTreeFileName); + TextFileLoader.GetTokenString("attributefilename", &m_strAttributeFileName); + TextFileLoader.GetTokenString("smokebonename", &m_strSmokeBoneName); + TextFileLoader.GetTokenString("motionlistfilename", &m_strMotionListFileName); + + if (!m_strTreeFileName.empty()) + { + CFileNameHelper::StringPath(m_strTreeFileName); + } + + CTokenVector* pSmokeTokenVector; + if (TextFileLoader.GetTokenVector("smokefilename", &pSmokeTokenVector)) + { + if (pSmokeTokenVector->size()%2!=0) + { + TraceError("SmokeFileName ArgCount[%d]%2==0", pSmokeTokenVector->size()); + return FALSE; + } + + UINT uLineCount=pSmokeTokenVector->size()/2; + + for (UINT uLine=0; uLineat(uLine*2+0).c_str()); + if (eSmoke<0 || eSmoke>=SMOKE_NUM) + { + TraceError("SmokeFileName SmokeNum[%d] OUT OF RANGE", eSmoke); + return FALSE; + } + + const std::string& c_rstrEffectFileName = pSmokeTokenVector->at(uLine*2+1); + + DWORD& rdwCRCEft=m_adwSmokeEffectID[eSmoke]; + if (!CEffectManager::Instance().RegisterEffect2(c_rstrEffectFileName.c_str(), &rdwCRCEft)) + { + TraceError("CRaceData::RegisterEffect2(%s) ERROR", c_rstrEffectFileName.c_str()); + rdwCRCEft=0; + return false; + } + } + } + + if (TextFileLoader.SetChildNode("shapedata")) + { + std::string strPathName; + DWORD dwShapeDataCount = 0; + if (TextFileLoader.GetTokenString("pathname", &strPathName) && + TextFileLoader.GetTokenDoubleWord("shapedatacount", &dwShapeDataCount)) + { + for (DWORD i = 0; i < dwShapeDataCount; ++i) + { + if (!TextFileLoader.SetChildNode("shapedata", i)) + { + continue; + } + + ///////////////////////// + // Temporary - ̺Ʈ ӽ + TextFileLoader.GetTokenString("specialpath", &strPathName); + ///////////////////////// + + DWORD dwShapeIndex; + if (!TextFileLoader.GetTokenDoubleWord("shapeindex", &dwShapeIndex)) + { + continue; + } + + // LOCAL_PATH_SUPPORT + std::string strModel; + if (TextFileLoader.GetTokenString("model", &strModel)) + { + SetShapeModel(dwShapeIndex, (strPathName + strModel).c_str()); + } + else + { + if (!TextFileLoader.GetTokenString("local_model", &strModel)) + continue; + + SetShapeModel(dwShapeIndex, strModel.c_str()); + } + // END_OF_LOCAL_PATH_SUPPORT + + + + std::string strSourceSkin; + std::string strTargetSkin; + + // LOCAL_PATH_SUPPORT + if (TextFileLoader.GetTokenString("local_sourceskin", &strSourceSkin) && + TextFileLoader.GetTokenString("local_targetskin", &strTargetSkin)) + { + AppendShapeSkin(dwShapeIndex, 0, strSourceSkin.c_str(), strTargetSkin.c_str()); + } + // END_OF_LOCAL_PATH_SUPPORT + + if (TextFileLoader.GetTokenString("sourceskin", &strSourceSkin) && + TextFileLoader.GetTokenString("targetskin", &strTargetSkin)) + { + AppendShapeSkin(dwShapeIndex, 0, (strPathName + strSourceSkin).c_str(), (strPathName + strTargetSkin).c_str()); + } + + if (TextFileLoader.GetTokenString("sourceskin2", &strSourceSkin) && + TextFileLoader.GetTokenString("targetskin2", &strTargetSkin)) + { + AppendShapeSkin(dwShapeIndex, 0, (strPathName + strSourceSkin).c_str(), (strPathName + strTargetSkin).c_str()); + } + + TextFileLoader.SetParentNode(); + } + } + + TextFileLoader.SetParentNode(); + } + + if (TextFileLoader.SetChildNode("hairdata")) + { + std::string strPathName; + DWORD dwHairDataCount = 0; + if (TextFileLoader.GetTokenString("pathname", &strPathName) && + TextFileLoader.GetTokenDoubleWord("hairdatacount", &dwHairDataCount)) + { + + for (DWORD i = 0; i < dwHairDataCount; ++i) + { + if (!TextFileLoader.SetChildNode("hairdata", i)) + { + continue; + } + + ///////////////////////// + // Temporary - ̺Ʈ ӽ + TextFileLoader.GetTokenString("specialpath", &strPathName); + ///////////////////////// + + DWORD dwShapeIndex; + if (!TextFileLoader.GetTokenDoubleWord("hairindex", &dwShapeIndex)) + { + continue; + } + + std::string strModel; + std::string strSourceSkin; + std::string strTargetSkin; + if (TextFileLoader.GetTokenString("model", &strModel) && + TextFileLoader.GetTokenString("sourceskin", &strSourceSkin) && + TextFileLoader.GetTokenString("targetskin", &strTargetSkin)) + { + SetHairSkin(dwShapeIndex, 0, (strPathName + strModel).c_str(), (strPathName + strSourceSkin).c_str(), (strPathName + strTargetSkin).c_str()); + } + + TextFileLoader.SetParentNode(); + } + } + + TextFileLoader.SetParentNode(); + } + + + if (TextFileLoader.SetChildNode("attachingdata")) + { + if (!NRaceData::LoadAttachingData(TextFileLoader, &m_AttachingDataVector)) + return FALSE; + + TextFileLoader.SetParentNode(); + } + + return TRUE; +} diff --git a/source/GameLib/RaceManager.cpp b/source/GameLib/RaceManager.cpp new file mode 100644 index 0000000..9a28aa3 --- /dev/null +++ b/source/GameLib/RaceManager.cpp @@ -0,0 +1,451 @@ +#include "StdAfx.h" +#include "RaceManager.h" +#include "RaceMotionData.h" +#include "../EterPack/EterPackManager.h" + +bool __IsGuildRace(unsigned race) +{ + if (race >= 14000 && race < 15000) + return true; + + if (20043 == race) + return true; + + return false; +} + +bool __IsNPCRace(unsigned race) +{ + if (race > 9000) + return true; + + return false; +} + +void __GetRaceResourcePathes(unsigned race, std::vector & vec_stPathes) +{ + if (__IsGuildRace(race)) + { + vec_stPathes.push_back ("d:/ymir work/guild/"); + vec_stPathes.push_back ("d:/ymir work/npc/"); + vec_stPathes.push_back ("d:/ymir work/npc2/"); + vec_stPathes.push_back ("d:/ymir work/monster/"); + vec_stPathes.push_back ("d:/ymir work/monster2/"); + } + else if (__IsNPCRace(race)) + { + if (race >= 30000) + { + vec_stPathes.push_back ("d:/ymir work/npc2/"); + vec_stPathes.push_back ("d:/ymir work/npc/"); + vec_stPathes.push_back ("d:/ymir work/monster/"); + vec_stPathes.push_back ("d:/ymir work/monster2/"); + vec_stPathes.push_back ("d:/ymir work/guild/"); + } + else + { + vec_stPathes.push_back ("d:/ymir work/npc/"); + vec_stPathes.push_back ("d:/ymir work/npc2/"); + vec_stPathes.push_back ("d:/ymir work/monster/"); + vec_stPathes.push_back ("d:/ymir work/monster2/"); + vec_stPathes.push_back ("d:/ymir work/guild/"); + } + } + // ̺Ʈ + else if (8507 == race || 8510 == race) + { + vec_stPathes.push_back ("d:/ymir work/monster2/"); + vec_stPathes.push_back ("d:/ymir work/monster/"); + vec_stPathes.push_back ("d:/ymir work/npc/"); + vec_stPathes.push_back ("d:/ymir work/npc2/"); + vec_stPathes.push_back ("d:/ymir work/guild/"); + } + else if (race > 8000) + { + vec_stPathes.push_back ("d:/ymir work/monster/"); + vec_stPathes.push_back ("d:/ymir work/monster2/"); + vec_stPathes.push_back ("d:/ymir work/npc/"); + vec_stPathes.push_back ("d:/ymir work/npc2/"); + vec_stPathes.push_back ("d:/ymir work/guild/"); + } + else if (race > 2000) + { + vec_stPathes.push_back ("d:/ymir work/monster2/"); + vec_stPathes.push_back ("d:/ymir work/monster/"); + vec_stPathes.push_back ("d:/ymir work/npc/"); + vec_stPathes.push_back ("d:/ymir work/npc2/"); + vec_stPathes.push_back ("d:/ymir work/guild/"); + } + else if (race>=1400 && race<=1700) + { + vec_stPathes.push_back ("d:/ymir work/monster2/"); + vec_stPathes.push_back ("d:/ymir work/monster/"); + vec_stPathes.push_back ("d:/ymir work/npc/"); + vec_stPathes.push_back ("d:/ymir work/npc2/"); + vec_stPathes.push_back ("d:/ymir work/guild/"); + } + else + { + vec_stPathes.push_back ("d:/ymir work/monster/"); + vec_stPathes.push_back ("d:/ymir work/monster2/"); + vec_stPathes.push_back ("d:/ymir work/npc/"); + vec_stPathes.push_back ("d:/ymir work/npc2/"); + vec_stPathes.push_back ("d:/ymir work/guild/"); + } + return; +} + +CRaceData* CRaceManager::__LoadRaceData(DWORD dwRaceIndex) +{ + std::map::iterator fRaceName=m_kMap_dwRaceKey_stRaceName.find(dwRaceIndex); + if (m_kMap_dwRaceKey_stRaceName.end()==fRaceName) + return NULL; + + const std::string& c_rstRaceName=fRaceName->second; + + if (c_rstRaceName.empty()) + return NULL; + + // LOAD_LOCAL_RESOURCE + if (c_rstRaceName[0] == '#') + { + const char* pathName = c_rstRaceName.c_str() + 1; + char shapeFileName[256]; + char motionListFileName[256]; + _snprintf(shapeFileName, sizeof(shapeFileName), "%sshape.msm", pathName); + _snprintf(motionListFileName, sizeof(motionListFileName), "%smotlist.txt", pathName); + + CRaceData * pRaceData = CRaceData::New(); + pRaceData->SetRace(dwRaceIndex); + if (!pRaceData->LoadRaceData(shapeFileName)) + { + TraceError("CRaceManager::RegisterRacePath(race=%u).LoadRaceData(%s)", dwRaceIndex, shapeFileName); + CRaceData::Delete(pRaceData); + return NULL; + } + + __LoadRaceMotionList(*pRaceData, pathName, motionListFileName); + + return pRaceData; + } + // END_OF_LOAD_LOCAL_RESOURCE + std::vector vec_stFullPathName; + __GetRaceResourcePathes(dwRaceIndex, vec_stFullPathName); + + CRaceData * pRaceData = CRaceData::New(); + pRaceData->SetRace(dwRaceIndex); + + for (int i = 0; i < vec_stFullPathName.size(); i++) + { + std::string stFullPathName = vec_stFullPathName[i]; + { + std::map::iterator fRaceSrcName=m_kMap_stRaceName_stSrcName.find(c_rstRaceName); + if (m_kMap_stRaceName_stSrcName.end()==fRaceSrcName) + stFullPathName+=c_rstRaceName; + else + stFullPathName+=fRaceSrcName->second; + } + + stFullPathName+="/"; + + std::string stMSMFileName=stFullPathName; + stMSMFileName+=c_rstRaceName; + stMSMFileName+=".msm"; + + if (!pRaceData->LoadRaceData(stMSMFileName.c_str())) + { + if (i != vec_stFullPathName.size() - 1) + { + TraceError("CRaceManager::RegisterRacePath : RACE[%u] LOAD MSMFILE[%s] ERROR. Will Find Another Path.", dwRaceIndex, stMSMFileName.c_str()); + continue; + } + + TraceError("CRaceManager::RegisterRacePath : RACE[%u] LOAD MSMFILE[%s] ERROR", dwRaceIndex, stMSMFileName.c_str()); + CRaceData::Delete(pRaceData); + return NULL; + } + + std::string stMotionListFileName=stFullPathName; + stMotionListFileName+=pRaceData->GetMotionListFileName(); + + __LoadRaceMotionList(*pRaceData, stFullPathName.c_str(), stMotionListFileName.c_str()); + + return pRaceData; + } + TraceError("CRaceManager::RegisterRacePath : RACE[%u] HAVE NO PATH ERROR", dwRaceIndex); + CRaceData::Delete(pRaceData); + return NULL; +} + +bool CRaceManager::__LoadRaceMotionList(CRaceData& rkRaceData, const char* pathName, const char* motionListFileName) +{ + static std::map s_kMap_stType_dwIndex; + static bool s_isInit=false; + + if (!s_isInit) + { + s_isInit=true; + + s_kMap_stType_dwIndex.insert(std::map::value_type("SPAWN", CRaceMotionData::NAME_SPAWN)); + s_kMap_stType_dwIndex.insert(std::map::value_type("WAIT", CRaceMotionData::NAME_WAIT)); + s_kMap_stType_dwIndex.insert(std::map::value_type("WAIT1", CRaceMotionData::NAME_WAIT)); + s_kMap_stType_dwIndex.insert(std::map::value_type("WAIT2", CRaceMotionData::NAME_WAIT)); + s_kMap_stType_dwIndex.insert(std::map::value_type("WALK", CRaceMotionData::NAME_WALK)); + s_kMap_stType_dwIndex.insert(std::map::value_type("WALK1", CRaceMotionData::NAME_WALK)); + s_kMap_stType_dwIndex.insert(std::map::value_type("WALK2", CRaceMotionData::NAME_WALK)); + s_kMap_stType_dwIndex.insert(std::map::value_type("RUN", CRaceMotionData::NAME_RUN)); + s_kMap_stType_dwIndex.insert(std::map::value_type("RUN1", CRaceMotionData::NAME_RUN)); + s_kMap_stType_dwIndex.insert(std::map::value_type("RUN2", CRaceMotionData::NAME_RUN)); + s_kMap_stType_dwIndex.insert(std::map::value_type("STOP", CRaceMotionData::NAME_STOP)); + s_kMap_stType_dwIndex.insert(std::map::value_type("DEAD", CRaceMotionData::NAME_DEAD)); + s_kMap_stType_dwIndex.insert(std::map::value_type("COMBO_ATTACK", CRaceMotionData::NAME_COMBO_ATTACK_1)); + s_kMap_stType_dwIndex.insert(std::map::value_type("COMBO_ATTACK1", CRaceMotionData::NAME_COMBO_ATTACK_2)); + s_kMap_stType_dwIndex.insert(std::map::value_type("COMBO_ATTACK2", CRaceMotionData::NAME_COMBO_ATTACK_3)); + s_kMap_stType_dwIndex.insert(std::map::value_type("NORMAL_ATTACK", CRaceMotionData::NAME_NORMAL_ATTACK)); + s_kMap_stType_dwIndex.insert(std::map::value_type("NORMAL_ATTACK1", CRaceMotionData::NAME_NORMAL_ATTACK)); + s_kMap_stType_dwIndex.insert(std::map::value_type("NORMAL_ATTACK2", CRaceMotionData::NAME_NORMAL_ATTACK)); + s_kMap_stType_dwIndex.insert(std::map::value_type("FRONT_DAMAGE", CRaceMotionData::NAME_DAMAGE)); + s_kMap_stType_dwIndex.insert(std::map::value_type("FRONT_DAMAGE1", CRaceMotionData::NAME_DAMAGE)); + s_kMap_stType_dwIndex.insert(std::map::value_type("FRONT_DAMAGE2", CRaceMotionData::NAME_DAMAGE)); + s_kMap_stType_dwIndex.insert(std::map::value_type("FRONT_DAMAGE3", CRaceMotionData::NAME_DAMAGE)); + s_kMap_stType_dwIndex.insert(std::map::value_type("FRONT_DEAD", CRaceMotionData::NAME_DEAD)); + s_kMap_stType_dwIndex.insert(std::map::value_type("FRONT_DEAD1", CRaceMotionData::NAME_DEAD)); + s_kMap_stType_dwIndex.insert(std::map::value_type("FRONT_DEAD2", CRaceMotionData::NAME_DEAD)); + s_kMap_stType_dwIndex.insert(std::map::value_type("FRONT_KNOCKDOWN", CRaceMotionData::NAME_DAMAGE_FLYING)); + s_kMap_stType_dwIndex.insert(std::map::value_type("FRONT_KNOCKDOWN1", CRaceMotionData::NAME_DAMAGE_FLYING)); + s_kMap_stType_dwIndex.insert(std::map::value_type("FRONT_STANDUP", CRaceMotionData::NAME_STAND_UP)); + s_kMap_stType_dwIndex.insert(std::map::value_type("FRONT_STANDUP1", CRaceMotionData::NAME_STAND_UP)); + s_kMap_stType_dwIndex.insert(std::map::value_type("BACK_DAMAGE", CRaceMotionData::NAME_DAMAGE_BACK)); + s_kMap_stType_dwIndex.insert(std::map::value_type("BACK_DAMAGE1", CRaceMotionData::NAME_DAMAGE_BACK)); + s_kMap_stType_dwIndex.insert(std::map::value_type("BACK_DEAD", CRaceMotionData::NAME_DEAD_BACK)); + s_kMap_stType_dwIndex.insert(std::map::value_type("BACK_DEAD1", CRaceMotionData::NAME_DEAD_BACK)); + s_kMap_stType_dwIndex.insert(std::map::value_type("BACK_DEAD2", CRaceMotionData::NAME_DEAD_BACK)); + s_kMap_stType_dwIndex.insert(std::map::value_type("BACK_KNOCKDOWN", CRaceMotionData::NAME_DAMAGE_FLYING_BACK)); + s_kMap_stType_dwIndex.insert(std::map::value_type("BACK_KNOCKDOWN1", CRaceMotionData::NAME_DAMAGE_FLYING_BACK)); + s_kMap_stType_dwIndex.insert(std::map::value_type("BACK_STANDUP", CRaceMotionData::NAME_STAND_UP_BACK)); + s_kMap_stType_dwIndex.insert(std::map::value_type("BACK_STANDUP1", CRaceMotionData::NAME_STAND_UP_BACK)); + s_kMap_stType_dwIndex.insert(std::map::value_type("SPECIAL", CRaceMotionData::NAME_SPECIAL_1)); + s_kMap_stType_dwIndex.insert(std::map::value_type("SPECIAL1", CRaceMotionData::NAME_SPECIAL_2)); + s_kMap_stType_dwIndex.insert(std::map::value_type("SPECIAL2", CRaceMotionData::NAME_SPECIAL_3)); + s_kMap_stType_dwIndex.insert(std::map::value_type("SPECIAL3", CRaceMotionData::NAME_SPECIAL_4)); + s_kMap_stType_dwIndex.insert(std::map::value_type("SPECIAL4", CRaceMotionData::NAME_SPECIAL_5)); + s_kMap_stType_dwIndex.insert(std::map::value_type("SPECIAL5", CRaceMotionData::NAME_SPECIAL_6)); + s_kMap_stType_dwIndex.insert(std::map::value_type("SKILL1", CRaceMotionData::NAME_SKILL+121)); + s_kMap_stType_dwIndex.insert(std::map::value_type("SKILL2", CRaceMotionData::NAME_SKILL+122)); + s_kMap_stType_dwIndex.insert(std::map::value_type("SKILL3", CRaceMotionData::NAME_SKILL+123)); + s_kMap_stType_dwIndex.insert(std::map::value_type("SKILL4", CRaceMotionData::NAME_SKILL+124)); + s_kMap_stType_dwIndex.insert(std::map::value_type("SKILL5", CRaceMotionData::NAME_SKILL+125)); + } + + const void* pvData; + CMappedFile kMappedFile; + if (!CEterPackManager::Instance().Get(kMappedFile, motionListFileName, &pvData)) + return false; + + + CMemoryTextFileLoader kTextFileLoader; + kTextFileLoader.Bind(kMappedFile.Size(), pvData); + + rkRaceData.RegisterMotionMode(CRaceMotionData::MODE_GENERAL); + + char szMode[256]; + char szType[256]; + char szFile[256]; + int nPercent = 0; + + bool isSpawn=false; + + static std::string stSpawnMotionFileName; + static std::string stMotionFileName; + + stSpawnMotionFileName = ""; + stMotionFileName = ""; + + UINT uLineCount=kTextFileLoader.GetLineCount(); + for (UINT uLineIndex=0; uLineIndex::iterator fTypeIndex=s_kMap_stType_dwIndex.find(szType); + + if (s_kMap_stType_dwIndex.end() == fTypeIndex) + { + // Ͽ WAIT, WAIT4, WAIT20 ̷ ϵǾ , + // WAIT4, WAIT20 WAIT ν ֵ ó + const size_t c_cutLengthLimit = 2; + bool bFound = false; + + if (c_cutLengthLimit < strlen(szType) + 1) + { + for (size_t i = 1; i <= c_cutLengthLimit; ++i) + { + std::string typeName = std::string(szType).substr(0, strlen(szType) - i); + fTypeIndex = s_kMap_stType_dwIndex.find(typeName); + + if (s_kMap_stType_dwIndex.end() != fTypeIndex) + { + bFound = true; + break; + } + } + } + + if (false == bFound) + continue; + } + + motionType = fTypeIndex->second; + + stMotionFileName = pathName; + stMotionFileName += szFile; + + rkRaceData.RegisterMotionData(CRaceMotionData::MODE_GENERAL, motionType, stMotionFileName.c_str(), nPercent); + + switch (motionType) + { + case CRaceMotionData::NAME_SPAWN: + isSpawn=true; + break; + case CRaceMotionData::NAME_DAMAGE: + stSpawnMotionFileName=stMotionFileName; + break; + } + } + + if (!isSpawn && stSpawnMotionFileName!="") + { + rkRaceData.RegisterMotionData(CRaceMotionData::MODE_GENERAL, CRaceMotionData::NAME_SPAWN, stSpawnMotionFileName.c_str(), nPercent); + } + + rkRaceData.RegisterNormalAttack(CRaceMotionData::MODE_GENERAL, CRaceMotionData::NAME_NORMAL_ATTACK); + + return true; +} + +void CRaceManager::RegisterRaceSrcName(const char * c_szName, const char * c_szSrcName) +{ + m_kMap_stRaceName_stSrcName.insert(std::map::value_type(c_szName, c_szSrcName)); +} + +void CRaceManager::RegisterRaceName(DWORD dwRaceIndex, const char * c_szName) +{ + m_kMap_dwRaceKey_stRaceName.insert(std::map::value_type(dwRaceIndex, c_szName)); +} + +void CRaceManager::CreateRace(DWORD dwRaceIndex) +{ + if (m_RaceDataMap.end() != m_RaceDataMap.find(dwRaceIndex)) + { + TraceError("RaceManager::CreateRace : Race %u already created", dwRaceIndex); + return; + } + + CRaceData * pRaceData = CRaceData::New(); + pRaceData->SetRace(dwRaceIndex); + m_RaceDataMap.insert(TRaceDataMap::value_type(dwRaceIndex, pRaceData)); + + Tracenf("CRaceManager::CreateRace(dwRaceIndex=%d)", dwRaceIndex); +} + +void CRaceManager::SelectRace(DWORD dwRaceIndex) +{ + TRaceDataIterator itor = m_RaceDataMap.find(dwRaceIndex); + if (m_RaceDataMap.end() == itor) + { + assert(!"Failed to select race data!"); + return; + } + + m_pSelectedRaceData = itor->second; +} + +CRaceData * CRaceManager::GetSelectedRaceDataPointer() +{ + return m_pSelectedRaceData; +} + +BOOL CRaceManager::GetRaceDataPointer(DWORD dwRaceIndex, CRaceData ** ppRaceData) +{ + TRaceDataIterator itor = m_RaceDataMap.find(dwRaceIndex); + + if (m_RaceDataMap.end() == itor) + { + CRaceData* pRaceData = __LoadRaceData(dwRaceIndex); + + if (pRaceData) + { + m_RaceDataMap.insert(TRaceDataMap::value_type(dwRaceIndex, pRaceData)); + *ppRaceData = pRaceData; + return TRUE; + } + + TraceError("CRaceManager::GetRaceDataPointer: cannot load data by dwRaceIndex %lu", dwRaceIndex); + return FALSE; + } + + *ppRaceData = itor->second; + return TRUE; +} + +void CRaceManager::SetPathName(const char * c_szPathName) +{ + m_strPathName = c_szPathName; +} + +const char * CRaceManager::GetFullPathFileName(const char * c_szFileName) +{ + static std::string s_stFileName; + + if (c_szFileName[0] != '.') + { + s_stFileName = m_strPathName; + s_stFileName += c_szFileName; + } + else + { + s_stFileName = c_szFileName; + } + + return s_stFileName.c_str(); +} + + +void CRaceManager::Create() +{ + CRaceMotionData::CreateSystem(2048); + CRaceData::CreateSystem(256, 512); +} + +void CRaceManager::__Initialize() +{ + m_pSelectedRaceData = NULL; +} + +void CRaceManager::__DestroyRaceDataMap() +{ + TRaceDataMap::iterator i; + for (i=m_RaceDataMap.begin(); i!=m_RaceDataMap.end(); ++i) + CRaceData::Delete(i->second); + + m_RaceDataMap.clear(); +} + +void CRaceManager::Destroy() +{ + __DestroyRaceDataMap(); + + __Initialize(); +} + +CRaceManager::CRaceManager() +{ + __Initialize(); +} + +CRaceManager::~CRaceManager() +{ + Destroy(); +} diff --git a/source/GameLib/RaceManager.h b/source/GameLib/RaceManager.h new file mode 100644 index 0000000..bdb0fbe --- /dev/null +++ b/source/GameLib/RaceManager.h @@ -0,0 +1,49 @@ +#pragma once + +#include "RaceData.h" + +class CRaceManager : public CSingleton +{ + public: + typedef std::map TRaceDataMap; + typedef TRaceDataMap::iterator TRaceDataIterator; + + public: + CRaceManager(); + virtual ~CRaceManager(); + + void Create(); + void Destroy(); + + void RegisterRaceName(DWORD dwRaceIndex, const char * c_szName); + void RegisterRaceSrcName(const char * c_szName, const char * c_szSrcName); + + void SetPathName(const char * c_szPathName); + const char * GetFullPathFileName(const char* c_szFileName); + + // Handling + void CreateRace(DWORD dwRaceIndex); + void SelectRace(DWORD dwRaceIndex); + CRaceData * GetSelectedRaceDataPointer(); + // Handling + + BOOL GetRaceDataPointer(DWORD dwRaceIndex, CRaceData ** ppRaceData); + + + protected: + CRaceData* __LoadRaceData(DWORD dwRaceIndex); + bool __LoadRaceMotionList(CRaceData& rkRaceData, const char* pathName, const char* motionListFileName); + + void __Initialize(); + void __DestroyRaceDataMap(); + + protected: + TRaceDataMap m_RaceDataMap; + + std::map m_kMap_stRaceName_stSrcName; + std::map m_kMap_dwRaceKey_stRaceName; + + private: + std::string m_strPathName; + CRaceData * m_pSelectedRaceData; +}; \ No newline at end of file diff --git a/source/GameLib/RaceMotionData.cpp b/source/GameLib/RaceMotionData.cpp new file mode 100644 index 0000000..e0e8c70 --- /dev/null +++ b/source/GameLib/RaceMotionData.cpp @@ -0,0 +1,617 @@ +#include "StdAfx.h" +#include "../EffectLib/EffectManager.h" +#include "FlyingObjectManager.h" +#include "RaceMotionData.h" + +CDynamicPool CRaceMotionData::ms_kPool; + +void CRaceMotionData::CreateSystem(UINT uCapacity) +{ + ms_kPool.Create(uCapacity); +} + +void CRaceMotionData::DestroySystem() +{ + ms_kPool.Clear(); +} + +CRaceMotionData* CRaceMotionData::New() +{ + return ms_kPool.Alloc(); +} + +void CRaceMotionData::Delete(CRaceMotionData* pkData) +{ + pkData->Destroy(); + + ms_kPool.Free(pkData); +} + +void CRaceMotionData::SetName(UINT eName) +{ + m_eName=eName; + + switch (m_eName) + { + case NAME_NONE: + SetType(TYPE_NONE); + break; + case NAME_WAIT: + case NAME_INTRO_WAIT: + case NAME_STOP: + SetType(TYPE_WAIT); + break; + case NAME_WALK: + case NAME_RUN: + SetType(TYPE_MOVE); + break; + case NAME_DAMAGE: + case NAME_DAMAGE_BACK: + SetType(TYPE_DAMAGE); + break; + case NAME_DAMAGE_FLYING: + case NAME_DAMAGE_FLYING_BACK: + SetType(TYPE_KNOCKDOWN); + break; + case NAME_STAND_UP: + case NAME_STAND_UP_BACK: + SetType(TYPE_STANDUP); + break; + case NAME_SPAWN: + case NAME_CHANGE_WEAPON: + case NAME_INTRO_SELECTED: + case NAME_INTRO_NOT_SELECTED: + case NAME_SPECIAL_1: + case NAME_SPECIAL_2: + case NAME_SPECIAL_3: + case NAME_SPECIAL_4: + case NAME_SPECIAL_5: + case NAME_SPECIAL_6: + case NAME_CLAP: + case NAME_DANCE_1: + case NAME_DANCE_2: + case NAME_DANCE_3: + case NAME_DANCE_4: + case NAME_DANCE_5: + case NAME_DANCE_6: + case NAME_CONGRATULATION: + case NAME_FORGIVE: + case NAME_ANGRY: + case NAME_ATTRACTIVE: + case NAME_SAD: + case NAME_SHY: + case NAME_CHEERUP: + case NAME_BANTER: + case NAME_JOY: + case NAME_CHEERS_1: + case NAME_CHEERS_2: + case NAME_KISS_WITH_WARRIOR: + case NAME_KISS_WITH_ASSASSIN: + case NAME_KISS_WITH_SURA: + case NAME_KISS_WITH_SHAMAN: + case NAME_FRENCH_KISS_WITH_WARRIOR: + case NAME_FRENCH_KISS_WITH_ASSASSIN: + case NAME_FRENCH_KISS_WITH_SURA: + case NAME_FRENCH_KISS_WITH_SHAMAN: + case NAME_SLAP_HIT_WITH_WARRIOR: + case NAME_SLAP_HIT_WITH_ASSASSIN: + case NAME_SLAP_HIT_WITH_SURA: + case NAME_SLAP_HIT_WITH_SHAMAN: + case NAME_SLAP_HURT_WITH_WARRIOR: + case NAME_SLAP_HURT_WITH_ASSASSIN: + case NAME_SLAP_HURT_WITH_SURA: + case NAME_SLAP_HURT_WITH_SHAMAN: + case NAME_DIG: + SetType(TYPE_EVENT); + break; + case NAME_DEAD: + case NAME_DEAD_BACK: + SetType(TYPE_DIE); + break; + case NAME_NORMAL_ATTACK: + SetType(TYPE_ATTACK); + break; + case NAME_COMBO_ATTACK_1: + case NAME_COMBO_ATTACK_2: + case NAME_COMBO_ATTACK_3: + case NAME_COMBO_ATTACK_4: + case NAME_COMBO_ATTACK_5: + case NAME_COMBO_ATTACK_6: + case NAME_COMBO_ATTACK_7: + case NAME_COMBO_ATTACK_8: + SetType(TYPE_COMBO); + break; + case NAME_FISHING_THROW: + case NAME_FISHING_WAIT: + case NAME_FISHING_REACT: + case NAME_FISHING_CATCH: + case NAME_FISHING_FAIL: + case NAME_FISHING_STOP: + SetType(TYPE_FISHING); + break; + default: + if (eName>=NAME_SKILL && eName<=NAME_SKILL+SKILL_NUM) + SetType(TYPE_SKILL); + else + TraceError("CRaceMotionData::SetName - UNKNOWN NAME %d", eName); + break; + } +} +void CRaceMotionData::SetType(UINT eType) +{ + m_eType=eType; + + switch (m_eType) + { + case TYPE_ATTACK: + case TYPE_COMBO: + case TYPE_SKILL: + m_isLock=TRUE; + break; + default: + m_isLock=FALSE; + break; + } +} + +UINT CRaceMotionData::GetType() const +{ + return m_eType; +} + +bool CRaceMotionData::IsLock() const +{ + return m_isLock ? true : false; +} + +int CRaceMotionData::GetLoopCount() const +{ + return m_iLoopCount; +} + +float CRaceMotionData::GetMotionDuration() +{ + return m_fMotionDuration; +} + +void CRaceMotionData::SetMotionDuration(float fDuration) +{ + m_fMotionDuration = fDuration; +} + +// Combo +BOOL CRaceMotionData::IsComboInputTimeData() const +{ + return m_isComboMotion; +} + +float CRaceMotionData::GetComboInputStartTime() const +{ + assert(m_isComboMotion); + return m_ComboInputData.fInputStartTime; +} + +float CRaceMotionData::GetNextComboTime() const +{ + assert(m_isComboMotion); + return m_ComboInputData.fNextComboTime; +} + +float CRaceMotionData::GetComboInputEndTime() const +{ + assert(m_isComboMotion); + return m_ComboInputData.fInputEndTime; +} + +// Attacking +BOOL CRaceMotionData::isAttackingMotion() const +{ + return m_isAttackingMotion; +} + +const NRaceData::TMotionAttackData * CRaceMotionData::GetMotionAttackDataPointer() const +{ + return & m_MotionAttackData; +} + +const NRaceData::TMotionAttackData & CRaceMotionData::GetMotionAttackDataReference() const +{ + assert(m_isAttackingMotion); + return m_MotionAttackData; +} + +BOOL CRaceMotionData::HasSplashMotionEvent() const +{ + return m_hasSplashEvent; +} + +// Skill +BOOL CRaceMotionData::IsCancelEnableSkill() const +{ + return m_bCancelEnableSkill; +} + +// Loop +BOOL CRaceMotionData::IsLoopMotion() const +{ + return m_isLoopMotion; +} + +float CRaceMotionData::GetLoopStartTime() const +{ + return m_fLoopStartTime; +} + +float CRaceMotionData::GetLoopEndTime() const +{ + return m_fLoopEndTime; +} + +// Motion Event Data +DWORD CRaceMotionData::GetMotionEventDataCount() const +{ + return m_MotionEventDataVector.size(); +} + +BOOL CRaceMotionData::GetMotionEventDataPointer(BYTE byIndex, const CRaceMotionData::TMotionEventData ** c_ppData) const +{ + if (byIndex >= m_MotionEventDataVector.size()) + return FALSE; + + *c_ppData = m_MotionEventDataVector[byIndex]; + + return TRUE; +} + +BOOL CRaceMotionData::GetMotionAttackingEventDataPointer(BYTE byIndex, const CRaceMotionData::TMotionAttackingEventData ** c_ppData) const +{ + if (byIndex >= m_MotionEventDataVector.size()) + return FALSE; + + const CRaceMotionData::TMotionEventData * pData = m_MotionEventDataVector[byIndex]; + const CRaceMotionData::TMotionAttackingEventData * pAttackingEvent = (const CRaceMotionData::TMotionAttackingEventData *)pData; + + if (MOTION_EVENT_TYPE_SPECIAL_ATTACKING == pAttackingEvent->iType) + return FALSE; + + *c_ppData = pAttackingEvent; + + return TRUE; +} + +int CRaceMotionData::GetEventType(DWORD dwIndex) const +{ + if (dwIndex >= m_MotionEventDataVector.size()) + return MOTION_EVENT_TYPE_NONE; + + return m_MotionEventDataVector[dwIndex]->iType; +} + +float CRaceMotionData::GetEventStartTime(DWORD dwIndex) const +{ + if (dwIndex >= m_MotionEventDataVector.size()) + return 0.0f; + + return m_MotionEventDataVector[dwIndex]->fStartingTime; +} + +const NSound::TSoundInstanceVector * CRaceMotionData::GetSoundInstanceVectorPointer() const +{ + return &m_SoundInstanceVector; +} + +void CRaceMotionData::SetAccumulationPosition(const TPixelPosition & c_rPos) +{ + m_accumulationPosition = c_rPos; + m_isAccumulationMotion = TRUE; +} + +bool CRaceMotionData::LoadMotionData(const char * c_szFileName) +{ + const float c_fFrameTime = 1.0f / g_fGameFPS; + + CTextFileLoader* pkTextFileLoader=CTextFileLoader::Cache(c_szFileName); + if (!pkTextFileLoader) + return false; + + CTextFileLoader& rkTextFileLoader=*pkTextFileLoader; + + if (rkTextFileLoader.IsEmpty()) + return false; + + rkTextFileLoader.SetTop(); + + if (!rkTextFileLoader.GetTokenString("motionfilename", &m_strMotionFileName)) + return false; + + if (!rkTextFileLoader.GetTokenFloat("motionduration", &m_fMotionDuration)) + return false; + + CTokenVector * pTokenVector; + + if (rkTextFileLoader.GetTokenVector("accumulation", &pTokenVector)) + { + if (pTokenVector->size() != 3) + { + TraceError("CRaceMotioNData::LoadMotionData : syntax error on accumulation, vector size %d", pTokenVector->size()); + return false; + } + + TPixelPosition pos(atof(pTokenVector->at(0).c_str()), + atof(pTokenVector->at(1).c_str()), + atof(pTokenVector->at(2).c_str())); + + SetAccumulationPosition(pos); + } + + std::string strNodeName; + for (DWORD i = 0; i < rkTextFileLoader.GetChildNodeCount(); ++i) + { + CTextFileLoader::CGotoChild GotoChild(&rkTextFileLoader, i); + + rkTextFileLoader.GetCurrentNodeName(&strNodeName); + + if (0 == strNodeName.compare("comboinputdata")) + { + m_isComboMotion = TRUE; + + if (!rkTextFileLoader.GetTokenFloat("preinputtime", &m_ComboInputData.fInputStartTime)) + return false; + if (!rkTextFileLoader.GetTokenFloat("directinputtime", &m_ComboInputData.fNextComboTime)) + return false; + if (!rkTextFileLoader.GetTokenFloat("inputlimittime", &m_ComboInputData.fInputEndTime)) + return false; + } + else if (0 == strNodeName.compare("attackingdata")) + { + m_isAttackingMotion = TRUE; + + if (!NRaceData::LoadMotionAttackData(rkTextFileLoader, &m_MotionAttackData)) + return false; + } + else if (0 == strNodeName.compare("loopdata")) + { + m_isLoopMotion = TRUE; + if (!rkTextFileLoader.GetTokenInteger("motionloopcount", &m_iLoopCount)) + { + m_iLoopCount = -1; + } + if (!rkTextFileLoader.GetTokenInteger("loopcancelenable", &m_bCancelEnableSkill)) + { + m_bCancelEnableSkill = FALSE; + } + if (!rkTextFileLoader.GetTokenFloat("loopstarttime", &m_fLoopStartTime)) + return false; + if (!rkTextFileLoader.GetTokenFloat("loopendtime", &m_fLoopEndTime)) + return false; + } + else if (0 == strNodeName.compare("motioneventdata")) + { + DWORD dwMotionEventDataCount; + + if (!rkTextFileLoader.GetTokenDoubleWord("motioneventdatacount", &dwMotionEventDataCount)) + continue; + + stl_wipe(m_MotionEventDataVector); + + m_MotionEventDataVector.resize(dwMotionEventDataCount, NULL); + + for (DWORD j = 0; j < m_MotionEventDataVector.size(); ++j) + { + if (!rkTextFileLoader.SetChildNode("event", j)) + return false; + + int iType; + if (!rkTextFileLoader.GetTokenInteger("motioneventtype", &iType)) + return false; + + TMotionEventData * pData = NULL; + switch(iType) + { + case MOTION_EVENT_TYPE_FLY: + pData = new TMotionFlyEventData; + break; + case MOTION_EVENT_TYPE_EFFECT: + pData = new TMotionEffectEventData; + break; + case MOTION_EVENT_TYPE_SCREEN_WAVING: + pData = new TScreenWavingEventData; + break; + case MOTION_EVENT_TYPE_SPECIAL_ATTACKING: + pData = new TMotionAttackingEventData; + m_hasSplashEvent = TRUE; + break; + case MOTION_EVENT_TYPE_SOUND: + pData = new TMotionSoundEventData; + break; + case MOTION_EVENT_TYPE_CHARACTER_SHOW: + pData = new TMotionCharacterShowEventData; + break; + case MOTION_EVENT_TYPE_CHARACTER_HIDE: + pData = new TMotionCharacterHideEventData; + break; + case MOTION_EVENT_TYPE_WARP: + pData = new TMotionWarpEventData; + break; + case MOTION_EVENT_TYPE_EFFECT_TO_TARGET: + pData = new TMotionEffectToTargetEventData; + break; + default: + assert(!" CRaceMotionData::LoadMotionData - Strange Event Type"); + return false; + break; + } + m_MotionEventDataVector[j] = pData; + m_MotionEventDataVector[j]->Load(rkTextFileLoader); + m_MotionEventDataVector[j]->iType = iType; + if (!rkTextFileLoader.GetTokenFloat("startingtime", &m_MotionEventDataVector[j]->fStartingTime)) + return false; + + m_MotionEventDataVector[j]->dwFrame = (m_MotionEventDataVector[j]->fStartingTime / c_fFrameTime); + + rkTextFileLoader.SetParentNode(); + } + } + } + + std::string strSoundFileNameTemp=c_szFileName; + strSoundFileNameTemp = CFileNameHelper::NoExtension(strSoundFileNameTemp); + strSoundFileNameTemp+= ".mss"; + + if (strSoundFileNameTemp.length() > 13) + { + const char * c_szHeader = &strSoundFileNameTemp[13]; + + m_strSoundScriptDataFileName = "sound/"; + m_strSoundScriptDataFileName += c_szHeader; + + LoadSoundScriptData(m_strSoundScriptDataFileName.c_str()); + } + + return true; +} +#ifdef WORLD_EDITOR +bool CRaceMotionData::SaveMotionData(const char * c_szFileName) +{ + FILE * File; + + SetFileAttributes(c_szFileName, FILE_ATTRIBUTE_NORMAL); + File = fopen(c_szFileName, "w"); + + if (!File) + { + TraceError("CRaceMotionData::SaveMotionData : cannot open file for writing (filename: %s)", c_szFileName); + return false; + } + + fprintf(File, "ScriptType MotionData\n"); + fprintf(File, "\n"); + + fprintf(File, "MotionFileName \"%s\"\n", m_strMotionFileName.c_str()); + fprintf(File, "MotionDuration %f\n", m_fMotionDuration); + + if (m_isAccumulationMotion) + fprintf(File, "Accumulation %.2f\t%.2f\t%.2f\n", m_accumulationPosition.x, m_accumulationPosition.y, m_accumulationPosition.z); + + fprintf(File, "\n"); + + if (m_isComboMotion) + { + fprintf(File, "Group ComboInputData\n"); + fprintf(File, "{\n"); + fprintf(File, " PreInputTime %f\n", m_ComboInputData.fInputStartTime); + fprintf(File, " DirectInputTime %f\n", m_ComboInputData.fNextComboTime); + fprintf(File, " InputLimitTime %f\n", m_ComboInputData.fInputEndTime); + fprintf(File, "}\n"); + fprintf(File, "\n"); + } + + if (m_isAttackingMotion) + { + fprintf(File, "Group AttackingData\n"); + fprintf(File, "{\n"); + NRaceData::SaveMotionAttackData(File, 1, m_MotionAttackData); + fprintf(File, "}\n"); + fprintf(File, "\n"); + } + + if (m_isLoopMotion) + { + fprintf(File, "Group LoopData\n"); + fprintf(File, "{\n"); + fprintf(File, " MotionLoopCount %d\n", m_iLoopCount); + fprintf(File, " LoopCancelEnable %d\n", m_bCancelEnableSkill); + fprintf(File, " LoopStartTime %f\n", m_fLoopStartTime); + fprintf(File, " LoopEndTime %f\n", m_fLoopEndTime); + fprintf(File, "}\n"); + fprintf(File, "\n"); + } + + if (!m_MotionEventDataVector.empty()) + { + fprintf(File, "Group MotionEventData\n"); + fprintf(File, "{\n"); + fprintf(File, " MotionEventDataCount %d\n", m_MotionEventDataVector.size()); + + for (DWORD j = 0; j < m_MotionEventDataVector.size(); ++j) + { + TMotionEventData * c_pData = m_MotionEventDataVector[j]; + + fprintf(File, " Group Event%02d\n", j); + fprintf(File, " {\n"); + fprintf(File, " MotionEventType %d\n", c_pData->iType); + fprintf(File, " StartingTime %f\n", c_pData->fStartingTime); + c_pData->Save(File, 2); + fprintf(File, " }\n"); + } + fprintf(File, "}\n"); + } + + fclose(File); + return true; +} +#endif +bool CRaceMotionData::LoadSoundScriptData(const char * c_szFileName) +{ + NSound::TSoundDataVector SoundDataVector; + if (!NSound::LoadSoundInformationPiece(c_szFileName, SoundDataVector)) + { + return false; + } + + NSound::DataToInstance(SoundDataVector, &m_SoundInstanceVector); + return true; +} + +const char * CRaceMotionData::GetMotionFileName() const +{ + return m_strMotionFileName.c_str(); +} + +const char * CRaceMotionData::GetSoundScriptFileName() const +{ + return m_strSoundScriptDataFileName.c_str(); +} + +void CRaceMotionData::Initialize() +{ + m_iLoopCount = 0; + m_fMotionDuration = 0.0f; + m_accumulationPosition.x = 0.0f; + m_accumulationPosition.y = 0.0f; + m_accumulationPosition.z = 0.0f; + m_fLoopStartTime = 0.0f; + m_fLoopEndTime = 0.0f; + + m_isAccumulationMotion = FALSE; + m_isComboMotion = FALSE; + m_isLoopMotion = FALSE; + m_isAttackingMotion = FALSE; + m_bCancelEnableSkill = FALSE; + + m_hasSplashEvent = FALSE; + + m_isLock = FALSE; + + m_eType=TYPE_NONE; + m_eName=NAME_NONE; + + m_MotionEventDataVector.clear(); + m_SoundInstanceVector.clear(); +} + +void CRaceMotionData::Destroy() +{ + stl_wipe(m_MotionEventDataVector); + Initialize(); +} + +CRaceMotionData::CRaceMotionData() +{ + Initialize(); +} + +CRaceMotionData::~CRaceMotionData() +{ + Destroy(); +} diff --git a/source/GameLib/RaceMotionData.h b/source/GameLib/RaceMotionData.h new file mode 100644 index 0000000..5d61894 --- /dev/null +++ b/source/GameLib/RaceMotionData.h @@ -0,0 +1,301 @@ +#pragma once + +#include "../milesLib/Type.h" +#include "RaceMotionDataEvent.h" + +class CRaceMotionData +{ + public: + enum EType + { + TYPE_NONE, + TYPE_WAIT, + TYPE_MOVE, + TYPE_ATTACK, + TYPE_COMBO, + TYPE_DAMAGE, + TYPE_KNOCKDOWN, + TYPE_DIE, + TYPE_SKILL, + TYPE_STANDUP, + TYPE_EVENT, + TYPE_FISHING, + TYPE_NUM, + }; + + enum + { + SKILL_NUM = 255, + }; + + enum EMode + { + MODE_RESERVED, + MODE_GENERAL, + + MODE_ONEHAND_SWORD, + MODE_TWOHAND_SWORD, + MODE_DUALHAND_SWORD, + MODE_BOW, + MODE_FAN, + MODE_BELL, + MODE_FISHING, + + MODE_HORSE, + MODE_HORSE_ONEHAND_SWORD, + MODE_HORSE_TWOHAND_SWORD, + MODE_HORSE_DUALHAND_SWORD, + MODE_HORSE_BOW, + MODE_HORSE_FAN, + MODE_HORSE_BELL, + + MODE_WEDDING_DRESS, + + MODE_MAX_NUM, + }; + + enum EName + { + NAME_NONE, // 0 + NAME_WAIT, // 1 (00.msa) + NAME_WALK, // 2 ȱ (02.msa) + NAME_RUN, // 3 ٱ (03.msa) + NAME_CHANGE_WEAPON, // 4 ٲٱ + NAME_DAMAGE, // 5 ± (30.msa) + NAME_DAMAGE_FLYING, // 6 鳯ư (32.msa) + NAME_STAND_UP, // 7 Ͼ (33.msa) + NAME_DAMAGE_BACK, // 8 ĸ± (34.msa) + NAME_DAMAGE_FLYING_BACK, // 9 ĸ鳯ư (35.msa) + NAME_STAND_UP_BACK, // 10 ĸϾ (36.msa) + NAME_DEAD, // 11 ױ (31.msa) + NAME_DEAD_BACK, // 12 ĸױ (37.msa) + NAME_NORMAL_ATTACK, // 13 (20.msa) + NAME_COMBO_ATTACK_1, // 14 ޺ + NAME_COMBO_ATTACK_2, // 15 ޺ + NAME_COMBO_ATTACK_3, // 16 ޺ + NAME_COMBO_ATTACK_4, // 17 ޺ + NAME_COMBO_ATTACK_5, // 18 ޺ + NAME_COMBO_ATTACK_6, // 19 ޺ + NAME_COMBO_ATTACK_7, // 20 ޺ + NAME_COMBO_ATTACK_8, // 21 ޺ + NAME_INTRO_WAIT, // 22 ȭ + NAME_INTRO_SELECTED, // 23 ȭ + NAME_INTRO_NOT_SELECTED, // 24 ȭ + NAME_SPAWN, // 25 ȯ + NAME_FISHING_THROW, // 26 + NAME_FISHING_WAIT, // 27 + NAME_FISHING_STOP, // 28 ׸α + NAME_FISHING_REACT, // 29 + NAME_FISHING_CATCH, // 30 + NAME_FISHING_FAIL, // 31 + NAME_STOP, // 32 ߱ + NAME_SPECIAL_1, // 33 /NPC Ư (24.msa) + NAME_SPECIAL_2, // 34 /NPC Ư (25.msa) + NAME_SPECIAL_3, + NAME_SPECIAL_4, + NAME_SPECIAL_5, + NAME_SPECIAL_6, + NAME_SKILL = 50, + NAME_SKILL_END = NAME_SKILL+SKILL_NUM, + + // CLAP + NAME_CLAP, + + // CHEERS + NAME_CHEERS_1, + NAME_CHEERS_2, + + // KISS + NAME_KISS_START, + NAME_KISS_WITH_WARRIOR = NAME_KISS_START + 0, + NAME_KISS_WITH_ASSASSIN = NAME_KISS_START + 1, + NAME_KISS_WITH_SURA = NAME_KISS_START + 2, + NAME_KISS_WITH_SHAMAN = NAME_KISS_START + 3, + + // FRENCH_KISS + NAME_FRENCH_KISS_START, + NAME_FRENCH_KISS_WITH_WARRIOR = NAME_FRENCH_KISS_START + 0, + NAME_FRENCH_KISS_WITH_ASSASSIN = NAME_FRENCH_KISS_START + 1, + NAME_FRENCH_KISS_WITH_SURA = NAME_FRENCH_KISS_START + 2, + NAME_FRENCH_KISS_WITH_SHAMAN = NAME_FRENCH_KISS_START + 3, + + // SLAP + NAME_SLAP_HIT_START, + NAME_SLAP_HIT_WITH_WARRIOR = NAME_SLAP_HIT_START + 0, + NAME_SLAP_HIT_WITH_ASSASSIN = NAME_SLAP_HIT_START + 1, + NAME_SLAP_HIT_WITH_SURA = NAME_SLAP_HIT_START + 2, + NAME_SLAP_HIT_WITH_SHAMAN = NAME_SLAP_HIT_START + 3, + + NAME_SLAP_HURT_START, + NAME_SLAP_HURT_WITH_WARRIOR = NAME_SLAP_HURT_START + 0, + NAME_SLAP_HURT_WITH_ASSASSIN = NAME_SLAP_HURT_START + 1, + NAME_SLAP_HURT_WITH_SURA = NAME_SLAP_HURT_START + 2, + NAME_SLAP_HURT_WITH_SHAMAN = NAME_SLAP_HURT_START + 3, + + NAME_DIG, + + NAME_DANCE_1, + NAME_DANCE_2, + NAME_DANCE_3, + NAME_DANCE_4, + NAME_DANCE_5, + NAME_DANCE_6, // Ÿ + + NAME_DANCE_END = NAME_DANCE_1 + 16, + + NAME_CONGRATULATION, + NAME_FORGIVE, + NAME_ANGRY, + NAME_ATTRACTIVE, + NAME_SAD, + NAME_SHY, + NAME_CHEERUP, + NAME_BANTER, + NAME_JOY, + + NAME_MAX_NUM, + }; + + enum EMotionEventType + { + MOTION_EVENT_TYPE_NONE, + + MOTION_EVENT_TYPE_EFFECT, + MOTION_EVENT_TYPE_SCREEN_WAVING, + MOTION_EVENT_TYPE_SCREEN_FLASHING, + MOTION_EVENT_TYPE_SPECIAL_ATTACKING, + MOTION_EVENT_TYPE_SOUND, + MOTION_EVENT_TYPE_FLY, + MOTION_EVENT_TYPE_CHARACTER_SHOW, + MOTION_EVENT_TYPE_CHARACTER_HIDE, + MOTION_EVENT_TYPE_WARP, + MOTION_EVENT_TYPE_EFFECT_TO_TARGET, + + MOTION_EVENT_TYPE_MAX_NUM, + }; + + typedef struct SComboInputData + { + float fInputStartTime; + float fNextComboTime; + float fInputEndTime; + } TComboInputData; + + typedef struct NMotionEvent::SMotionEventData TMotionEventData; + typedef struct NMotionEvent::SMotionEventDataScreenWaving TScreenWavingEventData; + typedef struct NMotionEvent::SMotionEventDataScreenFlashing TScreenFlashingEventData; + typedef struct NMotionEvent::SMotionEventDataEffect TMotionEffectEventData; + typedef struct NMotionEvent::SMotionEventDataFly TMotionFlyEventData; + typedef struct NMotionEvent::SMotionEventDataAttack TMotionAttackingEventData; + typedef struct NMotionEvent::SMotionEventDataSound TMotionSoundEventData; + typedef struct NMotionEvent::SMotionEventDataCharacterShow TMotionCharacterShowEventData; + typedef struct NMotionEvent::SMotionEventDataCharacterHide TMotionCharacterHideEventData; + typedef struct NMotionEvent::SMotionEventDataWarp TMotionWarpEventData; + typedef struct NMotionEvent::SMotionEventDataEffectToTarget TMotionEffectToTargetEventData; + typedef std::vector TMotionEventDataVector; + + public: + static CRaceMotionData* New(); + static void Delete(CRaceMotionData* pkData); + + static void CreateSystem(UINT uCapacity); + static void DestroySystem(); + + public: + CRaceMotionData(); + virtual ~CRaceMotionData(); + + void Initialize(); + void Destroy(); + + void SetName(UINT eName); + + UINT GetType() const; // Ÿ + bool IsLock() const; // ΰ? (ٸ ǿ ĵ ) + + int GetLoopCount() const; + + const char * GetMotionFileName() const; + const char * GetSoundScriptFileName() const; + + void SetMotionDuration(float fDur); + float GetMotionDuration(); + + bool IsAccumulationMotion(); + void SetAccumulationPosition(const TPixelPosition & c_rPos); + const TPixelPosition & GetAccumulationPosition() { return m_accumulationPosition; } + + BOOL IsComboInputTimeData() const; // ޺ Է Ÿ̹ Ͱ ִ°? + + float GetComboInputStartTime() const; + float GetNextComboTime() const; + float GetComboInputEndTime() const; + + // Attacking + BOOL isAttackingMotion() const; + const NRaceData::TMotionAttackData * GetMotionAttackDataPointer() const; + const NRaceData::TMotionAttackData & GetMotionAttackDataReference() const; + BOOL HasSplashMotionEvent() const; + + // Skill + BOOL IsCancelEnableSkill() const; + + // Loop + BOOL IsLoopMotion() const; + float GetLoopStartTime() const; + float GetLoopEndTime() const; + + // Motion Event Data + DWORD GetMotionEventDataCount() const; + BOOL GetMotionEventDataPointer(BYTE byIndex, const CRaceMotionData::TMotionEventData ** c_ppData) const; + BOOL GetMotionAttackingEventDataPointer(BYTE byIndex, const CRaceMotionData::TMotionAttackingEventData ** c_ppMotionEventData) const; + int GetEventType(DWORD dwIndex) const; + float GetEventStartTime(DWORD dwIndex) const; + + // Sound Data + const NSound::TSoundInstanceVector * GetSoundInstanceVectorPointer() const; + + // File +#ifdef WORLD_EDITOR + bool SaveMotionData(const char * c_szFileName); +#endif + bool LoadMotionData(const char * c_szFileName); + bool LoadSoundScriptData(const char * c_szFileName); + + protected: + void SetType(UINT eType); + + protected: + UINT m_eType; + UINT m_eName; + BOOL m_isLock; + int m_iLoopCount; + + std::string m_strMotionFileName; + std::string m_strSoundScriptDataFileName; + float m_fMotionDuration; + + BOOL m_isAccumulationMotion; + TPixelPosition m_accumulationPosition; + + BOOL m_isComboMotion; + TComboInputData m_ComboInputData; + + BOOL m_isLoopMotion; + float m_fLoopStartTime; + float m_fLoopEndTime; + + BOOL m_isAttackingMotion; + NRaceData::TMotionAttackData m_MotionAttackData; + + BOOL m_bCancelEnableSkill; + + TMotionEventDataVector m_MotionEventDataVector; + NSound::TSoundInstanceVector m_SoundInstanceVector; + + private: + BOOL m_hasSplashEvent; + + protected: + static CDynamicPool ms_kPool; +}; \ No newline at end of file diff --git a/source/GameLib/RaceMotionDataEvent.h b/source/GameLib/RaceMotionDataEvent.h new file mode 100644 index 0000000..9e74a7c --- /dev/null +++ b/source/GameLib/RaceMotionDataEvent.h @@ -0,0 +1,290 @@ +#pragma once + +#include "../EffectLib/EffectManager.h" +#include "FlyingObjectManager.h" + +namespace NMotionEvent +{ + typedef struct SMotionEventData + { + int iType; + DWORD dwFrame; + float fStartingTime; + float fDurationTime; + + SMotionEventData() : dwFrame(0), fStartingTime(0.0f), fDurationTime(0.0f) {} + virtual ~SMotionEventData() {} + + virtual void Save(FILE * File, int iTabs) = 0; + virtual bool Load(CTextFileLoader & rTextFileLoader) { return true; } + } TMotionEventData; + + // Screen Waving + typedef struct SMotionEventDataScreenWaving : public SMotionEventData + { + int iPower; + int iAffectingRange; + + SMotionEventDataScreenWaving() {} + virtual ~SMotionEventDataScreenWaving() {} + + void Save(FILE * File, int iTabs) + { + PrintfTabs(File, iTabs, "\n"); + PrintfTabs(File, iTabs, "DuringTime %f\n", fDurationTime); + PrintfTabs(File, iTabs, "Power %d\n", iPower); + PrintfTabs(File, iTabs, "AffectingRange %d\n", iAffectingRange); + } + bool Load(CTextFileLoader & rTextFileLoader) + { + if (!rTextFileLoader.GetTokenFloat("duringtime", &fDurationTime)) + return false; + if (!rTextFileLoader.GetTokenInteger("power", &iPower)) + return false; + if (!rTextFileLoader.GetTokenInteger("affectingrange", &iAffectingRange)) + iAffectingRange = 0; + + return true; + } + } TMotionEventDataScreenWaving; + + // Screen Flashing + typedef struct SMotionEventDataScreenFlashing : public SMotionEventData + { + D3DXCOLOR FlashingColor; + + SMotionEventDataScreenFlashing() {} + virtual ~SMotionEventDataScreenFlashing() {} + + void Save(FILE * File, int iTabs) {} + bool Load(CTextFileLoader & rTextFileLoader) + { + return true; + } + } TMotionEventDataScreenFlashing; + + // Effect + typedef struct SMotionEventDataEffect : public SMotionEventData + { + BOOL isAttaching; + BOOL isFollowing; + BOOL isIndependent; + std::string strAttachingBoneName; + D3DXVECTOR3 v3EffectPosition; + + DWORD dwEffectIndex; + std::string strEffectFileName; + + SMotionEventDataEffect() {} + virtual ~SMotionEventDataEffect() {} + + void Save(FILE * File, int iTabs) + { + PrintfTabs(File, iTabs, "\n"); + PrintfTabs(File, iTabs, "IndependentFlag %d\n", isIndependent); + PrintfTabs(File, iTabs, "AttachingEnable %d\n", isAttaching); + PrintfTabs(File, iTabs, "AttachingBoneName \"%s\"\n", strAttachingBoneName.c_str()); + PrintfTabs(File, iTabs, "FollowingEnable %d\n", isFollowing); + PrintfTabs(File, iTabs, "EffectFileName \"%s\"\n", strEffectFileName.c_str()); + PrintfTabs(File, iTabs, "EffectPosition %f %f %f\n", v3EffectPosition.x, v3EffectPosition.y, v3EffectPosition.z); + } + virtual bool Load(CTextFileLoader & rTextFileLoader) + { + if (!rTextFileLoader.GetTokenBoolean("independentflag", &isIndependent)) + isIndependent = FALSE; + if (!rTextFileLoader.GetTokenBoolean("attachingenable", &isAttaching)) + return false; + if (!rTextFileLoader.GetTokenString("attachingbonename", &strAttachingBoneName)) + return false; + if (!rTextFileLoader.GetTokenString("effectfilename", &strEffectFileName)) + return false; + if (!rTextFileLoader.GetTokenPosition("effectposition", &v3EffectPosition)) + return false; + if (!rTextFileLoader.GetTokenBoolean("followingenable", &isFollowing)) + { + isFollowing = FALSE; + } + dwEffectIndex = GetCaseCRC32(strEffectFileName.c_str(), strEffectFileName.length()); + CEffectManager::Instance().RegisterEffect(strEffectFileName.c_str()); + + return true; + } + } TMotionEventDataEffect; + + // Effect To Target + typedef struct SMotionEventDataEffectToTarget : public SMotionEventData + { + DWORD dwEffectIndex; + + std::string strEffectFileName; + D3DXVECTOR3 v3EffectPosition; + BOOL isFollowing; + BOOL isFishingEffect; + + SMotionEventDataEffectToTarget() {} + virtual ~SMotionEventDataEffectToTarget() {} + + void Save(FILE * File, int iTabs) + { + PrintfTabs(File, iTabs, "\n"); + PrintfTabs(File, iTabs, "EffectFileName \"%s\"\n", strEffectFileName.c_str()); + PrintfTabs(File, iTabs, "EffectPosition %f %f %f\n", v3EffectPosition.x, v3EffectPosition.y, v3EffectPosition.z); + PrintfTabs(File, iTabs, "FollowingEnable %d\n", isFollowing); + PrintfTabs(File, iTabs, "FishingEffectFlag %d\n", isFishingEffect); + } + virtual bool Load(CTextFileLoader & rTextFileLoader) + { + if (!rTextFileLoader.GetTokenString("effectfilename", &strEffectFileName)) + return false; + if (!rTextFileLoader.GetTokenPosition("effectposition", &v3EffectPosition)) + return false; + if (!rTextFileLoader.GetTokenBoolean("followingenable", &isFollowing)) + { + isFollowing = FALSE; + } + if (!rTextFileLoader.GetTokenBoolean("fishingeffectflag", &isFishingEffect)) + { + isFishingEffect = FALSE; + } + dwEffectIndex = GetCaseCRC32(strEffectFileName.c_str(), strEffectFileName.length()); +#ifndef _DEBUG + CEffectManager::Instance().RegisterEffect(strEffectFileName.c_str()); +#endif + + return true; + } + } TMotionEventDataEffectToTarget; + + // Fly + typedef struct SMotionEventDataFly : public SMotionEventData + { + BOOL isAttaching; + std::string strAttachingBoneName; + D3DXVECTOR3 v3FlyPosition; + + DWORD dwFlyIndex; + std::string strFlyFileName; + + SMotionEventDataFly() {} + virtual ~SMotionEventDataFly() {} + + void Save(FILE * File, int iTabs) + { + PrintfTabs(File, iTabs, "\n"); + PrintfTabs(File, iTabs, "AttachingEnable %d\n", isAttaching); + PrintfTabs(File, iTabs, "AttachingBoneName \"%s\"\n", strAttachingBoneName.c_str()); + PrintfTabs(File, iTabs, "FlyFileName \"%s\"\n", strFlyFileName.c_str()); + PrintfTabs(File, iTabs, "FlyPosition %f %f %f\n", v3FlyPosition.x, v3FlyPosition.y, v3FlyPosition.z); + } + bool Load(CTextFileLoader & rTextFileLoader) + { + if (!rTextFileLoader.GetTokenBoolean("attachingenable", &isAttaching)) + return false; + if (!rTextFileLoader.GetTokenString("attachingbonename", &strAttachingBoneName)) + return false; + if (!rTextFileLoader.GetTokenString("flyfilename", &strFlyFileName)) + return false; + if (!rTextFileLoader.GetTokenPosition("flyposition", &v3FlyPosition)) + return false; + dwFlyIndex = GetCaseCRC32(strFlyFileName.c_str(), strFlyFileName.length()); + +#ifndef _DEBUG + // Register Fly + CFlyingManager::Instance().RegisterFlyingData(strFlyFileName.c_str()); +#endif + + return true; + } + } TMotionEventDataFly; + + // Attacking + typedef struct SMotionEventDataAttack : public SMotionEventData + { + NRaceData::TCollisionData CollisionData; + NRaceData::TAttackData AttackData; + BOOL isEnableHitProcess; + + SMotionEventDataAttack() {} + virtual ~SMotionEventDataAttack() {} + + void Save(FILE * File, int iTabs) + { + PrintfTabs(File, iTabs, "DuringTime %f\n", fDurationTime); + PrintfTabs(File, iTabs, "EnableHitProcess %d\n", isEnableHitProcess); + PrintfTabs(File, iTabs, "\n"); + + NRaceData::SaveAttackData(File, iTabs, AttackData); + NRaceData::SaveCollisionData(File, iTabs, CollisionData); + } + bool Load(CTextFileLoader & rTextFileLoader) + { + if (!rTextFileLoader.GetTokenFloat("duringtime", &fDurationTime)) + return false; + + if (!rTextFileLoader.GetTokenBoolean("enablehitprocess", &isEnableHitProcess)) + { + isEnableHitProcess = TRUE; + } + + if (!NRaceData::LoadAttackData(rTextFileLoader, &AttackData)) + return false; + + if (!NRaceData::LoadCollisionData(rTextFileLoader, &CollisionData)) + return false; + + return true; + } + } TMotionEventDataAttacking; + + // Sound + typedef struct SMotionEventDataSound : public SMotionEventData + { + std::string strSoundFileName; // Direct Sound Node + + SMotionEventDataSound() {} + virtual ~SMotionEventDataSound() {} + + void Save(FILE * File, int iTabs) + { + PrintfTabs(File, iTabs, "\n"); + PrintfTabs(File, iTabs, "SoundFileName \"%s\"\n", strSoundFileName.c_str()); + } + bool Load(CTextFileLoader & rTextFileLoader) + { + if (!rTextFileLoader.GetTokenString("soundfilename", &strSoundFileName)) + return false; + + return true; + } + } TMotionEventDataSound; + + // Character Show + typedef struct SMotionEventDataCharacterShow : public SMotionEventData + { + SMotionEventDataCharacterShow() {} + virtual ~SMotionEventDataCharacterShow() {} + + void Save(FILE * File, int iTabs) {} + void Load() {} + } TMotionEventDataCharacterShow; + + // Character Hide + typedef struct SMotionEventDataCharacterHide : public SMotionEventData + { + SMotionEventDataCharacterHide() {} + virtual ~SMotionEventDataCharacterHide() {} + + void Save(FILE * File, int iTabs) {} + void Load() {} + } TMotionEventDataCharacterHide; + + // Warp + typedef struct SMotionEventDataWarp : public SMotionEventData + { + SMotionEventDataWarp() {} + virtual ~SMotionEventDataWarp() {} + + void Save(FILE * File, int iTabs) {} + void Load() {} + } TMotionWarpEventData; +}; \ No newline at end of file diff --git a/source/GameLib/SnowEnvironment.cpp b/source/GameLib/SnowEnvironment.cpp new file mode 100644 index 0000000..f63c002 --- /dev/null +++ b/source/GameLib/SnowEnvironment.cpp @@ -0,0 +1,353 @@ +#include "StdAfx.h" +#include "SnowEnvironment.h" + +#include "../EterLib/StateManager.h" +#include "../EterLib/Camera.h" +#include "../EterLib/ResourceManager.h" +#include "SnowParticle.h" + +void CSnowEnvironment::Enable() +{ + if (!m_bSnowEnable) + { + Create(); + } + + m_bSnowEnable = TRUE; +} + +void CSnowEnvironment::Disable() +{ + m_bSnowEnable = FALSE; +} + +void CSnowEnvironment::Update(const D3DXVECTOR3 & c_rv3Pos) +{ + if (!m_bSnowEnable) + { + if (m_kVct_pkParticleSnow.empty()) + return; + } + + m_v3Center=c_rv3Pos; +} + +void CSnowEnvironment::Deform() +{ + if (!m_bSnowEnable) + { + if (m_kVct_pkParticleSnow.empty()) + return; + } + + const D3DXVECTOR3 & c_rv3Pos=m_v3Center; + + static long s_lLastTime = CTimer::Instance().GetCurrentMillisecond(); + long lcurTime = CTimer::Instance().GetCurrentMillisecond(); + float fElapsedTime = float(lcurTime - s_lLastTime) / 1000.0f; + s_lLastTime = lcurTime; + + CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera(); + if (!pCamera) + return; + + const D3DXVECTOR3 & c_rv3View = pCamera->GetView(); + + D3DXVECTOR3 v3ChangedPos = c_rv3View * 3500.0f + c_rv3Pos; + v3ChangedPos.z = c_rv3Pos.z; + + std::vector::iterator itor = m_kVct_pkParticleSnow.begin(); + for (; itor != m_kVct_pkParticleSnow.end();) + { + CSnowParticle * pSnow = *itor; + pSnow->Update(fElapsedTime, v3ChangedPos); + + if (!pSnow->IsActivate()) + { + CSnowParticle::Delete(pSnow); + + itor = m_kVct_pkParticleSnow.erase(itor); + } + else + { + ++itor; + } + } + + if (m_bSnowEnable) + { + for (int p = 0; p < min(10, m_dwParticleMaxNum - m_kVct_pkParticleSnow.size()); ++p) + { + CSnowParticle * pSnowParticle = CSnowParticle::New(); + pSnowParticle->Init(v3ChangedPos); + m_kVct_pkParticleSnow.push_back(pSnowParticle); + } + } +} + +void CSnowEnvironment::__BeginBlur() +{ + if (!m_bBlurEnable) + return; + + ms_lpd3dDevice->GetRenderTarget(&m_lpOldSurface); + ms_lpd3dDevice->GetDepthStencilSurface(&m_lpOldDepthStencilSurface); + ms_lpd3dDevice->SetRenderTarget(m_lpSnowRenderTargetSurface, m_lpSnowDepthSurface); + ms_lpd3dDevice->Clear(0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L); + + STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_DESTALPHA); +} + +void CSnowEnvironment::__ApplyBlur() +{ + if (!m_bBlurEnable) + return; + +// { +// STATEMANAGER.SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); +// STATEMANAGER.SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); +// STATEMANAGER.SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); +// STATEMANAGER.SetRenderState( D3DRS_COLORVERTEX ,TRUE); +// STATEMANAGER.SetRenderState( D3DRS_DIFFUSEMATERIALSOURCE , D3DMCS_COLOR1 ); +// STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); +// STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); +// STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); +// STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); +// STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); +// STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); +// DWORD alphaColor = 0xFFFFFF | ((DWORD)(0.6f*255.0f) << 24); +// +// BlurVertex V[4] = { BlurVertex(D3DXVECTOR3(0.0f,0.0f,0.0f),1.0f, alphaColor, 0,0) , +// BlurVertex(D3DXVECTOR3(wTextureSize,0.0f,0.0f),1.0f, alphaColor, 1,0) , +// BlurVertex(D3DXVECTOR3(0.0f,wTextureSize,0.0f),1.0f, alphaColor, 0,1) , +// BlurVertex(D3DXVECTOR3(wTextureSize,wTextureSize,0.0f),1.0f, alphaColor, 1,1) }; +// // ؽĸ ´. +// STATEMANAGER.SetTexture(0,m_lpAccumTexture); +// STATEMANAGER.SetVertexShader( D3DFVF_XYZRHW | D3DFVF_DIFFUSE|D3DFVF_TEX1 ); +// STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,V,sizeof(BlurVertex)); +// } +// +// { +// STATEMANAGER.SetRenderTarget(m_lpAccumRenderTargetSurface, m_lpAccumDepthSurface); +// +// BlurVertex V[4] = { BlurVertex(D3DXVECTOR3(0.0f,0.0f,0.0f),1.0f, 0xFFFFFF, 0,0) , +// BlurVertex(D3DXVECTOR3(wTextureSize,0.0f,0.0f),1.0f, 0xFFFFFF, 1,0) , +// BlurVertex(D3DXVECTOR3(0.0f,wTextureSize,0.0f),1.0f, 0xFFFFFF, 0,1) , +// BlurVertex(D3DXVECTOR3(wTextureSize,wTextureSize,0.0f),1.0f, 0xFFFFFF, 1,1) }; +// +// STATEMANAGER.SetTexture(0,m_lpSnowTexture); +// STATEMANAGER.SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE); +// STATEMANAGER.SetVertexShader( D3DFVF_XYZRHW | D3DFVF_DIFFUSE|D3DFVF_TEX1 ); +// STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,V,sizeof(BlurVertex)); +// } + + /////////////// + { + ms_lpd3dDevice->SetRenderTarget(m_lpOldSurface, m_lpOldDepthStencilSurface); + + STATEMANAGER.SetTexture(0,m_lpSnowTexture); + STATEMANAGER.SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE); + + D3DSURFACE_DESC desc; + m_lpOldSurface->GetDesc(&desc); + float sx = (float)desc.Width ; + float sy = (float)desc.Height; + SAFE_RELEASE( m_lpOldSurface ); + SAFE_RELEASE( m_lpOldDepthStencilSurface ); + + BlurVertex V[4] = { BlurVertex(D3DXVECTOR3(0.0f,0.0f,0.0f),1.0f ,0xFFFFFF, 0,0) , + BlurVertex(D3DXVECTOR3(sx,0.0f,0.0f),1.0f ,0xFFFFFF, 1,0) , + BlurVertex(D3DXVECTOR3(0.0f,sy,0.0f),1.0f ,0xFFFFFF, 0,1) , + BlurVertex(D3DXVECTOR3(sx,sy,0.0f),1.0f ,0xFFFFFF, 1,1) }; + + STATEMANAGER.SetVertexShader( D3DFVF_XYZRHW | D3DFVF_DIFFUSE|D3DFVF_TEX1 ); + STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,V,sizeof(BlurVertex)); + } +} + +void CSnowEnvironment::Render() +{ + if (!m_bSnowEnable) + { + if (m_kVct_pkParticleSnow.empty()) + return; + } + + __BeginBlur(); + + DWORD dwParticleCount = min(m_dwParticleMaxNum, m_kVct_pkParticleSnow.size()); + + CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera(); + if (!pCamera) + return; + + const D3DXVECTOR3 & c_rv3Up = pCamera->GetUp(); + const D3DXVECTOR3 & c_rv3Cross = pCamera->GetCross(); + + SParticleVertex * pv3Verticies; + if (SUCCEEDED(m_pVB->Lock(0, sizeof(SParticleVertex)*dwParticleCount*4, (BYTE **) &pv3Verticies, D3DLOCK_DISCARD))) + { + int i = 0; + std::vector::iterator itor = m_kVct_pkParticleSnow.begin(); + for (; i < dwParticleCount && itor != m_kVct_pkParticleSnow.end(); ++i, ++itor) + { + CSnowParticle * pSnow = *itor; + pSnow->SetCameraVertex(c_rv3Up, c_rv3Cross); + pSnow->GetVerticies(pv3Verticies[i*4+0], + pv3Verticies[i*4+1], + pv3Verticies[i*4+2], + pv3Verticies[i*4+3]); + } + m_pVB->Unlock(); + } + + STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, FALSE); + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + m_pImageInstance->GetGraphicImagePointer()->GetTextureReference().SetTextureStage(0); + STATEMANAGER.SetIndices(m_pIB, 0); + STATEMANAGER.SetStreamSource(0, m_pVB, sizeof(SParticleVertex)); + STATEMANAGER.SetVertexShader(D3DFVF_XYZ | D3DFVF_TEX1); + STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, dwParticleCount*4, 0, dwParticleCount*2); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE); + + __ApplyBlur(); +} + +bool CSnowEnvironment::__CreateBlurTexture() +{ + if (!m_bBlurEnable) + return true; + + if (FAILED(ms_lpd3dDevice->CreateTexture(m_wBlurTextureSize, m_wBlurTextureSize, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &m_lpSnowTexture))) + return false; + if (FAILED(m_lpSnowTexture->GetSurfaceLevel(0, &m_lpSnowRenderTargetSurface))) + return false; + if (FAILED(ms_lpd3dDevice->CreateDepthStencilSurface(m_wBlurTextureSize, m_wBlurTextureSize, D3DFMT_D16, D3DMULTISAMPLE_NONE, &m_lpSnowDepthSurface))) + return false; + + if (FAILED(ms_lpd3dDevice->CreateTexture(m_wBlurTextureSize, m_wBlurTextureSize, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &m_lpAccumTexture))) + return false; + if (FAILED(m_lpAccumTexture->GetSurfaceLevel(0, &m_lpAccumRenderTargetSurface))) + return false; + if (FAILED(ms_lpd3dDevice->CreateDepthStencilSurface(m_wBlurTextureSize, m_wBlurTextureSize, D3DFMT_D16, D3DMULTISAMPLE_NONE, &m_lpAccumDepthSurface))) + return false; + + return true; +} + +bool CSnowEnvironment::__CreateGeometry() +{ + if (FAILED(ms_lpd3dDevice->CreateVertexBuffer(sizeof(SParticleVertex)*m_dwParticleMaxNum*4, + D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY, + D3DFVF_XYZ | D3DFVF_TEX1, + D3DPOOL_SYSTEMMEM, + &m_pVB))) + return false; + + if (FAILED(ms_lpd3dDevice->CreateIndexBuffer(sizeof(WORD)*m_dwParticleMaxNum*6, + D3DUSAGE_WRITEONLY, + D3DFMT_INDEX16, + D3DPOOL_MANAGED, + &m_pIB))) + return false; + + WORD* dstIndices; + if (FAILED(m_pIB->Lock(0, sizeof(WORD)*m_dwParticleMaxNum*6, (BYTE**)&dstIndices, 0))) + return false; + + const WORD c_awFillRectIndices[6] = { 0, 2, 1, 2, 3, 1, }; + for (int i = 0; i < m_dwParticleMaxNum; ++i) + { + for (int j = 0; j < 6; ++j) + { + dstIndices[i*6 + j] = i*4 + c_awFillRectIndices[j]; + } + } + + m_pIB->Unlock(); + return true; +} + +bool CSnowEnvironment::Create() +{ + Destroy(); + + if (!__CreateBlurTexture()) + return false; + + if (!__CreateGeometry()) + return false; + + CGraphicImage * pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer("d:/ymir work/special/snow.dds"); + m_pImageInstance = CGraphicImageInstance::New(); + m_pImageInstance->SetImagePointer(pImage); + + return true; +} + +void CSnowEnvironment::Destroy() +{ + SAFE_RELEASE(m_lpSnowTexture); + SAFE_RELEASE(m_lpSnowRenderTargetSurface); + SAFE_RELEASE(m_lpSnowDepthSurface); + SAFE_RELEASE(m_lpAccumTexture); + SAFE_RELEASE(m_lpAccumRenderTargetSurface); + SAFE_RELEASE(m_lpAccumDepthSurface); + SAFE_RELEASE(m_pVB); + SAFE_RELEASE(m_pIB); + + stl_wipe(m_kVct_pkParticleSnow); + CSnowParticle::DestroyPool(); + + if (m_pImageInstance) + { + CGraphicImageInstance::Delete(m_pImageInstance); + m_pImageInstance = NULL; + } + + __Initialize(); +} + +void CSnowEnvironment::__Initialize() +{ + m_bSnowEnable = FALSE; + m_lpSnowTexture = NULL; + m_lpSnowRenderTargetSurface = NULL; + m_lpSnowDepthSurface = NULL; + m_lpAccumTexture = NULL; + m_lpAccumRenderTargetSurface = NULL; + m_lpAccumDepthSurface = NULL; + m_pVB = NULL; + m_pIB = NULL; + m_pImageInstance = NULL; + + m_kVct_pkParticleSnow.reserve(m_dwParticleMaxNum); +} + +CSnowEnvironment::CSnowEnvironment() +{ + m_bBlurEnable = FALSE; + m_dwParticleMaxNum = 3000; + m_wBlurTextureSize = 512; + + __Initialize(); +} +CSnowEnvironment::~CSnowEnvironment() +{ + Destroy(); +} diff --git a/source/GameLib/SnowEnvironment.h b/source/GameLib/SnowEnvironment.h new file mode 100644 index 0000000..3ec91cf --- /dev/null +++ b/source/GameLib/SnowEnvironment.h @@ -0,0 +1,55 @@ +#pragma once + +#include "../EterLib/GrpScreen.h" + +class CSnowParticle; + +class CSnowEnvironment : public CScreen +{ + public: + CSnowEnvironment(); + virtual ~CSnowEnvironment(); + + bool Create(); + void Destroy(); + + void Enable(); + void Disable(); + + void Update(const D3DXVECTOR3 & c_rv3Pos); + void Deform(); + void Render(); + + protected: + void __Initialize(); + bool __CreateBlurTexture(); + bool __CreateGeometry(); + void __BeginBlur(); + void __ApplyBlur(); + + protected: + LPDIRECT3DSURFACE8 m_lpOldSurface; + LPDIRECT3DSURFACE8 m_lpOldDepthStencilSurface; + + LPDIRECT3DTEXTURE8 m_lpSnowTexture; + LPDIRECT3DSURFACE8 m_lpSnowRenderTargetSurface; + LPDIRECT3DSURFACE8 m_lpSnowDepthSurface; + + LPDIRECT3DTEXTURE8 m_lpAccumTexture; + LPDIRECT3DSURFACE8 m_lpAccumRenderTargetSurface; + LPDIRECT3DSURFACE8 m_lpAccumDepthSurface; + + LPDIRECT3DVERTEXBUFFER8 m_pVB; + LPDIRECT3DINDEXBUFFER8 m_pIB; + + D3DXVECTOR3 m_v3Center; + + WORD m_wBlurTextureSize; + CGraphicImageInstance * m_pImageInstance; + std::vector m_kVct_pkParticleSnow; + + DWORD m_dwParticleMaxNum; + BOOL m_bBlurEnable; + + BOOL m_bSnowEnable; +}; diff --git a/source/GameLib/SnowParticle.cpp b/source/GameLib/SnowParticle.cpp new file mode 100644 index 0000000..85889cc --- /dev/null +++ b/source/GameLib/SnowParticle.cpp @@ -0,0 +1,103 @@ +#include "StdAfx.h" +#include "SnowParticle.h" + +const float c_fSnowDistance = 70000.0f; + +std::vector CSnowParticle::ms_kVct_SnowParticlePool; + +void CSnowParticle::SetCameraVertex(const D3DXVECTOR3 & rv3Up, const D3DXVECTOR3 & rv3Cross) +{ + m_v3Up = rv3Up*m_fHalfWidth; + m_v3Cross = rv3Cross*m_fHalfHeight; +} + +bool CSnowParticle::IsActivate() +{ + return m_bActivate; +} + +void CSnowParticle::Update(float fElapsedTime, const D3DXVECTOR3 & c_rv3Pos) +{ + m_v3Position += m_v3Velocity * fElapsedTime; + + m_v3Position.x += m_v3Cross.x * sin(m_fcurRadian) / 10.0f; + m_v3Position.y += m_v3Cross.y * sin(m_fcurRadian) / 10.0f; + m_fcurRadian += m_fPeriod * fElapsedTime; + + if (m_v3Position.z < c_rv3Pos.z - 500.0f) + m_bActivate = false; + else if (abs(m_v3Position.x - c_rv3Pos.x) > c_fSnowDistance) + m_bActivate = false; + else if (abs(m_v3Position.y - c_rv3Pos.y) > c_fSnowDistance) + m_bActivate = false; +} + +void CSnowParticle::GetVerticies(SParticleVertex & rv3Vertex1, SParticleVertex & rv3Vertex2, + SParticleVertex & rv3Vertex3, SParticleVertex & rv3Vertex4) +{ + rv3Vertex1.v3Pos = m_v3Position - m_v3Cross - m_v3Up; + rv3Vertex1.u = 0.0f; + rv3Vertex1.v = 0.0f; + + rv3Vertex2.v3Pos = m_v3Position + m_v3Cross - m_v3Up; + rv3Vertex2.u = 1.0f; + rv3Vertex2.v = 0.0f; + + rv3Vertex3.v3Pos = m_v3Position - m_v3Cross + m_v3Up; + rv3Vertex3.u = 0.0f; + rv3Vertex3.v = 1.0f; + + rv3Vertex4.v3Pos = m_v3Position + m_v3Cross + m_v3Up; + rv3Vertex4.u = 1.0f; + rv3Vertex4.v = 1.0f; +} + +void CSnowParticle::Init(const D3DXVECTOR3 & c_rv3Pos) +{ + float fRot = frandom(0.0f, 36000.0f) / 100.0f; + float fDistance = frandom(0.0f, c_fSnowDistance) / 10.0f; + + m_v3Position.x = c_rv3Pos.x + fDistance*sin((double)D3DXToRadian(fRot)); + m_v3Position.y = c_rv3Pos.y + fDistance*cos((double)D3DXToRadian(fRot)); + m_v3Position.z = c_rv3Pos.z + frandom(1500.0f, 2000.0f); + m_v3Velocity.x = 0.0f; + m_v3Velocity.y = 0.0f; + m_v3Velocity.z = frandom(-50.0f, -200.0f); + m_fHalfWidth = frandom(2.0f, 7.0f); + m_fHalfHeight = m_fHalfWidth; + m_bActivate = true; + m_bChangedSize = false; + + m_fPeriod = frandom(1.5f, 5.0f); + m_fcurRadian = frandom(-1.6f, 1.6f); + m_fAmplitude = frandom(1.0f, 3.0f); +} + +CSnowParticle * CSnowParticle::New() +{ + if (ms_kVct_SnowParticlePool.empty()) + { + return new CSnowParticle; + } + + CSnowParticle * pParticle = ms_kVct_SnowParticlePool.back(); + ms_kVct_SnowParticlePool.pop_back(); + return pParticle; +} + +void CSnowParticle::Delete(CSnowParticle * pSnowParticle) +{ + ms_kVct_SnowParticlePool.push_back(pSnowParticle); +} + +void CSnowParticle::DestroyPool() +{ + stl_wipe(ms_kVct_SnowParticlePool); +} + +CSnowParticle::CSnowParticle() +{ +} +CSnowParticle::~CSnowParticle() +{ +} diff --git a/source/GameLib/SnowParticle.h b/source/GameLib/SnowParticle.h new file mode 100644 index 0000000..8cc0d66 --- /dev/null +++ b/source/GameLib/SnowParticle.h @@ -0,0 +1,59 @@ +#pragma once + +struct SParticleVertex +{ + D3DXVECTOR3 v3Pos; + float u, v; +}; + +struct BlurVertex +{ + D3DXVECTOR3 pos; + FLOAT rhw; + DWORD color; + FLOAT tu, tv; + + static const DWORD FVF; + + BlurVertex(D3DXVECTOR3 p, float w,DWORD c,float u,float v):pos(p),rhw(w),color(c),tu(u),tv(v) {} + ~BlurVertex(){}; +}; + +class CSnowParticle +{ + public: + CSnowParticle(); + ~CSnowParticle(); + + static CSnowParticle * New(); + static void Delete(CSnowParticle * pSnowParticle); + static void DestroyPool(); + + void Init(const D3DXVECTOR3 & c_rv3Pos); + + void SetCameraVertex(const D3DXVECTOR3 & rv3Up, const D3DXVECTOR3 & rv3Cross); + bool IsActivate(); + + void Update(float fElapsedTime, const D3DXVECTOR3 & c_rv3Pos); + void GetVerticies(SParticleVertex & rv3Vertex1, SParticleVertex & rv3Vertex2, + SParticleVertex & rv3Vertex3, SParticleVertex & rv3Vertex4); + + protected: + bool m_bActivate; + bool m_bChangedSize; + float m_fHalfWidth; + float m_fHalfHeight; + + D3DXVECTOR3 m_v3Velocity; + D3DXVECTOR3 m_v3Position; + + D3DXVECTOR3 m_v3Up; + D3DXVECTOR3 m_v3Cross; + + float m_fPeriod; + float m_fcurRadian; + float m_fAmplitude; + + public: + static std::vector ms_kVct_SnowParticlePool; +}; diff --git a/source/GameLib/StdAfx.cpp b/source/GameLib/StdAfx.cpp new file mode 100644 index 0000000..5ac0416 --- /dev/null +++ b/source/GameLib/StdAfx.cpp @@ -0,0 +1,6 @@ +// stdafx.cpp : source file that includes just the standard includes +// gamelib.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + diff --git a/source/GameLib/StdAfx.h b/source/GameLib/StdAfx.h new file mode 100644 index 0000000..1e1287a --- /dev/null +++ b/source/GameLib/StdAfx.h @@ -0,0 +1,70 @@ +#ifndef __INC_YMIR_GAMELIB__ +#define __INC_YMIR_GAMELIB__ + +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif + +#pragma warning(disable:4710) // not inlined +#pragma warning(disable:4786) // character 255 Ѿ° +#pragma warning(disable:4244) // type conversion possible lose of data + +#pragma warning(disable:4018) +#pragma warning(disable:4245) +#pragma warning(disable:4512) +#pragma warning(disable:4201) + +#if _MSC_VER >= 1400 +#pragma warning(disable:4201 4512 4238 4239) +#endif + +#include "../eterBase/Utils.h" +#include "../eterBase/CRC32.h" +#include "../eterBase/Random.h" + +#include "../eterLib/StdAfx.h" +#include "../milesLib/StdAfx.h" +#include "../effectLib/StdAfx.h" + +#include "GameType.h" +#include "GameUtil.h" +#include "MapType.h" +#include "MapUtil.h" +#include "Interface.h" + +//#include "FlyingObjectManager.h" +//#include "FlyingData.h" +//#include "FlyingInstance.h" + + +// Octree +//#include "Octree.h" + +// Item +//#include "ItemData.h" +//#include "ItemManager.h" + +// Actor +//#include "WeaponTrace.h" +//#include "PhysicsObject.h" +//#include "RaceMotionData.h" +//#include "RaceData.h" +//#include "ActorInstance.h" +//#include "RaceManager.h" + +// Property +//#include "Property.h" +//#include "PropertyManager.h" +//#include "PropertyLoader.h" + +// Map +//#include "Area.h" + +// Path Finder +//#include "PathFinder.h" + +// Game Event Manager +//#include "GameEventManager.h" + + +#endif \ No newline at end of file diff --git a/source/GameLib/TerrainDecal.cpp b/source/GameLib/TerrainDecal.cpp new file mode 100644 index 0000000..326e440 --- /dev/null +++ b/source/GameLib/TerrainDecal.cpp @@ -0,0 +1,180 @@ +// TerrainDecal.cpp: implementation of the CTerrainDecal class. +// +////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "../eterLib/StateManager.h" +#include "../PRTerrainLib/StdAfx.h" + +#include "TerrainDecal.h" +#include "MapOutdoor.h" +#include "AreaTerrain.h" + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CTerrainDecal::CTerrainDecal(CMapOutdoor * pMapOutdoor):m_pMapOutdoor(pMapOutdoor) +{ + +} + +CTerrainDecal::~CTerrainDecal() +{ + CDecal::Clear(); +} + +void CTerrainDecal::Make(D3DXVECTOR3 v3Center, D3DXVECTOR3 v3Normal, D3DXVECTOR3 v3Tangent, float fWidth, float fHeight, float fDepth) +{ + Clear(); + m_v3Center = v3Center; + m_v3Normal = v3Normal; + + D3DXVECTOR3 v3Binormal; + D3DXVec3Normalize(&v3Normal, &v3Normal); + D3DXVec3Normalize(&v3Tangent, &v3Tangent); + D3DXVec3Cross(&v3Binormal, &m_v3Normal, &v3Tangent); + D3DXVec3Normalize(&v3Binormal, &v3Binormal); + + // Calculate boundary planes + float fd = D3DXVec3Dot(&m_v3Center, &v3Tangent); + m_v4LeftPlane = D3DXPLANE(v3Tangent.x, v3Tangent.y, v3Tangent.z, fWidth * 0.5f - fd); + m_v4RightPlane = D3DXPLANE(-v3Tangent.x, -v3Tangent.y, -v3Tangent.z, fWidth * 0.5f + fd); + + fd = D3DXVec3Dot(&m_v3Center, &v3Binormal); + m_v4BottomPlane = D3DXPLANE(v3Binormal.x, v3Binormal.y, v3Binormal.z, fHeight * 0.5f - fd); + m_v4TopPlane = D3DXPLANE(-v3Binormal.x, -v3Binormal.y, -v3Binormal.z, fHeight * 0.5f + fd); + + fd = D3DXVec3Dot(&m_v3Center, &m_v3Normal); + m_v4FrontPlane = D3DXPLANE(-m_v3Normal.x, -m_v3Normal.y, -m_v3Normal.z, fDepth + fd); + m_v4BackPlane = D3DXPLANE(m_v3Normal.x, m_v3Normal.y, m_v3Normal.z, fDepth - fd); + + // Begin with empty mesh + m_dwVertexCount = 0; + m_dwPrimitiveCount = 0; + + // Add this point, determine which surfaces may be affected by this decal and call ClipMesh(). + + float fSearchRadius = fMAX(fWidth, fHeight);// 0.75f >= sqrtf(2)/2; + float fMinX = v3Center.x - fSearchRadius; + float fMaxX = v3Center.x + fSearchRadius; + float fMinY = fabs(v3Center.y) - fSearchRadius; + float fMaxY = fabs(v3Center.y) + fSearchRadius; + + DWORD dwAffectedPrimitiveCount = 0; + D3DXVECTOR3 v3AffectedVertex[MAX_SEARCH_VERTICES]; + D3DXVECTOR3 v3AffectedNormal[MAX_SEARCH_VERTICES]; + memset(v3AffectedVertex, 0, sizeof(v3AffectedVertex)); + memset(v3AffectedNormal, 0, sizeof(v3AffectedNormal)); + + SearchAffectedTerrainMesh(fMinX, fMaxX, fMinY, fMaxY, &dwAffectedPrimitiveCount, v3AffectedVertex, v3AffectedNormal); + + ClipMesh(dwAffectedPrimitiveCount, v3AffectedVertex, v3AffectedNormal); + + // Assign texture mapping coordinates + float fOne_over_w = 1.0f / fWidth; + float fOne_over_h = 1.0f / fHeight; + for (DWORD dwi = 0; dwi < m_dwVertexCount; ++dwi) + { + D3DXVECTOR3 v3 = m_Vertices[dwi].position - m_v3Center; + float fu = -D3DXVec3Dot(&v3, &v3Binormal) * fOne_over_w + 0.5f; + float fv = -D3DXVec3Dot(&v3, &v3Tangent) * fOne_over_h + 0.5f; + m_Vertices[dwi].texCoord = D3DXVECTOR2(fu, fv); + } +} + +/* +void CTerrainDecal::Update() +{ +} +*/ + +void CTerrainDecal::Render() +{ + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + + STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); + + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + CDecal::Render(); + + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXCOORDINDEX); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSU); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSV); + + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); +} + +void CTerrainDecal::SearchAffectedTerrainMesh(float fMinX, + float fMaxX, + float fMinY, + float fMaxY, + DWORD * pdwAffectedPrimitiveCount, + D3DXVECTOR3 * pv3AffectedVertex, + D3DXVECTOR3 * pv3AffectedNormal) +{ + if (!m_pMapOutdoor) + return; + int iMinX, iMaxX, iMinY, iMaxY; + PR_FLOAT_TO_INT(fMinX, iMinX); + PR_FLOAT_TO_INT(fMaxX, iMaxX); + PR_FLOAT_TO_INT(fMinY, iMinY); + PR_FLOAT_TO_INT(fMaxY, iMaxY); + + iMinX -= iMinX % CTerrainImpl::CELLSCALE; + iMaxX -= iMaxX % CTerrainImpl::CELLSCALE; + iMinY -= iMinY % CTerrainImpl::CELLSCALE; + iMaxY -= iMaxY % CTerrainImpl::CELLSCALE; + + for(int iy = iMinY; iy <= iMaxY; iy += CTerrainImpl::CELLSCALE) + { + if (iy < 0) + continue; + WORD wTerrainNumY = iy / CTerrainImpl::TERRAIN_YSIZE; + for(int ix = iMinX; ix <= iMaxX; ix += CTerrainImpl::CELLSCALE) + { + if (ix < 0) + continue; + WORD wTerrainNumX = ix / CTerrainImpl::TERRAIN_YSIZE; + + BYTE byTerrainNum; + if (!m_pMapOutdoor->GetTerrainNumFromCoord(wTerrainNumX, wTerrainNumY, &byTerrainNum)) + continue; + CTerrain * pTerrain; + if (!m_pMapOutdoor->GetTerrainPointer(byTerrainNum, &pTerrain)) + continue; + + float fHeightLT = pTerrain->GetHeight(ix, iy) + m_cfDecalEpsilon; + float fHeightRT = pTerrain->GetHeight(ix + CTerrainImpl::CELLSCALE, iy) + m_cfDecalEpsilon; + float fHeightLB = pTerrain->GetHeight(ix, iy + CTerrainImpl::CELLSCALE) + m_cfDecalEpsilon; + float fHeightRB = pTerrain->GetHeight(ix + CTerrainImpl::CELLSCALE, iy + CTerrainImpl::CELLSCALE) + m_cfDecalEpsilon; + + *pdwAffectedPrimitiveCount += 2; + + *pv3AffectedVertex++ = D3DXVECTOR3((float)ix, (float)(-iy), fHeightLT); + *pv3AffectedVertex++ = D3DXVECTOR3((float)ix, (float)(-iy - CTerrainImpl::CELLSCALE), fHeightLB); + *pv3AffectedVertex++ = D3DXVECTOR3((float)(ix + CTerrainImpl::CELLSCALE), (float)(-iy), fHeightRT); + *pv3AffectedVertex++ = D3DXVECTOR3((float)(ix + CTerrainImpl::CELLSCALE), (float)(-iy), fHeightRT); + *pv3AffectedVertex++ = D3DXVECTOR3((float)ix, (float)(-iy - CTerrainImpl::CELLSCALE), fHeightLB); + *pv3AffectedVertex++ = D3DXVECTOR3((float)(ix + CTerrainImpl::CELLSCALE), (float)(-iy - CTerrainImpl::CELLSCALE), fHeightRB); + + *pv3AffectedNormal++ = D3DXVECTOR3(0.0f, 0.0f, 1.0f); + *pv3AffectedNormal++ = D3DXVECTOR3(0.0f, 0.0f, 1.0f); + *pv3AffectedNormal++ = D3DXVECTOR3(0.0f, 0.0f, 1.0f); + *pv3AffectedNormal++ = D3DXVECTOR3(0.0f, 0.0f, 1.0f); + *pv3AffectedNormal++ = D3DXVECTOR3(0.0f, 0.0f, 1.0f); + *pv3AffectedNormal++ = D3DXVECTOR3(0.0f, 0.0f, 1.0f); + } + } +} diff --git a/source/GameLib/TerrainDecal.h b/source/GameLib/TerrainDecal.h new file mode 100644 index 0000000..89df15b --- /dev/null +++ b/source/GameLib/TerrainDecal.h @@ -0,0 +1,46 @@ +// TerrainDecal.h: interface for the CTerrainDecal class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_TERRAINDECAL_H__8E387316_FCCF_446F_AB82_82721F7AC08C__INCLUDED_) +#define AFX_TERRAINDECAL_H__8E387316_FCCF_446F_AB82_82721F7AC08C__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "../eterlib/Decal.h" + +class CMapOutdoor; + +class CTerrainDecal : public CDecal +{ +public: + enum + { + MAX_SEARCH_VERTICES = 1024, + }; + + CTerrainDecal(CMapOutdoor * pMapOutdoor = NULL); + virtual ~CTerrainDecal(); + + virtual void Make(D3DXVECTOR3 v3Center, D3DXVECTOR3 v3Normal, D3DXVECTOR3 v3Tangent, float fWidth, float fHeight, float fDepth); +// virtual void Update(); + virtual void Render(); + + void SetMapOutdoor(CMapOutdoor * pMapOutdoor) { m_pMapOutdoor = pMapOutdoor; } + +protected: + + void SearchAffectedTerrainMesh(float fMinX, + float fMaxX, + float fMinY, + float fMaxY, + DWORD * pdwAffectedPrimitiveCount, + D3DXVECTOR3 * pv3AffectedVertex, + D3DXVECTOR3 * pv3AffectedNormal); + + CMapOutdoor * m_pMapOutdoor; +}; + +#endif // !defined(AFX_TERRAINDECAL_H__8E387316_FCCF_446F_AB82_82721F7AC08C__INCLUDED_) diff --git a/source/GameLib/TerrainPatch.cpp b/source/GameLib/TerrainPatch.cpp new file mode 100644 index 0000000..bd957c4 --- /dev/null +++ b/source/GameLib/TerrainPatch.cpp @@ -0,0 +1,240 @@ +// TerrainPatch.cpp: implementation of the CTerrainPatch class. +// +////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "TerrainPatch.h" + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CTerrainPatch::SSoftwareTransformPatch::SSoftwareTransformPatch() +{ + __Initialize(); +} + +CTerrainPatch::SSoftwareTransformPatch::~SSoftwareTransformPatch() +{ + Destroy(); +} + +void CTerrainPatch::SSoftwareTransformPatch::Create() +{ + assert(NULL==m_akTerrainVertex); + m_akTerrainVertex=new SoftwareTransformPatch_SSourceVertex[TERRAIN_VERTEX_COUNT]; +} + +void CTerrainPatch::SSoftwareTransformPatch::Destroy() +{ + if (m_akTerrainVertex) + delete [] m_akTerrainVertex; + + __Initialize(); +} + +void CTerrainPatch::SSoftwareTransformPatch::__Initialize() +{ + m_akTerrainVertex=NULL; +} + +bool CTerrainPatch::SOFTWARE_TRANSFORM_PATCH_ENABLE=TRUE; + +void CTerrainPatch::Clear() +{ + m_kHT.m_kVB.Destroy(); + m_kST.Destroy(); + + m_WaterVertexBuffer.Destroy(); + ClearID(); + SetUse(false); + + m_bWaterExist = false; + m_bNeedUpdate = true; + + m_dwWaterPriCount = 0; + m_byType = PATCH_TYPE_PLAIN; + + m_fMinX = m_fMaxX = m_fMinY = m_fMaxY = m_fMinZ = m_fMaxZ = 0.0f; + + m_dwVersion=0; +} + +void CTerrainPatch::BuildWaterVertexBuffer(SWaterVertex* akSrcVertex, UINT uWaterVertexCount) +{ + CGraphicVertexBuffer& rkVB=m_WaterVertexBuffer; + + if (!rkVB.Create(uWaterVertexCount, D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DUSAGE_WRITEONLY, D3DPOOL_MANAGED)) + return; + + SWaterVertex* akDstWaterVertex; + if (rkVB.Lock((void **) &akDstWaterVertex)) + { + UINT uVBSize=sizeof(SWaterVertex)*uWaterVertexCount; + memcpy(akDstWaterVertex, akSrcVertex, uVBSize); + m_dwWaterPriCount=uWaterVertexCount/3; + + rkVB.Unlock(); + } +} + +void CTerrainPatch::BuildTerrainVertexBuffer(HardwareTransformPatch_SSourceVertex* akSrcVertex) +{ + if (SOFTWARE_TRANSFORM_PATCH_ENABLE) + __BuildSoftwareTerrainVertexBuffer(akSrcVertex); + else + __BuildHardwareTerrainVertexBuffer(akSrcVertex); +} + +void CTerrainPatch::__BuildSoftwareTerrainVertexBuffer(HardwareTransformPatch_SSourceVertex* akSrcVertex) +{ + //DWORD dwVBSize=sizeof(HardwareTransformPatch_SSourceVertex)*TERRAIN_VERTEX_COUNT; + + m_kST.Create(); + + SoftwareTransformPatch_SSourceVertex* akDstVertex=SoftwareTransformPatch_GetTerrainVertexDataPtr(); + for (UINT uIndex=0; uIndex!=TERRAIN_VERTEX_COUNT; ++uIndex) + { + *((HardwareTransformPatch_SSourceVertex*)(akDstVertex+uIndex))=*(akSrcVertex+uIndex); + akDstVertex[uIndex].dwDiffuse=0xFFFFFFFF; + } +} + +void CTerrainPatch::__BuildHardwareTerrainVertexBuffer(HardwareTransformPatch_SSourceVertex* akSrcVertex) +{ + + CGraphicVertexBuffer& rkVB=m_kHT.m_kVB; + if (!rkVB.Create(TERRAIN_VERTEX_COUNT, D3DFVF_XYZ | D3DFVF_NORMAL, D3DUSAGE_WRITEONLY, D3DPOOL_MANAGED)) + return; + + HardwareTransformPatch_SSourceVertex* akDstVertex; + if (rkVB.Lock((void **) &akDstVertex)) + { + UINT uVBSize=sizeof(HardwareTransformPatch_SSourceVertex)*TERRAIN_VERTEX_COUNT; + + memcpy(akDstVertex, akSrcVertex, uVBSize); + rkVB.Unlock(); + } +} + +void CTerrainPatch::SoftwareTransformPatch_UpdateTerrainLighting(DWORD dwVersion, const D3DLIGHT8& c_rkLight, const D3DMATERIAL8& c_rkMtrl) +{ + if (m_dwVersion==dwVersion) + return; + + m_dwVersion=dwVersion; + + SoftwareTransformPatch_SSourceVertex* akSrcVertex=SoftwareTransformPatch_GetTerrainVertexDataPtr(); + if (!akSrcVertex) + return; + + D3DXVECTOR3 kLightDir=c_rkLight.Direction; + + + DWORD dwDot; + DWORD dwAmbientR=(c_rkMtrl.Ambient.r*c_rkLight.Ambient.r+c_rkMtrl.Emissive.r)*255.0f; + DWORD dwAmbientG=(c_rkMtrl.Ambient.g*c_rkLight.Ambient.g+c_rkMtrl.Emissive.g)*255.0f; + DWORD dwAmbientB=(c_rkMtrl.Ambient.b*c_rkLight.Ambient.b+c_rkMtrl.Emissive.b)*255.0f; + DWORD dwDiffuseR=(c_rkMtrl.Diffuse.r*c_rkLight.Diffuse.r)*255.0f; + DWORD dwDiffuseG=(c_rkMtrl.Diffuse.g*c_rkLight.Diffuse.g)*255.0f; + DWORD dwDiffuseB=(c_rkMtrl.Diffuse.b*c_rkLight.Diffuse.b)*255.0f; + + if (dwDiffuseR>255-dwAmbientR) + dwDiffuseR=255-dwAmbientR; + + if (dwDiffuseG+dwAmbientG>255) + dwDiffuseG=255-dwAmbientG; + + if (dwDiffuseB+dwAmbientB>255) + dwDiffuseB=255-dwAmbientB; + + for (UINT uIndex=0; uIndex!=CTerrainPatch::TERRAIN_VERTEX_COUNT; ++uIndex) + { + float fDot=D3DXVec3Dot(&akSrcVertex[uIndex].kNormal, &kLightDir); + + const float N=0xffffff; + const int S=24; + if (fDot<0.0f) + dwDot=(N*-fDot); + else + dwDot=(N*+fDot); + + akSrcVertex[uIndex].dwDiffuse=(0xff000000)| + (((dwDiffuseR*dwDot>>S)+dwAmbientR)<<16)| + (((dwDiffuseG*dwDot>>S)+dwAmbientG)<<8)| + ((dwDiffuseB*dwDot>>S)+dwAmbientB); + } + +} + +UINT CTerrainPatch::GetWaterFaceCount() +{ + return m_dwWaterPriCount; +} + +CTerrainPatchProxy::CTerrainPatchProxy() +{ + Clear(); +} + +CTerrainPatchProxy::~CTerrainPatchProxy() +{ + Clear(); +} + +void CTerrainPatchProxy::SetCenterPosition(const D3DXVECTOR3& c_rv3Center) +{ + m_v3Center=c_rv3Center; +} + +bool CTerrainPatchProxy::IsIn(const D3DXVECTOR3& c_rv3Target, float fRadius) +{ + float dx=m_v3Center.x-c_rv3Target.x; + float dy=m_v3Center.y-c_rv3Target.y; + float fDist=dx*dx+dy*dy; + float fCheck=fRadius*fRadius; + + if (fDistSoftwareTransformPatch_UpdateTerrainLighting(dwVersion, c_rkLight, c_rkMtrl); +} + +CGraphicVertexBuffer* CTerrainPatchProxy::HardwareTransformPatch_GetVertexBufferPtr() +{ + if (m_pTerrainPatch) + return m_pTerrainPatch->HardwareTransformPatch_GetVertexBufferPtr(); + + return NULL; +} + +SoftwareTransformPatch_SSourceVertex* CTerrainPatchProxy::SoftwareTransformPatch_GetTerrainVertexDataPtr() +{ + if (m_pTerrainPatch) + return m_pTerrainPatch->SoftwareTransformPatch_GetTerrainVertexDataPtr(); + + return NULL; +} + +UINT CTerrainPatchProxy::GetWaterFaceCount() +{ + if (m_pTerrainPatch) + return m_pTerrainPatch->GetWaterFaceCount(); + + return 0; +} + +void CTerrainPatchProxy::Clear() +{ + m_bUsed = false; + m_sPatchNum = 0; + m_byTerrainNum = 0xFF; + + m_pTerrainPatch = NULL; +} diff --git a/source/GameLib/TerrainPatch.h b/source/GameLib/TerrainPatch.h new file mode 100644 index 0000000..1fec89d --- /dev/null +++ b/source/GameLib/TerrainPatch.h @@ -0,0 +1,250 @@ +// TerrainPatch.h: interface for the CTerrainPatch class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_TERRAINPATCH_H__CDD52438_D542_433C_8748_3A15C910A65E__INCLUDED_) +#define AFX_TERRAINPATCH_H__CDD52438_D542_433C_8748_3A15C910A65E__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "../eterlib/GrpVertexBuffer.h" +#include "../PRTerrainLib/Terrain.h" + +#pragma pack(push) +#pragma pack(1) + +struct HardwareTransformPatch_SSourceVertex +{ + D3DXVECTOR3 kPosition; + D3DXVECTOR3 kNormal; +}; + +struct SoftwareTransformPatch_SSourceVertex +{ + D3DXVECTOR3 kPosition; + D3DXVECTOR3 kNormal; + DWORD dwDiffuse; +}; + +struct SWaterVertex +{ + float x, y, z; // position + DWORD dwDiffuse; +}; +#pragma pack(pop) + +class CTerrainPatch +{ +public: + enum + { + PATCH_TYPE_PLAIN = 0, + PATCH_TYPE_HILL, + PATCH_TYPE_CLIFF, + }; + + enum + { + TERRAIN_VERTEX_COUNT = (CTerrainImpl::PATCH_XSIZE+1)*(CTerrainImpl::PATCH_YSIZE+1) + }; + + static bool SOFTWARE_TRANSFORM_PATCH_ENABLE; + +public: + CTerrainPatch() { Clear(); } + ~CTerrainPatch() { Clear(); } + + void Clear(); + + void ClearID() { SetID(0xFFFFFFFF); } + + void SetMinX(float fMinX) { m_fMinX = fMinX; } + float GetMinX() { return m_fMinX; } + + void SetMaxX(float fMaxX) { m_fMaxX = fMaxX; } + float GetMaxX() { return m_fMaxX; } + + void SetMinY(float fMinY) { m_fMinY = fMinY; } + float GetMinY() { return m_fMinY; } + + void SetMaxY(float fMaxY) { m_fMaxY = fMaxY; } + float GetMaxY() { return m_fMaxY; } + + void SetMinZ(float fMinZ) { m_fMinZ = fMinZ; } + float GetMinZ() { return m_fMinZ; } + + void SetMaxZ(float fMaxZ) { m_fMaxZ = fMaxZ; } + float GetMaxZ() { return m_fMaxZ; } + + bool IsUse() { return m_bUse; } + void SetUse(bool bUse) { m_bUse = bUse; } + + bool IsWaterExist() { return m_bWaterExist; } + void SetWaterExist(bool bWaterExist) { m_bWaterExist = bWaterExist; } + + DWORD GetID() { return m_dwID; } + void SetID(DWORD dwID) { m_dwID = dwID; } + + void SetType(BYTE byType) { m_byType = byType; } + BYTE GetType() { return m_byType; } + + void NeedUpdate(bool bNeedUpdate) { m_bNeedUpdate = bNeedUpdate;} + bool NeedUpdate() { return m_bNeedUpdate; } + + UINT GetWaterFaceCount(); + + void SoftwareTransformPatch_UpdateTerrainLighting(DWORD dwVersion, const D3DLIGHT8& c_rkLight, const D3DMATERIAL8& c_rkMtrl); + + void BuildTerrainVertexBuffer(HardwareTransformPatch_SSourceVertex* akSrcVertex); + void BuildWaterVertexBuffer(SWaterVertex* akSrcVertex, UINT uWaterVertexCount); + +protected: + void __BuildHardwareTerrainVertexBuffer(HardwareTransformPatch_SSourceVertex* akSrcVertex); + void __BuildSoftwareTerrainVertexBuffer(HardwareTransformPatch_SSourceVertex* akSrcVertex); + +private: + float m_fMinX; + float m_fMaxX; + float m_fMinY; + float m_fMaxY; + float m_fMinZ; + float m_fMaxZ; + bool m_bUse; + bool m_bWaterExist; + DWORD m_dwID; + DWORD m_dwWaterPriCount; + + CGraphicVertexBuffer m_WaterVertexBuffer; + BYTE m_byType; + + bool m_bNeedUpdate; + DWORD m_dwVersion; + +public: + CGraphicVertexBuffer* GetWaterVertexBufferPointer() { return &m_WaterVertexBuffer;} + +public: + CGraphicVertexBuffer* HardwareTransformPatch_GetVertexBufferPtr() {return &m_kHT.m_kVB;} + +protected: + struct SHardwareTransformPatch + { + CGraphicVertexBuffer m_kVB; + } m_kHT; + + +public: + SoftwareTransformPatch_SSourceVertex* SoftwareTransformPatch_GetTerrainVertexDataPtr() + {return m_kST.m_akTerrainVertex;} + +protected: + struct SSoftwareTransformPatch + { + SoftwareTransformPatch_SSourceVertex* m_akTerrainVertex; + + SSoftwareTransformPatch(); + ~SSoftwareTransformPatch(); + + void Create(); + void Destroy(); + + void __Initialize(); + } m_kST; + +}; + +class CTerrainPatchProxy +{ +public: + CTerrainPatchProxy(); + virtual ~CTerrainPatchProxy(); + + void Clear(); + + void SetCenterPosition(const D3DXVECTOR3& c_rv3Center); + + bool IsIn(const D3DXVECTOR3& c_rv3Target, float fRadius); + + bool isUsed() { return m_bUsed; } + void SetUsed(bool bUsed) { m_bUsed = bUsed; } + + short GetPatchNum() { return m_sPatchNum; } + void SetPatchNum(short sPatchNum) { m_sPatchNum = sPatchNum; } + + BYTE GetTerrainNum() { return m_byTerrainNum; } + void SetTerrainNum(BYTE byTerrainNum) { m_byTerrainNum = byTerrainNum; } + + void SetTerrainPatch(CTerrainPatch * pTerrainPatch) { m_pTerrainPatch = pTerrainPatch;} + + bool isWaterExists(); + + UINT GetWaterFaceCount(); + + float GetMinX(); + float GetMaxX(); + float GetMinY(); + float GetMaxY(); + float GetMinZ(); + float GetMaxZ(); + + // Vertex Buffer + CGraphicVertexBuffer * GetWaterVertexBufferPointer(); + SoftwareTransformPatch_SSourceVertex* SoftwareTransformPatch_GetTerrainVertexDataPtr(); + CGraphicVertexBuffer* HardwareTransformPatch_GetVertexBufferPtr(); + + void SoftwareTransformPatch_UpdateTerrainLighting(DWORD dwVersion, const D3DLIGHT8& c_rkLight, const D3DMATERIAL8& c_rkMtrl); + +protected: + bool m_bUsed; + short m_sPatchNum; // Patch Number + + BYTE m_byTerrainNum; + + CTerrainPatch * m_pTerrainPatch; + + D3DXVECTOR3 m_v3Center; +}; + +inline bool CTerrainPatchProxy::isWaterExists() +{ + return m_pTerrainPatch->IsWaterExist(); +} + +inline float CTerrainPatchProxy::GetMinX() +{ + return m_pTerrainPatch->GetMinX(); +} + +inline float CTerrainPatchProxy::GetMaxX() +{ + return m_pTerrainPatch->GetMaxX(); +} + +inline float CTerrainPatchProxy::GetMinY() +{ + return m_pTerrainPatch->GetMinY(); +} + +inline float CTerrainPatchProxy::GetMaxY() +{ + return m_pTerrainPatch->GetMaxY(); +} + +inline float CTerrainPatchProxy::GetMinZ() +{ + return m_pTerrainPatch->GetMinZ(); +} + +inline float CTerrainPatchProxy::GetMaxZ() +{ + return m_pTerrainPatch->GetMaxZ(); +} + +inline CGraphicVertexBuffer * CTerrainPatchProxy::GetWaterVertexBufferPointer() +{ + return m_pTerrainPatch->GetWaterVertexBufferPointer(); +} + +#endif // !defined(AFX_TERRAINPATCH_H__CDD52438_D542_433C_8748_3A15C910A65E__INCLUDED_) diff --git a/source/GameLib/TerrainQuadtree.cpp b/source/GameLib/TerrainQuadtree.cpp new file mode 100644 index 0000000..ace434f --- /dev/null +++ b/source/GameLib/TerrainQuadtree.cpp @@ -0,0 +1,46 @@ +// TerrainQuadtreeNode.cpp: implementation of the CTerrainQuadtreeNode class. +// +////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "TerrainQuadtree.h" + +////////////////////////////////////////////////////////////////////// +// CTerrainQuadtree +////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////// +// CTerrainQuadtreeNode +////////////////////////////////////////////////////////////////////// +CTerrainQuadtreeNode::CTerrainQuadtreeNode():NW_Node(NULL), NE_Node(NULL), SW_Node(NULL), SE_Node(NULL), center(-1.0f, -1.0f, -1.0f) +{ + x0 = y0 = x1 = y1 = 0; + Size = 0; + PatchNum = 0; + radius = 0.0f; + m_byLODLevel = 0; +} + +CTerrainQuadtreeNode::~CTerrainQuadtreeNode() +{ + if (NW_Node) + { + delete NW_Node; + NW_Node = NULL; + } + if (NE_Node) + { + delete NE_Node; + NE_Node = NULL; + } + if (SW_Node) + { + delete SW_Node; + SW_Node = NULL; + } + if (SE_Node) + { + delete SE_Node; + SE_Node = NULL; + } +} diff --git a/source/GameLib/TerrainQuadtree.h b/source/GameLib/TerrainQuadtree.h new file mode 100644 index 0000000..3e1f875 --- /dev/null +++ b/source/GameLib/TerrainQuadtree.h @@ -0,0 +1,32 @@ +// TerrainQuadtreeNode.h: interface for the CTerrainQuadtreeNode class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_TERRAINQUADTREENODE_H__C788298F_1098_4CEE_B6F3_5975D618BBF3__INCLUDED_) +#define AFX_TERRAINQUADTREENODE_H__C788298F_1098_4CEE_B6F3_5975D618BBF3__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +class CTerrainQuadtreeNode +{ +public: + CTerrainQuadtreeNode(); + virtual ~CTerrainQuadtreeNode(); + +public: + long x0, y0, x1, y1; + CTerrainQuadtreeNode * NW_Node; + CTerrainQuadtreeNode * NE_Node; + CTerrainQuadtreeNode * SW_Node; + CTerrainQuadtreeNode * SE_Node; + long Size; + long PatchNum; + D3DXVECTOR3 center; + float radius; + BYTE m_byLODLevel; +}; + + +#endif // !defined(AFX_TERRAINQUADTREENODE_H__C788298F_1098_4CEE_B6F3_5975D618BBF3__INCLUDED_) diff --git a/source/GameLib/WeaponTrace.cpp b/source/GameLib/WeaponTrace.cpp new file mode 100644 index 0000000..7684abb --- /dev/null +++ b/source/GameLib/WeaponTrace.cpp @@ -0,0 +1,490 @@ +#include "StdAfx.h" +#include "../eterLib/ResourceManager.h" +#include "../eterLib/StateManager.h" + +#include "WeaponTrace.h" + +CDynamicPool CWeaponTrace::ms_kPool; + +void CWeaponTrace::DestroySystem() +{ + ms_kPool.Destroy(); +} + +void CWeaponTrace::Delete(CWeaponTrace* pkWTDel) +{ + assert(pkWTDel!=NULL && "CWeaponTrace::Delete"); + + pkWTDel->Clear(); + ms_kPool.Free(pkWTDel); +} + +CWeaponTrace* CWeaponTrace::New() +{ + return ms_kPool.Alloc(); +} + +void CWeaponTrace::Update(float fReachScale) +{ + float fElapsedTime = CTimer::Instance().GetCurrentSecond() - m_fLastUpdate; + m_fLastUpdate = CTimer::Instance().GetCurrentSecond(); + + if (!m_pInstance) + return; + { + // ܻ ð 鸸 մϴ. + TTimePointList::iterator it; + for(it=m_ShortTimePointList.begin();it!=m_ShortTimePointList.end();++it) + { + it->first += fElapsedTime; + if (it->first>m_fLifeTime) + { + it++; + break; + } + } + if (it!=m_ShortTimePointList.end()) + m_ShortTimePointList.erase(it,m_ShortTimePointList.end()); + for(it=m_LongTimePointList.begin();it!=m_LongTimePointList.end();++it) + { + it->first += fElapsedTime; + if (it->first>m_fLifeTime) + { + it++; + break; + } + } + if (it!=m_LongTimePointList.end()) + m_LongTimePointList.erase(it, m_LongTimePointList.end()); + } + + if (m_isPlaying && m_fz>=0.0001f) + { + D3DXMATRIX * pMatrix; + if (m_pInstance->GetCompositeBoneMatrix(m_dwModelInstanceIndex, m_iBoneIndex, &pMatrix)) + { + D3DXMATRIX * pBoneMat; + m_pInstance->GetBoneMatrix(m_dwModelInstanceIndex, m_iBoneIndex, &pBoneMat); + D3DXMATRIX mat = *pMatrix; + mat._41 = pBoneMat->_41; + mat._42 = pBoneMat->_42; + mat._43 = pBoneMat->_43; + // ġ ߰մϴ. + D3DXMATRIX matPoint; + D3DXMATRIX matTranslation; + D3DXMATRIX matRotation; + + //D3DXMatrixTranslation(&matTranslation, 0.0f, m_fLength, 0.0f); + D3DXMatrixTranslation(&matTranslation, 0.0f, 0.0f, m_fLength*fReachScale); + D3DXMatrixRotationZ(&matRotation, D3DXToRadian(m_fRotation)); + + + matPoint = /**pMatrix*/mat * matRotation; + /*TPDTVertex PDTVertex; + PDTVertex.position.x = m_fx + matPoint._41; + PDTVertex.position.y = m_fy + matPoint._42; + PDTVertex.position.z = m_fz + matPoint._43; + PDTVertex.diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 0.1f); + m_PDTVertexVector.push_back(PDTVertex);*/ + m_ShortTimePointList.push_front( + TTimePoint( + 0.0f, + D3DXVECTOR3( + m_fx + matPoint._41, + m_fy + matPoint._42, + m_fz + matPoint._43 + ) + ) + ); + + matPoint = matTranslation * matPoint; + /*PDTVertex.position.x = m_fx + matPoint._41; + PDTVertex.position.y = m_fy + matPoint._42; + PDTVertex.position.z = m_fz + matPoint._43; + PDTVertex.diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 0.1f); + m_PDTVertexVector.push_back(PDTVertex);*/ + m_LongTimePointList.push_front( + TTimePoint( + 0.0f, + D3DXVECTOR3( + m_fx + matPoint._41, + m_fy + matPoint._42, + m_fz + matPoint._43 + ) + ) + ); + } + } + + //if (!BuildVertex()) + // return; +} + +bool CWeaponTrace::BuildVertex() +{ + const int max_size = 300; + // calculate speed + float h[max_size]; + float stk[max_size]; + int sp=0; + D3DXVECTOR3 r[max_size]; + + if (m_LongTimePointList.size()<=1) + return false; + + + //Tracef("## %f %f %f\n", m_LongTimePointList[0].second.x, m_LongTimePointList[0].second.y, m_LongTimePointList[0].second.z); + + /*m_LongTimePointList.clear(); + m_LongTimePointList.push_back(TTimePoint(0.00,D3DXVECTOR3(0,0,0))); + m_LongTimePointList.push_back(TTimePoint(0.01,D3DXVECTOR3(0,1,0))); + m_LongTimePointList.push_back(TTimePoint(0.04,D3DXVECTOR3(0,1,0))); + m_LongTimePointList.push_back(TTimePoint(0.05,D3DXVECTOR3(0,0,0))); + m_ShortTimePointList = m_LongTimePointList; + + */ + std::vector m_ShortVertexVector, m_LongVertexVector; + + float length = min(m_fLifeTime, m_LongTimePointList.back().first); + + int n = m_LongTimePointList.size()-1; + assert(n & Output = (loop) ? m_LongVertexVector : m_ShortVertexVector; + TTimePointList::iterator it; + int i; + + for(i=0;i0;i--) + { + r[i]+=r[i-1]; + } + + float rate = 0.5f; + r[0] *= 0.5f; + stk[sp++] = rate; + for(i=1;i=0;i--) + { + r[i] -= stk[--sp] * r[i+1]; + } + + int base = 0; + D3DXVECTOR3 a,b,c,d; + D3DXVECTOR3 v3Tmp = Input[base+1].second-Input[base].second; + float timebase=0,timenext=h[base], dt=m_fSamplingTime; + a = Input[base].second; + b = r[base]; + c = ( 3*v3Tmp - r[base+1]*h[base] - (2*h[base])*r[base] ) + * (1/(h[base]*h[base])); + d = ( -2*v3Tmp + (r[base+1]+r[base])*h[base]) + * (1/(h[base]*h[base]*h[base])); + + for(float t = 0; t<=length; t+=dt) + { + while (t>timenext) + { + timebase = timenext; + base++; + if (base>=n) break; + D3DXVECTOR3 v3Tmp = Input[base+1].second-Input[base].second; + a = Input[base].second; + b = r[base]; + c = ( 3*v3Tmp - r[base+1]*h[base] - (2*h[base])*r[base] ) + * (1/(h[base]*h[base])); + d = ( -2*v3Tmp + (r[base+1]+r[base])*h[base]) + * (1/(h[base]*h[base]*h[base])); + + timenext+=h[base]; + if (loop) + { + //Tracef("%f:%f %f %f\n",Input[base].first,Input[base].second.x,Input[base].second.y,Input[base].second.z); + } + } + if (base>n) break; + float cc = t - timebase; + + TPDTVertex v; + //v.diffuse = D3DXCOLOR(0.3f,0.8f,1.0f, (loop)?max(1.0f-(t/m_fLifeTime),0.0f)/2:0.0f ); + float ttt = min(max((t+Input[0].first)/m_fLifeTime,0.0f),1.0f); + v.diffuse = D3DXCOLOR(0.3f,0.8f,1.0f, (loop)?min(max((1.0f-ttt)*(1.0f-ttt)/2.5-0.1f,0.0f),1.0f):0.0f ); + //v.diffuse = D3DXCOLOR(0.0f,0.0f,0.0f, (loop)?min(max((1.0f-ttt)*(1.0f-ttt)-0.1f,0.0f),1.0f):0.0f ); + //v.diffuse = 0xffffffff; + v.position = a+cc*(b+cc*(c+cc*d)); // next position + v.texCoord.x = t/m_fLifeTime; + v.texCoord.y = loop ? 0 : 1; + Output.push_back(v); + if (loop) + { + // Tracef("%f %f %f\n", timebase,t,timenext); + //Tracef("a:%f %f %f\nb:%f %f %f \nc:%f %f %f \nd:%f %f %f, \n",,a.x,a.y,a.z,b.x,b.y,b.z,c.x,c.y,c.z,d.x,d.y,d.z); + + //Tracef("%f %f %f\n",v.position.x,v.position.y,v.position.z); + /*D3DXMATRIX * pBoneMat; + m_pInstance->GetBoneMatrix(m_dwModelInstanceIndex, 55, &pBoneMat); + D3DXVECTOR3 vbone(m_fx+pBoneMat->_41,m_fy+pBoneMat->_42,m_fz+pBoneMat->_43); + float len = D3DXVec3Length(&(v.position-vbone));*/ + } + } + } + + // build vertex + + m_PDTVertexVector.clear(); + + /* + TTimePointList::iterator lit1,lit2, sit1,sit2; + + lit2 = lit1 = m_LongTimePointList.begin(); + ++lit2; + + sit2 = sit1 = m_ShortTimePointList.begin(); + ++sit2; + */ + std::vector::iterator lit,sit; + for(lit = m_LongVertexVector.begin(), sit = m_ShortVertexVector.begin(); + lit != m_LongVertexVector.end(); + ++lit,++sit) + { + m_PDTVertexVector.push_back(*lit); + m_PDTVertexVector.push_back(*sit); + /*float len = D3DXVec3Length(&(lit->position - sit->position)); + if (len>160) + Tracef("dist:%f\n",len);*/ + } + + return true; +} + +void CWeaponTrace::Render() +{ + //if (!m_isPlaying) + // return; + //if (m_CurvingTraceVector.size() < 4) + // return; + + if (!BuildVertex()) + return; + + if (m_PDTVertexVector.size()<4) + return; + + + LPDIRECT3DTEXTURE8 lpTexture=NULL; + + // Have to optimize + D3DXMATRIX matWorld; + D3DXMatrixIdentity(&matWorld); + + STATEMANAGER.SaveTransform(D3DTS_WORLD, &matWorld); + STATEMANAGER.SaveVertexShader(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1); + STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + + STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, FALSE); + STATEMANAGER.SaveRenderState(D3DRS_ALPHAREF, 0x00000011); + STATEMANAGER.SaveRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER); + + STATEMANAGER.SaveRenderState(D3DRS_ZENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); + STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, FALSE); + + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, (m_bUseTexture)?D3DTOP_SELECTARG2:D3DTOP_SELECTARG1); + //STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + //STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); + //STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, (m_bUseTexture)?D3DTOP_SELECTARG2:D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); + STATEMANAGER.SetTexture(0, lpTexture); + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, + int(m_PDTVertexVector.size() - 2), + &m_PDTVertexVector[0], + sizeof(TPDTVertex)); + + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, TRUE); + + STATEMANAGER.RestoreRenderState(D3DRS_ZENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_ZFUNC); + STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE); + + STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHAREF); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHAFUNC); + + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND); + STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND); + + STATEMANAGER.RestoreTransform(D3DTS_WORLD); + STATEMANAGER.RestoreVertexShader(); + STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE); +} + +void CWeaponTrace::UseAlpha() +{ + m_bUseTexture = false; +} + +void CWeaponTrace::UseTexture() +{ + m_bUseTexture = true; +} + +void CWeaponTrace::SetTexture(const char * c_szFileName) +{ + CGraphicImage * pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer("lot_ade10-2.tga"); + m_ImageInstance.SetImagePointer(pImage); + + //CGraphicTexture * pTexture = m_ImageInstance.GetTexturePointer(); + //m_lpTexture = pTexture->GetD3DTexture(); +} + +bool CWeaponTrace::SetWeaponInstance(CGraphicThingInstance * pInstance, DWORD dwModelIndex, const char * c_szBoneName) +{ + pInstance->Update(); + pInstance->DeformNoSkin(); + + D3DXVECTOR3 v3Min; + D3DXVECTOR3 v3Max; + if (!pInstance->GetBoundBox(dwModelIndex, &v3Min, &v3Max)) + return false; + + m_iBoneIndex = 0; + m_dwModelInstanceIndex = dwModelIndex; + + m_pInstance = pInstance; + D3DXMATRIX * pmat; + pInstance->GetBoneMatrix(dwModelIndex, 0, &pmat); + D3DXVECTOR3 v3Bone(pmat->_41,pmat->_42,pmat->_43); + + const auto vv1 = (v3Bone - v3Min); + const auto vv2 = (v3Bone - v3Max); + m_fLength = + sqrtf( + fMAX( + D3DXVec3LengthSq(&vv1), + D3DXVec3LengthSq(&vv2) + ) + ); + + return true; +} + +void CWeaponTrace::SetPosition(float fx, float fy, float fz) +{ + m_fx = fx; + m_fy = fy; + m_fz = fz; +} + +void CWeaponTrace::SetRotation(float fRotation) +{ + m_fRotation = fRotation; +} + +void CWeaponTrace::SetLifeTime(float fLifeTime) +{ + m_fLifeTime = fLifeTime; +} + +void CWeaponTrace::SetSamplingTime(float fSamplingTime) +{ + m_fSamplingTime = fSamplingTime; +} + +void CWeaponTrace::TurnOn() +{ + m_isPlaying = TRUE; +} +void CWeaponTrace::TurnOff() +{ + m_isPlaying = FALSE; + //Clear(); +} + +void CWeaponTrace::Clear() +{ + //m_PDTVertexVector.clear(); + //m_CurvingTraceVector.clear(); + + m_ShortTimePointList.clear(); + m_LongTimePointList.clear(); + Initialize(); +} + +void CWeaponTrace::Initialize() +{ + m_pInstance = NULL; + m_dwModelInstanceIndex = 0; + + m_fx = 0.0f; + m_fy = 0.0f; + m_fz = 0.0f; + m_fRotation = 0.0f; + + m_fLifeTime = 0.18f; + //m_fLifeTime = 3.0f; + m_fSamplingTime = 0.003f; + //m_fLifeTime = 3.0f; + //m_fSamplingTime = 0.003f; + + m_isPlaying = FALSE; + + m_bUseTexture = false; + + m_iBoneIndex = 0; + + m_fLastUpdate = CTimer::Instance().GetCurrentSecond(); + /////////////////////////////////////////////////////////////////////// + + //const int c_iSplineCount = 8; + //m_SplineValueVector.clear(); + //m_SplineValueVector.resize(c_iSplineCount); + + //for (int i = 0; i < c_iSplineCount; ++i) + //{ + // float fValue = float(i) / float(c_iSplineCount); + // m_SplineValueVector[i].fValue1 = fValue; + // m_SplineValueVector[i].fValue2 = fValue * fValue; + // m_SplineValueVector[i].fValue3 = fValue * fValue * fValue; + //} + +} + +CWeaponTrace::CWeaponTrace() +{ + Initialize(); +} +CWeaponTrace::~CWeaponTrace() +{ +} diff --git a/source/GameLib/WeaponTrace.h b/source/GameLib/WeaponTrace.h new file mode 100644 index 0000000..a429331 --- /dev/null +++ b/source/GameLib/WeaponTrace.h @@ -0,0 +1,86 @@ +#pragma once + +// change CatMull to cubic spline +#include "../eterGrnLib/ThingInstance.h" + +class CWeaponTrace +{ + /* + public: + typedef struct SSplineValue + { + float fValue1; + float fValue2; + float fValue3; + } TSplineValue; + */ + public: + static void DestroySystem(); + static void Delete(CWeaponTrace* pkWTDel); + static CWeaponTrace* New(); + + public: + CWeaponTrace(); + virtual ~CWeaponTrace(); + + void Clear(); + + void TurnOn(); + void TurnOff(); + + void UseAlpha(); + void UseTexture(); + + void SetTexture(const char * c_szFileName); + bool SetWeaponInstance(CGraphicThingInstance * pInstance, DWORD dwModelIndex, const char * c_szBoneName); + void SetPosition(float fx, float fy, float fz); + void SetRotation(float fRotation); + + void SetLifeTime(float fLifeTime); + void SetSamplingTime(float fSamplingTime); + + void Update(float fReachScale); + void Render(); + + void Initialize(); + + protected: + bool BuildVertex(); + + protected: + + float m_fLastUpdate; + + typedef std::pair TTimePoint; + typedef std::deque TTimePointList; + TTimePointList m_ShortTimePointList; + TTimePointList m_LongTimePointList; + + std::vector m_PDTVertexVector; + + float m_fLifeTime; + float m_fSamplingTime; + + //std::vector m_PDTVertexVector; + //std::vector m_CurvingTraceVector; + //std::vector m_SplineValueVector; + + CGraphicThingInstance * m_pInstance; + DWORD m_dwModelInstanceIndex; + + CGraphicImageInstance m_ImageInstance; + + float m_fx; + float m_fy; + float m_fz; + float m_fRotation; + float m_fLength; + + BOOL m_isPlaying; + bool m_bUseTexture; + + int m_iBoneIndex; + + protected: + static CDynamicPool ms_kPool; +}; diff --git a/source/MilesLib/SoundBase.cpp b/source/MilesLib/SoundBase.cpp new file mode 100644 index 0000000..95e7f9f --- /dev/null +++ b/source/MilesLib/SoundBase.cpp @@ -0,0 +1,70 @@ +#include "Stdafx.h" +#include "SoundBase.h" + +HDIGDRIVER CSoundBase::ms_DIGDriver = NULL; +TSoundDataMap CSoundBase::ms_dataMap; +TProvider * CSoundBase::ms_pProviderDefault = NULL; +std::vector CSoundBase::ms_ProviderVector; +bool CSoundBase::ms_bInitialized = false; +int CSoundBase::ms_iRefCount = 0; + +CSoundBase::CSoundBase() +{ +} + +CSoundBase::~CSoundBase() +{ +} + +void CSoundBase::Destroy() +{ + if (ms_iRefCount > 1) + { + --ms_iRefCount; + return; + } + + ms_iRefCount = 0; + + if (!ms_dataMap.empty()) + { + TSoundDataMap::iterator i; + for (i = ms_dataMap.begin(); i != ms_dataMap.end(); ++i) + { + CSoundData * pSoundData = i->second; + delete pSoundData; + } + + ms_dataMap.clear(); + } + + AIL_shutdown(); +} + +void CSoundBase::Initialize() +{ + ++ms_iRefCount; + + if (ms_iRefCount > 1) + return; + + AIL_set_redist_directory("miles"); + AIL_startup(); + + ms_ProviderVector.clear(); + ms_dataMap.clear(); + +} + +DWORD CSoundBase::GetFileCRC(const char * filename) +{ + return GetCRC32(filename, strlen(filename)); +} + +CSoundData * CSoundBase::AddFile(DWORD dwFileCRC, const char* filename) +{ + CSoundData * pSoundData = new CSoundData; + pSoundData->Assign(filename); + ms_dataMap.insert(TSoundDataMap::value_type(dwFileCRC, pSoundData)); + return pSoundData; +} diff --git a/source/MilesLib/SoundBase.h b/source/MilesLib/SoundBase.h new file mode 100644 index 0000000..07d3c70 --- /dev/null +++ b/source/MilesLib/SoundBase.h @@ -0,0 +1,37 @@ +#ifndef __MILESLIB_CSOUNDBASE_H__ +#define __MILESLIB_CSOUNDBASE_H__ + +#include +#include +#include "SoundData.h" + +typedef struct SProvider +{ + char* name; + HPROVIDER hProvider; +} TProvider; + +typedef std::map TSoundDataMap; + +class CSoundBase +{ + public: + CSoundBase(); + virtual ~CSoundBase(); + + void Initialize(); + void Destroy(); + + CSoundData * AddFile(DWORD dwFileCRC, const char* filename); + DWORD GetFileCRC(const char* filename); + + protected: + static int ms_iRefCount; + static HDIGDRIVER ms_DIGDriver; + static TProvider * ms_pProviderDefault; + static std::vector ms_ProviderVector; + static TSoundDataMap ms_dataMap; + static bool ms_bInitialized; +}; + +#endif diff --git a/source/MilesLib/SoundData.cpp b/source/MilesLib/SoundData.cpp new file mode 100644 index 0000000..91c99f1 --- /dev/null +++ b/source/MilesLib/SoundData.cpp @@ -0,0 +1,212 @@ +#include "StdAfx.h" +#include "SoundData.h" + +#include "../EterPack/EterPackManager.h" +#include "../eterBase/Timer.h" + +bool CSoundData::ms_isSoundFile[SOUND_FILE_MAX_NUM]; +CMappedFile CSoundData::ms_SoundFile[SOUND_FILE_MAX_NUM]; + +const char * CSoundData::GetFileName() +{ + return m_filename; +} + +void CSoundData::Assign(const char* filename) +{ + assert(m_assigned == false); + + strncpy(m_filename, filename, sizeof(m_filename)-1); + m_assigned = true; +} + +LPVOID CSoundData::Get() +{ + ++m_iRefCount; + m_dwAccessTime = ELTimer_GetMSec(); + + if (!m_data) + ReadFromDisk(); + + if (m_flag & FLAG_DATA_SIZE) + return ((S32 *) m_data + 1); + else + return (m_data); +} + +ULONG CSoundData::GetSize() +{ + return m_size; +} + +void CSoundData::Release() +{ + assert(m_iRefCount != 0); + --m_iRefCount; + m_dwAccessTime = ELTimer_GetMSec(); +} + +DWORD CSoundData::GetPlayTime() +{ + return m_dwPlayTime; +} + +void CSoundData::SetPlayTime(DWORD dwPlayTime) +{ + m_dwPlayTime = dwPlayTime; +} + +DWORD CSoundData::GetAccessTime() +{ + return m_dwAccessTime; +} + +bool CSoundData::ReadFromDisk() +{ + assert(m_assigned == true); + + LARGE_INTEGER start; + QueryPerformanceCounter(&start); + + U32* s = (U32 *) AIL_file_read(m_filename, FILE_READ_WITH_SIZE); + + if (s == NULL) + return false; + + S32 type = AIL_file_type(s + 1, s[0]); + AILSOUNDINFO info; + + switch (type) + { + case AILFILETYPE_PCM_WAV: + { + m_data = s; + m_size = *((S32 *) s); + m_flag |= FLAG_DATA_SIZE; + } + break; + + case AILFILETYPE_ADPCM_WAV: // 3D decompress ؾ . + { + AIL_WAV_info(s + 1, &info); + AIL_decompress_ADPCM(&info, &m_data, &m_size); + AIL_mem_free_lock(s); + } + break; + + case AILFILETYPE_MPEG_L3_AUDIO: + { + AIL_decompress_ASI(s + 1, *((S32 *) s), m_filename, &m_data, &m_size, 0); + AIL_mem_free_lock(s); + } + break; + + default: + assert(!"Unknown File Type"); + AIL_mem_free_lock(s); + return false; + } + + return true; +} + +bool CSoundData::isSlotIndex(DWORD dwIndex) +{ + if (dwIndex >= SOUND_FILE_MAX_NUM) + return false; + + if (!ms_isSoundFile[dwIndex]) + return false; + + return true; +} + +int CSoundData::GetEmptySlotIndex() +{ + for (int i = 0; i < SOUND_FILE_MAX_NUM; ++i) + { + if (!ms_isSoundFile[i]) + return i; + } + + return -1; +} + +U32 AILCALLBACK CSoundData::open_callback(char const * filename, U32 *file_handle) +{ + int iIndex = GetEmptySlotIndex(); + + if (-1 == iIndex) + return 0; + + LPCVOID pMap; + + if (!CEterPackManager::Instance().Get(ms_SoundFile[iIndex], filename, &pMap)) + return 0; + + ms_isSoundFile[iIndex] = true; + + *file_handle = iIndex; + return 1; +} + +void AILCALLBACK CSoundData::close_callback(U32 file_handle) +{ + if (!isSlotIndex(file_handle)) + return; + + ms_SoundFile[file_handle].Destroy(); + ms_isSoundFile[file_handle] = false; +} + +S32 AILCALLBACK CSoundData::seek_callback(U32 file_handle, S32 offset, U32 type) +{ + if (!isSlotIndex(file_handle)) + return 0; + + return ms_SoundFile[file_handle].Seek(offset, type); +} + +U32 AILCALLBACK CSoundData::read_callback(U32 file_handle, void * buffer, U32 bytes) +{ + if (!isSlotIndex(file_handle)) + return 0; + + DWORD dwRealSize = min(ms_SoundFile[file_handle].Size(), bytes); + ms_SoundFile[file_handle].Read(buffer, dwRealSize); + return dwRealSize; +} + +void CSoundData::SetPackMode() +{ + // if sound data reads from pack file, the callbacks of the MSS should be changed. + AIL_set_file_callbacks(open_callback, close_callback, seek_callback, read_callback); + + for (int i = 0; i < SOUND_FILE_MAX_NUM; ++i) + ms_isSoundFile[i] = false; +} + +void CSoundData::Destroy() +{ + if (m_data) + { + AIL_mem_free_lock(m_data); + m_data = NULL; + } +} + +CSoundData::CSoundData() : +m_assigned(false), +m_iRefCount(0), +m_dwPlayTime(0), +m_dwAccessTime(ELTimer_GetMSec()), +m_size(0), +m_data(NULL), +m_flag(0) +{ +} + +CSoundData::~CSoundData() +{ + Destroy(); +} diff --git a/source/MilesLib/SoundData.h b/source/MilesLib/SoundData.h new file mode 100644 index 0000000..dc28cfe --- /dev/null +++ b/source/MilesLib/SoundData.h @@ -0,0 +1,59 @@ +#ifndef __MILESLIB_CSOUNDDATA_H__ +#define __MILESLIB_CSOUNDDATA_H__ + +#include +#include "../eterBase/MappedFile.h" + +class CSoundData +{ + public: + enum + { + FLAG_DATA_SIZE = 1, + SOUND_FILE_MAX_NUM = 5, + }; + + public: + static void SetPackMode(); + + CSoundData(); + virtual ~CSoundData(); + + void Assign(const char* filename); + LPVOID Get(); + ULONG GetSize(); + void Release(); + DWORD GetAccessTime(); + const char * GetFileName(); + + void SetPlayTime(DWORD dwPlayTime); + DWORD GetPlayTime(); + + protected: + bool ReadFromDisk(); + void Destroy(); + + protected: + char m_filename[128]; + int m_iRefCount; + DWORD m_dwAccessTime; + DWORD m_dwPlayTime; + ULONG m_size; + LPVOID m_data; + long m_flag; + bool m_assigned; + + private: + static U32 AILCALLBACK open_callback(char const * filename, U32 *file_handle); + static void AILCALLBACK close_callback(U32 file_handle); + static S32 AILCALLBACK seek_callback(U32 file_handle, S32 offset, U32 type); + static U32 AILCALLBACK read_callback(U32 file_handle, void *buffer, U32 bytes); + + static bool isSlotIndex(DWORD dwIndex); + static int GetEmptySlotIndex(); + + static bool ms_isSoundFile[SOUND_FILE_MAX_NUM]; + static CMappedFile ms_SoundFile[SOUND_FILE_MAX_NUM]; +}; + +#endif \ No newline at end of file diff --git a/source/MilesLib/SoundInstance.h b/source/MilesLib/SoundInstance.h new file mode 100644 index 0000000..780b2f0 --- /dev/null +++ b/source/MilesLib/SoundInstance.h @@ -0,0 +1,118 @@ +#ifndef __MILESLIB_CSOUNDINSTANCE_H__ +#define __MILESLIB_CSOUNDINSTANCE_H__ + +#include "SoundBase.h" + +class ISoundInstance : public CSoundBase +{ +public: + ISoundInstance() {} + virtual ~ISoundInstance() {} + + virtual bool Initialize() = 0; + virtual void Destroy() = 0; + virtual bool SetSound(CSoundData* pSound) = 0; + virtual void Play(int iLoopCount = 1, DWORD dwPlayCycleTimeLimit = 0) const = 0; + virtual void Pause() const = 0; + virtual void Resume() const = 0; + virtual void Stop() = 0; + virtual void GetVolume(float& rfVolume) const = 0; + virtual void SetVolume(float volume) const = 0; + virtual bool IsDone() const = 0; + virtual void SetPosition(float x, float y, float z) const = 0; + virtual void SetOrientation(float x_face, float y_face, float z_face, + float x_normal, float y_normal, float z_normal) const = 0; + virtual void SetVelocity(float x, float y, float z, float fMagnitude) const = 0; +}; + +class CSoundInstance2D : public ISoundInstance +{ +public: + CSoundInstance2D(); + virtual ~CSoundInstance2D(); + +public: // from interface + bool Initialize(); + void Destroy(); + + bool SetSound(CSoundData* pSound); + void Play(int iLoopCount = 1, DWORD dwPlayCycleTimeLimit = 0) const; + void Pause() const; + void Resume() const; + void Stop(); + void GetVolume(float& rfVolume) const; + void SetVolume(float volume) const; + bool IsDone() const; + void SetPosition(float x, float y, float z) const; + void SetOrientation(float x_face, float y_face, float z_face, + float x_normal, float y_normal, float z_normal) const; + void SetVelocity(float fx, float fy, float fz, float fMagnitude) const; + +private: + HSAMPLE m_sample; + CSoundData* m_pSoundData; +}; + +class CSoundInstance3D : public ISoundInstance +{ + public: + CSoundInstance3D(); + virtual ~CSoundInstance3D(); + + public: // from interface + bool Initialize(); + void Destroy(); + + bool SetSound(CSoundData * pSound); + void Play(int iLoopCount = 1, DWORD dwPlayCycleTimeLimit = 0) const; + void Pause() const; + void Resume() const; + void Stop(); + void GetVolume(float& rfVolume) const; + void SetVolume(float volume) const; + bool IsDone() const; + + void SetPosition(float x, float y, float z) const; + void SetOrientation(float x_face, float y_face, float z_face, + float x_normal, float y_normal, float z_normal) const; + void SetVelocity(float fx, float fy, float fz, float fMagnitude) const; + + void UpdatePosition(float fElapsedTime); + + private: + H3DSAMPLE m_sample; + CSoundData * m_pSoundData; +}; + +class CSoundInstanceStream : public ISoundInstance +{ +public: + CSoundInstanceStream(); + virtual ~CSoundInstanceStream(); + +public: // from interface + bool Initialize(); + void Destroy(); + + void SetStream(HSTREAM stream); + bool SetSound(CSoundData* pSound); + + void Play(int iLoopCount = 1, DWORD dwPlayCycleTimeLimit = 0) const; + void Pause() const; + void Resume() const; + void Stop(); + void GetVolume(float& rfVolume) const; + void SetVolume(float volume) const; + bool IsDone() const; + bool IsData() const; + + void SetPosition(float x, float y, float z) const; + void SetOrientation(float x_face, float y_face, float z_face, + float x_normal, float y_normal, float z_normal) const; + void SetVelocity(float fx, float fy, float fz, float fMagnitude) const; + +private: + HSTREAM m_stream; +}; + +#endif diff --git a/source/MilesLib/SoundInstance2D.cpp b/source/MilesLib/SoundInstance2D.cpp new file mode 100644 index 0000000..594c610 --- /dev/null +++ b/source/MilesLib/SoundInstance2D.cpp @@ -0,0 +1,121 @@ +#include "stdafx.h" +#include "SoundManager2D.h" + +CSoundInstance2D::CSoundInstance2D() : m_sample(NULL), m_pSoundData(NULL) +{ +} + +CSoundInstance2D::~CSoundInstance2D() +{ + Destroy(); +} + +void CSoundInstance2D::Destroy() +{ + SAFE_RELEASE(m_pSoundData); + + if (m_sample) + { + AIL_release_sample_handle(m_sample); + m_sample = NULL; + } +} + +bool CSoundInstance2D::Initialize() +{ + if (m_sample) + return true; + + m_sample = AIL_allocate_sample_handle(ms_DIGDriver); + return m_sample ? true : false; +} + +bool CSoundInstance2D::SetSound(CSoundData * pSoundData) +{ + assert(m_sample != NULL && pSoundData != NULL); + + // ۷ īƮ 1 ε带 ؾ  + // ǹǷ ݵ Get ȣ ϰ ؾ Ѵ. + // , m_pSoundData pSoundData m_pSoundData ۷ + // īͰ 1 , ʿϰ ε尡 ϾǷ ̸ ۷ + // ī͸ ÷ Ѵ. + LPVOID lpData = pSoundData->Get(); + + AIL_init_sample(m_sample); + + if (AIL_set_sample_file(m_sample, lpData, pSoundData->GetSize()) == NULL) + { + if (m_pSoundData != NULL) + { + m_pSoundData->Release(); + m_pSoundData = NULL; + } + + pSoundData->Release(); + TraceError("%s: %s", AIL_last_error(), pSoundData->GetFileName()); + return false; + } + + if (m_pSoundData != NULL) + { + m_pSoundData->Release(); + m_pSoundData = NULL; + } + + m_pSoundData = pSoundData; + return true; +} + +bool CSoundInstance2D::IsDone() const +{ + return AIL_sample_status(m_sample) == SMP_DONE; +} + +void CSoundInstance2D::Play(int iLoopCount, DWORD dwPlayCycleTimeLimit) const +{ + AIL_set_sample_loop_count(m_sample, iLoopCount); + AIL_start_sample(m_sample); +} + +void CSoundInstance2D::Pause() const +{ + AIL_stop_sample(m_sample); +} + +void CSoundInstance2D::Resume() const +{ + AIL_resume_sample(m_sample); +} + +void CSoundInstance2D::Stop() +{ + AIL_end_sample(m_sample); + m_sample = NULL; +} + +void CSoundInstance2D::GetVolume(float& rfVolume) const +{ + AIL_sample_volume_pan(m_sample, &rfVolume, NULL); +} + +void CSoundInstance2D::SetVolume(float volume) const +{ + volume = max(0.0f, min(1.0f, volume)); + AIL_set_sample_volume_pan(m_sample, volume, 0.5f); +} + +void CSoundInstance2D::SetPosition(float x, float y, float z) const +{ + assert(!"must not call this method"); +} + +void CSoundInstance2D::SetOrientation(float x_face, float y_face, float z_face, + float x_normal, float y_normal, float z_normal) const +{ + assert(!"must not call this method"); +} + +void CSoundInstance2D::SetVelocity(float fx, float fy, float fz, float fMagnitude) const +{ + assert(!"must not call this method"); +} diff --git a/source/MilesLib/SoundInstance3D.cpp b/source/MilesLib/SoundInstance3D.cpp new file mode 100644 index 0000000..42fcd9f --- /dev/null +++ b/source/MilesLib/SoundInstance3D.cpp @@ -0,0 +1,137 @@ +#include "stdafx.h" +#include "SoundManager3D.h" +#include "../eterBase/Timer.h" + +CSoundInstance3D::CSoundInstance3D() : m_sample(NULL), m_pSoundData(NULL) +{ +} + +CSoundInstance3D::~CSoundInstance3D() +{ + Destroy(); +} + +void CSoundInstance3D::Destroy() +{ + SAFE_RELEASE(m_pSoundData); + + if (m_sample) + { + AIL_release_3D_sample_handle(m_sample); + m_sample = NULL; + } +} + +bool CSoundInstance3D::Initialize() +{ + if (m_sample) + return true; + + m_sample = AIL_allocate_3D_sample_handle(ms_pProviderDefault->hProvider); + return m_sample ? true : false; +} + +bool CSoundInstance3D::SetSound(CSoundData* pSoundData) +{ + assert(m_sample != NULL && pSoundData != NULL); + + // ۷ īƮ 1 ε带 ؾ  + // ǹǷ ݵ Get ȣ ϰ ؾ Ѵ. + // , m_pSoundData pSoundData m_pSoundData ۷ + // īͰ 1 , ʿϰ ε尡 ϾǷ ̸ ۷ + // ī͸ ÷ Ѵ. + LPVOID lpData = pSoundData->Get(); + + if (m_pSoundData != NULL) + { + m_pSoundData->Release(); + m_pSoundData = NULL; + } + + if (AIL_set_3D_sample_file(m_sample, lpData) == NULL) + { + TraceError("%s: %s", AIL_last_error(), pSoundData->GetFileName()); + pSoundData->Release(); + return false; + } + + m_pSoundData = pSoundData; + + AIL_set_3D_position(m_sample, 0.0F, 0.0F, 0.0F); + AIL_auto_update_3D_position(m_sample, 0); + return true; +} + +bool CSoundInstance3D::IsDone() const +{ + return AIL_3D_sample_status(m_sample) == SMP_DONE; +} + +void CSoundInstance3D::Play(int iLoopCount, DWORD dwPlayCycleTimeLimit) const +{ + if (!m_pSoundData) + return; + + DWORD dwCurTime = ELTimer_GetMSec(); + + if (dwCurTime - m_pSoundData->GetPlayTime() < dwPlayCycleTimeLimit) + return; + + m_pSoundData->SetPlayTime(dwCurTime); + + AIL_set_3D_sample_loop_count(m_sample, iLoopCount); + AIL_start_3D_sample(m_sample); +} + +void CSoundInstance3D::Pause() const +{ + AIL_stop_3D_sample(m_sample); +} + +void CSoundInstance3D::Resume() const +{ + AIL_resume_3D_sample(m_sample); +} + +void CSoundInstance3D::Stop() +{ + AIL_end_3D_sample(m_sample); +// m_sample = NULL; +// NOTE : IsDone üũϷ m_sample ־ մϴ - [levites] +} + +void CSoundInstance3D::GetVolume(float& rfVolume) const +{ + rfVolume = AIL_3D_sample_volume(m_sample); +} + +void CSoundInstance3D::SetVolume(float volume) const +{ + volume = max(0.0f, min(1.0f, volume)); + AIL_set_3D_sample_volume(m_sample, volume); +} + +void CSoundInstance3D::SetPosition(float x, float y, float z) const +{ + AIL_set_3D_position(m_sample, x, y, -z); +} + +void CSoundInstance3D::SetOrientation(float x_face, float y_face, float z_face, + float x_normal, float y_normal, float z_normal) const +{ + assert(!" CSoundInstance3D::SetOrientation - ʴ Լ"); +// AIL_set_3D_orientation(m_sample, +// x_face, y_face, z_face, +// x_normal, y_normal, z_normal); +} + +void CSoundInstance3D::SetVelocity(float fDistanceX, float fDistanceY, float fDistanceZ, float fNagnitude) const +{ + AIL_set_3D_velocity(m_sample, fDistanceX, fDistanceY, fDistanceZ, fNagnitude); + AIL_auto_update_3D_position(m_sample, 1); +} + +void CSoundInstance3D::UpdatePosition(float fElapsedTime) +{ + AIL_update_3D_position(m_sample, fElapsedTime); +} \ No newline at end of file diff --git a/source/MilesLib/SoundInstanceStream.cpp b/source/MilesLib/SoundInstanceStream.cpp new file mode 100644 index 0000000..798f3f9 --- /dev/null +++ b/source/MilesLib/SoundInstanceStream.cpp @@ -0,0 +1,114 @@ +#include "stdafx.h" +#include "SoundInstance.h" + +CSoundInstanceStream::CSoundInstanceStream() : m_stream(NULL) +{ +} + +CSoundInstanceStream::~CSoundInstanceStream() +{ + Destroy(); +} + +void CSoundInstanceStream::Destroy() +{ + if (m_stream != NULL) + { + AIL_close_stream(m_stream); + m_stream = NULL; + } +} + +bool CSoundInstanceStream::Initialize() +{ + return true; +} + +void CSoundInstanceStream::SetStream(HSTREAM stream) +{ + m_stream = stream; +} + +bool CSoundInstanceStream::IsDone() const +{ + return AIL_stream_status(m_stream) == -1; +} + +bool CSoundInstanceStream::IsData() const +{ + if (m_stream) + return true; + + return false; +} + +void CSoundInstanceStream::Play(int count, DWORD dwPlayCycleTimeLimit) const +{ + if (!IsData()) + return; + + AIL_set_stream_loop_count(m_stream, count); + AIL_start_stream(m_stream); +} + +void CSoundInstanceStream::Pause() const +{ + if (!IsData()) + return; + + AIL_pause_stream(m_stream, 1); +} + +void CSoundInstanceStream::Resume() const +{ + if (!IsData()) + return; + + AIL_pause_stream(m_stream, 0); +} + +void CSoundInstanceStream::Stop() +{ + if (!IsData()) + return; + + AIL_close_stream(m_stream); + m_stream = NULL; +} + +void CSoundInstanceStream::GetVolume(float& rfVolume) const +{ + float tmp; + + if (!IsData()) + return; + + AIL_stream_volume_levels(m_stream, &rfVolume, &tmp); +} + +void CSoundInstanceStream::SetVolume(float volume) const +{ + if (!IsData()) + return; + + volume = max(0.0f, min(1.0f, volume)); + AIL_set_stream_volume_levels(m_stream, volume, volume); +} + +bool CSoundInstanceStream::SetSound(CSoundData* pSound) +{ + return true; +} + +void CSoundInstanceStream::SetPosition(float x, float y, float z) const +{ +} + +void CSoundInstanceStream::SetOrientation(float x_face, float y_face, float z_face, + float x_normal, float y_normal, float z_normal) const +{ +} + +void CSoundInstanceStream::SetVelocity(float fx, float fy, float fz, float fMagnitude) const +{ +} diff --git a/source/MilesLib/SoundManager.cpp b/source/MilesLib/SoundManager.cpp new file mode 100644 index 0000000..9df66b1 --- /dev/null +++ b/source/MilesLib/SoundManager.cpp @@ -0,0 +1,646 @@ +#include "StdAfx.h" +#include + +#include "SoundManager.h" +#include "../EterBase/Timer.h" + +CSoundManager2D CSoundManager::ms_SoundManager2D; +CSoundManager3D CSoundManager::ms_SoundManager3D; +CSoundManagerStream CSoundManager::ms_SoundManagerStream; + +CSoundManager::CSoundManager() +{ + m_bInitialized = FALSE; + m_isSoundDisable = FALSE; + + m_fxPosition = 0.0f; + m_fyPosition = 0.0f; + m_fzPosition = 0.0f; + + m_fSoundScale = 200.0f; + m_fAmbienceSoundScale = 1000.0f; + m_fSoundVolume = 1.0f; + m_fMusicVolume = 1.0f; + + m_fBackupMusicVolume = 0.0f; + m_fBackupSoundVolume = 0.0f; + + for (int i = 0; i < CSoundManagerStream::MUSIC_INSTANCE_MAX_NUM; ++i) + { + TMusicInstance & rInstance = m_MusicInstances[i]; + rInstance.dwMusicFileNameCRC = 0; + rInstance.MusicState = MUSIC_STATE_OFF; + rInstance.fVolume = 0.0f; + rInstance.fVolumeSpeed = 0.0f; + } +} + +CSoundManager::~CSoundManager() +{ +} + +BOOL CSoundManager::Create() +{ + if (!ms_SoundManager2D.Initialize()) { + Tracen("CSoundManager::Create - Sound2D::Initialize - FAILURE"); + return FALSE; + } + + if (!ms_SoundManagerStream.Initialize()) + { + Tracen("CSoundManager::Create - SoundStream::Initialize - FAILURE"); + return FALSE; + } + + if (!ms_SoundManager3D.Initialize()) + { + Tracen("CSoundManager::Create - Sound3D::Initialize - FAILURE"); + return FALSE; + } + + return TRUE; +} + +void CSoundManager::Destroy() +{ + ms_SoundManagerStream.Destroy(); + ms_SoundManager3D.Destroy(); + ms_SoundManager2D.Destroy(); + m_PlaySoundHistoryMap.clear(); // Fix +} + +void CSoundManager::SetPosition(float fx, float fy, float fz) +{ + m_fxPosition = fx; + m_fyPosition = fy; + m_fzPosition = fz; +} + +void CSoundManager::SetDirection(float fxDir, float fyDir, float fzDir, float fxUp, float fyUp, float fzUp) +{ + ms_SoundManager3D.SetListenerDirection(fxDir, fyDir, fzDir, fxUp, fyUp, fzUp); +} + +void CSoundManager::Update() +{ + // Update Information about 3D Sound + ms_SoundManager3D.SetListenerPosition(0.0f, 0.0f, 0.0f); + + for (int i = 0; i < CSoundManagerStream::MUSIC_INSTANCE_MAX_NUM; ++i) + { + TMusicInstance & rMusicInstance = m_MusicInstances[i]; + if (MUSIC_STATE_OFF == rMusicInstance.MusicState) + continue; + + switch (rMusicInstance.MusicState) + { + case MUSIC_STATE_FADE_IN: + rMusicInstance.fVolume += rMusicInstance.fVolumeSpeed; + + if (rMusicInstance.fVolume >= GetMusicVolume()) + { + rMusicInstance.fVolume = GetMusicVolume(); + rMusicInstance.fVolumeSpeed = 0.0f; + rMusicInstance.MusicState = MUSIC_STATE_PLAY; + } + + { + CSoundInstanceStream * pInstance = ms_SoundManagerStream.GetInstance(i); + if (pInstance) + pInstance->SetVolume(rMusicInstance.fVolume); + } + break; + + case MUSIC_STATE_FADE_LIMIT_OUT: + rMusicInstance.fVolume -= rMusicInstance.fVolumeSpeed; + if (rMusicInstance.fVolume <= rMusicInstance.fLimitVolume) + { + rMusicInstance.fVolume = rMusicInstance.fLimitVolume; + rMusicInstance.fVolumeSpeed = 0.0f; + rMusicInstance.MusicState = MUSIC_STATE_PLAY; + } + { + CSoundInstanceStream * pInstance = ms_SoundManagerStream.GetInstance(i); + if (pInstance) + pInstance->SetVolume(rMusicInstance.fVolume); + } + break; + case MUSIC_STATE_FADE_OUT: + rMusicInstance.fVolume -= rMusicInstance.fVolumeSpeed; + if (rMusicInstance.fVolume <= 0.0f) + { + rMusicInstance.fVolume = 0.0f; + rMusicInstance.fVolumeSpeed = 0.0f; + rMusicInstance.MusicState = MUSIC_STATE_OFF; + + StopMusic(i); + } + { + CSoundInstanceStream * pInstance = ms_SoundManagerStream.GetInstance(i); + if (pInstance) + pInstance->SetVolume(rMusicInstance.fVolume); + } + break; + } + } +} + +void CSoundManager::UpdateSoundData(DWORD dwcurTime, const NSound::TSoundDataVector * c_pSoundDataVector) +{ + assert(!"CSoundManager::UpdateSoundData"); +} + +void CSoundManager::UpdateSoundData(float fx, float fy, float fz, DWORD dwcurTime, const NSound::TSoundDataVector * c_pSoundDataVector) +{ + assert(!"CSoundManager::UpdateSoundData"); +} + +void CSoundManager::UpdateSoundInstance(float fx, float fy, float fz, DWORD dwcurFrame, const NSound::TSoundInstanceVector * c_pSoundInstanceVector, BOOL bCheckFrequency) +{ + for (DWORD i = 0; i < c_pSoundInstanceVector->size(); ++i) + { + const NSound::TSoundInstance & c_rSoundInstance = c_pSoundInstanceVector->at(i); + if (c_rSoundInstance.dwFrame == dwcurFrame) + { + //Tracenf("PLAY SOUND %s", c_rSoundInstance.strSoundFileName.c_str()); + PlayCharacterSound3D(fx, fy, fz, c_rSoundInstance.strSoundFileName.c_str(), bCheckFrequency); + } + } +} + +void CSoundManager::UpdateSoundInstance(DWORD dwcurFrame, const NSound::TSoundInstanceVector * c_pSoundInstanceVector) +{ + for (DWORD i = 0; i < c_pSoundInstanceVector->size(); ++i) + { + const NSound::TSoundInstance & c_rSoundInstance = c_pSoundInstanceVector->at(i); + + if (c_rSoundInstance.dwFrame == dwcurFrame) + { + PlaySound2D(c_rSoundInstance.strSoundFileName.c_str()); + } + } +} + +float CSoundManager::GetSoundScale() +{ + return m_fSoundScale; +} + +void CSoundManager::SetSoundScale(float fScale) +{ + m_fSoundScale = fScale; +} + +void CSoundManager::SetAmbienceSoundScale(float fScale) +{ + m_fAmbienceSoundScale = fScale; +} + +void CSoundManager::SetSoundVolume(float fVolume) +{ + if (m_isSoundDisable) + { + m_fBackupSoundVolume = fVolume; + return; + } + + fVolume = fMAX(fVolume, 0.0f); + fVolume = fMIN(fVolume, 1.0f); + m_fSoundVolume = fVolume; + + if (!m_isSoundDisable) + { + m_fBackupSoundVolume = fVolume; + } +} + +void CSoundManager::__SetMusicVolume(float fVolume) +{ + if (m_isSoundDisable) + { + m_fBackupMusicVolume = fVolume; + return; + } + + fVolume = fMAX(fVolume, 0.0f); + fVolume = fMIN(fVolume, 1.0f); + m_fMusicVolume = fVolume; + + if (!m_isSoundDisable) + { + m_fBackupMusicVolume = fVolume; + } + + for (int i = 0; i < CSoundManagerStream::MUSIC_INSTANCE_MAX_NUM; ++i) + { + TMusicInstance & rMusicInstance = m_MusicInstances[i]; + if (MUSIC_STATE_OFF == rMusicInstance.MusicState) + continue; + if (MUSIC_STATE_FADE_OUT == rMusicInstance.MusicState) + continue; + + rMusicInstance.fVolume = fVolume; + + CSoundInstanceStream * pInstance = ms_SoundManagerStream.GetInstance(i); + if (pInstance) + pInstance->SetVolume(fVolume); + } +} + +float CSoundManager::__ConvertRatioVolumeToApplyVolume(float fRatioVolume) +{ + if (0.1f>fRatioVolume) + return fRatioVolume; + + return (float)pow(10.0f, (-1.0f + fRatioVolume)); +} + +float CSoundManager::__ConvertGradeVolumeToApplyVolume(int nGradeVolume) +{ + return __ConvertRatioVolumeToApplyVolume(nGradeVolume/5.0f); +} + + +void CSoundManager::SetSoundVolumeGrade(int iGrade) +{ + float fVolume=__ConvertGradeVolumeToApplyVolume(iGrade); + SetSoundVolume(fVolume); +} + +//void CSoundManager::SetMusicVolumeGrade(int iGrade) +//{ +// float fVolume=__ConvertGradeVolumeToApplyVolume(iGrade); +// __SetMusicVolume(fVolume); +//} + +void CSoundManager::SetSoundVolumeRatio(float fRatio) +{ + float fVolume = __ConvertRatioVolumeToApplyVolume(fRatio); + SetSoundVolume(fVolume); +} + +void CSoundManager::SetMusicVolume(float fVolume) +{ + //float fVolume = __ConvertRatioVolumeToApplyVolume(fRatio); + __SetMusicVolume(fVolume); +} + +float CSoundManager::GetSoundVolume() +{ + return m_fSoundVolume; +} + +float CSoundManager::GetMusicVolume() +{ + return m_fMusicVolume; +} + +BOOL CSoundManager::GetSoundInstance2D(const char * c_szSoundFileName, ISoundInstance ** ppInstance) +{ + *ppInstance = ms_SoundManager2D.GetInstance(c_szSoundFileName); + + if (!*ppInstance) + return FALSE; + + return TRUE; +} + +BOOL CSoundManager::GetSoundInstance3D(const char * c_szFileName, ISoundInstance ** ppInstance) +{ + int iIndex = ms_SoundManager3D.SetInstance(c_szFileName); + + if (-1 == iIndex) + return FALSE; + + *ppInstance = ms_SoundManager3D.GetInstance(iIndex); + + if (!*ppInstance) + return FALSE; + + return TRUE; +} + +void CSoundManager::PlaySound2D(const char * c_szFileName) +{ + if (0.0f == GetSoundVolume()) + return; + + ISoundInstance * pInstance; + if (!GetSoundInstance2D(c_szFileName, &pInstance)) + return; + + pInstance->SetVolume(GetSoundVolume()); + pInstance->Play(1); +} + +void CSoundManager::PlaySound3D(float fx, float fy, float fz, const char * c_szFileName, int iPlayCount) +{ + if (0.0f == GetSoundVolume()) + return; + + int iIndex = ms_SoundManager3D.SetInstance(c_szFileName); + if (-1 == iIndex) + return; + + ISoundInstance * pInstance = ms_SoundManager3D.GetInstance(iIndex); + if (!pInstance) + return; + + pInstance->SetPosition((fx - m_fxPosition) / m_fSoundScale, + (fy - m_fyPosition) / m_fSoundScale, + (fz - m_fzPosition) / m_fSoundScale); + + pInstance->SetVolume(GetSoundVolume()); + pInstance->Play(iPlayCount); +} + +int CSoundManager::PlayAmbienceSound3D(float fx, float fy, float fz, const char * c_szFileName, int iPlayCount) +{ + if (0.0f == GetSoundVolume()) + return -1; + + int iIndex = ms_SoundManager3D.SetInstance(c_szFileName); + if (-1 == iIndex) + return -1; + + ISoundInstance * pInstance = ms_SoundManager3D.GetInstance(iIndex); + if (!pInstance) + return -1; + + pInstance->SetPosition((fx - m_fxPosition) / m_fAmbienceSoundScale, + (fy - m_fyPosition) / m_fAmbienceSoundScale, + (fz - m_fzPosition) / m_fAmbienceSoundScale); + + pInstance->SetVolume(GetSoundVolume()); + pInstance->Play(iPlayCount); + + return iIndex; +} + +void CSoundManager::PlayCharacterSound3D(float fx, float fy, float fz, const char * c_szFileName, BOOL bCheckFrequency) +{ + if (0.0f == GetSoundVolume()) + return; + + // ȭ ʿ ִ - [levites] + if (bCheckFrequency) + { + static float s_fLimitDistance = 5000*5000; + float fdx = (fx - m_fxPosition) * (fx - m_fxPosition); + float fdy = (fy - m_fyPosition) * (fy - m_fyPosition); + + if (fdx+fdy > s_fLimitDistance) + return; + + std::map::iterator itor = m_PlaySoundHistoryMap.find(c_szFileName); + if (m_PlaySoundHistoryMap.end() != itor) + { + float fTime = itor->second; + if (CTimer::Instance().GetCurrentSecond() - fTime < 0.3f) + { + //Tracef("Ȱ Ҹ 0.3 ٽ ÷ %s\n", c_szFileName); + return; + } + } + + m_PlaySoundHistoryMap.erase(c_szFileName); + m_PlaySoundHistoryMap.insert(std::map::value_type(c_szFileName, CTimer::Instance().GetCurrentSecond())); + } + + ISoundInstance * pInstance; + + if (!GetSoundInstance3D(c_szFileName, &pInstance)) + return; + + pInstance->SetPosition((fx - m_fxPosition) / m_fSoundScale, + (fy - m_fyPosition) / m_fSoundScale, + (fz - m_fzPosition) / m_fSoundScale); + + pInstance->SetVolume(GetSoundVolume()); + pInstance->Play(1); +} + +void CSoundManager::StopSound3D(int iIndex) +{ + ISoundInstance * pInstance = ms_SoundManager3D.GetInstance(iIndex); + + if (!pInstance) + return; + + pInstance->Stop(); + //bool bisDone = pInstance->IsDone(); +} + +void CSoundManager::SetSoundVolume3D(int iIndex, float fVolume) +{ + ISoundInstance * pInstance = ms_SoundManager3D.GetInstance(iIndex); + + if (!pInstance) + return; + + pInstance->SetVolume(fVolume); +} + +void CSoundManager::StopAllSound3D() +{ + for (int i = 0; i < CSoundManager3D::INSTANCE_MAX_COUNT; ++i) + { + StopSound3D(i); + } + + m_PlaySoundHistoryMap.clear(); // Fix +} + +void CSoundManager::PlayMusic(const char * c_szFileName) +{ + PlayMusic(0, c_szFileName, GetMusicVolume(), 0.0f); +} + +void CSoundManager::FadeInMusic(const char * c_szFileName, float fVolumeSpeed) +{ + DWORD dwIndex; + if (GetMusicIndex(c_szFileName, &dwIndex)) + { + m_MusicInstances[dwIndex].MusicState = MUSIC_STATE_FADE_IN; + m_MusicInstances[dwIndex].fVolumeSpeed = fVolumeSpeed; + return; + } + + FadeOutAllMusic(); + + //Tracenf("FadeInMusic: %s", c_szFileName); + + for (int i = 0; i < CSoundManagerStream::MUSIC_INSTANCE_MAX_NUM; ++i) + { + TMusicInstance & rMusicInstance = m_MusicInstances[i]; + if (MUSIC_STATE_OFF != rMusicInstance.MusicState) + continue; + + PlayMusic(i, c_szFileName, 0.0f, fVolumeSpeed); + return; + } + + return; + + // If there is no empty music slot, then play music on slot 0. + /* + StopMusic(0); + PlayMusic(0, c_szFileName, 0.0f, fVolumeSpeed); + */ +} + +void CSoundManager::FadeLimitOutMusic(const char * c_szFileName, float fLimitVolume, float fVolumeSpeed) +{ + //Tracenf("FadeLimitOutMusic: %s", c_szFileName); + + DWORD dwIndex; + if (!GetMusicIndex(c_szFileName, &dwIndex)) + { + Tracenf("FadeOutMusic: %s - ERROR NOT EXIST", c_szFileName); + return; + } + + if (dwIndex >= CSoundManagerStream::MUSIC_INSTANCE_MAX_NUM) + { + Tracenf("FadeOutMusic: %s - ERROR OUT OF RANGE", c_szFileName); + return; + } + + SMusicInstance& rkMusicInst=m_MusicInstances[dwIndex]; + rkMusicInst.MusicState = MUSIC_STATE_FADE_LIMIT_OUT; + rkMusicInst.fVolumeSpeed = fVolumeSpeed; + rkMusicInst.fLimitVolume = __ConvertRatioVolumeToApplyVolume(fLimitVolume); + + //Tracenf("LimitVolume %f(%f)", fLimitVolume, rkMusicInst.fLimitVolume); +} + +void CSoundManager::FadeOutMusic(const char * c_szFileName, float fVolumeSpeed) +{ + //Tracenf("FadeOutMusic: %s", c_szFileName); + + DWORD dwIndex; + if (!GetMusicIndex(c_szFileName, &dwIndex)) + { + Tracenf("FadeOutMusic: %s - ERROR NOT EXIST", c_szFileName); + return; + } + + if (dwIndex >= CSoundManagerStream::MUSIC_INSTANCE_MAX_NUM) + { + Tracenf("FadeOutMusic: %s - ERROR OUT OF RANGE", c_szFileName); + return; + } + + m_MusicInstances[dwIndex].MusicState = MUSIC_STATE_FADE_OUT; + m_MusicInstances[dwIndex].fVolumeSpeed = fVolumeSpeed; +} + +void CSoundManager::FadeOutAllMusic() +{ + //Tracenf("FadeOutAllMusic"); + + for (int i = 0; i < CSoundManagerStream::MUSIC_INSTANCE_MAX_NUM; ++i) + { + if (MUSIC_STATE_OFF == m_MusicInstances[i].MusicState) + continue; + + m_MusicInstances[i].MusicState = MUSIC_STATE_FADE_OUT; + m_MusicInstances[i].fVolumeSpeed = 0.01f; + } +} + +void CSoundManager::SaveVolume() +{ + // NOTE : ι ̻ Save õҶ ׳ Return + if (m_isSoundDisable) + return; + + float fBackupMusicVolume = m_fMusicVolume; + float fBackupSoundVolume = m_fSoundVolume; + __SetMusicVolume(0.0f); + SetSoundVolume(0.0f); + m_fBackupMusicVolume = fBackupMusicVolume; + m_fBackupSoundVolume = fBackupSoundVolume; + m_isSoundDisable = TRUE; +} + +void CSoundManager::RestoreVolume() +{ + m_isSoundDisable = FALSE; + __SetMusicVolume(m_fBackupMusicVolume); + SetSoundVolume(m_fBackupSoundVolume); +} + +void CSoundManager::PlayMusic(DWORD dwIndex, const char * c_szFileName, float fVolume, float fVolumeSpeed) +{ + if (dwIndex >= CSoundManagerStream::MUSIC_INSTANCE_MAX_NUM) + return; + + if (!ms_SoundManagerStream.SetInstance(dwIndex, c_szFileName)) + { + TraceError("CSoundManager::PlayMusic - Failed to load stream sound : %s", c_szFileName); + return; + } + + CSoundInstanceStream * pInstance = ms_SoundManagerStream.GetInstance(dwIndex); + if (!pInstance) + { + TraceError("CSoundManager::PlayMusic - There is no stream sound instance : %s", c_szFileName); + return; + } + + pInstance->SetVolume(fVolume); + pInstance->Play(0); + + TMusicInstance & rMusicInstance = m_MusicInstances[dwIndex]; + rMusicInstance.fVolume = fVolume; + rMusicInstance.fVolumeSpeed = fVolumeSpeed; + rMusicInstance.MusicState = MUSIC_STATE_FADE_IN; + + std::string strFileName; + StringPath(c_szFileName, strFileName); + rMusicInstance.dwMusicFileNameCRC = GetCaseCRC32(strFileName.c_str(), strFileName.length()); +} + +void CSoundManager::StopMusic(DWORD dwIndex) +{ + if (dwIndex >= CSoundManagerStream::MUSIC_INSTANCE_MAX_NUM) + return; + + CSoundInstanceStream * pInstance = ms_SoundManagerStream.GetInstance(dwIndex); + if (!pInstance) + return; + + pInstance->Stop(); + + TMusicInstance & rMusicInstance = m_MusicInstances[dwIndex]; + rMusicInstance.fVolume = 0.0f; + rMusicInstance.fVolumeSpeed = 0.0f; + rMusicInstance.MusicState = MUSIC_STATE_OFF; + rMusicInstance.dwMusicFileNameCRC = 0; +} + +BOOL CSoundManager::GetMusicIndex(const char * c_szFileName, DWORD * pdwIndex) +{ + std::string strFileName; + StringPath(c_szFileName, strFileName); + DWORD dwCRC = GetCaseCRC32(strFileName.c_str(), strFileName.length()); + + for (int i = 0; i < CSoundManagerStream::MUSIC_INSTANCE_MAX_NUM; ++i) + { + const TMusicInstance & c_rMusicInstance = m_MusicInstances[i]; + if (MUSIC_STATE_OFF != c_rMusicInstance.MusicState) + if (c_rMusicInstance.dwMusicFileNameCRC == dwCRC) + { + *pdwIndex = i; + return TRUE; + } + } + + return FALSE; +} + +void CSoundManager::FadeAll() +{ + FadeOutAllMusic(); +} diff --git a/source/MilesLib/SoundManager.h b/source/MilesLib/SoundManager.h new file mode 100644 index 0000000..d241762 --- /dev/null +++ b/source/MilesLib/SoundManager.h @@ -0,0 +1,111 @@ +#pragma once + +#include "../eterBase/Singleton.h" + +#include "SoundManagerStream.h" +#include "SoundManager2D.h" +#include "SoundManager3D.h" +#include "Type.h" + +class CSoundManager : public CSingleton +{ +public: + CSoundManager(); + virtual ~CSoundManager(); + + BOOL Create(); + void Destroy(); + + void SetPosition(float fx, float fy, float fz); + void SetDirection(float fxDir, float fyDir, float fzDir, float fxUp, float fyUp, float fzUp); + void Update(); + + float GetSoundScale(); + void SetSoundScale(float fScale); + void SetAmbienceSoundScale(float fScale); + void SetSoundVolume(float fVolume); + void SetSoundVolumeRatio(float fRatio); + void SetMusicVolume(float fVolume); + void SetMusicVolumeRatio(float fRatio); + void SetSoundVolumeGrade(int iGrade); + void SetMusicVolumeGrade(int iGrade); + void SaveVolume(); + void RestoreVolume(); + float GetSoundVolume(); + float GetMusicVolume(); + + // Sound + void PlaySound2D(const char * c_szFileName); + void PlaySound3D(float fx, float fy, float fz, const char * c_szFileName, int iPlayCount = 1); + void StopSound3D(int iIndex); + int PlayAmbienceSound3D(float fx, float fy, float fz, const char * c_szFileName, int iPlayCount = 1); + void PlayCharacterSound3D(float fx, float fy, float fz, const char * c_szFileName, BOOL bCheckFrequency = FALSE); + void SetSoundVolume3D(int iIndex, float fVolume); + void StopAllSound3D(); + + // Music + void PlayMusic(const char * c_szFileName); + void FadeInMusic(const char * c_szFileName, float fVolumeSpeed = 0.016f); + void FadeOutMusic(const char * c_szFileName, float fVolumeSpeed = 0.016f); + void FadeLimitOutMusic(const char * c_szFileName, float fLimitVolume, float fVolumeSpeed = 0.016f); + void FadeOutAllMusic(); + void FadeAll(); + + // Sound Node + void UpdateSoundData(DWORD dwcurFrame, const NSound::TSoundDataVector * c_pSoundDataVector); + void UpdateSoundData(float fx, float fy, float fz, DWORD dwcurFrame, const NSound::TSoundDataVector * c_pSoundDataVector); + void UpdateSoundInstance(float fx, float fy, float fz, DWORD dwcurFrame, const NSound::TSoundInstanceVector * c_pSoundInstanceVector, BOOL bCheckFrequency = FALSE); + void UpdateSoundInstance(DWORD dwcurFrame, const NSound::TSoundInstanceVector * c_pSoundInstanceVector); + +protected: + enum EMusicState + { + MUSIC_STATE_OFF, + MUSIC_STATE_PLAY, + MUSIC_STATE_FADE_IN, + MUSIC_STATE_FADE_OUT, + MUSIC_STATE_FADE_LIMIT_OUT, + }; + typedef struct SMusicInstance + { + DWORD dwMusicFileNameCRC; + EMusicState MusicState; + float fVolume; + float fLimitVolume; + float fVolumeSpeed; + } TMusicInstance; + + void PlayMusic(DWORD dwIndex, const char * c_szFileName, float fVolume, float fVolumeSpeed); + void StopMusic(DWORD dwIndex); + BOOL GetMusicIndex(const char * c_szFileName, DWORD * pdwIndex); + +protected: + float __ConvertGradeVolumeToApplyVolume(int nVolumeGrade); + float __ConvertRatioVolumeToApplyVolume(float fVolumeRatio); + void __SetMusicVolume(float fVolume); + BOOL GetSoundInstance2D(const char * c_szSoundFileName, ISoundInstance ** ppInstance); + BOOL GetSoundInstance3D(const char * c_szFileName, ISoundInstance ** ppInstance); + +protected: + BOOL m_bInitialized; + BOOL m_isSoundDisable; + + float m_fxPosition; + float m_fyPosition; + float m_fzPosition; + + float m_fSoundScale; + float m_fAmbienceSoundScale; + float m_fSoundVolume; + float m_fMusicVolume; + + float m_fBackupMusicVolume; + float m_fBackupSoundVolume; + + TMusicInstance m_MusicInstances[CSoundManagerStream::MUSIC_INSTANCE_MAX_NUM]; + std::map m_PlaySoundHistoryMap; + + static CSoundManager2D ms_SoundManager2D; + static CSoundManager3D ms_SoundManager3D; + static CSoundManagerStream ms_SoundManagerStream; +}; diff --git a/source/MilesLib/SoundManager2D.cpp b/source/MilesLib/SoundManager2D.cpp new file mode 100644 index 0000000..98957ba --- /dev/null +++ b/source/MilesLib/SoundManager2D.cpp @@ -0,0 +1,79 @@ +#include "Stdafx.h" +#include "SoundManager2D.h" + +CSoundManager2D::CSoundManager2D() +{ +} + +CSoundManager2D::~CSoundManager2D() +{ +} + +bool CSoundManager2D::Initialize() +{ + CSoundBase::Initialize(); + + if (ms_DIGDriver) + return true; + + ms_DIGDriver = AIL_open_digital_driver(44100, 16, 2, 0); + + for (int i = 0; i < INSTANCE_MAX_COUNT; ++i) + ms_Instances[i].Initialize(); +/* ms_DIGDriver = AIL_open_digital_driver(44100, + (DIG_F_STEREO_16 & DIG_F_16BITS_MASK) ? 16 : 8, + (DIG_F_STEREO_16 & DIG_F_16BITS_MASK) ? 2 : 1, + 0); +*/ + return true; +} + +void CSoundManager2D::Destroy() +{ + for (int i = 0; i < INSTANCE_MAX_COUNT; ++i) + ms_Instances[i].Destroy(); + + if (ms_DIGDriver != NULL) + { + AIL_close_digital_driver(ms_DIGDriver); + ms_DIGDriver = NULL; + } + + CSoundBase::Destroy(); +} + +ISoundInstance * CSoundManager2D::GetInstance(const char * c_pszFileName) +{ + DWORD dwFileCRC = GetFileCRC(c_pszFileName); + TSoundDataMap::iterator itor = ms_dataMap.find(dwFileCRC); + + CSoundData * pkSoundData; + + if (itor == ms_dataMap.end()) + pkSoundData = AddFile(dwFileCRC, c_pszFileName); // CSoundBase::AddFile + else + pkSoundData = itor->second; + + assert(pkSoundData != NULL); + + static DWORD k = 0; + + DWORD start = k++; + DWORD end = start + INSTANCE_MAX_COUNT; + + while (start < end) + { + CSoundInstance2D * pkInst = &ms_Instances[start % INSTANCE_MAX_COUNT]; + + if (pkInst->IsDone()) + { + if (!pkInst->SetSound(pkSoundData)) + TraceError("CSoundManager2D::GetInstance (filename: %s)", c_pszFileName); + return (pkInst); + } + + ++start; + } + + return NULL; +} diff --git a/source/MilesLib/SoundManager2D.h b/source/MilesLib/SoundManager2D.h new file mode 100644 index 0000000..f0730ce --- /dev/null +++ b/source/MilesLib/SoundManager2D.h @@ -0,0 +1,27 @@ +#ifndef __MILESLIB_CSOUNDMANAGER2D_H__ +#define __MILESLIB_CSOUNDMANAGER2D_H__ + +#include "SoundBase.h" +#include "SoundInstance.h" + +class CSoundManager2D : public CSoundBase +{ + public: + enum + { + INSTANCE_MAX_COUNT = 4 + }; + + CSoundManager2D(); + virtual ~CSoundManager2D(); + + bool Initialize(); + void Destroy(); + + ISoundInstance * GetInstance(const char* filename); + + protected: + CSoundInstance2D ms_Instances[INSTANCE_MAX_COUNT]; +}; + +#endif \ No newline at end of file diff --git a/source/MilesLib/SoundManager3D.cpp b/source/MilesLib/SoundManager3D.cpp new file mode 100644 index 0000000..e0e8631 --- /dev/null +++ b/source/MilesLib/SoundManager3D.cpp @@ -0,0 +1,205 @@ +#include "Stdafx.h" +#include "SoundManager3D.h" + +CSoundManager3D::CSoundManager3D() +{ + m_bInit = false; +} + +CSoundManager3D::~CSoundManager3D() +{ +} + +bool CSoundManager3D::Initialize() +{ + CSoundBase::Initialize(); + + if (ms_pProviderDefault) + return true; + + ms_ProviderVector.resize(MAX_PROVIDERS); + + HPROENUM enum3D = HPROENUM_FIRST; + int i = 0; + + while (AIL_enumerate_3D_providers(&enum3D, + &ms_ProviderVector[i].hProvider, + &ms_ProviderVector[i].name) && (i < MAX_PROVIDERS)) + { + TProvider * provider = &ms_ProviderVector[i]; + + //if (strcmp(provider->name, "DirectSound3D Software Emulation") == 0) + //if (strcmp(provider->name, "DirectSound3D Hardware Support") == 0) + //if (strcmp(provider->name, "DirectSound3D 7+ Software - Pan and Volume") == 0) + //if (strcmp(provider->name, "DirectSound3D 7+ Software - Light HRTF") == 0) + //if (strcmp(provider->name, "DirectSound3D 7+ Software - Full HRTF") == 0) + //if (strcmp(provider->name, "RAD Game Tools RSX 3D Audio") == 0) + //if (strcmp(provider->name, "Dolby Surround") == 0) + if (strcmp(provider->name, "Miles Fast 2D Positional Audio") == 0) + ms_pProviderDefault = provider; + + ++i; + } + + if (!ms_pProviderDefault) + { + CSoundBase::Destroy(); + return false; + } + + assert(ms_pProviderDefault != NULL); + + if (M3D_NOERR != AIL_open_3D_provider(ms_pProviderDefault->hProvider)) + { +// assert(!"AIL_open_3D_provider error"); +// char buf[64]; +// sprintf(buf, "Error AIL_open_3D_provider: %s\n", AIL_last_error()); +// OutputDebugString(buf); + + CSoundBase::Destroy(); + return false; + } + + m_pListener = AIL_open_3D_listener(ms_pProviderDefault->hProvider); + + SetListenerPosition(0.0f, 0.0f, 0.0f); + + for (i = 0; i < INSTANCE_MAX_COUNT; ++i) + { + m_Instances[i].Initialize(); + m_bLockingFlag[i] = false; + } + + m_bInit = true; + return true; +} + + +void CSoundManager3D::Destroy() +{ + if (!m_bInit) + return; + + for (int i = 0; i < INSTANCE_MAX_COUNT; ++i) + m_Instances[i].Destroy(); + + if (m_pListener) + { + AIL_close_3D_listener(m_pListener); + m_pListener = NULL; + } + + if (ms_pProviderDefault) + { + AIL_close_3D_provider(ms_pProviderDefault->hProvider); + ms_pProviderDefault = NULL; + } + + CSoundBase::Destroy(); + m_bInit = false; +} + +void CSoundManager3D::SetListenerDirection(float fxDir, float fyDir, float fzDir, float fxUp, float fyUp, float fzUp) +{ + if (NULL == m_pListener) + return; + AIL_set_3D_orientation(m_pListener, fxDir, fyDir, -fzDir, fxUp, fyUp, -fzUp); +} + +void CSoundManager3D::SetListenerPosition(float fX, float fY, float fZ) +{ +// assert(m_pListener != NULL); + if (NULL == m_pListener) + return; + AIL_set_3D_position(m_pListener, fX, fY, -fZ); +} + +void CSoundManager3D::SetListenerVelocity(float fDistanceX, float fDistanceY, float fDistanceZ, float fNagnitude) +{ +// assert(m_pListener != NULL); + if (NULL == m_pListener) + return; + AIL_set_3D_velocity(m_pListener, fDistanceX, fDistanceY, -fDistanceZ, fNagnitude); +} + +int CSoundManager3D::SetInstance(const char * c_pszFileName) +{ + DWORD dwFileCRC = GetFileCRC(c_pszFileName); + TSoundDataMap::iterator itor = ms_dataMap.find(dwFileCRC); + + CSoundData * pkSoundData; + + if (itor == ms_dataMap.end()) + pkSoundData = AddFile(dwFileCRC, c_pszFileName); // CSoundBase::AddFile + else + pkSoundData = itor->second; + + assert(pkSoundData != NULL); + + static DWORD k = 0; + + DWORD start = k++; + DWORD end = start + INSTANCE_MAX_COUNT; + + while (start < end) + { + CSoundInstance3D * pkInst = &m_Instances[start % INSTANCE_MAX_COUNT]; + + if (pkInst->IsDone()) + { + if (!pkInst->SetSound(pkSoundData)) + { + TraceError("CSoundManager3D::GetInstance (filename: %s)", c_pszFileName); + // NOTE : 尡 Failed to set. return NULL. - [levites] + return -1; + } + + return (start % INSTANCE_MAX_COUNT); + } + + ++start; + + // DWORD Ѱ谪 Ѿ .. ׷.. Ȥó.. - [levites] + if (start > 50000) + { + start = 0; + return -1; + } + } + + return -1; +} + +ISoundInstance * CSoundManager3D::GetInstance(DWORD dwIndex) +{ + if (dwIndex >= INSTANCE_MAX_COUNT) + { + assert(dwIndex < INSTANCE_MAX_COUNT); + return NULL; + } + return &m_Instances[dwIndex]; +} + +__forceinline bool CSoundManager3D::IsValidInstanceIndex(int iIndex) +{ + if (iIndex >= 0 && iIndex < INSTANCE_MAX_COUNT) + return true; + + return false; +} + +void CSoundManager3D::Lock(int iIndex) +{ + if (!IsValidInstanceIndex(iIndex)) + return; + + m_bLockingFlag[iIndex] = true; +} + +void CSoundManager3D::Unlock(int iIndex) +{ + if (!IsValidInstanceIndex(iIndex)) + return; + + m_bLockingFlag[iIndex] = false; +} diff --git a/source/MilesLib/SoundManager3D.h b/source/MilesLib/SoundManager3D.h new file mode 100644 index 0000000..aee9f55 --- /dev/null +++ b/source/MilesLib/SoundManager3D.h @@ -0,0 +1,45 @@ +#ifndef __MILESLIB_CSOUNDMANAGER3D_H__ +#define __MILESLIB_CSOUNDMANAGER3D_H__ + +#include "SoundBase.h" +#include "SoundInstance.h" + +class CSoundManager3D : public CSoundBase +{ + public: + enum + { + INSTANCE_MAX_COUNT = 32, + MAX_PROVIDERS = 32, + }; + + public: + CSoundManager3D(); + virtual ~CSoundManager3D(); + + bool Initialize(); + void Destroy(); + + int GetEmptyInstanceIndex(); + int SetInstance(const char * c_szFileName); + ISoundInstance * GetInstance(DWORD dwIndex); + + void SetListenerDirection(float fxDir, float fyDir, float fzDir, float fxUp, float fyUp, float fzUp); + void SetListenerPosition(float x, float y, float z); + void SetListenerVelocity(float fDistanceX, float fDistanceY, float fDistanceZ, float fNagnitude); + + void Lock(int iIndex); + void Unlock(int iIndex); + + protected: + bool IsValidInstanceIndex(int iIndex); + + protected: + bool m_bLockingFlag[INSTANCE_MAX_COUNT]; + CSoundInstance3D m_Instances[INSTANCE_MAX_COUNT]; + H3DPOBJECT m_pListener; + + bool m_bInit; +}; + +#endif \ No newline at end of file diff --git a/source/MilesLib/SoundManagerStream.cpp b/source/MilesLib/SoundManagerStream.cpp new file mode 100644 index 0000000..c8eb8b4 --- /dev/null +++ b/source/MilesLib/SoundManagerStream.cpp @@ -0,0 +1,64 @@ +#include "stdafx.h" +#include "SoundManagerStream.h" + +CSoundManagerStream::CSoundManagerStream() +{ +} + +CSoundManagerStream::~CSoundManagerStream() +{ +} + +bool CSoundManagerStream::Initialize() +{ + CSoundBase::Initialize(); + + if (ms_DIGDriver) + return true; + + ms_DIGDriver = AIL_open_digital_driver(44100, 16, 2, 0); + + for (int i = 0; i < MUSIC_INSTANCE_MAX_NUM; ++i) + m_Instances[i].Initialize(); + + return true; +} + +void CSoundManagerStream::Destroy() +{ + for (int i=0; i= DWORD(MUSIC_INSTANCE_MAX_NUM)) + return false; + + return true; +} \ No newline at end of file diff --git a/source/MilesLib/SoundManagerStream.h b/source/MilesLib/SoundManagerStream.h new file mode 100644 index 0000000..78deba6 --- /dev/null +++ b/source/MilesLib/SoundManagerStream.h @@ -0,0 +1,32 @@ +#ifndef __MILESLIB_CSOUNDMANAGERSTREAM_H__ +#define __MILESLIB_CSOUNDMANAGERSTREAM_H__ + +#include "SoundBase.h" +#include "SoundInstance.h" + +class CSoundManagerStream : public CSoundBase +{ + public: + enum + { + MUSIC_INSTANCE_MAX_NUM = 3, + }; + + public: + CSoundManagerStream(); + virtual ~CSoundManagerStream(); + + bool Initialize(); + void Destroy(); + + bool SetInstance(DWORD dwIndex, const char* filename); + CSoundInstanceStream * GetInstance(DWORD dwIndex); + + protected: + bool CheckInstanceIndex(DWORD dwIndex); + + protected: + CSoundInstanceStream m_Instances[MUSIC_INSTANCE_MAX_NUM]; +}; + +#endif \ No newline at end of file diff --git a/source/MilesLib/Stdafx.cpp b/source/MilesLib/Stdafx.cpp new file mode 100644 index 0000000..804d088 --- /dev/null +++ b/source/MilesLib/Stdafx.cpp @@ -0,0 +1,2 @@ +#include "stdafx.h" + diff --git a/source/MilesLib/Stdafx.h b/source/MilesLib/Stdafx.h new file mode 100644 index 0000000..a143c16 --- /dev/null +++ b/source/MilesLib/Stdafx.h @@ -0,0 +1,35 @@ +#ifndef __INC_MILESLIB_STDAFX_H__ +#define __INC_MILESLIB_STDAFX_H__ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#pragma warning(disable:4786) +#pragma warning(disable:4100) + +#pragma warning(disable:4201) +#pragma warning(default:4201) +#include + +//#include + +#include "../eterBase/CRC32.h" +#include "../eterBase/Utils.h" +#include "../eterBase/Debug.h" + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +// Armadillo nanomite protection +#ifndef NANOBEGIN + #ifdef __BORLANDC__ + #define NANOBEGIN __emit__ (0xEB,0x03,0xD6,0xD7,0x01) + #define NANOEND __emit__ (0xEB,0x03,0xD6,0xD7,0x00) + #else + #define NANOBEGIN __asm _emit 0xEB __asm _emit 0x03 __asm _emit 0xD6 __asm _emit 0xD7 __asm _emit 0x01 + #define NANOEND __asm _emit 0xEB __asm _emit 0x03 __asm _emit 0xD6 __asm _emit 0xD7 __asm _emit 0x00 + #endif +#endif + +#endif \ No newline at end of file diff --git a/source/MilesLib/Type.cpp b/source/MilesLib/Type.cpp new file mode 100644 index 0000000..6456cd2 --- /dev/null +++ b/source/MilesLib/Type.cpp @@ -0,0 +1,136 @@ +#include "StdAfx.h" +#include "Type.h" +#include "../EterLib/TextFileLoader.h" + +std::string NSound::strResult; + +const char * NSound::GetResultString() +{ + return strResult.c_str(); +} + +void NSound::SetResultString(const char * c_pszStr) +{ + strResult.assign(c_pszStr); +} + +bool NSound::LoadSoundInformationPiece(const char * c_szFileName, NSound::TSoundDataVector & rSoundDataVector, const char * c_szPathHeader) +{ + std::string strResult; + strResult = c_szFileName; + + CTextFileLoader* pkTextFileLoader=CTextFileLoader::Cache(c_szFileName); + if (!pkTextFileLoader) + return false; + + CTextFileLoader& rkTextFileLoader=*pkTextFileLoader; + if (rkTextFileLoader.IsEmpty()) + { + SetResultString((strResult + " б ").c_str()); + return false; + } + + rkTextFileLoader.SetTop(); + + int iCount; + if (!rkTextFileLoader.GetTokenInteger("sounddatacount", &iCount)) + { + SetResultString((strResult + " , SoundDataCount ã ").c_str()); + return false; + } + + rSoundDataVector.clear(); + rSoundDataVector.resize(iCount); + + char szSoundDataHeader[32+1]; + for (DWORD i = 0; i < rSoundDataVector.size(); ++i) + { + _snprintf(szSoundDataHeader, sizeof(szSoundDataHeader), "sounddata%02d", i); + CTokenVector * pTokenVector; + if (!rkTextFileLoader.GetTokenVector(szSoundDataHeader, &pTokenVector)) + { + SetResultString((strResult + " : " + szSoundDataHeader + " ã ").c_str()); + return false; + } + + if (2 != pTokenVector->size()) + { + SetResultString((strResult + " : ũⰡ 2 ƴ").c_str()); + return false; + } + + rSoundDataVector[i].fTime = (float) atof(pTokenVector->at(0).c_str()); + if (c_szPathHeader) + { + rSoundDataVector[i].strSoundFileName = c_szPathHeader; + rSoundDataVector[i].strSoundFileName += pTokenVector->at(1).c_str(); + } + else + { + rSoundDataVector[i].strSoundFileName = pTokenVector->at(1).c_str(); + } + } + + SetResultString((strResult + " ҷ").c_str()); + return true; +} + +bool NSound::SaveSoundInformationPiece(const char * c_szFileName, NSound::TSoundDataVector & rSoundDataVector) +{ + if (rSoundDataVector.empty()) // Ͱ + { + if (IsFile(c_szFileName)) // ʹ ִµ ִٸ + { + _unlink(c_szFileName); // . + } + return true; + } + + std::string strResult; + strResult = c_szFileName; + + FILE * File = fopen(c_szFileName, "wt"); + + if (!File) + { + char szErrorText[256+1]; + _snprintf(szErrorText, sizeof(szErrorText), "Failed to save file (%s).\nPlease check if it is read-only or you have no space on the disk.\n", c_szFileName); + LogBox(szErrorText, ""); + SetResultString((strResult + " ").c_str()); + return false; + } + + fprintf(File, "ScriptType CharacterSoundInformation\n"); + fprintf(File, "\n"); + + fprintf(File, "SoundDataCount %d\n", rSoundDataVector.size()); + + for (DWORD i = 0; i < rSoundDataVector.size(); ++i) + { + NSound::TSoundData & rSoundData = rSoundDataVector[i]; + fprintf(File, "SoundData%02d %f \"%s\"\n", i, rSoundData.fTime, rSoundData.strSoundFileName.c_str()); + } + + fclose(File); + return true; +} + +void NSound::DataToInstance(const TSoundDataVector & c_rSoundDataVector, TSoundInstanceVector * pSoundInstanceVector) +{ + if (c_rSoundDataVector.empty()) + return; + + DWORD dwFPS = 60; + const float c_fFrameTime = 1.0f / float(dwFPS); + + pSoundInstanceVector->clear(); + pSoundInstanceVector->resize(c_rSoundDataVector.size()); + for (DWORD i = 0; i < c_rSoundDataVector.size(); ++i) + { + const TSoundData & c_rSoundData = c_rSoundDataVector[i]; + TSoundInstance & rSoundInstance = pSoundInstanceVector->at(i); + + rSoundInstance.dwFrame = (DWORD) (c_rSoundData.fTime / c_fFrameTime); + rSoundInstance.strSoundFileName = c_rSoundData.strSoundFileName; + } +} \ No newline at end of file diff --git a/source/MilesLib/Type.h b/source/MilesLib/Type.h new file mode 100644 index 0000000..7b7bba1 --- /dev/null +++ b/source/MilesLib/Type.h @@ -0,0 +1,28 @@ +#pragma once + +#include + +namespace NSound +{ + extern std::string strResult; + + typedef struct SSoundData + { + float fTime; + std::string strSoundFileName; + } TSoundData; + typedef struct SSoundInstance + { + DWORD dwFrame; + std::string strSoundFileName; + } TSoundInstance; + typedef std::vector TSoundDataVector; + typedef std::vector TSoundInstanceVector; + + bool LoadSoundInformationPiece(const char * c_szFileName, TSoundDataVector & rSoundDataVector, const char * c_szPathHeader = NULL); + bool SaveSoundInformationPiece(const char * c_szFileName, TSoundDataVector & rSoundDataVector); + void DataToInstance(const TSoundDataVector & c_rSoundDataVector, TSoundInstanceVector * pSoundInstanceVector); + + const char * GetResultString(); + void SetResultString(const char * c_pszStr); +}; diff --git a/source/PRTerrainLib/StdAfx.cpp b/source/PRTerrainLib/StdAfx.cpp new file mode 100644 index 0000000..dd3348d --- /dev/null +++ b/source/PRTerrainLib/StdAfx.cpp @@ -0,0 +1,10 @@ +// stdafx.cpp : source file that includes just the standard includes +// PRTerrainLib.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +/* Fast Float<->Integer conversion */ +float PR_FCNV; +long PR_ICNV; + diff --git a/source/PRTerrainLib/StdAfx.h b/source/PRTerrainLib/StdAfx.h new file mode 100644 index 0000000..bdc2032 --- /dev/null +++ b/source/PRTerrainLib/StdAfx.h @@ -0,0 +1,31 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__EECC0C4D_07A5_4D9E_B40F_767A80FD6DE6__INCLUDED_) +#define AFX_STDAFX_H__EECC0C4D_07A5_4D9E_B40F_767A80FD6DE6__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +// TODO: reference additional headers your program requires here +#pragma warning(disable:4702) + +//#include + +#include "../EterLib/StdAfx.h" +#include "../EterGrnLib/StdAfx.h" +#include "../scriptLib/StdAfx.h" + +/* Fast Float<->Integer conversion */ +extern float PR_FCNV; +extern long PR_ICNV; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__EECC0C4D_07A5_4D9E_B40F_767A80FD6DE6__INCLUDED_) diff --git a/source/PRTerrainLib/Terrain.cpp b/source/PRTerrainLib/Terrain.cpp new file mode 100644 index 0000000..c4812b8 --- /dev/null +++ b/source/PRTerrainLib/Terrain.cpp @@ -0,0 +1,324 @@ +#include "Stdafx.h" +#include "../eterPack/EterPackManager.h" + +#include "terrain.h" +#include + +////////////////////////////////////////////////////////////////////////// +// Texture Set +////////////////////////////////////////////////////////////////////////// +CTextureSet * CTerrainImpl::ms_pTextureSet = NULL; + +void CTerrainImpl::SetTextureSet(CTextureSet * pTextureSet) +{ + static CTextureSet s_EmptyTextureSet; + + if (!pTextureSet) + ms_pTextureSet = &s_EmptyTextureSet; + else + ms_pTextureSet = pTextureSet; +} + +CTextureSet * CTerrainImpl::GetTextureSet() +{ + if (!ms_pTextureSet) + SetTextureSet(NULL); + + return ms_pTextureSet; +} + +CTerrainImpl::CTerrainImpl() +{ + Initialize(); +} + +CTerrainImpl::~CTerrainImpl() +{ + Clear(); +} + +void CTerrainImpl::Initialize() +{ + memset(m_lWaterHeight, -1, sizeof(m_lWaterHeight)); + + m_byNumWater = 0; + memset(&m_HeightMapHeader, 0, sizeof(TGA_HEADER)); + memset(&m_awShadowMap, 0xFFFF, sizeof(m_awShadowMap)); + memset(&m_lpAlphaTexture, NULL, sizeof(m_lpAlphaTexture)); + + m_lViewRadius = 0; + + m_wTileMapVersion = 8976; + + m_fHeightScale = 0.0f; + + m_lpShadowTexture = NULL; + + m_lSplatTilesX = 0; + m_lSplatTilesY = 0; +} + +void CTerrainImpl::Clear() +{ + for (DWORD i = 0; i < GetTextureSet()->GetTextureCount(); ++i) + { + if (m_lpAlphaTexture[i]) + { + m_lpAlphaTexture[i]->Release(); + m_lpAlphaTexture[i] = NULL; + } + } + + Initialize(); +} + +bool CTerrainImpl::LoadHeightMap(const char*c_szFileName) +{ + Tracef("LoadRawHeightMapFile %s ", c_szFileName); + + CMappedFile kMappedFile; + LPCVOID lpcvFileData; + + if (!CEterPackManager::Instance().Get(kMappedFile, c_szFileName, &lpcvFileData)) + { + Tracen("Error"); + TraceError("CTerrainImpl::LoadHeightMap - %s OPEN ERROR", c_szFileName); + return false; + } + + memcpy(m_awRawHeightMap, lpcvFileData, sizeof(WORD)*HEIGHTMAP_RAW_XSIZE*HEIGHTMAP_RAW_YSIZE); + + return true; +} + +bool CTerrainImpl::LoadAttrMap(const char *c_szFileName) +{ + DWORD dwStart = ELTimer_GetMSec(); + Tracef("LoadAttrMapFile %s ", c_szFileName); + + CMappedFile kMappedFile; + LPCVOID lpcvFileData; + + if (!CEterPackManager::Instance().Get(kMappedFile, c_szFileName, &lpcvFileData)) + { + TraceError("CTerrainImpl::LoadAttrMap - %s OPEN ERROR", c_szFileName); + return false; + } + + DWORD dwFileSize = kMappedFile.Size(); + BYTE * abFileData = (BYTE *) lpcvFileData; + + // LoadAttrMap + { +#pragma pack(push) +#pragma pack(1) + struct SAttrMapHeader + { + WORD m_wMagic; + WORD m_wWidth; + WORD m_wHeight; + }; +#pragma pack(pop) + + if (dwFileSize < sizeof(SAttrMapHeader)) + { + TraceError(" CTerrainImpl::LoadAttrMap - %s FILE SIZE ERROR", c_szFileName); + return false; + } + + SAttrMapHeader kAttrMapHeader; + memcpy(&kAttrMapHeader, abFileData, sizeof(kAttrMapHeader)); + + const WORD c_wAttrMapMagic = 2634; + if (c_wAttrMapMagic != kAttrMapHeader.m_wMagic) + { + TraceError("CTerrainImpl::LoadAttrMap - %s MAGIC NUMBER(%d!=MAGIC[%d]) ERROR", c_szFileName, kAttrMapHeader.m_wMagic, kAttrMapHeader.m_wMagic); + return false; + } + + if (ATTRMAP_XSIZE != kAttrMapHeader.m_wWidth) + { + TraceError("CTerrainImpl::LoadAttrMap - kAttrMapHeader(%s).m_width(%d)!=ATTRMAP_XSIZE(%d)", c_szFileName, kAttrMapHeader.m_wWidth, ATTRMAP_XSIZE); + return false; + } + + if (ATTRMAP_YSIZE != kAttrMapHeader.m_wHeight) + { + TraceError("CTerrainImpl::LoadAttrMap - kAttrMapHeader(%s).m_height(%d)!=ATTRMAP_YSIZE(%d)", c_szFileName, kAttrMapHeader.m_wHeight, ATTRMAP_YSIZE); + return false; + } + + DWORD dwFileRestSize=dwFileSize-sizeof(kAttrMapHeader); + DWORD dwFileNeedSize=sizeof(m_abyAttrMap); + if (dwFileRestSize != dwFileNeedSize) + { + TraceError("CTerrainImpl::LoadAttrMap - %s FILE DATA SIZE(rest %d != need %d) ERROR", c_szFileName, dwFileRestSize, dwFileNeedSize); + return false; + } + + BYTE* abSrcAttrData= abFileData+sizeof(kAttrMapHeader); + memcpy(m_abyAttrMap, abSrcAttrData, sizeof(m_abyAttrMap)); + } + + Tracef("%d\n", ELTimer_GetMSec() - dwStart); + return true; +} + +bool CTerrainImpl::RAW_LoadTileMap(const char * c_szFileName) +{ + Tracef("LoadSplatFile %s ", c_szFileName); + + CMappedFile kMappedFile; + LPCVOID lpcvFileData; + + if (!CEterPackManager::Instance().Get(kMappedFile, c_szFileName, &lpcvFileData)) + { + Tracen("Error"); + TraceError("CTerrainImpl::RAW_LoadTileMap - %s OPEN ERROR", c_szFileName); + return false; + } + + memcpy(m_abyTileMap, lpcvFileData, sizeof(BYTE)*(TILEMAP_RAW_XSIZE)*(TILEMAP_RAW_YSIZE)); + + return true; + +} + +bool CTerrainImpl::LoadWaterMap(const char * c_szFileName) +{ + DWORD dwStart = ELTimer_GetMSec(); + + if (!LoadWaterMapFile(c_szFileName)) + { + memset(m_abyWaterMap, 0xFF, sizeof(m_abyWaterMap)); + + m_byNumWater = 0; + memset(m_lWaterHeight, -1, sizeof(m_lWaterHeight)); + + TraceError("CMapOutdoor::LoadWaterMap LoadWaterMapFile(%s) Failed", c_szFileName); + + return false; + } + + Tracef("LoadWaterMapFile %s %d\n", c_szFileName, ELTimer_GetMSec() - dwStart); + return true; +} + +bool CTerrainImpl::LoadWaterMapFile(const char * c_szFileName) +{ + CMappedFile kMappedFile; + LPCVOID lpcvFileData; + + if (!CEterPackManager::Instance().Get(kMappedFile, c_szFileName, &lpcvFileData)) + { + Tracen("Error"); + TraceError("CTerrainImpl::LoadWaterMap - %s OPEN ERROR", c_szFileName); + return false; + } + + DWORD dwFileSize = kMappedFile.Size(); + BYTE* abFileData = (BYTE*)lpcvFileData; + + { +#pragma pack(push) +#pragma pack(1) + struct SWaterMapHeader + { + WORD m_wMagic; + WORD m_wWidth; + WORD m_wHeight; + BYTE m_byLayerCount; + }; +#pragma pack(pop) + + if (dwFileSize < sizeof(SWaterMapHeader)) + { + TraceError("CTerrainImpl::LoadWaterMap - %s FILE SIZE ERROR", c_szFileName); + return false; + } + + SWaterMapHeader kWaterMapHeader; + memcpy(&kWaterMapHeader, abFileData, sizeof(kWaterMapHeader)); + + const WORD c_wWaterMapMagic = 5426; + + if (c_wWaterMapMagic != kWaterMapHeader.m_wMagic) + { + TraceError("CTerrainImpl::LoadWaterMap - %s MAGIC NUMBER(%d!=MAGIC[%d]) ERROR", c_szFileName, kWaterMapHeader.m_wMagic, c_wWaterMapMagic); + return false; + } + + if (WATERMAP_XSIZE != kWaterMapHeader.m_wWidth) + { + TraceError("CTerrainImpl::LoadWaterMap - kWaterMapHeader(%s).m_width(%d)!=WATERMAP_XSIZE(%d)", c_szFileName, kWaterMapHeader.m_wWidth, WATERMAP_XSIZE); + return false; + } + + if (WATERMAP_YSIZE != kWaterMapHeader.m_wHeight) + { + TraceError("CTerrainImpl::LoadWaterMap - kWaterMapHeader(%s).m_height(%d)!=WATERMAP_YSIZE(%d)", c_szFileName, kWaterMapHeader.m_wHeight, WATERMAP_YSIZE); + return false; + } + + m_byNumWater = kWaterMapHeader.m_byLayerCount; + + DWORD dwFileRestSize = dwFileSize - sizeof(kWaterMapHeader); + DWORD dwFileNeedSize = sizeof(m_abyWaterMap) + sizeof(long) * m_byNumWater; + DWORD dwFileNeedSize2 = sizeof(m_abyWaterMap) + sizeof(WORD) * m_byNumWater; + if (dwFileRestSize == dwFileNeedSize2) + { + WORD wWaterHeight[MAX_WATER_NUM + 1]; + + BYTE * abSrcWaterData = abFileData + sizeof(kWaterMapHeader); + memcpy(m_abyWaterMap, abSrcWaterData, sizeof(m_abyWaterMap)); + + BYTE * abSrcWaterHeight = abSrcWaterData + sizeof(m_abyWaterMap); + + m_byNumWater = MIN(MAX_WATER_NUM, m_byNumWater); + if (m_byNumWater) + { + memcpy(wWaterHeight, abSrcWaterHeight, sizeof(WORD) * m_byNumWater); + + for (int i = 0; i < m_byNumWater; ++i) + m_lWaterHeight[i] = wWaterHeight[i]; + } + } + else if (dwFileRestSize != dwFileNeedSize) + { + TraceError("CTerrainImpl::LoadWaterMap - %s FILE DATA SIZE(rest %d != need %d) ERROR", c_szFileName, dwFileRestSize, dwFileNeedSize); + return false; + } + + BYTE * abSrcWaterData = abFileData + sizeof(kWaterMapHeader); + memcpy(m_abyWaterMap, abSrcWaterData, sizeof(m_abyWaterMap)); + + BYTE * abSrcWaterHeight = abSrcWaterData + sizeof(m_abyWaterMap); + + if (m_byNumWater) + memcpy(m_lWaterHeight, abSrcWaterHeight, sizeof(long) * m_byNumWater); + } + + return true; +} + +DWORD CTerrainImpl::GetShadowMapColor(float fx, float fy) +{ + float fMapSize = (float)(TERRAIN_XSIZE); + float fooMapSize = 1.0f / fMapSize; + if (fx < 0 || fy < 0 || fx >= fMapSize || fy >= fMapSize) + return 0xFFFFFFFF; + + fx = fx * fooMapSize * (float)(SHADOWMAP_XSIZE - 1); + fy = fy * fooMapSize * (float)(SHADOWMAP_YSIZE - 1); + int ix, iy; + PR_FLOAT_TO_INT(fx, ix); + PR_FLOAT_TO_INT(fy, iy); + + WORD w = *(m_awShadowMap + (iy * SHADOWMAP_XSIZE) + ix); + + int b = w & 0x1f; w >>= 5; b <<= 3; + int g = w & 0x1f; w >>= 5; g <<= 3; + int r = w & 0x1f; r <<= 3; + + return (DWORD) (0xff << 24) | (g << 16) | (g << 8) | r; +} diff --git a/source/PRTerrainLib/Terrain.h b/source/PRTerrainLib/Terrain.h new file mode 100644 index 0000000..fdaeb6a --- /dev/null +++ b/source/PRTerrainLib/Terrain.h @@ -0,0 +1,156 @@ +// Terrain.h: interface for the CTerrainImpl class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_TERRAIN_H__1C9108E1_69A7_4392_9B68_0E6CD4E1BFBA__INCLUDED_) +#define AFX_TERRAIN_H__1C9108E1_69A7_4392_9B68_0E6CD4E1BFBA__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "../eterImageLib/TGAImage.h" + +#include "TextureSet.h" +#include "TerrainType.h" + +class CTerrainImpl +{ + public: + enum + { + XSIZE = TERRAIN_SIZE, + YSIZE = TERRAIN_SIZE, + HEIGHTMAP_XSIZE = XSIZE+1, + HEIGHTMAP_YSIZE = YSIZE+1, + HEIGHTMAP_RAW_XSIZE = XSIZE+3, + HEIGHTMAP_RAW_YSIZE = YSIZE+3, + ATTRMAP_XSIZE = XSIZE*2, + ATTRMAP_YSIZE = YSIZE*2, + ATTRMAP_ZCOUNT = 8, + TILEMAP_XSIZE = XSIZE*2, + TILEMAP_YSIZE = YSIZE*2, + TILEMAP_RAW_XSIZE = XSIZE*2+2, + TILEMAP_RAW_YSIZE = YSIZE*2+2, + WATERMAP_XSIZE = XSIZE, + WATERMAP_YSIZE = YSIZE, + NORMALMAP_XSIZE = XSIZE+1, + NORMALMAP_YSIZE = YSIZE+1, + SHADOWMAP_XSIZE = XSIZE*2, + SHADOWMAP_YSIZE = YSIZE*2, + SPLATALPHA_RAW_XSIZE = XSIZE*2+2, + SPLATALPHA_RAW_YSIZE = YSIZE*2+2, + SPLATALPHA_ZCOUNT = 7, + HEIGHT_TILE_XRATIO = TILEMAP_XSIZE / XSIZE, + HEIGHT_TILE_YRATIO = TILEMAP_XSIZE / XSIZE, + + PATCH_XSIZE = TERRAIN_PATCHSIZE, + PATCH_YSIZE = TERRAIN_PATCHSIZE, + PATCH_TILE_XSIZE = PATCH_XSIZE * HEIGHT_TILE_XRATIO, + PATCH_TILE_YSIZE = PATCH_YSIZE * HEIGHT_TILE_YRATIO, + PATCH_XCOUNT = TERRAIN_PATCHCOUNT, + PATCH_YCOUNT = TERRAIN_PATCHCOUNT, + + CELLSCALE = 200, + CELLSCALE_IN_METER = CELLSCALE / 100, + HALF_CELLSCALE = CELLSCALE / 2, + HALF_CELLSCALE_IN_METER = HALF_CELLSCALE / 100, + TERRAIN_XSIZE = XSIZE * CELLSCALE, + TERRAIN_YSIZE = YSIZE * CELLSCALE, + }; + + enum + { + MAX_ATTRIBUTE_NUM = 8, + MAX_WATER_NUM = 255, + }; + + enum + { + ATTRIBUTE_BLOCK = (1 << 0), + ATTRIBUTE_WATER = (1 << 1), + ATTRIBUTE_BANPK = (1 << 2), + }; + + public: + static void SetTextureSet(CTextureSet * pTextureSet); + static CTextureSet * GetTextureSet(); // ؾ + + protected: + static CTextureSet * ms_pTextureSet; + + public: + CTerrainImpl(); + virtual ~CTerrainImpl(); + + TTerrainSplatPatch & GetTerrainSplatPatch() {return m_TerrainSplatPatch;} + DWORD GetNumTextures() { return ms_pTextureSet->GetTextureCount(); } + TTerrainTexture & GetTexture(const long & c_rlTextureNum) { return ms_pTextureSet->GetTexture(c_rlTextureNum); } +// int GetHeightTileMapRatio() { return m_iHeightTileRatio; } + + bool LoadWaterMap(const char * c_szWaterMapName); + bool LoadWaterMapFile(const char * c_szWaterMapName); + + LPDIRECT3DTEXTURE8 GetShadowTexture() { return m_lpShadowTexture; } + + DWORD GetShadowMapColor(float fx, float fy); + + protected: + void Initialize(); + virtual void Clear(); + + void LoadTextures(); + bool LoadHeightMap(const char *c_szFileName); + bool RAW_LoadTileMap(const char * c_szFileName); + bool LoadAttrMap(const char *c_pszFileName); +#ifdef WORLD_EDITOR + public: +#endif + __forceinline WORD GetHeightMapValue(short sx, short sy); + + protected: + LPDIRECT3DTEXTURE8 m_lpAlphaTexture[MAXTERRAINTEXTURES]; + WORD m_awRawHeightMap[HEIGHTMAP_RAW_YSIZE*HEIGHTMAP_RAW_XSIZE]; + + BYTE m_abyTileMap[TILEMAP_RAW_YSIZE*TILEMAP_RAW_XSIZE]; + BYTE m_abyAttrMap[ATTRMAP_YSIZE*ATTRMAP_XSIZE]; + BYTE m_abyWaterMap[WATERMAP_YSIZE*WATERMAP_XSIZE]; + CHAR m_acNormalMap[NORMALMAP_YSIZE*NORMALMAP_XSIZE*3]; + + TGA_HEADER m_HeightMapHeader; + + WORD m_wTileMapVersion; + + long m_lViewRadius; + float m_fHeightScale; + + TTerrainSplatPatch m_TerrainSplatPatch; + + ////////////////////////////////////////////////////////////////////////// + //Water Map + BYTE m_byNumWater; + long m_lWaterHeight[MAX_WATER_NUM + 1]; + //Water Map + ////////////////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////////// + // TileMap HeightMap +// int m_iHeightTileRatio; + + ////////////////////////////////////////////////////////////////////////// + // Shadow Map + LPDIRECT3DTEXTURE8 m_lpShadowTexture; + WORD m_awShadowMap[SHADOWMAP_YSIZE*SHADOWMAP_XSIZE]; // 16bit R5 G6 B5 + + protected: + long m_lSplatTilesX; + long m_lSplatTilesY; +}; + + +__forceinline WORD CTerrainImpl::GetHeightMapValue(short sx, short sy) +{ + return m_awRawHeightMap[(sy+1) * HEIGHTMAP_RAW_XSIZE + sx+1]; +} + +#endif // !defined(AFX_TERRAIN_H__1C9108E1_69A7_4392_9B68_0E6CD4E1BFBA__INCLUDED_) diff --git a/source/PRTerrainLib/TerrainType.h b/source/PRTerrainLib/TerrainType.h new file mode 100644 index 0000000..50f6213 --- /dev/null +++ b/source/PRTerrainLib/TerrainType.h @@ -0,0 +1,95 @@ +#ifndef __TERRAIn_TYPES__ +#define __TERRAIn_TYPES__ + +#include "../eterlib/GrpVertexBuffer.h" +#include "../eterlib/GrpIndexBuffer.h" + +#define TERRAIN_PATCHSIZE 16 +#define TERRAIN_SIZE 128 +#define TERRAIN_PATCHCOUNT TERRAIN_SIZE/TERRAIN_PATCHSIZE +#define MAXTERRAINTEXTURES 256 + +typedef struct +{ + long Active; + long NeedsUpdate; + LPDIRECT3DTEXTURE8 pd3dTexture; +} TTerainSplat; + +typedef struct +{ + DWORD TileCount[MAXTERRAINTEXTURES]; + DWORD PatchTileCount[TERRAIN_PATCHCOUNT*TERRAIN_PATCHCOUNT][MAXTERRAINTEXTURES]; + TTerainSplat Splats[MAXTERRAINTEXTURES]; + bool m_bNeedsUpdate; +} TTerrainSplatPatch; + +typedef struct +{ + char used; + short mat; + + CGraphicVertexBuffer vb; + CGraphicIndexBuffer ib; + long VertexSize; + + short NumIndices; + + float minx, maxx; + float miny, maxy; + float minz, maxz; +} TERRAIN_VBUFFER; + +typedef struct +{ + char name[19]; + float ambi_r, ambi_g, ambi_b, ambi_a; /* Ambient Color */ + float diff_r, diff_g, diff_b, diff_a; /* Diffuse Color */ + float spec_r, spec_g, spec_b, spec_a; /* Specular Color */ + float spec_power; /* Specular power */ +} PR_MATERIAL; + +typedef struct +{ + /* Public Settings */ + float PageUVLength; + long SquaresPerTexture; /* Heightfield squares per texture (128 texels) */ + long SplatTilesX; /* Number of splat textures across map */ + long SplatTilesY; /* Number of splat textures down map */ + long DisableWrapping; + long DisableShadow; + long ShadowMode; + long OutsideVisible; + D3DXVECTOR3 SunLocation; +} TTerrainGlobals; + +/* Converts a floating point number to an integer by truncation, using + the FISTP instruction */ +#define PR_FLOAT_TO_INTASM __asm \ +{ \ + __asm fld PR_FCNV \ + __asm fistp PR_ICNV \ +} + +#define PR_FLOAT_TO_FIXED(inreal, outint) \ +{ \ + PR_FCNV = (inreal) * 65536.0f; \ + PR_FLOAT_TO_INTASM; \ + (outint) = PR_ICNV; \ +} + +#define PR_FLOAT_TO_INT(inreal, outint) \ +{ \ + PR_FCNV = (inreal); \ + PR_FLOAT_TO_INTASM; \ + (outint) = PR_ICNV > PR_FCNV ? PR_ICNV - 1 : PR_ICNV; \ +} + +#define PR_FLOAT_ADD_TO_INT(inreal, outint) \ +{ \ + PR_FCNV = (inreal); \ + PR_FLOAT_TO_INTASM; \ + (outint) += PR_ICNV; \ +} + +#endif //__TERRAIn_TYPES__ \ No newline at end of file diff --git a/source/PRTerrainLib/TextureSet.cpp b/source/PRTerrainLib/TextureSet.cpp new file mode 100644 index 0000000..a429d86 --- /dev/null +++ b/source/PRTerrainLib/TextureSet.cpp @@ -0,0 +1,275 @@ +#include "StdAfx.h" +#include "TextureSet.h" + +CTextureSet::CTextureSet() +{ + Initialize(); +} + +CTextureSet::~CTextureSet() +{ + Clear(); +} + +void CTextureSet::Initialize() +{ +} + +void CTextureSet::Create() +{ + CResource * pResource = CResourceManager::Instance().GetResourcePointer("d:/ymir work/special/error.tga"); + m_ErrorTexture.ImageInstance.SetImagePointer(static_cast (pResource)); + AddEmptyTexture(); // 찳 ؽ縦 ó ߰ ؾ +} + +bool CTextureSet::Load(const char * c_szTextureSetFileName, float fTerrainTexCoordBase) +{ + NANOBEGIN + Clear(); + + CTokenVectorMap stTokenVectorMap; + + if (!LoadMultipleTextData(c_szTextureSetFileName, stTokenVectorMap)) + { + TraceError("TextureSet::Load : cannot load %s", c_szTextureSetFileName); + return false; + } + + if (stTokenVectorMap.end() == stTokenVectorMap.find("textureset")) + { + TraceError("TextureSet::Load : syntax error, TextureSet (filename: %s)", c_szTextureSetFileName); + return false; + } + + if (stTokenVectorMap.end() == stTokenVectorMap.find("texturecount")) + { + TraceError("TextureSet::Load : syntax error, TextureCount (filename: %s)", c_szTextureSetFileName); + return false; + } + + Create(); + + const std::string & c_rstrCount = stTokenVectorMap["texturecount"][0]; + + long lCount = atol(c_rstrCount.c_str()); + char szTextureName[32 + 1]; + + m_Textures.resize(lCount + 1); + + for (long i = 0; i < lCount; ++i) + { + _snprintf(szTextureName, sizeof(szTextureName), "texture%03d", i + 1); + + if (stTokenVectorMap.end() == stTokenVectorMap.find(szTextureName)) + continue; + + const CTokenVector & rVector = stTokenVectorMap[szTextureName]; + + const std::string & c_rstrFileName = rVector[0].c_str(); + const std::string & c_rstrUScale = rVector[1].c_str(); + const std::string & c_rstrVScale = rVector[2].c_str(); + const std::string & c_rstrUOffset = rVector[3].c_str(); + const std::string & c_rstrVOffset = rVector[4].c_str(); + const std::string & c_rstrbSplat = rVector[5].c_str(); + const std::string & c_rstrBegin = rVector[6].c_str(); + const std::string & c_rstrEnd = rVector[7].c_str(); + + float fuScale, fvScale, fuOffset, fvOffset; + bool bSplat; + unsigned short usBegin, usEnd; + + fuScale = atof(c_rstrUScale.c_str()); + fvScale = atof(c_rstrVScale.c_str()); + fuOffset = atof(c_rstrUOffset.c_str()); + fvOffset = atof(c_rstrVOffset.c_str()); + bSplat = 0 != atoi(c_rstrbSplat.c_str()); + usBegin = static_cast(atoi(c_rstrBegin.c_str())); + usEnd = static_cast(atoi(c_rstrEnd.c_str())); + + if (!SetTexture(i + 1, c_rstrFileName.c_str(), fuScale, fvScale, fuOffset, fvOffset, bSplat, usBegin, usEnd, fTerrainTexCoordBase)) + TraceError("CTextureSet::Load : SetTexture failed : Filename: %s", c_rstrFileName.c_str()); + } + + m_stFileName.assign(c_szTextureSetFileName); + NANOEND + return true; +} + +void CTextureSet::Clear() +{ + m_ErrorTexture.ImageInstance.Destroy(); + m_Textures.clear(); + Initialize(); +} + +void CTextureSet::AddEmptyTexture() +{ + TTerrainTexture eraser; + m_Textures.push_back(eraser); +} + +unsigned long CTextureSet::GetTextureCount() +{ + return m_Textures.size(); +} + +TTerrainTexture & CTextureSet::GetTexture(unsigned long ulIndex) +{ + if (GetTextureCount() <= ulIndex) + return m_ErrorTexture; + + return m_Textures[ulIndex]; +} + +bool CTextureSet::SetTexture(unsigned long ulIndex, + const char * c_szFileName, + float fuScale, + float fvScale, + float fuOffset, + float fvOffset, + bool bSplat, + unsigned short usBegin, + unsigned short usEnd, + float fTerrainTexCoordBase) +{ + + if (ulIndex >= m_Textures.size()) + { + TraceError("CTextureSet::SetTexture : Index Error : Index(%d) is Larger than TextureSet Size(%d)", ulIndex, m_Textures.size()); + return false; + } + + CResource * pResource = CResourceManager::Instance().GetResourcePointer(c_szFileName); + + if (!pResource->IsType(CGraphicImage::Type())) + { + TraceError("CTerrainImpl::GenerateTexture : %s is NOT Image File", pResource->GetFileName()); + return false; + } + + TTerrainTexture & tex = m_Textures[ulIndex]; + + tex.stFilename = c_szFileName; + tex.UScale = fuScale; + tex.VScale = fvScale; + tex.UOffset = fuOffset; + tex.VOffset = fvOffset; + tex.bSplat = bSplat; + tex.Begin = usBegin; + tex.End = usEnd; + tex.ImageInstance.SetImagePointer(static_cast(pResource)); + tex.pd3dTexture = tex.ImageInstance.GetTexturePointer()->GetD3DTexture(); + + + D3DXMatrixScaling(&tex.m_matTransform, fTerrainTexCoordBase * tex.UScale, -fTerrainTexCoordBase * tex.VScale, 0.0f); + tex.m_matTransform._41 = tex.UOffset; + tex.m_matTransform._42 = -tex.VOffset; + return true; +} + +void CTextureSet::Reload(float fTerrainTexCoordBase) +{ + for (DWORD dwIndex = 1; dwIndex < GetTextureCount(); ++dwIndex) + { + TTerrainTexture & tex = m_Textures[dwIndex]; + + tex.ImageInstance.ReloadImagePointer((CGraphicImage *) CResourceManager::Instance().GetResourcePointer(tex.stFilename.c_str())); + tex.pd3dTexture = tex.ImageInstance.GetTexturePointer()->GetD3DTexture(); + + D3DXMatrixScaling(&tex.m_matTransform, fTerrainTexCoordBase * tex.UScale, -fTerrainTexCoordBase * tex.VScale, 0.0f); + tex.m_matTransform._41 = tex.UOffset; + tex.m_matTransform._42 = -tex.VOffset; + } +} + +bool CTextureSet::AddTexture(const char * c_szFileName, + float fuScale, + float fvScale, + float fuOffset, + float fvOffset, + bool bSplat, + unsigned short usBegin, + unsigned short usEnd, + float fTerrainTexCoordBase) +{ + if (GetTextureCount() >= 256) + { + LogBox("ؽó ̻ ߰ ϴ.", "ִ ؽó 255"); + return false; + } + + for (unsigned long i = 1; i < GetTextureCount(); ++i) + { + if (0 == m_Textures[i].stFilename.compare(c_szFileName)) + { + LogBox(" ̸ ؽó ̹ ֽϴ.", "ߺ"); + return false; + } + } + + CResource * pResource = CResourceManager::Instance().GetResourcePointer(c_szFileName); + + if (!pResource->IsType(CGraphicImage::Type())) + { + LogBox("CTerrainImpl::GenerateTexture : ̹ ƴմϴ. %s", pResource->GetFileName()); + return false; + } + + m_Textures.reserve(m_Textures.size() + 1); + + SetTexture(m_Textures.size() - 1, + c_szFileName, + fuScale, + fvScale, + fuOffset, + fvOffset, + bSplat, + usBegin, + usEnd, + fTerrainTexCoordBase); + + return true; +} + +bool CTextureSet::RemoveTexture(unsigned long ulIndex) +{ + if (GetTextureCount() <= ulIndex) + return false; + + TTextureVector::iterator itor = m_Textures.begin() + ulIndex; + m_Textures.erase(itor); + return true; +} + +bool CTextureSet::Save(const char * c_pszFileName) +{ + FILE * pFile = fopen(c_pszFileName, "w"); + + if (!pFile) + return false; + + fprintf(pFile, "TextureSet\n"); + fprintf(pFile, "\n"); + + fprintf(pFile, "TextureCount %ld\n", GetTextureCount() - 1); // -1 ϴ 찳 + fprintf(pFile, "\n"); + + for (DWORD i = 1; i < GetTextureCount(); ++i) + { + TTerrainTexture & rTex = m_Textures[i]; + + fprintf(pFile, "Start Texture%03d\n", i); + fprintf(pFile, " \"%s\"\n", rTex.stFilename.c_str()); + fprintf(pFile, " %f\n", rTex.UScale); + fprintf(pFile, " %f\n", rTex.VScale); + fprintf(pFile, " %f\n", rTex.UOffset); + fprintf(pFile, " %f\n", rTex.VOffset); + fprintf(pFile, " %d\n", rTex.bSplat); + fprintf(pFile, " %hu\n", rTex.Begin); + fprintf(pFile, " %hu\n", rTex.End); + fprintf(pFile, "End Texture%03d\n", i); + } + + fclose(pFile); + return true; +} diff --git a/source/PRTerrainLib/TextureSet.h b/source/PRTerrainLib/TextureSet.h new file mode 100644 index 0000000..731a79b --- /dev/null +++ b/source/PRTerrainLib/TextureSet.h @@ -0,0 +1,90 @@ +#ifndef __INC_TERRAINLIB_TEXTURESET_H__ +#define __INC_TERRAINLIB_TEXTURESET_H__ + +#include "../eterLib/GrpImageInstance.h" + +typedef struct STerrainTexture +{ + STerrainTexture() : pd3dTexture(NULL), + UScale(4.0f), + VScale(4.0f), + UOffset(0.0f), + VOffset(0.0f), + bSplat(true), + Begin(0), + End(0) + { + } + + ~STerrainTexture() + { + } + + std::string stFilename; + LPDIRECT3DTEXTURE8 pd3dTexture; + CGraphicImageInstance ImageInstance; + float UScale; + float VScale; + float UOffset; + float VOffset; + bool bSplat; + unsigned short Begin, End; // 0 ~ 65535 16bit heightfield ̰. + D3DXMATRIX m_matTransform; +} TTerrainTexture; + +class CTextureSet +{ + public: + typedef std::vector TTextureVector; + + CTextureSet(); + virtual ~CTextureSet(); + + void Initialize(); + void Clear(); + + void Create(); + + bool Load(const char * c_pszFileName, float fTerrainTexCoordBase); + bool Save(const char * c_pszFileName); + + unsigned long GetTextureCount(); + + TTerrainTexture & GetTexture(unsigned long ulIndex); + bool RemoveTexture(unsigned long ulIndex); + + bool SetTexture(unsigned long ulIndex, + const char * c_szFileName, + float fuScale, + float fvScale, + float fuOffset, + float fvOffset, + bool bSplat, + unsigned short usBegin, + unsigned short usEnd, + float fTerrainTexCoordBase); + + void Reload(float fTerrainTexCoordBase); + + bool AddTexture(const char * c_szFileName, + float fuScale, + float fvScale, + float fuOffset, + float fvOffset, + bool bSplat, + unsigned short usBegin, + unsigned short usEnd, + float fTerrainTexCoordBase); + + const char * GetFileName() { return m_stFileName.c_str(); } + + protected: + void AddEmptyTexture(); + + protected: + TTextureVector m_Textures; + TTerrainTexture m_ErrorTexture; + std::string m_stFileName; +}; + +#endif \ No newline at end of file diff --git a/source/ScriptLib/PythonDebugModule.cpp b/source/ScriptLib/PythonDebugModule.cpp new file mode 100644 index 0000000..710981e --- /dev/null +++ b/source/ScriptLib/PythonDebugModule.cpp @@ -0,0 +1,77 @@ +#include "StdAfx.h" + +extern IPythonExceptionSender * g_pkExceptionSender; + +PyObject* dbgLogBox(PyObject* poSelf, PyObject* poArgs) +{ + char* szMsg; + char* szCaption; + if (!PyTuple_GetString(poArgs, 0, &szMsg)) + return Py_BuildException(); + if (!PyTuple_GetString(poArgs, 1, &szCaption)) + { + LogBox(szMsg); + } + else + { + LogBox(szMsg,szCaption); + } + return Py_BuildNone(); +} + +PyObject* dbgTrace(PyObject* poSelf, PyObject* poArgs) +{ + char* szMsg; + if (!PyTuple_GetString(poArgs, 0, &szMsg)) + return Py_BuildException(); + + Trace(szMsg); + return Py_BuildNone(); +} + +PyObject* dbgTracen(PyObject* poSelf, PyObject* poArgs) +{ + char* szMsg; + if (!PyTuple_GetString(poArgs, 0, &szMsg)) + return Py_BuildException(); + + Tracen(szMsg); + return Py_BuildNone(); +} + +PyObject* dbgTraceError(PyObject* poSelf, PyObject* poArgs) +{ + char* szMsg; + if (!PyTuple_GetString(poArgs, 0, &szMsg)) + return Py_BuildException(); + + TraceError( "%s", szMsg ); + return Py_BuildNone(); +} + +PyObject* dbgRegisterExceptionString(PyObject* poSelf, PyObject* poArgs) +{ + char* szMsg; + if (!PyTuple_GetString(poArgs, 0, &szMsg)) + return Py_BuildException(); + + if (g_pkExceptionSender) + g_pkExceptionSender->RegisterExceptionString(szMsg); + + return Py_BuildNone(); +} + +void initdbg() +{ + static PyMethodDef s_methods[] = + { + { "LogBox", dbgLogBox, METH_VARARGS }, + { "Trace", dbgTrace, METH_VARARGS }, + { "Tracen", dbgTracen, METH_VARARGS }, + { "TraceError", dbgTraceError, METH_VARARGS }, + { "RegisterExceptionString", dbgRegisterExceptionString, METH_VARARGS }, + { NULL, NULL}, + }; + + Py_InitModule("dbg", s_methods); +} \ No newline at end of file diff --git a/source/ScriptLib/PythonDebugModule.h b/source/ScriptLib/PythonDebugModule.h new file mode 100644 index 0000000..efd3eba --- /dev/null +++ b/source/ScriptLib/PythonDebugModule.h @@ -0,0 +1,3 @@ +#pragma once + +void initdbg(); diff --git a/source/ScriptLib/PythonLauncher.cpp b/source/ScriptLib/PythonLauncher.cpp new file mode 100644 index 0000000..3c1367f --- /dev/null +++ b/source/ScriptLib/PythonLauncher.cpp @@ -0,0 +1,282 @@ +#include "StdAfx.h" +#include +#include "../eterPack/EterPackManager.h" + +#include "PythonLauncher.h" + +CPythonLauncher::CPythonLauncher() +{ + Py_Initialize(); +} + +CPythonLauncher::~CPythonLauncher() +{ + Clear(); +} + +void CPythonLauncher::Clear() +{ + Py_Finalize(); +} + +std::string g_stTraceBuffer[512]; +int g_nCurTraceN = 0; + +void Traceback() +{ + std::string str; + + for (int i = 0; i < g_nCurTraceN; ++i) + { + str.append(g_stTraceBuffer[i]); + str.append("\n"); + } + + PyObject * exc; + PyObject * v; + PyObject * tb; + const char * errStr; + + PyErr_Fetch(&exc, &v, &tb); + + if (PyString_Check(v)) + { + errStr = PyString_AS_STRING(v); + str.append("Error: "); + str.append(errStr); + + Tracef("%s\n", errStr); + } + Py_DECREF(exc); + Py_DECREF(v); + Py_DECREF(tb); + LogBoxf("Traceback:\n\n%s\n", str.c_str()); +} + +int TraceFunc(PyObject * obj, PyFrameObject * f, int what, PyObject *arg) +{ + const char * funcname; + char szTraceBuffer[128]; + + switch (what) + { + case PyTrace_CALL: + if (g_nCurTraceN >= 512) + return 0; + + if (Py_OptimizeFlag) + f->f_lineno = PyCode_Addr2Line(f->f_code, f->f_lasti); + + funcname = PyString_AsString(f->f_code->co_name); + + _snprintf(szTraceBuffer, sizeof(szTraceBuffer), "Call: File \"%s\", line %d, in %s", + PyString_AsString(f->f_code->co_filename), + f->f_lineno, + funcname); + + g_stTraceBuffer[g_nCurTraceN++]=szTraceBuffer; + break; + + case PyTrace_RETURN: + if (g_nCurTraceN > 0) + --g_nCurTraceN; + break; + + case PyTrace_EXCEPTION: + if (g_nCurTraceN >= 512) + return 0; + + PyObject * exc_type, * exc_value, * exc_traceback; + + PyTuple_GetObject(arg, 0, &exc_type); + PyTuple_GetObject(arg, 1, &exc_value); + PyTuple_GetObject(arg, 2, &exc_traceback); + + int len; + const char * exc_str; + PyObject_AsCharBuffer(exc_type, &exc_str, &len); + + _snprintf(szTraceBuffer, sizeof(szTraceBuffer), "Exception: File \"%s\", line %d, in %s", + PyString_AS_STRING(f->f_code->co_filename), + f->f_lineno, + PyString_AS_STRING(f->f_code->co_name)); + + g_stTraceBuffer[g_nCurTraceN++]=szTraceBuffer; + + break; + } + return 0; +} + +void CPythonLauncher::SetTraceFunc(int (*pFunc)(PyObject * obj, PyFrameObject * f, int what, PyObject *arg)) +{ + PyEval_SetTrace(pFunc, NULL); +} + +bool CPythonLauncher::Create(const char* c_szProgramName) +{ + NANOBEGIN + Py_SetProgramName((char*)c_szProgramName); +#ifdef _DEBUG + PyEval_SetTrace(TraceFunc, NULL); +#endif + m_poModule = PyImport_AddModule((char *) "__main__"); + + if (!m_poModule) + return false; + + m_poDic = PyModule_GetDict(m_poModule); + + PyObject * builtins = PyImport_ImportModule("__builtin__"); + PyModule_AddIntConstant(builtins, "TRUE", 1); + PyModule_AddIntConstant(builtins, "FALSE", 0); + PyDict_SetItemString(m_poDic, "__builtins__", builtins); + Py_DECREF(builtins); + + if (!RunLine("import __main__")) + return false; + + if (!RunLine("import sys")) + return false; + + NANOEND + return true; +} + +bool CPythonLauncher::RunCompiledFile(const char* c_szFileName) +{ + NANOBEGIN + FILE * fp = fopen(c_szFileName, "rb"); + + if (!fp) + return false; + + PyCodeObject *co; + PyObject *v; + long magic; + long PyImport_GetMagicNumber(void); + + magic = _PyMarshal_ReadLongFromFile(fp); + + if (magic != PyImport_GetMagicNumber()) + { + PyErr_SetString(PyExc_RuntimeError, "Bad magic number in .pyc file"); + fclose(fp); + return false; + } + + _PyMarshal_ReadLongFromFile(fp); + v = _PyMarshal_ReadLastObjectFromFile(fp); + + fclose(fp); + + if (!v || !PyCode_Check(v)) + { + Py_XDECREF(v); + PyErr_SetString(PyExc_RuntimeError, "Bad code object in .pyc file"); + return false; + } + + co = (PyCodeObject *) v; + v = PyEval_EvalCode(co, m_poDic, m_poDic); +/* if (v && flags) + flags->cf_flags |= (co->co_flags & PyCF_MASK);*/ + Py_DECREF(co); + if (!v) + { + Traceback(); + return false; + } + + Py_DECREF(v); + if (Py_FlushLine()) + PyErr_Clear(); + + NANOEND + return true; +} + + +bool CPythonLauncher::RunMemoryTextFile(const char* c_szFileName, UINT uFileSize, const VOID* c_pvFileData) +{ + NANOBEGIN + const CHAR* c_pcFileData=(const CHAR*)c_pvFileData; + + std::string stConvFileData; + stConvFileData.reserve(uFileSize); + stConvFileData+="exec(compile('''"; + + // ConvertPythonTextFormat + { + for (UINT i=0; i + +#include "../eterBase/Singleton.h" + +class CPythonLauncher : public CSingleton +{ + public: + CPythonLauncher(); + virtual ~CPythonLauncher(); + + void Clear(); + + bool Create(const char* c_szProgramName="eter.python"); + void SetTraceFunc(int (*pFunc)(PyObject * obj, PyFrameObject * f, int what, PyObject *arg)); + bool RunLine(const char* c_szLine); + bool RunFile(const char* c_szFileName); + bool RunMemoryTextFile(const char* c_szFileName, UINT uFileSize, const VOID* c_pvFileData); + bool RunCompiledFile(const char* c_szFileName); + const char* GetError(); + + protected: + PyObject* m_poModule; + PyObject* m_poDic; +}; diff --git a/source/ScriptLib/PythonMarshal.cpp b/source/ScriptLib/PythonMarshal.cpp new file mode 100644 index 0000000..28625f5 --- /dev/null +++ b/source/ScriptLib/PythonMarshal.cpp @@ -0,0 +1,478 @@ +/* Write Python objects to files and read them back. + This is intended for writing and reading compiled Python code only; + a true persistent storage facility would be much harder, since + it would have to take circular links and sharing into account. */ + +#include "Stdafx.h" +#include + +/* High water mark to determine when the marshalled object is dangerously deep + * and risks coring the interpreter. When the object stack gets this deep, + * raise an exception instead of continuing. + */ +#define MAX_MARSHAL_STACK_DEPTH 5000 + +#define TYPE_NULL '0' +#define TYPE_NONE 'N' +#define TYPE_STOPITER 'S' +#define TYPE_ELLIPSIS '.' +#define TYPE_INT 'i' +#define TYPE_INT64 'I' +#define TYPE_FLOAT 'f' +#define TYPE_COMPLEX 'x' +#define TYPE_LONG 'l' +#define TYPE_STRING 's' +#define TYPE_TUPLE '(' +#define TYPE_LIST '[' +#define TYPE_DICT '{' +#define TYPE_CODE 'c' +#define TYPE_UNICODE 'u' +#define TYPE_UNKNOWN '?' + +typedef struct +{ + FILE * fp; + int error; + int depth; + PyObject * str; + char * ptr; + char * end; +} WFILE; + +typedef WFILE RFILE; /* Same struct with different invariants */ + +#define rs_byte(p) (((p)->ptr != (p)->end) ? (unsigned char)*(p)->ptr++ : EOF) + +#define r_byte(p) ((p)->fp ? getc((p)->fp) : rs_byte(p)) + +static int r_string(char *s, int n, RFILE *p) +{ + if (p->fp != NULL) + return fread(s, 1, n, p->fp); + if (p->end - p->ptr < n) + n = p->end - p->ptr; + memcpy(s, p->ptr, n); + p->ptr += n; + return n; +} + +static int r_short(RFILE *p) +{ + short x; + x = (short) r_byte(p); + x |= (short) r_byte(p) << 8; + /* Sign-extension, in case short greater than 16 bits */ + x |= -(x & 0x8000); + return x; +} + +static long r_long(RFILE *p) +{ + long x; + FILE *fp = p->fp; + if (fp) { + x = getc(fp); + x |= (long)getc(fp) << 8; + x |= (long)getc(fp) << 16; + x |= (long)getc(fp) << 24; + } + else { + x = rs_byte(p); + x |= (long)rs_byte(p) << 8; + x |= (long)rs_byte(p) << 16; + x |= (long)rs_byte(p) << 24; + } +#if SIZEOF_LONG > 4 + /* Sign extension for 64-bit machines */ + x |= -(x & 0x80000000L); +#endif + return x; +} + +/* r_long64 deals with the TYPE_INT64 code. On a machine with + sizeof(long) > 4, it returns a Python int object, else a Python long + object. Note that w_long64 writes out TYPE_INT if 32 bits is enough, + so there's no inefficiency here in returning a PyLong on 32-bit boxes + for everything written via TYPE_INT64 (i.e., if an int is written via + TYPE_INT64, it *needs* more than 32 bits). +*/ +static PyObject * r_long64(RFILE *p) +{ + long lo4 = r_long(p); + long hi4 = r_long(p); +#if SIZEOF_LONG > 4 + long x = (hi4 << 32) | (lo4 & 0xFFFFFFFFL); + return PyInt_FromLong(x); +#else + unsigned char buf[8]; + int one = 1; + int is_little_endian = (int)*(char*)&one; + if (is_little_endian) { + memcpy(buf, &lo4, 4); + memcpy(buf+4, &hi4, 4); + } + else { + memcpy(buf, &hi4, 4); + memcpy(buf+4, &lo4, 4); + } + return _PyLong_FromByteArray(buf, 8, is_little_endian, 1); +#endif +} + +static PyObject * r_object(RFILE *p) +{ + PyObject *v, *v2; + long i, n; + int type = r_byte(p); + + switch (type) { + + case EOF: + PyErr_SetString(PyExc_EOFError, + "EOF read where object expected"); + return NULL; + + case TYPE_NULL: + return NULL; + + case TYPE_NONE: + Py_INCREF(Py_None); + return Py_None; + + case TYPE_STOPITER: + Py_INCREF(PyExc_StopIteration); + return PyExc_StopIteration; + + case TYPE_ELLIPSIS: + Py_INCREF(Py_Ellipsis); + return Py_Ellipsis; + + case TYPE_INT: + return PyInt_FromLong(r_long(p)); + + case TYPE_INT64: + return r_long64(p); + + case TYPE_LONG: + { + int size; + PyLongObject* ob; + n = r_long(p); + size = n<0 ? -n : n; + ob = _PyLong_New(size); + if (ob == NULL) + return NULL; + ob->ob_size = n; + for (i = 0; i < size; i++) + ob->ob_digit[i] = (short) r_short(p); + return (PyObject *) ob; + } + + case TYPE_FLOAT: + { + char buf[256]; + double dx; + n = r_byte(p); + if (r_string(buf, (int)n, p) != n) { + PyErr_SetString(PyExc_EOFError, + "EOF read where object expected"); + return NULL; + } + buf[n] = '\0'; + PyFPE_START_PROTECT("atof", return 0) + dx = atof(buf); + PyFPE_END_PROTECT(dx) + return PyFloat_FromDouble(dx); + } + +#ifndef WITHOUT_COMPLEX + case TYPE_COMPLEX: + { + char buf[256]; + Py_complex c; + n = r_byte(p); + if (r_string(buf, (int)n, p) != n) { + PyErr_SetString(PyExc_EOFError, + "EOF read where object expected"); + return NULL; + } + buf[n] = '\0'; + PyFPE_START_PROTECT("atof", return 0) + c.real = atof(buf); + PyFPE_END_PROTECT(c) + n = r_byte(p); + if (r_string(buf, (int)n, p) != n) { + PyErr_SetString(PyExc_EOFError, + "EOF read where object expected"); + return NULL; + } + buf[n] = '\0'; + PyFPE_START_PROTECT("atof", return 0) + c.imag = atof(buf); + PyFPE_END_PROTECT(c) + return PyComplex_FromCComplex(c); + } +#endif + + case TYPE_STRING: + n = r_long(p); + if (n < 0) { + PyErr_SetString(PyExc_ValueError, "bad marshal data"); + return NULL; + } + v = PyString_FromStringAndSize((char *)NULL, n); + if (v != NULL) { + if (r_string(PyString_AS_STRING(v), (int)n, p) != n) { + Py_DECREF(v); + v = NULL; + PyErr_SetString(PyExc_EOFError, + "EOF read where object expected"); + } + } + return v; + +#ifdef Py_USING_UNICODE + case TYPE_UNICODE: + { + char *buffer; + + n = r_long(p); + if (n < 0) { + PyErr_SetString(PyExc_ValueError, "bad marshal data"); + return NULL; + } + buffer = PyMem_NEW(char, n); + if (buffer == NULL) + return PyErr_NoMemory(); + if (r_string(buffer, (int)n, p) != n) { + PyMem_DEL(buffer); + PyErr_SetString(PyExc_EOFError, + "EOF read where object expected"); + return NULL; + } + v = PyUnicode_DecodeUTF8(buffer, n, NULL); + PyMem_DEL(buffer); + return v; + } +#endif + + case TYPE_TUPLE: + n = r_long(p); + if (n < 0) { + PyErr_SetString(PyExc_ValueError, "bad marshal data"); + return NULL; + } + v = PyTuple_New((int)n); + if (v == NULL) + return v; + for (i = 0; i < n; i++) { + v2 = r_object(p); + if ( v2 == NULL ) { + Py_DECREF(v); + v = NULL; + break; + } + PyTuple_SET_ITEM(v, (int)i, v2); + } + return v; + + case TYPE_LIST: + n = r_long(p); + if (n < 0) { + PyErr_SetString(PyExc_ValueError, "bad marshal data"); + return NULL; + } + v = PyList_New((int)n); + if (v == NULL) + return v; + for (i = 0; i < n; i++) { + v2 = r_object(p); + if ( v2 == NULL ) { + Py_DECREF(v); + v = NULL; + break; + } + PyList_SetItem(v, (int)i, v2); + } + return v; + + case TYPE_DICT: + v = PyDict_New(); + if (v == NULL) + return NULL; + for (;;) { + PyObject *key, *val; + key = r_object(p); + if (key == NULL) + break; /* XXX Assume TYPE_NULL, not an error */ + val = r_object(p); + if (val != NULL) + PyDict_SetItem(v, key, val); + Py_DECREF(key); + Py_XDECREF(val); + } + return v; + + case TYPE_CODE: + if (PyEval_GetRestricted()) { + PyErr_SetString(PyExc_RuntimeError, + "cannot unmarshal code objects in " + "restricted execution mode"); + return NULL; + } + else { + int argcount = r_short(p); + int nlocals = r_short(p); + int stacksize = r_short(p); + int flags = r_short(p); + PyObject *code = NULL; + PyObject *consts = NULL; + PyObject *names = NULL; + PyObject *varnames = NULL; + PyObject *freevars = NULL; + PyObject *cellvars = NULL; + PyObject *filename = NULL; + PyObject *name = NULL; + int firstlineno = 0; + PyObject *lnotab = NULL; + + code = r_object(p); + if (code) consts = r_object(p); + if (consts) names = r_object(p); + if (names) varnames = r_object(p); + if (varnames) freevars = r_object(p); + if (freevars) cellvars = r_object(p); + if (cellvars) filename = r_object(p); + if (filename) name = r_object(p); + if (name) { + firstlineno = r_short(p); + lnotab = r_object(p); + } + + if (!PyErr_Occurred()) { + v = (PyObject *) PyCode_New( + argcount, nlocals, stacksize, flags, + code, consts, names, varnames, + freevars, cellvars, filename, name, + firstlineno, lnotab); + } + else + v = NULL; + Py_XDECREF(code); + Py_XDECREF(consts); + Py_XDECREF(names); + Py_XDECREF(varnames); + Py_XDECREF(freevars); + Py_XDECREF(cellvars); + Py_XDECREF(filename); + Py_XDECREF(name); + Py_XDECREF(lnotab); + + } + return v; + + default: + /* Bogus data got written, which isn't ideal. + This will let you keep working and recover. */ + PyErr_SetString(PyExc_ValueError, "bad marshal data"); + return NULL; + } +} + +int _PyMarshal_ReadShortFromFile(FILE *fp) +{ + RFILE rf; + rf.fp = fp; + return r_short(&rf); +} + +long _PyMarshal_ReadLongFromFile(FILE *fp) +{ + RFILE rf; + rf.fp = fp; + return r_long(&rf); +} + +/* Return size of file in bytes; < 0 if unknown. */ +static off_t getfilesize(FILE *fp) +{ + struct stat st; + if (fstat(fileno(fp), &st) != 0) + return -1; + else + return st.st_size; +} + +/* If we can get the size of the file up-front, and it's reasonably small, + * read it in one gulp and delegate to ...FromString() instead. Much quicker + * than reading a byte at a time from file; speeds .pyc imports. + * CAUTION: since this may read the entire remainder of the file, don't + * call it unless you know you're done with the file. + */ +PyObject *_PyMarshal_ReadLastObjectFromFile(FILE *fp) +{ + /* 75% of 2.1's .pyc files can exploit SMALL_FILE_LIMIT. + * REASONABLE_FILE_LIMIT is by defn something big enough for Tkinter.pyc. + */ +#define SMALL_FILE_LIMIT (1L << 14) +#define REASONABLE_FILE_LIMIT (1L << 18) + + off_t filesize; + + if (PyErr_Occurred()) + { + fprintf(stderr, "XXX rd_object called with exception set\n"); + return NULL; + } + + filesize = getfilesize(fp); + if (filesize > 0) { + char buf[SMALL_FILE_LIMIT]; + char* pBuf = NULL; + if (filesize <= SMALL_FILE_LIMIT) + pBuf = buf; + else if (filesize <= REASONABLE_FILE_LIMIT) + pBuf = (char *)PyMem_MALLOC(filesize); + if (pBuf != NULL) { + PyObject* v; + size_t n = fread(pBuf, 1, filesize, fp); + v = PyMarshal_ReadObjectFromString(pBuf, n); + if (pBuf != buf) + PyMem_FREE(pBuf); + return v; + } + + } + + /* We don't have fstat, or we do but the file is larger than + * REASONABLE_FILE_LIMIT or malloc failed -- read a byte at a time. + */ + return _PyMarshal_ReadObjectFromFile(fp); +#undef SMALL_FILE_LIMIT +#undef REASONABLE_FILE_LIMIT +} + +PyObject * _PyMarshal_ReadObjectFromFile(FILE *fp) +{ + RFILE rf; + if (PyErr_Occurred()) { + fprintf(stderr, "XXX rd_object called with exception set\n"); + return NULL; + } + rf.fp = fp; + return r_object(&rf); +} + +PyObject * _PyMarshal_ReadObjectFromString(char *str, int len) +{ + RFILE rf; + if (PyErr_Occurred()) { + fprintf(stderr, "XXX rds_object called with exception set\n"); + return NULL; + } + rf.fp = NULL; + rf.str = NULL; + rf.ptr = str; + rf.end = str + len; + return r_object(&rf); +} diff --git a/source/ScriptLib/PythonMarshal.h b/source/ScriptLib/PythonMarshal.h new file mode 100644 index 0000000..7ef6c1c --- /dev/null +++ b/source/ScriptLib/PythonMarshal.h @@ -0,0 +1,8 @@ +#ifndef __INC_ETERMARSHAL_H__ +#define __INC_ETERMARSHAL_H__ + +extern PyObject * _PyMarshal_ReadObjectFromFile(FILE* fp); +extern PyObject * _PyMarshal_ReadLastObjectFromFile(FILE* fp); +extern long _PyMarshal_ReadLongFromFile(FILE *fp); + +#endif diff --git a/source/ScriptLib/PythonUtils.cpp b/source/ScriptLib/PythonUtils.cpp new file mode 100644 index 0000000..2941559 --- /dev/null +++ b/source/ScriptLib/PythonUtils.cpp @@ -0,0 +1,425 @@ +#include "StdAfx.h" +#include "PythonUtils.h" + +IPythonExceptionSender * g_pkExceptionSender = NULL; + +bool __PyCallClassMemberFunc_ByCString(PyObject* poClass, const char* c_szFunc, PyObject* poArgs, PyObject** poRet); +bool __PyCallClassMemberFunc_ByPyString(PyObject* poClass, PyObject* poFuncName, PyObject* poArgs, PyObject** poRet); +bool __PyCallClassMemberFunc(PyObject* poClass, PyObject* poFunc, PyObject* poArgs, PyObject** poRet); + +PyObject * Py_BadArgument() +{ + PyErr_BadArgument(); + return NULL; +} + +PyObject * Py_BuildException(const char * c_pszErr, ...) +{ + if (!c_pszErr) + PyErr_Clear(); + else + { + char szErrBuf[512+1]; + va_list args; + va_start(args, c_pszErr); + vsnprintf(szErrBuf, sizeof(szErrBuf), c_pszErr, args); + va_end(args); + + PyErr_SetString(PyExc_RuntimeError, szErrBuf); + } + + return Py_BuildNone(); + //return NULL; +} + +PyObject * Py_BuildNone() +{ + Py_INCREF(Py_None); + return Py_None; +} + +void Py_ReleaseNone() +{ + Py_DECREF(Py_None); +} + +bool PyTuple_GetObject(PyObject* poArgs, int pos, PyObject** ret) +{ + if (pos >= PyTuple_Size(poArgs)) + return false; + + PyObject * poItem = PyTuple_GetItem(poArgs, pos); + + if (!poItem) + return false; + + *ret = poItem; + return true; +} + +bool PyTuple_GetLong(PyObject* poArgs, int pos, long* ret) +{ + if (pos >= PyTuple_Size(poArgs)) + return false; + + PyObject* poItem = PyTuple_GetItem(poArgs, pos); + + if (!poItem) + return false; + + *ret = PyLong_AsLong(poItem); + return true; +} + +bool PyTuple_GetDouble(PyObject* poArgs, int pos, double* ret) +{ + if (pos >= PyTuple_Size(poArgs)) + return false; + + PyObject* poItem = PyTuple_GetItem(poArgs, pos); + + if (!poItem) + return false; + + *ret = PyFloat_AsDouble(poItem); + return true; +} + +bool PyTuple_GetFloat(PyObject* poArgs, int pos, float* ret) +{ + if (pos >= PyTuple_Size(poArgs)) + return false; + + PyObject * poItem = PyTuple_GetItem(poArgs, pos); + + if (!poItem) + return false; + + *ret = float(PyFloat_AsDouble(poItem)); + return true; +} + +bool PyTuple_GetByte(PyObject* poArgs, int pos, unsigned char* ret) +{ + int val; + bool result = PyTuple_GetInteger(poArgs,pos,&val); + *ret = unsigned char(val); + return result; +} + +bool PyTuple_GetInteger(PyObject* poArgs, int pos, unsigned char* ret) +{ + int val; + bool result = PyTuple_GetInteger(poArgs,pos,&val); + *ret = unsigned char(val); + return result; +} + +bool PyTuple_GetInteger(PyObject* poArgs, int pos, WORD* ret) +{ + int val; + bool result = PyTuple_GetInteger(poArgs,pos,&val); + *ret = WORD(val); + return result; +} + +bool PyTuple_GetInteger(PyObject* poArgs, int pos, int* ret) +{ + if (pos >= PyTuple_Size(poArgs)) + return false; + + PyObject* poItem = PyTuple_GetItem(poArgs, pos); + + if (!poItem) + return false; + + *ret = PyLong_AsLong(poItem); + return true; +} + +bool PyTuple_GetUnsignedLong(PyObject* poArgs, int pos, unsigned long* ret) +{ + if (pos >= PyTuple_Size(poArgs)) + return false; + + PyObject * poItem = PyTuple_GetItem(poArgs, pos); + + if (!poItem) + return false; + + *ret = PyLong_AsUnsignedLong(poItem); + return true; +} + +bool PyTuple_GetUnsignedInteger(PyObject* poArgs, int pos, unsigned int* ret) +{ + if (pos >= PyTuple_Size(poArgs)) + return false; + + PyObject* poItem = PyTuple_GetItem(poArgs, pos); + + if (!poItem) + return false; + + *ret = PyLong_AsUnsignedLong(poItem); + return true; +} + +bool PyTuple_GetString(PyObject* poArgs, int pos, char** ret) +{ + if (pos >= PyTuple_Size(poArgs)) + return false; + + PyObject* poItem = PyTuple_GetItem(poArgs, pos); + + if (!poItem) + return false; + + if (!PyString_Check(poItem)) + return false; + + *ret = PyString_AsString(poItem); + return true; +} + +bool PyTuple_GetBoolean(PyObject* poArgs, int pos, bool* ret) +{ + if (pos >= PyTuple_Size(poArgs)) + return false; + + PyObject* poItem = PyTuple_GetItem(poArgs, pos); + + if (!poItem) + return false; + + *ret = PyLong_AsLong(poItem) ? true : false; + return true; +} + +bool PyCallClassMemberFunc(PyObject* poClass, PyObject* poFunc, PyObject* poArgs) +{ + PyObject* poRet; + + // NOTE : NULL üũ ߰.. - [levites] + if (!poClass) + { + Py_XDECREF(poArgs); + return false; + } + + if (!__PyCallClassMemberFunc(poClass, poFunc, poArgs, &poRet)) + return false; + + Py_DECREF(poRet); + return true; +} + +bool PyCallClassMemberFunc(PyObject* poClass, const char* c_szFunc, PyObject* poArgs) +{ + PyObject* poRet; + + // NOTE : NULL üũ ߰.. - [levites] + if (!poClass) + { + Py_XDECREF(poArgs); + return false; + } + + if (!__PyCallClassMemberFunc_ByCString(poClass, c_szFunc, poArgs, &poRet)) + return false; + + Py_DECREF(poRet); + return true; +} + +bool PyCallClassMemberFunc_ByPyString(PyObject* poClass, PyObject* poFuncName, PyObject* poArgs) +{ + PyObject* poRet; + + // NOTE : NULL üũ ߰.. - [levites] + if (!poClass) + { + Py_XDECREF(poArgs); + return false; + } + + if (!__PyCallClassMemberFunc_ByPyString(poClass, poFuncName, poArgs, &poRet)) + return false; + + Py_DECREF(poRet); + return true; +} + +bool PyCallClassMemberFunc(PyObject* poClass, const char* c_szFunc, PyObject* poArgs, bool* pisRet) +{ + PyObject* poRet; + + if (!__PyCallClassMemberFunc_ByCString(poClass, c_szFunc, poArgs, &poRet)) + return false; + + if (PyNumber_Check(poRet)) + *pisRet = (PyLong_AsLong(poRet) != 0); + else + *pisRet = true; + + Py_DECREF(poRet); + return true; +} + +bool PyCallClassMemberFunc(PyObject* poClass, const char* c_szFunc, PyObject* poArgs, long * plRetValue) +{ + PyObject* poRet; + + if (!__PyCallClassMemberFunc_ByCString(poClass, c_szFunc, poArgs, &poRet)) + return false; + + if (PyNumber_Check(poRet)) + { + *plRetValue = PyLong_AsLong(poRet); + Py_DECREF(poRet); + return true; + } + + Py_DECREF(poRet); + return false; +} + +/* + * Լ ȣ ʵ Ѵ. + * ε ϰ ȣ 쿡 ݵ false + * Py_DECREF(poArgs); ش. + */ +bool __PyCallClassMemberFunc_ByCString(PyObject* poClass, const char* c_szFunc, PyObject* poArgs, PyObject** ppoRet) +{ + if (!poClass) + { + Py_XDECREF(poArgs); + return false; + } + + PyObject * poFunc = PyObject_GetAttrString(poClass, (char *)c_szFunc); // New Reference + + if (!poFunc) + { + PyErr_Clear(); + Py_XDECREF(poArgs); + return false; + } + + if (!PyCallable_Check(poFunc)) + { + Py_DECREF(poFunc); + Py_XDECREF(poArgs); + return false; + } + + PyObject * poRet = PyObject_CallObject(poFunc, poArgs); // New Reference + + if (!poRet) + { + if (g_pkExceptionSender) + g_pkExceptionSender->Clear(); + + PyErr_Print(); + + if (g_pkExceptionSender) + g_pkExceptionSender->Send(); + + Py_DECREF(poFunc); + Py_XDECREF(poArgs); + return false; + } + + *ppoRet = poRet; + + Py_DECREF(poFunc); + Py_XDECREF(poArgs); + return true; +} + +bool __PyCallClassMemberFunc_ByPyString(PyObject* poClass, PyObject* poFuncName, PyObject* poArgs, PyObject** ppoRet) +{ + if (!poClass) + { + Py_XDECREF(poArgs); + return false; + } + + PyObject * poFunc = PyObject_GetAttr(poClass, poFuncName); // New Reference + + if (!poFunc) + { + PyErr_Clear(); + Py_XDECREF(poArgs); + return false; + } + + if (!PyCallable_Check(poFunc)) + { + Py_DECREF(poFunc); + Py_XDECREF(poArgs); + return false; + } + + PyObject * poRet = PyObject_CallObject(poFunc, poArgs); // New Reference + + if (!poRet) + { + if (g_pkExceptionSender) + g_pkExceptionSender->Clear(); + + PyErr_Print(); + + if (g_pkExceptionSender) + g_pkExceptionSender->Send(); + + Py_DECREF(poFunc); + Py_XDECREF(poArgs); + return false; + } + + *ppoRet = poRet; + + Py_DECREF(poFunc); + Py_XDECREF(poArgs); + return true; +} + +bool __PyCallClassMemberFunc(PyObject* poClass, PyObject * poFunc, PyObject* poArgs, PyObject** ppoRet) +{ + if (!poClass) + { + Py_XDECREF(poArgs); + return false; + } + + if (!poFunc) + { + PyErr_Clear(); + Py_XDECREF(poArgs); + return false; + } + + if (!PyCallable_Check(poFunc)) + { + Py_DECREF(poFunc); + Py_XDECREF(poArgs); + return false; + } + + PyObject * poRet = PyObject_CallObject(poFunc, poArgs); // New Reference + + if (!poRet) + { + PyErr_Print(); + Py_DECREF(poFunc); + Py_XDECREF(poArgs); + return false; + } + + *ppoRet = poRet; + + Py_DECREF(poFunc); + Py_XDECREF(poArgs); + return true; +} \ No newline at end of file diff --git a/source/ScriptLib/PythonUtils.h b/source/ScriptLib/PythonUtils.h new file mode 100644 index 0000000..4055a76 --- /dev/null +++ b/source/ScriptLib/PythonUtils.h @@ -0,0 +1,28 @@ +#pragma once + +#define SET_EXCEPTION(x) PyErr_SetString(PyExc_RuntimeError, #x) + +bool PyTuple_GetString(PyObject* poArgs, int pos, char** ret); +bool PyTuple_GetInteger(PyObject* poArgs, int pos, unsigned char* ret); +bool PyTuple_GetInteger(PyObject* poArgs, int pos, int* ret); +bool PyTuple_GetInteger(PyObject* poArgs, int pos, WORD* ret); +bool PyTuple_GetByte(PyObject* poArgs, int pos, unsigned char* ret); +bool PyTuple_GetUnsignedInteger(PyObject* poArgs, int pos, unsigned int* ret); +bool PyTuple_GetLong(PyObject* poArgs, int pos, long* ret); +bool PyTuple_GetUnsignedLong(PyObject* poArgs, int pos, unsigned long* ret); +bool PyTuple_GetFloat(PyObject* poArgs, int pos, float* ret); +bool PyTuple_GetDouble(PyObject* poArgs, int pos, double* ret); +bool PyTuple_GetObject(PyObject* poArgs, int pos, PyObject** ret); +bool PyTuple_GetBoolean(PyObject* poArgs, int pos, bool* ret); + +bool PyCallClassMemberFunc(PyObject* poClass, const char* c_szFunc, PyObject* poArgs); +bool PyCallClassMemberFunc(PyObject* poClass, const char* c_szFunc, PyObject* poArgs, bool* pisRet); +bool PyCallClassMemberFunc(PyObject* poClass, const char* c_szFunc, PyObject* poArgs, long * plRetValue); + +bool PyCallClassMemberFunc_ByPyString(PyObject* poClass, PyObject* poFuncName, PyObject* poArgs); +bool PyCallClassMemberFunc(PyObject* poClass, PyObject* poFunc, PyObject* poArgs); + +PyObject * Py_BuildException(const char * c_pszErr = NULL, ...); +PyObject * Py_BadArgument(); +PyObject * Py_BuildNone(); +PyObject * Py_BuildEmptyTuple(); diff --git a/source/ScriptLib/Resource.cpp b/source/ScriptLib/Resource.cpp new file mode 100644 index 0000000..87d1dca --- /dev/null +++ b/source/ScriptLib/Resource.cpp @@ -0,0 +1,105 @@ +#include "StdAfx.h" +#include "../eterLib/GrpExpandedImageInstance.h" +#include "../eterLib/GrpTextInstance.h" +#include "../eterLib/GrpMarkInstance.h" +#include "../eterLib/GrpSubImage.h" +#include "../eterLib/GrpText.h" +#include "../eterLib/AttributeData.h" +#include "../eterGrnLib/Thing.h" +#include "../eterGrnLib/ThingInstance.h" +#include "../effectLib/EffectMesh.h" +#include "../effectLib/EffectInstance.h" +#include "../gamelib/WeaponTrace.h" +#include "../gamelib/MapType.h" +#include "../gamelib/GameType.h" +#include "../gamelib/RaceData.h" +#include "../gamelib/RaceMotionData.h" +#include "../gamelib/ActorInstance.h" +#include "../gamelib/Area.h" +#include "../gamelib/ItemData.h" +#include "../gamelib/FlyingData.h" +#include "../gamelib/FlyTrace.h" +#include "../gamelib/FlyingInstance.h" +#include "../gamelib/FlyingData.h" + +#include "Resource.h" + +CResource * NewImage(const char* c_szFileName) +{ + return new CGraphicImage(c_szFileName); +} + +CResource * NewSubImage(const char* c_szFileName) +{ + return new CGraphicSubImage(c_szFileName); +} + +CResource * NewText(const char* c_szFileName) +{ + return new CGraphicText(c_szFileName); +} + +CResource * NewThing(const char* c_szFileName) +{ + return new CGraphicThing(c_szFileName); +} + +CResource * NewEffectMesh(const char* c_szFileName) +{ + return new CEffectMesh(c_szFileName); +} + +CResource * NewAttributeData(const char* c_szFileName) +{ + return new CAttributeData(c_szFileName); +} + +void CPythonResource::DumpFileList(const char * c_szFileName) +{ + m_resManager.DumpFileListToTextFile(c_szFileName); +} + +void CPythonResource::Destroy() +{ + CFlyingInstance::DestroySystem(); + CActorInstance::DestroySystem(); + CArea::DestroySystem(); + CGraphicExpandedImageInstance::DestroySystem(); + CGraphicImageInstance::DestroySystem(); + CGraphicMarkInstance::DestroySystem(); + CGraphicThingInstance::DestroySystem(); + CGrannyModelInstance::DestroySystem(); + CGraphicTextInstance::DestroySystem(); + CEffectInstance::DestroySystem(); + CWeaponTrace::DestroySystem(); + CFlyTrace::DestroySystem(); + + m_resManager.DestroyDeletingList(); + + CFlyingData::DestroySystem(); + CItemData::DestroySystem(); + CEffectData::DestroySystem(); + CEffectMesh::SEffectMeshData::DestroySystem(); + CRaceData::DestroySystem(); + NRaceData::DestroySystem(); + CRaceMotionData::DestroySystem(); + + m_resManager.Destroy(); +} + +CPythonResource::CPythonResource() +{ + m_resManager.RegisterResourceNewFunctionPointer("sub", NewSubImage); + m_resManager.RegisterResourceNewFunctionPointer("dds", NewImage); + m_resManager.RegisterResourceNewFunctionPointer("jpg", NewImage); + m_resManager.RegisterResourceNewFunctionPointer("tga", NewImage); + m_resManager.RegisterResourceNewFunctionPointer("bmp", NewImage); + m_resManager.RegisterResourceNewFunctionPointer("fnt", NewText); + m_resManager.RegisterResourceNewFunctionPointer("gr2", NewThing); + m_resManager.RegisterResourceNewFunctionPointer("mde", NewEffectMesh); + m_resManager.RegisterResourceNewFunctionPointer("mdatr", NewAttributeData); +} + +CPythonResource::~CPythonResource() +{ +} diff --git a/source/ScriptLib/Resource.h b/source/ScriptLib/Resource.h new file mode 100644 index 0000000..c9b1d60 --- /dev/null +++ b/source/ScriptLib/Resource.h @@ -0,0 +1,24 @@ +#pragma once + +#include "../EffectLib/StdAfx.h" +#include "../eterlib/Resource.h" +#include "../eterlib/ResourceManager.h" + +enum EResourceTypes +{ + RES_TYPE_UNKNOWN, +}; + +class CPythonResource : public CSingleton +{ + public: + CPythonResource(); + virtual ~CPythonResource(); + + void Destroy(); + + void DumpFileList(const char * c_szFileName); + + protected: + CResourceManager m_resManager; +}; \ No newline at end of file diff --git a/source/ScriptLib/StdAfx.cpp b/source/ScriptLib/StdAfx.cpp new file mode 100644 index 0000000..7f04122 --- /dev/null +++ b/source/ScriptLib/StdAfx.cpp @@ -0,0 +1,10 @@ +// stdafx.cpp : source file that includes just the standard includes +// scriptLib.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +void SetExceptionSender(IPythonExceptionSender * pkExceptionSender) +{ + g_pkExceptionSender = pkExceptionSender; +} diff --git a/source/ScriptLib/StdAfx.h b/source/ScriptLib/StdAfx.h new file mode 100644 index 0000000..63bc79d --- /dev/null +++ b/source/ScriptLib/StdAfx.h @@ -0,0 +1,54 @@ +#pragma once + +#include "../eterLib/StdAfx.h" +#include "../eterGrnLib/StdAfx.h" + +//#include +#ifdef _DEBUG + #undef _DEBUG + #include + #define _DEBUG +#else + #include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "PythonUtils.h" +#include "PythonLauncher.h" +#include "PythonMarshal.h" +#include "Resource.h" + +void initdbg(); + +// PYTHON_EXCEPTION_SENDER +class IPythonExceptionSender +{ + public: + void Clear() + { + m_strExceptionString = ""; + } + + void RegisterExceptionString(const char * c_szString) + { + m_strExceptionString += c_szString; + } + + virtual void Send() = 0; + + protected: + std::string m_strExceptionString; +}; + +extern IPythonExceptionSender * g_pkExceptionSender; + +void SetExceptionSender(IPythonExceptionSender * pkExceptionSender); +// END_OF_PYTHON_EXCEPTION_SENDER diff --git a/source/SpeedTreeLib/BoundaryShapeManager.cpp b/source/SpeedTreeLib/BoundaryShapeManager.cpp new file mode 100644 index 0000000..13bc41d --- /dev/null +++ b/source/SpeedTreeLib/BoundaryShapeManager.cpp @@ -0,0 +1,213 @@ +/////////////////////////////////////////////////////////////////////// +// Name: BoundaryShapeManager.cpp +// +// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION *** +// +// Copyright (c) 2002-2003 IDV, Inc. +// All Rights Reserved. +// +// IDV, Inc. +// 1233 Washington St. Suite 610 +// Columbia, SC 29201 +// Voice: (803) 799-1699 +// Fax: (803) 931-0320 +// Web: http://www.idvinc.com +// +// This software is supplied under the terms of a license agreement or +// nondisclosure agreement with Interactive Data Visualization and may not +// be copied or disclosed except in accordance with the terms of that +// agreement. + + +/////////////////////////////////////////////////////////////////////// +// Preprocessor +#include "StdAfx.h" + +#include +#include "../eterbase/Random.h" +#include "BoundaryShapeManager.h" + +using namespace std; + +/////////////////////////////////////////////////////////////////////// +// CBoundaryShapeManager::CBoundaryShapeManager +CBoundaryShapeManager::CBoundaryShapeManager() +{ +} + + +/////////////////////////////////////////////////////////////////////// +// CBoundaryShapeManager::~CBoundaryShapeManager + +CBoundaryShapeManager::~CBoundaryShapeManager() +{ +} + + +/////////////////////////////////////////////////////////////////////// +// CBoundaryShapeManager::LoadBsfFile + +bool CBoundaryShapeManager::LoadBsfFile(const char* pszFilename) +{ + bool bSuccess = true; + try + { + FILE* pFile = fopen(pszFilename, "rb"); + if (pFile) + { + // number of boundary shapes + unsigned int nNumBoundaries; + if (fread(&nNumBoundaries, sizeof(unsigned int), 1, pFile) == 1) + { + for (unsigned int i = 0; i < nNumBoundaries && bSuccess; ++i) + { + SBoundaryShape sShape; + + // number of contours for this shape + unsigned int nNumContours; + if (fread(&nNumContours, sizeof(unsigned int), 1, pFile) == 1) + { + for (unsigned int j = 0; j < nNumContours && bSuccess; ++j) + { + // number of points in this contour + vector vPoints; + unsigned int nNumPoints; + if (fread(&nNumPoints, sizeof(unsigned int), 1, pFile) == 1) + { + // read the points + for (unsigned int k = 0; k < nNumPoints && bSuccess; ++k) + { + SPoint sPoint; + + if (fread(sPoint.m_afData, sizeof(float), 3, pFile) == 3) + { + vPoints.push_back(sPoint); + + // update extents + if (j == 0 && k == 0) + { + // first point of this shape + memcpy(sShape.m_afMin, sPoint.m_afData, 3 * sizeof(float)); + memcpy(sShape.m_afMax, sPoint.m_afData, 3 * sizeof(float)); + } + else + { + // check extents + for (int l = 0; l < 3; ++l) + { + if (sPoint.m_afData[l] < sShape.m_afMin[l]) + sShape.m_afMin[l] = sPoint.m_afData[l]; + else if (sPoint.m_afData[l] > sShape.m_afMax[l]) + sShape.m_afMax[l] = sPoint.m_afData[l]; + } + } + } + else + { + m_strCurrentError = "Error in CBoundaryShapeManager::LoadBsfFile(): Failed to read point"; + bSuccess = false; + } + + } + sShape.m_vContours.push_back(vPoints); + } + else + { + m_strCurrentError = "Error in CBoundaryShapeManager::LoadBsfFile(): Failed to read number of points"; + bSuccess = false; + } + + } + m_vBoundaries.push_back(sShape); + } + else + { + m_strCurrentError = "Error in CBoundaryShapeManager::LoadBsfFile(): Failed to read number of contours"; + bSuccess = false; + } + } + } + else + { + m_strCurrentError = "Error in CBoundaryShapeManager::LoadBsfFile(): Failed to read number of boundaries"; + bSuccess = false; + } + fclose(pFile); + } + else + { + m_strCurrentError = string("Error in CBoundaryShapeManager::LoadBsfFile(): Could not open ") + string(pszFilename); + bSuccess = false; + } + } + + catch(...) + { + m_strCurrentError = "Error in CBoundaryShapeManager::LoadBsfFile(): Unknown exception"; + } + + return bSuccess; +} + + +/////////////////////////////////////////////////////////////////////// +// CBoundaryShapeManager::PointInside + +bool CBoundaryShapeManager::PointInside(float fX, float fY) +{ + bool bInside = false; + + for (DWORD i = 0; i < m_vBoundaries.size() && !bInside; ++i) + bInside = PointInShape(m_vBoundaries[i], fX, fY); + + return bInside; +} + + +/////////////////////////////////////////////////////////////////////// +// CBoundaryShapeManager::PointInShape + +bool CBoundaryShapeManager::PointInShape(SBoundaryShape& sShape, float fX, float fY) +{ + bool bInside = false; + + for (DWORD k = 0; k < sShape.m_vContours.size(); ++k) + { + for (DWORD i = 0, j = sShape.m_vContours[k].size() - 1; i < sShape.m_vContours[k].size(); j = i++) + { + if ((((sShape.m_vContours[k][i][1] <= fY) && (fY < sShape.m_vContours[k][j][1])) || + ((sShape.m_vContours[k][j][1] <= fY) && (fY < sShape.m_vContours[k][i][1]))) && + (fX < (sShape.m_vContours[k][i][0] - sShape.m_vContours[k][i][0]) * (fY - sShape.m_vContours[k][i][1]) / (sShape.m_vContours[k][j][1] - sShape.m_vContours[k][i][1]) + sShape.m_vContours[k][i][0])) + { + bInside = !bInside; + } + } + } + + return bInside; +} + + +/////////////////////////////////////////////////////////////////////// +// CBoundaryShapeManager::RandomPoint + +bool CBoundaryShapeManager::RandomPoint(float& fX, float& fY) +{ + bool bSuccess = false; + + if (m_vBoundaries.size() > 0) + { + // pick a random boundary shape + int nIndex = random_range(0, m_vBoundaries.size() - 1); + SBoundaryShape& sShape = m_vBoundaries[nIndex]; + + // pick a point at random within its extents + fX = frandom(sShape.m_afMin[0], sShape.m_afMax[0]); + fY = frandom(sShape.m_afMin[1], sShape.m_afMax[1]); + + // try it + bSuccess = PointInShape(sShape, fX, fY); + } + + return bSuccess; +} diff --git a/source/SpeedTreeLib/BoundaryShapeManager.h b/source/SpeedTreeLib/BoundaryShapeManager.h new file mode 100644 index 0000000..19bb930 --- /dev/null +++ b/source/SpeedTreeLib/BoundaryShapeManager.h @@ -0,0 +1,67 @@ +// Name: BoundaryShapeManager.h +// +// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION *** +// +// Copyright (c) 2002-2003 IDV, Inc. +// All Rights Reserved. +// +// IDV, Inc. +// 1233 Washington St. Suite 610 +// Columbia, SC 29201 +// Voice: (803) 799-1699 +// Fax: (803) 931-0320 +// Web: http://www.idvinc.com +// +// This software is supplied under the terms of a license agreement or +// nondisclosure agreement with Interactive Data Visualization and may not +// be copied or disclosed except in accordance with the terms of that +// agreement. +// +// Release version 1.0 + + +/////////////////////////////////////////////////////////////////////// +// Preprocessor +#include +#include + +/////////////////////////////////////////////////////////////////////// +// SPoint +struct SPoint +{ + float& operator[](int i) { return m_afData[i]; } + float m_afData[3]; +}; + + +/////////////////////////////////////////////////////////////////////// +// SBoundaryShape +struct SBoundaryShape +{ + std::vector< std::vector > m_vContours; + float m_afMin[3]; + float m_afMax[3]; +}; + + +/////////////////////////////////////////////////////////////////////// +// CBoundaryShapeManager +class CBoundaryShapeManager +{ +public: + CBoundaryShapeManager( ); + virtual ~CBoundaryShapeManager( ); + + bool LoadBsfFile(const char* pFilename); + + bool PointInside(float fX, float fY); + bool RandomPoint(float& fX, float& fY); + + std::string GetCurrentError( ) { return m_strCurrentError; } + +private: + bool PointInShape(SBoundaryShape& sShape, float fX, float fY); + + std::vector m_vBoundaries; + std::string m_strCurrentError; +}; diff --git a/source/SpeedTreeLib/Constants.h b/source/SpeedTreeLib/Constants.h new file mode 100644 index 0000000..2f83f06 --- /dev/null +++ b/source/SpeedTreeLib/Constants.h @@ -0,0 +1,162 @@ +/////////////////////////////////////////////////////////////////////// +// Constants +// +// (c) 2003 IDV, Inc. +// +// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION *** +// +// This software is supplied under the terms of a license agreement or +// nondisclosure agreement with Interactive Data Visualization and may +// not be copied or disclosed except in accordance with the terms of +// that agreement. +// +// Copyright (c) 2001-2003 IDV, Inc. +// All Rights Reserved. +// +// IDV, Inc. +// 1233 Washington St. Suite 610 +// Columbia, SC 29201 +// Voice: (803) 799-1699 +// Fax: (803) 931-0320 +// Web: http://www.idvinc.com +// + +#pragma once +//#include "LibVector_Source/IdvVector.h" +//#include "../Common Source/Filename.h" + +// used to isolate SpeedGrass usage +#define USE_SPEEDGRASS + + +// paths +//const CFilename c_strTreePath = "../data/TheValley/Trees/"; +//const CFilename c_strDataPath = "../data/TheValley/"; + +// vertex shader constant locations +const int c_nShaderLightPosition = 16; +const int c_nShaderGrassBillboard = 4; +const int c_nShaderGrassLodParameters = 8; +const int c_nShaderCameraPosition = 9; +const int c_nShaderGrassWindDirection = 10; +const int c_nShaderGrassPeriods = 11; +const int c_nShaderLeafAmbient = 47; +const int c_nShaderLeafDiffuse = 48; +const int c_nShaderLeafSpecular = 49; +const int c_nShaderLeafLightingAdjustment = 50; + +// lighting +//const float c_afLightDirBumpMapping[3] = { 0.8f, 0.0f, 0.4f }; +//const float c_afLightDir[3] = { 0.7434f, 0.0f, 0.57f }; +//const float c_afLightPos[3] = { c_afLightDir[0] * 1000.0f, c_afLightDir[1] * 1000.0f, c_afLightDir[2] * 1000.0f }; + +// stats +//const int c_nStatFrameRate = 0; +//const int c_nStatDrawTime = 1; +//const int c_nStatSceneTriangles = 2; +//const int c_nStatTriangleRate = 3; +//const int c_nStatNone = 4; +//const int c_nStatSummary = 5; +//const int c_nStatCount = 6; + +// grass +const float c_fDefaultGrassFarLod = 300.0f; +const float c_fGrassFadeLength = 50.0f; +const float c_fMinBladeNoise = -0.2f; +const float c_fMaxBladeNoise = 0.2f; +const float c_fMinBladeThrow = 1.0f; +const float c_fMaxBladeThrow = 2.5f; +const float c_fMinBladeSize = 7.5f; +const float c_fMaxBladeSize = 10.0f; +const int c_nNumBladeMaps = 2; +const float c_fGrassBillboardWideScalar = 1.75f; +const float c_fWalkerHeight = 12.0f; +const int c_nDefaultGrassBladeCount = 33000; +const int c_nGrassRegionCount = 20; + +// terrain +//const float c_fTerrainBaseRepeat = 1.0f; +//const float c_fTerrainDetail1Repeat = 80.0f; +//const float c_fTerrainDetail2Repeat = 8.0f; + +// wind +//const int c_nNumWindMatrices = 4; // number of unique wind matrices +//const int c_nNumMatricesPerTree = 3; // number of individual matrices used per tree +//const float c_fShimmerSpeed = 50.0f; // controls how fast the shimmer map rotates +//const float c_fShimmerExponent = 3.0f; // controls linearity of shimmer speed + +// lod +//const float c_fShadowCutoff = 5000.0f; // how far out shadows are no longer drawn (feet) +//const float c_fBillboardAlphaValue = 0.3294f; // value for glAlphaFunc() for single billboards +//const float c_fNearLod = 200.0f; +//const float c_fFarLod = 750.0f; + +// misc +const float c_fPi = 3.1415926535897932384626433832795f; +const float c_fHalfPi = c_fPi * 0.5f; +const float c_fQuarterPi = c_fPi * 0.25f; +const float c_fTwoPi = 2.0f * c_fPi; +const float c_fDeg2Rad = 57.29578f; // divide degrees by this to get radians +const float c_f90 = 0.5f * c_fPi; + +// branch vertex attribute sizes +//const int c_nBranchVertexTexture0Size = 4 * sizeof(float); // normal map coordinates + wind index + wind weight +//const int c_nBranchVertexTexture1Size = 3 * sizeof(float); // vertex tangents +//const int c_nBranchVertexTexture2Size = 3 * sizeof(float); // vertex binormals +//const int c_nBranchVertexTexture3Size = 2 * sizeof(float); // branch/frond shadow projection coordinates +//const int c_nBranchVertexNormalSize = 3 * sizeof(float); // (nx, ny, nz) +//const int c_nBranchVertexPositionSize = 3 * sizeof(float); // (x, y, z) +// +//const int c_nBranchVertexTotalSize = c_nBranchVertexTexture0Size + +// c_nBranchVertexTexture1Size + +// c_nBranchVertexTexture2Size + +// c_nBranchVertexTexture3Size + +// c_nBranchVertexNormalSize + +// c_nBranchVertexPositionSize; + +// frond vertex attribute sizes +//const int c_nFrondVertexTexture0Size = 2 * sizeof(float); // normal map coordinates +//const int c_nFrondVertexNormalSize = 3 * sizeof(float); // (nx, ny, nz) +//const int c_nFrondVertexPositionSize = 3 * sizeof(float); // (x, y, z) +// +//const int c_nFrondVertexTotalSize = c_nFrondVertexTexture0Size + +// c_nFrondVertexNormalSize + +// c_nFrondVertexPositionSize; + +// leaf vertex attribute sizes +//const int c_nLeafVertexTexture0Size = 2 * sizeof(float); // base map coordinate +//const int c_nLeafVertexTexture1Size = 2 * sizeof(float); // shimmer map coordinates (s & t) + shimmer-effect index +//const int c_nLeafVertexNormalSize = 3 * sizeof(float); // (nx, ny, nz) +//const int c_nLeafVertexPositionSize = 3 * sizeof(float); // (x, y, z) +// +//const int c_nLeafVertexTotalSize = c_nLeafVertexTexture0Size + +// c_nLeafVertexTexture1Size + +// c_nLeafVertexNormalSize + +// c_nLeafVertexPositionSize; + +// grass vertex attribute sizes +const int c_nGrassVertexTexture0Size = 2 * sizeof(float); // base map coordinate +const int c_nGrassVertexTexture1Size = 4 * sizeof(float); // vertex index, blade size, wind weight, noise factor +const int c_nGrassVertexColorSize = 4 * sizeof(unsigned char); // (rgba) +const int c_nGrassVertexPositionSize = 3 * sizeof(float); // (x, y, z) + +const int c_nGrassVertexTotalSize = c_nGrassVertexTexture0Size + + c_nGrassVertexTexture1Size + + c_nGrassVertexColorSize + + c_nGrassVertexPositionSize; + + +// terrain vertex attribute sizes +//const int c_nTerrainVertexTexture0Size = 2 * sizeof(float); +//const int c_nTerrainVertexTexture1Size = 2 * sizeof(float); +//const int c_nTerrainVertexTexture2Size = 2 * sizeof(float); +//const int c_nTerrainVertexPositionSize = 3 * sizeof(float); // (x, y, z) +//const int c_nTerrainVertexTotalSize = c_nTerrainVertexTexture0Size + +// c_nTerrainVertexTexture1Size + +// c_nTerrainVertexTexture2Size + +// c_nTerrainVertexPositionSize; + +// crosshair +//const float c_fCrosshairSize = 25.0f; +//const float c_fCrosshairAlpha = 0.075f; + diff --git a/source/SpeedTreeLib/SpeedGrassRT.cpp b/source/SpeedTreeLib/SpeedGrassRT.cpp new file mode 100644 index 0000000..b52c1a5 --- /dev/null +++ b/source/SpeedTreeLib/SpeedGrassRT.cpp @@ -0,0 +1,769 @@ +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassRT Class +// +// (c) 2003 IDV, Inc. +// +// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION *** +// +// This software is supplied under the terms of a license agreement or +// nondisclosure agreement with Interactive Data Visualization and may +// not be copied or disclosed except in accordance with the terms of +// that agreement. +// +// Copyright (c) 2001-2003 IDV, Inc. +// All Rights Reserved. +// +// IDV, Inc. +// 1233 Washington St. Suite 610 +// Columbia, SC 29201 +// Voice: (803) 799-1699 +// Fax: (803) 931-0320 +// Web: http://www.idvinc.com + + +#include "StdAfx.h" +#include "BoundaryShapeManager.h" + +#ifdef USE_SPEEDGRASS + +inline float VecInterpolate(float fStart, float fEnd, float fPercent) +{ + return fStart + (fEnd - fStart) * fPercent; +} + +#define VectorSinD(x) sinf((x) / 57.29578f) +#define VectorCosD(x) cosf((x) / 57.29578f) + +using namespace std; + +// macros +#ifndef max +#define max(a, b) (((a) > (b)) ? (a) : (b)) +#endif +#ifndef min +#define min(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +// static variables +float CSpeedGrassRT::m_fLodFarDistance = 100.0f; +float CSpeedGrassRT::m_fLodTransitionLength = 37.5f; +float CSpeedGrassRT::m_afUnitBillboard[12] = { 0.0f }; +float CSpeedGrassRT::m_afWindDir[4] = { 1.0f, 0.3f, 0.0f, 0.0f }; + +// camera +float CSpeedGrassRT::m_afCameraOut[3] = { 0.0f, 1.0f, 0.0f }; +float CSpeedGrassRT::m_afCameraUp[3] = { 0.0f, 0.0f, 1.0f }; +float CSpeedGrassRT::m_afCameraRight[3] = { 1.0f, 0.0f, 0.0f }; +float CSpeedGrassRT::m_afCameraPos[3] = { 0.0f, 0.0f, 0.0f }; +float CSpeedGrassRT::m_fFieldOfView = D3DXToRadian(40.0f); +float CSpeedGrassRT::m_fAspectRatio = 4.0f / 3.0f; + +// culling +float CSpeedGrassRT::m_afFrustumBox[6] = { 0.0f }; +float CSpeedGrassRT::m_afFrustumMin[2] = { FLT_MAX, FLT_MAX }; +float CSpeedGrassRT::m_afFrustumMax[2] = { -FLT_MAX, -FLT_MAX }; +float CSpeedGrassRT::m_afFrustumPlanes[5][4] = { 0.0f }; + + +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassRT::SBlade::SBlade + +CSpeedGrassRT::SBlade::SBlade( ) : + m_fSize(1.0f), + m_fNoise(0.0f), + m_fThrow(0.0f), + m_ucWhichTexture(0) +{ + m_afBottomColor[0] = m_afBottomColor[1] = m_afBottomColor[2] = 1.0f; + m_afTopColor[0] = m_afTopColor[1] = m_afTopColor[2] = 1.0f; +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassRT::SRegion::SRegion + +CSpeedGrassRT::SRegion::SRegion( ) : + m_bCulled(false), + m_fCullingRadius(1.0f) +{ + m_afCenter[0] = m_afCenter[1] = m_afCenter[2] = 0.5f; + m_afMin[0] = m_afMin[1] = m_afMin[2] = 0.0f; + m_afMax[0] = m_afMax[1] = m_afMax[2] = 1.0f; + m_VertexBuffer.Destroy(); +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassRT::CSpeedGrassRT + +CSpeedGrassRT::CSpeedGrassRT( ) : + m_nNumRegions(0), + m_nNumRegionCols(0), + m_nNumRegionRows(0), + m_pRegions(NULL), + m_bAllRegionsCulled(false) +{ + m_afBoundingBox[0] = m_afBoundingBox[1] = m_afBoundingBox[2] = 0.0f; + m_afBoundingBox[3] = m_afBoundingBox[4] = m_afBoundingBox[5] = 1.0f; +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassRT::~CSpeedGrassRT + +CSpeedGrassRT::~CSpeedGrassRT( ) +{ +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassRT::DeleteRegions + +void CSpeedGrassRT::DeleteRegions(void) +{ + delete[] m_pRegions; + m_pRegions = NULL; + m_nNumRegions = 0; +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassRT::GetRegions + +const CSpeedGrassRT::SRegion* CSpeedGrassRT::GetRegions(unsigned int& uiNumRegions) +{ + uiNumRegions = m_nNumRegions; + + return m_pRegions; +} + +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassRT::ParseBsfFile + +bool CSpeedGrassRT::ParseBsfFile(const char* pFilename, unsigned int nNumBlades, unsigned int uiRows, unsigned int uiCols, float fCollisionDistance) +{ + bool bSuccess = false; + + // copy region settings + m_nNumRegionCols = int(uiCols); + m_nNumRegionRows = int(uiRows); + + // initialize bounding box + m_afBoundingBox[0] = m_afBoundingBox[1] = m_afBoundingBox[2] = FLT_MAX; + m_afBoundingBox[3] = m_afBoundingBox[4] = m_afBoundingBox[5] = -FLT_MAX; + + CBoundaryShapeManager cManager; + vector vSceneBlades; + + if (cManager.LoadBsfFile(pFilename)) + { + for (unsigned int i = 0; i < nNumBlades; ++i) + { + SBlade sBlade; + + // try to place a blade + if (cManager.RandomPoint(sBlade.m_afPos[0], sBlade.m_afPos[1])) + { + sBlade.m_afPos[2] = Height(sBlade.m_afPos[0], sBlade.m_afPos[1], sBlade.m_afNormal); + +// CVec3 cNormal(sBlade.m_afNormal[0], sBlade.m_afNormal[1], sBlade.m_afNormal[2]); +// cNormal.Normalize( ); +// cNormal[2] = -cNormal[2]; +// memcpy(sBlade.m_afNormal, cNormal, 3 * sizeof(float)); + D3DXVECTOR3 v3Normal(sBlade.m_afNormal[0], sBlade.m_afNormal[1], sBlade.m_afNormal[2]); + D3DXVec3Normalize(&v3Normal, &v3Normal); + v3Normal.z = -v3Normal.z; + sBlade.m_afNormal[0] = v3Normal.x; + sBlade.m_afNormal[1] = v3Normal.y; + sBlade.m_afNormal[2] = v3Normal.z; + + // check against overall scene bounding box + for (int nAxis = 0; nAxis < 3; ++nAxis) + { + m_afBoundingBox[nAxis] = min(m_afBoundingBox[nAxis], sBlade.m_afPos[nAxis]); + m_afBoundingBox[nAxis + 3] = max(m_afBoundingBox[nAxis + 3], sBlade.m_afPos[nAxis]); + } + + // set bottom and top color + float fHeightPercent = Color(sBlade.m_afPos[0], sBlade.m_afPos[1], sBlade.m_afNormal, sBlade.m_afTopColor, sBlade.m_afBottomColor); + sBlade.m_fSize = VecInterpolate(c_fMinBladeSize, c_fMaxBladeSize, fHeightPercent); + + // assign which blade texture map + sBlade.m_ucWhichTexture = GetRandom(0, c_nNumBladeMaps - 1); + + // compute wind effects + sBlade.m_fNoise = GetRandom(c_fMinBladeNoise, c_fMaxBladeNoise); + sBlade.m_fThrow = GetRandom(c_fMinBladeThrow, c_fMaxBladeThrow); + + // store all blades together + vSceneBlades.push_back(sBlade); + } + } + + bSuccess = true; + } + else + fprintf(stderr, "%s\n", cManager.GetCurrentError( ).c_str( )); + + if (bSuccess) + CreateRegions(vSceneBlades, fCollisionDistance); + + return bSuccess; +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassRT::CustomPlacement +// +// Use this function to perform custom grass blade placement. Feel free +// to add parameters as necessary but be sure to call CreateRegions( ) +// at the end of the function to set up the SpeedGrass region system. + +bool CSpeedGrassRT::CustomPlacement(unsigned int uiRows, unsigned int uiCols) +{ + // copy region settings (do not remove) + m_nNumRegionCols = int(uiCols); + m_nNumRegionRows = int(uiRows); + + // initialize bounding box (do not remove) + m_afBoundingBox[0] = m_afBoundingBox[1] = m_afBoundingBox[2] = FLT_MAX; + m_afBoundingBox[3] = m_afBoundingBox[4] = m_afBoundingBox[5] = -FLT_MAX; + + // place one blade as an example + vector vSceneBlades; + + SBlade sBlade; + + sBlade.m_afPos[0] = 0.0f; + sBlade.m_afPos[1] = 0.0f; + sBlade.m_afPos[2] = 0.0f; + + sBlade.m_afNormal[0] = 0.0f; + sBlade.m_afNormal[1] = 0.0f; + sBlade.m_afNormal[2] = 1.0f; + + // check against overall scene bounding box (always do this) + for (int nAxis = 0; nAxis < 3; ++nAxis) + { + m_afBoundingBox[nAxis] = min(m_afBoundingBox[nAxis], sBlade.m_afPos[nAxis]); + m_afBoundingBox[nAxis + 3] = max(m_afBoundingBox[nAxis + 3], sBlade.m_afPos[nAxis]); + } + + // set bottom and top color + memcpy(sBlade.m_afBottomColor, sBlade.m_afNormal, 12); + memcpy(sBlade.m_afTopColor, sBlade.m_afNormal, 12); + + // assign which blade texture map + sBlade.m_ucWhichTexture = GetRandom(0, c_nNumBladeMaps - 1); + + // compute wind effects + sBlade.m_fNoise = GetRandom(c_fMinBladeNoise, c_fMaxBladeNoise); + sBlade.m_fThrow = GetRandom(c_fMinBladeThrow, c_fMaxBladeThrow); + + // compute dimensions + sBlade.m_fSize = GetRandom(c_fMinBladeSize, c_fMaxBladeSize); + + // store all blades together + vSceneBlades.push_back(sBlade); + + // create regions based on blades (do not remove) + CreateRegions(vSceneBlades); + + // true = success, false = error + return true; +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassRT::GetLodParams + +void CSpeedGrassRT::GetLodParams(float& fFarDistance, float& fTransitionLength) +{ + fFarDistance = m_fLodFarDistance; + fTransitionLength = m_fLodTransitionLength; +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassRT::SetLodParams + +void CSpeedGrassRT::SetLodParams(float fFarDistance, float fTransitionLength) +{ + m_fLodFarDistance = fFarDistance; + m_fLodTransitionLength = fTransitionLength; +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassRT::Cull +// +// Using a two-dimensional projection, determine which regions +// intersect with the view frustum (+Z is assumed to be up) + +void CSpeedGrassRT::Cull(void) +{ + // convert raw frustum min and max values into min and max region cell indices + int anFrustumCellsMin[2], anFrustumCellsMax[2]; + ConvertCoordsToCell(m_afFrustumMin, anFrustumCellsMin); + ConvertCoordsToCell(m_afFrustumMax, anFrustumCellsMax); + + // set all regions to culled, modify later + for (int i = 0; i < m_nNumRegions; ++i) + m_pRegions[i].m_bCulled = true; + + int nRegionsDrawn = 0; + + // is the entire set of regions culled? + if ((anFrustumCellsMin[0] < 0 && anFrustumCellsMax[0] < 0) || + (anFrustumCellsMin[0] >= m_nNumRegionCols && anFrustumCellsMax[0] >= m_nNumRegionCols) || + (anFrustumCellsMin[1] < 0 && anFrustumCellsMax[1] < 0) || + (anFrustumCellsMin[1] >= m_nNumRegionRows && anFrustumCellsMax[1] >= m_nNumRegionRows)) + m_bAllRegionsCulled = true; + else + { + // clip cell values + anFrustumCellsMin[0] = max(anFrustumCellsMin[0], 0); + anFrustumCellsMin[1] = max(anFrustumCellsMin[1], 0); + anFrustumCellsMax[0] = min(anFrustumCellsMax[0], m_nNumRegionCols - 1); + anFrustumCellsMax[1] = min(anFrustumCellsMax[1], m_nNumRegionRows - 1); + + for (i = anFrustumCellsMin[0]; i <= anFrustumCellsMax[0]; ++i) + for (int j = anFrustumCellsMin[1]; j <= anFrustumCellsMax[1]; ++j) + { + SRegion* pRegion = m_pRegions + GetRegionIndex(j, i); + pRegion->m_bCulled = OutsideFrustum(pRegion); + } + + m_bAllRegionsCulled = false; + } +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassRT::SetWindDirection + +void CSpeedGrassRT::SetWindDirection(const float* pWindDir) +{ + memcpy(m_afWindDir, pWindDir, 3 * sizeof(float)); + m_afWindDir[3] = 0.0f; +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassRT::GetWindDirection + +const float* CSpeedGrassRT::GetWindDirection(void) +{ + return m_afWindDir; +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassRT::GetCameraPos + +const float* CSpeedGrassRT::GetCameraPos(void) +{ + return m_afCameraPos; +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassRT::SetCamera + +void CSpeedGrassRT::SetCamera(const float* pPosition, const double* pModelviewMatrix) +{ + memcpy(m_afCameraPos, pPosition, 3 * sizeof(float)); + + // "right" vector + m_afCameraRight[0] = pModelviewMatrix[0]; + m_afCameraRight[1] = pModelviewMatrix[4]; + m_afCameraRight[2] = pModelviewMatrix[8]; + + // "up" vector + m_afCameraUp[0] = pModelviewMatrix[1]; + m_afCameraUp[1] = pModelviewMatrix[5]; + m_afCameraUp[2] = pModelviewMatrix[9]; + + // "out of screen" vector + m_afCameraOut[0] = pModelviewMatrix[2]; + m_afCameraOut[1] = pModelviewMatrix[6]; + m_afCameraOut[2] = pModelviewMatrix[10]; + + // with direction changed, billboard turns + ComputeUnitBillboard( ); + + // compute new frustum box + ComputeFrustum( ); +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassRT::SetPerspective + +void CSpeedGrassRT::SetPerspective(float fAspectRatio, float fFieldOfView) +{ + m_fAspectRatio = fAspectRatio; + m_fFieldOfView = D3DXToRadian(fAspectRatio * fFieldOfView); +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassRT::CreateRegions + +void CSpeedGrassRT::CreateRegions(const vector& vSceneBlades, float fCollisionDistance) +{ + // create regions based on overall extents + DeleteRegions( ); + m_nNumRegions = int(m_nNumRegionRows * m_nNumRegionCols); + m_pRegions = new SRegion[m_nNumRegions]; + + // run through all regions, computing extents for each + float fCellWidth = (m_afBoundingBox[3] - m_afBoundingBox[0]) / m_nNumRegionCols; + float fCellHeight = (m_afBoundingBox[4] - m_afBoundingBox[1]) / m_nNumRegionRows; + + float fY = m_afBoundingBox[1]; + for (int nRow = 0; nRow < m_nNumRegionRows; ++nRow) + { + float fX = m_afBoundingBox[0]; + for (int nCol = 0; nCol < m_nNumRegionCols; ++nCol) + { + SRegion* pRegion = m_pRegions + GetRegionIndex(nRow, nCol); + + // compute extents + pRegion->m_afMin[0] = fX; + pRegion->m_afMax[0] = fX + fCellWidth; + pRegion->m_afMin[1] = fY; + pRegion->m_afMax[1] = fY + fCellHeight; + + // compute center + pRegion->m_afCenter[0] = 0.5f * (pRegion->m_afMin[0] + pRegion->m_afMax[0]); + pRegion->m_afCenter[1] = 0.5f * (pRegion->m_afMin[1] + pRegion->m_afMax[1]); + + // compute culling radius + pRegion->m_fCullingRadius = 1.1f * sqrt( + ((pRegion->m_afMax[0] - pRegion->m_afCenter[0]) * (pRegion->m_afMax[0] - pRegion->m_afCenter[0])) + + ((pRegion->m_afMax[1] - pRegion->m_afCenter[1]) * (pRegion->m_afMax[1] - pRegion->m_afCenter[1])) + ); + + fX += fCellWidth; + } + + fY += fCellHeight; + } + + // assign each blade of grass to its particular region + for (vector::const_iterator iBlade = vSceneBlades.begin( ); iBlade != vSceneBlades.end( ); ++iBlade) + { + // convert position to row/col index + float fPercentAlongX = (iBlade->m_afPos[0] - m_afBoundingBox[0]) / (m_afBoundingBox[3] - m_afBoundingBox[0]); + float fPercentAlongY = (iBlade->m_afPos[1] - m_afBoundingBox[1]) / (m_afBoundingBox[4] - m_afBoundingBox[1]); + + // clip values + unsigned int uiCol = min(fPercentAlongX * m_nNumRegionCols, m_nNumRegionCols - 1); + unsigned int uiRow = min(fPercentAlongY * m_nNumRegionRows, m_nNumRegionRows - 1); + + m_pRegions[GetRegionIndex(uiRow, uiCol)].m_vBlades.push_back(*iBlade); + } + + // compute z extents (now that the blades are in) + for (int i = 0; i < m_nNumRegions; ++i) + { + SRegion* pRegion = m_pRegions + i; + + pRegion->m_afMin[2] = FLT_MAX; + pRegion->m_afMax[2] = -FLT_MAX; + for (vector::iterator iBlade = pRegion->m_vBlades.begin( ); iBlade != pRegion->m_vBlades.end( ); ++iBlade) + { + pRegion->m_afMin[2] = min(pRegion->m_afMin[2], iBlade->m_afPos[2]); + pRegion->m_afMax[2] = max(pRegion->m_afMax[2], iBlade->m_afPos[2] + iBlade->m_fSize); + } + + pRegion->m_afCenter[0] = 0.5f * (pRegion->m_afMin[0] + pRegion->m_afMax[0]); + pRegion->m_afCenter[1] = 0.5f * (pRegion->m_afMin[1] + pRegion->m_afMax[1]); + pRegion->m_afCenter[2] = 0.5f * (pRegion->m_afMin[2] + pRegion->m_afMax[2]); + + // compute culling radius + pRegion->m_fCullingRadius = 1.1f * sqrt( + ((pRegion->m_afMax[0] - pRegion->m_afCenter[0]) * (pRegion->m_afMax[0] - pRegion->m_afCenter[0])) + + ((pRegion->m_afMax[1] - pRegion->m_afCenter[1]) * (pRegion->m_afMax[1] - pRegion->m_afCenter[1])) + + ((pRegion->m_afMax[2] - pRegion->m_afCenter[2]) * (pRegion->m_afMax[2] - pRegion->m_afCenter[2])) + ); + } + + // collision detection + if (fCollisionDistance > 0.0f) + { + fCollisionDistance *= fCollisionDistance; + for (int nRow = 0; nRow < m_nNumRegionRows; ++nRow) + { + float fX = m_afBoundingBox[0]; + for (int nCol = 0; nCol < m_nNumRegionCols; ++nCol) + { + SRegion* pRegion = m_pRegions + GetRegionIndex(nRow, nCol); + + // check each blade against all other blades in the region + for (DWORD i = 0; i < pRegion->m_vBlades.size( ); ++i) + { + float fX = pRegion->m_vBlades[i].m_afPos[0]; + float fY = pRegion->m_vBlades[i].m_afPos[1]; + bool bCollision = false; + for (DWORD j = 0; j < pRegion->m_vBlades.size( ) && !bCollision; ++j) + { + if (i != j) + { + float fDistance = (fX - pRegion->m_vBlades[j].m_afPos[0]) * (fX - pRegion->m_vBlades[j].m_afPos[0]) + (fY - pRegion->m_vBlades[j].m_afPos[1]) * (fY - pRegion->m_vBlades[j].m_afPos[1]); + if (fDistance < fCollisionDistance) + bCollision = true; + } + } + + // delete the blade if necessary and adjust the main loop counter to compensate + if (bCollision) + pRegion->m_vBlades.erase(pRegion->m_vBlades.begin( ) + i--); + } + } + } + } +} + +////////////////////////////////////////////////////////////////////////// +// CSpeedGrassRT::RotateAxisFromIdentity + +__forceinline void CSpeedGrassRT::RotateAxisFromIdentity(D3DXMATRIX * pMat, const float & c_fAngle, const D3DXVECTOR3 & c_rv3Axis) +{ + float s = VectorSinD(c_fAngle); + float c = VectorCosD(c_fAngle); + float t = 1.0 - c; + + float x = c_rv3Axis.x; + float y = c_rv3Axis.y; + float z = c_rv3Axis.z; + + pMat->_11 = t * x * x + c; + pMat->_12 = t * x * y + s * z; + pMat->_13 = t * x * z - s * y; + pMat->_21 = t * x * y - s * z; + pMat->_22 = t * y * y + c; + pMat->_23 = t * y * z + s * x; + pMat->_31 = t * x * z + s * y; + pMat->_32 = t * y * z - s * x; + pMat->_33 = t * z * z + c; +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassRT::ComputeFrustum + +void CSpeedGrassRT::ComputeFrustum(void) +{ + // setup useful vectors +// CVec3 cCameraIn(-m_afCameraOut[0], -m_afCameraOut[1], -m_afCameraOut[2]); +// CVec3 cCameraUp(m_afCameraUp[0], m_afCameraUp[1], m_afCameraUp[2]); +// CVec3 cCameraRight(m_afCameraRight[0], m_afCameraRight[1], m_afCameraRight[2]); +// CVec3 cCameraPos(m_afCameraPos[0], m_afCameraPos[1], m_afCameraPos[2]); +// CVec3 cFarPoint = cCameraPos + cCameraIn * (m_fLodFarDistance + m_fLodTransitionLength); + D3DXVECTOR3 cCameraIn(-m_afCameraOut[0], -m_afCameraOut[1], -m_afCameraOut[2]); + D3DXVECTOR3 cCameraUp(m_afCameraUp[0], m_afCameraUp[1], m_afCameraUp[2]); + D3DXVECTOR3 cCameraRight(m_afCameraRight[0], m_afCameraRight[1], m_afCameraRight[2]); + D3DXVECTOR3 cCameraPos(m_afCameraPos[0], m_afCameraPos[1], m_afCameraPos[2]); + D3DXVECTOR3 cFarPoint = cCameraPos + cCameraIn * (m_fLodFarDistance + m_fLodTransitionLength); + + // far plane +// memcpy(m_afFrustumPlanes[0], cCameraIn, 3 * sizeof(float)); +// m_afFrustumPlanes[0][3] = -(cCameraIn ^ cFarPoint); // operator^ is dot product + m_afFrustumPlanes[0][0] = cCameraIn.x; + m_afFrustumPlanes[0][1] = cCameraIn.y; + m_afFrustumPlanes[0][2] = cCameraIn.z; + m_afFrustumPlanes[0][3] = -D3DXVec3Dot(&cCameraIn, &cFarPoint); // operator^ is dot product + +// CRotTransform cRotate(true); + D3DXMATRIX cRotate; + D3DXMatrixIdentity(&cRotate); + D3DXVECTOR3 cNormal; + + // upper plane +// cRotate.RotateAxisFromIdentity(VecRad2Deg(0.5f * m_fFieldOfView * m_fAspectRatio + c_fHalfPi) , cCameraRight); +// CVec3 cNormal = cCameraIn * cRotate; +// cNormal.Normalize( ); +// memcpy(m_afFrustumPlanes[1], cNormal, 3 * sizeof(float)); +// m_afFrustumPlanes[1][3] = -(cNormal ^ cCameraPos); + + // left plane +// cRotate.RotateAxisFromIdentity(VecRad2Deg(0.5f * m_fFieldOfView + c_fHalfPi) , cCameraUp); +// cNormal = cCameraIn * cRotate; +// cNormal.Normalize( ); +// memcpy(m_afFrustumPlanes[2], cNormal, 3 * sizeof(float)); +// m_afFrustumPlanes[2][3] = -(cNormal ^ cCameraPos); + + // lower plane +// cRotate.RotateAxisFromIdentity(-VecRad2Deg(0.5f * m_fFieldOfView * m_fAspectRatio + c_fHalfPi) , cCameraRight); +// cNormal = cCameraIn * cRotate; +// cNormal.Normalize( ); +// memcpy(m_afFrustumPlanes[3], cNormal, 3 * sizeof(float)); +// m_afFrustumPlanes[3][3] = -(cNormal ^ cCameraPos); + + // right plane +// cRotate.RotateAxisFromIdentity(-VecRad2Deg(0.5f * m_fFieldOfView + c_fHalfPi) , cCameraUp); +// cNormal = cCameraIn * cRotate; +// cNormal.Normalize( ); +// memcpy(m_afFrustumPlanes[4], cNormal, 3 * sizeof(float)); +// m_afFrustumPlanes[4][3] = -(cNormal ^ cCameraPos); + + RotateAxisFromIdentity(&cRotate, D3DXToDegree(0.5f * m_fFieldOfView * m_fAspectRatio + c_fHalfPi), cCameraRight); + D3DXVec3TransformCoord(&cNormal, &cCameraIn, &cRotate); + D3DXVec3Normalize(&cNormal, &cNormal); + m_afFrustumPlanes[1][0] = cNormal.x; + m_afFrustumPlanes[1][1] = cNormal.y; + m_afFrustumPlanes[1][2] = cNormal.z; + m_afFrustumPlanes[1][3] = -D3DXVec3Dot(&cNormal, &cCameraPos); // operator^ is dot product + + RotateAxisFromIdentity(&cRotate, D3DXToDegree(0.5f * m_fFieldOfView + c_fHalfPi), cCameraUp); + D3DXVec3TransformCoord(&cNormal, &cCameraIn, &cRotate); + D3DXVec3Normalize(&cNormal, &cNormal); + m_afFrustumPlanes[2][0] = cNormal.x; + m_afFrustumPlanes[2][1] = cNormal.y; + m_afFrustumPlanes[2][2] = cNormal.z; + m_afFrustumPlanes[2][3] = -D3DXVec3Dot(&cNormal, &cCameraPos); // operator^ is dot product + + RotateAxisFromIdentity(&cRotate, -D3DXToDegree(0.5f * m_fFieldOfView * m_fAspectRatio + c_fHalfPi), cCameraRight); + D3DXVec3TransformCoord(&cNormal, &cCameraIn, &cRotate); + D3DXVec3Normalize(&cNormal, &cNormal); + m_afFrustumPlanes[3][0] = cNormal.x; + m_afFrustumPlanes[3][1] = cNormal.y; + m_afFrustumPlanes[3][2] = cNormal.z; + m_afFrustumPlanes[3][3] = -D3DXVec3Dot(&cNormal, &cCameraPos); // operator^ is dot product + + RotateAxisFromIdentity(&cRotate, -D3DXToDegree(0.5f * m_fFieldOfView + c_fHalfPi), cCameraUp); + D3DXVec3TransformCoord(&cNormal, &cCameraIn, &cRotate); + D3DXVec3Normalize(&cNormal, &cNormal); + m_afFrustumPlanes[4][0] = cNormal.x; + m_afFrustumPlanes[4][1] = cNormal.y; + m_afFrustumPlanes[4][2] = cNormal.z; + m_afFrustumPlanes[4][3] = -D3DXVec3Dot(&cNormal, &cCameraPos); // operator^ is dot product + + // frustum points + float fFrustumHeight = (m_fLodFarDistance + m_fLodTransitionLength) * tanf(0.5f * m_fFieldOfView); + float fFrustumWidth = (m_fLodFarDistance + m_fLodTransitionLength) * tanf(0.5f * m_fFieldOfView * m_fAspectRatio); + +// CVec3 acFrustum[5]; + D3DXVECTOR3 acFrustum[5]; + acFrustum[0] = cCameraPos; + acFrustum[1] = cFarPoint + cCameraRight * fFrustumWidth + cCameraUp * fFrustumHeight; + acFrustum[2] = cFarPoint - cCameraRight * fFrustumWidth + cCameraUp * fFrustumHeight; + acFrustum[3] = cFarPoint - cCameraRight * fFrustumWidth - cCameraUp * fFrustumHeight; + acFrustum[4] = cFarPoint + cCameraRight * fFrustumWidth - cCameraUp * fFrustumHeight; + + // find min/max (x,y) coordinates + m_afFrustumMin[0] = m_afFrustumMin[1] = FLT_MAX; + m_afFrustumMax[0] = m_afFrustumMax[1] = -FLT_MAX; + for (int i = 0; i < 5; ++i) + { + m_afFrustumMin[0] = min(m_afFrustumMin[0], acFrustum[i][0]); + m_afFrustumMax[0] = max(m_afFrustumMax[0], acFrustum[i][0]); + m_afFrustumMin[1] = min(m_afFrustumMin[1], acFrustum[i][1]); + m_afFrustumMax[1] = max(m_afFrustumMax[1], acFrustum[i][1]); + } +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassRT::ComputeUnitBillboard + +void CSpeedGrassRT::ComputeUnitBillboard(void) +{ +// float fAzimuth = D3DXToDegree(atan2(-m_afCameraOut[1], -m_afCameraOut[0])); + float fAzimuth = atan2(-m_afCameraOut[1], -m_afCameraOut[0]); + +// CRotTransform cTrans; +// cTrans.RotateZ(fAzimuth); +// +// static CVec3 afCorner1(0.0f, 0.5f, 1.0f); +// static CVec3 afCorner2(0.0f, -0.5f, 1.0f); +// static CVec3 afCorner3(0.0f, -0.5f, 0.0f); +// static CVec3 afCorner4(0.0f, 0.5f, 0.0f); +// +// CVec3 afNewCorner1 = afCorner1 * cTrans; +// CVec3 afNewCorner2 = afCorner2 * cTrans; +// CVec3 afNewCorner3 = afCorner3 * cTrans; +// CVec3 afNewCorner4 = afCorner4 * cTrans; +// +// memcpy(m_afUnitBillboard + 0, afNewCorner1.m_afData, 3 * sizeof(float)); +// memcpy(m_afUnitBillboard + 3, afNewCorner2.m_afData, 3 * sizeof(float)); +// memcpy(m_afUnitBillboard + 6, afNewCorner3.m_afData, 3 * sizeof(float)); +// memcpy(m_afUnitBillboard + 9, afNewCorner4.m_afData, 3 * sizeof(float)); + + D3DXMATRIX cTrans; + D3DXMatrixRotationZ(&cTrans, fAzimuth); + + static D3DXVECTOR3 afCorner1(0.0f, 0.5f, 1.0f); + static D3DXVECTOR3 afCorner2(0.0f, -0.5f, 1.0f); + static D3DXVECTOR3 afCorner3(0.0f, -0.5f, 0.0f); + static D3DXVECTOR3 afCorner4(0.0f, 0.5f, 0.0f); + + D3DXVECTOR3 afNewCorner1; + D3DXVECTOR3 afNewCorner2; + D3DXVECTOR3 afNewCorner3; + D3DXVECTOR3 afNewCorner4; + + D3DXVec3TransformCoord(&afNewCorner1, &afCorner1, &cTrans); + D3DXVec3TransformCoord(&afNewCorner2, &afCorner2, &cTrans); + D3DXVec3TransformCoord(&afNewCorner3, &afCorner3, &cTrans); + D3DXVec3TransformCoord(&afNewCorner4, &afCorner4, &cTrans); + + m_afUnitBillboard[0] = afNewCorner1.x; + m_afUnitBillboard[1] = afNewCorner1.y; + m_afUnitBillboard[2] = afNewCorner1.z; + m_afUnitBillboard[3] = afNewCorner2.x; + m_afUnitBillboard[4] = afNewCorner2.y; + m_afUnitBillboard[5] = afNewCorner2.z; + m_afUnitBillboard[6] = afNewCorner3.x; + m_afUnitBillboard[7] = afNewCorner3.y; + m_afUnitBillboard[8] = afNewCorner3.z; + m_afUnitBillboard[9] = afNewCorner4.x; + m_afUnitBillboard[10] = afNewCorner4.y; + m_afUnitBillboard[11] = afNewCorner4.z; +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassRT::ConvertCoordsToCell + +void CSpeedGrassRT::ConvertCoordsToCell(const float* pCoords, int* pGridCoords) const +{ + float fPercentAlongX = (pCoords[0] - m_afBoundingBox[0]) / (m_afBoundingBox[3] - m_afBoundingBox[0]); + float fPercentAlongY = (pCoords[1] - m_afBoundingBox[1]) / (m_afBoundingBox[4] - m_afBoundingBox[1]); + + if (fPercentAlongX < 0.0f) + pGridCoords[0] = -1; + else if (fPercentAlongX > 1.0f) + pGridCoords[0] = m_nNumRegionCols; + else + pGridCoords[0] = fPercentAlongX * m_nNumRegionCols; + + if (fPercentAlongY < 0.0f) + pGridCoords[1] = -1; + else if (fPercentAlongY > 1.0f) + pGridCoords[1] = m_nNumRegionRows; + else + pGridCoords[1] = fPercentAlongY * m_nNumRegionRows; +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassRT::OutsideFrustum + +__forceinline bool CSpeedGrassRT::OutsideFrustum(CSpeedGrassRT::SRegion* pRegion) +{ + bool bOutside = false; + + for (int i = 0; i < 5 && !bOutside; ++i) + if (m_afFrustumPlanes[i][0] * pRegion->m_afCenter[0] + + m_afFrustumPlanes[i][1] * pRegion->m_afCenter[1] + + m_afFrustumPlanes[i][2] * pRegion->m_afCenter[2] + + m_afFrustumPlanes[i][3] > pRegion->m_fCullingRadius) + bOutside = true; + + return bOutside; +} + +#endif // USE_SPEEDGRASS \ No newline at end of file diff --git a/source/SpeedTreeLib/SpeedGrassRT.h b/source/SpeedTreeLib/SpeedGrassRT.h new file mode 100644 index 0000000..fd8a2ba --- /dev/null +++ b/source/SpeedTreeLib/SpeedGrassRT.h @@ -0,0 +1,180 @@ +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassRT Class +// +// (c) 2003 IDV, Inc. +// +// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION *** +// +// This software is supplied under the terms of a license agreement or +// nondisclosure agreement with Interactive Data Visualization and may +// not be copied or disclosed except in accordance with the terms of +// that agreement. +// +// Copyright (c) 2001-2003 IDV, Inc. +// All Rights Reserved. +// +// IDV, Inc. +// 1233 Washington St. Suite 610 +// Columbia, SC 29201 +// Voice: (803) 799-1699 +// Fax: (803) 931-0320 +// Web: http://www.idvinc.com + +#pragma once + +//#include +//#include "Constants.h" +//#include "../Common Source/IdvVertexBuffer.h" + +#ifdef USE_SPEEDGRASS + + +// forward reference +class CIdvTerrain; + + +/////////////////////////////////////////////////////////////////////// +// class CSpeedGrassRT declaration + +class CSpeedGrassRT +{ +public: + CSpeedGrassRT( ); + virtual ~CSpeedGrassRT( ); + + + /////////////////////////////////////////////////////////////////////// + // struct SBlade + + struct SBlade + { + SBlade( ); + + // geometry + float m_afPos[3]; + float m_afNormal[3]; + float m_fSize; + unsigned char m_ucWhichTexture; + + // wind + float m_fNoise; + float m_fThrow; + + // color + float m_afBottomColor[3]; + float m_afTopColor[3]; + }; + + + /////////////////////////////////////////////////////////////////////// + // struct SRegion + + struct SRegion + { + SRegion( ); + + // dimensions + float m_afCenter[3]; + float m_afMin[3]; + float m_afMax[3]; + + // culling + bool m_bCulled; + float m_fCullingRadius; + + // grass/brush blades + std::vector m_vBlades; +// CIdvVertexBuffer* m_pVertexBuffer; + CGraphicVertexBuffer m_VertexBuffer; + }; + + void DeleteRegions(void); + const SRegion* GetRegions(unsigned int& uiNumRegions); + bool ParseBsfFile(const char* pFilename, unsigned int nNumBlades, unsigned int uiRows, unsigned int uiCols, float fCollisionDistance = 0.0f); + bool CustomPlacement(unsigned int uiRows, unsigned int uiCols); + + ////////////////////////////////////////////////////////////////////////// + // Utility +static void RotateAxisFromIdentity(D3DXMATRIX * pMat, const float & c_fAngle, const D3DXVECTOR3 & c_rv3Axis); + + /////////////////////////////////////////////////////////////////////// + // Geometry + +static const float* GetUnitBillboard(void) { return m_afUnitBillboard; } + + + /////////////////////////////////////////////////////////////////////// + // LOD + +static void GetLodParams(float& fFarDistance, float& fTransitionLength); +static void SetLodParams(float fFarDistance, float fTransitionLength); + + + /////////////////////////////////////////////////////////////////////// + // Culling + + bool AllRegionsAreCulled(void) const { return m_bAllRegionsCulled; } + void Cull(void); + + + /////////////////////////////////////////////////////////////////////// + // Wind + +static void SetWindDirection(const float* pWindDir); +static const float* GetWindDirection(void); + + + /////////////////////////////////////////////////////////////////////// + // Camera + +static const float* GetCameraPos(void); +static void SetCamera(const float* pPosition, const double* pModelviewMatrix); +static void SetPerspective(float fAspectRatio, float fFieldOfView); + + + /////////////////////////////////////////////////////////////////////// + // Terrain hugging + +virtual float Color(float fX, float fY, const float* pNormal, float* pTopColor, float* pBottomColor) const { return 0.0f; } +virtual float Height(float fX, float fY, float* pNormal) const { return 0.0f; } + +protected: + + void CreateRegions(const std::vector& vSceneBlades, float fCollisionDistance = 0.0f); +static void ComputeFrustum(void); +static void ComputeUnitBillboard(void); + void ConvertCoordsToCell(const float* pCoords, int* pGridCoords) const; + unsigned int GetRegionIndex(unsigned int uiRow, unsigned int uiCol) const { return uiRow * m_nNumRegionCols + uiCol; } +static bool OutsideFrustum(SRegion* pRegion); + + // general +static float m_fLodFarDistance; +static float m_fLodTransitionLength; +static float m_afUnitBillboard[12]; +static float m_afWindDir[4]; + + // regions + int m_nNumRegions; + int m_nNumRegionCols; + int m_nNumRegionRows; + SRegion* m_pRegions; + + // camera +static float m_afCameraOut[3]; +static float m_afCameraRight[3]; +static float m_afCameraUp[3]; +static float m_afCameraPos[3]; +static float m_fFieldOfView; +static float m_fAspectRatio; + + // culling +static float m_afFrustumBox[6]; +static float m_afFrustumMin[2]; +static float m_afFrustumMax[2]; +static float m_afFrustumPlanes[5][4]; + float m_afBoundingBox[6]; + bool m_bAllRegionsCulled; +}; + +extern float VecInterpolate(float fStart, float fEnd, float fPercent); +#endif // USE_SPEEDGRASS \ No newline at end of file diff --git a/source/SpeedTreeLib/SpeedGrassWrapper.cpp b/source/SpeedTreeLib/SpeedGrassWrapper.cpp new file mode 100644 index 0000000..dd9ede6 --- /dev/null +++ b/source/SpeedTreeLib/SpeedGrassWrapper.cpp @@ -0,0 +1,322 @@ +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassWrapper Class +// +// (c) 2003 IDV, Inc. +// +// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION *** +// +// This software is supplied under the terms of a license agreement or +// nondisclosure agreement with Interactive Data Visualization and may +// not be copied or disclosed except in accordance with the terms of +// that agreement. +// +// Copyright (c) 2001-2003 IDV, Inc. +// All Rights Reserved. +// +// IDV, Inc. +// 1233 Washington St. Suite 610 +// Columbia, SC 29201 +// Voice: (803) 799-1699 +// Fax: (803) 931-0320 +// Web: http://www.idvinc.com + +#include "StdAfx.h" + +#include +#include +#include +//#include "../Common Source/extgl.h" +//#include "SpeedGrassWrapper.h" +//#include "Scene.h" +//#include "../Common Source/nv_dds.h" +//#include "../Common Source/Random.h" +//#include "TextureLayers.h" + +using namespace std; + +#ifdef USE_SPEEDGRASS + + +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassWrapper::CSpeedGrassWrapper + +CSpeedGrassWrapper::CSpeedGrassWrapper() : m_pMapOutdoor(NULL), m_lpD3DTexure8(NULL)//m_uiTexture(0) +{ +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassWrapper::~CSpeedGrassWrapper + +CSpeedGrassWrapper::~CSpeedGrassWrapper( ) +{ +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassWrapper::Draw + +int CSpeedGrassWrapper::Draw(float fDensity) +{ + int nTriangleCount = 0; + +// // determine which regions are visible +// Cull( ); +// +// // setup opengl state +// glPushAttrib(GL_ENABLE_BIT); +// glDisable(GL_CULL_FACE); +// glDisable(GL_BLEND); +// +// glEnable(GL_TEXTURE_2D); +// glBindTexture(GL_TEXTURE_2D, m_uiTexture); +// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); +// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); +// +// glEnable(GL_ALPHA_TEST); +// glAlphaFunc(GL_GREATER, 0.4f); +// glDisable(GL_LIGHTING); +// +// unsigned int uiCount = 0; +// unsigned int uiNumRegions = 0; +// const SRegion* pRegions = GetRegions(uiNumRegions); +// +// // setup for vertex buffer rendering (enable client buffers) +// CIdvVertexBuffer::Enable(true); +// if (uiNumRegions > 0) +// pRegions[0].m_pVertexBuffer->EnableClientStates( ); +// +// // run through the regions and render those that aren't culled +// for (unsigned int i = 0; i < uiNumRegions; ++i) +// { +// if (!pRegions[i].m_bCulled) +// { +// pRegions[i].m_pVertexBuffer->Bind( ); +// unsigned int uiNumBlades = int(fDensity * pRegions[i].m_vBlades.size( )); +// glDrawArrays(GL_QUADS, 0, uiNumBlades * 4); +// nTriangleCount += uiNumBlades * 2; +// } +// } +// +// // disable client buffers +// if (uiNumRegions > 0) +// pRegions[0].m_pVertexBuffer->DisableClientStates( ); +// CIdvVertexBuffer::Disable(true); +// +// // restore opengl state +// glPopAttrib( ); + + return nTriangleCount; +} + +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassWrapper::InitFromBsfFile + +bool CSpeedGrassWrapper::InitFromBsfFile(const char* pFilename, + unsigned int nNumBlades, + unsigned int uiRows, + unsigned int uiCols, + float fCollisionDistance) +{ + bool bSuccess = false; + + if (pFilename) + { + // use SpeedGrass's built-in parse function + if (ParseBsfFile(pFilename, nNumBlades, uiRows, uiCols, fCollisionDistance)) + bSuccess = true; + } + InitGraphics( ); + + return bSuccess; +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassWrapper::Color + +float CSpeedGrassWrapper::Color(float fX, float fY, const float* pNormal, float* pTopColor, float* pBottomColor) const +{ + const float c_fColorAdjust = 0.3f; // controls how much the color of the top vertices of each grass blade can vary + const float c_fColorThrow = 1.0f; // controls how much the r, g, and b components can vary + const float c_fColorRandomness = 0.01f; // controls how much the r, g, and b components can vary + const float c_TopLight = 0.75f; + + float afLowColor[4] = { 0.0f }, afHighColor[4] = { 0.0f }; + if (m_pMapOutdoor->GetBrushColor(fX, fY, afLowColor, afHighColor)) + { + pBottomColor[0] = afLowColor[2]; + pBottomColor[1] = afLowColor[1]; + pBottomColor[2] = afLowColor[0]; + + float fColorThrow = GetRandom(0.0f, c_fColorThrow); + pTopColor[0] = VecInterpolate(pBottomColor[0], afHighColor[2], fColorThrow) + GetRandom(-c_fColorRandomness, c_fColorRandomness); + pTopColor[1] = VecInterpolate(pBottomColor[1], afHighColor[1], fColorThrow) + GetRandom(-c_fColorRandomness, c_fColorRandomness); + pTopColor[2] = VecInterpolate(pBottomColor[2], afHighColor[0], fColorThrow) + GetRandom(-c_fColorRandomness, c_fColorRandomness); + + float fLargest = pTopColor[0]; + if (pTopColor[1] > fLargest) + fLargest = pTopColor[1]; + if (pTopColor[2] > fLargest) + fLargest = pTopColor[2]; + if (fLargest > 1.0f) + { + pTopColor[0] /= fLargest; + pTopColor[1] /= fLargest; + pTopColor[2] /= fLargest; + } + pTopColor[0] = max(0.0f, pTopColor[0]); + pTopColor[1] = max(0.0f, pTopColor[1]); + pTopColor[2] = max(0.0f, pTopColor[2]); + } + + return afLowColor[3]; +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassWrapper::Height + +float CSpeedGrassWrapper::Height(float fX, float fY, float* pNormal) const +{ + float fHeight = 0.0f; + float afPos[3] = { fX, fY, 0.0f }; + fHeight = m_pMapOutdoor->GetHeight(afPos); + + pNormal[0] = 0.0f; + pNormal[1] = 0.0f; + pNormal[2] = 1.0f; + + return fHeight; +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassWrapper::InitGraphics + +void CSpeedGrassWrapper::InitGraphics(void) +{ + // load texture +// m_uiTexture = LoadDDS((c_strDataPath + string("brush_2.dds")).c_str( )); + CGraphicImage * pImage = (CGraphicImage *) CResourceManager::Instance().GetResourcePointer("D:/ymir work/special/brush_2.dds"); + m_GrassImageInstance.SetImagePointer(pImage); + m_lpD3DTexure8 = m_GrassImageInstance.GetTexturePointer()->GetD3DTexture(); + + // prepare static vertex buffers + for (int i = 0; i < m_nNumRegions; ++i) + { + SRegion* pRegion = m_pRegions + i; + +// pRegion->m_pVertexBuffer = new CIdvVertexBuffer; + + // setup up temporary buffer to copy later + const int c_nNumCorners = 4; + unsigned int uiNumBlades = pRegion->m_vBlades.size( ); + unsigned int uiBufferSize = uiNumBlades * c_nNumCorners * c_nGrassVertexTotalSize; + unsigned char* pBuffer = new unsigned char[uiBufferSize]; + + // setup initial pointers for individual attribute copying + float* pTexCoords0 = reinterpret_cast(pBuffer + 0); + float* pTexCoords1 = reinterpret_cast(pTexCoords0 + c_nGrassVertexTexture0Size * uiNumBlades * c_nNumCorners / sizeof(float)); + unsigned char* pColors = (unsigned char*) pTexCoords1 + c_nGrassVertexTexture1Size * uiNumBlades * c_nNumCorners; + float* pPositions = reinterpret_cast(pColors + c_nGrassVertexColorSize * uiNumBlades * c_nNumCorners); + + for (vector::const_iterator iBlade = pRegion->m_vBlades.begin( ); iBlade != pRegion->m_vBlades.end( ); ++iBlade) + { + float fS1 = float(iBlade->m_ucWhichTexture) / c_nNumBladeMaps; + float fS2 = float(iBlade->m_ucWhichTexture + 1) / c_nNumBladeMaps; + + for (int nCorner = 0; nCorner < c_nNumCorners; ++nCorner) + { + // texcoord 0 + switch (nCorner) + { + case 0: + pTexCoords0[0] = fS2; + pTexCoords0[1] = 1.0f; + break; + case 1: + pTexCoords0[0] = fS1; + pTexCoords0[1] = 1.0f; + break; + case 2: + pTexCoords0[0] = fS1; + pTexCoords0[1] = 0.0f; + break; + case 3: + pTexCoords0[0] = fS2; + pTexCoords0[1] = 0.0f; + break; + default: + assert(false); + } + pTexCoords0 += c_nGrassVertexTexture0Size / sizeof(float); + + // texcoord 1 + switch (nCorner) + { + case 0: + pTexCoords1[0] = c_nShaderGrassBillboard; + pTexCoords1[2] = iBlade->m_fThrow; + break; + case 1: + pTexCoords1[0] = c_nShaderGrassBillboard + 1; + pTexCoords1[2] = iBlade->m_fThrow; + break; + case 2: + pTexCoords1[0] = c_nShaderGrassBillboard + 2; + pTexCoords1[2] = 0.0f; + break; + case 3: + pTexCoords1[0] = c_nShaderGrassBillboard + 3; + pTexCoords1[2] = 0.0f; + break; + default: + assert(false); + } + // same for all corners + pTexCoords1[1] = iBlade->m_fSize; + pTexCoords1[3] = iBlade->m_fNoise; + pTexCoords1 += c_nGrassVertexTexture1Size / sizeof(float); + + // color + unsigned long ulColor = 0; + if (nCorner == 0 || nCorner == 1) + ulColor = (int(iBlade->m_afTopColor[0] * 255.0f) << 0) + + (int(iBlade->m_afTopColor[1] * 255.0f) << 8) + + (int(iBlade->m_afTopColor[2] * 255.0f) << 16) + + 0xff000000; + else + ulColor = (int(iBlade->m_afBottomColor[0] * 255.0f) << 0) + + (int(iBlade->m_afBottomColor[1] * 255.0f) << 8) + + (int(iBlade->m_afBottomColor[2] * 255.0f) << 16) + + 0xff000000; + memcpy(pColors, &ulColor, c_nGrassVertexColorSize); + pColors += c_nGrassVertexColorSize; + + // position + memcpy(pPositions, iBlade->m_afPos, c_nGrassVertexPositionSize); + pPositions += c_nGrassVertexPositionSize / sizeof(float); + } + } + +// assert((unsigned char*) pTexCoords0 - pBuffer == c_nGrassVertexTexture0Size * uiNumBlades * c_nNumCorners); +// assert(pTexCoords1 - pTexCoords0 == (c_nGrassVertexTexture1Size * uiNumBlades * c_nNumCorners) / sizeof(float)); +// assert(pColors - (unsigned char*) pTexCoords1 == c_nGrassVertexColorSize * uiNumBlades * c_nNumCorners); +// assert((unsigned char*) pPositions - pColors == c_nGrassVertexPositionSize * uiNumBlades * c_nNumCorners); + +// pRegion->m_pVertexBuffer->SetBuffer(pBuffer, uiBufferSize, true); +// pRegion->m_pVertexBuffer->SetStride(CIdvVertexBuffer::VERTEX_TEXCOORD0, 2, GL_FLOAT, 0, 0); +// pRegion->m_pVertexBuffer->SetStride(CIdvVertexBuffer::VERTEX_TEXCOORD1, 4, GL_FLOAT, 0, (unsigned char*) pTexCoords0 - pBuffer); +// pRegion->m_pVertexBuffer->SetStride(CIdvVertexBuffer::VERTEX_COLOR, 4, GL_UNSIGNED_BYTE, 0, (unsigned char*) pTexCoords1 - pBuffer); +// pRegion->m_pVertexBuffer->SetStride(CIdvVertexBuffer::VERTEX_POSITION, 3, GL_FLOAT, 0, pColors - pBuffer); + + DWORD dwFVF = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1; +// pRegion->m_VertexBuffer.Create(); + + delete[] pBuffer; + } +} + +#endif // USE_SPEEDGRASS + diff --git a/source/SpeedTreeLib/SpeedGrassWrapper.h b/source/SpeedTreeLib/SpeedGrassWrapper.h new file mode 100644 index 0000000..5bcf73d --- /dev/null +++ b/source/SpeedTreeLib/SpeedGrassWrapper.h @@ -0,0 +1,64 @@ +/////////////////////////////////////////////////////////////////////// +// CSpeedGrassWrapper Class +// +// (c) 2003 IDV, Inc. +// +// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION *** +// +// This software is supplied under the terms of a license agreement or +// nondisclosure agreement with Interactive Data Visualization and may +// not be copied or disclosed except in accordance with the terms of +// that agreement. +// +// Copyright (c) 2001-2003 IDV, Inc. +// All Rights Reserved. +// +// IDV, Inc. +// 1233 Washington St. Suite 610 +// Columbia, SC 29201 +// Voice: (803) 799-1699 +// Fax: (803) 931-0320 +// Web: http://www.idvinc.com + + +#pragma once +//#include "SpeedGrassRT.h" +#ifdef USE_SPEEDGRASS +//#include "../Common Source/IdvVertexBuffer.h" +//#include + +// forward reference +//class CScene; +class CMapOutdoor; + + +/////////////////////////////////////////////////////////////////////// +// class CSpeedGrassWrapper declaration + +class CSpeedGrassWrapper : public CSpeedGrassRT +{ +public: + CSpeedGrassWrapper( ); + virtual ~CSpeedGrassWrapper( ); + + void SetMapOutdoor(CMapOutdoor* pMapOutdoor) { m_pMapOutdoor = pMapOutdoor; } + int Draw(float fDensity); + bool InitFromBsfFile(const char* pFilename, + unsigned int nNumBlades, + unsigned int uiRows, + unsigned int uiCols, + float fCollisionDistance); + +private: +virtual float Color(float fX, float fY, const float* pNormal, float* pTopColor, float* pBottomColor) const; +virtual float Height(float fX, float fY, float* pNormal) const; + void InitGraphics(void); + + CMapOutdoor * m_pMapOutdoor; + + LPDIRECT3DTEXTURE8 m_lpD3DTexure8; + + CGraphicImageInstance m_GrassImageInstance; +}; + +#endif // USE_SPEEDGRASS diff --git a/source/SpeedTreeLib/SpeedTreeConfig.h b/source/SpeedTreeLib/SpeedTreeConfig.h new file mode 100644 index 0000000..9a0f86f --- /dev/null +++ b/source/SpeedTreeLib/SpeedTreeConfig.h @@ -0,0 +1,120 @@ +/////////////////////////////////////////////////////////////////////// +// SpeedTreeRT runtime configuration #defines +// +// (c) 2003 IDV, Inc. +// +// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION *** +// +// This software is supplied under the terms of a license agreement or +// nondisclosure agreement with Interactive Data Visualization and may +// not be copied or disclosed except in accordance with the terms of +// that agreement. +// +// Copyright (c) 2001-2003 IDV, Inc. +// All Rights Reserved. +// +// IDV, Inc. +// 1233 Washington St. Suite 610 +// Columbia, SC 29201 +// Voice: (803) 799-1699 +// Fax: (803) 931-0320 +// Web: http://www.idvinc.com + +#pragma once + +const int c_nNumWindMatrices = 4; +const int c_nNumInstancesPerModel = 10; +const float c_fForestSize = 200.0f; +const float c_fSpacingTolerance = 30.0f; +const int c_nMaxPlacementIterations = 500; +const int c_nDefaultAlphaTestValue = 84; +const float c_fNearLodFactor = 2.0f; +const float c_fFarLodFactor = 9.0f; +const float c_fBenchmarkPeriod = 1.0f; + +// vertex shader constant locations +const int c_nVertexShader_LeafLightingAdjustment = 70; +const int c_nVertexShader_Light = 71; +const int c_nVertexShader_Material = 74; +const int c_nVertexShader_TreePos = 52; +const int c_nVertexShader_CompoundMatrix = 0; +const int c_nVertexShader_WindMatrices = 54; +const int c_nVertexShader_LeafTables = 4; +const int c_nVertexShader_Fog = 85; + +// lighting +const float c_afLightPosition[4] = { -0.707f, 0.0f, 0.707f, 0.0f }; +const float c_afLightAmbient[4] = { 0.5f, 0.5f, 0.5f, 1.0f }; +const float c_afLightDiffuse[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; +const float c_afLightSpecular[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; +const float c_afLightGlobalAmbient[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; + + +// setup lighting (enable ONE of the two below) +#define WRAPPER_USE_STATIC_LIGHTING +//#define WRAPPER_USE_DYNAMIC_LIGHTING + +#if defined WRAPPER_USE_STATIC_LIGHTING && defined WRAPPER_USE_DYNAMIC_LIGHTING + #error Please define exactly one lighting mode +#endif + +// setup wind (enable ONE of the three below) +//#define WRAPPER_USE_GPU_WIND +//#define WRAPPER_USE_CPU_WIND +#define WRAPPER_USE_NO_WIND + +#if defined WRAPPER_USE_GPU_WIND && defined WRAPPER_USE_CPU_WIND + #error Please define exactly one lighting mode +#elif defined WRAPPER_USE_GPU_WIND && defined WRAPPER_USE_NO_WIND + #error Please define exactly one lighting mode +#elif defined WRAPPER_USE_CPU_WIND && defined WRAPPER_USE_NO_WIND + #error Please define exactly one lighting mode +#endif + +// leaf placement algorithm (enable ONE of the two below) +//#define WRAPPER_USE_GPU_LEAF_PLACEMENT +#define WRAPPER_USE_CPU_LEAF_PLACEMENT + +#if defined WRAPPER_USE_GPU_LEAF_PLACEMENT && defined WRAPPER_USE_CPU_LEAF_PLACEMENT + #error Please define exactly one leaf placement algorithm +#endif + +// texture coordinates (enable this define for DirectX-based engines) +#define WRAPPER_FLIP_T_TEXCOORD + +// up vector +//#define WRAPPER_UP_POS_Y +#define WRAPPER_UP_POS_Z + +#if defined WRAPPER_UP_POS_Y && defined WRAPPER_UP_POS_Z + #error Please define exactly one up vector +#endif + +// loading from STF or clones/instances? (enable ONE of the two below) +//#define WRAPPER_FOREST_FROM_STF +#define WRAPPER_FOREST_FROM_INSTANCES + +#if defined WRAPPER_FOREST_FROM_STF && defined WRAPPER_FOREST_FROM_INSTANCES + #error Please define exactly one loading mechanism +#endif + +// billboard modes +#define WRAPPER_BILLBOARD_MODE +//#define WRAPPER_RENDER_HORIZONTAL_BILLBOARD + +// render self-shadows +#define WRAPPER_RENDER_SELF_SHADOWS + +// use fog +#define WRAPPER_USE_FOG + +// derived constants +#ifdef WRAPPER_USE_GPU_WIND + #define BRANCHES_USE_SHADERS + #define FRONDS_USE_SHADERS + #define LEAVES_USE_SHADERS +#endif + +#ifdef WRAPPER_USE_GPU_LEAF_PLACEMENT + #define LEAVES_USE_SHADERS +#endif diff --git a/source/SpeedTreeLib/SpeedTreeForest.cpp b/source/SpeedTreeLib/SpeedTreeForest.cpp new file mode 100644 index 0000000..b7342de --- /dev/null +++ b/source/SpeedTreeLib/SpeedTreeForest.cpp @@ -0,0 +1,316 @@ +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeForest Class + +/////////////////////////////////////////////////////////////////////// +// Include Files +#include "StdAfx.h" + +#include +#include "../eterBase/Filename.h" +#include "../eterBase/MappedFile.h" +#include "../eterPack/EterPackManager.h" + +#include "SpeedTreeForest.h" +#include "SpeedTreeConfig.h" +#include + +using namespace std; + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeForest constructor + +CSpeedTreeForest::CSpeedTreeForest() : m_fWindStrength(0.0f) +{ + CSpeedTreeRT::SetNumWindMatrices(c_nNumWindMatrices); + + m_afForestExtents[0] = m_afForestExtents[1] = m_afForestExtents[2] = FLT_MAX; + m_afForestExtents[3] = m_afForestExtents[4] = m_afForestExtents[5] = -FLT_MAX; +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeForest destructor + +CSpeedTreeForest::~CSpeedTreeForest() +{ + Clear(); +} + +void CSpeedTreeForest::Clear() +{ + TTreeMap::iterator itor = m_pMainTreeMap.begin(); + UINT uiCount; + + while (itor != m_pMainTreeMap.end()) + { + CSpeedTreeWrapper * pMainTree = (itor++)->second; + CSpeedTreeWrapper ** ppInstances = pMainTree->GetInstances(uiCount); + + for (UINT i = 0; i < uiCount; ++i) + delete ppInstances[i]; + + delete pMainTree; + } + + m_pMainTreeMap.clear(); +} + +CSpeedTreeWrapper * CSpeedTreeForest::GetMainTree(DWORD dwCRC) +{ + TTreeMap::iterator itor = m_pMainTreeMap.find(dwCRC); + + if (itor == m_pMainTreeMap.end()) + return NULL; + + return itor->second; +} + +BOOL CSpeedTreeForest::GetMainTree(DWORD dwCRC, CSpeedTreeWrapper ** ppMainTree, const char * c_pszFileName) +{ + TTreeMap::iterator itor = m_pMainTreeMap.find(dwCRC); + + CSpeedTreeWrapper * pTree; + + if (itor != m_pMainTreeMap.end()) + pTree = itor->second; + else + { + CMappedFile file; + LPCVOID c_pvData; + + // NOTE : return FALSE ƴѰ? - [levites] + if (!CEterPackManager::Instance().Get(file, c_pszFileName, &c_pvData)) + return FALSE; + + pTree = new CSpeedTreeWrapper; + + if (!pTree->LoadTree(c_pszFileName, (const BYTE *) c_pvData, file.Size())) + { + delete pTree; + return FALSE; + } + + m_pMainTreeMap.insert(std::map::value_type(dwCRC, pTree)); + + file.Destroy(); + } + + *ppMainTree = pTree; + return TRUE; +} + +CSpeedTreeWrapper* CSpeedTreeForest::CreateInstance(float x, float y, float z, DWORD dwTreeCRC, const char * c_szTreeName) +{ + CSpeedTreeWrapper * pMainTree; + if (!GetMainTree(dwTreeCRC, &pMainTree, c_szTreeName)) + return NULL; + + CSpeedTreeWrapper* pTreeInst = pMainTree->MakeInstance(); + pTreeInst->SetPosition(x, y, z); + pTreeInst->RegisterBoundingSphere(); + return pTreeInst; +} + +void CSpeedTreeForest::DeleteInstance(CSpeedTreeWrapper * pInstance) +{ + if (!pInstance) + return; + + CSpeedTreeWrapper * pParentTree = pInstance->InstanceOf(); + + if (!pParentTree) + return; + + pParentTree->DeleteInstance(pInstance); +} + +void CSpeedTreeForest::UpdateSystem(float fCurrentTime) +{ + // Ʈ ѹ + static float fLastTime = fCurrentTime; + float fElapsedTime = fCurrentTime - fLastTime; + CSpeedTreeRT::SetTime(fElapsedTime); + + m_fAccumTime += fElapsedTime; + SetupWindMatrices(m_fAccumTime); +} + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeForest::AdjustExtents +void CSpeedTreeForest::AdjustExtents(float x, float y, float z) +{ + // min + m_afForestExtents[0] = __min(m_afForestExtents[0], x); + m_afForestExtents[1] = __min(m_afForestExtents[1], y); + m_afForestExtents[2] = __min(m_afForestExtents[2], z); + + // max + m_afForestExtents[3] = __max(m_afForestExtents[3], x); + m_afForestExtents[4] = __max(m_afForestExtents[4], y); + m_afForestExtents[5] = __max(m_afForestExtents[5], z); +} + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeForest::SetWindStrength +void CSpeedTreeForest::SetWindStrength(float fStrength) +{ + if (m_fWindStrength == fStrength) + return; + + m_fWindStrength = fStrength; + + TTreeMap::iterator itor = m_pMainTreeMap.begin(); + UINT uiCount; + + while (itor != m_pMainTreeMap.end()) + { + CSpeedTreeWrapper * pMainTree = (itor++)->second; + CSpeedTreeWrapper ** ppInstances = pMainTree->GetInstances(uiCount); + + for (UINT i = 0; i < uiCount; ++i) + ppInstances[i]->GetSpeedTree()->SetWindStrength(m_fWindStrength); + } +} + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeForest::SetupWindMatrices +void CSpeedTreeForest::SetupWindMatrices(float fTimeInSecs) +{ + // matrix computational data + static float afMatrixTimes[c_nNumWindMatrices] = { 0.0f }; + static float afFrequencies[c_nNumWindMatrices][2] = + { + { 0.15f, 0.17f }, + { 0.25f, 0.15f }, + { 0.19f, 0.05f }, + { 0.15f, 0.22f } + }; + + // compute time since last call + static float fTimeOfLastCall = 0.0f; + float fTimeSinceLastCall = fTimeInSecs - fTimeOfLastCall; + fTimeOfLastCall = fTimeInSecs; + + // wind strength + static float fOldStrength = m_fWindStrength; + + // increment matrix times + for (int i = 0; i < c_nNumWindMatrices; ++i) + afMatrixTimes[i] += fTimeSinceLastCall; + + // compute maximum branch throw + float fBaseAngle = m_fWindStrength * 35.0f; + + // build rotation matrices + for (int j = 0; j < c_nNumWindMatrices; ++j) + { + // adjust time to prevent "jumping" + if (m_fWindStrength != 0.0f) + afMatrixTimes[j] = (afMatrixTimes[j] * fOldStrength) / m_fWindStrength; + + // compute percentages for each axis + float fBaseFreq = m_fWindStrength * 20.0f; + float fXPercent = sinf(fBaseFreq * afFrequencies[j % c_nNumWindMatrices][0] * afMatrixTimes[j]); + float fYPercent = cosf(fBaseFreq * afFrequencies[j % c_nNumWindMatrices][1] * afMatrixTimes[j]); + + // build compound rotation matrix (rotate on 'x' then on 'y') + const float c_fDeg2Rad = 57.2957795f; + float fSinX = sinf(fBaseAngle * fXPercent / c_fDeg2Rad); + float fSinY = sinf(fBaseAngle * fYPercent / c_fDeg2Rad); + float fCosX = cosf(fBaseAngle * fXPercent / c_fDeg2Rad); + float fCosY = cosf(fBaseAngle * fYPercent / c_fDeg2Rad); + + float afMatrix[16] = { 0.0f }; + afMatrix[0] = fCosY; + afMatrix[2] = -fSinY; + afMatrix[4] = fSinX * fSinY; + afMatrix[5] = fCosX; + afMatrix[6] = fSinX * fCosY; + afMatrix[8] = fSinY * fCosX; + afMatrix[9] = -fSinX; + afMatrix[10] = fCosX * fCosY; + afMatrix[15] = 1.0f; + + #ifdef WRAPPER_USE_CPU_WIND + CSpeedTreeRT::SetWindMatrix(j, afMatrix); + #endif + + #ifdef WRAPPER_USE_GPU_WIND + // graphics API specific + UploadWindMatrix(c_nVertexShader_WindMatrices + j * 4, afMatrix); + #endif + } + + // track wind strength + fOldStrength = m_fWindStrength; +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeForest::SetLodLimits +/* +void CSpeedTreeForest::SetLodLimits(void) +{ + // find tallest tree + float fTallest = -1.0f; + + TTreeMap::iterator itor = m_pMainTreeMap.begin(); + UINT uiCount; + + while (itor != m_pMainTreeMap.end()) + { + CSpeedTreeWrapper * pMainTree = (itor++)->second; + CSpeedTreeWrapper ** ppInstances = pMainTree->GetInstances(uiCount); + + float fHeight; + fHeight = pMainTree->GetBoundingBox()[5] - pMainTree->GetBoundingBox()[0]; + fTallest = __max(fHeight, fTallest); + + for (UINT i = 0; i < uiCount; ++i) + { + fHeight = ppInstances[i]->GetBoundingBox()[5] - ppInstances[i]->GetBoundingBox()[0]; + fTallest = __max(fHeight, fTallest); + } + } + + itor = m_pMainTreeMap.begin(); + + while (itor != m_pMainTreeMap.end()) + { + CSpeedTreeWrapper * pMainTree = (itor++)->second; + CSpeedTreeWrapper ** ppInstances = pMainTree->GetInstances(uiCount); + + pMainTree->GetSpeedTree()->SetLodLimits(fTallest * c_fNearLodFactor, fTallest * c_fFarLodFactor); + + for (UINT i = 0; i < uiCount; ++i) + ppInstances[i]->GetSpeedTree()->SetLodLimits(fTallest * c_fNearLodFactor, fTallest * c_fFarLodFactor); + } +} +*/ +void CSpeedTreeForest::SetLight(const float * afDirection, const float * afAmbient, const float * afDiffuse) +{ + m_afLighting[0] = afDirection[0]; + m_afLighting[1] = afDirection[1]; + m_afLighting[2] = afDirection[2]; + m_afLighting[3] = 1.0f; + + m_afLighting[4] = afAmbient[0]; + m_afLighting[5] = afAmbient[1]; + m_afLighting[6] = afAmbient[2]; + m_afLighting[7] = afAmbient[3]; + + m_afLighting[8] = afDiffuse[0]; + m_afLighting[9] = afDiffuse[1]; + m_afLighting[10] = afDiffuse[2]; + m_afLighting[11] = afDiffuse[3]; +} + +void CSpeedTreeForest::SetFog(float fFogNear, float fFogFar) +{ + const float c_fFogLinearScale = (1.0f / (fFogFar - fFogNear)); + + m_afFog[0] = fFogNear; + m_afFog[1] = fFogFar; + m_afFog[2] = c_fFogLinearScale; + m_afFog[3] = 0.0f; +} diff --git a/source/SpeedTreeLib/SpeedTreeForest.h b/source/SpeedTreeLib/SpeedTreeForest.h new file mode 100644 index 0000000..e4bd382 --- /dev/null +++ b/source/SpeedTreeLib/SpeedTreeForest.h @@ -0,0 +1,108 @@ +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeForest Class +// +// (c) 2003 IDV, Inc. +// +// This class is provided to illustrate one way to incorporate +// SpeedTreeRT into an OpenGL application. All of the SpeedTreeRT +// calls that must be made on a per tree basis are done by this class. +// Calls that apply to all trees (i.e. static SpeedTreeRT functions) +// are made in the functions in main.cpp. +// +// +// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION *** +// +// This software is supplied under the terms of a license agreement or +// nondisclosure agreement with Interactive Data Visualization and may +// not be copied or disclosed except in accordance with the terms of +// that agreement. +// +// Copyright (c) 2001-2003 IDV, Inc. +// All Rights Reserved. +// +// IDV, Inc. +// 1233 Washington St. Suite 610 +// Columbia, SC 29201 +// Voice: (803) 799-1699 +// Fax: (803) 931-0320 +// Web: http://www.idvinc.com + +#pragma once + + +/////////////////////////////////////////////////////////////////////// +// Include Files +#include +#include "SpeedTreeWrapper.h" + +#include +#include + +/////////////////////////////////////////////////////////////////////// +// Render bit vector + +#define Forest_RenderBranches (1 << 0) +#define Forest_RenderLeaves (1 << 1) +#define Forest_RenderFronds (1 << 2) +#define Forest_RenderBillboards (1 << 3) +#define Forest_RenderAll ((1 << 4) - 1) +#define Forest_RenderToShadow (1 << 5) +#define Forest_RenderToMiniMap (1 << 6) + +/////////////////////////////////////////////////////////////////////// +// class CSpeedTreeForest declaration + +class CSpeedTreeForest +{ + public: + typedef std::map TTreeMap; + + public: + CSpeedTreeForest(); + virtual ~CSpeedTreeForest(); + + void ClearMainTree(); + + + BOOL GetMainTree(DWORD dwCRC, CSpeedTreeWrapper ** ppMainTree, const char * c_pszFileName); + CSpeedTreeWrapper * GetMainTree(DWORD dwCRC); + void DeleteMainTree(DWORD dwCRC); + + CSpeedTreeWrapper * CreateInstance(float x, float y, float z, DWORD dwTreeCRC, const char * c_pszTreeName); + void DeleteInstance(CSpeedTreeWrapper * pTree); + + //void SetLodLimits(void); + + void UpdateSystem(float fCurrentTime); + + void Clear(); + + void SetLight(const float * afDirection, const float * afAmbient, const float * afDiffuse); + void SetFog(float fFogNear, float fFogFar); + ////////////////////////////////////////////////////////////////////////// + + const float * GetExtents(void) const { return m_afForestExtents; } + + // wind management + float GetWindStrength(void) const { return m_fWindStrength; } + void SetWindStrength(float fStrength); + void SetupWindMatrices(float fTimeInSecs); + + // overridden by specific graphics API + virtual void UploadWindMatrix(unsigned int uiLocation, const float* pMatrix) const = 0; + virtual void Render(unsigned long ulRenderBitVector) = 0; + + protected: + TTreeMap m_pMainTreeMap; + + float m_afLighting[12]; + float m_afFog[4]; + + private: + void AdjustExtents(float x, float y, float z); + + float m_afForestExtents[6]; // [0] = min x, [1] = min y..., [3] = max x, [4] = max y... + float m_fWindStrength; // 0.0 = no wind, 1.0 = full strength + + float m_fAccumTime; +}; diff --git a/source/SpeedTreeLib/SpeedTreeForestDirectX8.cpp b/source/SpeedTreeLib/SpeedTreeForestDirectX8.cpp new file mode 100644 index 0000000..1b2e3a1 --- /dev/null +++ b/source/SpeedTreeLib/SpeedTreeForestDirectX8.cpp @@ -0,0 +1,344 @@ +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeForestDirectX8 Class +// +// (c) 2003 IDV, Inc. +// +// This class is provided to illustrate one way to incorporate +// SpeedTreeRT into an OpenGL application. All of the SpeedTreeRT +// calls that must be made on a per tree basis are done by this class. +// Calls that apply to all trees (i.e. static SpeedTreeRT functions) +// are made in the functions in main.cpp. +// +// +// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION *** +// +// This software is supplied under the terms of a license agreement or +// nondisclosure agreement with Interactive Data Visualization and may +// not be copied or disclosed except in accordance with the terms of +// that agreement. +// +// Copyright (c) 2001-2003 IDV, Inc. +// All Rights Reserved. +// +// IDV, Inc. +// 1233 Washington St. Suite 610 +// Columbia, SC 29201 +// Voice: (803) 799-1699 +// Fax: (803) 931-0320 +// Web: http://www.idvinc.com + +#include "StdAfx.h" + +#include +#include +#include +#include + +#include "../eterBase/Timer.h" +#include "../eterlib/StateManager.h" +#include "../eterlib/Camera.h" + +#include "SpeedTreeForestDirectX8.h" +#include "SpeedTreeConfig.h" +#include "VertexShaders.h" + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeForestDirectX8::CSpeedTreeForestDirectX8 + +CSpeedTreeForestDirectX8::CSpeedTreeForestDirectX8() : m_dwBranchVertexShader(0), m_dwLeafVertexShader(0) +{ +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeForestDirectX8::~CSpeedTreeForestDirectX8 + +CSpeedTreeForestDirectX8::~CSpeedTreeForestDirectX8() +{ +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeForestDirectX8::InitVertexShaders +bool CSpeedTreeForestDirectX8::InitVertexShaders(void) +{ + NANOBEGIN + // load the vertex shaders + if (!m_dwBranchVertexShader) + m_dwBranchVertexShader = LoadBranchShader(m_pDx); + + if (!m_dwLeafVertexShader) + m_dwLeafVertexShader = LoadLeafShader(m_pDx); + + if (m_dwBranchVertexShader && m_dwLeafVertexShader) + { + CSpeedTreeWrapper::SetVertexShaders(m_dwBranchVertexShader, m_dwLeafVertexShader); + return true; + } + + NANOEND + return false; +} + +bool CSpeedTreeForestDirectX8::SetRenderingDevice(LPDIRECT3DDEVICE8 lpDevice) +{ + m_pDx = lpDevice; + + if (!InitVertexShaders()) + return false; + + const float c_afLightPosition[4] = { -0.707f, -0.300f, 0.707f, 0.0f }; + const float c_afLightAmbient[4] = { 0.5f, 0.5f, 0.5f, 1.0f }; + const float c_afLightDiffuse[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + const float c_afLightSpecular[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + + float afLight1[] = + { + c_afLightPosition[0], c_afLightPosition[1], c_afLightPosition[2], // pos + c_afLightDiffuse[0], c_afLightDiffuse[1], c_afLightDiffuse[2], // diffuse + c_afLightAmbient[0], c_afLightAmbient[1], c_afLightAmbient[2], // ambient + c_afLightSpecular[0], c_afLightSpecular[1], c_afLightSpecular[2], // specular + c_afLightPosition[3], // directional flag + 1.0f, 0.0f, 0.0f // attenuation (constant, linear, quadratic) + }; + + CSpeedTreeRT::SetNumWindMatrices(c_nNumWindMatrices); + + CSpeedTreeRT::SetLightAttributes(0, afLight1); + CSpeedTreeRT::SetLightState(0, true); + return true; +} + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeForestDirectX8::UploadWindMatrix + +void CSpeedTreeForestDirectX8::UploadWindMatrix(UINT uiLocation, const float* pMatrix) const +{ + STATEMANAGER.SetVertexShaderConstant(uiLocation, pMatrix, 4); +} + +void CSpeedTreeForestDirectX8::UpdateCompundMatrix(const D3DXVECTOR3 & c_rEyeVec, const D3DXMATRIX & c_rmatView, const D3DXMATRIX & c_rmatProj) +{ + // setup composite matrix for shader + D3DXMATRIX matBlend; + D3DXMatrixIdentity(&matBlend); + + D3DXMATRIX matBlendShader; + D3DXMatrixMultiply(&matBlendShader, &c_rmatView, &c_rmatProj); + + float afDirection[3]; + afDirection[0] = matBlendShader.m[0][2]; + afDirection[1] = matBlendShader.m[1][2]; + afDirection[2] = matBlendShader.m[2][2]; + CSpeedTreeRT::SetCamera(c_rEyeVec, afDirection); + + D3DXMatrixTranspose(&matBlendShader, &matBlendShader); + STATEMANAGER.SetVertexShaderConstant(c_nVertexShader_CompoundMatrix, &matBlendShader, 4); +} + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeForestDirectX8::Render + +void CSpeedTreeForestDirectX8::Render(unsigned long ulRenderBitVector) +{ + UpdateSystem(CTimer::Instance().GetCurrentSecond()); + + if (m_pMainTreeMap.empty()) + return; + + if (!(ulRenderBitVector & Forest_RenderToShadow) && !(ulRenderBitVector & Forest_RenderToMiniMap)) + UpdateCompundMatrix(CCameraManager::Instance().GetCurrentCamera()->GetEye(), ms_matView, ms_matProj); + + DWORD dwLightState = STATEMANAGER.GetRenderState(D3DRS_LIGHTING); + DWORD dwColorVertexState = STATEMANAGER.GetRenderState(D3DRS_COLORVERTEX); + DWORD dwFogVertexMode = STATEMANAGER.GetRenderState(D3DRS_FOGVERTEXMODE); + +#ifdef WRAPPER_USE_DYNAMIC_LIGHTING + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, TRUE); +#else + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); + STATEMANAGER.SetRenderState(D3DRS_COLORVERTEX, TRUE); +#endif + + TTreeMap::iterator itor; + UINT uiCount; + + itor = m_pMainTreeMap.begin(); + + while (itor != m_pMainTreeMap.end()) + { + CSpeedTreeWrapper * pMainTree = (itor++)->second; + CSpeedTreeWrapper ** ppInstances = pMainTree->GetInstances(uiCount); + + for (UINT i = 0; i < uiCount; ++i) + { + ppInstances[i]->Advance(); + } + } + + STATEMANAGER.SetVertexShaderConstant(c_nVertexShader_Light, m_afLighting, 3); + STATEMANAGER.SetVertexShaderConstant(c_nVertexShader_Fog, m_afFog, 1); + + if (ulRenderBitVector & Forest_RenderToShadow) + { + //STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + } + else + { + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + STATEMANAGER.SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + STATEMANAGER.SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); + + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); + } + + STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER); + STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_CW); + + // set up fog if it is enabled + if (STATEMANAGER.GetRenderState(D3DRS_FOGENABLE)) + { + #ifdef WRAPPER_USE_GPU_WIND + STATEMANAGER.SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_NONE); // GPU needs to work on all cards + #endif + } + + // choose fixed function pipeline or custom shader for fronds and branches + STATEMANAGER.SetVertexShader(m_dwBranchVertexShader); + + // render branches + if (ulRenderBitVector & Forest_RenderBranches) + { + itor = m_pMainTreeMap.begin(); + + while (itor != m_pMainTreeMap.end()) + { + CSpeedTreeWrapper * pMainTree = (itor++)->second; + CSpeedTreeWrapper ** ppInstances = pMainTree->GetInstances(uiCount); + + pMainTree->SetupBranchForTreeType(); + + for (UINT i = 0; i < uiCount; ++i) + if (ppInstances[i]->isShow()) + ppInstances[i]->RenderBranches(); + } + } + + // set render states + STATEMANAGER.SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + + // render fronds + if (ulRenderBitVector & Forest_RenderFronds) + { + itor = m_pMainTreeMap.begin(); + + while (itor != m_pMainTreeMap.end()) + { + CSpeedTreeWrapper * pMainTree = (itor++)->second; + CSpeedTreeWrapper ** ppInstances = pMainTree->GetInstances(uiCount); + + pMainTree->SetupFrondForTreeType(); + + for (UINT i = 0; i < uiCount; ++i) + if (ppInstances[i]->isShow()) + ppInstances[i]->RenderFronds(); + } + } + + // render leaves + if (ulRenderBitVector & Forest_RenderLeaves) + { + STATEMANAGER.SetVertexShader(m_dwLeafVertexShader); + + if (STATEMANAGER.GetRenderState(D3DRS_FOGENABLE)) + { + #if defined WRAPPER_USE_GPU_WIND || defined WRAPPER_USE_GPU_LEAF_PLACEMENT + STATEMANAGER.SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_NONE); + #endif + } + + if (ulRenderBitVector & Forest_RenderToShadow || ulRenderBitVector & Forest_RenderToMiniMap) + { + STATEMANAGER.SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_NOTEQUAL); + STATEMANAGER.SaveRenderState(D3DRS_ALPHAREF, 0x00000000); + } + + itor = m_pMainTreeMap.begin(); + + while (itor != m_pMainTreeMap.end()) + { + CSpeedTreeWrapper * pMainTree = (itor++)->second; + CSpeedTreeWrapper ** ppInstances = pMainTree->GetInstances(uiCount); + + pMainTree->SetupLeafForTreeType(); + + for (UINT i = 0; i < uiCount; ++i) + if (ppInstances[i]->isShow()) + ppInstances[i]->RenderLeaves(); + } + + while (itor != m_pMainTreeMap.end()) + (itor++)->second->EndLeafForTreeType(); + + if (ulRenderBitVector & Forest_RenderToShadow || ulRenderBitVector & Forest_RenderToMiniMap) + { + STATEMANAGER.SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHAREF); + } + } + + // render billboards + #ifndef WRAPPER_NO_BILLBOARD_MODE + if (ulRenderBitVector & Forest_RenderBillboards) + { + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); + STATEMANAGER.SetRenderState(D3DRS_COLORVERTEX, FALSE); + + itor = m_pMainTreeMap.begin(); + + while (itor != m_pMainTreeMap.end()) + { + CSpeedTreeWrapper * pMainTree = (itor++)->second; + CSpeedTreeWrapper ** ppInstances = pMainTree->GetInstances(uiCount); + + pMainTree->SetupBranchForTreeType(); + + for (UINT i = 0; i < uiCount; ++i) + if (ppInstances[i]->isShow()) + ppInstances[i]->RenderBillboards(); + } + } + #endif + + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, dwLightState); + STATEMANAGER.SetRenderState(D3DRS_COLORVERTEX, dwColorVertexState); + STATEMANAGER.SetRenderState(D3DRS_FOGVERTEXMODE, dwFogVertexMode); + + // TextureStage 1 COLOROP ALPHAOP + // ´. (ȱ׷ ˰ ɼ..) + if (!(ulRenderBitVector & Forest_RenderToShadow)) + { + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + } + + STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHAFUNC); + STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE); +} + diff --git a/source/SpeedTreeLib/SpeedTreeForestDirectX8.h b/source/SpeedTreeLib/SpeedTreeForestDirectX8.h new file mode 100644 index 0000000..186d00d --- /dev/null +++ b/source/SpeedTreeLib/SpeedTreeForestDirectX8.h @@ -0,0 +1,64 @@ +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeForestOpenGL Class +// +// (c) 2003 IDV, Inc. +// +// This class is provided to illustrate one way to incorporate +// SpeedTreeRT into an OpenGL application. All of the SpeedTreeRT +// calls that must be made on a per tree basis are done by this class. +// Calls that apply to all trees (i.e. static SpeedTreeRT functions) +// are made in the functions in main.cpp. +// +// +// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION *** +// +// This software is supplied under the terms of a license agreement or +// nondisclosure agreement with Interactive Data Visualization and may +// not be copied or disclosed except in accordance with the terms of +// that agreement. +// +// Copyright (c) 2001-2003 IDV, Inc. +// All Rights Reserved. +// +// IDV, Inc. +// 1233 Washington St. Suite 610 +// Columbia, SC 29201 +// Voice: (803) 799-1699 +// Fax: (803) 931-0320 +// Web: http://www.idvinc.com + +#pragma once + + +/////////////////////////////////////////////////////////////////////// +// Include Files + +//#include +#define SPEEDTREE_DATA_FORMAT_DIRECTX + +#include "SpeedTreeForest.h" +#include "SpeedTreeMaterial.h" + +/////////////////////////////////////////////////////////////////////// +// class CSpeedTreeForestDirectX8 declaration +class CSpeedTreeForestDirectX8 : public CSpeedTreeForest, public CGraphicBase, public CSingleton +{ + public: + CSpeedTreeForestDirectX8(); + virtual ~CSpeedTreeForestDirectX8(); + + void UploadWindMatrix(unsigned int uiLocation, const float* pMatrix) const; + void UpdateCompundMatrix(const D3DXVECTOR3 & c_rEyeVec, const D3DXMATRIX & c_rmatView, const D3DXMATRIX & c_rmatProj); + + void Render(unsigned long ulRenderBitVector = Forest_RenderAll); + bool SetRenderingDevice(LPDIRECT3DDEVICE8 pDevice); + + private: + bool InitVertexShaders(); + + private: + LPDIRECT3DDEVICE8 m_pDx; // the rendering context + + DWORD m_dwBranchVertexShader; // branch/frond vertex shaders + DWORD m_dwLeafVertexShader; // leaf vertex shader +}; diff --git a/source/SpeedTreeLib/SpeedTreeMaterial.h b/source/SpeedTreeLib/SpeedTreeMaterial.h new file mode 100644 index 0000000..6a8127d --- /dev/null +++ b/source/SpeedTreeLib/SpeedTreeMaterial.h @@ -0,0 +1,79 @@ +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeMaterial Class +// +// (c) 2003 IDV, Inc. +// +// This class is provided to illustrate one way to incorporate +// SpeedTreeRT into an OpenGL application. All of the SpeedTreeRT +// calls that must be made on a per tree basis are done by this class. +// Calls that apply to all trees (i.e. static SpeedTreeRT functions) +// are made in the functions in main.cpp. +// +// +// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION *** +// +// This software is supplied under the terms of a license agreement or +// nondisclosure agreement with Interactive Data Visualization and may +// not be copied or disclosed except in accordance with the terms of +// that agreement. +// +// Copyright (c) 2001-2003 IDV, Inc. +// All Rights Reserved. +// +// IDV, Inc. +// 1233 Washington St. Suite 610 +// Columbia, SC 29201 +// Voice: (803) 799-1699 +// Fax: (803) 931-0320 +// Web: http://www.idvinc.com + +#pragma once + + +/////////////////////////////////////////////////////////////////////// +// Include Files + +#include +#include +#include + +/////////////////////////////////////////////////////////////////////// +// class CSpeedTreeMaterial declaration/definiton + +class CSpeedTreeMaterial +{ + public: + CSpeedTreeMaterial() + { + m_cMaterial.Ambient.r = m_cMaterial.Diffuse.r = m_cMaterial.Specular.r = m_cMaterial.Emissive.r = 1.0f; + m_cMaterial.Ambient.g = m_cMaterial.Diffuse.g = m_cMaterial.Specular.g = m_cMaterial.Emissive.g = 1.0f; + m_cMaterial.Ambient.b = m_cMaterial.Diffuse.b = m_cMaterial.Specular.b = m_cMaterial.Emissive.b = 1.0f; + m_cMaterial.Ambient.a = m_cMaterial.Diffuse.a = m_cMaterial.Specular.a = m_cMaterial.Emissive.a = 1.0f; + m_cMaterial.Power = 5.0f; + } + + void Set(const float * pMaterialArray) + { + memcpy(&m_cMaterial.Diffuse, pMaterialArray, 3 * sizeof(float)); + m_cMaterial.Diffuse.a = 1.0f; + + memcpy(&m_cMaterial.Ambient, pMaterialArray + 3, 3 * sizeof(float)); + m_cMaterial.Ambient.a = 1.0f; + + memcpy(&m_cMaterial.Specular, pMaterialArray + 6, 3 * sizeof(float)); + m_cMaterial.Specular.a = 1.0f; + + memcpy(&m_cMaterial.Emissive, pMaterialArray + 9, 3 * sizeof(float)); + m_cMaterial.Emissive.a = 1.0f; + + m_cMaterial.Power = pMaterialArray[12]; + } + + D3DMATERIAL8 * Get() + { + return &m_cMaterial; + } + + private: + D3DMATERIAL8 m_cMaterial; // the material object +}; diff --git a/source/SpeedTreeLib/SpeedTreeWrapper.cpp b/source/SpeedTreeLib/SpeedTreeWrapper.cpp new file mode 100644 index 0000000..f3820c6 --- /dev/null +++ b/source/SpeedTreeLib/SpeedTreeWrapper.cpp @@ -0,0 +1,1485 @@ +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeWrapper Class +// +// (c) 2003 IDV, Inc. +// +// This class is provided to illustrate one way to incorporate +// SpeedTreeRT into an OpenGL application. All of the SpeedTreeRT +// calls that must be made on a per tree basis are done by this class. +// Calls that apply to all trees (i.e. static SpeedTreeRT functions) +// are made in the functions in main.cpp. +// +// +// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION *** +// +// This software is supplied under the terms of a license agreement or +// nondisclosure agreement with Interactive Data Visualization and may +// not be copied or disclosed except in accordance with the terms of +// that agreement. +// +// Copyright (c) 2001-2003 IDV, Inc. +// All Rights Reserved. +// +// IDV, Inc. +// 1233 Washington St. Suite 610 +// Columbia, SC 29201 +// Voice: (803) 799-1699 +// Fax: (803) 931-0320 +// Web: http://www.idvinc.com +// + +#pragma warning(disable:4786) + +/////////////////////////////////////////////////////////////////////// +// Include Files +#include "StdAfx.h" + +#include +#include +#include "../eterBase/Debug.h" +#include "../eterBase/Timer.h" +#include "../eterBase/Filename.h" +#include "../eterLib/ResourceManager.h" +#include "../eterLib/Camera.h" +#include "../eterLib/StateManager.h" + +#include "SpeedTreeConfig.h" +#include "SpeedTreeForestDirectX8.h" +#include "SpeedTreeWrapper.h" +#include "VertexShaders.h" + +using namespace std; + +DWORD CSpeedTreeWrapper::ms_dwBranchVertexShader = 0; +DWORD CSpeedTreeWrapper::ms_dwLeafVertexShader = 0; +bool CSpeedTreeWrapper::ms_bSelfShadowOn = true; + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeWrapper::CSpeedTreeWrapper +CSpeedTreeWrapper::CSpeedTreeWrapper() : +m_pSpeedTree(new CSpeedTreeRT), +m_bIsInstance(false), +m_pInstanceOf(NULL), +m_pGeometryCache(NULL), +m_usNumLeafLods(0), +m_pBranchIndexCounts(NULL), +m_pBranchIndexBuffer(NULL), +m_pBranchVertexBuffer(NULL), +m_pFrondIndexCounts(NULL), +m_pFrondIndexBuffer(NULL), +m_pFrondVertexBuffer(NULL), +m_pLeafVertexBuffer(NULL), +m_pLeavesUpdatedByCpu(NULL), +m_unBranchVertexCount(0), +m_unFrondVertexCount(0), +m_pTextureInfo(NULL) +{ + // set initial position + m_afPos[0] = m_afPos[1] = m_afPos[2] = 0.0f; + + m_pSpeedTree->SetWindStrength(1.0f); + m_pSpeedTree->SetLocalMatrices(0, 4); +} + +void CSpeedTreeWrapper::SetVertexShaders(DWORD dwBranchVertexShader, DWORD dwLeafVertexShader) +{ + ms_dwBranchVertexShader = dwBranchVertexShader; + ms_dwLeafVertexShader = dwLeafVertexShader; +} + +void CSpeedTreeWrapper::OnRenderPCBlocker() +{ + if (ms_dwBranchVertexShader == 0) + { + ms_dwBranchVertexShader = LoadBranchShader(ms_lpd3dDevice); + //LogBox("Vertex Shader not assigned. You must call CSpeedTreeWrapper::SetVertexShader for this"); + } + + if (ms_dwLeafVertexShader == 0) + { + ms_dwLeafVertexShader = LoadLeafShader(ms_lpd3dDevice); + //LogBox("Vertex Shader not assigned. You must call CSpeedTreeWrapper::SetVertexShader for this"); + } + + CSpeedTreeForestDirectX8::Instance().UpdateSystem(ELTimer_GetMSec() / 1000.0f); + + // ϳ LOD + m_pSpeedTree->SetLodLevel(1.0f); + //Advance(); + + CSpeedTreeForestDirectX8::Instance().UpdateCompundMatrix(CCameraManager::Instance().GetCurrentCamera()->GetEye(), ms_matView, ms_matProj); + + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + + DWORD dwLighting = STATEMANAGER.GetRenderState(D3DRS_LIGHTING); + DWORD dwFogEnable = STATEMANAGER.GetRenderState(D3DRS_FOGENABLE); + DWORD dwAlphaBlendEnable = STATEMANAGER.GetRenderState(D3DRS_ALPHABLENDENABLE); + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); + STATEMANAGER.SaveRenderState(D3DRS_COLORVERTEX, TRUE); + STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER); + STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_CW); + STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, FALSE); + + // choose fixed function pipeline or custom shader for fronds and branches + STATEMANAGER.SetVertexShader(ms_dwBranchVertexShader); + +// SetupBranchForTreeType(); + { + // update the branch geometry for CPU wind +#ifdef WRAPPER_USE_CPU_WIND + m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_BranchGeometry); + + if (m_pGeometryCache->m_sBranches.m_usNumStrips > 0) + { + // update the vertex array + SFVFBranchVertex* pVertexBuffer = NULL; + m_pBranchVertexBuffer->Lock(0, 0, reinterpret_cast(&pVertexBuffer), D3DLOCK_DISCARD | D3DLOCK_NOSYSLOCK); + for (UINT i = 0; i < m_unBranchVertexCount; ++i) + { + memcpy(&(pVertexBuffer[i].m_vPosition), &(m_pGeometryCache->m_sBranches.m_pCoords[i * 3]), 3 * sizeof(float)); + } + m_pBranchVertexBuffer->Unlock(); + } +#endif + + LPDIRECT3DTEXTURE8 lpd3dTexture; + + // set texture map + if ((lpd3dTexture = m_BranchImageInstance.GetTextureReference().GetD3DTexture())) + STATEMANAGER.SetTexture(0, lpd3dTexture); + + if (m_pGeometryCache->m_sBranches.m_usVertexCount > 0) + { + // activate the branch vertex buffer + STATEMANAGER.SetStreamSource(0, m_pBranchVertexBuffer, sizeof(SFVFBranchVertex)); + // set the index buffer + STATEMANAGER.SetIndices(m_pBranchIndexBuffer, 0); + } + } + + RenderBranches(); + + STATEMANAGER.SetTexture(0, m_CompositeImageInstance.GetTextureReference().GetD3DTexture()); + STATEMANAGER.SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + +// SetupFrondForTreeType(); + { + // update the frond geometry for CPU wind +#ifdef WRAPPER_USE_CPU_WIND + m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_FrondGeometry); + if (m_pGeometryCache->m_sFronds.m_usNumStrips > 0) + { + // update the vertex array + SFVFBranchVertex * pVertexBuffer = NULL; + m_pFrondVertexBuffer->Lock(0, 0, reinterpret_cast(&pVertexBuffer), D3DLOCK_DISCARD | D3DLOCK_NOSYSLOCK); + for (UINT i = 0; i < m_unFrondVertexCount; ++i) + { + memcpy(&(pVertexBuffer[i].m_vPosition), &(m_pGeometryCache->m_sFronds.m_pCoords[i * 3]), 3 * sizeof(float)); + } + m_pFrondVertexBuffer->Unlock(); + } +#endif + + if (!m_CompositeImageInstance.IsEmpty()) + STATEMANAGER.SetTexture(0, m_CompositeImageInstance.GetTextureReference().GetD3DTexture()); + + if (m_pGeometryCache->m_sFronds.m_usVertexCount > 0) + { + // activate the frond vertex buffer + STATEMANAGER.SetStreamSource(0, m_pFrondVertexBuffer, sizeof(SFVFBranchVertex)); + // set the index buffer + STATEMANAGER.SetIndices(m_pFrondIndexBuffer, 0); + } + } + RenderFronds(); + + STATEMANAGER.SetVertexShader(ms_dwLeafVertexShader); + +// SetupLeafForTreeType(); + { + // pass leaf tables to shader +#ifdef WRAPPER_USE_GPU_LEAF_PLACEMENT + UploadLeafTables(c_nVertexShader_LeafTables); +#endif + + if (!m_CompositeImageInstance.IsEmpty()) + STATEMANAGER.SetTexture(0, m_CompositeImageInstance.GetTextureReference().GetD3DTexture()); + } + RenderLeaves(); + EndLeafForTreeType(); + + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); + STATEMANAGER.SetRenderState(D3DRS_COLORVERTEX, FALSE); + RenderBillboards(); + + STATEMANAGER.RestoreRenderState(D3DRS_COLORVERTEX); + STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHAFUNC); + STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, dwAlphaBlendEnable); + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, dwLighting); + STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, dwFogEnable); + + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); +} + +void CSpeedTreeWrapper::OnRender() +{ + if (ms_dwBranchVertexShader == 0) + { + ms_dwBranchVertexShader = LoadBranchShader(ms_lpd3dDevice); + //LogBox("Vertex Shader not assigned. You must call CSpeedTreeWrapper::SetVertexShader for this"); + } + + if (ms_dwLeafVertexShader == 0) + { + ms_dwLeafVertexShader = LoadLeafShader(ms_lpd3dDevice); + //LogBox("Vertex Shader not assigned. You must call CSpeedTreeWrapper::SetVertexShader for this"); + } + + CSpeedTreeForestDirectX8::Instance().UpdateSystem(ELTimer_GetMSec() / 1000.0f); + + // ϳ LOD + m_pSpeedTree->SetLodLevel(1.0f); + //Advance(); + + CSpeedTreeForestDirectX8::Instance().UpdateCompundMatrix(CCameraManager::Instance().GetCurrentCamera()->GetEye(), ms_matView, ms_matProj); + + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); + + STATEMANAGER.SaveRenderState(D3DRS_LIGHTING, FALSE); + STATEMANAGER.SaveRenderState(D3DRS_COLORVERTEX, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER); + STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_CW); + STATEMANAGER.SaveRenderState(D3DRS_FOGENABLE, FALSE); + + // choose fixed function pipeline or custom shader for fronds and branches + STATEMANAGER.SetVertexShader(ms_dwBranchVertexShader); + + SetupBranchForTreeType(); + RenderBranches(); + + STATEMANAGER.SetTexture(0, m_CompositeImageInstance.GetTextureReference().GetD3DTexture()); + STATEMANAGER.SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + + SetupFrondForTreeType(); + RenderFronds(); + + STATEMANAGER.SetVertexShader(ms_dwLeafVertexShader); + + SetupLeafForTreeType(); + RenderLeaves(); + EndLeafForTreeType(); + + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); + STATEMANAGER.SetRenderState(D3DRS_COLORVERTEX, FALSE); + RenderBillboards(); + + STATEMANAGER.RestoreRenderState(D3DRS_LIGHTING); + STATEMANAGER.RestoreRenderState(D3DRS_COLORVERTEX); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE); + STATEMANAGER.RestoreRenderState(D3DRS_ALPHAFUNC); + STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE); + STATEMANAGER.RestoreRenderState(D3DRS_FOGENABLE); +} + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeWrapper::~CSpeedTreeWrapper + +CSpeedTreeWrapper::~CSpeedTreeWrapper() +{ + // if this is not an instance, clean up + if (!m_bIsInstance) + { + if (m_unBranchVertexCount > 0) + { + SAFE_RELEASE(m_pBranchVertexBuffer); + SAFE_RELEASE(m_pBranchIndexBuffer); + SAFE_DELETE_ARRAY(m_pBranchIndexCounts); + } + + if (m_unFrondVertexCount > 0) + { + SAFE_RELEASE(m_pFrondVertexBuffer); + SAFE_RELEASE(m_pFrondIndexBuffer); + SAFE_DELETE_ARRAY(m_pFrondIndexCounts); + } + + for (short i = 0; i < m_usNumLeafLods; ++i) + { + m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_LeafGeometry, -1, -1, i); + + if (m_pGeometryCache->m_sLeaves0.m_usLeafCount > 0) + SAFE_RELEASE(m_pLeafVertexBuffer[i]); + } + + SAFE_DELETE_ARRAY(m_pLeavesUpdatedByCpu); + SAFE_DELETE_ARRAY(m_pLeafVertexBuffer); + + SAFE_DELETE(m_pTextureInfo); + + SAFE_DELETE(m_pGeometryCache); + } + + // always delete the speedtree + SAFE_DELETE(m_pSpeedTree); + + Clear(); +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeWrapper::LoadTree +bool CSpeedTreeWrapper::LoadTree(const char * pszSptFile, const BYTE * c_pbBlock, unsigned int uiBlockSize, UINT nSeed, float fSize, float fSizeVariance) +{ + bool bSuccess = false; + + // directx, so allow for flipping of the texture coordinate +#ifdef WRAPPER_FLIP_T_TEXCOORD + m_pSpeedTree->SetTextureFlip(true); +#endif + + // load the tree file + if (!m_pSpeedTree->LoadTree(c_pbBlock, uiBlockSize)) + { + if (!m_pSpeedTree->LoadTree(pszSptFile)) + { + TraceError("SpeedTreeRT Error: %s", CSpeedTreeRT::GetCurrentError()); + return false; + } + } + + // override the lighting method stored in the spt file +#ifdef WRAPPER_USE_DYNAMIC_LIGHTING + m_pSpeedTree->SetBranchLightingMethod(CSpeedTreeRT::LIGHT_DYNAMIC); + m_pSpeedTree->SetLeafLightingMethod(CSpeedTreeRT::LIGHT_DYNAMIC); + m_pSpeedTree->SetFrondLightingMethod(CSpeedTreeRT::LIGHT_DYNAMIC); +#else + m_pSpeedTree->SetBranchLightingMethod(CSpeedTreeRT::LIGHT_STATIC); + m_pSpeedTree->SetLeafLightingMethod(CSpeedTreeRT::LIGHT_STATIC); + m_pSpeedTree->SetFrondLightingMethod(CSpeedTreeRT::LIGHT_STATIC); +#endif + + // set the wind method +#ifdef WRAPPER_USE_GPU_WIND + m_pSpeedTree->SetBranchWindMethod(CSpeedTreeRT::WIND_GPU); + m_pSpeedTree->SetLeafWindMethod(CSpeedTreeRT::WIND_GPU); + m_pSpeedTree->SetFrondWindMethod(CSpeedTreeRT::WIND_GPU); +#endif +#ifdef WRAPPER_USE_CPU_WIND + m_pSpeedTree->SetBranchWindMethod(CSpeedTreeRT::WIND_CPU); + m_pSpeedTree->SetLeafWindMethod(CSpeedTreeRT::WIND_CPU); + m_pSpeedTree->SetFrondWindMethod(CSpeedTreeRT::WIND_CPU); +#endif +#ifdef WRAPPER_USE_NO_WIND + m_pSpeedTree->SetBranchWindMethod(CSpeedTreeRT::WIND_NONE); + m_pSpeedTree->SetLeafWindMethod(CSpeedTreeRT::WIND_NONE); + m_pSpeedTree->SetFrondWindMethod(CSpeedTreeRT::WIND_NONE); +#endif + + m_pSpeedTree->SetNumLeafRockingGroups(1); + + // override the size, if necessary + if (fSize >= 0.0f && fSizeVariance >= 0.0f) + m_pSpeedTree->SetTreeSize(fSize, fSizeVariance); + + // generate tree geometry + if (m_pSpeedTree->Compute(NULL, nSeed)) + { + // get the dimensions + m_pSpeedTree->GetBoundingBox(m_afBoundingBox); + + // make the leaves rock in the wind + m_pSpeedTree->SetLeafRockingState(true); + + // billboard setup +#ifdef WRAPPER_NO_BILLBOARD_MODE + CSpeedTreeRT::SetDropToBillboard(false); +#else + CSpeedTreeRT::SetDropToBillboard(true); +#endif + + // query & set materials + m_cBranchMaterial.Set(m_pSpeedTree->GetBranchMaterial()); + m_cFrondMaterial.Set(m_pSpeedTree->GetFrondMaterial()); + m_cLeafMaterial.Set(m_pSpeedTree->GetLeafMaterial()); + + // adjust lod distances + float fHeight = m_afBoundingBox[5] - m_afBoundingBox[2]; + m_pSpeedTree->SetLodLimits(fHeight * c_fNearLodFactor, fHeight * c_fFarLodFactor); + + // query textures + m_pTextureInfo = new CSpeedTreeRT::STextures; + m_pSpeedTree->GetTextures(*m_pTextureInfo); + + // load branch textures + auto vs1 = std::string(pszSptFile); + auto vs2 = std::string(m_pTextureInfo->m_pBranchTextureFilename); + LoadTexture((CFileNameHelper::GetPath(vs1) + CFileNameHelper::NoExtension(vs2) + ".dds").c_str(), m_BranchImageInstance); + +#ifdef WRAPPER_RENDER_SELF_SHADOWS + if (m_pTextureInfo->m_pSelfShadowFilename != NULL) + { + auto vss = std::string(m_pTextureInfo->m_pSelfShadowFilename); + LoadTexture((CFileNameHelper::GetPath(vs1) + CFileNameHelper::NoExtension(vss) + ".dds").c_str(), m_ShadowImageInstance); + } +#endif + if (m_pTextureInfo->m_pCompositeFilename) + { + auto vss = std::string(m_pTextureInfo->m_pCompositeFilename); + LoadTexture((CFileNameHelper::GetPath(vs1) + CFileNameHelper::NoExtension(vss) + ".dds").c_str(), m_CompositeImageInstance); + } + + // setup the index and vertex buffers + SetupBuffers(); + + // everything appeared to go well + bSuccess = true; + } + else // tree failed to compute + fprintf(stderr, "\nFatal Error, cannot compute tree [%s]\n\n", CSpeedTreeRT::GetCurrentError()); + + return bSuccess; +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeWrapper::SetupBuffers + +void CSpeedTreeWrapper::SetupBuffers(void) +{ + // read all the geometry for highest LOD into the geometry cache (just a precaution, it's updated later) + m_pSpeedTree->SetLodLevel(1.0f); + + if (m_pGeometryCache == NULL) + m_pGeometryCache = new CSpeedTreeRT::SGeometry; + + m_pSpeedTree->GetGeometry(*m_pGeometryCache); + + // setup the buffers for each part + SetupBranchBuffers(); + SetupFrondBuffers(); + SetupLeafBuffers(); +} + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeWrapper::SetupBranchBuffers + +void CSpeedTreeWrapper::SetupBranchBuffers(void) +{ + // reference to branch structure + CSpeedTreeRT::SGeometry::SIndexed* pBranches = &(m_pGeometryCache->m_sBranches); + m_unBranchVertexCount = pBranches->m_usVertexCount; // we asked for a contiguous strip + + // check if this tree has branches + if (m_unBranchVertexCount > 1) + { + // create the vertex buffer for storing branch vertices + SFVFBranchVertex * pVertexBuffer = NULL; + +#ifndef WRAPPER_USE_CPU_WIND + ms_lpd3dDevice->CreateVertexBuffer(m_unBranchVertexCount * sizeof(SFVFBranchVertex), D3DUSAGE_WRITEONLY, D3DFVF_SPEEDTREE_BRANCH_VERTEX, D3DPOOL_MANAGED, &m_pBranchVertexBuffer); + // fill the vertex buffer by interleaving SpeedTree data + m_pBranchVertexBuffer->Lock(0, 0, reinterpret_cast(&pVertexBuffer), 0); +#else + ms_lpd3dDevice->CreateVertexBuffer(m_unBranchVertexCount * sizeof(SFVFBranchVertex), D3DUSAGE_DYNAMIC, D3DFVF_SPEEDTREE_BRANCH_VERTEX, D3DPOOL_SYSTEMMEM, &m_pBranchVertexBuffer); + // fill the vertex buffer by interleaving SpeedTree data + m_pBranchVertexBuffer->Lock(0, 0, reinterpret_cast(&pVertexBuffer), D3DLOCK_DISCARD | D3DLOCK_NOSYSLOCK); +#endif + { + for (UINT i = 0; i < m_unBranchVertexCount; ++i) + { + // position + memcpy(&pVertexBuffer->m_vPosition, &(pBranches->m_pCoords[i * 3]), 3 * sizeof(float)); + + // normal or color +#ifdef WRAPPER_USE_DYNAMIC_LIGHTING + memcpy(&pVertexBuffer->m_vNormal, &(pBranches->m_pNormals[i * 3]), 3 * sizeof(float)); +#else + pVertexBuffer->m_dwDiffuseColor = pBranches->m_pColors[i]; +#endif + + // texcoords for layer 0 + pVertexBuffer->m_fTexCoords[0] = pBranches->m_pTexCoords0[i * 2]; + pVertexBuffer->m_fTexCoords[1] = pBranches->m_pTexCoords0[i * 2 + 1]; + + // texcoords for layer 1 (if enabled) +#ifdef WRAPPER_RENDER_SELF_SHADOWS + pVertexBuffer->m_fShadowCoords[0] = pBranches->m_pTexCoords1[i * 2]; + pVertexBuffer->m_fShadowCoords[1] = pBranches->m_pTexCoords1[i * 2 + 1]; +#endif + + // extra data for gpu wind +#ifdef WRAPPER_USE_GPU_WIND + pVertexBuffer->m_fWindIndex = 4.0f * pBranches->m_pWindMatrixIndices[i]; + pVertexBuffer->m_fWindWeight = pBranches->m_pWindWeights[i]; +#endif + + ++pVertexBuffer; + } + m_pBranchVertexBuffer->Unlock(); + } + + // create and fill the index counts for each LOD + UINT unNumLodLevels = m_pSpeedTree->GetNumBranchLodLevels(); + m_pBranchIndexCounts = new unsigned short[unNumLodLevels]; + for (UINT i = 0; i < unNumLodLevels; ++i) + { + // force update for particular LOD + m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_BranchGeometry, i); + + // check if this LOD has branches + if (pBranches->m_usNumStrips > 0) + m_pBranchIndexCounts[i] = pBranches->m_pStripLengths[0]; + else + m_pBranchIndexCounts[i] = 0; + } + // set back to highest LOD + m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_BranchGeometry, 0); + + // the first LOD level contains the most indices of all the levels, so + // we use its size to allocate the index buffer + ms_lpd3dDevice->CreateIndexBuffer(m_pBranchIndexCounts[0] * sizeof(unsigned short), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &m_pBranchIndexBuffer); + + // fill the index buffer + unsigned short* pIndexBuffer = NULL; + m_pBranchIndexBuffer->Lock(0, 0, reinterpret_cast(&pIndexBuffer), 0); + memcpy(pIndexBuffer, pBranches->m_pStrips[0], pBranches->m_pStripLengths[0] * sizeof(unsigned short)); + m_pBranchIndexBuffer->Unlock(); + } +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeWrapper::SetupFrondBuffers + +void CSpeedTreeWrapper::SetupFrondBuffers(void) +{ + // reference to frond structure + CSpeedTreeRT::SGeometry::SIndexed* pFronds = &(m_pGeometryCache->m_sFronds); + m_unFrondVertexCount = pFronds->m_usVertexCount; // we asked for a contiguous strip + + // check if tree has fronds + if (m_unFrondVertexCount > 1) + { + // create the vertex buffer for storing frond vertices + SFVFBranchVertex * pVertexBuffer = NULL; +#ifndef WRAPPER_USE_CPU_WIND + ms_lpd3dDevice->CreateVertexBuffer(m_unFrondVertexCount * sizeof(SFVFBranchVertex), D3DUSAGE_WRITEONLY, D3DFVF_SPEEDTREE_BRANCH_VERTEX, D3DPOOL_MANAGED, &m_pFrondVertexBuffer); + // fill the vertex buffer by interleaving SpeedTree data + m_pFrondVertexBuffer->Lock(0, 0, reinterpret_cast(&pVertexBuffer), 0); +#else + ms_lpd3dDevice->CreateVertexBuffer(m_unFrondVertexCount * sizeof(SFVFBranchVertex), D3DUSAGE_DYNAMIC, D3DFVF_SPEEDTREE_BRANCH_VERTEX, D3DPOOL_SYSTEMMEM, &m_pFrondVertexBuffer); + // fill the vertex buffer by interleaving SpeedTree data + m_pFrondVertexBuffer->Lock(0, 0, reinterpret_cast(&pVertexBuffer), D3DLOCK_DISCARD | D3DLOCK_NOSYSLOCK); +#endif + for (UINT i = 0; i < m_unFrondVertexCount; ++i) + { + // position + memcpy(&pVertexBuffer->m_vPosition, &(pFronds->m_pCoords[i * 3]), 3 * sizeof(float)); + + // normal or color +#ifdef WRAPPER_USE_DYNAMIC_LIGHTING + memcpy(&pVertexBuffer->m_vNormal, &(pFronds->m_pNormals[i * 3]), 3 * sizeof(float)); +#else + pVertexBuffer->m_dwDiffuseColor = pFronds->m_pColors[i]; +#endif + + // texcoords for layer 0 + pVertexBuffer->m_fTexCoords[0] = pFronds->m_pTexCoords0[i * 2]; + pVertexBuffer->m_fTexCoords[1] = pFronds->m_pTexCoords0[i * 2 + 1]; + + // texcoords for layer 1 (if enabled) +#ifdef WRAPPER_RENDER_SELF_SHADOWS + pVertexBuffer->m_fShadowCoords[0] = pFronds->m_pTexCoords1[i * 2]; + pVertexBuffer->m_fShadowCoords[1] = pFronds->m_pTexCoords1[i * 2 + 1]; +#endif + + // extra data for gpu wind +#ifdef WRAPPER_USE_GPU_WIND + pVertexBuffer->m_fWindIndex = 4.0f * pFronds->m_pWindMatrixIndices[i]; + pVertexBuffer->m_fWindWeight = pFronds->m_pWindWeights[i]; +#endif + + ++pVertexBuffer; + } + m_pFrondVertexBuffer->Unlock(); + + // create and fill the index counts for each LOD + UINT unNumLodLevels = m_pSpeedTree->GetNumFrondLodLevels(); + m_pFrondIndexCounts = new unsigned short[unNumLodLevels]; + for (WORD j = 0; j < unNumLodLevels; ++j) + { + // force update for this LOD + m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_FrondGeometry, -1, j); + + // check if this LOD has fronds + if (pFronds->m_usNumStrips > 0) + m_pFrondIndexCounts[j] = pFronds->m_pStripLengths[0]; + else + m_pFrondIndexCounts[j] = 0; + } + // go back to highest LOD + m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_FrondGeometry, -1, 0); + + // the first LOD level contains the most indices of all the levels, so + // we use its size to allocate the index buffer + ms_lpd3dDevice->CreateIndexBuffer(m_pFrondIndexCounts[0] * sizeof(unsigned short), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &m_pFrondIndexBuffer); + + // fill the index buffer + unsigned short * pIndexBuffer = NULL; + m_pFrondIndexBuffer->Lock(0, 0, reinterpret_cast(&pIndexBuffer), 0); + memcpy(pIndexBuffer, pFronds->m_pStrips[0], pFronds->m_pStripLengths[0] * sizeof(unsigned short)); + m_pFrondIndexBuffer->Unlock(); + } +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeWrapper::SetupLeafBuffers + +void CSpeedTreeWrapper::SetupLeafBuffers(void) +{ + // set up constants + const short anVertexIndices[6] = { 0, 1, 2, 0, 2, 3 }; + //const int nNumLeafMaps = m_pTextureInfo->m_uiLeafTextureCount; + + // set up the leaf counts for each LOD + m_usNumLeafLods = m_pSpeedTree->GetNumLeafLodLevels(); + + // create array of vertex buffers (one for each LOD) + m_pLeafVertexBuffer = new LPDIRECT3DVERTEXBUFFER8[m_usNumLeafLods]; + + // create array of bools for CPU updating (so we don't update for each instance) + m_pLeavesUpdatedByCpu = new bool[m_usNumLeafLods]; + + // cycle through LODs + for (UINT unLod = 0; unLod < m_usNumLeafLods; ++unLod) + { + m_pLeavesUpdatedByCpu[unLod] = false; + m_pLeafVertexBuffer[unLod] = NULL; + + // if this LOD has no leaves, skip it + unsigned short usLeafCount = m_pGeometryCache->m_sLeaves0.m_usLeafCount; + + if (usLeafCount < 1) + continue; + + SFVFLeafVertex* pVertexBuffer = NULL; + // create the vertex buffer for storing leaf vertices +#ifndef WRAPPER_USE_CPU_LEAF_PLACEMENT + ms_lpd3dDevice->CreateVertexBuffer(usLeafCount * 6 * sizeof(SFVFLeafVertex), D3DUSAGE_WRITEONLY, D3DFVF_SPEEDTREE_LEAF_VERTEX, D3DPOOL_MANAGED, &m_pLeafVertexBuffer[unLod]); + // fill the vertex buffer by interleaving SpeedTree data + m_pLeafVertexBuffer[unLod]->Lock(0, 0, reinterpret_cast(&pVertexBuffer), 0); +#else + ms_lpd3dDevice->CreateVertexBuffer(usLeafCount * 6 * sizeof(SFVFLeafVertex), D3DUSAGE_DYNAMIC, D3DFVF_SPEEDTREE_LEAF_VERTEX, D3DPOOL_SYSTEMMEM, &m_pLeafVertexBuffer[unLod]); + // fill the vertex buffer by interleaving SpeedTree data + m_pLeafVertexBuffer[unLod]->Lock(0, 0, reinterpret_cast(&pVertexBuffer), D3DLOCK_DISCARD | D3DLOCK_NOSYSLOCK); +#endif + SFVFLeafVertex* pVertex = pVertexBuffer; + for (UINT unLeaf = 0; unLeaf < usLeafCount; ++unLeaf) + { + const CSpeedTreeRT::SGeometry::SLeaf* pLeaf = &(m_pGeometryCache->m_sLeaves0); + for (UINT unVert = 0; unVert < 6; ++unVert) // 6 verts == 2 triangles + { + // position + memcpy(pVertex->m_vPosition, &(pLeaf->m_pCenterCoords[unLeaf * 3]), 3 * sizeof(float)); + +#ifdef WRAPPER_USE_DYNAMIC_LIGHTING + // normal + memcpy(&pVertex->m_vNormal, &(pLeaf->m_pNormals[unLeaf * 3]), 3 * sizeof(float)); +#else + // color + pVertex->m_dwDiffuseColor = pLeaf->m_pColors[unLeaf]; +#endif + + // tex coord + memcpy(pVertex->m_fTexCoords, &(pLeaf->m_pLeafMapTexCoords[unLeaf][anVertexIndices[unVert] * 2]), 2 * sizeof(float)); + + // wind weights +#ifdef WRAPPER_USE_GPU_WIND + pVertex->m_fWindIndex = 4.0f * pLeaf->m_pWindMatrixIndices[unLeaf]; + pVertex->m_fWindWeight = pLeaf->m_pWindWeights[unLeaf]; +#endif + + // GPU placement data +#ifdef WRAPPER_USE_GPU_LEAF_PLACEMENT + pVertex->m_fLeafPlacementIndex = c_nVertexShader_LeafTables + pLeaf->m_pLeafClusterIndices[unLeaf] * 4.0f + anVertexIndices[unVert]; + pVertex->m_fLeafScalarValue = m_pSpeedTree->GetLeafLodSizeAdjustments()[unLod]; +#endif + + ++pVertex; + } + } + m_pLeafVertexBuffer[unLod]->Unlock(); + } +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeWrapper::Advance + +void CSpeedTreeWrapper::Advance(void) +{ + // compute LOD level (based on distance from camera) + m_pSpeedTree->ComputeLodLevel(); + m_pSpeedTree->SetLodLevel(1.0f); + + // compute wind +#ifdef WRAPPER_USE_CPU_WIND + m_pSpeedTree->ComputeWindEffects(true, true, true); +#endif +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeWrapper::MakeInstance +CSpeedTreeWrapper * CSpeedTreeWrapper::MakeInstance() +{ + CSpeedTreeWrapper * pInstance = new CSpeedTreeWrapper; + + // make an instance of this object's SpeedTree + pInstance->m_bIsInstance = true; + pInstance->m_pSpeedTree = m_pSpeedTree->MakeInstance(); + + if (pInstance->m_pSpeedTree) + { + // use the same materials + pInstance->m_cBranchMaterial = m_cBranchMaterial; + pInstance->m_cLeafMaterial = m_cLeafMaterial; + pInstance->m_cFrondMaterial = m_cFrondMaterial; + pInstance->m_CompositeImageInstance.SetImagePointer(m_CompositeImageInstance.GetGraphicImagePointer()); + pInstance->m_BranchImageInstance.SetImagePointer(m_BranchImageInstance.GetGraphicImagePointer()); + + if (!m_ShadowImageInstance.IsEmpty()) + pInstance->m_ShadowImageInstance.SetImagePointer(m_ShadowImageInstance.GetGraphicImagePointer()); + + pInstance->m_pTextureInfo = m_pTextureInfo; + + // use the same geometry cache + pInstance->m_pGeometryCache = m_pGeometryCache; + + // use the same buffers + pInstance->m_pBranchIndexBuffer = m_pBranchIndexBuffer; + pInstance->m_pBranchIndexCounts = m_pBranchIndexCounts; + pInstance->m_pBranchVertexBuffer = m_pBranchVertexBuffer; + pInstance->m_unBranchVertexCount = m_unBranchVertexCount; + + pInstance->m_pFrondIndexBuffer = m_pFrondIndexBuffer; + pInstance->m_pFrondIndexCounts = m_pFrondIndexCounts; + pInstance->m_pFrondVertexBuffer = m_pFrondVertexBuffer; + pInstance->m_unFrondVertexCount = m_unFrondVertexCount; + + pInstance->m_pLeafVertexBuffer = m_pLeafVertexBuffer; + pInstance->m_usNumLeafLods = m_usNumLeafLods; + pInstance->m_pLeavesUpdatedByCpu = m_pLeavesUpdatedByCpu; + + // new stuff + memcpy(pInstance->m_afPos, m_afPos, 3 * sizeof(float)); + memcpy(pInstance->m_afBoundingBox, m_afBoundingBox, 6 * sizeof(float)); + pInstance->m_pInstanceOf = this; + m_vInstances.push_back(pInstance); + } + else + { + fprintf(stderr, "SpeedTreeRT Error: %s\n", m_pSpeedTree->GetCurrentError()); + delete pInstance; + pInstance = NULL; + } + + return pInstance; +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeWrapper::GetInstances + +CSpeedTreeWrapper ** CSpeedTreeWrapper::GetInstances(UINT& nCount) +{ + nCount = m_vInstances.size(); + if (nCount) + return &(m_vInstances[0]); + else + return NULL; +} + +void CSpeedTreeWrapper::DeleteInstance(CSpeedTreeWrapper * pInstance) +{ + std::vector::iterator itor = m_vInstances.begin(); + + while (itor != m_vInstances.end()) + { + if (*itor == pInstance) + { + itor = m_vInstances.erase(itor); + } + else + ++itor; + } + delete pInstance; +} + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeWrapper::SetupBranchForTreeType + +void CSpeedTreeWrapper::SetupBranchForTreeType(void) const +{ +#ifdef WRAPPER_USE_DYNAMIC_LIGHTING + // set lighting material + STATEMANAGER.SetMaterial(m_cBranchMaterial.Get()); + SetShaderConstants(m_pSpeedTree->GetBranchMaterial()); +#endif + + // update the branch geometry for CPU wind +#ifdef WRAPPER_USE_CPU_WIND + m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_BranchGeometry); + + if (m_pGeometryCache->m_sBranches.m_usNumStrips > 0) + { + // update the vertex array + SFVFBranchVertex* pVertexBuffer = NULL; + m_pBranchVertexBuffer->Lock(0, 0, reinterpret_cast(&pVertexBuffer), D3DLOCK_DISCARD | D3DLOCK_NOSYSLOCK); + for (UINT i = 0; i < m_unBranchVertexCount; ++i) + { + memcpy(&(pVertexBuffer[i].m_vPosition), &(m_pGeometryCache->m_sBranches.m_pCoords[i * 3]), 3 * sizeof(float)); + } + m_pBranchVertexBuffer->Unlock(); + } +#endif + + LPDIRECT3DTEXTURE8 lpd3dTexture; + + // set texture map + if ((lpd3dTexture = m_BranchImageInstance.GetTextureReference().GetD3DTexture())) + STATEMANAGER.SetTexture(0, lpd3dTexture); + + // bind shadow texture +#ifdef WRAPPER_RENDER_SELF_SHADOWS + if (ms_bSelfShadowOn && (lpd3dTexture = m_ShadowImageInstance.GetTextureReference().GetD3DTexture())) + STATEMANAGER.SetTexture(1, lpd3dTexture); + else + STATEMANAGER.SetTexture(1, NULL); +#endif + + if (m_pGeometryCache->m_sBranches.m_usVertexCount > 0) + { + // activate the branch vertex buffer + STATEMANAGER.SetStreamSource(0, m_pBranchVertexBuffer, sizeof(SFVFBranchVertex)); + // set the index buffer + STATEMANAGER.SetIndices(m_pBranchIndexBuffer, 0); + } +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeWrapper::RenderBranches + +void CSpeedTreeWrapper::RenderBranches(void) const +{ + m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_BranchGeometry); + + if (m_pGeometryCache->m_fBranchAlphaTestValue) + { + PositionTree(); + + // set alpha test value + STATEMANAGER.SetRenderState(D3DRS_ALPHAREF, DWORD(m_pGeometryCache->m_fBranchAlphaTestValue)); + + // render if this LOD has branches + if (m_pBranchIndexCounts && + m_pBranchIndexCounts[m_pGeometryCache->m_sBranches.m_nDiscreteLodLevel] > 0) + { + ms_faceCount += m_pBranchIndexCounts[m_pGeometryCache->m_sBranches.m_nDiscreteLodLevel] - 2; + STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, m_pGeometryCache->m_sBranches.m_usVertexCount, 0, m_pBranchIndexCounts[m_pGeometryCache->m_sBranches.m_nDiscreteLodLevel] - 2); + } + } +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeWrapper::SetupFrondForTreeType + +void CSpeedTreeWrapper::SetupFrondForTreeType(void) const +{ +#ifdef SPEEDTREE_LIGHTING_DYNAMIC + // set lighting material + STATEMANAGER.SetMaterial(m_cFrondMaterial.Get()); + SetShaderConstants(m_pSpeedTree->GetFrondMaterial()); +#endif + + // update the frond geometry for CPU wind +#ifdef WRAPPER_USE_CPU_WIND + m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_FrondGeometry); + if (m_pGeometryCache->m_sFronds.m_usNumStrips > 0) + { + // update the vertex array + SFVFBranchVertex * pVertexBuffer = NULL; + m_pFrondVertexBuffer->Lock(0, 0, reinterpret_cast(&pVertexBuffer), D3DLOCK_DISCARD | D3DLOCK_NOSYSLOCK); + for (UINT i = 0; i < m_unFrondVertexCount; ++i) + { + memcpy(&(pVertexBuffer[i].m_vPosition), &(m_pGeometryCache->m_sFronds.m_pCoords[i * 3]), 3 * sizeof(float)); + } + m_pFrondVertexBuffer->Unlock(); + } +#endif + + if (!m_CompositeImageInstance.IsEmpty()) + STATEMANAGER.SetTexture(0, m_CompositeImageInstance.GetTextureReference().GetD3DTexture()); + + // bind shadow texture +#ifdef WRAPPER_RENDER_SELF_SHADOWS + LPDIRECT3DTEXTURE8 lpd3dTexture; + + if ((lpd3dTexture = m_ShadowImageInstance.GetTextureReference().GetD3DTexture())) + STATEMANAGER.SetTexture(1, lpd3dTexture); +#endif + + if (m_pGeometryCache->m_sFronds.m_usVertexCount > 0) + { + // activate the frond vertex buffer + STATEMANAGER.SetStreamSource(0, m_pFrondVertexBuffer, sizeof(SFVFBranchVertex)); + // set the index buffer + STATEMANAGER.SetIndices(m_pFrondIndexBuffer, 0); + } +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeWrapper::RenderFronds + +void CSpeedTreeWrapper::RenderFronds(void) const +{ + m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_FrondGeometry); + + if (m_pGeometryCache->m_fFrondAlphaTestValue > 0.0f) + { + PositionTree(); + + // set alpha test value + STATEMANAGER.SetRenderState(D3DRS_ALPHAREF, DWORD(m_pGeometryCache->m_fFrondAlphaTestValue)); + + // render if this LOD has fronds + if (m_pFrondIndexCounts && + m_pFrondIndexCounts[m_pGeometryCache->m_sFronds.m_nDiscreteLodLevel] > 0) + { + ms_faceCount += m_pFrondIndexCounts[m_pGeometryCache->m_sFronds.m_nDiscreteLodLevel] - 2; + STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, m_pGeometryCache->m_sFronds.m_usVertexCount, 0, m_pFrondIndexCounts[m_pGeometryCache->m_sFronds.m_nDiscreteLodLevel] - 2); + } + } +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeWrapper::SetupLeafForTreeType + +void CSpeedTreeWrapper::SetupLeafForTreeType(void) const +{ +#ifdef SPEEDTREE_LIGHTING_DYNAMIC + // set lighting material + STATEMANAGER.SetMaterial(m_cLeafMaterial.Get()); + SetShaderConstants(m_pSpeedTree->GetLeafMaterial()); +#endif + + // pass leaf tables to shader +#ifdef WRAPPER_USE_GPU_LEAF_PLACEMENT + UploadLeafTables(c_nVertexShader_LeafTables); +#endif + + if (!m_CompositeImageInstance.IsEmpty()) + STATEMANAGER.SetTexture(0, m_CompositeImageInstance.GetTextureReference().GetD3DTexture()); + + // bind shadow texture +#ifdef WRAPPER_RENDER_SELF_SHADOWS + STATEMANAGER.SetTexture(1, NULL); +#endif +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeWrapper::UploadLeafTables + +#ifdef WRAPPER_USE_GPU_LEAF_PLACEMENT +void CSpeedTreeWrapper::UploadLeafTables(UINT uiLocation) const +{ + // query leaf cluster table from RT + UINT uiEntryCount = 0; + const float * pTable = m_pSpeedTree->GetLeafBillboardTable(uiEntryCount); + + // upload for vertex shader use + STATEMANAGER.SetVertexShaderConstant(c_nVertexShader_LeafTables, pTable, uiEntryCount / 4); +} +#endif + + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeWrapper::RenderLeaves + +void CSpeedTreeWrapper::RenderLeaves(void) const +{ + // update leaf geometry + m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_LeafGeometry); + + // update the LOD level vertex arrays we need +#if defined(WRAPPER_USE_GPU_LEAF_PLACEMENT) && defined(WRAPPER_USE_GPU_WIND) + // do nothing, needs no updates +#else +#if !defined WRAPPER_USE_NO_WIND || defined WRAPPER_USE_CPU_LEAF_PLACEMENT + // possibly need to update both leaf LOD's + for (UINT i = 0; i < 2; ++i) + { + // reference to leaf structure + const CSpeedTreeRT::SGeometry::SLeaf* pLeaf = (i == 0) ? &m_pGeometryCache->m_sLeaves0 : &m_pGeometryCache->m_sLeaves1; + int unLod = pLeaf->m_nDiscreteLodLevel; + +#if defined WRAPPER_USE_GPU_LEAF_PLACEMENT + if (pLeaf->m_bIsActive && !m_pLeavesUpdatedByCpu[unLod]) + { + // update the centers + SFVFLeafVertex* pVertex = NULL; + m_pLeafVertexBuffer[unLod]->Lock(0, 0, reinterpret_cast(&pVertex), D3DLOCK_DISCARD | D3DLOCK_NOSYSLOCK); + for (UINT unLeaf = 0; unLeaf < pLeaf->m_usLeafCount; ++unLeaf) + { + D3DXVECTOR3 vecCenter(&(pLeaf->m_pCenterCoords[unLeaf * 3])); + (pVertex++)->m_vPosition = vecCenter; // vertex 0 + (pVertex++)->m_vPosition = vecCenter; // vertex 1 + (pVertex++)->m_vPosition = vecCenter; // vertex 2 + (pVertex++)->m_vPosition = vecCenter; // vertex 0 + (pVertex++)->m_vPosition = vecCenter; // vertex 2 + (pVertex++)->m_vPosition = vecCenter; // vertex 3 + } + m_pLeafVertexBuffer[unLod]->Unlock(); + m_pLeavesUpdatedByCpu[unLod] = true; + } +#else + if (pLeaf->m_bIsActive && m_pLeafVertexBuffer[unLod]) + { + // update the vertex positions + SFVFLeafVertex * pVertex = NULL; + + const UINT VERTEX_NUM = 8192; + if (pLeaf->m_usLeafCount*3>=VERTEX_NUM) + return; + + D3DXVECTOR3 akPosition[VERTEX_NUM]; + D3DXVECTOR3*pkPosition=akPosition; + const float* center=pLeaf->m_pCenterCoords; + for (UINT unLeaf = 0; unLeaf < pLeaf->m_usLeafCount; ++unLeaf) + { + pkPosition[0].x=pLeaf->m_pLeafMapCoords[unLeaf][0]+center[0]; + pkPosition[0].y=pLeaf->m_pLeafMapCoords[unLeaf][1]+center[1]; + pkPosition[0].z=pLeaf->m_pLeafMapCoords[unLeaf][2]+center[2]; + pkPosition[1].x=pLeaf->m_pLeafMapCoords[unLeaf][4]+center[0]; + pkPosition[1].y=pLeaf->m_pLeafMapCoords[unLeaf][5]+center[1]; + pkPosition[1].z=pLeaf->m_pLeafMapCoords[unLeaf][6]+center[2]; + pkPosition[2].x=pLeaf->m_pLeafMapCoords[unLeaf][8]+center[0]; + pkPosition[2].y=pLeaf->m_pLeafMapCoords[unLeaf][9]+center[1]; + pkPosition[2].z=pLeaf->m_pLeafMapCoords[unLeaf][10]+center[2]; + pkPosition[3]=pkPosition[0]; + pkPosition[4]=pkPosition[2]; + pkPosition[5].x=pLeaf->m_pLeafMapCoords[unLeaf][12]+center[0]; + pkPosition[5].y=pLeaf->m_pLeafMapCoords[unLeaf][13]+center[1]; + pkPosition[5].z=pLeaf->m_pLeafMapCoords[unLeaf][14]+center[2]; + pkPosition+=6; + center+=3; + } + + if (SUCCEEDED( + m_pLeafVertexBuffer[unLod]->Lock(0, 0, reinterpret_cast(&pVertex), D3DLOCK_DISCARD | D3DLOCK_NOSYSLOCK) + )) + { + UINT uVtxCount=pLeaf->m_usLeafCount*6; + for (UINT i = 0; im_pLeafMapCoords[unLeaf]+0, sizeof(D3DXVECTOR3)); + memcpy(vec1, pLeaf->m_pLeafMapCoords[unLeaf]+4, sizeof(D3DXVECTOR3)); + memcpy(vec2, pLeaf->m_pLeafMapCoords[unLeaf]+8, sizeof(D3DXVECTOR3)); + memcpy(vec3, pLeaf->m_pLeafMapCoords[unLeaf]+12, sizeof(D3DXVECTOR3)); + memcpy(vecCenter, pLeaf->m_pCenterCoords + unLeaf * 3, sizeof(D3DXVECTOR3)); + vec0 += vecCenter; + vec1 += vecCenter; + vec2 += vecCenter; + vec3 += vecCenter; + + pVertex[0].m_vPosition = vec0; + pVertex[3].m_vPosition = vec0; + pVertex[1].m_vPosition = vec1; + pVertex[4].m_vPosition = vec2; + pVertex[2].m_vPosition = vec2; + pVertex[5].m_vPosition = vec3; + */ + /* + for (UINT unLeaf = 0; unLeaf < pLeaf->m_usLeafCount; ++unLeaf) + { + D3DXVECTOR3 vecCenter(&(pLeaf->m_pCenterCoords[unLeaf * 3])); + D3DXVECTOR3 vec0(&pLeaf->m_pLeafMapCoords[unLeaf][0]); + D3DXVECTOR3 vec1(&pLeaf->m_pLeafMapCoords[unLeaf][4]); + D3DXVECTOR3 vec2(&pLeaf->m_pLeafMapCoords[unLeaf][8]); + D3DXVECTOR3 vec3(&pLeaf->m_pLeafMapCoords[unLeaf][12]); + + (pVertex++)->m_vPosition = vecCenter + vec0; // vertex 0 + (pVertex++)->m_vPosition = vecCenter + vec1; // vertex 1 + (pVertex++)->m_vPosition = vecCenter + vec2; // vertex 2 + (pVertex++)->m_vPosition = vecCenter + vec0; // vertex 0 + (pVertex++)->m_vPosition = vecCenter + vec2; // vertex 2 + (pVertex++)->m_vPosition = vecCenter + vec3; // vertex 3 + } + */ + m_pLeafVertexBuffer[unLod]->Unlock(); + } + } +#endif + } +#endif +#endif + + PositionTree(); + + // render LODs, if needed + for (UINT unLeafLevel = 0; unLeafLevel < 2; ++unLeafLevel) + { + const CSpeedTreeRT::SGeometry::SLeaf* pLeaf = (unLeafLevel == 0) ? + &m_pGeometryCache->m_sLeaves0 : &m_pGeometryCache->m_sLeaves1; + + int unLod = pLeaf->m_nDiscreteLodLevel; + + if (unLod > -1 && pLeaf->m_bIsActive && pLeaf->m_usLeafCount > 0) + { + STATEMANAGER.SetStreamSource(0, m_pLeafVertexBuffer[unLod], sizeof(SFVFLeafVertex)); + STATEMANAGER.SetRenderState(D3DRS_ALPHAREF, DWORD(pLeaf->m_fAlphaTestValue)); + + ms_faceCount += pLeaf->m_usLeafCount * 2; + STATEMANAGER.DrawPrimitive(D3DPT_TRIANGLELIST, 0, pLeaf->m_usLeafCount * 2); + } + } +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeWrapper::EndLeafForTreeType + +void CSpeedTreeWrapper::EndLeafForTreeType(void) +{ + // reset copy flags for CPU wind + for (UINT i = 0; i < m_usNumLeafLods; ++i) + m_pLeavesUpdatedByCpu[i] = false; +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeWrapper::RenderBillboards + +void CSpeedTreeWrapper::RenderBillboards(void) const +{ + // render billboards in immediate mode (as close as DirectX comes to immediate mode) +#ifdef WRAPPER_BILLBOARD_MODE + if (!m_CompositeImageInstance.IsEmpty()) + STATEMANAGER.SetTexture(0, m_CompositeImageInstance.GetTextureReference().GetD3DTexture()); + + PositionTree(); + + struct SBillboardVertex + { + float fX, fY, fZ; + float fU, fV; + }; + + m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_BillboardGeometry); + + if (m_pGeometryCache->m_sBillboard0.m_bIsActive) + { + const float* pCoords = m_pGeometryCache->m_sBillboard0.m_pCoords; + const float* pTexCoords = m_pGeometryCache->m_sBillboard0.m_pTexCoords; + SBillboardVertex sVertex[4] = + { + { pCoords[0], pCoords[1], pCoords[2], pTexCoords[0], pTexCoords[1] }, + { pCoords[3], pCoords[4], pCoords[5], pTexCoords[2], pTexCoords[3] }, + { pCoords[6], pCoords[7], pCoords[8], pTexCoords[4], pTexCoords[5] }, + { pCoords[9], pCoords[10], pCoords[11], pTexCoords[6], pTexCoords[7] }, + }; + + STATEMANAGER.SetVertexShader(D3DFVF_XYZ | D3DFVF_TEX1); + STATEMANAGER.SetRenderState(D3DRS_ALPHAREF, DWORD(m_pGeometryCache->m_sBillboard0.m_fAlphaTestValue)); + + ms_faceCount += 2; + STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, sVertex, sizeof(SBillboardVertex)); + } + + // if tree supports 360 degree billboards, render the second + if (m_pGeometryCache->m_sBillboard1.m_bIsActive) + { + const float* pCoords = m_pGeometryCache->m_sBillboard1.m_pCoords; + const float* pTexCoords = m_pGeometryCache->m_sBillboard1.m_pTexCoords; + SBillboardVertex sVertex[4] = + { + { pCoords[0], pCoords[1], pCoords[2], pTexCoords[0], pTexCoords[1] }, + { pCoords[3], pCoords[4], pCoords[5], pTexCoords[2], pTexCoords[3] }, + { pCoords[6], pCoords[7], pCoords[8], pTexCoords[4], pTexCoords[5] }, + { pCoords[9], pCoords[10], pCoords[11], pTexCoords[6], pTexCoords[7] }, + }; + STATEMANAGER.SetRenderState(D3DRS_ALPHAREF, DWORD(m_pGeometryCache->m_sBillboard1.m_fAlphaTestValue)); + + ms_faceCount += 2; + STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, sVertex, sizeof(SBillboardVertex)); + } + +#ifdef WRAPPER_RENDER_HORIZONTAL_BILLBOARD + // render horizontal billboard (if enabled) + if (m_pGeometryCache->m_sHorizontalBillboard.m_bIsActive) + { + const float* pCoords = m_pGeometryCache->m_sHorizontalBillboard.m_pCoords; + const float* pTexCoords = m_pGeometryCache->m_sHorizontalBillboard.m_pTexCoords; + SBillboardVertex sVertex[4] = + { + { pCoords[0], pCoords[1], pCoords[2], pTexCoords[0], pTexCoords[1] }, + { pCoords[3], pCoords[4], pCoords[5], pTexCoords[2], pTexCoords[3] }, + { pCoords[6], pCoords[7], pCoords[8], pTexCoords[4], pTexCoords[5] }, + { pCoords[9], pCoords[10], pCoords[11], pTexCoords[6], pTexCoords[7] }, + }; + STATEMANAGER.SetRenderState(D3DRS_ALPHAREF, DWORD(m_pGeometryCache->m_sHorizontalBillboard.m_fAlphaTestValue)); + + ms_faceCount += 2; + STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, sVertex, sizeof(SBillboardVertex)); + } + +#endif +#endif +} + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeWrapper::CleanUpMemory + +void CSpeedTreeWrapper::CleanUpMemory(void) +{ + if (!m_bIsInstance) + m_pSpeedTree->DeleteTransientData(); +} + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeWrapper::PositionTree + +void CSpeedTreeWrapper::PositionTree(void) const +{ + D3DXVECTOR3 vecPosition = m_pSpeedTree->GetTreePosition(); + D3DXMATRIX matTranslation; + D3DXMatrixIdentity(&matTranslation); + D3DXMatrixTranslation(&matTranslation, vecPosition.x, vecPosition.y, vecPosition.z); + + // store translation for client-side transformation + STATEMANAGER.SetTransform(D3DTS_WORLD, &matTranslation); + + // store translation for use in vertex shader + D3DXVECTOR4 vecConstant(vecPosition[0], vecPosition[1], vecPosition[2], 0.0f); + STATEMANAGER.SetVertexShaderConstant(c_nVertexShader_TreePos, (float*)&vecConstant, 1); +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeWrapper::LoadTexture + +bool CSpeedTreeWrapper::LoadTexture(const char * pFilename, CGraphicImageInstance & rImage) +{ + CResource * pResource = CResourceManager::Instance().GetResourcePointer(pFilename); + rImage.SetImagePointer(static_cast(pResource)); + + if (rImage.IsEmpty()) + return false; + + //TraceError("SpeedTreeWrapper::LoadTexture: %s", pFilename); + return true; +} + + +/////////////////////////////////////////////////////////////////////// +// CSpeedTreeWrapper::SetShaderConstants + +void CSpeedTreeWrapper::SetShaderConstants(const float* pMaterial) const +{ + const float afUsefulConstants[] = + { + m_pSpeedTree->GetLeafLightingAdjustment(), 0.0f, 0.0f, 0.0f, + }; + + STATEMANAGER.SetVertexShaderConstant(c_nVertexShader_LeafLightingAdjustment, afUsefulConstants, 1); + + const float afMaterial[] = + { + pMaterial[0], pMaterial[1], pMaterial[2], 1.0f, + pMaterial[3], pMaterial[4], pMaterial[5], 1.0f + }; + + STATEMANAGER.SetVertexShaderConstant(c_nVertexShader_Material, afMaterial, 2); +} + +void CSpeedTreeWrapper::SetPosition(float x, float y, float z) +{ + m_afPos[0] = x; + m_afPos[1] = y; + m_afPos[2] = z; + m_pSpeedTree->SetTreePosition(x, y, z); + CGraphicObjectInstance::SetPosition(x, y, z); +} + +bool CSpeedTreeWrapper::GetBoundingSphere(D3DXVECTOR3 & v3Center, float & fRadius) +{ + float fX, fY, fZ; + + fX = m_afBoundingBox[3] - m_afBoundingBox[0]; + fY = m_afBoundingBox[4] - m_afBoundingBox[1]; + fZ = m_afBoundingBox[5] - m_afBoundingBox[2]; + + v3Center.x = 0.0f; + v3Center.y = 0.0f; + v3Center.z = fZ * 0.5f; + + fRadius = sqrtf(fX * fX + fY * fY + fZ * fZ) * 0.5f * 0.9f; // 0.9f for reduce size + + D3DXVECTOR3 vec = m_pSpeedTree->GetTreePosition(); + + v3Center+=vec; + + return true; +} + +void CSpeedTreeWrapper::CalculateBBox() +{ + float fX, fY, fZ; + + fX = m_afBoundingBox[3] - m_afBoundingBox[0]; + fY = m_afBoundingBox[4] - m_afBoundingBox[1]; + fZ = m_afBoundingBox[5] - m_afBoundingBox[2]; + + m_v3BBoxMin.x = -fX / 2.0f; + m_v3BBoxMin.y = -fY / 2.0f; + m_v3BBoxMin.z = 0.0f; + m_v3BBoxMax.x = fX / 2.0f; + m_v3BBoxMax.y = fY / 2.0f; + m_v3BBoxMax.z = fZ; + + m_v4TBBox[0] = D3DXVECTOR4(m_v3BBoxMin.x, m_v3BBoxMin.y, m_v3BBoxMin.z, 1.0f); + m_v4TBBox[1] = D3DXVECTOR4(m_v3BBoxMin.x, m_v3BBoxMax.y, m_v3BBoxMin.z, 1.0f); + m_v4TBBox[2] = D3DXVECTOR4(m_v3BBoxMax.x, m_v3BBoxMin.y, m_v3BBoxMin.z, 1.0f); + m_v4TBBox[3] = D3DXVECTOR4(m_v3BBoxMax.x, m_v3BBoxMax.y, m_v3BBoxMin.z, 1.0f); + m_v4TBBox[4] = D3DXVECTOR4(m_v3BBoxMin.x, m_v3BBoxMin.y, m_v3BBoxMax.z, 1.0f); + m_v4TBBox[5] = D3DXVECTOR4(m_v3BBoxMin.x, m_v3BBoxMax.y, m_v3BBoxMax.z, 1.0f); + m_v4TBBox[6] = D3DXVECTOR4(m_v3BBoxMax.x, m_v3BBoxMin.y, m_v3BBoxMax.z, 1.0f); + m_v4TBBox[7] = D3DXVECTOR4(m_v3BBoxMax.x, m_v3BBoxMax.y, m_v3BBoxMax.z, 1.0f); + + const D3DXMATRIX & c_rmatTransform = GetTransform(); + + for (DWORD i = 0; i < 8; ++i) + { + D3DXVec4Transform(&m_v4TBBox[i], &m_v4TBBox[i], &c_rmatTransform); + if (0 == i) + { + m_v3TBBoxMin.x = m_v4TBBox[i].x; + m_v3TBBoxMin.y = m_v4TBBox[i].y; + m_v3TBBoxMin.z = m_v4TBBox[i].z; + m_v3TBBoxMax.x = m_v4TBBox[i].x; + m_v3TBBoxMax.y = m_v4TBBox[i].y; + m_v3TBBoxMax.z = m_v4TBBox[i].z; + } + else + { + if (m_v3TBBoxMin.x > m_v4TBBox[i].x) + m_v3TBBoxMin.x = m_v4TBBox[i].x; + if (m_v3TBBoxMax.x < m_v4TBBox[i].x) + m_v3TBBoxMax.x = m_v4TBBox[i].x; + if (m_v3TBBoxMin.y > m_v4TBBox[i].y) + m_v3TBBoxMin.y = m_v4TBBox[i].y; + if (m_v3TBBoxMax.y < m_v4TBBox[i].y) + m_v3TBBoxMax.y = m_v4TBBox[i].y; + if (m_v3TBBoxMin.z > m_v4TBBox[i].z) + m_v3TBBoxMin.z = m_v4TBBox[i].z; + if (m_v3TBBoxMax.z < m_v4TBBox[i].z) + m_v3TBBoxMax.z = m_v4TBBox[i].z; + } + } +} + +// collision detection routines +UINT CSpeedTreeWrapper::GetCollisionObjectCount() +{ + assert(m_pSpeedTree); + return m_pSpeedTree->GetCollisionObjectCount(); +} + +void CSpeedTreeWrapper::GetCollisionObject(UINT nIndex, CSpeedTreeRT::ECollisionObjectType& eType, float* pPosition, float* pDimensions) +{ + assert(m_pSpeedTree); + m_pSpeedTree->GetCollisionObject(nIndex, eType, pPosition, pDimensions); +} + + +const float * CSpeedTreeWrapper::GetPosition() +{ + return m_afPos; +} + +void CSpeedTreeWrapper::GetTreeSize(float & r_fSize, float & r_fVariance) +{ + m_pSpeedTree->GetTreeSize(r_fSize, r_fVariance); +} + +// pscdVector may be null +void CSpeedTreeWrapper::OnUpdateCollisionData(const CStaticCollisionDataVector * /*pscdVector*/) +{ + D3DXMATRIX mat; + D3DXMatrixTranslation(&mat, m_afPos[0], m_afPos[1], m_afPos[2]); + + ///// + for (UINT i = 0; i < GetCollisionObjectCount(); ++i) + { + CSpeedTreeRT::ECollisionObjectType ObjectType; + CStaticCollisionData CollisionData; + + GetCollisionObject(i, ObjectType, (float * )&CollisionData.v3Position, CollisionData.fDimensions); + + if (ObjectType == CSpeedTreeRT::CO_BOX) + continue; + + switch(ObjectType) + { + case CSpeedTreeRT::CO_SPHERE: + CollisionData.dwType = COLLISION_TYPE_SPHERE; + CollisionData.fDimensions[0] = CollisionData.fDimensions[0] /** fSizeRatio*/; + //AddCollision(&CollisionData); + break; + + case CSpeedTreeRT::CO_CYLINDER: + CollisionData.dwType = COLLISION_TYPE_CYLINDER; + CollisionData.fDimensions[0] = CollisionData.fDimensions[0] /** fSizeRatio*/; + CollisionData.fDimensions[1] = CollisionData.fDimensions[1] /** fSizeRatio*/; + //AddCollision(&CollisionData); + break; + + /*case CSpeedTreeRT::CO_BOX: + break;*/ + } + AddCollision(&CollisionData, &mat); + } +} diff --git a/source/SpeedTreeLib/SpeedTreeWrapper.h b/source/SpeedTreeLib/SpeedTreeWrapper.h new file mode 100644 index 0000000..ea9e9ce --- /dev/null +++ b/source/SpeedTreeLib/SpeedTreeWrapper.h @@ -0,0 +1,203 @@ +/////////////////////////////////////////////////////////////////////// +// SpeedTreeRTExample Class +// +// (c) 2003 IDV, Inc. +// +// This class is provided to illustrate one way to incorporate +// SpeedTreeRT into an OpenGL application. All of the SpeedTreeRT +// calls that must be made on a per tree basis are done by this class. +// Calls that apply to all trees (i.e. static SpeedTreeRT functions) +// are made in the functions in main.cpp. +// +// +// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION *** +// +// This software is supplied under the terms of a license agreement or +// nondisclosure agreement with Interactive Data Visualization and may +// not be copied or disclosed except in accordance with the terms of +// that agreement. +// +// Copyright (c) 2001-2003 IDV, Inc. +// All Rights Reserved. +// +// IDV, Inc. +// 1233 Washington St. Suite 610 +// Columbia, SC 29201 +// Voice: (803) 799-1699 +// Fax: (803) 931-0320 +// Web: http://www.idvinc.com +// + +#pragma once +#pragma warning (disable : 4786) + +/////////////////////////////////////////////////////////////////////// +// Include files + +#include "SpeedTreeMaterial.h" +#include + +#include +#include +#include +#include + +#include "../eterLib/GrpObjectInstance.h" +#include "../eterLib/GrpImageInstance.h" + +#ifndef SAFE_DELETE +#define SAFE_DELETE(p) { if (p) { delete (p); (p) = NULL; } } +#endif + +#ifndef SAFE_DELETE_ARRAY +#define SAFE_DELETE_ARRAY(p) { if (p) { delete[] (p); (p) = NULL; } } +#endif + +#ifndef SAFE_RELEASE +#define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p) = NULL; } } +#endif + +/////////////////////////////////////////////////////////////////////// +// class CSpeedTreeWrapper declaration +#pragma warning(push) +#pragma warning(disable:4100) + +class CSpeedTreeWrapper : public CGraphicObjectInstance +{ + enum + { + ID = TREE_OBJECT + }; + int GetType() const { return ID; } + + // Collision Data +protected: + virtual void OnUpdateCollisionData(const CStaticCollisionDataVector * pscdVector); + virtual void OnUpdateHeighInstance(CAttributeInstance * pAttributeInstance) {} + virtual bool OnGetObjectHeight(float fX, float fY, float * pfHeight) { return false; } + // Bounding Sphere +public: + virtual bool GetBoundingSphere(D3DXVECTOR3 & v3Center, float & fRadius); + +public: + static bool ms_bSelfShadowOn; + +public: + // methods from CGraphicObjectInstance + virtual void SetPosition(float x, float y, float z); + virtual void CalculateBBox(); + + virtual void OnRender(); // Render ÿ ޼ҵ, ׷ 䳪 Ư 쿡 Render θ + // ̿ܿ RenderBranches, RenderFronds ޼ҵ带 CSpeedTreeForest ȣѴ. + virtual void OnBlendRender() {} + virtual void OnRenderToShadowMap() {} + virtual void OnRenderShadow() {} + virtual void OnRenderPCBlocker(); + +public: + CSpeedTreeWrapper(); + virtual ~CSpeedTreeWrapper(); + + const float * GetPosition(); + static void SetVertexShaders(DWORD dwBranchVertexShader, DWORD dwLeafVertexShader); + + // geometry + bool LoadTree(const char * pszSptFile, const BYTE * c_pbBlock = NULL, unsigned int uiBlockSize = 0, unsigned int nSeed = 1, float fSize = -1.0f, float fSizeVariance = -1.0f); + const float * GetBoundingBox(void) const { return m_afBoundingBox; } + void GetTreeSize(float & r_fSize, float & r_fVariance); + UINT GetCollisionObjectCount(); + void GetCollisionObject(unsigned int nIndex, CSpeedTreeRT::ECollisionObjectType& eType, float* pPosition, float* pDimensions); + + // rendering + void SetupBranchForTreeType(void) const; + void SetupFrondForTreeType(void) const; + void SetupLeafForTreeType(void) const; + void EndLeafForTreeType(void); + +#ifdef WRAPPER_USE_GPU_LEAF_PLACEMENT + void UploadLeafTables(unsigned int uiLocation) const; +#endif + + void RenderBranches(void) const; + void RenderFronds(void) const; + void RenderLeaves(void) const; + void RenderBillboards(void) const; + + // instancing + CSpeedTreeWrapper ** GetInstances(unsigned int& nCount); + CSpeedTreeWrapper * InstanceOf(void) const { return m_pInstanceOf; } + CSpeedTreeWrapper * MakeInstance(); + void DeleteInstance(CSpeedTreeWrapper * pInstance); + CSpeedTreeRT * GetSpeedTree(void) const { return m_pSpeedTree; } + + // lighting + const CSpeedTreeMaterial & GetBranchMaterial(void) const { return m_cBranchMaterial; } + const CSpeedTreeMaterial & GetFrondMaterial(void) const { return m_cFrondMaterial; } + const CSpeedTreeMaterial & GetLeafMaterial(void) const { return m_cLeafMaterial; } + float GetLeafLightingAdjustment(void) const { return m_pSpeedTree->GetLeafLightingAdjustment( ); } + + // wind + void SetWindStrength(float fStrength) { m_pSpeedTree->SetWindStrength(fStrength); } + void Advance(void); + + // utility + LPDIRECT3DTEXTURE8 GetBranchTexture(void) const; + void CleanUpMemory(void); + +private: + void SetupBuffers(void); + void SetupBranchBuffers(void); + void SetupFrondBuffers(void); + void SetupLeafBuffers(void); + void PositionTree(void) const; + static bool LoadTexture(const char* pFilename, CGraphicImageInstance & rImage); + void SetShaderConstants(const float* pMaterial) const; + + +private: + // SpeedTreeRT data + CSpeedTreeRT* m_pSpeedTree; // the SpeedTree object + CSpeedTreeRT::STextures* m_pTextureInfo; // texture info cache + bool m_bIsInstance; // is this an instance? + std::vector m_vInstances; // what is an instance of us + CSpeedTreeWrapper* m_pInstanceOf; // which tree is this an instance of + + // geometry cache + CSpeedTreeRT::SGeometry* m_pGeometryCache; // cache for pulling geometry from SpeedTree avoids lots of reallocation + + // branch buffers + LPDIRECT3DVERTEXBUFFER8 m_pBranchVertexBuffer; // branch vertex buffer + unsigned int m_unBranchVertexCount; // number of vertices in branches + LPDIRECT3DINDEXBUFFER8 m_pBranchIndexBuffer; // branch index buffer + unsigned short* m_pBranchIndexCounts; // number of indexes per branch LOD level + + // frond buffers + LPDIRECT3DVERTEXBUFFER8 m_pFrondVertexBuffer; // frond vertex buffer + unsigned int m_unFrondVertexCount; // number of vertices in frond + LPDIRECT3DINDEXBUFFER8 m_pFrondIndexBuffer; // frond index buffer + unsigned short* m_pFrondIndexCounts; // number of indexes per frond LOD level + + // leaf buffers + unsigned short m_usNumLeafLods; // the number of leaf LODs + LPDIRECT3DVERTEXBUFFER8* m_pLeafVertexBuffer; // leaf vertex buffer + bool* m_pLeavesUpdatedByCpu; // stores which LOD's have been updated already per frame + + // tree properties + float m_afPos[3]; // tree position + float m_afBoundingBox[6]; // tree bounding box + + // materials + CSpeedTreeMaterial m_cBranchMaterial; // branch material + CSpeedTreeMaterial m_cLeafMaterial; // leaf material + CSpeedTreeMaterial m_cFrondMaterial; // frond material + + // branch texture + CGraphicImageInstance m_BranchImageInstance; + CGraphicImageInstance m_ShadowImageInstance; // shadow texture object (used if shadows are enabled) + CGraphicImageInstance m_CompositeImageInstance; + + static DWORD ms_dwBranchVertexShader; + static DWORD ms_dwLeafVertexShader; +}; + +#pragma warning(pop) diff --git a/source/SpeedTreeLib/StdAfx.cpp b/source/SpeedTreeLib/StdAfx.cpp new file mode 100644 index 0000000..a1d743a --- /dev/null +++ b/source/SpeedTreeLib/StdAfx.cpp @@ -0,0 +1,6 @@ +// stdafx.cpp : source file that includes just the standard includes +// SpeedTreeLib.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + diff --git a/source/SpeedTreeLib/StdAfx.h b/source/SpeedTreeLib/StdAfx.h new file mode 100644 index 0000000..002379b --- /dev/null +++ b/source/SpeedTreeLib/StdAfx.h @@ -0,0 +1,20 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +#include +//#include + +//#include "Forest.h" +#include "SpeedTreeForestDirectX8.h" + +// Armadillo nanomite protection +#ifndef NANOBEGIN + #ifdef __BORLANDC__ + #define NANOBEGIN __emit__ (0xEB,0x03,0xD6,0xD7,0x01) + #define NANOEND __emit__ (0xEB,0x03,0xD6,0xD7,0x00) + #else + #define NANOBEGIN __asm _emit 0xEB __asm _emit 0x03 __asm _emit 0xD6 __asm _emit 0xD7 __asm _emit 0x01 + #define NANOEND __asm _emit 0xEB __asm _emit 0x03 __asm _emit 0xD6 __asm _emit 0xD7 __asm _emit 0x00 + #endif +#endif diff --git a/source/SpeedTreeLib/VertexShaders.h b/source/SpeedTreeLib/VertexShaders.h new file mode 100644 index 0000000..6d5f2f9 --- /dev/null +++ b/source/SpeedTreeLib/VertexShaders.h @@ -0,0 +1,332 @@ +/////////////////////////////////////////////////////////////////////// +// SpeedTreeRT DirectX Example +// +// (c) 2003 IDV, Inc. +// +// This example demonstrates how to render trees using SpeedTreeRT +// and DirectX. Techniques illustrated include ".spt" file parsing, +// static lighting, dynamic lighting, LOD implementation, cloning, +// instancing, and dynamic wind effects. +// +// +// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION *** +// +// This software is supplied under the terms of a license agreement or +// nondisclosure agreement with Interactive Data Visualization and may +// not be copied or disclosed except in accordance with the terms of +// that agreement. +// +// Copyright (c) 2001-2003 IDV, Inc. +// All Rights Reserved. +// +// IDV, Inc. +// 1233 Washington St. Suite 610 +// Columbia, SC 29201 +// Voice: (803) 799-1699 +// Fax: (803) 931-0320 +// Web: http://www.idvinc.com + +/////////////////////////////////////////////////////////////////////// +// Includes + +#pragma once +#include "SpeedTreeConfig.h" +#include +#include + +/////////////////////////////////////////////////////////////////////// +// Branch & Frond Vertex Formats + +static DWORD D3DFVF_SPEEDTREE_BRANCH_VERTEX = + D3DFVF_XYZ | // always have the position + #ifdef WRAPPER_USE_DYNAMIC_LIGHTING // precomputed colors or geometric normals + D3DFVF_NORMAL | + #else + D3DFVF_DIFFUSE | + #endif + #ifdef WRAPPER_RENDER_SELF_SHADOWS + D3DFVF_TEX2 | D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEXCOORDSIZE2(1) // shadow texture coordinates + #else + D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0) // always have first texture layer coords + #endif + #ifdef WRAPPER_USE_GPU_WIND + | D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE2(2) // GPU Only - wind weight and index passed in second texture layer + #endif + ; + +/////////////////////////////////////////////////////////////////////// +// FVF Branch Vertex Structure + +struct SFVFBranchVertex +{ + D3DXVECTOR3 m_vPosition; // Always Used +#ifdef WRAPPER_USE_DYNAMIC_LIGHTING + D3DXVECTOR3 m_vNormal; // Dynamic Lighting Only +#else + DWORD m_dwDiffuseColor; // Static Lighting Only +#endif + FLOAT m_fTexCoords[2]; // Always Used +#ifdef WRAPPER_RENDER_SELF_SHADOWS + FLOAT m_fShadowCoords[2]; // Texture coordinates for the shadows +#endif +#ifdef WRAPPER_USE_GPU_WIND + FLOAT m_fWindIndex; // GPU Only + FLOAT m_fWindWeight; +#endif +}; + + +/////////////////////////////////////////////////////////////////////// +// Branch/Frond Vertex Program + +static const char g_achSimpleVertexProgram[] = +{ + "vs.1.1\n" // identity shader version + + "mov oT0.xy, v7\n" // always pass texcoord0 through + + #ifdef WRAPPER_RENDER_SELF_SHADOWS + "mov oT1.xy, v8\n" // pass shadow texcoords through if enabled + #endif + + // retrieve and convert wind matrix index + "mov a0.x, v9.x\n" + + // perform wind interpolation + "m4x4 r1, v0, c[54+a0.x]\n" // compute full wind effect + "sub r2, r1, v0\n" // compute difference between full wind and none + "mov r3.x, v9.y\n" // mad can't access two v's at once, use r3.x as tmp + "mad r1, r2, r3.x, v0\n" // perform interpolation + + "add r2, c[52], r1\n" // translate to tree's position + "m4x4 oPos, r2, c[0]\n" // project to screen + + #ifdef WRAPPER_USE_FOG + "dp4 r1, r2, c[2]\n" // find distance to vertex + "sub r2.x, c[85].y, r1.z\n" // linear fogging + "mul oFog, r2.x, c[85].z\n" // write to fog register + #endif + + #ifdef WRAPPER_USE_STATIC_LIGHTING + "mov oD0, v5\n" // pass color through + #else + "mov r1, c[74]\n" // can only use one const register per instruction + "mul r5, c[73], r1\n" // diffuse values + + "mov r1, c[75]\n" // can only use one const register per instruction + "mul r4, c[72], r1\n" // ambient values + + "dp3 r2, v3, c[71]\n" // dot light direction with normal +// "max r2.x, r2.x, c[70].x\n" // limit it + "mad oD0, r2.x, r5, r4\n" // compute the final color + #endif +}; + + +/////////////////////////////////////////////////////////////////////// +// LoadBranchShader + +static DWORD LoadBranchShader(LPDIRECT3DDEVICE8 pDx) +{ + #ifndef WRAPPER_USE_GPU_WIND + return D3DFVF_SPEEDTREE_BRANCH_VERTEX; + #endif + + // branch shader declaration + DWORD pBranchShaderDecl[] = + { + D3DVSD_STREAM(0), + D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3), + #ifdef WRAPPER_USE_DYNAMIC_LIGHTING + D3DVSD_REG(D3DVSDE_NORMAL, D3DVSDT_FLOAT3), + #else + D3DVSD_REG(D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR), + #endif + D3DVSD_REG(D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2), + #ifdef WRAPPER_RENDER_SELF_SHADOWS + D3DVSD_REG(D3DVSDE_TEXCOORD1, D3DVSDT_FLOAT2), + #endif + #ifdef WRAPPER_USE_GPU_WIND + D3DVSD_REG(D3DVSDE_TEXCOORD2, D3DVSDT_FLOAT2), + #endif + D3DVSD_END( ) + }; + + // assemble shader + DWORD dwShader; + LPD3DXBUFFER pCode, pError; + + if (D3DXAssembleShader(g_achSimpleVertexProgram, sizeof(g_achSimpleVertexProgram) - 1, 0, NULL, &pCode, &pError) == D3D_OK) + { + if (pDx->CreateVertexShader(pBranchShaderDecl, (DWORD*) pCode->GetBufferPointer( ), &dwShader, 0) != D3D_OK) + { + char szError[1024]; + sprintf(szError, "Failed to create branch vertex shader."); + MessageBox(NULL, szError, "Vertex Shader Error", MB_ICONSTOP); + } + } + else + { + char szError[1024]; + sprintf(szError, "Failed to assemble branch vertex shader.\nThe error reported is [ %s ].\n", pError->GetBufferPointer( )); + MessageBox(NULL, szError, "Vertex Shader Error", MB_ICONSTOP); + } + + if (pCode) + pCode->Release(); + + return dwShader; +} + +/////////////////////////////////////////////////////////////////////// +// Leaf Vertex Formats + +static DWORD D3DFVF_SPEEDTREE_LEAF_VERTEX = + D3DFVF_XYZ | // always have the position + #ifdef WRAPPER_USE_DYNAMIC_LIGHTING // precomputed colors or geometric normals + D3DFVF_NORMAL | + #else + D3DFVF_DIFFUSE | + #endif + D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0) // always have first texture layer coords + #if defined WRAPPER_USE_GPU_WIND || defined WRAPPER_USE_GPU_LEAF_PLACEMENT + | D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE4(2) // GPU Only - wind weight and index passed in second texture layer + #endif + ; + + +/////////////////////////////////////////////////////////////////////// +// FVF Leaf Vertex Structure + +struct SFVFLeafVertex +{ + D3DXVECTOR3 m_vPosition; // Always Used + #ifdef WRAPPER_USE_DYNAMIC_LIGHTING + D3DXVECTOR3 m_vNormal; // Dynamic Lighting Only + #else + DWORD m_dwDiffuseColor; // Static Lighting Only + #endif + FLOAT m_fTexCoords[2]; // Always Used + #if defined WRAPPER_USE_GPU_WIND || defined WRAPPER_USE_GPU_LEAF_PLACEMENT + FLOAT m_fWindIndex; // Only used when GPU is involved + FLOAT m_fWindWeight; + FLOAT m_fLeafPlacementIndex; + FLOAT m_fLeafScalarValue; + #endif +}; + + +/////////////////////////////////////////////////////////////////////// +// Leaf Vertex Program + +static const char g_achLeafVertexProgram[] = +{ + "vs.1.1\n" // identity shader version + + "mov oT0.xy, v7\n" // always pass texcoord0 through + + #ifdef WRAPPER_USE_GPU_WIND + // retrieve and convert wind matrix index + "mov a0.x, v9.x\n" + + // perform wind interpolation + "m4x4 r1, v0, c[54+a0.x]\n" // compute full wind effect + "sub r2, r1, v0\n" // compute difference between full wind and none + "mov r3.x, v9.y\n" // mad can't access two v's at once, use r3.x as tmp + "mad r0, r2, r3.x, v0\n" // perform interpolation + #else + "mov r0, v0\n" // wind already handled, pass the vertex through + #endif + + #ifdef WRAPPER_USE_GPU_LEAF_PLACEMENT + "mov a0.x, v9.z\n" // place the leaves + "mul r1, c[a0.x], v9.w\n" + "add r0, r1, r0\n" + #endif + + "add r0, c[52], r0\n" // translate to tree's position + "m4x4 oPos, r0, c[0]\n" // project to screen + + #ifdef WRAPPER_USE_FOG + "dp4 r1, r0, c[2]\n" // find distance to vertex + "sub r2.x, c[85].y, r1.z\n" // + "mul oFog, r2.x, c[85].z\n" + #endif + + #ifdef WRAPPER_USE_STATIC_LIGHTING + "mov oD0, v5\n" // pass color through + #else + "mov r1, c[74]\n" // can only use one const register per instruction + "mul r5, c[73], r1\n" // diffuse values + + "mov r1, c[75]\n" // can only use one const register per instruction + "mul r4, c[72], r1\n" // ambient values + + "dp3 r2.x, v3, c[71]\n" // dot light direction with normal + "max r2.x, r2.x, c[70].x\n" // limit it + "mad oD0, r2.x, r5, r4\n" // compute the final color + #endif +}; + + +/////////////////////////////////////////////////////////////////////// +// LoadLeafShader + +static DWORD LoadLeafShader(LPDIRECT3DDEVICE8 pDx) +{ + DWORD dwShader = D3DFVF_SPEEDTREE_LEAF_VERTEX; + + #if defined WRAPPER_USE_GPU_LEAF_PLACEMENT || defined WRAPPER_USE_GPU_WIND + + // leaf shader declaration + DWORD pLeafShaderDecl[ ] = + { + D3DVSD_STREAM(0), + D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3), + #ifdef WRAPPER_USE_DYNAMIC_LIGHTING + D3DVSD_REG(D3DVSDE_NORMAL, D3DVSDT_FLOAT3), + #else + D3DVSD_REG(D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR), + #endif + D3DVSD_REG(D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2), + D3DVSD_REG(D3DVSDE_TEXCOORD2, D3DVSDT_FLOAT4), + D3DVSD_END( ) + }; + + // assemble shader + LPD3DXBUFFER pCode, pError; + + if (D3DXAssembleShader(g_achLeafVertexProgram, sizeof(g_achLeafVertexProgram) - 1, 0, NULL, &pCode, &pError) == D3D_OK) + { + if (pDx->CreateVertexShader(pLeafShaderDecl, (DWORD*) pCode->GetBufferPointer( ), &dwShader, 0) != D3D_OK) + { + Tracef("Failed to create leaf vertex shader."); + /* + char szError[1024]; + sprintf(szError, "Failed to create leaf vertex shader."); + MessageBox(NULL, szError, "Vertex Shader Error", MB_ICONSTOP); + */ + } + } + else + { + Tracef("Failed to assemble leaf vertex shader. The error reported is [ %s ].\n", pError->GetBufferPointer( )); + /* + char szError[1024]; + sprintf(szError, "Failed to assemble leaf vertex shader. The error reported is [ %s ].\n", pError->GetBufferPointer( )); + MessageBox(NULL, szError, "Vertex Shader Error", MB_ICONSTOP); + */ + } + + if (pCode) + pCode->Release( ); + + #else + + dwShader = D3DFVF_SPEEDTREE_LEAF_VERTEX; + + #endif + + return dwShader; +} + \ No newline at end of file diff --git a/source/SphereLib/StdAfx.cpp b/source/SphereLib/StdAfx.cpp new file mode 100644 index 0000000..75e308b --- /dev/null +++ b/source/SphereLib/StdAfx.cpp @@ -0,0 +1,6 @@ +// stdafx.cpp : source file that includes just the standard includes +// SphereLib.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + diff --git a/source/SphereLib/StdAfx.h b/source/SphereLib/StdAfx.h new file mode 100644 index 0000000..9a69b87 --- /dev/null +++ b/source/SphereLib/StdAfx.h @@ -0,0 +1,16 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +//#define SPHERELIB_STRICT +//#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "../eterBase/StdAfx.h" diff --git a/source/SphereLib/frustum.cpp b/source/SphereLib/frustum.cpp new file mode 100644 index 0000000..6a9212f --- /dev/null +++ b/source/SphereLib/frustum.cpp @@ -0,0 +1,93 @@ +/* Copyright (C) John W. Ratcliff, 2001. + * All rights reserved worldwide. + * + * This software is provided "as is" without express or implied + * warranties. You may freely copy and compile this source into + * applications you distribute provided that the copyright text + * below is included in the resulting source code, for example: + * "Portions Copyright (C) John W. Ratcliff, 2001" + */ + +#include "Stdafx.h" +#include "frustum.h" + +//#include "frustum.h" + +/*void Frustum::Set(int x1,int y1,int x2,int y2) +{ + mX1 = x1; + mY1 = y1; + mX2 = x2; + mY2 = y2; +} + +*/ +ViewState Frustum::ViewVolumeTest(const Vector3d &c_v3Center,const float c_fRadius) const +{ + if (m_bUsingSphere) + { + D3DXVECTOR3 v( + c_v3Center.x-m_v3Center.x, + c_v3Center.y-m_v3Center.y, + c_v3Center.z-m_v3Center.z); + + if ((c_fRadius + m_fRadius) * (c_fRadius + m_fRadius) < D3DXVec3LengthSq(&v)) + { + return VS_OUTSIDE; + } + } + + const int count=6; + + D3DXVECTOR3 center = c_v3Center; + //center.y *=-1; + + int i; + + float distance[count]; + for(i=0;i class Pool +{ +public: + Pool(void) + { + mHead = 0; + mFree = 0; + mData = 0; + mCurrent = 0; + mFreeCount = 0; + mUsedCount = 0; + }; + + ~Pool(void) + { + if (mData) + delete [] mData; + }; + + + void Release(void) + { + if (mData) + delete [] mData; + + mHead = 0; + mFree = 0; + + mData = 0; + mCurrent = 0; + mFreeCount = 0; + mUsedCount = 0; + }; + + void Set(int maxitems) + { + if (mData) + delete [] mData; // delete any previous incarnation. + mMaxItems = maxitems; + mData = new Type[mMaxItems]; + mFree = mData; + mHead = 0; + int loopValue = (mMaxItems-1); + for (int i=0; i + mFreeCount = maxitems; + mUsedCount = 0; + }; + + + Type * GetNext(bool &looped) + { + + looped = false; //default value + + if ( !mHead ) return 0; // there is no data to process. + Type *ret; + + if ( !mCurrent ) + { + ret = mHead; + looped = true; + } + else + { + ret = mCurrent; + } + + if ( ret ) mCurrent = ret->GetNext(); + + + return ret; + }; + + bool IsEmpty(void) const + { + if ( !mHead ) return true; + return false; + }; + + int Begin(void) + { + mCurrent = mHead; + return mUsedCount; + }; + + int GetUsedCount(void) const { return mUsedCount; }; + int GetFreeCount(void) const { return mFreeCount; }; + + Type * GetNext(void) + { + if ( !mHead ) return 0; // there is no data to process. + + Type *ret; + + if ( !mCurrent ) + { + ret = mHead; + } + else + { + ret = mCurrent; + } + + if ( ret ) mCurrent = ret->GetNext(); + + + return ret; + }; + + void Release(Type *t) + { + + if ( t == mCurrent ) mCurrent = t->GetNext(); + + // first patch old linked list.. his previous now points to his next + Type *prev = t->GetPrevious(); + + if ( prev ) + { + Type *next = t->GetNext(); + prev->SetNext( next ); // my previous now points to my next + if ( next ) next->SetPrevious(prev); + // list is patched! + } + else + { + Type *next = t->GetNext(); + mHead = next; + if ( mHead ) mHead->SetPrevious(0); + } + + Type *temp = mFree; // old head of free list. + mFree = t; // new head of linked list. + t->SetPrevious(0); + t->SetNext(temp); + + mUsedCount--; + mFreeCount++; + }; + + Type * GetFreeNoLink(void) // get free, but don't link it to the used list!! + { + // Free allocated items are always added to the head of the list + if ( !mFree ) return 0; + Type *ret = mFree; + mFree = ret->GetNext(); // new head of free list + mUsedCount++; + mFreeCount--; + ret->SetNext(0); + ret->SetPrevious(0); + return ret; + }; + + Type * GetFreeLink(void) + { + // Free allocated items are always added to the head of the list + if ( !mFree ) return 0; + Type *ret = mFree; + mFree = ret->GetNext(); // new head of free list + Type *temp = mHead; // current head of list + mHead = ret; // new head of list is this free one + if ( temp ) temp->SetPrevious(ret); + mHead->SetNext(temp); + mHead->SetPrevious(0); + mUsedCount++; + mFreeCount--; + return ret; + }; + + void AddAfter(Type *e,Type *item) + { + // Add 'item' after 'e' + if ( e ) + { + Type *eprev = e->GetPrevious(); + Type *enext = e->GetNext(); + e->SetNext(item); + item->SetNext(enext); + item->SetPrevious(e); + if ( enext ) enext->SetPrevious(item); + } + else + { + mHead = item; + item->SetPrevious(0); + item->SetNext(0); + } + + } + + void AddBefore(Type *e,Type *item) + { + // Add 'item' before 'e' + Type *eprev = e->GetPrevious(); + Type *enext = e->GetNext(); + + if ( !eprev ) + mHead = item; + else + eprev->SetNext(item); + + item->SetPrevious(eprev); + item->SetNext(e); + + e->SetPrevious(item); + + } + + +private: + int mMaxItems; + Type *mCurrent; // current iteration location. + Type *mData; + Type *mHead; // head of used list. + Type *mFree; // head of free list. + int mUsedCount; + int mFreeCount; +}; diff --git a/source/SphereLib/sphere.cpp b/source/SphereLib/sphere.cpp new file mode 100644 index 0000000..51aaed4 --- /dev/null +++ b/source/SphereLib/sphere.cpp @@ -0,0 +1,248 @@ +/* Copyright (C) John W. Ratcliff, 2001. + * All rights reserved worldwide. + * + * This software is provided "as is" without express or implied + * warranties. You may freely copy and compile this source into + * applications you distribute provided that the copyright text + * below is included in the resulting source code, for example: + * "Portions Copyright (C) John W. Ratcliff, 2001" + */ + +#include "Stdafx.h" +#include "sphere.h" + +#include +#include +#include +#include + +bool Vector3d::IsInStaticRange() const +{ + const float LIMIT = 3276700.0f; + if (x-LIMIT) + if (y-LIMIT) + if (z-LIMIT) + return true; + + return false; +} + +void Sphere::Set(const Vector3d ¢er, float radius) +{ +#ifdef __STATIC_RANGE__ + assert(center.IsInStaticRange()); +#endif + mCenter = center; + mRadius = radius; + mRadius2 = radius*radius; +} + + +//ray-sphere intersection test from Graphics Gems p.388 +// **NOTE** There is a bug in this Graphics Gem. If the origin +// of the ray is *inside* the sphere being tested, it reports the +// wrong intersection location. This code has a fix for the bug. +bool Sphere::RayIntersection(const Vector3d &rayOrigin, + const Vector3d &dir, + Vector3d *intersect) +{ + //notation: + //point E = rayOrigin + //point O = sphere center + + Vector3d EO = mCenter - rayOrigin; + Vector3d V = dir; + float dist2 = EO.x*EO.x + EO.y*EO.y + EO.z * EO.z; + // Bug Fix For Gem, if origin is *inside* the sphere, invert the + // direction vector so that we get a valid intersection location. + if ( dist2 < mRadius2 ) V*=-1; + + float v = EO.Dot(V); + + float disc = mRadius2 - (EO.Length2() - v*v); + + if (disc > 0.0f) + { + + if ( intersect ) + { + + float d = sqrtf(disc); + + //float dist2 = rayOrigin.DistanceSq(mCenter); + + *intersect = rayOrigin + V*(v-d); + + } + + return true; + } + return false; +} + +// +bool Sphere::RayIntersection(const Vector3d &rayOrigin, + const Vector3d &V, + float distance, + Vector3d *intersect) +{ + Vector3d sect; + bool hit = RayIntersectionInFront(rayOrigin,V,§); + + if ( hit ) + { + float d = rayOrigin.DistanceSq(sect); + if ( d > (distance*distance) ) return false; + if ( intersect ) *intersect = sect; + return true; + } + return false; +} + + +bool Sphere::RayIntersectionInFront(const Vector3d &rayOrigin, + const Vector3d &V, + Vector3d *intersect) +{ + Vector3d sect; + bool hit = RayIntersection(rayOrigin,V,§); + + if ( hit ) + { + + Vector3d dir = sect - rayOrigin; + + float dot = dir.Dot(V); + + if ( dot >= 0 ) // then it's in front! + { + if ( intersect ) *intersect = sect; + return true; + } + } + return false; +} + +void Sphere::Report(void) +{ +} + +/* +An Efficient Bounding Sphere +by Jack Ritter +from "Graphics Gems", Academic Press, 1990 +*/ + +/* Routine to calculate tight bounding sphere over */ +/* a set of points in 3D */ +/* This contains the routine find_bounding_sphere(), */ +/* the struct definition, and the globals used for parameters. */ +/* The abs() of all coordinates must be < BIGNUMBER */ +/* Code written by Jack Ritter and Lyle Rains. */ + +#define BIGNUMBER 100000000.0 /* hundred million */ + +void Sphere::Compute(const SphereInterface &source) +{ + + Vector3d xmin,xmax,ymin,ymax,zmin,zmax,dia1,dia2; + + /* FIRST PASS: find 6 minima/maxima points */ + xmin.Set(BIGNUMBER,BIGNUMBER,BIGNUMBER); + xmax.Set(-BIGNUMBER,-BIGNUMBER,-BIGNUMBER); + ymin.Set(BIGNUMBER,BIGNUMBER,BIGNUMBER); + ymax.Set(-BIGNUMBER,-BIGNUMBER,-BIGNUMBER); + zmin.Set(BIGNUMBER,BIGNUMBER,BIGNUMBER); + zmax.Set(-BIGNUMBER,-BIGNUMBER,-BIGNUMBER); + + int count = source.GetVertexCount(); + + for (int i=0; ixmax.GetX()) xmax = caller_p; + if (caller_p.GetY()ymax.GetY()) ymax = caller_p; + if (caller_p.GetZ()zmax.GetZ()) zmax = caller_p; + } + + /* Set xspan = distance between the 2 points xmin & xmax (squared) */ + float dx = xmax.GetX() - xmin.GetX(); + float dy = xmax.GetY() - xmin.GetY(); + float dz = xmax.GetZ() - xmin.GetZ(); + float xspan = dx*dx + dy*dy + dz*dz; + + /* Same for y & z spans */ + dx = ymax.GetX() - ymin.GetX(); + dy = ymax.GetY() - ymin.GetY(); + dz = ymax.GetZ() - ymin.GetZ(); + float yspan = dx*dx + dy*dy + dz*dz; + + dx = zmax.GetX() - zmin.GetX(); + dy = zmax.GetY() - zmin.GetY(); + dz = zmax.GetZ() - zmin.GetZ(); + float zspan = dx*dx + dy*dy + dz*dz; + + /* Set points dia1 & dia2 to the maximally separated pair */ + dia1 = xmin; + dia2 = xmax; /* assume xspan biggest */ + float maxspan = xspan; + + if (yspan>maxspan) + { + maxspan = yspan; + dia1 = ymin; + dia2 = ymax; + } + + if (zspan>maxspan) + { + dia1 = zmin; + dia2 = zmax; + } + + + /* dia1,dia2 is a diameter of initial sphere */ + /* calc initial center */ + mCenter.SetX( (dia1.GetX()+dia2.GetX())*0.5f ); + mCenter.SetY( (dia1.GetY()+dia2.GetY())*0.5f ); + mCenter.SetZ( (dia1.GetZ()+dia2.GetZ())*0.5f ); + /* calculate initial radius**2 and radius */ + dx = dia2.GetX()-mCenter.GetX(); /* x component of radius vector */ + dy = dia2.GetY()-mCenter.GetY(); /* y component of radius vector */ + dz = dia2.GetZ()-mCenter.GetZ(); /* z component of radius vector */ + mRadius2 = dx*dx + dy*dy + dz*dz; + mRadius = float(sqrt(mRadius2)); + + /* SECOND PASS: increment current sphere */ + + for (int j=0; j mRadius2) /* do r**2 test first */ + { /* this point is outside of current sphere */ + float old_to_p = float(sqrt(old_to_p_sq)); + /* calc radius of new sphere */ + mRadius = (mRadius + old_to_p) * 0.5f; + mRadius2 = mRadius*mRadius; /* for next r**2 compare */ + float old_to_new = old_to_p - mRadius; + /* calc center of new sphere */ + float recip = 1.0f /old_to_p; + + float cx = (mRadius*mCenter.GetX() + old_to_new*caller_p.GetX()) * recip; + float cy = (mRadius*mCenter.GetY() + old_to_new*caller_p.GetY()) * recip; + float cz = (mRadius*mCenter.GetZ() + old_to_new*caller_p.GetZ()) * recip; + + mCenter.Set(cx,cy,cz); + } + } +} diff --git a/source/SphereLib/sphere.h b/source/SphereLib/sphere.h new file mode 100644 index 0000000..6e8af25 --- /dev/null +++ b/source/SphereLib/sphere.h @@ -0,0 +1,106 @@ +/* Copyright (C) John W. Ratcliff, 2001. +* All rights reserved worldwide. +* +* This software is provided "as is" without express or implied +* warranties. You may freely copy and compile this source into +* applications you distribute provided that the copyright text +* below is included in the resulting source code, for example: +* "Portions Copyright (C) John W. Ratcliff, 2001" +*/ +#pragma once + +#include "vector.h" + + +/***********************************************************************/ +/** SPHERE.H : Base class to represent a Sphere in 3 space. */ +/** */ +/** Written by John W. Ratcliff jratcliff@att.net */ +/***********************************************************************/ + +class SphereInterface +{ +public: + SphereInterface(); + virtual ~SphereInterface(); + virtual int GetVertexCount(void) const = 0; + virtual bool GetVertex(int i,Vector3d &vect) const = 0; +private: +}; + + + +class Sphere +{ +public: + Sphere(); + Sphere(const Vector3d ¢er, float radius); + + virtual ~Sphere() {} + + void Set(const Vector3d ¢er, float radius); + + void Compute(const SphereInterface &source); + + float GetRadius(void) const { return mRadius; }; + float GetRadius2(void) const { return mRadius2; }; + const Vector3d& GetCenter(void) const { return mCenter; }; + + bool RayIntersection(const Vector3d &rayOrigin, + const Vector3d &V, + float distance, + Vector3d *intersect); + + + bool RayIntersection(const Vector3d &rayOrigin, + const Vector3d &rayDirection, + Vector3d *intersect); + + bool RayIntersectionInFront(const Vector3d &rayOrigin, + const Vector3d &rayDirection, + Vector3d *intersect); + + void Report(void); + + void SetRadius(float radius) + { + mRadius = radius; + mRadius2 = radius*radius; + } + + + bool InSphereXY(const Vector3d &pos,float distance) const + { + float dx = pos.x - mCenter.x; + float dy = pos.y - mCenter.y; + float dist = sqrtf( dx*dx + dy*dy ); + if ( dist < (mRadius+distance) ) return true; + return false; + }; + + bool InSphere(const Vector3d &pos,float distance) const + { + float dx = pos.x - mCenter.x; + float dy = pos.y - mCenter.y; + float dz = pos.z - mCenter.z; + + float dist = sqrtf( dx*dx + dy*dy + dz*dz ); + if ( dist < (mRadius+distance) ) return true; + return false; + } + + + +protected: + Vector3d mCenter; +private: + float mRadius; + float mRadius2; // radius squared. +}; + + +inline Sphere::Sphere() +: mCenter(Vector3d(0.0f, 0.0f, 0.0f)), mRadius(0.0f), mRadius2(0.0f) { }; + +inline Sphere::Sphere(const Vector3d ¢er, float radius) +: mCenter(center), mRadius(radius), mRadius2(radius*radius) { }; diff --git a/source/SphereLib/spherepack.cpp b/source/SphereLib/spherepack.cpp new file mode 100644 index 0000000..5bacb4d --- /dev/null +++ b/source/SphereLib/spherepack.cpp @@ -0,0 +1,878 @@ +/* Copyright (C) John W. Ratcliff, 2001. + * All rights reserved worldwide. + * + * This software is provided "as is" without express or implied + * warranties. You may freely copy and compile this source into + * applications you distribute provided that the copyright text + * below is included in the resulting source code, for example: + * "Portions Copyright (C) John W. Ratcliff, 2001" + */ + +#include "Stdafx.h" +#include "spherepack.h" + +#if DEMO +int PrintText(int x, int y, int color, char* output, ...); +int DrawLine(int x1, int y1, int x2, int y2, int color); +int DrawCircle(int locx, int locy, int radius, int color); +#endif + +SpherePackFactory::SpherePackFactory(int maxspheres, float rootsize, float leafsize, float gravy) +{ + NANOBEGIN + maxspheres *= 4; // include room for both trees, the root node and leaf node tree, and the superspheres + mMaxRootSize = rootsize; + mMaxLeafSize = leafsize; + mSuperSphereGravy = gravy; + mIntegrate = new SpherePackFifo(maxspheres); + mRecompute = new SpherePackFifo(maxspheres); + + mSpheres.Set(maxspheres); // init pool to hold all possible SpherePack instances. + + Vector3d p(0,0,0); + + mRoot = mSpheres.GetFreeLink(); // initially empty + mRoot->Init(this,p,6553600,0, false); + mRoot->SetSpherePackFlag(SpherePackFlag(SPF_SUPERSPHERE | SPF_ROOTNODE | SPF_ROOT_TREE)); + +#if DEMO + mRoot->SetColor(0x00FFFFFF); +#endif + + mLeaf = mSpheres.GetFreeLink();; // initially empty + mLeaf->Init(this,p,1638400,0,false); + mLeaf->SetSpherePackFlag(SpherePackFlag(SPF_SUPERSPHERE | SPF_ROOTNODE | SPF_LEAF_TREE)); + +#if DEMO + mLeaf->SetColor(0x00FFFFFF); + mColorCount = 0; + + mColors[0] = 0x00FF0000; + mColors[1] = 0x0000FF00; + mColors[2] = 0x000000FF; + mColors[3] = 0x00FFFF00; + mColors[4] = 0x00FF00FF; + mColors[5] = 0x0000FFFF; + mColors[6] = 0x00FF8080; + mColors[7] = 0x0000FF80; + mColors[8] = 0x000080FF; + mColors[9] = 0x00FFFF80; + mColors[10] = 0x00FF80FF; + mColors[11] = 0x0080FFFF; + +#endif + NANOEND +} + +SpherePackFactory::~SpherePackFactory(void) +{ + delete mIntegrate; // free up integration fifo + delete mRecompute; // free up recomputation fifo. +} + +void SpherePackFactory::Process(void) +{ + { + // First recompute anybody that needs to be recomputed!! + // When leaf node spheres exit their parent sphere, then the parent sphere needs to be rebalanced. In fact,it may now be empty and + // need to be removed. + // This is the location where (n) number of spheres in the recomputation FIFO are allowed to be rebalanced in the tree. + int maxrecompute = mRecompute->GetCount(); + for (int i = 0; i < maxrecompute; ++i) + { + SpherePack * pack = mRecompute->Pop(); + if (!pack) break; + pack->SetFifo1(0); // no longer on the fifo!! + bool kill = pack->Recompute(mSuperSphereGravy); + if (kill) Remove(pack); + } + } + + { + // Now, process the integration step. + int maxintegrate = mIntegrate->GetCount(); + + for (int i = 0; i < maxintegrate; ++i) + { + SpherePack * pack = mIntegrate->Pop(); + if (!pack) + break; + pack->SetFifo2(0); + + if (pack->HasSpherePackFlag(SPF_ROOT_TREE)) + Integrate(pack,mRoot,mMaxRootSize); // integrate this one single dude against the root node. + else + Integrate(pack,mLeaf,mMaxLeafSize); // integrate this one single dude against the root node. + } + } + +} + + +SpherePack * SpherePackFactory::AddSphere_(const Vector3d &pos, + float radius, + void *userdata, + bool isSphere, + int flags) +{ + + SpherePack *pack = mSpheres.GetFreeLink(); + + assert(pack); + + if (pack) + { + if (flags & SPF_ROOT_TREE) + { + pack->Init(this,pos,radius,userdata, isSphere); + pack->SetSpherePackFlag(SPF_ROOT_TREE); // member of the leaf node tree! + AddIntegrate(pack); // add to integration list. + } + else + { + pack->Init(this,pos,radius,userdata, isSphere); + pack->SetSpherePackFlag(SPF_LEAF_TREE); // member of the leaf node tree! + AddIntegrate(pack); // add to integration list. + } + } + + return pack; +} + +void SpherePackFactory::AddIntegrate(SpherePack *pack) +{ + if (pack->HasSpherePackFlag(SPF_ROOT_TREE)) + mRoot->AddChild(pack); + else + mLeaf->AddChild(pack); + + pack->SetSpherePackFlag(SPF_INTEGRATE); // still needs to be integrated! + SpherePack **fifo = mIntegrate->Push(pack); // add it to the integration stack. + pack->SetFifo2(fifo); +} + +void SpherePackFactory::AddRecompute(SpherePack *recompute) +{ + if (!recompute->HasSpherePackFlag(SPF_RECOMPUTE)) + { + if (recompute->GetChildCount()) + { + recompute->SetSpherePackFlag(SPF_RECOMPUTE); // needs to be recalculated! + SpherePack **fifo = mRecompute->Push(recompute); + recompute->SetFifo1(fifo); + } + else + { + Remove(recompute); + } + } +} + +void SpherePackFactory::Render(void) +{ +#if DEMO + mRoot->Render(mRoot->GetColor()); + mLeaf->Render(mLeaf->GetColor()); +#endif +} + + +void SpherePack::Render(unsigned int /*color*/) +{ +#if DEMO + if (!HasSpherePackFlag(SPF_ROOTNODE)) + { + + if (HasSpherePackFlag(SPF_SUPERSPHERE)) + { + color = mColor; + } + else + { + if (mParent->HasSpherePackFlag(SPF_ROOTNODE)) color = 0x00FFFFFF; + } +#if DEMO + DrawCircle(int(mCenter.x), int(mCenter.y),int(GetRadius()),color); +#endif + if (HasSpherePackFlag(SPF_SUPERSPHERE)) + { + if (HasSpherePackFlag(SPF_LEAF_TREE)) + { + +#if DEMO + DrawCircle(int(mCenter.x), int(mCenter.y),int(GetRadius()),color); +#endif +#ifdef SPHERELIB_STRICT + if (!sphere->IS_SPHERE) + puts("SpherePack::Render"); +#endif + SpherePack *link = (SpherePack *) GetUserData(); + + link = link->GetParent(); + + if (link && !link->HasSpherePackFlag(SPF_ROOTNODE)) + { + DrawLine(int(mCenter.x), int(mCenter.y), + int(link->mCenter.x), int(link->mCenter.y), + link->GetColor()); + } + } + else + { +#if DEMO + DrawCircle(int(mCenter.x), int(mCenter.y),int(GetRadius())+3,color); +#endif + } + + } + + } + + if (mChildren) + { + SpherePack *pack = mChildren; + + while (pack) + { + pack->Render(color); + pack = pack->_GetNextSibling(); + } + } +#endif +} + +bool SpherePack::Recompute(float gravy) +{ + if (!mChildren) return true; // kill it! + if (HasSpherePackFlag(SPF_ROOTNODE)) return false; // don't recompute root nodes! + +#if 1 + // recompute bounding sphere! + Vector3d total(0,0,0); + int count=0; + SpherePack *pack = mChildren; + while (pack) + { + total+=pack->mCenter; + count++; + pack = pack->_GetNextSibling(); + } + + if (count) + { + float recip = 1.0f / float(count); + total*=recip; + + Vector3d oldpos = mCenter; + +#ifdef __STATIC_RANGE__ + assert(total.IsInStaticRange()); +#endif + mCenter = total; // new origin! + float maxradius = 0; + + pack = mChildren; + + while (pack) + { + float dist = DistanceSquared(pack); + float radius = sqrtf(dist) + pack->GetRadius(); + if (radius > maxradius) + { + maxradius = radius; + if ((maxradius+gravy) >= GetRadius()) + { +#ifdef __STATIC_RANGE__ + assert(oldpos.IsInStaticRange()); +#endif + mCenter = oldpos; + ClearSpherePackFlag(SPF_RECOMPUTE); + return false; + } + } + pack = pack->_GetNextSibling(); + } + + maxradius+=gravy; + + SetRadius(maxradius); + + // now all children have to recompute binding distance!! + pack = mChildren; + + while (pack) + { + pack->ComputeBindingDistance(this); + pack = pack->_GetNextSibling(); + } + + } + +#endif + + ClearSpherePackFlag(SPF_RECOMPUTE); + + return false; +} + + +void SpherePack::LostChild(SpherePack *t) +{ + assert(mChildCount); + assert(mChildren); + +#ifdef _DEBUG // debug validation code. + + SpherePack *pack = mChildren; + bool found = false; + while (pack) + { + if (pack == t) + { + assert(!found); + found = true; + } + pack = pack->_GetNextSibling(); + } + assert(found); + +#endif + + // first patch old linked list.. his previous now points to his next + SpherePack *prev = t->_GetPrevSibling(); + + if (prev) + { + SpherePack *next = t->_GetNextSibling(); + prev->SetNextSibling(next); // my previous now points to my next + if (next) next->SetPrevSibling(prev); + // list is patched! + } + else + { + SpherePack *next = t->_GetNextSibling(); + mChildren = next; + if (mChildren) mChildren->SetPrevSibling(0); + } + + mChildCount--; + + if (!mChildCount && HasSpherePackFlag(SPF_SUPERSPHERE)) + { + mFactory->Remove(this); + } +} + +void SpherePackFactory::Remove(SpherePack*pack) +{ + + if (pack->HasSpherePackFlag(SPF_ROOTNODE)) return; // CAN NEVER REMOVE THE ROOT NODE EVER!!! + + if (pack->HasSpherePackFlag(SPF_SUPERSPHERE) && pack->HasSpherePackFlag(SPF_LEAF_TREE)) + { +#ifdef SPHERELIB_STRICT + if (!pack->IS_SPHERE) + puts("SpherePackFactory::Remove"); +#endif + SpherePack *link = (SpherePack *) pack->GetUserData(); + + Remove(link); + } + + pack->Unlink(); + + mSpheres.Release(pack); +} + +#if DEMO +unsigned int SpherePackFactory::GetColor(void) +{ + unsigned int ret = mColors[mColorCount]; + mColorCount++; + if (mColorCount == MAXCOLORS) mColorCount = 0; + return ret; +} +#endif + +void SpherePackFactory::Integrate(SpherePack *pack, + SpherePack *supersphere, + float node_size) +{ + // ok..time to integrate this sphere with the tree + // first find which supersphere we are closest to the center of + + SpherePack *search = supersphere->GetChildren(); + + SpherePack *nearest1 = 0; // nearest supersphere we are completely + float neardist1 = 1e38f; // enclosed within + + SpherePack *nearest2 = 0; // supersphere we must grow the least to + float neardist2 = 1e38f; // add ourselves to. + + //int scount = 1; + + while (search) + { + if (search->HasSpherePackFlag(SPF_SUPERSPHERE) && !search->HasSpherePackFlag(SPF_ROOTNODE) && search->GetChildCount()) + { + + float dist = pack->DistanceSquared(search); + + if (nearest1) + { + if (dist < neardist1) + { + + float d = sqrtf(dist)+pack->GetRadius(); + + if (d <= search->GetRadius()) + { + neardist1 = dist; + nearest1 = search; + } + } + } + else + { + + float d = (sqrtf(dist) + pack->GetRadius())-search->GetRadius(); + + if (d < neardist2) + { + if (d < 0) + { + neardist1 = dist; + nearest1 = search; + } + else + { + neardist2 = d; + nearest2 = search; + } + } + } + } + search = search->_GetNextSibling(); + } + + // ok...now..on exit let's see what we got. + if (nearest1) + { + // if we are inside an existing supersphere, we are all good! + // we need to detach item from wherever it is, and then add it to + // this supersphere as a child. + pack->Unlink(); + nearest1->AddChild(pack); + pack->ComputeBindingDistance(nearest1); + nearest1->Recompute(mSuperSphereGravy); + + if (nearest1->HasSpherePackFlag(SPF_LEAF_TREE)) + { +#ifdef SPHERELIB_STRICT + if (!nearest1->IS_SPHERE) + puts("SpherePackFactory::Integrate1"); +#endif + SpherePack *link = (SpherePack *) nearest1->GetUserData(); + link->NewPosRadius(nearest1->GetPos(), nearest1->GetRadius()); + } + + } + else + { + bool newsphere = true; + + if (nearest2) + { + float newsize = neardist2 + nearest2->GetRadius() + mSuperSphereGravy; + + if (newsize <= node_size) + { + pack->Unlink(); + + nearest2->SetRadius(newsize); + nearest2->AddChild(pack); + nearest2->Recompute(mSuperSphereGravy); + pack->ComputeBindingDistance(nearest2); + + if (nearest2->HasSpherePackFlag(SPF_LEAF_TREE)) + { +#ifdef SPHERELIB_STRICT + if (!nearest2->IS_SPHERE) + puts("SpherePackFactory::Integrate2"); +#endif + SpherePack *link = (SpherePack *) nearest2->GetUserData(); + link->NewPosRadius(nearest2->GetPos(), nearest2->GetRadius()); + } + + newsphere = false; + + } + + } + + if (newsphere) + { + assert(supersphere->HasSpherePackFlag(SPF_ROOTNODE)); + // we are going to create a new superesphere around this guy! + pack->Unlink(); + + SpherePack *parent = mSpheres.GetFreeLink(); + assert(parent); + parent->Init(this, pack->GetPos(), pack->GetRadius()+mSuperSphereGravy, 0, false); + + if (supersphere->HasSpherePackFlag(SPF_ROOT_TREE)) + parent->SetSpherePackFlag(SPF_ROOT_TREE); + else + parent->SetSpherePackFlag(SPF_LEAF_TREE); + + parent->SetSpherePackFlag(SPF_SUPERSPHERE); +#if DEMO + parent->SetColor(GetColor()); +#endif + parent->AddChild(pack); + + supersphere->AddChild(parent); + + parent->Recompute(mSuperSphereGravy); + pack->ComputeBindingDistance(parent); + + if (parent->HasSpherePackFlag(SPF_LEAF_TREE)) + { + // need to create parent association! + SpherePack *link = AddSphere_(parent->GetPos(), parent->GetRadius(), parent, true, SPF_ROOT_TREE); + parent->SetUserData(link, true); // hook him up!! + } + + } + } + + pack->ClearSpherePackFlag(SPF_INTEGRATE); // we've been integrated! +} + + +void SpherePackFactory::FrustumTest(const Frustum &f,SpherePackCallback *callback) +{ + // test case here, just traverse children. + mCallback = callback; + mRoot->VisibilityTest(f,this,VS_PARTIAL); +} + + +void SpherePack::VisibilityTest(const Frustum &f,SpherePackCallback *callback,ViewState state) +{ + + if (state == VS_PARTIAL) + { + state = f.ViewVolumeTest(mCenter, GetRadius()); +#if DEMO + if (state != VS_OUTSIDE) + { + DrawCircle(int(mCenter.x), int(mCenter.y), int(GetRadius()), 0x404040); + } +#endif + } + + if (HasSpherePackFlag(SPF_SUPERSPHERE)) + { + + + if (state == VS_OUTSIDE) + { + if (HasSpherePackFlag(SPF_HIDDEN)) return; // no state change + ClearSpherePackFlag(SpherePackFlag(SPF_INSIDE | SPF_PARTIAL)); + SetSpherePackFlag(SPF_HIDDEN); + } + else + { + if (state == VS_INSIDE) + { + if (HasSpherePackFlag(SPF_INSIDE)) return; // no state change + ClearSpherePackFlag(SpherePackFlag(SPF_PARTIAL | SPF_HIDDEN)); + SetSpherePackFlag(SPF_INSIDE); + } + else + { + ClearSpherePackFlag(SpherePackFlag(SPF_HIDDEN | SPF_INSIDE)); + SetSpherePackFlag(SPF_PARTIAL); + } + } + + SpherePack *pack = mChildren; + + while (pack) + { + pack->VisibilityTest(f,callback,state); + pack = pack->_GetNextSibling(); + } + + } + else + { + switch (state) + { + case VS_INSIDE: + if (!HasSpherePackFlag(SPF_INSIDE)) + { + ClearSpherePackFlag(SpherePackFlag(SPF_HIDDEN | SPF_PARTIAL)); + SetSpherePackFlag(SPF_INSIDE); + callback->VisibilityCallback(f,this,state); + } + break; + case VS_OUTSIDE: + if (!HasSpherePackFlag(SPF_HIDDEN)) + { + ClearSpherePackFlag(SpherePackFlag(SPF_INSIDE | SPF_PARTIAL)); + SetSpherePackFlag(SPF_HIDDEN); + callback->VisibilityCallback(f,this,state); + } + break; + case VS_PARTIAL: + //if (!HasSpherePackFlag(SPF_PARTIAL)) + { + ClearSpherePackFlag(SpherePackFlag(SPF_INSIDE | SPF_HIDDEN)); + SetSpherePackFlag(SPF_PARTIAL); + callback->VisibilityCallback(f,this,state); + } + break; + } + + } +} + +void SpherePackFactory::RayTrace(const Vector3d &p1, + const Vector3d &p2, + SpherePackCallback *callback) +{ + // test case here, just traverse children. + Vector3d dir = p2; + float dist = dir.Normalize(); + mCallback = callback; + mRoot->RayTrace(p1,dir,dist,this); +} + +#include "../EterBase/Debug.h" + +void SpherePackFactory::RangeTest(const Vector3d ¢er,float radius,SpherePackCallback *callback) +{ +#ifdef __STATIC_RANGE__ + if (!center.IsInStaticRange()) + { + TraceError("SpherePackFactory::RangeTest - RANGE ERROR %f, %f, %f", + center.x, center.y, center.z); + assert("SpherePackFactory::RangeTest - RANGE ERROR"); + return; + } +#endif + mCallback = callback; + mRoot->RangeTest(center,radius,this,VS_PARTIAL); +} + +void SpherePackFactory::PointTest2d(const Vector3d ¢er, SpherePackCallback *callback) +{ +#ifdef __STATIC_RANGE__ + if (!center.IsInStaticRange()) + { + TraceError("SpherePackFactory::RangeTest2d - RANGE ERROR %f, %f, %f", + center.x, center.y, center.z); + assert("SpherePackFactory::RangeTest2d - RANGE ERROR"); + return; + } +#endif + mCallback = callback; + +#ifdef SPHERELIB_STRICT + mRoot->PointTest2d(center, this,VS_PARTIAL); + extern bool MAPOUTDOOR_GET_HEIGHT_TRACE; + if (MAPOUTDOOR_GET_HEIGHT_TRACE) + puts("================================================"); +#else + mRoot->PointTest2d(center, this,VS_PARTIAL); + +#endif + +} + +void SpherePack::RangeTest(const Vector3d &p, + float distance, + SpherePackCallback *callback, + ViewState state) +{ + + if (state == VS_PARTIAL) + { + float d = p.Distance(mCenter); + if ((d-distance) > GetRadius()) return;; + if ((GetRadius()+d) < distance) state = VS_INSIDE; + } + + if (HasSpherePackFlag(SPF_SUPERSPHERE)) + { +#if DEMO + if (state == VS_PARTIAL) + { + DrawCircle(int(mCenter.x), int(mCenter.y), int(GetRadius()), 0x404040); + } +#endif + SpherePack *pack = mChildren; + while (pack) + { + pack->RangeTest(p,distance,callback,state); + pack = pack->_GetNextSibling(); + } + + } + else + { + callback->RangeTestCallback(p,distance,this,state); + } +} + +void SpherePack::PointTest2d(const Vector3d &p, + SpherePackCallback *callback, + ViewState state) +{ + if (state == VS_PARTIAL) + { + float dx=p.x-mCenter.x; + float dy=p.y-mCenter.y; + float distSquare = (dx*dx)+(dy*dy); + + if (distSquare > GetRadius2()) return;; + if (GetRadius2() < -distSquare) state = VS_INSIDE; + } + + if (HasSpherePackFlag(SPF_SUPERSPHERE)) + { +#if DEMO + if (state == VS_PARTIAL) + { + DrawCircle(int(mCenter.x), int(mCenter.y), int(GetRadius()), 0x404040); + } +#endif + SpherePack *pack = mChildren; + while (pack) + { + pack->PointTest2d(p, callback, state); + pack = pack->_GetNextSibling(); + } + + } + else + { +#ifdef SPHERELIB_STRICT + extern bool MAPOUTDOOR_GET_HEIGHT_TRACE; + if (MAPOUTDOOR_GET_HEIGHT_TRACE) + { + float dx=p.x-mCenter.x; + float dy=p.y-mCenter.y; + float distSquare = (dx*dx)+(dy*dy); + printf("--- (%f, %f) dist %f radius %f isSphere %d\n", mCenter.x, mCenter.y, distSquare, GetRadius(), IS_SPHERE); + } +#endif + callback->PointTest2dCallback(p, this, state); + } +} + +void SpherePackFactory::RangeTestCallback(const Vector3d &p,float distance,SpherePack *sphere,ViewState state) +{ +#ifdef SPHERELIB_STRICT + if (!sphere->IS_SPHERE) + puts("SpherePackFactory::RangeTestCallback"); +#endif + SpherePack *link = (SpherePack *) sphere->GetUserData(); + if (link) link->RangeTest(p,distance,mCallback,state); +}; + +void SpherePackFactory::PointTest2dCallback(const Vector3d &p, SpherePack *sphere,ViewState state) +{ +#ifdef SPHERELIB_STRICT + if (!sphere->IS_SPHERE) + puts("SpherePackFactory::PointTest2dCallback"); +#endif + SpherePack *link = (SpherePack *) sphere->GetUserData(); + if (link) link->PointTest2d(p, mCallback,state); +}; + +void SpherePack::RayTrace(const Vector3d &p1, + const Vector3d &dir, + float distance, + SpherePackCallback *callback) +{ + bool hit = false; + + if (HasSpherePackFlag(SPF_SUPERSPHERE)) + { + + hit = RayIntersectionInFront(p1,dir,0); + + if (hit) + { +#if DEMO + DrawCircle(int(mCenter.x), int(mCenter.y), int(GetRadius()), 0x404040); +#endif + SpherePack *pack = mChildren; + + while (pack) + { + pack->RayTrace(p1,dir,distance,callback); + pack = pack->_GetNextSibling(); + } + } + + } + else + { + Vector3d sect; + hit = RayIntersection(p1,dir,distance,§); + if (hit) + { + callback->RayTraceCallback(p1,dir,distance,sect,this); + } + } +} + +void SpherePackFactory::RayTraceCallback(const Vector3d &p1, // source pos of ray + const Vector3d &dir, // direction of ray + float distance, // distance of ray + const Vector3d &/*sect*/, // intersection location + SpherePack *sphere) +{ +#ifdef SPHERELIB_STRICT + if (!sphere->IS_SPHERE) + puts("SpherePackFactory::RayTraceCallback"); +#endif + SpherePack *link = (SpherePack *) sphere->GetUserData(); + if (link) link->RayTrace(p1,dir,distance,mCallback); +}; + + + + +void SpherePackFactory::Reset(void) +{ + mRoot->Reset(); + mLeaf->Reset(); +} + + +void SpherePack::Reset(void) +{ + ClearSpherePackFlag(SpherePackFlag(SPF_HIDDEN | SPF_PARTIAL | SPF_INSIDE)); + + SpherePack *pack = mChildren; + while (pack) + { + pack->Reset(); + pack = pack->_GetNextSibling(); + } +} + +void SpherePackFactory::VisibilityCallback(const Frustum &f,SpherePack *sphere,ViewState state) +{ +#ifdef SPHERELIB_STRICT + if (!sphere->IS_SPHERE) + puts("SpherePackFactory::VisibilityCallback"); +#endif + SpherePack *link = (SpherePack *) sphere->GetUserData(); + if (link) link->VisibilityTest(f,mCallback,state); +} diff --git a/source/SphereLib/spherepack.h b/source/SphereLib/spherepack.h new file mode 100644 index 0000000..a626c40 --- /dev/null +++ b/source/SphereLib/spherepack.h @@ -0,0 +1,492 @@ +/* Copyright (C) John W. Ratcliff, 2001. +* All rights reserved worldwide. +* +* This software is provided "as is" without express or implied +* warranties. You may freely copy and compile this source into +* applications you distribute provided that the copyright text +* below is included in the resulting source code, for example: +* "Portions Copyright (C) John W. Ratcliff, 2001" +*/ +#pragma once + +/***********************************************************************/ +/** SPHEREPACK.H: Contains all of the support code for Sphere Trees. */ +/** */ +/** Written by John W. Ratcliff jratcliff@att.net */ +/***********************************************************************/ + + +#include + +#include "vector.h" // need 3d vector support. +#include "pool.h" // need memory pool template class. +#include "sphere.h" // Need sphere base class. +#include "frustum.h" // Need to know what a frustum is. + +#define DEMO 0// true if running in windows test app + +enum SpherePackFlag +{ + + SPF_SUPERSPHERE =(1<<0), // this is a supersphere, allocated and deleted by us + SPF_ROOT_TREE =(1<<1), // member of the root tree + SPF_LEAF_TREE =(1<<2), // member of the leaf node tree + SPF_ROOTNODE =(1<<3), // this is the root node + SPF_RECOMPUTE =(1<<4), // needs recomputed bounding sphere + SPF_INTEGRATE =(1<<5), // needs to be reintegrated into tree + // Frame-to-frame view frustum status. Only does callbacks when a + // state change occurs. + SPF_HIDDEN =(1<<6), // outside of view frustum + SPF_PARTIAL =(1<<7), // partially inside view frustum + SPF_INSIDE =(1<<8) // completely inside view frustum +}; + +class SpherePackFactory; // forward reference the factory. +class SpherePack; // forward reference the sphere package + +#pragma warning(push) +#pragma warning(disable:4100) + +// Virtual base class, used to implement callbacks for RayTracing, +// range testing, and frustum culling. +class SpherePackCallback +{ +public: + SpherePackCallback() {} + virtual ~SpherePackCallback() {} + + virtual void VisibilityCallback(const Frustum &f, // frustum clipped against + SpherePack *sphere, // leaf node sphere in question + ViewState state) // new state it is in. + {}; + + virtual void RayTraceCallback(const Vector3d &p1, // source pos of ray + const Vector3d &dir, // direction of ray + float distance, // distance of ray + const Vector3d §, // intersection location + SpherePack *sphere) // sphere ray hit + {}; + + virtual void RangeTestCallback(const Vector3d &searchpos, // position we are performing range test against. + float distance, // squared distance we are range searching against. + SpherePack *sphere, + ViewState state) // sphere within range, VS_PARTIAL if sphere straddles range test + {}; + + virtual void PointTest2dCallback(const Vector3d &searchpos, // position we are performing range test against. + SpherePack *sphere, + ViewState state) // sphere within range, VS_PARTIAL if sphere straddles range test + {}; + +private: +}; + +#pragma warning(pop) + +class SpherePack : public Sphere +{ +public: + SpherePack(void) + { + mUserData = 0; // default user data is null + mFactory = 0; // factory we are a member of + mNext = 0; // linked list pointers + mPrevious = 0; + mParent = 0; + mNextSibling = 0; // our brothers and sisters at this level. + mPrevSibling = 0; + mChildren = 0; // our children. + mChildCount = 0; // number of children we have. + mFifo1 = 0; // our FIFO1 location if we have one. + mFifo2 = 0; // our FIFO2 location if we have one. + SetRadius(0); // default radius + mCenter.Set(0,0,0); // default center position. + IS_SPHERE = false; + }; + virtual ~SpherePack() + { + } + + void Init(SpherePackFactory *factory, // factory we belong to + const Vector3d &pos, // center of sphere + float radius, // radius of sphere + void *userdata, bool isSphere) // user data + { + IS_SPHERE = isSphere; + mUserData = userdata; + mParent = 0; + mNextSibling = 0; + mPrevSibling = 0; + mFlags = 0; + mFifo1 = 0; + mFifo2 = 0; + mFactory = factory; + mCenter = pos; + SetRadius(radius); + }; + + // Access to SpherePack bit flags. + void SetSpherePackFlag(SpherePackFlag flag) { mFlags|=flag; }; + void ClearSpherePackFlag(SpherePackFlag flag) { mFlags&=~flag; }; + bool HasSpherePackFlag(SpherePackFlag flag) const + { + if ( mFlags & flag ) return true; + return false; + }; + + + void SetParent(SpherePack *pack) { mParent = pack; }; + SpherePack * GetParent(void) const { return mParent; }; + + // Sphere has a new position. + inline void NewPos(const Vector3d &pos); + // Sphere has a new position and radius + inline void NewPosRadius(const Vector3d &pos,float radius); + + void Unlink(void) + { + if ( mFifo1 ) // if we belong to fifo1, null us out + { + *mFifo1 = 0; + mFifo1 = 0; + } + + if ( mFifo2 ) // if we belong to fifo2, null us out + { + *mFifo2 = 0; + mFifo2 = 0; + } + + if ( mParent ) mParent->LostChild(this); + + assert( !mChildren ); // can't unlink guys with children! + + mParent = 0; // got no father anymore + } + + + void AddChild(SpherePack *pack) + { + + SpherePack *my_child = mChildren; + mChildren = pack; // new head of list + + pack->SetNextSibling(my_child); // his next is my old next + pack->SetPrevSibling(0); // at head of list, no previous + pack->SetParent(this); + + if ( my_child ) my_child->SetPrevSibling(pack); // previous now this.. + + mChildCount++; + +#if defined(_DEBUG) + float dist = DistanceSquared(pack); + float radius = sqrtf(dist) + pack->GetRadius(); + + assert( radius <= GetRadius()+0.0001f ); +#endif + } + + void SetNextSibling(SpherePack *child) { mNextSibling = child; } + void SetPrevSibling(SpherePack *child) { mPrevSibling = child; } + + SpherePack * _GetNextSibling(void) const + { + return mNextSibling; + } + SpherePack * _GetPrevSibling(void) const + { + return mPrevSibling; + } + SpherePack * GetChildren(void) const { return mChildren; } + + SpherePack * GetNext(void) const { return mNext; }; + SpherePack * GetPrevious(void) const { return mPrevious; }; + + void SetNext(SpherePack *pack) { mNext = pack; }; + void SetPrevious(SpherePack *pack) { mPrevious = pack; }; + + void * GetUserData(void) const { return mUserData; }; + void SetUserData(void *data, bool isSphere) { mUserData = data; IS_SPHERE=isSphere;}; + + float DistanceSquared(const SpherePack *pack) const { return mCenter.DistanceSq( pack->mCenter ); }; + + void LostChild(SpherePack *pack); + + const Vector3d& GetPos(void) const { return mCenter; }; + + inline void Render(unsigned int color); + + inline bool Recompute(float gravy); + + int GetChildCount(void) const { return mChildCount; }; + +#if DEMO + void SetColor(unsigned int color) { mColor = color; }; + unsigned int GetColor(void) const { return mColor; }; +#endif + + void SetFifo1(SpherePack **fifo) + { + mFifo1 = fifo; + }; + + void SetFifo2(SpherePack **fifo) + { + mFifo2 = fifo; + }; + + void ComputeBindingDistance(SpherePack *parent) + { + mBindingDistance = parent->GetRadius() - GetRadius(); + if ( mBindingDistance <= 0 ) + mBindingDistance = 0; + else + mBindingDistance*=mBindingDistance; + } + + void VisibilityTest(const Frustum &f, + SpherePackCallback *callback, + ViewState state); + + void RayTrace(const Vector3d &p1, // origin of Ray + const Vector3d &dir, // direction of Ray + float distance, // length of ray. + SpherePackCallback *callback); + + + void RangeTest(const Vector3d &p, + float distance, + SpherePackCallback *callback, + ViewState state); + + void PointTest2d(const Vector3d &p, + SpherePackCallback *callback, + ViewState state); + + void Reset(void); + +private: + SpherePack *mNext; + SpherePack *mPrevious; // used by pool memory management linked list code + + SpherePack *mParent; + SpherePack *mChildren; // *my* children + + SpherePack *mNextSibling; // doubly linked list of my brothers + SpherePack *mPrevSibling; // and sisters + + SpherePack **mFifo1; // address of location inside of fifo1 + SpherePack **mFifo2; // address of location inside of fifo2 + + long mFlags; // my bit flags. + long mChildCount; // number of children + + float mBindingDistance; + + void *mUserData; + + SpherePackFactory *mFactory; // the factory we are a member of. +#if DEMO + unsigned long mColor; +#endif + +public: + bool IS_SPHERE; +}; + +class SpherePackFifo +{ +public: + SpherePackFifo(int fifosize) + { + mCount = 0; + mSP = 0; + mBottom = 0; + mFifoSize = fifosize; + mFifo = new SpherePack *[mFifoSize]; + }; + + virtual ~SpherePackFifo(void) + { + delete [] mFifo; + }; + + SpherePack ** Push(SpherePack *sphere) + { + mCount++; + SpherePack **ret = &mFifo[mSP]; + mFifo[mSP] = sphere; + mSP++; + if ( mSP == mFifoSize ) mSP = 0; + return ret; + }; + + SpherePack * Pop(void) + { + while ( mSP != mBottom ) + { + mCount--; + SpherePack *ret = mFifo[mBottom]; + mBottom++; + if ( mBottom == mFifoSize ) mBottom = 0; + if ( ret ) return ret; + } + return 0; + } + + bool Flush(SpherePack *pack) + { + if ( mSP == mBottom ) return false; + int i = mBottom; + while ( i != mSP ) + { + if ( mFifo[i] == pack ) + { + mFifo[i] = 0; + return true; + } + i++; + if ( i == mFifoSize ) i = 0; + } + return false; + }; + + int GetCount(void) const { return mCount; }; + +private: + int mCount; + int mSP; // stack pointer + int mBottom; + int mFifoSize; + SpherePack **mFifo; +}; + + +class SpherePackFactory : public SpherePackCallback +{ +public: + + SpherePackFactory(int maxspheres, + float rootsize, + float leafsize, + float gravy); + + + virtual ~SpherePackFactory(void); + + void Process(void); + + SpherePack *AddSphere_(const Vector3d &pos, + float radius, + void *userdata, + bool isSphere, + int flags=SPF_LEAF_TREE); + + void AddIntegrate(SpherePack *pack); // add to the integration FIFO + void AddRecompute(SpherePack *recompute); // add to the recomputation (balancing) FIFO. + + void Integrate(SpherePack *pack,SpherePack *supersphere,float node_size); + + void Render(void); + + void Remove(SpherePack *pack); + // see if any other spheres are contained within this one, if so + // collapse them and inherit their children. +#if DEMO + unsigned int GetColor(void); +#endif + + void FrustumTest(const Frustum &f,SpherePackCallback *callback); + + void RayTrace(const Vector3d &p1, // source + const Vector3d &p2, // dest + SpherePackCallback *callback); + + void RangeTest(const Vector3d ¢er,float radius,SpherePackCallback *callback); + void PointTest2d(const Vector3d ¢er, SpherePackCallback *callback); + + virtual void RayTraceCallback(const Vector3d &p1, // source pos of ray + const Vector3d &dir, // direction of ray + float distance, // distance of ray + const Vector3d §, // intersection location + SpherePack *sphere); + + virtual void RangeTestCallback(const Vector3d &p,float distance,SpherePack *sphere,ViewState state); + virtual void PointTest2dCallback(const Vector3d &p, SpherePack *sphere,ViewState state); + + virtual void VisibilityCallback(const Frustum &f,SpherePack *sphere,ViewState state); + + + void Reset(void); + +private: + + + SpherePack *mRoot; // 1024x1024 root node of all active spheres. + SpherePack *mLeaf; // 1024x1024 root node of all active spheres. + SpherePackCallback *mCallback; + + Pool< SpherePack > mSpheres; // all spheres possibly represented. + + SpherePackFifo *mIntegrate; // integration fifo + SpherePackFifo *mRecompute; // recomputation fifo + +#if DEMO +#define MAXCOLORS 12 + int mColorCount; + unsigned int mColors[MAXCOLORS]; +#endif + + float mMaxRootSize; // maximum size of a root node supersphere + float mMaxLeafSize; // maximum size of the leaf node supersphere + float mSuperSphereGravy; // binding distance gravy. +}; + +//*** Source code placed in header file so that it will be inlined! +void SpherePack::NewPos(const Vector3d &pos) +{ + mCenter = pos; // set our new center position. + + // is we have a parent (meaning we are a valid leaf node) and we have not already been flagged for re-integration, then..... + if (mParent && !HasSpherePackFlag(SPF_INTEGRATE)) + { + float dist = DistanceSquared(mParent); // compute squared distance to our parent. + + if (dist >= mBindingDistance) // if that exceeds our binding distance... + { + // If our parent, is not already marked to be recomputed (rebalance the sphere), then add him to the recomputation fifo. + mFactory->AddRecompute(mParent); + + // Unlink ourselves from the parent sphere and place ourselves into the root node. + Unlink(); + mFactory->AddIntegrate(this); // add ourselves to the re-integration fifo. + } + } + +} + +void SpherePack::NewPosRadius(const Vector3d &pos,float radius) +{ + // New position and, possibly, a new radius. + mCenter = pos; + + if (mParent && !HasSpherePackFlag(SPF_INTEGRATE)) + { + if (radius != GetRadius()) + { + SetRadius(radius); + ComputeBindingDistance(mParent); + } + + mFactory->AddRecompute(mParent); + + float dist = DistanceSquared(mParent); + + if (dist >= mBindingDistance) + { + Unlink(); + mFactory->AddIntegrate(this); + } + } +} diff --git a/source/SphereLib/vector.h b/source/SphereLib/vector.h new file mode 100644 index 0000000..279d175 --- /dev/null +++ b/source/SphereLib/vector.h @@ -0,0 +1,225 @@ +/* Copyright (C) John W. Ratcliff, 2001. +* All rights reserved worldwide. +* +* This software is provided "as is" without express or implied +* warranties. You may freely copy and compile this source into +* applications you distribute provided that the copyright text +* below is included in the resulting source code, for example: +* "Portions Copyright (C) John W. Ratcliff, 2001" +*/ +#pragma once + +#include +#include +//#include "stl.h" + + +/***********************************************************************/ +/** VECTOR.H : Template class to represent a 2d and 3d vector type. */ +/** */ +/** Written by John W. Ratcliff jratcliff@att.net */ +/***********************************************************************/ + +class Vector3d : public D3DXVECTOR3 +{ +public: + Vector3d(void) { }; // null constructor, does not inialize point. + + Vector3d(const Vector3d &a) // constructor copies existing vector. + { + x = a.x; + y = a.y; + z = a.z; + }; + + Vector3d(float a,float b,float c) // construct with initial point. + { + x = a; + y = b; + z = c; + }; + + bool operator==(const Vector3d &a) const + { + if ( a.x == x && a.y == y && a.z == z ) return true; + return false; + }; + + bool operator!=(const Vector3d &a) const + { + if ( a.x != x || a.y != y || a.z != z ) return true; + return false; + }; + + + // Operators + Vector3d& operator = (const Vector3d& A) // ASSIGNMENT (=) + { x=A.x; y=A.y; z=A.z; + return(*this); }; + + Vector3d operator + (const Vector3d& A) const // ADDITION (+) + { Vector3d Sum(x+A.x, y+A.y, z+A.z); + return(Sum); }; + + Vector3d operator - (const Vector3d& A) const // SUBTRACTION (-) + { Vector3d Diff(x-A.x, y-A.y, z-A.z); + return(Diff); }; + + Vector3d operator * (const float s) const // MULTIPLY BY SCALAR (*) + { Vector3d Scaled(x*s, y*s, z*s); + return(Scaled); }; + + Vector3d operator / (const float s) const // DIVIDE BY SCALAR (/) + { + float r = 1.0f / s; + Vector3d Scaled(x*r, y*r, z*r); + return(Scaled); + }; + + void operator += (const Vector3d A) // ACCUMULATED VECTOR ADDITION (+=) + { x+=A.x; y+=A.y; z+=A.z; }; + void operator -= (const Vector3d A) // ACCUMULATED VECTOR SUBTRACTION (+=) + { x-=A.x; y-=A.y; z-=A.z; }; + void operator *= (const float s) // ACCUMULATED SCALAR MULTIPLICATION (*=) (bpc 4/24/2000) + {x*=s; y*=s; z*=s;} + + Vector3d operator - (void) const // NEGATION (-) + { Vector3d Negated(-x, -y, -z); + return(Negated); }; + + float operator [] (const int i) const // ALLOWS VECTOR ACCESS AS AN ARRAY. + { return( (i==0)?x:((i==1)?y:z) ); }; + float & operator [] (const int i) + { return( (i==0)?x:((i==1)?y:z) ); }; + // + + // accessor methods. + float GetX(void) const { return x; }; + float GetY(void) const { return y; }; + float GetZ(void) const { return z; }; + + void SetX(float t) { x = t; }; + void SetY(float t) { y = t; }; + void SetZ(float t) { z = t; }; + + void Set(float a,float b,float c) + { + x = a; + y = b; + z = c; + }; + + void Zero(void) + { + x = y = z = 0; + }; + + // return -(*this). + Vector3d negative(void) const + { + Vector3d result; + result.x = -x; + result.y = -y; + result.z = -z; + return result; + } + + float Magnitude(void) const + { + return (sqrtf(x * x + y * y + z * z)); + }; + + void Lerp(const Vector3d& from,const Vector3d& to,float slerp) + { + *this = to-from; // delta on all 3 axis + *this*=slerp; // times interpolant distance. + *this+=from; // plus source + }; + + float Length(void) const // length of vector. + { + return float(sqrtf( x*x + y*y + z*z )); + }; + + float Length2(void) const // squared distance, prior to square root. + { + float l2 = x*x+y*y+z*z; + return l2; + }; + + inline float Distance(const Vector3d &a) const // distance between two points. + { + return sqrtf(DistanceSq(a)); + } + + inline float Distance2d(const Vector3d &a) const // distance between two points. + { + return sqrtf(DistanceSq2d(a)); + } + + float DistanceXY(const Vector3d &a) const + { + float dx = a.x - x; + float dy = a.y - y; + float dist = dx*dx + dy*dy; + return dist; + } + + float DistanceSq(const Vector3d &a) const // squared distance. + { + float dx = a.x - x; + float dy = a.y - y; + float dz = a.z - z; + return dx*dx + dy*dy + dz*dz; + }; + + float DistanceSq2d(const Vector3d &a) const // squared distance. + { + float dx = a.x - x; + float dy = a.y - y; + return dx*dx + dy*dy; + }; + + float Normalize(void) // normalize to a unit vector, returns distance. + { + float l = Length(); // get length. + if ( l != 0 ) + { + x/=l; + y/=l; + z/=l; + } + else + { + x = y = z = 0; + } + return l; + }; + + float Dot(const Vector3d &a) const // computes dot product. + { + return (x * a.x + y * a.y + z * a.z ); + }; + bool IsInStaticRange() const; + void Cross(const Vector3d &a,const Vector3d &b) // cross two vectors result in this one. + { + x = a.y*b.z - a.z*b.y; + y = a.z*b.x - a.x*b.z; + z = a.x*b.y - a.y*b.x; + }; + + //private: + + // float x; + // float y; + // float z; +}; + + +typedef std::vector< Vector3d > Vector3dVector; + +inline Vector3d operator * (float s, const Vector3d &v ) +{ Vector3d Scaled(v.x*s, v.y*s, v.z*s); +return(Scaled); }; + + diff --git a/source/UserInterface/AbstractApplication.h b/source/UserInterface/AbstractApplication.h new file mode 100644 index 0000000..004d59c --- /dev/null +++ b/source/UserInterface/AbstractApplication.h @@ -0,0 +1,56 @@ +#pragma once + +#include "AbstractSingleton.h" + +class IAbstractApplication : public TAbstractSingleton +{ + public: + struct SCameraPos + { + float m_fUpDir; + float m_fViewDir; + float m_fCrossDir; + + SCameraPos() : m_fUpDir(0.0f), m_fViewDir(0.0f), m_fCrossDir(0.0f) {} + }; + + struct SCameraSetting + { + D3DXVECTOR3 v3CenterPosition; + SCameraPos kCmrPos; + float fRotation; + float fPitch; + float fZoom; + + SCameraSetting() : v3CenterPosition(0.0f, 0.0f, 0.0f), + fRotation(0.0f), + fPitch(0.0f), + fZoom(0.0f) {} + }; + + public: + IAbstractApplication() {} + virtual ~IAbstractApplication() {} + + virtual void GetMousePosition(POINT* ppt) = 0; + virtual float GetGlobalTime() = 0; + virtual float GetGlobalElapsedTime() = 0; + + virtual void SkipRenderBuffering(DWORD dwSleepMSec) = 0; + virtual void SetServerTime(time_t tTime) = 0; + virtual void SetCenterPosition(float fx, float fy, float fz) = 0; + + virtual void SetEventCamera(const SCameraSetting & c_rCameraSetting) = 0; + virtual void BlendEventCamera(const SCameraSetting & c_rCameraSetting, float fBlendTime) = 0; + virtual void SetDefaultCamera() = 0; + + virtual void RunIMEUpdate() = 0; + virtual void RunIMETabEvent() = 0; + virtual void RunIMEReturnEvent() = 0; + + virtual void RunIMEChangeCodePage() = 0; + virtual void RunIMEOpenCandidateListEvent() = 0; + virtual void RunIMECloseCandidateListEvent() = 0; + virtual void RunIMEOpenReadingWndEvent() = 0; + virtual void RunIMECloseReadingWndEvent() = 0; +}; \ No newline at end of file diff --git a/source/UserInterface/AbstractCharacterManager.h b/source/UserInterface/AbstractCharacterManager.h new file mode 100644 index 0000000..68d4f77 --- /dev/null +++ b/source/UserInterface/AbstractCharacterManager.h @@ -0,0 +1,15 @@ +#pragma once + +#include "AbstractSingleton.h" + +class CInstanceBase; + +class IAbstractCharacterManager : public TAbstractSingleton +{ + public: + IAbstractCharacterManager() {} + virtual ~IAbstractCharacterManager() {} + + virtual void Destroy() = 0; + virtual CInstanceBase * GetInstancePtr(DWORD dwVID) = 0; +}; \ No newline at end of file diff --git a/source/UserInterface/AbstractChat.h b/source/UserInterface/AbstractChat.h new file mode 100644 index 0000000..809eedc --- /dev/null +++ b/source/UserInterface/AbstractChat.h @@ -0,0 +1,12 @@ +#pragma once + +#include "AbstractSingleton.h" + +class IAbstractChat : public TAbstractSingleton +{ + public: + IAbstractChat() {} + virtual ~IAbstractChat() {} + + virtual void AppendChat(int iType, const char * c_szChat) = 0; +}; \ No newline at end of file diff --git a/source/UserInterface/AbstractPlayer.h b/source/UserInterface/AbstractPlayer.h new file mode 100644 index 0000000..bbfa6e9 --- /dev/null +++ b/source/UserInterface/AbstractPlayer.h @@ -0,0 +1,65 @@ +#pragma once + +#include "AbstractSingleton.h" + +class CInstanceBase; + +class IAbstractPlayer : public TAbstractSingleton +{ + public: + IAbstractPlayer() {} + virtual ~IAbstractPlayer() {} + + virtual DWORD GetMainCharacterIndex() = 0; + virtual void SetMainCharacterIndex(int iIndex) = 0; + virtual bool IsMainCharacterIndex(DWORD dwIndex) = 0; + + virtual int GetStatus(DWORD dwType) = 0; + + virtual const char * GetName() = 0; + + virtual void SetRace(DWORD dwRace) = 0; + + virtual void StartStaminaConsume(DWORD dwConsumePerSec, DWORD dwCurrentStamina) = 0; + virtual void StopStaminaConsume(DWORD dwCurrentStamina) = 0; + + virtual bool IsPartyMemberByVID(DWORD dwVID) = 0; + virtual bool PartyMemberVIDToPID(DWORD dwVID, DWORD * pdwPID) = 0; + virtual bool IsSamePartyMember(DWORD dwVID1, DWORD dwVID2) = 0; + + virtual void SetItemData(TItemPos itemPos, const TItemData & c_rkItemInst) = 0; + virtual void SetItemCount(TItemPos itemPos, BYTE byCount) = 0; + virtual void SetItemMetinSocket(TItemPos itemPos, DWORD dwMetinSocketIndex, DWORD dwMetinNumber) = 0; + virtual void SetItemAttribute(TItemPos itemPos, DWORD dwAttrIndex, BYTE byType, short sValue) = 0; +#if defined(GAIDEN) + virtual void SetItemUnbindTime(DWORD dwItemSlotIndex, DWORD dwUnbindSecondsLeft) = 0; +#endif + + virtual DWORD GetItemIndex(TItemPos itemPos) = 0; + virtual DWORD GetItemFlags(TItemPos itemPos) = 0; + virtual DWORD GetItemCount(TItemPos itemPos) = 0; + + virtual bool IsEquipItemInSlot(TItemPos itemPos) = 0; + + virtual void AddQuickSlot(int QuickslotIndex, char IconType, char IconPosition) = 0; + virtual void DeleteQuickSlot(int QuickslotIndex) = 0; + virtual void MoveQuickSlot(int Source, int Target) = 0; + + virtual void SetWeaponPower(DWORD dwMinPower, DWORD dwMaxPower, DWORD dwMinMagicPower, DWORD dwMaxMagicPower, DWORD dwAddPower) = 0; + + virtual void SetTarget(DWORD dwVID, BOOL bForceChange = TRUE) = 0; + virtual void NotifyCharacterUpdate(DWORD dwVID) = 0; + virtual void NotifyCharacterDead(DWORD dwVID) = 0; + virtual void NotifyDeletingCharacterInstance(DWORD dwVID) = 0; + virtual void NotifyChangePKMode() = 0; + + virtual void SetObserverMode(bool isEnable) = 0; + virtual void SetMobileFlag(BOOL bFlag) = 0; + virtual void SetComboSkillFlag(BOOL bFlag) = 0; + + virtual void StartEmotionProcess() = 0; + virtual void EndEmotionProcess() = 0; + + virtual CInstanceBase* NEW_GetMainActorPtr() = 0; +}; + diff --git a/source/UserInterface/AbstractSingleton.h b/source/UserInterface/AbstractSingleton.h new file mode 100644 index 0000000..7e29e56 --- /dev/null +++ b/source/UserInterface/AbstractSingleton.h @@ -0,0 +1,29 @@ +#pragma once + +template +class TAbstractSingleton +{ + static T * ms_singleton; + +public: + TAbstractSingleton() + { + assert(!ms_singleton); + int offset = (int) (T*) 1 - (int) (CSingleton *) (T*) 1; + ms_singleton = (T*) ((int) this + offset); + } + + virtual ~TAbstractSingleton() + { + assert(ms_singleton); + ms_singleton = 0; + } + + __forceinline static T & GetSingleton() + { + assert(ms_singleton!=NULL); + return (*ms_singleton); + } +}; + +template T * TAbstractSingleton ::ms_singleton = 0; \ No newline at end of file diff --git a/source/UserInterface/AccountConnector.cpp b/source/UserInterface/AccountConnector.cpp new file mode 100644 index 0000000..00ecfbe --- /dev/null +++ b/source/UserInterface/AccountConnector.cpp @@ -0,0 +1,745 @@ +#include "StdAfx.h" +#include "AccountConnector.h" +#include "Packet.h" +#include "PythonNetworkStream.h" +#include "../EterBase/tea.h" +#include "../EterPack/EterPackManager.h" + +#include "Hackshield.h" +#include "WiseLogicXTrap.h" + +// CHINA_CRYPT_KEY +extern DWORD g_adwEncryptKey[4]; +extern DWORD g_adwDecryptKey[4]; +// END_OF_CHINA_CRYPT_KEY + +#ifdef USE_OPENID +extern int openid_test; +#endif + +void CAccountConnector::SetHandler(PyObject* poHandler) +{ + m_poHandler = poHandler; +} + +void CAccountConnector::SetLoginInfo(const char * c_szName, const char * c_szPwd) +{ + m_strID = c_szName; + m_strPassword = c_szPwd; +} + + +void CAccountConnector::ClearLoginInfo( void ) +{ + m_strPassword = ""; +} + +bool CAccountConnector::Connect(const char * c_szAddr, int iPort, const char * c_szAccountAddr, int iAccountPort) +{ +#ifndef _IMPROVED_PACKET_ENCRYPTION_ + __BuildClientKey(); +#endif + + m_strAddr = c_szAddr; + m_iPort = iPort; + + __OfflineState_Set(); + + // CHINA_CRYPT_KEY + if (LocaleService_IsYMIR()) + { + } + else + { + __BuildClientKey_20050304Myevan(); + } + // END_OF_CHINA_CRYPT_KEY + + return CNetworkStream::Connect(c_szAccountAddr, iAccountPort); +} + +void CAccountConnector::Disconnect() +{ + CNetworkStream::Disconnect(); + __OfflineState_Set(); +} + +bool CAccountConnector::SendNEWCIBNPasspodAnswerPacket(const char * answer) +{ + TPacketCGNEWCIBNPasspodAnswer answerPacket; + answerPacket.bHeader = HEADER_CG_NEWCIBN_PASSPOD_ANSWER; + strncpy(answerPacket.szAnswer, answer, NEWCIBN_PASSPOD_ANSWER_MAX_LEN); + answerPacket.szAnswer[NEWCIBN_PASSPOD_ANSWER_MAX_LEN] = '\0'; + if (!Send(sizeof(answerPacket), &answerPacket)) + { + TraceError("SendNEWCIBNPasspodAnswerPacket"); + return false; + } + return SendSequence(); +} + +bool CAccountConnector::SendRunupMatrixCardPacket(const char * c_szMatrixCardString) +{ + TPacketCGRunupMatrixAnswer answerPacket; + answerPacket.bHeader = HEADER_CG_RUNUP_MATRIX_ANSWER; + strncpy(answerPacket.szAnswer, c_szMatrixCardString, RUNUP_MATRIX_ANSWER_MAX_LEN); + answerPacket.szAnswer[RUNUP_MATRIX_ANSWER_MAX_LEN] = '\0'; + if (!Send(sizeof(answerPacket), &answerPacket)) + { + TraceError("SendRunupMatrixCardPacketError"); + return false; + } + return SendSequence(); +} + +bool CAccountConnector::SendChinaMatrixCardPacket(const char * c_szMatrixCardString) +{ + TPacketCGChinaMatrixCard MatrixCardPacket; + MatrixCardPacket.bHeader = HEADER_CG_CHINA_MATRIX_CARD; + strncpy(MatrixCardPacket.szAnswer, c_szMatrixCardString, CHINA_MATRIX_ANSWER_MAX_LEN); + MatrixCardPacket.szAnswer[CHINA_MATRIX_ANSWER_MAX_LEN] = '\0'; + + if (!Send(sizeof(MatrixCardPacket), &MatrixCardPacket)) + { + Tracen("SendLogin Error"); + return false; + } + + CPythonNetworkStream::Instance().SetWaitFlag(); + m_isWaitKey = TRUE; + + return SendSequence(); +} + +void CAccountConnector::Process() +{ + CNetworkStream::Process(); + + if (!__StateProcess()) + { + __OfflineState_Set(); + Disconnect(); + } +} + +bool CAccountConnector::__StateProcess() +{ + switch (m_eState) + { + case STATE_HANDSHAKE: + return __HandshakeState_Process(); + break; + case STATE_AUTH: + return __AuthState_Process(); + break; + } + + return true; +} + +bool CAccountConnector::__HandshakeState_Process() +{ + if (!__AnalyzePacket(HEADER_GC_PHASE, sizeof(TPacketGCPhase), &CAccountConnector::__AuthState_RecvPhase)) + return false; + + if (!__AnalyzePacket(HEADER_GC_HANDSHAKE, sizeof(TPacketGCHandshake), &CAccountConnector::__AuthState_RecvHandshake)) + return false; + + if (!__AnalyzePacket(HEADER_GC_PING, sizeof(TPacketGCPing), &CAccountConnector::__AuthState_RecvPing)) + return false; + + // TODO : ϰ data serialize & deserialize ۾ؾ Ѵ. + if (!__AnalyzeVarSizePacket(HEADER_GC_HYBRIDCRYPT_KEYS, &CAccountConnector::__AuthState_RecvHybridCryptKeys)) + return false; + + if (!__AnalyzeVarSizePacket(HEADER_GC_HYBRIDCRYPT_SDB, &CAccountConnector::__AuthState_RecvHybridCryptSDB)) + return false; + +#ifdef _IMPROVED_PACKET_ENCRYPTION_ + if (!__AnalyzePacket(HEADER_GC_KEY_AGREEMENT, sizeof(TPacketKeyAgreement), &CAccountConnector::__AuthState_RecvKeyAgreement)) + return false; + + if (!__AnalyzePacket(HEADER_GC_KEY_AGREEMENT_COMPLETED, sizeof(TPacketKeyAgreementCompleted), &CAccountConnector::__AuthState_RecvKeyAgreementCompleted)) + return false; +#endif + + return true; +} + +bool CAccountConnector::__AuthState_Process() +{ + if (!__AnalyzePacket(0, sizeof(BYTE), &CAccountConnector::__AuthState_RecvEmpty)) + return true; + + if (!__AnalyzePacket(HEADER_GC_PHASE, sizeof(TPacketGCPhase), &CAccountConnector::__AuthState_RecvPhase)) + return false; + + if (!__AnalyzePacket(HEADER_GC_PING, sizeof(TPacketGCPing), &CAccountConnector::__AuthState_RecvPing)) + return false; + + if (!__AnalyzePacket(HEADER_GC_AUTH_SUCCESS, sizeof(TPacketGCAuthSuccess), &CAccountConnector::__AuthState_RecvAuthSuccess)) + return true; + +#ifdef USE_OPENID + if (!__AnalyzePacket(HEADER_GC_AUTH_SUCCESS_OPENID, sizeof(TPacketGCAuthSuccess), &CAccountConnector::__AuthState_RecvAuthSuccess_OpenID)) + return true; +#endif /* USE_OPENID */ + + if (!__AnalyzePacket(HEADER_GC_LOGIN_FAILURE, sizeof(TPacketGCAuthSuccess), &CAccountConnector::__AuthState_RecvAuthFailure)) + return true; + + if (!__AnalyzePacket(HEADER_GC_CHINA_MATRIX_CARD, sizeof(TPacketGCChinaMatrixCard), &CAccountConnector::__AuthState_RecvChinaMatrixCard)) + return true; + + if (!__AnalyzePacket(HEADER_GC_RUNUP_MATRIX_QUIZ, sizeof(TPacketGCRunupMatrixQuiz), &CAccountConnector::__AuthState_RecvRunupMatrixQuiz)) + return true; + + if (!__AnalyzePacket(HEADER_GC_NEWCIBN_PASSPOD_REQUEST, sizeof(TPacketGCNEWCIBNPasspodRequest), &CAccountConnector::__AuthState_RecvNEWCIBNPasspodRequest)) + return true; + + if (!__AnalyzePacket(HEADER_GC_HANDSHAKE, sizeof(TPacketGCHandshake), &CAccountConnector::__AuthState_RecvHandshake)) + return false; + + if (!__AnalyzePacket(HEADER_GC_PANAMA_PACK, sizeof(TPacketGCPanamaPack), &CAccountConnector::__AuthState_RecvPanamaPack)) + return false; + +#ifdef _IMPROVED_PACKET_ENCRYPTION_ + if (!__AnalyzePacket(HEADER_GC_KEY_AGREEMENT, sizeof(TPacketKeyAgreement), &CAccountConnector::__AuthState_RecvKeyAgreement)) + return false; + + if (!__AnalyzePacket(HEADER_GC_KEY_AGREEMENT_COMPLETED, sizeof(TPacketKeyAgreementCompleted), &CAccountConnector::__AuthState_RecvKeyAgreementCompleted)) + return false; +#endif + + // TODO : ϰ data serialize & deserialize ۾ؾ Ѵ. + if (!__AnalyzeVarSizePacket(HEADER_GC_HYBRIDCRYPT_KEYS, &CAccountConnector::__AuthState_RecvHybridCryptKeys)) + return false; + + if (!__AnalyzeVarSizePacket(HEADER_GC_HYBRIDCRYPT_SDB, &CAccountConnector::__AuthState_RecvHybridCryptSDB)) + return false; + + return true; +} + +bool CAccountConnector::__AuthState_RecvEmpty() +{ + BYTE byEmpty; + Recv(sizeof(BYTE), &byEmpty); + return true; +} + +bool CAccountConnector::__AuthState_RecvPhase() +{ + TPacketGCPhase kPacketPhase; + if (!Recv(sizeof(kPacketPhase), &kPacketPhase)) + return false; + + if (kPacketPhase.phase == PHASE_HANDSHAKE) + { + __HandshakeState_Set(); + } + else if (kPacketPhase.phase == PHASE_AUTH) + { +#ifndef _IMPROVED_PACKET_ENCRYPTION_ + const char* key = LocaleService_GetSecurityKey(); + SetSecurityMode(true, key); +#endif + +#ifdef USE_OPENID + if (!openid_test) + { + //2012.07.19 OpenID : + //Ongoing : ̵ -> TPacketCGLogin5 + //Ŭ ִ Ű . + + //const char* tempAuthKey = "d4025bc1f752b64fe5d51ae575ec4730"; //ϵڵ 32 + TPacketCGLogin5 LoginPacket; + LoginPacket.header = HEADER_CG_LOGIN5_OPENID; + + strncpy(LoginPacket.authKey, LocaleService_GetOpenIDAuthKey(), OPENID_AUTHKEY_LEN); + LoginPacket.authKey[OPENID_AUTHKEY_LEN] = '\0'; + + for (DWORD i = 0; i < 4; ++i) + LoginPacket.adwClientKey[i] = g_adwEncryptKey[i]; + + if (!Send(sizeof(LoginPacket), &LoginPacket)) + { + Tracen(" CAccountConnector::__AuthState_RecvPhase - SendLogin5 Error"); + return false; + } + + if (!SendSequence()) + { + return false; + } + } + else + { + TPacketCGLogin3 LoginPacket; + LoginPacket.header = HEADER_CG_LOGIN3; + + strncpy(LoginPacket.name, m_strID.c_str(), ID_MAX_NUM); + strncpy(LoginPacket.pwd, m_strPassword.c_str(), PASS_MAX_NUM); + LoginPacket.name[ID_MAX_NUM] = '\0'; + LoginPacket.pwd[PASS_MAX_NUM] = '\0'; + + // йȣ ޸𸮿 ִ ־, + ClearLoginInfo(); + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.ClearLoginInfo(); + + m_strPassword = ""; + + for (DWORD i = 0; i < 4; ++i) + LoginPacket.adwClientKey[i] = g_adwEncryptKey[i]; + + if (!Send(sizeof(LoginPacket), &LoginPacket)) + { + Tracen(" CAccountConnector::__AuthState_RecvPhase - SendLogin3 Error"); + return false; + } + + if (!SendSequence()) + { + return false; + } + } +#else /* USE_OPENID */ + +#ifdef USE_AHNLAB_HACKSHIELD + HackShield_SetUserInfo(m_strID.c_str()); +#endif +#ifdef XTRAP_CLIENT_ENABLE + XTrap_SetUserInfo(m_strID.c_str(), NULL, NULL, NULL, NULL); +#endif + + + TPacketCGLogin3 LoginPacket; + LoginPacket.header = HEADER_CG_LOGIN3; + + strncpy(LoginPacket.name, m_strID.c_str(), ID_MAX_NUM); + strncpy(LoginPacket.pwd, m_strPassword.c_str(), PASS_MAX_NUM); + LoginPacket.name[ID_MAX_NUM] = '\0'; + LoginPacket.pwd[PASS_MAX_NUM] = '\0'; + + // йȣ ޸𸮿 ִ ־, + ClearLoginInfo(); + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.ClearLoginInfo(); + + m_strPassword = ""; + + for (DWORD i = 0; i < 4; ++i) + LoginPacket.adwClientKey[i] = g_adwEncryptKey[i]; + + if (!Send(sizeof(LoginPacket), &LoginPacket)) + { + Tracen(" CAccountConnector::__AuthState_RecvPhase - SendLogin3 Error"); + return false; + } + + if (!SendSequence()) + { + return false; + } +#endif /* USE_OPENID */ + + __AuthState_Set(); + } + + return true; +} + +bool CAccountConnector::__AuthState_RecvHandshake() +{ + TPacketGCHandshake kPacketHandshake; + if (!Recv(sizeof(kPacketHandshake), &kPacketHandshake)) + return false; + + // HandShake + { + Tracenf("HANDSHAKE RECV %u %d", kPacketHandshake.dwTime, kPacketHandshake.lDelta); + + ELTimer_SetServerMSec(kPacketHandshake.dwTime+ kPacketHandshake.lDelta); + + //DWORD dwBaseServerTime = kPacketHandshake.dwTime+ kPacketHandshake.lDelta; + //DWORD dwBaseClientTime = ELTimer_GetMSec(); + + kPacketHandshake.dwTime = kPacketHandshake.dwTime + kPacketHandshake.lDelta + kPacketHandshake.lDelta; + kPacketHandshake.lDelta = 0; + + Tracenf("HANDSHAKE SEND %u", kPacketHandshake.dwTime); + + if (!Send(sizeof(kPacketHandshake), &kPacketHandshake)) + { + Tracen(" CAccountConnector::__AuthState_RecvHandshake - SendHandshake Error"); + return false; + } + } + + return true; +} + +bool CAccountConnector::__AuthState_RecvPanamaPack() +{ + TPacketGCPanamaPack kPacket; + + if (!Recv(sizeof(TPacketGCPanamaPack), &kPacket)) + return false; + + CEterPackManager::instance().RegisterPack(kPacket.szPackName, "*", kPacket.abIV); + return true; +} + +bool CAccountConnector::__AuthState_RecvHybridCryptKeys(int iTotalSize) +{ + int iFixedHeaderSize = TPacketGCHybridCryptKeys::GetFixedHeaderSize(); + + TPacketGCHybridCryptKeys kPacket(iTotalSize-iFixedHeaderSize); + + if (!Recv(iFixedHeaderSize, &kPacket)) + return false; + + if (!Recv(kPacket.iKeyStreamLen, kPacket.m_pStream)) + return false; + + CEterPackManager::Instance().RetrieveHybridCryptPackKeys( kPacket.m_pStream ); + return true; +} + +bool CAccountConnector::__AuthState_RecvHybridCryptSDB(int iTotalSize) +{ + int iFixedHeaderSize = TPacketGCHybridSDB::GetFixedHeaderSize(); + + TPacketGCHybridSDB kPacket(iTotalSize-iFixedHeaderSize); + + if (!Recv(iFixedHeaderSize, &kPacket)) + return false; + + if (!Recv(kPacket.iSDBStreamLen, kPacket.m_pStream)) + return false; + + CEterPackManager::Instance().RetrieveHybridCryptPackSDB( kPacket.m_pStream ); + return true; +} + + +bool CAccountConnector::__AuthState_RecvPing() +{ + TPacketGCPing kPacketPing; + if (!Recv(sizeof(kPacketPing), &kPacketPing)) + return false; + + __AuthState_SendPong(); + + return true; +} + +bool CAccountConnector::__AuthState_SendPong() +{ + TPacketCGPong kPacketPong; + kPacketPong.bHeader = HEADER_CG_PONG; + if (!Send(sizeof(kPacketPong), &kPacketPong)) + return false; + + if (IsSecurityMode()) + return SendSequence(); + + return true; +} + +bool CAccountConnector::__AuthState_RecvAuthSuccess() +{ + TPacketGCAuthSuccess kAuthSuccessPacket; + if (!Recv(sizeof(kAuthSuccessPacket), &kAuthSuccessPacket)) + return false; + + if (!kAuthSuccessPacket.bResult) + { + if (m_poHandler) + PyCallClassMemberFunc(m_poHandler, "OnLoginFailure", Py_BuildValue("(s)", "BESAMEKEY")); + } + else + { + DWORD dwPanamaKey = kAuthSuccessPacket.dwLoginKey ^ g_adwEncryptKey[0] ^ g_adwEncryptKey[1] ^ g_adwEncryptKey[2] ^ g_adwEncryptKey[3]; + CEterPackManager::instance().DecryptPackIV(dwPanamaKey); + + CPythonNetworkStream & rkNet = CPythonNetworkStream::Instance(); + rkNet.SetLoginKey(kAuthSuccessPacket.dwLoginKey); + rkNet.Connect(m_strAddr.c_str(), m_iPort); + } + + Disconnect(); + __OfflineState_Set(); + + return true; +} + +#ifdef USE_OPENID +bool CAccountConnector::__AuthState_RecvAuthSuccess_OpenID() +{ + TPacketGCAuthSuccessOpenID kAuthSuccessOpenIDPacket; + if (!Recv(sizeof(kAuthSuccessOpenIDPacket), &kAuthSuccessOpenIDPacket)) + return false; + + if (!kAuthSuccessOpenIDPacket.bResult) + { + if (m_poHandler) + PyCallClassMemberFunc(m_poHandler, "OnLoginFailure", Py_BuildValue("(s)", "BESAMEKEY")); + } + else + { + DWORD dwPanamaKey = kAuthSuccessOpenIDPacket.dwLoginKey ^ g_adwEncryptKey[0] ^ g_adwEncryptKey[1] ^ g_adwEncryptKey[2] ^ g_adwEncryptKey[3]; + CEterPackManager::instance().DecryptPackIV(dwPanamaKey); + + CPythonNetworkStream & rkNet = CPythonNetworkStream::Instance(); + rkNet.SetLoginInfo(kAuthSuccessOpenIDPacket.login, "0000"); //OpenID йȣ ʴ´. + rkNet.SetLoginKey(kAuthSuccessOpenIDPacket.dwLoginKey); + rkNet.Connect(m_strAddr.c_str(), m_iPort); + } + + Disconnect(); + __OfflineState_Set(); + + return true; +} +#endif /* USE_OPENID */ + + +bool CAccountConnector::__AuthState_RecvAuthFailure() +{ + TPacketGCLoginFailure packet_failure; + if (!Recv(sizeof(TPacketGCLoginFailure), &packet_failure)) + return false; + + if (m_poHandler) + PyCallClassMemberFunc(m_poHandler, "OnLoginFailure", Py_BuildValue("(s)", packet_failure.szStatus)); + +// __OfflineState_Set(); + + return true; +} + +bool CAccountConnector::__AuthState_RecvRunupMatrixQuiz() +{ + TPacketGCRunupMatrixQuiz kMatrixQuizPacket; + if (!Recv(sizeof(TPacketGCRunupMatrixQuiz), &kMatrixQuizPacket)) + return false; + + PyCallClassMemberFunc(m_poHandler, "BINARY_OnRunupMatrixQuiz", Py_BuildValue("(s)", kMatrixQuizPacket.szQuiz)); + return true; +} + +bool CAccountConnector::__AuthState_RecvNEWCIBNPasspodRequest() +{ + TPacketGCNEWCIBNPasspodRequest kRequestPacket; + if (!Recv(sizeof(kRequestPacket), &kRequestPacket)) + return false; + + PyCallClassMemberFunc(m_poHandler, "BINARY_OnNEWCIBNPasspodRequest", Py_BuildValue("()")); + return true; +} + +#define ROW(rows, i) ((rows >> ((4 - i - 1) * 8)) & 0x000000FF) +#define COL(cols, i) ((cols >> ((4 - i - 1) * 8)) & 0x000000FF) + +bool CAccountConnector::__AuthState_RecvChinaMatrixCard() +{ + TPacketGCChinaMatrixCard kMatrixCardPacket; + if (!Recv(sizeof(TPacketGCChinaMatrixCard), &kMatrixCardPacket)) + return false; + + if (m_poHandler) + { + PyObject * pyValue = Py_BuildValue("(iiiiiiii)", ROW(kMatrixCardPacket.dwRows, 0), + ROW(kMatrixCardPacket.dwRows, 1), + ROW(kMatrixCardPacket.dwRows, 2), + ROW(kMatrixCardPacket.dwRows, 3), + COL(kMatrixCardPacket.dwCols, 0), + COL(kMatrixCardPacket.dwCols, 1), + COL(kMatrixCardPacket.dwCols, 2), + COL(kMatrixCardPacket.dwCols, 3)); + PyCallClassMemberFunc(m_poHandler, "OnMatrixCard", pyValue); + } + + return true; +} + +#ifdef _IMPROVED_PACKET_ENCRYPTION_ +bool CAccountConnector::__AuthState_RecvKeyAgreement() +{ + TPacketKeyAgreement packet; + if (!Recv(sizeof(packet), &packet)) + { + return false; + } + + Tracenf("KEY_AGREEMENT RECV %u", packet.wDataLength); + + TPacketKeyAgreement packetToSend; + size_t dataLength = TPacketKeyAgreement::MAX_DATA_LEN; + size_t agreedLength = Prepare(packetToSend.data, &dataLength); + if (agreedLength == 0) + { + // ʱȭ + Disconnect(); + return false; + } + assert(dataLength <= TPacketKeyAgreement::MAX_DATA_LEN); + + if (Activate(packet.wAgreedLength, packet.data, packet.wDataLength)) + { + // Key agreement , + packetToSend.bHeader = HEADER_CG_KEY_AGREEMENT; + packetToSend.wAgreedLength = (WORD)agreedLength; + packetToSend.wDataLength = (WORD)dataLength; + + if (!Send(sizeof(packetToSend), &packetToSend)) + { + Tracen(" CAccountConnector::__AuthState_RecvKeyAgreement - SendKeyAgreement Error"); + return false; + } + Tracenf("KEY_AGREEMENT SEND %u", packetToSend.wDataLength); + } + else + { + // Ű + Disconnect(); + return false; + } + return true; +} + +bool CAccountConnector::__AuthState_RecvKeyAgreementCompleted() +{ + TPacketKeyAgreementCompleted packet; + if (!Recv(sizeof(packet), &packet)) + { + return false; + } + + Tracenf("KEY_AGREEMENT_COMPLETED RECV"); + + ActivateCipher(); + + return true; +} +#endif // _IMPROVED_PACKET_ENCRYPTION_ + +bool CAccountConnector::__AnalyzePacket(UINT uHeader, UINT uPacketSize, bool (CAccountConnector::*pfnDispatchPacket)()) +{ + BYTE bHeader; + if (!Peek(sizeof(bHeader), &bHeader)) + return true; + + if (bHeader!=uHeader) + return true; + + if (!Peek(uPacketSize)) + return true; + + return (this->*pfnDispatchPacket)(); +} + +bool CAccountConnector::__AnalyzeVarSizePacket(UINT uHeader, bool (CAccountConnector::*pfnDispatchPacket)(int)) +{ + BYTE bHeader; + if (!Peek(sizeof(bHeader), &bHeader)) + return true; + + if (bHeader!=uHeader) + return true; + + TDynamicSizePacketHeader dynamicHeader; + + if (!Peek(sizeof(dynamicHeader), &dynamicHeader)) + return true; + + if (!Peek(dynamicHeader.size)) + return true; + + return (this->*pfnDispatchPacket)(dynamicHeader.size); +} + + +void CAccountConnector::__OfflineState_Set() +{ + __Inialize(); +} + +void CAccountConnector::__HandshakeState_Set() +{ + m_eState=STATE_HANDSHAKE; +} + +void CAccountConnector::__AuthState_Set() +{ + m_eState=STATE_AUTH; +} + +void CAccountConnector::OnConnectFailure() +{ + if (m_poHandler) + PyCallClassMemberFunc(m_poHandler, "OnConnectFailure", Py_BuildValue("()")); + + __OfflineState_Set(); +} + +void CAccountConnector::OnConnectSuccess() +{ + m_eState = STATE_HANDSHAKE; +} + +void CAccountConnector::OnRemoteDisconnect() +{ + // Matrix Card Number Ҵµ close Ǹ α׷ Ѵ. + if (m_isWaitKey) + { + if (m_poHandler) + { + PyCallClassMemberFunc(m_poHandler, "OnExit", Py_BuildValue("()")); + return; + } + } + + __OfflineState_Set(); +} + +void CAccountConnector::OnDisconnect() +{ + __OfflineState_Set(); +} + +#ifndef _IMPROVED_PACKET_ENCRYPTION_ +void CAccountConnector::__BuildClientKey() +{ + for (DWORD i = 0; i < 4; ++i) + g_adwEncryptKey[i] = random(); + + const BYTE * c_pszKey = (const BYTE *) "JyTxtHljHJlVJHorRM301vf@4fvj10-v"; + tea_encrypt((DWORD *) g_adwDecryptKey, (const DWORD *) g_adwEncryptKey, (const DWORD *) c_pszKey, 16); +} +#endif + +void CAccountConnector::__Inialize() +{ + m_eState=STATE_OFFLINE; + m_isWaitKey = FALSE; +} + +CAccountConnector::CAccountConnector() +{ + m_poHandler = NULL; + m_strAddr = ""; + m_iPort = 0; + + SetLoginInfo("", ""); + SetRecvBufferSize(1024 * 128); + SetSendBufferSize(2048); + __Inialize(); +} + +CAccountConnector::~CAccountConnector() +{ + __OfflineState_Set(); +} diff --git a/source/UserInterface/AccountConnector.h b/source/UserInterface/AccountConnector.h new file mode 100644 index 0000000..d7be7fa --- /dev/null +++ b/source/UserInterface/AccountConnector.h @@ -0,0 +1,93 @@ +#pragma + +#include "../EterLib/NetStream.h" +#include "../EterLib/FuncObject.h" + +class CAccountConnector : public CNetworkStream, public CSingleton +{ + public: + enum + { + STATE_OFFLINE, + STATE_HANDSHAKE, + STATE_AUTH, + }; + + public: + CAccountConnector(); + virtual ~CAccountConnector(); + + void SetHandler(PyObject* poHandler); + void SetLoginInfo(const char * c_szName, const char * c_szPwd); + void ClearLoginInfo( void ); + + bool SendChinaMatrixCardPacket(const char * c_szMatrixCardString); + bool SendRunupMatrixCardPacket(const char * c_szMatrixCardString); + bool SendNEWCIBNPasspodAnswerPacket(const char * answer); + + bool Connect(const char * c_szAddr, int iPort, const char * c_szAccountAddr, int iAccountPort); + void Disconnect(); + void Process(); + + protected: + void OnConnectFailure(); + void OnConnectSuccess(); + void OnRemoteDisconnect(); + void OnDisconnect(); + + protected: + void __Inialize(); + bool __StateProcess(); + + void __OfflineState_Set(); + void __HandshakeState_Set(); + void __AuthState_Set(); + + bool __HandshakeState_Process(); + bool __AuthState_Process(); + + bool __AuthState_RecvEmpty(); + bool __AuthState_RecvPhase(); + bool __AuthState_RecvHandshake(); + bool __AuthState_RecvPing(); + bool __AuthState_SendPong(); + bool __AuthState_RecvAuthSuccess(); +#ifdef USE_OPENID + bool __AuthState_RecvAuthSuccess_OpenID(); +#endif /* USE_OPENID */ + bool __AuthState_RecvAuthFailure(); + bool __AuthState_RecvChinaMatrixCard(); + bool __AuthState_RecvRunupMatrixQuiz(); + bool __AuthState_RecvNEWCIBNPasspodRequest(); + bool __AuthState_RecvPanamaPack(); +#ifdef _IMPROVED_PACKET_ENCRYPTION_ + bool __AuthState_RecvKeyAgreement(); + bool __AuthState_RecvKeyAgreementCompleted(); +#endif + bool __AuthState_RecvHybridCryptKeys(int VarSize); + bool __AuthState_RecvHybridCryptSDB(int VarSize); + + bool __AnalyzePacket(UINT uHeader, UINT uPacketSize, bool (CAccountConnector::*pfnDispatchPacket)()); + // TODO: ӽô. headerڿ size 4byte ´ٴ . + // Ϸ Packet System Refactoringؾ Ѵ. + bool __AnalyzeVarSizePacket(UINT uHeader, bool (CAccountConnector::*pfnDispatchPacket)(int)); + +#ifndef _IMPROVED_PACKET_ENCRYPTION_ + void __BuildClientKey(); +#endif + + protected: + UINT m_eState; + std::string m_strID; + std::string m_strPassword; + + std::string m_strAddr; + int m_iPort; + BOOL m_isWaitKey; + + PyObject * m_poHandler; + + // CHINA_CRYPT_KEY + void __BuildClientKey_20050304Myevan(); + // END_OF_CHINA_CRYPT_KEY +}; diff --git a/source/UserInterface/AffectFlagContainer.cpp b/source/UserInterface/AffectFlagContainer.cpp new file mode 100644 index 0000000..2e84841 --- /dev/null +++ b/source/UserInterface/AffectFlagContainer.cpp @@ -0,0 +1,92 @@ +#include "StdAfx.h" +#include "AffectFlagContainer.h" + +CAffectFlagContainer::CAffectFlagContainer() +{ + Clear(); +} + +CAffectFlagContainer::~CAffectFlagContainer() +{ +} + +void CAffectFlagContainer::Clear() +{ + memset(m_aElement, 0, sizeof(m_aElement)); +} + +void CAffectFlagContainer::CopyInstance(const CAffectFlagContainer& c_rkAffectContainer) +{ + memcpy(m_aElement, c_rkAffectContainer.m_aElement, sizeof(m_aElement)); +} + +void CAffectFlagContainer::CopyData(UINT uPos, UINT uByteSize, const void* c_pvData) +{ + const BYTE* c_pbData=(const BYTE*)c_pvData; + Element bMask=0x01; + + UINT uBitEnd=uPos+uByteSize*8; + for (UINT i=uPos; i=BYTE_SIZE) + { + return NULL; + } + + return (const void *)&m_aElement[uPos]; +} +*/ + +void CAffectFlagContainer::Set(UINT uPos, bool isSet) +{ + if (uPos/8>=BYTE_SIZE) + { + TraceError("CAffectFlagContainer::Set(uPos=%d>%d, isSet=%d", uPos, BYTE_SIZE*8, isSet); + return; + } + + BYTE& rElement=m_aElement[uPos/8]; + + BYTE bMask=BYTE(1<<(uPos&7)); + if (isSet) + rElement|=bMask; + else + rElement&=~bMask; +} + +bool CAffectFlagContainer::IsSet(UINT uPos) const +{ + if (uPos/8>=BYTE_SIZE) + { + TraceError("CAffectFlagContainer::IsSet(uPos=%d>%d", uPos, BYTE_SIZE*8); + return false; + } + + const BYTE& c_rElement=m_aElement[uPos/8]; + + BYTE bMask=BYTE(1<<(uPos&7)); + if (c_rElement&bMask) + return true; + + return false; +} diff --git a/source/UserInterface/AffectFlagContainer.h b/source/UserInterface/AffectFlagContainer.h new file mode 100644 index 0000000..bbbfc8b --- /dev/null +++ b/source/UserInterface/AffectFlagContainer.h @@ -0,0 +1,29 @@ +#pragma once + +class CAffectFlagContainer +{ + public: + enum + { + BIT_SIZE = 64, + BYTE_SIZE = BIT_SIZE/8+(1*((BIT_SIZE&7) ? 1 : 0)), + }; + + public: + CAffectFlagContainer(); + ~CAffectFlagContainer(); + + void Clear(); + void CopyInstance(const CAffectFlagContainer& c_rkAffectContainer); + void Set(UINT uPos, bool isSet); + bool IsSet(UINT uPos) const; + + void CopyData(UINT uPos, UINT uByteSize, const void* c_pvData); + + void ConvertToPosition(unsigned* uRetX, unsigned* uRetY) const; + + private: + typedef unsigned char Element; + + Element m_aElement[BYTE_SIZE]; +}; \ No newline at end of file diff --git a/source/UserInterface/CameraProcedure.cpp b/source/UserInterface/CameraProcedure.cpp new file mode 100644 index 0000000..1ac4d88 --- /dev/null +++ b/source/UserInterface/CameraProcedure.cpp @@ -0,0 +1,354 @@ +#include "StdAfx.h" +#include "PythonBackground.h" +#include "../eterlib/Camera.h" + +////////////////////////////////////////////////////////////////////////// +// ޼ + +extern void SetHeightLog(bool isLog); + +float CCamera::CAMERA_MIN_DISTANCE = 200.0f; +float CCamera::CAMERA_MAX_DISTANCE = 2500.0f; + +void CCamera::ProcessTerrainCollision() +{ + CPythonBackground & rPythonBackground = CPythonBackground::Instance(); + D3DXVECTOR3 v3CollisionPoint; + + if (rPythonBackground.GetPickingPointWithRayOnlyTerrain(m_kTargetToCameraBottomRay, &v3CollisionPoint)) + { + SetCameraState(CAMERA_STATE_CANTGODOWN); + D3DXVECTOR3 v3CheckVector = m_v3Eye - 2.0f * m_fTerrainCollisionRadius * m_v3Up; + v3CheckVector.z = rPythonBackground.GetHeight(floorf(v3CheckVector.x), floorf(v3CheckVector.y)); + D3DXVECTOR3 v3NewEye = v3CheckVector + 2.0f * m_fTerrainCollisionRadius * m_v3Up; + if (v3NewEye.z > m_v3Eye.z) + { + //printf("ToCameraBottom(%f, %f, %f) TCR %f, UP(%f, %f, %f), new %f > old %f", + // v3CheckVector.x, v3CheckVector.y, v3CheckVector.z, + // m_fTerrainCollisionRadius, + // m_v3Up.x, m_v3Up.y, m_v3Up.z, + // v3NewEye.z, m_v3Eye.z); + SetEye(v3NewEye); + } + /* + SetCameraState(CAMERA_STATE_NORMAL); + D3DXVECTOR3 v3NewEye = v3CollisionPoint; + SetEye(v3NewEye); + */ + } + else + SetCameraState(CAMERA_STATE_NORMAL); + + if (rPythonBackground.GetPickingPointWithRayOnlyTerrain(m_kCameraBottomToTerrainRay, &v3CollisionPoint)) + { + SetCameraState(CAMERA_STATE_CANTGODOWN); + auto d3dd = (m_v3Eye - v3CollisionPoint); + if (D3DXVec3Length(&d3dd) < 2.0f * m_fTerrainCollisionRadius) + { + D3DXVECTOR3 v3NewEye = v3CollisionPoint + 2.0f * m_fTerrainCollisionRadius * m_v3Up; + //printf("CameraBottomToTerrain new %f > old %f", v3NewEye.z, m_v3Eye.z); + SetEye(v3NewEye); + } + } + else + SetCameraState(CAMERA_STATE_NORMAL); +/* + if (rPythonBackground.GetPickingPointWithRayOnlyTerrain(m_kCameraFrontToTerrainRay, &v3CollisionPoint)) + { + if (D3DXVec3Length(&(m_v3Eye - v3CollisionPoint)) < 4.0f * m_fTerrainCollisionRadius) + { + D3DXVECTOR3 v3NewEye = v3CollisionPoint - 4.0f * m_fTerrainCollisionRadius * m_v3View; + //printf("CameraFrontToTerrain new %f > old %f", v3NewEye.z, m_v3Eye.z); + SetEye(v3NewEye); + } + } + + if (rPythonBackground.GetPickingPointWithRayOnlyTerrain(m_kCameraBackToTerrainRay, &v3CollisionPoint)) + { + if (D3DXVec3Length(&(m_v3Eye - v3CollisionPoint)) < m_fTerrainCollisionRadius) + { + D3DXVECTOR3 v3NewEye = v3CollisionPoint + m_fTerrainCollisionRadius * m_v3View; + //printf("CameraBackToTerrain new %f > old %f", v3NewEye.z, m_v3Eye.z); + SetEye(v3NewEye); + } + } + + // Left + if (rPythonBackground.GetPickingPointWithRayOnlyTerrain(m_kCameraLeftToTerrainRay, &v3CollisionPoint)) + { + SetCameraState(CAMERA_STATE_CANTGOLEFT); + if (D3DXVec3Length(&(m_v3Eye - v3CollisionPoint)) < 3.0f * m_fTerrainCollisionRadius) + { + D3DXVECTOR3 v3NewEye = v3CollisionPoint + 3.0f * m_fTerrainCollisionRadius * m_v3Cross; + //printf("CameraLeftToTerrain new %f > old %f", v3NewEye.z, m_v3Eye.z); + SetEye(v3NewEye); + } + } + else + SetCameraState(CAMERA_STATE_NORMAL); + + // Right + if (rPythonBackground.GetPickingPointWithRayOnlyTerrain(m_kCameraRightToTerrainRay, &v3CollisionPoint)) + { + SetCameraState(CAMERA_STATE_CANTGORIGHT); + if (D3DXVec3Length(&(m_v3Eye - v3CollisionPoint)) < 3.0f * m_fTerrainCollisionRadius) + { + D3DXVECTOR3 v3NewEye = v3CollisionPoint - 3.0f * m_fTerrainCollisionRadius * m_v3Cross; + //printf("CameraRightToTerrain new %f > old %f", v3NewEye.z, m_v3Eye.z); + SetEye(v3NewEye); + } + } + else + SetCameraState(CAMERA_STATE_NORMAL); + */ +} + +struct CameraCollisionChecker +{ + bool m_isBlocked; + std::vector* m_pkVct_v3Position; + CDynamicSphereInstance * m_pdsi; + + CameraCollisionChecker(CDynamicSphereInstance * pdsi, std::vector* pkVct_v3Position) : m_pdsi(pdsi), m_pkVct_v3Position(pkVct_v3Position), m_isBlocked(false) + { + } + void operator () (CGraphicObjectInstance* pOpponent) + { + if (pOpponent->CollisionDynamicSphere(*m_pdsi)) + { + m_pkVct_v3Position->push_back(pOpponent->GetPosition()); + m_isBlocked = true; + } + } +}; + +void CCamera::ProcessBuildingCollision() +{ + float fMoveAmountSmall = 2.0f; + float fMoveAmountLarge = 4.0f; + + D3DXVECTOR3 v3CheckVector; + + CDynamicSphereInstance s; + s.fRadius = m_fObjectCollisionRadius; + s.v3LastPosition = m_v3Eye; + + Vector3d aVector3d; + aVector3d.Set(m_v3Eye.x, m_v3Eye.y, m_v3Eye.z); + + // + + CCullingManager & rkCullingMgr = CCullingManager::Instance(); + + { + v3CheckVector = m_v3Eye - m_fObjectCollisionRadius * m_v3View; + s.v3Position = v3CheckVector; + + std::vector kVct_kPosition; + CameraCollisionChecker kCameraCollisionChecker(&s, &kVct_kPosition); + rkCullingMgr.ForInRange(aVector3d, m_fObjectCollisionRadius, &kCameraCollisionChecker); + bool bCollide = kCameraCollisionChecker.m_isBlocked; + + if (bCollide) + { + if (m_v3AngularVelocity.y > 0.0f) + { + m_v3AngularVelocity.y = 0.0f; + m_v3AngularVelocity.z += fMoveAmountLarge; + } + // m_v3AngularVelocity.y = fMAX(fMoveAmountSmall, m_v3AngularVelocity.y); + //// m_v3AngularVelocity.y += fMoveAmountSmall; + + if (kVct_kPosition.size() > 1) + { + // m_v3AngularVelocity.z = fMAX(fMoveAmountSmall, m_v3AngularVelocity.z); + m_v3AngularVelocity.z += fMoveAmountSmall; + } + else + { + auto d3dd = (kVct_kPosition[0] - m_v3Eye); + D3DXVec3Cross(&v3CheckVector, &d3dd, &m_v3View); + float fDot = D3DXVec3Dot(&v3CheckVector, &m_v3Up); + if (fDot < 0) + { + // m_v3AngularVelocity.x = fMIN(-fMoveAmountSmall, m_v3AngularVelocity.x); + m_v3AngularVelocity.x -= fMoveAmountSmall; + } + else if(fDot > 0) + { + // m_v3AngularVelocity.x = fMAX(fMoveAmountSmall, m_v3AngularVelocity.x); + m_v3AngularVelocity.x += fMoveAmountSmall; + } + else + { + // m_v3AngularVelocity.z = fMAX(fMoveAmountSmall, m_v3AngularVelocity.z); + m_v3AngularVelocity.z += fMoveAmountSmall; + } + } + } + } + + // + { + v3CheckVector = m_v3Eye + 2.0f * m_fObjectCollisionRadius * m_v3Up; + s.v3Position = v3CheckVector; + + std::vector kVct_kPosition; + CameraCollisionChecker kCameraCollisionChecker(&s, &kVct_kPosition); + rkCullingMgr.ForInRange(aVector3d, m_fObjectCollisionRadius, &kCameraCollisionChecker); + bool bCollide = kCameraCollisionChecker.m_isBlocked; + + if (bCollide) + { + m_v3AngularVelocity.z = fMIN(-fMoveAmountSmall, m_v3AngularVelocity.y); + // m_v3AngularVelocity.z -= 1.0f; + } + } + + // + { + v3CheckVector = m_v3Eye + 3.0f * m_fObjectCollisionRadius * m_v3Cross; + s.v3Position = v3CheckVector; + + std::vector kVct_kPosition; + CameraCollisionChecker kCameraCollisionChecker(&s, &kVct_kPosition); + rkCullingMgr.ForInRange(aVector3d, m_fObjectCollisionRadius, &kCameraCollisionChecker); + bool bCollide = kCameraCollisionChecker.m_isBlocked; + + if (bCollide) + { + if (m_v3AngularVelocity.x > 0.0f) + { + m_v3AngularVelocity.x = 0.0f; + m_v3AngularVelocity.y += fMoveAmountLarge; + } + } + } + + // + { + v3CheckVector = m_v3Eye - 3.0f * m_fObjectCollisionRadius * m_v3Cross; + s.v3Position = v3CheckVector; + + std::vector kVct_kPosition; + CameraCollisionChecker kCameraCollisionChecker(&s, &kVct_kPosition); + rkCullingMgr.ForInRange(aVector3d, m_fObjectCollisionRadius, &kCameraCollisionChecker); + bool bCollide = kCameraCollisionChecker.m_isBlocked; + + if (bCollide) + { + if (m_v3AngularVelocity.x < 0.0f) + { + m_v3AngularVelocity.x = 0.0f; + m_v3AngularVelocity.y += fMoveAmountLarge; + } + } + } + + // Ʒ + { + v3CheckVector = m_v3Eye - 2.0f * m_fTerrainCollisionRadius * m_v3Up; + s.v3Position = v3CheckVector; + + std::vector kVct_kPosition; + CameraCollisionChecker kCameraCollisionChecker(&s, &kVct_kPosition); + rkCullingMgr.ForInRange(aVector3d, m_fObjectCollisionRadius, &kCameraCollisionChecker); + bool bCollide = kCameraCollisionChecker.m_isBlocked; + + if (bCollide) + { + if (m_v3AngularVelocity.z < 0.0f) + { + m_v3AngularVelocity.z = 0.0f; + m_v3AngularVelocity.y += fMoveAmountLarge; + } + } + } + + // + { + v3CheckVector = m_v3Eye + 4.0f * m_fObjectCollisionRadius * m_v3View; + s.v3Position = v3CheckVector; + + std::vector kVct_kPosition; + CameraCollisionChecker kCameraCollisionChecker(&s, &kVct_kPosition); + rkCullingMgr.ForInRange(aVector3d, m_fObjectCollisionRadius, &kCameraCollisionChecker); + bool bCollide = kCameraCollisionChecker.m_isBlocked; + + if (bCollide) + { + if (m_v3AngularVelocity.y < 0.0f) + { + m_v3AngularVelocity.y = 0.0f; + m_v3AngularVelocity.z += fMoveAmountLarge; + } + + if (kVct_kPosition.size() > 1) + { + // m_v3AngularVelocity.z = fMAX(fMoveAmountLarge, m_v3AngularVelocity.z); + m_v3AngularVelocity.z += fMoveAmountLarge; + } + else + { + auto d3dd = (kVct_kPosition[0] - m_v3Eye); + D3DXVec3Cross(&v3CheckVector, &d3dd, &m_v3View); + float fDot = D3DXVec3Dot(&v3CheckVector, &m_v3Up); + if (fDot < 0) + { + // m_v3AngularVelocity.x = fMIN(-fMoveAmountSmall, m_v3AngularVelocity.x); + m_v3AngularVelocity.x -= fMoveAmountSmall; + } + else if(fDot > 0) + { + // m_v3AngularVelocity.x = fMAX(fMoveAmountSmall, m_v3AngularVelocity.x); + m_v3AngularVelocity.x += fMoveAmountSmall; + } + else + { + // m_v3AngularVelocity.z = fMAX(fMoveAmountSmall, m_v3AngularVelocity.z); + m_v3AngularVelocity.z += fMoveAmountSmall; + } + } + } + } +} + +void CCamera::Update() +{ +// ProcessBuildingCollision(); + + RotateEyeAroundTarget(m_v3AngularVelocity.z, m_v3AngularVelocity.x); + + float fNewDistance=fMAX(CAMERA_MIN_DISTANCE, fMIN( CAMERA_MAX_DISTANCE, GetDistance() - m_v3AngularVelocity.y ) ); + SetDistance(fNewDistance); + + if (m_bProcessTerrainCollision) + ProcessTerrainCollision(); + + m_v3AngularVelocity *= 0.5f; + if (fabs(m_v3AngularVelocity.x) < 1.0f) + m_v3AngularVelocity.x = 0.0f; + if (fabs(m_v3AngularVelocity.y) < 1.0f) + m_v3AngularVelocity.y = 0.0f; + if (fabs(m_v3AngularVelocity.z) < 1.0f) + m_v3AngularVelocity.z = 0.0f; + + const float CAMERA_MOVABLE_DISTANCE = CAMERA_MAX_DISTANCE - CAMERA_MIN_DISTANCE; + const float CAMERA_TARGET_DELTA = CAMERA_TARGET_FACE - CAMERA_TARGET_STANDARD; + float fCameraCurMovableDistance=CAMERA_MAX_DISTANCE - GetDistance(); + float fNewTargetHeight = CAMERA_TARGET_STANDARD + CAMERA_TARGET_DELTA * fCameraCurMovableDistance / CAMERA_MOVABLE_DISTANCE; + + SetTargetHeight(fNewTargetHeight); + + // Cinematic +#ifdef __20040725_CAMERA_WORK__ + m_MovementPosition += m_MovementSpeed; + + if (0.0f != m_MovementPosition.m_fViewDir) + MoveFront(m_MovementPosition.m_fViewDir); + if (0.0f != m_MovementPosition.m_fCrossDir) + MoveAlongCross(m_MovementPosition.m_fCrossDir); + if (0.0f != m_MovementPosition.m_fUpDir) + MoveVertical(m_MovementPosition.m_fUpDir); +#endif +} diff --git a/source/UserInterface/CheckLatestFiles.cpp b/source/UserInterface/CheckLatestFiles.cpp new file mode 100644 index 0000000..4b036c6 --- /dev/null +++ b/source/UserInterface/CheckLatestFiles.cpp @@ -0,0 +1,64 @@ +#include "StdAfx.h" +#if defined(CHECK_LATEST_DATA_FILES) +#include "CheckLatestFiles.h" +#include "resource.h" + +static struct SCHECKFILELIST +{ + LPCSTR szFileName; + DWORD dwCRC32; + ULONGLONG ullSize; +} s_astCRC32FileList[] = { +#include "CRC32_inc.h" + { NULL, 0 } +}; + +static bool gs_bQuit = false; + +bool CheckLatestFiles_PollEvent( void ) +{ + return gs_bQuit; +} + +// Ÿ CRC32 ˻ϱ +bool CheckFileCRC32( LPCSTR szFileName, DWORD dwCRC32 ) +{ + char szMessage[256]; + + if (_access( szFileName, 4 ) != 0) { + _snprintf(szMessage, sizeof(szMessage)/sizeof(szMessage[0])-1, ApplicationStringTable_GetStringz(IDS_ERR_CANNOT_READ_FILE, "ERR_CANNOT_READ_FILE"), szFileName); + ApplicationSetErrorString(szMessage); + return false; + } + DWORD dwLocalCRC32 = GetFileCRC32(szFileName); + + if (dwCRC32 != dwLocalCRC32) { + _snprintf(szMessage, sizeof(szMessage)/sizeof(szMessage[0])-1, ApplicationStringTable_GetStringz(IDS_ERR_NOT_LATEST_FILE, "ERR_NOT_LATEST_FILE"), szFileName); + ApplicationSetErrorString(szMessage); + return false; + } + + return true; +} + +UINT CALLBACK CheckLatestFilesEntry(void * pThis) +{ + ::Sleep( 500 ); + for( int i=0; s_astCRC32FileList[i].szFileName != NULL; i++ ) { + if (false == CheckFileCRC32(s_astCRC32FileList[i].szFileName, s_astCRC32FileList[i].dwCRC32)) { + gs_bQuit = true; + break; + } + } + return 0; +} + +bool CheckLatestFiles( void ) +{ + unsigned int uThreadID = 0; + + HANDLE hThread = (HANDLE) _beginthreadex(NULL, 0, CheckLatestFilesEntry, NULL, 0, &uThreadID); + ::SetThreadPriority(hThread, THREAD_PRIORITY_LOWEST); + return true; +} +#endif diff --git a/source/UserInterface/CheckLatestFiles.h b/source/UserInterface/CheckLatestFiles.h new file mode 100644 index 0000000..9726cbd --- /dev/null +++ b/source/UserInterface/CheckLatestFiles.h @@ -0,0 +1,6 @@ +#pragma once + +#if defined(CHECK_LATEST_DATA_FILES) +bool CheckLatestFiles( void ); +bool CheckLatestFiles_PollEvent( void ); +#endif diff --git a/source/UserInterface/Cursors/cursor.cur b/source/UserInterface/Cursors/cursor.cur new file mode 100644 index 0000000..f8d2622 Binary files /dev/null and b/source/UserInterface/Cursors/cursor.cur differ diff --git a/source/UserInterface/Cursors/cursor_attack.cur b/source/UserInterface/Cursors/cursor_attack.cur new file mode 100644 index 0000000..91fce13 Binary files /dev/null and b/source/UserInterface/Cursors/cursor_attack.cur differ diff --git a/source/UserInterface/Cursors/cursor_buy.cur b/source/UserInterface/Cursors/cursor_buy.cur new file mode 100644 index 0000000..6ac8013 Binary files /dev/null and b/source/UserInterface/Cursors/cursor_buy.cur differ diff --git a/source/UserInterface/Cursors/cursor_camera_rotate.cur b/source/UserInterface/Cursors/cursor_camera_rotate.cur new file mode 100644 index 0000000..df84002 Binary files /dev/null and b/source/UserInterface/Cursors/cursor_camera_rotate.cur differ diff --git a/source/UserInterface/Cursors/cursor_chair.cur b/source/UserInterface/Cursors/cursor_chair.cur new file mode 100644 index 0000000..c05e15f Binary files /dev/null and b/source/UserInterface/Cursors/cursor_chair.cur differ diff --git a/source/UserInterface/Cursors/cursor_door.cur b/source/UserInterface/Cursors/cursor_door.cur new file mode 100644 index 0000000..0abf25f Binary files /dev/null and b/source/UserInterface/Cursors/cursor_door.cur differ diff --git a/source/UserInterface/Cursors/cursor_hsize.cur b/source/UserInterface/Cursors/cursor_hsize.cur new file mode 100644 index 0000000..daafe9f Binary files /dev/null and b/source/UserInterface/Cursors/cursor_hsize.cur differ diff --git a/source/UserInterface/Cursors/cursor_hvsize.cur b/source/UserInterface/Cursors/cursor_hvsize.cur new file mode 100644 index 0000000..61eb5b9 Binary files /dev/null and b/source/UserInterface/Cursors/cursor_hvsize.cur differ diff --git a/source/UserInterface/Cursors/cursor_no.cur b/source/UserInterface/Cursors/cursor_no.cur new file mode 100644 index 0000000..ca82dfb Binary files /dev/null and b/source/UserInterface/Cursors/cursor_no.cur differ diff --git a/source/UserInterface/Cursors/cursor_pick.cur b/source/UserInterface/Cursors/cursor_pick.cur new file mode 100644 index 0000000..a71ba1f Binary files /dev/null and b/source/UserInterface/Cursors/cursor_pick.cur differ diff --git a/source/UserInterface/Cursors/cursor_sell.cur b/source/UserInterface/Cursors/cursor_sell.cur new file mode 100644 index 0000000..68a0e1f Binary files /dev/null and b/source/UserInterface/Cursors/cursor_sell.cur differ diff --git a/source/UserInterface/Cursors/cursor_talk.cur b/source/UserInterface/Cursors/cursor_talk.cur new file mode 100644 index 0000000..229495d Binary files /dev/null and b/source/UserInterface/Cursors/cursor_talk.cur differ diff --git a/source/UserInterface/Cursors/cursor_vsize.cur b/source/UserInterface/Cursors/cursor_vsize.cur new file mode 100644 index 0000000..00e215b Binary files /dev/null and b/source/UserInterface/Cursors/cursor_vsize.cur differ diff --git a/source/UserInterface/Discord.h b/source/UserInterface/Discord.h new file mode 100644 index 0000000..d3c1ea8 --- /dev/null +++ b/source/UserInterface/Discord.h @@ -0,0 +1,104 @@ +/* +* blackdragonx61 +* Mali +*/ + +#pragma once +#include "StdAfx.h" +#include "PythonCharacterManager.h" +#include "PythonBackground.h" +#include "PythonPlayer.h" +#include "PythonGuild.h" + +namespace Discord +{ + inline constexpr auto DiscordClientID = "667352913621942276"; + + using DCDATA = std::pair; + + + /*NAME*/ + inline DCDATA GetNameData() + { + /*Map Name*/ + auto WarpName = std::string(CPythonBackground::Instance().GetWarpMapName()); + + //atlasinfo.txt + static const std::map m_MapName { + { "metin2_map_a1", "Yongan" }, + { "metin2_map_b1", "Joan" }, + { "metin2_map_c1", "Pyungmoo" }, + }; + + auto MapName = "Location: " + (m_MapName.count(WarpName) ? m_MapName.at(WarpName) : WarpName); + + /*CH Name*/ + auto CHName = "Name: " + std::string(CPythonPlayer::Instance().GetName()); + std::string GuildName; + if (CPythonGuild::Instance().GetGuildName(CPythonPlayer::Instance().GetGuildID(), &GuildName)) + CHName += "-Guild: " + GuildName; + + return { MapName, CHName }; + } + + /*RACE*/ + inline DCDATA GetRaceData() + { + auto pInstance = CPythonCharacterManager::Instance().GetMainInstancePtr(); + if (!pInstance) + return { "","" }; + + auto RACENUM = pInstance->GetRace(); + + /*Image*/ + auto RaceImage = "race_" + std::to_string(RACENUM); + + /*Name*/ + auto RaceName = "Warrior"; + switch (RACENUM) + { + case NRaceData::JOB_ASSASSIN: + case NRaceData::JOB_ASSASSIN + 4: + RaceName = "Assassin"; + break; + case NRaceData::JOB_SURA: + case NRaceData::JOB_SURA + 4: + RaceName = "Sura"; + break; + case NRaceData::JOB_SHAMAN: + case NRaceData::JOB_SHAMAN + 4: + RaceName = "Shaman"; + break; +#if defined(ENABLE_WOLFMAN_CHARACTER) + case NRaceData::JOB_WOLFMAN: + RaceName = "Lycan"; +#endif + } + return { RaceImage , RaceName }; + } + + /*EMPIRE*/ + inline DCDATA GetEmpireData() + { + auto pInstance = CPythonCharacterManager::Instance().GetMainInstancePtr(); + if (!pInstance) + return { "","" }; + + auto EmpireID = pInstance->GetEmpireID(); + + /*Image*/ + auto EmpireImage = "empire_" + std::to_string(EmpireID); + + /*Name*/ + auto EmpireName = "Shinsoo"; + switch (EmpireID) + { + case 2: + EmpireName = "Chunjo"; + break; + case 3: + EmpireName = "Jinno"; + } + return { EmpireImage, EmpireName}; + } +} \ No newline at end of file diff --git a/source/UserInterface/GameType.cpp b/source/UserInterface/GameType.cpp new file mode 100644 index 0000000..f57670a --- /dev/null +++ b/source/UserInterface/GameType.cpp @@ -0,0 +1,112 @@ +#include "StdAfx.h" +#include "GameType.h" + +std::string g_strResourcePath = "d:/ymir work/"; +std::string g_strImagePath = "d:/ymir work/ui/"; + +std::string g_strGuildSymbolPathName = "mark/10/"; + +// DEFAULT_FONT +static std::string gs_strDefaultFontName = "ü:12.fnt"; +static std::string gs_strDefaultItalicFontName = "ü:12i.fnt"; +static CResource* gs_pkDefaultFont = NULL; +static CResource* gs_pkDefaultItalicFont = NULL; + +static bool gs_isReloadDefaultFont = false; + +void DefaultFont_Startup() +{ + gs_pkDefaultFont = NULL; +} + +void DefaultFont_Cleanup() +{ + if (gs_pkDefaultFont) + gs_pkDefaultFont->Release(); +} + +void DefaultFont_SetName(const char * c_szFontName) +{ + gs_strDefaultFontName = c_szFontName; + gs_strDefaultFontName += ".fnt"; + + gs_strDefaultItalicFontName = c_szFontName; + if(strchr(c_szFontName, ':')) + gs_strDefaultItalicFontName += "i"; + gs_strDefaultItalicFontName += ".fnt"; + + gs_isReloadDefaultFont = true; +} + +bool ReloadDefaultFonts() +{ + CResourceManager& rkResMgr = CResourceManager::Instance(); + + gs_isReloadDefaultFont = false; + + CResource* pkNewFont = rkResMgr.GetResourcePointer(gs_strDefaultFontName.c_str()); + pkNewFont->AddReference(); + if (gs_pkDefaultFont) + gs_pkDefaultFont->Release(); + gs_pkDefaultFont = pkNewFont; + + CResource* pkNewItalicFont = rkResMgr.GetResourcePointer(gs_strDefaultItalicFontName.c_str()); + pkNewItalicFont->AddReference(); + if (gs_pkDefaultItalicFont) + gs_pkDefaultItalicFont->Release(); + gs_pkDefaultItalicFont = pkNewItalicFont; + + return true; +} + +CResource* DefaultFont_GetResource() +{ + if (!gs_pkDefaultFont || gs_isReloadDefaultFont) + ReloadDefaultFonts(); + return gs_pkDefaultFont; +} + +CResource* DefaultItalicFont_GetResource() +{ + if (!gs_pkDefaultItalicFont || gs_isReloadDefaultFont) + ReloadDefaultFonts(); + return gs_pkDefaultItalicFont; +} + +// END_OF_DEFAULT_FONT + +void SetGuildSymbolPath(const char * c_szPathName) +{ + g_strGuildSymbolPathName = "mark/"; + g_strGuildSymbolPathName += c_szPathName; + g_strGuildSymbolPathName += "/"; +} + +const char * GetGuildSymbolFileName(DWORD dwGuildID) +{ + return _getf("%s%03d.jpg", g_strGuildSymbolPathName.c_str(), dwGuildID); +} + +BYTE c_aSlotTypeToInvenType[SLOT_TYPE_MAX] = +{ + RESERVED_WINDOW, // SLOT_TYPE_NONE + INVENTORY, // SLOT_TYPE_INVENTORY + RESERVED_WINDOW, // SLOT_TYPE_SKILL + RESERVED_WINDOW, // SLOT_TYPE_EMOTION + RESERVED_WINDOW, // SLOT_TYPE_SHOP + RESERVED_WINDOW, // SLOT_TYPE_EXCHANGE_OWNER + RESERVED_WINDOW, // SLOT_TYPE_EXCHANGE_TARGET + RESERVED_WINDOW, // SLOT_TYPE_QUICK_SLOT + RESERVED_WINDOW, // SLOT_TYPE_SAFEBOX <- SAFEBOX, MALL ϵ ڵǾִ LEGACY ڵ带 . + RESERVED_WINDOW, // SLOT_TYPE_PRIVATE_SHOP + RESERVED_WINDOW, // SLOT_TYPE_MALL <- SAFEBOX, MALL ϵ ڵǾִ LEGACY ڵ带 . + DRAGON_SOUL_INVENTORY, // SLOT_TYPE_DRAGON_SOUL_INVENTORY +}; + +BYTE SlotTypeToInvenType(BYTE bSlotType) +{ + if (bSlotType >= SLOT_TYPE_MAX) + return RESERVED_WINDOW; + else + return c_aSlotTypeToInvenType[bSlotType]; +} diff --git a/source/UserInterface/GameType.h b/source/UserInterface/GameType.h new file mode 100644 index 0000000..8d84dd9 --- /dev/null +++ b/source/UserInterface/GameType.h @@ -0,0 +1,360 @@ +#pragma once +#include "../GameLib/ItemData.h" + +struct SAffects +{ + enum + { + AFFECT_MAX_NUM = 32, + }; + + SAffects() : dwAffects(0) {} + SAffects(const DWORD & c_rAffects) + { + __SetAffects(c_rAffects); + } + int operator = (const DWORD & c_rAffects) + { + __SetAffects(c_rAffects); + } + + BOOL IsAffect(BYTE byIndex) + { + return dwAffects & (1 << byIndex); + } + + void __SetAffects(const DWORD & c_rAffects) + { + dwAffects = c_rAffects; + } + + DWORD dwAffects; +}; + +extern std::string g_strGuildSymbolPathName; + +const DWORD c_Name_Max_Length = 64; +const DWORD c_FileName_Max_Length = 128; +const DWORD c_Short_Name_Max_Length = 32; + +const DWORD c_Inventory_Page_Size = 5*9; // x*y +const DWORD c_Inventory_Page_Count = 2; +const DWORD c_ItemSlot_Count = c_Inventory_Page_Size * c_Inventory_Page_Count; +const DWORD c_Equipment_Count = 12; + +const DWORD c_Equipment_Start = c_ItemSlot_Count; + +const DWORD c_Equipment_Body = c_Equipment_Start + 0; +const DWORD c_Equipment_Head = c_Equipment_Start + 1; +const DWORD c_Equipment_Shoes = c_Equipment_Start + 2; +const DWORD c_Equipment_Wrist = c_Equipment_Start + 3; +const DWORD c_Equipment_Weapon = c_Equipment_Start + 4; +const DWORD c_Equipment_Neck = c_Equipment_Start + 5; +const DWORD c_Equipment_Ear = c_Equipment_Start + 6; +const DWORD c_Equipment_Unique1 = c_Equipment_Start + 7; +const DWORD c_Equipment_Unique2 = c_Equipment_Start + 8; +const DWORD c_Equipment_Arrow = c_Equipment_Start + 9; +const DWORD c_Equipment_Shield = c_Equipment_Start + 10; + +// ߰ ű & Ʈ +// ۿ Ҵ ִ ġ , ä Ʈ , ڽƬ ý ؼ ߷ִ. +// ̰ ä ó ... +// +// ϸ, â DB 90 ~ 102 ̰, +// 2013 ʿ ߰Ǵ Ե 111 ~ Ѵ. 񿡼 ִ ִ 121 ̰, 122ʹ ȥ Ѵ. +#ifdef ENABLE_NEW_EQUIPMENT_SYSTEM + const DWORD c_New_Equipment_Start = c_Equipment_Start + 21; + const DWORD c_New_Equipment_Count = 3; + const DWORD c_Equipment_Ring1 = c_New_Equipment_Start + 0; + const DWORD c_Equipment_Ring2 = c_New_Equipment_Start + 1; + const DWORD c_Equipment_Belt = c_New_Equipment_Start + 2;; +#endif + +enum EDragonSoulDeckType +{ + DS_DECK_1, + DS_DECK_2, + DS_DECK_MAX_NUM = 2, +}; + +enum EDragonSoulGradeTypes +{ + DRAGON_SOUL_GRADE_NORMAL, + DRAGON_SOUL_GRADE_BRILLIANT, + DRAGON_SOUL_GRADE_RARE, + DRAGON_SOUL_GRADE_ANCIENT, + DRAGON_SOUL_GRADE_LEGENDARY, + DRAGON_SOUL_GRADE_MAX, + +}; + +enum EDragonSoulStepTypes +{ + DRAGON_SOUL_STEP_LOWEST, + DRAGON_SOUL_STEP_LOW, + DRAGON_SOUL_STEP_MID, + DRAGON_SOUL_STEP_HIGH, + DRAGON_SOUL_STEP_HIGHEST, + DRAGON_SOUL_STEP_MAX, +}; + +#ifdef ENABLE_COSTUME_SYSTEM + const DWORD c_Costume_Slot_Start = c_Equipment_Start + 19; // [] (19) ϵڵ . ڽ 19. common/length.h EWearPositions . + const DWORD c_Costume_Slot_Body = c_Costume_Slot_Start + 0; + const DWORD c_Costume_Slot_Hair = c_Costume_Slot_Start + 1; + const DWORD c_Costume_Slot_Count = 2; + const DWORD c_Costume_Slot_End = c_Costume_Slot_Start + c_Costume_Slot_Count; +#endif + + +// [] (32) ϵڵ . ȥ 32. +// common/length.h EWearPositions 32 Ȯ ϰ(32 ̻ Ȯ ϱ Ǿ.), +// ĺ͸ ȥ . +const DWORD c_Wear_Max = 32; +const DWORD c_DragonSoul_Equip_Start = c_ItemSlot_Count + c_Wear_Max; +const DWORD c_DragonSoul_Equip_Slot_Max = 6; +const DWORD c_DragonSoul_Equip_End = c_DragonSoul_Equip_Start + c_DragonSoul_Equip_Slot_Max * DS_DECK_MAX_NUM; + +// NOTE: 2013 2 5 ... ȥ ũ 2 ϴµ, Ȯ ɼ ־ 3 ũ Ҵ . Ʈ κ丮 +const DWORD c_DragonSoul_Equip_Reserved_Count = c_DragonSoul_Equip_Slot_Max * 3; + +#ifdef ENABLE_NEW_EQUIPMENT_SYSTEM + // Ʈ ϴ κ丮 + const DWORD c_Belt_Inventory_Slot_Start = c_DragonSoul_Equip_End + c_DragonSoul_Equip_Reserved_Count; + const DWORD c_Belt_Inventory_Width = 4; + const DWORD c_Belt_Inventory_Height= 4; + const DWORD c_Belt_Inventory_Slot_Count = c_Belt_Inventory_Width * c_Belt_Inventory_Height; + const DWORD c_Belt_Inventory_Slot_End = c_Belt_Inventory_Slot_Start + c_Belt_Inventory_Slot_Count; + + const DWORD c_Inventory_Count = c_Belt_Inventory_Slot_End; +#else + const DWORD c_Inventory_Count = c_DragonSoul_Equip_End; +#endif + +// ȥ κ丮 +const DWORD c_DragonSoul_Inventory_Start = 0; +const DWORD c_DragonSoul_Inventory_Box_Size = 32; +const DWORD c_DragonSoul_Inventory_Count = CItemData::DS_SLOT_NUM_TYPES * DRAGON_SOUL_GRADE_MAX * c_DragonSoul_Inventory_Box_Size; +const DWORD c_DragonSoul_Inventory_End = c_DragonSoul_Inventory_Start + c_DragonSoul_Inventory_Count; + +enum ESlotType +{ + SLOT_TYPE_NONE, + SLOT_TYPE_INVENTORY, + SLOT_TYPE_SKILL, + SLOT_TYPE_EMOTION, + SLOT_TYPE_SHOP, + SLOT_TYPE_EXCHANGE_OWNER, + SLOT_TYPE_EXCHANGE_TARGET, + SLOT_TYPE_QUICK_SLOT, + SLOT_TYPE_SAFEBOX, + SLOT_TYPE_PRIVATE_SHOP, + SLOT_TYPE_MALL, + SLOT_TYPE_DRAGON_SOUL_INVENTORY, + SLOT_TYPE_MAX, +}; + +enum EWindows +{ + RESERVED_WINDOW, + INVENTORY, // ⺻ κ丮. (45ĭ ¥ 2 = 90ĭ) + EQUIPMENT, + SAFEBOX, + MALL, + DRAGON_SOUL_INVENTORY, + GROUND, // NOTE: 2013 25 unused.. ִ°??? + BELT_INVENTORY, // NOTE: W2.1 ߰Ǵ Ʈ ϴ Ʈ κ丮 + + WINDOW_TYPE_MAX, +}; + +enum EDSInventoryMaxNum +{ + DS_INVENTORY_MAX_NUM = c_DragonSoul_Inventory_Count, + DS_REFINE_WINDOW_MAX_NUM = 15, +}; + +#pragma pack (push, 1) +#define WORD_MAX 0xffff + +typedef struct SItemPos +{ + BYTE window_type; + WORD cell; + SItemPos () + { + window_type = INVENTORY; + cell = WORD_MAX; + } + SItemPos (BYTE _window_type, WORD _cell) + { + window_type = _window_type; + cell = _cell; + } + + // cell BYTE κ, oi + //  κ int,  κ WORD Ǿ־, + // ū ڷ int ޴´. + // int operator=(const int _cell) + // { + //window_type = INVENTORY; + // cell = _cell; + // return cell; + // } + bool IsValidCell() + { + switch (window_type) + { + case INVENTORY: + return cell < c_Inventory_Count; + break; + case EQUIPMENT: + return cell < c_DragonSoul_Equip_End; + break; + case DRAGON_SOUL_INVENTORY: + return cell < (DS_INVENTORY_MAX_NUM); + break; + default: + return false; + } + } + bool IsEquipCell() + { + switch (window_type) + { + case INVENTORY: + case EQUIPMENT: + return (c_Equipment_Start + c_Wear_Max > cell) && (c_Equipment_Start <= cell); + break; + + case BELT_INVENTORY: + case DRAGON_SOUL_INVENTORY: + return false; + break; + + default: + return false; + } + } + +#ifdef ENABLE_NEW_EQUIPMENT_SYSTEM + bool IsBeltInventoryCell() + { + bool bResult = c_Belt_Inventory_Slot_Start <= cell && c_Belt_Inventory_Slot_End > cell; + return bResult; + } +#endif + + bool operator==(const struct SItemPos& rhs) const + { + return (window_type == rhs.window_type) && (cell == rhs.cell); + } + + bool operator<(const struct SItemPos& rhs) const + { + return (window_type < rhs.window_type) || ((window_type == rhs.window_type) && (cell < rhs.cell)); + } +} TItemPos; +#pragma pack(pop) + +const DWORD c_QuickBar_Line_Count = 3; +const DWORD c_QuickBar_Slot_Count = 12; + +const float c_Idle_WaitTime = 5.0f; + +const int c_Monster_Race_Start_Number = 6; +const int c_Monster_Model_Start_Number = 20001; + +const float c_fAttack_Delay_Time = 0.2f; +const float c_fHit_Delay_Time = 0.1f; +const float c_fCrash_Wave_Time = 0.2f; +const float c_fCrash_Wave_Distance = 3.0f; + +const float c_fHeight_Step_Distance = 50.0f; + +enum +{ + DISTANCE_TYPE_FOUR_WAY, + DISTANCE_TYPE_EIGHT_WAY, + DISTANCE_TYPE_ONE_WAY, + DISTANCE_TYPE_MAX_NUM, +}; + +const float c_fMagic_Script_Version = 1.0f; +const float c_fSkill_Script_Version = 1.0f; +const float c_fMagicSoundInformation_Version = 1.0f; +const float c_fBattleCommand_Script_Version = 1.0f; +const float c_fEmotionCommand_Script_Version = 1.0f; +const float c_fActive_Script_Version = 1.0f; +const float c_fPassive_Script_Version = 1.0f; + +// Used by PushMove +const float c_fWalkDistance = 175.0f; +const float c_fRunDistance = 310.0f; + +#define FILE_MAX_LEN 128 + +enum +{ + ITEM_SOCKET_SLOT_MAX_NUM = 3, + ITEM_ATTRIBUTE_SLOT_MAX_NUM = 7, +}; + +#pragma pack(push) +#pragma pack(1) + +typedef struct SQuickSlot +{ + BYTE Type; + BYTE Position; +} TQuickSlot; + +typedef struct TPlayerItemAttribute +{ + BYTE bType; + short sValue; +} TPlayerItemAttribute; + +typedef struct packet_item +{ + DWORD vnum; + BYTE count; + DWORD flags; + DWORD anti_flags; + long alSockets[ITEM_SOCKET_SLOT_MAX_NUM]; + TPlayerItemAttribute aAttr[ITEM_ATTRIBUTE_SLOT_MAX_NUM]; +} TItemData; + +typedef struct packet_shop_item +{ + DWORD vnum; + DWORD price; + BYTE count; + BYTE display_pos; + long alSockets[ITEM_SOCKET_SLOT_MAX_NUM]; + TPlayerItemAttribute aAttr[ITEM_ATTRIBUTE_SLOT_MAX_NUM]; +} TShopItemData; + +#pragma pack(pop) + +inline float GetSqrtDistance(int ix1, int iy1, int ix2, int iy2) // By sqrt +{ + float dx, dy; + + dx = float(ix1 - ix2); + dy = float(iy1 - iy2); + + return sqrtf(dx*dx + dy*dy); +} + +// DEFAULT_FONT +void DefaultFont_Startup(); +void DefaultFont_Cleanup(); +void DefaultFont_SetName(const char * c_szFontName); +CResource* DefaultFont_GetResource(); +CResource* DefaultItalicFont_GetResource(); +// END_OF_DEFAULT_FONT + +void SetGuildSymbolPath(const char * c_szPathName); +const char * GetGuildSymbolFileName(DWORD dwGuildID); +BYTE SlotTypeToInvenType(BYTE bSlotType); diff --git a/source/UserInterface/GuildMarkDownloader.cpp b/source/UserInterface/GuildMarkDownloader.cpp new file mode 100644 index 0000000..8bc2ff4 --- /dev/null +++ b/source/UserInterface/GuildMarkDownloader.cpp @@ -0,0 +1,546 @@ +#include "StdAfx.h" +#include "GuildMarkDownloader.h" +#include "PythonCharacterManager.h" +#include "Packet.h" +#include "Test.h" + +// MARK_BUG_FIX +struct SMarkIndex +{ + WORD guild_id; + WORD mark_id; +}; + +// END_OFMARK_BUG_FIX + +CGuildMarkDownloader::CGuildMarkDownloader() +{ + SetRecvBufferSize(640*1024); + SetSendBufferSize(1024); + __Initialize(); +} + +CGuildMarkDownloader::~CGuildMarkDownloader() +{ + __OfflineState_Set(); +} + +bool CGuildMarkDownloader::Connect(const CNetworkAddress& c_rkNetAddr, DWORD dwHandle, DWORD dwRandomKey) +{ + __OfflineState_Set(); + + m_dwHandle=dwHandle; + m_dwRandomKey=dwRandomKey; + m_dwTodo=TODO_RECV_MARK; + return CNetworkStream::Connect(c_rkNetAddr); +} + +bool CGuildMarkDownloader::ConnectToRecvSymbol(const CNetworkAddress& c_rkNetAddr, DWORD dwHandle, DWORD dwRandomKey, const std::vector & c_rkVec_dwGuildID) +{ + __OfflineState_Set(); + + m_dwHandle=dwHandle; + m_dwRandomKey=dwRandomKey; + m_dwTodo=TODO_RECV_SYMBOL; + m_kVec_dwGuildID = c_rkVec_dwGuildID; + return CNetworkStream::Connect(c_rkNetAddr); +} + +void CGuildMarkDownloader::Process() +{ + CNetworkStream::Process(); + + if (!__StateProcess()) + { + __OfflineState_Set(); + Disconnect(); + } +} + +void CGuildMarkDownloader::OnConnectFailure() +{ + __OfflineState_Set(); +} + +void CGuildMarkDownloader::OnConnectSuccess() +{ + __LoginState_Set(); +} + +void CGuildMarkDownloader::OnRemoteDisconnect() +{ + __OfflineState_Set(); +} + +void CGuildMarkDownloader::OnDisconnect() +{ + __OfflineState_Set(); +} + +void CGuildMarkDownloader::__Initialize() +{ + m_eState=STATE_OFFLINE; + m_pkMarkMgr=NULL; + m_currentRequestingImageIndex=0; + m_dwBlockIndex=0; + m_dwBlockDataPos=0; + m_dwBlockDataSize=0; + + m_dwHandle=0; + m_dwRandomKey=0; + m_dwTodo=TODO_RECV_NONE; + m_kVec_dwGuildID.clear(); +} + +bool CGuildMarkDownloader::__StateProcess() +{ + switch (m_eState) + { + case STATE_LOGIN: + return __LoginState_Process(); + break; + case STATE_COMPLETE: + return false; + } + + return true; +} + +void CGuildMarkDownloader::__OfflineState_Set() +{ + __Initialize(); +} + +void CGuildMarkDownloader::__CompleteState_Set() +{ + m_eState = STATE_COMPLETE; + CPythonCharacterManager::instance().RefreshAllGuildMark(); +} + +void CGuildMarkDownloader::__LoginState_Set() +{ + m_eState = STATE_LOGIN; +} + +bool CGuildMarkDownloader::__LoginState_Process() +{ + BYTE header; + + if (!Peek(sizeof(BYTE), &header)) + return true; + + if (IsSecurityMode()) + { + if (0 == header) + { + if (!Recv(sizeof(header), &header)) + return false; + + return true; + } + } + + UINT needPacketSize = __GetPacketSize(header); + + if (!needPacketSize) + return false; + + if (!Peek(needPacketSize)) + return true; + + __DispatchPacket(header); + return true; +} + +// MARK_BUG_FIX +UINT CGuildMarkDownloader::__GetPacketSize(UINT header) +{ + switch (header) + { + case HEADER_GC_PHASE: + return sizeof(TPacketGCPhase); + case HEADER_GC_HANDSHAKE: + return sizeof(TPacketGCHandshake); + case HEADER_GC_PING: + return sizeof(TPacketGCPing); + case HEADER_GC_MARK_IDXLIST: + return sizeof(TPacketGCMarkIDXList); + case HEADER_GC_MARK_BLOCK: + return sizeof(TPacketGCMarkBlock); + case HEADER_GC_GUILD_SYMBOL_DATA: + return sizeof(TPacketGCGuildSymbolData); + case HEADER_GC_MARK_DIFF_DATA: // + return sizeof(BYTE); +#ifdef _IMPROVED_PACKET_ENCRYPTION_ + case HEADER_GC_KEY_AGREEMENT: + return sizeof(TPacketKeyAgreement); + case HEADER_GC_KEY_AGREEMENT_COMPLETED: + return sizeof(TPacketKeyAgreementCompleted); + +#endif + } + return 0; +} + +bool CGuildMarkDownloader::__DispatchPacket(UINT header) +{ + switch (header) + { + case HEADER_GC_PHASE: + return __LoginState_RecvPhase(); + case HEADER_GC_HANDSHAKE: + return __LoginState_RecvHandshake(); + case HEADER_GC_PING: + return __LoginState_RecvPing(); + case HEADER_GC_MARK_IDXLIST: + return __LoginState_RecvMarkIndex(); + case HEADER_GC_MARK_BLOCK: + return __LoginState_RecvMarkBlock(); + case HEADER_GC_GUILD_SYMBOL_DATA: + return __LoginState_RecvSymbolData(); + case HEADER_GC_MARK_DIFF_DATA: // + return true; +#ifdef _IMPROVED_PACKET_ENCRYPTION_ + case HEADER_GC_KEY_AGREEMENT: + return __LoginState_RecvKeyAgreement(); + case HEADER_GC_KEY_AGREEMENT_COMPLETED: + return __LoginState_RecvKeyAgreementCompleted(); +#endif + } + return false; +} +// END_OF_MARK_BUG_FIX + +bool CGuildMarkDownloader::__LoginState_RecvHandshake() +{ + TPacketGCHandshake kPacketHandshake; + if (!Recv(sizeof(kPacketHandshake), &kPacketHandshake)) + return false; + + TPacketCGMarkLogin kPacketMarkLogin; + + kPacketMarkLogin.header = HEADER_CG_MARK_LOGIN; + kPacketMarkLogin.handle = m_dwHandle; + kPacketMarkLogin.random_key = m_dwRandomKey; + + if (!Send(sizeof(kPacketMarkLogin), &kPacketMarkLogin)) + return false; + + return true; +} + +bool CGuildMarkDownloader::__LoginState_RecvPing() +{ + TPacketGCPing kPacketPing; + + if (!Recv(sizeof(kPacketPing), &kPacketPing)) + return false; + + TPacketCGPong kPacketPong; + kPacketPong.bHeader = HEADER_CG_PONG; + + if (!Send(sizeof(TPacketCGPong), &kPacketPong)) + return false; + + if (IsSecurityMode()) + return SendSequence(); + else + return true; +} + +bool CGuildMarkDownloader::__LoginState_RecvPhase() +{ + TPacketGCPhase kPacketPhase; + + if (!Recv(sizeof(kPacketPhase), &kPacketPhase)) + return false; + + if (kPacketPhase.phase == PHASE_LOGIN) + { +#ifndef _IMPROVED_PACKET_ENCRYPTION_ + const char* key = LocaleService_GetSecurityKey(); + SetSecurityMode(true, key); +#endif + + switch (m_dwTodo) + { + case TODO_RECV_NONE: + { + assert(!"CGuildMarkDownloader::__LoginState_RecvPhase - Todo type is none"); + break; + } + case TODO_RECV_MARK: + { + // MARK_BUG_FIX + if (!__SendMarkIDXList()) + return false; + // END_OF_MARK_BUG_FIX + break; + } + case TODO_RECV_SYMBOL: + { + if (!__SendSymbolCRCList()) + return false; + break; + } + } + } + + return true; +} + +// MARK_BUG_FIX +bool CGuildMarkDownloader::__SendMarkIDXList() +{ + TPacketCGMarkIDXList kPacketMarkIDXList; + kPacketMarkIDXList.header = HEADER_CG_MARK_IDXLIST; + if (!Send(sizeof(kPacketMarkIDXList), &kPacketMarkIDXList)) + return false; + + return true; +} + +bool CGuildMarkDownloader::__LoginState_RecvMarkIndex() +{ + TPacketGCMarkIDXList kPacketMarkIndex; + + if (!Peek(sizeof(kPacketMarkIndex), &kPacketMarkIndex)) + return false; + + //DWORD bufSize = sizeof(WORD) * 2 * kPacketMarkIndex.count; + + if (!Peek(kPacketMarkIndex.bufSize)) + return false; + + Recv(sizeof(kPacketMarkIndex)); + + WORD guildID, markID; + + for (DWORD i = 0; i < kPacketMarkIndex.count; ++i) + { + Recv(sizeof(WORD), &guildID); + Recv(sizeof(WORD), &markID); + + // ID -> ũID ε + CGuildMarkManager::Instance().AddMarkIDByGuildID(guildID, markID); + } + + // ũ ̹ εѴ. ( ) + CGuildMarkManager::Instance().LoadMarkImages(); + + m_currentRequestingImageIndex = 0; + __SendMarkCRCList(); + return true; +} + +bool CGuildMarkDownloader::__SendMarkCRCList() +{ + TPacketCGMarkCRCList kPacketMarkCRCList; + + if (!CGuildMarkManager::Instance().GetBlockCRCList(m_currentRequestingImageIndex, kPacketMarkCRCList.crclist)) + __CompleteState_Set(); + else + { + kPacketMarkCRCList.header = HEADER_CG_MARK_CRCLIST; + kPacketMarkCRCList.imgIdx = m_currentRequestingImageIndex; + ++m_currentRequestingImageIndex; + + if (!Send(sizeof(kPacketMarkCRCList), &kPacketMarkCRCList)) + return false; + } + return true; +} + +bool CGuildMarkDownloader::__LoginState_RecvMarkBlock() +{ + TPacketGCMarkBlock kPacket; + + if (!Peek(sizeof(kPacket), &kPacket)) + return false; + + if (!Peek(kPacket.bufSize)) + return false; + + Recv(sizeof(kPacket)); + + BYTE posBlock; + DWORD compSize; + char compBuf[SGuildMarkBlock::MAX_COMP_SIZE]; + + for (DWORD i = 0; i < kPacket.count; ++i) + { + Recv(sizeof(BYTE), &posBlock); + Recv(sizeof(DWORD), &compSize); + + if (compSize > SGuildMarkBlock::MAX_COMP_SIZE) + { + TraceError("RecvMarkBlock: data corrupted"); + Recv(compSize); + } + else + { + Recv(compSize, compBuf); + // ̹ Ѵ. CRC Բ ȴ. + CGuildMarkManager::Instance().SaveBlockFromCompressedData(kPacket.imgIdx, posBlock, (const BYTE *) compBuf, compSize); + } + } + + if (kPacket.count > 0) + { + // ũ ̹ + CGuildMarkManager::Instance().SaveMarkImage(kPacket.imgIdx); + + // ҽ ε ( ص ΰ ̰ ) + std::string imagePath; + + if (CGuildMarkManager::Instance().GetMarkImageFilename(kPacket.imgIdx, imagePath)) + { + CResource * pResource = CResourceManager::Instance().GetResourcePointer(imagePath.c_str()); + if (pResource->IsType(CGraphicImage::Type())) + { + CGraphicImage* pkGrpImg=static_cast(pResource); + pkGrpImg->Reload(); + } + } + } + + // û ûϰ ƴϸ ̹ ϰ + if (m_currentRequestingImageIndex < CGuildMarkManager::Instance().GetMarkImageCount()) + __SendMarkCRCList(); + else + __CompleteState_Set(); + + return true; +} +// END_OF_MARK_BUG_FIX + +#ifdef _IMPROVED_PACKET_ENCRYPTION_ +bool CGuildMarkDownloader::__LoginState_RecvKeyAgreement() +{ + TPacketKeyAgreement packet; + if (!Recv(sizeof(packet), &packet)) + { + return false; + } + + Tracenf("KEY_AGREEMENT RECV %u", packet.wDataLength); + + TPacketKeyAgreement packetToSend; + size_t dataLength = TPacketKeyAgreement::MAX_DATA_LEN; + size_t agreedLength = Prepare(packetToSend.data, &dataLength); + if (agreedLength == 0) + { + // ʱȭ + Disconnect(); + return false; + } + assert(dataLength <= TPacketKeyAgreement::MAX_DATA_LEN); + + if (Activate(packet.wAgreedLength, packet.data, packet.wDataLength)) + { + // Key agreement , + packetToSend.bHeader = HEADER_CG_KEY_AGREEMENT; + packetToSend.wAgreedLength = (WORD)agreedLength; + packetToSend.wDataLength = (WORD)dataLength; + + if (!Send(sizeof(packetToSend), &packetToSend)) + { + Tracen(" CAccountConnector::__AuthState_RecvKeyAgreement - SendKeyAgreement Error"); + return false; + } + Tracenf("KEY_AGREEMENT SEND %u", packetToSend.wDataLength); + } + else + { + // Ű + Disconnect(); + return false; + } + return true; +} + +bool CGuildMarkDownloader::__LoginState_RecvKeyAgreementCompleted() +{ + TPacketKeyAgreementCompleted packet; + if (!Recv(sizeof(packet), &packet)) + { + return false; + } + + Tracenf("KEY_AGREEMENT_COMPLETED RECV"); + + ActivateCipher(); + + return true; +} +#endif // _IMPROVED_PACKET_ENCRYPTION_ + +bool CGuildMarkDownloader::__SendSymbolCRCList() +{ + for (DWORD i=0; i GetRecvBufferSize()) + return true; + + ////////////////////////////////////////////////////////////// + + TPacketGCGuildSymbolData kPacketSymbolData; + if (!Recv(sizeof(kPacketSymbolData), &kPacketSymbolData)) + return false; + + WORD wDataSize = kPacketSymbolData.size - sizeof(kPacketSymbolData); + DWORD dwGuildID = kPacketSymbolData.guild_id; + BYTE * pbyBuf = new BYTE [wDataSize]; + + if (!Recv(wDataSize, pbyBuf)) + { + delete[] pbyBuf; + return false; + } + + MyCreateDirectory(g_strGuildSymbolPathName.c_str()); + + std::string strFileName = GetGuildSymbolFileName(dwGuildID); + + FILE * File = fopen(strFileName.c_str(), "wb"); + if (!File) + { + delete[] pbyBuf; + return false; + } + fwrite(pbyBuf, wDataSize, 1, File); + fclose(File); + +#ifdef _DEBUG + printf("__LoginState_RecvSymbolData(filename:%s, datasize:%d, guildid:%d)\n", strFileName.c_str(), wDataSize, dwGuildID); +#endif + + delete[] pbyBuf; + return true; +} diff --git a/source/UserInterface/GuildMarkDownloader.h b/source/UserInterface/GuildMarkDownloader.h new file mode 100644 index 0000000..5719352 --- /dev/null +++ b/source/UserInterface/GuildMarkDownloader.h @@ -0,0 +1,79 @@ +#pragma once + +#include "../EterLib/NetStream.h" +#include "MarkManager.h" + +class CGuildMarkDownloader : public CNetworkStream, public CSingleton +{ + public: + CGuildMarkDownloader(); + virtual ~CGuildMarkDownloader(); + + bool Connect(const CNetworkAddress& c_rkNetAddr, DWORD dwHandle, DWORD dwRandomKey); + bool ConnectToRecvSymbol(const CNetworkAddress& c_rkNetAddr, DWORD dwHandle, DWORD dwRandomKey, const std::vector & c_rkVec_dwGuildID); + + void Process(); + + private: + enum + { + STATE_OFFLINE, + STATE_LOGIN, + STATE_COMPLETE, + }; + + enum + { + TODO_RECV_NONE, + TODO_RECV_MARK, + TODO_RECV_SYMBOL, + }; + + private: + void OnConnectFailure(); + void OnConnectSuccess(); + void OnRemoteDisconnect(); + void OnDisconnect(); + + void __Initialize(); + bool __StateProcess(); + + UINT __GetPacketSize(UINT header); + bool __DispatchPacket(UINT header); + + void __OfflineState_Set(); + void __CompleteState_Set(); + + void __LoginState_Set(); + bool __LoginState_Process(); + bool __LoginState_RecvPhase(); + bool __LoginState_RecvHandshake(); + bool __LoginState_RecvPing(); + bool __LoginState_RecvMarkIndex(); + bool __LoginState_RecvMarkBlock(); + bool __LoginState_RecvSymbolData(); +#ifdef _IMPROVED_PACKET_ENCRYPTION_ + bool __LoginState_RecvKeyAgreement(); + bool __LoginState_RecvKeyAgreementCompleted(); +#endif + bool __SendMarkIDXList(); + bool __SendMarkCRCList(); + bool __SendSymbolCRCList(); + + private: + DWORD m_dwHandle; + DWORD m_dwRandomKey; + DWORD m_dwTodo; + + std::vector m_kVec_dwGuildID; + + UINT m_eState; + + BYTE m_currentRequestingImageIndex; + + CGuildMarkManager * m_pkMarkMgr; + + DWORD m_dwBlockIndex; + DWORD m_dwBlockDataSize; + DWORD m_dwBlockDataPos; +}; diff --git a/source/UserInterface/GuildMarkUploader.cpp b/source/UserInterface/GuildMarkUploader.cpp new file mode 100644 index 0000000..ce19c7f --- /dev/null +++ b/source/UserInterface/GuildMarkUploader.cpp @@ -0,0 +1,482 @@ +#include "StdAfx.h" +#include "GuildMarkUploader.h" +#include "Packet.h" +#include "Test.h" + +#ifdef __VTUNE__ +#else + +CGuildMarkUploader::CGuildMarkUploader() + : m_pbySymbolBuf(NULL) +{ + SetRecvBufferSize(1024); + SetSendBufferSize(1024); + __Inialize(); +} + +CGuildMarkUploader::~CGuildMarkUploader() +{ + __OfflineState_Set(); +} + +void CGuildMarkUploader::Disconnect() +{ + __OfflineState_Set(); +} + +bool CGuildMarkUploader::IsCompleteUploading() +{ + return STATE_OFFLINE == m_eState; +} + +bool CGuildMarkUploader::__Save(const char* c_szFileName) +{ + /* δ ʾƾ ; + ILuint uImg; + ilGenImages(1, &uImg); + ilBindImage(uImg); + ilEnable(IL_FILE_OVERWRITE); + ilEnable(IL_ORIGIN_SET); + ilOriginFunc(IL_ORIGIN_UPPER_LEFT); + + if (!ilLoad(IL_TYPE_UNKNOWN, (const ILstring)c_szFileName)) + { + return false; + } + + if (ilGetInteger(IL_IMAGE_WIDTH) != CGuildMarkImage::WIDTH) + { + return false; + } + + if (ilGetInteger(IL_IMAGE_HEIGHT) != CGuildMarkImage::HEIGHT) + { + return false; + } + + ilConvertImage(IL_BGRA, IL_BYTE); + + UINT uColCount = CGuildMarkImage::MARK_COL_COUNT; + UINT uCol = m_dwGuildID % uColCount; + UINT uRow = m_dwGuildID / uColCount; + + ilSetPixels(uCol*SGuildMark::WIDTH, uRow*SGuildMark::HEIGHT, 0, SGuildMark::WIDTH, SGuildMark::HEIGHT, 1, IL_BGRA, IL_BYTE, (ILvoid*)m_kMark.m_apxBuf); + + ilSave(IL_TGA, (ILstring)c_szFileName); + + ilDeleteImages(1, &uImg); + */ + return true; +} + +bool CGuildMarkUploader::__Load(const char* c_szFileName, UINT* peError) +{ + ILuint uImg; + ilGenImages(1, &uImg); + ilBindImage(uImg); + ilEnable(IL_ORIGIN_SET); + ilOriginFunc(IL_ORIGIN_UPPER_LEFT); + + if (!ilLoad(IL_TYPE_UNKNOWN, (const ILstring)c_szFileName)) + { + *peError=ERROR_LOAD; + return false; + } + + if (ilGetInteger(IL_IMAGE_WIDTH)!=SGuildMark::WIDTH) + { + *peError=ERROR_WIDTH; + return false; + } + + if (ilGetInteger(IL_IMAGE_HEIGHT)!=SGuildMark::HEIGHT) + { + *peError=ERROR_HEIGHT; + return false; + } + + ilConvertImage(IL_BGRA, IL_BYTE); + + ilCopyPixels(0, 0, 0, SGuildMark::WIDTH, SGuildMark::HEIGHT, 1, IL_BGRA, IL_BYTE, (ILvoid*)m_kMark.m_apxBuf); + + ilDeleteImages(1, &uImg); + return true; +} + +bool CGuildMarkUploader::__LoadSymbol(const char* c_szFileName, UINT* peError) +{ + // For Check Image + ILuint uImg; + ilGenImages(1, &uImg); + ilBindImage(uImg); + ilEnable(IL_ORIGIN_SET); + ilOriginFunc(IL_ORIGIN_UPPER_LEFT); + if (!ilLoad(IL_TYPE_UNKNOWN, (const ILstring)c_szFileName)) + { + *peError=ERROR_LOAD; + return false; + } + if (ilGetInteger(IL_IMAGE_WIDTH) != 64) + { + *peError=ERROR_WIDTH; + return false; + } + if (ilGetInteger(IL_IMAGE_HEIGHT) != 128) + { + *peError=ERROR_HEIGHT; + return false; + } + ilDeleteImages(1, &uImg); + ilShutDown(); + + ///// + + FILE * file = fopen(c_szFileName, "rb"); + if (!file) + { + *peError=ERROR_LOAD; + } + + fseek(file, 0, SEEK_END); + m_dwSymbolBufSize = ftell(file); + fseek(file, 0, SEEK_SET); + + m_pbySymbolBuf = new BYTE [m_dwSymbolBufSize]; + fread(m_pbySymbolBuf, m_dwSymbolBufSize, 1, file); + + fclose(file); + + ///// + + m_dwSymbolCRC32 = GetFileCRC32(c_szFileName); + return true; +} + +bool CGuildMarkUploader::Connect(const CNetworkAddress& c_rkNetAddr, DWORD dwHandle, DWORD dwRandomKey, DWORD dwGuildID, const char* c_szFileName, UINT* peError) +{ + __OfflineState_Set(); + SetRecvBufferSize(1024); + SetSendBufferSize(1024); + + if (!CNetworkStream::Connect(c_rkNetAddr)) + { + *peError=ERROR_CONNECT; + return false; + } + + m_dwSendType=SEND_TYPE_MARK; + m_dwHandle=dwHandle; + m_dwRandomKey=dwRandomKey; + m_dwGuildID=dwGuildID; + + if (!__Load(c_szFileName, peError)) + return false; + + //if (!__Save(CGraphicMarkInstance::GetImageFileName().c_str())) + // return false; + //CGraphicMarkInstance::ReloadImageFile(); + return true; +} + +bool CGuildMarkUploader::ConnectToSendSymbol(const CNetworkAddress& c_rkNetAddr, DWORD dwHandle, DWORD dwRandomKey, DWORD dwGuildID, const char* c_szFileName, UINT* peError) +{ + __OfflineState_Set(); + SetRecvBufferSize(1024); + SetSendBufferSize(64*1024); + + if (!CNetworkStream::Connect(c_rkNetAddr)) + { + *peError=ERROR_CONNECT; + return false; + } + + m_dwSendType=SEND_TYPE_SYMBOL; + m_dwHandle=dwHandle; + m_dwRandomKey=dwRandomKey; + m_dwGuildID=dwGuildID; + + if (!__LoadSymbol(c_szFileName, peError)) + return false; + + return true; +} + +void CGuildMarkUploader::Process() +{ + CNetworkStream::Process(); + + if (!__StateProcess()) + { + __OfflineState_Set(); + Disconnect(); + } +} + +void CGuildMarkUploader::OnConnectFailure() +{ + __OfflineState_Set(); +} + +void CGuildMarkUploader::OnConnectSuccess() +{ + __LoginState_Set(); +} + +void CGuildMarkUploader::OnRemoteDisconnect() +{ + __OfflineState_Set(); +} + +void CGuildMarkUploader::OnDisconnect() +{ + __OfflineState_Set(); +} + +void CGuildMarkUploader::__Inialize() +{ + m_eState = STATE_OFFLINE; + + m_dwGuildID = 0; + m_dwHandle = 0; + m_dwRandomKey = 0; + + if (m_pbySymbolBuf) + { + delete m_pbySymbolBuf; + } + + m_dwSymbolBufSize = 0; + m_pbySymbolBuf = NULL; +} + +bool CGuildMarkUploader::__StateProcess() +{ + switch (m_eState) + { + case STATE_LOGIN: + return __LoginState_Process(); + break; + } + + return true; +} + +void CGuildMarkUploader::__OfflineState_Set() +{ + __Inialize(); +} + +void CGuildMarkUploader::__CompleteState_Set() +{ + m_eState=STATE_COMPLETE; + + __OfflineState_Set(); +} + + +void CGuildMarkUploader::__LoginState_Set() +{ + m_eState=STATE_LOGIN; +} + +bool CGuildMarkUploader::__LoginState_Process() +{ + if (!__AnalyzePacket(HEADER_GC_PHASE, sizeof(TPacketGCPhase), &CGuildMarkUploader::__LoginState_RecvPhase)) + return false; + + if (!__AnalyzePacket(HEADER_GC_HANDSHAKE, sizeof(TPacketGCHandshake), &CGuildMarkUploader::__LoginState_RecvHandshake)) + return false; + + if (!__AnalyzePacket(HEADER_GC_PING, sizeof(TPacketGCPing), &CGuildMarkUploader::__LoginState_RecvPing)) + return false; + +#ifdef _IMPROVED_PACKET_ENCRYPTION_ + if (!__AnalyzePacket(HEADER_GC_KEY_AGREEMENT, sizeof(TPacketKeyAgreement), &CGuildMarkUploader::__LoginState_RecvKeyAgreement)) + return false; + + if (!__AnalyzePacket(HEADER_GC_KEY_AGREEMENT_COMPLETED, sizeof(TPacketKeyAgreementCompleted), &CGuildMarkUploader::__LoginState_RecvKeyAgreementCompleted)) + return false; +#endif + + return true; +} + +bool CGuildMarkUploader::__SendMarkPacket() +{ + TPacketCGMarkUpload kPacketMarkUpload; + kPacketMarkUpload.header=HEADER_CG_MARK_UPLOAD; + kPacketMarkUpload.gid=m_dwGuildID; + + assert(sizeof(kPacketMarkUpload.image) == sizeof(m_kMark.m_apxBuf)); + memcpy(kPacketMarkUpload.image, m_kMark.m_apxBuf, sizeof(kPacketMarkUpload.image)); + + if (!Send(sizeof(kPacketMarkUpload), &kPacketMarkUpload)) + return false; + + return true; +} +bool CGuildMarkUploader::__SendSymbolPacket() +{ + if (!m_pbySymbolBuf) + return false; + + TPacketCGSymbolUpload kPacketSymbolUpload; + kPacketSymbolUpload.header=HEADER_CG_GUILD_SYMBOL_UPLOAD; + kPacketSymbolUpload.handle=m_dwGuildID; + kPacketSymbolUpload.size=sizeof(TPacketCGSymbolUpload) + m_dwSymbolBufSize; + + if (!Send(sizeof(TPacketCGSymbolUpload), &kPacketSymbolUpload)) + return false; + if (!Send(m_dwSymbolBufSize, m_pbySymbolBuf)) + return false; + +#ifdef _DEBUG + printf("__SendSymbolPacket : [GuildID:%d/PacketSize:%d/BufSize:%d/CRC:%d]\n", m_dwGuildID, kPacketSymbolUpload.size, m_dwSymbolBufSize, m_dwSymbolCRC32); +#endif + + CNetworkStream::__SendInternalBuffer(); + __CompleteState_Set(); + + return true; +} + +bool CGuildMarkUploader::__LoginState_RecvPhase() +{ + TPacketGCPhase kPacketPhase; + if (!Recv(sizeof(kPacketPhase), &kPacketPhase)) + return false; + + if (kPacketPhase.phase==PHASE_LOGIN) + { +#ifndef _IMPROVED_PACKET_ENCRYPTION_ + const char* key = LocaleService_GetSecurityKey(); + SetSecurityMode(true, key); +#endif + + if (SEND_TYPE_MARK == m_dwSendType) + { + if (!__SendMarkPacket()) + return false; + } + else if (SEND_TYPE_SYMBOL == m_dwSendType) + { + if (!__SendSymbolPacket()) + return false; + } + } + + return true; +} + +bool CGuildMarkUploader::__LoginState_RecvHandshake() +{ + TPacketGCHandshake kPacketHandshake; + if (!Recv(sizeof(kPacketHandshake), &kPacketHandshake)) + return false; + + { + TPacketCGMarkLogin kPacketMarkLogin; + kPacketMarkLogin.header=HEADER_CG_MARK_LOGIN; + kPacketMarkLogin.handle=m_dwHandle; + kPacketMarkLogin.random_key=m_dwRandomKey; + if (!Send(sizeof(kPacketMarkLogin), &kPacketMarkLogin)) + return false; + } + + return true; +} + +bool CGuildMarkUploader::__LoginState_RecvPing() +{ + TPacketGCPing kPacketPing; + if (!Recv(sizeof(kPacketPing), &kPacketPing)) + return false; + + TPacketCGPong kPacketPong; + kPacketPong.bHeader = HEADER_CG_PONG; + + if (!Send(sizeof(TPacketCGPong), &kPacketPong)) + return false; + + if (IsSecurityMode()) + return SendSequence(); + else + return true; +} + +#ifdef _IMPROVED_PACKET_ENCRYPTION_ +bool CGuildMarkUploader::__LoginState_RecvKeyAgreement() +{ + TPacketKeyAgreement packet; + if (!Recv(sizeof(packet), &packet)) + { + return false; + } + + Tracenf("KEY_AGREEMENT RECV %u", packet.wDataLength); + + TPacketKeyAgreement packetToSend; + size_t dataLength = TPacketKeyAgreement::MAX_DATA_LEN; + size_t agreedLength = Prepare(packetToSend.data, &dataLength); + if (agreedLength == 0) + { + // ʱȭ + Disconnect(); + return false; + } + assert(dataLength <= TPacketKeyAgreement::MAX_DATA_LEN); + + if (Activate(packet.wAgreedLength, packet.data, packet.wDataLength)) + { + // Key agreement , + packetToSend.bHeader = HEADER_CG_KEY_AGREEMENT; + packetToSend.wAgreedLength = (WORD)agreedLength; + packetToSend.wDataLength = (WORD)dataLength; + + if (!Send(sizeof(packetToSend), &packetToSend)) + { + Tracen(" CAccountConnector::__AuthState_RecvKeyAgreement - SendKeyAgreement Error"); + return false; + } + Tracenf("KEY_AGREEMENT SEND %u", packetToSend.wDataLength); + } + else + { + // Ű + Disconnect(); + return false; + } + return true; +} + +bool CGuildMarkUploader::__LoginState_RecvKeyAgreementCompleted() +{ + TPacketKeyAgreementCompleted packet; + if (!Recv(sizeof(packet), &packet)) + { + return false; + } + + Tracenf("KEY_AGREEMENT_COMPLETED RECV"); + + ActivateCipher(); + + return true; +} +#endif // _IMPROVED_PACKET_ENCRYPTION_ + +bool CGuildMarkUploader::__AnalyzePacket(UINT uHeader, UINT uPacketSize, bool (CGuildMarkUploader::*pfnDispatchPacket)()) +{ + BYTE bHeader; + if (!Peek(sizeof(bHeader), &bHeader)) + return true; + + if (bHeader!=uHeader) + return true; + + if (!Peek(uPacketSize)) + return true; + + return (this->*pfnDispatchPacket)(); +} +#endif diff --git a/source/UserInterface/GuildMarkUploader.h b/source/UserInterface/GuildMarkUploader.h new file mode 100644 index 0000000..1068c03 --- /dev/null +++ b/source/UserInterface/GuildMarkUploader.h @@ -0,0 +1,118 @@ +#pragma once + +#include "../EterLib/NetStream.h" +#include "MarkImage.h" + +#ifdef __VTUNE__ + +class CGuildMarkUploader : public CNetworkStream, public CSingleton +{ + public: + enum + { + ERROR_NONE, + ERROR_CONNECT, + ERROR_LOAD, + ERROR_WIDTH, + ERROR_HEIGHT, + }; + + public: + CGuildMarkUploader() {} + virtual ~CGuildMarkUploader() {} + + void Disconnect() {} + bool Connect(const CNetworkAddress& c_rkNetAddr, DWORD dwHandle, DWORD dwRandomKey, DWORD dwGuildID, const char* c_szFileName, UINT* peError) {return false;} + bool ConnectToSendSymbol(const CNetworkAddress& c_rkNetAddr, DWORD dwHandle, DWORD dwRandomKey, DWORD dwGuildID, const char* c_szFileName, UINT* peError) {return false;} + void Process() {} +}; + +#else + +#include + +class CGuildMarkUploader : public CNetworkStream, public CSingleton +{ + public: + enum + { + ERROR_NONE, + ERROR_CONNECT, + ERROR_LOAD, + ERROR_WIDTH, + ERROR_HEIGHT, + }; + + enum + { + SEND_TYPE_MARK, + SEND_TYPE_SYMBOL, + }; + + public: + CGuildMarkUploader(); + virtual ~CGuildMarkUploader(); + + void Disconnect(); + bool Connect(const CNetworkAddress& c_rkNetAddr, DWORD dwHandle, DWORD dwRandomKey, DWORD dwGuildID, const char* c_szFileName, UINT* peError); + bool ConnectToSendSymbol(const CNetworkAddress& c_rkNetAddr, DWORD dwHandle, DWORD dwRandomKey, DWORD dwGuildID, const char* c_szFileName, UINT* peError); + bool IsCompleteUploading(); + + void Process(); + + private: + enum + { + STATE_OFFLINE, + STATE_LOGIN, + STATE_COMPLETE, + }; + + private: + void OnConnectFailure(); + void OnConnectSuccess(); + void OnRemoteDisconnect(); + void OnDisconnect(); + + bool __Load(const char* c_szFileName, UINT* peError); + bool __LoadSymbol(const char* c_szFileName, UINT* peError); + + bool __Save(const char* c_szFileName); + + void __Inialize(); + bool __StateProcess(); + + void __OfflineState_Set(); + void __CompleteState_Set(); + + void __LoginState_Set(); + bool __LoginState_Process(); + bool __LoginState_RecvPhase(); + bool __LoginState_RecvHandshake(); + bool __LoginState_RecvPing(); +#ifdef _IMPROVED_PACKET_ENCRYPTION_ + bool __LoginState_RecvKeyAgreement(); + bool __LoginState_RecvKeyAgreementCompleted(); +#endif + + bool __AnalyzePacket(UINT uHeader, UINT uPacketSize, bool (CGuildMarkUploader::*pfnDispatchPacket)()); + + bool __SendMarkPacket(); + bool __SendSymbolPacket(); + + private: + UINT m_eState; + + DWORD m_dwSendType; + DWORD m_dwHandle; + DWORD m_dwRandomKey; + DWORD m_dwGuildID; + + SGuildMark m_kMark; + + DWORD m_dwSymbolBufSize; + DWORD m_dwSymbolCRC32; + BYTE * m_pbySymbolBuf; +}; + +#endif \ No newline at end of file diff --git a/source/UserInterface/HackShield.cpp b/source/UserInterface/HackShield.cpp new file mode 100644 index 0000000..8db43ce --- /dev/null +++ b/source/UserInterface/HackShield.cpp @@ -0,0 +1,380 @@ +#include "StdAfx.h" +#include "Hackshield.h" + +#ifdef USE_AHNLAB_HACKSHIELD + +#if defined(LOCALE_SERVICE_EUROPE) +#define METIN2HS_MONITORING_SERVER_ADDR "79.110.88.84" +#elif +#define METIN2HS_MONITORING_SERVER_ADDR "79.110.88.84" // GF +#endif +//#define METIN2HS_MONITORING_SERVER_ADDR "119.192.130.160" // pc + +#include METIN2HS_INCLUDE_HSUPCHK +#include METIN2HS_INCLUDE_HSUSERUTIL +#include METIN2HS_INCLUDE_HSHIELD +#include METIN2HS_INCLUDE_HSHIELDLIBLINK + +#define MA_MAX_PATH MAX_PATH +#define MA_T +#define MA_TCHAR char +#define MA_StringFormat snprintf +#define MA_ARRAYCOUNT sizeof + +static DWORD gs_dwMainThreadID = 0; + +static bool gs_isHackDetected = false; +static char gs_szHackMsg[256]; + +void MA_PathSplit(MA_TCHAR* src, MA_TCHAR* branch, size_t branchLen, MA_TCHAR* leaf, size_t leafLen) +{ + char* p = src; + char* n = p; + while (n = strchr(p, '\\')) + p = n + 1; + + if (branch) + strncpy(branch, src, p - src); + + if (leaf) + strcpy(leaf, p); +} + +void MA_PathMerge(MA_TCHAR* dst, size_t dstLen, MA_TCHAR* branch, MA_TCHAR* leaf) +{ + snprintf(dst, dstLen, "%s\\%s", branch, leaf); +} + +int __stdcall AhnHS_Callback(long lCode, long lParamSize, void* pParam) +{ + switch (lCode) + { + //Engine Callback + case AHNHS_ENGINE_DETECT_GAME_HACK: + { + MA_StringFormat(gs_szHackMsg, MA_ARRAYCOUNT(gs_szHackMsg), MA_T("DETECT_GAME_HACK\n%s"), (char*)pParam); + gs_isHackDetected = true; + break; + } + //â ŷ + case AHNHS_ENGINE_DETECT_WINDOWED_HACK: + { + //MA_StringFormat(gs_szHackMsg, MA_ARRAYCOUNT(gs_szHackMsg), MA_T("DETECT_WINDOWED_HACK")); + //gs_isHackDetected = true; + break; + } + + //Speed + case AHNHS_ACTAPC_DETECT_SPEEDHACK: + { + MA_StringFormat(gs_szHackMsg, MA_ARRAYCOUNT(gs_szHackMsg), MA_T("DETECT_SPEED_HACK")); + gs_isHackDetected = true; + break; + } + + // + case AHNHS_ACTAPC_DETECT_KDTRACE: +// case AHNHS_ACTAPC_DETECT_KDTRACE_CHANGED: + { + MA_StringFormat(gs_szHackMsg, MA_ARRAYCOUNT(gs_szHackMsg), MA_T("DETECT_DEBUGING(checkCode=%x)"), lCode); + gs_isHackDetected = true; + break; + } + + case AHNHS_ACTAPC_DETECT_AUTOMACRO: + { + MA_StringFormat(gs_szHackMsg, MA_ARRAYCOUNT(gs_szHackMsg), MA_T("DETECT_MACRO(checkCode=%x)"), lCode); + gs_isHackDetected = true; + break; + } + + // ڵ ġ + case AHNHS_ACTAPC_DETECT_ABNORMAL_MEMORY_ACCESS: + { + MA_StringFormat(gs_szHackMsg, MA_ARRAYCOUNT(gs_szHackMsg), MA_T("DETECT_MEMORY_ACCESS\n%s"), (char*)pParam); + gs_isHackDetected = true; + break; + } + + //޸ . + case AHNHS_ACTAPC_DETECT_MEM_MODIFY_FROM_LMP: // ּ (Randomized Base Address) Ȯغ. Linker->Advanced->(/DYNAMICBASE:NO) + { + MA_StringFormat(gs_szHackMsg, MA_ARRAYCOUNT(gs_szHackMsg), MA_T("DETECT_MEMORY_MODIFY")); + gs_isHackDetected = true; + + } + break; + + // ٽ ޸ ȣ ʽϴ. + case AHNHS_ACTAPC_DETECT_LMP_FAILED: + { + MA_StringFormat(gs_szHackMsg, MA_ARRAYCOUNT(gs_szHackMsg), MA_T("LOCAL_MEMORY_PROTECT_FAILED")); + gs_isHackDetected = true; + + } + break; + + //׿ ŷ ̻ +// case AHNHS_ACTAPC_DETECT_AUTOMOUSE: + case AHNHS_ACTAPC_DETECT_DRIVERFAILED: + case AHNHS_ACTAPC_DETECT_HOOKFUNCTION: +// case AHNHS_ACTAPC_DETECT_MESSAGEHOOK: +// case AHNHS_ACTAPC_DETECT_MODULE_CHANGE: + case AHNHS_ACTAPC_DETECT_ENGINEFAILED: + case AHNHS_ACTAPC_DETECT_CODEMISMATCH: +// case AHNHS_ACTAPC_DETECT_PROTECTSCREENFAILED: + { + MA_StringFormat(gs_szHackMsg, MA_ARRAYCOUNT(gs_szHackMsg), MA_T("DETECT_HACKING(checkCode = %x)\n"), lCode); + gs_isHackDetected = true; + break; + } + } + return 1; +} + +bool HackShield_PollEvent() +{ + return gs_isHackDetected; + //return false; +} + +bool HackShield_Init() +{ + + MA_TCHAR szModuleDirPath[MA_MAX_PATH]; + ::GetCurrentDirectory(MA_ARRAYCOUNT(szModuleDirPath), szModuleDirPath); + +#ifndef _DEBUG + //ٽ Ʈ + DWORD dwUpRet = 0; + MA_TCHAR szFullFilePath[MA_MAX_PATH]; + // ٽ ġ մϴ. + MA_PathMerge(szFullFilePath, MA_ARRAYCOUNT(szFullFilePath), szModuleDirPath, "hshield"); + AHNHS_EXT_ERRORINFO HsExtError = {0,}; + + // _AhnHS_HSUpdate Լ ȣ + dwUpRet = _AhnHS_HSUpdateEx( szFullFilePath, // ٽ + 1000 * 600, // Ʈ ü Ÿ ƿ + METIN2HS_CODE, // ڵ + AHNHSUPDATE_CHKOPT_HOSTFILE| AHNHSUPDATE_CHKOPT_GAMECODE, + HsExtError, + 1000* 20 ); // ŸӾƿ + + // Ex Լ ϽǶ ݵ HSUpSetEnv.exe env Ͽ + // ڵ带 Էϼž մϴ. + if ( dwUpRet != ERROR_SUCCESS) + { + + // ó + switch ( dwUpRet ) + { + case HSERROR_ENVFILE_NOTREAD: + MessageBox(NULL, MA_T("HACK_SHIELD_UPDATE_ERROR : HSERROR_ENVFILE_NOTREAD"), "HACK_SHIELD", MB_OK); + break; + case HSERROR_ENVFILE_NOTWRITE: + MessageBox(NULL, MA_T("HACK_SHIELD_UPDATE_ERROR : HSERROR_ENVFILE_NOTWRITE"), "HACK_SHIELD", MB_OK); + break; + case HSERROR_NETWORK_CONNECT_FAIL: + MessageBox(NULL, MA_T("HACK_SHIELD_UPDATE_ERROR : HSERROR_NETWORK_CONNECT_FAIL"), "HACK_SHIELD", MB_OK); + break; + case HSERROR_HSUPDATE_TIMEOUT: + MessageBox(NULL, MA_T("HACK_SHIELD_UPDATE_ERROR : HSERROR_HSUPDATE_TIMEOUT"), "HACK_SHIELD", MB_OK); + break; + case HSERROR_MISMATCH_ENVFILE: + MessageBox(NULL, MA_T("HACK_SHIELD_UPDATE_ERROR : HSERROR_MISMATCH_ENVFILE"), "HACK_SHIELD", MB_OK); + break; + case HSERROR_HOSTFILE_MODIFICATION: + MessageBox(NULL, MA_T("HACK_SHIELD_UPDATE_ERROR : HSERROR_HOSTFILE_MODIFICATION"), "HACK_SHIELD", MB_OK); + break; + default: + break; + } + + MessageBox(NULL, MA_T("HACK_SHIELD_UPDATE_ERROR"), "HACK_SHIELD", MB_OK); + + return false; + + } +#endif + + MA_TCHAR szInterfaceFilePath[MA_MAX_PATH]; + { + if (!_AhnHSUserUtil_IsAdmin() && !_AhnHsUserUtil_IsEnableHSAdminRights()) + { + DWORD dwRet = _AhnHsUserUtil_CreateUser(); + switch (dwRet) + { + case HSUSERUTIL_ERR_OK: // pass + break; + case HSUSERUTIL_ERR_NOT_ADMIN: // ϹǷ ƴ + break; + case HSUSERUTIL_ERR_NOT_NT: // 98 ϹǷ ƴ + break; + case HSUSERUTIL_ERR_DELHIDEIDINFO_FAIL: + MessageBox(NULL, MA_T("DEL_SHADOW_HIDDEN_ERROR"), "HACK_SHIELD", MB_OK); + return false; + case HSUSERUTIL_ERR_DELSHADOWACNT_FAIL: + MessageBox(NULL, MA_T("DEL_SHADOW_ACCOUNT_ERROR"), "HACK_SHIELD", MB_OK); + return false; + case HSUSERUTIL_ERR_ADDSHADOWACNT_FAIL: + MessageBox(NULL, MA_T("ADD_SHADOW_ACCOUNT_ERROR"), "HACK_SHIELD", MB_OK); + return false; + } + + } + +#ifdef _DEBUG + MA_PathMerge(szInterfaceFilePath, MA_ARRAYCOUNT(szInterfaceFilePath), szModuleDirPath, "hshield\\EHsvc.dll"); +#else + MA_PathMerge(szInterfaceFilePath, MA_ARRAYCOUNT(szInterfaceFilePath), szModuleDirPath, "hshield\\EHsvc.dll"); +#endif + } + +#ifndef _DEBUG + { + AHNHS_EXT_ERRORINFO HsExtError = { 0, }; + strcpy(HsExtError.szServer, METIN2HS_MONITORING_SERVER_ADDR); //͸ ּ + strcpy(HsExtError.szGameVersion, "1.0.0.0"); //Game + strcpy(HsExtError.szUserId, "Metin2User_test"); // ID + + DWORD dwRet = _AhnHS_StartMonitor (HsExtError, szInterfaceFilePath); + if( dwRet != ERROR_SUCCESS ) + { + MessageBox(NULL, MA_T("START_MONITORING_SERVICE_ERROR"), "HACK_SHIELD", MB_OK); + } + } +#endif + + { + int nRet = _AhnHS_Initialize(szInterfaceFilePath, AhnHS_Callback, + METIN2HS_CODE, + METIN2HS_LICENSE, + AHNHS_CHKOPT_SPEEDHACK + | AHNHS_CHKOPT_READWRITEPROCESSMEMORY + | AHNHS_CHKOPT_KDTRACER +// | AHNHS_CHKOPT_OPENPROCESS + | AHNHS_CHKOPT_AUTOMOUSE + | AHNHS_CHKOPT_MESSAGEHOOK + | AHNHS_CHKOPT_PROTECT_D3DX + | AHNHS_CHKOPT_LOCAL_MEMORY_PROTECTION // ڵ ε ȣ + //| AHNHS_CHKOPT_ANTIFREESERVER // + | AHNHS_USE_LOG_FILE +// | AHNHS_ALLOW_SVCHOST_OPENPROCESS + //| AHNHS_ALLOW_LSASS_OPENPROCESS // ſ ī + //| AHNHS_ALLOW_CSRSS_OPENPROCESS // ſ ī + //| AHNHS_CHKOPT_SELF_DESTRUCTION // ó: ݹ ó + | AHNHS_CHKOPT_PROCESSSCAN + | AHNHS_CHKOPT_UPDATED_FILE_CHECK + | AHNHS_CHKOPT_SEND_MONITOR_ONCE // ͸: 1ȸ + | AHNHS_CHKOPT_SEND_MONITOR_DELAY // ͸: ̵ õõ + | AHNHS_DONOT_TERMINATE_PROCESS, // ˸ + AHNHS_SPEEDHACK_SENSING_RATIO_NORMAL + ); + + if (nRet != HS_ERR_OK) + { + //Error ó + switch(nRet) + { + case HS_ERR_ANOTHER_SERVICE_RUNNING: + { + MessageBox(NULL, MA_T("ANOTHER_SERVICE_RUNNING"), "HACK_SHIELD", MB_OK); + break; + } + case HS_ERR_INVALID_LICENSE: + { + MessageBox(NULL, MA_T("INVALID_LICENSE"), "HACK_SHIELD", MB_OK); + break; + } + case HS_ERR_INVALID_FILES: + { + MessageBox(NULL, MA_T("INVALID_FILES"), "HACK_SHIELD", MB_OK); + break; + } + case HS_ERR_DEBUGGER_DETECT: + { + MessageBox(NULL, MA_T("DEBUG_DETECT"), "HACK_SHIELD", MB_OK); + break; + } + case HS_ERR_NEED_ADMIN_RIGHTS: + { + MessageBox(NULL, MA_T("NEED_ADMIN_RIGHTS"), "HACK_SHIELD", MB_OK); + break; + } + case HS_ERR_COMPATIBILITY_MODE_RUNNING: + { + MessageBox(NULL, MA_T("COMPATIBILITY_MODE_RUNNING"), "HACK_SHIELD", MB_OK); + break; + } + default: + { + MA_TCHAR szMsg[255]; + MA_StringFormat(szMsg, MA_ARRAYCOUNT(szMsg), MA_T("UNKNOWN_ERROR(errorCode=%x)"), nRet); + MessageBox(NULL, szMsg, "HACK_SHIELD", MB_OK); + break; + } + } + return false; + } + } + + gs_dwMainThreadID = GetCurrentThreadId(); + + { + int nRet = _AhnHS_StartService(); + assert(nRet != HS_ERR_NOT_INITIALIZED); + assert(nRet != HS_ERR_ALREADY_SERVICE_RUNNING); + + if (nRet != HS_ERR_OK) + { + MA_TCHAR szMsg[255]; + MA_StringFormat(szMsg, MA_ARRAYCOUNT(szMsg), MA_T("START_SERVICE_ERROR(errorCode=%x)"), nRet); + MessageBox(NULL, szMsg, "HACK_SHIELD", MB_OK); + return false; + } + } + return true; +} + +bool HackShield_Shutdown() +{ + if (gs_dwMainThreadID) + { + gs_dwMainThreadID = 0; + _AhnHS_StopService(); + } + + int nRet = _AhnHS_Uninitialize(); + if (nRet != HS_ERR_OK) + { + MA_TCHAR szMsg[255]; + MA_StringFormat(szMsg, MA_ARRAYCOUNT(szMsg), MA_T("UNINITIALIZE_ERROR(errorCode=%x)"), nRet); + MessageBox(NULL, szMsg, "HACK_SHIELD", MB_OK); + } + + if (_AhnHsUserUtil_CheckHSShadowAccount()) + { + _AhnHsUserUtil_DeleteUser(); + } + + if (gs_isHackDetected) + { + MessageBox(NULL, gs_szHackMsg, "HACK_SHIELD", MB_OK); + } + return true; +} + +#define PREFIX_LOCALE "locale/" + +void HackShield_SetUserInfo(const char* szAccountName) +{ + MA_TCHAR szUserInfo[256]; + + const char* szLocaleName = LocaleService_IsYMIR() ? MA_T("unknown") : LocaleService_GetLocalePath(); + if( strncmp( szLocaleName, PREFIX_LOCALE, strlen(PREFIX_LOCALE) ) == 0 ) + szLocaleName += strlen(PREFIX_LOCALE); + MA_StringFormat(szUserInfo, MA_ARRAYCOUNT(szUserInfo), MA_T("%s / %s"), szAccountName, szLocaleName ); + _AhnHS_SetUserId(szUserInfo); +} + +#endif /* USE_AHNLAB_HACKSHIELD */ diff --git a/source/UserInterface/Hackshield.h b/source/UserInterface/Hackshield.h new file mode 100644 index 0000000..0deb861 --- /dev/null +++ b/source/UserInterface/Hackshield.h @@ -0,0 +1,23 @@ +#pragma once + +#ifdef USE_AHNLAB_HACKSHIELD + +#include "HackshieldLicense.h" + +#ifndef METIN2HS_INCLUDE +//#define METIN2HS_INCLUDE hshield-5.4.8.1 +#define METIN2HS_INCLUDE hackshield //2012 3 +#endif + +#define METIN2HS_INCLUDE_HSUPCHK +#define METIN2HS_INCLUDE_HSUSERUTIL +#define METIN2HS_INCLUDE_HSHIELD +#define METIN2HS_INCLUDE_HSHIELDLIBLINK +#define METIN2HS_INCLUDE_ANTICPXSVR + +bool HackShield_Init(); +bool HackShield_Shutdown(); +bool HackShield_PollEvent(); +void HackShield_SetUserInfo(const char* szAccountName); + +#endif /* USE_AHNLAB_HACKSHIELD */ diff --git a/source/UserInterface/HackshieldLicense.h b/source/UserInterface/HackshieldLicense.h new file mode 100644 index 0000000..e69de29 diff --git a/source/UserInterface/HackshieldLicense_metin2.h b/source/UserInterface/HackshieldLicense_metin2.h new file mode 100644 index 0000000..380647d --- /dev/null +++ b/source/UserInterface/HackshieldLicense_metin2.h @@ -0,0 +1,5 @@ +#pragma once + +#define METIN2HS_EXE_FILE_NAME "metin2.bin" +#define METIN2HS_CODE 5858 +#define METIN2HS_LICENSE "2A126BBDC6C61351124B2872" diff --git a/source/UserInterface/HackshieldLicense_metin2client.h b/source/UserInterface/HackshieldLicense_metin2client.h new file mode 100644 index 0000000..f60dc54 --- /dev/null +++ b/source/UserInterface/HackshieldLicense_metin2client.h @@ -0,0 +1,5 @@ +#pragma once + +#define METIN2HS_EXE_FILE_NAME "metin2client.bin" +#define METIN2HS_CODE 5857 +#define METIN2HS_LICENSE "B1FECACB51BD40B919EFCDB9" diff --git a/source/UserInterface/InstanceBase.cpp b/source/UserInterface/InstanceBase.cpp new file mode 100644 index 0000000..0b77b41 --- /dev/null +++ b/source/UserInterface/InstanceBase.cpp @@ -0,0 +1,3119 @@ +#include "StdAfx.h" +#include "InstanceBase.h" +#include "PythonBackground.h" +#include "PythonNonPlayer.h" +#include "PythonPlayer.h" +#include "PythonCharacterManager.h" +#include "AbstractPlayer.h" +#include "AbstractApplication.h" +#include "packet.h" + +#include "../eterlib/StateManager.h" +#include "../gamelib/ItemManager.h" + +BOOL HAIR_COLOR_ENABLE=FALSE; +BOOL USE_ARMOR_SPECULAR=FALSE; +BOOL RIDE_HORSE_ENABLE=TRUE; +const float c_fDefaultRotationSpeed = 1200.0f; +const float c_fDefaultHorseRotationSpeed = 300.0f; + + +bool IsWall(unsigned race) +{ + switch (race) + { + case 14201: + case 14202: + case 14203: + case 14204: + return true; + break; + } + return false; +} + +////////////////////////////////////////////////////////////////////////////////////// + + +CInstanceBase::SHORSE::SHORSE() +{ + __Initialize(); +} + +CInstanceBase::SHORSE::~SHORSE() +{ + assert(m_pkActor==NULL); +} + +void CInstanceBase::SHORSE::__Initialize() +{ + m_isMounting=false; + m_pkActor=NULL; +} + +void CInstanceBase::SHORSE::SetAttackSpeed(UINT uAtkSpd) +{ + if (!IsMounting()) + return; + + CActorInstance& rkActor=GetActorRef(); + rkActor.SetAttackSpeed(uAtkSpd/100.0f); +} + +void CInstanceBase::SHORSE::SetMoveSpeed(UINT uMovSpd) +{ + if (!IsMounting()) + return; + + CActorInstance& rkActor=GetActorRef(); + rkActor.SetMoveSpeed(uMovSpd/100.0f); +} + +void CInstanceBase::SHORSE::Create(const TPixelPosition& c_rkPPos, UINT eRace, UINT eHitEffect) +{ + assert(NULL==m_pkActor && "CInstanceBase::SHORSE::Create - ALREADY MOUNT"); + + m_pkActor=new CActorInstance; + + CActorInstance& rkActor=GetActorRef(); + rkActor.SetEventHandler(CActorInstance::IEventHandler::GetEmptyPtr()); + if (!rkActor.SetRace(eRace)) + { + delete m_pkActor; + m_pkActor=NULL; + return; + } + + rkActor.SetShape(0); + rkActor.SetBattleHitEffect(eHitEffect); + rkActor.SetAlphaValue(0.0f); + rkActor.BlendAlphaValue(1.0f, 0.5f); + rkActor.SetMoveSpeed(1.0f); + rkActor.SetAttackSpeed(1.0f); + rkActor.SetMotionMode(CRaceMotionData::MODE_GENERAL); + rkActor.Stop(); + rkActor.RefreshActorInstance(); + + rkActor.SetCurPixelPosition(c_rkPPos); + + m_isMounting=true; +} + +void CInstanceBase::SHORSE::Destroy() +{ + if (m_pkActor) + { + m_pkActor->Destroy(); + delete m_pkActor; + } + + __Initialize(); +} + +CActorInstance& CInstanceBase::SHORSE::GetActorRef() +{ + assert(NULL!=m_pkActor && "CInstanceBase::SHORSE::GetActorRef"); + return *m_pkActor; +} + +CActorInstance* CInstanceBase::SHORSE::GetActorPtr() +{ + return m_pkActor; +} + +UINT CInstanceBase::SHORSE::GetLevel() +{ + if (m_pkActor) + { + DWORD mount = m_pkActor->GetRace(); + switch (mount) + { + case 20101: + case 20102: + case 20103: + return 1; + case 20104: + case 20105: + case 20106: + return 2; + case 20107: + case 20108: + case 20109: + case 20110: // #0000673: [M2EU] ο Ż Ÿ ȵ + case 20111: // #0000673: [M2EU] ο Ż Ÿ ȵ + case 20112: // #0000673: [M2EU] ο Ż Ÿ ȵ + case 20113: // #0000673: [M2EU] ο Ż Ÿ ȵ + case 20114: + case 20115: + case 20116: + case 20117: + case 20118: + case 20120: + case 20121: + case 20122: + case 20123: + case 20124: + case 20125: + return 3; + case 20119: // 󸶴 ̺Ʈ 渶 ųҰ, ݰ 2 + case 20219: // ҷ ̺Ʈ 渶 ųҰ, ݰ 2 (=󸶴 渶 Ŭ) + case 20220: + case 20221: + case 20222: + return 2; + } + + // Ʈ Ȯ ýۿ Ư ó (20201 ~ 20212 뿪 ϰ 4 ʱ, ߱, ) + // -- Ż Ŭ󿡼 ϰ /ų 밡 ε Ŭ󿡼 óϴ ü ִ .. [hyo] + { + // ߱ Ż 2 ( , ų Ұ) + if ((20205 <= mount && 20208 >= mount) || + (20214 == mount) || (20217 == mount) || // , ϼ + (20224 == mount) || (20229 == mount) + ) + return 2; + + // Ż 3 ( , ų ) + if ((20209 <= mount && 20212 >= mount) || + (20215 == mount) || (20218 == mount) || // , ϼ + (20220 == mount) || (20225 == mount) || (20230 == mount) + ) + return 3; + } + } + return 0; +} + +bool CInstanceBase::SHORSE::IsNewMount() +{ + if (!m_pkActor) + return false; + DWORD mount = m_pkActor->GetRace(); + + if ((20205 <= mount && 20208 >= mount) || + (20214 == mount) || (20217 == mount) // , ϼ + ) + return true; + + // Ż + if ((20209 <= mount && 20212 >= mount) || + (20215 == mount) || (20218 == mount) || // , ϼ + (20220 == mount) + ) + return true; + + return false; +} +bool CInstanceBase::SHORSE::CanUseSkill() +{ + // ų 3 ̻̾߸ . + if (IsMounting()) + return 2 < GetLevel(); + + return true; +} + +bool CInstanceBase::SHORSE::CanAttack() +{ + if (IsMounting()) + if (GetLevel()<=1) + return false; + + return true; +} + +bool CInstanceBase::SHORSE::IsMounting() +{ + return m_isMounting; +} + +void CInstanceBase::SHORSE::Deform() +{ + if (!IsMounting()) + return; + + CActorInstance& rkActor=GetActorRef(); + rkActor.INSTANCEBASE_Deform(); +} + +void CInstanceBase::SHORSE::Render() +{ + if (!IsMounting()) + return; + + CActorInstance& rkActor=GetActorRef(); + rkActor.Render(); +} + +void CInstanceBase::__AttachHorseSaddle() +{ + if (!IsMountingHorse()) + return; + m_kHorse.m_pkActor->AttachModelInstance(CRaceData::PART_MAIN, "saddle", m_GraphicThingInstance, CRaceData::PART_MAIN); +} + +void CInstanceBase::__DetachHorseSaddle() +{ + if (!IsMountingHorse()) + return; + m_kHorse.m_pkActor->DetachModelInstance(CRaceData::PART_MAIN, m_GraphicThingInstance, CRaceData::PART_MAIN); +} + +////////////////////////////////////////////////////////////////////////////////////// + +void CInstanceBase::BlockMovement() +{ + m_GraphicThingInstance.BlockMovement(); +} + +bool CInstanceBase::IsBlockObject(const CGraphicObjectInstance& c_rkBGObj) +{ + return m_GraphicThingInstance.IsBlockObject(c_rkBGObj); +} + +bool CInstanceBase::AvoidObject(const CGraphicObjectInstance& c_rkBGObj) +{ + return m_GraphicThingInstance.AvoidObject(c_rkBGObj); +} + +/////////////////////////////////////////////////////////////////////////////////// + +bool __ArmorVnumToShape(int iVnum, DWORD * pdwShape) +{ + *pdwShape = iVnum; + + ///////////////////////////////////////// + + if (0 == iVnum || 1 == iVnum) + return false; + + if (!USE_ARMOR_SPECULAR) + return false; + + CItemData * pItemData; + if (!CItemManager::Instance().GetItemDataPointer(iVnum, &pItemData)) + return false; + + enum + { + SHAPE_VALUE_SLOT_INDEX = 3, + }; + + *pdwShape = pItemData->GetValue(SHAPE_VALUE_SLOT_INDEX); + + return true; +} + +// 2004.07.05.myevan.ýź ̴ +class CActorInstanceBackground : public IBackground +{ + public: + CActorInstanceBackground() {} + virtual ~CActorInstanceBackground() {} + bool IsBlock(int x, int y) + { + CPythonBackground& rkBG=CPythonBackground::Instance(); + return rkBG.isAttrOn(x, y, CTerrainImpl::ATTRIBUTE_BLOCK); + } +}; + +static CActorInstanceBackground gs_kActorInstBG; + +bool CInstanceBase::LessRenderOrder(CInstanceBase* pkInst) +{ + int nMainAlpha=(__GetAlphaValue() < 1.0f) ? 1 : 0; + int nTestAlpha=(pkInst->__GetAlphaValue() < 1.0f) ? 1 : 0; + if (nMainAlpha < nTestAlpha) + return true; + if (nMainAlpha > nTestAlpha) + return false; + + if (GetRace()GetRace()) + return true; + if (GetRace()>pkInst->GetRace()) + return false; + + if (GetShape()GetShape()) + return true; + + if (GetShape()>pkInst->GetShape()) + return false; + + UINT uLeftLODLevel=__LessRenderOrder_GetLODLevel(); + UINT uRightLODLevel=pkInst->__LessRenderOrder_GetLODLevel(); + if (uLeftLODLeveluRightLODLevel) + return false; + + if (m_awPart[CRaceData::PART_WEAPON]m_awPart[CRaceData::PART_WEAPON]) + return true; + + return false; +} + +UINT CInstanceBase::__LessRenderOrder_GetLODLevel() +{ + CGrannyLODController* pLODCtrl=m_GraphicThingInstance.GetLODControllerPointer(0); + if (!pLODCtrl) + return 0; + + return pLODCtrl->GetLODLevel(); +} + +bool CInstanceBase::__Background_GetWaterHeight(const TPixelPosition& c_rkPPos, float* pfHeight) +{ + long lHeight; + if (!CPythonBackground::Instance().GetWaterHeight(int(c_rkPPos.x), int(c_rkPPos.y), &lHeight)) + return false; + + *pfHeight = float(lHeight); + + return true; +} + +bool CInstanceBase::__Background_IsWaterPixelPosition(const TPixelPosition& c_rkPPos) +{ + return CPythonBackground::Instance().isAttrOn(c_rkPPos.x, c_rkPPos.y, CTerrainImpl::ATTRIBUTE_WATER); +} + +const float PC_DUST_RANGE = 2000.0f; +const float NPC_DUST_RANGE = 1000.0f; + +DWORD CInstanceBase::ms_dwUpdateCounter=0; +DWORD CInstanceBase::ms_dwRenderCounter=0; +DWORD CInstanceBase::ms_dwDeformCounter=0; + +CDynamicPool CInstanceBase::ms_kPool; + +bool CInstanceBase::__IsInDustRange() +{ + if (!__IsExistMainInstance()) + return false; + + CInstanceBase* pkInstMain=__GetMainInstancePtr(); + + float fDistance=NEW_GetDistanceFromDestInstance(*pkInstMain); + + if (IsPC()) + { + if (fDistance<=PC_DUST_RANGE) + return true; + } + + if (fDistance<=NPC_DUST_RANGE) + return true; + + return false; +} + +void CInstanceBase::__EnableSkipCollision() +{ + if (__IsMainInstance()) + { + TraceError("CInstanceBase::__EnableSkipCollision - ڽ 浹˻罺ŵ Ǹ ȵȴ!!"); + return; + } + m_GraphicThingInstance.EnableSkipCollision(); +} + +void CInstanceBase::__DisableSkipCollision() +{ + m_GraphicThingInstance.DisableSkipCollision(); +} + +DWORD CInstanceBase::__GetShadowMapColor(float x, float y) +{ + CPythonBackground& rkBG=CPythonBackground::Instance(); + return rkBG.GetShadowMapColor(x, y); +} + +float CInstanceBase::__GetBackgroundHeight(float x, float y) +{ + CPythonBackground& rkBG=CPythonBackground::Instance(); + return rkBG.GetHeight(x, y); +} + +#ifdef __MOVIE_MODE__ + +BOOL CInstanceBase::IsMovieMode() +{ + if (IsAffect(AFFECT_INVISIBILITY)) + return true; + + return false; +} + +#endif + +BOOL CInstanceBase::IsInvisibility() +{ + if (IsAffect(AFFECT_INVISIBILITY)) + return true; + + return false; +} + +BOOL CInstanceBase::IsParalysis() +{ + return m_GraphicThingInstance.IsParalysis(); +} + +BOOL CInstanceBase::IsGameMaster() +{ + if (m_kAffectFlagContainer.IsSet(AFFECT_YMIR)) + return true; + return false; +} + + +BOOL CInstanceBase::IsSameEmpire(CInstanceBase& rkInstDst) +{ + if (0 == rkInstDst.m_dwEmpireID) + return TRUE; + + if (IsGameMaster()) + return TRUE; + + if (rkInstDst.IsGameMaster()) + return TRUE; + + if (rkInstDst.m_dwEmpireID==m_dwEmpireID) + return TRUE; + + return FALSE; +} + +DWORD CInstanceBase::GetEmpireID() +{ + return m_dwEmpireID; +} + +DWORD CInstanceBase::GetGuildID() +{ + return m_dwGuildID; +} + +int CInstanceBase::GetAlignment() +{ + return m_sAlignment; +} + +UINT CInstanceBase::GetAlignmentGrade() +{ + if (m_sAlignment >= 12000) + return 0; + else if (m_sAlignment >= 8000) + return 1; + else if (m_sAlignment >= 4000) + return 2; + else if (m_sAlignment >= 1000) + return 3; + else if (m_sAlignment >= 0) + return 4; + else if (m_sAlignment > -4000) + return 5; + else if (m_sAlignment > -8000) + return 6; + else if (m_sAlignment > -12000) + return 7; + + return 8; +} + +int CInstanceBase::GetAlignmentType() +{ + switch (GetAlignmentGrade()) + { + case 0: + case 1: + case 2: + case 3: + { + return ALIGNMENT_TYPE_WHITE; + break; + } + + case 5: + case 6: + case 7: + case 8: + { + return ALIGNMENT_TYPE_DARK; + break; + } + } + + return ALIGNMENT_TYPE_NORMAL; +} + +BYTE CInstanceBase::GetPKMode() +{ + return m_byPKMode; +} + +bool CInstanceBase::IsKiller() +{ + return m_isKiller; +} + +bool CInstanceBase::IsPartyMember() +{ + return m_isPartyMember; +} + +BOOL CInstanceBase::IsInSafe() +{ + const TPixelPosition& c_rkPPosCur=m_GraphicThingInstance.NEW_GetCurPixelPositionRef(); + if (CPythonBackground::Instance().isAttrOn(c_rkPPosCur.x, c_rkPPosCur.y, CTerrainImpl::ATTRIBUTE_BANPK)) + return TRUE; + + return FALSE; +} + +float CInstanceBase::CalculateDistanceSq3d(const TPixelPosition& c_rkPPosDst) +{ + const TPixelPosition& c_rkPPosSrc=m_GraphicThingInstance.NEW_GetCurPixelPositionRef(); + return SPixelPosition_CalculateDistanceSq3d(c_rkPPosSrc, c_rkPPosDst); +} + +void CInstanceBase::OnSelected() +{ +#ifdef __MOVIE_MODE__ + if (!__IsExistMainInstance()) + return; +#endif + + if (IsStoneDoor()) + return; + + if (IsDead()) + return; + + __AttachSelectEffect(); +} + +void CInstanceBase::OnUnselected() +{ + __DetachSelectEffect(); +} + +void CInstanceBase::OnTargeted() +{ +#ifdef __MOVIE_MODE__ + if (!__IsExistMainInstance()) + return; +#endif + + if (IsStoneDoor()) + return; + + if (IsDead()) + return; + + __AttachTargetEffect(); +} + +void CInstanceBase::OnUntargeted() +{ + __DetachTargetEffect(); +} + +void CInstanceBase::DestroySystem() +{ + ms_kPool.Clear(); +} + +void CInstanceBase::CreateSystem(UINT uCapacity) +{ + ms_kPool.Create(uCapacity); + + memset(ms_adwCRCAffectEffect, 0, sizeof(ms_adwCRCAffectEffect)); + + ms_fDustGap=250.0f; + ms_fHorseDustGap=500.0f; +} + +CInstanceBase* CInstanceBase::New() +{ + return ms_kPool.Alloc(); +} + +void CInstanceBase::Delete(CInstanceBase* pkInst) +{ + pkInst->Destroy(); + ms_kPool.Free(pkInst); +} + +void CInstanceBase::SetMainInstance() +{ + CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance(); + + DWORD dwVID=GetVirtualID(); + rkChrMgr.SetMainInstance(dwVID); + + m_GraphicThingInstance.SetMainInstance(); +} + +CInstanceBase* CInstanceBase::__GetMainInstancePtr() +{ + CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance(); + return rkChrMgr.GetMainInstancePtr(); +} + +void CInstanceBase::__ClearMainInstance() +{ + CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance(); + rkChrMgr.ClearMainInstance(); +} + +/* ÷̾ ij .*/ +bool CInstanceBase::__IsMainInstance() +{ + if (this==__GetMainInstancePtr()) + return true; + + return false; +} + +bool CInstanceBase::__IsExistMainInstance() +{ + if(__GetMainInstancePtr()) + return true; + else + return false; +} + +bool CInstanceBase::__MainCanSeeHiddenThing() +{ + return false; +// CInstanceBase * pInstance = __GetMainInstancePtr(); +// return pInstance->IsAffect(AFFECT_GAMJI); +} + +float CInstanceBase::__GetBowRange() +{ + float fRange = 2500.0f - 100.0f; + + if (__IsMainInstance()) + { + IAbstractPlayer& rPlayer=IAbstractPlayer::GetSingleton(); + fRange += float(rPlayer.GetStatus(POINT_BOW_DISTANCE)); + } + + return fRange; +} + +CInstanceBase* CInstanceBase::__FindInstancePtr(DWORD dwVID) +{ + CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance(); + return rkChrMgr.GetInstancePtr(dwVID); +} + +bool CInstanceBase::__FindRaceType(DWORD dwRace, BYTE* pbType) +{ + CPythonNonPlayer& rkNonPlayer=CPythonNonPlayer::Instance(); + return rkNonPlayer.GetInstanceType(dwRace, pbType); +} + +bool CInstanceBase::Create(const SCreateData& c_rkCreateData) +{ + IAbstractApplication::GetSingleton().SkipRenderBuffering(300); + + SetInstanceType(c_rkCreateData.m_bType); + + + if (!SetRace(c_rkCreateData.m_dwRace)) + return false; + + SetVirtualID(c_rkCreateData.m_dwVID); + + if (c_rkCreateData.m_isMain) + SetMainInstance(); + + if (IsGuildWall()) + { + unsigned center_x; + unsigned center_y; + + c_rkCreateData.m_kAffectFlags.ConvertToPosition(¢er_x, ¢er_y); + + float center_z = __GetBackgroundHeight(center_x, center_y); + NEW_SetPixelPosition(TPixelPosition(float(c_rkCreateData.m_lPosX), float(c_rkCreateData.m_lPosY), center_z)); + } + else + { + SCRIPT_SetPixelPosition(float(c_rkCreateData.m_lPosX), float(c_rkCreateData.m_lPosY)); + } + + if (0 != c_rkCreateData.m_dwMountVnum) + MountHorse(c_rkCreateData.m_dwMountVnum); + + SetArmor(c_rkCreateData.m_dwArmor); + + if (IsPC()) + { + SetHair(c_rkCreateData.m_dwHair); + SetWeapon(c_rkCreateData.m_dwWeapon); + } + + __Create_SetName(c_rkCreateData); + + m_dwLevel = c_rkCreateData.m_dwLevel; + m_dwGuildID = c_rkCreateData.m_dwGuildID; + m_dwEmpireID = c_rkCreateData.m_dwEmpireID; + + SetVirtualNumber(c_rkCreateData.m_dwRace); + SetRotation(c_rkCreateData.m_fRot); + + SetAlignment(c_rkCreateData.m_sAlignment); + SetPKMode(c_rkCreateData.m_byPKMode); + + SetMoveSpeed(c_rkCreateData.m_dwMovSpd); + SetAttackSpeed(c_rkCreateData.m_dwAtkSpd); + + // NOTE : Dress ԰ Alpha ʴ´. + if (!IsWearingDress()) + { + // NOTE : ݵ Affect ʿ ־ + m_GraphicThingInstance.SetAlphaValue(0.0f); + m_GraphicThingInstance.BlendAlphaValue(1.0f, 0.5f); + } + + if (!IsGuildWall()) + { + SetAffectFlagContainer(c_rkCreateData.m_kAffectFlags); + } + + // NOTE : ݵ Affect Ŀ ؾ + AttachTextTail(); + RefreshTextTail(); + + if (c_rkCreateData.m_dwStateFlags & ADD_CHARACTER_STATE_SPAWN) + { + if (IsAffect(AFFECT_SPAWN)) + __AttachEffect(EFFECT_SPAWN_APPEAR); + + if (IsPC()) + { + Refresh(CRaceMotionData::NAME_WAIT, true); + } + else + { + Refresh(CRaceMotionData::NAME_SPAWN, false); + } + } + else + { + Refresh(CRaceMotionData::NAME_WAIT, true); + } + + __AttachEmpireEffect(c_rkCreateData.m_dwEmpireID); + + RegisterBoundingSphere(); + + if (c_rkCreateData.m_dwStateFlags & ADD_CHARACTER_STATE_DEAD) + m_GraphicThingInstance.DieEnd(); + + SetStateFlags(c_rkCreateData.m_dwStateFlags); + + m_GraphicThingInstance.SetBattleHitEffect(ms_adwCRCAffectEffect[EFFECT_HIT]); + + if (!IsPC()) + { + DWORD dwBodyColor = CPythonNonPlayer::Instance().GetMonsterColor(c_rkCreateData.m_dwRace); + if (0 != dwBodyColor) + { + SetModulateRenderMode(); + SetAddColor(dwBodyColor); + } + } + + __AttachHorseSaddle(); + + // ɺ ӽ ڵ, ġ ã + const int c_iGuildSymbolRace = 14200; + if (c_iGuildSymbolRace == GetRace()) + { + std::string strFileName = GetGuildSymbolFileName(m_dwGuildID); + if (IsFile(strFileName.c_str())) + m_GraphicThingInstance.ChangeMaterial(strFileName.c_str()); + } + + return true; +} + + +void CInstanceBase::__Create_SetName(const SCreateData& c_rkCreateData) +{ + if (IsGoto()) + { + SetNameString("", 0); + return; + } + if (IsWarp()) + { + __Create_SetWarpName(c_rkCreateData); + return; + } + + SetNameString(c_rkCreateData.m_stName.c_str(), c_rkCreateData.m_stName.length()); +} + +void CInstanceBase::__Create_SetWarpName(const SCreateData& c_rkCreateData) +{ + const char * c_szName; + if (CPythonNonPlayer::Instance().GetName(c_rkCreateData.m_dwRace, &c_szName)) + { + std::string strName = c_szName; + int iFindingPos = strName.find_first_of(" ", 0); + if (iFindingPos > 0) + { + strName.resize(iFindingPos); + } + SetNameString(strName.c_str(), strName.length()); + } + else + { + SetNameString(c_rkCreateData.m_stName.c_str(), c_rkCreateData.m_stName.length()); + } +} + +void CInstanceBase::SetNameString(const char* c_szName, int len) +{ + m_stName.assign(c_szName, len); +} + + +bool CInstanceBase::SetRace(DWORD eRace) +{ + m_dwRace = eRace; + + if (!m_GraphicThingInstance.SetRace(eRace)) + return false; + + if (!__FindRaceType(m_dwRace, &m_eRaceType)) + m_eRaceType=CActorInstance::TYPE_PC; + + return true; +} + +BOOL CInstanceBase::__IsChangableWeapon(int iWeaponID) +{ + // 巹 ԰ ɿ ʰ.. + if (IsWearingDress()) + { + const int c_iBouquets[] = + { + 50201, // Bouquet for Assassin + 50202, // Bouquet for Shaman + 50203, + 50204, + 0, // #0000545: [M2CN] 巹 + }; + + for (int i = 0; c_iBouquets[i] != 0; ++i) + if (iWeaponID == c_iBouquets[i]) + return true; + + return false; + } + else + return true; +} + +BOOL CInstanceBase::IsWearingDress() +{ + const int c_iWeddingDressShape = 201; + return c_iWeddingDressShape == m_eShape; +} + +BOOL CInstanceBase::IsHoldingPickAxe() +{ + const int c_iPickAxeStart = 29101; + const int c_iPickAxeEnd = 29110; + return m_awPart[CRaceData::PART_WEAPON] >= c_iPickAxeStart && m_awPart[CRaceData::PART_WEAPON] <= c_iPickAxeEnd; +} + +BOOL CInstanceBase::IsNewMount() +{ + return m_kHorse.IsNewMount(); +} + +BOOL CInstanceBase::IsMountingHorse() +{ + return m_kHorse.IsMounting(); +} + +void CInstanceBase::MountHorse(UINT eRace) +{ + m_kHorse.Destroy(); + m_kHorse.Create(m_GraphicThingInstance.NEW_GetCurPixelPositionRef(), eRace, ms_adwCRCAffectEffect[EFFECT_HIT]); + + SetMotionMode(CRaceMotionData::MODE_HORSE); + SetRotationSpeed(c_fDefaultHorseRotationSpeed); + + m_GraphicThingInstance.MountHorse(m_kHorse.GetActorPtr()); + m_GraphicThingInstance.Stop(); + m_GraphicThingInstance.RefreshActorInstance(); +} + +void CInstanceBase::DismountHorse() +{ + m_kHorse.Destroy(); +} + +void CInstanceBase::GetInfo(std::string* pstInfo) +{ + char szInfo[256]; + sprintf(szInfo, "Inst - UC %d, RC %d Pool - %d ", + ms_dwUpdateCounter, + ms_dwRenderCounter, + ms_kPool.GetCapacity() + ); + + pstInfo->append(szInfo); +} + +void CInstanceBase::ResetPerformanceCounter() +{ + ms_dwUpdateCounter=0; + ms_dwRenderCounter=0; + ms_dwDeformCounter=0; +} + +bool CInstanceBase::NEW_IsLastPixelPosition() +{ + return m_GraphicThingInstance.IsPushing(); +} + +const TPixelPosition& CInstanceBase::NEW_GetLastPixelPositionRef() +{ + return m_GraphicThingInstance.NEW_GetLastPixelPositionRef(); +} + +void CInstanceBase::NEW_SetDstPixelPositionZ(FLOAT z) +{ + m_GraphicThingInstance.NEW_SetDstPixelPositionZ(z); +} + +void CInstanceBase::NEW_SetDstPixelPosition(const TPixelPosition& c_rkPPosDst) +{ + m_GraphicThingInstance.NEW_SetDstPixelPosition(c_rkPPosDst); +} + +void CInstanceBase::NEW_SetSrcPixelPosition(const TPixelPosition& c_rkPPosSrc) +{ + m_GraphicThingInstance.NEW_SetSrcPixelPosition(c_rkPPosSrc); +} + +const TPixelPosition& CInstanceBase::NEW_GetCurPixelPositionRef() +{ + return m_GraphicThingInstance.NEW_GetCurPixelPositionRef(); +} + +const TPixelPosition& CInstanceBase::NEW_GetDstPixelPositionRef() +{ + return m_GraphicThingInstance.NEW_GetDstPixelPositionRef(); +} + +const TPixelPosition& CInstanceBase::NEW_GetSrcPixelPositionRef() +{ + return m_GraphicThingInstance.NEW_GetSrcPixelPositionRef(); +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +void CInstanceBase::OnSyncing() +{ + m_GraphicThingInstance.__OnSyncing(); +} + +void CInstanceBase::OnWaiting() +{ + m_GraphicThingInstance.__OnWaiting(); +} + +void CInstanceBase::OnMoving() +{ + m_GraphicThingInstance.__OnMoving(); +} + +void CInstanceBase::ChangeGuild(DWORD dwGuildID) +{ + m_dwGuildID=dwGuildID; + + DetachTextTail(); + AttachTextTail(); + RefreshTextTail(); +} + +DWORD CInstanceBase::GetPart(CRaceData::EParts part) +{ + assert(part >= 0 && part < CRaceData::PART_MAX_NUM); + return m_awPart[part]; +} + +DWORD CInstanceBase::GetShape() +{ + return m_eShape; +} + +bool CInstanceBase::CanAct() +{ + return m_GraphicThingInstance.CanAct(); +} + +bool CInstanceBase::CanMove() +{ + return m_GraphicThingInstance.CanMove(); +} + +bool CInstanceBase::CanUseSkill() +{ + if (IsPoly()) + return false; + + if (IsWearingDress()) + return false; + + if (IsHoldingPickAxe()) + return false; + + if (!m_kHorse.CanUseSkill()) + return false; + + if (!m_GraphicThingInstance.CanUseSkill()) + return false; + + return true; +} + +bool CInstanceBase::CanAttack() +{ + if (!m_kHorse.CanAttack()) + return false; + + if (IsWearingDress()) + return false; + + if (IsHoldingPickAxe()) + return false; + + return m_GraphicThingInstance.CanAttack(); +} + + + +bool CInstanceBase::CanFishing() +{ + return m_GraphicThingInstance.CanFishing(); +} + + +BOOL CInstanceBase::IsBowMode() +{ + return m_GraphicThingInstance.IsBowMode(); +} + +BOOL CInstanceBase::IsHandMode() +{ + return m_GraphicThingInstance.IsHandMode(); +} + +BOOL CInstanceBase::IsFishingMode() +{ + if (CRaceMotionData::MODE_FISHING == m_GraphicThingInstance.GetMotionMode()) + return true; + + return false; +} + +BOOL CInstanceBase::IsFishing() +{ + return m_GraphicThingInstance.IsFishing(); +} + +BOOL CInstanceBase::IsDead() +{ + return m_GraphicThingInstance.IsDead(); +} + +BOOL CInstanceBase::IsStun() +{ + return m_GraphicThingInstance.IsStun(); +} + +BOOL CInstanceBase::IsSleep() +{ + return m_GraphicThingInstance.IsSleep(); +} + + +BOOL CInstanceBase::__IsSyncing() +{ + return m_GraphicThingInstance.__IsSyncing(); +} + + + +void CInstanceBase::NEW_SetOwner(DWORD dwVIDOwner) +{ + m_GraphicThingInstance.SetOwner(dwVIDOwner); +} + +float CInstanceBase::GetLocalTime() +{ + return m_GraphicThingInstance.GetLocalTime(); +} + + +void CInstanceBase::PushUDPState(DWORD dwCmdTime, const TPixelPosition& c_rkPPosDst, float fDstRot, UINT eFunc, UINT uArg) +{ +} + +DWORD ELTimer_GetServerFrameMSec(); + +void CInstanceBase::PushTCPStateExpanded(DWORD dwCmdTime, const TPixelPosition& c_rkPPosDst, float fDstRot, UINT eFunc, UINT uArg, UINT uTargetVID) +{ + SCommand kCmdNew; + kCmdNew.m_kPPosDst = c_rkPPosDst; + kCmdNew.m_dwChkTime = dwCmdTime+100; + kCmdNew.m_dwCmdTime = dwCmdTime; + kCmdNew.m_fDstRot = fDstRot; + kCmdNew.m_eFunc = eFunc; + kCmdNew.m_uArg = uArg; + kCmdNew.m_uTargetVID = uTargetVID; + m_kQue_kCmdNew.push_back(kCmdNew); +} + +void CInstanceBase::PushTCPState(DWORD dwCmdTime, const TPixelPosition& c_rkPPosDst, float fDstRot, UINT eFunc, UINT uArg) +{ + if (__IsMainInstance()) + { + //assert(!"CInstanceBase::PushTCPState ÷̾ ڽſ ̵Ŷ ȵȴ!"); + TraceError("CInstanceBase::PushTCPState ÷̾ ڽſ ̵Ŷ ȵȴ!"); + return; + } + + int nNetworkGap=ELTimer_GetServerFrameMSec()-dwCmdTime; + + m_nAverageNetworkGap=(m_nAverageNetworkGap*70+nNetworkGap*30)/100; + + /* + if (m_dwBaseCmdTime == 0) + { + m_dwBaseChkTime = ELTimer_GetFrameMSec()-nNetworkGap; + m_dwBaseCmdTime = dwCmdTime; + + Tracenf("VID[%d] Ʈ [%d]", GetVirtualID(), nNetworkGap); + } + */ + + //m_dwBaseChkTime-m_dwBaseCmdTime+ELTimer_GetServerMSec(); + + SCommand kCmdNew; + kCmdNew.m_kPPosDst = c_rkPPosDst; + kCmdNew.m_dwChkTime = dwCmdTime+m_nAverageNetworkGap;//m_dwBaseChkTime + (dwCmdTime - m_dwBaseCmdTime);// + nNetworkGap; + kCmdNew.m_dwCmdTime = dwCmdTime; + kCmdNew.m_fDstRot = fDstRot; + kCmdNew.m_eFunc = eFunc; + kCmdNew.m_uArg = uArg; + m_kQue_kCmdNew.push_back(kCmdNew); + + //int nApplyGap=kCmdNew.m_dwChkTime-ELTimer_GetServerFrameMSec(); + + //if (nApplyGap<-500 || nApplyGap>500) + // Tracenf("VID[%d] NAME[%s] Ʈ [cur:%d ave:%d] ۵ð (%d)", GetVirtualID(), GetNameString(), nNetworkGap, m_nAverageNetworkGap, nApplyGap); +} + +/* +CInstanceBase::TStateQueue::iterator CInstanceBase::FindSameState(TStateQueue& rkQuekStt, DWORD dwCmdTime, UINT eFunc, UINT uArg) +{ + TStateQueue::iterator i=rkQuekStt.begin(); + while (rkQuekStt.end()!=i) + { + SState& rkSttEach=*i; + if (rkSttEach.m_dwCmdTime==dwCmdTime) + if (rkSttEach.m_eFunc==eFunc) + if (rkSttEach.m_uArg==uArg) + break; + ++i; + } + + return i; +} +*/ + +BOOL CInstanceBase::__CanProcessNetworkStatePacket() +{ + if (m_GraphicThingInstance.IsDead()) + return FALSE; + if (m_GraphicThingInstance.IsKnockDown()) + return FALSE; + if (m_GraphicThingInstance.IsUsingSkill()) + if (!m_GraphicThingInstance.CanCancelSkill()) + return FALSE; + + return TRUE; +} + +BOOL CInstanceBase::__IsEnableTCPProcess(UINT eCurFunc) +{ + if (m_GraphicThingInstance.IsActEmotion()) + { + return FALSE; + } + + if (!m_bEnableTCPState) + { + if (FUNC_EMOTION != eCurFunc) + { + return FALSE; + } + } + + return TRUE; +} + +void CInstanceBase::StateProcess() +{ + while (1) + { + if (m_kQue_kCmdNew.empty()) + return; + + DWORD dwDstChkTime = m_kQue_kCmdNew.front().m_dwChkTime; + DWORD dwCurChkTime = ELTimer_GetServerFrameMSec(); + + if (dwCurChkTime < dwDstChkTime) + return; + + SCommand kCmdTop = m_kQue_kCmdNew.front(); + m_kQue_kCmdNew.pop_front(); + + TPixelPosition kPPosDst = kCmdTop.m_kPPosDst; + //DWORD dwCmdTime = kCmdTop.m_dwCmdTime; + FLOAT fRotDst = kCmdTop.m_fDstRot; + UINT eFunc = kCmdTop.m_eFunc; + UINT uArg = kCmdTop.m_uArg; + UINT uVID = GetVirtualID(); + UINT uTargetVID = kCmdTop.m_uTargetVID; + + TPixelPosition kPPosCur; + NEW_GetPixelPosition(&kPPosCur); + + /* + if (IsPC()) + Tracenf("%d cmd: vid=%d[%s] func=%d arg=%d curPos=(%f, %f) dstPos=(%f, %f) rot=%f (time %d)", + ELTimer_GetMSec(), + uVID, m_stName.c_str(), eFunc, uArg, + kPPosCur.x, kPPosCur.y, + kPPosDst.x, kPPosDst.y, fRotDst, dwCmdTime-m_dwBaseCmdTime); + */ + + TPixelPosition kPPosDir = kPPosDst - kPPosCur; + float fDirLen = (float)sqrt(kPPosDir.x * kPPosDir.x + kPPosDir.y * kPPosDir.y); + + //Tracenf("Ÿ %f", fDirLen); + + if (!__CanProcessNetworkStatePacket()) + { + Lognf(0, "vid=%d ¶ ŵ IsDead=%d, IsKnockDown=%d", uVID, m_GraphicThingInstance.IsDead(), m_GraphicThingInstance.IsKnockDown()); + return; + } + + if (!__IsEnableTCPProcess(eFunc)) + { + return; + } + + switch (eFunc) + { + case FUNC_WAIT: + { + //Tracenf("%s (%f, %f) -> (%f, %f) Ÿ %f", GetNameString(), kPPosCur.x, kPPosCur.y, kPPosDst.x, kPPosDst.y, fDirLen); + if (fDirLen > 1.0f) + { + //NEW_GetSrcPixelPositionRef() = kPPosCur; + //NEW_GetDstPixelPositionRef() = kPPosDst; + NEW_SetSrcPixelPosition(kPPosCur); + NEW_SetDstPixelPosition(kPPosDst); + + __EnableSkipCollision(); + + m_fDstRot = fRotDst; + m_isGoing = TRUE; + + m_kMovAfterFunc.eFunc = FUNC_WAIT; + + if (!IsWalking()) + StartWalking(); + + //Tracen("ǥ"); + } + else + { + //Tracen(" "); + + m_isGoing = FALSE; + + if (!IsWaiting()) + EndWalking(); + + SCRIPT_SetPixelPosition(kPPosDst.x, kPPosDst.y); + SetAdvancingRotation(fRotDst); + SetRotation(fRotDst); + } + break; + } + + case FUNC_MOVE: + { + //NEW_GetSrcPixelPositionRef() = kPPosCur; + //NEW_GetDstPixelPositionRef() = kPPosDst; + NEW_SetSrcPixelPosition(kPPosCur); + NEW_SetDstPixelPosition(kPPosDst); + m_fDstRot = fRotDst; + m_isGoing = TRUE; + __EnableSkipCollision(); + //m_isSyncMov = TRUE; + + m_kMovAfterFunc.eFunc = FUNC_MOVE; + + if (!IsWalking()) + { + //Tracen("Ȱ ʾ ȱ "); + StartWalking(); + } + else + { + //Tracen("̹ ȴ "); + } + break; + } + + case FUNC_COMBO: + { + if (fDirLen >= 50.0f) + { + NEW_SetSrcPixelPosition(kPPosCur); + NEW_SetDstPixelPosition(kPPosDst); + m_fDstRot=fRotDst; + m_isGoing = TRUE; + __EnableSkipCollision(); + + m_kMovAfterFunc.eFunc = FUNC_COMBO; + m_kMovAfterFunc.uArg = uArg; + + if (!IsWalking()) + StartWalking(); + } + else + { + //Tracen(" "); + + m_isGoing = FALSE; + + if (IsWalking()) + EndWalking(); + + SCRIPT_SetPixelPosition(kPPosDst.x, kPPosDst.y); + RunComboAttack(fRotDst, uArg); + } + break; + } + + case FUNC_ATTACK: + { + if (fDirLen>=50.0f) + { + //NEW_GetSrcPixelPositionRef() = kPPosCur; + //NEW_GetDstPixelPositionRef() = kPPosDst; + NEW_SetSrcPixelPosition(kPPosCur); + NEW_SetDstPixelPosition(kPPosDst); + m_fDstRot = fRotDst; + m_isGoing = TRUE; + __EnableSkipCollision(); + //m_isSyncMov = TRUE; + + m_kMovAfterFunc.eFunc = FUNC_ATTACK; + + if (!IsWalking()) + StartWalking(); + + //Tracen("ʹ ־ ̵ "); + } + else + { + //Tracen("븻 "); + + m_isGoing = FALSE; + + if (IsWalking()) + EndWalking(); + + SCRIPT_SetPixelPosition(kPPosDst.x, kPPosDst.y); + BlendRotation(fRotDst); + + RunNormalAttack(fRotDst); + + //Tracen(" "); + } + break; + } + + case FUNC_MOB_SKILL: + { + if (fDirLen >= 50.0f) + { + NEW_SetSrcPixelPosition(kPPosCur); + NEW_SetDstPixelPosition(kPPosDst); + m_fDstRot = fRotDst; + m_isGoing = TRUE; + __EnableSkipCollision(); + + m_kMovAfterFunc.eFunc = FUNC_MOB_SKILL; + m_kMovAfterFunc.uArg = uArg; + + if (!IsWalking()) + StartWalking(); + } + else + { + m_isGoing = FALSE; + + if (IsWalking()) + EndWalking(); + + SCRIPT_SetPixelPosition(kPPosDst.x, kPPosDst.y); + BlendRotation(fRotDst); + + m_GraphicThingInstance.InterceptOnceMotion(CRaceMotionData::NAME_SPECIAL_1 + uArg); + } + break; + } + + case FUNC_EMOTION: + { + if (fDirLen>100.0f) + { + NEW_SetSrcPixelPosition(kPPosCur); + NEW_SetDstPixelPosition(kPPosDst); + m_fDstRot = fRotDst; + m_isGoing = TRUE; + + if (__IsMainInstance()) + __EnableSkipCollision(); + + m_kMovAfterFunc.eFunc = FUNC_EMOTION; + m_kMovAfterFunc.uArg = uArg; + m_kMovAfterFunc.uArgExpanded = uTargetVID; + m_kMovAfterFunc.kPosDst = kPPosDst; + + if (!IsWalking()) + StartWalking(); + } + else + { + __ProcessFunctionEmotion(uArg, uTargetVID, kPPosDst); + } + break; + } + + default: + { + if (eFunc & FUNC_SKILL) + { + if (fDirLen >= 50.0f) + { + //NEW_GetSrcPixelPositionRef() = kPPosCur; + //NEW_GetDstPixelPositionRef() = kPPosDst; + NEW_SetSrcPixelPosition(kPPosCur); + NEW_SetDstPixelPosition(kPPosDst); + m_fDstRot = fRotDst; + m_isGoing = TRUE; + //m_isSyncMov = TRUE; + __EnableSkipCollision(); + + m_kMovAfterFunc.eFunc = eFunc; + m_kMovAfterFunc.uArg = uArg; + + if (!IsWalking()) + StartWalking(); + + //Tracen("ʹ ־ ̵ "); + } + else + { + //Tracen("ų "); + + m_isGoing = FALSE; + + if (IsWalking()) + EndWalking(); + + SCRIPT_SetPixelPosition(kPPosDst.x, kPPosDst.y); + SetAdvancingRotation(fRotDst); + SetRotation(fRotDst); + + NEW_UseSkill(0, eFunc & 0x7f, uArg&0x0f, (uArg>>4) ? true : false); + //Tracen(" "); + } + } + break; + } + } + } +} + + +void CInstanceBase::MovementProcess() +{ + TPixelPosition kPPosCur; + NEW_GetPixelPosition(&kPPosCur); + + // ǥ̹Ƿ y -ȭؼ Ѵ. + + TPixelPosition kPPosNext; + { + const D3DXVECTOR3 & c_rkV3Mov = m_GraphicThingInstance.GetMovementVectorRef(); + + kPPosNext.x = kPPosCur.x + (+c_rkV3Mov.x); + kPPosNext.y = kPPosCur.y + (-c_rkV3Mov.y); + kPPosNext.z = kPPosCur.z + (+c_rkV3Mov.z); + } + + TPixelPosition kPPosDeltaSC = kPPosCur - NEW_GetSrcPixelPositionRef(); + TPixelPosition kPPosDeltaSN = kPPosNext - NEW_GetSrcPixelPositionRef(); + TPixelPosition kPPosDeltaSD = NEW_GetDstPixelPositionRef() - NEW_GetSrcPixelPositionRef(); + + float fCurLen = sqrtf(kPPosDeltaSC.x * kPPosDeltaSC.x + kPPosDeltaSC.y * kPPosDeltaSC.y); + float fNextLen = sqrtf(kPPosDeltaSN.x * kPPosDeltaSN.x + kPPosDeltaSN.y * kPPosDeltaSN.y); + float fTotalLen = sqrtf(kPPosDeltaSD.x * kPPosDeltaSD.x + kPPosDeltaSD.y * kPPosDeltaSD.y); + float fRestLen = fTotalLen - fCurLen; + + if (__IsMainInstance()) + { + if (m_isGoing && IsWalking()) + { + float fDstRot = NEW_GetAdvancingRotationFromPixelPosition(NEW_GetSrcPixelPositionRef(), NEW_GetDstPixelPositionRef()); + + SetAdvancingRotation(fDstRot); + + if (fRestLen<=0.0) + { + if (IsWalking()) + EndWalking(); + + //Tracen("ǥ "); + + m_isGoing = FALSE; + + BlockMovement(); + + if (FUNC_EMOTION == m_kMovAfterFunc.eFunc) + { + DWORD dwMotionNumber = m_kMovAfterFunc.uArg; + DWORD dwTargetVID = m_kMovAfterFunc.uArgExpanded; + __ProcessFunctionEmotion(dwMotionNumber, dwTargetVID, m_kMovAfterFunc.kPosDst); + m_kMovAfterFunc.eFunc = FUNC_WAIT; + return; + } + } + } + } + else + { + if (m_isGoing && IsWalking()) + { + float fDstRot = NEW_GetAdvancingRotationFromPixelPosition(NEW_GetSrcPixelPositionRef(), NEW_GetDstPixelPositionRef()); + + SetAdvancingRotation(fDstRot); + + // Ͻð ʾ ʹ ̵ߴٸ.. + if (fRestLen < -100.0f) + { + NEW_SetSrcPixelPosition(kPPosCur); + + float fDstRot = NEW_GetAdvancingRotationFromPixelPosition(kPPosCur, NEW_GetDstPixelPositionRef()); + SetAdvancingRotation(fDstRot); + //Tracenf("VID %d ⼳ (%f, %f) %f rest %f", GetVirtualID(), kPPosCur.x, kPPosCur.y, fDstRot, fRestLen); + + // ̵̶ ߰ Ѵ + if (FUNC_MOVE == m_kMovAfterFunc.eFunc) + { + m_kMovAfterFunc.eFunc = FUNC_WAIT; + } + } + // ߴٸ... + else if (fCurLen <= fTotalLen && fTotalLen <= fNextLen) + { + if (m_GraphicThingInstance.IsDead() || m_GraphicThingInstance.IsKnockDown()) + { + __DisableSkipCollision(); + + //Tracen(" ¶ ŵ"); + + m_isGoing = FALSE; + + //Tracen("ൿ Ҵ ¶ ŵ"); + } + else + { + switch (m_kMovAfterFunc.eFunc) + { + case FUNC_ATTACK: + { + if (IsWalking()) + EndWalking(); + + __DisableSkipCollision(); + m_isGoing = FALSE; + + BlockMovement(); + SCRIPT_SetPixelPosition(NEW_GetDstPixelPositionRef().x, NEW_GetDstPixelPositionRef().y); + SetAdvancingRotation(m_fDstRot); + SetRotation(m_fDstRot); + + RunNormalAttack(m_fDstRot); + break; + } + + case FUNC_COMBO: + { + if (IsWalking()) + EndWalking(); + + __DisableSkipCollision(); + m_isGoing = FALSE; + + BlockMovement(); + SCRIPT_SetPixelPosition(NEW_GetDstPixelPositionRef().x, NEW_GetDstPixelPositionRef().y); + RunComboAttack(m_fDstRot, m_kMovAfterFunc.uArg); + break; + } + + case FUNC_EMOTION: + { + m_isGoing = FALSE; + m_kMovAfterFunc.eFunc = FUNC_WAIT; + __DisableSkipCollision(); + BlockMovement(); + + DWORD dwMotionNumber = m_kMovAfterFunc.uArg; + DWORD dwTargetVID = m_kMovAfterFunc.uArgExpanded; + __ProcessFunctionEmotion(dwMotionNumber, dwTargetVID, m_kMovAfterFunc.kPosDst); + break; + } + + case FUNC_MOVE: + { + break; + } + + case FUNC_MOB_SKILL: + { + if (IsWalking()) + EndWalking(); + + __DisableSkipCollision(); + m_isGoing = FALSE; + + BlockMovement(); + SCRIPT_SetPixelPosition(NEW_GetDstPixelPositionRef().x, NEW_GetDstPixelPositionRef().y); + SetAdvancingRotation(m_fDstRot); + SetRotation(m_fDstRot); + + m_GraphicThingInstance.InterceptOnceMotion(CRaceMotionData::NAME_SPECIAL_1 + m_kMovAfterFunc.uArg); + break; + } + + default: + { + if (m_kMovAfterFunc.eFunc & FUNC_SKILL) + { + SetAdvancingRotation(m_fDstRot); + BlendRotation(m_fDstRot); + NEW_UseSkill(0, m_kMovAfterFunc.eFunc & 0x7f, m_kMovAfterFunc.uArg&0x0f, (m_kMovAfterFunc.uArg>>4) ? true : false); + } + else + { + //Tracenf("VID %d ų (%f, %f) rot %f", GetVirtualID(), NEW_GetDstPixelPositionRef().x, NEW_GetDstPixelPositionRef().y, m_fDstRot); + + __DisableSkipCollision(); + m_isGoing = FALSE; + + BlockMovement(); + SCRIPT_SetPixelPosition(NEW_GetDstPixelPositionRef().x, NEW_GetDstPixelPositionRef().y); + SetAdvancingRotation(m_fDstRot); + BlendRotation(m_fDstRot); + if (!IsWaiting()) + { + EndWalking(); + } + + //Tracenf("VID %d (%f, %f) rot %f IsWalking %d", GetVirtualID(), NEW_GetDstPixelPositionRef().x, NEW_GetDstPixelPositionRef().y, m_fDstRot, IsWalking()); + } + break; + } + } + + } + } + + } + } + + if (IsWalking() || m_GraphicThingInstance.IsUsingMovingSkill()) + { + float fRotation = m_GraphicThingInstance.GetRotation(); + float fAdvancingRotation = m_GraphicThingInstance.GetAdvancingRotation(); + int iDirection = GetRotatingDirection(fRotation, fAdvancingRotation); + + if (DEGREE_DIRECTION_SAME != m_iRotatingDirection) + { + if (DEGREE_DIRECTION_LEFT == iDirection) + { + fRotation = fmodf(fRotation + m_fRotSpd*m_GraphicThingInstance.GetSecondElapsed(), 360.0f); + } + else if (DEGREE_DIRECTION_RIGHT == iDirection) + { + fRotation = fmodf(fRotation - m_fRotSpd*m_GraphicThingInstance.GetSecondElapsed() + 360.0f, 360.0f); + } + + if (m_iRotatingDirection != GetRotatingDirection(fRotation, fAdvancingRotation)) + { + m_iRotatingDirection = DEGREE_DIRECTION_SAME; + fRotation = fAdvancingRotation; + } + + m_GraphicThingInstance.SetRotation(fRotation); + } + + if (__IsInDustRange()) + { + float fDustDistance = NEW_GetDistanceFromDestPixelPosition(m_kPPosDust); + if (IsMountingHorse()) + { + if (fDustDistance > ms_fHorseDustGap) + { + NEW_GetPixelPosition(&m_kPPosDust); + __AttachEffect(EFFECT_HORSE_DUST); + } + } + else + { + if (fDustDistance > ms_fDustGap) + { + NEW_GetPixelPosition(&m_kPPosDust); + __AttachEffect(EFFECT_DUST); + } + } + } + } +} + +void CInstanceBase::__ProcessFunctionEmotion(DWORD dwMotionNumber, DWORD dwTargetVID, const TPixelPosition & c_rkPosDst) +{ + if (IsWalking()) + EndWalkingWithoutBlending(); + + __EnableChangingTCPState(); + SCRIPT_SetPixelPosition(c_rkPosDst.x, c_rkPosDst.y); + + CInstanceBase * pTargetInstance = CPythonCharacterManager::Instance().GetInstancePtr(dwTargetVID); + if (pTargetInstance) + { + pTargetInstance->__EnableChangingTCPState(); + + if (pTargetInstance->IsWalking()) + pTargetInstance->EndWalkingWithoutBlending(); + + WORD wMotionNumber1 = HIWORD(dwMotionNumber); + WORD wMotionNumber2 = LOWORD(dwMotionNumber); + + int src_job = RaceToJob(GetRace()); + int dst_job = RaceToJob(pTargetInstance->GetRace()); + + NEW_LookAtDestInstance(*pTargetInstance); + m_GraphicThingInstance.InterceptOnceMotion(wMotionNumber1 + dst_job); + m_GraphicThingInstance.SetRotation(m_GraphicThingInstance.GetTargetRotation()); + m_GraphicThingInstance.SetAdvancingRotation(m_GraphicThingInstance.GetTargetRotation()); + + pTargetInstance->NEW_LookAtDestInstance(*this); + pTargetInstance->m_GraphicThingInstance.InterceptOnceMotion(wMotionNumber2 + src_job); + pTargetInstance->m_GraphicThingInstance.SetRotation(pTargetInstance->m_GraphicThingInstance.GetTargetRotation()); + pTargetInstance->m_GraphicThingInstance.SetAdvancingRotation(pTargetInstance->m_GraphicThingInstance.GetTargetRotation()); + + if (pTargetInstance->__IsMainInstance()) + { + IAbstractPlayer & rPlayer=IAbstractPlayer::GetSingleton(); + rPlayer.EndEmotionProcess(); + } + } + + if (__IsMainInstance()) + { + IAbstractPlayer & rPlayer=IAbstractPlayer::GetSingleton(); + rPlayer.EndEmotionProcess(); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Update & Deform & Render + +int g_iAccumulationTime = 0; + +void CInstanceBase::Update() +{ + ++ms_dwUpdateCounter; + + StateProcess(); + m_GraphicThingInstance.PhysicsProcess(); + m_GraphicThingInstance.RotationProcess(); + m_GraphicThingInstance.ComboProcess(); + m_GraphicThingInstance.AccumulationMovement(); + + if (m_GraphicThingInstance.IsMovement()) + { + TPixelPosition kPPosCur; + NEW_GetPixelPosition(&kPPosCur); + + DWORD dwCurTime=ELTimer_GetFrameMSec(); + //if (m_dwNextUpdateHeightTimeHORSE_MotionProcess(FALSE); + } + + __ComboProcess(); + + ProcessDamage(); + +} + +void CInstanceBase::Transform() +{ + if (__IsSyncing()) + { + //OnSyncing(); + } + else + { + if (IsWalking() || m_GraphicThingInstance.IsUsingMovingSkill()) + { + const D3DXVECTOR3& c_rv3Movment=m_GraphicThingInstance.GetMovementVectorRef(); + + float len=(c_rv3Movment.x*c_rv3Movment.x)+(c_rv3Movment.y*c_rv3Movment.y); + if (len>1.0f) + OnMoving(); + else + OnWaiting(); + } + } + + m_GraphicThingInstance.INSTANCEBASE_Transform(); +} + + +void CInstanceBase::Deform() +{ + // 2004.07.17.levites.isShow ViewFrustumCheck + if (!__CanRender()) + return; + + ++ms_dwDeformCounter; + + m_GraphicThingInstance.INSTANCEBASE_Deform(); + + m_kHorse.Deform(); +} + +void CInstanceBase::RenderTrace() +{ + if (!__CanRender()) + return; + + m_GraphicThingInstance.RenderTrace(); +} + + + + +void CInstanceBase::Render() +{ + // 2004.07.17.levites.isShow ViewFrustumCheck + if (!__CanRender()) + return; + + ++ms_dwRenderCounter; + + m_kHorse.Render(); + m_GraphicThingInstance.Render(); + + if (CActorInstance::IsDirLine()) + { + if (NEW_GetDstPixelPositionRef().x != 0.0f) + { + static CScreen s_kScreen; + + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + STATEMANAGER.SaveRenderState(D3DRS_ZENABLE, FALSE); + STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, FALSE); + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); + + TPixelPosition px; + m_GraphicThingInstance.GetPixelPosition(&px); + D3DXVECTOR3 kD3DVt3Cur(px.x, px.y, px.z); + //D3DXVECTOR3 kD3DVt3Cur(NEW_GetSrcPixelPositionRef().x, -NEW_GetSrcPixelPositionRef().y, NEW_GetSrcPixelPositionRef().z); + D3DXVECTOR3 kD3DVt3Dest(NEW_GetDstPixelPositionRef().x, -NEW_GetDstPixelPositionRef().y, NEW_GetDstPixelPositionRef().z); + + //printf("%s %f\n", GetNameString(), kD3DVt3Cur.y - kD3DVt3Dest.y); + //float fdx = NEW_GetDstPixelPositionRef().x - NEW_GetSrcPixelPositionRef().x; + //float fdy = NEW_GetDstPixelPositionRef().y - NEW_GetSrcPixelPositionRef().y; + + s_kScreen.SetDiffuseColor(0.0f, 0.0f, 1.0f); + s_kScreen.RenderLine3d(kD3DVt3Cur.x, kD3DVt3Cur.y, px.z, kD3DVt3Dest.x, kD3DVt3Dest.y, px.z); + STATEMANAGER.RestoreRenderState(D3DRS_ZENABLE); + STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, TRUE); + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, TRUE); + } + } +} + +void CInstanceBase::RenderToShadowMap() +{ + if (IsDoor()) + return; + + if (IsBuilding()) + return; + + if (!__CanRender()) + return; + + if (!__IsExistMainInstance()) + return; + + CInstanceBase* pkInstMain=__GetMainInstancePtr(); + + const float SHADOW_APPLY_DISTANCE = 2500.0f; + + float fDistance=NEW_GetDistanceFromDestInstance(*pkInstMain); + if (fDistance>=SHADOW_APPLY_DISTANCE) + return; + + m_GraphicThingInstance.RenderToShadowMap(); +} + +void CInstanceBase::RenderCollision() +{ + m_GraphicThingInstance.RenderCollisionData(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Setting & Getting Data + +void CInstanceBase::SetVirtualID(DWORD dwVirtualID) +{ + m_GraphicThingInstance.SetVirtualID(dwVirtualID); +} + +void CInstanceBase::SetVirtualNumber(DWORD dwVirtualNumber) +{ + m_dwVirtualNumber = dwVirtualNumber; +} + +void CInstanceBase::SetInstanceType(int iInstanceType) +{ + m_GraphicThingInstance.SetActorType(iInstanceType); +} + +void CInstanceBase::SetAlignment(short sAlignment) +{ + m_sAlignment = sAlignment; + RefreshTextTailTitle(); +} + +void CInstanceBase::SetPKMode(BYTE byPKMode) +{ + if (m_byPKMode == byPKMode) + return; + + m_byPKMode = byPKMode; + + if (__IsMainInstance()) + { + IAbstractPlayer& rPlayer=IAbstractPlayer::GetSingleton(); + rPlayer.NotifyChangePKMode(); + } +} + +void CInstanceBase::SetKiller(bool bFlag) +{ + if (m_isKiller == bFlag) + return; + + m_isKiller = bFlag; + RefreshTextTail(); +} + +void CInstanceBase::SetPartyMemberFlag(bool bFlag) +{ + m_isPartyMember = bFlag; +} + +void CInstanceBase::SetStateFlags(DWORD dwStateFlags) +{ + if (dwStateFlags & ADD_CHARACTER_STATE_KILLER) + SetKiller(TRUE); + else + SetKiller(FALSE); + + if (dwStateFlags & ADD_CHARACTER_STATE_PARTY) + SetPartyMemberFlag(TRUE); + else + SetPartyMemberFlag(FALSE); +} + +void CInstanceBase::SetComboType(UINT uComboType) +{ + m_GraphicThingInstance.SetComboType(uComboType); +} + +const char * CInstanceBase::GetNameString() +{ + return m_stName.c_str(); +} + +DWORD CInstanceBase::GetRace() +{ + return m_dwRace; +} + + +bool CInstanceBase::IsConflictAlignmentInstance(CInstanceBase& rkInstVictim) +{ + if (PK_MODE_PROTECT == rkInstVictim.GetPKMode()) + return false; + + switch (GetAlignmentType()) + { + case ALIGNMENT_TYPE_NORMAL: + case ALIGNMENT_TYPE_WHITE: + if (ALIGNMENT_TYPE_DARK == rkInstVictim.GetAlignmentType()) + return true; + break; + case ALIGNMENT_TYPE_DARK: + if (GetAlignmentType() != rkInstVictim.GetAlignmentType()) + return true; + break; + } + + return false; +} + +void CInstanceBase::SetDuelMode(DWORD type) +{ + m_dwDuelMode = type; +} + +DWORD CInstanceBase::GetDuelMode() +{ + return m_dwDuelMode; +} + +bool CInstanceBase::IsAttackableInstance(CInstanceBase& rkInstVictim) +{ + if (__IsMainInstance()) + { + CPythonPlayer& rkPlayer=CPythonPlayer::Instance(); + if(rkPlayer.IsObserverMode()) + return false; + } + + if (GetVirtualID() == rkInstVictim.GetVirtualID()) + return false; + + if (IsStone()) + { + if (rkInstVictim.IsPC()) + return true; + } + else if (IsPC()) + { + if (rkInstVictim.IsStone()) + return true; + + if (rkInstVictim.IsPC()) + { + if (GetDuelMode()) + { + switch(GetDuelMode()) + { + case DUEL_CANNOTATTACK: + return false; + case DUEL_START: + if(__FindDUELKey(GetVirtualID(),rkInstVictim.GetVirtualID())) + return true; + else + return false; + } + } + if (PK_MODE_GUILD == GetPKMode()) + if (GetGuildID() == rkInstVictim.GetGuildID()) + return false; + + if (rkInstVictim.IsKiller()) + if (!IAbstractPlayer::GetSingleton().IsSamePartyMember(GetVirtualID(), rkInstVictim.GetVirtualID())) + return true; + + if (PK_MODE_PROTECT != GetPKMode()) + { + if (PK_MODE_FREE == GetPKMode()) + { + if (PK_MODE_PROTECT != rkInstVictim.GetPKMode()) + if (!IAbstractPlayer::GetSingleton().IsSamePartyMember(GetVirtualID(), rkInstVictim.GetVirtualID())) + return true; + } + if (PK_MODE_GUILD == GetPKMode()) + { + if (PK_MODE_PROTECT != rkInstVictim.GetPKMode()) + if (!IAbstractPlayer::GetSingleton().IsSamePartyMember(GetVirtualID(), rkInstVictim.GetVirtualID())) + if (GetGuildID() != rkInstVictim.GetGuildID()) + return true; + } + } + + if (IsSameEmpire(rkInstVictim)) + { + if (IsPVPInstance(rkInstVictim)) + return true; + + if (PK_MODE_REVENGE == GetPKMode()) + if (!IAbstractPlayer::GetSingleton().IsSamePartyMember(GetVirtualID(), rkInstVictim.GetVirtualID())) + if (IsConflictAlignmentInstance(rkInstVictim)) + return true; + } + else + { + return true; + } + } + + if (rkInstVictim.IsEnemy()) + return true; + + if (rkInstVictim.IsWoodenDoor()) + return true; + } + else if (IsEnemy()) + { + if (rkInstVictim.IsPC()) + return true; + + if (rkInstVictim.IsBuilding()) + return true; + + } + else if (IsPoly()) + { + if (rkInstVictim.IsPC()) + return true; + + if (rkInstVictim.IsEnemy()) + return true; + } + return false; +} + +bool CInstanceBase::IsTargetableInstance(CInstanceBase& rkInstVictim) +{ + return rkInstVictim.CanPickInstance(); +} + +// 2004. 07. 07. [levites] - ų Ÿ ٲ ذ ڵ +bool CInstanceBase::CanChangeTarget() +{ + return m_GraphicThingInstance.CanChangeTarget(); +} + +// 2004.07.17.levites.isShow ViewFrustumCheck +bool CInstanceBase::CanPickInstance() +{ + if (!__IsInViewFrustum()) + return false; + + if (IsDoor()) + { + if (IsDead()) + return false; + } + + if (IsPC()) + { + if (IsAffect(AFFECT_EUNHYEONG)) + { + if (!__MainCanSeeHiddenThing()) + return false; + } + if (IsAffect(AFFECT_REVIVE_INVISIBILITY)) + return false; + if (IsAffect(AFFECT_INVISIBILITY)) + return false; + } + + if (IsDead()) + return false; + + return true; +} + +bool CInstanceBase::CanViewTargetHP(CInstanceBase& rkInstVictim) +{ + if (rkInstVictim.IsStone()) + return true; + if (rkInstVictim.IsWoodenDoor()) + return true; + if (rkInstVictim.IsEnemy()) + return true; + + return false; +} + +BOOL CInstanceBase::IsPoly() +{ + return m_GraphicThingInstance.IsPoly(); +} + +BOOL CInstanceBase::IsPC() +{ + return m_GraphicThingInstance.IsPC(); +} + +BOOL CInstanceBase::IsNPC() +{ + return m_GraphicThingInstance.IsNPC(); +} + +BOOL CInstanceBase::IsEnemy() +{ + return m_GraphicThingInstance.IsEnemy(); +} + +BOOL CInstanceBase::IsStone() +{ + return m_GraphicThingInstance.IsStone(); +} + + +BOOL CInstanceBase::IsGuildWall() //IsBuilding ǹü IsGuildWall 庮( ) +{ + return IsWall(m_dwRace); +} + + +BOOL CInstanceBase::IsResource() +{ + switch (m_dwVirtualNumber) + { + case 20047: + case 20048: + case 20049: + case 20050: + case 20051: + case 20052: + case 20053: + case 20054: + case 20055: + case 20056: + case 20057: + case 20058: + case 20059: + case 30301: + case 30302: + case 30303: + case 30304: + case 30305: + return TRUE; + } + + return FALSE; +} + +BOOL CInstanceBase::IsWarp() +{ + return m_GraphicThingInstance.IsWarp(); +} + +BOOL CInstanceBase::IsGoto() +{ + return m_GraphicThingInstance.IsGoto(); +} + +BOOL CInstanceBase::IsObject() +{ + return m_GraphicThingInstance.IsObject(); +} + +BOOL CInstanceBase::IsBuilding() +{ + return m_GraphicThingInstance.IsBuilding(); +} + +BOOL CInstanceBase::IsDoor() +{ + return m_GraphicThingInstance.IsDoor(); +} + +BOOL CInstanceBase::IsWoodenDoor() +{ + if (m_GraphicThingInstance.IsDoor()) + { + int vnum = GetVirtualNumber(); + if (vnum == 13000) // + return true; + else if (vnum >= 30111 && vnum <= 30119) // ͹ + return true; + else + return false; + } + else + { + return false; + } +} + +BOOL CInstanceBase::IsStoneDoor() +{ + return m_GraphicThingInstance.IsDoor() && 13001 == GetVirtualNumber(); +} + +BOOL CInstanceBase::IsFlag() +{ + if (GetRace() == 20035) + return TRUE; + if (GetRace() == 20036) + return TRUE; + if (GetRace() == 20037) + return TRUE; + + return FALSE; +} + +BOOL CInstanceBase::IsForceVisible() +{ + if (IsAffect(AFFECT_SHOW_ALWAYS)) + return TRUE; + + if (IsObject() || IsBuilding() || IsDoor() ) + return TRUE; + + return FALSE; +} + +int CInstanceBase::GetInstanceType() +{ + return m_GraphicThingInstance.GetActorType(); +} + +DWORD CInstanceBase::GetVirtualID() +{ + return m_GraphicThingInstance.GetVirtualID(); +} + +DWORD CInstanceBase::GetVirtualNumber() +{ + return m_dwVirtualNumber; +} + +// 2004.07.17.levites.isShow ViewFrustumCheck +bool CInstanceBase::__IsInViewFrustum() +{ + return m_GraphicThingInstance.isShow(); +} + +bool CInstanceBase::__CanRender() +{ + if (!__IsInViewFrustum()) + return false; + if (IsAffect(AFFECT_INVISIBILITY)) + return false; + + return true; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Graphic Control + +bool CInstanceBase::IntersectBoundingBox() +{ + float u, v, t; + return m_GraphicThingInstance.Intersect(&u, &v, &t); +} + +bool CInstanceBase::IntersectDefendingSphere() +{ + return m_GraphicThingInstance.IntersectDefendingSphere(); +} + +float CInstanceBase::GetDistance(CInstanceBase * pkTargetInst) +{ + TPixelPosition TargetPixelPosition; + pkTargetInst->m_GraphicThingInstance.GetPixelPosition(&TargetPixelPosition); + return GetDistance(TargetPixelPosition); +} + +float CInstanceBase::GetDistance(const TPixelPosition & c_rPixelPosition) +{ + TPixelPosition PixelPosition; + m_GraphicThingInstance.GetPixelPosition(&PixelPosition); + + float fdx = PixelPosition.x - c_rPixelPosition.x; + float fdy = PixelPosition.y - c_rPixelPosition.y; + + return sqrtf((fdx*fdx) + (fdy*fdy)); +} + +CActorInstance& CInstanceBase::GetGraphicThingInstanceRef() +{ + return m_GraphicThingInstance; +} + +CActorInstance* CInstanceBase::GetGraphicThingInstancePtr() +{ + return &m_GraphicThingInstance; +} + +void CInstanceBase::RefreshActorInstance() +{ + m_GraphicThingInstance.RefreshActorInstance(); +} + +void CInstanceBase::Refresh(DWORD dwMotIndex, bool isLoop) +{ + RefreshState(dwMotIndex, isLoop); +} + +void CInstanceBase::RestoreRenderMode() +{ + m_GraphicThingInstance.RestoreRenderMode(); +} + +void CInstanceBase::SetAddRenderMode() +{ + m_GraphicThingInstance.SetAddRenderMode(); +} + +void CInstanceBase::SetModulateRenderMode() +{ + m_GraphicThingInstance.SetModulateRenderMode(); +} + +void CInstanceBase::SetRenderMode(int iRenderMode) +{ + m_GraphicThingInstance.SetRenderMode(iRenderMode); +} + +void CInstanceBase::SetAddColor(const D3DXCOLOR & c_rColor) +{ + m_GraphicThingInstance.SetAddColor(c_rColor); +} + +void CInstanceBase::__SetBlendRenderingMode() +{ + m_GraphicThingInstance.SetBlendRenderMode(); +} + +void CInstanceBase::__SetAlphaValue(float fAlpha) +{ + m_GraphicThingInstance.SetAlphaValue(fAlpha); +} + +float CInstanceBase::__GetAlphaValue() +{ + return m_GraphicThingInstance.GetAlphaValue(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Part + +void CInstanceBase::SetHair(DWORD eHair) +{ + if (!HAIR_COLOR_ENABLE) + return; + + if (IsPC()==false) + return; + m_awPart[CRaceData::PART_HAIR] = eHair; + m_GraphicThingInstance.SetHair(eHair); +} + +void CInstanceBase::ChangeHair(DWORD eHair) +{ + if (!HAIR_COLOR_ENABLE) + return; + + if (IsPC()==false) + return; + + if (GetPart(CRaceData::PART_HAIR)==eHair) + return; + + SetHair(eHair); + + //int type = m_GraphicThingInstance.GetMotionMode(); + + RefreshState(CRaceMotionData::NAME_WAIT, true); + //RefreshState(type, true); +} + +void CInstanceBase::SetArmor(DWORD dwArmor) +{ + DWORD dwShape; + if (__ArmorVnumToShape(dwArmor, &dwShape)) + { + CItemData * pItemData; + if (CItemManager::Instance().GetItemDataPointer(dwArmor, &pItemData)) + { + float fSpecularPower=pItemData->GetSpecularPowerf(); + SetShape(dwShape, fSpecularPower); + __GetRefinedEffect(pItemData); + return; + } + else + __ClearArmorRefineEffect(); + } + + SetShape(dwArmor); +} + +void CInstanceBase::SetShape(DWORD eShape, float fSpecular) +{ + if (IsPoly()) + { + m_GraphicThingInstance.SetShape(0); + } + else + { + m_GraphicThingInstance.SetShape(eShape, fSpecular); + } + + m_eShape = eShape; +} + + + +DWORD CInstanceBase::GetWeaponType() +{ + DWORD dwWeapon = GetPart(CRaceData::PART_WEAPON); + CItemData * pItemData; + if (!CItemManager::Instance().GetItemDataPointer(dwWeapon, &pItemData)) + return CItemData::WEAPON_NONE; + + return pItemData->GetWeaponType(); +} + +/* +void CInstanceBase::SetParts(const WORD * c_pParts) +{ + if (IsPoly()) + return; + + if (__IsShapeAnimalWear()) + return; + + UINT eWeapon=c_pParts[CRaceData::PART_WEAPON]; + + if (__IsChangableWeapon(eWeapon) == false) + eWeapon = 0; + + if (eWeapon != m_GraphicThingInstance.GetPartItemID(CRaceData::PART_WEAPON)) + { + m_GraphicThingInstance.AttachPart(CRaceData::PART_MAIN, CRaceData::PART_WEAPON, eWeapon); + m_awPart[CRaceData::PART_WEAPON] = eWeapon; + } + + __AttachHorseSaddle(); +} +*/ + +void CInstanceBase::__ClearWeaponRefineEffect() +{ + if (m_swordRefineEffectRight) + { + __DetachEffect(m_swordRefineEffectRight); + m_swordRefineEffectRight = 0; + } + if (m_swordRefineEffectLeft) + { + __DetachEffect(m_swordRefineEffectLeft); + m_swordRefineEffectLeft = 0; + } +} + +void CInstanceBase::__ClearArmorRefineEffect() +{ + if (m_armorRefineEffect) + { + __DetachEffect(m_armorRefineEffect); + m_armorRefineEffect = 0; + } +} + +UINT CInstanceBase::__GetRefinedEffect(CItemData* pItem) +{ + DWORD refine = max(pItem->GetRefine() + pItem->GetSocketCount(),CItemData::ITEM_SOCKET_MAX_NUM) - CItemData::ITEM_SOCKET_MAX_NUM; + switch (pItem->GetType()) + { + case CItemData::ITEM_TYPE_WEAPON: + __ClearWeaponRefineEffect(); + if (refine < 7) // õ 7 ̻ Ʈ ֽϴ. + return 0; + switch(pItem->GetSubType()) + { + case CItemData::WEAPON_DAGGER: + m_swordRefineEffectRight = EFFECT_REFINED+EFFECT_SMALLSWORD_REFINED7+refine-7; + m_swordRefineEffectLeft = EFFECT_REFINED+EFFECT_SMALLSWORD_REFINED7_LEFT+refine-7; + break; + case CItemData::WEAPON_FAN: + m_swordRefineEffectRight = EFFECT_REFINED+EFFECT_FANBELL_REFINED7+refine-7; + break; + case CItemData::WEAPON_ARROW: + case CItemData::WEAPON_BELL: + m_swordRefineEffectRight = EFFECT_REFINED+EFFECT_SMALLSWORD_REFINED7+refine-7; + break; + case CItemData::WEAPON_BOW: + m_swordRefineEffectRight = EFFECT_REFINED+EFFECT_BOW_REFINED7+refine-7; + break; + default: + m_swordRefineEffectRight = EFFECT_REFINED+EFFECT_SWORD_REFINED7+refine-7; + } + if (m_swordRefineEffectRight) + m_swordRefineEffectRight = __AttachEffect(m_swordRefineEffectRight); + if (m_swordRefineEffectLeft) + m_swordRefineEffectLeft = __AttachEffect(m_swordRefineEffectLeft); + break; + case CItemData::ITEM_TYPE_ARMOR: + __ClearArmorRefineEffect(); + + // Ưȭ Ʈ + if (pItem->GetSubType() == CItemData::ARMOR_BODY) + { + DWORD vnum = pItem->GetIndex(); + + if (12010 <= vnum && vnum <= 12049) + { + __AttachEffect(EFFECT_REFINED+EFFECT_BODYARMOR_SPECIAL); + __AttachEffect(EFFECT_REFINED+EFFECT_BODYARMOR_SPECIAL2); + } + } + + if (refine < 7) // õ 7 ̻ Ʈ ֽϴ. + return 0; + + if (pItem->GetSubType() == CItemData::ARMOR_BODY) + { + m_armorRefineEffect = EFFECT_REFINED+EFFECT_BODYARMOR_REFINED7+refine-7; + __AttachEffect(m_armorRefineEffect); + } + break; + } + return 0; +} + +bool CInstanceBase::SetWeapon(DWORD eWeapon) +{ + if (IsPoly()) + return false; + + if (__IsShapeAnimalWear()) + return false; + + if (__IsChangableWeapon(eWeapon) == false) + eWeapon = 0; + + m_GraphicThingInstance.AttachWeapon(eWeapon); + m_awPart[CRaceData::PART_WEAPON] = eWeapon; + + //Weapon Effect + CItemData * pItemData; + if (CItemManager::Instance().GetItemDataPointer(eWeapon, &pItemData)) + __GetRefinedEffect(pItemData); + else + __ClearWeaponRefineEffect(); + + return true; +} + +void CInstanceBase::ChangeWeapon(DWORD eWeapon) +{ + if (eWeapon == m_GraphicThingInstance.GetPartItemID(CRaceData::PART_WEAPON)) + return; + + if (SetWeapon(eWeapon)) + RefreshState(CRaceMotionData::NAME_WAIT, true); +} + +bool CInstanceBase::ChangeArmor(DWORD dwArmor) +{ + DWORD eShape; + __ArmorVnumToShape(dwArmor, &eShape); + + if (GetShape()==eShape) + return false; + + CAffectFlagContainer kAffectFlagContainer; + kAffectFlagContainer.CopyInstance(m_kAffectFlagContainer); + + DWORD dwVID = GetVirtualID(); + DWORD dwRace = GetRace(); + DWORD eHair = GetPart(CRaceData::PART_HAIR); + DWORD eWeapon = GetPart(CRaceData::PART_WEAPON); + float fRot = GetRotation(); + float fAdvRot = GetAdvancingRotation(); + + if (IsWalking()) + EndWalking(); + + // 2004.07.25.myevan.Ʈ ٴ + ////////////////////////////////////////////////////// + __ClearAffects(); + ////////////////////////////////////////////////////// + + if (!SetRace(dwRace)) + { + TraceError("CPythonCharacterManager::ChangeArmor - SetRace VID[%d] Race[%d] ERROR", dwVID, dwRace); + return false; + } + + SetArmor(dwArmor); + SetHair(eHair); + SetWeapon(eWeapon); + + SetRotation(fRot); + SetAdvancingRotation(fAdvRot); + + __AttachHorseSaddle(); + + RefreshState(CRaceMotionData::NAME_WAIT, TRUE); + + // 2004.07.25.myevan.Ʈ ٴ + ///////////////////////////////////////////////// + SetAffectFlagContainer(kAffectFlagContainer); + ///////////////////////////////////////////////// + + CActorInstance::IEventHandler& rkEventHandler=GetEventHandlerRef(); + rkEventHandler.OnChangeShape(); + + return true; +} + +bool CInstanceBase::__IsShapeAnimalWear() +{ + if (100 == GetShape() || + 101 == GetShape() || + 102 == GetShape() || + 103 == GetShape()) + return true; + + return false; +} + +DWORD CInstanceBase::__GetRaceType() +{ + return m_eRaceType; +} + + +void CInstanceBase::RefreshState(DWORD dwMotIndex, bool isLoop) +{ + DWORD dwPartItemID = m_GraphicThingInstance.GetPartItemID(CRaceData::PART_WEAPON); + + BYTE byItemType = 0xff; + BYTE bySubType = 0xff; + + CItemManager & rkItemMgr = CItemManager::Instance(); + CItemData * pItemData; + + if (rkItemMgr.GetItemDataPointer(dwPartItemID, &pItemData)) + { + byItemType = pItemData->GetType(); + bySubType = pItemData->GetWeaponType(); + } + + if (IsPoly()) + { + SetMotionMode(CRaceMotionData::MODE_GENERAL); + } + else if (IsWearingDress()) + { + SetMotionMode(CRaceMotionData::MODE_WEDDING_DRESS); + } + else if (IsHoldingPickAxe()) + { + if (m_kHorse.IsMounting()) + { + SetMotionMode(CRaceMotionData::MODE_HORSE); + } + else + { + SetMotionMode(CRaceMotionData::MODE_GENERAL); + } + } + else if (CItemData::ITEM_TYPE_ROD == byItemType) + { + if (m_kHorse.IsMounting()) + { + SetMotionMode(CRaceMotionData::MODE_HORSE); + } + else + { + SetMotionMode(CRaceMotionData::MODE_FISHING); + } + } + else if (m_kHorse.IsMounting()) + { + switch (bySubType) + { + case CItemData::WEAPON_SWORD: + SetMotionMode(CRaceMotionData::MODE_HORSE_ONEHAND_SWORD); + break; + + case CItemData::WEAPON_TWO_HANDED: + SetMotionMode(CRaceMotionData::MODE_HORSE_TWOHAND_SWORD); // Only Warrior + break; + + case CItemData::WEAPON_DAGGER: + SetMotionMode(CRaceMotionData::MODE_HORSE_DUALHAND_SWORD); // Only Assassin + break; + + case CItemData::WEAPON_FAN: + SetMotionMode(CRaceMotionData::MODE_HORSE_FAN); // Only Shaman + break; + + case CItemData::WEAPON_BELL: + SetMotionMode(CRaceMotionData::MODE_HORSE_BELL); // Only Shaman + break; + + case CItemData::WEAPON_BOW: + SetMotionMode(CRaceMotionData::MODE_HORSE_BOW); // Only Shaman + break; + + default: + SetMotionMode(CRaceMotionData::MODE_HORSE); + break; + } + } + else + { + switch (bySubType) + { + case CItemData::WEAPON_SWORD: + SetMotionMode(CRaceMotionData::MODE_ONEHAND_SWORD); + break; + + case CItemData::WEAPON_TWO_HANDED: + SetMotionMode(CRaceMotionData::MODE_TWOHAND_SWORD); // Only Warrior + break; + + case CItemData::WEAPON_DAGGER: + SetMotionMode(CRaceMotionData::MODE_DUALHAND_SWORD); // Only Assassin + break; + + case CItemData::WEAPON_BOW: + SetMotionMode(CRaceMotionData::MODE_BOW); // Only Assassin + break; + + case CItemData::WEAPON_FAN: + SetMotionMode(CRaceMotionData::MODE_FAN); // Only Shaman + break; + + case CItemData::WEAPON_BELL: + SetMotionMode(CRaceMotionData::MODE_BELL); // Only Shaman + break; + + case CItemData::WEAPON_ARROW: + default: + SetMotionMode(CRaceMotionData::MODE_GENERAL); + break; + } + } + + if (isLoop) + m_GraphicThingInstance.InterceptLoopMotion(dwMotIndex); + else + m_GraphicThingInstance.InterceptOnceMotion(dwMotIndex); + + RefreshActorInstance(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Device + +void CInstanceBase::RegisterBoundingSphere() +{ + // Stone DeforomNoSkin ϸ + // ϴ ִϸ̼ ִϸ̼ + // ٿ ڽ ø ̷ ʴ´. + if (!IsStone()) + { + m_GraphicThingInstance.DeformNoSkin(); + } + + m_GraphicThingInstance.RegisterBoundingSphere(); +} + +bool CInstanceBase::CreateDeviceObjects() +{ + return m_GraphicThingInstance.CreateDeviceObjects(); +} + +void CInstanceBase::DestroyDeviceObjects() +{ + m_GraphicThingInstance.DestroyDeviceObjects(); +} + +void CInstanceBase::Destroy() +{ + DetachTextTail(); + + DismountHorse(); + + m_kQue_kCmdNew.clear(); + + __EffectContainer_Destroy(); + __StoneSmoke_Destroy(); + + if (__IsMainInstance()) + __ClearMainInstance(); + + m_GraphicThingInstance.Destroy(); + + __Initialize(); +} + +void CInstanceBase::__InitializeRotationSpeed() +{ + SetRotationSpeed(c_fDefaultRotationSpeed); +} + +void CInstanceBase::__Warrior_Initialize() +{ + m_kWarrior.m_dwGeomgyeongEffect=0; +} + +void CInstanceBase::__Initialize() +{ + __Warrior_Initialize(); + __StoneSmoke_Inialize(); + __EffectContainer_Initialize(); + __InitializeRotationSpeed(); + + SetEventHandler(CActorInstance::IEventHandler::GetEmptyPtr()); + + m_kAffectFlagContainer.Clear(); + + m_dwLevel = 0; + m_dwGuildID = 0; + m_dwEmpireID = 0; + + m_eType = 0; + m_eRaceType = 0; + m_eShape = 0; + m_dwRace = 0; + m_dwVirtualNumber = 0; + + m_dwBaseCmdTime=0; + m_dwBaseChkTime=0; + m_dwSkipTime=0; + + m_GraphicThingInstance.Initialize(); + + m_dwAdvActorVID=0; + m_dwLastDmgActorVID=0; + + m_nAverageNetworkGap=0; + m_dwNextUpdateHeightTime=0; + + // Moving by keyboard + m_iRotatingDirection = DEGREE_DIRECTION_SAME; + + // Moving by mouse + m_isTextTail = FALSE; + m_isGoing = FALSE; + NEW_SetSrcPixelPosition(TPixelPosition(0, 0, 0)); + NEW_SetDstPixelPosition(TPixelPosition(0, 0, 0)); + + m_kPPosDust = TPixelPosition(0, 0, 0); + + + m_kQue_kCmdNew.clear(); + + m_dwLastComboIndex = 0; + + m_swordRefineEffectRight = 0; + m_swordRefineEffectLeft = 0; + m_armorRefineEffect = 0; + + m_sAlignment = 0; + m_byPKMode = 0; + m_isKiller = false; + m_isPartyMember = false; + + m_bEnableTCPState = TRUE; + + m_stName = ""; + + memset(m_awPart, 0, sizeof(m_awPart)); + memset(m_adwCRCAffectEffect, 0, sizeof(m_adwCRCAffectEffect)); + //memset(m_adwCRCEmoticonEffect, 0, sizeof(m_adwCRCEmoticonEffect)); + memset(&m_kMovAfterFunc, 0, sizeof(m_kMovAfterFunc)); + + m_bDamageEffectType = false; + m_dwDuelMode = DUEL_NONE; + m_dwEmoticonTime = 0; +} + +CInstanceBase::CInstanceBase() +{ + __Initialize(); +} + +CInstanceBase::~CInstanceBase() +{ + Destroy(); +} + + +void CInstanceBase::GetBoundBox(D3DXVECTOR3 * vtMin, D3DXVECTOR3 * vtMax) +{ + m_GraphicThingInstance.GetBoundBox(vtMin, vtMax); +} + +void CInstanceBase::SetLevel(DWORD dwLvl) +{ + m_dwLevel = dwLvl; +} diff --git a/source/UserInterface/InstanceBase.h b/source/UserInterface/InstanceBase.h new file mode 100644 index 0000000..9df0c81 --- /dev/null +++ b/source/UserInterface/InstanceBase.h @@ -0,0 +1,1132 @@ +#pragma once + +#include "../gamelib/RaceData.h" +#include "../gamelib/ActorInstance.h" + +#include "AffectFlagContainer.h" + +class CInstanceBase +{ + public: + struct SCreateData + { + BYTE m_bType; + DWORD m_dwStateFlags; + DWORD m_dwEmpireID; + DWORD m_dwGuildID; + DWORD m_dwLevel; + DWORD m_dwVID; + DWORD m_dwRace; + DWORD m_dwMovSpd; + DWORD m_dwAtkSpd; + LONG m_lPosX; + LONG m_lPosY; + FLOAT m_fRot; + DWORD m_dwArmor; + DWORD m_dwWeapon; + DWORD m_dwHair; + DWORD m_dwMountVnum; + + short m_sAlignment; + BYTE m_byPKMode; + CAffectFlagContainer m_kAffectFlags; + + std::string m_stName; + + bool m_isMain; + }; + + public: + typedef DWORD TType; + + enum EDirection + { + DIR_NORTH, + DIR_NORTHEAST, + DIR_EAST, + DIR_SOUTHEAST, + DIR_SOUTH, + DIR_SOUTHWEST, + DIR_WEST, + DIR_NORTHWEST, + DIR_MAX_NUM, + }; + + enum + { + FUNC_WAIT, + FUNC_MOVE, + FUNC_ATTACK, + FUNC_COMBO, + FUNC_MOB_SKILL, + FUNC_EMOTION, + FUNC_SKILL = 0x80, + }; + + enum + { + AFFECT_YMIR, + AFFECT_INVISIBILITY, + AFFECT_SPAWN, + + AFFECT_POISON, + AFFECT_SLOW, + AFFECT_STUN, + + AFFECT_DUNGEON_READY, // غ + AFFECT_SHOW_ALWAYS, // AFFECT_DUNGEON_UNIQUE (Ŭ̾Ʈ ø) + + AFFECT_BUILDING_CONSTRUCTION_SMALL, + AFFECT_BUILDING_CONSTRUCTION_LARGE, + AFFECT_BUILDING_UPGRADE, + + AFFECT_MOV_SPEED_POTION, // 11 + AFFECT_ATT_SPEED_POTION, // 12 + + AFFECT_FISH_MIND, // 13 + + AFFECT_JEONGWI, // 14 ȥ + AFFECT_GEOMGYEONG, // 15 ˰ + AFFECT_CHEONGEUN, // 16 õ + AFFECT_GYEONGGONG, // 17 + AFFECT_EUNHYEONG, // 18 + AFFECT_GWIGEOM, // 19 Ͱ + AFFECT_GONGPO, // 20 + AFFECT_JUMAGAP, // 21 ָ + AFFECT_HOSIN, // 22 ȣ + AFFECT_BOHO, // 23 ȣ + AFFECT_KWAESOK, // 24 + AFFECT_HEUKSIN, // 25 żȣ + AFFECT_MUYEONG, // 26 + AFFECT_REVIVE_INVISIBILITY, // 27 Ȱ + AFFECT_FIRE, // 28 + AFFECT_GICHEON, // 29 õ + AFFECT_JEUNGRYEOK, // 30 ¼ + AFFECT_DASH, // 31 뽬 + AFFECT_PABEOP, // 32 Ĺ + AFFECT_FALLEN_CHEONGEUN, // 33 ٿ ׷̵ õ + AFFECT_POLYMORPH, // 34 + AFFECT_WAR_FLAG1, // 35 + AFFECT_WAR_FLAG2, // 36 + AFFECT_WAR_FLAG3, // 37 + AFFECT_CHINA_FIREWORK, // 38 + AFFECT_PREMIUM_SILVER, + AFFECT_PREMIUM_GOLD, + AFFECT_RAMADAN_RING, // 41 ʽ´ Affect + + AFFECT_NUM = 64, + + AFFECT_HWAYEOM = AFFECT_GEOMGYEONG, + }; + + enum + { + NEW_AFFECT_MOV_SPEED = 200, + NEW_AFFECT_ATT_SPEED, + NEW_AFFECT_ATT_GRADE, + NEW_AFFECT_INVISIBILITY, + NEW_AFFECT_STR, + NEW_AFFECT_DEX, // 205 + NEW_AFFECT_CON, + NEW_AFFECT_INT, + NEW_AFFECT_FISH_MIND_PILL, + + NEW_AFFECT_POISON, + NEW_AFFECT_STUN, // 210 + NEW_AFFECT_SLOW, + NEW_AFFECT_DUNGEON_READY, + NEW_AFFECT_DUNGEON_UNIQUE, + + NEW_AFFECT_BUILDING, + NEW_AFFECT_REVIVE_INVISIBLE, // 215 + NEW_AFFECT_FIRE, + NEW_AFFECT_CAST_SPEED, + NEW_AFFECT_HP_RECOVER_CONTINUE, + NEW_AFFECT_SP_RECOVER_CONTINUE, + + NEW_AFFECT_POLYMORPH, // 220 + NEW_AFFECT_MOUNT, + + NEW_AFFECT_WAR_FLAG, // 222 + + NEW_AFFECT_BLOCK_CHAT, // 223 + NEW_AFFECT_CHINA_FIREWORK, + + NEW_AFFECT_BOW_DISTANCE, // 225 + + NEW_AFFECT_EXP_BONUS = 500, // + NEW_AFFECT_ITEM_BONUS = 501, // 尩 + NEW_AFFECT_SAFEBOX = 502, // PREMIUM_SAFEBOX, + NEW_AFFECT_AUTOLOOT = 503, // PREMIUM_AUTOLOOT, + NEW_AFFECT_FISH_MIND = 504, // PREMIUM_FISH_MIND, + NEW_AFFECT_MARRIAGE_FAST = 505, // (ݽ), + NEW_AFFECT_GOLD_BONUS = 506, + + NEW_AFFECT_MALL = 510, // Ʈ + NEW_AFFECT_NO_DEATH_PENALTY = 511, // ȣ (ġ гƼ ѹ ش) + NEW_AFFECT_SKILL_BOOK_BONUS = 512, // (å Ȯ 50% ) + NEW_AFFECT_SKILL_BOOK_NO_DELAY = 513, // ־ (å ) + + NEW_AFFECT_EXP_BONUS_EURO_FREE = 516, // ( 14 ⺻ ȿ) + NEW_AFFECT_EXP_BONUS_EURO_FREE_UNDER_15 = 517, + + NEW_AFFECT_AUTO_HP_RECOVERY = 534, // ڵ HP + NEW_AFFECT_AUTO_SP_RECOVERY = 535, // ڵ SP + + NEW_AFFECT_DRAGON_SOUL_QUALIFIED = 540, + NEW_AFFECT_DRAGON_SOUL_DECK1 = 541, + NEW_AFFECT_DRAGON_SOUL_DECK2 = 542, + + NEW_AFFECT_RAMADAN_ABILITY = 300, + NEW_AFFECT_RAMADAN_RING = 301, // 󸶴 ̺Ʈ Ư ʽ´ + + NEW_AFFECT_NOG_POCKET_ABILITY = 302, + + NEW_AFFECT_QUEST_START_IDX = 1000, + }; + + enum + { + STONE_SMOKE1 = 0, // 99% + STONE_SMOKE2 = 1, // 85% + STONE_SMOKE3 = 2, // 80% + STONE_SMOKE4 = 3, // 60% + STONE_SMOKE5 = 4, // 45% + STONE_SMOKE6 = 5, // 40% + STONE_SMOKE7 = 6, // 20% + STONE_SMOKE8 = 7, // 10% + STONE_SMOKE_NUM = 4, + }; + + enum EBuildingAffect + { + BUILDING_CONSTRUCTION_SMALL = 0, + BUILDING_CONSTRUCTION_LARGE = 1, + BUILDING_UPGRADE = 2, + }; + + enum + { + WEAPON_DUALHAND, + WEAPON_ONEHAND, + WEAPON_TWOHAND, + WEAPON_NUM, + }; + + enum + { + EMPIRE_NONE, + EMPIRE_A, + EMPIRE_B, + EMPIRE_C, + EMPIRE_NUM, + }; + + enum + { + NAMECOLOR_MOB, + NAMECOLOR_NPC, + NAMECOLOR_PC, + NAMECOLOR_PC_END = NAMECOLOR_PC + EMPIRE_NUM, + NAMECOLOR_NORMAL_MOB, + NAMECOLOR_NORMAL_NPC, + NAMECOLOR_NORMAL_PC, + NAMECOLOR_NORMAL_PC_END = NAMECOLOR_NORMAL_PC + EMPIRE_NUM, + NAMECOLOR_EMPIRE_MOB, + NAMECOLOR_EMPIRE_NPC, + NAMECOLOR_EMPIRE_PC, + NAMECOLOR_EMPIRE_PC_END = NAMECOLOR_EMPIRE_PC + EMPIRE_NUM, + NAMECOLOR_FUNC, + NAMECOLOR_PK, + NAMECOLOR_PVP, + NAMECOLOR_PARTY, + NAMECOLOR_WARP, + NAMECOLOR_WAYPOINT, + NAMECOLOR_EXTRA = NAMECOLOR_FUNC + 10, + NAMECOLOR_NUM = NAMECOLOR_EXTRA + 10, + }; + + enum + { + ALIGNMENT_TYPE_WHITE, + ALIGNMENT_TYPE_NORMAL, + ALIGNMENT_TYPE_DARK, + }; + + enum + { + EMOTICON_EXCLAMATION = 1, + EMOTICON_FISH = 11, + EMOTICON_NUM = 128, + + TITLE_NUM = 9, + TITLE_NONE = 4, + }; + + enum //Ʒ ȣ ٲ registerEffect ʵ ٲپ Ѵ. + { + EFFECT_REFINED_NONE, + + EFFECT_SWORD_REFINED7, + EFFECT_SWORD_REFINED8, + EFFECT_SWORD_REFINED9, + + EFFECT_BOW_REFINED7, + EFFECT_BOW_REFINED8, + EFFECT_BOW_REFINED9, + + EFFECT_FANBELL_REFINED7, + EFFECT_FANBELL_REFINED8, + EFFECT_FANBELL_REFINED9, + + EFFECT_SMALLSWORD_REFINED7, + EFFECT_SMALLSWORD_REFINED8, + EFFECT_SMALLSWORD_REFINED9, + + EFFECT_SMALLSWORD_REFINED7_LEFT, + EFFECT_SMALLSWORD_REFINED8_LEFT, + EFFECT_SMALLSWORD_REFINED9_LEFT, + + EFFECT_BODYARMOR_REFINED7, + EFFECT_BODYARMOR_REFINED8, + EFFECT_BODYARMOR_REFINED9, + + EFFECT_BODYARMOR_SPECIAL, // 4-2-1 + EFFECT_BODYARMOR_SPECIAL2, // 4-2-2 + + EFFECT_REFINED_NUM, + }; + + enum DamageFlag + { + DAMAGE_NORMAL = (1<<0), + DAMAGE_POISON = (1<<1), + DAMAGE_DODGE = (1<<2), + DAMAGE_BLOCK = (1<<3), + DAMAGE_PENETRATE= (1<<4), + DAMAGE_CRITICAL = (1<<5), + // -_- + }; + + enum + { + EFFECT_DUST, + EFFECT_STUN, + EFFECT_HIT, + EFFECT_FLAME_ATTACK, + EFFECT_FLAME_HIT, + EFFECT_FLAME_ATTACH, + EFFECT_ELECTRIC_ATTACK, + EFFECT_ELECTRIC_HIT, + EFFECT_ELECTRIC_ATTACH, + EFFECT_SPAWN_APPEAR, + EFFECT_SPAWN_DISAPPEAR, + EFFECT_LEVELUP, + EFFECT_SKILLUP, + EFFECT_HPUP_RED, + EFFECT_SPUP_BLUE, + EFFECT_SPEEDUP_GREEN, + EFFECT_DXUP_PURPLE, + EFFECT_CRITICAL, + EFFECT_PENETRATE, + EFFECT_BLOCK, + EFFECT_DODGE, + EFFECT_FIRECRACKER, + EFFECT_SPIN_TOP, + EFFECT_WEAPON, + EFFECT_WEAPON_END = EFFECT_WEAPON + WEAPON_NUM, + EFFECT_AFFECT, + EFFECT_AFFECT_GYEONGGONG = EFFECT_AFFECT + AFFECT_GYEONGGONG, + EFFECT_AFFECT_KWAESOK = EFFECT_AFFECT + AFFECT_KWAESOK, + EFFECT_AFFECT_END = EFFECT_AFFECT + AFFECT_NUM, + EFFECT_EMOTICON, + EFFECT_EMOTICON_END = EFFECT_EMOTICON + EMOTICON_NUM, + EFFECT_SELECT, + EFFECT_TARGET, + EFFECT_EMPIRE, + EFFECT_EMPIRE_END = EFFECT_EMPIRE + EMPIRE_NUM, + EFFECT_HORSE_DUST, + EFFECT_REFINED, + EFFECT_REFINED_END = EFFECT_REFINED + EFFECT_REFINED_NUM, + EFFECT_DAMAGE_TARGET, + EFFECT_DAMAGE_NOT_TARGET, + EFFECT_DAMAGE_SELFDAMAGE, + EFFECT_DAMAGE_SELFDAMAGE2, + EFFECT_DAMAGE_POISON, + EFFECT_DAMAGE_MISS, + EFFECT_DAMAGE_TARGETMISS, + EFFECT_DAMAGE_CRITICAL, + EFFECT_SUCCESS, + EFFECT_FAIL, + EFFECT_FR_SUCCESS, + EFFECT_LEVELUP_ON_14_FOR_GERMANY, // 14϶ ( ) + EFFECT_LEVELUP_UNDER_15_FOR_GERMANY,// 15϶ ( ) + EFFECT_PERCENT_DAMAGE1, + EFFECT_PERCENT_DAMAGE2, + EFFECT_PERCENT_DAMAGE3, + EFFECT_AUTO_HPUP, + EFFECT_AUTO_SPUP, + EFFECT_RAMADAN_RING_EQUIP, // ʽ´ ߵϴ Ʈ + EFFECT_HALLOWEEN_CANDY_EQUIP, // ҷ ߵϴ Ʈ + EFFECT_HAPPINESS_RING_EQUIP, // ູ ߵϴ Ʈ + EFFECT_LOVE_PENDANT_EQUIP, // ູ ߵϴ Ʈ + EFFECT_TEMP, + EFFECT_NUM, + }; + + enum + { + DUEL_NONE, + DUEL_CANNOTATTACK, + DUEL_START, + }; + + public: + static void DestroySystem(); + static void CreateSystem(UINT uCapacity); + static bool RegisterEffect(UINT eEftType, const char* c_szEftAttachBone, const char* c_szEftName, bool isCache); + static void RegisterTitleName(int iIndex, const char * c_szTitleName); + static bool RegisterNameColor(UINT uIndex, UINT r, UINT g, UINT b); + static bool RegisterTitleColor(UINT uIndex, UINT r, UINT g, UINT b); + static bool ChangeEffectTexture(UINT eEftType, const char* c_szSrcFileName, const char* c_szDstFileName); + + static void SetDustGap(float fDustGap); + static void SetHorseDustGap(float fDustGap); + + static void SetEmpireNameMode(bool isEnable); + static const D3DXCOLOR& GetIndexedNameColor(UINT eNameColor); + + public: + void SetMainInstance(); + + void OnSelected(); + void OnUnselected(); + void OnTargeted(); + void OnUntargeted(); + + protected: + bool __IsExistMainInstance(); + bool __IsMainInstance(); + bool __MainCanSeeHiddenThing(); + float __GetBowRange(); + + protected: + DWORD __AttachEffect(UINT eEftType); + DWORD __AttachEffect(char filename[128]); + void __DetachEffect(DWORD dwEID); + + public: + void CreateSpecialEffect(DWORD iEffectIndex); + void AttachSpecialEffect(DWORD effect); + + protected: + static std::string ms_astAffectEffectAttachBone[EFFECT_NUM]; + static DWORD ms_adwCRCAffectEffect[EFFECT_NUM]; + static float ms_fDustGap; + static float ms_fHorseDustGap; + + public: + CInstanceBase(); + virtual ~CInstanceBase(); + + bool LessRenderOrder(CInstanceBase* pkInst); + + void MountHorse(UINT eRace); + void DismountHorse(); + + // ũƮ ׽Ʈ Լ. ߿ + void SCRIPT_SetAffect(UINT eAffect, bool isVisible); + + float CalculateDistanceSq3d(const TPixelPosition& c_rkPPosDst); + + // Instance Data + bool IsFlyTargetObject(); + void ClearFlyTargetInstance(); + void SetFlyTargetInstance(CInstanceBase& rkInstDst); + void AddFlyTargetInstance(CInstanceBase& rkInstDst); + void AddFlyTargetPosition(const TPixelPosition& c_rkPPosDst); + + float GetFlyTargetDistance(); + + void SetAlpha(float fAlpha); + + void DeleteBlendOut(); + + void AttachTextTail(); + void DetachTextTail(); + void UpdateTextTailLevel(DWORD level); + + void RefreshTextTail(); + void RefreshTextTailTitle(); + + bool Create(const SCreateData& c_rkCreateData); + + bool CreateDeviceObjects(); + void DestroyDeviceObjects(); + + void Destroy(); + + void Update(); + bool UpdateDeleting(); + + void Transform(); + void Deform(); + void Render(); + void RenderTrace(); + void RenderToShadowMap(); + void RenderCollision(); + void RegisterBoundingSphere(); + + // Temporary + void GetBoundBox(D3DXVECTOR3 * vtMin, D3DXVECTOR3 * vtMax); + + void SetNameString(const char* c_szName, int len); + bool SetRace(DWORD dwRaceIndex); + void SetVirtualID(DWORD wVirtualNumber); + void SetVirtualNumber(DWORD dwVirtualNumber); + void SetInstanceType(int iInstanceType); + void SetAlignment(short sAlignment); + void SetPKMode(BYTE byPKMode); + void SetKiller(bool bFlag); + void SetPartyMemberFlag(bool bFlag); + void SetStateFlags(DWORD dwStateFlags); + + void SetArmor(DWORD dwArmor); + void SetShape(DWORD eShape, float fSpecular=0.0f); + void SetHair(DWORD eHair); + bool SetWeapon(DWORD eWeapon); + bool ChangeArmor(DWORD dwArmor); + void ChangeWeapon(DWORD eWeapon); + void ChangeHair(DWORD eHair); + void ChangeGuild(DWORD dwGuildID); + DWORD GetWeaponType(); + + void SetComboType(UINT uComboType); + void SetAttackSpeed(UINT uAtkSpd); + void SetMoveSpeed(UINT uMovSpd); + void SetRotationSpeed(float fRotSpd); + + const char * GetNameString(); + int GetInstanceType(); + DWORD GetPart(CRaceData::EParts part); + DWORD GetShape(); + DWORD GetRace(); + DWORD GetVirtualID(); + DWORD GetVirtualNumber(); + DWORD GetEmpireID(); + DWORD GetGuildID(); + int GetAlignment(); + UINT GetAlignmentGrade(); + int GetAlignmentType(); + BYTE GetPKMode(); + bool IsKiller(); + bool IsPartyMember(); + + void ActDualEmotion(CInstanceBase & rkDstInst, WORD dwMotionNumber1, WORD dwMotionNumber2); + void ActEmotion(DWORD dwMotionNumber); + void LevelUp(); + void SkillUp(); + void UseSpinTop(); + void Revive(); + void Stun(); + void Die(); + void Hide(); + void Show(); + + bool CanAct(); + bool CanMove(); + bool CanAttack(); + bool CanUseSkill(); + bool CanFishing(); + bool IsConflictAlignmentInstance(CInstanceBase& rkInstVictim); + bool IsAttackableInstance(CInstanceBase& rkInstVictim); + bool IsTargetableInstance(CInstanceBase& rkInstVictim); + bool IsPVPInstance(CInstanceBase& rkInstVictim); + bool CanChangeTarget(); + bool CanPickInstance(); + bool CanViewTargetHP(CInstanceBase& rkInstVictim); + + + // Movement + BOOL IsGoing(); + bool NEW_Goto(const TPixelPosition& c_rkPPosDst, float fDstRot); + void EndGoing(); + + void SetRunMode(); + void SetWalkMode(); + + bool IsAffect(UINT uAffect); + BOOL IsInvisibility(); + BOOL IsParalysis(); + BOOL IsGameMaster(); + BOOL IsSameEmpire(CInstanceBase& rkInstDst); + BOOL IsBowMode(); + BOOL IsHandMode(); + BOOL IsFishingMode(); + BOOL IsFishing(); + + BOOL IsWearingDress(); + BOOL IsHoldingPickAxe(); + BOOL IsMountingHorse(); + BOOL IsNewMount(); + BOOL IsForceVisible(); + BOOL IsInSafe(); + BOOL IsEnemy(); + BOOL IsStone(); + BOOL IsResource(); + BOOL IsNPC(); + BOOL IsPC(); + BOOL IsPoly(); + BOOL IsWarp(); + BOOL IsGoto(); + BOOL IsObject(); + BOOL IsDoor(); + BOOL IsBuilding(); + BOOL IsWoodenDoor(); + BOOL IsStoneDoor(); + BOOL IsFlag(); + BOOL IsGuildWall(); + + BOOL IsDead(); + BOOL IsStun(); + BOOL IsSleep(); + BOOL __IsSyncing(); + BOOL IsWaiting(); + BOOL IsWalking(); + BOOL IsPushing(); + BOOL IsAttacking(); + BOOL IsActingEmotion(); + BOOL IsAttacked(); + BOOL IsKnockDown(); + BOOL IsUsingSkill(); + BOOL IsUsingMovingSkill(); + BOOL CanCancelSkill(); + BOOL CanAttackHorseLevel(); + +#ifdef __MOVIE_MODE__ + BOOL IsMovieMode(); // ڿ Ⱥ̴° +#endif + bool NEW_CanMoveToDestPixelPosition(const TPixelPosition& c_rkPPosDst); + + void NEW_SetAdvancingRotationFromPixelPosition(const TPixelPosition& c_rkPPosSrc, const TPixelPosition& c_rkPPosDst); + void NEW_SetAdvancingRotationFromDirPixelPosition(const TPixelPosition& c_rkPPosDir); + bool NEW_SetAdvancingRotationFromDestPixelPosition(const TPixelPosition& c_rkPPosDst); + void SetAdvancingRotation(float fRotation); + + void EndWalking(float fBlendingTime=0.15f); + void EndWalkingWithoutBlending(); + + // Battle + void SetEventHandler(CActorInstance::IEventHandler* pkEventHandler); + + void PushUDPState(DWORD dwCmdTime, const TPixelPosition& c_rkPPosDst, float fDstRot, UINT eFunc, UINT uArg); + void PushTCPState(DWORD dwCmdTime, const TPixelPosition& c_rkPPosDst, float fDstRot, UINT eFunc, UINT uArg); + void PushTCPStateExpanded(DWORD dwCmdTime, const TPixelPosition& c_rkPPosDst, float fDstRot, UINT eFunc, UINT uArg, UINT uTargetVID); + + void NEW_Stop(); + + bool NEW_UseSkill(UINT uSkill, UINT uMot, UINT uMotLoopCount, bool isMovingSkill); + void NEW_Attack(); + void NEW_Attack(float fDirRot); + void NEW_AttackToDestPixelPositionDirection(const TPixelPosition& c_rkPPosDst); + bool NEW_AttackToDestInstanceDirection(CInstanceBase& rkInstDst, IFlyEventHandler* pkFlyHandler); + bool NEW_AttackToDestInstanceDirection(CInstanceBase& rkInstDst); + + bool NEW_MoveToDestPixelPositionDirection(const TPixelPosition& c_rkPPosDst); + void NEW_MoveToDestInstanceDirection(CInstanceBase& rkInstDst); + void NEW_MoveToDirection(float fDirRot); + + float NEW_GetDistanceFromDirPixelPosition(const TPixelPosition& c_rkPPosDir); + float NEW_GetDistanceFromDestPixelPosition(const TPixelPosition& c_rkPPosDst); + float NEW_GetDistanceFromDestInstance(CInstanceBase& rkInstDst); + + float NEW_GetRotation(); + float NEW_GetRotationFromDestPixelPosition(const TPixelPosition& c_rkPPosDst); + float NEW_GetRotationFromDirPixelPosition(const TPixelPosition& c_rkPPosDir); + float NEW_GetRotationFromDestInstance(CInstanceBase& rkInstDst); + + float NEW_GetAdvancingRotationFromDirPixelPosition(const TPixelPosition& c_rkPPosDir); + float NEW_GetAdvancingRotationFromDestPixelPosition(const TPixelPosition& c_rkPPosDst); + float NEW_GetAdvancingRotationFromPixelPosition(const TPixelPosition& c_rkPPosSrc, const TPixelPosition& c_rkPPosDst); + + BOOL NEW_IsClickableDistanceDestPixelPosition(const TPixelPosition& c_rkPPosDst); + BOOL NEW_IsClickableDistanceDestInstance(CInstanceBase& rkInstDst); + + bool NEW_GetFrontInstance(CInstanceBase ** ppoutTargetInstance, float fDistance); + void NEW_GetRandomPositionInFanRange(CInstanceBase& rkInstTarget, TPixelPosition* pkPPosDst); + bool NEW_GetInstanceVectorInFanRange(float fSkillDistance, CInstanceBase& rkInstTarget, std::vector* pkVct_pkInst); + bool NEW_GetInstanceVectorInCircleRange(float fSkillDistance, std::vector* pkVct_pkInst); + + void NEW_SetOwner(DWORD dwOwnerVID); + void NEW_SyncPixelPosition(long & nPPosX, long & nPPosY); + void NEW_SyncCurrentPixelPosition(); + + void NEW_SetPixelPosition(const TPixelPosition& c_rkPPosDst); + + bool NEW_IsLastPixelPosition(); + const TPixelPosition& NEW_GetLastPixelPositionRef(); + + + // Battle + BOOL isNormalAttacking(); + BOOL isComboAttacking(); + MOTION_KEY GetNormalAttackIndex(); + DWORD GetComboIndex(); + float GetAttackingElapsedTime(); + void InputNormalAttack(float fAtkDirRot); + void InputComboAttack(float fAtkDirRot); + + void RunNormalAttack(float fAtkDirRot); + void RunComboAttack(float fAtkDirRot, DWORD wMotionIndex); + + CInstanceBase* FindNearestVictim(); + BOOL CheckAdvancing(); + + + bool AvoidObject(const CGraphicObjectInstance& c_rkBGObj); + bool IsBlockObject(const CGraphicObjectInstance& c_rkBGObj); + void BlockMovement(); + + public: + BOOL CheckAttacking(CInstanceBase& rkInstVictim); + void ProcessHitting(DWORD dwMotionKey, CInstanceBase * pVictimInstance); + void ProcessHitting(DWORD dwMotionKey, BYTE byEventIndex, CInstanceBase * pVictimInstance); + void GetBlendingPosition(TPixelPosition * pPixelPosition); + void SetBlendingPosition(const TPixelPosition & c_rPixelPosition); + + // Fishing + void StartFishing(float frot); + void StopFishing(); + void ReactFishing(); + void CatchSuccess(); + void CatchFail(); + BOOL GetFishingRot(int * pirot); + + // Render Mode + void RestoreRenderMode(); + void SetAddRenderMode(); + void SetModulateRenderMode(); + void SetRenderMode(int iRenderMode); + void SetAddColor(const D3DXCOLOR & c_rColor); + + // Position + void SCRIPT_SetPixelPosition(float fx, float fy); + void NEW_GetPixelPosition(TPixelPosition * pPixelPosition); + + // Rotation + void NEW_LookAtFlyTarget(); + void NEW_LookAtDestInstance(CInstanceBase& rkInstDst); + void NEW_LookAtDestPixelPosition(const TPixelPosition& c_rkPPosDst); + + float GetRotation(); + float GetAdvancingRotation(); + void SetRotation(float fRotation); + void BlendRotation(float fRotation, float fBlendTime = 0.1f); + + void SetDirection(int dir); + void BlendDirection(int dir, float blendTime); + float GetDegreeFromDirection(int dir); + + // Motion + // Motion Deque + BOOL isLock(); + + void SetMotionMode(int iMotionMode); + int GetMotionMode(DWORD dwMotionIndex); + + // Motion + // Pushing Motion + void ResetLocalTime(); + void SetLoopMotion(WORD wMotion, float fBlendTime=0.1f, float fSpeedRatio=1.0f); + void PushOnceMotion(WORD wMotion, float fBlendTime=0.1f, float fSpeedRatio=1.0f); + void PushLoopMotion(WORD wMotion, float fBlendTime=0.1f, float fSpeedRatio=1.0f); + void SetEndStopMotion(); + + // Intersect + bool IntersectDefendingSphere(); + bool IntersectBoundingBox(); + + // Part + //void SetParts(const WORD * c_pParts); + void Refresh(DWORD dwMotIndex, bool isLoop); + + //void AttachEffectByID(DWORD dwParentPartIndex, const char * c_pszBoneName, DWORD dwEffectID, int dwLife = CActorInstance::EFFECT_LIFE_INFINITE ); // msԴϴ. + //void AttachEffectByName(DWORD dwParentPartIndex, const char * c_pszBoneName, const char * c_pszEffectName, int dwLife = CActorInstance::EFFECT_LIFE_INFINITE ); // msԴϴ. + + float GetDistance(CInstanceBase * pkTargetInst); + float GetDistance(const TPixelPosition & c_rPixelPosition); + + // ETC + CActorInstance& GetGraphicThingInstanceRef(); + CActorInstance* GetGraphicThingInstancePtr(); + + bool __Background_IsWaterPixelPosition(const TPixelPosition& c_rkPPos); + bool __Background_GetWaterHeight(const TPixelPosition& c_rkPPos, float* pfHeight); + + // 2004.07.25.myevan.Ʈ ȳ + ///////////////////////////////////////////////////////////// + void __ClearAffectFlagContainer(); + void __ClearAffects(); + ///////////////////////////////////////////////////////////// + + void __SetAffect(UINT eAffect, bool isVisible); + + void SetAffectFlagContainer(const CAffectFlagContainer& c_rkAffectFlagContainer); + + void __SetNormalAffectFlagContainer(const CAffectFlagContainer& c_rkAffectFlagContainer); + void __SetStoneSmokeFlagContainer(const CAffectFlagContainer& c_rkAffectFlagContainer); + + void SetEmoticon(UINT eEmoticon); + void SetFishEmoticon(); + bool IsPossibleEmoticon(); + + protected: + UINT __LessRenderOrder_GetLODLevel(); + void __Initialize(); + void __InitializeRotationSpeed(); + + void __Create_SetName(const SCreateData& c_rkCreateData); + void __Create_SetWarpName(const SCreateData& c_rkCreateData); + + CInstanceBase* __GetMainInstancePtr(); + CInstanceBase* __FindInstancePtr(DWORD dwVID); + + bool __FindRaceType(DWORD dwRace, BYTE* pbType); + DWORD __GetRaceType(); + + bool __IsShapeAnimalWear(); + BOOL __IsChangableWeapon(int iWeaponID); + + void __EnableSkipCollision(); + void __DisableSkipCollision(); + + void __ClearMainInstance(); + + void __Shaman_SetParalysis(bool isParalysis); + void __Warrior_SetGeomgyeongAffect(bool isVisible); + void __Assassin_SetEunhyeongAffect(bool isVisible); + void __SetReviveInvisibilityAffect(bool isVisible); + + BOOL __CanProcessNetworkStatePacket(); + + bool __IsInDustRange(); + + // Emotion + void __ProcessFunctionEmotion(DWORD dwMotionNumber, DWORD dwTargetVID, const TPixelPosition & c_rkPosDst); + void __EnableChangingTCPState(); + void __DisableChangingTCPState(); + BOOL __IsEnableTCPProcess(UINT eCurFunc); + + // 2004.07.17.levites.isShow ViewFrustumCheck + bool __CanRender(); + bool __IsInViewFrustum(); + + // HORSE + void __AttachHorseSaddle(); + void __DetachHorseSaddle(); + + struct SHORSE + { + bool m_isMounting; + CActorInstance* m_pkActor; + + SHORSE(); + ~SHORSE(); + + void Destroy(); + void Create(const TPixelPosition& c_rkPPos, UINT eRace, UINT eHitEffect); + + void SetAttackSpeed(UINT uAtkSpd); + void SetMoveSpeed(UINT uMovSpd); + void Deform(); + void Render(); + CActorInstance& GetActorRef(); + CActorInstance* GetActorPtr(); + + bool IsMounting(); + bool CanAttack(); + bool CanUseSkill(); + + UINT GetLevel(); + bool IsNewMount(); + + void __Initialize(); + } m_kHorse; + + + protected: + // Blend Mode + void __SetBlendRenderingMode(); + void __SetAlphaValue(float fAlpha); + float __GetAlphaValue(); + + void __ComboProcess(); + void MovementProcess(); + void TodoProcess(); + void StateProcess(); + void AttackProcess(); + + void StartWalking(); + float GetLocalTime(); + + void RefreshState(DWORD dwMotIndex, bool isLoop); + void RefreshActorInstance(); + + protected: + void OnSyncing(); + void OnWaiting(); + void OnMoving(); + + void NEW_SetCurPixelPosition(const TPixelPosition& c_rkPPosDst); + void NEW_SetSrcPixelPosition(const TPixelPosition& c_rkPPosDst); + void NEW_SetDstPixelPosition(const TPixelPosition& c_rkPPosDst); + void NEW_SetDstPixelPositionZ(FLOAT z); + + const TPixelPosition& NEW_GetCurPixelPositionRef(); + const TPixelPosition& NEW_GetSrcPixelPositionRef(); + + public: + const TPixelPosition& NEW_GetDstPixelPositionRef(); + + protected: + BOOL m_isTextTail; + + // Instance Data + std::string m_stName; + + DWORD m_awPart[CRaceData::PART_MAX_NUM]; + + DWORD m_dwLevel; + DWORD m_dwEmpireID; + DWORD m_dwGuildID; + + protected: + CAffectFlagContainer m_kAffectFlagContainer; + DWORD m_adwCRCAffectEffect[AFFECT_NUM]; + + UINT __GetRefinedEffect(CItemData* pItem); + void __ClearWeaponRefineEffect(); + void __ClearArmorRefineEffect(); + + protected: + void __AttachSelectEffect(); + void __DetachSelectEffect(); + + void __AttachTargetEffect(); + void __DetachTargetEffect(); + + void __AttachEmpireEffect(DWORD eEmpire); + + protected: + struct SEffectContainer + { + typedef std::map Dict; + Dict m_kDct_dwEftID; + } m_kEffectContainer; + + void __EffectContainer_Initialize(); + void __EffectContainer_Destroy(); + + DWORD __EffectContainer_AttachEffect(DWORD eEffect); + void __EffectContainer_DetachEffect(DWORD eEffect); + + SEffectContainer::Dict& __EffectContainer_GetDict(); + + protected: + struct SStoneSmoke + { + DWORD m_dwEftID; + } m_kStoneSmoke; + + void __StoneSmoke_Inialize(); + void __StoneSmoke_Destroy(); + void __StoneSmoke_Create(DWORD eSmoke); + + + protected: + // Emoticon + //DWORD m_adwCRCEmoticonEffect[EMOTICON_NUM]; + + BYTE m_eType; + BYTE m_eRaceType; + DWORD m_eShape; + DWORD m_dwRace; + DWORD m_dwVirtualNumber; + short m_sAlignment; + BYTE m_byPKMode; + bool m_isKiller; + bool m_isPartyMember; + + // Movement + int m_iRotatingDirection; + + DWORD m_dwAdvActorVID; + DWORD m_dwLastDmgActorVID; + + LONG m_nAverageNetworkGap; + DWORD m_dwNextUpdateHeightTime; + + bool m_isGoing; + + TPixelPosition m_kPPosDust; + + DWORD m_dwLastComboIndex; + + DWORD m_swordRefineEffectRight; + DWORD m_swordRefineEffectLeft; + DWORD m_armorRefineEffect; + + struct SMoveAfterFunc + { + UINT eFunc; + UINT uArg; + + // For Emotion Function + UINT uArgExpanded; + TPixelPosition kPosDst; + }; + + SMoveAfterFunc m_kMovAfterFunc; + + float m_fDstRot; + float m_fAtkPosTime; + float m_fRotSpd; + float m_fMaxRotSpd; + + BOOL m_bEnableTCPState; + + // Graphic Instance + CActorInstance m_GraphicThingInstance; + + + protected: + struct SCommand + { + DWORD m_dwChkTime; + DWORD m_dwCmdTime; + float m_fDstRot; + UINT m_eFunc; + UINT m_uArg; + UINT m_uTargetVID; + TPixelPosition m_kPPosDst; + }; + + typedef std::list CommandQueue; + + DWORD m_dwBaseChkTime; + DWORD m_dwBaseCmdTime; + + DWORD m_dwSkipTime; + + CommandQueue m_kQue_kCmdNew; + + BOOL m_bDamageEffectType; + + struct SEffectDamage + { + DWORD damage; + BYTE flag; + BOOL bSelf; + BOOL bTarget; + }; + + typedef std::list CommandDamageQueue; + CommandDamageQueue m_DamageQueue; + + void ProcessDamage(); + + public: + void AddDamageEffect(DWORD damage,BYTE flag,BOOL bSelf,BOOL bTarget); + + protected: + struct SWarrior + { + DWORD m_dwGeomgyeongEffect; + }; + + SWarrior m_kWarrior; + + void __Warrior_Initialize(); + + public: + static void ClearPVPKeySystem(); + + static void InsertPVPKey(DWORD dwSrcVID, DWORD dwDstVID); + static void InsertPVPReadyKey(DWORD dwSrcVID, DWORD dwDstVID); + static void RemovePVPKey(DWORD dwSrcVID, DWORD dwDstVID); + + static void InsertGVGKey(DWORD dwSrcGuildVID, DWORD dwDstGuildVID); + static void RemoveGVGKey(DWORD dwSrcGuildVID, DWORD dwDstGuildVID); + + static void InsertDUELKey(DWORD dwSrcVID, DWORD dwDstVID); + + UINT GetNameColorIndex(); + + const D3DXCOLOR& GetNameColor(); + const D3DXCOLOR& GetTitleColor(); + + protected: + static DWORD __GetPVPKey(DWORD dwSrcVID, DWORD dwDstVID); + static bool __FindPVPKey(DWORD dwSrcVID, DWORD dwDstVID); + static bool __FindPVPReadyKey(DWORD dwSrcVID, DWORD dwDstVID); + static bool __FindGVGKey(DWORD dwSrcGuildID, DWORD dwDstGuildID); + static bool __FindDUELKey(DWORD dwSrcGuildID, DWORD dwDstGuildID); + + protected: + CActorInstance::IEventHandler* GetEventHandlerPtr(); + CActorInstance::IEventHandler& GetEventHandlerRef(); + + protected: + static float __GetBackgroundHeight(float x, float y); + static DWORD __GetShadowMapColor(float x, float y); + + public: + static void ResetPerformanceCounter(); + static void GetInfo(std::string* pstInfo); + + public: + static CInstanceBase* New(); + static void Delete(CInstanceBase* pkInst); + + static CDynamicPool ms_kPool; + + protected: + static DWORD ms_dwUpdateCounter; + static DWORD ms_dwRenderCounter; + static DWORD ms_dwDeformCounter; + + public: + DWORD GetDuelMode(); + void SetDuelMode(DWORD type); + protected: + DWORD m_dwDuelMode; + DWORD m_dwEmoticonTime; + public: + DWORD GetLevel() const { return m_dwLevel; } + void SetLevel(DWORD dwLvl); +}; + +inline int RaceToJob(int race) +{ + const int JOB_NUM = 4; + return race % JOB_NUM; +} + +inline int RaceToSex(int race) +{ + switch (race) + { + case 0: + case 2: + case 5: + case 7: + return 1; + case 1: + case 3: + case 4: + case 6: + return 0; + + } + return 0; +} \ No newline at end of file diff --git a/source/UserInterface/InstanceBaseBattle.cpp b/source/UserInterface/InstanceBaseBattle.cpp new file mode 100644 index 0000000..94eb4df --- /dev/null +++ b/source/UserInterface/InstanceBaseBattle.cpp @@ -0,0 +1,719 @@ +#include "StdAfx.h" +#include "InstanceBase.h" +#include "PythonBackground.h" +#include "PythonCharacterManager.h" +#include "../PRTerrainLib/Terrain.h" + +float NEW_UnsignedDegreeToSignedDegree(float fUD) +{ + float fSD; + if (fUD>180.0f) + fSD=-(360.0f-fUD); + else if (fUD<-180.0f) + fSD=+(360.0f+fUD); + else + fSD=fUD; + + return fSD; +} + +float NEW_GetSignedDegreeFromDirPixelPosition(const TPixelPosition& kPPosDir) +{ + D3DXVECTOR3 vtDir(kPPosDir.x, -kPPosDir.y, kPPosDir.z); + D3DXVECTOR3 vtDirNormal; + D3DXVec3Normalize(&vtDirNormal, &vtDir); + + D3DXVECTOR3 vtDirNormalStan(0, -1, 0); + float fDirRot = D3DXToDegree(acosf(D3DXVec3Dot(&vtDirNormal, &vtDirNormalStan))); + + if (vtDirNormal.x<0.0f) + fDirRot=-fDirRot; + + return fDirRot; +} + +bool CInstanceBase::IsFlyTargetObject() +{ + return m_GraphicThingInstance.IsFlyTargetObject(); +} + +float CInstanceBase::GetFlyTargetDistance() +{ + return m_GraphicThingInstance.GetFlyTargetDistance(); +} + +void CInstanceBase::ClearFlyTargetInstance() +{ + m_GraphicThingInstance.ClearFlyTarget(); +} + +void CInstanceBase::SetFlyTargetInstance(CInstanceBase& rkInstDst) +{ +// NOTE : NEW_Attack Target ٲܶ ⼭ Ǿ - [levites] +// if (isLock()) +// return; + + m_GraphicThingInstance.SetFlyTarget(rkInstDst.GetGraphicThingInstancePtr()); +} + +void CInstanceBase::AddFlyTargetPosition(const TPixelPosition& c_rkPPosDst) +{ + m_GraphicThingInstance.AddFlyTarget(c_rkPPosDst); +} + +void CInstanceBase::AddFlyTargetInstance(CInstanceBase& rkInstDst) +{ + m_GraphicThingInstance.AddFlyTarget(rkInstDst.GetGraphicThingInstancePtr()); +} + + +float CInstanceBase::NEW_GetDistanceFromDestInstance(CInstanceBase& rkInstDst) +{ + TPixelPosition kPPosDst; + rkInstDst.NEW_GetPixelPosition(&kPPosDst); + + return NEW_GetDistanceFromDestPixelPosition(kPPosDst); +} + +float CInstanceBase::NEW_GetDistanceFromDestPixelPosition(const TPixelPosition& c_rkPPosDst) +{ + TPixelPosition kPPosCur; + NEW_GetPixelPosition(&kPPosCur); + + TPixelPosition kPPosDir; + kPPosDir=c_rkPPosDst-kPPosCur; + + return NEW_GetDistanceFromDirPixelPosition(kPPosDir); +} + +float CInstanceBase::NEW_GetDistanceFromDirPixelPosition(const TPixelPosition& c_rkPPosDir) +{ + return sqrtf(c_rkPPosDir.x*c_rkPPosDir.x+c_rkPPosDir.y*c_rkPPosDir.y); +} + +float CInstanceBase::NEW_GetRotation() +{ + float fCurRot=GetRotation(); + return NEW_UnsignedDegreeToSignedDegree(fCurRot); +} + +float CInstanceBase::NEW_GetRotationFromDirPixelPosition(const TPixelPosition& c_rkPPosDir) +{ + return NEW_GetSignedDegreeFromDirPixelPosition(c_rkPPosDir); +} + +float CInstanceBase::NEW_GetRotationFromDestPixelPosition(const TPixelPosition& c_rkPPosDst) +{ + TPixelPosition kPPosCur; + NEW_GetPixelPosition(&kPPosCur); + + TPixelPosition kPPosDir; + kPPosDir=c_rkPPosDst-kPPosCur; + + return NEW_GetRotationFromDirPixelPosition(kPPosDir); +} + +float CInstanceBase::NEW_GetRotationFromDestInstance(CInstanceBase& rkInstDst) +{ + TPixelPosition kPPosDst; + rkInstDst.NEW_GetPixelPosition(&kPPosDst); + + return NEW_GetRotationFromDestPixelPosition(kPPosDst); +} + +void CInstanceBase::NEW_GetRandomPositionInFanRange(CInstanceBase& rkInstTarget, TPixelPosition* pkPPosDst) +{ + float fDstDirRot=NEW_GetRotationFromDestInstance(rkInstTarget); + + float fRot=frandom(fDstDirRot-10.0f, fDstDirRot+10.0f); + + D3DXMATRIX kMatRot; + D3DXMatrixRotationZ(&kMatRot, D3DXToRadian(-fRot)); + + D3DXVECTOR3 v3Src(0.0f, 8000.0f, 0.0f); + D3DXVECTOR3 v3Pos; + D3DXVec3TransformCoord(&v3Pos, &v3Src, &kMatRot); + + const TPixelPosition& c_rkPPosCur=NEW_GetCurPixelPositionRef(); + //const TPixelPosition& c_rkPPosFront=rkInstTarget.NEW_GetCurPixelPositionRef(); + + pkPPosDst->x=c_rkPPosCur.x+v3Pos.x; + pkPPosDst->y=c_rkPPosCur.y+v3Pos.y; + pkPPosDst->z=__GetBackgroundHeight(c_rkPPosCur.x, c_rkPPosCur.y); +} + +bool CInstanceBase::NEW_GetFrontInstance(CInstanceBase ** ppoutTargetInstance, float fDistance) +{ + const float HALF_FAN_ROT_MIN = 10.0f; + const float HALF_FAN_ROT_MAX = 50.0f; + const float HALF_FAN_ROT_MIN_DISTANCE = 1000.0f; + const float RPM = (HALF_FAN_ROT_MAX-HALF_FAN_ROT_MIN)/HALF_FAN_ROT_MIN_DISTANCE; + + float fDstRot=NEW_GetRotation(); + + std::multimap kMap_pkInstNear; + { + CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance(); + CPythonCharacterManager::CharacterIterator i; + for(i = rkChrMgr.CharacterInstanceBegin(); i!=rkChrMgr.CharacterInstanceEnd(); ++i) + { + CInstanceBase* pkInstEach=*i; + if (pkInstEach==this) + continue; + + if (!IsAttackableInstance(*pkInstEach)) + continue; + + if (NEW_GetDistanceFromDestInstance(*pkInstEach) > fDistance) + continue; + + float fEachInstDistance=min(NEW_GetDistanceFromDestInstance(*pkInstEach), HALF_FAN_ROT_MIN_DISTANCE); + float fEachInstDirRot=NEW_GetRotationFromDestInstance(*pkInstEach); + + float fHalfFanRot=(HALF_FAN_ROT_MAX-HALF_FAN_ROT_MIN)-RPM*fEachInstDistance+HALF_FAN_ROT_MIN; + + float fMinDstDirRot=fDstRot-fHalfFanRot; + float fMaxDstDirRot=fDstRot+fHalfFanRot; + + if (fEachInstDirRot>=fMinDstDirRot && fEachInstDirRot<=fMaxDstDirRot) + kMap_pkInstNear.insert(std::multimap::value_type(fEachInstDistance, pkInstEach)); + } + } + + if (kMap_pkInstNear.empty()) + return false; + + *ppoutTargetInstance = kMap_pkInstNear.begin()->second; + + return true; +} + +// 2004.07.21.levites - ĺ Ÿ +bool CInstanceBase::NEW_GetInstanceVectorInFanRange(float fSkillDistance, CInstanceBase& rkInstTarget, std::vector* pkVct_pkInst) +{ + const float HALF_FAN_ROT_MIN = 20.0f; + const float HALF_FAN_ROT_MAX = 40.0f; + const float HALF_FAN_ROT_MIN_DISTANCE = 1000.0f; + const float RPM = (HALF_FAN_ROT_MAX-HALF_FAN_ROT_MIN)/HALF_FAN_ROT_MIN_DISTANCE; + + float fDstDirRot=NEW_GetRotationFromDestInstance(rkInstTarget); + + // 2004.07.24.myevan - ĺ ִ + std::multimap kMap_pkInstNear; + { + CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance(); + CPythonCharacterManager::CharacterIterator i; + for(i = rkChrMgr.CharacterInstanceBegin(); i!=rkChrMgr.CharacterInstanceEnd(); ++i) + { + CInstanceBase* pkInstEach=*i; + if (pkInstEach==this) + continue; + + // 2004.07.25.myevan - 츸 ߰Ѵ + if (!IsAttackableInstance(*pkInstEach)) + continue; + + // 2004.07.21.levites - ĺ Ÿ + if (m_GraphicThingInstance.IsClickableDistanceDestInstance(pkInstEach->m_GraphicThingInstance, fSkillDistance)) + { + float fEachInstDistance=min(NEW_GetDistanceFromDestInstance(*pkInstEach), HALF_FAN_ROT_MIN_DISTANCE); + float fEachInstDirRot=NEW_GetRotationFromDestInstance(*pkInstEach); + + float fHalfFanRot=(HALF_FAN_ROT_MAX-HALF_FAN_ROT_MIN)-RPM*fEachInstDistance+HALF_FAN_ROT_MIN; + + float fMinDstDirRot=fDstDirRot-fHalfFanRot; + float fMaxDstDirRot=fDstDirRot+fHalfFanRot; + + if (fEachInstDirRot>=fMinDstDirRot && fEachInstDirRot<=fMaxDstDirRot) + kMap_pkInstNear.insert(std::multimap::value_type(fEachInstDistance, pkInstEach)); + } + } + } + + { + std::multimap::iterator i=kMap_pkInstNear.begin(); + for (i=kMap_pkInstNear.begin(); i!=kMap_pkInstNear.end(); ++i) + pkVct_pkInst->push_back(i->second); + } + + if (pkVct_pkInst->empty()) + return false; + + return true; +} + +bool CInstanceBase::NEW_GetInstanceVectorInCircleRange(float fSkillDistance, std::vector* pkVct_pkInst) +{ + std::multimap kMap_pkInstNear; + + { + CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance(); + CPythonCharacterManager::CharacterIterator i; + for(i = rkChrMgr.CharacterInstanceBegin(); i!=rkChrMgr.CharacterInstanceEnd(); ++i) + { + CInstanceBase* pkInstEach=*i; + + // ڽ ߰ ʴ´ + if (pkInstEach==this) + continue; + + // 츸 ߰Ѵ + if (!IsAttackableInstance(*pkInstEach)) + continue; + + if (m_GraphicThingInstance.IsClickableDistanceDestInstance(pkInstEach->m_GraphicThingInstance, fSkillDistance)) + { + float fEachInstDistance=NEW_GetDistanceFromDestInstance(*pkInstEach); + kMap_pkInstNear.insert(std::make_pair(fEachInstDistance, pkInstEach)); + } + } + } + + { + std::multimap::iterator i=kMap_pkInstNear.begin(); + for (i=kMap_pkInstNear.begin(); i!=kMap_pkInstNear.end(); ++i) + pkVct_pkInst->push_back(i->second); + } + + if (pkVct_pkInst->empty()) + return false; + + return true; +} + +BOOL CInstanceBase::NEW_IsClickableDistanceDestPixelPosition(const TPixelPosition& c_rkPPosDst) +{ + float fDistance=NEW_GetDistanceFromDestPixelPosition(c_rkPPosDst); + + if (fDistance>150.0f) + return FALSE; + + return TRUE; +} + +BOOL CInstanceBase::NEW_IsClickableDistanceDestInstance(CInstanceBase& rkInstDst) +{ + float fDistance = 150.0f; + + if (IsBowMode()) + fDistance = __GetBowRange(); + + if (rkInstDst.IsNPC()) + fDistance = 500.0f; + + if (rkInstDst.IsResource()) + fDistance = 100.0f; + + return m_GraphicThingInstance.IsClickableDistanceDestInstance(rkInstDst.m_GraphicThingInstance, fDistance); +} + +bool CInstanceBase::NEW_UseSkill(UINT uSkill, UINT uMot, UINT uMotLoopCount, bool isMovingSkill) +{ + if (IsDead()) + return false; + + if (IsStun()) + return false; + + if (IsKnockDown()) + return false; + + if (isMovingSkill) + { + if (!IsWalking()) + StartWalking(); + + m_isGoing = TRUE; + } + else + { + if (IsWalking()) + EndWalking(); + + m_isGoing = FALSE; + } + + float fCurRot=m_GraphicThingInstance.GetTargetRotation(); + SetAdvancingRotation(fCurRot); + + m_GraphicThingInstance.InterceptOnceMotion(CRaceMotionData::NAME_SKILL + uMot, 0.1f, uSkill, 1.0f); + + m_GraphicThingInstance.__OnUseSkill(uMot, uMotLoopCount, isMovingSkill); + + if (uMotLoopCount > 0) + m_GraphicThingInstance.SetMotionLoopCount(uMotLoopCount); + + return true; +} + +void CInstanceBase::NEW_Attack() +{ + float fDirRot=GetRotation(); + NEW_Attack(fDirRot); +} + +void CInstanceBase::NEW_Attack(float fDirRot) +{ + if (IsDead()) + return; + + if (IsStun()) + return; + + if (IsKnockDown()) + return; + + if (IsUsingSkill()) + return; + + if (IsWalking()) + EndWalking(); + + m_isGoing = FALSE; + + if (IsPoly()) + { + InputNormalAttack(fDirRot); + } + else + { + if (m_kHorse.IsMounting()) + { + InputComboAttack(fDirRot); + } + else + { + InputComboAttack(fDirRot); + } + } +} + + +void CInstanceBase::NEW_AttackToDestPixelPositionDirection(const TPixelPosition& c_rkPPosDst) +{ + float fDirRot=NEW_GetRotationFromDestPixelPosition(c_rkPPosDst); + + NEW_Attack(fDirRot); +} + +bool CInstanceBase::NEW_AttackToDestInstanceDirection(CInstanceBase& rkInstDst, IFlyEventHandler* pkFlyHandler) +{ + return NEW_AttackToDestInstanceDirection(rkInstDst); +} + +bool CInstanceBase::NEW_AttackToDestInstanceDirection(CInstanceBase& rkInstDst) +{ + TPixelPosition kPPosDst; + rkInstDst.NEW_GetPixelPosition(&kPPosDst); + NEW_AttackToDestPixelPositionDirection(kPPosDst); + + return true; +} + +void CInstanceBase::AttackProcess() +{ + if (!m_GraphicThingInstance.CanCheckAttacking()) + return; + + CInstanceBase * pkInstLast = NULL; + CPythonCharacterManager& rkChrMgr = CPythonCharacterManager::Instance(); + CPythonCharacterManager::CharacterIterator i = rkChrMgr.CharacterInstanceBegin(); + while (rkChrMgr.CharacterInstanceEnd()!=i) + { + CInstanceBase* pkInstEach=*i; + ++i; + + // ΰ InstanceType + if (!IsAttackableInstance(*pkInstEach)) + continue; + + if (pkInstEach!=this) + { + if (CheckAttacking(*pkInstEach)) + { + pkInstLast=pkInstEach; + } + } + } + + if (pkInstLast) + { + m_dwLastDmgActorVID=pkInstLast->GetVirtualID(); + } +} + +void CInstanceBase::InputNormalAttack(float fAtkDirRot) +{ + m_GraphicThingInstance.InputNormalAttackCommand(fAtkDirRot); +} + +void CInstanceBase::InputComboAttack(float fAtkDirRot) +{ + m_GraphicThingInstance.InputComboAttackCommand(fAtkDirRot); + __ComboProcess(); +} + +void CInstanceBase::RunNormalAttack(float fAtkDirRot) +{ + EndGoing(); + m_GraphicThingInstance.NormalAttack(fAtkDirRot); +} + +void CInstanceBase::RunComboAttack(float fAtkDirRot, DWORD wMotionIndex) +{ + EndGoing(); + m_GraphicThingInstance.ComboAttack(wMotionIndex, fAtkDirRot); +} + +// ϰ TRUE ΰ ִ +BOOL CInstanceBase::CheckAdvancing() +{ +#ifdef __MOVIE_MODE__ + if (IsMovieMode()) + return FALSE; +#endif + if (!__IsMainInstance() && !IsAttacking()) + { + if (IsPC() && IsWalking()) + { + CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance(); + for(CPythonCharacterManager::CharacterIterator i = rkChrMgr.CharacterInstanceBegin(); i!=rkChrMgr.CharacterInstanceEnd();++i) + { + CInstanceBase* pkInstEach=*i; + if (pkInstEach==this) + continue; + if (!pkInstEach->IsDoor()) + continue; + + if (m_GraphicThingInstance.TestActorCollision(pkInstEach->GetGraphicThingInstanceRef())) + { + BlockMovement(); + return true; + } + } + } + return FALSE; + } + + if (m_GraphicThingInstance.CanSkipCollision()) + { + //Tracenf("%x VID %d 浹 ŵ", ELTimer_GetMSec(), GetVirtualID()); + return FALSE; + } + + + BOOL bUsingSkill = m_GraphicThingInstance.IsUsingSkill(); + + m_dwAdvActorVID = 0; + UINT uCollisionCount=0; + + CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance(); + for(CPythonCharacterManager::CharacterIterator i = rkChrMgr.CharacterInstanceBegin(); i!=rkChrMgr.CharacterInstanceEnd();++i) + { + CInstanceBase* pkInstEach=*i; + if (pkInstEach==this) + continue; + + CActorInstance& rkActorSelf=m_GraphicThingInstance; + CActorInstance& rkActorEach=pkInstEach->GetGraphicThingInstanceRef(); + + //NOTE : Skil Door Type Collisionüũ Ѵ. + if( bUsingSkill && !rkActorEach.IsDoor() ) + continue; + + // Ҽ ִ°? + if (rkActorSelf.TestActorCollision(rkActorEach)) + { + uCollisionCount++; + if (uCollisionCount==2) + { + rkActorSelf.BlockMovement(); + return TRUE; + } + rkActorSelf.AdjustDynamicCollisionMovement(&rkActorEach); + + if (rkActorSelf.TestActorCollision(rkActorEach)) + { + rkActorSelf.BlockMovement(); + return TRUE; + } + else + { + NEW_MoveToDestPixelPositionDirection(NEW_GetDstPixelPositionRef()); + } + } + } + + // ʼӼ üũ + CPythonBackground& rkBG=CPythonBackground::Instance(); + const D3DXVECTOR3 & rv3Position = m_GraphicThingInstance.GetPosition(); + const D3DXVECTOR3 & rv3MoveDirection = m_GraphicThingInstance.GetMovementVectorRef(); + + // NOTE : ̵ Ÿ ũٸ ɰ Ӽ üũ + // 10.0f Ÿ - [levites] + int iStep = int(D3DXVec3Length(&rv3MoveDirection) / 10.0f); + D3DXVECTOR3 v3CheckStep = rv3MoveDirection / float(iStep); + D3DXVECTOR3 v3CheckPosition = rv3Position; + for (int j = 0; j < iStep; ++j) + { + v3CheckPosition += v3CheckStep; + + // Check + if (rkBG.isAttrOn(v3CheckPosition.x, -v3CheckPosition.y, CTerrainImpl::ATTRIBUTE_BLOCK)) + { + BlockMovement(); + //return TRUE; + } + } + + // Check + D3DXVECTOR3 v3NextPosition = rv3Position + rv3MoveDirection; + if (rkBG.isAttrOn(v3NextPosition.x, -v3NextPosition.y, CTerrainImpl::ATTRIBUTE_BLOCK)) + { + BlockMovement(); + return TRUE; + } + + return FALSE; +} + +BOOL CInstanceBase::CheckAttacking(CInstanceBase& rkInstVictim) +{ + if (IsInSafe()) + return FALSE; + + if (rkInstVictim.IsInSafe()) + return FALSE; + +#ifdef __MOVIE_MODE__ + return FALSE; +#endif + + if (!m_GraphicThingInstance.AttackingProcess(rkInstVictim.m_GraphicThingInstance)) + return FALSE; + + return TRUE; +} + +BOOL CInstanceBase::isNormalAttacking() +{ + return m_GraphicThingInstance.isNormalAttacking(); +} + +BOOL CInstanceBase::isComboAttacking() +{ + return m_GraphicThingInstance.isComboAttacking(); +} + +BOOL CInstanceBase::IsUsingSkill() +{ + return m_GraphicThingInstance.IsUsingSkill(); +} + +BOOL CInstanceBase::IsUsingMovingSkill() +{ + return m_GraphicThingInstance.IsUsingMovingSkill(); +} + +BOOL CInstanceBase::CanCancelSkill() +{ + return m_GraphicThingInstance.CanCancelSkill(); +} + +BOOL CInstanceBase::CanAttackHorseLevel() +{ + if (!IsMountingHorse()) + return FALSE; + + return m_kHorse.CanAttack(); +} + +bool CInstanceBase::IsAffect(UINT uAffect) +{ + return m_kAffectFlagContainer.IsSet(uAffect); +} + +MOTION_KEY CInstanceBase::GetNormalAttackIndex() +{ + return m_GraphicThingInstance.GetNormalAttackIndex(); +} + +DWORD CInstanceBase::GetComboIndex() +{ + return m_GraphicThingInstance.GetComboIndex(); +} + +float CInstanceBase::GetAttackingElapsedTime() +{ + return m_GraphicThingInstance.GetAttackingElapsedTime(); +} + +void CInstanceBase::ProcessHitting(DWORD dwMotionKey, CInstanceBase * pVictimInstance) +{ + assert(!"-_-" && "CInstanceBase::ProcessHitting"); + //m_GraphicThingInstance.ProcessSucceedingAttacking(dwMotionKey, pVictimInstance->m_GraphicThingInstance); +} + +void CInstanceBase::ProcessHitting(DWORD dwMotionKey, BYTE byEventIndex, CInstanceBase * pVictimInstance) +{ + assert(!"-_-" && "CInstanceBase::ProcessHitting"); + //m_GraphicThingInstance.ProcessSucceedingAttacking(dwMotionKey, byEventIndex, pVictimInstance->m_GraphicThingInstance); +} + +void CInstanceBase::GetBlendingPosition(TPixelPosition * pPixelPosition) +{ + m_GraphicThingInstance.GetBlendingPosition(pPixelPosition); +} + +void CInstanceBase::SetBlendingPosition(const TPixelPosition & c_rPixelPosition) +{ + m_GraphicThingInstance.SetBlendingPosition(c_rPixelPosition); +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void CInstanceBase::Revive() +{ + m_isGoing=FALSE; + m_GraphicThingInstance.Revive(); + + __AttachHorseSaddle(); +} + +void CInstanceBase::Stun() +{ + NEW_Stop(); + m_GraphicThingInstance.Stun(); + + __AttachEffect(EFFECT_STUN); +} + +void CInstanceBase::Die() +{ + __DetachHorseSaddle(); + + if (IsAffect(AFFECT_SPAWN)) + __AttachEffect(EFFECT_SPAWN_DISAPPEAR); + + // 2004.07.25.Ʈ Ⱥٴ ذ + //////////////////////////////////////// + __ClearAffects(); + //////////////////////////////////////// + + OnUnselected(); + OnUntargeted(); + + m_GraphicThingInstance.Die(); +} + +void CInstanceBase::Hide() +{ + m_GraphicThingInstance.SetAlphaValue(0.0f); + m_GraphicThingInstance.BlendAlphaValue(0.0f, 0.1f); +} + +void CInstanceBase::Show() +{ + m_GraphicThingInstance.SetAlphaValue(1.0f); + m_GraphicThingInstance.BlendAlphaValue(1.0f, 0.1f); +} \ No newline at end of file diff --git a/source/UserInterface/InstanceBaseEffect.cpp b/source/UserInterface/InstanceBaseEffect.cpp new file mode 100644 index 0000000..2e28c8a --- /dev/null +++ b/source/UserInterface/InstanceBaseEffect.cpp @@ -0,0 +1,1138 @@ +#include "StdAfx.h" +#include "InstanceBase.h" +#include "PythonTextTail.h" +#include "AbstractApplication.h" +#include "AbstractPlayer.h" +#include "PythonPlayer.h" +#include "PythonSystem.h" + +#include "../EffectLib/EffectManager.h" +#include "../EffectLib/ParticleSystemData.h" +#include "../EterLib/Camera.h" + +float CInstanceBase::ms_fDustGap; +float CInstanceBase::ms_fHorseDustGap; +DWORD CInstanceBase::ms_adwCRCAffectEffect[CInstanceBase::EFFECT_NUM]; +std::string CInstanceBase::ms_astAffectEffectAttachBone[EFFECT_NUM]; + +#define BYTE_COLOR_TO_D3DX_COLOR(r, g, b) D3DXCOLOR(float(r)/255.0f, float(g)/255.0f, float(b)/255.0f, 1.0f) + +/* +D3DXCOLOR CInstanceBase::ms_kD3DXClrPC(0xFFFFD84D);//1.0f, 0.8470f, 0.3f, 1.0f +D3DXCOLOR CInstanceBase::ms_kD3DXClrNPC(0xFF7BE85E);//0.4823f, 0.9098f, 0.3686f, 1.0f +D3DXCOLOR CInstanceBase::ms_kD3DXClrMOB(0xFFEC170a);//0.9254f, 0.0901f, 0.0392f, 1.0f +D3DXCOLOR CInstanceBase::ms_kD3DXClrPVP(0xFF8532D9); +D3DXCOLOR CInstanceBase::ms_kD3DXClrPVPSelf(0xFFEE36DF); +D3DXCOLOR CInstanceBase::ms_kD3DXClrKiller = BYTE_COLOR_TO_D3DX_COLOR(180, 100, 0); +D3DXCOLOR CInstanceBase::ms_kD3DXClrTitle[CInstanceBase::TITLE_MAX_NUM] = +{ + BYTE_COLOR_TO_D3DX_COLOR( 0, 204, 255), + BYTE_COLOR_TO_D3DX_COLOR( 0, 144, 255), + BYTE_COLOR_TO_D3DX_COLOR( 92, 110, 255), + BYTE_COLOR_TO_D3DX_COLOR(155, 155, 255), + 0xFFFFFFFF, // None + BYTE_COLOR_TO_D3DX_COLOR(207, 117, 0), + BYTE_COLOR_TO_D3DX_COLOR(235, 83, 0), + BYTE_COLOR_TO_D3DX_COLOR(227, 0, 0), + BYTE_COLOR_TO_D3DX_COLOR(255, 0, 0), +}; +*/ + +D3DXCOLOR g_akD3DXClrTitle[CInstanceBase::TITLE_NUM]; +D3DXCOLOR g_akD3DXClrName[CInstanceBase::NAMECOLOR_NUM]; + +std::map g_TitleNameMap; +std::set g_kSet_dwPVPReadyKey; +std::set g_kSet_dwPVPKey; +std::set g_kSet_dwGVGKey; +std::set g_kSet_dwDUELKey; + +bool g_isEmpireNameMode=false; + +void CInstanceBase::SetEmpireNameMode(bool isEnable) +{ + g_isEmpireNameMode=isEnable; + + if (isEnable) + { + g_akD3DXClrName[NAMECOLOR_MOB]=g_akD3DXClrName[NAMECOLOR_EMPIRE_MOB]; + g_akD3DXClrName[NAMECOLOR_NPC]=g_akD3DXClrName[NAMECOLOR_EMPIRE_NPC]; + g_akD3DXClrName[NAMECOLOR_PC]=g_akD3DXClrName[NAMECOLOR_NORMAL_PC]; + + for (UINT uEmpire=1; uEmpire=NAMECOLOR_NUM) + { + static D3DXCOLOR s_kD3DXClrNameDefault(0xffffffff); + return s_kD3DXClrNameDefault; + } + + return g_akD3DXClrName[eNameColor]; +} + +void CInstanceBase::AddDamageEffect(DWORD damage,BYTE flag,BOOL bSelf,BOOL bTarget) +{ + if(CPythonSystem::Instance().IsShowDamage()) + { + SEffectDamage sDamage; + sDamage.bSelf = bSelf; + sDamage.bTarget = bTarget; + sDamage.damage = damage; + sDamage.flag = flag; + m_DamageQueue.push_back(sDamage); + } +} + +void CInstanceBase::ProcessDamage() +{ + if(m_DamageQueue.empty()) + return; + + SEffectDamage sDamage = m_DamageQueue.front(); + + m_DamageQueue.pop_front(); + + DWORD damage = sDamage.damage; + BYTE flag = sDamage.flag; + BOOL bSelf = sDamage.bSelf; + BOOL bTarget = sDamage.bTarget; + + CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera(); + float cameraAngle = GetDegreeFromPosition2(pCamera->GetTarget().x,pCamera->GetTarget().y,pCamera->GetEye().x,pCamera->GetEye().y); + + DWORD FONT_WIDTH = 30; + + CEffectManager& rkEftMgr=CEffectManager::Instance(); + + D3DXVECTOR3 v3Pos = m_GraphicThingInstance.GetPosition(); + v3Pos.z += float(m_GraphicThingInstance.GetHeight()); + + D3DXVECTOR3 v3Rot = D3DXVECTOR3(0.0f, 0.0f, cameraAngle); + + if ( (flag & DAMAGE_DODGE) || (flag & DAMAGE_BLOCK) ) + { + if(bSelf) + rkEftMgr.CreateEffect(ms_adwCRCAffectEffect[EFFECT_DAMAGE_MISS],v3Pos,v3Rot); + else + rkEftMgr.CreateEffect(ms_adwCRCAffectEffect[EFFECT_DAMAGE_TARGETMISS],v3Pos,v3Rot); + //__AttachEffect(EFFECT_DAMAGE_MISS); + return; + } + else if (flag & DAMAGE_CRITICAL) + { + //rkEftMgr.CreateEffect(ms_adwCRCAffectEffect[EFFECT_DAMAGE_CRITICAL],v3Pos,v3Rot); + //return; ڵ ǥ. + } + + std::string strDamageType; + DWORD rdwCRCEft = 0; + /* + if ( (flag & DAMAGE_POISON) ) + { + strDamageType = "poison_"; + rdwCRCEft = EFFECT_DAMAGE_POISON; + } + else + */ + { + if(bSelf) + { + strDamageType = "damage_"; + if(m_bDamageEffectType==0) + rdwCRCEft = EFFECT_DAMAGE_SELFDAMAGE; + else + rdwCRCEft = EFFECT_DAMAGE_SELFDAMAGE2; + m_bDamageEffectType = !m_bDamageEffectType; + } + else if(bTarget == false) + { + strDamageType = "nontarget_"; + rdwCRCEft = EFFECT_DAMAGE_NOT_TARGET; + return;// ȵ. + } + else + { + strDamageType = "target_"; + rdwCRCEft = EFFECT_DAMAGE_TARGET; + } + } + + DWORD index = 0; + DWORD num = 0; + std::vector textures; + while(damage>0) + { + if(index > 7) + { + TraceError("ProcessDamageѷ ɼ"); + break; + } + num = damage%10; + damage /= 10; + char numBuf[MAX_PATH]; + sprintf(numBuf,"%d.dds",num); + textures.push_back("d:/ymir work/effect/affect/damagevalue/"+strDamageType+numBuf); + + rkEftMgr.SetEffectTextures(ms_adwCRCAffectEffect[rdwCRCEft],textures); + + D3DXMATRIX matrix,matTrans; + D3DXMatrixIdentity(&matrix); + matrix._41 = v3Pos.x; + matrix._42 = v3Pos.y; + matrix._43 = v3Pos.z; + D3DXMatrixTranslation(&matrix,v3Pos.x,v3Pos.y,v3Pos.z); + D3DXMatrixMultiply(&matrix,&pCamera->GetInverseViewMatrix(),&matrix); + D3DXMatrixTranslation(&matTrans,FONT_WIDTH*index,0,0); + matTrans._41 = -matTrans._41; + matrix = matTrans*matrix; + D3DXMatrixMultiply(&matrix,&pCamera->GetViewMatrix(),&matrix); + + rkEftMgr.CreateEffect(ms_adwCRCAffectEffect[rdwCRCEft],D3DXVECTOR3(matrix._41,matrix._42,matrix._43) + ,v3Rot); + + textures.clear(); + + index++; + } +} + +void CInstanceBase::AttachSpecialEffect(DWORD effect) +{ + __AttachEffect(effect); +} + +void CInstanceBase::LevelUp() +{ + __AttachEffect(EFFECT_LEVELUP); +} + +void CInstanceBase::SkillUp() +{ + __AttachEffect(EFFECT_SKILLUP); +} + +void CInstanceBase::CreateSpecialEffect(DWORD iEffectIndex) +{ + const D3DXMATRIX & c_rmatGlobal = m_GraphicThingInstance.GetTransform(); + + DWORD dwEffectIndex = CEffectManager::Instance().GetEmptyIndex(); + DWORD dwEffectCRC = ms_adwCRCAffectEffect[iEffectIndex]; + CEffectManager::Instance().CreateEffectInstance(dwEffectIndex, dwEffectCRC); + CEffectManager::Instance().SelectEffectInstance(dwEffectIndex); + CEffectManager::Instance().SetEffectInstanceGlobalMatrix(c_rmatGlobal); +} + +void CInstanceBase::__EffectContainer_Destroy() +{ + SEffectContainer::Dict& rkDctEftID=__EffectContainer_GetDict(); + + SEffectContainer::Dict::iterator i; + for (i=rkDctEftID.begin(); i!=rkDctEftID.end(); ++i) + __DetachEffect(i->second); + + rkDctEftID.clear(); +} + +void CInstanceBase::__EffectContainer_Initialize() +{ + SEffectContainer::Dict& rkDctEftID=__EffectContainer_GetDict(); + rkDctEftID.clear(); +} + +CInstanceBase::SEffectContainer::Dict& CInstanceBase::__EffectContainer_GetDict() +{ + return m_kEffectContainer.m_kDct_dwEftID; +} + +// Return value boolean ID ٲߴϴ +DWORD CInstanceBase::__EffectContainer_AttachEffect(DWORD dwEftKey) +{ + SEffectContainer::Dict& rkDctEftID=__EffectContainer_GetDict(); + SEffectContainer::Dict::iterator f=rkDctEftID.find(dwEftKey); + if (rkDctEftID.end()!=f) + return 0; + + DWORD dwEftID=__AttachEffect(dwEftKey); + rkDctEftID.insert(SEffectContainer::Dict::value_type(dwEftKey, dwEftID)); + return dwEftID; +} + + +void CInstanceBase::__EffectContainer_DetachEffect(DWORD dwEftKey) +{ + SEffectContainer::Dict& rkDctEftID=__EffectContainer_GetDict(); + SEffectContainer::Dict::iterator f=rkDctEftID.find(dwEftKey); + if (rkDctEftID.end()==f) + return; + + __DetachEffect(f->second); + + rkDctEftID.erase(f); +} + +void CInstanceBase::__AttachEmpireEffect(DWORD eEmpire) +{ + if (!__IsExistMainInstance()) + return; + + CInstanceBase* pkInstMain=__GetMainInstancePtr(); + + if (IsWarp()) + return; + if (IsObject()) + return; + if (IsFlag()) + return; + if (IsResource()) + return; + + if (pkInstMain->IsGameMaster()) + { + } + else + { + if (pkInstMain->IsSameEmpire(*this)) + return; + + // HIDE_OTHER_EMPIRE_EUNHYEONG_ASSASSIN + if (IsAffect(AFFECT_EUNHYEONG)) + return; + // END_OF_HIDE_OTHER_EMPIRE_EUNHYEONG_ASSASSIN + } + + if (IsGameMaster()) + return; + + __EffectContainer_AttachEffect(EFFECT_EMPIRE+eEmpire); +} + +void CInstanceBase::__AttachSelectEffect() +{ + __EffectContainer_AttachEffect(EFFECT_SELECT); +} + +void CInstanceBase::__DetachSelectEffect() +{ + __EffectContainer_DetachEffect(EFFECT_SELECT); +} + +void CInstanceBase::__AttachTargetEffect() +{ + __EffectContainer_AttachEffect(EFFECT_TARGET); +} + +void CInstanceBase::__DetachTargetEffect() +{ + __EffectContainer_DetachEffect(EFFECT_TARGET); +} + + +void CInstanceBase::__StoneSmoke_Inialize() +{ + m_kStoneSmoke.m_dwEftID=0; +} + +void CInstanceBase::__StoneSmoke_Destroy() +{ + if (!m_kStoneSmoke.m_dwEftID) + return; + + __DetachEffect(m_kStoneSmoke.m_dwEftID); + m_kStoneSmoke.m_dwEftID=0; +} + +void CInstanceBase::__StoneSmoke_Create(DWORD eSmoke) +{ + m_kStoneSmoke.m_dwEftID=m_GraphicThingInstance.AttachSmokeEffect(eSmoke); +} + +void CInstanceBase::SetAlpha(float fAlpha) +{ + __SetBlendRenderingMode(); + __SetAlphaValue(fAlpha); +} + +bool CInstanceBase::UpdateDeleting() +{ + Update(); + Transform(); + + IAbstractApplication& rApp=IAbstractApplication::GetSingleton(); + + float fAlpha = __GetAlphaValue() - (rApp.GetGlobalElapsedTime() * 1.5f); + __SetAlphaValue(fAlpha); + + if (fAlpha < 0.0f) + return false; + + return true; +} + +void CInstanceBase::DeleteBlendOut() +{ + __SetBlendRenderingMode(); + __SetAlphaValue(1.0f); + DetachTextTail(); + + IAbstractPlayer& rkPlayer=IAbstractPlayer::GetSingleton(); + rkPlayer.NotifyDeletingCharacterInstance(GetVirtualID()); +} + +void CInstanceBase::ClearPVPKeySystem() +{ + g_kSet_dwPVPReadyKey.clear(); + g_kSet_dwPVPKey.clear(); + g_kSet_dwGVGKey.clear(); + g_kSet_dwDUELKey.clear(); +} + +void CInstanceBase::InsertPVPKey(DWORD dwVIDSrc, DWORD dwVIDDst) +{ + DWORD dwPVPKey=__GetPVPKey(dwVIDSrc, dwVIDDst); + + g_kSet_dwPVPKey.insert(dwPVPKey); +} + +void CInstanceBase::InsertPVPReadyKey(DWORD dwVIDSrc, DWORD dwVIDDst) +{ + DWORD dwPVPReadyKey=__GetPVPKey(dwVIDSrc, dwVIDDst); + + g_kSet_dwPVPKey.insert(dwPVPReadyKey); +} + +void CInstanceBase::RemovePVPKey(DWORD dwVIDSrc, DWORD dwVIDDst) +{ + DWORD dwPVPKey=__GetPVPKey(dwVIDSrc, dwVIDDst); + + g_kSet_dwPVPKey.erase(dwPVPKey); +} + +void CInstanceBase::InsertGVGKey(DWORD dwSrcGuildVID, DWORD dwDstGuildVID) +{ + DWORD dwGVGKey = __GetPVPKey(dwSrcGuildVID, dwDstGuildVID); + g_kSet_dwGVGKey.insert(dwGVGKey); +} + +void CInstanceBase::RemoveGVGKey(DWORD dwSrcGuildVID, DWORD dwDstGuildVID) +{ + DWORD dwGVGKey = __GetPVPKey(dwSrcGuildVID, dwDstGuildVID); + g_kSet_dwGVGKey.erase(dwGVGKey); +} + +void CInstanceBase::InsertDUELKey(DWORD dwVIDSrc, DWORD dwVIDDst) +{ + DWORD dwPVPKey=__GetPVPKey(dwVIDSrc, dwVIDDst); + + g_kSet_dwDUELKey.insert(dwPVPKey); +} + +DWORD CInstanceBase::__GetPVPKey(DWORD dwVIDSrc, DWORD dwVIDDst) +{ + if (dwVIDSrc>dwVIDDst) + std::swap(dwVIDSrc, dwVIDDst); + + DWORD awSrc[2]; + awSrc[0]=dwVIDSrc; + awSrc[1]=dwVIDDst; + + const BYTE * s = (const BYTE *) awSrc; + const BYTE * end = s + sizeof(awSrc); + unsigned long h = 0; + + while (s < end) + { + h *= 16777619; + h ^= (BYTE) *(BYTE *) (s++); + } + + return h; +} + +bool CInstanceBase::__FindPVPKey(DWORD dwVIDSrc, DWORD dwVIDDst) +{ + DWORD dwPVPKey=__GetPVPKey(dwVIDSrc, dwVIDDst); + + if (g_kSet_dwPVPKey.end()==g_kSet_dwPVPKey.find(dwPVPKey)) + return false; + + return true; +} + +bool CInstanceBase::__FindPVPReadyKey(DWORD dwVIDSrc, DWORD dwVIDDst) +{ + DWORD dwPVPKey=__GetPVPKey(dwVIDSrc, dwVIDDst); + + if (g_kSet_dwPVPReadyKey.end()==g_kSet_dwPVPReadyKey.find(dwPVPKey)) + return false; + + return true; +} +// ȮҶ. +bool CInstanceBase::__FindGVGKey(DWORD dwSrcGuildID, DWORD dwDstGuildID) +{ + DWORD dwGVGKey=__GetPVPKey(dwSrcGuildID, dwDstGuildID); + + if (g_kSet_dwGVGKey.end()==g_kSet_dwGVGKey.find(dwGVGKey)) + return false; + + return true; +} +// 忡 븸 ִ. +bool CInstanceBase::__FindDUELKey(DWORD dwVIDSrc, DWORD dwVIDDst) +{ + DWORD dwDUELKey=__GetPVPKey(dwVIDSrc, dwVIDDst); + + if (g_kSet_dwDUELKey.end()==g_kSet_dwDUELKey.find(dwDUELKey)) + return false; + + return true; +} + +bool CInstanceBase::IsPVPInstance(CInstanceBase& rkInstSel) +{ + DWORD dwVIDSrc=GetVirtualID(); + DWORD dwVIDDst=rkInstSel.GetVirtualID(); + + DWORD dwGuildIDSrc=GetGuildID(); + DWORD dwGuildIDDst=rkInstSel.GetGuildID(); + + if (GetDuelMode()) // ϶ ~_~ + return true; + + return __FindPVPKey(dwVIDSrc, dwVIDDst) || __FindGVGKey(dwGuildIDSrc, dwGuildIDDst); + //__FindDUELKey(dwVIDSrc, dwVIDDst); +} + +const D3DXCOLOR& CInstanceBase::GetNameColor() +{ + return GetIndexedNameColor(GetNameColorIndex()); +} + +UINT CInstanceBase::GetNameColorIndex() +{ + if (IsPC()) + { + if (m_isKiller) + { + return NAMECOLOR_PK; + } + + if (__IsExistMainInstance() && !__IsMainInstance()) + { + CInstanceBase* pkInstMain=__GetMainInstancePtr(); + if (!pkInstMain) + { + TraceError("CInstanceBase::GetNameColorIndex - MainInstance is NULL"); + return NAMECOLOR_PC; + } + DWORD dwVIDMain=pkInstMain->GetVirtualID(); + DWORD dwVIDSelf=GetVirtualID(); + + if (pkInstMain->GetDuelMode()) + { + switch(pkInstMain->GetDuelMode()) + { + case DUEL_CANNOTATTACK: + return NAMECOLOR_PC + GetEmpireID(); + case DUEL_START: + if(__FindDUELKey(dwVIDMain, dwVIDSelf)) + return NAMECOLOR_PVP; + else + return NAMECOLOR_PC + GetEmpireID(); + } + } + + if (pkInstMain->IsSameEmpire(*this)) + { + if (__FindPVPKey(dwVIDMain, dwVIDSelf)) + { + return NAMECOLOR_PVP; + } + + DWORD dwGuildIDMain=pkInstMain->GetGuildID(); + DWORD dwGuildIDSelf=GetGuildID(); + if (__FindGVGKey(dwGuildIDMain, dwGuildIDSelf)) + { + return NAMECOLOR_PVP; + } + /* + if (__FindDUELKey(dwVIDMain, dwVIDSelf)) + { + return NAMECOLOR_PVP; + } + */ + } + else + { + return NAMECOLOR_PVP; + } + } + + IAbstractPlayer& rPlayer=IAbstractPlayer::GetSingleton(); + if (rPlayer.IsPartyMemberByVID(GetVirtualID())) + return NAMECOLOR_PARTY; + + return NAMECOLOR_PC + GetEmpireID(); + + } + else if (IsNPC()) + { + return NAMECOLOR_NPC; + } + else if (IsEnemy()) + { + return NAMECOLOR_MOB; + } + else if (IsPoly()) + { + return NAMECOLOR_MOB; + } + + + return D3DXCOLOR(0xffffffff); +} + +const D3DXCOLOR& CInstanceBase::GetTitleColor() +{ + UINT uGrade = GetAlignmentGrade(); + if ( uGrade >= TITLE_NUM) + { + static D3DXCOLOR s_kD3DXClrTitleDefault(0xffffffff); + return s_kD3DXClrTitleDefault; + } + + return g_akD3DXClrTitle[uGrade]; +} + +void CInstanceBase::AttachTextTail() +{ + if (m_isTextTail) + { + TraceError("CInstanceBase::AttachTextTail - VID [%d] ALREADY EXIST", GetVirtualID()); + return; + } + + m_isTextTail=true; + + DWORD dwVID=GetVirtualID(); + + float fTextTailHeight=IsMountingHorse() ? 110.0f : 10.0f; + + static D3DXCOLOR s_kD3DXClrTextTail=D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); + CPythonTextTail::Instance().RegisterCharacterTextTail(m_dwGuildID, dwVID, s_kD3DXClrTextTail, fTextTailHeight); + + // CHARACTER_LEVEL + if (m_dwLevel) + { + UpdateTextTailLevel(m_dwLevel); + } +} + +void CInstanceBase::DetachTextTail() +{ + if (!m_isTextTail) + return; + + m_isTextTail=false; + CPythonTextTail::Instance().DeleteCharacterTextTail(GetVirtualID()); +} + +void CInstanceBase::UpdateTextTailLevel(DWORD level) +{ + //static D3DXCOLOR s_kLevelColor = D3DXCOLOR(119.0f/255.0f, 246.0f/255.0f, 168.0f/255.0f, 1.0f); + static D3DXCOLOR s_kLevelColor = D3DXCOLOR(152.0f/255.0f, 255.0f/255.0f, 51.0f/255.0f, 1.0f); + + char szText[256]; + sprintf(szText, "Lv %d", level); + CPythonTextTail::Instance().AttachLevel(GetVirtualID(), szText, s_kLevelColor); +} + +void CInstanceBase::RefreshTextTail() +{ + CPythonTextTail::Instance().SetCharacterTextTailColor(GetVirtualID(), GetNameColor()); + + int iAlignmentGrade = GetAlignmentGrade(); + if (TITLE_NONE == iAlignmentGrade) + { + CPythonTextTail::Instance().DetachTitle(GetVirtualID()); + } + else + { + std::map::iterator itor = g_TitleNameMap.find(iAlignmentGrade); + if (g_TitleNameMap.end() != itor) + { + const std::string & c_rstrTitleName = itor->second; + CPythonTextTail::Instance().AttachTitle(GetVirtualID(), c_rstrTitleName.c_str(), GetTitleColor()); + } + } +} + +void CInstanceBase::RefreshTextTailTitle() +{ + RefreshTextTail(); +} + +// 2004.07.25.myevan.Ʈ ٴ ذ +///////////////////////////////////////////////// +void CInstanceBase::__ClearAffectFlagContainer() +{ + m_kAffectFlagContainer.Clear(); +} + +void CInstanceBase::__ClearAffects() +{ + if (IsStone()) + { + __StoneSmoke_Destroy(); + } + else + { + for (int iAffect=0; iAffect=AFFECT_NUM) + { + TraceError("CInstanceBase[VID:%d]::SetAffect(eAffect:%d=EMOTICON_NUM) + { + TraceError("CInstanceBase[VID:%d]::SetEmoticon(eEmoticon:%dGetEye()-v3Pos)*9/10; + v3Pos = pCamera->GetEye()-v3Dir; + + v3Pos = D3DXVECTOR3(0,0,0); + v3Pos.z += float(m_GraphicThingInstance.GetHeight()); + + //rkEftMgr.CreateEffect(ms_adwCRCAffectEffect[EFFECT_EMOTICON+eEmoticon],v3Pos,D3DXVECTOR3(0,0,0)); + m_GraphicThingInstance.AttachEffectByID(0, NULL, ms_adwCRCAffectEffect[EFFECT_EMOTICON+eEmoticon],&v3Pos); + m_dwEmoticonTime = ELTimer_GetMSec(); + } +} + +void CInstanceBase::SetDustGap(float fDustGap) +{ + ms_fDustGap=fDustGap; +} + +void CInstanceBase::SetHorseDustGap(float fDustGap) +{ + ms_fHorseDustGap=fDustGap; +} + +void CInstanceBase::__DetachEffect(DWORD dwEID) +{ + m_GraphicThingInstance.DettachEffect(dwEID); +} + +DWORD CInstanceBase::__AttachEffect(UINT eEftType) +{ + // 2004.07.17.levites.isShow ViewFrustumCheck + if (IsAffect(AFFECT_INVISIBILITY)) + return 0; + + if (eEftType>=EFFECT_NUM) + return 0; + + if (ms_astAffectEffectAttachBone[eEftType].empty()) + { + return m_GraphicThingInstance.AttachEffectByID(0, NULL, ms_adwCRCAffectEffect[eEftType]); + } + else + { + std::string & rstrBoneName = ms_astAffectEffectAttachBone[eEftType]; + const char * c_szBoneName; + // տ Ѵ. + // ̷ ó س ij Equip Bone Name ٸ . + if (0 == rstrBoneName.compare("PART_WEAPON")) + { + if (m_GraphicThingInstance.GetAttachingBoneName(CRaceData::PART_WEAPON, &c_szBoneName)) + { + return m_GraphicThingInstance.AttachEffectByID(0, c_szBoneName, ms_adwCRCAffectEffect[eEftType]); + } + } + else if (0 == rstrBoneName.compare("PART_WEAPON_LEFT")) + { + if (m_GraphicThingInstance.GetAttachingBoneName(CRaceData::PART_WEAPON_LEFT, &c_szBoneName)) + { + return m_GraphicThingInstance.AttachEffectByID(0, c_szBoneName, ms_adwCRCAffectEffect[eEftType]); + } + } + else + { + return m_GraphicThingInstance.AttachEffectByID(0, rstrBoneName.c_str(), ms_adwCRCAffectEffect[eEftType]); + } + } + + return 0; +} + +void CInstanceBase::__ComboProcess() +{ + /* + DWORD dwcurComboIndex = m_GraphicThingInstance.GetComboIndex(); + + if (0 != dwcurComboIndex) + { + if (m_dwLastComboIndex != m_GraphicThingInstance.GetComboIndex()) + { + if (!m_GraphicThingInstance.IsHandMode() & IsAffect(AFFECT_HWAYEOM)) + { + __AttachEffect(EFFECT_FLAME_ATTACK); + } + } + } + + m_dwLastComboIndex = dwcurComboIndex; + */ +} + +bool CInstanceBase::RegisterEffect(UINT eEftType, const char* c_szEftAttachBone, const char* c_szEftName, bool isCache) +{ + if (eEftType>=EFFECT_NUM) + return false; + + ms_astAffectEffectAttachBone[eEftType]=c_szEftAttachBone; + + DWORD& rdwCRCEft=ms_adwCRCAffectEffect[eEftType]; + if (!CEffectManager::Instance().RegisterEffect2(c_szEftName, &rdwCRCEft, isCache)) + { + TraceError("CInstanceBase::RegisterEffect(eEftType=%d, c_szEftAttachBone=%s, c_szEftName=%s, isCache=%d) - Error", eEftType, c_szEftAttachBone, c_szEftName, isCache); + rdwCRCEft=0; + return false; + } + + return true; +} + +void CInstanceBase::RegisterTitleName(int iIndex, const char * c_szTitleName) +{ + g_TitleNameMap.insert(std::make_pair(iIndex, c_szTitleName)); +} + +D3DXCOLOR __RGBToD3DXColoru(UINT r, UINT g, UINT b) +{ + DWORD dwColor=0xff;dwColor<<=8; + dwColor|=r;dwColor<<=8; + dwColor|=g;dwColor<<=8; + dwColor|=b; + + return D3DXCOLOR(dwColor); +} + +bool CInstanceBase::RegisterNameColor(UINT uIndex, UINT r, UINT g, UINT b) +{ + if (uIndex>=NAMECOLOR_NUM) + return false; + + g_akD3DXClrName[uIndex]=__RGBToD3DXColoru(r, g, b); + return true; +} + +bool CInstanceBase::RegisterTitleColor(UINT uIndex, UINT r, UINT g, UINT b) +{ + if (uIndex>=TITLE_NUM) + return false; + + g_akD3DXClrTitle[uIndex]=__RGBToD3DXColoru(r, g, b); + return true; +} diff --git a/source/UserInterface/InstanceBaseEvent.cpp b/source/UserInterface/InstanceBaseEvent.cpp new file mode 100644 index 0000000..a1e9393 --- /dev/null +++ b/source/UserInterface/InstanceBaseEvent.cpp @@ -0,0 +1,17 @@ +#include "StdAfx.h" +#include "InstanceBase.h" + +CActorInstance::IEventHandler& CInstanceBase::GetEventHandlerRef() +{ + return m_GraphicThingInstance.__GetEventHandlerRef(); +} + +CActorInstance::IEventHandler* CInstanceBase::GetEventHandlerPtr() +{ + return m_GraphicThingInstance.__GetEventHandlerPtr(); +} + +void CInstanceBase::SetEventHandler(CActorInstance::IEventHandler* pkEventHandler) +{ + m_GraphicThingInstance.SetEventHandler(pkEventHandler); +} diff --git a/source/UserInterface/InstanceBaseMotion.cpp b/source/UserInterface/InstanceBaseMotion.cpp new file mode 100644 index 0000000..95a35f0 --- /dev/null +++ b/source/UserInterface/InstanceBaseMotion.cpp @@ -0,0 +1,165 @@ +#include "StdAfx.h" +#include "InstanceBase.h" +#include "AbstractPlayer.h" +#include "../gameLib/ActorInstance.h" + +const int c_iFishingRotStep = 8; +const float c_fFishingDistance = 600.0f; + +void CInstanceBase::SetMotionMode(int iMotionMode) +{ + m_GraphicThingInstance.SetMotionMode(iMotionMode); +} + +int CInstanceBase::GetMotionMode(DWORD dwMotionIndex) +{ + return m_GraphicThingInstance.GetMotionMode(); +} + +void CInstanceBase::SetLoopMotion(WORD wMotion, float fBlendTime/* =0.1f */, float fSpeedRatio) +{ + m_GraphicThingInstance.SetLoopMotion(wMotion, fBlendTime, fSpeedRatio); +} + +void CInstanceBase::PushOnceMotion(WORD wMotion, float fBlendTime, float fSpeedRatio) +{ + m_GraphicThingInstance.PushOnceMotion(wMotion, fBlendTime, fSpeedRatio); +} + +void CInstanceBase::PushLoopMotion(WORD wMotion, float fBlendTime, float fSpeedRatio) +{ + m_GraphicThingInstance.PushLoopMotion(wMotion, fBlendTime, fSpeedRatio); +} + +void CInstanceBase::ResetLocalTime() +{ + m_GraphicThingInstance.ResetLocalTime(); +} + +void CInstanceBase::SetEndStopMotion() +{ + m_GraphicThingInstance.SetEndStopMotion(); +} + +BOOL CInstanceBase::isLock() +{ + return m_GraphicThingInstance.isLock(); +} + +void CInstanceBase::StartFishing(float frot) +{ + BlendRotation(frot); + + const TPixelPosition& c_rkPPosCur=m_GraphicThingInstance.NEW_GetCurPixelPositionRef(); + float fRot = m_GraphicThingInstance.GetTargetRotation(); + //float fPlainCoordRot=ELRightCoord_ConvertToPlainCoordDegree(fRightCoordRot); + + TPixelPosition kPPosFishing; + ELPlainCoord_GetRotatedPixelPosition(c_rkPPosCur.x, c_rkPPosCur.y, c_fFishingDistance, fRot, &kPPosFishing.x, &kPPosFishing.y); + if (!__Background_GetWaterHeight(kPPosFishing, &kPPosFishing.z)) + kPPosFishing.z=c_rkPPosCur.z; + + D3DXVECTOR3 v3Fishing; + PixelPositionToD3DXVECTOR3(kPPosFishing, &v3Fishing); + m_GraphicThingInstance.SetFishingPosition(v3Fishing); + + PushOnceMotion(CRaceMotionData::NAME_FISHING_THROW); + PushLoopMotion(CRaceMotionData::NAME_FISHING_WAIT); +} +void CInstanceBase::StopFishing() +{ + m_GraphicThingInstance.InterceptOnceMotion(CRaceMotionData::NAME_FISHING_STOP); + PushLoopMotion(CRaceMotionData::NAME_WAIT); +} +void CInstanceBase::ReactFishing() +{ + PushOnceMotion(CRaceMotionData::NAME_FISHING_REACT); + PushLoopMotion(CRaceMotionData::NAME_FISHING_WAIT); +} +void CInstanceBase::CatchSuccess() +{ + m_GraphicThingInstance.InterceptOnceMotion(CRaceMotionData::NAME_FISHING_CATCH); + PushLoopMotion(CRaceMotionData::NAME_WAIT); +} +void CInstanceBase::CatchFail() +{ + m_GraphicThingInstance.InterceptOnceMotion(CRaceMotionData::NAME_FISHING_FAIL); + PushLoopMotion(CRaceMotionData::NAME_WAIT); +} + +BOOL CInstanceBase::GetFishingRot(int * pirot) +{ + const TPixelPosition& c_rkPPosCur=m_GraphicThingInstance.NEW_GetCurPixelPositionRef(); + float fCharacterRot = m_GraphicThingInstance.GetRotation(); + + //float frot = fCharacterRot; + + for (float fRot=0.0f; fRot<=180.0f; fRot+=10.0f) + { + TPixelPosition kPPosFishingRight; + ELPlainCoord_GetRotatedPixelPosition(c_rkPPosCur.x, c_rkPPosCur.y, c_fFishingDistance, fCharacterRot+fRot, &kPPosFishingRight.x, &kPPosFishingRight.y); + if (__Background_IsWaterPixelPosition(kPPosFishingRight)) + { + *pirot = fCharacterRot+fRot; + return TRUE; + } + + TPixelPosition kPPosFishingLeft; + ELPlainCoord_GetRotatedPixelPosition(c_rkPPosCur.x, c_rkPPosCur.y, c_fFishingDistance, fCharacterRot-fRot, &kPPosFishingLeft.x, &kPPosFishingLeft.y); + if (__Background_IsWaterPixelPosition(kPPosFishingLeft)) + { + *pirot = fCharacterRot-fRot; + return TRUE; + } + } + + return FALSE; +} + +void CInstanceBase::__EnableChangingTCPState() +{ + m_bEnableTCPState = TRUE; +} + +void CInstanceBase::__DisableChangingTCPState() +{ + m_bEnableTCPState = FALSE; +} + +void CInstanceBase::ActDualEmotion(CInstanceBase & rkDstInst, WORD wMotionNumber1, WORD wMotionNumber2) +{ + if (!IsWaiting()) + { + m_GraphicThingInstance.SetLoopMotion(CRaceMotionData::NAME_WAIT, 0.05f); + } + if (!rkDstInst.IsWaiting()) + { + rkDstInst.m_GraphicThingInstance.SetLoopMotion(CRaceMotionData::NAME_WAIT, 0.05f); + } + + const float c_fEmotionDistance = 100.0f; + const TPixelPosition & c_rMainPosition = NEW_GetCurPixelPositionRef(); + const TPixelPosition & c_rTargetPosition = rkDstInst.NEW_GetCurPixelPositionRef(); + TPixelPosition kDirection = c_rMainPosition - c_rTargetPosition; + float fDistance = sqrtf((kDirection.x*kDirection.x) + (kDirection.y*kDirection.y)); + TPixelPosition kDstPosition; + kDstPosition.x = c_rTargetPosition.x + (kDirection.x/fDistance)*c_fEmotionDistance; + kDstPosition.y = c_rTargetPosition.y + (kDirection.y/fDistance)*c_fEmotionDistance; + + DWORD dwCurTime = ELTimer_GetServerMSec() + 500; + PushTCPStateExpanded(dwCurTime, kDstPosition, 0.0f, FUNC_EMOTION, MAKELONG(wMotionNumber1, wMotionNumber2), rkDstInst.GetVirtualID()); + + __DisableChangingTCPState(); + rkDstInst.__DisableChangingTCPState(); + + if (__IsMainInstance() || rkDstInst.__IsMainInstance()) + { + IAbstractPlayer & rPlayer=IAbstractPlayer::GetSingleton(); + rPlayer.StartEmotionProcess(); + } +} + +void CInstanceBase::ActEmotion(DWORD dwMotionNumber) +{ + PushOnceMotion(dwMotionNumber); +} diff --git a/source/UserInterface/InstanceBaseMovement.cpp b/source/UserInterface/InstanceBaseMovement.cpp new file mode 100644 index 0000000..d55d19c --- /dev/null +++ b/source/UserInterface/InstanceBaseMovement.cpp @@ -0,0 +1,356 @@ +#include "StdAfx.h" +#include "InstanceBase.h" +#include "PythonBackground.h" +#include "../eterLib/GrpMath.h" + +void CInstanceBase::SetAttackSpeed(UINT uAtkSpd) +{ + if (uAtkSpd > 1100) + uAtkSpd = 0; + + m_GraphicThingInstance.SetAttackSpeed(uAtkSpd/100.0f); + m_kHorse.SetAttackSpeed(uAtkSpd); +} + +void CInstanceBase::SetMoveSpeed(UINT uMovSpd) +{ + if (uMovSpd > 1100) + uMovSpd = 0; + + m_GraphicThingInstance.SetMoveSpeed(uMovSpd/100.0f); + m_kHorse.SetMoveSpeed(uMovSpd); +} + + +void CInstanceBase::SetRotationSpeed(float fRotSpd) +{ + m_fMaxRotSpd = fRotSpd; +} + +void CInstanceBase::NEW_Stop() +{ + if (__IsSyncing()) + return; + + if (isLock()) + return; + + if (IsUsingSkill()) + return; + + if (!IsWaiting()) + EndWalking(); + + m_GraphicThingInstance.__OnStop(); +} + +void CInstanceBase::NEW_SyncPixelPosition(long & nPPosX, long & nPPosY) +{ + m_GraphicThingInstance.TEMP_Push(nPPosX, nPPosY); +} + +bool CInstanceBase::NEW_CanMoveToDestPixelPosition(const TPixelPosition& c_rkPPosDst) +{ + TPixelPosition kPPosCur; + NEW_GetPixelPosition(&kPPosCur); + + if (kPPosCur.x==c_rkPPosDst.x && kPPosCur.y==c_rkPPosDst.y) + return false; + + return true; +} + +float CInstanceBase_GetDegreeFromPosition(float x, float y) +{ + D3DXVECTOR3 vtDir(floor(x), floor(y), 0.0f); + D3DXVec3Normalize(&vtDir, &vtDir); + + D3DXVECTOR3 vtStan(0, -1, 0); + float ret = D3DXToDegree(acosf(D3DXVec3Dot(&vtDir, &vtStan))); + + if (vtDir.x < 0.0f) + ret = 360.0f - ret; + + return ret; +} + +float CInstanceBase::NEW_GetAdvancingRotationFromDirPixelPosition(const TPixelPosition& c_rkPPosDir) +{ + float fDirRot=CInstanceBase_GetDegreeFromPosition(c_rkPPosDir.x, -c_rkPPosDir.y); + float fClampDirRot=ClampDegree(fDirRot); + + return fClampDirRot; +} + +float CInstanceBase::NEW_GetAdvancingRotationFromDestPixelPosition(const TPixelPosition& c_rkPPosDst) +{ + TPixelPosition kPPosCur; + NEW_GetPixelPosition(&kPPosCur); + return NEW_GetAdvancingRotationFromPixelPosition(kPPosCur, c_rkPPosDst); +} + +float CInstanceBase::NEW_GetAdvancingRotationFromPixelPosition(const TPixelPosition& c_rkPPosSrc, const TPixelPosition& c_rkPPosDst) +{ + TPixelPosition kPPosDelta; + kPPosDelta=c_rkPPosDst-c_rkPPosSrc; + return NEW_GetAdvancingRotationFromDirPixelPosition(kPPosDelta); +} + + +void CInstanceBase::NEW_SetAdvancingRotationFromDirPixelPosition(const TPixelPosition& c_rkPPosDir) +{ + float fClampDirRot=NEW_GetAdvancingRotationFromDirPixelPosition(c_rkPPosDir); + m_GraphicThingInstance.SetAdvancingRotation(fClampDirRot); + + float fCurRot=m_GraphicThingInstance.GetRotation(); + float fAdvRot=m_GraphicThingInstance.GetAdvancingRotation(); + + m_iRotatingDirection = GetRotatingDirection(fCurRot, fAdvRot); +} + + +void CInstanceBase::NEW_SetAdvancingRotationFromPixelPosition(const TPixelPosition& c_rkPPosSrc, const TPixelPosition& c_rkPPosDst) +{ + TPixelPosition kPPosDelta; + kPPosDelta=c_rkPPosDst-c_rkPPosSrc; + + NEW_SetAdvancingRotationFromDirPixelPosition(kPPosDelta); +} + +bool CInstanceBase::NEW_SetAdvancingRotationFromDestPixelPosition(const TPixelPosition& c_rkPPosDst) +{ + if (!NEW_CanMoveToDestPixelPosition(c_rkPPosDst)) + { + Tracenf("Failed to move next position (%f,%f, %f)", c_rkPPosDst.x, c_rkPPosDst.y, c_rkPPosDst.z); + return false; + } + + TPixelPosition kPPosSrc; + NEW_GetPixelPosition(&kPPosSrc); + NEW_SetAdvancingRotationFromPixelPosition(kPPosSrc, c_rkPPosDst); + return true; +} + + +void CInstanceBase::SetAdvancingRotation(float fRotation) +{ + float frotDifference = GetDegreeDifference(GetRotation(), fRotation); + + if (frotDifference > 45.0f) + m_fRotSpd = m_fMaxRotSpd; + else + m_fRotSpd = m_fMaxRotSpd * 5 / 12; + + m_GraphicThingInstance.SetAdvancingRotation(ClampDegree(fRotation)); + m_iRotatingDirection = GetRotatingDirection(m_GraphicThingInstance.GetRotation(), + m_GraphicThingInstance.GetAdvancingRotation()); +} + +void CInstanceBase::StartWalking() +{ + m_GraphicThingInstance.Move(); + + if (IsAffect(AFFECT_GYEONGGONG)) + { + m_adwCRCAffectEffect[AFFECT_GYEONGGONG] = __EffectContainer_AttachEffect(EFFECT_AFFECT_GYEONGGONG); + } + else if (IsAffect(AFFECT_KWAESOK)) + { + m_adwCRCAffectEffect[AFFECT_KWAESOK] = __EffectContainer_AttachEffect(EFFECT_AFFECT_KWAESOK); + } +} + +void CInstanceBase::EndWalking(float fBlendingTime) +{ + assert (!IsWaiting() && "CInstanceBase::EndWalking"); + + m_isGoing = FALSE; + + // Ȱ ߰ ؾ Ѵ + if (IsWalking()||!IsAttacked()) + { + m_GraphicThingInstance.Stop(fBlendingTime); + if (IsAffect(AFFECT_GYEONGGONG)) + { + __EffectContainer_DetachEffect(EFFECT_AFFECT_GYEONGGONG); + } + else if (IsAffect(AFFECT_KWAESOK)) + { + __EffectContainer_DetachEffect(EFFECT_AFFECT_KWAESOK); + } + } +} + +void CInstanceBase::EndWalkingWithoutBlending() +{ + EndWalking(0.0f); +} + +BOOL CInstanceBase::IsWaiting() +{ + return m_GraphicThingInstance.IsWaiting(); +} + +BOOL CInstanceBase::IsWalking() +{ + return m_GraphicThingInstance.IsMoving(); +} + +BOOL CInstanceBase::IsPushing() +{ + return m_GraphicThingInstance.IsPushing(); +} + +BOOL CInstanceBase::IsAttacked() +{ + return m_GraphicThingInstance.IsAttacked(); +} + +BOOL CInstanceBase::IsKnockDown() +{ + if (!m_GraphicThingInstance.IsKnockDown()) + return FALSE; + + return TRUE; +} + +BOOL CInstanceBase::IsAttacking() +{ + return m_GraphicThingInstance.isAttacking(); +} + +BOOL CInstanceBase::IsActingEmotion() +{ + return m_GraphicThingInstance.IsActEmotion(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +BOOL CInstanceBase::IsGoing() +{ + return m_isGoing; +} + +void CInstanceBase::NEW_MoveToDestInstanceDirection(CInstanceBase & rkInstDst) +{ + TPixelPosition kPPosDst; + rkInstDst.NEW_GetPixelPosition(&kPPosDst); + + NEW_MoveToDestPixelPositionDirection(kPPosDst); +} + +bool CInstanceBase::NEW_MoveToDestPixelPositionDirection(const TPixelPosition & c_rkPPosDst) +{ + TPixelPosition kPPosCur; + NEW_GetPixelPosition(&kPPosCur); + float fDstRot = NEW_GetAdvancingRotationFromPixelPosition(kPPosCur, c_rkPPosDst); + + return NEW_Goto(c_rkPPosDst, fDstRot); +} + +bool CInstanceBase::NEW_Goto(const TPixelPosition& c_rkPPosDst, float fDstRot) +{ + if (__IsSyncing()) + { + return false; + } + + if (m_GraphicThingInstance.IsUsingMovingSkill()) + { + SetAdvancingRotation(fDstRot); + return true; + } + + if (isLock()) + { + return false; + } + + if (!NEW_CanMoveToDestPixelPosition(c_rkPPosDst)) + { + if (!IsWaiting()) + EndWalking(); + + return true; + } + + NEW_SetSrcPixelPosition(NEW_GetCurPixelPositionRef()); + NEW_SetDstPixelPosition(c_rkPPosDst); + NEW_SetDstPixelPositionZ(NEW_GetSrcPixelPositionRef().z); + m_fDstRot=fDstRot; + m_isGoing = TRUE; + + if (!IsWalking()) + { + StartWalking(); + } + + NEW_SetAdvancingRotationFromPixelPosition(NEW_GetSrcPixelPositionRef(), NEW_GetDstPixelPositionRef()); + + return true; +} + +void CInstanceBase::NEW_MoveToDirection(float fDirRot) +{ + if (__IsSyncing()) + return; + + if (m_GraphicThingInstance.IsUsingMovingSkill()) + { + SetAdvancingRotation(fDirRot); + return; + } + + if (isLock()) + return; + + m_isGoing = FALSE; + + SetAdvancingRotation(fDirRot); + + if (!IsWalking()) + { + StartWalking(); + } + + TPixelPosition kPPosCur; + NEW_GetPixelPosition(&kPPosCur); + + D3DXVECTOR3 kD3DVt3Cur(kPPosCur.x, -kPPosCur.y, kPPosCur.z); + D3DXVECTOR3 kD3DVt3Dst; + + D3DXVECTOR3 kD3DVt3AdvDir(0.0f, -1.0f, 0.0f); + D3DXMATRIX kD3DMatAdv; + D3DXMatrixRotationZ(&kD3DMatAdv, D3DXToRadian(fDirRot)); + D3DXVec3TransformCoord(&kD3DVt3AdvDir, &kD3DVt3AdvDir, &kD3DMatAdv); + D3DXVec3Scale(&kD3DVt3AdvDir, &kD3DVt3AdvDir, 300.0f); + D3DXVec3Add(&kD3DVt3Dst, &kD3DVt3AdvDir, &kD3DVt3Cur); + + TPixelPosition kPPosDst; + kPPosDst.x = +kD3DVt3Dst.x; + kPPosDst.y = -kD3DVt3Dst.y; + kPPosDst.z = +kD3DVt3Dst.z; + + NEW_SetSrcPixelPosition(kPPosCur); + NEW_SetDstPixelPosition(kPPosDst); +} + +void CInstanceBase::EndGoing() +{ + if (!IsWaiting()) + EndWalking(); + + //Tracen("EndGoing"); + + m_isGoing = FALSE; +} + +void CInstanceBase::SetRunMode() +{ + m_GraphicThingInstance.SetRunMode(); +} + +void CInstanceBase::SetWalkMode() +{ + m_GraphicThingInstance.SetWalkMode(); +} diff --git a/source/UserInterface/InstanceBaseTransform.cpp b/source/UserInterface/InstanceBaseTransform.cpp new file mode 100644 index 0000000..e5a762c --- /dev/null +++ b/source/UserInterface/InstanceBaseTransform.cpp @@ -0,0 +1,93 @@ +#include "StdAfx.h" +#include "InstanceBase.h" +#include "PythonBackground.h" + + + + +void CInstanceBase::SCRIPT_SetPixelPosition(float fx, float fy) +{ + float fz = __GetBackgroundHeight(fx, fy); + NEW_SetPixelPosition(TPixelPosition(fx, fy, fz)); +} + +void CInstanceBase::NEW_SetPixelPosition(const TPixelPosition & c_rPixelPosition) +{ + m_GraphicThingInstance.SetCurPixelPosition(c_rPixelPosition); +} + +void CInstanceBase::NEW_GetPixelPosition(TPixelPosition * pPixelPosition) +{ + *pPixelPosition=m_GraphicThingInstance.NEW_GetCurPixelPositionRef(); +} + +void CInstanceBase::SetRotation(float fRotation) +{ + m_GraphicThingInstance.SetRotation(fRotation); +} + +void CInstanceBase::BlendRotation(float fRotation, float fBlendTime) +{ + m_GraphicThingInstance.BlendRotation(fRotation, fBlendTime); +} + +void CInstanceBase::NEW_LookAtFlyTarget() +{ + m_GraphicThingInstance.LookAtFlyTarget(); +} + +void CInstanceBase::NEW_LookAtDestPixelPosition(const TPixelPosition& c_rkPPosDst) +{ + m_GraphicThingInstance.LookAt(c_rkPPosDst.x, -c_rkPPosDst.y); +} + +void CInstanceBase::NEW_LookAtDestInstance(CInstanceBase& rkInstDst) +{ + m_GraphicThingInstance.LookAt(&rkInstDst.m_GraphicThingInstance); +// Tracenf("LookAt %f", m_GraphicThingInstance.GetTargetRotation()); +} + +float CInstanceBase::GetRotation() +{ + return m_GraphicThingInstance.GetRotation(); +} + +float CInstanceBase::GetAdvancingRotation() +{ + return m_GraphicThingInstance.GetAdvancingRotation(); +} + +void CInstanceBase::SetDirection(int dir) +{ + float fDegree = GetDegreeFromDirection(dir); + SetRotation(fDegree); + SetAdvancingRotation(fDegree); +} + +void CInstanceBase::BlendDirection(int dir, float blendTime) +{ + m_GraphicThingInstance.BlendRotation(GetDegreeFromDirection(dir), blendTime); +} + +float CInstanceBase::GetDegreeFromDirection(int dir) +{ + if (dir < 0) + return 0.0f; + + if (dir >= DIR_MAX_NUM) + return 0.0f; + + static float s_dirRot[DIR_MAX_NUM]= + { + +45.0f * 4, + +45.0f * 3, + +45.0f * 2, + +45.0f, + +0.0f, + 360.0f-45.0f, + 360.0f-45.0f * 2, + 360.0f-45.0f * 3, + }; + + return s_dirRot[dir]; +} diff --git a/source/UserInterface/InsultChecker.cpp b/source/UserInterface/InsultChecker.cpp new file mode 100644 index 0000000..06bcb51 --- /dev/null +++ b/source/UserInterface/InsultChecker.cpp @@ -0,0 +1,97 @@ +#include "StdAfx.h" +#include "InsultChecker.h" + +CInsultChecker& CInsultChecker::GetSingleton() +{ + static CInsultChecker s_kInsultChecker; + return s_kInsultChecker; +} + +CInsultChecker::CInsultChecker() +{ +} + +CInsultChecker::~CInsultChecker() +{ +} + +void CInsultChecker::Clear() +{ + m_kList_stInsult.clear(); +} + +void CInsultChecker::AppendInsult(const std::string& c_rstInsult) +{ + if (c_rstInsult.length()>0) + m_kList_stInsult.push_back(c_rstInsult); +} + +bool CInsultChecker::__GetInsultLength(const char* c_szWord, UINT* puInsultLen) +{ + std::list::iterator i; + for (i=m_kList_stInsult.begin(); i!=m_kList_stInsult.end(); ++i) + { + std::string& rstInsult=*i; + + int ret=LocaleService_StringCompareCI(c_szWord, rstInsult.c_str(), rstInsult.length()); + if (0==ret) + { + *puInsultLen=rstInsult.length(); + return true; + } + } + + return false; +} + +bool CInsultChecker::__IsInsult(const char* c_szWord) +{ + UINT uInsultLen; + return __GetInsultLength(c_szWord, &uInsultLen); +} + +void CInsultChecker::FilterInsult(char* szLine, UINT uLineLen) +{ + const char INSULT_FILTER_CHAR = '*'; + for (UINT uPos=0; uPos m_kList_stInsult; +}; diff --git a/source/UserInterface/Locale.cpp b/source/UserInterface/Locale.cpp new file mode 100644 index 0000000..b83d0b3 --- /dev/null +++ b/source/UserInterface/Locale.cpp @@ -0,0 +1,441 @@ +#include "StdAfx.h" +#include "Locale.h" +#include "PythonApplication.h" +#include "resource.h" +#include "../eterBase/CRC32.h" +#include "../eterpack/EterPackManager.h" +#include "../eterLocale/Japanese.h" +#include + +const char* LSS_YMIR = "YMIR"; +const char* LSS_JAPAN = "JAPAN"; +const char* LSS_ENGLISH = "ENGLISH"; +const char* LSS_HONGKONG = "HONGKONG"; +const char* LSS_TAIWAN = "TAIWAN"; +const char* LSS_NEWCIBN = "NEWCIBN"; +const char* LSS_EUROPE = "EUROPE"; +const char* LSS_GLOBAL = "GLOBAL"; + +static bool IS_CHEONMA = false; + +#ifndef LSS_SECURITY_KEY +#define LSS_SECURITY_KEY "testtesttesttest" +#endif + +std::string __SECURITY_KEY_STRING__ = LSS_SECURITY_KEY; + +char MULTI_LOCALE_SERVICE[256] = "YMIR"; +char MULTI_LOCALE_PATH[256] = "locale/ymir"; +char MULTI_LOCALE_NAME[256] = "ymir"; +int MULTI_LOCALE_CODE = 949; +int MULTI_LOCALE_REPORT_PORT = 10000; + +void LocaleService_LoadConfig(const char* fileName) +{ + NANOBEGIN + FILE* fp = fopen(fileName, "rt"); + + if (fp) + { + char line[256]; + char name[256]; + int code; + int id; + if (fgets(line, sizeof(line)-1, fp)) + { + line[sizeof(line)-1] = '\0'; + sscanf(line, "%d %d %s", &id, &code, name); + + MULTI_LOCALE_REPORT_PORT = id; + MULTI_LOCALE_CODE = code; + strcpy(MULTI_LOCALE_NAME, name); + sprintf(MULTI_LOCALE_PATH, "locale/%s", MULTI_LOCALE_NAME); + } + fclose(fp); + } + NANOEND +} + +unsigned LocaleService_GetLastExp(int level) +{ + static const int GUILD_LEVEL_MAX = 20; + + if (LocaleService_IsCHEONMA()) + { + static DWORD CHEONMA_GUILDEXP_LIST[GUILD_LEVEL_MAX+1] = + { + 0, // 0 + 15000ul, // 1 + 45000ul, // 2 + 90000ul, // 3 + 160000ul, // 4 + 235000ul, // 5 + 325000ul, // 6 + 430000ul, // 7 + 550000ul, // 8 + 685000ul, // 9 + 835000ul, // 10 + 1000000ul, // 11 + 1500000ul, // 12 + 2100000ul, // 13 + 2800000ul, // 14 + 3600000ul, // 15 + 4500000ul, // 16 + 6500000ul, // 17 + 8000000ul, // 18 + 10000000ul, // 19 + 42000000UL // 20 + }; + if (level < 0 && level >= GUILD_LEVEL_MAX) + return 0; + + return CHEONMA_GUILDEXP_LIST[level]; + } + + static DWORD INTERNATIONAL_GUILDEXP_LIST[GUILD_LEVEL_MAX+1] = + { + 0, // 0 + 6000UL, // 1 + 18000UL, // 2 + 36000UL, // 3 + 64000UL, // 4 + 94000UL, // 5 + 130000UL, // 6 + 172000UL, // 7 + 220000UL, // 8 + 274000UL, // 9 + 334000UL, // 10 + 400000UL, // 11 + 600000UL, // 12 + 840000UL, // 13 + 1120000UL, // 14 + 1440000UL, // 15 + 1800000UL, // 16 + 2600000UL, // 17 + 3200000UL, // 18 + 4000000UL, // 19 + 16800000UL // 20 + }; + + if (level < 0 && level >= GUILD_LEVEL_MAX) + return 0; + + return INTERNATIONAL_GUILDEXP_LIST[level]; +} + +int LocaleService_GetSkillPower(unsigned level) +{ + static const unsigned SKILL_POWER_NUM = 50; + + if (level >= SKILL_POWER_NUM) + return 0; + + if (LocaleService_IsCHEONMA()) + { + static unsigned CHEONMA_SKILL_POWERS[SKILL_POWER_NUM]= + { + 0, + 5, 7, 9, 11, 13, + 15, 17, 19, 20, 22, + 24, 26, 28, 30, 32, + 34, 36, 38, 40, 50, // master + 52, 55, 58, 61, 63, + 66, 69, 72, 75, 80, // grand_master + 82, 84, 87, 90, 95, + 100,110,120,130,150,// perfect_master + 150, + }; + return CHEONMA_SKILL_POWERS[level]; + } + + // 0 5 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 50 52 54 56 58 60 63 66 69 72 82 85 88 91 94 98 102 106 110 115 125 125 125 125 125 + static unsigned INTERNATIONAL_SKILL_POWERS[SKILL_POWER_NUM]= + { + 0, + 5, 6, 8, 10, 12, + 14, 16, 18, 20, 22, + 24, 26, 28, 30, 32, + 34, 36, 38, 40, 50, // master + 52, 54, 56, 58, 60, + 63, 66, 69, 72, 82, // grand_master + 85, 88, 91, 94, 98, + 102,106,110,115,125,// perfect_master + 125, + }; + return INTERNATIONAL_SKILL_POWERS[level]; +} + +const char* LocaleService_GetSecurityKey() +{ + return __SECURITY_KEY_STRING__.c_str(); +} + +// CHEONMA +void LocaleService_SetCHEONMA(bool isEnable) +{ + IS_CHEONMA = isEnable; +} + +bool LocaleService_IsCHEONMA() +{ + return LocaleService_IsYMIR(); +} + +// END_OF_CHEONMA + +#if defined(LOCALE_SERVICE_EUROPE) || defined(LOCALE_SERVICE_BRAZIL) || defined(LOCALE_SERVICE_CANADA) || defined(LOCALE_SERVICE_SINGAPORE) || defined(LOCALE_SERVICE_VIETNAM) || defined(LOCALE_SERVICE_TAIWAN) || defined(LOCALE_SERVICE_NEWCIBN) +#define _LSS_USE_LOCALE_CFG 1 +#define _LSS_SERVICE_NAME LSS_EUROPE +#elif defined(LOCALE_SERVICE_ITALY) +#define _LSS_SERVICE_NAME LSS_ITALY +#define _LSS_SERVICE_CODEPAGE CP_LATIN +#define _LSS_SERVICE_LOCALE_NAME "it" +#define _LSS_SERVICE_LOCALE_PATH "locale/it" +#elif defined(LOCALE_SERVICE_ENGLISH) +#define _LSS_SERVICE_NAME LSS_ENGLISH +#define _LSS_SERVICE_CODEPAGE CP_LATIN +#define _LSS_SERVICE_LOCALE_NAME "english" +#define _LSS_SERVICE_LOCALE_PATH "locale/english" +#elif defined(LOCALE_SERVICE_JAPAN) +#define _LSS_SERVICE_NAME LSS_JAPAN +#define _LSS_SERVICE_CODEPAGE CP_JAPANESE +#define _LSS_SERVICE_LOCALE_NAME "japan" +#define _LSS_SERVICE_LOCALE_PATH "locale/japan" +#elif defined(LOCALE_SERVICE_YMIR) +#define _LSS_SERVICE_NAME LSS_YMIR +#define _LSS_SERVICE_CODEPAGE CP_HANGUL +#define _LSS_SERVICE_LOCALE_NAME "ymir" +#define _LSS_SERVICE_LOCALE_PATH "locale/ymir" +#elif defined(LOCALE_SERVICE_HONGKONG) +#define _LSS_SERVICE_NAME LSS_HONGKONG +#define _LSS_SERVICE_CODEPAGE CP_CHINESE_TRAD +#define _LSS_SERVICE_LOCALE_NAME "hongkong" +#define _LSS_SERVICE_LOCALE_PATH "locale/hongkong" +#elif defined(LOCALE_SERVICE_TAIWAN) +#define _LSS_SERVICE_NAME LSS_TAIWAN +#define _LSS_SERVICE_CODEPAGE CP_CHINESE_TRAD +#define _LSS_SERVICE_LOCALE_NAME "taiwan" +#define _LSS_SERVICE_LOCALE_PATH "locale/taiwan" +#elif defined(LOCALE_SERVICE_NEWCIBN) +#define _LSS_SERVICE_NAME LSS_NEWCIBN +#define _LSS_SERVICE_CODEPAGE CP_CHINESE_SIMPLE +#define _LSS_SERVICE_LOCALE_NAME "newcibn" +#define _LSS_SERVICE_LOCALE_PATH "locale/newcibn" +#endif + +#if defined(_LSS_USE_LOCALE_CFG) +#if defined(_LSS_SERVICE_NAME) +const char* LocaleService_GetName() { return _LSS_SERVICE_NAME;} +#else +const char* LocaleService_GetName() { return MULTI_LOCALE_SERVICE; } +#endif +unsigned int LocaleService_GetCodePage() { return MULTI_LOCALE_CODE; } +const char* LocaleService_GetLocaleName() { return MULTI_LOCALE_NAME; } +const char* LocaleService_GetLocalePath() { return MULTI_LOCALE_PATH; } +#elif defined(_LSS_SERVICE_NAME) +const char* LocaleService_GetName() { return _LSS_SERVICE_NAME;} +unsigned int LocaleService_GetCodePage() { return _LSS_SERVICE_CODEPAGE; } +const char* LocaleService_GetLocaleName() { return _LSS_SERVICE_LOCALE_NAME; } +const char* LocaleService_GetLocalePath() { return _LSS_SERVICE_LOCALE_PATH; } +#endif + +void LocaleService_ForceSetLocale(const char* name, const char* localePath) +{ + strcpy(MULTI_LOCALE_NAME, name); + strcpy(MULTI_LOCALE_PATH, localePath); + + // õ ӽÿ security key (WE Ŭ õ ϱ ) + if (0 == stricmp(name, "ymir")) + __SECURITY_KEY_STRING__ = "testtesttesttest"; + if (0 == stricmp(name, "we_korea")) + __SECURITY_KEY_STRING__ = "1234abcd5678efgh"; +} + +#if defined(LOCALE_SERVICE_GLOBAL) +struct SLOCALEDATA +{ + const char* szServiceName; + const char* szLocaleName; + WORD wCodePage; + const char* szSecurityKey; +} gs_stLocaleData[] = { + { LSS_YMIR, "ymir", 949, "testtesttesttest" }, // Korea + { LSS_EUROPE, "de", 1252, "1234abcd5678efgh" }, // GameForge (Germany) + { LSS_EUROPE, "en", 1252, "1234abcd5678efgh" }, // GameForge (United Kingdom) + { LSS_EUROPE, "us", 1252, "1234abcd5678efgh" }, // GameForge (USA) + { LSS_EUROPE, "es", 1252, "1234abcd5678efgh" }, // GameForge (Spain) + { LSS_EUROPE, "it", 1252, "1234abcd5678efgh" }, // GameForge (Italy) + { LSS_EUROPE, "fr", 1252, "1234abcd5678efgh" }, // GameForge (France) + { LSS_EUROPE, "pt", 1252, "1234abcd5678efgh" }, // GameForge (Portugal) + { LSS_EUROPE, "tr", 1253, "1234abcd5678efgh" }, // GameForge (Greece) + { LSS_EUROPE, "pl", 1250, "1234abcd5678efgh" }, // GameForge (Poland) + { LSS_EUROPE, "tr", 1254, "1234abcd5678efgh" }, // GameForge (Turkey) + { LSS_EUROPE, "dk", 1252, "1234abcd5678efgh" }, // GameForge (Demmark) + { LSS_EUROPE, "ae", 1256, "1234abcd5678efgh" }, // GameForge (United Arab Emirate) + { LSS_EUROPE, "mx", 1252, "1234abcd5678efgh" }, // GameForge (Mexico) + { LSS_EUROPE, "nl", 1252, "1234abcd5678efgh" }, // GameForge (Netherlands) + { LSS_EUROPE, "cz", 1252, "1234abcd5678efgh" }, // GameForge (Czech Republic) + { LSS_EUROPE, "ru", 1251, "1234abcd5678efgh" }, // GameForge (Russian Federation) + { LSS_EUROPE, "hu", 1250, "1234abcd5678efgh" }, // GameForge (Hungary) + { LSS_EUROPE, "ro", 1250, "1234abcd5678efgh" }, // GameForge (Romania) + { LSS_EUROPE, "ca", 1252, "testtesttesttest" }, // Z8Games (Canada) + { LSS_EUROPE, "sg", 1252, "testtesttesttest" }, // TEC (Singapore) + { LSS_JAPAN, "japan", 932, "testtesttesttest" }, // Japan + { LSS_EUROPE, "br", 1252, "testtesttesttest" }, // OnGame (Brazil) + { LSS_HONGKONG, "hongkong", 950, "testtesttesttest" }, // HongKong & Taiwan + { LSS_NEWCIBN, "newcibn", 936, "testtesttesttest" }, // CIBN (Free world) + { LSS_ENGLISH, "english", 949, "testtesttesttest" }, // English (Obsoleted) + { LSS_YMIR, "kr", 949, "testtesttesttest" }, // Korea (Obsoleted) + { NULL, NULL, 0, "testtesttesttest" } +}; + +const char* LocaleService_GetName() +{ + return MULTI_LOCALE_SERVICE; +} + +unsigned int LocaleService_GetCodePage() +{ + return MULTI_LOCALE_CODE; +} + +const char* LocaleService_GetLocaleName() +{ + return MULTI_LOCALE_NAME; +} + +const char* LocaleService_GetLocalePath() +{ + return MULTI_LOCALE_PATH; +} + +static int gs_iLocale = -1; + +LRESULT CALLBACK SelectDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + switch( uMsg ) { + case WM_INITDIALOG : { + char szLocalePath[256], szDisplayName[256]; + for(int i=0; gs_stLocaleData[i].szServiceName; i++ ) { + sprintf(szLocalePath, "locale/%s/item_proto", gs_stLocaleData[i].szLocaleName); + if( CEterPackManager::Instance().isExist(szLocalePath)) { + sprintf(szDisplayName, "%s (%s, %d)", gs_stLocaleData[i].szLocaleName, gs_stLocaleData[i].szServiceName, gs_stLocaleData[i].wCodePage); + int iIndex = ListBox_AddString(GetDlgItem(hDlg, IDC_LOCALE_LIST), szDisplayName); + ListBox_SetItemData(GetDlgItem(hDlg, IDC_LOCALE_LIST), iIndex, i); + } + } + return TRUE; + } + case WM_COMMAND : + switch( LOWORD( wParam ) ) { + case IDC_LOCALE_LIST: { + int iSelected = ListBox_GetCurSel(GetDlgItem(hDlg, IDC_LOCALE_LIST)); + switch(HIWORD(wParam)) { + case LBN_SELCHANGE : + gs_iLocale = ListBox_GetItemData(GetDlgItem(hDlg, IDC_LOCALE_LIST), iSelected); + break; + case LBN_DBLCLK : + gs_iLocale = ListBox_GetItemData(GetDlgItem(hDlg, IDC_LOCALE_LIST), iSelected); + ::EndDialog(hDlg, 0); + break; + } + break; + } + case IDC_START: { + ::EndDialog(hDlg, 0); + break; + } + case IDC_EXIT: { + gs_iLocale = -1; + ::EndDialog(hDlg, 0); + break; + } + } + return FALSE; + } + return FALSE; +} + +bool LocaleService_LoadGlobal(HINSTANCE hInstance) +{ + int nFoundLocales = 0; + char szLocalePath[256]; + + for(int i=0; gs_stLocaleData[i].szServiceName; i++ ) { + sprintf(szLocalePath, "locale/%s/item_proto", gs_stLocaleData[i].szLocaleName); + if( CEterPackManager::Instance().isExist(szLocalePath)) { + nFoundLocales++; + if(gs_iLocale == -1) + gs_iLocale = i; + } + } + if (gs_iLocale < 0) + return false; + if(nFoundLocales > 1) + ::DialogBox(hInstance, MAKEINTRESOURCE(IDD_SELECT_LOCALE), NULL, (DLGPROC) SelectDlgProc); + if (gs_iLocale < 0) + return false; + strcpy(MULTI_LOCALE_SERVICE, gs_stLocaleData[gs_iLocale].szServiceName); + strcpy(MULTI_LOCALE_NAME, gs_stLocaleData[gs_iLocale].szLocaleName); + sprintf(MULTI_LOCALE_PATH, "locale/%s", gs_stLocaleData[gs_iLocale].szLocaleName); + MULTI_LOCALE_CODE = gs_stLocaleData[gs_iLocale].wCodePage; + if(gs_stLocaleData[gs_iLocale].szSecurityKey) + __SECURITY_KEY_STRING__ = gs_stLocaleData[gs_iLocale].szSecurityKey; + return true; +} +#else +bool LocaleService_LoadGlobal(HINSTANCE hInstance) +{ + return false; +} +#endif + +bool LocaleService_IsYMIR() { return (stricmp( LocaleService_GetName(), LSS_YMIR ) == 0) || (stricmp( LocaleService_GetLocaleName(), "ymir" ) == 0); } +bool LocaleService_IsJAPAN() { return (stricmp( LocaleService_GetName(), LSS_JAPAN ) == 0) || (stricmp( LocaleService_GetLocaleName(), "japan" ) == 0); } +bool LocaleService_IsENGLISH() { return (stricmp( LocaleService_GetName(), LSS_ENGLISH ) == 0); } +bool LocaleService_IsEUROPE() { return (stricmp( LocaleService_GetName(), LSS_EUROPE ) == 0); } +bool LocaleService_IsHONGKONG() { return (stricmp( LocaleService_GetName(), LSS_HONGKONG ) == 0); } +bool LocaleService_IsTAIWAN() { return (stricmp( LocaleService_GetName(), LSS_TAIWAN ) == 0); } +bool LocaleService_IsNEWCIBN() { return (stricmp( LocaleService_GetName(), LSS_NEWCIBN ) == 0); } + +#if defined(LOCALE_SERVICE_WE_JAPAN) +BOOL LocaleService_IsLeadByte( const char chByte ) +{ + return ShiftJIS_IsLeadByte( chByte ); +} + +int LocaleService_StringCompareCI( LPCSTR szStringLeft, LPCSTR szStringRight, size_t sizeLength ) +{ + return ShiftJIS_StringCompareCI( szStringLeft, szStringRight, sizeLength ); +} +#else +BOOL LocaleService_IsLeadByte( const char chByte ) +{ + return (((unsigned char) chByte) & 0x80) != 0; +} + +int LocaleService_StringCompareCI( LPCSTR szStringLeft, LPCSTR szStringRight, size_t sizeLength ) +{ + return strnicmp( szStringLeft, szStringRight, sizeLength ); +} +#endif + + +#ifdef USE_OPENID + +std::string __OPENID_AUTH_KEY_STRING__; +int openid_test = 0; + +void LocaleService_SetOpenIDAuthKey(const char *authKey) +{ + __OPENID_AUTH_KEY_STRING__ = authKey; + + return; +} + +const char* LocaleService_GetOpenIDAuthKey() +{ + return __OPENID_AUTH_KEY_STRING__.c_str(); +} + +#endif /* USE_OPENID */ \ No newline at end of file diff --git a/source/UserInterface/Locale.h b/source/UserInterface/Locale.h new file mode 100644 index 0000000..d163042 --- /dev/null +++ b/source/UserInterface/Locale.h @@ -0,0 +1,36 @@ +#pragma once + +#include "Locale_inc.h" + +bool LocaleService_IsYMIR(); +bool LocaleService_IsJAPAN(); +bool LocaleService_IsENGLISH(); +bool LocaleService_IsHONGKONG(); +bool LocaleService_IsTAIWAN(); +bool LocaleService_IsNEWCIBN(); +bool LocaleService_IsEUROPE(); +bool LocaleService_IsWorldEdition(); + +unsigned LocaleService_GetCodePage(); +const char* LocaleService_GetName(); +const char* LocaleService_GetLocaleName(); +const char* LocaleService_GetLocalePath(); +const char* LocaleService_GetSecurityKey(); +BOOL LocaleService_IsLeadByte( const char chByte ); +int LocaleService_StringCompareCI( LPCSTR szStringLeft, LPCSTR szStringRight, size_t sizeLength ); + +void LocaleService_ForceSetLocale(const char* name, const char* localePath); +void LocaleService_LoadConfig(const char* fileName); +bool LocaleService_LoadGlobal(HINSTANCE hInstance); +unsigned LocaleService_GetLastExp(int level); +int LocaleService_GetSkillPower(unsigned level); + +// CHEONMA +void LocaleService_SetCHEONMA(bool isEnable); +bool LocaleService_IsCHEONMA(); +// END_OF_CHEONMA + +#ifdef USE_OPENID +void LocaleService_SetOpenIDAuthKey(const char *authKey); +const char* LocaleService_GetOpenIDAuthKey(); +#endif \ No newline at end of file diff --git a/source/UserInterface/Locale_inc.h b/source/UserInterface/Locale_inc.h new file mode 100644 index 0000000..4703cb2 --- /dev/null +++ b/source/UserInterface/Locale_inc.h @@ -0,0 +1,6 @@ +#define LOCALE_SERVICE_SINGAPORE // ̰ +#define ENABLE_COSTUME_SYSTEM +#define ENABLE_ENERGY_SYSTEM +#define ENABLE_DRAGON_SOUL_SYSTEM +#define ENABLE_NEW_EQUIPMENT_SYSTEM +//#define ENABLE_DISCORD_RPC diff --git a/source/UserInterface/Locale_inc_BR.h b/source/UserInterface/Locale_inc_BR.h new file mode 100644 index 0000000..b8ca7e6 --- /dev/null +++ b/source/UserInterface/Locale_inc_BR.h @@ -0,0 +1,7 @@ +#define LOCALE_SERVICE_BRAZIL // + +#define XTRAP_CLIENT_ENABLE +#define XTRAP_PATCH_ARG "660970B4483BDC32C5266D9844CFED6230832A3E2F95F8DD45DB9AED6AE8B837900845956432BD8F2D14136A8CF8BD970A93B783971789382A493B68C5C2BA650F7D04245246E41FB1670C4E955F790A585C3F5D8EB0BADD81C6DD2DB7" +#define ENABLE_COSTUME_SYSTEM +#define ENABLE_ENERGY_SYSTEM +#define ENABLE_DRAGON_SOUL_SYSTEM \ No newline at end of file diff --git a/source/UserInterface/Locale_inc_CA.h b/source/UserInterface/Locale_inc_CA.h new file mode 100644 index 0000000..7ae11be --- /dev/null +++ b/source/UserInterface/Locale_inc_CA.h @@ -0,0 +1,6 @@ +#define LOCALE_SERVICE_CANADA // ij + +#define XTRAP_CLIENT_ENABLE +#define XTRAP_PATCH_ARG "660970B4953BDCCFC5266D9844CFED62D9D88487BAFA5824E622544D919AC5C535B7B5BB27DF7189499DA1EFA3745A052BE7AE8B12275EDE90BAFDD333407BF80F7D04245246E40AF7650C4AD8583917B21AD7B2AFDE3D4F588C800D128456E1DFEC" +#define ENABLE_COSTUME_SYSTEM +#define ENABLE_ENERGY_SYSTEM diff --git a/source/UserInterface/Locale_inc_EU.h b/source/UserInterface/Locale_inc_EU.h new file mode 100644 index 0000000..b9999da --- /dev/null +++ b/source/UserInterface/Locale_inc_EU.h @@ -0,0 +1,5 @@ +#define LOCALE_SERVICE_EUROPE // + +#define LSS_SECURITY_KEY "1234abcd5678efgh" + +#define CHECK_LATEST_DATA_FILES diff --git a/source/UserInterface/Locale_inc_EU2.h b/source/UserInterface/Locale_inc_EU2.h new file mode 100644 index 0000000..39824e2 --- /dev/null +++ b/source/UserInterface/Locale_inc_EU2.h @@ -0,0 +1,15 @@ +#define LOCALE_SERVICE_EUROPE // + +//#define USE_AHNLAB_HACKSHIELD + +//#define CHECK_LATEST_DATA_FILES + +#define LSS_SECURITY_KEY "1234abcd5678efgh" + +#define ENABLE_COSTUME_SYSTEM + +#define ENABLE_ENERGY_SYSTEM + +#define ENABLE_DRAGON_SOUL_SYSTEM +#define ENABLE_NEW_EQUIPMENT_SYSTEM + diff --git a/source/UserInterface/Locale_inc_GB.h b/source/UserInterface/Locale_inc_GB.h new file mode 100644 index 0000000..8574589 --- /dev/null +++ b/source/UserInterface/Locale_inc_GB.h @@ -0,0 +1,3 @@ +#define LOCALE_SERVICE_GLOBAL // GLOBAL version + +#define USE_RELATIVE_PATH diff --git a/source/UserInterface/Locale_inc_HK.h b/source/UserInterface/Locale_inc_HK.h new file mode 100644 index 0000000..e1d64b0 --- /dev/null +++ b/source/UserInterface/Locale_inc_HK.h @@ -0,0 +1,2 @@ +#define LOCALE_SERVICE_HONGKONG // ȫ + diff --git a/source/UserInterface/Locale_inc_JP.h b/source/UserInterface/Locale_inc_JP.h new file mode 100644 index 0000000..72651b8 --- /dev/null +++ b/source/UserInterface/Locale_inc_JP.h @@ -0,0 +1,13 @@ +#define LOCALE_SERVICE_WE_JAPAN // World Edition( ) Ϻ +#define LOCALE_SERVICE_EUROPE // + +#define LSS_SECURITY_KEY "1234abcd5678efgh" + +#define CHECK_LATEST_DATA_FILES + +#define XTRAP_CLIENT_ENABLE +#define XTRAP_PATCH_ARG "660970B45839DC81C5456D9844CFED62303A1E1A50FFCBE4EA66A304B961F2C32CE50A020A6641FABDF1012DCA07BBC05387C8AD0D4781097428789FE68B54150F7D04245246E404A17B4351DC553907911A3FD51AEE1C697A03BC66B3A378" + +#define ENABLE_COSTUME_SYSTEM +#define ENABLE_ENERGY_SYSTEM +#define USE_OPENID diff --git a/source/UserInterface/Locale_inc_KO.h b/source/UserInterface/Locale_inc_KO.h new file mode 100644 index 0000000..e53d11c --- /dev/null +++ b/source/UserInterface/Locale_inc_KO.h @@ -0,0 +1,9 @@ +#include "Locale_inc_EU.h" + +//#define XTRAP_CLIENT_ENABLE +#define XTRAP_PATCH_ARG "660970B47839DCBFC5206D9844CFED627251D23A44458651BD1F0E57E26D7C85B4CC00C30B1D1724026D5F65A662992141DB6C233A24040C5A6BCD6D25A5576D0F7D04245246E417A4610E56955D721985C1414D9E254947FC" + +#define ENABLE_COSTUME_SYSTEM +#define ENABLE_ENERGY_SYSTEM +#define ENABLE_DRAGON_SOUL_SYSTEM +#define ENABLE_NEW_EQUIPMENT_SYSTEM diff --git a/source/UserInterface/Locale_inc_KO_DEV.h b/source/UserInterface/Locale_inc_KO_DEV.h new file mode 100644 index 0000000..28fcbc8 --- /dev/null +++ b/source/UserInterface/Locale_inc_KO_DEV.h @@ -0,0 +1,5 @@ +#define LOCALE_SERVICE_YMIR // Korean + +#define LOCALE_SERVICE_STAGE_DEVELOPMENT + +#define USE_RELATIVE_PATH diff --git a/source/UserInterface/Locale_inc_NEWCIBN.h b/source/UserInterface/Locale_inc_NEWCIBN.h new file mode 100644 index 0000000..4c20a68 --- /dev/null +++ b/source/UserInterface/Locale_inc_NEWCIBN.h @@ -0,0 +1,6 @@ +#define LOCALE_SERVICE_NEWCIBN // ߱ + +#define ENABLE_COSTUME_SYSTEM +#define ENABLE_ENERGY_SYSTEM +#define ENABLE_DRAGON_SOUL_SYSTEM +#define ENABLE_NEW_EQUIPMENT_SYSTEM \ No newline at end of file diff --git a/source/UserInterface/Locale_inc_SG.h b/source/UserInterface/Locale_inc_SG.h new file mode 100644 index 0000000..0d59ed9 --- /dev/null +++ b/source/UserInterface/Locale_inc_SG.h @@ -0,0 +1,3 @@ +#define LOCALE_SERVICE_SINGAPORE // ̰ +#define ENABLE_COSTUME_SYSTEM +#define ENABLE_ENERGY_SYSTEM diff --git a/source/UserInterface/Locale_inc_VI.h b/source/UserInterface/Locale_inc_VI.h new file mode 100644 index 0000000..0048938 --- /dev/null +++ b/source/UserInterface/Locale_inc_VI.h @@ -0,0 +1 @@ +#define LOCALE_SERVICE_VIETNAM // Ʈ diff --git a/source/UserInterface/Locale_inc_dev.h b/source/UserInterface/Locale_inc_dev.h new file mode 100644 index 0000000..3757066 --- /dev/null +++ b/source/UserInterface/Locale_inc_dev.h @@ -0,0 +1,9 @@ +#include "Locale_inc_EU.h" + +//#define XTRAP_CLIENT_ENABLE +//#define XTRAP_PATCH_ARG "660970B47839DCBFC5206D9844CFED627251D23A44458651BD1F0E57E26D7C85B4CC00C30B1D1724026D5F65A662992141DB6C233A24040C5A6BCD6D25A5576D0F7D04245246E417A4610E56955D721985C1414D9E254947FC" + +#define ENABLE_COSTUME_SYSTEM +#define ENABLE_ENERGY_SYSTEM +#define ENABLE_DRAGON_SOUL_SYSTEM +#define ENABLE_NEW_EQUIPMENT_SYSTEM \ No newline at end of file diff --git a/source/UserInterface/MarkImage.cpp b/source/UserInterface/MarkImage.cpp new file mode 100644 index 0000000..33c4292 --- /dev/null +++ b/source/UserInterface/MarkImage.cpp @@ -0,0 +1,313 @@ +#include "stdafx.h" +#include "MarkImage.h" + +#if !defined(_MSC_VER) +#include +#include "crc32.h" +#include "lzo_manager.h" +#include "minilzo.h" +#define CLZO LZOManager +#else +#define sys_err TraceError +#define sys_log //(n, format, ...) Tracenf(format, __VA_ARGS__) +#define thecore_memcpy memcpy +#define itertype(cont) typeof(cont.begin()) +#endif + +CGuildMarkImage * NewMarkImage() +{ + return new CGuildMarkImage; +} + +void DeleteMarkImage(CGuildMarkImage * pkImage) +{ + delete pkImage; +} + +CGuildMarkImage::CGuildMarkImage() +{ + m_uImg = INVALID_HANDLE; +} + +CGuildMarkImage::~CGuildMarkImage() +{ + Destroy(); +} + +void CGuildMarkImage::Destroy() +{ + if (INVALID_HANDLE == m_uImg) + return; + + ilDeleteImages(1, &m_uImg); + m_uImg = INVALID_HANDLE; +} + +void CGuildMarkImage::Create() +{ + if (INVALID_HANDLE != m_uImg) + return; + + ilGenImages(1, &m_uImg); +} + +bool CGuildMarkImage::Save(const char* c_szFileName) +{ + ilEnable(IL_FILE_OVERWRITE); + ilBindImage(m_uImg); + + if (!ilSave(IL_TGA, (const ILstring)c_szFileName)) + return false; + + return true; +} + +bool CGuildMarkImage::Build(const char * c_szFileName) +{ + Destroy(); + Create(); + + ilBindImage(m_uImg); + ilEnable(IL_ORIGIN_SET); + ilOriginFunc(IL_ORIGIN_UPPER_LEFT); + + BYTE * data = (BYTE *) malloc(sizeof(Pixel) * WIDTH * HEIGHT); + memset(data, 0, sizeof(Pixel) * WIDTH * HEIGHT); + + if (!ilTexImage(WIDTH, HEIGHT, 1, 4, IL_BGRA, IL_UNSIGNED_BYTE, data)) + { + sys_err("CGuildMarkImage: cannot initialize image"); + return false; + } + + free(data); + + ilEnable(IL_FILE_OVERWRITE); + + if (!ilSave(IL_TGA, (const ILstring)c_szFileName)) + return false; + + return true; +} + +bool CGuildMarkImage::Load(const char * c_szFileName) +{ + Destroy(); + Create(); + + ilBindImage(m_uImg); + ilEnable(IL_ORIGIN_SET); + ilOriginFunc(IL_ORIGIN_UPPER_LEFT); + + if (!ilLoad(IL_TYPE_UNKNOWN, (const ILstring) c_szFileName)) + { + Build(c_szFileName); + + if (!Load(c_szFileName)) + { + sys_err("CGuildMarkImage: cannot open file for writing %s", c_szFileName); + return false; + } + } + + if (ilGetInteger(IL_IMAGE_WIDTH) != WIDTH) + { + sys_err("CGuildMarkImage: %s width must be %u", c_szFileName, WIDTH); + return false; + } + + if (ilGetInteger(IL_IMAGE_HEIGHT) != HEIGHT) + { + sys_err("CGuildMarkImage: %s height must be %u", c_szFileName, HEIGHT); + return false; + } + + ilConvertImage(IL_BGRA, IL_UNSIGNED_BYTE); + + BuildAllBlocks(); + return true; +} + +void CGuildMarkImage::PutData(UINT x, UINT y, UINT width, UINT height, void * data) +{ + ilBindImage(m_uImg); + ilSetPixels(x, y, 0, width, height, 1, IL_BGRA, IL_UNSIGNED_BYTE, data); +} + +void CGuildMarkImage::GetData(UINT x, UINT y, UINT width, UINT height, void * data) +{ + ilBindImage(m_uImg); + ilCopyPixels(x, y, 0, width, height, 1, IL_BGRA, IL_UNSIGNED_BYTE, data); +} + +// ̹ = 512x512 +// = ũ 4 x 4 +// ũ = 16 x 12 +// ̹ = 8 x 10 + +// SERVER +bool CGuildMarkImage::SaveMark(DWORD posMark, BYTE * pbImage) +{ + if (posMark >= MARK_TOTAL_COUNT) + { + sys_err("CGuildMarkImage::CopyMarkFromData: Invalid mark position %u", posMark); + return false; + } + + // ũ ü ̹ ׸. + DWORD colMark = posMark % MARK_COL_COUNT; + DWORD rowMark = posMark / MARK_COL_COUNT; + + printf("PutMark pos %u %ux%u\n", posMark, colMark * SGuildMark::WIDTH, rowMark * SGuildMark::HEIGHT); + PutData(colMark * SGuildMark::WIDTH, rowMark * SGuildMark::HEIGHT, SGuildMark::WIDTH, SGuildMark::HEIGHT, pbImage); + + // ׷ Ʈ + DWORD rowBlock = rowMark / SGuildMarkBlock::MARK_PER_BLOCK_HEIGHT; + DWORD colBlock = colMark / SGuildMarkBlock::MARK_PER_BLOCK_WIDTH; + + Pixel apxBuf[SGuildMarkBlock::SIZE]; + GetData(colBlock * SGuildMarkBlock::WIDTH, rowBlock * SGuildMarkBlock::HEIGHT, SGuildMarkBlock::WIDTH, SGuildMarkBlock::HEIGHT, apxBuf); + m_aakBlock[rowBlock][colBlock].Compress(apxBuf); + return true; +} + +bool CGuildMarkImage::DeleteMark(DWORD posMark) +{ + Pixel image[SGuildMark::SIZE]; + memset(&image, 0, sizeof(image)); + return SaveMark(posMark, (BYTE *) &image); +} + +// CLIENT +bool CGuildMarkImage::SaveBlockFromCompressedData(DWORD posBlock, const BYTE * pbComp, DWORD dwCompSize) +{ + if (posBlock >= BLOCK_TOTAL_COUNT) + return false; + + Pixel apxBuf[SGuildMarkBlock::SIZE]; + size_t sizeBuf = sizeof(apxBuf); + + if (LZO_E_OK != lzo1x_decompress_safe(pbComp, dwCompSize, (BYTE *) apxBuf, (lzo_uint*) &sizeBuf, CLZO::Instance().GetWorkMemory())) + { + sys_err("CGuildMarkImage::CopyBlockFromCompressedData: cannot decompress, compressed size = %u", dwCompSize); + return false; + } + + if (sizeBuf != sizeof(apxBuf)) + { + sys_err("CGuildMarkImage::CopyBlockFromCompressedData: image corrupted, decompressed size = %u", sizeBuf); + return false; + } + + DWORD rowBlock = posBlock / BLOCK_COL_COUNT; + DWORD colBlock = posBlock % BLOCK_COL_COUNT; + + PutData(colBlock * SGuildMarkBlock::WIDTH, rowBlock * SGuildMarkBlock::HEIGHT, SGuildMarkBlock::WIDTH, SGuildMarkBlock::HEIGHT, apxBuf); + + m_aakBlock[rowBlock][colBlock].CopyFrom(pbComp, dwCompSize, GetCRC32((const char *) apxBuf, sizeof(Pixel) * SGuildMarkBlock::SIZE)); + return true; +} + +void CGuildMarkImage::BuildAllBlocks() // ̹ ü ȭ +{ + Pixel apxBuf[SGuildMarkBlock::SIZE]; + sys_log(0, "CGuildMarkImage::BuildAllBlocks"); + + for (UINT row = 0; row < BLOCK_ROW_COUNT; ++row) + for (UINT col = 0; col < BLOCK_COL_COUNT; ++col) + { + GetData(col * SGuildMarkBlock::WIDTH, row * SGuildMarkBlock::HEIGHT, SGuildMarkBlock::WIDTH, SGuildMarkBlock::HEIGHT, apxBuf); + m_aakBlock[row][col].Compress(apxBuf); + } +} + +DWORD CGuildMarkImage::GetEmptyPosition() +{ + SGuildMark kMark; + + for (DWORD row = 0; row < MARK_ROW_COUNT; ++row) + { + for (DWORD col = 0; col < MARK_COL_COUNT; ++col) + { + GetData(col * SGuildMark::WIDTH, row * SGuildMark::HEIGHT, SGuildMark::WIDTH, SGuildMark::HEIGHT, kMark.m_apxBuf); + + if (kMark.IsEmpty()) + return (row * MARK_COL_COUNT + col); + } + } + + return INVALID_MARK_POSITION; +} + +void CGuildMarkImage::GetDiffBlocks(const DWORD * crcList, std::map & mapDiffBlocks) +{ + BYTE posBlock = 0; + + for (DWORD row = 0; row < BLOCK_ROW_COUNT; ++row) + for (DWORD col = 0; col < BLOCK_COL_COUNT; ++col) + { + if (m_aakBlock[row][col].m_crc != *crcList) + { + mapDiffBlocks.insert(std::map::value_type(posBlock, &m_aakBlock[row][col])); + } + ++crcList; + ++posBlock; + } +} + +void CGuildMarkImage::GetBlockCRCList(DWORD * crcList) +{ + for (DWORD row = 0; row < BLOCK_ROW_COUNT; ++row) + for (DWORD col = 0; col < BLOCK_COL_COUNT; ++col) + *(crcList++) = m_aakBlock[row][col].GetCRC(); +} + +//////////////////////////////////////////////////////////////////////////////// +void SGuildMark::Clear() +{ + for (DWORD iPixel = 0; iPixel < SIZE; ++iPixel) + m_apxBuf[iPixel] = 0xff000000; +} + +bool SGuildMark::IsEmpty() +{ + for (DWORD iPixel = 0; iPixel < SIZE; ++iPixel) + if (m_apxBuf[iPixel] != 0x00000000) + return false; + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +DWORD SGuildMarkBlock::GetCRC() const +{ + return m_crc; +} + +void SGuildMarkBlock::CopyFrom(const BYTE * pbCompBuf, DWORD dwCompSize, DWORD crc) +{ + if (dwCompSize > MAX_COMP_SIZE) + return; + + m_sizeCompBuf = dwCompSize; + thecore_memcpy(m_abCompBuf, pbCompBuf, dwCompSize); + m_crc = crc; + //printf("SGuildMarkBlock::CopyFrom: %u > %u crc %u\n", sizeof(Pixel) * SGuildMarkBlock::SIZE, m_sizeCompBuf, m_crc); +} + +void SGuildMarkBlock::Compress(const Pixel * pxBuf) +{ + m_sizeCompBuf = MAX_COMP_SIZE; + + if (LZO_E_OK != lzo1x_999_compress((const BYTE *) pxBuf, + sizeof(Pixel) * SGuildMarkBlock::SIZE, m_abCompBuf, + (lzo_uint*) &m_sizeCompBuf, + CLZO::Instance().GetWorkMemory())) + { + sys_err("SGuildMarkBlock::Compress: Error! %u > %u", sizeof(Pixel) * SGuildMarkBlock::SIZE, m_sizeCompBuf); + return; + } + + //sys_log(0, "SGuildMarkBlock::Compress %u > %u", sizeof(Pixel) * SGuildMarkBlock::SIZE, m_sizeCompBuf); + m_crc = GetCRC32((const char *) pxBuf, sizeof(Pixel) * SGuildMarkBlock::SIZE); +} diff --git a/source/UserInterface/MarkImage.h b/source/UserInterface/MarkImage.h new file mode 100644 index 0000000..16dcde5 --- /dev/null +++ b/source/UserInterface/MarkImage.h @@ -0,0 +1,110 @@ +#ifndef __INC_METIN_II_MARKIMAGE_H__ +#define __INC_METIN_II_MARKIMAGE_H__ + +#include + +typedef unsigned long Pixel; + +struct SGuildMark +{ + enum + { + WIDTH = 16, + HEIGHT = 12, + SIZE = WIDTH * HEIGHT, + }; + + /////////////////////////////////////////////////////////////////////////////// + Pixel m_apxBuf[SIZE]; // ̹ + + /////////////////////////////////////////////////////////////////////////////// + void Clear(); + bool IsEmpty(); +}; + +struct SGuildMarkBlock +{ + enum + { + MARK_PER_BLOCK_WIDTH = 4, + MARK_PER_BLOCK_HEIGHT = 4, + + WIDTH = SGuildMark::WIDTH * MARK_PER_BLOCK_WIDTH, + HEIGHT = SGuildMark::HEIGHT * MARK_PER_BLOCK_HEIGHT, + + SIZE = WIDTH * HEIGHT, + MAX_COMP_SIZE = (SIZE * sizeof(Pixel)) + ((SIZE * sizeof(Pixel)) >> 4) + 64 + 3 + }; + + /////////////////////////////////////////////////////////////////////////////// + Pixel m_apxBuf[SIZE]; // ̹ + + BYTE m_abCompBuf[MAX_COMP_SIZE]; // + size_t m_sizeCompBuf; // ũ + DWORD m_crc; // CRC + + /////////////////////////////////////////////////////////////////////////////// + DWORD GetCRC() const; + + void CopyFrom(const BYTE * pbCompBuf, DWORD dwCompSize, DWORD crc); + void Compress(const Pixel * pxBuf); +}; + +class CGuildMarkImage +{ + public: + enum + { + WIDTH = 512, + HEIGHT = 512, + + BLOCK_ROW_COUNT = HEIGHT / SGuildMarkBlock::HEIGHT, // 10 + BLOCK_COL_COUNT = WIDTH / SGuildMarkBlock::WIDTH, // 8 + + BLOCK_TOTAL_COUNT = BLOCK_ROW_COUNT * BLOCK_COL_COUNT, // 80 + + MARK_ROW_COUNT = BLOCK_ROW_COUNT * SGuildMarkBlock::MARK_PER_BLOCK_HEIGHT, // 40 + MARK_COL_COUNT = BLOCK_COL_COUNT * SGuildMarkBlock::MARK_PER_BLOCK_WIDTH, // 32 + + MARK_TOTAL_COUNT = MARK_ROW_COUNT * MARK_COL_COUNT, // 1280 + + INVALID_MARK_POSITION = 0xffffffff, + }; + + CGuildMarkImage(); + virtual ~CGuildMarkImage(); + + void Create(); + void Destroy(); + + bool Build(const char * c_szFileName); + bool Save(const char* c_szFileName); + bool Load(const char* c_szFileName); + + void PutData(UINT x, UINT y, UINT width, UINT height, void* data); + void GetData(UINT x, UINT y, UINT width, UINT height, void* data); + + bool SaveMark(DWORD posMark, BYTE * pbMarkImage); + bool DeleteMark(DWORD posMark); + bool SaveBlockFromCompressedData(DWORD posBlock, const BYTE * pbComp, DWORD dwCompSize); // -> Ŭ̾Ʈ + + DWORD GetEmptyPosition(); // ũ ġ ´. + + void GetBlockCRCList(DWORD * crcList); + void GetDiffBlocks(const DWORD * crcList, std::map & mapDiffBlocks); + + private: + enum + { + INVALID_HANDLE = 0xffffffff, + }; + + void BuildAllBlocks(); + + SGuildMarkBlock m_aakBlock[BLOCK_ROW_COUNT][BLOCK_COL_COUNT]; + Pixel m_apxImage[WIDTH * HEIGHT * sizeof(Pixel)]; + + ILuint m_uImg; +}; + +#endif diff --git a/source/UserInterface/MarkManager.cpp b/source/UserInterface/MarkManager.cpp new file mode 100644 index 0000000..2e3f3a8 --- /dev/null +++ b/source/UserInterface/MarkManager.cpp @@ -0,0 +1,488 @@ +#include "stdafx.h" +#include "MarkManager.h" + +#if _MSC_VER < 1200 +#include "crc32.h" +#else +#define sys_err TraceError +#define sys_log // (n, format, ...) Tracenf(format, __VA_ARGS__) +#define thecore_memcpy memcpy +#define itertype(cont) typeof((cont).begin()) +#endif + +CGuildMarkImage * CGuildMarkManager::__NewImage() +{ + return new CGuildMarkImage; +} + +void CGuildMarkManager::__DeleteImage(CGuildMarkImage * pkImgDel) +{ + delete pkImgDel; +} + +CGuildMarkManager::CGuildMarkManager() +{ +#if _MSC_VER >= 1200 + _mkdir("mark"); +#endif + // mark id . () + for (DWORD i = 0; i < MAX_IMAGE_COUNT * CGuildMarkImage::MARK_TOTAL_COUNT; ++i) + m_setFreeMarkID.insert(i); +} + +CGuildMarkManager::~CGuildMarkManager() +{ + for (std::map::iterator it = m_mapIdx_Image.begin(); it != m_mapIdx_Image.end(); ++it) + __DeleteImage(it->second); + + m_mapIdx_Image.clear(); +} + +bool CGuildMarkManager::GetMarkImageFilename(DWORD imgIdx, std::string & path) const +{ + if (imgIdx >= MAX_IMAGE_COUNT) + return false; + + char buf[64]; + snprintf(buf, sizeof(buf), "mark/%s_%lu.tga", m_pathPrefix.c_str(), imgIdx); + path = buf; + return true; +} + +void CGuildMarkManager::SetMarkPathPrefix(const char * prefix) +{ + m_pathPrefix = prefix; +} + +// ũ ε ҷ ( ) +bool CGuildMarkManager::LoadMarkIndex() +{ + char buf[64]; + snprintf(buf, sizeof(buf), "mark/%s_index", m_pathPrefix.c_str()); + FILE * fp = fopen(buf, "r"); + + if (!fp) + return false; + + DWORD guildID; + DWORD markID; + + char line[256]; + + while (fgets(line, sizeof(line)-1, fp)) + { + sscanf(line, "%lu %lu", &guildID, &markID); + line[0] = '\0'; + AddMarkIDByGuildID(guildID, markID); + } + + LoadMarkImages(); + + fclose(fp); + return true; +} + +bool CGuildMarkManager::SaveMarkIndex() +{ + char buf[64]; + snprintf(buf, sizeof(buf), "mark/%s_index", m_pathPrefix.c_str()); + FILE * fp = fopen(buf, "w"); + + if (!fp) + { + sys_err("MarkManager::SaveMarkData: cannot open index file."); + return false; + } + + for (std::map::iterator it = m_mapGID_MarkID.begin(); it != m_mapGID_MarkID.end(); ++it) + fprintf(fp, "%d %d\n", it->first, it->second); + + fclose(fp); + sys_log(0, "MarkManager::SaveMarkData: index count %d", m_mapGID_MarkID.size()); + return true; +} + +void CGuildMarkManager::LoadMarkImages() +{ + bool isMarkExists[MAX_IMAGE_COUNT]; + memset(isMarkExists, 0, sizeof(isMarkExists)); + + for (std::map::iterator it = m_mapGID_MarkID.begin(); it != m_mapGID_MarkID.end(); ++it) + { + DWORD markID = it->second; + + if (markID < MAX_IMAGE_COUNT * CGuildMarkImage::MARK_TOTAL_COUNT) + isMarkExists[markID / CGuildMarkImage::MARK_TOTAL_COUNT] = true; + } + + for (DWORD i = 0; i < MAX_IMAGE_COUNT; ++i) + if (isMarkExists[i]) + __GetImage(i); +} + +void CGuildMarkManager::SaveMarkImage(DWORD imgIdx) +{ + std::string path; + + if (GetMarkImageFilename(imgIdx, path)) + if (!__GetImage(imgIdx)->Save(path.c_str())) + sys_err("%s Save failed\n", path.c_str()); +} + +CGuildMarkImage * CGuildMarkManager::__GetImage(DWORD imgIdx) +{ + std::map::iterator it = m_mapIdx_Image.find(imgIdx); + + if (it == m_mapIdx_Image.end()) + { + std::string imagePath; + + if (GetMarkImageFilename(imgIdx, imagePath)) + { + CGuildMarkImage * pkImage = __NewImage(); + m_mapIdx_Image.insert(std::map::value_type(imgIdx, pkImage)); + pkImage->Load(imagePath.c_str()); + return pkImage; + } + else + return NULL; + } + else + return it->second; +} + +bool CGuildMarkManager::AddMarkIDByGuildID(DWORD guildID, DWORD markID) +{ + if (markID >= MAX_IMAGE_COUNT * CGuildMarkImage::MARK_TOTAL_COUNT) + return false; + + //sys_log(0, "MarkManager: guild_id=%d mark_id=%d", guildID, markID); + m_mapGID_MarkID.insert(std::map::value_type(guildID, markID)); + m_setFreeMarkID.erase(markID); + return true; +} + +DWORD CGuildMarkManager::GetMarkID(DWORD guildID) +{ + std::map::iterator it = m_mapGID_MarkID.find(guildID); + + if (it == m_mapGID_MarkID.end()) + return INVALID_MARK_ID; + + return it->second; +} + +DWORD CGuildMarkManager::__AllocMarkID(DWORD guildID) +{ + std::set::iterator it = m_setFreeMarkID.lower_bound(0); + + if (it == m_setFreeMarkID.end()) + return INVALID_MARK_ID; + + DWORD markID = *it; + + DWORD imgIdx = markID / CGuildMarkImage::MARK_TOTAL_COUNT; + CGuildMarkImage * pkImage = __GetImage(imgIdx); // ̹ ٸ + + if (pkImage && AddMarkIDByGuildID(guildID, markID)) + return markID; + + return INVALID_MARK_ID; +} + +DWORD CGuildMarkManager::GetMarkImageCount() const +{ + return m_mapIdx_Image.size(); +} + +DWORD CGuildMarkManager::GetMarkCount() const +{ + return m_mapGID_MarkID.size(); +} + +// SERVER +void CGuildMarkManager::CopyMarkIdx(char * pcBuf) const +{ + WORD * pwBuf = (WORD *) pcBuf; + + for (std::map::const_iterator it = m_mapGID_MarkID.begin(); it != m_mapGID_MarkID.end(); ++it) + { + *(pwBuf++) = it->first; // guild id + *(pwBuf++) = it->second; // mark id + } +} + +// SERVER +DWORD CGuildMarkManager::SaveMark(DWORD guildID, BYTE * pbMarkImage) +{ + DWORD idMark; + + if ((idMark = GetMarkID(guildID)) == INVALID_MARK_ID) + { + if ((idMark = __AllocMarkID(guildID)) == INVALID_MARK_ID) + { + sys_err("CGuildMarkManager: cannot alloc mark id %u", guildID); + return false; + } + else + sys_log(0, "SaveMark: mark id alloc %u", idMark); + } + else + sys_log(0, "SaveMark: mark id found %u", idMark); + + DWORD imgIdx = (idMark / CGuildMarkImage::MARK_TOTAL_COUNT); + CGuildMarkImage * pkImage = __GetImage(imgIdx); + + if (pkImage) + { + printf("imgidx %u ", imgIdx); + + std::string pathImage; + GetMarkImageFilename(imgIdx, pathImage); + pkImage->Save(pathImage.c_str()); + + SaveMarkIndex(); + } + + return idMark; +} + +// SERVER +void CGuildMarkManager::DeleteMark(DWORD guildID) +{ + std::map::iterator it = m_mapGID_MarkID.find(guildID); + + if (it == m_mapGID_MarkID.end()) + return; + + CGuildMarkImage * pkImage; + + if ((pkImage = __GetImage(it->second / CGuildMarkImage::MARK_TOTAL_COUNT)) != NULL) + pkImage->DeleteMark(it->second % CGuildMarkImage::MARK_TOTAL_COUNT); + + m_mapGID_MarkID.erase(it); + m_setFreeMarkID.insert(it->second); + + SaveMarkIndex(); +} + +// SERVER +void CGuildMarkManager::GetDiffBlocks(DWORD imgIdx, const DWORD * crcList, std::map & mapDiffBlocks) +{ + mapDiffBlocks.clear(); + + // Ŭ̾Ʈ ̹ û . + if (m_mapIdx_Image.end() == m_mapIdx_Image.find(imgIdx)) + { + sys_err("invalid idx %u", imgIdx); + return; + } + + CGuildMarkImage * p = __GetImage(imgIdx); + + if (p) + p->GetDiffBlocks(crcList, mapDiffBlocks); +} + +// CLIENT +bool CGuildMarkManager::SaveBlockFromCompressedData(DWORD imgIdx, DWORD posBlock, const BYTE * pbBlock, DWORD dwSize) +{ + CGuildMarkImage * pkImage = __GetImage(imgIdx); + + if (pkImage) + pkImage->SaveBlockFromCompressedData(posBlock, pbBlock, dwSize); + + return false; +} + +// CLIENT +bool CGuildMarkManager::GetBlockCRCList(DWORD imgIdx, DWORD * crcList) +{ + // Ŭ̾Ʈ ̹ û . + if (m_mapIdx_Image.end() == m_mapIdx_Image.find(imgIdx)) + { + sys_err("invalid idx %u", imgIdx); + return false; + } + + CGuildMarkImage * p = __GetImage(imgIdx); + + if (p) + p->GetBlockCRCList(crcList); + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////// +// Symbol +/////////////////////////////////////////////////////////////////////////////////////// +const CGuildMarkManager::TGuildSymbol * CGuildMarkManager::GetGuildSymbol(DWORD guildID) +{ + std::map::iterator it = m_mapSymbol.find(guildID); + + if (it == m_mapSymbol.end()) + return NULL; + + return &it->second; +} + +bool CGuildMarkManager::LoadSymbol(const char* filename) +{ + FILE* fp = fopen(filename, "rb"); + + if (!fp) + return true; + else + { + DWORD symbolCount; + fread(&symbolCount, 4, 1, fp); + + for(DWORD i = 0; i < symbolCount; i++) + { + DWORD guildID; + DWORD dwSize; + fread(&guildID, 4, 1, fp); + fread(&dwSize, 4, 1, fp); + + TGuildSymbol gs; + gs.raw.resize(dwSize); + fread(&gs.raw[0], 1, dwSize, fp); + gs.crc = GetCRC32(reinterpret_cast(&gs.raw[0]), dwSize); + m_mapSymbol.insert(std::make_pair(guildID, gs)); + } + } + + fclose(fp); + return true; +} + +void CGuildMarkManager::SaveSymbol(const char* filename) +{ + FILE* fp = fopen(filename, "wb"); + if (!fp) + { + sys_err("Cannot open Symbol file (name: %s)", filename); + return; + } + + DWORD symbolCount = m_mapSymbol.size(); + fwrite(&symbolCount, 4, 1, fp); + + for (std::map::iterator it = m_mapSymbol.begin(); it != m_mapSymbol.end(); ++it) + { + DWORD guildID = it->first; + DWORD dwSize = it->second.raw.size(); + fwrite(&guildID, 4, 1, fp); + fwrite(&dwSize, 4, 1, fp); + fwrite(&it->second.raw[0], 1, dwSize, fp); + } + + fclose(fp); +} + +void CGuildMarkManager::UploadSymbol(DWORD guildID, int iSize, const BYTE* pbyData) +{ + sys_log(0, "GuildSymbolUpload guildID %lu Size %d", guildID, iSize); + + if (m_mapSymbol.find(guildID) == m_mapSymbol.end()) + m_mapSymbol.insert(std::make_pair(guildID, TGuildSymbol())); + + TGuildSymbol& rSymbol = m_mapSymbol[guildID]; + rSymbol.raw.clear(); + + if (iSize > 0) + { + rSymbol.raw.reserve(iSize); + std::copy(pbyData, (pbyData + iSize), std::back_inserter(rSymbol.raw)); + rSymbol.crc = GetCRC32(reinterpret_cast(pbyData), iSize); + } +} + +#ifdef __UNITTEST__ +#include "lzo_manager.h" + +Guild::CGuildMarkManager * mgr; + +void heartbeat(LPHEART ht, int pulse) +{ + return; +} + +void SaveMark(DWORD guildID, const char * filename) +{ + ILuint m_uImg; + + ilGenImages(1, &m_uImg); + ilBindImage(m_uImg); + ilEnable(IL_ORIGIN_SET); + ilOriginFunc(IL_ORIGIN_UPPER_LEFT); + + if (ilLoad(IL_TYPE_UNKNOWN, (const ILstring) filename)) + { + ILuint width = ilGetInteger(IL_IMAGE_WIDTH); + ILuint height = ilGetInteger(IL_IMAGE_HEIGHT); + + ilConvertImage(IL_BGRA, IL_UNSIGNED_BYTE); + + BYTE * data = (BYTE *) malloc(sizeof(DWORD) * width * height); + ilCopyPixels(0, 0, 0, width, height, 1, IL_BGRA, IL_UNSIGNED_BYTE, data); + ilDeleteImages(1, &m_uImg); + + printf("%s w%u h%u ", filename, width, height); + mgr->SaveMark(guildID, data); + } + else + printf("%s cannot open file.\n", filename); +} + +int main(int argc, char **argv) +{ + LZOManager lzo; + char f[64]; + + srandom(time(0)); + + ilInit(); // DevIL Initialize + thecore_init(25, heartbeat); + + std::vector vec_guild_id; + + for (int i = 1; i < 1281; ++i) + vec_guild_id.push_back(i); + + mgr = new CGuildMarkManager; + mgr->LoadMarkData(vec_guild_id); + /* + for (int i = 1401; i < 1500; ++i) + { + snprintf(f, sizeof(f), "%lu.jpg", (random() % 5) + 1); + //SaveMark(i, f); + mgr->DeleteMark(i); + } + */ + //snprintf(f, sizeof(f), "%lu.jpg", (random() % 5) + 1); + //SaveMark(1, f); + DWORD idx_client[CGuildMarkImage::BLOCK_TOTAL_COUNT]; + DWORD idx_server[CGuildMarkImage::BLOCK_TOTAL_COUNT]; + + mgr->GetBlockCRCList(0, idx_client); + mgr->GetBlockCRCList(1, idx_server); + + std::map mapDiff; + mgr->GetDiffBlocks(1, idx_client, mapDiff); + + printf("#1 Diff %u\n", mapDiff.size()); + + for (itertype(mapDiff) it = mapDiff.begin(); it != mapDiff.end(); ++it) + { + printf("Put Block pos %u crc %u\n", it->first, it->second->m_crc); + mgr->SaveBlockFromCompressedData(0, it->first, it->second->m_abCompBuf, it->second->m_sizeCompBuf); + } + + mgr->GetBlockCRCList(0, idx_client); + mgr->GetDiffBlocks(1, idx_client, mapDiff); + printf("#2 Diff %u\n", mapDiff.size()); + delete mgr; + return 1; +} +#endif diff --git a/source/UserInterface/MarkManager.h b/source/UserInterface/MarkManager.h new file mode 100644 index 0000000..f8fa142 --- /dev/null +++ b/source/UserInterface/MarkManager.h @@ -0,0 +1,82 @@ +#ifndef __INC_METIN_II_GUILDLIB_MARK_MANAGER_H__ +#define __INC_METIN_II_GUILDLIB_MARK_MANAGER_H__ + +#include "MarkImage.h" + +class CGuildMarkManager : public singleton +{ + public: + enum + { + MAX_IMAGE_COUNT = 5, + INVALID_MARK_ID = 0xffffffff, + }; + + // Symbol + struct TGuildSymbol + { + DWORD crc; + std::vector raw; + }; + + CGuildMarkManager(); + virtual ~CGuildMarkManager(); + + const TGuildSymbol * GetGuildSymbol(DWORD GID); + bool LoadSymbol(const char* filename); + void SaveSymbol(const char* filename); + void UploadSymbol(DWORD guildID, int iSize, const BYTE* pbyData); + + // + // Mark + // + void SetMarkPathPrefix(const char * prefix); + + bool LoadMarkIndex(); // ũ ε ҷ ( ) + bool SaveMarkIndex(); // ũ ε ϱ + + void LoadMarkImages(); // ũ ̹ ҷ + void SaveMarkImage(DWORD imgIdx); // ũ ̹ + + bool GetMarkImageFilename(DWORD imgIdx, std::string & path) const; + bool AddMarkIDByGuildID(DWORD guildID, DWORD markID); + DWORD GetMarkImageCount() const; + DWORD GetMarkCount() const; + DWORD GetMarkID(DWORD guildID); + + // SERVER + void CopyMarkIdx(char * pcBuf) const; + DWORD SaveMark(DWORD guildID, BYTE * pbMarkImage); + void DeleteMark(DWORD guildID); + void GetDiffBlocks(DWORD imgIdx, const DWORD * crcList, std::map & mapDiffBlocks); + + // CLIENT + bool SaveBlockFromCompressedData(DWORD imgIdx, DWORD idBlock, const BYTE * pbBlock, DWORD dwSize); + bool GetBlockCRCList(DWORD imgIdx, DWORD * crcList); + + private: + // + // Mark + // + CGuildMarkImage * __NewImage(); + void __DeleteImage(CGuildMarkImage * pkImgDel); + + DWORD __AllocMarkID(DWORD guildID); + + CGuildMarkImage * __GetImage(DWORD imgIdx); + CGuildMarkImage * __GetImagePtr(DWORD idMark); + + std::map m_mapIdx_Image; // index = image index + std::map m_mapGID_MarkID; // index = guild id + + std::set m_setFreeMarkID; + std::string m_pathPrefix; + + private: + // + // Symbol + // + std::map m_mapSymbol; +}; + +#endif diff --git a/source/UserInterface/MovieMan.cpp b/source/UserInterface/MovieMan.cpp new file mode 100644 index 0000000..a74a1bb --- /dev/null +++ b/source/UserInterface/MovieMan.cpp @@ -0,0 +1,686 @@ +#include "stdafx.h" +#include "MovieMan.h" +#include "PythonApplication.h" + +// 2007-08-19, nuclei +// add following files to the [Project Settings-Linker-Input] +// DEBUG: ../dshow/strmbasd.lib ../dshow/dmoguids.lib ddraw.lib +// RELEASE: ../dshow/strmbase.lib ../dshow/dmoguids.lib ddraw.lib + +// 2007-08-09, nuclei +// if one of following header files are missing, +// please install "Microsoft Platform SDK for Windows Server 2003 R2" or later +#include "ddraw.h" +#include "mmstream.h" +#include "amstream.h" +#include "ddstream.h" +#include "uuids.h" +#include "control.h" +#include "dmodshow.h" +#include "dmoreg.h" + +#define LOGO_PMANG_FILE "ymir.mpg" +#define LOGO_NW_FILE "logoNW.mpg" +#define LOGO_EA_FILE "logoEA.mpg" +#define LOGO_EA_ENGLISH_FILE "logoEA_english.mpg" +#define LOGO_GAMEON "gameonbi.mpg" //for japan +#define LOGO_IAH_FILE "logoIAH.mpg" +#define INTRO_FILE "intro.mpg" +#define LEGAL_FILE_00 "legal00.mpg" +#define LEGAL_FILE_01 "legal01.mpg" +#define TUTORIAL_0 "TutorialMovie\\Tutorial0.mpg" +#define TUTORIAL_1 "TutorialMovie\\Tutorial1.mpg" +#define TUTORIAL_2 "TutorialMovie\\Tutorial2.mpg" + +void CMovieMan::ClearToBlack() +{ + PAINTSTRUCT ps; + HDC dc; + + // + // Get the repaint DC and then fill the window with black. + // + HWND window = CPythonApplication::Instance().GetWindowHandle();//CFFClientApp::GetInstance()->GetMainWindow(); + InvalidateRect( window, NULL, FALSE ); + dc = BeginPaint( window, &ps ); + + PatBlt( dc, ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom, BLACKNESS); + + EndPaint( window, &ps ); +} + +void CMovieMan::FillRect( RECT& fillRect, DWORD fillColor ) +{ + assert(m_pPrimarySurface); + + if (fillRect.bottom == fillRect.top || fillRect.left == fillRect.right) + { + // ä ʿ + return; + } + + DDBLTFX colorFillBltFX; + colorFillBltFX.dwSize = sizeof(DDBLTFX); + colorFillBltFX.dwFillColor = fillColor; + if (!m_usingRGB32 || FAILED(m_pPrimarySurface->Blt(&fillRect, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &colorFillBltFX))) + { + GDIFillRect(fillRect, fillColor); + return; + } +} + +inline void CMovieMan::GDIFillRect( RECT& fillRect, DWORD fillColor ) +{ + HBRUSH fillBrush = CreateSolidBrush( + RGB((fillColor >> 16) & 255, (fillColor >> 8) & 255, fillColor & 255) + ); + + HDC desktopDC = GetDC(0); + ::FillRect(desktopDC, &fillRect, fillBrush); + ReleaseDC(0, desktopDC); + + DeleteObject(fillBrush); +} + +//---------------------------------------------------------------------------------------------------- +// Ư ǽ GDI ȭ鿡 Ѹ +// +inline void CMovieMan::GDIBlt(IDirectDrawSurface *pSrcSurface, RECT *pDestRect) +{ + HDC surfaceDC; + HDC desktopDC = GetDC(0); + if (SUCCEEDED(pSrcSurface->GetDC(&surfaceDC))) + { + StretchBlt(desktopDC, pDestRect->left, pDestRect->top, pDestRect->right - pDestRect->left, pDestRect->bottom - pDestRect->top, + surfaceDC, 0, 0, m_movieWidth, m_movieHeight, SRCCOPY); + pSrcSurface->ReleaseDC(surfaceDC); + } + ReleaseDC(0, desktopDC); +} + +void CMovieMan::PlayLogo(const char *pcszName) +{ + PlayMovie(pcszName); +} + +void CMovieMan::PlayIntro() +{ + // Ʈ Ű Է̳ 콺 Ŭ ŵ + PlayMovie( INTRO_FILE, MOVIEMAN_SKIPPABLE_YES, MOVIEMAN_POSTEFFECT_FADEOUT, 0xFFFFFF ); +} + +BOOL CMovieMan::PlayTutorial(LONG nIdx) +{ + BOOL bRet = FALSE; + ClearToBlack(); + switch( nIdx ) { + case 0: + bRet = PlayMovie( TUTORIAL_0, MOVIEMAN_SKIPPABLE_YES, MOVIEMAN_POSTEFFECT_FADEOUT, 0xFFFFFF ); + return bRet; + case 1: + bRet = PlayMovie( TUTORIAL_1, MOVIEMAN_SKIPPABLE_YES, MOVIEMAN_POSTEFFECT_FADEOUT, 0xFFFFFF ); + return bRet; + case 2: + bRet = PlayMovie( TUTORIAL_2, MOVIEMAN_SKIPPABLE_YES, MOVIEMAN_POSTEFFECT_FADEOUT, 0xFFFFFF ); + return bRet; + } + return bRet; +} + +BOOL CMovieMan::PlayMovie( const char *cpFileName, const bool bSkipAllowed, const int nPostEffectID, const DWORD dwPostEffectData ) +{ + HWND hWnd = CPythonApplication::Instance().GetWindowHandle(); + + IDirectDraw *pDD = NULL; + DirectDrawCreate(NULL, &pDD, NULL); + pDD->SetCooperativeLevel(hWnd, DDSCL_NORMAL); + + DDSURFACEDESC ddsd; + ZeroMemory(&ddsd, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_CAPS; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + if (FAILED(pDD->CreateSurface(&ddsd, &m_pPrimarySurface, NULL))) + { + pDD->Release(); + return FALSE; + } + + // 32Ʈ ˾ƺ + ZeroMemory(&ddsd, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_PIXELFORMAT; + m_pPrimarySurface->GetSurfaceDesc(&ddsd); + ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat); + m_usingRGB32 = (ddsd.ddpfPixelFormat.dwRGBBitCount == 32); + + IDirectDrawClipper *pDDClipper = NULL; + HRESULT hr = pDD->CreateClipper(0, &pDDClipper, NULL); + if (SUCCEEDED(hr)) + { + pDDClipper->SetHWnd(0, hWnd); + m_pPrimarySurface->SetClipper(pDDClipper); + } + + IMultiMediaStream *pMMStream = NULL; + hr = RenderFileToMMStream(cpFileName, &pMMStream, pDD); + if (SUCCEEDED(hr)) + { + IMediaStream *pPrimaryVidStream = NULL; + HRESULT hr = pMMStream->GetMediaStream(MSPID_PrimaryVideo, &pPrimaryVidStream); + if (SUCCEEDED(hr)) + { + IDirectDrawMediaStream *pDDStream = NULL; + pPrimaryVidStream->QueryInterface(IID_IDirectDrawMediaStream, (void **) &pDDStream); + pPrimaryVidStream->Release(); + + ddsd.dwSize = sizeof(ddsd); + hr = pDDStream->GetFormat(&ddsd, NULL, NULL, NULL); + if (SUCCEEDED(hr)) + { + // ũ ũ⸦ + m_movieWidth = ddsd.dwWidth; + m_movieHeight = ddsd.dwHeight; + + // ۴ RGB32 PrimarySurface ٸ + // GDI fallback ؼ StretchBlt Ѵ + DDSURFACEDESC ddsdBackSurface; + ZeroMemory(&ddsdBackSurface, sizeof(ddsdBackSurface)); + ddsdBackSurface.ddpfPixelFormat.dwSize = sizeof(ddsdBackSurface.ddpfPixelFormat); + ddsdBackSurface.ddpfPixelFormat.dwFlags = DDPF_RGB; + ddsdBackSurface.ddpfPixelFormat.dwRGBBitCount = 32; + ddsdBackSurface.ddpfPixelFormat.dwRBitMask = 255 << 16; + ddsdBackSurface.ddpfPixelFormat.dwGBitMask = 255 << 8; + ddsdBackSurface.ddpfPixelFormat.dwBBitMask = 255; + ddsdBackSurface.dwSize = sizeof(ddsdBackSurface); + ddsdBackSurface.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT; + ddsdBackSurface.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + ddsdBackSurface.dwHeight = m_movieHeight; + ddsdBackSurface.dwWidth = m_movieWidth; + + IDirectDrawSurface *pSurface; + hr = pDD->CreateSurface(&ddsdBackSurface, &pSurface, NULL); + if (SUCCEEDED(hr)) + { + RenderStreamToSurface(pSurface, pDDStream, pMMStream, bSkipAllowed, nPostEffectID, dwPostEffectData); + pSurface->Release(); + } + } + pDDStream->Release(); + } + pMMStream->Release(); + } + + m_pPrimarySurface->Release(); + m_pPrimarySurface = NULL; + + if (m_pBasicAudio) + { + m_pBasicAudio->Release(); + m_pBasicAudio = NULL; + } + + if (pDDClipper) + { + pDDClipper->Release(); + pDDClipper = NULL; + } + + pDD->Release(); + + // Ű, 콺 + MSG msg; + while (PeekMessage(&msg, hWnd, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE)); + while (PeekMessage(&msg, hWnd, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE)); + + return SUCCEEDED(hr); +} + +//---------------------------------------------------------------------------------------------------- +// Screen ǥ ȯ +// +void CMovieMan::GetWindowRect(RECT& windowRect) +{ + HWND hWnd = CPythonApplication::Instance().GetWindowHandle(); + POINT p; + + // + // Get the position of the upper-left client coordinate (in screen space). + // + p.x = 0; + p.y = 0; + ClientToScreen( hWnd, &p ); + + // + // Get the client rectangle of the window. + // + GetClientRect( hWnd, &windowRect ); + + // clientRect ClientToScreen ϴ Ͱ + OffsetRect( &windowRect, p.x, p.y ); +} + +//---------------------------------------------------------------------------------------------------- +// 쿡 ä RECT ȯ(/ ) +// +void CMovieMan::CalcMovieRect(int srcWidth, int srcHeight, RECT& movieRect) +{ + RECT windowRect; + GetWindowRect(windowRect); + + int nMovieWidth, nMovieHeight; + if (srcWidth >= srcHeight) + { + nMovieWidth = (windowRect.right - windowRect.left); + nMovieHeight = srcHeight * nMovieWidth / srcWidth; + if( nMovieHeight > windowRect.bottom - windowRect.top ) + nMovieHeight = windowRect.bottom - windowRect.top; + } + else + { + nMovieHeight = (windowRect.bottom - windowRect.top); + nMovieWidth = srcWidth * nMovieHeight / srcHeight; + if( nMovieWidth > windowRect.right - windowRect.left ) + nMovieWidth = windowRect.right - windowRect.left; + } + movieRect.left = windowRect.left + ((windowRect.right - windowRect.left) - nMovieWidth) / 2; + movieRect.top = windowRect.top + ((windowRect.bottom - windowRect.top) - nMovieHeight) / 2; + movieRect.right = movieRect.left + nMovieWidth; + movieRect.bottom = movieRect.top + nMovieHeight; +} + +//---------------------------------------------------------------------------------------------------- +// ȭ ƴ , ׻ 2 RECT ǥ +// +void CMovieMan::CalcBackgroundRect(const RECT& movieRect, RECT& upperRect, RECT& lowerRect) +{ + RECT windowRect; + GetWindowRect(windowRect); + + if (m_movieWidth > m_movieHeight) + { + // Ʒ ΰ + SetRect(&upperRect, windowRect.left, windowRect.top, windowRect.right, movieRect.top); + SetRect(&lowerRect, windowRect.left, movieRect.bottom, windowRect.right, windowRect.bottom); + } + else + { + // ¿ ΰ + SetRect(&upperRect, windowRect.left, windowRect.top, movieRect.left, windowRect.bottom); + SetRect(&lowerRect, movieRect.right, windowRect.top, windowRect.right, windowRect.bottom); + } +} + +//---------------------------------------------------------------------------------------------------- +// Ư ǽ Blocking ׸ +// +HRESULT CMovieMan::RenderStreamToSurface(IDirectDrawSurface *pSurface, IDirectDrawMediaStream *pDDStream, IMultiMediaStream *pMMStream, bool bSkipAllowed, int nPostEffectID, DWORD dwPostEffectData) +{ + #define KEY_DOWN(vk) (GetAsyncKeyState(vk) & 0x8000) + + IDirectDrawStreamSample *pSample = NULL; + HRESULT hr = pDDStream->CreateSample(pSurface, NULL, 0, &pSample); + if (SUCCEEDED(hr)) + { + // ѹ ĥش + RECT movieRect; + RECT upperRect, lowerRect; + CalcMovieRect(m_movieWidth, m_movieHeight, movieRect); + CalcBackgroundRect(movieRect, upperRect, lowerRect); + FillRect(upperRect, 0); + FillRect(lowerRect, 0); + + pMMStream->SetState(STREAMSTATE_RUN); + while (pSample->Update(0, NULL, NULL, NULL) == S_OK) + { + // ߾ ׸ + CalcMovieRect(m_movieWidth, m_movieHeight, movieRect); + if (FAILED(m_pPrimarySurface->Blt(&movieRect, pSurface, NULL, DDBLT_WAIT, NULL))) + { + GDIBlt(pSurface, &movieRect); + } + + // ߰ ŵ ϸ ŰESC/콺 Է½ Ż + if (bSkipAllowed && (KEY_DOWN(VK_LBUTTON) || KEY_DOWN(VK_ESCAPE) || KEY_DOWN(VK_SPACE))) + { + break; + } + } + + // ÿ 2 ̵ƿ + switch(nPostEffectID) + { + case MOVIEMAN_POSTEFFECT_FADEOUT: + RenderPostEffectFadeOut(pSurface, MOVIEMAN_FADE_DURATION, dwPostEffectData); + break; + } + + pMMStream->SetState(STREAMSTATE_STOP); + pSample->Release(); + } + + return hr; +} + +HRESULT CMovieMan::RenderFileToMMStream(const char *cpFilename, IMultiMediaStream **ppMMStream, IDirectDraw *pDD) +{ + IAMMultiMediaStream *pAMStream; + HRESULT hr = CoCreateInstance(CLSID_AMMultiMediaStream, NULL, CLSCTX_INPROC_SERVER, IID_IAMMultiMediaStream, (void **) &pAMStream); + if (FAILED(hr)) + { + return hr; + } + + WCHAR wPath[MAX_PATH + 1]; + MultiByteToWideChar(CP_ACP, 0, cpFilename, -1, wPath, MAX_PATH + 1); + // + WCHAR wsDir[MAX_PATH + 1]; + ::memset(wsDir, 0, sizeof(wsDir)); + ::GetCurrentDirectoryW( MAX_PATH, wsDir ); + ::wcsncat( wsDir, L"\\", sizeof(WCHAR)*1 ); + ::wcsncat( wsDir, wPath, sizeof(WCHAR)*::wcsnlen(wPath, MAX_PATH) ); + ::memset(wPath, 0, sizeof(wPath)); + ::wcsncpy( wPath, wsDir, sizeof(WCHAR)*::wcsnlen(wsDir, MAX_PATH) ); + // + + pAMStream->Initialize(STREAMTYPE_READ, AMMSF_NOGRAPHTHREAD, NULL); + pAMStream->AddMediaStream(pDD, &MSPID_PrimaryVideo, 0, NULL); + pAMStream->AddMediaStream(NULL, &MSPID_PrimaryAudio, AMMSF_ADDDEFAULTRENDERER, NULL); + + std::string ext; + GetFileExtension(cpFilename, strlen(cpFilename), &ext); + std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower); + if (ext == "mpg") + { + // 2007-08-01, nuclei + // MPG Ѵٰ ϰ Ŵ ڵ + // ܺ ڵ(ffdshow ) ʵ Ѵ + // (Ÿ ϵ ڵ ) + hr = BuildFilterGraphManually(wPath, pAMStream, CLSID_MPEG1Splitter, CLSID_CMpegVideoCodec, CLSID_CMpegAudioCodec); + } + else if (ext == "mp43") + { + // 2007-08-12, nuclei + // MPEG-4, MP3 ڵ ̿ AVI ߰(Ȯڴ .mp43 ؾ) + hr = BuildFilterGraphManually(wPath, pAMStream, CLSID_AviSplitter, CLSID_MP4VideoCodec, CLSID_MP3AudioCodec); + } + else + { + hr = pAMStream->OpenFile(wPath, 0); + } + + // hr S_OK + if (SUCCEEDED(hr)) + { + pAMStream->QueryInterface(IID_IMultiMediaStream, (void**) ppMMStream); + } + + pAMStream->Release(); + + return hr; +} + +//---------------------------------------------------------------------------------------------------- +// Ư ȭ ų ο +// +HRESULT CMovieMan::RenderPostEffectFadeOut(IDirectDrawSurface *pSurface, int fadeOutDuration, DWORD fadeOutColor) +{ + // Lock ɱ ʱȭ + DDSURFACEDESC lockedSurfaceDesc; + + int *pCopiedSrcSurBuf = NULL; + LONG fadeBegin = GetTickCount(); + float fadeProgress = 0.0; + while ((fadeProgress = ((float)((LONG)GetTickCount()) - fadeBegin) / fadeOutDuration) < 1.0) + { + ZeroMemory(&lockedSurfaceDesc, sizeof(lockedSurfaceDesc)); + lockedSurfaceDesc.dwSize = sizeof(lockedSurfaceDesc); + HRESULT hr = pSurface->Lock(NULL, &lockedSurfaceDesc, DDLOCK_WAIT | DDLOCK_NOSYSLOCK | DDLOCK_READONLY, NULL); + if (FAILED(hr)) + { + return hr; + } + + // 1ȸ ǽ ϰ 纻 FadeOut óѴ + if (!pCopiedSrcSurBuf) + { + if (!(pCopiedSrcSurBuf = (int*)malloc((LONG)lockedSurfaceDesc.lPitch * m_movieHeight))) + { + pSurface->Unlock(lockedSurfaceDesc.lpSurface); + return E_OUTOFMEMORY; + } + CopyMemory(pCopiedSrcSurBuf, lockedSurfaceDesc.lpSurface, (LONG)lockedSurfaceDesc.lPitch * m_movieHeight); + } + + // ȼ ö(32Ʈ) + int *pSrcSurfaceBuf = pCopiedSrcSurBuf; + int *pDestSurfaceBuf = (int*)lockedSurfaceDesc.lpSurface; + + int fadeOutColorRed = (int)(((fadeOutColor >> 16) & 255) * fadeProgress); + int fadeOutColorGreen = (int)(((fadeOutColor >> 8) & 255) * fadeProgress); + int fadeOutColorBlue = (int)((fadeOutColor & 255) * fadeProgress); + for(int y = 0; y < m_movieHeight; ++y) + { + for(int x = 0; x < m_movieWidth; ++x) + { + DWORD srcPixel = *pSrcSurfaceBuf; + *pDestSurfaceBuf = RGB( + (srcPixel & 255) * (1 - fadeProgress) + fadeOutColorBlue, + ((srcPixel >> 8) & 255) * (1 - fadeProgress) + fadeOutColorGreen, + ((srcPixel >> 16) & 255) * (1 - fadeProgress) + fadeOutColorRed); + pSrcSurfaceBuf++; + pDestSurfaceBuf++; + } + pSrcSurfaceBuf += (lockedSurfaceDesc.lPitch / 4) - m_movieWidth; + pDestSurfaceBuf += (lockedSurfaceDesc.lPitch / 4) - m_movieWidth; + } + pSurface->Unlock(lockedSurfaceDesc.lpSurface); + + // ٲ ̹ ׸ + RECT movieRect; + CalcMovieRect(m_movieWidth, m_movieHeight, movieRect); + if (FAILED(m_pPrimarySurface->Blt(&movieRect, pSurface, NULL, DDBLT_WAIT, NULL))) + { + GDIBlt(pSurface, &movieRect); + } + + // Ǵ ĭ ä + RECT upperRect, lowerRect; + CalcBackgroundRect(movieRect, upperRect, lowerRect); + FillRect(upperRect, (fadeOutColorRed << 16) | (fadeOutColorGreen << 8) | fadeOutColorBlue); + FillRect(lowerRect, (fadeOutColorRed << 16) | (fadeOutColorGreen << 8) | fadeOutColorBlue); + + // + if (m_pBasicAudio) + { + m_pBasicAudio->put_Volume((long)(-10000 * fadeProgress)); + } + } + + // ޸ + free(pCopiedSrcSurBuf); + + // 1.0 FadeOut ȭ ׸ + RECT windowRect; + GetWindowRect(windowRect); + FillRect(windowRect, fadeOutColor); + + return S_OK; +} + +//---------------------------------------------------------------------------------------------------- +// MPEG-1 ܺ ڵ ϴ Լ +// +HRESULT CMovieMan::BuildFilterGraphManually( + WCHAR* wpFilename, + IAMMultiMediaStream *pAMStream, + const GUID FAR clsidSplitter, + const GUID FAR clsidVideoCodec, + const GUID FAR clsidAudioCodec) +{ + IGraphBuilder* pGraphBuilder = NULL; + pAMStream->GetFilterGraph(&pGraphBuilder); + + assert(pGraphBuilder); + +//#ifdef _DEBUG +// DWORD dwRegister; +// AddToRot(pGraphBuilder, &dwRegister); +//#endif + + IBaseFilter *pSourceFilter = NULL; + IBaseFilter *pSplitterFilter = NULL; + IBaseFilter *pVideoFilter = NULL; + IBaseFilter *pAudioFilter = NULL; + + CoCreateInstance(clsidSplitter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **) &pSplitterFilter); + CoCreateInstance(clsidVideoCodec, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **) &pVideoFilter); + CoCreateInstance(clsidAudioCodec, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **) &pAudioFilter); + + // MP43 ڴ ٸ DMO ڵ ־ش + // MONSTER ߰ߵ ̽(ڵ ) + if (!pVideoFilter && IsEqualGUID(clsidVideoCodec, CLSID_MP4VideoCodec)) + { + // Create the DMO Wrapper filter. + HRESULT hr = CoCreateInstance(CLSID_DMOWrapperFilter, NULL, CLSCTX_INPROC, IID_IBaseFilter, (void **)&pVideoFilter); + if (SUCCEEDED(hr)) + { + IDMOWrapperFilter *pWrap; + hr = pVideoFilter->QueryInterface(IID_IDMOWrapperFilter, (void **)&pWrap); + if (SUCCEEDED(hr)) + { + hr = pWrap->Init(CLSID_MP43DMOCodec, DMOCATEGORY_VIDEO_DECODER); + pWrap->Release(); + } + } + } + + pGraphBuilder->AddSourceFilter(wpFilename, L"Source Filter", &pSourceFilter); + pGraphBuilder->AddFilter(pSplitterFilter, L"Splitter"); + pGraphBuilder->AddFilter(pVideoFilter, L"Video Decoder"); + pGraphBuilder->AddFilter(pAudioFilter, L"Audio Decoder"); + + assert(m_pBasicAudio == NULL); + pGraphBuilder->QueryInterface(IID_IBasicAudio, (void**) &m_pBasicAudio); + + // Connect "Source" -> "Splitter" + IPin *pInPin = NULL; + IPin *pOutPin = NULL; + IPin *pSplitterVideoOutPin = NULL; + IPin *pSplitterAudioOutPin = NULL; + IEnumPins *pEnumPins = NULL; + pSourceFilter->EnumPins(&pEnumPins); + pEnumPins->Next(1, &pOutPin, NULL); + pEnumPins->Release(); + pSplitterFilter->EnumPins(&pEnumPins); + pEnumPins->Next(1, &pInPin, NULL); + pEnumPins->Release(); + HRESULT hr = pGraphBuilder->Connect(pOutPin, pInPin); + pInPin->Release(); + pOutPin->Release(); + if (SUCCEEDED(hr)) + { + // Ŀ Output ɵ Ÿ + pSplitterFilter->EnumPins(&pEnumPins); + PIN_INFO pinInfo; + while( SUCCEEDED(pEnumPins->Next(1, &pInPin, NULL)) ) + { + pInPin->QueryPinInfo(&pinInfo); + pinInfo.pFilter->Release(); + if (pinInfo.dir == PINDIR_OUTPUT) + { + // Pin - + pSplitterVideoOutPin = pInPin; + pEnumPins->Next(1, &pSplitterAudioOutPin, NULL); + break; + } + pInPin->Release(); + } + pEnumPins->Release(); + + // Splitter -> Video/Audio codecs + pVideoFilter->EnumPins(&pEnumPins); + pEnumPins->Next(1, &pInPin, NULL); + pEnumPins->Next(1, &pOutPin, NULL); + pEnumPins->Release(); + hr = pGraphBuilder->Connect(pSplitterVideoOutPin, pInPin); + if (SUCCEEDED(hr)) + { + // + hr = pGraphBuilder->Render(pOutPin); + pInPin->Release(); + pOutPin->Release(); + + // Ͽ ִ + if (pSplitterAudioOutPin && pAudioFilter) + { + pAudioFilter->EnumPins(&pEnumPins); + pEnumPins->Next(1, &pInPin, NULL); + pEnumPins->Next(1, &pOutPin, NULL); + pEnumPins->Release(); + pGraphBuilder->Connect(pSplitterAudioOutPin, pInPin); + // ص Ѿ + pGraphBuilder->Render(pOutPin); + pInPin->Release(); + pOutPin->Release(); + } + } + } + + // +//#ifdef _DEBUG +// RemoveFromRot(dwRegister); +//#endif + + if (pSplitterVideoOutPin) + { + pSplitterVideoOutPin->Release(); + } + if (pSplitterAudioOutPin) + { + pSplitterAudioOutPin->Release(); + } + pVideoFilter->Release(); + if (pAudioFilter) + { + pAudioFilter->Release(); + } + pSplitterFilter->Release(); + pSourceFilter->Release(); + pGraphBuilder->Release(); + + return hr; +} + +//#ifdef _DEBUG +//HRESULT CMovieMan::AddToRot(IGraphBuilder* pGraphBuilder, DWORD *pdwRegister) +//{ +// assert(pGraphBuilder); +// +// IMoniker *pMoniker; +// IRunningObjectTable *pROT; +// if (FAILED(GetRunningObjectTable(0, &pROT))) { +// return E_FAIL; +// } +// +// ZString monikerName; +// monikerName.Format(_T("FilterGraph %08x pid %08x"), (DWORD_PTR)pGraphBuilder, GetCurrentProcessId()); +// HRESULT hr = CreateItemMoniker(L"!", monikerName, &pMoniker); +// if (SUCCEEDED(hr)) { +// hr = pROT->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, pGraphBuilder, +// pMoniker, pdwRegister); +// pMoniker->Release(); +// } +// pROT->Release(); +// return hr; +//} +// +//void CMovieMan::RemoveFromRot(DWORD pdwRegister) +//{ +// IRunningObjectTable *pROT; +// if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) { +// pROT->Revoke(pdwRegister); +// pROT->Release(); +// } +//} +//#endif diff --git a/source/UserInterface/MovieMan.h b/source/UserInterface/MovieMan.h new file mode 100644 index 0000000..54acfc9 --- /dev/null +++ b/source/UserInterface/MovieMan.h @@ -0,0 +1,78 @@ +#pragma once + +// ̵ƿ () +#define MOVIEMAN_FADE_DURATION 1300 +#define MOVIEMAN_SKIPPABLE_YES true +#define MOVIEMAN_POSTEFFECT_FADEOUT 1 + +// DX 7.0 +struct IDirectDraw; +struct IDirectDrawSurface; +struct IDirectDrawMediaStream; +struct IGraphBuilder; +struct IBasicAudio; +struct IMultiMediaStream; +struct IAMMultiMediaStream; + +const GUID CLSID_MP43DMOCodec = { 0xcba9e78b, 0x49a3, 0x49ea, 0x93, 0xd4, 0x6b, 0xcb, 0xa8, 0xc4, 0xde, 0x07 }; +const GUID CLSID_MP4VideoCodec = { 0x82ccd3e0, 0xf71a, 0x11d0, 0x9f, 0xe5, 0x0, 0x60, 0x97, 0x78, 0xea, 0x66 }; +const GUID CLSID_MP3AudioCodec = { 0x38be3000, 0xdbf4, 0x11d0, 0x86, 0x0e, 0x0, 0xa0, 0x24, 0xcf, 0xef, 0x6d }; +const GUID CLSID_DIrectSoundRenderer = { 0x79376820, 0x07D0, 0x11CF, 0xA2, 0x4D, 0x0, 0x20, 0xAF, 0xD7, 0x97, 0x67 }; + +class CMovieMan : public CSingleton +{ +public: + CMovieMan() + : m_movieWidth(0), + m_movieHeight(0), + m_usingRGB32(false), + m_pPrimarySurface(NULL), + m_pBasicAudio(NULL) + { + CoInitialize(NULL); + }; + + virtual ~CMovieMan() + { + CoUninitialize(); + }; + + void ClearToBlack(); + void PlayLogo(const char *pcszName); + void PlayIntro(); + BOOL PlayTutorial(LONG nIdx); + +private: + bool m_usingRGB32; + int m_movieWidth; + int m_movieHeight; + RECT m_movieRect; + IDirectDrawSurface* m_pPrimarySurface; + IBasicAudio* m_pBasicAudio; + + void FillRect(RECT& fillRect, DWORD fillColor); + inline void GDIFillRect(RECT& fillRect, DWORD fillColor); + inline void GDIBlt(IDirectDrawSurface *pSrcSurface, RECT *pDestRect); + + void GetWindowRect(RECT& windowRect); + void CalcMovieRect(int srcWidth, int srcHeight, RECT& movieRect); + void CalcBackgroundRect(const RECT& movieRect, RECT& upperRect, RECT& lowerRect); + + BOOL PlayMovie(const char *cpFileName, const bool bSkipAllowed = FALSE, const int nPostEffectID = 0, const DWORD dwPostEffectData = 0); + + HRESULT BuildFilterGraphManually( + WCHAR* wpFilename, + IAMMultiMediaStream *pAMStream, + const GUID FAR clsidSplitter, + const GUID FAR clsidVideoCodec, + const GUID FAR clsidAudioCodec); + + HRESULT RenderFileToMMStream(const char *cpFilename, IMultiMediaStream **ppMMStream, IDirectDraw *pDD); + HRESULT RenderStreamToSurface(IDirectDrawSurface *pSurface, IDirectDrawMediaStream *pDDStream, IMultiMediaStream *pMMStream, bool bSkipAllowed, int nPostEffectID, DWORD dwPostEffectData); + HRESULT RenderPostEffectFadeOut(IDirectDrawSurface *pSurface, int fadeOutDuration, DWORD fadeOutColor); + +//#ifdef _DEBUG +// HRESULT AddToRot(IGraphBuilder* pGraphBuilder, DWORD *pdwRegister); +// void RemoveFromRot(DWORD pdwRegister); +//#endif +}; diff --git a/source/UserInterface/NProtectGameGuard.cpp b/source/UserInterface/NProtectGameGuard.cpp new file mode 100644 index 0000000..541d698 --- /dev/null +++ b/source/UserInterface/NProtectGameGuard.cpp @@ -0,0 +1,261 @@ +#include "StdAfx.h" +#include "NProtectGameGuard.h" + +#ifdef USE_NPROTECT_GAMEGUARD + +static struct GameGuard +{ + bool isInitError; + bool isProcError; + unsigned msg; + unsigned arg; +} gs_gameGuard = { + false, 0, 0, +}; + +#ifdef LOCALE_SERVICE_HONGKONG +#include "NProtect/NPGameLibHK.h" +#pragma comment(lib, "NPGameLibHK_MT.lib") +CNPGameLib npgl("Metin2HK"); +#endif + +#ifdef LOCALE_SERVICE_TAIWAN +#include "NProtect/NPGameLibTW.h" +#pragma comment(lib, "NPGameLibTW_MT.lib") +CNPGameLib npgl("Metin2TW"); +#endif + +#ifdef LOCALE_SERVICE_EUROPE +#include "NProtect/NPGameLibEU.h" +#pragma comment(lib, "NPGameLibEU_MT.lib") +CNPGameLib npgl("Metin2EU"); +#endif + +BOOL CALLBACK NPGameMonCallback(DWORD msg, DWORD arg) +{ + switch (msg) + { + case NPGAMEMON_COMM_ERROR: + case NPGAMEMON_COMM_CLOSE: + case NPGAMEMON_INIT_ERROR: + case NPGAMEMON_SPEEDHACK: + case NPGAMEMON_GAMEHACK_KILLED: + case NPGAMEMON_GAMEHACK_DETECT: + case NPGAMEMON_GAMEHACK_DOUBT: + gs_gameGuard.msg = msg; + gs_gameGuard.arg = arg; + gs_gameGuard.isProcError = true; + return false; + break; + } + return true; +} + +bool LocaleService_IsGameGuardError() +{ + return gs_gameGuard.isProcError; +} + +bool LocaleService_InitGameGuard() +{ + unsigned result = npgl.Init(); + if (NPGAMEMON_SUCCESS != result) + { + gs_gameGuard.isInitError = true; + gs_gameGuard.msg = result; + return false; + } + return true; +} + +bool LocaleService_RunGameGuard(HWND hWnd) +{ + npgl.SetHwnd(hWnd); + return true; +} + +void LocaleService_NoticeGameGuardInitError_HongKong() +{ + char msg[256]; + switch (gs_gameGuard.msg) + { + case NPGAMEMON_ERROR_EXIST: + sprintf(msg, "GameGuard?Cy??άO?sҰʤA?C "); + break; + case NPGAMEMON_ERROR_GAME_EXIST: + sprintf(msg, "C?ư?GameGuardwb?C?C?s?C "); + break; + case NPGAMEMON_ERROR_INIT: + sprintf(msg, "GameGuardƿ?C?sҰʫA?άOi??oͽĬ?A?C "); + break; + case NPGAMEMON_ERROR_AUTH_GAMEGUARD: + case NPGAMEMON_ERROR_NFOUND_GG: + case NPGAMEMON_ERROR_AUTH_INI: + case NPGAMEMON_ERROR_NFOUND_INI: + sprintf(msg, "LGameGuard?βͲܡCЦwGameGuard wɡC "); + break; + case NPGAMEMON_ERROR_CRYPTOAPI: + sprintf(msg, "WindowYt?lC?swIEC "); + break; + case NPGAMEMON_ERROR_EXECUTE: + sprintf(msg, "GameGuard?ѡC?s?GameGuardwɡC "); + break; + case NPGAMEMON_ERROR_ILLEGAL_PRG: + sprintf(msg, "o?Dk?Cе?ݭn??s?C "); + break; + case NPGMUP_ERROR_ABORT: + sprintf(msg, "GameGuard??CpG?LksuA?վ?H?wC "); + break; + case NPGMUP_ERROR_CONNECT: + case NPGMUP_ERROR_DOWNCFG: + sprintf(msg, "GameGuard睊(?)?AsuѡCyA?s?άOpG?H𪺸ܽнվ?H?wAաC "); + break; + case NPGMUP_ERROR_AUTH: + sprintf(msg, "GameGuard睊S?C??r?A?s?άOϥPC޲z?վ?wA?C "); + break; + case NPGAMEMON_ERROR_NPSCAN: + sprintf(msg, "frεnJbȤJIuˬdҲեѡCi?OO餣άOPVFfrC "); + break; + default: + sprintf(msg, "GameGuard??o??CбNC?̪GameGuard?*.erl?Hqll??Hgame2@inca.co.krHcC "); + break; + } + + MessageBox(NULL, msg, "GameGuard ?", MB_OK); +} + +void LocaleService_NoticeGameGuardInitError_International() +{ + char msg[256]; + switch (gs_gameGuard.msg) + { + case NPGAMEMON_ERROR_EXIST: + sprintf(msg, "GameGuard is already running.\nPlease reboot and restart the game."); + break; + case NPGAMEMON_ERROR_GAME_EXIST: + sprintf(msg, "GameGuard is already running.\nPlease restart the game."); + break; + case NPGAMEMON_ERROR_INIT: + sprintf(msg, "GameGuard has initial error.\nPlease kill other conflict programs and restart game."); + break; + case NPGAMEMON_ERROR_AUTH_GAMEGUARD: + case NPGAMEMON_ERROR_NFOUND_GG: + case NPGAMEMON_ERROR_AUTH_INI: + case NPGAMEMON_ERROR_NFOUND_INI: + sprintf(msg, "GameGuard files are modified or deleted.\nPlease reinstall GameGuard."); + break; + case NPGAMEMON_ERROR_CRYPTOAPI: + sprintf(msg, "GameGuard detects Windows system file error.\nPlease reinstall Internet Explorer(IE)"); + break; + case NPGAMEMON_ERROR_EXECUTE: + sprintf(msg, "GameGuard running is failed.\nPlease reinstall GameGuard."); + break; + case NPGAMEMON_ERROR_ILLEGAL_PRG: + sprintf(msg, "GameGuard detects Illegal Program.\nPlease kill other programs not needs and restart game"); + break; + case NPGMUP_ERROR_ABORT: + sprintf(msg, "GameGuard update was canceled.\nWhen not connect, change the internal or private firewall settings"); + break; + case NPGMUP_ERROR_CONNECT: + sprintf(msg, "GameGuard hooking is failed.\nPlease download newer anti-virus and check all system."); + break; + case NPGAMEMON_ERROR_GAMEGUARD: + sprintf(msg, "GameGuard has initial error or old game guard.\nPlease reinstall GameGuard"); + break; + case NPGMUP_ERROR_PARAM: + sprintf(msg, "GameGuard detects .ini file is modified.\nPlease reinstall GameGuard"); + break; + case NPGMUP_ERROR_INIT: + sprintf(msg, "GameGuard detects npgmup.des initial error.\nPlease delete GameGuard Folder and reinstall GameGuard"); + break; + case NPGMUP_ERROR_DOWNCFG: + sprintf(msg, "GameGuard update server connection is failed.\nPlease restart or check private firewall settings."); + break; + case NPGMUP_ERROR_AUTH: + sprintf(msg, "GameGuard update is not completed.\nPlease pause anti-virus and restart game."); + break; + case NPGAMEMON_ERROR_NPSCAN: + sprintf(msg, "GameGuard virus-hacking checker loading is failed\nPlease check memory lack or virus."); + break; + default: + sprintf(msg, "UnknownErrorCode: %d\nPlease send a letter that has *.erl in game folder to Game1@inca.co.kr", gs_gameGuard.msg); + break; + } + + MessageBox(NULL, msg, "GameGuard Initiail Error", MB_OK); +} + +void LocaleService_NoticeGameGuardProcError_HongKong() +{ + char msg[256]; + switch (gs_gameGuard.msg) + { + case NPGAMEMON_COMM_ERROR: + case NPGAMEMON_COMM_CLOSE: + return; + case NPGAMEMON_INIT_ERROR: + sprintf(msg, "GameGuardƿ? : %lu", gs_gameGuard.arg); + break; + case NPGAMEMON_SPEEDHACK: + sprintf(msg, "o?speed hackC "); + break; + case NPGAMEMON_GAMEHACK_KILLED: + sprintf(msg, "o?ChackC "); + break; + case NPGAMEMON_GAMEHACK_DETECT: + sprintf(msg, "o?ChackC "); + break; + case NPGAMEMON_GAMEHACK_DOUBT: + sprintf(msg, "CGameGuardw?C "); + break; + } + MessageBox(NULL, msg, "GameGuard Error", MB_OK); +} + +void LocaleService_NoticeGameGuardProcError_International() +{ + char msg[256]; + switch (gs_gameGuard.msg) + { + case NPGAMEMON_COMM_ERROR: + case NPGAMEMON_COMM_CLOSE: + break; + case NPGAMEMON_INIT_ERROR: + wsprintf(msg, "GameGuard has initial error : %lu", gs_gameGuard.arg); + break; + case NPGAMEMON_SPEEDHACK: + wsprintf(msg, "GameGuard detects SpeedHack"); + break; + case NPGAMEMON_GAMEHACK_KILLED: + wsprintf(msg, "GameGuard detects GameHack\r\n%s", npgl.GetInfo()); + break; + case NPGAMEMON_GAMEHACK_DETECT: + wsprintf(msg, "GameGuard detects GameHack\r\n%s", npgl.GetInfo()); + break; + case NPGAMEMON_GAMEHACK_DOUBT: + wsprintf(msg, "Game or Gamguard was modified."); + break; + } + MessageBox(NULL, msg, "GameGuard Error", MB_OK); +} + +void LocaleService_NoticeGameGuardMessasge() +{ + if (gs_gameGuard.isInitError) + { + if (LocaleService_IsHONGKONG()) + LocaleService_NoticeGameGuardInitError_HongKong(); + else + LocaleService_NoticeGameGuardInitError_International(); + + } + else if (gs_gameGuard.isProcError) + { + if (LocaleService_IsHONGKONG()) + LocaleService_NoticeGameGuardProcError_HongKong(); + else + LocaleService_NoticeGameGuardProcError_International(); + } +} + +#endif /* USE_NPROTECT_GAMEGUARD */ diff --git a/source/UserInterface/NProtectGameGuard.h b/source/UserInterface/NProtectGameGuard.h new file mode 100644 index 0000000..b020077 --- /dev/null +++ b/source/UserInterface/NProtectGameGuard.h @@ -0,0 +1,10 @@ +#pragma once + +#ifdef USE_NPROTECT_GAMEGUARD + +bool GameGuard_Init(); +bool GameGuard_IsError(); +bool GameGuard_Run(HWND hWnd); +void GameGuard_NoticeMessage(); + +#endif /* USE_NPROTECT_GAMEGUARD */ diff --git a/source/UserInterface/NetworkActorManager.cpp b/source/UserInterface/NetworkActorManager.cpp new file mode 100644 index 0000000..f3d8c4c --- /dev/null +++ b/source/UserInterface/NetworkActorManager.cpp @@ -0,0 +1,582 @@ +#include "StdAfx.h" +#include "NetworkActorManager.h" +#include "PythonCharacterManager.h" +#include "PythonItem.h" + +#include "AbstractPlayer.h" + +void SNetworkActorData::UpdatePosition() +{ + DWORD dwClientCurTime=ELTimer_GetMSec(); + DWORD dwElapsedTime=dwClientCurTime-m_dwClientSrcTime; + + if (dwElapsedTime::iterator i; + for (i=m_kNetActorDict.begin(); i!=m_kNetActorDict.end(); ++i) + { + SNetworkActorData& rkNetActorData=i->second; + rkNetActorData.UpdatePosition(); + + CInstanceBase * pkInstFind = rkChrMgr.GetInstancePtr(rkNetActorData.m_dwVID); + if (!pkInstFind) + { + if (__IsVisibleActor(rkNetActorData)) + __AppendCharacterManagerActor(rkNetActorData); + } + } +} + +CInstanceBase* CNetworkActorManager::__FindActor(SNetworkActorData& rkNetActorData, LONG lDstX, LONG lDstY) +{ + CPythonCharacterManager& rkChrMgr=__GetCharacterManager(); + CInstanceBase * pkInstFind = rkChrMgr.GetInstancePtr(rkNetActorData.m_dwVID); + if (!pkInstFind) + { + if (__IsVisiblePos(lDstX, lDstY)) + return __AppendCharacterManagerActor(rkNetActorData); + + return NULL; + } + + return pkInstFind; +} + +CInstanceBase* CNetworkActorManager::__FindActor(SNetworkActorData& rkNetActorData) +{ + CPythonCharacterManager& rkChrMgr=__GetCharacterManager(); + CInstanceBase * pkInstFind = rkChrMgr.GetInstancePtr(rkNetActorData.m_dwVID); + if (!pkInstFind) + { + if (__IsVisibleActor(rkNetActorData)) + return __AppendCharacterManagerActor(rkNetActorData); + + return NULL; + } + + return pkInstFind; +} + +void CNetworkActorManager::__RemoveAllGroundItems() +{ + CPythonItem& rkItemMgr=CPythonItem::Instance(); + rkItemMgr.DeleteAllItems(); +} + +void CNetworkActorManager::__RemoveAllActors() +{ + m_kNetActorDict.clear(); + + CPythonCharacterManager & rkChrMgr = CPythonCharacterManager::Instance(); + rkChrMgr.DeleteAllInstances(); +} + +void CNetworkActorManager::__RemoveDynamicActors() +{ + //copy it + std::vector dwCharacterVIDList; + + CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance(); + for(CPythonCharacterManager::CharacterIterator i = rkChrMgr.CharacterInstanceBegin(); i!=rkChrMgr.CharacterInstanceEnd(); ++i) + { + dwCharacterVIDList.push_back( (*i)->GetVirtualID() ); + } + + for( int i = 0; i < dwCharacterVIDList.size(); ++i ) + { + CInstanceBase* pkInstEach = rkChrMgr.GetInstancePtr( dwCharacterVIDList[i] ); + if( !pkInstEach ) + continue; + + CActorInstance* rkActorEach=pkInstEach->GetGraphicThingInstancePtr(); + if( rkActorEach->IsPC() || rkActorEach->IsNPC() || rkActorEach->IsEnemy() ) + { + rkChrMgr.DeleteInstance(dwCharacterVIDList[i]); + std::map::iterator it =m_kNetActorDict.find(dwCharacterVIDList[i]); + if (it != m_kNetActorDict.end()) + { + m_kNetActorDict.erase(it); + } + } + } + + rkChrMgr.DestroyDeadInstanceList(); +} + +void CNetworkActorManager::__UpdateMainActor() +{ + CPythonCharacterManager & rkChrMgr = CPythonCharacterManager::Instance(); + CInstanceBase* pkInstMain=rkChrMgr.GetMainInstancePtr(); + if (!pkInstMain) + return; + + TPixelPosition kPPosMain; + pkInstMain->NEW_GetPixelPosition(&kPPosMain); + + m_lMainPosX=LONG(kPPosMain.x); + m_lMainPosY=LONG(kPPosMain.y); +} + +extern bool IsWall(unsigned race); + +bool CNetworkActorManager::__IsVisibleActor(const SNetworkActorData& c_rkNetActorData) +{ + if (__IsMainActorVID(c_rkNetActorData.m_dwVID)) + return true; + + // 2004.08.02.myevan.׻ ̱ ÷ + if (c_rkNetActorData.m_kAffectFlags.IsSet(CInstanceBase::AFFECT_SHOW_ALWAYS)) + return true; + + if (__IsVisiblePos(c_rkNetActorData.m_lCurX, c_rkNetActorData.m_lCurY)) + return true; + + if (IsWall(c_rkNetActorData.m_dwRace)) + return true; + + return false; +} + +bool CNetworkActorManager::__IsVisiblePos(LONG lPosX, LONG lPosY) +{ + LONG dx = lPosX-m_lMainPosX; + LONG dy = lPosY-m_lMainPosY; + LONG len = (LONG)sqrt(double(dx * dx + dy * dy)); + + extern int CHAR_STAGE_VIEW_BOUND; + if (len < CHAR_STAGE_VIEW_BOUND) // Ÿ cm + return true; + + return false; +} + +bool CNetworkActorManager::__IsMainActorVID(DWORD dwVID) +{ + if (dwVID == m_dwMainVID) + return true; + + return false; +} + +CPythonCharacterManager& CNetworkActorManager::__GetCharacterManager() +{ + return CPythonCharacterManager::Instance(); +} + +void CNetworkActorManager::__RemoveCharacterManagerActor(SNetworkActorData& rkNetActorData) +{ + CPythonCharacterManager & rkChrMgr = CPythonCharacterManager::Instance(); + + if (__IsMainActorVID(rkNetActorData.m_dwVID)) + { + rkChrMgr.DeleteInstance(rkNetActorData.m_dwVID); + } + else + { + rkChrMgr.DeleteInstanceByFade(rkNetActorData.m_dwVID); + } +} + +CInstanceBase* CNetworkActorManager::__AppendCharacterManagerActor(SNetworkActorData& rkNetActorData) +{ + Lognf(0, "CNetworkActorManager::__AppendCharacterManagerActor(%d, %s)", rkNetActorData.m_dwVID, rkNetActorData.m_stName.c_str()); + + DWORD dwVID=rkNetActorData.m_dwVID; + + CPythonCharacterManager & rkChrMgr = CPythonCharacterManager::Instance(); + + + CInstanceBase::SCreateData kCreateData; + kCreateData.m_bType=rkNetActorData.m_bType; + kCreateData.m_dwLevel=rkNetActorData.m_dwLevel; + kCreateData.m_dwGuildID=rkNetActorData.m_dwGuildID; + kCreateData.m_dwEmpireID=rkNetActorData.m_dwEmpireID; + kCreateData.m_dwVID=rkNetActorData.m_dwVID; + kCreateData.m_dwMountVnum=rkNetActorData.m_dwMountVnum; + kCreateData.m_dwRace=rkNetActorData.m_dwRace; + kCreateData.m_fRot=rkNetActorData.m_fRot; + kCreateData.m_lPosX=rkNetActorData.m_lCurX; + kCreateData.m_lPosY=rkNetActorData.m_lCurY; + kCreateData.m_stName=rkNetActorData.m_stName; + kCreateData.m_dwStateFlags=rkNetActorData.m_dwStateFlags; + kCreateData.m_dwMovSpd=rkNetActorData.m_dwMovSpd; + kCreateData.m_dwAtkSpd=rkNetActorData.m_dwAtkSpd; + kCreateData.m_sAlignment=rkNetActorData.m_sAlignment; + kCreateData.m_byPKMode=rkNetActorData.m_byPKMode; + kCreateData.m_kAffectFlags=rkNetActorData.m_kAffectFlags; + kCreateData.m_dwArmor=rkNetActorData.m_dwArmor; + kCreateData.m_dwWeapon=rkNetActorData.m_dwWeapon; + kCreateData.m_dwHair=rkNetActorData.m_dwHair; + kCreateData.m_isMain=__IsMainActorVID(dwVID); + + CInstanceBase* pOldInstance = rkChrMgr.GetInstancePtr(dwVID); + if (pOldInstance) + { + TPixelPosition oldPos; + pOldInstance->GetGraphicThingInstancePtr()->GetPixelPosition( &oldPos ); + + bool bIsMountingHorse = pOldInstance->IsMountingHorse(); + if( (bIsMountingHorse && kCreateData.m_dwMountVnum == 0) || + (!bIsMountingHorse && kCreateData.m_dwMountVnum != 0) ) + { + //Override Pos + kCreateData.m_lPosX = oldPos.x; + kCreateData.m_lPosY = -oldPos.y; + } + + rkChrMgr.DeleteInstance(dwVID); + } + + + CInstanceBase* pNewInstance = rkChrMgr.CreateInstance(kCreateData); + if (!pNewInstance) + return NULL; + + if (kCreateData.m_isMain) + { + IAbstractPlayer & rkPlayer = IAbstractPlayer::GetSingleton(); + rkPlayer.SetMainCharacterIndex(dwVID); + + + m_lMainPosX=rkNetActorData.m_lCurX; + m_lMainPosY=rkNetActorData.m_lCurY; + } + + DWORD dwClientCurTime=ELTimer_GetMSec(); + DWORD dwElapsedTime=dwClientCurTime-rkNetActorData.m_dwClientSrcTime; + + if (dwElapsedTimePushTCPState(rkNetActorData.m_dwServerSrcTime+dwElapsedTime, kPPosDst, rkNetActorData.m_fRot, CInstanceBase::FUNC_MOVE, 0); + } + return pNewInstance; +} + +void CNetworkActorManager::AppendActor(const SNetworkActorData& c_rkNetActorData) +{ + if (__IsMainActorVID(c_rkNetActorData.m_dwVID)) + { + bool bChangeMountStatus = false; + + CInstanceBase* pMainInstance = CPythonCharacterManager::Instance().GetInstancePtr(c_rkNetActorData.m_dwVID); + if( pMainInstance ) + { + bool bIsMountingHorse = pMainInstance->IsMountingHorse(); + bChangeMountStatus = (bIsMountingHorse && c_rkNetActorData.m_dwMountVnum == 0) || (!bIsMountingHorse && c_rkNetActorData.m_dwMountVnum != 0); + } + + if( !bChangeMountStatus ) + { + //__RemoveAllActors(); + __RemoveDynamicActors(); + __RemoveAllGroundItems(); + } + + } + + SNetworkActorData& rkNetActorData=m_kNetActorDict[c_rkNetActorData.m_dwVID]; + rkNetActorData=c_rkNetActorData; + + if (__IsVisibleActor(rkNetActorData)) + { + if (!__AppendCharacterManagerActor(rkNetActorData)) + m_kNetActorDict.erase(c_rkNetActorData.m_dwVID); + } +} + +void CNetworkActorManager::RemoveActor(DWORD dwVID) +{ + std::map::iterator f=m_kNetActorDict.find(dwVID); + if (m_kNetActorDict.end()==f) + { +#ifdef _DEBUG + TraceError("CNetworkActorManager::RemoveActor(dwVID=%d) - NOT EXIST VID", dwVID); +#endif + return; + } + + SNetworkActorData& rkNetActorData=f->second; + __RemoveCharacterManagerActor(rkNetActorData); + + m_kNetActorDict.erase(f); +} + +void CNetworkActorManager::UpdateActor(const SNetworkUpdateActorData& c_rkNetUpdateActorData) +{ + std::map::iterator f=m_kNetActorDict.find(c_rkNetUpdateActorData.m_dwVID); + if (m_kNetActorDict.end()==f) + { +#ifdef _DEBUG + TraceError("CNetworkActorManager::UpdateActor(dwVID=%d) - NOT EXIST VID", c_rkNetUpdateActorData.m_dwVID); +#endif + return; + } + + SNetworkActorData& rkNetActorData=f->second; + + CInstanceBase* pkInstFind=__FindActor(rkNetActorData); + if (pkInstFind) + { + pkInstFind->ChangeArmor(c_rkNetUpdateActorData.m_dwArmor); + pkInstFind->ChangeWeapon(c_rkNetUpdateActorData.m_dwWeapon); + pkInstFind->ChangeHair(c_rkNetUpdateActorData.m_dwHair); + pkInstFind->ChangeGuild(c_rkNetUpdateActorData.m_dwGuildID); + pkInstFind->SetAffectFlagContainer(c_rkNetUpdateActorData.m_kAffectFlags); + pkInstFind->SetMoveSpeed(c_rkNetUpdateActorData.m_dwMovSpd); + pkInstFind->SetAttackSpeed(c_rkNetUpdateActorData.m_dwAtkSpd); + pkInstFind->SetAlignment(c_rkNetUpdateActorData.m_sAlignment); + pkInstFind->SetPKMode(c_rkNetUpdateActorData.m_byPKMode); + pkInstFind->SetStateFlags(c_rkNetUpdateActorData.m_dwStateFlags); + + //if( c_rkNetUpdateActorData.m_dwMountVnum != 0 ) + //{ + // pkInstFind->MountHorse(c_rkNetUpdateActorData.m_dwMountVnum); + //} + //else + //{ + // if( pkInstFind->IsMountingHorse() ) + // { + // pkInstFind->DismountHorse(); + // } + //} + } + + rkNetActorData.m_kAffectFlags=c_rkNetUpdateActorData.m_kAffectFlags; + rkNetActorData.m_dwGuildID=c_rkNetUpdateActorData.m_dwGuildID; + //rkNetActorData.m_dwLevel=c_rkNetUpdateActorData.m_dwLevel; + rkNetActorData.m_dwMovSpd=c_rkNetUpdateActorData.m_dwMovSpd; + rkNetActorData.m_dwAtkSpd=c_rkNetUpdateActorData.m_dwAtkSpd; + rkNetActorData.m_dwArmor=c_rkNetUpdateActorData.m_dwArmor; + rkNetActorData.m_dwWeapon=c_rkNetUpdateActorData.m_dwWeapon; + rkNetActorData.m_dwHair=c_rkNetUpdateActorData.m_dwHair; + rkNetActorData.m_sAlignment=c_rkNetUpdateActorData.m_sAlignment; + rkNetActorData.m_byPKMode=c_rkNetUpdateActorData.m_byPKMode; +} + +void CNetworkActorManager::MoveActor(const SNetworkMoveActorData& c_rkNetMoveActorData) +{ + std::map::iterator f=m_kNetActorDict.find(c_rkNetMoveActorData.m_dwVID); + if (m_kNetActorDict.end()==f) + { +#ifdef _DEBUG + TraceError("CNetworkActorManager::MoveActor(dwVID=%d) - NOT EXIST VID", c_rkNetMoveActorData.m_dwVID); +#endif + return; + } + + SNetworkActorData& rkNetActorData=f->second; + + CInstanceBase* pkInstFind=__FindActor(rkNetActorData, c_rkNetMoveActorData.m_lPosX, c_rkNetMoveActorData.m_lPosY); + if (pkInstFind) + { + TPixelPosition kPPosDst; + kPPosDst.x=float(c_rkNetMoveActorData.m_lPosX); + kPPosDst.y=float(c_rkNetMoveActorData.m_lPosY); + kPPosDst.z=0.0f; + + pkInstFind->PushTCPState(c_rkNetMoveActorData.m_dwTime, kPPosDst, + c_rkNetMoveActorData.m_fRot, c_rkNetMoveActorData.m_dwFunc, c_rkNetMoveActorData.m_dwArg); + } + + rkNetActorData.SetDstPosition(c_rkNetMoveActorData.m_dwTime, + c_rkNetMoveActorData.m_lPosX, c_rkNetMoveActorData.m_lPosY, c_rkNetMoveActorData.m_dwDuration); + rkNetActorData.m_fRot=c_rkNetMoveActorData.m_fRot; +} + +void CNetworkActorManager::SyncActor(DWORD dwVID, LONG lPosX, LONG lPosY) +{ + std::map::iterator f=m_kNetActorDict.find(dwVID); + if (m_kNetActorDict.end()==f) + { +#ifdef _DEBUG + TraceError("CNetworkActorManager::SyncActor(dwVID=%d) - NOT EXIST VID", dwVID); +#endif + return; + } + + SNetworkActorData& rkNetActorData=f->second; + + CInstanceBase* pkInstFind=__FindActor(rkNetActorData); + if (pkInstFind) + { + pkInstFind->NEW_SyncPixelPosition(lPosX, lPosY); + } + + rkNetActorData.SetPosition(lPosX, lPosY); +} + +void CNetworkActorManager::SetActorOwner(DWORD dwOwnerVID, DWORD dwVictimVID) +{ + std::map::iterator f=m_kNetActorDict.find(dwVictimVID); + if (m_kNetActorDict.end()==f) + { +#ifdef _DEBUG + TraceError("CNetworkActorManager::SetActorOwner(dwOwnerVID=%d, dwVictimVID=%d) - NOT EXIST VID", dwOwnerVID, dwVictimVID); +#endif + return; + } + + SNetworkActorData& rkNetActorData=f->second; + rkNetActorData.m_dwOwnerVID=dwOwnerVID; + + CInstanceBase* pkInstFind=__FindActor(rkNetActorData); + if (pkInstFind) + { + pkInstFind->NEW_SetOwner(rkNetActorData.m_dwOwnerVID); + } + + +} diff --git a/source/UserInterface/NetworkActorManager.h b/source/UserInterface/NetworkActorManager.h new file mode 100644 index 0000000..629b967 --- /dev/null +++ b/source/UserInterface/NetworkActorManager.h @@ -0,0 +1,164 @@ +#pragma once + +#include "InstanceBase.h" + +struct SNetworkActorData +{ + std::string m_stName; + + CAffectFlagContainer m_kAffectFlags; + + BYTE m_bType; + DWORD m_dwVID; + DWORD m_dwStateFlags; + DWORD m_dwEmpireID; + DWORD m_dwRace; + DWORD m_dwMovSpd; + DWORD m_dwAtkSpd; + FLOAT m_fRot; + LONG m_lCurX; + LONG m_lCurY; + LONG m_lSrcX; + LONG m_lSrcY; + LONG m_lDstX; + LONG m_lDstY; + + + DWORD m_dwServerSrcTime; + DWORD m_dwClientSrcTime; + DWORD m_dwDuration; + + DWORD m_dwArmor; + DWORD m_dwWeapon; + DWORD m_dwHair; + + DWORD m_dwOwnerVID; + + short m_sAlignment; + BYTE m_byPKMode; + DWORD m_dwMountVnum; + + DWORD m_dwGuildID; + DWORD m_dwLevel; + + SNetworkActorData(); + + void SetDstPosition(DWORD dwServerTime, LONG lDstX, LONG lDstY, DWORD dwDuration); + void SetPosition(LONG lPosX, LONG lPosY); + void UpdatePosition(); + + // NETWORK_ACTOR_DATA_COPY + SNetworkActorData(const SNetworkActorData& src); + void operator=(const SNetworkActorData& src); + void __copy__(const SNetworkActorData& src); + // END_OF_NETWORK_ACTOR_DATA_COPY +}; + +struct SNetworkMoveActorData +{ + DWORD m_dwVID; + DWORD m_dwTime; + LONG m_lPosX; + LONG m_lPosY; + float m_fRot; + DWORD m_dwFunc; + DWORD m_dwArg; + DWORD m_dwDuration; + + SNetworkMoveActorData() + { + m_dwVID=0; + m_dwTime=0; + m_fRot=0.0f; + m_lPosX=0; + m_lPosY=0; + m_dwFunc=0; + m_dwArg=0; + m_dwDuration=0; + } +}; + +struct SNetworkUpdateActorData +{ + DWORD m_dwVID; + DWORD m_dwGuildID; + DWORD m_dwArmor; + DWORD m_dwWeapon; + DWORD m_dwHair; + DWORD m_dwMovSpd; + DWORD m_dwAtkSpd; + short m_sAlignment; + BYTE m_byPKMode; + DWORD m_dwMountVnum; + DWORD m_dwStateFlags; // Create ̴ + CAffectFlagContainer m_kAffectFlags; + + SNetworkUpdateActorData() + { + m_dwGuildID=0; + m_dwVID=0; + m_dwArmor=0; + m_dwWeapon=0; + m_dwHair=0; + m_dwMovSpd=0; + m_dwAtkSpd=0; + m_sAlignment=0; + m_byPKMode=0; + m_dwMountVnum=0; + m_dwStateFlags=0; + m_kAffectFlags.Clear(); + } +}; + +class CPythonCharacterManager; + +class CNetworkActorManager : public CReferenceObject +{ + public: + CNetworkActorManager(); + virtual ~CNetworkActorManager(); + + void Destroy(); + + void SetMainActorVID(DWORD dwVID); + + void RemoveActor(DWORD dwVID); + void AppendActor(const SNetworkActorData& c_rkNetActorData); + void UpdateActor(const SNetworkUpdateActorData& c_rkNetUpdateActorData); + void MoveActor(const SNetworkMoveActorData& c_rkNetMoveActorData); + + void SyncActor(DWORD dwVID, LONG lPosX, LONG lPosY); + void SetActorOwner(DWORD dwOwnerVID, DWORD dwVictimVID); + + void Update(); + + protected: + void __OLD_Update(); + + void __UpdateMainActor(); + + bool __IsVisiblePos(LONG lPosX, LONG lPosY); + bool __IsVisibleActor(const SNetworkActorData& c_rkNetActorData); + bool __IsMainActorVID(DWORD dwVID); + + void __RemoveAllGroundItems(); + void __RemoveAllActors(); + void __RemoveDynamicActors(); + void __RemoveCharacterManagerActor(SNetworkActorData& rkNetActorData); + + SNetworkActorData* __FindActorData(DWORD dwVID); + + CInstanceBase* __AppendCharacterManagerActor(SNetworkActorData& rkNetActorData); + CInstanceBase* __FindActor(SNetworkActorData& rkNetActorData); + CInstanceBase* __FindActor(SNetworkActorData& rkNetActorData, LONG lDstX, LONG lDstY); + + CPythonCharacterManager& __GetCharacterManager(); + + protected: + DWORD m_dwMainVID; + + LONG m_lMainPosX; + LONG m_lMainPosY; + + std::map m_kNetActorDict; +}; diff --git a/source/UserInterface/Packet.h b/source/UserInterface/Packet.h new file mode 100644 index 0000000..d498dd3 --- /dev/null +++ b/source/UserInterface/Packet.h @@ -0,0 +1,2813 @@ +#pragma once + +#ifdef USE_AHNLAB_HACKSHIELD +#include "Hackshield.h" +#include METIN2HS_INCLUDE_ANTICPXSVR +#else +#pragma pack(push) // alignment +#pragma pack(8) + +#define ANTICPX_TRANS_BUFFER_MAX 400 + +typedef struct _AHNHS_TRANS_BUFFER +{ + unsigned char byBuffer[ANTICPX_TRANS_BUFFER_MAX/* ۼ Ŷ ִ ũ */]; + unsigned short nLength; +} AHNHS_TRANS_BUFFER, *PAHNHS_TRANS_BUFFER; + +#pragma pack(pop) // alignment . +#endif /* !USE_AHNLAB_HACKSHIELD */ + +#include "../gamelib/RaceData.h" + +typedef BYTE TPacketHeader; + +enum +{ + ///////////////////////////////////////////////// + // To Server + // HEADER_BLANK is the not use(for future use) + HEADER_CG_LOGIN = 1, + HEADER_CG_ATTACK = 2, + HEADER_CG_CHAT = 3, + HEADER_CG_PLAYER_CREATE = 4, // ο ÷̾ + HEADER_CG_PLAYER_DESTROY = 5, // ÷̾ . + HEADER_CG_PLAYER_SELECT = 6, + HEADER_CG_CHARACTER_MOVE = 7, + HEADER_CG_SYNC_POSITION = 8, + HEADER_CG_DIRECT_ENTER = 9, + HEADER_CG_ENTERGAME = 10, + HEADER_CG_ITEM_USE = 11, + HEADER_CG_ITEM_DROP = 12, + HEADER_CG_ITEM_MOVE = 13, + HEADER_CG_ITEM_PICKUP = 15, + HEADER_CG_QUICKSLOT_ADD = 16, + HEADER_CG_QUICKSLOT_DEL = 17, + HEADER_CG_QUICKSLOT_SWAP = 18, + HEADER_CG_WHISPER = 19, + HEADER_CG_ITEM_DROP2 = 20, + //HEADER_BLANK21 = 21, + //HEADER_BLANK22 = 22, + //HEADER_BLANK22 = 23, + //HEADER_BLANK24 = 24, + //HEADER_BLANK25 = 25, + HEADER_CG_ON_CLICK = 26, + HEADER_CG_EXCHANGE = 27, + HEADER_CG_CHARACTER_POSITION = 28, + HEADER_CG_SCRIPT_ANSWER = 29, + HEADER_CG_QUEST_INPUT_STRING = 30, + HEADER_CG_QUEST_CONFIRM = 31, + //HEADER_BLANK32 = 32, + //HEADER_BLANK33 = 33, + //HEADER_BLANK34 = 34, + //HEADER_BLANK35 = 35, + //HEADER_BLANK36 = 36, + //HEADER_BLANK37 = 37, + //HEADER_BLANK38 = 38, + //HEADER_BLANK39 = 39, + //HEADER_BLANK40 = 40, + HEADER_CG_PVP = 41, + //HEADER_BLANK42 = 42, + //HEADER_BLANK43 = 43, + //HEADER_BLANK44 = 44, + //HEADER_BLANK45 = 45, + //HEADER_BLANK46 = 46, + //HEADER_BLANK47 = 47, + //HEADER_BLANK48 = 48, + //HEADER_BLANK49 = 49, + HEADER_CG_SHOP = 50, + HEADER_CG_FLY_TARGETING = 51, + HEADER_CG_USE_SKILL = 52, + HEADER_CG_ADD_FLY_TARGETING = 53, + HEADER_CG_SHOOT = 54, + HEADER_CG_MYSHOP = 55, + //HEADER_BLANK56 = 56, + //HEADER_BLANK57 = 57, + //HEADER_BLANK58 = 58, + //HEADER_BLANK59 = 59, + HEADER_CG_ITEM_USE_TO_ITEM = 60, + HEADER_CG_TARGET = 61, + //HEADER_BLANK62 = 62, + //HEADER_BLANK63 = 63, + //HEADER_BLANK64 = 64, + HEADER_CG_WARP = 65, + HEADER_CG_SCRIPT_BUTTON = 66, + HEADER_CG_MESSENGER = 67, + //HEADER_BLANK68 = 68, + HEADER_CG_MALL_CHECKOUT = 69, + HEADER_CG_SAFEBOX_CHECKIN = 70, // â ִ´. + HEADER_CG_SAFEBOX_CHECKOUT = 71, // â ´. + HEADER_CG_PARTY_INVITE = 72, + HEADER_CG_PARTY_INVITE_ANSWER = 73, + HEADER_CG_PARTY_REMOVE = 74, + HEADER_CG_PARTY_SET_STATE = 75, + HEADER_CG_PARTY_USE_SKILL = 76, + HEADER_CG_SAFEBOX_ITEM_MOVE = 77, + HEADER_CG_PARTY_PARAMETER = 78, + //HEADER_BLANK68 = 79, + HEADER_CG_GUILD = 80, + HEADER_CG_ANSWER_MAKE_GUILD = 81, + HEADER_CG_FISHING = 82, + HEADER_CG_GIVE_ITEM = 83, + //HEADER_BLANK84 = 84, + //HEADER_BLANK85 = 85, + //HEADER_BLANK86 = 86, + //HEADER_BLANK87 = 87, + //HEADER_BLANK88 = 88, + //HEADER_BLANK89 = 89, + HEADER_CG_EMPIRE = 90, + //HEADER_BLANK91 = 91, + //HEADER_BLANK92 = 92, + //HEADER_BLANK93 = 93, + //HEADER_BLANK94 = 94, + //HEADER_BLANK95 = 95, + HEADER_CG_REFINE = 96, + //HEADER_BLANK97 = 97, + //HEADER_BLANK98 = 98, + //HEADER_BLANK99 = 99, + + HEADER_CG_MARK_LOGIN = 100, + HEADER_CG_MARK_CRCLIST = 101, + HEADER_CG_MARK_UPLOAD = 102, + HEADER_CG_MARK_IDXLIST = 104, + + HEADER_CG_CRC_REPORT = 103, + + HEADER_CG_HACK = 105, + HEADER_CG_CHANGE_NAME = 106, + HEADER_CG_SMS = 107, + HEADER_CG_CHINA_MATRIX_CARD = 108, + HEADER_CG_LOGIN2 = 109, + HEADER_CG_DUNGEON = 110, + HEADER_CG_LOGIN3 = 111, + HEADER_CG_GUILD_SYMBOL_UPLOAD = 112, + HEADER_CG_GUILD_SYMBOL_CRC = 113, + HEADER_CG_SCRIPT_SELECT_ITEM = 114, + HEADER_CG_LOGIN4 = 115, + HEADER_CG_LOGIN5_OPENID = 116, //OpenID : Ű . + + HEADER_CG_RUNUP_MATRIX_ANSWER = 201, + HEADER_CG_NEWCIBN_PASSPOD_ANSWER = 202, + + HEADER_CG_HS_ACK = 203, + HEADER_CG_XTRAP_ACK = 204, + + HEADER_CG_DRAGON_SOUL_REFINE = 205, + HEADER_CG_STATE_CHECKER = 206, + +#ifdef __AUCTION__ + HEADER_CG_AUCTION_CMD = 205, +#endif + + HEADER_CG_KEY_AGREEMENT = 0xfb, // _IMPROVED_PACKET_ENCRYPTION_ + HEADER_CG_TIME_SYNC = 0xfc, + HEADER_CG_CLIENT_VERSION = 0xfd, + HEADER_CG_CLIENT_VERSION2 = 0xf1, + HEADER_CG_PONG = 0xfe, + HEADER_CG_HANDSHAKE = 0xff, + ///////////////////////////////////////////////// + // From Server + + HEADER_GC_CHARACTER_ADD = 1, + HEADER_GC_CHARACTER_DEL = 2, + HEADER_GC_CHARACTER_MOVE = 3, + HEADER_GC_CHAT = 4, + HEADER_GC_SYNC_POSITION = 5, + HEADER_GC_LOGIN_SUCCESS3 = 6, + HEADER_GC_LOGIN_FAILURE = 7, + HEADER_GC_PLAYER_CREATE_SUCCESS = 8, + HEADER_GC_PLAYER_CREATE_FAILURE = 9, + HEADER_GC_PLAYER_DELETE_SUCCESS = 10, + HEADER_GC_PLAYER_DELETE_WRONG_SOCIAL_ID = 11, + // 12 + HEADER_GC_STUN = 13, + HEADER_GC_DEAD = 14, + + HEADER_GC_MAIN_CHARACTER = 15, + HEADER_GC_PLAYER_POINTS = 16, + HEADER_GC_PLAYER_POINT_CHANGE = 17, + HEADER_GC_CHANGE_SPEED = 18, + HEADER_GC_CHARACTER_UPDATE = 19, +#if defined(GAIDEN) + HEADER_GC_ITEM_DEL = 20, // â ߰ + HEADER_GC_ITEM_SET = 21, // â ߰ +#else + HEADER_GC_ITEM_SET = 20, // â ߰ + HEADER_GC_ITEM_SET2 = 21, // â ߰ +#endif + HEADER_GC_ITEM_USE = 22, // ( 鿡 ֱ ) + HEADER_GC_ITEM_DROP = 23, // + HEADER_GC_ITEM_UPDATE = 25, // ġ Ʈ + HEADER_GC_ITEM_GROUND_ADD = 26, // ٴڿ ߰ + HEADER_GC_ITEM_GROUND_DEL = 27, // ٴڿ + HEADER_GC_QUICKSLOT_ADD = 28, + HEADER_GC_QUICKSLOT_DEL = 29, + HEADER_GC_QUICKSLOT_SWAP = 30, + HEADER_GC_ITEM_OWNERSHIP = 31, + HEADER_GC_LOGIN_SUCCESS4 = 32, + HEADER_GC_ITEM_UNBIND_TIME = 33, + HEADER_GC_WHISPER = 34, + HEADER_GC_ALERT = 35, + + HEADER_GC_MOTION = 36, + + HEADER_GC_SHOP = 38, + HEADER_GC_SHOP_SIGN = 39, + + // 39 ~ 41 Balnk + HEADER_GC_DUEL_START = 40, + HEADER_GC_PVP = 41, + HEADER_GC_EXCHANGE = 42, + HEADER_GC_CHARACTER_POSITION = 43, + + HEADER_GC_PING = 44, + + HEADER_GC_SCRIPT = 45, + HEADER_GC_QUEST_CONFIRM = 46, + + HEADER_GC_MOUNT = 61, + HEADER_GC_OWNERSHIP = 62, + HEADER_GC_TARGET = 63, + HEADER_GC_WARP = 65, + HEADER_GC_ADD_FLY_TARGETING = 69, + + HEADER_GC_CREATE_FLY = 70, + HEADER_GC_FLY_TARGETING = 71, + HEADER_GC_SKILL_LEVEL = 72, + HEADER_GC_SKILL_COOLTIME_END = 73, + HEADER_GC_MESSENGER = 74, + HEADER_GC_GUILD = 75, + HEADER_GC_SKILL_LEVEL_NEW = 76, + + HEADER_GC_PARTY_INVITE = 77, + HEADER_GC_PARTY_ADD = 78, + HEADER_GC_PARTY_UPDATE = 79, + HEADER_GC_PARTY_REMOVE = 80, + + HEADER_GC_QUEST_INFO = 81, + HEADER_GC_REQUEST_MAKE_GUILD = 82, + HEADER_GC_PARTY_PARAMETER = 83, + + HEADER_GC_SAFEBOX_MONEY_CHANGE = 84, + HEADER_GC_SAFEBOX_SET = 85, + HEADER_GC_SAFEBOX_DEL = 86, + HEADER_GC_SAFEBOX_WRONG_PASSWORD = 87, + HEADER_GC_SAFEBOX_SIZE = 88, + + HEADER_GC_FISHING = 89, + + HEADER_GC_EMPIRE = 90, + + HEADER_GC_PARTY_LINK = 91, + HEADER_GC_PARTY_UNLINK = 92, + + HEADER_GC_REFINE_INFORMATION = 95, + + HEADER_GC_OBSERVER_ADD = 96, + HEADER_GC_OBSERVER_REMOVE = 97, + HEADER_GC_OBSERVER_MOVE = 98, + HEADER_GC_VIEW_EQUIP = 99, + + HEADER_GC_MARK_BLOCK = 100, + HEADER_GC_MARK_DIFF_DATA = 101, + HEADER_GC_MARK_IDXLIST = 102, + + //HEADER_GC_SLOW_TIMER = 105, + HEADER_GC_TIME = 106, + HEADER_GC_CHANGE_NAME = 107, + + HEADER_GC_DUNGEON = 110, + HEADER_GC_WALK_MODE = 111, + HEADER_GC_CHANGE_SKILL_GROUP = 112, + +#if defined(GAIDEN) + HEADER_GC_MAIN_CHARACTER = 113, + HEADER_GC_MAIN_CHARACTER3_BGM = 137, + HEADER_GC_MAIN_CHARACTER4_BGM_VOL = 138, +#else + // SUPPORT_BGM + HEADER_GC_MAIN_CHARACTER2_EMPIRE = 113, + // END_OF_SUPPORT_BGM +#endif + + HEADER_GC_SEPCIAL_EFFECT = 114, + HEADER_GC_NPC_POSITION = 115, + + HEADER_GC_CHINA_MATRIX_CARD = 116, + HEADER_GC_CHARACTER_UPDATE2 = 117, + HEADER_GC_LOGIN_KEY = 118, + HEADER_GC_REFINE_INFORMATION_NEW = 119, + HEADER_GC_CHARACTER_ADD2 = 120, + HEADER_GC_CHANNEL = 121, + + HEADER_GC_MALL_OPEN = 122, + HEADER_GC_TARGET_UPDATE = 123, + HEADER_GC_TARGET_DELETE = 124, + HEADER_GC_TARGET_CREATE_NEW = 125, + + HEADER_GC_AFFECT_ADD = 126, + HEADER_GC_AFFECT_REMOVE = 127, + + HEADER_GC_MALL_SET = 128, + HEADER_GC_MALL_DEL = 129, + HEADER_GC_LAND_LIST = 130, + HEADER_GC_LOVER_INFO = 131, + HEADER_GC_LOVE_POINT_UPDATE = 132, + HEADER_GC_GUILD_SYMBOL_DATA = 133, + HEADER_GC_DIG_MOTION = 134, + + HEADER_GC_DAMAGE_INFO = 135, + HEADER_GC_CHAR_ADDITIONAL_INFO = 136, + + // SUPPORT_BGM + HEADER_GC_MAIN_CHARACTER3_BGM = 137, + HEADER_GC_MAIN_CHARACTER4_BGM_VOL = 138, + // END_OF_SUPPORT_BGM + + HEADER_GC_AUTH_SUCCESS = 150, + HEADER_GC_PANAMA_PACK = 151, + + //HYBRID CRYPT + HEADER_GC_HYBRIDCRYPT_KEYS = 152, + HEADER_GC_HYBRIDCRYPT_SDB = 153, // SDB means Supplmentary Data Blocks + //HYBRID CRYPT + + HEADER_GC_AUTH_SUCCESS_OPENID = 154, + + HEADER_GC_RUNUP_MATRIX_QUIZ = 201, + HEADER_GC_NEWCIBN_PASSPOD_REQUEST = 202, + HEADER_GC_NEWCIBN_PASSPOD_FAILURE = 203, +#if defined(GAIDEN) + HEADER_GC_ONTIME = 204, + HEADER_GC_RESET_ONTIME = 205, + + // AUTOBAN + HEADER_GC_AUTOBAN_QUIZ = 206, + // END_OF_AUTOBAN + + HEADER_GC_HS_REQUEST = 207, // Origially it's 204 on devel branch +#else + HEADER_GC_HS_REQUEST = 204, + HEADER_GC_XTRAP_CS1_REQUEST = 205, +#endif + +#ifdef __AUCTION__ + HEADER_GC_AUCTOIN_ITEM_LIST = 206, +#endif + + HEADER_GC_SPECIFIC_EFFECT = 208, + HEADER_GC_DRAGON_SOUL_REFINE = 209, + HEADER_GC_RESPOND_CHANNELSTATUS = 210, + + HEADER_GC_KEY_AGREEMENT_COMPLETED = 0xfa, // _IMPROVED_PACKET_ENCRYPTION_ + HEADER_GC_KEY_AGREEMENT = 0xfb, // _IMPROVED_PACKET_ENCRYPTION_ + HEADER_GC_HANDSHAKE_OK = 0xfc, // 252 + HEADER_GC_PHASE = 0xfd, // 253 + HEADER_GC_BINDUDP = 0xfe, // 254 + HEADER_GC_HANDSHAKE = 0xff, // 255 + + ///////////////////////////////////////////////// + // Client To Client for UDP + /* + HEADER_CC_STATE_WAITING = 1, + HEADER_CC_STATE_WALKING = 2, + HEADER_CC_STATE_GOING = 3, + HEADER_CC_EVENT_NORMAL_ATTACKING = 4, + HEADER_CC_EVENT_COMBO_ATTACKING = 5, + HEADER_CC_EVENT_HIT = 6, + */ +}; + +enum +{ + ID_MAX_NUM = 30, + PASS_MAX_NUM = 16, + CHAT_MAX_NUM = 128, + PATH_NODE_MAX_NUM = 64, + SHOP_SIGN_MAX_LEN = 32, + + PLAYER_PER_ACCOUNT3 = 3, + PLAYER_PER_ACCOUNT4 = 4, + + PLAYER_ITEM_SLOT_MAX_NUM = 20, // ÷̾ Դ  . + + QUICKSLOT_MAX_LINE = 4, + QUICKSLOT_MAX_COUNT_PER_LINE = 8, // Ŭ̾Ʈ + QUICKSLOT_MAX_COUNT = QUICKSLOT_MAX_LINE * QUICKSLOT_MAX_COUNT_PER_LINE, + + QUICKSLOT_MAX_NUM = 36, // ִ + + SHOP_HOST_ITEM_MAX_NUM = 40, + + METIN_SOCKET_COUNT = 6, + + PARTY_AFFECT_SLOT_MAX_NUM = 7, + + GUILD_GRADE_NAME_MAX_LEN = 8, + GUILD_NAME_MAX_LEN = 12, + GUILD_GRADE_COUNT = 15, + GULID_COMMENT_MAX_LEN = 50, + + MARK_CRC_NUM = 8*8, + MARK_DATA_SIZE = 16*12, + SYMBOL_DATA_SIZE = 128*256, + QUEST_INPUT_STRING_MAX_NUM = 64, + + PRIVATE_CODE_LENGTH = 8, + + REFINE_MATERIAL_MAX_NUM = 5, + + CHINA_MATRIX_ANSWER_MAX_LEN = 8, + + RUNUP_MATRIX_QUIZ_MAX_LEN = 8, + RUNUP_MATRIX_ANSWER_MAX_LEN = 4, + NEWCIBN_PASSPOD_ANSWER_MAX_LEN = 8, + NEWCIBN_PASSPOD_FAILURE_MAX_LEN = 128, + + WEAR_MAX_NUM = 11, + + OPENID_AUTHKEY_LEN = 32, + + SHOP_TAB_NAME_MAX = 32, + SHOP_TAB_COUNT_MAX = 3, +}; + +#pragma pack(push) +#pragma pack(1) + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Mark +typedef struct command_mark_login +{ + BYTE header; + DWORD handle; + DWORD random_key; +} TPacketCGMarkLogin; + +typedef struct command_mark_upload +{ + BYTE header; + DWORD gid; + BYTE image[16*12*4]; +} TPacketCGMarkUpload; + +typedef struct command_mark_idxlist +{ + BYTE header; +} TPacketCGMarkIDXList; + +typedef struct command_mark_crclist +{ + BYTE header; + BYTE imgIdx; + DWORD crclist[80]; +} TPacketCGMarkCRCList; + +typedef struct packet_mark_idxlist +{ + BYTE header; + DWORD bufSize; + WORD count; + //ڿ size * (WORD + WORD)ŭ +} TPacketGCMarkIDXList; + +typedef struct packet_mark_block +{ + BYTE header; + DWORD bufSize; + BYTE imgIdx; + DWORD count; + // ڿ 64 x 48 x ȼũ(4Ʈ) = 12288ŭ +} TPacketGCMarkBlock; + +typedef struct command_symbol_upload +{ + BYTE header; + WORD size; + DWORD handle; +} TPacketCGSymbolUpload; + +typedef struct command_symbol_crc +{ + BYTE header; + DWORD dwGuildID; + DWORD dwCRC; + DWORD dwSize; +} TPacketCGSymbolCRC; + +typedef struct packet_symbol_data +{ + BYTE header; + WORD size; + DWORD guild_id; +} TPacketGCGuildSymbolData; + +// +// +// +typedef struct packet_observer_add +{ + BYTE header; + DWORD vid; + WORD x; + WORD y; +} TPacketGCObserverAdd; + +typedef struct packet_observer_move +{ + BYTE header; + DWORD vid; + WORD x; + WORD y; +} TPacketGCObserverMove; + + +typedef struct packet_observer_remove +{ + BYTE header; + DWORD vid; +} TPacketGCObserverRemove; + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// To Server + +typedef struct command_checkin +{ + BYTE header; + char name[ID_MAX_NUM+1]; + char pwd[PASS_MAX_NUM+1]; +} TPacketCGCheckin; + +typedef struct command_login +{ + BYTE header; + char name[ID_MAX_NUM + 1]; + char pwd[PASS_MAX_NUM + 1]; +} TPacketCGLogin; + +// start - Ŷ +typedef struct command_login2 +{ + BYTE header; + char name[ID_MAX_NUM + 1]; + DWORD login_key; + DWORD adwClientKey[4]; +} TPacketCGLogin2; + +typedef struct command_login3 +{ + BYTE header; + char name[ID_MAX_NUM + 1]; + char pwd[PASS_MAX_NUM + 1]; + DWORD adwClientKey[4]; +} TPacketCGLogin3; + +typedef struct command_login5 +{ + BYTE header; + char authKey[OPENID_AUTHKEY_LEN + 1]; + DWORD adwClientKey[4]; +} TPacketCGLogin5; +// end - Ŷ + +typedef struct command_direct_enter +{ + BYTE bHeader; + char login[ID_MAX_NUM + 1]; + char passwd[PASS_MAX_NUM + 1]; + BYTE index; +} TPacketCGDirectEnter; + +typedef struct command_player_select +{ + BYTE header; + BYTE player_index; +} TPacketCGSelectCharacter; + +typedef struct command_attack +{ + BYTE header; + BYTE bType; // + DWORD dwVictimVID; // VID + BYTE bCRCMagicCubeProcPiece; + BYTE bCRCMagicCubeFilePiece; +} TPacketCGAttack; + +typedef struct command_chat +{ + BYTE header; + WORD length; + BYTE type; +} TPacketCGChat; + +typedef struct command_whisper +{ + BYTE bHeader; + WORD wSize; + char szNameTo[CHARACTER_NAME_MAX_LEN + 1]; +} TPacketCGWhisper; + +typedef struct command_sms +{ + BYTE bHeader; + WORD wSize; + char szNameTo[CHARACTER_NAME_MAX_LEN + 1]; +} TPacketCGSMS; + +enum EBattleMode +{ + BATTLEMODE_ATTACK = 0, + BATTLEMODE_DEFENSE = 1, +}; + +typedef struct command_EnterFrontGame +{ + BYTE header; +} TPacketCGEnterFrontGame; + +typedef struct command_item_use +{ + BYTE header; + TItemPos pos; +} TPacketCGItemUse; + +typedef struct command_item_use_to_item +{ + BYTE header; + TItemPos source_pos; + TItemPos target_pos; +} TPacketCGItemUseToItem; + +typedef struct command_item_drop +{ + BYTE header; + TItemPos pos; + DWORD elk; +} TPacketCGItemDrop; + +typedef struct command_item_drop2 +{ + BYTE header; + TItemPos pos; + DWORD gold; + BYTE count; +} TPacketCGItemDrop2; + +typedef struct command_item_move +{ + BYTE header; + TItemPos pos; + TItemPos change_pos; + BYTE num; +} TPacketCGItemMove; + +typedef struct command_item_pickup +{ + BYTE header; + DWORD vid; +} TPacketCGItemPickUp; + +typedef struct command_quickslot_add +{ + BYTE header; + BYTE pos; + TQuickSlot slot; +}TPacketCGQuickSlotAdd; + +typedef struct command_quickslot_del +{ + BYTE header; + BYTE pos; +}TPacketCGQuickSlotDel; + +typedef struct command_quickslot_swap +{ + BYTE header; + BYTE pos; + BYTE change_pos; +}TPacketCGQuickSlotSwap; + +typedef struct command_on_click +{ + BYTE header; + DWORD vid; +} TPacketCGOnClick; + + +enum +{ + SHOP_SUBHEADER_CG_END, + SHOP_SUBHEADER_CG_BUY, + SHOP_SUBHEADER_CG_SELL, + SHOP_SUBHEADER_CG_SELL2, +}; + +typedef struct command_shop +{ + BYTE header; + BYTE subheader; +} TPacketCGShop; + +enum +{ + EXCHANGE_SUBHEADER_CG_START, // arg1 == vid of target character + EXCHANGE_SUBHEADER_CG_ITEM_ADD, // arg1 == position of item + EXCHANGE_SUBHEADER_CG_ITEM_DEL, // arg1 == position of item + EXCHANGE_SUBHEADER_CG_ELK_ADD, // arg1 == amount of elk + EXCHANGE_SUBHEADER_CG_ACCEPT, // arg1 == not used + EXCHANGE_SUBHEADER_CG_CANCEL, // arg1 == not used +}; + +typedef struct command_exchange +{ + BYTE header; + BYTE subheader; + DWORD arg1; + BYTE arg2; + TItemPos Pos; +} TPacketCGExchange; + +typedef struct command_position +{ + BYTE header; + BYTE position; +} TPacketCGPosition; + +typedef struct command_script_answer +{ + BYTE header; + BYTE answer; +} TPacketCGScriptAnswer; + +typedef struct command_script_button +{ + BYTE header; + unsigned int idx; +} TPacketCGScriptButton; + +typedef struct command_target +{ + BYTE header; + DWORD dwVID; +} TPacketCGTarget; + +typedef struct command_move +{ + BYTE bHeader; + BYTE bFunc; + BYTE bArg; + BYTE bRot; + LONG lX; + LONG lY; + DWORD dwTime; +} TPacketCGMove; + +typedef struct command_sync_position_element +{ + DWORD dwVID; + long lX; + long lY; +} TPacketCGSyncPositionElement; + +typedef struct command_sync_position +{ + BYTE bHeader; + WORD wSize; +} TPacketCGSyncPosition; + +typedef struct command_fly_targeting +{ + BYTE bHeader; + DWORD dwTargetVID; + long lX; + long lY; +} TPacketCGFlyTargeting; + +typedef struct packet_fly_targeting +{ + BYTE bHeader; + DWORD dwShooterVID; + DWORD dwTargetVID; + long lX; + long lY; +} TPacketGCFlyTargeting; + +typedef struct packet_shoot +{ + BYTE bHeader; + BYTE bType; +} TPacketCGShoot; + +typedef struct command_warp +{ + BYTE bHeader; +} TPacketCGWarp; + +enum +{ + MESSENGER_SUBHEADER_GC_LIST, + MESSENGER_SUBHEADER_GC_LOGIN, + MESSENGER_SUBHEADER_GC_LOGOUT, + MESSENGER_SUBHEADER_GC_INVITE, + MESSENGER_SUBHEADER_GC_MOBILE, +}; + +typedef struct packet_messenger +{ + BYTE header; + WORD size; + BYTE subheader; +} TPacketGCMessenger; + +typedef struct packet_messenger_list_offline +{ + BYTE connected; // always 0 + BYTE length; +} TPacketGCMessengerListOffline; + +enum +{ + MESSENGER_CONNECTED_STATE_OFFLINE, + MESSENGER_CONNECTED_STATE_ONLINE, + MESSENGER_CONNECTED_STATE_MOBILE, +}; + +typedef struct packet_messenger_list_online +{ + BYTE connected; + BYTE length; + //BYTE length_char_name; +} TPacketGCMessengerListOnline; + +typedef struct packet_messenger_login +{ + //BYTE length_login; + //BYTE length_char_name; + BYTE length; +} TPacketGCMessengerLogin; + +typedef struct packet_messenger_logout +{ + BYTE length; +} TPacketGCMessengerLogout; + +enum +{ + MESSENGER_SUBHEADER_CG_ADD_BY_VID, + MESSENGER_SUBHEADER_CG_ADD_BY_NAME, + MESSENGER_SUBHEADER_CG_REMOVE, +}; + +typedef struct command_messenger +{ + BYTE header; + BYTE subheader; +} TPacketCGMessenger; + +typedef struct command_messenger_remove +{ + BYTE length; +} TPacketCGMessengerRemove; + +enum +{ + SAFEBOX_MONEY_STATE_SAVE, + SAFEBOX_MONEY_STATE_WITHDRAW, +}; + +typedef struct command_safebox_money +{ + BYTE bHeader; + BYTE bState; + DWORD dwMoney; +} TPacketCGSafeboxMoney; + +typedef struct command_safebox_checkout +{ + BYTE bHeader; + BYTE bSafePos; + TItemPos ItemPos; +} TPacketCGSafeboxCheckout; + +typedef struct command_safebox_checkin +{ + BYTE bHeader; + BYTE bSafePos; + TItemPos ItemPos; +} TPacketCGSafeboxCheckin; + +typedef struct command_mall_checkout +{ + BYTE bHeader; + BYTE bMallPos; + TItemPos ItemPos; +} TPacketCGMallCheckout; + +/////////////////////////////////////////////////////////////////////////////////// +// Party + +typedef struct command_use_skill +{ + BYTE bHeader; + DWORD dwVnum; + DWORD dwTargetVID; +} TPacketCGUseSkill; + +typedef struct command_party_invite +{ + BYTE header; + DWORD vid; +} TPacketCGPartyInvite; + +typedef struct command_party_invite_answer +{ + BYTE header; + DWORD leader_pid; + BYTE accept; +} TPacketCGPartyInviteAnswer; + +typedef struct command_party_remove +{ + BYTE header; + DWORD pid; +} TPacketCGPartyRemove; + +typedef struct command_party_set_state +{ + BYTE byHeader; + DWORD dwVID; + BYTE byState; + BYTE byFlag; +} TPacketCGPartySetState; + +typedef struct packet_party_link +{ + BYTE header; + DWORD pid; + DWORD vid; +} TPacketGCPartyLink; + +typedef struct packet_party_unlink +{ + BYTE header; + DWORD pid; + DWORD vid; +} TPacketGCPartyUnlink; + +typedef struct command_party_use_skill +{ + BYTE byHeader; + BYTE bySkillIndex; + DWORD dwTargetVID; +} TPacketCGPartyUseSkill; + +enum +{ + GUILD_SUBHEADER_CG_ADD_MEMBER, + GUILD_SUBHEADER_CG_REMOVE_MEMBER, + GUILD_SUBHEADER_CG_CHANGE_GRADE_NAME, + GUILD_SUBHEADER_CG_CHANGE_GRADE_AUTHORITY, + GUILD_SUBHEADER_CG_OFFER, + GUILD_SUBHEADER_CG_POST_COMMENT, + GUILD_SUBHEADER_CG_DELETE_COMMENT, + GUILD_SUBHEADER_CG_REFRESH_COMMENT, + GUILD_SUBHEADER_CG_CHANGE_MEMBER_GRADE, + GUILD_SUBHEADER_CG_USE_SKILL, + GUILD_SUBHEADER_CG_CHANGE_MEMBER_GENERAL, + GUILD_SUBHEADER_CG_GUILD_INVITE_ANSWER, + GUILD_SUBHEADER_CG_CHARGE_GSP, + GUILD_SUBHEADER_CG_DEPOSIT_MONEY, + GUILD_SUBHEADER_CG_WITHDRAW_MONEY, +}; + +typedef struct command_guild +{ + BYTE byHeader; + BYTE bySubHeader; +} TPacketCGGuild; + +typedef struct command_guild_answer_make_guild +{ + BYTE header; + char guild_name[GUILD_NAME_MAX_LEN+1]; +} TPacketCGAnswerMakeGuild; + +typedef struct command_give_item +{ + BYTE byHeader; + DWORD dwTargetVID; + TItemPos ItemPos; + BYTE byItemCount; +} TPacketCGGiveItem; + +typedef struct SPacketCGHack +{ + BYTE bHeader; + char szBuf[255 + 1]; +} TPacketCGHack; + +typedef struct command_dungeon +{ + BYTE bHeader; + WORD size; +} TPacketCGDungeon; + +// Private Shop +typedef struct SShopItemTable +{ + DWORD vnum; + BYTE count; + + TItemPos pos; // PC ̿ + DWORD price; // PC ̿ + BYTE display_pos; // PC ̿, ġ. +} TShopItemTable; + +typedef struct SPacketCGMyShop +{ + BYTE bHeader; + char szSign[SHOP_SIGN_MAX_LEN + 1]; + BYTE bCount; // count of TShopItemTable, max 39 +} TPacketCGMyShop; + +typedef struct SPacketCGRefine +{ + BYTE header; + BYTE pos; + BYTE type; +} TPacketCGRefine; + +typedef struct SPacketCGChangeName +{ + BYTE header; + BYTE index; + char name[CHARACTER_NAME_MAX_LEN+1]; +} TPacketCGChangeName; + +typedef struct command_client_version +{ + BYTE header; + char filename[32+1]; + char timestamp[32+1]; +} TPacketCGClientVersion; + +typedef struct command_client_version2 +{ + BYTE header; + char filename[32+1]; + char timestamp[32+1]; +} TPacketCGClientVersion2; + +typedef struct command_crc_report +{ + BYTE header; + BYTE byPackMode; + DWORD dwBinaryCRC32; + DWORD dwProcessCRC32; + DWORD dwRootPackCRC32; +} TPacketCGCRCReport; + +typedef struct command_china_matrix_card +{ + BYTE bHeader; + char szAnswer[CHINA_MATRIX_ANSWER_MAX_LEN + 1]; +} TPacketCGChinaMatrixCard; + +typedef struct command_runup_matrix_answer +{ + BYTE bHeader; + char szAnswer[RUNUP_MATRIX_ANSWER_MAX_LEN + 1]; +} TPacketCGRunupMatrixAnswer; + +typedef struct command_newcibn_passpod_answer +{ + BYTE bHeader; + char szAnswer[NEWCIBN_PASSPOD_ANSWER_MAX_LEN + 1]; +} TPacketCGNEWCIBNPasspodAnswer; + +enum EPartyExpDistributionType +{ + PARTY_EXP_DISTRIBUTION_NON_PARITY, + PARTY_EXP_DISTRIBUTION_PARITY, +}; + +typedef struct command_party_parameter +{ + BYTE bHeader; + BYTE bDistributeMode; +} TPacketCGPartyParameter; + +typedef struct command_quest_input_string +{ + BYTE bHeader; + char szString[QUEST_INPUT_STRING_MAX_NUM+1]; +} TPacketCGQuestInputString; + +typedef struct command_quest_confirm +{ + BYTE header; + BYTE answer; + DWORD requestPID; +} TPacketCGQuestConfirm; + +typedef struct command_script_select_item +{ + BYTE header; + DWORD selection; +} TPacketCGScriptSelectItem; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// From Server +enum EPhase +{ + PHASE_CLOSE, // (Ǵ ) + PHASE_HANDSHAKE, // Ǽ..;; + PHASE_LOGIN, // α + PHASE_SELECT, // ij ȭ + PHASE_LOADING, // ε ȭ + PHASE_GAME, // ȭ + PHASE_DEAD, // ׾ .. ( ȿ ִ ..) + + PHASE_DBCLIENT_CONNECTING, // + PHASE_DBCLIENT, // + PHASE_P2P, // + PHASE_AUTH, // α +}; + +typedef struct packet_phase +{ + BYTE header; + BYTE phase; +} TPacketGCPhase; + +typedef struct packet_blank // Ŷ. +{ + BYTE header; +} TPacketGCBlank; + +typedef struct packet_blank_dynamic +{ + BYTE header; + WORD size; +} TPacketGCBlankDynamic; + +typedef struct packet_header_handshake +{ + BYTE header; + DWORD dwHandshake; + DWORD dwTime; + LONG lDelta; +} TPacketGCHandshake; + +typedef struct packet_header_bindudp +{ + BYTE header; + DWORD addr; + WORD port; +} TPacketGCBindUDP; + +typedef struct packet_header_dynamic_size +{ + BYTE header; + WORD size; +} TDynamicSizePacketHeader; + +typedef struct SSimplePlayerInformation +{ + DWORD dwID; + char szName[CHARACTER_NAME_MAX_LEN + 1]; + BYTE byJob; + BYTE byLevel; + DWORD dwPlayMinutes; + BYTE byST, byHT, byDX, byIQ; +// WORD wParts[CRaceData::PART_MAX_NUM]; + WORD wMainPart; + BYTE bChangeName; + WORD wHairPart; + BYTE bDummy[4]; + long x, y; + LONG lAddr; + WORD wPort; + BYTE bySkillGroup; +} TSimplePlayerInformation; + +typedef struct packet_login_success3 +{ + BYTE header; + TSimplePlayerInformation akSimplePlayerInformation[PLAYER_PER_ACCOUNT3]; + DWORD guild_id[PLAYER_PER_ACCOUNT3]; + char guild_name[PLAYER_PER_ACCOUNT3][GUILD_NAME_MAX_LEN+1]; + DWORD handle; + DWORD random_key; +} TPacketGCLoginSuccess3; + +typedef struct packet_login_success4 +{ + BYTE header; + TSimplePlayerInformation akSimplePlayerInformation[PLAYER_PER_ACCOUNT4]; + DWORD guild_id[PLAYER_PER_ACCOUNT4]; + char guild_name[PLAYER_PER_ACCOUNT4][GUILD_NAME_MAX_LEN+1]; + DWORD handle; + DWORD random_key; +} TPacketGCLoginSuccess4; + + +enum { LOGIN_STATUS_MAX_LEN = 8 }; +typedef struct packet_login_failure +{ + BYTE header; + char szStatus[LOGIN_STATUS_MAX_LEN + 1]; +} TPacketGCLoginFailure; + +typedef struct command_player_create +{ + BYTE header; + BYTE index; + char name[CHARACTER_NAME_MAX_LEN + 1]; + WORD job; + BYTE shape; + BYTE CON; + BYTE INT; + BYTE STR; + BYTE DEX; +} TPacketCGCreateCharacter; + +typedef struct command_player_create_success +{ + BYTE header; + BYTE bAccountCharacterSlot; + TSimplePlayerInformation kSimplePlayerInfomation; +} TPacketGCPlayerCreateSuccess; + +typedef struct command_create_failure +{ + BYTE header; + BYTE bType; +} TPacketGCCreateFailure; + +typedef struct command_player_delete +{ + BYTE header; + BYTE index; + char szPrivateCode[PRIVATE_CODE_LENGTH]; +} TPacketCGDestroyCharacter; + +typedef struct packet_player_delete_success +{ + BYTE header; + BYTE account_index; +} TPacketGCDestroyCharacterSuccess; + +enum +{ + ADD_CHARACTER_STATE_DEAD = (1 << 0), + ADD_CHARACTER_STATE_SPAWN = (1 << 1), + ADD_CHARACTER_STATE_GUNGON = (1 << 2), + ADD_CHARACTER_STATE_KILLER = (1 << 3), + ADD_CHARACTER_STATE_PARTY = (1 << 4), +}; + +enum EPKModes +{ + PK_MODE_PEACE, + PK_MODE_REVENGE, + PK_MODE_FREE, + PK_MODE_PROTECT, + PK_MODE_GUILD, + PK_MODE_MAX_NUM, +}; + +// 2004.11.20.myevan.CRaceData::PART_MAX_NUM ϰ - ϴ°Ͱ ġ +enum ECharacterEquipmentPart +{ + CHR_EQUIPPART_ARMOR, + CHR_EQUIPPART_WEAPON, + CHR_EQUIPPART_HEAD, + CHR_EQUIPPART_HAIR, + + CHR_EQUIPPART_NUM, +}; + +typedef struct packet_char_additional_info +{ + BYTE header; + DWORD dwVID; + char name[CHARACTER_NAME_MAX_LEN + 1]; + WORD awPart[CHR_EQUIPPART_NUM]; + BYTE bEmpire; + DWORD dwGuildID; + DWORD dwLevel; + short sAlignment; //ġ + BYTE bPKMode; + DWORD dwMountVnum; +} TPacketGCCharacterAdditionalInfo; + +typedef struct packet_add_char +{ + BYTE header; + + DWORD dwVID; + + //char name[CHARACTER_NAME_MAX_LEN + 1]; + + float angle; + long x; + long y; + long z; + + BYTE bType; + WORD wRaceNum; + //WORD awPart[CHR_EQUIPPART_NUM]; + BYTE bMovingSpeed; + BYTE bAttackSpeed; + + BYTE bStateFlag; + DWORD dwAffectFlag[2]; // ?? + //BYTE bEmpire; + //DWORD dwGuild; + //short sAlignment; + //BYTE bPKMode; + //DWORD dwMountVnum; +} TPacketGCCharacterAdd; + +typedef struct packet_add_char2 +{ + BYTE header; + + DWORD dwVID; + + char name[CHARACTER_NAME_MAX_LEN + 1]; + + float angle; + long x; + long y; + long z; + + BYTE bType; + WORD wRaceNum; + WORD awPart[CHR_EQUIPPART_NUM]; + BYTE bMovingSpeed; + BYTE bAttackSpeed; + + BYTE bStateFlag; + DWORD dwAffectFlag[2]; // ?? + BYTE bEmpire; + + DWORD dwGuild; + short sAlignment; + BYTE bPKMode; + DWORD dwMountVnum; +} TPacketGCCharacterAdd2; + +typedef struct packet_update_char +{ + BYTE header; + DWORD dwVID; + + WORD awPart[CHR_EQUIPPART_NUM]; + BYTE bMovingSpeed; + BYTE bAttackSpeed; + + BYTE bStateFlag; + DWORD dwAffectFlag[2]; + + DWORD dwGuildID; + short sAlignment; + BYTE bPKMode; + DWORD dwMountVnum; +} TPacketGCCharacterUpdate; + +typedef struct packet_update_char2 +{ + BYTE header; + DWORD dwVID; + + WORD awPart[CHR_EQUIPPART_NUM]; + BYTE bMovingSpeed; + BYTE bAttackSpeed; + + BYTE bStateFlag; + DWORD dwAffectFlag[2]; + + DWORD dwGuildID; + short sAlignment; + BYTE bPKMode; + DWORD dwMountVnum; +} TPacketGCCharacterUpdate2; + +typedef struct packet_del_char +{ + BYTE header; + DWORD dwVID; +} TPacketGCCharacterDelete; + +typedef struct packet_GlobalTime +{ + BYTE header; + float GlobalTime; +} TPacketGCGlobalTime; + +enum EChatType +{ + CHAT_TYPE_TALKING, /* ׳ ä */ + CHAT_TYPE_INFO, /* ( , ġ . ) */ + CHAT_TYPE_NOTICE, /* */ + CHAT_TYPE_PARTY, /* Ƽ */ + CHAT_TYPE_GUILD, /* 帻 */ + CHAT_TYPE_COMMAND, /* */ + CHAT_TYPE_SHOUT, /* ġ */ + CHAT_TYPE_WHISPER, // ʹ ʴ Only Client Enum + CHAT_TYPE_BIG_NOTICE, + CHAT_TYPE_MAX_NUM, +}; + +typedef struct packet_chatting +{ + BYTE header; + WORD size; + BYTE type; + DWORD dwVID; + BYTE bEmpire; +} TPacketGCChat; + +typedef struct packet_whisper // Ŷ +{ + BYTE bHeader; + WORD wSize; + BYTE bType; + char szNameFrom[CHARACTER_NAME_MAX_LEN + 1]; +} TPacketGCWhisper; + +typedef struct packet_stun +{ + BYTE header; + DWORD vid; +} TPacketGCStun; + +typedef struct packet_dead +{ + BYTE header; + DWORD vid; +} TPacketGCDead; + +typedef struct packet_main_character +{ + BYTE header; + DWORD dwVID; + WORD wRaceNum; + char szName[CHARACTER_NAME_MAX_LEN + 1]; + long lX, lY, lZ; + BYTE bySkillGroup; +} TPacketGCMainCharacter; + +// SUPPORT_BGM +typedef struct packet_main_character2_empire +{ + BYTE header; + DWORD dwVID; + WORD wRaceNum; + char szName[CHARACTER_NAME_MAX_LEN + 1]; + long lX, lY, lZ; + BYTE byEmpire; + BYTE bySkillGroup; +} TPacketGCMainCharacter2_EMPIRE; + +typedef struct packet_main_character3_bgm +{ + enum + { + MUSIC_NAME_MAX_LEN = 24, + }; + BYTE header; + DWORD dwVID; + WORD wRaceNum; + char szUserName[CHARACTER_NAME_MAX_LEN + 1]; + char szBGMName[MUSIC_NAME_MAX_LEN + 1]; + long lX, lY, lZ; + BYTE byEmpire; + BYTE bySkillGroup; +} TPacketGCMainCharacter3_BGM; + +typedef struct packet_main_character4_bgm_vol +{ + enum + { + MUSIC_NAME_MAX_LEN = 24, + }; + BYTE header; + DWORD dwVID; + WORD wRaceNum; + char szUserName[CHARACTER_NAME_MAX_LEN + 1]; + char szBGMName[MUSIC_NAME_MAX_LEN + 1]; + float fBGMVol; + long lX, lY, lZ; + BYTE byEmpire; + BYTE bySkillGroup; +} TPacketGCMainCharacter4_BGM_VOL; +// END_OF_SUPPORT_BGM + +enum EPointTypes +{ + POINT_NONE, // 0 + POINT_LEVEL, // 1 + POINT_VOICE, // 2 + POINT_EXP, // 3 + POINT_NEXT_EXP, // 4 + POINT_HP, // 5 + POINT_MAX_HP, // 6 + POINT_SP, // 7 + POINT_MAX_SP, // 8 + POINT_STAMINA, // 9 ׹̳ + POINT_MAX_STAMINA, // 10 ִ ׹̳ + + POINT_GOLD, // 11 + POINT_ST, // 12 ٷ + POINT_HT, // 13 ü + POINT_DX, // 14 ø + POINT_IQ, // 15 ŷ + POINT_ATT_POWER, // 16 ݷ + POINT_ATT_SPEED, // 17 ݼӵ + POINT_EVADE_RATE, // 18 ȸ + POINT_MOV_SPEED, // 19 ̵ӵ + POINT_DEF_GRADE, // 20 + POINT_CASTING_SPEED, // 21 ֹӵ (ٿŸ*100) / (100 + ̰) = ٿ Ÿ + POINT_MAGIC_ATT_GRADE, // 22 ݷ + POINT_MAGIC_DEF_GRADE, // 23 + POINT_EMPIRE_POINT, // 24 + POINT_LEVEL_STEP, // 25 ܰ.. (1 2 3 , 4 Ǹ ) + POINT_STAT, // 26 ɷġ ø ִ + POINT_SUB_SKILL, // 27 ų Ʈ + POINT_SKILL, // 28 Ƽ ų Ʈ +// POINT_SKILL_PASV, // 27 нú ø ִ +// POINT_SKILL_ACTIVE, // 28 Ƽ ų Ʈ + POINT_MIN_ATK, // 29 ּ ı + POINT_MAX_ATK, // 30 ִ ı + POINT_PLAYTIME, // 31 ÷̽ð + POINT_HP_REGEN, // 32 HP ȸ + POINT_SP_REGEN, // 33 SP ȸ + + POINT_BOW_DISTANCE, // 34 Ȱ Ÿ ġ (meter) + + POINT_HP_RECOVERY, // 35 ü ȸ + POINT_SP_RECOVERY, // 36 ŷ ȸ + + POINT_POISON_PCT, // 37 Ȯ + POINT_STUN_PCT, // 38 Ȯ + POINT_SLOW_PCT, // 39 ο Ȯ + POINT_CRITICAL_PCT, // 40 ũƼ Ȯ + POINT_PENETRATE_PCT, // 41 Ÿ Ȯ + POINT_CURSE_PCT, // 42 Ȯ + + POINT_ATTBONUS_HUMAN, // 43 ΰ + POINT_ATTBONUS_ANIMAL, // 44 % + POINT_ATTBONUS_ORC, // 45 Ϳ % + POINT_ATTBONUS_MILGYO, // 46 б % + POINT_ATTBONUS_UNDEAD, // 47 ü % + POINT_ATTBONUS_DEVIL, // 48 (Ǹ) % + POINT_ATTBONUS_INSECT, // 49 + POINT_ATTBONUS_FIRE, // 50 ȭ + POINT_ATTBONUS_ICE, // 51 + POINT_ATTBONUS_DESERT, // 52 縷 + POINT_ATTBONUS_UNUSED0, // 53 UNUSED0 + POINT_ATTBONUS_UNUSED1, // 54 UNUSED1 + POINT_ATTBONUS_UNUSED2, // 55 UNUSED2 + POINT_ATTBONUS_UNUSED3, // 56 UNUSED3 + POINT_ATTBONUS_UNUSED4, // 57 UNUSED4 + POINT_ATTBONUS_UNUSED5, // 58 UNUSED5 + POINT_ATTBONUS_UNUSED6, // 59 UNUSED6 + POINT_ATTBONUS_UNUSED7, // 60 UNUSED7 + POINT_ATTBONUS_UNUSED8, // 61 UNUSED8 + POINT_ATTBONUS_UNUSED9, // 62 UNUSED9 + + POINT_STEAL_HP, // 63 + POINT_STEAL_SP, // 64 ŷ + + POINT_MANA_BURN_PCT, // 65 + + /// ؽ ʽ /// + + POINT_DAMAGE_SP_RECOVER, // 66 ݴ ŷ ȸ Ȯ + + POINT_BLOCK, // 67 + POINT_DODGE, // 68 ȸ + + POINT_RESIST_SWORD, // 69 + POINT_RESIST_TWOHAND, // 70 + POINT_RESIST_DAGGER, // 71 + POINT_RESIST_BELL, // 72 + POINT_RESIST_FAN, // 73 + POINT_RESIST_BOW, // 74 ȭ : + POINT_RESIST_FIRE, // 75 ȭ : ȭݿ + POINT_RESIST_ELEC, // 76 : ݿ + POINT_RESIST_MAGIC, // 77 : + POINT_RESIST_WIND, // 78 ٶ : ٶݿ + + POINT_REFLECT_MELEE, // 79 ݻ + + /// Ư ؽ /// + POINT_REFLECT_CURSE, // 80 ݻ + POINT_POISON_REDUCE, // 81 + + /// Ҹ /// + POINT_KILL_SP_RECOVER, // 82 Ҹ MP ȸ + POINT_EXP_DOUBLE_BONUS, // 83 + POINT_GOLD_DOUBLE_BONUS, // 84 + POINT_ITEM_DROP_BONUS, // 85 + + /// ȸ /// + POINT_POTION_BONUS, // 86 + POINT_KILL_HP_RECOVER, // 87 + + POINT_IMMUNE_STUN, // 88 + POINT_IMMUNE_SLOW, // 89 + POINT_IMMUNE_FALL, // 90 + ////////////////// + + POINT_PARTY_ATT_GRADE, // 91 + POINT_PARTY_DEF_GRADE, // 92 + + POINT_ATT_BONUS, // 93 + POINT_DEF_BONUS, // 94 + + POINT_ATT_GRADE_BONUS, // 95 + POINT_DEF_GRADE_BONUS, // 96 + POINT_MAGIC_ATT_GRADE_BONUS, // 97 + POINT_MAGIC_DEF_GRADE_BONUS, // 98 + + POINT_RESIST_NORMAL_DAMAGE, // 99 + + POINT_STAT_RESET_COUNT = 112, + POINT_HORSE_SKILL = 113, + + POINT_MALL_ATTBONUS, // 114 ݷ +x% + POINT_MALL_DEFBONUS, // 115 +x% + POINT_MALL_EXPBONUS, // 116 ġ +x% + POINT_MALL_ITEMBONUS, // 117 x/10 + POINT_MALL_GOLDBONUS, // 118 x/10 + POINT_MAX_HP_PCT, // 119 ִ +x% + POINT_MAX_SP_PCT, // 120 ִŷ +x% + + POINT_SKILL_DAMAGE_BONUS, // 121 ų *(100+x)% + POINT_NORMAL_HIT_DAMAGE_BONUS, // 122 Ÿ *(100+x)% + + POINT_SKILL_DEFEND_BONUS, // 123 ų + POINT_NORMAL_HIT_DEFEND_BONUS, // 124 Ÿ + POINT_PC_BANG_EXP_BONUS, // 125 + POINT_PC_BANG_DROP_BONUS, // 126 PC ӷ ʽ + + POINT_ENERGY = 128, // 128 + + // ui . + // ̷ ϰ ʾ, + // uiTaskBar affect , + // Ŭ󸮾Ʈ blend_affect ʾ, + // ӽ÷ ̷ д. + POINT_ENERGY_END_TIME = 129, // 129 ð + + // Ŭ̾Ʈ Ʈ + POINT_MIN_WEP = 200, + POINT_MAX_WEP, + POINT_MIN_MAGIC_WEP, + POINT_MAX_MAGIC_WEP, + POINT_HIT_RATE, + + + //POINT_MAX_NUM = 255,=>stdafx.h / +}; + +typedef struct packet_points +{ + BYTE header; + long points[POINT_MAX_NUM]; +} TPacketGCPoints; + +typedef struct packet_point_change +{ + int header; + + DWORD dwVID; + BYTE Type; + + long amount; // ٲ + long value; // +} TPacketGCPointChange; + +typedef struct packet_motion +{ + BYTE header; + DWORD vid; + DWORD victim_vid; + WORD motion; +} TPacketGCMotion; + +#if defined(GAIDEN) +struct TPacketGCItemDelDeprecate +{ + TPacketGCItemDelDeprecate() : + header(HEADER_GC_ITEM_DEL), + pos(0), + vnum(0), + count(0) + { + memset(&alSockets, 0, sizeof(alSockets)); + memset(&aAttr, 0, sizeof(aAttr)); + } + + BYTE header; + BYTE pos; + DWORD vnum; + BYTE count; + long alSockets[ITEM_SOCKET_SLOT_MAX_NUM]; + TPlayerItemAttribute aAttr[ITEM_ATTRIBUTE_SLOT_MAX_NUM]; +}; + +typedef struct packet_set_item +{ + BYTE header; + BYTE pos; + DWORD vnum; + BYTE count; + DWORD flags; // ÷ ߰ + long alSockets[ITEM_SOCKET_SLOT_MAX_NUM]; + TPlayerItemAttribute aAttr[ITEM_ATTRIBUTE_SLOT_MAX_NUM]; +} TPacketGCItemSet; + +typedef struct packet_item_del +{ + BYTE header; + BYTE pos; +} TPacketGCItemDel; +#else +typedef struct packet_set_item +{ + BYTE header; + TItemPos Cell; + DWORD vnum; + BYTE count; + long alSockets[ITEM_SOCKET_SLOT_MAX_NUM]; + TPlayerItemAttribute aAttr[ITEM_ATTRIBUTE_SLOT_MAX_NUM]; +} TPacketGCItemSet; + +typedef struct packet_set_item2 +{ + BYTE header; + TItemPos Cell; + DWORD vnum; + BYTE count; + DWORD flags; // ÷ ߰ + DWORD anti_flags; // ÷ ߰ + bool highlight; + long alSockets[ITEM_SOCKET_SLOT_MAX_NUM]; + TPlayerItemAttribute aAttr[ITEM_ATTRIBUTE_SLOT_MAX_NUM]; +} TPacketGCItemSet2; +#endif + +typedef struct packet_item_del +{ + BYTE header; + BYTE pos; +} TPacketGCItemDel; + +typedef struct packet_use_item +{ + BYTE header; + TItemPos Cell; + DWORD ch_vid; + DWORD victim_vid; + + DWORD vnum; +} TPacketGCItemUse; + +typedef struct packet_update_item +{ + BYTE header; + TItemPos Cell; + BYTE count; + long alSockets[ITEM_SOCKET_SLOT_MAX_NUM]; + TPlayerItemAttribute aAttr[ITEM_ATTRIBUTE_SLOT_MAX_NUM]; +} TPacketGCItemUpdate; + +typedef struct packet_ground_add_item +{ + BYTE bHeader; + long lX; + long lY; + long lZ; + + DWORD dwVID; + DWORD dwVnum; +} TPacketGCItemGroundAdd; + +typedef struct packet_ground_del_item +{ + BYTE header; + DWORD vid; +} TPacketGCItemGroundDel; + +typedef struct packet_item_ownership +{ + BYTE bHeader; + DWORD dwVID; + char szName[CHARACTER_NAME_MAX_LEN + 1]; +} TPacketGCItemOwnership; + +typedef struct packet_quickslot_add +{ + BYTE header; + BYTE pos; + TQuickSlot slot; +} TPacketGCQuickSlotAdd; + +typedef struct packet_quickslot_del +{ + BYTE header; + BYTE pos; +} TPacketGCQuickSlotDel; + +typedef struct packet_quickslot_swap +{ + BYTE header; + BYTE pos; + BYTE change_pos; +} TPacketGCQuickSlotSwap; + +typedef struct packet_shop_start +{ + struct packet_shop_item items[SHOP_HOST_ITEM_MAX_NUM]; +} TPacketGCShopStart; + +typedef struct packet_shop_start_ex // TSubPacketShopTab* shop_tabs . +{ + typedef struct sub_packet_shop_tab + { + char name[SHOP_TAB_NAME_MAX]; + BYTE coin_type; + packet_shop_item items[SHOP_HOST_ITEM_MAX_NUM]; + } TSubPacketShopTab; + DWORD owner_vid; + BYTE shop_tab_count; +} TPacketGCShopStartEx; + + +typedef struct packet_shop_update_item +{ + BYTE pos; + struct packet_shop_item item; +} TPacketGCShopUpdateItem; + +typedef struct packet_shop_update_price +{ + int iElkAmount; +} TPacketGCShopUpdatePrice; + +enum EPacketShopSubHeaders +{ + SHOP_SUBHEADER_GC_START, + SHOP_SUBHEADER_GC_END, + SHOP_SUBHEADER_GC_UPDATE_ITEM, + SHOP_SUBHEADER_GC_UPDATE_PRICE, + SHOP_SUBHEADER_GC_OK, + SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY, + SHOP_SUBHEADER_GC_SOLDOUT, + SHOP_SUBHEADER_GC_INVENTORY_FULL, + SHOP_SUBHEADER_GC_INVALID_POS, + SHOP_SUBHEADER_GC_SOLD_OUT, + SHOP_SUBHEADER_GC_START_EX, + SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY_EX, +}; + +typedef struct packet_shop +{ + BYTE header; + WORD size; + BYTE subheader; +} TPacketGCShop; + +typedef struct packet_exchange +{ + BYTE header; + BYTE subheader; + BYTE is_me; + DWORD arg1; + TItemPos arg2; + DWORD arg3; + long alValues[ITEM_SOCKET_SLOT_MAX_NUM]; + TPlayerItemAttribute aAttr[ITEM_ATTRIBUTE_SLOT_MAX_NUM]; +} TPacketGCExchange; + +enum +{ + EXCHANGE_SUBHEADER_GC_START, // arg1 == vid + EXCHANGE_SUBHEADER_GC_ITEM_ADD, // arg1 == vnum arg2 == pos arg3 == count + EXCHANGE_SUBHEADER_GC_ITEM_DEL, // arg1 == pos + EXCHANGE_SUBHEADER_GC_ELK_ADD, // arg1 == elk + EXCHANGE_SUBHEADER_GC_ACCEPT, // arg1 == accept + EXCHANGE_SUBHEADER_GC_END, // arg1 == not used + EXCHANGE_SUBHEADER_GC_ALREADY, // arg1 == not used + EXCHANGE_SUBHEADER_GC_LESS_ELK, // arg1 == not used +}; + +typedef struct packet_position +{ + BYTE header; + DWORD vid; + BYTE position; +} TPacketGCPosition; + +typedef struct packet_ping +{ + BYTE header; +} TPacketGCPing; + +typedef struct packet_pong +{ + BYTE bHeader; +} TPacketCGPong; + +typedef struct packet_script +{ + BYTE header; + WORD size; + BYTE skin; + WORD src_size; +} TPacketGCScript; + +typedef struct packet_target +{ + BYTE header; + DWORD dwVID; + BYTE bHPPercent; +} TPacketGCTarget; + +typedef struct packet_damage_info +{ + BYTE header; + DWORD dwVID; + BYTE flag; + int damage; +} TPacketGCDamageInfo; + +typedef struct packet_mount +{ + BYTE header; + DWORD vid; + DWORD mount_vid; + BYTE pos; + DWORD _x, _y; +} TPacketGCMount; + +typedef struct packet_change_speed +{ + BYTE header; + DWORD vid; + WORD moving_speed; +} TPacketGCChangeSpeed; + +typedef struct packet_move +{ + BYTE bHeader; + BYTE bFunc; + BYTE bArg; + BYTE bRot; + DWORD dwVID; + LONG lX; + LONG lY; + DWORD dwTime; + DWORD dwDuration; +} TPacketGCMove; + +enum +{ + QUEST_SEND_IS_BEGIN = 1 << 0, + QUEST_SEND_TITLE = 1 << 1, // 28 + QUEST_SEND_CLOCK_NAME = 1 << 2, // 16 + QUEST_SEND_CLOCK_VALUE = 1 << 3, + QUEST_SEND_COUNTER_NAME = 1 << 4, // 16 + QUEST_SEND_COUNTER_VALUE = 1 << 5, + QUEST_SEND_ICON_FILE = 1 << 6, // 24 +}; + +typedef struct packet_quest_info +{ + BYTE header; + WORD size; + WORD index; + BYTE flag; +} TPacketGCQuestInfo; + +typedef struct packet_quest_confirm +{ + BYTE header; + char msg[64+1]; + long timeout; + DWORD requestPID; +} TPacketGCQuestConfirm; + +typedef struct packet_attack +{ + BYTE header; + DWORD dwVID; + DWORD dwVictimVID; // VID + BYTE bType; // +} TPacketGCAttack; + +typedef struct packet_c2c +{ + BYTE header; + WORD wSize; +} TPacketGCC2C; + +typedef struct packetd_sync_position_element +{ + DWORD dwVID; + long lX; + long lY; +} TPacketGCSyncPositionElement; + +typedef struct packetd_sync_position +{ + BYTE bHeader; + WORD wSize; +} TPacketGCSyncPosition; + +typedef struct packet_ownership +{ + BYTE bHeader; + DWORD dwOwnerVID; + DWORD dwVictimVID; +} TPacketGCOwnership; + +#define SKILL_MAX_NUM 255 + +typedef struct packet_skill_level +{ + BYTE bHeader; + BYTE abSkillLevels[SKILL_MAX_NUM]; +} TPacketGCSkillLevel; + +typedef struct SPlayerSkill +{ + BYTE bMasterType; + BYTE bLevel; + time_t tNextRead; +} TPlayerSkill; + +typedef struct packet_skill_level_new +{ + BYTE bHeader; + TPlayerSkill skills[SKILL_MAX_NUM]; +} TPacketGCSkillLevelNew; + +// fly +typedef struct packet_fly +{ + BYTE bHeader; + BYTE bType; + DWORD dwStartVID; + DWORD dwEndVID; +} TPacketGCCreateFly; + +enum EPVPModes +{ + PVP_MODE_NONE, + PVP_MODE_AGREE, + PVP_MODE_FIGHT, + PVP_MODE_REVENGE, +}; + +typedef struct packet_duel_start +{ + BYTE header ; + WORD wSize ; // DWORD ? = (wSize - sizeof(TPacketGCPVPList)) / 4 +} TPacketGCDuelStart ; + +typedef struct packet_pvp +{ + BYTE header; + DWORD dwVIDSrc; + DWORD dwVIDDst; + BYTE bMode; +} TPacketGCPVP; + +typedef struct packet_skill_cooltime_end +{ + BYTE header; + BYTE bSkill; +} TPacketGCSkillCoolTimeEnd; + +typedef struct packet_warp +{ + BYTE bHeader; + LONG lX; + LONG lY; + LONG lAddr; + WORD wPort; +} TPacketGCWarp; + +typedef struct packet_party_invite +{ + BYTE header; + DWORD leader_pid; +} TPacketGCPartyInvite; + +typedef struct packet_party_add +{ + BYTE header; + DWORD pid; + char name[CHARACTER_NAME_MAX_LEN+1]; +} TPacketGCPartyAdd; + +typedef struct packet_party_update +{ + BYTE header; + DWORD pid; + BYTE state; + BYTE percent_hp; + short affects[PARTY_AFFECT_SLOT_MAX_NUM]; +} TPacketGCPartyUpdate; + +typedef struct packet_party_remove +{ + BYTE header; + DWORD pid; +} TPacketGCPartyRemove; + +typedef TPacketCGSafeboxCheckout TPacketGCSafeboxCheckout; +typedef TPacketCGSafeboxCheckin TPacketGCSafeboxCheckin; + +typedef struct packet_safebox_wrong_password +{ + BYTE bHeader; +} TPacketGCSafeboxWrongPassword; + +typedef struct packet_safebox_size +{ + BYTE bHeader; + BYTE bSize; +} TPacketGCSafeboxSize; + +typedef struct packet_safebox_money_change +{ + BYTE bHeader; + DWORD dwMoney; +} TPacketGCSafeboxMoneyChange; + +typedef struct command_empire +{ + BYTE bHeader; + BYTE bEmpire; +} TPacketCGEmpire; + +typedef struct packet_empire +{ + BYTE bHeader; + BYTE bEmpire; +} TPacketGCEmpire; + +enum +{ + FISHING_SUBHEADER_GC_START, + FISHING_SUBHEADER_GC_STOP, + FISHING_SUBHEADER_GC_REACT, + FISHING_SUBHEADER_GC_SUCCESS, + FISHING_SUBHEADER_GC_FAIL, + FISHING_SUBHEADER_GC_FISH, +}; + +typedef struct packet_fishing +{ + BYTE header; + BYTE subheader; + DWORD info; + BYTE dir; +} TPacketGCFishing; + +typedef struct paryt_parameter +{ + BYTE bHeader; + BYTE bDistributeMode; +} TPacketGCPartyParameter; + +////////////////////////////////////////////////////////////////////////// +// Guild + +enum +{ + GUILD_SUBHEADER_GC_LOGIN, + GUILD_SUBHEADER_GC_LOGOUT, + GUILD_SUBHEADER_GC_LIST, + GUILD_SUBHEADER_GC_GRADE, + GUILD_SUBHEADER_GC_ADD, + GUILD_SUBHEADER_GC_REMOVE, + GUILD_SUBHEADER_GC_GRADE_NAME, + GUILD_SUBHEADER_GC_GRADE_AUTH, + GUILD_SUBHEADER_GC_INFO, + GUILD_SUBHEADER_GC_COMMENTS, + GUILD_SUBHEADER_GC_CHANGE_EXP, + GUILD_SUBHEADER_GC_CHANGE_MEMBER_GRADE, + GUILD_SUBHEADER_GC_SKILL_INFO, + GUILD_SUBHEADER_GC_CHANGE_MEMBER_GENERAL, + GUILD_SUBHEADER_GC_GUILD_INVITE, + GUILD_SUBHEADER_GC_WAR, + GUILD_SUBHEADER_GC_GUILD_NAME, + GUILD_SUBHEADER_GC_GUILD_WAR_LIST, + GUILD_SUBHEADER_GC_GUILD_WAR_END_LIST, + GUILD_SUBHEADER_GC_WAR_POINT, + GUILD_SUBHEADER_GC_MONEY_CHANGE, +}; + +typedef struct packet_guild +{ + BYTE header; + WORD size; + BYTE subheader; +} TPacketGCGuild; + +// SubHeader - Grade +enum +{ + GUILD_AUTH_ADD_MEMBER = (1 << 0), + GUILD_AUTH_REMOVE_MEMBER = (1 << 1), + GUILD_AUTH_NOTICE = (1 << 2), + GUILD_AUTH_SKILL = (1 << 3), +}; + +typedef struct packet_guild_sub_grade +{ + char grade_name[GUILD_GRADE_NAME_MAX_LEN+1]; // 8+1 , ̸ + BYTE auth_flag; +} TPacketGCGuildSubGrade; + +typedef struct packet_guild_sub_member +{ + DWORD pid; + BYTE byGrade; + BYTE byIsGeneral; + BYTE byJob; + BYTE byLevel; + DWORD dwOffer; + BYTE byNameFlag; +// if NameFlag is TRUE, name is sent from server. +// char szName[CHARACTER_ME_MAX_LEN+1]; +} TPacketGCGuildSubMember; + +typedef struct packet_guild_sub_info +{ + WORD member_count; + WORD max_member_count; + DWORD guild_id; + DWORD master_pid; + DWORD exp; + BYTE level; + char name[GUILD_NAME_MAX_LEN+1]; + DWORD gold; + BYTE hasLand; +} TPacketGCGuildInfo; + +enum EGuildWarState +{ + GUILD_WAR_NONE, + GUILD_WAR_SEND_DECLARE, + GUILD_WAR_REFUSE, + GUILD_WAR_RECV_DECLARE, + GUILD_WAR_WAIT_START, + GUILD_WAR_CANCEL, + GUILD_WAR_ON_WAR, + GUILD_WAR_END, + + GUILD_WAR_DURATION = 2*60*60, // 2ð +}; + +typedef struct packet_guild_war +{ + DWORD dwGuildSelf; + DWORD dwGuildOpp; + BYTE bType; + BYTE bWarState; +} TPacketGCGuildWar; + +typedef struct SPacketGuildWarPoint +{ + DWORD dwGainGuildID; + DWORD dwOpponentGuildID; + long lPoint; +} TPacketGuildWarPoint; + +// SubHeader - Dungeon +enum +{ + DUNGEON_SUBHEADER_GC_TIME_ATTACK_START = 0, + DUNGEON_SUBHEADER_GC_DESTINATION_POSITION = 1, +}; + +typedef struct packet_dungeon +{ + BYTE bHeader; + WORD size; + BYTE subheader; +} TPacketGCDungeon; + +// Private Shop +typedef struct SPacketGCShopSign +{ + BYTE bHeader; + DWORD dwVID; + char szSign[SHOP_SIGN_MAX_LEN + 1]; +} TPacketGCShopSign; + +typedef struct SPacketGCTime +{ + BYTE bHeader; + time_t time; +} TPacketGCTime; + +enum +{ + WALKMODE_RUN, + WALKMODE_WALK, +}; + +typedef struct SPacketGCWalkMode +{ + BYTE header; + DWORD vid; + BYTE mode; +} TPacketGCWalkMode; + +typedef struct SPacketGCChangeSkillGroup +{ + BYTE header; + BYTE skill_group; +} TPacketGCChangeSkillGroup; + +struct TMaterial +{ + DWORD vnum; + DWORD count; +}; + +typedef struct SRefineTable +{ + DWORD src_vnum; + DWORD result_vnum; + BYTE material_count; + int cost; // ҿ + int prob; // Ȯ + TMaterial materials[REFINE_MATERIAL_MAX_NUM]; +} TRefineTable; + +typedef struct SPacketGCRefineInformation +{ + BYTE header; + BYTE pos; + TRefineTable refine_table; +} TPacketGCRefineInformation; + +typedef struct SPacketGCRefineInformationNew +{ + BYTE header; + BYTE type; + BYTE pos; + TRefineTable refine_table; +} TPacketGCRefineInformationNew; + +enum SPECIAL_EFFECT +{ + SE_NONE, + SE_HPUP_RED, + SE_SPUP_BLUE, + SE_SPEEDUP_GREEN, + SE_DXUP_PURPLE, + SE_CRITICAL, + SE_PENETRATE, + SE_BLOCK, + SE_DODGE, + SE_CHINA_FIREWORK, + SE_SPIN_TOP, + SE_SUCCESS, + SE_FAIL, + SE_FR_SUCCESS, + SE_LEVELUP_ON_14_FOR_GERMANY, // 14϶ ( ) + SE_LEVELUP_UNDER_15_FOR_GERMANY,// 15϶ ( ) + SE_PERCENT_DAMAGE1, + SE_PERCENT_DAMAGE2, + SE_PERCENT_DAMAGE3, + SE_AUTO_HPUP, + SE_AUTO_SPUP, + SE_EQUIP_RAMADAN_RING, // ʽ´ ϴ ߵϴ Ʈ + SE_EQUIP_HALLOWEEN_CANDY, // ҷ (-_-;) ߵϴ Ʈ + SE_EQUIP_HAPPINESS_RING, // ũ ູ ϴ ߵϴ Ʈ + SE_EQUIP_LOVE_PENDANT, // ߷Ÿ ҴƮ(71145) Ʈ (ߵƮ, Ʈ ƴ) +}; + +typedef struct SPacketGCSpecialEffect +{ + BYTE header; + BYTE type; + DWORD vid; +} TPacketGCSpecialEffect; + +typedef struct SPacketGCNPCPosition +{ + BYTE header; + WORD size; + WORD count; +} TPacketGCNPCPosition; + +struct TNPCPosition +{ + BYTE bType; + char name[CHARACTER_NAME_MAX_LEN+1]; + long x; + long y; +}; + +typedef struct SPacketGCChangeName +{ + BYTE header; + DWORD pid; + char name[CHARACTER_NAME_MAX_LEN+1]; +} TPacketGCChangeName; + +enum EBlockAction +{ + BLOCK_EXCHANGE = (1 << 0), + BLOCK_PARTY_INVITE = (1 << 1), + BLOCK_GUILD_INVITE = (1 << 2), + BLOCK_WHISPER = (1 << 3), + BLOCK_MESSENGER_INVITE = (1 << 4), + BLOCK_PARTY_REQUEST = (1 << 5), +}; + +typedef struct packet_china_matrixd_card +{ + BYTE bHeader; + DWORD dwRows; + DWORD dwCols; +} TPacketGCChinaMatrixCard; + +typedef struct packet_runup_matrixd_quiz +{ + BYTE bHeader; + char szQuiz[RUNUP_MATRIX_QUIZ_MAX_LEN + 1]; +} TPacketGCRunupMatrixQuiz; + +typedef struct packet_newcibn_passpod_request +{ + BYTE bHeader; +} TPacketGCNEWCIBNPasspodRequest; + +typedef struct packet_newcibn_passpod_failure +{ + BYTE bHeader; + char szMessage[NEWCIBN_PASSPOD_FAILURE_MAX_LEN + 1]; +} TPacketGCNEWCIBNPasspodFailure; + +typedef struct packet_login_key +{ + BYTE bHeader; + DWORD dwLoginKey; +} TPacketGCLoginKey; + +typedef struct packet_auth_success +{ + BYTE bHeader; + DWORD dwLoginKey; + BYTE bResult; +} TPacketGCAuthSuccess; + +typedef struct packet_auth_success_openid +{ + BYTE bHeader; + DWORD dwLoginKey; + BYTE bResult; + char login[ID_MAX_NUM + 1]; +} TPacketGCAuthSuccessOpenID; + +typedef struct packet_channel +{ + BYTE header; + BYTE channel; +} TPacketGCChannel; + +typedef struct SEquipmentItemSet +{ + DWORD vnum; + BYTE count; + long alSockets[ITEM_SOCKET_SLOT_MAX_NUM]; + TPlayerItemAttribute aAttr[ITEM_ATTRIBUTE_SLOT_MAX_NUM]; +} TEquipmentItemSet; + +typedef struct pakcet_view_equip +{ + BYTE header; + DWORD dwVID; + TEquipmentItemSet equips[WEAR_MAX_NUM]; +} TPacketGCViewEquip; + +typedef struct +{ + DWORD dwID; + long x, y; + long width, height; + DWORD dwGuildID; +} TLandPacketElement; + +typedef struct packet_land_list +{ + BYTE header; + WORD size; +} TPacketGCLandList; + +typedef struct +{ + BYTE bHeader; + long lID; + char szTargetName[32+1]; +} TPacketGCTargetCreate; + +enum +{ + CREATE_TARGET_TYPE_NONE, + CREATE_TARGET_TYPE_LOCATION, + CREATE_TARGET_TYPE_CHARACTER, +}; + +typedef struct +{ + BYTE bHeader; + long lID; + char szTargetName[32+1]; + DWORD dwVID; + BYTE byType; +} TPacketGCTargetCreateNew; + +typedef struct +{ + BYTE bHeader; + long lID; + long lX, lY; +} TPacketGCTargetUpdate; + +typedef struct +{ + BYTE bHeader; + long lID; +} TPacketGCTargetDelete; + +typedef struct +{ + DWORD dwType; + BYTE bPointIdxApplyOn; + long lApplyValue; + DWORD dwFlag; + long lDuration; + long lSPCost; +} TPacketAffectElement; + +typedef struct +{ + BYTE bHeader; + TPacketAffectElement elem; +} TPacketGCAffectAdd; + +typedef struct +{ + BYTE bHeader; + DWORD dwType; + BYTE bApplyOn; +} TPacketGCAffectRemove; + +typedef struct packet_mall_open +{ + BYTE bHeader; + BYTE bSize; +} TPacketGCMallOpen; + +typedef struct packet_lover_info +{ + BYTE bHeader; + char szName[CHARACTER_NAME_MAX_LEN + 1]; + BYTE byLovePoint; +} TPacketGCLoverInfo; + +typedef struct packet_love_point_update +{ + BYTE bHeader; + BYTE byLovePoint; +} TPacketGCLovePointUpdate; + +typedef struct packet_dig_motion +{ + BYTE header; + DWORD vid; + DWORD target_vid; + BYTE count; +} TPacketGCDigMotion; + +typedef struct SPacketGCOnTime +{ + BYTE header; + int ontime; // sec +} TPacketGCOnTime; + +typedef struct SPacketGCResetOnTime +{ + BYTE header; +} TPacketGCResetOnTime; + +typedef struct SPacketGCPanamaPack +{ + BYTE bHeader; + char szPackName[256]; + BYTE abIV[32]; +} TPacketGCPanamaPack; + +typedef struct SPacketGCHybridCryptKeys +{ +private: + SPacketGCHybridCryptKeys() : m_pStream(NULL) {} + +public: + SPacketGCHybridCryptKeys(int iStreamSize) : iKeyStreamLen(iStreamSize) + { + m_pStream = new BYTE[iStreamSize]; + } + ~SPacketGCHybridCryptKeys() + { + if( m_pStream ) + { + delete[] m_pStream; + m_pStream = NULL; + } + } + static int GetFixedHeaderSize() + { + return sizeof(BYTE)+sizeof(WORD)+sizeof(int); + } + + BYTE bHeader; + WORD wDynamicPacketSize; + int iKeyStreamLen; + BYTE* m_pStream; + +} TPacketGCHybridCryptKeys; + + +typedef struct SPacketGCHybridSDB +{ +private: + SPacketGCHybridSDB() : m_pStream(NULL) {} + +public: + SPacketGCHybridSDB(int iStreamSize) : iSDBStreamLen(iStreamSize) + { + m_pStream = new BYTE[iStreamSize]; + } + ~SPacketGCHybridSDB() + { + delete[] m_pStream; + m_pStream = NULL; + } + static int GetFixedHeaderSize() + { + return sizeof(BYTE)+sizeof(WORD)+sizeof(int); + } + + BYTE bHeader; + WORD wDynamicPacketSize; + int iSDBStreamLen; + BYTE* m_pStream; + +} TPacketGCHybridSDB; +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Client To Client + +typedef struct packet_state +{ + BYTE bHeader; + BYTE bFunc; + BYTE bArg; + BYTE bRot; + DWORD dwVID; + DWORD dwTime; + TPixelPosition kPPos; +} TPacketCCState; + +typedef struct packet_hs_check_req +{ + BYTE bHeader; + AHNHS_TRANS_BUFFER Req; +} TPacketHSCheck; + +//NOTE : recv/send , bPacketData 븸 ٲ. +typedef struct packet_xtrap_verify +{ + BYTE bHeader; + BYTE bPacketData[128]; + +} TPacketXTrapCSVerify; +// AUTOBAN +typedef struct packet_autoban_quiz +{ + BYTE bHeader; + BYTE bDuration; + BYTE bCaptcha[64*32]; + char szQuiz[256]; +} TPacketGCAutoBanQuiz; +// END_OF_AUTOBAN + +#ifdef _IMPROVED_PACKET_ENCRYPTION_ +struct TPacketKeyAgreement +{ + static const int MAX_DATA_LEN = 256; + BYTE bHeader; + WORD wAgreedLength; + WORD wDataLength; + BYTE data[MAX_DATA_LEN]; +}; + +struct TPacketKeyAgreementCompleted +{ + BYTE bHeader; + BYTE data[3]; // dummy (not used) +}; +#endif // _IMPROVED_PACKET_ENCRYPTION_ + +#ifdef __AUCTION__ +// Argument 뵵 cmd ٸ. +typedef struct SPacketCGAuctionCmd +{ + BYTE bHeader; + BYTE cmd; + int arg1; + int arg2; + int arg3; + int arg4; +} TPacketCGAuctionCmd; + +typedef struct SPacketGCAuctionItemListPack +{ + BYTE bHeader; + BYTE bNumbers; +} TPacketGCAuctionItemListPack; + +#endif + +typedef struct SPacketGCSpecificEffect +{ + BYTE header; + DWORD vid; + char effect_file[128]; +} TPacketGCSpecificEffect; + +// ȥ +enum EDragonSoulRefineWindowRefineType +{ + DragonSoulRefineWindow_UPGRADE, + DragonSoulRefineWindow_IMPROVEMENT, + DragonSoulRefineWindow_REFINE, +}; + +enum EPacketCGDragonSoulSubHeaderType +{ + DS_SUB_HEADER_OPEN, + DS_SUB_HEADER_CLOSE, + DS_SUB_HEADER_DO_UPGRADE, + DS_SUB_HEADER_DO_IMPROVEMENT, + DS_SUB_HEADER_DO_REFINE, + DS_SUB_HEADER_REFINE_FAIL, + DS_SUB_HEADER_REFINE_FAIL_MAX_REFINE, + DS_SUB_HEADER_REFINE_FAIL_INVALID_MATERIAL, + DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MONEY, + DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MATERIAL, + DS_SUB_HEADER_REFINE_FAIL_TOO_MUCH_MATERIAL, + DS_SUB_HEADER_REFINE_SUCCEED, +}; + +typedef struct SPacketCGDragonSoulRefine +{ + SPacketCGDragonSoulRefine() : header (HEADER_CG_DRAGON_SOUL_REFINE) + {} + BYTE header; + BYTE bSubType; + TItemPos ItemGrid[DS_REFINE_WINDOW_MAX_NUM]; +} TPacketCGDragonSoulRefine; + +typedef struct SPacketGCDragonSoulRefine +{ + SPacketGCDragonSoulRefine() : header(HEADER_GC_DRAGON_SOUL_REFINE) + {} + BYTE header; + BYTE bSubType; + TItemPos Pos; +} TPacketGCDragonSoulRefine; + +typedef struct SChannelStatus +{ + short nPort; + BYTE bStatus; +} TChannelStatus; + +#pragma pack(pop) diff --git a/source/UserInterface/ProcessCRC.cpp b/source/UserInterface/ProcessCRC.cpp new file mode 100644 index 0000000..5fcb8a1 --- /dev/null +++ b/source/UserInterface/ProcessCRC.cpp @@ -0,0 +1,130 @@ +#include "StdAfx.h" + +#include + +static BYTE abCRCMagicCube[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; +static BYTE abCRCXorTable[8] = { 102, 30, 188, 44, 39, 201, 43, 5 }; +static BYTE bMagicCubeIdx = 0; + +const char * stristr(const char * big, const char * little) +{ + const char * t = big; + size_t len = strlen(little) - 1; + + for (t = big; *t; ++t) + if (!_strnicmp(t, little, len)) + return t; + + return NULL; +} + +bool GetProcessInformation(std::string & exeFileName, LPCVOID * ppvAddress) +{ + HANDLE hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId()); + if (hModuleSnap != INVALID_HANDLE_VALUE) + { + std::string filename; + + GetExcutedFileName(filename); + + MODULEENTRY32 me32; + memset(&me32, 0, sizeof(me32)); + me32.dwSize = sizeof(MODULEENTRY32); + + BOOL bRet = Module32First(hModuleSnap, &me32); + + while (bRet) + { + if (stristr(me32.szExePath, filename.c_str())) + { + exeFileName = me32.szExePath; + *ppvAddress = me32.modBaseAddr; + CloseHandle(hModuleSnap); + return true; + } + + ZeroMemory(&me32, sizeof(MODULEENTRY32)); + me32.dwSize = sizeof(MODULEENTRY32); + + bRet = Module32Next(hModuleSnap, &me32); + } + + CloseHandle(hModuleSnap); + } + + return false; +} + +DWORD GetProcessMemoryCRC(LPCVOID c_pvBaseAddress) +{ + HANDLE hProcess = GetCurrentProcess(); + char * pBuf = new char[1024*1024]; + DWORD dwBytesRead; + + BOOL bRet = ReadProcessMemory(hProcess, c_pvBaseAddress, pBuf, 1024*1024, &dwBytesRead); + + if (!bRet && GetLastError() == ERROR_PARTIAL_COPY) + bRet = true; + + if (bRet) + { + DWORD dwCRC = GetCRC32(pBuf, dwBytesRead); + delete [] pBuf; + return dwCRC; + } + + delete [] pBuf; + return 0; +} + +bool __GetExeCRC(DWORD & r_dwProcCRC, DWORD & r_dwFileCRC) +{ + std::string exeFileName; + LPCVOID c_pvBaseAddress; + + GetExcutedFileName(exeFileName); + + if (GetProcessInformation(exeFileName, &c_pvBaseAddress)) + r_dwProcCRC = GetProcessMemoryCRC(c_pvBaseAddress); + else + r_dwProcCRC = 0; + + r_dwFileCRC = GetFileCRC32(exeFileName.c_str()); + return true; +} + +void BuildProcessCRC() +{ + if (LocaleService_IsHONGKONG() || LocaleService_IsTAIWAN()) + { + memset(abCRCMagicCube, 0, sizeof(abCRCMagicCube)); + bMagicCubeIdx = 0; + return; + } + + DWORD dwProcCRC, dwFileCRC; + + if (__GetExeCRC(dwProcCRC, dwFileCRC)) + { + abCRCMagicCube[0] = BYTE(dwProcCRC & 0x000000ff); + abCRCMagicCube[1] = BYTE(dwFileCRC & 0x000000ff); + abCRCMagicCube[2] = BYTE( (dwProcCRC & 0x0000ff00) >> 8 ); + abCRCMagicCube[3] = BYTE( (dwFileCRC & 0x0000ff00) >> 8 ); + abCRCMagicCube[4] = BYTE( (dwProcCRC & 0x00ff0000) >> 16 ); + abCRCMagicCube[5] = BYTE( (dwFileCRC & 0x00ff0000) >> 16 ); + abCRCMagicCube[6] = BYTE( (dwProcCRC & 0xff000000) >> 24 ); + abCRCMagicCube[7] = BYTE( (dwFileCRC & 0xff000000) >> 24 ); + + bMagicCubeIdx = 0; + } +} + +BYTE GetProcessCRCMagicCubePiece() +{ + BYTE bPiece = BYTE(abCRCMagicCube[bMagicCubeIdx] ^ abCRCXorTable[bMagicCubeIdx]); + + if (!(++bMagicCubeIdx & 7)) + bMagicCubeIdx = 0; + + return bPiece; +} diff --git a/source/UserInterface/ProcessCRC.h b/source/UserInterface/ProcessCRC.h new file mode 100644 index 0000000..09faeba --- /dev/null +++ b/source/UserInterface/ProcessCRC.h @@ -0,0 +1,6 @@ +#pragma once + +extern bool GetExeCRC(DWORD & r_dwProcCRC, DWORD & r_dwFileCRC); + +extern void BuildProcessCRC(); +extern BYTE GetProcessCRCMagicCubePiece(); diff --git a/source/UserInterface/ProcessScanner.cpp b/source/UserInterface/ProcessScanner.cpp new file mode 100644 index 0000000..642e74b --- /dev/null +++ b/source/UserInterface/ProcessScanner.cpp @@ -0,0 +1,142 @@ +#include "StdAfx.h" +#include "ProcessScanner.h" + +#include + +static std::vector gs_kVct_crcPair; +static CRITICAL_SECTION gs_csData; +static HANDLE gs_evReqExit=NULL; +static HANDLE gs_evResExit=NULL; +static HANDLE gs_hThread=NULL; + +void ScanProcessList(std::map& rkMap_crcProc, std::vector* pkVct_crcPair) +{ + SYSTEM_INFO si; + memset(&si, 0, sizeof(si)); + GetSystemInfo(&si); + + PROCESSENTRY32 pro; + pro.dwSize = sizeof(PROCESSENTRY32); + + LPPROCESSENTRY32 Entry; + Entry = &pro; + + HANDLE process = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); + + BOOL bOK = Process32First(process, Entry); + + while(bOK) + { + HANDLE hProc = OpenProcess(PROCESS_VM_READ, FALSE, Entry->th32ProcessID); + if (hProc) + { + HANDLE hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, Entry->th32ProcessID); + if (hModuleSnap != INVALID_HANDLE_VALUE) + { + MODULEENTRY32 me32; + memset(&me32, 0, sizeof(me32)); + me32.dwSize = sizeof(MODULEENTRY32); + + BOOL bRet = Module32First(hModuleSnap, &me32); + while (bRet) + { + DWORD crcExtPath=GetCRC32((const char*)me32.szExePath, strlen(me32.szExePath)); + + std::map::iterator f=rkMap_crcProc.find(crcExtPath); + if (rkMap_crcProc.end()==f) + { + DWORD crcProc=GetFileCRC32(me32.szExePath); + rkMap_crcProc.insert(std::make_pair(crcExtPath, crcProc)); + pkVct_crcPair->push_back(std::make_pair(crcProc, (const char*)me32.szExePath)); + } + Sleep(1); + + ZeroMemory(&me32, sizeof(MODULEENTRY32)); + me32.dwSize = sizeof(MODULEENTRY32); + bRet = Module32Next(hModuleSnap, &me32); + } + + CloseHandle(hModuleSnap); + } + + CloseHandle(hProc); + } + + + bOK = Process32Next(process, Entry); + } + CloseHandle(process); +} + +void ProcessScanner_ReleaseQuitEvent() +{ + SetEvent(gs_evReqExit); +} + +void ProcessScanner_Destroy() +{ + ProcessScanner_ReleaseQuitEvent(); + + WaitForSingleObject(gs_evResExit, INFINITE); + CloseHandle(gs_evReqExit); + CloseHandle(gs_evResExit); + DeleteCriticalSection(&gs_csData); +} + +bool ProcessScanner_PopProcessQueue(std::vector* pkVct_crcPair) +{ + EnterCriticalSection(&gs_csData); + *pkVct_crcPair=gs_kVct_crcPair; + gs_kVct_crcPair.clear(); + LeaveCriticalSection(&gs_csData); + + if (pkVct_crcPair->empty()) + return false; + + return true; +} + +void ProcessScanner_Thread(void* pv) +{ + DWORD dwDelay=(rand()%10)*1000+1000*10; + + std::map kMap_crcProc; + std::vector kVct_crcPair; + + while (WAIT_OBJECT_0 != WaitForSingleObject(gs_evReqExit, dwDelay)) + { + kVct_crcPair.clear(); + ScanProcessList(kMap_crcProc, &kVct_crcPair); + + EnterCriticalSection(&gs_csData); + gs_kVct_crcPair.insert(gs_kVct_crcPair.end(), kVct_crcPair.begin(), kVct_crcPair.end()); + LeaveCriticalSection(&gs_csData); + + dwDelay=(rand()%10)*1000+1000; + } + + SetEvent(gs_evResExit); +} + + +bool ProcessScanner_Create() +{ + InitializeCriticalSection(&gs_csData); + gs_evReqExit=CreateEvent(NULL, FALSE, FALSE, "ProcessScanner_ReqExit"); + gs_evResExit=CreateEvent(NULL, FALSE, FALSE, "ProcessScanner_ResExit"); + + gs_hThread=(HANDLE)_beginthread(ProcessScanner_Thread, 64*1024, NULL); + if (INVALID_HANDLE_VALUE==gs_hThread) + { + LogBox("CreateThread Error"); + return false; + } + + if (!SetThreadPriority(gs_hThread, THREAD_PRIORITY_LOWEST)) + { + LogBox("SetThreadPriority Error"); + return false; + } + + return true; +} diff --git a/source/UserInterface/ProcessScanner.h b/source/UserInterface/ProcessScanner.h new file mode 100644 index 0000000..8f4dc95 --- /dev/null +++ b/source/UserInterface/ProcessScanner.h @@ -0,0 +1,9 @@ +#pragma once + +typedef std::pair CRCPair; + +void ProcessScanner_Destroy(); +bool ProcessScanner_Create(); +void ProcessScanner_ReleaseQuitEvent(); + +bool ProcessScanner_PopProcessQueue(std::vector* pkVct_crcPair); \ No newline at end of file diff --git a/source/UserInterface/PythonApplication.cpp b/source/UserInterface/PythonApplication.cpp new file mode 100644 index 0000000..7661731 --- /dev/null +++ b/source/UserInterface/PythonApplication.cpp @@ -0,0 +1,1459 @@ +#include "StdAfx.h" +#include "../eterBase/Error.h" +#include "../eterlib/Camera.h" +#include "../eterlib/AttributeInstance.h" +#include "../gamelib/AreaTerrain.h" +#include "../EterGrnLib/Material.h" +#include "../CWebBrowser/CWebBrowser.h" + +#include "resource.h" +#include "PythonApplication.h" +#include "PythonCharacterManager.h" + +#include "ProcessScanner.h" + +#include "HackShield.h" +#include "NProtectGameGuard.h" +#include "WiseLogicXTrap.h" +#include "CheckLatestFiles.h" + +extern void GrannyCreateSharedDeformBuffer(); +extern void GrannyDestroySharedDeformBuffer(); + +float MIN_FOG = 2400.0f; +double g_specularSpd=0.007f; + +CPythonApplication * CPythonApplication::ms_pInstance; + +float c_fDefaultCameraRotateSpeed = 1.5f; +float c_fDefaultCameraPitchSpeed = 1.5f; +float c_fDefaultCameraZoomSpeed = 0.05f; + +CPythonApplication::CPythonApplication() : +m_bCursorVisible(TRUE), +m_bLiarCursorOn(false), +m_iCursorMode(CURSOR_MODE_HARDWARE), +m_isWindowed(false), +m_isFrameSkipDisable(false), +m_poMouseHandler(NULL), +m_dwUpdateFPS(0), +m_dwRenderFPS(0), +m_fAveRenderTime(0.0f), +m_dwFaceCount(0), +m_fGlobalTime(0.0f), +m_fGlobalElapsedTime(0.0f), +m_dwLButtonDownTime(0), +m_dwLastIdleTime(0) +{ +#ifndef _DEBUG + SetEterExceptionHandler(); +#endif + + CTimer::Instance().UseCustomTime(); + m_dwWidth = 800; + m_dwHeight = 600; + + ms_pInstance = this; + m_isWindowFullScreenEnable = FALSE; + + m_v3CenterPosition = D3DXVECTOR3(0.0f, 0.0f, 0.0f); + m_dwStartLocalTime = ELTimer_GetMSec(); + m_tServerTime = 0; + m_tLocalStartTime = 0; + + m_iPort = 0; + m_iFPS = 60; + + m_isActivateWnd = false; + m_isMinimizedWnd = true; + + m_fRotationSpeed = 0.0f; + m_fPitchSpeed = 0.0f; + m_fZoomSpeed = 0.0f; + + m_fFaceSpd=0.0f; + + m_dwFaceAccCount=0; + m_dwFaceAccTime=0; + + m_dwFaceSpdSum=0; + m_dwFaceSpdCount=0; + + m_FlyingManager.SetMapManagerPtr(&m_pyBackground); + + m_iCursorNum = CURSOR_SHAPE_NORMAL; + m_iContinuousCursorNum = CURSOR_SHAPE_NORMAL; + + m_isSpecialCameraMode = FALSE; + m_fCameraRotateSpeed = c_fDefaultCameraRotateSpeed; + m_fCameraPitchSpeed = c_fDefaultCameraPitchSpeed; + m_fCameraZoomSpeed = c_fDefaultCameraZoomSpeed; + + m_iCameraMode = CAMERA_MODE_NORMAL; + m_fBlendCameraStartTime = 0.0f; + m_fBlendCameraBlendTime = 0.0f; + + m_iForceSightRange = -1; + + CCameraManager::Instance().AddCamera(EVENT_CAMERA_NUMBER); +} + +CPythonApplication::~CPythonApplication() +{ +} + +void CPythonApplication::GetMousePosition(POINT* ppt) +{ + CMSApplication::GetMousePosition(ppt); +} + +void CPythonApplication::SetMinFog(float fMinFog) +{ + MIN_FOG = fMinFog; +} + +void CPythonApplication::SetFrameSkip(bool isEnable) +{ + if (isEnable) + m_isFrameSkipDisable=false; + else + m_isFrameSkipDisable=true; +} + +void CPythonApplication::NotifyHack(const char* c_szFormat, ...) +{ + char szBuf[1024]; + + va_list args; + va_start(args, c_szFormat); + _vsnprintf(szBuf, sizeof(szBuf), c_szFormat, args); + va_end(args); + m_pyNetworkStream.NotifyHack(szBuf); +} + +void CPythonApplication::GetInfo(UINT eInfo, std::string* pstInfo) +{ + switch (eInfo) + { + case INFO_ACTOR: + m_kChrMgr.GetInfo(pstInfo); + break; + case INFO_EFFECT: + m_kEftMgr.GetInfo(pstInfo); + break; + case INFO_ITEM: + m_pyItem.GetInfo(pstInfo); + break; + case INFO_TEXTTAIL: + m_pyTextTail.GetInfo(pstInfo); + break; + } +} + +void CPythonApplication::Abort() +{ + TraceError("============================================================================================================"); + TraceError("Abort!!!!\n\n"); + + PostQuitMessage(0); +} + +void CPythonApplication::Exit() +{ + PostQuitMessage(0); +} + +bool PERF_CHECKER_RENDER_GAME = false; + +void CPythonApplication::RenderGame() +{ + if (!PERF_CHECKER_RENDER_GAME) + { + float fAspect=m_kWndMgr.GetAspect(); + float fFarClip=m_pyBackground.GetFarClip(); + + m_pyGraphic.SetPerspective(30.0f, fAspect, 100.0, fFarClip); + + CCullingManager::Instance().Process(); + + m_kChrMgr.Deform(); + m_kEftMgr.Update(); + + m_pyBackground.RenderCharacterShadowToTexture(); + + m_pyGraphic.SetGameRenderState(); + m_pyGraphic.PushState(); + + { + long lx, ly; + m_kWndMgr.GetMousePosition(lx, ly); + m_pyGraphic.SetCursorPosition(lx, ly); + } + + m_pyBackground.RenderSky(); + + m_pyBackground.RenderBeforeLensFlare(); + + m_pyBackground.RenderCloud(); + + m_pyBackground.BeginEnvironment(); + m_pyBackground.Render(); + + m_pyBackground.SetCharacterDirLight(); + m_kChrMgr.Render(); + + m_pyBackground.SetBackgroundDirLight(); + m_pyBackground.RenderWater(); + m_pyBackground.RenderSnow(); + m_pyBackground.RenderEffect(); + + m_pyBackground.EndEnvironment(); + + m_kEftMgr.Render(); + m_pyItem.Render(); + m_FlyingManager.Render(); + + m_pyBackground.BeginEnvironment(); + m_pyBackground.RenderPCBlocker(); + m_pyBackground.EndEnvironment(); + + m_pyBackground.RenderAfterLensFlare(); + + return; + } + + //if (GetAsyncKeyState(VK_Z)) + // STATEMANAGER.SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); + + DWORD t1=ELTimer_GetMSec(); + m_kChrMgr.Deform(); + DWORD t2=ELTimer_GetMSec(); + m_kEftMgr.Update(); + DWORD t3=ELTimer_GetMSec(); + m_pyBackground.RenderCharacterShadowToTexture(); + DWORD t4=ELTimer_GetMSec(); + + m_pyGraphic.SetGameRenderState(); + m_pyGraphic.PushState(); + + float fAspect=m_kWndMgr.GetAspect(); + float fFarClip=m_pyBackground.GetFarClip(); + + m_pyGraphic.SetPerspective(30.0f, fAspect, 100.0, fFarClip); + + DWORD t5=ELTimer_GetMSec(); + + CCullingManager::Instance().Process(); + + DWORD t6=ELTimer_GetMSec(); + + { + long lx, ly; + m_kWndMgr.GetMousePosition(lx, ly); + m_pyGraphic.SetCursorPosition(lx, ly); + } + + m_pyBackground.RenderSky(); + DWORD t7=ELTimer_GetMSec(); + m_pyBackground.RenderBeforeLensFlare(); + DWORD t8=ELTimer_GetMSec(); + m_pyBackground.RenderCloud(); + DWORD t9=ELTimer_GetMSec(); + m_pyBackground.BeginEnvironment(); + m_pyBackground.Render(); + + m_pyBackground.SetCharacterDirLight(); + DWORD t10=ELTimer_GetMSec(); + m_kChrMgr.Render(); + DWORD t11=ELTimer_GetMSec(); + + m_pyBackground.SetBackgroundDirLight(); + m_pyBackground.RenderWater(); + DWORD t12=ELTimer_GetMSec(); + m_pyBackground.RenderEffect(); + DWORD t13=ELTimer_GetMSec(); + m_pyBackground.EndEnvironment(); + m_kEftMgr.Render(); + DWORD t14=ELTimer_GetMSec(); + m_pyItem.Render(); + DWORD t15=ELTimer_GetMSec(); + m_FlyingManager.Render(); + DWORD t16=ELTimer_GetMSec(); + m_pyBackground.BeginEnvironment(); + m_pyBackground.RenderPCBlocker(); + m_pyBackground.EndEnvironment(); + DWORD t17=ELTimer_GetMSec(); + m_pyBackground.RenderAfterLensFlare(); + DWORD t18=ELTimer_GetMSec(); + DWORD tEnd=ELTimer_GetMSec(); + + if (GetAsyncKeyState(VK_Z)) + STATEMANAGER.SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + + if (tEnd-t1<3) + return; + + static FILE* fp=fopen("perf_game_render.txt", "w"); + + fprintf(fp, "GR.Total %d (Time %d)\n", tEnd-t1, ELTimer_GetMSec()); + fprintf(fp, "GR.DFM %d\n", t2-t1); + fprintf(fp, "GR.EFT.UP %d\n", t3-t2); + fprintf(fp, "GR.SHW %d\n", t4-t3); + fprintf(fp, "GR.STT %d\n", t5-t4); + fprintf(fp, "GR.CLL %d\n", t6-t5); + fprintf(fp, "GR.BG.SKY %d\n", t7-t6); + fprintf(fp, "GR.BG.LEN %d\n", t8-t7); + fprintf(fp, "GR.BG.CLD %d\n", t9-t8); + fprintf(fp, "GR.BG.MAIN %d\n", t10-t9); + fprintf(fp, "GR.CHR %d\n", t11-t10); + fprintf(fp, "GR.BG.WTR %d\n", t12-t11); + fprintf(fp, "GR.BG.EFT %d\n", t13-t12); + fprintf(fp, "GR.EFT %d\n", t14-t13); + fprintf(fp, "GR.ITM %d\n", t15-t14); + fprintf(fp, "GR.FLY %d\n", t16-t15); + fprintf(fp, "GR.BG.BLK %d\n", t17-t16); + fprintf(fp, "GR.BG.LEN %d\n", t18-t17); + + + fflush(fp); +} + +void CPythonApplication::UpdateGame() +{ + DWORD t1=ELTimer_GetMSec(); + POINT ptMouse; + GetMousePosition(&ptMouse); + + CGraphicTextInstance::Hyperlink_UpdateMousePos(ptMouse.x, ptMouse.y); + + DWORD t2=ELTimer_GetMSec(); + + //!@# Alt+Tab SetTransfor ƨ ذ - [levites] + //if (m_isActivateWnd) + { + CScreen s; + float fAspect = UI::CWindowManager::Instance().GetAspect(); + float fFarClip = CPythonBackground::Instance().GetFarClip(); + + s.SetPerspective(30.0f,fAspect, 100.0f, fFarClip); + s.BuildViewFrustum(); + } + + DWORD t3=ELTimer_GetMSec(); + TPixelPosition kPPosMainActor; + m_pyPlayer.NEW_GetMainActorPosition(&kPPosMainActor); + + DWORD t4=ELTimer_GetMSec(); + m_pyBackground.Update(kPPosMainActor.x, kPPosMainActor.y, kPPosMainActor.z); + + DWORD t5=ELTimer_GetMSec(); + m_GameEventManager.SetCenterPosition(kPPosMainActor.x, kPPosMainActor.y, kPPosMainActor.z); + m_GameEventManager.Update(); + + DWORD t6=ELTimer_GetMSec(); + m_kChrMgr.Update(); + DWORD t7=ELTimer_GetMSec(); + m_kEftMgr.UpdateSound(); + DWORD t8=ELTimer_GetMSec(); + m_FlyingManager.Update(); + DWORD t9=ELTimer_GetMSec(); + m_pyItem.Update(ptMouse); + DWORD t10=ELTimer_GetMSec(); + m_pyPlayer.Update(); + DWORD t11=ELTimer_GetMSec(); + + // NOTE : Update ġ ٲǷ ٽ ɴϴ - [levites] + // κ ɸ Sound ġ ÷ Ǵ ־. + m_pyPlayer.NEW_GetMainActorPosition(&kPPosMainActor); + SetCenterPosition(kPPosMainActor.x, kPPosMainActor.y, kPPosMainActor.z); + DWORD t12=ELTimer_GetMSec(); + + if (PERF_CHECKER_RENDER_GAME) + { + if (t12-t1>5) + { + static FILE* fp=fopen("perf_game_update.txt", "w"); + + fprintf(fp, "GU.Total %d (Time %d)\n", t12-t1, ELTimer_GetMSec()); + fprintf(fp, "GU.GMP %d\n", t2-t1); + fprintf(fp, "GU.SCR %d\n", t3-t2); + fprintf(fp, "GU.MPS %d\n", t4-t3); + fprintf(fp, "GU.BG %d\n", t5-t4); + fprintf(fp, "GU.GEM %d\n", t6-t5); + fprintf(fp, "GU.CHR %d\n", t7-t6); + fprintf(fp, "GU.EFT %d\n", t8-t7); + fprintf(fp, "GU.FLY %d\n", t9-t8); + fprintf(fp, "GU.ITM %d\n", t10-t9); + fprintf(fp, "GU.PLR %d\n", t11-t10); + fprintf(fp, "GU.POS %d\n", t12-t11); + fflush(fp); + } + } +} + +void CPythonApplication::SkipRenderBuffering(DWORD dwSleepMSec) +{ + m_dwBufSleepSkipTime=ELTimer_GetMSec()+dwSleepMSec; +} + +bool CPythonApplication::Process() +{ +#if defined(CHECK_LATEST_DATA_FILES) + if (CheckLatestFiles_PollEvent()) + return false; +#endif +#ifdef USE_AHNLAB_HACKSHIELD + if (HackShield_PollEvent()) + return false; +#endif +#ifdef XTRAP_CLIENT_ENABLE + XTrap_PollEvent(); +#endif + ELTimer_SetFrameMSec(); + + // m_Profiler.Clear(); + DWORD dwStart = ELTimer_GetMSec(); + + /////////////////////////////////////////////////////////////////////////////////////////////////// + static DWORD s_dwUpdateFrameCount = 0; + static DWORD s_dwRenderFrameCount = 0; + static DWORD s_dwFaceCount = 0; + static UINT s_uiLoad = 0; + static DWORD s_dwCheckTime = ELTimer_GetMSec(); + + if (ELTimer_GetMSec() - s_dwCheckTime > 1000) + { + m_dwUpdateFPS = s_dwUpdateFrameCount; + m_dwRenderFPS = s_dwRenderFrameCount; + m_dwLoad = s_uiLoad; + + m_dwFaceCount = s_dwFaceCount / max(1, s_dwRenderFrameCount); + + s_dwCheckTime = ELTimer_GetMSec(); + + s_uiLoad = s_dwFaceCount = s_dwUpdateFrameCount = s_dwRenderFrameCount = 0; + } + + // Update Time + static BOOL s_bFrameSkip = false; + static UINT s_uiNextFrameTime = ELTimer_GetMSec(); + +#ifdef __PERFORMANCE_CHECK__ + DWORD dwUpdateTime1=ELTimer_GetMSec(); +#endif + CTimer& rkTimer=CTimer::Instance(); + rkTimer.Advance(); + + m_fGlobalTime = rkTimer.GetCurrentSecond(); + m_fGlobalElapsedTime = rkTimer.GetElapsedSecond(); + + UINT uiFrameTime = rkTimer.GetElapsedMilliecond(); + s_uiNextFrameTime += uiFrameTime; //17 - 1ʴ 60fps. + + DWORD updatestart = ELTimer_GetMSec(); +#ifdef __PERFORMANCE_CHECK__ + DWORD dwUpdateTime2=ELTimer_GetMSec(); +#endif + // Network I/O + m_pyNetworkStream.Process(); + //m_pyNetworkDatagram.Process(); + + m_kGuildMarkUploader.Process(); + +#ifdef USE_NPROTECT_GAMEGUARD + if (GameGuard_IsError()) + return false; +#endif + + m_kGuildMarkDownloader.Process(); + m_kAccountConnector.Process(); + +#ifdef __PERFORMANCE_CHECK__ + DWORD dwUpdateTime3=ELTimer_GetMSec(); +#endif + ////////////////////// + // Input Process + // Keyboard + UpdateKeyboard(); +#ifdef __PERFORMANCE_CHECK__ + DWORD dwUpdateTime4=ELTimer_GetMSec(); +#endif + // Mouse + POINT Point; + if (GetCursorPos(&Point)) + { + ScreenToClient(m_hWnd, &Point); + OnMouseMove(Point.x, Point.y); + } + ////////////////////// +#ifdef __PERFORMANCE_CHECK__ + DWORD dwUpdateTime5=ELTimer_GetMSec(); +#endif + //!@# Alt+Tab SetTransfor ƨ ذ - [levites] + //if (m_isActivateWnd) + __UpdateCamera(); +#ifdef __PERFORMANCE_CHECK__ + DWORD dwUpdateTime6=ELTimer_GetMSec(); +#endif + // Update Game Playing + CResourceManager::Instance().Update(); +#ifdef __PERFORMANCE_CHECK__ + DWORD dwUpdateTime7=ELTimer_GetMSec(); +#endif + OnCameraUpdate(); +#ifdef __PERFORMANCE_CHECK__ + DWORD dwUpdateTime8=ELTimer_GetMSec(); +#endif + OnMouseUpdate(); +#ifdef __PERFORMANCE_CHECK__ + DWORD dwUpdateTime9=ELTimer_GetMSec(); +#endif + OnUIUpdate(); + +#ifdef __PERFORMANCE_CHECK__ + DWORD dwUpdateTime10=ELTimer_GetMSec(); + + if (dwUpdateTime10-dwUpdateTime1>10) + { + static FILE* fp=fopen("perf_app_update.txt", "w"); + + fprintf(fp, "AU.Total %d (Time %d)\n", dwUpdateTime9-dwUpdateTime1, ELTimer_GetMSec()); + fprintf(fp, "AU.TU %d\n", dwUpdateTime2-dwUpdateTime1); + fprintf(fp, "AU.NU %d\n", dwUpdateTime3-dwUpdateTime2); + fprintf(fp, "AU.KU %d\n", dwUpdateTime4-dwUpdateTime3); + fprintf(fp, "AU.MP %d\n", dwUpdateTime5-dwUpdateTime4); + fprintf(fp, "AU.CP %d\n", dwUpdateTime6-dwUpdateTime5); + fprintf(fp, "AU.RU %d\n", dwUpdateTime7-dwUpdateTime6); + fprintf(fp, "AU.CU %d\n", dwUpdateTime8-dwUpdateTime7); + fprintf(fp, "AU.MU %d\n", dwUpdateTime9-dwUpdateTime8); + fprintf(fp, "AU.UU %d\n", dwUpdateTime10-dwUpdateTime9); + fprintf(fp, "----------------------------------\n"); + fflush(fp); + } +#endif + + //Updateϴµ ɸð.delta + m_dwCurUpdateTime = ELTimer_GetMSec() - updatestart; + + DWORD dwCurrentTime = ELTimer_GetMSec(); + BOOL bCurrentLateUpdate = FALSE; + + s_bFrameSkip = false; + + if (dwCurrentTime > s_uiNextFrameTime) + { + int dt = dwCurrentTime - s_uiNextFrameTime; + int nAdjustTime = ((float)dt / (float)uiFrameTime) * uiFrameTime; + + if ( dt >= 500 ) + { + s_uiNextFrameTime += nAdjustTime; + printf("FrameSkip %d\n",nAdjustTime); + CTimer::Instance().Adjust(nAdjustTime); + } + + s_bFrameSkip = true; + bCurrentLateUpdate = TRUE; + } + + //s_bFrameSkip = false; + + //if (dwCurrentTime > s_uiNextFrameTime) + //{ + // int dt = dwCurrentTime - s_uiNextFrameTime; + + // //ʹ ʾ ´. + // //׸ m_dwCurUpdateTime deltaε delta absolute time̶ ϸ ¼ڴ°? + // //if (dt >= 500 || m_dwCurUpdateTime > s_uiNextFrameTime) + + // //ڵ ϸ 0.5 ̳ · update ӵǸ rendering frame skip߻ + // if (dt >= 500 || m_dwCurUpdateTime > s_uiNextFrameTime) + // { + // s_uiNextFrameTime += dt / uiFrameTime * uiFrameTime; + // printf("FrameSkip %d\n", dt / uiFrameTime * uiFrameTime); + // CTimer::Instance().Adjust((dt / uiFrameTime) * uiFrameTime); + // s_bFrameSkip = true; + // } + //} + + if (m_isFrameSkipDisable) + s_bFrameSkip = false; + +#ifdef __VTUNE__ + s_bFrameSkip = false; +#endif + /* + static bool s_isPrevFrameSkip=false; + static DWORD s_dwFrameSkipCount=0; + static DWORD s_dwFrameSkipEndTime=0; + + static DWORD ERROR_FRAME_SKIP_COUNT = 60*5; + static DWORD ERROR_FRAME_SKIP_TIME = ERROR_FRAME_SKIP_COUNT*18; + + //static DWORD MAX_FRAME_SKIP=0; + + if (IsActive()) + { + DWORD dwFrameSkipCurTime=ELTimer_GetMSec(); + + if (s_bFrameSkip) + { + // ӵ ŵ̶.. + if (s_isPrevFrameSkip) + { + if (s_dwFrameSkipEndTime==0) + { + s_dwFrameSkipCount=0; // üũ ε + s_dwFrameSkipEndTime=dwFrameSkipCurTime+ERROR_FRAME_SKIP_TIME; // ð üũ ε ŵ üũ + + //printf("FrameSkipCheck Start\n"); + } + ++s_dwFrameSkipCount; + + //if (MAX_FRAME_SKIPERROR_FRAME_SKIP_COUNT && s_dwFrameSkipEndTime1000) + { + m_fAveRenderTime=float(double(s_dwRenderRangeTime)/double(s_dwRenderRangeFrame)); + + s_dwRenderCheckTime=ELTimer_GetMSec(); + s_dwRenderRangeTime=0; + s_dwRenderRangeFrame=0; + } + + DWORD dwCurFaceCount=m_pyGraphic.GetFaceCount(); + m_pyGraphic.ResetFaceCount(); + s_dwFaceCount += dwCurFaceCount; + + if (dwCurFaceCount > 5000) + { + // ó + if (dwRenderEndTime > m_dwBufSleepSkipTime) + { + static float s_fBufRenderTime = 0.0f; + + float fCurRenderTime = m_dwCurRenderTime; + + if (fCurRenderTime > s_fBufRenderTime) + { + float fRatio = fMAX(0.5f, (fCurRenderTime - s_fBufRenderTime) / 30.0f); + s_fBufRenderTime = (s_fBufRenderTime * (100.0f - fRatio) + (fCurRenderTime + 5) * fRatio) / 100.0f; + } + else + { + float fRatio = 0.5f; + s_fBufRenderTime = (s_fBufRenderTime * (100.0f - fRatio) + fCurRenderTime * fRatio) / 100.0f; + } + + // Ѱġ Ѵ + if (s_fBufRenderTime > 100.0f) + s_fBufRenderTime = 100.0f; + + DWORD dwBufRenderTime = s_fBufRenderTime; + + if (m_isWindowed) + { + if (dwBufRenderTime>58) + dwBufRenderTime=64; + else if (dwBufRenderTime>42) + dwBufRenderTime=48; + else if (dwBufRenderTime>26) + dwBufRenderTime=32; + else if (dwBufRenderTime>10) + dwBufRenderTime=16; + else + dwBufRenderTime=8; + } + + // ӵ ߾ִʿ ϴ + // Ʒ ѹ ϸ ? + //if (m_dwCurRenderTime 0 && !bCurrentLateUpdate ) + { + s_uiLoad -= rest; // ð ε忡 .. + Sleep(rest); + } + + ++s_dwUpdateFrameCount; + + s_uiLoad += ELTimer_GetMSec() - dwStart; + //m_Profiler.ProfileByScreen(); + return true; +} + +void CPythonApplication::UpdateClientRect() +{ + RECT rcApp; + GetClientRect(&rcApp); + OnSizeChange(rcApp.right - rcApp.left, rcApp.bottom - rcApp.top); +} + +void CPythonApplication::SetMouseHandler(PyObject* poMouseHandler) +{ + m_poMouseHandler = poMouseHandler; +} + +int CPythonApplication::CheckDeviceState() +{ + CGraphicDevice::EDeviceState e_deviceState = m_grpDevice.GetDeviceState(); + + switch (e_deviceState) + { + // ̽ α׷ Ǿ Ѵ. + case CGraphicDevice::DEVICESTATE_NULL: + return DEVICE_STATE_FALSE; + + // DEVICESTATE_BROKEN ֵ Ѵ. + // ׳ DrawPrimitive ϸ α׷ . + case CGraphicDevice::DEVICESTATE_BROKEN: + return DEVICE_STATE_SKIP; + + case CGraphicDevice::DEVICESTATE_NEEDS_RESET: + if (!m_grpDevice.Reset()) + return DEVICE_STATE_SKIP; + + break; + } + + return DEVICE_STATE_OK; +} + +bool CPythonApplication::CreateDevice(int width, int height, int Windowed, int bit /* = 32*/, int frequency /* = 0*/) +{ + int iRet; + + m_grpDevice.InitBackBufferCount(2); + m_grpDevice.RegisterWarningString(CGraphicDevice::CREATE_BAD_DRIVER, ApplicationStringTable_GetStringz(IDS_WARN_BAD_DRIVER, "WARN_BAD_DRIVER")); + m_grpDevice.RegisterWarningString(CGraphicDevice::CREATE_NO_TNL, ApplicationStringTable_GetStringz(IDS_WARN_NO_TNL, "WARN_NO_TNL")); + + iRet = m_grpDevice.Create(GetWindowHandle(), width, height, Windowed ? true : false, bit,frequency); + + switch (iRet) + { + case CGraphicDevice::CREATE_OK: + return true; + + case CGraphicDevice::CREATE_REFRESHRATE: + return true; + + case CGraphicDevice::CREATE_ENUM: + case CGraphicDevice::CREATE_DETECT: + SET_EXCEPTION(CREATE_NO_APPROPRIATE_DEVICE); + TraceError("CreateDevice: Enum & Detect failed"); + return false; + + case CGraphicDevice::CREATE_NO_DIRECTX: + //PyErr_SetString(PyExc_RuntimeError, "DirectX 8.1 or greater required to run game"); + SET_EXCEPTION(CREATE_NO_DIRECTX); + TraceError("CreateDevice: DirectX 8.1 or greater required to run game"); + return false; + + case CGraphicDevice::CREATE_DEVICE: + //PyErr_SetString(PyExc_RuntimeError, "GraphicDevice create failed"); + SET_EXCEPTION(CREATE_DEVICE); + TraceError("CreateDevice: GraphicDevice create failed"); + return false; + + case CGraphicDevice::CREATE_FORMAT: + SET_EXCEPTION(CREATE_FORMAT); + TraceError("CreateDevice: Change the screen format"); + return false; + + /*case CGraphicDevice::CREATE_GET_ADAPTER_DISPLAY_MODE: + //PyErr_SetString(PyExc_RuntimeError, "GetAdapterDisplayMode failed"); + SET_EXCEPTION(CREATE_GET_ADAPTER_DISPLAY_MODE); + TraceError("CreateDevice: GetAdapterDisplayMode failed"); + return false;*/ + + case CGraphicDevice::CREATE_GET_DEVICE_CAPS: + PyErr_SetString(PyExc_RuntimeError, "GetDevCaps failed"); + TraceError("CreateDevice: GetDevCaps failed"); + return false; + + case CGraphicDevice::CREATE_GET_DEVICE_CAPS2: + PyErr_SetString(PyExc_RuntimeError, "GetDevCaps2 failed"); + TraceError("CreateDevice: GetDevCaps2 failed"); + return false; + + default: + if (iRet & CGraphicDevice::CREATE_OK) + { + //if (iRet & CGraphicDevice::CREATE_BAD_DRIVER) + //{ + // LogBox(ApplicationStringTable_GetStringz(IDS_WARN_BAD_DRIVER), NULL, GetWindowHandle()); + //} + if (iRet & CGraphicDevice::CREATE_NO_TNL) + { + CGrannyLODController::SetMinLODMode(true); + //LogBox(ApplicationStringTable_GetStringz(IDS_WARN_NO_TNL), NULL, GetWindowHandle()); + } + return true; + } + + //PyErr_SetString(PyExc_RuntimeError, "Unknown Error!"); + SET_EXCEPTION(UNKNOWN_ERROR); + TraceError("CreateDevice: Unknown Error!"); + return false; + } +} + +void CPythonApplication::Loop() +{ + while (1) + { + if (IsMessage()) + { + if (!MessageProcess()) + break; + } + else + { + if (!Process()) + break; + + m_dwLastIdleTime=ELTimer_GetMSec(); + } + } +} + +// SUPPORT_NEW_KOREA_SERVER +bool LoadLocaleData(const char* localePath) +{ + NANOBEGIN + CPythonNonPlayer& rkNPCMgr = CPythonNonPlayer::Instance(); + CItemManager& rkItemMgr = CItemManager::Instance(); + CPythonSkill& rkSkillMgr = CPythonSkill::Instance(); + CPythonNetworkStream& rkNetStream = CPythonNetworkStream::Instance(); + + char szItemList[256]; + char szItemProto[256]; + char szItemDesc[256]; + char szMobProto[256]; + char szSkillDescFileName[256]; + char szSkillTableFileName[256]; + char szInsultList[256]; + snprintf(szItemList, sizeof(szItemList) , "%s/item_list.txt", localePath); + snprintf(szItemProto, sizeof(szItemProto), "%s/item_proto", localePath); + snprintf(szItemDesc, sizeof(szItemDesc), "%s/itemdesc.txt", localePath); + snprintf(szMobProto, sizeof(szMobProto), "%s/mob_proto", localePath); + snprintf(szSkillDescFileName, sizeof(szSkillDescFileName), "%s/SkillDesc.txt", localePath); + snprintf(szSkillTableFileName, sizeof(szSkillTableFileName), "%s/SkillTable.txt", localePath); + snprintf(szInsultList, sizeof(szInsultList), "%s/insult.txt", localePath); + + rkNPCMgr.Destroy(); + rkItemMgr.Destroy(); + rkSkillMgr.Destroy(); + + if (!rkItemMgr.LoadItemList(szItemList)) + { + TraceError("LoadLocaleData - LoadItemList(%s) Error", szItemList); + } + + if (!rkItemMgr.LoadItemTable(szItemProto)) + { + TraceError("LoadLocaleData - LoadItemProto(%s) Error", szItemProto); + return false; + } + + if (!rkItemMgr.LoadItemDesc(szItemDesc)) + { + Tracenf("LoadLocaleData - LoadItemDesc(%s) Error", szItemDesc); + } + + if (!rkNPCMgr.LoadNonPlayerData(szMobProto)) + { + TraceError("LoadLocaleData - LoadMobProto(%s) Error", szMobProto); + return false; + } + + if (!rkSkillMgr.RegisterSkillDesc(szSkillDescFileName)) + { + TraceError("LoadLocaleData - RegisterSkillDesc(%s) Error", szMobProto); + return false; + } + + if (!rkSkillMgr.RegisterSkillTable(szSkillTableFileName)) + { + TraceError("LoadLocaleData - RegisterSkillTable(%s) Error", szMobProto); + return false; + } + + if (!rkNetStream.LoadInsultList(szInsultList)) + { + Tracenf("CPythonApplication - CPythonNetworkStream::LoadInsultList(%s)", szInsultList); + } + + if (LocaleService_IsYMIR()) + { + char szEmpireTextConvFile[256]; + for (DWORD dwEmpireID=1; dwEmpireID<=3; ++dwEmpireID) + { + sprintf(szEmpireTextConvFile, "%s/lang%d.cvt", localePath, dwEmpireID); + if (!rkNetStream.LoadConvertTable(dwEmpireID, szEmpireTextConvFile)) + { + TraceError("LoadLocaleData - CPythonNetworkStream::LoadConvertTable(%d, %s) FAILURE", dwEmpireID, szEmpireTextConvFile); + } + } + } + + NANOEND + return true; +} +// END_OF_SUPPORT_NEW_KOREA_SERVER + +unsigned __GetWindowMode(bool windowed) +{ + if (windowed) + return WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; + + return WS_POPUP; +} + +bool CPythonApplication::Create(PyObject * poSelf, const char * c_szName, int width, int height, int Windowed) +{ + NANOBEGIN + Windowed = CPythonSystem::Instance().IsWindowed() ? 1 : 0; + + bool bAnotherWindow = false; + + if (FindWindow(NULL, c_szName)) + bAnotherWindow = true; + + m_dwWidth = width; + m_dwHeight = height; + + // Window + UINT WindowMode = __GetWindowMode(Windowed ? true : false); + + if (!CMSWindow::Create(c_szName, 4, 0, WindowMode, ::LoadIcon( GetInstance(), MAKEINTRESOURCE( IDI_METIN2 ) ), IDC_CURSOR_NORMAL)) + { + //PyErr_SetString(PyExc_RuntimeError, "CMSWindow::Create failed"); + TraceError("CMSWindow::Create failed"); + SET_EXCEPTION(CREATE_WINDOW); + return false; + } + +#ifdef USE_NPROTECT_GAMEGUARD + if (!GameGuard_Run(CMSWindow::GetWindowHandle())) + return false; +#endif +#ifdef XTRAP_CLIENT_ENABLE + if (!XTrap_CheckInit()) + return false; +#endif + + if (m_pySystem.IsUseDefaultIME()) + { + CPythonIME::Instance().UseDefaultIME(); + } + +#if defined(ENABLE_DISCORD_RPC) + m_pyNetworkStream.Discord_Start(); +#endif + + // Ǯũ ̰ + // Ʈ IME ϰų ̸ + // Ǯũ 带 Ѵ + if (!m_pySystem.IsWindowed() && (m_pySystem.IsUseDefaultIME() || LocaleService_IsEUROPE())) + { + m_isWindowed = false; + m_isWindowFullScreenEnable = TRUE; + __SetFullScreenWindow(GetWindowHandle(), width, height, m_pySystem.GetBPP()); + + Windowed = true; + } + else + { + AdjustSize(m_pySystem.GetWidth(), m_pySystem.GetHeight()); + + if (Windowed) + { + m_isWindowed = true; + + if (bAnotherWindow) + { + RECT rc; + + GetClientRect(&rc); + + int windowWidth = rc.right - rc.left; + int windowHeight = (rc.bottom - rc.top); + + CMSApplication::SetPosition(GetScreenWidth() - windowWidth, GetScreenHeight() - 60 - windowHeight); + } + SetPosition(-8, 0); //Fix + } + else + { + m_isWindowed = false; + SetPosition(0, 0); + } + } + + NANOEND + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + // Cursor + if (!CreateCursors()) + { + //PyErr_SetString(PyExc_RuntimeError, "CMSWindow::Cursors Create Error"); + TraceError("CMSWindow::Cursors Create Error"); + SET_EXCEPTION("CREATE_CURSOR"); + return false; + } + + if (!m_pySystem.IsNoSoundCard()) + { + // Sound + if (!m_SoundManager.Create()) + { + // NOTE : ߱ û + // LogBox(ApplicationStringTable_GetStringz(IDS_WARN_NO_SOUND_DEVICE)); + } + } + + extern bool GRAPHICS_CAPS_SOFTWARE_TILING; + + if (!m_pySystem.IsAutoTiling()) + GRAPHICS_CAPS_SOFTWARE_TILING = m_pySystem.IsSoftwareTiling(); + + // Device + if (!CreateDevice(m_pySystem.GetWidth(), m_pySystem.GetHeight(), Windowed, m_pySystem.GetBPP(), m_pySystem.GetFrequency())) + return false; + + GrannyCreateSharedDeformBuffer(); + + if (m_pySystem.IsAutoTiling()) + { + if (m_grpDevice.IsFastTNL()) + { + m_pyBackground.ReserveSoftwareTilingEnable(false); + } + else + { + m_pyBackground.ReserveSoftwareTilingEnable(true); + } + } + else + { + m_pyBackground.ReserveSoftwareTilingEnable(m_pySystem.IsSoftwareTiling()); + } + + SetVisibleMode(true); + + if (m_isWindowFullScreenEnable) //m_pySystem.IsUseDefaultIME() && !m_pySystem.IsWindowed()) + { + SetWindowPos(GetWindowHandle(), HWND_TOP, 0, 0, width, height, SWP_SHOWWINDOW); + } + + if (!InitializeKeyboard(GetWindowHandle())) + return false; + + m_pySystem.GetDisplaySettings(); + + // Mouse + if (m_pySystem.IsSoftwareCursor()) + SetCursorMode(CURSOR_MODE_SOFTWARE); + else + SetCursorMode(CURSOR_MODE_HARDWARE); + + // Network + if (!m_netDevice.Create()) + { + //PyErr_SetString(PyExc_RuntimeError, "NetDevice::Create failed"); + TraceError("NetDevice::Create failed"); + SET_EXCEPTION("CREATE_NETWORK"); + return false; + } + + if (!m_grpDevice.IsFastTNL()) + CGrannyLODController::SetMinLODMode(true); + + m_pyItem.Create(); + + // Other Modules + DefaultFont_Startup(); + + CPythonIME::Instance().Create(GetWindowHandle()); + CPythonIME::Instance().SetText("", 0); + CPythonTextTail::Instance().Initialize(); + + // Light Manager + m_LightManager.Initialize(); + + CGraphicImageInstance::CreateSystem(32); + + // + STICKYKEYS sStickKeys; + memset(&sStickKeys, 0, sizeof(sStickKeys)); + sStickKeys.cbSize = sizeof(sStickKeys); + SystemParametersInfo( SPI_GETSTICKYKEYS, sizeof(sStickKeys), &sStickKeys, 0 ); + m_dwStickyKeysFlag = sStickKeys.dwFlags; + + // + sStickKeys.dwFlags &= ~(SKF_AVAILABLE|SKF_HOTKEYACTIVE); + SystemParametersInfo( SPI_SETSTICKYKEYS, sizeof(sStickKeys), &sStickKeys, 0 ); + + // SphereMap + CGrannyMaterial::CreateSphereMap(0, "d:/ymir work/special/spheremap.jpg"); + CGrannyMaterial::CreateSphereMap(1, "d:/ymir work/special/spheremap01.jpg"); + return true; +} + +void CPythonApplication::SetGlobalCenterPosition(LONG x, LONG y) +{ + CPythonBackground& rkBG=CPythonBackground::Instance(); + rkBG.GlobalPositionToLocalPosition(x, y); + + float z = CPythonBackground::Instance().GetHeight(x, y); + + CPythonApplication::Instance().SetCenterPosition(x, y, z); +} + +void CPythonApplication::SetCenterPosition(float fx, float fy, float fz) +{ + m_v3CenterPosition.x = +fx; + m_v3CenterPosition.y = -fy; + m_v3CenterPosition.z = +fz; +} + +void CPythonApplication::GetCenterPosition(TPixelPosition * pPixelPosition) +{ + pPixelPosition->x = +m_v3CenterPosition.x; + pPixelPosition->y = -m_v3CenterPosition.y; + pPixelPosition->z = +m_v3CenterPosition.z; +} + + +void CPythonApplication::SetServerTime(time_t tTime) +{ + m_dwStartLocalTime = ELTimer_GetMSec(); + m_tServerTime = tTime; + m_tLocalStartTime = time(0); +} + +time_t CPythonApplication::GetServerTime() +{ + return (ELTimer_GetMSec() - m_dwStartLocalTime) + m_tServerTime; +} + +// 2005.03.28 - MALL ۿ ִ ð time(0) +// ̱ ߱ ð ó ߰ +time_t CPythonApplication::GetServerTimeStamp() +{ + return (time(0) - m_tLocalStartTime) + m_tServerTime; +} + +float CPythonApplication::GetGlobalTime() +{ + return m_fGlobalTime; +} + +float CPythonApplication::GetGlobalElapsedTime() +{ + return m_fGlobalElapsedTime; +} + +void CPythonApplication::SetFPS(int iFPS) +{ + m_iFPS = iFPS; +} + +int CPythonApplication::GetWidth() +{ + return m_dwWidth; +} + +int CPythonApplication::GetHeight() +{ + return m_dwHeight; +} + +void CPythonApplication::SetConnectData(const char * c_szIP, int iPort) +{ + m_strIP = c_szIP; + m_iPort = iPort; +} + +void CPythonApplication::GetConnectData(std::string & rstIP, int & riPort) +{ + rstIP = m_strIP; + riPort = m_iPort; +} + +void CPythonApplication::EnableSpecialCameraMode() +{ + m_isSpecialCameraMode = TRUE; +} + +void CPythonApplication::SetCameraSpeed(int iPercentage) +{ + m_fCameraRotateSpeed = c_fDefaultCameraRotateSpeed * float(iPercentage) / 100.0f; + m_fCameraPitchSpeed = c_fDefaultCameraPitchSpeed * float(iPercentage) / 100.0f; + m_fCameraZoomSpeed = c_fDefaultCameraZoomSpeed * float(iPercentage) / 100.0f; +} + +void CPythonApplication::SetForceSightRange(int iRange) +{ + m_iForceSightRange = iRange; +} + +void CPythonApplication::Clear() +{ + m_pySystem.Clear(); +} + +void CPythonApplication::Destroy() +{ + WebBrowser_Destroy(); + + // SphereMap + CGrannyMaterial::DestroySphereMap(); + + m_kWndMgr.Destroy(); + + CPythonSystem::Instance().SaveConfig(); + + DestroyCollisionInstanceSystem(); + + m_pySystem.SaveInterfaceStatus(); + + m_pyEventManager.Destroy(); + m_FlyingManager.Destroy(); + + m_pyMiniMap.Destroy(); + + m_pyTextTail.Destroy(); + m_pyChat.Destroy(); + m_kChrMgr.Destroy(); + m_RaceManager.Destroy(); + + m_pyItem.Destroy(); + m_kItemMgr.Destroy(); + + m_pyBackground.Destroy(); + + m_kEftMgr.Destroy(); + m_LightManager.Destroy(); + + // DEFAULT_FONT + DefaultFont_Cleanup(); + // END_OF_DEFAULT_FONT + + GrannyDestroySharedDeformBuffer(); + + m_pyGraphic.Destroy(); + +#if defined(ENABLE_DISCORD_RPC) + m_pyNetworkStream.Discord_Close(); +#endif + + //m_pyNetworkDatagram.Destroy(); + + m_pyRes.Destroy(); + + m_kGuildMarkDownloader.Disconnect(); + + CGrannyModelInstance::DestroySystem(); + CGraphicImageInstance::DestroySystem(); + + + m_SoundManager.Destroy(); + m_grpDevice.Destroy(); + + // FIXME : - [levites] + //CSpeedTreeForestDirectX8::Instance().Clear(); + + CAttributeInstance::DestroySystem(); + CTextFileLoader::DestroySystem(); + DestroyCursors(); + + CMSApplication::Destroy(); + + STICKYKEYS sStickKeys; + memset(&sStickKeys, 0, sizeof(sStickKeys)); + sStickKeys.cbSize = sizeof(sStickKeys); + sStickKeys.dwFlags = m_dwStickyKeysFlag; + SystemParametersInfo( SPI_SETSTICKYKEYS, sizeof(sStickKeys), &sStickKeys, 0 ); +} diff --git a/source/UserInterface/PythonApplication.h b/source/UserInterface/PythonApplication.h new file mode 100644 index 0000000..9085038 --- /dev/null +++ b/source/UserInterface/PythonApplication.h @@ -0,0 +1,440 @@ +#pragma once + +#include "../eterLib/MSApplication.h" +#include "../eterLib/Input.h" +#include "../eterLib/Profiler.h" +#include "../eterLib/GrpDevice.h" +#include "../eterLib/NetDevice.h" +#include "../eterLib/GrpLightManager.h" +#include "../EffectLib/EffectManager.h" +#include "../gamelib/RaceManager.h" +#include "../gamelib/ItemManager.h" +#include "../gamelib/FlyingObjectManager.h" +#include "../gamelib/GameEventManager.h" +#include "../milesLib/SoundManager.h" + +#include "PythonEventManager.h" +#include "PythonPlayer.h" +#include "PythonNonPlayer.h" +#include "PythonMiniMap.h" +#include "PythonIME.h" +#include "PythonItem.h" +#include "PythonShop.h" +#include "PythonExchange.h" +#include "PythonChat.h" +#include "PythonTextTail.h" +#include "PythonSkill.h" +#include "PythonSystem.h" +//#include "PythonNetworkDatagram.h" +#include "PythonNetworkStream.h" +#include "PythonCharacterManager.h" +#include "PythonQuest.h" +#include "PythonMessenger.h" +#include "PythonSafeBox.h" +#include "PythonGuild.h" + +#include "GuildMarkDownloader.h" +#include "GuildMarkUploader.h" + +#include "AccountConnector.h" + +#include "ServerStateChecker.h" +#include "AbstractApplication.h" +#include "MovieMan.h" + +class CPythonApplication : public CMSApplication, public CInputKeyboard, public IAbstractApplication +{ + public: + enum EDeviceState + { + DEVICE_STATE_FALSE, + DEVICE_STATE_SKIP, + DEVICE_STATE_OK, + }; + + enum ECursorMode + { + CURSOR_MODE_HARDWARE, + CURSOR_MODE_SOFTWARE, + }; + + enum ECursorShape + { + CURSOR_SHAPE_NORMAL, + CURSOR_SHAPE_ATTACK, + CURSOR_SHAPE_TARGET, + CURSOR_SHAPE_TALK, + CURSOR_SHAPE_CANT_GO, + CURSOR_SHAPE_PICK, + + CURSOR_SHAPE_DOOR, + CURSOR_SHAPE_CHAIR, + CURSOR_SHAPE_MAGIC, // Magic + CURSOR_SHAPE_BUY, // Buy + CURSOR_SHAPE_SELL, // Sell + + CURSOR_SHAPE_CAMERA_ROTATE, // Camera Rotate + CURSOR_SHAPE_HSIZE, // Horizontal Size + CURSOR_SHAPE_VSIZE, // Vertical Size + CURSOR_SHAPE_HVSIZE, // Horizontal & Vertical Size + + CURSOR_SHAPE_COUNT, + + // ̹ ȯ ӽ enumerate + NORMAL = CURSOR_SHAPE_NORMAL, + ATTACK = CURSOR_SHAPE_ATTACK, + TARGET = CURSOR_SHAPE_TARGET, + CAMERA_ROTATE = CURSOR_SHAPE_CAMERA_ROTATE, + CURSOR_COUNT = CURSOR_SHAPE_COUNT, + }; + + enum EInfo + { + INFO_ACTOR, + INFO_EFFECT, + INFO_ITEM, + INFO_TEXTTAIL, + }; + + enum ECameraControlDirection + { + CAMERA_TO_POSITIVE = 1, + CAMERA_TO_NEGITIVE = -1, + CAMERA_STOP = 0, + }; + + enum + { + CAMERA_MODE_NORMAL = 0, + CAMERA_MODE_STAND = 1, + CAMERA_MODE_BLEND = 2, + + EVENT_CAMERA_NUMBER = 101, + }; + + struct SCameraSpeed + { + float m_fUpDir; + float m_fViewDir; + float m_fCrossDir; + + SCameraSpeed() : m_fUpDir(0.0f), m_fViewDir(0.0f), m_fCrossDir(0.0f) {} + }; + + public: + CPythonApplication(); + virtual ~CPythonApplication(); + + public: + void ShowWebPage(const char* c_szURL, const RECT& c_rcWebPage); + void MoveWebPage(const RECT& c_rcWebPage); + void HideWebPage(); + + bool IsWebPageMode(); + + public: + void NotifyHack(const char* c_szFormat, ...); + void GetInfo(UINT eInfo, std::string* pstInfo); + void GetMousePosition(POINT* ppt); + + static CPythonApplication& Instance() + { + assert(ms_pInstance != NULL); + return *ms_pInstance; + } + + void Loop(); + void Destroy(); + void Clear(); + void Exit(); + void Abort(); + + void SetMinFog(float fMinFog); + void SetFrameSkip(bool isEnable); + void SkipRenderBuffering(DWORD dwSleepMSec); + + bool Create(PyObject* poSelf, const char* c_szName, int width, int height, int Windowed); + bool CreateDevice(int width, int height, int Windowed, int bit = 32, int frequency = 0); + + void UpdateGame(); + void RenderGame(); + + bool Process(); + + void UpdateClientRect(); + + bool CreateCursors(); + void DestroyCursors(); + + void SafeSetCapture(); + void SafeReleaseCapture(); + + BOOL SetCursorNum(int iCursorNum); + void SetCursorVisible(BOOL bFlag, bool bLiarCursorOn = false); + BOOL GetCursorVisible(); + bool GetLiarCursorOn(); + void SetCursorMode(int iMode); + int GetCursorMode(); + int GetCursorNum() { return m_iCursorNum; } + + void SetMouseHandler(PyObject * poMouseHandler); + + int GetWidth(); + int GetHeight(); + + void SetGlobalCenterPosition(LONG x, LONG y); + void SetCenterPosition(float fx, float fy, float fz); + void GetCenterPosition(TPixelPosition * pPixelPosition); + void SetCamera(float Distance, float Pitch, float Rotation, float fDestinationHeight); + void GetCamera(float * Distance, float * Pitch, float * Rotation, float * DestinationHeight); + void RotateCamera(int iDirection); + void PitchCamera(int iDirection); + void ZoomCamera(int iDirection); + void MovieRotateCamera(int iDirection); + void MoviePitchCamera(int iDirection); + void MovieZoomCamera(int iDirection); + void MovieResetCamera(); + void SetViewDirCameraSpeed(float fSpeed); + void SetCrossDirCameraSpeed(float fSpeed); + void SetUpDirCameraSpeed(float fSpeed); + float GetRotation(); + float GetPitch(); + + void SetFPS(int iFPS); + void SetServerTime(time_t tTime); + time_t GetServerTime(); + time_t GetServerTimeStamp(); + float GetGlobalTime(); + float GetGlobalElapsedTime(); + + float GetFaceSpeed() { return m_fFaceSpd; } + float GetAveRenderTime() { return m_fAveRenderTime; } + DWORD GetCurRenderTime() { return m_dwCurRenderTime; } + DWORD GetCurUpdateTime() { return m_dwCurUpdateTime; } + DWORD GetUpdateFPS() { return m_dwUpdateFPS; } + DWORD GetRenderFPS() { return m_dwRenderFPS; } + DWORD GetLoad() { return m_dwLoad; } + DWORD GetFaceCount() { return m_dwFaceCount; } + + void SetConnectData(const char * c_szIP, int iPort); + void GetConnectData(std::string & rstIP, int & riPort); + + void RunIMEUpdate(); + void RunIMETabEvent(); + void RunIMEReturnEvent(); + void RunPressExitKey(); + + void RunIMEChangeCodePage(); + void RunIMEOpenCandidateListEvent(); + void RunIMECloseCandidateListEvent(); + void RunIMEOpenReadingWndEvent(); + void RunIMECloseReadingWndEvent(); + + void EnableSpecialCameraMode(); + void SetCameraSpeed(int iPercentage); + + bool IsLockCurrentCamera(); + void SetEventCamera(const SCameraSetting & c_rCameraSetting); + void BlendEventCamera(const SCameraSetting & c_rCameraSetting, float fBlendTime); + void SetDefaultCamera(); + + void SetCameraSetting(const SCameraSetting & c_rCameraSetting); + void GetCameraSetting(SCameraSetting * pCameraSetting); + void SaveCameraSetting(const char * c_szFileName); + bool LoadCameraSetting(const char * c_szFileName); + + void SetForceSightRange(int iRange); + + + public: + int OnLogoOpen(char* szName); + int OnLogoUpdate(); + void OnLogoRender(); + void OnLogoClose(); + + protected: + IGraphBuilder* m_pGraphBuilder; // Graph Builder + IBaseFilter* m_pFilterSG; // Sample Grabber + ISampleGrabber* m_pSampleGrabber; // ̹ ĸó ׷ + IMediaControl* m_pMediaCtrl; // Media Control + IMediaEventEx* m_pMediaEvent; // Media Event + IVideoWindow* m_pVideoWnd; // Video Window + IBasicVideo* m_pBasicVideo; + BYTE* m_pCaptureBuffer; // ̹ ĸó + LONG m_lBufferSize; // Video ũ + CGraphicImageTexture* m_pLogoTex; // ؽ + bool m_bLogoError; // б + bool m_bLogoPlay; + + int m_nLeft, m_nRight, m_nTop, m_nBottom; + + + protected: + LRESULT WindowProcedure(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam); + + void OnCameraUpdate(); + + void OnUIUpdate(); + void OnUIRender(); + + void OnMouseUpdate(); + void OnMouseRender(); + + void OnMouseWheel(int nLen); + void OnMouseMove(int x, int y); + void OnMouseMiddleButtonDown(int x, int y); + void OnMouseMiddleButtonUp(int x, int y); + void OnMouseLeftButtonDown(int x, int y); + void OnMouseLeftButtonUp(int x, int y); + void OnMouseLeftButtonDoubleClick(int x, int y); + void OnMouseRightButtonDown(int x, int y); + void OnMouseRightButtonUp(int x, int y); + void OnSizeChange(int width, int height); + void OnKeyDown(int iIndex); + void OnKeyUp(int iIndex); + void OnIMEKeyDown(int iIndex); + + int CheckDeviceState(); + + BOOL __IsContinuousChangeTypeCursor(int iCursorNum); + + void __UpdateCamera(); + + void __SetFullScreenWindow(HWND hWnd, DWORD dwWidth, DWORD dwHeight, DWORD dwBPP); + void __MinimizeFullScreenWindow(HWND hWnd, DWORD dwWidth, DWORD dwHeight); + + + protected: + CTimer m_timer; + + CLightManager m_LightManager; + CSoundManager m_SoundManager; + CFlyingManager m_FlyingManager; + CRaceManager m_RaceManager; + CGameEventManager m_GameEventManager; + CItemManager m_kItemMgr; + CMovieMan m_MovieManager; + + UI::CWindowManager m_kWndMgr; + CEffectManager m_kEftMgr; + CPythonCharacterManager m_kChrMgr; + + CServerStateChecker m_kServerStateChecker; + CPythonGraphic m_pyGraphic; + CPythonNetworkStream m_pyNetworkStream; + //CPythonNetworkDatagram m_pyNetworkDatagram; + CPythonPlayer m_pyPlayer; + CPythonIME m_pyIme; + CPythonItem m_pyItem; + CPythonShop m_pyShop; + CPythonExchange m_pyExchange; + CPythonChat m_pyChat; + CPythonTextTail m_pyTextTail; + CPythonNonPlayer m_pyNonPlayer; + CPythonMiniMap m_pyMiniMap; + CPythonEventManager m_pyEventManager; + CPythonBackground m_pyBackground; + CPythonSkill m_pySkill; + CPythonResource m_pyRes; + CPythonQuest m_pyQuest; + CPythonMessenger m_pyManager; + CPythonSafeBox m_pySafeBox; + CPythonGuild m_pyGuild; + + CGuildMarkManager m_kGuildMarkManager; + CGuildMarkDownloader m_kGuildMarkDownloader; + CGuildMarkUploader m_kGuildMarkUploader; + CAccountConnector m_kAccountConnector; + + CGraphicDevice m_grpDevice; + CNetworkDevice m_netDevice; + + CPythonSystem m_pySystem; + + + PyObject * m_poMouseHandler; + D3DXVECTOR3 m_v3CenterPosition; + + unsigned int m_iFPS; + float m_fAveRenderTime; + DWORD m_dwCurRenderTime; + DWORD m_dwCurUpdateTime; + DWORD m_dwLoad; + DWORD m_dwWidth; + DWORD m_dwHeight; + + protected: + // Time + DWORD m_dwLastIdleTime; + DWORD m_dwStartLocalTime; + time_t m_tServerTime; + time_t m_tLocalStartTime; + float m_fGlobalTime; + float m_fGlobalElapsedTime; + + ///////////////////////////////////////////////////////////// + // Camera + SCameraSetting m_DefaultCameraSetting; + SCameraSetting m_kEventCameraSetting; + + int m_iCameraMode; + float m_fBlendCameraStartTime; + float m_fBlendCameraBlendTime; + SCameraSetting m_kEndBlendCameraSetting; + + float m_fRotationSpeed; + float m_fPitchSpeed; + float m_fZoomSpeed; + float m_fCameraRotateSpeed; + float m_fCameraPitchSpeed; + float m_fCameraZoomSpeed; + + SCameraPos m_kCmrPos; + SCameraSpeed m_kCmrSpd; + + BOOL m_isSpecialCameraMode; + // Camera + ///////////////////////////////////////////////////////////// + + float m_fFaceSpd; + DWORD m_dwFaceSpdSum; + DWORD m_dwFaceSpdCount; + + DWORD m_dwFaceAccCount; + DWORD m_dwFaceAccTime; + + DWORD m_dwUpdateFPS; + DWORD m_dwRenderFPS; + DWORD m_dwFaceCount; + + DWORD m_dwLButtonDownTime; + DWORD m_dwLButtonUpTime; + + typedef std::map TCursorHandleMap; + TCursorHandleMap m_CursorHandleMap; + HANDLE m_hCurrentCursor; + + BOOL m_bCursorVisible; + bool m_bLiarCursorOn; + int m_iCursorMode; + bool m_isWindowed; + bool m_isFrameSkipDisable; + + // Connect Data + std::string m_strIP; + int m_iPort; + + static CPythonApplication* ms_pInstance; + + bool m_isMinimizedWnd; + bool m_isActivateWnd; + BOOL m_isWindowFullScreenEnable; + + DWORD m_dwStickyKeysFlag; + DWORD m_dwBufSleepSkipTime; + int m_iForceSightRange; + + protected: + int m_iCursorNum; + int m_iContinuousCursorNum; +}; diff --git a/source/UserInterface/PythonApplicationCamera.cpp b/source/UserInterface/PythonApplicationCamera.cpp new file mode 100644 index 0000000..cd201d4 --- /dev/null +++ b/source/UserInterface/PythonApplicationCamera.cpp @@ -0,0 +1,415 @@ +#include "StdAfx.h" +#include "PythonApplication.h" + +#include "../eterbase/timer.h" +#include "../eterlib/Camera.h" + +float BlendValueByLinear(float fElapsedTime, float fDuration, float fBeginValue, float fEndValue) +{ + if (fElapsedTime >= fDuration) + return fEndValue; + + return (fEndValue - fBeginValue) * (fElapsedTime / fDuration) + fBeginValue; +} + +void CPythonApplication::__UpdateCamera() +{ + ////////////////////// + // Camera Setting + CCamera * pMainCamera = CCameraManager::Instance().GetCurrentCamera(); + if (!pMainCamera) + return; + + if (CAMERA_MODE_BLEND == m_iCameraMode) + { + float fcurTime = CTimer::Instance().GetCurrentSecond(); + float fElapsedTime = fcurTime - m_fBlendCameraStartTime; + + float fxCenter = BlendValueByLinear(fElapsedTime, m_fBlendCameraBlendTime, m_kEventCameraSetting.v3CenterPosition.x, m_kEndBlendCameraSetting.v3CenterPosition.x); + float fyCenter = BlendValueByLinear(fElapsedTime, m_fBlendCameraBlendTime, m_kEventCameraSetting.v3CenterPosition.y, m_kEndBlendCameraSetting.v3CenterPosition.y); + float fzCenter = BlendValueByLinear(fElapsedTime, m_fBlendCameraBlendTime, m_kEventCameraSetting.v3CenterPosition.z, m_kEndBlendCameraSetting.v3CenterPosition.z); + + float fDistance = BlendValueByLinear(fElapsedTime, m_fBlendCameraBlendTime, m_kEventCameraSetting.fZoom, m_kEndBlendCameraSetting.fZoom); + float fPitch = BlendValueByLinear(fElapsedTime, m_fBlendCameraBlendTime, m_kEventCameraSetting.fPitch, m_kEndBlendCameraSetting.fPitch); + float fRotation = BlendValueByLinear(fElapsedTime, m_fBlendCameraBlendTime, m_kEventCameraSetting.fRotation, m_kEndBlendCameraSetting.fRotation); + + float fUpDir = BlendValueByLinear(fElapsedTime, m_fBlendCameraBlendTime, m_kEventCameraSetting.kCmrPos.m_fUpDir, m_kEndBlendCameraSetting.kCmrPos.m_fUpDir); + float fViewDir = BlendValueByLinear(fElapsedTime, m_fBlendCameraBlendTime, m_kEventCameraSetting.kCmrPos.m_fViewDir, m_kEndBlendCameraSetting.kCmrPos.m_fViewDir); + float fCrossDir = BlendValueByLinear(fElapsedTime, m_fBlendCameraBlendTime, m_kEventCameraSetting.kCmrPos.m_fCrossDir, m_kEndBlendCameraSetting.kCmrPos.m_fCrossDir); + + // Temporary. Have to fix that this work in camera class. - [levites] + pMainCamera->Unlock(); + m_pyGraphic.SetPositionCamera(fxCenter, fyCenter, fzCenter, fDistance, fPitch, fRotation); + pMainCamera->MoveVertical(fUpDir); + pMainCamera->MoveFront(fViewDir); + pMainCamera->MoveAlongCross(fCrossDir); + pMainCamera->Lock(); + } + else if (CAMERA_MODE_STAND == m_iCameraMode) + { + float fDistance, fPitch, fRotation, fHeight; + GetCamera(&fDistance, &fPitch, &fRotation, &fHeight); + m_pyGraphic.SetPositionCamera(m_kEventCameraSetting.v3CenterPosition.x, + m_kEventCameraSetting.v3CenterPosition.y, + m_kEventCameraSetting.v3CenterPosition.z + pMainCamera->GetTargetHeight(), + fDistance, fPitch, fRotation); + } + else if (CAMERA_MODE_NORMAL == m_iCameraMode) + { + float fDistance, fPitch, fRotation, fHeight; + GetCamera(&fDistance, &fPitch, &fRotation, &fHeight); + m_pyGraphic.SetPositionCamera(m_v3CenterPosition.x, m_v3CenterPosition.y, m_v3CenterPosition.z + pMainCamera->GetTargetHeight(), fDistance, fPitch, fRotation); + } + + if (0.0f != m_fRotationSpeed) + pMainCamera->Roll(m_fRotationSpeed); + if (0.0f != m_fPitchSpeed) + pMainCamera->Pitch(m_fPitchSpeed); + if (0.0f != m_fZoomSpeed) + pMainCamera->Zoom(m_fZoomSpeed); + + if (0.0f !=m_kCmrSpd.m_fViewDir) + m_kCmrPos.m_fViewDir+=m_kCmrSpd.m_fViewDir; + if (0.0f !=m_kCmrSpd.m_fCrossDir) + m_kCmrPos.m_fCrossDir+=m_kCmrSpd.m_fCrossDir; + if (0.0f !=m_kCmrSpd.m_fUpDir) + m_kCmrPos.m_fUpDir+=m_kCmrSpd.m_fUpDir; + + if (0.0f != m_kCmrPos.m_fViewDir) + pMainCamera->MoveFront(m_kCmrPos.m_fViewDir); + if (0.0f != m_kCmrPos.m_fCrossDir) + pMainCamera->MoveAlongCross(m_kCmrPos.m_fCrossDir); + if (0.0f != m_kCmrPos.m_fUpDir) + pMainCamera->MoveVertical(m_kCmrPos.m_fUpDir); + + ////////////////////// + + if (pMainCamera->IsDraging()) + SkipRenderBuffering(3000); + + ////////////////////// + // Sound Setting + const D3DXVECTOR3 & c_rv3CameraDirection = pMainCamera->GetView(); + const D3DXVECTOR3 & c_rv3CameraUp = pMainCamera->GetUp(); + m_SoundManager.SetPosition(m_v3CenterPosition.x, m_v3CenterPosition.y, m_v3CenterPosition.z); // Listener - ij ġ + m_SoundManager.SetDirection(c_rv3CameraDirection.x, c_rv3CameraDirection.y, c_rv3CameraDirection.z, c_rv3CameraUp.x, c_rv3CameraUp.y, c_rv3CameraUp.z); + m_SoundManager.Update(); + ////////////////////// +} + +void CPythonApplication::SetViewDirCameraSpeed(float fSpeed) +{ + if (IsLockCurrentCamera()) + return; + + m_kCmrSpd.m_fViewDir=fSpeed; +} + +void CPythonApplication::SetCrossDirCameraSpeed(float fSpeed) +{ + if (IsLockCurrentCamera()) + return; + + m_kCmrSpd.m_fCrossDir=fSpeed; +} + +void CPythonApplication::SetUpDirCameraSpeed(float fSpeed) +{ + if (IsLockCurrentCamera()) + return; + + m_kCmrSpd.m_fUpDir=fSpeed; +} + +void CPythonApplication::SetCamera(float Distance, float Pitch, float Rotation, float fDestinationHeight) +{ + if (IsLockCurrentCamera()) + return; + + CCamera * pCurrentCamera = CCameraManager::Instance().GetCurrentCamera(); + if (!pCurrentCamera) + return; + + D3DXVECTOR3 v3Target = pCurrentCamera->GetTarget(); + m_pyGraphic.SetPositionCamera(v3Target.x, v3Target.y, v3Target.z, Distance, Pitch, Rotation); + + CCamera * pMainCamera = CCameraManager::Instance().GetCurrentCamera(); + if (pMainCamera) + pMainCamera->SetTargetHeight(fDestinationHeight); +} + +void CPythonApplication::GetCamera(float * Distance, float * Pitch, float * Rotation, float * DestinationHeight) +{ + CCamera * pCurrentCamera = CCameraManager::Instance().GetCurrentCamera(); + *Distance = pCurrentCamera->GetDistance(); + *Pitch = pCurrentCamera->GetPitch(); + *Rotation = pCurrentCamera->GetRoll(); + *DestinationHeight = pCurrentCamera->GetTarget().z; +} + +void CPythonApplication::RotateCamera(int iDirection) +{ + if (IsLockCurrentCamera()) + return; + + float fDegree = m_fCameraRotateSpeed * float(iDirection); + m_fRotationSpeed = fDegree; +} + +void CPythonApplication::PitchCamera(int iDirection) +{ + if (IsLockCurrentCamera()) + return; + + float fDegree = m_fCameraPitchSpeed * float(iDirection); + m_fPitchSpeed = fDegree; +} + +void CPythonApplication::ZoomCamera(int iDirection) +{ + if (IsLockCurrentCamera()) + return; + + float fRatio = 1.0f + m_fCameraZoomSpeed * float(iDirection); + m_fZoomSpeed = fRatio; +} + +void CPythonApplication::MovieRotateCamera(int iDirection) +{ + if (IsLockCurrentCamera()) + return; + + float fDegree = m_fCameraRotateSpeed * float(iDirection); + if (m_isSpecialCameraMode) + { + if (GetKeyState(VK_SCROLL) & 1) + { + SetCrossDirCameraSpeed(-fDegree * 6.0f); + return; + } + } + m_fRotationSpeed = fDegree; +} + +void CPythonApplication::MoviePitchCamera(int iDirection) +{ + if (IsLockCurrentCamera()) + return; + + float fDegree = m_fCameraPitchSpeed * float(iDirection); + if (m_isSpecialCameraMode) + { + if (GetKeyState(VK_SCROLL) & 1) + { + SetViewDirCameraSpeed(-fDegree * 6.0f); + return; + } + } + m_fPitchSpeed = fDegree; +} + +void CPythonApplication::MovieZoomCamera(int iDirection) +{ + if (IsLockCurrentCamera()) + return; + + float fRatio = 1.0f + m_fCameraZoomSpeed * float(iDirection); + if (m_isSpecialCameraMode) + { + if (GetKeyState(VK_SCROLL) & 1) + { + SetUpDirCameraSpeed((1.0f - fRatio) * 200.0f); + return; + } + } + m_fZoomSpeed = fRatio; +} + +void CPythonApplication::MovieResetCamera() +{ + if (IsLockCurrentCamera()) + return; + + if (m_isSpecialCameraMode) + { + SetCrossDirCameraSpeed(0.0f); + SetViewDirCameraSpeed(0.0f); + SetUpDirCameraSpeed(0.0f); + + m_kCmrPos.m_fViewDir = 0; + m_kCmrPos.m_fCrossDir = 0; + m_kCmrPos.m_fUpDir = 0; + } +} + +float CPythonApplication::GetRotation() +{ + return CCameraManager::Instance().GetCurrentCamera()->GetRoll(); +} + +float CPythonApplication::GetPitch() +{ + return CCameraManager::Instance().GetCurrentCamera()->GetPitch(); +} + +bool CPythonApplication::IsLockCurrentCamera() +{ + CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera(); + if (!pCamera) + return false; + + return pCamera->IsLock(); +} + +void CPythonApplication::SetEventCamera(const SCameraSetting & c_rCameraSetting) +{ + if (CCameraManager::DEFAULT_PERSPECTIVE_CAMERA == CCameraManager::Instance().GetCurrentCameraNum()) + { + GetCameraSetting(&m_DefaultCameraSetting); + } + + ///// + + CCameraManager::Instance().SetCurrentCamera(EVENT_CAMERA_NUMBER); + CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera(); + if (!pCamera) + return; + + SetCameraSetting(c_rCameraSetting); + m_kEventCameraSetting = c_rCameraSetting; + m_iCameraMode = CAMERA_MODE_STAND; +} + +void CPythonApplication::BlendEventCamera(const SCameraSetting & c_rCameraSetting, float fBlendTime) +{ + m_iCameraMode = CAMERA_MODE_BLEND; + m_fBlendCameraStartTime = CTimer::Instance().GetCurrentSecond(); + m_fBlendCameraBlendTime = fBlendTime; + m_kEndBlendCameraSetting = c_rCameraSetting; + + CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera(); + if (pCamera) + pCamera->Lock(); +} + +void CPythonApplication::SetDefaultCamera() +{ + m_iCameraMode = CAMERA_MODE_NORMAL; + m_fBlendCameraStartTime = 0.0f; + m_fBlendCameraBlendTime = 0.0f; + + ///// + + CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera(); + if (pCamera) + pCamera->Unlock(); + + if (CCameraManager::DEFAULT_PERSPECTIVE_CAMERA != CCameraManager::Instance().GetCurrentCameraNum()) + { + CCameraManager::Instance().SetCurrentCamera(CCameraManager::DEFAULT_PERSPECTIVE_CAMERA); + SetCameraSetting(m_DefaultCameraSetting); + } +} + +void CPythonApplication::SetCameraSetting(const SCameraSetting & c_rCameraSetting) +{ + CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera(); + if (!pCamera) + return; + + m_pyGraphic.SetPositionCamera( c_rCameraSetting.v3CenterPosition.x, + c_rCameraSetting.v3CenterPosition.y, + c_rCameraSetting.v3CenterPosition.z, + c_rCameraSetting.fZoom, + c_rCameraSetting.fPitch, + c_rCameraSetting.fRotation); + + if (0.0f != c_rCameraSetting.kCmrPos.m_fViewDir) + pCamera->MoveFront(c_rCameraSetting.kCmrPos.m_fViewDir); + if (0.0f != c_rCameraSetting.kCmrPos.m_fCrossDir) + pCamera->MoveAlongCross(c_rCameraSetting.kCmrPos.m_fCrossDir); + if (0.0f != c_rCameraSetting.kCmrPos.m_fUpDir) + pCamera->MoveVertical(c_rCameraSetting.kCmrPos.m_fUpDir); + + m_kCmrPos.m_fUpDir = 0.0f; + m_kCmrPos.m_fViewDir = 0.0f; + m_kCmrPos.m_fCrossDir = 0.0f; + m_kCmrSpd.m_fUpDir = 0.0f; + m_kCmrSpd.m_fViewDir = 0.0f; + m_kCmrSpd.m_fCrossDir = 0.0f; + m_fZoomSpeed = 0.0f; + m_fPitchSpeed = 0.0f; + m_fRotationSpeed = 0.0f; +} + +void CPythonApplication::GetCameraSetting(SCameraSetting * pCameraSetting) +{ + pCameraSetting->v3CenterPosition = m_v3CenterPosition; + pCameraSetting->kCmrPos = m_kCmrPos; + + if (CCameraManager::Instance().GetCurrentCamera()) + pCameraSetting->v3CenterPosition.z += CCameraManager::Instance().GetCurrentCamera()->GetTargetHeight(); + + float fHeight; + GetCamera(&pCameraSetting->fZoom, &pCameraSetting->fPitch, &pCameraSetting->fRotation, &fHeight); +} + +void CPythonApplication::SaveCameraSetting(const char * c_szFileName) +{ + SCameraSetting CameraSetting; + GetCameraSetting(&CameraSetting); + + FILE * File = fopen(c_szFileName, "w"); + SetFileAttributes(c_szFileName, FILE_ATTRIBUTE_NORMAL); + + PrintfTabs(File, 0, "CenterPos %f %f %f\n", CameraSetting.v3CenterPosition.x, CameraSetting.v3CenterPosition.y, CameraSetting.v3CenterPosition.z); + PrintfTabs(File, 0, "CameraSetting %f %f %f\n", CameraSetting.fZoom, CameraSetting.fPitch, CameraSetting.fRotation); + PrintfTabs(File, 0, "CmrPos %f %f %f\n", CameraSetting.kCmrPos.m_fUpDir, CameraSetting.kCmrPos.m_fViewDir, CameraSetting.kCmrPos.m_fCrossDir); + PrintfTabs(File, 0, "Line \"x;%d|y;%d|z;%d|distance;%d|pitch;%d|rot;%d|up;%d|view;%d|cross;%d\"\n", + int(CameraSetting.v3CenterPosition.x), + int(CameraSetting.v3CenterPosition.y), + int(CameraSetting.v3CenterPosition.z), + int(CameraSetting.fZoom), + int(CameraSetting.fPitch), + int(CameraSetting.fRotation), + int(CameraSetting.kCmrPos.m_fUpDir), + int(CameraSetting.kCmrPos.m_fViewDir), + int(CameraSetting.kCmrPos.m_fCrossDir)); + + fclose(File); +} + +bool CPythonApplication::LoadCameraSetting(const char * c_szFileName) +{ + CTextFileLoader TextFileLoader; + if (!TextFileLoader.Load(c_szFileName)) + return false; + + TextFileLoader.SetTop(); + + D3DXVECTOR3 v3CenterPosition; + CTokenVector * pCameraSetting; + CTokenVector * pCmrPos; + if (TextFileLoader.GetTokenVector3("centerpos", &v3CenterPosition)) + if (TextFileLoader.GetTokenVector("camerasetting", &pCameraSetting)) + if (TextFileLoader.GetTokenVector("cmrpos", &pCmrPos)) + if (3 == pCameraSetting->size()) + if (3 == pCmrPos->size()) + { + SCameraSetting CameraSetting; + CameraSetting.v3CenterPosition = v3CenterPosition; + + CameraSetting.fZoom = atof(pCameraSetting->at(0).c_str()); + CameraSetting.fPitch = atof(pCameraSetting->at(1).c_str()); + CameraSetting.fRotation = atof(pCameraSetting->at(2).c_str()); + + CameraSetting.kCmrPos.m_fUpDir = atof(pCmrPos->at(0).c_str()); + CameraSetting.kCmrPos.m_fViewDir = atof(pCmrPos->at(1).c_str()); + CameraSetting.kCmrPos.m_fCrossDir = atof(pCmrPos->at(2).c_str()); + + SetEventCamera(CameraSetting); + return true; + } + + return false; +} diff --git a/source/UserInterface/PythonApplicationCursor.cpp b/source/UserInterface/PythonApplicationCursor.cpp new file mode 100644 index 0000000..0b7e2f6 --- /dev/null +++ b/source/UserInterface/PythonApplicationCursor.cpp @@ -0,0 +1,165 @@ +#include "StdAfx.h" +#include "PythonApplication.h" +#include "resource.h" + +bool CPythonApplication::CreateCursors() +{ + NANOBEGIN + m_bCursorVisible = TRUE; + m_bLiarCursorOn = false; + + int ResourceID[CURSOR_COUNT] = + { + IDC_CURSOR_NORMAL, + IDC_CURSOR_ATTACK, + IDC_CURSOR_ATTACK, + IDC_CURSOR_TALK, + IDC_CURSOR_NO, + IDC_CURSOR_PICK, + + IDC_CURSOR_DOOR, + IDC_CURSOR_CHAIR, + IDC_CURSOR_CHAIR, // Magic + IDC_CURSOR_BUY, // Buy + IDC_CURSOR_SELL, // Sell + + IDC_CURSOR_CAMERA_ROTATE, // Camera Rotate + IDC_CURSOR_HSIZE, // Horizontal Size + IDC_CURSOR_VSIZE, // Vertical Size + IDC_CURSOR_HVSIZE, // Horizontal & Vertical Size + }; + + m_CursorHandleMap.clear(); + + for (int i = 0; i < CURSOR_COUNT; ++i) + { + HANDLE hCursor = LoadImage(ms_hInstance, MAKEINTRESOURCE(ResourceID[i]), IMAGE_CURSOR, 32, 32, LR_VGACOLOR); + + if (NULL == hCursor) + return false; + + m_CursorHandleMap.insert(TCursorHandleMap::value_type(i, hCursor)); + } + + NANOEND + return true; +} + +void CPythonApplication::DestroyCursors() +{ + TCursorHandleMap::iterator itor; + for (itor = m_CursorHandleMap.begin(); itor != m_CursorHandleMap.end(); ++itor) + { + DestroyCursor((HCURSOR) itor->second); + } +} + +void CPythonApplication::SetCursorVisible(BOOL bFlag, bool bLiarCursorOn) +{ + m_bCursorVisible = bFlag; + m_bLiarCursorOn = bLiarCursorOn; + + if (CURSOR_MODE_HARDWARE == m_iCursorMode) + { + int iShowNum; + if (FALSE == m_bCursorVisible) + { + do + { + iShowNum = ShowCursor(m_bCursorVisible); + } while(iShowNum >= 0); + } + else + { + do + { + iShowNum = ShowCursor(m_bCursorVisible); + } while(iShowNum < 0); + } + } +} + +BOOL CPythonApplication::GetCursorVisible() +{ + return m_bCursorVisible; +} + +bool CPythonApplication::GetLiarCursorOn() +{ + return m_bLiarCursorOn; +} + +int CPythonApplication::GetCursorMode() +{ + return m_iCursorMode; +} + +BOOL CPythonApplication::__IsContinuousChangeTypeCursor(int iCursorNum) +{ + switch (iCursorNum) + { + case CURSOR_SHAPE_NORMAL: + case CURSOR_SHAPE_ATTACK: + case CURSOR_SHAPE_TARGET: + case CURSOR_SHAPE_MAGIC: + case CURSOR_SHAPE_BUY: + case CURSOR_SHAPE_SELL: + return TRUE; + break; + } + + return FALSE; +} + +BOOL CPythonApplication::SetCursorNum(int iCursorNum) +{ + if (CURSOR_SHAPE_NORMAL == iCursorNum) + { + if (!__IsContinuousChangeTypeCursor(m_iCursorNum)) + { + iCursorNum = m_iContinuousCursorNum; + } + } + else + { + if (__IsContinuousChangeTypeCursor(m_iCursorNum)) // Ŀ Ŀ϶ + { + m_iContinuousCursorNum = m_iCursorNum; // Ŀ Ѵ. + } + } + + if (CURSOR_MODE_HARDWARE == m_iCursorMode) + { + TCursorHandleMap::iterator itor = m_CursorHandleMap.find(iCursorNum); + if (m_CursorHandleMap.end() == itor) + return FALSE; + + HCURSOR hCursor = (HCURSOR)itor->second; + + SetCursor(hCursor); + m_hCurrentCursor = hCursor; + } + + m_iCursorNum = iCursorNum; + + PyCallClassMemberFunc(m_poMouseHandler, "ChangeCursor", Py_BuildValue("(i)", m_iCursorNum)); + + return TRUE; +} + +void CPythonApplication::SetCursorMode(int iMode) +{ + switch (iMode) + { + case CURSOR_MODE_HARDWARE: + m_iCursorMode = CURSOR_MODE_HARDWARE; + ShowCursor(true); + break; + + case CURSOR_MODE_SOFTWARE: + m_iCursorMode = CURSOR_MODE_SOFTWARE; + SetCursor(NULL); + ShowCursor(false); + break; + } +} diff --git a/source/UserInterface/PythonApplicationEvent.cpp b/source/UserInterface/PythonApplicationEvent.cpp new file mode 100644 index 0000000..7919e3b --- /dev/null +++ b/source/UserInterface/PythonApplicationEvent.cpp @@ -0,0 +1,231 @@ +#include "StdAfx.h" +#include "PythonApplication.h" +#include "../eterlib/Camera.h" + +void CPythonApplication::OnCameraUpdate() +{ + if ( m_pyBackground.IsMapReady() ) + { + CCamera* pkCameraMgr = CCameraManager::Instance().GetCurrentCamera(); + if (pkCameraMgr) + pkCameraMgr->Update(); + } +} + +void CPythonApplication::OnUIUpdate() +{ + UI::CWindowManager& rkUIMgr=UI::CWindowManager::Instance(); + rkUIMgr.Update(); +} + +void CPythonApplication::OnUIRender() +{ + UI::CWindowManager& rkUIMgr=UI::CWindowManager::Instance(); + rkUIMgr.Render(); +} + +void CPythonApplication::OnSizeChange(int width, int height) +{ +} + +void CPythonApplication::OnMouseMiddleButtonDown(int x, int y) +{ + CCameraManager& rkCmrMgr=CCameraManager::Instance(); + CCamera* pkCmrCur=rkCmrMgr.GetCurrentCamera(); + if (pkCmrCur) + pkCmrCur->BeginDrag(x, y); + + if ( !m_pyBackground.IsMapReady() ) + return; + + SetCursorNum(CAMERA_ROTATE); + if ( CURSOR_MODE_HARDWARE == GetCursorMode()) + SetCursorVisible(FALSE, true); +} + +void CPythonApplication::OnMouseMiddleButtonUp(int x, int y) +{ + CCameraManager& rkCmrMgr=CCameraManager::Instance(); + CCamera* pkCmrCur=rkCmrMgr.GetCurrentCamera(); + if (pkCmrCur) + pkCmrCur->EndDrag(); + + if ( !m_pyBackground.IsMapReady() ) + return; + + SetCursorNum(NORMAL); + if ( CURSOR_MODE_HARDWARE == GetCursorMode()) + SetCursorVisible(TRUE); +} + +void CPythonApplication::OnMouseWheel(int nLen) +{ + CCameraManager& rkCmrMgr=CCameraManager::Instance(); + CCamera* pkCmrCur=rkCmrMgr.GetCurrentCamera(); + if (pkCmrCur) + pkCmrCur->Wheel(nLen); +} + + +void CPythonApplication::OnMouseMove(int x, int y) +{ + CCameraManager& rkCmrMgr=CCameraManager::Instance(); + CCamera* pkCmrCur=rkCmrMgr.GetCurrentCamera(); + + POINT Point; + if (pkCmrCur) + { + if ( CPythonBackground::Instance().IsMapReady() && pkCmrCur->Drag(x, y, &Point) ) + { + x = Point.x; + y = Point.y; + ClientToScreen(m_hWnd, &Point); + + // 2004.07.26.myevan.öHackShield 浹 + SetCursorPos(Point.x, Point.y); + + } + } + + RECT rcWnd; + GetClientRect(&rcWnd); + + UI::CWindowManager& rkWndMgr=UI::CWindowManager::Instance(); + rkWndMgr.SetResolution(rcWnd.right-rcWnd.left, rcWnd.bottom-rcWnd.top); + + rkWndMgr.RunMouseMove(x, y); +} + +void CPythonApplication::OnMouseLeftButtonDown(int x, int y) +{ + UI::CWindowManager& rkWndMgr=UI::CWindowManager::Instance(); + rkWndMgr.RunMouseLeftButtonDown(x, y); +} + +void CPythonApplication::OnMouseLeftButtonUp(int x, int y) +{ + UI::CWindowManager& rkWndMgr=UI::CWindowManager::Instance(); + rkWndMgr.RunMouseLeftButtonUp(x, y); +} + +void CPythonApplication::OnMouseLeftButtonDoubleClick(int x, int y) +{ + UI::CWindowManager& rkWndMgr=UI::CWindowManager::Instance(); + rkWndMgr.RunMouseLeftButtonDown(x, y); + rkWndMgr.RunMouseLeftButtonDoubleClick(x, y); +} + +void CPythonApplication::OnMouseRightButtonDown(int x, int y) +{ + UI::CWindowManager& rkWndMgr=UI::CWindowManager::Instance(); + rkWndMgr.RunMouseRightButtonDown(x, y); +} + +void CPythonApplication::OnMouseRightButtonUp(int x, int y) +{ + UI::CWindowManager& rkWndMgr=UI::CWindowManager::Instance(); + rkWndMgr.RunMouseRightButtonUp(x, y); +} + +void CPythonApplication::OnKeyDown(int iIndex) +{ + UI::CWindowManager& rkWndMgr=UI::CWindowManager::Instance(); + + if (DIK_ESCAPE == iIndex) + { + rkWndMgr.RunPressEscapeKey(); + } + + rkWndMgr.RunKeyDown(iIndex); +} + +void CPythonApplication::OnKeyUp(int iIndex) +{ + UI::CWindowManager& rkWndMgr=UI::CWindowManager::Instance(); + rkWndMgr.RunKeyUp(iIndex); +} + +void CPythonApplication::RunIMEUpdate() +{ + UI::CWindowManager& rkWndMgr=UI::CWindowManager::Instance(); + rkWndMgr.RunIMEUpdate(); +} +void CPythonApplication::RunIMETabEvent() +{ + UI::CWindowManager& rkWndMgr=UI::CWindowManager::Instance(); + rkWndMgr.RunIMETabEvent(); +} +void CPythonApplication::RunIMEReturnEvent() +{ + UI::CWindowManager& rkWndMgr=UI::CWindowManager::Instance(); + rkWndMgr.RunIMEReturnEvent(); +} +void CPythonApplication::OnIMEKeyDown(int iIndex) +{ + UI::CWindowManager& rkWndMgr=UI::CWindowManager::Instance(); + rkWndMgr.RunIMEKeyDown(iIndex); +} +///////////////////////////// + +void CPythonApplication::RunIMEChangeCodePage() +{ + UI::CWindowManager& rkWndMgr=UI::CWindowManager::Instance(); + rkWndMgr.RunChangeCodePage(); +} +void CPythonApplication::RunIMEOpenCandidateListEvent() +{ + UI::CWindowManager& rkWndMgr=UI::CWindowManager::Instance(); + rkWndMgr.RunOpenCandidate(); +} +void CPythonApplication::RunIMECloseCandidateListEvent() +{ + UI::CWindowManager& rkWndMgr=UI::CWindowManager::Instance(); + rkWndMgr.RunCloseCandidate(); +} +void CPythonApplication::RunIMEOpenReadingWndEvent() +{ + UI::CWindowManager& rkWndMgr=UI::CWindowManager::Instance(); + rkWndMgr.RunOpenReading(); +} +void CPythonApplication::RunIMECloseReadingWndEvent() +{ + UI::CWindowManager& rkWndMgr=UI::CWindowManager::Instance(); + rkWndMgr.RunCloseReading(); +} + +///////////////////////////// +void CPythonApplication::RunPressExitKey() +{ + UI::CWindowManager& rkWndMgr=UI::CWindowManager::Instance(); + rkWndMgr.RunPressExitKey(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +void CPythonApplication::OnMouseUpdate() +{ +#ifdef _DEBUG + if (!m_poMouseHandler) + { + //assert(!" CPythonApplication::OnMouseUpdate - Mouse handler has not set!"); + return; + } +#endif _DEBUG + + UI::CWindowManager& rkWndMgr=UI::CWindowManager::Instance(); + long lx, ly; + rkWndMgr.GetMousePosition(lx, ly); + PyCallClassMemberFunc(m_poMouseHandler, "Update", Py_BuildValue("(ii)", lx, ly)); +} + +void CPythonApplication::OnMouseRender() +{ +#ifdef _DEBUG + if (!m_poMouseHandler) + { + //assert(!" CPythonApplication::OnMouseRender - Mouse handler has not set!"); + return; + } +#endif _DEBUG + + PyCallClassMemberFunc(m_poMouseHandler, "Render", Py_BuildValue("()")); +} diff --git a/source/UserInterface/PythonApplicationLogo.cpp b/source/UserInterface/PythonApplicationLogo.cpp new file mode 100644 index 0000000..8a1bd3e --- /dev/null +++ b/source/UserInterface/PythonApplicationLogo.cpp @@ -0,0 +1,242 @@ +#include "StdAfx.h" +#include "PythonApplication.h" + +static bool bInitializedLogo = false; + +int CPythonApplication::OnLogoOpen(char* szName) +{ + m_pLogoTex = NULL; + m_pLogoTex = new CGraphicImageTexture(); + m_pCaptureBuffer = NULL; + m_lBufferSize = 0; + m_bLogoError = true; + m_bLogoPlay = false; + + m_pGraphBuilder = NULL; + m_pFilterSG = NULL; + m_pSampleGrabber = NULL; + m_pMediaCtrl = NULL; + m_pMediaEvent = NULL; + m_pVideoWnd = NULL; + m_pBasicVideo = NULL; + + m_nLeft = 0; m_nRight = 0; m_nTop = 0; m_nBottom = 0; + + + // ó 1/1 ũ ؽĸ صд. + if(!m_pLogoTex->Create(1, 1, D3DFMT_A8R8G8B8)) { return 0; } + + // Set GraphBuilder / SampleGrabber + if(FAILED(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (VOID**)(&m_pGraphBuilder)))) { return 0; } + if(FAILED(CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (VOID**)&m_pFilterSG))) { return 0; } + if(FAILED(m_pGraphBuilder->AddFilter(m_pFilterSG, L"SampleGrabber"))) { return 0; } + + // Create Media Type + AM_MEDIA_TYPE mediaType; + ZeroMemory(&mediaType, sizeof(mediaType)); + mediaType.majortype = MEDIATYPE_Video; + mediaType.subtype = MEDIASUBTYPE_RGB32; + if(FAILED(m_pFilterSG->QueryInterface(IID_ISampleGrabber, (VOID**) &m_pSampleGrabber))) { return 0; } + if(FAILED(m_pSampleGrabber->SetMediaType( &mediaType))) { return 0; } + + // Render File + WCHAR wFileName[ MAX_PATH ]; + MultiByteToWideChar(CP_ACP, 0, szName, -1, wFileName, MAX_PATH); + if(FAILED(m_pGraphBuilder->RenderFile(wFileName, NULL))) { return 0; } + + IBaseFilter* pSrc; + m_pGraphBuilder->AddSourceFilter(wFileName, L"Source", &pSrc); + + // Media Control + if(FAILED(m_pGraphBuilder->QueryInterface(IID_IMediaControl, (VOID**) &m_pMediaCtrl))) { return 0; } + + // Video Window + if(FAILED(m_pGraphBuilder->QueryInterface(IID_IVideoWindow, (VOID**) &m_pVideoWnd))) { return 0; } + if(FAILED(m_pVideoWnd->put_MessageDrain((OAHWND)this->m_hWnd))) { return 0; } + + // Basic Video + if(FAILED(m_pGraphBuilder->QueryInterface(IID_IBasicVideo, (VOID**)&m_pBasicVideo))) { return 0; } + + // Media Event + if(FAILED(m_pGraphBuilder->QueryInterface(IID_IMediaEventEx, (VOID**) &m_pMediaEvent))) { return 0; } + + // Window Ⱥ̰ + m_pVideoWnd->SetWindowPosition( 3000, 3000, 0, 0 ); + m_pVideoWnd->put_Visible(0); + m_pSampleGrabber->SetBufferSamples(TRUE); + + m_pVideoWnd->put_Owner((OAHWND)m_hWnd); + m_pMediaEvent->SetNotifyWindow((OAHWND)m_hWnd, WM_APP + 1, 0); + + bInitializedLogo = true; + + return 1; +} + +int CPythonApplication::OnLogoUpdate() +{ + //OSVERSIONINFO osvi; + //ZeroMemory(&osvi, sizeof(osvi)); + //osvi.dwOSVersionInfoSize = sizeof(osvi); + //GetVersionEx(&osvi); + + //// windows xp logo skip. + //// m_pSampleGrabber->GetCurrentBuffer(&m_lBufferSize, (LONG*)m_pCaptureBuffer) fail . + //if (osvi.dwMajorVersion <= 5) + //{ + // return 0; + //} + + if(m_pGraphBuilder == NULL || m_pFilterSG == NULL || m_pSampleGrabber == NULL || m_pMediaCtrl == NULL || m_pMediaEvent == NULL || m_pVideoWnd == NULL || false == bInitializedLogo) + { + return 0; + } + + BYTE* pBuffer = m_pCaptureBuffer; LONG lBufferSize = m_lBufferSize; + + // ȉ? . + if(!m_bLogoPlay) { m_pMediaCtrl->Run(); m_bLogoPlay = true; } + + // о ۰ 0ΰ ۸ Ҵ. + if( lBufferSize == 0 ) { + m_pSampleGrabber->GetCurrentBuffer(&m_lBufferSize, NULL); + + SAFE_DELETE_ARRAY(m_pCaptureBuffer); + m_pCaptureBuffer = new BYTE[ m_lBufferSize ]; + pBuffer = m_pCaptureBuffer; + lBufferSize = m_lBufferSize; + } + + // ε߿ UpdateǴ , ⿡ ϴ 찡 . + // ϴ Ǵ ƴϹǷ, ߴ ʴ´. + if(FAILED(m_pSampleGrabber->GetCurrentBuffer(&m_lBufferSize, (LONG*)m_pCaptureBuffer))) + { + m_bLogoError = true; + + LPDIRECT3DTEXTURE8 tex = m_pLogoTex->GetD3DTexture(); + D3DLOCKED_RECT rt; + ZeroMemory(&rt, sizeof(rt)); + + // 쿡 ؽĸ İ . + tex->LockRect(0, &rt, 0, 0); + BYTE* destb = static_cast(rt.pBits); + for(int a = 0; a < 4; a+= 4) + { + BYTE* dest = &destb[a]; + dest[0] = 0; dest[1] = 0; dest[2] = 0; dest[3] = 0xff; + } + tex->UnlockRect(0); + + return 1; + } + + m_bLogoError = false; + + long lWidth, lHeight; + m_pBasicVideo->GetVideoSize(&lWidth, &lHeight); + + if(lWidth >= lHeight) + { + m_nLeft = 0; m_nRight = this->GetWidth(); + m_nTop = (this->GetHeight() >> 1) - ((this->GetWidth() * lHeight / lWidth) >> 1); + m_nBottom = (this->GetHeight() >> 1) + ((this->GetWidth() * lHeight / lWidth) >> 1); + } + else + { + m_nTop = 0; m_nBottom = this->GetHeight(); + m_nLeft = (this->GetWidth() >> 1) - ((this->GetHeight() * lWidth / lHeight) >> 1); + m_nRight = (this->GetWidth() >> 1) - ((this->GetHeight() * lWidth / lHeight) >> 1); + } + + + + // ũⰡ 1, ؽ غ ȵȰ ٽ . + if(m_pLogoTex->GetWidth() == 1) + { + m_pLogoTex->Destroy(); m_pLogoTex->Create(lWidth, lHeight, D3DFMT_A8R8G8B8); + + } + + // غ?ۿ ؽķ ؿ´. + LPDIRECT3DTEXTURE8 tex = m_pLogoTex->GetD3DTexture(); + D3DLOCKED_RECT rt; + ZeroMemory(&rt, sizeof(rt)); + + tex->LockRect(0, &rt, 0, 0); + BYTE* destb = static_cast(rt.pBits); + for(int a = 0; a < lBufferSize; a+= 4) + { + BYTE* src = &m_pCaptureBuffer[a]; BYTE* dest = &destb[a]; + dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 0xff; + } + tex->UnlockRect(0); + + // üũ (Ǿ) + long evCode, param1, param2; + while(SUCCEEDED(m_pMediaEvent->GetEvent(&evCode, ¶m1, ¶m2, 0))) + { + switch(evCode) + { + case EC_COMPLETE: + return 0; + case EC_USERABORT: + return 0; + case EC_ERRORABORT: + return 0; + } + + m_pMediaEvent->FreeEventParams(evCode, param1, param2); + } + + if(GetAsyncKeyState(VK_ESCAPE) & 0x8000) { return 0; } + + return 1; +} + +void CPythonApplication::OnLogoRender() +{ + if(!m_pLogoTex->IsEmpty() && !m_bLogoError && true == bInitializedLogo) + { + STATEMANAGER.SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + STATEMANAGER.SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + m_pLogoTex->SetTextureStage(0); + CPythonGraphic::instance().RenderTextureBox(m_nLeft, m_nTop, m_nRight, m_nBottom, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f); + } +} + +void CPythonApplication::OnLogoClose() +{ + // NOTE: LOGO ҷ 쿡 OnLogoClose ũð + if (false == bInitializedLogo) + return; + + if(m_pCaptureBuffer != NULL) + { + delete[] m_pCaptureBuffer; + m_pCaptureBuffer = NULL; + } + if(m_pLogoTex != NULL) + { + m_pLogoTex->Destroy(); + delete m_pLogoTex; + m_pLogoTex = NULL; + } + + if(m_pMediaEvent != NULL) + { + m_pMediaEvent->SetNotifyWindow(NULL, 0, 0); + m_pMediaEvent->Release(); + m_pMediaEvent = NULL; + } + if(m_pBasicVideo != NULL) m_pBasicVideo->Release(); m_pBasicVideo = NULL; + if(m_pVideoWnd != NULL) m_pVideoWnd->Release(); m_pVideoWnd = NULL; + if(m_pMediaCtrl != NULL) m_pMediaCtrl->Release(); m_pMediaCtrl = NULL; + if(m_pSampleGrabber != NULL) m_pSampleGrabber->Release(); m_pSampleGrabber = NULL; + if(m_pFilterSG != NULL) m_pFilterSG->Release(); m_pFilterSG = NULL; + if(m_pGraphBuilder != NULL) m_pGraphBuilder->Release(); m_pGraphBuilder = NULL; + + STATEMANAGER.SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_POINT); + STATEMANAGER.SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_POINT); + + +} \ No newline at end of file diff --git a/source/UserInterface/PythonApplicationModule.cpp b/source/UserInterface/PythonApplicationModule.cpp new file mode 100644 index 0000000..a5e0645 --- /dev/null +++ b/source/UserInterface/PythonApplicationModule.cpp @@ -0,0 +1,1530 @@ +#include "StdAfx.h" +#include "Resource.h" +#include "PythonApplication.h" +#include "../EterLib/Camera.h" + +extern bool PERF_CHECKER_RENDER_GAME; +extern D3DXCOLOR g_fSpecularColor; +extern BOOL bVisibleNotice = true; +extern BOOL bTestServerFlag = FALSE; +extern int TWOHANDED_WEWAPON_ATT_SPEED_DECREASE_VALUE = 0; + +#ifdef USE_OPENID +extern int openid_test; +#endif + +PyObject* appShowWebPage(PyObject* poSelf, PyObject* poArgs) +{ + char* szWebPage; + if (!PyTuple_GetString(poArgs, 0, &szWebPage)) + return Py_BuildException(); + + PyObject* poRect=PyTuple_GetItem(poArgs, 1); + if (!PyTuple_Check(poRect)) + return Py_BuildException(); + + RECT rcWebPage; + rcWebPage.left=PyInt_AsLong(PyTuple_GetItem(poRect, 0)); + rcWebPage.top=PyInt_AsLong(PyTuple_GetItem(poRect, 1)); + rcWebPage.right=PyInt_AsLong(PyTuple_GetItem(poRect, 2)); + rcWebPage.bottom=PyInt_AsLong(PyTuple_GetItem(poRect, 3)); + + CPythonApplication::Instance().ShowWebPage( + szWebPage, + rcWebPage + ); + return Py_BuildNone(); +} + +PyObject* appMoveWebPage(PyObject* poSelf, PyObject* poArgs) +{ + PyObject* poRect=PyTuple_GetItem(poArgs, 0); + if (!PyTuple_Check(poRect)) + return Py_BuildException(); + + RECT rcWebPage; + rcWebPage.left=PyInt_AsLong(PyTuple_GetItem(poRect, 0)); + rcWebPage.top=PyInt_AsLong(PyTuple_GetItem(poRect, 1)); + rcWebPage.right=PyInt_AsLong(PyTuple_GetItem(poRect, 2)); + rcWebPage.bottom=PyInt_AsLong(PyTuple_GetItem(poRect, 3)); + + CPythonApplication::Instance().MoveWebPage(rcWebPage); + return Py_BuildNone(); +} + +PyObject* appHideWebPage(PyObject* poSelf, PyObject* poArgs) +{ + CPythonApplication::Instance().HideWebPage(); + return Py_BuildNone(); +} + + +PyObject * appIsWebPageMode(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonApplication::Instance().IsWebPageMode()); +} + +PyObject* appEnablePerformanceTime(PyObject* poSelf, PyObject* poArgs) +{ + char* szMode; + if (!PyTuple_GetString(poArgs, 0, &szMode)) + return Py_BuildException(); + + int nEnable; + if (!PyTuple_GetInteger(poArgs, 1, &nEnable)) + return Py_BuildException(); + + bool isEnable=nEnable ? true : false; + + if (strcmp(szMode, "RENDER_GAME")==0) + PERF_CHECKER_RENDER_GAME = isEnable; + + return Py_BuildNone(); +} + +///////////////////////////////////////////////////// + +extern BOOL HAIR_COLOR_ENABLE; +extern BOOL USE_ARMOR_SPECULAR; +extern BOOL USE_WEAPON_SPECULAR; +extern BOOL SKILL_EFFECT_UPGRADE_ENABLE; +extern BOOL RIDE_HORSE_ENABLE; +extern double g_specularSpd; + +// TEXTTAIL_LIVINGTIME_CONTROL +extern void TextTail_SetLivingTime(long livingTime); + +PyObject* appSetTextTailLivingTime(PyObject* poSelf, PyObject* poArgs) +{ + float livingTime; + if (!PyTuple_GetFloat(poArgs, 0, &livingTime)) + return Py_BuildException(); + + TextTail_SetLivingTime(livingTime*1000); + + return Py_BuildNone(); +} +// END_OF_TEXTTAIL_LIVINGTIME_CONTROL + +PyObject* appSetHairColorEnable(PyObject* poSelf, PyObject* poArgs) +{ + int nEnable; + if (!PyTuple_GetInteger(poArgs, 0, &nEnable)) + return Py_BuildException(); + + HAIR_COLOR_ENABLE=nEnable; + + return Py_BuildNone(); +} + +PyObject* appSetArmorSpecularEnable(PyObject* poSelf, PyObject* poArgs) +{ + int nEnable; + if (!PyTuple_GetInteger(poArgs, 0, &nEnable)) + return Py_BuildException(); + + USE_ARMOR_SPECULAR=nEnable; + + return Py_BuildNone(); +} + +PyObject* appSetWeaponSpecularEnable(PyObject* poSelf, PyObject* poArgs) +{ + int nEnable; + if (!PyTuple_GetInteger(poArgs, 0, &nEnable)) + return Py_BuildException(); + + USE_WEAPON_SPECULAR=nEnable; + + return Py_BuildNone(); +} + +PyObject* appSetSkillEffectUpgradeEnable(PyObject* poSelf, PyObject* poArgs) +{ + int nEnable; + if (!PyTuple_GetInteger(poArgs, 0, &nEnable)) + return Py_BuildException(); + + SKILL_EFFECT_UPGRADE_ENABLE=nEnable; + + return Py_BuildNone(); +} + +PyObject* SetTwoHandedWeaponAttSpeedDecreaseValue(PyObject* poSelf, PyObject* poArgs) +{ + int iValue; + if (!PyTuple_GetInteger(poArgs, 0, &iValue)) + return Py_BuildException(); + + TWOHANDED_WEWAPON_ATT_SPEED_DECREASE_VALUE = iValue; + + return Py_BuildNone(); +} + +PyObject* appSetRideHorseEnable(PyObject* poSelf, PyObject* poArgs) +{ + int nEnable; + if (!PyTuple_GetInteger(poArgs, 0, &nEnable)) + return Py_BuildException(); + + RIDE_HORSE_ENABLE=nEnable; + + return Py_BuildNone(); +} + +PyObject* appSetCameraMaxDistance(PyObject* poSelf, PyObject* poArgs) +{ + float fMax; + if (!PyTuple_GetFloat(poArgs, 0, &fMax)) + return Py_BuildException(); + + CCamera::SetCameraMaxDistance(fMax); + return Py_BuildNone(); +} + +PyObject* appSetControlFP(PyObject* poSelf, PyObject* poArgs) +{ + _controlfp( _PC_24, _MCW_PC ); + return Py_BuildNone(); +} + +PyObject* appSetSpecularSpeed(PyObject* poSelf, PyObject* poArgs) +{ + float fSpeed; + if (!PyTuple_GetFloat(poArgs, 0, &fSpeed)) + return Py_BuildException(); + + g_specularSpd = fSpeed; + + return Py_BuildNone(); +} + +PyObject * appSetMinFog(PyObject * poSelf, PyObject * poArgs) +{ + float fMinFog; + if (!PyTuple_GetFloat(poArgs, 0, &fMinFog)) + return Py_BuildException(); + + CPythonApplication::Instance().SetMinFog(fMinFog); + return Py_BuildNone(); +} + +PyObject* appSetFrameSkip(PyObject* poSelf, PyObject* poArgs) +{ + int nFrameSkip; + if (!PyTuple_GetInteger(poArgs, 0, &nFrameSkip)) + return Py_BuildException(); + + CPythonApplication::Instance().SetFrameSkip(nFrameSkip ? true : false); + return Py_BuildNone(); +} + +// LOCALE + +PyObject* appForceSetLocale(PyObject* poSelf, PyObject* poArgs) +{ + char* szName; + if (!PyTuple_GetString(poArgs, 0, &szName)) + return Py_BuildException(); + + char* szLocalePath; + if (!PyTuple_GetString(poArgs, 1, &szLocalePath)) + return Py_BuildException(); + + LocaleService_ForceSetLocale(szName, szLocalePath); + + return Py_BuildNone(); +} + +PyObject* appGetLocaleServiceName(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildValue("s", LocaleService_GetName()); +} + +// +bool LoadLocaleData(const char* localePath); + +PyObject* appSetCHEONMA(PyObject* poSelf, PyObject* poArgs) +{ + int enable; + if (!PyTuple_GetInteger(poArgs, 0, &enable)) + return Py_BuildException(); + + LocaleService_SetCHEONMA(enable ? true : false); + return Py_BuildNone(); +} + +PyObject* appIsCHEONMA(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildValue("i", LocaleService_IsCHEONMA()); +} + +#include "../eterBase/tea.h" + +PyObject* appLoadLocaleAddr(PyObject* poSelf, PyObject* poArgs) +{ + char* addrPath; + if (!PyTuple_GetString(poArgs, 0, &addrPath)) + return Py_BuildException(); + + FILE* fp = fopen(addrPath, "rb"); + if (!fp) + return Py_BuildException(); + + fseek(fp, 0, SEEK_END); + + int size = ftell(fp); + char* enc = (char*)_alloca(size); + fseek(fp, 0, SEEK_SET); + fread(enc, size, 1, fp); + fclose(fp); + + static const unsigned char key[16] = { + 0x82, 0x1b, 0x34, 0xae, + 0x12, 0x3b, 0xfb, 0x17, + 0xd7, 0x2c, 0x39, 0xae, + 0x41, 0x98, 0xf1, 0x63 + }; + + char* buf = (char*)_alloca(size); + //int decSize = + tea_decrypt((unsigned long*)buf, (const unsigned long*)enc, (const unsigned long*)key, size); + unsigned int retSize = *(unsigned int*)buf; + char* ret = buf + sizeof(unsigned int); + return Py_BuildValue("s#", ret, retSize); +} + +PyObject* appLoadLocaleData(PyObject* poSelf, PyObject* poArgs) +{ + char* localePath; + if (!PyTuple_GetString(poArgs, 0, &localePath)) + return Py_BuildException(); + + return Py_BuildValue("i", LoadLocaleData(localePath)); +} + +PyObject* appGetLocaleName(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildValue("s", LocaleService_GetLocaleName()); +} + +PyObject* appGetLocalePath(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildValue("s", LocaleService_GetLocalePath()); +} +// END_OF_LOCALE + +PyObject* appGetDefaultCodePage(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildValue("i", LocaleService_GetCodePage()); +} + +#ifdef __VTUNE__ + +PyObject* appGetImageInfo(PyObject* poSelf, PyObject* poArgs) +{ + char* szFileName; + if (!PyTuple_GetString(poArgs, 0, &szFileName)) + return Py_BuildException(); + + return Py_BuildValue("iii", 0, 0, 0); +} + +#else + +#include + +PyObject* appGetImageInfo(PyObject* poSelf, PyObject* poArgs) +{ + char* szFileName; + if (!PyTuple_GetString(poArgs, 0, &szFileName)) + return Py_BuildException(); + + BOOL canLoad=FALSE; + ILuint uWidth=0; + ILuint uHeight=0; + + ILuint uImg; + ilGenImages(1, &uImg); + ilBindImage(uImg); + if (ilLoad(IL_TYPE_UNKNOWN, szFileName)) + { + canLoad=TRUE; + uWidth=ilGetInteger(IL_IMAGE_WIDTH); + uHeight=ilGetInteger(IL_IMAGE_HEIGHT); + } + + ilDeleteImages(1, &uImg); + + return Py_BuildValue("iii", canLoad, uWidth, uHeight); +} +#endif + +#include "../EterPack/EterPackManager.h" + +PyObject* appIsExistFile(PyObject* poSelf, PyObject* poArgs) +{ + char* szFileName; + if (!PyTuple_GetString(poArgs, 0, &szFileName)) + return Py_BuildException(); + + bool isExist=CEterPackManager::Instance().isExist(szFileName); + + return Py_BuildValue("i", isExist); +} + +PyObject* appGetFileList(PyObject* poSelf, PyObject* poArgs) +{ + char* szFilter; + if (!PyTuple_GetString(poArgs, 0, &szFilter)) + return Py_BuildException(); + + PyObject* poList=PyList_New(0); + + WIN32_FIND_DATA wfd; + memset(&wfd, 0, sizeof(wfd)); + + HANDLE hFind = FindFirstFile(szFilter, &wfd); + if (hFind != INVALID_HANDLE_VALUE) + { + do + { + PyObject* poFileName=PyString_FromString(wfd.cFileName) ; + PyList_Append(poList, poFileName); + } + while (FindNextFile(hFind, &wfd)); + + + FindClose(hFind); + } + + return poList; +} + + +PyObject* appUpdateGame(PyObject* poSelf, PyObject* poArgs) +{ + CPythonApplication::Instance().UpdateGame(); + return Py_BuildNone(); +} + +PyObject* appRenderGame(PyObject* poSelf, PyObject* poArgs) +{ + CPythonApplication::Instance().RenderGame(); + return Py_BuildNone(); +} + + + +PyObject* appSetMouseHandler(PyObject* poSelf, PyObject* poArgs) +{ + PyObject* poHandler; + if (!PyTuple_GetObject(poArgs, 0, &poHandler)) + return Py_BuildException(); + + CPythonApplication::Instance().SetMouseHandler(poHandler); + return Py_BuildNone(); +} + +PyObject* appCreate(PyObject* poSelf, PyObject* poArgs) +{ + char* szName; + if (!PyTuple_GetString(poArgs, 0, &szName)) + return Py_BuildException(); + + int width; + if (!PyTuple_GetInteger(poArgs, 1, &width)) + return Py_BuildException(); + + int height; + if (!PyTuple_GetInteger(poArgs, 2, &height)) + return Py_BuildException(); + + int Windowed; + if (!PyTuple_GetInteger(poArgs, 3, &Windowed)) + return Py_BuildException(); + + CPythonApplication& rkApp=CPythonApplication::Instance(); + if (!rkApp.Create(poSelf, szName, width, height, Windowed)) + { + //return Py_BuildNone(); + return NULL; + } + + return Py_BuildNone(); +} + +PyObject* appLoop(PyObject* poSelf, PyObject* poArgs) +{ + CPythonApplication::Instance().Loop(); + + return Py_BuildNone(); +} + +PyObject* appGetInfo(PyObject* poSelf, PyObject* poArgs) +{ + int nInfo; + if (!PyTuple_GetInteger(poArgs, 0, &nInfo)) + return Py_BuildException(); + + std::string stInfo; + CPythonApplication::Instance().GetInfo(nInfo, &stInfo); + return Py_BuildValue("s", stInfo.c_str()); +} + +PyObject* appProcess(PyObject* poSelf, PyObject* poArgs) +{ + if (CPythonApplication::Instance().Process()) + return Py_BuildValue("i", 1); + + return Py_BuildValue("i", 0); +} + +PyObject* appAbort(PyObject* poSelf, PyObject* poArgs) +{ + CPythonApplication::Instance().Abort(); + return Py_BuildNone(); +} + +PyObject* appExit(PyObject* poSelf, PyObject* poArgs) +{ + CPythonApplication::Instance().Exit(); + return Py_BuildNone(); +} + +PyObject * appSetCamera(PyObject * poSelf, PyObject * poArgs) +{ + float Distance; + if (!PyTuple_GetFloat(poArgs, 0, &Distance)) + return Py_BuildException(); + + float Pitch; + if (!PyTuple_GetFloat(poArgs, 1, &Pitch)) + return Py_BuildException(); + + float Rotation; + if (!PyTuple_GetFloat(poArgs, 2, &Rotation)) + return Py_BuildException(); + + float fDestinationHeight; + if (!PyTuple_GetFloat(poArgs, 3, &fDestinationHeight)) + return Py_BuildException(); + + CPythonApplication::Instance().SetCamera(Distance, Pitch, Rotation, fDestinationHeight); + return Py_BuildNone(); +} + +PyObject * appGetCamera(PyObject * poSelf, PyObject * poArgs) +{ + float Distance, Pitch, Rotation, DestinationHeight; + CPythonApplication::Instance().GetCamera(&Distance, &Pitch, &Rotation, &DestinationHeight); + + return Py_BuildValue("ffff", Distance, Pitch, Rotation, DestinationHeight); +} + +PyObject * appGetCameraPitch(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("f", CPythonApplication::Instance().GetPitch()); +} + +PyObject * appGetCameraRotation(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("f", CPythonApplication::Instance().GetRotation()); +} + +PyObject * appGetTime(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("f", CPythonApplication::Instance().GetGlobalTime()); +} + +PyObject * appGetGlobalTime(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonApplication::Instance().GetServerTime()); +} + +PyObject * appGetGlobalTimeStamp(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonApplication::Instance().GetServerTimeStamp()); +} + +PyObject * appGetUpdateFPS(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonApplication::Instance().GetUpdateFPS()); +} + +PyObject * appGetRenderFPS(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonApplication::Instance().GetRenderFPS()); +} + +PyObject * appRotateCamera(PyObject * poSelf, PyObject * poArgs) +{ + int iDirection; + if (!PyTuple_GetInteger(poArgs, 0, &iDirection)) + return Py_BuildException(); + CPythonApplication::Instance().RotateCamera(iDirection); + return Py_BuildNone(); +} + +PyObject * appPitchCamera(PyObject * poSelf, PyObject * poArgs) +{ + int iDirection; + if (!PyTuple_GetInteger(poArgs, 0, &iDirection)) + return Py_BuildException(); + CPythonApplication::Instance().PitchCamera(iDirection); + return Py_BuildNone(); +} + +PyObject * appZoomCamera(PyObject * poSelf, PyObject * poArgs) +{ + int iDirection; + if (!PyTuple_GetInteger(poArgs, 0, &iDirection)) + return Py_BuildException(); + CPythonApplication::Instance().ZoomCamera(iDirection); + return Py_BuildNone(); +} + +PyObject * appMovieRotateCamera(PyObject * poSelf, PyObject * poArgs) +{ + int iDirection; + if (!PyTuple_GetInteger(poArgs, 0, &iDirection)) + return Py_BuildException(); + CPythonApplication::Instance().MovieRotateCamera(iDirection); + return Py_BuildNone(); +} + +PyObject * appMoviePitchCamera(PyObject * poSelf, PyObject * poArgs) +{ + int iDirection; + if (!PyTuple_GetInteger(poArgs, 0, &iDirection)) + return Py_BuildException(); + CPythonApplication::Instance().MoviePitchCamera(iDirection); + return Py_BuildNone(); +} + +PyObject * appMovieZoomCamera(PyObject * poSelf, PyObject * poArgs) +{ + int iDirection; + if (!PyTuple_GetInteger(poArgs, 0, &iDirection)) + return Py_BuildException(); + CPythonApplication::Instance().MovieZoomCamera(iDirection); + return Py_BuildNone(); +} + +PyObject * appMovieResetCamera(PyObject * poSelf, PyObject * poArgs) +{ + CPythonApplication::Instance().MovieResetCamera(); + return Py_BuildNone(); +} + +PyObject * appGetFaceSpeed(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("f", CPythonApplication::Instance().GetFaceSpeed()); +} + +PyObject * appGetRenderTime(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("fi", + CPythonApplication::Instance().GetAveRenderTime(), + CPythonApplication::Instance().GetCurRenderTime()); +} + +PyObject * appGetUpdateTime(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonApplication::Instance().GetCurUpdateTime()); +} + +PyObject * appGetLoad(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonApplication::Instance().GetLoad()); +} +PyObject * appGetFaceCount(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonApplication::Instance().GetFaceCount()); +} + +PyObject * appGetAvaiableTextureMememory(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CGraphicBase::GetAvailableTextureMemory()); +} + +PyObject * appSetFPS(PyObject * poSelf, PyObject * poArgs) +{ + int iFPS; + if (!PyTuple_GetInteger(poArgs, 0, &iFPS)) + return Py_BuildException(); + + CPythonApplication::Instance().SetFPS(iFPS); + + return Py_BuildNone(); +} + +PyObject * appSetGlobalCenterPosition(PyObject * poSelf, PyObject * poArgs) +{ + int x; + if (!PyTuple_GetInteger(poArgs, 0, &x)) + return Py_BuildException(); + + int y; + if (!PyTuple_GetInteger(poArgs, 1, &y)) + return Py_BuildException(); + + CPythonApplication::Instance().SetGlobalCenterPosition(x, y); + return Py_BuildNone(); +} + + +PyObject * appSetCenterPosition(PyObject * poSelf, PyObject * poArgs) +{ + float fx; + if (!PyTuple_GetFloat(poArgs, 0, &fx)) + return Py_BuildException(); + + float fy; + if (!PyTuple_GetFloat(poArgs, 1, &fy)) + return Py_BuildException(); + + float fz; + if (!PyTuple_GetFloat(poArgs, 2, &fz)) + return Py_BuildException(); + + CPythonApplication::Instance().SetCenterPosition(fx, -fy, fz); + return Py_BuildNone(); +} + +PyObject * appGetCursorPosition(PyObject * poSelf, PyObject * poArgs) +{ + long lx, ly; + UI::CWindowManager& rkWndMgr=UI::CWindowManager::Instance(); + rkWndMgr.GetMousePosition(lx, ly); + + return Py_BuildValue("ii", lx, ly); +} + +PyObject * appRunPythonFile(PyObject * poSelf, PyObject * poArgs) +{ + char *szFileName; + if (!PyTuple_GetString(poArgs, 0, &szFileName)) + return Py_BuildException(); + + bool ret = CPythonLauncher::Instance().RunFile(szFileName); + return Py_BuildValue("i", ret); +} + +PyObject * appIsPressed(PyObject * poSelf, PyObject * poArgs) +{ + int iKey; + if (!PyTuple_GetInteger(poArgs, 0, &iKey)) + return Py_BuildException(); + + return Py_BuildValue("i", CPythonApplication::Instance().IsPressed(iKey)); +} + +PyObject * appSetCursor(PyObject * poSelf, PyObject * poArgs) +{ +/* + char * szName; + if (!PyTuple_GetString(poArgs, 0, &szName)) + return Py_BuildException(); + + if (!CPythonApplication::Instance().SetHardwareCursor(szName)) + return Py_BuildException("Wrong Cursor Name [%s]", szName); +*/ + int iCursorNum; + if (!PyTuple_GetInteger(poArgs, 0, &iCursorNum)) + return Py_BuildException(); + + if (!CPythonApplication::Instance().SetCursorNum(iCursorNum)) + return Py_BuildException("Wrong Cursor Name [%d]", iCursorNum); + + return Py_BuildNone(); +} + +PyObject * appGetCursor(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonApplication::Instance().GetCursorNum()); +} + +PyObject * appShowCursor(PyObject * poSelf, PyObject * poArgs) +{ + CPythonApplication::Instance().SetCursorVisible(TRUE); + + return Py_BuildNone(); +} + +PyObject * appHideCursor(PyObject * poSelf, PyObject * poArgs) +{ + CPythonApplication::Instance().SetCursorVisible(FALSE); + + return Py_BuildNone(); +} + +PyObject * appIsShowCursor(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", TRUE == CPythonApplication::Instance().GetCursorVisible()); +} + +PyObject * appIsLiarCursorOn(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", TRUE == CPythonApplication::Instance().GetLiarCursorOn()); +} + +PyObject * appSetSoftwareCursor(PyObject * poSelf, PyObject * poArgs) +{ + CPythonApplication::Instance().SetCursorMode(CPythonApplication::CURSOR_MODE_SOFTWARE); + return Py_BuildNone(); +} + +PyObject * appSetHardwareCursor(PyObject * poSelf, PyObject * poArgs) +{ + CPythonApplication::Instance().SetCursorMode(CPythonApplication::CURSOR_MODE_HARDWARE); + return Py_BuildNone(); +} + +PyObject * appSetConnectData(PyObject * poSelf, PyObject * poArgs) +{ + char * szIP; + if (!PyTuple_GetString(poArgs, 0, &szIP)) + return Py_BuildException(); + + int iPort; + if (!PyTuple_GetInteger(poArgs, 1, &iPort)) + return Py_BuildException(); + + CPythonApplication::Instance().SetConnectData(szIP, iPort); + + return Py_BuildNone(); +} + +PyObject * appGetConnectData(PyObject * poSelf, PyObject * poArgs) +{ + std::string strIP; + int iPort; + + CPythonApplication::Instance().GetConnectData(strIP, iPort); + + return Py_BuildValue("si", strIP.c_str(), iPort); +} + +PyObject * appGetRandom(PyObject * poSelf, PyObject * poArgs) +{ + int from; + if (!PyTuple_GetInteger(poArgs, 0, &from)) + return Py_BuildException(); + + int to; + if (!PyTuple_GetInteger(poArgs, 1, &to)) + return Py_BuildException(); + + if (from > to) + { + int tmp = from; + from = to; + to = tmp; + } + + return Py_BuildValue("i", random_range(from, to)); +} + +PyObject * appGetRotatingDirection(PyObject * poSelf, PyObject * poArgs) +{ + float fSource; + if (!PyTuple_GetFloat(poArgs, 0, &fSource)) + return Py_BuildException(); + float fTarget; + if (!PyTuple_GetFloat(poArgs, 1, &fTarget)) + return Py_BuildException(); + + return Py_BuildValue("i", GetRotatingDirection(fSource, fTarget)); +} + +PyObject * appGetDegreeDifference(PyObject * poSelf, PyObject * poArgs) +{ + float fSource; + if (!PyTuple_GetFloat(poArgs, 0, &fSource)) + return Py_BuildException(); + float fTarget; + if (!PyTuple_GetFloat(poArgs, 1, &fTarget)) + return Py_BuildException(); + + return Py_BuildValue("f", GetDegreeDifference(fSource, fTarget)); +} + +PyObject * appSleep(PyObject * poSelf, PyObject * poArgs) +{ + int iTime; + if (!PyTuple_GetInteger(poArgs, 0, &iTime)) + return Py_BuildException(); + + Sleep(iTime); + + return Py_BuildNone(); +} + +PyObject * appSetDefaultFontName(PyObject * poSelf, PyObject * poArgs) +{ + char * szFontName; + if (!PyTuple_GetString(poArgs, 0, &szFontName)) + return Py_BuildException(); + + // DEFAULT_FONT + DefaultFont_SetName(szFontName); + // END_OF_DEFAULT_FONT + + return Py_BuildNone(); +} + +PyObject * appSetGuildSymbolPath(PyObject * poSelf, PyObject * poArgs) +{ + char * szPathName; + if (!PyTuple_GetString(poArgs, 0, &szPathName)) + return Py_BuildException(); + + SetGuildSymbolPath(szPathName); + + return Py_BuildNone(); +} + +PyObject * appEnableSpecialCameraMode(PyObject * poSelf, PyObject * poArgs) +{ + CPythonApplication::Instance().EnableSpecialCameraMode(); + return Py_BuildNone(); +} + +PyObject * appSetCameraSpeed(PyObject * poSelf, PyObject * poArgs) +{ + int iPercentage; + if (!PyTuple_GetInteger(poArgs, 0, &iPercentage)) + return Py_BuildException(); + + CPythonApplication::Instance().SetCameraSpeed(iPercentage); + + CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera(); + if (pCamera) + pCamera->SetResistance(float(iPercentage) / 100.0f); + return Py_BuildNone(); +} + +PyObject * appIsFileExist(PyObject * poSelf, PyObject * poArgs) +{ + char * szFileName; + if (!PyTuple_GetString(poArgs, 0, &szFileName)) + return Py_BuildException(); + + return Py_BuildValue("i", -1 != _access(szFileName, 0)); +} + +PyObject * appSetCameraSetting(PyObject * poSelf, PyObject * poArgs) +{ + int ix; + if (!PyTuple_GetInteger(poArgs, 0, &ix)) + return Py_BuildException(); + int iy; + if (!PyTuple_GetInteger(poArgs, 1, &iy)) + return Py_BuildException(); + int iz; + if (!PyTuple_GetInteger(poArgs, 2, &iz)) + return Py_BuildException(); + + int iZoom; + if (!PyTuple_GetInteger(poArgs, 3, &iZoom)) + return Py_BuildException(); + int iRotation; + if (!PyTuple_GetInteger(poArgs, 4, &iRotation)) + return Py_BuildException(); + int iPitch; + if (!PyTuple_GetInteger(poArgs, 5, &iPitch)) + return Py_BuildException(); + + CPythonApplication::SCameraSetting CameraSetting; + ZeroMemory(&CameraSetting, sizeof(CameraSetting)); + CameraSetting.v3CenterPosition.x = float(ix); + CameraSetting.v3CenterPosition.y = float(iy); + CameraSetting.v3CenterPosition.z = float(iz); + CameraSetting.fZoom = float(iZoom); + CameraSetting.fRotation = float(iRotation); + CameraSetting.fPitch = float(iPitch); + CPythonApplication::Instance().SetEventCamera(CameraSetting); + return Py_BuildNone(); +} + +PyObject * appSaveCameraSetting(PyObject * poSelf, PyObject * poArgs) +{ + char * szFileName; + if (!PyTuple_GetString(poArgs, 0, &szFileName)) + return Py_BuildException(); + + CPythonApplication::Instance().SaveCameraSetting(szFileName); + return Py_BuildNone(); +} + +PyObject * appLoadCameraSetting(PyObject * poSelf, PyObject * poArgs) +{ + char * szFileName; + if (!PyTuple_GetString(poArgs, 0, &szFileName)) + return Py_BuildException(); + + bool bResult = CPythonApplication::Instance().LoadCameraSetting(szFileName); + return Py_BuildValue("i", bResult); +} + +PyObject * appSetDefaultCamera(PyObject * poSelf, PyObject * poArgs) +{ + CPythonApplication::Instance().SetDefaultCamera(); + return Py_BuildNone(); +} + +PyObject * appSetSightRange(PyObject * poSelf, PyObject * poArgs) +{ + int iRange; + if (!PyTuple_GetInteger(poArgs, 0, &iRange)) + return Py_BuildException(); + + CPythonApplication::Instance().SetForceSightRange(iRange); + return Py_BuildNone(); +} + +extern int g_iAccumulationTime; + +PyObject * apptestGetAccumulationTime(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", g_iAccumulationTime); +} + +PyObject * apptestResetAccumulationTime(PyObject * poSelf, PyObject * poArgs) +{ + g_iAccumulationTime = 0; + return Py_BuildNone(); +} + +PyObject * apptestSetSpecularColor(PyObject * poSelf, PyObject * poArgs) +{ + float fr; + if (!PyTuple_GetFloat(poArgs, 0, &fr)) + return Py_BuildException(); + float fg; + if (!PyTuple_GetFloat(poArgs, 1, &fg)) + return Py_BuildException(); + float fb; + if (!PyTuple_GetFloat(poArgs, 2, &fb)) + return Py_BuildException(); + g_fSpecularColor = D3DXCOLOR(fr, fg, fb, 1.0f); + return Py_BuildNone(); +} + +PyObject * appSetVisibleNotice(PyObject * poSelf, PyObject * poArgs) +{ + int iFlag; + if (!PyTuple_GetInteger(poArgs, 0, &iFlag)) + return Py_BuildException(); + bVisibleNotice = iFlag; + return Py_BuildNone(); +} + +PyObject * appIsVisibleNotice(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", bVisibleNotice); +} + +PyObject * appEnableTestServerFlag(PyObject * poSelf, PyObject * poArgs) +{ + bTestServerFlag = TRUE; + return Py_BuildNone(); +} + +PyObject * appIsEnableTestServerFlag(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", bTestServerFlag); +} + +class CTextLineLoader +{ + public: + CTextLineLoader(const char * c_szFileName) + { + const VOID* pvData; + CMappedFile kFile; + if (!CEterPackManager::Instance().Get(kFile, c_szFileName, &pvData)) + return; + + m_kTextFileLoader.Bind(kFile.Size(), pvData); + } + + DWORD GetLineCount() + { + return m_kTextFileLoader.GetLineCount(); + } + + const char * GetLine(DWORD dwIndex) + { + if (dwIndex >= GetLineCount()) + return ""; + + return m_kTextFileLoader.GetLineString(dwIndex).c_str(); + } + + protected: + CMemoryTextFileLoader m_kTextFileLoader; +}; + +PyObject * appOpenTextFile(PyObject * poSelf, PyObject * poArgs) +{ + char * szFileName; + if (!PyTuple_GetString(poArgs, 0, &szFileName)) + return Py_BuildException(); + + CTextLineLoader * pTextLineLoader = new CTextLineLoader(szFileName); + + return Py_BuildValue("i", (int)pTextLineLoader); +} + +PyObject * appCloseTextFile(PyObject * poSelf, PyObject * poArgs) +{ + int iHandle; + if (!PyTuple_GetInteger(poArgs, 0, &iHandle)) + return Py_BuildException(); + + CTextLineLoader * pTextFileLoader = (CTextLineLoader *)iHandle; + delete pTextFileLoader; + + return Py_BuildNone(); +} + +PyObject * appGetTextFileLineCount(PyObject * poSelf, PyObject * poArgs) +{ + int iHandle; + if (!PyTuple_GetInteger(poArgs, 0, &iHandle)) + return Py_BuildException(); + + CTextLineLoader * pTextFileLoader = (CTextLineLoader *)iHandle; + return Py_BuildValue("i", pTextFileLoader->GetLineCount()); +} + +PyObject * appGetTextFileLine(PyObject * poSelf, PyObject * poArgs) +{ + int iHandle; + if (!PyTuple_GetInteger(poArgs, 0, &iHandle)) + return Py_BuildException(); + int iLineIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iLineIndex)) + return Py_BuildException(); + + CTextLineLoader * pTextFileLoader = (CTextLineLoader *)iHandle; + return Py_BuildValue("s", pTextFileLoader->GetLine(iLineIndex)); +} + +PyObject * appSetGuildMarkPath(PyObject * poSelf, PyObject * poArgs) +{ + char * path; + if (!PyTuple_GetString(poArgs, 0, &path)) + return Py_BuildException(); + + char newPath[256]; + char * ext = strstr(path, ".tga"); + + if (ext) + { + int extPos = ext - path; + strncpy(newPath, path, extPos); + newPath[extPos] = '\0'; + } + else + strncpy(newPath, path, sizeof(newPath)-1); + + CGuildMarkManager::Instance().SetMarkPathPrefix(newPath); + return Py_BuildNone(); +} + +PyObject* appIsDevStage(PyObject* poSelf, PyObject* poArgs) +{ + int nIsDevelopmentStage = 0; +#if defined(LOCALE_SERVICE_STAGE_DEVELOPMENT) + nIsDevelopmentStage = 1; +#endif + return Py_BuildValue("i", nIsDevelopmentStage); +} + +PyObject* appIsTestStage(PyObject* poSelf, PyObject* poArgs) +{ + int nIsTestStage = 0; +#if defined(LOCALE_SERVICE_STAGE_TEST) + nIsTestStage = 1; +#endif + return Py_BuildValue("i", nIsTestStage); +} + +PyObject* appIsLiveStage(PyObject* poSelf, PyObject* poArgs) +{ + int nIsLiveStage = 0; +#if !defined(LOCALE_SERVICE_STAGE_TEST) && !defined(LOCALE_SERVICE_STAGE_DEVELOPMENT) + nIsLiveStage = 1; +#endif + return Py_BuildValue("i", nIsLiveStage); +} + +PyObject* appLogoOpen(PyObject* poSelf, PyObject* poArgs) +{ + char* szName; + if (!PyTuple_GetString(poArgs, 0, &szName)) + return Py_BuildException(); + + int nIsSuccess = 1; //CPythonApplication::Instance().OnLogoOpen(szName); + CMovieMan::Instance().PlayLogo(szName); + + return Py_BuildValue("i", nIsSuccess); +} + +PyObject* appLogoUpdate(PyObject* poSelf, PyObject* poArgs) +{ + int nIsRun = 0; //CPythonApplication::Instance().OnLogoUpdate(); + return Py_BuildValue("i", nIsRun); +} + +PyObject* appLogoRender(PyObject* poSelf, PyObject* poArgs) +{ + //CPythonApplication::Instance().OnLogoRender(); + return Py_BuildNone(); +} + +PyObject* appLogoClose(PyObject* poSelf, PyObject* poArgs) +{ + //CPythonApplication::Instance().OnLogoClose(); + return Py_BuildNone(); +} + +void initapp() +{ + static PyMethodDef s_methods[] = + { + { "IsDevStage", appIsDevStage, METH_VARARGS }, + { "IsTestStage", appIsTestStage, METH_VARARGS }, + { "IsLiveStage", appIsLiveStage, METH_VARARGS }, + + // TEXTTAIL_LIVINGTIME_CONTROL + { "SetTextTailLivingTime", appSetTextTailLivingTime, METH_VARARGS }, + // END_OF_TEXTTAIL_LIVINGTIME_CONTROL + + { "EnablePerformanceTime", appEnablePerformanceTime, METH_VARARGS }, + { "SetHairColorEnable", appSetHairColorEnable, METH_VARARGS }, + + { "SetArmorSpecularEnable", appSetArmorSpecularEnable, METH_VARARGS }, + { "SetWeaponSpecularEnable", appSetWeaponSpecularEnable, METH_VARARGS }, + { "SetSkillEffectUpgradeEnable",appSetSkillEffectUpgradeEnable, METH_VARARGS }, + { "SetTwoHandedWeaponAttSpeedDecreaseValue", SetTwoHandedWeaponAttSpeedDecreaseValue, METH_VARARGS }, + { "SetRideHorseEnable", appSetRideHorseEnable, METH_VARARGS }, + + { "SetCameraMaxDistance", appSetCameraMaxDistance, METH_VARARGS }, + { "SetMinFog", appSetMinFog, METH_VARARGS }, + { "SetFrameSkip", appSetFrameSkip, METH_VARARGS }, + { "GetImageInfo", appGetImageInfo, METH_VARARGS }, + { "GetInfo", appGetInfo, METH_VARARGS }, + { "UpdateGame", appUpdateGame, METH_VARARGS }, + { "RenderGame", appRenderGame, METH_VARARGS }, + { "Loop", appLoop, METH_VARARGS }, + { "Create", appCreate, METH_VARARGS }, + { "Process", appProcess, METH_VARARGS }, + { "Exit", appExit, METH_VARARGS }, + { "Abort", appAbort, METH_VARARGS }, + { "SetMouseHandler", appSetMouseHandler, METH_VARARGS }, + { "IsExistFile", appIsExistFile, METH_VARARGS }, + { "GetFileList", appGetFileList, METH_VARARGS }, + + { "SetCamera", appSetCamera, METH_VARARGS }, + { "GetCamera", appGetCamera, METH_VARARGS }, + { "GetCameraPitch", appGetCameraPitch, METH_VARARGS }, + { "GetCameraRotation", appGetCameraRotation, METH_VARARGS }, + { "GetTime", appGetTime, METH_VARARGS }, + { "GetGlobalTime", appGetGlobalTime, METH_VARARGS }, + { "GetGlobalTimeStamp", appGetGlobalTimeStamp, METH_VARARGS }, + { "GetUpdateFPS", appGetUpdateFPS, METH_VARARGS }, + { "GetRenderFPS", appGetRenderFPS, METH_VARARGS }, + { "RotateCamera", appRotateCamera, METH_VARARGS }, + { "PitchCamera", appPitchCamera, METH_VARARGS }, + { "ZoomCamera", appZoomCamera, METH_VARARGS }, + { "MovieRotateCamera", appMovieRotateCamera, METH_VARARGS }, + { "MoviePitchCamera", appMoviePitchCamera, METH_VARARGS }, + { "MovieZoomCamera", appMovieZoomCamera, METH_VARARGS }, + { "MovieResetCamera", appMovieResetCamera, METH_VARARGS }, + + { "GetAvailableTextureMemory", appGetAvaiableTextureMememory, METH_VARARGS }, + { "GetRenderTime", appGetRenderTime, METH_VARARGS }, + { "GetUpdateTime", appGetUpdateTime, METH_VARARGS }, + { "GetLoad", appGetLoad, METH_VARARGS }, + { "GetFaceSpeed", appGetFaceSpeed, METH_VARARGS }, + { "GetFaceCount", appGetFaceCount, METH_VARARGS }, + { "SetFPS", appSetFPS, METH_VARARGS }, + { "SetGlobalCenterPosition", appSetGlobalCenterPosition, METH_VARARGS }, + { "SetCenterPosition", appSetCenterPosition, METH_VARARGS }, + { "GetCursorPosition", appGetCursorPosition, METH_VARARGS }, + + { "GetRandom", appGetRandom, METH_VARARGS }, + { "RunPythonFile", appRunPythonFile, METH_VARARGS }, + { "IsWebPageMode", appIsWebPageMode, METH_VARARGS }, + { "ShowWebPage", appShowWebPage, METH_VARARGS }, + { "MoveWebPage", appMoveWebPage, METH_VARARGS }, + { "HideWebPage", appHideWebPage, METH_VARARGS }, + { "IsPressed", appIsPressed, METH_VARARGS }, + { "SetCursor", appSetCursor, METH_VARARGS }, + { "GetCursor", appGetCursor, METH_VARARGS }, + { "ShowCursor", appShowCursor, METH_VARARGS }, + { "HideCursor", appHideCursor, METH_VARARGS }, + { "IsShowCursor", appIsShowCursor, METH_VARARGS }, + { "IsLiarCursorOn", appIsLiarCursorOn, METH_VARARGS }, + { "SetSoftwareCursor", appSetSoftwareCursor, METH_VARARGS }, + { "SetHardwareCursor", appSetHardwareCursor, METH_VARARGS }, + + { "SetConnectData", appSetConnectData, METH_VARARGS }, + { "GetConnectData", appGetConnectData, METH_VARARGS }, + + { "GetRotatingDirection", appGetRotatingDirection, METH_VARARGS }, + { "GetDegreeDifference", appGetDegreeDifference, METH_VARARGS }, + { "Sleep", appSleep, METH_VARARGS }, + { "SetDefaultFontName", appSetDefaultFontName, METH_VARARGS }, + { "SetGuildSymbolPath", appSetGuildSymbolPath, METH_VARARGS }, + + { "EnableSpecialCameraMode", appEnableSpecialCameraMode, METH_VARARGS }, + { "SetCameraSpeed", appSetCameraSpeed, METH_VARARGS }, + + { "SaveCameraSetting", appSaveCameraSetting, METH_VARARGS }, + { "LoadCameraSetting", appLoadCameraSetting, METH_VARARGS }, + { "SetDefaultCamera", appSetDefaultCamera, METH_VARARGS }, + { "SetCameraSetting", appSetCameraSetting, METH_VARARGS }, + + { "SetSightRange", appSetSightRange, METH_VARARGS }, + + { "IsFileExist", appIsFileExist, METH_VARARGS }, + { "OpenTextFile", appOpenTextFile, METH_VARARGS }, + { "CloseTextFile", appCloseTextFile, METH_VARARGS }, + { "GetTextFileLineCount", appGetTextFileLineCount, METH_VARARGS }, + { "GetTextFileLine", appGetTextFileLine, METH_VARARGS }, + + // LOCALE + { "GetLocaleServiceName", appGetLocaleServiceName, METH_VARARGS }, + { "GetLocaleName", appGetLocaleName, METH_VARARGS }, + { "GetLocalePath", appGetLocalePath, METH_VARARGS }, + { "ForceSetLocale", appForceSetLocale, METH_VARARGS }, + // END_OF_LOCALE + + // CHEONMA + { "LoadLocaleAddr", appLoadLocaleAddr, METH_VARARGS }, + { "LoadLocaleData", appLoadLocaleData, METH_VARARGS }, + { "SetCHEONMA", appSetCHEONMA, METH_VARARGS }, + { "IsCHEONMA", appIsCHEONMA, METH_VARARGS }, + // END_OF_CHEONMA + + { "GetDefaultCodePage", appGetDefaultCodePage, METH_VARARGS }, + { "SetControlFP", appSetControlFP, METH_VARARGS }, + { "SetSpecularSpeed", appSetSpecularSpeed, METH_VARARGS }, + + { "testGetAccumulationTime", apptestGetAccumulationTime, METH_VARARGS }, + { "testResetAccumulationTime", apptestResetAccumulationTime, METH_VARARGS }, + { "testSetSpecularColor", apptestSetSpecularColor, METH_VARARGS }, + + { "SetVisibleNotice", appSetVisibleNotice, METH_VARARGS }, + { "IsVisibleNotice", appIsVisibleNotice, METH_VARARGS }, + { "EnableTestServerFlag", appEnableTestServerFlag, METH_VARARGS }, + { "IsEnableTestServerFlag", appIsEnableTestServerFlag, METH_VARARGS }, + + { "SetGuildMarkPath", appSetGuildMarkPath, METH_VARARGS }, + + { "OnLogoUpdate", appLogoUpdate, METH_VARARGS }, + { "OnLogoRender", appLogoRender, METH_VARARGS }, + { "OnLogoOpen", appLogoOpen, METH_VARARGS }, + { "OnLogoClose", appLogoClose, METH_VARARGS }, + + + { NULL, NULL }, + }; + + PyObject * poModule = Py_InitModule("app", s_methods); + + PyModule_AddIntConstant(poModule, "INFO_ITEM", CPythonApplication::INFO_ITEM); + PyModule_AddIntConstant(poModule, "INFO_ACTOR", CPythonApplication::INFO_ACTOR); + PyModule_AddIntConstant(poModule, "INFO_EFFECT", CPythonApplication::INFO_EFFECT); + PyModule_AddIntConstant(poModule, "INFO_TEXTTAIL", CPythonApplication::INFO_TEXTTAIL); + + PyModule_AddIntConstant(poModule, "DEGREE_DIRECTION_SAME", DEGREE_DIRECTION_SAME); + PyModule_AddIntConstant(poModule, "DEGREE_DIRECTION_RIGHT", DEGREE_DIRECTION_RIGHT); + PyModule_AddIntConstant(poModule, "DEGREE_DIRECTION_LEFT", DEGREE_DIRECTION_LEFT); + + PyModule_AddIntConstant(poModule, "VK_LEFT", VK_LEFT); + PyModule_AddIntConstant(poModule, "VK_RIGHT", VK_RIGHT); + PyModule_AddIntConstant(poModule, "VK_UP", VK_UP); + PyModule_AddIntConstant(poModule, "VK_DOWN", VK_DOWN); + PyModule_AddIntConstant(poModule, "VK_HOME", VK_HOME); + PyModule_AddIntConstant(poModule, "VK_END", VK_END); + PyModule_AddIntConstant(poModule, "VK_DELETE", VK_DELETE); + + PyModule_AddIntConstant(poModule, "DIK_ESCAPE", DIK_ESCAPE); + PyModule_AddIntConstant(poModule, "DIK_ESC", DIK_ESCAPE); // Ǹ + PyModule_AddIntConstant(poModule, "DIK_1", DIK_1); + PyModule_AddIntConstant(poModule, "DIK_2", DIK_2); + PyModule_AddIntConstant(poModule, "DIK_3", DIK_3); + PyModule_AddIntConstant(poModule, "DIK_4", DIK_4); + PyModule_AddIntConstant(poModule, "DIK_5", DIK_5); + PyModule_AddIntConstant(poModule, "DIK_6", DIK_6); + PyModule_AddIntConstant(poModule, "DIK_7", DIK_7); + PyModule_AddIntConstant(poModule, "DIK_8", DIK_8); + PyModule_AddIntConstant(poModule, "DIK_9", DIK_9); + PyModule_AddIntConstant(poModule, "DIK_0", DIK_0); + PyModule_AddIntConstant(poModule, "DIK_MINUS", DIK_MINUS); /* - on main keyboard */ + PyModule_AddIntConstant(poModule, "DIK_EQUALS", DIK_EQUALS); + PyModule_AddIntConstant(poModule, "DIK_BACK", DIK_BACK); /* backspace */ + PyModule_AddIntConstant(poModule, "DIK_TAB", DIK_TAB); + PyModule_AddIntConstant(poModule, "DIK_Q", DIK_Q); + PyModule_AddIntConstant(poModule, "DIK_W", DIK_W); + PyModule_AddIntConstant(poModule, "DIK_E", DIK_E); + PyModule_AddIntConstant(poModule, "DIK_R", DIK_R); + PyModule_AddIntConstant(poModule, "DIK_T", DIK_T); + PyModule_AddIntConstant(poModule, "DIK_Y", DIK_Y); + PyModule_AddIntConstant(poModule, "DIK_U", DIK_U); + PyModule_AddIntConstant(poModule, "DIK_I", DIK_I); + PyModule_AddIntConstant(poModule, "DIK_O", DIK_O); + PyModule_AddIntConstant(poModule, "DIK_P", DIK_P); + PyModule_AddIntConstant(poModule, "DIK_LBRACKET", DIK_LBRACKET); + PyModule_AddIntConstant(poModule, "DIK_RBRACKET", DIK_RBRACKET); + PyModule_AddIntConstant(poModule, "DIK_RETURN", DIK_RETURN); /* Enter on main keyboard */ + PyModule_AddIntConstant(poModule, "DIK_LCONTROL", DIK_LCONTROL); + PyModule_AddIntConstant(poModule, "DIK_A", DIK_A); + PyModule_AddIntConstant(poModule, "DIK_S", DIK_S); + PyModule_AddIntConstant(poModule, "DIK_D", DIK_D); + PyModule_AddIntConstant(poModule, "DIK_F", DIK_F); + PyModule_AddIntConstant(poModule, "DIK_G", DIK_G); + PyModule_AddIntConstant(poModule, "DIK_H", DIK_H); + PyModule_AddIntConstant(poModule, "DIK_J", DIK_J); + PyModule_AddIntConstant(poModule, "DIK_K", DIK_K); + PyModule_AddIntConstant(poModule, "DIK_L", DIK_L); + PyModule_AddIntConstant(poModule, "DIK_SEMICOLON", DIK_SEMICOLON); + PyModule_AddIntConstant(poModule, "DIK_APOSTROPHE", DIK_APOSTROPHE); + PyModule_AddIntConstant(poModule, "DIK_GRAVE", DIK_GRAVE); /* accent grave */ + PyModule_AddIntConstant(poModule, "DIK_LSHIFT", DIK_LSHIFT); + PyModule_AddIntConstant(poModule, "DIK_BACKSLASH", DIK_BACKSLASH); + PyModule_AddIntConstant(poModule, "DIK_Z", DIK_Z); + PyModule_AddIntConstant(poModule, "DIK_X", DIK_X); + PyModule_AddIntConstant(poModule, "DIK_C", DIK_C); + PyModule_AddIntConstant(poModule, "DIK_V", DIK_V); + PyModule_AddIntConstant(poModule, "DIK_B", DIK_B); + PyModule_AddIntConstant(poModule, "DIK_N", DIK_N); + PyModule_AddIntConstant(poModule, "DIK_M", DIK_M); + PyModule_AddIntConstant(poModule, "DIK_COMMA", DIK_COMMA); + PyModule_AddIntConstant(poModule, "DIK_PERIOD", DIK_PERIOD); /* . on main keyboard */ + PyModule_AddIntConstant(poModule, "DIK_SLASH", DIK_SLASH); /* / on main keyboard */ + PyModule_AddIntConstant(poModule, "DIK_RSHIFT", DIK_RSHIFT); + PyModule_AddIntConstant(poModule, "DIK_MULTIPLY", DIK_MULTIPLY); /* * on numeric keypad */ + PyModule_AddIntConstant(poModule, "DIK_LALT", DIK_LMENU); /* left Alt */ + PyModule_AddIntConstant(poModule, "DIK_SPACE", DIK_SPACE); + PyModule_AddIntConstant(poModule, "DIK_CAPITAL", DIK_CAPITAL); + PyModule_AddIntConstant(poModule, "DIK_F1", DIK_F1); + PyModule_AddIntConstant(poModule, "DIK_F2", DIK_F2); + PyModule_AddIntConstant(poModule, "DIK_F3", DIK_F3); + PyModule_AddIntConstant(poModule, "DIK_F4", DIK_F4); + PyModule_AddIntConstant(poModule, "DIK_F5", DIK_F5); + PyModule_AddIntConstant(poModule, "DIK_F6", DIK_F6); + PyModule_AddIntConstant(poModule, "DIK_F7", DIK_F7); + PyModule_AddIntConstant(poModule, "DIK_F8", DIK_F8); + PyModule_AddIntConstant(poModule, "DIK_F9", DIK_F9); + PyModule_AddIntConstant(poModule, "DIK_F10", DIK_F10); + PyModule_AddIntConstant(poModule, "DIK_NUMLOCK", DIK_NUMLOCK); + PyModule_AddIntConstant(poModule, "DIK_SCROLL", DIK_SCROLL); /* Scroll Lock */ + PyModule_AddIntConstant(poModule, "DIK_NUMPAD7", DIK_NUMPAD7); + PyModule_AddIntConstant(poModule, "DIK_NUMPAD8", DIK_NUMPAD8); + PyModule_AddIntConstant(poModule, "DIK_NUMPAD9", DIK_NUMPAD9); + PyModule_AddIntConstant(poModule, "DIK_SUBTRACT", DIK_SUBTRACT); /* - on numeric keypad */ + PyModule_AddIntConstant(poModule, "DIK_NUMPAD4", DIK_NUMPAD4); + PyModule_AddIntConstant(poModule, "DIK_NUMPAD5", DIK_NUMPAD5); + PyModule_AddIntConstant(poModule, "DIK_NUMPAD6", DIK_NUMPAD6); + PyModule_AddIntConstant(poModule, "DIK_ADD", DIK_ADD); /* + on numeric keypad */ + PyModule_AddIntConstant(poModule, "DIK_NUMPAD1", DIK_NUMPAD1); + PyModule_AddIntConstant(poModule, "DIK_NUMPAD2", DIK_NUMPAD2); + PyModule_AddIntConstant(poModule, "DIK_NUMPAD3", DIK_NUMPAD3); + PyModule_AddIntConstant(poModule, "DIK_NUMPAD0", DIK_NUMPAD0); + PyModule_AddIntConstant(poModule, "DIK_DECIMAL", DIK_DECIMAL); /* . on numeric keypad */ + PyModule_AddIntConstant(poModule, "DIK_F11", DIK_F11); + PyModule_AddIntConstant(poModule, "DIK_F12", DIK_F12); + PyModule_AddIntConstant(poModule, "DIK_NEXTTRACK", DIK_NEXTTRACK); /* Next Track */ + PyModule_AddIntConstant(poModule, "DIK_NUMPADENTER", DIK_NUMPADENTER); /* Enter on numeric keypad */ + PyModule_AddIntConstant(poModule, "DIK_RCONTROL", DIK_RCONTROL); + PyModule_AddIntConstant(poModule, "DIK_MUTE", DIK_MUTE); /* Mute */ + PyModule_AddIntConstant(poModule, "DIK_CALCULATOR", DIK_CALCULATOR); /* Calculator */ + PyModule_AddIntConstant(poModule, "DIK_PLAYPAUSE", DIK_PLAYPAUSE); /* Play / Pause */ + PyModule_AddIntConstant(poModule, "DIK_MEDIASTOP", DIK_MEDIASTOP); /* Media Stop */ + PyModule_AddIntConstant(poModule, "DIK_VOLUMEDOWN", DIK_VOLUMEDOWN); /* Volume - */ + PyModule_AddIntConstant(poModule, "DIK_VOLUMEUP", DIK_VOLUMEUP); /* Volume + */ + PyModule_AddIntConstant(poModule, "DIK_WEBHOME", DIK_WEBHOME); /* Web home */ + PyModule_AddIntConstant(poModule, "DIK_NUMPADCOMMA", DIK_NUMPADCOMMA); /* , on numeric keypad (NEC PC98) */ + PyModule_AddIntConstant(poModule, "DIK_DIVIDE", DIK_DIVIDE); /* / on numeric keypad */ + PyModule_AddIntConstant(poModule, "DIK_SYSRQ", DIK_SYSRQ); + PyModule_AddIntConstant(poModule, "DIK_RALT", DIK_RMENU); /* right Alt */ + PyModule_AddIntConstant(poModule, "DIK_PAUSE", DIK_PAUSE); /* Pause */ + PyModule_AddIntConstant(poModule, "DIK_HOME", DIK_HOME); /* Home on arrow keypad */ + PyModule_AddIntConstant(poModule, "DIK_UP", DIK_UP); /* UpArrow on arrow keypad */ + PyModule_AddIntConstant(poModule, "DIK_PGUP", DIK_PRIOR); /* PgUp on arrow keypad */ + PyModule_AddIntConstant(poModule, "DIK_LEFT", DIK_LEFT); /* LeftArrow on arrow keypad */ + PyModule_AddIntConstant(poModule, "DIK_RIGHT", DIK_RIGHT); /* RightArrow on arrow keypad */ + PyModule_AddIntConstant(poModule, "DIK_END", DIK_END); /* End on arrow keypad */ + PyModule_AddIntConstant(poModule, "DIK_DOWN", DIK_DOWN); /* DownArrow on arrow keypad */ + PyModule_AddIntConstant(poModule, "DIK_PGDN", DIK_NEXT); /* PgDn on arrow keypad */ + PyModule_AddIntConstant(poModule, "DIK_INSERT", DIK_INSERT); /* Insert on arrow keypad */ + PyModule_AddIntConstant(poModule, "DIK_DELETE", DIK_DELETE); /* Delete on arrow keypad */ + PyModule_AddIntConstant(poModule, "DIK_LWIN", DIK_LWIN); /* Left Windows key */ + PyModule_AddIntConstant(poModule, "DIK_RWIN", DIK_RWIN); /* Right Windows key */ + PyModule_AddIntConstant(poModule, "DIK_APPS", DIK_APPS); /* AppMenu key */ + + // Cursor + PyModule_AddIntConstant(poModule, "NORMAL", CPythonApplication::CURSOR_SHAPE_NORMAL); + PyModule_AddIntConstant(poModule, "ATTACK", CPythonApplication::CURSOR_SHAPE_ATTACK); + PyModule_AddIntConstant(poModule, "TARGET", CPythonApplication::CURSOR_SHAPE_TARGET); + PyModule_AddIntConstant(poModule, "TALK", CPythonApplication::CURSOR_SHAPE_TALK); + PyModule_AddIntConstant(poModule, "CANT_GO", CPythonApplication::CURSOR_SHAPE_CANT_GO); + PyModule_AddIntConstant(poModule, "PICK", CPythonApplication::CURSOR_SHAPE_PICK); + + PyModule_AddIntConstant(poModule, "DOOR", CPythonApplication::CURSOR_SHAPE_DOOR); + PyModule_AddIntConstant(poModule, "CHAIR", CPythonApplication::CURSOR_SHAPE_CHAIR); + PyModule_AddIntConstant(poModule, "MAGIC", CPythonApplication::CURSOR_SHAPE_MAGIC); + PyModule_AddIntConstant(poModule, "BUY", CPythonApplication::CURSOR_SHAPE_BUY); + PyModule_AddIntConstant(poModule, "SELL", CPythonApplication::CURSOR_SHAPE_SELL); + + PyModule_AddIntConstant(poModule, "CAMERA_ROTATE", CPythonApplication::CURSOR_SHAPE_CAMERA_ROTATE); + PyModule_AddIntConstant(poModule, "HSIZE", CPythonApplication::CURSOR_SHAPE_HSIZE); + PyModule_AddIntConstant(poModule, "VSIZE", CPythonApplication::CURSOR_SHAPE_VSIZE); + PyModule_AddIntConstant(poModule, "HVSIZE", CPythonApplication::CURSOR_SHAPE_HVSIZE); + + PyModule_AddIntConstant(poModule, "CAMERA_TO_POSITIVE", CPythonApplication::CAMERA_TO_POSITIVE); + PyModule_AddIntConstant(poModule, "CAMERA_TO_NEGATIVE", CPythonApplication::CAMERA_TO_NEGITIVE); + PyModule_AddIntConstant(poModule, "CAMERA_STOP", CPythonApplication::CAMERA_STOP); + +#ifdef ENABLE_COSTUME_SYSTEM + PyModule_AddIntConstant(poModule, "ENABLE_COSTUME_SYSTEM", 1); +#else + PyModule_AddIntConstant(poModule, "ENABLE_COSTUME_SYSTEM", 0); +#endif + +#ifdef ENABLE_ENERGY_SYSTEM + PyModule_AddIntConstant(poModule, "ENABLE_ENERGY_SYSTEM", 1); +#else + PyModule_AddIntConstant(poModule, "ENABLE_ENERGY_SYSTEM", 0); +#endif + +#ifdef ENABLE_DRAGON_SOUL_SYSTEM + PyModule_AddIntConstant(poModule, "ENABLE_DRAGON_SOUL_SYSTEM", 1); +#else + PyModule_AddIntConstant(poModule, "ENABLE_DRAGON_SOUL_SYSTEM", 0); +#endif + +#ifdef ENABLE_NEW_EQUIPMENT_SYSTEM + PyModule_AddIntConstant(poModule, "ENABLE_NEW_EQUIPMENT_SYSTEM", 1); +#else + PyModule_AddIntConstant(poModule, "ENABLE_NEW_EQUIPMENT_SYSTEM", 0); +#endif + +#ifdef USE_OPENID + PyModule_AddIntConstant(poModule, "USE_OPENID", 1); + if (openid_test) + PyModule_AddIntConstant(poModule, "OPENID_TEST", 1); + else + PyModule_AddIntConstant(poModule, "OPENID_TEST", 0); +#else + PyModule_AddIntConstant(poModule, "USE_OPENID", 0); + PyModule_AddIntConstant(poModule, "OPENID_TEST", 0); +#endif /* USE_OPENID */ +} diff --git a/source/UserInterface/PythonApplicationProcedure.cpp b/source/UserInterface/PythonApplicationProcedure.cpp new file mode 100644 index 0000000..d6ecf8d --- /dev/null +++ b/source/UserInterface/PythonApplicationProcedure.cpp @@ -0,0 +1,281 @@ +#include "StdAfx.h" +#include "PythonApplication.h" +#include "../eterlib/Camera.h" +#include "../CWebBrowser/CWebBrowser.h" + +#include + +static int gs_nMouseCaptureRef = 0; + +void CPythonApplication::SafeSetCapture() +{ + SetCapture(m_hWnd); + gs_nMouseCaptureRef++; +} + +void CPythonApplication::SafeReleaseCapture() +{ + gs_nMouseCaptureRef--; + if (gs_nMouseCaptureRef==0) + ReleaseCapture(); +} + +void CPythonApplication::__SetFullScreenWindow(HWND hWnd, DWORD dwWidth, DWORD dwHeight, DWORD dwBPP) +{ + DEVMODE DevMode; + DevMode.dmSize = sizeof(DevMode); + DevMode.dmBitsPerPel = dwBPP; + DevMode.dmPelsWidth = dwWidth; + DevMode.dmPelsHeight = dwHeight; + DevMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; + + LONG Error = ChangeDisplaySettings(&DevMode, CDS_FULLSCREEN); + if(Error == DISP_CHANGE_RESTART) + { + ChangeDisplaySettings(0,0); + } +} + +void CPythonApplication::__MinimizeFullScreenWindow(HWND hWnd, DWORD dwWidth, DWORD dwHeight) +{ + ChangeDisplaySettings(0, 0); + SetWindowPos(hWnd, 0, 0, 0, + dwWidth, + dwHeight, + SWP_SHOWWINDOW); + ShowWindow(hWnd, SW_MINIMIZE); +} + +LRESULT CPythonApplication::WindowProcedure(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam) +{ + const int c_DoubleClickTime = 300; + const int c_DoubleClickBox = 5; + static int s_xDownPosition = 0; + static int s_yDownPosition = 0; + + switch (uiMsg) + { + case WM_ACTIVATEAPP: + { + m_isActivateWnd = (wParam == WA_ACTIVE) || (wParam == WA_CLICKACTIVE); + + if (m_isActivateWnd) + { + m_SoundManager.RestoreVolume(); + + ////////////////// + + if (m_isWindowFullScreenEnable) + { + __SetFullScreenWindow(hWnd, m_dwWidth, m_dwHeight, m_pySystem.GetBPP()); + } + } + else + { + m_SoundManager.SaveVolume(); + + ////////////////// + + if (m_isWindowFullScreenEnable) + { + __MinimizeFullScreenWindow(hWnd, m_dwWidth, m_dwHeight); + } + } + } + break; + + case WM_INPUTLANGCHANGE: + return CPythonIME::Instance().WMInputLanguage(hWnd, uiMsg, wParam, lParam); + break; + + case WM_IME_STARTCOMPOSITION: + return CPythonIME::Instance().WMStartComposition(hWnd, uiMsg, wParam, lParam); + break; + + case WM_IME_COMPOSITION: + return CPythonIME::Instance().WMComposition(hWnd, uiMsg, wParam, lParam); + break; + + case WM_IME_ENDCOMPOSITION: + return CPythonIME::Instance().WMEndComposition(hWnd, uiMsg, wParam, lParam); + break; + + case WM_IME_NOTIFY: + return CPythonIME::Instance().WMNotify(hWnd, uiMsg, wParam, lParam); + break; + + case WM_IME_SETCONTEXT: + lParam &= ~(ISC_SHOWUICOMPOSITIONWINDOW | ISC_SHOWUIALLCANDIDATEWINDOW); + break; + + case WM_CHAR: + return CPythonIME::Instance().WMChar(hWnd, uiMsg, wParam, lParam); + break; + + case WM_KEYDOWN: + OnIMEKeyDown(LOWORD(wParam)); + break; + + case WM_LBUTTONDOWN: + SafeSetCapture(); + + if (ELTimer_GetMSec() - m_dwLButtonDownTime < c_DoubleClickTime && + abs(LOWORD(lParam) - s_xDownPosition) < c_DoubleClickBox && + abs(HIWORD(lParam) - s_yDownPosition) < c_DoubleClickBox) + { + m_dwLButtonDownTime = 0; + + OnMouseLeftButtonDoubleClick(short(LOWORD(lParam)), short(HIWORD(lParam))); + } + else + { + m_dwLButtonDownTime = ELTimer_GetMSec(); + + OnMouseLeftButtonDown(short(LOWORD(lParam)), short(HIWORD(lParam))); + } + + s_xDownPosition = LOWORD(lParam); + s_yDownPosition = HIWORD(lParam); + return 0; + + case WM_LBUTTONUP: + m_dwLButtonUpTime = ELTimer_GetMSec(); + + if (hWnd == GetCapture()) + { + SafeReleaseCapture(); + OnMouseLeftButtonUp(short(LOWORD(lParam)), short(HIWORD(lParam))); + } + return 0; + + case WM_MBUTTONDOWN: + SafeSetCapture(); + + UI::CWindowManager::Instance().RunMouseMiddleButtonDown(short(LOWORD(lParam)), short(HIWORD(lParam))); +// OnMouseMiddleButtonDown(short(LOWORD(lParam)), short(HIWORD(lParam))); + break; + + case WM_MBUTTONUP: + if (GetCapture() == hWnd) + { + SafeReleaseCapture(); + + UI::CWindowManager::Instance().RunMouseMiddleButtonUp(short(LOWORD(lParam)), short(HIWORD(lParam))); +// OnMouseMiddleButtonUp(short(LOWORD(lParam)), short(HIWORD(lParam))); + } + break; + + case WM_RBUTTONDOWN: + SafeSetCapture(); + OnMouseRightButtonDown(short(LOWORD(lParam)), short(HIWORD(lParam))); + return 0; + + case WM_RBUTTONUP: + if (hWnd == GetCapture()) + { + SafeReleaseCapture(); + + OnMouseRightButtonUp(short(LOWORD(lParam)), short(HIWORD(lParam))); + } + return 0; + + case 0x20a: + if (WebBrowser_IsVisible()) + { + // ϶ ۵ ȵǵ ó + } + else + { + OnMouseWheel(short(HIWORD(wParam))); + } + break; + + case WM_SIZE: + switch (wParam) + { + case SIZE_RESTORED: + case SIZE_MAXIMIZED: + { + RECT rcWnd; + GetClientRect(&rcWnd); + + UINT uWidth=rcWnd.right-rcWnd.left; + UINT uHeight=rcWnd.bottom-rcWnd.left; + m_grpDevice.ResizeBackBuffer(uWidth, uHeight); + } + break; + } + + if (wParam==SIZE_MINIMIZED) + m_isMinimizedWnd=true; + else + m_isMinimizedWnd=false; + + OnSizeChange(short(LOWORD(lParam)), short(HIWORD(lParam))); + + break; + + case WM_EXITSIZEMOVE: + { + RECT rcWnd; + GetClientRect(&rcWnd); + + UINT uWidth=rcWnd.right-rcWnd.left; + UINT uHeight=rcWnd.bottom-rcWnd.left; + m_grpDevice.ResizeBackBuffer(uWidth, uHeight); + OnSizeChange(short(LOWORD(lParam)), short(HIWORD(lParam))); + } + break; + + case WM_SYSKEYDOWN: + switch (LOWORD(wParam)) + { + case VK_F10: + break; + } + break; + + case WM_SYSKEYUP: + switch(LOWORD(wParam)) + { + case 18: + return FALSE; + break; + case VK_F10: + break; + } + break; + + case WM_SETCURSOR: + if (IsActive()) + { + if (m_bCursorVisible && CURSOR_MODE_HARDWARE == m_iCursorMode) + { + SetCursor((HCURSOR) m_hCurrentCursor); + return 0; + } + else + { + SetCursor(NULL); + return 0; + } + } + break; + + case WM_CLOSE: +#ifdef _DEBUG + PostQuitMessage(0); +#else + RunPressExitKey(); +#endif + return 0; + + case WM_DESTROY: + return 0; + default: + //Tracenf("%x msg %x", timeGetTime(), uiMsg); + break; + } + + return CMSApplication::WindowProcedure(hWnd, uiMsg, wParam, lParam); +} diff --git a/source/UserInterface/PythonApplicationWebPage.cpp b/source/UserInterface/PythonApplicationWebPage.cpp new file mode 100644 index 0000000..43c5e5d --- /dev/null +++ b/source/UserInterface/PythonApplicationWebPage.cpp @@ -0,0 +1,46 @@ +#include "StdAfx.h" +#include "PythonApplication.h" +#include "../CWebBrowser/CWebBrowser.h" + +bool CPythonApplication::IsWebPageMode() +{ + return WebBrowser_IsVisible() ? true : false; +} + +void CPythonApplication::ShowWebPage(const char* c_szURL, const RECT& c_rcWebPage) +{ + if (WebBrowser_IsVisible()) + return; + + m_grpDevice.EnableWebBrowserMode(c_rcWebPage); + if (!WebBrowser_Show(GetWindowHandle(), c_szURL, &c_rcWebPage)) + { + TraceError("CREATE_WEBBROWSER_ERROR:%d", GetLastError()); + } + + SetCursorMode(CURSOR_MODE_HARDWARE); +} + +void CPythonApplication::MoveWebPage(const RECT& c_rcWebPage) +{ + if (WebBrowser_IsVisible()) + { + m_grpDevice.MoveWebBrowserRect(c_rcWebPage); + WebBrowser_Move(&c_rcWebPage); + } +} + +void CPythonApplication::HideWebPage() +{ + if (WebBrowser_IsVisible()) + { + WebBrowser_Hide(); + + m_grpDevice.DisableWebBrowserMode(); + + if (m_pySystem.IsSoftwareCursor()) + SetCursorMode(CURSOR_MODE_SOFTWARE); + else + SetCursorMode(CURSOR_MODE_HARDWARE); + } +} diff --git a/source/UserInterface/PythonBackground.cpp b/source/UserInterface/PythonBackground.cpp new file mode 100644 index 0000000..fbef52c --- /dev/null +++ b/source/UserInterface/PythonBackground.cpp @@ -0,0 +1,921 @@ +// PythonBackground.cpp: implementation of the CPythonBackground class. +// +////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "../eterlib/CullingManager.h" +#include "../eterlib/Camera.h" +#include "../eterPack/EterPackManager.h" +#include "../gamelib/MapOutDoor.h" +#include "../gamelib/PropertyLoader.h" + +#include "PythonBackground.h" +#include "PythonCharacterManager.h" +#include "PythonNetworkStream.h" +#include "PythonMiniMap.h" +#include "PythonSystem.h" + +std::string g_strEffectName = "d:/ymir work/effect/etc/direction/direction_land.mse"; + +DWORD CPythonBackground::GetRenderShadowTime() +{ + return m_dwRenderShadowTime; +} + +bool CPythonBackground::SetVisiblePart(int eMapOutDoorPart, bool isVisible) +{ + if (!m_pkMap) + return false; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + rkMap.SetVisiblePart(eMapOutDoorPart, isVisible); + return true; +} + +void CPythonBackground::EnableTerrainOnlyForHeight() +{ + if (!m_pkMap) + return; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + rkMap.EnableTerrainOnlyForHeight(TRUE); +} + +bool CPythonBackground::SetSplatLimit(int iSplatNum) +{ + if (!m_pkMap) + return false; + + CMapOutdoor& rkMap = GetMapOutdoorRef(); + rkMap.SetSplatLimit(iSplatNum); + return true; +} + +void CPythonBackground::CreateCharacterShadowTexture() +{ + if (!m_pkMap) + return; + + CMapOutdoor& rkMap = GetMapOutdoorRef(); + rkMap.CreateCharacterShadowTexture(); +} + +void CPythonBackground::ReleaseCharacterShadowTexture() +{ + if (!m_pkMap) + return; + + CMapOutdoor& rkMap = GetMapOutdoorRef(); + rkMap.ReleaseCharacterShadowTexture(); +} + +void CPythonBackground::RefreshShadowLevel() +{ + SetShadowLevel(CPythonSystem::Instance().GetShadowLevel()); +} + +bool CPythonBackground::SetShadowLevel(int eLevel) +{ + if (!m_pkMap) + return false; + + if (m_eShadowLevel == eLevel) + return true; + + CMapOutdoor& rkMap = GetMapOutdoorRef(); + + m_eShadowLevel = eLevel; + + switch (m_eShadowLevel) + { + case SHADOW_NONE: + rkMap.SetDrawShadow(false); + rkMap.SetShadowTextureSize(512); + break; + + case SHADOW_GROUND: + rkMap.SetDrawShadow(true); + rkMap.SetDrawCharacterShadow(false); + rkMap.SetShadowTextureSize(512); + break; + + case SHADOW_GROUND_AND_SOLO: + rkMap.SetDrawShadow(true); + rkMap.SetDrawCharacterShadow(true); + rkMap.SetShadowTextureSize(512); + break; + + case SHADOW_ALL: + rkMap.SetDrawShadow(true); + rkMap.SetDrawCharacterShadow(true); + rkMap.SetShadowTextureSize(512); + break; + + case SHADOW_ALL_HIGH: + rkMap.SetDrawShadow(true); + rkMap.SetDrawCharacterShadow(true); + rkMap.SetShadowTextureSize(1024); + break; + + case SHADOW_ALL_MAX: + rkMap.SetDrawShadow(true); + rkMap.SetDrawCharacterShadow(true); + rkMap.SetShadowTextureSize(2048); + break; + } + + return true; +} + +void CPythonBackground::SelectViewDistanceNum(int eNum) +{ + if (!m_pkMap) + return; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + + if (!mc_pcurEnvironmentData) + { + TraceError("CPythonBackground::SelectViewDistanceNum(int eNum=%d) mc_pcurEnvironmentData is NULL", eNum); + return; + } + + m_eViewDistanceNum = eNum; + + TEnvironmentData * env = ((TEnvironmentData *) mc_pcurEnvironmentData); + + // ⸦ ٲ Ƿ reserve Ǿ ġ ʴ´. + if (env->bReserve) + { + env->m_fFogNearDistance = m_ViewDistanceSet[m_eViewDistanceNum].m_fFogStart; + env->m_fFogFarDistance = m_ViewDistanceSet[m_eViewDistanceNum].m_fFogEnd; + env->v3SkyBoxScale = m_ViewDistanceSet[m_eViewDistanceNum].m_v3SkyBoxScale; + rkMap.SetEnvironmentSkyBox(); + } +} + +void CPythonBackground::SetViewDistanceSet(int eNum, float fFarClip) +{ + if (!m_pkMap) + return; + + m_ViewDistanceSet[eNum].m_fFogStart = fFarClip * 0.5f;//0.3333333f; + m_ViewDistanceSet[eNum].m_fFogEnd = fFarClip * 0.7f;//0.6666667f; + + float fSkyBoxScale = fFarClip * 0.6f;//0.5773502f; + m_ViewDistanceSet[eNum].m_v3SkyBoxScale = D3DXVECTOR3(fSkyBoxScale, fSkyBoxScale, fSkyBoxScale); + m_ViewDistanceSet[eNum].m_fFarClip = fFarClip; + + if (eNum == m_eViewDistanceNum) + SelectViewDistanceNum(eNum); +} + +float CPythonBackground::GetFarClip() +{ + if (!m_pkMap) + return 50000.0f; + + if (m_ViewDistanceSet[m_eViewDistanceNum].m_fFarClip==0.0f) + { + TraceError("CPythonBackground::GetFarClip m_eViewDistanceNum=%d", m_eViewDistanceNum); + m_ViewDistanceSet[m_eViewDistanceNum].m_fFarClip=25600.0f; + } + + return m_ViewDistanceSet[m_eViewDistanceNum].m_fFarClip; +} + +void CPythonBackground::GetDistanceSetInfo(int * peNum, float * pfStart, float * pfEnd, float * pfFarClip) +{ + if (!m_pkMap) + { + *peNum = 4; + *pfStart= 10000.0f; + *pfEnd= 15000.0f; + *pfFarClip = 50000.0f; + return; + } + *peNum = m_eViewDistanceNum; + *pfStart = m_ViewDistanceSet[m_eViewDistanceNum].m_fFogStart; + *pfEnd= m_ViewDistanceSet[m_eViewDistanceNum].m_fFogEnd; + *pfFarClip = m_ViewDistanceSet[m_eViewDistanceNum].m_fFarClip; +} + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CPythonBackground::CPythonBackground() +{ + m_dwRenderShadowTime=0; + m_eViewDistanceNum=0; + m_eViewDistanceNum=0; + m_eViewDistanceNum=0; + m_eShadowLevel=SHADOW_NONE; + m_dwBaseX=0; + m_dwBaseY=0; + m_strMapName=""; + m_iDayMode = DAY_MODE_LIGHT; + m_iXMasTreeGrade = 0; + m_bVisibleGuildArea = FALSE; + + SetViewDistanceSet(4, 25600.0f); + SetViewDistanceSet(3, 25600.0f); + SetViewDistanceSet(2, 25600.0f); + SetViewDistanceSet(1, 25600.0f); + SetViewDistanceSet(0, 25600.0f); + Initialize(); +} + +CPythonBackground::~CPythonBackground() +{ + Tracen("CPythonBackground Clear"); +} + +void CPythonBackground::Initialize() +{ + std::string stAtlasInfoFileName (LocaleService_GetLocalePath()); + stAtlasInfoFileName += "/AtlasInfo.txt"; + SetAtlasInfoFileName(stAtlasInfoFileName.c_str()); + CMapManager::Initialize(); +} + +void CPythonBackground::__CreateProperty() +{ + if (CEterPackManager::SEARCH_FILE_FIRST == CEterPackManager::Instance().GetSearchMode() && + _access("property", 0) == 0) + { + m_PropertyManager.Initialize(NULL); + + CPropertyLoader PropertyLoader; + PropertyLoader.SetPropertyManager(&m_PropertyManager); + PropertyLoader.Create("*.*", "Property"); + } + else + { + m_PropertyManager.Initialize("pack/property"); + } +} + +////////////////////////////////////////////////////////////////////// +// Normal Functions +////////////////////////////////////////////////////////////////////// + +bool CPythonBackground::GetPickingPoint(D3DXVECTOR3 * v3IntersectPt) +{ + CMapOutdoor& rkMap=GetMapOutdoorRef(); + return rkMap.GetPickingPoint(v3IntersectPt); +} + +bool CPythonBackground::GetPickingPointWithRay(const CRay & rRay, D3DXVECTOR3 * v3IntersectPt) +{ + CMapOutdoor& rkMap=GetMapOutdoorRef(); + return rkMap.GetPickingPointWithRay(rRay, v3IntersectPt); +} + +bool CPythonBackground::GetPickingPointWithRayOnlyTerrain(const CRay & rRay, D3DXVECTOR3 * v3IntersectPt) +{ + CMapOutdoor& rkMap=GetMapOutdoorRef(); + return rkMap.GetPickingPointWithRayOnlyTerrain(rRay, v3IntersectPt); +} + +BOOL CPythonBackground::GetLightDirection(D3DXVECTOR3 & rv3LightDirection) +{ + if (!mc_pcurEnvironmentData) + return FALSE; + + rv3LightDirection.x = mc_pcurEnvironmentData->DirLights[ENV_DIRLIGHT_BACKGROUND].Direction.x; + rv3LightDirection.y = mc_pcurEnvironmentData->DirLights[ENV_DIRLIGHT_BACKGROUND].Direction.y; + rv3LightDirection.z = mc_pcurEnvironmentData->DirLights[ENV_DIRLIGHT_BACKGROUND].Direction.z; + return TRUE; +} + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// +void CPythonBackground::Destroy() +{ + CMapManager::Destroy(); + m_SnowEnvironment.Destroy(); + m_bVisibleGuildArea = FALSE; +} + +void CPythonBackground::Create() +{ + static int s_isCreateProperty=false; + + if (!s_isCreateProperty) + { + s_isCreateProperty=true; + __CreateProperty(); + } + + CMapManager::Create(); + + m_SnowEnvironment.Create(); +} + +struct FGetPortalID +{ + float m_fRequestX, m_fRequestY; + std::set m_kSet_iPortalID; + FGetPortalID(float fRequestX, float fRequestY) + { + m_fRequestX=fRequestX; + m_fRequestY=fRequestY; + } + void operator () (CGraphicObjectInstance * pObject) + { + for (int i = 0; i < PORTAL_ID_MAX_NUM; ++i) + { + int iID = pObject->GetPortal(i); + if (0 == iID) + break; + + m_kSet_iPortalID.insert(iID); + } + } +}; + +void CPythonBackground::Update(float fCenterX, float fCenterY, float fCenterZ) +{ + if (!IsMapReady()) + return; +#ifdef __PERFORMANCE_CHECKER__ + DWORD t1=ELTimer_GetMSec(); +#endif + UpdateMap(fCenterX, fCenterY, fCenterZ); +#ifdef __PERFORMANCE_CHECKER__ + DWORD t2=ELTimer_GetMSec(); +#endif + UpdateAroundAmbience(fCenterX, fCenterY, fCenterZ); +#ifdef __PERFORMANCE_CHECKER__ + DWORD t3=ELTimer_GetMSec(); +#endif + m_SnowEnvironment.Update(D3DXVECTOR3(fCenterX, -fCenterY, fCenterZ)); + +#ifdef __PERFORMANCE_CHECKER__ + { + static FILE* fp=fopen("perf_bg_update.txt", "w"); + if (t3-t1>5) + { + fprintf(fp, "BG.Total %d (Time %f)\n", t3-t1, ELTimer_GetMSec()/1000.0f); + fprintf(fp, "BG.UpdateMap %d\n", t2-t1); + fprintf(fp, "BG.UpdateAmb %d\n", t3-t2); + fflush(fp); + } + } +#endif + + // Portal Process + CMapOutdoor& rkMap=GetMapOutdoorRef(); + if (rkMap.IsEnablePortal()) + { + CCullingManager & rkCullingMgr = CCullingManager::Instance(); + FGetPortalID kGetPortalID(fCenterX, -fCenterY); + + Vector3d aVector3d; + aVector3d.Set(fCenterX, -fCenterY, fCenterZ); + + Vector3d toTop; + toTop.Set(0, 0, 25000.0f); + + rkCullingMgr.ForInRay(aVector3d, toTop, &kGetPortalID); + + std::set::iterator itor = kGetPortalID.m_kSet_iPortalID.begin(); + if (!__IsSame(kGetPortalID.m_kSet_iPortalID, m_kSet_iShowingPortalID)) + { + ClearPortal(); + std::set::iterator itor=kGetPortalID.m_kSet_iPortalID.begin(); + for (; itor!=kGetPortalID.m_kSet_iPortalID.end(); ++itor) + { + AddShowingPortalID(*itor); + } + RefreshPortal(); + + m_kSet_iShowingPortalID = kGetPortalID.m_kSet_iPortalID; + } + } + + // Target Effect Process + { + std::map::iterator itor = m_kMap_dwTargetID_dwChrID.begin(); + for (; itor != m_kMap_dwTargetID_dwChrID.end(); ++itor) + { + DWORD dwTargetID = itor->first; + DWORD dwChrID = itor->second; + + CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetInstancePtr(dwChrID); + + if (!pInstance) + continue; + + TPixelPosition kPixelPosition; + pInstance->NEW_GetPixelPosition(&kPixelPosition); + + CreateSpecialEffect(dwTargetID, + +kPixelPosition.x, + -kPixelPosition.y, + +kPixelPosition.z, + g_strEffectName.c_str()); + } + } + + // Reserve Target Effect + { + std::map::iterator itor = m_kMap_dwID_kReserveTargetEffect.begin(); + for (; itor != m_kMap_dwID_kReserveTargetEffect.end();) + { + DWORD dwID = itor->first; + SReserveTargetEffect & rReserveTargetEffect = itor->second; + + float ilx = float(rReserveTargetEffect.ilx); + float ily = float(rReserveTargetEffect.ily); + + float fHeight = rkMap.GetHeight(ilx, ily); + if (0.0f == fHeight) + { + ++itor; + continue; + } + + CreateSpecialEffect(dwID, ilx, ily, fHeight, g_strEffectName.c_str()); + + itor = m_kMap_dwID_kReserveTargetEffect.erase(itor); + } + } +} + +bool CPythonBackground::__IsSame(std::set & rleft, std::set & rright) +{ + std::set::iterator itor_l; + std::set::iterator itor_r; + + for (itor_l=rleft.begin(); itor_l!=rleft.end(); ++itor_l) + { + if (rright.end() == rright.find(*itor_l)) + return false; + } + + for (itor_r=rright.begin(); itor_r!=rright.end(); ++itor_r) + { + if (rleft.end() == rleft.find(*itor_r)) + return false; + } + + return true; +} + +void CPythonBackground::Render() +{ + if (!IsMapReady()) + return; + + m_SnowEnvironment.Deform(); + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + rkMap.Render(); + if (m_bVisibleGuildArea) + rkMap.RenderMarkedArea(); +} + +void CPythonBackground::RenderSnow() +{ + m_SnowEnvironment.Render(); +} + +void CPythonBackground::RenderPCBlocker() +{ + if (!IsMapReady()) + return; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + rkMap.RenderPCBlocker(); +} + +void CPythonBackground::RenderCollision() +{ + if (!IsMapReady()) + return; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + rkMap.RenderCollision(); +} + +void CPythonBackground::RenderCharacterShadowToTexture() +{ + extern bool GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW; + if (GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW) + return; + + if (!IsMapReady()) + return; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + DWORD t1=ELTimer_GetMSec(); + + if (m_eShadowLevel == SHADOW_ALL || + m_eShadowLevel == SHADOW_ALL_HIGH || + m_eShadowLevel == SHADOW_ALL_MAX || + m_eShadowLevel == SHADOW_GROUND_AND_SOLO) + { + D3DXMATRIX matWorld; + STATEMANAGER.GetTransform(D3DTS_WORLD, &matWorld); + + bool canRender=rkMap.BeginRenderCharacterShadowToTexture(); + if (canRender) + { + CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance(); + + if (m_eShadowLevel == SHADOW_GROUND_AND_SOLO) + rkChrMgr.RenderShadowMainInstance(); + else + rkChrMgr.RenderShadowAllInstances(); + } + rkMap.EndRenderCharacterShadowToTexture(); + + STATEMANAGER.SetTransform(D3DTS_WORLD, &matWorld); + } + + DWORD t2=ELTimer_GetMSec(); + + m_dwRenderShadowTime=t2-t1; +} + +inline float Interpolate(float fStart, float fEnd, float fPercent) +{ + return fStart + (fEnd - fStart) * fPercent; +} +struct CollisionChecker +{ + bool isBlocked; + CInstanceBase* pInstance; + CollisionChecker(CInstanceBase* pInstance) : pInstance(pInstance), isBlocked(false) {} + void operator () (CGraphicObjectInstance* pOpponent) + { + if (isBlocked) + return; + + if (!pOpponent) + return; + + if (pInstance->IsBlockObject(*pOpponent)) + isBlocked=true; + } +}; + +struct CollisionAdjustChecker +{ + bool isBlocked; + CInstanceBase* pInstance; + CollisionAdjustChecker(CInstanceBase* pInstance) : pInstance(pInstance), isBlocked(false) {} + void operator () (CGraphicObjectInstance* pOpponent) + { + if (!pOpponent) + return; + + if (pInstance->AvoidObject(*pOpponent)) + isBlocked=true; + } +}; + +bool CPythonBackground::CheckAdvancing(CInstanceBase * pInstance) +{ + if (!IsMapReady()) + return true; + + Vector3d center; + float radius; + pInstance->GetGraphicThingInstanceRef().GetBoundingSphere(center,radius); + + CCullingManager & rkCullingMgr = CCullingManager::Instance(); + + CollisionAdjustChecker kCollisionAdjustChecker(pInstance); + rkCullingMgr.ForInRange(center, radius, &kCollisionAdjustChecker); + if (kCollisionAdjustChecker.isBlocked) + { + CollisionChecker kCollisionChecker(pInstance); + rkCullingMgr.ForInRange(center, radius, &kCollisionChecker); + if (kCollisionChecker.isBlocked) + { + pInstance->BlockMovement(); + return true; + } + else + { + pInstance->NEW_MoveToDestPixelPositionDirection(pInstance->NEW_GetDstPixelPositionRef()); + } + return false; + } + return false; +} + +void CPythonBackground::RenderSky() +{ + if (!IsMapReady()) + return; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + rkMap.RenderSky(); +} + +void CPythonBackground::RenderCloud() +{ + if (!IsMapReady()) + return; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + rkMap.RenderCloud(); +} + +void CPythonBackground::RenderWater() +{ + if (!IsMapReady()) + return; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + rkMap.RenderWater(); +} + +void CPythonBackground::RenderEffect() +{ + if (!IsMapReady()) + return; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + rkMap.RenderEffect(); +} + +void CPythonBackground::RenderBeforeLensFlare() +{ + if (!IsMapReady()) + return; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + rkMap.RenderBeforeLensFlare(); +} + +void CPythonBackground::RenderAfterLensFlare() +{ + if (!IsMapReady()) + return; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + rkMap.RenderAfterLensFlare(); +} + +void CPythonBackground::ClearGuildArea() +{ + if (!IsMapReady()) + return; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + rkMap.ClearGuildArea(); +} + +void CPythonBackground::RegisterGuildArea(int isx, int isy, int iex, int iey) +{ + if (!IsMapReady()) + return; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + rkMap.RegisterGuildArea(isx, isy, iex, iey); +} + +void CPythonBackground::SetCharacterDirLight() +{ + if (!IsMapReady()) + return; + + if (!mc_pcurEnvironmentData) + return; + + STATEMANAGER.SetLight(0, &mc_pcurEnvironmentData->DirLights[ENV_DIRLIGHT_CHARACTER]); +} + +void CPythonBackground::SetBackgroundDirLight() +{ + if (!IsMapReady()) + return; + if (!mc_pcurEnvironmentData) + return; + + STATEMANAGER.SetLight(0, &mc_pcurEnvironmentData->DirLights[ENV_DIRLIGHT_BACKGROUND]); +} + +void CPythonBackground::GlobalPositionToLocalPosition(LONG& rGlobalX, LONG& rGlobalY) +{ + rGlobalX-=m_dwBaseX; + rGlobalY-=m_dwBaseY; +} + +void CPythonBackground::LocalPositionToGlobalPosition(LONG& rLocalX, LONG& rLocalY) +{ + rLocalX+=m_dwBaseX; + rLocalY+=m_dwBaseY; +} + +void CPythonBackground::RegisterDungeonMapName(const char * c_szMapName) +{ + m_kSet_strDungeonMapName.insert(c_szMapName); +} + +CPythonBackground::TMapInfo* CPythonBackground::GlobalPositionToMapInfo(DWORD dwGlobalX, DWORD dwGlobalY) +{ + TMapInfoVector::iterator f = std::find_if(m_kVct_kMapInfo.begin(), m_kVct_kMapInfo.end(), FFindWarpMapName(dwGlobalX, dwGlobalY)); + if (f == m_kVct_kMapInfo.end()) + return NULL; + + return &(*f); +} + +void CPythonBackground::Warp(DWORD dwX, DWORD dwY) +{ + TMapInfo* pkMapInfo = GlobalPositionToMapInfo(dwX, dwY); + if (!pkMapInfo) + { + TraceError("NOT_FOUND_GLOBAL_POSITION(%d, %d)", dwX, dwY); + return; + } + + RefreshShadowLevel(); + TMapInfo & rMapInfo = *pkMapInfo; + assert( (dwX >= rMapInfo.m_dwBaseX) && (dwY >= rMapInfo.m_dwBaseY) ); + + if (!LoadMap(rMapInfo.m_strName, float(dwX - rMapInfo.m_dwBaseX), float(dwY - rMapInfo.m_dwBaseY), 0)) + { + // LOAD_MAP_ERROR_HANDLING + PostQuitMessage(0); + // END_OF_LOAD_MAP_ERROR_HANDLING + return; + } + + CPythonMiniMap::Instance().LoadAtlas(); + + m_dwBaseX=rMapInfo.m_dwBaseX; + m_dwBaseY=rMapInfo.m_dwBaseY; + + m_strMapName = rMapInfo.m_strName; + + SetXMaxTree(m_iXMasTreeGrade); + + if (m_kSet_strDungeonMapName.end() != m_kSet_strDungeonMapName.find(m_strMapName)) + { + EnableTerrainOnlyForHeight(); + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + rkMap.EnablePortal(TRUE); + } + + m_kSet_iShowingPortalID.clear(); + m_kMap_dwTargetID_dwChrID.clear(); + m_kMap_dwID_kReserveTargetEffect.clear(); +} + +void CPythonBackground::VisibleGuildArea() +{ + if (!IsMapReady()) + return; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + rkMap.VisibleMarkedArea(); + + m_bVisibleGuildArea = TRUE; +} + +void CPythonBackground::DisableGuildArea() +{ + if (!IsMapReady()) + return; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + rkMap.DisableMarkedArea(); + + m_bVisibleGuildArea = FALSE; +} + +const char * CPythonBackground::GetWarpMapName() +{ + return m_strMapName.c_str(); +} + +void CPythonBackground::ChangeToDay() +{ + m_iDayMode = DAY_MODE_LIGHT; +} + +void CPythonBackground::ChangeToNight() +{ + m_iDayMode = DAY_MODE_DARK; +} + +void CPythonBackground::EnableSnowEnvironment() +{ + m_SnowEnvironment.Enable(); +} + +void CPythonBackground::DisableSnowEnvironment() +{ + m_SnowEnvironment.Disable(); +} + +const D3DXVECTOR3 c_v3TreePos = D3DXVECTOR3(76500.0f, -60900.0f, 20215.0f); + +void CPythonBackground::SetXMaxTree(int iGrade) +{ + if (!m_pkMap) + return; + + assert(iGrade >= 0 && iGrade <= 3); + m_iXMasTreeGrade = iGrade; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + + if ("map_n_snowm_01" != m_strMapName) + { + rkMap.XMasTree_Destroy(); + return; + } + + if (0 == iGrade) + { + rkMap.XMasTree_Destroy(); + return; + } + + ////////////////////////////////////////////////////////////////////// + + iGrade -= 1; + iGrade = max(iGrade, 0); + iGrade = min(iGrade, 2); + + static std::string s_strTreeName[3] = { + "d:/ymir work/tree/christmastree1.spt", + "d:/ymir work/tree/christmastree2.spt", + "d:/ymir work/tree/christmastree3.spt" + }; + static std::string s_strEffectName[3] = { + "d:/ymir work/effect/etc/christmas_tree/tree_1s.mse", + "d:/ymir work/effect/etc/christmas_tree/tree_2s.mse", + "d:/ymir work/effect/etc/christmas_tree/tree_3s.mse", + }; + rkMap.XMasTree_Set(c_v3TreePos.x, c_v3TreePos.y, c_v3TreePos.z, s_strTreeName[iGrade].c_str(), s_strEffectName[iGrade].c_str()); +} + +void CPythonBackground::CreateTargetEffect(DWORD dwID, DWORD dwChrVID) +{ + m_kMap_dwTargetID_dwChrID.insert(std::make_pair(dwID, dwChrVID)); +} + +void CPythonBackground::CreateTargetEffect(DWORD dwID, long lx, long ly) +{ + if (m_kMap_dwTargetID_dwChrID.end() != m_kMap_dwTargetID_dwChrID.find(dwID)) + return; + + CMapOutdoor& rkMap=GetMapOutdoorRef(); + + DWORD dwBaseX; + DWORD dwBaseY; + rkMap.GetBaseXY(&dwBaseX, &dwBaseY); + + int ilx = +(lx-int(dwBaseX)); + int ily = -(ly-int(dwBaseY)); + + float fHeight = rkMap.GetHeight(float(ilx), float(ily)); + + if (0.0f == fHeight) + { + SReserveTargetEffect ReserveTargetEffect; + ReserveTargetEffect.ilx = ilx; + ReserveTargetEffect.ily = ily; + m_kMap_dwID_kReserveTargetEffect.insert(std::make_pair(dwID, ReserveTargetEffect)); + return; + } + + CreateSpecialEffect(dwID, ilx, ily, fHeight, g_strEffectName.c_str()); +} + +void CPythonBackground::DeleteTargetEffect(DWORD dwID) +{ + if (m_kMap_dwID_kReserveTargetEffect.end() != m_kMap_dwID_kReserveTargetEffect.find(dwID)) + { + m_kMap_dwID_kReserveTargetEffect.erase(dwID); + } + if (m_kMap_dwTargetID_dwChrID.end() != m_kMap_dwTargetID_dwChrID.find(dwID)) + { + m_kMap_dwTargetID_dwChrID.erase(dwID); + } + + DeleteSpecialEffect(dwID); +} + +void CPythonBackground::CreateSpecialEffect(DWORD dwID, float fx, float fy, float fz, const char * c_szFileName) +{ + CMapOutdoor& rkMap=GetMapOutdoorRef(); + rkMap.SpecialEffect_Create(dwID, fx, fy, fz, c_szFileName); +} + +void CPythonBackground::DeleteSpecialEffect(DWORD dwID) +{ + CMapOutdoor& rkMap=GetMapOutdoorRef(); + rkMap.SpecialEffect_Delete(dwID); +} diff --git a/source/UserInterface/PythonBackground.h b/source/UserInterface/PythonBackground.h new file mode 100644 index 0000000..92656e5 --- /dev/null +++ b/source/UserInterface/PythonBackground.h @@ -0,0 +1,183 @@ +// PythonBackground.h: interface for the CPythonBackground class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_PYTHONBACKGROUND_H__A202CB18_9553_4CF3_8500_5D7062B55432__INCLUDED_) +#define AFX_PYTHONBACKGROUND_H__A202CB18_9553_4CF3_8500_5D7062B55432__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "../gamelib/MapManager.h" +#include "../gamelib/TerrainDecal.h" +#include "../gamelib/SnowEnvironment.h" + +class CInstanceBase; + +class CPythonBackground : public CMapManager, public CSingleton +{ +public: + enum + { + SHADOW_NONE, + SHADOW_GROUND, + SHADOW_GROUND_AND_SOLO, + SHADOW_ALL, + SHADOW_ALL_HIGH, + SHADOW_ALL_MAX, + }; + + enum + { + DISTANCE0, + DISTANCE1, + DISTANCE2, + DISTANCE3, + DISTANCE4, + NUM_DISTANCE_SET + }; + + enum + { + DAY_MODE_LIGHT, + DAY_MODE_DARK, + }; + + typedef struct SVIEWDISTANCESET + { + float m_fFogStart; + float m_fFogEnd; + float m_fFarClip; + D3DXVECTOR3 m_v3SkyBoxScale; + } TVIEWDISTANCESET; + +public: + CPythonBackground(); + virtual ~CPythonBackground(); + + void Initialize(); + + void Destroy(); + void Create(); + + void GlobalPositionToLocalPosition(LONG& rGlobalX, LONG& rGlobalY); + void LocalPositionToGlobalPosition(LONG& rLocalX, LONG& rLocalY); + + void EnableTerrainOnlyForHeight(); + bool SetSplatLimit(int iSplatNum); + bool SetVisiblePart(int ePart, bool isVisible); + bool SetShadowLevel(int eLevel); + void RefreshShadowLevel(); + void SelectViewDistanceNum(int eNum); + void SetViewDistanceSet(int eNum, float fFarClip); + float GetFarClip(); + + DWORD GetRenderShadowTime(); + void GetDistanceSetInfo(int * peNum, float * pfStart, float * pfEnd, float * pfFarClip); + + bool GetPickingPoint(D3DXVECTOR3 * v3IntersectPt); + bool GetPickingPointWithRay(const CRay & rRay, D3DXVECTOR3 * v3IntersectPt); + bool GetPickingPointWithRayOnlyTerrain(const CRay & rRay, D3DXVECTOR3 * v3IntersectPt); + BOOL GetLightDirection(D3DXVECTOR3 & rv3LightDirection); + + void Update(float fCenterX, float fCenterY, float fCenterZ); + + void CreateCharacterShadowTexture(); + void ReleaseCharacterShadowTexture(); + void Render(); + void RenderSnow(); + void RenderPCBlocker(); + void RenderCollision(); + void RenderCharacterShadowToTexture(); + void RenderSky(); + void RenderCloud(); + void RenderWater(); + void RenderEffect(); + void RenderBeforeLensFlare(); + void RenderAfterLensFlare(); + + bool CheckAdvancing(CInstanceBase * pInstance); + + void SetCharacterDirLight(); + void SetBackgroundDirLight(); + + void ChangeToDay(); + void ChangeToNight(); + void EnableSnowEnvironment(); + void DisableSnowEnvironment(); + void SetXMaxTree(int iGrade); + + void ClearGuildArea(); + void RegisterGuildArea(int isx, int isy, int iex, int iey); + + void CreateTargetEffect(DWORD dwID, DWORD dwChrVID); + void CreateTargetEffect(DWORD dwID, long lx, long ly); + void DeleteTargetEffect(DWORD dwID); + + void CreateSpecialEffect(DWORD dwID, float fx, float fy, float fz, const char * c_szFileName); + void DeleteSpecialEffect(DWORD dwID); + + void Warp(DWORD dwX, DWORD dwY); + + void VisibleGuildArea(); + void DisableGuildArea(); + + void RegisterDungeonMapName(const char * c_szMapName); + TMapInfo* GlobalPositionToMapInfo(DWORD dwGlobalX, DWORD dwGlobalY); + const char* GetWarpMapName(); + +protected: + void __CreateProperty(); + bool __IsSame(std::set & rleft, std::set & rright); + +protected: + std::string m_strMapName; + +private: + CSnowEnvironment m_SnowEnvironment; + + int m_iDayMode; + int m_iXMasTreeGrade; + + int m_eShadowLevel; + int m_eViewDistanceNum; + + BOOL m_bVisibleGuildArea; + + DWORD m_dwRenderShadowTime; + + DWORD m_dwBaseX; + DWORD m_dwBaseY; + + TVIEWDISTANCESET m_ViewDistanceSet[NUM_DISTANCE_SET]; + + std::set m_kSet_iShowingPortalID; + std::set m_kSet_strDungeonMapName; + std::map m_kMap_dwTargetID_dwChrID; + + struct SReserveTargetEffect + { + int ilx; + int ily; + }; + std::map m_kMap_dwID_kReserveTargetEffect; + + struct FFindWarpMapName + { + DWORD m_dwX, m_dwY; + FFindWarpMapName(DWORD dwX, DWORD dwY) + { + m_dwX = dwX; + m_dwY = dwY; + } + bool operator() (TMapInfo & rMapInfo) + { + if (m_dwX < rMapInfo.m_dwBaseX || m_dwX >= rMapInfo.m_dwEndX || m_dwY < rMapInfo.m_dwBaseY || m_dwY >= rMapInfo.m_dwEndY) + return false; + return true; + } + }; +}; + +#endif // !defined(AFX_PYTHONBACKGROUND_H__A202CB18_9553_4CF3_8500_5D7062B55432__INCLUDED_) diff --git a/source/UserInterface/PythonBackgroundModule.cpp b/source/UserInterface/PythonBackgroundModule.cpp new file mode 100644 index 0000000..ae5dcef --- /dev/null +++ b/source/UserInterface/PythonBackgroundModule.cpp @@ -0,0 +1,619 @@ +#include "StdAfx.h" +#include "PythonSystem.h" +#include "PythonBackground.h" +#include "../eterlib/StateManager.h" +#include "../gamelib/MapOutDoor.h" + +PyObject * backgroundIsSoftwareTiling(PyObject * poSelf, PyObject * poArgs) +{ + CPythonBackground& rkBG=CPythonBackground::Instance(); + return Py_BuildValue("i", rkBG.IsSoftwareTilingEnable()); +} + +PyObject * backgroundEnableSoftwareTiling(PyObject * poSelf, PyObject * poArgs) +{ + int nIsEnable; + if (!PyTuple_GetInteger(poArgs, 0, &nIsEnable)) + return Py_BadArgument(); + + bool isEnable=nIsEnable ? true : false; + + CPythonBackground& rkBG=CPythonBackground::Instance(); + rkBG.ReserveSoftwareTilingEnable(isEnable); + + CPythonSystem& rkSystem=CPythonSystem::Instance(); + rkSystem.SetSoftwareTiling(isEnable); + return Py_BuildNone(); +} + +PyObject * backgroundEnableSnow(PyObject * poSelf, PyObject * poArgs) +{ + int nIsEnable; + if (!PyTuple_GetInteger(poArgs, 0, &nIsEnable)) + return Py_BadArgument(); + + CPythonBackground& rkBG=CPythonBackground::Instance(); + if (nIsEnable) + rkBG.EnableSnowEnvironment(); + else + rkBG.DisableSnowEnvironment(); + + return Py_BuildNone(); +} + +PyObject * backgroundLoadMap(PyObject * poSelf, PyObject * poArgs) +{ + char * pszMapPathName; + + if (!PyTuple_GetString(poArgs, 0, &pszMapPathName)) + return Py_BadArgument(); + + float x, y, z; + + if (!PyTuple_GetFloat(poArgs, 1, &x)) + return Py_BadArgument(); + + if (!PyTuple_GetFloat(poArgs, 2, &y)) + return Py_BadArgument(); + + if (!PyTuple_GetFloat(poArgs, 3, &z)) + return Py_BadArgument(); + + CPythonBackground& rkBG=CPythonBackground::Instance(); + rkBG.LoadMap(pszMapPathName, x, y, z); + +//#ifdef _DEBUG +// CMapOutdoor& rkMap=rkBG.GetMapOutdoorRef(); +// rkMap.EnablePortal(TRUE); +// rkBG.EnableTerrainOnlyForHeight(); +//#endif + + return Py_BuildNone(); +} + +PyObject * backgroundDestroy(PyObject * poSelf, PyObject * poArgs) +{ + CPythonBackground& rkBG=CPythonBackground::Instance(); + rkBG.SetShadowLevel(CPythonBackground::SHADOW_NONE); + rkBG.Destroy(); + return Py_BuildNone(); +} + +PyObject * backgroundRegisterEnvironmentData(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BadArgument(); + + char * pszEnvironmentFileName; + if (!PyTuple_GetString(poArgs, 1, &pszEnvironmentFileName)) + return Py_BadArgument(); + + CPythonBackground& rkBG=CPythonBackground::Instance(); + if (!rkBG.RegisterEnvironmentData(iIndex, pszEnvironmentFileName)) + { + TraceError("background.RegisterEnvironmentData(iIndex=%d, szEnvironmentFileName=%s)", iIndex, pszEnvironmentFileName); + + // TODO: + // Ʈ ȯ ۾ + } + + return Py_BuildNone(); +} + +PyObject * backgroundSetEnvironmentData(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BadArgument(); + + const TEnvironmentData * c_pEnvironmenData; + + CPythonBackground& rkBG=CPythonBackground::Instance(); + if (rkBG.GetEnvironmentData(iIndex, &c_pEnvironmenData)) + rkBG.ResetEnvironmentDataPtr(c_pEnvironmenData); + + return Py_BuildNone(); +} + +PyObject * backgroundGetCurrentMapName(PyObject * poSelf, PyObject * poArgs) +{ + CPythonBackground& rkBG=CPythonBackground::Instance(); + return Py_BuildValue("s", rkBG.GetWarpMapName()); +} + +PyObject * backgroundGetPickingPoint(PyObject * poSelf, PyObject * poArgs) +{ + CPythonBackground& rkBG=CPythonBackground::Instance(); + TPixelPosition kPPosPicked(0.0f, 0.0f, 0.0f); + if (rkBG.GetPickingPoint(&kPPosPicked)) + { + kPPosPicked.y=-kPPosPicked.y; + } + return Py_BuildValue("fff", kPPosPicked.x, kPPosPicked.y, kPPosPicked.z); +} + +PyObject * backgroundBeginEnvironment(PyObject * poSelf, PyObject * poArgs) +{ + CPythonBackground& rkBG=CPythonBackground::Instance(); + rkBG.BeginEnvironment(); + return Py_BuildNone(); +} + +PyObject * backgroundEndEnvironemt(PyObject * poSelf, PyObject * poArgs) +{ + CPythonBackground& rkBG=CPythonBackground::Instance(); + rkBG.EndEnvironment(); + return Py_BuildNone(); +} + +PyObject * backgroundSetCharacterDirLight(PyObject * poSelf, PyObject * poArgs) +{ + CPythonBackground& rkBG = CPythonBackground::Instance(); + rkBG.SetCharacterDirLight(); + return Py_BuildNone(); +} + +PyObject * backgroundSetBackgroundDirLight(PyObject * poSelf, PyObject * poArgs) +{ + CPythonBackground& rkBG = CPythonBackground::Instance(); + rkBG.SetBackgroundDirLight(); + return Py_BuildNone(); +} + +PyObject * backgroundInitialize(PyObject * poSelf, PyObject * poArgs) +{ + CPythonBackground& rkBG=CPythonBackground::Instance(); + rkBG.Create(); + return Py_BuildNone(); +} + +PyObject * backgroundUpdate(PyObject * poSelf, PyObject * poArgs) +{ + float fCameraX; + if (!PyTuple_GetFloat(poArgs, 0, &fCameraX)) + return Py_BadArgument(); + + float fCameraY; + if (!PyTuple_GetFloat(poArgs, 1, &fCameraY)) + return Py_BadArgument(); + + float fCameraZ; + if (!PyTuple_GetFloat(poArgs, 2, &fCameraZ)) + return Py_BadArgument(); + + CPythonBackground::Instance().Update(fCameraX, fCameraY, fCameraZ); + return Py_BuildNone(); +} + +PyObject * backgroundRender(PyObject * poSelf, PyObject * poArgs) +{ + CPythonBackground::Instance().Render(); + return Py_BuildNone(); +} + +PyObject * backgroundRenderPCBlocker(PyObject * poSelf, PyObject * poArgs) +{ + CPythonBackground::Instance().RenderPCBlocker(); + return Py_BuildNone(); +} + +PyObject * backgroundRenderCollision(PyObject * poSelf, PyObject * poArgs) +{ + CPythonBackground::Instance().RenderCollision(); + return Py_BuildNone(); +} + +PyObject * backgroundRenderSky(PyObject * poSelf, PyObject * poArgs) +{ + CPythonBackground::Instance().RenderSky(); + return Py_BuildNone(); +} + +PyObject * backgroundRenderCloud(PyObject * poSelf, PyObject * poArgs) +{ + CPythonBackground::Instance().RenderCloud(); + return Py_BuildNone(); +} + +PyObject * backgroundRenderWater(PyObject * poSelf, PyObject * poArgs) +{ + CPythonBackground::Instance().RenderWater(); + return Py_BuildNone(); +} + +PyObject * backgroundRenderEffect(PyObject * poSelf, PyObject * poArgs) +{ + CPythonBackground::Instance().RenderEffect(); + return Py_BuildNone(); +} + +PyObject * backgroundRenderBeforeLensFlare(PyObject * poSelf, PyObject * poArgs) +{ + CPythonBackground::Instance().RenderBeforeLensFlare(); + return Py_BuildNone(); +} + +PyObject * backgroundRenderAfterLensFlare(PyObject * poSelf, PyObject * poArgs) +{ + CPythonBackground::Instance().RenderAfterLensFlare(); + return Py_BuildNone(); +} + +PyObject * backgroundRenderCharacterShadowToTexture(PyObject * poSelf, PyObject * poArgs) +{ + CPythonBackground::Instance().RenderCharacterShadowToTexture(); + return Py_BuildNone(); +} + +PyObject * backgroundRenderDungeon(PyObject * poSelf, PyObject * poArgs) +{ + assert(!"background.RenderDungeon() - ʴ ԼԴϴ - [levites]"); + return Py_BuildNone(); +} + +PyObject * backgroundGetHeight(PyObject * poSelf, PyObject * poArgs) +{ + float fx; + if (!PyTuple_GetFloat(poArgs, 0, &fx)) + return Py_BadArgument(); + + float fy; + if (!PyTuple_GetFloat(poArgs, 1, &fy)) + return Py_BadArgument(); + + float fz = CPythonBackground::Instance().GetHeight(fx, fy); + return Py_BuildValue("f", fz); +} + +PyObject * backgroundGetRenderedSplatNum(PyObject * poSelf, PyObject * poArgs) +{ + int iPatch; + int iSplat; + float fSplatRatio; + + std::vector & aTextureNumVector = CPythonBackground::Instance().GetRenderedSplatNum(&iPatch, &iSplat, &fSplatRatio); + + char szOutput[MAX_PATH] = ""; + int iOutput = 0; + for( std::vector::iterator it = aTextureNumVector.begin(); it != aTextureNumVector.end(); it++ ) { + iOutput += snprintf(szOutput + iOutput, sizeof(szOutput) - iOutput, "%d ", *it); + } + //std::copy(aTextureNumVector.begin(),aTextureNumVector.end(),std::ostream_iterator(ostr," ")); + + return Py_BuildValue("iifs", iPatch, iSplat, fSplatRatio, szOutput); +} + +PyObject * backgroundGetRenderedGTINum(PyObject * poSelf, PyObject * poArgs) +{ + DWORD dwGraphicThingInstanceNum; + DWORD dwCRCNum; + + /*CArea::TCRCWithNumberVector & rCRCWithNumberVector = */ + CPythonBackground::Instance().GetRenderedGraphicThingInstanceNum(&dwGraphicThingInstanceNum, &dwCRCNum); + +/* + std::ostringstream ostr; + + std::for_each(rCRCWithNumberVector.begin(),rCRCWithNumberVector.end(),std::ostream_iterator(ostr," ")); +*/ + + return Py_BuildValue("ii", dwGraphicThingInstanceNum, dwCRCNum); +} + +PyObject * backgroundGetRenderShadowTime(PyObject * poSelf, PyObject * poArgs) +{ + CPythonBackground& rkBG=CPythonBackground::Instance(); + return Py_BuildValue("i", rkBG.GetRenderShadowTime()); +} + +PyObject * backgroundGetShadowMapcolor(PyObject * poSelf, PyObject * poArgs) +{ + float fx; + if (!PyTuple_GetFloat(poArgs, 0, &fx)) + return Py_BadArgument(); + + float fy; + if (!PyTuple_GetFloat(poArgs, 1, &fy)) + return Py_BadArgument(); + + DWORD dwColor = CPythonBackground::Instance().GetShadowMapColor(fx, fy); + return Py_BuildValue("i", dwColor); +} + +PyObject * backgroundSetShadowLevel(PyObject * poSelf, PyObject * poArgs) +{ + int iLevel; + + if (!PyTuple_GetInteger(poArgs, 0, &iLevel)) + return Py_BadArgument(); + + CPythonBackground& rkBG = CPythonBackground::Instance(); + rkBG.SetShadowLevel(iLevel); + return Py_BuildNone(); +} + +PyObject * backgroundSetVisiblePart(PyObject * poSelf, PyObject * poArgs) +{ + int ePart; + if (!PyTuple_GetInteger(poArgs, 0, &ePart)) + return Py_BadArgument(); + + int isVisible; + if (!PyTuple_GetInteger(poArgs, 1, &isVisible)) + return Py_BadArgument(); + + if (ePart>=CMapOutdoor::PART_NUM) + return Py_BuildException("ePart(%d)=0)", iSplatNum); + + CPythonBackground& rkBG=CPythonBackground::Instance(); + rkBG.SetSplatLimit(iSplatNum); + + return Py_BuildNone(); +} + +PyObject * backgroundSelectViewDistanceNum(PyObject * poSelf, PyObject * poArgs) +{ + int iNum; + + if (!PyTuple_GetInteger(poArgs, 0, &iNum)) + return Py_BadArgument(); + + CPythonBackground& rkBG=CPythonBackground::Instance(); + rkBG.SelectViewDistanceNum(iNum); + + return Py_BuildNone(); +} + +PyObject * backgroundSetViewDistanceSet(PyObject * poSelf, PyObject * poArgs) +{ + int iNum; + if (!PyTuple_GetInteger(poArgs, 0, &iNum)) + return Py_BadArgument(); + + float fFarClip; + if (!PyTuple_GetFloat(poArgs, 1, &fFarClip)) + return Py_BadArgument(); + + CPythonBackground& rkBG=CPythonBackground::Instance(); + rkBG.SetViewDistanceSet(iNum, fFarClip); + return Py_BuildNone(); +} + +PyObject * backgroundGetFarClip(PyObject * poSelf, PyObject * poArgs) +{ + float fFarClip = CPythonBackground::Instance().GetFarClip(); + return Py_BuildValue("f", fFarClip); +} + +PyObject * backgroundGetDistanceSetInfo(PyObject * poSelf, PyObject * poArgs) +{ + int iNum; + float fStart, fEnd, fFarClip; + CPythonBackground::Instance().GetDistanceSetInfo(&iNum, &fStart, &fEnd, &fFarClip); + return Py_BuildValue("ifff", iNum, fStart, fEnd, fFarClip); +} + +PyObject * backgroundSetBGLoading(PyObject * poSelf, PyObject * poArgs) +{ + bool bBGLoading; + if (!PyTuple_GetBoolean(poArgs, 0, &bBGLoading)) + return Py_BadArgument(); + + //CPythonBackground::Instance().BGLoadingEnable(bBGLoading); + return Py_BuildNone(); +} + +PyObject * backgroundSetRenderSort(PyObject * poSelf, PyObject * poArgs) +{ + int eSort; + if (!PyTuple_GetInteger(poArgs, 0, &eSort)) + return Py_BadArgument(); + + CPythonBackground::Instance().SetTerrainRenderSort((CMapOutdoor::ETerrainRenderSort) eSort); + return Py_BuildNone(); +} + +PyObject * backgroundSetTransparentTree(PyObject * poSelf, PyObject * poArgs) +{ + int bTransparent; + if (!PyTuple_GetInteger(poArgs, 0, &bTransparent)) + return Py_BadArgument(); + + CPythonBackground::Instance().SetTransparentTree(bTransparent ? true : false); + return Py_BuildNone(); +} + +PyObject * backgroundGlobalPositionToLocalPosition(PyObject * poSelf, PyObject * poArgs) +{ + int iX; + if (!PyTuple_GetInteger(poArgs, 0, &iX)) + return Py_BadArgument(); + + int iY; + if (!PyTuple_GetInteger(poArgs, 1, &iY)) + return Py_BadArgument(); + + LONG lX=iX; + LONG lY=iY; + CPythonBackground& rkBG=CPythonBackground::Instance(); + rkBG.GlobalPositionToLocalPosition(lX, lY); + + return Py_BuildValue("ii", lX, lY); +} + +PyObject * backgroundGlobalPositionToMapInfo(PyObject * poSelf, PyObject * poArgs) +{ + int iX; + if (!PyTuple_GetInteger(poArgs, 0, &iX)) + return Py_BadArgument(); + + int iY; + if (!PyTuple_GetInteger(poArgs, 1, &iY)) + return Py_BadArgument(); + + CPythonBackground& rkBG=CPythonBackground::Instance(); + CPythonBackground::TMapInfo* pkMapInfo=rkBG.GlobalPositionToMapInfo(iX, iY); + + if (pkMapInfo) + return Py_BuildValue("sii", pkMapInfo->m_strName.c_str(), pkMapInfo->m_dwBaseX, pkMapInfo->m_dwBaseY); + else + return Py_BuildValue("sii", "", 0, 0); +} + + +PyObject * backgroundWarpTest(PyObject * poSelf, PyObject * poArgs) +{ + int iX; + if (!PyTuple_GetInteger(poArgs, 0, &iX)) + return Py_BadArgument(); + + int iY; + if (!PyTuple_GetInteger(poArgs, 1, &iY)) + return Py_BadArgument(); + + CPythonBackground::Instance().Warp((DWORD)iX * 100 , (DWORD)iY * 100); + return Py_BuildNone(); +} + +PyObject * backgroundSetXMasTree(PyObject * poSelf, PyObject * poArgs) +{ + int iGrade; + if (!PyTuple_GetInteger(poArgs, 0, &iGrade)) + return Py_BadArgument(); + + CPythonBackground::Instance().SetXMaxTree(iGrade); + return Py_BuildNone(); +} + +PyObject * backgroundRegisterDungeonMapName(PyObject * poSelf, PyObject * poArgs) +{ + char * szName; + if (!PyTuple_GetString(poArgs, 0, &szName)) + return Py_BadArgument(); + + CPythonBackground::Instance().RegisterDungeonMapName(szName); + return Py_BuildNone(); +} + +PyObject * backgroundVisibleGuildArea(PyObject * poSelf, PyObject * poArgs) +{ + CPythonBackground::Instance().VisibleGuildArea(); + return Py_BuildNone(); +} + +PyObject * backgroundDisableGuildArea(PyObject * poSelf, PyObject * poArgs) +{ + CPythonBackground::Instance().DisableGuildArea(); + return Py_BuildNone(); +} + +void initBackground() +{ + static PyMethodDef s_methods[] = + { + { "IsSoftwareTiling", backgroundIsSoftwareTiling, METH_VARARGS }, + { "EnableSoftwareTiling", backgroundEnableSoftwareTiling, METH_VARARGS }, + { "EnableSnow", backgroundEnableSnow, METH_VARARGS }, + { "GlobalPositionToLocalPosition", backgroundGlobalPositionToLocalPosition, METH_VARARGS }, + { "GlobalPositionToMapInfo", backgroundGlobalPositionToMapInfo, METH_VARARGS }, + { "GetRenderShadowTime", backgroundGetRenderShadowTime, METH_VARARGS }, + { "LoadMap", backgroundLoadMap, METH_VARARGS }, + { "Destroy", backgroundDestroy, METH_VARARGS }, + { "RegisterEnvironmentData", backgroundRegisterEnvironmentData, METH_VARARGS }, + { "SetEnvironmentData", backgroundSetEnvironmentData, METH_VARARGS }, + { "GetCurrentMapName", backgroundGetCurrentMapName, METH_VARARGS }, + { "GetPickingPoint", backgroundGetPickingPoint, METH_VARARGS }, + + { "BeginEnvironment", backgroundBeginEnvironment, METH_VARARGS }, + { "EndEnvironment", backgroundEndEnvironemt, METH_VARARGS }, + { "SetCharacterDirLight", backgroundSetCharacterDirLight, METH_VARARGS }, + { "SetBackgroundDirLight", backgroundSetBackgroundDirLight, METH_VARARGS }, + + { "Initialize", backgroundInitialize, METH_VARARGS }, + { "Update", backgroundUpdate, METH_VARARGS }, + { "Render", backgroundRender, METH_VARARGS }, + { "RenderPCBlocker", backgroundRenderPCBlocker, METH_VARARGS }, + { "RenderCollision", backgroundRenderCollision, METH_VARARGS }, + { "RenderSky", backgroundRenderSky, METH_VARARGS }, + { "RenderCloud", backgroundRenderCloud, METH_VARARGS }, + { "RenderWater", backgroundRenderWater, METH_VARARGS }, + { "RenderEffect", backgroundRenderEffect, METH_VARARGS }, + { "RenderBeforeLensFlare", backgroundRenderBeforeLensFlare, METH_VARARGS }, + { "RenderAfterLensFlare", backgroundRenderAfterLensFlare, METH_VARARGS }, + { "RenderCharacterShadowToTexture", backgroundRenderCharacterShadowToTexture, METH_VARARGS }, + { "RenderDungeon", backgroundRenderDungeon, METH_VARARGS }, + { "GetHeight", backgroundGetHeight, METH_VARARGS }, + + { "SetShadowLevel", backgroundSetShadowLevel, METH_VARARGS }, + + { "SetVisiblePart", backgroundSetVisiblePart, METH_VARARGS }, + { "GetShadowMapColor", backgroundGetShadowMapcolor, METH_VARARGS }, + { "SetSplatLimit", backgroundSetSpaltLimit, METH_VARARGS }, + { "GetRenderedSplatNum", backgroundGetRenderedSplatNum, METH_VARARGS }, + { "GetRenderedGraphicThingInstanceNum", backgroundGetRenderedGTINum, METH_VARARGS }, + { "SelectViewDistanceNum", backgroundSelectViewDistanceNum, METH_VARARGS }, + { "SetViewDistanceSet", backgroundSetViewDistanceSet, METH_VARARGS }, + { "GetFarClip", backgroundGetFarClip, METH_VARARGS }, + { "GetDistanceSetInfo", backgroundGetDistanceSetInfo, METH_VARARGS }, + { "SetBGLoading", backgroundSetBGLoading, METH_VARARGS }, + { "SetRenderSort", backgroundSetRenderSort, METH_VARARGS }, + { "SetTransparentTree", backgroundSetTransparentTree, METH_VARARGS }, + { "SetXMasTree", backgroundSetXMasTree, METH_VARARGS }, + { "RegisterDungeonMapName", backgroundRegisterDungeonMapName, METH_VARARGS }, + + { "VisibleGuildArea", backgroundVisibleGuildArea, METH_VARARGS }, + { "DisableGuildArea", backgroundDisableGuildArea, METH_VARARGS }, + + { "WarpTest", backgroundWarpTest, METH_VARARGS }, + + { NULL, NULL, NULL }, + }; + + PyObject * poModule = Py_InitModule("background", s_methods); + + PyModule_AddIntConstant(poModule, "PART_SKY", CMapOutdoor::PART_SKY); + PyModule_AddIntConstant(poModule, "PART_TREE", CMapOutdoor::PART_TREE); + PyModule_AddIntConstant(poModule, "PART_CLOUD", CMapOutdoor::PART_CLOUD); + PyModule_AddIntConstant(poModule, "PART_WATER", CMapOutdoor::PART_WATER); + PyModule_AddIntConstant(poModule, "PART_OBJECT", CMapOutdoor::PART_OBJECT); + PyModule_AddIntConstant(poModule, "PART_TERRAIN", CMapOutdoor::PART_TERRAIN); + + PyModule_AddIntConstant(poModule, "SKY_RENDER_MODE_DEFAULT", CSkyObject::SKY_RENDER_MODE_DEFAULT); + PyModule_AddIntConstant(poModule, "SKY_RENDER_MODE_DIFFUSE", CSkyObject::SKY_RENDER_MODE_DIFFUSE); + PyModule_AddIntConstant(poModule, "SKY_RENDER_MODE_TEXTURE", CSkyObject::SKY_RENDER_MODE_TEXTURE); + PyModule_AddIntConstant(poModule, "SKY_RENDER_MODE_MODULATE", CSkyObject::SKY_RENDER_MODE_MODULATE); + PyModule_AddIntConstant(poModule, "SKY_RENDER_MODE_MODULATE2X", CSkyObject::SKY_RENDER_MODE_MODULATE2X); + PyModule_AddIntConstant(poModule, "SKY_RENDER_MODE_MODULATE4X", CSkyObject::SKY_RENDER_MODE_MODULATE4X); + + PyModule_AddIntConstant(poModule, "SHADOW_NONE", CPythonBackground::SHADOW_NONE); + PyModule_AddIntConstant(poModule, "SHADOW_GROUND", CPythonBackground::SHADOW_GROUND); + PyModule_AddIntConstant(poModule, "SHADOW_GROUND_AND_SOLO", CPythonBackground::SHADOW_GROUND_AND_SOLO); + PyModule_AddIntConstant(poModule, "SHADOW_ALL", CPythonBackground::SHADOW_ALL); + PyModule_AddIntConstant(poModule, "SHADOW_ALL_HIGH", CPythonBackground::SHADOW_ALL_HIGH); + PyModule_AddIntConstant(poModule, "SHADOW_ALL_MAX", CPythonBackground::SHADOW_ALL_MAX); + + PyModule_AddIntConstant(poModule, "DISTANCE0", CPythonBackground::DISTANCE0); + PyModule_AddIntConstant(poModule, "DISTANCE1", CPythonBackground::DISTANCE1); + PyModule_AddIntConstant(poModule, "DISTANCE2", CPythonBackground::DISTANCE2); + PyModule_AddIntConstant(poModule, "DISTANCE3", CPythonBackground::DISTANCE3); + PyModule_AddIntConstant(poModule, "DISTANCE4", CPythonBackground::DISTANCE4); + + PyModule_AddIntConstant(poModule, "DISTANCE_SORT", CMapOutdoor::DISTANCE_SORT); + PyModule_AddIntConstant(poModule, "TEXTURE_SORT", CMapOutdoor::TEXTURE_SORT); +} diff --git a/source/UserInterface/PythonCharacterManager.cpp b/source/UserInterface/PythonCharacterManager.cpp new file mode 100644 index 0000000..ee4f0f1 --- /dev/null +++ b/source/UserInterface/PythonCharacterManager.cpp @@ -0,0 +1,965 @@ +#include "stdafx.h" +#include "pythoncharactermanager.h" +#include "PythonBackground.h" +#include "PythonNonPlayer.h" +#include "AbstractPlayer.h" +#include "packet.h" + +#include "../eterLib/Camera.h" + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Frame Process + +int CHAR_STAGE_VIEW_BOUND = 200*100; + +struct FCharacterManagerCharacterInstanceUpdate +{ + inline void operator () (const std::pair& cr_Pair) + { + cr_Pair.second->Update(); + } +}; + +void CPythonCharacterManager::AdjustCollisionWithOtherObjects(CActorInstance* pInst ) +{ + if( !pInst->IsPC() ) + return; + + CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance(); + for(CPythonCharacterManager::CharacterIterator i = rkChrMgr.CharacterInstanceBegin(); i!=rkChrMgr.CharacterInstanceEnd();++i) + { + CInstanceBase* pkInstEach=*i; + CActorInstance* rkActorEach=pkInstEach->GetGraphicThingInstancePtr(); + + if (rkActorEach==pInst) + continue; + + if( rkActorEach->IsPC() || rkActorEach->IsNPC() || rkActorEach->IsEnemy() ) + continue; + + if(pInst->TestPhysicsBlendingCollision(*rkActorEach) ) + { + // NOTE : ϴ ġ + // TODO : ݴ óѴٸ physic movementŸ stepingؼ iterationóؾ . + TPixelPosition curPos; + pInst->GetPixelPosition(&curPos); + pInst->SetBlendingPosition(curPos); + //Tracef("!!!!!! Collision Adjusted\n"); + break; + } + } +} + + +void CPythonCharacterManager::EnableSortRendering(bool isEnable) +{ +} + +void CPythonCharacterManager::InsertPVPKey(DWORD dwVIDSrc, DWORD dwVIDDst) +{ + CInstanceBase::InsertPVPKey(dwVIDSrc, dwVIDDst); + + CInstanceBase* pkInstSrc=GetInstancePtr(dwVIDSrc); + if (pkInstSrc) + pkInstSrc->RefreshTextTail(); + + CInstanceBase* pkInstDst=GetInstancePtr(dwVIDDst); + if (pkInstDst) + pkInstDst->RefreshTextTail(); +} + +void CPythonCharacterManager::RemovePVPKey(DWORD dwVIDSrc, DWORD dwVIDDst) +{ + CInstanceBase::RemovePVPKey(dwVIDSrc, dwVIDDst); + + CInstanceBase* pkInstSrc=GetInstancePtr(dwVIDSrc); + if (pkInstSrc) + pkInstSrc->RefreshTextTail(); + + CInstanceBase* pkInstDst=GetInstancePtr(dwVIDDst); + if (pkInstDst) + pkInstDst->RefreshTextTail(); +} + +void CPythonCharacterManager::ChangeGVG(DWORD dwSrcGuildID, DWORD dwDstGuildID) +{ + TCharacterInstanceMap::iterator itor; + for (itor = m_kAliveInstMap.begin(); itor != m_kAliveInstMap.end(); itor++) + { + CInstanceBase * pInstance = itor->second; + + DWORD dwInstanceGuildID = pInstance->GetGuildID(); + if (dwSrcGuildID == dwInstanceGuildID || dwDstGuildID == dwInstanceGuildID) + { + pInstance->RefreshTextTail(); + } + } +} + +void CPythonCharacterManager::ClearMainInstance() +{ + m_pkInstMain=NULL; +} + +bool CPythonCharacterManager::SetMainInstance(DWORD dwVID) +{ + m_pkInstMain=GetInstancePtr(dwVID); + + if (!m_pkInstMain) + return false; + + return true; +} + +CInstanceBase* CPythonCharacterManager::GetMainInstancePtr() +{ + return m_pkInstMain; +} + +void CPythonCharacterManager::GetInfo(std::string* pstInfo) +{ + pstInfo->append("Actor: "); + + CInstanceBase::GetInfo(pstInfo); + + char szInfo[256]; + sprintf(szInfo, "Container - Live %d, Dead %d", m_kAliveInstMap.size(), m_kDeadInstList.size()); + pstInfo->append(szInfo); +} + + +bool CPythonCharacterManager::IsCacheMode() +{ + static bool s_isOldCacheMode=false; + + bool isCacheMode=s_isOldCacheMode; + if (s_isOldCacheMode) + { + if (m_kAliveInstMap.size()<30) + isCacheMode=false; + } + else + { + if (m_kAliveInstMap.size()>40) + isCacheMode=true; + } + s_isOldCacheMode=isCacheMode; + + return isCacheMode; +} + +void CPythonCharacterManager::Update() +{ +#ifdef __PERFORMANCE_CHECKER__ + DWORD t1=timeGetTime(); +#endif + CInstanceBase::ResetPerformanceCounter(); + + CInstanceBase* pkInstMain=GetMainInstancePtr(); +#ifdef __PERFORMANCE_CHECKER__ + DWORD t2=timeGetTime(); +#endif + DWORD dwDeadInstCount=0; + DWORD dwForceVisibleInstCount=0; + + TCharacterInstanceMap::iterator i=m_kAliveInstMap.begin(); + while (m_kAliveInstMap.end()!=i) + { + TCharacterInstanceMap::iterator c=i++; + + CInstanceBase* pkInstEach=c->second; + pkInstEach->Update(); + + if (pkInstMain) + { + if (pkInstEach->IsForceVisible()) + { + dwForceVisibleInstCount++; + continue; + } + + int nDistance = int(pkInstEach->NEW_GetDistanceFromDestInstance(*pkInstMain)); + if (nDistance > CHAR_STAGE_VIEW_BOUND + 10) + { + __DeleteBlendOutInstance(pkInstEach); + m_kAliveInstMap.erase(c); + dwDeadInstCount++; + } + } + } +#ifdef __PERFORMANCE_CHECKER__ + DWORD t3=timeGetTime(); +#endif + UpdateTransform(); +#ifdef __PERFORMANCE_CHECKER__ + DWORD t4=timeGetTime(); +#endif + + UpdateDeleting(); +#ifdef __PERFORMANCE_CHECKER__ + DWORD t5=timeGetTime(); +#endif + + __NEW_Pick(); +#ifdef __PERFORMANCE_CHECKER__ + DWORD t6=timeGetTime(); +#endif + +#ifdef __PERFORMANCE_CHECKER__ + { + static FILE* fp=fopen("perf_chrmgr_update.txt", "w"); + + if (t6-t1>1) + { + fprintf(fp, "CU.Total %d (Time %d, Alive %d, Dead %d)\n", + t6-t1, ELTimer_GetMSec(), + m_kAliveInstMap.size(), + m_kDeadInstList.size()); + fprintf(fp, "CU.Counter %d\n", t2-t1); + fprintf(fp, "CU.ForEach %d\n", t3-t2); + fprintf(fp, "CU.Trans %d\n", t4-t3); + fprintf(fp, "CU.Del %d\n", t5-t4); + fprintf(fp, "CU.Pick %d\n", t6-t5); + fprintf(fp, "CU.AI %d\n", m_kAliveInstMap.size()); + fprintf(fp, "CU.DI %d\n", dwDeadInstCount); + fprintf(fp, "CU.FVI %d\n", dwForceVisibleInstCount); + fprintf(fp, "-------------------------------- \n"); + fflush(fp); + } + } +#endif +} + +void CPythonCharacterManager::ShowPointEffect(DWORD ePoint, DWORD dwVID) +{ + CInstanceBase * pkInstSel = (dwVID == 0xffffffff) ? GetMainInstancePtr() : GetInstancePtr(dwVID); + + if (!pkInstSel) + return; + + switch (ePoint) + { + case POINT_LEVEL: + pkInstSel->LevelUp(); + break; + case POINT_LEVEL_STEP: + pkInstSel->SkillUp(); + break; + } +} + +bool CPythonCharacterManager::RegisterPointEffect(DWORD ePoint, const char* c_szFileName) +{ + if (ePoint>=POINT_MAX_NUM) + return false; + + CEffectManager& rkEftMgr=CEffectManager::Instance(); + rkEftMgr.RegisterEffect2(c_szFileName, &m_adwPointEffect[ePoint]); + + return true; +} + +void CPythonCharacterManager::UpdateTransform() +{ +#ifdef __PERFORMANCE_CHECKER__ + DWORD t1=timeGetTime(); + DWORD t2=timeGetTime(); +#endif + + CInstanceBase * pMainInstance = GetMainInstancePtr(); + if (pMainInstance) + { + CPythonBackground& rkBG=CPythonBackground::Instance(); + for (TCharacterInstanceMap::iterator i = m_kAliveInstMap.begin(); i != m_kAliveInstMap.end(); ++i) + { + CInstanceBase * pSrcInstance = i->second; + + pSrcInstance->CheckAdvancing(); + + // 2004.08.02.myevan.IsAttacked ׾ üũϹǷ, + // Ÿ Ǵ IsPushing϶ üũϵ Ѵ + if (pSrcInstance->IsPushing()) + rkBG.CheckAdvancing(pSrcInstance); + } +#ifdef __PERFORMANCE_CHECKER__ + t2=timeGetTime(); +#endif + +#ifdef __MOVIE_MODE__ + if (!m_pkInstMain->IsMovieMode()) + { + rkBG.CheckAdvancing(m_pkInstMain); + } +#else + rkBG.CheckAdvancing(m_pkInstMain); +#endif + } + +#ifdef __PERFORMANCE_CHECKER__ + DWORD t3=timeGetTime(); +#endif + + { + for (TCharacterInstanceMap::iterator itor = m_kAliveInstMap.begin(); itor != m_kAliveInstMap.end(); ++itor) + { + CInstanceBase * pInstance = itor->second; + pInstance->Transform(); + } + } + +#ifdef __PERFORMANCE_CHECKER__ + DWORD t4=timeGetTime(); +#endif + +#ifdef __PERFORMANCE_CHECKER__ + { + static FILE* fp=fopen("perf_chrmgr_updatetransform.txt", "w"); + + if (t4-t1>5) + { + fprintf(fp, "CUT.Total %d (Time %f, Alive %d, Dead %d)\n", + t4-t1, ELTimer_GetMSec()/1000.0f, + m_kAliveInstMap.size(), + m_kDeadInstList.size()); + fprintf(fp, "CUT.ChkAdvInst %d\n", t2-t1); + fprintf(fp, "CUT.ChkAdvBG %d\n", t3-t2); + fprintf(fp, "CUT.Trans %d\n", t4-t3); + + fprintf(fp, "-------------------------------- \n"); + fflush(fp); + } + + fflush(fp); + } +#endif +} +void CPythonCharacterManager::UpdateDeleting() +{ + TCharacterInstanceList::iterator itor = m_kDeadInstList.begin(); + for (; itor != m_kDeadInstList.end();) + { + CInstanceBase * pInstance = *itor; + + if (pInstance->UpdateDeleting()) + { + ++itor; + } + else + { + CInstanceBase::Delete(pInstance); + itor = m_kDeadInstList.erase(itor); + } + } +} + +struct FCharacterManagerCharacterInstanceDeform +{ + inline void operator () (const std::pair& cr_Pair) + { + cr_Pair.second->Deform(); + //pInstance->Update(); + } +}; +struct FCharacterManagerCharacterInstanceListDeform +{ + inline void operator () (CInstanceBase * pInstance) + { + pInstance->Deform(); + } +}; + +void CPythonCharacterManager::Deform() +{ + std::for_each(m_kAliveInstMap.begin(), m_kAliveInstMap.end(), FCharacterManagerCharacterInstanceDeform()); + std::for_each(m_kDeadInstList.begin(), m_kDeadInstList.end(), FCharacterManagerCharacterInstanceListDeform()); +} + + + + +bool CPythonCharacterManager::OLD_GetPickedInstanceVID(DWORD* pdwPickedActorID) +{ + if (!m_pkInstPick) + return false; + + *pdwPickedActorID=m_pkInstPick->GetVirtualID(); + return true; +} + +CInstanceBase * CPythonCharacterManager::OLD_GetPickedInstancePtr() +{ + return m_pkInstPick; +} + +D3DXVECTOR2 & CPythonCharacterManager::OLD_GetPickedInstPosReference() +{ + return m_v2PickedInstProjPos; +} + +bool CPythonCharacterManager::IsRegisteredVID(DWORD dwVID) +{ + if (m_kAliveInstMap.end()==m_kAliveInstMap.find(dwVID)) + return false; + + return true; +} + +bool CPythonCharacterManager::IsAliveVID(DWORD dwVID) +{ + return m_kAliveInstMap.find(dwVID)!=m_kAliveInstMap.end(); +} + +bool CPythonCharacterManager::IsDeadVID(DWORD dwVID) +{ + for (TCharacterInstanceList::iterator f=m_kDeadInstList.begin(); f!=m_kDeadInstList.end(); ++f) + { + if ((*f)->GetVirtualID()==dwVID) + return true; + } + + return false; +} + +struct LessCharacterInstancePtrRenderOrder +{ + bool operator() (CInstanceBase* pkLeft, CInstanceBase* pkRight) + { + return pkLeft->LessRenderOrder(pkRight); + } +}; + +struct FCharacterManagerCharacterInstanceRender +{ + inline void operator () (const std::pair& cr_Pair) + { + cr_Pair.second->Render(); + cr_Pair.second->RenderTrace(); + } +}; +struct FCharacterInstanceRender +{ + inline void operator () (CInstanceBase * pInstance) + { + pInstance->Render(); + } +}; +struct FCharacterInstanceRenderTrace +{ + inline void operator () (CInstanceBase * pInstance) + { + pInstance->RenderTrace(); + } +}; + + +void CPythonCharacterManager::__RenderSortedAliveActorList() +{ + static std::vector s_kVct_pkInstAliveSort; + s_kVct_pkInstAliveSort.clear(); + + TCharacterInstanceMap& rkMap_pkInstAlive=m_kAliveInstMap; + TCharacterInstanceMap::iterator i; + for (i=rkMap_pkInstAlive.begin(); i!=rkMap_pkInstAlive.end(); ++i) + s_kVct_pkInstAliveSort.push_back(i->second); + + std::sort(s_kVct_pkInstAliveSort.begin(), s_kVct_pkInstAliveSort.end(), LessCharacterInstancePtrRenderOrder()); + std::for_each(s_kVct_pkInstAliveSort.begin(), s_kVct_pkInstAliveSort.end(), FCharacterInstanceRender()); + std::for_each(s_kVct_pkInstAliveSort.begin(), s_kVct_pkInstAliveSort.end(), FCharacterInstanceRenderTrace()); +} + +void CPythonCharacterManager::__RenderSortedDeadActorList() +{ + static std::vector s_kVct_pkInstDeadSort; + s_kVct_pkInstDeadSort.clear(); + + TCharacterInstanceList& rkLst_pkInstDead=m_kDeadInstList; + TCharacterInstanceList::iterator i; + for (i=rkLst_pkInstDead.begin(); i!=rkLst_pkInstDead.end(); ++i) + s_kVct_pkInstDeadSort.push_back(*i); + + std::sort(s_kVct_pkInstDeadSort.begin(), s_kVct_pkInstDeadSort.end(), LessCharacterInstancePtrRenderOrder()); + std::for_each(s_kVct_pkInstDeadSort.begin(), s_kVct_pkInstDeadSort.end(), FCharacterInstanceRender()); + +} + +void CPythonCharacterManager::Render() +{ + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + + STATEMANAGER.SetTexture(1, NULL); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + + __RenderSortedAliveActorList(); + __RenderSortedDeadActorList(); + + CInstanceBase * pkPickedInst = OLD_GetPickedInstancePtr(); + if (pkPickedInst) + { + const D3DXVECTOR3 & c_rv3Position = pkPickedInst->GetGraphicThingInstanceRef().GetPosition(); + CPythonGraphic::Instance().ProjectPosition(c_rv3Position.x, c_rv3Position.y, c_rv3Position.z, &m_v2PickedInstProjPos.x, &m_v2PickedInstProjPos.y); + } +} + +void CPythonCharacterManager::RenderShadowMainInstance() +{ + CInstanceBase* pkInstMain=GetMainInstancePtr(); + if (pkInstMain) + pkInstMain->RenderToShadowMap(); +} + +struct FCharacterManagerCharacterInstanceRenderToShadowMap +{ + inline void operator () (const std::pair& cr_Pair) + { + cr_Pair.second->RenderToShadowMap(); + } +}; + +void CPythonCharacterManager::RenderShadowAllInstances() +{ + std::for_each(m_kAliveInstMap.begin(), m_kAliveInstMap.end(), FCharacterManagerCharacterInstanceRenderToShadowMap()); +} + +struct FCharacterManagerCharacterInstanceRenderCollision +{ + inline void operator () (const std::pair& cr_Pair) + { + cr_Pair.second->RenderCollision(); + } +}; + +void CPythonCharacterManager::RenderCollision() +{ + std::for_each(m_kAliveInstMap.begin(), m_kAliveInstMap.end(), FCharacterManagerCharacterInstanceRenderCollision()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Managing Process + +CInstanceBase * CPythonCharacterManager::CreateInstance(const CInstanceBase::SCreateData& c_rkCreateData) +{ + CInstanceBase * pCharacterInstance = RegisterInstance(c_rkCreateData.m_dwVID); + if (!pCharacterInstance) + { + TraceError("CPythonCharacterManager::CreateInstance: VID[%d] - ALREADY EXIST\n", c_rkCreateData); + return NULL; + } + + if (!pCharacterInstance->Create(c_rkCreateData)) + { + TraceError("CPythonCharacterManager::CreateInstance VID[%d] Race[%d]", c_rkCreateData.m_dwVID, c_rkCreateData.m_dwRace); + DeleteInstance(c_rkCreateData.m_dwVID); + return NULL; + } + + if (c_rkCreateData.m_isMain) + SelectInstance(c_rkCreateData.m_dwVID); + + return (pCharacterInstance); +} + +CInstanceBase * CPythonCharacterManager::RegisterInstance(DWORD VirtualID) +{ + TCharacterInstanceMap::iterator itor = m_kAliveInstMap.find(VirtualID); + + if (m_kAliveInstMap.end() != itor) + { + return NULL; + } + + CInstanceBase * pCharacterInstance = CInstanceBase::New(); + m_kAliveInstMap.insert(TCharacterInstanceMap::value_type(VirtualID, pCharacterInstance)); + + return (pCharacterInstance); +} + +void CPythonCharacterManager::DeleteInstance(DWORD dwDelVID) +{ + TCharacterInstanceMap::iterator itor = m_kAliveInstMap.find(dwDelVID); + + if (m_kAliveInstMap.end() == itor) + { + Tracef("DeleteCharacterInstance: no vid by %d\n", dwDelVID); + return; + } + + CInstanceBase * pkInstDel = itor->second; + + if (pkInstDel == m_pkInstBind) + m_pkInstBind = NULL; + + if (pkInstDel == m_pkInstMain) + m_pkInstMain = NULL; + + if (pkInstDel == m_pkInstPick) + m_pkInstPick = NULL; + + CInstanceBase::Delete(pkInstDel); + + m_kAliveInstMap.erase(itor); +} + +void CPythonCharacterManager::__DeleteBlendOutInstance(CInstanceBase* pkInstDel) +{ + pkInstDel->DeleteBlendOut(); + m_kDeadInstList.push_back(pkInstDel); + + IAbstractPlayer& rkPlayer=IAbstractPlayer::GetSingleton(); + rkPlayer.NotifyCharacterDead(pkInstDel->GetVirtualID()); +} + +void CPythonCharacterManager::DeleteInstanceByFade(DWORD dwVID) +{ + TCharacterInstanceMap::iterator f = m_kAliveInstMap.find(dwVID); + if (m_kAliveInstMap.end() == f) + { + return; + } + __DeleteBlendOutInstance(f->second); + m_kAliveInstMap.erase(f); +} + +void CPythonCharacterManager::SelectInstance(DWORD VirtualID) +{ + TCharacterInstanceMap::iterator itor = m_kAliveInstMap.find(VirtualID); + + if (m_kAliveInstMap.end() == itor) + { + Tracef("SelectCharacterInstance: no vid by %d\n", VirtualID); + return; + } + + m_pkInstBind = itor->second; +} + +CInstanceBase * CPythonCharacterManager::GetInstancePtr(DWORD VirtualID) +{ + TCharacterInstanceMap::iterator itor = m_kAliveInstMap.find(VirtualID); + + if (m_kAliveInstMap.end() == itor) + return NULL; + + return itor->second; +} + +CInstanceBase * CPythonCharacterManager::GetInstancePtrByName(const char *name) +{ + TCharacterInstanceMap::iterator itor; + + for (itor = m_kAliveInstMap.begin(); itor != m_kAliveInstMap.end(); itor++) + { + CInstanceBase * pInstance = itor->second; + + if (!strcmp(pInstance->GetNameString(), name)) + return pInstance; + } + + return NULL; +} + +CInstanceBase * CPythonCharacterManager::GetSelectedInstancePtr() +{ + return m_pkInstBind; +} + +CInstanceBase* CPythonCharacterManager::FindClickableInstancePtr() +{ + return NULL; +} + +void CPythonCharacterManager::__UpdateSortPickedActorList() +{ + __UpdatePickedActorList(); + __SortPickedActorList(); +} + +void CPythonCharacterManager::__UpdatePickedActorList() +{ + m_kVct_pkInstPicked.clear(); + + TCharacterInstanceMap::iterator i; + for (i=m_kAliveInstMap.begin(); i!=m_kAliveInstMap.end(); ++i) + { + CInstanceBase* pkInstEach=i->second; + // 2004.07.17.levites.isShow ViewFrustumCheck + if (pkInstEach->CanPickInstance()) + { + if (pkInstEach->IsDead()) + { + if (pkInstEach->IntersectBoundingBox()) + m_kVct_pkInstPicked.push_back(pkInstEach); + } + else + { + if (pkInstEach->IntersectDefendingSphere()) + m_kVct_pkInstPicked.push_back(pkInstEach); + } + } + } +} + +struct CInstanceBase_SLessCameraDistance +{ + TPixelPosition m_kPPosEye; + + bool operator() (CInstanceBase* pkInstLeft, CInstanceBase* pkInstRight) + { + int nLeftDeadPoint=pkInstLeft->IsDead(); + int nRightDeadPoint=pkInstRight->IsDead(); + + if (nLeftDeadPointCalculateDistanceSq3d(m_kPPosEye)CalculateDistanceSq3d(m_kPPosEye)) + return true; + + return false; + } +}; + +void CPythonCharacterManager::__SortPickedActorList() +{ + CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera(); + const D3DXVECTOR3& c_rv3EyePos=pCamera->GetEye(); + + CInstanceBase_SLessCameraDistance kLess; + kLess.m_kPPosEye=TPixelPosition(+c_rv3EyePos.x, -c_rv3EyePos.y, +c_rv3EyePos.z); + + std::sort(m_kVct_pkInstPicked.begin(), m_kVct_pkInstPicked.end(), kLess); +} + +void CPythonCharacterManager::__NEW_Pick() +{ + __UpdateSortPickedActorList(); + + CInstanceBase* pkInstMain=GetMainInstancePtr(); + +#ifdef __MOVIE_MODE + if (pkInstMain) + if (pkInstMain->IsMovieMode()) + { + if (m_pkInstPick) + m_pkInstPick->OnUnselected(); + return; + } +#endif + + // üũ + { + std::vector::iterator f; + for (f=m_kVct_pkInstPicked.begin(); f!=m_kVct_pkInstPicked.end(); ++f) + { + CInstanceBase* pkInstEach=*f; + if (pkInstEach!=pkInstMain && pkInstEach->IntersectBoundingBox()) + { + if (m_pkInstPick) + if (m_pkInstPick!=pkInstEach) + m_pkInstPick->OnUnselected(); + + if (pkInstEach->CanPickInstance()) + { + m_pkInstPick = pkInstEach; + m_pkInstPick->OnSelected(); + return; + } + } + } + } + + // ã + { + std::vector::iterator f; + for (f=m_kVct_pkInstPicked.begin(); f!=m_kVct_pkInstPicked.end(); ++f) + { + CInstanceBase* pkInstEach=*f; + if (pkInstEach!=pkInstMain) + { + if (m_pkInstPick) + if (m_pkInstPick!=pkInstEach) + m_pkInstPick->OnUnselected(); + + if (pkInstEach->CanPickInstance()) + { + m_pkInstPick = pkInstEach; + m_pkInstPick->OnSelected(); + return; + } + } + } + } + + if (pkInstMain) + if (pkInstMain->CanPickInstance()) + if (m_kVct_pkInstPicked.end() != std::find(m_kVct_pkInstPicked.begin(), m_kVct_pkInstPicked.end(), pkInstMain)) + { + if (m_pkInstPick) + if (m_pkInstPick!=pkInstMain) + m_pkInstPick->OnUnselected(); + + m_pkInstPick = pkInstMain; + m_pkInstPick->OnSelected(); + return; + } + + if (m_pkInstPick) + { + m_pkInstPick->OnUnselected(); + m_pkInstPick=NULL; + } +} + +void CPythonCharacterManager::__OLD_Pick() +{ + for (TCharacterInstanceMap::iterator itor = m_kAliveInstMap.begin(); itor != m_kAliveInstMap.end(); ++itor) + { + CInstanceBase * pkInstEach = itor->second; + + if (pkInstEach == m_pkInstMain) + continue; + + if (pkInstEach->IntersectDefendingSphere()) + { + if (m_pkInstPick) + if (m_pkInstPick!=pkInstEach) + m_pkInstPick->OnUnselected(); + + m_pkInstPick = pkInstEach; + m_pkInstPick->OnSelected(); + + return; + } + } + + if (m_pkInstPick) + { + m_pkInstPick->OnUnselected(); + m_pkInstPick=NULL; + } +} + +int CPythonCharacterManager::PickAll() +{ + for (TCharacterInstanceMap::iterator itor = m_kAliveInstMap.begin(); itor != m_kAliveInstMap.end(); ++itor) + { + CInstanceBase * pInstance = itor->second; + + if (pInstance->IntersectDefendingSphere()) + return pInstance->GetVirtualID(); + } + + return -1; +} + +CInstanceBase * CPythonCharacterManager::GetCloseInstance(CInstanceBase * pInstance) +{ + float fMinDistance = 10000.0f; + CInstanceBase * pCloseInstance = NULL; + + TCharacterInstanceMap::iterator itor = m_kAliveInstMap.begin(); + for (; itor != m_kAliveInstMap.end(); ++itor) + { + CInstanceBase * pTargetInstance = itor->second; + + if (pTargetInstance == pInstance) + continue; + + DWORD dwVirtualNumber = pTargetInstance->GetVirtualNumber(); + if (CPythonNonPlayer::ON_CLICK_EVENT_BATTLE != CPythonNonPlayer::Instance().GetEventType(dwVirtualNumber)) + continue; + + float fDistance = pInstance->GetDistance(pTargetInstance); + if (fDistance < fMinDistance) + { + fMinDistance = fDistance; + pCloseInstance = pTargetInstance; + } + } + + return pCloseInstance; +} + +void CPythonCharacterManager::RefreshAllPCTextTail() +{ + CPythonCharacterManager::CharacterIterator itor = CharacterInstanceBegin(); + CPythonCharacterManager::CharacterIterator itorEnd = CharacterInstanceEnd(); + for (; itor != itorEnd; ++itor) + { + CInstanceBase * pInstance = *itor; + if (!pInstance->IsPC()) + continue; + + pInstance->RefreshTextTail(); + } +} + +void CPythonCharacterManager::RefreshAllGuildMark() +{ + CPythonCharacterManager::CharacterIterator itor = CharacterInstanceBegin(); + CPythonCharacterManager::CharacterIterator itorEnd = CharacterInstanceEnd(); + for (; itor != itorEnd; ++itor) + { + CInstanceBase * pInstance = *itor; + if (!pInstance->IsPC()) + continue; + + pInstance->ChangeGuild(pInstance->GetGuildID()); + pInstance->RefreshTextTail(); + } +} + +void CPythonCharacterManager::DeleteAllInstances() +{ + DestroyAliveInstanceMap(); + DestroyDeadInstanceList(); +} + + +void CPythonCharacterManager::DestroyAliveInstanceMap() +{ + for (TCharacterInstanceMap::iterator i = m_kAliveInstMap.begin(); i != m_kAliveInstMap.end(); ++i) + CInstanceBase::Delete(i->second); + + m_kAliveInstMap.clear(); +} + +void CPythonCharacterManager::DestroyDeadInstanceList() +{ + std::for_each(m_kDeadInstList.begin(), m_kDeadInstList.end(), CInstanceBase::Delete); + m_kDeadInstList.clear(); +} + +void CPythonCharacterManager::Destroy() +{ + DeleteAllInstances(); + + CInstanceBase::DestroySystem(); + + __Initialize(); +} + +void CPythonCharacterManager::__Initialize() +{ + memset(m_adwPointEffect, 0, sizeof(m_adwPointEffect)); + m_pkInstMain = NULL; + m_pkInstBind = NULL; + m_pkInstPick = NULL; + m_v2PickedInstProjPos = D3DXVECTOR2(0.0f, 0.0f); +} + + +CPythonCharacterManager::CPythonCharacterManager() +{ + __Initialize(); +} + +CPythonCharacterManager::~CPythonCharacterManager() +{ + Destroy(); +} diff --git a/source/UserInterface/PythonCharacterManager.h b/source/UserInterface/PythonCharacterManager.h new file mode 100644 index 0000000..ad41f4b --- /dev/null +++ b/source/UserInterface/PythonCharacterManager.h @@ -0,0 +1,168 @@ +#pragma once + +#include "AbstractCharacterManager.h" +#include "InstanceBase.h" +#include "../GameLib/PhysicsObject.h" + +class CPythonCharacterManager : public CSingleton, public IAbstractCharacterManager, public IObjectManager +{ + public: + // Character List + typedef std::list TCharacterInstanceList; + typedef std::map TCharacterInstanceMap; + + class CharacterIterator; + + public: + CPythonCharacterManager(); + virtual ~CPythonCharacterManager(); + + virtual void AdjustCollisionWithOtherObjects(CActorInstance* pInst ); + + void EnableSortRendering(bool isEnable); + + bool IsRegisteredVID(DWORD dwVID); + bool IsAliveVID(DWORD dwVID); + bool IsDeadVID(DWORD dwVID); + bool IsCacheMode(); + + bool OLD_GetPickedInstanceVID(DWORD* pdwPickedActorID); + CInstanceBase* OLD_GetPickedInstancePtr(); + D3DXVECTOR2& OLD_GetPickedInstPosReference(); + + CInstanceBase* FindClickableInstancePtr(); + + void InsertPVPKey(DWORD dwVIDSrc, DWORD dwVIDDst); + void RemovePVPKey(DWORD dwVIDSrc, DWORD dwVIDDst); + void ChangeGVG(DWORD dwSrcGuildID, DWORD dwDstGuildID); + + void GetInfo(std::string* pstInfo); + + void ClearMainInstance(); + bool SetMainInstance(DWORD dwVID); + CInstanceBase* GetMainInstancePtr(); + + void SCRIPT_SetAffect(DWORD dwVID, DWORD eAffect, BOOL isVisible); + void SetEmoticon(DWORD dwVID, DWORD eEmoticon); + bool IsPossibleEmoticon(DWORD dwVID); + void ShowPointEffect(DWORD dwVID, DWORD ePoint); + bool RegisterPointEffect(DWORD ePoint, const char* c_szFileName); + + // System + void Destroy(); + + void DeleteAllInstances(); + + bool CreateDeviceObjects(); + void DestroyDeviceObjects(); + + void Update(); + void Deform(); + void Render(); + void RenderShadowMainInstance(); + void RenderShadowAllInstances(); + void RenderCollision(); + + // Create/Delete Instance + CInstanceBase * CreateInstance(const CInstanceBase::SCreateData& c_rkCreateData); + CInstanceBase * RegisterInstance(DWORD VirtualID); + + void DeleteInstance(DWORD VirtualID); + void DeleteInstanceByFade(DWORD VirtualID); + void DeleteVehicleInstance(DWORD VirtualID); + + void DestroyAliveInstanceMap(); + void DestroyDeadInstanceList(); + + inline CharacterIterator CharacterInstanceBegin() { return CharacterIterator(m_kAliveInstMap.begin());} + inline CharacterIterator CharacterInstanceEnd() { return CharacterIterator(m_kAliveInstMap.end());} + + // Access Instance + void SelectInstance(DWORD VirtualID); + CInstanceBase * GetSelectedInstancePtr(); + + CInstanceBase * GetInstancePtr(DWORD VirtualID); + CInstanceBase * GetInstancePtrByName(const char *name); + + // Pick + int PickAll(); + CInstanceBase * GetCloseInstance(CInstanceBase * pInstance); + + // Refresh TextTail + void RefreshAllPCTextTail(); + void RefreshAllGuildMark(); + + protected: + void UpdateTransform(); + void UpdateDeleting(); + + protected: + void __Initialize(); + + void __DeleteBlendOutInstance(CInstanceBase* pkInstDel); + + void __OLD_Pick(); + void __NEW_Pick(); + + void __UpdateSortPickedActorList(); + void __UpdatePickedActorList(); + void __SortPickedActorList(); + + void __RenderSortedAliveActorList(); + void __RenderSortedDeadActorList(); + + protected: + CInstanceBase * m_pkInstMain; + CInstanceBase * m_pkInstPick; + CInstanceBase * m_pkInstBind; + D3DXVECTOR2 m_v2PickedInstProjPos; + + TCharacterInstanceMap m_kAliveInstMap; + TCharacterInstanceList m_kDeadInstList; + + std::vector m_kVct_pkInstPicked; + + DWORD m_adwPointEffect[POINT_MAX_NUM]; + + public: + class CharacterIterator + { + public: + CharacterIterator(){} + CharacterIterator(const TCharacterInstanceMap::iterator & it) : m_it(it) {} + + inline CInstanceBase * operator * () { return m_it->second; } + + inline CharacterIterator & operator ++() + { + ++m_it; + return *this; + } + + inline CharacterIterator operator ++(int) + { + CharacterIterator new_it = *this; + ++(*this); + return new_it; + } + + inline CharacterIterator & operator = (const CharacterIterator & rhs) + { + m_it = rhs.m_it; + return (*this); + } + + inline bool operator == (const CharacterIterator & rhs) const + { + return m_it == rhs.m_it; + } + + inline bool operator != (const CharacterIterator & rhs) const + { + return m_it != rhs.m_it; + } + + private: + TCharacterInstanceMap::iterator m_it; + }; +}; diff --git a/source/UserInterface/PythonCharacterManagerModule.cpp b/source/UserInterface/PythonCharacterManagerModule.cpp new file mode 100644 index 0000000..7d440fd --- /dev/null +++ b/source/UserInterface/PythonCharacterManagerModule.cpp @@ -0,0 +1,844 @@ +#include "StdAfx.h" +#include "PythonCharacterManager.h" +#include "PythonBackground.h" +#include "InstanceBase.h" +#include "../gamelib/RaceManager.h" + +////////////////////////////////////////////////////////////////////////// +// RaceData +////////////////////////////////////////////////////////////////////////// + +PyObject * chrmgrSetEmpireNameMode(PyObject* poSelf, PyObject* poArgs) +{ + int iEnable; + if (!PyTuple_GetInteger(poArgs, 0, &iEnable)) + return Py_BadArgument(); + + CInstanceBase::SetEmpireNameMode(iEnable ? true : false); + CPythonCharacterManager::Instance().RefreshAllPCTextTail(); + + return Py_BuildNone(); +} + +PyObject * chrmgrRegisterTitleName(PyObject* poSelf, PyObject* poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BadArgument(); + char * szTitleName; + if (!PyTuple_GetString(poArgs, 1, &szTitleName)) + return Py_BadArgument(); + + CInstanceBase::RegisterTitleName(iIndex, szTitleName); + return Py_BuildNone(); +} + +PyObject * chrmgrRegisterNameColor(PyObject* poSelf, PyObject* poArgs) +{ + int index; + if (!PyTuple_GetInteger(poArgs, 0, &index)) + return Py_BadArgument(); + + int ir; + if (!PyTuple_GetInteger(poArgs, 1, &ir)) + return Py_BadArgument(); + int ig; + if (!PyTuple_GetInteger(poArgs, 2, &ig)) + return Py_BadArgument(); + int ib; + if (!PyTuple_GetInteger(poArgs, 3, &ib)) + return Py_BadArgument(); + + CInstanceBase::RegisterNameColor(index, ir, ig, ib); + return Py_BuildNone(); +} + +PyObject * chrmgrRegisterTitleColor(PyObject* poSelf, PyObject* poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BadArgument(); + int ir; + if (!PyTuple_GetInteger(poArgs, 1, &ir)) + return Py_BadArgument(); + int ig; + if (!PyTuple_GetInteger(poArgs, 2, &ig)) + return Py_BadArgument(); + int ib; + if (!PyTuple_GetInteger(poArgs, 3, &ib)) + return Py_BadArgument(); + + CInstanceBase::RegisterTitleColor(iIndex, ir, ig, ib); + return Py_BuildNone(); +} + +PyObject * chrmgrGetPickedVID(PyObject* poSelf, PyObject* poArgs) +{ + CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance(); + + DWORD dwPickedActorID; + if (rkChrMgr.OLD_GetPickedInstanceVID(&dwPickedActorID)) + return Py_BuildValue("i", dwPickedActorID); + else + return Py_BuildValue("i", -1); +} + +PyObject * chrmgrGetVIDInfo(PyObject* poSelf, PyObject* poArgs) +{ + int nVID; + if (!PyTuple_GetInteger(poArgs, 0, &nVID)) + return Py_BadArgument(); + + CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance(); + + char szDetail[256]=""; + CInstanceBase* pkInstBase=rkChrMgr.GetInstancePtr(nVID); + if (pkInstBase) + { + TPixelPosition kPPosInst; + pkInstBase->NEW_GetPixelPosition(&kPPosInst); + + LONG xInst=kPPosInst.x; + LONG yInst=kPPosInst.y; + + CPythonBackground& rkBG=CPythonBackground::Instance(); + rkBG.LocalPositionToGlobalPosition(xInst, yInst); + sprintf(szDetail, "pos=(%d, %d)", xInst, yInst); + } + + + char szInfo[1024]; + sprintf(szInfo, "VID %d (isRegistered=%d, isAlive=%d, isDead=%d) %s", + nVID, + rkChrMgr.IsRegisteredVID(nVID), + rkChrMgr.IsAliveVID(nVID), + rkChrMgr.IsDeadVID(nVID), + szDetail + ); + + return Py_BuildValue("s", szInfo); +} + + +PyObject * chrmgrSetPathName(PyObject* poSelf, PyObject* poArgs) +{ + char * szPathName; + if (!PyTuple_GetString(poArgs, 0, &szPathName)) + return Py_BadArgument(); + + CRaceManager::Instance().SetPathName(szPathName); + return Py_BuildNone(); +} + +PyObject * chrmgrCreateRace(PyObject * poSelf, PyObject * poArgs) +{ + int iRace; + if (!PyTuple_GetInteger(poArgs, 0, &iRace)) + return Py_BadArgument(); + + CRaceManager::Instance().CreateRace(iRace); + return Py_BuildNone(); +} + +PyObject * chrmgrSelectRace(PyObject * poSelf, PyObject * poArgs) +{ + int iRace; + if (!PyTuple_GetInteger(poArgs, 0, &iRace)) + return Py_BadArgument(); + + CRaceManager::Instance().SelectRace(iRace); + return Py_BuildNone(); +} + +PyObject * chrmgrRegisterAttachingBoneName(PyObject * poSelf, PyObject * poArgs) +{ + int iPartIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iPartIndex)) + return Py_BadArgument(); + char * szBoneName; + if (!PyTuple_GetString(poArgs, 1, &szBoneName)) + return Py_BadArgument(); + + CRaceData * pRaceData = CRaceManager::Instance().GetSelectedRaceDataPointer(); + if (!pRaceData) + return Py_BuildException("RaceData has not selected!"); + + pRaceData->RegisterAttachingBoneName(iPartIndex, szBoneName); + return Py_BuildNone(); +} + +PyObject * chrmgrRegisterMotionMode(PyObject* poSelf, PyObject* poArgs) +{ + int iMotionIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iMotionIndex)) + return Py_BadArgument(); + + CRaceData * pRaceData = CRaceManager::Instance().GetSelectedRaceDataPointer(); + if (!pRaceData) + return Py_BuildException("RaceData has not selected!"); + + pRaceData->RegisterMotionMode(iMotionIndex); + return Py_BuildNone(); +} + + + +PyObject * chrmgrSetMotionRandomWeight(PyObject* poSelf, PyObject* poArgs) +{ + int iMode; + if (!PyTuple_GetInteger(poArgs, 0, &iMode)) + return Py_BadArgument(); + + int iMotion; + if (!PyTuple_GetInteger(poArgs, 1, &iMotion)) + return Py_BadArgument(); + + int iSubMotion; + if (!PyTuple_GetInteger(poArgs, 2, &iSubMotion)) + return Py_BadArgument(); + + int iPercentage; + if (!PyTuple_GetInteger(poArgs, 3, &iPercentage)) + return Py_BadArgument(); + + CRaceData * pRaceData = CRaceManager::Instance().GetSelectedRaceDataPointer(); + if (!pRaceData) + return Py_BuildException("RaceData has not selected!"); + + if (!pRaceData->SetMotionRandomWeight(iMode, iMotion, iSubMotion, iPercentage)) + Py_BuildException("Failed to SetMotionRandomWeight"); + + return Py_BuildNone(); +} + +PyObject * chrmgrRegisterNormalAttack(PyObject* poSelf, PyObject* poArgs) +{ + int iMode; + if (!PyTuple_GetInteger(poArgs, 0, &iMode)) + return Py_BadArgument(); + + int iMotion; + if (!PyTuple_GetInteger(poArgs, 1, &iMotion)) + return Py_BadArgument(); + + CRaceData * pRaceData = CRaceManager::Instance().GetSelectedRaceDataPointer(); + if (!pRaceData) + return Py_BuildException("RaceData has not selected!"); + + pRaceData->RegisterNormalAttack(iMode, iMotion); + return Py_BuildNone(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Լ +PyObject * chrmgrReserveComboAttack(PyObject* poSelf, PyObject* poArgs) +{ + int iMode; + if (!PyTuple_GetInteger(poArgs, 0, &iMode)) + return Py_BadArgument(); + + int iCount; + if (!PyTuple_GetInteger(poArgs, 1, &iCount)) + return Py_BadArgument(); + + CRaceData * pRaceData = CRaceManager::Instance().GetSelectedRaceDataPointer(); + if (!pRaceData) + return Py_BuildException("RaceData has not selected!"); + + pRaceData->ReserveComboAttack(iMode, 0, iCount); + return Py_BuildNone(); +} + +PyObject * chrmgrRegisterComboAttack(PyObject* poSelf, PyObject* poArgs) +{ + int iMode; + if (!PyTuple_GetInteger(poArgs, 0, &iMode)) + return Py_BadArgument(); + + int iComboIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iComboIndex)) + return Py_BadArgument(); + + int iMotionIndex; + if (!PyTuple_GetInteger(poArgs, 2, &iMotionIndex)) + return Py_BadArgument(); + + CRaceData * pRaceData = CRaceManager::Instance().GetSelectedRaceDataPointer(); + if (!pRaceData) + return Py_BuildException("RaceData has not selected!"); + + pRaceData->RegisterComboAttack(iMode, 0, iComboIndex, iMotionIndex); + return Py_BuildNone(); +} +// Լ +/////////////////////////////////////////////////////////////////////////////////////////////////// + +PyObject * chrmgrReserveComboAttackNew(PyObject* poSelf, PyObject* poArgs) +{ + int iMotionMode; + if (!PyTuple_GetInteger(poArgs, 0, &iMotionMode)) + return Py_BadArgument(); + + int iComboType; + if (!PyTuple_GetInteger(poArgs, 1, &iComboType)) + return Py_BadArgument(); + + int iCount; + if (!PyTuple_GetInteger(poArgs, 2, &iCount)) + return Py_BadArgument(); + + CRaceData * pRaceData = CRaceManager::Instance().GetSelectedRaceDataPointer(); + if (!pRaceData) + return Py_BuildException("RaceData has not selected!"); + + pRaceData->ReserveComboAttack(iMotionMode, iComboType, iCount); + return Py_BuildNone(); +} + +PyObject * chrmgrRegisterComboAttackNew(PyObject* poSelf, PyObject* poArgs) +{ + int iMotionMode; + if (!PyTuple_GetInteger(poArgs, 0, &iMotionMode)) + return Py_BadArgument(); + + int iComboType; + if (!PyTuple_GetInteger(poArgs, 1, &iComboType)) + return Py_BadArgument(); + + int iComboIndex; + if (!PyTuple_GetInteger(poArgs, 2, &iComboIndex)) + return Py_BadArgument(); + + int iMotionIndex; + if (!PyTuple_GetInteger(poArgs, 3, &iMotionIndex)) + return Py_BadArgument(); + + CRaceData * pRaceData = CRaceManager::Instance().GetSelectedRaceDataPointer(); + if (!pRaceData) + return Py_BuildException("RaceData has not selected!"); + + pRaceData->RegisterComboAttack(iMotionMode, iComboType, iComboIndex, iMotionIndex); + return Py_BuildNone(); +} + +PyObject * chrmgrLoadRaceData(PyObject* poSelf, PyObject* poArgs) +{ + char* szFileName; + if (!PyTuple_GetString(poArgs, 0, &szFileName)) + return Py_BadArgument(); + + CRaceData * pRaceData = CRaceManager::Instance().GetSelectedRaceDataPointer(); + if (!pRaceData) + return Py_BuildException("RaceData has not selected!"); + + const char * c_szFullFileName = CRaceManager::Instance().GetFullPathFileName(szFileName); + if (!pRaceData->LoadRaceData(c_szFullFileName)) + { + TraceError("Failed to load race data : %s\n", c_szFullFileName); + } + + return Py_BuildNone(); +} + +PyObject * chrmgrLoadLocalRaceData(PyObject* poSelf, PyObject* poArgs) +{ + char* szFileName; + if (!PyTuple_GetString(poArgs, 0, &szFileName)) + return Py_BadArgument(); + + CRaceData * pRaceData = CRaceManager::Instance().GetSelectedRaceDataPointer(); + if (!pRaceData) + return Py_BuildException("RaceData has not selected!"); + + if (!pRaceData->LoadRaceData(szFileName)) + { + TraceError("Failed to load race data : %s\n", szFileName); + } + + return Py_BuildNone(); +} + +/* +PyObject * chrmgrRegisterMotion(PyObject* poSelf, PyObject* poArgs) +{ + int iMode; + if (!PyTuple_GetInteger(poArgs, 0, &iMode)) + return Py_BadArgument(); + + int iMotion; + if (!PyTuple_GetInteger(poArgs, 1, &iMotion)) + return Py_BadArgument(); + + char* szFileName; + if (!PyTuple_GetString(poArgs, 2, &szFileName)) + return Py_BadArgument(); + + int iWeight = 0; + PyTuple_GetInteger(poArgs, 3, &iWeight); + iWeight = MIN(100, iWeight); + + CRaceData * pRaceData = CRaceManager::Instance().GetSelectedRaceDataPointer(); + if (!pRaceData) + return Py_BuildException("RaceData has not selected!"); + + pRaceData->NEW_RegisterMotion(iMode, iMotion, CRaceManager::Instance().GetFullPathFileName(szFileName), iWeight); + return Py_BuildNone(); +} +*/ + +PyObject * chrmgrRegisterCacheMotionData(PyObject* poSelf, PyObject* poArgs) +{ + int iMode; + if (!PyTuple_GetInteger(poArgs, 0, &iMode)) + return Py_BadArgument(); + + int iMotion; + if (!PyTuple_GetInteger(poArgs, 1, &iMotion)) + return Py_BadArgument(); + + char * szFileName; + if (!PyTuple_GetString(poArgs, 2, &szFileName)) + return Py_BadArgument(); + + int iWeight = 0; + PyTuple_GetInteger(poArgs, 3, &iWeight); + iWeight = MIN(100, iWeight); + + CRaceData * pRaceData = CRaceManager::Instance().GetSelectedRaceDataPointer(); + if (!pRaceData) + return Py_BuildException("RaceData has not selected!"); + + const char * c_szFullFileName = CRaceManager::Instance().GetFullPathFileName(szFileName); + CGraphicThing* pkMotionThing=pRaceData->RegisterMotionData(iMode, iMotion, c_szFullFileName, iWeight); + + if (pkMotionThing) + CResourceManager::Instance().LoadStaticCache(pkMotionThing->GetFileName()); + + return Py_BuildNone(); +} + +PyObject * chrmgrRegisterMotionData(PyObject* poSelf, PyObject* poArgs) +{ + int iMode; + if (!PyTuple_GetInteger(poArgs, 0, &iMode)) + return Py_BadArgument(); + + int iMotion; + if (!PyTuple_GetInteger(poArgs, 1, &iMotion)) + return Py_BadArgument(); + + char * szFileName; + if (!PyTuple_GetString(poArgs, 2, &szFileName)) + return Py_BadArgument(); + + int iWeight = 0; + PyTuple_GetInteger(poArgs, 3, &iWeight); + iWeight = MIN(100, iWeight); + + CRaceData * pRaceData = CRaceManager::Instance().GetSelectedRaceDataPointer(); + if (!pRaceData) + return Py_BuildException("RaceData has not selected!"); + + const char * c_szFullFileName = CRaceManager::Instance().GetFullPathFileName(szFileName); + pRaceData->RegisterMotionData(iMode, iMotion, c_szFullFileName, iWeight); + + return Py_BuildNone(); +} + +PyObject * chrmgrRegisterRaceSrcName(PyObject* poSelf, PyObject* poArgs) +{ + char * szName; + if (!PyTuple_GetString(poArgs, 0, &szName)) + return Py_BadArgument(); + + char * szSrcName; + if (!PyTuple_GetString(poArgs, 1, &szSrcName)) + return Py_BadArgument(); + + CRaceManager::Instance().RegisterRaceSrcName(szName, szSrcName); + + return Py_BuildNone(); +} + +PyObject * chrmgrRegisterRaceName(PyObject* poSelf, PyObject* poArgs) +{ + int iRaceIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iRaceIndex)) + return Py_BadArgument(); + + char * szName; + if (!PyTuple_GetString(poArgs, 1, &szName)) + return Py_BadArgument(); + + CRaceManager::Instance().RegisterRaceName(iRaceIndex, szName); + + return Py_BuildNone(); +} + +PyObject * chrmgrSetShapeModel(PyObject* poSelf, PyObject* poArgs) +{ + int eShape; + if (!PyTuple_GetInteger(poArgs, 0, &eShape)) + return Py_BadArgument(); + + char * szFileName; + if (!PyTuple_GetString(poArgs, 1, &szFileName)) + return Py_BadArgument(); + + + CRaceData * pRaceData = CRaceManager::Instance().GetSelectedRaceDataPointer(); + if (!pRaceData) + return Py_BuildException("RaceData has not selected!"); + + pRaceData->SetShapeModel(eShape, szFileName); + return Py_BuildNone(); +} + +PyObject * chrmgrAppendShapeSkin(PyObject* poSelf, PyObject* poArgs) +{ + int eShape; + if (!PyTuple_GetInteger(poArgs, 0, &eShape)) + return Py_BadArgument(); + + int ePart; + if (!PyTuple_GetInteger(poArgs, 1, &ePart)) + return Py_BadArgument(); + + char * szSrcFileName; + if (!PyTuple_GetString(poArgs, 2, &szSrcFileName)) + return Py_BadArgument(); + + char * szDstFileName; + if (!PyTuple_GetString(poArgs, 3, &szDstFileName)) + return Py_BadArgument(); + + CRaceData * pRaceData = CRaceManager::Instance().GetSelectedRaceDataPointer(); + if (!pRaceData) + return Py_BuildException("RaceData has not selected!"); + + pRaceData->AppendShapeSkin(eShape, ePart, szSrcFileName, szDstFileName); + return Py_BuildNone(); +} +////////////////////////////////////////////////////////////////////////// +// RaceData +////////////////////////////////////////////////////////////////////////// + +PyObject * chrmgrSetMovingSpeed(PyObject* poSelf, PyObject* poArgs) +{ +#ifndef _DISTRIBUTE + int nMovSpd; + if (!PyTuple_GetInteger(poArgs, 0, &nMovSpd)) + return Py_BadArgument(); + + if (nMovSpd<0) + return Py_BuildException("MovingSpeed < 0"); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + + if (!pkInst) + return Py_BuildException("MainCharacter has not selected!"); + + pkInst->SetMoveSpeed(nMovSpd); +#endif + return Py_BuildNone(); +} + +PyObject * chrmgrRegisterEffect(PyObject* poSelf, PyObject* poArgs) +{ + int eEftType; + if (!PyTuple_GetInteger(poArgs, 0, &eEftType)) + return Py_BadArgument(); + + char * szBoneName; + if (!PyTuple_GetString(poArgs, 1, &szBoneName)) + return Py_BadArgument(); + + char * szPathName; + if (!PyTuple_GetString(poArgs, 2, &szPathName)) + return Py_BadArgument(); + + CInstanceBase::RegisterEffect(eEftType, szBoneName, szPathName, false); + return Py_BuildNone(); +} + +PyObject * chrmgrRegisterCacheEffect(PyObject* poSelf, PyObject* poArgs) +{ + int eEftType; + if (!PyTuple_GetInteger(poArgs, 0, &eEftType)) + return Py_BadArgument(); + + char * szBoneName; + if (!PyTuple_GetString(poArgs, 1, &szBoneName)) + return Py_BadArgument(); + + char * szPathName; + if (!PyTuple_GetString(poArgs, 2, &szPathName)) + return Py_BadArgument(); + + CInstanceBase::RegisterEffect(eEftType, szBoneName, szPathName, true); + + return Py_BuildNone(); +} + +PyObject * chrmgrSetDustGap(PyObject* poSelf, PyObject* poArgs) +{ + int nGap; + if (!PyTuple_GetInteger(poArgs, 0, &nGap)) + return Py_BadArgument(); + + CInstanceBase::SetDustGap(nGap); + return Py_BuildNone(); +} + +PyObject * chrmgrSetHorseDustGap(PyObject* poSelf, PyObject* poArgs) +{ + int nGap; + if (!PyTuple_GetInteger(poArgs, 0, &nGap)) + return Py_BadArgument(); + + CInstanceBase::SetHorseDustGap(nGap); + return Py_BuildNone(); +} + +PyObject * chrmgrToggleDirectionLine(PyObject* poSelf, PyObject* poArgs) +{ + static bool s_isVisible=true; + CActorInstance::ShowDirectionLine(s_isVisible); + + s_isVisible=!s_isVisible; + return Py_BuildNone(); +} + +PyObject * chrmgrRegisterPointEffect(PyObject* poSelf, PyObject* poArgs) +{ + int iEft; + if (!PyTuple_GetInteger(poArgs, 0, &iEft)) + return Py_BadArgument(); + + char * szFileName; + if (!PyTuple_GetString(poArgs, 1, &szFileName)) + return Py_BadArgument(); + + CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance(); + rkChrMgr.RegisterPointEffect(iEft, szFileName); + return Py_BuildNone(); +} + +PyObject * chrmgrShowPointEffect(PyObject* poSelf, PyObject* poArgs) +{ + int nVID; + if (!PyTuple_GetInteger(poArgs, 0, &nVID)) + return Py_BadArgument(); + + int nEft; + if (!PyTuple_GetInteger(poArgs, 1, &nEft)) + return Py_BadArgument(); + + CPythonCharacterManager & rkChrMgr = CPythonCharacterManager::Instance(); + rkChrMgr.ShowPointEffect(nEft, nVID >= 0 ? nVID : 0xffffffff); + return Py_BuildNone(); +} + + +void CPythonCharacterManager::SCRIPT_SetAffect(DWORD dwVID, DWORD eState, BOOL isVisible) +{ + CInstanceBase * pkInstSel = (dwVID == 0xffffffff) ? GetSelectedInstancePtr() : GetInstancePtr(dwVID); + if (!pkInstSel) + return; + + pkInstSel->SCRIPT_SetAffect(eState, isVisible ? true : false); +} + +PyObject * chrmgrSetAffect(PyObject* poSelf, PyObject* poArgs) +{ + int nVID; + if (!PyTuple_GetInteger(poArgs, 0, &nVID)) + return Py_BadArgument(); + + int nEft; + if (!PyTuple_GetInteger(poArgs, 1, &nEft)) + return Py_BadArgument(); + + int nVisible; + if (!PyTuple_GetInteger(poArgs, 2, &nVisible)) + return Py_BadArgument(); + + CPythonCharacterManager & rkChrMgr = CPythonCharacterManager::Instance(); + rkChrMgr.SCRIPT_SetAffect(nVID >= 0 ? nVID : 0xffffffff, nEft, nVisible); + return Py_BuildNone(); +} + +void CPythonCharacterManager::SetEmoticon(DWORD dwVID, DWORD eState) +{ + CInstanceBase * pkInstSel = (dwVID == 0xffffffff) ? GetSelectedInstancePtr() : GetInstancePtr(dwVID); + if (!pkInstSel) + return; + + pkInstSel->SetEmoticon(eState); +} + +bool CPythonCharacterManager::IsPossibleEmoticon(DWORD dwVID) +{ + CInstanceBase * pkInstSel = (dwVID == 0xffffffff) ? GetSelectedInstancePtr() : GetInstancePtr(dwVID); + if (!pkInstSel) + return false; + + return pkInstSel->IsPossibleEmoticon(); +} + +PyObject * chrmgrSetEmoticon(PyObject* poSelf, PyObject* poArgs) +{ + int nVID; + if (!PyTuple_GetInteger(poArgs, 0, &nVID)) + return Py_BadArgument(); + + int nEft; + if (!PyTuple_GetInteger(poArgs, 1, &nEft)) + return Py_BadArgument(); + + CPythonCharacterManager & rkChrMgr = CPythonCharacterManager::Instance(); + rkChrMgr.SetEmoticon(nVID >= 0 ? nVID : 0xffffffff, nEft); + return Py_BuildNone(); +} + +PyObject * chrmgrIsPossibleEmoticon(PyObject* poSelf, PyObject* poArgs) +{ + int nVID; + if (!PyTuple_GetInteger(poArgs, 0, &nVID)) + return Py_BadArgument(); + + CPythonCharacterManager & rkChrMgr = CPythonCharacterManager::Instance(); + int result = rkChrMgr.IsPossibleEmoticon(nVID >= 0 ? nVID : 0xffffffff); + + return Py_BuildValue("i", result); +} + +void initchrmgr() +{ + static PyMethodDef s_methods[] = + { + // RaceData + { "SetEmpireNameMode", chrmgrSetEmpireNameMode, METH_VARARGS }, + { "GetVIDInfo", chrmgrGetVIDInfo, METH_VARARGS }, + { "GetPickedVID", chrmgrGetPickedVID, METH_VARARGS }, + { "SetShapeModel", chrmgrSetShapeModel, METH_VARARGS }, + { "AppendShapeSkin", chrmgrAppendShapeSkin, METH_VARARGS }, + { "SetPathName", chrmgrSetPathName, METH_VARARGS }, + { "LoadRaceData", chrmgrLoadRaceData, METH_VARARGS }, + { "LoadLocalRaceData", chrmgrLoadLocalRaceData, METH_VARARGS }, + { "CreateRace", chrmgrCreateRace, METH_VARARGS }, + { "SelectRace", chrmgrSelectRace, METH_VARARGS }, + { "RegisterAttachingBoneName", chrmgrRegisterAttachingBoneName, METH_VARARGS }, + { "RegisterMotionMode", chrmgrRegisterMotionMode, METH_VARARGS }, + //{ "RegisterMotion", chrmgrRegisterMotion, METH_VARARGS }, + { "SetMotionRandomWeight", chrmgrSetMotionRandomWeight, METH_VARARGS }, + { "RegisterNormalAttack", chrmgrRegisterNormalAttack, METH_VARARGS }, + { "ReserveComboAttack", chrmgrReserveComboAttack, METH_VARARGS }, + { "RegisterComboAttack", chrmgrRegisterComboAttack, METH_VARARGS }, + { "ReserveComboAttackNew", chrmgrReserveComboAttackNew, METH_VARARGS }, + { "RegisterComboAttackNew", chrmgrRegisterComboAttackNew, METH_VARARGS }, + { "RegisterMotionData", chrmgrRegisterMotionData, METH_VARARGS }, + { "RegisterRaceName", chrmgrRegisterRaceName, METH_VARARGS }, + { "RegisterRaceSrcName", chrmgrRegisterRaceSrcName, METH_VARARGS }, + { "RegisterCacheMotionData", chrmgrRegisterCacheMotionData, METH_VARARGS }, + + // ETC + { "SetAffect", chrmgrSetAffect, METH_VARARGS }, + { "SetEmoticon", chrmgrSetEmoticon, METH_VARARGS }, + { "IsPossibleEmoticon", chrmgrIsPossibleEmoticon, METH_VARARGS }, + { "RegisterEffect", chrmgrRegisterEffect, METH_VARARGS }, + { "RegisterCacheEffect", chrmgrRegisterCacheEffect, METH_VARARGS }, + { "RegisterPointEffect", chrmgrRegisterPointEffect, METH_VARARGS }, + { "ShowPointEffect", chrmgrShowPointEffect, METH_VARARGS }, + { "ToggleDirectionLine", chrmgrToggleDirectionLine, METH_VARARGS }, + { "SetMovingSpeed", chrmgrSetMovingSpeed, METH_VARARGS }, + { "SetDustGap", chrmgrSetDustGap, METH_VARARGS }, + { "SetHorseDustGap", chrmgrSetHorseDustGap, METH_VARARGS }, + + { "RegisterTitleName", chrmgrRegisterTitleName, METH_VARARGS }, + { "RegisterNameColor", chrmgrRegisterNameColor, METH_VARARGS }, + { "RegisterTitleColor", chrmgrRegisterTitleColor, METH_VARARGS }, + + { NULL, NULL, NULL }, + }; + + PyObject * poModule = Py_InitModule("chrmgr", s_methods); + + PyModule_AddIntConstant(poModule, "NAMECOLOR_MOB", CInstanceBase::NAMECOLOR_NORMAL_MOB); + PyModule_AddIntConstant(poModule, "NAMECOLOR_NPC", CInstanceBase::NAMECOLOR_NORMAL_NPC); + PyModule_AddIntConstant(poModule, "NAMECOLOR_PC", CInstanceBase::NAMECOLOR_NORMAL_PC); + PyModule_AddIntConstant(poModule, "NAMECOLOR_EMPIRE_MOB", CInstanceBase::NAMECOLOR_EMPIRE_MOB); + PyModule_AddIntConstant(poModule, "NAMECOLOR_EMPIRE_NPC", CInstanceBase::NAMECOLOR_EMPIRE_NPC); + PyModule_AddIntConstant(poModule, "NAMECOLOR_EMPIRE_PC", CInstanceBase::NAMECOLOR_EMPIRE_PC); + PyModule_AddIntConstant(poModule, "NAMECOLOR_FUNC", CInstanceBase::NAMECOLOR_FUNC); + PyModule_AddIntConstant(poModule, "NAMECOLOR_PK", CInstanceBase::NAMECOLOR_PK); + PyModule_AddIntConstant(poModule, "NAMECOLOR_PVP", CInstanceBase::NAMECOLOR_PVP); + PyModule_AddIntConstant(poModule, "NAMECOLOR_PARTY", CInstanceBase::NAMECOLOR_PARTY); + PyModule_AddIntConstant(poModule, "NAMECOLOR_WARP", CInstanceBase::NAMECOLOR_WARP); + PyModule_AddIntConstant(poModule, "NAMECOLOR_WAYPOINT", CInstanceBase::NAMECOLOR_WAYPOINT); + PyModule_AddIntConstant(poModule, "NAMECOLOR_EXTRA", CInstanceBase::NAMECOLOR_EXTRA); + + PyModule_AddIntConstant(poModule, "EFFECT_SPAWN_DISAPPEAR", CInstanceBase::EFFECT_SPAWN_DISAPPEAR); + PyModule_AddIntConstant(poModule, "EFFECT_SPAWN_APPEAR", CInstanceBase::EFFECT_SPAWN_APPEAR); + PyModule_AddIntConstant(poModule, "EFFECT_DUST", CInstanceBase::EFFECT_DUST); + PyModule_AddIntConstant(poModule, "EFFECT_HORSE_DUST", CInstanceBase::EFFECT_HORSE_DUST); + PyModule_AddIntConstant(poModule, "EFFECT_STUN", CInstanceBase::EFFECT_STUN); + PyModule_AddIntConstant(poModule, "EFFECT_HIT", CInstanceBase::EFFECT_HIT); + PyModule_AddIntConstant(poModule, "EFFECT_FLAME_ATTACK", CInstanceBase::EFFECT_FLAME_ATTACK); + PyModule_AddIntConstant(poModule, "EFFECT_FLAME_HIT", CInstanceBase::EFFECT_FLAME_HIT); + PyModule_AddIntConstant(poModule, "EFFECT_FLAME_ATTACH", CInstanceBase::EFFECT_FLAME_ATTACH); + PyModule_AddIntConstant(poModule, "EFFECT_ELECTRIC_ATTACK", CInstanceBase::EFFECT_ELECTRIC_ATTACK); + PyModule_AddIntConstant(poModule, "EFFECT_ELECTRIC_HIT", CInstanceBase::EFFECT_ELECTRIC_HIT); + PyModule_AddIntConstant(poModule, "EFFECT_ELECTRIC_ATTACH", CInstanceBase::EFFECT_ELECTRIC_ATTACH); + PyModule_AddIntConstant(poModule, "EFFECT_SELECT", CInstanceBase::EFFECT_SELECT); + PyModule_AddIntConstant(poModule, "EFFECT_TARGET", CInstanceBase::EFFECT_TARGET); + PyModule_AddIntConstant(poModule, "EFFECT_CRITICAL", CInstanceBase::EFFECT_CRITICAL); + + PyModule_AddIntConstant(poModule, "EFFECT_DAMAGE_TARGET", CInstanceBase::EFFECT_DAMAGE_TARGET); + PyModule_AddIntConstant(poModule, "EFFECT_DAMAGE_NOT_TARGET", CInstanceBase::EFFECT_DAMAGE_NOT_TARGET); + PyModule_AddIntConstant(poModule, "EFFECT_DAMAGE_SELFDAMAGE", CInstanceBase::EFFECT_DAMAGE_SELFDAMAGE); + PyModule_AddIntConstant(poModule, "EFFECT_DAMAGE_SELFDAMAGE2", CInstanceBase::EFFECT_DAMAGE_SELFDAMAGE2); + PyModule_AddIntConstant(poModule, "EFFECT_DAMAGE_POISON", CInstanceBase::EFFECT_DAMAGE_POISON); + PyModule_AddIntConstant(poModule, "EFFECT_DAMAGE_MISS", CInstanceBase::EFFECT_DAMAGE_MISS); + PyModule_AddIntConstant(poModule, "EFFECT_DAMAGE_TARGETMISS", CInstanceBase::EFFECT_DAMAGE_TARGETMISS); + PyModule_AddIntConstant(poModule, "EFFECT_DAMAGE_CRITICAL", CInstanceBase::EFFECT_DAMAGE_CRITICAL); + + PyModule_AddIntConstant(poModule, "EFFECT_LEVELUP", CInstanceBase::EFFECT_LEVELUP); + PyModule_AddIntConstant(poModule, "EFFECT_SKILLUP", CInstanceBase::EFFECT_SKILLUP); + PyModule_AddIntConstant(poModule, "EFFECT_HPUP_RED", CInstanceBase::EFFECT_HPUP_RED); + PyModule_AddIntConstant(poModule, "EFFECT_SPUP_BLUE", CInstanceBase::EFFECT_SPUP_BLUE); + PyModule_AddIntConstant(poModule, "EFFECT_SPEEDUP_GREEN", CInstanceBase::EFFECT_SPEEDUP_GREEN); + PyModule_AddIntConstant(poModule, "EFFECT_DXUP_PURPLE", CInstanceBase::EFFECT_DXUP_PURPLE); + PyModule_AddIntConstant(poModule, "EFFECT_PENETRATE", CInstanceBase::EFFECT_PENETRATE); + PyModule_AddIntConstant(poModule, "EFFECT_BLOCK", CInstanceBase::EFFECT_BLOCK); + PyModule_AddIntConstant(poModule, "EFFECT_DODGE", CInstanceBase::EFFECT_DODGE); + PyModule_AddIntConstant(poModule, "EFFECT_FIRECRACKER", CInstanceBase::EFFECT_FIRECRACKER); + PyModule_AddIntConstant(poModule, "EFFECT_SPIN_TOP", CInstanceBase::EFFECT_SPIN_TOP); + + PyModule_AddIntConstant(poModule, "EFFECT_WEAPON", CInstanceBase::EFFECT_WEAPON); + + PyModule_AddIntConstant(poModule, "EFFECT_AFFECT", CInstanceBase::EFFECT_AFFECT); + PyModule_AddIntConstant(poModule, "EFFECT_EMOTICON", CInstanceBase::EFFECT_EMOTICON); + PyModule_AddIntConstant(poModule, "EFFECT_EMPIRE", CInstanceBase::EFFECT_EMPIRE); + + PyModule_AddIntConstant(poModule, "EFFECT_REFINED", CInstanceBase::EFFECT_REFINED); + + PyModule_AddIntConstant(poModule, "EFFECT_SUCCESS", CInstanceBase::EFFECT_SUCCESS) ; + PyModule_AddIntConstant(poModule, "EFFECT_FAIL", CInstanceBase::EFFECT_FAIL) ; + PyModule_AddIntConstant(poModule, "EFFECT_FR_SUCCESS", CInstanceBase::EFFECT_FR_SUCCESS) ; + PyModule_AddIntConstant(poModule, "EFFECT_LEVELUP_ON_14_FOR_GERMANY", CInstanceBase::EFFECT_LEVELUP_ON_14_FOR_GERMANY ); // 14϶ ( ) + PyModule_AddIntConstant(poModule, "EFFECT_LEVELUP_UNDER_15_FOR_GERMANY", CInstanceBase::EFFECT_LEVELUP_UNDER_15_FOR_GERMANY );// 15϶ ( ) + PyModule_AddIntConstant(poModule, "EFFECT_PERCENT_DAMAGE1", CInstanceBase::EFFECT_PERCENT_DAMAGE1); + PyModule_AddIntConstant(poModule, "EFFECT_PERCENT_DAMAGE2", CInstanceBase::EFFECT_PERCENT_DAMAGE2); + PyModule_AddIntConstant(poModule, "EFFECT_PERCENT_DAMAGE3", CInstanceBase::EFFECT_PERCENT_DAMAGE3); + + // ڵ HP, SP + PyModule_AddIntConstant(poModule, "EFFECT_AUTO_HPUP", CInstanceBase::EFFECT_AUTO_HPUP); + PyModule_AddIntConstant(poModule, "EFFECT_AUTO_SPUP", CInstanceBase::EFFECT_AUTO_SPUP); + + PyModule_AddIntConstant(poModule, "EFFECT_RAMADAN_RING_EQUIP", CInstanceBase::EFFECT_RAMADAN_RING_EQUIP); + PyModule_AddIntConstant(poModule, "EFFECT_HALLOWEEN_CANDY_EQUIP", CInstanceBase::EFFECT_HALLOWEEN_CANDY_EQUIP); + PyModule_AddIntConstant(poModule, "EFFECT_HAPPINESS_RING_EQUIP", CInstanceBase::EFFECT_HAPPINESS_RING_EQUIP); + PyModule_AddIntConstant(poModule, "EFFECT_LOVE_PENDANT_EQUIP", CInstanceBase::EFFECT_LOVE_PENDANT_EQUIP); + +} diff --git a/source/UserInterface/PythonCharacterModule.cpp b/source/UserInterface/PythonCharacterModule.cpp new file mode 100644 index 0000000..bbd95c5 --- /dev/null +++ b/source/UserInterface/PythonCharacterModule.cpp @@ -0,0 +1,1491 @@ +#include "StdAfx.h" +#include "PythonCharacterManager.h" +#include "PythonNonPlayer.h" + +PyObject * chrRaceToJob(PyObject * poSelf, PyObject * poArgs) +{ + int race; + if (!PyTuple_GetInteger(poArgs, 0, &race)) + return Py_BuildException(); + + return Py_BuildValue("i", RaceToJob(race)); +} + +PyObject * chrRaceToSex(PyObject * poSelf, PyObject * poArgs) +{ + int race; + if (!PyTuple_GetInteger(poArgs, 0, &race)) + return Py_BuildException(); + + return Py_BuildValue("i", RaceToSex(race)); +} + +PyObject * chrDestroy(PyObject * poSelf, PyObject * poArgs) +{ + CPythonCharacterManager::Instance().Destroy(); + return Py_BuildNone(); +} + +PyObject * chrUpdate(PyObject * poSelf, PyObject * poArgs) +{ + CPythonCharacterManager::Instance().Update(); + return Py_BuildNone(); +} + +PyObject * chrDeform(PyObject * poSelf, PyObject * poArgs) +{ + CPythonCharacterManager::Instance().Deform(); + return Py_BuildNone(); +} + +PyObject * chrRender(PyObject * poSelf, PyObject * poArgs) +{ + CPythonCharacterManager::Instance().Render(); + return Py_BuildNone(); +} + +PyObject * chrRenderCollision(PyObject * poSelf, PyObject * poArgs) +{ + CPythonCharacterManager::Instance().RenderCollision(); + return Py_BuildNone(); +} + +// Functions For Python Test Code +PyObject * chrCreateInstance(PyObject* poSelf, PyObject* poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + + if (PyTuple_Size(poArgs)==2) + { + PyObject* poDict=PyTuple_GetItem(poArgs, 1); + if (!PyDict_Check(poDict)) + return Py_BuildException(); + + CInstanceBase::SCreateData kCreateData; + kCreateData.m_bType=CActorInstance::TYPE_PC; + kCreateData.m_dwLevel = 0; + kCreateData.m_dwGuildID=0; + kCreateData.m_dwEmpireID=0; + kCreateData.m_dwVID=iVirtualID; + kCreateData.m_dwMountVnum=0; + kCreateData.m_dwRace=0; + kCreateData.m_fRot=CInstanceBase::DIR_NORTH; + kCreateData.m_lPosX=0; + kCreateData.m_lPosY=0; + kCreateData.m_stName="NONAME"; + kCreateData.m_dwStateFlags=0; + kCreateData.m_dwMovSpd=100; + kCreateData.m_dwAtkSpd=100; + kCreateData.m_sAlignment=0; + kCreateData.m_byPKMode=0; + kCreateData.m_kAffectFlags.Clear(); + kCreateData.m_dwArmor=8; + kCreateData.m_dwWeapon=0; + kCreateData.m_dwHair=0; + kCreateData.m_isMain=false; + + PyObject* poHorse=PyDict_GetItemString(poDict, "horse"); + if (poHorse) + kCreateData.m_dwMountVnum=PyLong_AsLong(poHorse); + + PyObject* poX=PyDict_GetItemString(poDict, "x"); + if (poX) + kCreateData.m_lPosX=PyLong_AsLong(poX); + + PyObject* poY=PyDict_GetItemString(poDict, "y"); + if (poY) + kCreateData.m_lPosX=PyLong_AsLong(poY); + + CPythonCharacterManager::Instance().CreateInstance(kCreateData); + } + else + { + CPythonCharacterManager::Instance().RegisterInstance(iVirtualID); + } + + return Py_BuildNone(); +} + +PyObject * chrDeleteInstance(PyObject* poSelf, PyObject* poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + + CPythonCharacterManager::Instance().DeleteInstance(iVirtualID); + return Py_BuildNone(); +} + +PyObject * chrDeleteInstanceByFade(PyObject* poSelf, PyObject* poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + + CPythonCharacterManager::Instance().DeleteInstanceByFade(iVirtualID); + return Py_BuildNone(); +} + +PyObject * chrSelectInstance(PyObject* poSelf, PyObject* poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + + CPythonCharacterManager::Instance().SelectInstance(iVirtualID); + return Py_BuildNone(); +} + +PyObject * chrHasInstance(PyObject* poSelf, PyObject* poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + + bool bFlag = CPythonCharacterManager::Instance().GetInstancePtr(iVirtualID) ? TRUE : FALSE; + return Py_BuildValue("i", bFlag); +} + +PyObject * chrIsEnemy(PyObject* poSelf, PyObject* poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + + CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetInstancePtr(iVirtualID); + if (!pInstance) + return Py_BuildValue("i", 0); + + return Py_BuildValue("i", pInstance->IsEnemy()); +} + +PyObject * chrIsNPC(PyObject* poSelf, PyObject* poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + + CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetInstancePtr(iVirtualID); + if (!pInstance) + return Py_BuildValue("i", 0); + + return Py_BuildValue("i", pInstance->IsNPC()); +} + +PyObject * chrIsGameMaster(PyObject* poSelf, PyObject* poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + + CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetInstancePtr(iVirtualID); + if (!pInstance) + return Py_BuildValue("i", 0); + + return Py_BuildValue("i", pInstance->IsGameMaster()); +} + +PyObject * chrIsPartyMember(PyObject* poSelf, PyObject* poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + + CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetInstancePtr(iVirtualID); + if (!pInstance) + return Py_BuildValue("i", 0); + + return Py_BuildValue("i", pInstance->IsPartyMember()); +} + +PyObject * chrSelect(PyObject* poSelf, PyObject* poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetInstancePtr(iVirtualID); + + if (!pkInst) + return Py_BuildNone(); + + switch (CPythonNonPlayer::Instance().GetEventType(pkInst->GetVirtualNumber())) + { + case CPythonNonPlayer::ON_CLICK_EVENT_SHOP: + pkInst->SetAddRenderMode(); + pkInst->SetAddColor(D3DXCOLOR(0.0f, 0.3f, 0.0f, 1.0f)); + break; + + default: + // NOTE: ϸ Ⱑ Ƽ ڸƮ Ͽϴ [cronan 040226] + //pkInst->SetAddColor(D3DXCOLOR(0.3f, 0.0f, 0.0f, 1.0f)); + break; + } + + return Py_BuildNone(); +} + +PyObject * chrSetAddRenderMode(PyObject* poSelf, PyObject* poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + + float fr; + if (!PyTuple_GetFloat(poArgs, 1, &fr)) + return Py_BuildException(); + float fg; + if (!PyTuple_GetFloat(poArgs, 2, &fg)) + return Py_BuildException(); + float fb; + if (!PyTuple_GetFloat(poArgs, 3, &fb)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetInstancePtr(iVirtualID); + + if (!pkInst) + return Py_BuildNone(); + + pkInst->SetAddRenderMode(); + pkInst->SetAddColor(D3DXCOLOR(fr, fg, fb, 1.0f)); + + return Py_BuildNone(); +} + +PyObject * chrSetBlendRenderMode(PyObject* poSelf, PyObject* poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + + float fAlpha; + if (!PyTuple_GetFloat(poArgs, 1, &fAlpha)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetInstancePtr(iVirtualID); + + if (!pkInst) + return Py_BuildNone(); + + pkInst->SetAlpha(fAlpha); + + return Py_BuildNone(); +} + +PyObject * chrUnselect(PyObject* poSelf, PyObject* poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetInstancePtr(iVirtualID); + if (!pkInst) + return Py_BuildNone(); + + pkInst->RestoreRenderMode(); + return Py_BuildNone(); +} + +PyObject * chrPick(PyObject* poSelf, PyObject* poArgs) +{ + DWORD VirtualID = 0; + if (CPythonCharacterManager::Instance().OLD_GetPickedInstanceVID(&VirtualID)) + return Py_BuildValue("i", VirtualID); + else + return Py_BuildValue("i", -1); +} + +PyObject * chrHide(PyObject* poSelf, PyObject* poArgs) +{ + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + if (!pkInst) + return Py_BuildNone(); + + pkInst->Hide(); + return Py_BuildNone(); +} + +PyObject * chrShow(PyObject* poSelf, PyObject* poArgs) +{ + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + if (!pkInst) + return Py_BuildNone(); + + pkInst->Show(); + return Py_BuildNone(); +} + +PyObject * chrPickAll(PyObject* poSelf, PyObject* poArgs) +{ + DWORD VirtualID = CPythonCharacterManager::Instance().PickAll(); + return Py_BuildValue("i", VirtualID); +} + +PyObject * chrSetRace(PyObject* poSelf, PyObject* poArgs) +{ + int iRace; + if (!PyTuple_GetInteger(poArgs, 0, &iRace)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + if (!pkInst) + return Py_BuildNone(); + + pkInst->SetRace(iRace); + + return Py_BuildNone(); +} + +PyObject * chrSetHair(PyObject* poSelf, PyObject* poArgs) +{ + int iRace; + if (!PyTuple_GetInteger(poArgs, 0, &iRace)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + if (!pkInst) + return Py_BuildNone(); + + pkInst->SetHair(iRace); + + return Py_BuildNone(); +} + +PyObject * chrChangeHair(PyObject* poSelf, PyObject* poArgs) +{ + int iHair; + + if (!PyTuple_GetInteger(poArgs, 0, &iHair)) + return Py_BuildException(); + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + if (!pkInst) + return Py_BuildNone(); + pkInst->ChangeHair(iHair); + return Py_BuildNone(); +} + +PyObject * chrSetArmor(PyObject* poSelf, PyObject* poArgs) +{ + int iForm; + if (!PyTuple_GetInteger(poArgs, 0, &iForm)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + if (!pkInst) + return Py_BuildNone(); + + pkInst->SetArmor(iForm); + + pkInst->RegisterBoundingSphere(); + + return Py_BuildNone(); +} + +PyObject * chrChangeShape(PyObject* poSelf, PyObject* poArgs) +{ + int iForm; + if (!PyTuple_GetInteger(poArgs, 0, &iForm)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + if (!pkInst) + return Py_BuildNone(); + + pkInst->ChangeArmor(iForm); + + return Py_BuildNone(); +} + +PyObject * chrSetWeapon(PyObject* poSelf, PyObject* poArgs) +{ + int iForm; + if (!PyTuple_GetInteger(poArgs, 0, &iForm)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + if (!pkInst) + return Py_BuildNone(); + + pkInst->SetWeapon(iForm); + + return Py_BuildNone(); +} + +PyObject * chrSetVirtualID(PyObject* poSelf, PyObject* poArgs) +{ + int iVID; + if (!PyTuple_GetInteger(poArgs, 0, &iVID)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + if (!pkInst) + return Py_BuildNone(); + pkInst->SetVirtualID(iVID); + return Py_BuildNone(); +} + +PyObject * chrSetNameString(PyObject* poSelf, PyObject* poArgs) +{ + char * c_szName; + if (!PyTuple_GetString(poArgs, 0, &c_szName)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + if (!pkInst) + return Py_BuildNone(); + pkInst->SetNameString(c_szName, strlen(c_szName)); + return Py_BuildNone(); +} + +PyObject * chrSetInstanceType(PyObject* poSelf, PyObject* poArgs) +{ + int iInstanceType; + if (!PyTuple_GetInteger(poArgs, 0, &iInstanceType)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + if (!pkInst) + return Py_BuildNone(); + pkInst->SetInstanceType(iInstanceType); + return Py_BuildNone(); +} + +PyObject * chrAttachEffectByName(PyObject* poSelf, PyObject* poArgs) +{ + int iParentPartIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iParentPartIndex)) + return Py_BuildException(); + + char * pszBoneName; + if (!PyTuple_GetString(poArgs, 1, &pszBoneName)) + { + pszBoneName = NULL; + //return Py_BuildException(); + } + + char * pszEffectName; + if (!PyTuple_GetString(poArgs, 2, &pszEffectName)) + return Py_BuildException(); + + int iLife = CActorInstance::EFFECT_LIFE_INFINITE; + + if (PyTuple_Size(poArgs)==4) + { + if (!PyTuple_GetInteger(poArgs, 3, &iLife)) + return Py_BuildException(); + } + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + + if (!pkInst) + return Py_BuildNone(); + + //pkInst->AttachEffectByName(iParentPartIndex, pszBoneName, pszEffectName, iLife); + return Py_BuildNone(); +} + +PyObject * chrAttachEffectByID(PyObject* poSelf, PyObject* poArgs) +{ + int iParentPartIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iParentPartIndex)) + return Py_BuildException(); + + char * pszBoneName; + if (!PyTuple_GetString(poArgs, 1, &pszBoneName)) + { + pszBoneName = NULL; + } + // return Py_BuildException(); + + // FIXME : bug or error on getting unsigned value + int iEffectID; + if (!PyTuple_GetInteger(poArgs, 2, &iEffectID)) + return Py_BuildException(); + + int iLife = CActorInstance::EFFECT_LIFE_INFINITE; + + if (PyTuple_Size(poArgs)==4) + { + if (!PyTuple_GetInteger(poArgs, 3, &iLife)) + return Py_BuildException(); + } + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + + if (!pkInst) + return Py_BuildNone(); + + //pkInst->AttachEffectByID(iParentPartIndex, pszBoneName, iEffectID, iLife); + return Py_BuildNone(); +} + +PyObject * chrRefresh(PyObject* poSelf, PyObject* poArgs) +{ + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + + if (!pkInst) + return Py_BuildNone(); + + // Select ȭ鿡 WAIT غ ̱ . + //pkInst->Refresh(CRaceMotionData::NAME_WAIT, true); + return Py_BuildNone(); +} + +PyObject * chrMountHorse(PyObject* poSelf, PyObject* poArgs) +{ + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + if (!pkInst) + return Py_BuildNone(); + pkInst->MountHorse(20030); + return Py_BuildNone(); +} + +PyObject * chrDismountHorse(PyObject* poSelf, PyObject* poArgs) +{ + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + if (!pkInst) + return Py_BuildNone(); + pkInst->DismountHorse(); + return Py_BuildNone(); +} + +PyObject * chrRevive(PyObject* poSelf, PyObject* poArgs) +{ + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + if (!pkInst) + return Py_BuildNone(); + pkInst->Revive(); + return Py_BuildNone(); +} + +PyObject * chrDie(PyObject* poSelf, PyObject* poArgs) +{ + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + if (!pkInst) + return Py_BuildNone(); + pkInst->Die(); + return Py_BuildNone(); +} + +PyObject * chrLookAt(PyObject* poSelf, PyObject* poArgs) +{ + int iCellX; + if (!PyTuple_GetInteger(poArgs, 0, &iCellX)) + return Py_BuildException(); + + int iCellY; + if (!PyTuple_GetInteger(poArgs, 1, &iCellY)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + if (!pkInst) + return Py_BuildNone(); +// pkInst->LookAt(TPixelPosition(iCellX * c_Section_xAttributeCellSize, iCellY * c_Section_xAttributeCellSize)); + return Py_BuildNone(); +} + +PyObject * chrSetMotionMode(PyObject* poSelf, PyObject* poArgs) +{ + int iMotionMode; + if (!PyTuple_GetInteger(poArgs, 0, &iMotionMode)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + if (!pkInst) + return Py_BuildNone(); + + pkInst->SetMotionMode(iMotionMode); + return Py_BuildNone(); +} + +PyObject * chrSetLoopMotion(PyObject* poSelf, PyObject* poArgs) +{ + int iMotionIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iMotionIndex)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + if (!pkInst) + return Py_BuildNone(); + pkInst->SetLoopMotion(WORD(iMotionIndex)); + + return Py_BuildNone(); +} + +PyObject * chrBlendLoopMotion(PyObject* poSelf, PyObject* poArgs) +{ + int iMotionIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iMotionIndex)) + return Py_BuildException(); + float fBlendTime; + if (!PyTuple_GetFloat(poArgs, 1, &fBlendTime)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + if (!pkInst) + return Py_BuildNone(); + pkInst->SetLoopMotion(WORD(iMotionIndex), fBlendTime); + + return Py_BuildNone(); +} + +PyObject * chrPushOnceMotion(PyObject* poSelf, PyObject* poArgs) +{ + int iMotionIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iMotionIndex)) + return Py_BuildException(); + + float fBlendTime; + if (!PyTuple_GetFloat(poArgs, 1, &fBlendTime)) + { + fBlendTime = 0.1f; + } + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + if (!pkInst) + return Py_BuildNone(); + pkInst->PushOnceMotion(WORD(iMotionIndex), fBlendTime); + + return Py_BuildNone(); +} + +PyObject * chrPushLoopMotion(PyObject* poSelf, PyObject* poArgs) +{ + int iMotionIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iMotionIndex)) + return Py_BuildException(); + + float fBlendTime; + if (!PyTuple_GetFloat(poArgs, 1, &fBlendTime)) + { + fBlendTime = 0.1f; + } + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + if (!pkInst) + return Py_BuildNone(); + pkInst->PushLoopMotion(WORD(iMotionIndex), fBlendTime); + + return Py_BuildNone(); +} + +PyObject * chrSetPixelPosition(PyObject* poSelf, PyObject* poArgs) +{ + int iX; + if (!PyTuple_GetInteger(poArgs, 0, &iX)) + return Py_BuildException(); + int iY; + if (!PyTuple_GetInteger(poArgs, 1, &iY)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + if (!pkInst) + return Py_BuildNone(); + + int iZ; + if (PyTuple_GetInteger(poArgs, 2, &iZ)) + { + pkInst->NEW_SetPixelPosition(TPixelPosition(iX, iY, iZ)); + } + else + { + pkInst->SCRIPT_SetPixelPosition(iX, iY); + } + return Py_BuildNone(); +} + +PyObject * chrSetDirection(PyObject* poSelf, PyObject* poArgs) +{ + int iDirection; + if (!PyTuple_GetInteger(poArgs, 0, &iDirection)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + pkInst->SetDirection(iDirection); + return Py_BuildNone(); +} + +PyObject * chrGetPixelPosition(PyObject* poSelf, PyObject* poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetInstancePtr(iVirtualID); + + if (!pkInst) + return Py_BuildException(); + + TPixelPosition PixelPosition; + pkInst->NEW_GetPixelPosition(&PixelPosition); + + return Py_BuildValue("fff", PixelPosition.x, PixelPosition.y, PixelPosition.z); +} + +PyObject * chrSetRotation(PyObject* poSelf, PyObject* poArgs) +{ + float fRotation; + if (!PyTuple_GetFloat(poArgs, 0, &fRotation)) + return Py_BuildException(); + + CInstanceBase * pCharacterInstance = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + + if (!pCharacterInstance) + return Py_BuildNone(); + + fRotation = fmod(fRotation + 180.0f, 360.0f); + + pCharacterInstance->SetRotation(fRotation); + + return Py_BuildNone(); +} + +PyObject * chrSetRotationAll(PyObject* poSelf, PyObject* poArgs) +{ + float fRotX; + if (!PyTuple_GetFloat(poArgs, 0, &fRotX)) + return Py_BuildException(); + float fRotY; + if (!PyTuple_GetFloat(poArgs, 1, &fRotY)) + return Py_BuildException(); + float fRotZ; + if (!PyTuple_GetFloat(poArgs, 2, &fRotZ)) + return Py_BuildException(); + + CInstanceBase * pCharacterInstance = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + if (!pCharacterInstance) + return Py_BuildNone(); + + pCharacterInstance->GetGraphicThingInstanceRef().SetXYRotation(fRotX, fRotY); + pCharacterInstance->GetGraphicThingInstanceRef().SetRotation(fRotZ); + return Py_BuildNone(); +} + +PyObject * chrBlendRotation(PyObject* poSelf, PyObject* poArgs) +{ + float fRotation; + if (!PyTuple_GetFloat(poArgs, 0, &fRotation)) + return Py_BuildException(); + float fBlendTime; + if (!PyTuple_GetFloat(poArgs, 1, &fBlendTime)) + return Py_BuildException(); + + fRotation = fmod(720.0f - fRotation, 360.0f); + + CInstanceBase * pCharacterInstance = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + if (!pCharacterInstance) + return Py_BuildNone(); + pCharacterInstance->BlendRotation(fRotation, fBlendTime); + + return Py_BuildNone(); +} + +PyObject * chrGetRotation(PyObject* poSelf, PyObject* poArgs) +{ + CInstanceBase * pCharacterInstance = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + + if (!pCharacterInstance) + return Py_BuildValue("f", 0.0f); + + float fRotation = pCharacterInstance->GetRotation(); + + return Py_BuildValue("f", 360.0f - fRotation); +} + +PyObject * chrGetRace(PyObject* poSelf, PyObject* poArgs) +{ + CInstanceBase * pCharacterInstance = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + + if (!pCharacterInstance) + return Py_BuildValue("i", 0); + + return Py_BuildValue("i", pCharacterInstance->GetRace()); +} + +PyObject * chrGetName(PyObject* poSelf, PyObject* poArgs) +{ + CInstanceBase * pCharacterInstance = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + + if (!pCharacterInstance) + return Py_BuildValue("i", 0); + + return Py_BuildValue("s", pCharacterInstance->GetNameString()); +} + +PyObject * chrGetNameByVID(PyObject* poSelf, PyObject* poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + + CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetInstancePtr(iVirtualID); + + if (!pInstance) + return Py_BuildValue("s", "None"); + + return Py_BuildValue("s", pInstance->GetNameString()); +} + +PyObject * chrGetGuildID(PyObject* poSelf, PyObject* poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + + CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetInstancePtr(iVirtualID); + + if (!pInstance) + return Py_BuildValue("i", 0); + + return Py_BuildValue("i", pInstance->GetGuildID()); +} + +PyObject * chrGetProjectPosition(PyObject* poSelf, PyObject* poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + int iHeight; + if (!PyTuple_GetInteger(poArgs, 1, &iHeight)) + return Py_BuildException(); + + CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetInstancePtr(iVirtualID); + + if (!pInstance) + return Py_BuildValue("ii", -100, -100); + + TPixelPosition PixelPosition; + pInstance->NEW_GetPixelPosition(&PixelPosition); + + CPythonGraphic & rpyGraphic = CPythonGraphic::Instance(); + + float fx, fy, fz; + rpyGraphic.ProjectPosition(PixelPosition.x, + -PixelPosition.y, + PixelPosition.z + float(iHeight), + &fx, &fy, &fz); + + if (1 == int(fz)) + return Py_BuildValue("ii", -100, -100); + + return Py_BuildValue("ii", int(fx), int(fy)); +} + +PyObject * chrGetVirtualNumber(PyObject* poSelf, PyObject* poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetInstancePtr(iVirtualID); + + if (NULL != pkInst) + return Py_BuildValue("i", pkInst->GetVirtualNumber()); + + return Py_BuildValue("i", CActorInstance::TYPE_PC); +} + +PyObject * chrGetInstanceType(PyObject* poSelf, PyObject* poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetInstancePtr(iVirtualID); + + if (NULL != pkInst) + return Py_BuildValue("i", pkInst->GetInstanceType()); + + return Py_BuildValue("i", CActorInstance::TYPE_PC); +} + +PyObject * chrGetBoundBoxOnlyXY(PyObject* poSelf, PyObject* poArgs) +{ + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + + if (!pkInst) + return Py_BuildValue("ffff", 0.0f, 0.0f, 0.0f, 0.0f); + + D3DXVECTOR3 v3Min, v3Max; + pkInst->GetBoundBox(&v3Min, &v3Max); + + return Py_BuildValue("ffff", v3Min.x, v3Min.y, v3Max.x, v3Max.y); +} + +PyObject * chrtestGetPKData(PyObject* poSelf, PyObject* poArgs) +{ + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + + if (!pkInst) + return Py_BuildValue("ii", 0, 4); + + return Py_BuildValue("ii", pkInst->GetAlignment(), pkInst->GetAlignmentGrade()); +} + +PyObject * chrtestSetComboType(PyObject* poSelf, PyObject* poArgs) +{ + int iComboType; + if (!PyTuple_GetInteger(poArgs, 0, &iComboType)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + if (!pkInst) + return Py_BuildNone(); + + pkInst->GetGraphicThingInstanceRef().SetComboType(iComboType); + + return Py_BuildNone(); +} + +PyObject * chrtestSetAddRenderMode(PyObject* poSelf, PyObject* poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + int iColor; + if (!PyTuple_GetInteger(poArgs, 1, &iColor)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetInstancePtr(iVirtualID); + if (pkInst) + { + pkInst->SetAddRenderMode(); + pkInst->SetAddColor(0xff000000 | iColor); + } + + return Py_BuildNone(); +} + +PyObject * chrtestSetModulateRenderMode(PyObject* poSelf, PyObject* poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + int iColor; + if (!PyTuple_GetInteger(poArgs, 1, &iColor)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetInstancePtr(iVirtualID); + if (pkInst) + { + pkInst->SetModulateRenderMode(); + pkInst->SetAddColor(0xff000000 | iColor); + } + + return Py_BuildNone(); +} + +PyObject * chrtestSetAddRenderModeRGB(PyObject* poSelf, PyObject* poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + float fr; + if (!PyTuple_GetFloat(poArgs, 1, &fr)) + return Py_BuildException(); + float fg; + if (!PyTuple_GetFloat(poArgs, 2, &fg)) + return Py_BuildException(); + float fb; + if (!PyTuple_GetFloat(poArgs, 3, &fb)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetInstancePtr(iVirtualID); + if (pkInst) + { + pkInst->SetAddRenderMode(); + pkInst->SetAddColor(D3DXCOLOR(fr, fg, fb, 1.0f)); + } + + return Py_BuildNone(); +} + +PyObject * chrtestSetModulateRenderModeRGB(PyObject* poSelf, PyObject* poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + float fr; + if (!PyTuple_GetFloat(poArgs, 1, &fr)) + return Py_BuildException(); + float fg; + if (!PyTuple_GetFloat(poArgs, 2, &fg)) + return Py_BuildException(); + float fb; + if (!PyTuple_GetFloat(poArgs, 3, &fb)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetInstancePtr(iVirtualID); + if (pkInst) + { + pkInst->SetModulateRenderMode(); + pkInst->SetAddColor(D3DXCOLOR(fr, fg, fb, 1.0f)); + } + + return Py_BuildNone(); +} + +PyObject * chrtestSetSpecularRenderMode(PyObject* poSelf, PyObject* poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + int iPart; + if (!PyTuple_GetInteger(poArgs, 1, &iPart)) + return Py_BuildException(); + float fAlpha; + if (!PyTuple_GetFloat(poArgs, 2, &fAlpha)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetInstancePtr(iVirtualID); + if (pkInst) + { + pkInst->GetGraphicThingInstanceRef().SetSpecularInfo(TRUE, iPart, fAlpha); + } + + return Py_BuildNone(); +} + +PyObject * chrtestSetSpecularRenderMode2(PyObject* poSelf, PyObject* poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + int iPart; + if (!PyTuple_GetInteger(poArgs, 1, &iPart)) + return Py_BuildException(); + float fAlpha; + if (!PyTuple_GetFloat(poArgs, 2, &fAlpha)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetInstancePtr(iVirtualID); + if (pkInst) + { + pkInst->GetGraphicThingInstanceRef().SetSpecularInfoForce(TRUE, iPart, fAlpha); + } + + return Py_BuildNone(); +} + +PyObject * chrtestRestoreRenderMode(PyObject* poSelf, PyObject* poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetInstancePtr(iVirtualID); + if (pkInst) + { + pkInst->RestoreRenderMode(); + } + + return Py_BuildNone(); +} + +PyObject * chrFaintTest(PyObject* poSelf, PyObject* poArgs) +{ + CInstanceBase * pCharacterInstance = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + if (pCharacterInstance) + { + if (pCharacterInstance->GetGraphicThingInstanceRef().IsFaint()) + { + pCharacterInstance->GetGraphicThingInstanceRef().SetFaint(false); + } + else + { + pCharacterInstance->GetGraphicThingInstanceRef().InterceptOnceMotion(CRaceMotionData::NAME_DAMAGE_FLYING); + pCharacterInstance->GetGraphicThingInstanceRef().PushOnceMotion(CRaceMotionData::NAME_STAND_UP); + pCharacterInstance->GetGraphicThingInstanceRef().PushLoopMotion(CRaceMotionData::NAME_WAIT); + pCharacterInstance->GetGraphicThingInstanceRef().SetFaint(true); + } + } + + return Py_BuildNone(); +} + +PyObject * chrSetMoveSpeed(PyObject* poSelf, PyObject* poArgs) +{ + //int iSpeed; + //if (!PyTuple_GetInteger(poArgs, 0, &iSpeed)) + // return Py_BadArgument(); + + //CInstanceBase * pCharacterInstance = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + + //if (!pCharacterInstance) + // return Py_BuildValue("i", 0); + + //pCharacterInstance->SetMoveSpeed(iSpeed); + + return Py_BuildNone(); +} + +PyObject * chrSetAttackSpeed(PyObject* poSelf, PyObject* poArgs) +{ + //int iSpeed; + //if (!PyTuple_GetInteger(poArgs, 0, &iSpeed)) + // return Py_BadArgument(); + + //CInstanceBase * pCharacterInstance = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + + //if (!pCharacterInstance) + // return Py_BuildValue("i", 0); + + //pCharacterInstance->SetAttackSpeed(iSpeed); + + return Py_BuildNone(); +} + +PyObject * chrWeaponTraceSetTexture(PyObject* poSelf, PyObject* poArgs) +{ + char * szPathName; + if (!PyTuple_GetString(poArgs, 0, &szPathName)) + return Py_BadArgument(); + + CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetMainInstancePtr(); + if (pInstance) + { + pInstance->GetGraphicThingInstanceRef().SetWeaponTraceTexture(szPathName); + } + return Py_BuildNone(); +} + +PyObject * chrWeaponTraceUseTexture(PyObject* poSelf, PyObject* poArgs) +{ + CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetMainInstancePtr(); + if (pInstance) + { + pInstance->GetGraphicThingInstanceRef().UseTextureWeaponTrace(); + } + return Py_BuildNone(); +} + +PyObject * chrWeaponTraceUseAlpha(PyObject* poSelf, PyObject* poArgs) +{ + CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetMainInstancePtr(); + if (pInstance) + { + pInstance->GetGraphicThingInstanceRef().UseAlphaWeaponTrace(); + } + return Py_BuildNone(); +} + +PyObject * chrMoveToDestPosition(PyObject* poSelf, PyObject* poArgs) +{ + int iVID; + if (!PyTuple_GetInteger(poArgs, 0, &iVID)) + return Py_BadArgument(); + + int ix; + if (!PyTuple_GetInteger(poArgs, 1, &ix)) + return Py_BadArgument(); + int iy; + if (!PyTuple_GetInteger(poArgs, 2, &iy)) + return Py_BadArgument(); + + CInstanceBase * pCharacterInstance = CPythonCharacterManager::Instance().GetInstancePtr(iVID); + if (!pCharacterInstance) + return Py_BuildNone(); + + pCharacterInstance->NEW_MoveToDestPixelPositionDirection(TPixelPosition(ix, iy, 0.0f)); + + return Py_BuildNone(); +} + +PyObject * chrtestSetRideMan(PyObject* poSelf, PyObject* poArgs) +{ + int ix; + if (!PyTuple_GetInteger(poArgs, 0, &ix)) + return Py_BadArgument(); + int iy; + if (!PyTuple_GetInteger(poArgs, 1, &iy)) + return Py_BadArgument(); + int imount = 20030; + PyTuple_GetInteger(poArgs, 2, &imount); + + CInstanceBase * pCharacterInstance = CPythonCharacterManager::Instance().RegisterInstance(1); + CInstanceBase::SCreateData kCreateData; + ZeroMemory(&kCreateData, sizeof(kCreateData)); + kCreateData.m_bType = CActorInstance::TYPE_PC; + kCreateData.m_dwRace = 0; + kCreateData.m_dwArmor = 0; + kCreateData.m_dwHair = 100; + kCreateData.m_dwMovSpd = 100; + kCreateData.m_dwAtkSpd = 100; + kCreateData.m_dwMountVnum = imount; + kCreateData.m_lPosX = ix; + kCreateData.m_lPosY = iy; + pCharacterInstance->Create(kCreateData); + + return Py_BuildNone(); +} + +void initchr() +{ + static PyMethodDef s_methods[] = + { + { "DismountHorse", chrDismountHorse, METH_VARARGS }, + { "MountHorse", chrMountHorse, METH_VARARGS }, + + { "Destroy", chrDestroy, METH_VARARGS }, + { "Update", chrUpdate, METH_VARARGS }, + { "Deform", chrDeform, METH_VARARGS }, + { "Render", chrRender, METH_VARARGS }, + { "RenderCollision", chrRenderCollision, METH_VARARGS }, + + // Functions For Python Code + { "CreateInstance", chrCreateInstance, METH_VARARGS }, + { "DeleteInstance", chrDeleteInstance, METH_VARARGS }, + { "DeleteInstanceByFade", chrDeleteInstanceByFade, METH_VARARGS }, + { "SelectInstance", chrSelectInstance, METH_VARARGS }, + + { "HasInstance", chrHasInstance, METH_VARARGS }, + { "IsEnemy", chrIsEnemy, METH_VARARGS }, + { "IsNPC", chrIsNPC, METH_VARARGS }, + { "IsGameMaster", chrIsGameMaster, METH_VARARGS }, + { "IsPartyMember", chrIsPartyMember, METH_VARARGS }, + + { "Select", chrSelect, METH_VARARGS }, + { "SetAddRenderMode", chrSetAddRenderMode, METH_VARARGS }, + { "SetBlendRenderMode", chrSetBlendRenderMode, METH_VARARGS }, + { "Unselect", chrUnselect, METH_VARARGS }, + + { "Hide", chrHide, METH_VARARGS }, + { "Show", chrShow, METH_VARARGS }, + { "Pick", chrPick, METH_VARARGS }, + { "PickAll", chrPickAll, METH_VARARGS }, + + { "SetArmor", chrSetArmor, METH_VARARGS }, + { "SetWeapon", chrSetWeapon, METH_VARARGS }, + { "ChangeShape", chrChangeShape, METH_VARARGS }, + { "SetRace", chrSetRace, METH_VARARGS }, + { "SetHair", chrSetHair, METH_VARARGS }, + { "ChangeHair", chrChangeHair, METH_VARARGS }, + { "SetVirtualID", chrSetVirtualID, METH_VARARGS }, + { "SetNameString", chrSetNameString, METH_VARARGS }, + { "SetInstanceType", chrSetInstanceType, METH_VARARGS }, + + { "SetPixelPosition", chrSetPixelPosition, METH_VARARGS }, + { "SetDirection", chrSetDirection, METH_VARARGS }, + { "Refresh", chrRefresh, METH_VARARGS }, + { "Revive", chrRevive, METH_VARARGS }, + { "Die", chrDie, METH_VARARGS }, + + { "AttachEffectByID", chrAttachEffectByID, METH_VARARGS }, + { "AttachEffectByName", chrAttachEffectByName, METH_VARARGS }, + + { "LookAt", chrLookAt, METH_VARARGS }, + { "SetMotionMode", chrSetMotionMode, METH_VARARGS }, + { "SetLoopMotion", chrSetLoopMotion, METH_VARARGS }, + { "BlendLoopMotion", chrBlendLoopMotion, METH_VARARGS }, + { "PushOnceMotion", chrPushOnceMotion, METH_VARARGS }, + { "PushLoopMotion", chrPushLoopMotion, METH_VARARGS }, + { "GetPixelPosition", chrGetPixelPosition, METH_VARARGS }, + { "SetRotation", chrSetRotation, METH_VARARGS }, + { "SetRotationAll", chrSetRotationAll, METH_VARARGS }, + { "BlendRotation", chrBlendRotation, METH_VARARGS }, + { "GetRotation", chrGetRotation, METH_VARARGS }, + { "GetRace", chrGetRace, METH_VARARGS }, + { "GetName", chrGetName, METH_VARARGS }, + { "GetNameByVID", chrGetNameByVID, METH_VARARGS }, + { "GetGuildID", chrGetGuildID, METH_VARARGS }, + { "GetProjectPosition", chrGetProjectPosition, METH_VARARGS }, + + { "GetVirtualNumber", chrGetVirtualNumber, METH_VARARGS }, + { "GetInstanceType", chrGetInstanceType, METH_VARARGS }, + + { "GetBoundBoxOnlyXY", chrGetBoundBoxOnlyXY, METH_VARARGS }, + + { "RaceToJob", chrRaceToJob, METH_VARARGS }, + { "RaceToSex", chrRaceToSex, METH_VARARGS }, + + // For Test + { "testGetPKData", chrtestGetPKData, METH_VARARGS }, + { "FaintTest", chrFaintTest, METH_VARARGS }, + { "SetMoveSpeed", chrSetMoveSpeed, METH_VARARGS }, + { "SetAttackSpeed", chrSetAttackSpeed, METH_VARARGS }, + { "WeaponTraceSetTexture", chrWeaponTraceSetTexture, METH_VARARGS }, + { "WeaponTraceUseAlpha", chrWeaponTraceUseAlpha, METH_VARARGS }, + { "WeaponTraceUseTexture", chrWeaponTraceUseTexture, METH_VARARGS }, + { "MoveToDestPosition", chrMoveToDestPosition, METH_VARARGS }, + { "testSetComboType", chrtestSetComboType, METH_VARARGS }, + { "testSetAddRenderMode", chrtestSetAddRenderMode, METH_VARARGS }, + { "testSetModulateRenderMode", chrtestSetModulateRenderMode, METH_VARARGS }, + { "testSetAddRenderModeRGB", chrtestSetAddRenderModeRGB, METH_VARARGS }, + { "testSetModulateRenderModeRGB", chrtestSetModulateRenderModeRGB, METH_VARARGS }, + { "testSetSpecularRenderMode", chrtestSetSpecularRenderMode, METH_VARARGS }, + { "testSetSpecularRenderMode2", chrtestSetSpecularRenderMode2, METH_VARARGS }, + { "testRestoreRenderMode", chrtestRestoreRenderMode, METH_VARARGS }, + { "testSetRideMan", chrtestSetRideMan, METH_VARARGS }, + + { NULL, NULL, NULL }, + }; + + PyObject * poModule = Py_InitModule("chr", s_methods); + + // Length + PyModule_AddIntConstant(poModule, "PLAYER_NAME_MAX_LEN", PLAYER_NAME_MAX_LEN); + + // General + PyModule_AddIntConstant(poModule, "MOTION_NONE", CRaceMotionData::NAME_NONE); + + PyModule_AddIntConstant(poModule, "MOTION_SPAWN", CRaceMotionData::NAME_SPAWN); + PyModule_AddIntConstant(poModule, "MOTION_WAIT", CRaceMotionData::NAME_WAIT); + PyModule_AddIntConstant(poModule, "MOTION_WALK", CRaceMotionData::NAME_WALK); + PyModule_AddIntConstant(poModule, "MOTION_RUN", CRaceMotionData::NAME_RUN); + PyModule_AddIntConstant(poModule, "MOTION_CHANGE_WEAPON", CRaceMotionData::NAME_CHANGE_WEAPON); + PyModule_AddIntConstant(poModule, "MOTION_DAMAGE", CRaceMotionData::NAME_DAMAGE); + PyModule_AddIntConstant(poModule, "MOTION_DAMAGE_FLYING", CRaceMotionData::NAME_DAMAGE_FLYING); + PyModule_AddIntConstant(poModule, "MOTION_STAND_UP", CRaceMotionData::NAME_STAND_UP); + PyModule_AddIntConstant(poModule, "MOTION_DAMAGE_BACK", CRaceMotionData::NAME_DAMAGE_BACK); + PyModule_AddIntConstant(poModule, "MOTION_DAMAGE_FLYING_BACK", CRaceMotionData::NAME_DAMAGE_FLYING_BACK); + PyModule_AddIntConstant(poModule, "MOTION_STAND_UP_BACK", CRaceMotionData::NAME_STAND_UP_BACK); + PyModule_AddIntConstant(poModule, "MOTION_DEAD", CRaceMotionData::NAME_DEAD); + PyModule_AddIntConstant(poModule, "MOTION_DEAD_BACK", CRaceMotionData::NAME_DEAD_BACK); + PyModule_AddIntConstant(poModule, "MOTION_NORMAL_ATTACK", CRaceMotionData::NAME_NORMAL_ATTACK); + PyModule_AddIntConstant(poModule, "MOTION_COMBO_ATTACK_1", CRaceMotionData::NAME_COMBO_ATTACK_1); + PyModule_AddIntConstant(poModule, "MOTION_COMBO_ATTACK_2", CRaceMotionData::NAME_COMBO_ATTACK_2); + PyModule_AddIntConstant(poModule, "MOTION_COMBO_ATTACK_3", CRaceMotionData::NAME_COMBO_ATTACK_3); + PyModule_AddIntConstant(poModule, "MOTION_COMBO_ATTACK_4", CRaceMotionData::NAME_COMBO_ATTACK_4); + PyModule_AddIntConstant(poModule, "MOTION_COMBO_ATTACK_5", CRaceMotionData::NAME_COMBO_ATTACK_5); + PyModule_AddIntConstant(poModule, "MOTION_COMBO_ATTACK_6", CRaceMotionData::NAME_COMBO_ATTACK_6); + PyModule_AddIntConstant(poModule, "MOTION_COMBO_ATTACK_7", CRaceMotionData::NAME_COMBO_ATTACK_7); + PyModule_AddIntConstant(poModule, "MOTION_COMBO_ATTACK_8", CRaceMotionData::NAME_COMBO_ATTACK_8); + PyModule_AddIntConstant(poModule, "MOTION_INTRO_WAIT", CRaceMotionData::NAME_INTRO_WAIT); + PyModule_AddIntConstant(poModule, "MOTION_INTRO_SELECTED", CRaceMotionData::NAME_INTRO_SELECTED); + PyModule_AddIntConstant(poModule, "MOTION_INTRO_NOT_SELECTED", CRaceMotionData::NAME_INTRO_NOT_SELECTED); + PyModule_AddIntConstant(poModule, "MOTION_FISHING_THROW", CRaceMotionData::NAME_FISHING_THROW); + PyModule_AddIntConstant(poModule, "MOTION_FISHING_WAIT", CRaceMotionData::NAME_FISHING_WAIT); + PyModule_AddIntConstant(poModule, "MOTION_FISHING_STOP", CRaceMotionData::NAME_FISHING_STOP); + PyModule_AddIntConstant(poModule, "MOTION_FISHING_REACT", CRaceMotionData::NAME_FISHING_REACT); + PyModule_AddIntConstant(poModule, "MOTION_FISHING_CATCH", CRaceMotionData::NAME_FISHING_CATCH); + PyModule_AddIntConstant(poModule, "MOTION_FISHING_FAIL", CRaceMotionData::NAME_FISHING_FAIL); + PyModule_AddIntConstant(poModule, "MOTION_STOP", CRaceMotionData::NAME_STOP); + PyModule_AddIntConstant(poModule, "MOTION_SKILL", CRaceMotionData::NAME_SKILL); + PyModule_AddIntConstant(poModule, "MOTION_CLAP", CRaceMotionData::NAME_CLAP); + PyModule_AddIntConstant(poModule, "MOTION_DANCE_1", CRaceMotionData::NAME_DANCE_1); + PyModule_AddIntConstant(poModule, "MOTION_DANCE_2", CRaceMotionData::NAME_DANCE_2); + + PyModule_AddIntConstant(poModule, "MOTION_DANCE_3", CRaceMotionData::NAME_DANCE_3); + PyModule_AddIntConstant(poModule, "MOTION_DANCE_4", CRaceMotionData::NAME_DANCE_4); + PyModule_AddIntConstant(poModule, "MOTION_DANCE_5", CRaceMotionData::NAME_DANCE_5); + PyModule_AddIntConstant(poModule, "MOTION_DANCE_6", CRaceMotionData::NAME_DANCE_6); + PyModule_AddIntConstant(poModule, "MOTION_CONGRATULATION", CRaceMotionData::NAME_CONGRATULATION); + PyModule_AddIntConstant(poModule, "MOTION_FORGIVE", CRaceMotionData::NAME_FORGIVE); + PyModule_AddIntConstant(poModule, "MOTION_ANGRY", CRaceMotionData::NAME_ANGRY); + PyModule_AddIntConstant(poModule, "MOTION_ATTRACTIVE", CRaceMotionData::NAME_ATTRACTIVE); + PyModule_AddIntConstant(poModule, "MOTION_SAD", CRaceMotionData::NAME_SAD); + PyModule_AddIntConstant(poModule, "MOTION_SHY", CRaceMotionData::NAME_SHY); + PyModule_AddIntConstant(poModule, "MOTION_CHEERUP", CRaceMotionData::NAME_CHEERUP); + PyModule_AddIntConstant(poModule, "MOTION_BANTER", CRaceMotionData::NAME_BANTER); + PyModule_AddIntConstant(poModule, "MOTION_JOY", CRaceMotionData::NAME_JOY); + + + PyModule_AddIntConstant(poModule, "MOTION_CHEERS_1", CRaceMotionData::NAME_CHEERS_1); + PyModule_AddIntConstant(poModule, "MOTION_CHEERS_2", CRaceMotionData::NAME_CHEERS_2); + PyModule_AddIntConstant(poModule, "MOTION_KISS_WITH_WARRIOR", CRaceMotionData::NAME_KISS_WITH_WARRIOR); + PyModule_AddIntConstant(poModule, "MOTION_KISS_WITH_ASSASSIN", CRaceMotionData::NAME_KISS_WITH_ASSASSIN); + PyModule_AddIntConstant(poModule, "MOTION_KISS_WITH_SURA", CRaceMotionData::NAME_KISS_WITH_SURA); + PyModule_AddIntConstant(poModule, "MOTION_KISS_WITH_SHAMAN", CRaceMotionData::NAME_KISS_WITH_SHAMAN); + PyModule_AddIntConstant(poModule, "MOTION_FRENCH_KISS_WITH_WARRIOR", CRaceMotionData::NAME_FRENCH_KISS_WITH_WARRIOR); + PyModule_AddIntConstant(poModule, "MOTION_FRENCH_KISS_WITH_ASSASSIN", CRaceMotionData::NAME_FRENCH_KISS_WITH_ASSASSIN); + PyModule_AddIntConstant(poModule, "MOTION_FRENCH_KISS_WITH_SURA", CRaceMotionData::NAME_FRENCH_KISS_WITH_SURA); + PyModule_AddIntConstant(poModule, "MOTION_FRENCH_KISS_WITH_SHAMAN", CRaceMotionData::NAME_FRENCH_KISS_WITH_SHAMAN); + PyModule_AddIntConstant(poModule, "MOTION_SLAP_HIT_WITH_WARRIOR", CRaceMotionData::NAME_SLAP_HIT_WITH_WARRIOR); + PyModule_AddIntConstant(poModule, "MOTION_SLAP_HIT_WITH_ASSASSIN", CRaceMotionData::NAME_SLAP_HIT_WITH_ASSASSIN); + PyModule_AddIntConstant(poModule, "MOTION_SLAP_HIT_WITH_SURA", CRaceMotionData::NAME_SLAP_HIT_WITH_SURA); + PyModule_AddIntConstant(poModule, "MOTION_SLAP_HIT_WITH_SHAMAN", CRaceMotionData::NAME_SLAP_HIT_WITH_SHAMAN); + PyModule_AddIntConstant(poModule, "MOTION_SLAP_HURT_WITH_WARRIOR", CRaceMotionData::NAME_SLAP_HURT_WITH_WARRIOR); + PyModule_AddIntConstant(poModule, "MOTION_SLAP_HURT_WITH_ASSASSIN", CRaceMotionData::NAME_SLAP_HURT_WITH_ASSASSIN); + PyModule_AddIntConstant(poModule, "MOTION_SLAP_HURT_WITH_SURA", CRaceMotionData::NAME_SLAP_HURT_WITH_SURA); + PyModule_AddIntConstant(poModule, "MOTION_SLAP_HURT_WITH_SHAMAN", CRaceMotionData::NAME_SLAP_HURT_WITH_SHAMAN); + PyModule_AddIntConstant(poModule, "MOTION_DIG", CRaceMotionData::NAME_DIG); + + PyModule_AddIntConstant(poModule, "MOTION_MODE_RESERVED", CRaceMotionData::MODE_RESERVED); + PyModule_AddIntConstant(poModule, "MOTION_MODE_GENERAL", CRaceMotionData::MODE_GENERAL); + PyModule_AddIntConstant(poModule, "MOTION_MODE_ONEHAND_SWORD", CRaceMotionData::MODE_ONEHAND_SWORD); + PyModule_AddIntConstant(poModule, "MOTION_MODE_TWOHAND_SWORD", CRaceMotionData::MODE_TWOHAND_SWORD); + PyModule_AddIntConstant(poModule, "MOTION_MODE_DUALHAND_SWORD", CRaceMotionData::MODE_DUALHAND_SWORD); + PyModule_AddIntConstant(poModule, "MOTION_MODE_BOW", CRaceMotionData::MODE_BOW); + PyModule_AddIntConstant(poModule, "MOTION_MODE_FAN", CRaceMotionData::MODE_FAN); + PyModule_AddIntConstant(poModule, "MOTION_MODE_BELL", CRaceMotionData::MODE_BELL); + PyModule_AddIntConstant(poModule, "MOTION_MODE_FISHING", CRaceMotionData::MODE_FISHING); + PyModule_AddIntConstant(poModule, "MOTION_MODE_HORSE", CRaceMotionData::MODE_HORSE); + PyModule_AddIntConstant(poModule, "MOTION_MODE_HORSE_ONEHAND_SWORD", CRaceMotionData::MODE_HORSE_ONEHAND_SWORD); + PyModule_AddIntConstant(poModule, "MOTION_MODE_HORSE_TWOHAND_SWORD", CRaceMotionData::MODE_HORSE_TWOHAND_SWORD); + PyModule_AddIntConstant(poModule, "MOTION_MODE_HORSE_DUALHAND_SWORD", CRaceMotionData::MODE_HORSE_DUALHAND_SWORD); + PyModule_AddIntConstant(poModule, "MOTION_MODE_HORSE_BOW", CRaceMotionData::MODE_HORSE_BOW); + PyModule_AddIntConstant(poModule, "MOTION_MODE_HORSE_FAN", CRaceMotionData::MODE_HORSE_FAN); + PyModule_AddIntConstant(poModule, "MOTION_MODE_HORSE_BELL", CRaceMotionData::MODE_HORSE_BELL); + PyModule_AddIntConstant(poModule, "MOTION_MODE_WEDDING_DRESS", CRaceMotionData::MODE_WEDDING_DRESS); + + PyModule_AddIntConstant(poModule, "DIR_NORTH", CInstanceBase::DIR_NORTH); + PyModule_AddIntConstant(poModule, "DIR_NORTHEAST", CInstanceBase::DIR_NORTHEAST); + PyModule_AddIntConstant(poModule, "DIR_EAST", CInstanceBase::DIR_EAST); + PyModule_AddIntConstant(poModule, "DIR_SOUTHEAST", CInstanceBase::DIR_SOUTHEAST); + PyModule_AddIntConstant(poModule, "DIR_SOUTH", CInstanceBase::DIR_SOUTH); + PyModule_AddIntConstant(poModule, "DIR_SOUTHWEST", CInstanceBase::DIR_SOUTHWEST); + PyModule_AddIntConstant(poModule, "DIR_WEST", CInstanceBase::DIR_WEST); + PyModule_AddIntConstant(poModule, "DIR_NORTHWEST", CInstanceBase::DIR_NORTHWEST); + + PyModule_AddIntConstant(poModule, "INSTANCE_TYPE_PLAYER", CActorInstance::TYPE_PC); + PyModule_AddIntConstant(poModule, "INSTANCE_TYPE_NPC", CActorInstance::TYPE_NPC); + PyModule_AddIntConstant(poModule, "INSTANCE_TYPE_ENEMY", CActorInstance::TYPE_ENEMY); + PyModule_AddIntConstant(poModule, "INSTANCE_TYPE_BUILDING", CActorInstance::TYPE_BUILDING); + PyModule_AddIntConstant(poModule, "INSTANCE_TYPE_OBJECT", CActorInstance::TYPE_OBJECT); + + PyModule_AddIntConstant(poModule, "PART_WEAPON", CRaceData::PART_WEAPON); + PyModule_AddIntConstant(poModule, "PART_HEAD", CRaceData::PART_HEAD); + PyModule_AddIntConstant(poModule, "PART_WEAPON_LEFT", CRaceData::PART_WEAPON_LEFT); + + ///// + + PyModule_AddIntConstant(poModule, "AFFECT_POISON", CInstanceBase::AFFECT_POISON); + PyModule_AddIntConstant(poModule, "AFFECT_SLOW", CInstanceBase::AFFECT_SLOW); + PyModule_AddIntConstant(poModule, "AFFECT_STUN", CInstanceBase::AFFECT_STUN); + PyModule_AddIntConstant(poModule, "AFFECT_MOV_SPEED_POTION", CInstanceBase::AFFECT_MOV_SPEED_POTION); + PyModule_AddIntConstant(poModule, "AFFECT_ATT_SPEED_POTION", CInstanceBase::AFFECT_ATT_SPEED_POTION); + PyModule_AddIntConstant(poModule, "AFFECT_FISH_MIND", CInstanceBase::AFFECT_FISH_MIND); + + PyModule_AddIntConstant(poModule, "AFFECT_JEONGWI", CInstanceBase::AFFECT_JEONGWI); + PyModule_AddIntConstant(poModule, "AFFECT_GEOMGYEONG", CInstanceBase::AFFECT_GEOMGYEONG); + PyModule_AddIntConstant(poModule, "AFFECT_CHEONGEUN", CInstanceBase::AFFECT_CHEONGEUN); + PyModule_AddIntConstant(poModule, "AFFECT_GYEONGGONG", CInstanceBase::AFFECT_GYEONGGONG); + PyModule_AddIntConstant(poModule, "AFFECT_EUNHYEONG", CInstanceBase::AFFECT_EUNHYEONG); + PyModule_AddIntConstant(poModule, "AFFECT_GWIGEOM", CInstanceBase::AFFECT_GWIGEOM); + PyModule_AddIntConstant(poModule, "AFFECT_GONGPO", CInstanceBase::AFFECT_GONGPO); + PyModule_AddIntConstant(poModule, "AFFECT_JUMAGAP", CInstanceBase::AFFECT_JUMAGAP); + PyModule_AddIntConstant(poModule, "AFFECT_HOSIN", CInstanceBase::AFFECT_HOSIN); + PyModule_AddIntConstant(poModule, "AFFECT_BOHO", CInstanceBase::AFFECT_BOHO); + PyModule_AddIntConstant(poModule, "AFFECT_KWAESOK", CInstanceBase::AFFECT_KWAESOK); + PyModule_AddIntConstant(poModule, "AFFECT_HEUKSIN", CInstanceBase::AFFECT_HEUKSIN); + PyModule_AddIntConstant(poModule, "AFFECT_MUYEONG", CInstanceBase::AFFECT_MUYEONG); + PyModule_AddIntConstant(poModule, "AFFECT_GICHEON", CInstanceBase::AFFECT_GICHEON); + PyModule_AddIntConstant(poModule, "AFFECT_JEUNGRYEOK", CInstanceBase::AFFECT_JEUNGRYEOK); + PyModule_AddIntConstant(poModule, "AFFECT_PABEOP", CInstanceBase::AFFECT_PABEOP); + PyModule_AddIntConstant(poModule, "AFFECT_FALLEN_CHEONGEUN", CInstanceBase::AFFECT_FALLEN_CHEONGEUN); + PyModule_AddIntConstant(poModule, "AFFECT_CHINA_FIREWORK", CInstanceBase::AFFECT_CHINA_FIREWORK); + PyModule_AddIntConstant(poModule, "NEW_AFFECT_MALL", CInstanceBase::NEW_AFFECT_MALL); + PyModule_AddIntConstant(poModule, "NEW_AFFECT_NO_DEATH_PENALTY", CInstanceBase::NEW_AFFECT_NO_DEATH_PENALTY); + PyModule_AddIntConstant(poModule, "NEW_AFFECT_SKILL_BOOK_BONUS", CInstanceBase::NEW_AFFECT_SKILL_BOOK_BONUS); + PyModule_AddIntConstant(poModule, "NEW_AFFECT_SKILL_BOOK_NO_DELAY", CInstanceBase::NEW_AFFECT_SKILL_BOOK_NO_DELAY); + PyModule_AddIntConstant(poModule, "NEW_AFFECT_EXP_BONUS", CInstanceBase::NEW_AFFECT_EXP_BONUS); + PyModule_AddIntConstant(poModule, "NEW_AFFECT_EXP_BONUS_EURO_FREE", CInstanceBase::NEW_AFFECT_EXP_BONUS_EURO_FREE); + PyModule_AddIntConstant(poModule, "NEW_AFFECT_EXP_BONUS_EURO_FREE_UNDER_15",CInstanceBase::NEW_AFFECT_EXP_BONUS_EURO_FREE_UNDER_15); + + PyModule_AddIntConstant(poModule, "NEW_AFFECT_ITEM_BONUS", CInstanceBase::NEW_AFFECT_ITEM_BONUS); + PyModule_AddIntConstant(poModule, "NEW_AFFECT_SAFEBOX", CInstanceBase::NEW_AFFECT_SAFEBOX); + PyModule_AddIntConstant(poModule, "NEW_AFFECT_AUTOLOOT", CInstanceBase::NEW_AFFECT_AUTOLOOT); + PyModule_AddIntConstant(poModule, "NEW_AFFECT_FISH_MIND", CInstanceBase::NEW_AFFECT_FISH_MIND); + PyModule_AddIntConstant(poModule, "NEW_AFFECT_MARRIAGE_FAST", CInstanceBase::NEW_AFFECT_MARRIAGE_FAST); + PyModule_AddIntConstant(poModule, "NEW_AFFECT_GOLD_BONUS", CInstanceBase::NEW_AFFECT_GOLD_BONUS); + PyModule_AddIntConstant(poModule, "NEW_AFFECT_AUTO_HP_RECOVERY", CInstanceBase::NEW_AFFECT_AUTO_HP_RECOVERY); + PyModule_AddIntConstant(poModule, "NEW_AFFECT_AUTO_SP_RECOVERY", CInstanceBase::NEW_AFFECT_AUTO_SP_RECOVERY); + + PyModule_AddIntConstant(poModule, "NEW_AFFECT_DRAGON_SOUL_QUALIFIED", CInstanceBase::NEW_AFFECT_DRAGON_SOUL_QUALIFIED); + + PyModule_AddIntConstant(poModule, "NEW_AFFECT_DRAGON_SOUL_DECK1", CInstanceBase::NEW_AFFECT_DRAGON_SOUL_DECK1); + PyModule_AddIntConstant(poModule, "NEW_AFFECT_DRAGON_SOUL_DECK2", CInstanceBase::NEW_AFFECT_DRAGON_SOUL_DECK2); + +} diff --git a/source/UserInterface/PythonChat.cpp b/source/UserInterface/PythonChat.cpp new file mode 100644 index 0000000..64fea8f --- /dev/null +++ b/source/UserInterface/PythonChat.cpp @@ -0,0 +1,833 @@ +#include "StdAfx.h" +#include "PythonChat.h" + +#include "AbstractApplication.h" +#include "PythonCharacterManager.h" +#include "../eterbase/Timer.h" + +int CPythonChat::TChatSet::ms_iChatModeSize = CHAT_TYPE_MAX_NUM; + +const float c_fStartDisappearingTime = 5.0f; +const int c_iMaxLineCount = 5; + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +CDynamicPool CPythonChat::SChatLine::ms_kPool; + +void CPythonChat::SetChatColor(UINT eType, UINT r, UINT g, UINT b) +{ + if (eType>=CHAT_TYPE_MAX_NUM) + return; + + DWORD dwColor=(0xff000000)|(r<<16)|(g<<8)|(b); + m_akD3DXClrChat[eType]=D3DXCOLOR(dwColor); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +CPythonChat::SChatLine* CPythonChat::SChatLine::New() +{ + return ms_kPool.Alloc(); +} + +void CPythonChat::SChatLine::Delete(CPythonChat::SChatLine* pkChatLine) +{ + pkChatLine->Instance.Destroy(); + ms_kPool.Free(pkChatLine); +} + +void CPythonChat::SChatLine::DestroySystem() +{ + ms_kPool.Destroy(); +} + +void CPythonChat::SChatLine::SetColor(DWORD dwID, DWORD dwColor) +{ + assert(dwID < CHAT_LINE_COLOR_ARRAY_MAX_NUM); + + if (dwID >= CHAT_LINE_COLOR_ARRAY_MAX_NUM) + return; + + aColor[dwID] = dwColor; +} + +void CPythonChat::SChatLine::SetColorAll(DWORD dwColor) +{ + for (int i = 0; i < CHAT_LINE_COLOR_ARRAY_MAX_NUM; ++i) + aColor[i] = dwColor; +} + +D3DXCOLOR & CPythonChat::SChatLine::GetColorRef(DWORD dwID) +{ + assert(dwID < CHAT_LINE_COLOR_ARRAY_MAX_NUM); + + if (dwID >= CHAT_LINE_COLOR_ARRAY_MAX_NUM) + { + static D3DXCOLOR color(1.0f, 0.0f, 0.0f, 1.0f); + return color; + } + + return aColor[dwID]; +} + +CPythonChat::SChatLine::SChatLine() +{ + for (int i = 0; i < CHAT_LINE_COLOR_ARRAY_MAX_NUM; ++i) + aColor[i] = 0xff0000ff; +} +CPythonChat::SChatLine::~SChatLine() +{ + Instance.Destroy(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +int CPythonChat::CreateChatSet(DWORD dwID) +{ + m_ChatSetMap.insert(std::make_pair(dwID, TChatSet())); + return dwID; +} + +void CPythonChat::UpdateViewMode(DWORD dwID) +{ + IAbstractApplication& rApp=IAbstractApplication::GetSingleton(); + + float fcurTime = rApp.GetGlobalTime(); + //float felapsedTime = rApp.GetGlobalElapsedTime(); + + TChatSet * pChatSet = GetChatSetPtr(dwID); + if (!pChatSet) + return; + + TChatLineList * pLineList = &(pChatSet->m_ShowingChatLineList); + int iLineIndex = pLineList->size(); + int iHeight = -(int(pLineList->size()+1) * pChatSet->m_iStep); + + TChatLineList::iterator itor; + for (itor = pLineList->begin(); itor != pLineList->end();) + { + TChatLine * pChatLine = (*itor); + + D3DXCOLOR & rColor = pChatLine->GetColorRef(dwID); + + float fElapsedTime = (fcurTime - pChatLine->fAppendedTime); + if (fElapsedTime >= c_fStartDisappearingTime || iLineIndex >= c_iMaxLineCount) + { + rColor.a -= rColor.a / 10.0f; + + if (rColor.a <= 0.1f) + { + itor = pLineList->erase(itor); + } + else + { + ++itor; + } + } + else + { + ++itor; + } + + ///// + + iHeight += pChatSet->m_iStep; + --iLineIndex; + + pChatLine->Instance.SetPosition(pChatSet->m_ix, pChatSet->m_iy + iHeight); + pChatLine->Instance.SetColor(rColor); + pChatLine->Instance.Update(); + } +} + +void CPythonChat::UpdateEditMode(DWORD dwID) +{ + TChatSet * pChatSet = GetChatSetPtr(dwID); + if (!pChatSet) + return; + + const int c_iAlphaLine = max(0, GetVisibleLineCount(dwID) - GetEditableLineCount(dwID) + 2); + + int iLineIndex = 0; + float fAlpha = 0.0f; + float fAlphaStep = 0.0f; + + if (c_iAlphaLine > 0) + fAlphaStep = 1.0f / float(c_iAlphaLine); + + TChatLineList * pLineList = &(pChatSet->m_ShowingChatLineList); + int iHeight = -(int(pLineList->size()+1) * pChatSet->m_iStep); + + for (TChatLineList::iterator itor = pLineList->begin(); itor != pLineList->end(); ++itor) + { + TChatLine * pChatLine = (*itor); + + D3DXCOLOR & rColor = pChatLine->GetColorRef(dwID); + + if (iLineIndex < c_iAlphaLine) + { + rColor.a += (fAlpha - rColor.a) / 10.0f; + fAlpha = fMIN(fAlpha+fAlphaStep, 1.0f); + } + else + { + rColor.a = fMIN(rColor.a+0.05f, 1.0f); + } + + iHeight += pChatSet->m_iStep; + pChatLine->Instance.SetPosition(pChatSet->m_ix, pChatSet->m_iy + iHeight); + pChatLine->Instance.SetColor(rColor); + pChatLine->Instance.Update(); + } +} + +void CPythonChat::UpdateLogMode(DWORD dwID) +{ + TChatSet * pChatSet = GetChatSetPtr(dwID); + if (!pChatSet) + return; + + TChatLineList * pLineList = &(pChatSet->m_ShowingChatLineList); + int iHeight = 0; + + for (TChatLineList::reverse_iterator itor = pLineList->rbegin(); itor != pLineList->rend(); ++itor) + { + TChatLine * pChatLine = (*itor); + + iHeight -= pChatSet->m_iStep; + pChatLine->Instance.SetPosition(pChatSet->m_ix, pChatSet->m_iy + iHeight); + pChatLine->Instance.SetColor(pChatLine->GetColorRef(dwID)); + pChatLine->Instance.Update(); + } +} + +void CPythonChat::Update(DWORD dwID) +{ + TChatSet * pChatSet = GetChatSetPtr(dwID); + if (!pChatSet) + return; + + switch (pChatSet->m_iBoardState) + { + case BOARD_STATE_VIEW: + UpdateViewMode(dwID); + break; + case BOARD_STATE_EDIT: + UpdateEditMode(dwID); + break; + case BOARD_STATE_LOG: + UpdateLogMode(dwID); + break; + } + + DWORD dwcurTime = CTimer::Instance().GetCurrentMillisecond(); + for (TWaitChatList::iterator itor = m_WaitChatList.begin(); itor != m_WaitChatList.end();) + { + TWaitChat & rWaitChat = *itor; + + if (rWaitChat.dwAppendingTime < dwcurTime) + { + AppendChat(rWaitChat.iType, rWaitChat.strChat.c_str()); + + itor = m_WaitChatList.erase(itor); + } + else + { + ++itor; + } + } +} + +void CPythonChat::Render(DWORD dwID) +{ + TChatLineList * pLineList = GetChatLineListPtr(dwID); + if (!pLineList) + return; + + for (TChatLineList::iterator itor = pLineList->begin(); itor != pLineList->end(); ++itor) + { + CGraphicTextInstance & rInstance = (*itor)->Instance; + rInstance.Render(); + } +} + + +void CPythonChat::SetBoardState(DWORD dwID, int iState) +{ + TChatSet * pChatSet = GetChatSetPtr(dwID); + if (!pChatSet) + return; + + pChatSet->m_iBoardState = iState; + ArrangeShowingChat(dwID); +} +void CPythonChat::SetPosition(DWORD dwID, int ix, int iy) +{ + TChatSet * pChatSet = GetChatSetPtr(dwID); + if (!pChatSet) + return; + + pChatSet->m_ix = ix; + pChatSet->m_iy = iy; +} +void CPythonChat::SetHeight(DWORD dwID, int iHeight) +{ + TChatSet * pChatSet = GetChatSetPtr(dwID); + if (!pChatSet) + return; + + pChatSet->m_iHeight = iHeight; +} +void CPythonChat::SetStep(DWORD dwID, int iStep) +{ + TChatSet * pChatSet = GetChatSetPtr(dwID); + if (!pChatSet) + return; + + pChatSet->m_iStep = iStep; +} +void CPythonChat::ToggleChatMode(DWORD dwID, int iMode) +{ + TChatSet * pChatSet = GetChatSetPtr(dwID); + if (!pChatSet) + return; + + pChatSet->m_iMode[iMode] = 1 - pChatSet->m_iMode[iMode]; +// Tracef("ToggleChatMode : %d\n", iMode); + ArrangeShowingChat(dwID); +} +void CPythonChat::EnableChatMode(DWORD dwID, int iMode) +{ + TChatSet * pChatSet = GetChatSetPtr(dwID); + if (!pChatSet) + return; + + pChatSet->m_iMode[iMode] = TRUE; +// Tracef("EnableChatMode : %d\n", iMode); + ArrangeShowingChat(dwID); +} +void CPythonChat::DisableChatMode(DWORD dwID, int iMode) +{ + TChatSet * pChatSet = GetChatSetPtr(dwID); + if (!pChatSet) + return; + + pChatSet->m_iMode[iMode] = FALSE; +// Tracef("DisableChatMode : %d\n", iMode); + ArrangeShowingChat(dwID); +} +void CPythonChat::SetEndPos(DWORD dwID, float fPos) +{ + TChatSet * pChatSet = GetChatSetPtr(dwID); + if (!pChatSet) + return; + + fPos = max(0.0f, fPos); + fPos = min(1.0f, fPos); + if (pChatSet->m_fEndPos != fPos) + { + pChatSet->m_fEndPos = fPos; + ArrangeShowingChat(dwID); + } +} + + +int CPythonChat::GetVisibleLineCount(DWORD dwID) +{ + TChatLineList * pLineList = GetChatLineListPtr(dwID); + if (!pLineList) + return 0; + + return pLineList->size(); +} + +int CPythonChat::GetEditableLineCount(DWORD dwID) +{ + TChatSet * pChatSet = GetChatSetPtr(dwID); + if (!pChatSet) + return 0; + + return pChatSet->m_iHeight / pChatSet->m_iStep + 1; +} + +int CPythonChat::GetLineCount(DWORD dwID) +{ + TChatSet * pChatSet = GetChatSetPtr(dwID); + if (!pChatSet) + return 0; + + int iCount = 0; + for (DWORD i = 0; i < m_ChatLineDeque.size(); ++i) + { + if (!pChatSet->CheckMode(m_ChatLineDeque[i]->iType)) + continue; + + ++iCount; + } + + return iCount; +} + +int CPythonChat::GetLineStep(DWORD dwID) +{ + TChatSet * pChatSet = GetChatSetPtr(dwID); + if (!pChatSet) + return 0; + + return pChatSet->m_iStep; +} + +CPythonChat::TChatLineList * CPythonChat::GetChatLineListPtr(DWORD dwID) +{ + TChatSetMap::iterator itor = m_ChatSetMap.find(dwID); + if (m_ChatSetMap.end() == itor) + return NULL; + + TChatSet & rChatSet = itor->second; + return &(rChatSet.m_ShowingChatLineList); +} + +CPythonChat::TChatSet * CPythonChat::GetChatSetPtr(DWORD dwID) +{ + TChatSetMap::iterator itor = m_ChatSetMap.find(dwID); + if (m_ChatSetMap.end() == itor) + return NULL; + + TChatSet & rChatSet = itor->second; + return &rChatSet; +} + +void CPythonChat::ArrangeShowingChat(DWORD dwID) +{ + TChatSet * pChatSet = GetChatSetPtr(dwID); + if (!pChatSet) + return; + + pChatSet->m_ShowingChatLineList.clear(); + + TChatLineDeque TempChatLineDeque; + for (TChatLineDeque::iterator itor = m_ChatLineDeque.begin(); itor != m_ChatLineDeque.end(); ++itor) + { + TChatLine * pChatLine = *itor; + if (pChatSet->CheckMode(pChatLine->iType)) + TempChatLineDeque.push_back(pChatLine); + } + + int icurLineCount = TempChatLineDeque.size(); + int iVisibleLineCount = min(icurLineCount, (pChatSet->m_iHeight + pChatSet->m_iStep) / pChatSet->m_iStep); + int iEndLine = iVisibleLineCount + int(float(icurLineCount - iVisibleLineCount - 1) * pChatSet->m_fEndPos); + + ///// + + int iHeight = 12; + for (int i = min(icurLineCount-1, iEndLine); i >= 0; --i) + { + if (!pChatSet->CheckMode(TempChatLineDeque[i]->iType)) + continue; + + if (pChatSet->m_iHeight + pChatSet->m_iStep <= iHeight) + { + break; + } + + pChatSet->m_ShowingChatLineList.push_front(TempChatLineDeque[i]); + + iHeight += pChatSet->m_iStep; + } +} + +void CPythonChat::AppendChat(int iType, const char * c_szChat) +{ + // DEFAULT_FONT + //static CResource * s_pResource = CResourceManager::Instance().GetResourcePointer(g_strDefaultFontName.c_str()); + + CGraphicText* pkDefaultFont = static_cast(DefaultFont_GetResource()); + if (!pkDefaultFont) + { + TraceError("CPythonChat::AppendChat - CANNOT_FIND_DEFAULT_FONT"); + return; + } + // END_OF_DEFAULT_FONT + + IAbstractApplication& rApp=IAbstractApplication::GetSingleton(); + SChatLine * pChatLine = SChatLine::New(); + pChatLine->iType = iType; + pChatLine->Instance.SetValue(c_szChat); + + // DEFAULT_FONT + pChatLine->Instance.SetTextPointer(pkDefaultFont); + // END_OF_DEFAULT_FONT + + pChatLine->fAppendedTime = rApp.GetGlobalTime(); + pChatLine->SetColorAll(GetChatColor(iType)); + + m_ChatLineDeque.push_back(pChatLine); + if (m_ChatLineDeque.size() > CHAT_LINE_MAX_NUM) + { + SChatLine * pChatLine = m_ChatLineDeque.front(); + SChatLine::Delete(pChatLine); + m_ChatLineDeque.pop_front(); + } + + for (TChatSetMap::iterator itor = m_ChatSetMap.begin(); itor != m_ChatSetMap.end(); ++itor) + { + TChatSet * pChatSet = &(itor->second); + //pChatLine->SetColor(itor->first, GetChatColor(iType)); + + // Edit Mode ߱ ߰ + if (BOARD_STATE_EDIT == pChatSet->m_iBoardState) + { + ArrangeShowingChat(itor->first); + } + else// if (BOARD_STATE_VIEW == pChatSet->m_iBoardState) + { + pChatSet->m_ShowingChatLineList.push_back(pChatLine); + if (pChatSet->m_ShowingChatLineList.size() > CHAT_LINE_MAX_NUM) + { + pChatSet->m_ShowingChatLineList.pop_front(); + } + } + } +} + +void CPythonChat::AppendChatWithDelay(int iType, const char * c_szChat, int iDelay) +{ + TWaitChat WaitChat; + WaitChat.iType = iType; + WaitChat.strChat = c_szChat; + WaitChat.dwAppendingTime = CTimer::Instance().GetCurrentMillisecond() + iDelay; + m_WaitChatList.push_back(WaitChat); +} + +DWORD CPythonChat::GetChatColor(int iType) +{ + if (iTypesecond; + } + + pWhisper->AppendChat(iType, c_szChat); +} + +void CPythonChat::ClearWhisper(const char * c_szName) +{ + TWhisperMap::iterator itor = m_WhisperMap.find(c_szName); + + if (itor != m_WhisperMap.end()) + { + CWhisper * pWhisper = itor->second; + CWhisper::Delete(pWhisper); + + m_WhisperMap.erase(itor); + } +} + +BOOL CPythonChat::GetWhisper(const char * c_szName, CWhisper ** ppWhisper) +{ + TWhisperMap::iterator itor = m_WhisperMap.find(c_szName); + + if (itor == m_WhisperMap.end()) + return FALSE; + + *ppWhisper = itor->second; + + return TRUE; +} + +void CPythonChat::InitWhisper(PyObject * ppyObject) +{ + TWhisperMap::iterator itor = m_WhisperMap.begin(); + for (; itor != m_WhisperMap.end(); ++itor) + { + std::string strName = itor->first; + PyCallClassMemberFunc(ppyObject, "MakeWhisperButton", Py_BuildValue("(s)", strName.c_str())); + } +} + +void CPythonChat::__DestroyWhisperMap() +{ + TWhisperMap::iterator itor = m_WhisperMap.begin(); + for (; itor != m_WhisperMap.end(); ++itor) + { + CWhisper::Delete(itor->second); + } + m_WhisperMap.clear(); +} + +void CPythonChat::Close() +{ + TChatSetMap::iterator itor = m_ChatSetMap.begin(); + for (; itor != m_ChatSetMap.end(); ++itor) + { + TChatSet & rChatSet = itor->second; + TChatLineList * pLineList = &(rChatSet.m_ShowingChatLineList); + for (TChatLineList::iterator itor = pLineList->begin(); itor != pLineList->end(); ++itor) + { + TChatLine * pChatLine = (*itor); + pChatLine->fAppendedTime = 0.0f; + } + } +} + +void CPythonChat::Destroy() +{ + __DestroyWhisperMap(); + + m_ShowingChatLineList.clear(); + m_ChatSetMap.clear(); + m_ChatLineDeque.clear(); + + SChatLine::DestroySystem(); + CWhisper::DestroySystem(); + + __Initialize(); +} + +void CPythonChat::__Initialize() +{ + m_akD3DXClrChat[CHAT_TYPE_TALKING] = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); + m_akD3DXClrChat[CHAT_TYPE_INFO] = D3DXCOLOR(1.0f, 0.785f, 0.785f, 1.0f); + m_akD3DXClrChat[CHAT_TYPE_NOTICE] = D3DXCOLOR(1.0f, 0.902f, 0.730f, 1.0f); + m_akD3DXClrChat[CHAT_TYPE_PARTY] = D3DXCOLOR(0.542f, 1.0f, 0.949f, 1.0f); + m_akD3DXClrChat[CHAT_TYPE_GUILD] = D3DXCOLOR(0.906f, 0.847f, 1.0f, 1.0f); + m_akD3DXClrChat[CHAT_TYPE_COMMAND] = D3DXCOLOR(0.658f, 1.0f, 0.835f, 1.0f); + m_akD3DXClrChat[CHAT_TYPE_SHOUT] = D3DXCOLOR(0.658f, 1.0f, 0.835f, 1.0f); + m_akD3DXClrChat[CHAT_TYPE_WHISPER] = D3DXCOLOR(0xff4AE14A); + m_akD3DXClrChat[CHAT_TYPE_BIG_NOTICE] = D3DXCOLOR(1.0f, 0.902f, 0.730f, 1.0f); +} + +CPythonChat::CPythonChat() +{ + __Initialize(); +} + +CPythonChat::~CPythonChat() +{ + assert(m_ChatLineDeque.empty()); + assert(m_ShowingChatLineList.empty()); + assert(m_ChatSetMap.empty()); + assert(m_WhisperMap.empty()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +CDynamicPool CWhisper::ms_kPool; + +CWhisper* CWhisper::New() +{ + return ms_kPool.Alloc(); +} + +void CWhisper::Delete(CWhisper* pkWhisper) +{ + pkWhisper->Destroy(); + ms_kPool.Free(pkWhisper); +} + +void CWhisper::DestroySystem() +{ + ms_kPool.Destroy(); + + SChatLine::DestroySystem(); +} + +void CWhisper::SetPosition(float fPosition) +{ + m_fcurPosition = fPosition; + __ArrangeChat(); +} + +void CWhisper::SetBoxSize(float fWidth, float fHeight) +{ + m_fWidth = fWidth; + m_fHeight = fHeight; + + for (TChatLineDeque::iterator itor = m_ChatLineDeque.begin(); itor != m_ChatLineDeque.end(); ++itor) + { + TChatLine * pChatLine = *itor; + pChatLine->Instance.SetLimitWidth(fWidth); + } +} + +void CWhisper::AppendChat(int iType, const char * c_szChat) +{ + // DEFAULT_FONT + //static CResource * s_pResource = CResourceManager::Instance().GetResourcePointer(g_strDefaultFontName.c_str()); + +#if defined(LOCALE_SERVICE_YMIR) || defined(LOCALE_SERVICE_JAPAN) || defined(LOCALE_SERVICE_HONGKONG) || defined(LOCALE_SERVICE_TAIWAN) || defined(LOCALE_SERVICE_NEWCIBN) + CGraphicText* pkDefaultFont = static_cast(DefaultFont_GetResource()); +#else + CGraphicText* pkDefaultFont = (iType == CPythonChat::WHISPER_TYPE_GM) ? static_cast(DefaultItalicFont_GetResource()) : static_cast(DefaultFont_GetResource()); +#endif + + if (!pkDefaultFont) + { + TraceError("CWhisper::AppendChat - CANNOT_FIND_DEFAULT_FONT"); + return; + } + // END_OF_DEFAULT_FONT + + SChatLine * pChatLine = SChatLine::New(); + pChatLine->Instance.SetValue(c_szChat); + + // DEFAULT_FONT + pChatLine->Instance.SetTextPointer(pkDefaultFont); + // END_OF_DEFAULT_FONT + + pChatLine->Instance.SetLimitWidth(m_fWidth); + pChatLine->Instance.SetMultiLine(TRUE); + + switch(iType) + { + case CPythonChat::WHISPER_TYPE_SYSTEM: + pChatLine->Instance.SetColor(D3DXCOLOR(1.0f, 0.785f, 0.785f, 1.0f)); + break; + case CPythonChat::WHISPER_TYPE_GM: + pChatLine->Instance.SetColor(D3DXCOLOR(1.0f, 0.632f, 0.0f, 1.0f)); + break; + case CPythonChat::WHISPER_TYPE_CHAT: + default: + pChatLine->Instance.SetColor(0xffffffff); + break; + } + + m_ChatLineDeque.push_back(pChatLine); + + __ArrangeChat(); +} + +void CWhisper::__ArrangeChat() +{ + for (TChatLineDeque::iterator itor = m_ChatLineDeque.begin(); itor != m_ChatLineDeque.end(); ++itor) + { + TChatLine * pChatLine = *itor; + pChatLine->Instance.Update(); + } +} + +void CWhisper::Render(float fx, float fy) +{ + float fHeight = fy + m_fHeight; + + int iViewCount = int(m_fHeight / m_fLineStep) - 1; + int iLineCount = int(m_ChatLineDeque.size()); + int iStartLine = -1; + if (iLineCount > iViewCount) + { + iStartLine = int(float(iLineCount-iViewCount) * m_fcurPosition) + iViewCount - 1; + } + else if (!m_ChatLineDeque.empty()) + { + iStartLine = iLineCount - 1; + } + + RECT Rect = { static_cast(fx), static_cast(fy), static_cast(fx+m_fWidth), static_cast(fy+m_fHeight) }; + + for (int i = iStartLine; i >= 0; --i) + { + assert(i >= 0 && i < int(m_ChatLineDeque.size())); + TChatLine * pChatLine = m_ChatLineDeque[i]; + + WORD wLineCount = pChatLine->Instance.GetTextLineCount(); + fHeight -= wLineCount * m_fLineStep; + + pChatLine->Instance.SetPosition(fx, fHeight); + pChatLine->Instance.Render(&Rect); + + if (fHeight < fy) + break; + } +} + +void CWhisper::__Initialize() +{ + m_fLineStep = 15.0f; + m_fWidth = 300.0f; + m_fHeight = 120.0f; + m_fcurPosition = 1.0f; +} + +void CWhisper::Destroy() +{ + std::for_each(m_ChatLineDeque.begin(), m_ChatLineDeque.end(), SChatLine::Delete); + m_ChatLineDeque.clear(); + m_ShowingChatLineList.clear(); +} + +CWhisper::CWhisper() +{ + __Initialize(); +} + +CWhisper::~CWhisper() +{ + Destroy(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +CDynamicPool CWhisper::SChatLine::ms_kPool; + +CWhisper::SChatLine* CWhisper::SChatLine::New() +{ + return ms_kPool.Alloc(); +} + +void CWhisper::SChatLine::Delete(CWhisper::SChatLine* pkChatLine) +{ + pkChatLine->Instance.Destroy(); + ms_kPool.Free(pkChatLine); +} + +void CWhisper::SChatLine::DestroySystem() +{ + ms_kPool.Destroy(); +} diff --git a/source/UserInterface/PythonChat.h b/source/UserInterface/PythonChat.h new file mode 100644 index 0000000..f8f24b2 --- /dev/null +++ b/source/UserInterface/PythonChat.h @@ -0,0 +1,234 @@ +#pragma once + +#include "Packet.h" +#include "AbstractChat.h" + +class CWhisper +{ + public: + typedef struct SChatLine + { + CGraphicTextInstance Instance; + + SChatLine() + { + } + ~SChatLine() + { + Instance.Destroy(); + } + + static void DestroySystem(); + + static SChatLine* New(); + static void Delete(SChatLine* pkChatLine); + + static CDynamicPool ms_kPool; + } TChatLine; + + typedef std::deque TChatLineDeque; + typedef std::list TChatLineList; + + public: + CWhisper(); + ~CWhisper(); + + void Destroy(); + + void SetPosition(float fPosition); + void SetBoxSize(float fWidth, float fHeight); + void AppendChat(int iType, const char* c_szChat); + void Render(float fx, float fy); + + protected: + void __Initialize(); + void __ArrangeChat(); + + protected: + float m_fLineStep; + float m_fWidth; + float m_fHeight; + float m_fcurPosition; + + TChatLineDeque m_ChatLineDeque; + TChatLineList m_ShowingChatLineList; + + public: + static void DestroySystem(); + + static CWhisper* New(); + static void Delete(CWhisper* pkWhisper); + + static CDynamicPool ms_kPool; +}; + +class CPythonChat : public CSingleton, public IAbstractChat +{ + public: + enum EWhisperType + { + WHISPER_TYPE_CHAT = 0, + WHISPER_TYPE_NOT_EXIST = 1, + WHISPER_TYPE_TARGET_BLOCKED = 2, + WHISPER_TYPE_SENDER_BLOCKED = 3, + WHISPER_TYPE_ERROR = 4, + WHISPER_TYPE_GM = 5, + WHISPER_TYPE_SYSTEM = 0xFF + }; + + enum EBoardState + { + BOARD_STATE_VIEW, + BOARD_STATE_EDIT, + BOARD_STATE_LOG, + }; + + enum + { + CHAT_LINE_MAX_NUM = 300, + CHAT_LINE_COLOR_ARRAY_MAX_NUM = 3, + }; + + typedef struct SChatLine + { + int iType; + float fAppendedTime; + D3DXCOLOR aColor[CHAT_LINE_COLOR_ARRAY_MAX_NUM]; + CGraphicTextInstance Instance; + + SChatLine(); + virtual ~SChatLine(); + + void SetColor(DWORD dwID, DWORD dwColor); + void SetColorAll(DWORD dwColor); + D3DXCOLOR & GetColorRef(DWORD dwID); + static void DestroySystem(); + + static SChatLine* New(); + static void Delete(SChatLine* pkChatLine); + + static CDynamicPool ms_kPool; + } TChatLine; + + typedef struct SWaitChat + { + int iType; + std::string strChat; + + DWORD dwAppendingTime; + } TWaitChat; + + typedef std::deque TChatLineDeque; + typedef std::list TChatLineList; + + typedef std::map TWhisperMap; + typedef std::set TIgnoreCharacterSet; + typedef std::list TWaitChatList; + + typedef struct SChatSet + { + int m_ix; + int m_iy; + int m_iHeight; + int m_iStep; + float m_fEndPos; + + int m_iBoardState; + std::vector m_iMode; + + TChatLineList m_ShowingChatLineList; + + bool CheckMode(DWORD dwType) + { + if (dwType >= m_iMode.size()) + return false; + + return m_iMode[dwType] ? true : false; + } + + SChatSet() + { + m_iBoardState = BOARD_STATE_VIEW; + + m_ix = 0; + m_iy = 0; + m_fEndPos = 1.0f; + m_iHeight = 0; + m_iStep = 15; + + m_iMode.clear(); + m_iMode.resize(ms_iChatModeSize, 1); + } + + static int ms_iChatModeSize; + } TChatSet; + + typedef std::map TChatSetMap; + + public: + CPythonChat(); + virtual ~CPythonChat(); + + void SetChatColor(UINT eType, UINT r, UINT g, UINT b); + + void Destroy(); + void Close(); + + int CreateChatSet(DWORD dwID); + void Update(DWORD dwID); + void Render(DWORD dwID); + void RenderWhisper(const char * c_szName, float fx, float fy); + + void SetBoardState(DWORD dwID, int iState); + void SetPosition(DWORD dwID, int ix, int iy); + void SetHeight(DWORD dwID, int iHeight); + void SetStep(DWORD dwID, int iStep); + void ToggleChatMode(DWORD dwID, int iMode); + void EnableChatMode(DWORD dwID, int iMode); + void DisableChatMode(DWORD dwID, int iMode); + void SetEndPos(DWORD dwID, float fPos); + + int GetVisibleLineCount(DWORD dwID); + int GetEditableLineCount(DWORD dwID); + int GetLineCount(DWORD dwID); + int GetLineStep(DWORD dwID); + + // Chat + void AppendChat(int iType, const char * c_szChat); + void AppendChatWithDelay(int iType, const char * c_szChat, int iDelay); + void ArrangeShowingChat(DWORD dwID); + + // Ignore + void IgnoreCharacter(const char * c_szName); + BOOL IsIgnoreCharacter(const char * c_szName); + + // Whisper + CWhisper * CreateWhisper(const char * c_szName); + void AppendWhisper(int iType, const char * c_szName, const char * c_szChat); + void ClearWhisper(const char * c_szName); + BOOL GetWhisper(const char * c_szName, CWhisper ** ppWhisper); + void InitWhisper(PyObject * ppyObject); + + protected: + void __Initialize(); + void __DestroyWhisperMap(); + + TChatLineList * GetChatLineListPtr(DWORD dwID); + TChatSet * GetChatSetPtr(DWORD dwID); + + void UpdateViewMode(DWORD dwID); + void UpdateEditMode(DWORD dwID); + void UpdateLogMode(DWORD dwID); + + DWORD GetChatColor(int iType); + + protected: + TChatLineDeque m_ChatLineDeque; + TChatLineList m_ShowingChatLineList; + TChatSetMap m_ChatSetMap; + TWhisperMap m_WhisperMap; + TIgnoreCharacterSet m_IgnoreCharacterSet; + TWaitChatList m_WaitChatList; + + D3DXCOLOR m_akD3DXClrChat[CHAT_TYPE_MAX_NUM]; +}; \ No newline at end of file diff --git a/source/UserInterface/PythonChatModule.cpp b/source/UserInterface/PythonChatModule.cpp new file mode 100644 index 0000000..d658843 --- /dev/null +++ b/source/UserInterface/PythonChatModule.cpp @@ -0,0 +1,520 @@ +#include "StdAfx.h" +#include "PythonChat.h" +#include "PythonItem.h" +#include "../gamelib/ItemManager.h" + +PyObject * chatSetChatColor(PyObject* poSelf, PyObject* poArgs) +{ + int iType; + if (!PyTuple_GetInteger(poArgs, 0, &iType)) + return Py_BuildException(); + + int r; + if (!PyTuple_GetInteger(poArgs, 1, &r)) + return Py_BuildException(); + + int g; + if (!PyTuple_GetInteger(poArgs, 2, &g)) + return Py_BuildException(); + + int b; + if (!PyTuple_GetInteger(poArgs, 3, &b)) + return Py_BuildException(); + + CPythonChat::Instance().SetChatColor(iType, r, g, b); + return Py_BuildNone(); +} + +PyObject * chatClear(PyObject* poSelf, PyObject* poArgs) +{ + CPythonChat::Instance().Destroy(); + return Py_BuildNone(); +} + +PyObject * chatClose(PyObject* poSelf, PyObject* poArgs) +{ + CPythonChat::Instance().Close(); + return Py_BuildNone(); +} + +PyObject * chatCreateChatSet(PyObject* poSelf, PyObject* poArgs) +{ + int iID; + if (!PyTuple_GetInteger(poArgs, 0, &iID)) + return Py_BuildException(); + + return Py_BuildValue("i", CPythonChat::Instance().CreateChatSet(iID)); +} + +PyObject * chatUpdate(PyObject* poSelf, PyObject* poArgs) +{ + int iID; + if (!PyTuple_GetInteger(poArgs, 0, &iID)) + return Py_BuildException(); + + CPythonChat::Instance().Update(iID); + return Py_BuildNone(); +} + +PyObject * chatRender(PyObject* poSelf, PyObject* poArgs) +{ + int iID; + if (!PyTuple_GetInteger(poArgs, 0, &iID)) + return Py_BuildException(); + + CPythonChat::Instance().Render(iID); + return Py_BuildNone(); +} + +PyObject * chatSetBoardState(PyObject* poSelf, PyObject* poArgs) +{ + int iID; + if (!PyTuple_GetInteger(poArgs, 0, &iID)) + return Py_BuildException(); + int iState; + if (!PyTuple_GetInteger(poArgs, 1, &iState)) + return Py_BuildException(); + + CPythonChat::Instance().SetBoardState(iID, iState); + + return Py_BuildNone(); +} + +PyObject * chatSetPosition(PyObject* poSelf, PyObject* poArgs) +{ + int iID; + if (!PyTuple_GetInteger(poArgs, 0, &iID)) + return Py_BuildException(); + int ix; + if (!PyTuple_GetInteger(poArgs, 1, &ix)) + return Py_BuildException(); + int iy; + if (!PyTuple_GetInteger(poArgs, 2, &iy)) + return Py_BuildException(); + + CPythonChat::Instance().SetPosition(iID, ix, iy); + + return Py_BuildNone(); +} + +PyObject * chatSetHeight(PyObject* poSelf, PyObject* poArgs) +{ + int iID; + if (!PyTuple_GetInteger(poArgs, 0, &iID)) + return Py_BuildException(); + int iHeight; + if (!PyTuple_GetInteger(poArgs, 1, &iHeight)) + return Py_BuildException(); + + CPythonChat::Instance().SetHeight(iID, iHeight); + + return Py_BuildNone(); +} + +PyObject * chatSetStep(PyObject* poSelf, PyObject* poArgs) +{ + int iID; + if (!PyTuple_GetInteger(poArgs, 0, &iID)) + return Py_BuildException(); + int iStep; + if (!PyTuple_GetInteger(poArgs, 1, &iStep)) + return Py_BuildException(); + + CPythonChat::Instance().SetStep(iID, iStep); + + return Py_BuildNone(); +} + +PyObject * chatToggleChatMode(PyObject* poSelf, PyObject* poArgs) +{ + int iID; + if (!PyTuple_GetInteger(poArgs, 0, &iID)) + return Py_BuildException(); + int iType; + if (!PyTuple_GetInteger(poArgs, 1, &iType)) + return Py_BuildException(); + + CPythonChat::Instance().ToggleChatMode(iID, iType); + + return Py_BuildNone(); +} + +PyObject * chatEnableChatMode(PyObject* poSelf, PyObject* poArgs) +{ + int iID; + if (!PyTuple_GetInteger(poArgs, 0, &iID)) + return Py_BuildException(); + int iType; + if (!PyTuple_GetInteger(poArgs, 1, &iType)) + return Py_BuildException(); + + CPythonChat::Instance().EnableChatMode(iID, iType); + + return Py_BuildNone(); +} + +PyObject * chatDisableChatMode(PyObject* poSelf, PyObject* poArgs) +{ + int iID; + if (!PyTuple_GetInteger(poArgs, 0, &iID)) + return Py_BuildException(); + int iType; + if (!PyTuple_GetInteger(poArgs, 1, &iType)) + return Py_BuildException(); + + CPythonChat::Instance().DisableChatMode(iID, iType); + + return Py_BuildNone(); +} + +PyObject * chatSetEndPos(PyObject* poSelf, PyObject* poArgs) +{ + int iID; + if (!PyTuple_GetInteger(poArgs, 0, &iID)) + return Py_BuildException(); + float fPos; + if (!PyTuple_GetFloat(poArgs, 1, &fPos)) + return Py_BuildException(); + + CPythonChat::Instance().SetEndPos(iID, fPos); + + return Py_BuildNone(); +} + +PyObject * chatGetLineCount(PyObject* poSelf, PyObject* poArgs) +{ + int iID; + if (!PyTuple_GetInteger(poArgs, 0, &iID)) + return Py_BuildException(); + + return Py_BuildValue("i", CPythonChat::Instance().GetLineCount(iID)); +} + +PyObject * chatGetVisibleLineCount(PyObject* poSelf, PyObject* poArgs) +{ + int iID; + if (!PyTuple_GetInteger(poArgs, 0, &iID)) + return Py_BuildException(); + + return Py_BuildValue("i", CPythonChat::Instance().GetVisibleLineCount(iID)); +} + +PyObject * chatGetLineStep(PyObject* poSelf, PyObject* poArgs) +{ + int iID; + if (!PyTuple_GetInteger(poArgs, 0, &iID)) + return Py_BuildException(); + + return Py_BuildValue("i", CPythonChat::Instance().GetLineStep(iID)); +} + +PyObject * chatAppendChat(PyObject* poSelf, PyObject* poArgs) +{ + int iType; + if (!PyTuple_GetInteger(poArgs, 0, &iType)) + return Py_BuildException(); + + char * szChat; + if (!PyTuple_GetString(poArgs, 1, &szChat)) + return Py_BuildException(); + + CPythonChat::Instance().AppendChat(iType, szChat); + + return Py_BuildNone(); +} + +PyObject * chatAppendChatWithDelay(PyObject* poSelf, PyObject* poArgs) +{ + int iType; + if (!PyTuple_GetInteger(poArgs, 0, &iType)) + return Py_BuildException(); + + char * szChat; + if (!PyTuple_GetString(poArgs, 1, &szChat)) + return Py_BuildException(); + + int iDelay; + if (!PyTuple_GetInteger(poArgs, 2, &iDelay)) + return Py_BuildException(); + + CPythonChat::Instance().AppendChatWithDelay(iType, szChat, iDelay); + + return Py_BuildNone(); +} + +PyObject * chatArrangeShowingChat(PyObject* poSelf, PyObject* poArgs) +{ + int iID; + if (!PyTuple_GetInteger(poArgs, 0, &iID)) + return Py_BuildException(); + + CPythonChat::Instance().ArrangeShowingChat(iID); + + return Py_BuildNone(); +} + +PyObject * chatIgnoreCharacter(PyObject* poSelf, PyObject* poArgs) +{ + char * szName; + if (!PyTuple_GetString(poArgs, 0, &szName)) + return Py_BuildException(); + + CPythonChat::Instance().IgnoreCharacter(szName); + + return Py_BuildNone(); +} + +PyObject * chatIsIgnoreCharacter(PyObject* poSelf, PyObject* poArgs) +{ + char * szName; + if (!PyTuple_GetString(poArgs, 0, &szName)) + return Py_BuildException(); + + CPythonChat::Instance().IsIgnoreCharacter(szName); + + return Py_BuildNone(); +} + +PyObject * chatCreateWhisper(PyObject* poSelf, PyObject* poArgs) +{ + char * szName; + if (!PyTuple_GetString(poArgs, 0, &szName)) + return Py_BuildException(); + + CPythonChat::Instance().CreateWhisper(szName); + + return Py_BuildNone(); +} + +PyObject * chatAppendWhisper(PyObject* poSelf, PyObject* poArgs) +{ + int iType; + if (!PyTuple_GetInteger(poArgs, 0, &iType)) + return Py_BuildException(); + + char * szName; + if (!PyTuple_GetString(poArgs, 1, &szName)) + return Py_BuildException(); + + char * szChat; + if (!PyTuple_GetString(poArgs, 2, &szChat)) + return Py_BuildException(); + + CPythonChat::Instance().AppendWhisper(iType, szName, szChat); + return Py_BuildNone(); +} + +PyObject * chatRenderWhisper(PyObject* poSelf, PyObject* poArgs) +{ + char * szName; + if (!PyTuple_GetString(poArgs, 0, &szName)) + return Py_BuildException(); + + float fx; + if (!PyTuple_GetFloat(poArgs, 1, &fx)) + return Py_BuildException(); + + float fy; + if (!PyTuple_GetFloat(poArgs, 2, &fy)) + return Py_BuildException(); + + CWhisper * pWhisper; + if (CPythonChat::Instance().GetWhisper(szName, &pWhisper)) + { + pWhisper->Render(fx, fy); + } + + return Py_BuildNone(); +} + +PyObject * chatSetWhisperBoxSize(PyObject* poSelf, PyObject* poArgs) +{ + char * szName; + if (!PyTuple_GetString(poArgs, 0, &szName)) + return Py_BuildException(); + + float fWidth; + if (!PyTuple_GetFloat(poArgs, 1, &fWidth)) + return Py_BuildException(); + + float fHeight; + if (!PyTuple_GetFloat(poArgs, 2, &fHeight)) + return Py_BuildException(); + + CWhisper * pWhisper; + if (CPythonChat::Instance().GetWhisper(szName, &pWhisper)) + { + pWhisper->SetBoxSize(fWidth, fHeight); + } + + return Py_BuildNone(); +} + +PyObject * chatSetWhisperPosition(PyObject* poSelf, PyObject* poArgs) +{ + char * szName; + if (!PyTuple_GetString(poArgs, 0, &szName)) + return Py_BuildException(); + + float fPosition; + if (!PyTuple_GetFloat(poArgs, 1, &fPosition)) + return Py_BuildException(); + + CWhisper * pWhisper; + if (CPythonChat::Instance().GetWhisper(szName, &pWhisper)) + { + pWhisper->SetPosition(fPosition); + } + + return Py_BuildNone(); +} + +PyObject * chatClearWhisper(PyObject* poSelf, PyObject* poArgs) +{ + char * szName; + if (!PyTuple_GetString(poArgs, 0, &szName)) + return Py_BuildException(); + + CPythonChat::Instance().ClearWhisper(szName); + + return Py_BuildNone(); +} + +PyObject * chatInitWhisper(PyObject* poSelf, PyObject* poArgs) +{ + PyObject * poInterface; + if (!PyTuple_GetObject(poArgs, 0, &poInterface)) + return Py_BuildException(); + + CPythonChat::Instance().InitWhisper(poInterface); + return Py_BuildNone(); +} + +PyObject * chatGetLinkFromHyperlink(PyObject * poSelf, PyObject * poArgs) +{ + char * szHyperlink; + + if (!PyTuple_GetString(poArgs, 0, &szHyperlink)) + return Py_BuildException(); + + std::string stHyperlink(szHyperlink); + std::vector results; + + split_string(stHyperlink, ":", results, false); + + // item:vnum:flag:socket0:socket1:socket2 + if (0 == results[0].compare("item")) + { + if (results.size() < 6) + return Py_BuildValue("s", ""); + + CItemData * pItemData = NULL; + + if (CItemManager::Instance().GetItemDataPointer(htoi(results[1].c_str()), &pItemData)) + { + char buf[1024] = { 0 }; + char itemlink[256]; + int len; + bool isAttr = false; + + len = snprintf(itemlink, sizeof(itemlink), "item:%x:%x:%x:%x:%x", + htoi(results[1].c_str()), + htoi(results[2].c_str()), + htoi(results[3].c_str()), + htoi(results[4].c_str()), + htoi(results[5].c_str())); + + if (results.size() >= 8) + { + for (int i = 6; i < results.size(); i += 2) + { + len += snprintf(itemlink + len, sizeof(itemlink) - len, ":%x:%I64d", + htoi(results[i].c_str()), + atoi(results[i+1].c_str())); + isAttr = true; + } + } + + if (isAttr) + //"item:ȣ:÷:0:1:2" + snprintf(buf, sizeof(buf), "|cffffc700|H%s|h[%s]|h|r", itemlink, pItemData->GetName()); + else + snprintf(buf, sizeof(buf), "|cfff1e6c0|H%s|h[%s]|h|r", itemlink, pItemData->GetName()); + + return Py_BuildValue("s", buf); + } + } + + return Py_BuildValue("s", ""); +} + +void initChat() +{ + static PyMethodDef s_methods[] = + { + { "SetChatColor", chatSetChatColor, METH_VARARGS }, + { "Clear", chatClear, METH_VARARGS }, + { "Close", chatClose, METH_VARARGS }, + + { "CreateChatSet", chatCreateChatSet, METH_VARARGS }, + { "Update", chatUpdate, METH_VARARGS }, + { "Render", chatRender, METH_VARARGS }, + + { "SetBoardState", chatSetBoardState, METH_VARARGS }, + { "SetPosition", chatSetPosition, METH_VARARGS }, + { "SetHeight", chatSetHeight, METH_VARARGS }, + { "SetStep", chatSetStep, METH_VARARGS }, + { "ToggleChatMode", chatToggleChatMode, METH_VARARGS }, + { "EnableChatMode", chatEnableChatMode, METH_VARARGS }, + { "DisableChatMode", chatDisableChatMode, METH_VARARGS }, + { "SetEndPos", chatSetEndPos, METH_VARARGS }, + + { "GetLineCount", chatGetLineCount, METH_VARARGS }, + { "GetVisibleLineCount", chatGetVisibleLineCount, METH_VARARGS }, + { "GetLineStep", chatGetLineStep, METH_VARARGS }, + + // Chat + { "AppendChat", chatAppendChat, METH_VARARGS }, + { "AppendChatWithDelay", chatAppendChatWithDelay, METH_VARARGS }, + { "ArrangeShowingChat", chatArrangeShowingChat, METH_VARARGS }, + + // Ignore + { "IgnoreCharacter", chatIgnoreCharacter, METH_VARARGS }, + { "IsIgnoreCharacter", chatIsIgnoreCharacter, METH_VARARGS }, + + // Whisper + { "CreateWhisper", chatCreateWhisper, METH_VARARGS }, + { "AppendWhisper", chatAppendWhisper, METH_VARARGS }, + { "RenderWhisper", chatRenderWhisper, METH_VARARGS }, + { "SetWhisperBoxSize", chatSetWhisperBoxSize, METH_VARARGS }, + { "SetWhisperPosition", chatSetWhisperPosition, METH_VARARGS }, + { "ClearWhisper", chatClearWhisper, METH_VARARGS }, + { "InitWhisper", chatInitWhisper, METH_VARARGS }, + + // Link + { "GetLinkFromHyperlink", chatGetLinkFromHyperlink, METH_VARARGS }, + + { NULL, NULL, NULL }, + }; + + PyObject * poModule = Py_InitModule("chat", s_methods); + + PyModule_AddIntConstant(poModule, "CHAT_TYPE_TALKING", CHAT_TYPE_TALKING); + PyModule_AddIntConstant(poModule, "CHAT_TYPE_INFO", CHAT_TYPE_INFO); + PyModule_AddIntConstant(poModule, "CHAT_TYPE_NOTICE", CHAT_TYPE_NOTICE); + PyModule_AddIntConstant(poModule, "CHAT_TYPE_PARTY", CHAT_TYPE_PARTY); + PyModule_AddIntConstant(poModule, "CHAT_TYPE_GUILD", CHAT_TYPE_GUILD); + PyModule_AddIntConstant(poModule, "CHAT_TYPE_COMMAND", CHAT_TYPE_COMMAND); + PyModule_AddIntConstant(poModule, "CHAT_TYPE_SHOUT", CHAT_TYPE_SHOUT); + PyModule_AddIntConstant(poModule, "CHAT_TYPE_WHISPER", CHAT_TYPE_WHISPER); + PyModule_AddIntConstant(poModule, "WHISPER_TYPE_CHAT", CPythonChat::WHISPER_TYPE_CHAT); + PyModule_AddIntConstant(poModule, "WHISPER_TYPE_SYSTEM", CPythonChat::WHISPER_TYPE_SYSTEM); + PyModule_AddIntConstant(poModule, "WHISPER_TYPE_GM", CPythonChat::WHISPER_TYPE_GM); + + PyModule_AddIntConstant(poModule, "BOARD_STATE_VIEW", CPythonChat::BOARD_STATE_VIEW); + PyModule_AddIntConstant(poModule, "BOARD_STATE_EDIT", CPythonChat::BOARD_STATE_EDIT); + PyModule_AddIntConstant(poModule, "BOARD_STATE_LOG", CPythonChat::BOARD_STATE_LOG); + + PyModule_AddIntConstant(poModule, "CHAT_SET_CHAT_WINDOW", 0); + PyModule_AddIntConstant(poModule, "CHAT_SET_LOG_WINDOW", 1); +} diff --git a/source/UserInterface/PythonEffectModule.cpp b/source/UserInterface/PythonEffectModule.cpp new file mode 100644 index 0000000..9cab6ea --- /dev/null +++ b/source/UserInterface/PythonEffectModule.cpp @@ -0,0 +1,150 @@ +#include "StdAfx.h" +#include "../EffectLib/EffectManager.h" +#include "PythonCharacterManager.h" + +PyObject * effectRegisterEffect(PyObject * poSelf, PyObject * poArgs) +{ + char * szFileName; + if (!PyTuple_GetString(poArgs, 0, &szFileName)) + return Py_BuildException(); + + CEffectManager::Instance().RegisterEffect(szFileName); + return Py_BuildNone(); +} + +PyObject * effectUpdate(PyObject * poSelf, PyObject * poArgs) +{ + CEffectManager::Instance().Update(); + return Py_BuildNone(); +} + +PyObject * effectRender(PyObject * poSelf, PyObject * poArgs) +{ + CEffectManager::Instance().Render(); + return Py_BuildNone(); +} + +PyObject * effectCreateEffect(PyObject * poSelf, PyObject * poArgs) +{ + char * szEffectName; + if (!PyTuple_GetString(poArgs, 0, &szEffectName)) + return Py_BuildException(); + + CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetSelectedInstancePtr(); + TPixelPosition PixelPosition; + pInstance->NEW_GetPixelPosition(&PixelPosition); + int iIndex = CEffectManager::Instance().CreateEffect(szEffectName, PixelPosition, D3DXVECTOR3(0.0f, 0.0f, 0.0f)); + + return Py_BuildValue("i", iIndex); +} + +PyObject * effectDeleteEffect(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + + CEffectManager::Instance().DestroyEffectInstance(iIndex); + + return Py_BuildNone(); +} + +PyObject * effectSetPosition(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + float fx; + if (!PyTuple_GetFloat(poArgs, 1, &fx)) + return Py_BuildException(); + float fy; + if (!PyTuple_GetFloat(poArgs, 2, &fy)) + return Py_BuildException(); + float fz; + if (!PyTuple_GetFloat(poArgs, 3, &fz)) + return Py_BuildException(); + + CEffectManager::Instance().SelectEffectInstance(iIndex); + CEffectManager::Instance().SetEffectInstancePosition(D3DXVECTOR3(fx, fy, fz)); + + return Py_BuildNone(); +} + +PyObject * effectRegisterIndexedFlyData(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + int iType; + if (!PyTuple_GetInteger(poArgs, 1, &iType)) + return Py_BuildException(); + char * szFlyDataName; + if (!PyTuple_GetString(poArgs, 2, &szFlyDataName)) + return Py_BuildException(); + + CFlyingManager::Instance().RegisterIndexedFlyData(iIndex, iType, szFlyDataName); + + return Py_BuildNone(); +} + +void initeffect() +{ + static PyMethodDef s_methods[] = + { + { "RegisterEffect", effectRegisterEffect, METH_VARARGS }, + { "CreateEffect", effectCreateEffect, METH_VARARGS }, + { "DeleteEffect", effectDeleteEffect, METH_VARARGS }, + { "SetPosition", effectSetPosition, METH_VARARGS }, + + { "RegisterIndexedFlyData", effectRegisterIndexedFlyData, METH_VARARGS }, + + { "Update", effectUpdate, METH_VARARGS }, + { "Render", effectRender, METH_VARARGS }, + + { NULL, NULL, NULL }, + }; + + PyObject * poModule = Py_InitModule("effect", s_methods); + PyModule_AddIntConstant(poModule, "INDEX_FLY_TYPE_NORMAL", CFlyingManager::INDEX_FLY_TYPE_NORMAL); + PyModule_AddIntConstant(poModule, "INDEX_FLY_TYPE_FIRE_CRACKER", CFlyingManager::INDEX_FLY_TYPE_FIRE_CRACKER); + PyModule_AddIntConstant(poModule, "INDEX_FLY_TYPE_AUTO_FIRE", CFlyingManager::INDEX_FLY_TYPE_AUTO_FIRE); + + enum + { + FLY_NONE, + FLY_EXP, + FLY_HP_MEDIUM, + FLY_HP_BIG, + FLY_SP_SMALL, + FLY_SP_MEDIUM, + FLY_SP_BIG, + FLY_FIREWORK1, + FLY_FIREWORK2, + FLY_FIREWORK3, + FLY_FIREWORK4, + FLY_FIREWORK5, + FLY_FIREWORK6, + FLY_FIREWORK_XMAS, + FLY_CHAIN_LIGHTNING, + FLY_HP_SMALL, + FLY_SKILL_MUYEONG, + }; + + PyModule_AddIntConstant(poModule, "FLY_NONE", FLY_NONE); + PyModule_AddIntConstant(poModule, "FLY_EXP", FLY_EXP); + PyModule_AddIntConstant(poModule, "FLY_HP_MEDIUM", FLY_HP_MEDIUM); + PyModule_AddIntConstant(poModule, "FLY_HP_BIG", FLY_HP_BIG); + PyModule_AddIntConstant(poModule, "FLY_SP_SMALL", FLY_SP_SMALL); + PyModule_AddIntConstant(poModule, "FLY_SP_MEDIUM", FLY_SP_MEDIUM); + PyModule_AddIntConstant(poModule, "FLY_SP_BIG", FLY_SP_BIG); + PyModule_AddIntConstant(poModule, "FLY_FIREWORK1", FLY_FIREWORK1); + PyModule_AddIntConstant(poModule, "FLY_FIREWORK2", FLY_FIREWORK2); + PyModule_AddIntConstant(poModule, "FLY_FIREWORK3", FLY_FIREWORK3); + PyModule_AddIntConstant(poModule, "FLY_FIREWORK4", FLY_FIREWORK4); + PyModule_AddIntConstant(poModule, "FLY_FIREWORK5", FLY_FIREWORK5); + PyModule_AddIntConstant(poModule, "FLY_FIREWORK6", FLY_FIREWORK6); + PyModule_AddIntConstant(poModule, "FLY_FIREWORK_XMAS", FLY_FIREWORK_XMAS); + PyModule_AddIntConstant(poModule, "FLY_CHAIN_LIGHTNING", FLY_CHAIN_LIGHTNING); + PyModule_AddIntConstant(poModule, "FLY_HP_SMALL", FLY_HP_SMALL); + PyModule_AddIntConstant(poModule, "FLY_SKILL_MUYEONG", FLY_SKILL_MUYEONG); +} diff --git a/source/UserInterface/PythonEventManager.cpp b/source/UserInterface/PythonEventManager.cpp new file mode 100644 index 0000000..345a004 --- /dev/null +++ b/source/UserInterface/PythonEventManager.cpp @@ -0,0 +1,1211 @@ +#include "StdAfx.h" +#include "PythonEventManager.h" +#include "PythonNetworkStream.h" +#include "PythonNonPlayer.h" + +#include "AbstractApplication.h" + +#include "../gamelib/ItemData.h" +#include "../gamelib/ItemManager.h" + +#include "../eterPack/EterPackManager.h" + +#include "PythonMiniMap.h" + +const long c_lNormal_Waiting_Time = 10; +const int c_fLine_Temp = 16; + +void ShowArgument(script::TArgList & rArgumentList) +{ + for (script::TArgList::iterator itor=rArgumentList.begin(); itor!=rArgumentList.end(); ++itor) + { + const std::string & rName = (*itor).strName; + + Tracen(rName.c_str()); + } + +} + +const std::string& GetArgumentString(const char * c_szName, script::TArgList & rArgumentList) +{ + for (script::TArgList::iterator itor = rArgumentList.begin(); itor != rArgumentList.end(); ++itor) + { + const std::string & rName = (*itor).strName; + + if (0 == rName.compare(c_szName)) + return (*itor).strValue; + } + + static std::string strEmptyValue = ""; + return strEmptyValue; +} + +const char * GetArgument(const char * c_szName, script::TArgList & rArgumentList) +{ + return GetArgumentString(c_szName, rArgumentList).c_str(); +} + +void GetCameraSettingFromArgList(script::TArgList & rArgList, IAbstractApplication::SCameraSetting * pCameraSetting) +{ + int ix = atoi(GetArgument("x", rArgList)); + int iy = atoi(GetArgument("y", rArgList)); + int iz = atoi(GetArgument("z", rArgList)); + int iUpDir = atoi(GetArgument("up", rArgList)); + int iViewDir = atoi(GetArgument("view", rArgList)); + int iCrossDir = atoi(GetArgument("cross", rArgList)); + int iDistance = atoi(GetArgument("distance", rArgList)); + int iRot = atoi(GetArgument("rot", rArgList)); + int iPitch = atoi(GetArgument("pitch", rArgList)); + + ZeroMemory(pCameraSetting, sizeof(IAbstractApplication::SCameraSetting)); + pCameraSetting->v3CenterPosition.x = float(ix); + pCameraSetting->v3CenterPosition.y = float(iy); + pCameraSetting->v3CenterPosition.z = float(iz); + pCameraSetting->kCmrPos.m_fUpDir = float(iUpDir); + pCameraSetting->kCmrPos.m_fViewDir = float(iViewDir); + pCameraSetting->kCmrPos.m_fCrossDir = float(iCrossDir); + pCameraSetting->fZoom = float(iDistance); + pCameraSetting->fRotation = float(iRot); + pCameraSetting->fPitch = float(iPitch); +} + +void CPythonEventManager::__InitEventSet(TEventSet& rEventSet) +{ + rEventSet.ix = 0; + rEventSet.iy = 0; + rEventSet.iWidth = 0; + rEventSet.iyLocal = 0; + + rEventSet.isLock = false; + rEventSet.lLastDelayTime = 0; + rEventSet.iCurrentLetter = 0; + rEventSet.CurrentColor = D3DXCOLOR(1, 1, 1, 1); + rEventSet.strCurrentLine = ""; + + rEventSet.pCurrentTextLine = NULL; + rEventSet.ScriptTextLineList.clear(); + + rEventSet.isConfirmWait = FALSE; + rEventSet.pConfirmTimeTextLine = NULL; + rEventSet.iConfirmEndTime = 0; + + rEventSet.DiffuseColor = D3DXCOLOR(1, 1, 1, 1); + rEventSet.lWaitingTime = c_lNormal_Waiting_Time; + rEventSet.iRestrictedCharacterCount = 30; + + rEventSet.iVisibleStartLine = 0; + rEventSet.iVisibleLineCount = BOX_VISIBLE_LINE_COUNT; + + rEventSet.iAdjustLine = 0; + + rEventSet.isTextCenterMode = false; + rEventSet.isWaitFlag = false; + + __InsertLine(rEventSet); +} + +int CPythonEventManager::RegisterEventSet(const char * c_szFileName) +{ + CMappedFile File; + LPCVOID pMap; + + if (!CEterPackManager::Instance().Get(File, c_szFileName, &pMap)) + return -1; + + std::string strEventString; + strEventString.resize(File.Size()+1); + + File.Read(&strEventString[0], File.Size()); + + TEventSet * pEventSet = m_EventSetPool.Alloc(); + if (!pEventSet) + return -1; + + if (!pEventSet->ScriptGroup.Create(strEventString)) + { + __ClearEventSetp(pEventSet); + return -1; + } + + strncpy(pEventSet->szFileName, c_szFileName, 32); + + pEventSet->pCurrentTextLine = NULL; + pEventSet->poEventHandler = NULL; + + __InitEventSet(*pEventSet); + + int iEmptySlotIndex = GetEmptyEventSetSlot(); + m_EventSetVector[iEmptySlotIndex] = pEventSet; + return iEmptySlotIndex; +} + +int CPythonEventManager::RegisterEventSetFromString(const std::string& strScript) +{ + TEventSet* pEventSet = m_EventSetPool.Alloc(); + if (!pEventSet) + return -1; + + // SCRIPT_PARSING_FAILURE_CLEAR_BUG ũƮ Ľ н __ClearEventSetp ߻ + pEventSet->pCurrentTextLine = NULL; + // END_OF_SCRIPT_PARSING_FAILURE_CLEAR_BUG + + if (!pEventSet->ScriptGroup.Create(strScript)) + { + __ClearEventSetp(pEventSet); + return -1; + } + + pEventSet->szFileName[0] = 0; + pEventSet->poEventHandler = NULL; + __InitEventSet(*pEventSet); + + // NOTE : ܼ ũƮ ̺Ʈ Ŀǵ ٽ . + script::TCmd ScriptCommand; + int pEventPosition; + int iEventType; + if (pEventSet->ScriptGroup.ReadCmd(ScriptCommand)) + { + if (GetScriptEventIndex(ScriptCommand.name.c_str(), &pEventPosition, &iEventType)) + { + if (EVENT_TYPE_RUN_CINEMA == iEventType) + { + std::string strFileName = GetArgument("value", ScriptCommand.argList); + + __ClearEventSetp(pEventSet); + + return RegisterEventSet(strFileName.c_str()); + } + } + } + + int iEmptySlotIndex = GetEmptyEventSetSlot(); + m_EventSetVector[iEmptySlotIndex] = pEventSet; + return iEmptySlotIndex; +} + +void CPythonEventManager::ClearEventSeti(int iIndex) +{ + if (!CheckEventSetIndex(iIndex)) + return; + + __ClearEventSetp(m_EventSetVector[iIndex]); + m_EventSetVector[iIndex] = NULL; +} + +void CPythonEventManager::__ClearEventSetp(TEventSet * pEventSet) +{ + if (!pEventSet) + return; + + for (TScriptTextLineList::iterator itor = pEventSet->ScriptTextLineList.begin(); itor != pEventSet->ScriptTextLineList.end(); ++itor) + { + TTextLine & rkLine = *itor; + rkLine.pInstance->Destroy(); + m_ScriptTextLinePool.Free(rkLine.pInstance); + } + pEventSet->ScriptTextLineList.clear(); + + if (pEventSet->pCurrentTextLine) + { + pEventSet->pCurrentTextLine->Destroy(); + m_ScriptTextLinePool.Free(pEventSet->pCurrentTextLine); + } + pEventSet->pCurrentTextLine = NULL; + pEventSet->strCurrentLine = ""; + pEventSet->iCurrentLetter = 0; + + m_EventSetPool.Free(pEventSet); +} + +DWORD CPythonEventManager::GetEmptyEventSetSlot() +{ + for (DWORD i = 0; i < m_EventSetVector.size(); ++i) + { + if (NULL == m_EventSetVector[i]) + { + return i; + } + } + + m_EventSetVector.push_back(NULL); + return m_EventSetVector.size()-1; +} + +void CPythonEventManager::SetRestrictedCount(int iIndex, int iCount) +{ + if (!CheckEventSetIndex(iIndex)) + return; + + TEventSet * pEventSet = m_EventSetVector[iIndex]; + if (!pEventSet) + { + TraceError("CPythonEventManager::SetRestrictedCount m_EventSetVector[iIndex=%d]==NULL", iIndex); + return; + } + + pEventSet->iRestrictedCharacterCount = iCount; +} + +void CPythonEventManager::SetEventHandler(int iIndex, PyObject * poEventHandler) +{ + if (!CheckEventSetIndex(iIndex)) + return; + + TEventSet * pEventSet = m_EventSetVector[iIndex]; + if (!pEventSet) + { + TraceError("CPythonEventManager::SetEventHandler m_EventSetVector[iIndex=%d]==NULL", iIndex); + return; + } + + pEventSet->poEventHandler = poEventHandler; +} + +int CPythonEventManager::GetEventSetLocalYPosition(int iIndex) +{ + if (!CheckEventSetIndex(iIndex)) + return 0; + + TEventSet * pEventSet = m_EventSetVector[iIndex]; + if (!pEventSet) + return 0; + + return pEventSet->iyLocal; +} + +void CPythonEventManager::AddEventSetLocalYPosition(int iIndex, int iAddValue) +{ + if (!CheckEventSetIndex(iIndex)) + return; + + TEventSet * pEventSet = m_EventSetVector[iIndex]; + if (!pEventSet) + return; + + pEventSet->iyLocal += iAddValue; +} + +void CPythonEventManager::InsertText(int iIndex, const char * c_szText,int iX_pos) +{ + if (!CheckEventSetIndex(iIndex)) + return; + + TEventSet * pEventSet = m_EventSetVector[iIndex]; + if (!pEventSet) + return; + + pEventSet->strCurrentLine = c_szText; + if (pEventSet->pCurrentTextLine) + { + pEventSet->pCurrentTextLine->SetValue(c_szText); + if (iX_pos == 0) + { + pEventSet->pCurrentTextLine->SetHorizonalAlign(CGraphicTextInstance::HORIZONTAL_ALIGN_CENTER); + } + } + + pEventSet->pCurrentTextLine->Update(); + __InsertLine(*pEventSet, FALSE, iX_pos); +} + + +void CPythonEventManager::UpdateEventSet(int iIndex, int ix, int iy) +{ + if (!CheckEventSetIndex(iIndex)) + return; + + TEventSet * pEventSet = m_EventSetVector[iIndex]; + if (!pEventSet) + return; + + pEventSet->ix = ix; + pEventSet->iy = iy; + + RefreshLinePosition(pEventSet); + + if (pEventSet->isConfirmWait) + { + int iLeftTime = max(0, pEventSet->iConfirmEndTime - timeGetTime()/1000); + pEventSet->pConfirmTimeTextLine->SetValue(_getf(m_strLeftTimeString.c_str(), iLeftTime)); + } + + if (pEventSet->isWaitFlag) + return; + + /////////////////////////////////////////////////////////////////////////////////////////////// + + // Process EventSet + long lElapsedTime = CTimer::Instance().GetElapsedMilliecond(); + + pEventSet->lLastDelayTime = max(0, pEventSet->lLastDelayTime - lElapsedTime); + + while (lElapsedTime > 0) + { + pEventSet->lLastDelayTime -= lElapsedTime; + + if (pEventSet->lLastDelayTime <= 0) + { + lElapsedTime = -pEventSet->lLastDelayTime; + if (lElapsedTime <= 0) + break; + + ProcessEventSet(pEventSet); + + if (pEventSet->lLastDelayTime < 0) + { + pEventSet->lLastDelayTime = 0; + break; + } + } + else + break; + } +} + +void CPythonEventManager::SetEventSetWidth(int iIndex, int iWidth) +{ + if (!CheckEventSetIndex(iIndex)) + return; + + TEventSet * pEventSet = m_EventSetVector[iIndex]; + if (!pEventSet) + return; + + pEventSet->iWidth = iWidth; +} + +void CPythonEventManager::ProcessEventSet(TEventSet * pEventSet) +{ + if (pEventSet->isLock) + return; + + script::TCmd ScriptCommand; + + IAbstractApplication& rApp=IAbstractApplication::GetSingleton(); + + if (!pEventSet->ScriptGroup.GetCmd(ScriptCommand)) + { + pEventSet->isLock = true; + return; + } + + int pEventPosition; + int iEventType; + if (!GetScriptEventIndex(ScriptCommand.name.c_str(), &pEventPosition, &iEventType)) + return; + + switch (iEventType) + { + case EVENT_TYPE_LETTER: + { + const std::string& c_rstValue = GetArgumentString("value", ScriptCommand.argList); + pEventSet->strCurrentLine.append(c_rstValue); + pEventSet->pCurrentTextLine->SetValueString(pEventSet->strCurrentLine); + pEventSet->pCurrentTextLine->SetColor(pEventSet->CurrentColor.r,pEventSet->CurrentColor.g,pEventSet->CurrentColor.b); + pEventSet->iCurrentLetter+=c_rstValue.length(); + + if (pEventSet->iCurrentLetter >= pEventSet->iRestrictedCharacterCount) + { + __InsertLine(*pEventSet); + } + + pEventSet->lLastDelayTime = pEventSet->lWaitingTime; + break; + } + + case EVENT_TYPE_DELAY: + { + if (EVENT_POSITION_START == pEventPosition) + pEventSet->lWaitingTime = atoi(GetArgument("value", ScriptCommand.argList)); + else + pEventSet->lWaitingTime = c_lNormal_Waiting_Time; + break; + } + + case EVENT_TYPE_COLOR: + { + if (EVENT_POSITION_START == pEventPosition) + { + pEventSet->CurrentColor.r = (float)atof(GetArgument("r", ScriptCommand.argList)); + pEventSet->CurrentColor.g = (float)atof(GetArgument("g", ScriptCommand.argList)); + pEventSet->CurrentColor.b = (float)atof(GetArgument("b", ScriptCommand.argList)); + pEventSet->CurrentColor.a = 1.0f; + } + else + { + pEventSet->CurrentColor.r = 1.0f; + pEventSet->CurrentColor.g = 1.0f; + pEventSet->CurrentColor.a = 1.0f; + pEventSet->CurrentColor.b = 1.0f; + } + break; + } + + case EVENT_TYPE_COLOR256: + { + if (EVENT_POSITION_START == pEventPosition) + { + pEventSet->CurrentColor.r = float(atof(GetArgument("r", ScriptCommand.argList)) / 255.0f); + pEventSet->CurrentColor.g = float(atof(GetArgument("g", ScriptCommand.argList)) / 255.0f); + pEventSet->CurrentColor.b = float(atof(GetArgument("b", ScriptCommand.argList)) / 255.0f); + pEventSet->CurrentColor.a = 1.0f; + } + else + { + pEventSet->CurrentColor.r = 1.0f; + pEventSet->CurrentColor.g = 1.0f; + pEventSet->CurrentColor.a = 1.0f; + pEventSet->CurrentColor.b = 1.0f; + } + break; + } + + case EVENT_TYPE_ENTER: + { + __InsertLine(*pEventSet); + break; + } + + case EVENT_TYPE_WAIT: + { + //ijƽ  /EVENT_TYPE_WAIT ؼ ׽Ʈ ʿ. + pEventSet->iyLocal = 0; + pEventSet->isLock = true; + break; + } + + case EVENT_TYPE_NEXT: + { + MakeNextButton(pEventSet, BUTTON_TYPE_NEXT); + pEventSet->iAdjustLine += 2; + break; + } + + case EVENT_TYPE_DONE: + { + MakeNextButton(pEventSet, BUTTON_TYPE_DONE); + PyCallClassMemberFunc(pEventSet->poEventHandler, "DoneEvent", Py_BuildValue("()")); + pEventSet->iAdjustLine += 2; + break; + } + + case EVENT_TYPE_CLEAR: + { + ClearLine(pEventSet); + break; + } + + case EVENT_TYPE_QUESTION: + { + MakeQuestion(pEventSet, ScriptCommand.argList); + break; + } + + case EVENT_TYPE_LEFT_IMAGE: + { + PyCallClassMemberFunc(pEventSet->poEventHandler, "OnLeftImage", Py_BuildValue("(s)", GetArgument("src", ScriptCommand.argList))); + break; + } + + case EVENT_TYPE_TOP_IMAGE: + { + PyCallClassMemberFunc(pEventSet->poEventHandler, "OnTopImage", Py_BuildValue("(s)", GetArgument("src", ScriptCommand.argList))); + break; + } + + case EVENT_TYPE_BACKGROUND_IMAGE: + { + PyCallClassMemberFunc(pEventSet->poEventHandler, "OnBackgroundImage", Py_BuildValue("(s)",GetArgument("src", ScriptCommand.argList))); + break; + } + + case EVENT_TYPE_IMAGE: + { + int x = atoi(GetArgument("x", ScriptCommand.argList)); + int y = atoi(GetArgument("y", ScriptCommand.argList)); + const char * src = GetArgument("src", ScriptCommand.argList); + + PyCallClassMemberFunc(pEventSet->poEventHandler, "OnImage", Py_BuildValue("(iis)", x, y, src)); + break; + } + + case EVENT_TYPE_INSERT_IMAGE: + { + const std::string & imageFile = GetArgumentString("image_name", ScriptCommand.argList); + const char * title = GetArgument("title", ScriptCommand.argList); + const char * desc = GetArgument("desc", ScriptCommand.argList); + int index = atoi(GetArgument("index", ScriptCommand.argList)); + int total = atoi(GetArgument("total", ScriptCommand.argList)); + + if (imageFile.empty()) + { + const char * imageType = GetArgument("image_type", ScriptCommand.argList); + int iItemIndex = atoi(GetArgument("idx", ScriptCommand.argList)); + PyCallClassMemberFunc(pEventSet->poEventHandler, "OnInsertItemIcon", Py_BuildValue("(sissii)", imageType, iItemIndex, title, desc, index, total)); + } + else + { + PyCallClassMemberFunc(pEventSet->poEventHandler, "OnInsertImage", Py_BuildValue("(ssssii)", imageFile.c_str(), title, title, desc, index, total)); + } + pEventSet->iAdjustLine += 2; + break; + } + + case EVENT_TYPE_ADD_MAP_SIGNAL: + { + float x, y; + x = (float)atof(GetArgument("x",ScriptCommand.argList)); + y = (float)atof(GetArgument("y",ScriptCommand.argList)); + CPythonMiniMap::Instance().AddSignalPoint(x,y); + CPythonMiniMap::Instance().OpenAtlasWindow(); + break; + } + + case EVENT_TYPE_CLEAR_MAP_SIGNAL: + { + CPythonMiniMap::Instance().ClearAllSignalPoint(); + break; + } + + // HIDE_QUEST_LETTER + case EVENT_TYPE_QUEST_BUTTON_CLOSE: + { + PyCallClassMemberFunc(m_poInterface, "BINARY_ClearQuest", + Py_BuildValue("(i)", atoi(GetArgument("idx", ScriptCommand.argList)))); + break; + } + // END_OF_HIDE_QUEST_LETTER + + case EVENT_TYPE_QUEST_BUTTON: + { + const std::string& c_rstType = GetArgumentString("icon_type", ScriptCommand.argList); + const std::string& c_rstFile = GetArgumentString("icon_name", ScriptCommand.argList); + + int idx = atoi(GetArgument("idx", ScriptCommand.argList)); + const char * name = GetArgument("name", ScriptCommand.argList); + + // Ʈ UI Ǹ ذ ǹǷ ϴ ȥ by chrislee + if (!strcmp(name, " ȥ?....")) { + PyCallClassMemberFunc(m_poInterface, "BINARY_RecvQuest", Py_BuildValue("(isss)", idx, name, "highlight", "")); + } + else { + if (c_rstFile.empty()) + { + PyCallClassMemberFunc(m_poInterface, "RecvQuest", Py_BuildValue("(is)", idx, name)); + } + else + { + PyCallClassMemberFunc(m_poInterface, "BINARY_RecvQuest", + Py_BuildValue("(isss)", idx, name, c_rstType.c_str(), c_rstFile.c_str())); + } + } + break; + } + case EVENT_TYPE_SET_MESSAGE_POSITION: + { + break; + } + case EVENT_TYPE_ADJUST_MESSAGE_POSITION: + { + break; + } + case EVENT_TYPE_SET_CENTER_MAP_POSITION: + { + CPythonMiniMap::Instance().SetAtlasCenterPosition(atoi(GetArgument("x", ScriptCommand.argList)),atoi(GetArgument("y", ScriptCommand.argList))); + break; + } + case EVENT_TYPE_SLEEP: + pEventSet->lLastDelayTime = atoi(GetArgument("value", ScriptCommand.argList)); + break; + case EVENT_TYPE_SET_CAMERA: + { + IAbstractApplication::SCameraSetting CameraSetting; + GetCameraSettingFromArgList(ScriptCommand.argList, &CameraSetting); + rApp.SetEventCamera(CameraSetting); + break; + } + case EVENT_TYPE_BLEND_CAMERA: + { + IAbstractApplication::SCameraSetting CameraSetting; + GetCameraSettingFromArgList(ScriptCommand.argList, &CameraSetting); + + float fBlendTime = atoi(GetArgument("blendtime", ScriptCommand.argList)); + + rApp.BlendEventCamera(CameraSetting, fBlendTime); + break; + } + case EVENT_TYPE_RESTORE_CAMERA: + { + rApp.SetDefaultCamera(); + break; + } + case EVENT_TYPE_FADE_OUT: + { + float fSpeed = (float)atof(GetArgument("speed", ScriptCommand.argList)); + PyCallClassMemberFunc(pEventSet->poEventHandler, "FadeOut", Py_BuildValue("(f)", fSpeed)); + pEventSet->isWaitFlag = true; + break; + } + case EVENT_TYPE_FADE_IN: + { + PyCallClassMemberFunc(pEventSet->poEventHandler, "FadeIn", Py_BuildValue("(f)", atof(GetArgument("speed", ScriptCommand.argList)))); + pEventSet->isWaitFlag = true; + break; + } + case EVENT_TYPE_WHITE_OUT: + { + PyCallClassMemberFunc(pEventSet->poEventHandler, "WhiteOut", Py_BuildValue("(f)", atof(GetArgument("speed", ScriptCommand.argList)))); + pEventSet->isWaitFlag = true; + break; + } + case EVENT_TYPE_WHITE_IN: + { + PyCallClassMemberFunc(pEventSet->poEventHandler, "WhiteIn", Py_BuildValue("(f)", atof(GetArgument("speed", ScriptCommand.argList)))); + pEventSet->isWaitFlag = true; + break; + } + case EVENT_TYPE_CLEAR_TEXT: + { + ClearLine(pEventSet); + break; + } + case EVENT_TYPE_TEXT_HORIZONTAL_ALIGN_CENTER: + { + pEventSet->isTextCenterMode = true; + if (pEventSet->pCurrentTextLine) + pEventSet->pCurrentTextLine->SetHorizonalAlign(CGraphicTextInstance::HORIZONTAL_ALIGN_CENTER); + break; + } + case EVENT_TYPE_TITLE_IMAGE: + { + PyCallClassMemberFunc(pEventSet->poEventHandler, "OnTitleImage", Py_BuildValue("(s)", GetArgument("src", ScriptCommand.argList))); + break; + } + case EVENT_TYPE_DUNGEON_RESULT: + { + int killstone_count = atoi(GetArgument("killstone_count", ScriptCommand.argList)); + int killmob_count = atoi(GetArgument("killmob_count", ScriptCommand.argList)); + int find_hidden = atoi(GetArgument("find_hidden", ScriptCommand.argList)); + int hidden_total = atoi(GetArgument("hidden_total", ScriptCommand.argList)); + int use_potion = atoi(GetArgument("use_potion", ScriptCommand.argList)); + int is_revived = atoi(GetArgument("is_revived", ScriptCommand.argList)); + int killallmob = atoi(GetArgument("killallmob", ScriptCommand.argList)); + int total_time = atoi(GetArgument("total_time", ScriptCommand.argList)); + int bonus_exp = atoi(GetArgument("bonus_exp", ScriptCommand.argList)); + + PyCallClassMemberFunc(m_poInterface, "ShowDungeonResult", + Py_BuildValue("(iiiiiiiii)", + killstone_count, + killmob_count, + find_hidden, + hidden_total, + use_potion, + is_revived, + killallmob, + total_time, + bonus_exp)); + break; + } + case EVENT_TYPE_ITEM_NAME: + { + int iIndex = atoi(GetArgument("value", ScriptCommand.argList)); + CItemData * pItemData; + if (CItemManager::Instance().GetItemDataPointer(iIndex, &pItemData)) + { + pEventSet->strCurrentLine.append(pItemData->GetName()); + pEventSet->pCurrentTextLine->SetValue(pEventSet->strCurrentLine.c_str()); + pEventSet->pCurrentTextLine->SetColor(1.0f, 0.2f, 0.2f); + pEventSet->iCurrentLetter+= strlen(pItemData->GetName()); + + if (pEventSet->iCurrentLetter >= pEventSet->iRestrictedCharacterCount) + __InsertLine(*pEventSet); + + pEventSet->lLastDelayTime = pEventSet->lWaitingTime; + } + + break; + } + case EVENT_TYPE_MONSTER_NAME: + { + int iIndex = atoi(GetArgument("value", ScriptCommand.argList)); + const char * c_szName; + + CPythonNonPlayer& rkNonPlayer=CPythonNonPlayer::Instance(); + if (rkNonPlayer.GetName(iIndex, &c_szName)) + { + pEventSet->strCurrentLine.append(c_szName); + pEventSet->pCurrentTextLine->SetValue(pEventSet->strCurrentLine.c_str()); + pEventSet->iCurrentLetter+= strlen(c_szName); + + if (pEventSet->iCurrentLetter >= pEventSet->iRestrictedCharacterCount) + __InsertLine(*pEventSet); + + pEventSet->lLastDelayTime = pEventSet->lWaitingTime; + } + + break; + } + case EVENT_TYPE_WINDOW_SIZE: + { + int iWidth = atoi(GetArgument("width", ScriptCommand.argList)); + int iHeight = atoi(GetArgument("height", ScriptCommand.argList)); + PyCallClassMemberFunc(pEventSet->poEventHandler, "OnSize", Py_BuildValue("(ii)", iWidth, iHeight)); + break; + } + case EVENT_TYPE_INPUT: + { + __InsertLine(*pEventSet); + PyCallClassMemberFunc(pEventSet->poEventHandler, "OnInput", Py_BuildValue("()")); + break; + } + case EVENT_TYPE_CONFIRM_WAIT: + { + int iTimeOut = atoi(GetArgument("timeout", ScriptCommand.argList)); + pEventSet->isConfirmWait = TRUE; + pEventSet->pConfirmTimeTextLine = pEventSet->pCurrentTextLine; + pEventSet->iConfirmEndTime = timeGetTime()/1000 + iTimeOut; + __InsertLine(*pEventSet, TRUE); + MakeNextButton(pEventSet, BUTTON_TYPE_CANCEL); + break; + } + case EVENT_TYPE_END_CONFIRM_WAIT: + { + for (DWORD i = 0; i < m_EventSetVector.size(); ++i) + { + if (NULL == m_EventSetVector[i]) + continue; + + TEventSet * pSet = m_EventSetVector[i]; + if (!pSet->isConfirmWait) + continue; + + pSet->isConfirmWait = FALSE; + pSet->pConfirmTimeTextLine = NULL; + pSet->iConfirmEndTime = 0; + + PyCallClassMemberFunc(pSet->poEventHandler, "CloseSelf", Py_BuildValue("()")); + } + break; + } + case EVENT_TYPE_SELECT_ITEM: + { + PyCallClassMemberFunc(m_poInterface, "BINARY_OpenSelectItemWindow", Py_BuildValue("()")); + break; + } + } +} + +void CPythonEventManager::RenderEventSet(int iIndex) +{ + if (!CheckEventSetIndex(iIndex)) + return; + + TEventSet * pEventSet = m_EventSetVector[iIndex]; + if (!pEventSet) + return; + + int iCount = 0; + + for (TScriptTextLineList::iterator itor = pEventSet->ScriptTextLineList.begin(); itor != pEventSet->ScriptTextLineList.end(); ++itor, ++iCount) + { + if (iCount < pEventSet->iVisibleStartLine) + continue; + + if (iCount >= pEventSet->iVisibleStartLine + pEventSet->iVisibleLineCount) + continue; + + TTextLine & rkLine = *itor; + CGraphicTextInstance * pInstance = rkLine.pInstance; + + pInstance->Update(); + pInstance->Render(); + } + + if (iCount >= pEventSet->iVisibleStartLine) + if (iCount < pEventSet->iVisibleStartLine + pEventSet->iVisibleLineCount) + { + pEventSet->pCurrentTextLine->Update(); + pEventSet->pCurrentTextLine->Render(); + } +} + +void CPythonEventManager::Skip(int iIndex) +{ + if (!CheckEventSetIndex(iIndex)) + return; + + TEventSet * pEventSet = m_EventSetVector[iIndex]; + + if (true == pEventSet->isLock) + { + pEventSet->lLastDelayTime = 0; + pEventSet->isLock = false; + } + else + { + pEventSet->lLastDelayTime = -1000; + } +} + +bool CPythonEventManager::IsWait(int iIndex) +{ + if (!CheckEventSetIndex(iIndex)) + return false; + + TEventSet * pEventSet = m_EventSetVector[iIndex]; + if (!pEventSet) + { + return false; + } + + return pEventSet->isLock; +} + +void CPythonEventManager::EndEventProcess(int iIndex) +{ + if (!CheckEventSetIndex(iIndex)) + return; + + TEventSet * pEventSet = m_EventSetVector[iIndex]; + if (!pEventSet) + { + return; + } + + pEventSet->isWaitFlag = false; +} + +void CPythonEventManager::MakeNextButton(TEventSet * pEventSet, int iButtonType) +{ + __AddSpace(*pEventSet, c_fLine_Temp+5); + PyCallClassMemberFunc(pEventSet->poEventHandler, "MakeNextButton", Py_BuildValue("(i)", iButtonType)); +} + +void CPythonEventManager::MakeQuestion(TEventSet * pEventSet, script::TArgList & rArgumentList) +{ + if (rArgumentList.empty()) + return; + + PyCallClassMemberFunc(pEventSet->poEventHandler, "MakeQuestion", Py_BuildValue("(i)", rArgumentList.size())); + pEventSet->nAnswer = rArgumentList.size(); + + int iIndex = 0; + for (script::TArgList::iterator itor=rArgumentList.begin(); itor!=rArgumentList.end(); ++itor) + { + script::TArg & rArgument = *itor; + PyCallClassMemberFunc(pEventSet->poEventHandler, "AppendQuestion", Py_BuildValue("(si)", rArgument.strValue.c_str(), iIndex)); + ++iIndex; + } +} + + +void CPythonEventManager::SelectAnswer(int iIndex, int iAnswer) +{ + if (!CheckEventSetIndex(iIndex)) + return; + + //TEventSet * pEventSet = m_EventSetVector[iIndex]; + + CPythonNetworkStream::Instance().SendScriptAnswerPacket(iAnswer); +} + +void CPythonEventManager::SetVisibleStartLine(int iIndex, int iStartLine) +{ + if (!CheckEventSetIndex(iIndex)) + return; + + TEventSet * pEventSet = m_EventSetVector[iIndex]; + + if (DWORD(iStartLine) > pEventSet->ScriptTextLineList.size()) + return; + + pEventSet->iVisibleStartLine = iStartLine; +} + +void CPythonEventManager::SetVisibleLineCount(int iIndex, int iLineCount) +{ + if (!CheckEventSetIndex(iIndex)) + return; + + TEventSet * pEventSet = m_EventSetVector[iIndex]; + + pEventSet->iVisibleLineCount = iLineCount; +} + +int CPythonEventManager::GetVisibleStartLine(int iIndex) +{ + if (!CheckEventSetIndex(iIndex)) + return 0; + + TEventSet * pEventSet = m_EventSetVector[iIndex]; + return pEventSet->iVisibleStartLine; +} + +int CPythonEventManager::GetLineCount(int iIndex) +{ + if (!CheckEventSetIndex(iIndex)) + return 0; + + TEventSet * pEventSet = m_EventSetVector[iIndex]; + return pEventSet->ScriptTextLineList.size()+pEventSet->iAdjustLine; +} + +void CPythonEventManager::ClearLine(TEventSet * pEventSet) +{ + if (!pEventSet) + return; + + for (TScriptTextLineList::iterator itor = pEventSet->ScriptTextLineList.begin(); itor != pEventSet->ScriptTextLineList.end(); ++itor) + { + TTextLine & rkLine = *itor; + CGraphicTextInstance * pInstance = rkLine.pInstance; + pInstance->Destroy(); + pInstance->Update(); + } + + pEventSet->pCurrentTextLine->Destroy(); + pEventSet->pCurrentTextLine->Update(); + + // clear + pEventSet->pCurrentTextLine = NULL; + pEventSet->ScriptTextLineList.clear(); + + __InsertLine(*pEventSet); +} + +void CPythonEventManager::__InsertLine(TEventSet& rEventSet, BOOL isCenter, int iX_pos) +{ + if (rEventSet.pCurrentTextLine) + { + TTextLine kLine; + if (CGraphicTextInstance::HORIZONTAL_ALIGN_CENTER == rEventSet.pCurrentTextLine->GetHorizontalAlign()) + { + kLine.ixLocal = rEventSet.iWidth/2; + kLine.iyLocal = rEventSet.iyLocal; + + } + else + { + int textWidth; + int textHeight; + rEventSet.pCurrentTextLine->GetTextSize(&textWidth,&textHeight); + if (GetDefaultCodePage() == CP_1256) + { + kLine.ixLocal = rEventSet.iWidth; + if (iX_pos != 0) + { + kLine.ixLocal -= iX_pos - 20; + kLine.ixLocal += textWidth / 2; + } + } + else + { + kLine.ixLocal = 0; + if (iX_pos != 0) + { + kLine.ixLocal += (iX_pos - 20); + kLine.ixLocal -= textWidth / 2; + } + } + + kLine.iyLocal = rEventSet.iyLocal; + } + kLine.pInstance = rEventSet.pCurrentTextLine; + rEventSet.ScriptTextLineList.push_back(kLine); + __AddSpace(rEventSet, c_fLine_Temp); + } + + // DEFAULT_FONT + //CGraphicText * pText = (CGraphicText*)CResourceManager::Instance().GetTypeResourcePointer(g_strDefaultFontName.c_str()); + CGraphicText* pkDefaultFont = static_cast(DefaultFont_GetResource()); + if (!pkDefaultFont) + { + TraceError("CPythonEventManager::InsertLine - CANNOT_FIND_DEFAULT_FONT"); + return; + } + + rEventSet.pCurrentTextLine = m_ScriptTextLinePool.Alloc(); + if (!rEventSet.pCurrentTextLine) + { + TraceError("CPythonEventManager::InsertLine - OUT_OF_TEXT_LINE"); + return; + } + + rEventSet.pCurrentTextLine->SetTextPointer(pkDefaultFont); + // END_OF_DEFAULT_FONT + + rEventSet.pCurrentTextLine->SetColor(1.0f, 1.0f, 1.0f); + rEventSet.pCurrentTextLine->SetValue(""); + + if (rEventSet.isTextCenterMode || isCenter) + { + rEventSet.pCurrentTextLine->SetHorizonalAlign(CGraphicTextInstance::HORIZONTAL_ALIGN_CENTER); + rEventSet.pCurrentTextLine->SetPosition(rEventSet.ix+rEventSet.iWidth/2, rEventSet.iy + rEventSet.iyLocal); + } + else + { + if (GetDefaultCodePage() == CP_1256) + { + rEventSet.pCurrentTextLine->SetHorizonalAlign(CGraphicTextInstance::HORIZONTAL_ALIGN_LEFT); + rEventSet.pCurrentTextLine->SetPosition(rEventSet.ix + rEventSet.iWidth, rEventSet.iy + rEventSet.iyLocal); + } + else + { + rEventSet.pCurrentTextLine->SetHorizonalAlign(CGraphicTextInstance::HORIZONTAL_ALIGN_LEFT); + rEventSet.pCurrentTextLine->SetPosition(rEventSet.ix, rEventSet.iy + rEventSet.iyLocal); + } + } + + rEventSet.iCurrentLetter = 0; + rEventSet.strCurrentLine = ""; +} + +void CPythonEventManager::RefreshLinePosition(TEventSet * pEventSet) +{ + //int iCount = 0; + for (TScriptTextLineList::iterator itor = pEventSet->ScriptTextLineList.begin(); itor != pEventSet->ScriptTextLineList.end(); ++itor) + { + TTextLine & rkLine = *itor; + CGraphicTextInstance * pInstance = rkLine.pInstance; + pInstance->SetPosition(pEventSet->ix + rkLine.ixLocal, pEventSet->iy + rkLine.iyLocal); + } + + int ixTextPos; + if (CGraphicTextInstance::HORIZONTAL_ALIGN_CENTER == pEventSet->pCurrentTextLine->GetHorizontalAlign()) + { + ixTextPos = pEventSet->ix+pEventSet->iWidth/2; + } + else + { + if (GetDefaultCodePage() == CP_1256) + ixTextPos = pEventSet->ix+pEventSet->iWidth; + else + ixTextPos = pEventSet->ix; + } + pEventSet->pCurrentTextLine->SetPosition(ixTextPos, pEventSet->iy + pEventSet->iyLocal); +} + +void CPythonEventManager::__AddSpace(TEventSet& rEventSet, int iSpace) +{ + rEventSet.iyLocal += iSpace; +} + +bool CPythonEventManager::GetScriptEventIndex(const char * c_szName, int * pEventPosition, int * pEventType) +{ + const char * c_szEventName; + + if ('/' == c_szName[0]) + { + *pEventPosition = EVENT_POSITION_END; + c_szEventName = &c_szName[1]; + } + else + { + *pEventPosition = EVENT_POSITION_START; + c_szEventName = &c_szName[0]; + } + + std::map::iterator it = EventTypeMap.find(c_szEventName); + if (it == EventTypeMap.end()) + { + Tracef(" !! PARSING ERROR - Strange Command : %s\n", c_szEventName); + return false; + } + + *pEventType = it->second; + + return true; +} + +bool CPythonEventManager::CheckEventSetIndex(int iIndex) +{ + if (iIndex < 0) + return false; + + if ((DWORD) iIndex >= m_EventSetVector.size()) + return false; + + return true; +} + +void CPythonEventManager::Destroy() +{ + m_EventSetVector.clear(); + m_EventSetPool.Clear(); + m_ScriptTextLinePool.Clear(); +} + +void CPythonEventManager::SetInterfaceWindow(PyObject * poInterface) +{ + m_poInterface = poInterface; +} + +void CPythonEventManager::SetLeftTimeString(const char * c_szString) +{ + m_strLeftTimeString = c_szString; +} + +CPythonEventManager::CPythonEventManager() + : m_poInterface(0), m_strLeftTimeString(" ð : %d") +{ + EventTypeMap["LETTER"]=EVENT_TYPE_LETTER; + EventTypeMap["COLOR"]=EVENT_TYPE_COLOR; + EventTypeMap["DELAY"]=EVENT_TYPE_DELAY; + EventTypeMap["ENTER"]=EVENT_TYPE_ENTER; + EventTypeMap["WAIT"]=EVENT_TYPE_WAIT; + EventTypeMap["CLEAR"]=EVENT_TYPE_CLEAR; + EventTypeMap["QUESTION"]=EVENT_TYPE_QUESTION; + EventTypeMap["NEXT"]=EVENT_TYPE_NEXT; + EventTypeMap["DONE"]=EVENT_TYPE_DONE; + + EventTypeMap["LEFTIMAGE"]=EVENT_TYPE_LEFT_IMAGE; + EventTypeMap["TOPIMAGE"]=EVENT_TYPE_TOP_IMAGE; + EventTypeMap["BGIMAGE"]=EVENT_TYPE_BACKGROUND_IMAGE; + EventTypeMap["IMAGE"]=EVENT_TYPE_IMAGE; + + EventTypeMap["ADDMAPSIGNAL"]=EVENT_TYPE_ADD_MAP_SIGNAL; + EventTypeMap["CLEARMAPSIGNAL"]=EVENT_TYPE_CLEAR_MAP_SIGNAL; + + EventTypeMap["SETMSGPOS"]=EVENT_TYPE_SET_MESSAGE_POSITION; + EventTypeMap["ADJMSGPOS"]=EVENT_TYPE_ADJUST_MESSAGE_POSITION; + EventTypeMap["SETCMAPPOS"]=EVENT_TYPE_SET_CENTER_MAP_POSITION; + + EventTypeMap["QUESTBUTTON"]=EVENT_TYPE_QUEST_BUTTON; + + // HIDE_QUEST_LETTER + EventTypeMap["QUESTBUTTON_CLOSE"]=EVENT_TYPE_QUEST_BUTTON_CLOSE; + // END_OF_HIDE_QUEST_LETTER + + EventTypeMap["SLEEP"]=EVENT_TYPE_SLEEP; + EventTypeMap["SET_CAMERA"]=EVENT_TYPE_SET_CAMERA; + EventTypeMap["BLEND_CAMERA"]=EVENT_TYPE_BLEND_CAMERA; + EventTypeMap["RESTORE_CAMERA"]=EVENT_TYPE_RESTORE_CAMERA; + EventTypeMap["FADE_OUT"]=EVENT_TYPE_FADE_OUT; + EventTypeMap["FADE_IN"]=EVENT_TYPE_FADE_IN; + EventTypeMap["WHITE_OUT"]=EVENT_TYPE_WHITE_OUT; + EventTypeMap["WHITE_IN"]=EVENT_TYPE_WHITE_IN; + EventTypeMap["CLEAR_TEXT"]=EVENT_TYPE_CLEAR_TEXT; + EventTypeMap["TEXT_HORIZONTAL_ALIGN_CENTER"]=EVENT_TYPE_TEXT_HORIZONTAL_ALIGN_CENTER; + EventTypeMap["TITLE_IMAGE"]=EVENT_TYPE_TITLE_IMAGE; + + EventTypeMap["RUN_CINEMA"]=EVENT_TYPE_RUN_CINEMA; + EventTypeMap["DUNGEON_RESULT"]=EVENT_TYPE_DUNGEON_RESULT; + + EventTypeMap["ITEM"]=EVENT_TYPE_ITEM_NAME; + EventTypeMap["MOB"]=EVENT_TYPE_MONSTER_NAME; + + EventTypeMap["COLOR256"]=EVENT_TYPE_COLOR256; + EventTypeMap["WINDOW_SIZE"]=EVENT_TYPE_WINDOW_SIZE; + + EventTypeMap["INPUT"]=EVENT_TYPE_INPUT; + EventTypeMap["CONFIRM_WAIT"]=EVENT_TYPE_CONFIRM_WAIT; + EventTypeMap["END_CONFIRM_WAIT"]=EVENT_TYPE_END_CONFIRM_WAIT; + + EventTypeMap["INSERT_IMAGE"]=EVENT_TYPE_INSERT_IMAGE; + + EventTypeMap["SELECT_ITEM"]=EVENT_TYPE_SELECT_ITEM; +} + +CPythonEventManager::~CPythonEventManager() +{ +} diff --git a/source/UserInterface/PythonEventManager.h b/source/UserInterface/PythonEventManager.h new file mode 100644 index 0000000..86ba7a4 --- /dev/null +++ b/source/UserInterface/PythonEventManager.h @@ -0,0 +1,212 @@ +#pragma once + +#include "../eterLib/parser.h" + +#include +#include + +class CPythonEventManager : public CSingleton +{ + public: + typedef struct STextLine + { + int ixLocal, iyLocal; + CGraphicTextInstance * pInstance; + } TTextLine; + + typedef std::list TScriptTextLineList; + typedef std::map TEventAnswerMap; + + enum + { + EVENT_POSITION_START = 0, + EVENT_POSITION_END = 1, + + BOX_VISIBLE_LINE_COUNT = 5, + }; + + enum EButtonType + { + BUTTON_TYPE_NEXT, + BUTTON_TYPE_DONE, + BUTTON_TYPE_CANCEL, + }; + + enum EEventType + { + EVENT_TYPE_LETTER, + EVENT_TYPE_COLOR, + EVENT_TYPE_DELAY, + EVENT_TYPE_ENTER, + EVENT_TYPE_WAIT, + EVENT_TYPE_CLEAR, + EVENT_TYPE_QUESTION, + EVENT_TYPE_NEXT, + EVENT_TYPE_DONE, + + EVENT_TYPE_LEFT_IMAGE, + EVENT_TYPE_TOP_IMAGE, + EVENT_TYPE_BACKGROUND_IMAGE, + EVENT_TYPE_IMAGE, + + EVENT_TYPE_ADD_MAP_SIGNAL, + EVENT_TYPE_CLEAR_MAP_SIGNAL, + EVENT_TYPE_SET_MESSAGE_POSITION, + EVENT_TYPE_ADJUST_MESSAGE_POSITION, + EVENT_TYPE_SET_CENTER_MAP_POSITION, + + EVENT_TYPE_QUEST_BUTTON, + + // HIDE_QUEST_LETTER + EVENT_TYPE_QUEST_BUTTON_CLOSE, + // END_OF_HIDE_QUEST_LETTER + + EVENT_TYPE_SLEEP, + EVENT_TYPE_SET_CAMERA, + EVENT_TYPE_BLEND_CAMERA, + EVENT_TYPE_RESTORE_CAMERA, + EVENT_TYPE_FADE_OUT, + EVENT_TYPE_FADE_IN, + EVENT_TYPE_WHITE_OUT, + EVENT_TYPE_WHITE_IN, + EVENT_TYPE_CLEAR_TEXT, + EVENT_TYPE_TEXT_HORIZONTAL_ALIGN_CENTER, + EVENT_TYPE_TITLE_IMAGE, + + EVENT_TYPE_RUN_CINEMA, + EVENT_TYPE_DUNGEON_RESULT, + + EVENT_TYPE_ITEM_NAME, + EVENT_TYPE_MONSTER_NAME, + + EVENT_TYPE_COLOR256, + EVENT_TYPE_WINDOW_SIZE, + + EVENT_TYPE_INPUT, + EVENT_TYPE_CONFIRM_WAIT, + EVENT_TYPE_END_CONFIRM_WAIT, + + EVENT_TYPE_INSERT_IMAGE, + + EVENT_TYPE_SELECT_ITEM, + }; + + private: + std::map EventTypeMap; + + public: + typedef struct SEventSet + { + int ix, iy; + int iWidth; + int iyLocal; + + // State + bool isLock; + + long lLastDelayTime; + + int iCurrentLetter; + + D3DXCOLOR CurrentColor; + std::string strCurrentLine; + + CGraphicTextInstance * pCurrentTextLine; + TScriptTextLineList ScriptTextLineList; + + BOOL isConfirmWait; + CGraphicTextInstance * pConfirmTimeTextLine; + int iConfirmEndTime; + + // Group Data + script::Group ScriptGroup; + + // Static Data + char szFileName[32+1]; + + int iVisibleStartLine; + int iVisibleLineCount; + + int iAdjustLine; + + D3DXCOLOR DiffuseColor; + long lWaitingTime; + int iRestrictedCharacterCount; + + int nAnswer; + + bool isTextCenterMode; + bool isWaitFlag; + + PyObject * poEventHandler; + + SEventSet() {} + virtual ~SEventSet() {} + } TEventSet; + + typedef std::vector TEventSetVector; + + + public: + CPythonEventManager(); + virtual ~CPythonEventManager(); + + void Destroy(); + + int RegisterEventSet(const char * c_szFileName); + int RegisterEventSetFromString(const std::string& strScript); + void ClearEventSeti(int iIndex); + void __ClearEventSetp(TEventSet * pEventSet); + + void SetEventHandler(int iIndex, PyObject * poEventHandler); + void SetRestrictedCount(int iIndex, int iCount); + + int GetEventSetLocalYPosition(int iIndex); + void AddEventSetLocalYPosition(int iIndex, int iAddValue); + void InsertText(int iIndex, const char * c_szText, int iX_pos = 0); + + void UpdateEventSet(int iIndex, int ix, int iy); + void RenderEventSet(int iIndex); + void SetEventSetWidth(int iIndex, int iWidth); + + void Skip(int iIndex); + bool IsWait(int iIndex); + void EndEventProcess(int iIndex); + + void SelectAnswer(int iIndex, int iAnswer); + void SetVisibleStartLine(int iIndex, int iStartLine); + int GetVisibleStartLine(int iIndex); + int GetLineCount(int iIndex); + void SetVisibleLineCount(int iIndex, int iLineCount); + + void SetInterfaceWindow(PyObject * poInterface); + void SetLeftTimeString(const char * c_szString); + + protected: + void __InitEventSet(TEventSet& rEventSet); + void __InsertLine(TEventSet& rEventSet, BOOL isCenter=FALSE, int iX_pos=0); + void __AddSpace(TEventSet& pEventSet, int iSpace); + + DWORD GetEmptyEventSetSlot(); + + bool CheckEventSetIndex(int iIndex); + + void ProcessEventSet(TEventSet * pEventSet); + + void ClearLine(TEventSet * pEventSet); + void RefreshLinePosition(TEventSet * pEventSet); + bool GetScriptEventIndex(const char * c_szName, int * pEventPosition, int * pEventType); + + void MakeQuestion(TEventSet * pEventSet, script::TArgList & rArgumentList); + void MakeNextButton(TEventSet * pEventSet, int iButtonType); + + protected: + TEventSetVector m_EventSetVector; + BOOL m_isQuestConfirmWait; + + private: + CDynamicPool m_EventSetPool; + CDynamicPool m_ScriptTextLinePool; + PyObject * m_poInterface; + std::string m_strLeftTimeString; +}; \ No newline at end of file diff --git a/source/UserInterface/PythonEventManagerMoudle.cpp b/source/UserInterface/PythonEventManagerMoudle.cpp new file mode 100644 index 0000000..6d72057 --- /dev/null +++ b/source/UserInterface/PythonEventManagerMoudle.cpp @@ -0,0 +1,315 @@ +#include "StdAfx.h" +#include "PythonEventManager.h" +#include "PythonNetworkStream.h" + +PyObject * eventRegisterEventSet(PyObject * poSelf, PyObject * poArgs) +{ + char * szFileName; + if (!PyTuple_GetString(poArgs, 0, &szFileName)) + return Py_BuildException(); + + int iEventIndex = CPythonEventManager::Instance().RegisterEventSet(szFileName); + return Py_BuildValue("i", iEventIndex); +} + +PyObject * eventRegisterEventSetFromString(PyObject * poSelf, PyObject * poArgs) +{ + char * szEventString; + if (!PyTuple_GetString(poArgs, 0, &szEventString)) + return Py_BuildException(); + + int iEventIndex = CPythonEventManager::Instance().RegisterEventSetFromString(szEventString); + return Py_BuildValue("i", iEventIndex); +} + +PyObject * eventClearEventSet(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + + CPythonEventManager::Instance().ClearEventSeti(iIndex); + return Py_BuildNone(); +} + +PyObject * eventSetRestrictedCount(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + + int iCount; + if (!PyTuple_GetInteger(poArgs, 1, &iCount)) + return Py_BuildException(); + + CPythonEventManager::Instance().SetRestrictedCount(iIndex, iCount); + return Py_BuildNone(); +} + +PyObject * eventGetEventSetLocalYPosition(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + + return Py_BuildValue("i", CPythonEventManager::Instance().GetEventSetLocalYPosition(iIndex)); +} + +PyObject * eventAddEventSetLocalYPosition(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + int iPos; + if (!PyTuple_GetInteger(poArgs, 1, &iPos)) + return Py_BuildException(); + + CPythonEventManager::Instance().AddEventSetLocalYPosition(iIndex, iPos); + return Py_BuildNone(); +} + +PyObject * eventInsertText(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + char * szText; + if (!PyTuple_GetString(poArgs, 1, &szText)) + return Py_BuildException(); + + CPythonEventManager::Instance().InsertText(iIndex, szText); + return Py_BuildNone(); +} + +PyObject * eventInsertTextInline(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + char * szText; + if (!PyTuple_GetString(poArgs, 1, &szText)) + return Py_BuildException(); + int iXIndex; + if (!PyTuple_GetInteger(poArgs, 2, &iXIndex)) + return Py_BuildException(); + + CPythonEventManager::Instance().InsertText(iIndex, szText,iXIndex); + return Py_BuildNone(); +} + +PyObject * eventUpdateEventSet(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + + int ix; + if (!PyTuple_GetInteger(poArgs, 1, &ix)) + return Py_BuildException(); + + int iy; + if (!PyTuple_GetInteger(poArgs, 2, &iy)) + return Py_BuildException(); + + CPythonEventManager::Instance().UpdateEventSet(iIndex, ix, -iy); + return Py_BuildNone(); +} + +PyObject * eventRenderEventSet(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + + CPythonEventManager::Instance().RenderEventSet(iIndex); + return Py_BuildNone(); +} + +PyObject * eventSetEventSetWidth(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + int iWidth; + if (!PyTuple_GetInteger(poArgs, 1, &iWidth)) + return Py_BuildException(); + + CPythonEventManager::Instance().SetEventSetWidth(iIndex, iWidth); + return Py_BuildNone(); +} + +PyObject * eventSkip(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + + CPythonEventManager::Instance().Skip(iIndex); + return Py_BuildNone(); +} + +PyObject * eventIsWait(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + + return Py_BuildValue("i", CPythonEventManager::Instance().IsWait(iIndex) == true ? 1 : 0); +} + +PyObject * eventEndEventProcess(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + + CPythonEventManager::Instance().EndEventProcess(iIndex); + + return Py_BuildNone(); +} + +PyObject * eventSetEventHandler(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + + PyObject * poEventHandler; + if (!PyTuple_GetObject(poArgs, 1, &poEventHandler)) + return Py_BuildException(); + + CPythonEventManager::Instance().SetEventHandler(iIndex, poEventHandler); + return Py_BuildNone(); +} + +PyObject * eventSelectAnswer(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + + int iAnswer; + if (!PyTuple_GetInteger(poArgs, 1, &iAnswer)) + return Py_BuildException(); + + CPythonEventManager::Instance().SelectAnswer(iIndex, iAnswer); + return Py_BuildNone(); +} + +PyObject * eventGetLineCount(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + + int iLineCount = CPythonEventManager::Instance().GetLineCount(iIndex); + return Py_BuildValue("i", iLineCount); +} + +PyObject * eventSetVisibleStartLine(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + + int iStartLine; + if (!PyTuple_GetInteger(poArgs, 1, &iStartLine)) + return Py_BuildException(); + + CPythonEventManager::Instance().SetVisibleStartLine(iIndex, iStartLine); + return Py_BuildNone(); +} + +PyObject * eventGetVisibleStartLine(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + + return Py_BuildValue("i", CPythonEventManager::Instance().GetVisibleStartLine(iIndex)); +} + +PyObject * eventQuestButtonClick(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + + CPythonNetworkStream::Instance().SendScriptButtonPacket(iIndex); + + return Py_BuildNone(); +} + +PyObject * eventSetInterfaceWindow(PyObject* poSelf, PyObject* poArgs) +{ + PyObject * pyHandle; + if (!PyTuple_GetObject(poArgs, 0, &pyHandle)) + return Py_BadArgument(); + + CPythonEventManager & rpem = CPythonEventManager::Instance(); + rpem.SetInterfaceWindow(pyHandle); + return Py_BuildNone(); +} + +PyObject * eventSetLeftTimeString(PyObject* poSelf, PyObject* poArgs) +{ + char * szText; + if (!PyTuple_GetString(poArgs, 0, &szText)) + return Py_BuildException(); + + CPythonEventManager & rpem = CPythonEventManager::Instance(); + rpem.SetLeftTimeString(szText); + return Py_BuildNone(); +} + +PyObject * eventDestroy(PyObject* poSelf, PyObject* poArgs) +{ + CPythonEventManager & rpem = CPythonEventManager::Instance(); + rpem.Destroy(); + return Py_BuildNone(); +} + +void initEvent() +{ + static PyMethodDef s_methods[] = + { + { "RegisterEventSet", eventRegisterEventSet, METH_VARARGS }, + { "RegisterEventSetFromString", eventRegisterEventSetFromString, METH_VARARGS }, + { "ClearEventSet", eventClearEventSet, METH_VARARGS }, + + { "SetRestrictedCount", eventSetRestrictedCount, METH_VARARGS }, + + { "GetEventSetLocalYPosition", eventGetEventSetLocalYPosition, METH_VARARGS }, + { "AddEventSetLocalYPosition", eventAddEventSetLocalYPosition, METH_VARARGS }, + { "InsertText", eventInsertText, METH_VARARGS }, + { "InsertTextInline", eventInsertTextInline, METH_VARARGS }, + + { "UpdateEventSet", eventUpdateEventSet, METH_VARARGS }, + { "RenderEventSet", eventRenderEventSet, METH_VARARGS }, + { "SetEventSetWidth", eventSetEventSetWidth, METH_VARARGS }, + + { "Skip", eventSkip, METH_VARARGS }, + { "IsWait", eventIsWait, METH_VARARGS }, + { "EndEventProcess", eventEndEventProcess, METH_VARARGS }, + + { "SelectAnswer", eventSelectAnswer, METH_VARARGS }, + { "GetLineCount", eventGetLineCount, METH_VARARGS }, + { "SetVisibleStartLine", eventSetVisibleStartLine, METH_VARARGS }, + { "GetVisibleStartLine", eventGetVisibleStartLine, METH_VARARGS }, + + { "SetEventHandler", eventSetEventHandler, METH_VARARGS }, + { "SetInterfaceWindow", eventSetInterfaceWindow, METH_VARARGS }, + { "SetLeftTimeString", eventSetLeftTimeString, METH_VARARGS }, + + { "QuestButtonClick", eventQuestButtonClick, METH_VARARGS }, + { "Destroy", eventDestroy, METH_VARARGS }, + { NULL, NULL, NULL }, + }; + + PyObject * poModule = Py_InitModule("event", s_methods); + + PyModule_AddIntConstant(poModule, "BOX_VISIBLE_LINE_COUNT", CPythonEventManager::BOX_VISIBLE_LINE_COUNT); + PyModule_AddIntConstant(poModule, "BUTTON_TYPE_NEXT", CPythonEventManager::BUTTON_TYPE_NEXT); + PyModule_AddIntConstant(poModule, "BUTTON_TYPE_DONE", CPythonEventManager::BUTTON_TYPE_DONE); + PyModule_AddIntConstant(poModule, "BUTTON_TYPE_CANCEL", CPythonEventManager::BUTTON_TYPE_CANCEL); +} \ No newline at end of file diff --git a/source/UserInterface/PythonExceptionSender.cpp b/source/UserInterface/PythonExceptionSender.cpp new file mode 100644 index 0000000..b5f0f67 --- /dev/null +++ b/source/UserInterface/PythonExceptionSender.cpp @@ -0,0 +1,67 @@ +#include "StdAfx.h" +#include "PythonExceptionSender.h" + +void CPythonExceptionSender::Send() +{ + //DWORD dwCRC32 = GetCaseCRC32(m_strExceptionString.c_str(), m_strExceptionString.length()); + //if (m_kSet_dwSendedExceptionCRC.end() != m_kSet_dwSendedExceptionCRC.find(dwCRC32)) + // return; + + //TraceError("%s", m_strExceptionString.c_str()); + + //SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + + //if (s==INVALID_SOCKET) + //{ + // Tracef(" CPythonExceptionSender::Send() - Invalid Socket"); + //} + + + //DWORD arg = 1; + //ioctlsocket(s, FIONBIO, &arg); // Non-blocking mode + + //char szServerAddr[256]; + //int nServerPort; + //strncpy(szServerAddr, "211.105.222.20", sizeof(szServerAddr)-1); + + //nServerPort=LocaleService_GetPythonErrorReportPort(); + // + //sockaddr_in sa; + //sa.sin_family = AF_INET; + //sa.sin_port = htons(nServerPort); + //sa.sin_addr.s_addr = inet_addr(szServerAddr); + //if (connect(s,(sockaddr*)&sa,sizeof(sa))) + // return; + + //int number_ticket=0; + //if (recv(s,(char*)&number_ticket,4,0)) + // return; + + //int length=m_strExceptionString.length(); + //int total=0; + //int ret=0; + + //int count = 100; + //while(count--) + //{ + // // send plain text + // ret = send(s,(char*)(&m_strExceptionString[0])+total,length-total,0); + // + // if (ret<0) + // break; + + // total+=ret; + // if (total>=length) + // break; + //} + //closesocket(s); + + //m_kSet_dwSendedExceptionCRC.insert(dwCRC32); +} + +CPythonExceptionSender::CPythonExceptionSender() +{ +} +CPythonExceptionSender::~CPythonExceptionSender() +{ +} diff --git a/source/UserInterface/PythonExceptionSender.h b/source/UserInterface/PythonExceptionSender.h new file mode 100644 index 0000000..0aa331e --- /dev/null +++ b/source/UserInterface/PythonExceptionSender.h @@ -0,0 +1,13 @@ +#pragma once + +class CPythonExceptionSender : public IPythonExceptionSender +{ + public: + CPythonExceptionSender(); + virtual ~CPythonExceptionSender(); + + void Send(); + + protected: + std::set m_kSet_dwSendedExceptionCRC; +}; diff --git a/source/UserInterface/PythonExchange.cpp b/source/UserInterface/PythonExchange.cpp new file mode 100644 index 0000000..4d21dcc --- /dev/null +++ b/source/UserInterface/PythonExchange.cpp @@ -0,0 +1,248 @@ +#include "stdafx.h" +#include "PythonExchange.h" + +void CPythonExchange::SetSelfName(const char *name) +{ + strncpy(m_self.name, name, CHARACTER_NAME_MAX_LEN); +} + +void CPythonExchange::SetTargetName(const char *name) +{ + strncpy(m_victim.name, name, CHARACTER_NAME_MAX_LEN); +} + +char * CPythonExchange::GetNameFromSelf() +{ + return m_self.name; +} + +char * CPythonExchange::GetNameFromTarget() +{ + return m_victim.name; +} + +void CPythonExchange::SetElkToTarget(DWORD elk) +{ + m_victim.elk = elk; +} + +void CPythonExchange::SetElkToSelf(DWORD elk) +{ + m_self.elk = elk; +} + +DWORD CPythonExchange::GetElkFromTarget() +{ + return m_victim.elk; +} + +DWORD CPythonExchange::GetElkFromSelf() +{ + return m_self.elk; +} + +void CPythonExchange::SetItemToTarget(DWORD pos, DWORD vnum, BYTE count) +{ + if (pos >= EXCHANGE_ITEM_MAX_NUM) + return; + + m_victim.item_vnum[pos] = vnum; + m_victim.item_count[pos] = count; +} + +void CPythonExchange::SetItemToSelf(DWORD pos, DWORD vnum, BYTE count) +{ + if (pos >= EXCHANGE_ITEM_MAX_NUM) + return; + + m_self.item_vnum[pos] = vnum; + m_self.item_count[pos] = count; +} + +void CPythonExchange::SetItemMetinSocketToTarget(int pos, int imetinpos, DWORD vnum) +{ + if (pos >= EXCHANGE_ITEM_MAX_NUM) + return; + + m_victim.item_metin[pos][imetinpos] = vnum; +} + +void CPythonExchange::SetItemMetinSocketToSelf(int pos, int imetinpos, DWORD vnum) +{ + if (pos >= EXCHANGE_ITEM_MAX_NUM) + return; + + m_self.item_metin[pos][imetinpos] = vnum; +} + +void CPythonExchange::SetItemAttributeToTarget(int pos, int iattrpos, BYTE byType, short sValue) +{ + if (pos >= EXCHANGE_ITEM_MAX_NUM) + return; + + m_victim.item_attr[pos][iattrpos].bType = byType; + m_victim.item_attr[pos][iattrpos].sValue = sValue; +} + +void CPythonExchange::SetItemAttributeToSelf(int pos, int iattrpos, BYTE byType, short sValue) +{ + if (pos >= EXCHANGE_ITEM_MAX_NUM) + return; + + m_self.item_attr[pos][iattrpos].bType = byType; + m_self.item_attr[pos][iattrpos].sValue = sValue; +} + +void CPythonExchange::DelItemOfTarget(BYTE pos) +{ + if (pos >= EXCHANGE_ITEM_MAX_NUM) + return; + + m_victim.item_vnum[pos] = 0; + m_victim.item_count[pos] = 0; +} + +void CPythonExchange::DelItemOfSelf(BYTE pos) +{ + if (pos >= EXCHANGE_ITEM_MAX_NUM) + return; + + m_self.item_vnum[pos] = 0; + m_self.item_count[pos] = 0; +} + +DWORD CPythonExchange::GetItemVnumFromTarget(BYTE pos) +{ + if (pos >= EXCHANGE_ITEM_MAX_NUM) + return 0; + + return m_victim.item_vnum[pos]; +} + +DWORD CPythonExchange::GetItemVnumFromSelf(BYTE pos) +{ + if (pos >= EXCHANGE_ITEM_MAX_NUM) + return 0; + + return m_self.item_vnum[pos]; +} + +BYTE CPythonExchange::GetItemCountFromTarget(BYTE pos) +{ + if (pos >= EXCHANGE_ITEM_MAX_NUM) + return 0; + + return m_victim.item_count[pos]; +} + +BYTE CPythonExchange::GetItemCountFromSelf(BYTE pos) +{ + if (pos >= EXCHANGE_ITEM_MAX_NUM) + return 0; + + return m_self.item_count[pos]; +} + +DWORD CPythonExchange::GetItemMetinSocketFromTarget(BYTE pos, int iMetinSocketPos) +{ + if (pos >= EXCHANGE_ITEM_MAX_NUM) + return 0; + + return m_victim.item_metin[pos][iMetinSocketPos]; +} + +DWORD CPythonExchange::GetItemMetinSocketFromSelf(BYTE pos, int iMetinSocketPos) +{ + if (pos >= EXCHANGE_ITEM_MAX_NUM) + return 0; + + return m_self.item_metin[pos][iMetinSocketPos]; +} + +void CPythonExchange::GetItemAttributeFromTarget(BYTE pos, int iAttrPos, BYTE * pbyType, short * psValue) +{ + if (pos >= EXCHANGE_ITEM_MAX_NUM) + return; + + *pbyType = m_victim.item_attr[pos][iAttrPos].bType; + *psValue = m_victim.item_attr[pos][iAttrPos].sValue; +} + +void CPythonExchange::GetItemAttributeFromSelf(BYTE pos, int iAttrPos, BYTE * pbyType, short * psValue) +{ + if (pos >= EXCHANGE_ITEM_MAX_NUM) + return; + + *pbyType = m_self.item_attr[pos][iAttrPos].bType; + *psValue = m_self.item_attr[pos][iAttrPos].sValue; +} + +void CPythonExchange::SetAcceptToTarget(BYTE Accept) +{ + m_victim.accept = Accept ? true : false; +} + +void CPythonExchange::SetAcceptToSelf(BYTE Accept) +{ + m_self.accept = Accept ? true : false; +} + +bool CPythonExchange::GetAcceptFromTarget() +{ + return m_victim.accept ? true : false; +} + +bool CPythonExchange::GetAcceptFromSelf() +{ + return m_self.accept ? true : false; +} + +bool CPythonExchange::GetElkMode() +{ + return m_elk_mode; +} + +void CPythonExchange::SetElkMode(bool value) +{ + m_elk_mode = value; +} + +void CPythonExchange::Start() +{ + m_isTrading = true; +} + +void CPythonExchange::End() +{ + m_isTrading = false; +} + +bool CPythonExchange::isTrading() +{ + return m_isTrading; +} + +void CPythonExchange::Clear() +{ + memset(&m_self, 0, sizeof(m_self)); + memset(&m_victim, 0, sizeof(m_victim)); +/* + m_self.item_vnum[0] = 30; + m_victim.item_vnum[0] = 30; + m_victim.item_vnum[1] = 40; + m_victim.item_vnum[2] = 50; +*/ +} + +CPythonExchange::CPythonExchange() +{ + Clear(); + m_isTrading = false; + m_elk_mode = false; + // Clear Ȱܳ ȵ. + // trade_start Ŷ Clear ϴµ + // m_elk_mode Ŭ Ǽ ȵ.; +} +CPythonExchange::~CPythonExchange() +{ +} \ No newline at end of file diff --git a/source/UserInterface/PythonExchange.h b/source/UserInterface/PythonExchange.h new file mode 100644 index 0000000..3e34ba3 --- /dev/null +++ b/source/UserInterface/PythonExchange.h @@ -0,0 +1,92 @@ +#pragma once + +#include "Packet.h" + +/* + * ȯ â + */ +class CPythonExchange : public CSingleton +{ + public: + enum + { + EXCHANGE_ITEM_MAX_NUM = 12, + }; + + typedef struct trade + { + char name[CHARACTER_NAME_MAX_LEN + 1]; + + DWORD item_vnum[EXCHANGE_ITEM_MAX_NUM]; + BYTE item_count[EXCHANGE_ITEM_MAX_NUM]; + DWORD item_metin[EXCHANGE_ITEM_MAX_NUM][ITEM_SOCKET_SLOT_MAX_NUM]; + TPlayerItemAttribute item_attr[EXCHANGE_ITEM_MAX_NUM][ITEM_ATTRIBUTE_SLOT_MAX_NUM]; + + BYTE accept; + DWORD elk; + } TExchangeData; + + public: + CPythonExchange(); + virtual ~CPythonExchange(); + + void Clear(); + + void Start(); + void End(); + bool isTrading(); + + // Interface + + void SetSelfName(const char *name); + void SetTargetName(const char *name); + + char *GetNameFromSelf(); + char *GetNameFromTarget(); + + void SetElkToTarget(DWORD elk); + void SetElkToSelf(DWORD elk); + + DWORD GetElkFromTarget(); + DWORD GetElkFromSelf(); + + void SetItemToTarget(DWORD pos, DWORD vnum, BYTE count); + void SetItemToSelf(DWORD pos, DWORD vnum, BYTE count); + + void SetItemMetinSocketToTarget(int pos, int imetinpos, DWORD vnum); + void SetItemMetinSocketToSelf(int pos, int imetinpos, DWORD vnum); + + void SetItemAttributeToTarget(int pos, int iattrpos, BYTE byType, short sValue); + void SetItemAttributeToSelf(int pos, int iattrpos, BYTE byType, short sValue); + + void DelItemOfTarget(BYTE pos); + void DelItemOfSelf(BYTE pos); + + DWORD GetItemVnumFromTarget(BYTE pos); + DWORD GetItemVnumFromSelf(BYTE pos); + + BYTE GetItemCountFromTarget(BYTE pos); + BYTE GetItemCountFromSelf(BYTE pos); + + DWORD GetItemMetinSocketFromTarget(BYTE pos, int iMetinSocketPos); + DWORD GetItemMetinSocketFromSelf(BYTE pos, int iMetinSocketPos); + + void GetItemAttributeFromTarget(BYTE pos, int iAttrPos, BYTE * pbyType, short * psValue); + void GetItemAttributeFromSelf(BYTE pos, int iAttrPos, BYTE * pbyType, short * psValue); + + void SetAcceptToTarget(BYTE Accept); + void SetAcceptToSelf(BYTE Accept); + + bool GetAcceptFromTarget(); + bool GetAcceptFromSelf(); + + bool GetElkMode(); + void SetElkMode(bool value); + + protected: + bool m_isTrading; + + bool m_elk_mode; // ũ Ŭؼ ȯ . + TExchangeData m_self; + TExchangeData m_victim; +}; diff --git a/source/UserInterface/PythonExchangeModule.cpp b/source/UserInterface/PythonExchangeModule.cpp new file mode 100644 index 0000000..0874c35 --- /dev/null +++ b/source/UserInterface/PythonExchangeModule.cpp @@ -0,0 +1,191 @@ +#include "stdafx.h" +#include "PythonExchange.h" + +PyObject * exchangeInitTrading(PyObject * poSelf, PyObject * poArgs) +{ + CPythonExchange::Instance().End(); + return Py_BuildNone(); +} + +PyObject * exchangeisTrading(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonExchange::Instance().isTrading()); +} + +PyObject * exchangeGetElkFromSelf(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonExchange::Instance().GetElkFromSelf()); +} + +PyObject * exchangeGetElkFromTarget(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonExchange::Instance().GetElkFromTarget()); +} + +PyObject * exchangeGetAcceptFromSelf(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonExchange::Instance().GetAcceptFromSelf()); +} + +PyObject * exchangeGetAcceptFromTarget(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonExchange::Instance().GetAcceptFromTarget()); +} + +PyObject * exchangeGetItemVnumFromSelf(PyObject * poSelf, PyObject * poArgs) +{ + int pos; + + if (!PyTuple_GetInteger(poArgs, 0, &pos)) + return Py_BuildException(); + + return Py_BuildValue("i", CPythonExchange::Instance().GetItemVnumFromSelf((char) pos)); +} + +PyObject * exchangeGetItemVnumFromTarget(PyObject * poTarget, PyObject * poArgs) +{ + int pos; + + if (!PyTuple_GetInteger(poArgs, 0, &pos)) + return Py_BuildException(); + + return Py_BuildValue("i", CPythonExchange::Instance().GetItemVnumFromTarget((char) pos)); +} + +PyObject * exchangeGetItemCountFromSelf(PyObject * poSelf, PyObject * poArgs) +{ + int pos; + + if (!PyTuple_GetInteger(poArgs, 0, &pos)) + return Py_BuildException(); + + return Py_BuildValue("i", CPythonExchange::Instance().GetItemCountFromSelf((char) pos)); +} + +PyObject * exchangeGetItemCountFromTarget(PyObject * poTarget, PyObject * poArgs) +{ + int pos; + + if (!PyTuple_GetInteger(poArgs, 0, &pos)) + return Py_BuildException(); + + return Py_BuildValue("i", CPythonExchange::Instance().GetItemCountFromTarget((char) pos)); +} + +PyObject * exchangeGetNameFromSelf(PyObject * poTarget, PyObject * poArgs) +{ + return Py_BuildValue("s", CPythonExchange::Instance().GetNameFromSelf()); +} + +PyObject * exchangeGetNameFromTarget(PyObject * poTarget, PyObject * poArgs) +{ + return Py_BuildValue("s", CPythonExchange::Instance().GetNameFromTarget()); +} + +PyObject * exchangeGetItemMetinSocketFromTarget(PyObject * poTarget, PyObject * poArgs) +{ + int pos; + if (!PyTuple_GetInteger(poArgs, 0, &pos)) + return Py_BuildException(); + int iMetinSocketPos; + if (!PyTuple_GetInteger(poArgs, 1, &iMetinSocketPos)) + return Py_BuildException(); + return Py_BuildValue("i", CPythonExchange::Instance().GetItemMetinSocketFromTarget(pos, iMetinSocketPos)); +} + +PyObject * exchangeGetItemMetinSocketFromSelf(PyObject * poTarget, PyObject * poArgs) +{ + int pos; + if (!PyTuple_GetInteger(poArgs, 0, &pos)) + return Py_BuildException(); + int iMetinSocketPos; + if (!PyTuple_GetInteger(poArgs, 1, &iMetinSocketPos)) + return Py_BuildException(); + return Py_BuildValue("i", CPythonExchange::Instance().GetItemMetinSocketFromSelf(pos, iMetinSocketPos)); +} + +PyObject * exchangeGetItemAttributeFromTarget(PyObject * poTarget, PyObject * poArgs) +{ + int pos; + if (!PyTuple_GetInteger(poArgs, 0, &pos)) + return Py_BuildException(); + int iAttrSlotPos; + if (!PyTuple_GetInteger(poArgs, 1, &iAttrSlotPos)) + return Py_BuildException(); + + BYTE byType; + short sValue; + CPythonExchange::Instance().GetItemAttributeFromTarget(pos, iAttrSlotPos, &byType, &sValue); + + return Py_BuildValue("ii", byType, sValue); +} + +PyObject * exchangeGetItemAttributeFromSelf(PyObject * poTarget, PyObject * poArgs) +{ + int pos; + if (!PyTuple_GetInteger(poArgs, 0, &pos)) + return Py_BuildException(); + int iAttrSlotPos; + if (!PyTuple_GetInteger(poArgs, 1, &iAttrSlotPos)) + return Py_BuildException(); + + BYTE byType; + short sValue; + CPythonExchange::Instance().GetItemAttributeFromSelf(pos, iAttrSlotPos, &byType, &sValue); + + return Py_BuildValue("ii", byType, sValue); +} + +PyObject * exchangeGetElkMode(PyObject * poTarget, PyObject * poArgs) +{ + return Py_BuildValue("b", CPythonExchange::Instance().GetElkMode()); +} + +PyObject * exchangeSetElkMode(PyObject * poTarget, PyObject * poArgs) +{ + int elk_mode; + + if (!PyTuple_GetInteger(poArgs, 0, &elk_mode)) + return Py_BuildException(); + + CPythonExchange::Instance().SetElkMode(elk_mode ? true : false); + return Py_BuildNone(); +} + +void initTrade() +{ + static PyMethodDef s_methods[] = + { + {"InitTrading", exchangeInitTrading, METH_VARARGS}, + {"isTrading", exchangeisTrading, METH_VARARGS}, + + {"GetElkFromSelf", exchangeGetElkFromSelf, METH_VARARGS}, + {"GetElkFromTarget", exchangeGetElkFromTarget, METH_VARARGS}, + + {"GetItemVnumFromSelf", exchangeGetItemVnumFromSelf, METH_VARARGS}, + {"GetItemVnumFromTarget", exchangeGetItemVnumFromTarget, METH_VARARGS}, + + {"GetItemCountFromSelf", exchangeGetItemCountFromSelf, METH_VARARGS}, + {"GetItemCountFromTarget", exchangeGetItemCountFromTarget, METH_VARARGS}, + + {"GetAcceptFromSelf", exchangeGetAcceptFromSelf, METH_VARARGS}, + {"GetAcceptFromTarget", exchangeGetAcceptFromTarget, METH_VARARGS}, + + {"GetNameFromSelf", exchangeGetNameFromSelf, METH_VARARGS}, + {"GetNameFromTarget", exchangeGetNameFromTarget, METH_VARARGS}, + + {"GetItemMetinSocketFromTarget", exchangeGetItemMetinSocketFromTarget, METH_VARARGS}, + {"GetItemMetinSocketFromSelf", exchangeGetItemMetinSocketFromSelf, METH_VARARGS}, + + {"GetItemAttributeFromTarget", exchangeGetItemAttributeFromTarget, METH_VARARGS}, + {"GetItemAttributeFromSelf", exchangeGetItemAttributeFromSelf, METH_VARARGS}, + + {"GetElkMode", exchangeGetElkMode, METH_VARARGS}, + {"SetElkMode", exchangeSetElkMode, METH_VARARGS}, + + {NULL, NULL}, + }; + + PyObject * poModule = Py_InitModule("exchange", s_methods); + PyModule_AddIntConstant(poModule, "EXCHANGE_ITEM_MAX_NUM", CPythonExchange::EXCHANGE_ITEM_MAX_NUM); +} \ No newline at end of file diff --git a/source/UserInterface/PythonFlyModule.cpp b/source/UserInterface/PythonFlyModule.cpp new file mode 100644 index 0000000..1757854 --- /dev/null +++ b/source/UserInterface/PythonFlyModule.cpp @@ -0,0 +1,26 @@ +#include "stdafx.h" +#include "../gamelib/FlyingObjectManager.h" +PyObject * flyUpdate(PyObject * poSelf, PyObject * poArgs) +{ + CFlyingManager::Instance().Update(); + return Py_BuildNone(); +} + +PyObject * flyRender(PyObject * poSelf, PyObject * poArgs) +{ + CFlyingManager::Instance().Render(); + return Py_BuildNone(); +} + +void initfly() +{ + static PyMethodDef s_methods[] = + { + { "Update", flyUpdate, METH_VARARGS }, + { "Render", flyRender, METH_VARARGS }, + + { NULL, NULL, NULL }, + }; + + Py_InitModule("fly", s_methods); +} \ No newline at end of file diff --git a/source/UserInterface/PythonGameEventManagerModule.cpp b/source/UserInterface/PythonGameEventManagerModule.cpp new file mode 100644 index 0000000..bbaceb4 --- /dev/null +++ b/source/UserInterface/PythonGameEventManagerModule.cpp @@ -0,0 +1,30 @@ +#include "StdAfx.h" +#include "../gamelib/GameEventManager.h" + +PyObject * eventMgrUpdate(PyObject * poSelf, PyObject * poArgs) +{ + float fx; + if (!PyTuple_GetFloat(poArgs, 0, &fx)) + return Py_BuildException(); + float fy; + if (!PyTuple_GetFloat(poArgs, 1, &fy)) + return Py_BuildException(); + float fz; + if (!PyTuple_GetFloat(poArgs, 2, &fz)) + return Py_BuildException(); + + CGameEventManager::Instance().SetCenterPosition(fx, fy, fz); + CGameEventManager::Instance().Update(); + return Py_BuildNone(); +} + +void initeventmgr() +{ + static PyMethodDef s_methods[] = + { + { "Update", eventMgrUpdate, METH_VARARGS }, + { NULL, NULL, NULL }, + }; + + Py_InitModule("eventMgr", s_methods); +} \ No newline at end of file diff --git a/source/UserInterface/PythonGuild.cpp b/source/UserInterface/PythonGuild.cpp new file mode 100644 index 0000000..96cb603 --- /dev/null +++ b/source/UserInterface/PythonGuild.cpp @@ -0,0 +1,799 @@ +#include "StdAfx.h" +#include "PythonGuild.h" +#include "AbstractPlayer.h" +#include "MarkManager.h" + +std::map g_GuildSkillSlotToIndexMap; + +void CPythonGuild::EnableGuild() +{ + m_bGuildEnable = TRUE; +} + +void CPythonGuild::SetGuildMoney(DWORD dwMoney) +{ + m_GuildInfo.dwGuildMoney = dwMoney; +} + +void CPythonGuild::SetGuildEXP(BYTE byLevel, DWORD dwEXP) +{ + m_GuildInfo.dwGuildLevel = byLevel; + m_GuildInfo.dwCurrentExperience = dwEXP; +} + +void CPythonGuild::SetGradeData(BYTE byGradeNumber, TGuildGradeData & rGuildGradeData) +{ + m_GradeDataMap[byGradeNumber] = rGuildGradeData; +} + +void CPythonGuild::SetGradeName(BYTE byGradeNumber, const char * c_szName) +{ + if (!__IsGradeData(byGradeNumber)) + return; + + TGuildGradeData & rGradeData = m_GradeDataMap.find(byGradeNumber)->second; + rGradeData.strName = c_szName; +} + +void CPythonGuild::SetGradeAuthority(BYTE byGradeNumber, BYTE byAuthority) +{ + if (!__IsGradeData(byGradeNumber)) + return; + + TGuildGradeData & rGradeData = m_GradeDataMap.find(byGradeNumber)->second; + rGradeData.byAuthorityFlag = byAuthority; +} + +void CPythonGuild::ClearComment() +{ + m_GuildBoardCommentVector.clear(); +} + +void CPythonGuild::RegisterComment(DWORD dwCommentID, const char * c_szName, const char * c_szComment) +{ + if (0 == strlen(c_szComment)) + return; + + TGuildBoardCommentData CommentData; + CommentData.dwCommentID = dwCommentID; + CommentData.strName = c_szName; + CommentData.strComment = c_szComment; + + m_GuildBoardCommentVector.push_back(CommentData); +} + +void CPythonGuild::RegisterMember(TGuildMemberData & rGuildMemberData) +{ + TGuildMemberData * pGuildMemberData; + if (GetMemberDataPtrByPID(rGuildMemberData.dwPID, &pGuildMemberData)) + { + pGuildMemberData->byGeneralFlag = rGuildMemberData.byGeneralFlag; + pGuildMemberData->byGrade = rGuildMemberData.byGrade; + pGuildMemberData->byLevel = rGuildMemberData.byLevel; + pGuildMemberData->dwOffer = rGuildMemberData.dwOffer; + } + else + { + m_GuildMemberDataVector.push_back(rGuildMemberData); + } + + __CalculateLevelAverage(); + __SortMember(); +} + +struct CPythonGuild_FFindGuildMemberByPID +{ + CPythonGuild_FFindGuildMemberByPID(DWORD dwSearchingPID_) : dwSearchingPID(dwSearchingPID_) {} + int operator () (CPythonGuild::TGuildMemberData & rGuildMemberData) + { + return rGuildMemberData.dwPID == dwSearchingPID; + } + + DWORD dwSearchingPID; +}; + +struct CPythonGuild_FFindGuildMemberByName +{ + CPythonGuild_FFindGuildMemberByName(const char * c_szSearchingName) : strSearchingName(c_szSearchingName) {} + int operator () (CPythonGuild::TGuildMemberData & rGuildMemberData) + { + return 0 == strSearchingName.compare(rGuildMemberData.strName.c_str()); + } + + std::string strSearchingName; +}; + +void CPythonGuild::ChangeGuildMemberGrade(DWORD dwPID, BYTE byGrade) +{ + TGuildMemberData * pGuildMemberData; + if (!GetMemberDataPtrByPID(dwPID, &pGuildMemberData)) + return; + + pGuildMemberData->byGrade = byGrade; +} + +void CPythonGuild::ChangeGuildMemberGeneralFlag(DWORD dwPID, BYTE byFlag) +{ + TGuildMemberData * pGuildMemberData; + if (!GetMemberDataPtrByPID(dwPID, &pGuildMemberData)) + return; + + pGuildMemberData->byGeneralFlag = byFlag; +} + +void CPythonGuild::RemoveMember(DWORD dwPID) +{ + TGuildMemberDataVector::iterator itor; + itor = std::find_if( m_GuildMemberDataVector.begin(), + m_GuildMemberDataVector.end(), + CPythonGuild_FFindGuildMemberByPID(dwPID)); + + if (m_GuildMemberDataVector.end() == itor) + return; + + m_GuildMemberDataVector.erase(itor); +} + +void CPythonGuild::RegisterGuildName(DWORD dwID, const char * c_szName) +{ + m_GuildNameMap.insert(std::make_pair(dwID, std::string(c_szName))); +} + +BOOL CPythonGuild::IsMainPlayer(DWORD dwPID) +{ + TGuildMemberData * pGuildMemberData; + if (!GetMemberDataPtrByPID(dwPID, &pGuildMemberData)) + return FALSE; + + IAbstractPlayer& rPlayer=IAbstractPlayer::GetSingleton(); + return 0 == pGuildMemberData->strName.compare(rPlayer.GetName()); +} + +BOOL CPythonGuild::IsGuildEnable() +{ + return m_bGuildEnable; +} + +CPythonGuild::TGuildInfo & CPythonGuild::GetGuildInfoRef() +{ + return m_GuildInfo; +} + +BOOL CPythonGuild::GetGradeDataPtr(DWORD dwGradeNumber, TGuildGradeData ** ppData) +{ + TGradeDataMap::iterator itor = m_GradeDataMap.find(dwGradeNumber); + if (m_GradeDataMap.end() == itor) + return FALSE; + + *ppData = &(itor->second); + + return TRUE; +} + +const CPythonGuild::TGuildBoardCommentDataVector & CPythonGuild::GetGuildBoardCommentVector() +{ + return m_GuildBoardCommentVector; +} + +DWORD CPythonGuild::GetMemberCount() +{ + return m_GuildMemberDataVector.size(); +} + +BOOL CPythonGuild::GetMemberDataPtr(DWORD dwIndex, TGuildMemberData ** ppData) +{ + if (dwIndex >= m_GuildMemberDataVector.size()) + return FALSE; + + *ppData = &m_GuildMemberDataVector[dwIndex]; + + return TRUE; +} + +BOOL CPythonGuild::GetMemberDataPtrByPID(DWORD dwPID, TGuildMemberData ** ppData) +{ + TGuildMemberDataVector::iterator itor; + itor = std::find_if( m_GuildMemberDataVector.begin(), + m_GuildMemberDataVector.end(), + CPythonGuild_FFindGuildMemberByPID(dwPID)); + + if (m_GuildMemberDataVector.end() == itor) + return FALSE; + + *ppData = &(*itor); + return TRUE; +} + +BOOL CPythonGuild::GetMemberDataPtrByName(const char * c_szName, TGuildMemberData ** ppData) +{ + TGuildMemberDataVector::iterator itor; + itor = std::find_if( m_GuildMemberDataVector.begin(), + m_GuildMemberDataVector.end(), + CPythonGuild_FFindGuildMemberByName(c_szName)); + + if (m_GuildMemberDataVector.end() == itor) + return FALSE; + + *ppData = &(*itor); + return TRUE; +} + +DWORD CPythonGuild::GetGuildMemberLevelSummary() +{ + return m_dwMemberLevelSummary; +} + +DWORD CPythonGuild::GetGuildMemberLevelAverage() +{ + return m_dwMemberLevelAverage; +} + +DWORD CPythonGuild::GetGuildExperienceSummary() +{ + return m_dwMemberExperienceSummary; +} + +CPythonGuild::TGuildSkillData & CPythonGuild::GetGuildSkillDataRef() +{ + return m_GuildSkillData; +} + +bool CPythonGuild::GetGuildName(DWORD dwID, std::string * pstrGuildName) +{ + if (m_GuildNameMap.end() == m_GuildNameMap.find(dwID)) + return false; + + *pstrGuildName = m_GuildNameMap[dwID]; + + return true; +} + +DWORD CPythonGuild::GetGuildID() +{ + return m_GuildInfo.dwGuildID; +} + +BOOL CPythonGuild::HasGuildLand() +{ + return m_GuildInfo.bHasLand; +} + +void CPythonGuild::StartGuildWar(DWORD dwEnemyGuildID) +{ + int i; + + for (i = 0; i < ENEMY_GUILD_SLOT_MAX_COUNT; ++i) + if (dwEnemyGuildID == m_adwEnemyGuildID[i]) + return; + + for (i = 0; i < ENEMY_GUILD_SLOT_MAX_COUNT; ++i) + if (0 == m_adwEnemyGuildID[i]) + { + m_adwEnemyGuildID[i] = dwEnemyGuildID; + break; + } +} + +void CPythonGuild::EndGuildWar(DWORD dwEnemyGuildID) +{ + for (int i = 0; i < ENEMY_GUILD_SLOT_MAX_COUNT; ++i) + if (dwEnemyGuildID == m_adwEnemyGuildID[i]) + m_adwEnemyGuildID[i] = 0; +} + +DWORD CPythonGuild::GetEnemyGuildID(DWORD dwIndex) +{ + if (dwIndex >= ENEMY_GUILD_SLOT_MAX_COUNT) + return 0; + + return m_adwEnemyGuildID[dwIndex]; +} + +BOOL CPythonGuild::IsDoingGuildWar() +{ + for (int i = 0; i < ENEMY_GUILD_SLOT_MAX_COUNT; ++i) + if (0 != m_adwEnemyGuildID[i]) + { + return TRUE; + } + + return FALSE; +} + +void CPythonGuild::__CalculateLevelAverage() +{ + m_dwMemberLevelSummary = 0; + m_dwMemberLevelAverage = 0; + m_dwMemberExperienceSummary = 0; + + if (m_GuildMemberDataVector.empty()) + return; + + TGuildMemberDataVector::iterator itor; + + // Sum Level & Experience + itor = m_GuildMemberDataVector.begin(); + for (; itor != m_GuildMemberDataVector.end(); ++itor) + { + TGuildMemberData & rGuildMemberData = *itor; + m_dwMemberLevelSummary += rGuildMemberData.byLevel; + m_dwMemberExperienceSummary += rGuildMemberData.dwOffer; + } + + assert(!m_GuildMemberDataVector.empty()); + m_dwMemberLevelAverage = m_dwMemberLevelSummary / m_GuildMemberDataVector.size(); +} + +struct CPythonGuild_SLessMemberGrade +{ + bool operator() (CPythonGuild::TGuildMemberData & rleft, CPythonGuild::TGuildMemberData & rright) + { + if (rleft.byGrade < rright.byGrade) + return true; + + return false; + } +}; + +void CPythonGuild::__SortMember() +{ + std::sort(m_GuildMemberDataVector.begin(), m_GuildMemberDataVector.end(), CPythonGuild_SLessMemberGrade()); +} + +BOOL CPythonGuild::__IsGradeData(BYTE byGradeNumber) +{ + return m_GradeDataMap.end() != m_GradeDataMap.find(byGradeNumber); +} + +void CPythonGuild::__Initialize() +{ + ZeroMemory(&m_GuildInfo, sizeof(m_GuildInfo)); + ZeroMemory(&m_GuildSkillData, sizeof(m_GuildSkillData)); + ZeroMemory(&m_adwEnemyGuildID, ENEMY_GUILD_SLOT_MAX_COUNT*sizeof(DWORD)); + m_GradeDataMap.clear(); + m_GuildMemberDataVector.clear(); + m_dwMemberLevelSummary = 0; + m_dwMemberLevelAverage = 0; + m_bGuildEnable = FALSE; + m_GuildNameMap.clear(); +} + +void CPythonGuild::Destroy() +{ + __Initialize(); +} + +CPythonGuild::CPythonGuild() +{ + __Initialize(); +} +CPythonGuild::~CPythonGuild() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// + +PyObject * guildIsGuildEnable(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonGuild::Instance().IsGuildEnable()); +} + +PyObject * guildGetGuildID(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonGuild::Instance().GetGuildID()); +} + +PyObject * guildHasGuildLand(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonGuild::Instance().HasGuildLand()); +} + +PyObject * guildGetGuildName(PyObject * poSelf, PyObject * poArgs) +{ + int iGuildID; + if (!PyTuple_GetInteger(poArgs, 0, &iGuildID)) + { + CPythonGuild::TGuildInfo & rGuildInfo = CPythonGuild::Instance().GetGuildInfoRef(); + return Py_BuildValue("s", rGuildInfo.szGuildName); + } + + std::string strGuildName; + if (!CPythonGuild::Instance().GetGuildName(iGuildID, &strGuildName)) + return Py_BuildValue("s", "Noname"); + + return Py_BuildValue("s", strGuildName.c_str()); +} + +PyObject * guildGetGuildMasterName(PyObject * poSelf, PyObject * poArgs) +{ + CPythonGuild::TGuildInfo & rGuildInfo = CPythonGuild::Instance().GetGuildInfoRef(); + + CPythonGuild::TGuildMemberData * pData; + if (!CPythonGuild::Instance().GetMemberDataPtrByPID(rGuildInfo.dwMasterPID, &pData)) + return Py_BuildValue("s", "Noname"); + + return Py_BuildValue("s", pData->strName.c_str()); +} + +PyObject * guildGetEnemyGuildName(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildValue("s", ""); + + DWORD dwEnemyGuildID = CPythonGuild::Instance().GetEnemyGuildID(iIndex); + + std::string strEnemyGuildName; + if (!CPythonGuild::Instance().GetGuildName(dwEnemyGuildID, &strEnemyGuildName)) + return Py_BuildValue("s", ""); + + return Py_BuildValue("s", strEnemyGuildName.c_str()); +} + +PyObject * guildGetGuildMoney(PyObject * poSelf, PyObject * poArgs) +{ + CPythonGuild::TGuildInfo & rGuildInfo = CPythonGuild::Instance().GetGuildInfoRef(); + return Py_BuildValue("i", rGuildInfo.dwGuildMoney); +} + +PyObject * guildGetGuildBoardCommentCount(PyObject * poSelf, PyObject * poArgs) +{ + const CPythonGuild::TGuildBoardCommentDataVector & rCommentVector = CPythonGuild::Instance().GetGuildBoardCommentVector(); + return Py_BuildValue("i", rCommentVector.size()); +} + +PyObject * guildGetGuildBoardCommentData(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + + const CPythonGuild::TGuildBoardCommentDataVector & c_rCommentVector = CPythonGuild::Instance().GetGuildBoardCommentVector(); + if (DWORD(iIndex) >= c_rCommentVector.size()) + return Py_BuildValue("iss", 0, "Noname", "Noname"); + + const CPythonGuild::TGuildBoardCommentData & c_rData = c_rCommentVector[iIndex]; + + return Py_BuildValue("iss", c_rData.dwCommentID, c_rData.strName.c_str(), c_rData.strComment.c_str()); +} + +PyObject * guildGetGuildLevel(PyObject * poSelf, PyObject * poArgs) +{ + CPythonGuild::TGuildInfo & rGuildInfo = CPythonGuild::Instance().GetGuildInfoRef(); + return Py_BuildValue("i", rGuildInfo.dwGuildLevel); +} + + + +PyObject * guildGetGuildExperience(PyObject * poSelf, PyObject * poArgs) +{ + CPythonGuild::TGuildInfo & rGuildInfo = CPythonGuild::Instance().GetGuildInfoRef(); + + int GULID_MAX_LEVEL = 20; + if (rGuildInfo.dwGuildLevel >= GULID_MAX_LEVEL) + return Py_BuildValue("ii", 0, 0); + + unsigned lastExp = LocaleService_GetLastExp(rGuildInfo.dwGuildLevel); + + return Py_BuildValue("ii", rGuildInfo.dwCurrentExperience, lastExp - rGuildInfo.dwCurrentExperience); +} + +PyObject * guildGetGuildMemberCount(PyObject * poSelf, PyObject * poArgs) +{ + CPythonGuild::TGuildInfo & rGuildInfo = CPythonGuild::Instance().GetGuildInfoRef(); + return Py_BuildValue("ii", rGuildInfo.dwCurrentMemberCount, rGuildInfo.dwMaxMemberCount); +} + +PyObject * guildGetGuildMemberLevelSummary(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonGuild::Instance().GetGuildMemberLevelSummary()); +} + +PyObject * guildGetGuildMemberLevelAverage(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonGuild::Instance().GetGuildMemberLevelAverage()); +} + +PyObject * guildGetGuildExperienceSummary(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonGuild::Instance().GetGuildExperienceSummary()); +} + +PyObject * guildGetGuildSkillPoint(PyObject * poSelf, PyObject * poArgs) +{ + const CPythonGuild::TGuildSkillData & c_rSkillData = CPythonGuild::Instance().GetGuildSkillDataRef(); + return Py_BuildValue("i", c_rSkillData.bySkillPoint); +} + +PyObject * guildGetDragonPowerPoint(PyObject * poSelf, PyObject * poArgs) +{ + const CPythonGuild::TGuildSkillData & c_rSkillData = CPythonGuild::Instance().GetGuildSkillDataRef(); + return Py_BuildValue("ii", c_rSkillData.wGuildPoint, c_rSkillData.wMaxGuildPoint); +} + +PyObject * guildGetGuildSkillLevel(PyObject * poSelf, PyObject * poArgs) +{ + assert(FALSE && !"guildGetGuildSkillLevel - ʴ ԼԴϴ."); + + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BuildException(); + + const CPythonGuild::TGuildSkillData & c_rSkillData = CPythonGuild::Instance().GetGuildSkillDataRef(); + return Py_BuildValue("i", c_rSkillData.bySkillLevel[iSkillIndex]); +} + +PyObject * guildGetSkillLevel(PyObject * poSelf, PyObject * poArgs) +{ + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + + std::map::iterator itor = g_GuildSkillSlotToIndexMap.find(iSlotIndex); + + if (g_GuildSkillSlotToIndexMap.end() == itor) + return Py_BuildValue("i", 0); + + DWORD dwSkillIndex = itor->second; + assert(dwSkillIndex < CPythonGuild::GUILD_SKILL_MAX_NUM); + + const CPythonGuild::TGuildSkillData & c_rSkillData = CPythonGuild::Instance().GetGuildSkillDataRef(); + return Py_BuildValue("i", c_rSkillData.bySkillLevel[dwSkillIndex]); +} + +PyObject * guildGetSkillMaxLevelNew(PyObject * poSelf, PyObject * poArgs) +{ + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + + std::map::iterator itor = g_GuildSkillSlotToIndexMap.find(iSlotIndex); + + if (g_GuildSkillSlotToIndexMap.end() == itor) + return Py_BuildValue("i", 0); + + DWORD dwSkillIndex = itor->second; + assert(dwSkillIndex < CPythonGuild::GUILD_SKILL_MAX_NUM); + + const CPythonGuild::TGuildSkillData & c_rSkillData = CPythonGuild::Instance().GetGuildSkillDataRef(); + return Py_BuildValue("i", c_rSkillData.bySkillLevel[dwSkillIndex]); +} + +PyObject * guildSetSkillIndex(PyObject * poSelf, PyObject * poArgs) +{ + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iSkillIndex)) + return Py_BuildException(); + + g_GuildSkillSlotToIndexMap.insert(std::make_pair(iSlotIndex, iSkillIndex)); + + return Py_BuildNone(); +} + +PyObject * guildGetSkillIndex(PyObject * poSelf, PyObject * poArgs) +{ + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + + std::map::iterator itor = g_GuildSkillSlotToIndexMap.find(iSlotIndex); + + if (g_GuildSkillSlotToIndexMap.end() == itor) + return Py_BuildValue("i", 0); + + DWORD dwSkillIndex = itor->second; + return Py_BuildValue("i", dwSkillIndex); +} + +PyObject * guildGetGradeData(PyObject * poSelf, PyObject * poArgs) +{ + int iGradeNumber; + if (!PyTuple_GetInteger(poArgs, 0, &iGradeNumber)) + return Py_BuildException(); + + CPythonGuild::TGuildGradeData * pData; + if (!CPythonGuild::Instance().GetGradeDataPtr(iGradeNumber, &pData)) + return Py_BuildValue("si", "?", 0); + + return Py_BuildValue("si", pData->strName.c_str(), pData->byAuthorityFlag); +} + +PyObject * guildGetGradeName(PyObject * poSelf, PyObject * poArgs) +{ + int iGradeNumber; + if (!PyTuple_GetInteger(poArgs, 0, &iGradeNumber)) + return Py_BuildException(); + + CPythonGuild::TGuildGradeData * pData; + if (!CPythonGuild::Instance().GetGradeDataPtr(iGradeNumber, &pData)) + return Py_BuildValue("s", "?"); + + return Py_BuildValue("s", pData->strName.c_str()); +} + +PyObject * guildGetMemberCount(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonGuild::Instance().GetMemberCount()); +} + +PyObject * guildGetMemberData(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + + CPythonGuild::TGuildMemberData * pData; + if (!CPythonGuild::Instance().GetMemberDataPtr(iIndex, &pData)) + return Py_BuildValue("isiiiii", -1, "", 0, 0, 0, 0, 0); + + return Py_BuildValue("isiiiii", pData->dwPID, pData->strName.c_str(), pData->byGrade, pData->byJob, pData->byLevel, pData->dwOffer, pData->byGeneralFlag); +} + +PyObject * guildMemberIndexToPID(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + + CPythonGuild::TGuildMemberData * pData; + if (!CPythonGuild::Instance().GetMemberDataPtr(iIndex, &pData)) + return Py_BuildValue("i", -1); + + return Py_BuildValue("i", pData->dwPID); +} + +PyObject * guildIsMember(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + + CPythonGuild::TGuildMemberData * pData; + if (CPythonGuild::Instance().GetMemberDataPtr(iIndex, &pData)) + return Py_BuildValue("i", TRUE); + + return Py_BuildValue("i", FALSE); +} + +PyObject * guildIsMemberByName(PyObject * poSelf, PyObject * poArgs) +{ + char * szName; + if (!PyTuple_GetString(poArgs, 0, &szName)) + return Py_BuildException(); + + CPythonGuild::TGuildMemberData * pData; + if (CPythonGuild::Instance().GetMemberDataPtrByName(szName, &pData)) + return Py_BuildValue("i", TRUE); + + return Py_BuildValue("i", FALSE); +} + +PyObject * guildMainPlayerHasAuthority(PyObject * poSelf, PyObject * poArgs) +{ + int iAuthority; + if (!PyTuple_GetInteger(poArgs, 0, &iAuthority)) + return Py_BuildException(); + + IAbstractPlayer& rPlayer=IAbstractPlayer::GetSingleton(); + const char * c_szMainPlayerName = rPlayer.GetName(); + + CPythonGuild::TGuildMemberData * pMemberData; + if (!CPythonGuild::Instance().GetMemberDataPtrByName(c_szMainPlayerName, &pMemberData)) + return Py_BuildValue("i", FALSE); + + CPythonGuild::TGuildGradeData * pGradeData; + if (!CPythonGuild::Instance().GetGradeDataPtr(pMemberData->byGrade, &pGradeData)) + return Py_BuildValue("i", FALSE); + + return Py_BuildValue("i", iAuthority == (pGradeData->byAuthorityFlag & iAuthority)); +} + +PyObject * guildDestroy(PyObject * poSelf, PyObject * poArgs) +{ + CPythonGuild::Instance().Destroy(); + g_GuildSkillSlotToIndexMap.clear(); + return Py_BuildNone(); +} + + +PyObject * guildGuildIDToMarkID(PyObject * poSelf, PyObject * poArgs) +{ + int guild_id; + if (!PyTuple_GetInteger(poArgs, 0, &guild_id)) + return Py_BuildException(); + + return Py_BuildValue("i", CGuildMarkManager::Instance().GetMarkID(guild_id)); +} + +PyObject * guildGetMarkImageFilenameByMarkID(PyObject * poSelf, PyObject * poArgs) +{ + int markID; + + if (!PyTuple_GetInteger(poArgs, 0, &markID)) + return Py_BuildException(); + + std::string imagePath; + CGuildMarkManager::Instance().GetMarkImageFilename(markID / CGuildMarkImage::MARK_TOTAL_COUNT, imagePath); + return Py_BuildValue("s", imagePath.c_str()); +} + +PyObject * guildGetMarkIndexByMarkID(PyObject * poSelf, PyObject * poArgs) +{ + int markID; + + if (!PyTuple_GetInteger(poArgs, 0, &markID)) + return Py_BuildException(); + + return Py_BuildValue("i", markID % CGuildMarkImage::MARK_TOTAL_COUNT); +} + +void initguild() +{ + static PyMethodDef s_methods[] = + { + // Enable + { "IsGuildEnable", guildIsGuildEnable, METH_VARARGS }, + { "GuildIDToMarkID", guildGuildIDToMarkID, METH_VARARGS }, + { "GetMarkImageFilenameByMarkID", guildGetMarkImageFilenameByMarkID, METH_VARARGS }, + { "GetMarkIndexByMarkID", guildGetMarkIndexByMarkID, METH_VARARGS }, + + // GuildInfo + { "GetGuildID", guildGetGuildID, METH_VARARGS }, + { "HasGuildLand", guildHasGuildLand, METH_VARARGS }, + { "GetGuildName", guildGetGuildName, METH_VARARGS }, + { "GetGuildMasterName", guildGetGuildMasterName, METH_VARARGS }, + { "GetEnemyGuildName", guildGetEnemyGuildName, METH_VARARGS }, + { "GetGuildMoney", guildGetGuildMoney, METH_VARARGS }, + + // BoardPage + { "GetGuildBoardCommentCount", guildGetGuildBoardCommentCount, METH_VARARGS }, + { "GetGuildBoardCommentData", guildGetGuildBoardCommentData, METH_VARARGS }, + + // MemberPage + { "GetGuildLevel", guildGetGuildLevel, METH_VARARGS }, + { "GetGuildExperience", guildGetGuildExperience, METH_VARARGS }, + { "GetGuildMemberCount", guildGetGuildMemberCount, METH_VARARGS }, + { "GetGuildMemberLevelSummary", guildGetGuildMemberLevelSummary, METH_VARARGS }, + { "GetGuildMemberLevelAverage", guildGetGuildMemberLevelAverage, METH_VARARGS }, + { "GetGuildExperienceSummary", guildGetGuildExperienceSummary, METH_VARARGS }, + + // SkillPage + { "GetGuildSkillPoint", guildGetGuildSkillPoint, METH_VARARGS }, + { "GetDragonPowerPoint", guildGetDragonPowerPoint, METH_VARARGS }, + { "GetGuildSkillLevel", guildGetGuildSkillLevel, METH_VARARGS }, + { "GetSkillLevel", guildGetSkillLevel, METH_VARARGS }, + { "GetSkillMaxLevelNew", guildGetSkillMaxLevelNew, METH_VARARGS }, + + { "SetSkillIndex", guildSetSkillIndex, METH_VARARGS }, + { "GetSkillIndex", guildGetSkillIndex, METH_VARARGS }, + + // GradePage + { "GetGradeData", guildGetGradeData, METH_VARARGS }, + { "GetGradeName", guildGetGradeName, METH_VARARGS }, + + // About Member + { "GetMemberCount", guildGetMemberCount, METH_VARARGS }, + { "GetMemberData", guildGetMemberData, METH_VARARGS }, + { "MemberIndexToPID", guildMemberIndexToPID, METH_VARARGS }, + { "IsMember", guildIsMember, METH_VARARGS }, + { "IsMemberByName", guildIsMemberByName, METH_VARARGS }, + { "MainPlayerHasAuthority", guildMainPlayerHasAuthority, METH_VARARGS }, + + // Guild + { "Destroy", guildDestroy, METH_VARARGS }, + + { NULL, NULL, NULL }, + }; + + PyObject * poModule = Py_InitModule("guild", s_methods); + PyModule_AddIntConstant(poModule, "AUTH_ADD_MEMBER", GUILD_AUTH_ADD_MEMBER); + PyModule_AddIntConstant(poModule, "AUTH_REMOVE_MEMBER", GUILD_AUTH_REMOVE_MEMBER); + PyModule_AddIntConstant(poModule, "AUTH_NOTICE", GUILD_AUTH_NOTICE); + PyModule_AddIntConstant(poModule, "AUTH_SKILL", GUILD_AUTH_SKILL); + PyModule_AddIntConstant(poModule, "ENEMY_GUILD_SLOT_MAX_COUNT", CPythonGuild::ENEMY_GUILD_SLOT_MAX_COUNT); +} diff --git a/source/UserInterface/PythonGuild.h b/source/UserInterface/PythonGuild.h new file mode 100644 index 0000000..e3f09f3 --- /dev/null +++ b/source/UserInterface/PythonGuild.h @@ -0,0 +1,130 @@ +#pragma once + +#include "Packet.h" + +class CPythonGuild : public CSingleton +{ + public: + enum + { + GUILD_SKILL_MAX_NUM = 12, + ENEMY_GUILD_SLOT_MAX_COUNT = 6, + }; + + typedef struct SGulidInfo + { + DWORD dwGuildID; + char szGuildName[GUILD_NAME_MAX_LEN+1]; + DWORD dwMasterPID; + DWORD dwGuildLevel; + DWORD dwCurrentExperience; + DWORD dwCurrentMemberCount; + DWORD dwMaxMemberCount; + DWORD dwGuildMoney; + BOOL bHasLand; + } TGuildInfo; + + typedef struct SGuildGradeData + { + SGuildGradeData(){} + SGuildGradeData(BYTE byAuthorityFlag_, const char * c_szName_) : byAuthorityFlag(byAuthorityFlag_), strName(c_szName_) {} + BYTE byAuthorityFlag; + std::string strName; + } TGuildGradeData; + typedef std::map TGradeDataMap; + + typedef struct SGuildMemberData + { + DWORD dwPID; + + std::string strName; + BYTE byGrade; + BYTE byJob; + BYTE byLevel; + BYTE byGeneralFlag; + DWORD dwOffer; + } TGuildMemberData; + typedef std::vector TGuildMemberDataVector; + + typedef struct SGuildBoardCommentData + { + DWORD dwCommentID; + std::string strName; + std::string strComment; + } TGuildBoardCommentData; + typedef std::vector TGuildBoardCommentDataVector; + + typedef struct SGuildSkillData + { + BYTE bySkillPoint; + BYTE bySkillLevel[GUILD_SKILL_MAX_NUM]; + WORD wGuildPoint; + WORD wMaxGuildPoint; + } TGuildSkillData; + + typedef std::map TGuildNameMap; + + public: + CPythonGuild(); + virtual ~CPythonGuild(); + + void Destroy(); + + void EnableGuild(); + void SetGuildMoney(DWORD dwMoney); + void SetGuildEXP(BYTE byLevel, DWORD dwEXP); + void SetGradeData(BYTE byGradeNumber, TGuildGradeData & rGuildGradeData); + void SetGradeName(BYTE byGradeNumber, const char * c_szName); + void SetGradeAuthority(BYTE byGradeNumber, BYTE byAuthority); + void ClearComment(); + void RegisterComment(DWORD dwCommentID, const char * c_szName, const char * c_szComment); + void RegisterMember(TGuildMemberData & rGuildMemberData); + void ChangeGuildMemberGrade(DWORD dwPID, BYTE byGrade); + void ChangeGuildMemberGeneralFlag(DWORD dwPID, BYTE byFlag); + void RemoveMember(DWORD dwPID); + void RegisterGuildName(DWORD dwID, const char * c_szName); + + BOOL IsMainPlayer(DWORD dwPID); + BOOL IsGuildEnable(); + TGuildInfo & GetGuildInfoRef(); + BOOL GetGradeDataPtr(DWORD dwGradeNumber, TGuildGradeData ** ppData); + const TGuildBoardCommentDataVector & GetGuildBoardCommentVector(); + DWORD GetMemberCount(); + BOOL GetMemberDataPtr(DWORD dwIndex, TGuildMemberData ** ppData); + BOOL GetMemberDataPtrByPID(DWORD dwPID, TGuildMemberData ** ppData); + BOOL GetMemberDataPtrByName(const char * c_szName, TGuildMemberData ** ppData); + DWORD GetGuildMemberLevelSummary(); + DWORD GetGuildMemberLevelAverage(); + DWORD GetGuildExperienceSummary(); + TGuildSkillData & GetGuildSkillDataRef(); + bool GetGuildName(DWORD dwID, std::string * pstrGuildName); + DWORD GetGuildID(); + BOOL HasGuildLand(); + + void StartGuildWar(DWORD dwEnemyGuildID); + void EndGuildWar(DWORD dwEnemyGuildID); + DWORD GetEnemyGuildID(DWORD dwIndex); + BOOL IsDoingGuildWar(); + + protected: + void __CalculateLevelAverage(); + void __SortMember(); + BOOL __IsGradeData(BYTE byGradeNumber); + + void __Initialize(); + + protected: + TGuildInfo m_GuildInfo; + TGradeDataMap m_GradeDataMap; + TGuildMemberDataVector m_GuildMemberDataVector; + TGuildBoardCommentDataVector m_GuildBoardCommentVector; + TGuildSkillData m_GuildSkillData; + TGuildNameMap m_GuildNameMap; + DWORD m_adwEnemyGuildID[ENEMY_GUILD_SLOT_MAX_COUNT]; + + DWORD m_dwMemberLevelSummary; + DWORD m_dwMemberLevelAverage; + DWORD m_dwMemberExperienceSummary; + + BOOL m_bGuildEnable; +}; \ No newline at end of file diff --git a/source/UserInterface/PythonIME.cpp b/source/UserInterface/PythonIME.cpp new file mode 100644 index 0000000..5ae38d5 --- /dev/null +++ b/source/UserInterface/PythonIME.cpp @@ -0,0 +1,119 @@ +#include "StdAfx.h" +#include "PythonIME.h" +#include "AbstractApplication.h" + +CPythonIME::CPythonIME() +: CIME() +{ + ms_pEvent = this; +} + +CPythonIME::~CPythonIME() +{ + Tracen("PythonIME Clear"); +} + +void CPythonIME::Create(HWND hWnd) +{ + Initialize(hWnd); +} + +void CPythonIME::MoveLeft() +{ + DecCurPos(); +} + +void CPythonIME::MoveRight() +{ + IncCurPos(); +} + +void CPythonIME::MoveHome() +{ + ms_curpos = 0; +} + +void CPythonIME::MoveEnd() +{ + ms_curpos = ms_lastpos; +} + +void CPythonIME::SetCursorPosition(int iPosition) +{ + SetCurPos(iPosition); +} + +void CPythonIME::Delete() +{ + DelCurPos(); +} + +void CPythonIME::OnUpdate() +{ + IAbstractApplication::GetSingleton().RunIMEUpdate(); +} + +void CPythonIME::OnTab() +{ + IAbstractApplication::GetSingleton().RunIMETabEvent(); +} + +void CPythonIME::OnReturn() +{ + IAbstractApplication::GetSingleton().RunIMEReturnEvent(); +} + +void CPythonIME::OnEscape() +{ +// IAbstractApplication::GetSingleton().RunIMEEscapeEvent(); +} + +bool CPythonIME::OnWM_CHAR( WPARAM wParam, LPARAM lParam ) +{ + unsigned char c = unsigned char(wParam & 0xff); + + switch (c) + { + case VK_RETURN: + OnReturn(); + return true; + + case VK_TAB: + if(ms_bCaptureInput == false) + return 0; + OnTab(); + return true; + + case VK_ESCAPE: + if(ms_bCaptureInput == false) + return 0; + OnEscape(); + return true; + } + return false; +} + +void CPythonIME::OnChangeCodePage() +{ + IAbstractApplication::GetSingleton().RunIMEChangeCodePage(); +} + +void CPythonIME::OnOpenCandidateList() +{ + IAbstractApplication::GetSingleton().RunIMEOpenCandidateListEvent(); +} + +void CPythonIME::OnCloseCandidateList() +{ + IAbstractApplication::GetSingleton().RunIMECloseCandidateListEvent(); +} + +void CPythonIME::OnOpenReadingWnd() +{ + IAbstractApplication::GetSingleton().RunIMEOpenReadingWndEvent(); +} + +void CPythonIME::OnCloseReadingWnd() +{ + IAbstractApplication::GetSingleton().RunIMECloseReadingWndEvent(); +} diff --git a/source/UserInterface/PythonIME.h b/source/UserInterface/PythonIME.h new file mode 100644 index 0000000..4031ff8 --- /dev/null +++ b/source/UserInterface/PythonIME.h @@ -0,0 +1,36 @@ +#pragma once + +#include "../eterBase/Singleton.h" +#include "../eterlib/IME.h" + +class CPythonIME : + public IIMEEventSink, + public CIME, + public CSingleton +{ +public: + CPythonIME(); + virtual ~CPythonIME(); + + void MoveLeft(); + void MoveRight(); + void MoveHome(); + void MoveEnd(); + void SetCursorPosition(int iPosition); + void Delete(); + + void Create(HWND hWnd); + +protected: + virtual void OnTab(); + virtual void OnReturn(); + virtual void OnEscape(); + + virtual bool OnWM_CHAR( WPARAM wParam, LPARAM lParam ); + virtual void OnUpdate(); + virtual void OnChangeCodePage(); + virtual void OnOpenCandidateList(); + virtual void OnCloseCandidateList(); + virtual void OnOpenReadingWnd(); + virtual void OnCloseReadingWnd(); +}; diff --git a/source/UserInterface/PythonIMEModule.cpp b/source/UserInterface/PythonIMEModule.cpp new file mode 100644 index 0000000..cfc6845 --- /dev/null +++ b/source/UserInterface/PythonIMEModule.cpp @@ -0,0 +1,289 @@ +#include "StdAfx.h" +#include "PythonIME.h" +#include "PythonApplication.h" + +PyObject* imeEnable(PyObject* poSelf, PyObject* poArgs) +{ + CPythonIME::Instance().Initialize(CPythonApplication::Instance().GetWindowHandle()); + return Py_BuildNone(); +} + +PyObject* imeDisable(PyObject* poSelf, PyObject* poArgs) +{ + CPythonIME::Instance().Uninitialize(); + return Py_BuildNone(); +} + +PyObject* imeEnableCaptureInput(PyObject* poSelf, PyObject* poArgs) +{ + CPythonIME::Instance().EnableCaptureInput(); + return Py_BuildNone(); +} + +PyObject* imeDisableCaptureInput(PyObject* poSelf, PyObject* poArgs) +{ + CPythonIME::Instance().DisableCaptureInput(); + return Py_BuildNone(); +} + +PyObject* imeSetMax(PyObject* poSelf, PyObject* poArgs) +{ + int iMax; + if (!PyTuple_GetInteger(poArgs, 0, &iMax)) + return Py_BuildException(); + + CPythonIME::Instance().SetMax(iMax); + return Py_BuildNone(); +} + +PyObject* imeSetUserMax(PyObject* poSelf, PyObject* poArgs) +{ + int iMax; + if (!PyTuple_GetInteger(poArgs, 0, &iMax)) + return Py_BuildException(); + + CPythonIME::Instance().SetUserMax(iMax); + return Py_BuildNone(); +} + +PyObject* imeSetText(PyObject* poSelf, PyObject* poArgs) +{ + char* szText; + if (!PyTuple_GetString(poArgs, 0, &szText)) + return Py_BuildException(); + + CPythonIME::Instance().SetText(szText, strlen(szText)); + return Py_BuildNone(); +} + +PyObject* imeGetText(PyObject* poSelf, PyObject* poArgs) +{ + int bCodePage; + if (!PyTuple_GetInteger(poArgs, 0, &bCodePage)) + bCodePage = 0; + + std::string strText; + CPythonIME::Instance().GetText(strText, bCodePage ? true : false); + return Py_BuildValue("s", strText.c_str()); +} + +PyObject* imeGetCodePage(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildValue("i", CPythonIME::Instance().GetCodePage()); +} + +PyObject* imeGetCandidateCount(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildValue("i", CPythonIME::Instance().GetCandidatePageCount()); +} + +PyObject* imeGetCandidate(PyObject* poSelf, PyObject* poArgs) +{ + int index; + if (!PyTuple_GetInteger(poArgs, 0, &index)) + return Py_BuildException(); + + std::string strText; + int iLength = CPythonIME::Instance().GetCandidate(index, strText); + return Py_BuildValue("si", strText.c_str(), iLength); +} + +PyObject* imeGetCandidateSelection(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildValue("i", CPythonIME::Instance().GetCandidateSelection()); +} + +PyObject* imeGetReading(PyObject* poSelf, PyObject* poArgs) +{ + std::string strText; + CPythonIME::Instance().GetReading(strText); + return Py_BuildValue("s", strText.c_str()); +} + +PyObject* imeGetReadingError(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildValue("i", CPythonIME::Instance().GetReadingError()); +} + +PyObject* imeEnableIME(PyObject* poSelf, PyObject* poArgs) +{ + CPythonIME::Instance().EnableIME(); + return Py_BuildNone(); +} + +PyObject* imeDisableIME(PyObject* poSelf, PyObject* poArgs) +{ + CPythonIME::Instance().DisableIME(); + return Py_BuildNone(); +} + +PyObject* imeSetInputMode(PyObject* poSelf, PyObject* poArgs) +{ + int mode; + if (!PyTuple_GetInteger(poArgs, 0, &mode)) + return Py_BuildException(); + + CPythonIME::Instance().SetInputMode(mode); + return Py_BuildNone(); +} + +PyObject * imeSetNumberMode(PyObject* poSelf, PyObject* poArgs) +{ + CPythonIME::Instance().SetNumberMode(); + return Py_BuildNone(); +} + +PyObject * imeAddExceptKey(PyObject* poSelf, PyObject* poArgs) +{ + int key; + if (!PyTuple_GetInteger(poArgs, 0, &key)) + return Py_BuildException(); + + CPythonIME::Instance().AddExceptKey(key); + return Py_BuildNone(); +} + +PyObject * imeClearExceptKey(PyObject* poSelf, PyObject* poArgs) +{ + CPythonIME::Instance().ClearExceptKey(); + return Py_BuildNone(); +} + +PyObject * imeSetStringMode(PyObject* poSelf, PyObject* poArgs) +{ + CPythonIME::Instance().SetStringMode(); + return Py_BuildNone(); +} + +PyObject* imeGetInputMode(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildValue("i", CPythonIME::Instance().GetInputMode()); +} + +PyObject* imeMoveLeft(PyObject* poSelf, PyObject* poArgs) +{ + CPythonIME::Instance().MoveLeft(); + + return Py_BuildNone(); +} +PyObject* imeMoveRight(PyObject* poSelf, PyObject* poArgs) +{ + CPythonIME::Instance().MoveRight(); + + return Py_BuildNone(); +} + +PyObject* imeMoveHome(PyObject* poSelf, PyObject* poArgs) +{ + CPythonIME::Instance().MoveHome(); + + return Py_BuildNone(); +} +PyObject* imeMoveEnd(PyObject* poSelf, PyObject* poArgs) +{ + CPythonIME::Instance().MoveEnd(); + + return Py_BuildNone(); +} + +PyObject* imeSetCursorPosition(PyObject* poSelf, PyObject* poArgs) +{ + int iPosition; + if (!PyTuple_GetInteger(poArgs, 0, &iPosition)) + return Py_BuildException(); + + CPythonIME::Instance().SetCursorPosition(iPosition); + + return Py_BuildNone(); +} + +PyObject* imeDelete(PyObject* poSelf, PyObject* poArgs) +{ + CPythonIME::Instance().Delete(); + + return Py_BuildNone(); +} + +PyObject* imePasteTextFromClipBoard(PyObject* poSelf, PyObject* poArgs) +{ + CPythonIME::Instance().PasteTextFromClipBoard(); + return Py_BuildNone(); +} + +PyObject* imeEnablePaste(PyObject* poSelf, PyObject* poArgs) +{ + int iFlag; + if (!PyTuple_GetInteger(poArgs, 0, &iFlag)) + return Py_BuildException(); + + CPythonIME::Instance().EnablePaste(iFlag ? true : false); + return Py_BuildNone(); +} + +PyObject* imePasteString(PyObject * poSelf, PyObject * poArgs) +{ + char* szText; + if (!PyTuple_GetString(poArgs, 0, &szText)) + return Py_BuildException(); + CPythonIME::Instance().PasteString(szText); + return Py_BuildNone(); +} + +PyObject* imePasteBackspace(PyObject * poSelf, PyObject * poArgs) +{ + CPythonIME::Instance().WMChar(NULL, WM_CHAR, 0x08, NULL); + return Py_BuildNone(); +} + +PyObject* imePasteReturn(PyObject * poSelf, PyObject * poArgs) +{ + CPythonIME::Instance().WMChar(NULL, WM_CHAR, 0x0D, NULL); + return Py_BuildNone(); +} + +void initime() +{ + static PyMethodDef s_methods[] = + { + { "Enable", imeEnable, METH_VARARGS }, + { "Disable", imeDisable, METH_VARARGS }, + + { "EnableCaptureInput", imeEnableCaptureInput, METH_VARARGS }, + { "DisableCaptureInput", imeDisableCaptureInput, METH_VARARGS }, + { "SetMax", imeSetMax, METH_VARARGS }, + { "SetUserMax", imeSetUserMax, METH_VARARGS }, + { "SetText", imeSetText, METH_VARARGS }, + { "GetText", imeGetText, METH_VARARGS }, + { "GetCodePage", imeGetCodePage, METH_VARARGS }, + { "GetCandidateCount", imeGetCandidateCount, METH_VARARGS }, + { "GetCandidate", imeGetCandidate, METH_VARARGS }, + { "GetCandidateSelection", imeGetCandidateSelection, METH_VARARGS }, + { "GetReading", imeGetReading, METH_VARARGS }, + { "GetReadingError", imeGetReadingError, METH_VARARGS }, + { "EnableIME", imeEnableIME, METH_VARARGS }, + { "DisableIME", imeDisableIME, METH_VARARGS }, + { "GetInputMode", imeGetInputMode, METH_VARARGS }, + { "SetInputMode", imeSetInputMode, METH_VARARGS }, + + { "SetNumberMode", imeSetNumberMode, METH_VARARGS }, + { "SetStringMode", imeSetStringMode, METH_VARARGS }, + { "AddExceptKey", imeAddExceptKey, METH_VARARGS }, + { "ClearExceptKey", imeClearExceptKey, METH_VARARGS }, + + { "MoveLeft", imeMoveLeft, METH_VARARGS }, + { "MoveRight", imeMoveRight, METH_VARARGS }, + { "MoveHome", imeMoveHome, METH_VARARGS }, + { "MoveEnd", imeMoveEnd, METH_VARARGS }, + { "SetCursorPosition", imeSetCursorPosition, METH_VARARGS }, + { "Delete", imeDelete, METH_VARARGS }, + { "PasteString", imePasteString, METH_VARARGS }, + { "PasteBackspace", imePasteBackspace, METH_VARARGS }, + { "PasteReturn", imePasteReturn, METH_VARARGS }, + { "PasteTextFromClipBoard", imePasteTextFromClipBoard, METH_VARARGS }, + { "EnablePaste", imeEnablePaste, METH_VARARGS }, + + { NULL, NULL, NULL }, + }; + + Py_InitModule("ime", s_methods); +} \ No newline at end of file diff --git a/source/UserInterface/PythonItem.cpp b/source/UserInterface/PythonItem.cpp new file mode 100644 index 0000000..9248523 --- /dev/null +++ b/source/UserInterface/PythonItem.cpp @@ -0,0 +1,763 @@ +#include "stdafx.h" +#include "../eterlib/GrpMath.h" +#include "../gamelib/ItemManager.h" +#include "../EffectLib/EffectManager.h" +#include "PythonBackground.h" + +#include "pythonitem.h" +#include "PythonTextTail.h" + +const float c_fDropStartHeight = 100.0f; +const float c_fDropTime = 0.5f; + +std::string CPythonItem::TGroundItemInstance::ms_astDropSoundFileName[DROPSOUND_NUM]; + +void CPythonItem::GetInfo(std::string* pstInfo) +{ + char szInfo[256]; + sprintf(szInfo, "Item: Inst %d, Pool %d", m_GroundItemInstanceMap.size(), m_GroundItemInstancePool.GetCapacity()); + + pstInfo->append(szInfo); +} + +void CPythonItem::TGroundItemInstance::Clear() +{ + stOwnership = ""; + ThingInstance.Clear(); + CEffectManager::Instance().DestroyEffectInstance(dwEffectInstanceIndex); +} + +void CPythonItem::TGroundItemInstance::__PlayDropSound(DWORD eItemType, const D3DXVECTOR3& c_rv3Pos) +{ + if (eItemType>=DROPSOUND_NUM) + return; + + CSoundManager::Instance().PlaySound3D(c_rv3Pos.x, c_rv3Pos.y, c_rv3Pos.z, ms_astDropSoundFileName[eItemType].c_str()); +} + +bool CPythonItem::TGroundItemInstance::Update() +{ + if (bAnimEnded) + return false; + if (dwEndTime < CTimer::Instance().GetCurrentMillisecond()) + { + ThingInstance.SetRotationQuaternion(qEnd); + + /*D3DXVECTOR3 v3Adjust = -v3Center; + D3DXMATRIX mat; + D3DXMatrixRotationYawPitchRoll(&mat, + D3DXToRadian(rEnd.y), + D3DXToRadian(rEnd.x), + D3DXToRadian(rEnd.z)); + D3DXVec3TransformCoord(&v3Adjust,&v3Adjust,&mat);*/ + + D3DXQUATERNION qAdjust(-v3Center.x, -v3Center.y, -v3Center.z, 0.0f); + D3DXQUATERNION qc; + D3DXQuaternionConjugate(&qc, &qEnd); + D3DXQuaternionMultiply(&qAdjust,&qAdjust,&qEnd); + D3DXQuaternionMultiply(&qAdjust,&qc,&qAdjust); + + ThingInstance.SetPosition(v3EndPosition.x+qAdjust.x, + v3EndPosition.y+qAdjust.y, + v3EndPosition.z+qAdjust.z); + //ThingInstance.Update(); + bAnimEnded = true; + + __PlayDropSound(eDropSoundType, v3EndPosition); + } + else + { + DWORD time = CTimer::Instance().GetCurrentMillisecond() - dwStartTime; + DWORD etime = dwEndTime - CTimer::Instance().GetCurrentMillisecond(); + float rate = time * 1.0f / (dwEndTime - dwStartTime); + + D3DXVECTOR3 v3NewPosition=v3EndPosition;// = rate*(v3EndPosition - v3StartPosition) + v3StartPosition; + v3NewPosition.z += 100-100*rate*(3*rate-2);//-100*(rate-1)*(3*rate+2); + + D3DXQUATERNION q; + D3DXQuaternionRotationAxis(&q, &v3RotationAxis, etime * 0.03f *(-1+rate*(3*rate-2))); + //ThingInstance.SetRotation(rEnd.y + etime*rStart.y, rEnd.x + etime*rStart.x, rEnd.z + etime*rStart.z); + D3DXQuaternionMultiply(&q,&qEnd,&q); + + ThingInstance.SetRotationQuaternion(q); + D3DXQUATERNION qAdjust(-v3Center.x, -v3Center.y, -v3Center.z, 0.0f); + D3DXQUATERNION qc; + D3DXQuaternionConjugate(&qc, &q); + D3DXQuaternionMultiply(&qAdjust,&qAdjust,&q); + D3DXQuaternionMultiply(&qAdjust,&qc,&qAdjust); + + ThingInstance.SetPosition(v3NewPosition.x+qAdjust.x, + v3NewPosition.y+qAdjust.y, + v3NewPosition.z+qAdjust.z); + + /*D3DXVECTOR3 v3Adjust = -v3Center; + D3DXMATRIX mat; + D3DXMatrixRotationYawPitchRoll(&mat, + D3DXToRadian(rEnd.y + etime*rStart.y), + D3DXToRadian(rEnd.x + etime*rStart.x), + D3DXToRadian(rEnd.z + etime*rStart.z)); + + D3DXVec3TransformCoord(&v3Adjust,&v3Adjust,&mat); + //Tracef("%f %f %f\n",v3Adjust.x,v3Adjust.y,v3Adjust.z); + v3NewPosition += v3Adjust; + ThingInstance.SetPosition(v3NewPosition.x, v3NewPosition.y, v3NewPosition.z);*/ + } + ThingInstance.Transform(); + ThingInstance.Deform(); + return !bAnimEnded; +} + +void CPythonItem::Update(const POINT& c_rkPtMouse) +{ + TGroundItemInstanceMap::iterator itor = m_GroundItemInstanceMap.begin(); + for(; itor != m_GroundItemInstanceMap.end(); ++itor) + { + itor->second->Update(); + } + + m_dwPickedItemID=__Pick(c_rkPtMouse); +} + +void CPythonItem::Render() +{ + CPythonGraphic::Instance().SetDiffuseOperation(); + TGroundItemInstanceMap::iterator itor = m_GroundItemInstanceMap.begin(); + for (; itor != m_GroundItemInstanceMap.end(); ++itor) + { + CGraphicThingInstance & rInstance = itor->second->ThingInstance; + //rInstance.Update(); + rInstance.Render(); + rInstance.BlendRender(); + } +} + +void CPythonItem::SetUseSoundFileName(DWORD eItemType, const std::string& c_rstFileName) +{ + if (eItemType>=USESOUND_NUM) + return; + + //Tracenf("SetUseSoundFile %d : %s", eItemType, c_rstFileName.c_str()); + + m_astUseSoundFileName[eItemType]=c_rstFileName; +} + +void CPythonItem::SetDropSoundFileName(DWORD eItemType, const std::string& c_rstFileName) +{ + if (eItemType>=DROPSOUND_NUM) + return; + + Tracenf("SetDropSoundFile %d : %s", eItemType, c_rstFileName.c_str()); + + SGroundItemInstance::ms_astDropSoundFileName[eItemType]=c_rstFileName; +} + +void CPythonItem::PlayUseSound(DWORD dwItemID) +{ + //CItemManager& rkItemMgr=CItemManager::Instance(); + + CItemData* pkItemData; + if (!CItemManager::Instance().GetItemDataPointer(dwItemID, &pkItemData)) + return; + + DWORD eItemType=__GetUseSoundType(*pkItemData); + if (eItemType==USESOUND_NONE) + return; + if (eItemType>=USESOUND_NUM) + return; + + CSoundManager::Instance().PlaySound2D(m_astUseSoundFileName[eItemType].c_str()); +} + + +void CPythonItem::PlayDropSound(DWORD dwItemID) +{ + //CItemManager& rkItemMgr=CItemManager::Instance(); + + CItemData* pkItemData; + if (!CItemManager::Instance().GetItemDataPointer(dwItemID, &pkItemData)) + return; + + DWORD eItemType=__GetDropSoundType(*pkItemData); + if (eItemType>=DROPSOUND_NUM) + return; + + CSoundManager::Instance().PlaySound2D(SGroundItemInstance::ms_astDropSoundFileName[eItemType].c_str()); +} + +void CPythonItem::PlayUsePotionSound() +{ + CSoundManager::Instance().PlaySound2D(m_astUseSoundFileName[USESOUND_POTION].c_str()); +} + +DWORD CPythonItem::__GetDropSoundType(const CItemData& c_rkItemData) +{ + switch (c_rkItemData.GetType()) + { + case CItemData::ITEM_TYPE_WEAPON: + switch (c_rkItemData.GetWeaponType()) + { + case CItemData::WEAPON_BOW: + return DROPSOUND_BOW; + break; + case CItemData::WEAPON_ARROW: + return DROPSOUND_DEFAULT; + break; + default: + return DROPSOUND_WEAPON; + break; + } + break; + case CItemData::ITEM_TYPE_ARMOR: + switch (c_rkItemData.GetSubType()) + { + case CItemData::ARMOR_NECK: + case CItemData::ARMOR_EAR: + return DROPSOUND_ACCESSORY; + break; + case CItemData::ARMOR_BODY: + return DROPSOUND_ARMOR; + default: + return DROPSOUND_DEFAULT; + break; + } + break; + default: + return DROPSOUND_DEFAULT; + break; + } + + return DROPSOUND_DEFAULT; +} + + +DWORD CPythonItem::__GetUseSoundType(const CItemData& c_rkItemData) +{ + switch (c_rkItemData.GetType()) + { + case CItemData::ITEM_TYPE_WEAPON: + switch (c_rkItemData.GetWeaponType()) + { + case CItemData::WEAPON_BOW: + return USESOUND_BOW; + break; + case CItemData::WEAPON_ARROW: + return USESOUND_DEFAULT; + break; + default: + return USESOUND_WEAPON; + break; + } + break; + case CItemData::ITEM_TYPE_ARMOR: + switch (c_rkItemData.GetSubType()) + { + case CItemData::ARMOR_NECK: + case CItemData::ARMOR_EAR: + return USESOUND_ACCESSORY; + break; + case CItemData::ARMOR_BODY: + return USESOUND_ARMOR; + default: + return USESOUND_DEFAULT; + break; + } + break; + case CItemData::ITEM_TYPE_USE: + switch (c_rkItemData.GetSubType()) + { + case CItemData::USE_ABILITY_UP: + return USESOUND_POTION; + break; + case CItemData::USE_POTION: + return USESOUND_NONE; + break; + case CItemData::USE_TALISMAN: + return USESOUND_PORTAL; + break; + default: + return USESOUND_DEFAULT; + break; + } + break; + default: + return USESOUND_DEFAULT; + break; + } + + return USESOUND_DEFAULT; +} + +void CPythonItem::CreateItem(DWORD dwVirtualID, DWORD dwVirtualNumber, float x, float y, float z, bool bDrop) +{ + //CItemManager& rkItemMgr=CItemManager::Instance(); + + CItemData * pItemData; + if (!CItemManager::Instance().GetItemDataPointer(dwVirtualNumber, &pItemData)) + return; + + CGraphicThing* pItemModel = pItemData->GetDropModelThing(); + + TGroundItemInstance * pGroundItemInstance = m_GroundItemInstancePool.Alloc(); + pGroundItemInstance->dwVirtualNumber = dwVirtualNumber; + + bool bStabGround = false; + + if (bDrop) + { + z = CPythonBackground::Instance().GetHeight(x, y) + 10.0f; + + if (pItemData->GetType()==CItemData::ITEM_TYPE_WEAPON && + (pItemData->GetWeaponType() == CItemData::WEAPON_SWORD || + pItemData->GetWeaponType() == CItemData::WEAPON_ARROW)) + bStabGround = true; + + bStabGround = false; + pGroundItemInstance->bAnimEnded = false; + } + else + { + pGroundItemInstance->bAnimEnded = true; + } + + { + // attaching effect + CEffectManager & rem =CEffectManager::Instance(); + pGroundItemInstance->dwEffectInstanceIndex = + rem.CreateEffect(m_dwDropItemEffectID, D3DXVECTOR3(x, -y, z), D3DXVECTOR3(0,0,0)); + + pGroundItemInstance->eDropSoundType=__GetDropSoundType(*pItemData); + } + + + D3DXVECTOR3 normal; + if (!CPythonBackground::Instance().GetNormal(int(x),int(y),&normal)) + normal = D3DXVECTOR3(0.0f,0.0f,1.0f); + + pGroundItemInstance->ThingInstance.Clear(); + pGroundItemInstance->ThingInstance.ReserveModelThing(1); + pGroundItemInstance->ThingInstance.ReserveModelInstance(1); + pGroundItemInstance->ThingInstance.RegisterModelThing(0, pItemModel); + pGroundItemInstance->ThingInstance.SetModelInstance(0, 0, 0); + if (bDrop) + { + pGroundItemInstance->v3EndPosition = D3DXVECTOR3(x,-y,z); + pGroundItemInstance->ThingInstance.SetPosition(0,0,0); + } + else + pGroundItemInstance->ThingInstance.SetPosition(x, -y, z); + + pGroundItemInstance->ThingInstance.Update(); + pGroundItemInstance->ThingInstance.Transform(); + pGroundItemInstance->ThingInstance.Deform(); + + if (bDrop) + { + D3DXVECTOR3 vMin, vMax; + pGroundItemInstance->ThingInstance.GetBoundBox(&vMin,&vMax); + pGroundItemInstance->v3Center = (vMin + vMax) * 0.5f; + + std::pair f[3] = + { + std::make_pair(vMax.x - vMin.x,0), + std::make_pair(vMax.y - vMin.y,1), + std::make_pair(vMax.z - vMin.z,2) + }; + + std::sort(f,f+3); + + //int no_rotation_axis=-1; + + D3DXVECTOR3 rEnd; + + if (/*f[1].first-f[0].first < (f[2].first-f[0].first)*0.30f*/ bStabGround) + { + // + if (f[2].second == 0) // axis x + { + rEnd.y = 90.0f + frandom(-15.0f, 15.0f); + rEnd.x = frandom(0.0f, 360.0f); + rEnd.z = frandom(-15.0f, 15.0f); + } + else if (f[2].second == 1) // axis y + { + rEnd.y = frandom(0.0f, 360.0f); + rEnd.x = frandom(-15.0f, 15.0f); + rEnd.z = 180.0f + frandom(-15.0f, 15.0f); + } + else // axis z + { + rEnd.y = 180.0f + frandom(-15.0f, 15.0f); + rEnd.x = 0.0f+frandom(-15.0f, 15.0f); + rEnd.z = frandom(0.0f, 360.0f); + } + } + else + { + // + // 븻 + if (f[0].second == 0) + { + // y,z = by normal + pGroundItemInstance->qEnd = + RotationArc( + D3DXVECTOR3( + ((float)(random()%2))*2-1+frandom(-0.1f,0.1f), + 0+frandom(-0.1f,0.1f), + 0+frandom(-0.1f,0.1f)), + D3DXVECTOR3(0,0,1)/*normal*/); + } + else if (f[0].second == 1) + { + pGroundItemInstance->qEnd = + RotationArc( + D3DXVECTOR3( + 0+frandom(-0.1f,0.1f), + ((float)(random()%2))*2-1+frandom(-0.1f,0.1f), + 0+frandom(-0.1f,0.1f)), + D3DXVECTOR3(0,0,1)/*normal*/); + } + else + { + pGroundItemInstance->qEnd = + RotationArc( + D3DXVECTOR3( + 0+frandom(-0.1f,0.1f), + 0+frandom(-0.1f,0.1f), + ((float)(random()%2))*2-1+frandom(-0.1f,0.1f)), + D3DXVECTOR3(0,0,1)/*normal*/); + } + } + //D3DXQuaternionRotationYawPitchRoll(&pGroundItemInstance->qEnd, rEnd.y, rEnd.x, rEnd.z ); + float rot = frandom(0, 2*3.1415926535f); + D3DXQUATERNION q(0,0,cosf(rot),sinf(rot)); + D3DXQuaternionMultiply(&pGroundItemInstance->qEnd, &pGroundItemInstance->qEnd, &q); + q = RotationArc(D3DXVECTOR3(0,0,1),normal); + D3DXQuaternionMultiply(&pGroundItemInstance->qEnd, &pGroundItemInstance->qEnd, &q); + + pGroundItemInstance->dwStartTime = CTimer::Instance().GetCurrentMillisecond(); + pGroundItemInstance->dwEndTime = pGroundItemInstance->dwStartTime+300; + pGroundItemInstance->v3RotationAxis.x = sinf(rot+0);//frandom(0.4f,0.7f) * (2*(int)(random()%2) - 1); + pGroundItemInstance->v3RotationAxis.y = cosf(rot+0);//frandom(0.4f,0.7f) * (2*(int)(random()%2) - 1); + pGroundItemInstance->v3RotationAxis.z = 0;//frandom(0.4f,0.7f) * (2*(int)(random()%2) - 1); + + /* + switch (no_rotation_axis) + { + case 0: + pGroundItemInstance->rStart.x = 0; + break; + case 1: + pGroundItemInstance->rStart.y = 0; + break; + case 2: + pGroundItemInstance->rStart.z = 0; + break; + }*/ + + D3DXVECTOR3 v3Adjust = -pGroundItemInstance->v3Center; + D3DXMATRIX mat; + D3DXMatrixRotationQuaternion(&mat, &pGroundItemInstance->qEnd); + /*D3DXMatrixRotationYawPitchRoll(&mat, + D3DXToRadian(pGroundItemInstance->rEnd.y), + D3DXToRadian(pGroundItemInstance->rEnd.x), + D3DXToRadian(pGroundItemInstance->rEnd.z));*/ + + D3DXVec3TransformCoord(&v3Adjust,&v3Adjust,&mat); + //Tracef("%f %f %f\n",v3Adjust.x,v3Adjust.y,v3Adjust.z); + //pGroundItemInstance->v3EndPosition += v3Adjust; + //pGroundItemInstance->rEnd.z += pGroundItemInstance->v3Center.z; + } + + pGroundItemInstance->ThingInstance.Show(); + + m_GroundItemInstanceMap.insert(TGroundItemInstanceMap::value_type(dwVirtualID, pGroundItemInstance)); + + CPythonTextTail& rkTextTail=CPythonTextTail::Instance(); + rkTextTail.RegisterItemTextTail( + dwVirtualID, + pItemData->GetName(), + &pGroundItemInstance->ThingInstance); +} + +void CPythonItem::SetOwnership(DWORD dwVID, const char * c_pszName) +{ + TGroundItemInstanceMap::iterator itor = m_GroundItemInstanceMap.find(dwVID); + + if (m_GroundItemInstanceMap.end() == itor) + return; + + TGroundItemInstance * pGroundItemInstance = itor->second; + pGroundItemInstance->stOwnership.assign(c_pszName); + + CPythonTextTail& rkTextTail = CPythonTextTail::Instance(); + rkTextTail.SetItemTextTailOwner(dwVID, c_pszName); +} + +bool CPythonItem::GetOwnership(DWORD dwVID, const char ** c_pszName) +{ + TGroundItemInstanceMap::iterator itor = m_GroundItemInstanceMap.find(dwVID); + + if (m_GroundItemInstanceMap.end() == itor) + return false; + + TGroundItemInstance * pGroundItemInstance = itor->second; + *c_pszName = pGroundItemInstance->stOwnership.c_str(); + + return true; +} + +void CPythonItem::DeleteAllItems() +{ + CPythonTextTail& rkTextTail=CPythonTextTail::Instance(); + + TGroundItemInstanceMap::iterator i; + for (i= m_GroundItemInstanceMap.begin(); i!=m_GroundItemInstanceMap.end(); ++i) + { + TGroundItemInstance* pGroundItemInst=i->second; + rkTextTail.DeleteItemTextTail(i->first); + pGroundItemInst->Clear(); + m_GroundItemInstancePool.Free(pGroundItemInst); + } + m_GroundItemInstanceMap.clear(); +} + +void CPythonItem::DeleteItem(DWORD dwVirtualID) +{ + TGroundItemInstanceMap::iterator itor = m_GroundItemInstanceMap.find(dwVirtualID); + if (m_GroundItemInstanceMap.end() == itor) + return; + + TGroundItemInstance * pGroundItemInstance = itor->second; + pGroundItemInstance->Clear(); + m_GroundItemInstancePool.Free(pGroundItemInstance); + m_GroundItemInstanceMap.erase(itor); + + // Text Tail + CPythonTextTail::Instance().DeleteItemTextTail(dwVirtualID); +} + + +bool CPythonItem::GetCloseMoney(const TPixelPosition & c_rPixelPosition, DWORD * pdwItemID, DWORD dwDistance) +{ + DWORD dwCloseItemID = 0; + DWORD dwCloseItemDistance = 1000 * 1000; + + TGroundItemInstanceMap::iterator i; + for (i = m_GroundItemInstanceMap.begin(); i != m_GroundItemInstanceMap.end(); ++i) + { + TGroundItemInstance * pInstance = i->second; + + if (pInstance->dwVirtualNumber!=VNUM_MONEY) + continue; + + DWORD dwxDistance = DWORD(c_rPixelPosition.x-pInstance->v3EndPosition.x); + DWORD dwyDistance = DWORD(c_rPixelPosition.y-(-pInstance->v3EndPosition.y)); + DWORD dwDistance = DWORD(dwxDistance*dwxDistance + dwyDistance*dwyDistance); + + if (dwxDistance*dwxDistance + dwyDistance*dwyDistance < dwCloseItemDistance) + { + dwCloseItemID = i->first; + dwCloseItemDistance = dwDistance; + } + } + + if (dwCloseItemDistance>float(dwDistance)*float(dwDistance)) + return false; + + *pdwItemID=dwCloseItemID; + + return true; +} + +// bool CPythonItem::GetCloseItem(const TPixelPosition & c_rPixelPosition, DWORD * pdwItemID, DWORD dwDistance) +// { + // DWORD dwCloseItemID = 0; + // DWORD dwCloseItemDistance = 1000 * 1000; + + // TGroundItemInstanceMap::iterator i; + // for (i = m_GroundItemInstanceMap.begin(); i != m_GroundItemInstanceMap.end(); ++i) + // { + // TGroundItemInstance * pInstance = i->second; + + // DWORD dwxDistance = DWORD(c_rPixelPosition.x-pInstance->v3EndPosition.x); + // DWORD dwyDistance = DWORD(c_rPixelPosition.y-(-pInstance->v3EndPosition.y)); + // DWORD dwDistance = DWORD(dwxDistance*dwxDistance + dwyDistance*dwyDistance); + + // if (dwxDistance*dwxDistance + dwyDistance*dwyDistance < dwCloseItemDistance) + // { + // dwCloseItemID = i->first; + // dwCloseItemDistance = dwDistance; + // } + // } + + // if (dwCloseItemDistance>float(dwDistance)*float(dwDistance)) + // return false; + + // *pdwItemID=dwCloseItemID; + + // return true; +// } + +// Fix for picking up items +// https://metin2.dev/board/topic/24691-fix-pickup-distances-bug/ +int DISTANCE_APPROX(int dx, int dy) +{ + int min, max; + + if (dx < 0) + dx = -dx; + + if (dy < 0) + dy = -dy; + + if (dx < dy) + { + min = dx; + max = dy; + } + else + { + min = dy; + max = dx; + } + + // coefficients equivalent to ( 123/128 * max ) and ( 51/128 * min ) + return (((max << 8) + (max << 3) - (max << 4) - (max << 1) + + (min << 7) - (min << 5) + (min << 3) - (min << 1)) >> 8); +} + +bool CPythonItem::GetCloseItem(const TPixelPosition& c_rPixelPosition, DWORD* pdwItemID, DWORD dwDistance) +{ + DWORD dwCloseItemID = 0; + DWORD dwCloseItemDistance = 0; + int aproMin = 0; + + TGroundItemInstanceMap::iterator i; + for (i = m_GroundItemInstanceMap.begin(); i != m_GroundItemInstanceMap.end(); ++i) + { + TGroundItemInstance* pInstance = i->second; + + int iDist = DISTANCE_APPROX((int)c_rPixelPosition.x - (int)pInstance->v3EndPosition.x, (int)c_rPixelPosition.y - (-(int)pInstance->v3EndPosition.y)); + if (aproMin == 0) + aproMin = iDist; + if (aproMin >= iDist) { + aproMin = iDist; + dwCloseItemID = i->first; + dwCloseItemDistance = iDist; + } + } + + if (dwCloseItemDistance > 300) + return false; + + *pdwItemID = dwCloseItemID; + + return true; +} + +BOOL CPythonItem::GetGroundItemPosition(DWORD dwVirtualID, TPixelPosition * pPosition) +{ + TGroundItemInstanceMap::iterator itor = m_GroundItemInstanceMap.find(dwVirtualID); + if (m_GroundItemInstanceMap.end() == itor) + return FALSE; + + TGroundItemInstance * pInstance = itor->second; + + const D3DXVECTOR3& rkD3DVct3=pInstance->ThingInstance.GetPosition(); + + pPosition->x=+rkD3DVct3.x; + pPosition->y=-rkD3DVct3.y; + pPosition->z=+rkD3DVct3.z; + + return TRUE; +} + +DWORD CPythonItem::__Pick(const POINT& c_rkPtMouse) +{ + float fu, fv, ft; + + TGroundItemInstanceMap::iterator itor = m_GroundItemInstanceMap.begin(); + for (; itor != m_GroundItemInstanceMap.end(); ++itor) + { + TGroundItemInstance * pInstance = itor->second; + + if (pInstance->ThingInstance.Intersect(&fu, &fv, &ft)) + { + return itor->first; + } + } + + CPythonTextTail& rkTextTailMgr=CPythonTextTail::Instance(); + return rkTextTailMgr.Pick(c_rkPtMouse.x, c_rkPtMouse.y); +} + +bool CPythonItem::GetPickedItemID(DWORD* pdwPickedItemID) +{ + if (INVALID_ID==m_dwPickedItemID) + return false; + + *pdwPickedItemID=m_dwPickedItemID; + return true; +} + +DWORD CPythonItem::GetVirtualNumberOfGroundItem(DWORD dwVID) +{ + TGroundItemInstanceMap::iterator itor = m_GroundItemInstanceMap.find(dwVID); + + if (itor == m_GroundItemInstanceMap.end()) + return 0; + else + return itor->second->dwVirtualNumber; +} + +void CPythonItem::BuildNoGradeNameData(int iType) +{ + /* + CMapIterator itor = CItemManager::Instance().GetItemNameMapIterator(); + + m_NoGradeNameItemData.clear(); + m_NoGradeNameItemData.reserve(1024); + + while (++itor) + { + CItemData * pItemData = *itor; + if (iType == pItemData->GetType()) + m_NoGradeNameItemData.push_back(pItemData); + } + */ +} + +DWORD CPythonItem::GetNoGradeNameDataCount() +{ + return m_NoGradeNameItemData.size(); +} + +CItemData * CPythonItem::GetNoGradeNameDataPtr(DWORD dwIndex) +{ + if (dwIndex >= m_NoGradeNameItemData.size()) + return NULL; + + return m_NoGradeNameItemData[dwIndex]; +} + +void CPythonItem::Destroy() +{ + DeleteAllItems(); + m_GroundItemInstancePool.Clear(); +} + +void CPythonItem::Create() +{ + CEffectManager::Instance().RegisterEffect2("d:/ymir work/effect/etc/dropitem/dropitem.mse", &m_dwDropItemEffectID); +} + +CPythonItem::CPythonItem() +{ + m_GroundItemInstancePool.SetName("CDynamicPool"); + m_dwPickedItemID = INVALID_ID; +} + +CPythonItem::~CPythonItem() +{ + assert(m_GroundItemInstanceMap.empty()); +} \ No newline at end of file diff --git a/source/UserInterface/PythonItem.h b/source/UserInterface/PythonItem.h new file mode 100644 index 0000000..3b6b4b4 --- /dev/null +++ b/source/UserInterface/PythonItem.h @@ -0,0 +1,136 @@ +#pragma once + +// Note : ȭ Item Update Rendering å +// Ÿ Icon Image Instance Ŵ ұ ְ +// ⵵ ϴ - 2003. 01. 13. [levites] + +#include "../EterGrnLib/ThingInstance.h" + +class CItemData; + +class CPythonItem : public CSingleton +{ + public: + enum + { + INVALID_ID = 0xffffffff, + }; + + enum + { + VNUM_MONEY = 1, + }; + + enum + { + USESOUND_NONE, + USESOUND_DEFAULT, + USESOUND_ARMOR, + USESOUND_WEAPON, + USESOUND_BOW, + USESOUND_ACCESSORY, + USESOUND_POTION, + USESOUND_PORTAL, + USESOUND_NUM, + }; + + enum + { + DROPSOUND_DEFAULT, + DROPSOUND_ARMOR, + DROPSOUND_WEAPON, + DROPSOUND_BOW, + DROPSOUND_ACCESSORY, + DROPSOUND_NUM + }; + + typedef struct SGroundItemInstance + { + DWORD dwVirtualNumber; + D3DXVECTOR3 v3EndPosition; + + D3DXVECTOR3 v3RotationAxis; + D3DXQUATERNION qEnd; + D3DXVECTOR3 v3Center; + CGraphicThingInstance ThingInstance; + DWORD dwStartTime; + DWORD dwEndTime; + + DWORD eDropSoundType; + + bool bAnimEnded; + bool Update(); + void Clear(); + + DWORD dwEffectInstanceIndex; + std::string stOwnership; + + static void __PlayDropSound(DWORD eItemType, const D3DXVECTOR3& c_rv3Pos); + static std::string ms_astDropSoundFileName[DROPSOUND_NUM]; + + SGroundItemInstance() {} + virtual ~SGroundItemInstance() {} + } TGroundItemInstance; + + typedef std::map TGroundItemInstanceMap; + + public: + CPythonItem(void); + virtual ~CPythonItem(void); + + // Initialize + void Destroy(); + void Create(); + + void PlayUseSound(DWORD dwItemID); + void PlayDropSound(DWORD dwItemID); + void PlayUsePotionSound(); + + void SetUseSoundFileName(DWORD eItemType, const std::string& c_rstFileName); + void SetDropSoundFileName(DWORD eItemType, const std::string& c_rstFileName); + + void GetInfo(std::string* pstInfo); + + void DeleteAllItems(); + + void Render(); + void Update(const POINT& c_rkPtMouse); + + void CreateItem(DWORD dwVirtualID, DWORD dwVirtualNumber, float x, float y, float z, bool bDrop=true); + void DeleteItem(DWORD dwVirtualID); + void SetOwnership(DWORD dwVID, const char * c_pszName); + bool GetOwnership(DWORD dwVID, const char ** c_pszName); + + BOOL GetGroundItemPosition(DWORD dwVirtualID, TPixelPosition * pPosition); + + bool GetPickedItemID(DWORD* pdwPickedItemID); + + bool GetCloseItem(const TPixelPosition & c_rPixelPosition, DWORD* pdwItemID, DWORD dwDistance=300); + bool GetCloseMoney(const TPixelPosition & c_rPixelPosition, DWORD* dwItemID, DWORD dwDistance=300); + + DWORD GetVirtualNumberOfGroundItem(DWORD dwVID); + + void BuildNoGradeNameData(int iType); + DWORD GetNoGradeNameDataCount(); + CItemData * GetNoGradeNameDataPtr(DWORD dwIndex); + + protected: + DWORD __Pick(const POINT& c_rkPtMouse); + + DWORD __GetUseSoundType(const CItemData& c_rkItemData); + DWORD __GetDropSoundType(const CItemData& c_rkItemData); + + protected: + TGroundItemInstanceMap m_GroundItemInstanceMap; + CDynamicPool m_GroundItemInstancePool; + + DWORD m_dwDropItemEffectID; + DWORD m_dwPickedItemID; + + int m_nMouseX; + int m_nMouseY; + + std::string m_astUseSoundFileName[USESOUND_NUM]; + + std::vector m_NoGradeNameItemData; +}; \ No newline at end of file diff --git a/source/UserInterface/PythonItemModule.cpp b/source/UserInterface/PythonItemModule.cpp new file mode 100644 index 0000000..705b19e --- /dev/null +++ b/source/UserInterface/PythonItemModule.cpp @@ -0,0 +1,840 @@ +#include "StdAfx.h" +#include "PythonItem.h" + +#include "../gamelib/ItemManager.h" +#include "InstanceBase.h" +#include "AbstractApplication.h" + +extern int TWOHANDED_WEWAPON_ATT_SPEED_DECREASE_VALUE; + +PyObject * itemSetUseSoundFileName(PyObject * poSelf, PyObject * poArgs) +{ + int iUseSound; + if (!PyTuple_GetInteger(poArgs, 0, &iUseSound)) + return Py_BadArgument(); + + char* szFileName; + if (!PyTuple_GetString(poArgs, 1, &szFileName)) + return Py_BadArgument(); + + CPythonItem& rkItem=CPythonItem::Instance(); + rkItem.SetUseSoundFileName(iUseSound, szFileName); + return Py_BuildNone(); +} + +PyObject * itemSetDropSoundFileName(PyObject * poSelf, PyObject * poArgs) +{ + int iDropSound; + if (!PyTuple_GetInteger(poArgs, 0, &iDropSound)) + return Py_BadArgument(); + + char* szFileName; + if (!PyTuple_GetString(poArgs, 1, &szFileName)) + return Py_BadArgument(); + + CPythonItem& rkItem=CPythonItem::Instance(); + rkItem.SetDropSoundFileName(iDropSound, szFileName); + return Py_BuildNone(); +} + +PyObject * itemSelectItem(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BadArgument(); + + if (!CItemManager::Instance().SelectItemData(iIndex)) + { + TraceError("Cannot find item by %d", iIndex); + CItemManager::Instance().SelectItemData(60001); + } + + return Py_BuildNone(); +} + +PyObject * itemGetItemName(PyObject * poSelf, PyObject * poArgs) +{ + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pItemData) + return Py_BuildException("no selected item data"); + + return Py_BuildValue("s", pItemData->GetName()); +} + +PyObject * itemGetItemDescription(PyObject * poSelf, PyObject * poArgs) +{ + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pItemData) + return Py_BuildException("no selected item data"); + + return Py_BuildValue("s", pItemData->GetDescription()); +} + +PyObject * itemGetItemSummary(PyObject * poSelf, PyObject * poArgs) +{ + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pItemData) + return Py_BuildException("no selected item data"); + + return Py_BuildValue("s", pItemData->GetSummary()); +} + +PyObject * itemGetIconImage(PyObject * poSelf, PyObject * poArgs) +{ + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pItemData) + return Py_BuildException("no selected item data"); + +// if (CItemData::ITEM_TYPE_SKILLBOOK == pItemData->GetType()) +// { +// char szItemName[64+1]; +// _snprintf(szItemName, "d:/ymir work/ui/items/etc/book_%02d.sub", ); +// CGraphicImage * pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer(szItemName); +// } + + return Py_BuildValue("i", pItemData->GetIconImage()); +} + +PyObject * itemGetIconImageFileName(PyObject * poSelf, PyObject * poArgs) +{ + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pItemData) + return Py_BuildException("no selected item data"); + + CGraphicSubImage * pImage = pItemData->GetIconImage(); + if (!pImage) + return Py_BuildValue("s", "Noname"); + + return Py_BuildValue("s", pImage->GetFileName()); +} + +PyObject * itemGetItemSize(PyObject * poSelf, PyObject * poArgs) +{ + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pItemData) + return Py_BuildException("no selected item data"); + + return Py_BuildValue("(ii)", 1, pItemData->GetSize()); +} + +PyObject * itemGetItemType(PyObject * poSelf, PyObject * poArgs) +{ + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pItemData) + return Py_BuildException("no selected item data"); + + return Py_BuildValue("i", pItemData->GetType()); +} + +PyObject * itemGetItemSubType(PyObject * poSelf, PyObject * poArgs) +{ + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pItemData) + return Py_BuildException("no selected item data"); + + return Py_BuildValue("i", pItemData->GetSubType()); +} + +PyObject * itemGetIBuyItemPrice(PyObject * poSelf, PyObject * poArgs) +{ + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + + if (!pItemData) + return Py_BuildException("no selected item data"); + + return Py_BuildValue("i", pItemData->GetIBuyItemPrice()); +} + +PyObject * itemGetISellItemPrice(PyObject * poSelf, PyObject * poArgs) +{ + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + + if (!pItemData) + return Py_BuildException("no selected item data"); + + return Py_BuildValue("i", pItemData->GetISellItemPrice()); +} + + +PyObject * itemIsAntiFlag(PyObject * poSelf, PyObject * poArgs) +{ + int iFlag; + if (!PyTuple_GetInteger(poArgs, 0, &iFlag)) + return Py_BadArgument(); + + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pItemData) + return Py_BuildException("no selected item data"); + + return Py_BuildValue("i", pItemData->IsAntiFlag(iFlag)); +} + +PyObject * itemIsFlag(PyObject * poSelf, PyObject * poArgs) +{ + int iFlag; + if (!PyTuple_GetInteger(poArgs, 0, &iFlag)) + return Py_BadArgument(); + + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pItemData) + return Py_BuildException("no selected item data"); + + return Py_BuildValue("i", pItemData->IsFlag(iFlag)); +} + +PyObject * itemIsWearableFlag(PyObject * poSelf, PyObject * poArgs) +{ + int iFlag; + if (!PyTuple_GetInteger(poArgs, 0, &iFlag)) + return Py_BadArgument(); + + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pItemData) + return Py_BuildException("no selected item data"); + + return Py_BuildValue("i", pItemData->IsWearableFlag(iFlag)); +} + +PyObject * itemIs1GoldItem(PyObject * poSelf, PyObject * poArgs) +{ + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pItemData) + return Py_BuildException("no selected item data"); + + return Py_BuildValue("i", pItemData->IsFlag(CItemData::ITEM_FLAG_COUNT_PER_1GOLD)); +} + +PyObject * itemGetLimit(PyObject * poSelf, PyObject * poArgs) +{ + int iValueIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iValueIndex)) + return Py_BadArgument(); + + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pItemData) + return Py_BuildException("Not yet select item data"); + + CItemData::TItemLimit ItemLimit; + if (!pItemData->GetLimit(iValueIndex, &ItemLimit)) + return Py_BuildException(); + + return Py_BuildValue("ii", ItemLimit.bType, ItemLimit.lValue); +} + +PyObject * itemGetAffect(PyObject * poSelf, PyObject * poArgs) +{ + int iValueIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iValueIndex)) + return Py_BadArgument(); + + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pItemData) + return Py_BuildException("Not yet select item data"); + + CItemData::TItemApply ItemApply; + if (!pItemData->GetApply(iValueIndex, &ItemApply)) + return Py_BuildException(); + + if ((CItemData::APPLY_ATT_SPEED == ItemApply.bType) && (CItemData::ITEM_TYPE_WEAPON == pItemData->GetType()) && (CItemData::WEAPON_TWO_HANDED == pItemData->GetSubType())) + { + ItemApply.lValue -= TWOHANDED_WEWAPON_ATT_SPEED_DECREASE_VALUE; + } + + return Py_BuildValue("ii", ItemApply.bType, ItemApply.lValue); +} + +PyObject * itemGetValue(PyObject * poSelf, PyObject * poArgs) +{ + int iValueIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iValueIndex)) + return Py_BadArgument(); + + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pItemData) + return Py_BuildException("Not yet select item data"); + + return Py_BuildValue("i", pItemData->GetValue(iValueIndex)); +} + +PyObject * itemGetSocket(PyObject * poSelf, PyObject * poArgs) +{ + int iValueIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iValueIndex)) + return Py_BadArgument(); + + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pItemData) + return Py_BuildException("Not yet select item data"); + + return Py_BuildValue("i", pItemData->GetSocket(iValueIndex)); +} + +PyObject * itemGetIconInstance(PyObject * poSelf, PyObject * poArgs) +{ + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pItemData) + return Py_BuildException("Not yet select item data"); + + CGraphicSubImage * pImage = pItemData->GetIconImage(); + if (!pImage) + return Py_BuildException("Cannot get icon image by %d", pItemData->GetIndex()); + + CGraphicImageInstance * pImageInstance = CGraphicImageInstance::New(); + pImageInstance->SetImagePointer(pImage); + + return Py_BuildValue("i", pImageInstance); +} + +PyObject * itemDeleteIconInstance(PyObject * poSelf, PyObject * poArgs) +{ + int iHandle; + if (!PyTuple_GetInteger(poArgs, 0, &iHandle)) + return Py_BadArgument(); + + CGraphicImageInstance::Delete((CGraphicImageInstance *) iHandle); + + return Py_BuildNone(); +} + +PyObject * itemIsEquipmentVID(PyObject * poSelf, PyObject * poArgs) +{ + int iItemVID; + if (!PyTuple_GetInteger(poArgs, 0, &iItemVID)) + return Py_BadArgument(); + + CItemManager::Instance().SelectItemData(iItemVID); + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pItemData) + return Py_BuildException("Not yet select item data"); + + return Py_BuildValue("i", pItemData->IsEquipment()); +} + +// 2005.05.20.myevan. USE_TYPE üũ +PyObject* itemGetUseType(PyObject * poSelf, PyObject * poArgs) +{ + int iItemVID; + if (!PyTuple_GetInteger(poArgs, 0, &iItemVID)) + return Py_BadArgument(); + + CItemManager::Instance().SelectItemData(iItemVID); + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pItemData) + return Py_BuildException("Can't find select item data"); + + return Py_BuildValue("s", pItemData->GetUseTypeString()); +} + +PyObject * itemIsRefineScroll(PyObject * poSelf, PyObject * poArgs) +{ + int iItemIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iItemIndex)) + return Py_BadArgument(); + + CItemManager::Instance().SelectItemData(iItemIndex); + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pItemData) + return Py_BuildException("Can't find select item data"); + + if (pItemData->GetType() != CItemData::ITEM_TYPE_USE) + return Py_BuildValue("i", FALSE); + + switch (pItemData->GetSubType()) + { + case CItemData::USE_TUNING: + return Py_BuildValue("i", TRUE); + break; + } + + return Py_BuildValue("i", FALSE); +} + +PyObject * itemIsDetachScroll(PyObject * poSelf, PyObject * poArgs) +{ + int iItemIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iItemIndex)) + return Py_BadArgument(); + + CItemManager::Instance().SelectItemData(iItemIndex); + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pItemData) + return Py_BuildException("Can't find select item data"); + + int iType = pItemData->GetType(); + int iSubType = pItemData->GetSubType(); + if (iType == CItemData::ITEM_TYPE_USE) + if (iSubType == CItemData::USE_DETACHMENT) + { + return Py_BuildValue("i", TRUE); + } + + return Py_BuildValue("i", FALSE); +} + +PyObject * itemCanAddToQuickSlotItem(PyObject * poSelf, PyObject * poArgs) +{ + int iItemIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iItemIndex)) + return Py_BadArgument(); + + CItemManager::Instance().SelectItemData(iItemIndex); + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pItemData) + return Py_BuildException("Can't find select item data"); + + if (CItemData::ITEM_TYPE_USE == pItemData->GetType() || CItemData::ITEM_TYPE_QUEST == pItemData->GetType()) + { + return Py_BuildValue("i", TRUE); + } + + return Py_BuildValue("i", FALSE); +} + +PyObject * itemIsKey(PyObject * poSelf, PyObject * poArgs) +{ + int iItemIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iItemIndex)) + return Py_BadArgument(); + + CItemManager::Instance().SelectItemData(iItemIndex); + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pItemData) + return Py_BuildException("Can't find select item data"); + + if (CItemData::ITEM_TYPE_TREASURE_KEY == pItemData->GetType()) + { + return Py_BuildValue("i", TRUE); + } + + return Py_BuildValue("i", FALSE); +} + +PyObject * itemIsMetin(PyObject * poSelf, PyObject * poArgs) +{ + int iItemIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iItemIndex)) + return Py_BadArgument(); + + CItemManager::Instance().SelectItemData(iItemIndex); + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pItemData) + return Py_BuildException("Can't find select item data"); + + if (CItemData::ITEM_TYPE_METIN == pItemData->GetType()) + { + return Py_BuildValue("i", TRUE); + } + + return Py_BuildValue("i", FALSE); +} + +PyObject * itemRender(PyObject * poSelf, PyObject * poArgs) +{ + CPythonItem::Instance().Render(); + return Py_BuildNone(); +} + +PyObject * itemUpdate(PyObject * poSelf, PyObject * poArgs) +{ + IAbstractApplication& rkApp=IAbstractApplication::GetSingleton(); + + POINT ptMouse; + rkApp.GetMousePosition(&ptMouse); + + CPythonItem::Instance().Update(ptMouse); + return Py_BuildNone(); +} + +PyObject * itemCreateItem(PyObject * poSelf, PyObject * poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BadArgument(); + int iVirtualNumber; + if (!PyTuple_GetInteger(poArgs, 1, &iVirtualNumber)) + return Py_BadArgument(); + + float x; + if (!PyTuple_GetFloat(poArgs, 2, &x)) + return Py_BadArgument(); + float y; + if (!PyTuple_GetFloat(poArgs, 3, &y)) + return Py_BadArgument(); + float z; + if (!PyTuple_GetFloat(poArgs, 4, &z)) + return Py_BadArgument(); + + bool bDrop = true; + PyTuple_GetBoolean(poArgs, 5, &bDrop); + + CPythonItem::Instance().CreateItem(iVirtualID, iVirtualNumber, x, y, z, bDrop); + + return Py_BuildNone(); +} + +PyObject * itemDeleteItem(PyObject * poSelf, PyObject * poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BadArgument(); + + CPythonItem::Instance().DeleteItem(iVirtualID); + return Py_BuildNone(); +} + +PyObject * itemPick(PyObject * poSelf, PyObject * poArgs) +{ + DWORD dwItemID; + if (CPythonItem::Instance().GetPickedItemID(&dwItemID)) + return Py_BuildValue("i", dwItemID); + else + return Py_BuildValue("i", -1); +} + +PyObject* itemLoadItemTable(PyObject* poSelf, PyObject* poArgs) +{ + char * szFileName; + if (!PyTuple_GetString(poArgs, 0, &szFileName)) + return Py_BadArgument(); + + CItemManager::Instance().LoadItemTable(szFileName); + return Py_BuildNone(); +} + +void initItem() +{ + static PyMethodDef s_methods[] = + { + { "SetUseSoundFileName", itemSetUseSoundFileName, METH_VARARGS }, + { "SetDropSoundFileName", itemSetDropSoundFileName, METH_VARARGS }, + { "SelectItem", itemSelectItem, METH_VARARGS }, + + { "GetItemName", itemGetItemName, METH_VARARGS }, + { "GetItemDescription", itemGetItemDescription, METH_VARARGS }, + { "GetItemSummary", itemGetItemSummary, METH_VARARGS }, + { "GetIconImage", itemGetIconImage, METH_VARARGS }, + { "GetIconImageFileName", itemGetIconImageFileName, METH_VARARGS }, + { "GetItemSize", itemGetItemSize, METH_VARARGS }, + { "GetItemType", itemGetItemType, METH_VARARGS }, + { "GetItemSubType", itemGetItemSubType, METH_VARARGS }, + { "GetIBuyItemPrice", itemGetIBuyItemPrice, METH_VARARGS }, + { "GetISellItemPrice", itemGetISellItemPrice, METH_VARARGS }, + { "IsAntiFlag", itemIsAntiFlag, METH_VARARGS }, + { "IsFlag", itemIsFlag, METH_VARARGS }, + { "IsWearableFlag", itemIsWearableFlag, METH_VARARGS }, + { "Is1GoldItem", itemIs1GoldItem, METH_VARARGS }, + { "GetLimit", itemGetLimit, METH_VARARGS }, + { "GetAffect", itemGetAffect, METH_VARARGS }, + { "GetValue", itemGetValue, METH_VARARGS }, + { "GetSocket", itemGetSocket, METH_VARARGS }, + { "GetIconInstance", itemGetIconInstance, METH_VARARGS }, + { "GetUseType", itemGetUseType, METH_VARARGS }, + { "DeleteIconInstance", itemDeleteIconInstance, METH_VARARGS }, + { "IsEquipmentVID", itemIsEquipmentVID, METH_VARARGS }, + { "IsRefineScroll", itemIsRefineScroll, METH_VARARGS }, + { "IsDetachScroll", itemIsDetachScroll, METH_VARARGS }, + { "IsKey", itemIsKey, METH_VARARGS }, + { "IsMetin", itemIsMetin, METH_VARARGS }, + { "CanAddToQuickSlotItem", itemCanAddToQuickSlotItem, METH_VARARGS }, + + { "Update", itemUpdate, METH_VARARGS }, + { "Render", itemRender, METH_VARARGS }, + { "CreateItem", itemCreateItem, METH_VARARGS }, + { "DeleteItem", itemDeleteItem, METH_VARARGS }, + { "Pick", itemPick, METH_VARARGS }, + + { "LoadItemTable", itemLoadItemTable, METH_VARARGS }, + + { NULL, NULL, NULL }, + }; + + PyObject * poModule = Py_InitModule("item", s_methods); + + PyModule_AddIntConstant(poModule, "USESOUND_ACCESSORY", CPythonItem::USESOUND_ACCESSORY); + PyModule_AddIntConstant(poModule, "USESOUND_ARMOR", CPythonItem::USESOUND_ARMOR); + PyModule_AddIntConstant(poModule, "USESOUND_BOW", CPythonItem::USESOUND_BOW); + PyModule_AddIntConstant(poModule, "USESOUND_DEFAULT", CPythonItem::USESOUND_DEFAULT); + PyModule_AddIntConstant(poModule, "USESOUND_WEAPON", CPythonItem::USESOUND_WEAPON); + PyModule_AddIntConstant(poModule, "USESOUND_POTION", CPythonItem::USESOUND_POTION); + PyModule_AddIntConstant(poModule, "USESOUND_PORTAL", CPythonItem::USESOUND_PORTAL); + + PyModule_AddIntConstant(poModule, "DROPSOUND_ACCESSORY", CPythonItem::DROPSOUND_ACCESSORY); + PyModule_AddIntConstant(poModule, "DROPSOUND_ARMOR", CPythonItem::DROPSOUND_ARMOR); + PyModule_AddIntConstant(poModule, "DROPSOUND_BOW", CPythonItem::DROPSOUND_BOW); + PyModule_AddIntConstant(poModule, "DROPSOUND_DEFAULT", CPythonItem::DROPSOUND_DEFAULT); + PyModule_AddIntConstant(poModule, "DROPSOUND_WEAPON", CPythonItem::DROPSOUND_WEAPON); + + PyModule_AddIntConstant(poModule, "EQUIPMENT_COUNT", c_Equipment_Count); + PyModule_AddIntConstant(poModule, "EQUIPMENT_HEAD", c_Equipment_Head); + PyModule_AddIntConstant(poModule, "EQUIPMENT_BODY", c_Equipment_Body); + PyModule_AddIntConstant(poModule, "EQUIPMENT_WEAPON", c_Equipment_Weapon); + PyModule_AddIntConstant(poModule, "EQUIPMENT_WRIST", c_Equipment_Wrist); + PyModule_AddIntConstant(poModule, "EQUIPMENT_SHOES", c_Equipment_Shoes); + PyModule_AddIntConstant(poModule, "EQUIPMENT_NECK", c_Equipment_Neck); + PyModule_AddIntConstant(poModule, "EQUIPMENT_EAR", c_Equipment_Ear); + PyModule_AddIntConstant(poModule, "EQUIPMENT_UNIQUE1", c_Equipment_Unique1); + PyModule_AddIntConstant(poModule, "EQUIPMENT_UNIQUE2", c_Equipment_Unique2); + PyModule_AddIntConstant(poModule, "EQUIPMENT_ARROW", c_Equipment_Arrow); + +#ifdef ENABLE_NEW_EQUIPMENT_SYSTEM + PyModule_AddIntConstant(poModule, "EQUIPMENT_RING1", c_Equipment_Ring1); + PyModule_AddIntConstant(poModule, "EQUIPMENT_RING2", c_Equipment_Ring2); + PyModule_AddIntConstant(poModule, "EQUIPMENT_BELT", c_Equipment_Belt); +#endif + + PyModule_AddIntConstant(poModule, "ITEM_TYPE_NONE", CItemData::ITEM_TYPE_NONE); + PyModule_AddIntConstant(poModule, "ITEM_TYPE_WEAPON", CItemData::ITEM_TYPE_WEAPON); + PyModule_AddIntConstant(poModule, "ITEM_TYPE_ARMOR", CItemData::ITEM_TYPE_ARMOR); + PyModule_AddIntConstant(poModule, "ITEM_TYPE_USE", CItemData::ITEM_TYPE_USE); + PyModule_AddIntConstant(poModule, "ITEM_TYPE_AUTOUSE", CItemData::ITEM_TYPE_AUTOUSE); + PyModule_AddIntConstant(poModule, "ITEM_TYPE_MATERIAL", CItemData::ITEM_TYPE_MATERIAL); + PyModule_AddIntConstant(poModule, "ITEM_TYPE_SPECIAL", CItemData::ITEM_TYPE_SPECIAL); + PyModule_AddIntConstant(poModule, "ITEM_TYPE_TOOL", CItemData::ITEM_TYPE_TOOL); + PyModule_AddIntConstant(poModule, "ITEM_TYPE_LOTTERY", CItemData::ITEM_TYPE_LOTTERY); + PyModule_AddIntConstant(poModule, "ITEM_TYPE_ELK", CItemData::ITEM_TYPE_ELK); + PyModule_AddIntConstant(poModule, "ITEM_TYPE_METIN", CItemData::ITEM_TYPE_METIN); + PyModule_AddIntConstant(poModule, "ITEM_TYPE_CONTAINER", CItemData::ITEM_TYPE_CONTAINER); + PyModule_AddIntConstant(poModule, "ITEM_TYPE_FISH", CItemData::ITEM_TYPE_FISH); + PyModule_AddIntConstant(poModule, "ITEM_TYPE_ROD", CItemData::ITEM_TYPE_ROD); + PyModule_AddIntConstant(poModule, "ITEM_TYPE_RESOURCE", CItemData::ITEM_TYPE_RESOURCE); + PyModule_AddIntConstant(poModule, "ITEM_TYPE_CAMPFIRE", CItemData::ITEM_TYPE_CAMPFIRE); + PyModule_AddIntConstant(poModule, "ITEM_TYPE_UNIQUE", CItemData::ITEM_TYPE_UNIQUE); + PyModule_AddIntConstant(poModule, "ITEM_TYPE_SKILLBOOK", CItemData::ITEM_TYPE_SKILLBOOK); + PyModule_AddIntConstant(poModule, "ITEM_TYPE_QUEST", CItemData::ITEM_TYPE_QUEST); + PyModule_AddIntConstant(poModule, "ITEM_TYPE_POLYMORPH", CItemData::ITEM_TYPE_POLYMORPH); + PyModule_AddIntConstant(poModule, "ITEM_TYPE_TREASURE_BOX", CItemData::ITEM_TYPE_TREASURE_BOX); + PyModule_AddIntConstant(poModule, "ITEM_TYPE_TREASURE_KEY", CItemData::ITEM_TYPE_TREASURE_KEY); + PyModule_AddIntConstant(poModule, "ITEM_TYPE_PICK", CItemData::ITEM_TYPE_PICK); + PyModule_AddIntConstant(poModule, "ITEM_TYPE_BLEND", CItemData::ITEM_TYPE_BLEND); + PyModule_AddIntConstant(poModule, "ITEM_TYPE_DS", CItemData::ITEM_TYPE_DS); + PyModule_AddIntConstant(poModule, "ITEM_TYPE_SPECIAL_DS", CItemData::ITEM_TYPE_SPECIAL_DS); + PyModule_AddIntConstant(poModule, "ITEM_TYPE_RING", CItemData::ITEM_TYPE_RING); + PyModule_AddIntConstant(poModule, "ITEM_TYPE_BELT", CItemData::ITEM_TYPE_BELT); + + +#ifdef ENABLE_COSTUME_SYSTEM + PyModule_AddIntConstant(poModule, "ITEM_TYPE_COSTUME", CItemData::ITEM_TYPE_COSTUME); + + // Item Sub Type + PyModule_AddIntConstant(poModule, "COSTUME_TYPE_BODY", CItemData::COSTUME_BODY); + PyModule_AddIntConstant(poModule, "COSTUME_TYPE_HAIR", CItemData::COSTUME_HAIR); + + // κ丮 â ȣ + PyModule_AddIntConstant(poModule, "COSTUME_SLOT_START", c_Costume_Slot_Start); + PyModule_AddIntConstant(poModule, "COSTUME_SLOT_COUNT", c_Costume_Slot_Count); + PyModule_AddIntConstant(poModule, "COSTUME_SLOT_BODY", c_Costume_Slot_Body); + PyModule_AddIntConstant(poModule, "COSTUME_SLOT_HAIR", c_Costume_Slot_Hair); + PyModule_AddIntConstant(poModule, "COSTUME_SLOT_END", c_Costume_Slot_End); +#endif + +#ifdef ENABLE_NEW_EQUIPMENT_SYSTEM + PyModule_AddIntConstant(poModule, "BELT_INVENTORY_SLOT_START", c_Belt_Inventory_Slot_Start); + PyModule_AddIntConstant(poModule, "BELT_INVENTORY_SLOT_COUNT", c_Belt_Inventory_Slot_Count); + PyModule_AddIntConstant(poModule, "BELT_INVENTORY_SLOT_END", c_Belt_Inventory_Slot_End); + +#endif + + PyModule_AddIntConstant(poModule, "WEAPON_SWORD", CItemData::WEAPON_SWORD); + PyModule_AddIntConstant(poModule, "WEAPON_DAGGER", CItemData::WEAPON_DAGGER); + PyModule_AddIntConstant(poModule, "WEAPON_BOW", CItemData::WEAPON_BOW); + PyModule_AddIntConstant(poModule, "WEAPON_TWO_HANDED", CItemData::WEAPON_TWO_HANDED); + PyModule_AddIntConstant(poModule, "WEAPON_BELL", CItemData::WEAPON_BELL); + PyModule_AddIntConstant(poModule, "WEAPON_FAN", CItemData::WEAPON_FAN); + PyModule_AddIntConstant(poModule, "WEAPON_ARROW", CItemData::WEAPON_ARROW); + PyModule_AddIntConstant(poModule, "WEAPON_NUM_TYPES", CItemData::WEAPON_NUM_TYPES); + + PyModule_AddIntConstant(poModule, "USE_POTION", CItemData::USE_POTION); + PyModule_AddIntConstant(poModule, "USE_TALISMAN", CItemData::USE_TALISMAN); + PyModule_AddIntConstant(poModule, "USE_TUNING", CItemData::USE_TUNING); + PyModule_AddIntConstant(poModule, "USE_MOVE", CItemData::USE_MOVE); + PyModule_AddIntConstant(poModule, "USE_TREASURE_BOX", CItemData::USE_TREASURE_BOX); + PyModule_AddIntConstant(poModule, "USE_MONEYBAG", CItemData::USE_MONEYBAG); + PyModule_AddIntConstant(poModule, "USE_BAIT", CItemData::USE_BAIT); + PyModule_AddIntConstant(poModule, "USE_ABILITY_UP", CItemData::USE_ABILITY_UP); + PyModule_AddIntConstant(poModule, "USE_AFFECT", CItemData::USE_AFFECT); + PyModule_AddIntConstant(poModule, "USE_CREATE_STONE", CItemData::USE_CREATE_STONE); + PyModule_AddIntConstant(poModule, "USE_SPECIAL", CItemData::USE_SPECIAL); + PyModule_AddIntConstant(poModule, "USE_POTION_NODELAY", CItemData::USE_POTION_NODELAY); + PyModule_AddIntConstant(poModule, "USE_CLEAR", CItemData::USE_CLEAR); + PyModule_AddIntConstant(poModule, "USE_INVISIBILITY", CItemData::USE_INVISIBILITY); + PyModule_AddIntConstant(poModule, "USE_DETACHMENT", CItemData::USE_DETACHMENT); + PyModule_AddIntConstant(poModule, "USE_TIME_CHARGE_PER", CItemData::USE_TIME_CHARGE_PER); + PyModule_AddIntConstant(poModule, "USE_TIME_CHARGE_FIX", CItemData::USE_TIME_CHARGE_FIX); + + PyModule_AddIntConstant(poModule, "MATERIAL_DS_REFINE_NORMAL", CItemData::MATERIAL_DS_REFINE_NORMAL); + PyModule_AddIntConstant(poModule, "MATERIAL_DS_REFINE_BLESSED", CItemData::MATERIAL_DS_REFINE_BLESSED); + PyModule_AddIntConstant(poModule, "MATERIAL_DS_REFINE_HOLLY", CItemData::MATERIAL_DS_REFINE_HOLLY); + + PyModule_AddIntConstant(poModule, "METIN_NORMAL", CItemData::METIN_NORMAL); + PyModule_AddIntConstant(poModule, "METIN_GOLD", CItemData::METIN_GOLD); + + PyModule_AddIntConstant(poModule, "LIMIT_NONE", CItemData::LIMIT_NONE); + PyModule_AddIntConstant(poModule, "LIMIT_LEVEL", CItemData::LIMIT_LEVEL); + PyModule_AddIntConstant(poModule, "LIMIT_STR", CItemData::LIMIT_STR); + PyModule_AddIntConstant(poModule, "LIMIT_DEX", CItemData::LIMIT_DEX); + PyModule_AddIntConstant(poModule, "LIMIT_INT", CItemData::LIMIT_INT); + PyModule_AddIntConstant(poModule, "LIMIT_CON", CItemData::LIMIT_CON); + PyModule_AddIntConstant(poModule, "LIMIT_PCBANG", CItemData::LIMIT_PCBANG); + PyModule_AddIntConstant(poModule, "LIMIT_REAL_TIME", CItemData::LIMIT_REAL_TIME); + PyModule_AddIntConstant(poModule, "LIMIT_REAL_TIME_START_FIRST_USE", CItemData::LIMIT_REAL_TIME_START_FIRST_USE); + PyModule_AddIntConstant(poModule, "LIMIT_TIMER_BASED_ON_WEAR", CItemData::LIMIT_TIMER_BASED_ON_WEAR); + PyModule_AddIntConstant(poModule, "LIMIT_TYPE_MAX_NUM", CItemData::LIMIT_MAX_NUM); + PyModule_AddIntConstant(poModule, "LIMIT_MAX_NUM", CItemData::ITEM_LIMIT_MAX_NUM); + + PyModule_AddIntConstant(poModule, "ITEM_ANTIFLAG_FEMALE", CItemData::ITEM_ANTIFLAG_FEMALE); + PyModule_AddIntConstant(poModule, "ITEM_ANTIFLAG_MALE", CItemData::ITEM_ANTIFLAG_MALE); + PyModule_AddIntConstant(poModule, "ITEM_ANTIFLAG_WARRIOR", CItemData::ITEM_ANTIFLAG_WARRIOR); + PyModule_AddIntConstant(poModule, "ITEM_ANTIFLAG_ASSASSIN", CItemData::ITEM_ANTIFLAG_ASSASSIN); + PyModule_AddIntConstant(poModule, "ITEM_ANTIFLAG_SURA", CItemData::ITEM_ANTIFLAG_SURA); + PyModule_AddIntConstant(poModule, "ITEM_ANTIFLAG_SHAMAN", CItemData::ITEM_ANTIFLAG_SHAMAN); + PyModule_AddIntConstant(poModule, "ITEM_ANTIFLAG_GET", CItemData::ITEM_ANTIFLAG_GET); + PyModule_AddIntConstant(poModule, "ITEM_ANTIFLAG_DROP", CItemData::ITEM_ANTIFLAG_DROP); + PyModule_AddIntConstant(poModule, "ITEM_ANTIFLAG_SELL", CItemData::ITEM_ANTIFLAG_SELL); + PyModule_AddIntConstant(poModule, "ITEM_ANTIFLAG_EMPIRE_A", CItemData::ITEM_ANTIFLAG_EMPIRE_A); + PyModule_AddIntConstant(poModule, "ITEM_ANTIFLAG_EMPIRE_B", CItemData::ITEM_ANTIFLAG_EMPIRE_B); + PyModule_AddIntConstant(poModule, "ITEM_ANTIFLAG_EMPIRE_R", CItemData::ITEM_ANTIFLAG_EMPIRE_R); + PyModule_AddIntConstant(poModule, "ITEM_ANTIFLAG_SAVE", CItemData::ITEM_ANTIFLAG_SAVE); + PyModule_AddIntConstant(poModule, "ITEM_ANTIFLAG_GIVE", CItemData::ITEM_ANTIFLAG_GIVE); + PyModule_AddIntConstant(poModule, "ITEM_ANTIFLAG_PKDROP", CItemData::ITEM_ANTIFLAG_PKDROP); + PyModule_AddIntConstant(poModule, "ITEM_ANTIFLAG_STACK", CItemData::ITEM_ANTIFLAG_STACK); + PyModule_AddIntConstant(poModule, "ITEM_ANTIFLAG_MYSHOP", CItemData::ITEM_ANTIFLAG_MYSHOP); + + PyModule_AddIntConstant(poModule, "ITEM_FLAG_RARE", CItemData::ITEM_FLAG_RARE); + PyModule_AddIntConstant(poModule, "ITEM_FLAG_UNIQUE", CItemData::ITEM_FLAG_UNIQUE); + PyModule_AddIntConstant(poModule, "ITEM_FLAG_CONFIRM_WHEN_USE", CItemData::ITEM_FLAG_CONFIRM_WHEN_USE); + + PyModule_AddIntConstant(poModule, "ANTIFLAG_FEMALE", CItemData::ITEM_ANTIFLAG_FEMALE); + PyModule_AddIntConstant(poModule, "ANTIFLAG_MALE", CItemData::ITEM_ANTIFLAG_MALE); + PyModule_AddIntConstant(poModule, "ANTIFLAG_WARRIOR", CItemData::ITEM_ANTIFLAG_WARRIOR); + PyModule_AddIntConstant(poModule, "ANTIFLAG_ASSASSIN", CItemData::ITEM_ANTIFLAG_ASSASSIN); + PyModule_AddIntConstant(poModule, "ANTIFLAG_SURA", CItemData::ITEM_ANTIFLAG_SURA); + PyModule_AddIntConstant(poModule, "ANTIFLAG_SHAMAN", CItemData::ITEM_ANTIFLAG_SHAMAN); + PyModule_AddIntConstant(poModule, "ANTIFLAG_GET", CItemData::ITEM_ANTIFLAG_GET); + PyModule_AddIntConstant(poModule, "ANTIFLAG_DROP", CItemData::ITEM_ANTIFLAG_DROP); + PyModule_AddIntConstant(poModule, "ANTIFLAG_SELL", CItemData::ITEM_ANTIFLAG_SELL); + PyModule_AddIntConstant(poModule, "ANTIFLAG_EMPIRE_A", CItemData::ITEM_ANTIFLAG_EMPIRE_A); + PyModule_AddIntConstant(poModule, "ANTIFLAG_EMPIRE_B", CItemData::ITEM_ANTIFLAG_EMPIRE_B); + PyModule_AddIntConstant(poModule, "ANTIFLAG_EMPIRE_R", CItemData::ITEM_ANTIFLAG_EMPIRE_R); + PyModule_AddIntConstant(poModule, "ANTIFLAG_SAVE", CItemData::ITEM_ANTIFLAG_SAVE); + PyModule_AddIntConstant(poModule, "ANTIFLAG_GIVE", CItemData::ITEM_ANTIFLAG_GIVE); + PyModule_AddIntConstant(poModule, "ANTIFLAG_PKDROP", CItemData::ITEM_ANTIFLAG_PKDROP); + PyModule_AddIntConstant(poModule, "ANTIFLAG_STACK", CItemData::ITEM_ANTIFLAG_STACK); + PyModule_AddIntConstant(poModule, "ANTIFLAG_MYSHOP", CItemData::ITEM_ANTIFLAG_MYSHOP); + + PyModule_AddIntConstant(poModule, "WEARABLE_BODY", CItemData::WEARABLE_BODY); + PyModule_AddIntConstant(poModule, "WEARABLE_HEAD", CItemData::WEARABLE_HEAD); + PyModule_AddIntConstant(poModule, "WEARABLE_FOOTS", CItemData::WEARABLE_FOOTS); + PyModule_AddIntConstant(poModule, "WEARABLE_WRIST", CItemData::WEARABLE_WRIST); + PyModule_AddIntConstant(poModule, "WEARABLE_WEAPON", CItemData::WEARABLE_WEAPON); + PyModule_AddIntConstant(poModule, "WEARABLE_NECK", CItemData::WEARABLE_NECK); + PyModule_AddIntConstant(poModule, "WEARABLE_EAR", CItemData::WEARABLE_EAR); + PyModule_AddIntConstant(poModule, "WEARABLE_UNIQUE", CItemData::WEARABLE_UNIQUE); + PyModule_AddIntConstant(poModule, "WEARABLE_SHIELD", CItemData::WEARABLE_SHIELD); + PyModule_AddIntConstant(poModule, "WEARABLE_ARROW", CItemData::WEARABLE_ARROW); + + PyModule_AddIntConstant(poModule, "ARMOR_BODY", CItemData::ARMOR_BODY); + PyModule_AddIntConstant(poModule, "ARMOR_HEAD", CItemData::ARMOR_HEAD); + PyModule_AddIntConstant(poModule, "ARMOR_SHIELD", CItemData::ARMOR_SHIELD); + PyModule_AddIntConstant(poModule, "ARMOR_WRIST", CItemData::ARMOR_WRIST); + PyModule_AddIntConstant(poModule, "ARMOR_FOOTS", CItemData::ARMOR_FOOTS); + PyModule_AddIntConstant(poModule, "ARMOR_NECK", CItemData::ARMOR_NECK); + PyModule_AddIntConstant(poModule, "ARMOR_EAR", CItemData::ARMOR_EAR); + + PyModule_AddIntConstant(poModule, "ITEM_APPLY_MAX_NUM", CItemData::ITEM_APPLY_MAX_NUM); + PyModule_AddIntConstant(poModule, "ITEM_SOCKET_MAX_NUM", CItemData::ITEM_SOCKET_MAX_NUM); + + PyModule_AddIntConstant(poModule, "APPLY_NONE", CItemData::APPLY_NONE); + PyModule_AddIntConstant(poModule, "APPLY_STR", CItemData::APPLY_STR); + PyModule_AddIntConstant(poModule, "APPLY_DEX", CItemData::APPLY_DEX); + PyModule_AddIntConstant(poModule, "APPLY_CON", CItemData::APPLY_CON); + PyModule_AddIntConstant(poModule, "APPLY_INT", CItemData::APPLY_INT); + PyModule_AddIntConstant(poModule, "APPLY_MAX_HP", CItemData::APPLY_MAX_HP); + PyModule_AddIntConstant(poModule, "APPLY_MAX_SP", CItemData::APPLY_MAX_SP); + PyModule_AddIntConstant(poModule, "APPLY_HP_REGEN", CItemData::APPLY_HP_REGEN); + PyModule_AddIntConstant(poModule, "APPLY_SP_REGEN", CItemData::APPLY_SP_REGEN); + PyModule_AddIntConstant(poModule, "APPLY_DEF_GRADE_BONUS", CItemData::APPLY_DEF_GRADE_BONUS); + PyModule_AddIntConstant(poModule, "APPLY_ATT_GRADE_BONUS", CItemData::APPLY_ATT_GRADE_BONUS); + PyModule_AddIntConstant(poModule, "APPLY_ATT_SPEED", CItemData::APPLY_ATT_SPEED); + PyModule_AddIntConstant(poModule, "APPLY_MOV_SPEED", CItemData::APPLY_MOV_SPEED); + PyModule_AddIntConstant(poModule, "APPLY_CAST_SPEED", CItemData::APPLY_CAST_SPEED); + PyModule_AddIntConstant(poModule, "APPLY_MAGIC_ATT_GRADE", CItemData::APPLY_MAGIC_ATT_GRADE); + PyModule_AddIntConstant(poModule, "APPLY_MAGIC_DEF_GRADE", CItemData::APPLY_MAGIC_DEF_GRADE); + PyModule_AddIntConstant(poModule, "APPLY_SKILL", CItemData::APPLY_SKILL); + PyModule_AddIntConstant(poModule, "APPLY_ATTBONUS_ANIMAL", CItemData::APPLY_ATTBONUS_ANIMAL); + PyModule_AddIntConstant(poModule, "APPLY_ATTBONUS_UNDEAD", CItemData::APPLY_ATTBONUS_UNDEAD); + PyModule_AddIntConstant(poModule, "APPLY_ATTBONUS_DEVIL", CItemData::APPLY_ATTBONUS_DEVIL); + PyModule_AddIntConstant(poModule, "APPLY_ATTBONUS_HUMAN", CItemData::APPLY_ATTBONUS_HUMAN); + PyModule_AddIntConstant(poModule, "APPLY_BOW_DISTANCE", CItemData::APPLY_BOW_DISTANCE); + PyModule_AddIntConstant(poModule, "APPLY_RESIST_BOW", CItemData::APPLY_RESIST_BOW); + PyModule_AddIntConstant(poModule, "APPLY_RESIST_FIRE", CItemData::APPLY_RESIST_FIRE); + PyModule_AddIntConstant(poModule, "APPLY_RESIST_ELEC", CItemData::APPLY_RESIST_ELEC); + PyModule_AddIntConstant(poModule, "APPLY_RESIST_MAGIC", CItemData::APPLY_RESIST_MAGIC); + PyModule_AddIntConstant(poModule, "APPLY_POISON_PCT", CItemData::APPLY_POISON_PCT); + PyModule_AddIntConstant(poModule, "APPLY_SLOW_PCT", CItemData::APPLY_SLOW_PCT); + PyModule_AddIntConstant(poModule, "APPLY_STUN_PCT", CItemData::APPLY_STUN_PCT); + PyModule_AddIntConstant(poModule, "APPLY_CRITICAL_PCT", CItemData::APPLY_CRITICAL_PCT); // n% Ȯ ι Ÿ + PyModule_AddIntConstant(poModule, "APPLY_PENETRATE_PCT", CItemData::APPLY_PENETRATE_PCT); // n% Ȯ + PyModule_AddIntConstant(poModule, "APPLY_ATTBONUS_ORC", CItemData::APPLY_ATTBONUS_ORC); // Ϳ n% ߰ + PyModule_AddIntConstant(poModule, "APPLY_ATTBONUS_MILGYO", CItemData::APPLY_ATTBONUS_MILGYO); // б n% ߰ + PyModule_AddIntConstant(poModule, "APPLY_ATTBONUS_UNDEAD", CItemData::APPLY_ATTBONUS_UNDEAD); // ü n% ߰ + PyModule_AddIntConstant(poModule, "APPLY_ATTBONUS_DEVIL", CItemData::APPLY_ATTBONUS_DEVIL); // Ǹ n% ߰ + PyModule_AddIntConstant(poModule, "APPLY_STEAL_HP", CItemData::APPLY_STEAL_HP); // n% Ȯ Ÿ 10% + PyModule_AddIntConstant(poModule, "APPLY_STEAL_SP", CItemData::APPLY_STEAL_SP); // n% Ȯ Ÿ 10% ŷ + PyModule_AddIntConstant(poModule, "APPLY_MANA_BURN_PCT", CItemData::APPLY_MANA_BURN_PCT); // n% Ȯ ´ + PyModule_AddIntConstant(poModule, "APPLY_DAMAGE_SP_RECOVER", CItemData::APPLY_DAMAGE_SP_RECOVER); // n% Ȯ ŷ 2 ȸ + PyModule_AddIntConstant(poModule, "APPLY_BLOCK", CItemData::APPLY_BLOCK); // n% Ȯ Ϻ + PyModule_AddIntConstant(poModule, "APPLY_DODGE", CItemData::APPLY_DODGE); // n% Ȯ Ϻ ȸ + PyModule_AddIntConstant(poModule, "APPLY_RESIST_SWORD", CItemData::APPLY_RESIST_SWORD); // Ѽհ˿ ظ n% + PyModule_AddIntConstant(poModule, "APPLY_RESIST_TWOHAND", CItemData::APPLY_RESIST_TWOHAND); // հ˿ ظ n% + PyModule_AddIntConstant(poModule, "APPLY_RESIST_DAGGER", CItemData::APPLY_RESIST_DAGGER); // ܵ ظ n% + PyModule_AddIntConstant(poModule, "APPLY_RESIST_BELL", CItemData::APPLY_RESIST_BELL); // £ ظ n% + PyModule_AddIntConstant(poModule, "APPLY_RESIST_FAN", CItemData::APPLY_RESIST_FAN); // ä ظ n% + PyModule_AddIntConstant(poModule, "APPLY_RESIST_WIND", CItemData::APPLY_RESIST_WIND); // ٶ ظ n% + PyModule_AddIntConstant(poModule, "APPLY_REFLECT_MELEE", CItemData::APPLY_REFLECT_MELEE); // Ÿ n% ǵ + PyModule_AddIntConstant(poModule, "APPLY_REFLECT_CURSE", CItemData::APPLY_REFLECT_CURSE); // n% Ȯ ǵ + PyModule_AddIntConstant(poModule, "APPLY_POISON_REDUCE", CItemData::APPLY_POISON_REDUCE); // + PyModule_AddIntConstant(poModule, "APPLY_KILL_SP_RECOVER", CItemData::APPLY_KILL_SP_RECOVER); // ׿ n% Ȯ ŷ 10 ȸ + PyModule_AddIntConstant(poModule, "APPLY_EXP_DOUBLE_BONUS", CItemData::APPLY_EXP_DOUBLE_BONUS); // n% Ȯ ġ ȹ淮 2 + PyModule_AddIntConstant(poModule, "APPLY_GOLD_DOUBLE_BONUS", CItemData::APPLY_GOLD_DOUBLE_BONUS); // n% Ȯ ȹ淮 2 + PyModule_AddIntConstant(poModule, "APPLY_ITEM_DROP_BONUS", CItemData::APPLY_ITEM_DROP_BONUS); // n% Ȯ ȹ淮 2 + PyModule_AddIntConstant(poModule, "APPLY_POTION_BONUS", CItemData::APPLY_POTION_BONUS); // n% ŭ + PyModule_AddIntConstant(poModule, "APPLY_KILL_HP_RECOVER", CItemData::APPLY_KILL_HP_RECOVER); // ϶ ȸ + PyModule_AddIntConstant(poModule, "APPLY_IMMUNE_STUN", CItemData::APPLY_IMMUNE_STUN); // ʴ´ + PyModule_AddIntConstant(poModule, "APPLY_IMMUNE_SLOW", CItemData::APPLY_IMMUNE_SLOW); // ʴ´ + PyModule_AddIntConstant(poModule, "APPLY_IMMUNE_FALL", CItemData::APPLY_IMMUNE_FALL); // Ѿ ʴ´ + PyModule_AddIntConstant(poModule, "APPLY_MAX_STAMINA", CItemData::APPLY_MAX_STAMINA); // ִ ׹̳ + PyModule_AddIntConstant(poModule, "APPLY_ATTBONUS_WARRIOR", CItemData::APPLY_ATT_BONUS_TO_WARRIOR); + PyModule_AddIntConstant(poModule, "APPLY_ATTBONUS_ASSASSIN", CItemData::APPLY_ATT_BONUS_TO_ASSASSIN); + PyModule_AddIntConstant(poModule, "APPLY_ATTBONUS_SURA", CItemData::APPLY_ATT_BONUS_TO_SURA); + PyModule_AddIntConstant(poModule, "APPLY_ATTBONUS_SHAMAN", CItemData::APPLY_ATT_BONUS_TO_SHAMAN); + PyModule_AddIntConstant(poModule, "APPLY_ATTBONUS_MONSTER", CItemData::APPLY_ATT_BONUS_TO_MONSTER); + PyModule_AddIntConstant(poModule, "APPLY_MALL_ATTBONUS", CItemData::APPLY_MALL_ATTBONUS); + PyModule_AddIntConstant(poModule, "APPLY_MALL_DEFBONUS", CItemData::APPLY_MALL_DEFBONUS); + PyModule_AddIntConstant(poModule, "APPLY_MALL_EXPBONUS", CItemData::APPLY_MALL_EXPBONUS); + PyModule_AddIntConstant(poModule, "APPLY_MALL_ITEMBONUS", CItemData::APPLY_MALL_ITEMBONUS); + PyModule_AddIntConstant(poModule, "APPLY_MALL_GOLDBONUS", CItemData::APPLY_MALL_GOLDBONUS); + PyModule_AddIntConstant(poModule, "APPLY_MAX_HP_PCT", CItemData::APPLY_MAX_HP_PCT); + PyModule_AddIntConstant(poModule, "APPLY_MAX_SP_PCT", CItemData::APPLY_MAX_SP_PCT); + PyModule_AddIntConstant(poModule, "APPLY_SKILL_DAMAGE_BONUS", CItemData::APPLY_SKILL_DAMAGE_BONUS); + PyModule_AddIntConstant(poModule, "APPLY_NORMAL_HIT_DAMAGE_BONUS", CItemData::APPLY_NORMAL_HIT_DAMAGE_BONUS); + PyModule_AddIntConstant(poModule, "APPLY_SKILL_DEFEND_BONUS", CItemData::APPLY_SKILL_DEFEND_BONUS); + PyModule_AddIntConstant(poModule, "APPLY_NORMAL_HIT_DEFEND_BONUS", CItemData::APPLY_NORMAL_HIT_DEFEND_BONUS); + + PyModule_AddIntConstant(poModule, "APPLY_PC_BANG_EXP_BONUS", CItemData::APPLY_PC_BANG_EXP_BONUS); + PyModule_AddIntConstant(poModule, "APPLY_PC_BANG_DROP_BONUS", CItemData::APPLY_PC_BANG_DROP_BONUS); + + PyModule_AddIntConstant(poModule, "APPLY_RESIST_WARRIOR", CItemData::APPLY_RESIST_WARRIOR ); + PyModule_AddIntConstant(poModule, "APPLY_RESIST_ASSASSIN", CItemData::APPLY_RESIST_ASSASSIN ); + PyModule_AddIntConstant(poModule, "APPLY_RESIST_SURA", CItemData::APPLY_RESIST_SURA ); + PyModule_AddIntConstant(poModule, "APPLY_RESIST_SHAMAN", CItemData::APPLY_RESIST_SHAMAN ); + PyModule_AddIntConstant(poModule, "APPLY_ENERGY", CItemData::APPLY_ENERGY ); // + PyModule_AddIntConstant(poModule, "APPLY_COSTUME_ATTR_BONUS", CItemData::APPLY_COSTUME_ATTR_BONUS ); + + PyModule_AddIntConstant(poModule, "APPLY_MAGIC_ATTBONUS_PER", CItemData::APPLY_MAGIC_ATTBONUS_PER ); + PyModule_AddIntConstant(poModule, "APPLY_MELEE_MAGIC_ATTBONUS_PER", CItemData::APPLY_MELEE_MAGIC_ATTBONUS_PER ); + PyModule_AddIntConstant(poModule, "APPLY_RESIST_ICE", CItemData::APPLY_RESIST_ICE ); + PyModule_AddIntConstant(poModule, "APPLY_RESIST_EARTH", CItemData::APPLY_RESIST_EARTH ); + PyModule_AddIntConstant(poModule, "APPLY_RESIST_DARK", CItemData::APPLY_RESIST_DARK ); + PyModule_AddIntConstant(poModule, "APPLY_ANTI_CRITICAL_PCT", CItemData::APPLY_ANTI_CRITICAL_PCT ); + PyModule_AddIntConstant(poModule, "APPLY_ANTI_PENETRATE_PCT", CItemData::APPLY_ANTI_PENETRATE_PCT ); +} diff --git a/source/UserInterface/PythonMessenger.cpp b/source/UserInterface/PythonMessenger.cpp new file mode 100644 index 0000000..1394d45 --- /dev/null +++ b/source/UserInterface/PythonMessenger.cpp @@ -0,0 +1,168 @@ +#include "stdafx.h" +#include "PythonMessenger.h" + +void CPythonMessenger::RemoveFriend(const char * c_szKey) +{ + m_FriendNameMap.erase(c_szKey); +} + +void CPythonMessenger::OnFriendLogin(const char * c_szKey/*, const char * c_szName*/) +{ + m_FriendNameMap.insert(c_szKey); + + if (m_poMessengerHandler) + PyCallClassMemberFunc(m_poMessengerHandler, "OnLogin", Py_BuildValue("(is)", MESSENGER_GRUOP_INDEX_FRIEND, c_szKey)); +} + +void CPythonMessenger::OnFriendLogout(const char * c_szKey) +{ + m_FriendNameMap.insert(c_szKey); + + if (m_poMessengerHandler) + PyCallClassMemberFunc(m_poMessengerHandler, "OnLogout", Py_BuildValue("(is)", MESSENGER_GRUOP_INDEX_FRIEND, c_szKey)); +} + +void CPythonMessenger::SetMobile(const char * c_szKey, BYTE byState) +{ + m_FriendNameMap.insert(c_szKey); + + if (m_poMessengerHandler) + PyCallClassMemberFunc(m_poMessengerHandler, "OnMobile", Py_BuildValue("(isi)", MESSENGER_GRUOP_INDEX_FRIEND, c_szKey, byState)); +} + +BOOL CPythonMessenger::IsFriendByKey(const char * c_szKey) +{ + return m_FriendNameMap.end() != m_FriendNameMap.find(c_szKey); +} + +BOOL CPythonMessenger::IsFriendByName(const char * c_szName) +{ + return IsFriendByKey(c_szName); +} + +void CPythonMessenger::AppendGuildMember(const char * c_szName) +{ + if (m_GuildMemberStateMap.end() != m_GuildMemberStateMap.find(c_szName)) + return; + + LogoutGuildMember(c_szName); +} + +void CPythonMessenger::RemoveGuildMember(const char * c_szName) +{ + m_GuildMemberStateMap.erase(c_szName); + + if (m_poMessengerHandler) + PyCallClassMemberFunc(m_poMessengerHandler, "OnRemoveList", Py_BuildValue("(is)", MESSENGER_GRUOP_INDEX_GUILD, c_szName)); +} + +void CPythonMessenger::RemoveAllGuildMember() +{ + m_GuildMemberStateMap.clear(); + + if (m_poMessengerHandler) + PyCallClassMemberFunc(m_poMessengerHandler, "OnRemoveAllList", Py_BuildValue("(i)", MESSENGER_GRUOP_INDEX_GUILD)); +} + +void CPythonMessenger::LoginGuildMember(const char * c_szName) +{ + m_GuildMemberStateMap[c_szName] = 1; + if (m_poMessengerHandler) + PyCallClassMemberFunc(m_poMessengerHandler, "OnLogin", Py_BuildValue("(is)", MESSENGER_GRUOP_INDEX_GUILD, c_szName)); +} + +void CPythonMessenger::LogoutGuildMember(const char * c_szName) +{ + m_GuildMemberStateMap[c_szName] = 0; + if (m_poMessengerHandler) + PyCallClassMemberFunc(m_poMessengerHandler, "OnLogout", Py_BuildValue("(is)", MESSENGER_GRUOP_INDEX_GUILD, c_szName)); +} + +void CPythonMessenger::RefreshGuildMember() +{ + for (TGuildMemberStateMap::iterator itor = m_GuildMemberStateMap.begin(); itor != m_GuildMemberStateMap.end(); ++itor) + { + if (itor->second) + PyCallClassMemberFunc(m_poMessengerHandler, "OnLogin", Py_BuildValue("(is)", MESSENGER_GRUOP_INDEX_GUILD, (itor->first).c_str())); + else + PyCallClassMemberFunc(m_poMessengerHandler, "OnLogout", Py_BuildValue("(is)", MESSENGER_GRUOP_INDEX_GUILD, (itor->first).c_str())); + } +} + +void CPythonMessenger::Destroy() +{ + m_FriendNameMap.clear(); + m_GuildMemberStateMap.clear(); +} + +void CPythonMessenger::SetMessengerHandler(PyObject* poHandler) +{ + m_poMessengerHandler = poHandler; +} + +CPythonMessenger::CPythonMessenger() + : m_poMessengerHandler(NULL) +{ +} + +CPythonMessenger::~CPythonMessenger() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +PyObject * messengerRemoveFriend(PyObject* poSelf, PyObject* poArgs) +{ + char * szKey; + if (!PyTuple_GetString(poArgs, 0, &szKey)) + return Py_BuildException(); + + CPythonMessenger::Instance().RemoveFriend(szKey); + return Py_BuildNone(); +} + +PyObject * messengerIsFriendByName(PyObject* poSelf, PyObject* poArgs) +{ + char * szName; + if (!PyTuple_GetString(poArgs, 0, &szName)) + return Py_BuildException(); + + return Py_BuildValue("i", CPythonMessenger::Instance().IsFriendByName(szName)); +} + +PyObject * messengerDestroy(PyObject* poSelf, PyObject* poArgs) +{ + CPythonMessenger::Instance().Destroy(); + return Py_BuildNone(); +} + +PyObject * messengerRefreshGuildMember(PyObject* poSelf, PyObject* poArgs) +{ + CPythonMessenger::Instance().RefreshGuildMember(); + return Py_BuildNone(); +} + +PyObject * messengerSetMessengerHandler(PyObject* poSelf, PyObject* poArgs) +{ + PyObject * poEventHandler; + if (!PyTuple_GetObject(poArgs, 0, &poEventHandler)) + return Py_BuildException(); + + CPythonMessenger::Instance().SetMessengerHandler(poEventHandler); + return Py_BuildNone(); +} + +void initMessenger() +{ + static PyMethodDef s_methods[] = + { + { "RemoveFriend", messengerRemoveFriend, METH_VARARGS }, + { "IsFriendByName", messengerIsFriendByName, METH_VARARGS } , + { "Destroy", messengerDestroy, METH_VARARGS }, + { "RefreshGuildMember", messengerRefreshGuildMember, METH_VARARGS }, + { "SetMessengerHandler", messengerSetMessengerHandler, METH_VARARGS }, + { NULL, NULL, NULL }, + }; + + Py_InitModule("messenger", s_methods); +} diff --git a/source/UserInterface/PythonMessenger.h b/source/UserInterface/PythonMessenger.h new file mode 100644 index 0000000..150ae9c --- /dev/null +++ b/source/UserInterface/PythonMessenger.h @@ -0,0 +1,45 @@ +#pragma once + +class CPythonMessenger : public CSingleton +{ + public: + typedef std::set TFriendNameMap; + typedef std::map TGuildMemberStateMap; + + enum EMessengerGroupIndex + { + MESSENGER_GRUOP_INDEX_FRIEND, + MESSENGER_GRUOP_INDEX_GUILD, + }; + + public: + CPythonMessenger(); + virtual ~CPythonMessenger(); + + void Destroy(); + + // Friend + void RemoveFriend(const char * c_szKey); + void OnFriendLogin(const char * c_szKey); + void OnFriendLogout(const char * c_szKey); + void SetMobile(const char * c_szKey, BYTE byState); + BOOL IsFriendByKey(const char * c_szKey); + BOOL IsFriendByName(const char * c_szName); + + // Guild + void AppendGuildMember(const char * c_szName); + void RemoveGuildMember(const char * c_szName); + void RemoveAllGuildMember(); + void LoginGuildMember(const char * c_szName); + void LogoutGuildMember(const char * c_szName); + void RefreshGuildMember(); + + void SetMessengerHandler(PyObject* poHandler); + + protected: + TFriendNameMap m_FriendNameMap; + TGuildMemberStateMap m_GuildMemberStateMap; + + private: + PyObject * m_poMessengerHandler; +}; diff --git a/source/UserInterface/PythonMiniMap.cpp b/source/UserInterface/PythonMiniMap.cpp new file mode 100644 index 0000000..df05623 --- /dev/null +++ b/source/UserInterface/PythonMiniMap.cpp @@ -0,0 +1,1497 @@ +#include "StdAfx.h" +#include "../eterLib/StateManager.h" +#include "../eterLib/GrpSubImage.h" +#include "../eterlib/Camera.h" +#include "../EterPack/EterPackManager.h" + +#include "PythonMiniMap.h" +#include "PythonBackground.h" +#include "PythonCharacterManager.h" +#include "PythonGuild.h" + +#include "AbstractPlayer.h" + +#include "../eterPythonLib/PythonWindowManager.h" + +void CPythonMiniMap::AddObserver(DWORD dwVID, float fSrcX, float fSrcY) +{ + std::map::iterator f=m_kMap_dwVID_kObserver.find(dwVID); + if (m_kMap_dwVID_kObserver.end()==f) + { + SObserver kObserver; + kObserver.dwSrcTime=ELTimer_GetMSec(); + kObserver.dwDstTime=kObserver.dwSrcTime+1000; + kObserver.fSrcX=fSrcX; + kObserver.fSrcY=fSrcY; + kObserver.fDstX=fSrcX; + kObserver.fDstY=fSrcY; + kObserver.fCurX=fSrcX; + kObserver.fCurY=fSrcY; + m_kMap_dwVID_kObserver.insert(std::map::value_type(dwVID, kObserver)); + } + else + { + SObserver& rkObserver=f->second; + rkObserver.dwSrcTime=ELTimer_GetMSec(); + rkObserver.dwDstTime=rkObserver.dwSrcTime+1000; + rkObserver.fSrcX=fSrcX; + rkObserver.fSrcY=fSrcY; + rkObserver.fDstX=fSrcX; + rkObserver.fDstY=fSrcY; + rkObserver.fCurX=fSrcX; + rkObserver.fCurY=fSrcY; + } +} + +void CPythonMiniMap::MoveObserver(DWORD dwVID, float fDstX, float fDstY) +{ + std::map::iterator f=m_kMap_dwVID_kObserver.find(dwVID); + if (m_kMap_dwVID_kObserver.end()==f) + return; + + SObserver& rkObserver=f->second; + rkObserver.dwSrcTime=ELTimer_GetMSec(); + rkObserver.dwDstTime=rkObserver.dwSrcTime+1000; + rkObserver.fSrcX=rkObserver.fCurX; + rkObserver.fSrcY=rkObserver.fCurY; + rkObserver.fDstX=fDstX; + rkObserver.fDstY=fDstY; +} + +void CPythonMiniMap::RemoveObserver(DWORD dwVID) +{ + m_kMap_dwVID_kObserver.erase(dwVID); +} + +void CPythonMiniMap::SetCenterPosition(float fCenterX, float fCenterY) +{ + m_fCenterX = fCenterX; + m_fCenterY = fCenterY; + + CMapOutdoor& rkMap = CPythonBackground::Instance().GetMapOutdoorRef(); + for (BYTE byTerrainNum = 0; byTerrainNum < AROUND_AREA_NUM; ++byTerrainNum) + { + m_lpMiniMapTexture[byTerrainNum] = NULL; + CTerrain * pTerrain; + if (rkMap.GetTerrainPointer(byTerrainNum, &pTerrain)) + m_lpMiniMapTexture[byTerrainNum] = pTerrain->GetMiniMapTexture(); + } + + const TOutdoorMapCoordinate & rOutdoorMapCoord = rkMap.GetCurCoordinate(); + + m_fCenterCellX = (m_fCenterX - (float)(rOutdoorMapCoord.m_sTerrainCoordX * CTerrainImpl::TERRAIN_XSIZE)) / (float)(CTerrainImpl::CELLSCALE); + m_fCenterCellY = (m_fCenterY - (float)(rOutdoorMapCoord.m_sTerrainCoordY * CTerrainImpl::TERRAIN_YSIZE)) / (float)(CTerrainImpl::CELLSCALE); + + __SetPosition(); +} + +void CPythonMiniMap::Update(float fCenterX, float fCenterY) +{ + CPythonBackground& rkBG=CPythonBackground::Instance(); + if (!rkBG.IsMapOutdoor()) + return; + + // ̴ϸ ׸ + if (m_fCenterX != fCenterX || m_fCenterY != fCenterY ) + SetCenterPosition(fCenterX, fCenterY); + + // ij Ʈ + m_OtherPCPositionVector.clear(); + m_PartyPCPositionVector.clear(); + m_NPCPositionVector.clear(); + m_MonsterPositionVector.clear(); + m_WarpPositionVector.clear(); + + float fooCellScale = 1.0f / ((float) CTerrainImpl::CELLSCALE); + + CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance(); + + CInstanceBase* pkInstMain=rkChrMgr.GetMainInstancePtr(); + if (!pkInstMain) + return; + + CPythonCharacterManager::CharacterIterator i; + for(i = rkChrMgr.CharacterInstanceBegin(); i!=rkChrMgr.CharacterInstanceEnd(); ++i) + { + CInstanceBase* pkInstEach=*i; + + TPixelPosition kInstancePosition; + pkInstEach->NEW_GetPixelPosition(&kInstancePosition); + float fDistanceFromCenterX = (kInstancePosition.x - m_fCenterX) * fooCellScale * m_fScale; + float fDistanceFromCenterY = (kInstancePosition.y - m_fCenterY) * fooCellScale * m_fScale; + if (fabs(fDistanceFromCenterX) >= m_fMiniMapRadius || fabs(fDistanceFromCenterY) >= m_fMiniMapRadius) + continue; + + float fDistanceFromCenter = sqrtf(fDistanceFromCenterX * fDistanceFromCenterX + fDistanceFromCenterY * fDistanceFromCenterY ); + if ( fDistanceFromCenter >= m_fMiniMapRadius ) + continue; + + TMarkPosition aMarkPosition; + + if (pkInstEach->IsPC() && !pkInstEach->IsInvisibility()) + { + if (pkInstEach == CPythonCharacterManager::Instance().GetMainInstancePtr()) + continue; + + aMarkPosition.m_fX = ( m_fWidth - (float)m_WhiteMark.GetWidth() ) / 2.0f + fDistanceFromCenterX + m_fScreenX; + aMarkPosition.m_fY = ( m_fHeight - (float)m_WhiteMark.GetHeight() ) / 2.0f + fDistanceFromCenterY + m_fScreenY; + aMarkPosition.m_eNameColor=pkInstEach->GetNameColorIndex(); + if (aMarkPosition.m_eNameColor==CInstanceBase::NAMECOLOR_PARTY) + m_PartyPCPositionVector.push_back(aMarkPosition); + else + m_OtherPCPositionVector.push_back(aMarkPosition); + } + else if (pkInstEach->IsNPC()) + { + aMarkPosition.m_fX = ( m_fWidth - (float)m_WhiteMark.GetWidth() ) / 2.0f + fDistanceFromCenterX + m_fScreenX; + aMarkPosition.m_fY = ( m_fHeight - (float)m_WhiteMark.GetHeight() ) / 2.0f + fDistanceFromCenterY + m_fScreenY; + + m_NPCPositionVector.push_back(aMarkPosition); + } + else if (pkInstEach->IsEnemy()) + { + aMarkPosition.m_fX = ( m_fWidth - (float)m_WhiteMark.GetWidth() ) / 2.0f + fDistanceFromCenterX + m_fScreenX; + aMarkPosition.m_fY = ( m_fHeight - (float)m_WhiteMark.GetHeight() ) / 2.0f + fDistanceFromCenterY + m_fScreenY; + + m_MonsterPositionVector.push_back(aMarkPosition); + } + else if (pkInstEach->IsWarp()) + { + aMarkPosition.m_fX = ( m_fWidth - (float)m_WhiteMark.GetWidth() ) / 2.0f + fDistanceFromCenterX + m_fScreenX; + aMarkPosition.m_fY = ( m_fHeight - (float)m_WhiteMark.GetHeight() ) / 2.0f + fDistanceFromCenterY + m_fScreenY; + + m_WarpPositionVector.push_back(aMarkPosition); + } + } + + { + DWORD dwCurTime=ELTimer_GetMSec(); + + std::map::iterator i; + for (i=m_kMap_dwVID_kObserver.begin(); i!=m_kMap_dwVID_kObserver.end(); ++i) + { + SObserver& rkObserver=i->second; + + float fPos=float(dwCurTime-rkObserver.dwSrcTime)/float(rkObserver.dwDstTime-rkObserver.dwSrcTime); + if (fPos<0.0f) fPos=0.0f; + else if (fPos>1.0f) fPos=1.0f; + + rkObserver.fCurX=(rkObserver.fDstX-rkObserver.fSrcX)*fPos+rkObserver.fSrcX; + rkObserver.fCurY=(rkObserver.fDstY-rkObserver.fSrcY)*fPos+rkObserver.fSrcY; + + TPixelPosition kInstancePosition; + kInstancePosition.x=rkObserver.fCurX; + kInstancePosition.y=rkObserver.fCurY; + kInstancePosition.z=0.0f; + + float fDistanceFromCenterX = (kInstancePosition.x - m_fCenterX) * fooCellScale * m_fScale; + float fDistanceFromCenterY = (kInstancePosition.y - m_fCenterY) * fooCellScale * m_fScale; + if (fabs(fDistanceFromCenterX) >= m_fMiniMapRadius || fabs(fDistanceFromCenterY) >= m_fMiniMapRadius) + continue; + + float fDistanceFromCenter = sqrtf(fDistanceFromCenterX * fDistanceFromCenterX + fDistanceFromCenterY * fDistanceFromCenterY ); + if ( fDistanceFromCenter >= m_fMiniMapRadius ) + continue; + + TMarkPosition aMarkPosition; + aMarkPosition.m_fX = ( m_fWidth - (float)m_WhiteMark.GetWidth() ) / 2.0f + fDistanceFromCenterX + m_fScreenX; + aMarkPosition.m_fY = ( m_fHeight - (float)m_WhiteMark.GetHeight() ) / 2.0f + fDistanceFromCenterY + m_fScreenY; + aMarkPosition.m_eNameColor=CInstanceBase::NAMECOLOR_PARTY; + m_PartyPCPositionVector.push_back(aMarkPosition); + } + } + + { + TAtlasMarkInfoVector::iterator itor = m_AtlasWayPointInfoVector.begin(); + for (; itor != m_AtlasWayPointInfoVector.end(); ++itor) + { + TAtlasMarkInfo & rAtlasMarkInfo = *itor; + + if (TYPE_TARGET != rAtlasMarkInfo.m_byType) + continue; + + if (0 != rAtlasMarkInfo.m_dwChrVID) + { + CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetInstancePtr(rAtlasMarkInfo.m_dwChrVID); + if (pInstance) + { + TPixelPosition kPixelPosition; + pInstance->NEW_GetPixelPosition(&kPixelPosition); + __UpdateWayPoint(&rAtlasMarkInfo, kPixelPosition.x, kPixelPosition.y); + } + } + + const float c_fMiniMapWindowRadius = 55.0f; + + float fDistanceFromCenterX = (rAtlasMarkInfo.m_fX - m_fCenterX) * fooCellScale * m_fScale; + float fDistanceFromCenterY = (rAtlasMarkInfo.m_fY - m_fCenterY) * fooCellScale * m_fScale; + float fDistanceFromCenter = sqrtf(fDistanceFromCenterX * fDistanceFromCenterX + fDistanceFromCenterY * fDistanceFromCenterY ); + + if (fDistanceFromCenter >= c_fMiniMapWindowRadius) + { + float fRadianX = acosf(fDistanceFromCenterX / fDistanceFromCenter); + float fRadianY = asinf(fDistanceFromCenterY / fDistanceFromCenter); + fDistanceFromCenterX = 55.0f * cosf(fRadianX); + fDistanceFromCenterY = 55.0f * sinf(fRadianY); + rAtlasMarkInfo.m_fMiniMapX = ( m_fWidth - (float)m_WhiteMark.GetWidth() ) / 2.0f + fDistanceFromCenterX + m_fScreenX + 2.0f; + rAtlasMarkInfo.m_fMiniMapY = ( m_fHeight - (float)m_WhiteMark.GetHeight() ) / 2.0f + fDistanceFromCenterY + m_fScreenY + 2.0f; + } + else + { + rAtlasMarkInfo.m_fMiniMapX = ( m_fWidth - (float)m_WhiteMark.GetWidth() ) / 2.0f + fDistanceFromCenterX + m_fScreenX; + rAtlasMarkInfo.m_fMiniMapY = ( m_fHeight - (float)m_WhiteMark.GetHeight() ) / 2.0f + fDistanceFromCenterY + m_fScreenY; + } + } + } +} + +void CPythonMiniMap::Render(float fScreenX, float fScreenY) +{ + CPythonBackground& rkBG=CPythonBackground::Instance(); + if (!rkBG.IsMapOutdoor()) + return; + + if (!m_bShow) + return; + + if (!rkBG.IsMapReady()) + return; + + if (m_fScreenX != fScreenX || m_fScreenY != fScreenY) + { + m_fScreenX = fScreenX; + m_fScreenY = fScreenY; + __SetPosition(); + } + + STATEMANAGER.SaveTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_POINT); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_POINT); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_POINT); + + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); + + STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); + + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + + STATEMANAGER.SaveTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + + STATEMANAGER.SaveRenderState(D3DRS_TEXTUREFACTOR, 0xFF000000); + + STATEMANAGER.SetTexture(1, m_MiniMapFilterGraphicImageInstance.GetTexturePointer()->GetD3DTexture()); + STATEMANAGER.SetTransform(D3DTS_TEXTURE1, &m_matMiniMapCover); + + STATEMANAGER.SetVertexShader(D3DFVF_XYZ | D3DFVF_TEX1); + STATEMANAGER.SetStreamSource(0, m_VertexBuffer.GetD3DVertexBuffer(), 20); + STATEMANAGER.SetIndices(m_IndexBuffer.GetD3DIndexBuffer(), 0); + STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matWorld); + + for (BYTE byTerrainNum = 0; byTerrainNum < AROUND_AREA_NUM; ++byTerrainNum) + { + LPDIRECT3DTEXTURE8 pMiniMapTexture = m_lpMiniMapTexture[byTerrainNum]; + STATEMANAGER.SetTexture(0, pMiniMapTexture); + if (pMiniMapTexture) + { + CStateManager& rkSttMgr=CStateManager::Instance(); + rkSttMgr.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, byTerrainNum * 4, 4, byTerrainNum * 6, 2); + } + else + { + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, byTerrainNum * 4, 4, byTerrainNum * 6, 2); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + } + } + + STATEMANAGER.RestoreRenderState(D3DRS_TEXTUREFACTOR); + + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ALPHAARG2); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ALPHAARG1); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ALPHAOP); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_COLORARG1); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_COLORARG2); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_COLOROP); + + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAARG2); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAARG1); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAOP); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG2); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP); + + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSU); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSV); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXCOORDINDEX); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSU); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSV); + + SetDiffuseOperation(); + STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matIdentity); + + STATEMANAGER.SaveRenderState(D3DRS_TEXTUREFACTOR, 0xFFFFFFFF); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); + + TInstancePositionVectorIterator aIterator; + + if (m_fScale >= 2.0f) + { + // Monster + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_MOB));//m_MarkTypeToColorMap[TYPE_MONSTER]); + aIterator = m_MonsterPositionVector.begin(); + while (aIterator != m_MonsterPositionVector.end()) + { + TMarkPosition & rPosition = *aIterator; + m_WhiteMark.SetPosition(rPosition.m_fX, rPosition.m_fY); + m_WhiteMark.Render(); + ++aIterator; + } + + // Other PC + aIterator = m_OtherPCPositionVector.begin(); + while (aIterator != m_OtherPCPositionVector.end()) + { + TMarkPosition & rPosition = *aIterator; + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, CInstanceBase::GetIndexedNameColor(rPosition.m_eNameColor)); + m_WhiteMark.SetPosition(rPosition.m_fX, rPosition.m_fY); + m_WhiteMark.Render(); + ++aIterator; + } + + // Party PC + if (!m_PartyPCPositionVector.empty()) + { + float v = (1+sinf(CTimer::Instance().GetCurrentSecond()*6))/5+0.6; + D3DXCOLOR c(CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_PARTY));//(m_MarkTypeToColorMap[TYPE_PARTY]); + D3DXCOLOR d(v,v,v,1); + D3DXColorModulate(&c,&c,&d); + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, (DWORD)c); + aIterator = m_PartyPCPositionVector.begin(); + while (aIterator != m_PartyPCPositionVector.end()) + { + TMarkPosition & rPosition = *aIterator; + m_WhiteMark.SetPosition(rPosition.m_fX, rPosition.m_fY); + m_WhiteMark.Render(); + ++aIterator; + } + } + } + + // NPC + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_NPC)); + aIterator = m_NPCPositionVector.begin(); + while (aIterator != m_NPCPositionVector.end()) + { + TMarkPosition & rPosition = *aIterator; + m_WhiteMark.SetPosition(rPosition.m_fX, rPosition.m_fY); + m_WhiteMark.Render(); + ++aIterator; + } + + // Warp + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_WARP)); + aIterator = m_WarpPositionVector.begin(); + while (aIterator != m_WarpPositionVector.end()) + { + TMarkPosition & rPosition = *aIterator; + m_WhiteMark.SetPosition(rPosition.m_fX, rPosition.m_fY); + m_WhiteMark.Render(); + ++aIterator; + } + + STATEMANAGER.RestoreRenderState(D3DRS_TEXTUREFACTOR); + + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAARG2); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAARG1); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAOP); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG2); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP); + + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MIPFILTER); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MINFILTER); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MAGFILTER); + + STATEMANAGER.SaveTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + + // ij ũ + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetMainInstancePtr(); + + if (pkInst) + { + float fRotation; + fRotation = (540.0f - pkInst->GetRotation()); + while(fRotation > 360.0f) + fRotation -= 360.0f; + while(fRotation < 0.0f) + fRotation += 360.0f; + + m_PlayerMark.SetRotation(fRotation); + m_PlayerMark.Render(); + } + + // Target + { + TAtlasMarkInfoVector::iterator itor = m_AtlasWayPointInfoVector.begin(); + for (; itor != m_AtlasWayPointInfoVector.end(); ++itor) + { + TAtlasMarkInfo & rAtlasMarkInfo = *itor; + + if (TYPE_TARGET != rAtlasMarkInfo.m_byType) + continue; + if (rAtlasMarkInfo.m_fMiniMapX <= 0.0f) + continue; + if (rAtlasMarkInfo.m_fMiniMapY <= 0.0f) + continue; + + __RenderTargetMark(rAtlasMarkInfo.m_fMiniMapX, rAtlasMarkInfo.m_fMiniMapY); + } + } + + CCamera* pkCmrCur=CCameraManager::Instance().GetCurrentCamera(); + + // ī޶ + if (pkCmrCur) + { + m_MiniMapCameraraphicImageInstance.SetRotation(pkCmrCur->GetRoll()); + m_MiniMapCameraraphicImageInstance.Render(); + } + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MINFILTER); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MAGFILTER); +} + +void CPythonMiniMap::SetScale(float fScale) +{ + if (fScale >= 4.0f) + fScale = 4.0f; + if (fScale <= 0.5f) + fScale = 0.5f; + m_fScale = fScale; + + __SetPosition(); +} + +void CPythonMiniMap::ScaleUp() +{ + m_fScale *= 2.0f; + if (m_fScale >= 4.0f) + m_fScale = 4.0f; + __SetPosition(); +} + +void CPythonMiniMap::ScaleDown() +{ + m_fScale *= 0.5f; + if (m_fScale <= 0.5f) + m_fScale = 0.5f; + __SetPosition(); +} + +void CPythonMiniMap::SetMiniMapSize(float fWidth, float fHeight) +{ + m_fWidth = fWidth; + m_fHeight = fHeight; +} + +#pragma pack(push) +#pragma pack(1) +typedef struct _MINIMAPVERTEX +{ + float x, y, z; // position + float u, v; // normal +} MINIMAPVERTEX, *LPMINIMAPVERTEX; +#pragma pack(pop) + +bool CPythonMiniMap::Create() +{ + const std::string strImageRoot = "D:/ymir work/ui/"; + const std::string strImageFilter = strImageRoot + "minimap_image_filter.dds"; + const std::string strImageCamera = strImageRoot + "minimap_camera.dds"; + const std::string strPlayerMark = strImageRoot + "minimap/playermark.sub"; + const std::string strWhiteMark = strImageRoot + "minimap/whitemark.sub"; + + // ̴ϸ Ŀ + CGraphicImage * pImage = (CGraphicImage *) CResourceManager::Instance().GetResourcePointer(strImageFilter.c_str()); + m_MiniMapFilterGraphicImageInstance.SetImagePointer(pImage); + pImage = (CGraphicImage *) CResourceManager::Instance().GetResourcePointer(strImageCamera.c_str()); + m_MiniMapCameraraphicImageInstance.SetImagePointer(pImage); + + m_matMiniMapCover._11 = 1.0f / ((float)m_MiniMapFilterGraphicImageInstance.GetWidth()); + m_matMiniMapCover._22 = 1.0f / ((float)m_MiniMapFilterGraphicImageInstance.GetHeight()); + m_matMiniMapCover._33 = 0.0f; + + // ij ũ + CGraphicSubImage * pSubImage = (CGraphicSubImage *) CResourceManager::Instance().GetResourcePointer(strPlayerMark.c_str()); + m_PlayerMark.SetImagePointer(pSubImage); + + pSubImage = (CGraphicSubImage *) CResourceManager::Instance().GetResourcePointer(strWhiteMark.c_str()); + m_WhiteMark.SetImagePointer(pSubImage); + + char buf[256]; + for (int i = 0; i < MINI_WAYPOINT_IMAGE_COUNT; ++i) + { + sprintf(buf, "%sminimap/mini_waypoint%02d.sub", strImageRoot.c_str(), i+1); + m_MiniWayPointGraphicImageInstances[i].SetImagePointer((CGraphicSubImage *) CResourceManager::Instance().GetResourcePointer(buf)); + m_MiniWayPointGraphicImageInstances[i].SetRenderingMode(CGraphicExpandedImageInstance::RENDERING_MODE_SCREEN); + } + for (int j = 0; j < WAYPOINT_IMAGE_COUNT; ++j) + { + sprintf(buf, "%sminimap/waypoint%02d.sub", strImageRoot.c_str(), j+1); + m_WayPointGraphicImageInstances[j].SetImagePointer((CGraphicSubImage *) CResourceManager::Instance().GetResourcePointer(buf)); + m_WayPointGraphicImageInstances[j].SetRenderingMode(CGraphicExpandedImageInstance::RENDERING_MODE_SCREEN); + } + for (int k = 0; k < TARGET_MARK_IMAGE_COUNT; ++k) + { + sprintf(buf, "%sminimap/targetmark%02d.sub", strImageRoot.c_str(), k+1); + m_TargetMarkGraphicImageInstances[k].SetImagePointer((CGraphicSubImage *) CResourceManager::Instance().GetResourcePointer(buf)); + m_TargetMarkGraphicImageInstances[k].SetRenderingMode(CGraphicExpandedImageInstance::RENDERING_MODE_SCREEN); + } + + m_GuildAreaFlagImageInstance.SetImagePointer((CGraphicSubImage *) CResourceManager::Instance().GetResourcePointer("d:/ymir work/ui/minimap/GuildArea01.sub")); + + // ׷ +#pragma pack(push) +#pragma pack(1) + LPMINIMAPVERTEX lpMiniMapVertex; + LPMINIMAPVERTEX lpOrigMiniMapVertex; +#pragma pack(pop) + + if (!m_VertexBuffer.Create(36, D3DFVF_XYZ | D3DFVF_TEX1, D3DUSAGE_WRITEONLY, D3DPOOL_MANAGED) ) + { + return false; + } + + if (m_VertexBuffer.Lock((void **) &lpOrigMiniMapVertex)) + { + char * pchMiniMapVertex = (char *)lpOrigMiniMapVertex; + memset(pchMiniMapVertex, 0, sizeof(char) * 720); + lpMiniMapVertex = (LPMINIMAPVERTEX) pchMiniMapVertex; + + for (int iY = -3; iY <= 1; ++iY) + { + if (0 == iY%2) + continue; + float fY = 0.5f * ((float)iY); + for (int iX = -3; iX <= 1; ++iX) + { + if (0 == iX%2) + continue; + float fX = 0.5f * ((float)iX); + lpMiniMapVertex = (LPMINIMAPVERTEX) pchMiniMapVertex; + lpMiniMapVertex->x = fX; + lpMiniMapVertex->y = fY; + lpMiniMapVertex->z = 0.0f; + lpMiniMapVertex->u = 0.0f; + lpMiniMapVertex->v = 0.0f; + pchMiniMapVertex += 20; + lpMiniMapVertex = (LPMINIMAPVERTEX) pchMiniMapVertex; + lpMiniMapVertex->x = fX; + lpMiniMapVertex->y = fY + 1.0f; + lpMiniMapVertex->z = 0.0f; + lpMiniMapVertex->u = 0.0f; + lpMiniMapVertex->v = 1.0f; + pchMiniMapVertex += 20; + lpMiniMapVertex = (LPMINIMAPVERTEX) pchMiniMapVertex; + lpMiniMapVertex->x = fX + 1.0f; + lpMiniMapVertex->y = fY; + lpMiniMapVertex->z = 0.0f; + lpMiniMapVertex->u = 1.0f; + lpMiniMapVertex->v = 0.0f; + pchMiniMapVertex += 20; + lpMiniMapVertex = (LPMINIMAPVERTEX) pchMiniMapVertex; + lpMiniMapVertex->x = fX + 1.0f; + lpMiniMapVertex->y = fY + 1.0f; + lpMiniMapVertex->z = 0.0f; + lpMiniMapVertex->u = 1.0f; + lpMiniMapVertex->v = 1.0f; + pchMiniMapVertex += 20; + } + } + + m_VertexBuffer.Unlock(); + } + + if (!m_IndexBuffer.Create(54, D3DFMT_INDEX16)) + { + return false; + } + + WORD pwIndices[54] = + { + 0, 1, 2, 2, 1, 3, + 4, 5, 6, 6, 5, 7, + 8, 9, 10, 10, 9, 11, + + 12, 13, 14, 14, 13, 15, + 16, 17, 18, 18, 17, 19, + 20, 21, 22, 22, 21, 23, + + 24, 25, 26, 26, 25, 27, + 28, 29, 30, 30, 29, 31, + 32, 33, 34, 34, 33, 35 + }; + + void * pIndices; + + if (m_IndexBuffer.Lock(&pIndices)) + { + memcpy(pIndices, pwIndices, 54 * sizeof(WORD)); + m_IndexBuffer.Unlock(); + } + + return true; +} + +void CPythonMiniMap::__SetPosition() +{ + m_fMiniMapRadius = fMIN(6400.0f / ((float) CTerrainImpl::CELLSCALE) * m_fScale, 64.0f); + + m_matWorld._11 = m_fWidth * m_fScale; + m_matWorld._22 = m_fHeight * m_fScale; + m_matWorld._41 = (1.0f + m_fScale) * m_fWidth * 0.5f - m_fCenterCellX * m_fScale + m_fScreenX; + m_matWorld._42 = (1.0f + m_fScale) * m_fHeight * 0.5f - m_fCenterCellY * m_fScale + m_fScreenY; + + if (!m_MiniMapFilterGraphicImageInstance.IsEmpty()) + { + m_matMiniMapCover._41 = -(m_fScreenX) / ((float)m_MiniMapFilterGraphicImageInstance.GetWidth()); + m_matMiniMapCover._42 = -(m_fScreenY) / ((float)m_MiniMapFilterGraphicImageInstance.GetHeight()); + } + + if (!m_PlayerMark.IsEmpty()) + m_PlayerMark.SetPosition( ( m_fWidth - (float)m_PlayerMark.GetWidth() ) / 2.0f + m_fScreenX, + ( m_fHeight - (float)m_PlayerMark.GetHeight() ) / 2.0f + m_fScreenY ); + + if (!m_MiniMapCameraraphicImageInstance.IsEmpty()) + m_MiniMapCameraraphicImageInstance.SetPosition( ( m_fWidth - (float)m_MiniMapCameraraphicImageInstance.GetWidth() ) / 2.0f + m_fScreenX, + ( m_fHeight - (float)m_MiniMapCameraraphicImageInstance.GetHeight() ) / 2.0f + m_fScreenY ); +} + +////////////////////////////////////////////////////////////////////////// +// Atlas + +void CPythonMiniMap::ClearAtlasMarkInfo() +{ + m_AtlasNPCInfoVector.clear(); + m_AtlasWarpInfoVector.clear(); +} + +void CPythonMiniMap::RegisterAtlasMark(BYTE byType, const char * c_szName, long lx, long ly) +{ + TAtlasMarkInfo aAtlasMarkInfo; + + aAtlasMarkInfo.m_fX = float(lx); + aAtlasMarkInfo.m_fY = float(ly); + aAtlasMarkInfo.m_strText = c_szName; + + aAtlasMarkInfo.m_fScreenX = aAtlasMarkInfo.m_fX / m_fAtlasMaxX * m_fAtlasImageSizeX - (float)m_WhiteMark.GetWidth() / 2.0f; + aAtlasMarkInfo.m_fScreenY = aAtlasMarkInfo.m_fY / m_fAtlasMaxY * m_fAtlasImageSizeY - (float)m_WhiteMark.GetHeight() / 2.0f; + + switch(byType) + { + case CActorInstance::TYPE_NPC: + aAtlasMarkInfo.m_byType = TYPE_NPC; + m_AtlasNPCInfoVector.push_back(aAtlasMarkInfo); + break; + case CActorInstance::TYPE_WARP: + aAtlasMarkInfo.m_byType = TYPE_WARP; + { + int iPos = aAtlasMarkInfo.m_strText.find(" "); + if (iPos >= 0) + aAtlasMarkInfo.m_strText[iPos]=0; + + } + m_AtlasWarpInfoVector.push_back(aAtlasMarkInfo); + break; + } +} + +void CPythonMiniMap::ClearGuildArea() +{ + m_GuildAreaInfoVector.clear(); +} + +void CPythonMiniMap::RegisterGuildArea(DWORD dwID, DWORD dwGuildID, long x, long y, long width, long height) +{ + TGuildAreaInfo kGuildAreaInfo; + kGuildAreaInfo.dwGuildID = dwGuildID; + kGuildAreaInfo.lx = x; + kGuildAreaInfo.ly = y; + kGuildAreaInfo.lwidth = width; + kGuildAreaInfo.lheight = height; + m_GuildAreaInfoVector.push_back(kGuildAreaInfo); +} + +DWORD CPythonMiniMap::GetGuildAreaID(DWORD x, DWORD y) +{ + TGuildAreaInfoVectorIterator itor = m_GuildAreaInfoVector.begin(); + for (; itor != m_GuildAreaInfoVector.end(); ++itor) + { + TGuildAreaInfo & rAreaInfo = *itor; + + if (x >= rAreaInfo.lx) + if (y >= rAreaInfo.ly) + if (x <= rAreaInfo.lx + rAreaInfo.lwidth) + if (y <= rAreaInfo.ly + rAreaInfo.lheight) + { + return rAreaInfo.dwGuildID; + } + } + + return 0xffffffff; +} + +void CPythonMiniMap::CreateTarget(int iID, const char * c_szName) +{ + AddWayPoint(TYPE_TARGET, iID, 0.0f, 0.0f, c_szName); +} + +void CPythonMiniMap::UpdateTarget(int iID, int ix, int iy) +{ + TAtlasMarkInfo * pkInfo; + if (!__GetWayPoint(iID, &pkInfo)) + return; + + if (0 != pkInfo->m_dwChrVID) + { + if (CPythonCharacterManager::Instance().GetInstancePtr(pkInfo->m_dwChrVID)) + return; + } + + if (ix < m_dwAtlasBaseX) + return; + if (iy < m_dwAtlasBaseY) + return; + if (ix > m_dwAtlasBaseX+DWORD(m_fAtlasMaxX)) + return; + if (iy > m_dwAtlasBaseY+DWORD(m_fAtlasMaxY)) + return; + + __UpdateWayPoint(pkInfo, ix-int(m_dwAtlasBaseX), iy-int(m_dwAtlasBaseY)); +} + +void CPythonMiniMap::CreateTarget(int iID, const char * c_szName, DWORD dwVID) +{ + AddWayPoint(TYPE_TARGET, iID, 0.0f, 0.0f, c_szName, dwVID); +} + +void CPythonMiniMap::DeleteTarget(int iID) +{ + RemoveWayPoint(iID); +} + +void CPythonMiniMap::__LoadAtlasMarkInfo() +{ + ClearAtlasMarkInfo(); + ClearGuildArea(); + + CPythonBackground& rkBG=CPythonBackground::Instance(); + if (!rkBG.IsMapOutdoor()) + return; + + CMapOutdoor& rkMap=rkBG.GetMapOutdoorRef(); + + // LOCALE + char szAtlasMarkInfoFileName[64+1]; + _snprintf(szAtlasMarkInfoFileName, sizeof(szAtlasMarkInfoFileName), "%s/map/%s_point.txt", LocaleService_GetLocalePath(), rkMap.GetName().c_str()); + // END_OF_LOCALE + + CTokenVectorMap stTokenVectorMap; + + if (!LoadMultipleTextData(szAtlasMarkInfoFileName, stTokenVectorMap)) + { + Tracef(" CPythonMiniMap::__LoadAtlasMarkInfo File Load %s ERROR\n", szAtlasMarkInfoFileName); + return; + } + + const std::string strType[TYPE_COUNT] = { "OPC", "OPCPVP", "OPCPVPSELF", "NPC", "MONSTER", "WARP", "WAYPOINT" }; + + for (DWORD i = 0; i < stTokenVectorMap.size(); ++i) + { + char szMarkInfoName[32+1]; + _snprintf(szMarkInfoName, sizeof(szMarkInfoName), "%d", i); + + if (stTokenVectorMap.end() == stTokenVectorMap.find(szMarkInfoName)) + continue; + + const CTokenVector & rVector = stTokenVectorMap[szMarkInfoName]; + + const std::string & c_rstrType = rVector[0].c_str(); + const std::string & c_rstrPositionX = rVector[1].c_str(); + const std::string & c_rstrPositionY = rVector[2].c_str(); + const std::string & c_rstrText = rVector[3].c_str(); + + TAtlasMarkInfo aAtlasMarkInfo; + + for ( int i = 0; i < TYPE_COUNT; ++i) + { + if (0 == c_rstrType.compare(strType[i])) + aAtlasMarkInfo.m_byType = (BYTE)i; + } + aAtlasMarkInfo.m_fX = atof(c_rstrPositionX.c_str()); + aAtlasMarkInfo.m_fY = atof(c_rstrPositionY.c_str()); + aAtlasMarkInfo.m_strText = c_rstrText; + + aAtlasMarkInfo.m_fScreenX = aAtlasMarkInfo.m_fX / m_fAtlasMaxX * m_fAtlasImageSizeX - (float)m_WhiteMark.GetWidth() / 2.0f; + aAtlasMarkInfo.m_fScreenY = aAtlasMarkInfo.m_fY / m_fAtlasMaxY * m_fAtlasImageSizeY - (float)m_WhiteMark.GetHeight() / 2.0f; + + switch(aAtlasMarkInfo.m_byType) + { + case TYPE_NPC: + m_AtlasNPCInfoVector.push_back(aAtlasMarkInfo); + break; + case TYPE_WARP: + m_AtlasWarpInfoVector.push_back(aAtlasMarkInfo); + break; + } + } +} + +bool CPythonMiniMap::LoadAtlas() +{ + CPythonBackground& rkBG=CPythonBackground::Instance(); + if (!rkBG.IsMapOutdoor()) + return false; + + CMapOutdoor& rkMap=rkBG.GetMapOutdoorRef(); + + const char* playerMarkFileName = "d:/ymir work/ui/minimap/playermark.sub"; + + char atlasFileName[1024+1]; + snprintf(atlasFileName, sizeof(atlasFileName), "%s/atlas.sub", rkMap.GetName().c_str()); + if (!CEterPackManager::Instance().isExist(atlasFileName)) + { + snprintf(atlasFileName, sizeof(atlasFileName), "d:/ymir work/ui/atlas/%s/atlas.sub", rkMap.GetName().c_str()); + } + + m_AtlasImageInstance.Destroy(); + m_AtlasPlayerMark.Destroy(); + CGraphicImage* pkGrpImgAtlas = (CGraphicImage *) CResourceManager::Instance().GetResourcePointer(atlasFileName); + if (pkGrpImgAtlas) + { + m_AtlasImageInstance.SetImagePointer(pkGrpImgAtlas); + + if (pkGrpImgAtlas->IsEmpty()) + m_bAtlas=false; + else + m_bAtlas=true; + } + else + { + } + m_AtlasPlayerMark.SetImagePointer((CGraphicSubImage *) CResourceManager::Instance().GetResourcePointer(playerMarkFileName)); + + short sTerrainCountX, sTerrainCountY; + rkMap.GetBaseXY(&m_dwAtlasBaseX, &m_dwAtlasBaseY); + rkMap.GetTerrainCount(&sTerrainCountX, &sTerrainCountY); + m_fAtlasMaxX = (float) sTerrainCountX * static_cast(CTerrainImpl::TERRAIN_XSIZE); + m_fAtlasMaxY = (float) sTerrainCountY * static_cast(CTerrainImpl::TERRAIN_YSIZE); + + m_fAtlasImageSizeX = (float) m_AtlasImageInstance.GetWidth(); + m_fAtlasImageSizeY = (float) m_AtlasImageInstance.GetHeight(); + + __LoadAtlasMarkInfo(); + + if (m_bShowAtlas) + OpenAtlasWindow(); + + return true; +} + +void CPythonMiniMap::__GlobalPositionToAtlasPosition(long lx, long ly, float * pfx, float * pfy) +{ + *pfx = lx / m_fAtlasMaxX * m_fAtlasImageSizeX; + *pfy = ly / m_fAtlasMaxY * m_fAtlasImageSizeY; +} + +void CPythonMiniMap::UpdateAtlas() +{ + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetMainInstancePtr(); + + if (pkInst) + { + TPixelPosition kInstPos; + pkInst->NEW_GetPixelPosition(&kInstPos); + + float fRotation; + fRotation = (540.0f - pkInst->GetRotation()); + while(fRotation > 360.0f) + fRotation -= 360.0f; + while(fRotation < 0.0f) + fRotation += 360.0f; + + m_AtlasPlayerMark.SetPosition(kInstPos.x / m_fAtlasMaxX * m_fAtlasImageSizeX - (float)m_AtlasPlayerMark.GetWidth() / 2.0f, + kInstPos.y / m_fAtlasMaxY * m_fAtlasImageSizeY - (float)m_AtlasPlayerMark.GetHeight() / 2.0f); + m_AtlasPlayerMark.SetRotation(fRotation); + } + + { + TGuildAreaInfoVectorIterator itor = m_GuildAreaInfoVector.begin(); + for (; itor != m_GuildAreaInfoVector.end(); ++itor) + { + TGuildAreaInfo & rInfo = *itor; + __GlobalPositionToAtlasPosition(rInfo.lx, rInfo.ly, &rInfo.fsxRender, &rInfo.fsyRender); + __GlobalPositionToAtlasPosition(rInfo.lx+rInfo.lwidth, rInfo.ly+rInfo.lheight, &rInfo.fexRender, &rInfo.feyRender); + } + } +} + +void CPythonMiniMap::RenderAtlas(float fScreenX, float fScreenY) +{ + if (!m_bShowAtlas) + return; + + if (m_fAtlasScreenX != fScreenX || m_fAtlasScreenY != fScreenY) + { + m_matWorldAtlas._41 = fScreenX; + m_matWorldAtlas._42 = fScreenY; + m_fAtlasScreenX = fScreenX; + m_fAtlasScreenY = fScreenY; + } + + STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matWorldAtlas); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_POINT); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_POINT); + m_AtlasImageInstance.Render(); + + STATEMANAGER.SaveRenderState(D3DRS_TEXTUREFACTOR, 0xFFFFFFFF); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_NPC)); + m_AtlasMarkInfoVectorIterator = m_AtlasNPCInfoVector.begin(); + while (m_AtlasMarkInfoVectorIterator != m_AtlasNPCInfoVector.end()) + { + TAtlasMarkInfo & rAtlasMarkInfo = *m_AtlasMarkInfoVectorIterator; + m_WhiteMark.SetPosition(rAtlasMarkInfo.m_fScreenX, rAtlasMarkInfo.m_fScreenY); + m_WhiteMark.Render(); + ++m_AtlasMarkInfoVectorIterator; + } + + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_WARP)); + m_AtlasMarkInfoVectorIterator = m_AtlasWarpInfoVector.begin(); + while (m_AtlasMarkInfoVectorIterator != m_AtlasWarpInfoVector.end()) + { + TAtlasMarkInfo & rAtlasMarkInfo = *m_AtlasMarkInfoVectorIterator; + m_WhiteMark.SetPosition(rAtlasMarkInfo.m_fScreenX, rAtlasMarkInfo.m_fScreenY); + m_WhiteMark.Render(); + ++m_AtlasMarkInfoVectorIterator; + } + + STATEMANAGER.SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + STATEMANAGER.SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_WAYPOINT)); + m_AtlasMarkInfoVectorIterator = m_AtlasWayPointInfoVector.begin(); + for (; m_AtlasMarkInfoVectorIterator != m_AtlasWayPointInfoVector.end(); ++m_AtlasMarkInfoVectorIterator) + { + TAtlasMarkInfo & rAtlasMarkInfo = *m_AtlasMarkInfoVectorIterator; + + if (rAtlasMarkInfo.m_fScreenX <= 0.0f) + continue; + if (rAtlasMarkInfo.m_fScreenY <= 0.0f) + continue; + + if (TYPE_TARGET == rAtlasMarkInfo.m_byType) + { + __RenderMiniWayPointMark(rAtlasMarkInfo.m_fScreenX, rAtlasMarkInfo.m_fScreenY); + } + else + { + __RenderWayPointMark(rAtlasMarkInfo.m_fScreenX, rAtlasMarkInfo.m_fScreenY); + } + } + + STATEMANAGER.RestoreRenderState(D3DRS_TEXTUREFACTOR); + + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG2); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP); + + if ((ELTimer_GetMSec() / 500) % 2) + m_AtlasPlayerMark.Render(); + + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MINFILTER); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MAGFILTER); + STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matIdentity); + + { + TGuildAreaInfoVectorIterator itor = m_GuildAreaInfoVector.begin(); + for (; itor != m_GuildAreaInfoVector.end(); ++itor) + { + TGuildAreaInfo & rInfo = *itor; + + m_GuildAreaFlagImageInstance.SetPosition(fScreenX+(rInfo.fsxRender+rInfo.fexRender)/2.0f - m_GuildAreaFlagImageInstance.GetWidth()/2, + fScreenY+(rInfo.fsyRender+rInfo.feyRender)/2.0f - m_GuildAreaFlagImageInstance.GetHeight()/2); + m_GuildAreaFlagImageInstance.Render(); + +// CScreen::RenderBar2d(fScreenX+rInfo.fsxRender, +// fScreenY+rInfo.fsyRender, +// fScreenX+rInfo.fexRender, +// fScreenY+rInfo.feyRender); + } + } +} + +bool CPythonMiniMap::GetPickedInstanceInfo(float fScreenX, float fScreenY, std::string & rReturnName, float * pReturnPosX, float * pReturnPosY, DWORD * pdwTextColor) +{ + float fDistanceFromMiniMapCenterX = fScreenX - m_fScreenX - m_fWidth * 0.5f; + float fDistanceFromMiniMapCenterY = fScreenY - m_fScreenY - m_fHeight * 0.5f; + + if (sqrtf(fDistanceFromMiniMapCenterX * fDistanceFromMiniMapCenterX + fDistanceFromMiniMapCenterY * fDistanceFromMiniMapCenterY) > m_fMiniMapRadius ) + return false; + + float fRealX = m_fCenterX + fDistanceFromMiniMapCenterX / m_fScale * ((float) CTerrainImpl::CELLSCALE); + float fRealY = m_fCenterY + fDistanceFromMiniMapCenterY / m_fScale * ((float) CTerrainImpl::CELLSCALE); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetMainInstancePtr(); + + if (pkInst) + { + TPixelPosition kInstPos; + pkInst->NEW_GetPixelPosition(&kInstPos); + + if (fabs(kInstPos.x - fRealX) < ((float) CTerrainImpl::CELLSCALE) * 6.0f / m_fScale && + fabs(kInstPos.y - fRealY) < ((float) CTerrainImpl::CELLSCALE) * 6.0f / m_fScale) + { + rReturnName = pkInst->GetNameString(); + *pReturnPosX = kInstPos.x; + *pReturnPosY = kInstPos.y; + *pdwTextColor = pkInst->GetNameColor(); + return true; + } + } + + if (m_fScale < 1.0f) + return false; + + CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance(); + CPythonCharacterManager::CharacterIterator i; + for(i = rkChrMgr.CharacterInstanceBegin(); i!=rkChrMgr.CharacterInstanceEnd(); ++i) + { + CInstanceBase* pkInstEach=*i; + if (pkInstEach->IsInvisibility()) + continue; + if (m_fScale < 2.0f && (pkInstEach->IsEnemy() || pkInstEach->IsPC())) + continue; + TPixelPosition kInstancePosition; + pkInstEach->NEW_GetPixelPosition(&kInstancePosition); + + if (fabs(kInstancePosition.x - fRealX) < ((float) CTerrainImpl::CELLSCALE) * 3.0f / m_fScale && + fabs(kInstancePosition.y - fRealY) < ((float) CTerrainImpl::CELLSCALE) * 3.0f / m_fScale) + { + rReturnName = pkInstEach->GetNameString(); + *pReturnPosX = kInstancePosition.x; + *pReturnPosY = kInstancePosition.y; + *pdwTextColor = pkInstEach->GetNameColor(); + return true; + } + } + return false; +} + + +bool CPythonMiniMap::GetAtlasInfo(float fScreenX, float fScreenY, std::string & rReturnString, float * pReturnPosX, float * pReturnPosY, DWORD * pdwTextColor, DWORD * pdwGuildID) +{ + float fRealX = (fScreenX - m_fAtlasScreenX) * (m_fAtlasMaxX / m_fAtlasImageSizeX); + float fRealY = (fScreenY - m_fAtlasScreenY) * (m_fAtlasMaxY / m_fAtlasImageSizeY); + + //((float) CTerrainImpl::CELLSCALE) * 10.0f + float fCheckWidth = (m_fAtlasMaxX / m_fAtlasImageSizeX) * 5.0f; + float fCheckHeight = (m_fAtlasMaxY / m_fAtlasImageSizeY) * 5.0f; + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetMainInstancePtr(); + + if (pkInst) + { + TPixelPosition kInstPos; + pkInst->NEW_GetPixelPosition(&kInstPos); + + if (kInstPos.x-fCheckWidthfRealX && + kInstPos.y-fCheckHeightfRealY) + { + rReturnString = pkInst->GetNameString(); + *pReturnPosX = kInstPos.x; + *pReturnPosY = kInstPos.y; + *pdwTextColor = pkInst->GetNameColor(); + return true; + } + } + + m_AtlasMarkInfoVectorIterator = m_AtlasNPCInfoVector.begin(); + while (m_AtlasMarkInfoVectorIterator != m_AtlasNPCInfoVector.end()) + { + TAtlasMarkInfo & rAtlasMarkInfo = *m_AtlasMarkInfoVectorIterator; + + if (rAtlasMarkInfo.m_fX-fCheckWidth/2fRealX && + rAtlasMarkInfo.m_fY-fCheckWidth/2fRealY) + { + rReturnString = rAtlasMarkInfo.m_strText; + *pReturnPosX = rAtlasMarkInfo.m_fX; + *pReturnPosY = rAtlasMarkInfo.m_fY; + *pdwTextColor = CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_NPC);//m_MarkTypeToColorMap[rAtlasMarkInfo.m_byType]; + return true; + } + ++m_AtlasMarkInfoVectorIterator; + } + + m_AtlasMarkInfoVectorIterator = m_AtlasWarpInfoVector.begin(); + while (m_AtlasMarkInfoVectorIterator != m_AtlasWarpInfoVector.end()) + { + TAtlasMarkInfo & rAtlasMarkInfo = *m_AtlasMarkInfoVectorIterator; + if (rAtlasMarkInfo.m_fX-fCheckWidth/2fRealX && + rAtlasMarkInfo.m_fY-fCheckWidth/2fRealY) + { + rReturnString = rAtlasMarkInfo.m_strText; + *pReturnPosX = rAtlasMarkInfo.m_fX; + *pReturnPosY = rAtlasMarkInfo.m_fY; + *pdwTextColor = CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_WARP);//m_MarkTypeToColorMap[rAtlasMarkInfo.m_byType]; + return true; + } + ++m_AtlasMarkInfoVectorIterator; + } + + m_AtlasMarkInfoVectorIterator = m_AtlasWayPointInfoVector.begin(); + while (m_AtlasMarkInfoVectorIterator != m_AtlasWayPointInfoVector.end()) + { + TAtlasMarkInfo & rAtlasMarkInfo = *m_AtlasMarkInfoVectorIterator; + if (rAtlasMarkInfo.m_fScreenX > 0.0f) + if (rAtlasMarkInfo.m_fScreenY > 0.0f) + if (rAtlasMarkInfo.m_fX-fCheckWidth/2fRealX && + rAtlasMarkInfo.m_fY-fCheckWidth/2fRealY) + { + rReturnString = rAtlasMarkInfo.m_strText; + *pReturnPosX = rAtlasMarkInfo.m_fX; + *pReturnPosY = rAtlasMarkInfo.m_fY; + *pdwTextColor = CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_WAYPOINT);//m_MarkTypeToColorMap[rAtlasMarkInfo.m_byType]; + return true; + } + ++m_AtlasMarkInfoVectorIterator; + } + + TGuildAreaInfoVector::iterator itor = m_GuildAreaInfoVector.begin(); + for (; itor!=m_GuildAreaInfoVector.end(); ++itor) + { + TGuildAreaInfo & rInfo = *itor; + if (fScreenX - m_fAtlasScreenX >= rInfo.fsxRender) + if (fScreenY - m_fAtlasScreenY >= rInfo.fsyRender) + if (fScreenX - m_fAtlasScreenX <= rInfo.fexRender) + if (fScreenY - m_fAtlasScreenY <= rInfo.feyRender) + { + if (CPythonGuild::Instance().GetGuildName(rInfo.dwGuildID, &rReturnString)) + { + *pdwGuildID = rInfo.dwGuildID; + } + else + { + rReturnString = "empty_guild_area"; + } + + *pReturnPosX = rInfo.lx + rInfo.lwidth/2; + *pReturnPosY = rInfo.ly + rInfo.lheight/2; + *pdwTextColor = CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_PARTY); + return true; + } + } + + return false; +} + +bool CPythonMiniMap::GetAtlasSize(float * pfSizeX, float * pfSizeY) +{ + CPythonBackground& rkBG=CPythonBackground::Instance(); + if (!rkBG.IsMapOutdoor()) + return false; + + *pfSizeX = m_fAtlasImageSizeX; + *pfSizeY = m_fAtlasImageSizeY; + + return true; +} + +// Atlas +////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////// +// WayPoint +void CPythonMiniMap::AddWayPoint(BYTE byType, DWORD dwID, float fX, float fY, std::string strText, DWORD dwChrVID) +{ + m_AtlasMarkInfoVectorIterator = m_AtlasWayPointInfoVector.begin(); + while (m_AtlasMarkInfoVectorIterator != m_AtlasWayPointInfoVector.end()) + { + TAtlasMarkInfo & rAtlasMarkInfo = *m_AtlasMarkInfoVectorIterator; + if (rAtlasMarkInfo.m_dwID == dwID) + return; + ++m_AtlasMarkInfoVectorIterator; + } + + TAtlasMarkInfo aAtlasMarkInfo; + aAtlasMarkInfo.m_byType = byType; + aAtlasMarkInfo.m_dwID = dwID; + aAtlasMarkInfo.m_fX = fX; + aAtlasMarkInfo.m_fY = fY; + aAtlasMarkInfo.m_fScreenX = 0.0f; + aAtlasMarkInfo.m_fScreenY = 0.0f; + aAtlasMarkInfo.m_fMiniMapX = 0.0f; + aAtlasMarkInfo.m_fMiniMapY = 0.0f; + aAtlasMarkInfo.m_strText = strText; + aAtlasMarkInfo.m_dwChrVID = dwChrVID; + __UpdateWayPoint(&aAtlasMarkInfo, fX, fY); + m_AtlasWayPointInfoVector.push_back(aAtlasMarkInfo); + +} + +void CPythonMiniMap::RemoveWayPoint(DWORD dwID) +{ + m_AtlasMarkInfoVectorIterator = m_AtlasWayPointInfoVector.begin(); + while (m_AtlasMarkInfoVectorIterator != m_AtlasWayPointInfoVector.end()) + { + TAtlasMarkInfo & rAtlasMarkInfo = *m_AtlasMarkInfoVectorIterator; + if (rAtlasMarkInfo.m_dwID == dwID) + { + m_AtlasMarkInfoVectorIterator = m_AtlasWayPointInfoVector.erase(m_AtlasMarkInfoVectorIterator); + return; + } + ++m_AtlasMarkInfoVectorIterator; + } +} + +bool CPythonMiniMap::__GetWayPoint(DWORD dwID, TAtlasMarkInfo ** ppkInfo) +{ + TAtlasMarkInfoVectorIterator itor = m_AtlasWayPointInfoVector.begin(); + for (; itor != m_AtlasWayPointInfoVector.end(); ++itor) + { + TAtlasMarkInfo & rInfo = *itor; + if (dwID == rInfo.m_dwID) + { + *ppkInfo = &rInfo; + return true; + } + } + + return false; +} + +void CPythonMiniMap::__UpdateWayPoint(TAtlasMarkInfo * pkInfo, int ix, int iy) +{ + pkInfo->m_fX = float(ix); + pkInfo->m_fY = float(iy); + pkInfo->m_fScreenX = pkInfo->m_fX / m_fAtlasMaxX * m_fAtlasImageSizeX; + pkInfo->m_fScreenY = pkInfo->m_fY / m_fAtlasMaxY * m_fAtlasImageSizeY; +} + +// WayPoint +////////////////////////////////////////////////////////////////////////// + +void CPythonMiniMap::__RenderWayPointMark(int ixCenter, int iyCenter) +{ + int iNum = (ELTimer_GetMSec() / 67) % WAYPOINT_IMAGE_COUNT; + + CGraphicImageInstance & rInstance = m_WayPointGraphicImageInstances[iNum]; + rInstance.SetPosition(ixCenter - rInstance.GetWidth()/2, iyCenter - rInstance.GetHeight()/2); + rInstance.Render(); +} + +void CPythonMiniMap::__RenderMiniWayPointMark(int ixCenter, int iyCenter) +{ + int iNum = (ELTimer_GetMSec() / 67) % MINI_WAYPOINT_IMAGE_COUNT; + + CGraphicImageInstance & rInstance = m_MiniWayPointGraphicImageInstances[iNum]; + rInstance.SetPosition(ixCenter - rInstance.GetWidth()/2, iyCenter - rInstance.GetHeight()/2); + rInstance.Render(); +} + +void CPythonMiniMap::__RenderTargetMark(int ixCenter, int iyCenter) +{ + int iNum = (ELTimer_GetMSec() / 80) % TARGET_MARK_IMAGE_COUNT; + + CGraphicImageInstance & rInstance = m_TargetMarkGraphicImageInstances[iNum]; + rInstance.SetPosition(ixCenter - rInstance.GetWidth()/2, iyCenter - rInstance.GetHeight()/2); + rInstance.Render(); +} + +void CPythonMiniMap::AddSignalPoint(float fX, float fY) +{ + static unsigned int g_id = 255; + + TSignalPoint sp; + sp.id = g_id; + sp.v2Pos.x = fX; + sp.v2Pos.y = fY; + + m_SignalPointVector.push_back(sp); + + AddWayPoint(TYPE_WAYPOINT, g_id, fX, fY, ""); + + g_id++; +} + +void CPythonMiniMap::ClearAllSignalPoint() +{ + std::vector::iterator it; + for(it = m_SignalPointVector.begin();it!=m_SignalPointVector.end();++it) + { + RemoveWayPoint(it->id); + } + m_SignalPointVector.clear(); +} + +void CPythonMiniMap::RegisterAtlasWindow(PyObject* poHandler) +{ + m_poHandler = poHandler; +} + +void CPythonMiniMap::UnregisterAtlasWindow() +{ + m_poHandler = 0; +} + +void CPythonMiniMap::OpenAtlasWindow() +{ + if (m_poHandler) + { + PyCallClassMemberFunc(m_poHandler,"Show", Py_BuildValue("()")); + } +} + +void CPythonMiniMap::SetAtlasCenterPosition(int x, int y) +{ + if (m_poHandler) + { + //int sw = UI::CWindowManager::Instance().GetScreenWidth(); + //int sh = UI::CWindowManager::Instance().GetScreenHeight(); + //PyCallClassMemberFunc(m_poHandler,"SetPosition", Py_BuildValue("(ii)",sw/2+x,sh/2+y)); + PyCallClassMemberFunc(m_poHandler,"SetCenterPositionAdjust", Py_BuildValue("(ii)",x,y)); + } +} + +bool CPythonMiniMap::IsAtlas() +{ + return m_bAtlas; +} + +void CPythonMiniMap::ShowAtlas() +{ + m_bShowAtlas=true; +} + +void CPythonMiniMap::HideAtlas() +{ + m_bShowAtlas=false; +} + +bool CPythonMiniMap::CanShowAtlas() +{ + return m_bShowAtlas; +} + +bool CPythonMiniMap::CanShow() +{ + return m_bShow; +} + +void CPythonMiniMap::Show() +{ + m_bShow=true; +} + +void CPythonMiniMap::Hide() +{ + m_bShow=false; +} + +void CPythonMiniMap::__Initialize() +{ + m_poHandler = 0; + + SetMiniMapSize(128.0f, 128.0f); + + m_fScale = 2.0f; + + m_fCenterX = m_fWidth * 0.5f; + m_fCenterY = m_fHeight * 0.5f; + + m_fScreenX = 0.0f; + m_fScreenY = 0.0f; + + m_fAtlasScreenX = 0.0f; + m_fAtlasScreenY = 0.0f; + + m_dwAtlasBaseX = 0; + m_dwAtlasBaseY = 0; + + m_fAtlasMaxX = 0.0f; + m_fAtlasMaxY = 0.0f; + + m_fAtlasImageSizeX = 0.0f; + m_fAtlasImageSizeY = 0.0f; + + m_bAtlas = false; + + m_bShow = false; + m_bShowAtlas = false; + + D3DXMatrixIdentity(&m_matIdentity); + D3DXMatrixIdentity(&m_matWorld); + D3DXMatrixIdentity(&m_matMiniMapCover); + D3DXMatrixIdentity(&m_matWorldAtlas); +} + +void CPythonMiniMap::Destroy() +{ + ClearAllSignalPoint(); + m_poHandler = 0; + + m_VertexBuffer.Destroy(); + m_IndexBuffer.Destroy(); + + m_PlayerMark.Destroy(); + + m_MiniMapFilterGraphicImageInstance.Destroy(); + m_MiniMapCameraraphicImageInstance.Destroy(); + + m_AtlasWayPointInfoVector.clear(); + m_AtlasImageInstance.Destroy(); + m_AtlasPlayerMark.Destroy(); + m_WhiteMark.Destroy(); + + for (int i = 0; i < MINI_WAYPOINT_IMAGE_COUNT; ++i) + m_MiniWayPointGraphicImageInstances[i].Destroy(); + for (int j = 0; j < WAYPOINT_IMAGE_COUNT; ++j) + m_WayPointGraphicImageInstances[j].Destroy(); + for (int k = 0; k < TARGET_MARK_IMAGE_COUNT; ++k) + m_TargetMarkGraphicImageInstances[k].Destroy(); + + m_GuildAreaFlagImageInstance.Destroy(); + + __Initialize(); +} + +CPythonMiniMap::CPythonMiniMap() +{ + __Initialize(); +} + +CPythonMiniMap::~CPythonMiniMap() +{ + Destroy(); +} diff --git a/source/UserInterface/PythonMiniMap.h b/source/UserInterface/PythonMiniMap.h new file mode 100644 index 0000000..dbbe48a --- /dev/null +++ b/source/UserInterface/PythonMiniMap.h @@ -0,0 +1,253 @@ +#pragma once + +#include "PythonBackground.h" + +class CPythonMiniMap : public CScreen, public CSingleton +{ + public: + enum + { + EMPIRE_NUM = 4, + + MINI_WAYPOINT_IMAGE_COUNT = 12, + WAYPOINT_IMAGE_COUNT = 15, + TARGET_MARK_IMAGE_COUNT = 2, + }; + enum + { + TYPE_OPC, + TYPE_OPCPVP, + TYPE_OPCPVPSELF, + TYPE_NPC, + TYPE_MONSTER, + TYPE_WARP, + TYPE_WAYPOINT, + TYPE_PARTY, + TYPE_EMPIRE, + TYPE_EMPIRE_END = TYPE_EMPIRE + EMPIRE_NUM, + TYPE_TARGET, + TYPE_COUNT, + }; + + public: + CPythonMiniMap(); + virtual ~CPythonMiniMap(); + + void Destroy(); + bool Create(); + + bool IsAtlas(); + bool CanShow(); + bool CanShowAtlas(); + + void SetMiniMapSize(float fWidth, float fHeight); + void SetScale(float fScale); + void ScaleUp(); + void ScaleDown(); + + void SetCenterPosition(float fCenterX, float fCenterY); + + void Update(float fCenterX, float fCenterY); + void Render(float fScreenX, float fScreenY); + + void Show(); + void Hide(); + + bool GetPickedInstanceInfo(float fScreenX, float fScreenY, std::string & rReturnName, float * pReturnPosX, float * pReturnPosY, DWORD * pdwTextColor); + + // Atlas + bool LoadAtlas(); + void UpdateAtlas(); + void RenderAtlas(float fScreenX, float fScreenY); + void ShowAtlas(); + void HideAtlas(); + + bool GetAtlasInfo(float fScreenX, float fScreenY, std::string & rReturnString, float * pReturnPosX, float * pReturnPosY, DWORD * pdwTextColor, DWORD * pdwGuildID); + bool GetAtlasSize(float * pfSizeX, float * pfSizeY); + + void AddObserver(DWORD dwVID, float fSrcX, float fSrcY); + void MoveObserver(DWORD dwVID, float fDstX, float fDstY); + void RemoveObserver(DWORD dwVID); + + // WayPoint + void AddWayPoint(BYTE byType, DWORD dwID, float fX, float fY, std::string strText, DWORD dwChrVID=0); + void RemoveWayPoint(DWORD dwID); + + // SignalPoint + void AddSignalPoint(float fX, float fY); + void ClearAllSignalPoint(); + + void RegisterAtlasWindow(PyObject* poHandler); + void UnregisterAtlasWindow(); + void OpenAtlasWindow(); + void SetAtlasCenterPosition(int x, int y); + + // NPC List + void ClearAtlasMarkInfo(); + void RegisterAtlasMark(BYTE byType, const char * c_szName, long lx, long ly); + + // Guild + void ClearGuildArea(); + void RegisterGuildArea(DWORD dwID, DWORD dwGuildID, long x, long y, long width, long height); + DWORD GetGuildAreaID(DWORD x, DWORD y); + + // Target + void CreateTarget(int iID, const char * c_szName); + void CreateTarget(int iID, const char * c_szName, DWORD dwVID); + void UpdateTarget(int iID, int ix, int iy); + void DeleteTarget(int iID); + + protected: + void __Initialize(); + void __SetPosition(); + void __LoadAtlasMarkInfo(); + + void __RenderWayPointMark(int ixCenter, int iyCenter); + void __RenderMiniWayPointMark(int ixCenter, int iyCenter); + void __RenderTargetMark(int ixCenter, int iyCenter); + + void __GlobalPositionToAtlasPosition(long lx, long ly, float * pfx, float * pfy); + + protected: + // Atlas + typedef struct + { + BYTE m_byType; + DWORD m_dwID; // For WayPoint + float m_fX; + float m_fY; + float m_fScreenX; + float m_fScreenY; + float m_fMiniMapX; + float m_fMiniMapY; + DWORD m_dwChrVID; + std::string m_strText; + } TAtlasMarkInfo; + + // GuildArea + typedef struct + { + DWORD dwGuildID; + long lx, ly; + long lwidth, lheight; + + float fsxRender, fsyRender; + float fexRender, feyRender; + } TGuildAreaInfo; + + struct SObserver + { + float fCurX; + float fCurY; + float fSrcX; + float fSrcY; + float fDstX; + float fDstY; + + DWORD dwSrcTime; + DWORD dwDstTime; + }; + + // ij Ʈ + typedef struct + { + float m_fX; + float m_fY; + UINT m_eNameColor; + } TMarkPosition; + + typedef std::vector TInstanceMarkPositionVector; + typedef TInstanceMarkPositionVector::iterator TInstancePositionVectorIterator; + + protected: + bool __GetWayPoint(DWORD dwID, TAtlasMarkInfo ** ppkInfo); + void __UpdateWayPoint(TAtlasMarkInfo * pkInfo, int ix, int iy); + + protected: + float m_fWidth; + float m_fHeight; + + float m_fScale; + + float m_fCenterX; + float m_fCenterY; + + float m_fCenterCellX; + float m_fCenterCellY; + + float m_fScreenX; + float m_fScreenY; + + float m_fMiniMapRadius; + + // ׸... + LPDIRECT3DTEXTURE8 m_lpMiniMapTexture[AROUND_AREA_NUM]; + + // ̴ϸ Ŀ + CGraphicImageInstance m_MiniMapFilterGraphicImageInstance; + CGraphicExpandedImageInstance m_MiniMapCameraraphicImageInstance; + + // ij ũ + CGraphicExpandedImageInstance m_PlayerMark; + CGraphicImageInstance m_WhiteMark; + + TInstanceMarkPositionVector m_PartyPCPositionVector; + TInstanceMarkPositionVector m_OtherPCPositionVector; + TInstanceMarkPositionVector m_NPCPositionVector; + TInstanceMarkPositionVector m_MonsterPositionVector; + TInstanceMarkPositionVector m_WarpPositionVector; + std::map m_kMap_dwVID_kObserver; + + bool m_bAtlas; + bool m_bShow; + + CGraphicVertexBuffer m_VertexBuffer; + CGraphicIndexBuffer m_IndexBuffer; + + D3DXMATRIX m_matIdentity; + D3DXMATRIX m_matWorld; + D3DXMATRIX m_matMiniMapCover; + + bool m_bShowAtlas; + CGraphicImageInstance m_AtlasImageInstance; + D3DXMATRIX m_matWorldAtlas; + CGraphicExpandedImageInstance m_AtlasPlayerMark; + + float m_fAtlasScreenX; + float m_fAtlasScreenY; + + DWORD m_dwAtlasBaseX; + DWORD m_dwAtlasBaseY; + + float m_fAtlasMaxX; + float m_fAtlasMaxY; + + float m_fAtlasImageSizeX; + float m_fAtlasImageSizeY; + + typedef std::vector TAtlasMarkInfoVector; + typedef TAtlasMarkInfoVector::iterator TAtlasMarkInfoVectorIterator; + typedef std::vector TGuildAreaInfoVector; + typedef TGuildAreaInfoVector::iterator TGuildAreaInfoVectorIterator; + TAtlasMarkInfoVectorIterator m_AtlasMarkInfoVectorIterator; + TAtlasMarkInfoVector m_AtlasNPCInfoVector; + TAtlasMarkInfoVector m_AtlasWarpInfoVector; + + // WayPoint + CGraphicExpandedImageInstance m_MiniWayPointGraphicImageInstances[MINI_WAYPOINT_IMAGE_COUNT]; + CGraphicExpandedImageInstance m_WayPointGraphicImageInstances[WAYPOINT_IMAGE_COUNT]; + CGraphicExpandedImageInstance m_TargetMarkGraphicImageInstances[TARGET_MARK_IMAGE_COUNT]; + CGraphicImageInstance m_GuildAreaFlagImageInstance; + TAtlasMarkInfoVector m_AtlasWayPointInfoVector; + TGuildAreaInfoVector m_GuildAreaInfoVector; + + // SignalPoint + struct TSignalPoint + { + D3DXVECTOR2 v2Pos; + unsigned int id; + }; + std::vector m_SignalPointVector; + + PyObject* m_poHandler; +}; \ No newline at end of file diff --git a/source/UserInterface/PythonMiniMapModule.cpp b/source/UserInterface/PythonMiniMapModule.cpp new file mode 100644 index 0000000..e6140ac --- /dev/null +++ b/source/UserInterface/PythonMiniMapModule.cpp @@ -0,0 +1,357 @@ +#include "StdAfx.h" +#include "PythonMiniMap.h" + +PyObject * miniMapSetScale(PyObject * poSelf, PyObject * poArgs) +{ + float fScale; + if (!PyTuple_GetFloat(poArgs, 0, &fScale)) + return Py_BuildException(); + + CPythonMiniMap::Instance().SetScale(fScale); + return Py_BuildNone(); +} + +PyObject * miniMapSetCenterPosition(PyObject * poSelf, PyObject * poArgs) +{ + float fCenterX; + if (!PyTuple_GetFloat(poArgs, 0, &fCenterX)) + return Py_BuildException(); + + float fCenterY; + if (!PyTuple_GetFloat(poArgs, 1, &fCenterY)) + return Py_BuildException(); + + CPythonMiniMap::Instance().SetCenterPosition(fCenterX, fCenterY); + return Py_BuildNone(); +} + + +PyObject * miniMapSetMiniMapSize(PyObject * poSelf, PyObject * poArgs) +{ + float fWidth; + if (!PyTuple_GetFloat(poArgs, 0, &fWidth)) + return Py_BuildException(); + + float fHeight; + if (!PyTuple_GetFloat(poArgs, 1, &fHeight)) + return Py_BuildException(); + + CPythonMiniMap::Instance().SetMiniMapSize(fWidth, fHeight); + return Py_BuildNone(); +} + +PyObject * miniMapDestroy(PyObject * poSelf, PyObject * poArgs) +{ + CPythonMiniMap::Instance().Destroy(); + return Py_BuildNone(); +} + +PyObject * miniMapCreate(PyObject * poSelf, PyObject * poArgs) +{ + CPythonMiniMap::Instance().Create(); + return Py_BuildNone(); +} + +PyObject * miniMapUpdate(PyObject * poSelf, PyObject * poArgs) +{ + float fCenterX; + if (!PyTuple_GetFloat(poArgs, 0, &fCenterX)) + return Py_BuildException(); + + float fCenterY; + if (!PyTuple_GetFloat(poArgs, 1, &fCenterY)) + return Py_BuildException(); + + CPythonMiniMap::Instance().Update(fCenterX, fCenterY); + return Py_BuildNone(); +} + +PyObject * miniMapRender(PyObject * poSelf, PyObject * poArgs) +{ + float fScrrenX; + if (!PyTuple_GetFloat(poArgs, 0, &fScrrenX)) + return Py_BuildException(); + + float fScrrenY; + if (!PyTuple_GetFloat(poArgs, 1, &fScrrenY)) + return Py_BuildException(); + + CPythonMiniMap::Instance().Render(fScrrenX, fScrrenY); + return Py_BuildNone(); +} + +PyObject * miniMapShow(PyObject * poSelf, PyObject * poArgs) +{ + CPythonMiniMap::Instance().Show(); + return Py_BuildNone(); +} + +PyObject * miniMapHide(PyObject * poSelf, PyObject * poArgs) +{ + CPythonMiniMap::Instance().Hide(); + return Py_BuildNone(); +} + +PyObject * miniMapisShow(PyObject * poSelf, PyObject * poArgs) +{ + bool bShow = CPythonMiniMap::Instance().CanShow(); + return Py_BuildValue("b", bShow); +} + +PyObject * miniMapScaleUp(PyObject * poSelf, PyObject * poArgs) +{ + CPythonMiniMap::Instance().ScaleUp(); + return Py_BuildNone(); +} + +PyObject * miniMapScaleDown(PyObject * poSelf, PyObject * poArgs) +{ + CPythonMiniMap::Instance().ScaleDown(); + return Py_BuildNone(); +} + +PyObject * miniMapGetInfo(PyObject * poSelf, PyObject * poArgs) +{ + float fScrrenX; + if (!PyTuple_GetFloat(poArgs, 0, &fScrrenX)) + return Py_BuildException(); + + float fScrrenY; + if (!PyTuple_GetFloat(poArgs, 1, &fScrrenY)) + return Py_BuildException(); + + std::string aString; + float fPosX, fPosY; + DWORD dwTextColor; + bool bFind = CPythonMiniMap::Instance().GetPickedInstanceInfo(fScrrenX, fScrrenY, aString, &fPosX, &fPosY, &dwTextColor); + int iPosX, iPosY; + PR_FLOAT_TO_INT(fPosX, iPosX); + PR_FLOAT_TO_INT(fPosY, iPosY); + iPosX /= 100; + iPosY /= 100; + return Py_BuildValue("isiil", (int)bFind, aString.c_str(), iPosX, iPosY, (signed) dwTextColor); +} + +////////////////////////////////////////////////////////////////////////// +// Atlas +PyObject * miniMapLoadAtlas(PyObject * poSelf, PyObject * poArgs) +{ + if (!CPythonMiniMap::Instance().LoadAtlas()) + TraceError("CPythonMiniMap::Instance().LoadAtlas() Failed"); + return Py_BuildNone(); +} + +PyObject * miniMapUpdateAtlas(PyObject * poSelf, PyObject * poArgs) +{ + CPythonMiniMap::Instance().UpdateAtlas(); + return Py_BuildNone(); +} + +PyObject * miniMapRenderAtlas(PyObject * poSelf, PyObject * poArgs) +{ + float fScrrenX; + if (!PyTuple_GetFloat(poArgs, 0, &fScrrenX)) + return Py_BuildException(); + + float fScrrenY; + if (!PyTuple_GetFloat(poArgs, 1, &fScrrenY)) + return Py_BuildException(); + + CPythonMiniMap::Instance().RenderAtlas(fScrrenX, fScrrenY); + return Py_BuildNone(); +} + +PyObject * miniMapShowAtlas(PyObject * poSelf, PyObject * poArgs) +{ + CPythonMiniMap::Instance().ShowAtlas(); + return Py_BuildNone(); +} + +PyObject * miniMapHideAtlas(PyObject * poSelf, PyObject * poArgs) +{ + CPythonMiniMap::Instance().HideAtlas(); + return Py_BuildNone(); +} + +PyObject * miniMapisShowAtlas(PyObject * poSelf, PyObject * poArgs) +{ + bool bShow = CPythonMiniMap::Instance().CanShowAtlas(); + return Py_BuildValue("b", bShow); +} + +PyObject * miniMapIsAtlas(PyObject * poSelf, PyObject * poArgs) +{ + bool isData = CPythonMiniMap::Instance().IsAtlas(); + return Py_BuildValue("b", isData); +} + + +PyObject * miniMapGetAtlasInfo(PyObject * poSelf, PyObject * poArgs) +{ + float fScrrenX; + if (!PyTuple_GetFloat(poArgs, 0, &fScrrenX)) + return Py_BuildException(); + float fScrrenY; + if (!PyTuple_GetFloat(poArgs, 1, &fScrrenY)) + return Py_BuildException(); + + std::string aString = ""; + float fPosX = 0.0f; + float fPosY = 0.0f; + DWORD dwTextColor = 0; + DWORD dwGuildID = 0; + bool bFind = CPythonMiniMap::Instance().GetAtlasInfo(fScrrenX, fScrrenY, aString, &fPosX, &fPosY, &dwTextColor, &dwGuildID); + int iPosX, iPosY; + PR_FLOAT_TO_INT(fPosX, iPosX); + PR_FLOAT_TO_INT(fPosY, iPosY); + iPosX /= 100; + iPosY /= 100; + return Py_BuildValue("isiili", (int)bFind, aString.c_str(), iPosX, iPosY, (signed) dwTextColor, dwGuildID); +} + +PyObject * miniMapGetAtlasSize(PyObject * poSelf, PyObject * poArgs) +{ + float fSizeX, fSizeY; + bool bGet = CPythonMiniMap::Instance().GetAtlasSize(&fSizeX, &fSizeY); + +/* + float fSizeXoo256 = fSizeX / 256.0f; + float fSizeYoo256 = fSizeY / 256.0f; + + if (fSizeXoo256 >= fSizeYoo256) + { + fSizeX /= fSizeYoo256; + fSizeY = 256.0f; + } + else + { + fSizeX = 256.0f; + fSizeY /= fSizeXoo256; + } +*/ + + int iSizeX, iSizeY; + PR_FLOAT_TO_INT(fSizeX, iSizeX); + PR_FLOAT_TO_INT(fSizeY, iSizeY); + + return Py_BuildValue("bii", (int)bGet, iSizeX, iSizeY); +} + +PyObject * miniMapAddWayPoint(PyObject * poSelf, PyObject * poArgs) +{ + int iID; + if (!PyTuple_GetInteger(poArgs, 0, &iID)) + return Py_BuildException(); + + float fX; + if (!PyTuple_GetFloat(poArgs, 1, &fX)) + return Py_BuildException(); + + float fY; + if (!PyTuple_GetFloat(poArgs, 2, &fY)) + return Py_BuildException(); + + char * buf; + if (!PyTuple_GetString(poArgs, 3, &buf)) + return Py_BuildException(); + + CPythonMiniMap::Instance().AddWayPoint(CPythonMiniMap::TYPE_WAYPOINT, (DWORD)iID, fX, fY, buf); + + return Py_BuildNone(); +} + +PyObject * miniMapRemoveWayPoint(PyObject * poSelf, PyObject * poArgs) +{ + int iID; + if (!PyTuple_GetInteger(poArgs, 0, &iID)) + return Py_BuildException(); + + CPythonMiniMap::Instance().RemoveWayPoint((DWORD)iID); + + return Py_BuildNone(); +} + +PyObject* miniMapRegisterAtlasWindow(PyObject* poSelf, PyObject* poArgs) +{ + PyObject * poHandler; + if (!PyTuple_GetObject(poArgs, 0, &poHandler)) + return Py_BuildException(); + CPythonMiniMap::Instance().RegisterAtlasWindow(poHandler); + return Py_BuildNone(); +} + +PyObject* miniMapUnregisterAtlasWindow(PyObject* poSelf, PyObject* poArgs) +{ + CPythonMiniMap::Instance().UnregisterAtlasWindow(); + return Py_BuildNone(); +} + +PyObject* miniMapGetGuildAreaID(PyObject* poSelf, PyObject* poArgs) +{ + float fx; + if (!PyTuple_GetFloat(poArgs, 0, &fx)) + return Py_BuildException(); + float fy; + if (!PyTuple_GetFloat(poArgs, 1, &fy)) + return Py_BuildException(); + + DWORD dwGuildID = CPythonMiniMap::Instance().GetGuildAreaID(fx, fy); + return Py_BuildValue("i", dwGuildID); +} + +void initMiniMap() +{ + static PyMethodDef s_methods[] = + { + { "SetScale", miniMapSetScale, METH_VARARGS }, + { "ScaleUp", miniMapScaleUp, METH_VARARGS }, + { "ScaleDown", miniMapScaleDown, METH_VARARGS }, + { "SetMiniMapSize", miniMapSetMiniMapSize, METH_VARARGS }, + + { "SetCenterPosition", miniMapSetCenterPosition, METH_VARARGS }, + + { "Destroy", miniMapDestroy, METH_VARARGS }, + { "Create", miniMapCreate, METH_VARARGS }, + { "Update", miniMapUpdate, METH_VARARGS }, + { "Render", miniMapRender, METH_VARARGS }, + + { "Show", miniMapShow, METH_VARARGS }, + { "Hide", miniMapHide, METH_VARARGS }, + + { "isShow", miniMapisShow, METH_VARARGS }, + + { "GetInfo", miniMapGetInfo, METH_VARARGS }, + + { "LoadAtlas", miniMapLoadAtlas, METH_VARARGS }, + { "UpdateAtlas", miniMapUpdateAtlas, METH_VARARGS }, + { "RenderAtlas", miniMapRenderAtlas, METH_VARARGS }, + { "ShowAtlas", miniMapShowAtlas, METH_VARARGS }, + { "HideAtlas", miniMapHideAtlas, METH_VARARGS }, + { "isShowAtlas", miniMapisShowAtlas, METH_VARARGS }, + { "IsAtlas", miniMapIsAtlas, METH_VARARGS }, + { "GetAtlasInfo", miniMapGetAtlasInfo, METH_VARARGS }, + { "GetAtlasSize", miniMapGetAtlasSize, METH_VARARGS }, + + { "AddWayPoint", miniMapAddWayPoint, METH_VARARGS }, + { "RemoveWayPoint", miniMapRemoveWayPoint, METH_VARARGS }, + + { "RegisterAtlasWindow", miniMapRegisterAtlasWindow, METH_VARARGS }, + { "UnregisterAtlasWindow", miniMapUnregisterAtlasWindow, METH_VARARGS }, + + { "GetGuildAreaID", miniMapGetGuildAreaID, METH_VARARGS }, + + { NULL, NULL }, + }; + + PyObject * poModule = Py_InitModule("miniMap", s_methods); + + PyModule_AddIntConstant(poModule, "TYPE_OPC", CPythonMiniMap::TYPE_OPC); + PyModule_AddIntConstant(poModule, "TYPE_OPCPVP", CPythonMiniMap::TYPE_OPCPVP); + PyModule_AddIntConstant(poModule, "TYPE_OPCPVPSELF", CPythonMiniMap::TYPE_OPCPVPSELF); + PyModule_AddIntConstant(poModule, "TYPE_NPC", CPythonMiniMap::TYPE_NPC); + PyModule_AddIntConstant(poModule, "TYPE_MONSTER", CPythonMiniMap::TYPE_MONSTER); + PyModule_AddIntConstant(poModule, "TYPE_WARP", CPythonMiniMap::TYPE_WARP); + PyModule_AddIntConstant(poModule, "TYPE_WAYPOINT", CPythonMiniMap::TYPE_WAYPOINT); + PyModule_AddIntConstant(poModule, "TYPE_PARTY", CPythonMiniMap::TYPE_PARTY); + PyModule_AddIntConstant(poModule, "TYPE_EMPIRE", CPythonMiniMap::TYPE_EMPIRE); +} \ No newline at end of file diff --git a/source/UserInterface/PythonNetworkDatagram.cpp b/source/UserInterface/PythonNetworkDatagram.cpp new file mode 100644 index 0000000..0ffdd21 --- /dev/null +++ b/source/UserInterface/PythonNetworkDatagram.cpp @@ -0,0 +1,213 @@ +#include "StdAfx.h" + +/* +#include "PythonNetworkDatagram.h" +#include "PythonNetworkStream.h" + +class CDatagramPacketHeaderMap : public CNetworkPacketHeaderMap +{ + public: + CDatagramPacketHeaderMap() + { + Set(HEADER_CC_STATE_WALKING, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketCCState), false)); + } +}; + +void CPythonNetworkDatagram::Destroy() +{ + m_NetSenderPool.Clear(); +} + +BOOL CPythonNetworkDatagram::CheckPacket(TPacketHeader * piRetHeader) +{ + static CDatagramPacketHeaderMap s_packetHeaderMap; + + if (!m_NetReceiver.isBind()) + return FALSE; + + *piRetHeader = 0; + + TPacketHeader header; + + if (!m_NetReceiver.Peek(&header, sizeof(TPacketHeader))) + return false; + + CNetworkPacketHeaderMap::TPacketType PacketType; + + if (!s_packetHeaderMap.Get(header, &PacketType)) + { + Tracef("Unknown UDP packet header"); + assert(!"Unknown UDP packet header"); + return FALSE; + } + + if (!header) + return FALSE; + + *piRetHeader = header; + return TRUE; +} + +void CPythonNetworkDatagram::Process() +{ + while (m_NetReceiver.Process()) + { + TPacketHeader iHeader; + + if (!CheckPacket(&iHeader)) + continue; + + switch(iHeader) + { + case HEADER_CC_STATE_WALKING: + RecvStateWalkingPacket(); + break; + + case HEADER_CC_STATE_WAITING: + case HEADER_CC_STATE_GOING: + case HEADER_CC_EVENT_NORMAL_ATTACKING: + case HEADER_CC_EVENT_COMBO_ATTACKING: + case HEADER_CC_EVENT_HIT: + break; + } + } +} + +void CPythonNetworkDatagram::SetConnection(const char * c_szIP, WORD wPortIndex) +{ + m_NetSender.SetSocket(c_szIP, wPortIndex); +} + +void CPythonNetworkDatagram::SetRecvBufferSize(DWORD dwSize) +{ + m_NetReceiver.SetRecvBufferSize(dwSize); +} + +void CPythonNetworkDatagram::SendToServer(const void * c_pBuffer, DWORD dwSize) +{ + if (!m_NetSender.isSocket()) + { + assert(!"UDP Socket has not set!"); + return; + } + + m_NetSender.Send(c_pBuffer, dwSize); +} + +void CPythonNetworkDatagram::Bind(DWORD dwAddress, WORD wPortIndex) +{ + m_NetReceiver.Bind(dwAddress, wPortIndex); +} + +void CPythonNetworkDatagram::RegisterSender(DWORD dwID, DWORD dwAddress, WORD wPortIndex) +{ + CNetDatagramSender * pSender = m_NetSenderPool.Alloc(); + + pSender->SetSocket(dwAddress, wPortIndex); + + m_NetSenderMap.insert(TNetSenderMap::value_type(dwID, pSender)); +} +void CPythonNetworkDatagram::DeleteSender(DWORD dwID) +{ + CNetDatagramSender * pSender; + if (!GetSenderPointer(dwID, &pSender)) + return; + + m_NetSenderPool.Free(pSender); + + m_NetSenderMap.erase(dwID); +} + +void CPythonNetworkDatagram::Select(DWORD dwID) +{ + CNetDatagramSender * pSender; + if (!GetSenderPointer(dwID, &pSender)) + return; + + m_NetSenderList.push_back(pSender); +} +void CPythonNetworkDatagram::SendToSenders(const void * c_pBuffer, DWORD dwSize) +{ + // NOTE : Temporary Code + // Now, Send to every around client. + for (TNetSenderMapIterator itorMap = m_NetSenderMap.begin(); itorMap != m_NetSenderMap.end(); ++itorMap) + { + CNetDatagramSender * pSender = itorMap->second; + m_NetSenderList.push_back(pSender); + } + // NOTE : Temporary Code + + for (TNetSenderListIterator itor = m_NetSenderList.begin(); itor != m_NetSenderList.end(); ++itor) + { + CNetDatagramSender * pSender = *itor; + + pSender->Send(c_pBuffer, dwSize); + } + + m_NetSenderList.clear(); +} + +BOOL CPythonNetworkDatagram::GetSenderPointer(DWORD dwID, CNetDatagramSender ** ppSender) +{ + TNetSenderMapIterator itor = m_NetSenderMap.find(dwID); + + if (m_NetSenderMap.end() == itor) + return FALSE; + + *ppSender = itor->second; + + return TRUE; +} + +////////////////////////////////// +// Walking + +void CPythonNetworkDatagram::SendCharacterStatePacket(DWORD dwVID, DWORD dwCmdTime, const TPixelPosition& c_rkPPosDst, float fDstRot, UINT eFunc, UINT uArg) +{ + fDstRot=fmod(fDstRot, 360.0f); + + if (fDstRot<0) + fDstRot=360.0f-fDstRot; + + TPacketCCState kStatePacket; + kStatePacket.bHeader=HEADER_CC_STATE_WALKING; + kStatePacket.dwVID=dwVID; + kStatePacket.bFunc=eFunc; + kStatePacket.bArg=uArg; + kStatePacket.bRot=fDstRot/5.0f; + kStatePacket.dwTime=dwCmdTime; + kStatePacket.kPPos=c_rkPPosDst; + //SendToSenders(&kStatePacket, sizeof(kStatePacket)); +} + +BOOL CPythonNetworkDatagram::RecvStateWalkingPacket() +{ + TPacketCCState kStatePacket; + if (!m_NetReceiver.Recv(&kStatePacket, sizeof(kStatePacket))) + { + assert(!"CPythonNetworkDatagram::RecvStatePacket - PAKCET READ ERROR"); + Tracenf("CPythonNetworkDatagram::RecvStatePacket - PAKCET READ ERROR"); + return FALSE; + } + + CInstanceBase * pkChrInst = CPythonCharacterManager::Instance().GetInstancePtr(kStatePacket.dwVID); + + if (!pkChrInst) + { + //Tracenf("CPythonNetworkDatagram::RecvStatePacket - NOT EXIST VID(kStateWaitingPacket.vid = %d)", kStatePacket.m_dwVID); + return TRUE; + } + + pkChrInst->PushUDPState(kStatePacket.dwTime, kStatePacket.kPPos, kStatePacket.bRot*5.0f, kStatePacket.bFunc, kStatePacket.bArg); + return TRUE; +} + +CPythonNetworkDatagram::CPythonNetworkDatagram() +{ +} + +CPythonNetworkDatagram::~CPythonNetworkDatagram() +{ +} + + */ \ No newline at end of file diff --git a/source/UserInterface/PythonNetworkDatagram.h b/source/UserInterface/PythonNetworkDatagram.h new file mode 100644 index 0000000..4d4ac3e --- /dev/null +++ b/source/UserInterface/PythonNetworkDatagram.h @@ -0,0 +1,58 @@ +#pragma once + +/* +#include "../eterLib/NetDatagramReceiver.h" +#include "../eterLib/NetDatagramSender.h" +#include "Packet.h" + +class CPythonNetworkDatagram : public CSingleton +{ + public: + CPythonNetworkDatagram(); + virtual ~CPythonNetworkDatagram(); + + void Destroy(); + + // With Server + void SetRecvBufferSize(DWORD dwSize); + void SetConnection(const char * c_szIP, WORD wPortIndex); + void SendToServer(const void * c_pBuffer, DWORD dwSize); + void Bind(DWORD dwAddress, WORD wPortIndex); + + // With UDP Senders + void RegisterSender(DWORD dwID, DWORD dwAddress, WORD wPortIndex); + void DeleteSender(DWORD dwID); + + void Select(DWORD dwID); + void SendToSenders(const void * c_pBuffer, DWORD dwSize); + + // Regulary update function + void Process(); + void SendCharacterStatePacket(DWORD dwVID, DWORD dwCmdTime, const TPixelPosition& c_rkPPosDst, float fDstRot, UINT eFunc, UINT uArg); + + protected: + BOOL CheckPacket(TPacketHeader * piRetHeader); + BOOL GetSenderPointer(DWORD dwID, CNetDatagramSender ** ppSender); + BOOL RecvStateWalkingPacket(); + + protected: + // Sender Map + typedef std::map TNetSenderMap; + typedef TNetSenderMap::iterator TNetSenderMapIterator; + // Sender List + typedef std::list TNetSenderList; + typedef TNetSenderList::iterator TNetSenderListIterator; + + protected: + // Sender + TNetSenderMap m_NetSenderMap; + TNetSenderList m_NetSenderList; + + // Connection with server + CNetDatagramSender m_NetSender; + CNetDatagramReceiver m_NetReceiver; + + private: + CDynamicPool m_NetSenderPool; +}; +*/ \ No newline at end of file diff --git a/source/UserInterface/PythonNetworkDatagramModule.cpp b/source/UserInterface/PythonNetworkDatagramModule.cpp new file mode 100644 index 0000000..217d108 --- /dev/null +++ b/source/UserInterface/PythonNetworkDatagramModule.cpp @@ -0,0 +1,29 @@ +#include "StdAfx.h" +#include "PythonNetworkDatagram.h" +/* +PyObject * udpEnable(PyObject* poSelf, PyObject* poArgs) +{ + CPythonNetworkDatagram::Instance().Enable(); + return Py_BuildNone(); +} + +PyObject * udpDisable(PyObject* poSelf, PyObject* poArgs) +{ + CPythonNetworkDatagram::Instance().Disable(); + return Py_BuildNone(); +} +*/ +void initudp() +{ + /* + static PyMethodDef s_methods[] = + { + { "Enable", udpEnable, METH_VARARGS }, + { "Disable", udpDisable, METH_VARARGS }, + + { NULL, NULL, NULL } + }; + + PyObject * poModule = Py_InitModule("udp", s_methods); + */ +} diff --git a/source/UserInterface/PythonNetworkStream.cpp b/source/UserInterface/PythonNetworkStream.cpp new file mode 100644 index 0000000..4dd6b9f --- /dev/null +++ b/source/UserInterface/PythonNetworkStream.cpp @@ -0,0 +1,911 @@ +#include "StdAfx.h" +#include "../eterLib/NetPacketHeaderMap.h" + +#include "PythonNetworkStream.h" +#include "Packet.h" +#include "NetworkActorManager.h" + +#include "GuildMarkDownloader.h" +#include "GuildMarkUploader.h" +#include "MarkManager.h" + +#include "ProcessCRC.h" + +// MARK_BUG_FIX +static DWORD gs_nextDownloadMarkTime = 0; +// END_OF_MARK_BUG_FIX + +// Packet --------------------------------------------------------------------------- +class CMainPacketHeaderMap : public CNetworkPacketHeaderMap +{ + public: + enum + { + STATIC_SIZE_PACKET = false, + DYNAMIC_SIZE_PACKET = true, + }; + + public: + CMainPacketHeaderMap() + { + Set(HEADER_GC_EMPIRE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCEmpire), STATIC_SIZE_PACKET)); + Set(HEADER_GC_WARP, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCWarp), STATIC_SIZE_PACKET)); + Set(HEADER_GC_SKILL_COOLTIME_END, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCSkillCoolTimeEnd), STATIC_SIZE_PACKET)); + Set(HEADER_GC_QUEST_INFO, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCQuestInfo), DYNAMIC_SIZE_PACKET)); + Set(HEADER_GC_REQUEST_MAKE_GUILD, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCBlank), STATIC_SIZE_PACKET)); + Set(HEADER_GC_PVP, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCPVP), STATIC_SIZE_PACKET)); + Set(HEADER_GC_DUEL_START, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCDuelStart), DYNAMIC_SIZE_PACKET)); + Set(HEADER_GC_CHARACTER_ADD, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCCharacterAdd), STATIC_SIZE_PACKET)); + Set(HEADER_GC_CHAR_ADDITIONAL_INFO, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCCharacterAdditionalInfo), STATIC_SIZE_PACKET)); + Set(HEADER_GC_CHARACTER_ADD2, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCCharacterAdd2), STATIC_SIZE_PACKET)); + Set(HEADER_GC_CHARACTER_UPDATE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCCharacterUpdate), STATIC_SIZE_PACKET)); + Set(HEADER_GC_CHARACTER_UPDATE2, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCCharacterUpdate2), STATIC_SIZE_PACKET)); + Set(HEADER_GC_CHARACTER_DEL, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCCharacterDelete), STATIC_SIZE_PACKET)); + Set(HEADER_GC_CHARACTER_MOVE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCMove), STATIC_SIZE_PACKET)); + Set(HEADER_GC_CHAT, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCChat), DYNAMIC_SIZE_PACKET)); + + Set(HEADER_GC_SYNC_POSITION, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCC2C), DYNAMIC_SIZE_PACKET)); + + Set(HEADER_GC_LOGIN_SUCCESS3, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCLoginSuccess3), STATIC_SIZE_PACKET)); + Set(HEADER_GC_LOGIN_SUCCESS4, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCLoginSuccess4), STATIC_SIZE_PACKET)); + Set(HEADER_GC_LOGIN_FAILURE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCLoginFailure), STATIC_SIZE_PACKET)); + + Set(HEADER_GC_PLAYER_CREATE_SUCCESS, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCPlayerCreateSuccess), STATIC_SIZE_PACKET)); + Set(HEADER_GC_PLAYER_CREATE_FAILURE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCCreateFailure), STATIC_SIZE_PACKET)); + Set(HEADER_GC_PLAYER_DELETE_SUCCESS, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCBlank), STATIC_SIZE_PACKET)); + Set(HEADER_GC_PLAYER_DELETE_WRONG_SOCIAL_ID, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCBlank), STATIC_SIZE_PACKET)); + + Set(HEADER_GC_STUN, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCStun), STATIC_SIZE_PACKET)); + Set(HEADER_GC_DEAD, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCDead), STATIC_SIZE_PACKET)); + + Set(HEADER_GC_MAIN_CHARACTER, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCMainCharacter), STATIC_SIZE_PACKET)); + + // SUPPORT_BGM + Set(HEADER_GC_MAIN_CHARACTER2_EMPIRE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCMainCharacter2_EMPIRE), STATIC_SIZE_PACKET)); + Set(HEADER_GC_MAIN_CHARACTER3_BGM, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCMainCharacter3_BGM), STATIC_SIZE_PACKET)); + Set(HEADER_GC_MAIN_CHARACTER4_BGM_VOL, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCMainCharacter4_BGM_VOL), STATIC_SIZE_PACKET)); + // END_OFSUPPORT_BGM + + Set(HEADER_GC_PLAYER_POINTS, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCPoints), STATIC_SIZE_PACKET)); + Set(HEADER_GC_PLAYER_POINT_CHANGE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCPointChange), STATIC_SIZE_PACKET)); + + Set(HEADER_GC_ITEM_SET, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCItemSet), STATIC_SIZE_PACKET)); + Set(HEADER_GC_ITEM_SET2, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCItemSet2), STATIC_SIZE_PACKET)); + + Set(HEADER_GC_ITEM_USE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCItemUse), STATIC_SIZE_PACKET)); + Set(HEADER_GC_ITEM_UPDATE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCItemUpdate), STATIC_SIZE_PACKET)); + + Set(HEADER_GC_ITEM_GROUND_ADD, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCItemGroundAdd), STATIC_SIZE_PACKET)); + Set(HEADER_GC_ITEM_GROUND_DEL, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCItemGroundDel), STATIC_SIZE_PACKET)); + Set(HEADER_GC_ITEM_OWNERSHIP, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCItemOwnership), STATIC_SIZE_PACKET)); + + Set(HEADER_GC_QUICKSLOT_ADD, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCQuickSlotAdd), STATIC_SIZE_PACKET)); + Set(HEADER_GC_QUICKSLOT_DEL, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCQuickSlotDel), STATIC_SIZE_PACKET)); + Set(HEADER_GC_QUICKSLOT_SWAP, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCQuickSlotSwap), STATIC_SIZE_PACKET)); + + Set(HEADER_GC_WHISPER, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCWhisper), STATIC_SIZE_PACKET)); + + Set(HEADER_GC_CHARACTER_POSITION, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCPosition), STATIC_SIZE_PACKET)); + Set(HEADER_GC_MOTION, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCMotion), STATIC_SIZE_PACKET)); + + Set(HEADER_GC_SHOP, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCShop), DYNAMIC_SIZE_PACKET)); + Set(HEADER_GC_SHOP_SIGN, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCShopSign), STATIC_SIZE_PACKET)); + Set(HEADER_GC_EXCHANGE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCExchange), STATIC_SIZE_PACKET)); + + Set(HEADER_GC_PING, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCPing), STATIC_SIZE_PACKET)); + + Set(HEADER_GC_SCRIPT, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCScript), DYNAMIC_SIZE_PACKET)); + Set(HEADER_GC_QUEST_CONFIRM, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCQuestConfirm), STATIC_SIZE_PACKET)); + + Set(HEADER_GC_TARGET, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCTarget), STATIC_SIZE_PACKET)); + Set(HEADER_GC_MOUNT, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCMount), STATIC_SIZE_PACKET)); + + Set(HEADER_GC_CHANGE_SPEED, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCChangeSpeed), STATIC_SIZE_PACKET)); + + Set(HEADER_GC_HANDSHAKE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCHandshake), STATIC_SIZE_PACKET)); + Set(HEADER_GC_HANDSHAKE_OK, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCBlank), STATIC_SIZE_PACKET)); + Set(HEADER_GC_BINDUDP, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCBindUDP), STATIC_SIZE_PACKET)); + Set(HEADER_GC_OWNERSHIP, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCOwnership), STATIC_SIZE_PACKET)); + Set(HEADER_GC_CREATE_FLY, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCCreateFly), STATIC_SIZE_PACKET)); +#ifdef _IMPROVED_PACKET_ENCRYPTION_ + Set(HEADER_GC_KEY_AGREEMENT, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketKeyAgreement), STATIC_SIZE_PACKET)); + Set(HEADER_GC_KEY_AGREEMENT_COMPLETED, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketKeyAgreementCompleted), STATIC_SIZE_PACKET)); +#endif + Set(HEADER_GC_ADD_FLY_TARGETING, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCFlyTargeting), STATIC_SIZE_PACKET)); + Set(HEADER_GC_FLY_TARGETING, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCFlyTargeting), STATIC_SIZE_PACKET)); + + Set(HEADER_GC_PHASE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCPhase), STATIC_SIZE_PACKET)); + Set(HEADER_GC_SKILL_LEVEL, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCSkillLevel), STATIC_SIZE_PACKET)); + Set(HEADER_GC_SKILL_LEVEL_NEW, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCSkillLevelNew), STATIC_SIZE_PACKET)); + + Set(HEADER_GC_MESSENGER, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCMessenger), DYNAMIC_SIZE_PACKET)); + Set(HEADER_GC_GUILD, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCGuild), DYNAMIC_SIZE_PACKET)); + + Set(HEADER_GC_PARTY_INVITE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCPartyInvite), STATIC_SIZE_PACKET)); + Set(HEADER_GC_PARTY_ADD, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCPartyAdd), STATIC_SIZE_PACKET)); + Set(HEADER_GC_PARTY_UPDATE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCPartyUpdate), STATIC_SIZE_PACKET)); + Set(HEADER_GC_PARTY_REMOVE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCPartyRemove), STATIC_SIZE_PACKET)); + Set(HEADER_GC_PARTY_LINK, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCPartyLink), STATIC_SIZE_PACKET)); + Set(HEADER_GC_PARTY_UNLINK, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCPartyUnlink), STATIC_SIZE_PACKET)); + Set(HEADER_GC_PARTY_PARAMETER, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCPartyParameter), STATIC_SIZE_PACKET)); + + Set(HEADER_GC_SAFEBOX_SET, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCItemSet), STATIC_SIZE_PACKET)); + Set(HEADER_GC_SAFEBOX_DEL, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCItemDel), STATIC_SIZE_PACKET)); + Set(HEADER_GC_SAFEBOX_WRONG_PASSWORD, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCSafeboxWrongPassword), STATIC_SIZE_PACKET)); + Set(HEADER_GC_SAFEBOX_SIZE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCSafeboxSize), STATIC_SIZE_PACKET)); + Set(HEADER_GC_SAFEBOX_MONEY_CHANGE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCSafeboxMoneyChange), STATIC_SIZE_PACKET)); + + Set(HEADER_GC_FISHING, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCFishing), STATIC_SIZE_PACKET)); + Set(HEADER_GC_DUNGEON, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCDungeon), DYNAMIC_SIZE_PACKET)); + //Set(HEADER_GC_SLOW_TIMER, CNetworkPacketHeaderMap::TPacketType(sizeof(BYTE), STATIC_SIZE_PACKET)); + Set(HEADER_GC_TIME, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCTime), STATIC_SIZE_PACKET)); + Set(HEADER_GC_WALK_MODE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCWalkMode), STATIC_SIZE_PACKET)); + Set(HEADER_GC_CHANGE_SKILL_GROUP, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCChangeSkillGroup), STATIC_SIZE_PACKET)); + Set(HEADER_GC_REFINE_INFORMATION, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCRefineInformation), STATIC_SIZE_PACKET)); + Set(HEADER_GC_REFINE_INFORMATION_NEW, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCRefineInformationNew), STATIC_SIZE_PACKET)); + Set(HEADER_GC_SEPCIAL_EFFECT, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCSpecialEffect), STATIC_SIZE_PACKET)); + Set(HEADER_GC_NPC_POSITION, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCNPCPosition), DYNAMIC_SIZE_PACKET)); + Set(HEADER_GC_CHANGE_NAME, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCChangeName), STATIC_SIZE_PACKET)); + + Set(HEADER_GC_CHINA_MATRIX_CARD, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCChinaMatrixCard), STATIC_SIZE_PACKET)); + Set(HEADER_GC_RUNUP_MATRIX_QUIZ, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCRunupMatrixQuiz), STATIC_SIZE_PACKET)); + Set(HEADER_GC_NEWCIBN_PASSPOD_REQUEST, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCNEWCIBNPasspodRequest), STATIC_SIZE_PACKET)); + Set(HEADER_GC_NEWCIBN_PASSPOD_FAILURE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCNEWCIBNPasspodFailure), STATIC_SIZE_PACKET)); + Set(HEADER_GC_LOGIN_KEY, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCLoginKey), STATIC_SIZE_PACKET)); + + Set(HEADER_GC_AUTH_SUCCESS, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCAuthSuccess), STATIC_SIZE_PACKET)); + Set(HEADER_GC_AUTH_SUCCESS_OPENID, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCAuthSuccessOpenID), STATIC_SIZE_PACKET)); + Set(HEADER_GC_CHANNEL, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCChannel), STATIC_SIZE_PACKET)); + Set(HEADER_GC_VIEW_EQUIP, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCViewEquip), STATIC_SIZE_PACKET)); + Set(HEADER_GC_LAND_LIST, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCLandList), DYNAMIC_SIZE_PACKET)); + + //Set(HEADER_GC_TARGET_CREATE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCTargetCreate), STATIC_SIZE_PACKET)); + Set(HEADER_GC_TARGET_UPDATE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCTargetUpdate), STATIC_SIZE_PACKET)); + Set(HEADER_GC_TARGET_DELETE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCTargetDelete), STATIC_SIZE_PACKET)); + Set(HEADER_GC_TARGET_CREATE_NEW, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCTargetCreateNew), STATIC_SIZE_PACKET)); + + Set(HEADER_GC_AFFECT_ADD, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCAffectAdd), STATIC_SIZE_PACKET)); + Set(HEADER_GC_AFFECT_REMOVE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCAffectRemove), STATIC_SIZE_PACKET)); + + Set(HEADER_GC_MALL_OPEN, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCMallOpen), STATIC_SIZE_PACKET)); + Set(HEADER_GC_MALL_SET, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCItemSet), STATIC_SIZE_PACKET)); + Set(HEADER_GC_MALL_DEL, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCItemDel), STATIC_SIZE_PACKET)); + + Set(HEADER_GC_LOVER_INFO, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCLoverInfo), STATIC_SIZE_PACKET)); + Set(HEADER_GC_LOVE_POINT_UPDATE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCLovePointUpdate), STATIC_SIZE_PACKET)); + + Set(HEADER_GC_DIG_MOTION, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCDigMotion), STATIC_SIZE_PACKET)); + Set(HEADER_GC_DAMAGE_INFO, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCDamageInfo), STATIC_SIZE_PACKET)); + + Set(HEADER_GC_HS_REQUEST, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketHSCheck), STATIC_SIZE_PACKET)); + Set(HEADER_GC_XTRAP_CS1_REQUEST, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketXTrapCSVerify), STATIC_SIZE_PACKET)); + + Set(HEADER_GC_HYBRIDCRYPT_KEYS, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCHybridCryptKeys), DYNAMIC_SIZE_PACKET)); + Set(HEADER_GC_HYBRIDCRYPT_SDB, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCHybridSDB), DYNAMIC_SIZE_PACKET)); + Set(HEADER_GC_SPECIFIC_EFFECT, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCSpecificEffect), STATIC_SIZE_PACKET)); + Set(HEADER_GC_DRAGON_SOUL_REFINE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCDragonSoulRefine), STATIC_SIZE_PACKET)); + + } +}; + +int g_iLastPacket[2] = { 0, 0 }; + +void CPythonNetworkStream::ExitApplication() +{ + if (__IsNotPing()) + { + AbsoluteExitApplication(); + } + else + { + SendChatPacket("/quit"); + } +} + +void CPythonNetworkStream::ExitGame() +{ + if (__IsNotPing()) + { + LogOutGame(); + } + else + { + SendChatPacket("/phase_select"); + } +} + + +void CPythonNetworkStream::LogOutGame() +{ + if (__IsNotPing()) + { + AbsoluteExitGame(); + } + else + { + SendChatPacket("/logout"); + } +} + +void CPythonNetworkStream::AbsoluteExitGame() +{ + if (!IsOnline()) + return; + + OnRemoteDisconnect(); + Disconnect(); +} + +void CPythonNetworkStream::AbsoluteExitApplication() +{ + PostQuitMessage(0); +} + +bool CPythonNetworkStream::__IsNotPing() +{ + // ȿö üũ̳ Ȯ ߾ Ѵ. + return false; +} + +DWORD CPythonNetworkStream::GetGuildID() +{ + return m_dwGuildID; +} + +UINT CPythonNetworkStream::UploadMark(const char * c_szImageFileName) +{ + // MARK_BUG_FIX + // 带 Ĵ ̵ 0̴. + if (0 == m_dwGuildID) + return ERROR_MARK_UPLOAD_NEED_RECONNECT; + + gs_nextDownloadMarkTime = 0; + // END_OF_MARK_BUG_FIX + + UINT uError=ERROR_UNKNOWN; + CGuildMarkUploader& rkGuildMarkUploader=CGuildMarkUploader::Instance(); + if (!rkGuildMarkUploader.Connect(m_kMarkAuth.m_kNetAddr, m_kMarkAuth.m_dwHandle, m_kMarkAuth.m_dwRandomKey, m_dwGuildID, c_szImageFileName, &uError)) + { + switch (uError) + { + case CGuildMarkUploader::ERROR_CONNECT: + return ERROR_CONNECT_MARK_SERVER; + break; + case CGuildMarkUploader::ERROR_LOAD: + return ERROR_LOAD_MARK; + break; + case CGuildMarkUploader::ERROR_WIDTH: + return ERROR_MARK_WIDTH; + break; + case CGuildMarkUploader::ERROR_HEIGHT: + return ERROR_MARK_HEIGHT; + break; + default: + return ERROR_UNKNOWN; + } + } + + // MARK_BUG_FIX + __DownloadMark(); + // END_OF_MARK_BUG_FIX + + if (CGuildMarkManager::INVALID_MARK_ID == CGuildMarkManager::Instance().GetMarkID(m_dwGuildID)) + return ERROR_MARK_CHECK_NEED_RECONNECT; + + return ERROR_NONE; +} + +UINT CPythonNetworkStream::UploadSymbol(const char* c_szImageFileName) +{ + UINT uError=ERROR_UNKNOWN; + CGuildMarkUploader& rkGuildMarkUploader=CGuildMarkUploader::Instance(); + if (!rkGuildMarkUploader.ConnectToSendSymbol(m_kMarkAuth.m_kNetAddr, m_kMarkAuth.m_dwHandle, m_kMarkAuth.m_dwRandomKey, m_dwGuildID, c_szImageFileName, &uError)) + { + switch (uError) + { + case CGuildMarkUploader::ERROR_CONNECT: + return ERROR_CONNECT_MARK_SERVER; + break; + case CGuildMarkUploader::ERROR_LOAD: + return ERROR_LOAD_MARK; + break; + case CGuildMarkUploader::ERROR_WIDTH: + return ERROR_MARK_WIDTH; + break; + case CGuildMarkUploader::ERROR_HEIGHT: + return ERROR_MARK_HEIGHT; + break; + default: + return ERROR_UNKNOWN; + } + } + + return ERROR_NONE; +} + +void CPythonNetworkStream::__DownloadMark() +{ + // 3 ȿ ٽ ʴ´. + DWORD curTime = ELTimer_GetMSec(); + + if (curTime < gs_nextDownloadMarkTime) + return; + + gs_nextDownloadMarkTime = curTime + 60000 * 3; // 3 + + CGuildMarkDownloader& rkGuildMarkDownloader = CGuildMarkDownloader::Instance(); + rkGuildMarkDownloader.Connect(m_kMarkAuth.m_kNetAddr, m_kMarkAuth.m_dwHandle, m_kMarkAuth.m_dwRandomKey); +} + +void CPythonNetworkStream::__DownloadSymbol(const std::vector & c_rkVec_dwGuildID) +{ + CGuildMarkDownloader& rkGuildMarkDownloader=CGuildMarkDownloader::Instance(); + rkGuildMarkDownloader.ConnectToRecvSymbol(m_kMarkAuth.m_kNetAddr, m_kMarkAuth.m_dwHandle, m_kMarkAuth.m_dwRandomKey, c_rkVec_dwGuildID); +} + +void CPythonNetworkStream::SetPhaseWindow(UINT ePhaseWnd, PyObject* poPhaseWnd) +{ + if (ePhaseWnd>=PHASE_WINDOW_NUM) + return; + + m_apoPhaseWnd[ePhaseWnd]=poPhaseWnd; +} + +void CPythonNetworkStream::ClearPhaseWindow(UINT ePhaseWnd, PyObject* poPhaseWnd) +{ + if (ePhaseWnd>=PHASE_WINDOW_NUM) + return; + + if (poPhaseWnd != m_apoPhaseWnd[ePhaseWnd]) + return; + + m_apoPhaseWnd[ePhaseWnd]=0; +} + +void CPythonNetworkStream::SetServerCommandParserWindow(PyObject* poWnd) +{ + m_poSerCommandParserWnd = poWnd; +} + +bool CPythonNetworkStream::IsSelectedEmpire() +{ + if (m_dwEmpireID) + return true; + + return false; +} + +UINT CPythonNetworkStream::GetAccountCharacterSlotDatau(UINT iSlot, UINT eType) +{ + if (iSlot >= PLAYER_PER_ACCOUNT4) + return 0; + + TSimplePlayerInformation& rkSimplePlayerInfo=m_akSimplePlayerInfo[iSlot]; + + switch (eType) + { + case ACCOUNT_CHARACTER_SLOT_ID: + return rkSimplePlayerInfo.dwID; + case ACCOUNT_CHARACTER_SLOT_RACE: + return rkSimplePlayerInfo.byJob; + case ACCOUNT_CHARACTER_SLOT_LEVEL: + return rkSimplePlayerInfo.byLevel; + case ACCOUNT_CHARACTER_SLOT_STR: + return rkSimplePlayerInfo.byST; + case ACCOUNT_CHARACTER_SLOT_DEX: + return rkSimplePlayerInfo.byDX; + case ACCOUNT_CHARACTER_SLOT_HTH: + return rkSimplePlayerInfo.byHT; + case ACCOUNT_CHARACTER_SLOT_INT: + return rkSimplePlayerInfo.byIQ; + case ACCOUNT_CHARACTER_SLOT_PLAYTIME: + return rkSimplePlayerInfo.dwPlayMinutes; + case ACCOUNT_CHARACTER_SLOT_FORM: +// return rkSimplePlayerInfo.wParts[CRaceData::PART_MAIN]; + return rkSimplePlayerInfo.wMainPart; + case ACCOUNT_CHARACTER_SLOT_PORT: + return rkSimplePlayerInfo.wPort; + case ACCOUNT_CHARACTER_SLOT_GUILD_ID: + return m_adwGuildID[iSlot]; + break; + case ACCOUNT_CHARACTER_SLOT_CHANGE_NAME_FLAG: + return rkSimplePlayerInfo.bChangeName; + break; + case ACCOUNT_CHARACTER_SLOT_HAIR: + return rkSimplePlayerInfo.wHairPart; + break; + } + return 0; +} + +const char* CPythonNetworkStream::GetAccountCharacterSlotDataz(UINT iSlot, UINT eType) +{ + static const char* sc_szEmpty=""; + + if (iSlot >= PLAYER_PER_ACCOUNT4) + return sc_szEmpty; + + TSimplePlayerInformation& rkSimplePlayerInfo=m_akSimplePlayerInfo[iSlot]; + + switch (eType) + { + case ACCOUNT_CHARACTER_SLOT_ADDR: + { + BYTE ip[4]; + + const int LEN = 4; + for (int i = 0; i < LEN; i++) + { + ip[i] = BYTE(rkSimplePlayerInfo.lAddr&0xff); + rkSimplePlayerInfo.lAddr>>=8; + } + + + static char s_szAddr[256]; + sprintf(s_szAddr, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); + return s_szAddr; + } + break; + case ACCOUNT_CHARACTER_SLOT_NAME: + return rkSimplePlayerInfo.szName; + break; + case ACCOUNT_CHARACTER_SLOT_GUILD_NAME: + return m_astrGuildName[iSlot].c_str(); + break; + } + return sc_szEmpty; +} + +void CPythonNetworkStream::ConnectLoginServer(const char* c_szAddr, UINT uPort) +{ + CNetworkStream::Connect(c_szAddr, uPort); +} + +void CPythonNetworkStream::SetMarkServer(const char* c_szAddr, UINT uPort) +{ + m_kMarkAuth.m_kNetAddr.Set(c_szAddr, uPort); +} + +void CPythonNetworkStream::ConnectGameServer(UINT iChrSlot) +{ + if (iChrSlot >= PLAYER_PER_ACCOUNT4) + return; + + m_dwSelectedCharacterIndex = iChrSlot; + + __DirectEnterMode_Set(iChrSlot); + + TSimplePlayerInformation& rkSimplePlayerInfo=m_akSimplePlayerInfo[iChrSlot]; + CNetworkStream::Connect((DWORD)rkSimplePlayerInfo.lAddr, rkSimplePlayerInfo.wPort); +} + +void CPythonNetworkStream::SetLoginInfo(const char* c_szID, const char* c_szPassword) +{ + m_stID=c_szID; + m_stPassword=c_szPassword; +} + +void CPythonNetworkStream::ClearLoginInfo( void ) +{ + m_stPassword = ""; +} + +void CPythonNetworkStream::SetLoginKey(DWORD dwLoginKey) +{ + m_dwLoginKey = dwLoginKey; +} + +bool CPythonNetworkStream::CheckPacket(TPacketHeader * pRetHeader) +{ + *pRetHeader = 0; + + static CMainPacketHeaderMap s_packetHeaderMap; + + TPacketHeader header; + + if (!Peek(sizeof(TPacketHeader), &header)) + return false; + + if (0 == header) + { + if (!Recv(sizeof(TPacketHeader), &header)) + return false; + + while (Peek(sizeof(TPacketHeader), &header)) + { + if (0 == header) + { + if (!Recv(sizeof(TPacketHeader), &header)) + return false; + } + else + { + break; + } + } + + if (0 == header) + return false; + } + + CNetworkPacketHeaderMap::TPacketType PacketType; + + if (!s_packetHeaderMap.Get(header, &PacketType)) + { + TraceError("Unknown packet header: %d, last: %d %d", header, g_iLastPacket[0], g_iLastPacket[1]); + ClearRecvBuffer(); + + PostQuitMessage(0); + return false; + } + + // Code for dynamic size packet + if (PacketType.isDynamicSizePacket) + { + TDynamicSizePacketHeader DynamicSizePacketHeader; + + if (!Peek(sizeof(TDynamicSizePacketHeader), &DynamicSizePacketHeader)) + return false; + + if (!Peek(DynamicSizePacketHeader.size)) + { + Tracef("CPythonNetworkStream::CheckPacket - Not enough dynamic packet size: header %d packet size: %d\n", + DynamicSizePacketHeader.header, + DynamicSizePacketHeader.size); + return false; + } + } + else + { + if (!Peek(PacketType.iPacketSize)) + { + //Tracef("Not enough packet size: header %d packet size: %d, recv buffer size: %d", + // header, + // PacketType.iPacketSize, + // GetRecvBufferSize()); + return false; + } + } + + if (!header) + return false; + + *pRetHeader = header; + + g_iLastPacket[0] = g_iLastPacket[1]; + g_iLastPacket[1] = header; + //Tracenf("header %d size %d", header, PacketType.iPacketSize); + //Tracenf("header %d size %d outputpos[%d] security %u", header, PacketType.iPacketSize, m_recvBufOutputPos, IsSecurityMode()); + return true; +} + +bool CPythonNetworkStream::RecvErrorPacket(int header) +{ + TraceError("Phase %s does not handle this header (header: %d, last: %d, %d)", + m_strPhase.c_str(), header, g_iLastPacket[0], g_iLastPacket[1]); + + ClearRecvBuffer(); + return true; +} + +bool CPythonNetworkStream::RecvPhasePacket() +{ + TPacketGCPhase packet_phase; + + if (!Recv(sizeof(TPacketGCPhase), &packet_phase)) + return false; + + switch (packet_phase.phase) + { + case PHASE_CLOSE: // (Ǵ ) + ClosePhase(); + break; + + case PHASE_HANDSHAKE: // Ǽ..;; + SetHandShakePhase(); + break; + + case PHASE_LOGIN: // α + SetLoginPhase(); + break; + + case PHASE_SELECT: // ij ȭ + SetSelectPhase(); +#if defined(ENABLE_DISCORD_RPC) + Discord_Update(false); +#endif + + BuildProcessCRC(); + + // MARK_BUG_FIX + __DownloadMark(); + // END_OF_MARK_BUG_FIX + break; + + case PHASE_LOADING: // ε ȭ + SetLoadingPhase(); + break; + + case PHASE_GAME: // ȭ + SetGamePhase(); +#if defined(ENABLE_DISCORD_RPC) + Discord_Update(true); +#endif + break; + + case PHASE_DEAD: // ׾ .. ( ȿ ִ ..) + break; + } + + return true; +} + +bool CPythonNetworkStream::RecvPingPacket() +{ + Tracef("recv ping packet. (securitymode %u)\n", IsSecurityMode()); + + TPacketGCPing kPacketPing; + + if (!Recv(sizeof(TPacketGCPing), &kPacketPing)) + return false; + + m_dwLastGamePingTime = ELTimer_GetMSec(); + + TPacketCGPong kPacketPong; + kPacketPong.bHeader = HEADER_CG_PONG; + + if (!Send(sizeof(TPacketCGPong), &kPacketPong)) + return false; + + if (IsSecurityMode()) + return SendSequence(); + else + return true; +} + +bool CPythonNetworkStream::RecvDefaultPacket(int header) +{ + if (!header) + return true; + + TraceError("ó Ŷ %d, state %s\n", header, m_strPhase.c_str()); + ClearRecvBuffer(); + return true; +} + +bool CPythonNetworkStream::OnProcess() +{ + if (m_isStartGame) + { + m_isStartGame = FALSE; + + PyCallClassMemberFunc(m_poHandler, "SetGamePhase", Py_BuildValue("()")); +// PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "StartGame", Py_BuildValue("()")); + } + + m_rokNetActorMgr->Update(); + + if (m_phaseProcessFunc.IsEmpty()) + return true; + + //TPacketHeader header; + //while(CheckPacket(&header)) + { + m_phaseProcessFunc.Run(); + } + + return true; +} + + +// Set +void CPythonNetworkStream::SetOffLinePhase() +{ + if ("OffLine" != m_strPhase) + m_phaseLeaveFunc.Run(); + + m_strPhase = "OffLine"; + + Tracen(""); + Tracen("## Network - OffLine Phase ##"); + Tracen(""); + +#if defined(ENABLE_DISCORD_RPC) + Discord_Update(false); +#endif + + m_dwChangingPhaseTime = ELTimer_GetMSec(); + m_phaseProcessFunc.Set(this, &CPythonNetworkStream::OffLinePhase); + m_phaseLeaveFunc.Set(this, &CPythonNetworkStream::__LeaveOfflinePhase); + + SetGameOffline(); + + m_dwSelectedCharacterIndex = 0; + + __DirectEnterMode_Initialize(); + __BettingGuildWar_Initialize(); +} + + +void CPythonNetworkStream::ClosePhase() +{ + PyCallClassMemberFunc(m_poHandler, "SetLoginPhase", Py_BuildValue("()")); +} + +// Game Online +void CPythonNetworkStream::SetGameOnline() +{ + m_isGameOnline = TRUE; +} + +void CPythonNetworkStream::SetGameOffline() +{ + m_isGameOnline = FALSE; +} + +BOOL CPythonNetworkStream::IsGameOnline() +{ + return m_isGameOnline; +} + +// Handler +void CPythonNetworkStream::SetHandler(PyObject* poHandler) +{ + m_poHandler = poHandler; +} + +// ETC +DWORD CPythonNetworkStream::GetMainActorVID() +{ + return m_dwMainActorVID; +} + +DWORD CPythonNetworkStream::GetMainActorRace() +{ + return m_dwMainActorRace; +} + +DWORD CPythonNetworkStream::GetMainActorEmpire() +{ + return m_dwMainActorEmpire; +} + +DWORD CPythonNetworkStream::GetMainActorSkillGroup() +{ + return m_dwMainActorSkillGroup; +} + +void CPythonNetworkStream::SetEmpireID(DWORD dwEmpireID) +{ + m_dwEmpireID = dwEmpireID; +} + +DWORD CPythonNetworkStream::GetEmpireID() +{ + return m_dwEmpireID; +} + +void CPythonNetworkStream::__ClearSelectCharacterData() +{ + NANOBEGIN + memset(&m_akSimplePlayerInfo, 0, sizeof(m_akSimplePlayerInfo)); + + for (int i = 0; i < PLAYER_PER_ACCOUNT4; ++i) + { + m_adwGuildID[i] = 0; + m_astrGuildName[i] = ""; + } + NANOEND +} + +void CPythonNetworkStream::__DirectEnterMode_Initialize() +{ + m_kDirectEnterMode.m_isSet=false; + m_kDirectEnterMode.m_dwChrSlotIndex=0; +} + +void CPythonNetworkStream::__DirectEnterMode_Set(UINT uChrSlotIndex) +{ + m_kDirectEnterMode.m_isSet=true; + m_kDirectEnterMode.m_dwChrSlotIndex=uChrSlotIndex; +} + +bool CPythonNetworkStream::__DirectEnterMode_IsSet() +{ + return m_kDirectEnterMode.m_isSet; +} + +void CPythonNetworkStream::__InitializeMarkAuth() +{ + m_kMarkAuth.m_dwHandle=0; + m_kMarkAuth.m_dwRandomKey=0; +} + +void CPythonNetworkStream::__BettingGuildWar_Initialize() +{ + m_kBettingGuildWar.m_dwBettingMoney=0; + m_kBettingGuildWar.m_dwObserverCount=0; +} + +void CPythonNetworkStream::__BettingGuildWar_SetObserverCount(UINT uObserverCount) +{ + m_kBettingGuildWar.m_dwObserverCount=uObserverCount; +} + +void CPythonNetworkStream::__BettingGuildWar_SetBettingMoney(UINT uBettingMoney) +{ + m_kBettingGuildWar.m_dwBettingMoney=uBettingMoney; +} + +DWORD CPythonNetworkStream::EXPORT_GetBettingGuildWarValue(const char* c_szValueName) +{ + if (stricmp(c_szValueName, "OBSERVER_COUNT") == 0) + return m_kBettingGuildWar.m_dwObserverCount; + + if (stricmp(c_szValueName, "BETTING_MONEY") == 0) + return m_kBettingGuildWar.m_dwBettingMoney; + + return 0; +} + +void CPythonNetworkStream::__ServerTimeSync_Initialize() +{ + m_kServerTimeSync.m_dwChangeClientTime=0; + m_kServerTimeSync.m_dwChangeServerTime=0; +} + +void CPythonNetworkStream::SetWaitFlag() +{ + m_isWaitLoginKey = TRUE; +} + +void CPythonNetworkStream::SendEmoticon(UINT eEmoticon) +{ + if(eEmoticon < m_EmoticonStringVector.size()) + SendChatPacket(m_EmoticonStringVector[eEmoticon].c_str()); + else + assert(false && "SendEmoticon Error"); +} + +CPythonNetworkStream::CPythonNetworkStream() +{ + m_rokNetActorMgr=new CNetworkActorManager; + + memset(m_akSimplePlayerInfo, 0, sizeof(m_akSimplePlayerInfo)); + + m_phaseProcessFunc.Clear(); + + m_dwEmpireID = 0; + m_dwGuildID = 0; + + m_dwMainActorVID = 0; + m_dwMainActorRace = 0; + m_dwMainActorEmpire = 0; + m_dwMainActorSkillGroup = 0; + m_poHandler = NULL; + + m_dwLastGamePingTime = 0; + + m_dwLoginKey = 0; + m_isWaitLoginKey = FALSE; + m_isStartGame = FALSE; + m_isEnableChatInsultFilter = FALSE; + m_bComboSkillFlag = FALSE; + m_strPhase = "OffLine"; + + __InitializeGamePhase(); + __InitializeMarkAuth(); + + __DirectEnterMode_Initialize(); + __BettingGuildWar_Initialize(); + + std::fill(m_apoPhaseWnd, m_apoPhaseWnd+PHASE_WINDOW_NUM, (PyObject*)NULL); + m_poSerCommandParserWnd = NULL; + + SetOffLinePhase(); +} + +CPythonNetworkStream::~CPythonNetworkStream() +{ + Tracen("PythonNetworkMainStream Clear"); +} diff --git a/source/UserInterface/PythonNetworkStream.h b/source/UserInterface/PythonNetworkStream.h new file mode 100644 index 0000000..e3d5481 --- /dev/null +++ b/source/UserInterface/PythonNetworkStream.h @@ -0,0 +1,738 @@ +#pragma once + +#include "../eterLib/FuncObject.h" +#include "../eterlib/NetStream.h" +#include "../eterLib/NetPacketHeaderMap.h" + +#include "InsultChecker.h" + +#include "packet.h" + +class CInstanceBase; +class CNetworkActorManager; +struct SNetworkActorData; +struct SNetworkUpdateActorData; + +class CPythonNetworkStream : public CNetworkStream, public CSingleton +{ + public: + enum + { + SERVER_COMMAND_LOG_OUT = 0, + SERVER_COMMAND_RETURN_TO_SELECT_CHARACTER = 1, + SERVER_COMMAND_QUIT = 2, + + MAX_ACCOUNT_PLAYER + }; + + enum + { + ERROR_NONE, + ERROR_UNKNOWN, + ERROR_CONNECT_MARK_SERVER, + ERROR_LOAD_MARK, + ERROR_MARK_WIDTH, + ERROR_MARK_HEIGHT, + + // MARK_BUG_FIX + ERROR_MARK_UPLOAD_NEED_RECONNECT, + ERROR_MARK_CHECK_NEED_RECONNECT, + // END_OF_MARK_BUG_FIX + }; + + enum + { + ACCOUNT_CHARACTER_SLOT_ID, + ACCOUNT_CHARACTER_SLOT_NAME, + ACCOUNT_CHARACTER_SLOT_RACE, + ACCOUNT_CHARACTER_SLOT_LEVEL, + ACCOUNT_CHARACTER_SLOT_STR, + ACCOUNT_CHARACTER_SLOT_DEX, + ACCOUNT_CHARACTER_SLOT_HTH, + ACCOUNT_CHARACTER_SLOT_INT, + ACCOUNT_CHARACTER_SLOT_PLAYTIME, + ACCOUNT_CHARACTER_SLOT_FORM, + ACCOUNT_CHARACTER_SLOT_ADDR, + ACCOUNT_CHARACTER_SLOT_PORT, + ACCOUNT_CHARACTER_SLOT_GUILD_ID, + ACCOUNT_CHARACTER_SLOT_GUILD_NAME, + ACCOUNT_CHARACTER_SLOT_CHANGE_NAME_FLAG, + ACCOUNT_CHARACTER_SLOT_HAIR, + }; + + enum + { + PHASE_WINDOW_LOGO, + PHASE_WINDOW_LOGIN, + PHASE_WINDOW_SELECT, + PHASE_WINDOW_CREATE, + PHASE_WINDOW_LOAD, + PHASE_WINDOW_GAME, + PHASE_WINDOW_EMPIRE, + PHASE_WINDOW_NUM, + }; + + public: + CPythonNetworkStream(); + virtual ~CPythonNetworkStream(); + + bool SendSpecial(int nLen, void * pvBuf); + + void StartGame(); + void Warp(LONG lGlobalX, LONG lGlobalY); + + void NotifyHack(const char* c_szMsg); + void SetWaitFlag(); +#if defined(ENABLE_DISCORD_RPC) + void Discord_Start(); + void Discord_Close(); + void Discord_Update(const bool bInGame); +#endif + + void SendEmoticon(UINT eEmoticon); + + void ExitApplication(); + void ExitGame(); + void LogOutGame(); + void AbsoluteExitGame(); + void AbsoluteExitApplication(); + + void EnableChatInsultFilter(bool isEnable); + bool IsChatInsultIn(const char* c_szMsg); + bool IsInsultIn(const char* c_szMsg); + + DWORD GetGuildID(); + + UINT UploadMark(const char* c_szImageFileName); + UINT UploadSymbol(const char* c_szImageFileName); + + bool LoadInsultList(const char* c_szInsultListFileName); + bool LoadConvertTable(DWORD dwEmpireID, const char* c_szFileName); + + UINT GetAccountCharacterSlotDatau(UINT iSlot, UINT eType); + const char* GetAccountCharacterSlotDataz(UINT iSlot, UINT eType); + + // SUPPORT_BGM + const char* GetFieldMusicFileName(); + float GetFieldMusicVolume(); + // END_OF_SUPPORT_BGM + + bool IsSelectedEmpire(); + + void ToggleGameDebugInfo(); + + void SetMarkServer(const char* c_szAddr, UINT uPort); + void ConnectLoginServer(const char* c_szAddr, UINT uPort); + void ConnectGameServer(UINT iChrSlot); + + void SetLoginInfo(const char* c_szID, const char* c_szPassword); + void SetLoginKey(DWORD dwLoginKey); + void ClearLoginInfo( void ); + + void SetHandler(PyObject* poHandler); + void SetPhaseWindow(UINT ePhaseWnd, PyObject* poPhaseWnd); + void ClearPhaseWindow(UINT ePhaseWnd, PyObject* poPhaseWnd); + void SetServerCommandParserWindow(PyObject* poPhaseWnd); + + bool SendSyncPositionElementPacket(DWORD dwVictimVID, DWORD dwVictimX, DWORD dwVictimY); + + bool SendAttackPacket(UINT uMotAttack, DWORD dwVIDVictim); + bool SendCharacterStatePacket(const TPixelPosition& c_rkPPosDst, float fDstRot, UINT eFunc, UINT uArg); + bool SendUseSkillPacket(DWORD dwSkillIndex, DWORD dwTargetVID=0); + bool SendTargetPacket(DWORD dwVID); + + // OLDCODE: + bool SendCharacterStartWalkingPacket(float fRotation, long lx, long ly); + bool SendCharacterEndWalkingPacket(float fRotation, long lx, long ly); + bool SendCharacterCheckWalkingPacket(float fRotation, long lx, long ly); + + bool SendCharacterPositionPacket(BYTE iPosition); + + bool SendItemUsePacket(TItemPos pos); + bool SendItemUseToItemPacket(TItemPos source_pos, TItemPos target_pos); + bool SendItemDropPacket(TItemPos pos, DWORD elk); + bool SendItemDropPacketNew(TItemPos pos, DWORD elk, DWORD count); + bool SendItemMovePacket(TItemPos pos, TItemPos change_pos, BYTE num); + bool SendItemPickUpPacket(DWORD vid); + + bool SendQuickSlotAddPacket(BYTE wpos, BYTE type, BYTE pos); + bool SendQuickSlotDelPacket(BYTE wpos); + bool SendQuickSlotMovePacket(BYTE wpos, BYTE change_pos); + + // PointReset ӽ + bool SendPointResetPacket(); + + // Shop + bool SendShopEndPacket(); + bool SendShopBuyPacket(BYTE byCount); + bool SendShopSellPacket(BYTE bySlot); + bool SendShopSellPacketNew(BYTE bySlot, BYTE byCount); + + // Exchange + bool SendExchangeStartPacket(DWORD vid); + bool SendExchangeItemAddPacket(TItemPos ItemPos, BYTE byDisplayPos); + bool SendExchangeElkAddPacket(DWORD elk); + bool SendExchangeItemDelPacket(BYTE pos); + bool SendExchangeAcceptPacket(); + bool SendExchangeExitPacket(); + + // Quest + bool SendScriptAnswerPacket(int iAnswer); + bool SendScriptButtonPacket(unsigned int iIndex); + bool SendAnswerMakeGuildPacket(const char * c_szName); + bool SendQuestInputStringPacket(const char * c_szString); + bool SendQuestConfirmPacket(BYTE byAnswer, DWORD dwPID); + + // Event + bool SendOnClickPacket(DWORD vid); + + // Fly + bool SendFlyTargetingPacket(DWORD dwTargetVID, const TPixelPosition& kPPosTarget); + bool SendAddFlyTargetingPacket(DWORD dwTargetVID, const TPixelPosition& kPPosTarget); + bool SendShootPacket(UINT uSkill); + + // Command + bool ClientCommand(const char * c_szCommand); + void ServerCommand(char * c_szCommand); + + // Emoticon + void RegisterEmoticonString(const char * pcEmoticonString); + + // Party + bool SendPartyInvitePacket(DWORD dwVID); + bool SendPartyInviteAnswerPacket(DWORD dwLeaderVID, BYTE byAccept); + bool SendPartyRemovePacket(DWORD dwPID); + bool SendPartySetStatePacket(DWORD dwVID, BYTE byState, BYTE byFlag); + bool SendPartyUseSkillPacket(BYTE bySkillIndex, DWORD dwVID); + bool SendPartyParameterPacket(BYTE byDistributeMode); + + // SafeBox + bool SendSafeBoxMoneyPacket(BYTE byState, DWORD dwMoney); + bool SendSafeBoxCheckinPacket(TItemPos InventoryPos, BYTE bySafeBoxPos); + bool SendSafeBoxCheckoutPacket(BYTE bySafeBoxPos, TItemPos InventoryPos); + bool SendSafeBoxItemMovePacket(BYTE bySourcePos, BYTE byTargetPos, BYTE byCount); + + // Mall + bool SendMallCheckoutPacket(BYTE byMallPos, TItemPos InventoryPos); + + // Guild + bool SendGuildAddMemberPacket(DWORD dwVID); + bool SendGuildRemoveMemberPacket(DWORD dwPID); + bool SendGuildChangeGradeNamePacket(BYTE byGradeNumber, const char * c_szName); + bool SendGuildChangeGradeAuthorityPacket(BYTE byGradeNumber, BYTE byAuthority); + bool SendGuildOfferPacket(DWORD dwExperience); + bool SendGuildPostCommentPacket(const char * c_szMessage); + bool SendGuildDeleteCommentPacket(DWORD dwIndex); + bool SendGuildRefreshCommentsPacket(DWORD dwHighestIndex); + bool SendGuildChangeMemberGradePacket(DWORD dwPID, BYTE byGrade); + bool SendGuildUseSkillPacket(DWORD dwSkillID, DWORD dwTargetVID); + bool SendGuildChangeMemberGeneralPacket(DWORD dwPID, BYTE byFlag); + bool SendGuildInvitePacket(DWORD dwVID); + bool SendGuildInviteAnswerPacket(DWORD dwGuildID, BYTE byAnswer); + bool SendGuildChargeGSPPacket(DWORD dwMoney); + bool SendGuildDepositMoneyPacket(DWORD dwMoney); + bool SendGuildWithdrawMoneyPacket(DWORD dwMoney); + + // Mall + bool RecvMallOpenPacket(); + bool RecvMallItemSetPacket(); + bool RecvMallItemDelPacket(); + + // Lover + bool RecvLoverInfoPacket(); + bool RecvLovePointUpdatePacket(); + + // Dig + bool RecvDigMotionPacket(); + + // Fishing + bool SendFishingPacket(int iRotation); + bool SendGiveItemPacket(DWORD dwTargetVID, TItemPos ItemPos, int iItemCount); + + // Private Shop + bool SendBuildPrivateShopPacket(const char * c_szName, const std::vector & c_rSellingItemStock); + + // Refine + bool SendRefinePacket(BYTE byPos, BYTE byType); + bool SendSelectItemPacket(DWORD dwItemPos); + + // Client Version + bool SendClientVersionPacket(); + + // CRC Report + bool __SendCRCReportPacket(); + + // ȫ ȭ + bool SendDragonSoulRefinePacket(BYTE bRefineType, TItemPos* pos); + + // Handshake + bool RecvHandshakePacket(); + bool RecvHandshakeOKPacket(); + + bool RecvHybridCryptKeyPacket(); + bool RecvHybridCryptSDBPacket(); +#ifdef _IMPROVED_PACKET_ENCRYPTION_ + bool RecvKeyAgreementPacket(); + bool RecvKeyAgreementCompletedPacket(); + +#endif + // ETC + DWORD GetMainActorVID(); + DWORD GetMainActorRace(); + DWORD GetMainActorEmpire(); + DWORD GetMainActorSkillGroup(); + void SetEmpireID(DWORD dwEmpireID); + DWORD GetEmpireID(); + void __TEST_SetSkillGroupFake(int iIndex); + + ////////////////////////////////////////////////////////////////////////// + // Phase + ////////////////////////////////////////////////////////////////////////// + public: + void SetOffLinePhase(); + void SetHandShakePhase(); + void SetLoginPhase(); + void SetSelectPhase(); + void SetLoadingPhase(); + void SetGamePhase(); + void ClosePhase(); + + // Login Phase + bool SendLoginPacket(const char * c_szName, const char * c_szPassword); + bool SendLoginPacketNew(const char * c_szName, const char * c_szPassword); + bool SendChinaMatrixCardPacket(const char * c_szMatrixCardString); + bool SendRunupMatrixAnswerPacket(const char * c_szMatrixCardString); + bool SendNEWCIBNPasspodAnswerPacket(const char * answer); + bool SendDirectEnterPacket(const char * c_szName, const char * c_szPassword, UINT uChrSlot); + + bool SendEnterGame(); + + // Select Phase + bool SendSelectEmpirePacket(DWORD dwEmpireID); + bool SendSelectCharacterPacket(BYTE account_Index); + bool SendChangeNamePacket(BYTE index, const char *name); + bool SendCreateCharacterPacket(BYTE index, const char *name, BYTE job, BYTE shape, BYTE byStat1, BYTE byStat2, BYTE byStat3, BYTE byStat4); + bool SendDestroyCharacterPacket(BYTE index, const char * szPrivateCode); + + // Main Game Phase + bool SendC2CPacket(DWORD dwSize, void * pData); + bool SendChatPacket(const char * c_szChat, BYTE byType = CHAT_TYPE_TALKING); + bool SendWhisperPacket(const char * name, const char * c_szChat); + bool SendMobileMessagePacket(const char * name, const char * c_szChat); + bool SendMessengerAddByVIDPacket(DWORD vid); + bool SendMessengerAddByNamePacket(const char * c_szName); + bool SendMessengerRemovePacket(const char * c_szKey, const char * c_szName); + + protected: + bool OnProcess(); // State Ѵ. + void OffLinePhase(); + void HandShakePhase(); + void LoginPhase(); + void SelectPhase(); + void LoadingPhase(); + void GamePhase(); + + bool __IsNotPing(); + + void __DownloadMark(); + void __DownloadSymbol(const std::vector & c_rkVec_dwGuildID); + + void __PlayInventoryItemUseSound(TItemPos uSlotPos); + void __PlayInventoryItemDropSound(TItemPos uSlotPos); + //void __PlayShopItemDropSound(UINT uSlotPos); + void __PlaySafeBoxItemDropSound(UINT uSlotPos); + void __PlayMallItemDropSound(UINT uSlotPos); + + bool __CanActMainInstance(); + + enum REFRESH_WINDOW_TYPE + { + RefreshStatus = (1 << 0), + RefreshAlignmentWindow = (1 << 1), + RefreshCharacterWindow = (1 << 2), + RefreshEquipmentWindow = (1 << 3), + RefreshInventoryWindow = (1 << 4), + RefreshExchangeWindow = (1 << 5), + RefreshSkillWindow = (1 << 6), + RefreshSafeboxWindow = (1 << 7), + RefreshMessengerWindow = (1 << 8), + RefreshGuildWindowInfoPage = (1 << 9), + RefreshGuildWindowBoardPage = (1 << 10), + RefreshGuildWindowMemberPage = (1 << 11), + RefreshGuildWindowMemberPageGradeComboBox = (1 << 12), + RefreshGuildWindowSkillPage = (1 << 13), + RefreshGuildWindowGradePage = (1 << 14), + RefreshTargetBoard = (1 << 15), + RefreshMallWindow = (1 << 16), + }; + + void __RefreshStatus(); + void __RefreshAlignmentWindow(); + void __RefreshCharacterWindow(); + void __RefreshEquipmentWindow(); + void __RefreshInventoryWindow(); + void __RefreshExchangeWindow(); + void __RefreshSkillWindow(); + void __RefreshSafeboxWindow(); + void __RefreshMessengerWindow(); + void __RefreshGuildWindowInfoPage(); + void __RefreshGuildWindowBoardPage(); + void __RefreshGuildWindowMemberPage(); + void __RefreshGuildWindowMemberPageGradeComboBox(); + void __RefreshGuildWindowSkillPage(); + void __RefreshGuildWindowGradePage(); + void __RefreshTargetBoardByVID(DWORD dwVID); + void __RefreshTargetBoardByName(const char * c_szName); + void __RefreshTargetBoard(); + void __RefreshMallWindow(); + + bool __SendHack(const char* c_szMsg); + + protected: + bool RecvObserverAddPacket(); + bool RecvObserverRemovePacket(); + bool RecvObserverMovePacket(); + + // Common + bool RecvErrorPacket(int header); + bool RecvPingPacket(); + bool RecvDefaultPacket(int header); + bool RecvPhasePacket(); + + // Login Phase + bool __RecvLoginSuccessPacket3(); + bool __RecvLoginSuccessPacket4(); + bool __RecvLoginFailurePacket(); + bool __RecvEmpirePacket(); + bool __RecvChinaMatrixCardPacket(); + bool __RecvRunupMatrixQuizPacket(); + bool __RecvNEWCIBNPasspodRequestPacket(); + bool __RecvNEWCIBNPasspodFailurePacket(); + bool __RecvLoginKeyPacket(); + + // Select Phase + bool __RecvPlayerCreateSuccessPacket(); + bool __RecvPlayerCreateFailurePacket(); + bool __RecvPlayerDestroySuccessPacket(); + bool __RecvPlayerDestroyFailurePacket(); + bool __RecvPreserveItemPacket(); + bool __RecvPlayerPoints(); + bool __RecvChangeName(); + + // Loading Phase + bool RecvMainCharacter(); + bool RecvMainCharacter2_EMPIRE(); + bool RecvMainCharacter3_BGM(); + bool RecvMainCharacter4_BGM_VOL(); + + void __SetFieldMusicFileName(const char* musicName); + void __SetFieldMusicFileInfo(const char* musicName, float vol); + // END_OF_SUPPORT_BGM + + // Main Game Phase + bool RecvWarpPacket(); + bool RecvPVPPacket(); + bool RecvDuelStartPacket(); + bool RecvGlobalTimePacket(); + bool RecvCharacterAppendPacket(); + bool RecvCharacterAdditionalInfo(); + bool RecvCharacterAppendPacketNew(); + bool RecvCharacterUpdatePacket(); + bool RecvCharacterUpdatePacketNew(); + bool RecvCharacterDeletePacket(); + bool RecvChatPacket(); + bool RecvOwnerShipPacket(); + bool RecvSyncPositionPacket(); + bool RecvWhisperPacket(); + bool RecvPointChange(); // Alarm to python + bool RecvChangeSpeedPacket(); + + bool RecvStunPacket(); + bool RecvDeadPacket(); + bool RecvCharacterMovePacket(); + + bool RecvItemSetPacket(); // Alarm to python + bool RecvItemSetPacket2(); // Alarm to python + bool RecvItemUsePacket(); // Alarm to python + bool RecvItemUpdatePacket(); // Alarm to python + bool RecvItemGroundAddPacket(); + bool RecvItemGroundDelPacket(); + bool RecvItemOwnership(); + + bool RecvQuickSlotAddPacket(); // Alarm to python + bool RecvQuickSlotDelPacket(); // Alarm to python + bool RecvQuickSlotMovePacket(); // Alarm to python + + bool RecvCharacterPositionPacket(); + bool RecvMotionPacket(); + + bool RecvShopPacket(); + bool RecvShopSignPacket(); + bool RecvExchangePacket(); + + // Quest + bool RecvScriptPacket(); + bool RecvQuestInfoPacket(); + bool RecvQuestConfirmPacket(); + bool RecvRequestMakeGuild(); + + // Skill + bool RecvSkillLevel(); + bool RecvSkillLevelNew(); + bool RecvSkillCoolTimeEnd(); + + // Target + bool RecvTargetPacket(); + bool RecvViewEquipPacket(); + bool RecvDamageInfoPacket(); + + // Mount + bool RecvMountPacket(); + + // Fly + bool RecvCreateFlyPacket(); + bool RecvFlyTargetingPacket(); + bool RecvAddFlyTargetingPacket(); + + // Messenger + bool RecvMessenger(); + + // Guild + bool RecvGuild(); + + // Party + bool RecvPartyInvite(); + bool RecvPartyAdd(); + bool RecvPartyUpdate(); + bool RecvPartyRemove(); + bool RecvPartyLink(); + bool RecvPartyUnlink(); + bool RecvPartyParameter(); + + // SafeBox + bool RecvSafeBoxSetPacket(); + bool RecvSafeBoxDelPacket(); + bool RecvSafeBoxWrongPasswordPacket(); + bool RecvSafeBoxSizePacket(); + bool RecvSafeBoxMoneyChangePacket(); + + // Fishing + bool RecvFishing(); + + // Dungeon + bool RecvDungeon(); + + // Time + bool RecvTimePacket(); + + // WalkMode + bool RecvWalkModePacket(); + + // ChangeSkillGroup + bool RecvChangeSkillGroupPacket(); + + // Refine + bool RecvRefineInformationPacket(); + bool RecvRefineInformationPacketNew(); + + // Use Potion + bool RecvSpecialEffect(); + + // Ʈ ߵ Ŷ. + bool RecvSpecificEffect(); + + // ȥ + bool RecvDragonSoulRefine(); + + // MiniMap Info + bool RecvNPCList(); + bool RecvLandPacket(); + bool RecvTargetCreatePacket(); + bool RecvTargetCreatePacketNew(); + bool RecvTargetUpdatePacket(); + bool RecvTargetDeletePacket(); + + // Affect + bool RecvAffectAddPacket(); + bool RecvAffectRemovePacket(); + + // Channel + bool RecvChannelPacket(); + + //Security + bool RecvHSCheckRequest(); + bool RecvXTrapVerifyRequest(); + + protected: + // ̸Ƽ + bool ParseEmoticon(const char * pChatMsg, DWORD * pdwEmoticon); + + // ̽ ݵ + void OnConnectFailure(); + void OnScriptEventStart(int iSkin, int iIndex); + + void OnRemoteDisconnect(); + void OnDisconnect(); + + void SetGameOnline(); + void SetGameOffline(); + BOOL IsGameOnline(); + + protected: + bool CheckPacket(TPacketHeader * pRetHeader); + + void __InitializeGamePhase(); + void __InitializeMarkAuth(); + void __GlobalPositionToLocalPosition(LONG& rGlobalX, LONG& rGlobalY); + void __LocalPositionToGlobalPosition(LONG& rLocalX, LONG& rLocalY); + + bool __IsPlayerAttacking(); + bool __IsEquipItemInSlot(TItemPos Cell); + + void __ShowMapName(LONG lLocalX, LONG lLocalY); + + void __LeaveOfflinePhase() {} + void __LeaveHandshakePhase() {} + void __LeaveLoginPhase() {} + void __LeaveSelectPhase() {} + void __LeaveLoadingPhase() {} + void __LeaveGamePhase(); + + void __ClearNetworkActorManager(); + + void __ClearSelectCharacterData(); + + // DELETEME + //void __SendWarpPacket(); + + void __ConvertEmpireText(DWORD dwEmpireID, char* szText); + + void __RecvCharacterAppendPacket(SNetworkActorData * pkNetActorData); + void __RecvCharacterUpdatePacket(SNetworkUpdateActorData * pkNetUpdateActorData); + + void __FilterInsult(char* szLine, UINT uLineLen); + + void __SetGuildID(DWORD id); + + protected: + TPacketGCHandshake m_HandshakeData; + DWORD m_dwChangingPhaseTime; + DWORD m_dwBindupRetryCount; + DWORD m_dwMainActorVID; + DWORD m_dwMainActorRace; + DWORD m_dwMainActorEmpire; + DWORD m_dwMainActorSkillGroup; + BOOL m_isGameOnline; + BOOL m_isStartGame; + + DWORD m_dwGuildID; + DWORD m_dwEmpireID; + + struct SServerTimeSync + { + DWORD m_dwChangeServerTime; + DWORD m_dwChangeClientTime; + } m_kServerTimeSync; + + void __ServerTimeSync_Initialize(); + //DWORD m_dwBaseServerTime; + //DWORD m_dwBaseClientTime; + + DWORD m_dwLastGamePingTime; + + std::string m_stID; + std::string m_stPassword; + std::string m_strLastCommand; + std::string m_strPhase; + DWORD m_dwLoginKey; + BOOL m_isWaitLoginKey; + + std::string m_stMarkIP; + + CFuncObject m_phaseProcessFunc; + CFuncObject m_phaseLeaveFunc; + + PyObject* m_poHandler; + PyObject* m_apoPhaseWnd[PHASE_WINDOW_NUM]; + PyObject* m_poSerCommandParserWnd; + + TSimplePlayerInformation m_akSimplePlayerInfo[PLAYER_PER_ACCOUNT4]; + DWORD m_adwGuildID[PLAYER_PER_ACCOUNT4]; + std::string m_astrGuildName[PLAYER_PER_ACCOUNT4]; + bool m_bSimplePlayerInfo; + + CRef m_rokNetActorMgr; + + bool m_isRefreshStatus; + bool m_isRefreshCharacterWnd; + bool m_isRefreshEquipmentWnd; + bool m_isRefreshInventoryWnd; + bool m_isRefreshExchangeWnd; + bool m_isRefreshSkillWnd; + bool m_isRefreshSafeboxWnd; + bool m_isRefreshMallWnd; + bool m_isRefreshMessengerWnd; + bool m_isRefreshGuildWndInfoPage; + bool m_isRefreshGuildWndBoardPage; + bool m_isRefreshGuildWndMemberPage; + bool m_isRefreshGuildWndMemberPageGradeComboBox; + bool m_isRefreshGuildWndSkillPage; + bool m_isRefreshGuildWndGradePage; + + // Emoticon + std::vector m_EmoticonStringVector; + + struct STextConvertTable + { + char acUpper[26]; + char acLower[26]; + BYTE aacHan[5000][2]; + } m_aTextConvTable[3]; + + + + struct SMarkAuth + { + CNetworkAddress m_kNetAddr; + DWORD m_dwHandle; + DWORD m_dwRandomKey; + } m_kMarkAuth; + + + + DWORD m_dwSelectedCharacterIndex; + + CInsultChecker m_kInsultChecker; + + bool m_isEnableChatInsultFilter; + bool m_bComboSkillFlag; + + std::deque m_kQue_stHack; + + private: + struct SDirectEnterMode + { + bool m_isSet; + DWORD m_dwChrSlotIndex; + } m_kDirectEnterMode; + + void __DirectEnterMode_Initialize(); + void __DirectEnterMode_Set(UINT uChrSlotIndex); + bool __DirectEnterMode_IsSet(); + + public: + DWORD EXPORT_GetBettingGuildWarValue(const char* c_szValueName); + + private: + struct SBettingGuildWar + { + DWORD m_dwBettingMoney; + DWORD m_dwObserverCount; + } m_kBettingGuildWar; + + CInstanceBase * m_pInstTarget; + + void __BettingGuildWar_Initialize(); + void __BettingGuildWar_SetObserverCount(UINT uObserverCount); + void __BettingGuildWar_SetBettingMoney(UINT uBettingMoney); +}; diff --git a/source/UserInterface/PythonNetworkStreamCommand.cpp b/source/UserInterface/PythonNetworkStreamCommand.cpp new file mode 100644 index 0000000..017ad23 --- /dev/null +++ b/source/UserInterface/PythonNetworkStreamCommand.cpp @@ -0,0 +1,557 @@ +#include "StdAfx.h" +#include "PythonNetworkStream.h" +#include "PythonNonPlayer.h" +#include "AbstractApplication.h" +#include "AbstractPlayer.h" +#include "AbstractCharacterManager.h" +#include "AbstractChat.h" +#include "InstanceBase.h" + +#define ishan(ch) (((ch) & 0xE0) > 0x90) +#define ishanasc(ch) (isascii(ch) || ishan(ch)) +#define ishanalp(ch) (isalpha(ch) || ishan(ch)) +#define isnhdigit(ch) (!ishan(ch) && isdigit(ch)) +#define isnhspace(ch) (!ishan(ch) && isspace(ch)) + +#define LOWER(c) (((c) >= 'A' && (c) <= 'Z') ? ((c) + ('a' - 'A')) : (c)) +#define UPPER(c) (((c) >= 'a' && (c) <= 'z') ? ((c) + ('A' - 'a')) : (c)) + +void SkipSpaces(char **string) +{ + for (; **string != '\0' && isnhspace((unsigned char) **string); ++(*string)); +} + +char *OneArgument(char *argument, char *first_arg) +{ + char mark = FALSE; + + if (!argument) + { + *first_arg = '\0'; + return NULL; + } + + SkipSpaces(&argument); + + while (*argument) + { + if (*argument == '\"') + { + mark = !mark; + ++argument; + continue; + } + + if (!mark && isnhspace((unsigned char) *argument)) + break; + + *(first_arg++) = LOWER(*argument); + ++argument; + } + + *first_arg = '\0'; + + SkipSpaces(&argument); + return (argument); +} + +void AppendMonsterList(const CPythonNonPlayer::TMobTableList & c_rMobTableList, const char * c_szHeader, int iType) +{ + DWORD dwMonsterCount = 0; + std::string strMonsterList = c_szHeader; + + CPythonNonPlayer::TMobTableList::const_iterator itor = c_rMobTableList.begin(); + for (; itor!=c_rMobTableList.end(); ++itor) + { + const CPythonNonPlayer::TMobTable * c_pMobTable = *itor; + if (iType == c_pMobTable->bRank) + { + if (dwMonsterCount != 0) + strMonsterList += ", "; + strMonsterList += c_pMobTable->szLocaleName; + if (++dwMonsterCount > 5) + break; + } + } + if (dwMonsterCount > 0) + { + IAbstractChat& rkChat=IAbstractChat::GetSingleton(); + rkChat.AppendChat(CHAT_TYPE_INFO, strMonsterList.c_str()); + } +} + +bool CPythonNetworkStream::ClientCommand(const char * c_szCommand) +{ + return false; +} + +bool SplitToken(const char * c_szLine, CTokenVector * pstTokenVector, const char * c_szDelimeter = " ") +{ + pstTokenVector->reserve(10); + pstTokenVector->clear(); + + std::string stToken; + std::string strLine = c_szLine; + + DWORD basePos = 0; + + do + { + int beginPos = strLine.find_first_not_of(c_szDelimeter, basePos); + if (beginPos < 0) + return false; + + int endPos; + + if (strLine[beginPos] == '"') + { + ++beginPos; + endPos = strLine.find_first_of("\"", beginPos); + + if (endPos < 0) + return false; + + basePos = endPos + 1; + } + else + { + endPos = strLine.find_first_of(c_szDelimeter, beginPos); + basePos = endPos; + } + + pstTokenVector->push_back(strLine.substr(beginPos, endPos - beginPos)); + + // ߰ ڵ. ǵڿ ִ 츦 üũѴ. - [levites] + if (int(strLine.find_first_not_of(c_szDelimeter, basePos)) < 0) + break; + } while (basePos < strLine.length()); + + return true; +} + +void CPythonNetworkStream::ServerCommand(char * c_szCommand) +{ + // #0000811: [M2EU] ܼâ + if (strcmpi(c_szCommand, "ConsoleEnable") == 0) + return; + + if (m_apoPhaseWnd[PHASE_WINDOW_GAME]) + { + bool isTrue; + if (PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], + "BINARY_ServerCommand_Run", + Py_BuildValue("(s)", c_szCommand), + &isTrue + )) + { + if (isTrue) + return; + } + } + else if (m_poSerCommandParserWnd) + { + bool isTrue; + if (PyCallClassMemberFunc(m_poSerCommandParserWnd, + "BINARY_ServerCommand_Run", + Py_BuildValue("(s)", c_szCommand), + &isTrue + )) + { + if (isTrue) + return; + } + } + + CTokenVector TokenVector; + if (!SplitToken(c_szCommand, &TokenVector)) + return; + if (TokenVector.empty()) + return; + + const char * szCmd = TokenVector[0].c_str(); + + if (!strcmpi(szCmd, "quit")) + { + PostQuitMessage(0); + } + else if (!strcmpi(szCmd, "BettingMoney")) + { + if (2 != TokenVector.size()) + { + TraceError("CPythonNetworkStream::ServerCommand(c_szCommand=%s) - Strange Parameter Count : %s", c_szCommand); + return; + } + + //UINT uMoney= atoi(TokenVector[1].c_str()); + + } + // GIFT NOTIFY + else if (!strcmpi(szCmd, "gift")) + { + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "Gift_Show", Py_BuildValue("()")); + } + // CUBE + else if (!strcmpi(szCmd, "cube")) + { + if (TokenVector.size() < 2) + { + TraceError("CPythonNetworkStream::ServerCommand(c_szCommand=%s) - Strange Parameter Count : %s", c_szCommand); + return; + } + + if ("open" == TokenVector[1]) + { + if (3 > TokenVector.size()) + { + TraceError("CPythonNetworkStream::ServerCommand(c_szCommand=%s) - Strange Parameter Count : %s", c_szCommand); + return; + } + + DWORD npcVNUM = (DWORD)atoi(TokenVector[2].c_str()); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_Cube_Open", Py_BuildValue("(i)", npcVNUM)); + } + else if ("close" == TokenVector[1]) + { + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_Cube_Close", Py_BuildValue("()")); + } + else if ("info" == TokenVector[1]) + { + if (5 != TokenVector.size()) + { + TraceError("CPythonNetworkStream::ServerCommand(c_szCommand=%s) - Strange Parameter Count : %s", c_szCommand); + return; + } + + UINT gold = atoi(TokenVector[2].c_str()); + UINT itemVnum = atoi(TokenVector[3].c_str()); + UINT count = atoi(TokenVector[4].c_str()); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_Cube_UpdateInfo", Py_BuildValue("(iii)", gold, itemVnum, count)); + } + else if ("success" == TokenVector[1]) + { + if (4 != TokenVector.size()) + { + TraceError("CPythonNetworkStream::ServerCommand(c_szCommand=%s) - Strange Parameter Count : %s", c_szCommand); + return; + } + + UINT itemVnum = atoi(TokenVector[2].c_str()); + UINT count = atoi(TokenVector[3].c_str()); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_Cube_Succeed", Py_BuildValue("(ii)", itemVnum, count)); + } + else if ("fail" == TokenVector[1]) + { + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_Cube_Failed", Py_BuildValue("()")); + } + else if ("r_list" == TokenVector[1]) + { + // result list (/cube r_list npcVNUM resultCount resultText) + // 20383 4 72723,1/72725,1/72730.1/50001,5 <- ̷ "/" ڷ е Ʈ + if (5 != TokenVector.size()) + { + TraceError("CPythonNetworkStream::ServerCommand(c_szCommand=%s) - Strange Parameter Count : %d", c_szCommand, 5); + return; + } + + DWORD npcVNUM = (DWORD)atoi(TokenVector[2].c_str()); + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_Cube_ResultList", Py_BuildValue("(is)", npcVNUM, TokenVector[4].c_str())); + } + else if ("m_info" == TokenVector[1]) + { + // material list (/cube m_info requestStartIndex resultCount MaterialText) + // ex) requestStartIndex: 0, resultCount : 5 - ش NPC ִ 0~4° شϴ ʿ MaterialText + // ó ټ "@" ڸ + // 0 5 125,1|126,2|127,2|123,5&555,5&555,4/120000 <- ̷ Ŭ Ʈ + + if (5 != TokenVector.size()) + { + TraceError("CPythonNetworkStream::ServerCommand(c_szCommand=%s) - Strange Parameter Count : %d", c_szCommand, 5); + return; + } + + UINT requestStartIndex = (UINT)atoi(TokenVector[2].c_str()); + UINT resultCount = (UINT)atoi(TokenVector[3].c_str()); + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_Cube_MaterialInfo", Py_BuildValue("(iis)", requestStartIndex, resultCount, TokenVector[4].c_str())); + } + } + // CUEBE_END + else if (!strcmpi(szCmd, "ObserverCount")) + { + if (2 != TokenVector.size()) + { + TraceError("CPythonNetworkStream::ServerCommand(c_szCommand=%s) - Strange Parameter Count : %s", c_szCommand); + return; + } + + UINT uObserverCount= atoi(TokenVector[1].c_str()); + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], + "BINARY_BettingGuildWar_UpdateObserverCount", + Py_BuildValue("(i)", uObserverCount) + ); + } + else if (!strcmpi(szCmd, "ObserverMode")) + { + if (2 != TokenVector.size()) + { + TraceError("CPythonNetworkStream::ServerCommand(c_szCommand=%s) - Strange Parameter Count : %s", c_szCommand); + return; + } + + UINT uMode= atoi(TokenVector[1].c_str()); + + IAbstractPlayer& rkPlayer=IAbstractPlayer::GetSingleton(); + rkPlayer.SetObserverMode(uMode ? true : false); + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], + "BINARY_BettingGuildWar_SetObserverMode", + Py_BuildValue("(i)", uMode) + ); + } + else if (!strcmpi(szCmd, "ObserverTeamInfo")) + { + } + else if (!strcmpi(szCmd, "StoneDetect")) + { + if (4 != TokenVector.size()) + { + TraceError("CPythonNetworkStream::ServerCommand(c_szCommand=%s) - Strange Parameter Count : %s", c_szCommand); + return; + } + + // vid distance(1-3) angle(0-360) + DWORD dwVID = atoi(TokenVector[1].c_str()); + BYTE byDistance = atoi(TokenVector[2].c_str()); + float fAngle = atof(TokenVector[3].c_str()); + fAngle = fmod(540.0f - fAngle, 360.0f); + Tracef("StoneDetect [VID:%d] [Distance:%d] [Angle:%d->%f]\n", dwVID, byDistance, atoi(TokenVector[3].c_str()), fAngle); + + IAbstractCharacterManager& rkChrMgr=IAbstractCharacterManager::GetSingleton(); + + CInstanceBase * pInstance = rkChrMgr.GetInstancePtr(dwVID); + if (!pInstance) + { + TraceError("CPythonNetworkStream::ServerCommand(c_szCommand=%s) - Not Exist Instance", c_szCommand); + return; + } + + TPixelPosition PixelPosition; + D3DXVECTOR3 v3Rotation(0.0f, 0.0f, fAngle); + pInstance->NEW_GetPixelPosition(&PixelPosition); + + PixelPosition.y *= -1.0f; + + switch (byDistance) + { + case 0: + CEffectManager::Instance().RegisterEffect("d:/ymir work/effect/etc/firecracker/find_out.mse"); + CEffectManager::Instance().CreateEffect("d:/ymir work/effect/etc/firecracker/find_out.mse", PixelPosition, v3Rotation); + break; + case 1: + CEffectManager::Instance().RegisterEffect("d:/ymir work/effect/etc/compass/appear_small.mse"); + CEffectManager::Instance().CreateEffect("d:/ymir work/effect/etc/compass/appear_small.mse", PixelPosition, v3Rotation); + break; + case 2: + CEffectManager::Instance().RegisterEffect("d:/ymir work/effect/etc/compass/appear_middle.mse"); + CEffectManager::Instance().CreateEffect("d:/ymir work/effect/etc/compass/appear_middle.mse", PixelPosition, v3Rotation); + break; + case 3: + CEffectManager::Instance().RegisterEffect("d:/ymir work/effect/etc/compass/appear_large.mse"); + CEffectManager::Instance().CreateEffect("d:/ymir work/effect/etc/compass/appear_large.mse", PixelPosition, v3Rotation); + break; + default: + TraceError("CPythonNetworkStream::ServerCommand(c_szCommand=%s) - Strange Distance", c_szCommand); + break; + } + +#ifdef _DEBUG + IAbstractChat& rkChat=IAbstractChat::GetSingleton(); + rkChat.AppendChat(CHAT_TYPE_INFO, c_szCommand); +#endif + } + else if (!strcmpi(szCmd, "StartStaminaConsume")) + { + if (3 != TokenVector.size()) + { + TraceError("CPythonNetworkStream::ServerCommand(c_szCommand=%s) - Strange Parameter Count : %s", c_szCommand); + return; + } + + DWORD dwConsumePerSec = atoi(TokenVector[1].c_str()); + DWORD dwCurrentStamina = atoi(TokenVector[2].c_str()); + + IAbstractPlayer& rPlayer=IAbstractPlayer::GetSingleton(); + rPlayer.StartStaminaConsume(dwConsumePerSec, dwCurrentStamina); + } + + else if (!strcmpi(szCmd, "StopStaminaConsume")) + { + if (2 != TokenVector.size()) + { + TraceError("CPythonNetworkStream::ServerCommand(c_szCommand=%s) - Strange Parameter Count : %d", c_szCommand, TokenVector.size()); + return; + } + + DWORD dwCurrentStamina = atoi(TokenVector[1].c_str()); + + IAbstractPlayer& rPlayer=IAbstractPlayer::GetSingleton(); + rPlayer.StopStaminaConsume(dwCurrentStamina); + } + else if (!strcmpi(szCmd, "sms")) + { + IAbstractPlayer& rPlayer=IAbstractPlayer::GetSingleton(); + rPlayer.SetMobileFlag(TRUE); + } + else if (!strcmpi(szCmd, "nosms")) + { + IAbstractPlayer& rPlayer=IAbstractPlayer::GetSingleton(); + rPlayer.SetMobileFlag(FALSE); + } + else if (!strcmpi(szCmd, "mobile_auth")) + { + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnMobileAuthority", Py_BuildValue("()")); + } + else if (!strcmpi(szCmd, "messenger_auth")) + { + const std::string & c_rstrName = TokenVector[1].c_str(); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnMessengerAddFriendQuestion", Py_BuildValue("(s)", c_rstrName.c_str())); + } + else if (!strcmpi(szCmd, "combo")) + { + int iFlag = atoi(TokenVector[1].c_str()); + IAbstractPlayer& rPlayer=IAbstractPlayer::GetSingleton(); + rPlayer.SetComboSkillFlag(iFlag); + m_bComboSkillFlag = iFlag ? true : false; + } + else if (!strcmpi(szCmd, "setblockmode")) + { + int iFlag = atoi(TokenVector[1].c_str()); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnBlockMode", Py_BuildValue("(i)", iFlag)); + } + // Emotion Start + else if (!strcmpi(szCmd, "french_kiss")) + { + int iVID1 = atoi(TokenVector[1].c_str()); + int iVID2 = atoi(TokenVector[2].c_str()); + + IAbstractCharacterManager & rkChrMgr = IAbstractCharacterManager::GetSingleton(); + CInstanceBase * pInstance1 = rkChrMgr.GetInstancePtr(iVID1); + CInstanceBase * pInstance2 = rkChrMgr.GetInstancePtr(iVID2); + if (pInstance1 && pInstance2) + pInstance1->ActDualEmotion(*pInstance2, CRaceMotionData::NAME_FRENCH_KISS_START, CRaceMotionData::NAME_FRENCH_KISS_START); + } + else if (!strcmpi(szCmd, "kiss")) + { + int iVID1 = atoi(TokenVector[1].c_str()); + int iVID2 = atoi(TokenVector[2].c_str()); + + IAbstractCharacterManager & rkChrMgr = IAbstractCharacterManager::GetSingleton(); + CInstanceBase * pInstance1 = rkChrMgr.GetInstancePtr(iVID1); + CInstanceBase * pInstance2 = rkChrMgr.GetInstancePtr(iVID2); + if (pInstance1 && pInstance2) + pInstance1->ActDualEmotion(*pInstance2, CRaceMotionData::NAME_KISS_START, CRaceMotionData::NAME_KISS_START); + } + else if (!strcmpi(szCmd, "slap")) + { + int iVID1 = atoi(TokenVector[1].c_str()); + int iVID2 = atoi(TokenVector[2].c_str()); + + IAbstractCharacterManager & rkChrMgr = IAbstractCharacterManager::GetSingleton(); + CInstanceBase * pInstance1 = rkChrMgr.GetInstancePtr(iVID1); + CInstanceBase * pInstance2 = rkChrMgr.GetInstancePtr(iVID2); + if (pInstance1 && pInstance2) + pInstance1->ActDualEmotion(*pInstance2, CRaceMotionData::NAME_SLAP_HURT_START, CRaceMotionData::NAME_SLAP_HIT_START); + } + else if (!strcmpi(szCmd, "clap")) + { + int iVID = atoi(TokenVector[1].c_str()); + IAbstractCharacterManager & rkChrMgr = IAbstractCharacterManager::GetSingleton(); + CInstanceBase * pInstance = rkChrMgr.GetInstancePtr(iVID); + if (pInstance) + pInstance->ActEmotion(CRaceMotionData::NAME_CLAP); + } + else if (!strcmpi(szCmd, "cheer1")) + { + int iVID = atoi(TokenVector[1].c_str()); + IAbstractCharacterManager & rkChrMgr = IAbstractCharacterManager::GetSingleton(); + CInstanceBase * pInstance = rkChrMgr.GetInstancePtr(iVID); + if (pInstance) + pInstance->ActEmotion(CRaceMotionData::NAME_CHEERS_1); + } + else if (!strcmpi(szCmd, "cheer2")) + { + int iVID = atoi(TokenVector[1].c_str()); + IAbstractCharacterManager & rkChrMgr = IAbstractCharacterManager::GetSingleton(); + CInstanceBase * pInstance = rkChrMgr.GetInstancePtr(iVID); + if (pInstance) + pInstance->ActEmotion(CRaceMotionData::NAME_CHEERS_2); + } + else if (!strcmpi(szCmd, "dance1")) + { + int iVID = atoi(TokenVector[1].c_str()); + IAbstractCharacterManager & rkChrMgr = IAbstractCharacterManager::GetSingleton(); + CInstanceBase * pInstance = rkChrMgr.GetInstancePtr(iVID); + if (pInstance) + pInstance->ActEmotion(CRaceMotionData::NAME_DANCE_1); + } + else if (!strcmpi(szCmd, "dance2")) + { + int iVID = atoi(TokenVector[1].c_str()); + IAbstractCharacterManager & rkChrMgr = IAbstractCharacterManager::GetSingleton(); + CInstanceBase * pInstance = rkChrMgr.GetInstancePtr(iVID); + if (pInstance) + pInstance->ActEmotion(CRaceMotionData::NAME_DANCE_2); + } + else if (!strcmpi(szCmd, "dig_motion")) + { + int iVID = atoi(TokenVector[1].c_str()); + IAbstractCharacterManager & rkChrMgr = IAbstractCharacterManager::GetSingleton(); + CInstanceBase * pInstance = rkChrMgr.GetInstancePtr(iVID); + if (pInstance) + pInstance->ActEmotion(CRaceMotionData::NAME_DIG); + } + // Emotion End + else + { + static std::map s_emotionDict; + + static bool s_isFirst = true; + if (s_isFirst) + { + s_isFirst = false; + + s_emotionDict["dance3"] = CRaceMotionData::NAME_DANCE_3; + s_emotionDict["dance4"] = CRaceMotionData::NAME_DANCE_4; + s_emotionDict["dance5"] = CRaceMotionData::NAME_DANCE_5; + s_emotionDict["dance6"] = CRaceMotionData::NAME_DANCE_6; + s_emotionDict["congratulation"] = CRaceMotionData::NAME_CONGRATULATION; + s_emotionDict["forgive"] = CRaceMotionData::NAME_FORGIVE; + s_emotionDict["angry"] = CRaceMotionData::NAME_ANGRY; + s_emotionDict["attractive"] = CRaceMotionData::NAME_ATTRACTIVE; + s_emotionDict["sad"] = CRaceMotionData::NAME_SAD; + s_emotionDict["shy"] = CRaceMotionData::NAME_SHY; + s_emotionDict["cheerup"] = CRaceMotionData::NAME_CHEERUP; + s_emotionDict["banter"] = CRaceMotionData::NAME_BANTER; + s_emotionDict["joy"] = CRaceMotionData::NAME_JOY; + } + + std::map::iterator f = s_emotionDict.find(szCmd); + if (f == s_emotionDict.end()) + { + TraceError("Unknown Server Command %s | %s", c_szCommand, szCmd); + } + else + { + int emotionIndex = f->second; + + int iVID = atoi(TokenVector[1].c_str()); + IAbstractCharacterManager & rkChrMgr = IAbstractCharacterManager::GetSingleton(); + CInstanceBase * pInstance = rkChrMgr.GetInstancePtr(iVID); + + if (pInstance) + pInstance->ActEmotion(emotionIndex); + } + } +} diff --git a/source/UserInterface/PythonNetworkStreamEvent.cpp b/source/UserInterface/PythonNetworkStreamEvent.cpp new file mode 100644 index 0000000..f74cffc --- /dev/null +++ b/source/UserInterface/PythonNetworkStreamEvent.cpp @@ -0,0 +1,18 @@ +#include "StdAfx.h" +#include "PythonNetworkStream.h" + +void CPythonNetworkStream::OnRemoteDisconnect() +{ + PyCallClassMemberFunc(m_poHandler, "SetLoginPhase", Py_BuildValue("()")); +} + +void CPythonNetworkStream::OnDisconnect() +{ +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////// +// Main Game +void CPythonNetworkStream::OnScriptEventStart(int iSkin, int iIndex) +{ + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OpenQuestWindow", Py_BuildValue("(ii)", iSkin, iIndex)); +} \ No newline at end of file diff --git a/source/UserInterface/PythonNetworkStreamModule.cpp b/source/UserInterface/PythonNetworkStreamModule.cpp new file mode 100644 index 0000000..ca1207e --- /dev/null +++ b/source/UserInterface/PythonNetworkStreamModule.cpp @@ -0,0 +1,1932 @@ +#include "StdAfx.h" +#include "PythonNetworkStream.h" +//#include "PythonNetworkDatagram.h" +#include "AccountConnector.h" +#include "PythonGuild.h" +#include "Test.h" + +#include "AbstractPlayer.h" + +static std::string gs_stServerInfo; +extern BOOL gs_bEmpireLanuageEnable; +std::list g_kList_strCommand; + +PyObject* netGetBettingGuildWarValue(PyObject* poSelf, PyObject* poArgs) +{ + char* szName; + if (!PyTuple_GetString(poArgs, 0, &szName)) + return Py_BuildException(); + + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + return Py_BuildValue("i", rkNetStream.EXPORT_GetBettingGuildWarValue(szName)); +} + +PyObject* netSetServerInfo(PyObject* poSelf, PyObject* poArgs) +{ + char* szFileName; + if (!PyTuple_GetString(poArgs, 0, &szFileName)) + return Py_BuildException(); + + gs_stServerInfo=szFileName; + return Py_BuildNone(); +} + +PyObject* netGetServerInfo(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildValue("s", gs_stServerInfo.c_str()); +} + +PyObject* netPreserveServerCommand(PyObject* poSelf, PyObject* poArgs) +{ + char* szLine; + if (!PyTuple_GetString(poArgs, 0, &szLine)) + return Py_BuildException(); + + g_kList_strCommand.push_back(szLine); + + return Py_BuildNone(); +} + +PyObject* netGetPreservedServerCommand(PyObject* poSelf, PyObject* poArgs) +{ + if (g_kList_strCommand.empty()) + return Py_BuildValue("s", ""); + + std::string strCommand = g_kList_strCommand.front(); + g_kList_strCommand.pop_front(); + + return Py_BuildValue("s", strCommand.c_str()); +} + +PyObject* netStartGame(PyObject* poSelf, PyObject* poArgs) +{ + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.StartGame(); + + return Py_BuildNone(); +} + +PyObject* netIsTest(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildValue("i", __IS_TEST_SERVER_MODE__); +} + +PyObject* netWarp(PyObject* poSelf, PyObject* poArgs) +{ + int nX; + if (!PyTuple_GetInteger(poArgs, 0, &nX)) + return Py_BuildException(); + + int nY; + if (!PyTuple_GetInteger(poArgs, 1, &nY)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.Warp(nX, nY); + + return Py_BuildNone(); +} + +PyObject* netLoadInsultList(PyObject* poSelf, PyObject* poArgs) +{ + char* szFileName; + if (!PyTuple_GetString(poArgs, 0, &szFileName)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + return Py_BuildValue("i", rkNetStream.LoadInsultList(szFileName)); +} + +PyObject* netUploadMark(PyObject* poSelf, PyObject* poArgs) +{ + char* szFileName; + if (!PyTuple_GetString(poArgs, 0, &szFileName)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + return Py_BuildValue("i", rkNetStream.UploadMark(szFileName)); +} + +PyObject* netUploadSymbol(PyObject* poSelf, PyObject* poArgs) +{ + char* szFileName; + if (!PyTuple_GetString(poArgs, 0, &szFileName)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + return Py_BuildValue("i", rkNetStream.UploadSymbol(szFileName)); +} + +PyObject* netGetGuildID(PyObject* poSelf, PyObject* poArgs) +{ + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + return Py_BuildValue("i", rkNetStream.GetGuildID()); +} + +PyObject* netGetEmpireID(PyObject* poSelf, PyObject* poArgs) +{ + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + return Py_BuildValue("i", rkNetStream.GetEmpireID()); +} + +PyObject* netGetMainActorVID(PyObject* poSelf, PyObject* poArgs) +{ + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + return Py_BuildValue("i", rkNetStream.GetMainActorVID()); +} + +PyObject* netGetMainActorRace(PyObject* poSelf, PyObject* poArgs) +{ + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + return Py_BuildValue("i", rkNetStream.GetMainActorRace()); +} + +PyObject* netGetMainActorEmpire(PyObject* poSelf, PyObject* poArgs) +{ + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + return Py_BuildValue("i", rkNetStream.GetMainActorEmpire()); +} + +PyObject* netGetMainActorSkillGroup(PyObject* poSelf, PyObject* poArgs) +{ + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + return Py_BuildValue("i", rkNetStream.GetMainActorSkillGroup()); +} + +PyObject* netIsSelectedEmpire(PyObject* poSelf, PyObject* poArgs) +{ + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + return Py_BuildValue("i", rkNetStream.IsSelectedEmpire()); +} + + +PyObject* netGetAccountCharacterSlotDataInteger(PyObject* poSelf, PyObject* poArgs) +{ + int nIndex; + if (!PyTuple_GetInteger(poArgs, 0, &nIndex)) + return Py_BuildException(); + + int nType; + if (!PyTuple_GetInteger(poArgs, 1, &nType)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + UINT uResult=rkNetStream.GetAccountCharacterSlotDatau(nIndex, nType); + return Py_BuildValue("i", uResult); +} + +PyObject* netGetAccountCharacterSlotDataString(PyObject* poSelf, PyObject* poArgs) +{ + int nIndex; + if (!PyTuple_GetInteger(poArgs, 0, &nIndex)) + return Py_BuildException(); + + int nType; + if (!PyTuple_GetInteger(poArgs, 1, &nType)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + return Py_BuildValue("s", rkNetStream.GetAccountCharacterSlotDataz(nIndex, nType)); +} + +// SUPPORT_BGM +PyObject* netGetFieldMusicFileName(PyObject* poSelf, PyObject* poArgs) +{ + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + return Py_BuildValue("s", rkNetStream.GetFieldMusicFileName()); +} + +PyObject* netGetFieldMusicVolume(PyObject* poSelf, PyObject* poArgs) +{ + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + return Py_BuildValue("f", rkNetStream.GetFieldMusicVolume()); +} +// END_OF_SUPPORT_BGM + +PyObject* netSetPhaseWindow(PyObject* poSelf, PyObject* poArgs) +{ + int ePhaseWnd; + if (!PyTuple_GetInteger(poArgs, 0, &ePhaseWnd)) + return Py_BuildException(); + + PyObject* poPhaseWnd; + if (!PyTuple_GetObject(poArgs, 1, &poPhaseWnd)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SetPhaseWindow(ePhaseWnd, poPhaseWnd); + return Py_BuildNone(); +} + +PyObject* netClearPhaseWindow(PyObject* poSelf, PyObject* poArgs) +{ + int ePhaseWnd; + if (!PyTuple_GetInteger(poArgs, 0, &ePhaseWnd)) + return Py_BuildException(); + + PyObject* poPhaseWnd; + if (!PyTuple_GetObject(poArgs, 1, &poPhaseWnd)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.ClearPhaseWindow(ePhaseWnd, poPhaseWnd); + return Py_BuildNone(); +} + +PyObject* netSetServerCommandParserWindow(PyObject* poSelf, PyObject* poArgs) +{ + PyObject* poPhaseWnd; + if (!PyTuple_GetObject(poArgs, 0, &poPhaseWnd)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SetServerCommandParserWindow(poPhaseWnd); + return Py_BuildNone(); +} + +PyObject* netSetAccountConnectorHandler(PyObject* poSelf, PyObject* poArgs) +{ + PyObject* poPhaseWnd; + if (!PyTuple_GetObject(poArgs, 0, &poPhaseWnd)) + return Py_BuildException(); + + CAccountConnector & rkAccountConnector = CAccountConnector::Instance(); + rkAccountConnector.SetHandler(poPhaseWnd); + return Py_BuildNone(); +} + +PyObject* netSetHandler(PyObject* poSelf, PyObject* poArgs) +{ + PyObject* poHandler; + + if (!PyTuple_GetObject(poArgs, 0, &poHandler)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SetHandler(poHandler); + return Py_BuildNone(); +} + +PyObject* netSetTCPRecvBufferSize(PyObject* poSelf, PyObject* poArgs) +{ + int bufSize; + if (!PyTuple_GetInteger(poArgs, 0, &bufSize)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SetRecvBufferSize(bufSize); + return Py_BuildNone(); +} + +PyObject* netSetTCPSendBufferSize(PyObject* poSelf, PyObject* poArgs) +{ + int bufSize; + if (!PyTuple_GetInteger(poArgs, 0, &bufSize)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SetSendBufferSize(bufSize); + return Py_BuildNone(); +} + +PyObject* netSetUDPRecvBufferSize(PyObject* poSelf, PyObject* poArgs) +{ + int bufSize; + if (!PyTuple_GetInteger(poArgs, 0, &bufSize)) + return Py_BuildException(); + + //CPythonNetworkDatagram::Instance().SetRecvBufferSize(bufSize); + return Py_BuildNone(); +} + +PyObject* netSetMarkServer(PyObject* poSelf, PyObject* poArgs) +{ + char* szAddr; + if (!PyTuple_GetString(poArgs, 0, &szAddr)) + return Py_BuildException(); + + int port; + if (!PyTuple_GetInteger(poArgs, 1, &port)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SetMarkServer(szAddr, port); + return Py_BuildNone(); +} + +PyObject* netConnectTCP(PyObject* poSelf, PyObject* poArgs) +{ + char* szAddr; + if (!PyTuple_GetString(poArgs, 0, &szAddr)) + return Py_BuildException(); + + int port; + if (!PyTuple_GetInteger(poArgs, 1, &port)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.ConnectLoginServer(szAddr, port); + return Py_BuildNone(); +} + +PyObject* netConnectUDP(PyObject* poSelf, PyObject* poArgs) +{ + char * c_szIP; + if (!PyTuple_GetString(poArgs, 0, &c_szIP)) + return Py_BuildException(); + int iPort; + if (!PyTuple_GetInteger(poArgs, 1, &iPort)) + return Py_BuildException(); + + //CPythonNetworkDatagram::Instance().SetConnection(c_szIP, iPort); + return Py_BuildNone(); +} + +PyObject* netConnectToAccountServer(PyObject* poSelf, PyObject* poArgs) +{ + char* addr; + if (!PyTuple_GetString(poArgs, 0, &addr)) + return Py_BuildException(); + + int port; + if (!PyTuple_GetInteger(poArgs, 1, &port)) + return Py_BuildException(); + + char* account_addr; + if (!PyTuple_GetString(poArgs, 2, &account_addr)) + return Py_BuildException(); + + int account_port; + if (!PyTuple_GetInteger(poArgs, 3, &account_port)) + return Py_BuildException(); + + CAccountConnector & rkAccountConnector = CAccountConnector::Instance(); + rkAccountConnector.Connect(addr, port, account_addr, account_port); + return Py_BuildNone(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +PyObject* netSetLoginInfo(PyObject* poSelf, PyObject* poArgs) +{ + char* szName; + if (!PyTuple_GetString(poArgs, 0, &szName)) + return Py_BuildException(); + + char* szPwd; + if (!PyTuple_GetString(poArgs, 1, &szPwd)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + CAccountConnector & rkAccountConnector = CAccountConnector::Instance(); + rkNetStream.SetLoginInfo(szName, szPwd); + rkAccountConnector.SetLoginInfo(szName, szPwd); + return Py_BuildNone(); +} + +PyObject* netSetOfflinePhase(PyObject* poSelf, PyObject* poArgs) +{ + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SetOffLinePhase(); + return Py_BuildNone(); +} + +PyObject* netSendSelectEmpirePacket(PyObject* poSelf, PyObject* poArgs) +{ + int iEmpireIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iEmpireIndex)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendSelectEmpirePacket(iEmpireIndex); + return Py_BuildNone(); +} + +PyObject* netSendLoginPacket(PyObject* poSelf, PyObject* poArgs) +{ + char* szName; + if (!PyTuple_GetString(poArgs, 0, &szName)) + return Py_BuildException(); + + char* szPwd; + if (!PyTuple_GetString(poArgs, 1, &szPwd)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendLoginPacket(szName, szPwd); + return Py_BuildNone(); +} + +PyObject* netSendChinaMatrixCardPacket(PyObject* poSelf, PyObject* poArgs) +{ + char* szMatrixCardString; + if (!PyTuple_GetString(poArgs, 0, &szMatrixCardString)) + return Py_BuildException(); + + CAccountConnector & rkAccountConnector = CAccountConnector::Instance(); + rkAccountConnector.SendChinaMatrixCardPacket(szMatrixCardString); + return Py_BuildNone(); +} + +PyObject* netSendRunupMatrixCardPacket(PyObject* poSelf, PyObject* poArgs) +{ + char* szMatrixCardString; + if (!PyTuple_GetString(poArgs, 0, &szMatrixCardString)) + return Py_BuildException(); + + CAccountConnector & rkAccountConnector = CAccountConnector::Instance(); + rkAccountConnector.SendRunupMatrixCardPacket(szMatrixCardString); + return Py_BuildNone(); +} + +PyObject* netSendNEWCIBNPasspodAnswerPacket(PyObject* poSelf, PyObject* poArgs) +{ + char* szMatrixCardString; + if (!PyTuple_GetString(poArgs, 0, &szMatrixCardString)) + return Py_BuildException(); + + CAccountConnector & rkAccountConnector = CAccountConnector::Instance(); + rkAccountConnector.SendNEWCIBNPasspodAnswerPacket(szMatrixCardString); + return Py_BuildNone(); +} + + +PyObject* netDirectEnter(PyObject* poSelf, PyObject* poArgs) +{ + int nChrSlot; + if (!PyTuple_GetInteger(poArgs, 0, &nChrSlot)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.ConnectGameServer(nChrSlot); + return Py_BuildNone(); +} + +PyObject* netSendSelectCharacterPacket(PyObject* poSelf, PyObject* poArgs) +{ + int Index; + if (!PyTuple_GetInteger(poArgs, 0, &Index)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendSelectCharacterPacket((BYTE) Index); + return Py_BuildNone(); +} + +PyObject* netSendChangeNamePacket(PyObject* poSelf, PyObject* poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + char* szName; + if (!PyTuple_GetString(poArgs, 1, &szName)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendChangeNamePacket((BYTE)iIndex, szName); + return Py_BuildNone(); +} + +PyObject* netEnableChatInsultFilter(PyObject* poSelf, PyObject* poArgs) +{ + int nEnable; + if (!PyTuple_GetInteger(poArgs, 0, &nEnable)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.EnableChatInsultFilter(nEnable ? true : false); + return Py_BuildNone(); +} + +PyObject* netIsChatInsultIn(PyObject* poSelf, PyObject* poArgs) +{ + char* szMsg; + if (!PyTuple_GetString(poArgs, 0, &szMsg)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + return Py_BuildValue("i", rkNetStream.IsChatInsultIn(szMsg)); +} + + +PyObject* netIsInsultIn(PyObject* poSelf, PyObject* poArgs) +{ + char* szMsg; + if (!PyTuple_GetString(poArgs, 0, &szMsg)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + return Py_BuildValue("i", rkNetStream.IsInsultIn(szMsg)); +} + +PyObject* netSendWhisperPacket(PyObject* poSelf, PyObject* poArgs) +{ + char* szName; + char* szLine; + + if (!PyTuple_GetString(poArgs, 0, &szName)) + return Py_BuildException(); + + if (!PyTuple_GetString(poArgs, 1, &szLine)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendWhisperPacket(szName, szLine); + return Py_BuildNone(); +} + +PyObject* netSendMobileMessagePacket(PyObject* poSelf, PyObject* poArgs) +{ + char* szName; + char* szLine; + if (!PyTuple_GetString(poArgs, 0, &szName)) + return Py_BuildException(); + + if (!PyTuple_GetString(poArgs, 1, &szLine)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendMobileMessagePacket(szName, szLine); + return Py_BuildNone(); +} + +PyObject* netSendCharacterPositionPacket(PyObject* poSelf, PyObject* poArgs) +{ + int iPosition; + if (!PyTuple_GetInteger(poArgs, 0, &iPosition)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendCharacterPositionPacket((BYTE) iPosition); + return Py_BuildNone(); +} + +PyObject* netSendChatPacket(PyObject* poSelf, PyObject* poArgs) +{ + char* szLine; + if (!PyTuple_GetString(poArgs, 0, &szLine)) + return Py_BuildException(); + int iType; + if (!PyTuple_GetInteger(poArgs, 1, &iType)) + { + iType = CHAT_TYPE_TALKING; + } + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendChatPacket(szLine, iType); + return Py_BuildNone(); +} + +PyObject* netSendEmoticon(PyObject* poSelf, PyObject* poArgs) +{ + int eEmoticon; + if (!PyTuple_GetInteger(poArgs, 0, &eEmoticon)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendEmoticon(eEmoticon); + return Py_BuildNone(); +} + +PyObject* netSendCreateCharacterPacket(PyObject* poSelf, PyObject* poArgs) +{ + int index; + if (!PyTuple_GetInteger(poArgs, 0, &index)) + return Py_BuildException(); + + char* name; + if (!PyTuple_GetString(poArgs, 1, &name)) + return Py_BuildException(); + + int job; + if (!PyTuple_GetInteger(poArgs, 2, &job)) + return Py_BuildException(); + + int shape; + if (!PyTuple_GetInteger(poArgs, 3, &shape)) + return Py_BuildException(); + + int stat1; + if (!PyTuple_GetInteger(poArgs, 4, &stat1)) + return Py_BuildException(); + int stat2; + if (!PyTuple_GetInteger(poArgs, 5, &stat2)) + return Py_BuildException(); + int stat3; + if (!PyTuple_GetInteger(poArgs, 6, &stat3)) + return Py_BuildException(); + int stat4; + if (!PyTuple_GetInteger(poArgs, 7, &stat4)) + return Py_BuildException(); + + if (index<0 && index>3) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendCreateCharacterPacket((BYTE) index, name, (BYTE) job, (BYTE) shape, stat1, stat2, stat3, stat4); + return Py_BuildNone(); +} + +PyObject* netSendDestroyCharacterPacket(PyObject* poSelf, PyObject* poArgs) +{ + int index; + if (!PyTuple_GetInteger(poArgs, 0, &index)) + return Py_BuildException(); + + char * szPrivateCode; + if (!PyTuple_GetString(poArgs, 1, &szPrivateCode)) + return Py_BuildException(); + + if (index<0 && index>3) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendDestroyCharacterPacket((BYTE) index, szPrivateCode); + return Py_BuildNone(); +} + +PyObject* netSendEnterGamePacket(PyObject* poSelf, PyObject* poArgs) +{ + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendEnterGame(); + return Py_BuildNone(); +} + +PyObject* netOnClickPacket(PyObject* poSelf, PyObject* poArgs) +{ + int index; + if (!PyTuple_GetInteger(poArgs, 0, &index)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendOnClickPacket(index); + + return Py_BuildNone(); +} + +PyObject* netSendItemUsePacket(PyObject* poSelf, PyObject* poArgs) +{ + TItemPos Cell; + switch (PyTuple_Size(poArgs)) + { + case 1: + if (!PyTuple_GetInteger(poArgs, 0, &Cell.cell)) + return Py_BuildException(); + break; + case 2: + if (!PyTuple_GetByte(poArgs, 0, &Cell.window_type)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 1, &Cell.cell)) + return Py_BuildException(); + break; + default: + return Py_BuildException(); + } + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendItemUsePacket(Cell); + return Py_BuildNone(); +} + +PyObject* netSendItemUseToItemPacket(PyObject* poSelf, PyObject* poArgs) +{ + TItemPos SourceCell; + TItemPos TargetCell; + switch (PyTuple_Size(poArgs)) + { + case 2: + if (!PyTuple_GetInteger(poArgs, 0, &SourceCell.cell)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 1, &TargetCell.cell)) + return Py_BuildException(); + break; + case 4: + if (!PyTuple_GetByte(poArgs, 0, &SourceCell.window_type)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 1, &SourceCell.cell)) + return Py_BuildException(); + + if (!PyTuple_GetByte(poArgs, 2, &TargetCell.window_type)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 3, &TargetCell.cell)) + return Py_BuildException(); + break; + default: + return Py_BuildException(); + } + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendItemUseToItemPacket(SourceCell, TargetCell); + return Py_BuildNone(); +} + +PyObject* netSendItemDropPacket(PyObject* poSelf, PyObject* poArgs) +{ + TItemPos Cell; + switch (PyTuple_Size(poArgs)) + { + case 1: + if (!PyTuple_GetInteger(poArgs, 0, &Cell.cell)) + return Py_BuildException(); + break; + case 2: + if (!PyTuple_GetByte(poArgs, 0, &Cell.window_type)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 1, &Cell.cell)) + return Py_BuildException(); + break; + default: + return Py_BuildException(); + } + + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendItemDropPacket(Cell, 0); + return Py_BuildNone(); +} + +PyObject* netSendItemDropPacketNew(PyObject* poSelf, PyObject* poArgs) +{ + TItemPos Cell; + int count; + switch (PyTuple_Size(poArgs)) + { + case 2: + if (!PyTuple_GetInteger(poArgs, 0, &Cell.cell)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 1, &count)) + return Py_BuildException(); + + break; + case 3: + if (!PyTuple_GetByte(poArgs, 0, &Cell.window_type)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 1, &Cell.cell)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 2, &count)) + return Py_BuildException(); + + break; + default: + return Py_BuildException(); + } + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendItemDropPacketNew(Cell, 0, count); + return Py_BuildNone(); +} + +PyObject* netSendElkDropPacket(PyObject* poSelf, PyObject* poArgs) +{ + int iElk; + if (!PyTuple_GetInteger(poArgs, 0, &iElk)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendItemDropPacket(TItemPos(RESERVED_WINDOW, 0), (DWORD) iElk); + return Py_BuildNone(); +} + +PyObject* netSendGoldDropPacketNew(PyObject* poSelf, PyObject* poArgs) +{ + int iElk; + if (!PyTuple_GetInteger(poArgs, 0, &iElk)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendItemDropPacketNew(TItemPos (RESERVED_WINDOW, 0), (DWORD) iElk, 0); + return Py_BuildNone(); +} + +PyObject* netSendItemMovePacket(PyObject* poSelf, PyObject* poArgs) +{ + TItemPos Cell; + TItemPos ChangeCell; + int num; + + switch (PyTuple_Size(poArgs)) + { + case 3: + if (!PyTuple_GetInteger(poArgs, 0, &Cell.cell)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 1, &ChangeCell.cell)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 2, &num)) + return Py_BuildException(); + break; + case 5: + { + if (!PyTuple_GetByte(poArgs, 0, &Cell.window_type)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 1, &Cell.cell)) + return Py_BuildException(); + if (!PyTuple_GetByte(poArgs, 2, &ChangeCell.window_type)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 3, &ChangeCell.cell)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 4, &num)) + return Py_BuildException(); + } + break; + default: + return Py_BuildException(); + } + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendItemMovePacket(Cell, ChangeCell, (BYTE) num); + return Py_BuildNone(); +} + +PyObject* netSendItemPickUpPacket(PyObject* poSelf, PyObject* poArgs) +{ + int vid; + if (!PyTuple_GetInteger(poArgs, 0, &vid)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendItemPickUpPacket(vid); + return Py_BuildNone(); +} + +PyObject* netSendGiveItemPacket(PyObject* poSelf, PyObject* poArgs) +{ + int iTargetVID; + TItemPos Cell; + int iItemCount; + switch (PyTuple_Size(poArgs)) + { + case 3: + if (!PyTuple_GetInteger(poArgs, 0, &iTargetVID)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 1, &Cell.cell)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 2, &iItemCount)) + return Py_BuildException(); + break; + case 4: + if (!PyTuple_GetInteger(poArgs, 0, &iTargetVID)) + return Py_BuildException(); + if (!PyTuple_GetByte(poArgs, 1, &Cell.window_type)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 2, &Cell.cell)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 3, &iItemCount)) + return Py_BuildException(); + break; + default: + break; + } + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendGiveItemPacket(iTargetVID, Cell, iItemCount); + return Py_BuildNone(); +} + +PyObject* netSendShopEndPacket(PyObject* poSelf, PyObject* poArgs) +{ + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendShopEndPacket(); + return Py_BuildNone(); +} + +PyObject* netSendShopBuyPacket(PyObject* poSelf, PyObject* poArgs) +{ + int iCount; + if (!PyTuple_GetInteger(poArgs, 0, &iCount)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendShopBuyPacket(iCount); + return Py_BuildNone(); +} + +PyObject* netSendShopSellPacket(PyObject* poSelf, PyObject* poArgs) +{ + int iSlotNumber; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotNumber)) + return Py_BuildException(); + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendShopSellPacket(iSlotNumber); + return Py_BuildNone(); +} + +PyObject* netSendShopSellPacketNew(PyObject* poSelf, PyObject* poArgs) +{ + int iSlotNumber; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotNumber)) + return Py_BuildException(); + int iCount; + if (!PyTuple_GetInteger(poArgs, 1, &iCount)) + return Py_BuildException(); + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendShopSellPacketNew(iSlotNumber, iCount); + return Py_BuildNone(); +} + +PyObject* netSendExchangeStartPacket(PyObject* poSelf, PyObject* poArgs) +{ + int vid; + if (!PyTuple_GetInteger(poArgs, 0, &vid)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendExchangeStartPacket(vid); + return Py_BuildNone(); +} + +PyObject* netSendExchangeElkAddPacket(PyObject* poSelf, PyObject* poArgs) +{ + int iElk; + if (!PyTuple_GetInteger(poArgs, 0, &iElk)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendExchangeElkAddPacket(iElk); + return Py_BuildNone(); +} + +PyObject* netSendExchangeItemAddPacket(PyObject* poSelf, PyObject* poArgs) +{ + BYTE bWindowType; + if (!PyTuple_GetInteger(poArgs, 0, &bWindowType)) + return Py_BuildException(); + WORD wSlotIndex; + if (!PyTuple_GetInteger(poArgs, 1, &wSlotIndex)) + return Py_BuildException(); + int iDisplaySlotIndex; + if (!PyTuple_GetInteger(poArgs, 2, &iDisplaySlotIndex)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendExchangeItemAddPacket(TItemPos(bWindowType, wSlotIndex), iDisplaySlotIndex); + return Py_BuildNone(); +} + +PyObject* netSendExchangeItemDelPacket(PyObject* poSelf, PyObject* poArgs) +{ + int pos; + if (!PyTuple_GetInteger(poArgs, 0, &pos)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendExchangeItemDelPacket((BYTE) pos); + return Py_BuildNone(); +} + +PyObject* netSendExchangeAcceptPacket(PyObject* poSelf, PyObject* poArgs) +{ + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendExchangeAcceptPacket(); + return Py_BuildNone(); +} + +PyObject* netSendExchangeExitPacket(PyObject* poSelf, PyObject* poArgs) +{ + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendExchangeExitPacket(); + return Py_BuildNone(); +} + +PyObject* netExitApplication(PyObject* poSelf, PyObject* poArgs) +{ + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.ExitApplication(); + return Py_BuildNone(); +} + +PyObject* netExitGame(PyObject* poSelf, PyObject* poArgs) +{ + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.ExitGame(); + return Py_BuildNone(); +} + +PyObject* netLogOutGame(PyObject* poSelf, PyObject* poArgs) +{ + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.LogOutGame(); + return Py_BuildNone(); +} + +PyObject* netDisconnect(PyObject* poSelf, PyObject* poArgs) +{ + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SetOffLinePhase(); + rkNetStream.Disconnect(); + + return Py_BuildNone(); +} + +PyObject* netIsConnect(PyObject* poSelf, PyObject* poArgs) +{ + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + return Py_BuildValue("i", rkNetStream.IsOnline()); +} + +PyObject* netToggleGameDebugInfo(PyObject* poSelf, PyObject* poArgs) +{ + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.ToggleGameDebugInfo(); + return Py_BuildNone(); +} + +PyObject* netRegisterEmoticonString(PyObject* poSelf, PyObject* poArgs) +{ + char * pcEmoticonString; + if (!PyTuple_GetString(poArgs, 0, &pcEmoticonString)) + return Py_BuildException(); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.RegisterEmoticonString(pcEmoticonString); + return Py_BuildNone(); +} + +PyObject* netSendMessengerAddByVIDPacket(PyObject* poSelf, PyObject* poArgs) +{ + int vid; + if (!PyTuple_GetInteger(poArgs, 0, &vid)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendMessengerAddByVIDPacket(vid); + + return Py_BuildNone(); +} + +PyObject* netSendMessengerAddByNamePacket(PyObject* poSelf, PyObject* poArgs) +{ + char * szName; + if (!PyTuple_GetString(poArgs, 0, &szName)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendMessengerAddByNamePacket(szName); + + return Py_BuildNone(); +} + +PyObject* netSendMessengerRemovePacket(PyObject* poSelf, PyObject* poArgs) +{ + char * szKey; + if (!PyTuple_GetString(poArgs, 0, &szKey)) + return Py_BuildException(); + char * szName; + if (!PyTuple_GetString(poArgs, 1, &szName)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendMessengerRemovePacket(szKey, szName); + + return Py_BuildNone(); +} + +PyObject* netSendPartyInvitePacket(PyObject* poSelf, PyObject* poArgs) +{ + int vid; + if (!PyTuple_GetInteger(poArgs, 0, &vid)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendPartyInvitePacket(vid); + + return Py_BuildNone(); +} + +PyObject* netSendPartyInviteAnswerPacket(PyObject* poSelf, PyObject* poArgs) +{ + int vid; + if (!PyTuple_GetInteger(poArgs, 0, &vid)) + return Py_BuildException(); + int answer; + if (!PyTuple_GetInteger(poArgs, 1, &answer)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendPartyInviteAnswerPacket(vid, answer); + + return Py_BuildNone(); +} + +PyObject* netSendPartyExitPacket(PyObject* poSelf, PyObject* poArgs) +{ + IAbstractPlayer& rPlayer=IAbstractPlayer::GetSingleton(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + + DWORD dwVID = rPlayer.GetMainCharacterIndex(); + DWORD dwPID; + if (rPlayer.PartyMemberVIDToPID(dwVID, &dwPID)) + rns.SendPartyRemovePacket(dwPID); + + return Py_BuildNone(); +} + +PyObject* netSendPartyRemovePacket(PyObject* poSelf, PyObject* poArgs) +{ + int vid; + if (!PyTuple_GetInteger(poArgs, 0, &vid)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendPartyRemovePacket(vid); + + return Py_BuildNone(); +} + +PyObject* netSendPartySetStatePacket(PyObject* poSelf, PyObject* poArgs) +{ + int iVID; + if (!PyTuple_GetInteger(poArgs, 0, &iVID)) + return Py_BuildException(); + int iState; + if (!PyTuple_GetInteger(poArgs, 1, &iState)) + return Py_BuildException(); + int iFlag; + if (!PyTuple_GetInteger(poArgs, 2, &iFlag)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendPartySetStatePacket(iVID, iState, iFlag); + + return Py_BuildNone(); +} + +PyObject* netSendPartyUseSkillPacket(PyObject* poSelf, PyObject* poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BuildException(); + int iVID; + if (!PyTuple_GetInteger(poArgs, 1, &iVID)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendPartyUseSkillPacket(iSkillIndex, iVID); + + return Py_BuildNone(); +} + +PyObject* netSendPartyParameterPacket(PyObject* poSelf, PyObject* poArgs) +{ + int iMode; + if (!PyTuple_GetInteger(poArgs, 0, &iMode)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendPartyParameterPacket(iMode); + + return Py_BuildNone(); +} + +PyObject* netSendSafeboxSaveMoneyPacket(PyObject* poSelf, PyObject* poArgs) +{ + int iMoney; + if (!PyTuple_GetInteger(poArgs, 0, &iMoney)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendSafeBoxMoneyPacket(SAFEBOX_MONEY_STATE_SAVE, iMoney); + + return Py_BuildNone(); +} + +PyObject* netSendSafeboxWithdrawMoneyPacket(PyObject* poSelf, PyObject* poArgs) +{ + int iMoney; + if (!PyTuple_GetInteger(poArgs, 0, &iMoney)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendSafeBoxMoneyPacket(SAFEBOX_MONEY_STATE_WITHDRAW, iMoney); + + return Py_BuildNone(); +} + +PyObject* netSendSafeboxCheckinPacket(PyObject* poSelf, PyObject* poArgs) +{ + TItemPos InventoryPos; + int iSafeBoxPos; + + switch (PyTuple_Size(poArgs)) + { + case 2: + InventoryPos.window_type = INVENTORY; + if (!PyTuple_GetInteger(poArgs, 0, &InventoryPos.cell)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 1, &iSafeBoxPos)) + return Py_BuildException(); + break; + case 3: + if (!PyTuple_GetInteger(poArgs, 0, &InventoryPos.window_type)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 1, &InventoryPos.cell)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 2, &iSafeBoxPos)) + return Py_BuildException(); + break; + + } + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendSafeBoxCheckinPacket(InventoryPos, iSafeBoxPos); + + return Py_BuildNone(); +} + +PyObject* netSendSafeboxCheckoutPacket(PyObject* poSelf, PyObject* poArgs) +{ + int iSafeBoxPos; + TItemPos InventoryPos; + + switch (PyTuple_Size(poArgs)) + { + case 2: + if (!PyTuple_GetInteger(poArgs, 0, &iSafeBoxPos)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 1, &InventoryPos.cell)) + return Py_BuildException(); + break; + case 3: + if (!PyTuple_GetInteger(poArgs, 0, &iSafeBoxPos)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 1, &InventoryPos.window_type)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 2, &InventoryPos.cell)) + return Py_BuildException(); + break; + default: + break; + } + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendSafeBoxCheckoutPacket(iSafeBoxPos, InventoryPos); + + return Py_BuildNone(); +} + +PyObject* netSendSafeboxItemMovePacket(PyObject* poSelf, PyObject* poArgs) +{ + int iSourcePos; + if (!PyTuple_GetInteger(poArgs, 0, &iSourcePos)) + return Py_BuildException(); + int iTargetPos; + if (!PyTuple_GetInteger(poArgs, 1, &iTargetPos)) + return Py_BuildException(); + int iCount; + if (!PyTuple_GetInteger(poArgs, 2, &iCount)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendSafeBoxItemMovePacket(iSourcePos, iTargetPos, iCount); + + return Py_BuildNone(); +} + +PyObject* netSendMallCheckoutPacket(PyObject* poSelf, PyObject* poArgs) +{ + int iMallPos; + TItemPos InventoryPos; + + switch (PyTuple_Size(poArgs)) + { + case 2: + if (!PyTuple_GetInteger(poArgs, 0, &iMallPos)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 1, &InventoryPos.cell)) + return Py_BuildException(); + break; + case 3: + if (!PyTuple_GetInteger(poArgs, 0, &iMallPos)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 1, &InventoryPos.window_type)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 2, &InventoryPos.cell)) + return Py_BuildException(); + break; + default: + return Py_BuildException(); + } + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendMallCheckoutPacket(iMallPos, InventoryPos); + + return Py_BuildNone(); +} + +PyObject* netSendAnswerMakeGuildPacket(PyObject* poSelf, PyObject* poArgs) +{ + char * szName; + if (!PyTuple_GetString(poArgs, 0, &szName)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendAnswerMakeGuildPacket(szName); + + return Py_BuildNone(); +} + +PyObject* netSendQuestInputStringPacket(PyObject* poSelf, PyObject* poArgs) +{ + char * szString; + if (!PyTuple_GetString(poArgs, 0, &szString)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendQuestInputStringPacket(szString); + + return Py_BuildNone(); +} + +PyObject* netSendQuestConfirmPacket(PyObject* poSelf, PyObject* poArgs) +{ + int iAnswer; + if (!PyTuple_GetInteger(poArgs, 0, &iAnswer)) + return Py_BuildException(); + int iPID; + if (!PyTuple_GetInteger(poArgs, 1, &iPID)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendQuestConfirmPacket(iAnswer, iPID); + + return Py_BuildNone(); +} + +PyObject* netSendGuildAddMemberPacket(PyObject* poSelf, PyObject* poArgs) +{ + int iVID; + if (!PyTuple_GetInteger(poArgs, 0, &iVID)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendGuildAddMemberPacket(iVID); + + return Py_BuildNone(); +} + +PyObject* netSendGuildRemoveMemberPacket(PyObject* poSelf, PyObject* poArgs) +{ + char * szKey; + if (!PyTuple_GetString(poArgs, 0, &szKey)) + return Py_BuildException(); + + CPythonGuild::TGuildMemberData * pGuildMemberData; + if (!CPythonGuild::Instance().GetMemberDataPtrByName(szKey, &pGuildMemberData)) + { + TraceError("netSendGuildRemoveMemberPacket(szKey=%s) - Can't Find Guild Member\n", szKey); + return Py_BuildNone(); + } + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendGuildRemoveMemberPacket(pGuildMemberData->dwPID); + + return Py_BuildNone(); +} + +PyObject* netSendGuildChangeGradeNamePacket(PyObject* poSelf, PyObject* poArgs) +{ + int iGradeNumber; + if (!PyTuple_GetInteger(poArgs, 0, &iGradeNumber)) + return Py_BuildException(); + char * szGradeName; + if (!PyTuple_GetString(poArgs, 1, &szGradeName)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendGuildChangeGradeNamePacket(iGradeNumber, szGradeName); + + return Py_BuildNone(); +} + +PyObject* netSendGuildChangeGradeAuthorityPacket(PyObject* poSelf, PyObject* poArgs) +{ + int iGradeNumber; + if (!PyTuple_GetInteger(poArgs, 0, &iGradeNumber)) + return Py_BuildException(); + int iAuthority; + if (!PyTuple_GetInteger(poArgs, 1, &iAuthority)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendGuildChangeGradeAuthorityPacket(iGradeNumber, iAuthority); + + return Py_BuildNone(); +} + +PyObject* netSendGuildOfferPacket(PyObject* poSelf, PyObject* poArgs) +{ + int iExperience; + if (!PyTuple_GetInteger(poArgs, 0, &iExperience)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendGuildOfferPacket(iExperience); + + return Py_BuildNone(); +} + +PyObject* netSnedGuildPostCommentPacket(PyObject* poSelf, PyObject* poArgs) +{ + char * szComment; + if (!PyTuple_GetString(poArgs, 0, &szComment)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendGuildPostCommentPacket(szComment); + + return Py_BuildNone(); +} + +PyObject* netSnedGuildDeleteCommentPacket(PyObject* poSelf, PyObject* poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendGuildDeleteCommentPacket(iIndex); + + return Py_BuildNone(); +} + +PyObject* netSendGuildRefreshCommentsPacket(PyObject* poSelf, PyObject* poArgs) +{ + int iHightestIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iHightestIndex)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendGuildRefreshCommentsPacket(iHightestIndex); + + return Py_BuildNone(); +} + +PyObject* netSendGuildChangeMemberGradePacket(PyObject* poSelf, PyObject* poArgs) +{ + int iPID; + if (!PyTuple_GetInteger(poArgs, 0, &iPID)) + return Py_BuildException(); + int iGradeNumber; + if (!PyTuple_GetInteger(poArgs, 1, &iGradeNumber)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendGuildChangeMemberGradePacket(iPID, iGradeNumber); + + return Py_BuildNone(); +} + +PyObject* netSendGuildUseSkillPacket(PyObject* poSelf, PyObject* poArgs) +{ + int iSkillID; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillID)) + return Py_BuildException(); + int iTargetVID; + if (!PyTuple_GetInteger(poArgs, 1, &iTargetVID)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendGuildUseSkillPacket(iSkillID, iTargetVID); + + return Py_BuildNone(); +} + +PyObject* netSendGuildChangeMemberGeneralPacket(PyObject* poSelf, PyObject* poArgs) +{ + int iPID; + if (!PyTuple_GetInteger(poArgs, 0, &iPID)) + return Py_BuildException(); + int iFlag; + if (!PyTuple_GetInteger(poArgs, 1, &iFlag)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendGuildChangeMemberGeneralPacket(iPID, iFlag); + + return Py_BuildNone(); +} + +PyObject* netSendGuildInviteAnswerPacket(PyObject* poSelf, PyObject* poArgs) +{ + int iGuildID; + if (!PyTuple_GetInteger(poArgs, 0, &iGuildID)) + return Py_BuildException(); + int iAnswer; + if (!PyTuple_GetInteger(poArgs, 1, &iAnswer)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendGuildInviteAnswerPacket(iGuildID, iAnswer); + + return Py_BuildNone(); +} + +PyObject* netSendGuildChargeGSPPacket(PyObject* poSelf, PyObject* poArgs) +{ + int iGSP; + if (!PyTuple_GetInteger(poArgs, 0, &iGSP)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendGuildChargeGSPPacket(iGSP); + + return Py_BuildNone(); +} + +PyObject* netSendGuildDepositMoneyPacket(PyObject* poSelf, PyObject* poArgs) +{ + int iGSP; + if (!PyTuple_GetInteger(poArgs, 0, &iGSP)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendGuildDepositMoneyPacket(iGSP); + + return Py_BuildNone(); +} + +PyObject* netSendGuildWithdrawMoneyPacket(PyObject* poSelf, PyObject* poArgs) +{ + int iGSP; + if (!PyTuple_GetInteger(poArgs, 0, &iGSP)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendGuildWithdrawMoneyPacket(iGSP); + + return Py_BuildNone(); +} + +PyObject* netSendRequestRefineInfoPacket(PyObject* poSelf, PyObject* poArgs) +{ + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + +// CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); +// rns.SendRequestRefineInfoPacket(iSlotIndex); + assert(!"netSendRequestRefineInfoPacket - ̻ ʴ Լ Դϴ"); + + return Py_BuildNone(); +} + +PyObject* netSendRefinePacket(PyObject* poSelf, PyObject* poArgs) +{ + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + int iType; + if (!PyTuple_GetInteger(poArgs, 1, &iType)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendRefinePacket(iSlotIndex, iType); + + return Py_BuildNone(); +} + +PyObject* netSendSelectItemPacket(PyObject* poSelf, PyObject* poArgs) +{ + int iItemPos; + if (!PyTuple_GetInteger(poArgs, 0, &iItemPos)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendSelectItemPacket(iItemPos); + + return Py_BuildNone(); +} + +PyObject* netSetPacketSequenceMode(PyObject* poSelf, PyObject* poArgs) +{ + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + CAccountConnector & rkAccountConnector = CAccountConnector::Instance(); + rns.SetPacketSequenceMode(true); + rkAccountConnector.SetPacketSequenceMode(true); + + return Py_BuildNone(); +} + +PyObject* netSetEmpireLanguageMode(PyObject* poSelf, PyObject* poArgs) +{ + int iMode; + if (!PyTuple_GetInteger(poArgs, 0, &iMode)) + return Py_BuildException(); + + //CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + gs_bEmpireLanuageEnable = iMode; + + return Py_BuildNone(); +} + +PyObject* netSetSkillGroupFake(PyObject* poSelf, PyObject* poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.__TEST_SetSkillGroupFake(iIndex); + + return Py_BuildNone(); +} + +#include "GuildMarkUploader.h" +#include "GuildMarkDownloader.h" + +PyObject* netSendGuildSymbol(PyObject* poSelf, PyObject* poArgs) +{ + char * szIP; + if (!PyTuple_GetString(poArgs, 0, &szIP)) + return Py_BuildException(); + int iPort; + if (!PyTuple_GetInteger(poArgs, 1, &iPort)) + return Py_BuildException(); + char * szFileName; + if (!PyTuple_GetString(poArgs, 2, &szFileName)) + return Py_BuildException(); + int iGuildID; + if (!PyTuple_GetInteger(poArgs, 3, &iGuildID)) + return Py_BuildException(); + + CNetworkAddress kAddress; + kAddress.Set(szIP, iPort); + + UINT uiError; + + CGuildMarkUploader& rkGuildMarkUploader=CGuildMarkUploader::Instance(); + if (!rkGuildMarkUploader.ConnectToSendSymbol(kAddress, 0, 0, iGuildID, szFileName, &uiError)) + { + assert(!"Failed connecting to send symbol"); + } + + return Py_BuildNone(); +} + +PyObject* netDisconnectUploader(PyObject* poSelf, PyObject* poArgs) +{ + CGuildMarkUploader& rkGuildMarkUploader=CGuildMarkUploader::Instance(); + rkGuildMarkUploader.Disconnect(); + return Py_BuildNone(); +} + +PyObject* netRecvGuildSymbol(PyObject* poSelf, PyObject* poArgs) +{ + char * szIP; + if (!PyTuple_GetString(poArgs, 0, &szIP)) + return Py_BuildException(); + int iPort; + if (!PyTuple_GetInteger(poArgs, 1, &iPort)) + return Py_BuildException(); + int iGuildID; + if (!PyTuple_GetInteger(poArgs, 2, &iGuildID)) + return Py_BuildException(); + + CNetworkAddress kAddress; + kAddress.Set(szIP, iPort); + + std::vector kVec_dwGuildID; + kVec_dwGuildID.clear(); + kVec_dwGuildID.push_back(iGuildID); + + CGuildMarkDownloader& rkGuildMarkDownloader=CGuildMarkDownloader::Instance(); + if (!rkGuildMarkDownloader.ConnectToRecvSymbol(kAddress, 0, 0, kVec_dwGuildID)) + { + assert(!"Failed connecting to recv symbol"); + } + + return Py_BuildNone(); +} + +PyObject* netRegisterErrorLog(PyObject* poSelf, PyObject* poArgs) +{ + char * szLog; + if (!PyTuple_GetString(poArgs, 0, &szLog)) + return Py_BuildException(); + + return Py_BuildNone(); +} + +void initnet() +{ + static PyMethodDef s_methods[] = + { + { "GetBettingGuildWarValue", netGetBettingGuildWarValue, METH_VARARGS }, + { "EnableChatInsultFilter", netEnableChatInsultFilter, METH_VARARGS }, + { "SetServerInfo", netSetServerInfo, METH_VARARGS }, + { "GetServerInfo", netGetServerInfo, METH_VARARGS }, + { "PreserveServerCommand", netPreserveServerCommand, METH_VARARGS }, + { "GetPreservedServerCommand", netGetPreservedServerCommand, METH_VARARGS }, + + { "StartGame", netStartGame, METH_VARARGS }, + { "Warp", netWarp, METH_VARARGS }, + { "IsTest", netIsTest, METH_VARARGS }, + { "SetMarkServer", netSetMarkServer, METH_VARARGS }, + { "IsChatInsultIn", netIsChatInsultIn, METH_VARARGS }, + { "IsInsultIn", netIsInsultIn, METH_VARARGS }, + { "LoadInsultList", netLoadInsultList, METH_VARARGS }, + { "UploadMark", netUploadMark, METH_VARARGS }, + { "UploadSymbol", netUploadSymbol, METH_VARARGS }, + { "GetGuildID", netGetGuildID, METH_VARARGS }, + { "GetEmpireID", netGetEmpireID, METH_VARARGS }, + { "GetMainActorVID", netGetMainActorVID, METH_VARARGS }, + { "GetMainActorRace", netGetMainActorRace, METH_VARARGS }, + { "GetMainActorEmpire", netGetMainActorEmpire, METH_VARARGS }, + { "GetMainActorSkillGroup", netGetMainActorSkillGroup, METH_VARARGS }, + { "GetAccountCharacterSlotDataInteger", netGetAccountCharacterSlotDataInteger, METH_VARARGS }, + { "GetAccountCharacterSlotDataString", netGetAccountCharacterSlotDataString, METH_VARARGS }, + + // FIELD_MUSIC + { "GetFieldMusicFileName", netGetFieldMusicFileName, METH_VARARGS }, + { "GetFieldMusicVolume", netGetFieldMusicVolume, METH_VARARGS }, + // END_OF_FIELD_MUSIC + + { "ToggleGameDebugInfo", netToggleGameDebugInfo, METH_VARARGS }, + { "SetLoginInfo", netSetLoginInfo, METH_VARARGS }, + { "SetPhaseWindow", netSetPhaseWindow, METH_VARARGS }, + { "ClearPhaseWindow", netClearPhaseWindow, METH_VARARGS }, + { "SetServerCommandParserWindow", netSetServerCommandParserWindow, METH_VARARGS }, + { "SetAccountConnectorHandler", netSetAccountConnectorHandler, METH_VARARGS }, + { "SetHandler", netSetHandler, METH_VARARGS }, + { "SetTCPRecvBufferSize", netSetTCPRecvBufferSize, METH_VARARGS }, + { "SetTCPSendBufferSize", netSetTCPSendBufferSize, METH_VARARGS }, + { "SetUDPRecvBufferSize", netSetUDPRecvBufferSize, METH_VARARGS }, + { "DirectEnter", netDirectEnter, METH_VARARGS }, + + { "LogOutGame", netLogOutGame, METH_VARARGS }, + { "ExitGame", netExitGame, METH_VARARGS }, + { "ExitApplication", netExitApplication, METH_VARARGS }, + { "ConnectTCP", netConnectTCP, METH_VARARGS }, + { "ConnectUDP", netConnectUDP, METH_VARARGS }, + { "ConnectToAccountServer", netConnectToAccountServer, METH_VARARGS }, + + { "SendLoginPacket", netSendLoginPacket, METH_VARARGS }, + { "SendChinaMatrixCardPacket", netSendChinaMatrixCardPacket, METH_VARARGS }, + { "SendRunupMatrixCardPacket", netSendRunupMatrixCardPacket, METH_VARARGS }, + { "SendNEWCIBNPasspodAnswerPacket", netSendNEWCIBNPasspodAnswerPacket, METH_VARARGS }, + { "SendSelectEmpirePacket", netSendSelectEmpirePacket, METH_VARARGS }, + { "SendSelectCharacterPacket", netSendSelectCharacterPacket, METH_VARARGS }, + { "SendChangeNamePacket", netSendChangeNamePacket, METH_VARARGS }, + { "SendCreateCharacterPacket", netSendCreateCharacterPacket, METH_VARARGS }, + { "SendDestroyCharacterPacket", netSendDestroyCharacterPacket, METH_VARARGS }, + { "SendEnterGamePacket", netSendEnterGamePacket, METH_VARARGS }, + + { "SendItemUsePacket", netSendItemUsePacket, METH_VARARGS }, + { "SendItemUseToItemPacket", netSendItemUseToItemPacket, METH_VARARGS }, + { "SendItemDropPacket", netSendItemDropPacket, METH_VARARGS }, + { "SendItemDropPacketNew", netSendItemDropPacketNew, METH_VARARGS }, + { "SendElkDropPacket", netSendElkDropPacket, METH_VARARGS }, + { "SendGoldDropPacketNew", netSendGoldDropPacketNew, METH_VARARGS }, + { "SendItemMovePacket", netSendItemMovePacket, METH_VARARGS }, + { "SendItemPickUpPacket", netSendItemPickUpPacket, METH_VARARGS }, + { "SendGiveItemPacket", netSendGiveItemPacket, METH_VARARGS }, + + { "SetOfflinePhase", netSetOfflinePhase, METH_VARARGS }, + { "Disconnect", netDisconnect, METH_VARARGS }, + { "IsConnect", netIsConnect, METH_VARARGS }, + + { "SendChatPacket", netSendChatPacket, METH_VARARGS }, + { "SendEmoticon", netSendEmoticon, METH_VARARGS }, + { "SendWhisperPacket", netSendWhisperPacket, METH_VARARGS }, + { "SendMobileMessagePacket", netSendMobileMessagePacket, METH_VARARGS }, + + { "SendCharacterPositionPacket", netSendCharacterPositionPacket, METH_VARARGS }, + + { "SendShopEndPacket", netSendShopEndPacket, METH_VARARGS }, + { "SendShopBuyPacket", netSendShopBuyPacket, METH_VARARGS }, + { "SendShopSellPacket", netSendShopSellPacket, METH_VARARGS }, + { "SendShopSellPacketNew", netSendShopSellPacketNew, METH_VARARGS }, + + { "SendExchangeStartPacket", netSendExchangeStartPacket, METH_VARARGS }, + { "SendExchangeItemAddPacket", netSendExchangeItemAddPacket, METH_VARARGS }, + { "SendExchangeItemDelPacket", netSendExchangeItemDelPacket, METH_VARARGS }, + { "SendExchangeElkAddPacket", netSendExchangeElkAddPacket, METH_VARARGS }, + { "SendExchangeAcceptPacket", netSendExchangeAcceptPacket, METH_VARARGS }, + { "SendExchangeExitPacket", netSendExchangeExitPacket, METH_VARARGS }, + + { "SendOnClickPacket", netOnClickPacket, METH_VARARGS }, + + // Emoticon String + { "RegisterEmoticonString", netRegisterEmoticonString, METH_VARARGS }, + + // Messenger + { "SendMessengerAddByVIDPacket", netSendMessengerAddByVIDPacket, METH_VARARGS }, + { "SendMessengerAddByNamePacket", netSendMessengerAddByNamePacket, METH_VARARGS }, + { "SendMessengerRemovePacket", netSendMessengerRemovePacket, METH_VARARGS }, + + // Party + { "SendPartyInvitePacket", netSendPartyInvitePacket, METH_VARARGS }, + { "SendPartyInviteAnswerPacket", netSendPartyInviteAnswerPacket, METH_VARARGS }, + { "SendPartyExitPacket", netSendPartyExitPacket, METH_VARARGS }, + { "SendPartyRemovePacket", netSendPartyRemovePacket, METH_VARARGS }, + { "SendPartySetStatePacket", netSendPartySetStatePacket, METH_VARARGS }, + { "SendPartyUseSkillPacket", netSendPartyUseSkillPacket, METH_VARARGS }, + { "SendPartyParameterPacket", netSendPartyParameterPacket, METH_VARARGS }, + + // Safebox + { "SendSafeboxSaveMoneyPacket", netSendSafeboxSaveMoneyPacket, METH_VARARGS }, + { "SendSafeboxWithdrawMoneyPacket", netSendSafeboxWithdrawMoneyPacket, METH_VARARGS }, + { "SendSafeboxCheckinPacket", netSendSafeboxCheckinPacket, METH_VARARGS }, + { "SendSafeboxCheckoutPacket", netSendSafeboxCheckoutPacket, METH_VARARGS }, + { "SendSafeboxItemMovePacket", netSendSafeboxItemMovePacket, METH_VARARGS }, + + // Mall + { "SendMallCheckoutPacket", netSendMallCheckoutPacket, METH_VARARGS }, + + // Guild + { "SendAnswerMakeGuildPacket", netSendAnswerMakeGuildPacket, METH_VARARGS }, + { "SendQuestInputStringPacket", netSendQuestInputStringPacket, METH_VARARGS }, + { "SendQuestConfirmPacket", netSendQuestConfirmPacket, METH_VARARGS }, + { "SendGuildAddMemberPacket", netSendGuildAddMemberPacket, METH_VARARGS }, + { "SendGuildRemoveMemberPacket", netSendGuildRemoveMemberPacket, METH_VARARGS }, + { "SendGuildChangeGradeNamePacket", netSendGuildChangeGradeNamePacket, METH_VARARGS }, + { "SendGuildChangeGradeAuthorityPacket", netSendGuildChangeGradeAuthorityPacket, METH_VARARGS }, + { "SendGuildOfferPacket", netSendGuildOfferPacket, METH_VARARGS }, + { "SendGuildPostCommentPacket", netSnedGuildPostCommentPacket, METH_VARARGS }, + { "SendGuildDeleteCommentPacket", netSnedGuildDeleteCommentPacket, METH_VARARGS }, + { "SendGuildRefreshCommentsPacket", netSendGuildRefreshCommentsPacket, METH_VARARGS }, + { "SendGuildChangeMemberGradePacket", netSendGuildChangeMemberGradePacket, METH_VARARGS }, + { "SendGuildUseSkillPacket", netSendGuildUseSkillPacket, METH_VARARGS }, + { "SendGuildChangeMemberGeneralPacket", netSendGuildChangeMemberGeneralPacket, METH_VARARGS }, + { "SendGuildInviteAnswerPacket", netSendGuildInviteAnswerPacket, METH_VARARGS }, + { "SendGuildChargeGSPPacket", netSendGuildChargeGSPPacket, METH_VARARGS }, + { "SendGuildDepositMoneyPacket", netSendGuildDepositMoneyPacket, METH_VARARGS }, + { "SendGuildWithdrawMoneyPacket", netSendGuildWithdrawMoneyPacket, METH_VARARGS }, + + // Refine + { "SendRequestRefineInfoPacket", netSendRequestRefineInfoPacket, METH_VARARGS }, + { "SendRefinePacket", netSendRefinePacket, METH_VARARGS }, + { "SendSelectItemPacket", netSendSelectItemPacket, METH_VARARGS }, + + // SYSTEM + { "SetPacketSequenceMode", netSetPacketSequenceMode, METH_VARARGS }, + { "SetEmpireLanguageMode", netSetEmpireLanguageMode, METH_VARARGS }, + + // For Test + { "SetSkillGroupFake", netSetSkillGroupFake, METH_VARARGS }, + + // Guild Symbol + { "SendGuildSymbol", netSendGuildSymbol, METH_VARARGS }, + { "DisconnectUploader", netDisconnectUploader, METH_VARARGS }, + { "RecvGuildSymbol", netRecvGuildSymbol, METH_VARARGS }, + + // Log + { "RegisterErrorLog", netRegisterErrorLog, METH_VARARGS }, + + { NULL, NULL, NULL }, + }; + + PyObject* poModule = Py_InitModule("net", s_methods); + + PyModule_AddIntConstant(poModule, "ERROR_NONE", CPythonNetworkStream::ERROR_NONE); + PyModule_AddIntConstant(poModule, "ERROR_CONNECT_MARK_SERVER", CPythonNetworkStream::ERROR_CONNECT_MARK_SERVER); + PyModule_AddIntConstant(poModule, "ERROR_LOAD_MARK", CPythonNetworkStream::ERROR_LOAD_MARK); + PyModule_AddIntConstant(poModule, "ERROR_MARK_WIDTH", CPythonNetworkStream::ERROR_MARK_WIDTH); + PyModule_AddIntConstant(poModule, "ERROR_MARK_HEIGHT", CPythonNetworkStream::ERROR_MARK_HEIGHT); + + // MARK_BUG_FIX + PyModule_AddIntConstant(poModule, "ERROR_MARK_UPLOAD_NEED_RECONNECT", CPythonNetworkStream::ERROR_MARK_UPLOAD_NEED_RECONNECT); + PyModule_AddIntConstant(poModule, "ERROR_MARK_CHECK_NEED_RECONNECT", CPythonNetworkStream::ERROR_MARK_CHECK_NEED_RECONNECT); + // END_OF_MARK_BUG_FIX + + PyModule_AddIntConstant(poModule, "PHASE_WINDOW_LOGIN", CPythonNetworkStream::PHASE_WINDOW_LOGIN); + PyModule_AddIntConstant(poModule, "PHASE_WINDOW_SELECT", CPythonNetworkStream::PHASE_WINDOW_SELECT); + PyModule_AddIntConstant(poModule, "PHASE_WINDOW_CREATE", CPythonNetworkStream::PHASE_WINDOW_CREATE); + PyModule_AddIntConstant(poModule, "PHASE_WINDOW_LOAD", CPythonNetworkStream::PHASE_WINDOW_LOAD); + PyModule_AddIntConstant(poModule, "PHASE_WINDOW_GAME", CPythonNetworkStream::PHASE_WINDOW_GAME); + PyModule_AddIntConstant(poModule, "PHASE_WINDOW_EMPIRE", CPythonNetworkStream::PHASE_WINDOW_EMPIRE); + PyModule_AddIntConstant(poModule, "PHASE_WINDOW_LOGO", CPythonNetworkStream::PHASE_WINDOW_LOGO); + + PyModule_AddIntConstant(poModule, "ACCOUNT_CHARACTER_SLOT_ID", CPythonNetworkStream::ACCOUNT_CHARACTER_SLOT_ID); + PyModule_AddIntConstant(poModule, "ACCOUNT_CHARACTER_SLOT_NAME", CPythonNetworkStream::ACCOUNT_CHARACTER_SLOT_NAME); + PyModule_AddIntConstant(poModule, "ACCOUNT_CHARACTER_SLOT_RACE", CPythonNetworkStream::ACCOUNT_CHARACTER_SLOT_RACE); + PyModule_AddIntConstant(poModule, "ACCOUNT_CHARACTER_SLOT_LEVEL", CPythonNetworkStream::ACCOUNT_CHARACTER_SLOT_LEVEL); + PyModule_AddIntConstant(poModule, "ACCOUNT_CHARACTER_SLOT_STR", CPythonNetworkStream::ACCOUNT_CHARACTER_SLOT_STR); + PyModule_AddIntConstant(poModule, "ACCOUNT_CHARACTER_SLOT_DEX", CPythonNetworkStream::ACCOUNT_CHARACTER_SLOT_DEX); + PyModule_AddIntConstant(poModule, "ACCOUNT_CHARACTER_SLOT_INT", CPythonNetworkStream::ACCOUNT_CHARACTER_SLOT_INT); + PyModule_AddIntConstant(poModule, "ACCOUNT_CHARACTER_SLOT_HTH", CPythonNetworkStream::ACCOUNT_CHARACTER_SLOT_HTH); + PyModule_AddIntConstant(poModule, "ACCOUNT_CHARACTER_SLOT_PLAYTIME", CPythonNetworkStream::ACCOUNT_CHARACTER_SLOT_PLAYTIME); + PyModule_AddIntConstant(poModule, "ACCOUNT_CHARACTER_SLOT_FORM", CPythonNetworkStream::ACCOUNT_CHARACTER_SLOT_FORM); + PyModule_AddIntConstant(poModule, "ACCOUNT_CHARACTER_SLOT_ADDR", CPythonNetworkStream::ACCOUNT_CHARACTER_SLOT_ADDR); + PyModule_AddIntConstant(poModule, "ACCOUNT_CHARACTER_SLOT_PORT", CPythonNetworkStream::ACCOUNT_CHARACTER_SLOT_PORT); + PyModule_AddIntConstant(poModule, "ACCOUNT_CHARACTER_SLOT_GUILD_ID", CPythonNetworkStream::ACCOUNT_CHARACTER_SLOT_GUILD_ID); + PyModule_AddIntConstant(poModule, "ACCOUNT_CHARACTER_SLOT_GUILD_NAME", CPythonNetworkStream::ACCOUNT_CHARACTER_SLOT_GUILD_NAME); + PyModule_AddIntConstant(poModule, "ACCOUNT_CHARACTER_SLOT_CHANGE_NAME_FLAG", CPythonNetworkStream::ACCOUNT_CHARACTER_SLOT_CHANGE_NAME_FLAG); + PyModule_AddIntConstant(poModule, "ACCOUNT_CHARACTER_SLOT_HAIR", CPythonNetworkStream::ACCOUNT_CHARACTER_SLOT_HAIR); + + PyModule_AddIntConstant(poModule, "SERVER_COMMAND_LOG_OUT", CPythonNetworkStream::SERVER_COMMAND_LOG_OUT); + PyModule_AddIntConstant(poModule, "SERVER_COMMAND_RETURN_TO_SELECT_CHARACTER", CPythonNetworkStream::SERVER_COMMAND_RETURN_TO_SELECT_CHARACTER); + PyModule_AddIntConstant(poModule, "SERVER_COMMAND_QUIT", CPythonNetworkStream::SERVER_COMMAND_QUIT); + + PyModule_AddIntConstant(poModule, "EMPIRE_A", 1); + PyModule_AddIntConstant(poModule, "EMPIRE_B", 2); + PyModule_AddIntConstant(poModule, "EMPIRE_C", 3); + PyModule_AddIntConstant(poModule, "DS_SUB_HEADER_REFINE_FAIL", DS_SUB_HEADER_REFINE_FAIL); + PyModule_AddIntConstant(poModule, "DS_SUB_HEADER_REFINE_FAIL_MAX_REFINE", DS_SUB_HEADER_REFINE_FAIL_MAX_REFINE); + PyModule_AddIntConstant(poModule, "DS_SUB_HEADER_REFINE_FAIL_INVALID_MATERIAL", DS_SUB_HEADER_REFINE_FAIL_INVALID_MATERIAL); + PyModule_AddIntConstant(poModule, "DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MONEY", DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MONEY); + PyModule_AddIntConstant(poModule, "DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MATERIAL", DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MATERIAL); + PyModule_AddIntConstant(poModule, "DS_SUB_HEADER_REFINE_FAIL_TOO_MUCH_MATERIAL", DS_SUB_HEADER_REFINE_FAIL_TOO_MUCH_MATERIAL); + PyModule_AddIntConstant(poModule, "DS_SUB_HEADER_REFINE_SUCCEED", DS_SUB_HEADER_REFINE_SUCCEED); +} diff --git a/source/UserInterface/PythonNetworkStreamPhaseGame.cpp b/source/UserInterface/PythonNetworkStreamPhaseGame.cpp new file mode 100644 index 0000000..472788e --- /dev/null +++ b/source/UserInterface/PythonNetworkStreamPhaseGame.cpp @@ -0,0 +1,4508 @@ +#include "StdAfx.h" +#include "PythonNetworkStream.h" +#include "Packet.h" + +#include "PythonGuild.h" +#include "PythonCharacterManager.h" +#include "PythonPlayer.h" +#include "PythonBackground.h" +#include "PythonMiniMap.h" +#include "PythonTextTail.h" +#include "PythonItem.h" +#include "PythonChat.h" +#include "PythonShop.h" +#include "PythonExchange.h" +#include "PythonQuest.h" +#include "PythonEventManager.h" +#include "PythonMessenger.h" +#include "PythonApplication.h" + +#include "../EterPack/EterPackManager.h" +#include "../gamelib/ItemManager.h" + +#include "AbstractApplication.h" +#include "AbstractCharacterManager.h" +#include "InstanceBase.h" + +#include "ProcessCRC.h" + +BOOL gs_bEmpireLanuageEnable = TRUE; + +void CPythonNetworkStream::__RefreshAlignmentWindow() +{ + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshAlignment", Py_BuildValue("()")); +} + +void CPythonNetworkStream::__RefreshTargetBoardByVID(DWORD dwVID) +{ + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshTargetBoardByVID", Py_BuildValue("(i)", dwVID)); +} + +void CPythonNetworkStream::__RefreshTargetBoardByName(const char * c_szName) +{ + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshTargetBoardByName", Py_BuildValue("(s)", c_szName)); +} + +void CPythonNetworkStream::__RefreshTargetBoard() +{ + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshTargetBoard", Py_BuildValue("()")); +} + +void CPythonNetworkStream::__RefreshGuildWindowGradePage() +{ + m_isRefreshGuildWndGradePage=true; +} + +void CPythonNetworkStream::__RefreshGuildWindowSkillPage() +{ + m_isRefreshGuildWndSkillPage=true; +} + +void CPythonNetworkStream::__RefreshGuildWindowMemberPageGradeComboBox() +{ + m_isRefreshGuildWndMemberPageGradeComboBox=true; +} + +void CPythonNetworkStream::__RefreshGuildWindowMemberPage() +{ + m_isRefreshGuildWndMemberPage=true; +} + +void CPythonNetworkStream::__RefreshGuildWindowBoardPage() +{ + m_isRefreshGuildWndBoardPage=true; +} + +void CPythonNetworkStream::__RefreshGuildWindowInfoPage() +{ + m_isRefreshGuildWndInfoPage=true; +} + +void CPythonNetworkStream::__RefreshMessengerWindow() +{ + m_isRefreshMessengerWnd=true; +} + +void CPythonNetworkStream::__RefreshSafeboxWindow() +{ + m_isRefreshSafeboxWnd=true; +} + +void CPythonNetworkStream::__RefreshMallWindow() +{ + m_isRefreshMallWnd=true; +} + +void CPythonNetworkStream::__RefreshSkillWindow() +{ + m_isRefreshSkillWnd=true; +} + +void CPythonNetworkStream::__RefreshExchangeWindow() +{ + m_isRefreshExchangeWnd=true; +} + +void CPythonNetworkStream::__RefreshStatus() +{ + m_isRefreshStatus=true; +} + +void CPythonNetworkStream::__RefreshCharacterWindow() +{ + m_isRefreshCharacterWnd=true; +} + +void CPythonNetworkStream::__RefreshInventoryWindow() +{ + m_isRefreshInventoryWnd=true; +} + +void CPythonNetworkStream::__RefreshEquipmentWindow() +{ + m_isRefreshEquipmentWnd=true; +} + +void CPythonNetworkStream::__SetGuildID(DWORD id) +{ + if (m_dwGuildID != id) + { + m_dwGuildID = id; + IAbstractPlayer& rkPlayer = IAbstractPlayer::GetSingleton(); + + for (int i = 0; i < PLAYER_PER_ACCOUNT4; ++i) + if (!strncmp(m_akSimplePlayerInfo[i].szName, rkPlayer.GetName(), CHARACTER_NAME_MAX_LEN)) + { + m_adwGuildID[i] = id; + + std::string guildName; + if (CPythonGuild::Instance().GetGuildName(id, &guildName)) + { + m_astrGuildName[i] = guildName; + } + else + { + m_astrGuildName[i] = ""; + } + } + } +} + +struct PERF_PacketInfo +{ + DWORD dwCount; + DWORD dwTime; + + PERF_PacketInfo() + { + dwCount=0; + dwTime=0; + } +}; + + +#ifdef __PERFORMANCE_CHECK__ + +class PERF_PacketTimeAnalyzer +{ + public: + ~PERF_PacketTimeAnalyzer() + { + FILE* fp=fopen("perf_dispatch_packet_result.txt", "w"); + + for (std::map::iterator i=m_kMap_kPacketInfo.begin(); i!=m_kMap_kPacketInfo.end(); ++i) + { + if (i->second.dwTime>0) + fprintf(fp, "header %d: count %d, time %d, tpc %d\n", i->first, i->second.dwCount, i->second.dwTime, i->second.dwTime/i->second.dwCount); + } + fclose(fp); + } + + public: + std::map m_kMap_kPacketInfo; +}; + +PERF_PacketTimeAnalyzer gs_kPacketTimeAnalyzer; + +#endif + +// Game Phase --------------------------------------------------------------------------- +void CPythonNetworkStream::GamePhase() +{ + if (!m_kQue_stHack.empty()) + { + __SendHack(m_kQue_stHack.front().c_str()); + m_kQue_stHack.pop_front(); + } + + TPacketHeader header = 0; + bool ret = true; + +#ifdef __PERFORMANCE_CHECK__ + DWORD timeBeginDispatch=timeGetTime(); + + static std::map kMap_kPacketInfo; + kMap_kPacketInfo.clear(); +#endif + + const DWORD MAX_RECV_COUNT = 4; + const DWORD SAFE_RECV_BUFSIZE = 8192; + DWORD dwRecvCount = 0; + + while (ret) + { + if(dwRecvCount++ >= MAX_RECV_COUNT-1 && GetRecvBufferSize() < SAFE_RECV_BUFSIZE + && m_strPhase == "Game") //phase_game ƴϾ 찡 ִ. + break; + + if (!CheckPacket(&header)) + break; + +#ifdef __PERFORMANCE_CHECK__ + DWORD timeBeginPacket=timeGetTime(); +#endif + + switch (header) + { + case HEADER_GC_OBSERVER_ADD: + ret = RecvObserverAddPacket(); + break; + case HEADER_GC_OBSERVER_REMOVE: + ret = RecvObserverRemovePacket(); + break; + case HEADER_GC_OBSERVER_MOVE: + ret = RecvObserverMovePacket(); + break; + case HEADER_GC_WARP: + ret = RecvWarpPacket(); + break; + + case HEADER_GC_PHASE: + ret = RecvPhasePacket(); + return; // ߿ Phase ٲ ϴ GamePhase Ż - [levites] + break; + + case HEADER_GC_PVP: + ret = RecvPVPPacket(); + break; + + case HEADER_GC_DUEL_START: + ret = RecvDuelStartPacket(); + break; + + case HEADER_GC_CHARACTER_ADD: + ret = RecvCharacterAppendPacket(); + break; + + case HEADER_GC_CHAR_ADDITIONAL_INFO: + ret = RecvCharacterAdditionalInfo(); + break; + + case HEADER_GC_CHARACTER_ADD2: + ret = RecvCharacterAppendPacketNew(); + break; + + case HEADER_GC_CHARACTER_UPDATE: + ret = RecvCharacterUpdatePacket(); + break; + + case HEADER_GC_CHARACTER_UPDATE2: + ret = RecvCharacterUpdatePacketNew(); + break; + + case HEADER_GC_CHARACTER_DEL: + ret = RecvCharacterDeletePacket(); + break; + + case HEADER_GC_CHAT: + ret = RecvChatPacket(); + break; + + case HEADER_GC_SYNC_POSITION: + ret = RecvSyncPositionPacket(); + break; + + case HEADER_GC_OWNERSHIP: + ret = RecvOwnerShipPacket(); + break; + + case HEADER_GC_WHISPER: + ret = RecvWhisperPacket(); + break; + + case HEADER_GC_CHARACTER_MOVE: + ret = RecvCharacterMovePacket(); + break; + + // Position + case HEADER_GC_CHARACTER_POSITION: + ret = RecvCharacterPositionPacket(); + break; + + // Battle Packet + case HEADER_GC_STUN: + ret = RecvStunPacket(); + break; + + case HEADER_GC_DEAD: + ret = RecvDeadPacket(); + break; + + case HEADER_GC_PLAYER_POINT_CHANGE: + ret = RecvPointChange(); + break; + + // item packet. + case HEADER_GC_ITEM_SET: + ret = RecvItemSetPacket(); + break; + + case HEADER_GC_ITEM_SET2: + ret = RecvItemSetPacket2(); + break; + + case HEADER_GC_ITEM_USE: + ret = RecvItemUsePacket(); + break; + + case HEADER_GC_ITEM_UPDATE: + ret = RecvItemUpdatePacket(); + break; + + case HEADER_GC_ITEM_GROUND_ADD: + ret = RecvItemGroundAddPacket(); + break; + + case HEADER_GC_ITEM_GROUND_DEL: + ret = RecvItemGroundDelPacket(); + break; + + case HEADER_GC_ITEM_OWNERSHIP: + ret = RecvItemOwnership(); + break; + + case HEADER_GC_QUICKSLOT_ADD: + ret = RecvQuickSlotAddPacket(); + break; + + case HEADER_GC_QUICKSLOT_DEL: + ret = RecvQuickSlotDelPacket(); + break; + + case HEADER_GC_QUICKSLOT_SWAP: + ret = RecvQuickSlotMovePacket(); + break; + + case HEADER_GC_MOTION: + ret = RecvMotionPacket(); + break; + + case HEADER_GC_SHOP: + ret = RecvShopPacket(); + break; + + case HEADER_GC_SHOP_SIGN: + ret = RecvShopSignPacket(); + break; + + case HEADER_GC_EXCHANGE: + ret = RecvExchangePacket(); + break; + + case HEADER_GC_QUEST_INFO: + ret = RecvQuestInfoPacket(); + break; + + case HEADER_GC_REQUEST_MAKE_GUILD: + ret = RecvRequestMakeGuild(); + break; + + case HEADER_GC_PING: + ret = RecvPingPacket(); + break; + + case HEADER_GC_SCRIPT: + ret = RecvScriptPacket(); + break; + + case HEADER_GC_QUEST_CONFIRM: + ret = RecvQuestConfirmPacket(); + break; + + case HEADER_GC_TARGET: + ret = RecvTargetPacket(); + break; + + case HEADER_GC_DAMAGE_INFO: + ret = RecvDamageInfoPacket(); + break; + + case HEADER_GC_MOUNT: + ret = RecvMountPacket(); + break; + + case HEADER_GC_CHANGE_SPEED: + ret = RecvChangeSpeedPacket(); + break; + + case HEADER_GC_PLAYER_POINTS: + ret = __RecvPlayerPoints(); + break; + + case HEADER_GC_CREATE_FLY: + ret = RecvCreateFlyPacket(); + break; + + case HEADER_GC_FLY_TARGETING: + ret = RecvFlyTargetingPacket(); + break; + + case HEADER_GC_ADD_FLY_TARGETING: + ret = RecvAddFlyTargetingPacket(); + break; + + case HEADER_GC_SKILL_LEVEL: + ret = RecvSkillLevel(); + break; + + case HEADER_GC_SKILL_LEVEL_NEW: + ret = RecvSkillLevelNew(); + break; + + case HEADER_GC_MESSENGER: + ret = RecvMessenger(); + break; + + case HEADER_GC_GUILD: + ret = RecvGuild(); + break; + + case HEADER_GC_PARTY_INVITE: + ret = RecvPartyInvite(); + break; + + case HEADER_GC_PARTY_ADD: + ret = RecvPartyAdd(); + break; + + case HEADER_GC_PARTY_UPDATE: + ret = RecvPartyUpdate(); + break; + + case HEADER_GC_PARTY_REMOVE: + ret = RecvPartyRemove(); + break; + + case HEADER_GC_PARTY_LINK: + ret = RecvPartyLink(); + break; + + case HEADER_GC_PARTY_UNLINK: + ret = RecvPartyUnlink(); + break; + + case HEADER_GC_PARTY_PARAMETER: + ret = RecvPartyParameter(); + break; + + case HEADER_GC_SAFEBOX_SET: + ret = RecvSafeBoxSetPacket(); + break; + + case HEADER_GC_SAFEBOX_DEL: + ret = RecvSafeBoxDelPacket(); + break; + + case HEADER_GC_SAFEBOX_WRONG_PASSWORD: + ret = RecvSafeBoxWrongPasswordPacket(); + break; + + case HEADER_GC_SAFEBOX_SIZE: + ret = RecvSafeBoxSizePacket(); + break; + + case HEADER_GC_SAFEBOX_MONEY_CHANGE: + ret = RecvSafeBoxMoneyChangePacket(); + break; + + case HEADER_GC_FISHING: + ret = RecvFishing(); + break; + + case HEADER_GC_DUNGEON: + ret = RecvDungeon(); + break; + + case HEADER_GC_TIME: + ret = RecvTimePacket(); + break; + + case HEADER_GC_WALK_MODE: + ret = RecvWalkModePacket(); + break; + + case HEADER_GC_CHANGE_SKILL_GROUP: + ret = RecvChangeSkillGroupPacket(); + break; + + case HEADER_GC_REFINE_INFORMATION: + ret = RecvRefineInformationPacket(); + break; + + case HEADER_GC_REFINE_INFORMATION_NEW: + ret = RecvRefineInformationPacketNew(); + break; + + case HEADER_GC_SEPCIAL_EFFECT: + ret = RecvSpecialEffect(); + break; + + case HEADER_GC_NPC_POSITION: + ret = RecvNPCList(); + break; + + case HEADER_GC_CHANNEL: + ret = RecvChannelPacket(); + break; + + case HEADER_GC_VIEW_EQUIP: + ret = RecvViewEquipPacket(); + break; + + case HEADER_GC_LAND_LIST: + ret = RecvLandPacket(); + break; + + //case HEADER_GC_TARGET_CREATE: + // ret = RecvTargetCreatePacket(); + // break; + + case HEADER_GC_TARGET_CREATE_NEW: + ret = RecvTargetCreatePacketNew(); + break; + + case HEADER_GC_TARGET_UPDATE: + ret = RecvTargetUpdatePacket(); + break; + + case HEADER_GC_TARGET_DELETE: + ret = RecvTargetDeletePacket(); + break; + + case HEADER_GC_AFFECT_ADD: + ret = RecvAffectAddPacket(); + break; + + case HEADER_GC_AFFECT_REMOVE: + ret = RecvAffectRemovePacket(); + break; + + case HEADER_GC_MALL_OPEN: + ret = RecvMallOpenPacket(); + break; + + case HEADER_GC_MALL_SET: + ret = RecvMallItemSetPacket(); + break; + + case HEADER_GC_MALL_DEL: + ret = RecvMallItemDelPacket(); + break; + + case HEADER_GC_LOVER_INFO: + ret = RecvLoverInfoPacket(); + break; + + case HEADER_GC_LOVE_POINT_UPDATE: + ret = RecvLovePointUpdatePacket(); + break; + + case HEADER_GC_DIG_MOTION: + ret = RecvDigMotionPacket(); + break; + + case HEADER_GC_HANDSHAKE: + RecvHandshakePacket(); + return; + break; + + case HEADER_GC_HANDSHAKE_OK: + RecvHandshakeOKPacket(); + return; + break; + + case HEADER_GC_HYBRIDCRYPT_KEYS: + RecvHybridCryptKeyPacket(); + return; + break; + + case HEADER_GC_HYBRIDCRYPT_SDB: + RecvHybridCryptSDBPacket(); + return; + break; + + +#ifdef _IMPROVED_PACKET_ENCRYPTION_ + case HEADER_GC_KEY_AGREEMENT: + RecvKeyAgreementPacket(); + return; + break; + + case HEADER_GC_KEY_AGREEMENT_COMPLETED: + RecvKeyAgreementCompletedPacket(); + return; + break; +#endif + + case HEADER_GC_HS_REQUEST: + ret = RecvHSCheckRequest(); + break; + + case HEADER_GC_XTRAP_CS1_REQUEST: + ret = RecvXTrapVerifyRequest(); + break; + + case HEADER_GC_SPECIFIC_EFFECT: + ret = RecvSpecificEffect(); + break; + + case HEADER_GC_DRAGON_SOUL_REFINE: + ret = RecvDragonSoulRefine(); + break; + + default: + ret = RecvDefaultPacket(header); + break; + } +#ifdef __PERFORMANCE_CHECK__ + DWORD timeEndPacket=timeGetTime(); + + { + PERF_PacketInfo& rkPacketInfo=kMap_kPacketInfo[header]; + rkPacketInfo.dwCount++; + rkPacketInfo.dwTime+=timeEndPacket-timeBeginPacket; + } + + { + PERF_PacketInfo& rkPacketInfo=gs_kPacketTimeAnalyzer.m_kMap_kPacketInfo[header]; + rkPacketInfo.dwCount++; + rkPacketInfo.dwTime+=timeEndPacket-timeBeginPacket; + } +#endif + } + +#ifdef __PERFORMANCE_CHECK__ + DWORD timeEndDispatch=timeGetTime(); + + if (timeEndDispatch-timeBeginDispatch>2) + { + static FILE* fp=fopen("perf_dispatch_packet.txt", "w"); + + fprintf(fp, "delay %d\n", timeEndDispatch-timeBeginDispatch); + for (std::map::iterator i=kMap_kPacketInfo.begin(); i!=kMap_kPacketInfo.end(); ++i) + { + if (i->second.dwTime>0) + fprintf(fp, "header %d: count %d, time %d\n", i->first, i->second.dwCount, i->second.dwTime); + } + fputs("=====================================================\n", fp); + fflush(fp); + } +#endif + + if (!ret) + RecvErrorPacket(header); + + static DWORD s_nextRefreshTime = ELTimer_GetMSec(); + + DWORD curTime = ELTimer_GetMSec(); + if (s_nextRefreshTime > curTime) + return; + + + + if (m_isRefreshCharacterWnd) + { + m_isRefreshCharacterWnd=false; + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshCharacter", Py_BuildValue("()")); + s_nextRefreshTime = curTime + 300; + } + + if (m_isRefreshEquipmentWnd) + { + m_isRefreshEquipmentWnd=false; + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshEquipment", Py_BuildValue("()")); + s_nextRefreshTime = curTime + 300; + } + + if (m_isRefreshInventoryWnd) + { + m_isRefreshInventoryWnd=false; + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshInventory", Py_BuildValue("()")); + s_nextRefreshTime = curTime + 300; + } + + if (m_isRefreshExchangeWnd) + { + m_isRefreshExchangeWnd=false; + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshExchange", Py_BuildValue("()")); + s_nextRefreshTime = curTime + 300; + } + + if (m_isRefreshSkillWnd) + { + m_isRefreshSkillWnd=false; + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshSkill", Py_BuildValue("()")); + s_nextRefreshTime = curTime + 300; + } + + if (m_isRefreshSafeboxWnd) + { + m_isRefreshSafeboxWnd=false; + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshSafebox", Py_BuildValue("()")); + s_nextRefreshTime = curTime + 300; + } + + if (m_isRefreshMallWnd) + { + m_isRefreshMallWnd=false; + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshMall", Py_BuildValue("()")); + s_nextRefreshTime = curTime + 300; + } + + if (m_isRefreshStatus) + { + m_isRefreshStatus=false; + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshStatus", Py_BuildValue("()")); + s_nextRefreshTime = curTime + 300; + } + + if (m_isRefreshMessengerWnd) + { + m_isRefreshMessengerWnd=false; + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshMessenger", Py_BuildValue("()")); + s_nextRefreshTime = curTime + 300; + } + + if (m_isRefreshGuildWndInfoPage) + { + m_isRefreshGuildWndInfoPage=false; + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshGuildInfoPage", Py_BuildValue("()")); + s_nextRefreshTime = curTime + 300; + } + + if (m_isRefreshGuildWndBoardPage) + { + m_isRefreshGuildWndBoardPage=false; + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshGuildBoardPage", Py_BuildValue("()")); + s_nextRefreshTime = curTime + 300; + } + + if (m_isRefreshGuildWndMemberPage) + { + m_isRefreshGuildWndMemberPage=false; + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshGuildMemberPage", Py_BuildValue("()")); + s_nextRefreshTime = curTime + 300; + } + + if (m_isRefreshGuildWndMemberPageGradeComboBox) + { + m_isRefreshGuildWndMemberPageGradeComboBox=false; + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshGuildMemberPageGradeComboBox", Py_BuildValue("()")); + s_nextRefreshTime = curTime + 300; + } + + if (m_isRefreshGuildWndSkillPage) + { + m_isRefreshGuildWndSkillPage=false; + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshGuildSkillPage", Py_BuildValue("()")); + s_nextRefreshTime = curTime + 300; + } + + if (m_isRefreshGuildWndGradePage) + { + m_isRefreshGuildWndGradePage=false; + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshGuildGradePage", Py_BuildValue("()")); + s_nextRefreshTime = curTime + 300; + } +} + +void CPythonNetworkStream::__InitializeGamePhase() +{ + __ServerTimeSync_Initialize(); + + m_isRefreshStatus=false; + m_isRefreshCharacterWnd=false; + m_isRefreshEquipmentWnd=false; + m_isRefreshInventoryWnd=false; + m_isRefreshExchangeWnd=false; + m_isRefreshSkillWnd=false; + m_isRefreshSafeboxWnd=false; + m_isRefreshMallWnd=false; + m_isRefreshMessengerWnd=false; + m_isRefreshGuildWndInfoPage=false; + m_isRefreshGuildWndBoardPage=false; + m_isRefreshGuildWndMemberPage=false; + m_isRefreshGuildWndMemberPageGradeComboBox=false; + m_isRefreshGuildWndSkillPage=false; + m_isRefreshGuildWndGradePage=false; + + m_EmoticonStringVector.clear(); + + m_pInstTarget = NULL; +} + +void CPythonNetworkStream::Warp(LONG lGlobalX, LONG lGlobalY) +{ + CPythonBackground& rkBgMgr=CPythonBackground::Instance(); + rkBgMgr.Destroy(); + rkBgMgr.Create(); + rkBgMgr.Warp(lGlobalX, lGlobalY); + //rkBgMgr.SetShadowLevel(CPythonBackground::SHADOW_ALL); + rkBgMgr.RefreshShadowLevel(); + + // NOTE : Warp CenterPosition Height 0̱ ī޶ ٴڿ ְ + // ϶ Height DZ ̹Ƿ ̵ϸ Position ѹ + // ش - [levites] + LONG lLocalX = lGlobalX; + LONG lLocalY = lGlobalY; + __GlobalPositionToLocalPosition(lLocalX, lLocalY); + float fHeight = CPythonBackground::Instance().GetHeight(float(lLocalX), float(lLocalY)); + + IAbstractApplication& rkApp=IAbstractApplication::GetSingleton(); + rkApp.SetCenterPosition(float(lLocalX), float(lLocalY), fHeight); + + __ShowMapName(lLocalX, lLocalY); +} + +void CPythonNetworkStream::__ShowMapName(LONG lLocalX, LONG lLocalY) +{ + const std::string & c_rstrMapFileName = CPythonBackground::Instance().GetWarpMapName(); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "ShowMapName", Py_BuildValue("(sii)", c_rstrMapFileName.c_str(), lLocalX, lLocalY)); +} + +void CPythonNetworkStream::__LeaveGamePhase() +{ + CInstanceBase::ClearPVPKeySystem(); + + __ClearNetworkActorManager(); + + m_bComboSkillFlag = FALSE; + + IAbstractCharacterManager& rkChrMgr=IAbstractCharacterManager::GetSingleton(); + rkChrMgr.Destroy(); + + CPythonItem& rkItemMgr=CPythonItem::Instance(); + rkItemMgr.Destroy(); +} + +void CPythonNetworkStream::SetGamePhase() +{ + if ("Game"!=m_strPhase) + m_phaseLeaveFunc.Run(); + + Tracen(""); + Tracen("## Network - Game Phase ##"); + Tracen(""); + + m_strPhase = "Game"; + + m_dwChangingPhaseTime = ELTimer_GetMSec(); + m_phaseProcessFunc.Set(this, &CPythonNetworkStream::GamePhase); + m_phaseLeaveFunc.Set(this, &CPythonNetworkStream::__LeaveGamePhase); + + // Main Character O + + IAbstractPlayer & rkPlayer = IAbstractPlayer::GetSingleton(); + rkPlayer.SetMainCharacterIndex(GetMainActorVID()); + + __RefreshStatus(); +} + +bool CPythonNetworkStream::RecvObserverAddPacket() +{ + TPacketGCObserverAdd kObserverAddPacket; + if (!Recv(sizeof(kObserverAddPacket), &kObserverAddPacket)) + return false; + + CPythonMiniMap::Instance().AddObserver( + kObserverAddPacket.vid, + kObserverAddPacket.x*100.0f, + kObserverAddPacket.y*100.0f); + + return true; +} + +bool CPythonNetworkStream::RecvObserverRemovePacket() +{ + TPacketGCObserverAdd kObserverRemovePacket; + if (!Recv(sizeof(kObserverRemovePacket), &kObserverRemovePacket)) + return false; + + CPythonMiniMap::Instance().RemoveObserver( + kObserverRemovePacket.vid + ); + + return true; +} + +bool CPythonNetworkStream::RecvObserverMovePacket() +{ + TPacketGCObserverMove kObserverMovePacket; + if (!Recv(sizeof(kObserverMovePacket), &kObserverMovePacket)) + return false; + + CPythonMiniMap::Instance().MoveObserver( + kObserverMovePacket.vid, + kObserverMovePacket.x*100.0f, + kObserverMovePacket.y*100.0f); + + return true; +} + + +bool CPythonNetworkStream::RecvWarpPacket() +{ + TPacketGCWarp kWarpPacket; + + if (!Recv(sizeof(kWarpPacket), &kWarpPacket)) + return false; + + __DirectEnterMode_Set(m_dwSelectedCharacterIndex); + + CNetworkStream::Connect((DWORD)kWarpPacket.lAddr, kWarpPacket.wPort); + + return true; +} + +bool CPythonNetworkStream::RecvDuelStartPacket() +{ + TPacketGCDuelStart kDuelStartPacket; + if (!Recv(sizeof(kDuelStartPacket), &kDuelStartPacket)) + return false; + + DWORD count = (kDuelStartPacket.wSize - sizeof(kDuelStartPacket))/sizeof(DWORD); + + CPythonCharacterManager & rkChrMgr = CPythonCharacterManager::Instance(); + + CInstanceBase* pkInstMain=rkChrMgr.GetMainInstancePtr(); + if (!pkInstMain) + { + TraceError("CPythonNetworkStream::RecvDuelStartPacket - MainCharacter is NULL"); + return false; + } + DWORD dwVIDSrc = pkInstMain->GetVirtualID(); + DWORD dwVIDDest; + + for ( DWORD i = 0; i < count; i++) + { + Recv(sizeof(dwVIDDest),&dwVIDDest); + CInstanceBase::InsertDUELKey(dwVIDSrc,dwVIDDest); + } + + if(count == 0) + pkInstMain->SetDuelMode(CInstanceBase::DUEL_CANNOTATTACK); + else + pkInstMain->SetDuelMode(CInstanceBase::DUEL_START); + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "CloseTargetBoard", Py_BuildValue("()")); + + rkChrMgr.RefreshAllPCTextTail(); + + return true; +} + +bool CPythonNetworkStream::RecvPVPPacket() +{ + TPacketGCPVP kPVPPacket; + if (!Recv(sizeof(kPVPPacket), &kPVPPacket)) + return false; + + CPythonCharacterManager & rkChrMgr = CPythonCharacterManager::Instance(); + CPythonPlayer & rkPlayer = CPythonPlayer::Instance(); + + switch (kPVPPacket.bMode) + { + case PVP_MODE_AGREE: + rkChrMgr.RemovePVPKey(kPVPPacket.dwVIDSrc, kPVPPacket.dwVIDDst); + + // 밡 (Dst) Ǹ + if (rkPlayer.IsMainCharacterIndex(kPVPPacket.dwVIDDst)) + rkPlayer.RememberChallengeInstance(kPVPPacket.dwVIDSrc); + + // 뿡 Ǹ ȿ Ҵ + if (rkPlayer.IsMainCharacterIndex(kPVPPacket.dwVIDSrc)) + rkPlayer.RememberCantFightInstance(kPVPPacket.dwVIDDst); + break; + case PVP_MODE_REVENGE: + { + rkChrMgr.RemovePVPKey(kPVPPacket.dwVIDSrc, kPVPPacket.dwVIDDst); + + DWORD dwKiller = kPVPPacket.dwVIDSrc; + DWORD dwVictim = kPVPPacket.dwVIDDst; + + // (victim) 뿡 + if (rkPlayer.IsMainCharacterIndex(dwVictim)) + rkPlayer.RememberRevengeInstance(dwKiller); + + // (victim) ϴ ȿ Ҵ + if (rkPlayer.IsMainCharacterIndex(dwKiller)) + rkPlayer.RememberCantFightInstance(dwVictim); + break; + } + + case PVP_MODE_FIGHT: + rkChrMgr.InsertPVPKey(kPVPPacket.dwVIDSrc, kPVPPacket.dwVIDDst); + rkPlayer.ForgetInstance(kPVPPacket.dwVIDSrc); + rkPlayer.ForgetInstance(kPVPPacket.dwVIDDst); + break; + case PVP_MODE_NONE: + rkChrMgr.RemovePVPKey(kPVPPacket.dwVIDSrc, kPVPPacket.dwVIDDst); + rkPlayer.ForgetInstance(kPVPPacket.dwVIDSrc); + rkPlayer.ForgetInstance(kPVPPacket.dwVIDDst); + break; + } + + // NOTE : PVP ۽ TargetBoard Ʈ մϴ. + __RefreshTargetBoardByVID(kPVPPacket.dwVIDSrc); + __RefreshTargetBoardByVID(kPVPPacket.dwVIDDst); + + return true; +} + +// DELETEME +/* +void CPythonNetworkStream::__SendWarpPacket() +{ + TPacketCGWarp kWarpPacket; + kWarpPacket.bHeader=HEADER_GC_WARP; + if (!Send(sizeof(kWarpPacket), &kWarpPacket)) + { + return; + } +} +*/ +void CPythonNetworkStream::NotifyHack(const char* c_szMsg) +{ + if (!m_kQue_stHack.empty()) + if (c_szMsg==m_kQue_stHack.back()) + return; + + m_kQue_stHack.push_back(c_szMsg); +} + +bool CPythonNetworkStream::__SendHack(const char* c_szMsg) +{ + Tracen(c_szMsg); + + TPacketCGHack kPacketHack; + kPacketHack.bHeader=HEADER_CG_HACK; + strncpy(kPacketHack.szBuf, c_szMsg, sizeof(kPacketHack.szBuf)-1); + + if (!Send(sizeof(kPacketHack), &kPacketHack)) + return false; + + return SendSequence(); +} + +bool CPythonNetworkStream::SendMessengerAddByVIDPacket(DWORD vid) +{ + TPacketCGMessenger packet; + packet.header = HEADER_CG_MESSENGER; + packet.subheader = MESSENGER_SUBHEADER_CG_ADD_BY_VID; + if (!Send(sizeof(packet), &packet)) + return false; + if (!Send(sizeof(vid), &vid)) + return false; + return SendSequence(); +} + +bool CPythonNetworkStream::SendMessengerAddByNamePacket(const char * c_szName) +{ + TPacketCGMessenger packet; + packet.header = HEADER_CG_MESSENGER; + packet.subheader = MESSENGER_SUBHEADER_CG_ADD_BY_NAME; + if (!Send(sizeof(packet), &packet)) + return false; + char szName[CHARACTER_NAME_MAX_LEN]; + strncpy(szName, c_szName, CHARACTER_NAME_MAX_LEN-1); + szName[CHARACTER_NAME_MAX_LEN-1] = '\0'; // #720: ޽ ̸ ÷ο + + if (!Send(sizeof(szName), &szName)) + return false; + Tracef(" SendMessengerAddByNamePacket : %s\n", c_szName); + return SendSequence(); +} + +bool CPythonNetworkStream::SendMessengerRemovePacket(const char * c_szKey, const char * c_szName) +{ + TPacketCGMessenger packet; + packet.header = HEADER_CG_MESSENGER; + packet.subheader = MESSENGER_SUBHEADER_CG_REMOVE; + if (!Send(sizeof(packet), &packet)) + return false; + char szKey[CHARACTER_NAME_MAX_LEN]; + strncpy(szKey, c_szKey, CHARACTER_NAME_MAX_LEN-1); + if (!Send(sizeof(szKey), &szKey)) + return false; + __RefreshTargetBoardByName(c_szName); + return SendSequence(); +} + +bool CPythonNetworkStream::SendCharacterStatePacket(const TPixelPosition& c_rkPPosDst, float fDstRot, UINT eFunc, UINT uArg) +{ + NANOBEGIN + if (!__CanActMainInstance()) + return true; + + if (fDstRot < 0.0f) + fDstRot = 360 + fDstRot; + else if (fDstRot > 360.0f) + fDstRot = fmodf(fDstRot, 360.0f); + + // TODO: ߿ Ŷ̸ ٲ + TPacketCGMove kStatePacket; + kStatePacket.bHeader = HEADER_CG_CHARACTER_MOVE; + kStatePacket.bFunc = eFunc; + kStatePacket.bArg = uArg; + kStatePacket.bRot = fDstRot/5.0f; + kStatePacket.lX = long(c_rkPPosDst.x); + kStatePacket.lY = long(c_rkPPosDst.y); + kStatePacket.dwTime = ELTimer_GetServerMSec(); + + assert(kStatePacket.lX >= 0 && kStatePacket.lX < 204800); + + __LocalPositionToGlobalPosition(kStatePacket.lX, kStatePacket.lY); + + if (!Send(sizeof(kStatePacket), &kStatePacket)) + { + Tracenf("CPythonNetworkStream::SendCharacterStatePacket(dwCmdTime=%u, fDstPos=(%f, %f), fDstRot=%f, eFunc=%d uArg=%d) - PACKET SEND ERROR", + kStatePacket.dwTime, + float(kStatePacket.lX), + float(kStatePacket.lY), + fDstRot, + kStatePacket.bFunc, + kStatePacket.bArg); + return false; + } + NANOEND + return SendSequence(); +} + +// NOTE : SlotIndex ӽ +bool CPythonNetworkStream::SendUseSkillPacket(DWORD dwSkillIndex, DWORD dwTargetVID) +{ + TPacketCGUseSkill UseSkillPacket; + UseSkillPacket.bHeader = HEADER_CG_USE_SKILL; + UseSkillPacket.dwVnum = dwSkillIndex; + UseSkillPacket.dwTargetVID = dwTargetVID; + if (!Send(sizeof(TPacketCGUseSkill), &UseSkillPacket)) + { + Tracen("CPythonNetworkStream::SendUseSkillPacket - SEND PACKET ERROR"); + return false; + } + + return SendSequence(); +} + +bool CPythonNetworkStream::SendChatPacket(const char * c_szChat, BYTE byType) +{ + if (strlen(c_szChat) == 0) + return true; + + if (strlen(c_szChat) >= 512) + return true; + + if (c_szChat[0] == '/') + { + if (1 == strlen(c_szChat)) + { + if (!m_strLastCommand.empty()) + c_szChat = m_strLastCommand.c_str(); + } + else + { + m_strLastCommand = c_szChat; + } + } + + if (ClientCommand(c_szChat)) + return true; + + int iTextLen = strlen(c_szChat) + 1; + TPacketCGChat ChatPacket; + ChatPacket.header = HEADER_CG_CHAT; + ChatPacket.length = sizeof(ChatPacket) + iTextLen; + ChatPacket.type = byType; + + if (!Send(sizeof(ChatPacket), &ChatPacket)) + return false; + + if (!Send(iTextLen, c_szChat)) + return false; + + return SendSequence(); +} + +////////////////////////////////////////////////////////////////////////// +// Emoticon +void CPythonNetworkStream::RegisterEmoticonString(const char * pcEmoticonString) +{ + if (m_EmoticonStringVector.size() >= CInstanceBase::EMOTICON_NUM) + { + TraceError("Can't register emoticon string... vector is full (size:%d)", m_EmoticonStringVector.size() ); + return; + } + m_EmoticonStringVector.push_back(pcEmoticonString); +} + +bool CPythonNetworkStream::ParseEmoticon(const char * pChatMsg, DWORD * pdwEmoticon) +{ + for (DWORD dwEmoticonIndex = 0; dwEmoticonIndex < m_EmoticonStringVector.size() ; ++dwEmoticonIndex) + { + if (strlen(pChatMsg) > m_EmoticonStringVector[dwEmoticonIndex].size()) + continue; + + const char * pcFind = strstr(pChatMsg, m_EmoticonStringVector[dwEmoticonIndex].c_str()); + + if (pcFind != pChatMsg) + continue; + + *pdwEmoticon = dwEmoticonIndex; + + return true; + } + + return false; +} +// Emoticon +////////////////////////////////////////////////////////////////////////// + +void CPythonNetworkStream::__ConvertEmpireText(DWORD dwEmpireID, char* szText) +{ + if (dwEmpireID<1 || dwEmpireID>3) + return; + + UINT uHanPos; + + STextConvertTable& rkTextConvTable=m_aTextConvTable[dwEmpireID-1]; + + BYTE* pbText=(BYTE*)szText; + while (*pbText) + { + if (*pbText & 0x80) + { + if (pbText[0]>=0xb0 && pbText[0]<=0xc8 && pbText[1]>=0xa1 && pbText[1]<=0xfe) + { + uHanPos=(pbText[0]-0xb0)*(0xfe-0xa1+1)+(pbText[1]-0xa1); + pbText[0]=rkTextConvTable.aacHan[uHanPos][0]; + pbText[1]=rkTextConvTable.aacHan[uHanPos][1]; + } + pbText+=2; + } + else + { + if (*pbText>='a' && *pbText<='z') + { + *pbText=rkTextConvTable.acLower[*pbText-'a']; + } + else if (*pbText>='A' && *pbText<='Z') + { + *pbText=rkTextConvTable.acUpper[*pbText-'A']; + } + pbText++; + } + } +} + +bool CPythonNetworkStream::RecvChatPacket() +{ + TPacketGCChat kChat; + char buf[1024 + 1]; + char line[1024 + 1]; + + if (!Recv(sizeof(kChat), &kChat)) + return false; + + UINT uChatSize=kChat.size - sizeof(kChat); + + if (!Recv(uChatSize, buf)) + return false; + + buf[uChatSize]='\0'; + + // ƶ ó + // "̸: " Է ": ̸" ϱ (0x08) + // ƶ ȣ ó (1) : (2) ԷµǾ (2) : (1) ϰ + if (LocaleService_IsEUROPE() && GetDefaultCodePage() == 1256) + { + char * p = strchr(buf, ':'); + if (p && p[1] == ' ') + p[1] = 0x08; + } + + if (kChat.type >= CHAT_TYPE_MAX_NUM) + return true; + + if (CHAT_TYPE_COMMAND == kChat.type) + { + ServerCommand(buf); + return true; + } + + if (kChat.dwVID != 0) + { + CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance(); + CInstanceBase * pkInstChatter = rkChrMgr.GetInstancePtr(kChat.dwVID); + if (NULL == pkInstChatter) + return true; + + switch (kChat.type) + { + case CHAT_TYPE_TALKING: /* ׳ ä */ + case CHAT_TYPE_PARTY: /* Ƽ */ + case CHAT_TYPE_GUILD: /* 帻 */ + case CHAT_TYPE_SHOUT: /* ġ */ + case CHAT_TYPE_WHISPER: // ʹ ʴ Only Client Enum + { + char * p = strchr(buf, ':'); + + if (p) + p += 2; + else + p = buf; + + DWORD dwEmoticon; + + if (ParseEmoticon(p, &dwEmoticon)) + { + pkInstChatter->SetEmoticon(dwEmoticon); + return true; + } + else + { + if (gs_bEmpireLanuageEnable) + { + CInstanceBase* pkInstMain=rkChrMgr.GetMainInstancePtr(); + if (pkInstMain) + if (!pkInstMain->IsSameEmpire(*pkInstChatter)) + __ConvertEmpireText(pkInstChatter->GetEmpireID(), p); + } + + if (m_isEnableChatInsultFilter) + { + if (false == pkInstChatter->IsNPC() && false == pkInstChatter->IsEnemy()) + { + __FilterInsult(p, strlen(p)); + } + } + + _snprintf(line, sizeof(line), "%s", p); + } + } + break; + case CHAT_TYPE_COMMAND: /* */ + case CHAT_TYPE_INFO: /* ( , ġ . ) */ + case CHAT_TYPE_NOTICE: /* */ + case CHAT_TYPE_BIG_NOTICE: + case CHAT_TYPE_MAX_NUM: + default: + _snprintf(line, sizeof(line), "%s", buf); + break; + } + + if (CHAT_TYPE_SHOUT != kChat.type) + { + CPythonTextTail::Instance().RegisterChatTail(kChat.dwVID, line); + } + + if (pkInstChatter->IsPC()) + CPythonChat::Instance().AppendChat(kChat.type, buf); + } + else + { + if (CHAT_TYPE_NOTICE == kChat.type) + { + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_SetTipMessage", Py_BuildValue("(s)", buf)); + } + else if (CHAT_TYPE_BIG_NOTICE == kChat.type) + { + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_SetBigMessage", Py_BuildValue("(s)", buf)); + } + else if (CHAT_TYPE_SHOUT == kChat.type) + { + char * p = strchr(buf, ':'); + + if (p) + { + if (m_isEnableChatInsultFilter) + __FilterInsult(p, strlen(p)); + } + } + + CPythonChat::Instance().AppendChat(kChat.type, buf); + + } + return true; +} + +bool CPythonNetworkStream::RecvWhisperPacket() +{ + TPacketGCWhisper whisperPacket; + char buf[512 + 1]; + + if (!Recv(sizeof(whisperPacket), &whisperPacket)) + return false; + + assert(whisperPacket.wSize - sizeof(whisperPacket) < 512); + + if (!Recv(whisperPacket.wSize - sizeof(whisperPacket), &buf)) + return false; + + buf[whisperPacket.wSize - sizeof(whisperPacket)] = '\0'; + + static char line[256]; + if (CPythonChat::WHISPER_TYPE_CHAT == whisperPacket.bType || CPythonChat::WHISPER_TYPE_GM == whisperPacket.bType) + { + _snprintf(line, sizeof(line), "%s : %s", whisperPacket.szNameFrom, buf); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnRecvWhisper", Py_BuildValue("(iss)", (int) whisperPacket.bType, whisperPacket.szNameFrom, line)); + } + else if (CPythonChat::WHISPER_TYPE_SYSTEM == whisperPacket.bType || CPythonChat::WHISPER_TYPE_ERROR == whisperPacket.bType) + { + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnRecvWhisperSystemMessage", Py_BuildValue("(iss)", (int) whisperPacket.bType, whisperPacket.szNameFrom, buf)); + } + else + { + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnRecvWhisperError", Py_BuildValue("(iss)", (int) whisperPacket.bType, whisperPacket.szNameFrom, buf)); + } + + return true; +} + +bool CPythonNetworkStream::SendWhisperPacket(const char * name, const char * c_szChat) +{ + if (strlen(c_szChat) >= 255) + return true; + + int iTextLen = strlen(c_szChat) + 1; + TPacketCGWhisper WhisperPacket; + WhisperPacket.bHeader = HEADER_CG_WHISPER; + WhisperPacket.wSize = sizeof(WhisperPacket) + iTextLen; + + strncpy(WhisperPacket.szNameTo, name, sizeof(WhisperPacket.szNameTo) - 1); + + if (!Send(sizeof(WhisperPacket), &WhisperPacket)) + return false; + + if (!Send(iTextLen, c_szChat)) + return false; + + return SendSequence(); +} + +bool CPythonNetworkStream::SendMobileMessagePacket(const char * name, const char * c_szChat) +{ + int iTextLen = strlen(c_szChat) + 1; + TPacketCGSMS SMSPacket; + SMSPacket.bHeader = HEADER_CG_SMS; + SMSPacket.wSize = sizeof(SMSPacket) + iTextLen; + + strncpy(SMSPacket.szNameTo, name, sizeof(SMSPacket.szNameTo) - 1); + + if (!Send(sizeof(SMSPacket), &SMSPacket)) + return false; + + if (!Send(iTextLen, c_szChat)) + return false; + + return SendSequence(); +} + +bool CPythonNetworkStream::RecvPointChange() +{ + TPacketGCPointChange PointChange; + + if (!Recv(sizeof(TPacketGCPointChange), &PointChange)) + { + Tracen("Recv Point Change Packet Error"); + return false; + } + + CPythonCharacterManager& rkChrMgr = CPythonCharacterManager::Instance(); + rkChrMgr.ShowPointEffect(PointChange.Type, PointChange.dwVID); + + CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetMainInstancePtr(); + + // ڽ Point Ǿ .. + if (pInstance) + if (PointChange.dwVID == pInstance->GetVirtualID()) + { + CPythonPlayer & rkPlayer = CPythonPlayer::Instance(); + rkPlayer.SetStatus(PointChange.Type, PointChange.value); + + switch (PointChange.Type) + { + case POINT_STAT_RESET_COUNT: + __RefreshStatus(); + break; + case POINT_LEVEL: + case POINT_ST: + case POINT_DX: + case POINT_HT: + case POINT_IQ: + __RefreshStatus(); + __RefreshSkillWindow(); + break; + case POINT_SKILL: + case POINT_SUB_SKILL: + case POINT_HORSE_SKILL: + __RefreshSkillWindow(); + break; + case POINT_ENERGY: + if (PointChange.value == 0) + { + rkPlayer.SetStatus(POINT_ENERGY_END_TIME, 0); + } + __RefreshStatus(); + break; + default: + __RefreshStatus(); + break; + } + + if (POINT_GOLD == PointChange.Type) + { + if (PointChange.amount > 0) + { + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnPickMoney", Py_BuildValue("(i)", PointChange.amount)); + } + } + } + else + { + if (PointChange.Type == POINT_LEVEL) + { + pInstance = CPythonCharacterManager::Instance().GetInstancePtr(PointChange.dwVID); + if (pInstance) + { + pInstance->SetLevel(PointChange.value); + pInstance->UpdateTextTailLevel(PointChange.value); + } + } + } + + return true; +} + +bool CPythonNetworkStream::RecvStunPacket() +{ + TPacketGCStun StunPacket; + + if (!Recv(sizeof(StunPacket), &StunPacket)) + { + Tracen("CPythonNetworkStream::RecvStunPacket Error"); + return false; + } + + //Tracef("RecvStunPacket %d\n", StunPacket.vid); + + CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance(); + CInstanceBase * pkInstSel = rkChrMgr.GetInstancePtr(StunPacket.vid); + + if (pkInstSel) + { + if (CPythonCharacterManager::Instance().GetMainInstancePtr()==pkInstSel) + pkInstSel->Die(); + else + pkInstSel->Stun(); + } + + return true; +} + +bool CPythonNetworkStream::RecvDeadPacket() +{ + TPacketGCDead DeadPacket; + if (!Recv(sizeof(DeadPacket), &DeadPacket)) + { + Tracen("CPythonNetworkStream::RecvDeadPacket Error"); + return false; + } + + CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance(); + CInstanceBase * pkChrInstSel = rkChrMgr.GetInstancePtr(DeadPacket.vid); + if (pkChrInstSel) + { + CInstanceBase* pkInstMain=rkChrMgr.GetMainInstancePtr(); + if (pkInstMain==pkChrInstSel) + { + Tracenf("ΰ "); + if (false == pkInstMain->GetDuelMode()) + { + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnGameOver", Py_BuildValue("()")); + } + CPythonPlayer::Instance().NotifyDeadMainCharacter(); + } + + pkChrInstSel->Die(); + } + + return true; +} + +bool CPythonNetworkStream::SendCharacterPositionPacket(BYTE iPosition) +{ + TPacketCGPosition PositionPacket; + + PositionPacket.header = HEADER_CG_CHARACTER_POSITION; + PositionPacket.position = iPosition; + + if (!Send(sizeof(TPacketCGPosition), &PositionPacket)) + { + Tracen("Send Character Position Packet Error"); + return false; + } + + return SendSequence(); +} + +bool CPythonNetworkStream::SendOnClickPacket(DWORD vid) +{ + TPacketCGOnClick OnClickPacket; + OnClickPacket.header = HEADER_CG_ON_CLICK; + OnClickPacket.vid = vid; + + if (!Send(sizeof(OnClickPacket), &OnClickPacket)) + { + Tracen("Send On_Click Packet Error"); + return false; + } + + Tracef("SendOnClickPacket\n"); + return SendSequence(); +} + +bool CPythonNetworkStream::RecvCharacterPositionPacket() +{ + TPacketGCPosition PositionPacket; + + if (!Recv(sizeof(TPacketGCPosition), &PositionPacket)) + return false; + + CInstanceBase * pChrInstance = CPythonCharacterManager::Instance().GetInstancePtr(PositionPacket.vid); + + if (!pChrInstance) + return true; + + //pChrInstance->UpdatePosition(PositionPacket.position); + + return true; +} + +bool CPythonNetworkStream::RecvMotionPacket() +{ + TPacketGCMotion MotionPacket; + + if (!Recv(sizeof(TPacketGCMotion), &MotionPacket)) + return false; + + CInstanceBase * pMainInstance = CPythonCharacterManager::Instance().GetInstancePtr(MotionPacket.vid); + CInstanceBase * pVictimInstance = NULL; + + if (0 != MotionPacket.victim_vid) + pVictimInstance = CPythonCharacterManager::Instance().GetInstancePtr(MotionPacket.victim_vid); + + if (!pMainInstance) + return false; + + return true; +} + +bool CPythonNetworkStream::RecvShopPacket() +{ + std::vector vecBuffer; + vecBuffer.clear(); + + TPacketGCShop packet_shop; + if (!Recv(sizeof(packet_shop), &packet_shop)) + return false; + + int iSize = packet_shop.size - sizeof(packet_shop); + if (iSize > 0) + { + vecBuffer.resize(iSize); + if (!Recv(iSize, &vecBuffer[0])) + return false; + } + + switch (packet_shop.subheader) + { + case SHOP_SUBHEADER_GC_START: + { + CPythonShop::Instance().Clear(); + + DWORD dwVID = *(DWORD *)&vecBuffer[0]; + + TPacketGCShopStart * pShopStartPacket = (TPacketGCShopStart *)&vecBuffer[4]; + for (BYTE iItemIndex = 0; iItemIndex < SHOP_HOST_ITEM_MAX_NUM; ++iItemIndex) + { + CPythonShop::Instance().SetItemData(iItemIndex, pShopStartPacket->items[iItemIndex]); + } + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "StartShop", Py_BuildValue("(i)", dwVID)); + } + break; + + case SHOP_SUBHEADER_GC_START_EX: + { + CPythonShop::Instance().Clear(); + + TPacketGCShopStartEx * pShopStartPacket = (TPacketGCShopStartEx *)&vecBuffer[0]; + size_t read_point = sizeof(TPacketGCShopStartEx); + + DWORD dwVID = pShopStartPacket->owner_vid; + BYTE shop_tab_count = pShopStartPacket->shop_tab_count; + + CPythonShop::instance().SetTabCount(shop_tab_count); + + for (unsigned char i = 0; i < shop_tab_count; i++) + { + TPacketGCShopStartEx::TSubPacketShopTab* pPackTab = (TPacketGCShopStartEx::TSubPacketShopTab*)&vecBuffer[read_point]; + read_point += sizeof(TPacketGCShopStartEx::TSubPacketShopTab); + + CPythonShop::instance().SetTabCoinType(i, pPackTab->coin_type); + CPythonShop::instance().SetTabName(i, pPackTab->name); + + struct packet_shop_item* item = &pPackTab->items[0]; + + for (BYTE j = 0; j < SHOP_HOST_ITEM_MAX_NUM; j++) + { + TShopItemData* itemData = (item + j); + CPythonShop::Instance().SetItemData(i, j, *itemData); + } + } + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "StartShop", Py_BuildValue("(i)", dwVID)); + } + break; + + + case SHOP_SUBHEADER_GC_END: + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "EndShop", Py_BuildValue("()")); + break; + + case SHOP_SUBHEADER_GC_UPDATE_ITEM: + { + TPacketGCShopUpdateItem * pShopUpdateItemPacket = (TPacketGCShopUpdateItem *)&vecBuffer[0]; + CPythonShop::Instance().SetItemData(pShopUpdateItemPacket->pos, pShopUpdateItemPacket->item); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshShop", Py_BuildValue("()")); + } + break; + + case SHOP_SUBHEADER_GC_UPDATE_PRICE: + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "SetShopSellingPrice", Py_BuildValue("(i)", *(int *)&vecBuffer[0])); + break; + + case SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY: + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnShopError", Py_BuildValue("(s)", "NOT_ENOUGH_MONEY")); + break; + + case SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY_EX: + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnShopError", Py_BuildValue("(s)", "NOT_ENOUGH_MONEY_EX")); + break; + + case SHOP_SUBHEADER_GC_SOLDOUT: + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnShopError", Py_BuildValue("(s)", "SOLDOUT")); + break; + + case SHOP_SUBHEADER_GC_INVENTORY_FULL: + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnShopError", Py_BuildValue("(s)", "INVENTORY_FULL")); + break; + + case SHOP_SUBHEADER_GC_INVALID_POS: + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnShopError", Py_BuildValue("(s)", "INVALID_POS")); + break; + + default: + TraceError("CPythonNetworkStream::RecvShopPacket: Unknown subheader\n"); + break; + } + + return true; +} + +bool CPythonNetworkStream::RecvExchangePacket() +{ + TPacketGCExchange exchange_packet; + + if (!Recv(sizeof(exchange_packet), &exchange_packet)) + return false; + + switch (exchange_packet.subheader) + { + case EXCHANGE_SUBHEADER_GC_START: + CPythonExchange::Instance().Clear(); + CPythonExchange::Instance().Start(); + CPythonExchange::Instance().SetSelfName(CPythonPlayer::Instance().GetName()); + + { + CInstanceBase * pCharacterInstance = CPythonCharacterManager::Instance().GetInstancePtr(exchange_packet.arg1); + + if (pCharacterInstance) + CPythonExchange::Instance().SetTargetName(pCharacterInstance->GetNameString()); + } + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "StartExchange", Py_BuildValue("()")); + break; + + case EXCHANGE_SUBHEADER_GC_ITEM_ADD: + if (exchange_packet.is_me) + { + int iSlotIndex = exchange_packet.arg2.cell; + CPythonExchange::Instance().SetItemToSelf(iSlotIndex, exchange_packet.arg1, (BYTE) exchange_packet.arg3); + for (int i = 0; i < ITEM_SOCKET_SLOT_MAX_NUM; ++i) + CPythonExchange::Instance().SetItemMetinSocketToSelf(iSlotIndex, i, exchange_packet.alValues[i]); + for (int j = 0; j < ITEM_ATTRIBUTE_SLOT_MAX_NUM; ++j) + CPythonExchange::Instance().SetItemAttributeToSelf(iSlotIndex, j, exchange_packet.aAttr[j].bType, exchange_packet.aAttr[j].sValue); + } + else + { + int iSlotIndex = exchange_packet.arg2.cell; + CPythonExchange::Instance().SetItemToTarget(iSlotIndex, exchange_packet.arg1, (BYTE) exchange_packet.arg3); + for (int i = 0; i < ITEM_SOCKET_SLOT_MAX_NUM; ++i) + CPythonExchange::Instance().SetItemMetinSocketToTarget(iSlotIndex, i, exchange_packet.alValues[i]); + for (int j = 0; j < ITEM_ATTRIBUTE_SLOT_MAX_NUM; ++j) + CPythonExchange::Instance().SetItemAttributeToTarget(iSlotIndex, j, exchange_packet.aAttr[j].bType, exchange_packet.aAttr[j].sValue); + } + + __RefreshExchangeWindow(); + __RefreshInventoryWindow(); + break; + + case EXCHANGE_SUBHEADER_GC_ITEM_DEL: + if (exchange_packet.is_me) + { + CPythonExchange::Instance().DelItemOfSelf((BYTE) exchange_packet.arg1); + } + else + { + CPythonExchange::Instance().DelItemOfTarget((BYTE) exchange_packet.arg1); + } + __RefreshExchangeWindow(); + __RefreshInventoryWindow(); + break; + + case EXCHANGE_SUBHEADER_GC_ELK_ADD: + if (exchange_packet.is_me) + CPythonExchange::Instance().SetElkToSelf(exchange_packet.arg1); + else + CPythonExchange::Instance().SetElkToTarget(exchange_packet.arg1); + + __RefreshExchangeWindow(); + break; + + case EXCHANGE_SUBHEADER_GC_ACCEPT: + if (exchange_packet.is_me) + { + CPythonExchange::Instance().SetAcceptToSelf((BYTE) exchange_packet.arg1); + } + else + { + CPythonExchange::Instance().SetAcceptToTarget((BYTE) exchange_packet.arg1); + } + __RefreshExchangeWindow(); + break; + + case EXCHANGE_SUBHEADER_GC_END: + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "EndExchange", Py_BuildValue("()")); + __RefreshInventoryWindow(); + CPythonExchange::Instance().End(); + break; + + case EXCHANGE_SUBHEADER_GC_ALREADY: + Tracef("trade_already"); + break; + + case EXCHANGE_SUBHEADER_GC_LESS_ELK: + Tracef("trade_less_elk"); + break; + }; + + return true; +} + +bool CPythonNetworkStream::RecvQuestInfoPacket() +{ + TPacketGCQuestInfo QuestInfo; + + if (!Peek(sizeof(TPacketGCQuestInfo), &QuestInfo)) + { + Tracen("Recv Quest Info Packet Error #1"); + return false; + } + + if (!Peek(QuestInfo.size)) + { + Tracen("Recv Quest Info Packet Error #2"); + return false; + } + + Recv(sizeof(TPacketGCQuestInfo)); + + const BYTE & c_rFlag = QuestInfo.flag; + + enum + { + QUEST_PACKET_TYPE_NONE, + QUEST_PACKET_TYPE_BEGIN, + QUEST_PACKET_TYPE_UPDATE, + QUEST_PACKET_TYPE_END, + }; + + BYTE byQuestPacketType = QUEST_PACKET_TYPE_NONE; + + if (0 != (c_rFlag & QUEST_SEND_IS_BEGIN)) + { + BYTE isBegin; + if (!Recv(sizeof(isBegin), &isBegin)) + return false; + + if (isBegin) + byQuestPacketType = QUEST_PACKET_TYPE_BEGIN; + else + byQuestPacketType = QUEST_PACKET_TYPE_END; + } + else + { + byQuestPacketType = QUEST_PACKET_TYPE_UPDATE; + } + + // Recv Data Start + char szTitle[30 + 1] = ""; + char szClockName[16 + 1] = ""; + int iClockValue = 0; + char szCounterName[16 + 1] = ""; + int iCounterValue = 0; + char szIconFileName[24 + 1] = ""; + + if (0 != (c_rFlag & QUEST_SEND_TITLE)) + { + if (!Recv(sizeof(szTitle), &szTitle)) + return false; + + szTitle[30]='\0'; + } + if (0 != (c_rFlag & QUEST_SEND_CLOCK_NAME)) + { + if (!Recv(sizeof(szClockName), &szClockName)) + return false; + + szClockName[16]='\0'; + } + if (0 != (c_rFlag & QUEST_SEND_CLOCK_VALUE)) + { + if (!Recv(sizeof(iClockValue), &iClockValue)) + return false; + } + if (0 != (c_rFlag & QUEST_SEND_COUNTER_NAME)) + { + if (!Recv(sizeof(szCounterName), &szCounterName)) + return false; + + szCounterName[16]='\0'; + } + if (0 != (c_rFlag & QUEST_SEND_COUNTER_VALUE)) + { + if (!Recv(sizeof(iCounterValue), &iCounterValue)) + return false; + } + if (0 != (c_rFlag & QUEST_SEND_ICON_FILE)) + { + if (!Recv(sizeof(szIconFileName), &szIconFileName)) + return false; + + szIconFileName[24]='\0'; + } + // Recv Data End + + CPythonQuest& rkQuest=CPythonQuest::Instance(); + + // Process Start + if (QUEST_PACKET_TYPE_END == byQuestPacketType) + { + rkQuest.DeleteQuestInstance(QuestInfo.index); + } + else if (QUEST_PACKET_TYPE_UPDATE == byQuestPacketType) + { + if (!rkQuest.IsQuest(QuestInfo.index)) + { + rkQuest.MakeQuest(QuestInfo.index); + } + + if (strlen(szTitle) > 0) + rkQuest.SetQuestTitle(QuestInfo.index, szTitle); + if (strlen(szClockName) > 0) + rkQuest.SetQuestClockName(QuestInfo.index, szClockName); + if (strlen(szCounterName) > 0) + rkQuest.SetQuestCounterName(QuestInfo.index, szCounterName); + if (strlen(szIconFileName) > 0) + rkQuest.SetQuestIconFileName(QuestInfo.index, szIconFileName); + + if (c_rFlag & QUEST_SEND_CLOCK_VALUE) + rkQuest.SetQuestClockValue(QuestInfo.index, iClockValue); + if (c_rFlag & QUEST_SEND_COUNTER_VALUE) + rkQuest.SetQuestCounterValue(QuestInfo.index, iCounterValue); + } + else if (QUEST_PACKET_TYPE_BEGIN == byQuestPacketType) + { + CPythonQuest::SQuestInstance QuestInstance; + QuestInstance.dwIndex = QuestInfo.index; + QuestInstance.strTitle = szTitle; + QuestInstance.strClockName = szClockName; + QuestInstance.iClockValue = iClockValue; + QuestInstance.strCounterName = szCounterName; + QuestInstance.iCounterValue = iCounterValue; + QuestInstance.strIconFileName = szIconFileName; + CPythonQuest::Instance().RegisterQuestInstance(QuestInstance); + } + // Process Start End + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshQuest", Py_BuildValue("()")); + return true; +} + +bool CPythonNetworkStream::RecvQuestConfirmPacket() +{ + TPacketGCQuestConfirm kQuestConfirmPacket; + if (!Recv(sizeof(kQuestConfirmPacket), &kQuestConfirmPacket)) + { + Tracen("RecvQuestConfirmPacket Error"); + return false; + } + + PyObject * poArg = Py_BuildValue("(sii)", kQuestConfirmPacket.msg, kQuestConfirmPacket.timeout, kQuestConfirmPacket.requestPID); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_OnQuestConfirm", poArg); + return true; +} + +bool CPythonNetworkStream::RecvRequestMakeGuild() +{ + TPacketGCBlank blank; + if (!Recv(sizeof(blank), &blank)) + { + Tracen("RecvRequestMakeGuild Packet Error"); + return false; + } + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "AskGuildName", Py_BuildValue("()")); + + return true; +} + +void CPythonNetworkStream::ToggleGameDebugInfo() +{ + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "ToggleDebugInfo", Py_BuildValue("()")); +} + +bool CPythonNetworkStream::SendExchangeStartPacket(DWORD vid) +{ + if (!__CanActMainInstance()) + return true; + + TPacketCGExchange packet; + + packet.header = HEADER_CG_EXCHANGE; + packet.subheader = EXCHANGE_SUBHEADER_CG_START; + packet.arg1 = vid; + + if (!Send(sizeof(packet), &packet)) + { + Tracef("send_trade_start_packet Error\n"); + return false; + } + + Tracef("send_trade_start_packet vid %d \n", vid); + return SendSequence(); +} + +bool CPythonNetworkStream::SendExchangeElkAddPacket(DWORD elk) +{ + if (!__CanActMainInstance()) + return true; + + TPacketCGExchange packet; + + packet.header = HEADER_CG_EXCHANGE; + packet.subheader = EXCHANGE_SUBHEADER_CG_ELK_ADD; + packet.arg1 = elk; + + if (!Send(sizeof(packet), &packet)) + { + Tracef("send_trade_elk_add_packet Error\n"); + return false; + } + + return SendSequence(); +} + +bool CPythonNetworkStream::SendExchangeItemAddPacket(TItemPos ItemPos, BYTE byDisplayPos) +{ + if (!__CanActMainInstance()) + return true; + + TPacketCGExchange packet; + + packet.header = HEADER_CG_EXCHANGE; + packet.subheader = EXCHANGE_SUBHEADER_CG_ITEM_ADD; + packet.Pos = ItemPos; + packet.arg2 = byDisplayPos; + + if (!Send(sizeof(packet), &packet)) + { + Tracef("send_trade_item_add_packet Error\n"); + return false; + } + + return SendSequence(); +} + +bool CPythonNetworkStream::SendExchangeItemDelPacket(BYTE pos) +{ + assert(!"Can't be called function - CPythonNetworkStream::SendExchangeItemDelPacket"); + return true; + + if (!__CanActMainInstance()) + return true; + + TPacketCGExchange packet; + + packet.header = HEADER_CG_EXCHANGE; + packet.subheader = EXCHANGE_SUBHEADER_CG_ITEM_DEL; + packet.arg1 = pos; + + if (!Send(sizeof(packet), &packet)) + { + Tracef("send_trade_item_del_packet Error\n"); + return false; + } + + return SendSequence(); +} + +bool CPythonNetworkStream::SendExchangeAcceptPacket() +{ + if (!__CanActMainInstance()) + return true; + + TPacketCGExchange packet; + + packet.header = HEADER_CG_EXCHANGE; + packet.subheader = EXCHANGE_SUBHEADER_CG_ACCEPT; + + if (!Send(sizeof(packet), &packet)) + { + Tracef("send_trade_accept_packet Error\n"); + return false; + } + + return SendSequence(); +} + +bool CPythonNetworkStream::SendExchangeExitPacket() +{ + if (!__CanActMainInstance()) + return true; + + TPacketCGExchange packet; + + packet.header = HEADER_CG_EXCHANGE; + packet.subheader = EXCHANGE_SUBHEADER_CG_CANCEL; + + if (!Send(sizeof(packet), &packet)) + { + Tracef("send_trade_exit_packet Error\n"); + return false; + } + + return SendSequence(); +} + +// PointReset ӽ +bool CPythonNetworkStream::SendPointResetPacket() +{ + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "StartPointReset", Py_BuildValue("()")); + return true; +} + +bool CPythonNetworkStream::__IsPlayerAttacking() +{ + CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance(); + CInstanceBase* pkInstMain=rkChrMgr.GetMainInstancePtr(); + if (!pkInstMain) + return false; + + if (!pkInstMain->IsAttacking()) + return false; + + return true; +} + +bool CPythonNetworkStream::RecvScriptPacket() +{ + TPacketGCScript ScriptPacket; + + if (!Recv(sizeof(TPacketGCScript), &ScriptPacket)) + { + TraceError("RecvScriptPacket_RecvError"); + return false; + } + + if (ScriptPacket.size < sizeof(TPacketGCScript)) + { + TraceError("RecvScriptPacket_SizeError"); + return false; + } + + ScriptPacket.size -= sizeof(TPacketGCScript); + + static std::string str; + str = ""; + str.resize(ScriptPacket.size+1); + + if (!Recv(ScriptPacket.size, &str[0])) + return false; + + str[str.size()-1] = '\0'; + + int iIndex = CPythonEventManager::Instance().RegisterEventSetFromString(str); + + if (-1 != iIndex) + { + CPythonEventManager::Instance().SetVisibleLineCount(iIndex, 30); + CPythonNetworkStream::Instance().OnScriptEventStart(ScriptPacket.skin,iIndex); + } + + return true; +} + +bool CPythonNetworkStream::SendScriptAnswerPacket(int iAnswer) +{ + TPacketCGScriptAnswer ScriptAnswer; + + ScriptAnswer.header = HEADER_CG_SCRIPT_ANSWER; + ScriptAnswer.answer = (BYTE) iAnswer; + if (!Send(sizeof(TPacketCGScriptAnswer), &ScriptAnswer)) + { + Tracen("Send Script Answer Packet Error"); + return false; + } + + return SendSequence(); +} + +bool CPythonNetworkStream::SendScriptButtonPacket(unsigned int iIndex) +{ + TPacketCGScriptButton ScriptButton; + + ScriptButton.header = HEADER_CG_SCRIPT_BUTTON; + ScriptButton.idx = iIndex; + if (!Send(sizeof(TPacketCGScriptButton), &ScriptButton)) + { + Tracen("Send Script Button Packet Error"); + return false; + } + + return SendSequence(); +} + +bool CPythonNetworkStream::SendAnswerMakeGuildPacket(const char * c_szName) +{ + TPacketCGAnswerMakeGuild Packet; + + Packet.header = HEADER_CG_ANSWER_MAKE_GUILD; + strncpy(Packet.guild_name, c_szName, GUILD_NAME_MAX_LEN); + Packet.guild_name[GUILD_NAME_MAX_LEN] = '\0'; + + if (!Send(sizeof(Packet), &Packet)) + { + Tracen("SendAnswerMakeGuild Packet Error"); + return false; + } + +// Tracef(" SendAnswerMakeGuildPacket : %s", c_szName); + return SendSequence(); +} + +bool CPythonNetworkStream::SendQuestInputStringPacket(const char * c_szString) +{ + TPacketCGQuestInputString Packet; + Packet.bHeader = HEADER_CG_QUEST_INPUT_STRING; + strncpy(Packet.szString, c_szString, QUEST_INPUT_STRING_MAX_NUM); + + if (!Send(sizeof(Packet), &Packet)) + { + Tracen("SendQuestInputStringPacket Error"); + return false; + } + + return SendSequence(); +} + +bool CPythonNetworkStream::SendQuestConfirmPacket(BYTE byAnswer, DWORD dwPID) +{ + TPacketCGQuestConfirm kPacket; + kPacket.header = HEADER_CG_QUEST_CONFIRM; + kPacket.answer = byAnswer; + kPacket.requestPID = dwPID; + + if (!Send(sizeof(kPacket), &kPacket)) + { + Tracen("SendQuestConfirmPacket Error"); + return false; + } + + Tracenf(" SendQuestConfirmPacket : %d, %d", byAnswer, dwPID); + return SendSequence(); +} + +bool CPythonNetworkStream::RecvSkillCoolTimeEnd() +{ + TPacketGCSkillCoolTimeEnd kPacketSkillCoolTimeEnd; + if (!Recv(sizeof(kPacketSkillCoolTimeEnd), &kPacketSkillCoolTimeEnd)) + { + Tracen("CPythonNetworkStream::RecvSkillCoolTimeEnd - RecvError"); + return false; + } + + CPythonPlayer::Instance().EndSkillCoolTime(kPacketSkillCoolTimeEnd.bSkill); + + return true; +} + +bool CPythonNetworkStream::RecvSkillLevel() +{ + assert(!"CPythonNetworkStream::RecvSkillLevel - ʴ Լ"); + TPacketGCSkillLevel packet; + if (!Recv(sizeof(TPacketGCSkillLevel), &packet)) + { + Tracen("CPythonNetworkStream::RecvSkillLevel - RecvError"); + return false; + } + + DWORD dwSlotIndex; + + CPythonPlayer& rkPlayer=CPythonPlayer::Instance(); + for (int i = 0; i < SKILL_MAX_NUM; ++i) + { + if (rkPlayer.GetSkillSlotIndex(i, &dwSlotIndex)) + rkPlayer.SetSkillLevel(dwSlotIndex, packet.abSkillLevels[i]); + } + + __RefreshSkillWindow(); + __RefreshStatus(); + Tracef(" >> RecvSkillLevel\n"); + return true; +} + +bool CPythonNetworkStream::RecvSkillLevelNew() +{ + TPacketGCSkillLevelNew packet; + + if (!Recv(sizeof(TPacketGCSkillLevelNew), &packet)) + { + Tracen("CPythonNetworkStream::RecvSkillLevelNew - RecvError"); + return false; + } + + CPythonPlayer& rkPlayer=CPythonPlayer::Instance(); + + rkPlayer.SetSkill(7, 0); + rkPlayer.SetSkill(8, 0); + + for (int i = 0; i < SKILL_MAX_NUM; ++i) + { + TPlayerSkill & rPlayerSkill = packet.skills[i]; + + if (i >= 112 && i <= 115 && rPlayerSkill.bLevel) + rkPlayer.SetSkill(7, i); + + if (i >= 116 && i <= 119 && rPlayerSkill.bLevel) + rkPlayer.SetSkill(8, i); + + rkPlayer.SetSkillLevel_(i, rPlayerSkill.bMasterType, rPlayerSkill.bLevel); + } + + __RefreshSkillWindow(); + __RefreshStatus(); + //Tracef(" >> RecvSkillLevelNew\n"); + return true; +} + + +bool CPythonNetworkStream::RecvDamageInfoPacket() +{ + TPacketGCDamageInfo DamageInfoPacket; + + if (!Recv(sizeof(TPacketGCDamageInfo), &DamageInfoPacket)) + { + Tracen("Recv Target Packet Error"); + return false; + } + + CInstanceBase * pInstTarget = CPythonCharacterManager::Instance().GetInstancePtr(DamageInfoPacket.dwVID); + bool bSelf = (pInstTarget == CPythonCharacterManager::Instance().GetMainInstancePtr()); + bool bTarget = (pInstTarget==m_pInstTarget); + if (pInstTarget) + { + if(DamageInfoPacket.damage >= 0) + pInstTarget->AddDamageEffect(DamageInfoPacket.damage,DamageInfoPacket.flag,bSelf,bTarget); + else + TraceError("Damage is equal or below 0."); + } + + return true; +} +bool CPythonNetworkStream::RecvTargetPacket() +{ + TPacketGCTarget TargetPacket; + + if (!Recv(sizeof(TPacketGCTarget), &TargetPacket)) + { + Tracen("Recv Target Packet Error"); + return false; + } + + CInstanceBase * pInstPlayer = CPythonCharacterManager::Instance().GetMainInstancePtr(); + CInstanceBase * pInstTarget = CPythonCharacterManager::Instance().GetInstancePtr(TargetPacket.dwVID); + if (pInstPlayer && pInstTarget) + { + if (!pInstTarget->IsDead()) + { + if (pInstTarget->IsPC() || pInstTarget->IsBuilding()) + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "CloseTargetBoardIfDifferent", Py_BuildValue("(i)", TargetPacket.dwVID)); + else if (pInstPlayer->CanViewTargetHP(*pInstTarget)) + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "SetHPTargetBoard", Py_BuildValue("(ii)", TargetPacket.dwVID, TargetPacket.bHPPercent)); + else + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "CloseTargetBoard", Py_BuildValue("()")); + + m_pInstTarget = pInstTarget; + } + } + else + { + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "CloseTargetBoard", Py_BuildValue("()")); + } + + return true; +} + +bool CPythonNetworkStream::RecvMountPacket() +{ + TPacketGCMount MountPacket; + + if (!Recv(sizeof(TPacketGCMount), &MountPacket)) + { + Tracen("Recv Mount Packet Error"); + return false; + } + + CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetInstancePtr(MountPacket.vid); + + if (pInstance) + { + // Mount + if (0 != MountPacket.mount_vid) + { +// pInstance->Ride(MountPacket.pos, MountPacket.mount_vid); + } + // Unmount + else + { +// pInstance->Unride(MountPacket.pos, MountPacket.x, MountPacket.y); + } + } + + if (CPythonPlayer::Instance().IsMainCharacterIndex(MountPacket.vid)) + { +// CPythonPlayer::Instance().SetRidingVehicleIndex(MountPacket.mount_vid); + } + + return true; +} + +bool CPythonNetworkStream::RecvChangeSpeedPacket() +{ + TPacketGCChangeSpeed SpeedPacket; + + if (!Recv(sizeof(TPacketGCChangeSpeed), &SpeedPacket)) + { + Tracen("Recv Speed Packet Error"); + return false; + } + + CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetInstancePtr(SpeedPacket.vid); + + if (!pInstance) + return true; + +// pInstance->SetWalkSpeed(SpeedPacket.walking_speed); +// pInstance->SetRunSpeed(SpeedPacket.running_speed); + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Recv + +bool CPythonNetworkStream::SendAttackPacket(UINT uMotAttack, DWORD dwVIDVictim) +{ + if (!__CanActMainInstance()) + return true; + +#ifdef ATTACK_TIME_LOG + static DWORD prevTime = timeGetTime(); + DWORD curTime = timeGetTime(); + TraceError("TIME: %.4f(%.4f) ATTACK_PACKET: %d TARGET: %d", curTime/1000.0f, (curTime-prevTime)/1000.0f, uMotAttack, dwVIDVictim); + prevTime = curTime; +#endif + + TPacketCGAttack kPacketAtk; + + kPacketAtk.header = HEADER_CG_ATTACK; + kPacketAtk.bType = uMotAttack; + kPacketAtk.dwVictimVID = dwVIDVictim; + + if (!SendSpecial(sizeof(kPacketAtk), &kPacketAtk)) + { + Tracen("Send Battle Attack Packet Error"); + return false; + } + + return SendSequence(); +} + +bool CPythonNetworkStream::SendSpecial(int nLen, void * pvBuf) +{ + BYTE bHeader = *(BYTE *) pvBuf; + + switch (bHeader) + { + case HEADER_CG_ATTACK: + { + TPacketCGAttack * pkPacketAtk = (TPacketCGAttack *) pvBuf; + pkPacketAtk->bCRCMagicCubeProcPiece = GetProcessCRCMagicCubePiece(); + pkPacketAtk->bCRCMagicCubeFilePiece = GetProcessCRCMagicCubePiece(); + return Send(nLen, pvBuf); + } + break; + } + + return Send(nLen, pvBuf); +} + +bool CPythonNetworkStream::RecvAddFlyTargetingPacket() +{ + TPacketGCFlyTargeting kPacket; + if (!Recv(sizeof(kPacket), &kPacket)) + return false; + + __GlobalPositionToLocalPosition(kPacket.lX, kPacket.lY); + + Tracef("VID [%d] Ÿ ߰ \n",kPacket.dwShooterVID); + + CPythonCharacterManager & rpcm = CPythonCharacterManager::Instance(); + + CInstanceBase * pShooter = rpcm.GetInstancePtr(kPacket.dwShooterVID); + + if (!pShooter) + { +#ifndef _DEBUG + TraceError("CPythonNetworkStream::RecvFlyTargetingPacket() - dwShooterVID[%d] NOT EXIST", kPacket.dwShooterVID); +#endif + return true; + } + + CInstanceBase * pTarget = rpcm.GetInstancePtr(kPacket.dwTargetVID); + + if (kPacket.dwTargetVID && pTarget) + { + pShooter->GetGraphicThingInstancePtr()->AddFlyTarget(pTarget->GetGraphicThingInstancePtr()); + } + else + { + float h = CPythonBackground::Instance().GetHeight(kPacket.lX,kPacket.lY) + 60.0f; // TEMPORARY HEIGHT + pShooter->GetGraphicThingInstancePtr()->AddFlyTarget(D3DXVECTOR3(kPacket.lX,kPacket.lY,h)); + //pShooter->GetGraphicThingInstancePtr()->SetFlyTarget(kPacket.kPPosTarget.x,kPacket.kPPosTarget.y,); + } + + return true; +} + +bool CPythonNetworkStream::RecvFlyTargetingPacket() +{ + TPacketGCFlyTargeting kPacket; + if (!Recv(sizeof(kPacket), &kPacket)) + return false; + + __GlobalPositionToLocalPosition(kPacket.lX, kPacket.lY); + + //Tracef("CPythonNetworkStream::RecvFlyTargetingPacket - VID [%d]\n",kPacket.dwShooterVID); + + CPythonCharacterManager & rpcm = CPythonCharacterManager::Instance(); + + CInstanceBase * pShooter = rpcm.GetInstancePtr(kPacket.dwShooterVID); + + if (!pShooter) + { +#ifdef _DEBUG + TraceError("CPythonNetworkStream::RecvFlyTargetingPacket() - dwShooterVID[%d] NOT EXIST", kPacket.dwShooterVID); +#endif + return true; + } + + CInstanceBase * pTarget = rpcm.GetInstancePtr(kPacket.dwTargetVID); + + if (kPacket.dwTargetVID && pTarget) + { + pShooter->GetGraphicThingInstancePtr()->SetFlyTarget(pTarget->GetGraphicThingInstancePtr()); + } + else + { + float h = CPythonBackground::Instance().GetHeight(kPacket.lX, kPacket.lY) + 60.0f; // TEMPORARY HEIGHT + pShooter->GetGraphicThingInstancePtr()->SetFlyTarget(D3DXVECTOR3(kPacket.lX,kPacket.lY,h)); + //pShooter->GetGraphicThingInstancePtr()->SetFlyTarget(kPacket.kPPosTarget.x,kPacket.kPPosTarget.y,); + } + + return true; +} + +bool CPythonNetworkStream::SendShootPacket(UINT uSkill) +{ + TPacketCGShoot kPacketShoot; + kPacketShoot.bHeader=HEADER_CG_SHOOT; + kPacketShoot.bType=uSkill; + + if (!Send(sizeof(kPacketShoot), &kPacketShoot)) + { + Tracen("SendShootPacket Error"); + return false; + } + + return SendSequence(); +} + +bool CPythonNetworkStream::SendAddFlyTargetingPacket(DWORD dwTargetVID, const TPixelPosition & kPPosTarget) +{ + TPacketCGFlyTargeting packet; + + //CPythonCharacterManager & rpcm = CPythonCharacterManager::Instance(); + + packet.bHeader = HEADER_CG_ADD_FLY_TARGETING; + packet.dwTargetVID = dwTargetVID; + packet.lX = kPPosTarget.x; + packet.lY = kPPosTarget.y; + + __LocalPositionToGlobalPosition(packet.lX, packet.lY); + + if (!Send(sizeof(packet), &packet)) + { + Tracen("Send FlyTargeting Packet Error"); + return false; + } + + return SendSequence(); +} + + +bool CPythonNetworkStream::SendFlyTargetingPacket(DWORD dwTargetVID, const TPixelPosition & kPPosTarget) +{ + TPacketCGFlyTargeting packet; + + //CPythonCharacterManager & rpcm = CPythonCharacterManager::Instance(); + + packet.bHeader = HEADER_CG_FLY_TARGETING; + packet.dwTargetVID = dwTargetVID; + packet.lX = kPPosTarget.x; + packet.lY = kPPosTarget.y; + + __LocalPositionToGlobalPosition(packet.lX, packet.lY); + + if (!Send(sizeof(packet), &packet)) + { + Tracen("Send FlyTargeting Packet Error"); + return false; + } + + return SendSequence(); +} + +bool CPythonNetworkStream::RecvCreateFlyPacket() +{ + TPacketGCCreateFly kPacket; + if (!Recv(sizeof(TPacketGCCreateFly), &kPacket)) + return false; + + CFlyingManager& rkFlyMgr = CFlyingManager::Instance(); + CPythonCharacterManager & rkChrMgr = CPythonCharacterManager::Instance(); + + CInstanceBase * pkStartInst = rkChrMgr.GetInstancePtr(kPacket.dwStartVID); + CInstanceBase * pkEndInst = rkChrMgr.GetInstancePtr(kPacket.dwEndVID); + if (!pkStartInst || !pkEndInst) + return true; + + rkFlyMgr.CreateIndexedFly(kPacket.bType, pkStartInst->GetGraphicThingInstancePtr(), pkEndInst->GetGraphicThingInstancePtr()); + + return true; +} + +bool CPythonNetworkStream::SendTargetPacket(DWORD dwVID) +{ + TPacketCGTarget packet; + packet.header = HEADER_CG_TARGET; + packet.dwVID = dwVID; + + if (!Send(sizeof(packet), &packet)) + { + Tracen("Send Target Packet Error"); + return false; + } + + return SendSequence(); +} + +bool CPythonNetworkStream::SendSyncPositionElementPacket(DWORD dwVictimVID, DWORD dwVictimX, DWORD dwVictimY) +{ + TPacketCGSyncPositionElement kSyncPos; + kSyncPos.dwVID=dwVictimVID; + kSyncPos.lX=dwVictimX; + kSyncPos.lY=dwVictimY; + + __LocalPositionToGlobalPosition(kSyncPos.lX, kSyncPos.lY); + + if (!Send(sizeof(kSyncPos), &kSyncPos)) + { + Tracen("CPythonNetworkStream::SendSyncPositionElementPacket - ERROR"); + return false; + } + + return true; +} + +bool CPythonNetworkStream::RecvMessenger() +{ + TPacketGCMessenger p; + if (!Recv(sizeof(p), &p)) + return false; + + int iSize = p.size - sizeof(p); + char char_name[24+1]; + + switch (p.subheader) + { + case MESSENGER_SUBHEADER_GC_LIST: + { + TPacketGCMessengerListOnline on; + while(iSize) + { + if (!Recv(sizeof(TPacketGCMessengerListOffline),&on)) + return false; + + if (!Recv(on.length, char_name)) + return false; + + char_name[on.length] = 0; + + if (on.connected & MESSENGER_CONNECTED_STATE_ONLINE) + CPythonMessenger::Instance().OnFriendLogin(char_name); + else + CPythonMessenger::Instance().OnFriendLogout(char_name); + + if (on.connected & MESSENGER_CONNECTED_STATE_MOBILE) + CPythonMessenger::Instance().SetMobile(char_name, TRUE); + + iSize -= sizeof(TPacketGCMessengerListOffline); + iSize -= on.length; + } + break; + } + + case MESSENGER_SUBHEADER_GC_LOGIN: + { + TPacketGCMessengerLogin p; + if (!Recv(sizeof(p),&p)) + return false; + if (!Recv(p.length, char_name)) + return false; + char_name[p.length] = 0; + CPythonMessenger::Instance().OnFriendLogin(char_name); + __RefreshTargetBoardByName(char_name); + break; + } + + case MESSENGER_SUBHEADER_GC_LOGOUT: + { + TPacketGCMessengerLogout logout; + if (!Recv(sizeof(logout),&logout)) + return false; + if (!Recv(logout.length, char_name)) + return false; + char_name[logout.length] = 0; + CPythonMessenger::Instance().OnFriendLogout(char_name); + break; + } + + case MESSENGER_SUBHEADER_GC_MOBILE: + { + BYTE byState; // ȣ ÷ + BYTE byLength; + if (!Recv(sizeof(byState), &byState)) + return false; + if (!Recv(sizeof(byLength), &byLength)) + return false; + if (!Recv(byLength, char_name)) + return false; + char_name[byLength] = 0; + CPythonMessenger::Instance().SetMobile(char_name, byState); + break; + } + } + return true; +} + +////////////////////////////////////////////////////////////////////////// +// Party + +bool CPythonNetworkStream::SendPartyInvitePacket(DWORD dwVID) +{ + TPacketCGPartyInvite kPartyInvitePacket; + kPartyInvitePacket.header = HEADER_CG_PARTY_INVITE; + kPartyInvitePacket.vid = dwVID; + + if (!Send(sizeof(kPartyInvitePacket), &kPartyInvitePacket)) + { + Tracenf("CPythonNetworkStream::SendPartyInvitePacket [%ud] - PACKET SEND ERROR", dwVID); + return false; + } + + Tracef(" << SendPartyInvitePacket : %d\n", dwVID); + return SendSequence(); +} + +bool CPythonNetworkStream::SendPartyInviteAnswerPacket(DWORD dwLeaderVID, BYTE byAnswer) +{ + TPacketCGPartyInviteAnswer kPartyInviteAnswerPacket; + kPartyInviteAnswerPacket.header = HEADER_CG_PARTY_INVITE_ANSWER; + kPartyInviteAnswerPacket.leader_pid = dwLeaderVID; + kPartyInviteAnswerPacket.accept = byAnswer; + + if (!Send(sizeof(kPartyInviteAnswerPacket), &kPartyInviteAnswerPacket)) + { + Tracenf("CPythonNetworkStream::SendPartyInviteAnswerPacket [%ud %ud] - PACKET SEND ERROR", dwLeaderVID, byAnswer); + return false; + } + + Tracef(" << SendPartyInviteAnswerPacket : %d, %d\n", dwLeaderVID, byAnswer); + return SendSequence(); +} + +bool CPythonNetworkStream::SendPartyRemovePacket(DWORD dwPID) +{ + TPacketCGPartyRemove kPartyInviteRemove; + kPartyInviteRemove.header = HEADER_CG_PARTY_REMOVE; + kPartyInviteRemove.pid = dwPID; + + if (!Send(sizeof(kPartyInviteRemove), &kPartyInviteRemove)) + { + Tracenf("CPythonNetworkStream::SendPartyRemovePacket [%ud] - PACKET SEND ERROR", dwPID); + return false; + } + + Tracef(" << SendPartyRemovePacket : %d\n", dwPID); + return SendSequence(); +} + +bool CPythonNetworkStream::SendPartySetStatePacket(DWORD dwVID, BYTE byState, BYTE byFlag) +{ + TPacketCGPartySetState kPartySetState; + kPartySetState.byHeader = HEADER_CG_PARTY_SET_STATE; + kPartySetState.dwVID = dwVID; + kPartySetState.byState = byState; + kPartySetState.byFlag = byFlag; + + if (!Send(sizeof(kPartySetState), &kPartySetState)) + { + Tracenf("CPythonNetworkStream::SendPartySetStatePacket(%ud, %ud) - PACKET SEND ERROR", dwVID, byState); + return false; + } + + Tracef(" << SendPartySetStatePacket : %d, %d, %d\n", dwVID, byState, byFlag); + return SendSequence(); +} + +bool CPythonNetworkStream::SendPartyUseSkillPacket(BYTE bySkillIndex, DWORD dwVID) +{ + TPacketCGPartyUseSkill kPartyUseSkill; + kPartyUseSkill.byHeader = HEADER_CG_PARTY_USE_SKILL; + kPartyUseSkill.bySkillIndex = bySkillIndex; + kPartyUseSkill.dwTargetVID = dwVID; + + if (!Send(sizeof(kPartyUseSkill), &kPartyUseSkill)) + { + Tracenf("CPythonNetworkStream::SendPartyUseSkillPacket(%ud, %ud) - PACKET SEND ERROR", bySkillIndex, dwVID); + return false; + } + + Tracef(" << SendPartyUseSkillPacket : %d, %d\n", bySkillIndex, dwVID); + return SendSequence(); +} + +bool CPythonNetworkStream::SendPartyParameterPacket(BYTE byDistributeMode) +{ + TPacketCGPartyParameter kPartyParameter; + kPartyParameter.bHeader = HEADER_CG_PARTY_PARAMETER; + kPartyParameter.bDistributeMode = byDistributeMode; + + if (!Send(sizeof(kPartyParameter), &kPartyParameter)) + { + Tracenf("CPythonNetworkStream::SendPartyParameterPacket(%d) - PACKET SEND ERROR", byDistributeMode); + return false; + } + + Tracef(" << SendPartyParameterPacket : %d\n", byDistributeMode); + return SendSequence(); +} + +bool CPythonNetworkStream::RecvPartyInvite() +{ + TPacketGCPartyInvite kPartyInvitePacket; + if (!Recv(sizeof(kPartyInvitePacket), &kPartyInvitePacket)) + return false; + + CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetInstancePtr(kPartyInvitePacket.leader_pid); + if (!pInstance) + { + TraceError(" CPythonNetworkStream::RecvPartyInvite - Failed to find leader instance [%d]\n", kPartyInvitePacket.leader_pid); + return true; + } + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RecvPartyInviteQuestion", Py_BuildValue("(is)", kPartyInvitePacket.leader_pid, pInstance->GetNameString())); + Tracef(" >> RecvPartyInvite : %d, %s\n", kPartyInvitePacket.leader_pid, pInstance->GetNameString()); + + return true; +} + +bool CPythonNetworkStream::RecvPartyAdd() +{ + TPacketGCPartyAdd kPartyAddPacket; + if (!Recv(sizeof(kPartyAddPacket), &kPartyAddPacket)) + return false; + + CPythonPlayer::Instance().AppendPartyMember(kPartyAddPacket.pid, kPartyAddPacket.name); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "AddPartyMember", Py_BuildValue("(is)", kPartyAddPacket.pid, kPartyAddPacket.name)); + Tracef(" >> RecvPartyAdd : %d, %s\n", kPartyAddPacket.pid, kPartyAddPacket.name); + + return true; +} + +bool CPythonNetworkStream::RecvPartyUpdate() +{ + TPacketGCPartyUpdate kPartyUpdatePacket; + if (!Recv(sizeof(kPartyUpdatePacket), &kPartyUpdatePacket)) + return false; + + CPythonPlayer::TPartyMemberInfo * pPartyMemberInfo; + if (!CPythonPlayer::Instance().GetPartyMemberPtr(kPartyUpdatePacket.pid, &pPartyMemberInfo)) + return true; + + BYTE byOldState = pPartyMemberInfo->byState; + + CPythonPlayer::Instance().UpdatePartyMemberInfo(kPartyUpdatePacket.pid, kPartyUpdatePacket.state, kPartyUpdatePacket.percent_hp); + for (int i = 0; i < PARTY_AFFECT_SLOT_MAX_NUM; ++i) + { + CPythonPlayer::Instance().UpdatePartyMemberAffect(kPartyUpdatePacket.pid, i, kPartyUpdatePacket.affects[i]); + } + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "UpdatePartyMemberInfo", Py_BuildValue("(i)", kPartyUpdatePacket.pid)); + + // ٲٸ, TargetBoard ư Ʈ Ѵ. + DWORD dwVID; + if (CPythonPlayer::Instance().PartyMemberPIDToVID(kPartyUpdatePacket.pid, &dwVID)) + if (byOldState != kPartyUpdatePacket.state) + { + __RefreshTargetBoardByVID(dwVID); + } + +// Tracef(" >> RecvPartyUpdate : %d, %d, %d\n", kPartyUpdatePacket.pid, kPartyUpdatePacket.state, kPartyUpdatePacket.percent_hp); + + return true; +} + +bool CPythonNetworkStream::RecvPartyRemove() +{ + TPacketGCPartyRemove kPartyRemovePacket; + if (!Recv(sizeof(kPartyRemovePacket), &kPartyRemovePacket)) + return false; + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RemovePartyMember", Py_BuildValue("(i)", kPartyRemovePacket.pid)); + Tracef(" >> RecvPartyRemove : %d\n", kPartyRemovePacket.pid); + + return true; +} + +bool CPythonNetworkStream::RecvPartyLink() +{ + TPacketGCPartyLink kPartyLinkPacket; + if (!Recv(sizeof(kPartyLinkPacket), &kPartyLinkPacket)) + return false; + + CPythonPlayer::Instance().LinkPartyMember(kPartyLinkPacket.pid, kPartyLinkPacket.vid); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "LinkPartyMember", Py_BuildValue("(ii)", kPartyLinkPacket.pid, kPartyLinkPacket.vid)); + Tracef(" >> RecvPartyLink : %d, %d\n", kPartyLinkPacket.pid, kPartyLinkPacket.vid); + + return true; +} + +bool CPythonNetworkStream::RecvPartyUnlink() +{ + TPacketGCPartyUnlink kPartyUnlinkPacket; + if (!Recv(sizeof(kPartyUnlinkPacket), &kPartyUnlinkPacket)) + return false; + + CPythonPlayer::Instance().UnlinkPartyMember(kPartyUnlinkPacket.pid); + + if (CPythonPlayer::Instance().IsMainCharacterIndex(kPartyUnlinkPacket.vid)) + { + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "UnlinkAllPartyMember", Py_BuildValue("()")); + } + else + { + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "UnlinkPartyMember", Py_BuildValue("(i)", kPartyUnlinkPacket.pid)); + } + + Tracef(" >> RecvPartyUnlink : %d, %d\n", kPartyUnlinkPacket.pid, kPartyUnlinkPacket.vid); + + return true; +} + +bool CPythonNetworkStream::RecvPartyParameter() +{ + TPacketGCPartyParameter kPartyParameterPacket; + if (!Recv(sizeof(kPartyParameterPacket), &kPartyParameterPacket)) + return false; + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "ChangePartyParameter", Py_BuildValue("(i)", kPartyParameterPacket.bDistributeMode)); + Tracef(" >> RecvPartyParameter : %d\n", kPartyParameterPacket.bDistributeMode); + + return true; +} + +// Party +////////////////////////////////////////////////////////////////////////// + + +////////////////////////////////////////////////////////////////////////// +// Guild + +bool CPythonNetworkStream::SendGuildAddMemberPacket(DWORD dwVID) +{ + TPacketCGGuild GuildPacket; + GuildPacket.byHeader = HEADER_CG_GUILD; + GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_ADD_MEMBER; + if (!Send(sizeof(GuildPacket), &GuildPacket)) + return false; + if (!Send(sizeof(dwVID), &dwVID)) + return false; + + Tracef(" SendGuildAddMemberPacket\n", dwVID); + return SendSequence(); +} + +bool CPythonNetworkStream::SendGuildRemoveMemberPacket(DWORD dwPID) +{ + TPacketCGGuild GuildPacket; + GuildPacket.byHeader = HEADER_CG_GUILD; + GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_REMOVE_MEMBER; + if (!Send(sizeof(GuildPacket), &GuildPacket)) + return false; + if (!Send(sizeof(dwPID), &dwPID)) + return false; + + Tracef(" SendGuildRemoveMemberPacket %d\n", dwPID); + return SendSequence(); +} + +bool CPythonNetworkStream::SendGuildChangeGradeNamePacket(BYTE byGradeNumber, const char * c_szName) +{ + TPacketCGGuild GuildPacket; + GuildPacket.byHeader = HEADER_CG_GUILD; + GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_CHANGE_GRADE_NAME; + if (!Send(sizeof(GuildPacket), &GuildPacket)) + return false; + if (!Send(sizeof(byGradeNumber), &byGradeNumber)) + return false; + + char szName[GUILD_GRADE_NAME_MAX_LEN+1]; + strncpy(szName, c_szName, GUILD_GRADE_NAME_MAX_LEN); + szName[GUILD_GRADE_NAME_MAX_LEN] = '\0'; + + if (!Send(sizeof(szName), &szName)) + return false; + + Tracef(" SendGuildChangeGradeNamePacket %d, %s\n", byGradeNumber, c_szName); + return SendSequence(); +} + +bool CPythonNetworkStream::SendGuildChangeGradeAuthorityPacket(BYTE byGradeNumber, BYTE byAuthority) +{ + TPacketCGGuild GuildPacket; + GuildPacket.byHeader = HEADER_CG_GUILD; + GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_CHANGE_GRADE_AUTHORITY; + if (!Send(sizeof(GuildPacket), &GuildPacket)) + return false; + if (!Send(sizeof(byGradeNumber), &byGradeNumber)) + return false; + if (!Send(sizeof(byAuthority), &byAuthority)) + return false; + + Tracef(" SendGuildChangeGradeAuthorityPacket %d, %d\n", byGradeNumber, byAuthority); + return SendSequence(); +} + +bool CPythonNetworkStream::SendGuildOfferPacket(DWORD dwExperience) +{ + TPacketCGGuild GuildPacket; + GuildPacket.byHeader = HEADER_CG_GUILD; + GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_OFFER; + if (!Send(sizeof(GuildPacket), &GuildPacket)) + return false; + if (!Send(sizeof(dwExperience), &dwExperience)) + return false; + + Tracef(" SendGuildOfferPacket %d\n", dwExperience); + return SendSequence(); +} + +bool CPythonNetworkStream::SendGuildPostCommentPacket(const char * c_szMessage) +{ + TPacketCGGuild GuildPacket; + GuildPacket.byHeader = HEADER_CG_GUILD; + GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_POST_COMMENT; + if (!Send(sizeof(GuildPacket), &GuildPacket)) + return false; + + BYTE bySize = BYTE(strlen(c_szMessage)) + 1; + if (!Send(sizeof(bySize), &bySize)) + return false; + if (!Send(bySize, c_szMessage)) + return false; + + Tracef(" SendGuildPostCommentPacket %d, %s\n", bySize, c_szMessage); + return SendSequence(); +} + +bool CPythonNetworkStream::SendGuildDeleteCommentPacket(DWORD dwIndex) +{ + TPacketCGGuild GuildPacket; + GuildPacket.byHeader = HEADER_CG_GUILD; + GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_DELETE_COMMENT; + if (!Send(sizeof(GuildPacket), &GuildPacket)) + return false; + + if (!Send(sizeof(dwIndex), &dwIndex)) + return false; + + Tracef(" SendGuildDeleteCommentPacket %d\n", dwIndex); + return SendSequence(); +} + +bool CPythonNetworkStream::SendGuildRefreshCommentsPacket(DWORD dwHighestIndex) +{ + static DWORD s_LastTime = timeGetTime() - 1001; + + if (timeGetTime() - s_LastTime < 1000) + return true; + s_LastTime = timeGetTime(); + + TPacketCGGuild GuildPacket; + GuildPacket.byHeader = HEADER_CG_GUILD; + GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_REFRESH_COMMENT; + if (!Send(sizeof(GuildPacket), &GuildPacket)) + return false; + + Tracef(" SendGuildRefreshCommentPacket %d\n", dwHighestIndex); + return SendSequence(); +} + +bool CPythonNetworkStream::SendGuildChangeMemberGradePacket(DWORD dwPID, BYTE byGrade) +{ + TPacketCGGuild GuildPacket; + GuildPacket.byHeader = HEADER_CG_GUILD; + GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_CHANGE_MEMBER_GRADE; + if (!Send(sizeof(GuildPacket), &GuildPacket)) + return false; + + if (!Send(sizeof(dwPID), &dwPID)) + return false; + if (!Send(sizeof(byGrade), &byGrade)) + return false; + + Tracef(" SendGuildChangeMemberGradePacket %d, %d\n", dwPID, byGrade); + return SendSequence(); +} + +bool CPythonNetworkStream::SendGuildUseSkillPacket(DWORD dwSkillID, DWORD dwTargetVID) +{ + TPacketCGGuild GuildPacket; + GuildPacket.byHeader = HEADER_CG_GUILD; + GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_USE_SKILL; + if (!Send(sizeof(GuildPacket), &GuildPacket)) + return false; + + if (!Send(sizeof(dwSkillID), &dwSkillID)) + return false; + if (!Send(sizeof(dwTargetVID), &dwTargetVID)) + return false; + + Tracef(" SendGuildUseSkillPacket %d, %d\n", dwSkillID, dwTargetVID); + return SendSequence(); +} + +bool CPythonNetworkStream::SendGuildChangeMemberGeneralPacket(DWORD dwPID, BYTE byFlag) +{ + TPacketCGGuild GuildPacket; + GuildPacket.byHeader = HEADER_CG_GUILD; + GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_CHANGE_MEMBER_GENERAL; + if (!Send(sizeof(GuildPacket), &GuildPacket)) + return false; + + if (!Send(sizeof(dwPID), &dwPID)) + return false; + if (!Send(sizeof(byFlag), &byFlag)) + return false; + + Tracef(" SendGuildChangeMemberGeneralFlagPacket %d, %d\n", dwPID, byFlag); + return SendSequence(); +} + +bool CPythonNetworkStream::SendGuildInviteAnswerPacket(DWORD dwGuildID, BYTE byAnswer) +{ + TPacketCGGuild GuildPacket; + GuildPacket.byHeader = HEADER_CG_GUILD; + GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_GUILD_INVITE_ANSWER; + if (!Send(sizeof(GuildPacket), &GuildPacket)) + return false; + + if (!Send(sizeof(dwGuildID), &dwGuildID)) + return false; + if (!Send(sizeof(byAnswer), &byAnswer)) + return false; + + Tracef(" SendGuildInviteAnswerPacket %d, %d\n", dwGuildID, byAnswer); + return SendSequence(); +} + +bool CPythonNetworkStream::SendGuildChargeGSPPacket(DWORD dwMoney) +{ + TPacketCGGuild GuildPacket; + GuildPacket.byHeader = HEADER_CG_GUILD; + GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_CHARGE_GSP; + if (!Send(sizeof(GuildPacket), &GuildPacket)) + return false; + + if (!Send(sizeof(dwMoney), &dwMoney)) + return false; + + Tracef(" SendGuildChargeGSPPacket %d\n", dwMoney); + return SendSequence(); +} + +bool CPythonNetworkStream::SendGuildDepositMoneyPacket(DWORD dwMoney) +{ + TPacketCGGuild GuildPacket; + GuildPacket.byHeader = HEADER_CG_GUILD; + GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_DEPOSIT_MONEY; + if (!Send(sizeof(GuildPacket), &GuildPacket)) + return false; + if (!Send(sizeof(dwMoney), &dwMoney)) + return false; + + Tracef(" SendGuildDepositMoneyPacket %d\n", dwMoney); + return SendSequence(); +} + +bool CPythonNetworkStream::SendGuildWithdrawMoneyPacket(DWORD dwMoney) +{ + TPacketCGGuild GuildPacket; + GuildPacket.byHeader = HEADER_CG_GUILD; + GuildPacket.bySubHeader = GUILD_SUBHEADER_CG_WITHDRAW_MONEY; + if (!Send(sizeof(GuildPacket), &GuildPacket)) + return false; + if (!Send(sizeof(dwMoney), &dwMoney)) + return false; + + Tracef(" SendGuildWithdrawMoneyPacket %d\n", dwMoney); + return SendSequence(); +} + +bool CPythonNetworkStream::RecvGuild() +{ + TPacketGCGuild GuildPacket; + if (!Recv(sizeof(GuildPacket), &GuildPacket)) + return false; + + switch(GuildPacket.subheader) + { + case GUILD_SUBHEADER_GC_LOGIN: + { + DWORD dwPID; + if (!Recv(sizeof(DWORD), &dwPID)) + return false; + + // Messenger + CPythonGuild::TGuildMemberData * pGuildMemberData; + if (CPythonGuild::Instance().GetMemberDataPtrByPID(dwPID, &pGuildMemberData)) + if (0 != pGuildMemberData->strName.compare(CPythonPlayer::Instance().GetName())) + CPythonMessenger::Instance().LoginGuildMember(pGuildMemberData->strName.c_str()); + + //Tracef(" %d\n", dwPID); + break; + } + case GUILD_SUBHEADER_GC_LOGOUT: + { + DWORD dwPID; + if (!Recv(sizeof(DWORD), &dwPID)) + return false; + + // Messenger + CPythonGuild::TGuildMemberData * pGuildMemberData; + if (CPythonGuild::Instance().GetMemberDataPtrByPID(dwPID, &pGuildMemberData)) + if (0 != pGuildMemberData->strName.compare(CPythonPlayer::Instance().GetName())) + CPythonMessenger::Instance().LogoutGuildMember(pGuildMemberData->strName.c_str()); + + //Tracef(" %d\n", dwPID); + break; + } + case GUILD_SUBHEADER_GC_REMOVE: + { + DWORD dwPID; + if (!Recv(sizeof(dwPID), &dwPID)) + return false; + + // Main Player DeleteGuild + if (CPythonGuild::Instance().IsMainPlayer(dwPID)) + { + CPythonGuild::Instance().Destroy(); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "DeleteGuild", Py_BuildValue("()")); + CPythonMessenger::Instance().RemoveAllGuildMember(); + __SetGuildID(0); + __RefreshMessengerWindow(); + __RefreshTargetBoard(); + __RefreshCharacterWindow(); + } + else + { + // Get Member Name + std::string strMemberName = ""; + CPythonGuild::TGuildMemberData * pData; + if (CPythonGuild::Instance().GetMemberDataPtrByPID(dwPID, &pData)) + { + strMemberName = pData->strName; + CPythonMessenger::Instance().RemoveGuildMember(pData->strName.c_str()); + } + + CPythonGuild::Instance().RemoveMember(dwPID); + + // Refresh + __RefreshTargetBoardByName(strMemberName.c_str()); + __RefreshGuildWindowMemberPage(); + } + + Tracef(" %d\n", dwPID); + break; + } + case GUILD_SUBHEADER_GC_LIST: + { + int iPacketSize = int(GuildPacket.size) - sizeof(GuildPacket); + + for (; iPacketSize > 0;) + { + TPacketGCGuildSubMember memberPacket; + if (!Recv(sizeof(memberPacket), &memberPacket)) + return false; + + char szName[CHARACTER_NAME_MAX_LEN+1] = ""; + if (memberPacket.byNameFlag) + { + if (!Recv(sizeof(szName), &szName)) + return false; + + iPacketSize -= CHARACTER_NAME_MAX_LEN+1; + } + else + { + CPythonGuild::TGuildMemberData * pMemberData; + if (CPythonGuild::Instance().GetMemberDataPtrByPID(memberPacket.pid, &pMemberData)) + { + strncpy(szName, pMemberData->strName.c_str(), CHARACTER_NAME_MAX_LEN); + } + } + + //Tracef(" %d : %s, %d (%d, %d, %d)\n", memberPacket.pid, szName, memberPacket.byGrade, memberPacket.byJob, memberPacket.byLevel, memberPacket.dwOffer); + + CPythonGuild::SGuildMemberData GuildMemberData; + GuildMemberData.dwPID = memberPacket.pid; + GuildMemberData.byGrade = memberPacket.byGrade; + GuildMemberData.strName = szName; + GuildMemberData.byJob = memberPacket.byJob; + GuildMemberData.byLevel = memberPacket.byLevel; + GuildMemberData.dwOffer = memberPacket.dwOffer; + GuildMemberData.byGeneralFlag = memberPacket.byIsGeneral; + CPythonGuild::Instance().RegisterMember(GuildMemberData); + + // Messenger + if (strcmp(szName, CPythonPlayer::Instance().GetName())) + CPythonMessenger::Instance().AppendGuildMember(szName); + + __RefreshTargetBoardByName(szName); + + iPacketSize -= sizeof(memberPacket); + } + + __RefreshGuildWindowInfoPage(); + __RefreshGuildWindowMemberPage(); + __RefreshMessengerWindow(); + __RefreshCharacterWindow(); + break; + } + case GUILD_SUBHEADER_GC_GRADE: + { + BYTE byCount; + if (!Recv(sizeof(byCount), &byCount)) + return false; + + for (BYTE i = 0; i < byCount; ++ i) + { + BYTE byIndex; + if (!Recv(sizeof(byCount), &byIndex)) + return false; + TPacketGCGuildSubGrade GradePacket; + if (!Recv(sizeof(GradePacket), &GradePacket)) + return false; + + auto data = CPythonGuild::SGuildGradeData(GradePacket.auth_flag, GradePacket.grade_name); + CPythonGuild::Instance().SetGradeData(byIndex, data); + //Tracef(" [%d/%d] : %s, %d\n", byIndex, byCount, GradePacket.grade_name, GradePacket.auth_flag); + } + __RefreshGuildWindowGradePage(); + __RefreshGuildWindowMemberPageGradeComboBox(); + break; + } + case GUILD_SUBHEADER_GC_GRADE_NAME: + { + BYTE byGradeNumber; + if (!Recv(sizeof(byGradeNumber), &byGradeNumber)) + return false; + + char szGradeName[GUILD_GRADE_NAME_MAX_LEN+1] = ""; + if (!Recv(sizeof(szGradeName), &szGradeName)) + return false; + + CPythonGuild::Instance().SetGradeName(byGradeNumber, szGradeName); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshGuildGrade", Py_BuildValue("()")); + + Tracef(" %d, %s\n", byGradeNumber, szGradeName); + __RefreshGuildWindowGradePage(); + __RefreshGuildWindowMemberPageGradeComboBox(); + break; + } + case GUILD_SUBHEADER_GC_GRADE_AUTH: + { + BYTE byGradeNumber; + if (!Recv(sizeof(byGradeNumber), &byGradeNumber)) + return false; + BYTE byAuthorityFlag; + if (!Recv(sizeof(byAuthorityFlag), &byAuthorityFlag)) + return false; + + CPythonGuild::Instance().SetGradeAuthority(byGradeNumber, byAuthorityFlag); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshGuildGrade", Py_BuildValue("()")); + + Tracef(" %d, %d\n", byGradeNumber, byAuthorityFlag); + __RefreshGuildWindowGradePage(); + break; + } + case GUILD_SUBHEADER_GC_INFO: + { + TPacketGCGuildInfo GuildInfo; + if (!Recv(sizeof(GuildInfo), &GuildInfo)) + return false; + + CPythonGuild::Instance().EnableGuild(); + CPythonGuild::TGuildInfo & rGuildInfo = CPythonGuild::Instance().GetGuildInfoRef(); + strncpy(rGuildInfo.szGuildName, GuildInfo.name, GUILD_NAME_MAX_LEN); + rGuildInfo.szGuildName[GUILD_NAME_MAX_LEN] = '\0'; + + rGuildInfo.dwGuildID = GuildInfo.guild_id; + rGuildInfo.dwMasterPID = GuildInfo.master_pid; + rGuildInfo.dwGuildLevel = GuildInfo.level; + rGuildInfo.dwCurrentExperience = GuildInfo.exp; + rGuildInfo.dwCurrentMemberCount = GuildInfo.member_count; + rGuildInfo.dwMaxMemberCount = GuildInfo.max_member_count; + rGuildInfo.dwGuildMoney = GuildInfo.gold; + rGuildInfo.bHasLand = GuildInfo.hasLand; + + //Tracef(" %s, %d, %d : %d\n", GuildInfo.name, GuildInfo.master_pid, GuildInfo.level, rGuildInfo.bHasLand); + __RefreshGuildWindowInfoPage(); + break; + } + case GUILD_SUBHEADER_GC_COMMENTS: + { + BYTE byCount; + if (!Recv(sizeof(byCount), &byCount)) + return false; + + CPythonGuild::Instance().ClearComment(); + //Tracef(" >>> Comments Count : %d\n", byCount); + + for (BYTE i = 0; i < byCount; ++i) + { + DWORD dwCommentID; + if (!Recv(sizeof(dwCommentID), &dwCommentID)) + return false; + + char szName[CHARACTER_NAME_MAX_LEN+1] = ""; + if (!Recv(sizeof(szName), &szName)) + return false; + + char szComment[GULID_COMMENT_MAX_LEN+1] = ""; + if (!Recv(sizeof(szComment), &szComment)) + return false; + + //Tracef(" [Comment-%d] : %s, %s\n", dwCommentID, szName, szComment); + CPythonGuild::Instance().RegisterComment(dwCommentID, szName, szComment); + } + + __RefreshGuildWindowBoardPage(); + break; + } + case GUILD_SUBHEADER_GC_CHANGE_EXP: + { + BYTE byLevel; + if (!Recv(sizeof(byLevel), &byLevel)) + return false; + DWORD dwEXP; + if (!Recv(sizeof(dwEXP), &dwEXP)) + return false; + CPythonGuild::Instance().SetGuildEXP(byLevel, dwEXP); + Tracef(" %d, %d\n", byLevel, dwEXP); + __RefreshGuildWindowInfoPage(); + break; + } + case GUILD_SUBHEADER_GC_CHANGE_MEMBER_GRADE: + { + DWORD dwPID; + if (!Recv(sizeof(dwPID), &dwPID)) + return false; + BYTE byGrade; + if (!Recv(sizeof(byGrade), &byGrade)) + return false; + CPythonGuild::Instance().ChangeGuildMemberGrade(dwPID, byGrade); + Tracef(" %d, %d\n", dwPID, byGrade); + __RefreshGuildWindowMemberPage(); + break; + } + case GUILD_SUBHEADER_GC_SKILL_INFO: + { + CPythonGuild::TGuildSkillData & rSkillData = CPythonGuild::Instance().GetGuildSkillDataRef(); + if (!Recv(sizeof(rSkillData.bySkillPoint), &rSkillData.bySkillPoint)) + return false; + if (!Recv(sizeof(rSkillData.bySkillLevel), rSkillData.bySkillLevel)) + return false; + if (!Recv(sizeof(rSkillData.wGuildPoint), &rSkillData.wGuildPoint)) + return false; + if (!Recv(sizeof(rSkillData.wMaxGuildPoint), &rSkillData.wMaxGuildPoint)) + return false; + + Tracef(" %d / %d, %d\n", rSkillData.bySkillPoint, rSkillData.wGuildPoint, rSkillData.wMaxGuildPoint); + __RefreshGuildWindowSkillPage(); + break; + } + case GUILD_SUBHEADER_GC_CHANGE_MEMBER_GENERAL: + { + DWORD dwPID; + if (!Recv(sizeof(dwPID), &dwPID)) + return false; + BYTE byFlag; + if (!Recv(sizeof(byFlag), &byFlag)) + return false; + + CPythonGuild::Instance().ChangeGuildMemberGeneralFlag(dwPID, byFlag); + Tracef(" %d, %d\n", dwPID, byFlag); + __RefreshGuildWindowMemberPage(); + break; + } + case GUILD_SUBHEADER_GC_GUILD_INVITE: + { + DWORD dwGuildID; + if (!Recv(sizeof(dwGuildID), &dwGuildID)) + return false; + char szGuildName[GUILD_NAME_MAX_LEN+1]; + if (!Recv(GUILD_NAME_MAX_LEN, &szGuildName)) + return false; + + szGuildName[GUILD_NAME_MAX_LEN] = 0; + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RecvGuildInviteQuestion", Py_BuildValue("(is)", dwGuildID, szGuildName)); + Tracef(" %d, %s\n", dwGuildID, szGuildName); + break; + } + case GUILD_SUBHEADER_GC_WAR: + { + TPacketGCGuildWar kGuildWar; + if (!Recv(sizeof(kGuildWar), &kGuildWar)) + return false; + + switch (kGuildWar.bWarState) + { + case GUILD_WAR_SEND_DECLARE: + Tracef(" >> GUILD_SUBHEADER_GC_WAR : GUILD_WAR_SEND_DECLARE\n"); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], + "BINARY_GuildWar_OnSendDeclare", + Py_BuildValue("(i)", kGuildWar.dwGuildOpp) + ); + break; + case GUILD_WAR_RECV_DECLARE: + Tracef(" >> GUILD_SUBHEADER_GC_WAR : GUILD_WAR_RECV_DECLARE\n"); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], + "BINARY_GuildWar_OnRecvDeclare", + Py_BuildValue("(ii)", kGuildWar.dwGuildOpp, kGuildWar.bType) + ); + break; + case GUILD_WAR_ON_WAR: + Tracef(" >> GUILD_SUBHEADER_GC_WAR : GUILD_WAR_ON_WAR : %d, %d\n", kGuildWar.dwGuildSelf, kGuildWar.dwGuildOpp); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], + "BINARY_GuildWar_OnStart", + Py_BuildValue("(ii)", kGuildWar.dwGuildSelf, kGuildWar.dwGuildOpp) + ); + CPythonGuild::Instance().StartGuildWar(kGuildWar.dwGuildOpp); + break; + case GUILD_WAR_END: + Tracef(" >> GUILD_SUBHEADER_GC_WAR : GUILD_WAR_END\n"); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], + "BINARY_GuildWar_OnEnd", + Py_BuildValue("(ii)", kGuildWar.dwGuildSelf, kGuildWar.dwGuildOpp) + ); + CPythonGuild::Instance().EndGuildWar(kGuildWar.dwGuildOpp); + break; + } + break; + } + case GUILD_SUBHEADER_GC_GUILD_NAME: + { + DWORD dwID; + char szGuildName[GUILD_NAME_MAX_LEN+1]; + + int iPacketSize = int(GuildPacket.size) - sizeof(GuildPacket); + + int nItemSize = sizeof(dwID) + GUILD_NAME_MAX_LEN; + + assert(iPacketSize%nItemSize==0 && "GUILD_SUBHEADER_GC_GUILD_NAME"); + + for (; iPacketSize > 0;) + { + if (!Recv(sizeof(dwID), &dwID)) + return false; + + if (!Recv(GUILD_NAME_MAX_LEN, &szGuildName)) + return false; + + szGuildName[GUILD_NAME_MAX_LEN] = 0; + + //Tracef(" >> GulidName [%d : %s]\n", dwID, szGuildName); + CPythonGuild::Instance().RegisterGuildName(dwID, szGuildName); + iPacketSize -= nItemSize; + } + break; + } + case GUILD_SUBHEADER_GC_GUILD_WAR_LIST: + { + DWORD dwSrcGuildID; + DWORD dwDstGuildID; + + int iPacketSize = int(GuildPacket.size) - sizeof(GuildPacket); + int nItemSize = sizeof(dwSrcGuildID) + sizeof(dwDstGuildID); + + assert(iPacketSize%nItemSize==0 && "GUILD_SUBHEADER_GC_GUILD_WAR_LIST"); + + for (; iPacketSize > 0;) + { + if (!Recv(sizeof(dwSrcGuildID), &dwSrcGuildID)) + return false; + + if (!Recv(sizeof(dwDstGuildID), &dwDstGuildID)) + return false; + + Tracef(" >> GulidWarList [%d vs %d]\n", dwSrcGuildID, dwDstGuildID); + CInstanceBase::InsertGVGKey(dwSrcGuildID, dwDstGuildID); + CPythonCharacterManager::Instance().ChangeGVG(dwSrcGuildID, dwDstGuildID); + iPacketSize -= nItemSize; + } + break; + } + case GUILD_SUBHEADER_GC_GUILD_WAR_END_LIST: + { + DWORD dwSrcGuildID; + DWORD dwDstGuildID; + + int iPacketSize = int(GuildPacket.size) - sizeof(GuildPacket); + int nItemSize = sizeof(dwSrcGuildID) + sizeof(dwDstGuildID); + + assert(iPacketSize%nItemSize==0 && "GUILD_SUBHEADER_GC_GUILD_WAR_END_LIST"); + + for (; iPacketSize > 0;) + { + + if (!Recv(sizeof(dwSrcGuildID), &dwSrcGuildID)) + return false; + + if (!Recv(sizeof(dwDstGuildID), &dwDstGuildID)) + return false; + + Tracef(" >> GulidWarEndList [%d vs %d]\n", dwSrcGuildID, dwDstGuildID); + CInstanceBase::RemoveGVGKey(dwSrcGuildID, dwDstGuildID); + CPythonCharacterManager::Instance().ChangeGVG(dwSrcGuildID, dwDstGuildID); + iPacketSize -= nItemSize; + } + break; + } + case GUILD_SUBHEADER_GC_WAR_POINT: + { + TPacketGuildWarPoint GuildWarPoint; + if (!Recv(sizeof(GuildWarPoint), &GuildWarPoint)) + return false; + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], + "BINARY_GuildWar_OnRecvPoint", + Py_BuildValue("(iii)", GuildWarPoint.dwGainGuildID, GuildWarPoint.dwOpponentGuildID, GuildWarPoint.lPoint) + ); + break; + } + case GUILD_SUBHEADER_GC_MONEY_CHANGE: + { + DWORD dwMoney; + if (!Recv(sizeof(dwMoney), &dwMoney)) + return false; + + CPythonGuild::Instance().SetGuildMoney(dwMoney); + + __RefreshGuildWindowInfoPage(); + Tracef(" >> Guild Money Change : %d\n", dwMoney); + break; + } + } + + return true; +} + +// Guild +////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////// +// Fishing + +bool CPythonNetworkStream::SendFishingPacket(int iRotation) +{ + BYTE byHeader = HEADER_CG_FISHING; + if (!Send(sizeof(byHeader), &byHeader)) + return false; + BYTE byPacketRotation = iRotation / 5; + if (!Send(sizeof(BYTE), &byPacketRotation)) + return false; + + return SendSequence(); +} + +bool CPythonNetworkStream::SendGiveItemPacket(DWORD dwTargetVID, TItemPos ItemPos, int iItemCount) +{ + TPacketCGGiveItem GiveItemPacket; + GiveItemPacket.byHeader = HEADER_CG_GIVE_ITEM; + GiveItemPacket.dwTargetVID = dwTargetVID; + GiveItemPacket.ItemPos = ItemPos; + GiveItemPacket.byItemCount = iItemCount; + + if (!Send(sizeof(GiveItemPacket), &GiveItemPacket)) + return false; + + return SendSequence(); +} + +bool CPythonNetworkStream::RecvFishing() +{ + TPacketGCFishing FishingPacket; + if (!Recv(sizeof(FishingPacket), &FishingPacket)) + return false; + + CInstanceBase * pFishingInstance = NULL; + if (FISHING_SUBHEADER_GC_FISH != FishingPacket.subheader) + { + pFishingInstance = CPythonCharacterManager::Instance().GetInstancePtr(FishingPacket.info); + if (!pFishingInstance) + return true; + } + + switch (FishingPacket.subheader) + { + case FISHING_SUBHEADER_GC_START: + pFishingInstance->StartFishing(float(FishingPacket.dir) * 5.0f); + break; + case FISHING_SUBHEADER_GC_STOP: + if (pFishingInstance->IsFishing()) + pFishingInstance->StopFishing(); + break; + case FISHING_SUBHEADER_GC_REACT: + if (pFishingInstance->IsFishing()) + { + pFishingInstance->SetFishEmoticon(); // Fish Emoticon + pFishingInstance->ReactFishing(); + } + break; + case FISHING_SUBHEADER_GC_SUCCESS: + pFishingInstance->CatchSuccess(); + break; + case FISHING_SUBHEADER_GC_FAIL: + pFishingInstance->CatchFail(); + if (pFishingInstance == CPythonCharacterManager::Instance().GetMainInstancePtr()) + { + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnFishingFailure", Py_BuildValue("()")); + } + break; + case FISHING_SUBHEADER_GC_FISH: + { + DWORD dwFishID = FishingPacket.info; + + if (0 == FishingPacket.info) + { + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnFishingNotifyUnknown", Py_BuildValue("()")); + return true; + } + + CItemData * pItemData; + if (!CItemManager::Instance().GetItemDataPointer(dwFishID, &pItemData)) + return true; + + CInstanceBase * pMainInstance = CPythonCharacterManager::Instance().GetMainInstancePtr(); + if (!pMainInstance) + return true; + + if (pMainInstance->IsFishing()) + { + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnFishingNotify", Py_BuildValue("(is)", CItemData::ITEM_TYPE_FISH == pItemData->GetType(), pItemData->GetName())); + } + else + { + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnFishingSuccess", Py_BuildValue("(is)", CItemData::ITEM_TYPE_FISH == pItemData->GetType(), pItemData->GetName())); + } + break; + } + } + + return true; +} +// Fishing +///////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////// +// Dungeon +bool CPythonNetworkStream::RecvDungeon() +{ + TPacketGCDungeon DungeonPacket; + if (!Recv(sizeof(DungeonPacket), &DungeonPacket)) + return false; + + switch (DungeonPacket.subheader) + { + case DUNGEON_SUBHEADER_GC_TIME_ATTACK_START: + { + break; + } + case DUNGEON_SUBHEADER_GC_DESTINATION_POSITION: + { + unsigned long ulx, uly; + if (!Recv(sizeof(ulx), &ulx)) + return false; + if (!Recv(sizeof(uly), &uly)) + return false; + + CPythonPlayer::Instance().SetDungeonDestinationPosition(ulx, uly); + break; + } + } + + return true; +} +// Dungeon +///////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////// +// MyShop +bool CPythonNetworkStream::SendBuildPrivateShopPacket(const char * c_szName, const std::vector & c_rSellingItemStock) +{ + TPacketCGMyShop packet; + packet.bHeader = HEADER_CG_MYSHOP; + strncpy(packet.szSign, c_szName, SHOP_SIGN_MAX_LEN); + packet.bCount = static_cast(c_rSellingItemStock.size()); + if (!Send(sizeof(packet), &packet)) + return false; + + for (std::vector::const_iterator itor = c_rSellingItemStock.begin(); itor < c_rSellingItemStock.end(); ++itor) + { + const TShopItemTable & c_rItem = *itor; + if (!Send(sizeof(c_rItem), &c_rItem)) + return false; + } + + return SendSequence(); +} + +bool CPythonNetworkStream::RecvShopSignPacket() +{ + TPacketGCShopSign p; + if (!Recv(sizeof(TPacketGCShopSign), &p)) + return false; + + CPythonPlayer& rkPlayer=CPythonPlayer::Instance(); + + if (0 == strlen(p.szSign)) + { + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], + "BINARY_PrivateShop_Disappear", + Py_BuildValue("(i)", p.dwVID) + ); + + if (rkPlayer.IsMainCharacterIndex(p.dwVID)) + rkPlayer.ClosePrivateShop(); + } + else + { + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], + "BINARY_PrivateShop_Appear", + Py_BuildValue("(is)", p.dwVID, p.szSign) + ); + + if (rkPlayer.IsMainCharacterIndex(p.dwVID)) + rkPlayer.OpenPrivateShop(); + } + + return true; +} +///////////////////////////////////////////////////////////////////////// + +bool CPythonNetworkStream::RecvTimePacket() +{ + TPacketGCTime TimePacket; + if (!Recv(sizeof(TimePacket), &TimePacket)) + return false; + + IAbstractApplication& rkApp=IAbstractApplication::GetSingleton(); + rkApp.SetServerTime(TimePacket.time); + + return true; +} + +bool CPythonNetworkStream::RecvWalkModePacket() +{ + TPacketGCWalkMode WalkModePacket; + if (!Recv(sizeof(WalkModePacket), &WalkModePacket)) + return false; + + CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetInstancePtr(WalkModePacket.vid); + if (pInstance) + { + if (WALKMODE_RUN == WalkModePacket.mode) + { + pInstance->SetRunMode(); + } + else + { + pInstance->SetWalkMode(); + } + } + + return true; +} + +bool CPythonNetworkStream::RecvChangeSkillGroupPacket() +{ + TPacketGCChangeSkillGroup ChangeSkillGroup; + if (!Recv(sizeof(ChangeSkillGroup), &ChangeSkillGroup)) + return false; + + m_dwMainActorSkillGroup = ChangeSkillGroup.skill_group; + + CPythonPlayer::Instance().NEW_ClearSkillData(); + __RefreshCharacterWindow(); + return true; +} + +void CPythonNetworkStream::__TEST_SetSkillGroupFake(int iIndex) +{ + m_dwMainActorSkillGroup = DWORD(iIndex); + + CPythonPlayer::Instance().NEW_ClearSkillData(); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshCharacter", Py_BuildValue("()")); +} + +bool CPythonNetworkStream::SendRefinePacket(BYTE byPos, BYTE byType) +{ + TPacketCGRefine kRefinePacket; + kRefinePacket.header = HEADER_CG_REFINE; + kRefinePacket.pos = byPos; + kRefinePacket.type = byType; + + if (!Send(sizeof(kRefinePacket), &kRefinePacket)) + return false; + + return SendSequence(); +} + +bool CPythonNetworkStream::SendSelectItemPacket(DWORD dwItemPos) +{ + TPacketCGScriptSelectItem kScriptSelectItem; + kScriptSelectItem.header = HEADER_CG_SCRIPT_SELECT_ITEM; + kScriptSelectItem.selection = dwItemPos; + + if (!Send(sizeof(kScriptSelectItem), &kScriptSelectItem)) + return false; + + return SendSequence(); +} + +bool CPythonNetworkStream::RecvRefineInformationPacket() +{ + TPacketGCRefineInformation kRefineInfoPacket; + if (!Recv(sizeof(kRefineInfoPacket), &kRefineInfoPacket)) + return false; + + TRefineTable & rkRefineTable = kRefineInfoPacket.refine_table; + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], + "OpenRefineDialog", + Py_BuildValue("(iiii)", + kRefineInfoPacket.pos, + kRefineInfoPacket.refine_table.result_vnum, + rkRefineTable.cost, + rkRefineTable.prob)); + + for (int i = 0; i < rkRefineTable.material_count; ++i) + { + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "AppendMaterialToRefineDialog", Py_BuildValue("(ii)", rkRefineTable.materials[i].vnum, rkRefineTable.materials[i].count)); + } + +#ifdef _DEBUG + Tracef(" >> RecvRefineInformationPacket(pos=%d, result_vnum=%d, cost=%d, prob=%d)\n", + kRefineInfoPacket.pos, + kRefineInfoPacket.refine_table.result_vnum, + rkRefineTable.cost, + rkRefineTable.prob); +#endif + + return true; +} + +bool CPythonNetworkStream::RecvRefineInformationPacketNew() +{ + TPacketGCRefineInformationNew kRefineInfoPacket; + if (!Recv(sizeof(kRefineInfoPacket), &kRefineInfoPacket)) + return false; + + TRefineTable & rkRefineTable = kRefineInfoPacket.refine_table; + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], + "OpenRefineDialog", + Py_BuildValue("(iiiii)", + kRefineInfoPacket.pos, + kRefineInfoPacket.refine_table.result_vnum, + rkRefineTable.cost, + rkRefineTable.prob, + kRefineInfoPacket.type) + ); + + for (int i = 0; i < rkRefineTable.material_count; ++i) + { + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "AppendMaterialToRefineDialog", Py_BuildValue("(ii)", rkRefineTable.materials[i].vnum, rkRefineTable.materials[i].count)); + } + +#ifdef _DEBUG + Tracef(" >> RecvRefineInformationPacketNew(pos=%d, result_vnum=%d, cost=%d, prob=%d, type=%d)\n", + kRefineInfoPacket.pos, + kRefineInfoPacket.refine_table.result_vnum, + rkRefineTable.cost, + rkRefineTable.prob, + kRefineInfoPacket.type); +#endif + + return true; +} + +bool CPythonNetworkStream::RecvNPCList() +{ + TPacketGCNPCPosition kNPCPosition; + if (!Recv(sizeof(kNPCPosition), &kNPCPosition)) + return false; + + assert(int(kNPCPosition.size)-sizeof(kNPCPosition) == kNPCPosition.count*sizeof(TNPCPosition) && "HEADER_GC_NPC_POSITION"); + + CPythonMiniMap::Instance().ClearAtlasMarkInfo(); + + for (int i = 0; i < kNPCPosition.count; ++i) + { + TNPCPosition NPCPosition; + if (!Recv(sizeof(TNPCPosition), &NPCPosition)) + return false; + + CPythonMiniMap::Instance().RegisterAtlasMark(NPCPosition.bType, NPCPosition.name, NPCPosition.x, NPCPosition.y); + } + + return true; +} + +bool CPythonNetworkStream::__SendCRCReportPacket() +{ + /* + DWORD dwProcessCRC = 0; + DWORD dwFileCRC = 0; + CFilename exeFileName; + //LPCVOID c_pvBaseAddress = NULL; + + GetExeCRC(dwProcessCRC, dwFileCRC); + + CFilename strRootPackFileName = CEterPackManager::Instance().GetRootPacketFileName(); + strRootPackFileName.ChangeDosPath(); + + TPacketCGCRCReport kReportPacket; + + kReportPacket.header = HEADER_CG_CRC_REPORT; + kReportPacket.byPackMode = CEterPackManager::Instance().GetSearchMode(); + kReportPacket.dwBinaryCRC32 = dwFileCRC; + kReportPacket.dwProcessCRC32 = dwProcessCRC; + kReportPacket.dwRootPackCRC32 = GetFileCRC32(strRootPackFileName.c_str()); + + if (!Send(sizeof(kReportPacket), &kReportPacket)) + Tracef("SendClientReportPacket Error"); + + return SendSequence(); + */ + return true; +} + +bool CPythonNetworkStream::SendClientVersionPacket() +{ + std::string filename; + + GetExcutedFileName(filename); + + filename = CFileNameHelper::NoPath(filename); + CFileNameHelper::ChangeDosPath(filename); + + if (LocaleService_IsEUROPE() && false == LocaleService_IsYMIR()) + { + TPacketCGClientVersion2 kVersionPacket; + kVersionPacket.header = HEADER_CG_CLIENT_VERSION2; + strncpy(kVersionPacket.filename, filename.c_str(), sizeof(kVersionPacket.filename)-1); + strncpy(kVersionPacket.timestamp, "1215955205", sizeof(kVersionPacket.timestamp)-1); // # python time.time ڸ + //strncpy(kVersionPacket.timestamp, __TIMESTAMP__, sizeof(kVersionPacket.timestamp)-1); // old_string_ver + //strncpy(kVersionPacket.timestamp, "1218055205", sizeof(kVersionPacket.timestamp)-1); // new_future + //strncpy(kVersionPacket.timestamp, "1214055205", sizeof(kVersionPacket.timestamp)-1); // old_past + + if (!Send(sizeof(kVersionPacket), &kVersionPacket)) + Tracef("SendClientReportPacket Error"); + } + else + { + TPacketCGClientVersion kVersionPacket; + kVersionPacket.header = HEADER_CG_CLIENT_VERSION; + strncpy(kVersionPacket.filename, filename.c_str(), sizeof(kVersionPacket.filename)-1); + strncpy(kVersionPacket.timestamp, __TIMESTAMP__, sizeof(kVersionPacket.timestamp)-1); + + if (!Send(sizeof(kVersionPacket), &kVersionPacket)) + Tracef("SendClientReportPacket Error"); + } + return SendSequence(); +} + +bool CPythonNetworkStream::RecvAffectAddPacket() +{ + TPacketGCAffectAdd kAffectAdd; + if (!Recv(sizeof(kAffectAdd), &kAffectAdd)) + return false; + + TPacketAffectElement & rkElement = kAffectAdd.elem; + if (rkElement.bPointIdxApplyOn == POINT_ENERGY) + { + CPythonPlayer::instance().SetStatus (POINT_ENERGY_END_TIME, CPythonApplication::Instance().GetServerTimeStamp() + rkElement.lDuration); + __RefreshStatus(); + } + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_NEW_AddAffect", Py_BuildValue("(iiii)", rkElement.dwType, rkElement.bPointIdxApplyOn, rkElement.lApplyValue, rkElement.lDuration)); + + return true; +} + +bool CPythonNetworkStream::RecvAffectRemovePacket() +{ + TPacketGCAffectRemove kAffectRemove; + if (!Recv(sizeof(kAffectRemove), &kAffectRemove)) + return false; + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_NEW_RemoveAffect", Py_BuildValue("(ii)", kAffectRemove.dwType, kAffectRemove.bApplyOn)); + + return true; +} + +bool CPythonNetworkStream::RecvChannelPacket() +{ + TPacketGCChannel kChannelPacket; + if (!Recv(sizeof(kChannelPacket), &kChannelPacket)) + return false; + + //Tracef(" >> CPythonNetworkStream::RecvChannelPacket(channel=%d)\n", kChannelPacket.channel); + + return true; +} + +bool CPythonNetworkStream::RecvViewEquipPacket() +{ + TPacketGCViewEquip kViewEquipPacket; + if (!Recv(sizeof(kViewEquipPacket), &kViewEquipPacket)) + return false; + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OpenEquipmentDialog", Py_BuildValue("(i)", kViewEquipPacket.dwVID)); + + for (int i = 0; i < WEAR_MAX_NUM; ++i) + { + TEquipmentItemSet & rItemSet = kViewEquipPacket.equips[i]; + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "SetEquipmentDialogItem", Py_BuildValue("(iiii)", kViewEquipPacket.dwVID, i, rItemSet.vnum, rItemSet.count)); + + for (int j = 0; j < ITEM_SOCKET_SLOT_MAX_NUM; ++j) + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "SetEquipmentDialogSocket", Py_BuildValue("(iiii)", kViewEquipPacket.dwVID, i, j, rItemSet.alSockets[j])); + + for (int k = 0; k < ITEM_ATTRIBUTE_SLOT_MAX_NUM; ++k) + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "SetEquipmentDialogAttr", Py_BuildValue("(iiiii)", kViewEquipPacket.dwVID, i, k, rItemSet.aAttr[k].bType, rItemSet.aAttr[k].sValue)); + } + + return true; +} + +bool CPythonNetworkStream::RecvLandPacket() +{ + TPacketGCLandList kLandList; + if (!Recv(sizeof(kLandList), &kLandList)) + return false; + + std::vector kVec_dwGuildID; + + CPythonMiniMap & rkMiniMap = CPythonMiniMap::Instance(); + CPythonBackground & rkBG = CPythonBackground::Instance(); + CInstanceBase * pMainInstance = CPythonPlayer::Instance().NEW_GetMainActorPtr(); + + rkMiniMap.ClearGuildArea(); + rkBG.ClearGuildArea(); + + int iPacketSize = (kLandList.size - sizeof(TPacketGCLandList)); + for (; iPacketSize > 0; iPacketSize-=sizeof(TLandPacketElement)) + { + TLandPacketElement kElement; + if (!Recv(sizeof(TLandPacketElement), &kElement)) + return false; + + rkMiniMap.RegisterGuildArea(kElement.dwID, + kElement.dwGuildID, + kElement.x, + kElement.y, + kElement.width, + kElement.height); + + if (pMainInstance) + if (kElement.dwGuildID == pMainInstance->GetGuildID()) + { + rkBG.RegisterGuildArea(kElement.x, + kElement.y, + kElement.x+kElement.width, + kElement.y+kElement.height); + } + + if (0 != kElement.dwGuildID) + kVec_dwGuildID.push_back(kElement.dwGuildID); + } + + __DownloadSymbol(kVec_dwGuildID); + + return true; +} + +bool CPythonNetworkStream::RecvTargetCreatePacket() +{ + TPacketGCTargetCreate kTargetCreate; + if (!Recv(sizeof(kTargetCreate), &kTargetCreate)) + return false; + + CPythonMiniMap & rkpyMiniMap = CPythonMiniMap::Instance(); + rkpyMiniMap.CreateTarget(kTargetCreate.lID, kTargetCreate.szTargetName); + +//#ifdef _DEBUG +// char szBuf[256+1]; +// _snprintf(szBuf, sizeof(szBuf), "Ÿ Ǿϴ [%d:%s]", kTargetCreate.lID, kTargetCreate.szTargetName); +// CPythonChat::Instance().AppendChat(CHAT_TYPE_NOTICE, szBuf); +// Tracef(" >> RecvTargetCreatePacket %d : %s\n", kTargetCreate.lID, kTargetCreate.szTargetName); +//#endif + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_OpenAtlasWindow", Py_BuildValue("()")); + return true; +} + +bool CPythonNetworkStream::RecvTargetCreatePacketNew() +{ + TPacketGCTargetCreateNew kTargetCreate; + if (!Recv(sizeof(kTargetCreate), &kTargetCreate)) + return false; + + CPythonMiniMap & rkpyMiniMap = CPythonMiniMap::Instance(); + CPythonBackground & rkpyBG = CPythonBackground::Instance(); + if (CREATE_TARGET_TYPE_LOCATION == kTargetCreate.byType) + { + rkpyMiniMap.CreateTarget(kTargetCreate.lID, kTargetCreate.szTargetName); + } + else + { + rkpyMiniMap.CreateTarget(kTargetCreate.lID, kTargetCreate.szTargetName, kTargetCreate.dwVID); + rkpyBG.CreateTargetEffect(kTargetCreate.lID, kTargetCreate.dwVID); + } + +//#ifdef _DEBUG +// char szBuf[256+1]; +// _snprintf(szBuf, sizeof(szBuf), "ij Ÿ Ǿϴ [%d:%s:%d]", kTargetCreate.lID, kTargetCreate.szTargetName, kTargetCreate.dwVID); +// CPythonChat::Instance().AppendChat(CHAT_TYPE_NOTICE, szBuf); +// Tracef(" >> RecvTargetCreatePacketNew %d : %d/%d\n", kTargetCreate.lID, kTargetCreate.byType, kTargetCreate.dwVID); +//#endif + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_OpenAtlasWindow", Py_BuildValue("()")); + return true; +} + +bool CPythonNetworkStream::RecvTargetUpdatePacket() +{ + TPacketGCTargetUpdate kTargetUpdate; + if (!Recv(sizeof(kTargetUpdate), &kTargetUpdate)) + return false; + + CPythonMiniMap & rkpyMiniMap = CPythonMiniMap::Instance(); + rkpyMiniMap.UpdateTarget(kTargetUpdate.lID, kTargetUpdate.lX, kTargetUpdate.lY); + + CPythonBackground & rkpyBG = CPythonBackground::Instance(); + rkpyBG.CreateTargetEffect(kTargetUpdate.lID, kTargetUpdate.lX, kTargetUpdate.lY); + +//#ifdef _DEBUG +// char szBuf[256+1]; +// _snprintf(szBuf, sizeof(szBuf), "Ÿ ġ Ǿϴ [%d:%d/%d]", kTargetUpdate.lID, kTargetUpdate.lX, kTargetUpdate.lY); +// CPythonChat::Instance().AppendChat(CHAT_TYPE_NOTICE, szBuf); +// Tracef(" >> RecvTargetUpdatePacket %d : %d, %d\n", kTargetUpdate.lID, kTargetUpdate.lX, kTargetUpdate.lY); +//#endif + + return true; +} + +bool CPythonNetworkStream::RecvTargetDeletePacket() +{ + TPacketGCTargetDelete kTargetDelete; + if (!Recv(sizeof(kTargetDelete), &kTargetDelete)) + return false; + + CPythonMiniMap & rkpyMiniMap = CPythonMiniMap::Instance(); + rkpyMiniMap.DeleteTarget(kTargetDelete.lID); + + CPythonBackground & rkpyBG = CPythonBackground::Instance(); + rkpyBG.DeleteTargetEffect(kTargetDelete.lID); + +//#ifdef _DEBUG +// Tracef(" >> RecvTargetDeletePacket %d\n", kTargetDelete.lID); +//#endif + + return true; +} + +bool CPythonNetworkStream::RecvLoverInfoPacket() +{ + TPacketGCLoverInfo kLoverInfo; + if (!Recv(sizeof(kLoverInfo), &kLoverInfo)) + return false; + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_LoverInfo", Py_BuildValue("(si)", kLoverInfo.szName, kLoverInfo.byLovePoint)); +#ifdef _DEBUG + Tracef("RECV LOVER INFO : %s, %d\n", kLoverInfo.szName, kLoverInfo.byLovePoint); +#endif + return true; +} + +bool CPythonNetworkStream::RecvLovePointUpdatePacket() +{ + TPacketGCLovePointUpdate kLovePointUpdate; + if (!Recv(sizeof(kLovePointUpdate), &kLovePointUpdate)) + return false; + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_UpdateLovePoint", Py_BuildValue("(i)", kLovePointUpdate.byLovePoint)); +#ifdef _DEBUG + Tracef("RECV LOVE POINT UPDATE : %d\n", kLovePointUpdate.byLovePoint); +#endif + return true; +} + +bool CPythonNetworkStream::RecvDigMotionPacket() +{ + TPacketGCDigMotion kDigMotion; + if (!Recv(sizeof(kDigMotion), &kDigMotion)) + return false; + +#ifdef _DEBUG + Tracef(" Dig Motion [%d/%d]\n", kDigMotion.vid, kDigMotion.count); +#endif + + IAbstractCharacterManager& rkChrMgr=IAbstractCharacterManager::GetSingleton(); + CInstanceBase * pkInstMain = rkChrMgr.GetInstancePtr(kDigMotion.vid); + CInstanceBase * pkInstTarget = rkChrMgr.GetInstancePtr(kDigMotion.target_vid); + if (NULL == pkInstMain) + return true; + + if (pkInstTarget) + pkInstMain->NEW_LookAtDestInstance(*pkInstTarget); + + for (int i = 0; i < kDigMotion.count; ++i) + pkInstMain->PushOnceMotion(CRaceMotionData::NAME_DIG); + + return true; +} + + +// ȥ ȭ +bool CPythonNetworkStream::SendDragonSoulRefinePacket(BYTE bRefineType, TItemPos* pos) +{ + TPacketCGDragonSoulRefine pk; + pk.header = HEADER_CG_DRAGON_SOUL_REFINE; + pk.bSubType = bRefineType; + memcpy (pk.ItemGrid, pos, sizeof (TItemPos) * DS_REFINE_WINDOW_MAX_NUM); + if (!Send(sizeof (pk), &pk)) + { + return false; + } + return true; +} + + +#if defined(ENABLE_DISCORD_RPC) +#include "discord_rpc.h" +#include "Discord.h" +#ifdef _DEBUG +#pragma comment(lib, "discord_rpc_d.lib") +#else +#pragma comment(lib, "discord_rpc_r.lib") +#endif + +static int64_t StartTime = 0; +void CPythonNetworkStream::Discord_Start() +{ + StartTime = time(0); + DiscordEventHandlers handlers; + memset(&handlers, 0, sizeof(handlers)); + Discord_Initialize(Discord::DiscordClientID, &handlers, 1, nullptr); + Discord_Update(false); +} + +void CPythonNetworkStream::Discord_Update(const bool bInGame) +{ + DiscordRichPresence discordPresence; + memset(&discordPresence, 0, sizeof(discordPresence)); + discordPresence.startTimestamp = StartTime; + + if (!bInGame) { + Discord_UpdatePresence(&discordPresence); + return; + } + + /*Name*/ + auto NameData = Discord::GetNameData(); + discordPresence.state = std::get<0>(NameData).c_str(); + discordPresence.details = std::get<1>(NameData).c_str(); + + /*Race*/ + auto RaceData = Discord::GetRaceData(); + discordPresence.largeImageKey = std::get<0>(RaceData).c_str(); + discordPresence.largeImageText = std::get<1>(RaceData).c_str(); + + /*Empire*/ + auto EmpireData = Discord::GetEmpireData(); + discordPresence.smallImageKey = std::get<0>(EmpireData).c_str(); + discordPresence.smallImageText = std::get<1>(EmpireData).c_str(); + + Discord_UpdatePresence(&discordPresence); +} + +void CPythonNetworkStream::Discord_Close() +{ + Discord_Shutdown(); +} +#endif \ No newline at end of file diff --git a/source/UserInterface/PythonNetworkStreamPhaseGameActor.cpp b/source/UserInterface/PythonNetworkStreamPhaseGameActor.cpp new file mode 100644 index 0000000..48ab65a --- /dev/null +++ b/source/UserInterface/PythonNetworkStreamPhaseGameActor.cpp @@ -0,0 +1,454 @@ +#include "StdAfx.h" +#include "PythonNetworkStream.h" +#include "NetworkActorManager.h" +#include "PythonBackground.h" + +#include "PythonApplication.h" +#include "AbstractPlayer.h" +#include "../gamelib/ActorInstance.h" + + + + + +void CPythonNetworkStream::__GlobalPositionToLocalPosition(LONG& rGlobalX, LONG& rGlobalY) +{ + CPythonBackground&rkBgMgr=CPythonBackground::Instance(); + rkBgMgr.GlobalPositionToLocalPosition(rGlobalX, rGlobalY); +} + +void CPythonNetworkStream::__LocalPositionToGlobalPosition(LONG& rLocalX, LONG& rLocalY) +{ + CPythonBackground&rkBgMgr=CPythonBackground::Instance(); + rkBgMgr.LocalPositionToGlobalPosition(rLocalX, rLocalY); +} + +bool CPythonNetworkStream::__CanActMainInstance() +{ + CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance(); + CInstanceBase* pkInstMain=rkChrMgr.GetMainInstancePtr(); + if (!pkInstMain) + return false; + + return pkInstMain->CanAct(); +} + +void CPythonNetworkStream::__ClearNetworkActorManager() +{ + m_rokNetActorMgr->Destroy(); +} + +void __SetWeaponPower(IAbstractPlayer& rkPlayer, DWORD dwWeaponID) +{ + DWORD minPower=0; + DWORD maxPower=0; + DWORD minMagicPower=0; + DWORD maxMagicPower=0; + DWORD addPower=0; + + CItemData* pkWeapon; + if (CItemManager::Instance().GetItemDataPointer(dwWeaponID, &pkWeapon)) + { + if (pkWeapon->GetType()==CItemData::ITEM_TYPE_WEAPON) + { + minPower=pkWeapon->GetValue(3); + maxPower=pkWeapon->GetValue(4); + minMagicPower=pkWeapon->GetValue(1); + maxMagicPower=pkWeapon->GetValue(2); + addPower=pkWeapon->GetValue(5); + } + } + + rkPlayer.SetWeaponPower(minPower, maxPower, minMagicPower, maxMagicPower, addPower); +} + +//̺ ̸ "." ͵ +//Ŀ ʰ Ǹ Լ..(Բ !!; ) +bool IsInvisibleRace(WORD raceNum) +{ + switch(raceNum) + { + case 20025: + case 20038: + case 20039: + return true; + default: + return false; + } +} + +static SNetworkActorData s_kNetActorData; + + +bool CPythonNetworkStream::RecvCharacterAppendPacket() +{ + TPacketGCCharacterAdd chrAddPacket; + if (!Recv(sizeof(chrAddPacket), &chrAddPacket)) + return false; + + __GlobalPositionToLocalPosition(chrAddPacket.x, chrAddPacket.y); + + SNetworkActorData kNetActorData; + kNetActorData.m_bType=chrAddPacket.bType; + kNetActorData.m_dwMovSpd=chrAddPacket.bMovingSpeed; + kNetActorData.m_dwAtkSpd=chrAddPacket.bAttackSpeed; + kNetActorData.m_dwRace=chrAddPacket.wRaceNum; + + kNetActorData.m_dwStateFlags=chrAddPacket.bStateFlag; + kNetActorData.m_dwVID=chrAddPacket.dwVID; + kNetActorData.m_fRot=chrAddPacket.angle; + + kNetActorData.m_stName=""; + + kNetActorData.m_stName=""; + kNetActorData.m_kAffectFlags.CopyData(0, sizeof(chrAddPacket.dwAffectFlag[0]), &chrAddPacket.dwAffectFlag[0]); + kNetActorData.m_kAffectFlags.CopyData(32, sizeof(chrAddPacket.dwAffectFlag[1]), &chrAddPacket.dwAffectFlag[1]); + + kNetActorData.SetPosition(chrAddPacket.x, chrAddPacket.y); + + kNetActorData.m_sAlignment=0;/*chrAddPacket.sAlignment*/; + kNetActorData.m_byPKMode=0;/*chrAddPacket.bPKMode*/; + kNetActorData.m_dwGuildID=0;/*chrAddPacket.dwGuild*/; + kNetActorData.m_dwEmpireID=0;/*chrAddPacket.bEmpire*/; + kNetActorData.m_dwArmor=0;/*chrAddPacket.awPart[CHR_EQUIPPART_ARMOR]*/; + kNetActorData.m_dwWeapon=0;/*chrAddPacket.awPart[CHR_EQUIPPART_WEAPON]*/; + kNetActorData.m_dwHair=0;/*chrAddPacket.awPart[CHR_EQUIPPART_HAIR]*/; + kNetActorData.m_dwMountVnum=0;/*chrAddPacket.dwMountVnum*/; + + kNetActorData.m_dwLevel = 0; // ǥ + + if(kNetActorData.m_bType != CActorInstance::TYPE_PC && + kNetActorData.m_bType != CActorInstance::TYPE_NPC) + { + const char * c_szName; + CPythonNonPlayer& rkNonPlayer=CPythonNonPlayer::Instance(); + if (rkNonPlayer.GetName(kNetActorData.m_dwRace, &c_szName)) + kNetActorData.m_stName = c_szName; + //else + // kNetActorData.m_stName=chrAddPacket.name; + + __RecvCharacterAppendPacket(&kNetActorData); + } + else + { + s_kNetActorData = kNetActorData; + } + + return true; +} + +bool CPythonNetworkStream::RecvCharacterAdditionalInfo() +{ + TPacketGCCharacterAdditionalInfo chrInfoPacket; + if (!Recv(sizeof(chrInfoPacket), &chrInfoPacket)) + return false; + + + SNetworkActorData kNetActorData = s_kNetActorData; + if (IsInvisibleRace(kNetActorData.m_dwRace)) + return true; + + if(kNetActorData.m_dwVID == chrInfoPacket.dwVID) + { + kNetActorData.m_stName = chrInfoPacket.name; + kNetActorData.m_dwGuildID = chrInfoPacket.dwGuildID; + kNetActorData.m_dwLevel = chrInfoPacket.dwLevel; + kNetActorData.m_sAlignment=chrInfoPacket.sAlignment; + kNetActorData.m_byPKMode=chrInfoPacket.bPKMode; + kNetActorData.m_dwGuildID=chrInfoPacket.dwGuildID; + kNetActorData.m_dwEmpireID=chrInfoPacket.bEmpire; + kNetActorData.m_dwArmor=chrInfoPacket.awPart[CHR_EQUIPPART_ARMOR]; + kNetActorData.m_dwWeapon=chrInfoPacket.awPart[CHR_EQUIPPART_WEAPON]; + kNetActorData.m_dwHair=chrInfoPacket.awPart[CHR_EQUIPPART_HAIR]; + kNetActorData.m_dwMountVnum=chrInfoPacket.dwMountVnum; + + __RecvCharacterAppendPacket(&kNetActorData); + } + else + { + TraceError("TPacketGCCharacterAdditionalInfo name=%s vid=%d race=%d Error",chrInfoPacket.name,chrInfoPacket.dwVID,kNetActorData.m_dwRace); + } + return true; +} + +bool CPythonNetworkStream::RecvCharacterAppendPacketNew() +{ + TraceError("TPacketGCCharacterAdd2 ʴ ŶԴϴ."); + TPacketGCCharacterAdd2 chrAddPacket; + if (!Recv(sizeof(chrAddPacket), &chrAddPacket)) + return false; + if(IsInvisibleRace(chrAddPacket.wRaceNum)) + return true; + + __GlobalPositionToLocalPosition(chrAddPacket.x, chrAddPacket.y); + + SNetworkActorData kNetActorData; + kNetActorData.m_dwLevel = 0; + kNetActorData.m_bType=chrAddPacket.bType; + kNetActorData.m_dwGuildID=chrAddPacket.dwGuild; + kNetActorData.m_dwEmpireID=chrAddPacket.bEmpire; + kNetActorData.m_dwMovSpd=chrAddPacket.bMovingSpeed; + kNetActorData.m_dwAtkSpd=chrAddPacket.bAttackSpeed; + kNetActorData.m_dwRace=chrAddPacket.wRaceNum; + kNetActorData.m_dwArmor=chrAddPacket.awPart[CHR_EQUIPPART_ARMOR]; + kNetActorData.m_dwWeapon=chrAddPacket.awPart[CHR_EQUIPPART_WEAPON]; + kNetActorData.m_dwHair=chrAddPacket.awPart[CHR_EQUIPPART_HAIR]; + kNetActorData.m_dwStateFlags=chrAddPacket.bStateFlag; + kNetActorData.m_dwVID=chrAddPacket.dwVID; + kNetActorData.m_dwMountVnum=chrAddPacket.dwMountVnum; + kNetActorData.m_fRot=chrAddPacket.angle; + kNetActorData.m_kAffectFlags.CopyData(0, sizeof(chrAddPacket.dwAffectFlag[0]), &chrAddPacket.dwAffectFlag[0]); + kNetActorData.m_kAffectFlags.CopyData(32, sizeof(chrAddPacket.dwAffectFlag[1]), &chrAddPacket.dwAffectFlag[1]); + kNetActorData.SetPosition(chrAddPacket.x, chrAddPacket.y); + kNetActorData.m_sAlignment=chrAddPacket.sAlignment; + kNetActorData.m_byPKMode=chrAddPacket.bPKMode; + kNetActorData.m_stName=chrAddPacket.name; + __RecvCharacterAppendPacket(&kNetActorData); + + return true; +} + +bool CPythonNetworkStream::RecvCharacterUpdatePacket() +{ + TPacketGCCharacterUpdate chrUpdatePacket; + if (!Recv(sizeof(chrUpdatePacket), &chrUpdatePacket)) + return false; + + SNetworkUpdateActorData kNetUpdateActorData; + kNetUpdateActorData.m_dwGuildID=chrUpdatePacket.dwGuildID; + kNetUpdateActorData.m_dwMovSpd=chrUpdatePacket.bMovingSpeed; + kNetUpdateActorData.m_dwAtkSpd=chrUpdatePacket.bAttackSpeed; + kNetUpdateActorData.m_dwArmor=chrUpdatePacket.awPart[CHR_EQUIPPART_ARMOR]; + kNetUpdateActorData.m_dwWeapon=chrUpdatePacket.awPart[CHR_EQUIPPART_WEAPON]; + kNetUpdateActorData.m_dwHair=chrUpdatePacket.awPart[CHR_EQUIPPART_HAIR]; + kNetUpdateActorData.m_dwVID=chrUpdatePacket.dwVID; + kNetUpdateActorData.m_kAffectFlags.CopyData(0, sizeof(chrUpdatePacket.dwAffectFlag[0]), &chrUpdatePacket.dwAffectFlag[0]); + kNetUpdateActorData.m_kAffectFlags.CopyData(32, sizeof(chrUpdatePacket.dwAffectFlag[1]), &chrUpdatePacket.dwAffectFlag[1]); + kNetUpdateActorData.m_sAlignment=chrUpdatePacket.sAlignment; + kNetUpdateActorData.m_byPKMode=chrUpdatePacket.bPKMode; + kNetUpdateActorData.m_dwStateFlags=chrUpdatePacket.bStateFlag; + kNetUpdateActorData.m_dwMountVnum=chrUpdatePacket.dwMountVnum; + __RecvCharacterUpdatePacket(&kNetUpdateActorData); + + return true; +} + +bool CPythonNetworkStream::RecvCharacterUpdatePacketNew() +{ + TPacketGCCharacterUpdate2 chrUpdatePacket; + if (!Recv(sizeof(chrUpdatePacket), &chrUpdatePacket)) + return false; + + SNetworkUpdateActorData kNetUpdateActorData; + kNetUpdateActorData.m_dwGuildID=chrUpdatePacket.dwGuildID; + kNetUpdateActorData.m_dwMovSpd=chrUpdatePacket.bMovingSpeed; + kNetUpdateActorData.m_dwAtkSpd=chrUpdatePacket.bAttackSpeed; + kNetUpdateActorData.m_dwArmor=chrUpdatePacket.awPart[CHR_EQUIPPART_ARMOR]; + kNetUpdateActorData.m_dwWeapon=chrUpdatePacket.awPart[CHR_EQUIPPART_WEAPON]; + kNetUpdateActorData.m_dwHair=chrUpdatePacket.awPart[CHR_EQUIPPART_HAIR]; + kNetUpdateActorData.m_dwVID=chrUpdatePacket.dwVID; + kNetUpdateActorData.m_kAffectFlags.CopyData(0, sizeof(chrUpdatePacket.dwAffectFlag[0]), &chrUpdatePacket.dwAffectFlag[0]); + kNetUpdateActorData.m_kAffectFlags.CopyData(32, sizeof(chrUpdatePacket.dwAffectFlag[1]), &chrUpdatePacket.dwAffectFlag[1]); + kNetUpdateActorData.m_sAlignment=chrUpdatePacket.sAlignment; + kNetUpdateActorData.m_byPKMode=chrUpdatePacket.bPKMode; + kNetUpdateActorData.m_dwStateFlags=chrUpdatePacket.bStateFlag; + kNetUpdateActorData.m_dwMountVnum=chrUpdatePacket.dwMountVnum; + __RecvCharacterUpdatePacket(&kNetUpdateActorData); + + return true; +} + +void CPythonNetworkStream::__RecvCharacterAppendPacket(SNetworkActorData * pkNetActorData) +{ + // NOTE : ī޶ ذ ijͰ ÷ + // Ʈ ̸ ֵ سƾ մϴ. + // ,  ƴ ̹ ijͰ ߰ Ŀ մϴ. + // 嵥 ̵ε Move ϰ Append ϴ..? - [levites] + IAbstractPlayer& rkPlayer = IAbstractPlayer::GetSingleton(); + if (rkPlayer.IsMainCharacterIndex(pkNetActorData->m_dwVID)) + { + rkPlayer.SetRace(pkNetActorData->m_dwRace); + + __SetWeaponPower(rkPlayer, pkNetActorData->m_dwWeapon); + + if (rkPlayer.NEW_GetMainActorPtr()) + { + CPythonBackground::Instance().Update(pkNetActorData->m_lCurX, pkNetActorData->m_lCurY, 0.0f); + CPythonCharacterManager::Instance().Update(); + + // NOTE : Ÿ GOTO ̵ÿ ̸ ϵ ó + { + std::string strMapName = CPythonBackground::Instance().GetWarpMapName(); + if (strMapName == "metin2_map_deviltower1") + __ShowMapName(pkNetActorData->m_lCurX, pkNetActorData->m_lCurY); + } + } + else + { + __ShowMapName(pkNetActorData->m_lCurX, pkNetActorData->m_lCurY); + } + } + + m_rokNetActorMgr->AppendActor(*pkNetActorData); + + if (GetMainActorVID()==pkNetActorData->m_dwVID) + { + rkPlayer.SetTarget(0); + if (m_bComboSkillFlag) + rkPlayer.SetComboSkillFlag(m_bComboSkillFlag); + + __SetGuildID(pkNetActorData->m_dwGuildID); + //CPythonApplication::Instance().SkipRenderBuffering(10000); + } +} + +void CPythonNetworkStream::__RecvCharacterUpdatePacket(SNetworkUpdateActorData * pkNetUpdateActorData) +{ + m_rokNetActorMgr->UpdateActor(*pkNetUpdateActorData); + + IAbstractPlayer& rkPlayer = IAbstractPlayer::GetSingleton(); + if (rkPlayer.IsMainCharacterIndex(pkNetUpdateActorData->m_dwVID)) + { + __SetGuildID(pkNetUpdateActorData->m_dwGuildID); + __SetWeaponPower(rkPlayer, pkNetUpdateActorData->m_dwWeapon); + + __RefreshStatus(); + __RefreshAlignmentWindow(); + __RefreshEquipmentWindow(); + __RefreshInventoryWindow(); + } + else + { + rkPlayer.NotifyCharacterUpdate(pkNetUpdateActorData->m_dwVID); + } +} + +bool CPythonNetworkStream::RecvCharacterDeletePacket() +{ + TPacketGCCharacterDelete chrDelPacket; + + if (!Recv(sizeof(chrDelPacket), &chrDelPacket)) + { + TraceError("CPythonNetworkStream::RecvCharacterDeletePacket - Recv Error"); + return false; + } + + m_rokNetActorMgr->RemoveActor(chrDelPacket.dwVID); + + // ijͰ ݴϴ. + // Key Check ϱ⶧  ϴ. + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], + "BINARY_PrivateShop_Disappear", + Py_BuildValue("(i)", chrDelPacket.dwVID) + ); + + return true; +} + + +bool CPythonNetworkStream::RecvCharacterMovePacket() +{ + TPacketGCMove kMovePacket; + if (!Recv(sizeof(TPacketGCMove), &kMovePacket)) + { + Tracen("CPythonNetworkStream::RecvCharacterMovePacket - PACKET READ ERROR"); + return false; + } + + __GlobalPositionToLocalPosition(kMovePacket.lX, kMovePacket.lY); + + SNetworkMoveActorData kNetMoveActorData; + kNetMoveActorData.m_dwArg=kMovePacket.bArg; + kNetMoveActorData.m_dwFunc=kMovePacket.bFunc; + kNetMoveActorData.m_dwTime=kMovePacket.dwTime; + kNetMoveActorData.m_dwVID=kMovePacket.dwVID; + kNetMoveActorData.m_fRot=kMovePacket.bRot*5.0f; + kNetMoveActorData.m_lPosX=kMovePacket.lX; + kNetMoveActorData.m_lPosY=kMovePacket.lY; + kNetMoveActorData.m_dwDuration=kMovePacket.dwDuration; + + m_rokNetActorMgr->MoveActor(kNetMoveActorData); + + return true; +} + +bool CPythonNetworkStream::RecvOwnerShipPacket() +{ + TPacketGCOwnership kPacketOwnership; + + if (!Recv(sizeof(kPacketOwnership), &kPacketOwnership)) + return false; + + m_rokNetActorMgr->SetActorOwner(kPacketOwnership.dwOwnerVID, kPacketOwnership.dwVictimVID); + + return true; +} + +bool CPythonNetworkStream::RecvSyncPositionPacket() +{ + TPacketGCSyncPosition kPacketSyncPos; + if (!Recv(sizeof(kPacketSyncPos), &kPacketSyncPos)) + return false; + + TPacketGCSyncPositionElement kSyncPos; + + UINT uSyncPosCount=(kPacketSyncPos.wSize-sizeof(kPacketSyncPos))/sizeof(kSyncPos); + for (UINT iSyncPos=0; iSyncPosSyncActor(kSyncPos.dwVID, kSyncPos.lX, kSyncPos.lY); + + /* + CPythonCharacterManager & rkChrMgr = CPythonCharacterManager::Instance(); + CInstanceBase * pkChrInst = rkChrMgr.GetInstancePtr(kSyncPos.dwVID); + + if (pkChrInst) + { + pkChrInst->NEW_SyncPixelPosition(kSyncPos.lX, kSyncPos.lY); + } + */ +} + + return true; +} + + +/* +bool CPythonNetworkStream::RecvCharacterAppendPacket() +{ + TPacketGCCharacterAdd chrAddPacket; + + if (!Recv(sizeof(chrAddPacket), &chrAddPacket)) + return false; + + __GlobalPositionToLocalPosition(chrAddPacket.lX, chrAddPacket.lY); + + SNetworkActorData kNetActorData; + kNetActorData.m_dwGuildID=chrAddPacket.dwGuild; + kNetActorData.m_dwEmpireID=chrAddPacket.bEmpire; + kNetActorData.m_dwMovSpd=chrAddPacket.bMovingSpeed; + kNetActorData.m_dwAtkSpd=chrAddPacket.bAttackSpeed; + kNetActorData.m_dwRace=chrAddPacket.wRaceNum; + kNetActorData.m_dwShape=chrAddPacket.parts[CRaceData::PART_MAIN]; + kNetActorData.m_dwStateFlags=chrAddPacket.bStateFlag; + kNetActorData.m_dwVID=chrAddPacket.dwVID; + kNetActorData.m_dwWeapon=chrAddPacket.parts[CRaceData::PART_WEAPON]; + kNetActorData.m_fRot=chrAddPacket.angle; + kNetActorData.m_kAffectFlags.CopyData(0, sizeof(chrAddPacket.dwAffectFlag[0]), &chrAddPacket.dwAffectFlag[0]); + kNetActorData.m_kAffectFlags.CopyData(32, sizeof(chrAddPacket.dwAffectFlag[1]), &chrAddPacket.dwAffectFlag[1]); + kNetActorData.SetPosition(chrAddPacket.lX, chrAddPacket.lY); + kNetActorData.m_stName=chrAddPacket.name; + __RecvCharacterAppendPacket(&kNetActorData); + return true; +} +*/ + diff --git a/source/UserInterface/PythonNetworkStreamPhaseGameItem.cpp b/source/UserInterface/PythonNetworkStreamPhaseGameItem.cpp new file mode 100644 index 0000000..eee1d81 --- /dev/null +++ b/source/UserInterface/PythonNetworkStreamPhaseGameItem.cpp @@ -0,0 +1,940 @@ +#include "StdAfx.h" +#include "PythonNetworkStream.h" +#include "PythonItem.h" +#include "PythonShop.h" +#include "PythonExchange.h" +#include "PythonSafeBox.h" +#include "PythonCharacterManager.h" + +#include "AbstractPlayer.h" + +////////////////////////////////////////////////////////////////////////// +// SafeBox + +bool CPythonNetworkStream::SendSafeBoxMoneyPacket(BYTE byState, DWORD dwMoney) +{ + assert(!"CPythonNetworkStream::SendSafeBoxMoneyPacket - ʴ Լ"); + return false; + +// TPacketCGSafeboxMoney kSafeboxMoney; +// kSafeboxMoney.bHeader = HEADER_CG_SAFEBOX_MONEY; +// kSafeboxMoney.bState = byState; +// kSafeboxMoney.dwMoney = dwMoney; +// if (!Send(sizeof(kSafeboxMoney), &kSafeboxMoney)) +// return false; +// +// return SendSequence(); +} + +bool CPythonNetworkStream::SendSafeBoxCheckinPacket(TItemPos InventoryPos, BYTE bySafeBoxPos) +{ + __PlayInventoryItemDropSound(InventoryPos); + + TPacketCGSafeboxCheckin kSafeboxCheckin; + kSafeboxCheckin.bHeader = HEADER_CG_SAFEBOX_CHECKIN; + kSafeboxCheckin.ItemPos = InventoryPos; + kSafeboxCheckin.bSafePos = bySafeBoxPos; + if (!Send(sizeof(kSafeboxCheckin), &kSafeboxCheckin)) + return false; + + return SendSequence(); +} + +bool CPythonNetworkStream::SendSafeBoxCheckoutPacket(BYTE bySafeBoxPos, TItemPos InventoryPos) +{ + __PlaySafeBoxItemDropSound(bySafeBoxPos); + + TPacketCGSafeboxCheckout kSafeboxCheckout; + kSafeboxCheckout.bHeader = HEADER_CG_SAFEBOX_CHECKOUT; + kSafeboxCheckout.bSafePos = bySafeBoxPos; + kSafeboxCheckout.ItemPos = InventoryPos; + if (!Send(sizeof(kSafeboxCheckout), &kSafeboxCheckout)) + return false; + + return SendSequence(); +} + +bool CPythonNetworkStream::SendSafeBoxItemMovePacket(BYTE bySourcePos, BYTE byTargetPos, BYTE byCount) +{ + __PlaySafeBoxItemDropSound(bySourcePos); + + TPacketCGItemMove kItemMove; + kItemMove.header = HEADER_CG_SAFEBOX_ITEM_MOVE; + kItemMove.pos = TItemPos(INVENTORY, bySourcePos); + kItemMove.num = byCount; + kItemMove.change_pos = TItemPos(INVENTORY, byTargetPos); + if (!Send(sizeof(kItemMove), &kItemMove)) + return false; + + return SendSequence(); +} + +bool CPythonNetworkStream::RecvSafeBoxSetPacket() +{ + TPacketGCItemSet2 kItemSet; + if (!Recv(sizeof(kItemSet), &kItemSet)) + return false; + + TItemData kItemData; + kItemData.vnum = kItemSet.vnum; + kItemData.count = kItemSet.count; + kItemData.flags = kItemSet.flags; + kItemData.anti_flags = kItemSet.anti_flags; + for (int isocket=0; isocket> CPythonNetworkStream::RecvMallItemDelPacket\n"); + + return true; +} +// Mall +////////////////////////////////////////////////////////////////////////// + +// Item +// Recieve +bool CPythonNetworkStream::RecvItemSetPacket() +{ + TPacketGCItemSet packet_item_set; + + if (!Recv(sizeof(TPacketGCItemSet), &packet_item_set)) + return false; + + TItemData kItemData; + kItemData.vnum = packet_item_set.vnum; + kItemData.count = packet_item_set.count; + kItemData.flags = 0; + for (int i=0; iAttachSpecialEffect(effect); + else + pInstance->CreateSpecialEffect(effect); + } + } + + return true; +} + + +bool CPythonNetworkStream::RecvSpecificEffect() +{ + TPacketGCSpecificEffect kSpecificEffect; + if (!Recv(sizeof(kSpecificEffect), &kSpecificEffect)) + return false; + + CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetInstancePtr(kSpecificEffect.vid); + //EFFECT_TEMP + if (pInstance) + { + CInstanceBase::RegisterEffect(CInstanceBase::EFFECT_TEMP, "", kSpecificEffect.effect_file, false); + pInstance->AttachSpecialEffect(CInstanceBase::EFFECT_TEMP); + } + + return true; +} + +bool CPythonNetworkStream::RecvDragonSoulRefine() +{ + TPacketGCDragonSoulRefine kDragonSoul; + + if (!Recv(sizeof(kDragonSoul), &kDragonSoul)) + return false; + + + switch (kDragonSoul.bSubType) + { + case DS_SUB_HEADER_OPEN: + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_DragonSoulRefineWindow_Open", Py_BuildValue("()")); + break; + case DS_SUB_HEADER_REFINE_FAIL: + case DS_SUB_HEADER_REFINE_FAIL_MAX_REFINE: + case DS_SUB_HEADER_REFINE_FAIL_INVALID_MATERIAL: + case DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MONEY: + case DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MATERIAL: + case DS_SUB_HEADER_REFINE_FAIL_TOO_MUCH_MATERIAL: + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_DragonSoulRefineWindow_RefineFail", Py_BuildValue("(iii)", + kDragonSoul.bSubType, kDragonSoul.Pos.window_type, kDragonSoul.Pos.cell)); + break; + case DS_SUB_HEADER_REFINE_SUCCEED: + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_DragonSoulRefineWindow_RefineSucceed", + Py_BuildValue("(ii)", kDragonSoul.Pos.window_type, kDragonSoul.Pos.cell)); + break; + } + + return true; +} diff --git a/source/UserInterface/PythonNetworkStreamPhaseHandShake.cpp b/source/UserInterface/PythonNetworkStreamPhaseHandShake.cpp new file mode 100644 index 0000000..6eeedc2 --- /dev/null +++ b/source/UserInterface/PythonNetworkStreamPhaseHandShake.cpp @@ -0,0 +1,331 @@ +#include "StdAfx.h" +#include "PythonNetworkStream.h" +#include "PythonApplication.h" +#include "Packet.h" +#include "../eterpack/EterPackManager.h" +#include "Hackshield.h" +#include "WiseLogicXTrap.h" + +#ifdef USE_AHNLAB_HACKSHIELD +#include METIN2HS_INCLUDE_HSHIELD +#endif + +// HandShake --------------------------------------------------------------------------- +void CPythonNetworkStream::HandShakePhase() +{ + TPacketHeader header; + + if (!CheckPacket(&header)) + return; + + switch (header) + { + case HEADER_GC_PHASE: + if (RecvPhasePacket()) + return; + break; + + case HEADER_GC_BINDUDP: + { + TPacketGCBindUDP BindUDP; + + if (!Recv(sizeof(TPacketGCBindUDP), &BindUDP)) + return; + + return; + } + break; + + case HEADER_GC_HANDSHAKE: + { + if (!Recv(sizeof(TPacketGCHandshake), &m_HandshakeData)) + return; + + Tracenf("HANDSHAKE RECV %u %d", m_HandshakeData.dwTime, m_HandshakeData.lDelta); + + ELTimer_SetServerMSec(m_HandshakeData.dwTime+ m_HandshakeData.lDelta); + + //m_dwBaseServerTime = m_HandshakeData.dwTime+ m_HandshakeData.lDelta; + //m_dwBaseClientTime = ELTimer_GetMSec(); + + m_HandshakeData.dwTime = m_HandshakeData.dwTime + m_HandshakeData.lDelta + m_HandshakeData.lDelta; + m_HandshakeData.lDelta = 0; + + Tracenf("HANDSHAKE SEND %u", m_HandshakeData.dwTime); + + if (!Send(sizeof(TPacketGCHandshake), &m_HandshakeData)) + { + assert(!"Failed Sending Handshake"); + return; + } + + CTimer::Instance().SetBaseTime(); + return; + } + break; + case HEADER_GC_PING: + RecvPingPacket(); + return; + break; + + case HEADER_GC_HYBRIDCRYPT_KEYS: + RecvHybridCryptKeyPacket(); + return; + break; + + case HEADER_GC_HYBRIDCRYPT_SDB: + RecvHybridCryptSDBPacket(); + return; + break; + +#ifdef _IMPROVED_PACKET_ENCRYPTION_ + case HEADER_GC_KEY_AGREEMENT: + RecvKeyAgreementPacket(); + return; + break; + + case HEADER_GC_KEY_AGREEMENT_COMPLETED: + RecvKeyAgreementCompletedPacket(); + return; + break; +#endif + } + + RecvErrorPacket(header); +} + +void CPythonNetworkStream::SetHandShakePhase() +{ + if ("HandShake"!=m_strPhase) + m_phaseLeaveFunc.Run(); + + Tracen(""); + Tracen("## Network - Hand Shake Phase ##"); + Tracen(""); + + m_strPhase = "HandShake"; + + m_dwChangingPhaseTime = ELTimer_GetMSec(); + m_phaseProcessFunc.Set(this, &CPythonNetworkStream::HandShakePhase); + m_phaseLeaveFunc.Set(this, &CPythonNetworkStream::__LeaveHandshakePhase); + + SetGameOnline(); + + if (__DirectEnterMode_IsSet()) + { + // None + } + else + { + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_LOGIN], "OnHandShake", Py_BuildValue("()")); + } +} + +bool CPythonNetworkStream::RecvHandshakePacket() +{ + TPacketGCHandshake kHandshakeData; + if (!Recv(sizeof(TPacketGCHandshake), &kHandshakeData)) + return false; + + Tracenf("HANDSHAKE RECV %u %d", kHandshakeData.dwTime, kHandshakeData.lDelta); + + m_kServerTimeSync.m_dwChangeServerTime = kHandshakeData.dwTime + kHandshakeData.lDelta; + m_kServerTimeSync.m_dwChangeClientTime = ELTimer_GetMSec(); + + kHandshakeData.dwTime = kHandshakeData.dwTime + kHandshakeData.lDelta + kHandshakeData.lDelta; + kHandshakeData.lDelta = 0; + + Tracenf("HANDSHAKE SEND %u", kHandshakeData.dwTime); + + kHandshakeData.header = HEADER_CG_TIME_SYNC; + if (!Send(sizeof(TPacketGCHandshake), &kHandshakeData)) + { + assert(!"Failed Sending Handshake"); + return false; + } + + SendSequence(); + + return true; +} + +bool CPythonNetworkStream::RecvHandshakeOKPacket() +{ + TPacketGCBlank kBlankPacket; + if (!Recv(sizeof(TPacketGCBlank), &kBlankPacket)) + return false; + + DWORD dwDelta=ELTimer_GetMSec()-m_kServerTimeSync.m_dwChangeClientTime; + ELTimer_SetServerMSec(m_kServerTimeSync.m_dwChangeServerTime+dwDelta); + + Tracenf("HANDSHAKE OK RECV %u %u", m_kServerTimeSync.m_dwChangeServerTime, dwDelta); + + return true; +} + +bool CPythonNetworkStream::RecvHybridCryptKeyPacket() +{ + int iFixedHeaderSize = TPacketGCHybridCryptKeys::GetFixedHeaderSize(); + + TDynamicSizePacketHeader header; + if( !Peek( sizeof(header), &header) ) + return false; + + TPacketGCHybridCryptKeys kPacket(header.size-iFixedHeaderSize); + + if (!Recv(iFixedHeaderSize, &kPacket)) + return false; + + if (!Recv(kPacket.iKeyStreamLen, kPacket.m_pStream)) + return false; + + CEterPackManager::Instance().RetrieveHybridCryptPackKeys( kPacket.m_pStream ); + return true; +} + +bool CPythonNetworkStream::RecvHybridCryptSDBPacket() +{ + int iFixedHeaderSize = TPacketGCHybridSDB::GetFixedHeaderSize(); + + TDynamicSizePacketHeader header; + if( !Peek( sizeof(header), &header) ) + return false; + + TPacketGCHybridSDB kPacket(header.size-iFixedHeaderSize); + + if (!Recv(iFixedHeaderSize, &kPacket)) + return false; + + if (!Recv(kPacket.iSDBStreamLen, kPacket.m_pStream)) + return false; + + CEterPackManager::Instance().RetrieveHybridCryptPackSDB( kPacket.m_pStream ); + return true; +} + + +#ifdef _IMPROVED_PACKET_ENCRYPTION_ +bool CPythonNetworkStream::RecvKeyAgreementPacket() +{ + TPacketKeyAgreement packet; + if (!Recv(sizeof(packet), &packet)) + { + return false; + } + + Tracenf("KEY_AGREEMENT RECV %u", packet.wDataLength); + + TPacketKeyAgreement packetToSend; + size_t dataLength = TPacketKeyAgreement::MAX_DATA_LEN; + size_t agreedLength = Prepare(packetToSend.data, &dataLength); + if (agreedLength == 0) + { + // ʱȭ + Disconnect(); + return false; + } + assert(dataLength <= TPacketKeyAgreement::MAX_DATA_LEN); + + if (Activate(packet.wAgreedLength, packet.data, packet.wDataLength)) + { + // Key agreement , + packetToSend.bHeader = HEADER_CG_KEY_AGREEMENT; + packetToSend.wAgreedLength = (WORD)agreedLength; + packetToSend.wDataLength = (WORD)dataLength; + + if (!Send(sizeof(packetToSend), &packetToSend)) + { + assert(!"Failed Sending KeyAgreement"); + return false; + } + Tracenf("KEY_AGREEMENT SEND %u", packetToSend.wDataLength); + } + else + { + // Ű + Disconnect(); + return false; + } + return true; +} + +bool CPythonNetworkStream::RecvKeyAgreementCompletedPacket() +{ + TPacketKeyAgreementCompleted packet; + if (!Recv(sizeof(packet), &packet)) + { + return false; + } + + Tracenf("KEY_AGREEMENT_COMPLETED RECV"); + + ActivateCipher(); + + return true; +} +#endif // _IMPROVED_PACKET_ENCRYPTION_ + +bool CPythonNetworkStream::RecvHSCheckRequest() +{ + TPacketHSCheck packet; + + if (!Recv(sizeof(packet), &packet)) + { + TraceError("HShield: Recv failed"); + + return false; + } + +#if defined(USE_AHNLAB_HACKSHIELD) || defined(LOCALE_SERVICE_GLOBAL) + TPacketHSCheck pack_ret; + memset(&pack_ret, 0, sizeof(pack_ret)); + pack_ret.bHeader = HEADER_CG_HS_ACK; + +#if defined(USE_AHNLAB_HACKSHIELD) + unsigned long ret = _AhnHS_MakeResponse( packet.Req.byBuffer, packet.Req.nLength, &pack_ret.Req ); + + if (ERROR_SUCCESS != ret) + { + TraceError("HShield: _AhnHS_MakeResponse return error(%u)", ret); + + return false; + } +#endif + + if (!Send(sizeof(pack_ret), &pack_ret)) + { + TraceError("HShield: Send failed"); + + return false; + } + + return true; +#else + return false; +#endif +} + +bool CPythonNetworkStream::RecvXTrapVerifyRequest() +{ + TPacketXTrapCSVerify packet; + + if (!Recv(sizeof(packet), &packet)) + { + TraceError("XTrap: Recv failed"); + + return false; + } + + TPacketXTrapCSVerify packet_res; + packet_res.bHeader = HEADER_CG_XTRAP_ACK; + + XTrap_ValidateCheckStream( packet.bPacketData, packet_res.bPacketData ); + + if (!Send(sizeof(packet_res), &packet_res)) + { + TraceError("XTrap: Send failed"); + return false; + } + + return true; +} diff --git a/source/UserInterface/PythonNetworkStreamPhaseLoading.cpp b/source/UserInterface/PythonNetworkStreamPhaseLoading.cpp new file mode 100644 index 0000000..f003ce0 --- /dev/null +++ b/source/UserInterface/PythonNetworkStreamPhaseLoading.cpp @@ -0,0 +1,361 @@ +#include "StdAfx.h" +#include "PythonNetworkStream.h" +#include "Packet.h" +#include "PythonApplication.h" +#include "NetworkActorManager.h" + +#include "AbstractPlayer.h" + +#include "../eterPack/EterPackManager.h" + +void CPythonNetworkStream::EnableChatInsultFilter(bool isEnable) +{ + m_isEnableChatInsultFilter=isEnable; +} + +void CPythonNetworkStream::__FilterInsult(char* szLine, UINT uLineLen) +{ + m_kInsultChecker.FilterInsult(szLine, uLineLen); +} + +bool CPythonNetworkStream::IsChatInsultIn(const char* c_szMsg) +{ + if (m_isEnableChatInsultFilter) + return false; + + return IsInsultIn(c_szMsg); +} + +bool CPythonNetworkStream::IsInsultIn(const char* c_szMsg) +{ + return m_kInsultChecker.IsInsultIn(c_szMsg, strlen(c_szMsg)); +} + +bool CPythonNetworkStream::LoadInsultList(const char* c_szInsultListFileName) +{ + CMappedFile file; + const VOID* pvData; + if (!CEterPackManager::Instance().Get(file, c_szInsultListFileName, &pvData)) + return false; + + CMemoryTextFileLoader kMemTextFileLoader; + kMemTextFileLoader.Bind(file.Size(), pvData); + + m_kInsultChecker.Clear(); + for (DWORD dwLineIndex=0; dwLineIndex=4) + return false; + + CMappedFile file; + const VOID* pvData; + if (!CEterPackManager::Instance().Get(file, c_szFileName, &pvData)) + return false; + + DWORD dwEngCount=26; + DWORD dwHanCount=(0xc8-0xb0+1)*(0xfe-0xa1+1); + DWORD dwHanSize=dwHanCount*2; + DWORD dwFileSize=dwEngCount*2+dwHanSize; + + if (file.Size()SetMainActorVID(m_dwMainActorVID); + + CPythonPlayer& rkPlayer=CPythonPlayer::Instance(); + rkPlayer.SetName(MainChrPacket.szName); + rkPlayer.SetMainCharacterIndex(GetMainActorVID()); + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_LOAD], "LoadData", Py_BuildValue("(ii)", MainChrPacket.lX, MainChrPacket.lY)); + + //Tracef(" >> RecvMainCharacter\n"); + + SendClientVersionPacket(); + return true; +} + +// SUPPORT_BGM +bool CPythonNetworkStream::RecvMainCharacter2_EMPIRE() +{ + TPacketGCMainCharacter2_EMPIRE mainChrPacket; + if (!Recv(sizeof(mainChrPacket), &mainChrPacket)) + return false; + + m_dwMainActorVID = mainChrPacket.dwVID; + m_dwMainActorRace = mainChrPacket.wRaceNum; + m_dwMainActorEmpire = mainChrPacket.byEmpire; + m_dwMainActorSkillGroup = mainChrPacket.bySkillGroup; + + m_rokNetActorMgr->SetMainActorVID(m_dwMainActorVID); + + CPythonPlayer& rkPlayer=CPythonPlayer::Instance(); + rkPlayer.SetName(mainChrPacket.szName); + rkPlayer.SetMainCharacterIndex(GetMainActorVID()); + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_LOAD], "LoadData", Py_BuildValue("(ii)", mainChrPacket.lX, mainChrPacket.lY)); + + //Tracef(" >> RecvMainCharacterNew : %d\n", m_dwMainActorEmpire); + + SendClientVersionPacket(); + return true; +} + +bool CPythonNetworkStream::RecvMainCharacter3_BGM() +{ + TPacketGCMainCharacter3_BGM mainChrPacket; + if (!Recv(sizeof(mainChrPacket), &mainChrPacket)) + return false; + + m_dwMainActorVID = mainChrPacket.dwVID; + m_dwMainActorRace = mainChrPacket.wRaceNum; + m_dwMainActorEmpire = mainChrPacket.byEmpire; + m_dwMainActorSkillGroup = mainChrPacket.bySkillGroup; + + m_rokNetActorMgr->SetMainActorVID(m_dwMainActorVID); + + CPythonPlayer& rkPlayer=CPythonPlayer::Instance(); + rkPlayer.SetName(mainChrPacket.szUserName); + rkPlayer.SetMainCharacterIndex(GetMainActorVID()); + + __SetFieldMusicFileName(mainChrPacket.szBGMName); + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_LOAD], "LoadData", Py_BuildValue("(ii)", mainChrPacket.lX, mainChrPacket.lY)); + + //Tracef(" >> RecvMainCharacterNew : %d\n", m_dwMainActorEmpire); + + SendClientVersionPacket(); + return true; +} + +bool CPythonNetworkStream::RecvMainCharacter4_BGM_VOL() +{ + TPacketGCMainCharacter4_BGM_VOL mainChrPacket; + if (!Recv(sizeof(mainChrPacket), &mainChrPacket)) + return false; + + m_dwMainActorVID = mainChrPacket.dwVID; + m_dwMainActorRace = mainChrPacket.wRaceNum; + m_dwMainActorEmpire = mainChrPacket.byEmpire; + m_dwMainActorSkillGroup = mainChrPacket.bySkillGroup; + + m_rokNetActorMgr->SetMainActorVID(m_dwMainActorVID); + + CPythonPlayer& rkPlayer=CPythonPlayer::Instance(); + rkPlayer.SetName(mainChrPacket.szUserName); + rkPlayer.SetMainCharacterIndex(GetMainActorVID()); + + __SetFieldMusicFileInfo(mainChrPacket.szBGMName, mainChrPacket.fBGMVol); + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_LOAD], "LoadData", Py_BuildValue("(ii)", mainChrPacket.lX, mainChrPacket.lY)); + + //Tracef(" >> RecvMainCharacterNew : %d\n", m_dwMainActorEmpire); + + SendClientVersionPacket(); + return true; +} + + +static std::string gs_fieldMusic_fileName; +static float gs_fieldMusic_volume = 1.0f / 5.0f * 0.1f; + +void CPythonNetworkStream::__SetFieldMusicFileName(const char* musicName) +{ + gs_fieldMusic_fileName = musicName; +} + +void CPythonNetworkStream::__SetFieldMusicFileInfo(const char* musicName, float vol) +{ + gs_fieldMusic_fileName = musicName; + gs_fieldMusic_volume = vol; +} + +const char* CPythonNetworkStream::GetFieldMusicFileName() +{ + return gs_fieldMusic_fileName.c_str(); +} + +float CPythonNetworkStream::GetFieldMusicVolume() +{ + return gs_fieldMusic_volume; +} +// END_OF_SUPPORT_BGM + + +bool CPythonNetworkStream::__RecvPlayerPoints() +{ + TPacketGCPoints PointsPacket; + + if (!Recv(sizeof(TPacketGCPoints), &PointsPacket)) + return false; + + for (DWORD i = 0; i < POINT_MAX_NUM; ++i) + CPythonPlayer::Instance().SetStatus(i, PointsPacket.points[i]); + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshStatus", Py_BuildValue("()")); + return true; +} + +void CPythonNetworkStream::StartGame() +{ + m_isStartGame=TRUE; +} + +bool CPythonNetworkStream::SendEnterGame() +{ + TPacketCGEnterFrontGame EnterFrontGamePacket; + + EnterFrontGamePacket.header = HEADER_CG_ENTERGAME; + + if (!Send(sizeof(EnterFrontGamePacket), &EnterFrontGamePacket)) + { + Tracen("Send EnterFrontGamePacket"); + return false; + } + + if (!SendSequence()) + return false; + + __SendInternalBuffer(); + return true; +} diff --git a/source/UserInterface/PythonNetworkStreamPhaseLogin.cpp b/source/UserInterface/PythonNetworkStreamPhaseLogin.cpp new file mode 100644 index 0000000..50ae6b4 --- /dev/null +++ b/source/UserInterface/PythonNetworkStreamPhaseLogin.cpp @@ -0,0 +1,416 @@ +#include "StdAfx.h" +#include "PythonNetworkStream.h" +#include "Packet.h" +#include "Test.h" +#include "AccountConnector.h" + +#include "Hackshield.h" +#include "WiseLogicXTrap.h" + +// Login --------------------------------------------------------------------------- +void CPythonNetworkStream::LoginPhase() +{ + TPacketHeader header; + if (!CheckPacket(&header)) + return; + + switch (header) + { + case HEADER_GC_PHASE: + if (RecvPhasePacket()) + return; + break; + + case HEADER_GC_LOGIN_SUCCESS3: + if (__RecvLoginSuccessPacket3()) + return; + break; + case HEADER_GC_LOGIN_SUCCESS4: + if (__RecvLoginSuccessPacket4()) + return; + break; + + + case HEADER_GC_LOGIN_FAILURE: + if (__RecvLoginFailurePacket()) + return; + break; + + case HEADER_GC_EMPIRE: + if (__RecvEmpirePacket()) + return; + break; + + case HEADER_GC_CHINA_MATRIX_CARD: + if (__RecvChinaMatrixCardPacket()) + return; + break; + + case HEADER_GC_RUNUP_MATRIX_QUIZ: + if (__RecvRunupMatrixQuizPacket()) + return; + break; + + case HEADER_GC_NEWCIBN_PASSPOD_REQUEST: + if (__RecvNEWCIBNPasspodRequestPacket()) + return; + break; + case HEADER_GC_NEWCIBN_PASSPOD_FAILURE: + if (__RecvNEWCIBNPasspodFailurePacket()) + return; + break; + + + case HEADER_GC_LOGIN_KEY: + if (__RecvLoginKeyPacket()) + return; + break; + + case HEADER_GC_PING: + if (RecvPingPacket()) + return; + break; + + case HEADER_GC_HYBRIDCRYPT_KEYS: + RecvHybridCryptKeyPacket(); + return; + break; + + case HEADER_GC_HYBRIDCRYPT_SDB: + RecvHybridCryptSDBPacket(); + return; + break; + + default: + if (RecvDefaultPacket(header)) + return; + break; + } + + RecvErrorPacket(header); +} + +void CPythonNetworkStream::SetLoginPhase() +{ + const char* key = LocaleService_GetSecurityKey(); +#ifndef _IMPROVED_PACKET_ENCRYPTION_ + SetSecurityMode(true, key); +#endif + + if ("Login" != m_strPhase) + m_phaseLeaveFunc.Run(); + + Tracen(""); + Tracen("## Network - Login Phase ##"); + Tracen(""); + + m_strPhase = "Login"; + + m_phaseProcessFunc.Set(this, &CPythonNetworkStream::LoginPhase); + m_phaseLeaveFunc.Set(this, &CPythonNetworkStream::__LeaveLoginPhase); + + m_dwChangingPhaseTime = ELTimer_GetMSec(); + + if (__DirectEnterMode_IsSet()) + { + if (0 != m_dwLoginKey) + SendLoginPacketNew(m_stID.c_str(), m_stPassword.c_str()); + else + SendLoginPacket(m_stID.c_str(), m_stPassword.c_str()); + + // йȣ ޸𸮿 ִ ־, + ClearLoginInfo(); + CAccountConnector & rkAccountConnector = CAccountConnector::Instance(); + rkAccountConnector.ClearLoginInfo(); + } + else + { + if (0 != m_dwLoginKey) + SendLoginPacketNew(m_stID.c_str(), m_stPassword.c_str()); + else + SendLoginPacket(m_stID.c_str(), m_stPassword.c_str()); + + // йȣ ޸𸮿 ִ ־, + ClearLoginInfo(); + CAccountConnector & rkAccountConnector = CAccountConnector::Instance(); + rkAccountConnector.ClearLoginInfo(); + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_LOGIN], "OnLoginStart", Py_BuildValue("()")); + + __ClearSelectCharacterData(); + } +} + +bool CPythonNetworkStream::__RecvEmpirePacket() +{ + TPacketGCEmpire kPacketEmpire; + if (!Recv(sizeof(kPacketEmpire), &kPacketEmpire)) + return false; + + m_dwEmpireID=kPacketEmpire.bEmpire; + return true; +} + +bool CPythonNetworkStream::__RecvLoginSuccessPacket3() +{ + TPacketGCLoginSuccess3 kPacketLoginSuccess; + + if (!Recv(sizeof(kPacketLoginSuccess), &kPacketLoginSuccess)) + return false; + + for (int i = 0; i> ((4 - i - 1) * 8)) & 0x000000FF) +#define COL(cols, i) ((cols >> ((4 - i - 1) * 8)) & 0x000000FF) + +bool CPythonNetworkStream::__RecvChinaMatrixCardPacket() +{ + TPacketGCChinaMatrixCard kMatrixCardPacket; + if (!Recv(sizeof(TPacketGCChinaMatrixCard), &kMatrixCardPacket)) + return false; + + PyObject * pyValue = Py_BuildValue("(iiiiiiii)", ROW(kMatrixCardPacket.dwRows, 0), + ROW(kMatrixCardPacket.dwRows, 1), + ROW(kMatrixCardPacket.dwRows, 2), + ROW(kMatrixCardPacket.dwRows, 3), + COL(kMatrixCardPacket.dwCols, 0), + COL(kMatrixCardPacket.dwCols, 1), + COL(kMatrixCardPacket.dwCols, 2), + COL(kMatrixCardPacket.dwCols, 3)); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_LOGIN], "OnMatrixCard", pyValue); + return true; +} + +bool CPythonNetworkStream::__RecvLoginKeyPacket() +{ + TPacketGCLoginKey kLoginKeyPacket; + if (!Recv(sizeof(TPacketGCLoginKey), &kLoginKeyPacket)) + return false; + + m_dwLoginKey = kLoginKeyPacket.dwLoginKey; + m_isWaitLoginKey = FALSE; + + return true; +} diff --git a/source/UserInterface/PythonNetworkStreamPhaseOffline.cpp b/source/UserInterface/PythonNetworkStreamPhaseOffline.cpp new file mode 100644 index 0000000..754fce8 --- /dev/null +++ b/source/UserInterface/PythonNetworkStreamPhaseOffline.cpp @@ -0,0 +1,22 @@ +#include "StdAfx.h" +#include "PythonNetworkStream.h" +#include "PythonApplication.h" +#include "Packet.h" + +void CPythonNetworkStream::OffLinePhase() +{ + TPacketHeader header; + + if (!CheckPacket(&header)) + return; + + switch (header) + { + case HEADER_GC_PHASE: + if (RecvPhasePacket()) + return; + break; + } + + RecvErrorPacket(header); +} \ No newline at end of file diff --git a/source/UserInterface/PythonNetworkStreamPhaseSelect.cpp b/source/UserInterface/PythonNetworkStreamPhaseSelect.cpp new file mode 100644 index 0000000..157466d --- /dev/null +++ b/source/UserInterface/PythonNetworkStreamPhaseSelect.cpp @@ -0,0 +1,308 @@ +#include "StdAfx.h" +#include "PythonNetworkStream.h" +#include "Packet.h" + +extern DWORD g_adwEncryptKey[4]; +extern DWORD g_adwDecryptKey[4]; + +// Select Character --------------------------------------------------------------------------- +void CPythonNetworkStream::SetSelectPhase() +{ + if ("Select" != m_strPhase) + m_phaseLeaveFunc.Run(); + + Tracen(""); + Tracen("## Network - Select Phase ##"); + Tracen(""); + + m_strPhase = "Select"; + +#ifndef _IMPROVED_PACKET_ENCRYPTION_ + SetSecurityMode(true, (const char *) g_adwEncryptKey, (const char *) g_adwDecryptKey); +#endif + + m_dwChangingPhaseTime = ELTimer_GetMSec(); + m_phaseProcessFunc.Set(this, &CPythonNetworkStream::SelectPhase); + m_phaseLeaveFunc.Set(this, &CPythonNetworkStream::__LeaveSelectPhase); + + if (__DirectEnterMode_IsSet()) + { + PyCallClassMemberFunc(m_poHandler, "SetLoadingPhase", Py_BuildValue("()")); + } + else + { + if (IsSelectedEmpire()) + PyCallClassMemberFunc(m_poHandler, "SetSelectCharacterPhase", Py_BuildValue("()")); + else + PyCallClassMemberFunc(m_poHandler, "SetSelectEmpirePhase", Py_BuildValue("()")); + } +} + +void CPythonNetworkStream::SelectPhase() +{ + TPacketHeader header; + + if (!CheckPacket(&header)) + return; + + switch (header) + { + case HEADER_GC_PHASE: + if (RecvPhasePacket()) + return; + break; + + case HEADER_GC_EMPIRE: + if (__RecvEmpirePacket()) + return; + break; + + case HEADER_GC_LOGIN_SUCCESS3: + if (__RecvLoginSuccessPacket3()) + return; + break; + + case HEADER_GC_LOGIN_SUCCESS4: + if (__RecvLoginSuccessPacket4()) + return; + break; + + + case HEADER_GC_PLAYER_CREATE_SUCCESS: + if (__RecvPlayerCreateSuccessPacket()) + return; + break; + + case HEADER_GC_PLAYER_CREATE_FAILURE: + if (__RecvPlayerCreateFailurePacket()) + return; + break; + + case HEADER_GC_PLAYER_DELETE_WRONG_SOCIAL_ID: + if (__RecvPlayerDestroyFailurePacket()) + return; + break; + + case HEADER_GC_PLAYER_DELETE_SUCCESS: + if (__RecvPlayerDestroySuccessPacket()) + return; + break; + + case HEADER_GC_CHANGE_NAME: + if (__RecvChangeName()) + return; + break; + + case HEADER_GC_HANDSHAKE: + RecvHandshakePacket(); + return; + break; + + case HEADER_GC_HANDSHAKE_OK: + RecvHandshakeOKPacket(); + return; + break; + + case HEADER_GC_HYBRIDCRYPT_KEYS: + RecvHybridCryptKeyPacket(); + return; + break; + + case HEADER_GC_HYBRIDCRYPT_SDB: + RecvHybridCryptSDBPacket(); + return; + break; + + +#ifdef _IMPROVED_PACKET_ENCRYPTION_ + case HEADER_GC_KEY_AGREEMENT: + RecvKeyAgreementPacket(); + return; + break; + + case HEADER_GC_KEY_AGREEMENT_COMPLETED: + RecvKeyAgreementCompletedPacket(); + return; + break; +#endif + + case HEADER_GC_PLAYER_POINT_CHANGE: + TPacketGCPointChange PointChange; + Recv(sizeof(TPacketGCPointChange), &PointChange); + return; + break; + + /////////////////////////////////////////////////////////////////////////////////////////// + case HEADER_GC_PING: + if (RecvPingPacket()) + return; + break; + } + + RecvErrorPacket(header); +} + +bool CPythonNetworkStream::SendSelectEmpirePacket(DWORD dwEmpireID) +{ + TPacketCGEmpire kPacketEmpire; + kPacketEmpire.bHeader=HEADER_CG_EMPIRE; + kPacketEmpire.bEmpire=dwEmpireID; + + if (!Send(sizeof(kPacketEmpire), &kPacketEmpire)) + { + Tracen("SendSelectEmpirePacket - Error"); + return false; + } + + SetEmpireID(dwEmpireID); + return SendSequence(); +} + +bool CPythonNetworkStream::SendSelectCharacterPacket(BYTE Index) +{ + TPacketCGSelectCharacter SelectCharacterPacket; + + SelectCharacterPacket.header = HEADER_CG_PLAYER_SELECT; + SelectCharacterPacket.player_index = Index; + + if (!Send(sizeof(TPacketCGSelectCharacter), &SelectCharacterPacket)) + { + Tracen("SendSelectCharacterPacket - Error"); + return false; + } + + return SendSequence(); +} + +bool CPythonNetworkStream::SendDestroyCharacterPacket(BYTE index, const char * szPrivateCode) +{ + TPacketCGDestroyCharacter DestroyCharacterPacket; + + DestroyCharacterPacket.header = HEADER_CG_PLAYER_DESTROY; + DestroyCharacterPacket.index = index; + strncpy(DestroyCharacterPacket.szPrivateCode, szPrivateCode, PRIVATE_CODE_LENGTH-1); + + if (!Send(sizeof(TPacketCGDestroyCharacter), &DestroyCharacterPacket)) + { + Tracen("SendDestroyCharacterPacket"); + return false; + } + + return SendSequence(); +} + +bool CPythonNetworkStream::SendCreateCharacterPacket(BYTE index, const char *name, BYTE job, BYTE shape, BYTE byCON, BYTE byINT, BYTE bySTR, BYTE byDEX) +{ + TPacketCGCreateCharacter createCharacterPacket; + + createCharacterPacket.header = HEADER_CG_PLAYER_CREATE; + createCharacterPacket.index = index; + strncpy(createCharacterPacket.name, name, CHARACTER_NAME_MAX_LEN); + createCharacterPacket.job = job; + createCharacterPacket.shape = shape; + createCharacterPacket.CON = byCON; + createCharacterPacket.INT = byINT; + createCharacterPacket.STR = bySTR; + createCharacterPacket.DEX = byDEX; + + if (!Send(sizeof(TPacketCGCreateCharacter), &createCharacterPacket)) + { + Tracen("Failed to SendCreateCharacterPacket"); + return false; + } + + return SendSequence(); +} + +bool CPythonNetworkStream::SendChangeNamePacket(BYTE index, const char *name) +{ + TPacketCGChangeName ChangeNamePacket; + ChangeNamePacket.header = HEADER_CG_CHANGE_NAME; + ChangeNamePacket.index = index; + strncpy(ChangeNamePacket.name, name, CHARACTER_NAME_MAX_LEN); + + if (!Send(sizeof(TPacketCGChangeName), &ChangeNamePacket)) + { + Tracen("Failed to SendChangeNamePacket"); + return false; + } + + return SendSequence(); +} + +bool CPythonNetworkStream::__RecvPlayerCreateSuccessPacket() +{ + TPacketGCPlayerCreateSuccess kCreateSuccessPacket; + + if (!Recv(sizeof(kCreateSuccessPacket), &kCreateSuccessPacket)) + return false; + + if (kCreateSuccessPacket.bAccountCharacterSlot>=PLAYER_PER_ACCOUNT4) + { + TraceError("CPythonNetworkStream::RecvPlayerCreateSuccessPacket - OUT OF RANGE SLOT(%d) > PLATER_PER_ACCOUNT(%d)", + kCreateSuccessPacket.bAccountCharacterSlot, PLAYER_PER_ACCOUNT4); + return true; + } + + m_akSimplePlayerInfo[kCreateSuccessPacket.bAccountCharacterSlot]=kCreateSuccessPacket.kSimplePlayerInfomation; + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_CREATE], "OnCreateSuccess", Py_BuildValue("()")); + return true; +} + +bool CPythonNetworkStream::__RecvPlayerCreateFailurePacket() +{ + TPacketGCCreateFailure packet; + + if (!Recv(sizeof(TPacketGCCreateFailure), &packet)) + return false; + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_CREATE], "OnCreateFailure", Py_BuildValue("(i)", packet.bType)); + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_SELECT], "OnCreateFailure", Py_BuildValue("(i)", packet.bType)); + return true; +} + +bool CPythonNetworkStream::__RecvPlayerDestroySuccessPacket() +{ + TPacketGCDestroyCharacterSuccess packet; + if (!Recv(sizeof(TPacketGCDestroyCharacterSuccess), &packet)) + return false; + + memset(&m_akSimplePlayerInfo[packet.account_index], 0, sizeof(m_akSimplePlayerInfo[packet.account_index])); + m_adwGuildID[packet.account_index] = 0; + m_astrGuildName[packet.account_index] = ""; + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_SELECT], "OnDeleteSuccess", Py_BuildValue("(i)", packet.account_index)); + return true; +} + +bool CPythonNetworkStream::__RecvPlayerDestroyFailurePacket() +{ + TPacketGCBlank packet_blank; + if (!Recv(sizeof(TPacketGCBlank), &packet_blank)) + return false; + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_SELECT], "OnDeleteFailure", Py_BuildValue("()")); + return true; +} + +bool CPythonNetworkStream::__RecvChangeName() +{ + TPacketGCChangeName ChangeNamePacket; + if (!Recv(sizeof(TPacketGCChangeName), &ChangeNamePacket)) + return false; + + for (int i = 0; i < PLAYER_PER_ACCOUNT4; ++i) + { + if (ChangeNamePacket.pid == m_akSimplePlayerInfo[i].dwID) + { + m_akSimplePlayerInfo[i].bChangeName = FALSE; + strncpy(m_akSimplePlayerInfo[i].szName, ChangeNamePacket.name, CHARACTER_NAME_MAX_LEN); + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_SELECT], "OnChangeName", Py_BuildValue("(is)", i, ChangeNamePacket.name)); + return true; + } + } + + PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_SELECT], "OnCreateFailure", Py_BuildValue("(i)", 100)); + return true; +} diff --git a/source/UserInterface/PythonNonPlayer.cpp b/source/UserInterface/PythonNonPlayer.cpp new file mode 100644 index 0000000..e54e44b --- /dev/null +++ b/source/UserInterface/PythonNonPlayer.cpp @@ -0,0 +1,197 @@ +#include "stdafx.h" +#include "../eterPack/EterPackManager.h" +#include "pythonnonplayer.h" +#include "InstanceBase.h" +#include "PythonCharacterManager.h" + +bool CPythonNonPlayer::LoadNonPlayerData(const char * c_szFileName) +{ + static DWORD s_adwMobProtoKey[4] = + { + 4813894, + 18955, + 552631, + 6822045 + }; + + CMappedFile file; + LPCVOID pvData; + + Tracef("CPythonNonPlayer::LoadNonPlayerData: %s, sizeof(TMobTable)=%u\n", c_szFileName, sizeof(TMobTable)); + + if (!CEterPackManager::Instance().Get(file, c_szFileName, &pvData)) + return false; + + DWORD dwFourCC, dwElements, dwDataSize; + + file.Read(&dwFourCC, sizeof(DWORD)); + + if (dwFourCC != MAKEFOURCC('M', 'M', 'P', 'T')) + { + TraceError("CPythonNonPlayer::LoadNonPlayerData: invalid Mob proto type %s", c_szFileName); + return false; + } + + file.Read(&dwElements, sizeof(DWORD)); + file.Read(&dwDataSize, sizeof(DWORD)); + + BYTE * pbData = new BYTE[dwDataSize]; + file.Read(pbData, dwDataSize); + ///// + + CLZObject zObj; + + if (!CLZO::Instance().Decompress(zObj, pbData, s_adwMobProtoKey)) + { + delete [] pbData; + return false; + } + + if ((zObj.GetSize() % sizeof(TMobTable)) != 0) + { + TraceError("CPythonNonPlayer::LoadNonPlayerData: invalid size %u check data format.", zObj.GetSize()); + return false; + } + + TMobTable * pTable = (TMobTable *) zObj.GetBuffer(); + for (DWORD i = 0; i < dwElements; ++i, ++pTable) + { + TMobTable * pNonPlayerData = new TMobTable; + + memcpy(pNonPlayerData, pTable, sizeof(TMobTable)); + + //TraceError("%d : %s type[%d] color[%d]", pNonPlayerData->dwVnum, pNonPlayerData->szLocaleName, pNonPlayerData->bType, pNonPlayerData->dwMonsterColor); + m_NonPlayerDataMap.insert(TNonPlayerDataMap::value_type(pNonPlayerData->dwVnum, pNonPlayerData)); + } + + delete [] pbData; + return true; +} + +bool CPythonNonPlayer::GetName(DWORD dwVnum, const char ** c_pszName) +{ + const TMobTable * p = GetTable(dwVnum); + + if (!p) + return false; + + *c_pszName = p->szLocaleName; + + return true; +} + +bool CPythonNonPlayer::GetInstanceType(DWORD dwVnum, BYTE* pbType) +{ + const TMobTable * p = GetTable(dwVnum); + + // dwVnum ã ÷̾ ijͷ Ѵ. ڵ -_- [cronan] + if (!p) + return false; + + *pbType=p->bType; + + return true; +} + +const CPythonNonPlayer::TMobTable * CPythonNonPlayer::GetTable(DWORD dwVnum) +{ + TNonPlayerDataMap::iterator itor = m_NonPlayerDataMap.find(dwVnum); + + if (itor == m_NonPlayerDataMap.end()) + return NULL; + + return itor->second; +} + +BYTE CPythonNonPlayer::GetEventType(DWORD dwVnum) +{ + const TMobTable * p = GetTable(dwVnum); + + if (!p) + { + //Tracef("CPythonNonPlayer::GetEventType - Failed to find virtual number\n"); + return ON_CLICK_EVENT_NONE; + } + + return p->bOnClickType; +} + +BYTE CPythonNonPlayer::GetEventTypeByVID(DWORD dwVID) +{ + CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetInstancePtr(dwVID); + + if (NULL == pInstance) + { + //Tracef("CPythonNonPlayer::GetEventTypeByVID - There is no Virtual Number\n"); + return ON_CLICK_EVENT_NONE; + } + + WORD dwVnum = pInstance->GetVirtualNumber(); + return GetEventType(dwVnum); +} + +const char* CPythonNonPlayer::GetMonsterName(DWORD dwVnum) +{ + const CPythonNonPlayer::TMobTable * c_pTable = GetTable(dwVnum); + if (!c_pTable) + { + static const char* sc_szEmpty=""; + return sc_szEmpty; + } + + return c_pTable->szLocaleName; +} + +DWORD CPythonNonPlayer::GetMonsterColor(DWORD dwVnum) +{ + const CPythonNonPlayer::TMobTable * c_pTable = GetTable(dwVnum); + if (!c_pTable) + return 0; + + return c_pTable->dwMonsterColor; +} + +void CPythonNonPlayer::GetMatchableMobList(int iLevel, int iInterval, TMobTableList * pMobTableList) +{ +/* + pMobTableList->clear(); + + TNonPlayerDataMap::iterator itor = m_NonPlayerDataMap.begin(); + for (; itor != m_NonPlayerDataMap.end(); ++itor) + { + TMobTable * pMobTable = itor->second; + + int iLowerLevelLimit = iLevel-iInterval; + int iUpperLevelLimit = iLevel+iInterval; + + if ((pMobTable->abLevelRange[0] >= iLowerLevelLimit && pMobTable->abLevelRange[0] <= iUpperLevelLimit) || + (pMobTable->abLevelRange[1] >= iLowerLevelLimit && pMobTable->abLevelRange[1] <= iUpperLevelLimit)) + { + pMobTableList->push_back(pMobTable); + } + } +*/ +} + +void CPythonNonPlayer::Clear() +{ +} + +void CPythonNonPlayer::Destroy() +{ + for (TNonPlayerDataMap::iterator itor=m_NonPlayerDataMap.begin(); itor!=m_NonPlayerDataMap.end(); ++itor) + { + delete itor->second; + } + m_NonPlayerDataMap.clear(); +} + +CPythonNonPlayer::CPythonNonPlayer() +{ + Clear(); +} + +CPythonNonPlayer::~CPythonNonPlayer(void) +{ + Destroy(); +} \ No newline at end of file diff --git a/source/UserInterface/PythonNonPlayer.h b/source/UserInterface/PythonNonPlayer.h new file mode 100644 index 0000000..7c3a9a6 --- /dev/null +++ b/source/UserInterface/PythonNonPlayer.h @@ -0,0 +1,142 @@ +#pragma once + +/* + * NPC Ÿ Ѵ. + */ +class CPythonNonPlayer : public CSingleton +{ + public: + enum EClickEvent + { + ON_CLICK_EVENT_NONE = 0, + ON_CLICK_EVENT_BATTLE = 1, + ON_CLICK_EVENT_SHOP = 2, + ON_CLICK_EVENT_TALK = 3, + ON_CLICK_EVENT_VEHICLE = 4, + + ON_CLICK_EVENT_MAX_NUM, + }; + + enum EMobEnchants + { + MOB_ENCHANT_CURSE, + MOB_ENCHANT_SLOW, + MOB_ENCHANT_POISON, + MOB_ENCHANT_STUN, + MOB_ENCHANT_CRITICAL, + MOB_ENCHANT_PENETRATE, + MOB_ENCHANTS_MAX_NUM + }; + enum EMobResists + { + MOB_RESIST_SWORD, + MOB_RESIST_TWOHAND, + MOB_RESIST_DAGGER, + MOB_RESIST_BELL, + MOB_RESIST_FAN, + MOB_RESIST_BOW, + MOB_RESIST_FIRE, + MOB_RESIST_ELECT, + MOB_RESIST_MAGIC, + MOB_RESIST_WIND, + MOB_RESIST_POISON, + MOB_RESISTS_MAX_NUM + }; + + #define MOB_ATTRIBUTE_MAX_NUM 12 + #define MOB_SKILL_MAX_NUM 5 + +#pragma pack(push) +#pragma pack(1) + typedef struct SMobSkillLevel + { + DWORD dwVnum; + BYTE bLevel; + } TMobSkillLevel; + + typedef struct SMobTable + { + DWORD dwVnum; + char szName[CHARACTER_NAME_MAX_LEN + 1]; + char szLocaleName[CHARACTER_NAME_MAX_LEN + 1]; + + BYTE bType; // Monster, NPC + BYTE bRank; // PAWN, KNIGHT, KING + BYTE bBattleType; // MELEE, etc.. + BYTE bLevel; // Level + BYTE bSize; + + DWORD dwGoldMin; + DWORD dwGoldMax; + DWORD dwExp; + DWORD dwMaxHP; + BYTE bRegenCycle; + BYTE bRegenPercent; + WORD wDef; + + DWORD dwAIFlag; + DWORD dwRaceFlag; + DWORD dwImmuneFlag; + + BYTE bStr, bDex, bCon, bInt; + DWORD dwDamageRange[2]; + + short sAttackSpeed; + short sMovingSpeed; + BYTE bAggresiveHPPct; + WORD wAggressiveSight; + WORD wAttackRange; + + char cEnchants[MOB_ENCHANTS_MAX_NUM]; + char cResists[MOB_RESISTS_MAX_NUM]; + + DWORD dwResurrectionVnum; + DWORD dwDropItemVnum; + + BYTE bMountCapacity; + BYTE bOnClickType; + + BYTE bEmpire; + char szFolder[64 + 1]; + float fDamMultiply; + DWORD dwSummonVnum; + DWORD dwDrainSP; + DWORD dwMonsterColor; + DWORD dwPolymorphItemVnum; + + TMobSkillLevel Skills[MOB_SKILL_MAX_NUM]; + + BYTE bBerserkPoint; + BYTE bStoneSkinPoint; + BYTE bGodSpeedPoint; + BYTE bDeathBlowPoint; + BYTE bRevivePoint; + } TMobTable; +#pragma pack(pop) + + typedef std::list TMobTableList; + typedef std::map TNonPlayerDataMap; + + public: + CPythonNonPlayer(void); + virtual ~CPythonNonPlayer(void); + + void Clear(); + void Destroy(); + + bool LoadNonPlayerData(const char * c_szFileName); + + const TMobTable * GetTable(DWORD dwVnum); + bool GetName(DWORD dwVnum, const char ** c_pszName); + bool GetInstanceType(DWORD dwVnum, BYTE* pbType); + BYTE GetEventType(DWORD dwVnum); + BYTE GetEventTypeByVID(DWORD dwVID); + DWORD GetMonsterColor(DWORD dwVnum); + const char* GetMonsterName(DWORD dwVnum); + + // Function for outer + void GetMatchableMobList(int iLevel, int iInterval, TMobTableList * pMobTableList); + + protected: + TNonPlayerDataMap m_NonPlayerDataMap; +}; \ No newline at end of file diff --git a/source/UserInterface/PythonNonPlayerModule.cpp b/source/UserInterface/PythonNonPlayerModule.cpp new file mode 100644 index 0000000..133cdaf --- /dev/null +++ b/source/UserInterface/PythonNonPlayerModule.cpp @@ -0,0 +1,119 @@ +#include "StdAfx.h" +#include "PythonNonPlayer.h" + +#include "InstanceBase.h" +#include "PythonCharacterManager.h" + +PyObject * nonplayerGetEventType(PyObject * poSelf, PyObject * poArgs) +{ + int iVirtualNumber; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualNumber)) + return Py_BuildException(); + + BYTE iType = CPythonNonPlayer::Instance().GetEventType(iVirtualNumber); + + return Py_BuildValue("i", iType); +} + +PyObject * nonplayerGetEventTypeByVID(PyObject * poSelf, PyObject * poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + + BYTE iType = CPythonNonPlayer::Instance().GetEventTypeByVID(iVirtualID); + + return Py_BuildValue("i", iType); +} + +PyObject * nonplayerGetLevelByVID(PyObject * poSelf, PyObject * poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + + CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetInstancePtr(iVirtualID); + + if (!pInstance) + return Py_BuildValue("i", -1); + + const CPythonNonPlayer::TMobTable * pMobTable = CPythonNonPlayer::Instance().GetTable(pInstance->GetVirtualNumber()); + + if (!pMobTable) + return Py_BuildValue("i", -1); + + float fAverageLevel = pMobTable->bLevel;//(float(pMobTable->abLevelRange[0]) + float(pMobTable->abLevelRange[1])) / 2.0f; + fAverageLevel = floor(fAverageLevel + 0.5f); + return Py_BuildValue("i", int(fAverageLevel)); +} + +PyObject * nonplayerGetGradeByVID(PyObject * poSelf, PyObject * poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + + CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetInstancePtr(iVirtualID); + + if (!pInstance) + return Py_BuildValue("i", -1); + + const CPythonNonPlayer::TMobTable * pMobTable = CPythonNonPlayer::Instance().GetTable(pInstance->GetVirtualNumber()); + + if (!pMobTable) + return Py_BuildValue("i", -1); + + return Py_BuildValue("i", pMobTable->bRank); +} + + +PyObject * nonplayerGetMonsterName(PyObject * poSelf, PyObject * poArgs) +{ + int iVNum; + if (!PyTuple_GetInteger(poArgs, 0, &iVNum)) + return Py_BuildException(); + + CPythonNonPlayer& rkNonPlayer=CPythonNonPlayer::Instance(); + return Py_BuildValue("s", rkNonPlayer.GetMonsterName(iVNum)); +} + +PyObject * nonplayerLoadNonPlayerData(PyObject * poSelf, PyObject * poArgs) +{ + char * szFileName; + if(!PyTuple_GetString(poArgs, 0, &szFileName)) + return Py_BuildException(); + + CPythonNonPlayer::Instance().LoadNonPlayerData(szFileName); + return Py_BuildNone(); +} + +void initNonPlayer() +{ + static PyMethodDef s_methods[] = + { + { "GetEventType", nonplayerGetEventType, METH_VARARGS }, + { "GetEventTypeByVID", nonplayerGetEventTypeByVID, METH_VARARGS }, + { "GetLevelByVID", nonplayerGetLevelByVID, METH_VARARGS }, + { "GetGradeByVID", nonplayerGetGradeByVID, METH_VARARGS }, + { "GetMonsterName", nonplayerGetMonsterName, METH_VARARGS }, + + { "LoadNonPlayerData", nonplayerLoadNonPlayerData, METH_VARARGS }, + + { NULL, NULL, NULL }, + }; + + PyObject * poModule = Py_InitModule("nonplayer", s_methods); + + PyModule_AddIntConstant(poModule, "ON_CLICK_EVENT_NONE", CPythonNonPlayer::ON_CLICK_EVENT_NONE); + PyModule_AddIntConstant(poModule, "ON_CLICK_EVENT_BATTLE", CPythonNonPlayer::ON_CLICK_EVENT_BATTLE); + PyModule_AddIntConstant(poModule, "ON_CLICK_EVENT_SHOP", CPythonNonPlayer::ON_CLICK_EVENT_SHOP); + PyModule_AddIntConstant(poModule, "ON_CLICK_EVENT_TALK", CPythonNonPlayer::ON_CLICK_EVENT_TALK); + PyModule_AddIntConstant(poModule, "ON_CLICK_EVENT_VEHICLE", CPythonNonPlayer::ON_CLICK_EVENT_VEHICLE); + + PyModule_AddIntConstant(poModule, "PAWN", 0); + PyModule_AddIntConstant(poModule, "S_PAWN", 1); + PyModule_AddIntConstant(poModule, "KNIGHT", 2); + PyModule_AddIntConstant(poModule, "S_KNIGHT", 3); + PyModule_AddIntConstant(poModule, "BOSS", 4); + PyModule_AddIntConstant(poModule, "KING", 5); +} \ No newline at end of file diff --git a/source/UserInterface/PythonPackModule.cpp b/source/UserInterface/PythonPackModule.cpp new file mode 100644 index 0000000..e3bad81 --- /dev/null +++ b/source/UserInterface/PythonPackModule.cpp @@ -0,0 +1,87 @@ +#include "StdAfx.h" +#include "../eterPack/EterPackManager.h" +#include "../eterBase/tea.h" + +// CHINA_CRYPT_KEY +DWORD g_adwEncryptKey[4]; +DWORD g_adwDecryptKey[4]; + +#include "AccountConnector.h" + +inline const BYTE* GetKey_20050304Myevan() +{ + volatile static DWORD s_adwKey[1938]; + + volatile DWORD seed=1491971513; + for (UINT i=0; i + +void CAccountConnector::__BuildClientKey_20050304Myevan() +{ + const BYTE * c_pszKey = GetKey_20050304Myevan(); + memcpy(g_adwEncryptKey, c_pszKey+157, 16); + + for (DWORD i = 0; i < 4; ++i) + g_adwEncryptKey[i] = random(); + + tea_encrypt((DWORD *) g_adwDecryptKey, (const DWORD *) g_adwEncryptKey, (const DWORD *) (c_pszKey+37), 16); +// TEA_Encrypt((DWORD *) g_adwDecryptKey, (const DWORD *) g_adwEncryptKey, (const DWORD *) (c_pszKey+37), 16); +} +// END_OF_CHINA_CRYPT_KEY + +PyObject * packExist(PyObject * poSelf, PyObject * poArgs) +{ + char * strFileName; + + if (!PyTuple_GetString(poArgs, 0, &strFileName)) + return Py_BuildException(); + + return Py_BuildValue("i", CEterPackManager::Instance().isExist(strFileName)?1:0); +} + +PyObject * packGet(PyObject * poSelf, PyObject * poArgs) +{ + char * strFileName; + + if (!PyTuple_GetString(poArgs, 0, &strFileName)) + return Py_BuildException(); + + // ̽㿡 о帮 ŷ python ϰ txt Ͽ Ѵ + const char* pcExt = strrchr(strFileName, '.'); + if (pcExt) // Ȯڰ ְ + { + if ((stricmp(pcExt, ".py") == 0) || + (stricmp(pcExt, ".pyc") == 0) || + (stricmp(pcExt, ".txt") == 0)) + { + CMappedFile file; + const void * pData = NULL; + + if (CEterPackManager::Instance().Get(file,strFileName,&pData)) + return Py_BuildValue("s#",pData, file.Size()); + } + } + + return Py_BuildException(); +} + +void initpack() +{ + static PyMethodDef s_methods[] = + { + { "Exist", packExist, METH_VARARGS }, + { "Get", packGet, METH_VARARGS }, + { NULL, NULL }, + }; + + Py_InitModule("pack", s_methods); +} \ No newline at end of file diff --git a/source/UserInterface/PythonPlayer.cpp b/source/UserInterface/PythonPlayer.cpp new file mode 100644 index 0000000..caabc0f --- /dev/null +++ b/source/UserInterface/PythonPlayer.cpp @@ -0,0 +1,1731 @@ +#include "StdAfx.h" +#include "PythonPlayerEventHandler.h" +#include "PythonApplication.h" +#include "PythonItem.h" +#include "../eterbase/Timer.h" + +#include "AbstractPlayer.h" + +enum +{ + MAIN_RACE_WARRIOR_M, + MAIN_RACE_ASSASSIN_W, + MAIN_RACE_SURA_M, + MAIN_RACE_SHAMAN_W, + MAIN_RACE_WARRIOR_W, + MAIN_RACE_ASSASSIN_M, + MAIN_RACE_SURA_W, + MAIN_RACE_SHAMAN_M, + MAIN_RACE_MAX_NUM, +}; + +const DWORD POINT_MAGIC_NUMBER = 0xe73ac1da; + +void CPythonPlayer::SPlayerStatus::SetPoint(UINT ePoint, long lPoint) +{ + m_alPoint[ePoint]=lPoint ^ POINT_MAGIC_NUMBER; +} + +long CPythonPlayer::SPlayerStatus::GetPoint(UINT ePoint) +{ + return m_alPoint[ePoint] ^ POINT_MAGIC_NUMBER; +} + +bool CPythonPlayer::AffectIndexToSkillIndex(DWORD dwAffectIndex, DWORD * pdwSkillIndex) +{ + if (m_kMap_dwAffectIndexToSkillIndex.end() == m_kMap_dwAffectIndexToSkillIndex.find(dwAffectIndex)) + return false; + + *pdwSkillIndex = m_kMap_dwAffectIndexToSkillIndex[dwAffectIndex]; + return true; +} + +bool CPythonPlayer::AffectIndexToSkillSlotIndex(UINT uAffect, DWORD* pdwSkillSlotIndex) +{ + DWORD dwSkillIndex=m_kMap_dwAffectIndexToSkillIndex[uAffect]; + + return GetSkillSlotIndex(dwSkillIndex, pdwSkillSlotIndex); +} + +bool CPythonPlayer::__GetPickedActorPtr(CInstanceBase** ppkInstPicked) +{ + CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance(); + CInstanceBase* pkInstPicked=rkChrMgr.OLD_GetPickedInstancePtr(); + if (!pkInstPicked) + return false; + + *ppkInstPicked=pkInstPicked; + return true; +} + +bool CPythonPlayer::__GetPickedActorID(DWORD* pdwActorID) +{ + CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance(); + return rkChrMgr.OLD_GetPickedInstanceVID(pdwActorID); +} + +bool CPythonPlayer::__GetPickedItemID(DWORD* pdwItemID) +{ + CPythonItem& rkItemMgr=CPythonItem::Instance(); + return rkItemMgr.GetPickedItemID(pdwItemID); +} + +bool CPythonPlayer::__GetPickedGroundPos(TPixelPosition* pkPPosPicked) +{ + CPythonBackground& rkBG=CPythonBackground::Instance(); + + TPixelPosition kPPosPicked; + if (rkBG.GetPickingPoint(pkPPosPicked)) + { + pkPPosPicked->y=-pkPPosPicked->y; + return true; + } + + return false; +} + +void CPythonPlayer::NEW_GetMainActorPosition(TPixelPosition* pkPPosActor) +{ + TPixelPosition kPPosMainActor; + + IAbstractPlayer& rkPlayer=IAbstractPlayer::GetSingleton(); + CInstanceBase * pInstance = rkPlayer.NEW_GetMainActorPtr(); + if (pInstance) + { + pInstance->NEW_GetPixelPosition(pkPPosActor); + } + else + { + CPythonApplication::Instance().GetCenterPosition(pkPPosActor); + } +} + + + +bool CPythonPlayer::RegisterEffect(DWORD dwEID, const char* c_szFileName, bool isCache) +{ + if (dwEID>=EFFECT_NUM) + return false; + + CEffectManager& rkEftMgr=CEffectManager::Instance(); + rkEftMgr.RegisterEffect2(c_szFileName, &m_adwEffect[dwEID], isCache); + return true; +} + +void CPythonPlayer::NEW_ShowEffect(int dwEID, TPixelPosition kPPosDst) +{ + if (dwEID>=EFFECT_NUM) + return; + + D3DXVECTOR3 kD3DVt3Pos(kPPosDst.x, -kPPosDst.y, kPPosDst.z); + D3DXVECTOR3 kD3DVt3Dir(0.0f, 0.0f, 1.0f); + + CEffectManager& rkEftMgr=CEffectManager::Instance(); + rkEftMgr.CreateEffect(m_adwEffect[dwEID], kD3DVt3Pos, kD3DVt3Dir); +} + +CInstanceBase* CPythonPlayer::NEW_FindActorPtr(DWORD dwVID) +{ + CPythonCharacterManager& rkChrMgr = CPythonCharacterManager::Instance(); + return rkChrMgr.GetInstancePtr(dwVID); +} + +CInstanceBase* CPythonPlayer::NEW_GetMainActorPtr() +{ + return NEW_FindActorPtr(m_dwMainCharacterIndex); +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +void CPythonPlayer::Update() +{ + NEW_RefreshMouseWalkingDirection(); + + CPythonPlayerEventHandler& rkPlayerEventHandler=CPythonPlayerEventHandler::GetSingleton(); + rkPlayerEventHandler.FlushVictimList(); + + if (m_isDestPosition) + { + CInstanceBase * pInstance = NEW_GetMainActorPtr(); + if (pInstance) + { + TPixelPosition PixelPosition; + pInstance->NEW_GetPixelPosition(&PixelPosition); + + if (abs(int(PixelPosition.x) - m_ixDestPos) + abs(int(PixelPosition.y) - m_iyDestPos) < 10000) + { + m_isDestPosition = FALSE; + } + else + { + if (CTimer::Instance().GetCurrentMillisecond() - m_iLastAlarmTime > 20000) + { + AlarmHaveToGo(); + } + } + } + } + + if (m_isConsumingStamina) + { + float fElapsedTime = CTimer::Instance().GetElapsedSecond(); + m_fCurrentStamina -= (fElapsedTime * m_fConsumeStaminaPerSec); + + SetStatus(POINT_STAMINA, DWORD(m_fCurrentStamina)); + + PyCallClassMemberFunc(m_ppyGameWindow, "RefreshStamina", Py_BuildValue("()")); + } + + __Update_AutoAttack(); + __Update_NotifyGuildAreaEvent(); +} + +bool CPythonPlayer::__IsUsingChargeSkill() +{ + CInstanceBase * pkInstMain = NEW_GetMainActorPtr(); + if (!pkInstMain) + return false; + + if (__CheckDashAffect(*pkInstMain)) + return true; + + if (MODE_USE_SKILL != m_eReservedMode) + return false; + + if (m_dwSkillSlotIndexReserved >= SKILL_MAX_NUM) + return false; + + TSkillInstance & rkSkillInst = m_playerStatus.aSkill[m_dwSkillSlotIndexReserved]; + + CPythonSkill::TSkillData * pSkillData; + if (!CPythonSkill::Instance().GetSkillData(rkSkillInst.dwIndex, &pSkillData)) + return false; + + return pSkillData->IsChargeSkill() ? true : false; +} + +void CPythonPlayer::__Update_AutoAttack() +{ + if (0 == m_dwAutoAttackTargetVID) + return; + + CInstanceBase * pkInstMain = NEW_GetMainActorPtr(); + if (!pkInstMain) + return; + + // źȯ ޷ ߿ ŵ + if (__IsUsingChargeSkill()) + return; + + CInstanceBase* pkInstVictim=NEW_FindActorPtr(m_dwAutoAttackTargetVID); + if (!pkInstVictim) + { + __ClearAutoAttackTargetActorID(); + } + else + { + if (pkInstVictim->IsDead()) + { + __ClearAutoAttackTargetActorID(); + } + else if (pkInstMain->IsMountingHorse() && !pkInstMain->CanAttackHorseLevel()) + { + __ClearAutoAttackTargetActorID(); + } + else if (pkInstMain->IsAttackableInstance(*pkInstVictim)) + { + if (pkInstMain->IsSleep()) + { + //TraceError("SKIP_AUTO_ATTACK_IN_SLEEPING"); + } + else + { + __ReserveClickActor(m_dwAutoAttackTargetVID); + } + } + } +} + +void CPythonPlayer::__Update_NotifyGuildAreaEvent() +{ + CInstanceBase * pkInstMain = NEW_GetMainActorPtr(); + if (pkInstMain) + { + TPixelPosition kPixelPosition; + pkInstMain->NEW_GetPixelPosition(&kPixelPosition); + + DWORD dwAreaID = CPythonMiniMap::Instance().GetGuildAreaID( + ULONG(kPixelPosition.x), ULONG(kPixelPosition.y)); + + if (dwAreaID != m_inGuildAreaID) + { + if (0xffffffff != dwAreaID) + { + PyCallClassMemberFunc(m_ppyGameWindow, "BINARY_Guild_EnterGuildArea", Py_BuildValue("(i)", dwAreaID)); + } + else + { + PyCallClassMemberFunc(m_ppyGameWindow, "BINARY_Guild_ExitGuildArea", Py_BuildValue("(i)", dwAreaID)); + } + + m_inGuildAreaID = dwAreaID; + } + } +} + +void CPythonPlayer::SetMainCharacterIndex(int iIndex) +{ + m_dwMainCharacterIndex = iIndex; + + CInstanceBase* pkInstMain=NEW_GetMainActorPtr(); + if (pkInstMain) + { + CPythonPlayerEventHandler& rkPlayerEventHandler=CPythonPlayerEventHandler::GetSingleton(); + pkInstMain->SetEventHandler(&rkPlayerEventHandler); + } +} + +DWORD CPythonPlayer::GetMainCharacterIndex() +{ + return m_dwMainCharacterIndex; +} + +bool CPythonPlayer::IsMainCharacterIndex(DWORD dwIndex) +{ + return (m_dwMainCharacterIndex == dwIndex); +} + +DWORD CPythonPlayer::GetGuildID() +{ + CInstanceBase* pkInstMain=NEW_GetMainActorPtr(); + if (!pkInstMain) + return 0xffffffff; + + return pkInstMain->GetGuildID(); +} + +void CPythonPlayer::SetWeaponPower(DWORD dwMinPower, DWORD dwMaxPower, DWORD dwMinMagicPower, DWORD dwMaxMagicPower, DWORD dwAddPower) +{ + m_dwWeaponMinPower=dwMinPower; + m_dwWeaponMaxPower=dwMaxPower; + m_dwWeaponMinMagicPower=dwMinMagicPower; + m_dwWeaponMaxMagicPower=dwMaxMagicPower; + m_dwWeaponAddPower=dwAddPower; + + __UpdateBattleStatus(); +} + +void CPythonPlayer::SetRace(DWORD dwRace) +{ + m_dwRace=dwRace; +} + +DWORD CPythonPlayer::GetRace() +{ + return m_dwRace; +} + +DWORD CPythonPlayer::__GetRaceStat() +{ + switch (GetRace()) + { + case MAIN_RACE_WARRIOR_M: + case MAIN_RACE_WARRIOR_W: + return GetStatus(POINT_ST); + break; + case MAIN_RACE_ASSASSIN_M: + case MAIN_RACE_ASSASSIN_W: + return GetStatus(POINT_DX); + break; + case MAIN_RACE_SURA_M: + case MAIN_RACE_SURA_W: + return GetStatus(POINT_ST); + break; + case MAIN_RACE_SHAMAN_M: + case MAIN_RACE_SHAMAN_W: + return GetStatus(POINT_IQ); + break; + } + return GetStatus(POINT_ST); +} + +DWORD CPythonPlayer::__GetLevelAtk() +{ + return 2*GetStatus(POINT_LEVEL); +} + +DWORD CPythonPlayer::__GetStatAtk() +{ + return (4*GetStatus(POINT_ST)+2*__GetRaceStat())/3; +} + +DWORD CPythonPlayer::__GetWeaponAtk(DWORD dwWeaponPower) +{ + return 2*dwWeaponPower; +} + +DWORD CPythonPlayer::__GetTotalAtk(DWORD dwWeaponPower, DWORD dwRefineBonus) +{ + DWORD dwLvAtk=__GetLevelAtk(); + DWORD dwStAtk=__GetStatAtk(); + + ///// + + DWORD dwWepAtk; + DWORD dwTotalAtk; + + if (LocaleService_IsCHEONMA()) + { + dwWepAtk = __GetWeaponAtk(dwWeaponPower+dwRefineBonus); + dwTotalAtk = dwLvAtk+(dwStAtk+dwWepAtk)*(GetStatus(POINT_DX)+210)/300; + } + else + { + int hr = __GetHitRate(); + dwWepAtk = __GetWeaponAtk(dwWeaponPower+dwRefineBonus); + dwTotalAtk = dwLvAtk+(dwStAtk+dwWepAtk)*hr/100; + } + + return dwTotalAtk; +} + +DWORD CPythonPlayer::__GetHitRate() +{ + int src = 0; + + if (LocaleService_IsCHEONMA()) + { + src = GetStatus(POINT_DX); + } + else + { + src = (GetStatus(POINT_DX) * 4 + GetStatus(POINT_LEVEL) * 2)/6; + } + + return 100*(min(90, src)+210)/300; +} + +DWORD CPythonPlayer::__GetEvadeRate() +{ + return 30*(2*GetStatus(POINT_DX)+5)/(GetStatus(POINT_DX)+95); +} + +void CPythonPlayer::__UpdateBattleStatus() +{ + m_playerStatus.SetPoint(POINT_NONE, 0); + m_playerStatus.SetPoint(POINT_EVADE_RATE, __GetEvadeRate()); + m_playerStatus.SetPoint(POINT_HIT_RATE, __GetHitRate()); + m_playerStatus.SetPoint(POINT_MIN_WEP, m_dwWeaponMinPower+m_dwWeaponAddPower); + m_playerStatus.SetPoint(POINT_MAX_WEP, m_dwWeaponMaxPower+m_dwWeaponAddPower); + m_playerStatus.SetPoint(POINT_MIN_MAGIC_WEP, m_dwWeaponMinMagicPower+m_dwWeaponAddPower); + m_playerStatus.SetPoint(POINT_MAX_MAGIC_WEP, m_dwWeaponMaxMagicPower+m_dwWeaponAddPower); + m_playerStatus.SetPoint(POINT_MIN_ATK, __GetTotalAtk(m_dwWeaponMinPower, m_dwWeaponAddPower)); + m_playerStatus.SetPoint(POINT_MAX_ATK, __GetTotalAtk(m_dwWeaponMaxPower, m_dwWeaponAddPower)); +} + +void CPythonPlayer::SetStatus(DWORD dwType, long lValue) +{ + if (dwType >= POINT_MAX_NUM) + { + assert(!" CPythonPlayer::SetStatus - Strange Status Type!"); + Tracef("CPythonPlayer::SetStatus - Set Status Type Error\n"); + return; + } + + if (dwType == POINT_LEVEL) + { + CInstanceBase* pkPlayer = NEW_GetMainActorPtr(); + + if (pkPlayer) + { + pkPlayer->SetLevel(lValue); + pkPlayer->UpdateTextTailLevel(lValue); + } + + } + + switch (dwType) + { + case POINT_MIN_WEP: + case POINT_MAX_WEP: + case POINT_MIN_ATK: + case POINT_MAX_ATK: + case POINT_HIT_RATE: + case POINT_EVADE_RATE: + case POINT_LEVEL: + case POINT_ST: + case POINT_DX: + case POINT_IQ: + m_playerStatus.SetPoint(dwType, lValue); + __UpdateBattleStatus(); + break; + default: + m_playerStatus.SetPoint(dwType, lValue); + break; + } +} + +int CPythonPlayer::GetStatus(DWORD dwType) +{ + if (dwType >= POINT_MAX_NUM) + { + assert(!" CPythonPlayer::GetStatus - Strange Status Type!"); + Tracef("CPythonPlayer::GetStatus - Get Status Type Error\n"); + return 0; + } + + return m_playerStatus.GetPoint(dwType); +} + +const char* CPythonPlayer::GetName() +{ + return m_stName.c_str(); +} + +void CPythonPlayer::SetName(const char *name) +{ + m_stName = name; +} + +void CPythonPlayer::NotifyDeletingCharacterInstance(DWORD dwVID) +{ + if (m_dwMainCharacterIndex == dwVID) + m_dwMainCharacterIndex = 0; +} + +void CPythonPlayer::NotifyCharacterDead(DWORD dwVID) +{ + if (__IsSameTargetVID(dwVID)) + { + SetTarget(0); + } +} + +void CPythonPlayer::NotifyCharacterUpdate(DWORD dwVID) +{ + if (__IsSameTargetVID(dwVID)) + { + CInstanceBase * pMainInstance = NEW_GetMainActorPtr(); + CInstanceBase * pTargetInstance = CPythonCharacterManager::Instance().GetInstancePtr(dwVID); + if (pMainInstance && pTargetInstance) + { + if (!pMainInstance->IsTargetableInstance(*pTargetInstance)) + { + SetTarget(0); + PyCallClassMemberFunc(m_ppyGameWindow, "CloseTargetBoard", Py_BuildValue("()")); + } + else + { + PyCallClassMemberFunc(m_ppyGameWindow, "RefreshTargetBoardByVID", Py_BuildValue("(i)", dwVID)); + } + } + } +} + +void CPythonPlayer::NotifyDeadMainCharacter() +{ + __ClearAutoAttackTargetActorID(); +} + +void CPythonPlayer::NotifyChangePKMode() +{ + PyCallClassMemberFunc(m_ppyGameWindow, "OnChangePKMode", Py_BuildValue("()")); +} + + +void CPythonPlayer::MoveItemData(TItemPos SrcCell, TItemPos DstCell) +{ + if (!SrcCell.IsValidCell() || !DstCell.IsValidCell()) + return; + + TItemData src_item(*GetItemData(SrcCell)); + TItemData dst_item(*GetItemData(DstCell)); + SetItemData(DstCell, src_item); + SetItemData(SrcCell, dst_item); +} + +const TItemData * CPythonPlayer::GetItemData(TItemPos Cell) const +{ + if (!Cell.IsValidCell()) + return NULL; + + switch (Cell.window_type) + { + case INVENTORY: + case EQUIPMENT: + return &m_playerStatus.aItem[Cell.cell]; + case DRAGON_SOUL_INVENTORY: + return &m_playerStatus.aDSItem[Cell.cell]; + default: + return NULL; + } +} + +void CPythonPlayer::SetItemData(TItemPos Cell, const TItemData & c_rkItemInst) +{ + if (!Cell.IsValidCell()) + return; + + if (c_rkItemInst.vnum != 0) + { + CItemData * pItemData; + if (!CItemManager::Instance().GetItemDataPointer(c_rkItemInst.vnum, &pItemData)) + { + TraceError("CPythonPlayer::SetItemData(window_type : %d, dwSlotIndex=%d, itemIndex=%d) - Failed to item data\n", Cell.window_type, Cell.cell, c_rkItemInst.vnum); + return; + } + } + + switch (Cell.window_type) + { + case INVENTORY: + case EQUIPMENT: + m_playerStatus.aItem[Cell.cell] = c_rkItemInst; + break; + case DRAGON_SOUL_INVENTORY: + m_playerStatus.aDSItem[Cell.cell] = c_rkItemInst; + break; + } +} + +DWORD CPythonPlayer::GetItemIndex(TItemPos Cell) +{ + if (!Cell.IsValidCell()) + return 0; + + return GetItemData(Cell)->vnum; +} + +DWORD CPythonPlayer::GetItemFlags(TItemPos Cell) +{ + if (!Cell.IsValidCell()) + return 0; + const TItemData * pItem = GetItemData(Cell); + assert (pItem != NULL); + return pItem->flags; +} + +DWORD CPythonPlayer::GetItemCount(TItemPos Cell) +{ + if (!Cell.IsValidCell()) + return 0; + const TItemData * pItem = GetItemData(Cell); + if (pItem == NULL) + return 0; + else + return pItem->count; +} + +DWORD CPythonPlayer::GetItemCountByVnum(DWORD dwVnum) +{ + DWORD dwCount = 0; + + for (int i = 0; i < c_Inventory_Count; ++i) + { + const TItemData & c_rItemData = m_playerStatus.aItem[i]; + if (c_rItemData.vnum == dwVnum) + { + dwCount += c_rItemData.count; + } + } + + return dwCount; +} + +DWORD CPythonPlayer::GetItemMetinSocket(TItemPos Cell, DWORD dwMetinSocketIndex) +{ + if (!Cell.IsValidCell()) + return 0; + + if (dwMetinSocketIndex >= ITEM_SOCKET_SLOT_MAX_NUM) + return 0; + + return GetItemData(Cell)->alSockets[dwMetinSocketIndex]; +} + +void CPythonPlayer::GetItemAttribute(TItemPos Cell, DWORD dwAttrSlotIndex, BYTE * pbyType, short * psValue) +{ + *pbyType = 0; + *psValue = 0; + + if (!Cell.IsValidCell()) + return; + + if (dwAttrSlotIndex >= ITEM_ATTRIBUTE_SLOT_MAX_NUM) + return; + + *pbyType = GetItemData(Cell)->aAttr[dwAttrSlotIndex].bType; + *psValue = GetItemData(Cell)->aAttr[dwAttrSlotIndex].sValue; +} + +void CPythonPlayer::SetItemCount(TItemPos Cell, BYTE byCount) +{ + if (!Cell.IsValidCell()) + return; + + (const_cast (GetItemData(Cell)))->count = byCount; + PyCallClassMemberFunc(m_ppyGameWindow, "RefreshInventory", Py_BuildValue("()")); +} + +void CPythonPlayer::SetItemMetinSocket(TItemPos Cell, DWORD dwMetinSocketIndex, DWORD dwMetinNumber) +{ + if (!Cell.IsValidCell()) + return; + if (dwMetinSocketIndex >= ITEM_SOCKET_SLOT_MAX_NUM) + return; + + (const_cast (GetItemData(Cell)))->alSockets[dwMetinSocketIndex] = dwMetinNumber; +} + +void CPythonPlayer::SetItemAttribute(TItemPos Cell, DWORD dwAttrIndex, BYTE byType, short sValue) +{ + if (!Cell.IsValidCell()) + return; + if (dwAttrIndex >= ITEM_ATTRIBUTE_SLOT_MAX_NUM) + return; + + (const_cast (GetItemData(Cell)))->aAttr[dwAttrIndex].bType = byType; + (const_cast (GetItemData(Cell)))->aAttr[dwAttrIndex].sValue = sValue; +} + +int CPythonPlayer::GetQuickPage() +{ + return m_playerStatus.lQuickPageIndex; +} + +void CPythonPlayer::SetQuickPage(int nQuickPageIndex) +{ + if (nQuickPageIndex<0) + m_playerStatus.lQuickPageIndex=QUICKSLOT_MAX_LINE+nQuickPageIndex; + else if (nQuickPageIndex>=QUICKSLOT_MAX_LINE) + m_playerStatus.lQuickPageIndex=nQuickPageIndex%QUICKSLOT_MAX_LINE; + else + m_playerStatus.lQuickPageIndex=nQuickPageIndex; + + PyCallClassMemberFunc(m_ppyGameWindow, "RefreshInventory", Py_BuildValue("()")); +} + +DWORD CPythonPlayer::LocalQuickSlotIndexToGlobalQuickSlotIndex(DWORD dwLocalSlotIndex) +{ + return m_playerStatus.lQuickPageIndex*QUICKSLOT_MAX_COUNT_PER_LINE+dwLocalSlotIndex; +} + +void CPythonPlayer::GetGlobalQuickSlotData(DWORD dwGlobalSlotIndex, DWORD* pdwWndType, DWORD* pdwWndItemPos) +{ + TQuickSlot& rkQuickSlot=__RefGlobalQuickSlot(dwGlobalSlotIndex); + *pdwWndType=rkQuickSlot.Type; + *pdwWndItemPos=rkQuickSlot.Position; +} + +void CPythonPlayer::GetLocalQuickSlotData(DWORD dwSlotPos, DWORD* pdwWndType, DWORD* pdwWndItemPos) +{ + TQuickSlot& rkQuickSlot=__RefLocalQuickSlot(dwSlotPos); + *pdwWndType=rkQuickSlot.Type; + *pdwWndItemPos=rkQuickSlot.Position; +} + +TQuickSlot & CPythonPlayer::__RefLocalQuickSlot(int SlotIndex) +{ + return __RefGlobalQuickSlot(LocalQuickSlotIndexToGlobalQuickSlotIndex(SlotIndex)); +} + +TQuickSlot & CPythonPlayer::__RefGlobalQuickSlot(int SlotIndex) +{ + if (SlotIndex < 0 || SlotIndex >= QUICKSLOT_MAX_NUM) + { + static TQuickSlot s_kQuickSlot; + s_kQuickSlot.Type = 0; + s_kQuickSlot.Position = 0; + return s_kQuickSlot; + } + + return m_playerStatus.aQuickSlot[SlotIndex]; +} + +void CPythonPlayer::RemoveQuickSlotByValue(int iType, int iPosition) +{ + for (BYTE i = 0; i < QUICKSLOT_MAX_NUM; ++i) + { + if (iType == m_playerStatus.aQuickSlot[i].Type) + if (iPosition == m_playerStatus.aQuickSlot[i].Position) + CPythonNetworkStream::Instance().SendQuickSlotDelPacket(i); + } +} + +char CPythonPlayer::IsItem(TItemPos Cell) +{ + if (!Cell.IsValidCell()) + return 0; + + return 0 != GetItemData(Cell)->vnum; +} + +void CPythonPlayer::RequestMoveGlobalQuickSlotToLocalQuickSlot(DWORD dwGlobalSrcSlotIndex, DWORD dwLocalDstSlotIndex) +{ + //DWORD dwGlobalSrcSlotIndex=LocalQuickSlotIndexToGlobalQuickSlotIndex(dwLocalSrcSlotIndex); + DWORD dwGlobalDstSlotIndex=LocalQuickSlotIndexToGlobalQuickSlotIndex(dwLocalDstSlotIndex); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendQuickSlotMovePacket((BYTE) dwGlobalSrcSlotIndex, (BYTE)dwGlobalDstSlotIndex); +} + +void CPythonPlayer::RequestAddLocalQuickSlot(DWORD dwLocalSlotIndex, DWORD dwWndType, DWORD dwWndItemPos) +{ + if (dwLocalSlotIndex>=QUICKSLOT_MAX_COUNT_PER_LINE) + return; + + DWORD dwGlobalSlotIndex=LocalQuickSlotIndexToGlobalQuickSlotIndex(dwLocalSlotIndex); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendQuickSlotAddPacket((BYTE)dwGlobalSlotIndex, (BYTE)dwWndType, (BYTE)dwWndItemPos); +} + +void CPythonPlayer::RequestAddToEmptyLocalQuickSlot(DWORD dwWndType, DWORD dwWndItemPos) +{ + for (int i = 0; i < QUICKSLOT_MAX_COUNT_PER_LINE; ++i) + { + TQuickSlot& rkQuickSlot=__RefLocalQuickSlot(i); + + if (0 == rkQuickSlot.Type) + { + DWORD dwGlobalQuickSlotIndex=LocalQuickSlotIndexToGlobalQuickSlotIndex(i); + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendQuickSlotAddPacket((BYTE)dwGlobalQuickSlotIndex, (BYTE)dwWndType, (BYTE)dwWndItemPos); + return; + } + } + +} + +void CPythonPlayer::RequestDeleteGlobalQuickSlot(DWORD dwGlobalSlotIndex) +{ + if (dwGlobalSlotIndex>=QUICKSLOT_MAX_COUNT) + return; + + //if (dwLocalSlotIndex>=QUICKSLOT_MAX_SLOT_PER_LINE) + // return; + + //DWORD dwGlobalSlotIndex=LocalQuickSlotIndexToGlobalQuickSlotIndex(dwLocalSlotIndex); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendQuickSlotDelPacket((BYTE)dwGlobalSlotIndex); +} + +void CPythonPlayer::RequestUseLocalQuickSlot(DWORD dwLocalSlotIndex) +{ + if (dwLocalSlotIndex>=QUICKSLOT_MAX_COUNT_PER_LINE) + return; + + DWORD dwRegisteredType; + DWORD dwRegisteredItemPos; + GetLocalQuickSlotData(dwLocalSlotIndex, &dwRegisteredType, &dwRegisteredItemPos); + + switch (dwRegisteredType) + { + case SLOT_TYPE_INVENTORY: + { + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendItemUsePacket(TItemPos(INVENTORY, (WORD)dwRegisteredItemPos)); + break; + } + case SLOT_TYPE_SKILL: + { + ClickSkillSlot(dwRegisteredItemPos); + break; + } + case SLOT_TYPE_EMOTION: + { + PyCallClassMemberFunc(m_ppyGameWindow, "BINARY_ActEmotion", Py_BuildValue("(i)", dwRegisteredItemPos)); + break; + } + } +} + +void CPythonPlayer::AddQuickSlot(int QuickSlotIndex, char IconType, char IconPosition) +{ + if (QuickSlotIndex < 0 || QuickSlotIndex >= QUICKSLOT_MAX_NUM) + return; + + m_playerStatus.aQuickSlot[QuickSlotIndex].Type = IconType; + m_playerStatus.aQuickSlot[QuickSlotIndex].Position = IconPosition; +} + +void CPythonPlayer::DeleteQuickSlot(int QuickSlotIndex) +{ + if (QuickSlotIndex < 0 || QuickSlotIndex >= QUICKSLOT_MAX_NUM) + return; + + m_playerStatus.aQuickSlot[QuickSlotIndex].Type = 0; + m_playerStatus.aQuickSlot[QuickSlotIndex].Position = 0; +} + +void CPythonPlayer::MoveQuickSlot(int Source, int Target) +{ + if (Source < 0 || Source >= QUICKSLOT_MAX_NUM) + return; + + if (Target < 0 || Target >= QUICKSLOT_MAX_NUM) + return; + + TQuickSlot& rkSrcSlot=__RefGlobalQuickSlot(Source); + TQuickSlot& rkDstSlot=__RefGlobalQuickSlot(Target); + + std::swap(rkSrcSlot, rkDstSlot); +} + +#ifdef ENABLE_NEW_EQUIPMENT_SYSTEM +bool CPythonPlayer::IsBeltInventorySlot(TItemPos Cell) +{ + return Cell.IsBeltInventoryCell(); +} +#endif + +bool CPythonPlayer::IsInventorySlot(TItemPos Cell) +{ + return !Cell.IsEquipCell() && Cell.IsValidCell(); +} + +bool CPythonPlayer::IsEquipmentSlot(TItemPos Cell) +{ + return Cell.IsEquipCell(); +} + +bool CPythonPlayer::IsEquipItemInSlot(TItemPos Cell) +{ + if (!Cell.IsEquipCell()) + { + return false; + } + + const TItemData * pData = GetItemData(Cell); + + if (NULL == pData) + { + return false; + } + + DWORD dwItemIndex = pData->vnum; + + CItemManager::Instance().SelectItemData(dwItemIndex); + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pItemData) + { + TraceError("Failed to find ItemData - CPythonPlayer::IsEquipItem(window_type=%d, iSlotindex=%d)\n", Cell.window_type, Cell.cell); + return false; + } + + return pItemData->IsEquipment() ? true : false; +} + + +void CPythonPlayer::SetSkill(DWORD dwSlotIndex, DWORD dwSkillIndex) +{ + if (dwSlotIndex >= SKILL_MAX_NUM) + return; + + m_playerStatus.aSkill[dwSlotIndex].dwIndex = dwSkillIndex; + m_skillSlotDict[dwSkillIndex] = dwSlotIndex; +} + +int CPythonPlayer::GetSkillIndex(DWORD dwSlotIndex) +{ + if (dwSlotIndex >= SKILL_MAX_NUM) + return 0; + + return m_playerStatus.aSkill[dwSlotIndex].dwIndex; +} + +bool CPythonPlayer::GetSkillSlotIndex(DWORD dwSkillIndex, DWORD* pdwSlotIndex) +{ + std::map::iterator f=m_skillSlotDict.find(dwSkillIndex); + if (m_skillSlotDict.end()==f) + { + return false; + } + + *pdwSlotIndex=f->second; + + return true; +} + +int CPythonPlayer::GetSkillGrade(DWORD dwSlotIndex) +{ + if (dwSlotIndex >= SKILL_MAX_NUM) + return 0; + + return m_playerStatus.aSkill[dwSlotIndex].iGrade; +} + +int CPythonPlayer::GetSkillLevel(DWORD dwSlotIndex) +{ + if (dwSlotIndex >= SKILL_MAX_NUM) + return 0; + + return m_playerStatus.aSkill[dwSlotIndex].iLevel; +} + +float CPythonPlayer::GetSkillCurrentEfficientPercentage(DWORD dwSlotIndex) +{ + if (dwSlotIndex >= SKILL_MAX_NUM) + return 0; + + return m_playerStatus.aSkill[dwSlotIndex].fcurEfficientPercentage; +} + +float CPythonPlayer::GetSkillNextEfficientPercentage(DWORD dwSlotIndex) +{ + if (dwSlotIndex >= SKILL_MAX_NUM) + return 0; + + return m_playerStatus.aSkill[dwSlotIndex].fnextEfficientPercentage; +} + +void CPythonPlayer::SetSkillLevel(DWORD dwSlotIndex, DWORD dwSkillLevel) +{ + assert(!"CPythonPlayer::SetSkillLevel - ʴ Լ"); + if (dwSlotIndex >= SKILL_MAX_NUM) + return; + + m_playerStatus.aSkill[dwSlotIndex].iGrade = -1; + m_playerStatus.aSkill[dwSlotIndex].iLevel = dwSkillLevel; +} + +void CPythonPlayer::SetSkillLevel_(DWORD dwSkillIndex, DWORD dwSkillGrade, DWORD dwSkillLevel) +{ + DWORD dwSlotIndex; + if (!GetSkillSlotIndex(dwSkillIndex, &dwSlotIndex)) + return; + + if (dwSlotIndex >= SKILL_MAX_NUM) + return; + + switch (dwSkillGrade) + { + case 0: + m_playerStatus.aSkill[dwSlotIndex].iGrade = dwSkillGrade; + m_playerStatus.aSkill[dwSlotIndex].iLevel = dwSkillLevel; + break; + case 1: + m_playerStatus.aSkill[dwSlotIndex].iGrade = dwSkillGrade; + m_playerStatus.aSkill[dwSlotIndex].iLevel = dwSkillLevel-20+1; + break; + case 2: + m_playerStatus.aSkill[dwSlotIndex].iGrade = dwSkillGrade; + m_playerStatus.aSkill[dwSlotIndex].iLevel = dwSkillLevel-30+1; + break; + case 3: + m_playerStatus.aSkill[dwSlotIndex].iGrade = dwSkillGrade; + m_playerStatus.aSkill[dwSlotIndex].iLevel = dwSkillLevel-40+1; + break; + } + + const DWORD SKILL_MAX_LEVEL = 40; + + + + + + if (dwSkillLevel>SKILL_MAX_LEVEL) + { + m_playerStatus.aSkill[dwSlotIndex].fcurEfficientPercentage = 0.0f; + m_playerStatus.aSkill[dwSlotIndex].fnextEfficientPercentage = 0.0f; + + TraceError("CPythonPlayer::SetSkillLevel(SlotIndex=%d, SkillLevel=%d)", dwSlotIndex, dwSkillLevel); + return; + } + + m_playerStatus.aSkill[dwSlotIndex].fcurEfficientPercentage = LocaleService_GetSkillPower(dwSkillLevel)/100.0f; + m_playerStatus.aSkill[dwSlotIndex].fnextEfficientPercentage = LocaleService_GetSkillPower(dwSkillLevel+1)/100.0f; + +} + +void CPythonPlayer::SetSkillCoolTime(DWORD dwSkillIndex) +{ + DWORD dwSlotIndex; + if (!GetSkillSlotIndex(dwSkillIndex, &dwSlotIndex)) + { + Tracenf("CPythonPlayer::SetSkillCoolTime(dwSkillIndex=%d) - FIND SLOT ERROR", dwSkillIndex); + return; + } + + if (dwSlotIndex>=SKILL_MAX_NUM) + { + Tracenf("CPythonPlayer::SetSkillCoolTime(dwSkillIndex=%d) - dwSlotIndex=%d/%d OUT OF RANGE", dwSkillIndex, dwSlotIndex, SKILL_MAX_NUM); + return; + } + + m_playerStatus.aSkill[dwSlotIndex].isCoolTime=true; +} + +void CPythonPlayer::EndSkillCoolTime(DWORD dwSkillIndex) +{ + DWORD dwSlotIndex; + if (!GetSkillSlotIndex(dwSkillIndex, &dwSlotIndex)) + { + Tracenf("CPythonPlayer::EndSkillCoolTime(dwSkillIndex=%d) - FIND SLOT ERROR", dwSkillIndex); + return; + } + + if (dwSlotIndex>=SKILL_MAX_NUM) + { + Tracenf("CPythonPlayer::EndSkillCoolTime(dwSkillIndex=%d) - dwSlotIndex=%d/%d OUT OF RANGE", dwSkillIndex, dwSlotIndex, SKILL_MAX_NUM); + return; + } + + m_playerStatus.aSkill[dwSlotIndex].isCoolTime=false; +} + +float CPythonPlayer::GetSkillCoolTime(DWORD dwSlotIndex) +{ + if (dwSlotIndex >= SKILL_MAX_NUM) + return 0.0f; + + return m_playerStatus.aSkill[dwSlotIndex].fCoolTime; +} + +float CPythonPlayer::GetSkillElapsedCoolTime(DWORD dwSlotIndex) +{ + if (dwSlotIndex >= SKILL_MAX_NUM) + return 0.0f; + + return CTimer::Instance().GetCurrentSecond() - m_playerStatus.aSkill[dwSlotIndex].fLastUsedTime; +} + +void CPythonPlayer::__ActivateSkillSlot(DWORD dwSlotIndex) +{ + if (dwSlotIndex>=SKILL_MAX_NUM) + { + Tracenf("CPythonPlayer::ActivavteSkill(dwSlotIndex=%d/%d) - OUT OF RANGE", dwSlotIndex, SKILL_MAX_NUM); + return; + } + + m_playerStatus.aSkill[dwSlotIndex].bActive = TRUE; + PyCallClassMemberFunc(m_ppyGameWindow, "ActivateSkillSlot", Py_BuildValue("(i)", dwSlotIndex)); +} + +void CPythonPlayer::__DeactivateSkillSlot(DWORD dwSlotIndex) +{ + if (dwSlotIndex>=SKILL_MAX_NUM) + { + Tracenf("CPythonPlayer::DeactivavteSkill(dwSlotIndex=%d/%d) - OUT OF RANGE", dwSlotIndex, SKILL_MAX_NUM); + return; + } + + m_playerStatus.aSkill[dwSlotIndex].bActive = FALSE; + PyCallClassMemberFunc(m_ppyGameWindow, "DeactivateSkillSlot", Py_BuildValue("(i)", dwSlotIndex)); +} + +BOOL CPythonPlayer::IsSkillCoolTime(DWORD dwSlotIndex) +{ + if (!__CheckRestSkillCoolTime(dwSlotIndex)) + return FALSE; + + return TRUE; +} + +BOOL CPythonPlayer::IsSkillActive(DWORD dwSlotIndex) +{ + if (dwSlotIndex >= SKILL_MAX_NUM) + return FALSE; + + return m_playerStatus.aSkill[dwSlotIndex].bActive; +} + +BOOL CPythonPlayer::IsToggleSkill(DWORD dwSlotIndex) +{ + if (dwSlotIndex >= SKILL_MAX_NUM) + return FALSE; + + DWORD dwSkillIndex = m_playerStatus.aSkill[dwSlotIndex].dwIndex; + + CPythonSkill::TSkillData * pSkillData; + if (!CPythonSkill::Instance().GetSkillData(dwSkillIndex, &pSkillData)) + return FALSE; + + return pSkillData->IsToggleSkill(); +} + +void CPythonPlayer::SetPlayTime(DWORD dwPlayTime) +{ + m_dwPlayTime = dwPlayTime; +} + +DWORD CPythonPlayer::GetPlayTime() +{ + return m_dwPlayTime; +} + +void CPythonPlayer::SendClickItemPacket(DWORD dwIID) +{ + if (IsObserverMode()) + return; + + static DWORD s_dwNextTCPTime = 0; + + DWORD dwCurTime=ELTimer_GetMSec(); + + if (dwCurTime >= s_dwNextTCPTime) + { + s_dwNextTCPTime=dwCurTime + 500; + + const char * c_szOwnerName; + if (!CPythonItem::Instance().GetOwnership(dwIID, &c_szOwnerName)) + return; + + if (strlen(c_szOwnerName) > 0) + if (0 != strcmp(c_szOwnerName, GetName())) + { + CItemData * pItemData; + if (!CItemManager::Instance().GetItemDataPointer(CPythonItem::Instance().GetVirtualNumberOfGroundItem(dwIID), &pItemData)) + { + Tracenf("CPythonPlayer::SendClickItemPacket(dwIID=%d) : Non-exist item.", dwIID); + return; + } + if (!IsPartyMemberByName(c_szOwnerName) || pItemData->IsAntiFlag(CItemData::ITEM_ANTIFLAG_DROP | CItemData::ITEM_ANTIFLAG_GIVE)) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotPickItem", Py_BuildValue("()")); + return; + } + } + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendItemPickUpPacket(dwIID); + } +} + +void CPythonPlayer::__SendClickActorPacket(CInstanceBase& rkInstVictim) +{ + // Ÿ ij Ϳ ó + CInstanceBase* pkInstMain=NEW_GetMainActorPtr(); + if (pkInstMain) + if (pkInstMain->IsHoldingPickAxe()) + if (pkInstMain->IsMountingHorse()) + if (rkInstVictim.IsResource()) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotMining", Py_BuildValue("()")); + return; + } + + static DWORD s_dwNextTCPTime = 0; + + DWORD dwCurTime=ELTimer_GetMSec(); + + if (dwCurTime >= s_dwNextTCPTime) + { + s_dwNextTCPTime=dwCurTime+1000; + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + + DWORD dwVictimVID=rkInstVictim.GetVirtualID(); + rkNetStream.SendOnClickPacket(dwVictimVID); + } +} + +void CPythonPlayer::ActEmotion(DWORD dwEmotionID) +{ + CInstanceBase * pkInstTarget = __GetAliveTargetInstancePtr(); + if (!pkInstTarget) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotShotError", Py_BuildValue("(is)", GetMainCharacterIndex(), "NEED_TARGET")); + return; + } + + CPythonNetworkStream::Instance().SendChatPacket(_getf("/kiss %s", pkInstTarget->GetNameString())); +} + +void CPythonPlayer::StartEmotionProcess() +{ + __ClearReservedAction(); + __ClearAutoAttackTargetActorID(); + + m_bisProcessingEmotion = TRUE; +} + +void CPythonPlayer::EndEmotionProcess() +{ + m_bisProcessingEmotion = FALSE; +} + +BOOL CPythonPlayer::__IsProcessingEmotion() +{ + return m_bisProcessingEmotion; +} + +// Dungeon +void CPythonPlayer::SetDungeonDestinationPosition(int ix, int iy) +{ + m_isDestPosition = TRUE; + m_ixDestPos = ix; + m_iyDestPos = iy; + + AlarmHaveToGo(); +} + +void CPythonPlayer::AlarmHaveToGo() +{ + m_iLastAlarmTime = CTimer::Instance().GetCurrentMillisecond(); + + ///// + + CInstanceBase * pInstance = NEW_GetMainActorPtr(); + if (!pInstance) + return; + + TPixelPosition PixelPosition; + pInstance->NEW_GetPixelPosition(&PixelPosition); + + float fAngle = GetDegreeFromPosition2(PixelPosition.x, PixelPosition.y, float(m_ixDestPos), float(m_iyDestPos)); + fAngle = fmod(540.0f - fAngle, 360.0f); + D3DXVECTOR3 v3Rotation(0.0f, 0.0f, fAngle); + + PixelPosition.y *= -1.0f; + + CEffectManager::Instance().RegisterEffect("d:/ymir work/effect/etc/compass/appear_middle.mse"); + CEffectManager::Instance().CreateEffect("d:/ymir work/effect/etc/compass/appear_middle.mse", PixelPosition, v3Rotation); +} + +// Party +void CPythonPlayer::ExitParty() +{ + m_PartyMemberMap.clear(); + + CPythonCharacterManager::Instance().RefreshAllPCTextTail(); +} + +void CPythonPlayer::AppendPartyMember(DWORD dwPID, const char * c_szName) +{ + m_PartyMemberMap.insert(std::make_pair(dwPID, TPartyMemberInfo(dwPID, c_szName))); +} + +void CPythonPlayer::LinkPartyMember(DWORD dwPID, DWORD dwVID) +{ + TPartyMemberInfo * pPartyMemberInfo; + if (!GetPartyMemberPtr(dwPID, &pPartyMemberInfo)) + { + TraceError(" CPythonPlayer::LinkPartyMember(dwPID=%d, dwVID=%d) - Failed to find party member", dwPID, dwVID); + return; + } + + pPartyMemberInfo->dwVID = dwVID; + + CInstanceBase * pInstance = NEW_FindActorPtr(dwVID); + if (pInstance) + pInstance->RefreshTextTail(); +} + +void CPythonPlayer::UnlinkPartyMember(DWORD dwPID) +{ + TPartyMemberInfo * pPartyMemberInfo; + if (!GetPartyMemberPtr(dwPID, &pPartyMemberInfo)) + { + TraceError(" CPythonPlayer::UnlinkPartyMember(dwPID=%d) - Failed to find party member", dwPID); + return; + } + + pPartyMemberInfo->dwVID = 0; +} + +void CPythonPlayer::UpdatePartyMemberInfo(DWORD dwPID, BYTE byState, BYTE byHPPercentage) +{ + TPartyMemberInfo * pPartyMemberInfo; + if (!GetPartyMemberPtr(dwPID, &pPartyMemberInfo)) + { + TraceError(" CPythonPlayer::UpdatePartyMemberInfo(dwPID=%d, byState=%d, byHPPercentage=%d) - Failed to find character", dwPID, byState, byHPPercentage); + return; + } + + pPartyMemberInfo->byState = byState; + pPartyMemberInfo->byHPPercentage = byHPPercentage; +} + +void CPythonPlayer::UpdatePartyMemberAffect(DWORD dwPID, BYTE byAffectSlotIndex, short sAffectNumber) +{ + if (byAffectSlotIndex >= PARTY_AFFECT_SLOT_MAX_NUM) + { + TraceError(" CPythonPlayer::UpdatePartyMemberAffect(dwPID=%d, byAffectSlotIndex=%d, sAffectNumber=%d) - Strange affect slot index", dwPID, byAffectSlotIndex, sAffectNumber); + return; + } + + TPartyMemberInfo * pPartyMemberInfo; + if (!GetPartyMemberPtr(dwPID, &pPartyMemberInfo)) + { + TraceError(" CPythonPlayer::UpdatePartyMemberAffect(dwPID=%d, byAffectSlotIndex=%d, sAffectNumber=%d) - Failed to find character", dwPID, byAffectSlotIndex, sAffectNumber); + return; + } + + pPartyMemberInfo->sAffects[byAffectSlotIndex] = sAffectNumber; +} + +void CPythonPlayer::RemovePartyMember(DWORD dwPID) +{ + DWORD dwVID = 0; + TPartyMemberInfo * pPartyMemberInfo; + if (GetPartyMemberPtr(dwPID, &pPartyMemberInfo)) + { + dwVID = pPartyMemberInfo->dwVID; + } + + m_PartyMemberMap.erase(dwPID); + + if (dwVID > 0) + { + CInstanceBase * pInstance = NEW_FindActorPtr(dwVID); + if (pInstance) + pInstance->RefreshTextTail(); + } +} + +bool CPythonPlayer::IsPartyMemberByVID(DWORD dwVID) +{ + std::map::iterator itor = m_PartyMemberMap.begin(); + for (; itor != m_PartyMemberMap.end(); ++itor) + { + TPartyMemberInfo & rPartyMemberInfo = itor->second; + if (dwVID == rPartyMemberInfo.dwVID) + return true; + } + + return false; +} + +bool CPythonPlayer::IsPartyMemberByName(const char * c_szName) +{ + std::map::iterator itor = m_PartyMemberMap.begin(); + for (; itor != m_PartyMemberMap.end(); ++itor) + { + TPartyMemberInfo & rPartyMemberInfo = itor->second; + if (0 == rPartyMemberInfo.strName.compare(c_szName)) + return true; + } + + return false; +} + +bool CPythonPlayer::GetPartyMemberPtr(DWORD dwPID, TPartyMemberInfo ** ppPartyMemberInfo) +{ + std::map::iterator itor = m_PartyMemberMap.find(dwPID); + + if (m_PartyMemberMap.end() == itor) + return false; + + *ppPartyMemberInfo = &(itor->second); + + return true; +} + +bool CPythonPlayer::PartyMemberPIDToVID(DWORD dwPID, DWORD * pdwVID) +{ + std::map::iterator itor = m_PartyMemberMap.find(dwPID); + + if (m_PartyMemberMap.end() == itor) + return false; + + const TPartyMemberInfo & c_rPartyMemberInfo = itor->second; + *pdwVID = c_rPartyMemberInfo.dwVID; + + return true; +} + +bool CPythonPlayer::PartyMemberVIDToPID(DWORD dwVID, DWORD * pdwPID) +{ + std::map::iterator itor = m_PartyMemberMap.begin(); + for (; itor != m_PartyMemberMap.end(); ++itor) + { + TPartyMemberInfo & rPartyMemberInfo = itor->second; + if (dwVID == rPartyMemberInfo.dwVID) + { + *pdwPID = rPartyMemberInfo.dwPID; + return true; + } + } + + return false; +} + +bool CPythonPlayer::IsSamePartyMember(DWORD dwVID1, DWORD dwVID2) +{ + return (IsPartyMemberByVID(dwVID1) && IsPartyMemberByVID(dwVID2)); +} + +// PVP +void CPythonPlayer::RememberChallengeInstance(DWORD dwVID) +{ + m_RevengeInstanceSet.erase(dwVID); + m_ChallengeInstanceSet.insert(dwVID); +} +void CPythonPlayer::RememberRevengeInstance(DWORD dwVID) +{ + m_ChallengeInstanceSet.erase(dwVID); + m_RevengeInstanceSet.insert(dwVID); +} +void CPythonPlayer::RememberCantFightInstance(DWORD dwVID) +{ + m_CantFightInstanceSet.insert(dwVID); +} +void CPythonPlayer::ForgetInstance(DWORD dwVID) +{ + m_ChallengeInstanceSet.erase(dwVID); + m_RevengeInstanceSet.erase(dwVID); + m_CantFightInstanceSet.erase(dwVID); +} + +bool CPythonPlayer::IsChallengeInstance(DWORD dwVID) +{ + return m_ChallengeInstanceSet.end() != m_ChallengeInstanceSet.find(dwVID); +} +bool CPythonPlayer::IsRevengeInstance(DWORD dwVID) +{ + return m_RevengeInstanceSet.end() != m_RevengeInstanceSet.find(dwVID); +} +bool CPythonPlayer::IsCantFightInstance(DWORD dwVID) +{ + return m_CantFightInstanceSet.end() != m_CantFightInstanceSet.find(dwVID); +} + +void CPythonPlayer::OpenPrivateShop() +{ + m_isOpenPrivateShop = TRUE; +} +void CPythonPlayer::ClosePrivateShop() +{ + m_isOpenPrivateShop = FALSE; +} + +bool CPythonPlayer::IsOpenPrivateShop() +{ + return m_isOpenPrivateShop; +} + +void CPythonPlayer::SetObserverMode(bool isEnable) +{ + m_isObserverMode=isEnable; +} + +bool CPythonPlayer::IsObserverMode() +{ + return m_isObserverMode; +} + + +BOOL CPythonPlayer::__ToggleCoolTime() +{ + m_sysIsCoolTime = 1 - m_sysIsCoolTime; + return m_sysIsCoolTime; +} + +BOOL CPythonPlayer::__ToggleLevelLimit() +{ + m_sysIsLevelLimit = 1 - m_sysIsLevelLimit; + return m_sysIsLevelLimit; +} + +void CPythonPlayer::StartStaminaConsume(DWORD dwConsumePerSec, DWORD dwCurrentStamina) +{ + m_isConsumingStamina = TRUE; + m_fConsumeStaminaPerSec = float(dwConsumePerSec); + m_fCurrentStamina = float(dwCurrentStamina); + + SetStatus(POINT_STAMINA, dwCurrentStamina); +} + +void CPythonPlayer::StopStaminaConsume(DWORD dwCurrentStamina) +{ + m_isConsumingStamina = FALSE; + m_fConsumeStaminaPerSec = 0.0f; + m_fCurrentStamina = float(dwCurrentStamina); + + SetStatus(POINT_STAMINA, dwCurrentStamina); +} + +DWORD CPythonPlayer::GetPKMode() +{ + CInstanceBase * pInstance = NEW_GetMainActorPtr(); + if (!pInstance) + return 0; + + return pInstance->GetPKMode(); +} + +void CPythonPlayer::SetMobileFlag(BOOL bFlag) +{ + m_bMobileFlag = bFlag; + PyCallClassMemberFunc(m_ppyGameWindow, "RefreshMobile", Py_BuildValue("()")); +} + +BOOL CPythonPlayer::HasMobilePhoneNumber() +{ + return m_bMobileFlag; +} + +void CPythonPlayer::SetGameWindow(PyObject * ppyObject) +{ + m_ppyGameWindow = ppyObject; +} + +void CPythonPlayer::NEW_ClearSkillData(bool bAll) +{ + std::map::iterator it; + + for (it = m_skillSlotDict.begin(); it != m_skillSlotDict.end();) + { + if (bAll || __GetSkillType(it->first) == CPythonSkill::SKILL_TYPE_ACTIVE) + it = m_skillSlotDict.erase(it); + else + ++it; + } + + for (int i = 0; i < SKILL_MAX_NUM; ++i) + { + ZeroMemory(&m_playerStatus.aSkill[i], sizeof(TSkillInstance)); + } + + for (int j = 0; j < SKILL_MAX_NUM; ++j) + { + // 2004.09.30.myevan.ųŽ ų Ʈ[+] ư ȳ ó + m_playerStatus.aSkill[j].iGrade = 0; + m_playerStatus.aSkill[j].fcurEfficientPercentage=0.0f; + m_playerStatus.aSkill[j].fnextEfficientPercentage=0.05f; + } + + if (m_ppyGameWindow) + PyCallClassMemberFunc(m_ppyGameWindow, "BINARY_CheckGameButton", Py_BuildNone()); +} + +void CPythonPlayer::ClearSkillDict() +{ + // ClearSkillDict + m_skillSlotDict.clear(); + + // Game End - Player Data Reset + m_isOpenPrivateShop = false; + m_isObserverMode = false; + + m_isConsumingStamina = FALSE; + m_fConsumeStaminaPerSec = 0.0f; + m_fCurrentStamina = 0.0f; + + m_bMobileFlag = FALSE; + + __ClearAutoAttackTargetActorID(); +} + +void CPythonPlayer::Clear() +{ + memset(&m_playerStatus, 0, sizeof(m_playerStatus)); + NEW_ClearSkillData(true); + + m_bisProcessingEmotion = FALSE; + + m_dwSendingTargetVID = 0; + m_fTargetUpdateTime = 0.0f; + + // Test Code for Status Interface + m_stName = ""; + m_dwMainCharacterIndex = 0; + m_dwRace = 0; + m_dwWeaponMinPower = 0; + m_dwWeaponMaxPower = 0; + m_dwWeaponMinMagicPower = 0; + m_dwWeaponMaxMagicPower = 0; + m_dwWeaponAddPower = 0; + + ///// + m_MovingCursorPosition = TPixelPosition(0, 0, 0); + m_fMovingCursorSettingTime = 0.0f; + + m_eReservedMode = MODE_NONE; + m_fReservedDelayTime = 0.0f; + m_kPPosReserved = TPixelPosition(0, 0, 0); + m_dwVIDReserved = 0; + m_dwIIDReserved = 0; + m_dwSkillSlotIndexReserved = 0; + m_dwSkillRangeReserved = 0; + + m_isUp = false; + m_isDown = false; + m_isLeft = false; + m_isRight = false; + m_isSmtMov = false; + m_isDirMov = false; + m_isDirKey = false; + m_isAtkKey = false; + + m_isCmrRot = true; + m_fCmrRotSpd = 20.0f; + + m_iComboOld = 0; + + m_dwVIDPicked=0; + m_dwIIDPicked=0; + + m_dwcurSkillSlotIndex = DWORD(-1); + + m_dwTargetVID = 0; + m_dwTargetEndTime = 0; + + m_PartyMemberMap.clear(); + + m_ChallengeInstanceSet.clear(); + m_RevengeInstanceSet.clear(); + + m_isOpenPrivateShop = false; + m_isObserverMode = false; + + m_isConsumingStamina = FALSE; + m_fConsumeStaminaPerSec = 0.0f; + m_fCurrentStamina = 0.0f; + + m_inGuildAreaID = 0xffffffff; + + m_bMobileFlag = FALSE; + + __ClearAutoAttackTargetActorID(); +} + +CPythonPlayer::CPythonPlayer(void) +{ + SetMovableGroundDistance(40.0f); + + // AffectIndex To SkillIndex + m_kMap_dwAffectIndexToSkillIndex.insert(std::make_pair(int(CInstanceBase::AFFECT_JEONGWI), 3)); + m_kMap_dwAffectIndexToSkillIndex.insert(std::make_pair(int(CInstanceBase::AFFECT_GEOMGYEONG), 4)); + m_kMap_dwAffectIndexToSkillIndex.insert(std::make_pair(int(CInstanceBase::AFFECT_CHEONGEUN), 19)); + m_kMap_dwAffectIndexToSkillIndex.insert(std::make_pair(int(CInstanceBase::AFFECT_GYEONGGONG), 49)); + m_kMap_dwAffectIndexToSkillIndex.insert(std::make_pair(int(CInstanceBase::AFFECT_EUNHYEONG), 34)); + m_kMap_dwAffectIndexToSkillIndex.insert(std::make_pair(int(CInstanceBase::AFFECT_GONGPO), 64)); + m_kMap_dwAffectIndexToSkillIndex.insert(std::make_pair(int(CInstanceBase::AFFECT_JUMAGAP), 65)); + m_kMap_dwAffectIndexToSkillIndex.insert(std::make_pair(int(CInstanceBase::AFFECT_HOSIN), 94)); + m_kMap_dwAffectIndexToSkillIndex.insert(std::make_pair(int(CInstanceBase::AFFECT_BOHO), 95)); + m_kMap_dwAffectIndexToSkillIndex.insert(std::make_pair(int(CInstanceBase::AFFECT_KWAESOK), 110)); + m_kMap_dwAffectIndexToSkillIndex.insert(std::make_pair(int(CInstanceBase::AFFECT_GICHEON), 96)); + m_kMap_dwAffectIndexToSkillIndex.insert(std::make_pair(int(CInstanceBase::AFFECT_JEUNGRYEOK), 111)); + m_kMap_dwAffectIndexToSkillIndex.insert(std::make_pair(int(CInstanceBase::AFFECT_PABEOP), 66)); + m_kMap_dwAffectIndexToSkillIndex.insert(std::make_pair(int(CInstanceBase::AFFECT_FALLEN_CHEONGEUN), 19)); + ///// + m_kMap_dwAffectIndexToSkillIndex.insert(std::make_pair(int(CInstanceBase::AFFECT_GWIGEOM), 63)); + m_kMap_dwAffectIndexToSkillIndex.insert(std::make_pair(int(CInstanceBase::AFFECT_MUYEONG), 78)); + m_kMap_dwAffectIndexToSkillIndex.insert(std::make_pair(int(CInstanceBase::AFFECT_HEUKSIN), 79)); + + m_ppyGameWindow = NULL; + + m_sysIsCoolTime = TRUE; + m_sysIsLevelLimit = TRUE; + m_dwPlayTime = 0; + + m_aeMBFButton[MBT_LEFT]=CPythonPlayer::MBF_SMART; + m_aeMBFButton[MBT_RIGHT]=CPythonPlayer::MBF_CAMERA; + m_aeMBFButton[MBT_MIDDLE]=CPythonPlayer::MBF_CAMERA; + + memset(m_adwEffect, 0, sizeof(m_adwEffect)); + + m_isDestPosition = FALSE; + m_ixDestPos = 0; + m_iyDestPos = 0; + m_iLastAlarmTime = 0; + + Clear(); +} + +CPythonPlayer::~CPythonPlayer(void) +{ +} diff --git a/source/UserInterface/PythonPlayer.h b/source/UserInterface/PythonPlayer.h new file mode 100644 index 0000000..328507c --- /dev/null +++ b/source/UserInterface/PythonPlayer.h @@ -0,0 +1,689 @@ +#pragma once + +#include "AbstractPlayer.h" +#include "Packet.h" +#include "PythonSkill.h" + +class CInstanceBase; + +/* + * ij (ڽ ϴ ij) Ѵ. + * + * 2003-01-12 Levites CPythonCharacter ־ Ը ʹ Ŀ + * ġ ָؼ и + * 2003-07-19 Levites ij ̵ ó CharacterInstance + * Ÿ ҿ Ϻ ÷̾ Ŭ + * Żٲ . + */ + +class CPythonPlayer : public CSingleton, public IAbstractPlayer +{ + public: + enum + { + CATEGORY_NONE = 0, + CATEGORY_ACTIVE = 1, + CATEGORY_PASSIVE = 2, + CATEGORY_MAX_NUM = 3, + + STATUS_INDEX_ST = 1, + STATUS_INDEX_DX = 2, + STATUS_INDEX_IQ = 3, + STATUS_INDEX_HT = 4, + }; + + enum + { + MBT_LEFT, + MBT_RIGHT, + MBT_MIDDLE, + MBT_NUM, + }; + + enum + { + MBF_SMART, + MBF_MOVE, + MBF_CAMERA, + MBF_ATTACK, + MBF_SKILL, + MBF_AUTO, + }; + + enum + { + MBS_CLICK, + MBS_PRESS, + }; + + enum EMode + { + MODE_NONE, + MODE_CLICK_POSITION, + MODE_CLICK_ITEM, + MODE_CLICK_ACTOR, + MODE_USE_SKILL, + }; + + enum EEffect + { + EFFECT_PICK, + EFFECT_NUM, + }; + + enum EMetinSocketType + { + METIN_SOCKET_TYPE_NONE, + METIN_SOCKET_TYPE_SILVER, + METIN_SOCKET_TYPE_GOLD, + }; + + typedef struct SSkillInstance + { + DWORD dwIndex; + int iType; + int iGrade; + int iLevel; + float fcurEfficientPercentage; + float fnextEfficientPercentage; + BOOL isCoolTime; + + float fCoolTime; // NOTE : Ÿ ų + float fLastUsedTime; // â ϴ + BOOL bActive; + } TSkillInstance; + + enum EKeyBoard_UD + { + KEYBOARD_UD_NONE, + KEYBOARD_UD_UP, + KEYBOARD_UD_DOWN, + }; + + enum EKeyBoard_LR + { + KEYBOARD_LR_NONE, + KEYBOARD_LR_LEFT, + KEYBOARD_LR_RIGHT, + }; + + enum + { + DIR_UP, + DIR_DOWN, + DIR_LEFT, + DIR_RIGHT, + }; + + typedef struct SPlayerStatus + { + TItemData aItem[c_Inventory_Count]; + TItemData aDSItem[c_DragonSoul_Inventory_Count]; + TQuickSlot aQuickSlot[QUICKSLOT_MAX_NUM]; + TSkillInstance aSkill[SKILL_MAX_NUM]; + long m_alPoint[POINT_MAX_NUM]; + long lQuickPageIndex; + + void SetPoint(UINT ePoint, long lPoint); + long GetPoint(UINT ePoint); + } TPlayerStatus; + + typedef struct SPartyMemberInfo + { + SPartyMemberInfo(DWORD _dwPID, const char * c_szName) : dwPID(_dwPID), strName(c_szName), dwVID(0) {} + + DWORD dwVID; + DWORD dwPID; + std::string strName; + BYTE byState; + BYTE byHPPercentage; + short sAffects[PARTY_AFFECT_SLOT_MAX_NUM]; + } TPartyMemberInfo; + + enum EPartyRole + { + PARTY_ROLE_NORMAL, + PARTY_ROLE_LEADER, + PARTY_ROLE_ATTACKER, + PARTY_ROLE_TANKER, + PARTY_ROLE_BUFFER, + PARTY_ROLE_SKILL_MASTER, + PARTY_ROLE_BERSERKER, + PARTY_ROLE_DEFENDER, + PARTY_ROLE_MAX_NUM, + }; + + enum + { + SKILL_NORMAL, + SKILL_MASTER, + SKILL_GRAND_MASTER, + SKILL_PERFECT_MASTER, + }; + + // ڵ Ưȭ ü.. ̷ Ưȭ ó ۾ Ϸ ִ ϰ ᱹ Ưȭó. + struct SAutoPotionInfo + { + SAutoPotionInfo() : bActivated(false), totalAmount(0), currentAmount(0) {} + + bool bActivated; // Ȱȭ Ǿ°? + long currentAmount; // + long totalAmount; // ü + long inventorySlotIndex; // κ丮 ε + }; + + enum EAutoPotionType + { + AUTO_POTION_TYPE_HP = 0, + AUTO_POTION_TYPE_SP = 1, + AUTO_POTION_TYPE_NUM + }; + + public: + CPythonPlayer(void); + virtual ~CPythonPlayer(void); + + void PickCloseMoney(); + void PickCloseItem(); + + void SetGameWindow(PyObject * ppyObject); + + void SetObserverMode(bool isEnable); + bool IsObserverMode(); + + void SetQuickCameraMode(bool isEnable); + + void SetAttackKeyState(bool isPress); + + void NEW_GetMainActorPosition(TPixelPosition* pkPPosActor); + + bool RegisterEffect(DWORD dwEID, const char* c_szEftFileName, bool isCache); + + bool NEW_SetMouseState(int eMBType, int eMBState); + bool NEW_SetMouseFunc(int eMBType, int eMBFunc); + int NEW_GetMouseFunc(int eMBT); + void NEW_SetMouseMiddleButtonState(int eMBState); + + void NEW_SetAutoCameraRotationSpeed(float fRotSpd); + void NEW_ResetCameraRotation(); + + void NEW_SetSingleDirKeyState(int eDirKey, bool isPress); + void NEW_SetSingleDIKKeyState(int eDIKKey, bool isPress); + void NEW_SetMultiDirKeyState(bool isLeft, bool isRight, bool isUp, bool isDown); + + void NEW_Attack(); + void NEW_Fishing(); + bool NEW_CancelFishing(); + + void NEW_LookAtFocusActor(); + bool NEW_IsAttackableDistanceFocusActor(); + + + bool NEW_MoveToDestPixelPositionDirection(const TPixelPosition& c_rkPPosDst); + bool NEW_MoveToMousePickedDirection(); + bool NEW_MoveToMouseScreenDirection(); + bool NEW_MoveToDirection(float fDirRot); + void NEW_Stop(); + + + // Reserved + bool NEW_IsEmptyReservedDelayTime(float fElapsedtime); // ̹ ʿ - [levites] + + + // Dungeon + void SetDungeonDestinationPosition(int ix, int iy); + void AlarmHaveToGo(); + + + CInstanceBase* NEW_FindActorPtr(DWORD dwVID); + CInstanceBase* NEW_GetMainActorPtr(); + + // flying target set + void Clear(); + void ClearSkillDict(); // ų ClearGame Ե Լ + void NEW_ClearSkillData(bool bAll = false); + + void Update(); + + + // Play Time + DWORD GetPlayTime(); + void SetPlayTime(DWORD dwPlayTime); + + + // System + void SetMainCharacterIndex(int iIndex); + + DWORD GetMainCharacterIndex(); + bool IsMainCharacterIndex(DWORD dwIndex); + DWORD GetGuildID(); + void NotifyDeletingCharacterInstance(DWORD dwVID); + void NotifyCharacterDead(DWORD dwVID); + void NotifyCharacterUpdate(DWORD dwVID); + void NotifyDeadMainCharacter(); + void NotifyChangePKMode(); + + + // Player Status + const char * GetName(); + void SetName(const char *name); + + void SetRace(DWORD dwRace); + DWORD GetRace(); + + void SetWeaponPower(DWORD dwMinPower, DWORD dwMaxPower, DWORD dwMinMagicPower, DWORD dwMaxMagicPower, DWORD dwAddPower); + void SetStatus(DWORD dwType, long lValue); + int GetStatus(DWORD dwType); + + + // Item + void MoveItemData(TItemPos SrcCell, TItemPos DstCell); + void SetItemData(TItemPos Cell, const TItemData & c_rkItemInst); + const TItemData * GetItemData(TItemPos Cell) const; + void SetItemCount(TItemPos Cell, BYTE byCount); + void SetItemMetinSocket(TItemPos Cell, DWORD dwMetinSocketIndex, DWORD dwMetinNumber); + void SetItemAttribute(TItemPos Cell, DWORD dwAttrIndex, BYTE byType, short sValue); + DWORD GetItemIndex(TItemPos Cell); + DWORD GetItemFlags(TItemPos Cell); + DWORD GetItemCount(TItemPos Cell); + DWORD GetItemCountByVnum(DWORD dwVnum); + DWORD GetItemMetinSocket(TItemPos Cell, DWORD dwMetinSocketIndex); + void GetItemAttribute(TItemPos Cell, DWORD dwAttrSlotIndex, BYTE * pbyType, short * psValue); + void SendClickItemPacket(DWORD dwIID); + + void RequestAddLocalQuickSlot(DWORD dwLocalSlotIndex, DWORD dwWndType, DWORD dwWndItemPos); + void RequestAddToEmptyLocalQuickSlot(DWORD dwWndType, DWORD dwWndItemPos); + void RequestMoveGlobalQuickSlotToLocalQuickSlot(DWORD dwGlobalSrcSlotIndex, DWORD dwLocalDstSlotIndex); + void RequestDeleteGlobalQuickSlot(DWORD dwGlobalSlotIndex); + void RequestUseLocalQuickSlot(DWORD dwLocalSlotIndex); + DWORD LocalQuickSlotIndexToGlobalQuickSlotIndex(DWORD dwLocalSlotIndex); + + void GetGlobalQuickSlotData(DWORD dwGlobalSlotIndex, DWORD* pdwWndType, DWORD* pdwWndItemPos); + void GetLocalQuickSlotData(DWORD dwSlotPos, DWORD* pdwWndType, DWORD* pdwWndItemPos); + void RemoveQuickSlotByValue(int iType, int iPosition); + + char IsItem(TItemPos SlotIndex); + +#ifdef ENABLE_NEW_EQUIPMENT_SYSTEM + bool IsBeltInventorySlot(TItemPos Cell); +#endif + bool IsInventorySlot(TItemPos SlotIndex); + bool IsEquipmentSlot(TItemPos SlotIndex); + + bool IsEquipItemInSlot(TItemPos iSlotIndex); + + + // Quickslot + int GetQuickPage(); + void SetQuickPage(int nPageIndex); + void AddQuickSlot(int QuickslotIndex, char IconType, char IconPosition); + void DeleteQuickSlot(int QuickslotIndex); + void MoveQuickSlot(int Source, int Target); + + + // Skill + void SetSkill(DWORD dwSlotIndex, DWORD dwSkillIndex); + bool GetSkillSlotIndex(DWORD dwSkillIndex, DWORD* pdwSlotIndex); + int GetSkillIndex(DWORD dwSlotIndex); + int GetSkillGrade(DWORD dwSlotIndex); + int GetSkillLevel(DWORD dwSlotIndex); + float GetSkillCurrentEfficientPercentage(DWORD dwSlotIndex); + float GetSkillNextEfficientPercentage(DWORD dwSlotIndex); + void SetSkillLevel(DWORD dwSlotIndex, DWORD dwSkillLevel); + void SetSkillLevel_(DWORD dwSkillIndex, DWORD dwSkillGrade, DWORD dwSkillLevel); + BOOL IsToggleSkill(DWORD dwSlotIndex); + void ClickSkillSlot(DWORD dwSlotIndex); + void ChangeCurrentSkillNumberOnly(DWORD dwSlotIndex); + bool FindSkillSlotIndexBySkillIndex(DWORD dwSkillIndex, DWORD * pdwSkillSlotIndex); + + void SetSkillCoolTime(DWORD dwSkillIndex); + void EndSkillCoolTime(DWORD dwSkillIndex); + + float GetSkillCoolTime(DWORD dwSlotIndex); + float GetSkillElapsedCoolTime(DWORD dwSlotIndex); + BOOL IsSkillActive(DWORD dwSlotIndex); + BOOL IsSkillCoolTime(DWORD dwSlotIndex); + void UseGuildSkill(DWORD dwSkillSlotIndex); + bool AffectIndexToSkillSlotIndex(UINT uAffect, DWORD* pdwSkillSlotIndex); + bool AffectIndexToSkillIndex(DWORD dwAffectIndex, DWORD * pdwSkillIndex); + + void SetAffect(UINT uAffect); + void ResetAffect(UINT uAffect); + void ClearAffects(); + + + // Target + void SetTarget(DWORD dwVID, BOOL bForceChange = TRUE); + void OpenCharacterMenu(DWORD dwVictimActorID); + DWORD GetTargetVID(); + + + // Party + void ExitParty(); + void AppendPartyMember(DWORD dwPID, const char * c_szName); + void LinkPartyMember(DWORD dwPID, DWORD dwVID); + void UnlinkPartyMember(DWORD dwPID); + void UpdatePartyMemberInfo(DWORD dwPID, BYTE byState, BYTE byHPPercentage); + void UpdatePartyMemberAffect(DWORD dwPID, BYTE byAffectSlotIndex, short sAffectNumber); + void RemovePartyMember(DWORD dwPID); + bool IsPartyMemberByVID(DWORD dwVID); + bool IsPartyMemberByName(const char * c_szName); + bool GetPartyMemberPtr(DWORD dwPID, TPartyMemberInfo ** ppPartyMemberInfo); + bool PartyMemberPIDToVID(DWORD dwPID, DWORD * pdwVID); + bool PartyMemberVIDToPID(DWORD dwVID, DWORD * pdwPID); + bool IsSamePartyMember(DWORD dwVID1, DWORD dwVID2); + + + // Fight + void RememberChallengeInstance(DWORD dwVID); + void RememberRevengeInstance(DWORD dwVID); + void RememberCantFightInstance(DWORD dwVID); + void ForgetInstance(DWORD dwVID); + bool IsChallengeInstance(DWORD dwVID); + bool IsRevengeInstance(DWORD dwVID); + bool IsCantFightInstance(DWORD dwVID); + + + // Private Shop + void OpenPrivateShop(); + void ClosePrivateShop(); + bool IsOpenPrivateShop(); + + + + // Stamina + void StartStaminaConsume(DWORD dwConsumePerSec, DWORD dwCurrentStamina); + void StopStaminaConsume(DWORD dwCurrentStamina); + + + // PK Mode + DWORD GetPKMode(); + + + // Mobile + void SetMobileFlag(BOOL bFlag); + BOOL HasMobilePhoneNumber(); + + + // Combo + void SetComboSkillFlag(BOOL bFlag); + + + // System + void SetMovableGroundDistance(float fDistance); + + + // Emotion + void ActEmotion(DWORD dwEmotionID); + void StartEmotionProcess(); + void EndEmotionProcess(); + + + // Function Only For Console System + BOOL __ToggleCoolTime(); + BOOL __ToggleLevelLimit(); + + __inline const SAutoPotionInfo& GetAutoPotionInfo(int type) const { return m_kAutoPotionInfo[type]; } + __inline SAutoPotionInfo& GetAutoPotionInfo(int type) { return m_kAutoPotionInfo[type]; } + __inline void SetAutoPotionInfo(int type, const SAutoPotionInfo& info) { m_kAutoPotionInfo[type] = info; } + + protected: + TQuickSlot & __RefLocalQuickSlot(int SlotIndex); + TQuickSlot & __RefGlobalQuickSlot(int SlotIndex); + + + DWORD __GetLevelAtk(); + DWORD __GetStatAtk(); + DWORD __GetWeaponAtk(DWORD dwWeaponPower); + DWORD __GetTotalAtk(DWORD dwWeaponPower, DWORD dwRefineBonus); + DWORD __GetRaceStat(); + DWORD __GetHitRate(); + DWORD __GetEvadeRate(); + + void __UpdateBattleStatus(); + + void __DeactivateSkillSlot(DWORD dwSlotIndex); + void __ActivateSkillSlot(DWORD dwSlotIndex); + + void __OnPressSmart(CInstanceBase& rkInstMain, bool isAuto); + void __OnClickSmart(CInstanceBase& rkInstMain, bool isAuto); + + void __OnPressItem(CInstanceBase& rkInstMain, DWORD dwPickedItemID); + void __OnPressActor(CInstanceBase& rkInstMain, DWORD dwPickedActorID, bool isAuto); + void __OnPressGround(CInstanceBase& rkInstMain, const TPixelPosition& c_rkPPosPickedGround); + void __OnPressScreen(CInstanceBase& rkInstMain); + + void __OnClickActor(CInstanceBase& rkInstMain, DWORD dwPickedActorID, bool isAuto); + void __OnClickItem(CInstanceBase& rkInstMain, DWORD dwPickedItemID); + void __OnClickGround(CInstanceBase& rkInstMain, const TPixelPosition& c_rkPPosPickedGround); + + bool __IsMovableGroundDistance(CInstanceBase& rkInstMain, const TPixelPosition& c_rkPPosPickedGround); + + bool __GetPickedActorPtr(CInstanceBase** pkInstPicked); + + bool __GetPickedActorID(DWORD* pdwActorID); + bool __GetPickedItemID(DWORD* pdwItemID); + bool __GetPickedGroundPos(TPixelPosition* pkPPosPicked); + + void __ClearReservedAction(); + void __ReserveClickItem(DWORD dwItemID); + void __ReserveClickActor(DWORD dwActorID); + void __ReserveClickGround(const TPixelPosition& c_rkPPosPickedGround); + void __ReserveUseSkill(DWORD dwActorID, DWORD dwSkillSlotIndex, DWORD dwRange); + + void __ReserveProcess_ClickActor(); + + void __ShowPickedEffect(const TPixelPosition& c_rkPPosPickedGround); + void __SendClickActorPacket(CInstanceBase& rkInstVictim); + + void __ClearAutoAttackTargetActorID(); + void __SetAutoAttackTargetActorID(DWORD dwActorID); + + void NEW_ShowEffect(int dwEID, TPixelPosition kPPosDst); + + void NEW_SetMouseSmartState(int eMBS, bool isAuto); + void NEW_SetMouseMoveState(int eMBS); + void NEW_SetMouseCameraState(int eMBS); + void NEW_GetMouseDirRotation(float fScrX, float fScrY, float* pfDirRot); + void NEW_GetMultiKeyDirRotation(bool isLeft, bool isRight, bool isUp, bool isDown, float* pfDirRot); + + float GetDegreeFromDirection(int iUD, int iLR); + float GetDegreeFromPosition(int ix, int iy, int iHalfWidth, int iHalfHeight); + + bool CheckCategory(int iCategory); + bool CheckAbilitySlot(int iSlotIndex); + + void RefreshKeyWalkingDirection(); + void NEW_RefreshMouseWalkingDirection(); + + + // Instances + void RefreshInstances(); + + bool __CanShot(CInstanceBase& rkInstMain, CInstanceBase& rkInstTarget); + bool __CanUseSkill(); + + bool __CanMove(); + + bool __CanAttack(); + bool __CanChangeTarget(); + + bool __CheckSkillUsable(DWORD dwSlotIndex); + void __UseCurrentSkill(); + void __UseChargeSkill(DWORD dwSkillSlotIndex); + bool __UseSkill(DWORD dwSlotIndex); + bool __CheckSpecialSkill(DWORD dwSkillIndex); + + bool __CheckRestSkillCoolTime(DWORD dwSkillSlotIndex); + bool __CheckShortLife(TSkillInstance & rkSkillInst, CPythonSkill::TSkillData& rkSkillData); + bool __CheckShortMana(TSkillInstance & rkSkillInst, CPythonSkill::TSkillData& rkSkillData); + bool __CheckShortArrow(TSkillInstance & rkSkillInst, CPythonSkill::TSkillData& rkSkillData); + bool __CheckDashAffect(CInstanceBase& rkInstMain); + + void __SendUseSkill(DWORD dwSkillSlotIndex, DWORD dwTargetVID); + void __RunCoolTime(DWORD dwSkillSlotIndex); + + BYTE __GetSkillType(DWORD dwSkillSlotIndex); + + bool __IsReservedUseSkill(DWORD dwSkillSlotIndex); + bool __IsMeleeSkill(CPythonSkill::TSkillData& rkSkillData); + bool __IsChargeSkill(CPythonSkill::TSkillData& rkSkillData); + DWORD __GetSkillTargetRange(CPythonSkill::TSkillData& rkSkillData); + bool __SearchNearTarget(); + bool __IsUsingChargeSkill(); + + bool __ProcessEnemySkillTargetRange(CInstanceBase& rkInstMain, CInstanceBase& rkInstTarget, CPythonSkill::TSkillData& rkSkillData, DWORD dwSkillSlotIndex); + + + // Item + bool __HasEnoughArrow(); + bool __HasItem(DWORD dwItemID); + DWORD __GetPickableDistance(); + + + // Target + CInstanceBase* __GetTargetActorPtr(); + void __ClearTarget(); + DWORD __GetTargetVID(); + void __SetTargetVID(DWORD dwVID); + bool __IsSameTargetVID(DWORD dwVID); + bool __IsTarget(); + bool __ChangeTargetToPickedInstance(); + + CInstanceBase * __GetSkillTargetInstancePtr(CPythonSkill::TSkillData& rkSkillData); + CInstanceBase * __GetAliveTargetInstancePtr(); + CInstanceBase * __GetDeadTargetInstancePtr(); + + BOOL __IsRightButtonSkillMode(); + + + // Update + void __Update_AutoAttack(); + void __Update_NotifyGuildAreaEvent(); + + + + // Emotion + BOOL __IsProcessingEmotion(); + + + protected: + PyObject * m_ppyGameWindow; + + // Client Player Data + std::map m_skillSlotDict; + std::string m_stName; + DWORD m_dwMainCharacterIndex; + DWORD m_dwRace; + DWORD m_dwWeaponMinPower; + DWORD m_dwWeaponMaxPower; + DWORD m_dwWeaponMinMagicPower; + DWORD m_dwWeaponMaxMagicPower; + DWORD m_dwWeaponAddPower; + + // Todo + DWORD m_dwSendingTargetVID; + float m_fTargetUpdateTime; + + // Attack + DWORD m_dwAutoAttackTargetVID; + + // NEW_Move + EMode m_eReservedMode; + float m_fReservedDelayTime; + + float m_fMovDirRot; + + bool m_isUp; + bool m_isDown; + bool m_isLeft; + bool m_isRight; + bool m_isAtkKey; + bool m_isDirKey; + bool m_isCmrRot; + bool m_isSmtMov; + bool m_isDirMov; + + float m_fCmrRotSpd; + + TPlayerStatus m_playerStatus; + + UINT m_iComboOld; + DWORD m_dwVIDReserved; + DWORD m_dwIIDReserved; + + DWORD m_dwcurSkillSlotIndex; + DWORD m_dwSkillSlotIndexReserved; + DWORD m_dwSkillRangeReserved; + + TPixelPosition m_kPPosInstPrev; + TPixelPosition m_kPPosReserved; + + // Emotion + BOOL m_bisProcessingEmotion; + + // Dungeon + BOOL m_isDestPosition; + int m_ixDestPos; + int m_iyDestPos; + int m_iLastAlarmTime; + + // Party + std::map m_PartyMemberMap; + + // PVP + std::set m_ChallengeInstanceSet; + std::set m_RevengeInstanceSet; + std::set m_CantFightInstanceSet; + + // Private Shop + bool m_isOpenPrivateShop; + bool m_isObserverMode; + + // Stamina + BOOL m_isConsumingStamina; + float m_fCurrentStamina; + float m_fConsumeStaminaPerSec; + + // Guild + DWORD m_inGuildAreaID; + + // Mobile + BOOL m_bMobileFlag; + + // System + BOOL m_sysIsCoolTime; + BOOL m_sysIsLevelLimit; + + protected: + // Game Cursor Data + TPixelPosition m_MovingCursorPosition; + float m_fMovingCursorSettingTime; + DWORD m_adwEffect[EFFECT_NUM]; + + DWORD m_dwVIDPicked; + DWORD m_dwIIDPicked; + int m_aeMBFButton[MBT_NUM]; + + DWORD m_dwTargetVID; + DWORD m_dwTargetEndTime; + DWORD m_dwPlayTime; + + SAutoPotionInfo m_kAutoPotionInfo[AUTO_POTION_TYPE_NUM]; + + protected: + float MOVABLE_GROUND_DISTANCE; + + private: + std::map m_kMap_dwAffectIndexToSkillIndex; +}; + +extern const int c_iFastestSendingCount; +extern const int c_iSlowestSendingCount; +extern const float c_fFastestSendingDelay; +extern const float c_fSlowestSendingDelay; +extern const float c_fRotatingStepTime; + +extern const float c_fComboDistance; +extern const float c_fPickupDistance; +extern const float c_fClickDistance; diff --git a/source/UserInterface/PythonPlayerEventHandler.cpp b/source/UserInterface/PythonPlayerEventHandler.cpp new file mode 100644 index 0000000..72d22eb --- /dev/null +++ b/source/UserInterface/PythonPlayerEventHandler.cpp @@ -0,0 +1,280 @@ +#include "StdAfx.h" +#include "PythonPlayerEventHandler.h" +#include "PythonPlayer.h" +#include "PythonCharacterManager.h" +#include "PythonNetworkStream.h" + +CPythonPlayerEventHandler& CPythonPlayerEventHandler::GetSingleton() +{ + static CPythonPlayerEventHandler s_kPlayerEventHandler; + return s_kPlayerEventHandler; +} + +CPythonPlayerEventHandler::~CPythonPlayerEventHandler() +{ +} + +void CPythonPlayerEventHandler::OnClearAffects() +{ + CPythonPlayer::Instance().ClearAffects(); +} + +void CPythonPlayerEventHandler::OnSetAffect(UINT uAffect) +{ + CPythonPlayer::Instance().SetAffect(uAffect); +} + +void CPythonPlayerEventHandler::OnResetAffect(UINT uAffect) +{ + CPythonPlayer::Instance().ResetAffect(uAffect); +} + +void CPythonPlayerEventHandler::OnSyncing(const SState& c_rkState) +{ + const TPixelPosition& c_rkPPosCurSyncing=c_rkState.kPPosSelf; + m_kPPosPrevWaiting=c_rkPPosCurSyncing; +} + +void CPythonPlayerEventHandler::OnWaiting(const SState& c_rkState) +{ + DWORD dwCurTime=ELTimer_GetMSec(); + if (m_dwNextWaitingNotifyTime>dwCurTime) + return; + + m_dwNextWaitingNotifyTime=dwCurTime+100; + + const TPixelPosition& c_rkPPosCurWaiting=c_rkState.kPPosSelf; + float dx=m_kPPosPrevWaiting.x-c_rkPPosCurWaiting.x; + float dy=m_kPPosPrevWaiting.y-c_rkPPosCurWaiting.y; + float len=sqrt(dx*dx+dy*dy); + + if (len<1.0f) + return; + + m_kPPosPrevWaiting=c_rkPPosCurWaiting; + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendCharacterStatePacket(c_rkState.kPPosSelf, c_rkState.fAdvRotSelf, CInstanceBase::FUNC_WAIT, 0); + + //Trace("waiting\n"); +} + +void CPythonPlayerEventHandler::OnMoving(const SState& c_rkState) +{ + DWORD dwCurTime=ELTimer_GetMSec(); + if (m_dwNextMovingNotifyTime>dwCurTime) + return; + + m_dwNextMovingNotifyTime=dwCurTime+300; + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendCharacterStatePacket(c_rkState.kPPosSelf, c_rkState.fAdvRotSelf, CInstanceBase::FUNC_MOVE, 0); + +// Trace("moving\n"); +} + +void CPythonPlayerEventHandler::OnMove(const SState& c_rkState) +{ + DWORD dwCurTime=ELTimer_GetMSec(); + m_dwNextWaitingNotifyTime=dwCurTime+100; + m_dwNextMovingNotifyTime=dwCurTime+300; + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendCharacterStatePacket(c_rkState.kPPosSelf, c_rkState.fAdvRotSelf, CInstanceBase::FUNC_MOVE, 0); + +// Trace("move\n"); +} + +void CPythonPlayerEventHandler::OnStop(const SState& c_rkState) +{ + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendCharacterStatePacket(c_rkState.kPPosSelf, c_rkState.fAdvRotSelf, CInstanceBase::FUNC_WAIT, 0); + +// Trace("stop\n"); +} + +void CPythonPlayerEventHandler::OnWarp(const SState& c_rkState) +{ + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendCharacterStatePacket(c_rkState.kPPosSelf, c_rkState.fAdvRotSelf, CInstanceBase::FUNC_WAIT, 0); +} + +void CPythonPlayerEventHandler::OnAttack(const SState& c_rkState, WORD wMotionIndex) +{ +// Tracef("CPythonPlayerEventHandler::OnAttack [%d]\n", wMotionIndex); + assert(wMotionIndex < 255); + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendCharacterStatePacket(c_rkState.kPPosSelf, c_rkState.fAdvRotSelf, CInstanceBase::FUNC_COMBO, wMotionIndex); + +#ifdef __ATTACK_SPEED_CHECK__ + static DWORD s_dwLastTime=timeGetTime(); + + DWORD dwCurTime=timeGetTime(); + Tracef("%d\n", dwCurTime-s_dwLastTime); + s_dwLastTime=dwCurTime; +#endif + +} + +void CPythonPlayerEventHandler::OnUseSkill(const SState& c_rkState, UINT uMotSkill, UINT uArg) +{ + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendCharacterStatePacket(c_rkState.kPPosSelf, c_rkState.fAdvRotSelf, CInstanceBase::FUNC_SKILL|uMotSkill, uArg); +} + +void CPythonPlayerEventHandler::OnUpdate() +{ +} + +void CPythonPlayerEventHandler::OnChangeShape() +{ + CPythonPlayer::Instance().NEW_Stop(); +} + +void CPythonPlayerEventHandler::OnHit(UINT uSkill, CActorInstance& rkActorVictim, BOOL isSendPacket) +{ + DWORD dwVIDVictim=rkActorVictim.GetVirtualID(); + + // Update Target + CPythonPlayer::Instance().SetTarget(dwVIDVictim, FALSE); + // Update Target + + if (isSendPacket) + { +//#define ATTACK_TIME_LOG +#ifdef ATTACK_TIME_LOG + static std::map s_prevTimed; + float curTime = timeGetTime() / 1000.0f; + bool isFirst = false; + if (s_prevTimed.end() == s_prevTimed.find(dwVIDVictim)) + { + s_prevTimed[dwVIDVictim] = curTime; + isFirst = true; + } + float diffTime = curTime-s_prevTimed[dwVIDVictim]; + if (diffTime < 0.1f && !isFirst) + { + TraceError("ATTACK(SPEED_HACK): %.4f(%.4f) %d", curTime, diffTime, dwVIDVictim); + } + else + { + TraceError("ATTACK: %.4f(%.4f) %d", curTime, diffTime, dwVIDVictim); + } + + s_prevTimed[dwVIDVictim] = curTime; +#endif + CPythonNetworkStream& rkStream=CPythonNetworkStream::Instance(); + rkStream.SendAttackPacket(uSkill, dwVIDVictim); + } + + if (!rkActorVictim.IsPushing()) + return; + + // Ŵ и + extern bool IS_HUGE_RACE(unsigned int vnum); + if (IS_HUGE_RACE(rkActorVictim.GetRace())) + return; + + + CPythonCharacterManager::Instance().AdjustCollisionWithOtherObjects(&rkActorVictim); + + const TPixelPosition& kPPosLast=rkActorVictim.NEW_GetLastPixelPositionRef(); + + SVictim kVictim; + kVictim.m_dwVID=dwVIDVictim; + kVictim.m_lPixelX=long(kPPosLast.x); + kVictim.m_lPixelY=long(kPPosLast.y); + + rkActorVictim.TEMP_Push(kVictim.m_lPixelX, kVictim.m_lPixelY); + + m_kVctkVictim.push_back(kVictim); +} + +void CPythonPlayerEventHandler::FlushVictimList() +{ + if (m_kVctkVictim.empty()) + return; + + // #0000682: [M2EU] ų ƨ + unsigned int SYNC_POSITION_COUNT_LIMIT = 16; + unsigned int uiVictimCount = m_kVctkVictim.size(); + + CPythonNetworkStream& rkStream=CPythonNetworkStream::Instance(); + + TPacketCGSyncPosition kPacketSyncPos; + kPacketSyncPos.bHeader=HEADER_CG_SYNC_POSITION; + kPacketSyncPos.wSize=sizeof(kPacketSyncPos)+sizeof(TPacketCGSyncPositionElement) * uiVictimCount; + + rkStream.Send(sizeof(kPacketSyncPos), &kPacketSyncPos); + + for (unsigned int i = 0; i < uiVictimCount; ++i) + { + const SVictim& rkVictim = m_kVctkVictim[i]; + rkStream.SendSyncPositionElementPacket(rkVictim.m_dwVID, rkVictim.m_lPixelX, rkVictim.m_lPixelY); + } + + rkStream.SendSequence(); + m_kVctkVictim.clear(); +} + +CPythonPlayerEventHandler::CPythonPlayerEventHandler() +{ + m_dwPrevComboIndex=0; + m_dwNextMovingNotifyTime=0; + m_dwNextWaitingNotifyTime=0; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// + +void CPythonPlayerEventHandler::CNormalBowAttack_FlyEventHandler_AutoClear::OnSetFlyTarget() +{ + SState s; + m_pInstMain->NEW_GetPixelPosition(&s.kPPosSelf); + s.fAdvRotSelf=m_pInstMain->GetGraphicThingInstancePtr()->GetTargetRotation(); + + CPythonNetworkStream& rpns=CPythonNetworkStream::Instance(); + rpns.SendFlyTargetingPacket(m_pInstTarget->GetVirtualID(), m_pInstTarget->GetGraphicThingInstancePtr()->OnGetFlyTargetPosition()); +} +void CPythonPlayerEventHandler::CNormalBowAttack_FlyEventHandler_AutoClear::OnShoot(DWORD dwSkillIndex) +{ + CPythonNetworkStream& rpns=CPythonNetworkStream::Instance(); + rpns.SendShootPacket(dwSkillIndex); +} + +void CPythonPlayerEventHandler::CNormalBowAttack_FlyEventHandler_AutoClear::Set(CPythonPlayerEventHandler * pParent, CInstanceBase * pInstMain, CInstanceBase * pInstTarget) +{ + m_pParent=(pParent); + m_pInstMain=(pInstMain); + m_pInstTarget=(pInstTarget); +} + +void CPythonPlayerEventHandler::CNormalBowAttack_FlyEventHandler_AutoClear::SetTarget(CInstanceBase* pInstTarget) +{ + m_pInstTarget = pInstTarget; +} + +void CPythonPlayerEventHandler::CNormalBowAttack_FlyEventHandler_AutoClear::OnExplodingAtAnotherTarget(DWORD dwSkillIndex, DWORD dwVID) +{ + return; + + Tracef("Shoot : ٸ target ¾ҽϴ : %d, %d\n", dwSkillIndex, dwVID); + + CPythonNetworkStream& rkStream=CPythonNetworkStream::Instance(); + rkStream.SendAttackPacket(dwSkillIndex, dwVID); + + CPythonCharacterManager& rkChrMgr = CPythonCharacterManager::Instance(); + CInstanceBase * pInstance = rkChrMgr.GetInstancePtr(dwVID); + if (pInstance) + { + pInstance->GetGraphicThingInstanceRef().OnShootDamage(); + } +} +void CPythonPlayerEventHandler::CNormalBowAttack_FlyEventHandler_AutoClear::OnExplodingAtTarget(DWORD dwSkillIndex) +{ +// Tracef("Shoot : ϴ target ¾ҽϴ : %d, %d\n", dwSkillIndex, m_pInstTarget->GetVirtualID()); +// CPythonNetworkStream& rkStream=CPythonNetworkStream::Instance(); +// rkStream.SendAttackPacket(dwSkillIndex, m_pInstTarget->GetVirtualID()); +} diff --git a/source/UserInterface/PythonPlayerEventHandler.h b/source/UserInterface/PythonPlayerEventHandler.h new file mode 100644 index 0000000..d8fd73d --- /dev/null +++ b/source/UserInterface/PythonPlayerEventHandler.h @@ -0,0 +1,89 @@ +#pragma once + +#include "../gamelib/ActorInstance.h" +#include "../gamelib/FlyHandler.h" + +#include "PythonNetworkStream.h" +#include "InstanceBase.h" + +class CPythonPlayerEventHandler : public CActorInstance::IEventHandler +{ + public: + static CPythonPlayerEventHandler& GetSingleton(); + + public: + virtual ~CPythonPlayerEventHandler(); + + virtual void OnSyncing(const SState& c_rkState); + virtual void OnWaiting(const SState& c_rkState); + virtual void OnMoving(const SState& c_rkState); + virtual void OnMove(const SState& c_rkState); + virtual void OnStop(const SState& c_rkState); + virtual void OnWarp(const SState& c_rkState); + virtual void OnClearAffects(); + virtual void OnSetAffect(UINT uAffect); + virtual void OnResetAffect(UINT uAffect); + virtual void OnAttack(const SState& c_rkState, WORD wMotionIndex); + virtual void OnUseSkill(const SState& c_rkState, UINT uMotSkill, UINT uArg); + virtual void OnUpdate(); + virtual void OnChangeShape(); + virtual void OnHit(UINT uSkill, CActorInstance& rkActorVictim, BOOL isSendPacket); + + void FlushVictimList(); + + protected: + CPythonPlayerEventHandler(); + + protected: + struct SVictim + { + DWORD m_dwVID; + long m_lPixelX; + long m_lPixelY; + }; + + protected: + std::vector m_kVctkVictim; + + DWORD m_dwPrevComboIndex; + DWORD m_dwNextWaitingNotifyTime; + DWORD m_dwNextMovingNotifyTime; + TPixelPosition m_kPPosPrevWaiting; + + private: + class CNormalBowAttack_FlyEventHandler_AutoClear : public IFlyEventHandler + { + public: + CNormalBowAttack_FlyEventHandler_AutoClear() {} + virtual ~CNormalBowAttack_FlyEventHandler_AutoClear() {} + + void Set(CPythonPlayerEventHandler * pParent, CInstanceBase * pInstMain, CInstanceBase * pInstTarget); + void SetTarget(CInstanceBase* pInstTarget); + + virtual void OnSetFlyTarget(); + virtual void OnShoot(DWORD dwSkillIndex); + + virtual void OnNoTarget() { /*Tracenf("Shoot : target ϴ.");*/ } + virtual void OnExplodingOutOfRange() { /*Tracenf("Shoot : Ÿ ϴ.");*/ } + virtual void OnExplodingAtBackground() { /*Tracenf("Shoot : 濡 ¾ҽϴ.");*/ } + virtual void OnExplodingAtAnotherTarget(DWORD dwSkillIndex, DWORD dwVID); + virtual void OnExplodingAtTarget(DWORD dwSkillIndex); + + protected: + CPythonPlayerEventHandler * m_pParent; + CInstanceBase * m_pInstMain; + CInstanceBase * m_pInstTarget; + } m_NormalBowAttack_FlyEventHandler_AutoClear; + + public: + IFlyEventHandler * GetNormalBowAttackFlyEventHandler(CInstanceBase* pInstMain, CInstanceBase* pInstTarget) + { + m_NormalBowAttack_FlyEventHandler_AutoClear.Set(this,pInstMain,pInstTarget); + return &m_NormalBowAttack_FlyEventHandler_AutoClear; + } + + void ChangeFlyTarget(CInstanceBase* pInstTarget) + { + m_NormalBowAttack_FlyEventHandler_AutoClear.SetTarget(pInstTarget); + } +}; \ No newline at end of file diff --git a/source/UserInterface/PythonPlayerInput.cpp b/source/UserInterface/PythonPlayerInput.cpp new file mode 100644 index 0000000..c5bd4b5 --- /dev/null +++ b/source/UserInterface/PythonPlayerInput.cpp @@ -0,0 +1,1011 @@ +#include "StdAfx.h" +#include "PythonPlayer.h" +#include "PythonPlayerEventHandler.h" +#include "PythonApplication.h" +#include "../eterlib/Camera.h" +#include "../eterbase/Timer.h" + +const int c_iFastestSendingCount = 3; +const int c_iSlowestSendingCount = 3; +const float c_fFastestSendingDelay = 1.0f / float(c_iFastestSendingCount); +const float c_fSlowestSendingDelay = 1.0f / float(c_iSlowestSendingCount); +const float c_fRotatingStepTime = 0.5f; + +const float c_fComboDistance = 250.0f; +const float c_fClickDistance = 300.0f; + +DWORD CPythonPlayer::__GetPickableDistance() +{ + CInstanceBase * pkInstMain = NEW_GetMainActorPtr(); + if (pkInstMain) + if (pkInstMain->IsMountingHorse()) + return 500; + + return 300; +} + +void CPythonPlayer::PickCloseMoney() +{ + CInstanceBase * pkInstMain = NEW_GetMainActorPtr(); + if (!pkInstMain) + return; + + TPixelPosition kPPosMain; + pkInstMain->NEW_GetPixelPosition(&kPPosMain); + + DWORD dwItemID; + CPythonItem& rkItem=CPythonItem::Instance(); + if (!rkItem.GetCloseMoney(kPPosMain, &dwItemID, __GetPickableDistance())) + return; + + SendClickItemPacket(dwItemID); +} + +void CPythonPlayer::PickCloseItem() +{ + CInstanceBase * pkInstMain = NEW_GetMainActorPtr(); + if (!pkInstMain) + return; + + TPixelPosition kPPosMain; + pkInstMain->NEW_GetPixelPosition(&kPPosMain); + + DWORD dwItemID; + CPythonItem& rkItem=CPythonItem::Instance(); + if (!rkItem.GetCloseItem(kPPosMain, &dwItemID, __GetPickableDistance())) + return; + + SendClickItemPacket(dwItemID); +} + +bool CPythonPlayer::__IsTarget() +{ + return 0 != __GetTargetVID(); +} + +bool CPythonPlayer::__IsSameTargetVID(DWORD dwVID) +{ + return dwVID == __GetTargetVID(); +} + +DWORD CPythonPlayer::__GetTargetVID() +{ + return m_dwTargetVID; +} + +DWORD CPythonPlayer::GetTargetVID() +{ + return __GetTargetVID(); +} + + +CInstanceBase* CPythonPlayer::__GetTargetActorPtr() +{ + return NEW_FindActorPtr(__GetTargetVID()); +} + +void CPythonPlayer::__SetTargetVID(DWORD dwVID) +{ + m_dwTargetVID=dwVID; +} + +void CPythonPlayer::__ClearTarget() +{ + if (!__IsTarget()) + return; + + CInstanceBase * pkInstMain = NEW_GetMainActorPtr(); + if (!pkInstMain) + return; + + pkInstMain->ClearFlyTargetInstance(); + + CInstanceBase * pTargetedInstance = __GetTargetActorPtr(); + if (pTargetedInstance) + pTargetedInstance->OnUntargeted(); + + __SetTargetVID(0); + + CPythonNetworkStream::Instance().SendTargetPacket(0); +} + +void CPythonPlayer::SetTarget(DWORD dwVID, BOOL bForceChange) +{ + CInstanceBase * pkInstMain = NEW_GetMainActorPtr(); + if (!pkInstMain) + return; + + // 2004. 07. 07. [levites] - ų Ÿ ٲ ذ ڵ + if (!pkInstMain->CanChangeTarget()) + { + return; + } + + DWORD dwCurrentTime = CTimer::Instance().GetCurrentMillisecond(); + + if (__IsSameTargetVID(dwVID)) + { + if (dwVID==pkInstMain->GetVirtualID()) + { + __SetTargetVID(0); + + pkInstMain->OnUntargeted(); + pkInstMain->ClearFlyTargetInstance(); + CPythonNetworkStream::Instance().SendTargetPacket(0); + return; + } + m_dwTargetEndTime = dwCurrentTime + 1000; + return; + } + + if (bForceChange) + { + m_dwTargetEndTime = dwCurrentTime + 2000; + } + else + { + if (m_dwTargetEndTime > dwCurrentTime) + { + return; + } + + m_dwTargetEndTime = dwCurrentTime + 1000; + } + + if (__IsTarget()) + { + CInstanceBase * pTargetedInstance = __GetTargetActorPtr(); + if (pTargetedInstance) + pTargetedInstance->OnUntargeted(); + } + + + CInstanceBase * pkInstTarget = CPythonCharacterManager::Instance().GetInstancePtr(dwVID); + if (pkInstTarget) + { + if (pkInstMain->IsTargetableInstance(*pkInstTarget)) + { + __SetTargetVID(dwVID); + + pkInstTarget->OnTargeted(); + pkInstMain->SetFlyTargetInstance(*pkInstTarget); + pkInstMain->GetGraphicThingInstanceRef().SetFlyEventHandler(CPythonPlayerEventHandler::GetSingleton().GetNormalBowAttackFlyEventHandler(pkInstMain, pkInstTarget)); + CPythonNetworkStream::Instance().SendTargetPacket(dwVID); + + return; + } + } + + __SetTargetVID(0); + + pkInstMain->ClearFlyTargetInstance(); + CPythonNetworkStream::Instance().SendTargetPacket(0); + +} + +bool CPythonPlayer::__ChangeTargetToPickedInstance() +{ + DWORD dwVID; + if (!CPythonCharacterManager::Instance().OLD_GetPickedInstanceVID(&dwVID)) + return false; + + SetTarget(dwVID); + return true; +} + +CInstanceBase * CPythonPlayer::__GetSkillTargetInstancePtr(CPythonSkill::TSkillData& rkSkillData) +{ + if (rkSkillData.IsNeedCorpse()) + return __GetDeadTargetInstancePtr(); + + return __GetAliveTargetInstancePtr(); +} + +CInstanceBase * CPythonPlayer::__GetDeadTargetInstancePtr() +{ + if (!__IsTarget()) + return NULL; + + CInstanceBase * pkInstTarget = __GetTargetActorPtr(); + + if (!pkInstTarget) + return NULL; + + if (!pkInstTarget->IsDead()) + return NULL; + + return pkInstTarget; +} + +CInstanceBase * CPythonPlayer::__GetAliveTargetInstancePtr() +{ + if (!__IsTarget()) + return NULL; + + CInstanceBase * pkInstTarget = __GetTargetActorPtr(); + + if (!pkInstTarget) + return NULL; + + if (pkInstTarget->IsDead()) + return NULL; + + return pkInstTarget; +} + + +void CPythonPlayer::OpenCharacterMenu(DWORD dwVictimActorID) +{ + CInstanceBase * pkInstMain = CPythonPlayer::Instance().NEW_GetMainActorPtr(); + if (!pkInstMain) + return; + + CInstanceBase * pkInstTarget = CPythonCharacterManager::Instance().GetInstancePtr(dwVictimActorID); + if (!pkInstTarget) + return; + + if (!pkInstTarget->IsPC() && !pkInstTarget->IsBuilding()) + return; + +// if (pkInstMain == pkInstTarget) +// return; + + PyCallClassMemberFunc(m_ppyGameWindow, "SetPCTargetBoard", Py_BuildValue("(is)", pkInstTarget->GetVirtualID(), pkInstTarget->GetNameString())); +} + +void CPythonPlayer::__OnClickItem(CInstanceBase& rkInstMain, DWORD dwItemID) +{ +} + +void CPythonPlayer::__OnClickActor(CInstanceBase& rkInstMain, DWORD dwPickedActorID, bool isAuto) +{ + // ų Ἥ ̶.. + if (MODE_USE_SKILL == m_eReservedMode) + { + // ij͸ Ŭ + if (__GetTargetVID() == dwPickedActorID) + return; + + // 2005.03.25.levites + // źȯ ޷ ִ ٸ Ÿ Ŭϸ + if (__CheckDashAffect(rkInstMain)) + { + m_dwVIDReserved = dwPickedActorID; + return; + } + } + + __ClearReservedAction(); + + CInstanceBase* pkInstVictim=NEW_FindActorPtr(dwPickedActorID); + CInstanceBase& rkInstVictim=*pkInstVictim; + if (!pkInstVictim) + return; + + // 2005.01.28.myevan + // ʱ޸ ¿ ȵdz NPC Ŭ̵Ǿ + if (rkInstMain.IsAttackableInstance(*pkInstVictim)) + if (!__CanAttack()) + return; + + if (!rkInstMain.NEW_IsClickableDistanceDestInstance(rkInstVictim)) + { + __ReserveClickActor(dwPickedActorID); + return; + } + + if (rkInstVictim.IsNPC()) + { + __SendClickActorPacket(rkInstVictim); + } + + rkInstMain.NEW_Stop(); + return; +} + +void CPythonPlayer::__OnPressActor(CInstanceBase& rkInstMain, DWORD dwPickedActorID, bool isAuto) +{ + // ų Ἥ ̶.. + if (MODE_USE_SKILL == m_eReservedMode) + { + // ij͸ Ŭ + if (__GetTargetVID() == dwPickedActorID) + return; + + // 2005.03.25.levites + // źȯ ޷ ִ ٸ Ÿ Ŭϸ + if (__CheckDashAffect(rkInstMain)) + { + m_dwVIDReserved = dwPickedActorID; + return; + } + } + + __ChangeTargetToPickedInstance(); + __ClearReservedAction(); + + if (!__CanAttack()) + return; + + CInstanceBase* pkInstVictim=NEW_FindActorPtr(dwPickedActorID); + if (!pkInstVictim) + return; + + CInstanceBase& rkInstVictim=*pkInstVictim; + + if (isAuto) + { + // 2004.10.21.myevan.ݰ 븸 ڵ + if (rkInstMain.IsAttackableInstance(rkInstVictim)) + __SetAutoAttackTargetActorID(rkInstVictim.GetVirtualID()); + } + + if (rkInstMain.IsBowMode()) + { + if (rkInstMain.IsAttackableInstance(rkInstVictim)) + if (!__CanShot(rkInstMain, rkInstVictim)) + return; + } + + if (!rkInstMain.NEW_IsClickableDistanceDestInstance(rkInstVictim)) + { + __ReserveClickActor(dwPickedActorID); + return; + } + + if (!rkInstMain.IsAttackableInstance(rkInstVictim)) + { + return; + } + + CPythonPlayerEventHandler& rkPlayerEventHandler=CPythonPlayerEventHandler::GetSingleton(); + rkInstMain.NEW_AttackToDestInstanceDirection(rkInstVictim, rkPlayerEventHandler.GetNormalBowAttackFlyEventHandler(&rkInstMain, &rkInstVictim)); +} + +void CPythonPlayer::__OnPressItem(CInstanceBase& rkInstMain, DWORD dwPickedItemID) +{ + static DWORD s_dwLastPickItemID=0; + + if (s_dwLastPickItemID==dwPickedItemID) + { + Logn(1, "CPythonPlayer::__OnPressItem - ALREADY PICKED ITEM"); + return; + } + + __ClearReservedAction(); + __ClearAutoAttackTargetActorID(); + + CPythonItem& rkItem=CPythonItem::Instance(); + + TPixelPosition kPPosPickedItem; + if (!rkItem.GetGroundItemPosition(dwPickedItemID, &kPPosPickedItem)) + return; + + if (!rkInstMain.NEW_IsClickableDistanceDestPixelPosition(kPPosPickedItem)) + { + __ReserveClickItem(dwPickedItemID); + return; + } + + rkInstMain.NEW_Stop(); + SendClickItemPacket(dwPickedItemID); +} + +void CPythonPlayer::__OnClickGround(CInstanceBase& rkInstMain, const TPixelPosition& c_rkPPosPickedGround) +{ + if (!__IsMovableGroundDistance(rkInstMain, c_rkPPosPickedGround)) + return; + + if (rkInstMain.NEW_MoveToDestPixelPositionDirection(c_rkPPosPickedGround)) + __ShowPickedEffect(c_rkPPosPickedGround); +} + +void CPythonPlayer::SetMovableGroundDistance(float fDistance) +{ + MOVABLE_GROUND_DISTANCE=fDistance; +} + +bool CPythonPlayer::__IsMovableGroundDistance(CInstanceBase& rkInstMain, const TPixelPosition& c_rkPPosPickedGround) +{ + float fDistance=rkInstMain.NEW_GetDistanceFromDestPixelPosition(c_rkPPosPickedGround); + + if (fDistanceisLock()) + if (!pkInstMain->IsUsingMovingSkill()) + return true; + + CCamera* pkCmrCur=CCameraManager::Instance().GetCurrentCamera(); + if (pkCmrCur) + { + float fCmrCurRot=CameraRotationToCharacterRotation(pkCmrCur->GetRoll()); + + // + if (m_isCmrRot) + { + float fSigDirRot=fDirRot; + if (fSigDirRot>180.0f) + fSigDirRot=fSigDirRot-360.0f; + + float fRotRat=fSigDirRot; + if (fRotRat>90.0f) + fRotRat=(180.0f-fRotRat); + else if (fRotRat<-90.0f) + fRotRat=(-180.0f-fRotRat); + + float fElapsedTime = CPythonApplication::Instance().GetGlobalElapsedTime(); + + float fRotDeg = -m_fCmrRotSpd * fElapsedTime * fRotRat / 90.0f; + pkCmrCur->Roll(fRotDeg); + } + + fDirRot=fmod(360.0f + fCmrCurRot + fDirRot, 360.0f); + } + + pkInstMain->NEW_MoveToDirection(fDirRot); + + return true; +} + +void CPythonPlayer::NEW_Stop() +{ + CInstanceBase* pkInstMain=NEW_GetMainActorPtr(); + if (!pkInstMain) + return; + + pkInstMain->NEW_Stop(); + m_isLeft = FALSE; + m_isRight = FALSE; + m_isUp = FALSE; + m_isDown = FALSE; +} + +bool CPythonPlayer::NEW_CancelFishing() +{ + CInstanceBase* pkInstMain = NEW_GetMainActorPtr(); + if (!pkInstMain) + return false; + + if (pkInstMain->IsFishing()) + { + static DWORD s_dwLastCancelTime = 0; + if (CTimer::Instance().GetCurrentMillisecond() < s_dwLastCancelTime + 500) + return false; + + CPythonNetworkStream::Instance().SendFishingPacket(0); + s_dwLastCancelTime = CTimer::Instance().GetCurrentMillisecond(); + return true; + } + + return false; +} + +void CPythonPlayer::NEW_Fishing() +{ + CInstanceBase* pkInstMain = NEW_GetMainActorPtr(); + if (!pkInstMain) + return; + + if (pkInstMain->IsFishing()) + { + CPythonNetworkStream::Instance().SendFishingPacket(0); + } + else + { + if (pkInstMain->CanFishing()) + { + int irot; + if (pkInstMain->GetFishingRot(&irot)) + CPythonNetworkStream::Instance().SendFishingPacket(irot); + else + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnFishingWrongPlace", Py_BuildValue("()")); + } + } + } +} + +void CPythonPlayer::NEW_Attack() +{ + // PrivateShop + if (IsOpenPrivateShop()) + return; + + if (!__CanAttack()) + return; + + CInstanceBase* pkInstMain = NEW_GetMainActorPtr(); + if (!pkInstMain) + return; + + if (pkInstMain->IsBowMode()) + { + //CPythonPlayerEventHandler& rkPlayerEventHandler=CPythonPlayerEventHandler::GetSingleton(); + + CInstanceBase * pkInstTarget = __GetAliveTargetInstancePtr(); + if (!pkInstTarget) + { + __ChangeTargetToPickedInstance(); + pkInstTarget = __GetAliveTargetInstancePtr(); + } + + if (pkInstTarget) + { + if (!__CanShot(*pkInstMain, *pkInstTarget)) + return; + + if (!pkInstMain->NEW_IsClickableDistanceDestInstance(*pkInstTarget)) + { + __ReserveClickActor(pkInstTarget->GetVirtualID()); + return; + } + + if (pkInstMain->IsAttackableInstance(*pkInstTarget)) + { + pkInstMain->NEW_LookAtDestInstance(*pkInstTarget); + pkInstMain->NEW_AttackToDestInstanceDirection(*pkInstTarget); + } + } + else + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "NEED_TARGET")); + return; + } + } + else if (m_isDirKey) + { + float fDirRot=0.0f; + NEW_GetMultiKeyDirRotation(m_isLeft, m_isRight, m_isUp, m_isDown, &fDirRot); + + CCamera* pkCmrCur=CCameraManager::Instance().GetCurrentCamera(); + if (pkCmrCur) + { + float fCmrCurRot=CameraRotationToCharacterRotation(pkCmrCur->GetRoll()); + + fDirRot=fmod(360.0f + fCmrCurRot + fDirRot, 360.0f); + } + + pkInstMain->NEW_Attack(fDirRot); + } + else + { + //!@# ź ¿ Ǽ ʴ´ - [levites] + if (pkInstMain->IsMountingHorse()) + { + if (pkInstMain->IsHandMode()) + return; + } + + pkInstMain->NEW_Attack(); + } +} + +bool CPythonPlayer::NEW_IsEmptyReservedDelayTime(float fElapsedTime) +{ + m_fReservedDelayTime -= fElapsedTime; + + if (m_fReservedDelayTime <= 0.0f) + { + m_fReservedDelayTime = 0.0f; + return true; + } + + return false; +} + + +void CPythonPlayer::NEW_SetAutoCameraRotationSpeed(float fRotSpd) +{ + m_fCmrRotSpd=fRotSpd; +} + +void CPythonPlayer::NEW_ResetCameraRotation() +{ + CCamera* pkCmrCur=CCameraManager::Instance().GetCurrentCamera(); + CPythonApplication & rkApp = CPythonApplication::Instance(); + + pkCmrCur->EndDrag(); + + rkApp.SetCursorNum(CPythonApplication::NORMAL); + if ( CPythonApplication::CURSOR_MODE_HARDWARE == rkApp.GetCursorMode()) + rkApp.SetCursorVisible(TRUE); +} + + +bool CPythonPlayer::__CanShot(CInstanceBase& rkInstMain, CInstanceBase& rkInstTarget) +{ + if (!__HasEnoughArrow()) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotShot", Py_BuildValue("(is)", GetMainCharacterIndex(), "EMPTY_ARROW")); + return false; + } + + if (rkInstMain.IsInSafe()) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotShot", Py_BuildValue("(is)", GetMainCharacterIndex(), "IN_SAFE")); + return false; + } + + if (rkInstTarget.IsInSafe()) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotShot", Py_BuildValue("(is)", GetMainCharacterIndex(), "DEST_IN_SAFE")); + return false; + } + + return true; +} + +bool CPythonPlayer::__CanChangeTarget() +{ + CInstanceBase* pkInstMain=NEW_GetMainActorPtr(); + if (!pkInstMain) + return false; + + return pkInstMain->CanChangeTarget(); +} + +bool CPythonPlayer::__CanMove() +{ + if (__IsProcessingEmotion()) + { + return false; + } + + CInstanceBase* pkInstMain=NEW_GetMainActorPtr(); + if (!pkInstMain) + return false; + + if (!pkInstMain->CanMove()) + { + if (!pkInstMain->IsUsingMovingSkill()) + return false; + } + + return true; +} +/* +bool CPythonPlayer::__OLD_CanMove() +{ + if (__IsProcessingEmotion()) + { + return false; + } + + CInstanceBase* pkInstMain=NEW_GetMainActorPtr(); + if (!pkInstMain) + return false; + + if (pkInstMain->IsDead()) + return false; + + if (pkInstMain->IsStun()) + return false; + + if (pkInstMain->isLock()) + return false; + + if (pkInstMain->IsParalysis()) + return false; + + return true; +} +*/ + +bool CPythonPlayer::__CanAttack() +{ + if (__IsProcessingEmotion()) + { + return false; + } + + if (IsOpenPrivateShop()) + return false; + + if (IsObserverMode()) + return false; + + CInstanceBase* pkInstMain=NEW_GetMainActorPtr(); + if (!pkInstMain) + return false; + + // Fix me + // Ʈ 25 ̻ 35 ̸ ߱ Ʈ Ÿ ݸϵ ϵ ڵ... + // ߿ ð can attack üũ ... + // _ unique Կ Ż ̶ ־ Ѵ _ + // _ Ʈ üũ ϰ ... ____ + if (pkInstMain->IsMountingHorse() && pkInstMain->IsNewMount() && (GetSkillGrade(109) < 1 && GetSkillLevel(109) < 11)) + { + return false; + } + + return pkInstMain->CanAttack(); +} + +void CPythonPlayer::NEW_GetMultiKeyDirRotation(bool isLeft, bool isRight, bool isUp, bool isDown, float* pfDirRot) +{ + float fScrX=0.0f; + float fScrY=0.0f; + + if (isLeft) + fScrX=0.0f; + else if (isRight) + fScrX=1.0f; + else + fScrX=0.5f; + + if (isUp) + fScrY=0.0f; + else if (isDown) + fScrY=1.0f; + else + fScrY=0.5f; + + NEW_GetMouseDirRotation(fScrX, fScrY, pfDirRot); +} + +void CPythonPlayer::NEW_GetMouseDirRotation(float fScrX, float fScrY, float* pfDirRot) +{ + long lWidth = UI::CWindowManager::Instance().GetScreenWidth(); + long lHeight = UI::CWindowManager::Instance().GetScreenHeight(); + int nScrPosX=lWidth*fScrX; + int nScrPosY=lHeight*fScrY; + int nScrWidth=lWidth; + int nScrHeight=lHeight; + int nScrCenterX=nScrWidth/2; + int nScrCenterY=nScrHeight/2; + + float finputRotation = GetDegreeFromPosition(nScrPosX, nScrPosY, nScrCenterX, nScrCenterY); + *pfDirRot=finputRotation; +} + + +float CPythonPlayer::GetDegreeFromPosition(int ix, int iy, int iHalfWidth, int iHalfHeight) +{ + D3DXVECTOR3 vtDir(float(ix - iHalfWidth), float(iy - iHalfHeight), 0.0f); + D3DXVec3Normalize(&vtDir, &vtDir); + + D3DXVECTOR3 vtStan(0, -1, 0); + float ret = D3DXToDegree(acosf(D3DXVec3Dot(&vtDir, &vtStan))); + + if (vtDir.x < 0.0f) + ret = 360.0f - ret; + + return 360.0f - ret; +} + +void CPythonPlayer::__ClearReservedAction() +{ + m_eReservedMode=MODE_NONE; +} + +void CPythonPlayer::__ReserveClickItem(DWORD dwItemID) +{ + m_eReservedMode=MODE_CLICK_ITEM; + m_dwIIDReserved=dwItemID; +} + +void CPythonPlayer::__ReserveClickActor(DWORD dwActorID) +{ + m_eReservedMode=MODE_CLICK_ACTOR; + m_dwVIDReserved=dwActorID; +} + +void CPythonPlayer::__ReserveClickGround(const TPixelPosition& c_rkPPosPickedGround) +{ + m_eReservedMode=MODE_CLICK_POSITION; + m_kPPosReserved=c_rkPPosPickedGround; + m_fReservedDelayTime=0.1f; +} + +bool CPythonPlayer::__IsReservedUseSkill(DWORD dwSkillSlotIndex) +{ + if (MODE_USE_SKILL!=m_eReservedMode) + return false; + + if (m_dwSkillSlotIndexReserved!=dwSkillSlotIndex) + return false; + + return true; +} + +void CPythonPlayer::__ReserveUseSkill(DWORD dwActorID, DWORD dwSkillSlotIndex, DWORD dwRange) +{ + m_eReservedMode=MODE_USE_SKILL; + m_dwVIDReserved=dwActorID; + m_dwSkillSlotIndexReserved=dwSkillSlotIndex; + m_dwSkillRangeReserved=dwRange; + + // NOTE : ƽƽϰ Ÿ ̴ ־ ణ ϰ.. + if (m_dwSkillRangeReserved > 100) + m_dwSkillRangeReserved -= 10; +} + +void CPythonPlayer::__ClearAutoAttackTargetActorID() +{ + __SetAutoAttackTargetActorID(0); +} + +void CPythonPlayer::__SetAutoAttackTargetActorID(DWORD dwVID) +{ + m_dwAutoAttackTargetVID = dwVID; +} + + +void CPythonPlayer::__ReserveProcess_ClickActor() +{ + CInstanceBase* pkInstMain = NEW_GetMainActorPtr(); + CInstanceBase* pkInstReserved = NEW_FindActorPtr(m_dwVIDReserved); + if (!pkInstMain || !pkInstReserved) + { + __ClearReservedAction(); + return; + } + + if (!pkInstMain->NEW_IsClickableDistanceDestInstance(*pkInstReserved)) + { + pkInstMain->NEW_MoveToDestInstanceDirection(*pkInstReserved); + return; + } + + if (!pkInstMain->IsAttackableInstance(*pkInstReserved)) + { + pkInstMain->NEW_Stop(); + __SendClickActorPacket(*pkInstReserved); + __ClearReservedAction(); + return; + } + + if (pkInstReserved->IsDead()) + { + __ClearReservedAction(); + return; + } + + if (pkInstMain->IsInSafe()) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotAttack", Py_BuildValue("(is)", GetMainCharacterIndex(), "IN_SAFE")); + pkInstMain->NEW_Stop(); + __ClearReservedAction(); + return; + } + + if (pkInstReserved->IsInSafe()) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotAttack", Py_BuildValue("(is)", GetMainCharacterIndex(), "DEST_IN_SAFE")); + pkInstMain->NEW_Stop(); + __ClearReservedAction(); + return; + } + + // źȯ ޷ ߿ ʴ´. + if (__CheckDashAffect(*pkInstMain)) + { + return; + } + + ///// + + if (pkInstMain->IsBowMode()) + { + if (!__HasEnoughArrow()) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotShot", Py_BuildValue("(is)", GetMainCharacterIndex(), "EMPTY_ARROW")); + pkInstMain->NEW_Stop(); + __ClearReservedAction(); + return; + } + } + + if (pkInstReserved->GetVirtualID() != GetTargetVID()) + { + SetTarget(pkInstReserved->GetVirtualID()); + } + + pkInstMain->NEW_AttackToDestInstanceDirection(*pkInstReserved); + __ClearReservedAction(); +} +/* +CInstanceBase* pkInstReserved=NEW_FindActorPtr(m_dwVIDReserved); +if (pkInstReserved) +{ + if (pkInstMain->NEW_IsClickableDistanceDestInstance(*pkInstReserved)) + { + if (pkInstMain->IsAttackableInstance(*pkInstReserved) ) + { + if (!pkInstReserved->IsDead()) + { + if (pkInstMain->IsInSafe()) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotAttack", Py_BuildValue("(is)", GetMainCharacterIndex(), "IN_SAFE")); + pkInstMain->NEW_Stop(); + } + else if (pkInstReserved->IsInSafe()) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotAttack", Py_BuildValue("(is)", GetMainCharacterIndex(), "DEST_IN_SAFE")); + pkInstMain->NEW_Stop(); + } + else + { + if (pkInstMain->IsBowMode()) + { + if (!__HasEnoughArrow()) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotShot", Py_BuildValue("(is)", GetMainCharacterIndex(), "EMPTY_ARROW")); + pkInstMain->NEW_Stop(); + __ClearReservedAction(); + break; + } + } + + if (pkInstReserved->GetVirtualID() != GetTargetVID()) + { + SetTarget(pkInstReserved->GetVirtualID()); + } + + pkInstMain->NEW_AttackToDestInstanceDirection(*pkInstReserved); + } + } + } + else + { + __SendClickActorPacket(*pkInstReserved); + + pkInstMain->NEW_Stop(); + } + + __ClearReservedAction(); + } + else + { + //Tracen("ReservedMode: MOVE"); + pkInstMain->NEW_MoveToDestInstanceDirection(*pkInstReserved); + } +} +else +{ + __ClearReservedAction(); +} +*/ diff --git a/source/UserInterface/PythonPlayerInputKeyboard.cpp b/source/UserInterface/PythonPlayerInputKeyboard.cpp new file mode 100644 index 0000000..2ba1fb4 --- /dev/null +++ b/source/UserInterface/PythonPlayerInputKeyboard.cpp @@ -0,0 +1,134 @@ +#include "StdAfx.h" +#include "PythonPlayer.h" + +#include "InstanceBase.h" + +void CPythonPlayer::SetAttackKeyState(bool isPress) +{ + if (isPress) + { + CInstanceBase* pkInstMain = NEW_GetMainActorPtr(); + if (pkInstMain) + if (pkInstMain->IsFishingMode()) + { + NEW_Fishing(); + return; + } + } + + m_isAtkKey=isPress; +} + +void CPythonPlayer::NEW_SetSingleDIKKeyState(int eDIKKey, bool isPress) +{ + if (NEW_CancelFishing()) + return; + + switch (eDIKKey) + { + case DIK_UP: + NEW_SetSingleDirKeyState(DIR_UP, isPress); + break; + case DIK_DOWN: + NEW_SetSingleDirKeyState(DIR_DOWN, isPress); + break; + case DIK_LEFT: + NEW_SetSingleDirKeyState(DIR_LEFT, isPress); + break; + case DIK_RIGHT: + NEW_SetSingleDirKeyState(DIR_RIGHT, isPress); + break; + } +} + +void CPythonPlayer::NEW_SetSingleDirKeyState(int eDirKey, bool isPress) +{ + switch (eDirKey) + { + case DIR_UP: + m_isUp=isPress; + break; + case DIR_DOWN: + m_isDown=isPress; + break; + case DIR_LEFT: + m_isLeft=isPress; + break; + case DIR_RIGHT: + m_isRight=isPress; + break; + } + + m_isDirKey=(m_isUp || m_isDown || m_isLeft || m_isRight); + + NEW_SetMultiDirKeyState(m_isLeft, m_isRight, m_isUp, m_isDown); +} + +void CPythonPlayer::NEW_SetMultiDirKeyState(bool isLeft, bool isRight, bool isUp, bool isDown) +{ + if (!__CanMove()) + return; + + bool isAny=(isLeft || isRight || isUp || isDown); + + if (isAny) + { + float fDirRot=0.0f; + NEW_GetMultiKeyDirRotation(isLeft, isRight, isUp, isDown, &fDirRot); + + if (!NEW_MoveToDirection(fDirRot)) + { + Tracen("CPythonPlayer::NEW_SetMultiKeyState - NEW_Move -> ERROR"); + return; + } + } + else + { + NEW_Stop(); + } +} + +float CPythonPlayer::GetDegreeFromDirection(int iUD, int iLR) +{ + switch(iUD) + { + case KEYBOARD_UD_UP: + if (KEYBOARD_LR_LEFT == iLR) + { + return +45.0f; + } + else if (KEYBOARD_LR_RIGHT == iLR) + { + return -45.0f; + } + + return 0.0f; + break; + + case KEYBOARD_UD_DOWN: + if (KEYBOARD_LR_LEFT == iLR) + { + return +135.0f; + } + else if (KEYBOARD_LR_RIGHT == iLR) + { + return -135.0f; + } + + return +180.0f; + break; + + case KEYBOARD_UD_NONE: + if (KEYBOARD_LR_LEFT == iLR) + { + return +90.0f; + } + else if (KEYBOARD_LR_RIGHT == iLR) + { + return -90.0f; + } + break; + } + + return 0.0f; +} diff --git a/source/UserInterface/PythonPlayerInputMouse.cpp b/source/UserInterface/PythonPlayerInputMouse.cpp new file mode 100644 index 0000000..85c47df --- /dev/null +++ b/source/UserInterface/PythonPlayerInputMouse.cpp @@ -0,0 +1,394 @@ +#include "StdAfx.h" +#include "PythonPlayer.h" +#include "PythonApplication.h" + +#include "../eterlib/Camera.h" + +void CPythonPlayer::NEW_SetMouseMoveState(int eMBS) +{ + if (MBS_PRESS==eMBS) + { + NEW_MoveToMouseScreenDirection(); + + m_isDirMov=true; + } + else if (MBS_CLICK==eMBS) + { + NEW_Stop(); + + m_isDirMov=false; + } +} + +bool CPythonPlayer::NEW_MoveToMouseScreenDirection() +{ + UI::CWindowManager& rkWndMgr=UI::CWindowManager::Instance(); + + long lMouseX; + long lMouseY; + rkWndMgr.GetMousePosition(lMouseX, lMouseY); + + long lScrWidth = rkWndMgr.GetScreenWidth(); + long lScrHeight = rkWndMgr.GetScreenHeight(); + float fMouseX=lMouseX/float(lScrWidth); + float fMouseY=lMouseY/float(lScrHeight); + + float fDirRot; + NEW_GetMouseDirRotation(fMouseX, fMouseY, &fDirRot); + + return NEW_MoveToDirection(fDirRot); +} + +void CPythonPlayer::NEW_SetMouseCameraState(int eMBS) +{ + CPythonApplication & rkApp = CPythonApplication::Instance(); + CPythonBackground & rkBG = CPythonBackground::Instance(); + CCamera* pkCmrCur=CCameraManager::Instance().GetCurrentCamera(); + + if (pkCmrCur) + { + if (MBS_PRESS==eMBS) + { + UI::CWindowManager& rkWndMgr=UI::CWindowManager::Instance(); + + long lMouseX; + long lMouseY; + rkWndMgr.GetMousePosition(lMouseX, lMouseY); + + pkCmrCur->BeginDrag(lMouseX, lMouseY); + + if ( !rkBG.IsMapReady() ) + return; + + rkApp.SetCursorNum(CPythonApplication::CAMERA_ROTATE); + if ( CPythonApplication::CURSOR_MODE_HARDWARE == rkApp.GetCursorMode()) + rkApp.SetCursorVisible(FALSE, true); + + } + else if (MBS_CLICK==eMBS) + { + bool isCameraDrag=pkCmrCur->EndDrag(); + + if ( !rkBG.IsMapReady() ) + return; + + rkApp.SetCursorNum(CPythonApplication::NORMAL); + if ( CPythonApplication::CURSOR_MODE_HARDWARE == rkApp.GetCursorMode()) + rkApp.SetCursorVisible(TRUE); + + if (!isCameraDrag) + { + __ChangeTargetToPickedInstance(); + + CInstanceBase * pkInstPicked; + if (__GetPickedActorPtr(&pkInstPicked)) + { + OpenCharacterMenu(pkInstPicked->GetVirtualID()); + } + } + } + } +} + + + +void CPythonPlayer::NEW_SetMouseSmartState(int eMBS, bool isAuto) +{ + CInstanceBase* pkInstMain=NEW_GetMainActorPtr(); + if (!pkInstMain) return; + + // PrivateShop + if (IsOpenPrivateShop()) + { + // ShopPacket + m_isSmtMov=false; + return; + } + + // Emotion + if (__IsProcessingEmotion()) + { + return; + } + + // AFFECT_STUN ó + if (pkInstMain->IsSleep()) + { + return; + } + + if (MBS_PRESS==eMBS) + { + m_isSmtMov=true; + + __OnPressSmart(*pkInstMain, isAuto); + } + else if (MBS_CLICK==eMBS) + { + m_isSmtMov=false; + + __OnClickSmart(*pkInstMain, isAuto); + } +} + +void CPythonPlayer::__OnPressSmart(CInstanceBase& rkInstMain, bool isAuto) +{ + DWORD dwPickedItemID; + DWORD dwPickedActorID; + TPixelPosition kPPosPickedGround; + + bool isPickedItemID=__GetPickedItemID(&dwPickedItemID); + bool isPickedActorID=__GetPickedActorID(&dwPickedActorID); + bool isPickedGroundPos=__GetPickedGroundPos(&kPPosPickedGround); + + if (isPickedItemID) + { + __OnPressItem(rkInstMain, dwPickedItemID); + } + else if (isPickedActorID && dwPickedActorID != GetMainCharacterIndex()) + { + __OnPressActor(rkInstMain, dwPickedActorID, isAuto); + } + else if (isPickedGroundPos) + { + __OnPressGround(rkInstMain, kPPosPickedGround); + } + else + { + __OnPressScreen(rkInstMain); + } +} + +void CPythonPlayer::__OnClickSmart(CInstanceBase& rkInstMain, bool isAuto) +{ + DWORD dwPickedItemID; + DWORD dwPickedActorID; + TPixelPosition kPPosPickedGround; + if (__GetPickedItemID(&dwPickedItemID)) + { + __OnClickItem(rkInstMain, dwPickedItemID); + } + else if (__GetPickedActorID(&dwPickedActorID)) + { + __OnClickActor(rkInstMain, dwPickedActorID, isAuto); + } + else if (__GetPickedGroundPos(&kPPosPickedGround)) + { + __OnClickGround(rkInstMain, kPPosPickedGround); + } + else + { + rkInstMain.NEW_Stop(); + } +} + +void CPythonPlayer::__ShowPickedEffect(const TPixelPosition& c_rkPPosPickedGround) +{ +#ifdef __MOVIE_MODE__ + CInstanceBase* pkInstMain=NEW_GetMainActorPtr(); + if (!pkInstMain) return; + + if (pkInstMain->IsMovieMode()) + return; +#endif + NEW_ShowEffect(EFFECT_PICK, c_rkPPosPickedGround); +} + +bool CPythonPlayer::NEW_SetMouseFunc(int eMBT, int eMBF) +{ + if (eMBT>=MBT_NUM) + return false; + + m_aeMBFButton[eMBT]=eMBF; + + return true; +} + +int CPythonPlayer::NEW_GetMouseFunc(int eMBT) +{ + if (eMBT>=MBT_NUM) + return false; + + return m_aeMBFButton[eMBT]; +} + +void CPythonPlayer::SetQuickCameraMode(bool isEnable) +{ + if (isEnable) + { + } + else + { + NEW_SetMouseCameraState(MBS_CLICK); + } +} + +bool CPythonPlayer::NEW_SetMouseState(int eMBT, int eMBS) +{ + if (eMBT>=MBT_NUM) + return false; + + int eMBF=m_aeMBFButton[eMBT]; + switch (eMBF) + { + case MBF_MOVE: + if (__CanMove()) + NEW_SetMouseMoveState(eMBS); + break; + case MBF_SMART: + if (CPythonApplication::Instance().IsPressed(DIK_LCONTROL) || CPythonApplication::Instance().IsPressed(DIK_RCONTROL)) + { + NEW_Attack(); + } + else + { + NEW_SetMouseSmartState(eMBS, false); + } + break; + case MBF_CAMERA: + NEW_SetMouseCameraState(eMBS); + break; + case MBF_AUTO: + NEW_SetMouseSmartState(eMBS, true); + break; + case MBF_ATTACK: + NEW_Attack(); + break; + case MBF_SKILL: + if (CPythonApplication::Instance().IsPressed(DIK_LCONTROL)) + { + NEW_SetMouseCameraState(eMBS); + } + else + { + if (MBS_PRESS == eMBS) + { + __ChangeTargetToPickedInstance(); + __UseCurrentSkill(); + } + } + break; + } + + return true; +} + +void CPythonPlayer::NEW_SetMouseMiddleButtonState(int eMBState) +{ + NEW_SetMouseCameraState(eMBState); +} + + + +void CPythonPlayer::NEW_RefreshMouseWalkingDirection() +{ + CInstanceBase* pkInstMain = NEW_GetMainActorPtr(); + if (!pkInstMain) return; + + switch (m_eReservedMode) + { + case MODE_CLICK_ITEM: + { + CPythonItem& rkIT=CPythonItem::Instance(); + + TPixelPosition kPPosPickedItem; + if (rkIT.GetGroundItemPosition(m_dwIIDReserved, &kPPosPickedItem)) + { + if (pkInstMain->NEW_GetDistanceFromDestPixelPosition(kPPosPickedItem)<20.0f) + { + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + + TPixelPosition kPPosCur; + pkInstMain->NEW_GetPixelPosition(&kPPosCur); + + float fCurRot=pkInstMain->GetRotation(); + rkNetStream.SendCharacterStatePacket(kPPosCur, fCurRot, CInstanceBase::FUNC_WAIT, 0); + SendClickItemPacket(m_dwIIDReserved); + + pkInstMain->NEW_Stop(); + + __ClearReservedAction(); + } + else + { + pkInstMain->NEW_MoveToDestPixelPositionDirection(kPPosPickedItem); + } + } + else + { + __ClearReservedAction(); + } + + break; + } + + case MODE_CLICK_ACTOR: + { + __ReserveProcess_ClickActor(); + break; + } + + case MODE_CLICK_POSITION: + { + if (!pkInstMain->isLock()) + if (NEW_IsEmptyReservedDelayTime(CPythonApplication::Instance().GetGlobalElapsedTime())) + { + pkInstMain->NEW_MoveToDestPixelPositionDirection(m_kPPosReserved); + __ClearReservedAction(); + } + break; + } + + case MODE_USE_SKILL: + { + CInstanceBase* pkInstReserved=NEW_FindActorPtr(m_dwVIDReserved); + if (pkInstReserved) + { + float fDistance=pkInstMain->GetDistance(pkInstReserved); + + // #0000806: [M2EU] 濡 (ѱ) źȯ ų ȵ + extern bool IS_HUGE_RACE(unsigned int vnum); + if (IS_HUGE_RACE(pkInstReserved->GetRace())) // Ŵ + { + fDistance -= 200.0f; // TEMP: ϴ ϵ ڵ ó. δ ٿ Ǿ ؾ + } + + if (fDistance < float(m_dwSkillRangeReserved)) + { + // Target ٲ ִ - [levites] + SetTarget(m_dwVIDReserved); + if (__UseSkill(m_dwSkillSlotIndexReserved)) + __ClearReservedAction(); + } + else + { + pkInstMain->NEW_MoveToDestInstanceDirection(*pkInstReserved); + } + } + else + { + __ClearReservedAction(); + } + break; + } + } + + if (m_isSmtMov) + __OnPressSmart(*pkInstMain, false); + + if (m_isDirMov) + NEW_MoveToMouseScreenDirection(); + + if (m_isDirKey) + NEW_SetMultiDirKeyState(m_isLeft, m_isRight, m_isUp, m_isDown); + + if (m_isAtkKey) + NEW_Attack(); + + m_iComboOld=pkInstMain->GetComboIndex(); +} + +BOOL CPythonPlayer::__IsRightButtonSkillMode() +{ + return MBF_SKILL == m_aeMBFButton[MBT_RIGHT]; +} diff --git a/source/UserInterface/PythonPlayerModule.cpp b/source/UserInterface/PythonPlayerModule.cpp new file mode 100644 index 0000000..9388730 --- /dev/null +++ b/source/UserInterface/PythonPlayerModule.cpp @@ -0,0 +1,2572 @@ +#include "StdAfx.h" +#include "PythonPlayer.h" +#include "PythonApplication.h" + +extern const DWORD c_iSkillIndex_Tongsol = 121; +extern const DWORD c_iSkillIndex_Combo = 122; +extern const DWORD c_iSkillIndex_Fishing = 123; +extern const DWORD c_iSkillIndex_Mining = 124; +extern const DWORD c_iSkillIndex_Making = 125; +extern const DWORD c_iSkillIndex_Language1 = 126; +extern const DWORD c_iSkillIndex_Language2 = 127; +extern const DWORD c_iSkillIndex_Language3 = 128; +extern const DWORD c_iSkillIndex_Polymorph = 129; +extern const DWORD c_iSkillIndex_Riding = 130; +extern const DWORD c_iSkillIndex_Summon = 131; + +enum +{ + EMOTION_CLAP = 1, + EMOTION_CHEERS_1, + EMOTION_CHEERS_2, + EMOTION_DANCE_1, + EMOTION_DANCE_2, + EMOTION_DANCE_3, + EMOTION_DANCE_4, + EMOTION_DANCE_5, + EMOTION_DANCE_6, // Ÿ + EMOTION_CONGRATULATION, + EMOTION_FORGIVE, + EMOTION_ANGRY, + + EMOTION_ATTRACTIVE, + EMOTION_SAD, + EMOTION_SHY, + EMOTION_CHEERUP, + EMOTION_BANTER, + EMOTION_JOY, + + EMOTION_KISS = 51, + EMOTION_FRENCH_KISS, + EMOTION_SLAP, + +}; + +std::map m_kMap_iEmotionIndex_pkIconImage; + +extern int TWOHANDED_WEWAPON_ATT_SPEED_DECREASE_VALUE; + + +#ifdef ENABLE_NEW_EQUIPMENT_SYSTEM +class CBeltInventoryHelper +{ +public: + typedef BYTE TGradeUnit; + + static TGradeUnit GetBeltGradeByRefineLevel(int refineLevel) + { + static TGradeUnit beltGradeByLevelTable[] = + { + 0, // Ʈ+0 + 1, // +1 + 1, // +2 + 2, // +3 + 2, // +4, + 3, // +5 + 4, // +6, + 5, // +7, + 6, // +8, + 7, // +9 + }; + + return beltGradeByLevelTable[refineLevel]; + } + + // Ʈ ,  ̿ ִ + static const TGradeUnit* GetAvailableRuleTableByGrade() + { + /** + Ʈ +0 ~ +9 , 7ܰ еǾ κ丮 Ȱ ȭ ȴ. + Ʈ Ʒ ׸ . >= Ȱ ̸ . + (, 0̸ Ұ, ȣ ڴ ) + + 2(1) 4(2) 6(4) 8(6) + 5(3) 5(3) 6(4) 8(6) + 7(5) 7(5) 7(5) 8(6) + 9(7) 9(7) 9(7) 9(7) + + Ʈ κ丮 ũ 4x4 (16ĭ) + */ + + static TGradeUnit availableRuleByGrade[c_Belt_Inventory_Slot_Count] = { + 1, 2, 4, 6, + 3, 3, 4, 6, + 5, 5, 5, 6, + 7, 7, 7, 7 + }; + + return availableRuleByGrade; + } + + static bool IsAvailableCell(WORD cell, int beltGrade /*int beltLevel*/) + { + // ȹ ٲ.. Ƴ... + //const TGradeUnit beltGrade = GetBeltGradeByRefineLevel(beltLevel); + const TGradeUnit* ruleTable = GetAvailableRuleTableByGrade(); + + return ruleTable[cell] <= beltGrade; + } + +}; +#endif + +PyObject * playerPickCloseItem(PyObject* poSelf, PyObject* poArgs) +{ + CPythonPlayer::Instance().PickCloseItem(); + return Py_BuildNone(); +} + + +PyObject * playerSetGameWindow(PyObject* poSelf, PyObject* poArgs) +{ + PyObject * pyHandle; + if (!PyTuple_GetObject(poArgs, 0, &pyHandle)) + return Py_BadArgument(); + + CPythonPlayer & rkPlayer = CPythonPlayer::Instance(); + rkPlayer.SetGameWindow(pyHandle); + return Py_BuildNone(); +} + + +PyObject * playerSetQuickCameraMode(PyObject* poSelf, PyObject* poArgs) +{ + int nIsEnable; + if (!PyTuple_GetInteger(poArgs, 0, &nIsEnable)) + return Py_BadArgument(); + + CPythonPlayer & rkPlayer = CPythonPlayer::Instance(); + rkPlayer.SetQuickCameraMode(nIsEnable ? true : false); + + return Py_BuildNone(); +} + +// Test Code +PyObject * playerSetMainCharacterIndex(PyObject* poSelf, PyObject* poArgs) +{ + int iVID; + if (!PyTuple_GetInteger(poArgs, 0, &iVID)) + return Py_BuildException(); + + CPythonPlayer::Instance().SetMainCharacterIndex(iVID); + CPythonCharacterManager::Instance().SetMainInstance(iVID); + + return Py_BuildNone(); +} +// Test Code + +PyObject * playerGetMainCharacterIndex(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildValue("i", CPythonPlayer::Instance().GetMainCharacterIndex()); +} + +PyObject * playerGetMainCharacterName(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildValue("s", CPythonPlayer::Instance().GetName()); +} + +PyObject * playerGetMainCharacterPosition(PyObject* poSelf, PyObject* poArgs) +{ + TPixelPosition kPPosMainActor; + CPythonPlayer & rkPlayer = CPythonPlayer::Instance(); + rkPlayer.NEW_GetMainActorPosition(&kPPosMainActor); + return Py_BuildValue("fff", kPPosMainActor.x, kPPosMainActor.y, kPPosMainActor.z); +} + +PyObject * playerIsMainCharacterIndex(PyObject* poSelf, PyObject* poArgs) +{ + int iVID; + if (!PyTuple_GetInteger(poArgs, 0, &iVID)) + return Py_BuildException(); + + return Py_BuildValue("i", CPythonPlayer::Instance().IsMainCharacterIndex(iVID)); +} + +PyObject * playerCanAttackInstance(PyObject* poSelf, PyObject* poArgs) +{ + int iVID; + if (!PyTuple_GetInteger(poArgs, 0, &iVID)) + return Py_BuildException(); + + CInstanceBase * pMainInstance = CPythonPlayer::Instance().NEW_GetMainActorPtr(); + CInstanceBase * pTargetInstance = CPythonCharacterManager::Instance().GetInstancePtr(iVID); + if (!pMainInstance) + return Py_BuildValue("i", 0); + if (!pTargetInstance) + return Py_BuildValue("i", 0); + + return Py_BuildValue("i", pMainInstance->IsAttackableInstance(*pTargetInstance)); +} + +PyObject * playerIsActingEmotion(PyObject* poSelf, PyObject* poArgs) +{ + CInstanceBase * pMainInstance = CPythonPlayer::Instance().NEW_GetMainActorPtr(); + if (!pMainInstance) + return Py_BuildValue("i", 0); + + return Py_BuildValue("i", pMainInstance->IsActingEmotion()); +} + +PyObject * playerIsPVPInstance(PyObject* poSelf, PyObject* poArgs) +{ + int iVID; + if (!PyTuple_GetInteger(poArgs, 0, &iVID)) + return Py_BuildException(); + + CInstanceBase * pMainInstance = CPythonPlayer::Instance().NEW_GetMainActorPtr(); + CInstanceBase * pTargetInstance = CPythonCharacterManager::Instance().GetInstancePtr(iVID); + if (!pMainInstance) + return Py_BuildValue("i", 0); + if (!pTargetInstance) + return Py_BuildValue("i", 0); + + return Py_BuildValue("i", pMainInstance->IsPVPInstance(*pTargetInstance)); +} + +PyObject * playerIsSameEmpire(PyObject* poSelf, PyObject* poArgs) +{ + int iVID; + if (!PyTuple_GetInteger(poArgs, 0, &iVID)) + return Py_BuildException(); + + CInstanceBase * pMainInstance = CPythonPlayer::Instance().NEW_GetMainActorPtr(); + CInstanceBase * pTargetInstance = CPythonCharacterManager::Instance().GetInstancePtr(iVID); + if (!pMainInstance) + return Py_BuildValue("i", FALSE); + if (!pTargetInstance) + return Py_BuildValue("i", FALSE); + + return Py_BuildValue("i", pMainInstance->IsSameEmpire(*pTargetInstance)); +} + +PyObject * playerIsChallengeInstance(PyObject* poSelf, PyObject* poArgs) +{ + int iVID; + if (!PyTuple_GetInteger(poArgs, 0, &iVID)) + return Py_BuildException(); + + return Py_BuildValue("i", CPythonPlayer::Instance().IsChallengeInstance(iVID)); +} + +PyObject * playerIsRevengeInstance(PyObject* poSelf, PyObject* poArgs) +{ + int iVID; + if (!PyTuple_GetInteger(poArgs, 0, &iVID)) + return Py_BuildException(); + + return Py_BuildValue("i", CPythonPlayer::Instance().IsRevengeInstance(iVID)); +} + +PyObject * playerIsCantFightInstance(PyObject* poSelf, PyObject* poArgs) +{ + int iVID; + if (!PyTuple_GetInteger(poArgs, 0, &iVID)) + return Py_BuildException(); + + return Py_BuildValue("i", CPythonPlayer::Instance().IsCantFightInstance(iVID)); +} + +PyObject * playerGetCharacterDistance(PyObject* poSelf, PyObject* poArgs) +{ + int iVID; + if (!PyTuple_GetInteger(poArgs, 0, &iVID)) + return Py_BuildException(); + + CInstanceBase * pMainInstance = CPythonPlayer::Instance().NEW_GetMainActorPtr(); + CInstanceBase * pTargetInstance = CPythonCharacterManager::Instance().GetInstancePtr(iVID); + if (!pMainInstance) + return Py_BuildValue("f", -1.0f); + if (!pTargetInstance) + return Py_BuildValue("f", -1.0f); + + return Py_BuildValue("f", pMainInstance->GetDistance(pTargetInstance)); +} + +PyObject * playerIsInSafeArea(PyObject* poSelf, PyObject* poArgs) +{ + CInstanceBase * pMainInstance = CPythonPlayer::Instance().NEW_GetMainActorPtr(); + if (!pMainInstance) + return Py_BuildValue("i", FALSE); + + return Py_BuildValue("i", pMainInstance->IsInSafe()); +} + +PyObject * playerIsMountingHorse(PyObject* poSelf, PyObject* poArgs) +{ + CInstanceBase * pMainInstance = CPythonPlayer::Instance().NEW_GetMainActorPtr(); + if (!pMainInstance) + return Py_BuildValue("i", FALSE); + + return Py_BuildValue("i", pMainInstance->IsMountingHorse()); +} + +PyObject * playerIsObserverMode(PyObject* poSelf, PyObject* poArgs) +{ + CPythonPlayer& rkPlayer=CPythonPlayer::Instance(); + return Py_BuildValue("i", rkPlayer.IsObserverMode()); +} + +PyObject * playerActEmotion(PyObject* poSelf, PyObject* poArgs) +{ + int iVID; + if (!PyTuple_GetInteger(poArgs, 0, &iVID)) + return Py_BuildException(); + + CPythonPlayer& rkPlayer=CPythonPlayer::Instance(); + rkPlayer.ActEmotion(iVID); + return Py_BuildNone(); +} + +PyObject * playerShowPlayer(PyObject* poSelf, PyObject* poArgs) +{ + CInstanceBase * pMainInstance = CPythonPlayer::Instance().NEW_GetMainActorPtr(); + if (pMainInstance) + pMainInstance->GetGraphicThingInstanceRef().Show(); + return Py_BuildNone(); +} + +PyObject * playerHidePlayer(PyObject* poSelf, PyObject* poArgs) +{ + CInstanceBase * pMainInstance = CPythonPlayer::Instance().NEW_GetMainActorPtr(); + if (pMainInstance) + pMainInstance->GetGraphicThingInstanceRef().Hide(); + return Py_BuildNone(); +} + + +PyObject * playerComboAttack(PyObject* poSelf, PyObject* poArgs) +{ + CPythonPlayer::Instance().NEW_Attack(); + return Py_BuildNone(); +} + + +PyObject * playerRegisterEffect(PyObject* poSelf, PyObject* poArgs) +{ + int iEft; + if (!PyTuple_GetInteger(poArgs, 0, &iEft)) + return Py_BadArgument(); + + char* szFileName; + if (!PyTuple_GetString(poArgs, 1, &szFileName)) + return Py_BadArgument(); + + CPythonPlayer & rkPlayer = CPythonPlayer::Instance(); + if (!rkPlayer.RegisterEffect(iEft, szFileName, false)) + return Py_BuildException("CPythonPlayer::RegisterEffect(eEft=%d, szFileName=%s", iEft, szFileName); + + return Py_BuildNone(); +} + +PyObject * playerRegisterCacheEffect(PyObject* poSelf, PyObject* poArgs) +{ + int iEft; + if (!PyTuple_GetInteger(poArgs, 0, &iEft)) + return Py_BadArgument(); + + char* szFileName; + if (!PyTuple_GetString(poArgs, 1, &szFileName)) + return Py_BadArgument(); + + CPythonPlayer & rkPlayer = CPythonPlayer::Instance(); + if (!rkPlayer.RegisterEffect(iEft, szFileName, true)) + return Py_BuildException("CPythonPlayer::RegisterEffect(eEft=%d, szFileName=%s", iEft, szFileName); + + return Py_BuildNone(); +} + +PyObject * playerSetAttackKeyState(PyObject* poSelf, PyObject* poArgs) +{ + int isPressed; + if (!PyTuple_GetInteger(poArgs, 0, &isPressed)) + return Py_BuildException("playerSetAttackKeyState(isPressed) - There is no first argument"); + + CPythonPlayer & rkPlayer = CPythonPlayer::Instance(); + rkPlayer.SetAttackKeyState(isPressed ? true : false); + return Py_BuildNone(); +} + +PyObject * playerSetSingleDIKKeyState(PyObject* poSelf, PyObject* poArgs) +{ + int eDIK; + if (!PyTuple_GetInteger(poArgs, 0, &eDIK)) + return Py_BuildException("playerSetSingleDIKKeyState(eDIK, isPressed) - There is no first argument"); + + int isPressed; + if (!PyTuple_GetInteger(poArgs, 1, &isPressed)) + return Py_BuildException("playerSetSingleDIKKeyState(eDIK, isPressed) - There is no second argument"); + + CPythonPlayer & rkPlayer = CPythonPlayer::Instance(); + rkPlayer.NEW_SetSingleDIKKeyState(eDIK, isPressed ? true : false); + return Py_BuildNone(); +} + +PyObject * playerEndKeyWalkingImmediately(PyObject* poSelf, PyObject* poArgs) +{ + CPythonPlayer::Instance().NEW_Stop(); + return Py_BuildNone(); +} + + +PyObject * playerStartMouseWalking(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildNone(); +} + +PyObject * playerEndMouseWalking(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildNone(); +} + +PyObject * playerResetCameraRotation(PyObject* poSelf, PyObject* poArgs) +{ + CPythonPlayer::Instance().NEW_ResetCameraRotation(); + return Py_BuildNone(); +} + +PyObject* playerSetAutoCameraRotationSpeed(PyObject* poSelf, PyObject* poArgs) +{ + float fCmrRotSpd; + if (!PyTuple_GetFloat(poArgs, 0, &fCmrRotSpd)) + return Py_BuildException(); + + CPythonPlayer& rkPlayer=CPythonPlayer::Instance(); + rkPlayer.NEW_SetAutoCameraRotationSpeed(fCmrRotSpd); + return Py_BuildNone(); +} + +PyObject* playerSetMouseState(PyObject* poSelf, PyObject* poArgs) +{ + int eMBT; + if (!PyTuple_GetInteger(poArgs, 0, &eMBT)) + return Py_BuildException(); + + int eMBS; + if (!PyTuple_GetInteger(poArgs, 1, &eMBS)) + return Py_BuildException(); + + CPythonPlayer& rkPlayer=CPythonPlayer::Instance(); + rkPlayer.NEW_SetMouseState(eMBT, eMBS); + + return Py_BuildNone(); +} + +PyObject* playerSetMouseFunc(PyObject* poSelf, PyObject* poArgs) +{ + int eMBT; + if (!PyTuple_GetInteger(poArgs, 0, &eMBT)) + return Py_BuildException(); + + int eMBS; + if (!PyTuple_GetInteger(poArgs, 1, &eMBS)) + return Py_BuildException(); + + CPythonPlayer& rkPlayer=CPythonPlayer::Instance(); + rkPlayer.NEW_SetMouseFunc(eMBT, eMBS); + + return Py_BuildNone(); +} + +PyObject* playerGetMouseFunc(PyObject* poSelf, PyObject* poArgs) +{ + int eMBT; + if (!PyTuple_GetInteger(poArgs, 0, &eMBT)) + return Py_BuildException(); + + CPythonPlayer& rkPlayer=CPythonPlayer::Instance(); + return Py_BuildValue("i", rkPlayer.NEW_GetMouseFunc(eMBT)); +} + +PyObject* playerSetMouseMiddleButtonState(PyObject* poSelf, PyObject* poArgs) +{ + int eMBS; + if (!PyTuple_GetInteger(poArgs, 0, &eMBS)) + return Py_BuildException(); + + CPythonPlayer& rkPlayer=CPythonPlayer::Instance(); + rkPlayer.NEW_SetMouseMiddleButtonState(eMBS); + + return Py_BuildNone(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +PyObject * playerGetName(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildValue("s", CPythonPlayer::Instance().GetName()); +} + +PyObject * playerGetRace(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildValue("i", CPythonPlayer::Instance().GetRace()); +} + +PyObject * playerGetJob(PyObject* poSelf, PyObject* poArgs) +{ + int race = CPythonPlayer::Instance().GetRace(); + int job = RaceToJob(race); + return Py_BuildValue("i", job); +} + +PyObject * playerGetPlayTime(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildValue("i", CPythonPlayer::Instance().GetPlayTime()); +} + +PyObject * playerSetPlayTime(PyObject* poSelf, PyObject* poArgs) +{ + int iTime; + if (!PyTuple_GetInteger(poArgs, 0, &iTime)) + return Py_BuildException(); + + CPythonPlayer::Instance().SetPlayTime(iTime); + return Py_BuildNone(); +} + +PyObject * playerIsSkillCoolTime(PyObject* poSelf, PyObject* poArgs) +{ + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + + return Py_BuildValue("i", CPythonPlayer::Instance().IsSkillCoolTime(iSlotIndex)); +} + +PyObject * playerGetSkillCoolTime(PyObject* poSelf, PyObject* poArgs) +{ + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + + float fCoolTime = CPythonPlayer::Instance().GetSkillCoolTime(iSlotIndex); + float fElapsedCoolTime = CPythonPlayer::Instance().GetSkillElapsedCoolTime(iSlotIndex); + return Py_BuildValue("ff", fCoolTime, fElapsedCoolTime); +} + +PyObject * playerIsSkillActive(PyObject* poSelf, PyObject* poArgs) +{ + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + + return Py_BuildValue("i", CPythonPlayer::Instance().IsSkillActive(iSlotIndex)); +} + +PyObject * playerUseGuildSkill(PyObject* poSelf, PyObject* poArgs) +{ + int iSkillSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillSlotIndex)) + return Py_BuildException(); + + CPythonPlayer::Instance().UseGuildSkill(iSkillSlotIndex); + return Py_BuildNone(); +} + +PyObject * playerAffectIndexToSkillIndex(PyObject* poSelf, PyObject* poArgs) +{ + int iAffectIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iAffectIndex)) + return Py_BuildException(); + + DWORD dwSkillIndex; + if (!CPythonPlayer::Instance().AffectIndexToSkillIndex(iAffectIndex, &dwSkillIndex)) + return Py_BuildValue("i", 0); + + return Py_BuildValue("i", dwSkillIndex); +} + +PyObject * playerGetEXP(PyObject* poSelf, PyObject* poArgs) +{ + DWORD dwEXP = CPythonPlayer::Instance().GetStatus(POINT_EXP); + return Py_BuildValue("l", dwEXP); +} + +PyObject * playerGetStatus(PyObject* poSelf, PyObject* poArgs) +{ + int iType; + if (!PyTuple_GetInteger(poArgs, 0, &iType)) + return Py_BuildException(); + + long iValue = CPythonPlayer::Instance().GetStatus(iType); + + if (POINT_ATT_SPEED == iType) + { + CInstanceBase * pInstance = CPythonPlayer::Instance().NEW_GetMainActorPtr(); + if (pInstance && (CItemData::WEAPON_TWO_HANDED == pInstance->GetWeaponType())) + { + iValue -= TWOHANDED_WEWAPON_ATT_SPEED_DECREASE_VALUE; + } + } + + return Py_BuildValue("i", iValue); +} + +PyObject * playerSetStatus(PyObject* poSelf, PyObject* poArgs) +{ + int iType; + if (!PyTuple_GetInteger(poArgs, 0, &iType)) + return Py_BuildException(); + + int iValue; + if (!PyTuple_GetInteger(poArgs, 1, &iValue)) + return Py_BuildException(); + + CPythonPlayer::Instance().SetStatus(iType, iValue); + return Py_BuildNone(); +} + +PyObject * playerGetElk(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildValue("i", CPythonPlayer::Instance().GetStatus(POINT_GOLD)); +} + +PyObject * playerGetGuildID(PyObject* poSelf, PyObject* poArgs) +{ + CInstanceBase * pInstance = CPythonPlayer::Instance().NEW_GetMainActorPtr(); + if (!pInstance) + return Py_BuildValue("i", 0); + return Py_BuildValue("i", pInstance->GetGuildID()); +} + +PyObject * playerGetGuildName(PyObject* poSelf, PyObject* poArgs) +{ + CInstanceBase * pInstance = CPythonPlayer::Instance().NEW_GetMainActorPtr(); + if (pInstance) + { + DWORD dwID = pInstance->GetGuildID(); + std::string strName; + if (CPythonGuild::Instance().GetGuildName(dwID, &strName)) + return Py_BuildValue("s", strName.c_str()); + } + return Py_BuildValue("s", ""); +} + +PyObject * playerGetAlignmentData(PyObject* poSelf, PyObject* poArgs) +{ + CInstanceBase * pInstance = CPythonPlayer::Instance().NEW_GetMainActorPtr(); + int iAlignmentPoint = 0; + int iAlignmentGrade = 4; + if (pInstance) + { + iAlignmentPoint = pInstance->GetAlignment(); + iAlignmentGrade = pInstance->GetAlignmentGrade(); + } + return Py_BuildValue("ii", iAlignmentPoint, iAlignmentGrade); +} + +PyObject * playerSetSkill(PyObject* poSelf, PyObject* poArgs) +{ + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iSkillIndex)) + return Py_BuildException(); + + CPythonPlayer::Instance().SetSkill(iSlotIndex, iSkillIndex); + return Py_BuildNone(); +} + +PyObject * playerGetSkillIndex(PyObject* poSelf, PyObject* poArgs) +{ + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + + return Py_BuildValue("i", CPythonPlayer::Instance().GetSkillIndex(iSlotIndex)); +} + +PyObject * playerGetSkillSlotIndex(PyObject* poSelf, PyObject* poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BuildException(); + + DWORD dwSlotIndex; + if (!CPythonPlayer::Instance().GetSkillSlotIndex(iSkillIndex, &dwSlotIndex)) + return Py_BuildException(); + + return Py_BuildValue("i", dwSlotIndex); +} + +PyObject * playerGetSkillGrade(PyObject* poSelf, PyObject* poArgs) +{ + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + + return Py_BuildValue("i", CPythonPlayer::Instance().GetSkillGrade(iSlotIndex)); +} + +PyObject * playerGetSkillLevel(PyObject* poSelf, PyObject* poArgs) +{ + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + + return Py_BuildValue("i", CPythonPlayer::Instance().GetSkillLevel(iSlotIndex)); +} + +PyObject * playerGetSkillCurrentEfficientPercentage(PyObject* poSelf, PyObject* poArgs) +{ + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + + return Py_BuildValue("f", CPythonPlayer::Instance().GetSkillCurrentEfficientPercentage(iSlotIndex)); +} +PyObject * playerGetSkillNextEfficientPercentage(PyObject* poSelf, PyObject* poArgs) +{ + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + + return Py_BuildValue("f", CPythonPlayer::Instance().GetSkillNextEfficientPercentage(iSlotIndex)); +} + +PyObject * playerClickSkillSlot(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillSlot; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillSlot)) + return Py_BadArgument(); + + CPythonPlayer::Instance().ClickSkillSlot(iSkillSlot); + + return Py_BuildNone(); +} + +PyObject * playerChangeCurrentSkillNumberOnly(PyObject * poSelf, PyObject * poArgs) +{ + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BadArgument(); + + CPythonPlayer::Instance().ChangeCurrentSkillNumberOnly(iSlotIndex); + + return Py_BuildNone(); +} + +PyObject * playerClearSkillDict(PyObject * poSelf, PyObject * poArgs) +{ + CPythonPlayer::Instance().ClearSkillDict(); + return Py_BuildNone(); +} + +PyObject * playerMoveItem(PyObject* poSelf, PyObject* poArgs) +{ + TItemPos srcCell; + TItemPos dstCell; + switch (PyTuple_Size(poArgs)) + { + case 2: + //int iSourceSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &srcCell.cell)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 1, &dstCell.cell)) + return Py_BuildException(); + break; + case 4: + if (!PyTuple_GetByte(poArgs, 0, &srcCell.window_type)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 1, &srcCell.cell)) + return Py_BuildException(); + if (!PyTuple_GetByte(poArgs, 2, &dstCell.window_type)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 3, &dstCell.cell)) + return Py_BuildException(); + default: + return Py_BuildException(); + } + + CPythonPlayer::Instance().MoveItemData(srcCell, dstCell); + return Py_BuildNone(); +} + +PyObject * playerSendClickItemPacket(PyObject* poSelf, PyObject* poArgs) +{ + int ivid; + if (!PyTuple_GetInteger(poArgs, 0, &ivid)) + return Py_BuildException(); + + CPythonPlayer::Instance().SendClickItemPacket(ivid); + return Py_BuildNone(); +} + +PyObject * playerGetItemIndex(PyObject* poSelf, PyObject* poArgs) +{ + switch (PyTuple_Size(poArgs)) + { + case 1: + { + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + + int ItemIndex = CPythonPlayer::Instance().GetItemIndex(TItemPos (INVENTORY, iSlotIndex)); + return Py_BuildValue("i", ItemIndex); + } + case 2: + { + TItemPos Cell; + if (!PyTuple_GetByte(poArgs, 0, &Cell.window_type)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 1, &Cell.cell)) + return Py_BuildException(); + + int ItemIndex = CPythonPlayer::Instance().GetItemIndex(Cell); + return Py_BuildValue("i", ItemIndex); + } + default: + return Py_BuildException(); + + } +} + +PyObject * playerGetItemFlags(PyObject* poSelf, PyObject* poArgs) +{ + switch (PyTuple_Size(poArgs)) + { + case 1: + { + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + + DWORD flags = CPythonPlayer::Instance().GetItemFlags(TItemPos(INVENTORY, iSlotIndex)); + return Py_BuildValue("i", flags); + } + case 2: + { + TItemPos Cell; + if (!PyTuple_GetByte(poArgs, 0, &Cell.window_type)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 1, &Cell.cell)) + return Py_BuildException(); + + DWORD flags = CPythonPlayer::Instance().GetItemFlags(Cell); + return Py_BuildValue("i", flags); + } + default: + return Py_BuildException(); + } +} + + +PyObject * playerGetItemCount(PyObject* poSelf, PyObject* poArgs) +{ + switch (PyTuple_Size(poArgs)) + { + case 1: + { + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + + int ItemNum = CPythonPlayer::Instance().GetItemCount(TItemPos (INVENTORY, iSlotIndex)); + return Py_BuildValue("i", ItemNum); + } + case 2: + { + TItemPos Cell; + if (!PyTuple_GetByte(poArgs, 0, &Cell.window_type)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 1, &Cell.cell)) + return Py_BuildException(); + + int ItemNum = CPythonPlayer::Instance().GetItemCount(Cell); + + return Py_BuildValue("i", ItemNum); + } + default: + return Py_BuildException(); + + } +} + +PyObject * playerSetItemCount(PyObject* poSelf, PyObject* poArgs) +{ + switch (PyTuple_Size(poArgs)) + { + case 2: + { + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + + BYTE bCount; + if (!PyTuple_GetInteger(poArgs, 1, &bCount)) + return Py_BuildException(); + + if (0 == bCount) + return Py_BuildException(); + + CPythonPlayer::Instance().SetItemCount(TItemPos (INVENTORY, iSlotIndex), bCount); + return Py_BuildNone(); + } + case 3: + { + TItemPos Cell; + if (!PyTuple_GetByte(poArgs, 0, &Cell.window_type)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 1, &Cell.cell)) + return Py_BuildException(); + + BYTE bCount; + if (!PyTuple_GetInteger(poArgs, 2, &bCount)) + return Py_BuildException(); + + CPythonPlayer::Instance().SetItemCount(Cell, bCount); + + return Py_BuildNone(); + } + default: + return Py_BuildException(); + + } +} + +PyObject * playerGetItemCountByVnum(PyObject* poSelf, PyObject* poArgs) +{ + int ivnum; + if (!PyTuple_GetInteger(poArgs, 0, &ivnum)) + return Py_BuildException(); + + int ItemNum = CPythonPlayer::Instance().GetItemCountByVnum(ivnum); + return Py_BuildValue("i", ItemNum); +} + +PyObject * playerGetItemMetinSocket(PyObject* poSelf, PyObject* poArgs) +{ + TItemPos Cell; + int iMetinSocketIndex; + + switch (PyTuple_Size(poArgs)) + { + case 2: + if (!PyTuple_GetInteger(poArgs, 0, &Cell.cell)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 1, &iMetinSocketIndex)) + return Py_BuildException(); + + break; + case 3: + if (!PyTuple_GetByte(poArgs, 0, &Cell.window_type)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 1, &Cell.cell)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 2, &iMetinSocketIndex)) + return Py_BuildException(); + + break; + + default: + return Py_BuildException(); + + } + int nMetinSocketValue = CPythonPlayer::Instance().GetItemMetinSocket(Cell, iMetinSocketIndex); + return Py_BuildValue("i", nMetinSocketValue); +} + +PyObject * playerGetItemAttribute(PyObject* poSelf, PyObject* poArgs) +{ + TItemPos Cell; + //int iSlotPos; + int iAttributeSlotIndex; + switch (PyTuple_Size(poArgs)) + { + case 2: + if (!PyTuple_GetInteger(poArgs, 0, &Cell.cell)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 1, &iAttributeSlotIndex)) + return Py_BuildException(); + + break; + case 3: + if (!PyTuple_GetByte(poArgs, 0, &Cell.window_type)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 1, &Cell.cell)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 2, &iAttributeSlotIndex)) + return Py_BuildException(); + break; + default: + return Py_BuildException(); + } + BYTE byType; + short sValue; + CPythonPlayer::Instance().GetItemAttribute(Cell, iAttributeSlotIndex, &byType, &sValue); + + return Py_BuildValue("ii", byType, sValue); +} + +PyObject * playerGetItemLink(PyObject * poSelf, PyObject * poArgs) +{ + TItemPos Cell; + + switch (PyTuple_Size(poArgs)) + { + case 1: + if (!PyTuple_GetInteger(poArgs, 0, &Cell.cell)) + return Py_BuildException(); + break; + case 2: + if (!PyTuple_GetByte(poArgs, 0, &Cell.window_type)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 1, &Cell.cell)) + return Py_BuildException(); + break; + default: + return Py_BuildException(); + } + const TItemData * pPlayerItem = CPythonPlayer::Instance().GetItemData(Cell); + CItemData * pItemData = NULL; + char buf[1024]; + + if (pPlayerItem && CItemManager::Instance().GetItemDataPointer(pPlayerItem->vnum, &pItemData)) + { + char itemlink[256]; + int len; + bool isAttr = false; + + len = snprintf(itemlink, sizeof(itemlink), "item:%x:%x:%x:%x:%x", + pPlayerItem->vnum, pPlayerItem->flags, + pPlayerItem->alSockets[0], pPlayerItem->alSockets[1], pPlayerItem->alSockets[2]); + + for (int i = 0; i < ITEM_ATTRIBUTE_SLOT_MAX_NUM; ++i) + if (pPlayerItem->aAttr[i].bType != 0) + { + len += snprintf(itemlink + len, sizeof(itemlink) - len, ":%x:%d", + pPlayerItem->aAttr[i].bType, pPlayerItem->aAttr[i].sValue); + isAttr = true; + } + + + if( GetDefaultCodePage() == CP_ARABIC ) { + if (isAttr) + //"item:ȣ:÷:0:1:2" + snprintf(buf, sizeof(buf), " |h|r[%s]|cffffc700|H%s|h", pItemData->GetName(), itemlink); + else + snprintf(buf, sizeof(buf), " |h|r[%s]|cfff1e6c0|H%s|h", pItemData->GetName(), itemlink); + } else { + if (isAttr) + //"item:ȣ:÷:0:1:2" + snprintf(buf, sizeof(buf), "|cffffc700|H%s|h[%s]|h|r", itemlink, pItemData->GetName()); + else + snprintf(buf, sizeof(buf), "|cfff1e6c0|H%s|h[%s]|h|r", itemlink, pItemData->GetName()); + } + } + else + buf[0] = '\0'; + + return Py_BuildValue("s", buf); +} + +PyObject * playerGetISellItemPrice(PyObject * poSelf, PyObject * poArgs) +{ + TItemPos Cell; + + switch (PyTuple_Size(poArgs)) + { + case 1: + if (!PyTuple_GetInteger(poArgs, 0, &Cell.cell)) + return Py_BuildException(); + break; + case 2: + if (!PyTuple_GetByte(poArgs, 0, &Cell.window_type)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 1, &Cell.cell)) + return Py_BuildException(); + break; + default: + return Py_BuildException(); + } + CItemData * pItemData; + + if (!CItemManager::Instance().GetItemDataPointer(CPythonPlayer::Instance().GetItemIndex(Cell), &pItemData)) + return Py_BuildValue("i", 0); + + int iPrice; + + if (pItemData->IsFlag(CItemData::ITEM_FLAG_COUNT_PER_1GOLD)) + iPrice = CPythonPlayer::Instance().GetItemCount(Cell) / pItemData->GetISellItemPrice(); + else + iPrice = pItemData->GetISellItemPrice() * CPythonPlayer::Instance().GetItemCount(Cell); + + iPrice /= 5; + return Py_BuildValue("i", iPrice); +} + +PyObject * playerGetQuickPage(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildValue("i", CPythonPlayer::Instance().GetQuickPage()); +} + +PyObject * playerSetQuickPage(PyObject* poSelf, PyObject* poArgs) +{ + int iPageIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iPageIndex)) + return Py_BuildException(); + + CPythonPlayer::Instance().SetQuickPage(iPageIndex); + return Py_BuildNone(); +} + +PyObject * playerLocalQuickSlotIndexToGlobalQuickSlotIndex(PyObject* poSelf, PyObject* poArgs) +{ + int iLocalSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iLocalSlotIndex)) + return Py_BuildException(); + + CPythonPlayer& rkPlayer=CPythonPlayer::Instance(); + return Py_BuildValue("i", rkPlayer.LocalQuickSlotIndexToGlobalQuickSlotIndex(iLocalSlotIndex)); +} + + +PyObject * playerGetLocalQuickSlot(PyObject* poSelf, PyObject* poArgs) +{ + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + + DWORD dwWndType; + DWORD dwWndItemPos; + + CPythonPlayer& rkPlayer=CPythonPlayer::Instance(); + rkPlayer.GetLocalQuickSlotData(iSlotIndex, &dwWndType, &dwWndItemPos); + + return Py_BuildValue("ii", dwWndType, dwWndItemPos); +} + +PyObject * playerGetGlobalQuickSlot(PyObject* poSelf, PyObject* poArgs) +{ + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + + DWORD dwWndType; + DWORD dwWndItemPos; + + CPythonPlayer& rkPlayer=CPythonPlayer::Instance(); + rkPlayer.GetGlobalQuickSlotData(iSlotIndex, &dwWndType, &dwWndItemPos); + + return Py_BuildValue("ii", dwWndType, dwWndItemPos); +} + + +PyObject * playerRequestAddLocalQuickSlot(PyObject * poSelf, PyObject * poArgs) +{ + int nSlotIndex; + int nWndType; + int nWndItemPos; + + if (!PyTuple_GetInteger(poArgs, 0, &nSlotIndex)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 1, &nWndType)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 2, &nWndItemPos)) + return Py_BuildException(); + + CPythonPlayer& rkPlayer=CPythonPlayer::Instance(); + rkPlayer.RequestAddLocalQuickSlot(nSlotIndex, nWndType, nWndItemPos); + + return Py_BuildNone(); +} + +PyObject * playerRequestAddToEmptyLocalQuickSlot(PyObject* poSelf, PyObject* poArgs) +{ + int nWndType; + if (!PyTuple_GetInteger(poArgs, 0, &nWndType)) + return Py_BuildException(); + + int nWndItemPos; + if (!PyTuple_GetInteger(poArgs, 1, &nWndItemPos)) + return Py_BuildException(); + + CPythonPlayer& rkPlayer=CPythonPlayer::Instance(); + rkPlayer.RequestAddToEmptyLocalQuickSlot(nWndType, nWndItemPos); + + return Py_BuildNone(); +} + +PyObject * playerRequestDeleteGlobalQuickSlot(PyObject * poSelf, PyObject * poArgs) +{ + int nGlobalSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &nGlobalSlotIndex)) + return Py_BuildException(); + + CPythonPlayer& rkPlayer=CPythonPlayer::Instance(); + rkPlayer.RequestDeleteGlobalQuickSlot(nGlobalSlotIndex); + return Py_BuildNone(); +} + +PyObject * playerRequestMoveGlobalQuickSlotToLocalQuickSlot(PyObject * poSelf, PyObject * poArgs) +{ + int nGlobalSrcSlotIndex; + int nLocalDstSlotIndex; + + if (!PyTuple_GetInteger(poArgs, 0, &nGlobalSrcSlotIndex)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 1, &nLocalDstSlotIndex)) + return Py_BuildException(); + + CPythonPlayer& rkPlayer=CPythonPlayer::Instance(); + rkPlayer.RequestMoveGlobalQuickSlotToLocalQuickSlot(nGlobalSrcSlotIndex, nLocalDstSlotIndex); + return Py_BuildNone(); +} + +PyObject * playerRequestUseLocalQuickSlot(PyObject* poSelf, PyObject* poArgs) +{ + int iLocalPosition; + if (!PyTuple_GetInteger(poArgs, 0, &iLocalPosition)) + return Py_BuildException(); + + CPythonPlayer::Instance().RequestUseLocalQuickSlot(iLocalPosition); + + return Py_BuildNone(); +} + +PyObject * playerRemoveQuickSlotByValue(PyObject* poSelf, PyObject* poArgs) +{ + int iType; + if (!PyTuple_GetInteger(poArgs, 0, &iType)) + return Py_BuildException(); + + int iPosition; + if (!PyTuple_GetInteger(poArgs, 1, &iPosition)) + return Py_BuildException(); + + CPythonPlayer::Instance().RemoveQuickSlotByValue(iType, iPosition); + + return Py_BuildNone(); +} + +PyObject * playerisItem(PyObject* poSelf, PyObject* poArgs) +{ + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + + char Flag = CPythonPlayer::Instance().IsItem(TItemPos(INVENTORY, iSlotIndex)); + + return Py_BuildValue("i", Flag); +} + +#ifdef ENABLE_NEW_EQUIPMENT_SYSTEM +PyObject * playerIsBeltInventorySlot(PyObject* poSelf, PyObject* poArgs) +{ + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + + char Flag = CPythonPlayer::Instance().IsBeltInventorySlot(TItemPos(INVENTORY, iSlotIndex)); + + return Py_BuildValue("i", Flag); +} +#endif + +PyObject * playerIsEquipmentSlot(PyObject* poSelf, PyObject* poArgs) +{ + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + + if (iSlotIndex >= c_Equipment_Start) + if (iSlotIndex <= c_DragonSoul_Equip_End) + return Py_BuildValue("i", 1); + + return Py_BuildValue("i", 0); +} + +PyObject * playerIsDSEquipmentSlot(PyObject* poSelf, PyObject* poArgs) +{ + BYTE bWindowType; + if (!PyTuple_GetInteger(poArgs, 0, &bWindowType)) + return Py_BuildException(); + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iSlotIndex)) + return Py_BuildException(); + + if (INVENTORY == bWindowType) + if (iSlotIndex >= c_DragonSoul_Equip_Start) + if (iSlotIndex <= c_DragonSoul_Equip_End) + return Py_BuildValue("i", 1); + + return Py_BuildValue("i", 0); + +} + +PyObject * playerIsCostumeSlot(PyObject* poSelf, PyObject* poArgs) +{ + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + +#ifdef ENABLE_COSTUME_SYSTEM + if (iSlotIndex >= c_Costume_Slot_Start) + if (iSlotIndex <= c_Costume_Slot_End) + return Py_BuildValue("i", 1); +#endif + + return Py_BuildValue("i", 0); +} + +PyObject * playerIsOpenPrivateShop(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildValue("i", CPythonPlayer::Instance().IsOpenPrivateShop()); +} + +PyObject * playerIsValuableItem(PyObject* poSelf, PyObject* poArgs) +{ + TItemPos SlotIndex; + + switch (PyTuple_Size (poArgs)) + { + case 1: + if (!PyTuple_GetInteger(poArgs, 0, &SlotIndex.cell)) + return Py_BuildException(); + break; + case 2: + if (!PyTuple_GetInteger(poArgs, 0, &SlotIndex.window_type)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 0, &SlotIndex.cell)) + return Py_BuildException(); + break; + default: + return Py_BuildException(); + } + + DWORD dwItemIndex = CPythonPlayer::Instance().GetItemIndex(SlotIndex); + CItemManager::Instance().SelectItemData(dwItemIndex); + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pItemData) + return Py_BuildException("Can't find item data"); + + BOOL hasMetinSocket = FALSE; + BOOL isHighPrice = FALSE; + + for (int i = 0; i < METIN_SOCKET_COUNT; ++i) + if (CPythonPlayer::METIN_SOCKET_TYPE_NONE != CPythonPlayer::Instance().GetItemMetinSocket(SlotIndex, i)) + hasMetinSocket = TRUE; + + DWORD dwValue = pItemData->GetISellItemPrice(); + if (dwValue > 5000) + isHighPrice = TRUE; + + return Py_BuildValue("i", hasMetinSocket || isHighPrice); +} + +int GetItemGrade(const char * c_szItemName) +{ + std::string strName = c_szItemName; + if (strName.empty()) + return 0; + + char chGrade = strName[strName.length() - 1]; + if (chGrade < '0' || chGrade > '9') + chGrade = '0'; + + int iGrade = chGrade - '0'; + return iGrade; +} + +PyObject * playerGetItemGrade(PyObject* poSelf, PyObject* poArgs) +{ + TItemPos SlotIndex; + switch (PyTuple_Size(poArgs)) + { + case 1: + if (!PyTuple_GetInteger(poArgs, 0, &SlotIndex.cell)) + return Py_BuildException(); + break; + case 2: + if (!PyTuple_GetInteger(poArgs, 0, &SlotIndex.window_type)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 1, &SlotIndex.cell)) + return Py_BuildException(); + break; + default: + return Py_BuildException(); + } + + int iItemIndex = CPythonPlayer::Instance().GetItemIndex(SlotIndex); + CItemManager::Instance().SelectItemData(iItemIndex); + CItemData * pItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pItemData) + return Py_BuildException("Can't find item data"); + + return Py_BuildValue("i", GetItemGrade(pItemData->GetName())); +} + +#if defined(GAIDEN) +PyObject * playerGetItemUnbindTime(PyObject* poSelf, PyObject* poArgs) +{ + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + + return Py_BuildValue("i", (int) CPythonPlayer::instance().GetItemUnbindTime(iSlotIndex)); +} +#endif + +enum +{ + REFINE_SCROLL_TYPE_MAKE_SOCKET = 1, + REFINE_SCROLL_TYPE_UP_GRADE = 2, +}; + +enum +{ + REFINE_CANT, + REFINE_OK, + REFINE_ALREADY_MAX_SOCKET_COUNT, + REFINE_NEED_MORE_GOOD_SCROLL, + REFINE_CANT_MAKE_SOCKET_ITEM, + REFINE_NOT_NEXT_GRADE_ITEM, + REFINE_CANT_REFINE_METIN_TO_EQUIPMENT, + REFINE_CANT_REFINE_ROD, +}; + +PyObject * playerCanRefine(PyObject * poSelf, PyObject * poArgs) +{ + int iScrollItemIndex; + TItemPos TargetSlotIndex; + + switch (PyTuple_Size(poArgs)) + { + case 2: + if (!PyTuple_GetInteger(poArgs, 0, &iScrollItemIndex)) + return Py_BadArgument(); + if (!PyTuple_GetInteger(poArgs, 1, &TargetSlotIndex.cell)) + return Py_BadArgument(); + break; + case 3: + if (!PyTuple_GetInteger(poArgs, 0, &iScrollItemIndex)) + return Py_BadArgument(); + if (!PyTuple_GetInteger(poArgs, 1, &TargetSlotIndex.window_type)) + return Py_BadArgument(); + if (!PyTuple_GetInteger(poArgs, 2, &TargetSlotIndex.cell)) + return Py_BadArgument(); + break; + default: + return Py_BadArgument(); + } + + if (CPythonPlayer::Instance().IsEquipmentSlot(TargetSlotIndex)) + { + return Py_BuildValue("i", REFINE_CANT_REFINE_METIN_TO_EQUIPMENT); + } + + // Scroll + CItemManager::Instance().SelectItemData(iScrollItemIndex); + CItemData * pScrollItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pScrollItemData) + return Py_BuildValue("i", REFINE_CANT); + int iScrollType = pScrollItemData->GetType(); + int iScrollSubType = pScrollItemData->GetSubType(); + if (iScrollType != CItemData::ITEM_TYPE_USE) + return Py_BuildValue("i", REFINE_CANT); + if (iScrollSubType != CItemData::USE_TUNING) + return Py_BuildValue("i", REFINE_CANT); + + // Target Item + int iTargetItemIndex = CPythonPlayer::Instance().GetItemIndex(TargetSlotIndex); + CItemManager::Instance().SelectItemData(iTargetItemIndex); + CItemData * pTargetItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pTargetItemData) + return Py_BuildValue("i", REFINE_CANT); + int iTargetType = pTargetItemData->GetType(); + //int iTargetSubType = pTargetItemData->GetSubType(); + if (CItemData::ITEM_TYPE_ROD == iTargetType) + return Py_BuildValue("i", REFINE_CANT_REFINE_ROD); + + if (pTargetItemData->HasNextGrade()) + { + return Py_BuildValue("i", REFINE_OK); + } + else + { + return Py_BuildValue("i", REFINE_NOT_NEXT_GRADE_ITEM); + } + + return Py_BuildValue("i", REFINE_CANT); +} + +enum +{ + ATTACH_METIN_CANT, + ATTACH_METIN_OK, + ATTACH_METIN_NOT_MATCHABLE_ITEM, + ATTACH_METIN_NO_MATCHABLE_SOCKET, + ATTACH_METIN_NOT_EXIST_GOLD_SOCKET, + ATTACH_METIN_CANT_ATTACH_TO_EQUIPMENT, +}; + +PyObject * playerCanAttachMetin(PyObject* poSelf, PyObject* poArgs) +{ + int iMetinItemID; + TItemPos TargetSlotIndex; + + switch (PyTuple_Size(poArgs)) + { + case 2: + if (!PyTuple_GetInteger(poArgs, 0, &iMetinItemID)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 1, &TargetSlotIndex.cell)) + return Py_BuildException(); + break; + case 3: + if (!PyTuple_GetInteger(poArgs, 0, &iMetinItemID)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 1, &TargetSlotIndex.window_type)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 2, &TargetSlotIndex.cell)) + return Py_BuildException(); + break; + default: + return Py_BuildException(); + } + if (CPythonPlayer::Instance().IsEquipmentSlot(TargetSlotIndex)) + { + return Py_BuildValue("i", ATTACH_METIN_CANT_ATTACH_TO_EQUIPMENT); + } + + CItemData * pMetinItemData; + if (!CItemManager::Instance().GetItemDataPointer(iMetinItemID, &pMetinItemData)) + return Py_BuildException("can't find item data"); + + DWORD dwTargetItemIndex = CPythonPlayer::Instance().GetItemIndex(TargetSlotIndex); + CItemData * pTargetItemData; + if (!CItemManager::Instance().GetItemDataPointer(dwTargetItemIndex, &pTargetItemData)) + return Py_BuildException("can't find item data"); + + DWORD dwMetinWearFlags = pMetinItemData->GetWearFlags(); + DWORD dwTargetWearFlags = pTargetItemData->GetWearFlags(); + if (0 == (dwMetinWearFlags & dwTargetWearFlags)) + return Py_BuildValue("i", ATTACH_METIN_NOT_MATCHABLE_ITEM); + if (CItemData::ITEM_TYPE_ROD == pTargetItemData->GetType()) + return Py_BuildValue("i", ATTACH_METIN_CANT); + + BOOL bNotExistGoldSocket = FALSE; + + int iSubType = pMetinItemData->GetSubType(); + for (int i = 0; i < ITEM_SOCKET_SLOT_MAX_NUM; ++i) + { + DWORD dwSocketType = CPythonPlayer::Instance().GetItemMetinSocket(TargetSlotIndex, i); + if (CItemData::METIN_NORMAL == iSubType) + { + if (CPythonPlayer::METIN_SOCKET_TYPE_SILVER == dwSocketType || + CPythonPlayer::METIN_SOCKET_TYPE_GOLD == dwSocketType) + { + return Py_BuildValue("i", ATTACH_METIN_OK); + } + } + else if (CItemData::METIN_GOLD == iSubType) + { + if (CPythonPlayer::METIN_SOCKET_TYPE_GOLD == dwSocketType) + { + return Py_BuildValue("i", ATTACH_METIN_OK); + } + else if (CPythonPlayer::METIN_SOCKET_TYPE_SILVER == dwSocketType) + { + bNotExistGoldSocket = TRUE; + } + } + } + + if (bNotExistGoldSocket) + { + return Py_BuildValue("i", ATTACH_METIN_NOT_EXIST_GOLD_SOCKET); + } + + return Py_BuildValue("i", ATTACH_METIN_NO_MATCHABLE_SOCKET); +} + +enum +{ + DETACH_METIN_CANT, + DETACH_METIN_OK, +}; + +PyObject * playerCanDetach(PyObject * poSelf, PyObject * poArgs) +{ + int iScrollItemIndex; + TItemPos TargetSlotIndex; + switch (PyTuple_Size (poArgs)) + { + case 2: + if (!PyTuple_GetInteger(poArgs, 0, &iScrollItemIndex)) + return Py_BadArgument(); + if (!PyTuple_GetInteger(poArgs, 1, &TargetSlotIndex.cell)) + return Py_BadArgument(); + break; + case 3: + if (!PyTuple_GetInteger(poArgs, 0, &iScrollItemIndex)) + return Py_BadArgument(); + if (!PyTuple_GetInteger(poArgs, 1, &TargetSlotIndex.window_type)) + return Py_BadArgument(); + if (!PyTuple_GetInteger(poArgs, 2, &TargetSlotIndex.cell)) + return Py_BadArgument(); + break; + default: + return Py_BadArgument(); + } + + // Scroll + CItemManager::Instance().SelectItemData(iScrollItemIndex); + CItemData * pScrollItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pScrollItemData) + return Py_BuildException("Can't find item data"); + int iScrollType = pScrollItemData->GetType(); + int iScrollSubType = pScrollItemData->GetSubType(); + if (iScrollType != CItemData::ITEM_TYPE_USE) + return Py_BuildValue("i", DETACH_METIN_CANT); + if (iScrollSubType != CItemData::USE_DETACHMENT) + return Py_BuildValue("i", DETACH_METIN_CANT); + + // Target Item + int iTargetItemIndex = CPythonPlayer::Instance().GetItemIndex(TargetSlotIndex); + CItemManager::Instance().SelectItemData(iTargetItemIndex); + CItemData * pTargetItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pTargetItemData) + return Py_BuildException("Can't find item data"); + //int iTargetType = pTargetItemData->GetType(); + //int iTargetSubType = pTargetItemData->GetSubType(); + + if (pTargetItemData->IsFlag(CItemData::ITEM_FLAG_REFINEABLE)) + { + for (int iSlotCount = 0; iSlotCount < METIN_SOCKET_COUNT; ++iSlotCount) + if (CPythonPlayer::Instance().GetItemMetinSocket(TargetSlotIndex, iSlotCount) > 2) + { + return Py_BuildValue("i", DETACH_METIN_OK); + } + } + + return Py_BuildValue("i", DETACH_METIN_CANT); +} + +PyObject * playerCanUnlock(PyObject * poSelf, PyObject * poArgs) +{ + int iKeyItemIndex; + TItemPos TargetSlotIndex; + switch (PyTuple_Size(poArgs)) + { + case 2: + if (!PyTuple_GetInteger(poArgs, 0, &iKeyItemIndex)) + return Py_BadArgument(); + if (!PyTuple_GetInteger(poArgs, 1, &TargetSlotIndex.cell)) + return Py_BadArgument(); + break; + case 3: + if (!PyTuple_GetInteger(poArgs, 0, &iKeyItemIndex)) + return Py_BadArgument(); + if (!PyTuple_GetInteger(poArgs, 1, &TargetSlotIndex.window_type)) + return Py_BadArgument(); + if (!PyTuple_GetInteger(poArgs, 2, &TargetSlotIndex.cell)) + return Py_BadArgument(); + break; + default: + return Py_BadArgument(); + } + + // Key + CItemManager::Instance().SelectItemData(iKeyItemIndex); + CItemData * pKeyItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pKeyItemData) + return Py_BuildException("Can't find item data"); + int iKeyType = pKeyItemData->GetType(); + if (iKeyType != CItemData::ITEM_TYPE_TREASURE_KEY) + return Py_BuildValue("i", FALSE); + + // Target Item + int iTargetItemIndex = CPythonPlayer::Instance().GetItemIndex(TargetSlotIndex); + CItemManager::Instance().SelectItemData(iTargetItemIndex); + CItemData * pTargetItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pTargetItemData) + return Py_BuildException("Can't find item data"); + int iTargetType = pTargetItemData->GetType(); + if (iTargetType != CItemData::ITEM_TYPE_TREASURE_BOX) + return Py_BuildValue("i", FALSE); + + return Py_BuildValue("i", TRUE); +} + +PyObject * playerIsRefineGradeScroll(PyObject* poSelf, PyObject* poArgs) +{ + TItemPos ScrollSlotIndex; + switch (PyTuple_Size(poArgs)) + { + case 1: + if (!PyTuple_GetInteger(poArgs, 0, &ScrollSlotIndex.cell)) + return Py_BuildException(); + case 2: + if (!PyTuple_GetInteger(poArgs, 0, &ScrollSlotIndex.window_type)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 1, &ScrollSlotIndex.cell)) + return Py_BuildException(); + default: + return Py_BuildException(); + } + + int iScrollItemIndex = CPythonPlayer::Instance().GetItemIndex(ScrollSlotIndex); + CItemManager::Instance().SelectItemData(iScrollItemIndex); + CItemData * pScrollItemData = CItemManager::Instance().GetSelectedItemDataPointer(); + if (!pScrollItemData) + return Py_BuildException("Can't find item data"); + + return Py_BuildValue("i", REFINE_SCROLL_TYPE_UP_GRADE == pScrollItemData->GetValue(0)); +} + +PyObject * playerUpdate(PyObject* poSelf, PyObject* poArgs) +{ + CPythonPlayer::Instance().Update(); + return Py_BuildNone(); +} + +PyObject * playerRender(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildNone(); +} + +PyObject * playerClear(PyObject* poSelf, PyObject* poArgs) +{ + CPythonPlayer::Instance().Clear(); + return Py_BuildNone(); +} + +PyObject * playerClearTarget(PyObject* poSelf, PyObject* poArgs) +{ + CPythonPlayer::Instance().SetTarget(0); + return Py_BuildNone(); +} + +PyObject * playerSetTarget(PyObject* poSelf, PyObject* poArgs) +{ + int iVID; + if (!PyTuple_GetInteger(poArgs, 0, &iVID)) + return Py_BuildException(); + + CPythonPlayer::Instance().SetTarget(iVID); + return Py_BuildNone(); +} + +PyObject * playerOpenCharacterMenu(PyObject* poSelf, PyObject* poArgs) +{ + int iVID; + if (!PyTuple_GetInteger(poArgs, 0, &iVID)) + return Py_BuildException(); + + CPythonPlayer::Instance().OpenCharacterMenu(iVID); + return Py_BuildNone(); +} + +PyObject * playerIsPartyMember(PyObject* poSelf, PyObject* poArgs) +{ + int iVID; + if (!PyTuple_GetInteger(poArgs, 0, &iVID)) + return Py_BuildException(); + + return Py_BuildValue("i", CPythonPlayer::Instance().IsPartyMemberByVID(iVID)); +} + +PyObject * playerIsPartyLeader(PyObject* poSelf, PyObject* poArgs) +{ + int iVID; + if (!PyTuple_GetInteger(poArgs, 0, &iVID)) + return Py_BuildException(); + + DWORD dwPID; + if (!CPythonPlayer::Instance().PartyMemberVIDToPID(iVID, &dwPID)) + return Py_BuildValue("i", FALSE); + + CPythonPlayer::TPartyMemberInfo * pPartyMemberInfo; + if (!CPythonPlayer::Instance().GetPartyMemberPtr(dwPID, &pPartyMemberInfo)) + return Py_BuildValue("i", FALSE); + + return Py_BuildValue("i", CPythonPlayer::PARTY_ROLE_LEADER == pPartyMemberInfo->byState); +} + +PyObject * playerIsPartyLeaderByPID(PyObject* poSelf, PyObject* poArgs) +{ + int iPID; + if (!PyTuple_GetInteger(poArgs, 0, &iPID)) + return Py_BuildException(); + + CPythonPlayer::TPartyMemberInfo * pPartyMemberInfo; + if (!CPythonPlayer::Instance().GetPartyMemberPtr(iPID, &pPartyMemberInfo)) + return Py_BuildValue("i", FALSE); + + return Py_BuildValue("i", CPythonPlayer::PARTY_ROLE_LEADER == pPartyMemberInfo->byState); +} + +PyObject * playerGetPartyMemberHPPercentage(PyObject* poSelf, PyObject* poArgs) +{ + int iPID; + if (!PyTuple_GetInteger(poArgs, 0, &iPID)) + return Py_BuildException(); + + CPythonPlayer::TPartyMemberInfo * pPartyMemberInfo; + if (!CPythonPlayer::Instance().GetPartyMemberPtr(iPID, &pPartyMemberInfo)) + return Py_BuildValue("i", FALSE); + + return Py_BuildValue("i", pPartyMemberInfo->byHPPercentage); +} + +PyObject * playerGetPartyMemberState(PyObject* poSelf, PyObject* poArgs) +{ + int iPID; + if (!PyTuple_GetInteger(poArgs, 0, &iPID)) + return Py_BuildException(); + + CPythonPlayer::TPartyMemberInfo * pPartyMemberInfo; + if (!CPythonPlayer::Instance().GetPartyMemberPtr(iPID, &pPartyMemberInfo)) + return Py_BuildValue("i", FALSE); + + return Py_BuildValue("i", pPartyMemberInfo->byState); +} + +PyObject * playerGetPartyMemberAffects(PyObject* poSelf, PyObject* poArgs) +{ + int iPID; + if (!PyTuple_GetInteger(poArgs, 0, &iPID)) + return Py_BuildException(); + + CPythonPlayer::TPartyMemberInfo * pPartyMemberInfo; + if (!CPythonPlayer::Instance().GetPartyMemberPtr(iPID, &pPartyMemberInfo)) + return Py_BuildValue("i", FALSE); + + return Py_BuildValue("iiiiiii", pPartyMemberInfo->sAffects[0], + pPartyMemberInfo->sAffects[1], + pPartyMemberInfo->sAffects[2], + pPartyMemberInfo->sAffects[3], + pPartyMemberInfo->sAffects[4], + pPartyMemberInfo->sAffects[5], + pPartyMemberInfo->sAffects[6]); +} + +PyObject * playerRemovePartyMember(PyObject* poSelf, PyObject* poArgs) +{ + int iPID; + if (!PyTuple_GetInteger(poArgs, 0, &iPID)) + return Py_BuildException(); + + CPythonPlayer::Instance().RemovePartyMember(iPID); + return Py_BuildNone(); +} + +PyObject * playerExitParty(PyObject* poSelf, PyObject* poArgs) +{ + CPythonPlayer::Instance().ExitParty(); + return Py_BuildNone(); +} + +PyObject * playerGetPKMode(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildValue("i", CPythonPlayer::Instance().GetPKMode()); +} + +PyObject * playerHasMobilePhoneNumber(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildValue("i", CPythonPlayer::Instance().HasMobilePhoneNumber()); +} + +PyObject * playerSetWeaponAttackBonusFlag(PyObject* poSelf, PyObject* poArgs) +{ + int iFlag; + if (!PyTuple_GetInteger(poArgs, 0, &iFlag)) + return Py_BuildException(); + + return Py_BuildNone(); +} + +PyObject * playerToggleCoolTime(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildValue("i", CPythonPlayer::Instance().__ToggleCoolTime()); +} + +PyObject * playerToggleLevelLimit(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildValue("i", CPythonPlayer::Instance().__ToggleLevelLimit()); +} + +PyObject * playerGetTargetVID(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildValue("i", CPythonPlayer::Instance().GetTargetVID()); +} + +PyObject * playerRegisterEmotionIcon(PyObject* poSelf, PyObject* poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + char * szFileName; + if (!PyTuple_GetString(poArgs, 1, &szFileName)) + return Py_BuildException(); + + CGraphicImage * pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer(szFileName); + m_kMap_iEmotionIndex_pkIconImage.insert(std::make_pair(iIndex, pImage)); + + return Py_BuildNone(); +} + +PyObject * playerGetEmotionIconImage(PyObject* poSelf, PyObject* poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + + if (m_kMap_iEmotionIndex_pkIconImage.end() == m_kMap_iEmotionIndex_pkIconImage.find(iIndex)) + return Py_BuildValue("i", 0); + + return Py_BuildValue("i", m_kMap_iEmotionIndex_pkIconImage[iIndex]); +} + +PyObject * playerSetItemData(PyObject* poSelf, PyObject* poArgs) +{ + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 1, &iVirtualID)) + return Py_BuildException(); + + int iNum; + if (!PyTuple_GetInteger(poArgs, 2, &iNum)) + return Py_BuildException(); + + TItemData kItemInst; + ZeroMemory(&kItemInst, sizeof(kItemInst)); + kItemInst.vnum=iVirtualID; + kItemInst.count=iNum; + CPythonPlayer::Instance().SetItemData(TItemPos(INVENTORY, iSlotIndex), kItemInst); + return Py_BuildNone(); +} + +PyObject * playerSetItemMetinSocket(PyObject* poSelf, PyObject* poArgs) +{ + TItemPos ItemPos; + int iMetinSocketNumber; + int iNum; + + switch (PyTuple_Size(poArgs)) + { + case 3: + if (!PyTuple_GetInteger(poArgs, 0, &ItemPos.cell)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 1, &iMetinSocketNumber)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 2, &iNum)) + return Py_BuildException(); + + break; + case 4: + if (!PyTuple_GetInteger(poArgs, 0, &ItemPos.window_type)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 1, &ItemPos.cell)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 2, &iMetinSocketNumber)) + return Py_BuildException(); + if (!PyTuple_GetInteger(poArgs, 3, &iNum)) + return Py_BuildException(); + + break; + default: + return Py_BuildException(); + } + + CPythonPlayer::Instance().SetItemMetinSocket(ItemPos, iMetinSocketNumber, iNum); + return Py_BuildNone(); +} + +PyObject * playerSetItemAttribute(PyObject* poSelf, PyObject* poArgs) +{ + TItemPos ItemPos; + int iAttributeSlotIndex; + int iAttributeType; + int iAttributeValue; + + switch (PyTuple_Size(poArgs)) + { + case 4: + if (!PyTuple_GetInteger(poArgs, 0, &ItemPos.cell)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 1, &iAttributeSlotIndex)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 2, &iAttributeType)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 3, &iAttributeValue)) + return Py_BuildException(); + break; + case 5: + if (!PyTuple_GetInteger(poArgs, 0, &ItemPos.window_type)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 1, &ItemPos.cell)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 2, &iAttributeSlotIndex)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 3, &iAttributeType)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 4, &iAttributeValue)) + return Py_BuildException(); + break; + } + CPythonPlayer::Instance().SetItemAttribute(ItemPos, iAttributeSlotIndex, iAttributeType, iAttributeValue); + return Py_BuildNone(); +} + +PyObject * playerSetAutoPotionInfo(PyObject* poSelf, PyObject* poArgs) +{ + int potionType = 0; + if (!PyTuple_GetInteger(poArgs, 0, &potionType)) + return Py_BadArgument(); + + CPythonPlayer* player = CPythonPlayer::InstancePtr(); + + CPythonPlayer::SAutoPotionInfo& potionInfo = player->GetAutoPotionInfo(potionType); + + if (!PyTuple_GetBoolean(poArgs, 1, &potionInfo.bActivated)) + return Py_BadArgument(); + + if (!PyTuple_GetLong(poArgs, 2, &potionInfo.currentAmount)) + return Py_BadArgument(); + + if (!PyTuple_GetLong(poArgs, 3, &potionInfo.totalAmount)) + return Py_BadArgument(); + + if (!PyTuple_GetLong(poArgs, 4, &potionInfo.inventorySlotIndex)) + return Py_BadArgument(); + + return Py_BuildNone(); +} + +PyObject * playerGetAutoPotionInfo(PyObject* poSelf, PyObject* poArgs) +{ + CPythonPlayer* player = CPythonPlayer::InstancePtr(); + + int potionType = 0; + if (!PyTuple_GetInteger(poArgs, 0, &potionType)) + return Py_BadArgument(); + + CPythonPlayer::SAutoPotionInfo& potionInfo = player->GetAutoPotionInfo(potionType); + + return Py_BuildValue("biii", potionInfo.bActivated, int(potionInfo.currentAmount), int(potionInfo.totalAmount), int(potionInfo.inventorySlotIndex)); +} + +PyObject * playerSlotTypeToInvenType(PyObject* poSelf, PyObject* poArgs) +{ + int slotType = 0; + if (!PyTuple_GetInteger(poArgs, 0, &slotType)) + return Py_BadArgument(); + + return Py_BuildValue("i", SlotTypeToInvenType((BYTE)slotType)); +} + +#ifdef ENABLE_NEW_EQUIPMENT_SYSTEM +// ÷̾ Ʈ ? +PyObject * playerIsEquippingBelt(PyObject* poSelf, PyObject* poArgs) +{ + const CPythonPlayer* player = CPythonPlayer::InstancePtr(); + bool bEquipping = false; + + const TItemData* data = player->GetItemData(TItemPos(EQUIPMENT, c_Equipment_Belt)); + + if (NULL != data) + bEquipping = 0 < data->count; + + return Py_BuildValue("b", bEquipping); + +} + +// ˻Ϸ Ʈ κ丮 Cell ĭ? (밡 δ Ʈ ȭ ޶) +PyObject * playerIsAvailableBeltInventoryCell(PyObject* poSelf, PyObject* poArgs) +{ + const CPythonPlayer* player = CPythonPlayer::InstancePtr(); + const TItemData* pData = player->GetItemData(TItemPos(EQUIPMENT, c_Equipment_Belt)); + + if (NULL == pData || 0 == pData->count) + return Py_BuildValue("b", false); + + CItemManager::Instance().SelectItemData(pData->vnum); + CItemData * pItem = CItemManager::Instance().GetSelectedItemDataPointer(); + + long beltGrade = pItem->GetValue(0); + + int pos = 0; + if (!PyTuple_GetInteger(poArgs, 0, &pos)) + return Py_BadArgument(); + + //return Py_BuildValue("b", CBeltInventoryHelper::IsAvailableCell(pos - c_Belt_Inventory_Slot_Start, GetItemGrade(pItem->GetName()))); + return Py_BuildValue("b", CBeltInventoryHelper::IsAvailableCell(pos - c_Belt_Inventory_Slot_Start, beltGrade)); +} +#endif + + +// ȥ ȭ +PyObject* playerSendDragonSoulRefine(PyObject* poSelf, PyObject* poArgs) +{ + BYTE bSubHeader; + PyObject* pDic; + TItemPos RefineItemPoses[DS_REFINE_WINDOW_MAX_NUM]; + if (!PyTuple_GetByte(poArgs, 0, &bSubHeader)) + return Py_BuildException(); + switch (bSubHeader) + { + case DS_SUB_HEADER_CLOSE: + break; + case DS_SUB_HEADER_DO_UPGRADE: + case DS_SUB_HEADER_DO_IMPROVEMENT: + case DS_SUB_HEADER_DO_REFINE: + { + if (!PyTuple_GetObject(poArgs, 1, &pDic)) + return Py_BuildException(); + int pos = 0; + PyObject* key, *value; + int size = PyDict_Size(pDic); + + while (PyDict_Next(pDic, &pos, &key, &value)) + { + int i = PyInt_AsLong(key); + if (i > DS_REFINE_WINDOW_MAX_NUM) + return Py_BuildException(); + + if (!PyTuple_GetByte(value, 0, &RefineItemPoses[i].window_type) + || !PyTuple_GetInteger(value, 1, &RefineItemPoses[i].cell)) + { + return Py_BuildException(); + } + } + } + break; + } + + CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); + rns.SendDragonSoulRefinePacket(bSubHeader, RefineItemPoses); + + return Py_BuildNone(); +} +void initPlayer() +{ + static PyMethodDef s_methods[] = + { + { "GetAutoPotionInfo", playerGetAutoPotionInfo, METH_VARARGS }, + { "SetAutoPotionInfo", playerSetAutoPotionInfo, METH_VARARGS }, + + { "PickCloseItem", playerPickCloseItem, METH_VARARGS }, + { "SetGameWindow", playerSetGameWindow, METH_VARARGS }, + { "RegisterEffect", playerRegisterEffect, METH_VARARGS }, + { "RegisterCacheEffect", playerRegisterCacheEffect, METH_VARARGS }, + { "SetMouseState", playerSetMouseState, METH_VARARGS }, + { "SetMouseFunc", playerSetMouseFunc, METH_VARARGS }, + { "GetMouseFunc", playerGetMouseFunc, METH_VARARGS }, + { "SetMouseMiddleButtonState", playerSetMouseMiddleButtonState, METH_VARARGS }, + { "SetMainCharacterIndex", playerSetMainCharacterIndex, METH_VARARGS }, + { "GetMainCharacterIndex", playerGetMainCharacterIndex, METH_VARARGS }, + { "GetMainCharacterName", playerGetMainCharacterName, METH_VARARGS }, + { "GetMainCharacterPosition", playerGetMainCharacterPosition, METH_VARARGS }, + { "IsMainCharacterIndex", playerIsMainCharacterIndex, METH_VARARGS }, + { "CanAttackInstance", playerCanAttackInstance, METH_VARARGS }, + { "IsActingEmotion", playerIsActingEmotion, METH_VARARGS }, + { "IsPVPInstance", playerIsPVPInstance, METH_VARARGS }, + { "IsSameEmpire", playerIsSameEmpire, METH_VARARGS }, + { "IsChallengeInstance", playerIsChallengeInstance, METH_VARARGS }, + { "IsRevengeInstance", playerIsRevengeInstance, METH_VARARGS }, + { "IsCantFightInstance", playerIsCantFightInstance, METH_VARARGS }, + { "GetCharacterDistance", playerGetCharacterDistance, METH_VARARGS }, + { "IsInSafeArea", playerIsInSafeArea, METH_VARARGS }, + { "IsMountingHorse", playerIsMountingHorse, METH_VARARGS }, + { "IsObserverMode", playerIsObserverMode, METH_VARARGS }, + { "ActEmotion", playerActEmotion, METH_VARARGS }, + + { "ShowPlayer", playerShowPlayer, METH_VARARGS }, + { "HidePlayer", playerHidePlayer, METH_VARARGS }, + + { "ComboAttack", playerComboAttack, METH_VARARGS }, + + { "SetAutoCameraRotationSpeed", playerSetAutoCameraRotationSpeed, METH_VARARGS }, + { "SetAttackKeyState", playerSetAttackKeyState, METH_VARARGS }, + { "SetSingleDIKKeyState", playerSetSingleDIKKeyState, METH_VARARGS }, + { "EndKeyWalkingImmediately", playerEndKeyWalkingImmediately, METH_VARARGS }, + { "StartMouseWalking", playerStartMouseWalking, METH_VARARGS }, + { "EndMouseWalking", playerEndMouseWalking, METH_VARARGS }, + { "ResetCameraRotation", playerResetCameraRotation, METH_VARARGS }, + { "SetQuickCameraMode", playerSetQuickCameraMode, METH_VARARGS }, + + /////////////////////////////////////////////////////////////////////////////////////////// + + { "SetSkill", playerSetSkill, METH_VARARGS }, + { "GetSkillIndex", playerGetSkillIndex, METH_VARARGS }, + { "GetSkillSlotIndex", playerGetSkillSlotIndex, METH_VARARGS }, + { "GetSkillGrade", playerGetSkillGrade, METH_VARARGS }, + { "GetSkillLevel", playerGetSkillLevel, METH_VARARGS }, + { "GetSkillCurrentEfficientPercentage", playerGetSkillCurrentEfficientPercentage, METH_VARARGS }, + { "GetSkillNextEfficientPercentage", playerGetSkillNextEfficientPercentage, METH_VARARGS }, + { "ClickSkillSlot", playerClickSkillSlot, METH_VARARGS }, + { "ChangeCurrentSkillNumberOnly", playerChangeCurrentSkillNumberOnly, METH_VARARGS }, + { "ClearSkillDict", playerClearSkillDict, METH_VARARGS }, + + { "GetItemIndex", playerGetItemIndex, METH_VARARGS }, + { "GetItemFlags", playerGetItemFlags, METH_VARARGS }, + { "GetItemCount", playerGetItemCount, METH_VARARGS }, + { "GetItemCountByVnum", playerGetItemCountByVnum, METH_VARARGS }, + { "GetItemMetinSocket", playerGetItemMetinSocket, METH_VARARGS }, + { "GetItemAttribute", playerGetItemAttribute, METH_VARARGS }, +#if defined(GAIDEN) + { "GetItemUnbindTime", playerGetItemUnbindTime, METH_VARARGS }, +#endif + { "GetISellItemPrice", playerGetISellItemPrice, METH_VARARGS }, + { "MoveItem", playerMoveItem, METH_VARARGS }, + { "SendClickItemPacket", playerSendClickItemPacket, METH_VARARGS }, + + /////////////////////////////////////////////////////////////////////////////////////////// + + { "GetName", playerGetName, METH_VARARGS }, + { "GetJob", playerGetJob, METH_VARARGS }, + { "GetRace", playerGetRace, METH_VARARGS }, + { "GetPlayTime", playerGetPlayTime, METH_VARARGS }, + { "SetPlayTime", playerSetPlayTime, METH_VARARGS }, + + { "IsSkillCoolTime", playerIsSkillCoolTime, METH_VARARGS }, + { "GetSkillCoolTime", playerGetSkillCoolTime, METH_VARARGS }, + { "IsSkillActive", playerIsSkillActive, METH_VARARGS }, + { "UseGuildSkill", playerUseGuildSkill, METH_VARARGS }, + { "AffectIndexToSkillIndex", playerAffectIndexToSkillIndex, METH_VARARGS }, + { "GetEXP", playerGetEXP, METH_VARARGS }, + { "GetStatus", playerGetStatus, METH_VARARGS }, + { "SetStatus", playerSetStatus, METH_VARARGS }, + { "GetElk", playerGetElk, METH_VARARGS }, + { "GetMoney", playerGetElk, METH_VARARGS }, + { "GetGuildID", playerGetGuildID, METH_VARARGS }, + { "GetGuildName", playerGetGuildName, METH_VARARGS }, + { "GetAlignmentData", playerGetAlignmentData, METH_VARARGS }, + { "RequestAddLocalQuickSlot", playerRequestAddLocalQuickSlot, METH_VARARGS }, + { "RequestAddToEmptyLocalQuickSlot", playerRequestAddToEmptyLocalQuickSlot, METH_VARARGS }, + { "RequestDeleteGlobalQuickSlot", playerRequestDeleteGlobalQuickSlot, METH_VARARGS }, + { "RequestMoveGlobalQuickSlotToLocalQuickSlot", playerRequestMoveGlobalQuickSlotToLocalQuickSlot, METH_VARARGS }, + { "RequestUseLocalQuickSlot", playerRequestUseLocalQuickSlot, METH_VARARGS }, + { "LocalQuickSlotIndexToGlobalQuickSlotIndex", playerLocalQuickSlotIndexToGlobalQuickSlotIndex, METH_VARARGS }, + + { "GetQuickPage", playerGetQuickPage, METH_VARARGS }, + { "SetQuickPage", playerSetQuickPage, METH_VARARGS }, + { "GetLocalQuickSlot", playerGetLocalQuickSlot, METH_VARARGS }, + { "GetGlobalQuickSlot", playerGetGlobalQuickSlot, METH_VARARGS }, + { "RemoveQuickSlotByValue", playerRemoveQuickSlotByValue, METH_VARARGS }, + + { "isItem", playerisItem, METH_VARARGS }, + { "IsEquipmentSlot", playerIsEquipmentSlot, METH_VARARGS }, + { "IsDSEquipmentSlot", playerIsDSEquipmentSlot, METH_VARARGS }, + { "IsCostumeSlot", playerIsCostumeSlot, METH_VARARGS }, + { "IsValuableItem", playerIsValuableItem, METH_VARARGS }, + { "IsOpenPrivateShop", playerIsOpenPrivateShop, METH_VARARGS }, + +#ifdef ENABLE_NEW_EQUIPMENT_SYSTEM + { "IsBeltInventorySlot", playerIsBeltInventorySlot, METH_VARARGS }, + { "IsEquippingBelt", playerIsEquippingBelt, METH_VARARGS }, + { "IsAvailableBeltInventoryCell", playerIsAvailableBeltInventoryCell, METH_VARARGS }, +#endif + + // Refine + { "GetItemGrade", playerGetItemGrade, METH_VARARGS }, + { "CanRefine", playerCanRefine, METH_VARARGS }, + { "CanDetach", playerCanDetach, METH_VARARGS }, + { "CanUnlock", playerCanUnlock, METH_VARARGS }, + { "CanAttachMetin", playerCanAttachMetin, METH_VARARGS }, + { "IsRefineGradeScroll", playerIsRefineGradeScroll, METH_VARARGS }, + + { "ClearTarget", playerClearTarget, METH_VARARGS }, + { "SetTarget", playerSetTarget, METH_VARARGS }, + { "OpenCharacterMenu", playerOpenCharacterMenu, METH_VARARGS }, + + { "Update", playerUpdate, METH_VARARGS }, + { "Render", playerRender, METH_VARARGS }, + { "Clear", playerClear, METH_VARARGS }, + + // Party + { "IsPartyMember", playerIsPartyMember, METH_VARARGS }, + { "IsPartyLeader", playerIsPartyLeader, METH_VARARGS }, + { "IsPartyLeaderByPID", playerIsPartyLeaderByPID, METH_VARARGS }, + { "GetPartyMemberHPPercentage", playerGetPartyMemberHPPercentage, METH_VARARGS }, + { "GetPartyMemberState", playerGetPartyMemberState, METH_VARARGS }, + { "GetPartyMemberAffects", playerGetPartyMemberAffects, METH_VARARGS }, + { "RemovePartyMember", playerRemovePartyMember, METH_VARARGS }, + { "ExitParty", playerExitParty, METH_VARARGS }, + + // PK Mode + { "GetPKMode", playerGetPKMode, METH_VARARGS }, + + // Mobile + { "HasMobilePhoneNumber", playerHasMobilePhoneNumber, METH_VARARGS }, + + // Emotion + { "RegisterEmotionIcon", playerRegisterEmotionIcon, METH_VARARGS }, + { "GetEmotionIconImage", playerGetEmotionIconImage, METH_VARARGS }, + + // For System + { "SetWeaponAttackBonusFlag", playerSetWeaponAttackBonusFlag, METH_VARARGS }, + { "ToggleCoolTime", playerToggleCoolTime, METH_VARARGS }, + { "ToggleLevelLimit", playerToggleLevelLimit, METH_VARARGS }, + { "GetTargetVID", playerGetTargetVID, METH_VARARGS }, + + { "SetItemData", playerSetItemData, METH_VARARGS }, + { "SetItemMetinSocket", playerSetItemMetinSocket, METH_VARARGS }, + { "SetItemAttribute", playerSetItemAttribute, METH_VARARGS }, + { "SetItemCount", playerSetItemCount, METH_VARARGS }, + + { "GetItemLink", playerGetItemLink, METH_VARARGS }, + { "SlotTypeToInvenType", playerSlotTypeToInvenType, METH_VARARGS }, + { "SendDragonSoulRefine", playerSendDragonSoulRefine, METH_VARARGS }, + + { NULL, NULL, NULL }, + }; + + PyObject* poModule = Py_InitModule("player", s_methods); + PyModule_AddIntConstant(poModule, "LEVEL", POINT_LEVEL); + PyModule_AddIntConstant(poModule, "VOICE", POINT_VOICE); + PyModule_AddIntConstant(poModule, "EXP", POINT_EXP); + PyModule_AddIntConstant(poModule, "NEXT_EXP", POINT_NEXT_EXP); + PyModule_AddIntConstant(poModule, "HP", POINT_HP); + PyModule_AddIntConstant(poModule, "MAX_HP", POINT_MAX_HP); + PyModule_AddIntConstant(poModule, "SP", POINT_SP); + PyModule_AddIntConstant(poModule, "MAX_SP", POINT_MAX_SP); + PyModule_AddIntConstant(poModule, "STAMINA", POINT_STAMINA); + PyModule_AddIntConstant(poModule, "MAX_STAMINA", POINT_MAX_STAMINA); + PyModule_AddIntConstant(poModule, "ELK", POINT_GOLD); + PyModule_AddIntConstant(poModule, "ST", POINT_ST); + PyModule_AddIntConstant(poModule, "HT", POINT_HT); + PyModule_AddIntConstant(poModule, "DX", POINT_DX); + PyModule_AddIntConstant(poModule, "IQ", POINT_IQ); + PyModule_AddIntConstant(poModule, "ATT_POWER", POINT_ATT_POWER); + PyModule_AddIntConstant(poModule, "ATT_MIN", POINT_MIN_ATK); + PyModule_AddIntConstant(poModule, "ATT_MAX", POINT_MAX_ATK); + PyModule_AddIntConstant(poModule, "MIN_MAGIC_WEP", POINT_MIN_MAGIC_WEP); + PyModule_AddIntConstant(poModule, "MAX_MAGIC_WEP", POINT_MAX_MAGIC_WEP); + PyModule_AddIntConstant(poModule, "ATT_SPEED", POINT_ATT_SPEED); + PyModule_AddIntConstant(poModule, "ATT_BONUS", POINT_ATT_GRADE_BONUS); + PyModule_AddIntConstant(poModule, "EVADE_RATE", POINT_EVADE_RATE); + PyModule_AddIntConstant(poModule, "MOVING_SPEED", POINT_MOV_SPEED); + PyModule_AddIntConstant(poModule, "DEF_GRADE", POINT_DEF_GRADE); + PyModule_AddIntConstant(poModule, "DEF_BONUS", POINT_DEF_GRADE_BONUS); + PyModule_AddIntConstant(poModule, "CASTING_SPEED", POINT_CASTING_SPEED); + PyModule_AddIntConstant(poModule, "MAG_ATT", POINT_MAGIC_ATT_GRADE); + PyModule_AddIntConstant(poModule, "MAG_DEF", POINT_MAGIC_DEF_GRADE); + PyModule_AddIntConstant(poModule, "EMPIRE_POINT", POINT_EMPIRE_POINT); + PyModule_AddIntConstant(poModule, "STAT", POINT_STAT); + PyModule_AddIntConstant(poModule, "SKILL_PASSIVE", POINT_SUB_SKILL); + PyModule_AddIntConstant(poModule, "SKILL_SUPPORT", POINT_SUB_SKILL); + PyModule_AddIntConstant(poModule, "SKILL_ACTIVE", POINT_SKILL); + PyModule_AddIntConstant(poModule, "SKILL_HORSE", POINT_HORSE_SKILL); + PyModule_AddIntConstant(poModule, "PLAYTIME", POINT_PLAYTIME); + PyModule_AddIntConstant(poModule, "BOW_DISTANCE", POINT_BOW_DISTANCE); + PyModule_AddIntConstant(poModule, "HP_RECOVERY", POINT_HP_RECOVERY); + PyModule_AddIntConstant(poModule, "SP_RECOVERY", POINT_SP_RECOVERY); + PyModule_AddIntConstant(poModule, "ATTACKER_BONUS", POINT_PARTY_ATT_GRADE); + PyModule_AddIntConstant(poModule, "MAX_NUM", POINT_MAX_NUM); + //// + PyModule_AddIntConstant(poModule, "POINT_CRITICAL_PCT", POINT_CRITICAL_PCT); + PyModule_AddIntConstant(poModule, "POINT_PENETRATE_PCT", POINT_PENETRATE_PCT); + PyModule_AddIntConstant(poModule, "POINT_MALL_ATTBONUS", POINT_MALL_ATTBONUS); + PyModule_AddIntConstant(poModule, "POINT_MALL_DEFBONUS", POINT_MALL_DEFBONUS); + PyModule_AddIntConstant(poModule, "POINT_MALL_EXPBONUS", POINT_MALL_EXPBONUS); + PyModule_AddIntConstant(poModule, "POINT_MALL_ITEMBONUS", POINT_MALL_ITEMBONUS); + PyModule_AddIntConstant(poModule, "POINT_MALL_GOLDBONUS", POINT_MALL_GOLDBONUS); + PyModule_AddIntConstant(poModule, "POINT_MAX_HP_PCT", POINT_MAX_HP_PCT); + PyModule_AddIntConstant(poModule, "POINT_MAX_SP_PCT", POINT_MAX_SP_PCT); + + PyModule_AddIntConstant(poModule, "POINT_SKILL_DAMAGE_BONUS", POINT_SKILL_DAMAGE_BONUS); + PyModule_AddIntConstant(poModule, "POINT_NORMAL_HIT_DAMAGE_BONUS", POINT_NORMAL_HIT_DAMAGE_BONUS); + PyModule_AddIntConstant(poModule, "POINT_SKILL_DEFEND_BONUS", POINT_SKILL_DEFEND_BONUS); + PyModule_AddIntConstant(poModule, "POINT_NORMAL_HIT_DEFEND_BONUS", POINT_NORMAL_HIT_DEFEND_BONUS); + PyModule_AddIntConstant(poModule, "POINT_PC_BANG_EXP_BONUS", POINT_PC_BANG_EXP_BONUS); + PyModule_AddIntConstant(poModule, "POINT_PC_BANG_DROP_BONUS", POINT_PC_BANG_DROP_BONUS); + + PyModule_AddIntConstant(poModule, "ENERGY", POINT_ENERGY); + PyModule_AddIntConstant(poModule, "ENERGY_END_TIME", POINT_ENERGY_END_TIME); + + PyModule_AddIntConstant(poModule, "SKILL_GRADE_NORMAL", CPythonPlayer::SKILL_NORMAL); + PyModule_AddIntConstant(poModule, "SKILL_GRADE_MASTER", CPythonPlayer::SKILL_MASTER); + PyModule_AddIntConstant(poModule, "SKILL_GRADE_GRAND_MASTER", CPythonPlayer::SKILL_GRAND_MASTER); + PyModule_AddIntConstant(poModule, "SKILL_GRADE_PERFECT_MASTER", CPythonPlayer::SKILL_PERFECT_MASTER); + + PyModule_AddIntConstant(poModule, "CATEGORY_ACTIVE", CPythonPlayer::CATEGORY_ACTIVE); + PyModule_AddIntConstant(poModule, "CATEGORY_PASSIVE", CPythonPlayer::CATEGORY_PASSIVE); + + PyModule_AddIntConstant(poModule, "INVENTORY_PAGE_SIZE", c_Inventory_Page_Size); + PyModule_AddIntConstant(poModule, "INVENTORY_PAGE_COUNT", c_Inventory_Page_Count); + PyModule_AddIntConstant(poModule, "INVENTORY_SLOT_COUNT", c_Inventory_Count); + PyModule_AddIntConstant(poModule, "EQUIPMENT_SLOT_START", c_Equipment_Start); + PyModule_AddIntConstant(poModule, "EQUIPMENT_PAGE_COUNT", c_Equipment_Count); + +#ifdef ENABLE_NEW_EQUIPMENT_SYSTEM + PyModule_AddIntConstant(poModule, "NEW_EQUIPMENT_SLOT_START", c_New_Equipment_Start); + PyModule_AddIntConstant(poModule, "NEW_EQUIPMENT_SLOT_COUNT", c_New_Equipment_Count); +#endif + + PyModule_AddIntConstant(poModule, "MBF_SKILL", CPythonPlayer::MBF_SKILL); + PyModule_AddIntConstant(poModule, "MBF_ATTACK", CPythonPlayer::MBF_ATTACK); + PyModule_AddIntConstant(poModule, "MBF_CAMERA", CPythonPlayer::MBF_CAMERA); + PyModule_AddIntConstant(poModule, "MBF_SMART", CPythonPlayer::MBF_SMART); + PyModule_AddIntConstant(poModule, "MBF_MOVE", CPythonPlayer::MBF_MOVE); + PyModule_AddIntConstant(poModule, "MBF_AUTO", CPythonPlayer::MBF_AUTO); + PyModule_AddIntConstant(poModule, "MBS_PRESS", CPythonPlayer::MBS_PRESS); + PyModule_AddIntConstant(poModule, "MBS_CLICK", CPythonPlayer::MBS_CLICK); + PyModule_AddIntConstant(poModule, "MBT_RIGHT", CPythonPlayer::MBT_RIGHT); + PyModule_AddIntConstant(poModule, "MBT_LEFT", CPythonPlayer::MBT_LEFT); + + // Public code with server + PyModule_AddIntConstant(poModule, "SLOT_TYPE_NONE", SLOT_TYPE_NONE); + PyModule_AddIntConstant(poModule, "SLOT_TYPE_INVENTORY", SLOT_TYPE_INVENTORY); + PyModule_AddIntConstant(poModule, "SLOT_TYPE_SKILL", SLOT_TYPE_SKILL); + // Special indecies for client + PyModule_AddIntConstant(poModule, "SLOT_TYPE_SHOP", SLOT_TYPE_SHOP); + PyModule_AddIntConstant(poModule, "SLOT_TYPE_EXCHANGE_OWNER", SLOT_TYPE_EXCHANGE_OWNER); + PyModule_AddIntConstant(poModule, "SLOT_TYPE_EXCHANGE_TARGET", SLOT_TYPE_EXCHANGE_TARGET); + PyModule_AddIntConstant(poModule, "SLOT_TYPE_QUICK_SLOT", SLOT_TYPE_QUICK_SLOT); + PyModule_AddIntConstant(poModule, "SLOT_TYPE_SAFEBOX", SLOT_TYPE_SAFEBOX); + PyModule_AddIntConstant(poModule, "SLOT_TYPE_PRIVATE_SHOP", SLOT_TYPE_PRIVATE_SHOP); + PyModule_AddIntConstant(poModule, "SLOT_TYPE_MALL", SLOT_TYPE_MALL); + PyModule_AddIntConstant(poModule, "SLOT_TYPE_EMOTION", SLOT_TYPE_EMOTION); + PyModule_AddIntConstant(poModule, "SLOT_TYPE_DRAGON_SOUL_INVENTORY", SLOT_TYPE_DRAGON_SOUL_INVENTORY); + + PyModule_AddIntConstant(poModule, "RESERVED_WINDOW", RESERVED_WINDOW); + PyModule_AddIntConstant(poModule, "INVENTORY", INVENTORY); + PyModule_AddIntConstant(poModule, "EQUIPMENT", EQUIPMENT); + PyModule_AddIntConstant(poModule, "SAFEBOX", SAFEBOX); + PyModule_AddIntConstant(poModule, "MALL", MALL); + PyModule_AddIntConstant(poModule, "DRAGON_SOUL_INVENTORY", DRAGON_SOUL_INVENTORY); + PyModule_AddIntConstant(poModule, "GROUND", GROUND); + + PyModule_AddIntConstant(poModule, "ITEM_MONEY", -1); + + PyModule_AddIntConstant(poModule, "SKILL_SLOT_COUNT", SKILL_MAX_NUM); + + PyModule_AddIntConstant(poModule, "EFFECT_PICK", CPythonPlayer::EFFECT_PICK); + + PyModule_AddIntConstant(poModule, "METIN_SOCKET_TYPE_NONE", CPythonPlayer::METIN_SOCKET_TYPE_NONE); + PyModule_AddIntConstant(poModule, "METIN_SOCKET_TYPE_SILVER", CPythonPlayer::METIN_SOCKET_TYPE_SILVER); + PyModule_AddIntConstant(poModule, "METIN_SOCKET_TYPE_GOLD", CPythonPlayer::METIN_SOCKET_TYPE_GOLD); + PyModule_AddIntConstant(poModule, "METIN_SOCKET_MAX_NUM", ITEM_SOCKET_SLOT_MAX_NUM); + PyModule_AddIntConstant(poModule, "ATTRIBUTE_SLOT_MAX_NUM", ITEM_ATTRIBUTE_SLOT_MAX_NUM); + + PyModule_AddIntConstant(poModule, "REFINE_CANT", REFINE_CANT); + PyModule_AddIntConstant(poModule, "REFINE_OK", REFINE_OK); + PyModule_AddIntConstant(poModule, "REFINE_ALREADY_MAX_SOCKET_COUNT", REFINE_ALREADY_MAX_SOCKET_COUNT); + PyModule_AddIntConstant(poModule, "REFINE_NEED_MORE_GOOD_SCROLL", REFINE_NEED_MORE_GOOD_SCROLL); + PyModule_AddIntConstant(poModule, "REFINE_CANT_MAKE_SOCKET_ITEM", REFINE_CANT_MAKE_SOCKET_ITEM); + PyModule_AddIntConstant(poModule, "REFINE_NOT_NEXT_GRADE_ITEM", REFINE_NOT_NEXT_GRADE_ITEM); + PyModule_AddIntConstant(poModule, "REFINE_CANT_REFINE_METIN_TO_EQUIPMENT", REFINE_CANT_REFINE_METIN_TO_EQUIPMENT); + PyModule_AddIntConstant(poModule, "REFINE_CANT_REFINE_ROD", REFINE_CANT_REFINE_ROD); + PyModule_AddIntConstant(poModule, "ATTACH_METIN_CANT", ATTACH_METIN_CANT); + PyModule_AddIntConstant(poModule, "ATTACH_METIN_OK", ATTACH_METIN_OK); + PyModule_AddIntConstant(poModule, "ATTACH_METIN_NOT_MATCHABLE_ITEM", ATTACH_METIN_NOT_MATCHABLE_ITEM); + PyModule_AddIntConstant(poModule, "ATTACH_METIN_NO_MATCHABLE_SOCKET", ATTACH_METIN_NO_MATCHABLE_SOCKET); + PyModule_AddIntConstant(poModule, "ATTACH_METIN_NOT_EXIST_GOLD_SOCKET", ATTACH_METIN_NOT_EXIST_GOLD_SOCKET); + PyModule_AddIntConstant(poModule, "ATTACH_METIN_CANT_ATTACH_TO_EQUIPMENT", ATTACH_METIN_CANT_ATTACH_TO_EQUIPMENT); + PyModule_AddIntConstant(poModule, "DETACH_METIN_CANT", DETACH_METIN_CANT); + PyModule_AddIntConstant(poModule, "DETACH_METIN_OK", DETACH_METIN_OK); + + // Party + PyModule_AddIntConstant(poModule, "PARTY_STATE_NORMAL", CPythonPlayer::PARTY_ROLE_NORMAL); + PyModule_AddIntConstant(poModule, "PARTY_STATE_LEADER", CPythonPlayer::PARTY_ROLE_LEADER); + PyModule_AddIntConstant(poModule, "PARTY_STATE_ATTACKER", CPythonPlayer::PARTY_ROLE_ATTACKER); + PyModule_AddIntConstant(poModule, "PARTY_STATE_TANKER", CPythonPlayer::PARTY_ROLE_TANKER); + PyModule_AddIntConstant(poModule, "PARTY_STATE_BUFFER", CPythonPlayer::PARTY_ROLE_BUFFER); + PyModule_AddIntConstant(poModule, "PARTY_STATE_SKILL_MASTER", CPythonPlayer::PARTY_ROLE_SKILL_MASTER); + PyModule_AddIntConstant(poModule, "PARTY_STATE_BERSERKER", CPythonPlayer::PARTY_ROLE_BERSERKER); + PyModule_AddIntConstant(poModule, "PARTY_STATE_DEFENDER", CPythonPlayer::PARTY_ROLE_DEFENDER); + PyModule_AddIntConstant(poModule, "PARTY_STATE_MAX_NUM", CPythonPlayer::PARTY_ROLE_MAX_NUM); + + // Skill Index + PyModule_AddIntConstant(poModule, "SKILL_INDEX_TONGSOL", c_iSkillIndex_Tongsol); + PyModule_AddIntConstant(poModule, "SKILL_INDEX_FISHING", c_iSkillIndex_Fishing); + PyModule_AddIntConstant(poModule, "SKILL_INDEX_MINING", c_iSkillIndex_Mining); + PyModule_AddIntConstant(poModule, "SKILL_INDEX_MAKING", c_iSkillIndex_Making); + PyModule_AddIntConstant(poModule, "SKILL_INDEX_COMBO", c_iSkillIndex_Combo); + PyModule_AddIntConstant(poModule, "SKILL_INDEX_LANGUAGE1", c_iSkillIndex_Language1); + PyModule_AddIntConstant(poModule, "SKILL_INDEX_LANGUAGE2", c_iSkillIndex_Language2); + PyModule_AddIntConstant(poModule, "SKILL_INDEX_LANGUAGE3", c_iSkillIndex_Language3); + PyModule_AddIntConstant(poModule, "SKILL_INDEX_POLYMORPH", c_iSkillIndex_Polymorph); + PyModule_AddIntConstant(poModule, "SKILL_INDEX_RIDING", c_iSkillIndex_Riding); + PyModule_AddIntConstant(poModule, "SKILL_INDEX_SUMMON", c_iSkillIndex_Summon); + + // PK Mode + PyModule_AddIntConstant(poModule, "PK_MODE_PEACE", PK_MODE_PEACE); + PyModule_AddIntConstant(poModule, "PK_MODE_REVENGE", PK_MODE_REVENGE); + PyModule_AddIntConstant(poModule, "PK_MODE_FREE", PK_MODE_FREE); + PyModule_AddIntConstant(poModule, "PK_MODE_PROTECT", PK_MODE_PROTECT); + PyModule_AddIntConstant(poModule, "PK_MODE_GUILD", PK_MODE_GUILD); + PyModule_AddIntConstant(poModule, "PK_MODE_MAX_NUM", PK_MODE_MAX_NUM); + + // Block Mode + PyModule_AddIntConstant(poModule, "BLOCK_EXCHANGE", BLOCK_EXCHANGE); + PyModule_AddIntConstant(poModule, "BLOCK_PARTY", BLOCK_PARTY_INVITE); + PyModule_AddIntConstant(poModule, "BLOCK_GUILD", BLOCK_GUILD_INVITE); + PyModule_AddIntConstant(poModule, "BLOCK_WHISPER", BLOCK_WHISPER); + PyModule_AddIntConstant(poModule, "BLOCK_FRIEND", BLOCK_MESSENGER_INVITE); + PyModule_AddIntConstant(poModule, "BLOCK_PARTY_REQUEST", BLOCK_PARTY_REQUEST); + + // Party + PyModule_AddIntConstant(poModule, "PARTY_EXP_NON_DISTRIBUTION", PARTY_EXP_DISTRIBUTION_NON_PARITY); + PyModule_AddIntConstant(poModule, "PARTY_EXP_DISTRIBUTION_PARITY", PARTY_EXP_DISTRIBUTION_PARITY); + + // Emotion + PyModule_AddIntConstant(poModule, "EMOTION_CLAP", EMOTION_CLAP); + PyModule_AddIntConstant(poModule, "EMOTION_CHEERS_1", EMOTION_CHEERS_1); + PyModule_AddIntConstant(poModule, "EMOTION_CHEERS_2", EMOTION_CHEERS_2); + PyModule_AddIntConstant(poModule, "EMOTION_DANCE_1", EMOTION_DANCE_1); + PyModule_AddIntConstant(poModule, "EMOTION_DANCE_2", EMOTION_DANCE_2); + PyModule_AddIntConstant(poModule, "EMOTION_DANCE_3", EMOTION_DANCE_3); + PyModule_AddIntConstant(poModule, "EMOTION_DANCE_4", EMOTION_DANCE_4); + PyModule_AddIntConstant(poModule, "EMOTION_DANCE_5", EMOTION_DANCE_5); + PyModule_AddIntConstant(poModule, "EMOTION_DANCE_6", EMOTION_DANCE_6); // PSY Ÿ + PyModule_AddIntConstant(poModule, "EMOTION_CONGRATULATION", EMOTION_CONGRATULATION); + PyModule_AddIntConstant(poModule, "EMOTION_FORGIVE", EMOTION_FORGIVE); + PyModule_AddIntConstant(poModule, "EMOTION_ANGRY", EMOTION_ANGRY); + PyModule_AddIntConstant(poModule, "EMOTION_ATTRACTIVE", EMOTION_ATTRACTIVE); + PyModule_AddIntConstant(poModule, "EMOTION_SAD", EMOTION_SAD); + PyModule_AddIntConstant(poModule, "EMOTION_SHY", EMOTION_SHY); + PyModule_AddIntConstant(poModule, "EMOTION_CHEERUP", EMOTION_CHEERUP); + PyModule_AddIntConstant(poModule, "EMOTION_BANTER", EMOTION_BANTER); + PyModule_AddIntConstant(poModule, "EMOTION_JOY", EMOTION_JOY); + + PyModule_AddIntConstant(poModule, "EMOTION_KISS", EMOTION_KISS); + PyModule_AddIntConstant(poModule, "EMOTION_FRENCH_KISS", EMOTION_FRENCH_KISS); + PyModule_AddIntConstant(poModule, "EMOTION_SLAP", EMOTION_SLAP); + + //// ڵ Ÿ + PyModule_AddIntConstant(poModule, "AUTO_POTION_TYPE_HP", CPythonPlayer::AUTO_POTION_TYPE_HP); + PyModule_AddIntConstant(poModule, "AUTO_POTION_TYPE_SP", CPythonPlayer::AUTO_POTION_TYPE_SP); + + // ȥ + PyModule_AddIntConstant(poModule, "DRAGON_SOUL_PAGE_SIZE", c_DragonSoul_Inventory_Box_Size); + PyModule_AddIntConstant(poModule, "DRAGON_SOUL_PAGE_COUNT", DRAGON_SOUL_GRADE_MAX); + PyModule_AddIntConstant(poModule, "DRAGON_SOUL_SLOT_COUNT", c_DragonSoul_Inventory_Count); + PyModule_AddIntConstant(poModule, "DRAGON_SOUL_EQUIPMENT_SLOT_START", c_DragonSoul_Equip_Start); + PyModule_AddIntConstant(poModule, "DRAGON_SOUL_EQUIPMENT_PAGE_COUNT", DS_DECK_MAX_NUM); + PyModule_AddIntConstant(poModule, "DRAGON_SOUL_EQUIPMENT_FIRST_SIZE", c_DragonSoul_Equip_Slot_Max); + + // ȥ â + PyModule_AddIntConstant(poModule, "DRAGON_SOUL_REFINE_CLOSE", DS_SUB_HEADER_CLOSE); + PyModule_AddIntConstant(poModule, "DS_SUB_HEADER_DO_UPGRADE", DS_SUB_HEADER_DO_UPGRADE); + PyModule_AddIntConstant(poModule, "DS_SUB_HEADER_DO_IMPROVEMENT", DS_SUB_HEADER_DO_IMPROVEMENT); + PyModule_AddIntConstant(poModule, "DS_SUB_HEADER_DO_REFINE", DS_SUB_HEADER_DO_REFINE); + +} diff --git a/source/UserInterface/PythonPlayerSkill.cpp b/source/UserInterface/PythonPlayerSkill.cpp new file mode 100644 index 0000000..5e82696 --- /dev/null +++ b/source/UserInterface/PythonPlayerSkill.cpp @@ -0,0 +1,991 @@ +#include "StdAfx.h" +#include "PythonPlayer.h" +#include "PythonTextTail.h" +#include "PythonNetworkStream.h" +#include "InstanceBase.h" +#include "PythonChat.h" +#include "PythonGuild.h" +#include "../GameLib/ItemManager.h" + +void CPythonPlayer::ClearAffects() +{ + PyCallClassMemberFunc(m_ppyGameWindow, "ClearAffects", Py_BuildValue("()")); +} + +void CPythonPlayer::SetAffect(UINT uAffect) +{ + PyCallClassMemberFunc(m_ppyGameWindow, "SetAffect", Py_BuildValue("(i)", uAffect)); + + ///// + + DWORD dwSkillIndex; + if (!AffectIndexToSkillIndex(uAffect, &dwSkillIndex)) + return; + + CPythonSkill::TSkillData * pSkillData; + if (!CPythonSkill::Instance().GetSkillData(dwSkillIndex, &pSkillData)) + return; + + if (!pSkillData->IsToggleSkill()) + return; + + DWORD dwSkillSlotIndex; + if (!GetSkillSlotIndex(dwSkillIndex, &dwSkillSlotIndex)) + return; + + __ActivateSkillSlot(dwSkillSlotIndex); +} + +void CPythonPlayer::ResetAffect(UINT uAffect) +{ + // 2004.07.17.myevan.ų ƴ Ʈ + PyCallClassMemberFunc(m_ppyGameWindow, "ResetAffect", Py_BuildValue("(i)", uAffect)); + + DWORD dwSkillIndex; + if (!AffectIndexToSkillIndex(uAffect, &dwSkillIndex)) + return; + + CPythonSkill::TSkillData * pSkillData; + if (!CPythonSkill::Instance().GetSkillData(dwSkillIndex, &pSkillData)) + return; + + if (!pSkillData->IsToggleSkill()) + return; + + DWORD dwSkillSlotIndex; + if (!GetSkillSlotIndex(dwSkillIndex, &dwSkillSlotIndex)) + return; + + __DeactivateSkillSlot(dwSkillSlotIndex); +} + +bool CPythonPlayer::FindSkillSlotIndexBySkillIndex(DWORD dwSkillIndex, DWORD * pdwSkillSlotIndex) +{ + for (int i = 0; i < SKILL_MAX_NUM; ++i) + { + TSkillInstance & rkSkillInst = m_playerStatus.aSkill[i]; + if (dwSkillIndex == rkSkillInst.dwIndex) + { + *pdwSkillSlotIndex = i; + return true; + } + } + + return false; +} + +void CPythonPlayer::ChangeCurrentSkillNumberOnly(DWORD dwSlotIndex) +{ + if (dwSlotIndex >= SKILL_MAX_NUM) + return; + + TSkillInstance & rkSkillInst = m_playerStatus.aSkill[dwSlotIndex]; + + CPythonSkill::TSkillData * pSkillData; + if (!CPythonSkill::Instance().GetSkillData(rkSkillInst.dwIndex, &pSkillData)) + return; + + if (!pSkillData->IsCanUseSkill()) + return; + + if (!__IsRightButtonSkillMode()) + { + if (!__IsTarget()) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "NEED_TARGET")); + return; + } + + ClickSkillSlot(dwSlotIndex); + } + else + { + m_dwcurSkillSlotIndex = dwSlotIndex; + PyCallClassMemberFunc(m_ppyGameWindow, "ChangeCurrentSkill", Py_BuildValue("(i)", dwSlotIndex)); + } +} + +void CPythonPlayer::ClickSkillSlot(DWORD dwSlotIndex) +{ + if (dwSlotIndex >= SKILL_MAX_NUM) + return; + + TSkillInstance & rkSkillInst = m_playerStatus.aSkill[dwSlotIndex]; + + CPythonSkill::TSkillData * pSkillData; + if (!CPythonSkill::Instance().GetSkillData(rkSkillInst.dwIndex, &pSkillData)) + return; + + if (CPythonSkill::SKILL_TYPE_GUILD == pSkillData->byType) + { + UseGuildSkill(dwSlotIndex); + return; + } + + if (!pSkillData->IsCanUseSkill()) + return; + + if (pSkillData->IsStandingSkill()) + { + if (pSkillData->IsToggleSkill()) + { + if (IsSkillActive(dwSlotIndex)) + { + CInstanceBase * pkInstMain = NEW_GetMainActorPtr(); + if (!pkInstMain) + return; + if (pkInstMain->IsUsingSkill()) + return; + + CPythonNetworkStream::Instance().SendUseSkillPacket(rkSkillInst.dwIndex); + return; + } + } + + __UseSkill(dwSlotIndex); + return; + } + + if (m_dwcurSkillSlotIndex == dwSlotIndex) + { + __UseSkill(m_dwcurSkillSlotIndex); + return; + } + + if (!__IsRightButtonSkillMode()) + { + __UseSkill(dwSlotIndex); + } + else + { + m_dwcurSkillSlotIndex = dwSlotIndex; + PyCallClassMemberFunc(m_ppyGameWindow, "ChangeCurrentSkill", Py_BuildValue("(i)", dwSlotIndex)); + } +} + +bool CPythonPlayer::__CheckSkillUsable(DWORD dwSlotIndex) +{ + CInstanceBase * pkInstMain = NEW_GetMainActorPtr(); + if (!pkInstMain) + return false; + + if (dwSlotIndex >= SKILL_MAX_NUM) + return false; + + TSkillInstance & rkSkillInst = m_playerStatus.aSkill[dwSlotIndex]; + + CPythonSkill::TSkillData * pSkillData; + if (!CPythonSkill::Instance().GetSkillData(rkSkillInst.dwIndex, &pSkillData)) + return false; + + if (pkInstMain->IsMountingHorse()) + { + if (!pSkillData->IsHorseSkill()) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "NOT_HORSE_SKILL")); + return false; + } + } + + if (pSkillData->IsHorseSkill()) + { + if (!pkInstMain->IsMountingHorse()) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "HAVE_TO_RIDE")); + return false; + } + } + + // 2004.07.26.levites - 뿡 ϵ + // NOTE : ų 뿡 մϴ - [levites] + if (pSkillData->IsAttackSkill()) + { + if (pkInstMain->IsInSafe()) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "IN_SAFE")); + + return false; + } + } + + // NOTE : нú ų մϴ - [levites] + if (!pSkillData->IsCanUseSkill()) + return false; +// if (CPythonSkill::SKILL_TYPE_PASSIVE == pSkillData->byType) +// return false; + + // NOTE : [Only Assassin] ִ üũ մϴ. + if (pSkillData->IsNeedEmptyBottle()) + { + if (!__HasItem(27995)) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "NEED_EMPTY_BOTTLE")); + return false; + } + } + + // NOTE : [Only Assassin] ִ üũ մϴ. + if (pSkillData->IsNeedPoisonBottle()) + { + if (!__HasItem(27996)) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "NEED_POISON_BOTTLE")); + return false; + } + } + + // NOTE : ϶ ų մϴ. + if (pkInstMain->IsFishingMode()) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "REMOVE_FISHING_ROD")); + return false; + } + + // NOTE : üũ + if (m_sysIsLevelLimit) + { + if (rkSkillInst.iLevel <= 0) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "NOT_YET_LEARN")); + return false; + } + } + + // NOTE : ִ üũ + if (!pSkillData->CanUseWeaponType(pkInstMain->GetWeaponType())) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "NOT_MATCHABLE_WEAPON")); + return false; + } + + if (!pSkillData->IsHorseSkill()) // HORSE ų ߿ ȭ ʴ ų ֱ + { + if (__CheckShortArrow(rkSkillInst, *pSkillData)) + return false; + + // NOTE : Ȱ ʿ ȭ üũ + if (pSkillData->IsNeedBow()) + { + if (!__HasEnoughArrow()) + return false; + } + } + + if (__CheckDashAffect(*pkInstMain)) + { + if (!pSkillData->IsChargeSkill()) + { + if (__CheckRestSkillCoolTime(dwSlotIndex)) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "WAIT_COOLTIME")); + return false; + } + } + } + else + { + if (__CheckRestSkillCoolTime(dwSlotIndex)) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "WAIT_COOLTIME")); + return false; + } + + if (__CheckShortLife(rkSkillInst, *pSkillData)) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "NOT_ENOUGH_HP")); + return false; + } + + if (__CheckShortMana(rkSkillInst, *pSkillData)) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "NOT_ENOUGH_SP")); + return false; + } + } + + return true; +} + +bool CPythonPlayer::__CheckShortArrow(TSkillInstance & rkSkillInst, CPythonSkill::TSkillData& rkSkillData) +{ + if (!rkSkillData.IsNeedBow()) + return false; + + if (__HasEnoughArrow()) + return false; + + return true; +} + +bool CPythonPlayer::__CheckShortMana(TSkillInstance& rkSkillInst, CPythonSkill::TSkillData& rkSkillData) +{ + extern const DWORD c_iSkillIndex_Summon; + if (c_iSkillIndex_Summon == rkSkillInst.dwIndex) + return false; + + int iNeedSP = rkSkillData.GetNeedSP(rkSkillInst.fcurEfficientPercentage); + int icurSP = GetStatus(POINT_SP); + + // NOTE : ToggleSkill ƴѵ Ҹ SP 0 ̴. + if (!rkSkillData.IsToggleSkill()) + { + if (iNeedSP == 0) + { + CPythonChat::Instance().AppendChat(CHAT_TYPE_INFO, "!!! Find strange game data. Please reinstall metin2."); + return true; + } + } + + if (rkSkillData.CanUseIfNotEnough()) + { + if (icurSP <= 0) + return true; + } + else + { + if (-1 != iNeedSP) + if (iNeedSP > icurSP) + return true; + } + + return false; +} + +bool CPythonPlayer::__CheckShortLife(TSkillInstance& rkSkillInst, CPythonSkill::TSkillData& rkSkillData) +{ + if (!rkSkillData.IsUseHPSkill()) + return false; + + DWORD dwNeedHP = rkSkillData.GetNeedSP(rkSkillInst.fcurEfficientPercentage); + if (dwNeedHP <= GetStatus(POINT_HP)) + return false; + + return true; +} + +bool CPythonPlayer::__CheckRestSkillCoolTime(DWORD dwSlotIndex) +{ + if (!m_sysIsCoolTime) + return false; + + if (dwSlotIndex >= SKILL_MAX_NUM) + return false; + + float fElapsedTime = CTimer::Instance().GetCurrentSecond() - m_playerStatus.aSkill[dwSlotIndex].fLastUsedTime; + if (fElapsedTime >= m_playerStatus.aSkill[dwSlotIndex].fCoolTime) + return false; + + return true; +} + +bool CPythonPlayer::__CheckDashAffect(CInstanceBase& rkInstMain) +{ + return rkInstMain.IsAffect(CInstanceBase::AFFECT_DASH); +} + +void CPythonPlayer::__UseCurrentSkill() +{ + __UseSkill(m_dwcurSkillSlotIndex); +} + +DWORD CPythonPlayer::__GetSkillTargetRange(CPythonSkill::TSkillData& rkSkillData) +{ + return rkSkillData.GetTargetRange() + GetStatus(POINT_BOW_DISTANCE)*100; +} + +bool CPythonPlayer::__ProcessEnemySkillTargetRange(CInstanceBase& rkInstMain, CInstanceBase& rkInstTarget, CPythonSkill::TSkillData& rkSkillData, DWORD dwSkillSlotIndex) +{ + DWORD dwSkillTargetRange=__GetSkillTargetRange(rkSkillData); + float fSkillTargetRange = float(dwSkillTargetRange); + if (fSkillTargetRange <= 0.0f) + return true; + + // #0000806: [M2EU] 濡 (ѱ) źȯ ų ȵ + float fTargetDistance = rkInstMain.GetDistance(&rkInstTarget); + + extern bool IS_HUGE_RACE(unsigned int vnum); + if (IS_HUGE_RACE(rkInstTarget.GetRace())) + { + fTargetDistance -= 200.0f; // TEMP: ϴ ϵ ڵ ó. δ ٿ Ǿ ؾ + } + + if (fTargetDistance >= fSkillTargetRange) + { + if (rkSkillData.IsChargeSkill()) + { + if (!__IsReservedUseSkill(dwSkillSlotIndex)) + __SendUseSkill(dwSkillSlotIndex, 0); + } + + __ReserveUseSkill(rkInstTarget.GetVirtualID(), dwSkillSlotIndex, dwSkillTargetRange); + + return false; + } + + // 2004.07.05.myevan. ýź ʿ . ϱ ִ° üũ + TPixelPosition kPPosTarget; + rkInstTarget.NEW_GetPixelPosition(&kPPosTarget); + + IBackground& rkBG=IBackground::Instance(); + if (rkBG.IsBlock(kPPosTarget.x, kPPosTarget.y)) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "CANNOT_APPROACH")); + return false; + } + + return true; +} + +bool CPythonPlayer::__CanUseSkill() +{ + CInstanceBase* pkInstMain=NEW_GetMainActorPtr(); + if (!pkInstMain) + return false; + + if (IsObserverMode()) + return false; + + // Fix me + // Ʈ. ¸ų 20 ̸ , Ʈ Ÿ ¸ ų ϵ ϵ ڵ... + // ߿ ð can use skill üũ ... + if (pkInstMain->IsMountingHorse() && (GetSkillGrade(109) < 1 && GetSkillLevel(109) < 20)) + { + return false; + } + + return pkInstMain->CanUseSkill(); +} + + +bool CPythonPlayer::__UseSkill(DWORD dwSlotIndex) +{ + // PrivateShop + if (IsOpenPrivateShop()) + { + return true; + } + + if (!__CanUseSkill()) + { + return false; + } + + if (dwSlotIndex >= SKILL_MAX_NUM) + { + Tracenf("CPythonPlayer::__UseSkill(dwSlotIndex=%d) It's not available skill slot number", dwSlotIndex); + return false; + } + + TSkillInstance & rkSkillInst = m_playerStatus.aSkill[dwSlotIndex]; + + if (__CheckSpecialSkill(rkSkillInst.dwIndex)) + { + return true; + } + + CPythonSkill::TSkillData * pSkillData; + if (!CPythonSkill::Instance().GetSkillData(rkSkillInst.dwIndex, &pSkillData)) + { + Tracenf("CPythonPlayer::__UseSkill(dwSlotIndex=%d) There is no skill data", dwSlotIndex); + return false; + } + + if (pSkillData->IsToggleSkill()) + { + if (IsSkillActive(dwSlotIndex)) + { + CPythonNetworkStream::Instance().SendUseSkillPacket(rkSkillInst.dwIndex, dwSlotIndex); + return false; + } + } + + if (!__CheckSkillUsable(dwSlotIndex)) + { + return false; + } + + CInstanceBase * pkInstMain = NEW_GetMainActorPtr(); + if (!pkInstMain) + { + Tracenf("CPythonPlayer::__UseSkill(dwSlotIndex=%d) There is no main player", dwSlotIndex); + return false; + } + + if (pkInstMain->IsUsingSkill()) + { + return false; + } + + CInstanceBase * pkInstTarget = NULL; + + // NOTE : Ÿ ʿ + if (pSkillData->IsNeedTarget() || + pSkillData->CanChangeDirection() || + pSkillData->IsAutoSearchTarget()) + { + if (pSkillData->IsNeedCorpse()) + pkInstTarget=__GetDeadTargetInstancePtr(); + else + pkInstTarget=__GetAliveTargetInstancePtr(); + + // Ÿ .. + if (!pkInstTarget) + { + // Ʈϰ.. + __ChangeTargetToPickedInstance(); + + // ٽ . + if (pSkillData->IsNeedCorpse()) + pkInstTarget=__GetDeadTargetInstancePtr(); + else + pkInstTarget=__GetAliveTargetInstancePtr(); + } + + if (pkInstTarget) + { + if (pSkillData->IsOnlyForAlliance()) + { + if (pkInstMain == pkInstTarget) + { + if (!pSkillData->CanUseForMe()) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "CANNOT_USE_SELF")); + return false; + } + } + else if (!pkInstMain->IsAttackableInstance(*pkInstTarget) && pkInstTarget->IsPC()) + { + DWORD dwSkillRange = __GetSkillTargetRange(*pSkillData); + + if (dwSkillRange > 0) + { + float fDistance=pkInstMain->GetDistance(pkInstTarget); + if (fDistance>=float(dwSkillRange)) + { + __ReserveUseSkill(pkInstTarget->GetVirtualID(), dwSlotIndex, dwSkillRange); + return false; + } + } + } + else + { + if (pSkillData->CanUseForMe()) + { + pkInstTarget = pkInstMain; + Tracef(" [ALERT] ῡ ϴ ӿ Ÿ Ǿ־ ڽſԷ 缳\n"); + } + else + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "ONLY_FOR_ALLIANCE")); + return false; + } + } + } + else + { + if (pkInstTarget->IsInSafe()) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "CANNOT_ATTACK_ENEMY_IN_SAFE_AREA")); + return false; + } + + if (pkInstMain->IsAttackableInstance(*pkInstTarget)) + { + if (!__ProcessEnemySkillTargetRange(*pkInstMain, *pkInstTarget, *pSkillData, dwSlotIndex)) + return false; + } + else + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "CANNOT_ATTACK")); + return false; + } + } + + pkInstMain->SetFlyTargetInstance(*pkInstTarget); + + if (pkInstMain != pkInstTarget) + { + if (pkInstMain->IsFlyTargetObject()) + { + pkInstMain->NEW_LookAtFlyTarget(); + } + else + { + pkInstMain->NEW_LookAtDestInstance(*pkInstTarget); + } + } + } + else + { + if (pSkillData->IsAutoSearchTarget()) + { + if (pkInstMain->NEW_GetFrontInstance(&pkInstTarget, 2000.0f)) + { + SetTarget(pkInstTarget->GetVirtualID()); + if (!__ProcessEnemySkillTargetRange(*pkInstMain, *pkInstTarget, *pSkillData, dwSlotIndex)) + return false; + } + else + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "NEED_TARGET")); + return false; + } + } + + if (pSkillData->CanUseForMe()) + { + pkInstTarget = pkInstMain; + pkInstMain->SetFlyTargetInstance(*pkInstMain); + Tracef(" [ALERT] Ÿ  ÷̾ մϴ\n"); + } + else if (pSkillData->IsNeedCorpse()) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "ONLY_FOR_CORPSE")); + return false; + } + else + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "NEED_TARGET")); + return false; + } + } + } + + if (pSkillData->CanChangeDirection()) + { + DWORD dwPickedActorID; + TPixelPosition kPPosPickedGround; + + if (pkInstTarget && pkInstTarget!=pkInstMain) + { + pkInstMain->NEW_LookAtDestInstance(*pkInstTarget); + } + else if (__GetPickedActorID(&dwPickedActorID)) + { + CInstanceBase* pkInstVictim=NEW_FindActorPtr(dwPickedActorID); + if (pkInstVictim) + pkInstMain->NEW_LookAtDestInstance(*pkInstVictim); + } + else if (__GetPickedGroundPos(&kPPosPickedGround)) + { + pkInstMain->NEW_LookAtDestPixelPosition(kPPosPickedGround); + } + else + { + Tracenf("CPythonPlayer::__UseSkill(%d) - ȭ ؾ", dwSlotIndex); + } + } + + // ݼ ó + DWORD dwTargetMaxCount = pSkillData->GetTargetCount(rkSkillInst.fcurEfficientPercentage); + DWORD dwRange = __GetSkillTargetRange(*pSkillData); + if (dwTargetMaxCount>0 && pkInstTarget) + { + DWORD dwTargetCount=1; + std::vector kVct_pkInstTarget; + + if (pSkillData->IsFanRange()) + { + if (pkInstMain->NEW_GetInstanceVectorInFanRange(float(dwRange), *pkInstTarget, &kVct_pkInstTarget)) + { + std::vector::iterator i; + for (i=kVct_pkInstTarget.begin(); i!=kVct_pkInstTarget.end(); ++i) + { + if (dwTargetCount>=dwTargetMaxCount) + break; + + CInstanceBase* pkInstEach=*i; + + if (pkInstTarget!=pkInstEach && !pkInstEach->IsDead()) + { + pkInstMain->AddFlyTargetInstance(*pkInstEach); + CPythonNetworkStream::Instance().SendAddFlyTargetingPacket(pkInstEach->GetVirtualID(), pkInstEach->GetGraphicThingInstanceRef().OnGetFlyTargetPosition()); + + dwTargetCount++; + } + } + } + } + else if (pSkillData->IsCircleRange()) + { + if (pkInstMain->NEW_GetInstanceVectorInCircleRange(float(dwRange), &kVct_pkInstTarget)) + { + std::vector::iterator i; + for (i=kVct_pkInstTarget.begin(); i!=kVct_pkInstTarget.end(); ++i) + { + if (dwTargetCount>=dwTargetMaxCount) + break; + + CInstanceBase* pkInstEach=*i; + + if (pkInstTarget!=pkInstEach && !pkInstEach->IsDead()) + { + pkInstMain->AddFlyTargetInstance(*pkInstEach); + CPythonNetworkStream::Instance().SendAddFlyTargetingPacket(pkInstEach->GetVirtualID(), pkInstEach->GetGraphicThingInstanceRef().OnGetFlyTargetPosition()); + + dwTargetCount++; + } + } + } + } + + if (dwTargetCountNEW_GetRandomPositionInFanRange(*pkInstTarget, &kPPosDst); + + kPPosDst.x=kPPosDst.x; + kPPosDst.y=-kPPosDst.y; + + pkInstMain->AddFlyTargetPosition(kPPosDst); + CPythonNetworkStream::Instance().SendAddFlyTargetingPacket(0, kPPosDst); + + dwTargetCount++; + } + } + } + + ///// + // NOTE : ָ Ŭس ų ų ٷ ϴ ϱ ڵ - [levites] + __ClearReservedAction(); + ///// + + if (!pSkillData->IsNoMotion()) + { + DWORD dwMotionIndex = pSkillData->GetSkillMotionIndex(rkSkillInst.iGrade); + DWORD dwLoopCount = pSkillData->GetMotionLoopCount(rkSkillInst.fcurEfficientPercentage); + if (!pkInstMain->NEW_UseSkill(rkSkillInst.dwIndex, dwMotionIndex, dwLoopCount, pSkillData->IsMovingSkill() ? true : false)) + { + Tracenf("CPythonPlayer::__UseSkill(%d) - pkInstMain->NEW_UseSkill - ERROR", dwSlotIndex); + return false; + } + } + + DWORD dwTargetVID=pkInstTarget ? pkInstTarget->GetVirtualID() : 0; + + __SendUseSkill(dwSlotIndex, dwTargetVID); + return true; +} + +void CPythonPlayer::__SendUseSkill(DWORD dwSkillSlotIndex, DWORD dwTargetVID) +{ + TSkillInstance & rkSkillInst = m_playerStatus.aSkill[dwSkillSlotIndex]; + + CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance(); + rkNetStream.SendUseSkillPacket(rkSkillInst.dwIndex, dwTargetVID); + + __RunCoolTime(dwSkillSlotIndex); +} + +BYTE CPythonPlayer::__GetSkillType(DWORD dwSkillSlotIndex) +{ + TSkillInstance & rkSkillInst = m_playerStatus.aSkill[dwSkillSlotIndex]; + + CPythonSkill::TSkillData * pkSkillData; + CPythonSkill& rkPythonSkill = CPythonSkill::Instance(); + if (!rkPythonSkill.GetSkillData(rkSkillInst.dwIndex, &pkSkillData)) + { + //TraceError("CPythonPlayer::__GetSkillType(dwSkillSlotIndex=%d) - NOT CHECK", dwSkillSlotIndex); + return 0; + } + return pkSkillData->GetType(); +} + +void CPythonPlayer::__RunCoolTime(DWORD dwSkillSlotIndex) +{ + TSkillInstance & rkSkillInst = m_playerStatus.aSkill[dwSkillSlotIndex]; + + CPythonSkill::TSkillData * pkSkillData; + if (!CPythonSkill::Instance().GetSkillData(rkSkillInst.dwIndex, &pkSkillData)) + { + TraceError("CPythonPlayer::__SendUseSkill(dwSkillSlotIndex=%d) - NOT CHECK", dwSkillSlotIndex); + return; + } + + CPythonSkill::TSkillData& rkSkillData=*pkSkillData; + + rkSkillInst.fCoolTime = rkSkillData.GetSkillCoolTime(rkSkillInst.fcurEfficientPercentage); + rkSkillInst.fLastUsedTime = CTimer::Instance().GetCurrentSecond(); + + int iSpd = 100 - GetStatus(POINT_CASTING_SPEED); + if (iSpd > 0) + iSpd = 100 + iSpd; + else if (iSpd < 0) + iSpd = 10000 / (100 - iSpd); + else + iSpd = 100; + + rkSkillInst.fCoolTime = rkSkillInst.fCoolTime * iSpd / 100; + + PyCallClassMemberFunc(m_ppyGameWindow, "RunUseSkillEvent", Py_BuildValue("(if)", dwSkillSlotIndex, rkSkillInst.fCoolTime)); +} + +bool CPythonPlayer::__HasEnoughArrow() +{ + CItemData * pItemData; + if (CItemManager::Instance().GetItemDataPointer(GetItemIndex(TItemPos(INVENTORY, c_Equipment_Arrow)), &pItemData)) + if (CItemData::ITEM_TYPE_WEAPON == pItemData->GetType()) + if (CItemData::WEAPON_ARROW == pItemData->GetSubType()) + { + return true; + } + + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotShotError", Py_BuildValue("(is)", GetMainCharacterIndex(), "EMPTY_ARROW")); + return false; +} + +bool CPythonPlayer::__HasItem(DWORD dwItemID) +{ + for (int i = 0; i < c_Inventory_Count; ++i) + { + if (dwItemID == GetItemIndex(TItemPos (INVENTORY, i))) + return true; + } + for (int i = 0; i < c_DragonSoul_Inventory_Count; ++i) + { + if (dwItemID == GetItemIndex(TItemPos (DRAGON_SOUL_INVENTORY, i))) + return true; + } + + return false; +} + +extern const DWORD c_iSkillIndex_Tongsol; +extern const DWORD c_iSkillIndex_Fishing; +extern const DWORD c_iSkillIndex_Mining; +extern const DWORD c_iSkillIndex_Making; +extern const DWORD c_iSkillIndex_Combo; +extern const DWORD c_iSkillIndex_Language1; +extern const DWORD c_iSkillIndex_Language2; +extern const DWORD c_iSkillIndex_Language3; +extern const DWORD c_iSkillIndex_Polymorph; + +void CPythonPlayer::UseGuildSkill(DWORD dwSkillSlotIndex) +{ + CInstanceBase* pkInstMain = NEW_GetMainActorPtr(); + if (!pkInstMain) + return; + if (!pkInstMain->CanUseSkill()) + return; + + /////////////////////////////////////////////////////////////////////////////////////////////// + + if (dwSkillSlotIndex >= SKILL_MAX_NUM) + { + Tracenf("CPythonPlayer::UseGuildSkill(dwSkillSlotIndex=%d) It's not available skill slot number", dwSkillSlotIndex); + return; + } + + TSkillInstance & rkSkillInst = m_playerStatus.aSkill[dwSkillSlotIndex]; + + DWORD dwSkillIndex = rkSkillInst.dwIndex; + + CPythonSkill::TSkillData * pSkillData; + if (!CPythonSkill::Instance().GetSkillData(dwSkillIndex, &pSkillData)) + return; + + if (__CheckRestSkillCoolTime(dwSkillSlotIndex)) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "WAIT_COOLTIME")); + return; + } + + if (pSkillData->IsOnlyForGuildWar()) + { + if (!CPythonGuild::Instance().IsDoingGuildWar()) + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "ONLY_FOR_GUILD_WAR")); + return; + } + } + + DWORD dwMotionIndex = pSkillData->GetSkillMotionIndex(); + if (!pkInstMain->NEW_UseSkill(dwSkillIndex, dwMotionIndex, 1, false)) + { + Tracenf("CPythonPlayer::UseGuildSkill(%d) - pkInstMain->NEW_UseSkill - ERROR", dwSkillIndex); + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + + CPythonNetworkStream::Instance().SendGuildUseSkillPacket(dwSkillIndex, 0); + __RunCoolTime(dwSkillSlotIndex); +} + +void CPythonPlayer::SetComboSkillFlag(BOOL bFlag) +{ + DWORD dwSlotIndex; + if (!GetSkillSlotIndex(c_iSkillIndex_Combo, &dwSlotIndex)) + { + Tracef("CPythonPlayer::SetComboSkillFlag(killIndex=%d) - Can't Find Slot Index\n", c_iSkillIndex_Combo); + return; + } + + int iLevel = GetSkillLevel(dwSlotIndex); + if (iLevel <= 0) + { + Tracef("CPythonPlayer::SetComboSkillFlag(skillIndex=%d, skillLevel=%d) - Invalid Combo Skill Level\n", c_iSkillIndex_Combo, iLevel); + return; + } + + iLevel = MIN(iLevel, 2); + + CInstanceBase* pkInstMain = NEW_GetMainActorPtr(); + if (!pkInstMain) + return; + + if (bFlag) + { + pkInstMain->SetComboType(iLevel); + __ActivateSkillSlot(dwSlotIndex); + } + else + { + pkInstMain->SetComboType(0); + __DeactivateSkillSlot(dwSlotIndex); + } +} + +bool CPythonPlayer::__CheckSpecialSkill(DWORD dwSkillIndex) +{ + CInstanceBase* pkInstMain = NEW_GetMainActorPtr(); + if (!pkInstMain) + return false; + + // Fishing + if (c_iSkillIndex_Fishing == dwSkillIndex) + { + if (pkInstMain->IsFishingMode()) + { + NEW_Fishing(); + } + else + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "EQUIP_FISHING_ROD")); + } + return true; + } + + // Combo + else if (c_iSkillIndex_Combo == dwSkillIndex) + { + DWORD dwSlotIndex; + if (!GetSkillSlotIndex(dwSkillIndex, &dwSlotIndex)) + return false; + + int iLevel = GetSkillLevel(dwSlotIndex); + if (iLevel > 0) + { + CPythonNetworkStream::Instance().SendUseSkillPacket(dwSkillIndex); + } + else + { + PyCallClassMemberFunc(m_ppyGameWindow, "OnCannotUseSkill", Py_BuildValue("(is)", GetMainCharacterIndex(), "NOT_YET_LEARN")); + } + + return true; + } + + return false; +} diff --git a/source/UserInterface/PythonProfilerModule.cpp b/source/UserInterface/PythonProfilerModule.cpp new file mode 100644 index 0000000..c28ff16 --- /dev/null +++ b/source/UserInterface/PythonProfilerModule.cpp @@ -0,0 +1,33 @@ +#include "StdAfx.h" +#include "../eterLib/Profiler.h" + +PyObject * profilerPush(PyObject * poSelf, PyObject * poArgs) +{ + char * szName; + if (!PyTuple_GetString(poArgs, 0, &szName)) + return Py_BuildException(); + + return Py_BuildNone(); +} + +PyObject * profilerPop(PyObject * poSelf, PyObject * poArgs) +{ + char * szName; + if (!PyTuple_GetString(poArgs, 0, &szName)) + return Py_BuildException(); + + return Py_BuildNone(); +} + +void initProfiler() +{ + static PyMethodDef s_methods[] = + { + { "Push", profilerPush, METH_VARARGS }, + { "Pop", profilerPop, METH_VARARGS }, + + { NULL, NULL, NULL }, + }; + + Py_InitModule("profiler", s_methods); +} \ No newline at end of file diff --git a/source/UserInterface/PythonQuest.cpp b/source/UserInterface/PythonQuest.cpp new file mode 100644 index 0000000..cd7e35e --- /dev/null +++ b/source/UserInterface/PythonQuest.cpp @@ -0,0 +1,270 @@ +#include "StdAfx.h" +#include "PythonQuest.h" + +void CPythonQuest::RegisterQuestInstance(const SQuestInstance & c_rQuestInstance) +{ + DeleteQuestInstance(c_rQuestInstance.dwIndex); + m_QuestInstanceContainer.push_back(c_rQuestInstance); + + ///// + + SQuestInstance & rQuestInstance = *m_QuestInstanceContainer.rbegin(); + rQuestInstance.iStartTime = int(CTimer::Instance().GetCurrentSecond()); +} + +struct FQuestInstanceCompare +{ + DWORD dwSearchIndex; + FQuestInstanceCompare(DWORD dwIndex) : dwSearchIndex(dwIndex) {} + bool operator () (const CPythonQuest::SQuestInstance & rQuestInstance) + { + return dwSearchIndex == rQuestInstance.dwIndex; + } +}; + +void CPythonQuest::DeleteQuestInstance(DWORD dwIndex) +{ + TQuestInstanceContainer::iterator itor = std::find_if(m_QuestInstanceContainer.begin(), m_QuestInstanceContainer.end(), FQuestInstanceCompare(dwIndex)); + if (itor == m_QuestInstanceContainer.end()) + return; + + m_QuestInstanceContainer.erase(itor); +} + +bool CPythonQuest::IsQuest(DWORD dwIndex) +{ + TQuestInstanceContainer::iterator itor = std::find_if(m_QuestInstanceContainer.begin(), m_QuestInstanceContainer.end(), FQuestInstanceCompare(dwIndex)); + return itor != m_QuestInstanceContainer.end(); +} + +void CPythonQuest::MakeQuest(DWORD dwIndex) +{ + DeleteQuestInstance(dwIndex); + m_QuestInstanceContainer.push_back(SQuestInstance()); + + ///// + + SQuestInstance & rQuestInstance = *m_QuestInstanceContainer.rbegin(); + rQuestInstance.dwIndex = dwIndex; + rQuestInstance.iStartTime = int(CTimer::Instance().GetCurrentSecond()); +} + +void CPythonQuest::SetQuestTitle(DWORD dwIndex, const char * c_szTitle) +{ + SQuestInstance * pQuestInstance; + if (!__GetQuestInstancePtr(dwIndex, &pQuestInstance)) + return; + + pQuestInstance->strTitle = c_szTitle; +} + +void CPythonQuest::SetQuestClockName(DWORD dwIndex, const char * c_szClockName) +{ + SQuestInstance * pQuestInstance; + if (!__GetQuestInstancePtr(dwIndex, &pQuestInstance)) + return; + + pQuestInstance->strClockName = c_szClockName; +} + +void CPythonQuest::SetQuestCounterName(DWORD dwIndex, const char * c_szCounterName) +{ + SQuestInstance * pQuestInstance; + if (!__GetQuestInstancePtr(dwIndex, &pQuestInstance)) + return; + + pQuestInstance->strCounterName = c_szCounterName; +} + +void CPythonQuest::SetQuestClockValue(DWORD dwIndex, int iClockValue) +{ + SQuestInstance * pQuestInstance; + if (!__GetQuestInstancePtr(dwIndex, &pQuestInstance)) + return; + + pQuestInstance->iClockValue = iClockValue; + pQuestInstance->iStartTime = int(CTimer::Instance().GetCurrentSecond()); +} + +void CPythonQuest::SetQuestCounterValue(DWORD dwIndex, int iCounterValue) +{ + SQuestInstance * pQuestInstance; + if (!__GetQuestInstancePtr(dwIndex, &pQuestInstance)) + return; + + pQuestInstance->iCounterValue = iCounterValue; +} + +void CPythonQuest::SetQuestIconFileName(DWORD dwIndex, const char * c_szIconFileName) +{ + SQuestInstance * pQuestInstance; + if (!__GetQuestInstancePtr(dwIndex, &pQuestInstance)) + return; + + pQuestInstance->strIconFileName = c_szIconFileName; +} + +int CPythonQuest::GetQuestCount() +{ + return m_QuestInstanceContainer.size(); +} + +bool CPythonQuest::GetQuestInstancePtr(DWORD dwArrayIndex, SQuestInstance ** ppQuestInstance) +{ + if (dwArrayIndex >= m_QuestInstanceContainer.size()) + return false; + + *ppQuestInstance = &m_QuestInstanceContainer[dwArrayIndex]; + + return true; +} + +bool CPythonQuest::__GetQuestInstancePtr(DWORD dwQuestIndex, SQuestInstance ** ppQuestInstance) +{ + TQuestInstanceContainer::iterator itor = std::find_if(m_QuestInstanceContainer.begin(), m_QuestInstanceContainer.end(), FQuestInstanceCompare(dwQuestIndex)); + if (itor == m_QuestInstanceContainer.end()) + return false; + + *ppQuestInstance = &(*itor); + + return true; +} + +void CPythonQuest::__Initialize() +{ +/* +#ifdef _DEBUG + for (int i = 0; i < 7; ++i) + { + SQuestInstance test; + test.dwIndex = i; + test.strIconFileName = ""; + test.strTitle = _getf("test%d", i); + test.strClockName = " ð"; + test.strCounterName = " "; + test.iClockValue = 1000; + test.iCounterValue = 1000; + test.iStartTime = 0; + RegisterQuestInstance(test); + } +#endif +*/ +} + +void CPythonQuest::Clear() +{ + m_QuestInstanceContainer.clear(); +} + +CPythonQuest::CPythonQuest() +{ + __Initialize(); +} + +CPythonQuest::~CPythonQuest() +{ + Clear(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// + +PyObject * questGetQuestCount(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonQuest::Instance().GetQuestCount()); +} + +PyObject * questGetQuestData(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BadArgument(); + + CPythonQuest::SQuestInstance * pQuestInstance; + if (!CPythonQuest::Instance().GetQuestInstancePtr(iIndex, &pQuestInstance)) + return Py_BuildException("Failed to find quest by index %d", iIndex); + + CGraphicImage * pImage = NULL; + if (!pQuestInstance->strIconFileName.empty()) + { + std::string strIconFileName; + strIconFileName = "d:/ymir work/ui/game/quest/questicon/"; + strIconFileName += pQuestInstance->strIconFileName.c_str(); + pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer(strIconFileName.c_str()); + } + else + { + { + // Ʈ ̹ ִ´. + std::string strIconFileName = "season1/icon/scroll_open.tga"; + pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer(strIconFileName.c_str()); + } + } + + return Py_BuildValue("sisi", pQuestInstance->strTitle.c_str(), + pImage, + pQuestInstance->strCounterName.c_str(), + pQuestInstance->iCounterValue); +} + +PyObject * questGetQuestIndex(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BadArgument(); + + CPythonQuest::SQuestInstance * pQuestInstance; + if (!CPythonQuest::Instance().GetQuestInstancePtr(iIndex, &pQuestInstance)) + return Py_BuildException("Failed to find quest by index %d", iIndex); + + return Py_BuildValue("i", pQuestInstance->dwIndex); +} + +PyObject * questGetQuestLastTime(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BadArgument(); + + CPythonQuest::SQuestInstance * pQuestInstance; + if (!CPythonQuest::Instance().GetQuestInstancePtr(iIndex, &pQuestInstance)) + return Py_BuildException("Failed to find quest by index %d", iIndex); + + int iLastTime = 0; + + if (pQuestInstance->iClockValue >= 0) + { + iLastTime = (pQuestInstance->iStartTime + pQuestInstance->iClockValue) - int(CTimer::Instance().GetCurrentSecond()); + } + + // ð ó ڵ +// else +// { +// iLastTime = int(CTimer::Instance().GetCurrentSecond()) - pQuestInstance->iStartTime; +// } + + return Py_BuildValue("si", pQuestInstance->strClockName.c_str(), iLastTime); +} + +PyObject * questClear(PyObject * poSelf, PyObject * poArgs) +{ + CPythonQuest::Instance().Clear(); + return Py_BuildNone(); +} + +void initquest() +{ + static PyMethodDef s_methods[] = + { + { "GetQuestCount", questGetQuestCount, METH_VARARGS }, + { "GetQuestData", questGetQuestData, METH_VARARGS }, + { "GetQuestIndex", questGetQuestIndex, METH_VARARGS }, + { "GetQuestLastTime", questGetQuestLastTime, METH_VARARGS }, + { "Clear", questClear, METH_VARARGS }, + { NULL, NULL, NULL }, + }; + + PyObject * poModule = Py_InitModule("quest", s_methods); + PyModule_AddIntConstant(poModule, "QUEST_MAX_NUM", 5); +} diff --git a/source/UserInterface/PythonQuest.h b/source/UserInterface/PythonQuest.h new file mode 100644 index 0000000..bef0dc0 --- /dev/null +++ b/source/UserInterface/PythonQuest.h @@ -0,0 +1,59 @@ +#pragma once + +class CPythonQuest : public CSingleton +{ + public: + struct SQuestInstance + { + SQuestInstance() + { + dwIndex = 0; + iClockValue = 0; + iCounterValue = 0; + iStartTime = 0; + } + + DWORD dwIndex; + + std::string strIconFileName; + std::string strTitle; + + std::string strClockName; + std::string strCounterName; + + int iClockValue; + int iCounterValue; + + int iStartTime; + }; + typedef std::vector TQuestInstanceContainer; + + public: + CPythonQuest(); + virtual ~CPythonQuest(); + + void Clear(); + + void RegisterQuestInstance(const SQuestInstance & c_rQuestInstance); + void DeleteQuestInstance(DWORD dwIndex); + + bool IsQuest(DWORD dwIndex); + void MakeQuest(DWORD dwIndex); + + void SetQuestTitle(DWORD dwIndex, const char * c_szTitle); + void SetQuestClockName(DWORD dwIndex, const char * c_szClockName); + void SetQuestCounterName(DWORD dwIndex, const char * c_szCounterName); + void SetQuestClockValue(DWORD dwIndex, int iClockValue); + void SetQuestCounterValue(DWORD dwIndex, int iCounterValue); + void SetQuestIconFileName(DWORD dwIndex, const char * c_szIconFileName); + + int GetQuestCount(); + bool GetQuestInstancePtr(DWORD dwArrayIndex, SQuestInstance ** ppQuestInstance); + + protected: + void __Initialize(); + bool __GetQuestInstancePtr(DWORD dwQuestIndex, SQuestInstance ** ppQuestInstance); + + protected: + TQuestInstanceContainer m_QuestInstanceContainer; +}; \ No newline at end of file diff --git a/source/UserInterface/PythonSafeBox.cpp b/source/UserInterface/PythonSafeBox.cpp new file mode 100644 index 0000000..39a9e0e --- /dev/null +++ b/source/UserInterface/PythonSafeBox.cpp @@ -0,0 +1,338 @@ +#include "StdAfx.h" +#include "PythonSafeBox.h" + +void CPythonSafeBox::OpenSafeBox(int iSize) +{ + m_dwMoney = 0; + m_ItemInstanceVector.clear(); + m_ItemInstanceVector.resize(SAFEBOX_SLOT_X_COUNT * iSize); + + for (DWORD i = 0; i < m_ItemInstanceVector.size(); ++i) + { + TItemData & rInstance = m_ItemInstanceVector[i]; + ZeroMemory(&rInstance, sizeof(rInstance)); + } +} + +void CPythonSafeBox::SetItemData(DWORD dwSlotIndex, const TItemData & rItemInstance) +{ + if (dwSlotIndex >= m_ItemInstanceVector.size()) + { + TraceError("CPythonSafeBox::SetItemData(dwSlotIndex=%d) - Strange slot index", dwSlotIndex); + return; + } + + m_ItemInstanceVector[dwSlotIndex] = rItemInstance; +} + +void CPythonSafeBox::DelItemData(DWORD dwSlotIndex) +{ + if (dwSlotIndex >= m_ItemInstanceVector.size()) + { + TraceError("CPythonSafeBox::DelItemData(dwSlotIndex=%d) - Strange slot index", dwSlotIndex); + return; + } + + TItemData & rInstance = m_ItemInstanceVector[dwSlotIndex]; + ZeroMemory(&rInstance, sizeof(rInstance)); +} + +void CPythonSafeBox::SetMoney(DWORD dwMoney) +{ + m_dwMoney = dwMoney; +} + +DWORD CPythonSafeBox::GetMoney() +{ + return m_dwMoney; +} + +int CPythonSafeBox::GetCurrentSafeBoxSize() +{ + return m_ItemInstanceVector.size(); +} + +BOOL CPythonSafeBox::GetSlotItemID(DWORD dwSlotIndex, DWORD* pdwItemID) +{ + if (dwSlotIndex >= m_ItemInstanceVector.size()) + { + TraceError("CPythonSafeBox::GetSlotItemID(dwSlotIndex=%d) - Strange slot index", dwSlotIndex); + return FALSE; + } + + *pdwItemID=m_ItemInstanceVector[dwSlotIndex].vnum; + + return TRUE; +} + +BOOL CPythonSafeBox::GetItemDataPtr(DWORD dwSlotIndex, TItemData ** ppInstance) +{ + if (dwSlotIndex >= m_ItemInstanceVector.size()) + { + TraceError("CPythonSafeBox::GetItemData(dwSlotIndex=%d) - Strange slot index", dwSlotIndex); + return FALSE; + } + + *ppInstance = &m_ItemInstanceVector[dwSlotIndex]; + + return TRUE; +} + +void CPythonSafeBox::OpenMall(int iSize) +{ + m_MallItemInstanceVector.clear(); + m_MallItemInstanceVector.resize(SAFEBOX_SLOT_X_COUNT * iSize); + + for (DWORD i = 0; i < m_MallItemInstanceVector.size(); ++i) + { + TItemData & rInstance = m_MallItemInstanceVector[i]; + ZeroMemory(&rInstance, sizeof(rInstance)); + } +} + +void CPythonSafeBox::SetMallItemData(DWORD dwSlotIndex, const TItemData & rItemData) +{ + if (dwSlotIndex >= m_MallItemInstanceVector.size()) + { + TraceError("CPythonSafeBox::SetMallItemData(dwSlotIndex=%d) - Strange slot index", dwSlotIndex); + return; + } + + m_MallItemInstanceVector[dwSlotIndex] = rItemData; +} + +void CPythonSafeBox::DelMallItemData(DWORD dwSlotIndex) +{ + if (dwSlotIndex >= m_MallItemInstanceVector.size()) + { + TraceError("CPythonSafeBox::DelMallItemData(dwSlotIndex=%d) - Strange slot index", dwSlotIndex); + return; + } + + TItemData & rInstance = m_MallItemInstanceVector[dwSlotIndex]; + ZeroMemory(&rInstance, sizeof(rInstance)); +} + +BOOL CPythonSafeBox::GetMallItemDataPtr(DWORD dwSlotIndex, TItemData ** ppInstance) +{ + if (dwSlotIndex >= m_MallItemInstanceVector.size()) + { + TraceError("CPythonSafeBox::GetMallSlotItemID(dwSlotIndex=%d) - Strange slot index", dwSlotIndex); + return FALSE; + } + + *ppInstance = &m_MallItemInstanceVector[dwSlotIndex]; + + return TRUE; +} + +BOOL CPythonSafeBox::GetSlotMallItemID(DWORD dwSlotIndex, DWORD * pdwItemID) +{ + if (dwSlotIndex >= m_MallItemInstanceVector.size()) + { + TraceError("CPythonSafeBox::GetMallSlotItemID(dwSlotIndex=%d) - Strange slot index", dwSlotIndex); + return FALSE; + } + + *pdwItemID = m_MallItemInstanceVector[dwSlotIndex].vnum; + + return TRUE; +} + +DWORD CPythonSafeBox::GetMallSize() +{ + return m_MallItemInstanceVector.size(); +} + +CPythonSafeBox::CPythonSafeBox() +{ + m_dwMoney = 0; +} + +CPythonSafeBox::~CPythonSafeBox() +{ +} + +PyObject * safeboxGetCurrentSafeboxSize(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonSafeBox::Instance().GetCurrentSafeBoxSize()); +} + +PyObject * safeboxGetItemID(PyObject * poSelf, PyObject * poArgs) +{ + int ipos; + if (!PyTuple_GetInteger(poArgs, 0, &ipos)) + return Py_BadArgument(); + + TItemData * pInstance; + if (!CPythonSafeBox::Instance().GetItemDataPtr(ipos, &pInstance)) + return Py_BuildException(); + + return Py_BuildValue("i", pInstance->vnum); +} + +PyObject * safeboxGetItemCount(PyObject * poSelf, PyObject * poArgs) +{ + int ipos; + if (!PyTuple_GetInteger(poArgs, 0, &ipos)) + return Py_BadArgument(); + + TItemData * pInstance; + if (!CPythonSafeBox::Instance().GetItemDataPtr(ipos, &pInstance)) + return Py_BuildException(); + + return Py_BuildValue("i", pInstance->count); +} + +PyObject * safeboxGetItemFlags(PyObject * poSelf, PyObject * poArgs) +{ + int ipos; + if (!PyTuple_GetInteger(poArgs, 0, &ipos)) + return Py_BadArgument(); + + TItemData * pInstance; + if (!CPythonSafeBox::Instance().GetItemDataPtr(ipos, &pInstance)) + return Py_BuildException(); + + return Py_BuildValue("i", pInstance->flags); +} + +PyObject * safeboxGetItemMetinSocket(PyObject * poSelf, PyObject * poArgs) +{ + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BadArgument(); + int iSocketIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iSocketIndex)) + return Py_BadArgument(); + + if (iSocketIndex >= ITEM_SOCKET_SLOT_MAX_NUM) + return Py_BuildException(); + + TItemData * pItemData; + if (!CPythonSafeBox::Instance().GetItemDataPtr(iSlotIndex, &pItemData)) + return Py_BuildException(); + + return Py_BuildValue("i", pItemData->alSockets[iSocketIndex]); +} + +PyObject * safeboxGetItemAttribute(PyObject * poSelf, PyObject * poArgs) +{ + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + int iAttrSlotIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iAttrSlotIndex)) + return Py_BuildException(); + + if (iAttrSlotIndex >= 0 && iAttrSlotIndex < ITEM_ATTRIBUTE_SLOT_MAX_NUM) + { + TItemData * pItemData; + if (CPythonSafeBox::Instance().GetItemDataPtr(iSlotIndex, &pItemData)) + return Py_BuildValue("ii", pItemData->aAttr[iAttrSlotIndex].bType, pItemData->aAttr[iAttrSlotIndex].sValue); + } + + return Py_BuildValue("ii", 0, 0); +} + +PyObject * safeboxGetMoney(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonSafeBox::Instance().GetMoney()); +} + +PyObject * safeboxGetMallItemID(PyObject * poSelf, PyObject * poArgs) +{ + int ipos; + if (!PyTuple_GetInteger(poArgs, 0, &ipos)) + return Py_BadArgument(); + + TItemData * pInstance; + if (!CPythonSafeBox::Instance().GetMallItemDataPtr(ipos, &pInstance)) + return Py_BuildException(); + + return Py_BuildValue("i", pInstance->vnum); +} + +PyObject * safeboxGetMallItemCount(PyObject * poSelf, PyObject * poArgs) +{ + int ipos; + if (!PyTuple_GetInteger(poArgs, 0, &ipos)) + return Py_BadArgument(); + + TItemData * pInstance; + if (!CPythonSafeBox::Instance().GetMallItemDataPtr(ipos, &pInstance)) + return Py_BuildException(); + + return Py_BuildValue("i", pInstance->count); +} + +PyObject * safeboxGetMallItemMetinSocket(PyObject * poSelf, PyObject * poArgs) +{ + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BadArgument(); + int iSocketIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iSocketIndex)) + return Py_BadArgument(); + + if (iSocketIndex >= ITEM_SOCKET_SLOT_MAX_NUM) + return Py_BuildException(); + + TItemData * pItemData; + if (!CPythonSafeBox::Instance().GetMallItemDataPtr(iSlotIndex, &pItemData)) + return Py_BuildException(); + + return Py_BuildValue("i", pItemData->alSockets[iSocketIndex]); +} + +PyObject * safeboxGetMallItemAttribute(PyObject * poSelf, PyObject * poArgs) +{ + int iSlotIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) + return Py_BuildException(); + int iAttrSlotIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iAttrSlotIndex)) + return Py_BuildException(); + + if (iAttrSlotIndex >= 0 && iAttrSlotIndex < ITEM_ATTRIBUTE_SLOT_MAX_NUM) + { + TItemData * pItemData; + if (CPythonSafeBox::Instance().GetMallItemDataPtr(iSlotIndex, &pItemData)) + return Py_BuildValue("ii", pItemData->aAttr[iAttrSlotIndex].bType, pItemData->aAttr[iAttrSlotIndex].sValue); + } + + return Py_BuildValue("ii", 0, 0); +} + +PyObject * safeboxGetMallSize(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonSafeBox::Instance().GetMallSize()); +} + +void initsafebox() +{ + static PyMethodDef s_methods[] = + { + // SafeBox + { "GetCurrentSafeboxSize", safeboxGetCurrentSafeboxSize, METH_VARARGS }, + { "GetItemID", safeboxGetItemID, METH_VARARGS }, + { "GetItemCount", safeboxGetItemCount, METH_VARARGS }, + { "GetItemFlags", safeboxGetItemFlags, METH_VARARGS }, + { "GetItemMetinSocket", safeboxGetItemMetinSocket, METH_VARARGS }, + { "GetItemAttribute", safeboxGetItemAttribute, METH_VARARGS }, + { "GetMoney", safeboxGetMoney, METH_VARARGS }, + + // Mall + { "GetMallItemID", safeboxGetMallItemID, METH_VARARGS }, + { "GetMallItemCount", safeboxGetMallItemCount, METH_VARARGS }, + { "GetMallItemMetinSocket", safeboxGetMallItemMetinSocket, METH_VARARGS }, + { "GetMallItemAttribute", safeboxGetMallItemAttribute, METH_VARARGS }, + { "GetMallSize", safeboxGetMallSize, METH_VARARGS }, + { NULL, NULL, NULL }, + }; + + PyObject * poModule = Py_InitModule("safebox", s_methods); + PyModule_AddIntConstant(poModule, "SAFEBOX_SLOT_X_COUNT", CPythonSafeBox::SAFEBOX_SLOT_X_COUNT); + PyModule_AddIntConstant(poModule, "SAFEBOX_SLOT_Y_COUNT", CPythonSafeBox::SAFEBOX_SLOT_Y_COUNT); + PyModule_AddIntConstant(poModule, "SAFEBOX_PAGE_SIZE", CPythonSafeBox::SAFEBOX_PAGE_SIZE); +} diff --git a/source/UserInterface/PythonSafeBox.h b/source/UserInterface/PythonSafeBox.h new file mode 100644 index 0000000..4f06262 --- /dev/null +++ b/source/UserInterface/PythonSafeBox.h @@ -0,0 +1,42 @@ +#pragma once + +class CPythonSafeBox : public CSingleton +{ + public: + enum + { + SAFEBOX_SLOT_X_COUNT = 5, + SAFEBOX_SLOT_Y_COUNT = 9, + SAFEBOX_PAGE_SIZE = SAFEBOX_SLOT_X_COUNT * SAFEBOX_SLOT_Y_COUNT, + }; + typedef std::vector TItemInstanceVector; + + public: + CPythonSafeBox(); + virtual ~CPythonSafeBox(); + + void OpenSafeBox(int iSize); + void SetItemData(DWORD dwSlotIndex, const TItemData & rItemData); + void DelItemData(DWORD dwSlotIndex); + + void SetMoney(DWORD dwMoney); + DWORD GetMoney(); + + BOOL GetSlotItemID(DWORD dwSlotIndex, DWORD* pdwItemID); + + int GetCurrentSafeBoxSize(); + BOOL GetItemDataPtr(DWORD dwSlotIndex, TItemData ** ppInstance); + + // MALL + void OpenMall(int iSize); + void SetMallItemData(DWORD dwSlotIndex, const TItemData & rItemData); + void DelMallItemData(DWORD dwSlotIndex); + BOOL GetMallItemDataPtr(DWORD dwSlotIndex, TItemData ** ppInstance); + BOOL GetSlotMallItemID(DWORD dwSlotIndex, DWORD * pdwItemID); + DWORD GetMallSize(); + + protected: + TItemInstanceVector m_ItemInstanceVector; + TItemInstanceVector m_MallItemInstanceVector; + DWORD m_dwMoney; +}; \ No newline at end of file diff --git a/source/UserInterface/PythonShop.cpp b/source/UserInterface/PythonShop.cpp new file mode 100644 index 0000000..90a5476 --- /dev/null +++ b/source/UserInterface/PythonShop.cpp @@ -0,0 +1,434 @@ +#include "stdafx.h" +#include "PythonShop.h" + +#include "PythonNetworkStream.h" + +//BOOL CPythonShop::GetSlotItemID(DWORD dwSlotPos, DWORD* pdwItemID) +//{ +// if (!CheckSlotIndex(dwSlotPos)) +// return FALSE; +// const TShopItemData * itemData; +// if (!GetItemData(dwSlotPos, &itemData)) +// return FALSE; +// *pdwItemID=itemData->vnum; +// return TRUE; +//} +void CPythonShop::SetTabCoinType(BYTE tabIdx, BYTE coinType) +{ + if (tabIdx >= m_bTabCount) + { + TraceError("Out of Index. tabIdx(%d) must be less than %d.", tabIdx, SHOP_TAB_COUNT_MAX); + return; + } + m_aShoptabs[tabIdx].coinType = coinType; +} + +BYTE CPythonShop::GetTabCoinType(BYTE tabIdx) +{ + if (tabIdx >= m_bTabCount) + { + TraceError("Out of Index. tabIdx(%d) must be less than %d.", tabIdx, SHOP_TAB_COUNT_MAX); + return 0xff; + } + return m_aShoptabs[tabIdx].coinType; +} + +void CPythonShop::SetTabName(BYTE tabIdx, const char* name) +{ + if (tabIdx >= m_bTabCount) + { + TraceError("Out of Index. tabIdx(%d) must be less than %d.", tabIdx, SHOP_TAB_COUNT_MAX); + return; + } + m_aShoptabs[tabIdx].name = name; +} + +const char* CPythonShop::GetTabName(BYTE tabIdx) +{ + if (tabIdx >= m_bTabCount) + { + TraceError("Out of Index. tabIdx(%d) must be less than %d.", tabIdx, SHOP_TAB_COUNT_MAX); + return NULL; + } + + return m_aShoptabs[tabIdx].name.c_str(); +} + +void CPythonShop::SetItemData(DWORD dwIndex, const TShopItemData & c_rShopItemData) +{ + BYTE tabIdx = dwIndex / SHOP_HOST_ITEM_MAX_NUM; + DWORD dwSlotPos = dwIndex % SHOP_HOST_ITEM_MAX_NUM; + + SetItemData(tabIdx, dwSlotPos, c_rShopItemData); +} + +BOOL CPythonShop::GetItemData(DWORD dwIndex, const TShopItemData ** c_ppItemData) +{ + BYTE tabIdx = dwIndex / SHOP_HOST_ITEM_MAX_NUM; + DWORD dwSlotPos = dwIndex % SHOP_HOST_ITEM_MAX_NUM; + + return GetItemData(tabIdx, dwSlotPos, c_ppItemData); +} + +void CPythonShop::SetItemData(BYTE tabIdx, DWORD dwSlotPos, const TShopItemData & c_rShopItemData) +{ + if (tabIdx >= SHOP_TAB_COUNT_MAX || dwSlotPos >= SHOP_HOST_ITEM_MAX_NUM) + { + TraceError("Out of Index. tabIdx(%d) must be less than %d. dwSlotPos(%d) must be less than %d", tabIdx, SHOP_TAB_COUNT_MAX, dwSlotPos, SHOP_HOST_ITEM_MAX_NUM); + return; + } + + m_aShoptabs[tabIdx].items[dwSlotPos] = c_rShopItemData; +} + +BOOL CPythonShop::GetItemData(BYTE tabIdx, DWORD dwSlotPos, const TShopItemData ** c_ppItemData) +{ + if (tabIdx >= SHOP_TAB_COUNT_MAX || dwSlotPos >= SHOP_HOST_ITEM_MAX_NUM) + { + TraceError("Out of Index. tabIdx(%d) must be less than %d. dwSlotPos(%d) must be less than %d", tabIdx, SHOP_TAB_COUNT_MAX, dwSlotPos, SHOP_HOST_ITEM_MAX_NUM); + return FALSE; + } + + *c_ppItemData = &m_aShoptabs[tabIdx].items[dwSlotPos]; + + return TRUE; +} +// +//BOOL CPythonShop::CheckSlotIndex(DWORD dwSlotPos) +//{ +// if (dwSlotPos >= SHOP_HOST_ITEM_MAX_NUM * SHOP_TAB_COUNT_MAX) +// return FALSE; +// +// return TRUE; +//} + +void CPythonShop::ClearPrivateShopStock() +{ + m_PrivateShopItemStock.clear(); +} +void CPythonShop::AddPrivateShopItemStock(TItemPos ItemPos, BYTE dwDisplayPos, DWORD dwPrice) +{ + DelPrivateShopItemStock(ItemPos); + + TShopItemTable SellingItem; + SellingItem.vnum = 0; + SellingItem.count = 0; + SellingItem.pos = ItemPos; + SellingItem.price = dwPrice; + SellingItem.display_pos = dwDisplayPos; + m_PrivateShopItemStock.insert(std::make_pair(ItemPos, SellingItem)); +} +void CPythonShop::DelPrivateShopItemStock(TItemPos ItemPos) +{ + if (m_PrivateShopItemStock.end() == m_PrivateShopItemStock.find(ItemPos)) + return; + + m_PrivateShopItemStock.erase(ItemPos); +} +int CPythonShop::GetPrivateShopItemPrice(TItemPos ItemPos) +{ + TPrivateShopItemStock::iterator itor = m_PrivateShopItemStock.find(ItemPos); + + if (m_PrivateShopItemStock.end() == itor) + return 0; + + TShopItemTable & rShopItemTable = itor->second; + return rShopItemTable.price; +} +struct ItemStockSortFunc +{ + bool operator() (TShopItemTable & rkLeft, TShopItemTable & rkRight) + { + return rkLeft.display_pos < rkRight.display_pos; + } +}; +void CPythonShop::BuildPrivateShop(const char * c_szName) +{ + std::vector ItemStock; + ItemStock.reserve(m_PrivateShopItemStock.size()); + + TPrivateShopItemStock::iterator itor = m_PrivateShopItemStock.begin(); + for (; itor != m_PrivateShopItemStock.end(); ++itor) + { + ItemStock.push_back(itor->second); + } + + std::sort(ItemStock.begin(), ItemStock.end(), ItemStockSortFunc()); + + CPythonNetworkStream::Instance().SendBuildPrivateShopPacket(c_szName, ItemStock); +} + +void CPythonShop::Open(BOOL isPrivateShop, BOOL isMainPrivateShop) +{ + m_isShoping = TRUE; + m_isPrivateShop = isPrivateShop; + m_isMainPlayerPrivateShop = isMainPrivateShop; +} + +void CPythonShop::Close() +{ + m_isShoping = FALSE; + m_isPrivateShop = FALSE; + m_isMainPlayerPrivateShop = FALSE; +} + +BOOL CPythonShop::IsOpen() +{ + return m_isShoping; +} + +BOOL CPythonShop::IsPrivateShop() +{ + return m_isPrivateShop; +} + +BOOL CPythonShop::IsMainPlayerPrivateShop() +{ + return m_isMainPlayerPrivateShop; +} + +void CPythonShop::Clear() +{ + m_isShoping = FALSE; + m_isPrivateShop = FALSE; + m_isMainPlayerPrivateShop = FALSE; + ClearPrivateShopStock(); + m_bTabCount = 1; + + for (int i = 0; i < SHOP_TAB_COUNT_MAX; i++) + memset (m_aShoptabs[i].items, 0, sizeof(TShopItemData) * SHOP_HOST_ITEM_MAX_NUM); +} + +CPythonShop::CPythonShop(void) +{ + Clear(); +} + +CPythonShop::~CPythonShop(void) +{ +} + +PyObject * shopOpen(PyObject * poSelf, PyObject * poArgs) +{ + int isPrivateShop = false; + PyTuple_GetInteger(poArgs, 0, &isPrivateShop); + int isMainPrivateShop = false; + PyTuple_GetInteger(poArgs, 1, &isMainPrivateShop); + + CPythonShop& rkShop=CPythonShop::Instance(); + rkShop.Open(isPrivateShop, isMainPrivateShop); + return Py_BuildNone(); +} + +PyObject * shopClose(PyObject * poSelf, PyObject * poArgs) +{ + CPythonShop& rkShop=CPythonShop::Instance(); + rkShop.Close(); + return Py_BuildNone(); +} + +PyObject * shopIsOpen(PyObject * poSelf, PyObject * poArgs) +{ + CPythonShop& rkShop=CPythonShop::Instance(); + return Py_BuildValue("i", rkShop.IsOpen()); +} + +PyObject * shopIsPrviateShop(PyObject * poSelf, PyObject * poArgs) +{ + CPythonShop& rkShop=CPythonShop::Instance(); + return Py_BuildValue("i", rkShop.IsPrivateShop()); +} + +PyObject * shopIsMainPlayerPrivateShop(PyObject * poSelf, PyObject * poArgs) +{ + CPythonShop& rkShop=CPythonShop::Instance(); + return Py_BuildValue("i", rkShop.IsMainPlayerPrivateShop()); +} + +PyObject * shopGetItemID(PyObject * poSelf, PyObject * poArgs) +{ + int nPos; + if (!PyTuple_GetInteger(poArgs, 0, &nPos)) + return Py_BuildException(); + + const TShopItemData * c_pItemData; + if (CPythonShop::Instance().GetItemData(nPos, &c_pItemData)) + return Py_BuildValue("i", c_pItemData->vnum); + + return Py_BuildValue("i", 0); +} + +PyObject * shopGetItemCount(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + + const TShopItemData * c_pItemData; + if (CPythonShop::Instance().GetItemData(iIndex, &c_pItemData)) + return Py_BuildValue("i", c_pItemData->count); + + return Py_BuildValue("i", 0); +} + +PyObject * shopGetItemPrice(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + + const TShopItemData * c_pItemData; + if (CPythonShop::Instance().GetItemData(iIndex, &c_pItemData)) + return Py_BuildValue("i", c_pItemData->price); + + return Py_BuildValue("i", 0); +} + +PyObject * shopGetItemMetinSocket(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + int iMetinSocketIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iMetinSocketIndex)) + return Py_BuildException(); + + const TShopItemData * c_pItemData; + if (CPythonShop::Instance().GetItemData(iIndex, &c_pItemData)) + return Py_BuildValue("i", c_pItemData->alSockets[iMetinSocketIndex]); + + return Py_BuildValue("i", 0); +} + +PyObject * shopGetItemAttribute(PyObject * poSelf, PyObject * poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + int iAttrSlotIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iAttrSlotIndex)) + return Py_BuildException(); + + if (iAttrSlotIndex >= 0 && iAttrSlotIndex < ITEM_ATTRIBUTE_SLOT_MAX_NUM) + { + const TShopItemData * c_pItemData; + if (CPythonShop::Instance().GetItemData(iIndex, &c_pItemData)) + return Py_BuildValue("ii", c_pItemData->aAttr[iAttrSlotIndex].bType, c_pItemData->aAttr[iAttrSlotIndex].sValue); + } + + return Py_BuildValue("ii", 0, 0); +} + +PyObject * shopClearPrivateShopStock(PyObject * poSelf, PyObject * poArgs) +{ + CPythonShop::Instance().ClearPrivateShopStock(); + return Py_BuildNone(); +} +PyObject * shopAddPrivateShopItemStock(PyObject * poSelf, PyObject * poArgs) +{ + BYTE bItemWindowType; + if (!PyTuple_GetInteger(poArgs, 0, &bItemWindowType)) + return Py_BuildException(); + WORD wItemSlotIndex; + if (!PyTuple_GetInteger(poArgs, 1, &wItemSlotIndex)) + return Py_BuildException(); + int iDisplaySlotIndex; + if (!PyTuple_GetInteger(poArgs, 2, &iDisplaySlotIndex)) + return Py_BuildException(); + int iPrice; + if (!PyTuple_GetInteger(poArgs, 3, &iPrice)) + return Py_BuildException(); + + CPythonShop::Instance().AddPrivateShopItemStock(TItemPos(bItemWindowType, wItemSlotIndex), iDisplaySlotIndex, iPrice); + return Py_BuildNone(); +} +PyObject * shopDelPrivateShopItemStock(PyObject * poSelf, PyObject * poArgs) +{ + BYTE bItemWindowType; + if (!PyTuple_GetInteger(poArgs, 0, &bItemWindowType)) + return Py_BuildException(); + WORD wItemSlotIndex; + if (!PyTuple_GetInteger(poArgs, 1, &wItemSlotIndex)) + return Py_BuildException(); + + CPythonShop::Instance().DelPrivateShopItemStock(TItemPos(bItemWindowType, wItemSlotIndex)); + return Py_BuildNone(); +} +PyObject * shopGetPrivateShopItemPrice(PyObject * poSelf, PyObject * poArgs) +{ + BYTE bItemWindowType; + if (!PyTuple_GetInteger(poArgs, 0, &bItemWindowType)) + return Py_BuildException(); + WORD wItemSlotIndex; + if (!PyTuple_GetInteger(poArgs, 1, &wItemSlotIndex)) + return Py_BuildException(); + + int iValue = CPythonShop::Instance().GetPrivateShopItemPrice(TItemPos(bItemWindowType, wItemSlotIndex)); + return Py_BuildValue("i", iValue); +} +PyObject * shopBuildPrivateShop(PyObject * poSelf, PyObject * poArgs) +{ + char * szName; + if (!PyTuple_GetString(poArgs, 0, &szName)) + return Py_BuildException(); + + CPythonShop::Instance().BuildPrivateShop(szName); + return Py_BuildNone(); +} + +PyObject * shopGetTabCount(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonShop::instance().GetTabCount()); +} + +PyObject * shopGetTabName(PyObject * poSelf, PyObject * poArgs) +{ + BYTE bTabIdx; + if (!PyTuple_GetInteger(poArgs, 0, &bTabIdx)) + return Py_BuildException(); + + return Py_BuildValue("s", CPythonShop::instance().GetTabName(bTabIdx)); +} + +PyObject * shopGetTabCoinType(PyObject * poSelf, PyObject * poArgs) +{ + BYTE bTabIdx; + if (!PyTuple_GetInteger(poArgs, 0, &bTabIdx)) + return Py_BuildException(); + + return Py_BuildValue("i", CPythonShop::instance().GetTabCoinType(bTabIdx)); +} + +void initshop() +{ + static PyMethodDef s_methods[] = + { + // Shop + { "Open", shopOpen, METH_VARARGS }, + { "Close", shopClose, METH_VARARGS }, + { "IsOpen", shopIsOpen, METH_VARARGS }, + { "IsPrivateShop", shopIsPrviateShop, METH_VARARGS }, + { "IsMainPlayerPrivateShop", shopIsMainPlayerPrivateShop, METH_VARARGS }, + { "GetItemID", shopGetItemID, METH_VARARGS }, + { "GetItemCount", shopGetItemCount, METH_VARARGS }, + { "GetItemPrice", shopGetItemPrice, METH_VARARGS }, + { "GetItemMetinSocket", shopGetItemMetinSocket, METH_VARARGS }, + { "GetItemAttribute", shopGetItemAttribute, METH_VARARGS }, + { "GetTabCount", shopGetTabCount, METH_VARARGS }, + { "GetTabName", shopGetTabName, METH_VARARGS }, + { "GetTabCoinType", shopGetTabCoinType, METH_VARARGS }, + + // Private Shop + { "ClearPrivateShopStock", shopClearPrivateShopStock, METH_VARARGS }, + { "AddPrivateShopItemStock", shopAddPrivateShopItemStock, METH_VARARGS }, + { "DelPrivateShopItemStock", shopDelPrivateShopItemStock, METH_VARARGS }, + { "GetPrivateShopItemPrice", shopGetPrivateShopItemPrice, METH_VARARGS }, + { "BuildPrivateShop", shopBuildPrivateShop, METH_VARARGS }, + { NULL, NULL, NULL }, + }; + PyObject * poModule = Py_InitModule("shop", s_methods); + + PyModule_AddIntConstant(poModule, "SHOP_SLOT_COUNT", SHOP_HOST_ITEM_MAX_NUM); + PyModule_AddIntConstant(poModule, "SHOP_COIN_TYPE_GOLD", SHOP_COIN_TYPE_GOLD); + PyModule_AddIntConstant(poModule, "SHOP_COIN_TYPE_SECONDARY_COIN", SHOP_COIN_TYPE_SECONDARY_COIN); +} \ No newline at end of file diff --git a/source/UserInterface/PythonShop.h b/source/UserInterface/PythonShop.h new file mode 100644 index 0000000..40ecbf6 --- /dev/null +++ b/source/UserInterface/PythonShop.h @@ -0,0 +1,82 @@ +#pragma once + +#include "Packet.h" + +/* + * ó + * + * 2003-01-16 anoa Ϸ + * 2003-12-26 levites + * + * 2012-10-29 rtsummit ο ȭ tab ߰ shop Ȯ. + * + */ +typedef enum +{ + SHOP_COIN_TYPE_GOLD, // DEFAULT VALUE + SHOP_COIN_TYPE_SECONDARY_COIN, +} EShopCoinType; + +class CPythonShop : public CSingleton +{ + public: + CPythonShop(void); + virtual ~CPythonShop(void); + + void Clear(); + + void SetItemData(DWORD dwIndex, const TShopItemData & c_rShopItemData); + BOOL GetItemData(DWORD dwIndex, const TShopItemData ** c_ppItemData); + + void SetItemData(BYTE tabIdx, DWORD dwSlotPos, const TShopItemData & c_rShopItemData); + BOOL GetItemData(BYTE tabIdx, DWORD dwSlotPos, const TShopItemData ** c_ppItemData); + + void SetTabCount(BYTE bTabCount) { m_bTabCount = bTabCount; } + BYTE GetTabCount() { return m_bTabCount; } + + void SetTabCoinType(BYTE tabIdx, BYTE coinType); + BYTE GetTabCoinType(BYTE tabIdx); + + void SetTabName(BYTE tabIdx, const char* name); + const char* GetTabName(BYTE tabIdx); + + + //BOOL GetSlotItemID(DWORD dwSlotPos, DWORD* pdwItemID); + + void Open(BOOL isPrivateShop, BOOL isMainPrivateShop); + void Close(); + BOOL IsOpen(); + BOOL IsPrivateShop(); + BOOL IsMainPlayerPrivateShop(); + + void ClearPrivateShopStock(); + void AddPrivateShopItemStock(TItemPos ItemPos, BYTE byDisplayPos, DWORD dwPrice); + void DelPrivateShopItemStock(TItemPos ItemPos); + int GetPrivateShopItemPrice(TItemPos ItemPos); + void BuildPrivateShop(const char * c_szName); + + protected: + BOOL CheckSlotIndex(DWORD dwIndex); + + protected: + BOOL m_isShoping; + BOOL m_isPrivateShop; + BOOL m_isMainPlayerPrivateShop; + + struct ShopTab + { + ShopTab() + { + coinType = SHOP_COIN_TYPE_GOLD; + } + BYTE coinType; + std::string name; + TShopItemData items[SHOP_HOST_ITEM_MAX_NUM]; + }; + + BYTE m_bTabCount; + ShopTab m_aShoptabs[SHOP_TAB_COUNT_MAX]; + + typedef std::map TPrivateShopItemStock; + TPrivateShopItemStock m_PrivateShopItemStock; +}; diff --git a/source/UserInterface/PythonSkill.cpp b/source/UserInterface/PythonSkill.cpp new file mode 100644 index 0000000..6410190 --- /dev/null +++ b/source/UserInterface/PythonSkill.cpp @@ -0,0 +1,2256 @@ +#include "StdAfx.h" +#include "PythonSkill.h" + +#include "../EterBase/Poly/Poly.h" +#include "../EterPack/EterPackManager.h" +#include "InstanceBase.h" +#include "PythonPlayer.h" + +std::map CPythonSkill::SSkillData::ms_StatusNameMap; +std::map CPythonSkill::SSkillData::ms_NewMinStatusNameMap; +std::map CPythonSkill::SSkillData::ms_NewMaxStatusNameMap; +DWORD CPythonSkill::SSkillData::ms_dwTimeIncreaseSkillNumber = 0; + +BOOL SKILL_EFFECT_UPGRADE_ENABLE = FALSE; + +int SplitLine(const char * c_szText, CTokenVector* pstTokenVector, const char * c_szDelimeter) +{ + pstTokenVector->reserve(10); + pstTokenVector->clear(); + + std::string stToken; + std::string stLine = c_szText; + + DWORD basePos = 0; + + do + { + int beginPos = stLine.find_first_not_of(c_szDelimeter, basePos); + + if (beginPos < 0) + return -1; + + int endPos; + + if (stLine[beginPos] == '"') + { + ++beginPos; + endPos = stLine.find_first_of("\"", beginPos); + + if (endPos < 0) + return -2; + + basePos = endPos + 1; + } + else + { + endPos = stLine.find_first_of(c_szDelimeter, beginPos); + basePos = endPos; + } + + pstTokenVector->push_back(stLine.substr(beginPos, endPos - beginPos)); + + // ߰ ڵ. ǵڿ ִ 츦 üũѴ. - [levites] + if (int(stLine.find_first_not_of(c_szDelimeter, basePos)) < 0) + break; + } while (basePos < stLine.length()); + + return 0; +} + +// OVERWRITE_SKILLPROTO_POLY +void string_replace_word(const char* base, int base_len, const char* src, int src_len, const char* dst, int dst_len, std::string& result) +{ + result.resize(0); + if (base_len > 0 && dst_len > src_len) + result.reserve(base_len + (dst_len-src_len) * (base_len/src_len)); + else + result.reserve(base_len); + + int prev = 0; + int cur = 0; + while (cur < base_len) + { + if (memcmp(base + cur, src, src_len) == 0) + { + result.append(base + prev, cur - prev); + result.append(dst, dst_len); + cur += src_len; + prev = cur; + } + else + { + ++cur; + } + } + result.append(base + prev, cur - prev); +} +// END_OF_OVERWRITE_SKILLPROTO_POLY + +bool CPythonSkill::RegisterSkillTable(const char * c_szFileName) +{ + const VOID* pvData; + CMappedFile kFile; + if (!CEterPackManager::Instance().Get(kFile, c_szFileName, &pvData)) + return false; + + CMemoryTextFileLoader textFileLoader; + textFileLoader.Bind(kFile.Size(), pvData); + + // OVERWRITE_SKILLPROTO_POLY + std::string src_poly_rand; + std::string src_poly_atk; + std::string src_poly_mwep; + // END_OF_OVERWRITE_SKILLPROTO_POLY + + CTokenVector TokenVector; + for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i) + { + if (!textFileLoader.SplitLineByTab(i, &TokenVector)) + continue; + + std::string strLine = textFileLoader.GetLineString(i); + + if (TABLE_TOKEN_TYPE_MAX_NUM != TokenVector.size()) + { + Tracef("CPythonSkill::RegisterSkillTable(%s) - Strange Token Count [Line:%d / TokenCount:%d]\n", c_szFileName, i, TokenVector.size()); + continue; + } + + int iVnum = atoi(TokenVector[TABLE_TOKEN_TYPE_VNUM].c_str()); + + TSkillDataMap::iterator itor = m_SkillDataMap.find(iVnum); + if (m_SkillDataMap.end() == itor) + { + Tracef("CPythonSkill::RegisterSkillTable(%s) - NOT EXIST SkillDesc [Vnum:%d Line:%d]\n", c_szFileName, iVnum, i); + continue; + } + + TSkillData & rSkillData = itor->second; + + const std::string & c_strSPCostPoly = TokenVector[TABLE_TOKEN_TYPE_SP_COST_POLY]; + if (!c_strSPCostPoly.empty()) + { + rSkillData.strNeedSPFormula = c_strSPCostPoly; + } + + const std::string & c_strCooldownPoly = TokenVector[TABLE_TOKEN_TYPE_COOLDOWN_POLY]; + if (!c_strCooldownPoly.empty()) + { + rSkillData.strCoolTimeFormula = c_strCooldownPoly; + } + + const std::string & c_strDurationSPCostPoly = TokenVector[TABLE_TOKEN_TYPE_DURATION_SP_COST_POLY]; + if (!c_strDurationSPCostPoly.empty()) + { + rSkillData.strContinuationSPFormula = c_strDurationSPCostPoly; + } + + const std::string & c_strTargetRange = TokenVector[TABLE_TOKEN_TYPE_TARGET_RANGE]; + if (!c_strTargetRange.empty()) + { + rSkillData.dwTargetRange = atoi(c_strTargetRange.c_str()); + } + + rSkillData.strDuration = TokenVector[TABLE_TOKEN_TYPE_DURATION_POLY]; + + + const DWORD LevelEmpty = 1; + + const std::string & c_strMaxLevel = TokenVector[TABLE_TOKEN_TYPE_MAX_LEVEL]; + if (!c_strMaxLevel.empty()) + { + int maxLevel = atoi(c_strMaxLevel.c_str()); + if(maxLevel > LevelEmpty) + rSkillData.byMaxLevel = maxLevel; + } + + const std::string & c_strLevelLimit = TokenVector[TABLE_TOKEN_TYPE_LEVEL_LIMIT]; + if (!c_strLevelLimit.empty()) + { + int levelLimit = atoi(c_strLevelLimit.c_str()); + if(rSkillData.byLevelLimit > LevelEmpty) + rSkillData.byLevelLimit = levelLimit; + } + const std::string & c_strPointPoly = TokenVector[TABLE_TOKEN_TYPE_POINT_POLY]; + + // OVERWRITE_SKILLPROTO_POLY + bool USE_SKILL_PROTO = LocaleService_IsCHEONMA() ? false : true; + + switch (iVnum) + { + case 34: + + // GUILD_SKILL_DISPLAY_BUG_FIX + case 151: + case 152: + case 153: + case 154: + case 155: + case 156: + case 157: + // END_OF_GUILD_SKILL_DISPLAY_BUG_FIX + USE_SKILL_PROTO = false; + break; + } + + if (!rSkillData.AffectDataVector.empty() && USE_SKILL_PROTO) + { + TAffectData& affect = rSkillData.AffectDataVector[0]; + + if (strstr(c_strPointPoly.c_str(), "atk") != NULL || + strstr(c_strPointPoly.c_str(), "mwep") != NULL || + strstr(c_strPointPoly.c_str(), "number") != NULL) + { + src_poly_rand = ""; + src_poly_atk = ""; + src_poly_mwep = ""; + + // MIN + string_replace_word(c_strPointPoly.c_str(), c_strPointPoly.length(), + "number", 6, "min", 3, src_poly_rand); + string_replace_word(src_poly_rand.c_str(), src_poly_rand.length(), + "atk", 3, "minatk", 6, src_poly_atk); + string_replace_word(src_poly_atk.c_str(), src_poly_atk.length(), + "mwep", 4, "minmwep", 7, affect.strAffectMinFormula); + // END_OF_MIN + + // MAX + string_replace_word(c_strPointPoly.c_str(), c_strPointPoly.length(), + "number", 6, "max", 3, src_poly_rand); + string_replace_word(src_poly_rand.c_str(), src_poly_rand.length(), + "atk", 3, "maxatk", 6, src_poly_atk); + string_replace_word(src_poly_atk.c_str(), src_poly_atk.length(), + "mwep", 4, "maxmwep", 7, affect.strAffectMaxFormula); + // END_OF_MAX + + switch (iVnum) + { + case 1: // ↓ + affect.strAffectMinFormula += "* 3"; + affect.strAffectMaxFormula += "* 3"; + break; + } + + } + else + { + affect.strAffectMinFormula = c_strPointPoly; + affect.strAffectMaxFormula = ""; + } + } + // END_OF_OVERWRITE_SKILLPROTO_POLY + } + + return true; +} + +void CPythonSkill::__RegisterGradeIconImage(TSkillData & rData, const char * c_szHeader, const char * c_szImageName) +{ + for (int j = 0; j < SKILL_GRADE_COUNT; ++j) + { + TGradeData & rGradeData = rData.GradeData[j]; + + char szCount[8+1]; + _snprintf(szCount, sizeof(szCount), "_%02d", j+1); + + std::string strFileName = ""; + strFileName += c_szHeader; + strFileName += c_szImageName; + strFileName += szCount; + strFileName += ".sub"; + rGradeData.pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer(strFileName.c_str()); + } +} + +void CPythonSkill::__RegisterNormalIconImage(TSkillData & rData, const char * c_szHeader, const char * c_szImageName) +{ + std::string strFileName = ""; + strFileName += c_szHeader; + strFileName += c_szImageName; + strFileName += ".sub"; + rData.pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer(strFileName.c_str()); + for (int j = 0; j < SKILL_GRADE_COUNT; ++j) + { + TGradeData & rGradeData = rData.GradeData[j]; + rGradeData.pImage = rData.pImage; + } +} +extern const DWORD c_iSkillIndex_Riding; +bool CPythonSkill::RegisterSkillDesc(const char * c_szFileName) +{ + const VOID* pvData; + CMappedFile kFile; + if (!CEterPackManager::Instance().Get(kFile, c_szFileName, &pvData)) + return false; + + CMemoryTextFileLoader textFileLoader; + textFileLoader.Bind(kFile.Size(), pvData); + + CTokenVector TokenVector; + for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i) + { + if (!textFileLoader.SplitLineByTab(i, &TokenVector)) + continue; + + if (DESC_TOKEN_TYPE_VNUM >= TokenVector.size()) + { + TraceError("SkillDesc.line(%d).NO_VNUM_ERROR\n", i + 1); + continue; + } + + DWORD iSkillIndex = atoi(TokenVector[DESC_TOKEN_TYPE_VNUM].c_str()); + if (iSkillIndex == 0) + { + TraceError("SkillDesc.line(%d).NO_INDEX_ERROR\n", i + 1); + continue; + } + + if (DESC_TOKEN_TYPE_JOB >= TokenVector.size()) + { + TraceError("SkillDesc.line(%d).NO_JOB_ERROR\n", i + 1); + continue; + } + + m_SkillDataMap.insert(std::make_pair(iSkillIndex, TSkillData())); + TSkillData & rSkillData = m_SkillDataMap[iSkillIndex]; + + // Vnum + rSkillData.dwSkillIndex = iSkillIndex; + + // Type + { + std::string strJob = TokenVector[DESC_TOKEN_TYPE_JOB]; + stl_lowers(strJob); + + std::map::iterator it = m_SkillTypeIndexMap.find(strJob.c_str()); + if (m_SkillTypeIndexMap.end() == it) + { + TraceError("CPythonSkill::RegisterSkillDesc(dwSkillIndex=%d, strType=%s).STRANGE_SKILL_TYPE", iSkillIndex, strJob.c_str()); + continue; + } + + rSkillData.byType = BYTE(it->second); + } + + // Name + { + rSkillData.strName = TokenVector[DESC_TOKEN_TYPE_NAME1]; + rSkillData.GradeData[0].strName = TokenVector[DESC_TOKEN_TYPE_NAME1]; + rSkillData.GradeData[1].strName = TokenVector[DESC_TOKEN_TYPE_NAME2]; + rSkillData.GradeData[2].strName = TokenVector[DESC_TOKEN_TYPE_NAME3]; + + if (rSkillData.GradeData[1].strName.empty()) + rSkillData.GradeData[1].strName = TokenVector[DESC_TOKEN_TYPE_NAME1]; + if (rSkillData.GradeData[2].strName.empty()) + rSkillData.GradeData[2].strName = TokenVector[DESC_TOKEN_TYPE_NAME1]; + } + + // Description + { + rSkillData.strDescription = TokenVector[DESC_TOKEN_TYPE_DESCRIPTION]; + } + + // Condition + { + rSkillData.ConditionDataVector.clear(); + for (int j = 0; j < CONDITION_COLUMN_COUNT; ++j) + { + const std::string & c_rstrCondition = TokenVector[DESC_TOKEN_TYPE_CONDITION1+j]; + if (!c_rstrCondition.empty()) + rSkillData.ConditionDataVector.push_back(c_rstrCondition); + } + } + + // Attribute + { + const std::string & c_rstrAttribute = TokenVector[DESC_TOKEN_TYPE_ATTRIBUTE]; + CTokenVector AttributeTokenVector; + SplitLine(c_rstrAttribute.c_str(), &AttributeTokenVector, "|"); + + for (CTokenVector::iterator it = AttributeTokenVector.begin(); it != AttributeTokenVector.end(); ++it) + { + std::string & rstrToken = *it; + std::map::iterator it2 = m_SkillAttributeIndexMap.find(rstrToken); + if (m_SkillAttributeIndexMap.end() == it2) + { + TraceError("CPythonSkill::RegisterSkillDesc(dwSkillIndex=%d) - Strange Skill Attribute(%s)", iSkillIndex, rstrToken.c_str()); + continue; + } + rSkillData.dwSkillAttribute |= it2->second; + } + } + + // Weapon + { + const std::string & c_rstrWeapon = TokenVector[DESC_TOKEN_TYPE_WEAPON]; + CTokenVector WeaponTokenVector; + SplitLine(c_rstrWeapon.c_str(), &WeaponTokenVector, "|"); + + for (CTokenVector::iterator it = WeaponTokenVector.begin(); it != WeaponTokenVector.end(); ++it) + { + std::string & rstrToken = *it; + std::map::iterator it2 = m_SkillNeedWeaponIndexMap.find(rstrToken); + if (m_SkillNeedWeaponIndexMap.end() == it2) + { + TraceError("CPythonSkill::RegisterSkillDesc(dwSkillIndex=%d) - Strange Skill Need Weapon(%s)", iSkillIndex, rstrToken.c_str()); + continue; + } + rSkillData.dwNeedWeapon |= it2->second; + } + } + + // Icon Name + { + const std::string & c_rstrJob = TokenVector[DESC_TOKEN_TYPE_JOB]; + const std::string & c_rstrIconName = TokenVector[DESC_TOKEN_TYPE_ICON_NAME]; + + // NOTE : Support ųӿ 3ܰ踦 ؾ ؼ ó - [levites] + if (c_iSkillIndex_Riding == iSkillIndex) + { + char szIconFileNameHeader[64+1]; + _snprintf(szIconFileNameHeader, sizeof(szIconFileNameHeader), "%sskill/common/support/", g_strImagePath.c_str()); + + __RegisterGradeIconImage(rSkillData, szIconFileNameHeader, c_rstrIconName.c_str()); + } + else if (m_PathNameMap.end() != m_PathNameMap.find(c_rstrJob)) + { + char szIconFileNameHeader[64+1]; + _snprintf(szIconFileNameHeader, sizeof(szIconFileNameHeader), "%sskill/%s/", g_strImagePath.c_str(), m_PathNameMap[c_rstrJob].c_str()); + + switch (rSkillData.byType) + { + case SKILL_TYPE_ACTIVE: + { + __RegisterGradeIconImage(rSkillData, szIconFileNameHeader, c_rstrIconName.c_str()); + break; + } + case SKILL_TYPE_SUPPORT: + case SKILL_TYPE_GUILD: + case SKILL_TYPE_HORSE: + { + __RegisterNormalIconImage(rSkillData, szIconFileNameHeader, c_rstrIconName.c_str()); + break; + } + } + } + } + + // Motion Index + if (TokenVector.size() > DESC_TOKEN_TYPE_MOTION_INDEX) + { + const std::string & c_rstrMotionIndex = TokenVector[DESC_TOKEN_TYPE_MOTION_INDEX]; + if (c_rstrMotionIndex.empty()) + { + rSkillData.bNoMotion = TRUE; + rSkillData.wMotionIndex = 0; + } + else + { + rSkillData.bNoMotion = FALSE; + rSkillData.wMotionIndex = (WORD)atoi(c_rstrMotionIndex.c_str()); + } + } + else + { + rSkillData.wMotionIndex = 0; + } + + if (TokenVector.size() > DESC_TOKEN_TYPE_TARGET_COUNT_FORMULA) + rSkillData.strTargetCountFormula = TokenVector[DESC_TOKEN_TYPE_TARGET_COUNT_FORMULA].c_str(); + if (TokenVector.size() > DESC_TOKEN_TYPE_MOTION_LOOP_COUNT_FORMULA) + rSkillData.strMotionLoopCountFormula = TokenVector[DESC_TOKEN_TYPE_MOTION_LOOP_COUNT_FORMULA].c_str(); + + rSkillData.AffectDataNewVector.clear(); + rSkillData.AffectDataNewVector.reserve(3); + + // Affect + for (int j = 0; j < AFFECT_COLUMN_COUNT; ++j) + { + int iDescriptionSlotIndex = DESC_TOKEN_TYPE_AFFECT_DESCRIPTION_1 + j*AFFECT_STEP_COUNT; + int iMinSlotIndex = DESC_TOKEN_TYPE_AFFECT_MIN_1 + j*AFFECT_STEP_COUNT; + int iMaxSlotIndex = DESC_TOKEN_TYPE_AFFECT_MAX_1 + j*AFFECT_STEP_COUNT; + + if (TokenVector.size() > iDescriptionSlotIndex) + if (!TokenVector[iDescriptionSlotIndex].empty()) + { + rSkillData.AffectDataVector.push_back(TAffectData()); + + TAffectData & rAffectData = *rSkillData.AffectDataVector.rbegin(); + rAffectData.strAffectDescription = ""; + rAffectData.strAffectMinFormula = ""; + rAffectData.strAffectMaxFormula = ""; + + rAffectData.strAffectDescription = TokenVector[iDescriptionSlotIndex]; + if (TokenVector.size() > iMinSlotIndex) + if (!TokenVector[iMinSlotIndex].empty()) + rAffectData.strAffectMinFormula = TokenVector[iMinSlotIndex]; + if (TokenVector.size() > iMaxSlotIndex) + if (!TokenVector[iMaxSlotIndex].empty()) + rAffectData.strAffectMaxFormula = TokenVector[iMaxSlotIndex]; + } + } + + if (TokenVector.size() > DESC_TOKEN_TYPE_MOTION_INDEX_GRADE_NUM) + { + int numGrade = atoi(TokenVector[DESC_TOKEN_TYPE_MOTION_INDEX_GRADE_NUM].c_str()); + if (SKILL_EFFECT_COUNT < numGrade) + { + TraceError("%s[%s] [%d] Ѿϴ.",rSkillData.strName.c_str(), TokenVector[DESC_TOKEN_TYPE_MOTION_INDEX_GRADE_NUM].c_str(), SKILL_EFFECT_COUNT); + return false; + } + for (int iGrade = 0; iGrade < numGrade; iGrade++) + { + //if (iGrade == SKILL_GRADE_COUNT) + // rSkillData.GradeData[iGrade] = rSkillData.GradeData[iGrade-1]; + rSkillData.GradeData[iGrade].wMotionIndex = rSkillData.wMotionIndex+iGrade*SKILL_GRADEGAP; + } + for(int iSpace = numGrade; iSpace < SKILL_EFFECT_COUNT; iSpace++) + { + rSkillData.GradeData[iSpace].wMotionIndex = rSkillData.wMotionIndex; + } + } + + if (TokenVector.size() > DESC_TOKEN_TYPE_LEVEL_LIMIT) + { + const std::string & c_rstrLevelLimit = TokenVector[DESC_TOKEN_TYPE_LEVEL_LIMIT]; + if (c_rstrLevelLimit.empty()) + rSkillData.byLevelLimit = 0; + else + rSkillData.byLevelLimit = (WORD)atoi(c_rstrLevelLimit.c_str()); + } + + if (TokenVector.size() > DESC_TOKEN_TYPE_MAX_LEVEL) + { + const std::string & c_rstrMaxLevel = TokenVector[DESC_TOKEN_TYPE_MAX_LEVEL]; + const DWORD LevelLimitEmpty = 1; + if (c_rstrMaxLevel.empty()) + { + if(rSkillData.byLevelLimit > LevelLimitEmpty) + rSkillData.byMaxLevel = rSkillData.byLevelLimit; + else + rSkillData.byMaxLevel = 20; + } + else + rSkillData.byMaxLevel = (BYTE)atoi(c_rstrMaxLevel.c_str()); + } + } + + return true; +} + +void CPythonSkill::Destroy() +{ + m_SkillDataMap.clear(); +} + +bool CPythonSkill::RegisterSkill(DWORD dwSkillIndex, const char * c_szFileName) +{ + CTextFileLoader TextFileLoader; + if (!TextFileLoader.Load(c_szFileName)) + { + TraceError("CPythonSkill::RegisterSkill(dwSkillIndex=%d, c_szFileName=%s) - Failed to find file", dwSkillIndex, c_szFileName); + return false; + } + + TextFileLoader.SetTop(); + + TSkillData SkillData; + SkillData.dwSkillIndex = dwSkillIndex; + + std::string strTypeName; + if (TextFileLoader.GetTokenString("type", &strTypeName)) + { + stl_lowers(strTypeName); + std::map::iterator it = m_SkillTypeIndexMap.find(strTypeName.c_str()); + if (m_SkillTypeIndexMap.end() == it) + { + TraceError("Strange Skill Type - CPythonSkill::RegisterSkill(dwSkillIndex=%d, c_szFileName=%s)", dwSkillIndex, c_szFileName); + return false; + } + + SkillData.byType = (BYTE)it->second; + } + else + { + TraceError("CPythonSkill::RegisterSkill(dwSkillIndex=%d, c_szFileName=%s) - Failed to find key [type]", dwSkillIndex, c_szFileName); + return false; + } + + CTokenVector * pAttributeTokenVector; + if (TextFileLoader.GetTokenVector("attribute", &pAttributeTokenVector)) + { + for (CTokenVector::iterator it = pAttributeTokenVector->begin(); it != pAttributeTokenVector->end(); ++it) + { + std::string & rstrToken = *it; + std::map::iterator it2 = m_SkillAttributeIndexMap.find(rstrToken.c_str()); + if (m_SkillAttributeIndexMap.end() == it2) + { + TraceError("Strange Skill Attribute - CPythonSkill::RegisterSkill(dwSkillIndex=%d, c_szFileName=%s)", dwSkillIndex, c_szFileName); + continue; + } + SkillData.dwSkillAttribute |= it2->second; + } + } + + CTokenVector * pNeedWeaponVector; + if (TextFileLoader.GetTokenVector("needweapon", &pNeedWeaponVector)) + { + for (CTokenVector::iterator it = pNeedWeaponVector->begin(); it != pNeedWeaponVector->end(); ++it) + { + std::string & rstrToken = *it; + std::map::iterator it2 = m_SkillNeedWeaponIndexMap.find(rstrToken.c_str()); + if (m_SkillNeedWeaponIndexMap.end() == it2) + { + TraceError("Strange Skill Need Weapon - CPythonSkill::RegisterSkill(dwSkillIndex=%d, c_szFileName=%s)", dwSkillIndex, c_szFileName); + continue; + } + SkillData.dwNeedWeapon |= it2->second; + } + } + + { + char szName[256]; + sprintf(szName, "%dname", LocaleService_GetCodePage()); + if (!TextFileLoader.GetTokenString(szName, &SkillData.strName)) + if (!TextFileLoader.GetTokenString("name", &SkillData.strName)) + { + TraceError("CPythonSkill::RegisterSkill(dwSkillIndex=%d, c_szFileName=%s) - Failed to find [%s]", dwSkillIndex, c_szFileName, szName); + return false; + } + } + + { + char szName[256]; + sprintf(szName, "%ddescription", LocaleService_GetCodePage()); + if (!TextFileLoader.GetTokenString(szName, &SkillData.strDescription)) + TextFileLoader.GetTokenString("description", &SkillData.strDescription); + } + + if (!TextFileLoader.GetTokenString("iconfilename", &SkillData.strIconFileName)) + { + TraceError("CPythonSkill::RegisterSkill(dwSkillIndex=%d, c_szFileName=%s) - Failed to find [iconfilename]", dwSkillIndex, c_szFileName); + return false; + } + + { + CTokenVector * pConditionDataVector; + + char szConditionData[256]; + sprintf(szConditionData, "%dconditiondata", LocaleService_GetCodePage()); + + bool isConditionData=true; + if (!TextFileLoader.GetTokenVector(szConditionData, &pConditionDataVector)) + if (!TextFileLoader.GetTokenVector("conditiondata", &pConditionDataVector)) + isConditionData=false; + + if (isConditionData) + { + DWORD dwSize = pConditionDataVector->size(); + SkillData.ConditionDataVector.clear(); + SkillData.ConditionDataVector.resize(dwSize); + for (DWORD i = 0; i < dwSize; ++i) + { + SkillData.ConditionDataVector[i] = pConditionDataVector->at(i); + } + } + } + + { + CTokenVector * pAffectDataVector; + + char szAffectData[256]; + sprintf(szAffectData, "%daffectdata", LocaleService_GetCodePage()); + + bool isAffectData=true; + if (!TextFileLoader.GetTokenVector(szAffectData, &pAffectDataVector)) + if (!TextFileLoader.GetTokenVector("affectdata", &pAffectDataVector)) + isAffectData=false; + + if (isAffectData) + { + DWORD dwSize = pAffectDataVector->size()/3; + SkillData.AffectDataVector.clear(); + SkillData.AffectDataVector.resize(dwSize); + for (DWORD i = 0; i < dwSize; ++i) + { + SkillData.AffectDataVector[i].strAffectDescription = pAffectDataVector->at(i*3+0); + SkillData.AffectDataVector[i].strAffectMinFormula = pAffectDataVector->at(i*3+1); + SkillData.AffectDataVector[i].strAffectMaxFormula = pAffectDataVector->at(i*3+2); + } + } + } + + { + CTokenVector * pGradeDataVector; + + char szGradeData[256]; + sprintf(szGradeData, "%dgradedata", LocaleService_GetCodePage()); + + if (TextFileLoader.GetTokenVector(szGradeData, &pGradeDataVector)) + { + if (SKILL_GRADE_COUNT*2 != pGradeDataVector->size()) + TraceError("CPythonSkill::RegisterSkill(dwSkillIndex=%d, c_szFileName=%s) - Strange Grade Data Count", dwSkillIndex, c_szFileName); + + for (DWORD i = 0; i < min(SKILL_GRADE_COUNT, pGradeDataVector->size()/2); ++i) + { + SkillData.GradeData[i].strName = pGradeDataVector->at(i*2+0); + std::string strIconFileName = g_strImagePath + pGradeDataVector->at(i*2+1); + SkillData.GradeData[i].pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer(strIconFileName.c_str()); + } + } + } + + TextFileLoader.GetTokenString("cooltimeformula", &SkillData.strCoolTimeFormula); + TextFileLoader.GetTokenString("targetcountformula", &SkillData.strTargetCountFormula); + TextFileLoader.GetTokenString("motionloopcountformula", &SkillData.strMotionLoopCountFormula); + TextFileLoader.GetTokenString("needspformula", &SkillData.strNeedSPFormula); + TextFileLoader.GetTokenString("continuationspformula", &SkillData.strContinuationSPFormula); + TextFileLoader.GetTokenDoubleWord("range", &SkillData.dwTargetRange); + TextFileLoader.GetTokenByte("maxlevel", &SkillData.byMaxLevel); + TextFileLoader.GetTokenByte("leveluppoint", &SkillData.byLevelUpPoint); + + WORD wMotionIndex; + if (TextFileLoader.GetTokenWord("motionindex", &wMotionIndex)) + { + SkillData.wMotionIndex = wMotionIndex; + } + else + { + SkillData.wMotionIndex = 0; + } + + WORD wMotionIndexForMe; + if (TextFileLoader.GetTokenWord("motionindexforme", &wMotionIndexForMe)) + { + SkillData.wMotionIndexForMe = wMotionIndexForMe; + } + else + { + SkillData.wMotionIndexForMe = 0; + } + + SkillData.strIconFileName = g_strImagePath + SkillData.strIconFileName; + SkillData.pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer(SkillData.strIconFileName.c_str()); + + m_SkillDataMap.insert(TSkillDataMap::value_type(dwSkillIndex, SkillData)); + + ///// + + if (SkillData.IsTimeIncreaseSkill()) + { + CPythonSkill::SSkillData::ms_dwTimeIncreaseSkillNumber = SkillData.dwSkillIndex; + } + + return true; +} + +BOOL CPythonSkill::GetSkillData(DWORD dwSkillIndex, TSkillData ** ppSkillData) +{ + TSkillDataMap::iterator it = m_SkillDataMap.find(dwSkillIndex); + + if (m_SkillDataMap.end() == it) + return FALSE; + + *ppSkillData = &(it->second); + return TRUE; +} + +bool CPythonSkill::GetSkillDataByName(const char * c_szName, TSkillData ** ppSkillData) +{ + TSkillDataMap::iterator itor = m_SkillDataMap.begin(); + for (; itor != m_SkillDataMap.end(); ++itor) + { + TSkillData * pData = &(itor->second); + if (0 == pData->strName.compare(c_szName)) + { + *ppSkillData = &(itor->second); + return true; + } + } + return false; +} + +void CPythonSkill::SetPathName(const char * c_szFileName) +{ + m_strPathName = c_szFileName; +} + +const char * CPythonSkill::GetPathName() +{ + return m_strPathName.c_str(); +} + +void CPythonSkill::TEST() +{ + BOOL isFirst; + std::map::iterator itorSub; + + FILE * File = fopen("test.txt", "w"); + + for (TSkillDataMap::iterator itor = m_SkillDataMap.begin(); itor != m_SkillDataMap.end(); ++itor) + { + TSkillData & rSkillData = itor->second; + + std::string strLine = ""; + strLine += rSkillData.strName.c_str(); + strLine += "\t"; + // Name2 + strLine += "\t"; + // Name3 + strLine += "\t"; + strLine += rSkillData.strDescription; + strLine += "\t"; + if (rSkillData.ConditionDataVector.size() > 0) + strLine += rSkillData.ConditionDataVector[0]; + strLine += "\t"; + if (rSkillData.ConditionDataVector.size() > 1) + strLine += rSkillData.ConditionDataVector[1]; + strLine += "\t"; + if (rSkillData.ConditionDataVector.size() > 2) + strLine += rSkillData.ConditionDataVector[2]; + strLine += "\t"; + if (rSkillData.ConditionDataVector.size() > 3) + strLine += rSkillData.ConditionDataVector[3]; + + strLine += "\t"; + isFirst = TRUE; + for (itorSub = m_SkillAttributeIndexMap.begin(); itorSub != m_SkillAttributeIndexMap.end(); ++itorSub) + { + if (itorSub->second & rSkillData.dwSkillAttribute) + { + if (isFirst) + { + isFirst = FALSE; + } + else + { + strLine += "|"; + } + strLine += itorSub->first.c_str(); + } + } + + strLine += "\t"; + isFirst = TRUE; + for (itorSub = m_SkillNeedWeaponIndexMap.begin(); itorSub != m_SkillNeedWeaponIndexMap.end(); ++itorSub) + { + if (itorSub->second & rSkillData.dwNeedWeapon) + { + if (isFirst) + { + isFirst = FALSE; + } + else + { + strLine += "|"; + } + strLine += itorSub->first.c_str(); + } + } + + strLine += "\t"; + std::string strFileName = rSkillData.strIconFileName; + int iPos = strFileName.find_last_of("/", rSkillData.strIconFileName.length()); + if (iPos > 0) + strFileName = strFileName.substr(iPos+1, strFileName.length() - iPos - 4 - 1); + strLine += strFileName; + + strLine += "\t"; + char szMotionIndex[32+1]; + _snprintf(szMotionIndex, sizeof(szMotionIndex), "%d", rSkillData.wMotionIndex); + strLine += szMotionIndex; + + strLine += "\t"; + if (rSkillData.wMotionIndexForMe > 1) + { + char szMotionIndexForMe[32+1]; + _snprintf(szMotionIndexForMe, sizeof(szMotionIndexForMe), "%d", rSkillData.wMotionIndexForMe); + strLine += szMotionIndexForMe; + } + + assert(rSkillData.AffectDataVector.size() <= 3); + strLine += "\t"; + if (rSkillData.AffectDataVector.size() > 0) + { + strLine += rSkillData.AffectDataVector[0].strAffectDescription; + strLine += "\t"; + strLine += rSkillData.AffectDataVector[0].strAffectMinFormula; + strLine += "\t"; + strLine += rSkillData.AffectDataVector[0].strAffectMaxFormula; + } + strLine += "\t"; + if (rSkillData.AffectDataVector.size() > 1) + { + strLine += rSkillData.AffectDataVector[1].strAffectDescription; + strLine += "\t"; + strLine += rSkillData.AffectDataVector[1].strAffectMinFormula; + strLine += "\t"; + strLine += rSkillData.AffectDataVector[1].strAffectMaxFormula; + } + strLine += "\t"; + if (rSkillData.AffectDataVector.size() > 2) + { + strLine += rSkillData.AffectDataVector[2].strAffectDescription; + strLine += "\t"; + strLine += rSkillData.AffectDataVector[2].strAffectMinFormula; + strLine += "\t"; + strLine += rSkillData.AffectDataVector[2].strAffectMaxFormula; + } + + fprintf(File, "%s\n", strLine.c_str()); + } + + fclose(File); +} + +CPythonSkill::CPythonSkill() +{ + m_SkillTypeIndexMap.insert(std::map::value_type("none", SKILL_TYPE_NONE)); + m_SkillTypeIndexMap.insert(std::map::value_type("active", SKILL_TYPE_ACTIVE)); + m_SkillTypeIndexMap.insert(std::map::value_type("support", SKILL_TYPE_SUPPORT)); + m_SkillTypeIndexMap.insert(std::map::value_type("guild", SKILL_TYPE_GUILD)); + m_SkillTypeIndexMap.insert(std::map::value_type("horse", SKILL_TYPE_HORSE)); + m_SkillTypeIndexMap.insert(std::map::value_type("warrior", SKILL_TYPE_ACTIVE)); + m_SkillTypeIndexMap.insert(std::map::value_type("assassin", SKILL_TYPE_ACTIVE)); + m_SkillTypeIndexMap.insert(std::map::value_type("sura", SKILL_TYPE_ACTIVE)); + m_SkillTypeIndexMap.insert(std::map::value_type("shaman", SKILL_TYPE_ACTIVE)); + m_SkillTypeIndexMap.insert(std::map::value_type("passive", SKILL_TYPE_ACTIVE)); + + m_SkillAttributeIndexMap.insert(std::map::value_type("NEED_POISON_BOTTLE", SKILL_ATTRIBUTE_NEED_POISON_BOTTLE)); + m_SkillAttributeIndexMap.insert(std::map::value_type("NEED_EMPTY_BOTTLE", SKILL_ATTRIBUTE_NEED_EMPTY_BOTTLE)); + m_SkillAttributeIndexMap.insert(std::map::value_type("CAN_USE_IF_NOT_ENOUGH", SKILL_ATTRIBUTE_CAN_USE_IF_NOT_ENOUGH)); + m_SkillAttributeIndexMap.insert(std::map::value_type("FAN_RANGE", SKILL_ATTRIBUTE_FAN_RANGE)); + m_SkillAttributeIndexMap.insert(std::map::value_type("NEED_CORPSE", SKILL_ATTRIBUTE_NEED_CORPSE)); + m_SkillAttributeIndexMap.insert(std::map::value_type("NEED_TARGET", SKILL_ATTRIBUTE_NEED_TARGET)); + m_SkillAttributeIndexMap.insert(std::map::value_type("TOGGLE", SKILL_ATTRIBUTE_TOGGLE)); + m_SkillAttributeIndexMap.insert(std::map::value_type("WEAPON_LIMITATION", SKILL_ATTRIBUTE_WEAPON_LIMITATION)); + m_SkillAttributeIndexMap.insert(std::map::value_type("MELEE_ATTACK", SKILL_ATTRIBUTE_MELEE_ATTACK)); + m_SkillAttributeIndexMap.insert(std::map::value_type("CHARGE_ATTACK", SKILL_ATTRIBUTE_CHARGE_ATTACK)); + m_SkillAttributeIndexMap.insert(std::map::value_type("USE_HP", SKILL_ATTRIBUTE_USE_HP)); + m_SkillAttributeIndexMap.insert(std::map::value_type("CAN_CHANGE_DIRECTION", SKILL_ATTRIBUTE_CAN_CHANGE_DIRECTION)); + m_SkillAttributeIndexMap.insert(std::map::value_type("STANDING_SKILL", SKILL_ATTRIBUTE_STANDING_SKILL)); + m_SkillAttributeIndexMap.insert(std::map::value_type("ONLY_FOR_ALLIANCE", SKILL_ATTRIBUTE_ONLY_FOR_ALLIANCE)); + m_SkillAttributeIndexMap.insert(std::map::value_type("CAN_USE_FOR_ME", SKILL_ATTRIBUTE_CAN_USE_FOR_ME)); + m_SkillAttributeIndexMap.insert(std::map::value_type("ATTACK_SKILL", SKILL_ATTRIBUTE_ATTACK_SKILL)); + m_SkillAttributeIndexMap.insert(std::map::value_type("MOVING_SKILL", SKILL_ATTRIBUTE_MOVING_SKILL)); + m_SkillAttributeIndexMap.insert(std::map::value_type("HORSE_SKILL", SKILL_ATTRIBUTE_HORSE_SKILL)); + m_SkillAttributeIndexMap.insert(std::map::value_type("TIME_INCREASE_SKILL", SKILL_ATTRIBUTE_TIME_INCREASE_SKILL)); + m_SkillAttributeIndexMap.insert(std::map::value_type("PASSIVE", SKILL_ATTRIBUTE_PASSIVE)); + m_SkillAttributeIndexMap.insert(std::map::value_type("CANNOT_LEVEL_UP", SKILL_ATTRIBUTE_CANNOT_LEVEL_UP)); + m_SkillAttributeIndexMap.insert(std::map::value_type("ONLY_FOR_GUILD_WAR", SKILL_ATTRIBUTE_ONLY_FOR_GUILD_WAR)); + m_SkillAttributeIndexMap.insert(std::map::value_type("CIRCLE_RANGE", SKILL_ATTRIBUTE_CIRCLE_RANGE)); + m_SkillAttributeIndexMap.insert(std::map::value_type("SEARCH_TARGET", SKILL_ATTRIBUTE_SEARCH_TARGET)); + + m_SkillNeedWeaponIndexMap.insert(std::map::value_type("SWORD", SKILL_NEED_WEAPON_SWORD)); + m_SkillNeedWeaponIndexMap.insert(std::map::value_type("DAGGER", SKILL_NEED_WEAPON_DAGGER)); + m_SkillNeedWeaponIndexMap.insert(std::map::value_type("BOW", SKILL_NEED_WEAPON_BOW)); + m_SkillNeedWeaponIndexMap.insert(std::map::value_type("TWO_HANDED", SKILL_NEED_WEAPON_TWO_HANDED)); + m_SkillNeedWeaponIndexMap.insert(std::map::value_type("DOUBLE_SWORD", SKILL_NEED_WEAPON_DOUBLE_SWORD)); + m_SkillNeedWeaponIndexMap.insert(std::map::value_type("BELL", SKILL_NEED_WEAPON_BELL)); + m_SkillNeedWeaponIndexMap.insert(std::map::value_type("FAN", SKILL_NEED_WEAPON_FAN)); + m_SkillNeedWeaponIndexMap.insert(std::map::value_type("ARROW", SKILL_NEED_WEAPON_ARROW)); + m_SkillNeedWeaponIndexMap.insert(std::map::value_type("EMPTY_HAND", SKILL_NEED_WEAPON_EMPTY_HAND)); + + m_SkillWeaponTypeIndexMap.insert(std::make_pair(std::string("SWORD"), CItemData::WEAPON_SWORD)); + m_SkillWeaponTypeIndexMap.insert(std::make_pair(std::string("DAGGER"), CItemData::WEAPON_DAGGER)); + m_SkillWeaponTypeIndexMap.insert(std::make_pair(std::string("BOW"), CItemData::WEAPON_BOW)); + m_SkillWeaponTypeIndexMap.insert(std::make_pair(std::string("TWO_HANDED"), CItemData::WEAPON_TWO_HANDED)); + m_SkillWeaponTypeIndexMap.insert(std::make_pair(std::string("DOUBLE_SWORD"), CItemData::WEAPON_DAGGER)); + m_SkillWeaponTypeIndexMap.insert(std::make_pair(std::string("BELL"), CItemData::WEAPON_BELL)); + m_SkillWeaponTypeIndexMap.insert(std::make_pair(std::string("FAN"), CItemData::WEAPON_FAN)); + m_SkillWeaponTypeIndexMap.insert(std::make_pair(std::string("ARROW"), CItemData::WEAPON_ARROW)); + + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("chain"), POINT_NONE)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("HR"), POINT_HIT_RATE)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("LV"), POINT_LEVEL)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("Level"), POINT_LEVEL)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("MaxHP"), POINT_MAX_HP)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("MaxSP"), POINT_MAX_SP)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("MinMWEP"), POINT_MIN_WEP)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("MaxMWEP"), POINT_MAX_WEP)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("MinWEP"), POINT_MIN_WEP)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("MaxWEP"), POINT_MAX_WEP)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("MinATK"), POINT_MIN_ATK)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("MaxATK"), POINT_MAX_ATK)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("ATKSPD"), POINT_ATT_SPEED)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("AttackPower"), POINT_MIN_ATK)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("AtkMin"), POINT_MIN_ATK)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("AtkMax"), POINT_MAX_ATK)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("DefencePower"), POINT_DEF_GRADE)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("DEF"), POINT_DEF_GRADE)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("MWEP"), POINT_MAGIC_ATT_GRADE)); + + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("MagicAttackPower"), POINT_MAGIC_ATT_GRADE)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("INT"), POINT_IQ)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("STR"), POINT_ST)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("DEX"), POINT_DX)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("CON"), POINT_HT)); + + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("minatk"), POINT_MIN_ATK)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("maxatk"), POINT_MAX_ATK)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("minmtk"), POINT_MIN_WEP)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("maxmtk"), POINT_MAX_WEP)); + + // GUILD_SKILL_DISPLAY_BUG_FIX + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("maxhp"), POINT_MAX_HP)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("maxsp"), POINT_MAX_SP)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("odef"), POINT_DEF_GRADE)); + // END_OF_GUILD_SKILL_DISPLAY_BUG_FIX + + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("minwep"), POINT_MIN_WEP)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("maxwep"), POINT_MAX_WEP)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("minmwep"), POINT_MIN_MAGIC_WEP)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("maxmwep"), POINT_MAX_MAGIC_WEP)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("lv"), POINT_LEVEL)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("ar"), POINT_HIT_RATE)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("iq"), POINT_IQ)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("str"), POINT_ST)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("dex"), POINT_DX)); + SSkillData::ms_StatusNameMap.insert(std::make_pair(std::string("con"), POINT_HT)); + + ///// + + SSkillData::ms_NewMinStatusNameMap.insert(std::make_pair(std::string("atk"), POINT_MIN_ATK)); + SSkillData::ms_NewMinStatusNameMap.insert(std::make_pair(std::string("mtk"), POINT_MIN_WEP)); + SSkillData::ms_NewMinStatusNameMap.insert(std::make_pair(std::string("wep"), POINT_MIN_WEP)); + SSkillData::ms_NewMinStatusNameMap.insert(std::make_pair(std::string("lv"), POINT_LEVEL)); + SSkillData::ms_NewMinStatusNameMap.insert(std::make_pair(std::string("ar"), POINT_HIT_RATE)); + SSkillData::ms_NewMinStatusNameMap.insert(std::make_pair(std::string("iq"), POINT_IQ)); + SSkillData::ms_NewMinStatusNameMap.insert(std::make_pair(std::string("str"), POINT_ST)); + SSkillData::ms_NewMinStatusNameMap.insert(std::make_pair(std::string("dex"), POINT_DX)); + SSkillData::ms_NewMinStatusNameMap.insert(std::make_pair(std::string("con"), POINT_HT)); + + SSkillData::ms_NewMaxStatusNameMap.insert(std::make_pair(std::string("atk"), POINT_MAX_ATK)); + SSkillData::ms_NewMaxStatusNameMap.insert(std::make_pair(std::string("mtk"), POINT_MAX_WEP)); + SSkillData::ms_NewMinStatusNameMap.insert(std::make_pair(std::string("wep"), POINT_MAX_WEP)); + SSkillData::ms_NewMaxStatusNameMap.insert(std::make_pair(std::string("lv"), POINT_LEVEL)); + SSkillData::ms_NewMaxStatusNameMap.insert(std::make_pair(std::string("ar"), POINT_HIT_RATE)); + SSkillData::ms_NewMaxStatusNameMap.insert(std::make_pair(std::string("iq"), POINT_IQ)); + SSkillData::ms_NewMaxStatusNameMap.insert(std::make_pair(std::string("str"), POINT_ST)); + SSkillData::ms_NewMaxStatusNameMap.insert(std::make_pair(std::string("dex"), POINT_DX)); + SSkillData::ms_NewMaxStatusNameMap.insert(std::make_pair(std::string("con"), POINT_HT)); + + m_PathNameMap.insert(std::make_pair(std::string("WARRIOR"), std::string("warrior"))); + m_PathNameMap.insert(std::make_pair(std::string("ASSASSIN"), std::string("assassin"))); + m_PathNameMap.insert(std::make_pair(std::string("SURA"), std::string("sura"))); + m_PathNameMap.insert(std::make_pair(std::string("SHAMAN"), std::string("shaman"))); + m_PathNameMap.insert(std::make_pair(std::string("PASSIVE"), std::string("passive"))); + m_PathNameMap.insert(std::make_pair(std::string("SUPPORT"), std::string("common/support"))); + m_PathNameMap.insert(std::make_pair(std::string("GUILD"), std::string("common/guild"))); + m_PathNameMap.insert(std::make_pair(std::string("HORSE"), std::string("common/horse"))); +} +CPythonSkill::~CPythonSkill() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// + +DWORD CPythonSkill::SSkillData::MELEE_SKILL_TARGET_RANGE=170; + +const std::string CPythonSkill::SSkillData::GetName() const +{ + return strName; +} + +BYTE CPythonSkill::SSkillData::GetType() const +{ + return byType; +} + +BOOL CPythonSkill::SSkillData::IsMeleeSkill() +{ + if (dwSkillAttribute & SKILL_ATTRIBUTE_MELEE_ATTACK) + return TRUE; + + return FALSE; +} + +BOOL CPythonSkill::SSkillData::IsChargeSkill() +{ + if (dwSkillAttribute & SKILL_ATTRIBUTE_CHARGE_ATTACK) + return TRUE; + + return FALSE; +} + +BOOL CPythonSkill::SSkillData::IsOnlyForGuildWar() +{ + if (dwSkillAttribute & SKILL_ATTRIBUTE_ONLY_FOR_GUILD_WAR) + return TRUE; + + return FALSE; +} + +DWORD CPythonSkill::SSkillData::GetTargetRange() const +{ + if (dwSkillAttribute & SKILL_ATTRIBUTE_MELEE_ATTACK) + return MELEE_SKILL_TARGET_RANGE; + + if (dwSkillAttribute & SKILL_ATTRIBUTE_CHARGE_ATTACK) + return MELEE_SKILL_TARGET_RANGE; + + return dwTargetRange; +} + +BOOL CPythonSkill::SSkillData::CanChangeDirection() +{ + return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_CAN_CHANGE_DIRECTION); +} + +BOOL CPythonSkill::SSkillData::IsFanRange() +{ + return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_FAN_RANGE); +} + +BOOL CPythonSkill::SSkillData::IsCircleRange() +{ + return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_CIRCLE_RANGE); +} + +BOOL CPythonSkill::SSkillData::IsAutoSearchTarget() +{ + return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_SEARCH_TARGET); +} + +BOOL CPythonSkill::SSkillData::IsNeedCorpse() +{ + return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_NEED_CORPSE); +} + +BOOL CPythonSkill::SSkillData::IsNeedTarget() +{ + return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_NEED_TARGET); +} + +BOOL CPythonSkill::SSkillData::IsToggleSkill() +{ + return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_TOGGLE); +} + +BOOL CPythonSkill::SSkillData::IsUseHPSkill() +{ + return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_USE_HP); +} + +BOOL CPythonSkill::SSkillData::IsStandingSkill() +{ + return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_STANDING_SKILL); +} + +BOOL CPythonSkill::SSkillData::CanUseWeaponType(DWORD dwWeaponType) +{ + if (!(dwSkillAttribute & SKILL_ATTRIBUTE_WEAPON_LIMITATION)) + return TRUE; + + return 0 != (dwNeedWeapon & (1 << dwWeaponType)); +} + +BOOL CPythonSkill::SSkillData::IsOnlyForAlliance() +{ + return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_ONLY_FOR_ALLIANCE); +} + +BOOL CPythonSkill::SSkillData::CanUseForMe() +{ + return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_CAN_USE_FOR_ME); +} + +BOOL CPythonSkill::SSkillData::CanUseIfNotEnough() +{ + return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_CAN_USE_IF_NOT_ENOUGH); +} + +BOOL CPythonSkill::SSkillData::IsNeedEmptyBottle() +{ + return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_NEED_EMPTY_BOTTLE); +} + +BOOL CPythonSkill::SSkillData::IsNeedPoisonBottle() +{ + return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_NEED_POISON_BOTTLE); +} + +BOOL CPythonSkill::SSkillData::IsNeedBow() +{ + if (!(dwSkillAttribute & SKILL_ATTRIBUTE_WEAPON_LIMITATION)) + return FALSE; + + return 0 != (dwNeedWeapon & SKILL_NEED_WEAPON_BOW); +} + +BOOL CPythonSkill::SSkillData::IsHorseSkill() +{ + return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_HORSE_SKILL); +} + +BOOL CPythonSkill::SSkillData::IsMovingSkill() +{ + return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_MOVING_SKILL); +} + +BOOL CPythonSkill::SSkillData::IsAttackSkill() +{ + return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_ATTACK_SKILL); +} + +BOOL CPythonSkill::SSkillData::IsTimeIncreaseSkill() +{ + return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_TIME_INCREASE_SKILL); +} + +bool CPythonSkill::SSkillData::GetState(const char * c_szStateName, int * piState, int iMinMaxType) +{ + std::map * pStatusNameMap = NULL; + + switch (iMinMaxType) + { + case VALUE_TYPE_FREE: + pStatusNameMap = &ms_StatusNameMap; + break; + case VALUE_TYPE_MIN: + pStatusNameMap = &ms_NewMinStatusNameMap; + break; + case VALUE_TYPE_MAX: + pStatusNameMap = &ms_NewMaxStatusNameMap; + break; + default: + return false; + break; + } + + std::map::iterator it = pStatusNameMap->find(c_szStateName); + + if (it != pStatusNameMap->end()) + { + *piState = CPythonPlayer::Instance().GetStatus(it->second); + } + else if (0 == strncmp(c_szStateName, "JeungJi", 7)) + { + *piState = 0; + + // ӽ +/* + if (0 != ms_dwTimeIncreaseSkillNumber) + { + DWORD dwSkillSlotIndex; + if (!CPythonPlayer::Instance().FindSkillSlotIndexBySkillIndex(ms_dwTimeIncreaseSkillNumber, &dwSkillSlotIndex)) + return false; + + *piState = CPythonPlayer::Instance().GetSkillLevel(dwSkillSlotIndex); + } +*/ + } + + return true; +} + +float CPythonSkill::SSkillData::ProcessFormula(CPoly * pPoly, float fSkillLevel, int iMinMaxType) +{ + if (pPoly->Analyze()) + { + for (DWORD i = 0; i < pPoly->GetVarCount(); ++i) + { + const char * c_szVarName = pPoly->GetVarName(i); + float fState; + if (!strcmp("SkillPoint", c_szVarName) || !strcmp("k", c_szVarName)) + { + fState = fSkillLevel; + } + else + { + int iState; + if (!GetState(c_szVarName, &iState, iMinMaxType)) + return 0.0f; + + fState = float(iState); + + if (!strcmp("ar", c_szVarName)) + fState /= 100.0f; + } + pPoly->SetVar(c_szVarName, fState); + } + } + else + { + TraceError("skillGetAffect - Strange Formula [%s]", strName.c_str()); + return 0.0f; + } + + return pPoly->Eval(); +} + +const char * CPythonSkill::SSkillData::GetAffectDescription(DWORD dwIndex, float fSkillLevel) +{ + if (dwIndex >= AffectDataVector.size()) + return NULL; + + const std::string & c_rstrAffectDescription = AffectDataVector[dwIndex].strAffectDescription; + const std::string & c_rstrAffectMinFormula = AffectDataVector[dwIndex].strAffectMinFormula; + const std::string & c_rstrAffectMaxFormula = AffectDataVector[dwIndex].strAffectMaxFormula; + + CPoly minPoly; + CPoly maxPoly; + minPoly.SetStr(c_rstrAffectMinFormula.c_str()); + maxPoly.SetStr(c_rstrAffectMaxFormula.c_str()); + + // OVERWRITE_SKILLPROTO_POLY + float fMinValue = ProcessFormula(&minPoly, fSkillLevel); + float fMaxValue = ProcessFormula(&maxPoly, fSkillLevel); + + if (fMinValue < 0.0) + fMinValue = - fMinValue; + if (fMaxValue < 0.0) + fMaxValue = - fMaxValue; + + if (CP_ARABIC == ::GetDefaultCodePage()) + { + // #0000870: [M2AE] ѱ ϶ Ư ƶ 忡 ũ ߻ + static std::string strDescription; + strDescription = c_rstrAffectDescription; + int first = strDescription.find("%.0f"); + if (first >= 0) + { + fMinValue = floorf(fMinValue); + + char szMinValue[256]; + _snprintf(szMinValue, sizeof(szMinValue), "%.0f", fMinValue); + strDescription.replace(first, 4, szMinValue); + + int second = strDescription.find("%.0f", first); + if (second >= 0) + { + fMaxValue = floorf(fMaxValue); + + char szMaxValue[256]; + _snprintf(szMaxValue, sizeof(szMaxValue), "%.0f", fMaxValue); + strDescription.replace(second, 4, szMaxValue); + } + } + return strDescription.c_str(); + } + else + { + if (strstr(c_rstrAffectDescription.c_str(), "%.0f")) + { + fMinValue = floorf(fMinValue); + fMaxValue = floorf(fMaxValue); + } + + static char szDescription[64+1]; + _snprintf(szDescription, sizeof(szDescription), c_rstrAffectDescription.c_str(), fMinValue, fMaxValue); + + return szDescription; + } +} + +DWORD CPythonSkill::SSkillData::GetSkillCoolTime(float fSkillPoint) +{ + if (strCoolTimeFormula.empty()) + return 0; + + CPoly poly; + poly.SetStr(strCoolTimeFormula.c_str()); + + return DWORD(ProcessFormula(&poly, fSkillPoint)); +} + + +DWORD CPythonSkill::SSkillData::GetTargetCount(float fSkillPoint) +{ + if (strTargetCountFormula.empty()) + return 0; + + CPoly poly; + poly.SetStr(strTargetCountFormula.c_str()); + + return DWORD(ProcessFormula(&poly, fSkillPoint)); +} + +DWORD CPythonSkill::SSkillData::GetSkillMotionIndex(int iGrade) +{ + if (-1 != iGrade && SKILL_EFFECT_UPGRADE_ENABLE) + { + assert(iGrade >= 0 && iGrade < SKILL_EFFECT_COUNT); + /* + if (SKILL_GRADE_COUNT == iGrade) + { + return GradeData[SKILL_GRADE_COUNT-1].wMotionIndex; + } + else */ + if (iGrade >= 0 && iGrade < SKILL_EFFECT_COUNT) + { + return GradeData[iGrade].wMotionIndex; + } + } + + return wMotionIndex; +} + +BYTE CPythonSkill::SSkillData::GetMaxLevel() +{ + return byMaxLevel; +} + +BYTE CPythonSkill::SSkillData::GetLevelUpPoint() +{ + return byLevelUpPoint; +} + +BOOL CPythonSkill::SSkillData::IsNoMotion() +{ + return bNoMotion; +} + +bool CPythonSkill::SSkillData::IsCanUseSkill() +{ + if (0 != (dwSkillAttribute & SKILL_ATTRIBUTE_PASSIVE)) + return false; + + return true; +} + +DWORD CPythonSkill::SSkillData::GetMotionLoopCount(float fSkillPoint) +{ + if (strMotionLoopCountFormula.empty()) + return 0; + + CPoly poly; + poly.SetStr(strMotionLoopCountFormula.c_str()); + + return DWORD(ProcessFormula(&poly, fSkillPoint)); +} + +int CPythonSkill::SSkillData::GetNeedSP(float fSkillPoint) +{ + if (strNeedSPFormula.empty()) + return 0; + + CPoly poly; + poly.SetStr(strNeedSPFormula.c_str()); + + return int(ProcessFormula(&poly, fSkillPoint)); +} + +DWORD CPythonSkill::SSkillData::GetContinuationSP(float fSkillPoint) +{ + if (strContinuationSPFormula.empty()) + return 0; + + CPoly poly; + poly.SetStr(strContinuationSPFormula.c_str()); + + return DWORD(ProcessFormula(&poly, fSkillPoint)); +} + +DWORD CPythonSkill::SSkillData::GetDuration(float fSkillPoint) +{ + if (strDuration.empty()) + return 0; + + CPoly poly; + poly.SetStr(strDuration.c_str()); + + return DWORD(ProcessFormula(&poly, fSkillPoint)); +} + +CPythonSkill::SSkillData::SSkillData() +{ + byType = SKILL_TYPE_ACTIVE; + byMaxLevel = 20; + byLevelUpPoint = 1; + dwSkillAttribute = 0; + dwNeedWeapon = 0; + dwTargetRange = 0; + strCoolTimeFormula = ""; + strMotionLoopCountFormula = ""; + strNeedSPFormula = ""; + strContinuationSPFormula = ""; + isRequirement = FALSE; + strRequireSkillName = ""; + byRequireSkillLevel = 0; + strDuration = ""; + byLevelLimit = 0; + bNoMotion = FALSE; + + strName = ""; + pImage = NULL; + + for (int j = 0; j < SKILL_GRADE_COUNT; ++j) + { + TGradeData & rGradeData = GradeData[j]; + rGradeData.strName = ""; + rGradeData.pImage = NULL; + rGradeData.wMotionIndex = 0; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// + +PyObject * skillSetPathName(PyObject * poSelf, PyObject * poArgs) +{ + char * szPathName; + if (!PyTuple_GetString(poArgs, 0, &szPathName)) + return Py_BadArgument(); + + CPythonSkill::Instance().SetPathName(szPathName); + return Py_BuildNone(); +} + +PyObject * skillRegisterSkill(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + char * szFileName; + if (!PyTuple_GetString(poArgs, 1, &szFileName)) + return Py_BadArgument(); + + std::string strFullFileName; + strFullFileName = CPythonSkill::Instance().GetPathName(); + strFullFileName += szFileName; + + if (!CPythonSkill::Instance().RegisterSkill(iSkillIndex, strFullFileName.c_str())) + return Py_BuildException("skill.RegisterSkill - Failed to find skill data file : %d, %s", iSkillIndex, strFullFileName.c_str()); + + return Py_BuildNone(); +} + +PyObject * skillLoadSkillData(PyObject * poSelf, PyObject * poArgs) +{ + + + + return Py_BuildNone(); +} + +PyObject * skillRegisterSkillDesc(PyObject * poSelf, PyObject * poArgs) +{ + char * szFileName; + if (!PyTuple_GetString(poArgs, 0, &szFileName)) + return Py_BadArgument(); + + if (!CPythonSkill::Instance().RegisterSkillDesc(szFileName)) + return Py_BuildException("Failed to load Skill Desc"); + + return Py_BuildNone(); +} + +PyObject * skillClearSkillData(PyObject * poSelf, PyObject * poArgs) +{ + CPythonSkill::SSkillData::ms_dwTimeIncreaseSkillNumber = 0; + return Py_BuildNone(); +} + +PyObject * skillGetSkillName(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + int iSkillGrade = -1; + PyTuple_GetInteger(poArgs, 1, &iSkillGrade); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.GetSkillName - Failed to find skill by %d", iSkillIndex); + + if (-1 != iSkillGrade) + if (iSkillGrade >= 0 && iSkillGrade < CPythonSkill::SKILL_GRADE_COUNT) + { + return Py_BuildValue("s", c_pSkillData->GradeData[iSkillGrade].strName.c_str()); + } + + return Py_BuildValue("s", c_pSkillData->strName.c_str()); +} + +PyObject * skillGetSkillDescription(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.GetSkillDescription - Failed to find skill by %d", iSkillIndex); + + return Py_BuildValue("s", c_pSkillData->strDescription.c_str()); +} + +PyObject * skillGetSkillType(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.GetSkillType - Failed to find skill by %d", iSkillIndex); + + return Py_BuildValue("i", c_pSkillData->byType); +} + +PyObject * skillGetSkillConditionDescriptionCount(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.GetSkillConditionDescriptionCount - Failed to find skill by %d", iSkillIndex); + + return Py_BuildValue("i", c_pSkillData->ConditionDataVector.size()); +} + +PyObject * skillGetSkillConditionDescription(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + int iConditionIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iConditionIndex)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.GetSkillConditionDescription() - Failed to find skill by %d", iSkillIndex); + + if (iConditionIndex >= c_pSkillData->ConditionDataVector.size()) + return Py_BuildValue("None"); + + return Py_BuildValue("s", c_pSkillData->ConditionDataVector[iConditionIndex].c_str()); +} + +PyObject * skillGetSkillAffectDescriptionCount(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.GetSkillAffectDescriptionCount - Failed to find skill by %d", iSkillIndex); + + return Py_BuildValue("i", c_pSkillData->AffectDataVector.size()); +} + +PyObject * skillGetSkillAffectDescription(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + int iAffectIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iAffectIndex)) + return Py_BadArgument(); + + float fSkillPoint; + if (!PyTuple_GetFloat(poArgs, 2, &fSkillPoint)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.GetSkillAffectDescription - Failed to find skill by %d", iSkillIndex); + + return Py_BuildValue("s", c_pSkillData->GetAffectDescription(iAffectIndex, fSkillPoint)); +} + +PyObject * skillGetSkillCoolTime(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + float fSkillPoint; + if (!PyTuple_GetFloat(poArgs, 1, &fSkillPoint)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.GetSkillCoolTime - Failed to find skill by %d", iSkillIndex); + + return Py_BuildValue("i", c_pSkillData->GetSkillCoolTime(fSkillPoint)); +} + +PyObject * skillGetSkillNeedSP(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + float fSkillPoint; + if (!PyTuple_GetFloat(poArgs, 1, &fSkillPoint)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.GetSkillNeedSP Failed to find skill by %d", iSkillIndex); + + return Py_BuildValue("i", c_pSkillData->GetNeedSP(fSkillPoint)); +} + +PyObject * skillGetSkillContinuationSP(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + float fSkillPoint; + if (!PyTuple_GetFloat(poArgs, 1, &fSkillPoint)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.GetSkillContinuationSP - Failed to find skill by %d", iSkillIndex); + + return Py_BuildValue("i", c_pSkillData->GetContinuationSP(fSkillPoint)); +} + +PyObject * skillGetSkillMaxLevel(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.GetSkillMaxLevel - Failed to find skill by %d", iSkillIndex); + + return Py_BuildValue("i", c_pSkillData->GetMaxLevel()); +} + +PyObject * skillGetSkillLevelUpPoint(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.GetSkillLevelUpPoint - Failed to find skill by %d", iSkillIndex); + + return Py_BuildValue("i", c_pSkillData->GetLevelUpPoint()); +} + +PyObject * skillGetSkillLevelLimit(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.GetSkillLevelLimit - Failed to find skill by %d", iSkillIndex); + + return Py_BuildValue("i", c_pSkillData->byLevelLimit); +} + +PyObject * skillIsSkillRequirement(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.IsSkillRequirement - Failed to find skill by %d", iSkillIndex); + + if (c_pSkillData->isRequirement) + { + CPythonSkill::SSkillData * pRequireSkillData; + if (!CPythonSkill::Instance().GetSkillDataByName(c_pSkillData->strRequireSkillName.c_str(), &pRequireSkillData)) + { + TraceError("skill.IsSkillRequirement - Failed to find skill : [%d/%s] can't find [%s]\n", c_pSkillData->dwSkillIndex, c_pSkillData->strName.c_str(), c_pSkillData->strRequireSkillName.c_str()); + return Py_BuildValue("i", FALSE); + } + + DWORD dwRequireSkillSlotIndex; + if (!CPythonPlayer::Instance().FindSkillSlotIndexBySkillIndex(pRequireSkillData->dwSkillIndex, &dwRequireSkillSlotIndex)) + return Py_BuildValue("i", FALSE); + } + + return Py_BuildValue("i", c_pSkillData->isRequirement); +} + +PyObject * skillGetSkillRequirementData(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.GetSkillRequirementData - Failed to find skill by %d", iSkillIndex); + + CPythonSkill::SSkillData * pRequireSkillData; + if (!CPythonSkill::Instance().GetSkillDataByName(c_pSkillData->strRequireSkillName.c_str(), &pRequireSkillData)) + return Py_BuildValue("si", 0, "None", 0); + + int ireqLevel = (int)ceil(float(c_pSkillData->byRequireSkillLevel)/float(max(1, pRequireSkillData->byLevelUpPoint))); + return Py_BuildValue("si", c_pSkillData->strRequireSkillName.c_str(), ireqLevel); +} + +PyObject * skillGetSkillRequireStatCount(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.GetSkillRequireStatCount - Failed to find skill by %d", iSkillIndex); + + return Py_BuildValue("i", c_pSkillData->RequireStatDataVector.size()); +} + +PyObject * skillGetSkillRequireStatData(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + int iStatIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iStatIndex)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.GetSkillRequireStatData - Failed to find skill by %d", iSkillIndex); + + if (iStatIndex >= c_pSkillData->RequireStatDataVector.size()) + return Py_BuildValue("ii", 0, 0); + + const CPythonSkill::TRequireStatData & c_rRequireStatData = c_pSkillData->RequireStatDataVector[iStatIndex]; + + return Py_BuildValue("ii", c_rRequireStatData.byPoint, c_rRequireStatData.byLevel); +} + +PyObject * skillCanLevelUpSkill(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + int iSkillLevel; + if (!PyTuple_GetInteger(poArgs, 1, &iSkillLevel)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.CanLevelUpSkill - Failed to find skill by %d", iSkillIndex); + + if (iSkillLevel >= c_pSkillData->GetMaxLevel()) + return Py_BuildValue("i", FALSE); + + if (c_pSkillData->isRequirement) + { + CPythonSkill::SSkillData * pRequireSkillData; + if (CPythonSkill::Instance().GetSkillDataByName(c_pSkillData->strRequireSkillName.c_str(), &pRequireSkillData)) + { + DWORD dwRequireSkillSlotIndex; + if (CPythonPlayer::Instance().FindSkillSlotIndexBySkillIndex(pRequireSkillData->dwSkillIndex, &dwRequireSkillSlotIndex)) + { + int iSkillGrade = CPythonPlayer::Instance().GetSkillGrade(dwRequireSkillSlotIndex); + int iSkillLevel = CPythonPlayer::Instance().GetSkillLevel(dwRequireSkillSlotIndex); + if (iSkillGrade <= 0) + if (iSkillLevel < c_pSkillData->byRequireSkillLevel) + return Py_BuildValue("i", FALSE); + } + } + } + + for (DWORD i = 0; i < c_pSkillData->RequireStatDataVector.size(); ++i) + { + const CPythonSkill::TRequireStatData & c_rRequireStatData = c_pSkillData->RequireStatDataVector[i]; + if (CPythonPlayer::Instance().GetStatus(c_rRequireStatData.byPoint) < c_rRequireStatData.byLevel) + return Py_BuildValue("i", FALSE); + } + + if (0 != (c_pSkillData->dwSkillAttribute & CPythonSkill::SKILL_ATTRIBUTE_CANNOT_LEVEL_UP)) + return Py_BuildValue("i", FALSE); + + return Py_BuildValue("i", TRUE); +} + +PyObject * skillCheckRequirementSueccess(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.CheckRequirementSueccess - Failed to find skill by %d", iSkillIndex); + + if (c_pSkillData->isRequirement) + { + CPythonSkill::SSkillData * pRequireSkillData; + if (CPythonSkill::Instance().GetSkillDataByName(c_pSkillData->strRequireSkillName.c_str(), &pRequireSkillData)) + { + DWORD dwRequireSkillSlotIndex; + if (CPythonPlayer::Instance().FindSkillSlotIndexBySkillIndex(pRequireSkillData->dwSkillIndex, &dwRequireSkillSlotIndex)) + { + int iSkillGrade = CPythonPlayer::Instance().GetSkillGrade(dwRequireSkillSlotIndex); + int iSkillLevel = CPythonPlayer::Instance().GetSkillLevel(dwRequireSkillSlotIndex); + if (iSkillGrade <= 0) + if (iSkillLevel < c_pSkillData->byRequireSkillLevel) + return Py_BuildValue("i", FALSE); + } + } + } + + return Py_BuildValue("i", TRUE); +} + +PyObject * skillGetNeedCharacterLevel(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.GetNeedCharacterLevel - Failed to find skill by %d", iSkillIndex); + + std::vector::iterator itor = c_pSkillData->RequireStatDataVector.begin(); + for (; itor != c_pSkillData->RequireStatDataVector.end(); ++itor) + { + const CPythonSkill::TRequireStatData & c_rRequireStatData = *itor; + + if (POINT_LEVEL == c_rRequireStatData.byPoint) + return Py_BuildValue("i", c_rRequireStatData.byLevel); + } + + return Py_BuildValue("i", 0); +} + +PyObject * skillIsToggleSkill(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.IsToggleSkill - Failed to find skill by %d", iSkillIndex); + + return Py_BuildValue("i", c_pSkillData->IsToggleSkill()); +} + +PyObject * skillIsUseHPSkill(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.IsUseHPSkill - Failed to find skill by %d", iSkillIndex); + + return Py_BuildValue("i", c_pSkillData->IsUseHPSkill()); +} + +PyObject * skillIsStandingSkill(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.IsStandingSkill - Failed to find skill by %d", iSkillIndex); + + return Py_BuildValue("i", c_pSkillData->IsStandingSkill()); +} + +PyObject * skillCanUseSkill(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.CanUseSkill - Failed to find skill by %d", iSkillIndex); + + return Py_BuildValue("i", c_pSkillData->IsCanUseSkill()); +} + +PyObject * skillIsLevelUpSkill(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.IsLevelUpSkill - Failed to find skill by %d", iSkillIndex); + + // + + return Py_BuildValue("i", TRUE); +} + +PyObject * skillGetIconName(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildValue("s", ""); + + return Py_BuildValue("s", c_pSkillData->strIconFileName.c_str()); +} + +PyObject * skillGetIconImage(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildValue("i", 0); // ͼ 0 Ѵ. + + return Py_BuildValue("i", c_pSkillData->pImage); +} + + + +PyObject * skillGetIconInstance(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.GetIconInstance - Failed to find skill by %d", iSkillIndex); + + CGraphicImageInstance * pImageInstance = CGraphicImageInstance::New(); + pImageInstance->SetImagePointer(c_pSkillData->pImage); + + return Py_BuildValue("i", pImageInstance); +} + +PyObject * skillGetIconImageNew(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + int iGradeIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iGradeIndex)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildValue("i", 0); // ͼ 0 Ѵ. + + if (iGradeIndex < 0) + iGradeIndex = 0; + + if (iGradeIndex >= CPythonSkill::SKILL_GRADE_COUNT) + iGradeIndex = CPythonSkill::SKILL_GRADE_COUNT-1; + + return Py_BuildValue("i", c_pSkillData->GradeData[iGradeIndex].pImage); +} + +PyObject * skillGetIconInstanceNew(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + int iGradeIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iGradeIndex)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.GetIconInstanceNew - Failed to find skill by %d", iSkillIndex); + + //CGraphicImage * pImage = c_pSkillData->pImage; + + if (iGradeIndex < 0) + iGradeIndex = 0; + + if (iGradeIndex >= CPythonSkill::SKILL_GRADE_COUNT) + iGradeIndex = CPythonSkill::SKILL_GRADE_COUNT-1; + + CGraphicImageInstance * pImageInstance = CGraphicImageInstance::New(); + pImageInstance->SetImagePointer(c_pSkillData->GradeData[iGradeIndex].pImage); + + return Py_BuildValue("i", pImageInstance); +} + +PyObject * skillDeleteIconInstance(PyObject * poSelf, PyObject * poArgs) +{ + int iHandle; + if (!PyTuple_GetInteger(poArgs, 0, &iHandle)) + return Py_BadArgument(); + + CGraphicImageInstance::Delete((CGraphicImageInstance *) iHandle); + return Py_BuildNone(); +} + +PyObject * skillGetGradeData(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + int iGradeIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iGradeIndex)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.GetGradeData - Failed to find skill by %d", iSkillIndex); + + if (iGradeIndex < 0 || iGradeIndex >= CPythonSkill::SKILL_GRADE_COUNT) + return Py_BuildException("Strange grade index [%d]", iSkillIndex, iGradeIndex); + + return Py_BuildValue("i", c_pSkillData->GradeData[iGradeIndex]); +} + +PyObject * skillGetNewAffectDataCount(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.GetNewAffectDataCount - Failed to find skill by %d", iSkillIndex); + + return Py_BuildValue("i", c_pSkillData->AffectDataNewVector.size()); +} + +PyObject * skillGetNewAffectData(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + int iAffectIndex; + if (!PyTuple_GetInteger(poArgs, 1, &iAffectIndex)) + return Py_BadArgument(); + float fSkillLevel; + if (!PyTuple_GetFloat(poArgs, 2, &fSkillLevel)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &pSkillData)) + return Py_BuildException("skill.GetNewAffectData - Failed to find skill by %d", iSkillIndex); + + if (iAffectIndex < 0 || iAffectIndex >= pSkillData->AffectDataNewVector.size()) + return Py_BuildException(" skill.GetNewAffectData - Strange AffectIndex %d", iAffectIndex); + + CPythonSkill::TAffectDataNew & rAffectData = pSkillData->AffectDataNewVector[iAffectIndex]; + + CPoly minPoly; + CPoly maxPoly; + minPoly.SetRandom(CPoly::RANDOM_TYPE_FORCE_MIN); + maxPoly.SetRandom(CPoly::RANDOM_TYPE_FORCE_MAX); + minPoly.SetStr(rAffectData.strPointPoly.c_str()); + maxPoly.SetStr(rAffectData.strPointPoly.c_str()); + float fMinValue = pSkillData->ProcessFormula(&minPoly, fSkillLevel, CPythonSkill::VALUE_TYPE_MIN); + float fMaxValue = pSkillData->ProcessFormula(&maxPoly, fSkillLevel, CPythonSkill::VALUE_TYPE_MAX); + + return Py_BuildValue("sff", rAffectData.strPointType.c_str(), fMinValue, fMaxValue); +} + +PyObject * skillGetDuration(PyObject * poSelf, PyObject * poArgs) +{ + int iSkillIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex)) + return Py_BadArgument(); + float fSkillLevel; + if (!PyTuple_GetFloat(poArgs, 1, &fSkillLevel)) + return Py_BadArgument(); + + CPythonSkill::SSkillData * c_pSkillData; + if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData)) + return Py_BuildException("skill.GetDuration - Failed to find skill by %d", iSkillIndex); + + return Py_BuildValue("i", c_pSkillData->GetDuration(fSkillLevel)); +} + +PyObject * skillTEST(PyObject * poSelf, PyObject * poArgs) +{ + CPythonSkill::Instance().TEST(); + return Py_BuildNone(); +} + +void initskill() +{ + static PyMethodDef s_methods[] = + { + { "SetPathName", skillSetPathName, METH_VARARGS }, + { "RegisterSkill", skillRegisterSkill, METH_VARARGS }, + { "LoadSkillData", skillLoadSkillData, METH_VARARGS }, + { "ClearSkillData", skillClearSkillData, METH_VARARGS }, + + ///// + + { "GetSkillName", skillGetSkillName, METH_VARARGS }, + { "GetSkillDescription", skillGetSkillDescription, METH_VARARGS }, + { "GetSkillType", skillGetSkillType, METH_VARARGS }, + { "GetSkillConditionDescriptionCount", skillGetSkillConditionDescriptionCount, METH_VARARGS }, + { "GetSkillConditionDescription", skillGetSkillConditionDescription, METH_VARARGS }, + { "GetSkillAffectDescriptionCount", skillGetSkillAffectDescriptionCount, METH_VARARGS }, + { "GetSkillAffectDescription", skillGetSkillAffectDescription, METH_VARARGS }, + { "GetSkillCoolTime", skillGetSkillCoolTime, METH_VARARGS }, + { "GetSkillNeedSP", skillGetSkillNeedSP, METH_VARARGS }, + { "GetSkillContinuationSP", skillGetSkillContinuationSP, METH_VARARGS }, + { "GetSkillMaxLevel", skillGetSkillMaxLevel, METH_VARARGS }, + { "GetSkillLevelUpPoint", skillGetSkillLevelUpPoint, METH_VARARGS }, + { "GetSkillLevelLimit", skillGetSkillLevelLimit, METH_VARARGS }, + { "IsSkillRequirement", skillIsSkillRequirement, METH_VARARGS }, + { "GetSkillRequirementData", skillGetSkillRequirementData, METH_VARARGS }, + { "GetSkillRequireStatCount", skillGetSkillRequireStatCount, METH_VARARGS }, + { "GetSkillRequireStatData", skillGetSkillRequireStatData, METH_VARARGS }, + { "CanLevelUpSkill", skillCanLevelUpSkill, METH_VARARGS }, + { "IsLevelUpSkill", skillIsLevelUpSkill, METH_VARARGS }, + { "CheckRequirementSueccess", skillCheckRequirementSueccess, METH_VARARGS }, + { "GetNeedCharacterLevel", skillGetNeedCharacterLevel, METH_VARARGS }, + { "IsToggleSkill", skillIsToggleSkill, METH_VARARGS }, + { "IsUseHPSkill", skillIsUseHPSkill, METH_VARARGS }, + { "IsStandingSkill", skillIsStandingSkill, METH_VARARGS }, + { "CanUseSkill", skillCanUseSkill, METH_VARARGS }, + { "GetIconName", skillGetIconName, METH_VARARGS }, + { "GetIconImage", skillGetIconImage, METH_VARARGS }, + { "GetIconImageNew", skillGetIconImageNew, METH_VARARGS }, + { "GetIconInstance", skillGetIconInstance, METH_VARARGS }, + { "GetIconInstanceNew", skillGetIconInstanceNew, METH_VARARGS }, + { "DeleteIconInstance", skillDeleteIconInstance, METH_VARARGS }, + { "GetGradeData", skillGetGradeData, METH_VARARGS }, + + { "GetNewAffectDataCount", skillGetNewAffectDataCount, METH_VARARGS }, + { "GetNewAffectData", skillGetNewAffectData, METH_VARARGS }, + { "GetDuration", skillGetDuration, METH_VARARGS }, + + { "TEST", skillTEST, METH_VARARGS }, + + { NULL, NULL, NULL }, + }; + + PyObject * poModule = Py_InitModule("skill", s_methods); + PyModule_AddIntConstant(poModule, "SKILL_TYPE_NONE", CPythonSkill::SKILL_TYPE_NONE); + PyModule_AddIntConstant(poModule, "SKILL_TYPE_ACTIVE", CPythonSkill::SKILL_TYPE_ACTIVE); + PyModule_AddIntConstant(poModule, "SKILL_TYPE_SUPPORT", CPythonSkill::SKILL_TYPE_SUPPORT); + PyModule_AddIntConstant(poModule, "SKILL_TYPE_GUILD", CPythonSkill::SKILL_TYPE_GUILD); + PyModule_AddIntConstant(poModule, "SKILL_TYPE_HORSE", CPythonSkill::SKILL_TYPE_HORSE); + PyModule_AddIntConstant(poModule, "SKILL_TYPE_MAX_NUM", CPythonSkill::SKILL_TYPE_MAX_NUM); + + PyModule_AddIntConstant(poModule, "SKILL_GRADE_COUNT", CPythonSkill::SKILL_GRADE_COUNT); + PyModule_AddIntConstant(poModule, "SKILL_GRADE_STEP_COUNT", CPythonSkill::SKILL_GRADE_STEP_COUNT); + PyModule_AddIntConstant(poModule, "SKILL_GRADEGAP", CPythonSkill::SKILL_GRADEGAP); + PyModule_AddIntConstant(poModule, "SKILL_EFFECT_COUNT", CPythonSkill::SKILL_EFFECT_COUNT); +} diff --git a/source/UserInterface/PythonSkill.h b/source/UserInterface/PythonSkill.h new file mode 100644 index 0000000..8b11109 --- /dev/null +++ b/source/UserInterface/PythonSkill.h @@ -0,0 +1,299 @@ +#pragma once + +#include "../gamelib/ItemData.h" +#include "../EterBase/Poly/Poly.h" + +class CInstanceBase; + +class CPythonSkill : public CSingleton +{ + public: + enum + { + SKILL_TYPE_NONE, + SKILL_TYPE_ACTIVE, + SKILL_TYPE_SUPPORT, + SKILL_TYPE_GUILD, + SKILL_TYPE_HORSE, + SKILL_TYPE_MAX_NUM, + }; + + enum ESkillTableTokenType + { + TABLE_TOKEN_TYPE_VNUM, + TABLE_TOKEN_TYPE_NAME, + TABLE_TOKEN_TYPE_TYPE, + TABLE_TOKEN_TYPE_LEVEL_STEP, + TABLE_TOKEN_TYPE_MAX_LEVEL, + TABLE_TOKEN_TYPE_LEVEL_LIMIT, + TABLE_TOKEN_TYPE_POINT_ON, + TABLE_TOKEN_TYPE_POINT_POLY, + TABLE_TOKEN_TYPE_SP_COST_POLY, + TABLE_TOKEN_TYPE_DURATION_POLY, + TABLE_TOKEN_TYPE_DURATION_SP_COST_POLY, + TABLE_TOKEN_TYPE_COOLDOWN_POLY, + TABLE_TOKEN_TYPE_MASTER_BONUS_POLY, + TABLE_TOKEN_TYPE_ATTACK_GRADE_POLY, + TABLE_TOKEN_TYPE_FLAG, + TABLE_TOKEN_TYPE_AFFECT_FLAG, + TABLE_TOKEN_TYPE_POINT_ON2, + TABLE_TOKEN_TYPE_POINT_POLY2, + TABLE_TOKEN_TYPE_DURATION_POLY2, + TABLE_TOKEN_TYPE_AFFECT_FLAG2, + TABLE_TOKEN_TYPE_PREREQUISITE_SKILL_VNUM, + TABLE_TOKEN_TYPE_PREREQUISITE_SKILL_LEVEL, + TABLE_TOKEN_TYPE_SKILL_TYPE, + TABLE_TOKEN_TYPE_MAX_HIT, + TABLE_TOKEN_TYPE_SPLASH_AROUND_DAMAGE_ADJUST_POLY, + TABLE_TOKEN_TYPE_TARGET_RANGE, + TABLE_TOKEN_TYPE_SPLASH_RANGE, + TABLE_TOKEN_TYPE_MAX_NUM, + }; + + enum ESkillDescTokenType + { + DESC_TOKEN_TYPE_VNUM, + DESC_TOKEN_TYPE_JOB, + DESC_TOKEN_TYPE_NAME1, + DESC_TOKEN_TYPE_NAME2, + DESC_TOKEN_TYPE_NAME3, + DESC_TOKEN_TYPE_DESCRIPTION, + DESC_TOKEN_TYPE_CONDITION1, + DESC_TOKEN_TYPE_CONDITION2, + DESC_TOKEN_TYPE_CONDITION3, + DESC_TOKEN_TYPE_CONDITION4, + DESC_TOKEN_TYPE_ATTRIBUTE, + DESC_TOKEN_TYPE_WEAPON, + DESC_TOKEN_TYPE_ICON_NAME, + DESC_TOKEN_TYPE_MOTION_INDEX, + DESC_TOKEN_TYPE_MOTION_INDEX_GRADE_NUM, + DESC_TOKEN_TYPE_TARGET_COUNT_FORMULA, + DESC_TOKEN_TYPE_MOTION_LOOP_COUNT_FORMULA, + DESC_TOKEN_TYPE_AFFECT_DESCRIPTION_1, + DESC_TOKEN_TYPE_AFFECT_MIN_1, + DESC_TOKEN_TYPE_AFFECT_MAX_1, + DESC_TOKEN_TYPE_AFFECT_DESCRIPTION_2, + DESC_TOKEN_TYPE_AFFECT_MIN_2, + DESC_TOKEN_TYPE_AFFECT_MAX_2, + DESC_TOKEN_TYPE_AFFECT_DESCRIPTION_3, + DESC_TOKEN_TYPE_AFFECT_MIN_3, + DESC_TOKEN_TYPE_AFFECT_MAX_3, + DESC_TOKEN_TYPE_LEVEL_LIMIT, + DESC_TOKEN_TYPE_MAX_LEVEL, + DESC_TOKEN_TYPE_MAX_NUM, + + CONDITION_COLUMN_COUNT = 3, + AFFECT_COLUMN_COUNT = 3, + AFFECT_STEP_COUNT = 3, + }; + + enum + { + SKILL_ATTRIBUTE_NEED_TARGET = (1 << 0), + SKILL_ATTRIBUTE_TOGGLE = (1 << 1), + SKILL_ATTRIBUTE_WEAPON_LIMITATION = (1 << 2), + SKILL_ATTRIBUTE_MELEE_ATTACK = (1 << 3), + SKILL_ATTRIBUTE_USE_HP = (1 << 4), + SKILL_ATTRIBUTE_CAN_CHANGE_DIRECTION = (1 << 5), + SKILL_ATTRIBUTE_STANDING_SKILL = (1 << 6), + SKILL_ATTRIBUTE_ONLY_FOR_ALLIANCE = (1 << 7), + SKILL_ATTRIBUTE_CAN_USE_FOR_ME = (1 << 8), + SKILL_ATTRIBUTE_NEED_CORPSE = (1 << 9), + SKILL_ATTRIBUTE_FAN_RANGE = (1 << 10), + SKILL_ATTRIBUTE_CAN_USE_IF_NOT_ENOUGH = (1 << 11), + SKILL_ATTRIBUTE_NEED_EMPTY_BOTTLE = (1 << 12), + SKILL_ATTRIBUTE_NEED_POISON_BOTTLE = (1 << 13), + SKILL_ATTRIBUTE_ATTACK_SKILL = (1 << 14), + SKILL_ATTRIBUTE_TIME_INCREASE_SKILL = (1 << 15), // attribute + SKILL_ATTRIBUTE_CHARGE_ATTACK = (1 << 16), + SKILL_ATTRIBUTE_PASSIVE = (1 << 17), + SKILL_ATTRIBUTE_CANNOT_LEVEL_UP = (1 << 18), + SKILL_ATTRIBUTE_ONLY_FOR_GUILD_WAR = (1 << 19), + SKILL_ATTRIBUTE_MOVING_SKILL = (1 << 20), + SKILL_ATTRIBUTE_HORSE_SKILL = (1 << 21), + SKILL_ATTRIBUTE_CIRCLE_RANGE = (1 << 22), + SKILL_ATTRIBUTE_SEARCH_TARGET = (1 << 23), + }; + + enum + { + SKILL_NEED_WEAPON_SWORD = (1 << CItemData::WEAPON_SWORD), + SKILL_NEED_WEAPON_DAGGER = (1 << CItemData::WEAPON_DAGGER), + SKILL_NEED_WEAPON_BOW = (1 << CItemData::WEAPON_BOW), + SKILL_NEED_WEAPON_TWO_HANDED = (1 << CItemData::WEAPON_TWO_HANDED), + SKILL_NEED_WEAPON_DOUBLE_SWORD = (1 << CItemData::WEAPON_DAGGER), + SKILL_NEED_WEAPON_BELL = (1 << CItemData::WEAPON_BELL), + SKILL_NEED_WEAPON_FAN = (1 << CItemData::WEAPON_FAN), + SKILL_NEED_WEAPON_ARROW = (1 << CItemData::WEAPON_ARROW), + SKILL_NEED_WEAPON_EMPTY_HAND = (1 << CItemData::WEAPON_NONE), + }; + + enum + { + VALUE_TYPE_FREE, + VALUE_TYPE_MIN, + VALUE_TYPE_MAX, + }; + + enum + { + SKILL_GRADE_COUNT = 3, + SKILL_EFFECT_COUNT = 4, //ų ,, ̿ܿ ϶ Ʈ ߰. + SKILL_GRADE_STEP_COUNT = 20, + SKILL_GRADEGAP = 25, + }; + + typedef struct SAffectData + { + std::string strAffectDescription; + std::string strAffectMinFormula; + std::string strAffectMaxFormula; + } TAffectData; + typedef struct SAffectDataNew + { + std::string strPointType; + std::string strPointPoly; + } TAffectDataNew; + typedef struct SRequireStatData + { + BYTE byPoint; + BYTE byLevel; + } TRequireStatData; + typedef struct SGradeData + { + std::string strName; + CGraphicImage * pImage; + WORD wMotionIndex; + } TGradeData; + typedef struct SSkillData + { + static DWORD MELEE_SKILL_TARGET_RANGE; + // Functions + SSkillData(); + DWORD GetTargetRange() const; + BOOL CanChangeDirection(); + BOOL IsFanRange(); + BOOL IsCircleRange(); + BOOL IsAutoSearchTarget(); + BOOL IsNeedTarget(); + BOOL IsNeedCorpse(); + BOOL IsToggleSkill(); + BOOL IsUseHPSkill(); + BOOL IsStandingSkill(); + BOOL CanUseWeaponType(DWORD dwWeaponType); + BOOL IsOnlyForAlliance(); + BOOL CanUseForMe(); + BOOL CanUseIfNotEnough(); + BOOL IsNeedEmptyBottle(); + BOOL IsNeedPoisonBottle(); + BOOL IsNeedBow(); + BOOL IsAttackSkill(); + BOOL IsHorseSkill(); + BOOL IsMovingSkill(); + BOOL IsTimeIncreaseSkill(); + BOOL IsMeleeSkill(); + BOOL IsChargeSkill(); + BOOL IsOnlyForGuildWar(); + + bool GetState(const char * c_szStateName, int * piState, int iMinMaxType = VALUE_TYPE_FREE); + float ProcessFormula(CPoly * pPoly, float fSkillLevel = 0.0f, int iMinMaxType = VALUE_TYPE_FREE); + const char * GetAffectDescription(DWORD dwIndex, float fSkillLevel); + DWORD GetSkillCoolTime(float fSkillPoint); + int GetNeedSP(float fSkillPoint); + DWORD GetContinuationSP(float fSkillPoint); + DWORD GetMotionLoopCount(float fSkillPoint); + DWORD GetTargetCount(float fSkillPoint); + DWORD GetDuration(float fSkillPoint); + DWORD GetSkillMotionIndex(int iGrade=-1); + BYTE GetMaxLevel(); + BYTE GetLevelUpPoint(); + bool IsCanUseSkill(); + BOOL IsNoMotion(); + + const std::string GetName() const; + BYTE GetType() const; + + /////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////// + + // Variable + BYTE byType; + DWORD dwSkillIndex; + BYTE byMaxLevel; + BYTE byLevelUpPoint; + BYTE byLevelLimit; + BOOL bNoMotion; + + std::string strName; + std::string strIconFileName; + std::string strDescription; + std::string strMotionScriptFileName; + + std::vector ConditionDataVector; + std::vector AffectDataVector; + std::vector AffectDataNewVector; + std::vector RequireStatDataVector; + std::string strCoolTimeFormula; + std::string strTargetCountFormula; + std::string strMotionLoopCountFormula; + std::string strNeedSPFormula; + std::string strContinuationSPFormula; + std::string strDuration; + + DWORD dwSkillAttribute; + DWORD dwNeedWeapon; + DWORD dwTargetRange; + WORD wMotionIndex; // + WORD wMotionIndexForMe; // + + BOOL isRequirement; + std::string strRequireSkillName; + BYTE byRequireSkillLevel; + + TGradeData GradeData[SKILL_EFFECT_COUNT]; + + CGraphicImage * pImage; + + ///// + + static std::map ms_StatusNameMap; + static std::map ms_NewMinStatusNameMap; + static std::map ms_NewMaxStatusNameMap; + static DWORD ms_dwTimeIncreaseSkillNumber; + } TSkillData; + + typedef std::map TSkillDataMap; + typedef std::map TSkillMotionIndexMap; + typedef std::map TPathNameMap; + + public: + CPythonSkill(); + virtual ~CPythonSkill(); + + void Destroy(); + bool RegisterSkill(DWORD dwSkillIndex, const char * c_szFileName); + bool RegisterSkillTable(const char * c_szFileName); + bool RegisterSkillDesc(const char * c_szFileName); + BOOL GetSkillData(DWORD dwSkillIndex, TSkillData ** ppSkillData); + bool GetSkillDataByName(const char * c_szName, TSkillData ** ppSkillData); + + void SetPathName(const char * c_szFileName); + const char * GetPathName(); + + void TEST(); + + protected: + void __RegisterGradeIconImage(TSkillData & rData, const char * c_szHeader, const char * c_szImageName); + void __RegisterNormalIconImage(TSkillData & rData, const char * c_szHeader, const char * c_szImageName); + + protected: + TSkillDataMap m_SkillDataMap; + + std::string m_strPathName; + + std::map m_SkillTypeIndexMap; + std::map m_SkillAttributeIndexMap; + std::map m_SkillNeedWeaponIndexMap; + std::map m_SkillWeaponTypeIndexMap; + TPathNameMap m_PathNameMap; +}; \ No newline at end of file diff --git a/source/UserInterface/PythonSoundManagerModule.cpp b/source/UserInterface/PythonSoundManagerModule.cpp new file mode 100644 index 0000000..1547d29 --- /dev/null +++ b/source/UserInterface/PythonSoundManagerModule.cpp @@ -0,0 +1,176 @@ +#include "StdAfx.h" +#include "PythonApplication.h" + +PyObject * sndPlaySound(PyObject * poSelf, PyObject * poArgs) +{ + char * szFileName; + if (!PyTuple_GetString(poArgs, 0, &szFileName)) + return Py_BuildException(); + + CSoundManager& rkSndMgr=CSoundManager::Instance(); + rkSndMgr.PlaySound2D(szFileName); + return Py_BuildNone(); +} + +PyObject * sndPlaySound3D(PyObject * poSelf, PyObject * poArgs) +{ + float fx; + if (!PyTuple_GetFloat(poArgs, 0, &fx)) + return Py_BuildException(); + float fy; + if (!PyTuple_GetFloat(poArgs, 1, &fy)) + return Py_BuildException(); + float fz; + if (!PyTuple_GetFloat(poArgs, 2, &fz)) + return Py_BuildException(); + char * szFileName; + if (!PyTuple_GetString(poArgs, 3, &szFileName)) + return Py_BuildException(); + + CSoundManager& rkSndMgr=CSoundManager::Instance(); + rkSndMgr.PlaySound3D(fx, fy, fz, szFileName); + return Py_BuildNone(); +} + +PyObject * sndPlayMusic(PyObject * poSelf, PyObject * poArgs) +{ + char * szFileName; + if (!PyTuple_GetString(poArgs, 0, &szFileName)) + return Py_BuildException(); + + CSoundManager& rkSndMgr=CSoundManager::Instance(); + rkSndMgr.PlayMusic(szFileName); + return Py_BuildNone(); +} + +PyObject * sndFadeInMusic(PyObject * poSelf, PyObject * poArgs) +{ + char * szFileName; + if (!PyTuple_GetString(poArgs, 0, &szFileName)) + return Py_BuildException(); + + CSoundManager& rkSndMgr=CSoundManager::Instance(); + rkSndMgr.FadeInMusic(szFileName); + return Py_BuildNone(); +} + +PyObject * sndFadeOutMusic(PyObject * poSelf, PyObject * poArgs) +{ + char * szFileName; + if (!PyTuple_GetString(poArgs, 0, &szFileName)) + return Py_BuildException(); + + CSoundManager& rkSndMgr=CSoundManager::Instance(); + rkSndMgr.FadeOutMusic(szFileName); + return Py_BuildNone(); +} + +PyObject * sndFadeOutAllMusic(PyObject * poSelf, PyObject * poArgs) +{ + CSoundManager& rkSndMgr=CSoundManager::Instance(); + rkSndMgr.FadeOutAllMusic(); + return Py_BuildNone(); +} + +PyObject * sndFadeLimitOutMusic(PyObject * poSelf, PyObject * poArgs) +{ + char * szFileName; + if (!PyTuple_GetString(poArgs, 0, &szFileName)) + return Py_BuildException(); + + float fLimitVolume; + if (!PyTuple_GetFloat(poArgs, 1, &fLimitVolume)) + return Py_BuildException(); + + CSoundManager& rkSndMgr=CSoundManager::Instance(); + rkSndMgr.FadeLimitOutMusic(szFileName, fLimitVolume); + return Py_BuildNone(); +} + +PyObject * sndStopAllSound(PyObject * poSelf, PyObject * poArgs) +{ + CSoundManager& rkSndMgr=CSoundManager::Instance(); + rkSndMgr.StopAllSound3D(); + return Py_BuildNone(); +} + +PyObject * sndSetMusicVolume(PyObject * poSelf, PyObject * poArgs) +{ + float fVolume; + if (!PyTuple_GetFloat(poArgs, 0, &fVolume)) + return Py_BuildException(); + + CSoundManager& rkSndMgr=CSoundManager::Instance(); + rkSndMgr.SetMusicVolume(fVolume); + return Py_BuildNone(); +} + +PyObject * sndSetSoundVolumef(PyObject * poSelf, PyObject * poArgs) +{ + float fVolume; + if (!PyTuple_GetFloat(poArgs, 0, &fVolume)) + return Py_BuildException(); + + CSoundManager& rkSndMgr=CSoundManager::Instance(); + rkSndMgr.SetSoundVolumeRatio(fVolume); + return Py_BuildNone(); +} + + +PyObject * sndSetSoundVolume(PyObject * poSelf, PyObject * poArgs) +{ + int iVolume; + if (!PyTuple_GetInteger(poArgs, 0, &iVolume)) + return Py_BuildException(); + + CSoundManager& rkSndMgr=CSoundManager::Instance(); + rkSndMgr.SetSoundVolumeGrade(iVolume); + return Py_BuildNone(); +} + +PyObject * sndSetSoundScale(PyObject * poSelf, PyObject * poArgs) +{ + float fScale; + if (!PyTuple_GetFloat(poArgs, 0, &fScale)) + return Py_BuildException(); + + CSoundManager& rkSndMgr=CSoundManager::Instance(); + rkSndMgr.SetSoundScale(fScale); + return Py_BuildNone(); +} + +PyObject * sndSetAmbienceSoundScale(PyObject * poSelf, PyObject * poArgs) +{ + float fScale; + if (!PyTuple_GetFloat(poArgs, 0, &fScale)) + return Py_BuildException(); + + CSoundManager& rkSndMgr=CSoundManager::Instance(); + rkSndMgr.SetAmbienceSoundScale(fScale); + return Py_BuildNone(); +} + +void initsnd() +{ + static PyMethodDef s_methods[] = + { + { "PlaySound", sndPlaySound, METH_VARARGS }, + { "PlaySound3D", sndPlaySound3D, METH_VARARGS }, + { "PlayMusic", sndPlayMusic, METH_VARARGS }, + { "FadeInMusic", sndFadeInMusic, METH_VARARGS }, + { "FadeOutMusic", sndFadeOutMusic, METH_VARARGS }, + { "FadeOutAllMusic", sndFadeOutAllMusic, METH_VARARGS }, + { "FadeLimitOutMusic", sndFadeLimitOutMusic, METH_VARARGS }, + { "StopAllSound", sndStopAllSound, METH_VARARGS }, + + { "SetMusicVolumef", sndSetMusicVolume, METH_VARARGS }, + { "SetMusicVolume", sndSetMusicVolume, METH_VARARGS }, + { "SetSoundVolumef", sndSetSoundVolumef, METH_VARARGS }, + { "SetSoundVolume", sndSetSoundVolume, METH_VARARGS }, + { "SetSoundScale", sndSetSoundScale, METH_VARARGS }, + { "SetAmbienceSoundScale", sndSetAmbienceSoundScale, METH_VARARGS }, + { NULL, NULL, NULL }, + }; + + Py_InitModule("snd", s_methods); +} \ No newline at end of file diff --git a/source/UserInterface/PythonSystem.cpp b/source/UserInterface/PythonSystem.cpp new file mode 100644 index 0000000..89104b3 --- /dev/null +++ b/source/UserInterface/PythonSystem.cpp @@ -0,0 +1,681 @@ +#include "StdAfx.h" +#include "PythonSystem.h" +#include "PythonApplication.h" + +#define DEFAULT_VALUE_ALWAYS_SHOW_NAME true + +void CPythonSystem::SetInterfaceHandler(PyObject * poHandler) +{ +// NOTE : ۷ īƮ ٲ ʴ´. ۷ ־ Python ʱ . +// ſ __del__ Destroy ȣ Handler NULL Ѵ. - [levites] +// if (m_poInterfaceHandler) +// Py_DECREF(m_poInterfaceHandler); + + m_poInterfaceHandler = poHandler; + +// if (m_poInterfaceHandler) +// Py_INCREF(m_poInterfaceHandler); +} + +void CPythonSystem::DestroyInterfaceHandler() +{ + m_poInterfaceHandler = NULL; +} + +void CPythonSystem::SaveWindowStatus(int iIndex, int iVisible, int iMinimized, int ix, int iy, int iHeight) +{ + m_WindowStatus[iIndex].isVisible = iVisible; + m_WindowStatus[iIndex].isMinimized = iMinimized; + m_WindowStatus[iIndex].ixPosition = ix; + m_WindowStatus[iIndex].iyPosition = iy; + m_WindowStatus[iIndex].iHeight = iHeight; +} + +void CPythonSystem::GetDisplaySettings() +{ + memset(m_ResolutionList, 0, sizeof(TResolution) * RESOLUTION_MAX_NUM); + m_ResolutionCount = 0; + + LPDIRECT3D8 lpD3D = CPythonGraphic::Instance().GetD3D(); + + D3DADAPTER_IDENTIFIER8 d3dAdapterIdentifier; + D3DDISPLAYMODE d3ddmDesktop; + + lpD3D->GetAdapterIdentifier(0, D3DENUM_NO_WHQL_LEVEL, &d3dAdapterIdentifier); + lpD3D->GetAdapterDisplayMode(0, &d3ddmDesktop); + + // Ͱ ִ ÷ 尹 Ѵ.. + DWORD dwNumAdapterModes = lpD3D->GetAdapterModeCount(0); + + for (UINT iMode = 0; iMode < dwNumAdapterModes; iMode++) + { + D3DDISPLAYMODE DisplayMode; + lpD3D->EnumAdapterModes(0, iMode, &DisplayMode); + DWORD bpp = 0; + + // 800 600 ̻ ɷ. + if (DisplayMode.Width < 800 || DisplayMode.Height < 600) + continue; + + // ϴ 16bbp 32bbp . + // 16bbp óϰԲ - [levites] + if (DisplayMode.Format == D3DFMT_R5G6B5) + bpp = 16; + else if (DisplayMode.Format == D3DFMT_X8R8G8B8) + bpp = 32; + else + continue; + + int check_res = false; + + for (int i = 0; !check_res && i < m_ResolutionCount; ++i) + { + if (m_ResolutionList[i].bpp != bpp || + m_ResolutionList[i].width != DisplayMode.Width || + m_ResolutionList[i].height != DisplayMode.Height) + continue; + + int check_fre = false; + + // ø ٸǷ ø ش. + for (int j = 0; j < m_ResolutionList[i].frequency_count; ++j) + { + if (m_ResolutionList[i].frequency[j] == DisplayMode.RefreshRate) + { + check_fre = true; + break; + } + } + + if (!check_fre) + if (m_ResolutionList[i].frequency_count < FREQUENCY_MAX_NUM) + m_ResolutionList[i].frequency[m_ResolutionList[i].frequency_count++] = DisplayMode.RefreshRate; + + check_res = true; + } + + if (!check_res) + { + // ο Ŵϱ ߰. + if (m_ResolutionCount < RESOLUTION_MAX_NUM) + { + m_ResolutionList[m_ResolutionCount].width = DisplayMode.Width; + m_ResolutionList[m_ResolutionCount].height = DisplayMode.Height; + m_ResolutionList[m_ResolutionCount].bpp = bpp; + m_ResolutionList[m_ResolutionCount].frequency[0] = DisplayMode.RefreshRate; + m_ResolutionList[m_ResolutionCount].frequency_count = 1; + + ++m_ResolutionCount; + } + } + } +} + +int CPythonSystem::GetResolutionCount() +{ + return m_ResolutionCount; +} + +int CPythonSystem::GetFrequencyCount(int index) +{ + if (index >= m_ResolutionCount) + return 0; + + return m_ResolutionList[index].frequency_count; +} + +bool CPythonSystem::GetResolution(int index, OUT DWORD *width, OUT DWORD *height, OUT DWORD *bpp) +{ + if (index >= m_ResolutionCount) + return false; + + *width = m_ResolutionList[index].width; + *height = m_ResolutionList[index].height; + *bpp = m_ResolutionList[index].bpp; + return true; +} + +bool CPythonSystem::GetFrequency(int index, int freq_index, OUT DWORD *frequncy) +{ + if (index >= m_ResolutionCount) + return false; + + if (freq_index >= m_ResolutionList[index].frequency_count) + return false; + + *frequncy = m_ResolutionList[index].frequency[freq_index]; + return true; +} + +int CPythonSystem::GetResolutionIndex(DWORD width, DWORD height, DWORD bit) +{ + DWORD re_width, re_height, re_bit; + int i = 0; + + while (GetResolution(i, &re_width, &re_height, &re_bit)) + { + if (re_width == width) + if (re_height == height) + if (re_bit == bit) + return i; + i++; + } + + return 0; +} + +int CPythonSystem::GetFrequencyIndex(int res_index, DWORD frequency) +{ + DWORD re_frequency; + int i = 0; + + while (GetFrequency(res_index, i, &re_frequency)) + { + if (re_frequency == frequency) + return i; + + i++; + } + + return 0; +} + +DWORD CPythonSystem::GetWidth() +{ + return m_Config.width; +} + +DWORD CPythonSystem::GetHeight() +{ + return m_Config.height; +} +DWORD CPythonSystem::GetBPP() +{ + return m_Config.bpp; +} +DWORD CPythonSystem::GetFrequency() +{ + return m_Config.frequency; +} + +bool CPythonSystem::IsNoSoundCard() +{ + return m_Config.bNoSoundCard; +} + +bool CPythonSystem::IsSoftwareCursor() +{ + return m_Config.is_software_cursor; +} + +float CPythonSystem::GetMusicVolume() +{ + return m_Config.music_volume; +} + +int CPythonSystem::GetSoundVolume() +{ + return m_Config.voice_volume; +} + +void CPythonSystem::SetMusicVolume(float fVolume) +{ + m_Config.music_volume = fVolume; +} + +void CPythonSystem::SetSoundVolumef(float fVolume) +{ + m_Config.voice_volume = int(5 * fVolume); +} + +int CPythonSystem::GetDistance() +{ + return m_Config.iDistance; +} + +int CPythonSystem::GetShadowLevel() +{ + return m_Config.iShadowLevel; +} + +void CPythonSystem::SetShadowLevel(unsigned int level) +{ + m_Config.iShadowLevel = MIN(level, 5); + CPythonBackground::instance().RefreshShadowLevel(); +} + +int CPythonSystem::IsSaveID() +{ + return m_Config.isSaveID; +} + +const char * CPythonSystem::GetSaveID() +{ + return m_Config.SaveID; +} + +bool CPythonSystem::isViewCulling() +{ + return m_Config.is_object_culling; +} + +void CPythonSystem::SetSaveID(int iValue, const char * c_szSaveID) +{ + if (iValue != 1) + return; + + m_Config.isSaveID = iValue; + strncpy(m_Config.SaveID, c_szSaveID, sizeof(m_Config.SaveID) - 1); +} + +CPythonSystem::TConfig * CPythonSystem::GetConfig() +{ + return &m_Config; +} + +void CPythonSystem::SetConfig(TConfig * pNewConfig) +{ + m_Config = *pNewConfig; +} + +void CPythonSystem::SetDefaultConfig() +{ + memset(&m_Config, 0, sizeof(m_Config)); + + m_Config.width = 1024; + m_Config.height = 768; + m_Config.bpp = 32; + +#if defined( LOCALE_SERVICE_WE_JAPAN ) + m_Config.bWindowed = true; +#else + m_Config.bWindowed = false; +#endif + + m_Config.is_software_cursor = false; + m_Config.is_object_culling = true; + m_Config.iDistance = 3; + + m_Config.gamma = 3; + m_Config.music_volume = 1.0f; + m_Config.voice_volume = 5; + + m_Config.bDecompressDDS = 0; + m_Config.bSoftwareTiling = 0; + m_Config.iShadowLevel = 3; + m_Config.bViewChat = true; + m_Config.bAlwaysShowName = DEFAULT_VALUE_ALWAYS_SHOW_NAME; + m_Config.bShowDamage = true; + m_Config.bShowSalesText = true; +} + +bool CPythonSystem::IsWindowed() +{ + return m_Config.bWindowed; +} + +bool CPythonSystem::IsViewChat() +{ + return m_Config.bViewChat; +} + +void CPythonSystem::SetViewChatFlag(int iFlag) +{ + m_Config.bViewChat = iFlag == 1 ? true : false; +} + +bool CPythonSystem::IsAlwaysShowName() +{ + return m_Config.bAlwaysShowName; +} + +void CPythonSystem::SetAlwaysShowNameFlag(int iFlag) +{ + m_Config.bAlwaysShowName = iFlag == 1 ? true : false; +} + +bool CPythonSystem::IsShowDamage() +{ + return m_Config.bShowDamage; +} + +void CPythonSystem::SetShowDamageFlag(int iFlag) +{ + m_Config.bShowDamage = iFlag == 1 ? true : false; +} + +bool CPythonSystem::IsShowSalesText() +{ + return m_Config.bShowSalesText; +} + +void CPythonSystem::SetShowSalesTextFlag(int iFlag) +{ + m_Config.bShowSalesText = iFlag == 1 ? true : false; +} + +bool CPythonSystem::IsAutoTiling() +{ + if (m_Config.bSoftwareTiling == 0) + return true; + + return false; +} + +void CPythonSystem::SetSoftwareTiling(bool isEnable) +{ + if (isEnable) + m_Config.bSoftwareTiling=1; + else + m_Config.bSoftwareTiling=2; +} + +bool CPythonSystem::IsSoftwareTiling() +{ + if (m_Config.bSoftwareTiling==1) + return true; + + return false; +} + +bool CPythonSystem::IsUseDefaultIME() +{ + return m_Config.bUseDefaultIME; +} + +bool CPythonSystem::LoadConfig() +{ + FILE * fp = NULL; + + if (NULL == (fp = fopen("metin2.cfg", "rt"))) + return false; + + char buf[256]; + char command[256]; + char value[256]; + + while (fgets(buf, 256, fp)) + { + if (sscanf(buf, " %s %s\n", command, value) == EOF) + break; + + if (!stricmp(command, "WIDTH")) + m_Config.width = atoi(value); + else if (!stricmp(command, "HEIGHT")) + m_Config.height = atoi(value); + else if (!stricmp(command, "BPP")) + m_Config.bpp = atoi(value); + else if (!stricmp(command, "FREQUENCY")) + m_Config.frequency = atoi(value); + else if (!stricmp(command, "SOFTWARE_CURSOR")) + m_Config.is_software_cursor = atoi(value) ? true : false; + else if (!stricmp(command, "OBJECT_CULLING")) + m_Config.is_object_culling = atoi(value) ? true : false; + else if (!stricmp(command, "VISIBILITY")) + m_Config.iDistance = atoi(value); + else if (!stricmp(command, "MUSIC_VOLUME")) { + if(strchr(value, '.') == 0) { // Old compatiability + m_Config.music_volume = pow(10.0f, (-1.0f + (((float) atoi(value)) / 5.0f))); + if(atoi(value) == 0) + m_Config.music_volume = 0.0f; + } else + m_Config.music_volume = atof(value); + } else if (!stricmp(command, "VOICE_VOLUME")) + m_Config.voice_volume = (char) atoi(value); + else if (!stricmp(command, "GAMMA")) + m_Config.gamma = atoi(value); + else if (!stricmp(command, "IS_SAVE_ID")) + m_Config.isSaveID = atoi(value); + else if (!stricmp(command, "SAVE_ID")) + strncpy(m_Config.SaveID, value, 20); + else if (!stricmp(command, "PRE_LOADING_DELAY_TIME")) + g_iLoadingDelayTime = atoi(value); + else if (!stricmp(command, "WINDOWED")) + { + m_Config.bWindowed = atoi(value) == 1 ? true : false; + } + else if (!stricmp(command, "USE_DEFAULT_IME")) + m_Config.bUseDefaultIME = atoi(value) == 1 ? true : false; + else if (!stricmp(command, "SOFTWARE_TILING")) + m_Config.bSoftwareTiling = atoi(value); + else if (!stricmp(command, "SHADOW_LEVEL")) + m_Config.iShadowLevel = atoi(value); + else if (!stricmp(command, "DECOMPRESSED_TEXTURE")) + m_Config.bDecompressDDS = atoi(value) == 1 ? true : false; + else if (!stricmp(command, "NO_SOUND_CARD")) + m_Config.bNoSoundCard = atoi(value) == 1 ? true : false; + else if (!stricmp(command, "VIEW_CHAT")) + m_Config.bViewChat = atoi(value) == 1 ? true : false; + else if (!stricmp(command, "ALWAYS_VIEW_NAME")) + m_Config.bAlwaysShowName = atoi(value) == 1 ? true : false; + else if (!stricmp(command, "SHOW_DAMAGE")) + m_Config.bShowDamage = atoi(value) == 1 ? true : false; + else if (!stricmp(command, "SHOW_SALESTEXT")) + m_Config.bShowSalesText = atoi(value) == 1 ? true : false; + } + + if (m_Config.bWindowed) + { + unsigned screen_width = GetSystemMetrics(SM_CXFULLSCREEN); + unsigned screen_height = GetSystemMetrics(SM_CYFULLSCREEN); + + if (m_Config.width >= screen_width) + { + m_Config.width = screen_width; + } + // if (m_Config.height >= screen_height) + // { + // m_Config.height = screen_height; + // } + if (m_Config.height >= screen_height) //Fix + { + int config_height = m_Config.height; + int difference = (config_height-screen_height)+7; + m_Config.height = config_height - difference; + } + } + + m_OldConfig = m_Config; + + fclose(fp); + +// Tracef("LoadConfig: Resolution: %dx%d %dBPP %dHZ Software Cursor: %d, Music/Voice Volume: %d/%d Gamma: %d\n", +// m_Config.width, +// m_Config.height, +// m_Config.bpp, +// m_Config.frequency, +// m_Config.is_software_cursor, +// m_Config.music_volume, +// m_Config.voice_volume, +// m_Config.gamma); + + return true; +} + +bool CPythonSystem::SaveConfig() +{ + FILE *fp; + + if (NULL == (fp = fopen("metin2.cfg", "wt"))) + return false; + + fprintf(fp, "WIDTH %d\n" + "HEIGHT %d\n" + "BPP %d\n" + "FREQUENCY %d\n" + "SOFTWARE_CURSOR %d\n" + "OBJECT_CULLING %d\n" + "VISIBILITY %d\n" + "MUSIC_VOLUME %.3f\n" + "VOICE_VOLUME %d\n" + "GAMMA %d\n" + "IS_SAVE_ID %d\n" + "SAVE_ID %s\n" + "PRE_LOADING_DELAY_TIME %d\n" + "DECOMPRESSED_TEXTURE %d\n", + m_Config.width, + m_Config.height, + m_Config.bpp, + m_Config.frequency, + m_Config.is_software_cursor, + m_Config.is_object_culling, + m_Config.iDistance, + m_Config.music_volume, + m_Config.voice_volume, + m_Config.gamma, + m_Config.isSaveID, + m_Config.SaveID, + g_iLoadingDelayTime, + m_Config.bDecompressDDS); + + if (m_Config.bWindowed == 1) + fprintf(fp, "WINDOWED %d\n", m_Config.bWindowed); + if (m_Config.bViewChat == 0) + fprintf(fp, "VIEW_CHAT %d\n", m_Config.bViewChat); + if (m_Config.bAlwaysShowName != DEFAULT_VALUE_ALWAYS_SHOW_NAME) + fprintf(fp, "ALWAYS_VIEW_NAME %d\n", m_Config.bAlwaysShowName); + if (m_Config.bShowDamage == 0) + fprintf(fp, "SHOW_DAMAGE %d\n", m_Config.bShowDamage); + if (m_Config.bShowSalesText == 0) + fprintf(fp, "SHOW_SALESTEXT %d\n", m_Config.bShowSalesText); + + fprintf(fp, "USE_DEFAULT_IME %d\n", m_Config.bUseDefaultIME); + fprintf(fp, "SOFTWARE_TILING %d\n", m_Config.bSoftwareTiling); + fprintf(fp, "SHADOW_LEVEL %d\n", m_Config.iShadowLevel); + fprintf(fp, "\n"); + + fclose(fp); + return true; +} + +bool CPythonSystem::LoadInterfaceStatus() +{ + FILE * File; + File = fopen("interface.cfg", "rb"); + + if (!File) + return false; + + fread(m_WindowStatus, 1, sizeof(TWindowStatus) * WINDOW_MAX_NUM, File); + fclose(File); + return true; +} + +void CPythonSystem::SaveInterfaceStatus() +{ + if (!m_poInterfaceHandler) + return; + + PyCallClassMemberFunc(m_poInterfaceHandler, "OnSaveInterfaceStatus", Py_BuildValue("()")); + + FILE * File; + + File = fopen("interface.cfg", "wb"); + + if (!File) + { + TraceError("Cannot open interface.cfg"); + return; + } + + fwrite(m_WindowStatus, 1, sizeof(TWindowStatus) * WINDOW_MAX_NUM, File); + fclose(File); +} + +bool CPythonSystem::isInterfaceConfig() +{ + return m_isInterfaceConfig; +} + +const CPythonSystem::TWindowStatus & CPythonSystem::GetWindowStatusReference(int iIndex) +{ + return m_WindowStatus[iIndex]; +} + +void CPythonSystem::ApplyConfig() // ؼ ٲ Ѵ. +{ + if (m_OldConfig.gamma != m_Config.gamma) + { + float val = 1.0f; + + switch (m_Config.gamma) + { + case 0: val = 0.4f; break; + case 1: val = 0.7f; break; + case 2: val = 1.0f; break; + case 3: val = 1.2f; break; + case 4: val = 1.4f; break; + } + + CPythonGraphic::Instance().SetGamma(val); + } + + if (m_OldConfig.is_software_cursor != m_Config.is_software_cursor) + { + if (m_Config.is_software_cursor) + CPythonApplication::Instance().SetCursorMode(CPythonApplication::CURSOR_MODE_SOFTWARE); + else + CPythonApplication::Instance().SetCursorMode(CPythonApplication::CURSOR_MODE_HARDWARE); + } + + m_OldConfig = m_Config; + + ChangeSystem(); +} + +void CPythonSystem::ChangeSystem() +{ + // Shadow + /* + if (m_Config.is_shadow) + CScreen::SetShadowFlag(true); + else + CScreen::SetShadowFlag(false); + */ + CSoundManager& rkSndMgr = CSoundManager::Instance(); + /* + float fMusicVolume; + if (0 == m_Config.music_volume) + fMusicVolume = 0.0f; + else + fMusicVolume= (float)pow(10.0f, (-1.0f + (float)m_Config.music_volume / 5.0f)); + */ + rkSndMgr.SetMusicVolume(m_Config.music_volume); + + /* + float fVoiceVolume; + if (0 == m_Config.voice_volume) + fVoiceVolume = 0.0f; + else + fVoiceVolume = (float)pow(10.0f, (-1.0f + (float)m_Config.voice_volume / 5.0f)); + */ + rkSndMgr.SetSoundVolumeGrade(m_Config.voice_volume); +} + +void CPythonSystem::Clear() +{ + SetInterfaceHandler(NULL); +} + +CPythonSystem::CPythonSystem() +{ + memset(&m_Config, 0, sizeof(TConfig)); + + m_poInterfaceHandler = NULL; + + SetDefaultConfig(); + + LoadConfig(); + + ChangeSystem(); + + if (LoadInterfaceStatus()) + m_isInterfaceConfig = true; + else + m_isInterfaceConfig = false; +} + +CPythonSystem::~CPythonSystem() +{ + assert(m_poInterfaceHandler==NULL && "CPythonSystem MUST CLEAR!"); +} diff --git a/source/UserInterface/PythonSystem.h b/source/UserInterface/PythonSystem.h new file mode 100644 index 0000000..f70d2b3 --- /dev/null +++ b/source/UserInterface/PythonSystem.h @@ -0,0 +1,162 @@ +#pragma once + +class CPythonSystem : public CSingleton +{ + public: + enum EWindow + { + WINDOW_STATUS, + WINDOW_INVENTORY, + WINDOW_ABILITY, + WINDOW_SOCIETY, + WINDOW_JOURNAL, + WINDOW_COMMAND, + + WINDOW_QUICK, + WINDOW_GAUGE, + WINDOW_MINIMAP, + WINDOW_CHAT, + + WINDOW_MAX_NUM, + }; + + enum + { + FREQUENCY_MAX_NUM = 30, + RESOLUTION_MAX_NUM = 100 + }; + + typedef struct SResolution + { + DWORD width; + DWORD height; + DWORD bpp; // bits per pixel (high-color = 16bpp, true-color = 32bpp) + + DWORD frequency[20]; + BYTE frequency_count; + } TResolution; + + typedef struct SWindowStatus + { + int isVisible; + int isMinimized; + + int ixPosition; + int iyPosition; + int iHeight; + } TWindowStatus; + + typedef struct SConfig + { + DWORD width; + DWORD height; + DWORD bpp; + DWORD frequency; + + bool is_software_cursor; + bool is_object_culling; + int iDistance; + int iShadowLevel; + + FLOAT music_volume; + BYTE voice_volume; + + int gamma; + + int isSaveID; + char SaveID[20]; + + bool bWindowed; + bool bDecompressDDS; + bool bNoSoundCard; + bool bUseDefaultIME; + BYTE bSoftwareTiling; + bool bViewChat; + bool bAlwaysShowName; + bool bShowDamage; + bool bShowSalesText; + } TConfig; + + public: + CPythonSystem(); + virtual ~CPythonSystem(); + + void Clear(); + void SetInterfaceHandler(PyObject * poHandler); + void DestroyInterfaceHandler(); + + // Config + void SetDefaultConfig(); + bool LoadConfig(); + bool SaveConfig(); + void ApplyConfig(); + void SetConfig(TConfig * set_config); + TConfig * GetConfig(); + void ChangeSystem(); + + // Interface + bool LoadInterfaceStatus(); + void SaveInterfaceStatus(); + bool isInterfaceConfig(); + const TWindowStatus & GetWindowStatusReference(int iIndex); + + DWORD GetWidth(); + DWORD GetHeight(); + DWORD GetBPP(); + DWORD GetFrequency(); + bool IsSoftwareCursor(); + bool IsWindowed(); + bool IsViewChat(); + bool IsAlwaysShowName(); + bool IsShowDamage(); + bool IsShowSalesText(); + bool IsUseDefaultIME(); + bool IsNoSoundCard(); + bool IsAutoTiling(); + bool IsSoftwareTiling(); + void SetSoftwareTiling(bool isEnable); + void SetViewChatFlag(int iFlag); + void SetAlwaysShowNameFlag(int iFlag); + void SetShowDamageFlag(int iFlag); + void SetShowSalesTextFlag(int iFlag); + + // Window + void SaveWindowStatus(int iIndex, int iVisible, int iMinimized, int ix, int iy, int iHeight); + + // SaveID + int IsSaveID(); + const char * GetSaveID(); + void SetSaveID(int iValue, const char * c_szSaveID); + + /// Display + void GetDisplaySettings(); + + int GetResolutionCount(); + int GetFrequencyCount(int index); + bool GetResolution(int index, OUT DWORD *width, OUT DWORD *height, OUT DWORD *bpp); + bool GetFrequency(int index, int freq_index, OUT DWORD *frequncy); + int GetResolutionIndex(DWORD width, DWORD height, DWORD bpp); + int GetFrequencyIndex(int res_index, DWORD frequency); + bool isViewCulling(); + + // Sound + float GetMusicVolume(); + int GetSoundVolume(); + void SetMusicVolume(float fVolume); + void SetSoundVolumef(float fVolume); + + int GetDistance(); + int GetShadowLevel(); + void SetShadowLevel(unsigned int level); + + protected: + TResolution m_ResolutionList[RESOLUTION_MAX_NUM]; + int m_ResolutionCount; + + TConfig m_Config; + TConfig m_OldConfig; + + bool m_isInterfaceConfig; + PyObject * m_poInterfaceHandler; + TWindowStatus m_WindowStatus[WINDOW_MAX_NUM]; +}; \ No newline at end of file diff --git a/source/UserInterface/PythonSystemModule.cpp b/source/UserInterface/PythonSystemModule.cpp new file mode 100644 index 0000000..bc4f356 --- /dev/null +++ b/source/UserInterface/PythonSystemModule.cpp @@ -0,0 +1,445 @@ +#include "StdAfx.h" +#include "PythonSystem.h" + +PyObject * systemGetWidth(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildValue("i", CPythonSystem::Instance().GetWidth()); +} + +PyObject * systemGetHeight(PyObject* poSelf, PyObject* poArgs) +{ + return Py_BuildValue("i", CPythonSystem::Instance().GetHeight()); +} + +PyObject * systemSetInterfaceHandler(PyObject* poSelf, PyObject* poArgs) +{ + PyObject* poHandler; + if (!PyTuple_GetObject(poArgs, 0, &poHandler)) + return Py_BuildException(); + + CPythonSystem::Instance().SetInterfaceHandler(poHandler); + return Py_BuildNone(); +} + +PyObject * systemDestroyInterfaceHandler(PyObject* poSelf, PyObject* poArgs) +{ + CPythonSystem::Instance().DestroyInterfaceHandler(); + return Py_BuildNone(); +} + +PyObject * systemReserveResource(PyObject* poSelf, PyObject* poArgs) +{ + std::set ResourceSet; + CResourceManager::Instance().PushBackgroundLoadingSet(ResourceSet); + return Py_BuildNone(); +} + +PyObject * systemisInterfaceConfig(PyObject* poSelf, PyObject* poArgs) +{ + int isInterfaceConfig = CPythonSystem::Instance().isInterfaceConfig(); + return Py_BuildValue("i", isInterfaceConfig); +} + +PyObject * systemSaveWindowStatus(PyObject* poSelf, PyObject* poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + + int iVisible; + if (!PyTuple_GetInteger(poArgs, 1, &iVisible)) + return Py_BuildException(); + + int iMinimized; + if (!PyTuple_GetInteger(poArgs, 2, &iMinimized)) + return Py_BuildException(); + + int ix; + if (!PyTuple_GetInteger(poArgs, 3, &ix)) + return Py_BuildException(); + + int iy; + if (!PyTuple_GetInteger(poArgs, 4, &iy)) + return Py_BuildException(); + + int iHeight; + if (!PyTuple_GetInteger(poArgs, 5, &iHeight)) + return Py_BuildException(); + + CPythonSystem::Instance().SaveWindowStatus(iIndex, iVisible, iMinimized, ix, iy, iHeight); + return Py_BuildNone(); +} + +PyObject * systemGetWindowStatus(PyObject* poSelf, PyObject* poArgs) +{ + int iIndex; + if (!PyTuple_GetInteger(poArgs, 0, &iIndex)) + return Py_BuildException(); + + const CPythonSystem::TWindowStatus & c_rWindowStatus = CPythonSystem::Instance().GetWindowStatusReference(iIndex); + return Py_BuildValue("iiiii", c_rWindowStatus.isVisible, + c_rWindowStatus.isMinimized, + c_rWindowStatus.ixPosition, + c_rWindowStatus.iyPosition, + c_rWindowStatus.iHeight); +} + +PyObject * systemGetConfig(PyObject * poSelf, PyObject * poArgs) +{ + CPythonSystem::TConfig *tmp = CPythonSystem::Instance().GetConfig(); + + int iRes = CPythonSystem::Instance().GetResolutionIndex(tmp->width, tmp->height, tmp->bpp); + int iFrequency = CPythonSystem::Instance().GetFrequencyIndex(iRes, tmp->frequency); + + return Py_BuildValue("iiiiiiii", iRes, + iFrequency, + tmp->is_software_cursor, + tmp->is_object_culling, + tmp->music_volume, + tmp->voice_volume, + tmp->gamma, + tmp->iDistance); +} + +PyObject * systemSetSaveID(PyObject * poSelf, PyObject * poArgs) +{ + int iValue; + if (!PyTuple_GetInteger(poArgs, 0, &iValue)) + return Py_BuildException(); + + char * szSaveID; + if (!PyTuple_GetString(poArgs, 1, &szSaveID)) + return Py_BuildException(); + + CPythonSystem::Instance().SetSaveID(iValue, szSaveID); + return Py_BuildNone(); +} + +PyObject * systemisSaveID(PyObject * poSelf, PyObject * poArgs) +{ + int value = CPythonSystem::Instance().IsSaveID(); + return Py_BuildValue("i", value); +} + +PyObject * systemGetSaveID(PyObject * poSelf, PyObject * poArgs) +{ + const char * c_szSaveID = CPythonSystem::Instance().GetSaveID(); + return Py_BuildValue("s", c_szSaveID); +} + +PyObject * systemGetMusicVolume(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("f", CPythonSystem::Instance().GetMusicVolume()); +} + +PyObject * systemGetSoundVolume(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonSystem::Instance().GetSoundVolume()); +} + +PyObject * systemSetMusicVolume(PyObject * poSelf, PyObject * poArgs) +{ + float fVolume; + if (!PyTuple_GetFloat(poArgs, 0, &fVolume)) + return Py_BuildException(); + + CPythonSystem::Instance().SetMusicVolume(fVolume); + return Py_BuildNone(); +} + +PyObject * systemSetSoundVolumef(PyObject * poSelf, PyObject * poArgs) +{ + float fVolume; + if (!PyTuple_GetFloat(poArgs, 0, &fVolume)) + return Py_BuildException(); + + CPythonSystem::Instance().SetSoundVolumef(fVolume); + return Py_BuildNone(); +} + +PyObject * systemIsSoftwareCursor(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonSystem::Instance().IsSoftwareCursor()); +} + +PyObject * systemSetViewChatFlag(PyObject * poSelf, PyObject * poArgs) +{ + int iFlag; + if (!PyTuple_GetInteger(poArgs, 0, &iFlag)) + return Py_BuildException(); + + CPythonSystem::Instance().SetViewChatFlag(iFlag); + + return Py_BuildNone(); +} + +PyObject * systemIsViewChat(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonSystem::Instance().IsViewChat()); +} + +PyObject * systemSetAlwaysShowNameFlag(PyObject * poSelf, PyObject * poArgs) +{ + int iFlag; + if (!PyTuple_GetInteger(poArgs, 0, &iFlag)) + return Py_BuildException(); + + CPythonSystem::Instance().SetAlwaysShowNameFlag(iFlag); + + return Py_BuildNone(); +} + +PyObject * systemSetShowDamageFlag(PyObject * poSelf, PyObject * poArgs) +{ + int iFlag; + if (!PyTuple_GetInteger(poArgs, 0, &iFlag)) + return Py_BuildException(); + + CPythonSystem::Instance().SetShowDamageFlag(iFlag); + + return Py_BuildNone(); +} + +PyObject * systemSetShowSalesTextFlag(PyObject * poSelf, PyObject * poArgs) +{ + int iFlag; + if (!PyTuple_GetInteger(poArgs, 0, &iFlag)) + return Py_BuildException(); + + CPythonSystem::Instance().SetShowSalesTextFlag(iFlag); + + return Py_BuildNone(); +} + +PyObject * systemIsAlwaysShowName(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonSystem::Instance().IsAlwaysShowName()); +} + +PyObject * systemIsShowDamage(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonSystem::Instance().IsShowDamage()); +} + +PyObject * systemIsShowSalesText(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonSystem::Instance().IsShowSalesText()); +} + +PyObject * systemSetConfig(PyObject * poSelf, PyObject * poArgs) +{ + int res_index; + int width; + int height; + int bpp; + int frequency_index; + int frequency; + int software_cursor; + int shadow; + int object_culling; + int music_volume; + int voice_volume; + int gamma; + int distance; + + if (!PyTuple_GetInteger(poArgs, 0, &res_index)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 1, &frequency_index)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 2, &software_cursor)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 3, &shadow)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 4, &object_culling)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 5, &music_volume)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 6, &voice_volume)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 7, &gamma)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 8, &distance)) + return Py_BuildException(); + + if (!CPythonSystem::Instance().GetResolution(res_index, (DWORD *) &width, (DWORD *) &height, (DWORD *) &bpp)) + return Py_BuildNone(); + + if (!CPythonSystem::Instance().GetFrequency(res_index,frequency_index, (DWORD *) &frequency)) + return Py_BuildNone(); + + CPythonSystem::TConfig tmp; + + memcpy(&tmp, CPythonSystem::Instance().GetConfig(), sizeof(tmp)); + + tmp.width = width; + tmp.height = height; + tmp.bpp = bpp; + tmp.frequency = frequency; + tmp.is_software_cursor = software_cursor ? true : false; + tmp.is_object_culling = object_culling ? true : false; + tmp.music_volume = (char) music_volume; + tmp.voice_volume = (char) voice_volume; + tmp.gamma = gamma; + tmp.iDistance = distance; + + CPythonSystem::Instance().SetConfig(&tmp); + return Py_BuildNone(); +} + +PyObject * systemApplyConfig(PyObject * poSelf, PyObject * poArgs) +{ + CPythonSystem::Instance().ApplyConfig(); + return Py_BuildNone(); +} + +PyObject * systemSaveConfig(PyObject * poSelf, PyObject * poArgs) +{ + int ret = CPythonSystem::Instance().SaveConfig(); + return Py_BuildValue("i", ret); +} + +PyObject * systemGetResolutionCount(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonSystem::Instance().GetResolutionCount()); +} + +PyObject * systemGetFrequencyCount(PyObject * poSelf, PyObject * poArgs) +{ + int index; + + if (!PyTuple_GetInteger(poArgs, 0, &index)) + return Py_BuildException(); + + return Py_BuildValue("i", CPythonSystem::Instance().GetFrequencyCount(index)); +} + +PyObject * systemGetResolution(PyObject * poSelf, PyObject * poArgs) +{ + int index; + DWORD width = 0, height = 0, bpp = 0; + + if (!PyTuple_GetInteger(poArgs, 0, &index)) + return Py_BuildException(); + + CPythonSystem::Instance().GetResolution(index, &width, &height, &bpp); + return Py_BuildValue("iii", width, height, bpp); +} + +PyObject * systemGetCurrentResolution(PyObject * poSelf, PyObject *poArgs) +{ + CPythonSystem::TConfig *tmp = CPythonSystem::Instance().GetConfig(); + return Py_BuildValue("iii", tmp->width, tmp->height, tmp->bpp); +} + +PyObject * systemGetFrequency(PyObject * poSelf, PyObject * poArgs) +{ + int index, frequency_index; + DWORD frequency = 0; + + if (!PyTuple_GetInteger(poArgs, 0, &index)) + return Py_BuildException(); + + if (!PyTuple_GetInteger(poArgs, 1, &frequency_index)) + return Py_BuildException(); + + CPythonSystem::Instance().GetFrequency(index, frequency_index, &frequency); + return Py_BuildValue("i", frequency); +} + +PyObject * systemGetShadowLevel(PyObject * poSelf, PyObject * poArgs) +{ + return Py_BuildValue("i", CPythonSystem::Instance().GetShadowLevel()); +} + +PyObject * systemSetShadowLevel(PyObject * poSelf, PyObject * poArgs) +{ + int level; + + if (!PyTuple_GetInteger(poArgs, 0, &level)) + return Py_BuildException(); + + if (level > 0) + CPythonSystem::Instance().SetShadowLevel(level); + + return Py_BuildNone(); +} + +void initsystem() +{ + static PyMethodDef s_methods[] = + { + { "GetWidth", systemGetWidth, METH_VARARGS }, + { "GetHeight", systemGetHeight, METH_VARARGS }, + + { "SetInterfaceHandler", systemSetInterfaceHandler, METH_VARARGS }, + { "DestroyInterfaceHandler", systemDestroyInterfaceHandler, METH_VARARGS }, + { "ReserveResource", systemReserveResource, METH_VARARGS }, + + { "isInterfaceConfig", systemisInterfaceConfig, METH_VARARGS }, + { "SaveWindowStatus", systemSaveWindowStatus, METH_VARARGS }, + { "GetWindowStatus", systemGetWindowStatus, METH_VARARGS }, + + { "GetResolutionCount", systemGetResolutionCount, METH_VARARGS }, + { "GetFrequencyCount", systemGetFrequencyCount, METH_VARARGS }, + + { "GetCurrentResolution", systemGetCurrentResolution, METH_VARARGS }, + + { "GetResolution", systemGetResolution, METH_VARARGS }, + { "GetFrequency", systemGetFrequency, METH_VARARGS }, + + { "ApplyConfig", systemApplyConfig, METH_VARARGS }, + { "SetConfig", systemSetConfig, METH_VARARGS }, + { "SaveConfig", systemSaveConfig, METH_VARARGS }, + { "GetConfig", systemGetConfig, METH_VARARGS }, + + { "SetSaveID", systemSetSaveID, METH_VARARGS }, + { "isSaveID", systemisSaveID, METH_VARARGS }, + { "GetSaveID", systemGetSaveID, METH_VARARGS }, + + { "GetMusicVolume", systemGetMusicVolume, METH_VARARGS }, + { "GetSoundVolume", systemGetSoundVolume, METH_VARARGS }, + + { "SetMusicVolume", systemSetMusicVolume, METH_VARARGS }, + { "SetSoundVolumef", systemSetSoundVolumef, METH_VARARGS }, + { "IsSoftwareCursor", systemIsSoftwareCursor, METH_VARARGS }, + + { "SetViewChatFlag", systemSetViewChatFlag, METH_VARARGS }, + { "IsViewChat", systemIsViewChat, METH_VARARGS }, + + { "SetAlwaysShowNameFlag", systemSetAlwaysShowNameFlag, METH_VARARGS }, + { "IsAlwaysShowName", systemIsAlwaysShowName, METH_VARARGS }, + + { "SetShowDamageFlag", systemSetShowDamageFlag, METH_VARARGS }, + { "IsShowDamage", systemIsShowDamage, METH_VARARGS }, + + { "SetShowSalesTextFlag", systemSetShowSalesTextFlag, METH_VARARGS }, + { "IsShowSalesText", systemIsShowSalesText, METH_VARARGS }, + + { "GetShadowLevel", systemGetShadowLevel, METH_VARARGS }, + { "SetShadowLevel", systemSetShadowLevel, METH_VARARGS }, + + { NULL, NULL, NULL } + }; + + PyObject * poModule = Py_InitModule("systemSetting", s_methods); + + PyModule_AddIntConstant(poModule, "WINDOW_STATUS", CPythonSystem::WINDOW_STATUS); + PyModule_AddIntConstant(poModule, "WINDOW_INVENTORY", CPythonSystem::WINDOW_INVENTORY); + PyModule_AddIntConstant(poModule, "WINDOW_ABILITY", CPythonSystem::WINDOW_ABILITY); + PyModule_AddIntConstant(poModule, "WINDOW_SOCIETY", CPythonSystem::WINDOW_SOCIETY); + PyModule_AddIntConstant(poModule, "WINDOW_JOURNAL", CPythonSystem::WINDOW_JOURNAL); + PyModule_AddIntConstant(poModule, "WINDOW_COMMAND", CPythonSystem::WINDOW_COMMAND); + + PyModule_AddIntConstant(poModule, "WINDOW_QUICK", CPythonSystem::WINDOW_QUICK); + PyModule_AddIntConstant(poModule, "WINDOW_GAUGE", CPythonSystem::WINDOW_GAUGE); + PyModule_AddIntConstant(poModule, "WINDOW_MINIMAP", CPythonSystem::WINDOW_MINIMAP); + PyModule_AddIntConstant(poModule, "WINDOW_CHAT", CPythonSystem::WINDOW_CHAT); +} diff --git a/source/UserInterface/PythonTextTail.cpp b/source/UserInterface/PythonTextTail.cpp new file mode 100644 index 0000000..699acf1 --- /dev/null +++ b/source/UserInterface/PythonTextTail.cpp @@ -0,0 +1,1029 @@ +// +// ij͸ ٴϴ ؽƮ ҽ (̸, ̸, 帶ũ ) +// +#include "stdafx.h" +#include "InstanceBase.h" +#include "resource.h" +#include "PythonTextTail.h" +#include "PythonCharacterManager.h" +#include "PythonGuild.h" +#include "Locale.h" +#include "MarkManager.h" + +const D3DXCOLOR c_TextTail_Player_Color = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); +const D3DXCOLOR c_TextTail_Monster_Color = D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f); +const D3DXCOLOR c_TextTail_Item_Color = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); +const D3DXCOLOR c_TextTail_Chat_Color = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); +const D3DXCOLOR c_TextTail_Info_Color = D3DXCOLOR(1.0f, 0.785f, 0.785f, 1.0f); +const D3DXCOLOR c_TextTail_Guild_Name_Color = 0xFFEFD3FF; +const float c_TextTail_Name_Position = -10.0f; +const float c_fxMarkPosition = 1.5f; +const float c_fyGuildNamePosition = 15.0f; +const float c_fyMarkPosition = 15.0f + 11.0f; +BOOL bPKTitleEnable = TRUE; + +// TEXTTAIL_LIVINGTIME_CONTROL +long gs_TextTail_LivingTime = 5000; + +long TextTail_GetLivingTime() +{ + assert(gs_TextTail_LivingTime>1000); + return gs_TextTail_LivingTime; +} + +void TextTail_SetLivingTime(long livingTime) +{ + gs_TextTail_LivingTime = livingTime; +} +// END_OF_TEXTTAIL_LIVINGTIME_CONTROL + +CGraphicText * ms_pFont = NULL; + +void CPythonTextTail::GetInfo(std::string* pstInfo) +{ + char szInfo[256]; + sprintf(szInfo, "TextTail: ChatTail %d, ChrTail (Map %d, List %d), ItemTail (Map %d, List %d), Pool %d", + m_ChatTailMap.size(), + m_CharacterTextTailMap.size(), m_CharacterTextTailList.size(), + m_ItemTextTailMap.size(), m_ItemTextTailList.size(), + m_TextTailPool.GetCapacity()); + + pstInfo->append(szInfo); +} + +void CPythonTextTail::UpdateAllTextTail() +{ + CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetMainInstancePtr(); + if (pInstance) + { + TPixelPosition pixelPos; + pInstance->NEW_GetPixelPosition(&pixelPos); + + TTextTailMap::iterator itorMap; + + for (itorMap = m_CharacterTextTailMap.begin(); itorMap != m_CharacterTextTailMap.end(); ++itorMap) + { + UpdateDistance(pixelPos, itorMap->second); + } + + for (itorMap = m_ItemTextTailMap.begin(); itorMap != m_ItemTextTailMap.end(); ++itorMap) + { + UpdateDistance(pixelPos, itorMap->second); + } + + for (TChatTailMap::iterator itorChat=m_ChatTailMap.begin(); itorChat!=m_ChatTailMap.end(); ++itorChat) + { + UpdateDistance(pixelPos, itorChat->second); + + // NOTE : Chat TextTail ij ̸ Ѵ. + if (itorChat->second->bNameFlag) + { + DWORD dwVID = itorChat->first; + ShowCharacterTextTail(dwVID); + } + } + } +} + +void CPythonTextTail::UpdateShowingTextTail() +{ + TTextTailList::iterator itor; + + for (itor = m_ItemTextTailList.begin(); itor != m_ItemTextTailList.end(); ++itor) + { + UpdateTextTail(*itor); + } + + for (TChatTailMap::iterator itorChat=m_ChatTailMap.begin(); itorChat!=m_ChatTailMap.end(); ++itorChat) + { + UpdateTextTail(itorChat->second); + } + + for (itor = m_CharacterTextTailList.begin(); itor != m_CharacterTextTailList.end(); ++itor) + { + TTextTail * pTextTail = *itor; + UpdateTextTail(pTextTail); + + // NOTE : Chat TextTail ġ ٲ۴. + TChatTailMap::iterator itor = m_ChatTailMap.find(pTextTail->dwVirtualID); + if (m_ChatTailMap.end() != itor) + { + TTextTail * pChatTail = itor->second; + if (pChatTail->bNameFlag) + { + pTextTail->y = pChatTail->y - 17.0f; + } + } + } +} + +void CPythonTextTail::UpdateTextTail(TTextTail * pTextTail) +{ + if (!pTextTail->pOwner) + return; + + ///// + + CPythonGraphic & rpyGraphic = CPythonGraphic::Instance(); + rpyGraphic.Identity(); + + const D3DXVECTOR3 & c_rv3Position = pTextTail->pOwner->GetPosition(); + rpyGraphic.ProjectPosition(c_rv3Position.x, + c_rv3Position.y, + c_rv3Position.z + pTextTail->fHeight, + &pTextTail->x, + &pTextTail->y, + &pTextTail->z); + + pTextTail->x = floorf(pTextTail->x); + pTextTail->y = floorf(pTextTail->y); + + // NOTE : 13m ۿ ̸ ֽϴ - [levites] + if (pTextTail->fDistanceFromPlayer < 1300.0f) + { + pTextTail->z = 0.0f; + } + else + { + pTextTail->z = pTextTail->z * CPythonGraphic::Instance().GetOrthoDepth() * -1.0f; + pTextTail->z += 10.0f; + } +} + +void CPythonTextTail::ArrangeTextTail() +{ + TTextTailList::iterator itor; + TTextTailList::iterator itorCompare; + + DWORD dwTime = CTimer::Instance().GetCurrentMillisecond(); + + for (itor = m_ItemTextTailList.begin(); itor != m_ItemTextTailList.end(); ++itor) + { + TTextTail * pInsertTextTail = *itor; + + int yTemp = 5; + int LimitCount = 0; + + for (itorCompare = m_ItemTextTailList.begin(); itorCompare != m_ItemTextTailList.end();) + { + TTextTail * pCompareTextTail = *itorCompare; + + if (*itorCompare == *itor) + { + ++itorCompare; + continue; + } + + if (LimitCount >= 20) + break; + + if (isIn(pInsertTextTail, pCompareTextTail)) + { + pInsertTextTail->y = (pCompareTextTail->y + pCompareTextTail->yEnd + yTemp); + + itorCompare = m_ItemTextTailList.begin(); + ++LimitCount; + continue; + } + + ++itorCompare; + } + + + if (pInsertTextTail->pOwnerTextInstance) + { + pInsertTextTail->pOwnerTextInstance->SetPosition(pInsertTextTail->x, pInsertTextTail->y, pInsertTextTail->z); + pInsertTextTail->pOwnerTextInstance->Update(); + + pInsertTextTail->pTextInstance->SetColor(pInsertTextTail->Color.r, pInsertTextTail->Color.g, pInsertTextTail->Color.b); + pInsertTextTail->pTextInstance->SetPosition(pInsertTextTail->x, pInsertTextTail->y + 15.0f, pInsertTextTail->z); + pInsertTextTail->pTextInstance->Update(); + + } + else + { + pInsertTextTail->pTextInstance->SetColor(pInsertTextTail->Color.r, pInsertTextTail->Color.g, pInsertTextTail->Color.b); + pInsertTextTail->pTextInstance->SetPosition(pInsertTextTail->x, pInsertTextTail->y, pInsertTextTail->z); + pInsertTextTail->pTextInstance->Update(); + + } + } + + for (itor = m_CharacterTextTailList.begin(); itor != m_CharacterTextTailList.end(); ++itor) + { + TTextTail * pTextTail = *itor; + + float fxAdd = 0.0f; + + // Mark ġ Ʈ + CGraphicMarkInstance * pMarkInstance = pTextTail->pMarkInstance; + CGraphicTextInstance * pGuildNameInstance = pTextTail->pGuildNameTextInstance; + if (pMarkInstance && pGuildNameInstance) + { + int iWidth, iHeight; + int iImageHalfSize = pMarkInstance->GetWidth()/2 + c_fxMarkPosition; + pGuildNameInstance->GetTextSize(&iWidth, &iHeight); + + pMarkInstance->SetPosition(pTextTail->x - iWidth/2 - iImageHalfSize, pTextTail->y - c_fyMarkPosition); + pGuildNameInstance->SetPosition(pTextTail->x + iImageHalfSize, pTextTail->y - c_fyGuildNamePosition, pTextTail->z); + pGuildNameInstance->Update(); + } + + int iNameWidth, iNameHeight; + pTextTail->pTextInstance->GetTextSize(&iNameWidth, &iNameHeight); + + // Title ġ Ʈ + CGraphicTextInstance * pTitle = pTextTail->pTitleTextInstance; + if (pTitle) + { + int iTitleWidth, iTitleHeight; + pTitle->GetTextSize(&iTitleWidth, &iTitleHeight); + + fxAdd = 8.0f; + + if (LocaleService_IsEUROPE()) // Ͼ Ī + { + if( GetDefaultCodePage() == CP_ARABIC ) + { + pTitle->SetPosition(pTextTail->x - (iNameWidth / 2) - iTitleWidth - 4.0f, pTextTail->y, pTextTail->z); + } + else + { + // pTitle->SetPosition(pTextTail->x - (iNameWidth / 2), pTextTail->y, pTextTail->z); + pTitle->SetPosition(pTextTail->x - ((iNameWidth / 2)-4.0f), pTextTail->y, pTextTail->z); // Space between level and alignment + } + } + else + { + pTitle->SetPosition(pTextTail->x - (iNameWidth / 2) - fxAdd, pTextTail->y, pTextTail->z); + } + pTitle->Update(); + + // Level ġ Ʈ + CGraphicTextInstance * pLevel = pTextTail->pLevelTextInstance; + if (pLevel) + { + int iLevelWidth, iLevelHeight; + pLevel->GetTextSize(&iLevelWidth, &iLevelHeight); + + if (LocaleService_IsEUROPE()) // Ͼ Ī + { + if( GetDefaultCodePage() == CP_ARABIC ) + { + pLevel->SetPosition(pTextTail->x - (iNameWidth / 2) - iLevelWidth - iTitleWidth - 8.0f, pTextTail->y, pTextTail->z); + } + else + { + pLevel->SetPosition(pTextTail->x - (iNameWidth / 2) - iTitleWidth, pTextTail->y, pTextTail->z); + } + } + else + { + pLevel->SetPosition(pTextTail->x - (iNameWidth / 2) - fxAdd - iTitleWidth, pTextTail->y, pTextTail->z); + } + + pLevel->Update(); + } + } + else + { + fxAdd = 4.0f; + + // Level ġ Ʈ + CGraphicTextInstance * pLevel = pTextTail->pLevelTextInstance; + if (pLevel) + { + int iLevelWidth, iLevelHeight; + pLevel->GetTextSize(&iLevelWidth, &iLevelHeight); + + if (LocaleService_IsEUROPE()) // Ͼ Ī + { + if( GetDefaultCodePage() == CP_ARABIC ) + { + pLevel->SetPosition(pTextTail->x - (iNameWidth / 2) - iLevelWidth - 4.0f, pTextTail->y, pTextTail->z); + } + else + { + pLevel->SetPosition(pTextTail->x - (iNameWidth / 2), pTextTail->y, pTextTail->z); + } + } + else + { + pLevel->SetPosition(pTextTail->x - (iNameWidth / 2) - fxAdd, pTextTail->y, pTextTail->z); + } + + pLevel->Update(); + } + } + + pTextTail->pTextInstance->SetColor(pTextTail->Color.r, pTextTail->Color.g, pTextTail->Color.b); + pTextTail->pTextInstance->SetPosition(pTextTail->x + fxAdd, pTextTail->y, pTextTail->z); + pTextTail->pTextInstance->Update(); + } + + for (TChatTailMap::iterator itorChat=m_ChatTailMap.begin(); itorChat!=m_ChatTailMap.end();) + { + TTextTail * pTextTail = itorChat->second; + + if (pTextTail->LivingTime < dwTime) + { + DeleteTextTail(pTextTail); + itorChat = m_ChatTailMap.erase(itorChat); + continue; + } + else + ++itorChat; + + pTextTail->pTextInstance->SetColor(pTextTail->Color); + pTextTail->pTextInstance->SetPosition(pTextTail->x, pTextTail->y, pTextTail->z); + pTextTail->pTextInstance->Update(); + } +} + +void CPythonTextTail::Render() +{ + TTextTailList::iterator itor; + + for (itor = m_CharacterTextTailList.begin(); itor != m_CharacterTextTailList.end(); ++itor) + { + TTextTail * pTextTail = *itor; + pTextTail->pTextInstance->Render(); + if (pTextTail->pMarkInstance && pTextTail->pGuildNameTextInstance) + { + pTextTail->pMarkInstance->Render(); + pTextTail->pGuildNameTextInstance->Render(); + } + if (pTextTail->pTitleTextInstance) + { + pTextTail->pTitleTextInstance->Render(); + } + if (pTextTail->pLevelTextInstance) + { + pTextTail->pLevelTextInstance->Render(); + } + } + + for (itor = m_ItemTextTailList.begin(); itor != m_ItemTextTailList.end(); ++itor) + { + TTextTail * pTextTail = *itor; + + RenderTextTailBox(pTextTail); + pTextTail->pTextInstance->Render(); + if (pTextTail->pOwnerTextInstance) + pTextTail->pOwnerTextInstance->Render(); + } + + for (TChatTailMap::iterator itorChat = m_ChatTailMap.begin(); itorChat!=m_ChatTailMap.end(); ++itorChat) + { + TTextTail * pTextTail = itorChat->second; + if (pTextTail->pOwner->isShow()) + RenderTextTailName(pTextTail); + } +} + +void CPythonTextTail::RenderTextTailBox(TTextTail * pTextTail) +{ + // ׵θ + CPythonGraphic::Instance().SetDiffuseColor(0.0f, 0.0f, 0.0f, 1.0f); + CPythonGraphic::Instance().RenderBox2d(pTextTail->x + pTextTail->xStart, + pTextTail->y + pTextTail->yStart, + pTextTail->x + pTextTail->xEnd, + pTextTail->y + pTextTail->yEnd, + pTextTail->z); + + // ڽ + CPythonGraphic::Instance().SetDiffuseColor(0.0f, 0.0f, 0.0f, 0.3f); + CPythonGraphic::Instance().RenderBar2d(pTextTail->x + pTextTail->xStart, + pTextTail->y + pTextTail->yStart, + pTextTail->x + pTextTail->xEnd, + pTextTail->y + pTextTail->yEnd, + pTextTail->z); +} + +void CPythonTextTail::RenderTextTailName(TTextTail * pTextTail) +{ + pTextTail->pTextInstance->Render(); +} + +void CPythonTextTail::HideAllTextTail() +{ + // NOTE : Show All ص Hide All ߻ ɼ + // ü ׷ ϰ ʾ - [levites] + m_CharacterTextTailList.clear(); + m_ItemTextTailList.clear(); +} + +void CPythonTextTail::UpdateDistance(const TPixelPosition & c_rCenterPosition, TTextTail * pTextTail) +{ + const D3DXVECTOR3 & c_rv3Position = pTextTail->pOwner->GetPosition(); + D3DXVECTOR2 v2Distance(c_rv3Position.x - c_rCenterPosition.x, -c_rv3Position.y - c_rCenterPosition.y); + pTextTail->fDistanceFromPlayer = D3DXVec2Length(&v2Distance); +} + +void CPythonTextTail::ShowAllTextTail() +{ + TTextTailMap::iterator itor; + for (itor = m_CharacterTextTailMap.begin(); itor != m_CharacterTextTailMap.end(); ++itor) + { + TTextTail * pTextTail = itor->second; + if (pTextTail->fDistanceFromPlayer < 3500.0f) + ShowCharacterTextTail(itor->first); + } + for (itor = m_ItemTextTailMap.begin(); itor != m_ItemTextTailMap.end(); ++itor) + { + TTextTail * pTextTail = itor->second; + if (pTextTail->fDistanceFromPlayer < 3500.0f) + ShowItemTextTail(itor->first); + } +} + +void CPythonTextTail::ShowCharacterTextTail(DWORD VirtualID) +{ + TTextTailMap::iterator itor = m_CharacterTextTailMap.find(VirtualID); + + if (m_CharacterTextTailMap.end() == itor) + return; + + TTextTail * pTextTail = itor->second; + + if (m_CharacterTextTailList.end() != std::find(m_CharacterTextTailList.begin(), m_CharacterTextTailList.end(), pTextTail)) + { + //Tracef("̹ Ʈ : %d\n", VirtualID); + return; + } + + // NOTE : ShowAll ÿ Instance Pointer ãƼ üũϹǷ ϰ ɸ ɼ ִ. + // CInstanceBase TextTail ִ .. + if (!pTextTail->pOwner->isShow()) + return; + + CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetInstancePtr(pTextTail->dwVirtualID); + if (!pInstance) + return; + + if (pInstance->IsGuildWall()) + return; + + if (pInstance->CanPickInstance()) + m_CharacterTextTailList.push_back(pTextTail); +} + +void CPythonTextTail::ShowItemTextTail(DWORD VirtualID) +{ + TTextTailMap::iterator itor = m_ItemTextTailMap.find(VirtualID); + + if (m_ItemTextTailMap.end() == itor) + return; + + TTextTail * pTextTail = itor->second; + + if (m_ItemTextTailList.end() != std::find(m_ItemTextTailList.begin(), m_ItemTextTailList.end(), pTextTail)) + { + //Tracef("̹ Ʈ : %d\n", VirtualID); + return; + } + + m_ItemTextTailList.push_back(pTextTail); +} + +bool CPythonTextTail::isIn(CPythonTextTail::TTextTail * pSource, CPythonTextTail::TTextTail * pTarget) +{ + float x1Source = pSource->x + pSource->xStart; + float y1Source = pSource->y + pSource->yStart; + float x2Source = pSource->x + pSource->xEnd; + float y2Source = pSource->y + pSource->yEnd; + float x1Target = pTarget->x + pTarget->xStart; + float y1Target = pTarget->y + pTarget->yStart; + float x2Target = pTarget->x + pTarget->xEnd; + float y2Target = pTarget->y + pTarget->yEnd; + + if (x1Source <= x2Target && x2Source >= x1Target && + y1Source <= y2Target && y2Source >= y1Target) + { + return true; + } + + return false; +} + +void CPythonTextTail::RegisterCharacterTextTail(DWORD dwGuildID, DWORD dwVirtualID, const D3DXCOLOR & c_rColor, float fAddHeight) +{ + CInstanceBase * pCharacterInstance = CPythonCharacterManager::Instance().GetInstancePtr(dwVirtualID); + + if (!pCharacterInstance) + return; + + TTextTail * pTextTail = RegisterTextTail(dwVirtualID, + pCharacterInstance->GetNameString(), + pCharacterInstance->GetGraphicThingInstancePtr(), + pCharacterInstance->GetGraphicThingInstanceRef().GetHeight() + fAddHeight, + c_rColor); + + CGraphicTextInstance * pTextInstance = pTextTail->pTextInstance; + pTextInstance->SetOutline(true); + pTextInstance->SetVerticalAlign(CGraphicTextInstance::VERTICAL_ALIGN_BOTTOM); + + pTextTail->pMarkInstance=NULL; + pTextTail->pGuildNameTextInstance=NULL; + pTextTail->pTitleTextInstance=NULL; + pTextTail->pLevelTextInstance=NULL; + + if (0 != dwGuildID) + { + pTextTail->pMarkInstance = CGraphicMarkInstance::New(); + + DWORD dwMarkID = CGuildMarkManager::Instance().GetMarkID(dwGuildID); + + if (dwMarkID != CGuildMarkManager::INVALID_MARK_ID) + { + std::string markImagePath; + + if (CGuildMarkManager::Instance().GetMarkImageFilename(dwMarkID / CGuildMarkImage::MARK_TOTAL_COUNT, markImagePath)) + { + pTextTail->pMarkInstance->SetImageFileName(markImagePath.c_str()); + pTextTail->pMarkInstance->Load(); + pTextTail->pMarkInstance->SetIndex(dwMarkID % CGuildMarkImage::MARK_TOTAL_COUNT); + } + } + + std::string strGuildName; + if (!CPythonGuild::Instance().GetGuildName(dwGuildID, &strGuildName)) + strGuildName = "Noname"; + + CGraphicTextInstance *& prGuildNameInstance = pTextTail->pGuildNameTextInstance; + prGuildNameInstance = CGraphicTextInstance::New(); + prGuildNameInstance->SetTextPointer(ms_pFont); + prGuildNameInstance->SetOutline(true); + prGuildNameInstance->SetHorizonalAlign(CGraphicTextInstance::HORIZONTAL_ALIGN_CENTER); + prGuildNameInstance->SetVerticalAlign(CGraphicTextInstance::VERTICAL_ALIGN_BOTTOM); + prGuildNameInstance->SetValue(strGuildName.c_str()); + prGuildNameInstance->SetColor(c_TextTail_Guild_Name_Color.r, c_TextTail_Guild_Name_Color.g, c_TextTail_Guild_Name_Color.b); + prGuildNameInstance->Update(); + } + + m_CharacterTextTailMap.insert(TTextTailMap::value_type(dwVirtualID, pTextTail)); +} + +void CPythonTextTail::RegisterItemTextTail(DWORD VirtualID, const char * c_szText, CGraphicObjectInstance * pOwner) +{ +#ifdef __DEBUG + char szName[256]; + spritnf(szName, "%s[%d]", c_szText, VirtualID); + + TTextTail * pTextTail = RegisterTextTail(VirtualID, c_szText, pOwner, c_TextTail_Name_Position, c_TextTail_Item_Color); + m_ItemTextTailMap.insert(TTextTailMap::value_type(VirtualID, pTextTail)); +#else + TTextTail * pTextTail = RegisterTextTail(VirtualID, c_szText, pOwner, c_TextTail_Name_Position, c_TextTail_Item_Color); + m_ItemTextTailMap.insert(TTextTailMap::value_type(VirtualID, pTextTail)); +#endif +} + +void CPythonTextTail::RegisterChatTail(DWORD VirtualID, const char * c_szChat) +{ + CInstanceBase * pCharacterInstance = CPythonCharacterManager::Instance().GetInstancePtr(VirtualID); + + if (!pCharacterInstance) + return; + + TChatTailMap::iterator itor = m_ChatTailMap.find(VirtualID); + + if (m_ChatTailMap.end() != itor) + { + TTextTail * pTextTail = itor->second; + + pTextTail->pTextInstance->SetValue(c_szChat); + pTextTail->pTextInstance->Update(); + pTextTail->Color = c_TextTail_Chat_Color; + pTextTail->pTextInstance->SetColor(c_TextTail_Chat_Color); + + // TEXTTAIL_LIVINGTIME_CONTROL + pTextTail->LivingTime = CTimer::Instance().GetCurrentMillisecond() + TextTail_GetLivingTime(); + // END_OF_TEXTTAIL_LIVINGTIME_CONTROL + + pTextTail->bNameFlag = TRUE; + + return; + } + + TTextTail * pTextTail = RegisterTextTail(VirtualID, + c_szChat, + pCharacterInstance->GetGraphicThingInstancePtr(), + pCharacterInstance->GetGraphicThingInstanceRef().GetHeight() + 10.0f, + c_TextTail_Chat_Color); + + // TEXTTAIL_LIVINGTIME_CONTROL + pTextTail->LivingTime = CTimer::Instance().GetCurrentMillisecond() + TextTail_GetLivingTime(); + // END_OF_TEXTTAIL_LIVINGTIME_CONTROL + + pTextTail->bNameFlag = TRUE; + pTextTail->pTextInstance->SetOutline(true); + pTextTail->pTextInstance->SetVerticalAlign(CGraphicTextInstance::VERTICAL_ALIGN_BOTTOM); + m_ChatTailMap.insert(TTextTailMap::value_type(VirtualID, pTextTail)); +} + +void CPythonTextTail::RegisterInfoTail(DWORD VirtualID, const char * c_szChat) +{ + CInstanceBase * pCharacterInstance = CPythonCharacterManager::Instance().GetInstancePtr(VirtualID); + + if (!pCharacterInstance) + return; + + TChatTailMap::iterator itor = m_ChatTailMap.find(VirtualID); + + if (m_ChatTailMap.end() != itor) + { + TTextTail * pTextTail = itor->second; + + pTextTail->pTextInstance->SetValue(c_szChat); + pTextTail->pTextInstance->Update(); + pTextTail->Color = c_TextTail_Info_Color; + pTextTail->pTextInstance->SetColor(c_TextTail_Info_Color); + + // TEXTTAIL_LIVINGTIME_CONTROL + pTextTail->LivingTime = CTimer::Instance().GetCurrentMillisecond() + TextTail_GetLivingTime(); + // END_OF_TEXTTAIL_LIVINGTIME_CONTROL + + pTextTail->bNameFlag = FALSE; + + return; + } + + TTextTail * pTextTail = RegisterTextTail(VirtualID, + c_szChat, + pCharacterInstance->GetGraphicThingInstancePtr(), + pCharacterInstance->GetGraphicThingInstanceRef().GetHeight() + 10.0f, + c_TextTail_Info_Color); + + // TEXTTAIL_LIVINGTIME_CONTROL + pTextTail->LivingTime = CTimer::Instance().GetCurrentMillisecond() + TextTail_GetLivingTime(); + // END_OF_TEXTTAIL_LIVINGTIME_CONTROL + + pTextTail->bNameFlag = FALSE; + pTextTail->pTextInstance->SetOutline(true); + pTextTail->pTextInstance->SetVerticalAlign(CGraphicTextInstance::VERTICAL_ALIGN_BOTTOM); + m_ChatTailMap.insert(TTextTailMap::value_type(VirtualID, pTextTail)); +} + +bool CPythonTextTail::GetTextTailPosition(DWORD dwVID, float* px, float* py, float* pz) +{ + TTextTailMap::iterator itorCharacter = m_CharacterTextTailMap.find(dwVID); + + if (m_CharacterTextTailMap.end() == itorCharacter) + { + return false; + } + + TTextTail * pTextTail = itorCharacter->second; + *px=pTextTail->x; + *py=pTextTail->y; + *pz=pTextTail->z; + + return true; +} + +bool CPythonTextTail::IsChatTextTail(DWORD dwVID) +{ + TChatTailMap::iterator itorChat = m_ChatTailMap.find(dwVID); + + if (m_ChatTailMap.end() == itorChat) + return false; + + return true; +} + +void CPythonTextTail::SetCharacterTextTailColor(DWORD VirtualID, const D3DXCOLOR & c_rColor) +{ + TTextTailMap::iterator itorCharacter = m_CharacterTextTailMap.find(VirtualID); + + if (m_CharacterTextTailMap.end() == itorCharacter) + return; + + TTextTail * pTextTail = itorCharacter->second; + pTextTail->pTextInstance->SetColor(c_rColor); + pTextTail->Color = c_rColor; +} + +void CPythonTextTail::SetItemTextTailOwner(DWORD dwVID, const char * c_szName) +{ + TTextTailMap::iterator itor = m_ItemTextTailMap.find(dwVID); + if (m_ItemTextTailMap.end() == itor) + return; + + TTextTail * pTextTail = itor->second; + + if (strlen(c_szName) > 0) + { + if (!pTextTail->pOwnerTextInstance) + { + pTextTail->pOwnerTextInstance = CGraphicTextInstance::New(); + } + + std::string strName = c_szName; + static const std::string & strOwnership = ApplicationStringTable_GetString(IDS_POSSESSIVE_MORPHENE) == "" ? "'s" : ApplicationStringTable_GetString(IDS_POSSESSIVE_MORPHENE); + strName += strOwnership; + + + pTextTail->pOwnerTextInstance->SetTextPointer(ms_pFont); + pTextTail->pOwnerTextInstance->SetHorizonalAlign(CGraphicTextInstance::HORIZONTAL_ALIGN_CENTER); + pTextTail->pOwnerTextInstance->SetValue(strName.c_str()); + pTextTail->pOwnerTextInstance->SetColor(1.0f, 1.0f, 0.0f); + pTextTail->pOwnerTextInstance->Update(); + + int xOwnerSize, yOwnerSize; + pTextTail->pOwnerTextInstance->GetTextSize(&xOwnerSize, &yOwnerSize); + pTextTail->yStart = -2.0f; + pTextTail->yEnd += float(yOwnerSize + 4); + pTextTail->xStart = fMIN(pTextTail->xStart, float(-xOwnerSize / 2 - 1)); + pTextTail->xEnd = fMAX(pTextTail->xEnd, float(xOwnerSize / 2 + 1)); + } + else + { + if (pTextTail->pOwnerTextInstance) + { + CGraphicTextInstance::Delete(pTextTail->pOwnerTextInstance); + pTextTail->pOwnerTextInstance = NULL; + } + + int xSize, ySize; + pTextTail->pTextInstance->GetTextSize(&xSize, &ySize); + pTextTail->xStart = (float) (-xSize / 2 - 2); + pTextTail->yStart = -2.0f; + pTextTail->xEnd = (float) (xSize / 2 + 2); + pTextTail->yEnd = (float) ySize; + } +} + +void CPythonTextTail::DeleteCharacterTextTail(DWORD VirtualID) +{ + TTextTailMap::iterator itorCharacter = m_CharacterTextTailMap.find(VirtualID); + TTextTailMap::iterator itorChat = m_ChatTailMap.find(VirtualID); + + if (m_CharacterTextTailMap.end() != itorCharacter) + { + DeleteTextTail(itorCharacter->second); + m_CharacterTextTailMap.erase(itorCharacter); + } + else + { + Tracenf("CPythonTextTail::DeleteCharacterTextTail - Find VID[%d] Error", VirtualID); + } + + if (m_ChatTailMap.end() != itorChat) + { + DeleteTextTail(itorChat->second); + m_ChatTailMap.erase(itorChat); + } +} + +void CPythonTextTail::DeleteItemTextTail(DWORD VirtualID) +{ + TTextTailMap::iterator itor = m_ItemTextTailMap.find(VirtualID); + + if (m_ItemTextTailMap.end() == itor) + { + Tracef(" CPythonTextTail::DeleteItemTextTail - None Item Text Tail\n"); + return; + } + + DeleteTextTail(itor->second); + m_ItemTextTailMap.erase(itor); +} + +CPythonTextTail::TTextTail * CPythonTextTail::RegisterTextTail(DWORD dwVirtualID, const char * c_szText, CGraphicObjectInstance * pOwner, float fHeight, const D3DXCOLOR & c_rColor) +{ + TTextTail * pTextTail = m_TextTailPool.Alloc(); + + pTextTail->dwVirtualID = dwVirtualID; + pTextTail->pOwner = pOwner; + pTextTail->pTextInstance = CGraphicTextInstance::New(); + pTextTail->pOwnerTextInstance = NULL; + pTextTail->fHeight = fHeight; + + pTextTail->pTextInstance->SetTextPointer(ms_pFont); + pTextTail->pTextInstance->SetHorizonalAlign(CGraphicTextInstance::HORIZONTAL_ALIGN_CENTER); + pTextTail->pTextInstance->SetValue(c_szText); + pTextTail->pTextInstance->SetColor(c_rColor.r, c_rColor.g, c_rColor.b); + pTextTail->pTextInstance->Update(); + + int xSize, ySize; + pTextTail->pTextInstance->GetTextSize(&xSize, &ySize); + pTextTail->xStart = (float) (-xSize / 2 - 2); + pTextTail->yStart = -2.0f; + pTextTail->xEnd = (float) (xSize / 2 + 2); + pTextTail->yEnd = (float) ySize; + pTextTail->Color = c_rColor; + pTextTail->fDistanceFromPlayer = 0.0f; + pTextTail->x = -100.0f; + pTextTail->y = -100.0f; + pTextTail->z = 0.0f; + pTextTail->pMarkInstance = NULL; + pTextTail->pGuildNameTextInstance = NULL; + pTextTail->pTitleTextInstance = NULL; + pTextTail->pLevelTextInstance = NULL; + return pTextTail; +} + +void CPythonTextTail::DeleteTextTail(TTextTail * pTextTail) +{ + if (pTextTail->pTextInstance) + { + CGraphicTextInstance::Delete(pTextTail->pTextInstance); + pTextTail->pTextInstance = NULL; + } + if (pTextTail->pOwnerTextInstance) + { + CGraphicTextInstance::Delete(pTextTail->pOwnerTextInstance); + pTextTail->pOwnerTextInstance = NULL; + } + if (pTextTail->pMarkInstance) + { + CGraphicMarkInstance::Delete(pTextTail->pMarkInstance); + pTextTail->pMarkInstance = NULL; + } + if (pTextTail->pGuildNameTextInstance) + { + CGraphicTextInstance::Delete(pTextTail->pGuildNameTextInstance); + pTextTail->pGuildNameTextInstance = NULL; + } + if (pTextTail->pTitleTextInstance) + { + CGraphicTextInstance::Delete(pTextTail->pTitleTextInstance); + pTextTail->pTitleTextInstance = NULL; + } + if (pTextTail->pLevelTextInstance) + { + CGraphicTextInstance::Delete(pTextTail->pLevelTextInstance); + pTextTail->pLevelTextInstance = NULL; + } + + m_TextTailPool.Free(pTextTail); +} + +int CPythonTextTail::Pick(int ixMouse, int iyMouse) +{ + for (TTextTailMap::iterator itor = m_ItemTextTailMap.begin(); itor != m_ItemTextTailMap.end(); ++itor) + { + TTextTail * pTextTail = itor->second; + + if (ixMouse >= pTextTail->x + pTextTail->xStart && ixMouse <= pTextTail->x + pTextTail->xEnd && + iyMouse >= pTextTail->y + pTextTail->yStart && iyMouse <= pTextTail->y + pTextTail->yEnd) + { + SelectItemName(itor->first); + return (itor->first); + } + } + + return -1; +} + +void CPythonTextTail::SelectItemName(DWORD dwVirtualID) +{ + TTextTailMap::iterator itor = m_ItemTextTailMap.find(dwVirtualID); + + if (m_ItemTextTailMap.end() == itor) + return; + + TTextTail * pTextTail = itor->second; + pTextTail->pTextInstance->SetColor(0.1f, 0.9f, 0.1f); +} + +void CPythonTextTail::AttachTitle(DWORD dwVID, const char * c_szName, const D3DXCOLOR & c_rColor) +{ + if (!bPKTitleEnable) + return; + + TTextTailMap::iterator itor = m_CharacterTextTailMap.find(dwVID); + if (m_CharacterTextTailMap.end() == itor) + return; + + TTextTail * pTextTail = itor->second; + + CGraphicTextInstance *& prTitle = pTextTail->pTitleTextInstance; + if (!prTitle) + { + prTitle = CGraphicTextInstance::New(); + prTitle->SetTextPointer(ms_pFont); + prTitle->SetOutline(true); + + if (LocaleService_IsEUROPE()) + prTitle->SetHorizonalAlign(CGraphicTextInstance::HORIZONTAL_ALIGN_RIGHT); + else + prTitle->SetHorizonalAlign(CGraphicTextInstance::HORIZONTAL_ALIGN_CENTER); + prTitle->SetVerticalAlign(CGraphicTextInstance::VERTICAL_ALIGN_BOTTOM); + } + + prTitle->SetValue(c_szName); + prTitle->SetColor(c_rColor.r, c_rColor.g, c_rColor.b); + prTitle->Update(); +} + +void CPythonTextTail::DetachTitle(DWORD dwVID) +{ + if (!bPKTitleEnable) + return; + + TTextTailMap::iterator itor = m_CharacterTextTailMap.find(dwVID); + if (m_CharacterTextTailMap.end() == itor) + return; + + TTextTail * pTextTail = itor->second; + + if (pTextTail->pTitleTextInstance) + { + CGraphicTextInstance::Delete(pTextTail->pTitleTextInstance); + pTextTail->pTitleTextInstance = NULL; + } +} + +void CPythonTextTail::EnablePKTitle(BOOL bFlag) +{ + bPKTitleEnable = bFlag; +} + +void CPythonTextTail::AttachLevel(DWORD dwVID, const char * c_szText, const D3DXCOLOR & c_rColor) +{ + if (!bPKTitleEnable) + return; + + TTextTailMap::iterator itor = m_CharacterTextTailMap.find(dwVID); + if (m_CharacterTextTailMap.end() == itor) + return; + + TTextTail * pTextTail = itor->second; + + CGraphicTextInstance *& prLevel = pTextTail->pLevelTextInstance; + if (!prLevel) + { + prLevel = CGraphicTextInstance::New(); + prLevel->SetTextPointer(ms_pFont); + prLevel->SetOutline(true); + + prLevel->SetHorizonalAlign(CGraphicTextInstance::HORIZONTAL_ALIGN_RIGHT); + prLevel->SetVerticalAlign(CGraphicTextInstance::VERTICAL_ALIGN_BOTTOM); + } + + prLevel->SetValue(c_szText); + prLevel->SetColor(c_rColor.r, c_rColor.g, c_rColor.b); + prLevel->Update(); +} + +void CPythonTextTail::DetachLevel(DWORD dwVID) +{ + if (!bPKTitleEnable) + return; + + TTextTailMap::iterator itor = m_CharacterTextTailMap.find(dwVID); + if (m_CharacterTextTailMap.end() == itor) + return; + + TTextTail * pTextTail = itor->second; + + if (pTextTail->pLevelTextInstance) + { + CGraphicTextInstance::Delete(pTextTail->pLevelTextInstance); + pTextTail->pLevelTextInstance = NULL; + } +} + + +void CPythonTextTail::Initialize() +{ + // DEFAULT_FONT + //ms_pFont = (CGraphicText *)CResourceManager::Instance().GetTypeResourcePointer(g_strDefaultFontName.c_str()); + + CGraphicText* pkDefaultFont = static_cast(DefaultFont_GetResource()); + if (!pkDefaultFont) + { + TraceError("CPythonTextTail::Initialize - CANNOT_FIND_DEFAULT_FONT"); + return; + } + + ms_pFont = pkDefaultFont; + // END_OF_DEFAULT_FONT +} + +void CPythonTextTail::Destroy() +{ + m_TextTailPool.Clear(); +} + +void CPythonTextTail::Clear() +{ + m_CharacterTextTailMap.clear(); + m_CharacterTextTailList.clear(); + m_ItemTextTailMap.clear(); + m_ItemTextTailList.clear(); + m_ChatTailMap.clear(); + + m_TextTailPool.Clear(); +} + +CPythonTextTail::CPythonTextTail() +{ + Clear(); +} + +CPythonTextTail::~CPythonTextTail() +{ + Destroy(); +} diff --git a/source/UserInterface/PythonTextTail.h b/source/UserInterface/PythonTextTail.h new file mode 100644 index 0000000..ea59a0c --- /dev/null +++ b/source/UserInterface/PythonTextTail.h @@ -0,0 +1,113 @@ +#pragma once + +#include "../eterBase/Singleton.h" + +/* + * ٴϴ ؽƮ ó + */ +class CPythonTextTail : public CSingleton +{ + public: + typedef struct STextTail + { + CGraphicTextInstance* pTextInstance; + CGraphicTextInstance* pOwnerTextInstance; + + CGraphicMarkInstance* pMarkInstance; + CGraphicTextInstance* pGuildNameTextInstance; + + CGraphicTextInstance* pTitleTextInstance; + CGraphicTextInstance* pLevelTextInstance; + + + // Todo : ̰ VID ٲٵ Ѵ. + // ijͰ ƨ ɼ + CGraphicObjectInstance * pOwner; + + DWORD dwVirtualID; + + float x, y, z; + float fDistanceFromPlayer; + D3DXCOLOR Color; + BOOL bNameFlag; // ̸ Բ Ӱ ÷ + + float xStart, yStart; + float xEnd, yEnd; + + DWORD LivingTime; + + float fHeight; + + STextTail() {} + virtual ~STextTail() {} + } TTextTail; + + typedef std::map TTextTailMap; + typedef std::list TTextTailList; + typedef TTextTailMap TChatTailMap; + + public: + CPythonTextTail(void); + virtual ~CPythonTextTail(void); + + void GetInfo(std::string* pstInfo); + + void Initialize(); + void Destroy(); + void Clear(); + + void UpdateAllTextTail(); + void UpdateShowingTextTail(); + void Render(); + + void ArrangeTextTail(); + void HideAllTextTail(); + void ShowAllTextTail(); + void ShowCharacterTextTail(DWORD VirtualID); + void ShowItemTextTail(DWORD VirtualID); + + void RegisterCharacterTextTail(DWORD dwGuildID, DWORD dwVirtualID, const D3DXCOLOR & c_rColor, float fAddHeight=10.0f); + void RegisterItemTextTail(DWORD VirtualID, const char * c_szText, CGraphicObjectInstance * pOwner); + void RegisterChatTail(DWORD VirtualID, const char * c_szChat); + void RegisterInfoTail(DWORD VirtualID, const char * c_szChat); + void SetCharacterTextTailColor(DWORD VirtualID, const D3DXCOLOR & c_rColor); + void SetItemTextTailOwner(DWORD dwVID, const char * c_szName); + void DeleteCharacterTextTail(DWORD VirtualID); + void DeleteItemTextTail(DWORD VirtualID); + + int Pick(int ixMouse, int iyMouse); + void SelectItemName(DWORD dwVirtualID); + + bool GetTextTailPosition(DWORD dwVID, float* px, float* py, float* pz); + bool IsChatTextTail(DWORD dwVID); + + void EnablePKTitle(BOOL bFlag); + void AttachTitle(DWORD dwVID, const char * c_szName, const D3DXCOLOR& c_rColor); + void DetachTitle(DWORD dwVID); + + void AttachLevel(DWORD dwVID, const char* c_szText, const D3DXCOLOR& c_rColor); + void DetachLevel(DWORD dwVID); + + + protected: + TTextTail * RegisterTextTail(DWORD dwVirtualID, const char * c_szText, CGraphicObjectInstance * pOwner, float fHeight, const D3DXCOLOR & c_rColor); + void DeleteTextTail(TTextTail * pTextTail); + + void UpdateTextTail(TTextTail * pTextTail); + void RenderTextTailBox(TTextTail * pTextTail); + void RenderTextTailName(TTextTail * pTextTail); + void UpdateDistance(const TPixelPosition & c_rCenterPosition, TTextTail * pTextTail); + + bool isIn(TTextTail * pSource, TTextTail * pTarget); + + protected: + TTextTailMap m_CharacterTextTailMap; + TTextTailMap m_ItemTextTailMap; + TChatTailMap m_ChatTailMap; + + TTextTailList m_CharacterTextTailList; + TTextTailList m_ItemTextTailList; + + private: + CDynamicPool m_TextTailPool; +}; diff --git a/source/UserInterface/PythonTextTailModule.cpp b/source/UserInterface/PythonTextTailModule.cpp new file mode 100644 index 0000000..81af20a --- /dev/null +++ b/source/UserInterface/PythonTextTailModule.cpp @@ -0,0 +1,235 @@ +#include "StdAfx.h" +#include "PythonTextTail.h" +#include "PythonCharacterManager.h" + +PyObject * textTailClear(PyObject * poSelf, PyObject * poArgs) +{ + CPythonTextTail::Instance().Clear(); + return Py_BuildNone(); +} + +PyObject * textTailUpdateAllTextTail(PyObject * poSelf, PyObject * poArgs) +{ + CPythonTextTail::Instance().UpdateAllTextTail(); + return Py_BuildNone(); +} + +PyObject * textTailUpdateShowingTextTail(PyObject * poSelf, PyObject * poArgs) +{ + CPythonTextTail::Instance().UpdateShowingTextTail(); + return Py_BuildNone(); +} + +PyObject * textTailRender(PyObject * poSelf, PyObject * poArgs) +{ + CPythonTextTail::Instance().Render(); + return Py_BuildNone(); +} + +PyObject * textTailRegisterCharacterTextTail(PyObject * poSelf, PyObject * poArgs) +{ + int iGuildID; + if (!PyTuple_GetInteger(poArgs, 0, &iGuildID)) + return Py_BuildException(); + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 1, &iVirtualID)) + return Py_BuildException(); + + CPythonTextTail::Instance().RegisterCharacterTextTail(iGuildID, iVirtualID, D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f)); + + return Py_BuildNone(); +} + +PyObject * textTailGetPosition(PyObject * poSelf, PyObject * poArgs) +{ + int VirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &VirtualID)) + return Py_BuildException(); + + float x=0.0f; + float y=0.0f; + float z=0.0f; + bool isData=CPythonTextTail::Instance().GetTextTailPosition(VirtualID, &x, &y, &z); + if (!isData) + { + CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance(); + CInstanceBase* pkInstMain=rkChrMgr.GetMainInstancePtr(); + if (pkInstMain) + { + const D3DXVECTOR3 & c_rv3Position = pkInstMain->GetGraphicThingInstanceRef().GetPosition(); + CPythonGraphic::Instance().ProjectPosition(c_rv3Position.x, c_rv3Position.y, c_rv3Position.z, &x, &y); + } + } + + return Py_BuildValue("fff", x, y, z); +} + +PyObject * textTailIsChat(PyObject * poSelf, PyObject * poArgs) +{ + int VirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &VirtualID)) + return Py_BuildException(); + + return Py_BuildValue("i", CPythonTextTail::Instance().IsChatTextTail(VirtualID)); +} + +PyObject * textTailRegisterChatTail(PyObject * poSelf, PyObject * poArgs) +{ + int VirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &VirtualID)) + return Py_BuildException(); + + char * szText; + if (!PyTuple_GetString(poArgs, 1, &szText)) + return Py_BuildException(); + + CPythonTextTail::Instance().RegisterChatTail(VirtualID, szText); + + return Py_BuildNone(); +} + +PyObject * textTailRegisterInfoTail(PyObject * poSelf, PyObject * poArgs) +{ + int VirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &VirtualID)) + return Py_BuildException(); + + char * szText; + if (!PyTuple_GetString(poArgs, 1, &szText)) + return Py_BuildException(); + + CPythonTextTail::Instance().RegisterInfoTail(VirtualID, szText); + + return Py_BuildNone(); +} + +PyObject * textTailAttachTitle(PyObject * poSelf, PyObject * poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + char * szName; + if (!PyTuple_GetString(poArgs, 1, &szName)) + return Py_BuildException(); + float fr; + if (!PyTuple_GetFloat(poArgs, 2, &fr)) + return Py_BuildException(); + float fg; + if (!PyTuple_GetFloat(poArgs, 3, &fg)) + return Py_BuildException(); + float fb; + if (!PyTuple_GetFloat(poArgs, 4, &fb)) + return Py_BuildException(); + + CPythonTextTail::Instance().AttachTitle(iVirtualID, szName, D3DXCOLOR(fr, fg, fb, 1.0f)); + + return Py_BuildNone(); +} + +PyObject * textTailShowCharacterTextTail(PyObject * poSelf, PyObject * poArgs) +{ + int VirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &VirtualID)) + return Py_BuildException(); + + CPythonTextTail::Instance().ShowCharacterTextTail(VirtualID); + return Py_BuildNone(); +} + +PyObject * textTailShowItemTextTail(PyObject * poSelf, PyObject * poArgs) +{ + int VirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &VirtualID)) + return Py_BuildException(); + + CPythonTextTail::Instance().ShowItemTextTail(VirtualID); + return Py_BuildNone(); +} + +PyObject * textTailArrangeTextTail(PyObject * poSelf, PyObject * poArgs) +{ + CPythonTextTail::Instance().ArrangeTextTail(); + return Py_BuildNone(); +} + +PyObject * textTailHideAllTextTail(PyObject * poSelf, PyObject * poArgs) +{ + CPythonTextTail::Instance().HideAllTextTail(); + return Py_BuildNone(); +} + +PyObject * textTailShowAllTextTail(PyObject * poSelf, PyObject * poArgs) +{ + CPythonTextTail::Instance().ShowAllTextTail(); + return Py_BuildNone(); +} + +PyObject * textTailPick(PyObject * poSelf, PyObject * poArgs) +{ + int ix; + if (!PyTuple_GetInteger(poArgs, 0, &ix)) + return Py_BuildException(); + int iy; + if (!PyTuple_GetInteger(poArgs, 1, &iy)) + return Py_BuildException(); + + int iValue = CPythonTextTail::Instance().Pick(ix, iy); + return Py_BuildValue("i", iValue); +} + +PyObject * textTailSelectItemName(PyObject * poSelf, PyObject * poArgs) +{ + int iVirtualID; + if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID)) + return Py_BuildException(); + + CPythonTextTail::Instance().SelectItemName(iVirtualID); + return Py_BuildNone(); +} + +PyObject * textTailEnablePKTitle(PyObject * poSelf, PyObject * poArgs) +{ + int iFlag; + if (!PyTuple_GetInteger(poArgs, 0, &iFlag)) + return Py_BuildException(); + + CPythonTextTail::Instance().EnablePKTitle(iFlag); + return Py_BuildNone(); +} + +void initTextTail() +{ + static PyMethodDef s_methods[] = + { + { "Clear", textTailClear, METH_VARARGS }, + + { "UpdateAllTextTail", textTailUpdateAllTextTail, METH_VARARGS }, + { "UpdateShowingTextTail", textTailUpdateShowingTextTail, METH_VARARGS }, + { "Render", textTailRender, METH_VARARGS }, + + { "ShowCharacterTextTail", textTailShowCharacterTextTail, METH_VARARGS }, + { "ShowItemTextTail", textTailShowItemTextTail, METH_VARARGS }, + + { "GetPosition", textTailGetPosition, METH_VARARGS }, + { "IsChat", textTailIsChat, METH_VARARGS }, + + { "ArrangeTextTail", textTailArrangeTextTail, METH_VARARGS }, + { "HideAllTextTail", textTailHideAllTextTail, METH_VARARGS }, + { "ShowAllTextTail", textTailShowAllTextTail, METH_VARARGS }, + + { "Pick", textTailPick, METH_VARARGS }, + { "SelectItemName", textTailSelectItemName, METH_VARARGS }, + + { "EnablePKTitle", textTailEnablePKTitle, METH_VARARGS }, + + // For Test + { "RegisterCharacterTextTail", textTailRegisterCharacterTextTail, METH_VARARGS }, + { "RegisterChatTail", textTailRegisterChatTail, METH_VARARGS }, + { "RegisterInfoTail", textTailRegisterInfoTail, METH_VARARGS }, + { "AttachTitle", textTailAttachTitle, METH_VARARGS }, + + { NULL, NULL, NULL }, + }; + + Py_InitModule("textTail", s_methods); +} \ No newline at end of file diff --git a/source/UserInterface/ServerStateChecker.cpp b/source/UserInterface/ServerStateChecker.cpp new file mode 100644 index 0000000..c9c63ee --- /dev/null +++ b/source/UserInterface/ServerStateChecker.cpp @@ -0,0 +1,105 @@ +#include "StdAfx.h" +#include "Packet.h" +#include "ServerStateChecker.h" + +#include "../eterLib/NetAddress.h" + +#pragma pack(push) +#pragma pack(1) + +typedef unsigned char ServerStateChecker_Header; +typedef unsigned long ServerStateChecker_Key; +typedef unsigned long ServerStateChecker_Index; +typedef unsigned char ServerStateChecker_State; + +#pragma pack(pop) + +CServerStateChecker::CServerStateChecker() +{ + Initialize(); +} + +CServerStateChecker::~CServerStateChecker() +{ + Initialize(); + m_poWnd = NULL; +} + +void CServerStateChecker::Create(PyObject* poWnd) +{ + m_poWnd = poWnd; +} + +void CServerStateChecker::AddChannel(UINT uServerIndex, const char* c_szAddr, UINT uPort) +{ + TChannel c; + c.uServerIndex = uServerIndex; + c.c_szAddr = c_szAddr; + c.uPort = uPort; + + m_lstChannel.push_back(c); +} + +void CServerStateChecker::Request() +{ + if (m_lstChannel.empty()) { + return; + } + + if (!m_kStream.Connect(m_lstChannel.begin()->c_szAddr, m_lstChannel.begin()->uPort)) + { + for (std::list::const_iterator it = m_lstChannel.begin(); it != m_lstChannel.end(); ++it) { + PyCallClassMemberFunc(m_poWnd, "NotifyChannelState", Py_BuildValue("(ii)", it->uServerIndex, 0)); + } + return; + } + m_kStream.ClearRecvBuffer(); + m_kStream.SetSendBufferSize(1024); + m_kStream.SetRecvBufferSize(1024); + + BYTE bHeader = HEADER_CG_STATE_CHECKER; + if (!m_kStream.Send(sizeof(bHeader), &bHeader)) + { + for (std::list::const_iterator it = m_lstChannel.begin(); it != m_lstChannel.end(); ++it) { + PyCallClassMemberFunc(m_poWnd, "NotifyChannelState", Py_BuildValue("(ii)", it->uServerIndex, 0)); + } + Initialize(); + return; + } +} + +void CServerStateChecker::Update() +{ + m_kStream.Process(); + + BYTE bHeader; + if (!m_kStream.Recv(sizeof(bHeader), &bHeader)) { + return; + } + if (HEADER_GC_RESPOND_CHANNELSTATUS != bHeader) { + return; + } + int nSize; + if (!m_kStream.Recv(sizeof(nSize), &nSize)) { + return; + } + for (int i = 0; i < nSize; i++) { + TChannelStatus channelStatus; + if (!m_kStream.Recv(sizeof(channelStatus), &channelStatus)) { + return; + } + for (std::list::const_iterator it = m_lstChannel.begin(); it != m_lstChannel.end(); ++it) { + if (channelStatus.nPort == it->uPort) { + PyCallClassMemberFunc(m_poWnd, "NotifyChannelState", Py_BuildValue("(ii)", it->uServerIndex, channelStatus.bStatus)); + break; + } + } + } + Initialize(); +} + +void CServerStateChecker::Initialize() +{ + m_lstChannel.clear(); + m_kStream.Disconnect(); +} \ No newline at end of file diff --git a/source/UserInterface/ServerStateChecker.h b/source/UserInterface/ServerStateChecker.h new file mode 100644 index 0000000..0434e9c --- /dev/null +++ b/source/UserInterface/ServerStateChecker.h @@ -0,0 +1,31 @@ +#pragma once + +#include "../eterLib/NetStream.h" + +class CServerStateChecker : public CSingleton +{ + public: + CServerStateChecker(); + virtual ~CServerStateChecker(); + + void Create(PyObject* poWnd); + void AddChannel(UINT uServerIndex, const char* c_szAddr, UINT uPort); + void Request(); + void Update(); + + void Initialize(); + + private: + typedef struct SChannel + { + UINT uServerIndex; + const char* c_szAddr; + UINT uPort; + } TChannel; + + PyObject* m_poWnd; + + std::list m_lstChannel; + + CNetworkStream m_kStream; +}; \ No newline at end of file diff --git a/source/UserInterface/ServerStateCheckerModule.cpp b/source/UserInterface/ServerStateCheckerModule.cpp new file mode 100644 index 0000000..6e36f3d --- /dev/null +++ b/source/UserInterface/ServerStateCheckerModule.cpp @@ -0,0 +1,64 @@ +#include "StdAfx.h" +#include "ServerStateChecker.h" + +PyObject * ServerStateCheckerCreate(PyObject* poSelf, PyObject* poArgs) +{ + PyObject * poWnd; + if (!PyTuple_GetObject(poArgs, 0, &poWnd)) + return Py_BadArgument(); + + CServerStateChecker::Instance().Create(poWnd); + return Py_BuildNone(); +} + +PyObject * ServerStateCheckerUpdate(PyObject* poSelf, PyObject* poArgs) +{ + CServerStateChecker::Instance().Update(); + return Py_BuildNone(); +} + +PyObject * ServerStateCheckerRequest(PyObject* poSelf, PyObject* poArgs) +{ + CServerStateChecker::Instance().Request(); + return Py_BuildNone(); +} + +PyObject * ServerStateCheckerAddChannel(PyObject* poSelf, PyObject* poArgs) +{ + int nServerIndex; + if (!PyTuple_GetInteger(poArgs, 0, &nServerIndex)) + return Py_BuildException(); + + char * szAddr; + if (!PyTuple_GetString(poArgs, 1, &szAddr)) + return Py_BuildException(); + + int nPort; + if (!PyTuple_GetInteger(poArgs, 2, &nPort)) + return Py_BuildException(); + + CServerStateChecker::Instance().AddChannel(nServerIndex, szAddr, nPort); + return Py_BuildNone(); +} + +PyObject * ServerStateCheckerInitialize(PyObject* poSelf, PyObject* poArgs) +{ + CServerStateChecker::Instance().Initialize(); + return Py_BuildNone(); +} + +void initServerStateChecker() +{ + static PyMethodDef s_methods[] = + { + { "Create", ServerStateCheckerCreate, METH_VARARGS }, + { "Update", ServerStateCheckerUpdate, METH_VARARGS }, + { "Request", ServerStateCheckerRequest, METH_VARARGS }, + { "AddChannel", ServerStateCheckerAddChannel, METH_VARARGS }, + { "Initialize", ServerStateCheckerInitialize, METH_VARARGS }, + { NULL, NULL, NULL }, + }; + + //PyObject * poModule = Py_InitModule("ServerStateChecker", s_methods); + Py_InitModule("ServerStateChecker", s_methods); +} \ No newline at end of file diff --git a/source/UserInterface/StdAfx.cpp b/source/UserInterface/StdAfx.cpp new file mode 100644 index 0000000..9b754b6 --- /dev/null +++ b/source/UserInterface/StdAfx.cpp @@ -0,0 +1,6 @@ +// stdafx.cpp : source file that includes just the standard includes +// UserInterface.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + diff --git a/source/UserInterface/StdAfx.h b/source/UserInterface/StdAfx.h new file mode 100644 index 0000000..8fc7bc8 --- /dev/null +++ b/source/UserInterface/StdAfx.h @@ -0,0 +1,90 @@ +#pragma once + +#pragma warning(disable:4702) +#pragma warning(disable:4100) +#pragma warning(disable:4201) +#pragma warning(disable:4511) +#pragma warning(disable:4663) +#pragma warning(disable:4018) +#pragma warning(disable:4245) +#pragma warning(disable:4995) + +#if _MSC_VER >= 1400 +//if don't use below, time_t is 64bit +#define _USE_32BIT_TIME_T +#endif + +#include "../eterLib/StdAfx.h" +#include "../eterPythonLib/StdAfx.h" +#include "../gameLib/StdAfx.h" +#include "../scriptLib/StdAfx.h" +#include "../milesLib/StdAfx.h" +#include "../EffectLib/StdAfx.h" +#include "../PRTerrainLib/StdAfx.h" +#include "../SpeedTreeLib/StdAfx.h" + +#ifndef __D3DRM_H__ +#define __D3DRM_H__ +#endif + +#include +#include + +#include "Locale.h" + +#include "GameType.h" +extern DWORD __DEFAULT_CODE_PAGE__; + +#define APP_NAME "Metin 2" + +enum +{ + POINT_MAX_NUM = 255, + CHARACTER_NAME_MAX_LEN = 24, +#if defined(LOCALE_SERVICE_JAPAN) + PLAYER_NAME_MAX_LEN = 16, +#else + PLAYER_NAME_MAX_LEN = 12, +#endif +}; + +void initudp(); +void initapp(); +void initime(); +void initsystem(); +void initchr(); +void initchrmgr(); +void initChat(); +void initTextTail(); +void initime(); +void initItem(); +void initNonPlayer(); +void initnet(); +void initPlayer(); +void initSectionDisplayer(); +void initServerStateChecker(); +void initTrade(); +void initMiniMap(); +void initProfiler(); +void initEvent(); +void initeffect(); +void initsnd(); +void initeventmgr(); +void initBackground(); +void initwndMgr(); +void initshop(); +void initpack(); +void initskill(); +void initfly(); +void initquest(); +void initsafebox(); +void initguild(); +void initMessenger(); + +extern const std::string& ApplicationStringTable_GetString(DWORD dwID); +extern const std::string& ApplicationStringTable_GetString(DWORD dwID, LPCSTR szKey); + +extern const char* ApplicationStringTable_GetStringz(DWORD dwID); +extern const char* ApplicationStringTable_GetStringz(DWORD dwID, LPCSTR szKey); + +extern void ApplicationSetErrorString(const char* szErrorString); diff --git a/source/UserInterface/Test.h b/source/UserInterface/Test.h new file mode 100644 index 0000000..ab6c8c4 --- /dev/null +++ b/source/UserInterface/Test.h @@ -0,0 +1,3 @@ +#pragma once + +extern bool __IS_TEST_SERVER_MODE__; diff --git a/source/UserInterface/UserInterface.cpp b/source/UserInterface/UserInterface.cpp new file mode 100644 index 0000000..5d20679 --- /dev/null +++ b/source/UserInterface/UserInterface.cpp @@ -0,0 +1,725 @@ +#include "StdAfx.h" +#include "PythonApplication.h" +#include "ProcessScanner.h" +#include "PythonExceptionSender.h" +#include "resource.h" +#include "Version.h" + +#ifdef _DEBUG +#include +#endif + +#include "../eterPack/EterPackManager.h" +#include "../eterLib/Util.h" +#include "../CWebBrowser/CWebBrowser.h" +#include "../eterBase/CPostIt.h" + +#include "CheckLatestFiles.h" + +#include "Hackshield.h" +#include "NProtectGameGuard.h" +#include "WiseLogicXTrap.h" + +extern "C" { +extern int _fltused; +volatile int _AVOID_FLOATING_POINT_LIBRARY_BUG = _fltused; +}; +extern "C" { FILE __iob_func[3] = { *stdin,*stdout,*stderr }; } +#pragma comment(linker, "/NODEFAULTLIB:libci.lib") + +#pragma comment( lib, "version.lib" ) +#pragma comment( lib, "python27.lib" ) +#pragma comment( lib, "imagehlp.lib" ) +#pragma comment( lib, "devil.lib" ) +#pragma comment( lib, "granny2.lib" ) +#pragma comment( lib, "mss32.lib" ) +#pragma comment( lib, "winmm.lib" ) +#pragma comment( lib, "imm32.lib" ) +#pragma comment( lib, "oldnames.lib" ) +#pragma comment( lib, "SpeedTreeRT.lib" ) +#pragma comment( lib, "dinput8.lib" ) +#pragma comment( lib, "dxguid.lib" ) +#pragma comment( lib, "ws2_32.lib" ) +#pragma comment( lib, "strmiids.lib" ) +#pragma comment( lib, "ddraw.lib" ) +#pragma comment( lib, "dmoguids.lib" ) +//#pragma comment( lib, "wsock32.lib" ) +#include +#include +bool __IS_TEST_SERVER_MODE__=false; + +extern bool SetDefaultCodePage(DWORD codePage); + +#ifdef USE_OPENID +extern int openid_test; +#endif + +static const char * sc_apszPythonLibraryFilenames[] = +{ + "UserDict.pyc", + "__future__.pyc", + "copy_reg.pyc", + "linecache.pyc", + "ntpath.pyc", + "os.pyc", + "site.pyc", + "stat.pyc", + "string.pyc", + "traceback.pyc", + "types.pyc", + "\n", +}; + +char gs_szErrorString[512] = ""; + +void ApplicationSetErrorString(const char* szErrorString) +{ + strcpy(gs_szErrorString, szErrorString); +} + +bool CheckPythonLibraryFilenames() +{ + for (int i = 0; *sc_apszPythonLibraryFilenames[i] != '\n'; ++i) + { + std::string stFilename = "lib\\"; + stFilename += sc_apszPythonLibraryFilenames[i]; + + if (_access(stFilename.c_str(), 0) != 0) + { + return false; + } + + MoveFile(stFilename.c_str(), stFilename.c_str()); + } + + return true; +} + +struct ApplicationStringTable +{ + HINSTANCE m_hInstance; + std::map m_kMap_dwID_stLocale; +} gs_kAppStrTable; + +void ApplicationStringTable_Initialize(HINSTANCE hInstance) +{ + gs_kAppStrTable.m_hInstance=hInstance; +} + +const std::string& ApplicationStringTable_GetString(DWORD dwID, LPCSTR szKey) +{ + char szBuffer[512]; + char szIniFileName[256]; + char szLocale[256]; + + ::GetCurrentDirectory(sizeof(szIniFileName), szIniFileName); + if(szIniFileName[lstrlen(szIniFileName)-1] != '\\') + strcat(szIniFileName, "\\"); + strcat(szIniFileName, "metin2client.dat"); + + strcpy(szLocale, LocaleService_GetLocalePath()); + if(strnicmp(szLocale, "locale/", strlen("locale/")) == 0) + strcpy(szLocale, LocaleService_GetLocalePath() + strlen("locale/")); + ::GetPrivateProfileString(szLocale, szKey, NULL, szBuffer, sizeof(szBuffer)-1, szIniFileName); + if(szBuffer[0] == '\0') + LoadString(gs_kAppStrTable.m_hInstance, dwID, szBuffer, sizeof(szBuffer)-1); + if(szBuffer[0] == '\0') + ::GetPrivateProfileString("en", szKey, NULL, szBuffer, sizeof(szBuffer)-1, szIniFileName); + if(szBuffer[0] == '\0') + strcpy(szBuffer, szKey); + + std::string& rstLocale=gs_kAppStrTable.m_kMap_dwID_stLocale[dwID]; + rstLocale=szBuffer; + + return rstLocale; +} + +const std::string& ApplicationStringTable_GetString(DWORD dwID) +{ + char szBuffer[512]; + + LoadString(gs_kAppStrTable.m_hInstance, dwID, szBuffer, sizeof(szBuffer)-1); + std::string& rstLocale=gs_kAppStrTable.m_kMap_dwID_stLocale[dwID]; + rstLocale=szBuffer; + + return rstLocale; +} + +const char* ApplicationStringTable_GetStringz(DWORD dwID, LPCSTR szKey) +{ + return ApplicationStringTable_GetString(dwID, szKey).c_str(); +} + +const char* ApplicationStringTable_GetStringz(DWORD dwID) +{ + return ApplicationStringTable_GetString(dwID).c_str(); +} + +//////////////////////////////////////////// + +int Setup(LPSTR lpCmdLine); // Internal function forward + +bool PackInitialize(const char * c_pszFolder) +{ + NANOBEGIN + if (_access(c_pszFolder, 0) != 0) + return true; + + std::string stFolder(c_pszFolder); + stFolder += "/"; + + std::string stFileName(stFolder); + stFileName += "Index"; + + CMappedFile file; + LPCVOID pvData; + + if (!file.Create(stFileName.c_str(), &pvData, 0, 0)) + { + LogBoxf("FATAL ERROR! File not exist: %s", stFileName.c_str()); + TraceError("FATAL ERROR! File not exist: %s", stFileName.c_str()); + return true; + } + + CMemoryTextFileLoader TextLoader; + TextLoader.Bind(file.Size(), pvData); + + bool bPackFirst = TRUE; + + const std::string& strPackType = TextLoader.GetLineString(0); + + if (strPackType.compare("FILE") && strPackType.compare("PACK")) + { + TraceError("Pack/Index has invalid syntax. First line must be 'PACK' or 'FILE'"); + return false; + } + +#ifdef _DISTRIBUTE + Tracef("˸: Դϴ.\n"); + + //if (0 == strPackType.compare("FILE")) + //{ + // bPackFirst = FALSE; + // Tracef("˸: Դϴ.\n"); + //} + //else + //{ + // Tracef("˸: Դϴ.\n"); + //} +#else + bPackFirst = FALSE; + Tracef("˸: Դϴ.\n"); +#endif + + CTextFileLoader::SetCacheMode(); +#if defined(USE_RELATIVE_PATH) + CEterPackManager::Instance().SetRelativePathMode(); +#endif + CEterPackManager::Instance().SetCacheMode(); + CEterPackManager::Instance().SetSearchMode(bPackFirst); + + CSoundData::SetPackMode(); // Miles ݹ + + std::string strPackName, strTexCachePackName; + for (DWORD i = 1; i < TextLoader.GetLineCount() - 1; i += 2) + { + const std::string & c_rstFolder = TextLoader.GetLineString(i); + const std::string & c_rstName = TextLoader.GetLineString(i + 1); + + strPackName = stFolder + c_rstName; + strTexCachePackName = strPackName + "_texcache"; + + CEterPackManager::Instance().RegisterPack(strPackName.c_str(), c_rstFolder.c_str()); + CEterPackManager::Instance().RegisterPack(strTexCachePackName.c_str(), c_rstFolder.c_str()); + } + + CEterPackManager::Instance().RegisterRootPack((stFolder + std::string("root")).c_str()); + NANOEND + return true; +} + +bool RunMainScript(CPythonLauncher& pyLauncher, const char* lpCmdLine) +{ + initpack(); + initdbg(); + initime(); + initgrp(); + initgrpImage(); + initgrpText(); + initwndMgr(); + ///////////////////////////////////////////// + initudp(); + initapp(); + initsystem(); + initchr(); + initchrmgr(); + initPlayer(); + initItem(); + initNonPlayer(); + initTrade(); + initChat(); + initTextTail(); + initnet(); + initMiniMap(); + initProfiler(); + initEvent(); + initeffect(); + initfly(); + initsnd(); + initeventmgr(); + initshop(); + initskill(); + initquest(); + initBackground(); + initMessenger(); + initsafebox(); + initguild(); + initServerStateChecker(); + + NANOBEGIN + + // RegisterDebugFlag + { + std::string stRegisterDebugFlag; + +#ifdef _DISTRIBUTE + stRegisterDebugFlag ="__DEBUG__ = 0"; +#else + stRegisterDebugFlag ="__DEBUG__ = 1"; +#endif + + if (!pyLauncher.RunLine(stRegisterDebugFlag.c_str())) + { + TraceError("RegisterDebugFlag Error"); + return false; + } + } + + // RegisterCommandLine + { + std::string stRegisterCmdLine; + + const char * loginMark = "-cs"; + const char * loginMark_NonEncode = "-ncs"; + const char * seperator = " "; + + std::string stCmdLine; + const int CmdSize = 3; + std::vector stVec; + SplitLine(lpCmdLine,seperator,&stVec); + if (CmdSize == stVec.size() && stVec[0]==loginMark) + { + char buf[MAX_PATH]; //TODO Ʒ Լ string · + base64_decode(stVec[2].c_str(),buf); + stVec[2] = buf; + string_join(seperator,stVec,&stCmdLine); + } + else if (CmdSize <= stVec.size() && stVec[0]==loginMark_NonEncode) + { + stVec[0] = loginMark; + string_join(" ",stVec,&stCmdLine); + } + else + stCmdLine = lpCmdLine; + + stRegisterCmdLine ="__COMMAND_LINE__ = "; + stRegisterCmdLine+='"'; + stRegisterCmdLine+=stCmdLine; + stRegisterCmdLine+='"'; + + const CHAR* c_szRegisterCmdLine=stRegisterCmdLine.c_str(); + if (!pyLauncher.RunLine(c_szRegisterCmdLine)) + { + TraceError("RegisterCommandLine Error"); + return false; + } + } + { + std::vector stVec; + SplitLine(lpCmdLine," " ,&stVec); + + if (stVec.size() != 0 && "--pause-before-create-window" == stVec[0]) + { +#ifdef XTRAP_CLIENT_ENABLE + if (!XTrap_CheckInit()) + return false; +#endif + system("pause"); + } + if (!pyLauncher.RunFile("system.py")) + { + TraceError("RunMain Error"); + return false; + } + } + + NANOEND + return true; +} + +bool Main(HINSTANCE hInstance, LPSTR lpCmdLine) +{ +#ifdef LOCALE_SERVICE_YMIR + extern bool g_isScreenShotKey; + g_isScreenShotKey = true; +#endif + + DWORD dwRandSeed=time(NULL)+DWORD(GetCurrentProcess()); + srandom(dwRandSeed); + srand(random()); + + SetLogLevel(1); + +#ifdef LOCALE_SERVICE_VIETNAM_MILD + extern BOOL USE_VIETNAM_CONVERT_WEAPON_VNUM; + USE_VIETNAM_CONVERT_WEAPON_VNUM = true; +#endif + + if (_access("perf_game_update.txt", 0)==0) + { + DeleteFile("perf_game_update.txt"); + } + + if (_access("newpatch.exe", 0)==0) + { + system("patchupdater.exe"); + return false; + } +#ifndef __VTUNE__ + ilInit(); +#endif + if (!Setup(lpCmdLine)) + return false; + +#ifdef _DEBUG + OpenConsoleWindow(); + OpenLogFile(true); // true == uses syserr.txt and log.txt +#else + OpenLogFile(false); // false == uses syserr.txt only +#endif + + static CLZO lzo; + static CEterPackManager EterPackManager; + + if (!PackInitialize("pack")) + { + LogBox("Pack Initialization failed. Check log.txt file.."); + return false; + } + + if(LocaleService_LoadGlobal(hInstance)) + SetDefaultCodePage(LocaleService_GetCodePage()); + + CPythonApplication * app = new CPythonApplication; + + app->Initialize(hInstance); + + bool ret=false; + { + CPythonLauncher pyLauncher; + CPythonExceptionSender pyExceptionSender; + SetExceptionSender(&pyExceptionSender); + + if (pyLauncher.Create()) + { + ret=RunMainScript(pyLauncher, lpCmdLine); // ߿ Լ ʴ´. + } + + //ProcessScanner_ReleaseQuitEvent(); + + // . + app->Clear(); + + timeEndPeriod(1); + pyLauncher.Clear(); + } + + app->Destroy(); + delete app; + + return ret; +} + +HANDLE CreateMetin2GameMutex() +{ + SECURITY_ATTRIBUTES sa; + ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES)); + sa.nLength = sizeof(sa); + sa.lpSecurityDescriptor = NULL; + sa.bInheritHandle = FALSE; + + return CreateMutex(&sa, FALSE, "Metin2GameMutex"); +} + +void DestroyMetin2GameMutex(HANDLE hMutex) +{ + if (hMutex) + { + ReleaseMutex(hMutex); + hMutex = NULL; + } +} + +void __ErrorPythonLibraryIsNotExist() +{ + LogBoxf("FATAL ERROR!! Python Library file not exist!"); +} + +bool __IsTimeStampOption(LPSTR lpCmdLine) +{ + const char* TIMESTAMP = "/timestamp"; + return (strncmp(lpCmdLine, TIMESTAMP, strlen(TIMESTAMP))==0); +} + +void __PrintTimeStamp() +{ +#ifdef _DEBUG + if (__IS_TEST_SERVER_MODE__) + LogBoxf("METIN2 BINARY TEST DEBUG VERSION %s ( MS C++ %d Compiled )", __TIMESTAMP__, _MSC_VER); + else + LogBoxf("METIN2 BINARY DEBUG VERSION %s ( MS C++ %d Compiled )", __TIMESTAMP__, _MSC_VER); + +#else + if (__IS_TEST_SERVER_MODE__) + LogBoxf("METIN2 BINARY TEST VERSION %s ( MS C++ %d Compiled )", __TIMESTAMP__, _MSC_VER); + else + LogBoxf("METIN2 BINARY DISTRIBUTE VERSION %s ( MS C++ %d Compiled )", __TIMESTAMP__, _MSC_VER); +#endif +} + +bool __IsLocaleOption(LPSTR lpCmdLine) +{ + return (strcmp(lpCmdLine, "--locale") == 0); +} + +bool __IsLocaleVersion(LPSTR lpCmdLine) +{ + return (strcmp(lpCmdLine, "--perforce-revision") == 0); +} + +#ifdef USE_OPENID +//2012.07.16 +//Ϻ OpenID . Ű ߰ +bool __IsOpenIDAuthKeyOption(LPSTR lpCmdLine) +{ + return (strcmp(lpCmdLine, "--openid-authkey") == 0); +} + +bool __IsOpenIDTestOption(LPSTR lpCmdLine) //Ŭ̾Ʈ α ϴ. +{ + return (strcmp(lpCmdLine, "--openid-test") == 0); +} +#endif /* USE_OPENID */ + +int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) +{ + if (strstr(lpCmdLine, "--hackshield") != 0) + return 0; + +#ifdef _DEBUG + _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_CRT_DF | _CRTDBG_LEAK_CHECK_DF ); + //_CrtSetBreakAlloc( 110247 ); +#endif + + ApplicationStringTable_Initialize(hInstance); + + LocaleService_LoadConfig("locale.cfg"); + SetDefaultCodePage(LocaleService_GetCodePage()); + +#ifdef XTRAP_CLIENT_ENABLE + if (!XTrap_Init()) + return 0; +#endif + +#ifdef USE_AHNLAB_HACKSHIELD + if (!HackShield_Init()) + return 0; +#endif + +#ifdef USE_NPROTECT_GAMEGUARD + if (!GameGuard_Init()) + return 0; +#endif + +#if defined(CHECK_LATEST_DATA_FILES) + if (!CheckLatestFiles()) + return 0; +#endif + + bool bQuit = false; + bool bAuthKeyChecked = false; //OpenID Ű Դ ˱ . + int nArgc = 0; + PCHAR* szArgv = CommandLineToArgv( lpCmdLine, &nArgc ); + + for( int i=0; i < nArgc; i++ ) { + if(szArgv[i] == 0) + continue; + if (__IsLocaleVersion(szArgv[i])) // #0000829: [M2EU] ׻ ʵ + { + char szModuleName[MAX_PATH]; + char szVersionPath[MAX_PATH]; + GetModuleFileName(NULL, szModuleName, sizeof(szModuleName)); + sprintf(szVersionPath, "%s.version", szModuleName); + FILE* fp = fopen(szVersionPath, "wt"); + if (fp) + { + extern int METIN2_GET_VERSION(); + fprintf(fp, "r%d\n", METIN2_GET_VERSION()); + fclose(fp); + } + bQuit = true; + } else if (__IsLocaleOption(szArgv[i])) + { + FILE* fp=fopen("locale.txt", "wt"); + fprintf(fp, "service[%s] code_page[%d]", + LocaleService_GetName(), LocaleService_GetCodePage()); + fclose(fp); + bQuit = true; + } else if (__IsTimeStampOption(szArgv[i])) + { + __PrintTimeStamp(); + bQuit = true; + } else if ((strcmp(szArgv[i], "--force-set-locale") == 0)) + { + // locale ڰ ʿ ( Ī, ) + if (nArgc <= i + 2) + { + MessageBox(NULL, "Invalid arguments", ApplicationStringTable_GetStringz(IDS_APP_NAME, "APP_NAME"), MB_ICONSTOP); + goto Clean; + } + + const char* localeName = szArgv[++i]; + const char* localePath = szArgv[++i]; + + LocaleService_ForceSetLocale(localeName, localePath); + } +#ifdef USE_OPENID + else if (__IsOpenIDAuthKeyOption(szArgv[i])) //2012.07.16 OpenID : + { + // Ű ڰ ʿ (Ű) + if (nArgc <= i + 1) + { + MessageBox(NULL, "Invalid arguments", ApplicationStringTable_GetStringz(IDS_APP_NAME, "APP_NAME"), MB_ICONSTOP); + goto Clean; + } + + const char* authKey = szArgv[++i]; + + //ongoing (2012.07.16) + //Ű ϴ κ + LocaleService_SetOpenIDAuthKey(authKey); + + bAuthKeyChecked = true; + } + else if (__IsOpenIDTestOption(szArgv[i])) + { + openid_test = 1; + + } +#endif /* USE_OPENID */ + } + +#ifdef USE_OPENID + //OpenID + //OpenID Ŭ̾Ʈ Ű ޾ƿ ( ϰ ) Ŭ̾Ʈ . + + if (false == bAuthKeyChecked && !openid_test) + { + MessageBox(NULL, "Invalid execution", ApplicationStringTable_GetStringz(IDS_APP_NAME, "APP_NAME"), MB_ICONSTOP); + goto Clean; + } +#endif /* USE_OPENID */ + + + if(bQuit) + goto Clean; + +#if defined(NEEDED_COMMAND_ARGUMENT) + // ɼ , α׷ + if (strstr(lpCmdLine, NEEDED_COMMAND_ARGUMENT) == 0) { + MessageBox(NULL, ApplicationStringTable_GetStringz(IDS_ERR_MUST_LAUNCH_FROM_PATCHER, "ERR_MUST_LAUNCH_FROM_PATCHER"), ApplicationStringTable_GetStringz(IDS_APP_NAME, "APP_NAME"), MB_ICONSTOP); + goto Clean; + } +#endif + +#if defined(NEEDED_COMMAND_CLIPBOARD) + { + CHAR szSecKey[256]; + CPostIt cPostIt( "VOLUME1" ); + + if( cPostIt.Get( "SEC_KEY", szSecKey, sizeof(szSecKey) ) == FALSE ) { + MessageBox(NULL, ApplicationStringTable_GetStringz(IDS_ERR_MUST_LAUNCH_FROM_PATCHER, "ERR_MUST_LAUNCH_FROM_PATCHER"), ApplicationStringTable_GetStringz(IDS_APP_NAME, "APP_NAME"), MB_ICONSTOP); + goto Clean; + } + if( strstr(szSecKey, NEEDED_COMMAND_CLIPBOARD) == 0 ) { + MessageBox(NULL, ApplicationStringTable_GetStringz(IDS_ERR_MUST_LAUNCH_FROM_PATCHER, "ERR_MUST_LAUNCH_FROM_PATCHER"), ApplicationStringTable_GetStringz(IDS_APP_NAME, "APP_NAME"), MB_ICONSTOP); + goto Clean; + } + cPostIt.Empty(); + } +#endif + + WebBrowser_Startup(hInstance); + + if (!CheckPythonLibraryFilenames()) + { + __ErrorPythonLibraryIsNotExist(); + goto Clean; + } + + Main(hInstance, lpCmdLine); + +#ifdef USE_NPROTECT_GAMEGUARD + GameGuard_NoticeMessage(); +#endif + + WebBrowser_Cleanup(); + + ::CoUninitialize(); + + if(gs_szErrorString[0]) + MessageBox(NULL, gs_szErrorString, ApplicationStringTable_GetStringz(IDS_APP_NAME, "APP_NAME"), MB_ICONSTOP); + +Clean: +#ifdef USE_AHNLAB_HACKSHIELD + HackShield_Shutdown(); +#endif + SAFE_FREE_GLOBAL(szArgv); + + return 0; +} + +static void GrannyError(granny_log_message_type Type, + granny_log_message_origin Origin, + char const* File, + granny_int32x Line, + char const* Message, + void* UserData) +{ + TraceError("GRANNY: %s", Message); +} + +int Setup(LPSTR lpCmdLine) +{ + /* + * Ÿ̸ е ø. + */ + TIMECAPS tc; + UINT wTimerRes; + + if (timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR) + return 0; + + wTimerRes = MINMAX(tc.wPeriodMin, 1, tc.wPeriodMax); + timeBeginPeriod(wTimerRes); + + /* + * ׷ ڵ鸵 + */ + + granny_log_callback Callback; + Callback.Function = nullptr; + Callback.UserData = 0; + GrannySetLogCallback(&Callback); + return 1; +} diff --git a/source/UserInterface/UserInterface.rc b/source/UserInterface/UserInterface.rc new file mode 100644 index 0000000..d9a2438 --- /dev/null +++ b/source/UserInterface/UserInterface.rc @@ -0,0 +1,258 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" +#include "version.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +// #include "afxres.h" +#include + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Ϻ resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_JPN) +#ifdef _WIN32 +LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT +#pragma code_page(932) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_POSSESSIVE_MORPHENE "'s" +END + +#endif // Ϻ resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// ߱(߱) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS) +#ifdef _WIN32 +LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED +#pragma code_page(936) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_POSSESSIVE_MORPHENE "'s" + IDS_WARN_BAD_DRIVER "ϣܸԿ" + IDS_WARN_NO_TNL "Կ֧3D TnL Ӳ\nϷ޷С" +END + +#endif // ߱(߱) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// ѱ resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_KOR) +#ifdef _WIN32 +LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT +#pragma code_page(949) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_SELECT_LOCALE DIALOGEX 0, 0, 182, 142 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION +CAPTION "SELECT LOCALE" +FONT 10, "Arial", 0, 0, 0x0 +BEGIN + PUSHBUTTON "START",IDC_START,44,123,40,13 + PUSHBUTTON "EXIT",IDC_EXIT,96,123,40,13 + LISTBOX IDC_LOCALE_LIST,6,5,170,114,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP +END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Cursor +// + +IDC_CURSOR_NORMAL CURSOR "Cursors\\cursor.cur" +IDC_CURSOR_CHAIR CURSOR "Cursors\\cursor_chair.cur" +IDC_CURSOR_DOOR CURSOR "Cursors\\cursor_door.cur" +IDC_CURSOR_NO CURSOR "Cursors\\cursor_no.cur" +IDC_CURSOR_PICK CURSOR "Cursors\\cursor_pick.cur" +IDC_CURSOR_TALK CURSOR "Cursors\\cursor_talk.cur" +IDC_CURSOR_ATTACK CURSOR "Cursors\\cursor_attack.cur" +IDC_CURSOR_BUY CURSOR "cursors\\cursor_buy.cur" +IDC_CURSOR_SELL CURSOR "cursors\\cursor_sell.cur" +IDC_CURSOR_CAMERA_ROTATE CURSOR "Cursors\\cursor_camera_rotate.cur" +IDC_CURSOR_HSIZE CURSOR "Cursors\\cursor_hsize.cur" +IDC_CURSOR_VSIZE CURSOR "Cursors\\cursor_vsize.cur" +IDC_CURSOR_HVSIZE CURSOR "Cursors\\cursor_hvsize.cur" + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_SELECT_LOCALE, DIALOG + BEGIN + RIGHTMARGIN, 102 + BOTTOMMARGIN, 141 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_METIN2 ICON "metin2.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION VER_FILE_VERSION + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "080003b5" + BEGIN + VALUE "CompanyName", "Ymir Entertainment" + VALUE "FileDescription", "Metin2Client" + VALUE "FileVersion", VER_FILE_VERSION_STR "\0" + VALUE "InternalName", "Metin2Client" + VALUE "LegalCopyright", "Copyright (C) 2011" + VALUE "OriginalFilename", "Metin2Client.exe" + VALUE "ProductName", "Metin2Client" + VALUE "ProductVersion", "1, 0, 0, 1" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x800, 949 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_APP_NAME "ƾ2" + IDS_POSSESSIVE_MORPHENE "" + IDS_WARN_BAD_DRIVER "׷ ̹ Ʈ Ͻñ ٶϴ." + IDS_WARN_NO_TNL "ϰ ý ׷ī 3D TnL ϵ ʾ\n ǰų ֽϴ." + IDS_ERR_CANNOT_READ_FILE "%s ϴ." + IDS_ERR_NOT_LATEST_FILE "'%s' ֽŹ ƴմϴ. ó ٽ ּ." + IDS_ERR_MUST_LAUNCH_FROM_PATCHER "Ŭ̾Ʈ ó ؼ Ǿ մϴ." +END + +#endif // ѱ resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// (̱) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_APP_NAME "Metin 2" + IDS_POSSESSIVE_MORPHENE "'s" + IDS_WARN_BAD_DRIVER "IDS_WARN_BAD_DRIVER" + IDS_WARN_NO_TNL "IDS_WARN_NO_TNL" + IDS_ERR_CANNOT_READ_FILE "Cannot read %s file" + IDS_ERR_NOT_LATEST_FILE "File '%s' is not latest version. Please launch patcher." + IDS_ERR_MUST_LAUNCH_FROM_PATCHER "Please run patcher." +END + +#endif // (̱) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED diff --git a/source/UserInterface/Version.h b/source/UserInterface/Version.h new file mode 100644 index 0000000..60cc382 --- /dev/null +++ b/source/UserInterface/Version.h @@ -0,0 +1,3 @@ +#define VER_FILE_VERSION 1,0,28249,0 +#define VER_FILE_VERSION_STR "1.0.28249.1" +int METIN2_GET_VERSION() { return 28249; } diff --git a/source/UserInterface/Version.py b/source/UserInterface/Version.py new file mode 100644 index 0000000..eb599b5 --- /dev/null +++ b/source/UserInterface/Version.py @@ -0,0 +1,23 @@ +import os +import re +import sys +import subprocess as sp + +def P4_GetVersion(path): + cmd = "p4 changes -m1 %s" % path + proc = sp.Popen(cmd, stdout=sp.PIPE) + return proc.stdout.read() + +try: + oldData = open("Version.h").read() + mo = re.search("\d+;", oldData) + oldVersion = int(mo.group()[:-1]) if mo else 0 +except IOError: + oldVersion = 0 + +newVersion = int(P4_GetVersion("..\\..\\...").split()[1]) +if oldVersion != newVersion: + f = open ("Version.h", "wb") + f.write("#define VER_FILE_VERSION 1,0,%d,0\r\n" % newVersion) + f.write("#define VER_FILE_VERSION_STR \"1.0.%d.1\"\r\n" % newVersion) + f.write("int METIN2_GET_VERSION() { return %d; }\r\n" % newVersion) diff --git a/source/UserInterface/WiseLogicXTrap.cpp b/source/UserInterface/WiseLogicXTrap.cpp new file mode 100644 index 0000000..2d88712 --- /dev/null +++ b/source/UserInterface/WiseLogicXTrap.cpp @@ -0,0 +1,81 @@ +#include "StdAfx.h" +#include "Locale.h" +#include "WiseLogicXTrap.h" + +#ifdef XTRAP_CLIENT_ENABLE + + #include "urlmon.h" + #pragma comment(lib, "urlmon") + #pragma comment(lib, "wininet") + + #include + + #pragma comment(lib, "XTrap4Client_mt.lib") + #pragma comment(lib, "XTrap4Client_ClientPart_mt.lib") + #pragma comment(lib, "XTrap4Client_ServerPart_mt.lib") + #pragma comment(lib, "XTrap_Unipher_mt.lib") + //#pragma comment(lib, "XTrap4Launcher_mt.lib" ) + +bool XTrap_Init() +{ + //XTrap_L_Patch( XTRAP_PATCH_ARG, NULL, 60 ); + XTrap_C_Start( XTRAP_PATCH_ARG, NULL ); + return true; +} + +bool XTrap_CheckInit() +{ + XTrap_C_KeepAlive(); + return true; +} + +void XTrap_PollEvent() +{ + static DWORD dwLastTick = 0; + DWORD dwCurrentTick = ::GetTickCount(); + + if( (dwCurrentTick - dwLastTick) > 2000 ) + { + XTrap_C_CallbackAlive(2000); + dwLastTick = dwCurrentTick; + } +} + +void XTrap_ValidateCheckStream( LPVOID PacketBufferIn, LPVOID PacketBufferOut ) +{ + XTrap_CS_Step2( PacketBufferIn, PacketBufferOut, XTRAP_PROTECT_PE | XTRAP_PROTECT_TEXT | XTRAP_PROTECT_EXCEPT_VIRUS ); +} + + +void XTrap_SetUserInfo(LPCSTR szUserID, LPCSTR szServerName, LPCSTR szCharacterName, LPCSTR szCharacterClass, SOCKET hSocket) +{ + XTrap_C_SetUserInfoEx( szUserID, szServerName, szCharacterName, szCharacterClass, NULL, hSocket ); +} + +#else + +bool XTrap_Init() +{ + return true; +} + +bool XTrap_CheckInit() +{ + return true; +} + +void XTrap_PollEvent() +{ +} + +void XTrap_SetUserInfo(LPCSTR szUserID, LPCSTR szServerName, LPCSTR szCharacterName, LPCSTR szCharacterClass, SOCKET hSocket) +{ + +} + +void XTrap_ValidateCheckStream( LPVOID PacketBufferIn, LPVOID PacketBufferOut ) +{ + +} + +#endif /* XTRAP_CLIENT_ENABLE */ diff --git a/source/UserInterface/WiseLogicXTrap.h b/source/UserInterface/WiseLogicXTrap.h new file mode 100644 index 0000000..e699f23 --- /dev/null +++ b/source/UserInterface/WiseLogicXTrap.h @@ -0,0 +1,8 @@ +#pragma once + +bool XTrap_Init(); +bool XTrap_CheckInit(); +void XTrap_PollEvent(); +void XTrap_ValidateCheckStream( LPVOID PacketBufferIn, LPVOID PacketBufferOut ); +void XTrap_SetUserInfo(LPCSTR szUserID, LPCSTR szServerName, LPCSTR szCharacterName, LPCSTR szCharacterClass, SOCKET hSocket); + diff --git a/source/UserInterface/metin2.ico b/source/UserInterface/metin2.ico new file mode 100644 index 0000000..0c02a0a Binary files /dev/null and b/source/UserInterface/metin2.ico differ diff --git a/source/UserInterface/resource.h b/source/UserInterface/resource.h new file mode 100644 index 0000000..c307a88 --- /dev/null +++ b/source/UserInterface/resource.h @@ -0,0 +1,66 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by UserInterface.rc +// +#define IDS_APP_NAME 1 +#define IDS_POSSESSIVE_MORPHENE 2 +#define IDS_WARN_BAD_DRIVER 3 +#define IDS_WARN_NO_TNL 4 +#define IDS_ERR_CANNOT_READ_FILE 5 +#define IDS_ERR_NOT_LATEST_FILE 6 +#define IDS_ERR_MUST_LAUNCH_FROM_PATCHER 7 +#define IDI_METIN2 100 +#define IDD_COLOR_DIALOG 101 +#define IDC_CURSOR_NORMAL 102 +#define IDC_CURSOR_ATTACK 104 +#define IDC_CURSOR_CHAIR 105 +#define IDC_CURSOR_DOOR 106 +#define IDC_CURSOR_NO 107 +#define IDC_CURSOR_PICK 108 +#define IDC_CURSOR_TALK 109 +#define IDC_CURSOR_BUY 110 +#define IDC_CURSOR_SELL 111 +#define IDC_CURSOR_PICKUP 114 +#define IDC_CURSOR_CAMERA_ROTATE 139 +#define IDC_CURSOR_HSIZE 140 +#define IDC_CURSOR_VSIZE 141 +#define IDC_CURSOR_HVSIZE 142 +#define IDD_SELECT_LOCALE 143 +#define IDR_VERTEXSHADER_LEAF_DYNAMIC_LIGHTING 150 +#define IDR_VERTEXSHADER_LEAF_STATIC_LIGHTING 151 +#define IDR_VERTEXSHADER_WINDYBRANCH_DYNAMIC_LIGHTING 152 +#define IDR_VERTEXSHADER_WINDYLEAF_DYNAMIC_LIGHTING 153 +#define IDR_VERTEXSHADER_WINDYLEAF_STATIC_LIGHTING 154 +#define IDR_VERTEXSHADER_WINDYBRANCH_STATIC_LIGHTING 155 +#define IDC_MATERIAL_AMBIENT_SLIDER_RED 1000 +#define IDC_START 1001 +#define IDC_MATERIAL_AMBIENT_SLIDER_GREEN 1001 +#define IDC_EXIT 1002 +#define IDC_MATERIAL_AMBIENT_SLIDER_BLUE 1002 +#define IDC_LOCALE_LIST 1003 +#define IDC_MATERIAL_AMBIENT_PRINT_RED 1003 +#define IDC_MATERIAL_AMBIENT_PRINT_GREEN 1004 +#define IDC_MATERIAL_AMBIENT_PRINT_BLUE 1005 +#define IDC_NATURE_AMBIENT_SLIDER_RED 1006 +#define IDC_NATURE_AMBIENT_SLIDER_GREEN 1007 +#define IDC_NATURE_AMBIENT_SLIDER_BLUE 1008 +#define IDC_NATURE_AMBIENT_PRINT_RED 1009 +#define IDC_NATURE_AMBIENT_PRINT_GREEN 1010 +#define IDC_NATURE_AMBIENT_PRINT_BLUE 1011 +#define IDC_LIGHT_COLOR_SLIDER_RED 1012 +#define IDC_LIGHT_COLOR_SLIDER_GREEN 1013 +#define IDC_LIGHT_COLOR_SLIDER_BLUE 1014 +#define IDC_LIGHT_COLOR_PRINT_RED 1015 +#define IDC_LIGHT_COLOR_PRINT_GREEN 1016 +#define IDC_LIGHT_COLOR_PRINT_BLUE 1017 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 145 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif