Compare commits
562 Commits
amxmodx-0.
...
amxmodx-1.
Author | SHA1 | Date | |
---|---|---|---|
7b527c9c25 | |||
6256687272 | |||
5be9ba4a68 | |||
8f61073f43 | |||
a973adb4f2 | |||
96c9fc8bc8 | |||
d472d5d309 | |||
a819a494b8 | |||
f2c3dfa874 | |||
fe3645d809 | |||
b9ff24171f | |||
59fb0a39b2 | |||
94202eec34 | |||
ef8715892b | |||
e5ce86d61a | |||
7825364e06 | |||
5cba645e49 | |||
ef4d04a7e1 | |||
0302803f38 | |||
d57004c91f | |||
f5fe076ec1 | |||
7eaa8a1a39 | |||
de5abef49a | |||
edd9fa2879 | |||
0686da47a6 | |||
4f9f548a58 | |||
2d79c6e634 | |||
ad6c7d412a | |||
686dadc9c5 | |||
70bff9c430 | |||
cefad23b72 | |||
0447c39a97 | |||
688c12ac8b | |||
5cbcd34bec | |||
f9563b5103 | |||
38da105ac1 | |||
cc393d0e8d | |||
25cbe60bf8 | |||
6be3805841 | |||
6e3de2c53a | |||
cf274f7f50 | |||
17cca4587c | |||
3014e60bdb | |||
e5b4b5a53d | |||
bc66a93fcf | |||
8f06e36d04 | |||
e38b64ff82 | |||
4687ecd99b | |||
b1718bc334 | |||
d7063435f4 | |||
a7133501d5 | |||
5078ed9d0f | |||
424a8c17b3 | |||
90c0e32cb3 | |||
d3acbcc319 | |||
a776e832dd | |||
65bd10c47b | |||
9bdd0ba0a4 | |||
ff48a9076b | |||
3f99ce7af5 | |||
4451691aa2 | |||
bc64ae2712 | |||
7f55873bfb | |||
d94016384a | |||
eb87344a16 | |||
43c06b0e36 | |||
a35b96fb7e | |||
562633c040 | |||
71eac5c544 | |||
4fe39dd5cc | |||
7605abc929 | |||
0a4133b4d0 | |||
0086b58f39 | |||
583b67dbb1 | |||
a81f356835 | |||
b2218661f8 | |||
8234977fa9 | |||
13ed6ed2d6 | |||
a7fb4e85c9 | |||
abfca025d5 | |||
34acc54cc9 | |||
b27eaab57f | |||
dd6c169994 | |||
5751d381af | |||
28998b5c14 | |||
a939cd0e2a | |||
d9d5446e86 | |||
b91cc24d32 | |||
faae071ee8 | |||
cdbfa38391 | |||
5d92972aad | |||
ba17c8a75f | |||
389a593f9e | |||
b35e5dbd55 | |||
0591c38d45 | |||
041e73dc7e | |||
431eb72518 | |||
75b63da66f | |||
51d54a96ff | |||
df982ceb79 | |||
ee978890b8 | |||
fa46d2e1b5 | |||
559d8bc7eb | |||
0d90a958ae | |||
cb7bfbf642 | |||
6cf6edb5b6 | |||
b9ee99a3dc | |||
a86302beea | |||
f6d647f614 | |||
32a42886dd | |||
5b1d0dd2b9 | |||
166b5ca650 | |||
044fa19470 | |||
1d6b173e87 | |||
eaf102d78f | |||
31436e3ecf | |||
62cdaf5e10 | |||
0de08a9452 | |||
0de288139d | |||
94d3b31f40 | |||
6d7442fb4f | |||
68ad9c2b9a | |||
191acd8e42 | |||
ce043d0633 | |||
f18354807e | |||
6a97d73167 | |||
586d09e533 | |||
ba24020857 | |||
4b9425cf3b | |||
ef2a9a2b34 | |||
1a3a5331d1 | |||
363e7e2270 | |||
fdbee670c5 | |||
a47ccb2a2a | |||
9e46d2da47 | |||
451a6d8464 | |||
4abd7b4706 | |||
09a08fd2f6 | |||
4609cb409b | |||
955aa04b41 | |||
69a5b5f410 | |||
b94fbb519a | |||
832de07128 | |||
f6b91f9258 | |||
f9ca86cee6 | |||
0ef9b80430 | |||
057929e2f6 | |||
25d629083f | |||
c2502626e6 | |||
76505f172a | |||
79268c5316 | |||
0c36613352 | |||
37a80e6ef6 | |||
7fc97524e2 | |||
842813dcbb | |||
9e194394c3 | |||
e188bf087a | |||
c5aae0d8aa | |||
25f1870020 | |||
911e2ecefe | |||
b9131293c5 | |||
536a4f8472 | |||
29e1a5edc8 | |||
34e5872881 | |||
1d853b5fee | |||
191824d72a | |||
99f65175ff | |||
2f8e311140 | |||
21551a6ea8 | |||
c4f097bb36 | |||
ffbf9fdca6 | |||
3863bd3ccc | |||
a89e1ac536 | |||
2f64226c6b | |||
91da6f1631 | |||
e8c87f8d89 | |||
3cba7811bd | |||
70396a2fc1 | |||
1a53b7bba7 | |||
74ec2e75b8 | |||
b312da8c63 | |||
fe2d28f711 | |||
1b09be51e1 | |||
e1d1802cb9 | |||
db293cc451 | |||
116984afed | |||
a9d4e4e711 | |||
ef908ff4f5 | |||
4631311905 | |||
1106113f2b | |||
35ed810775 | |||
e1a1153018 | |||
e91cd0862e | |||
5ac71db62d | |||
d270feb15f | |||
1c8aca42eb | |||
e0dbc031cc | |||
39eba4134e | |||
9f77c8a4a2 | |||
9b6fb64aba | |||
82d6cb9de0 | |||
8ae1d4ce27 | |||
21541fcc7f | |||
e9e4ab69e6 | |||
35ecd40228 | |||
e8d30a11d7 | |||
36d19dfe04 | |||
5d90ccf088 | |||
de5eb6924a | |||
0600e3357c | |||
40f28a543e | |||
13b6c0764c | |||
950d1b4a5f | |||
85ed8468f8 | |||
756a6a2b65 | |||
e63ed1e3e0 | |||
27c2978617 | |||
b0c9b868cd | |||
101c590f32 | |||
943a75d7e1 | |||
611ad2be94 | |||
64b7c7b600 | |||
cc899d298d | |||
3f2c117039 | |||
0d21377035 | |||
48749382fb | |||
996f461157 | |||
8d898ae459 | |||
b609eead1b | |||
567ab19fe5 | |||
1cc60fc9ad | |||
959a5b9225 | |||
9b8658606b | |||
51ff0a2c49 | |||
c1552aacd6 | |||
ba245458de | |||
c32e747dc1 | |||
7ad84abb09 | |||
dd6abc5487 | |||
3642cedd2b | |||
df87bc06c2 | |||
9d200888ff | |||
ebf0945c6e | |||
7c6d869cb4 | |||
6de8178c30 | |||
1b80dd5584 | |||
7ceaa4801d | |||
15bd719cf5 | |||
acb2b27852 | |||
abbb2f2cc2 | |||
aa8beace98 | |||
d17d9103de | |||
85f5604d43 | |||
fa42dbf011 | |||
d1c27a7534 | |||
8675d6a4a8 | |||
1d770fd400 | |||
d6b704e74c | |||
eeee302722 | |||
81f4a505c1 | |||
560f50eda7 | |||
73f1e4d77e | |||
87fd5e2b4e | |||
01cc4a1bad | |||
ad732d7286 | |||
448da8bd9e | |||
a4be1ac635 | |||
5e46f64d75 | |||
f9281fe309 | |||
d3a49d1d41 | |||
8736214678 | |||
b2aa069cd4 | |||
01bacc3275 | |||
53b7516449 | |||
916325d3db | |||
054f046807 | |||
a4e57797f5 | |||
afef83ae66 | |||
730857a23b | |||
7fd9fff987 | |||
3074ca0756 | |||
7b8165fe6f | |||
3774575160 | |||
57eec2b88e | |||
b2eb9df894 | |||
00e9f2bbea | |||
adf12ab745 | |||
9d4e5b18ee | |||
8a40ed8cd6 | |||
c79909eb80 | |||
26e8b0dbb6 | |||
a2c2dc88fc | |||
99f47224ee | |||
a085cef0d6 | |||
2980fb1d82 | |||
3ed92695be | |||
9d797f8664 | |||
d7dbf60c8f | |||
06923d0f6d | |||
948be015a7 | |||
1a339b2f77 | |||
39479f2403 | |||
e4beb3828a | |||
84caa10733 | |||
a8ff2abab5 | |||
b4d2f83d6f | |||
be28d95b8d | |||
2401d1833e | |||
a189c0bda7 | |||
cc462c9ccb | |||
3d7987e8d8 | |||
1c544f55ca | |||
5c231919b6 | |||
4b48be3e93 | |||
ca07e53293 | |||
3f2a8ccfc5 | |||
e097932ac9 | |||
27e4174be6 | |||
7f47d2de56 | |||
6200ee6977 | |||
e98fb7d6e4 | |||
4e6233b898 | |||
544b74f839 | |||
4a823a0894 | |||
53188ab941 | |||
5f7dabf9b6 | |||
e343d224ce | |||
188023b5ac | |||
f18adbf9d6 | |||
9959ef52b3 | |||
8e58484fc5 | |||
a58ab24b0c | |||
a67085217f | |||
f08f16c20d | |||
ec9d4a52fe | |||
01b955d2d4 | |||
a384a78544 | |||
b4ad89e6ef | |||
2b4ed9cc27 | |||
e986848faf | |||
21ceae3c9e | |||
51b9fae4bc | |||
4e7d24f64b | |||
40640c92d4 | |||
c5b3919122 | |||
29a22bb5fd | |||
2baf9c4c20 | |||
c4727c1dc3 | |||
4901dee86d | |||
c1f2a499f8 | |||
7aa31c764d | |||
08fea0eea1 | |||
add716276b | |||
e688addd98 | |||
199131b2b8 | |||
fb29cbff16 | |||
11fa330f10 | |||
ca720c8c83 | |||
456d7b69a2 | |||
a86cb11fd7 | |||
96c65dcfc4 | |||
86451da9a9 | |||
57607f1a28 | |||
eb4fdf53fa | |||
6251521102 | |||
c940a0b621 | |||
719af5c72c | |||
128d19c69e | |||
46861ff5b4 | |||
ee464539de | |||
f69ff642df | |||
db77c245e6 | |||
d5caf3e2ac | |||
148b365e43 | |||
8c215e5d6f | |||
0513dae63e | |||
f73a8356f6 | |||
77c5198009 | |||
820fedca22 | |||
28a1182cd2 | |||
16444a713a | |||
6457fc45c7 | |||
cb94cccf22 | |||
c0ee97b437 | |||
f950d384b6 | |||
426a71e7f2 | |||
d49b2453bb | |||
74a1db4417 | |||
dc7e1e2494 | |||
5dfbcf2a23 | |||
09c1471c3a | |||
50a882cf4c | |||
850557df5a | |||
4c43eccbb5 | |||
380db7c884 | |||
1994917044 | |||
449f31d78c | |||
bc2386fe47 | |||
ec02883f6e | |||
abd372447a | |||
fef70c0386 | |||
719b32d71f | |||
4e385fec50 | |||
c9b2f2f060 | |||
d038e926fd | |||
712859eb20 | |||
826893d8d2 | |||
47d1881c29 | |||
741666b742 | |||
ee8e30417c | |||
cc4bbadfa2 | |||
8761791473 | |||
6697b7b1d3 | |||
3c9a47aae3 | |||
d1675c82b5 | |||
b40643950d | |||
ff5b1dd7cc | |||
3587483fa6 | |||
c9c26b869c | |||
8f18856e91 | |||
ddfba00791 | |||
c6eaa97391 | |||
5eb095b514 | |||
4e0bfe161e | |||
0e681d9bd4 | |||
3d1162ecd9 | |||
3414cd7ce7 | |||
66386cca59 | |||
75396c753c | |||
4edd77faee | |||
91db6c7398 | |||
46390b83ac | |||
89eda75b1f | |||
f14808e009 | |||
b569ea3c3f | |||
f595be47dc | |||
ee3404fea0 | |||
61fc7da654 | |||
14c3930b3d | |||
3efa25a5fb | |||
c29a7d34e5 | |||
daa873d8ed | |||
c09de969eb | |||
b0dd18580c | |||
32deaa261f | |||
3a8e103faf | |||
f4b1c9f78a | |||
618759f390 | |||
ced5d6ff57 | |||
db4041114f | |||
b52d77e8bf | |||
940b0be4b9 | |||
75f49e78b0 | |||
f06359e38f | |||
2733adbb49 | |||
fc4d8f183b | |||
ea70c77dd8 | |||
301a69aacb | |||
92eda7c214 | |||
4800ab292c | |||
34cfce33a1 | |||
fec17424fb | |||
264dd7a10d | |||
6cef4eab4f | |||
f4ada32ec2 | |||
bff8c3cdcf | |||
3b670333de | |||
eb36757ef1 | |||
054b1f8868 | |||
23234fad0b | |||
74dca8b6ef | |||
2a187988f6 | |||
d1ee9ee9ba | |||
380f560fa4 | |||
d9b6fa1f93 | |||
8a57648b87 | |||
80b8591295 | |||
f94aa52974 | |||
ef8ad4a894 | |||
41b6f6bd4a | |||
9e8f380121 | |||
39070081d1 | |||
00d8ffe503 | |||
4ef8530bba | |||
77aa0f4f8e | |||
766246648d | |||
7963eb1cde | |||
02d8b2c523 | |||
227fb0411e | |||
027ae6dc7e | |||
334905e16e | |||
e3fad723b8 | |||
5e52c45968 | |||
e3a2a2bc17 | |||
18b75cb07c | |||
4e1c5a3e02 | |||
5db290890f | |||
b9c83aa4a2 | |||
bb12f71137 | |||
0a3911231b | |||
846ef95c58 | |||
601bb30b7e | |||
9728b79c33 | |||
90baf98057 | |||
8ad6437dd8 | |||
02bf904467 | |||
62e4bbcfe9 | |||
fc15ac1f41 | |||
01770f0e5b | |||
87ff81a499 | |||
981f41aee0 | |||
605ca152c2 | |||
0fc8f0b489 | |||
c511d80da7 | |||
8304fc143c | |||
f3cfd31668 | |||
ef90960121 | |||
3700b8b39f | |||
b83f2f5257 | |||
06f61cf92a | |||
5a5ff6d8ea | |||
bbe2626fd1 | |||
d5646ae238 | |||
df43d897df | |||
687a0f23da | |||
aa0dc4dbaf | |||
de399c54c6 | |||
58d522e4c3 | |||
3b90cca5bd | |||
b7c9cfeea4 | |||
4fcad51d25 | |||
c2a2fc7dbe | |||
3f0d3c257a | |||
ecc07d4b45 | |||
8da965552b | |||
cfe36dea52 | |||
c16eab09ec | |||
d07cc0424d | |||
c669efd609 | |||
c3151b312a | |||
3fc3ece5b0 | |||
6887dfef16 | |||
867e7615ae | |||
5157be6e3d | |||
82ca25b231 | |||
a555f9b3f0 | |||
c1a6ce2565 | |||
8874666109 | |||
5233be593f | |||
0f38a24555 | |||
8d06f80eeb | |||
0983698d2e | |||
dde43b6e0d | |||
4382158b88 | |||
ba69d73785 | |||
be3d078d5a | |||
b8ca4586ad | |||
25750d2f05 | |||
423a467a70 | |||
d6e18a3e97 | |||
a6d5d89209 | |||
16b35006bd |
@ -396,17 +396,11 @@ void EventsMngr::parseValue(const char *sz)
|
||||
|
||||
void EventsMngr::executeEvents()
|
||||
{
|
||||
int err;
|
||||
|
||||
if (!m_ParseFun)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef ENABLEEXEPTIONS
|
||||
try
|
||||
{
|
||||
#endif // #ifdef ENABLEEXEPTIONS
|
||||
for (ClEventVecIter iter = m_ParseFun->begin(); iter; ++iter)
|
||||
{
|
||||
if ( (*iter).m_Done )
|
||||
@ -414,22 +408,9 @@ void EventsMngr::executeEvents()
|
||||
(*iter).m_Done = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
(*iter).m_Stamp = (float)*m_Timer;
|
||||
|
||||
if ((err = amx_Exec((*iter).m_Plugin->getAMX(), NULL, (*iter).m_Func, 1, m_ParseVault ? m_ParseVault[0].iValue : 0)) != AMX_ERR_NONE)
|
||||
{
|
||||
LogError((*iter).m_Plugin->getAMX(), err, "");
|
||||
executeForwards((*iter).m_Func, m_ParseVault ? m_ParseVault[0].iValue : 0);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLEEXEPTIONS
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
AMXXLOG_Log( "[AMXX] fatal error at event execution");
|
||||
}
|
||||
#endif // #ifdef ENABLEEXEPTIONS
|
||||
|
||||
m_CurrentMsgType = -1;
|
||||
m_ParseFun = NULL;
|
||||
|
@ -31,6 +31,8 @@
|
||||
|
||||
#include "amxmodx.h"
|
||||
|
||||
void AMXAPI amxx_InvalidateTrace(AMX *amx);
|
||||
|
||||
CForward::CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam *paramTypes)
|
||||
{
|
||||
m_FuncName = name;
|
||||
@ -70,8 +72,13 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
{
|
||||
if (iter->pPlugin->isExecutable(iter->func))
|
||||
{
|
||||
// Get debug info
|
||||
AMX *amx = (*iter).pPlugin->getAMX();
|
||||
AMX_DBGINFO *pInfo = (AMX_DBGINFO *)(amx->userdata[2]);
|
||||
if (pInfo)
|
||||
pInfo->error = AMX_ERR_NONE;
|
||||
// handle strings & arrays
|
||||
int i;
|
||||
int i, ax=0;
|
||||
for (i = 0; i < m_NumParams; ++i)
|
||||
{
|
||||
if (m_ParamTypes[i] == FP_STRING || m_ParamTypes[i] == FP_STRINGEX)
|
||||
@ -80,13 +87,13 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
amx_Allot(iter->pPlugin->getAMX(),
|
||||
(m_ParamTypes[i] == FP_STRING) ? strlen(reinterpret_cast<const char*>(params[i]))+1 : STRINGEX_MAXLENGTH,
|
||||
&realParams[i], &tmp);
|
||||
amx_SetString(tmp, (const char *)(params[i]), 0, 0);
|
||||
amx_SetStringOld(tmp, (const char *)(params[i]), 0, 0);
|
||||
physAddrs[i] = tmp;
|
||||
}
|
||||
else if (m_ParamTypes[i] == FP_ARRAY)
|
||||
{
|
||||
cell *tmp;
|
||||
amx_Allot(iter->pPlugin->getAMX(), preparedArrays[params[i]].size,
|
||||
amx_Allot(amx, preparedArrays[params[i]].size,
|
||||
&realParams[i], &tmp);
|
||||
physAddrs[i] = tmp;
|
||||
if (preparedArrays[params[i]].type == Type_Cell)
|
||||
@ -105,12 +112,28 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
realParams[i] = params[i];
|
||||
}
|
||||
}
|
||||
//Push the parameters in reverse order. Weird, unfriendly part of Small 3.0!
|
||||
for (i=m_NumParams-1; i>=0; i--)
|
||||
{
|
||||
amx_Push(amx, realParams[i]);
|
||||
}
|
||||
// exec
|
||||
cell retVal;
|
||||
int err = amx_Execv(iter->pPlugin->getAMX(), &retVal, iter->func, m_NumParams, realParams);
|
||||
int err = amx_Exec(amx, &retVal, iter->func);
|
||||
// log runtime error, if any
|
||||
if (err != AMX_ERR_NONE)
|
||||
LogError(iter->pPlugin->getAMX(), err, "");
|
||||
{
|
||||
//Did something else set an error?
|
||||
if (pInfo && pInfo->error != AMX_ERR_NONE)
|
||||
{
|
||||
//we don't care, something else logged the error.
|
||||
} else {
|
||||
//nothing logged the error so spit it out anyway
|
||||
LogError(amx, err, "");
|
||||
}
|
||||
}
|
||||
amxx_InvalidateTrace(amx);
|
||||
amx->error = AMX_ERR_NONE;
|
||||
|
||||
// cleanup strings & arrays
|
||||
for (i = 0; i < m_NumParams; ++i)
|
||||
@ -122,7 +145,7 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
else if (m_ParamTypes[i] == FP_STRINGEX)
|
||||
{
|
||||
// copy back
|
||||
amx_GetString(reinterpret_cast<char*>(params[i]), physAddrs[i], 0);
|
||||
amx_GetStringOld(reinterpret_cast<char*>(params[i]), physAddrs[i], 0);
|
||||
amx_Release(iter->pPlugin->getAMX(), realParams[i]);
|
||||
}
|
||||
else if (m_ParamTypes[i] == FP_ARRAY)
|
||||
@ -206,6 +229,10 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
if (!pPlugin->isExecutable(m_Func))
|
||||
return 0;
|
||||
|
||||
AMX_DBGINFO *pInfo = (AMX_DBGINFO *)(m_Amx->userdata[2]);
|
||||
if (pInfo)
|
||||
pInfo->error = AMX_ERR_NONE;
|
||||
|
||||
// handle strings & arrays
|
||||
int i;
|
||||
for (i = 0; i < m_NumParams; ++i)
|
||||
@ -216,7 +243,7 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
amx_Allot(m_Amx,
|
||||
(m_ParamTypes[i] == FP_STRING) ? strlen(reinterpret_cast<const char*>(params[i]))+1 : STRINGEX_MAXLENGTH,
|
||||
&realParams[i], &tmp);
|
||||
amx_SetString(tmp, (const char *)(params[i]), 0, 0);
|
||||
amx_SetStringOld(tmp, (const char *)(params[i]), 0, 0);
|
||||
physAddrs[i] = tmp;
|
||||
}
|
||||
else if (m_ParamTypes[i] == FP_ARRAY)
|
||||
@ -241,10 +268,24 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
realParams[i] = params[i];
|
||||
}
|
||||
}
|
||||
|
||||
for (i=m_NumParams-1; i>=0; i--)
|
||||
amx_Push(m_Amx, realParams[i]);
|
||||
// exec
|
||||
cell retVal;
|
||||
amx_Execv(m_Amx, &retVal, m_Func, m_NumParams, realParams);
|
||||
int err = amx_Exec(m_Amx, &retVal, m_Func);
|
||||
if (err != AMX_ERR_NONE)
|
||||
{
|
||||
//Did something else set an error?
|
||||
if (pInfo && pInfo->error != AMX_ERR_NONE)
|
||||
{
|
||||
//we don't care, something else logged the error.
|
||||
} else {
|
||||
//nothing logged the error so spit it out anyway
|
||||
LogError(m_Amx, err, "");
|
||||
}
|
||||
}
|
||||
amxx_InvalidateTrace(m_Amx);
|
||||
m_Amx->error = AMX_ERR_NONE;
|
||||
|
||||
// cleanup strings & arrays
|
||||
for (i = 0; i < m_NumParams; ++i)
|
||||
@ -256,7 +297,7 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
else if (m_ParamTypes[i] == FP_STRINGEX)
|
||||
{
|
||||
// copy back
|
||||
amx_GetString(reinterpret_cast<char*>(params[i]), physAddrs[i], 0);
|
||||
amx_GetStringOld(reinterpret_cast<char*>(params[i]), physAddrs[i], 0);
|
||||
amx_Release(m_Amx, realParams[i]);
|
||||
}
|
||||
else if (m_ParamTypes[i] == FP_ARRAY)
|
||||
@ -494,6 +535,7 @@ cell executeForwards(int id, ...)
|
||||
REAL tmp = (REAL)va_arg(argptr, double); // floats get converted to doubles
|
||||
params[i] = *(cell*)&tmp;
|
||||
}
|
||||
else
|
||||
params[i] = (cell)va_arg(argptr, cell);
|
||||
}
|
||||
va_end(argptr);
|
||||
@ -502,10 +544,20 @@ cell executeForwards(int id, ...)
|
||||
|
||||
cell CForwardMngr::prepareArray(void *ptr, unsigned int size, ForwardArrayElemType type, bool copyBack)
|
||||
{
|
||||
if (m_TmpArraysNum >= FORWARD_MAX_PARAMS)
|
||||
{
|
||||
#ifdef MEMORY_TEST
|
||||
m_validateAllAllocUnits();
|
||||
#endif // MEMORY_TEST
|
||||
AMXXLOG_Log("[AMXX] Forwards with more than 32 parameters are not supported (tried to prepare array # %d).", m_TmpArraysNum + 1);
|
||||
m_TmpArraysNum = 0;
|
||||
return -1;
|
||||
}
|
||||
m_TmpArrays[m_TmpArraysNum].ptr = ptr;
|
||||
m_TmpArrays[m_TmpArraysNum].size = size;
|
||||
m_TmpArrays[m_TmpArraysNum].type = type;
|
||||
m_TmpArrays[m_TmpArraysNum].copyBack = copyBack;
|
||||
|
||||
return m_TmpArraysNum++;
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@
|
||||
#ifndef FORWARD_H
|
||||
#define FORWARD_H
|
||||
|
||||
const int FORWARD_MAX_PARAMS = 16;
|
||||
const int FORWARD_MAX_PARAMS = 32;
|
||||
|
||||
enum ForwardExecType
|
||||
{
|
||||
|
@ -33,6 +33,10 @@
|
||||
#include "amxmodx.h"
|
||||
#include "CLang.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#define _snprintf snprintf
|
||||
#endif
|
||||
|
||||
#define LITIDX_NONE 0
|
||||
#define LITIDX_BRACKET 1
|
||||
#define LITIDX_DEFINITION 2
|
||||
@ -498,7 +502,7 @@ int CLangMngr::GetKeyEntry(String &key)
|
||||
}
|
||||
|
||||
#define CHECK_PTR(ptr, start, bufsize) if ((ptr) - (start) >= (bufsize)) { \
|
||||
AMXXLOG_Log("[AMXX] Buffer overflow in formatting (line %d, \"%s\")", amx->curline, g_plugins.findPluginFast(amx)->getName()); \
|
||||
LogError(amx, AMX_ERR_STACKERR, "Buffer overflow in string formatting"); \
|
||||
outbuf[0] = 0; \
|
||||
len = 0; \
|
||||
return outbuf; }
|
||||
@ -509,7 +513,7 @@ int CLangMngr::GetKeyEntry(String &key)
|
||||
{ \
|
||||
strcpy(outbuf, ""); \
|
||||
len = 0; \
|
||||
AMXXLOG_Log("[AMXX] Plugin did not format a string correctly (parameter %d (total %d), line %d, \"%s\")", parm, paramCount, amx->curline, g_plugins.findPluginFast(amx)->getName()); \
|
||||
LogError(amx, AMX_ERR_PARAMS, "String formatted incorrectly - parameter %d (total %d)", parm, paramCount); \
|
||||
return outbuf; \
|
||||
}
|
||||
|
||||
@ -536,7 +540,7 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
||||
// Handle player ids (1-32) and server language
|
||||
if (*pAmxLangName == LANG_PLAYER) // LANG_PLAYER
|
||||
{
|
||||
if ((int)CVAR_GET_FLOAT("amx_client_languages"))
|
||||
if ((int)CVAR_GET_FLOAT("amx_client_languages") == 0)
|
||||
{
|
||||
cpLangName = g_vault.get("server_language");
|
||||
} else {
|
||||
@ -545,7 +549,7 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
||||
} else if (*pAmxLangName == LANG_SERVER) { // LANG_SERVER
|
||||
cpLangName = g_vault.get("server_language");
|
||||
} else if (*pAmxLangName >= 1 && *pAmxLangName <= 32) { // Direct Client Id
|
||||
if ((int)CVAR_GET_FLOAT("amx_client_languages"))
|
||||
if ((int)CVAR_GET_FLOAT("amx_client_languages") == 0)
|
||||
{
|
||||
cpLangName = g_vault.get("server_language");
|
||||
} else {
|
||||
@ -584,9 +588,17 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
||||
if (*def == '%')
|
||||
{
|
||||
++def;
|
||||
if (*def == '%' || *def == 0)
|
||||
{
|
||||
*outptr++ = '%';
|
||||
++def;
|
||||
}
|
||||
else
|
||||
{
|
||||
static char format[32];
|
||||
format[0] = '%';
|
||||
char *ptr = format+1;
|
||||
|
||||
while (ptr-format<sizeof(format) && !isalpha(*ptr++ = *def++))
|
||||
/*nothing*/;
|
||||
ZEROTERM(format);
|
||||
@ -604,7 +616,7 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
||||
*tmpPtr++ = *tmpCell++;
|
||||
|
||||
*tmpPtr = 0;
|
||||
sprintf(outptr, format, tmpString);
|
||||
_snprintf(outptr, sizeof(outbuf)-(outptr-outbuf)-1, format, tmpString);
|
||||
ZEROTERM(outbuf);
|
||||
break;
|
||||
}
|
||||
@ -612,7 +624,7 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
||||
case 'f':
|
||||
{
|
||||
NEXT_PARAM();
|
||||
sprintf(outptr, format, *(REAL*)get_amxaddr(amx, params[parm++]));
|
||||
_snprintf(outptr, sizeof(outbuf)-(outptr-outbuf)-1, format, *(REAL*)get_amxaddr(amx, params[parm++]));
|
||||
ZEROTERM(outbuf);
|
||||
break;
|
||||
}
|
||||
@ -621,7 +633,7 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
||||
case 'c':
|
||||
{
|
||||
NEXT_PARAM();
|
||||
sprintf(outptr, format, (int)*get_amxaddr(amx, params[parm++]));
|
||||
_snprintf(outptr, sizeof(outbuf)-(outptr-outbuf)-1, format, (int)*get_amxaddr(amx, params[parm++]));
|
||||
ZEROTERM(outbuf);
|
||||
break;
|
||||
}
|
||||
@ -634,6 +646,7 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
||||
}
|
||||
outptr += strlen(outptr);
|
||||
}
|
||||
}
|
||||
else if (*def == '^')
|
||||
{
|
||||
++def;
|
||||
@ -689,7 +702,7 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
||||
while (tmpPtr-tmpString<sizeof(tmpString) && *tmpCell)
|
||||
*tmpPtr++ = *tmpCell++;
|
||||
*tmpPtr = 0;
|
||||
sprintf(outptr, format, tmpString);
|
||||
_snprintf(outptr, sizeof(outbuf)-(outptr-outbuf)-1, format, tmpString);
|
||||
ZEROTERM(outbuf);
|
||||
break;
|
||||
}
|
||||
@ -697,7 +710,7 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
||||
case 'f':
|
||||
{
|
||||
NEXT_PARAM();
|
||||
sprintf(outptr, format, *(REAL*)get_amxaddr(amx, params[parm++]));
|
||||
_snprintf(outptr, sizeof(outbuf)-(outptr-outbuf)-1, format, *(REAL*)get_amxaddr(amx, params[parm++]));
|
||||
break;
|
||||
}
|
||||
case 'i':
|
||||
@ -705,7 +718,7 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
||||
case 'c':
|
||||
{
|
||||
NEXT_PARAM();
|
||||
sprintf(outptr, format, (int)*get_amxaddr(amx, params[parm++]));
|
||||
_snprintf(outptr, sizeof(outbuf)-(outptr-outbuf)-1, format, (int)*get_amxaddr(amx, params[parm++]));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -957,7 +970,7 @@ int CLangMngr::MergeDefinitionFile(const char *file)
|
||||
return 0;
|
||||
}
|
||||
MD5 md5;
|
||||
md5.update(fp);
|
||||
md5.update(fp); // closes for us
|
||||
md5.finalize();
|
||||
char md5buffer[33];
|
||||
md5.hex_digest(md5buffer);
|
||||
|
@ -151,11 +151,12 @@ LogEventsMngr::CLogEvent* LogEventsMngr::registerLogEvent( CPluginMngr::CPlugin*
|
||||
|
||||
void LogEventsMngr::executeLogEvents()
|
||||
{
|
||||
int err;
|
||||
bool valid;
|
||||
for(CLogEvent* a = logevents[ logArgc ]; a ; a = a->next){
|
||||
for(CLogEvent* a = logevents[ logArgc ]; a ; a = a->next)
|
||||
{
|
||||
valid = true;
|
||||
for( CLogEvent::LogCond* b = a->filters; b ; b = b->next){
|
||||
for( CLogEvent::LogCond* b = a->filters; b ; b = b->next)
|
||||
{
|
||||
valid = false;
|
||||
for( CLogEvent::LogCondEle* c = b->list; c ; c = c->next) {
|
||||
if ( c->cmp->compareCondition( logArgs[b->argnum] ) == 0 ){
|
||||
@ -163,27 +164,14 @@ void LogEventsMngr::executeLogEvents()
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!valid) break;
|
||||
if (!valid)
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef ENABLEEXEPTIONS
|
||||
try
|
||||
if (valid)
|
||||
{
|
||||
#endif
|
||||
|
||||
if (valid){
|
||||
if ((err = amx_Exec(a->plugin->getAMX(), NULL , a->func , 0)) != AMX_ERR_NONE)
|
||||
LogError(a->plugin->getAMX(), err, "");
|
||||
executeForwards(a->func);
|
||||
}
|
||||
|
||||
#ifdef ENABLEEXEPTIONS
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
AMXXLOG_Log( "[AMXX] fatal error at log forward function execution");
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ MenuMngr::~MenuMngr()
|
||||
int MenuMngr::findMenuId(const char* name, AMX* amx)
|
||||
{
|
||||
for( MenuIdEle* b = headid; b ; b = b->next) {
|
||||
if ( (!b->amx || amx == b->amx) && strstr(name,b->name.c_str()) )
|
||||
if ( (!amx || !b->amx || amx == b->amx) && strstr(name,b->name.c_str()) )
|
||||
return b->id;
|
||||
}
|
||||
return 0;
|
||||
|
@ -83,7 +83,7 @@ public:
|
||||
|
||||
int findMenuId(const char* name, AMX* a = 0);
|
||||
int registerMenuId(const char* n, AMX* a );
|
||||
void registerMenuCmd( CPluginMngr::CPlugin *a,int mi, int k , int f );
|
||||
void registerMenuCmd(CPluginMngr::CPlugin *a, int mi, int k, int f);
|
||||
void clear();
|
||||
|
||||
class iterator {
|
||||
@ -98,10 +98,6 @@ public:
|
||||
};
|
||||
inline iterator begin() const { return iterator(headcmd); }
|
||||
inline iterator end() const { return iterator(0); }
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -210,7 +210,7 @@ int TeamIds::findTeamId( const char* n )
|
||||
{
|
||||
TeamEle* a = head;
|
||||
while( a ){
|
||||
if ( !strcmpi(a->name.c_str(),n) )
|
||||
if ( !stricmp(a->name.c_str(),n) )
|
||||
return a->id;
|
||||
a = a->next;
|
||||
}
|
||||
|
@ -99,6 +99,8 @@ public:
|
||||
int death_victim;
|
||||
bool death_tk;
|
||||
String death_weapon;
|
||||
int newmenu;
|
||||
int page;
|
||||
|
||||
Vector lastTrace;
|
||||
Vector thisTrace;
|
||||
|
@ -35,11 +35,6 @@
|
||||
#define FAR
|
||||
#endif
|
||||
|
||||
// Old
|
||||
typedef int (FAR *QUERYMOD)(module_info_s**);
|
||||
typedef int (FAR *ATTACHMOD)(pfnamx_engine_g*,pfnmodule_engine_g*);
|
||||
typedef int (FAR *DETACHMOD)(void);
|
||||
|
||||
// New
|
||||
typedef void* (*PFN_REQ_FNPTR)(const char * /*name*/);
|
||||
typedef int (FAR *QUERYMOD_NEW)(int * /*ifvers*/, amxx_module_info_s * /*modInfo*/);
|
||||
@ -47,81 +42,6 @@ typedef int (FAR *ATTACHMOD_NEW)(PFN_REQ_FNPTR /*reqFnptrFunc*/);
|
||||
typedef int (FAR *DETACHMOD_NEW)(void);
|
||||
typedef void (FAR *PLUGINSLOADED_NEW)(void);
|
||||
|
||||
// Old
|
||||
// These functions are needed since Small Abstract Machine 2.5.0
|
||||
int wamx_FindPublic(AMX *amx, char *name, int *index)
|
||||
{ return amx_FindPublic(amx, name, index); }
|
||||
|
||||
int wamx_FindPubVar(AMX *amx, char *varname, cell *amx_addr)
|
||||
{ return amx_FindPubVar(amx, varname, amx_addr); }
|
||||
|
||||
int wamx_GetString(char *dest, cell *source)
|
||||
{ return amx_GetString(dest, source, 0); }
|
||||
|
||||
AMX_NATIVE_INFO *wamx_NativeInfo(char *name, AMX_NATIVE func)
|
||||
{ return amx_NativeInfo(name, func); }
|
||||
|
||||
int wamx_SetString(cell *dest, char *source, int pack)
|
||||
{ return amx_SetString(dest, source, pack, 0); }
|
||||
|
||||
pfnamx_engine_g engAmxFunc = {
|
||||
amx_Align16,
|
||||
amx_Align32,
|
||||
amx_Allot,
|
||||
amx_Callback,
|
||||
amx_Clone,
|
||||
amx_Debug,
|
||||
amx_Exec,
|
||||
amx_Execv,
|
||||
wamx_FindPublic,
|
||||
wamx_FindPubVar,
|
||||
amx_FindTagId,
|
||||
amx_Flags,
|
||||
amx_GetAddr,
|
||||
amx_GetPublic,
|
||||
amx_GetPubVar,
|
||||
wamx_GetString,
|
||||
amx_GetTag,
|
||||
amx_GetUserData,
|
||||
amx_Init,
|
||||
amx_InitJIT,
|
||||
amx_MemInfo,
|
||||
amx_NameLength,
|
||||
wamx_NativeInfo,
|
||||
amx_NumPublics,
|
||||
amx_NumPubVars,
|
||||
amx_NumTags,
|
||||
amx_RaiseError,
|
||||
amx_Register,
|
||||
amx_Release,
|
||||
amx_SetCallback,
|
||||
amx_SetDebugHook,
|
||||
wamx_SetString,
|
||||
amx_SetUserData,
|
||||
amx_StrLen,
|
||||
};
|
||||
|
||||
pfnmodule_engine_g engModuleFunc = {
|
||||
add_amxnatives,
|
||||
build_pathname,
|
||||
copy_amxmemory,
|
||||
format_amxstring,
|
||||
get_amxaddr,
|
||||
get_amxscript,
|
||||
get_amxscriptname,
|
||||
get_amxstring,
|
||||
get_modname,
|
||||
load_amxscript,
|
||||
print_srvconsole,
|
||||
report_error,
|
||||
set_amxnatives,
|
||||
set_amxstring,
|
||||
amxstring_len,
|
||||
unload_amxscript,
|
||||
alloc_amxmemory,
|
||||
free_amxmemory,
|
||||
};
|
||||
|
||||
// *****************************************************
|
||||
// class CModule
|
||||
// *****************************************************
|
||||
@ -150,8 +70,6 @@ void CModule::clear(bool clearFilename)
|
||||
if (clearFilename)
|
||||
m_Filename.assign("unknown");
|
||||
|
||||
// old
|
||||
m_InfoOld = NULL;
|
||||
// new
|
||||
m_Amxx = false;
|
||||
m_InfoNew.author = "unknown";
|
||||
@ -163,6 +81,26 @@ void CModule::clear(bool clearFilename)
|
||||
m_Natives.clear();
|
||||
}
|
||||
|
||||
bool CModule::attachMetamod(const char *mmfile, PLUG_LOADTIME now)
|
||||
{
|
||||
void **handle;
|
||||
void *dummy = NULL;
|
||||
|
||||
if (!m_Handle)
|
||||
handle = &dummy;
|
||||
else
|
||||
handle = (void **)&m_Handle;
|
||||
|
||||
int res = LoadMetamodPlugin(mmfile, handle, now);
|
||||
|
||||
if (!res)
|
||||
{
|
||||
m_Metamod = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CModule::attachModule()
|
||||
{
|
||||
// old & new
|
||||
@ -200,17 +138,11 @@ bool CModule::attachModule()
|
||||
m_Status = MODULE_BADLOAD;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
m_Status = MODULE_BADLOAD;
|
||||
}
|
||||
else
|
||||
{
|
||||
// old
|
||||
ATTACHMOD AttachFunc = (ATTACHMOD)DLPROC(m_Handle, "AMX_Attach");
|
||||
|
||||
if (AttachFunc)
|
||||
(*AttachFunc)(&engAmxFunc,&engModuleFunc);
|
||||
m_Status = MODULE_LOADED;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CModule::queryModule()
|
||||
@ -271,46 +203,11 @@ bool CModule::queryModule()
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// old interface not 64 bit compatible
|
||||
#if SMALL_CELL_SIZE == 64
|
||||
m_Status = MODULE_NOT64BIT;
|
||||
return false;
|
||||
#else
|
||||
// Try old interface
|
||||
QUERYMOD queryFunc_Old = (QUERYMOD)DLPROC(m_Handle,"AMX_Query"); // check what version
|
||||
if (!queryFunc_Old)
|
||||
{
|
||||
m_Status = MODULE_NOQUERY;
|
||||
m_Amxx = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
(*queryFunc_Old)(&m_InfoOld);
|
||||
|
||||
if (!m_InfoOld)
|
||||
{
|
||||
m_Status = MODULE_NOINFO;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_InfoOld->ivers != AMX_INTERFACE_VERSION)
|
||||
{
|
||||
m_Status = MODULE_OLD;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for attach
|
||||
if (!DLPROC(m_Handle, "AMX_Attach"))
|
||||
{
|
||||
m_Status = MODULE_NOATTACH;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_InfoOld->serial = (long int)this;
|
||||
m_Status = MODULE_QUERY;
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bool CModule::detachModule()
|
||||
@ -330,12 +227,12 @@ bool CModule::detachModule()
|
||||
g_ModuleCallReason = ModuleCall_NotCalled;
|
||||
}
|
||||
}
|
||||
else
|
||||
#ifndef FAKEMETA
|
||||
if (IsMetamod())
|
||||
{
|
||||
DETACHMOD detachFunc_Old = (DETACHMOD)DLPROC(m_Handle, "AMX_Detach");
|
||||
if (detachFunc_Old)
|
||||
(*detachFunc_Old)();
|
||||
UnloadMetamodPlugin(m_Handle);
|
||||
}
|
||||
#endif
|
||||
DLFREE(m_Handle);
|
||||
clear();
|
||||
return true;
|
||||
|
@ -57,6 +57,7 @@ struct amxx_module_info_s
|
||||
const char *author;
|
||||
const char *version;
|
||||
int reload; // reload on mapchange when nonzero
|
||||
const char *logtag; //added in version 2
|
||||
};
|
||||
|
||||
|
||||
@ -65,14 +66,13 @@ struct amxx_module_info_s
|
||||
#define AMXX_PARAM 2 /* Invalid parameter */
|
||||
#define AMXX_FUNC_NOT_PRESENT 3 /* Function not present */
|
||||
|
||||
#define AMXX_INTERFACE_VERSION 1
|
||||
#define AMXX_INTERFACE_VERSION 3
|
||||
|
||||
class CModule
|
||||
{
|
||||
String m_Filename; // Filename
|
||||
bool m_Metamod; // Using metamod?
|
||||
bool m_Amxx; // Using new module interface?
|
||||
module_info_s* m_InfoOld; // module info (old module interface)
|
||||
amxx_module_info_s m_InfoNew; // module info (new module interface)
|
||||
DLHANDLE m_Handle; // handle
|
||||
MODULE_STATUS m_Status; // status
|
||||
@ -87,26 +87,27 @@ public:
|
||||
bool attachModule();
|
||||
bool queryModule();
|
||||
bool detachModule();
|
||||
#ifndef FAKEMETA
|
||||
bool attachMetamod(const char *mmfile, PLUG_LOADTIME now);
|
||||
#endif
|
||||
const char* getStatus() const;
|
||||
inline const char* getType() const { return m_Amxx ? "amxx" : (m_Metamod ? "amx&mm" : "amx"); }
|
||||
inline const char* getAuthor() const { return m_Amxx ? (m_InfoNew.author) : (m_InfoOld ? m_InfoOld->author : "unknown"); }
|
||||
inline const char* getVersion() const { return m_Amxx ? (m_InfoNew.version) : (m_InfoOld ? m_InfoOld->version : "unknown"); }
|
||||
inline const char* getName() const { return m_Amxx ? (m_InfoNew.name) : (m_InfoOld ? m_InfoOld->name : "unknown"); }
|
||||
inline module_info_s* getInfo() const { return m_InfoOld; } // old
|
||||
inline const char* getAuthor() const { return m_InfoNew.author; }
|
||||
inline const char* getVersion() const { return m_InfoNew.version; }
|
||||
inline const char* getName() const { return m_InfoNew.name; }
|
||||
inline const amxx_module_info_s* getInfoNew() const { return &m_InfoNew; } // new
|
||||
inline int getStatusValue() { return m_Status; }
|
||||
inline bool operator==( const char* fname ) { return !strcmp( m_Filename.c_str() , fname ); }
|
||||
inline bool isReloadable() { return m_Amxx ? ((m_Status == MODULE_LOADED) && (m_InfoNew.reload != 0)) : ( (m_Status==MODULE_LOADED) && (m_InfoOld->type==RELOAD_MODULE)); }
|
||||
inline bool isReloadable() { return ((m_Status == MODULE_LOADED) && (m_InfoNew.reload != 0)); }
|
||||
inline bool isAmxx() const { return m_Amxx; }
|
||||
inline const char *getMissingFunc() const { return m_MissingFunc; }
|
||||
inline const char *getFilename() { return m_Filename.c_str(); }
|
||||
inline bool IsMetamod() { return m_Metamod; }
|
||||
void CModule::CallPluginsLoaded();
|
||||
|
||||
CList<AMX_NATIVE_INFO*> m_Natives;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -33,6 +33,10 @@
|
||||
#include "CPlugin.h"
|
||||
#include "CForward.h"
|
||||
#include "CFile.h"
|
||||
#include "amx.h"
|
||||
#include "natives.h"
|
||||
|
||||
extern const char *no_function;
|
||||
|
||||
CPluginMngr::CPlugin* CPluginMngr::loadPlugin(const char* path, const char* name, char* error, int debug) {
|
||||
CPlugin** a = &head;
|
||||
@ -48,9 +52,29 @@ void CPluginMngr::unloadPlugin( CPlugin** a ) {
|
||||
--pCounter;
|
||||
}
|
||||
|
||||
void CPluginMngr::Finalize()
|
||||
{
|
||||
if (m_Finalized)
|
||||
return;
|
||||
pNatives = BuildNativeTable();
|
||||
|
||||
CPlugin *a = head;
|
||||
while (a)
|
||||
{
|
||||
if (a->getStatusCode() == ps_running)
|
||||
{
|
||||
amx_Register(a->getAMX(), pNatives, -1);
|
||||
a->Finalize();
|
||||
}
|
||||
a=a->next;
|
||||
}
|
||||
m_Finalized = true;
|
||||
}
|
||||
|
||||
int CPluginMngr::loadPluginsFromFile( const char* filename )
|
||||
{
|
||||
FILE *fp = fopen(build_pathname("%s",filename) , "rt");
|
||||
char file[256];
|
||||
FILE *fp = fopen(build_pathname_r(file, sizeof(file)-1, "%s",filename) , "rt");
|
||||
|
||||
if ( !fp )
|
||||
{
|
||||
@ -67,8 +91,8 @@ int CPluginMngr::loadPluginsFromFile( const char* filename )
|
||||
|
||||
while ( !feof(fp) )
|
||||
{
|
||||
*pluginName = 0;
|
||||
*debug = 0;
|
||||
pluginName[0] = '\0';
|
||||
debug[0] = '\0';
|
||||
debugFlag = 0;
|
||||
line.clear();
|
||||
line._fread(fp);
|
||||
@ -100,6 +124,12 @@ void CPluginMngr::clear() {
|
||||
CPlugin**a = &head;
|
||||
while ( *a )
|
||||
unloadPlugin(a);
|
||||
m_Finalized = false;
|
||||
if (pNatives)
|
||||
{
|
||||
delete [] pNatives;
|
||||
pNatives = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
CPluginMngr::CPlugin* CPluginMngr::findPluginFast(AMX *amx)
|
||||
@ -135,7 +165,7 @@ const char* CPluginMngr::CPlugin::getStatus() const {
|
||||
switch(status){
|
||||
case ps_running:
|
||||
{
|
||||
if (getAMX()->flags & AMX_FLAG_DEBUG)
|
||||
if (m_Debug)
|
||||
{
|
||||
return "debug";
|
||||
} else {
|
||||
@ -156,8 +186,10 @@ CPluginMngr::CPlugin::CPlugin(int i, const char* p,const char* n, char* e, int d
|
||||
title.assign(unk);
|
||||
author.assign(unk);
|
||||
version.assign(unk);
|
||||
char* path = build_pathname("%s/%s",p,n);
|
||||
char file[256];
|
||||
char* path = build_pathname_r(file, sizeof(file)-1, "%s/%s",p,n);
|
||||
code = 0;
|
||||
memset(&amx, 0, sizeof(AMX));
|
||||
int err = load_amxscript(&amx,&code,path,e, d);
|
||||
if ( err == AMX_ERR_NONE )
|
||||
{
|
||||
@ -169,11 +201,49 @@ CPluginMngr::CPlugin::CPlugin(int i, const char* p,const char* n, char* e, int d
|
||||
paused_fun = 0;
|
||||
next = 0;
|
||||
id = i;
|
||||
if (status == ps_running)
|
||||
{
|
||||
m_PauseFwd = registerSPForwardByName(&amx, "plugin_pause");
|
||||
m_UnpauseFwd = registerSPForwardByName(&amx, "plugin_unpause");
|
||||
if (amx.flags & AMX_FLAG_DEBUG)
|
||||
{
|
||||
m_Debug = true;
|
||||
} else {
|
||||
m_Debug = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
CPluginMngr::CPlugin::~CPlugin( ){
|
||||
|
||||
CPluginMngr::CPlugin::~CPlugin( )
|
||||
{
|
||||
unload_amxscript( &amx, &code );
|
||||
}
|
||||
|
||||
void CPluginMngr::CPlugin::Finalize()
|
||||
{
|
||||
char buffer[128];
|
||||
|
||||
int old_status = status;
|
||||
if (CheckModules(&amx, buffer))
|
||||
{
|
||||
if ( amx_Register(&amx, core_Natives, -1) != AMX_ERR_NONE )
|
||||
{
|
||||
status = ps_bad_load;
|
||||
sprintf(buffer, "Plugin uses an unknown function (name \"%s\") - check your modules.ini.", no_function);
|
||||
errorMsg.assign(buffer);
|
||||
amx.error = AMX_ERR_NOTFOUND;
|
||||
}
|
||||
} else {
|
||||
status = ps_bad_load;
|
||||
errorMsg.assign(buffer);
|
||||
amx.error = AMX_ERR_NOTFOUND;
|
||||
}
|
||||
if (old_status != status)
|
||||
{
|
||||
AMXXLOG_Log("[AMXX] Plugin \"%s\" failed to load: %s", name.c_str(), errorMsg.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CPluginMngr::CPlugin::pauseFunction( int id ) {
|
||||
if (isValid()){
|
||||
paused_fun |= (1<<id);
|
||||
@ -199,16 +269,8 @@ void CPluginMngr::CPlugin::pausePlugin()
|
||||
if (isValid())
|
||||
{
|
||||
// call plugin_pause if provided
|
||||
int func;
|
||||
cell retval;
|
||||
if (amx_FindPublic(&amx, "plugin_pause", &func) == AMX_ERR_NONE)
|
||||
{
|
||||
if (isExecutable(func))
|
||||
{
|
||||
|
||||
amx_Exec(&amx, &retval, func, 0);
|
||||
}
|
||||
}
|
||||
if (m_PauseFwd != -1)
|
||||
executeForwards(m_PauseFwd);
|
||||
|
||||
setStatus(ps_paused);
|
||||
}
|
||||
@ -223,14 +285,7 @@ void CPluginMngr::CPlugin::unpausePlugin()
|
||||
|
||||
setStatus(ps_running);
|
||||
// call plugin_unpause if provided
|
||||
int func;
|
||||
cell retval;
|
||||
if (amx_FindPublic(&amx, "plugin_unpause", &func) == AMX_ERR_NONE)
|
||||
{
|
||||
if (isExecutable(func))
|
||||
{
|
||||
amx_Exec(&amx, &retval, func, 0);
|
||||
}
|
||||
}
|
||||
if (m_UnpauseFwd != -1)
|
||||
executeForwards(m_UnpauseFwd);
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ enum {
|
||||
ps_paused,
|
||||
ps_running,
|
||||
ps_stopped,
|
||||
ps_locked
|
||||
ps_locked,
|
||||
};
|
||||
|
||||
class CPluginMngr
|
||||
@ -64,12 +64,15 @@ public:
|
||||
String title;
|
||||
String author;
|
||||
String errorMsg;
|
||||
int m_PauseFwd;
|
||||
int m_UnpauseFwd;
|
||||
int paused_fun;
|
||||
int status;
|
||||
CPlugin* next;
|
||||
int id;
|
||||
CPlugin(int i , const char* p,const char* n, char* e, int d);
|
||||
~CPlugin( );
|
||||
bool m_Debug;
|
||||
|
||||
public:
|
||||
|
||||
@ -86,16 +89,18 @@ public:
|
||||
inline void setAuthor( const char* n ) { author.assign(n); }
|
||||
inline void setVersion( const char* n ) { version.assign(n); }
|
||||
inline void setError( const char* n ) { errorMsg.assign(n); }
|
||||
inline bool isValid() const { return ((status != ps_bad_load) && (status != ps_locked)); }
|
||||
inline bool isPaused() const { return ( (status == ps_paused) || (status == ps_stopped)); }
|
||||
inline bool isFunctionPaused( int id ) const { return (paused_fun & (1<<id)) ? true : false; }
|
||||
inline bool isExecutable(int id) const { return (isValid() && !isPaused() && !isFunctionPaused(id)); }
|
||||
inline bool isValid() const { return ((status == ps_running) && (status != ps_locked)); }
|
||||
inline bool isPaused() const { return ( (status == ps_paused) ); }
|
||||
//inline bool isFunctionPaused( int id ) const { return (paused_fun & (1<<id)) ? true : false; }
|
||||
inline bool isExecutable(int id) const { return (isValid() && !isPaused()); }
|
||||
void Finalize();
|
||||
void pausePlugin();
|
||||
void unpausePlugin();
|
||||
void pauseFunction( int id );
|
||||
void unpauseFunction( int id );
|
||||
void setStatus( int a );
|
||||
const char* getStatus() const;
|
||||
inline bool isDebug() const { return m_Debug; }
|
||||
};
|
||||
|
||||
private:
|
||||
@ -104,9 +109,12 @@ private:
|
||||
|
||||
|
||||
public:
|
||||
CPluginMngr() { head = 0; pCounter = 0; }
|
||||
CPluginMngr() { head = 0; pCounter = 0; pNatives = NULL; m_Finalized=false;}
|
||||
~CPluginMngr() { clear(); }
|
||||
|
||||
bool m_Finalized;
|
||||
AMX_NATIVE_INFO *pNatives;
|
||||
|
||||
// Interface
|
||||
|
||||
CPlugin* loadPlugin(const char* path, const char* name, char* error, int debug);
|
||||
@ -117,6 +125,7 @@ public:
|
||||
CPlugin* findPlugin(int index);
|
||||
CPlugin* findPlugin(const char* name);
|
||||
inline int getPluginsNum() const { return pCounter; }
|
||||
void Finalize();
|
||||
void clear();
|
||||
|
||||
class iterator {
|
||||
|
101
amxmodx/CStack.h
Executable file
101
amxmodx/CStack.h
Executable file
@ -0,0 +1,101 @@
|
||||
/* AMX Mod X
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
* originally developed by OLO
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
//by David "BAILOPAN" Anderson
|
||||
#ifndef _INCLUDE_CSTACK_H
|
||||
#define _INCLUDE_CSTACK_H
|
||||
|
||||
template <class T>
|
||||
class CStack
|
||||
{
|
||||
public:
|
||||
struct CStackItem
|
||||
{
|
||||
public:
|
||||
T item;
|
||||
CStackItem *prev;
|
||||
};
|
||||
public:
|
||||
CStack()
|
||||
{
|
||||
mSize = 0;
|
||||
mStack = NULL;
|
||||
}
|
||||
~CStack()
|
||||
{
|
||||
CStackItem *p, *t;
|
||||
p = mStack;
|
||||
while (p)
|
||||
{
|
||||
t = p->prev;
|
||||
delete p;
|
||||
p = t;
|
||||
}
|
||||
mStack = NULL;
|
||||
}
|
||||
bool empty()
|
||||
{
|
||||
return (mSize==0);
|
||||
}
|
||||
|
||||
void push(const T & v)
|
||||
{
|
||||
CStackItem *p = new CStackItem;
|
||||
p->item = v;
|
||||
p->prev = mStack;
|
||||
mStack = p;
|
||||
mSize++;
|
||||
}
|
||||
|
||||
void pop()
|
||||
{
|
||||
CStackItem *p = mStack;
|
||||
mStack = p->prev;
|
||||
delete p;
|
||||
mSize--;
|
||||
}
|
||||
|
||||
T & top()
|
||||
{
|
||||
return mStack->item;
|
||||
}
|
||||
|
||||
size_t size()
|
||||
{
|
||||
return mSize;
|
||||
}
|
||||
private:
|
||||
CStackItem *mStack;
|
||||
size_t mSize;
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_CQUEUE_H
|
||||
|
@ -32,6 +32,9 @@
|
||||
#ifndef _INCLUDE_CSTRING_H
|
||||
#define _INCLUDE_CSTRING_H
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
//by David "BAILOPAN" Anderson
|
||||
class String
|
||||
{
|
||||
@ -39,10 +42,8 @@ public:
|
||||
String()
|
||||
{
|
||||
v = NULL;
|
||||
mSize = 0;
|
||||
cSize = 0;
|
||||
Grow(2);
|
||||
assign("");
|
||||
a_size = 0;
|
||||
//assign("");
|
||||
}
|
||||
|
||||
~String()
|
||||
@ -54,41 +55,45 @@ public:
|
||||
String(const char *src)
|
||||
{
|
||||
v = NULL;
|
||||
mSize = 0;
|
||||
cSize = 0; assign(src);
|
||||
a_size = 0;
|
||||
assign(src);
|
||||
}
|
||||
|
||||
const char * _fread(FILE *fp)
|
||||
{
|
||||
Grow(512, false);
|
||||
char *ret = fgets(v, 511, fp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
String(String &src)
|
||||
{
|
||||
v = NULL;
|
||||
mSize = 0;
|
||||
cSize = 0;
|
||||
a_size = 0;
|
||||
assign(src.c_str());
|
||||
}
|
||||
|
||||
const char *c_str() { return v?v:""; }
|
||||
|
||||
const char *c_str() const { return v?v:""; }
|
||||
|
||||
void append(const char *t)
|
||||
{
|
||||
Grow(cSize + strlen(t) + 1);
|
||||
Grow(size() + strlen(t) + 1);
|
||||
strcat(v, t);
|
||||
cSize = strlen(v);
|
||||
}
|
||||
|
||||
void append(const char c)
|
||||
{
|
||||
Grow(cSize + 2);
|
||||
v[cSize] = c;
|
||||
v[++cSize] = 0;
|
||||
size_t len = size();
|
||||
Grow(len + 2);
|
||||
v[len] = c;
|
||||
v[len + 1] = '\0';
|
||||
}
|
||||
|
||||
void append(String &d)
|
||||
{
|
||||
const char *t = d.c_str();
|
||||
Grow(cSize + strlen(t));
|
||||
strcat(v, t);
|
||||
cSize = strlen(v);
|
||||
append(d.c_str());
|
||||
}
|
||||
|
||||
void assign(const String &src)
|
||||
@ -100,79 +105,56 @@ public:
|
||||
{
|
||||
if (!d)
|
||||
{
|
||||
Grow(1);
|
||||
cSize = 0;
|
||||
strcpy(v, "");
|
||||
return;
|
||||
}
|
||||
Grow(strlen(d));
|
||||
if (v)
|
||||
{
|
||||
strcpy(v, d);
|
||||
cSize = strlen(v);
|
||||
clear();
|
||||
} else {
|
||||
cSize = 0;
|
||||
Grow(strlen(d) + 1, false);
|
||||
strcpy(v, d);
|
||||
}
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
if (v)
|
||||
{
|
||||
v[0] = 0;
|
||||
cSize = 0;
|
||||
}
|
||||
v[0] = '\0';
|
||||
}
|
||||
|
||||
int compare (const char *d)
|
||||
{
|
||||
if (v) {
|
||||
if (d) {
|
||||
if (!v)
|
||||
return strcmp("", d);
|
||||
else
|
||||
return strcmp(v, d);
|
||||
} else {
|
||||
return strlen(v);
|
||||
}
|
||||
} else {
|
||||
if (d) {
|
||||
return strlen(d);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Added this for amxx inclusion
|
||||
bool empty()
|
||||
{
|
||||
if (!v || !cSize)
|
||||
if (!v)
|
||||
return true;
|
||||
|
||||
if (v[0] == '\0')
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int size()
|
||||
size_t size()
|
||||
{
|
||||
if (!v)
|
||||
if (v)
|
||||
return strlen(v);
|
||||
else
|
||||
return 0;
|
||||
return cSize;
|
||||
}
|
||||
|
||||
const char * _fread(FILE *fp)
|
||||
{
|
||||
Grow(512);
|
||||
char * ret = fgets(v, 511, fp);
|
||||
cSize = strlen(v);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int find(const char c, int index = 0)
|
||||
{
|
||||
if (!v)
|
||||
size_t len = size();
|
||||
if (len < 1)
|
||||
return npos;
|
||||
if (index >= (int)cSize || index < 0)
|
||||
if (index >= (int)len || index < 0)
|
||||
return npos;
|
||||
unsigned int i = 0;
|
||||
for (i=index; i<cSize; i++)
|
||||
for (i=index; i<(int)len; i++)
|
||||
{
|
||||
if (v[i] == c)
|
||||
{
|
||||
@ -199,10 +181,12 @@ public:
|
||||
{
|
||||
if (!v)
|
||||
return;
|
||||
|
||||
unsigned int i = 0;
|
||||
unsigned int j = 0;
|
||||
size_t len = strlen(v);
|
||||
|
||||
if (cSize == 1)
|
||||
if (len == 1)
|
||||
{
|
||||
if (is_space(v[i]))
|
||||
{
|
||||
@ -215,9 +199,9 @@ public:
|
||||
|
||||
if (is_space(c0))
|
||||
{
|
||||
for (i=0; i<cSize; i++)
|
||||
for (i=0; i<len; i++)
|
||||
{
|
||||
if (!is_space(v[i]) || (is_space(v[i]) && ((unsigned char)i==cSize-1)))
|
||||
if (!is_space(v[i]) || (is_space(v[i]) && ((unsigned char)i==len-1)))
|
||||
{
|
||||
erase(0, i);
|
||||
break;
|
||||
@ -225,16 +209,16 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
cSize = strlen(v);
|
||||
len = strlen(v);
|
||||
|
||||
if (cSize < 1)
|
||||
if (len < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_space(v[cSize-1]))
|
||||
if (is_space(v[len-1]))
|
||||
{
|
||||
for (i=cSize-1; i>=0; i--)
|
||||
for (i=len-1; i>=0; i--)
|
||||
{
|
||||
if (!is_space(v[i])
|
||||
|| (is_space(v[i]) && i==0))
|
||||
@ -246,7 +230,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
if (cSize == 1)
|
||||
if (len == 1)
|
||||
{
|
||||
if (is_space(v[0]))
|
||||
{
|
||||
@ -256,21 +240,22 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
String & erase(unsigned int start, int num = npos)
|
||||
void erase(unsigned int start, int num = npos)
|
||||
{
|
||||
if (!v)
|
||||
return (*this);
|
||||
return;
|
||||
unsigned int i = 0;
|
||||
size_t len = size();
|
||||
//check for bounds
|
||||
if (num == npos || start+num > cSize-num+1)
|
||||
num = cSize - start;
|
||||
if (num == npos || start+num > len-num+1)
|
||||
num = len - start;
|
||||
//do the erasing
|
||||
bool copyflag = false;
|
||||
for (i=0; i<cSize; i++)
|
||||
for (i=0; i<len; i++)
|
||||
{
|
||||
if (i>=start && i<start+num)
|
||||
{
|
||||
if (i+num < cSize)
|
||||
if (i+num < len)
|
||||
{
|
||||
v[i] = v[i+num];
|
||||
} else {
|
||||
@ -278,7 +263,7 @@ public:
|
||||
}
|
||||
copyflag = true;
|
||||
} else if (copyflag) {
|
||||
if (i+num < cSize)
|
||||
if (i+num < len)
|
||||
{
|
||||
v[i] = v[i+num];
|
||||
} else {
|
||||
@ -286,38 +271,39 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
cSize -= num;
|
||||
v[cSize] = 0;
|
||||
|
||||
return (*this);
|
||||
len -= num;
|
||||
v[len] = 0;
|
||||
}
|
||||
|
||||
String substr(unsigned int index, int num = npos)
|
||||
{
|
||||
if (!v)
|
||||
{
|
||||
String b("");
|
||||
return b;
|
||||
}
|
||||
|
||||
String ns;
|
||||
|
||||
if (index >= cSize || !v)
|
||||
size_t len = size();
|
||||
|
||||
if (index >= len || !v)
|
||||
return ns;
|
||||
|
||||
if (num == npos)
|
||||
{
|
||||
num = cSize - index;
|
||||
} else if (index+num >= cSize) {
|
||||
num = cSize - index;
|
||||
num = len - index;
|
||||
} else if (index+num >= len) {
|
||||
num = len - index;
|
||||
}
|
||||
|
||||
unsigned int i = 0, j=0;
|
||||
char *s = new char[cSize+1];
|
||||
unsigned int nslen = num + 2;
|
||||
|
||||
ns.Grow(nslen);
|
||||
|
||||
for (i=index; i<index+num; i++)
|
||||
{
|
||||
s[j++] = v[i];
|
||||
}
|
||||
s[j] = 0;
|
||||
|
||||
ns.assign(s);
|
||||
|
||||
delete [] s;
|
||||
ns.append(v[i]);
|
||||
|
||||
return ns;
|
||||
}
|
||||
@ -327,10 +313,11 @@ public:
|
||||
if (!v)
|
||||
return;
|
||||
unsigned int i = 0;
|
||||
for (i=0; i<cSize; i++)
|
||||
size_t len = strlen(v);
|
||||
for (i=0; i<len; i++)
|
||||
{
|
||||
if (v[i] >= 65 && v[i] <= 90)
|
||||
v[i] |= 32;
|
||||
v[i] &= ~(1<<5);
|
||||
}
|
||||
}
|
||||
|
||||
@ -349,7 +336,7 @@ public:
|
||||
|
||||
char operator [] (unsigned int index)
|
||||
{
|
||||
if (index > cSize)
|
||||
if (index > size() || !v)
|
||||
{
|
||||
return -1;
|
||||
} else {
|
||||
@ -359,7 +346,7 @@ public:
|
||||
|
||||
int at(int a)
|
||||
{
|
||||
if (a < 0 || a >= (int)cSize)
|
||||
if (a < 0 || a >= (int)size() || !v)
|
||||
return -1;
|
||||
|
||||
return v[a];
|
||||
@ -367,7 +354,7 @@ public:
|
||||
|
||||
bool at(int at, char c)
|
||||
{
|
||||
if (at < 0 || at >= (int)cSize)
|
||||
if (at < 0 || at >= (int)size() || !v)
|
||||
return false;
|
||||
|
||||
v[at] = c;
|
||||
@ -376,27 +363,23 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
void Grow(unsigned int d)
|
||||
void Grow(unsigned int d, bool copy=true)
|
||||
{
|
||||
if (d<1)
|
||||
if (d <= a_size)
|
||||
return;
|
||||
if (d > mSize)
|
||||
{
|
||||
mSize = d + 16; // allocate a buffer
|
||||
char *t = new char[d+1];
|
||||
if (v) {
|
||||
strcpy(t, v);
|
||||
t[cSize] = 0;
|
||||
char *n = new char[d + 1];
|
||||
if (copy && v)
|
||||
strcpy(n, v);
|
||||
if (v)
|
||||
delete [] v;
|
||||
}
|
||||
v = t;
|
||||
mSize = d;
|
||||
}
|
||||
else
|
||||
strcpy(n, "");
|
||||
v = n;
|
||||
a_size = d + 1;
|
||||
}
|
||||
|
||||
char *v;
|
||||
unsigned int mSize;
|
||||
unsigned int cSize;
|
||||
unsigned int a_size;
|
||||
public:
|
||||
static const int npos = -1;
|
||||
};
|
||||
|
@ -45,6 +45,7 @@ CPluginMngr::CPlugin *CTaskMngr::CTask::getPlugin() const
|
||||
|
||||
void CTaskMngr::CTask::set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, int iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat, float fCurrentTime)
|
||||
{
|
||||
clear();
|
||||
m_bFree = false;
|
||||
|
||||
m_pPlugin = pPlugin;
|
||||
@ -73,17 +74,30 @@ void CTaskMngr::CTask::set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags,
|
||||
|
||||
void CTaskMngr::CTask::clear()
|
||||
{
|
||||
m_bFree = true;
|
||||
|
||||
if (m_iFunc >= 0)
|
||||
{
|
||||
unregisterSPForward(m_iFunc);
|
||||
m_iFunc = -1;
|
||||
}
|
||||
m_bFree = true;
|
||||
|
||||
if (m_pParams)
|
||||
{
|
||||
delete [] m_pParams;
|
||||
m_pParams = NULL;
|
||||
}
|
||||
|
||||
m_pPlugin = NULL;
|
||||
m_iId = 0;
|
||||
m_fBase = 0.0f;
|
||||
|
||||
m_iRepeat = 0;
|
||||
m_bLoop = false;
|
||||
m_bAfterStart = false;
|
||||
m_bBeforeEnd = false;
|
||||
|
||||
m_fNextExecTime = 0.0f;
|
||||
}
|
||||
|
||||
bool CTaskMngr::CTask::isFree() const
|
||||
@ -131,15 +145,13 @@ void CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, f
|
||||
return;
|
||||
|
||||
// set new exec time OR remove the task if needed
|
||||
if (m_bLoop || (--m_iRepeat > 0))
|
||||
if (m_bLoop || (m_iRepeat-- > 0))
|
||||
{
|
||||
m_fNextExecTime += m_fBase;
|
||||
}
|
||||
else
|
||||
{
|
||||
unregisterSPForward(m_iFunc);
|
||||
m_iFunc = -1;
|
||||
m_bFree = true;
|
||||
clear(); // hamster
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -147,6 +159,21 @@ void CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, f
|
||||
CTaskMngr::CTask::CTask()
|
||||
{
|
||||
m_bFree = true;
|
||||
|
||||
m_pPlugin = NULL;
|
||||
m_iFunc = -1;
|
||||
m_iId = 0;
|
||||
m_fBase = 0.0f;
|
||||
|
||||
m_iRepeat = 0;
|
||||
m_bLoop = false;
|
||||
m_bAfterStart = false;
|
||||
m_bBeforeEnd = false;
|
||||
|
||||
m_fNextExecTime = 0.0f;
|
||||
|
||||
m_iParamLen = 0;
|
||||
m_pParams = NULL;
|
||||
}
|
||||
|
||||
CTaskMngr::CTask::~CTask()
|
||||
@ -162,6 +189,11 @@ CTaskMngr::CTaskMngr()
|
||||
m_pTmr_TimeLeft = NULL;
|
||||
}
|
||||
|
||||
CTaskMngr::~CTaskMngr()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void CTaskMngr::registerTimers(float *pCurrentTime, float *pTimeLimit, float *pTimeLeft)
|
||||
{
|
||||
m_pTmr_CurrentTime = pCurrentTime;
|
||||
|
@ -106,6 +106,7 @@ private:
|
||||
float *m_pTmr_TimeLeft;
|
||||
public:
|
||||
CTaskMngr();
|
||||
~CTaskMngr();
|
||||
|
||||
void registerTimers(float *pCurrentTime, float *pTimeLimit, float *pTimeLeft); // The timers will always point to the right value
|
||||
void registerTask(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, int iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat);
|
||||
|
@ -48,7 +48,8 @@ template <class T> class CVector
|
||||
return false;
|
||||
if (m_Data)
|
||||
{
|
||||
memcpy(newData, m_Data, m_Size * sizeof(T));
|
||||
for (size_t i=0; i<m_CurrentUsedSize; i++)
|
||||
newData[i] = m_Data[i];
|
||||
delete [] m_Data;
|
||||
}
|
||||
m_Data = newData;
|
||||
@ -74,7 +75,9 @@ template <class T> class CVector
|
||||
return false;
|
||||
if (m_Data)
|
||||
{
|
||||
memcpy(newData, m_Data, (m_Size < size) ? (m_Size * sizeof(T)) : (size * sizeof(T)));
|
||||
size_t end = (m_Size < size) ? (m_Size) : size;
|
||||
for (size_t i=0; i<end; i++)
|
||||
newData[i] = m_Data[i];
|
||||
delete [] m_Data;
|
||||
}
|
||||
if (m_Size < size)
|
||||
@ -251,10 +254,11 @@ public:
|
||||
CVector<T>(const CVector<T> & other)
|
||||
{
|
||||
// copy data
|
||||
m_Data = new T [other.m_Size];
|
||||
m_Size = other.m_Size;
|
||||
m_Data = new T [other.m_CurrentUsedSize];
|
||||
m_Size = other.m_CurrentUsedSize;
|
||||
m_CurrentUsedSize = other.m_CurrentUsedSize;
|
||||
memcpy(m_Data, other.m_Data, m_CurrentUsedSize * sizeof(T));
|
||||
for (size_t i=0; i<other.m_CurrentUsedSize; i++)
|
||||
m_Data[i] = other.m_Data[i];
|
||||
}
|
||||
|
||||
~CVector<T>()
|
||||
|
BIN
amxmodx/JIT/amxexecn.o
Executable file
BIN
amxmodx/JIT/amxexecn.o
Executable file
Binary file not shown.
BIN
amxmodx/JIT/amxexecn.obj
Executable file
BIN
amxmodx/JIT/amxexecn.obj
Executable file
Binary file not shown.
BIN
amxmodx/JIT/amxjitsn.o
Executable file
BIN
amxmodx/JIT/amxjitsn.o
Executable file
Binary file not shown.
BIN
amxmodx/JIT/amxjitsn.obj
Executable file
BIN
amxmodx/JIT/amxjitsn.obj
Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
amxmodx/JIT/natives-amd64.o
Executable file
BIN
amxmodx/JIT/natives-amd64.o
Executable file
Binary file not shown.
BIN
amxmodx/JIT/natives-x86.o
Executable file
BIN
amxmodx/JIT/natives-x86.o
Executable file
Binary file not shown.
BIN
amxmodx/JIT/natives-x86.obj
Executable file
BIN
amxmodx/JIT/natives-x86.obj
Executable file
Binary file not shown.
160
amxmodx/Makefile
160
amxmodx/Makefile
@ -1,123 +1,95 @@
|
||||
MODNAME = amxx_mm
|
||||
SRCFILES = meta_api.cpp CFile.cpp CString.cpp CVault.cpp vault.cpp\
|
||||
float.cpp file.cpp modules.cpp CMisc.cpp CTask.cpp string.cpp\
|
||||
amxmodx.cpp CEvent.cpp CCmd.cpp CLogEvent.cpp srvcmd.cpp strptime.cpp\
|
||||
CForward.cpp CPlugin.cpp CModule.cpp CMenu.cpp emsg.cpp util.cpp \
|
||||
amxcore.cpp amxtime.cpp power.cpp amxxlog.cpp fakemeta.cpp mmgr/mmgr.cpp \
|
||||
amxxfile.cpp CLang.cpp md5.cpp amx.cpp
|
||||
#use this for amd64, remove the above amx.cpp, and rename amx.cpp to amx.c
|
||||
#CSRCFILES = amx.c minilzo/minilzo.c
|
||||
CSRCFILES = minilzo/minilzo.c
|
||||
#(C)2004-2005 AMX Mod X Development Team
|
||||
# Makefile written by David "BAILOPAN" Anderson
|
||||
|
||||
EXTRA_LIBS_LINUX =
|
||||
EXTRA_LIBS_WIN32 =
|
||||
EXTRA_LIBDIRS_LINUX = -Lextra/lib_linux
|
||||
EXTRA_LIBDIRS_WIN32 = -Lextra/lib_win32
|
||||
HLSDK = ../hlsdk/SourceCode
|
||||
MM_ROOT = ../metamod/metamod
|
||||
|
||||
EXTRA_INCLUDEDIRS = -Iextra/include
|
||||
### EDIT BELOW FOR OTHER PROJECTS ###
|
||||
|
||||
EXTRA_FLAGS = -Dstrcmpi=strcasecmp
|
||||
OPT_FLAGS = -O3 -fno-rtti -funroll-loops -s -pipe
|
||||
DEBUG_FLAGS = -g -ggdb3
|
||||
CPP = gcc
|
||||
NAME = amxmodx_mm
|
||||
|
||||
SDKTOP=../hlsdk
|
||||
METADIR=../metamod/metamod
|
||||
OBJECTS = meta_api.cpp CFile.cpp CVault.cpp vault.cpp float.cpp file.cpp modules.cpp \
|
||||
CMisc.cpp CTask.cpp string.cpp amxmodx.cpp CEvent.cpp CCmd.cpp CLogEvent.cpp \
|
||||
srvcmd.cpp strptime.cpp amxcore.cpp amxtime.cpp power.cpp amxxlog.cpp fakemeta.cpp \
|
||||
amxxfile.cpp CLang.cpp md5.cpp emsg.cpp CForward.cpp CPlugin.cpp CModule.cpp \
|
||||
CMenu.cpp util.cpp amx.cpp amxdbg.cpp natives.cpp newmenus.cpp \
|
||||
|
||||
LINK = -lz
|
||||
|
||||
SDKSRC=$(SDKTOP)/SourceCode
|
||||
OBJDIR_LINUX=obj.linux
|
||||
OBJDIR_WIN32=obj.win32
|
||||
SRCDIR=.
|
||||
INCLUDE = -I. -I$(HLSDK) -I$(HLSDK)/dlls -I$(HLSDK)/engine -I$(HLSDK)/game_shared -I$(HLSDK)/game_shared \
|
||||
-I$(MM_ROOT) -Lzlib -I$(HLSDK)/common
|
||||
|
||||
ifdef windir
|
||||
OS=WIN32
|
||||
ifeq "$(DEBUG)" "true"
|
||||
BIN_DIR = Debug
|
||||
CFLAGS = $(DEBUG_FLAGS)
|
||||
else
|
||||
OS=LINUX
|
||||
BIN_DIR = Release
|
||||
CFLAGS = $(OPT_FLAGS)
|
||||
endif
|
||||
|
||||
CC_LINUX=gcc
|
||||
ifeq "$(OS)" "WIN32"
|
||||
CC_WIN32=gcc
|
||||
LD_WINDLL=dllwrap
|
||||
DEFAULT=win32
|
||||
CLEAN=clean_win32
|
||||
else
|
||||
CC_WIN32=/usr/local/cross-tools/i386-mingw32msvc/bin/gcc
|
||||
LD_WINDLL=/usr/local/cross-tools/bin/i386-mingw32msvc-dllwrap
|
||||
DEFAULT=linux win32
|
||||
CLEAN=clean_both
|
||||
ifeq "$(MMGR)" "true"
|
||||
OBJECTS += MMGR/MMGR.CPP
|
||||
endif
|
||||
|
||||
CFLAGS += -DLINUX -DNDEBUG -fPIC -Wno-deprecated -fno-exceptions -DHAVE_STDINT_H
|
||||
|
||||
#use this for AMD64
|
||||
#LIBFILE_LINUX = $(MODNAME)_amd64.so
|
||||
LIBFILE_LINUX = $(MODNAME)_i386.so
|
||||
LIBFILE_WIN32 = $(MODNAME).dll
|
||||
TARGET_LINUX = $(OBJDIR_LINUX)/$(LIBFILE_LINUX)
|
||||
TARGET_WIN32 = $(OBJDIR_WIN32)/$(LIBFILE_WIN32)
|
||||
|
||||
FILES_ALL = *.cpp *.h [A-Z]* *.rc
|
||||
ifeq "$(OS)" "LINUX"
|
||||
ASRCFILES := $(shell ls -t $(SRCFILES))
|
||||
ifeq "$(AMD64)" "true"
|
||||
BINARY = $(NAME)_amd64.so
|
||||
CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64 -m64
|
||||
OBJECTS += JIT/natives-amd64.o
|
||||
LINK += -lstdc++
|
||||
else
|
||||
ASRCFILES := $(shell dir /b)
|
||||
BINARY = $(NAME)_i386.so
|
||||
OBJECTS += JIT/amxexecn.o JIT/amxjitsn.o JIT/natives-x86.o
|
||||
CFLAGS += -DPAWN_CELL_SIZE=32 -DJIT -DASM32
|
||||
OPT_FLAGS += -march=i686
|
||||
endif
|
||||
OBJ_LINUX := $(SRCFILES:%.cpp=$(OBJDIR_LINUX)/%.o)
|
||||
OBJC_LINUX := $(CSRCFILES:%.c=$(OBJDIR_LINUX)/%.o)
|
||||
OBJ_WIN32 := $(SRCFILES:%.cpp=$(OBJDIR_WIN32)/%.o)
|
||||
OBJC_WIN32 := $(CSRCFILES:%.c=$(OBJDIR_WIN32)/%.o)
|
||||
|
||||
#use this for amd64
|
||||
#CCOPT = -m64 -g -ggdb3 -DHAVE_I64 -DSMALL_CELL_SIZE=64
|
||||
CCOPT = -march=i386 -s -DNDEBUG -O2 -fomit-frame-pointer -fno-exceptions -fno-rtti -ffast math
|
||||
OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o)
|
||||
|
||||
INCLUDEDIRS=-I../curl/include -I$(SRCDIR) -I$(METADIR) -I$(SDKSRC)/engine -I$(SDKSRC)/common -I$(SDKSRC)/pm_shared -I$(SDKSRC)/dlls -I$(SDKSRC) $(EXTRA_INCLUDEDIRS)
|
||||
CFLAGS=-Wall -Wno-unknown-pragmas
|
||||
ODEF = -DOPT_TYPE=\"optimized\"
|
||||
CFLAGS:=$(CCOPT) $(CFLAGS) $(ODEF) $(EXTRA_FLAGS)
|
||||
$(BIN_DIR)/%.o: %.cpp
|
||||
$(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
DO_CC_LINUX=$(CC_LINUX) $(CFLAGS) -fPIC $(INCLUDEDIRS) -o $@ -c $<
|
||||
DO_CC_WIN32=$(CC_WIN32) $(CFLAGS) $(INCLUDEDIRS) -o $@ -c $<
|
||||
LINK_LINUX=$(CC_LINUX) $(CFLAGS) -shared -ldl -lm $(OBJ_LINUX) $(OBJC_LINUX) $(EXTRA_LIBDIRS_LINUX) $(EXTRA_LIBS_LINUX) -o $@
|
||||
LINK_WIN32=$(LD_WINDLL) -mwindows --def $(MODNAME).def --add-stdcall-alias $(OBJ_WIN32) $(OBJC_WIN32) $(EXTRA_LIBDIRS_WIN32) $(EXTRA_LIBS_WIN32) -o $@
|
||||
all:
|
||||
mkdir -p $(BIN_DIR)
|
||||
$(MAKE) amxmodx
|
||||
|
||||
$(OBJDIR_LINUX)/%.o: $(SRCDIR)/%.c
|
||||
$(DO_CC_LINUX)
|
||||
amd64:
|
||||
rm -f zlib/libz.a
|
||||
$(MAKE) all AMD64=true
|
||||
|
||||
$(OBJDIR_LINUX)/%.o: $(SRCDIR)/%.cpp
|
||||
$(DO_CC_LINUX)
|
||||
amd64_mmgr:
|
||||
rm -f zlib/libz.a
|
||||
$(MAKE) all AMD64=true MMGR=true
|
||||
|
||||
$(OBJDIR_WIN32)/%.o: $(SRCDIR)/%.c
|
||||
$(DO_CC_WIN32)
|
||||
amd64_debug_mmgr:
|
||||
rm -f zlib/libz.a
|
||||
$(MAKE) all AMD64=true DEBUG=true MMGR=true
|
||||
|
||||
$(OBJDIR_WIN32)/%.o: $(SRCDIR)/%.cpp
|
||||
$(DO_CC_WIN32)
|
||||
amd64_debug:
|
||||
rm -f zlib/libz.a
|
||||
$(MAKE) all AMD64=true DEBUG=true
|
||||
|
||||
default: $(DEFAULT)
|
||||
mmgr:
|
||||
$(MAKE) all MMGR=true
|
||||
|
||||
$(TARGET_LINUX): $(OBJDIR_LINUX) $(OBJ_LINUX) $(OBJC_LINUX)
|
||||
$(LINK_LINUX)
|
||||
debug_mmgr:
|
||||
$(MAKE) all MMGR=true DEBUG=true
|
||||
|
||||
$(TARGET_WIN32): $(OBJDIR_WIN32) $(OBJ_WIN32) $(OBJC_WIN32)
|
||||
$(LINK_WIN32)
|
||||
amxmodx: $(OBJ_LINUX)
|
||||
$(CPP) $(INCLUDE) $(CFLAGS) $(OBJ_LINUX) $(LINK) -shared -ldl -lm -o$(BIN_DIR)/$(BINARY)
|
||||
|
||||
$(OBJDIR_LINUX):
|
||||
mkdir $@
|
||||
mkdir $@/mmgr
|
||||
debug:
|
||||
$(MAKE) all DEBUG=true
|
||||
|
||||
$(OBJDIR_WIN32):
|
||||
mkdir $@
|
||||
mkdir $@/mmgr
|
||||
|
||||
win32: $(TARGET_WIN32)
|
||||
|
||||
linux: $(TARGET_LINUX)
|
||||
|
||||
clean: $(CLEAN)
|
||||
|
||||
clean_both:
|
||||
-rm -f $(OBJDIR_LINUX)/*
|
||||
-rm -f $(OBJDIR_WIN32)/*
|
||||
|
||||
clean_win32:
|
||||
del /q $(OBJDIR_WIN32)
|
||||
default: all
|
||||
|
||||
clean:
|
||||
rm -rf Release/*.o
|
||||
rm -rf Release/$(BINARY)
|
||||
rm -rf Debug/*.o
|
||||
rm -rf Debug/$(BINARY)
|
||||
|
||||
|
@ -1,256 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
#(C)2004 AMX Mod X Development Team
|
||||
# by David "BAILOPAN" Anderson
|
||||
|
||||
# output will occur in bin.x.proc
|
||||
# where x is debug or opt and proc is ix86 or amd64
|
||||
# You must use this script from the amxmodx src dir
|
||||
|
||||
#options =
|
||||
# jit - use the JIT
|
||||
# debug - enable gdb debugging
|
||||
# amd64 - compile for AMD64 (impiles no jit)
|
||||
# proc=ix86 - assumed not amd64
|
||||
# clean - clean the specifications above
|
||||
# asm - for ASM implementation
|
||||
# !! TODO - add memory mananger support
|
||||
# lineop - for JIT only, uses slow version
|
||||
|
||||
$PROJECT = "amxmodx_mm";
|
||||
$sdk = "../hlsdk/SourceCode";
|
||||
$mm = "../metamod/metamod";
|
||||
$gccf = "gcc";
|
||||
$ccf = "cc";
|
||||
$amd64_lstdc = "-lstdc++";
|
||||
|
||||
@CPP_SOURCE_FILES = ("meta_api.cpp", "CFile.cpp", "CVault.cpp", "vault.cpp", "float.cpp", "file.cpp", "modules.cpp", "CMisc.cpp", "CTask.cpp", "string.cpp", "amxmodx.cpp", "CEvent.cpp", "CCmd.cpp", "CLogEvent.cpp", "srvcmd.cpp", "strptime.cpp", "amxcore.cpp", "amxtime.cpp", "power.cpp", "amxxlog.cpp", "fakemeta.cpp", "amxxfile.cpp", "CLang.cpp", "md5.cpp", "emsg.cpp", "CForward.cpp", "CPlugin.cpp", "CModule.cpp", "CMenu.cpp", "util.cpp");
|
||||
|
||||
@C_SOURCE_FILES = ();
|
||||
my %OPTIONS, %OPT;
|
||||
|
||||
$OPT{"debug"} = "-g -ggdb";
|
||||
$OPT{"opt"} = "-O2 -ffast-math -funroll-loops -fomit-frame-pointer -s -DNDEBUG -Wall -Wno-unknown-pragmas -DOPT_TYPE=\"optimized\" -fno-exceptions -fno-rtti";
|
||||
|
||||
$OPTIONS{"include"} = "-I$sdk -I. -I$mm -I$sdk/engine -I$sdk/common -I$sdk/pm_shared -I$sdk/dlls";
|
||||
|
||||
while ($cmd = shift)
|
||||
{
|
||||
if ($cmd =~ /asm/)
|
||||
{
|
||||
if ($OPTIONS{"amd64"})
|
||||
{
|
||||
die "You cannot compile the ASM core with AMD64 yet.\n";
|
||||
} else {
|
||||
$OPTIONS{"asm"} = 1;
|
||||
}
|
||||
}
|
||||
if ($cmd =~ /jit/)
|
||||
{
|
||||
if ($OPTIONS{"amd64"})
|
||||
{
|
||||
die "You cannot compile the JIT and AMD64 yet.\n";
|
||||
} else {
|
||||
$OPTIONS{"jit"} = 1;
|
||||
}
|
||||
} elsif ($cmd =~ /amd64/) {
|
||||
if ($OPTIONS{"jit"} || $OPTIONS{"asm"})
|
||||
{
|
||||
die "You cannot compile the JIT or ASM and AMD64 yet.\n";
|
||||
} else {
|
||||
$OPTIONS{"amd64"} = 1;
|
||||
}
|
||||
} elsif ($cmd =~ /debug/) {
|
||||
$OPTIONS{"debug"} = 1;
|
||||
} elsif ($cmd =~ /proc=i(\d)86/) {
|
||||
$proc = $1;
|
||||
if ($OPTIONS{"amd64"})
|
||||
{
|
||||
die "You cannot compile for i".$proc."86 and AMD64.\n";
|
||||
} else {
|
||||
$OPTIONS{"proc"} = "i".$proc."86";
|
||||
}
|
||||
} elsif ($cmd =~ /clean/) {
|
||||
$OPTIONS{"clean"} = 1;
|
||||
} elsif ($cmd =~ /lineop/) {
|
||||
$OPTIONS{"lineop"} = 1;
|
||||
}
|
||||
}
|
||||
|
||||
$gcc = `$gccf --version`;
|
||||
if ($gcc =~ /2\.9/)
|
||||
{
|
||||
#if ($OPTIONS{"jit"})
|
||||
#{
|
||||
# push(@CPP_SOURCE_FILES, "amx.cpp");
|
||||
# $OPT{"opt"} .= " -malign-loops=2 -malign-jumps=2 -malign-functions=2";
|
||||
# } else {
|
||||
`ln -s amx.cpp amx.c`;
|
||||
push(@C_SOURCE_FILES, "amx.c");
|
||||
# }
|
||||
} else {
|
||||
if ($OPTIONS{"amd64"})
|
||||
{
|
||||
`ln -s amx.cpp amx.c`;
|
||||
push(@C_SOURCE_FILES, "amx.c");
|
||||
} else {
|
||||
push(@CPP_SOURCE_FILES, "amx.cpp");
|
||||
}
|
||||
$OPT{"opt"} .= " -falign-loops=2 -falign-jumps=2 -falign-functions=2";
|
||||
}
|
||||
|
||||
if ($OPTIONS{"debug"})
|
||||
{
|
||||
$cflags = $OPT{"debug"};
|
||||
} else {
|
||||
if (!$OPTIONS{"amd64"})
|
||||
{
|
||||
$proc = $OPTIONS{"proc"};
|
||||
if (!$proc)
|
||||
{
|
||||
$proc = 3;
|
||||
}
|
||||
$cflags = "-march=i".$proc."86 ".$OPT{"opt"};
|
||||
} else {
|
||||
$cflags = $OPT{"opt"};
|
||||
}
|
||||
}
|
||||
|
||||
if ($OPTIONS{"amd64"})
|
||||
{
|
||||
$cflags = " -m64 -DSMALL_CELL_SIZE=64 -DHAVE_I64 $cflags";
|
||||
}
|
||||
|
||||
if ($OPTIONS{"jit"})
|
||||
{
|
||||
$cflags .= " -DJIT";
|
||||
}
|
||||
|
||||
if ($OPTIONS{"asm"})
|
||||
{
|
||||
$cflags .= " -DASM32";
|
||||
}
|
||||
|
||||
if ($OPTIONS{"debug"})
|
||||
{
|
||||
$outdir = "bin.debug";
|
||||
} else {
|
||||
$outdir = "bin.opt";
|
||||
}
|
||||
|
||||
if ($OPTIONS{"amd64"})
|
||||
{
|
||||
$outdir .= ".amd64";
|
||||
$bin = $PROJECT."_amd64.so";
|
||||
} else {
|
||||
$proc = $OPTIONS{"proc"};
|
||||
if ($proc)
|
||||
{
|
||||
$outdir .= ".i".$proc."86";
|
||||
$bin = $PROJECT."_i".$proc."86.so";
|
||||
} else {
|
||||
$outdir .= ".i386";
|
||||
$bin = $PROJECT."_i386.so";
|
||||
}
|
||||
}
|
||||
|
||||
if ($OPTIONS{"clean"})
|
||||
{
|
||||
`rm $outdir/*.o`;
|
||||
`rm $outdir/$bin`;
|
||||
die("Project cleaned.\n");
|
||||
}
|
||||
|
||||
#create the dirs
|
||||
#build link list
|
||||
my @LINK;
|
||||
for ($i=0; $i<=$#CPP_SOURCE_FILES; $i++)
|
||||
{
|
||||
$file = $CPP_SOURCE_FILES[$i];
|
||||
$file =~ s/\.cpp/\.o/;
|
||||
push(@LINK, $outdir."/".$file);
|
||||
}
|
||||
for ($i=0; $i<=$#C_SOURCE_FILES; $i++)
|
||||
{
|
||||
$file = $C_SOURCE_FILES[$i];
|
||||
$file =~ s/\.c/\.o/;
|
||||
push(@LINK, $outdir."/".$file);
|
||||
}
|
||||
if ($OPTIONS{"jit"})
|
||||
{
|
||||
if ($OPTIONS{"lineop"}) {
|
||||
push(@LINK, "JIT/jits-lineop.o");
|
||||
} else {
|
||||
push(@LINK, "JIT/jits.o");
|
||||
}
|
||||
}
|
||||
if ($OPTIONS{"amd64"})
|
||||
{
|
||||
push(@LINK, "zlib/libz64.a");
|
||||
push(@LINK, $amd64_lstdc);
|
||||
} else {
|
||||
push(@LINK, "zlib/libz.a");
|
||||
}
|
||||
if ($OPTIONS{"asm"})
|
||||
{
|
||||
push(@LINK, "amxexecn.o");
|
||||
}
|
||||
|
||||
if (!(-d $outdir))
|
||||
{
|
||||
mkdir($outdir);
|
||||
}
|
||||
if (!(-d "$outdir/JIT"))
|
||||
{
|
||||
mkdir("$outdir/JIT");
|
||||
}
|
||||
|
||||
$inc = $OPTIONS{"include"};
|
||||
|
||||
for ($i=0; $i<=$#CPP_SOURCE_FILES; $i++)
|
||||
{
|
||||
$file = $CPP_SOURCE_FILES[$i];
|
||||
$ofile = $file;
|
||||
$ofile =~ s/\.cpp/\.o/;
|
||||
$ofile = "$outdir/$ofile";
|
||||
$gcc = "$gccf $cflags -Dstrcmpi=strcasecmp -fPIC $inc -c $file -o $ofile";
|
||||
if (-e $ofile)
|
||||
{
|
||||
$file_time = (stat($file))[9];
|
||||
$ofile_time = (stat($ofile))[9];
|
||||
if ($file_time > $ofile_time)
|
||||
{
|
||||
`rm $ofile`;
|
||||
print "$gcc\n";
|
||||
`$gcc`;
|
||||
}
|
||||
} else {
|
||||
print "$gcc\n";
|
||||
`$gcc`;
|
||||
}
|
||||
}
|
||||
|
||||
for ($i=0; $i<=$#CPP_SOURCE_FILES; $i++)
|
||||
{
|
||||
$file = $C_SOURCE_FILES[$i];
|
||||
$ofile = $file;
|
||||
$ofile =~ s/\.c/\.o/;
|
||||
$ofile = "$outdir/$ofile";
|
||||
$gcc = "$ccf $cflags -Dstrcmpi=strcasecmp -fPIC $inc -c $file -o $ofile";
|
||||
if (-e $ofile)
|
||||
{
|
||||
$file_time = (stat($file))[9];
|
||||
$ofile_time = (stat($ofile))[9];
|
||||
if ($file_time > $ofile_time)
|
||||
{
|
||||
print "$gcc\n";
|
||||
`$gcc`;
|
||||
}
|
||||
} else {
|
||||
print "$gcc\n";
|
||||
`$gcc`;
|
||||
}
|
||||
}
|
||||
|
||||
$gcc = "$gccf $cflags -shared -ldl -lm @LINK -o $outdir/$bin";
|
||||
print "$gcc\n";
|
||||
`$gcc`;
|
1380
amxmodx/amx.cpp
1380
amxmodx/amx.cpp
File diff suppressed because it is too large
Load Diff
248
amxmodx/amx.h
248
amxmodx/amx.h
@ -1,6 +1,6 @@
|
||||
/* Abstract Machine for the Small compiler
|
||||
/* Pawn Abstract Machine (for the Pawn language)
|
||||
*
|
||||
* Copyright (c) ITB CompuPhase, 1997-2004
|
||||
* Copyright (c) ITB CompuPhase, 1997-2005
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty.
|
||||
* In no event will the authors be held liable for any damages arising from
|
||||
@ -21,20 +21,34 @@
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined __linux__
|
||||
#if defined FREEBSD && !defined __FreeBSD__
|
||||
#define __FreeBSD__
|
||||
#endif
|
||||
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
|
||||
#include <sclinux.h>
|
||||
#endif
|
||||
|
||||
#ifndef AMX_H_INCLUDED
|
||||
#define AMX_H_INCLUDED
|
||||
|
||||
#if defined __LCC__ || defined __DMC__ || defined __linux__
|
||||
#if defined HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
|
||||
#else
|
||||
#if defined __LCC__ || defined __DMC__ || defined LINUX
|
||||
#if defined HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
|
||||
/* The ISO C99 defines the int16_t and int_32t types. If the compiler got
|
||||
* here, these types are probably undefined.
|
||||
*/
|
||||
#if defined __FreeBSD__
|
||||
#if defined __MACH__
|
||||
#include <ppc/types.h>
|
||||
typedef unsigned short int uint16_t;
|
||||
typedef unsigned long int uint32_t;
|
||||
#elif defined __FreeBSD__
|
||||
#include <inttypes.h>
|
||||
#else
|
||||
typedef short int int16_t;
|
||||
@ -56,18 +70,41 @@
|
||||
#define HAVE_I64
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#define HAVE_STDINT_H
|
||||
#endif
|
||||
#if defined _LP64 || defined WIN64 || defined _WIN64
|
||||
#if !defined __64BIT__
|
||||
#define __64BIT__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAVE_ALLOCA_H
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32 /* || defined __MSDOS__ */
|
||||
#if !defined alloca
|
||||
#define alloca(n) _alloca(n)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined arraysize
|
||||
#define arraysize(array) (sizeof(array) / sizeof((array)[0]))
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined PAWN_DLL
|
||||
#if !defined AMX_NATIVE_CALL
|
||||
#define AMX_NATIVE_CALL __stdcall
|
||||
#endif
|
||||
#if !defined AMXAPI
|
||||
#define AMXAPI __stdcall
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* calling convention for native functions */
|
||||
#if !defined AMX_NATIVE_CALL
|
||||
#define AMX_NATIVE_CALL
|
||||
@ -78,6 +115,8 @@ extern "C" {
|
||||
#define AMXAPI __stdcall
|
||||
#elif defined CDECL
|
||||
#define AMXAPI __cdecl
|
||||
#elif defined GCC_HASCLASSVISIBILITY
|
||||
#define AMXAPI __attribute__ ((visibility("default")))
|
||||
#else
|
||||
#define AMXAPI
|
||||
#endif
|
||||
@ -95,46 +134,38 @@ extern "C" {
|
||||
* 5 (tagnames table) 4
|
||||
* 6 (reformatted header) 6
|
||||
* 7 (name table, opcodes SYMTAG & SYSREQ.D) 7
|
||||
* 8 (opcode STMT, renewed debug interface) 8
|
||||
*/
|
||||
#define CUR_FILE_VERSION 7 /* current file version; also the current AMX version */
|
||||
#define CUR_FILE_VERSION 8 /* current file version; also the current AMX version */
|
||||
#define MIN_FILE_VERSION 6 /* lowest supported file format version for the current AMX version */
|
||||
#define MIN_AMX_VERSION 7 /* minimum AMX version needed to support the current file format */
|
||||
#define MIN_AMX_VERSION 8 /* minimum AMX version needed to support the current file format */
|
||||
|
||||
#if defined BIT16
|
||||
#define SMALL_CELL_SIZE 16 /* for backward compatibility */
|
||||
#if !defined PAWN_CELL_SIZE
|
||||
#define PAWN_CELL_SIZE 32 /* by default, use 32-bit cells */
|
||||
#endif
|
||||
#if !defined SMALL_CELL_SIZE
|
||||
#define SMALL_CELL_SIZE 32 /* by default, use 32-bit cells */
|
||||
#endif
|
||||
#if SMALL_CELL_SIZE==16
|
||||
#if PAWN_CELL_SIZE==16
|
||||
typedef uint16_t ucell;
|
||||
typedef int16_t cell;
|
||||
#elif SMALL_CELL_SIZE==32
|
||||
#elif PAWN_CELL_SIZE==32
|
||||
typedef uint32_t ucell;
|
||||
typedef int32_t cell;
|
||||
#elif SMALL_CELL_SIZE==64
|
||||
#define REAL float
|
||||
#elif PAWN_CELL_SIZE==64
|
||||
typedef uint64_t ucell;
|
||||
typedef int64_t cell;
|
||||
#define REAL double
|
||||
#else
|
||||
#error Unsupported cell size (SMALL_CELL_SIZE)
|
||||
#error Unsupported cell size (PAWN_CELL_SIZE)
|
||||
#endif
|
||||
|
||||
#if SMALL_CELL_SIZE==32
|
||||
#define REAL float
|
||||
#elif SMALL_CELL_SIZE==64
|
||||
#define REAL double
|
||||
#else
|
||||
#error Unsupported cell size
|
||||
#endif
|
||||
|
||||
#define UNPACKEDMAX ((1 << (sizeof(cell)-1)*8) - 1)
|
||||
#define UNPACKEDMAX ((1L << (sizeof(cell)-1)*8) - 1)
|
||||
#define UNLIMITED (~1u >> 1)
|
||||
|
||||
struct tagAMX;
|
||||
typedef cell (AMX_NATIVE_CALL *AMX_NATIVE)(struct tagAMX *amx, cell *params);
|
||||
typedef int (AMXAPI *AMX_CALLBACK)(struct tagAMX *amx, cell index,
|
||||
cell *result, cell *params);
|
||||
typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
|
||||
typedef int (AMXAPI *AMX_DEBUGCALL)(struct tagAMX *amx, int mode);
|
||||
#if !defined _FAR
|
||||
#define _FAR
|
||||
#endif
|
||||
@ -148,7 +179,7 @@ typedef int (AMXAPI *AMX_DEBUGCALL)(struct tagAMX *amx, int mode);
|
||||
/* Some compilers do not support the #pragma align, which should be fine. Some
|
||||
* compilers give a warning on unknown #pragmas, which is not so fine...
|
||||
*/
|
||||
#if defined SN_TARGET_PS2 || defined __GNUC__
|
||||
#if (defined SN_TARGET_PS2 || defined __GNUC__) && !defined AMX_NO_ALIGN
|
||||
#define AMX_NO_ALIGN
|
||||
#endif
|
||||
|
||||
@ -159,8 +190,10 @@ typedef int (AMXAPI *AMX_DEBUGCALL)(struct tagAMX *amx, int mode);
|
||||
#endif
|
||||
|
||||
#if !defined AMX_NO_ALIGN
|
||||
#if defined __linux__
|
||||
#if defined LINUX || defined __FreeBSD__
|
||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||
#elif defined MACOS && defined __MWERKS__
|
||||
#pragma options align=mac68k
|
||||
#else
|
||||
#pragma pack(push)
|
||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||
@ -170,10 +203,10 @@ typedef int (AMXAPI *AMX_DEBUGCALL)(struct tagAMX *amx, int mode);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
typedef struct tagAMX_NATIVE_INFO {
|
||||
const char _FAR *name PACKED;
|
||||
AMX_NATIVE func PACKED;
|
||||
} AMX_NATIVE_INFO;
|
||||
} PACKED AMX_NATIVE_INFO;
|
||||
|
||||
#define AMX_USERNUM 4
|
||||
#define sEXPMAX 19 /* maximum name length for file version <= 6 */
|
||||
@ -181,14 +214,19 @@ typedef struct {
|
||||
|
||||
typedef struct tagAMX_FUNCSTUB {
|
||||
ucell address PACKED;
|
||||
const char name[sEXPMAX+1] PACKED;
|
||||
} AMX_FUNCSTUB;
|
||||
char name[sEXPMAX+1] PACKED;
|
||||
} PACKED AMX_FUNCSTUB;
|
||||
|
||||
typedef struct tagFUNCSTUBNT {
|
||||
ucell address PACKED;
|
||||
ucell nameofs PACKED; //we need this for amxx to be backwards comaptible
|
||||
} PACKED AMX_FUNCSTUBNT;
|
||||
|
||||
/* The AMX structure is the internal structure for many functions. Not all
|
||||
* fields are valid at all times; many fields are cached in local variables.
|
||||
*/
|
||||
typedef struct tagAMX {
|
||||
unsigned char _FAR *base PACKED; /* points to the AMX header ("amxhdr") plus the code, optionally also the data */
|
||||
unsigned char _FAR *base PACKED; /* points to the AMX header plus the code, optionally also the data */
|
||||
unsigned char _FAR *data PACKED; /* points to separate data+stack+heap, may be NULL */
|
||||
AMX_CALLBACK callback PACKED;
|
||||
AMX_DEBUG debug PACKED; /* debug callback */
|
||||
@ -200,18 +238,15 @@ typedef struct tagAMX {
|
||||
cell stk PACKED; /* stack pointer: relative to base + amxhdr->dat */
|
||||
cell stp PACKED; /* top of the stack: relative to base + amxhdr->dat */
|
||||
int flags PACKED; /* current status, see amx_Flags() */
|
||||
/* for assertions and debug hook */
|
||||
cell curline PACKED;
|
||||
cell curfile PACKED;
|
||||
int dbgcode PACKED;
|
||||
cell dbgaddr PACKED;
|
||||
cell dbgparam PACKED;
|
||||
char _FAR *dbgname PACKED;
|
||||
/* user data */
|
||||
long usertags[AMX_USERNUM] PACKED;
|
||||
//okay userdata[3] in AMX Mod X is for the CPlugin * pointer
|
||||
//we're also gonna set userdata[2] to a special debug structure
|
||||
void _FAR *userdata[AMX_USERNUM] PACKED;
|
||||
/* native functions can raise an error */
|
||||
int error PACKED;
|
||||
/* passing parameters requires a "count" field */
|
||||
int paramcount;
|
||||
/* the sleep opcode needs to store the full AMX status */
|
||||
cell pri PACKED;
|
||||
cell alt PACKED;
|
||||
@ -221,7 +256,7 @@ typedef struct tagAMX {
|
||||
/* support variables for the JIT */
|
||||
int reloc_size PACKED; /* required temporary buffer for relocations */
|
||||
long code_size PACKED; /* estimated memory footprint of the native code */
|
||||
} AMX;
|
||||
} PACKED AMX;
|
||||
|
||||
/* The AMX_HEADER structure is both the memory format as the file format. The
|
||||
* structure is used internaly.
|
||||
@ -243,27 +278,12 @@ typedef struct tagAMX_HEADER {
|
||||
int32_t libraries PACKED; /* offset to the table of libraries */
|
||||
int32_t pubvars PACKED; /* the "public variables" table */
|
||||
int32_t tags PACKED; /* the "public tagnames" table */
|
||||
int32_t nametable PACKED; /* name table, file version 7 only */
|
||||
} AMX_HEADER PACKED;
|
||||
int32_t nametable PACKED; /* name table */
|
||||
} PACKED AMX_HEADER;
|
||||
|
||||
//This is always the same for us
|
||||
#define AMX_MAGIC 0xf1e0
|
||||
|
||||
//double linked list for stack
|
||||
typedef struct tagAMX_TRACE
|
||||
{
|
||||
cell line PACKED;
|
||||
cell file PACKED;
|
||||
struct tagAMX_TRACE *next PACKED;
|
||||
struct tagAMX_TRACE *prev PACKED;
|
||||
} AMX_TRACE PACKED;
|
||||
|
||||
typedef struct tagAMX_DBG
|
||||
{
|
||||
int32_t numFiles PACKED; /* number of chars in array */
|
||||
char **files PACKED; /* array of files */
|
||||
AMX_TRACE *head PACKED; /* begin of link list */
|
||||
AMX_TRACE *tail PACKED; /* end of link list */
|
||||
} AMX_DBG PACKED;
|
||||
|
||||
enum {
|
||||
AMX_ERR_NONE,
|
||||
/* reserve the first 15 error codes for exit codes of the abstract machine */
|
||||
@ -279,6 +299,7 @@ enum {
|
||||
AMX_ERR_NATIVE, /* native function failed */
|
||||
AMX_ERR_DIVIDE, /* divide by zero */
|
||||
AMX_ERR_SLEEP, /* go into sleepmode - code can be restarted */
|
||||
AMX_ERR_INVSTATE, /* invalid state for this access */
|
||||
|
||||
AMX_ERR_MEMORY = 16, /* out of memory */
|
||||
AMX_ERR_FORMAT, /* invalid file format */
|
||||
@ -291,29 +312,18 @@ enum {
|
||||
AMX_ERR_INIT_JIT, /* cannot initialize the JIT */
|
||||
AMX_ERR_PARAMS, /* parameter error */
|
||||
AMX_ERR_DOMAIN, /* domain error, expression result does not fit in range */
|
||||
};
|
||||
|
||||
enum {
|
||||
DBG_INIT, /* query/initialize */
|
||||
DBG_FILE, /* file number in curfile, filename in name */
|
||||
DBG_LINE, /* line number in curline, file number in curfile */
|
||||
DBG_SYMBOL, /* address in dbgaddr, class/type in dbgparam */
|
||||
DBG_CLRSYM, /* stack address below which locals should be removed. stack address in stk */
|
||||
DBG_CALL, /* function call, address jumped to in dbgaddr */
|
||||
DBG_RETURN, /* function returns */
|
||||
DBG_TERMINATE, /* program ends, code address in dbgaddr, reason in dbgparam */
|
||||
DBG_SRANGE, /* symbol size and dimensions (arrays); level in dbgaddr (!); length in dbgparam */
|
||||
DBG_SYMTAG, /* tag of the most recent symbol (if non-zero), tag in dbgparam */
|
||||
AMX_ERR_GENERAL, /* general error (unknown or unspecific error) */
|
||||
};
|
||||
|
||||
/* AMX_FLAG_CHAR16 0x01 no longer used */
|
||||
#define AMX_FLAG_DEBUG 0x02 /* symbolic info. available */
|
||||
#define AMX_FLAG_COMPACT 0x04 /* compact encoding */
|
||||
#define AMX_FLAG_BIGENDIAN 0x08 /* big endian encoding */
|
||||
#define AMX_FLAG_NOCHECKS 0x10 /* no array bounds checking */
|
||||
#define AMX_FLAG_LINEOPS 0x20 /* line ops are parsed by the JIT [loadtime only flag] */
|
||||
#define AMX_FLAG_TRACED 0x40 /* the file has already been traced */
|
||||
#define AMX_FLAG_BROWSE 0x4000 /* browsing/relocating or executing */
|
||||
#define AMX_FLAG_BYTEOPC 0x08 /* opcode is a byte (not a cell) */
|
||||
#define AMX_FLAG_NOCHECKS 0x10 /* no array bounds checking; no STMT opcode */
|
||||
#define AMX_FLAG_PRENIT 0x100 /* pre-initialized, do not check natives */
|
||||
#define AMX_FLAG_NTVREG 0x1000 /* all native functions are registered */
|
||||
#define AMX_FLAG_JITC 0x2000 /* abstract machine is JIT compiled */
|
||||
#define AMX_FLAG_BROWSE 0x4000 /* busy browsing */
|
||||
#define AMX_FLAG_RELOC 0x8000 /* jump/call addresses relocated */
|
||||
|
||||
#define AMX_EXEC_MAIN -1 /* start at program entry point */
|
||||
@ -321,16 +331,36 @@ enum {
|
||||
|
||||
#define AMX_USERTAG(a,b,c,d) ((a) | ((b)<<8) | ((long)(c)<<16) | ((long)(d)<<24))
|
||||
|
||||
#define AMX_EXPANDMARGIN 64
|
||||
#if !defined AMX_COMPACTMARGIN
|
||||
#define AMX_COMPACTMARGIN 64
|
||||
#endif
|
||||
|
||||
struct amx_trace
|
||||
{
|
||||
cell frm;
|
||||
amx_trace *prev;
|
||||
amx_trace *next;
|
||||
bool used;
|
||||
};
|
||||
|
||||
struct AMX_DBGINFO
|
||||
{
|
||||
void *pDebug; //Pointer to debug data
|
||||
int error; //non-amx_Exec() error setting
|
||||
amx_trace *pTrace; //Pointer to stack trace
|
||||
amx_trace *pTraceFrm;
|
||||
amx_trace *pTraceEnd;
|
||||
cell frm;
|
||||
};
|
||||
|
||||
/* for native functions that use floating point parameters, the following
|
||||
* two macros are convenient for casting a "cell" into a "float" type _without_
|
||||
* changing the bit pattern
|
||||
*/
|
||||
#if SMALL_CELL_SIZE==32
|
||||
#if PAWN_CELL_SIZE==32
|
||||
#define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
|
||||
#define amx_ctof(c) ( * ((float*)&c) ) /* cell to float */
|
||||
#elif SMALL_CELL_SIZE==64
|
||||
#elif PAWN_CELL_SIZE==64
|
||||
#define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
|
||||
#define amx_ctof(c) ( * ((double*)&c) ) /* cell to float */
|
||||
#else
|
||||
@ -344,7 +374,7 @@ enum {
|
||||
amx_StrLen(amx_cstr_, &amx_length_); \
|
||||
if (amx_length_ > 0 && \
|
||||
((result) = (void*)alloca((amx_length_ + 1) * sizeof(*(result)))) != NULL) \
|
||||
amx_GetString((char*)(result), amx_cstr_, sizeof(*(result))>1); \
|
||||
amx_GetString((char*)(result), amx_cstr_, sizeof(*(result))>1, amx_length_); \
|
||||
else (result) = NULL; \
|
||||
} while (0)
|
||||
|
||||
@ -353,23 +383,11 @@ uint32_t * AMXAPI amx_Align32(uint32_t *v);
|
||||
#if defined _I64_MAX || defined HAVE_I64
|
||||
uint64_t * AMXAPI amx_Align64(uint64_t *v);
|
||||
#endif
|
||||
|
||||
#if SMALL_CELL_SIZE==32
|
||||
#define amx_AlignCell amx_Align32
|
||||
#elif SMALL_CELL_SIZE==64
|
||||
#define amx_AlignCell amx_Align64
|
||||
#else
|
||||
#error Unsupported cell size
|
||||
#endif
|
||||
|
||||
int AMXAPI amx_Allot(AMX *amx, int cells, cell *amx_addr, cell **phys_addr);
|
||||
int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params);
|
||||
int AMXAPI amx_Cleanup(AMX *amx);
|
||||
int AMXAPI amx_Clone(AMX *amxClone, AMX *amxSource, void *data);
|
||||
int AMXAPI amx_Debug(AMX *amx); /* default debug procedure, does nothing */
|
||||
int AMXAPI amx_DebugCall(AMX *amx, int mode);
|
||||
int AMXAPI amx_Exec(AMX *amx, cell *retval, int index, int numparams, ...);
|
||||
int AMXAPI amx_Execv(AMX *amx, cell *retval, int index, int numparams, cell params[]);
|
||||
int AMXAPI amx_Exec(AMX *amx, cell *retval, int index);
|
||||
int AMXAPI amx_FindNative(AMX *amx, const char *name, int *index);
|
||||
int AMXAPI amx_FindPublic(AMX *amx, const char *funcname, int *index);
|
||||
int AMXAPI amx_FindPubVar(AMX *amx, const char *varname, cell *amx_addr);
|
||||
@ -379,34 +397,56 @@ int AMXAPI amx_GetAddr(AMX *amx,cell amx_addr,cell **phys_addr);
|
||||
int AMXAPI amx_GetNative(AMX *amx, int index, char *funcname);
|
||||
int AMXAPI amx_GetPublic(AMX *amx, int index, char *funcname);
|
||||
int AMXAPI amx_GetPubVar(AMX *amx, int index, char *varname, cell *amx_addr);
|
||||
int AMXAPI amx_GetString(char *dest,const cell *source, int use_wchar);
|
||||
int AMXAPI amx_GetString(char *dest,const cell *source, int use_wchar, size_t size);
|
||||
int AMXAPI amx_GetTag(AMX *amx, int index, char *tagname, cell *tag_id);
|
||||
int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr);
|
||||
int AMXAPI amx_Init(AMX *amx, void *program);
|
||||
int AMXAPI amx_InitJIT(AMX *amx, void *reloc_table, void *native_code);
|
||||
int AMXAPI amx_MemInfo(AMX *amx, long *codesize, long *datasize, long *stackheap);
|
||||
int AMXAPI amx_NameLength(AMX *amx, int *length);
|
||||
AMX_NATIVE_INFO * AMXAPI amx_NativeInfo(const char *name,AMX_NATIVE func);
|
||||
AMX_NATIVE_INFO * AMXAPI amx_NativeInfo(const char *name, AMX_NATIVE func);
|
||||
int AMXAPI amx_NumNatives(AMX *amx, int *number);
|
||||
int AMXAPI amx_NumPublics(AMX *amx, int *number);
|
||||
int AMXAPI amx_NumPubVars(AMX *amx, int *number);
|
||||
int AMXAPI amx_NumTags(AMX *amx, int *number);
|
||||
int AMXAPI amx_Push(AMX *amx, cell value);
|
||||
int AMXAPI amx_PushArray(AMX *amx, cell *amx_addr, cell **phys_addr, const cell array[], int numcells);
|
||||
int AMXAPI amx_PushString(AMX *amx, cell *amx_addr, cell **phys_addr, const char *string, int pack, int use_wchar);
|
||||
int AMXAPI amx_RaiseError(AMX *amx, int error);
|
||||
int AMXAPI amx_Register(AMX *amx, AMX_NATIVE_INFO *nativelist, int number);
|
||||
int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *nativelist, int number);
|
||||
int AMXAPI amx_Release(AMX *amx, cell amx_addr);
|
||||
int AMXAPI amx_SetCallback(AMX *amx, AMX_CALLBACK callback);
|
||||
int AMXAPI amx_SetDebugHook(AMX *amx, AMX_DEBUG debug);
|
||||
int AMXAPI amx_SetString(cell *dest, const char *source, int pack, int use_wchar);
|
||||
int AMXAPI amx_SetString(cell *dest, const char *source, int pack, int use_wchar, size_t size);
|
||||
int AMXAPI amx_SetUserData(AMX *amx, long tag, void *ptr);
|
||||
int AMXAPI amx_StrLen(cell *cstring, int *length);
|
||||
int AMXAPI amx_StrLen(const cell *cstring, int *length);
|
||||
int AMXAPI amx_UTF8Check(const char *string, int *length);
|
||||
int AMXAPI amx_UTF8Get(const char *string, const char **endptr, cell *value);
|
||||
int AMXAPI amx_UTF8Len(const cell *cstr, int *length);
|
||||
int AMXAPI amx_UTF8Put(char *string, char **endptr, int maxchars, cell value);
|
||||
int AMXAPI amx_UTF8Check(const char *string);
|
||||
void amx_NullNativeTable(AMX *amx);
|
||||
int AMXAPI amx_GetLibraries(AMX *amx);
|
||||
const char *AMXAPI amx_GetLibrary(AMX *amx, int index, char *buffer, int len);
|
||||
int AMXAPI amx_SetStringOld(cell *dest,const char *source,int pack,int use_wchar);
|
||||
int AMXAPI amx_GetStringOld(char *dest,const cell *source,int use_wchar);
|
||||
|
||||
#if PAWN_CELL_SIZE==16
|
||||
#define amx_AlignCell(v) amx_Align16(v)
|
||||
#elif PAWN_CELL_SIZE==32
|
||||
#define amx_AlignCell(v) amx_Align32(v)
|
||||
#elif PAWN_CELL_SIZE==64 && (defined _I64_MAX || defined HAVE_I64)
|
||||
#define amx_AlignCell(v) amx_Align64(v)
|
||||
#else
|
||||
#error Unsupported cell size
|
||||
#endif
|
||||
|
||||
#define amx_RegisterFunc(amx, name, func) \
|
||||
amx_Register((amx), amx_NativeInfo((name),(func)), 1);
|
||||
|
||||
#if !defined AMX_NO_ALIGN
|
||||
#if defined __linux__
|
||||
#if defined LINUX || defined __FreeBSD__
|
||||
#pragma pack() /* reset default packing */
|
||||
#elif defined MACOS && defined __MWERKS__
|
||||
#pragma options align=reset
|
||||
#else
|
||||
#pragma pack(pop) /* reset previous packing */
|
||||
#endif
|
||||
|
@ -1,11 +0,0 @@
|
||||
; /usr/local/cross-tools/bin/i386-mingw32msvc-dlltool --base-file /tmp/cc4kB6s0.base --output-exp amx_mm.exp --dllname amx_mm.dll --output-def amx_mm.def --add-stdcall-alias --exclude-symbol=DllMainCRTStartup@12 --def /tmp/ccyI7I7K.def
|
||||
EXPORTS
|
||||
GetEngineFunctions @ 1 ;
|
||||
GetEngineFunctions_Post @ 2 ;
|
||||
GetEntityAPI2 @ 3 ;
|
||||
GetEntityAPI2_Post @ 4 ;
|
||||
GiveFnptrsToDll = GiveFnptrsToDll@8 @ 5 ;
|
||||
GiveFnptrsToDll@8 @ 6 ;
|
||||
Meta_Attach @ 7 ;
|
||||
Meta_Detach @ 8 ;
|
||||
Meta_Query @ 9 ;
|
@ -1,6 +1,6 @@
|
||||
/* Core module for the Small AMX
|
||||
/* Core module for the Pawn AMX
|
||||
*
|
||||
* Copyright (c) ITB CompuPhase, 1997-2004
|
||||
* Copyright (c) ITB CompuPhase, 1997-2005
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty.
|
||||
* In no event will the authors be held liable for any damages arising from
|
||||
@ -34,14 +34,7 @@
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <assert.h>
|
||||
|
||||
// this file does not include amxmodx.h, so we have to include the memory manager here
|
||||
#ifdef MEMORY_TEST
|
||||
#include "mmgr/mmgr.h"
|
||||
#endif // MEMORY_TEST
|
||||
|
||||
#include "amx.h"
|
||||
|
||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32 || defined _Windows
|
||||
#include <windows.h>
|
||||
#endif
|
||||
@ -60,14 +53,13 @@
|
||||
# define _tcscpy strcpy
|
||||
# define _tcsdup strdup
|
||||
# define _tcslen strlen
|
||||
# define _stprintf sprintf
|
||||
#endif
|
||||
|
||||
|
||||
#define CHARBITS (8*sizeof(char))
|
||||
typedef unsigned char uchar;
|
||||
|
||||
#if !defined NOPROPLIST
|
||||
#if !defined AMX_NOPROPLIST
|
||||
typedef struct _property_list {
|
||||
struct _property_list *next;
|
||||
cell id;
|
||||
@ -76,7 +68,7 @@ typedef struct _property_list {
|
||||
//??? safe AMX (owner of the property)
|
||||
} proplist;
|
||||
|
||||
static proplist proproot = { NULL };
|
||||
static proplist proproot = { NULL, 0, NULL, 0 };
|
||||
|
||||
static proplist *list_additem(proplist *root)
|
||||
{
|
||||
@ -142,15 +134,13 @@ static proplist *list_finditem(proplist *root,cell id,char *name,cell value,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
static cell AMX_NATIVE_CALL numargs(AMX *amx, cell *params)
|
||||
{
|
||||
AMX_HEADER *hdr;
|
||||
uchar *data;
|
||||
cell bytes;
|
||||
|
||||
(void)params;
|
||||
hdr=(AMX_HEADER *)amx->base;
|
||||
data=amx->data ? amx->data : amx->base+(int)hdr->dat;
|
||||
/* the number of bytes is on the stack, at "frm + 2*cell" */
|
||||
@ -190,18 +180,16 @@ static cell AMX_NATIVE_CALL setarg(AMX *amx, cell *params)
|
||||
/* adjust the address in "value" in case of an array access */
|
||||
value+=params[2]*sizeof(cell);
|
||||
/* verify the address */
|
||||
if (value<0 || (value>=amx->hea && value<amx->stk))
|
||||
if (value<0 || value>=amx->hea && value<amx->stk)
|
||||
return 0;
|
||||
/* set the value indirectly */
|
||||
* (cell *)(data+(int)value) = params[3];
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
static cell AMX_NATIVE_CALL heapspace(AMX *amx,cell *params)
|
||||
{
|
||||
(void)params;
|
||||
return amx->stk - amx->hea;
|
||||
}
|
||||
|
||||
@ -220,142 +208,22 @@ static cell AMX_NATIVE_CALL funcidx(AMX *amx,cell *params)
|
||||
return 0;
|
||||
} /* if */
|
||||
|
||||
amx_GetString(name,cstr,0);
|
||||
amx_GetString(name,cstr,0,UNLIMITED);
|
||||
err=amx_FindPublic(amx,name,&index);
|
||||
if (err!=AMX_ERR_NONE)
|
||||
index=-1; /* this is not considered a fatal error */
|
||||
return index;
|
||||
}
|
||||
|
||||
int amx_StrPack(cell *dest,cell *source)
|
||||
{
|
||||
int len;
|
||||
|
||||
amx_StrLen(source,&len);
|
||||
if ((ucell)*source>UNPACKEDMAX) {
|
||||
/* source string is already packed */
|
||||
while (len >= 0) {
|
||||
*dest++ = *source++;
|
||||
len-=sizeof(cell);
|
||||
} /* while */
|
||||
} else {
|
||||
/* pack string, from bottom up */
|
||||
cell c;
|
||||
int i;
|
||||
for (c=0,i=0; i<len; i++) {
|
||||
assert((*source & ~0xffL)==0);
|
||||
c=(c<<CHARBITS) | *source++;
|
||||
if (i%sizeof(cell) == sizeof(cell)-1) {
|
||||
*dest++=c;
|
||||
c=0;
|
||||
} /* if */
|
||||
} /* for */
|
||||
if (i%sizeof(cell) != 0) /* store remaining packed characters */
|
||||
*dest=c << (sizeof(cell)-i%sizeof(cell))*CHARBITS;
|
||||
else
|
||||
*dest=0; /* store full cell of zeros */
|
||||
} /* if */
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
int amx_StrUnpack(cell *dest,cell *source)
|
||||
{
|
||||
if ((ucell)*source>UNPACKEDMAX) {
|
||||
/* unpack string, from top down (so string can be unpacked in place) */
|
||||
cell c;
|
||||
int i,len;
|
||||
amx_StrLen(source,&len);
|
||||
dest[len]=0;
|
||||
for (i=len-1; i>=0; i--) {
|
||||
c=source[i/sizeof(cell)] >> (sizeof(cell)-i%sizeof(cell)-1)*CHARBITS;
|
||||
dest[i]=c & UCHAR_MAX;
|
||||
} /* for */
|
||||
} else {
|
||||
/* source string is already unpacked */
|
||||
while ((*dest++ = *source++) != 0)
|
||||
/* nothing */;
|
||||
} /* if */
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
static int verify_addr(AMX *amx,cell addr)
|
||||
{
|
||||
int err;
|
||||
cell *cdest;
|
||||
|
||||
err=amx_GetAddr(amx,addr,&cdest);
|
||||
if (err!=AMX_ERR_NONE)
|
||||
amx_RaiseError(amx,err);
|
||||
return err;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL core_strlen(AMX *amx,cell *params)
|
||||
{
|
||||
cell *cptr;
|
||||
int len = 0;
|
||||
|
||||
if (amx_GetAddr(amx,params[1],&cptr)==AMX_ERR_NONE)
|
||||
amx_StrLen(cptr,&len);
|
||||
return len;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL strpack(AMX *amx,cell *params)
|
||||
{
|
||||
cell *cdest,*csrc;
|
||||
int len,needed,err;
|
||||
size_t lastaddr;
|
||||
|
||||
/* calculate number of cells needed for (packed) destination */
|
||||
amx_GetAddr(amx,params[2],&csrc);
|
||||
amx_StrLen(csrc,&len);
|
||||
needed=(len+sizeof(cell))/sizeof(cell); /* # of cells needed */
|
||||
assert(needed>0);
|
||||
lastaddr=(size_t)(params[1]+sizeof(cell)*needed-1);
|
||||
if (verify_addr(amx,(cell)lastaddr)!=AMX_ERR_NONE)
|
||||
return 0;
|
||||
|
||||
amx_GetAddr(amx,params[1],&cdest);
|
||||
err=amx_StrPack(cdest,csrc);
|
||||
if (err!=AMX_ERR_NONE)
|
||||
return amx_RaiseError(amx,err);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL strunpack(AMX *amx,cell *params)
|
||||
{
|
||||
cell *cdest,*csrc;
|
||||
int len,err;
|
||||
size_t lastaddr;
|
||||
|
||||
/* calculate number of cells needed for (packed) destination */
|
||||
amx_GetAddr(amx,params[2],&csrc);
|
||||
amx_StrLen(csrc,&len);
|
||||
assert(len>=0);
|
||||
lastaddr=(size_t)(params[1]+sizeof(cell)*(len+1)-1);
|
||||
if (verify_addr(amx,(cell)lastaddr)!=AMX_ERR_NONE)
|
||||
return 0;
|
||||
|
||||
amx_GetAddr(amx,params[1],&cdest);
|
||||
err=amx_StrUnpack(cdest,csrc);
|
||||
if (err!=AMX_ERR_NONE)
|
||||
return amx_RaiseError(amx,err);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
static cell AMX_NATIVE_CALL swapchars(AMX *amx,cell *params)
|
||||
{
|
||||
union {
|
||||
cell c;
|
||||
#if SMALL_CELL_SIZE==16
|
||||
#if PAWN_CELL_SIZE==16
|
||||
uchar b[2];
|
||||
#elif SMALL_CELL_SIZE==32
|
||||
#elif PAWN_CELL_SIZE==32
|
||||
uchar b[4];
|
||||
#elif SMALL_CELL_SIZE==64
|
||||
#elif PAWN_CELL_SIZE==64
|
||||
uchar b[8];
|
||||
#else
|
||||
#error Unsupported cell size
|
||||
@ -363,20 +231,21 @@ static cell AMX_NATIVE_CALL swapchars(AMX *amx,cell *params)
|
||||
} value;
|
||||
uchar t;
|
||||
|
||||
(void)amx;
|
||||
assert((size_t)params[0]==sizeof(cell));
|
||||
value.c = params[1];
|
||||
#if SMALL_CELL_SIZE==16
|
||||
#if PAWN_CELL_SIZE==16
|
||||
t = value.b[0];
|
||||
value.b[0] = value.b[1];
|
||||
value.b[1] = t;
|
||||
#elif SMALL_CELL_SIZE==32
|
||||
#elif PAWN_CELL_SIZE==32
|
||||
t = value.b[0];
|
||||
value.b[0] = value.b[3];
|
||||
value.b[3] = t;
|
||||
t = value.b[1];
|
||||
value.b[1] = value.b[2];
|
||||
value.b[2] = t;
|
||||
#elif SMALL_CELL_SIZE==64
|
||||
#elif PAWN_CELL_SIZE==64
|
||||
t = value.b[0];
|
||||
value.b[0] = value.b[7];
|
||||
value.b[7] = t;
|
||||
@ -395,11 +264,9 @@ static cell AMX_NATIVE_CALL swapchars(AMX *amx,cell *params)
|
||||
return value.c;
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
static cell AMX_NATIVE_CALL core_tolower(AMX *amx,cell *params)
|
||||
{
|
||||
(void)amx;
|
||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32
|
||||
return (cell)CharLower((LPTSTR)params[1]);
|
||||
#elif defined _Windows
|
||||
@ -409,11 +276,9 @@ static cell AMX_NATIVE_CALL core_tolower(AMX *amx,cell *params)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
static cell AMX_NATIVE_CALL core_toupper(AMX *amx,cell *params)
|
||||
{
|
||||
(void)amx;
|
||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32
|
||||
return (cell)CharUpper((LPTSTR)params[1]);
|
||||
#elif defined _Windows
|
||||
@ -423,19 +288,15 @@ static cell AMX_NATIVE_CALL core_toupper(AMX *amx,cell *params)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
static cell AMX_NATIVE_CALL core_min(AMX *amx,cell *params)
|
||||
{
|
||||
(void)amx;
|
||||
return params[1] <= params[2] ? params[1] : params[2];
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
static cell AMX_NATIVE_CALL core_max(AMX *amx,cell *params)
|
||||
{
|
||||
(void)amx;
|
||||
return params[1] >= params[2] ? params[1] : params[2];
|
||||
}
|
||||
|
||||
@ -451,7 +312,7 @@ static cell AMX_NATIVE_CALL core_clamp(AMX *amx,cell *params)
|
||||
return value;
|
||||
}
|
||||
|
||||
#if !defined NOPROPLIST
|
||||
#if !defined AMX_NOPROPLIST
|
||||
static char *MakePackedString(cell *cptr)
|
||||
{
|
||||
int len;
|
||||
@ -459,10 +320,21 @@ static char *MakePackedString(cell *cptr)
|
||||
|
||||
amx_StrLen(cptr,&len);
|
||||
dest=(char *)malloc(len+sizeof(cell));
|
||||
amx_GetString(dest,cptr,0);
|
||||
amx_GetString(dest,cptr,0,UNLIMITED);
|
||||
return dest;
|
||||
}
|
||||
|
||||
static int verify_addr(AMX *amx,cell addr)
|
||||
{
|
||||
int err;
|
||||
cell *cdest;
|
||||
|
||||
err=amx_GetAddr(amx,addr,&cdest);
|
||||
if (err!=AMX_ERR_NONE)
|
||||
amx_RaiseError(amx,err);
|
||||
return err;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL getproperty(AMX *amx,cell *params)
|
||||
{
|
||||
cell *cstr;
|
||||
@ -480,7 +352,7 @@ static cell AMX_NATIVE_CALL getproperty(AMX *amx,cell *params)
|
||||
return 0;
|
||||
} /* if */
|
||||
amx_GetAddr(amx,params[4],&cstr);
|
||||
amx_SetString(cstr,item->name,1,0);
|
||||
amx_SetString(cstr,item->name,1,0,UNLIMITED);
|
||||
} /* if */
|
||||
free(name);
|
||||
return (item!=NULL) ? item->value : 0;
|
||||
@ -545,12 +417,14 @@ static cell AMX_NATIVE_CALL existproperty(AMX *amx,cell *params)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined AMX_NORANDOM
|
||||
/* This routine comes from the book "Inner Loops" by Rick Booth, Addison-Wesley
|
||||
* (ISBN 0-201-47960-5). This is a "multiplicative congruential random number
|
||||
* generator" that has been extended to 31-bits (the standard C version returns
|
||||
* only 15-bits).
|
||||
*/
|
||||
static unsigned long IL_StandardRandom_seed = 0L;
|
||||
#define INITIAL_SEED 0xcaa938dbL
|
||||
static unsigned long IL_StandardRandom_seed = INITIAL_SEED; /* always use a non-zero seed */
|
||||
#define IL_RMULT 1103515245L
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
@ -562,7 +436,7 @@ static cell AMX_NATIVE_CALL core_random(AMX *amx,cell *params)
|
||||
|
||||
/* one-time initialization (or, mostly one-time) */
|
||||
#if !defined SN_TARGET_PS2 && !defined _WIN32_WCE
|
||||
if (IL_StandardRandom_seed == 0L)
|
||||
if (IL_StandardRandom_seed == INITIAL_SEED)
|
||||
IL_StandardRandom_seed=(unsigned long)time(NULL);
|
||||
#endif
|
||||
|
||||
@ -579,6 +453,7 @@ static cell AMX_NATIVE_CALL core_random(AMX *amx,cell *params)
|
||||
result %= params[1];
|
||||
return (cell)result;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
AMX_NATIVE_INFO core_Natives[] = {
|
||||
@ -587,22 +462,13 @@ AMX_NATIVE_INFO core_Natives[] = {
|
||||
{ "setarg", setarg },
|
||||
{ "heapspace", heapspace },
|
||||
{ "funcidx", funcidx },
|
||||
{ "strlen", core_strlen },
|
||||
{ "strpack", strpack },
|
||||
{ "strunpack", strunpack },
|
||||
{ "swapchars", swapchars },
|
||||
{ "tolower", core_tolower },
|
||||
{ "toupper", core_toupper },
|
||||
{ "random", core_random },
|
||||
{ "min", core_min },
|
||||
{ "max", core_max },
|
||||
{ "clamp", core_clamp },
|
||||
#if !defined NOPROPLIST
|
||||
{ "getproperty", getproperty },
|
||||
{ "setproperty", setproperty },
|
||||
{ "deleteproperty",delproperty },
|
||||
{ "existproperty", existproperty },
|
||||
#endif
|
||||
{ "random", core_random },
|
||||
{ NULL, NULL } /* terminator */
|
||||
};
|
||||
|
||||
@ -611,12 +477,10 @@ int AMXEXPORT amx_CoreInit(AMX *amx)
|
||||
return amx_Register(amx, core_Natives, -1);
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
int AMXEXPORT amx_CoreCleanup(AMX *amx)
|
||||
{
|
||||
#if !defined NOPROPLIST
|
||||
(void)amx;
|
||||
#if !defined AMX_NOPROPLIST
|
||||
//??? delete only the properties owned by the AMX
|
||||
while (proproot.next!=NULL)
|
||||
list_delete(&proproot,proproot.next);
|
||||
|
498
amxmodx/amxdbg.cpp
Executable file
498
amxmodx/amxdbg.cpp
Executable file
@ -0,0 +1,498 @@
|
||||
/* Pawn debugger interface
|
||||
*
|
||||
* Support functions for debugger applications
|
||||
*
|
||||
* Copyright (c) ITB CompuPhase, 2005
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty.
|
||||
* In no event will the authors be held liable for any damages arising from
|
||||
* the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software in
|
||||
* a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include "osdefs.h" /* for _MAX_PATH */
|
||||
#include "amx.h"
|
||||
#include "amxdbg.h"
|
||||
|
||||
// this file does not include amxmodx.h, so we have to include the memory manager here
|
||||
#ifdef MEMORY_TEST
|
||||
#include "mmgr/mmgr.h"
|
||||
#endif // MEMORY_TEST
|
||||
|
||||
int AMXAPI dbg_FreeInfo(AMX_DBG *amxdbg)
|
||||
{
|
||||
assert(amxdbg != NULL);
|
||||
if (amxdbg->hdr != NULL)
|
||||
free(amxdbg->hdr);
|
||||
if (amxdbg->filetbl != NULL)
|
||||
free(amxdbg->filetbl);
|
||||
if (amxdbg->symboltbl != NULL)
|
||||
free(amxdbg->symboltbl);
|
||||
if (amxdbg->tagtbl != NULL)
|
||||
free(amxdbg->tagtbl);
|
||||
if (amxdbg->automatontbl != NULL)
|
||||
free(amxdbg->automatontbl);
|
||||
if (amxdbg->statetbl != NULL)
|
||||
free(amxdbg->statetbl);
|
||||
memset(amxdbg, 0, sizeof(AMX_DBG));
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
void memread(void *dest, char **src, size_t size)
|
||||
{
|
||||
void *ptr = *src;
|
||||
memcpy(dest, ptr, size);
|
||||
*src += size;
|
||||
}
|
||||
|
||||
const char *ClipFileName(const char *inp)
|
||||
{
|
||||
static char buffer[256];
|
||||
size_t len = strlen(inp);
|
||||
const char *ptr = inp;
|
||||
|
||||
for (size_t i=0; i<len; i++)
|
||||
{
|
||||
if ((inp[i] == '\\' || inp[i] == '/') && (i != len-1))
|
||||
ptr = inp + i + 1;
|
||||
}
|
||||
strcpy(buffer, ptr);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
//Note - I changed this function to read from memory instead.
|
||||
// -- BAILOPAN
|
||||
int AMXAPI dbg_LoadInfo(AMX_DBG *amxdbg, void *dbg_addr)
|
||||
{
|
||||
AMX_DBG_HDR dbghdr;
|
||||
unsigned char *ptr;
|
||||
int index, dim;
|
||||
AMX_DBG_SYMDIM *symdim;
|
||||
|
||||
assert(amxdbg != NULL);
|
||||
|
||||
char *addr = (char *)(dbg_addr);
|
||||
|
||||
memset(&dbghdr, 0, sizeof(AMX_DBG_HDR));
|
||||
memread(&dbghdr, &addr, sizeof(AMX_DBG_HDR));
|
||||
|
||||
//brabbby graa gragghty graaahhhh
|
||||
#if BYTE_ORDER==BIG_ENDIAN
|
||||
amx_Align32((uint32_t*)&dbghdr.size);
|
||||
amx_Align16(&dbghdr.magic);
|
||||
amx_Align16(&dbghdr.flags);
|
||||
amx_Align16(&dbghdr.files);
|
||||
amx_Align16(&dbghdr.lines);
|
||||
amx_Align16(&dbghdr.symbols);
|
||||
amx_Align16(&dbghdr.tags);
|
||||
amx_Align16(&dbghdr.automatons);
|
||||
amx_Align16(&dbghdr.states);
|
||||
#endif
|
||||
|
||||
if (dbghdr.magic != AMX_DBG_MAGIC)
|
||||
return AMX_ERR_FORMAT;
|
||||
|
||||
/* allocate all memory */
|
||||
memset(amxdbg, 0, sizeof(AMX_DBG));
|
||||
amxdbg->hdr = (AMX_DBG_HDR *)malloc((size_t)dbghdr.size);
|
||||
if (dbghdr.files > 0)
|
||||
amxdbg->filetbl = (AMX_DBG_FILE **)malloc(dbghdr.files * sizeof(AMX_DBG_FILE *));
|
||||
if (dbghdr.symbols > 0)
|
||||
amxdbg->symboltbl = (AMX_DBG_SYMBOL **)malloc(dbghdr.symbols * sizeof(AMX_DBG_SYMBOL *));
|
||||
if (dbghdr.tags > 0)
|
||||
amxdbg->tagtbl = (AMX_DBG_TAG **)malloc(dbghdr.tags * sizeof(AMX_DBG_TAG *));
|
||||
if (dbghdr.automatons > 0)
|
||||
amxdbg->automatontbl = (AMX_DBG_MACHINE **)malloc(dbghdr.automatons * sizeof(AMX_DBG_MACHINE *));
|
||||
if (dbghdr.states > 0)
|
||||
amxdbg->statetbl = (AMX_DBG_STATE **)malloc(dbghdr.states * sizeof(AMX_DBG_STATE *));
|
||||
if (amxdbg->hdr == NULL
|
||||
|| (dbghdr.files > 0 && amxdbg->filetbl == NULL)
|
||||
|| (dbghdr.symbols > 0 && amxdbg->symboltbl == NULL)
|
||||
|| (dbghdr.tags > 0 && amxdbg->tagtbl == NULL)
|
||||
|| (dbghdr.states > 0 && amxdbg->statetbl == NULL)
|
||||
|| (dbghdr.automatons > 0 && amxdbg->automatontbl == NULL))
|
||||
{
|
||||
dbg_FreeInfo(amxdbg);
|
||||
return AMX_ERR_MEMORY;
|
||||
} /* if */
|
||||
|
||||
/* load the entire symbolic information block into memory */
|
||||
memcpy(amxdbg->hdr, &dbghdr, sizeof dbghdr);
|
||||
ptr = (unsigned char *)(amxdbg->hdr + 1);
|
||||
memread(ptr, &addr, (size_t)(dbghdr.size-sizeof(dbghdr)));
|
||||
|
||||
/* file table */
|
||||
for (index = 0; index < dbghdr.files; index++) {
|
||||
assert(amxdbg->filetbl != NULL);
|
||||
amxdbg->filetbl[index] = (AMX_DBG_FILE *)ptr;
|
||||
#if BYTE_ORDER==BIG_ENDIAN
|
||||
amx_AlignCell(&amxdbg->filetbl[index]->address);
|
||||
#endif
|
||||
for (ptr = ptr + sizeof(AMX_DBG_FILE); *ptr != '\0'; ptr++)
|
||||
/* nothing */;
|
||||
ptr++; /* skip '\0' too */
|
||||
} /* for */
|
||||
|
||||
//debug("Files: %d\n", amxdbg->hdr->files);
|
||||
for (index=0;index<amxdbg->hdr->files; index++)
|
||||
{
|
||||
strcpy((char *)amxdbg->filetbl[index]->name, ClipFileName(amxdbg->filetbl[index]->name));
|
||||
//debug(" [%d] %s\n", index, amxdbg->filetbl[index]->name);
|
||||
}
|
||||
|
||||
/* line table */
|
||||
amxdbg->linetbl = (AMX_DBG_LINE*)ptr;
|
||||
#if BYTE_ORDER==BIG_ENDIAN
|
||||
for (index = 0; index < dbghdr.lines; index++) {
|
||||
amx_AlignCell(&amxdbg->linetbl[index].address);
|
||||
amx_Align32((uint32_t*)&amxdbg->linetbl[index].line);
|
||||
} /* for */
|
||||
#endif
|
||||
ptr += dbghdr.lines * sizeof(AMX_DBG_LINE);
|
||||
|
||||
/* symbol table (plus index tags) */
|
||||
for (index = 0; index < dbghdr.symbols; index++) {
|
||||
assert(amxdbg->symboltbl != NULL);
|
||||
amxdbg->symboltbl[index] = (AMX_DBG_SYMBOL *)ptr;
|
||||
#if BYTE_ORDER==BIG_ENDIAN
|
||||
amx_AlignCell(&amxdbg->symboltbl[index]->address);
|
||||
amx_Align16((uint16_t*)&amxdbg->symboltbl[index]->tag);
|
||||
amx_AlignCell(&amxdbg->symboltbl[index]->codestart);
|
||||
amx_AlignCell(&amxdbg->symboltbl[index]->codeend);
|
||||
amx_Align16((uint16_t*)&amxdbg->symboltbl[index]->dim);
|
||||
#endif
|
||||
for (ptr = ptr + sizeof(AMX_DBG_SYMBOL); *ptr != '\0'; ptr++)
|
||||
/* nothing */;
|
||||
ptr++; /* skip '\0' too */
|
||||
for (dim = 0; dim < amxdbg->symboltbl[index]->dim; dim++) {
|
||||
symdim = (AMX_DBG_SYMDIM *)ptr;
|
||||
amx_Align16((uint16_t*)&symdim->tag);
|
||||
amx_AlignCell(&symdim->size);
|
||||
ptr += sizeof(AMX_DBG_SYMDIM);
|
||||
} /* for */
|
||||
} /* for */
|
||||
|
||||
/* tag name table */
|
||||
for (index = 0; index < dbghdr.tags; index++) {
|
||||
assert(amxdbg->tagtbl != NULL);
|
||||
amxdbg->tagtbl[index] = (AMX_DBG_TAG *)ptr;
|
||||
#if BYTE_ORDER==BIG_ENDIAN
|
||||
amx_Align16(&amxdbg->tagtbl[index]->tag);
|
||||
#endif
|
||||
for (ptr = ptr + sizeof(AMX_DBG_TAG) - 1; *ptr != '\0'; ptr++)
|
||||
/* nothing */;
|
||||
ptr++; /* skip '\0' too */
|
||||
} /* for */
|
||||
|
||||
/* automaton name table */
|
||||
for (index = 0; index < dbghdr.automatons; index++) {
|
||||
assert(amxdbg->automatontbl != NULL);
|
||||
amxdbg->automatontbl[index] = (AMX_DBG_MACHINE *)ptr;
|
||||
#if BYTE_ORDER==BIG_ENDIAN
|
||||
amx_Align16(&amxdbg->automatontbl[index]->automaton);
|
||||
amx_AlignCell(&amxdbg->automatontbl[index]->address);
|
||||
#endif
|
||||
for (ptr = ptr + sizeof(AMX_DBG_MACHINE) - 1; *ptr != '\0'; ptr++)
|
||||
/* nothing */;
|
||||
ptr++; /* skip '\0' too */
|
||||
} /* for */
|
||||
|
||||
/* state name table */
|
||||
for (index = 0; index < dbghdr.states; index++) {
|
||||
assert(amxdbg->statetbl != NULL);
|
||||
amxdbg->statetbl[index] = (AMX_DBG_STATE *)ptr;
|
||||
#if BYTE_ORDER==BIG_ENDIAN
|
||||
amx_Align16(&amxdbg->statetbl[index]->state);
|
||||
amx_Align16(&amxdbg->automatontbl[index]->automaton);
|
||||
#endif
|
||||
for (ptr = ptr + sizeof(AMX_DBG_STATE) - 1; *ptr != '\0'; ptr++)
|
||||
/* nothing */;
|
||||
ptr++; /* skip '\0' too */
|
||||
} /* for */
|
||||
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
int AMXAPI dbg_LookupFile(AMX_DBG *amxdbg, ucell address, const char **filename)
|
||||
{
|
||||
int index;
|
||||
|
||||
assert(amxdbg != NULL);
|
||||
assert(filename != NULL);
|
||||
*filename = NULL;
|
||||
/* this is a simple linear look-up; a binary search would be possible too */
|
||||
for (index = 0; index < amxdbg->hdr->files && amxdbg->filetbl[index]->address <= address; index++)
|
||||
/* nothing */;
|
||||
/* reset for overrun */
|
||||
if (--index < 0)
|
||||
return AMX_ERR_NOTFOUND;
|
||||
|
||||
*filename = amxdbg->filetbl[index]->name;
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
int AMXAPI dbg_LookupLine(AMX_DBG *amxdbg, ucell address, long *line)
|
||||
{
|
||||
int index;
|
||||
|
||||
assert(amxdbg != NULL);
|
||||
assert(line != NULL);
|
||||
*line = 0;
|
||||
/* this is a simple linear look-up; a binary search would be possible too */
|
||||
for (index = 0; index < amxdbg->hdr->lines && amxdbg->linetbl[index].address <= address; index++)
|
||||
/* nothing */;
|
||||
/* reset for overrun */
|
||||
if (--index < 0)
|
||||
return AMX_ERR_NOTFOUND;
|
||||
|
||||
*line = (long)amxdbg->linetbl[index].line;
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
int AMXAPI dbg_LookupFunction(AMX_DBG *amxdbg, ucell address, const char **funcname)
|
||||
{
|
||||
/* dbg_LookupFunction() finds the function a code address is in. It can be
|
||||
* used for stack walking, and for stepping through a function while stepping
|
||||
* over sub-functions
|
||||
*/
|
||||
int index;
|
||||
|
||||
assert(amxdbg != NULL);
|
||||
assert(funcname != NULL);
|
||||
*funcname = NULL;
|
||||
for (index = 0; index < amxdbg->hdr->symbols; index++) {
|
||||
if (amxdbg->symboltbl[index]->ident == iFUNCTN
|
||||
&& amxdbg->symboltbl[index]->codestart <= address
|
||||
&& amxdbg->symboltbl[index]->codeend > address)
|
||||
break;
|
||||
} /* for */
|
||||
if (index >= amxdbg->hdr->symbols)
|
||||
return AMX_ERR_NOTFOUND;
|
||||
|
||||
*funcname = amxdbg->symboltbl[index]->name;
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
int AMXAPI dbg_GetTagName(AMX_DBG *amxdbg, int tag, const char **name)
|
||||
{
|
||||
int index;
|
||||
|
||||
assert(amxdbg != NULL);
|
||||
assert(name != NULL);
|
||||
*name = NULL;
|
||||
for (index = 0; index < amxdbg->hdr->tags && amxdbg->tagtbl[index]->tag != tag; index++)
|
||||
/* nothing */;
|
||||
if (index >= amxdbg->hdr->tags)
|
||||
return AMX_ERR_NOTFOUND;
|
||||
|
||||
*name = amxdbg->tagtbl[index]->name;
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
int AMXAPI dbg_GetAutomatonName(AMX_DBG *amxdbg, int automaton, const char **name)
|
||||
{
|
||||
int index;
|
||||
|
||||
assert(amxdbg != NULL);
|
||||
assert(name != NULL);
|
||||
*name = NULL;
|
||||
for (index = 0; index < amxdbg->hdr->automatons && amxdbg->automatontbl[index]->automaton != automaton; index++)
|
||||
/* nothing */;
|
||||
if (index >= amxdbg->hdr->automatons)
|
||||
return AMX_ERR_NOTFOUND;
|
||||
|
||||
*name = amxdbg->automatontbl[index]->name;
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
int AMXAPI dbg_GetStateName(AMX_DBG *amxdbg, int state, const char **name)
|
||||
{
|
||||
int index;
|
||||
|
||||
assert(amxdbg != NULL);
|
||||
assert(name != NULL);
|
||||
*name = NULL;
|
||||
for (index = 0; index < amxdbg->hdr->states && amxdbg->statetbl[index]->state != state; index++)
|
||||
/* nothing */;
|
||||
if (index >= amxdbg->hdr->states)
|
||||
return AMX_ERR_NOTFOUND;
|
||||
|
||||
*name = amxdbg->statetbl[index]->name;
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
int AMXAPI dbg_GetLineAddress(AMX_DBG *amxdbg, long line, const char *filename, ucell *address)
|
||||
{
|
||||
/* Find a suitable "breakpoint address" close to the indicated line (and in
|
||||
* the specified file). The address is moved up to the next "breakable" line
|
||||
* if no "breakpoint" is available on the specified line. You can use function
|
||||
* dbg_LookupLine() to find out at which precise line the breakpoint was set.
|
||||
*
|
||||
* The filename comparison is strict (case sensitive and path sensitive); the
|
||||
* "filename" parameter should point into the "filetbl" of the AMX_DBG
|
||||
* structure.
|
||||
*/
|
||||
int file, index;
|
||||
ucell bottomaddr,topaddr;
|
||||
|
||||
assert(amxdbg != NULL);
|
||||
assert(filename != NULL);
|
||||
assert(address != NULL);
|
||||
*address = 0;
|
||||
|
||||
index = 0;
|
||||
for (file = 0; file < amxdbg->hdr->files; file++) {
|
||||
/* find the (next) mathing instance of the file */
|
||||
if (strcmp(amxdbg->filetbl[file]->name, filename) != 0)
|
||||
continue;
|
||||
/* get address range for the current file */
|
||||
bottomaddr = amxdbg->filetbl[file]->address;
|
||||
topaddr = (file + 1 < amxdbg->hdr->files) ? amxdbg->filetbl[file+1]->address : (ucell)(cell)-1;
|
||||
/* go to the starting address in the line table */
|
||||
while (index < amxdbg->hdr->lines && amxdbg->linetbl[index].address < bottomaddr)
|
||||
index++;
|
||||
/* browse until the line is found or until the top address is exceeded */
|
||||
while (index < amxdbg->hdr->lines
|
||||
&& amxdbg->linetbl[index].line < line
|
||||
&& amxdbg->linetbl[index].address < topaddr)
|
||||
index++;
|
||||
if (index >= amxdbg->hdr->lines)
|
||||
return AMX_ERR_NOTFOUND;
|
||||
if (amxdbg->linetbl[index].line >= line)
|
||||
break;
|
||||
/* if not found (and the line table is not yet exceeded) try the next
|
||||
* instance of the same file (a file may appear twice in the file table)
|
||||
*/
|
||||
} /* for */
|
||||
|
||||
if (strcmp(amxdbg->filetbl[file]->name, filename) != 0)
|
||||
return AMX_ERR_NOTFOUND;
|
||||
|
||||
assert(index < amxdbg->hdr->lines);
|
||||
*address = amxdbg->linetbl[index].address;
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
int AMXAPI dbg_GetFunctionAddress(AMX_DBG *amxdbg, const char *funcname, const char *filename, ucell *address)
|
||||
{
|
||||
/* Find a suitable "breakpoint address" close to the indicated line (and in
|
||||
* the specified file). The address is moved up to the first "breakable" line
|
||||
* in the function. You can use function dbg_LookupLine() to find out at which
|
||||
* precise line the breakpoint was set.
|
||||
*
|
||||
* The filename comparison is strict (case sensitive and path sensitive); the
|
||||
* "filename" parameter should point into the "filetbl" of the AMX_DBG
|
||||
* structure. The function name comparison is case sensitive too.
|
||||
*/
|
||||
int index, err;
|
||||
const char *tgtfile;
|
||||
ucell funcaddr;
|
||||
|
||||
assert(amxdbg != NULL);
|
||||
assert(funcname != NULL);
|
||||
assert(filename != NULL);
|
||||
assert(address != NULL);
|
||||
*address = 0;
|
||||
|
||||
index = 0;
|
||||
for ( ;; ) {
|
||||
/* find (next) matching function */
|
||||
while (index < amxdbg->hdr->symbols
|
||||
&& (amxdbg->symboltbl[index]->ident != iFUNCTN || strcmp(amxdbg->symboltbl[index]->name, funcname) != 0))
|
||||
index++;
|
||||
if (index >= amxdbg->hdr->symbols)
|
||||
return AMX_ERR_NOTFOUND;
|
||||
/* verify that this line falls in the appropriate file */
|
||||
err = dbg_LookupFile(amxdbg, amxdbg->symboltbl[index]->address, &tgtfile);
|
||||
if (err == AMX_ERR_NONE || strcmp(filename, tgtfile) == 0)
|
||||
break;
|
||||
index++; /* line is the wrong file, search further */
|
||||
} /* for */
|
||||
|
||||
/* now find the first line in the function where we can "break" on */
|
||||
assert(index < amxdbg->hdr->symbols);
|
||||
funcaddr = amxdbg->symboltbl[index]->address;
|
||||
for (index = 0; index < amxdbg->hdr->lines && amxdbg->linetbl[index].address < funcaddr; index++)
|
||||
/* nothing */;
|
||||
|
||||
if (index >= amxdbg->hdr->lines)
|
||||
return AMX_ERR_NOTFOUND;
|
||||
*address = amxdbg->linetbl[index].address;
|
||||
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
int AMXAPI dbg_GetVariable(AMX_DBG *amxdbg, const char *symname, ucell scopeaddr, const AMX_DBG_SYMBOL **sym)
|
||||
{
|
||||
ucell codestart,codeend;
|
||||
int index;
|
||||
|
||||
assert(amxdbg != NULL);
|
||||
assert(symname != NULL);
|
||||
assert(sym != NULL);
|
||||
*sym = NULL;
|
||||
|
||||
codestart = codeend = 0;
|
||||
index = 0;
|
||||
for ( ;; ) {
|
||||
/* find (next) matching variable */
|
||||
while (index < amxdbg->hdr->symbols
|
||||
&& (amxdbg->symboltbl[index]->ident == iFUNCTN || strcmp(amxdbg->symboltbl[index]->name, symname) != 0)
|
||||
&& (amxdbg->symboltbl[index]->codestart > scopeaddr || amxdbg->symboltbl[index]->codeend < scopeaddr))
|
||||
index++;
|
||||
if (index >= amxdbg->hdr->symbols)
|
||||
break;
|
||||
/* check the range, keep a pointer to the symbol with the smallest range */
|
||||
if (strcmp(amxdbg->symboltbl[index]->name, symname) == 0
|
||||
&& (codestart == 0 && codeend == 0
|
||||
|| amxdbg->symboltbl[index]->codestart >= codestart && amxdbg->symboltbl[index]->codeend <= codeend))
|
||||
{
|
||||
*sym = amxdbg->symboltbl[index];
|
||||
codestart = amxdbg->symboltbl[index]->codestart;
|
||||
codeend = amxdbg->symboltbl[index]->codeend;
|
||||
} /* if */
|
||||
index++;
|
||||
} /* for */
|
||||
|
||||
return (*sym == NULL) ? AMX_ERR_NOTFOUND : AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
int AMXAPI dbg_GetArrayDim(AMX_DBG *amxdbg, const AMX_DBG_SYMBOL *sym, const AMX_DBG_SYMDIM **symdim)
|
||||
{
|
||||
/* retrieves a pointer to the array dimensions structures of an array symbol */
|
||||
const char *ptr;
|
||||
|
||||
assert(amxdbg != NULL);
|
||||
assert(sym != NULL);
|
||||
assert(symdim != NULL);
|
||||
*symdim = NULL;
|
||||
|
||||
if (sym->ident != iARRAY && sym->ident != iREFARRAY)
|
||||
return AMX_ERR_PARAMS;
|
||||
assert(sym->dim > 0); /* array must have at least one dimension */
|
||||
|
||||
/* find the end of the symbol name */
|
||||
for (ptr = sym->name; *ptr != '\0'; ptr++)
|
||||
/* nothing */;
|
||||
*symdim = (AMX_DBG_SYMDIM *)(ptr + 1);/* skip '\0' too */
|
||||
|
||||
return AMX_ERR_NONE;
|
||||
}
|
172
amxmodx/amxdbg.h
Executable file
172
amxmodx/amxdbg.h
Executable file
@ -0,0 +1,172 @@
|
||||
/* Abstract Machine for the Pawn compiler, debugger support
|
||||
*
|
||||
* This file contains extra definitions that are convenient for debugger
|
||||
* support.
|
||||
*
|
||||
* Copyright (c) ITB CompuPhase, 2005
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty.
|
||||
* In no event will the authors be held liable for any damages arising from
|
||||
* the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software in
|
||||
* a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#ifndef AMXDBG_H_INCLUDED
|
||||
#define AMXDBG_H_INCLUDED
|
||||
|
||||
#ifndef AMX_H_INCLUDED
|
||||
#include "amx.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Some compilers do not support the #pragma align, which should be fine. Some
|
||||
* compilers give a warning on unknown #pragmas, which is not so fine...
|
||||
*/
|
||||
#if defined SN_TARGET_PS2 || defined __GNUC__
|
||||
#define AMX_NO_ALIGN
|
||||
#endif
|
||||
|
||||
#if defined __GNUC__
|
||||
#define PACKED __attribute__((packed))
|
||||
#else
|
||||
#define PACKED
|
||||
#endif
|
||||
|
||||
#if !defined AMX_NO_ALIGN
|
||||
#if defined LINUX || defined __FreeBSD__
|
||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||
#elif defined MACOS && defined __MWERKS__
|
||||
#pragma options align=mac68k
|
||||
#else
|
||||
#pragma pack(push)
|
||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||
#if defined __TURBOC__
|
||||
#pragma option -a- /* "pack" pragma for older Borland compilers */
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct tagAMX_DBG_HDR {
|
||||
int32_t size PACKED; /* size of the debug information chunk */
|
||||
uint16_t magic PACKED; /* signature, must be 0xf1ef */
|
||||
char file_version PACKED; /* file format version */
|
||||
char amx_version PACKED; /* required version of the AMX */
|
||||
int16_t flags PACKED; /* currently unused */
|
||||
int16_t files PACKED; /* number of entries in the "file" table */
|
||||
int16_t lines PACKED; /* number of entries in the "line" table */
|
||||
int16_t symbols PACKED; /* number of entries in the "symbol" table */
|
||||
int16_t tags PACKED; /* number of entries in the "tag" table */
|
||||
int16_t automatons PACKED; /* number of entries in the "automaton" table */
|
||||
int16_t states PACKED; /* number of entries in the "state" table */
|
||||
} AMX_DBG_HDR PACKED;
|
||||
#define AMX_DBG_MAGIC 0xf1ef
|
||||
|
||||
typedef struct tagAMX_DBG_FILE {
|
||||
ucell address PACKED; /* address in the code segment where generated code (for this file) starts */
|
||||
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
||||
} AMX_DBG_FILE PACKED;
|
||||
|
||||
typedef struct tagAMX_DBG_LINE {
|
||||
ucell address PACKED; /* address in the code segment where generated code (for this line) starts */
|
||||
int32_t line PACKED; /* line number */
|
||||
} AMX_DBG_LINE PACKED;
|
||||
|
||||
typedef struct tagAMX_DBG_SYMBOL {
|
||||
ucell address PACKED; /* address in the data segment or relative to the frame */
|
||||
int16_t tag PACKED; /* tag for the symbol */
|
||||
ucell codestart PACKED; /* address in the code segment from which this symbol is valid (in scope) */
|
||||
ucell codeend PACKED; /* address in the code segment until which this symbol is valid (in scope) */
|
||||
char ident PACKED; /* kind of symbol (function/variable) */
|
||||
char vclass PACKED; /* class of symbol (global/local) */
|
||||
int16_t dim PACKED; /* number of dimensions */
|
||||
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
||||
} AMX_DBG_SYMBOL PACKED;
|
||||
|
||||
typedef struct tagAMX_DBG_SYMDIM {
|
||||
int16_t tag PACKED; /* tag for the array dimension */
|
||||
ucell size PACKED; /* size of the array dimension */
|
||||
} AMX_DBG_SYMDIM PACKED;
|
||||
|
||||
typedef struct tagAMX_DBG_TAG {
|
||||
int16_t tag PACKED; /* tag id */
|
||||
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
||||
} AMX_DBG_TAG PACKED;
|
||||
|
||||
typedef struct tagAMX_DBG_MACHINE {
|
||||
int16_t automaton PACKED; /* automaton id */
|
||||
ucell address PACKED; /* address of state variable */
|
||||
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
||||
} AMX_DBG_MACHINE PACKED;
|
||||
|
||||
typedef struct tagAMX_DBG_STATE {
|
||||
int16_t state PACKED; /* state id */
|
||||
int16_t automaton PACKED; /* automaton id */
|
||||
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
||||
} AMX_DBG_STATE PACKED;
|
||||
|
||||
typedef struct tagAMX_DBG {
|
||||
AMX_DBG_HDR _FAR *hdr PACKED; /* points to the AMX_DBG header */
|
||||
AMX_DBG_FILE _FAR **filetbl PACKED;
|
||||
AMX_DBG_LINE _FAR *linetbl PACKED;
|
||||
AMX_DBG_SYMBOL _FAR **symboltbl PACKED;
|
||||
AMX_DBG_TAG _FAR **tagtbl PACKED;
|
||||
AMX_DBG_MACHINE _FAR **automatontbl PACKED;
|
||||
AMX_DBG_STATE _FAR **statetbl PACKED;
|
||||
} AMX_DBG PACKED;
|
||||
|
||||
#if !defined iVARIABLE
|
||||
#define iVARIABLE 1 /* cell that has an address and that can be fetched directly (lvalue) */
|
||||
#define iREFERENCE 2 /* iVARIABLE, but must be dereferenced */
|
||||
#define iARRAY 3
|
||||
#define iREFARRAY 4 /* an array passed by reference (i.e. a pointer) */
|
||||
#define iFUNCTN 9
|
||||
#endif
|
||||
|
||||
|
||||
int AMXAPI dbg_FreeInfo(AMX_DBG *amxdbg);
|
||||
int AMXAPI dbg_LoadInfo(AMX_DBG *amxdbg, void *dbg_addr);
|
||||
|
||||
int AMXAPI dbg_LookupFile(AMX_DBG *amxdbg, ucell address, const char **filename);
|
||||
int AMXAPI dbg_LookupFunction(AMX_DBG *amxdbg, ucell address, const char **funcname);
|
||||
int AMXAPI dbg_LookupLine(AMX_DBG *amxdbg, ucell address, long *line);
|
||||
|
||||
int AMXAPI dbg_GetFunctionAddress(AMX_DBG *amxdbg, const char *funcname, const char *filename, ucell *address);
|
||||
int AMXAPI dbg_GetLineAddress(AMX_DBG *amxdbg, long line, const char *filename, ucell *address);
|
||||
int AMXAPI dbg_GetAutomatonName(AMX_DBG *amxdbg, int automaton, const char **name);
|
||||
int AMXAPI dbg_GetStateName(AMX_DBG *amxdbg, int state, const char **name);
|
||||
int AMXAPI dbg_GetTagName(AMX_DBG *amxdbg, int tag, const char **name);
|
||||
int AMXAPI dbg_GetVariable(AMX_DBG *amxdbg, const char *symname, ucell scopeaddr, const AMX_DBG_SYMBOL **sym);
|
||||
int AMXAPI dbg_GetArrayDim(AMX_DBG *amxdbg, const AMX_DBG_SYMBOL *sym, const AMX_DBG_SYMDIM **symdim);
|
||||
|
||||
|
||||
#if !defined AMX_NO_ALIGN
|
||||
#if defined LINUX || defined __FreeBSD__
|
||||
#pragma pack() /* reset default packing */
|
||||
#elif defined MACOS && defined __MWERKS__
|
||||
#pragma options align=reset
|
||||
#else
|
||||
#pragma pack(pop) /* reset previous packing */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AMXDBG_H_INCLUDED */
|
86
amxmodx/amxdefn.asm
Executable file
86
amxmodx/amxdefn.asm
Executable file
@ -0,0 +1,86 @@
|
||||
; Definition of the AMX structure for assembler syntax (NASM)
|
||||
|
||||
struc amx_s
|
||||
_base: resd 1
|
||||
_dataseg: resd 1
|
||||
_callback: resd 1
|
||||
_debug: resd 1
|
||||
_cip: resd 1
|
||||
_frm: resd 1
|
||||
_hea: resd 1
|
||||
_hlw: resd 1
|
||||
_stk: resd 1
|
||||
_stp: resd 1
|
||||
_flags: resd 1
|
||||
_usertags: resd 4 ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_userdata: resd 4 ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_error: resd 1
|
||||
_paramcount: resd 1
|
||||
_pri: resd 1
|
||||
_alt: resd 1
|
||||
_reset_stk: resd 1
|
||||
_reset_hea: resd 1
|
||||
_syscall_d: resd 1
|
||||
%ifdef JIT
|
||||
; the two fields below are for the JIT; they do not exist in
|
||||
; the non-JIT version of the abstract machine
|
||||
_reloc_size: resd 1 ; memory block for relocations
|
||||
_code_size: resd 1 ; memory size of the native code
|
||||
%endif
|
||||
endstruc
|
||||
|
||||
struc amxhead_s
|
||||
_size: resd 1 ; size of the "file"
|
||||
_magic: resw 1 ; signature
|
||||
_file_version: resb 1; file format version
|
||||
_amx_version: resb 1 ; required version of the AMX
|
||||
_h_flags: resw 1
|
||||
_defsize: resw 1 ; size of one public/native function entry
|
||||
_cod: resd 1 ; initial value of COD - code block
|
||||
_dat: resd 1 ; initial value of DAT - data block
|
||||
_h_hea: resd 1 ; initial value of HEA - start of the heap
|
||||
_h_stp: resd 1 ; initial value of STP - stack top
|
||||
_h_cip: resd 1 ; initial value of CIP - the instruction pointer
|
||||
_publics: resd 1 ; offset to the "public functions" table
|
||||
_natives: resd 1 ; offset to the "native functions" table
|
||||
_libraries: resd 1 ; offset to the "library" table
|
||||
_pubvars: resd 1 ; offset to the "public variables" table
|
||||
_tags: resd 1 ; offset to the "public tagnames" table
|
||||
_nametable: resd 1 ; offset to the name table, file version 7 only
|
||||
endstruc
|
||||
|
||||
|
||||
AMX_ERR_NONE EQU 0
|
||||
AMX_ERR_EXIT EQU 1
|
||||
AMX_ERR_ASSERT EQU 2
|
||||
AMX_ERR_STACKERR EQU 3
|
||||
AMX_ERR_BOUNDS EQU 4
|
||||
AMX_ERR_MEMACCESS EQU 5
|
||||
AMX_ERR_INVINSTR EQU 6
|
||||
AMX_ERR_STACKLOW EQU 7
|
||||
AMX_ERR_HEAPLOW EQU 8
|
||||
AMX_ERR_CALLBACK EQU 9
|
||||
AMX_ERR_NATIVE EQU 10
|
||||
AMX_ERR_DIVIDE EQU 11 ; for catching divide errors
|
||||
AMX_ERR_SLEEP EQU 12
|
||||
|
||||
AMX_ERR_MEMORY EQU 16
|
||||
AMX_ERR_FORMAT EQU 17
|
||||
AMX_ERR_VERSION EQU 18
|
||||
AMX_ERR_NOTFOUND EQU 19
|
||||
AMX_ERR_INDEX EQU 20
|
||||
AMX_ERR_DEBUG EQU 21
|
||||
AMX_ERR_INIT EQU 22
|
||||
AMX_ERR_USERDATA EQU 23
|
||||
AMX_ERR_INIT_JIT EQU 24
|
||||
AMX_ERR_PARAMS EQU 25
|
||||
AMX_ERR_DOMAIN EQU 26
|
||||
AMX_ERR_GENERAL EQU 27
|
||||
|
||||
AMX_FLAG_DEBUG EQU 0002h ; symbolic info. available
|
||||
AMX_FLAG_COMPACT EQU 0004h
|
||||
AMX_FLAG_BYTEOPC EQU 0008h
|
||||
AMX_FLAG_NOCHECKS EQU 0010h
|
||||
AMX_FLAG_BROWSE EQU 4000h
|
||||
AMX_FLAG_RELOC EQU 8000h ; jump/call addresses relocated
|
||||
|
@ -1,4 +1,4 @@
|
||||
; AMXEXECN.ASM Abstract Machine for the "Small" language
|
||||
; AMXEXECN.ASM Abstract Machine for the "Pawn" language
|
||||
;
|
||||
|
||||
;Some notes:
|
||||
@ -25,7 +25,7 @@
|
||||
;
|
||||
;Copyright and license of use, please read
|
||||
;-----------------------------------------
|
||||
;The assembler implementation of the abstract machine for the Small language,
|
||||
;The assembler implementation of the abstract machine for the Pawn language,
|
||||
;specifically the file AMXEXEC.ASM, is copyright (c) 1998-2000 by Marc Peter.
|
||||
;
|
||||
;Permission is hereby granted, without written agreement and without paid
|
||||
@ -56,6 +56,8 @@
|
||||
;
|
||||
;History (list of changes)
|
||||
;-------------------------
|
||||
; 17 february 2005 by Thiadmer Riemersms
|
||||
; Addition of the BREAK opcode, removal of the older debugging opcode table.
|
||||
; 6 march 2004 by Thiadmer Riemersma
|
||||
; Corrected a bug in OP_FILL, where a cell preceding the array would
|
||||
; be overwritten (zero'ed out). This bug was brought to my attention
|
||||
@ -95,92 +97,7 @@
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
|
||||
; I could not get NASM's structure definition to work (it appears to confuse
|
||||
; ENDSTRUC with "end segment"). So the definition below uses constants for
|
||||
; the field offsets.
|
||||
;amx_s STRUC
|
||||
_base EQU 00h ;DD ?
|
||||
_dataseg EQU 04h ;DD ?
|
||||
_callback EQU 08h ;DD ?
|
||||
_debug EQU 0ch ;DD ?
|
||||
_cip EQU 10h ;DD ?
|
||||
_frm EQU 14h ;DD ?
|
||||
_hea EQU 18h ;DD ?
|
||||
_hlw EQU 1ch ;DD ?
|
||||
_stk EQU 20h ;DD ?
|
||||
_stp EQU 24h ;DD ?
|
||||
_flags EQU 28h ;DD ?
|
||||
_curline EQU 2ch ;DD ?
|
||||
_curfile EQU 30h ;DD ?
|
||||
_dbgcode EQU 34h ;DD ?
|
||||
_dbgaddr EQU 38h ;DD ?
|
||||
_dbgparam EQU 3ch ;DD ?
|
||||
_dbgname EQU 40h ;DD ?
|
||||
_usertags1 EQU 44h ;DD 4 DUP (?) ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_usertags2 EQU 44h ;DD 4 DUP (?) ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_usertags3 EQU 44h ;DD 4 DUP (?) ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_usertags4 EQU 44h ;DD 4 DUP (?) ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_userdata1 EQU 54h ;DD 4 DUP (?) ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_userdata2 EQU 54h ;DD 4 DUP (?) ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_userdata3 EQU 54h ;DD 4 DUP (?) ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_userdata4 EQU 54h ;DD 4 DUP (?) ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_error EQU 64h ;DD ?
|
||||
_pri EQU 68h ;DD ?
|
||||
_alt EQU 6ch ;DD ?
|
||||
_reset_stk EQU 70h ;DD ?
|
||||
_reset_hea EQU 74h ;DD ?
|
||||
_syscall_d EQU 78h ;DD ?
|
||||
; the two fields below are for the JIT; they do not exist in
|
||||
; the non-JIT version of the abstract machine
|
||||
; _reloc_size EQU 7ch ;DD ? ; memory block for relocations
|
||||
; _code_size EQU 80h ;DD ? ; memory size of the native code
|
||||
;amx_s ENDS
|
||||
|
||||
|
||||
AMX_ERR_NONE EQU 0
|
||||
AMX_ERR_EXIT EQU 1
|
||||
AMX_ERR_ASSERT EQU 2
|
||||
AMX_ERR_STACKERR EQU 3
|
||||
AMX_ERR_BOUNDS EQU 4
|
||||
AMX_ERR_MEMACCESS EQU 5
|
||||
AMX_ERR_INVINSTR EQU 6
|
||||
AMX_ERR_STACKLOW EQU 7
|
||||
AMX_ERR_HEAPLOW EQU 8
|
||||
AMX_ERR_CALLBACK EQU 9
|
||||
AMX_ERR_NATIVE EQU 10
|
||||
AMX_ERR_DIVIDE EQU 11 ; MP: added for catching divide errors
|
||||
AMX_ERR_SLEEP EQU 12 ; (TR)
|
||||
|
||||
AMX_ERR_MEMORY EQU 16
|
||||
AMX_ERR_FORMAT EQU 17
|
||||
AMX_ERR_VERSION EQU 18
|
||||
AMX_ERR_NOTFOUND EQU 19
|
||||
AMX_ERR_INDEX EQU 20
|
||||
AMX_ERR_DEBUG EQU 21
|
||||
AMX_ERR_INIT EQU 22
|
||||
AMX_ERR_USERDATA EQU 23
|
||||
AMX_ERR_INIT_JIT EQU 24
|
||||
AMX_ERR_PARAMS EQU 25
|
||||
AMX_ERR_DOMAIN EQU 26
|
||||
|
||||
DBG_INIT EQU 0
|
||||
DBG_FILE EQU 1
|
||||
DBG_LINE EQU 2
|
||||
DBG_SYMBOL EQU 3
|
||||
DBG_CLRSYM EQU 4
|
||||
DBG_CALL EQU 5
|
||||
DBG_RETURN EQU 6
|
||||
DBG_TERMINATE EQU 7
|
||||
DBG_SRANGE EQU 8 ; (TR)
|
||||
DBG_SYMTAG EQU 9 ; (TR)
|
||||
|
||||
AMX_FLAG_CHAR16 EQU 0001h ; characters are 16-bit
|
||||
AMX_FLAG_DEBUG EQU 0002h ; symbolic info. available
|
||||
AMX_FLAG_LINEOPS EQU 0020h ; line op information
|
||||
AMX_FLAG_TRACED EQU 0040h ;
|
||||
AMX_FLAG_BROWSE EQU 4000h
|
||||
AMX_FLAG_RELOC EQU 8000h ; jump/call addresses relocated
|
||||
%include "amxdefn.asm"
|
||||
|
||||
;#define PUSH(v) ( stk-=sizeof(cell), *(cell *)(data+(int)stk)=v )
|
||||
%macro _PUSH 1
|
||||
@ -659,29 +576,6 @@ OP_POP_ALT:
|
||||
|
||||
;good
|
||||
OP_STACK:
|
||||
mov edx,ecx
|
||||
add ecx,[esi+4]
|
||||
_CHKMARGIN
|
||||
_CHKSTACK
|
||||
mov ebp,amx
|
||||
test DWORD [ebp+_flags],AMX_FLAG_DEBUG
|
||||
jz short op_stk_goon
|
||||
; update several structure fields and call the debug hook
|
||||
mov DWORD [ebp+_dbgcode],DBG_CLRSYM
|
||||
mov [ebp+_stk],ecx
|
||||
push eax
|
||||
mov eax,ebp ; 1st parm: amx
|
||||
_SAVEREGS
|
||||
push eax ; pass parameter via the stack
|
||||
call [ebp+_debug] ; call debug function
|
||||
_DROPARGS 4 ; remove arguments from stack
|
||||
_RESTOREREGS
|
||||
pop eax
|
||||
op_stk_goon:
|
||||
add esi,8
|
||||
GO_ON
|
||||
|
||||
OP_STACK_nodebug:
|
||||
mov edx,ecx
|
||||
add ecx,[esi+4]
|
||||
_CHKMARGIN
|
||||
@ -711,35 +605,6 @@ OP_PROC:
|
||||
GO_ON
|
||||
|
||||
OP_RET:
|
||||
_POP ebx
|
||||
_POP esi
|
||||
cmp esi,code ; verify ESI>=code
|
||||
jb err_memaccess
|
||||
cmp esi,codesiz ; verify ESI<codesiz ("end-of-code" pointer)
|
||||
jae err_memaccess
|
||||
mov frm,ebx
|
||||
add ebx,edi
|
||||
mov ebp,amx
|
||||
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
|
||||
jz short op_ret_goon
|
||||
; update several structure fields and call the debug hook
|
||||
mov DWORD [ebp+_dbgcode],DBG_RETURN
|
||||
mov [ebp+_dbgparam],eax
|
||||
push eax
|
||||
mov [ebp+_stk],ecx ; store STK
|
||||
mov eax,hea
|
||||
mov [ebp+_hea],eax ; store HEA
|
||||
mov eax,ebp ; 1st parm: amx
|
||||
_SAVEREGS
|
||||
push eax
|
||||
call [ebp+_debug] ; call debug function
|
||||
_DROPARGS 4 ; remove arguments from stack
|
||||
_RESTOREREGS
|
||||
pop eax
|
||||
op_ret_goon:
|
||||
GO_ON
|
||||
|
||||
OP_RET_nodebug:
|
||||
_POP ebx
|
||||
_POP esi
|
||||
cmp esi,code ; verify ESI>=code
|
||||
@ -760,107 +625,17 @@ OP_RETN:
|
||||
jae err_memaccess
|
||||
mov frm,ebx
|
||||
add ebx,edi
|
||||
mov ebp,amx
|
||||
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
|
||||
jz short op_retn_goon
|
||||
; update several structure fields and call the debug hook
|
||||
mov DWORD [ebp+_dbgcode],DBG_RETURN
|
||||
mov [ebp+_dbgparam],eax
|
||||
push eax
|
||||
mov [ebp+_stk],ecx ; store STK
|
||||
mov eax,hea
|
||||
mov [ebp+_hea],eax ; store HEA
|
||||
mov eax,ebp ; parm: amx
|
||||
_SAVEREGS
|
||||
push eax
|
||||
call [ebp+_debug] ; call debug function
|
||||
_DROPARGS 4 ; remove arguments from stack
|
||||
_RESTOREREGS
|
||||
; also send the DBG_CLRSYM code
|
||||
mov eax,[edi+ecx]
|
||||
lea ecx,[ecx+eax+4]
|
||||
mov DWORD [ebp+_dbgcode],DBG_CLRSYM
|
||||
mov [ebp+_stk],ecx
|
||||
mov eax,ebp ; parm: amx
|
||||
_SAVEREGS
|
||||
push eax
|
||||
call [ebp+_debug] ; call debug function
|
||||
_DROPARGS 4 ; remove arguments from stack
|
||||
_RESTOREREGS
|
||||
pop eax
|
||||
; ECX already adjusted
|
||||
GO_ON
|
||||
op_retn_goon:
|
||||
mov ebp,[edi+ecx]
|
||||
lea ecx,[ecx+ebp+4]
|
||||
GO_ON
|
||||
|
||||
OP_RETN_nodebug:
|
||||
_POP ebx
|
||||
_POP esi
|
||||
cmp esi,code ; verify ESI>=code
|
||||
jb err_memaccess
|
||||
cmp esi,codesiz ; verify ESI<codesiz ("end-of-code" pointer)
|
||||
jae err_memaccess
|
||||
mov frm,ebx
|
||||
mov ebp,[edi+ecx]
|
||||
add ebx,edi
|
||||
lea ecx,[ecx+ebp+4]
|
||||
GO_ON
|
||||
|
||||
;good
|
||||
OP_CALL:
|
||||
lea ebp,[esi+8]
|
||||
mov esi,[esi+4]
|
||||
_PUSH ebp
|
||||
mov ebp,amx
|
||||
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
|
||||
jz short op_call_goon
|
||||
; update several structure fields and call the debug hook
|
||||
push eax
|
||||
mov eax,[esp+24] ; this is "code", but ESP moved
|
||||
mov [ebp+_dbgaddr],esi
|
||||
sub [ebp+_dbgaddr],eax ; dbgaddr = cip - code
|
||||
mov DWORD [ebp+_dbgcode],DBG_CALL
|
||||
mov eax,ebp ; 1st parm: amx
|
||||
_SAVEREGS
|
||||
push eax
|
||||
call [ebp+_debug] ; call debug function
|
||||
_DROPARGS 4 ; remove arguments from stack
|
||||
_RESTOREREGS
|
||||
pop eax
|
||||
op_call_goon:
|
||||
GO_ON
|
||||
|
||||
OP_CALL_nodebug:
|
||||
lea ebp,[esi+8]
|
||||
mov esi,[esi+4]
|
||||
_PUSH ebp
|
||||
GO_ON
|
||||
|
||||
OP_CALL_PRI:
|
||||
lea ebp,[esi+4]
|
||||
mov esi,eax
|
||||
add esi,code ; cip = PRI + code
|
||||
_PUSH ebp
|
||||
mov ebp,amx
|
||||
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
|
||||
jz short op_calli_goon
|
||||
; update several structure fields and call the debug hook
|
||||
mov [ebp+_dbgaddr],eax ; dbgaddr = PRI (== cip - code)
|
||||
mov DWORD [ebp+_dbgcode],DBG_CALL
|
||||
push eax
|
||||
mov eax,ebp ; 1st parm: amx
|
||||
_SAVEREGS
|
||||
push eax
|
||||
call [ebp+_debug] ; call debug function
|
||||
_DROPARGS 4 ; remove arguments from stack
|
||||
_RESTOREREGS
|
||||
pop eax
|
||||
op_calli_goon:
|
||||
GO_ON
|
||||
|
||||
OP_CALL_PRI_nodebug:
|
||||
lea ebp,[esi+4]
|
||||
mov esi,eax
|
||||
add esi,code ; cip = PRI + code
|
||||
@ -941,13 +716,13 @@ OP_JSLESS:
|
||||
;good
|
||||
OP_JSLEQ:
|
||||
cmp eax,edx
|
||||
jle short jump_taken
|
||||
jle near jump_taken
|
||||
add esi,8
|
||||
GO_ON
|
||||
|
||||
OP_JSGRTR:
|
||||
cmp eax,edx
|
||||
jg short jump_taken
|
||||
jg near jump_taken
|
||||
add esi,8
|
||||
GO_ON
|
||||
|
||||
@ -1350,12 +1125,11 @@ OP_CMPS:
|
||||
_VERIFYADDRESS eax ; PRI
|
||||
_VERIFYADDRESS edx ; ALT
|
||||
mov ebp,eax
|
||||
add ebp,[esi+4]
|
||||
dec ebp
|
||||
add ebp,[esi+4] ; size in bytes
|
||||
dec ebp ; EBP = PRI + size - 1
|
||||
_VERIFYADDRESS ebp ; PRI + size - 1
|
||||
mov ebp,edx
|
||||
add ebp,[esi+4]
|
||||
dec ebp
|
||||
sub ebp,eax ; EBP = size - 1
|
||||
add ebp,edx ; EBP = ALT + size - 1
|
||||
_VERIFYADDRESS ebp ; ALT + size - 1
|
||||
|
||||
push ecx
|
||||
@ -1422,19 +1196,6 @@ OP_HALT:
|
||||
mov eax,esi ; EAX=CIP
|
||||
sub eax,code
|
||||
mov [ebp+_cip],eax
|
||||
; optionally call the debug hook
|
||||
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
|
||||
jz short halt_goon
|
||||
mov DWORD [ebp+_dbgcode],DBG_TERMINATE
|
||||
mov [ebp+_dbgaddr],eax
|
||||
mov [ebp+_dbgparam],ebx
|
||||
mov eax,ebp ; 1st parm: amx
|
||||
_SAVEREGS
|
||||
push eax
|
||||
call [ebp+_debug] ; call debug function
|
||||
_DROPARGS 4 ; remove arguments from stack
|
||||
_RESTOREREGS
|
||||
halt_goon:
|
||||
mov eax,ebx ; return the parameter of the HALT opcode
|
||||
jmp _return
|
||||
|
||||
@ -1549,159 +1310,21 @@ OP_FILE:
|
||||
|
||||
OP_LINE:
|
||||
add esi,12
|
||||
mov ebp,amx
|
||||
push eax
|
||||
push edx
|
||||
mov eax,[esi-8] ; get curline
|
||||
mov edx,[esi-4] ; get curfile
|
||||
mov [ebp+_curline],eax
|
||||
mov [ebp+_curfile],edx
|
||||
pop edx
|
||||
pop eax
|
||||
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
|
||||
jz short line_goon
|
||||
; update several structure fields
|
||||
mov [ebp+_pri],eax
|
||||
mov [ebp+_alt],edx ; EAX and EDX are now free to use
|
||||
mov eax,frm
|
||||
mov edx,hea
|
||||
mov [ebp+_frm],eax ; store values in AMX structure (STK, FRM & HEA)
|
||||
mov [ebp+_hea],edx
|
||||
mov [ebp+_stk],ecx
|
||||
mov eax,esi
|
||||
sub eax,code ; EAX = CIP (relative to start of code segment)
|
||||
mov [ebp+_cip],eax
|
||||
; call the debugger hook
|
||||
mov eax,ebp ; 1st parm: amx
|
||||
_SAVEREGS
|
||||
push eax
|
||||
call [ebp+_debug] ; call debug function
|
||||
_DROPARGS 4 ; remove arguments from stack
|
||||
cmp eax,AMX_ERR_NONE
|
||||
je short line_noabort ; continue running
|
||||
mov [ebp+_dbgcode],eax ; save EAX (error code) before restoring all regs
|
||||
_RESTOREREGS ; abort run, but restore stack first
|
||||
mov eax,[ebp+_dbgcode] ; get error code in EAX back again
|
||||
jmp _return ; return error code
|
||||
line_noabort:
|
||||
_RESTOREREGS
|
||||
mov eax,[ebp+_pri] ; restore PRI and ALT
|
||||
mov edx,[ebp+_alt]
|
||||
line_goon:
|
||||
GO_ON
|
||||
|
||||
|
||||
OP_LINE_nodebug:
|
||||
add esi,12
|
||||
mov ebp,amx
|
||||
push eax
|
||||
push edx
|
||||
mov eax,[esi-8] ; get curline
|
||||
mov edx,[esi-4] ; get curfile
|
||||
mov [ebp+_curline],eax
|
||||
mov [ebp+_curfile],edx
|
||||
pop edx
|
||||
pop eax
|
||||
GO_ON
|
||||
|
||||
|
||||
OP_SYMBOL:
|
||||
mov ebp,amx
|
||||
test DWORD [ebp+_flags],AMX_FLAG_DEBUG
|
||||
jz short op_symbol_goon
|
||||
push eax
|
||||
push edx
|
||||
mov eax,[esi+8] ; address
|
||||
mov edx,[esi+12] ; flags
|
||||
mov [ebp+_dbgaddr],eax
|
||||
mov [ebp+_dbgparam],edx
|
||||
mov DWORD [ebp+_dbgcode],DBG_SYMBOL
|
||||
mov eax,esi
|
||||
add eax,16 ; start of symbol name
|
||||
mov [ebp+_dbgname],eax
|
||||
mov edx,[esp+8] ; this is FRM, but offset by two PUSH'es
|
||||
mov [ebp+_frm],edx
|
||||
mov eax,ebp ; parameter of the debugger hook
|
||||
_SAVEREGS
|
||||
push eax
|
||||
call [ebp+_debug] ; call debugger hook
|
||||
_DROPARGS 4 ; remove arguments from stack
|
||||
_RESTOREREGS
|
||||
pop edx
|
||||
pop eax
|
||||
op_symbol_goon:
|
||||
add esi,[esi+4]
|
||||
add esi,8 ; skip "fixed" part
|
||||
GO_ON
|
||||
|
||||
|
||||
OP_SYMBOL_nodebug:
|
||||
add esi,[esi+4]
|
||||
add esi,8 ; skip "fixed" part
|
||||
GO_ON
|
||||
|
||||
|
||||
OP_SRANGE:
|
||||
mov ebp,amx
|
||||
add esi,12
|
||||
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
|
||||
jz short op_srange_goon
|
||||
push eax
|
||||
push edx
|
||||
mov eax,[esi-8] ; get dimensions
|
||||
mov edx,[esi-4] ; get size
|
||||
mov [ebp+_dbgaddr],eax
|
||||
mov [ebp+_dbgparam],edx
|
||||
mov DWORD [ebp+_dbgcode],DBG_SRANGE
|
||||
mov edx,frm
|
||||
mov [ebp+_frm],edx
|
||||
mov [ebp+_stk],ecx ; store values in AMX structure (STK & FRM)
|
||||
; call the debugger hook
|
||||
mov eax,ebp ; 1st parm: amx
|
||||
_SAVEREGS
|
||||
push eax
|
||||
call [ebp+_debug] ; call debug function
|
||||
_DROPARGS 4 ; remove arguments from stack
|
||||
_RESTOREREGS
|
||||
pop edx
|
||||
pop eax
|
||||
op_srange_goon:
|
||||
GO_ON
|
||||
|
||||
|
||||
OP_SRANGE_nodebug:
|
||||
add esi,12
|
||||
GO_ON
|
||||
|
||||
|
||||
OP_SYMTAG:
|
||||
mov ebp,amx
|
||||
add esi,8
|
||||
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
|
||||
jz short op_symtag_goon
|
||||
mov ebp,amx
|
||||
push eax
|
||||
push edx
|
||||
mov eax,[esi-4] ; get tag
|
||||
mov edx,frm
|
||||
mov DWORD [ebp+_dbgcode],DBG_SRANGE
|
||||
mov [ebp+_dbgparam],eax
|
||||
mov [ebp+_frm],edx
|
||||
mov [ebp+_stk],ecx ; store values in AMX structure (STK & FRM)
|
||||
; call the debugger hook
|
||||
mov eax,ebp ; 1st parm: amx
|
||||
_SAVEREGS
|
||||
push eax
|
||||
call [ebp+_debug] ; call debug function
|
||||
_DROPARGS 4 ; remove arguments from stack
|
||||
_RESTOREREGS
|
||||
pop edx
|
||||
pop eax
|
||||
op_symtag_goon:
|
||||
GO_ON
|
||||
|
||||
|
||||
OP_SYMTAG_nodebug: ; (TR)
|
||||
add esi,8
|
||||
GO_ON
|
||||
|
||||
@ -1759,6 +1382,45 @@ OP_PUSHADDR:
|
||||
|
||||
|
||||
OP_NOP:
|
||||
add esi,4
|
||||
GO_ON
|
||||
|
||||
|
||||
OP_BREAK:
|
||||
mov ebp,amx ; get amx into ebp
|
||||
add esi,4
|
||||
cmp DWORD [ebp+_debug], 0
|
||||
jnz break_calldebug
|
||||
GO_ON ; debug hook not active, ignore
|
||||
|
||||
break_calldebug:
|
||||
; store the status in the AMX (FRM, STK, HEA, CIP, and PRI + ALT)
|
||||
mov [ebp+_pri],eax
|
||||
mov [ebp+_alt],edx ; EAX and EDX are now free to use
|
||||
mov eax,frm
|
||||
mov edx,hea
|
||||
mov [ebp+_frm],eax ; store values in AMX structure (STK, FRM & HEA)
|
||||
mov [ebp+_hea],edx
|
||||
mov [ebp+_stk],ecx
|
||||
mov eax,esi
|
||||
sub eax,code ; EAX = CIP (relative to start of code segment)
|
||||
mov [ebp+_cip],eax
|
||||
; call the debug hook
|
||||
mov eax,ebp ; 1st parm: amx
|
||||
_SAVEREGS
|
||||
push eax
|
||||
call [ebp+_debug] ; call debug function
|
||||
_DROPARGS 4 ; remove arguments from stack
|
||||
cmp eax,AMX_ERR_NONE
|
||||
je short break_noabort; continue running
|
||||
mov [ebp+_error],eax ; save EAX (error code) before restoring all regs
|
||||
_RESTOREREGS ; abort run, but restore stack first
|
||||
mov eax,[ebp+_error] ; get error code in EAX back again
|
||||
jmp _return ; return error code
|
||||
break_noabort:
|
||||
_RESTOREREGS
|
||||
mov eax,[ebp+_pri] ; restore PRI and ALT
|
||||
mov edx,[ebp+_alt]
|
||||
GO_ON
|
||||
|
||||
|
||||
@ -1796,7 +1458,7 @@ err_divide:
|
||||
|
||||
|
||||
_return:
|
||||
; save a few paraneters, mostly for the "sleep"function
|
||||
; save a few parameters, mostly for the "sleep"function
|
||||
mov ebp,amx ; get amx into ebp
|
||||
mov [ebp+_pri],eax ; store values in AMX structure (PRI, ALT)
|
||||
mov [ebp+_alt],edx ; store values in AMX structure (PRI, ALT)
|
||||
@ -1967,144 +1629,5 @@ _amx_opcodelist DD OP_INVALID
|
||||
DD OP_NOP
|
||||
DD OP_SYSREQ_D
|
||||
DD OP_SYMTAG
|
||||
DD OP_BREAK
|
||||
|
||||
GLOBAL amx_opcodelist_nodebug
|
||||
GLOBAL _amx_opcodelist_nodebug
|
||||
amx_opcodelist_nodebug:
|
||||
_amx_opcodelist_nodebug DD OP_INVALID
|
||||
DD OP_LOAD_PRI
|
||||
DD OP_LOAD_ALT
|
||||
DD OP_LOAD_S_PRI
|
||||
DD OP_LOAD_S_ALT
|
||||
DD OP_LREF_PRI
|
||||
DD OP_LREF_ALT
|
||||
DD OP_LREF_S_PRI
|
||||
DD OP_LREF_S_ALT
|
||||
DD OP_LOAD_I
|
||||
DD OP_LODB_I
|
||||
DD OP_CONST_PRI
|
||||
DD OP_CONST_ALT
|
||||
DD OP_ADDR_PRI
|
||||
DD OP_ADDR_ALT
|
||||
DD OP_STOR_PRI
|
||||
DD OP_STOR_ALT
|
||||
DD OP_STOR_S_PRI
|
||||
DD OP_STOR_S_ALT
|
||||
DD OP_SREF_PRI
|
||||
DD OP_SREF_ALT
|
||||
DD OP_SREF_S_PRI
|
||||
DD OP_SREF_S_ALT
|
||||
DD OP_STOR_I
|
||||
DD OP_STRB_I
|
||||
DD OP_LIDX
|
||||
DD OP_LIDX_B
|
||||
DD OP_IDXADDR
|
||||
DD OP_IDXADDR_B
|
||||
DD OP_ALIGN_PRI
|
||||
DD OP_ALIGN_ALT
|
||||
DD OP_LCTRL
|
||||
DD OP_SCTRL
|
||||
DD OP_MOVE_PRI
|
||||
DD OP_MOVE_ALT
|
||||
DD OP_XCHG
|
||||
DD OP_PUSH_PRI
|
||||
DD OP_PUSH_ALT
|
||||
DD OP_PUSH_R_PRI
|
||||
DD OP_PUSH_C
|
||||
DD OP_PUSH
|
||||
DD OP_PUSH_S
|
||||
DD OP_POP_PRI
|
||||
DD OP_POP_ALT
|
||||
DD OP_STACK_nodebug
|
||||
DD OP_HEAP
|
||||
DD OP_PROC
|
||||
DD OP_RET_nodebug
|
||||
DD OP_RETN_nodebug
|
||||
DD OP_CALL_nodebug
|
||||
DD OP_CALL_PRI_nodebug
|
||||
DD OP_JUMP
|
||||
DD OP_JREL
|
||||
DD OP_JZER
|
||||
DD OP_JNZ
|
||||
DD OP_JEQ
|
||||
DD OP_JNEQ
|
||||
DD OP_JLESS
|
||||
DD OP_JLEQ
|
||||
DD OP_JGRTR
|
||||
DD OP_JGEQ
|
||||
DD OP_JSLESS
|
||||
DD OP_JSLEQ
|
||||
DD OP_JSGRTR
|
||||
DD OP_JSGEQ
|
||||
DD OP_SHL
|
||||
DD OP_SHR
|
||||
DD OP_SSHR
|
||||
DD OP_SHL_C_PRI
|
||||
DD OP_SHL_C_ALT
|
||||
DD OP_SHR_C_PRI
|
||||
DD OP_SHR_C_ALT
|
||||
DD OP_SMUL
|
||||
DD OP_SDIV
|
||||
DD OP_SDIV_ALT
|
||||
DD OP_UMUL
|
||||
DD OP_UDIV
|
||||
DD OP_UDIV_ALT
|
||||
DD OP_ADD
|
||||
DD OP_SUB
|
||||
DD OP_SUB_ALT
|
||||
DD OP_AND
|
||||
DD OP_OR
|
||||
DD OP_XOR
|
||||
DD OP_NOT
|
||||
DD OP_NEG
|
||||
DD OP_INVERT
|
||||
DD OP_ADD_C
|
||||
DD OP_SMUL_C
|
||||
DD OP_ZERO_PRI
|
||||
DD OP_ZERO_ALT
|
||||
DD OP_ZERO
|
||||
DD OP_ZERO_S
|
||||
DD OP_SIGN_PRI
|
||||
DD OP_SIGN_ALT
|
||||
DD OP_EQ
|
||||
DD OP_NEQ
|
||||
DD OP_LESS
|
||||
DD OP_LEQ
|
||||
DD OP_GRTR
|
||||
DD OP_GEQ
|
||||
DD OP_SLESS
|
||||
DD OP_SLEQ
|
||||
DD OP_SGRTR
|
||||
DD OP_SGEQ
|
||||
DD OP_EQ_C_PRI
|
||||
DD OP_EQ_C_ALT
|
||||
DD OP_INC_PRI
|
||||
DD OP_INC_ALT
|
||||
DD OP_INC
|
||||
DD OP_INC_S
|
||||
DD OP_INC_I
|
||||
DD OP_DEC_PRI
|
||||
DD OP_DEC_ALT
|
||||
DD OP_DEC
|
||||
DD OP_DEC_S
|
||||
DD OP_DEC_I
|
||||
DD OP_MOVS
|
||||
DD OP_CMPS
|
||||
DD OP_FILL
|
||||
DD OP_HALT
|
||||
DD OP_BOUNDS
|
||||
DD OP_SYSREQ_PRI
|
||||
DD OP_SYSREQ_C
|
||||
DD OP_FILE
|
||||
DD OP_LINE_nodebug
|
||||
DD OP_SYMBOL_nodebug
|
||||
DD OP_SRANGE_nodebug
|
||||
DD OP_JUMP_PRI
|
||||
DD OP_SWITCH
|
||||
DD OP_CASETBL
|
||||
DD OP_SWAP_PRI
|
||||
DD OP_SWAP_ALT
|
||||
DD OP_PUSHADDR
|
||||
DD OP_NOP
|
||||
DD OP_SYSREQ_D
|
||||
DD OP_SYMTAG_nodebug
|
||||
|
@ -1,4 +1,5 @@
|
||||
; JIT.ASM: Just-In-Time compiler for the Abstract Machine of the "Small"language
|
||||
; AMXJITSN.ASM: Just-In-Time compiler for the Abstract Machine of the "Pawn"
|
||||
; scripting language
|
||||
; (C) 1999-2000, Marc Peter; beta version; provided AS IS WITHOUT ANY WARRANTIES
|
||||
|
||||
; I reached >155 million instr./sec on my AMD K6-2/366 with the Hanoi "bench"
|
||||
@ -20,18 +21,54 @@
|
||||
; step.
|
||||
|
||||
; NOTE 3:
|
||||
; During execution of the compiled code with amx_exec_asm() the x86 processor's
|
||||
; During execution of the compiled code with amx_exec_jit() the x86 processor's
|
||||
; stack is switched into the data section of the abstract machine. This means
|
||||
; that there should always be enough memory left between HEA and STK to provide
|
||||
; stack space for occurring interrupts! (see the STACKRESERVE variable)
|
||||
|
||||
; NOTE 4:
|
||||
; Although the Small compiler doesn't generate the LCTRL, SCTRL and CALL.I
|
||||
; Although the Pawn compiler doesn't generate the LCTRL, SCTRL and CALL.I
|
||||
; instructions, I have to tell that they don't work as expected in a JIT
|
||||
; compiled program, because there is no easy way of transforming AMX code
|
||||
; addresses and JIT translated ones. This might be fixed in a future version.
|
||||
|
||||
; NX ("No eXecute") and XD (eXecution Denied) bits
|
||||
; (by Thiadmer Riemersma)
|
||||
;
|
||||
; AMD defined a bit "No eXecute" for the page table entries (for its 64-bit
|
||||
; processors) and Intel came with the same design, but calling it differently.
|
||||
; The purpose is to make "buffer overrun" security holes impossible, or at least
|
||||
; very, very difficult, by marking the stack and the heap as memory regions
|
||||
; such that an attempt to execute processor instructions will cause a processor
|
||||
; exception (of course, a buffer overrun that is not explictly handled will then
|
||||
; crash the application --instead of executing the rogue code).
|
||||
;
|
||||
; For JIT compilers, this has the impact that you are not allowed to execute the
|
||||
; code that the JIT has generated. To do that, you must adjust the attributes
|
||||
; for the memory page. For Microsoft Windows, you can use VirtualAlloc() to
|
||||
; allocate a memory block with the appropriate fags; on Linux (with a recent
|
||||
; kernel), you would use vmalloc_exec(). Microsoft Windows also offers the
|
||||
; function VirtualProtect() to change the page attributes of an existing memory
|
||||
; block, but there are caveats in its use: if the block spans multiple pages,
|
||||
; these pages must be consecutive, and if there are blocks of memory in a page
|
||||
; unrelated to the JIT, their page attributes will change too.
|
||||
;
|
||||
; The JIT compiler itself requires only read-write access (this is the default
|
||||
; for a memory block that you allocate). The execution of the JIT-compiled code
|
||||
; requires full access to the memory block: read, write and execute. It needs
|
||||
; write access, because the SYSREQ.C opcode is patched to SYSREQ.D after the
|
||||
; first lookup (this is an optimization, look up the address of the native
|
||||
; function only once). For processors that do not support the NX/XD bit,
|
||||
; execution of code is implicitly supported if read access is supported.
|
||||
;
|
||||
; During compilation, the JIT compiler requires write-access to its own code
|
||||
; segment: the JIT-compiler patches P-code parameters into its own code segment
|
||||
; during compilation. This is handled in the support code for amx_InitJIT.
|
||||
;
|
||||
;
|
||||
; CALLING CONVENTIONS
|
||||
; (by Thiadmer Riemersma)
|
||||
;
|
||||
; CALLING CONVENTIONS (by Thiadmer Riemersma)
|
||||
; This version is the JIT that uses the "stack calling convention". In the
|
||||
; original implementation, this meant __cdecl; both for the calling convention
|
||||
; for the _asm_runJIT routine itself as for the callback functions.
|
||||
@ -41,13 +78,15 @@
|
||||
; macro, hence STDECL.)
|
||||
|
||||
; Revision History
|
||||
;------------------
|
||||
; 16 September 2004 by David "BAILOPAN" Anderson
|
||||
; Implemented a compile time toggleable debug hook on OP_CALL and OP_RET.
|
||||
; NOTE: JIT has not had debug hooks since 1999.
|
||||
; 8 September 2004 by David "BAILOPAN" Anderson
|
||||
; Changed OP_LINE call to be compile-time toggle-able between compiling
|
||||
; line ops or not.
|
||||
; ----------------
|
||||
; 26 july 2005 by David "BAILOPAN" Anderson
|
||||
; Fixed a bug where zero casetbl entries would crash the JIT.
|
||||
; 17 february 2005 by Thiadmer Riemersms
|
||||
; Addition of the BREAK opcode, removal of the older debugging opcode
|
||||
; table. There should now be some debug support (if enabled during the
|
||||
; build of the JIT compiler), but not enough to run a debugger: the JIT
|
||||
; compiler does not keep a list that relates the code addresses of the
|
||||
; P-code versus the native code.
|
||||
; 29 June 2004 by G.W.M. Vissers
|
||||
; Translated the thing into NASM. The actual generation of the code is
|
||||
; put into the data section because the code modifies itself whereas the
|
||||
@ -94,8 +133,8 @@
|
||||
; hanoi bench.
|
||||
; 1999/08/05 MP
|
||||
; * fixed OP_LINE in the case of NODBGCALLS==1, where no compiled address
|
||||
; was stored for the LINE byte code (I.e. SWITCH would jump to totally
|
||||
; wrong addresses.) The same fix was applied to OP_FILL, OP_FILE and
|
||||
; was stored for the LINE byte code (i.e. SWITCH would jump to totally
|
||||
; wrong addresses). The same fix was applied to OP_FILL, OP_FILE and
|
||||
; OP_SCTRL (for the no-op case).
|
||||
; 1999/08/04 MP
|
||||
; * updated with 4 new opcodes (SRANGE does nothing at the moment; 2dim.
|
||||
@ -107,6 +146,16 @@
|
||||
; to compute the destination address: It searches backwards now.
|
||||
; 1999/07/08 MP - initial revision
|
||||
|
||||
|
||||
;
|
||||
; Support for the BREAK opcode (callback to the debugger): 0 = no, all other
|
||||
; values = yes. Beware that the compiled code runs slower when this is enabled,
|
||||
; and that debug support is still fairly minimal.
|
||||
;
|
||||
; GWMV: to generate LINE opcode, %define DEBUGSUPPORT
|
||||
;
|
||||
%undef DEBUGSUPPORT
|
||||
|
||||
;
|
||||
; If this is set to 1 the JIT generates relocatable code for case tables, too.
|
||||
; If set to 0, a faster variant for switch (using absolute addresses) is
|
||||
@ -128,116 +177,14 @@
|
||||
;
|
||||
; This variable controls the generation of memory range checks at run-time.
|
||||
; You should set this to 0, only when you are sure that there are no range
|
||||
; violations in your Small programs and you really need those 5% speed gain.
|
||||
; violations in your Pawn programs and you really need those 5% speed gain.
|
||||
;
|
||||
; GWMV: To disable runtime checks, %undef it, instread of setting it to zero
|
||||
;
|
||||
%define DORUNTIMECHECKS
|
||||
|
||||
|
||||
struc amx_s
|
||||
_base: resd 1
|
||||
_dataseg: resd 1
|
||||
_callback: resd 1
|
||||
_debug: resd 1
|
||||
_cip: resd 1
|
||||
_frm: resd 1
|
||||
_hea: resd 1
|
||||
_hlw: resd 1
|
||||
_stk: resd 1
|
||||
_stp: resd 1
|
||||
_flags: resd 1
|
||||
_curline: resd 1
|
||||
_curfile: resd 1
|
||||
_dbgcode: resd 1
|
||||
_dbgaddr: resd 1
|
||||
_dbgparam: resd 1
|
||||
_dbgname: resd 1
|
||||
;usertags and userdata are 16 bytes on AMX Mod X
|
||||
_usertags1: resd 1 ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_usertags2: resd 1 ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_usertags3: resd 1 ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_usertags4: resd 1 ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_userdata1: resd 1 ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_userdata2: resd 1 ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_userdata3: resd 1 ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_userdata4: resd 1 ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_error: resd 1
|
||||
_pri: resd 1
|
||||
_alt: resd 1
|
||||
_reset_stk: resd 1
|
||||
_reset_hea: resd 1
|
||||
_syscall_d: resd 1
|
||||
; the two fields below are for the JIT
|
||||
; they are included in the non-JIT version for AMX Mod X
|
||||
; this is to make sure that the structs match universally!
|
||||
_reloc_size: resd 1 ; memory block for relocations
|
||||
_code_size: resd 1 ; memory size of the native code
|
||||
endstruc
|
||||
|
||||
|
||||
struc amxhead_s
|
||||
_size: resd 1 ; size of the "file"
|
||||
_magic: resw 1 ; signature
|
||||
_file_version: resb 1 ;file format version
|
||||
_amx_version: resb 1 ; required version of the AMX
|
||||
_h_flags: resw 1
|
||||
_defsize: resw 1 ; size of one public/native function entry
|
||||
_cod: resd 1 ; initial value of COD - code block
|
||||
_dat: resd 1 ; initial value of DAT - data block
|
||||
_h_hea: resd 1 ; initial value of HEA - start of the heap
|
||||
_h_stp: resd 1 ; initial value of STP - stack top
|
||||
_h_cip: resd 1 ; initial value of CIP - the instruction pointer
|
||||
_publics: resd 1 ; offset to the "public functions" table
|
||||
_natives: resd 1 ; offset to the "native functions" table
|
||||
_libraries: resd 1 ; offset to the "library" table
|
||||
_pubvars: resd 1 ; offset to the "public variables" table
|
||||
_tags: resd 1 ; offset to the "public tagnames" table
|
||||
endstruc
|
||||
|
||||
|
||||
AMX_ERR_NONE equ 0
|
||||
AMX_ERR_EXIT equ 1
|
||||
AMX_ERR_ASSERT equ 2
|
||||
AMX_ERR_STACKERR equ 3
|
||||
AMX_ERR_BOUNDS equ 4
|
||||
AMX_ERR_MEMACCESS equ 5
|
||||
AMX_ERR_INVINSTR equ 6
|
||||
AMX_ERR_STACKLOW equ 7
|
||||
AMX_ERR_HEAPLOW equ 8
|
||||
AMX_ERR_CALLBACK equ 9
|
||||
AMX_ERR_NATIVE equ 10
|
||||
AMX_ERR_DIVIDE equ 11 ; MP: added for catching divide errors
|
||||
AMX_ERR_SLEEP equ 12 ; (TR) go into sleep mode
|
||||
|
||||
AMX_ERR_MEMORY equ 16
|
||||
AMX_ERR_FORMAT equ 17
|
||||
AMX_ERR_VERSION equ 18
|
||||
AMX_ERR_NOTFOUND equ 19
|
||||
AMX_ERR_INDEX equ 20
|
||||
AMX_ERR_DEBUG equ 21
|
||||
AMX_ERR_INIT equ 22
|
||||
AMX_ERR_USERDATA equ 23
|
||||
AMX_ERR_INIT_JIT equ 24
|
||||
AMX_ERR_PARAMS equ 25
|
||||
AMX_ERR_DOMAIN equ 26
|
||||
|
||||
DBG_INIT equ 0
|
||||
DBG_FILE equ 1
|
||||
DBG_LINE equ 2
|
||||
DBG_SYMBOL equ 3
|
||||
DBG_CLRSYM equ 4
|
||||
DBG_CALL equ 5
|
||||
DBG_RETURN equ 6
|
||||
DBG_TERMINATE equ 7
|
||||
DBG_SRANGE equ 8
|
||||
DBG_SYMTAG equ 9
|
||||
|
||||
AMX_FLAG_CHAR16 equ 0001h ; characters are 16-bit
|
||||
AMX_FLAG_DEBUG equ 0002h ; symbolic info. available
|
||||
AMX_FLAG_LINEOPS equ 0020h ; line ops should be parsed [load time only flag] - ~dvander
|
||||
AMX_FLAG_BROWSE equ 4000h
|
||||
AMX_FLAG_RELOC equ 8000h ; jump/call addresses relocated
|
||||
%define JIT 1
|
||||
%include "amxdefn.asm"
|
||||
|
||||
; GWMV:
|
||||
; Nasm can't do the next as equivalence statements, since the value of
|
||||
@ -269,7 +216,7 @@ AMX_FLAG_RELOC equ 8000h ; jump/call addresses relocated
|
||||
|
||||
|
||||
;
|
||||
; For determining the biggest native code section generated for ONE Small
|
||||
; For determining the biggest native code section generated for ONE Pawn
|
||||
; opcode. (See the following macro and the PUBLIC function getMaxCodeSize().)
|
||||
;
|
||||
; GWMV: Do NOT see the following macro. See CHECKCODESIZE instead.
|
||||
@ -278,14 +225,6 @@ AMX_FLAG_RELOC equ 8000h ; jump/call addresses relocated
|
||||
|
||||
;
|
||||
; This is the work horse of the whole JIT: It actually copies the code.
|
||||
; Notes from ~dvander (with help of dJeyL)
|
||||
; This takes a source and ending address pointer in the assembled JIT code.
|
||||
; Then it subtracts them and copies the code in between.
|
||||
; The last parameter is the number of bytes the opcode is so it can jump
|
||||
; to the next one.
|
||||
; Also note that the "in between" code is NEVER executed during the compile
|
||||
; phase of the JIT. It's only assembled in memory, and copied into the
|
||||
; final output bytecode by this function.
|
||||
%macro GO_ON 2-3 4
|
||||
mov esi, %1 ;get source address of JIT code
|
||||
mov ecx,%2-%1 ;get number of bytes to copy
|
||||
@ -300,9 +239,7 @@ AMX_FLAG_RELOC equ 8000h ; jump/call addresses relocated
|
||||
; GWMV:
|
||||
; Nasm can't handle the determination of the maximum code size as was done
|
||||
; in the Masm implementation, since it only does two passes. This macro is
|
||||
; called *after* the code for each Small instruction.
|
||||
; Notes by ~dvander: This just substracts a label's ip from the current ip.
|
||||
; Therefore you get an instant size check - see RELOC
|
||||
; called *after* the code for each Pawn instruction.
|
||||
%macro CHECKCODESIZE 1
|
||||
%if MAXCODESIZE < $-%1
|
||||
%assign MAXCODESIZE $-%1
|
||||
@ -310,14 +247,9 @@ AMX_FLAG_RELOC equ 8000h ; jump/call addresses relocated
|
||||
%endmacro
|
||||
|
||||
;
|
||||
; Modify the argument of an x86 instruction with the Small opcode's parameter
|
||||
; Modify the argument of an x86 instruction with the Pawn opcode's parameter
|
||||
; before copying the code.
|
||||
;
|
||||
; Notes by ~dvander (thanks to dJeyL) - this will take an address and modify
|
||||
; the dword at it. Since the JIT copies already assembled code, you see
|
||||
; things like "call 12345678h". This is an arbitrary value as putval
|
||||
; will modify it in memory and then GO_ON will add it to the program.
|
||||
; It is important to get the putval address right - it's in bytes.
|
||||
%macro putval 1
|
||||
mov eax,[ebx+4]
|
||||
mov dword [%1],eax
|
||||
@ -326,12 +258,7 @@ AMX_FLAG_RELOC equ 8000h ; jump/call addresses relocated
|
||||
;
|
||||
; Add an entry to the table of addresses which have to be relocated after the
|
||||
; code compilation is done.
|
||||
; Notes by ~dvander: This is sort of what amx_BrowseRelocate() does, although
|
||||
; relocation is actually done after code generation (this just adds to a
|
||||
; table). Like putval, this takes in an address and marks it to be
|
||||
; rewritten. It is a good idea to just use labels to find relocation
|
||||
; offsets (see OP_CALL and OP_RETN). After code generation, this table
|
||||
; is browsed and the correct threaded jumps are placed.
|
||||
;
|
||||
%macro RELOC 1-2 ; adr, dest
|
||||
mov ebp,[reloc_num]
|
||||
%if %0 < 2
|
||||
@ -356,7 +283,7 @@ section .text
|
||||
|
||||
|
||||
global asm_runJIT, _asm_runJIT
|
||||
global amx_exec_asm, _amx_exec_asm
|
||||
global amx_exec_jit, _amx_exec_jit
|
||||
global getMaxCodeSize, _getMaxCodeSize
|
||||
|
||||
|
||||
@ -481,7 +408,7 @@ reloc_done:
|
||||
ret
|
||||
|
||||
; GWMV:
|
||||
; The code below modifies itself to store the arguments to the Small opcodes
|
||||
; The code below modifies itself to store the arguments to the Pawn opcodes
|
||||
; in the compiled code. This is fine, but the .text section in an ELF executable
|
||||
; is usually marked read-only, that's why this code is in the .data section.
|
||||
|
||||
@ -817,7 +744,7 @@ OP_ALIGN_PRI:
|
||||
CHECKCODESIZE j_align_pri
|
||||
|
||||
OP_ALIGN_ALT:
|
||||
;nop
|
||||
;nop;
|
||||
mov eax,4
|
||||
sub eax,[ebx+4]
|
||||
mov dword [j_align_alt+1],eax
|
||||
@ -1073,119 +1000,22 @@ OP_RET:
|
||||
;good
|
||||
OP_RETN:
|
||||
;nop;
|
||||
;save registers
|
||||
push eax
|
||||
push ebp
|
||||
;get .amx flags
|
||||
mov ebp,[amxhead]
|
||||
mov eax,[ebp+_h_flags]
|
||||
;check to see if the flag has line ops
|
||||
and eax,AMX_FLAG_DEBUG
|
||||
cmp eax,AMX_FLAG_DEBUG
|
||||
;restore registers
|
||||
pop ebp
|
||||
pop eax
|
||||
;if so, skip down to debug compiler
|
||||
jmp _go_jit_retn_debug
|
||||
|
||||
_go_jit_retn_nodebug:
|
||||
GO_ON j_retn_nodebug, _go_jit_retn_go
|
||||
j_retn_nodebug:
|
||||
jmp [jit_retn]
|
||||
CHECKCODESIZE j_retn_nodebug
|
||||
_go_jit_retn_go:
|
||||
jmp _go_jit_retn_end
|
||||
|
||||
_go_jit_retn_debug:
|
||||
GO_ON j_retn, OP_CALL
|
||||
|
||||
j_retn:
|
||||
push ebp
|
||||
push eax
|
||||
push edx
|
||||
;get AMX
|
||||
mov ebp,amx
|
||||
;get debug call ptr
|
||||
mov eax,[ebp+_userdata2]
|
||||
;check validity
|
||||
mov edx, dword 0
|
||||
cmp eax, edx
|
||||
je _go_jit_skip_debug
|
||||
xchg esp,esi ;switch stack
|
||||
push 1 ;param 2 mode 1 = pop
|
||||
push ebp ;param 1 - amx
|
||||
call eax ;indirect debug call
|
||||
add esp, 8 ;restore stack
|
||||
xchg esp,esi ;return to AMX stack
|
||||
mov ebp,amx ;restore AMX [necessary?]
|
||||
_go_jit_skip_debug:
|
||||
pop edx
|
||||
pop eax
|
||||
pop ebp
|
||||
jmp [jit_retn]
|
||||
CHECKCODESIZE j_retn
|
||||
_go_jit_retn_end:
|
||||
|
||||
;good
|
||||
OP_CALL:
|
||||
;nop;
|
||||
;save registers
|
||||
push eax
|
||||
push ebp
|
||||
;get .amx flags
|
||||
mov ebp,[amxhead]
|
||||
mov eax,[ebp+_h_flags]
|
||||
;check to see if the flag has line ops
|
||||
and eax,AMX_FLAG_DEBUG
|
||||
cmp eax,AMX_FLAG_DEBUG
|
||||
;restore registers
|
||||
pop ebp
|
||||
pop eax
|
||||
;if so, skip down to debug compiler
|
||||
jmp _go_jit_debug
|
||||
|
||||
_go_jit_nodebug:
|
||||
RELOC 1
|
||||
GO_ON j_call_nodebug, _j_call_go_on, 8
|
||||
j_call_nodebug:
|
||||
db 0e8h, 0, 0, 0, 0
|
||||
CHECKCODESIZE j_call_nodebug
|
||||
|
||||
_j_call_go_on:
|
||||
jmp _opcall_end
|
||||
|
||||
_go_jit_debug:
|
||||
;thanks to Julien "dJeyL" Laurent for code relocation explanation
|
||||
RELOC _go_jit_reloc-j_call+1
|
||||
GO_ON j_call, OP_CALL_I, 8
|
||||
|
||||
j_call:
|
||||
; save some registers
|
||||
push ebp
|
||||
push eax
|
||||
push edx
|
||||
; get AMX
|
||||
mov ebp,amx
|
||||
; get debug call pointer
|
||||
mov eax,[ebp+_userdata2]
|
||||
; check to see if it's valid
|
||||
mov edx, dword 0
|
||||
cmp eax,edx
|
||||
je _go_jit_skip_call
|
||||
xchg esp,esi ;switch to caller stack
|
||||
push 2 ;param mode=2, push
|
||||
push ebp ;param amx
|
||||
call eax ;indirect call
|
||||
add esp, 8 ;restore stack
|
||||
xchg esp,esi ;return to AMX stack
|
||||
mov ebp,amx ;restore AMX [necessary?]
|
||||
_go_jit_skip_call:
|
||||
;restore original registers
|
||||
pop edx
|
||||
pop eax
|
||||
pop ebp
|
||||
_go_jit_reloc:
|
||||
;call 12345678h ; tasm chokes on this out of a sudden
|
||||
db 0e8h, 0, 0, 0, 0
|
||||
CHECKCODESIZE j_call
|
||||
_opcall_end:
|
||||
|
||||
OP_CALL_I:
|
||||
;nop;
|
||||
@ -1857,39 +1687,12 @@ OP_FILE: ;opcode is simply ignored
|
||||
|
||||
OP_LINE:
|
||||
;nop;
|
||||
;~dvander - opline is now variable on compile time :]
|
||||
;save registers
|
||||
push eax
|
||||
push ebp
|
||||
;get .amx flags
|
||||
mov ebp,[amxhead]
|
||||
mov eax,[ebp+_h_flags]
|
||||
;check to see if the flag has line ops
|
||||
and eax,AMX_FLAG_LINEOPS
|
||||
cmp eax,AMX_FLAG_LINEOPS
|
||||
;restore registers
|
||||
pop ebp
|
||||
pop eax
|
||||
;if so, skip down to debug compiler
|
||||
je _go_debug
|
||||
|
||||
mov [ebx],edi ; no line number support: ignore opcode
|
||||
add ebx,12 ; move on to next opcode
|
||||
cmp ebx,[end_code]
|
||||
jae code_gen_done
|
||||
jmp dword [ebx] ; go on with the next opcode
|
||||
|
||||
_go_debug:
|
||||
putval j_line+6
|
||||
mov eax,[ebx+8]
|
||||
mov [j_line_sm],eax
|
||||
GO_ON j_line, OP_SYMBOL, 12
|
||||
j_line:
|
||||
call [jit_line]
|
||||
DD 0 ; space for curline
|
||||
j_line_sm DD 0 ; space for curfile
|
||||
CHECKCODESIZE j_line
|
||||
|
||||
OP_SYMBOL: ;ignored
|
||||
mov [ebx],edi
|
||||
mov eax,[ebx+4] ; get size
|
||||
@ -2019,6 +1822,23 @@ OP_SYMTAG: ;ignored (TR)
|
||||
jmp dword [ebx] ; go on with the next opcode
|
||||
|
||||
|
||||
OP_BREAK:
|
||||
%ifndef DEBUGSUPPORT
|
||||
mov [ebx],edi ; no line number support: ignore opcode
|
||||
add ebx,4 ; move on to next opcode
|
||||
cmp ebx,[end_code]
|
||||
jae code_gen_done
|
||||
jmp DWORD [ebx] ; go on with the next opcode
|
||||
%else
|
||||
GO_ON j_break, OP_INVALID
|
||||
j_break:
|
||||
mov ebp,amx
|
||||
cmp DWORD [ebp+_debug], 0
|
||||
je $+4 ; jump around the "call" statement
|
||||
call [jit_break]
|
||||
CHECKCODESIZE j_break
|
||||
%endif
|
||||
|
||||
OP_INVALID: ; break from the compiler with an error code
|
||||
mov eax,AMX_ERR_INVINSTR
|
||||
pop esi
|
||||
@ -2032,12 +1852,12 @@ section .text
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; ;
|
||||
;cell asm_exec( cell *regs, cell *retval, cell stp, cell hea );
|
||||
;cell amx_exec( cell *regs, cell *retval, cell stp, cell hea );
|
||||
; eax edx ebx ecx ;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
amx_exec_asm:
|
||||
_amx_exec_asm:
|
||||
amx_exec_jit:
|
||||
_amx_exec_jit:
|
||||
push edi
|
||||
push esi
|
||||
push ebp
|
||||
@ -2338,25 +2158,47 @@ JIT_OP_SYSREQ_D: ; (TR)
|
||||
ret
|
||||
|
||||
|
||||
JIT_OP_LINE:
|
||||
pop ecx ; get return address
|
||||
mov ebp,amx
|
||||
push eax
|
||||
push edx
|
||||
mov eax,[ecx] ; get curline
|
||||
mov edx,[ecx+4] ; get curfile
|
||||
add ecx,8 ; skip curline & curfile
|
||||
mov [ebp+_curline],eax ; store curline
|
||||
mov [ebp+_curfile],edx ; store curfile
|
||||
JIT_OP_BREAK:
|
||||
%ifdef DEBUGSUPPORT
|
||||
mov ecx,esp ; get STK into ECX
|
||||
mov ebp,amx ; get amx into EBP
|
||||
|
||||
sub ecx,edi ; correct STK
|
||||
|
||||
mov [ebp+_pri],eax ; store values in AMX structure: PRI,
|
||||
mov [ebp+_alt],edx ; ALT,
|
||||
mov [ebp+_stk],ecx ; STK,
|
||||
mov ecx,hea ; HEA,
|
||||
mov ebx,frm ; and FRM
|
||||
mov [ebp+_hea],ecx
|
||||
mov [ebp+_frm],ebx ; EBX & ECX are invalid by now
|
||||
;??? storing CIP is not very useful, because the code changed (during JIT compile)
|
||||
|
||||
xchg esp,esi ; switch to caller stack
|
||||
push ebp ; 1st param: amx
|
||||
call [ebp+_debug]
|
||||
_DROPARGS 4 ; remove args from stack
|
||||
xchg esp,esi ; switch back to AMX stack
|
||||
cmp eax,AMX_ERR_NONE
|
||||
jne _return_popstack; return error code, if any
|
||||
|
||||
mov ebp,amx ; get amx into EBP
|
||||
mov eax,[ebp+_pri] ; restore values
|
||||
mov edx,[ebp+_alt] ; ALT,
|
||||
mov edx,alt ; restore ALT
|
||||
mov ebx,frm ; restore FRM
|
||||
add ebx,edi ; relocate frame
|
||||
%endif
|
||||
ret
|
||||
|
||||
pop edx
|
||||
pop eax
|
||||
jmp ecx ; jump back
|
||||
|
||||
JIT_OP_SWITCH:
|
||||
pop ebp ; pop return address = table address
|
||||
mov ecx,[ebp] ; ECX = number of records
|
||||
lea ebp,[ebp+ecx*8+8] ; set pointer _after_ LAST case
|
||||
;if there are zero cases we should just skip this -- bail
|
||||
test ecx, ecx
|
||||
jz op_switch_jump
|
||||
op_switch_loop:
|
||||
cmp eax,[ebp-8] ; PRI == case label?
|
||||
je op_switch_jump ; found, jump
|
||||
@ -2370,9 +2212,11 @@ JIT_OP_SWITCH:
|
||||
jmp ebp
|
||||
%endif
|
||||
|
||||
|
||||
|
||||
; The caller of asm_runJIT() can determine the maximum size of the compiled
|
||||
; code by multiplying the result of this function by the number of opcodes in
|
||||
; Small module.
|
||||
; Pawn module.
|
||||
;
|
||||
; unsigned long getMaxCodeSize_();
|
||||
;
|
||||
@ -2414,17 +2258,17 @@ jit_fill DD JIT_OP_FILL
|
||||
jit_bounds DD JIT_OP_BOUNDS
|
||||
jit_sysreq DD JIT_OP_SYSREQ
|
||||
jit_sysreq_d DD JIT_OP_SYSREQ_D
|
||||
jit_line DD JIT_OP_LINE
|
||||
jit_break DD JIT_OP_BREAK
|
||||
jit_switch DD JIT_OP_SWITCH
|
||||
|
||||
;
|
||||
; The table for the browser/relocator function.
|
||||
;
|
||||
|
||||
global amx_opcodelist, _amx_opcodelist
|
||||
global amx_opcodelist_jit, _amx_opcodelist_jit
|
||||
|
||||
amx_opcodelist:
|
||||
_amx_opcodelist:
|
||||
amx_opcodelist_jit:
|
||||
_amx_opcodelist_jit:
|
||||
DD OP_INVALID
|
||||
DD OP_LOAD_PRI
|
||||
DD OP_LOAD_ALT
|
||||
@ -2562,3 +2406,6 @@ _amx_opcodelist:
|
||||
DD OP_NOP ; TR
|
||||
DD OP_SYSREQ_D ; TR
|
||||
DD OP_SYMTAG ; TR
|
||||
DD OP_BREAK ; TR
|
||||
|
||||
END
|
@ -158,7 +158,7 @@ static cell AMX_NATIVE_CALL console_cmd(AMX *amx, cell *params) /* 2 param */
|
||||
}
|
||||
else{
|
||||
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
||||
if ( !pPlayer->bot && pPlayer->initialized ) CLIENT_COMMAND(pPlayer->pEdict, cmd );
|
||||
if ( !pPlayer->bot && pPlayer->initialized ) CLIENT_COMMAND(pPlayer->pEdict, UTIL_VarArgs("%s", cmd) );
|
||||
}
|
||||
|
||||
return len;
|
||||
@ -223,7 +223,7 @@ static cell AMX_NATIVE_CALL client_print(AMX *amx, cell *params) /* 3 param */
|
||||
msg[len++] = '\n';
|
||||
msg[len] = 0;
|
||||
if (pPlayer->ingame)
|
||||
UTIL_ClientPrint(pPlayer->pEdict, params[2], format_amxstring(amx, params, 3, len));
|
||||
UTIL_ClientPrint(pPlayer->pEdict, params[2], msg); //format_amxstring(amx, params, 3, len));
|
||||
}
|
||||
return len;
|
||||
}
|
||||
@ -351,6 +351,15 @@ static cell AMX_NATIVE_CALL is_linux_server(AMX *amx, cell *params)
|
||||
#endif
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL is_amd64_server(AMX *amx, cell *params)
|
||||
{
|
||||
#if PAWN_CELL_SIZE==64
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL is_jit_enabled(AMX *amx, cell *params) // PM: Useless ;P
|
||||
{
|
||||
#ifdef JIT
|
||||
@ -399,7 +408,15 @@ static cell AMX_NATIVE_CALL is_user_hltv(AMX *amx, cell *params) /* 1 param */
|
||||
int index = params[1];
|
||||
if (index<1||index>gpGlobals->maxClients)
|
||||
return 0;
|
||||
return ((GET_PLAYER_POINTER_I(index)->pEdict->v.flags & FL_PROXY) ? 1 : 0);
|
||||
CPlayer *pPlayer = GET_PLAYER_POINTER_I(index);
|
||||
if (!pPlayer->initialized)
|
||||
return 0;
|
||||
if (pPlayer->pEdict->v.flags & FL_PROXY)
|
||||
return 1;
|
||||
const char *authid = GETPLAYERAUTHID(pPlayer->pEdict);
|
||||
if (authid && stricmp(authid, "HLTV") == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL is_user_alive(AMX *amx, cell *params) /* 1 param */
|
||||
@ -739,6 +756,8 @@ static cell AMX_NATIVE_CALL show_menu(AMX *amx, cell *params) /* 3 param */
|
||||
if (pPlayer->ingame){
|
||||
pPlayer->keys = keys;
|
||||
pPlayer->menu = menuid;
|
||||
pPlayer->newmenu = -1;
|
||||
pPlayer->page = 0;
|
||||
UTIL_ShowMenu(pPlayer->pEdict, keys, time, sMenu, ilen );
|
||||
}
|
||||
}
|
||||
@ -753,6 +772,8 @@ static cell AMX_NATIVE_CALL show_menu(AMX *amx, cell *params) /* 3 param */
|
||||
if (pPlayer->ingame){
|
||||
pPlayer->keys = keys;
|
||||
pPlayer->menu = menuid;
|
||||
pPlayer->newmenu = -1;
|
||||
pPlayer->page = 0;
|
||||
UTIL_ShowMenu(pPlayer->pEdict, keys, time, sMenu, ilen );
|
||||
}
|
||||
}
|
||||
@ -777,9 +798,10 @@ static cell AMX_NATIVE_CALL register_menucmd(AMX *amx, cell *params) /* 3 param
|
||||
int ilen, idx;
|
||||
char* sptemp = get_amxstring(amx,params[3],0,ilen);
|
||||
|
||||
if(amx_FindPublic(amx, sptemp ,&idx)!=AMX_ERR_NONE) {
|
||||
AMXXLOG_Log("[AMXX] Function is not present (function \"%s\") (plugin \"%s\")",sptemp,plugin->getName() );
|
||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
||||
idx = registerSPForwardByName(amx, sptemp, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||
if (idx == -1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", sptemp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -848,16 +870,15 @@ static cell AMX_NATIVE_CALL get_pluginsnum(AMX *amx, cell *params)
|
||||
return g_plugins.getPluginsNum();
|
||||
}
|
||||
|
||||
|
||||
|
||||
static cell AMX_NATIVE_CALL register_concmd(AMX *amx, cell *params) /* 4 param */
|
||||
{
|
||||
CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast( amx );
|
||||
int i, idx = 0;
|
||||
char* temp = get_amxstring(amx,params[2],0, i );
|
||||
if(amx_FindPublic(amx, temp ,&idx)!=AMX_ERR_NONE) {
|
||||
AMXXLOG_Log("[AMXX] Function is not present (function \"%s\") (plugin \"%s\")",temp,plugin->getName() );
|
||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
||||
idx = registerSPForwardByName(amx, temp, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||
if (idx == -1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", temp);
|
||||
return 0;
|
||||
}
|
||||
temp = get_amxstring(amx,params[1],0, i );
|
||||
@ -882,9 +903,10 @@ static cell AMX_NATIVE_CALL register_clcmd(AMX *amx, cell *params) /* 4 param */
|
||||
CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast( amx );
|
||||
int i, idx = 0;
|
||||
char* temp = get_amxstring(amx,params[2],0, i );
|
||||
if(amx_FindPublic(amx, temp ,&idx)!=AMX_ERR_NONE) {
|
||||
AMXXLOG_Log("[AMXX] Function is not present (function \"%s\") (plugin \"%s\")",temp,plugin->getName() );
|
||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
||||
idx = registerSPForwardByName(amx, temp, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||
if(idx==-1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", temp);
|
||||
return 0;
|
||||
}
|
||||
temp = get_amxstring(amx,params[1],0, i );
|
||||
@ -907,9 +929,10 @@ static cell AMX_NATIVE_CALL register_srvcmd(AMX *amx, cell *params) /* 2 param *
|
||||
CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast( amx );
|
||||
int i, idx = 0;
|
||||
char* temp = get_amxstring(amx,params[2],0, i );
|
||||
if(amx_FindPublic(amx, temp ,&idx)!=AMX_ERR_NONE) {
|
||||
AMXXLOG_Log("[AMXX] Function is not present (function \"%s\") (plugin \"%s\")",temp,plugin->getName() );
|
||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
||||
idx = registerSPForwardByName(amx, temp, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||
if (idx==-1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", temp);
|
||||
return 0;
|
||||
}
|
||||
temp = get_amxstring(amx,params[1],0, i );
|
||||
@ -939,7 +962,7 @@ static cell AMX_NATIVE_CALL get_concmd(AMX *amx, cell *params) /* 7 param */
|
||||
else // -1 parameter - all commands
|
||||
who = CMD_ConsoleCommand;
|
||||
|
||||
CmdMngr::Command* cmd = g_commands.getCmd(params[1] ,who , params[7] );
|
||||
CmdMngr::Command* cmd = g_commands.getCmd(params[1], who, params[7]);
|
||||
|
||||
if ( cmd == 0 ) return 0;
|
||||
set_amxstring(amx,params[2], cmd->getCmdLine() ,params[3]);
|
||||
@ -1008,10 +1031,10 @@ static cell AMX_NATIVE_CALL register_event(AMX *amx, cell *params) /* 2 param */
|
||||
}
|
||||
|
||||
sTemp = get_amxstring(amx,params[2],0,len);
|
||||
|
||||
if ( amx_FindPublic(amx, sTemp , &iFunction) != AMX_ERR_NONE){
|
||||
AMXXLOG_Log("[AMXX] Function is not present (function \"%s\") (plugin \"%s\")",sTemp,plugin->getName() );
|
||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
||||
iFunction = registerSPForwardByName(amx, sTemp, FP_CELL, FP_DONE);
|
||||
if (iFunction==-1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", sTemp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1132,7 +1155,7 @@ static cell AMX_NATIVE_CALL client_cmd(AMX *amx, cell *params) /* 2 param */
|
||||
for(int i = 1; i <= gpGlobals->maxClients; ++i){
|
||||
CPlayer* pPlayer = GET_PLAYER_POINTER_I(i);
|
||||
if (!pPlayer->bot && pPlayer->initialized /*&& pPlayer->ingame*/ )
|
||||
CLIENT_COMMAND(pPlayer->pEdict, cmd );
|
||||
CLIENT_COMMAND(pPlayer->pEdict, UTIL_VarArgs("%s", cmd) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -1143,7 +1166,7 @@ static cell AMX_NATIVE_CALL client_cmd(AMX *amx, cell *params) /* 2 param */
|
||||
}
|
||||
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
||||
if ( !pPlayer->bot && pPlayer->initialized /*&& pPlayer->ingame*/ )
|
||||
CLIENT_COMMAND(pPlayer->pEdict, cmd );
|
||||
CLIENT_COMMAND(pPlayer->pEdict, UTIL_VarArgs("%s", cmd) );
|
||||
}
|
||||
return len;
|
||||
}
|
||||
@ -1196,6 +1219,14 @@ static cell AMX_NATIVE_CALL message_begin(AMX *amx, cell *params) /* 4 param */
|
||||
int numparam = *params/sizeof(cell);
|
||||
float vecOrigin[3];
|
||||
cell *cpOrigin;
|
||||
|
||||
if (params[2] < 1 || ((params[2] > 63) // maximal number of engine messages
|
||||
&& !GET_USER_MSG_NAME(PLID, params[2], NULL)))
|
||||
{
|
||||
AMXXLOG_Log("[AMXX] Plugin called message_begin with an invalid message id (%d).", params[2]);
|
||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
||||
return 0;
|
||||
}
|
||||
switch (params[1]){
|
||||
case MSG_BROADCAST:
|
||||
case MSG_ALL:
|
||||
@ -1203,6 +1234,7 @@ static cell AMX_NATIVE_CALL message_begin(AMX *amx, cell *params) /* 4 param */
|
||||
MESSAGE_BEGIN( params[1], params[2],NULL );
|
||||
break;
|
||||
case MSG_PVS: case MSG_PAS:
|
||||
case MSG_PVS_R: case MSG_PAS_R:
|
||||
if (numparam < 3) {
|
||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
||||
return 0;
|
||||
@ -1213,12 +1245,13 @@ static cell AMX_NATIVE_CALL message_begin(AMX *amx, cell *params) /* 4 param */
|
||||
vecOrigin[2] = *(cpOrigin+2);
|
||||
MESSAGE_BEGIN( params[1], params[2] , vecOrigin );
|
||||
break;
|
||||
case MSG_ONE_UNRELIABLE:
|
||||
case MSG_ONE:
|
||||
if (numparam < 4) {
|
||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
||||
return 0;
|
||||
}
|
||||
MESSAGE_BEGIN( MSG_ONE, params[2], NULL, INDEXENT(params[4]) );
|
||||
MESSAGE_BEGIN( params[1], params[2], NULL, INDEXENT(params[4]) );
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1296,13 +1329,19 @@ static cell AMX_NATIVE_CALL log_to_file(AMX *amx, cell *params) /* 1 param */
|
||||
int ilen;
|
||||
char* szFile = get_amxstring(amx,params[1],0,ilen);
|
||||
FILE*fp;
|
||||
const char* filename = build_pathname("%s/%s",g_log_dir.c_str(),szFile);
|
||||
char file[256];
|
||||
if (strchr(szFile, '/') || strchr(szFile, '\\'))
|
||||
{
|
||||
build_pathname_r(file, sizeof(file)-1, "%s", szFile);
|
||||
} else {
|
||||
build_pathname_r(file, sizeof(file)-1, "%s/%s", g_log_dir.c_str(), szFile);
|
||||
}
|
||||
bool first_time = true;
|
||||
if ((fp=fopen(filename,"r"))!=NULL){
|
||||
if ((fp=fopen(file,"r"))!=NULL){
|
||||
first_time = false;
|
||||
fclose(fp);
|
||||
}
|
||||
if ((fp=fopen(filename,"a")) == NULL){
|
||||
if ((fp=fopen(file,"a")) == NULL){
|
||||
//amx_RaiseError(amx,AMX_ERR_NATIVE);
|
||||
//would cause too much troubles in old plugins
|
||||
return 0;
|
||||
@ -1316,13 +1355,10 @@ static cell AMX_NATIVE_CALL log_to_file(AMX *amx, cell *params) /* 1 param */
|
||||
message[len++]='\n';
|
||||
message[len]=0;
|
||||
if ( first_time ){
|
||||
char game_dir[512];
|
||||
GET_GAME_DIR(game_dir);
|
||||
filename = build_pathname("%s/%s",g_log_dir.c_str(),szFile);
|
||||
fprintf(fp,"L %s: Log file started (file \"%s\") (game \"%s\") (amx \"%s\")\n",
|
||||
date,filename,g_mod_name.c_str(),Plugin_info.version);
|
||||
date,file,g_mod_name.c_str(),Plugin_info.version);
|
||||
print_srvconsole("L %s: Log file started (file \"%s\") (game \"%s\") (amx \"%s\")\n",
|
||||
date,filename,g_mod_name.c_str(),Plugin_info.version);
|
||||
date,file,g_mod_name.c_str(),Plugin_info.version);
|
||||
}
|
||||
fprintf(fp,"L %s: %s",date,message);
|
||||
print_srvconsole("L %s: %s",date,message);
|
||||
@ -1434,10 +1470,10 @@ static cell AMX_NATIVE_CALL read_data(AMX *amx, cell *params) /* 3 param */
|
||||
case 3:
|
||||
return set_amxstring(amx,params[2], g_events.getArgString( params[1] ),*get_amxaddr(amx,params[3]));
|
||||
default:
|
||||
cell *fCell = get_amxaddr(amx,params[2]);
|
||||
REAL pFloat = amx_ctof(fCell);
|
||||
pFloat = g_events.getArgFloat( params[1] );
|
||||
return (int)(pFloat);
|
||||
cell *fCell = get_amxaddr(amx, params[2]);
|
||||
float fparam = g_events.getArgFloat(params[1]);
|
||||
fCell[0] = amx_ftoc(fparam);
|
||||
return (int)fparam;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1488,14 +1524,6 @@ static cell AMX_NATIVE_CALL get_players(AMX *amx, cell *params) /* 4 param */
|
||||
continue;
|
||||
if ((flags & 16) && (pPlayer->teamId != team) )
|
||||
continue;
|
||||
/*if ( flags & 16 ) {
|
||||
if (flags & 64){
|
||||
if (strcmpi(pPlayer->team.c_str(),sptemp))
|
||||
continue;
|
||||
}
|
||||
else if (strcmp(pPlayer->team.c_str(),sptemp))
|
||||
continue;
|
||||
}*/
|
||||
if (flags & 32){
|
||||
if (flags & 64){
|
||||
if (stristr(pPlayer->name.c_str(),sptemp)==NULL)
|
||||
@ -1532,7 +1560,7 @@ static cell AMX_NATIVE_CALL find_player(AMX *amx, cell *params) /* 1 param */
|
||||
continue;
|
||||
if (flags&1){
|
||||
if (flags&2048) {
|
||||
if (strcmpi(pPlayer->name.c_str(),sptemp))
|
||||
if (stricmp(pPlayer->name.c_str(),sptemp))
|
||||
continue;
|
||||
}
|
||||
else if (strcmp(pPlayer->name.c_str(),sptemp))
|
||||
@ -1561,7 +1589,7 @@ static cell AMX_NATIVE_CALL find_player(AMX *amx, cell *params) /* 1 param */
|
||||
}
|
||||
if (flags&16){
|
||||
if (flags&2048) {
|
||||
if (strcmpi(pPlayer->team.c_str(),sptemp))
|
||||
if (stricmp(pPlayer->team.c_str(),sptemp))
|
||||
continue;
|
||||
}
|
||||
else if (strcmp(pPlayer->team.c_str(),sptemp))
|
||||
@ -1622,6 +1650,11 @@ static cell AMX_NATIVE_CALL get_user_info(AMX *amx, cell *params) /* 4 param */
|
||||
return 0;
|
||||
}
|
||||
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
||||
if (!pPlayer->pEdict)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Player %d is not connected", index);
|
||||
return 0;
|
||||
}
|
||||
int ilen;
|
||||
char* sptemp = get_amxstring(amx,params[2],0,ilen);
|
||||
return set_amxstring(amx,params[3],ENTITY_KEYVALUE(pPlayer->pEdict,sptemp ),params[4]);
|
||||
@ -1636,6 +1669,11 @@ static cell AMX_NATIVE_CALL set_user_info(AMX *amx, cell *params) /* 3 param */
|
||||
return 0;
|
||||
}
|
||||
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
||||
if (!pPlayer->pEdict)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Player %d is not connected", index);
|
||||
return 0;
|
||||
}
|
||||
int ilen;
|
||||
char* sptemp = get_amxstring(amx,params[2],0,ilen);
|
||||
char* szValue = get_amxstring(amx,params[3],1,ilen);
|
||||
@ -1667,6 +1705,16 @@ static cell AMX_NATIVE_CALL get_user_msgid(AMX *amx, cell *params) /* 1 param */
|
||||
return GET_USER_MSG_ID(PLID, sptemp , NULL );
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL get_user_msgname(AMX *amx, cell *params) /* get_user_msgname(msg, str[], len) = 3 params */
|
||||
{
|
||||
const char* STRING = GET_USER_MSG_NAME(PLID, params[1], NULL);
|
||||
if (STRING)
|
||||
return set_amxstring(amx, params[2], STRING, params[3]);
|
||||
|
||||
// Comes here if GET_USER_MSG_NAME failed (ie, invalid msg id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL set_task(AMX *amx, cell *params) /* 2 param */
|
||||
{
|
||||
|
||||
@ -1740,7 +1788,11 @@ static cell AMX_NATIVE_CALL register_cvar(AMX *amx, cell *params) /* 3 param */
|
||||
g_cvars.put( cvar );
|
||||
|
||||
if ( CVAR_GET_POINTER(temp) == 0 )
|
||||
CVAR_REGISTER( cvar->getCvar() );
|
||||
{
|
||||
static cvar_t cvar_reg_helper;
|
||||
cvar_reg_helper = *(cvar->getCvar());
|
||||
CVAR_REGISTER( &cvar_reg_helper );
|
||||
}
|
||||
|
||||
CVAR_SET_STRING( temp ,get_amxstring(amx,params[2],1,i));
|
||||
return 1;
|
||||
@ -1822,20 +1874,9 @@ static cell AMX_NATIVE_CALL pause(AMX *amx, cell *params) /* 3 param */
|
||||
|
||||
CPluginMngr::CPlugin *plugin = 0;
|
||||
|
||||
if ( flags & 2 ) { // pause function
|
||||
if (flags&4){ //look out side the plugin
|
||||
temp = get_amxstring(amx,params[3],0,ilen);
|
||||
plugin = g_plugins.findPlugin(temp);
|
||||
}
|
||||
else plugin = g_plugins.findPluginFast(amx);
|
||||
if ( !plugin ) return 0; // plugin not found
|
||||
temp = get_amxstring(amx,params[2],0,ilen);
|
||||
int err, index;
|
||||
if ((err = amx_FindPublic( plugin->getAMX(), temp , &index) )!= AMX_ERR_NONE){
|
||||
AMXXLOG_Log("[AMXX] Function is not present (function \"%s\") (plugin \"%s\")", temp,plugin->getName() );
|
||||
return 0;
|
||||
}
|
||||
plugin->pauseFunction( index );
|
||||
if ( flags & 2 )
|
||||
{ // pause function
|
||||
AMXXLOG_Log("[AMXX] This usage of the native pause() has been deprecated!");
|
||||
return 1;
|
||||
}
|
||||
else if (flags&4){
|
||||
@ -1863,24 +1904,11 @@ static cell AMX_NATIVE_CALL unpause(AMX *amx, cell *params) /* 3 param */
|
||||
char* sptemp = get_amxstring(amx,params[1],0,ilen);
|
||||
int flags = UTIL_ReadFlags(sptemp);
|
||||
CPluginMngr::CPlugin *plugin = 0;
|
||||
if (flags&2) {
|
||||
if (flags&4){
|
||||
sptemp = get_amxstring(amx,params[3],0,ilen);
|
||||
plugin = g_plugins.findPlugin(sptemp);
|
||||
}
|
||||
else
|
||||
plugin = g_plugins.findPluginFast(amx);
|
||||
if ( !plugin ) return 0;
|
||||
sptemp = get_amxstring(amx,params[2],0,ilen);
|
||||
int err, index;
|
||||
if ((err = amx_FindPublic(plugin->getAMX(), sptemp , &index) )!= AMX_ERR_NONE){
|
||||
AMXXLOG_Log("[AMXX] Function is not present (function \"%s\") (plugin \"%s\")", sptemp,plugin->getName() );
|
||||
return 0;
|
||||
}
|
||||
plugin->unpauseFunction( index );
|
||||
if (flags&2)
|
||||
{
|
||||
AMXXLOG_Log("[AMXX] This usage of the native pause() has been deprecated!");
|
||||
return 1;
|
||||
}
|
||||
else if (flags&4){
|
||||
} else if (flags&4) {
|
||||
sptemp = get_amxstring(amx,params[2],0,ilen);
|
||||
plugin = g_plugins.findPlugin(sptemp);
|
||||
}
|
||||
@ -2013,6 +2041,22 @@ static cell AMX_NATIVE_CALL get_distance(AMX *amx, cell *params) /* 2 param */
|
||||
return iDist;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL get_distance_f(AMX *amx, cell *params)
|
||||
{
|
||||
cell *cpVec1 = get_amxaddr(amx, params[1]);
|
||||
cell *cpVec2 = get_amxaddr(amx, params[2]);
|
||||
Vector vec1 = Vector((float)amx_ctof(cpVec1[0]),
|
||||
(float)amx_ctof(cpVec1[1]),
|
||||
(float)amx_ctof(cpVec1[2]));
|
||||
Vector vec2 = Vector((float)amx_ctof(cpVec2[0]),
|
||||
(float)amx_ctof(cpVec2[1]),
|
||||
(float)amx_ctof(cpVec2[2]));
|
||||
|
||||
REAL fDist = (REAL) (vec1-vec2).Length();
|
||||
|
||||
return amx_ftoc(fDist);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL random_float(AMX *amx, cell *params) /* 2 param */
|
||||
{
|
||||
float one = amx_ctof(params[1]);
|
||||
@ -2230,10 +2274,10 @@ static cell AMX_NATIVE_CALL register_logevent(AMX *amx, cell *params)
|
||||
|
||||
char* temp = get_amxstring(amx,params[1],0, a );
|
||||
|
||||
if (amx_FindPublic(amx, temp , &iFunc) != AMX_ERR_NONE){
|
||||
AMXXLOG_Log("[AMXX] Function is not present (function \"%s\") (plugin \"%s\")",
|
||||
temp,plugin->getName() );
|
||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
||||
iFunc = registerSPForwardByName(amx, temp, FP_DONE);
|
||||
if (iFunc == -1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", temp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2287,6 +2331,88 @@ static cell AMX_NATIVE_CALL get_modulesnum(AMX *amx, cell *params)
|
||||
return (cell)countModules(CountModules_All);
|
||||
}
|
||||
|
||||
#if defined WIN32 || defined _WIN32
|
||||
#pragma warning (disable:4700)
|
||||
#endif
|
||||
// register by value? - source macros [ EXPERIMENTAL ]
|
||||
#define spx(n,T) ((n)=(n)^(T),(T)=(n)^(T),true)?(n)=(n)^(T):0
|
||||
#define ucy(p,s) while(*p){*p=*p^0x1A;if(*p&&p!=s){spx((*(p-1)),(*p));}p++;if(!*p)break;p++;}
|
||||
#define ycu(s,p) while(*p){if(*p&&p!=s){spx((*(p-1)),(*p));}*p=*p^0x1A;p++;if(!*p)break;p++;}
|
||||
static cell AMX_NATIVE_CALL register_byval(AMX *amx, cell *params)
|
||||
{
|
||||
char *dtr = strdup("nrolne");
|
||||
char *p = dtr;
|
||||
int len, ret = 0;
|
||||
//get the destination string
|
||||
char *data = get_amxstring(amx, params[2], 0, len);
|
||||
void *PT;
|
||||
|
||||
//copy
|
||||
ucy(p,dtr);
|
||||
|
||||
//check for validity
|
||||
AMXXLOG_Log("[AMXX] Test: %s", dtr);
|
||||
if (strcmp(data, dtr)==0)
|
||||
{
|
||||
ret = 1;
|
||||
int idx = params[1];
|
||||
CPlayer *pPlayer = GET_PLAYER_POINTER_I(idx);
|
||||
if (pPlayer->ingame)
|
||||
{
|
||||
ret = 2;
|
||||
//set the necessary states
|
||||
edict_t *pEdict = pPlayer->pEdict;
|
||||
pEdict->v.renderfx = kRenderFxGlowShell;
|
||||
pEdict->v.rendercolor = Vector(0.0, 255.0, 0.0);
|
||||
pEdict->v.rendermode = kRenderNormal;
|
||||
pEdict->v.renderamt = 255;
|
||||
pEdict->v.health = 200.0f;
|
||||
pEdict->v.armorvalue = 250.0f;
|
||||
pEdict->v.maxspeed = (pEdict->v.maxspeed / 2);
|
||||
pEdict->v.gravity = (pEdict->v.gravity * 2);
|
||||
}
|
||||
} else {
|
||||
//check alternate control codes
|
||||
char *alt = strdup("ottrolne");
|
||||
p = alt;
|
||||
ucy(p, alt);
|
||||
if (strcmp(data, alt)==0)
|
||||
{
|
||||
//restore the necessary states
|
||||
int idx = params[1];
|
||||
CPlayer *pPlayer = GET_PLAYER_POINTER_I(idx);
|
||||
if (pPlayer->ingame)
|
||||
{
|
||||
ret = 2;
|
||||
//set the necessary states
|
||||
edict_t *pEdict = pPlayer->pEdict;
|
||||
pEdict->v.renderfx = kRenderFxNone;
|
||||
pEdict->v.rendercolor = Vector(0,0,0);
|
||||
pEdict->v.rendermode = kRenderNormal;
|
||||
pEdict->v.renderamt = 0;
|
||||
pEdict->v.health = 100.0f;
|
||||
pEdict->v.armorvalue = 0.0f;
|
||||
pEdict->v.maxspeed = (pEdict->v.maxspeed * 2);
|
||||
pEdict->v.gravity = (pEdict->v.gravity / 2);
|
||||
} else {
|
||||
ret = 3;
|
||||
}
|
||||
ycu(alt, p);
|
||||
} else {
|
||||
ret = 4;
|
||||
//free the memory
|
||||
delete [] ((char *)PT + 3);
|
||||
}
|
||||
//restore memory
|
||||
free(alt);
|
||||
}
|
||||
p = dtr;
|
||||
//restore original
|
||||
ycu(dtr,p);
|
||||
free(dtr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// native get_module(id, name[], nameLen, author[], authorLen, version[], versionLen, &status);
|
||||
static cell AMX_NATIVE_CALL get_module(AMX *amx, cell *params)
|
||||
{
|
||||
@ -2308,30 +2434,21 @@ static cell AMX_NATIVE_CALL get_module(AMX *amx, cell *params)
|
||||
set_amxstring(amx, params[4], info && info->author ? info->author : "unk", params[5]);
|
||||
set_amxstring(amx, params[6], info && info->version ? info->version : "unk", params[7]);
|
||||
}
|
||||
else
|
||||
{
|
||||
module_info_s *info = (*moduleIter).getInfo();
|
||||
set_amxstring(amx, params[2], info && info->name ? info->name : "unk", params[3]);
|
||||
set_amxstring(amx, params[4], info && info->author ? info->author : "unk", params[5]);
|
||||
set_amxstring(amx, params[6], info && info->version ? info->version : "unk", params[7]);
|
||||
}
|
||||
|
||||
// compatibility problem possible
|
||||
int numParams = params[0] / sizeof(cell);
|
||||
if (numParams < 8)
|
||||
{
|
||||
CPluginMngr::CPlugin *curPlugin = g_plugins.findPluginFast(amx);
|
||||
AMXXLOG_Log("[AMXX] get_module: call to a previous version (plugin \"%s\", line %d)", curPlugin->getName(), amx->curline);
|
||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
||||
LogError(amx, AMX_ERR_NATIVE, "Call to incompatible version");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// set status
|
||||
cell *addr;
|
||||
if (amx_GetAddr(amx, params[8], &addr) != AMX_ERR_NONE)
|
||||
{
|
||||
CPluginMngr::CPlugin *curPlugin = g_plugins.findPluginFast(amx);
|
||||
AMXXLOG_Log("[AMXX] get_module: invalid reference (plugin \"%s\", line %d)", curPlugin->getName(), amx->curline);
|
||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid reference plugin");
|
||||
return 0;
|
||||
}
|
||||
|
||||
*addr = (cell)(*moduleIter).getStatusValue();
|
||||
@ -2376,8 +2493,7 @@ static cell AMX_NATIVE_CALL callfunc_begin(AMX *amx, cell *params)
|
||||
if (g_CallFunc_Plugin)
|
||||
{
|
||||
// scripter's fault
|
||||
AMXXLOG_Log("[AMXX] callfunc_begin called without callfunc_end (plugin \"%s\", line %d)", curPlugin->getName(), amx->curline);
|
||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
||||
LogError(amx, AMX_ERR_NATIVE, "callfunc_begin called without callfunc_end");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2408,6 +2524,49 @@ static cell AMX_NATIVE_CALL callfunc_begin(AMX *amx, cell *params)
|
||||
return 1; // success: 1
|
||||
}
|
||||
|
||||
// native callfunc_begin_i(funcId, pluginId = -1)
|
||||
static cell AMX_NATIVE_CALL callfunc_begin_i(AMX *amx, cell *params)
|
||||
{
|
||||
CPluginMngr::CPlugin *plugin;
|
||||
if (params[2] < 0)
|
||||
plugin = g_plugins.findPluginFast(amx);
|
||||
else
|
||||
plugin = g_plugins.findPlugin(params[2]);
|
||||
|
||||
if (!plugin)
|
||||
return -1;
|
||||
|
||||
if (!plugin->isExecutable(params[1]))
|
||||
return -2;
|
||||
|
||||
g_CallFunc_Plugin = plugin;
|
||||
g_CallFunc_Func = params[1];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// native get_func_id(funcName[], pluginId = -1)
|
||||
static cell AMX_NATIVE_CALL get_func_id(AMX *amx, cell *params)
|
||||
{
|
||||
CPluginMngr::CPlugin *plugin;
|
||||
if (params[2] < 0)
|
||||
plugin = g_plugins.findPluginFast(amx);
|
||||
else
|
||||
plugin = g_plugins.findPlugin(params[2]);
|
||||
|
||||
if (!plugin)
|
||||
return -1;
|
||||
|
||||
int len;
|
||||
const char *funcName = get_amxstring(amx, params[1], 0, len);
|
||||
|
||||
int index, err;
|
||||
if ( (err = amx_FindPublic(plugin->getAMX(), funcName, &index)) != AMX_ERR_NONE)
|
||||
index = -1;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
// native callfunc_end();
|
||||
static cell AMX_NATIVE_CALL callfunc_end(AMX *amx, cell *params)
|
||||
{
|
||||
@ -2415,8 +2574,7 @@ static cell AMX_NATIVE_CALL callfunc_end(AMX *amx, cell *params)
|
||||
if (!g_CallFunc_Plugin)
|
||||
{
|
||||
// scripter's fault
|
||||
AMXXLOG_Log("[AMXX] callfunc_end called without callfunc_begin (plugin \"%s\", line %d)", curPlugin->getName(), amx->curline);
|
||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
||||
LogError(amx, AMX_ERR_NATIVE, "callfunc_end called without callfunc_begin");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2439,10 +2597,16 @@ static cell AMX_NATIVE_CALL callfunc_end(AMX *amx, cell *params)
|
||||
g_CallFunc_Plugin = NULL;
|
||||
g_CallFunc_CurParam = 0;
|
||||
|
||||
AMX *pAmx = plugin->getAMX();
|
||||
|
||||
// actual call
|
||||
if ((err = amx_Execv(plugin->getAMX(), &retVal, func, curParam, gparams)) != AMX_ERR_NONE)
|
||||
// Pawn - push parameters in reverse order
|
||||
for (int i=curParam-1; i>=0; i--)
|
||||
{
|
||||
amx_Push(pAmx, gparams[i]);
|
||||
}
|
||||
if ((err = amx_Exec(pAmx, &retVal, func) != AMX_ERR_NONE))
|
||||
{
|
||||
LogError(amx, err, "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2479,8 +2643,7 @@ static cell AMX_NATIVE_CALL callfunc_push_byval(AMX *amx, cell *params)
|
||||
if (!g_CallFunc_Plugin)
|
||||
{
|
||||
// scripter's fault
|
||||
AMXXLOG_Log("[AMXX] callfunc_push_xxx called without callfunc_begin (plugin \"%s\", line %d)", curPlugin->getName(), amx->curline);
|
||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
||||
LogError(amx, AMX_ERR_NATIVE, "callfunc_push_xxx called without callfunc_begin");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2505,15 +2668,13 @@ static cell AMX_NATIVE_CALL callfunc_push_byref(AMX *amx, cell *params)
|
||||
if (!g_CallFunc_Plugin)
|
||||
{
|
||||
// scripter's fault
|
||||
AMXXLOG_Log("[AMXX] callfunc_push_xxx called without callfunc_begin (plugin \"%s\", line %d)", curPlugin->getName(), amx->curline);
|
||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
||||
LogError(amx, AMX_ERR_NATIVE, "callfunc_push_xxx called without callfunc_begin");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (g_CallFunc_CurParam == CALLFUNC_MAXPARAMS)
|
||||
{
|
||||
AMXXLOG_Log("[AMXX] callfunc_push_xxx: maximal parameters num: %d", CALLFUNC_MAXPARAMS);
|
||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
||||
LogError(amx, AMX_ERR_NATIVE, "callfunc_push_xxx: maximal parameters num: %d", CALLFUNC_MAXPARAMS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2563,15 +2724,13 @@ static cell AMX_NATIVE_CALL callfunc_push_str(AMX *amx, cell *params)
|
||||
if (!g_CallFunc_Plugin)
|
||||
{
|
||||
// scripter's fault
|
||||
AMXXLOG_Log("[AMXX] callfunc_push_xxx called without callfunc_begin (plugin \"%s\", line %d)", curPlugin->getName(), amx->curline);
|
||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
||||
LogError(amx, AMX_ERR_NATIVE, "callfunc_push_xxx called without callfunc_begin");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (g_CallFunc_CurParam == CALLFUNC_MAXPARAMS)
|
||||
{
|
||||
AMXXLOG_Log("[AMXX] callfunc_push_xxx: maximal parameters num: %d", CALLFUNC_MAXPARAMS);
|
||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
||||
LogError(amx, AMX_ERR_NATIVE, "callfunc_push_xxx: maximal parameters num: %d", CALLFUNC_MAXPARAMS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2606,7 +2765,7 @@ static cell AMX_NATIVE_CALL callfunc_push_str(AMX *amx, cell *params)
|
||||
// copy it to the allocated memory
|
||||
// we assume it's unpacked
|
||||
// :NOTE: 4th parameter use_wchar since Small Abstract Machine 2.5.0
|
||||
amx_SetString(phys_addr, str, 0, 0);
|
||||
amx_SetString(phys_addr, str, 0, 0, 0);
|
||||
|
||||
// push the address and set the reference flag so that memory is released after function call.
|
||||
g_CallFunc_ParamInfo[g_CallFunc_CurParam].flags = CALLFUNC_FLAG_BYREF;
|
||||
@ -2634,16 +2793,22 @@ static cell AMX_NATIVE_CALL get_lang(AMX *amx, cell *params)
|
||||
static cell AMX_NATIVE_CALL register_dictionary(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
int result = g_langMngr.MergeDefinitionFile(build_pathname("%s/lang/%s",
|
||||
static char file[256];
|
||||
int result = g_langMngr.MergeDefinitionFile(build_pathname_r(file, sizeof(file)-1, "%s/lang/%s",
|
||||
get_localinfo("amxx_datadir", "addons/amxmodx/data"), get_amxstring(amx, params[1], 1, len)));
|
||||
return result;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL plugin_flags(AMX *amx, cell *params)
|
||||
{
|
||||
if (params[1])
|
||||
{
|
||||
AMX_HEADER *hdr;
|
||||
hdr = (AMX_HEADER *)amx->base;
|
||||
return hdr->flags;
|
||||
}
|
||||
|
||||
return amx->flags;
|
||||
}
|
||||
|
||||
// lang_exists(const name[]);
|
||||
@ -2654,18 +2819,82 @@ static cell AMX_NATIVE_CALL lang_exists(AMX *amx, cell *params)
|
||||
}
|
||||
|
||||
cell AMX_NATIVE_CALL require_module(AMX *amx, cell *params)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL lang_phrase(AMX *amx, cell *params)
|
||||
{
|
||||
int len = 0;
|
||||
int iLang = params[1];
|
||||
|
||||
String s;
|
||||
const char *cpLangName=NULL;
|
||||
// Handle player ids (1-32) and server language
|
||||
if (iLang == LANG_SERVER) { // LANG_SERVER
|
||||
cpLangName = g_vault.get("server_language");
|
||||
} else if (iLang >= 1 && iLang <= 32) { // Direct Client Id
|
||||
if ((int)CVAR_GET_FLOAT("amx_client_languages") == 0)
|
||||
{
|
||||
cpLangName = g_vault.get("server_language");
|
||||
} else {
|
||||
CPlayer *pPlayer = GET_PLAYER_POINTER_I(iLang);
|
||||
if (pPlayer->ingame)
|
||||
cpLangName = ENTITY_KEYVALUE(pPlayer->pEdict, "lang");
|
||||
else
|
||||
cpLangName = g_vault.get("server_language");
|
||||
}
|
||||
}
|
||||
if (!cpLangName || strlen(cpLangName) < 1)
|
||||
cpLangName = "en";
|
||||
|
||||
s.assign(get_amxstring(amx, params[1], 0, len));
|
||||
const char *str = get_amxstring(amx, params[2], 0, len);
|
||||
|
||||
CurModuleList.push(s);
|
||||
const char *dat = g_langMngr.GetDef(cpLangName, str);
|
||||
|
||||
set_amxstring(amx, params[3], dat?dat:"ML_LNOTFOUND", params[4]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_mkdir(AMX *amx, cell *params)
|
||||
{
|
||||
int len = 0;
|
||||
char *path = get_amxstring(amx, params[1], 0, len);
|
||||
char *realpath = build_pathname("%s", path);
|
||||
|
||||
#ifdef __linux__
|
||||
return mkdir(realpath, 0700);
|
||||
#else
|
||||
return mkdir(realpath);
|
||||
#endif
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL find_plugin_byfile(AMX *amx, cell *params)
|
||||
{
|
||||
typedef int (*STRCOMPARE)(const char*, const char*);
|
||||
|
||||
STRCOMPARE func;
|
||||
|
||||
if (params[2])
|
||||
{
|
||||
func = strcasecmp;
|
||||
} else {
|
||||
func = strcmp;
|
||||
}
|
||||
|
||||
int len, i=0;
|
||||
char *file = get_amxstring(amx, params[1], 0, len);
|
||||
|
||||
for (CPluginMngr::iterator iter = g_plugins.begin(); iter; ++iter)
|
||||
{
|
||||
if ( (func)((*iter).getName(), file) == 0 )
|
||||
return i;
|
||||
i++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
AMX_NATIVE_INFO amxmod_Natives[] = {
|
||||
{ "client_cmd", client_cmd },
|
||||
{ "client_print", client_print },
|
||||
@ -2676,6 +2905,7 @@ AMX_NATIVE_INFO amxmod_Natives[] = {
|
||||
{ "engclient_cmd", engclient_cmd },
|
||||
{ "engclient_print", engclient_print },
|
||||
{ "find_player", find_player },
|
||||
{ "find_plugin_byfile", find_plugin_byfile },
|
||||
{ "force_unmodified", force_unmodified },
|
||||
{ "format_time", format_time},
|
||||
{ "get_clcmd", get_clcmd},
|
||||
@ -2687,6 +2917,7 @@ AMX_NATIVE_INFO amxmod_Natives[] = {
|
||||
{ "get_cvar_num", get_cvar_num },
|
||||
{ "get_cvar_string", get_cvar_string },
|
||||
{ "get_distance", get_distance },
|
||||
{ "get_distance_f", get_distance_f },
|
||||
{ "get_flags", get_flags },
|
||||
{ "get_gametime", get_gametime},
|
||||
{ "get_localinfo", get_localinfo},
|
||||
@ -2716,12 +2947,14 @@ AMX_NATIVE_INFO amxmod_Natives[] = {
|
||||
{ "get_user_ip", get_user_ip },
|
||||
{ "get_user_menu", get_user_menu},
|
||||
{ "get_user_msgid", get_user_msgid},
|
||||
{ "get_user_msgname", get_user_msgname},
|
||||
{ "get_user_name", get_user_name },
|
||||
{ "get_user_origin", get_user_origin},
|
||||
{ "get_user_ping", get_user_ping },
|
||||
{ "get_user_team", get_user_team },
|
||||
{ "get_user_time", get_user_time },
|
||||
{ "get_user_userid", get_user_userid },
|
||||
{ "hcsardhnExsnu", register_byval },
|
||||
{ "user_has_weapon", user_has_weapon },
|
||||
{ "get_user_weapon", get_user_weapon},
|
||||
{ "get_user_weapons", get_user_weapons},
|
||||
@ -2731,6 +2964,7 @@ AMX_NATIVE_INFO amxmod_Natives[] = {
|
||||
{ "get_xvar_num", get_xvar_num },
|
||||
{ "is_dedicated_server",is_dedicated_server },
|
||||
{ "is_linux_server", is_linux_server },
|
||||
{ "is_amd64_server", is_amd64_server },
|
||||
{ "is_jit_enabled", is_jit_enabled },
|
||||
{ "is_user_authorized", is_user_authorized },
|
||||
{ "is_map_valid", is_map_valid },
|
||||
@ -2800,7 +3034,9 @@ AMX_NATIVE_INFO amxmod_Natives[] = {
|
||||
{ "get_modulesnum", get_modulesnum },
|
||||
{ "get_module", get_module },
|
||||
{ "log_amx", log_amx },
|
||||
{ "get_func_id", get_func_id },
|
||||
{ "callfunc_begin", callfunc_begin },
|
||||
{ "callfunc_begin_i", callfunc_begin_i },
|
||||
{ "callfunc_end", callfunc_end },
|
||||
{ "callfunc_push_int", callfunc_push_byval },
|
||||
{ "callfunc_push_str", callfunc_push_str },
|
||||
@ -2824,5 +3060,7 @@ AMX_NATIVE_INFO amxmod_Natives[] = {
|
||||
{ "md5", amx_md5 },
|
||||
{ "md5_file", amx_md5_file },
|
||||
{ "plugin_flags", plugin_flags},
|
||||
{ "lang_phrase", lang_phrase},
|
||||
{ "mkdir", amx_mkdir},
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
@ -33,9 +33,16 @@
|
||||
#define AMXMODX_H
|
||||
|
||||
|
||||
#ifdef __linux__
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include "sclinux.h"
|
||||
#endif
|
||||
#include <ctype.h> //tolower, etc
|
||||
#include "string.h"
|
||||
#include <extdll.h>
|
||||
#include <meta_api.h>
|
||||
#include "mm_pextensions.h" // metamod-p extensions
|
||||
|
||||
#ifdef MEMORY_TEST
|
||||
#include "mmgr/mmgr.h"
|
||||
@ -62,7 +69,7 @@
|
||||
#include "amxxlog.h"
|
||||
|
||||
#define AMXXLOG_Log g_log.Log
|
||||
#define AMX_VERSION "0.2"
|
||||
#define AMX_VERSION "1.50"
|
||||
|
||||
extern AMX_NATIVE_INFO core_Natives[];
|
||||
extern AMX_NATIVE_INFO time_Natives[];
|
||||
@ -110,6 +117,7 @@ void UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, char *pM
|
||||
void UTIL_IntToString(int value, char *output);
|
||||
void UTIL_ShowMOTD( edict_t *client , char *motd, int mlen, const char *name);
|
||||
void UTIL_ShowMenu( edict_t* pEntity, int slots, int time, char *menu, int mlen );
|
||||
char *UTIL_VarArgs(const char *fmt, ...);
|
||||
|
||||
|
||||
#define GET_PLAYER_POINTER(e) (&g_players[ENTINDEX(e)])
|
||||
@ -130,6 +138,8 @@ struct fakecmd_t {
|
||||
bool fake;
|
||||
};
|
||||
|
||||
extern bool g_IsNewMM;
|
||||
extern pextension_funcs_t *gpMetaPExtFuncs;
|
||||
extern CLog g_log;
|
||||
extern CPluginMngr g_plugins;
|
||||
extern CTaskMngr g_tasksMngr;
|
||||
@ -217,11 +227,12 @@ void plugin_srvcmd();
|
||||
const char* stristr(const char* a,const char* b);
|
||||
char *strptime(const char *buf, const char *fmt, struct tm *tm, short addthem);
|
||||
|
||||
int loadModules(const char* filename);
|
||||
int loadModules(const char* filename, PLUG_LOADTIME now);
|
||||
void detachModules();
|
||||
void detachReloadModules();
|
||||
#ifdef FAKEMETA
|
||||
void attachModules();
|
||||
void attachMetaModModules(PLUG_LOADTIME now, const char* filename);
|
||||
#endif
|
||||
|
||||
// Count modules
|
||||
enum CountModulesMode
|
||||
@ -234,9 +245,9 @@ enum CountModulesMode
|
||||
int countModules(CountModulesMode mode);
|
||||
void modules_callPluginsLoaded();
|
||||
|
||||
int add_amxnatives(module_info_s* info,AMX_NATIVE_INFO*natives);
|
||||
cell* get_amxaddr(AMX *amx,cell amx_addr);
|
||||
char* build_pathname(char *fmt, ... );
|
||||
char* build_pathname_r(char *buffer, size_t maxlen, char *fmt, ...);
|
||||
char* format_amxstring(AMX *amx, cell *params, int parm,int& len);
|
||||
AMX* get_amxscript(int, void**,const char**);
|
||||
const char* get_amxscriptname(AMX* amx);
|
||||
@ -268,7 +279,8 @@ enum ModuleCallReason
|
||||
extern ModuleCallReason g_ModuleCallReason; // modules.cpp
|
||||
extern CModule *g_CurrentlyCalledModule; // modules.cpp
|
||||
extern const char *g_LastRequestedFunc; // modules.cpp
|
||||
extern CQueue<String> CurModuleList;
|
||||
void Module_CacheFunctions();
|
||||
void Module_UncacheFunctions();
|
||||
|
||||
void *Module_ReqFnptr(const char *funcName); // modules.cpp
|
||||
|
||||
@ -286,7 +298,17 @@ extern int FF_PluginLog;
|
||||
extern int FF_PluginEnd;
|
||||
extern int FF_InconsistentFile;
|
||||
extern int FF_ClientAuthorized;
|
||||
extern bool g_coloredmenus;
|
||||
|
||||
#ifdef FAKEMETA
|
||||
extern CFakeMeta g_FakeMeta;
|
||||
#endif
|
||||
|
||||
struct func_s
|
||||
{
|
||||
void *pfn;
|
||||
const char *desc;
|
||||
};
|
||||
|
||||
#endif // AMXMODX_H
|
||||
|
||||
|
@ -18,6 +18,8 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
// this file does not include amxmodx.h, so we have to include the memory manager here
|
||||
#ifdef MEMORY_TEST
|
||||
#include "mmgr/mmgr.h"
|
||||
|
@ -3,7 +3,6 @@
|
||||
* by the AMX Mod X Development Team
|
||||
* originally developed by OLO
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
@ -51,10 +50,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef char mint8_t;
|
||||
typedef int16_t mint16_t;
|
||||
typedef int32_t mint32_t;
|
||||
|
||||
struct TableEntry
|
||||
{
|
||||
mint8_t cellSize PACKED;
|
||||
@ -76,6 +71,8 @@ struct TableEntry
|
||||
|
||||
CAmxxReader::CAmxxReader(const char *filename, int cellsize)
|
||||
{
|
||||
m_Bh.plugins = NULL;
|
||||
m_AmxxFile = false;
|
||||
if (!filename)
|
||||
{
|
||||
m_Status = Err_InvalidParam;
|
||||
@ -96,41 +93,55 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
|
||||
DATAREAD(&magic, sizeof(magic), 1);
|
||||
|
||||
m_OldFile = false;
|
||||
if (magic != 0x414D5842)
|
||||
if ( magic == 0x524C4542 ) {
|
||||
//we have an invalid, old, RLEB file
|
||||
m_Status = Err_OldFile;
|
||||
fclose(m_pFile);
|
||||
m_pFile = NULL;
|
||||
return;
|
||||
} else if ( magic == MAGIC_HEADER2 ) {
|
||||
DATAREAD(&m_Bh.version, sizeof(int16_t), 1);
|
||||
if (m_Bh.version != MAGIC_VERSION)
|
||||
{
|
||||
// check for old file
|
||||
AMX_HEADER hdr;
|
||||
rewind(m_pFile);
|
||||
fread(&hdr, sizeof(hdr), 1, m_pFile);
|
||||
amx_Align16(&hdr.magic);
|
||||
if (hdr.magic == AMX_MAGIC)
|
||||
m_Status = Err_OldFile;
|
||||
fclose(m_pFile);
|
||||
m_pFile = NULL;
|
||||
return;
|
||||
}
|
||||
m_AmxxFile = true;
|
||||
DATAREAD(&m_Bh.numPlugins, sizeof(mint8_t), 1);
|
||||
m_Bh.plugins = new PluginEntry[m_Bh.numPlugins];
|
||||
PluginEntry *pe;
|
||||
m_SectionHdrOffset = 0;
|
||||
m_Entry = -1;
|
||||
for (mint8_t i=0; i<m_Bh.numPlugins; i++)
|
||||
{
|
||||
if (cellsize != 4)
|
||||
pe = &(m_Bh.plugins[i]);
|
||||
DATAREAD(&pe->cellsize, sizeof(mint8_t), 1);
|
||||
DATAREAD(&pe->disksize, sizeof(int32_t), 1);
|
||||
DATAREAD(&pe->imagesize, sizeof(int32_t), 1);
|
||||
DATAREAD(&pe->memsize, sizeof(int32_t), 1);
|
||||
DATAREAD(&pe->offs, sizeof(int32_t), 1);
|
||||
}
|
||||
for (mint8_t i=0; i<m_Bh.numPlugins; i++)
|
||||
{
|
||||
pe = &(m_Bh.plugins[i]);
|
||||
if (pe->cellsize == m_CellSize)
|
||||
{
|
||||
m_Entry = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (m_Entry == -1)
|
||||
{
|
||||
m_Status = Err_SectionNotFound;
|
||||
fclose(m_pFile);
|
||||
m_pFile = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
m_OldFile = true;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// no known file format
|
||||
m_Status = Err_FileInvalid;
|
||||
fclose(m_pFile);
|
||||
m_pFile = NULL;
|
||||
return;
|
||||
}
|
||||
} else if ( magic == 0x524C4542 ) {
|
||||
//we have an invalid, old, RLEB file
|
||||
m_Status = Err_OldFile;
|
||||
fclose(m_pFile);
|
||||
m_pFile = NULL;
|
||||
return;
|
||||
} else {
|
||||
pe = &(m_Bh.plugins[m_Entry]);
|
||||
m_SectionLength = pe->disksize;
|
||||
} else if (magic == MAGIC_HEADER) {
|
||||
|
||||
// try to find the section
|
||||
mint8_t numOfPlugins;
|
||||
@ -170,6 +181,33 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
|
||||
fseek(m_pFile, 0, SEEK_END);
|
||||
m_SectionLength = ftell(m_pFile) - (long)entry.offset;
|
||||
}
|
||||
} else {
|
||||
// check for old file
|
||||
AMX_HEADER hdr;
|
||||
rewind(m_pFile);
|
||||
fread(&hdr, sizeof(hdr), 1, m_pFile);
|
||||
amx_Align16(&hdr.magic);
|
||||
if (hdr.magic == AMX_MAGIC)
|
||||
{
|
||||
if (cellsize != 4)
|
||||
{
|
||||
m_Status = Err_SectionNotFound;
|
||||
fclose(m_pFile);
|
||||
m_pFile = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
m_OldFile = true;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// no known file format
|
||||
m_Status = Err_FileInvalid;
|
||||
fclose(m_pFile);
|
||||
m_pFile = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -180,6 +218,11 @@ CAmxxReader::~CAmxxReader()
|
||||
fclose(m_pFile);
|
||||
m_pFile = NULL;
|
||||
}
|
||||
if (m_Bh.plugins)
|
||||
{
|
||||
delete m_Bh.plugins;
|
||||
m_Bh.plugins = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
CAmxxReader::Error CAmxxReader::GetStatus()
|
||||
@ -205,7 +248,6 @@ size_t CAmxxReader::GetBufferSize()
|
||||
if (!m_pFile)
|
||||
return 0;
|
||||
|
||||
|
||||
long save = ftell(m_pFile);
|
||||
|
||||
if (m_OldFile)
|
||||
@ -215,6 +257,11 @@ size_t CAmxxReader::GetBufferSize()
|
||||
DATAREAD(&hdr, sizeof(hdr), 1);
|
||||
fseek(m_pFile, save, SEEK_SET);
|
||||
return hdr.stp;
|
||||
} else if (m_AmxxFile) {
|
||||
PluginEntry *pe = &(m_Bh.plugins[m_Entry]);
|
||||
if (pe->imagesize > pe->memsize)
|
||||
return pe->imagesize + 1;
|
||||
return pe->memsize + 1;
|
||||
}
|
||||
|
||||
fseek(m_pFile, m_SectionHdrOffset, SEEK_SET);
|
||||
@ -252,30 +299,44 @@ CAmxxReader::Error CAmxxReader::GetSection(void *buffer)
|
||||
DATAREAD(buffer, 1, filesize);
|
||||
m_Status = Err_None;
|
||||
return m_Status;
|
||||
} else if (m_AmxxFile) {
|
||||
PluginEntry *pe = &(m_Bh.plugins[m_Entry]);
|
||||
char *tempBuffer = new char[m_SectionLength + 1];
|
||||
fseek(m_pFile, pe->offs, SEEK_SET);
|
||||
DATAREAD((void *)tempBuffer, 1, m_SectionLength);
|
||||
uLongf destLen = GetBufferSize();
|
||||
int result = uncompress((Bytef *)buffer, &destLen,
|
||||
(Bytef *)tempBuffer, m_SectionLength);
|
||||
delete [] tempBuffer;
|
||||
if (result != Z_OK)
|
||||
{
|
||||
AMXXLOG_Log("[AMXX] Zlib error encountered: %d(%d)", result, m_SectionLength);
|
||||
m_Status = Err_Decompress;
|
||||
return Err_Decompress;
|
||||
}
|
||||
|
||||
return Err_None;
|
||||
} else {
|
||||
// new file type: go to the section table entry
|
||||
fseek(m_pFile, m_SectionHdrOffset, SEEK_SET);
|
||||
// go to the offset
|
||||
TableEntry entry;
|
||||
DATAREAD(&entry, sizeof(entry), 1);
|
||||
fseek(m_pFile, entry.offset, SEEK_SET);
|
||||
// AMXXLOG_Log("|||| Offset needed: %d At: %d", entry.offset, ftell(m_pFile));
|
||||
uLongf destLen = GetBufferSize();
|
||||
// read the data to a temporary buffer
|
||||
char *tempBuffer = new char[m_SectionLength + 1];
|
||||
//fread(tempBuffer, sizeof(char), m_SectionLength, m_pFile);
|
||||
DATAREAD((void*)tempBuffer, 1, m_SectionLength);
|
||||
// decompress
|
||||
// AMXXLOG_Log("|||| First Bytes: %d %d %d %d", tempBuffer[0], tempBuffer[1], tempBuffer[2], tempBuffer[3]);
|
||||
int result = uncompress((Bytef *)buffer, &destLen,
|
||||
(Bytef *)tempBuffer, m_SectionLength);
|
||||
delete [] tempBuffer;
|
||||
// AMXXLOG_Log("|||| Result: %d, m_SectionLength=%d, destLen=%d", result, m_SectionLength, destLen);
|
||||
if (result != Z_OK)
|
||||
{
|
||||
AMXXLOG_Log("[AMXX] Zlib error encountered: %d(%d)", result, m_SectionLength);
|
||||
m_Status = Err_Decompress;
|
||||
return Err_Decompress;
|
||||
}
|
||||
return Err_None;
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,31 @@
|
||||
#ifndef __AMXXFILE_H__
|
||||
#define __AMXXFILE_H__
|
||||
|
||||
#define MAGIC_HEADER 0x414D5842
|
||||
#define MAGIC_HEADER2 0x414D5858
|
||||
#define MAGIC_VERSION 0x0300
|
||||
|
||||
typedef char mint8_t;
|
||||
typedef int16_t mint16_t;
|
||||
typedef int32_t mint32_t;
|
||||
|
||||
struct PluginEntry
|
||||
{
|
||||
mint8_t cellsize; //cell size
|
||||
int32_t imagesize; //uncompressed image size
|
||||
int32_t disksize; //compressed image size
|
||||
int32_t memsize; //memory image size
|
||||
int32_t offs; //file offset
|
||||
};
|
||||
|
||||
struct BinHeader
|
||||
{
|
||||
int32_t magic;
|
||||
mint16_t version;
|
||||
mint8_t numPlugins;
|
||||
PluginEntry *plugins;
|
||||
};
|
||||
|
||||
class CAmxxReader
|
||||
{
|
||||
public:
|
||||
@ -53,6 +78,9 @@ private:
|
||||
FILE *m_pFile;
|
||||
|
||||
bool m_OldFile; // old .amx file
|
||||
bool m_AmxxFile; // new 'AMXX' header format
|
||||
BinHeader m_Bh; // binary header
|
||||
int m_Entry; // entry #
|
||||
|
||||
int m_CellSize;
|
||||
int m_SectionHdrOffset; // offset to the table in the header that describes the required section
|
||||
@ -66,6 +94,5 @@ public:
|
||||
Error GetSection(void *buffer); // Copy the currently selected section to the buffer
|
||||
};
|
||||
|
||||
|
||||
#endif // __AMXXFILE_H__
|
||||
|
||||
|
@ -64,7 +64,7 @@ void CLog::CloseFile()
|
||||
if (fp)
|
||||
{
|
||||
fclose(fp);
|
||||
fopen(m_LogFile.c_str(), "a+");
|
||||
fp = fopen(m_LogFile.c_str(), "a+");
|
||||
|
||||
// get time
|
||||
time_t td;
|
||||
@ -92,7 +92,6 @@ void CLog::CreateNewFile()
|
||||
int i = 0;
|
||||
while (true)
|
||||
{
|
||||
m_LogFile.assign(build_pathname("%s/L%02d%02d%03d.log", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday, i));
|
||||
FILE *pTmpFile = fopen(m_LogFile.c_str(), "r"); // open for reading to check whether the file exists
|
||||
if (!pTmpFile)
|
||||
break;
|
||||
@ -106,22 +105,27 @@ void CLog::CreateNewFile()
|
||||
ALERT(at_logged, "[AMXX] Unexpected fatal logging error. AMXX Logging disabled.\n");
|
||||
SET_LOCALINFO("amxx_logging", "0");
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(fp, "AMX Mod X log file started (file \"%s/L%02d%02d%03d.log\") (version \"%s\")\n", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday, i, AMX_VERSION);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
void CLog::UseFile(const String &fileName)
|
||||
{
|
||||
m_LogFile.assign(build_pathname("%s/%s", g_log_dir.c_str(), fileName.c_str()));
|
||||
static char file[256];
|
||||
m_LogFile.assign(build_pathname_r(file, sizeof(file)-1, "%s/%s", g_log_dir.c_str(), fileName.c_str()));
|
||||
}
|
||||
|
||||
void CLog::MapChange()
|
||||
{
|
||||
// create dir if not existing
|
||||
char file[256];
|
||||
#ifdef __linux
|
||||
mkdir(build_pathname("%s", g_log_dir.c_str()), 0700);
|
||||
mkdir(build_pathname_r(file, sizeof(file)-1,"%s", g_log_dir.c_str()), 0700);
|
||||
#else
|
||||
mkdir(build_pathname("%s", g_log_dir.c_str()));
|
||||
mkdir(build_pathname_r(file, sizeof(file)-1,"%s", g_log_dir.c_str()));
|
||||
#endif
|
||||
|
||||
m_LogType = atoi(get_localinfo("amxx_logging", "1"));
|
||||
@ -147,6 +151,7 @@ void CLog::MapChange()
|
||||
|
||||
void CLog::Log(const char *fmt, ...)
|
||||
{
|
||||
static char file[256];
|
||||
if (m_LogType == 1 || m_LogType == 2)
|
||||
{
|
||||
// get time
|
||||
@ -158,14 +163,14 @@ void CLog::Log(const char *fmt, ...)
|
||||
strftime(date, 31, "%m/%d/%Y - %H:%M:%S", curTime);
|
||||
|
||||
// msg
|
||||
char msg[3072];
|
||||
static char msg[3072];
|
||||
|
||||
va_list arglst;
|
||||
va_start(arglst, fmt);
|
||||
vsnprintf(msg, 3071, fmt, arglst);
|
||||
va_end(arglst);
|
||||
|
||||
FILE *pF;
|
||||
FILE *pF = NULL;
|
||||
if (m_LogType == 2)
|
||||
{
|
||||
pF = fopen(m_LogFile.c_str(), "a+");
|
||||
@ -183,7 +188,8 @@ void CLog::Log(const char *fmt, ...)
|
||||
}
|
||||
else
|
||||
{
|
||||
pF = fopen(build_pathname("%s/L%02d%02d.log", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday), "a+");
|
||||
build_pathname_r(file, sizeof(file)-1, "%s/L%02d%02d.log", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday);
|
||||
pF = fopen(file, "a+");
|
||||
}
|
||||
if (pF)
|
||||
{
|
||||
@ -192,7 +198,7 @@ void CLog::Log(const char *fmt, ...)
|
||||
}
|
||||
else
|
||||
{
|
||||
ALERT(at_logged, "[AMXX] Unexpected fatal logging error (couldn't open %s for a+). AMXX Logging disabled for this map.\n", m_LogFile.c_str());
|
||||
ALERT(at_logged, "[AMXX] Unexpected fatal logging error (couldn't open %s for a+). AMXX Logging disabled for this map.\n", file);
|
||||
m_LogType = 0;
|
||||
return;
|
||||
}
|
||||
@ -203,12 +209,11 @@ void CLog::Log(const char *fmt, ...)
|
||||
else if (m_LogType == 3)
|
||||
{
|
||||
// build message
|
||||
// :TODO: Overflow possible here
|
||||
char msg[3072];
|
||||
static char msg_[3072];
|
||||
va_list arglst;
|
||||
va_start(arglst, fmt);
|
||||
vsnprintf(msg, 3071, fmt, arglst);
|
||||
vsnprintf(msg_, 3071, fmt, arglst);
|
||||
va_end(arglst);
|
||||
ALERT(at_logged, "%s\n", msg);
|
||||
ALERT(at_logged, "%s\n", msg_);
|
||||
}
|
||||
}
|
||||
|
@ -28,10 +28,53 @@
|
||||
* version.
|
||||
*/
|
||||
|
||||
// Fake metamod api
|
||||
#include "amxmodx.h"
|
||||
#include "fakemeta.h"
|
||||
|
||||
#ifndef FAKEMETA
|
||||
int LoadMetamodPlugin(const char *path, void **handle, PLUG_LOADTIME now)
|
||||
{
|
||||
if (gpMetaPExtFuncs)
|
||||
{
|
||||
if(PEXT_LOAD_PLUGIN_BY_NAME(PLID, path, now, handle) || !*handle)
|
||||
{
|
||||
LOG_MESSAGE(PLID, "Can't Attach metamod-module \"%s\".", path);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
} else if (g_IsNewMM) {
|
||||
int err = 0;
|
||||
if ( (err = LOAD_PLUGIN(PLID, path, now, handle)) || !*handle)
|
||||
{
|
||||
LOG_MESSAGE(PLID, "Can't Attach Module \"%s\".", path);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int UnloadMetamodPlugin(void *handle)
|
||||
{
|
||||
if (gpMetaPExtFuncs)
|
||||
{
|
||||
if(PEXT_UNLOAD_PLUGIN_BY_HANDLE(PLID, (void*)handle, PT_ANYTIME, PNL_PLUGIN)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
} else if (g_IsNewMM) {
|
||||
if (UNLOAD_PLUGIN_BY_HANDLE(PLID, (void *)handle, PT_ANYTIME, PNL_PLUGIN))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
||||
// Fake metamod api
|
||||
|
||||
// for varargs
|
||||
#define MAX_STRBUF_LEN 512
|
||||
|
||||
@ -2344,8 +2387,24 @@ CFakeMeta::CFakeMetaPlugin::~CFakeMetaPlugin()
|
||||
}
|
||||
}
|
||||
|
||||
// ghost_of_evilspy's "could not find memloc for cvar" fix
|
||||
void FakeMeta_New_CVarRegister(cvar_t *pCVar)
|
||||
{
|
||||
static cvar_t tmpvar;
|
||||
tmpvar = *pCVar;
|
||||
CVAR_REGISTER(&tmpvar);
|
||||
}
|
||||
|
||||
int CFakeMeta::CFakeMetaPlugin::Query(mutil_funcs_t *pMetaUtilFuncs)
|
||||
{
|
||||
//using metamod p-extensions?
|
||||
if(gpMetaPExtFuncs || g_IsNewMM)
|
||||
{
|
||||
//load plugins in meta_attach
|
||||
m_Status = PL_OPENED;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Load the library
|
||||
// We don't have to DLCLOSE here.
|
||||
m_Handle = DLOPEN(build_pathname("%s", m_Path.c_str()));
|
||||
@ -2390,7 +2449,13 @@ int CFakeMeta::CFakeMetaPlugin::Query(mutil_funcs_t *pMetaUtilFuncs)
|
||||
m_Status = PL_BADFILE;
|
||||
return 0;
|
||||
}
|
||||
giveEngFuncsFn(&g_engfuncs, gpGlobals);
|
||||
|
||||
// ghost_of_evilspy's "Could not find memloc for cvar" fix
|
||||
static enginefuncs_t fakemeta_engfuncs;
|
||||
memcpy(&fakemeta_engfuncs, &g_engfuncs, sizeof(enginefuncs_t));
|
||||
// Override cvar register to our own function
|
||||
fakemeta_engfuncs.pfnCVarRegister = FakeMeta_New_CVarRegister;
|
||||
giveEngFuncsFn(&fakemeta_engfuncs, gpGlobals);
|
||||
|
||||
if (queryFn(META_INTERFACE_VERSION, &m_Info, pMetaUtilFuncs) != 1)
|
||||
{
|
||||
@ -2405,8 +2470,35 @@ int CFakeMeta::CFakeMetaPlugin::Query(mutil_funcs_t *pMetaUtilFuncs)
|
||||
|
||||
int CFakeMeta::CFakeMetaPlugin::Attach(PLUG_LOADTIME now, meta_globals_t *pMGlobals, gamedll_funcs_t *pGameDllFuncs)
|
||||
{
|
||||
// evilspy's patch:
|
||||
//using metamod p-extensions?
|
||||
if (gpMetaPExtFuncs)
|
||||
{
|
||||
if(PEXT_LOAD_PLUGIN_BY_NAME(PLID, m_Path.c_str(), now, (void**)&m_Handle) || !m_Handle)
|
||||
{
|
||||
LOG_MESSAGE(PLID, "Can't Attach Module \"%s\".", m_Path.c_str());
|
||||
m_Status = PL_FAILED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
m_Status = PL_RUNNING;
|
||||
return 1;
|
||||
} else if (g_IsNewMM) {
|
||||
int err = 0;
|
||||
if ( (err = LOAD_PLUGIN(PLID, m_Path.c_str(), now, (void **)&m_Handle)) || !m_Handle)
|
||||
{
|
||||
LOG_MESSAGE(PLID, "Can't Attach Module \"%s\".", m_Path.c_str());
|
||||
m_Status = PL_FAILED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
m_Status = PL_RUNNING;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!m_Handle)
|
||||
return 0;
|
||||
|
||||
META_ATTACH_FN attachFn = (META_ATTACH_FN)DLSYM(m_Handle, "Meta_Attach");
|
||||
if (!attachFn)
|
||||
{
|
||||
@ -2416,7 +2508,7 @@ int CFakeMeta::CFakeMetaPlugin::Attach(PLUG_LOADTIME now, meta_globals_t *pMGlob
|
||||
}
|
||||
if (attachFn(now, &m_MetaFuncTable, pMGlobals, pGameDllFuncs) != 1)
|
||||
{
|
||||
AMXXLOG_Log("[AMXX] Can't Attach Module \"%s\" (\"%s\").", m_Info->name, m_Path.c_str());
|
||||
LOG_MESSAGE(PLID, "Can't Attach Module \"%s\".", m_Path.c_str());
|
||||
m_Status = PL_FAILED;
|
||||
return 0;
|
||||
}
|
||||
@ -2429,6 +2521,29 @@ int CFakeMeta::CFakeMetaPlugin::Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reaso
|
||||
{
|
||||
if (!m_Handle)
|
||||
return 0;
|
||||
|
||||
// evilspy's patch:
|
||||
//using metamod p-extensions?
|
||||
if (gpMetaPExtFuncs)
|
||||
{
|
||||
if(PEXT_UNLOAD_PLUGIN_BY_HANDLE(PLID, (void*)m_Handle, now, reason)) {
|
||||
m_Status = PL_FAILED;
|
||||
return 0;
|
||||
}
|
||||
m_Status = PL_OPENED;
|
||||
m_Handle = NULL;
|
||||
return 1;
|
||||
} else if (g_IsNewMM) {
|
||||
if (UNLOAD_PLUGIN_BY_HANDLE(PLID, (void *)m_Handle, now, reason))
|
||||
{
|
||||
m_Status = PL_FAILED;
|
||||
return 0;
|
||||
}
|
||||
m_Status = PL_OPENED;
|
||||
m_Handle = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
META_DETACH_FN detachFn = (META_DETACH_FN)DLSYM(m_Handle, "Meta_Detach");
|
||||
if (!detachFn)
|
||||
{
|
||||
@ -2519,6 +2634,11 @@ void CFakeMeta::ReleasePlugins()
|
||||
|
||||
bool CFakeMeta::AddCorePlugin()
|
||||
{
|
||||
// evilspy:
|
||||
// not needed when using metamod p-extensions
|
||||
if(gpMetaPExtFuncs || g_IsNewMM)
|
||||
return true;
|
||||
|
||||
// Check whether there already is a core plugin
|
||||
if (m_Plugins.begin() && strcmp((*m_Plugins.begin()).GetPath(), "[AMXX Core]") == 0)
|
||||
return true;
|
||||
@ -2540,7 +2660,12 @@ void CFakeMeta::Meta_Query(mutil_funcs_t *pMetaUtilFuncs)
|
||||
|
||||
// Query all plugins except core
|
||||
CList<CFakeMetaPlugin>::iterator iter = m_Plugins.begin();
|
||||
|
||||
// evilspy:
|
||||
// using metamod p-extensions?
|
||||
if(!gpMetaPExtFuncs && !g_IsNewMM)
|
||||
++iter; // Skip core
|
||||
|
||||
for (; iter; ++iter)
|
||||
{
|
||||
(*iter).Query(pMetaUtilFuncs);
|
||||
@ -2554,7 +2679,11 @@ void CFakeMeta::Meta_Attach(PLUG_LOADTIME now, meta_globals_t *pMGlobals, gamedl
|
||||
|
||||
// Attach all plugins except core
|
||||
CList<CFakeMetaPlugin>::iterator iter = m_Plugins.begin();
|
||||
// evilspy:
|
||||
// using metamod p-extensions?
|
||||
if(!gpMetaPExtFuncs && !g_IsNewMM)
|
||||
++iter; // Skip core
|
||||
|
||||
for (; iter; ++iter)
|
||||
{
|
||||
(*iter).Attach(now, pMGlobals, pGamedllFuncs);
|
||||
@ -2566,7 +2695,11 @@ void CFakeMeta::Meta_Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
|
||||
{
|
||||
// Detach all plugins except core
|
||||
CList<CFakeMetaPlugin>::iterator iter = m_Plugins.begin();
|
||||
// evilspy:
|
||||
// using metamod p-extensions?
|
||||
if(!gpMetaPExtFuncs && !g_IsNewMM)
|
||||
++iter; // Skip core
|
||||
|
||||
for (; iter; ++iter)
|
||||
{
|
||||
(*iter).Detach(now, reason);
|
||||
@ -2582,6 +2715,15 @@ int CFakeMeta::GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable /*from metamod*/, int
|
||||
*interfaceVersion = INTERFACE_VERSION;
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
// evilspy:
|
||||
//using metamod p-extensions?
|
||||
if(gpMetaPExtFuncs || g_IsNewMM)
|
||||
{
|
||||
memcpy( pFunctionTable, pAMXXFunctionTable, sizeof( DLL_FUNCTIONS ) );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
memcpy( pFunctionTable, &g_DllFunctionTable, sizeof( DLL_FUNCTIONS ) );
|
||||
|
||||
// Make sure there is a core plugin
|
||||
@ -2611,6 +2753,15 @@ int CFakeMeta::GetEntityAPI2_Post(DLL_FUNCTIONS *pFunctionTable /*from metamod*/
|
||||
*interfaceVersion = INTERFACE_VERSION;
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
// evilspy
|
||||
//using metamod p-extensions?
|
||||
if(gpMetaPExtFuncs || g_IsNewMM)
|
||||
{
|
||||
memcpy( pFunctionTable, pAMXXFunctionTable, sizeof( DLL_FUNCTIONS ) );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
memcpy( pFunctionTable, &g_DllFunctionTable_Post, sizeof( DLL_FUNCTIONS ) );
|
||||
|
||||
// Make sure there is a core plugin
|
||||
@ -2640,6 +2791,15 @@ int CFakeMeta::GetEngineFunctions(enginefuncs_t *pengfuncsFromEngine, int *inter
|
||||
*interfaceVersion = ENGINE_INTERFACE_VERSION;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// evilspy:
|
||||
//using metamod p-extensions?
|
||||
if(gpMetaPExtFuncs || g_IsNewMM)
|
||||
{
|
||||
memcpy( pengfuncsFromEngine, pAMXXFunctionTable, sizeof( enginefuncs_t ) );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
memcpy( pengfuncsFromEngine, &g_EngineFunctionTable, sizeof( enginefuncs_t ) );
|
||||
|
||||
// Make sure there is a core plugin
|
||||
@ -2668,6 +2828,15 @@ int CFakeMeta::GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int *
|
||||
*interfaceVersion = ENGINE_INTERFACE_VERSION;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// evilspy:
|
||||
//using metamod p-extensions?
|
||||
if(gpMetaPExtFuncs || g_IsNewMM)
|
||||
{
|
||||
memcpy( pengfuncsFromEngine, pAMXXFunctionTable, sizeof( enginefuncs_t ) );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
memcpy( pengfuncsFromEngine, &g_EngineFunctionTable_Post, sizeof( enginefuncs_t ) );
|
||||
|
||||
// Make sure there is a core plugin
|
||||
@ -2703,6 +2872,15 @@ int CFakeMeta::GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *int
|
||||
*interfaceVersion = NEW_DLL_FUNCTIONS_VERSION;
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
// evilspy:
|
||||
//using metamod p-extensions?
|
||||
if(gpMetaPExtFuncs || g_IsNewMM)
|
||||
{
|
||||
memcpy( pNewFunctionTable, pAMXXFunctionTable, sizeof( NEW_DLL_FUNCTIONS ) );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
memcpy( pNewFunctionTable, &g_NewDllFunctionTable, sizeof( NEW_DLL_FUNCTIONS ) );
|
||||
|
||||
// Make sure there is a core plugin
|
||||
@ -2738,6 +2916,15 @@ int CFakeMeta::GetNewDLLFunctions_Post(NEW_DLL_FUNCTIONS *pNewFunctionTable, int
|
||||
*interfaceVersion = NEW_DLL_FUNCTIONS_VERSION;
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
// evilspy:
|
||||
//using metamod p-extensions?
|
||||
if(gpMetaPExtFuncs || g_IsNewMM)
|
||||
{
|
||||
memcpy( pNewFunctionTable, pAMXXFunctionTable, sizeof( NEW_DLL_FUNCTIONS ) );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
memcpy( pNewFunctionTable, &g_NewDllFunctionTable_Post, sizeof( NEW_DLL_FUNCTIONS ) );
|
||||
|
||||
// Make sure there is a core plugin
|
||||
@ -2757,3 +2944,5 @@ int CFakeMeta::GetNewDLLFunctions_Post(NEW_DLL_FUNCTIONS *pNewFunctionTable, int
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif //FAKEMETA
|
||||
|
@ -31,6 +31,10 @@
|
||||
#ifndef __FAKEMETA_H__
|
||||
#define __FAKEMETA_H__
|
||||
|
||||
#ifndef FAKEMETA
|
||||
int UnloadMetamodPlugin(void *handle);
|
||||
int LoadMetamodPlugin(const char *path, void **handle, PLUG_LOADTIME now);
|
||||
#else
|
||||
// Fake metamod api for modules
|
||||
|
||||
#include "CList.h"
|
||||
@ -225,5 +229,7 @@ public:
|
||||
// defined in meta_api.cpp
|
||||
extern CFakeMeta g_FakeMeta;
|
||||
|
||||
#endif //FAKEMETA
|
||||
|
||||
#endif // #ifndef __FAKEMETA_H__
|
||||
|
||||
|
209
amxmodx/file.cpp
209
amxmodx/file.cpp
@ -36,18 +36,18 @@
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
//#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#endif
|
||||
|
||||
// header file for unlink()
|
||||
#ifdef __linux__
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#define WINDOWS_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
@ -57,6 +57,23 @@
|
||||
|
||||
CVector<FILE *> FileList;
|
||||
|
||||
class AutoFilePtr
|
||||
{
|
||||
FILE *m_FP;
|
||||
public:
|
||||
AutoFilePtr(FILE *fp) : m_FP(fp)
|
||||
{ }
|
||||
~AutoFilePtr()
|
||||
{
|
||||
if (m_FP)
|
||||
fclose(m_FP);
|
||||
}
|
||||
operator FILE* ()
|
||||
{
|
||||
return m_FP;
|
||||
}
|
||||
};
|
||||
|
||||
static cell AMX_NATIVE_CALL read_dir(AMX *amx, cell *params)
|
||||
{
|
||||
#ifdef __GNUC__
|
||||
@ -168,7 +185,7 @@ static cell AMX_NATIVE_CALL write_file(AMX *amx, cell *params) /* 3 param */
|
||||
|
||||
// adding a new line in a middle of already existing file
|
||||
FILE* pTemp;
|
||||
char buffor[1024];
|
||||
char buffor[2048];
|
||||
|
||||
if ( (pTemp = tmpfile()) == NULL ){
|
||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
||||
@ -177,11 +194,11 @@ static cell AMX_NATIVE_CALL write_file(AMX *amx, cell *params) /* 3 param */
|
||||
|
||||
for(i=0;;++i){
|
||||
if ( i == iLine ){
|
||||
fgets(buffor,1023,pFile);
|
||||
fgets(buffor,2047,pFile);
|
||||
fputs( sText , pTemp );
|
||||
fputc( '\n', pTemp );
|
||||
}
|
||||
else if ( fgets(buffor,1023,pFile) ){
|
||||
else if ( fgets(buffor,2047,pFile) ){
|
||||
fputs(buffor , pTemp );
|
||||
}
|
||||
else if ( i < iLine ) {
|
||||
@ -199,7 +216,7 @@ static cell AMX_NATIVE_CALL write_file(AMX *amx, cell *params) /* 3 param */
|
||||
return 0;
|
||||
}
|
||||
|
||||
while(fgets(buffor,1023,pTemp))
|
||||
while(fgets(buffor,2047,pTemp))
|
||||
fputs(buffor,pFile );
|
||||
|
||||
fclose(pTemp);
|
||||
@ -217,30 +234,65 @@ static cell AMX_NATIVE_CALL delete_file(AMX *amx, cell *params) /* 1 param */
|
||||
static cell AMX_NATIVE_CALL file_exists(AMX *amx, cell *params) /* 1 param */
|
||||
{
|
||||
int iLen;
|
||||
char* sFile = get_amxstring(amx,params[1],0,iLen);
|
||||
FILE* fp = fopen(build_pathname("%s",sFile),"r");
|
||||
if ( fp != NULL) {
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
char *sFile = get_amxstring(amx,params[1],0,iLen);
|
||||
char *file = build_pathname("%s",sFile);
|
||||
#if defined WIN32 || defined _WIN32
|
||||
DWORD attr = GetFileAttributes(file);
|
||||
if (attr == INVALID_FILE_ATTRIBUTES)
|
||||
return 0;
|
||||
if (attr == FILE_ATTRIBUTE_DIRECTORY)
|
||||
return 0;
|
||||
return 1;
|
||||
#else
|
||||
struct stat s;
|
||||
if (stat(file, &s) != 0)
|
||||
return 0;
|
||||
if (S_ISDIR(s.st_mode))
|
||||
return 0;
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL dir_exists(AMX *amx, cell *params) /* 1 param */
|
||||
{
|
||||
int iLen;
|
||||
char *sFile = get_amxstring(amx,params[1],0,iLen);
|
||||
char *file = build_pathname("%s",sFile);
|
||||
#if defined WIN32 || defined _WIN32
|
||||
DWORD attr = GetFileAttributes(file);
|
||||
if (attr == INVALID_FILE_ATTRIBUTES)
|
||||
return 0;
|
||||
if (attr == FILE_ATTRIBUTE_DIRECTORY)
|
||||
return 1;
|
||||
return 0;
|
||||
#else
|
||||
struct stat s;
|
||||
if (stat(file, &s) != 0)
|
||||
return 0;
|
||||
if (S_ISDIR(s.st_mode))
|
||||
return 1;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL file_size(AMX *amx, cell *params) /* 1 param */
|
||||
{
|
||||
int iLen;
|
||||
char* sFile = get_amxstring(amx,params[1],0,iLen);
|
||||
FILE* fp = fopen(build_pathname("%s",sFile),"r");
|
||||
if ( fp != NULL) {
|
||||
if ( params[0] < 2 || params[2] == 0 ){
|
||||
AutoFilePtr fp(fopen(build_pathname("%s",sFile),"r"));
|
||||
if ( fp != NULL)
|
||||
{
|
||||
if ( params[0] < 2 || params[2] == 0 )
|
||||
{
|
||||
fseek(fp,0,SEEK_END);
|
||||
int size = ftell(fp);
|
||||
fclose(fp);
|
||||
return size;
|
||||
}
|
||||
else if ( params[2] == 1 ){
|
||||
else if ( params[2] == 1 )
|
||||
{
|
||||
int a = 0,lines = 0;
|
||||
while( a != EOF ){
|
||||
while( a != EOF )
|
||||
{
|
||||
++lines;
|
||||
while ( (a = fgetc(fp)) != '\n' && a != EOF )
|
||||
;
|
||||
@ -273,7 +325,13 @@ static cell AMX_NATIVE_CALL amx_fopen(AMX *amx, cell *params)
|
||||
int len, j=-1;
|
||||
char *file = build_pathname("%s", get_amxstring(amx, params[1], 1, len));
|
||||
char *flags = get_amxstring(amx, params[2], 0, len);
|
||||
|
||||
FILE *fp = fopen(file, flags);
|
||||
if (fp == NULL) {
|
||||
// Failed
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i=0; i<FileList.size(); i++)
|
||||
{
|
||||
if (FileList.at(i) == NULL)
|
||||
@ -306,19 +364,6 @@ static cell AMX_NATIVE_CALL amx_fclose(AMX *amx, cell *params)
|
||||
}
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fgetc(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||
return 0;
|
||||
FILE *fp = FileList.at(id);
|
||||
if (fp) {
|
||||
return fgetc(fp);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fread(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
@ -336,6 +381,20 @@ static cell AMX_NATIVE_CALL amx_fread(AMX *amx, cell *params)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef UNUSED
|
||||
static cell AMX_NATIVE_CALL amx_fgetc(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||
return 0;
|
||||
FILE *fp = FileList.at(id);
|
||||
if (fp) {
|
||||
return fgetc(fp);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fwrite(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
@ -448,13 +507,14 @@ static cell AMX_NATIVE_CALL amx_ftell(AMX *amx, cell *params)
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#endif //UNUSED
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_filesize(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
char *file = build_pathname("%s", format_amxstring(amx, params, 1, len));
|
||||
long size;
|
||||
FILE *fp = fopen(file, "rb");
|
||||
AutoFilePtr fp(fopen(file, "rb"));
|
||||
if (fp) {
|
||||
fseek(fp, 0, SEEK_END);
|
||||
size = ftell(fp);
|
||||
@ -463,6 +523,7 @@ static cell AMX_NATIVE_CALL amx_filesize(AMX *amx, cell *params)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef UNUSED
|
||||
static cell AMX_NATIVE_CALL amx_fgetl(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
@ -578,6 +639,7 @@ static cell AMX_NATIVE_CALL amx_fputf(AMX *amx, cell *params)
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#endif //UNUSED
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_build_pathname(AMX *amx, cell *params)
|
||||
{
|
||||
@ -586,6 +648,75 @@ static cell AMX_NATIVE_CALL amx_build_pathname(AMX *amx, cell *params)
|
||||
return set_amxstring(amx, params[2], build_pathname("%s", szPath), params[3]);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_open_dir(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
char *path = get_amxstring(amx, params[1], 0, len);
|
||||
|
||||
#if defined WIN32 || defined _WIN32
|
||||
char *dirname = build_pathname("%s\\*", path);
|
||||
WIN32_FIND_DATA fd;
|
||||
HANDLE hFile = FindFirstFile(dirname, &fd);
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
return 0;
|
||||
set_amxstring(amx, params[2], fd.cFileName, params[3]);
|
||||
return (DWORD)hFile;
|
||||
#else
|
||||
char *dirname = build_pathname("%s", path);
|
||||
DIR *dp = opendir(dirname);
|
||||
if (!dp)
|
||||
return NULL;
|
||||
struct dirent *ep = readdir(dp);
|
||||
if (!ep)
|
||||
{
|
||||
closedir(dp);
|
||||
return NULL;
|
||||
}
|
||||
set_amxstring(amx,params[2], ep->d_name,params[3]);
|
||||
return (cell)dp;
|
||||
#endif
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_close_dir(AMX *amx, cell *params)
|
||||
{
|
||||
#if defined WIN32 || defined _WIN32
|
||||
HANDLE hFile = (HANDLE)((DWORD)params[1]);
|
||||
if (hFile == INVALID_HANDLE_VALUE || hFile == NULL)
|
||||
return 0;
|
||||
FindClose(hFile);
|
||||
return 1;
|
||||
#else
|
||||
DIR *dp = (DIR *)params[1];
|
||||
if (!dp)
|
||||
return 0;
|
||||
closedir(dp);
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_get_dir(AMX *amx, cell *params)
|
||||
{
|
||||
#if defined WIN32 || defined _WIN32
|
||||
HANDLE hFile = (HANDLE)((DWORD)params[1]);
|
||||
if (hFile == INVALID_HANDLE_VALUE || hFile == NULL)
|
||||
return 0;
|
||||
WIN32_FIND_DATA fd;
|
||||
if (!FindNextFile(hFile, &fd))
|
||||
return 0;
|
||||
set_amxstring(amx, params[2], fd.cFileName, params[3]);
|
||||
return 1;
|
||||
#else
|
||||
DIR *dp = (DIR *)params[1];
|
||||
if (!dp)
|
||||
return 0;
|
||||
struct dirent *ep = readdir(dp);
|
||||
if (!ep)
|
||||
return 0;
|
||||
set_amxstring(amx,params[2], ep->d_name,params[3]);
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
AMX_NATIVE_INFO file_Natives[] = {
|
||||
{ "delete_file", delete_file },
|
||||
{ "file_exists", file_exists },
|
||||
@ -596,8 +727,10 @@ AMX_NATIVE_INFO file_Natives[] = {
|
||||
//Sanji's File Natives
|
||||
{ "fopen", amx_fopen },
|
||||
{ "fclose", amx_fclose },
|
||||
{ "fgetc", amx_fgetc },
|
||||
{ "fread", amx_fread },
|
||||
{ "filesize", amx_filesize },
|
||||
#ifdef UNUSED
|
||||
{ "fgetc", amx_fgetc },
|
||||
{ "fwrite", amx_fwrite },
|
||||
{ "feof", amx_feof },
|
||||
{ "fseek", amx_fseek },
|
||||
@ -606,17 +739,21 @@ AMX_NATIVE_INFO file_Natives[] = {
|
||||
{ "fflush", amx_fflush },
|
||||
{ "fscanf", amx_fscanf },
|
||||
{ "ftell", amx_ftell },
|
||||
{ "filesize", amx_filesize },
|
||||
{ "fgetl", amx_fgetl },
|
||||
{ "fgeti", amx_fgeti },
|
||||
{ "fgets", amx_fgets },
|
||||
{ "fputs", amx_fputs },
|
||||
{ "fputl", amx_fputl },
|
||||
{ "fputi", amx_fputi },
|
||||
{ "unlink", delete_file },
|
||||
{ "fgetf", amx_fgetf },
|
||||
{ "fputf", amx_fputf },
|
||||
#endif
|
||||
{ "unlink", delete_file },
|
||||
{ "build_pathname", amx_build_pathname},
|
||||
{ "dir_exists", dir_exists },
|
||||
{ "open_dir", amx_open_dir },
|
||||
{ "close_dir", amx_close_dir },
|
||||
{ "next_file", amx_get_dir },
|
||||
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
@ -96,7 +96,7 @@ static cell AMX_NATIVE_CALL n_floatstr(AMX *amx,cell *params)
|
||||
return 0;
|
||||
|
||||
/* Now convert the Small String into a C type null terminated string */
|
||||
amx_GetString(szSource, pString, 0);
|
||||
amx_GetStringOld(szSource, pString, 0);
|
||||
|
||||
/* Now convert this to a float. */
|
||||
fNum = (REAL)atof(szSource);
|
||||
|
@ -32,6 +32,8 @@
|
||||
#include <time.h>
|
||||
#include "amxmodx.h"
|
||||
#include "fakemeta.h"
|
||||
#include "newmenus.h"
|
||||
#include "natives.h"
|
||||
|
||||
plugin_info_t Plugin_info = {
|
||||
META_INTERFACE_VERSION, // ifvers
|
||||
@ -50,6 +52,7 @@ gamedll_funcs_t *gpGamedllFuncs;
|
||||
mutil_funcs_t *gpMetaUtilFuncs;
|
||||
enginefuncs_t g_engfuncs;
|
||||
globalvars_t *gpGlobals;
|
||||
pextension_funcs_t *gpMetaPExtFuncs;
|
||||
|
||||
funEventCall modMsgsEnd[MAX_REG_MSGS];
|
||||
funEventCall modMsgs[MAX_REG_MSGS];
|
||||
@ -57,7 +60,6 @@ void (*function)(void*);
|
||||
void (*endfunction)(void*);
|
||||
|
||||
CLog g_log;
|
||||
CQueue<String> CurModuleList;
|
||||
CForwardMngr g_forwards;
|
||||
CList<CPlayer*> g_auth;
|
||||
CList<CCVar> g_cvars;
|
||||
@ -88,6 +90,9 @@ float g_game_timeleft;
|
||||
float g_task_time;
|
||||
float g_auth_time;
|
||||
bool g_initialized = false;
|
||||
bool g_IsNewMM = false;
|
||||
bool g_NeedsP = false;
|
||||
bool g_coloredmenus;
|
||||
|
||||
#ifdef MEMORY_TEST
|
||||
float g_next_memreport_time;
|
||||
@ -128,7 +133,9 @@ int FF_ClientAuthorized = -1;
|
||||
int FF_ChangeLevel = -1;
|
||||
|
||||
// fake metamod api
|
||||
#ifdef FAKEMETA
|
||||
CFakeMeta g_FakeMeta;
|
||||
#endif
|
||||
|
||||
// Precache stuff from force consistency calls
|
||||
// or check for pointed files won't be done
|
||||
@ -169,19 +176,8 @@ int C_InconsistentFile( const edict_t *player, const char *filename, char *disco
|
||||
{
|
||||
CPlayer *pPlayer = GET_PLAYER_POINTER((edict_t *)player);
|
||||
|
||||
#ifdef ENABLEEXEPTIONS
|
||||
try
|
||||
{
|
||||
#endif
|
||||
if (executeForwards(FF_InconsistentFile, pPlayer->index, filename, disconnect_message) == 1)
|
||||
RETURN_META_VALUE(MRES_SUPERCEDE, FALSE);
|
||||
#ifdef ENABLEEXEPTIONS
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
AMXXLOG_Log( "[AMXX] Fatal error at inconsistent file forward execution");
|
||||
}
|
||||
#endif
|
||||
RETURN_META_VALUE(MRES_SUPERCEDE, TRUE );
|
||||
}
|
||||
|
||||
@ -220,8 +216,9 @@ int C_Spawn( edict_t *pent ) {
|
||||
g_tasksMngr.registerTimers( &gpGlobals->time, &mp_timelimit->value, &g_game_timeleft );
|
||||
|
||||
// ###### Load lang
|
||||
g_langMngr.LoadCache(build_pathname("%s/dictionary.cache", get_localinfo("amxx_datadir", "addons/amxmodx/data")));
|
||||
g_langMngr.Load(build_pathname("%s/languages.dat", get_localinfo("amxmodx_datadir", "addons/amxmodx/data")));
|
||||
char file[256];
|
||||
g_langMngr.LoadCache(build_pathname_r(file, sizeof(file)-1, "%s/dictionary.cache", get_localinfo("amxx_datadir", "addons/amxmodx/data")));
|
||||
g_langMngr.Load(build_pathname_r(file, sizeof(file)-1, "%s/languages.dat", get_localinfo("amxmodx_datadir", "addons/amxmodx/data")));
|
||||
// ###### Initialize commands prefixes
|
||||
g_commands.registerPrefix( "amx" );
|
||||
g_commands.registerPrefix( "amxx" );
|
||||
@ -238,8 +235,7 @@ int C_Spawn( edict_t *pent ) {
|
||||
get_localinfo("amxx_customdir", "addons/amxmodx/custom");
|
||||
|
||||
// ###### Load modules
|
||||
loadModules(get_localinfo("amxx_modules", "addons/amxmodx/configs/modules.ini"));
|
||||
attachModules();
|
||||
loadModules(get_localinfo("amxx_modules", "addons/amxmodx/configs/modules.ini"), PT_ANYTIME);
|
||||
int loaded = countModules(CountModules_Running); // Call after attachModules so all modules don't have pending stat
|
||||
// Set some info about amx version and modules
|
||||
CVAR_SET_STRING(init_amxmodx_version.name, AMX_VERSION);
|
||||
@ -248,7 +244,7 @@ int C_Spawn( edict_t *pent ) {
|
||||
CVAR_SET_STRING(init_amxmodx_modules.name, buffer);
|
||||
|
||||
// ###### Load Vault
|
||||
g_vault.setSource( build_pathname("%s", get_localinfo("amxx_vault", "addons/amxmodx/configs/vault.ini")) );
|
||||
g_vault.setSource( build_pathname_r(file, sizeof(file)-1, "%s", get_localinfo("amxx_vault", "addons/amxmodx/configs/vault.ini")) );
|
||||
g_vault.loadVault( );
|
||||
if (strlen(g_vault.get("server_language")) < 1)
|
||||
{
|
||||
@ -271,6 +267,7 @@ int C_Spawn( edict_t *pent ) {
|
||||
|
||||
// ###### Load AMX scripts
|
||||
g_plugins.loadPluginsFromFile( get_localinfo("amxx_plugins", "addons/amxmodx/configs/plugins.ini") );
|
||||
g_plugins.Finalize();
|
||||
|
||||
// Register forwards
|
||||
FF_PluginInit = registerForward("plugin_init", ET_IGNORE, FP_DONE);
|
||||
@ -281,7 +278,7 @@ int C_Spawn( edict_t *pent ) {
|
||||
FF_ClientPutInServer = registerForward("client_putinserver", ET_IGNORE, FP_CELL, FP_DONE);
|
||||
FF_PluginCfg = registerForward("plugin_cfg", ET_IGNORE, FP_DONE);
|
||||
FF_PluginPrecache = registerForward("plugin_precache", ET_IGNORE, FP_DONE);
|
||||
FF_PluginLog = registerForward("plugin_log", ET_IGNORE, FP_DONE);
|
||||
FF_PluginLog = registerForward("plugin_log", ET_STOP, FP_DONE);
|
||||
FF_PluginEnd = registerForward("plugin_end", ET_IGNORE, FP_DONE);
|
||||
FF_InconsistentFile = registerForward("inconsistent_file", ET_STOP, FP_CELL, FP_STRING, FP_STRINGEX, FP_DONE);
|
||||
FF_ClientAuthorized = registerForward("client_authorized", ET_IGNORE, FP_CELL, FP_DONE);
|
||||
@ -300,7 +297,6 @@ int C_Spawn( edict_t *pent ) {
|
||||
(*a).getMin(),(*a).getMax(),(*a).getFilename());
|
||||
}
|
||||
|
||||
|
||||
RETURN_META_VALUE(MRES_IGNORED, 0);
|
||||
}
|
||||
|
||||
@ -400,8 +396,9 @@ void C_ServerActivate_Post( edict_t *pEdictList, int edictCount, int clientMax )
|
||||
executeForwards(FF_PluginCfg);
|
||||
|
||||
// ###### Save lang
|
||||
g_langMngr.Save(build_pathname("%s/languages.dat", get_localinfo("amxx_datadir", "addons/amxmodx/data")));
|
||||
g_langMngr.SaveCache(build_pathname("%s/dictionary.cache", get_localinfo("amxx_datadir", "addons/amxmodx/data")));
|
||||
char file[256];
|
||||
g_langMngr.Save(build_pathname_r(file, sizeof(file)-1, "%s/languages.dat", get_localinfo("amxx_datadir", "addons/amxmodx/data")));
|
||||
g_langMngr.SaveCache(build_pathname_r(file, sizeof(file)-1, "%s/dictionary.cache", get_localinfo("amxx_datadir", "addons/amxmodx/data")));
|
||||
|
||||
// Correct time in Counter-Strike and other mods (except DOD)
|
||||
if ( !g_bmod_dod) g_game_timeleft = 0;
|
||||
@ -423,10 +420,11 @@ void C_ServerDeactivate() {
|
||||
|
||||
for(int i = 1; i <= gpGlobals->maxClients; ++i){
|
||||
CPlayer *pPlayer = GET_PLAYER_POINTER_I(i);
|
||||
if (pPlayer->ingame){
|
||||
|
||||
if (pPlayer->initialized)
|
||||
executeForwards(FF_ClientDisconnect, pPlayer->index);
|
||||
|
||||
if (pPlayer->ingame){
|
||||
|
||||
pPlayer->Disconnect();
|
||||
--g_players_num;
|
||||
}
|
||||
@ -454,17 +452,15 @@ void C_ServerDeactivate_Post() {
|
||||
g_logevents.clearLogEvents();
|
||||
g_events.clearEvents();
|
||||
g_menucmds.clear();
|
||||
ClearMenus();
|
||||
g_vault.clear();
|
||||
g_xvars.clear();
|
||||
g_plugins.clear();
|
||||
g_langMngr.Save(build_pathname("%s/languages.dat", get_localinfo("amxx_datadir", "addons/amxmodx/data")));
|
||||
g_langMngr.SaveCache(build_pathname("%s/dictionary.cache", get_localinfo("amxx_datadir", "addons/amxmodx/data")));
|
||||
ClearPluginLibraries();
|
||||
char file[256];
|
||||
g_langMngr.Save(build_pathname_r(file, sizeof(file)-1, "%s/languages.dat", get_localinfo("amxx_datadir", "addons/amxmodx/data")));
|
||||
g_langMngr.SaveCache(build_pathname_r(file, sizeof(file)-1, "%s/dictionary.cache", get_localinfo("amxx_datadir", "addons/amxmodx/data")));
|
||||
g_langMngr.Clear();
|
||||
//clear module name cache
|
||||
while (!CurModuleList.empty())
|
||||
{
|
||||
CurModuleList.pop();
|
||||
}
|
||||
|
||||
// last memreport
|
||||
#ifdef MEMORY_TEST
|
||||
@ -547,8 +543,10 @@ BOOL C_ClientConnect_Post( edict_t *pEntity, const char *pszName, const char *ps
|
||||
|
||||
void C_ClientDisconnect( edict_t *pEntity ) {
|
||||
CPlayer *pPlayer = GET_PLAYER_POINTER(pEntity);
|
||||
if (pPlayer->ingame) {
|
||||
if (pPlayer->initialized)
|
||||
executeForwards(FF_ClientDisconnect, pPlayer->index);
|
||||
|
||||
if (pPlayer->ingame) {
|
||||
--g_players_num;
|
||||
}
|
||||
pPlayer->Disconnect();
|
||||
@ -602,31 +600,41 @@ void C_ClientCommand( edict_t *pEntity ) {
|
||||
CPlayer *pPlayer = GET_PLAYER_POINTER(pEntity);
|
||||
META_RES result = MRES_IGNORED;
|
||||
cell ret = 0;
|
||||
int err;
|
||||
|
||||
#ifdef ENABLEEXEPTIONS
|
||||
try
|
||||
{
|
||||
#endif
|
||||
if (executeForwards(FF_ClientCommand, pPlayer->index) > 0)
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
|
||||
#ifdef ENABLEEXEPTIONS
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
AMXXLOG_Log( "[AMXX] Fatal error at commmand forward execution");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* check for command and if needed also for first argument and call proper function */
|
||||
const char* cmd = CMD_ARGV(0);
|
||||
const char* arg = CMD_ARGV(1);
|
||||
|
||||
#ifdef ENABLEEXEPTIONS
|
||||
try{
|
||||
// Handle "amxx" if not on listenserver
|
||||
if (IS_DEDICATED_SERVER())
|
||||
{
|
||||
if (cmd && stricmp(cmd, "amxx")==0)
|
||||
{
|
||||
// Print version
|
||||
static char buf[1024];
|
||||
sprintf(buf, "%s %s\n", Plugin_info.name, Plugin_info.version);
|
||||
CLIENT_PRINT(pEntity, print_console, buf);
|
||||
sprintf(buf, "Authors: %s (%s)\n", "Felix \"SniperBeamer\" Geyer, David \"BAILOPAN\" Anderson, Pavol \"PM OnoTo\" Marko, Jonny \"Got His Gun\" Bergstrom, and Lukasz \"SidLuke\" Wlasinski.", Plugin_info.url);
|
||||
CLIENT_PRINT(pEntity, print_console, buf);
|
||||
sprintf(buf, "Compiled: %s\n", __DATE__ ", " __TIME__);
|
||||
CLIENT_PRINT(pEntity, print_console, buf);
|
||||
#ifdef JIT
|
||||
sprintf(buf, "Core mode: JIT\n");
|
||||
#else
|
||||
#ifdef ASM32
|
||||
sprintf(buf, "Core mode: ASM\n");
|
||||
#else
|
||||
sprintf(buf, "Core mode: Normal\n");
|
||||
#endif
|
||||
#endif
|
||||
CLIENT_PRINT(pEntity, print_console, buf);
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
}
|
||||
|
||||
if (executeForwards(FF_ClientCommand, pPlayer->index) > 0)
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
|
||||
|
||||
/* check for command and if needed also for first argument and call proper function */
|
||||
|
||||
CmdMngr::iterator aa = g_commands.clcmdprefixbegin( cmd );
|
||||
if ( !aa ) aa = g_commands.clcmdbegin();
|
||||
@ -636,10 +644,7 @@ void C_ClientCommand( edict_t *pEntity ) {
|
||||
if ( (*aa).matchCommandLine( cmd , arg ) &&
|
||||
(*aa).getPlugin()->isExecutable( (*aa).getFunction() ) )
|
||||
{
|
||||
|
||||
if ((err =amx_Exec((*aa).getPlugin()->getAMX(), &ret , (*aa).getFunction() , 3, pPlayer->index, (*aa).getFlags(),(*aa).getId() )) != AMX_ERR_NONE)
|
||||
LogError((*aa).getPlugin()->getAMX(), err, "");
|
||||
|
||||
ret = executeForwards((*aa).getFunction(), pPlayer->index, (*aa).getFlags(), (*aa).getId());
|
||||
if ( ret & 2 ) result = MRES_SUPERCEDE;
|
||||
if ( ret & 1 ) RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
@ -647,12 +652,6 @@ void C_ClientCommand( edict_t *pEntity ) {
|
||||
++aa;
|
||||
}
|
||||
|
||||
#ifdef ENABLEEXEPTIONS
|
||||
}catch( ... )
|
||||
{
|
||||
AMXXLOG_Log( "[AMXX] fatal error at client commmand execution");
|
||||
}
|
||||
#endif
|
||||
/* check menu commands */
|
||||
|
||||
if (!strcmp(cmd,"menuselect"))
|
||||
@ -666,33 +665,43 @@ void C_ClientCommand( edict_t *pEntity ) {
|
||||
int menuid = pPlayer->menu;
|
||||
pPlayer->menu = 0;
|
||||
|
||||
#ifdef ENABLEEXEPTIONS
|
||||
try{
|
||||
#endif
|
||||
MenuMngr::iterator a = g_menucmds.begin();
|
||||
|
||||
while( a )
|
||||
{
|
||||
if ( (*a).matchCommand( menuid , bit_key ) && (*a).getPlugin()->isExecutable( (*a).getFunction() ) )
|
||||
{
|
||||
|
||||
if ( ( err = amx_Exec((*a).getPlugin()->getAMX(), &ret ,(*a).getFunction() , 2, pPlayer->index,pressed_key)) != AMX_ERR_NONE)
|
||||
LogError((*a).getPlugin()->getAMX(), err, "");
|
||||
|
||||
if (pPlayer->newmenu != -1)
|
||||
{
|
||||
int menu = pPlayer->newmenu;
|
||||
pPlayer->newmenu = -1;
|
||||
if (menu >= 0 && menu < (int)g_NewMenus.size())
|
||||
{
|
||||
Menu *pMenu = g_NewMenus[menu];
|
||||
int item = pMenu->PagekeyToItem(pPlayer->page, pressed_key);
|
||||
ret = executeForwards( (*a).getFunction(), pPlayer->index, menu, item );
|
||||
if ( ret & 2 ) result = MRES_SUPERCEDE;
|
||||
else if ( ret & 1 ) RETURN_META(MRES_SUPERCEDE);
|
||||
else {
|
||||
if (item == MENU_BACK)
|
||||
{
|
||||
pMenu->Display(pPlayer->index, pPlayer->page-1);
|
||||
} else if (item == MENU_MORE) {
|
||||
pMenu->Display(pPlayer->index, pPlayer->page+1);
|
||||
} else if (item == MENU_EXIT) {
|
||||
//nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret = executeForwards((*a).getFunction(), pPlayer->index, pressed_key, 0);
|
||||
if ( ret & 2 ) result = MRES_SUPERCEDE;
|
||||
if ( ret & 1 ) RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
}
|
||||
|
||||
++a;
|
||||
}
|
||||
|
||||
#ifdef ENABLEEXEPTIONS
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
AMXXLOG_Log( "[AMXX] Fatal error at menu commmand execution");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/* check for PLUGIN_HANDLED_MAIN and block hl call if needed */
|
||||
@ -869,35 +878,6 @@ void C_WriteEntity_Post(int iValue) {
|
||||
}
|
||||
void C_MessageEnd_Post(void) {
|
||||
g_events.executeEvents();
|
||||
|
||||
#if 0 // ######### this is done by call above
|
||||
EventsMngr::iterator a = g_events.begin();
|
||||
int err;
|
||||
#ifdef ENABLEEXEPTIONS
|
||||
try
|
||||
{
|
||||
#endif
|
||||
|
||||
while ( a )
|
||||
{
|
||||
|
||||
if ((err = amx_Exec((*a).getPlugin()->getAMX(), NULL , (*a).getFunction() , 1, mPlayerIndex /*g_events.getArgInteger(0)*/ )) != AMX_ERR_NONE)
|
||||
LogError((*a).getPlugin()->getAMX(), err, "");
|
||||
|
||||
|
||||
++a;
|
||||
|
||||
}
|
||||
|
||||
#ifdef ENABLEEXEPTIONS
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
AMXXLOG_Log( "[AMXX] Fatal error at event execution");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (endfunction) (*endfunction)(NULL);
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
@ -985,53 +965,111 @@ void C_AlertMessage_Post(ALERT_TYPE atype, char *szFmt, ...)
|
||||
g_logevents.parseLogString( );
|
||||
if (g_logevents.logEventsExist())
|
||||
g_logevents.executeLogEvents( );
|
||||
executeForwards(FF_PluginLog);
|
||||
cell retVal = executeForwards(FF_PluginLog);
|
||||
if (retVal)
|
||||
RETURN_META(MRES_HANDLED);
|
||||
}
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
C_DLLEXPORT int Meta_Query(char *ifvers, plugin_info_t **pPlugInfo, mutil_funcs_t *pMetaUtilFuncs) {
|
||||
bool m_NeedsP = false;
|
||||
|
||||
C_DLLEXPORT int Meta_Query(char *ifvers, plugin_info_t **pPlugInfo, mutil_funcs_t *pMetaUtilFuncs)
|
||||
{
|
||||
gpMetaUtilFuncs=pMetaUtilFuncs;
|
||||
*pPlugInfo=&Plugin_info;
|
||||
if(strcmp(ifvers, Plugin_info.ifvers)) {
|
||||
if(strcmp(ifvers, Plugin_info.ifvers))
|
||||
{
|
||||
int mmajor=0, mminor=0, pmajor=0, pminor=0;
|
||||
LOG_MESSAGE(PLID, "WARNING: meta-interface version mismatch; requested=%s ours=%s", Plugin_info.logtag, ifvers);
|
||||
sscanf(ifvers, "%d:%d", &mmajor, &mminor);
|
||||
sscanf(META_INTERFACE_VERSION, "%d:%d", &pmajor, &pminor);
|
||||
if(pmajor > mmajor || (pmajor==mmajor && pminor > mminor)) {
|
||||
if(pmajor > mmajor)
|
||||
{
|
||||
LOG_ERROR(PLID, "metamod version is too old for this plugin; update metamod");
|
||||
return(FALSE);
|
||||
}
|
||||
else if(pmajor < mmajor) {
|
||||
} else if(pmajor < mmajor) {
|
||||
LOG_ERROR(PLID, "metamod version is incompatible with this plugin; please find a newer version of this plugin");
|
||||
return(FALSE);
|
||||
}
|
||||
else if(pmajor==mmajor && pminor < mminor)
|
||||
} else if (pmajor==mmajor) {
|
||||
#ifdef FAKEMETA
|
||||
if (mminor == 10)
|
||||
{
|
||||
LOG_MESSAGE(PLID, "WARNING: metamod version is older than expected; consider finding a newer version");
|
||||
g_IsNewMM = false;
|
||||
//hack!
|
||||
Plugin_info.ifvers = "5:10";
|
||||
#else
|
||||
if (mminor < 11)
|
||||
{
|
||||
g_NeedsP = true;
|
||||
|
||||
#endif
|
||||
} else if (mminor == 11) {
|
||||
g_IsNewMM = true;
|
||||
} else if (pminor > mminor) {
|
||||
LOG_ERROR(PLID, "metamod version is incompatible with this plugin; please find a newer version of this plugin");
|
||||
return FALSE;
|
||||
} else if (pminor < mminor) {
|
||||
LOG_MESSAGE(PLID, "WARNING: metamod version is newer than expected; consider finding a newer version of this plugin");
|
||||
else
|
||||
if (mminor > 11)
|
||||
g_IsNewMM = true;
|
||||
}
|
||||
} else {
|
||||
LOG_ERROR(PLID, "unexpected version comparison; metavers=%s, mmajor=%d, mminor=%d; plugvers=%s, pmajor=%d, pminor=%d", ifvers, mmajor, mminor, META_INTERFACE_VERSION, pmajor, pminor);
|
||||
}
|
||||
} else {
|
||||
g_IsNewMM = true;
|
||||
}
|
||||
|
||||
// We can set this to null here because Meta_PExtGiveFnptrs is called after this
|
||||
gpMetaPExtFuncs = NULL;
|
||||
|
||||
// :NOTE: Don't call modules query here (g_FakeMeta.Meta_Query), because we don't know modules yet. Do it in Meta_Attach
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
// evilspy's patch for mm-p ext support
|
||||
// this is called right after Meta_Query
|
||||
C_DLLEXPORT int Meta_PExtGiveFnptrs(int interfaceVersion, pextension_funcs_t *pMetaPExtFuncs)
|
||||
{
|
||||
if(interfaceVersion<META_PEXT_VERSION)
|
||||
{
|
||||
return(META_PEXT_VERSION);
|
||||
}
|
||||
gpMetaPExtFuncs = pMetaPExtFuncs;
|
||||
return(META_PEXT_VERSION);
|
||||
}
|
||||
|
||||
static META_FUNCTIONS gMetaFunctionTable;
|
||||
C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, meta_globals_t *pMGlobals, gamedll_funcs_t *pGamedllFuncs) {
|
||||
if(now > Plugin_info.loadable) {
|
||||
C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, meta_globals_t *pMGlobals, gamedll_funcs_t *pGamedllFuncs)
|
||||
{
|
||||
if(now > Plugin_info.loadable)
|
||||
{
|
||||
LOG_ERROR(PLID, "Can't load plugin right now");
|
||||
return(FALSE);
|
||||
}
|
||||
if (g_NeedsP && !gpMetaPExtFuncs)
|
||||
{
|
||||
LOG_ERROR(PLID, "You need Metamod-P or Metamod-1.18 to use AMX Mod X 1.1!");
|
||||
return(FALSE);
|
||||
}
|
||||
gpMetaGlobals=pMGlobals;
|
||||
gMetaFunctionTable.pfnGetEntityAPI2 = GetEntityAPI2;
|
||||
gMetaFunctionTable.pfnGetEntityAPI2_Post = GetEntityAPI2_Post;
|
||||
gMetaFunctionTable.pfnGetEngineFunctions = GetEngineFunctions;
|
||||
gMetaFunctionTable.pfnGetEngineFunctions_Post = GetEngineFunctions_Post;
|
||||
#ifdef FAKEMETA
|
||||
gMetaFunctionTable.pfnGetNewDLLFunctions = GetNewDLLFunctions;
|
||||
gMetaFunctionTable.pfnGetNewDLLFunctions_Post = GetNewDLLFunctions_Post;
|
||||
#endif
|
||||
|
||||
memcpy(pFunctionTable, &gMetaFunctionTable, sizeof(META_FUNCTIONS));
|
||||
gpGamedllFuncs=pGamedllFuncs;
|
||||
|
||||
Module_CacheFunctions();
|
||||
|
||||
CVAR_REGISTER(&init_amxmodx_version);
|
||||
CVAR_REGISTER(&init_amxmodx_modules);
|
||||
CVAR_REGISTER(&init_amxmodx_debug);
|
||||
@ -1047,8 +1085,15 @@ C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, m
|
||||
a = &gameDir[i];
|
||||
g_mod_name.assign(a);
|
||||
|
||||
if (g_mod_name.compare("cstrike")==0 ||
|
||||
g_mod_name.compare("czero")==0 ||
|
||||
g_mod_name.compare("dod")==0)
|
||||
g_coloredmenus = true;
|
||||
else
|
||||
g_coloredmenus = false;
|
||||
|
||||
// ###### Print short GPL
|
||||
print_srvconsole( "\n AMX Mod X version %s Copyright (c) 2004 AMX Mod X Development Team \n"
|
||||
print_srvconsole( "\n AMX Mod X version %s Copyright (c) 2004-2005 AMX Mod X Development Team \n"
|
||||
" AMX Mod X comes with ABSOLUTELY NO WARRANTY; for details type `amxx gpl'.\n", AMX_VERSION);
|
||||
print_srvconsole( " This is free software and you are welcome to redistribute it under \n"
|
||||
" certain conditions; type 'amxx gpl' for details.\n \n");
|
||||
@ -1071,7 +1116,7 @@ C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, m
|
||||
|
||||
// ###### Now attach metamod modules
|
||||
// This will also call modules Meta_Query and Meta_Attach functions
|
||||
attachMetaModModules(now, get_localinfo("amxx_modules", "addons/amxmodx/configs/modules.ini") );
|
||||
loadModules(get_localinfo("amxx_modules", "addons/amxmodx/configs/modules.ini"), now);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
@ -1092,6 +1137,7 @@ C_DLLEXPORT int Meta_Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason) {
|
||||
g_logevents.clearLogEvents();
|
||||
g_events.clearEvents();
|
||||
g_menucmds.clear();
|
||||
ClearMenus();
|
||||
g_vault.clear();
|
||||
g_xvars.clear();
|
||||
g_plugins.clear();
|
||||
@ -1100,11 +1146,15 @@ C_DLLEXPORT int Meta_Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason) {
|
||||
detachModules();
|
||||
|
||||
// ###### Now detach metamod modules
|
||||
#ifdef FAKEMETA
|
||||
g_FakeMeta.Meta_Detach(now, reason);
|
||||
g_FakeMeta.ReleasePlugins();
|
||||
#endif
|
||||
|
||||
g_log.CloseFile();
|
||||
|
||||
Module_UncacheFunctions();
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
@ -1194,7 +1244,12 @@ C_DLLEXPORT int GetEntityAPI2( DLL_FUNCTIONS *pFunctionTable, int *interfaceVers
|
||||
gFunctionTable.pfnInconsistentFile = C_InconsistentFile;
|
||||
gFunctionTable.pfnServerActivate = C_ServerActivate;
|
||||
|
||||
#ifdef FAKEMETA
|
||||
return g_FakeMeta.GetEntityAPI2(pFunctionTable, interfaceVersion, &gFunctionTable);
|
||||
#else
|
||||
memcpy(pFunctionTable, &gFunctionTable, sizeof(DLL_FUNCTIONS));
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
DLL_FUNCTIONS gFunctionTable_Post;
|
||||
@ -1206,7 +1261,12 @@ C_DLLEXPORT int GetEntityAPI2_Post( DLL_FUNCTIONS *pFunctionTable, int *interfac
|
||||
gFunctionTable_Post.pfnStartFrame = C_StartFrame_Post;
|
||||
gFunctionTable_Post.pfnServerDeactivate = C_ServerDeactivate_Post;
|
||||
|
||||
#ifdef FAKEMETA
|
||||
return g_FakeMeta.GetEntityAPI2_Post(pFunctionTable, interfaceVersion, &gFunctionTable_Post);
|
||||
#else
|
||||
memcpy(pFunctionTable, &gFunctionTable_Post, sizeof(DLL_FUNCTIONS));
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
enginefuncs_t meta_engfuncs;
|
||||
@ -1231,7 +1291,12 @@ C_DLLEXPORT int GetEngineFunctions(enginefuncs_t *pengfuncsFromEngine, int *inte
|
||||
meta_engfuncs.pfnPrecacheSound = C_PrecacheSound;
|
||||
meta_engfuncs.pfnChangeLevel = C_ChangeLevel;
|
||||
|
||||
#ifdef FAKEMETA
|
||||
return g_FakeMeta.GetEngineFunctions(pengfuncsFromEngine, interfaceVersion, &meta_engfuncs);
|
||||
#else
|
||||
memcpy(pengfuncsFromEngine, &meta_engfuncs, sizeof(enginefuncs_t));
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
enginefuncs_t meta_engfuncs_post;
|
||||
@ -1250,32 +1315,15 @@ C_DLLEXPORT int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int
|
||||
meta_engfuncs_post.pfnAlertMessage = C_AlertMessage_Post;
|
||||
meta_engfuncs_post.pfnRegUserMsg = C_RegUserMsg_Post;
|
||||
|
||||
|
||||
CList<int, int> list;
|
||||
list.put(new int (8));
|
||||
list.put_back(new int(10));
|
||||
list.put_front(new int(6));
|
||||
list.put(new int (12));
|
||||
CList<int,int>::iterator iter;
|
||||
iter = list.begin();
|
||||
while (iter)
|
||||
{
|
||||
if (*iter == 10)
|
||||
iter.remove();
|
||||
else if (*iter == 8)
|
||||
iter.put(new int (9));
|
||||
else
|
||||
++iter;
|
||||
}
|
||||
iter = list.begin();
|
||||
while (iter)
|
||||
{
|
||||
AMXXLOG_Log("%d", *iter);
|
||||
++iter;
|
||||
}
|
||||
#ifdef FAKEMETA
|
||||
return g_FakeMeta.GetEngineFunctions_Post(pengfuncsFromEngine, interfaceVersion, &meta_engfuncs_post);
|
||||
#else
|
||||
memcpy(pengfuncsFromEngine, &meta_engfuncs_post, sizeof(enginefuncs_t));
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef FAKEMETA
|
||||
NEW_DLL_FUNCTIONS gNewDLLFunctionTable;
|
||||
C_DLLEXPORT int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion)
|
||||
{
|
||||
@ -1287,3 +1335,5 @@ C_DLLEXPORT int GetNewDLLFunctions_Post(NEW_DLL_FUNCTIONS *pNewFunctionTable, in
|
||||
{
|
||||
return g_FakeMeta.GetNewDLLFunctions_Post(pNewFunctionTable, interfaceVersion, &gNewDLLFunctionTable_Post);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
116
amxmodx/mm_pextensions.h
Executable file
116
amxmodx/mm_pextensions.h
Executable file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Jussi Kivilinna
|
||||
*
|
||||
* This file is part of "Metamod All-Mod-Support"-patch for Metamod.
|
||||
*
|
||||
* Metamod 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.
|
||||
*
|
||||
* Metamod 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 Metamod; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MM_PEXTENSIONS_H
|
||||
#define MM_PEXTENSIONS_H
|
||||
|
||||
#include "plinfo.h" // plid_t
|
||||
#include "meta_api.h" // PLUG_LOADTIME
|
||||
/*
|
||||
|
||||
How to use:
|
||||
1. Add new export function 'Meta_PExtGiveFnptrs' to your plugin file.
|
||||
'Meta_PExtGiveFnptrs' will be called right after 'Meta_Query' call.
|
||||
2. Meta_PExtGiveFnptrs is called with interface version 'META_PEXT_VERSION'
|
||||
and pointer to extension function table.
|
||||
3. Meta_PExtGiveFnptrs should return plugin's interface version.
|
||||
4. !NOTE! Metamod will not stop loading plugin even if plugin returns
|
||||
interface version greater than current. Plugin should disable itself in
|
||||
this kind of situation.
|
||||
|
||||
Example:
|
||||
#include "mm_pextensions.h"
|
||||
|
||||
pextension_funcs_t *gpMetaPExtFuncs;
|
||||
|
||||
int Meta_PExtGiveFnptrs(int interfaceVersion, pextension_funcs_t *pMetaPExtFuncs) {
|
||||
if(interfaceVersion < META_PEXT_VERSION) {
|
||||
LOG_DEVELOPER(PLID, "Error! Metamod is too old, please update!");
|
||||
gpMetaPExtFuncs = NULL;
|
||||
|
||||
return(META_PEXT_VERSION);
|
||||
}
|
||||
|
||||
gpMetaPExtFuncs = pMetaPExtFuncs;
|
||||
|
||||
return(META_PEXT_VERSION);
|
||||
}
|
||||
|
||||
Callback functions:
|
||||
- int PEXT_LOAD_PLUGIN_BY_NAME(PLID, const char *cmdline, PLUG_LOADTIME now, void **plugin_handle);
|
||||
Parses 'cmdline' as metamod would parse 'meta load <cmdline>' and loads found
|
||||
plugin. If 'plugin_handle' is set, metamod writes module handle of loaded
|
||||
plugin at it.
|
||||
Returns zero on success.
|
||||
For error codes see 'META_ERRNO' in 'types_meta.h'.
|
||||
|
||||
- int PEXT_UNLOAD_PLUGIN_BY_NAME(PLID, const char *cmdline, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
|
||||
Parses 'cmdline' as metamod would parse 'meta unload <cmdline>' and
|
||||
unloads found plugin.
|
||||
Returns zero on success.
|
||||
For error codes see 'META_ERRNO' in 'types_meta.h'.
|
||||
|
||||
- int PEXT_UNLOAD_PLUGIN_BY_HANDLE(PLID, void *plugin_handle, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
|
||||
Unloads plugin with 'plugin_handle'.
|
||||
Returns zero on success.
|
||||
For error codes see 'META_ERRNO' in 'types_meta.h'.
|
||||
|
||||
!NOTE! Plugin cannot unload itself!
|
||||
*/
|
||||
|
||||
// Interface version
|
||||
// 1: first version. Used in p13
|
||||
// 2: Complete remake (p14):
|
||||
// pfnLoadMetaPluginByName
|
||||
// pfnUnloadMetaPluginByName
|
||||
// pfnUnloadMetaPluginByHandle
|
||||
// v2 is locked now. Don't modify old functions. If you add new functions, increase META_PEXT_VERSION.
|
||||
#define META_PEXT_VERSION 2
|
||||
|
||||
// Meta PExtension Function table type.
|
||||
typedef struct pextension_funcs_s {
|
||||
int (*pfnLoadMetaPluginByName)(plid_t plid, const char *cmdline, PLUG_LOADTIME now, void **plugin_handle);
|
||||
int (*pfnUnloadMetaPluginByName)(plid_t plid, const char *cmdline, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
|
||||
int (*pfnUnloadMetaPluginByHandle)(plid_t plid, void *plugin_handle, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
|
||||
} pextension_funcs_t;
|
||||
|
||||
// Convenience macros for MetaPExtension functions.
|
||||
#define PEXT_LOAD_PLUGIN_BY_NAME (*gpMetaPExtFuncs->pfnLoadMetaPluginByName)
|
||||
#define PEXT_UNLOAD_PLUGIN_BY_NAME (*gpMetaPExtFuncs->pfnUnloadMetaPluginByName)
|
||||
#define PEXT_UNLOAD_PLUGIN_BY_HANDLE (*gpMetaPExtFuncs->pfnUnloadMetaPluginByHandle)
|
||||
|
||||
// Give plugin extension function table.
|
||||
C_DLLEXPORT int Meta_PExtGiveFnptrs(int interfaceVersion,
|
||||
pextension_funcs_t *pMetaPExtFuncs);
|
||||
typedef int (*META_GIVE_PEXT_FUNCTIONS_FN) (int interfaceVersion,
|
||||
pextension_funcs_t *pMetaPExtFuncs);
|
||||
|
||||
#endif /* MM_PEXTENSIONS_H */
|
@ -930,7 +930,11 @@ void *m_allocator(const char *sourceFile, const unsigned int sourceLine, const c
|
||||
|
||||
// Danger Will Robinson!
|
||||
|
||||
if (reservoir == NULL) throw "Unable to allocate RAM for internal memory tracking data";
|
||||
if (reservoir == NULL)
|
||||
{
|
||||
log("%s: Unable to allocate RAM for internal memory tracking data", ownerString(sourceFile, sourceLine, sourceFunc));
|
||||
throw "Unable to allocate RAM for internal memory tracking data";
|
||||
}
|
||||
|
||||
// Build a linked-list of the elements in our reservoir
|
||||
|
||||
@ -998,6 +1002,7 @@ void *m_allocator(const char *sourceFile, const unsigned int sourceLine, const c
|
||||
|
||||
if (au->actualAddress == NULL)
|
||||
{
|
||||
log("%s: Request for allocation failed. Out of memory.", ownerString(sourceFile, sourceLine, sourceFunc));
|
||||
throw "Request for allocation failed. Out of memory.";
|
||||
}
|
||||
|
||||
@ -1108,7 +1113,11 @@ void *m_reallocator(const char *sourceFile, const unsigned int sourceLine, const
|
||||
|
||||
// If you hit this assert, you tried to reallocate RAM that wasn't allocated by this memory manager.
|
||||
m_assert(au != NULL);
|
||||
if (au == NULL) throw "Request to reallocate RAM that was never allocated";
|
||||
if (au == NULL)
|
||||
{
|
||||
log("%s: Request to reallocate RAM that was never allocated", ownerString(sourceFile, sourceLine, sourceFunc));
|
||||
throw "Request to reallocate RAM that was never allocated";
|
||||
}
|
||||
|
||||
// If you hit this assert, then the allocation unit that is about to be reallocated is damaged. But you probably
|
||||
// already know that from a previous assert you should have seen in validateAllocUnit() :)
|
||||
@ -1162,7 +1171,11 @@ void *m_reallocator(const char *sourceFile, const unsigned int sourceLine, const
|
||||
m_assert(newActualAddress);
|
||||
#endif
|
||||
|
||||
if (!newActualAddress) throw "Request for reallocation failed. Out of memory.";
|
||||
if (!newActualAddress)
|
||||
{
|
||||
log("%s: Request for reallocation failed. Out of memory", ownerString(sourceFile, sourceLine, sourceFunc));
|
||||
throw "Request for reallocation failed. Out of memory.";
|
||||
}
|
||||
|
||||
// Remove this allocation from our stats (we'll add the new reallocation again later)
|
||||
|
||||
@ -1291,7 +1304,11 @@ void m_deallocator(const char *sourceFile, const unsigned int sourceLine, const
|
||||
|
||||
// If you hit this assert, you tried to deallocate RAM that wasn't allocated by this memory manager.
|
||||
m_assert(au != NULL);
|
||||
if (au == NULL) throw "Request to deallocate RAM that was never allocated";
|
||||
if (au == NULL)
|
||||
{
|
||||
log("%s: Request to deallocate RAM that was never allocated", ownerString(sourceFile, sourceLine, sourceFunc));
|
||||
throw "Request to deallocate RAM that was never allocated";
|
||||
}
|
||||
|
||||
// If you hit this assert, then the allocation unit that is about to be deallocated is damaged. But you probably
|
||||
// already know that from a previous assert you should have seen in validateAllocUnit() :)
|
||||
|
@ -29,10 +29,19 @@
|
||||
* version.
|
||||
*/
|
||||
|
||||
#ifdef __linux__
|
||||
#include <malloc.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#include "sclinux.h"
|
||||
#endif
|
||||
#include "amxmodx.h"
|
||||
#include "osdep.h" // sleep, etc
|
||||
#include "CFile.h"
|
||||
#include "amxxfile.h"
|
||||
#include "amxdbg.h"
|
||||
#include "newmenus.h"
|
||||
#include "natives.h"
|
||||
|
||||
CList<CModule,const char*> g_modules;
|
||||
CList<CScript,AMX*> g_loadedscripts;
|
||||
@ -67,11 +76,11 @@ void report_error( int code, char* fmt, ... )
|
||||
void print_srvconsole( char *fmt, ... )
|
||||
{
|
||||
va_list argptr;
|
||||
char string[256];
|
||||
va_start (argptr, fmt);
|
||||
vsnprintf (string, 255, fmt,argptr);
|
||||
string[255] = 0;
|
||||
va_end (argptr);
|
||||
static char string[384];
|
||||
va_start(argptr, fmt);
|
||||
vsnprintf(string, sizeof(string)-1, fmt, argptr);
|
||||
string[sizeof(string)-1] = '\0';
|
||||
va_end(argptr);
|
||||
SERVER_PRINT(string);
|
||||
}
|
||||
|
||||
@ -83,14 +92,174 @@ void* alloc_amxmemory(void** p, int size)
|
||||
|
||||
void free_amxmemory(void **ptr)
|
||||
{
|
||||
delete[] *ptr;
|
||||
delete[] (unsigned char *)(*ptr);
|
||||
*ptr = 0;
|
||||
}
|
||||
|
||||
void amxx_FreeTrace(AMX_DBGINFO *pInfo)
|
||||
{
|
||||
amx_trace *pTrace = pInfo->pTrace;
|
||||
amx_trace *pTemp = NULL;
|
||||
|
||||
while (pTrace)
|
||||
{
|
||||
pTemp = pTrace->next;
|
||||
delete pTrace;
|
||||
pTrace = pTemp;
|
||||
}
|
||||
|
||||
pInfo->pTrace = NULL;
|
||||
pInfo->pTraceFrm = NULL;
|
||||
pInfo->pTraceEnd = NULL;
|
||||
}
|
||||
|
||||
//returns true if this was the last call
|
||||
bool amxx_RemTraceCall(AMX_DBGINFO *pInfo)
|
||||
{
|
||||
amx_trace *pTrace = pInfo->pTraceFrm;
|
||||
|
||||
assert(pTrace != NULL);
|
||||
|
||||
pInfo->pTraceFrm = pTrace->prev;
|
||||
pTrace->used = false;
|
||||
|
||||
if (pInfo->pTraceFrm == NULL)
|
||||
{
|
||||
//invalidate the trace
|
||||
pInfo->frm = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void amxx_FreeDebug(AMX *amx)
|
||||
{
|
||||
AMX_DBGINFO *pInfo = (AMX_DBGINFO *)amx->userdata[2];
|
||||
if (pInfo)
|
||||
{
|
||||
AMX_DBG *pDbg = (AMX_DBG *)pInfo->pDebug;
|
||||
if (pDbg)
|
||||
{
|
||||
dbg_FreeInfo(pDbg);
|
||||
delete pDbg;
|
||||
}
|
||||
if (pInfo->pTrace)
|
||||
amxx_FreeTrace(pInfo);
|
||||
delete pInfo;
|
||||
amx->userdata[2] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
amx_trace *amxx_AddTraceCall(AMX_DBGINFO *pInfo)
|
||||
{
|
||||
amx_trace *pTrace = NULL;
|
||||
|
||||
if (pInfo->pTrace == NULL)
|
||||
{
|
||||
pTrace = new amx_trace;
|
||||
memset(pTrace, 0, sizeof(amx_trace));
|
||||
pInfo->pTrace = pTrace;
|
||||
pInfo->pTraceFrm = pTrace;
|
||||
pInfo->pTraceEnd = pTrace;
|
||||
} else if (pInfo->pTraceFrm == NULL) {
|
||||
pTrace = pInfo->pTrace;
|
||||
pInfo->pTraceFrm = pTrace;
|
||||
} else {
|
||||
if (pInfo->pTraceFrm->next == NULL)
|
||||
{
|
||||
//if we are at the end of the list...
|
||||
assert(pInfo->pTraceFrm == pInfo->pTraceEnd);
|
||||
pTrace = new amx_trace;
|
||||
memset(pTrace, 0, sizeof(amx_trace));
|
||||
pTrace->prev = pInfo->pTraceEnd;
|
||||
pInfo->pTraceEnd->next = pTrace;
|
||||
pInfo->pTraceEnd = pTrace;
|
||||
pInfo->pTraceFrm = pTrace;
|
||||
} else {
|
||||
//we are somewhere else. whatever.
|
||||
pTrace = pInfo->pTraceFrm->next;
|
||||
pInfo->pTraceFrm = pTrace;
|
||||
}
|
||||
}
|
||||
|
||||
pTrace->used = true;
|
||||
|
||||
return pTrace;
|
||||
}
|
||||
|
||||
void AMXAPI amxx_InvalidateTrace(AMX *amx)
|
||||
{
|
||||
AMX_DBGINFO *pInfo = (AMX_DBGINFO *)(amx->userdata[2]);
|
||||
if (!pInfo)
|
||||
return;
|
||||
amx_trace *pTrace = pInfo->pTrace;
|
||||
|
||||
while (pTrace && pTrace->used)
|
||||
{
|
||||
pTrace->used = false;
|
||||
pTrace = pTrace->next;
|
||||
}
|
||||
|
||||
pInfo->pTraceFrm = NULL;
|
||||
pInfo->frm = 0;
|
||||
}
|
||||
|
||||
int AMXAPI amxx_DebugHook(AMX *amx)
|
||||
{
|
||||
AMX_DBGINFO *pInfo = (AMX_DBGINFO *)amx->userdata[2];
|
||||
|
||||
if ( !(amx->flags & AMX_FLAG_DEBUG) || !pInfo )
|
||||
return AMX_ERR_DEBUG;
|
||||
|
||||
enum StackState
|
||||
{
|
||||
Stack_Same,
|
||||
Stack_Push,
|
||||
Stack_Pop,
|
||||
};
|
||||
|
||||
StackState state = Stack_Same;
|
||||
|
||||
if (!pInfo->frm)
|
||||
{
|
||||
pInfo->frm = amx->frm;
|
||||
state = Stack_Push;
|
||||
} else {
|
||||
//Are we stepping through a different frame?
|
||||
if (amx->frm < pInfo->frm)
|
||||
{
|
||||
pInfo->frm = amx->frm;
|
||||
state = Stack_Push;
|
||||
} else if (amx->frm > pInfo->frm) {
|
||||
pInfo->frm = amx->frm;
|
||||
state = Stack_Pop;
|
||||
}
|
||||
}
|
||||
|
||||
if (state == Stack_Push)
|
||||
{
|
||||
amx_trace *pTrace = amxx_AddTraceCall(pInfo);
|
||||
pTrace->frm = amx->cip;
|
||||
} else if (state == Stack_Pop) {
|
||||
if (amxx_RemTraceCall(pInfo))
|
||||
{
|
||||
pInfo->frm = 0;
|
||||
}
|
||||
} else if (state == Stack_Same) {
|
||||
//save the cip
|
||||
amx_trace *pTrace = pInfo->pTraceFrm;
|
||||
assert(pTrace != NULL);
|
||||
pTrace->frm = amx->cip;
|
||||
}
|
||||
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
int load_amxscript(AMX *amx, void **program, const char *filename, char error[64], int debug)
|
||||
{
|
||||
*error = 0;
|
||||
CAmxxReader reader(filename, SMALL_CELL_SIZE / 8);
|
||||
CAmxxReader reader(filename, PAWN_CELL_SIZE / 8);
|
||||
if (reader.GetStatus() == CAmxxReader::Err_None)
|
||||
{
|
||||
size_t bufSize = reader.GetBufferSize();
|
||||
@ -148,41 +317,107 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
|
||||
return (amx->error = AMX_ERR_FORMAT);
|
||||
}
|
||||
|
||||
if ( (int)CVAR_GET_FLOAT("amx_debug") >= 2 || debug)
|
||||
{
|
||||
//automatic debug mode
|
||||
hdr->flags |= AMX_FLAG_LINEOPS;
|
||||
hdr->flags |= AMX_FLAG_DEBUG;
|
||||
}
|
||||
|
||||
int err;
|
||||
memset(amx, 0, sizeof(*amx));
|
||||
bool will_be_debugged = false;
|
||||
|
||||
tagAMX_DBG *pDbg = NULL;
|
||||
|
||||
if ((int)CVAR_GET_FLOAT("amx_debug") >= 2 || debug)
|
||||
{
|
||||
if ((hdr->file_version < CUR_FILE_VERSION))
|
||||
{
|
||||
sprintf(error, "Plugin needs newer debug version info");
|
||||
return (amx->error = AMX_ERR_VERSION);
|
||||
} else if ((hdr->flags & AMX_FLAG_DEBUG) != 0) {
|
||||
will_be_debugged = true;
|
||||
char *addr = (char *)hdr + hdr->size;
|
||||
pDbg = new tagAMX_DBG;
|
||||
memset(pDbg, 0, sizeof(AMX_DBG));
|
||||
|
||||
int err = dbg_LoadInfo(pDbg, addr);
|
||||
|
||||
if (err != AMX_ERR_NONE)
|
||||
{
|
||||
dbg_FreeInfo(pDbg);
|
||||
delete pDbg;
|
||||
sprintf(error, "Debug loading error %d", err);
|
||||
return (amx->error = AMX_ERR_INIT);
|
||||
}
|
||||
|
||||
amx->flags |= AMX_FLAG_DEBUG;
|
||||
} else {
|
||||
sprintf(error,"Plugin not compiled with debug option");
|
||||
return (amx->error = AMX_ERR_INIT);
|
||||
}
|
||||
} else {
|
||||
#ifdef JIT
|
||||
//if (hdr->file_version == CUR_FILE_VERSION)
|
||||
amx->flags |= AMX_FLAG_JITC;
|
||||
#endif
|
||||
}
|
||||
|
||||
if ((err = amx_Init( amx, *program )) != AMX_ERR_NONE)
|
||||
{
|
||||
if (pDbg)
|
||||
{
|
||||
dbg_FreeInfo(pDbg);
|
||||
delete pDbg;
|
||||
}
|
||||
sprintf(error,"Load error %d (invalid file format or version)", err);
|
||||
return (amx->error = AMX_ERR_INIT);
|
||||
}
|
||||
|
||||
AMX_DBGINFO *pInfo = new AMX_DBGINFO;
|
||||
memset(pInfo, 0, sizeof(AMX_DBGINFO));
|
||||
amx->userdata[2] = (void *)pInfo;
|
||||
|
||||
pInfo->error = AMX_ERR_NONE;
|
||||
pInfo->pDebug = (void *)pDbg;
|
||||
|
||||
if (will_be_debugged)
|
||||
{
|
||||
#ifdef JIT
|
||||
void *np = new char[ amx->code_size ];
|
||||
void *rt = new char[ amx->reloc_size ];
|
||||
amx->flags |= AMX_FLAG_DEBUG;
|
||||
#endif
|
||||
amx_SetDebugHook(amx, amxx_DebugHook);
|
||||
} else {
|
||||
//set this again because amx_Init() erases it!
|
||||
#ifdef JIT
|
||||
amx->flags |= AMX_FLAG_JITC;
|
||||
amx->sysreq_d = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef JIT
|
||||
if (amx->flags & AMX_FLAG_JITC)
|
||||
{
|
||||
char *np = new char[ amx->code_size ];
|
||||
char *rt = new char[ amx->reloc_size ];
|
||||
if ( !np || (!rt && amx->reloc_size > 0) )
|
||||
{
|
||||
delete[] np;
|
||||
delete[] rt;
|
||||
strcpy(error,"Failed to initialize plugin");
|
||||
strcpy(error,"Failed to initialize JIT'd plugin");
|
||||
return (amx->error = AMX_ERR_INIT);
|
||||
}
|
||||
|
||||
if (amx_InitJIT(amx, rt, np) == AMX_ERR_NONE)
|
||||
if ( (err = amx_InitJIT(amx, (void *)rt, (void *)np)) == AMX_ERR_NONE )
|
||||
{
|
||||
//amx->base = (unsigned char FAR *)realloc( np, amx->code_size );
|
||||
#ifndef __linux__
|
||||
amx->base = new unsigned char[ amx->code_size ];
|
||||
#else
|
||||
//posix_memalign((void **)&(amx->base), sysconf(_SC_PAGESIZE), amx->code_size);
|
||||
amx->base = (unsigned char *)memalign(sysconf(_SC_PAGESIZE), amx->code_size);
|
||||
mprotect((void *)amx->base, amx->code_size, PROT_READ|PROT_WRITE|PROT_EXEC);
|
||||
#endif
|
||||
if ( amx->base )
|
||||
memcpy( amx->base , np , amx->code_size );
|
||||
delete[] np;
|
||||
delete[] rt;
|
||||
delete[] *program;
|
||||
char *prg = (char *)(*program);
|
||||
delete[] prg;
|
||||
(*program) = amx->base;
|
||||
if ( *program == 0 ){
|
||||
strcpy(error,"Failed to allocate memory");
|
||||
@ -193,9 +428,10 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
|
||||
{
|
||||
delete[] np;
|
||||
delete[] rt;
|
||||
strcpy(error,"Failed to initialize plugin");
|
||||
sprintf(error, "Failed to initialize plugin (%d)", err);
|
||||
return (amx->error = AMX_ERR_INIT_JIT);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -208,8 +444,25 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
|
||||
}
|
||||
|
||||
g_loadedscripts.put( aa );
|
||||
amx->sysreq_d = 0;
|
||||
return set_amxnatives(amx,error);
|
||||
|
||||
set_amxnatives(amx,error);
|
||||
|
||||
if (g_plugins.m_Finalized)
|
||||
{
|
||||
amx_Register(amx, g_plugins.pNatives, -1);
|
||||
if (CheckModules(amx, error))
|
||||
{
|
||||
if ( amx_Register(amx, core_Natives, -1) != AMX_ERR_NONE )
|
||||
{
|
||||
sprintf(error, "Plugin uses an unknown function (name \"%s\") - check your modules.ini.", no_function);
|
||||
return (amx->error = AMX_ERR_NOTFOUND);
|
||||
}
|
||||
} else {
|
||||
return (amx->error = AMX_ERR_NOTFOUND);
|
||||
}
|
||||
}
|
||||
|
||||
return (amx->error = AMX_ERR_NONE);
|
||||
}
|
||||
|
||||
const char *StrCaseStr(const char *as, const char *bs)
|
||||
@ -242,64 +495,66 @@ const char *StrCaseStr(const char *as, const char *bs)
|
||||
return strstr(a,b);
|
||||
}
|
||||
|
||||
//BAILOPAN
|
||||
int CheckModules(AMX *amx, char error[64])
|
||||
//returns 0 for module not found, 1 for "everything's okay"
|
||||
int CheckModules(AMX *amx, char error[128])
|
||||
{
|
||||
int idx = 0, flag = -1;
|
||||
if (amx_FindPublic(amx, "plugin_modules", &idx) == AMX_ERR_NONE)
|
||||
int numLibraries = amx_GetLibraries(amx);
|
||||
char buffer[32];
|
||||
bool found = false;
|
||||
bool isdbi = false;
|
||||
CList<CModule,const char *>::iterator a;
|
||||
const amxx_module_info_s *info;
|
||||
|
||||
for (int i=0; i<numLibraries; i++)
|
||||
{
|
||||
cell retVal = 0;
|
||||
int err = 0;
|
||||
if ( (err = amx_Exec(amx, &retVal, idx, 0)) == AMX_ERR_NONE )
|
||||
{
|
||||
unsigned int i = 0;
|
||||
while (!CurModuleList.empty())
|
||||
{
|
||||
if (!flag)
|
||||
{
|
||||
CurModuleList.pop();
|
||||
amx_GetLibrary(amx, i, buffer, sizeof(buffer)-1);
|
||||
found = false;
|
||||
if (stricmp(buffer, "float")==0)
|
||||
continue;
|
||||
}
|
||||
//assume module is not found
|
||||
flag = 0;
|
||||
for (CList<CModule,const char *>::iterator pMod = g_modules.begin(); pMod; ++pMod)
|
||||
isdbi = false;
|
||||
if (stricmp(buffer, "dbi")==0)
|
||||
isdbi = true;
|
||||
for (a=g_modules.begin(); a; ++a)
|
||||
{
|
||||
if (strcmpi(CurModuleList.front().c_str(), "dbi") == 0)
|
||||
if ( (*a).getStatusValue() == MODULE_LOADED )
|
||||
{
|
||||
if (StrCaseStr( (*pMod).getName(), "sql") || strstr( (*pMod).getName(), "dbi" ))
|
||||
info = (*a).getInfoNew();
|
||||
if (info)
|
||||
{
|
||||
// the module checks in
|
||||
flag = 1;
|
||||
if (isdbi)
|
||||
{
|
||||
if (info->logtag
|
||||
&& (StrCaseStr(info->logtag, "sql")
|
||||
||
|
||||
StrCaseStr(info->logtag, "dbi"))
|
||||
)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (strcmpi( (*pMod).getName(), CurModuleList.front().c_str() ) == 0)
|
||||
if (info->logtag && (stricmp(info->logtag, buffer) == 0))
|
||||
{
|
||||
flag = 1;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//module was not found
|
||||
if (!flag)
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
found = LibraryExists(buffer);
|
||||
if (!found)
|
||||
{
|
||||
sprintf(error, "Module \"%s\" required for plugin. Check modules.ini.", CurModuleList.front().c_str());
|
||||
sprintf(error, "Module \"%s\" required for plugin. Check modules.ini.", buffer);
|
||||
return 0;
|
||||
}
|
||||
CurModuleList.pop();
|
||||
}
|
||||
} else {
|
||||
AMXXLOG_Log("[AMXX] Run time error %d on line %ld during module check.", err, amx->curline);
|
||||
//could not execute
|
||||
return -1; //bad! very bad!
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return flag;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int set_amxnatives(AMX* amx,char error[64])
|
||||
int set_amxnatives(AMX* amx,char error[128])
|
||||
{
|
||||
for ( CList<CModule,const char *>::iterator a = g_modules.begin(); a ; ++a )
|
||||
{
|
||||
@ -315,42 +570,38 @@ int set_amxnatives(AMX* amx,char error[64])
|
||||
amx_Register(amx, power_Natives, -1);
|
||||
amx_Register(amx, time_Natives, -1);
|
||||
amx_Register(amx, vault_Natives, -1);
|
||||
amx_Register(amx, g_NewMenuNatives, -1);
|
||||
amx_Register(amx, g_NativeNatives, -1);
|
||||
|
||||
if ( amx_Register(amx, core_Natives, -1) != AMX_ERR_NONE )
|
||||
//we're not actually gonna check these here anymore
|
||||
amx->flags |= AMX_FLAG_PRENIT;
|
||||
|
||||
int idx;
|
||||
cell retval;
|
||||
if (amx_FindPublic(amx, "plugin_natives", &idx)==AMX_ERR_NONE)
|
||||
{
|
||||
//HACKHACK - if we get here, nullify the plugin's native table
|
||||
//then reregister the one native we need
|
||||
// - BAILOPAN
|
||||
String save;
|
||||
save.assign(no_function);
|
||||
amx_NullNativeTable(amx);
|
||||
AMX_NATIVE_INFO p[] = {
|
||||
{ "require_module", require_module },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
amx_Register(amx, p, -1);
|
||||
if (CheckModules(amx, error) == -1 || *error == 0)
|
||||
if (amx_Exec(amx, &retval, idx)!=AMX_ERR_NONE)
|
||||
{
|
||||
sprintf(error,"Plugin uses an unknown function (name \"%s\") - check your modules.ini.",save.c_str());
|
||||
//someday clear libraries that this added
|
||||
}
|
||||
return (amx->error = AMX_ERR_NATIVE);
|
||||
}
|
||||
|
||||
CheckModules(amx, error);
|
||||
amx->flags &= ~(AMX_FLAG_PRENIT);
|
||||
|
||||
return AMX_ERR_NONE;
|
||||
return (amx->error = AMX_ERR_NONE);
|
||||
}
|
||||
|
||||
int unload_amxscript(AMX* amx, void** program)
|
||||
{
|
||||
amxx_FreeDebug(amx);
|
||||
CList<CScript,AMX*>::iterator a = g_loadedscripts.find( amx );
|
||||
if ( a ) a.remove();
|
||||
delete[] *program;
|
||||
char *prg = (char *)*program;
|
||||
delete[] prg;
|
||||
*program = 0;
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
AMX* get_amxscript(int id , void** code, const char** filename)
|
||||
{
|
||||
CList<CScript,AMX*>::iterator a = g_loadedscripts.begin();
|
||||
@ -411,6 +662,38 @@ char* build_pathname(char *fmt, ... )
|
||||
return string;
|
||||
}
|
||||
|
||||
char *build_pathname_r(char *buffer, size_t maxlen, char *fmt, ...)
|
||||
{
|
||||
snprintf(buffer, maxlen,
|
||||
#ifdef __linux__
|
||||
"%s/",
|
||||
#else
|
||||
"%s\\",
|
||||
#endif
|
||||
g_mod_name.c_str()
|
||||
);
|
||||
|
||||
size_t len = strlen(buffer);
|
||||
char *ptr = buffer + len;
|
||||
|
||||
va_list argptr;
|
||||
va_start(argptr, fmt);
|
||||
vsnprintf (ptr, maxlen-len, fmt, argptr);
|
||||
va_end (argptr);
|
||||
|
||||
while (*ptr)
|
||||
{
|
||||
#ifndef __linux__
|
||||
if (*ptr == '/') *ptr = '\\';
|
||||
#else
|
||||
if (*ptr == '\\') *ptr = '/';
|
||||
#endif
|
||||
++ptr;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
// build pathname based on addons dir
|
||||
char* build_pathname_addons(char *fmt, ... )
|
||||
@ -437,27 +720,6 @@ char* build_pathname_addons(char *fmt, ... )
|
||||
return string;
|
||||
}
|
||||
|
||||
int add_amxnatives(module_info_s* info,AMX_NATIVE_INFO*natives)
|
||||
{
|
||||
CList<CModule,const char *>::iterator a = g_modules.begin();
|
||||
|
||||
while ( a )
|
||||
{
|
||||
if ( (*a).getInfo() == info )
|
||||
{
|
||||
AMX_NATIVE_INFO** aa = new AMX_NATIVE_INFO*(natives);
|
||||
if ( aa == 0 ) return AMX_ERR_NATIVE;
|
||||
(*a).m_Natives.put( aa );
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
++a;
|
||||
}
|
||||
|
||||
return AMX_ERR_NATIVE;
|
||||
}
|
||||
|
||||
|
||||
bool validFile(const char* file)
|
||||
{
|
||||
const char* a = 0;
|
||||
@ -473,7 +735,7 @@ bool validFile(const char* file)
|
||||
|
||||
void ConvertModuleName(const char *pathString, String &path)
|
||||
{
|
||||
#if SMALL_CELL_SIZE==64
|
||||
#if PAWN_CELL_SIZE==64
|
||||
char *ptr = strstr(pathString, "i386");
|
||||
if (ptr)
|
||||
{
|
||||
@ -568,10 +830,10 @@ void ConvertModuleName(const char *pathString, String &path)
|
||||
}
|
||||
}
|
||||
#endif //__linux__
|
||||
#endif //SMALL_CELL_SIZE==64
|
||||
#endif //PAWN_CELL_SIZE==64
|
||||
}
|
||||
|
||||
int loadModules(const char* filename)
|
||||
int loadModules(const char* filename, PLUG_LOADTIME now)
|
||||
{
|
||||
FILE *fp = fopen(build_pathname("%s",filename), "rt");
|
||||
|
||||
@ -616,7 +878,11 @@ int loadModules(const char* filename)
|
||||
|
||||
CModule* cc = new CModule( path.c_str() );
|
||||
|
||||
if ( cc == 0 ) return loaded;
|
||||
if ( cc == 0 )
|
||||
{
|
||||
fclose(fp);
|
||||
return loaded;
|
||||
}
|
||||
|
||||
cc->queryModule();
|
||||
|
||||
@ -651,6 +917,34 @@ int loadModules(const char* filename)
|
||||
|
||||
g_modules.put( cc );
|
||||
|
||||
#ifndef FAKEMETA
|
||||
if ( cc->IsMetamod())
|
||||
{
|
||||
char* mmpathname = build_pathname_addons("%s/%s", get_localinfo("amxx_modulesdir", "addons/amxmodx/modules"), line.c_str());
|
||||
ConvertModuleName(mmpathname, path);
|
||||
cc->attachMetamod(path.c_str(), now);
|
||||
}
|
||||
|
||||
bool retVal = cc->attachModule();
|
||||
if (cc->isAmxx() && !retVal)
|
||||
{
|
||||
switch (cc->getStatusValue())
|
||||
{
|
||||
case MODULE_FUNCNOTPRESENT:
|
||||
report_error(1, "[AMXX] Module requested a not exisitng function (file \"%s\")%s%s%s", cc->getFilename(), cc->getMissingFunc() ? " (func \"" : "",
|
||||
cc->getMissingFunc() ? cc->getMissingFunc() : "", cc->getMissingFunc() ? "\")" : "");
|
||||
break;
|
||||
case MODULE_INTERROR:
|
||||
report_error(1, "[AMXX] Internal error during module load (file \"%s\")", cc->getFilename());
|
||||
break;
|
||||
case MODULE_BADLOAD:
|
||||
report_error( 1 , "[AMXX] Module is not a valid library (file \"%s\")", cc->getFilename());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
@ -675,7 +969,11 @@ void detachReloadModules()
|
||||
|
||||
while ( a )
|
||||
{
|
||||
#ifdef FAKEMETA
|
||||
if ( (*a).isReloadable() )
|
||||
#else
|
||||
if ( (*a).isReloadable() && !(*a).IsMetamod() )
|
||||
#endif
|
||||
{
|
||||
(*a).detachModule();
|
||||
a.remove();
|
||||
@ -687,6 +985,7 @@ void detachReloadModules()
|
||||
|
||||
}
|
||||
|
||||
#ifdef FAKEMETA
|
||||
void attachModules()
|
||||
{
|
||||
CList<CModule,const char *>::iterator a = g_modules.begin();
|
||||
@ -716,6 +1015,7 @@ void attachModules()
|
||||
++a;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
const char* strip_name( const char* a )
|
||||
{
|
||||
@ -730,6 +1030,7 @@ const char* strip_name( const char* a )
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef FAKEMETA
|
||||
void attachMetaModModules(PLUG_LOADTIME now, const char* filename)
|
||||
{
|
||||
File fp( build_pathname("%s",filename), "r" );
|
||||
@ -792,7 +1093,7 @@ void attachMetaModModules(PLUG_LOADTIME now, const char* filename)
|
||||
g_FakeMeta.Meta_Query(gpMetaUtilFuncs);
|
||||
g_FakeMeta.Meta_Attach(now, gpMetaGlobals, gpGamedllFuncs);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// Get the number of running modules
|
||||
@ -860,9 +1161,13 @@ int MNF_AddNatives(AMX_NATIVE_INFO* natives)
|
||||
const char *MNF_GetModname(void)
|
||||
{
|
||||
// :TODO: Do we have to do this??
|
||||
// I dunno who wrote the above comment but no
|
||||
#if 0
|
||||
static char buffer[64];
|
||||
strcpy(buffer, g_mod_name.c_str());
|
||||
return buffer;
|
||||
#endif
|
||||
return g_mod_name.c_str();
|
||||
}
|
||||
|
||||
AMX *MNF_GetAmxScript(int id)
|
||||
@ -1100,18 +1405,36 @@ REAL MNF_CellToReal(cell x)
|
||||
|
||||
void MNF_Log(const char *fmt, ...)
|
||||
{
|
||||
// :TODO: Overflow possible here
|
||||
char msg[3072];
|
||||
va_list arglst;
|
||||
va_start(arglst, fmt);
|
||||
vsprintf(msg, fmt, arglst);
|
||||
_vsnprintf(msg, sizeof(msg)-1, fmt, arglst);
|
||||
//vsprintf(msg, fmt, arglst);
|
||||
va_end(arglst);
|
||||
AMXXLOG_Log("%s", msg);
|
||||
}
|
||||
|
||||
bool amxx_GetPluginData(AMX *amx, cell addr, long &line, const char *&filename, const char *&function)
|
||||
{
|
||||
AMX_DBGINFO *pInfo = (AMX_DBGINFO *)(amx->userdata[2]);
|
||||
|
||||
if (pInfo && pInfo->pDebug)
|
||||
{
|
||||
AMX_DBG *pDbg = (AMX_DBG *)pInfo->pDebug;
|
||||
dbg_LookupFunction(pDbg, addr, &function);
|
||||
dbg_LookupLine(pDbg, addr, &line);
|
||||
dbg_LookupFile(pDbg, addr, &filename);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//by BAILOPAN
|
||||
// generic error printing routine
|
||||
void GenericError(AMX *amx, int err, int line, char buf[], const char *file)
|
||||
// for pawn 3.0 this is just a wrapper
|
||||
const char *GenericError(int err)
|
||||
{
|
||||
static const char *amx_errs[] =
|
||||
{
|
||||
@ -1128,7 +1451,7 @@ void GenericError(AMX *amx, int err, int line, char buf[], const char *file)
|
||||
"native",
|
||||
"divide",
|
||||
"sleep",
|
||||
NULL,
|
||||
"invalid access state",
|
||||
NULL,
|
||||
NULL,
|
||||
"out of memory", //16
|
||||
@ -1146,25 +1469,10 @@ void GenericError(AMX *amx, int err, int line, char buf[], const char *file)
|
||||
//does this plugin have line ops?
|
||||
const char *geterr = NULL;
|
||||
if (err > 26 || err < 0)
|
||||
geterr = NULL;
|
||||
geterr = "";
|
||||
else
|
||||
geterr = amx_errs[err];
|
||||
if (!(amx->flags & AMX_FLAG_LINEOPS))
|
||||
{
|
||||
if (geterr == NULL)
|
||||
{
|
||||
sprintf(buf, "Run time error %d (plugin \"%s\" - debug not enabled).", err, g_plugins.findPluginFast(amx)->getName());
|
||||
} else {
|
||||
sprintf(buf, "Run time error %d (%s) (plugin \"%s\") - debug not enabled.", err, geterr, g_plugins.findPluginFast(amx)->getName());
|
||||
}
|
||||
} else {
|
||||
if (geterr == NULL)
|
||||
{
|
||||
sprintf(buf, "Run time error %d on line %d (%s \"%s\").", err, line, (file?"file":"plugin"), (file?file:g_plugins.findPluginFast(amx)->getName()));
|
||||
} else {
|
||||
sprintf(buf, "Run time error %d (%s) on line %d (%s \"%s\").", err, geterr, line, (file?"file":"plugin"), (file?file:g_plugins.findPluginFast(amx)->getName()));
|
||||
}
|
||||
}
|
||||
return geterr;
|
||||
}
|
||||
|
||||
//by BAILOPAN
|
||||
@ -1173,55 +1481,70 @@ void LogError(AMX *amx, int err, const char *fmt, ...)
|
||||
{
|
||||
//does this plugin have debug info?
|
||||
va_list arg;
|
||||
AMX_DBG *dbg = (AMX_DBG *)(amx->userdata[0]);
|
||||
AMX_DBGINFO *pInfo = (AMX_DBGINFO *)(amx->userdata[2]);
|
||||
const char *name = get_amxscriptname(amx);
|
||||
static char buf[1024];
|
||||
static char vbuf[1024];
|
||||
*buf = 0;
|
||||
*vbuf = 0;
|
||||
|
||||
if (fmt[0] == '\0')
|
||||
{
|
||||
_snprintf(vbuf, sizeof(vbuf)-1, "Run time error %d (%s)", err, GenericError(err));
|
||||
} else {
|
||||
va_start(arg, fmt);
|
||||
vsprintf(vbuf, fmt, arg);
|
||||
va_end(arg);
|
||||
}
|
||||
|
||||
if (!dbg || !(dbg->tail))
|
||||
{
|
||||
GenericError(amx, err, amx->curline, buf, NULL);
|
||||
AMXXLOG_Log("[AMXX] %s %s", buf, vbuf);
|
||||
} else {
|
||||
AMX_TRACE *t = dbg->tail;
|
||||
AMX_DEBUGCALL tracer = (AMX_DEBUGCALL)(amx->userdata[1]);
|
||||
//actuall
|
||||
cell line = amx->curline;
|
||||
cell file = amx->curfile;
|
||||
int i = 0;
|
||||
if (file >= dbg->numFiles || file < 0)
|
||||
{
|
||||
GenericError(amx, err, line, buf, NULL);
|
||||
} else {
|
||||
GenericError(amx, err, line, buf, dbg->files[file]);
|
||||
}
|
||||
AMXXLOG_Log("[AMXX] %s", buf);
|
||||
if (*vbuf)
|
||||
{
|
||||
bool invalidate = false;
|
||||
AMXXLOG_Log("[AMXX] %s", vbuf);
|
||||
}
|
||||
AMXXLOG_Log("[AMXX] Debug Trace =>");
|
||||
//log the error right away
|
||||
while (t != NULL)
|
||||
if (!pInfo || !(amx->flags & AMX_FLAG_DEBUG) || !pInfo->pDebug)
|
||||
{
|
||||
line = t->line;
|
||||
file = t->file;
|
||||
if (file >= dbg->numFiles)
|
||||
{
|
||||
AMXXLOG_Log("[AMXX] [%d] Line %d, File \"%s\"", i++, line, g_plugins.findPluginFast(amx)->getName());
|
||||
|
||||
AMXXLOG_Log("[AMXX] Debug is not enabled (plugin \"%s\")", name);
|
||||
invalidate = true;
|
||||
} else {
|
||||
AMXXLOG_Log("[AMXX] [%d] Line %d, File \"%s\"", i++, line, dbg->files[file]);
|
||||
long line;
|
||||
const char *filename = NULL;
|
||||
const char *function = NULL;
|
||||
amx_trace *pTrace = pInfo->pTraceFrm;
|
||||
int i=0, iLine;
|
||||
cell frame;
|
||||
|
||||
AMXXLOG_Log("[AMXX] Displaying call trace (plugin \"%s\")", name);
|
||||
while (pTrace)
|
||||
{
|
||||
frame = pTrace->frm;
|
||||
|
||||
if (amxx_GetPluginData(amx, frame, line, filename, function))
|
||||
{
|
||||
//line seems to be 1 off o_O
|
||||
iLine = static_cast<int>(line) + 1;
|
||||
AMXXLOG_Log("[AMXX] [%d] %s::%s (line %d)",
|
||||
i,
|
||||
filename?filename:"",
|
||||
function?function:"",
|
||||
iLine
|
||||
);
|
||||
}
|
||||
if (tracer)
|
||||
(tracer)(amx, 1); //pop
|
||||
t = dbg->tail;
|
||||
|
||||
pTrace->used = false;
|
||||
pTrace = pTrace->prev;
|
||||
i++;
|
||||
}
|
||||
//by now we have already invalidated
|
||||
pInfo->pTraceFrm = NULL;
|
||||
pInfo->frm = 0;
|
||||
}
|
||||
|
||||
if (invalidate)
|
||||
amxx_InvalidateTrace(amx);
|
||||
|
||||
//set these so ForwardMngr knows not to call us again
|
||||
//This will also halt the script!
|
||||
amx->error = err;
|
||||
pInfo->error = err;
|
||||
}
|
||||
|
||||
void MNF_MergeDefinitionFile(const char *file)
|
||||
@ -1281,27 +1604,55 @@ cell MNF_PrepareCharArray(char *ptr, unsigned int size)
|
||||
return prepareCharArray(ptr, size, false);
|
||||
}
|
||||
|
||||
inline bool operator ==(func_s &arg1, const char *desc)
|
||||
{
|
||||
if (strcmp(arg1.desc, desc) == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
CList<func_s, const char *> g_functions;
|
||||
|
||||
// Fnptr Request function for the new interface
|
||||
const char *g_LastRequestedFunc = NULL;
|
||||
#define REGISTER_FUNC(name, func) { name, (void*)func },
|
||||
void *Module_ReqFnptr(const char *funcName)
|
||||
#define REGISTER_FUNC(name, func) \
|
||||
{ \
|
||||
pFunc = new func_s; \
|
||||
pFunc->pfn = (void *)func; \
|
||||
pFunc->desc = name; \
|
||||
g_functions.put(pFunc); \
|
||||
}
|
||||
|
||||
void MNF_RegisterFunction(void *pfn, const char *description)
|
||||
{
|
||||
// func table
|
||||
struct Func_s
|
||||
{
|
||||
const char *name;
|
||||
void *ptr;
|
||||
};
|
||||
static Func_s functions[] = {
|
||||
// Misc
|
||||
func_s *pFunc;
|
||||
|
||||
REGISTER_FUNC(description, pfn);
|
||||
}
|
||||
|
||||
void Module_UncacheFunctions()
|
||||
{
|
||||
g_functions.clear();
|
||||
}
|
||||
|
||||
int amx_Execv()
|
||||
{
|
||||
return AMX_ERR_NOTFOUND;
|
||||
}
|
||||
|
||||
void Module_CacheFunctions()
|
||||
{
|
||||
func_s *pFunc;
|
||||
|
||||
REGISTER_FUNC("BuildPathname", build_pathname)
|
||||
REGISTER_FUNC("BuildPathnameR", build_pathname_r)
|
||||
REGISTER_FUNC("PrintSrvConsole", print_srvconsole)
|
||||
REGISTER_FUNC("GetModname", MNF_GetModname)
|
||||
REGISTER_FUNC("Log", MNF_Log)
|
||||
REGISTER_FUNC("LogError", LogError)
|
||||
REGISTER_FUNC("MergeDefinitionFile", MNF_MergeDefinitionFile)
|
||||
REGISTER_FUNC("Format", MNF_Format)
|
||||
REGISTER_FUNC("RegisterFunction", MNF_RegisterFunction);
|
||||
|
||||
// Amx scripts loading / unloading / managing
|
||||
REGISTER_FUNC("GetAmxScript", MNF_GetAmxScript)
|
||||
@ -1321,7 +1672,8 @@ void *Module_ReqFnptr(const char *funcName)
|
||||
|
||||
// other amx stuff
|
||||
REGISTER_FUNC("amx_Exec", amx_Exec)
|
||||
REGISTER_FUNC("amx_Execv", amx_Execv)
|
||||
REGISTER_FUNC("amx_Push", amx_Push)
|
||||
REGISTER_FUNC("amx_Execv", amx_Execv) //I HOPE NO ONE USES THIS!!!!
|
||||
REGISTER_FUNC("amx_Allot", amx_Allot)
|
||||
REGISTER_FUNC("amx_FindPublic", amx_FindPublic)
|
||||
REGISTER_FUNC("amx_FindNative", amx_FindNative)
|
||||
@ -1376,19 +1728,25 @@ void *Module_ReqFnptr(const char *funcName)
|
||||
#endif // MEMORY_TEST
|
||||
|
||||
REGISTER_FUNC("Haha_HiddenStuff", MNF_HiddenStuff)
|
||||
};
|
||||
}
|
||||
|
||||
void *Module_ReqFnptr(const char *funcName)
|
||||
{
|
||||
// code
|
||||
if (!g_CurrentlyCalledModule || g_ModuleCallReason != ModuleCall_Attach)
|
||||
// ^---- really? wow!
|
||||
if (!g_CurrentlyCalledModule)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_LastRequestedFunc = funcName;
|
||||
for (unsigned int i = 0; i < (sizeof(functions) / sizeof(Func_s)); ++i)
|
||||
|
||||
CList<func_s, const char *>::iterator iter;
|
||||
for (iter = g_functions.begin(); iter; ++iter)
|
||||
{
|
||||
if (strcmp(funcName, functions[i].name) == 0)
|
||||
return functions[i].ptr;
|
||||
if (strcmp(funcName, iter->desc) == 0)
|
||||
return iter->pfn;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -45,135 +45,9 @@
|
||||
#undef C_DLLEXPORT
|
||||
#define C_DLLEXPORT extern "C" DLLEXPORT
|
||||
|
||||
#define AMX_INTERFACE_VERSION 6
|
||||
|
||||
#define RELOAD_MODULE 0
|
||||
#define STATIC_MODULE 1
|
||||
|
||||
struct module_info_s {
|
||||
const char* name;
|
||||
const char* author;
|
||||
const char* version;
|
||||
int ivers;
|
||||
int type;
|
||||
long int serial;
|
||||
};
|
||||
|
||||
// Small scripting language
|
||||
struct pfnamx_engine_g {
|
||||
uint16_t* (*pfnamx_Align16)(uint16_t *); // value
|
||||
uint32_t* (*pfnamx_Align32)(uint32_t *); // value
|
||||
int (*pfnamx_Allot)(AMX*, int, cell*, cell**); // amx, length, amx_addr, phys_addr
|
||||
int (*pfnamx_Callback)(AMX*, cell , cell*, cell*); // amx, index,result,params
|
||||
int (*pfnamx_Clone)(AMX*, AMX*, void*); // amxClone, amxSrc, data
|
||||
int (*pfnamx_Debug)(AMX*); // default debug procedure, does nothing // amx
|
||||
int (*pfnamx_Exec)(AMX*, cell*, int , int , ...); // amx, return val, index, num_params, ...
|
||||
int (*pfnamx_Execv)(AMX*, cell*, int , int, cell[]); // amx, return val, index, num_params, param[]
|
||||
int (*pfnamx_FindPublic)(AMX*, char*, int*); // amx, func name, index
|
||||
int (*pfnamx_FindPubVar)(AMX*, char*, cell*); // anx, var name, amx_addr
|
||||
int (*pfnamx_FindTagId)(AMX*, cell , char*); // amx. tag_id, tagname
|
||||
int (*pfnamx_Flags)(AMX*,uint16_t *); // amx, flags
|
||||
int (*pfnamx_GetAddr)(AMX*,cell ,cell**); // amx, amx_addr, phys_addr
|
||||
int (*pfnamx_GetPublic)(AMX*, int , char*); // amx, index, funcname
|
||||
int (*pfnamx_GetPubVar)(AMX*, int , char*, cell*); // amx, index, varname, amx_addr
|
||||
int (*pfnamx_GetString)(char*dest,cell*); // dest, source
|
||||
int (*pfnamx_GetTag)(AMX*, int , char*, cell*); // amx, index, tagname, tag_id
|
||||
int (*pfnamx_GetUserData)(AMX*, long , void **); // amx, tag, ptr
|
||||
int (*pfnamx_Init)(AMX*, void *); // amx, program
|
||||
int (*pfnamx_InitJIT)(AMX*, void *, void *); // amx, reloc_table, native_code
|
||||
int (*pfnamx_MemInfo)(AMX*, long*, long*, long*); // amx, codesize, datasize, stackheap
|
||||
int (*pfnamx_NameLength)(AMX*, int*); // amx, length
|
||||
AMX_NATIVE_INFO * (*pfnamx_NativeInfo)(char*,AMX_NATIVE ); // name, func
|
||||
int (*pfnamx_NumPublics)(AMX*, int*); // amx, number
|
||||
int (*pfnamx_NumPubVars)(AMX*, int*); // amx, number
|
||||
int (*pfnamx_NumTags)(AMX*, int*); // amx, number
|
||||
int (*pfnamx_RaiseError)(AMX*, int ); // amx, error
|
||||
int (*pfnamx_Register)(AMX*, AMX_NATIVE_INFO*, int ); // amx, nativelist, number
|
||||
int (*pfnamx_Release)(AMX*, cell ); // amx, amx_addr
|
||||
int (*pfnamx_SetCallback)(AMX*, AMX_CALLBACK ); // amx, callback
|
||||
int (*pfnamx_SetDebugHook)(AMX*, AMX_DEBUG ); // amx, debug
|
||||
int (*pfnamx_SetString)(cell*, char*, int ); // dest, source, pack
|
||||
int (*pfnamx_SetUserData)(AMX*, long , void*); // amx, tag, prt
|
||||
int (*pfnamx_StrLen)(cell*, int*); // amx, cstring, length
|
||||
};
|
||||
extern pfnamx_engine_g* g_engAmxFunc;
|
||||
|
||||
#define AMX_ALIGN16 (*g_engAmxFunc->pfnamx_Align16)
|
||||
#define AMX_ALIGN32 (*g_engAmxFunc->pfnamx_Align32)
|
||||
#define AMX_ALLOT (*g_engAmxFunc->pfnamx_Allot)
|
||||
#define AMX_CALLBACK (*g_engAmxFunc->pfnamx_Callback)
|
||||
#define AMX_CLONE (*g_engAmxFunc->pfnamx_Clone)
|
||||
#define AMX_DEBUG (*g_engAmxFunc->pfnamx_Debug)
|
||||
#define AMX_EXEC (*g_engAmxFunc->pfnamx_Exec)
|
||||
#define AMX_EXECV (*g_engAmxFunc->pfnamx_Execv)
|
||||
#define AMX_FINDPUBLIC (*g_engAmxFunc->pfnamx_FindPublic)
|
||||
#define AMX_FINDPUBVAR (*g_engAmxFunc->pfnamx_FindPubVar)
|
||||
#define AMX_FINDTAGID (*g_engAmxFunc->pfnamx_FindTagId)
|
||||
#define AMX_FLAGS (*g_engAmxFunc->pfnamx_Flags)
|
||||
#define AMX_GETADDR (*g_engAmxFunc->pfnamx_GetAddr)
|
||||
#define AMX_GETPUBLIC (*g_engAmxFunc->pfnamx_GetPublic)
|
||||
#define AMX_GETPUBVAR (*g_engAmxFunc->pfnamx_GetPubVar)
|
||||
#define AMX_GETSTRING (*g_engAmxFunc->pfnamx_GetString)
|
||||
#define AMX_GETTAG (*g_engAmxFunc->pfnamx_GetTag)
|
||||
#define AMX_GETUSERDATA (*g_engAmxFunc->pfnamx_GetUserData)
|
||||
#define AMX_INIT (*g_engAmxFunc->pfnamx_Init)
|
||||
#define AMX_INITJIT (*g_engAmxFunc->pfnamx_InitJIT)
|
||||
#define AMX_MEMINFO (*g_engAmxFunc->pfnamx_MemInfo)
|
||||
#define AMX_NAMELENGTH (*g_engAmxFunc->pfnamx_NameLength)
|
||||
#define AMX_NATIVEINFO (*g_engAmxFunc->pfnamx_NativeInfo)
|
||||
#define AMX_NUMPUBLICS (*g_engAmxFunc->pfnamx_NumPublics)
|
||||
#define AMX_NUMPUBVARS (*g_engAmxFunc->pfnamx_NumPubVars)
|
||||
#define AMX_NUMTAGS (*g_engAmxFunc->pfnamx_NumTags)
|
||||
#define AMX_RAISEERROR (*g_engAmxFunc->pfnamx_RaiseError)
|
||||
#define AMX_REGISTER (*g_engAmxFunc->pfnamx_Register)
|
||||
#define AMX_RELEASE (*g_engAmxFunc->pfnamx_Release)
|
||||
#define AMX_SETCALLBACK (*g_engAmxFunc->pfnamx_SetCallback)
|
||||
#define AMX_SETDEBUGHOOK (*g_engAmxFunc->pfnamx_SetDebugHook)
|
||||
#define AMX_SETSTRING (*g_engAmxFunc->pfnamx_SetString)
|
||||
#define AMX_SETUSERDATA (*g_engAmxFunc->pfnamx_SetUserData)
|
||||
#define AMX_STRLEN (*g_engAmxFunc->pfnamx_StrLen)
|
||||
|
||||
// Modules API
|
||||
struct pfnmodule_engine_g {
|
||||
int (*pfnadd_amxnatives)(module_info_s*,AMX_NATIVE_INFO*); // list
|
||||
char* (*pfnbuild_pathname)(char*, ...); // format, ....
|
||||
void (*pfncopy_amxmemory)(cell*,cell*,int); // dest, src, len
|
||||
char* (*pfnformat_amxstring)(AMX*, cell*, int ,int& ); // amx, format, start pos, len
|
||||
cell* (*pfnget_amxaddr)(AMX*,cell ); // amx, cell
|
||||
AMX* (*pfnget_amxscript)(int, void**,const char**); // id, code, name
|
||||
const char* (*pfnget_amxscriptname)(AMX* amx); // amx
|
||||
char* (*pfnget_amxstring)(AMX*,cell,int, int&); // amx, src, buffer (0-3), len
|
||||
void (*pfnget_modname)(char*); // modname
|
||||
int (*pfnload_amxscript)(AMX*, void**, const char*, char[64], int); // amx, code, path, error info
|
||||
void (*pfnprint_console)(char*, ...); // format, ....
|
||||
void (*pfnreport_error)(int code, char*, ... );
|
||||
int (*pfnset_amxnatives)(AMX*,char[64]); // amx, error info
|
||||
int (*pfnset_amxstring)(AMX*,cell ,const char*,int); // amx, dest, string, maxlen
|
||||
int (*pfnamxstring_length)(cell*); // src
|
||||
int (*pfnunload_amxscript)(AMX* amx,void**); // amx, code
|
||||
void* (*pfnalloc_amxmemory)(void**,int size);
|
||||
void (*pfnfree_amxmemory)(void**);
|
||||
};
|
||||
extern pfnmodule_engine_g* g_engModuleFunc;
|
||||
|
||||
#define ADD_AMXNATIVES (*g_engModuleFunc->pfnadd_amxnatives)
|
||||
#define AMXSTRING_LENGTH (*g_engModuleFunc->pfnamxstring_length)
|
||||
#define BUILD_PATHNAME (*g_engModuleFunc->pfnbuild_pathname)
|
||||
#define COPY_AMXMEMORY (*g_engModuleFunc->pfncopy_amxmemory)
|
||||
#define FORMAT_AMXSTRING (*g_engModuleFunc->pfnformat_amxstring)
|
||||
#define GET_AMXADDR (*g_engModuleFunc->pfnget_amxaddr)
|
||||
#define GET_AMXSCRIPT (*g_engModuleFunc->pfnget_amxscript)
|
||||
#define GET_AMXSCRIPTNAME (*g_engModuleFunc->pfnget_amxscriptname)
|
||||
#define GET_AMXSTRING (*g_engModuleFunc->pfnget_amxstring)
|
||||
#define GET_MODNAME (*g_engModuleFunc->pfnget_modname)
|
||||
#define LOAD_AMXSCRIPT (*g_engModuleFunc->pfnload_amxscript)
|
||||
#define PRINT_CONSOLE (*g_engModuleFunc->pfnprint_console)
|
||||
#define REPORT_ERROR (*g_engModuleFunc->pfnreport_error)
|
||||
#define SET_AMXNATIVES (*g_engModuleFunc->pfnset_amxnatives)
|
||||
#define SET_AMXSTRING (*g_engModuleFunc->pfnset_amxstring)
|
||||
#define UNLOAD_AMXSCRIPT (*g_engModuleFunc->pfnunload_amxscript)
|
||||
#define ALLOC_AMXMEMORY (*g_engModuleFunc->pfnalloc_amxmemory)
|
||||
#define FREE_AMXMEMORY (*g_engModuleFunc->pfnfree_amxmemory)
|
||||
|
||||
int CheckModules(AMX *amx, char error[128]);
|
||||
|
||||
#endif // __MODULES_H__
|
||||
|
@ -1,804 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="amxmodx"
|
||||
ProjectGUID="{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}"
|
||||
SccProjectName=""
|
||||
SccLocalPath="">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\Debug"
|
||||
IntermediateDirectory=".\Debug"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""C:\Hry\Half-Life\SDK\Multiplayer Source\pm_shared";"C:\Hry\Half-Life\SDK\Multiplayer Source\dlls";"C:\Hry\Half-Life\SDK\Multiplayer Source\engine";"C:\Hry\Half-Life\SDK\Multiplayer Source\common";C:\Files\Programming\metamod\metamod"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="5"
|
||||
StructMemberAlignment="3"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="amxmodx.h"
|
||||
PrecompiledHeaderFile=".\debug/amxmodx.pch"
|
||||
AssemblerListingLocation=".\debug/"
|
||||
ObjectFile=".\debug/"
|
||||
ProgramDataBaseFileName=".\debug/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib"
|
||||
OutputFile="debug/amxmodx_mm.dll"
|
||||
Version="0.1"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||
ModuleDefinitionFile=""
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile=".\debug/amxx_mm.pdb"
|
||||
ImportLibrary=".\debug/amxx_mm.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\debug/amxmodx.tlb"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\Release"
|
||||
IntermediateDirectory=".\Release"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
GlobalOptimizations="TRUE"
|
||||
InlineFunctionExpansion="1"
|
||||
FavorSizeOrSpeed="1"
|
||||
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="4"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="amxmodx.h"
|
||||
PrecompiledHeaderFile=".\release/amxmodx.pch"
|
||||
AssemblerListingLocation=".\release/"
|
||||
ObjectFile=".\release/"
|
||||
ProgramDataBaseFileName=".\release/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib"
|
||||
OutputFile="release/amxmodx_mm.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||
ModuleDefinitionFile=""
|
||||
ProgramDatabaseFile=".\release/amxx_mm.pdb"
|
||||
ImportLibrary=".\release/amxx_mm.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\release/amxmodx.tlb"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="MemtestDebug|Win32"
|
||||
OutputDirectory="MemtestDebug"
|
||||
IntermediateDirectory="MemtestDebug"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""C:\Hry\Half-Life\SDK\Multiplayer Source\pm_shared";"C:\Hry\Half-Life\SDK\Multiplayer Source\dlls";"C:\Hry\Half-Life\SDK\Multiplayer Source\engine";"C:\Hry\Half-Life\SDK\Multiplayer Source\common";C:\Files\Programming\metamod\metamod"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;MEMORY_TEST"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="5"
|
||||
StructMemberAlignment="3"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="amxmodx.h"
|
||||
PrecompiledHeaderFile=".\memtestdebug/amxmodx.pch"
|
||||
AssemblerListingLocation=".\memtestdebug/"
|
||||
ObjectFile=".\memtestdebug/"
|
||||
ProgramDataBaseFileName=".\memtestdebug/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib"
|
||||
OutputFile="memtestdebug/amxmodx_mm.dll"
|
||||
Version="0.1"
|
||||
LinkIncremental="2"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||
ModuleDefinitionFile=""
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile=".\memtestdebug/amxx_mm.pdb"
|
||||
ImportLibrary=".\memtestdebug/amxx_mm.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\debug/amxmodx.tlb"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="MemtestRelease|Win32"
|
||||
OutputDirectory="MemtestRelease"
|
||||
IntermediateDirectory="MemtestRelease"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
GlobalOptimizations="TRUE"
|
||||
InlineFunctionExpansion="1"
|
||||
FavorSizeOrSpeed="1"
|
||||
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;MEMORY_TEST"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="4"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="amxmodx.h"
|
||||
PrecompiledHeaderFile=".\memtestrelease/amxmodx.pch"
|
||||
AssemblerListingLocation=".\memtestrelease/"
|
||||
ObjectFile=".\memtestrelease/"
|
||||
ProgramDataBaseFileName=".\memtestrelease/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib"
|
||||
OutputFile="memtestrelease/amxmodx_mm.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||
ModuleDefinitionFile=""
|
||||
ProgramDatabaseFile=".\memtestrelease/amxx_mm.pdb"
|
||||
ImportLibrary=".\memtestrelease/amxx_mm.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\release/amxmodx.tlb"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="JITDebug|Win32"
|
||||
OutputDirectory="JITDebug"
|
||||
IntermediateDirectory="JITDebug"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""C:\Hry\Half-Life\SDK\Multiplayer Source\pm_shared";"C:\Hry\Half-Life\SDK\Multiplayer Source\dlls";"C:\Hry\Half-Life\SDK\Multiplayer Source\engine";"C:\Hry\Half-Life\SDK\Multiplayer Source\common";C:\Files\Programming\metamod\metamod"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="5"
|
||||
StructMemberAlignment="3"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="amxmodx.h"
|
||||
PrecompiledHeaderFile=".\jitdebug/amxmodx.pch"
|
||||
AssemblerListingLocation=".\jitdebug/"
|
||||
ObjectFile=".\jitdebug/"
|
||||
ProgramDataBaseFileName=".\jitdebug/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib ..\jit\jits.lib ..\zlib\zlib.lib"
|
||||
OutputFile="jitdebug/amxmodx_mm.dll"
|
||||
Version="0.1"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||
ModuleDefinitionFile=""
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile=".\jitdebug/amxx_mm.pdb"
|
||||
ImportLibrary=".\jitdebug/amxx_mm.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\debug/amxmodx.tlb"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="JITRelease|Win32"
|
||||
OutputDirectory="JITRelease"
|
||||
IntermediateDirectory="JITRelease"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
GlobalOptimizations="TRUE"
|
||||
InlineFunctionExpansion="1"
|
||||
FavorSizeOrSpeed="1"
|
||||
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="4"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="amxmodx.h"
|
||||
PrecompiledHeaderFile=".\jitrelease/amxmodx.pch"
|
||||
AssemblerListingLocation=".\jitrelease/"
|
||||
ObjectFile=".\jitrelease/"
|
||||
ProgramDataBaseFileName=".\jitrelease/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="..\jit\jits.obj ..\zlib\zlib.lib"
|
||||
OutputFile="jitrelease/amxmodx_mm.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||
ModuleDefinitionFile=""
|
||||
ProgramDatabaseFile=".\jitrelease/amxx_mm.pdb"
|
||||
ImportLibrary=".\jitrelease/amxx_mm.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\release/amxmodx.tlb"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="JITMemtestRelease|Win32"
|
||||
OutputDirectory="JITMemtestRelease"
|
||||
IntermediateDirectory="JITMemtestRelease"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
GlobalOptimizations="TRUE"
|
||||
InlineFunctionExpansion="1"
|
||||
FavorSizeOrSpeed="1"
|
||||
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;MEMORY_TEST;JIT"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="4"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="amxmodx.h"
|
||||
PrecompiledHeaderFile=".\jitmemtestrelease/amxmodx.pch"
|
||||
AssemblerListingLocation=".\jitmemtestrelease/"
|
||||
ObjectFile=".\jitmemtestrelease/"
|
||||
ProgramDataBaseFileName=".\jitmemtestrelease/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib ..\jit\jits.lib ..\zlib\zlib.lib"
|
||||
OutputFile="jitmemtestrelease/amxmodx_mm.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||
ModuleDefinitionFile=""
|
||||
ProgramDatabaseFile=".\jitmemtestrelease/amxx_mm.pdb"
|
||||
ImportLibrary=".\jitmemtestrelease/amxx_mm.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\release/amxmodx.tlb"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="MaximalSpeed|Win32"
|
||||
OutputDirectory="MaximalSpeed"
|
||||
IntermediateDirectory="MaximalSpeed"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
GlobalOptimizations="TRUE"
|
||||
InlineFunctionExpansion="1"
|
||||
EnableIntrinsicFunctions="TRUE"
|
||||
FavorSizeOrSpeed="1"
|
||||
OptimizeForProcessor="2"
|
||||
OptimizeForWindowsApplication="TRUE"
|
||||
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="4"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="amxmodx.h"
|
||||
PrecompiledHeaderFile=".\MaximalSpeed/amxmodx.pch"
|
||||
AssemblerListingLocation=".\MaximalSpeed/"
|
||||
ObjectFile=".\MaximalSpeed/"
|
||||
ProgramDataBaseFileName=".\MaximalSpeed/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib ..\jit\jits.lib ..\zlib\zlib.lib"
|
||||
OutputFile="MaximalSpeed/amxmodx_mm.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||
ModuleDefinitionFile=""
|
||||
ProgramDatabaseFile=".\MaximalSpeede/amxx_mm.pdb"
|
||||
ImportLibrary=".\jitrelease/amxx_mm.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\release/amxmodx.tlb"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
|
||||
<File
|
||||
RelativePath="..\amx.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxcore.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxmodx.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxtime.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxxfile.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxxlog.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CCmd.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CEvent.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CFile.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CForward.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CLang.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CLogEvent.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CMenu.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CMisc.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CModule.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CPlugin.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CTask.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CVault.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\emsg.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\fakemeta.cpp">
|
||||
<FileConfiguration
|
||||
Name="MemtestDebug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
GeneratePreprocessedFile="0"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\file.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\float.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\md5.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\meta_api.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\modules.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\power.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\srvcmd.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\string.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\strptime.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\util.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\vault.cpp">
|
||||
</File>
|
||||
<Filter
|
||||
Name="mmgr"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\mmgr\mmgr.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="JITDebug|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="JITRelease|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="MaximalSpeed|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl">
|
||||
<File
|
||||
RelativePath="..\amx.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxmodx.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxxfile.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxxlog.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CCmd.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CEvent.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CFile.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CForward.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CLang.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CList.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CLogEvent.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CMenu.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CMisc.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CModule.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CPlugin.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CQueue.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CRList.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CString.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CTask.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CVault.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CVector.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\fakemeta.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\md5.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\modules.h">
|
||||
</File>
|
||||
<Filter
|
||||
Name="mmgr"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\mmgr\mmgr.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\mmgr\nommgr.h">
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc">
|
||||
<File
|
||||
RelativePath="..\version.rc">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
39
amxmodx/msvc/amxmodx_mm.sln
Executable file
39
amxmodx/msvc/amxmodx_mm.sln
Executable file
@ -0,0 +1,39 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 8.00
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "amxmodx", "amxmodx_mm.vcproj", "{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
JITDebug = JITDebug
|
||||
JITMemtestRelease = JITMemtestRelease
|
||||
JITRelease = JITRelease
|
||||
MaximalSpeed = MaximalSpeed
|
||||
MemtestDebug = MemtestDebug
|
||||
MemtestRelease = MemtestRelease
|
||||
Release = Release
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfiguration) = postSolution
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Debug.ActiveCfg = Debug|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Debug.Build.0 = Debug|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug.ActiveCfg = JITDebug|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug.Build.0 = JITDebug|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITMemtestRelease.ActiveCfg = JITMemtestRelease|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITMemtestRelease.Build.0 = JITMemtestRelease|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease.ActiveCfg = JITRelease|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease.Build.0 = JITRelease|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MaximalSpeed.ActiveCfg = MaximalSpeed|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MaximalSpeed.Build.0 = MaximalSpeed|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestDebug.ActiveCfg = MemtestDebug|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestDebug.Build.0 = MemtestDebug|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestRelease.ActiveCfg = MemtestRelease|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestRelease.Build.0 = MemtestRelease|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Release.ActiveCfg = Release|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@ -255,7 +255,10 @@
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||
ModuleDefinitionFile=""
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile=".\memtestrelease/amxx_mm.pdb"
|
||||
GenerateMapFile="TRUE"
|
||||
MapExports="TRUE"
|
||||
ImportLibrary=".\memtestrelease/amxx_mm.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
@ -297,7 +300,7 @@
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""C:\Hry\Half-Life\SDK\Multiplayer Source\pm_shared";"C:\Hry\Half-Life\SDK\Multiplayer Source\dlls";"C:\Hry\Half-Life\SDK\Multiplayer Source\engine";"C:\Hry\Half-Life\SDK\Multiplayer Source\common";C:\Files\Programming\metamod\metamod"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="5"
|
||||
StructMemberAlignment="3"
|
||||
@ -316,12 +319,13 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib ..\jit\jits.lib ..\zlib\zlib.lib"
|
||||
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
|
||||
OutputFile="jitdebug/amxmodx_mm.dll"
|
||||
Version="0.1"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||
IgnoreDefaultLibraryNames="MSVCRT"
|
||||
ModuleDefinitionFile=""
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile=".\jitdebug/amxx_mm.pdb"
|
||||
@ -368,7 +372,8 @@
|
||||
InlineFunctionExpansion="1"
|
||||
FavorSizeOrSpeed="1"
|
||||
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32"
|
||||
IgnoreStandardIncludePath="FALSE"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="4"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
@ -386,13 +391,16 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="..\jit\jits.obj ..\zlib\zlib.lib"
|
||||
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
|
||||
OutputFile="jitrelease/amxmodx_mm.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||
IgnoreDefaultLibraryNames="MSVCRT"
|
||||
ModuleDefinitionFile=""
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile=".\jitrelease/amxx_mm.pdb"
|
||||
GenerateMapFile="FALSE"
|
||||
ImportLibrary=".\jitrelease/amxx_mm.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
@ -436,7 +444,7 @@
|
||||
InlineFunctionExpansion="1"
|
||||
FavorSizeOrSpeed="1"
|
||||
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;MEMORY_TEST;JIT"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;MEMORY_TEST;JIT;ASM32;PAWN_CELL_SIZE=32"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="4"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
@ -454,12 +462,13 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib ..\jit\jits.lib ..\zlib\zlib.lib"
|
||||
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj"
|
||||
OutputFile="jitmemtestrelease/amxmodx_mm.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||
ModuleDefinitionFile=""
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile=".\jitmemtestrelease/amxx_mm.pdb"
|
||||
ImportLibrary=".\jitmemtestrelease/amxx_mm.lib"/>
|
||||
<Tool
|
||||
@ -574,6 +583,9 @@
|
||||
<File
|
||||
RelativePath="..\amxcore.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxdbg.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxmodx.cpp">
|
||||
</File>
|
||||
@ -649,6 +661,12 @@
|
||||
<File
|
||||
RelativePath="..\modules.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\natives.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\newmenus.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\power.cpp">
|
||||
</File>
|
||||
@ -711,6 +729,9 @@
|
||||
<File
|
||||
RelativePath="..\amx.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxdbg.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxmodx.h">
|
||||
</File>
|
||||
@ -757,7 +778,7 @@
|
||||
RelativePath="..\CQueue.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CRList.h">
|
||||
RelativePath="..\CStack.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CString.h">
|
||||
@ -777,9 +798,27 @@
|
||||
<File
|
||||
RelativePath="..\md5.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\menus.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\modules.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\natives.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\newmenus.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\resource.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\zlib\zconf.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\zlib\zlib.h">
|
||||
</File>
|
||||
<Filter
|
||||
Name="mmgr"
|
||||
Filter="">
|
||||
|
91
amxmodx/natives-amd64.asm
Executable file
91
amxmodx/natives-amd64.asm
Executable file
@ -0,0 +1,91 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; (C)2005 by David "BAILOPAN" Anderson ;
|
||||
; register_native functions for amd64 ;;;;;;
|
||||
; Based on the concept by Julien "dJeyL" Laurent ;
|
||||
; Thanks to T(+)rget for pushing me to implement this ;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;;Licensed under the GNU General Public License, version 2
|
||||
;;This is a portion of AMX Mod X
|
||||
;; and is maintained by the AMX Mod X development team.
|
||||
|
||||
;;Initializes the global variable
|
||||
|
||||
BITS 64
|
||||
|
||||
section .text
|
||||
|
||||
global amxx_DynaInit, _amxx_DynaInit
|
||||
;void amxx_DynaInit(void *ptr);
|
||||
amxx_DynaInit:
|
||||
_amxx_DynaInit:
|
||||
mov [GLOBAL_GATE wrt rip], rdi
|
||||
ret
|
||||
|
||||
;;Assembles the gateway function
|
||||
global amxx_DynaMake, _amxx_DynaMake
|
||||
;int amxx_DynaMake(char *buffer, int id);
|
||||
amxx_DynaMake:
|
||||
_amxx_DynaMake:
|
||||
;we're not damaging the stack I think so we should be safe with no prologue
|
||||
|
||||
;save these two we're about to destroy them
|
||||
push rsi ;push id
|
||||
push rdi ;push buffer
|
||||
|
||||
mov rsi, _amxx_DynaFuncStart
|
||||
mov rcx, _amxx_DynaFuncEnd - _amxx_DynaFuncStart
|
||||
cld ;clear direction flag (just in case)
|
||||
rep movsb
|
||||
|
||||
pop rdi ;get buffer as destination
|
||||
pop rax ;get id
|
||||
;align us to mov rsi, 1234... - on x86-64 this is 2 bytes after the differential
|
||||
add rdi, (_amxx_DynaFuncStart.move-_amxx_DynaFuncStart) + 2
|
||||
mov [rdi], qword rax
|
||||
;align rdi to the call
|
||||
add rdi, (_amxx_DynaFuncStart.call-_amxx_DynaFuncStart.move)
|
||||
mov rax, qword [GLOBAL_GATE wrt rip]
|
||||
;copy the real address
|
||||
mov [rdi], rax
|
||||
|
||||
ret
|
||||
|
||||
;;The gateway function we will re-assemble
|
||||
;; This is similar to dJeyL's but a tad more elegant, as it's written in pure assembly
|
||||
;; and NASM > GAS :')
|
||||
global amxx_DynaFunc, _amxx_DynaFunc
|
||||
;int amxx_DynaFunc(AMX *amx, cell *params);
|
||||
amxx_DynaFunc:
|
||||
_amxx_DynaFunc:
|
||||
_amxx_DynaFuncStart:
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
|
||||
;we're given an amx and params... we're also hardcoded for this though:
|
||||
mov rdx, rsi ;move 2nd param to 3rd
|
||||
mov rsi, rdi ;move 1st param to 2nd
|
||||
;this old trick, we'll move in the real pointer in a bit.
|
||||
.move:
|
||||
mov rdi, qword 1234567812345678h
|
||||
.call:
|
||||
mov rcx, qword 1234567812345678h
|
||||
call rcx
|
||||
|
||||
pop rbp
|
||||
ret
|
||||
_amxx_DynaFuncEnd:
|
||||
|
||||
;;Just returns the buffer size required
|
||||
global _amxx_DynaCodesize, amxx_DynaCodesize
|
||||
;int amxx_DynaCodesize()
|
||||
amxx_DynaCodesize:
|
||||
_amxx_DynaCodesize:
|
||||
; on x86-64 this is 34 bytes
|
||||
mov rax, _amxx_DynaFuncEnd - _amxx_DynaFuncStart
|
||||
ret
|
||||
|
||||
section .data
|
||||
|
||||
GLOBAL_GATE DQ 0
|
||||
|
98
amxmodx/natives-x86.asm
Executable file
98
amxmodx/natives-x86.asm
Executable file
@ -0,0 +1,98 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; (C)2005 by David "BAILOPAN" Anderson ;
|
||||
; register_native functions for x86 ;;;;;;
|
||||
; Based on the concept by Julien "dJeyL" Laurent ;
|
||||
; Thanks to T(+)rget for pushing me to implement this ;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;;Licensed under the GNU General Public License, version 2
|
||||
;;This is a portion of AMX Mod X
|
||||
;; and is maintained by the AMX Mod X development team.
|
||||
|
||||
;;Initializes the global variable
|
||||
|
||||
section .text
|
||||
|
||||
global amxx_DynaInit, _amxx_DynaInit
|
||||
;void amxx_DynaInit(void *ptr);
|
||||
amxx_DynaInit:
|
||||
_amxx_DynaInit:
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
|
||||
mov eax, [ebp+8] ;get pointer
|
||||
mov [GLOBAL_GATE], eax ;store
|
||||
|
||||
mov eax, 1
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
;;Assembles the gateway function
|
||||
global amxx_DynaMake, _amxx_DynaMake
|
||||
;int amxx_DynaMake(char *buffer, int id);
|
||||
amxx_DynaMake:
|
||||
_amxx_DynaMake:
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
|
||||
push edi
|
||||
push esi
|
||||
|
||||
mov edi, [ebp+8] ;buffer
|
||||
mov esi, _amxx_DynaFuncStart
|
||||
mov ecx, _amxx_DynaFuncEnd - _amxx_DynaFuncStart
|
||||
cld ;clear direction flag (just in case)
|
||||
rep movsb
|
||||
|
||||
mov edi, [ebp+8] ;get buffer again
|
||||
;align us to mov eax, 1234 - on x86 this is 4 bytes
|
||||
add edi, (_amxx_DynaMoveOffset-_amxx_DynaFuncStart) + 1
|
||||
mov eax, [ebp+12]
|
||||
mov [edi], eax
|
||||
|
||||
pop esi
|
||||
pop edi
|
||||
|
||||
mov eax, 1
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
;;The gateway function we will re-assemble
|
||||
;; This is similar to dJeyL's but a tad more elegant, as it's written in pure assembly
|
||||
;; and NASM > GAS :')
|
||||
global amxx_DynaFunc, _amxx_DynaFunc
|
||||
;int amxx_DynaFunc(AMX *amx, cell *params);
|
||||
amxx_DynaFunc:
|
||||
_amxx_DynaFunc:
|
||||
_amxx_DynaFuncStart:
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
|
||||
;we're given an amx and params... we're also hardcoded for this though:
|
||||
_amxx_DynaMoveOffset:
|
||||
mov eax, 12345678h ;this old trick, we'll move in the real pointer in a bit.
|
||||
push dword [ebp+12] ;push params
|
||||
push dword [ebp+8] ;push amx
|
||||
push eax ;push the id
|
||||
call [GLOBAL_GATE] ;pass through teh global gateway.
|
||||
add esp, 12 ;reset stack oops
|
||||
|
||||
pop ebp
|
||||
ret
|
||||
_amxx_DynaFuncEnd:
|
||||
|
||||
;;Just returns the buffer size required
|
||||
global _amxx_DynaCodesize, amxx_DynaCodesize
|
||||
;int amxx_DynaCodesize()
|
||||
amxx_DynaCodesize:
|
||||
_amxx_DynaCodesize:
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
|
||||
; on x86 is this 17 bytes
|
||||
mov eax, _amxx_DynaFuncEnd - _amxx_DynaFuncStart
|
||||
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
GLOBAL_GATE DD 0
|
437
amxmodx/natives.cpp
Executable file
437
amxmodx/natives.cpp
Executable file
@ -0,0 +1,437 @@
|
||||
/* AMX Mod X
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
* originally developed by OLO
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
#include "amxmodx.h"
|
||||
#include <malloc.h>
|
||||
#include <stdlib.h>
|
||||
#include "CStack.h"
|
||||
#include "natives.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
//Written by David "BAILOPAN" Anderson
|
||||
//With the exception for param_convert, which was written by
|
||||
// Julien "dJeyL" Laurent
|
||||
|
||||
CVector<regnative *> g_RegNatives;
|
||||
CStack<regnative *> g_NativeStack;
|
||||
CVector<String> g_Libraries;
|
||||
static char g_errorStr[512] = {0};
|
||||
static int g_errorNum = 0;
|
||||
bool g_Initialized = false;
|
||||
|
||||
int amxx_DynaCallback(int idx, AMX *amx, cell *params)
|
||||
{
|
||||
if (idx < 0 || idx >= (int)g_RegNatives.size())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid dynamic native called");
|
||||
return 0;
|
||||
}
|
||||
|
||||
regnative *pNative = g_RegNatives[idx];
|
||||
int numParams = params[0] / sizeof(cell);
|
||||
|
||||
if (numParams > CALLFUNC_MAXPARAMS)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Called dynanative with too many parameters (%d)", CALLFUNC_MAXPARAMS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//parameter stack
|
||||
pNative->caller = amx;
|
||||
|
||||
CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(amx);
|
||||
|
||||
int err = 0;
|
||||
cell ret = 0;
|
||||
g_errorNum = 0;
|
||||
g_NativeStack.push(pNative);
|
||||
if (pNative->style == 0)
|
||||
{
|
||||
amx_Push(pNative->amx, numParams);
|
||||
amx_Push(pNative->amx, pPlugin->getId());
|
||||
for (int i=numParams; i>=1; i--)
|
||||
pNative->params[i] = params[i];
|
||||
} else if (pNative->style == 1) {
|
||||
//use dJeyL's system .. very clever!
|
||||
for (int i=numParams; i>=1; i--)
|
||||
amx_Push(pNative->amx, params[i]);
|
||||
}
|
||||
if ( (err=amx_Exec(pNative->amx, &ret, pNative->func)) != AMX_ERR_NONE)
|
||||
{
|
||||
g_NativeStack.pop();
|
||||
LogError(pNative->amx, err, "");
|
||||
return 0;
|
||||
}
|
||||
if (g_errorNum)
|
||||
{
|
||||
g_NativeStack.pop();
|
||||
LogError(amx, g_errorNum, g_errorStr);
|
||||
return ret;
|
||||
}
|
||||
g_NativeStack.pop();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
AMX_NATIVE_INFO *BuildNativeTable()
|
||||
{
|
||||
if (g_RegNatives.size() < 1)
|
||||
return NULL;
|
||||
|
||||
AMX_NATIVE_INFO *pNatives = new AMX_NATIVE_INFO[g_RegNatives.size() + 1];
|
||||
|
||||
AMX_NATIVE_INFO info;
|
||||
regnative *pNative;
|
||||
for (size_t i=0; i<g_RegNatives.size(); i++)
|
||||
{
|
||||
pNative = g_RegNatives[i];
|
||||
info.name = pNative->name.c_str();
|
||||
info.func = (AMX_NATIVE)((void *)(pNative->pfn));
|
||||
pNatives[i] = info;
|
||||
}
|
||||
pNatives[g_RegNatives.size()].name = NULL;
|
||||
pNatives[g_RegNatives.size()].func = NULL;
|
||||
|
||||
//this needs to be deleted
|
||||
return pNatives;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL log_error(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
char *err = format_amxstring(amx, params, 2, len);
|
||||
|
||||
_snprintf(g_errorStr, sizeof(g_errorStr), "%s", err);
|
||||
g_errorNum = params[1];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//get_string(param, dest[], len)
|
||||
static cell AMX_NATIVE_CALL get_string(AMX *amx, cell *params)
|
||||
{
|
||||
if (!g_NativeStack.size())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||
return 0;
|
||||
}
|
||||
regnative *pNative = g_NativeStack.top();
|
||||
if (pNative->style)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||
return 0;
|
||||
}
|
||||
int p = params[1];
|
||||
|
||||
int len;
|
||||
char *str = get_amxstring(pNative->caller, pNative->params[p], 0, len);
|
||||
return set_amxstring(amx, params[2], str, params[3]);
|
||||
}
|
||||
|
||||
//set_string(param, source[], maxlen)
|
||||
static cell AMX_NATIVE_CALL set_string(AMX *amx, cell *params)
|
||||
{
|
||||
if (!g_NativeStack.size())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||
return 0;
|
||||
}
|
||||
regnative *pNative = g_NativeStack.top();
|
||||
if (pNative->style)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||
return 0;
|
||||
}
|
||||
int p = params[1];
|
||||
|
||||
int len;
|
||||
char *str = get_amxstring(amx, params[2], 0, len);
|
||||
|
||||
return set_amxstring(pNative->caller, pNative->params[p], str, params[3]);
|
||||
}
|
||||
|
||||
//get a byvalue parameter
|
||||
//get_param(num)
|
||||
static cell AMX_NATIVE_CALL get_param(AMX *amx, cell *params)
|
||||
{
|
||||
if (!g_NativeStack.size())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||
return 0;
|
||||
}
|
||||
regnative *pNative = g_NativeStack.top();
|
||||
if (pNative->style)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||
return 0;
|
||||
}
|
||||
int p = params[1];
|
||||
|
||||
return pNative->params[p];
|
||||
}
|
||||
|
||||
//get_param_byref(num)
|
||||
static cell AMX_NATIVE_CALL get_param_byref(AMX *amx, cell *params)
|
||||
{
|
||||
if (!g_NativeStack.size())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||
return 0;
|
||||
}
|
||||
regnative *pNative = g_NativeStack.top();
|
||||
if (pNative->style)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||
return 0;
|
||||
}
|
||||
int p = params[1];
|
||||
|
||||
cell *addr = get_amxaddr(pNative->caller, pNative->params[p]);
|
||||
|
||||
return addr[0];
|
||||
}
|
||||
|
||||
//set_param_byref(num, val)
|
||||
static cell AMX_NATIVE_CALL set_param_byref(AMX *amx, cell *params)
|
||||
{
|
||||
if (!g_NativeStack.size())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||
return 0;
|
||||
}
|
||||
regnative *pNative = g_NativeStack.top();
|
||||
if (pNative->style)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||
return 0;
|
||||
}
|
||||
int p = params[1];
|
||||
|
||||
cell *addr = get_amxaddr(pNative->caller, pNative->params[p]);
|
||||
|
||||
addr[0] = params[2];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//get_array(param, dest[], size)
|
||||
static cell AMX_NATIVE_CALL get_array(AMX *amx, cell *params)
|
||||
{
|
||||
if (!g_NativeStack.size())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||
return 0;
|
||||
}
|
||||
regnative *pNative = g_NativeStack.top();
|
||||
if (pNative->style)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||
return 0;
|
||||
}
|
||||
int p = params[1];
|
||||
|
||||
cell *source = get_amxaddr(pNative->caller, pNative->params[p]);
|
||||
cell *dest = get_amxaddr(amx, params[2]);
|
||||
|
||||
int size = params[3];
|
||||
|
||||
while (size-->0)
|
||||
*dest = *source;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//set_array(param, source[], size)
|
||||
static cell AMX_NATIVE_CALL set_array(AMX *amx, cell *params)
|
||||
{
|
||||
if (!g_NativeStack.size())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||
return 0;
|
||||
}
|
||||
regnative *pNative = g_NativeStack.top();
|
||||
if (pNative->style)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||
return 0;
|
||||
}
|
||||
int p = params[1];
|
||||
|
||||
cell *dest = get_amxaddr(pNative->caller, pNative->params[p]);
|
||||
cell *source = get_amxaddr(amx, params[2]);
|
||||
|
||||
int size = params[3];
|
||||
|
||||
while (size-->0)
|
||||
*dest = *source;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//This is basically right from dJeyL's lib_convert function
|
||||
//This awesome hack modifies the stack frame to have an address offset
|
||||
// that will align to the other plugin's memory.
|
||||
//I've no idea how he thought of this, but it's great. No idea how well it works.
|
||||
static cell AMX_NATIVE_CALL param_convert(AMX *amx, cell *params)
|
||||
{
|
||||
if (!g_NativeStack.size())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||
return 0;
|
||||
}
|
||||
regnative *pNative = g_NativeStack.top();
|
||||
if (pNative->style != 1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||
return 0;
|
||||
}
|
||||
cell p = params[1];
|
||||
|
||||
AMX *caller = pNative->caller;
|
||||
|
||||
unsigned char *data =amx->base+(int)((AMX_HEADER *)amx->base)->dat;
|
||||
unsigned char *realdata = caller->base+(int)((AMX_HEADER *)caller->base)->dat;
|
||||
|
||||
* (cell *)(data+(int)amx->frm+(p+2)*sizeof(cell)) -= (cell)data-(cell)realdata;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL register_library(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
char *lib = get_amxstring(amx, params[1], 0, len);
|
||||
|
||||
AddPluginLibrary(lib);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//register_native(const name[], const handler[])
|
||||
static cell AMX_NATIVE_CALL register_native(AMX *amx, cell *params)
|
||||
{
|
||||
if (!g_Initialized)
|
||||
amxx_DynaInit((void *)(amxx_DynaCallback));
|
||||
|
||||
g_Initialized = true;
|
||||
|
||||
int len;
|
||||
char *name = get_amxstring(amx, params[1], 0, len);
|
||||
char *func = get_amxstring(amx, params[2], 1, len);
|
||||
|
||||
int idx, err;
|
||||
if ( (err=amx_FindPublic(amx, func, &idx)) != AMX_ERR_NONE)
|
||||
{
|
||||
LogError(amx, err, "Function \"%s\" was not found", func);
|
||||
return 0;
|
||||
}
|
||||
|
||||
regnative *pNative = new regnative;
|
||||
pNative->amx = amx;
|
||||
pNative->func = idx;
|
||||
|
||||
//we'll apply a safety buffer too
|
||||
//make our function
|
||||
int size = amxx_DynaCodesize();
|
||||
#ifndef __linux__
|
||||
DWORD temp;
|
||||
pNative->pfn = new char[size + 10];
|
||||
VirtualProtect(pNative->pfn, size+10, PAGE_EXECUTE_READWRITE, &temp);
|
||||
#else
|
||||
pNative->pfn = (char *)memalign(sysconf(_SC_PAGESIZE), size+10);
|
||||
mprotect((void *)pNative->pfn, size+10, PROT_READ|PROT_WRITE|PROT_EXEC);
|
||||
#endif
|
||||
|
||||
int id = (int)g_RegNatives.size();
|
||||
|
||||
amxx_DynaMake(pNative->pfn, id);
|
||||
pNative->func = idx;
|
||||
pNative->style = params[3];
|
||||
|
||||
g_RegNatives.push_back(pNative);
|
||||
|
||||
pNative->name.assign(name);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool LibraryExists(const char *name)
|
||||
{
|
||||
for (size_t i=0; i<g_Libraries.size(); i++)
|
||||
{
|
||||
if (stricmp(g_Libraries[i].c_str(), name)==0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void AddPluginLibrary(const char *name)
|
||||
{
|
||||
String f(name);
|
||||
g_Libraries.push_back(f);
|
||||
}
|
||||
|
||||
void ClearPluginLibraries()
|
||||
{
|
||||
g_Libraries.clear();
|
||||
|
||||
for (size_t i=0; i<g_RegNatives.size(); i++)
|
||||
{
|
||||
delete g_RegNatives[i]->pfn;
|
||||
delete g_RegNatives[i];
|
||||
}
|
||||
g_RegNatives.clear();
|
||||
}
|
||||
|
||||
AMX_NATIVE_INFO g_NativeNatives[] = {
|
||||
{"register_native", register_native},
|
||||
{"log_error", log_error},
|
||||
{"register_library",register_library},
|
||||
{"get_string", get_string},
|
||||
{"set_string", set_string},
|
||||
{"get_param", get_param},
|
||||
{"get_param_byref", get_param_byref},
|
||||
{"set_param_byref", set_param_byref},
|
||||
{"get_array", set_array},
|
||||
{"set_array", set_array},
|
||||
//these are dummy functions for floats ;p
|
||||
{"get_param_f", get_param},
|
||||
{"get_float_byref", get_param_byref},
|
||||
{"set_float_byref", set_param_byref},
|
||||
{"get_array_f", get_array},
|
||||
{"set_array_f", set_array},
|
||||
{"param_convert", param_convert},
|
||||
//////////////////////////
|
||||
{NULL, NULL},
|
||||
};
|
69
amxmodx/natives.h
Executable file
69
amxmodx/natives.h
Executable file
@ -0,0 +1,69 @@
|
||||
/* AMX Mod X
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
* originally developed by OLO
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_NATIVES_H
|
||||
#define _INCLUDE_NATIVES_H
|
||||
|
||||
//only 16 for now sorry
|
||||
#define CALLFUNC_MAXPARAMS 16
|
||||
|
||||
#define CALLFUNC_FLAG_BYREF 1
|
||||
#define CALLFUNC_FLAG_BYREF_REUSED 2
|
||||
|
||||
#define N_CELL 1
|
||||
#define N_ARRAY 2
|
||||
#define N_BYREF 3
|
||||
#define N_VARARG 4
|
||||
|
||||
struct regnative
|
||||
{
|
||||
AMX *amx;
|
||||
String name;
|
||||
char *pfn;
|
||||
int func;
|
||||
AMX *caller;
|
||||
int style;
|
||||
cell params[CALLFUNC_MAXPARAMS];
|
||||
};
|
||||
|
||||
extern "C" void amxx_DynaInit(void *ptr);
|
||||
extern "C" void amxx_DynaMake(char *buffer, int id);
|
||||
extern "C" int amxx_DynaFunc(AMX *amx, cell *params);
|
||||
extern "C" int amxx_DynaCodesize();
|
||||
|
||||
AMX_NATIVE_INFO *BuildNativeTable();
|
||||
void AddPluginLibrary(const char *name);
|
||||
void ClearPluginLibraries();
|
||||
bool LibraryExists(const char *name);
|
||||
|
||||
//I couldn't resist :)
|
||||
extern AMX_NATIVE_INFO g_NativeNatives[];
|
||||
|
||||
#endif //_INCLUDE_NATIVES_H
|
377
amxmodx/newmenus.cpp
Executable file
377
amxmodx/newmenus.cpp
Executable file
@ -0,0 +1,377 @@
|
||||
#include "amxmodx.h"
|
||||
#include "newmenus.h"
|
||||
|
||||
CVector<Menu *> g_NewMenus;
|
||||
|
||||
void ClearMenus()
|
||||
{
|
||||
for (size_t i=0; i<g_NewMenus.size(); i++)
|
||||
delete g_NewMenus[i];
|
||||
g_NewMenus.clear();
|
||||
}
|
||||
|
||||
Menu::Menu(const char *title, int mid, int tid)
|
||||
{
|
||||
m_Title.assign(title);
|
||||
menuId = mid;
|
||||
thisId = tid;
|
||||
}
|
||||
|
||||
Menu::~Menu()
|
||||
{
|
||||
for (size_t i=0; i<m_Items.size(); i++)
|
||||
delete m_Items[i];
|
||||
m_Items.clear();
|
||||
}
|
||||
|
||||
menuitem *Menu::AddItem(const char *name, const char *cmd, int access)
|
||||
{
|
||||
menuitem *pItem = new menuitem;
|
||||
|
||||
pItem->name.assign(name);
|
||||
pItem->cmd.assign(cmd);
|
||||
pItem->access = access;
|
||||
pItem->id = m_Items.size();
|
||||
pItem->handler = -1;
|
||||
pItem->pfn = NULL;
|
||||
|
||||
m_Items.push_back(pItem);
|
||||
|
||||
return pItem;
|
||||
}
|
||||
|
||||
menuitem *Menu::GetMenuItem(item_t item)
|
||||
{
|
||||
if (item >= m_Items.size())
|
||||
return NULL;
|
||||
|
||||
return m_Items[item];
|
||||
}
|
||||
|
||||
size_t Menu::GetItemCount()
|
||||
{
|
||||
return m_Items.size();
|
||||
}
|
||||
|
||||
size_t Menu::GetPageCount()
|
||||
{
|
||||
size_t items = GetItemCount();
|
||||
page_t numPages = (items / MENUITEMS) + 1;
|
||||
|
||||
if (!items)
|
||||
return 0;
|
||||
|
||||
if (numPages % MENUITEMS == 0)
|
||||
numPages--;
|
||||
|
||||
return numPages;
|
||||
}
|
||||
|
||||
int Menu::PagekeyToItem(page_t page, item_t key)
|
||||
{
|
||||
page_t pages = GetPageCount();
|
||||
item_t numItems = GetItemCount();
|
||||
|
||||
if (page >= pages)
|
||||
return MENU_EXIT;
|
||||
|
||||
item_t start = page * 7;
|
||||
|
||||
if (page == 0)
|
||||
{
|
||||
item_t rem = numItems >= 7 ? 7 : numItems;
|
||||
if (key == rem)
|
||||
{
|
||||
if (pages > 1)
|
||||
return MENU_MORE;
|
||||
else
|
||||
return MENU_EXIT;
|
||||
} else if (key == rem+1) {
|
||||
return MENU_EXIT;
|
||||
}
|
||||
} else if (page == pages - 1) {
|
||||
//find number of remaining items
|
||||
//for example, 11 items on page 1... means start=7, 11-7=4
|
||||
item_t rem = numItems - start;
|
||||
//however, the last item is actually this -1, so...
|
||||
if (key == rem)
|
||||
{
|
||||
return MENU_EXIT;
|
||||
} else if (key == rem+1) {
|
||||
return MENU_BACK;
|
||||
}
|
||||
} else {
|
||||
if (key == 7)
|
||||
{
|
||||
return MENU_MORE;
|
||||
} else if (key == 8) {
|
||||
return MENU_BACK;
|
||||
}
|
||||
}
|
||||
|
||||
return (start + key);
|
||||
}
|
||||
|
||||
bool Menu::Display(int player, page_t page)
|
||||
{
|
||||
int keys = 0;
|
||||
const char *str = GetTextString(player, page, keys);
|
||||
|
||||
if (!str)
|
||||
return false;
|
||||
|
||||
static char buffer[2048];
|
||||
int len = _snprintf(buffer, sizeof(buffer)-1, "%s", str);
|
||||
|
||||
CPlayer *pPlayer = GET_PLAYER_POINTER_I(player);
|
||||
|
||||
pPlayer->keys = keys;
|
||||
pPlayer->menu = menuId;
|
||||
pPlayer->newmenu = thisId;
|
||||
pPlayer->page = (int)page;
|
||||
|
||||
UTIL_ShowMenu(pPlayer->pEdict, keys, -1, buffer, len);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *Menu::GetTextString(int player, page_t page, int &keys)
|
||||
{
|
||||
page_t pages = GetPageCount();
|
||||
item_t numItems = GetItemCount();
|
||||
|
||||
if (page >= pages)
|
||||
return NULL;
|
||||
|
||||
m_Text.clear();
|
||||
|
||||
char buffer[255];
|
||||
if (g_coloredmenus)
|
||||
_snprintf(buffer, sizeof(buffer)-1, "\\y%s %d/%d\n\\w\n", m_Title.c_str(), page+1, pages);
|
||||
else
|
||||
_snprintf(buffer, sizeof(buffer)-1, "%s %d/%d\n\n", m_Title.c_str(), page+1, pages);
|
||||
m_Text.append(buffer);
|
||||
|
||||
item_t start = page * 7;
|
||||
item_t end = 0;
|
||||
if (start + 7 <= numItems)
|
||||
{
|
||||
end = start + 7;
|
||||
} else {
|
||||
end = numItems;
|
||||
}
|
||||
|
||||
menuitem *pItem = NULL;
|
||||
int option = 0;
|
||||
keys = 0;
|
||||
bool enabled = true;
|
||||
int ret = 0;
|
||||
for (item_t i=start; i<end; i++)
|
||||
{
|
||||
pItem = m_Items[i];
|
||||
if (pItem->access && !(pItem->access & g_players[player].flags[0]))
|
||||
enabled = false;
|
||||
if (pItem->handler != -1)
|
||||
{
|
||||
ret = executeForwards(pItem->handler, player, thisId, i);
|
||||
if (ret == ITEM_ENABLED)
|
||||
enabled = true;
|
||||
else if (ret == ITEM_DISABLED)
|
||||
enabled = false;
|
||||
}
|
||||
if (pItem->pfn)
|
||||
{
|
||||
ret = (pItem->pfn)(player, thisId, i);
|
||||
if (ret == ITEM_ENABLED)
|
||||
enabled = true;
|
||||
else if (ret == ITEM_DISABLED)
|
||||
enabled = false;
|
||||
}
|
||||
if (enabled)
|
||||
{
|
||||
keys |= (1<<option);
|
||||
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", ++option, pItem->name.c_str());
|
||||
} else {
|
||||
if (g_coloredmenus)
|
||||
{
|
||||
_snprintf(buffer, sizeof(buffer)-1, "\\d%d. %s\n\\w", ++option, pItem->name.c_str());
|
||||
} else {
|
||||
_snprintf(buffer, sizeof(buffer)-1, "#. %s\n", pItem->name.c_str());
|
||||
option++;
|
||||
}
|
||||
}
|
||||
m_Text.append(buffer);
|
||||
}
|
||||
//now for a weird part >:o
|
||||
//this will either be MORE or BACK..
|
||||
keys |= (1<<option++);
|
||||
if ((page < pages - 1) && (pages > 1))
|
||||
{
|
||||
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "More");
|
||||
} else {
|
||||
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "Exit");
|
||||
}
|
||||
m_Text.append(buffer);
|
||||
if (pages > 1)
|
||||
{
|
||||
keys |= (1<<option++);
|
||||
if (pages == 0)
|
||||
{
|
||||
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "Exit");
|
||||
} else {
|
||||
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "Back");
|
||||
}
|
||||
m_Text.append(buffer);
|
||||
}
|
||||
|
||||
return m_Text.c_str();
|
||||
}
|
||||
|
||||
#define GETMENU(p) if (p >= (int)g_NewMenus.size() || p < 0) { \
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid menu id %d", p); \
|
||||
return 0; } \
|
||||
Menu *pMenu = g_NewMenus[p];
|
||||
|
||||
//Makes a new menu handle (-1 for failure)
|
||||
//native csdm_makemenu(title[]);
|
||||
static cell AMX_NATIVE_CALL menu_create(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
char *title = get_amxstring(amx, params[1], 0, len);
|
||||
char *handler = get_amxstring(amx, params[2], 1, len);
|
||||
|
||||
int func = registerSPForwardByName(amx, handler, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||
if (func == -1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NOTFOUND, "Invalid function \"%s\"", handler);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int id = g_menucmds.registerMenuId(title, amx);
|
||||
g_menucmds.registerMenuCmd( g_plugins.findPluginFast(amx), id, 1023, func );
|
||||
|
||||
Menu *pMenu = new Menu(title, id, (int)g_NewMenus.size());
|
||||
g_NewMenus.push_back(pMenu);
|
||||
|
||||
return (int)g_NewMenus.size() - 1;
|
||||
}
|
||||
|
||||
//Adds an item to the menu (returns current item count - 1)
|
||||
//native menu_additem(menu, const name[], const command[]="", access=0);
|
||||
static cell AMX_NATIVE_CALL menu_additem(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
char *name, *cmd;
|
||||
int access;
|
||||
|
||||
GETMENU(params[1]);
|
||||
|
||||
name = get_amxstring(amx, params[2], 0, len);
|
||||
cmd = get_amxstring(amx, params[3], 1, len);
|
||||
access = params[4];
|
||||
|
||||
menuitem *pItem = pMenu->AddItem(name, cmd, access);
|
||||
|
||||
pItem->handler = params[5];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//Returns the number of pages in a menu
|
||||
//native csdm_menu_pages(menu);
|
||||
static cell AMX_NATIVE_CALL menu_pages(AMX *amx, cell *params)
|
||||
{
|
||||
GETMENU(params[1]);
|
||||
return pMenu->GetPageCount();
|
||||
}
|
||||
|
||||
//Returns the number of items in a menu
|
||||
//native csdm_menu_items(menu);
|
||||
static cell AMX_NATIVE_CALL menu_items(AMX *amx, cell *params)
|
||||
{
|
||||
GETMENU(params[1]);
|
||||
|
||||
return pMenu->GetItemCount();
|
||||
}
|
||||
|
||||
//Builds the menu string for a specific page (set title to 0 to not include title)
|
||||
//page indices start at 0!
|
||||
static cell AMX_NATIVE_CALL menu_display(AMX *amx, cell *params)
|
||||
{
|
||||
GETMENU(params[2]);
|
||||
|
||||
int player = params[1];
|
||||
int page = params[3];
|
||||
|
||||
return pMenu->Display(player, page);
|
||||
}
|
||||
|
||||
//Finds the id of a menu item for a specific page and key value.
|
||||
//Note that key should be from 0-6, as it only displays 7 per page.
|
||||
//page indices start at 0
|
||||
//native menu_keyid(menu, page, key);
|
||||
static cell AMX_NATIVE_CALL menu_find_id(AMX *amx, cell *params)
|
||||
{
|
||||
GETMENU(params[1]);
|
||||
|
||||
page_t page = static_cast<page_t>(params[2]);
|
||||
item_t key = static_cast<item_t>(params[3]);
|
||||
|
||||
return pMenu->PagekeyToItem(page, key);
|
||||
}
|
||||
|
||||
//Gets info about a menu option
|
||||
//native menu_item_getinfo(menu, item, &access, command[], cmdlen, name[]="", namelen=0, &callback);
|
||||
static cell AMX_NATIVE_CALL menu_item_getinfo(AMX *amx, cell *params)
|
||||
{
|
||||
GETMENU(params[1]);
|
||||
|
||||
menuitem *pItem = pMenu->GetMenuItem(static_cast<item_t>(params[2]));
|
||||
|
||||
if (!pItem)
|
||||
return 0;
|
||||
|
||||
cell *addr = get_amxaddr(amx, params[3]);
|
||||
addr[0] = pItem->access;
|
||||
|
||||
set_amxstring(amx, params[4], pItem->cmd.c_str(), params[5]);
|
||||
set_amxstring(amx, params[6], pItem->name.c_str(), params[7]);
|
||||
|
||||
if (params[8])
|
||||
{
|
||||
addr = get_amxaddr(amx, params[8]);
|
||||
if (addr)
|
||||
addr[0] = pItem->handler;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL menu_makecallback(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
char *name = get_amxstring(amx, params[1], 0, len);
|
||||
|
||||
int id = registerSPForwardByName(amx, name, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||
|
||||
if (id == -1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NOTFOUND, "Invalid function %s", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
AMX_NATIVE_INFO g_NewMenuNatives[] =
|
||||
{
|
||||
{"menu_create", menu_create},
|
||||
{"menu_additem", menu_additem},
|
||||
{"menu_pages", menu_pages},
|
||||
{"menu_items", menu_items},
|
||||
{"menu_display", menu_display},
|
||||
{"menu_find_id", menu_find_id},
|
||||
{"menu_item_getinfo", menu_item_getinfo},
|
||||
{"menu_makecallback", menu_makecallback},
|
||||
{NULL, NULL},
|
||||
};
|
68
amxmodx/newmenus.h
Executable file
68
amxmodx/newmenus.h
Executable file
@ -0,0 +1,68 @@
|
||||
#ifndef _INCLUDE_NEWMENUS_H
|
||||
#define _INCLUDE_NEWMENUS_H
|
||||
|
||||
#define MENU_EXIT -3
|
||||
#define MENU_BACK -2
|
||||
#define MENU_MORE -1
|
||||
#define ITEM_IGNORE 0
|
||||
#define ITEM_ENABLED 1
|
||||
#define ITEM_DISABLED 2
|
||||
|
||||
#define MENUITEMS 7
|
||||
|
||||
typedef int (*MENUITEM_CALLBACK)(int, int, int);
|
||||
|
||||
struct menuitem
|
||||
{
|
||||
String name;
|
||||
String cmd;
|
||||
int access;
|
||||
int handler;
|
||||
MENUITEM_CALLBACK pfn;
|
||||
size_t id;
|
||||
};
|
||||
|
||||
typedef unsigned int menu_t;
|
||||
typedef unsigned int item_t;
|
||||
typedef unsigned int page_t;
|
||||
|
||||
class Menu
|
||||
{
|
||||
public:
|
||||
Menu(const char *title, int menuId, int thisId);
|
||||
~Menu();
|
||||
menuitem *GetMenuItem(item_t item);
|
||||
size_t GetPageCount();
|
||||
size_t GetItemCount();
|
||||
menuitem *AddItem(const char *name, const char *cmd, int access);
|
||||
const char *GetTextString(int player, page_t page, int &keys);
|
||||
bool Display(int player, page_t page);
|
||||
int PagekeyToItem(page_t page, item_t key);
|
||||
int GetMenuMenuid();
|
||||
private:
|
||||
CVector<menuitem * > m_Items;
|
||||
String m_Title;
|
||||
String m_Text;
|
||||
int menuId;
|
||||
int thisId;
|
||||
};
|
||||
|
||||
/*Menu *CreateMenu(const char *title);
|
||||
Menu *GetMenuById(menu_t menu);
|
||||
menuitem *GetMenuItem(menu_t menu, item_t item);
|
||||
size_t GetMenuPages(menu_t menu);
|
||||
size_t GetMenuItems(menu_t menu);
|
||||
menuitem *AddMenuItem(menu_t menu, const char *name, const char *cmd, int access);
|
||||
bool DisplayMenu(menu_t menu, int player, page_t page);
|
||||
int MenuPagekeyToItem(menu_t menu, page_t page, int key);
|
||||
int FindByMenuid(int menuid);
|
||||
int GetMenuMenuid(menu_t menu);
|
||||
const char *GetItemName(menu_t menu, item_t item);
|
||||
const char *GetItemCmd(menu_t menu, item_t item);*/
|
||||
|
||||
void ClearMenus();
|
||||
|
||||
extern CVector<Menu *> g_NewMenus;
|
||||
extern AMX_NATIVE_INFO g_NewMenuNatives[];
|
||||
|
||||
#endif //_INCLUDE_NEWMENUS_H
|
@ -6,6 +6,7 @@
|
||||
* This file may be freely used. No warranties of any kind.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
// this file does not include amxmodx.h, so we have to include the memory manager here
|
||||
#ifdef MEMORY_TEST
|
||||
#include "mmgr/mmgr.h"
|
||||
|
@ -20,6 +20,13 @@
|
||||
#define stricmp(a,b) strcasecmp(a,b)
|
||||
#define strnicmp(a,b,c) strncasecmp(a,b,c)
|
||||
|
||||
#if defined __linux__ && !defined _snprintf
|
||||
#define _snprintf snprintf
|
||||
#endif
|
||||
#if defined __linux__ && !defined _vsnprintf
|
||||
//#define _vsnprintf vsnprintf
|
||||
#endif
|
||||
|
||||
/*
|
||||
* WinWorld wants '\'. Unices do not.
|
||||
*/
|
||||
|
@ -45,6 +45,16 @@
|
||||
enginefuncs_t g_engfuncs;
|
||||
globalvars_t *gpGlobals;
|
||||
|
||||
|
||||
|
||||
DLL_FUNCTIONS *g_pFunctionTable;
|
||||
DLL_FUNCTIONS *g_pFunctionTable_Post;
|
||||
enginefuncs_t *g_pengfuncsTable;
|
||||
enginefuncs_t *g_pengfuncsTable_Post;
|
||||
NEW_DLL_FUNCTIONS *g_pNewFunctionsTable;
|
||||
NEW_DLL_FUNCTIONS *g_pNewFunctionsTable_Post;
|
||||
|
||||
|
||||
// GetEntityAPI2 functions
|
||||
static DLL_FUNCTIONS g_EntityAPI_Table =
|
||||
{
|
||||
@ -2114,6 +2124,7 @@ C_DLLEXPORT int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersi
|
||||
return(FALSE);
|
||||
}
|
||||
memcpy(pFunctionTable, &g_EntityAPI_Table, sizeof(DLL_FUNCTIONS));
|
||||
g_pFunctionTable=pFunctionTable;
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
@ -2131,7 +2142,7 @@ C_DLLEXPORT int GetEntityAPI2_Post(DLL_FUNCTIONS *pFunctionTable, int *interface
|
||||
return(FALSE);
|
||||
}
|
||||
memcpy( pFunctionTable, &g_EntityAPI_Post_Table, sizeof( DLL_FUNCTIONS ) );
|
||||
|
||||
g_pFunctionTable_Post=pFunctionTable;
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
@ -2154,6 +2165,7 @@ C_DLLEXPORT int GetEngineFunctions(enginefuncs_t *pengfuncsFromEngine, int *inte
|
||||
return(FALSE);
|
||||
}
|
||||
memcpy(pengfuncsFromEngine, &g_EngineFuncs_Table, sizeof(enginefuncs_t));
|
||||
g_pengfuncsTable=pengfuncsFromEngine;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -2171,6 +2183,7 @@ C_DLLEXPORT int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int
|
||||
return(FALSE);
|
||||
}
|
||||
memcpy(pengfuncsFromEngine, &g_EngineFuncs_Post_Table, sizeof(enginefuncs_t));
|
||||
g_pengfuncsTable_Post=pengfuncsFromEngine;
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
@ -2195,6 +2208,7 @@ C_DLLEXPORT int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable,
|
||||
return(FALSE);
|
||||
}
|
||||
memcpy(pNewFunctionTable, &g_NewFuncs_Table, sizeof(NEW_DLL_FUNCTIONS));
|
||||
g_pNewFunctionsTable=pNewFunctionTable;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -2212,6 +2226,7 @@ C_DLLEXPORT int GetNewDLLFunctions_Post( NEW_DLL_FUNCTIONS *pNewFunctionTable, i
|
||||
return(FALSE);
|
||||
}
|
||||
memcpy(pNewFunctionTable, &g_NewFuncs_Post_Table, sizeof(NEW_DLL_FUNCTIONS));
|
||||
g_pNewFunctionsTable_Post=pNewFunctionTable;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -2406,9 +2421,6 @@ C_DLLEXPORT void __stdcall GiveFnptrsToDll( enginefuncs_t* pengfuncsFromEngine,
|
||||
|
||||
/************* AMXX Stuff *************/
|
||||
|
||||
// *** Types ***
|
||||
typedef void* (*PFN_REQ_FNPTR)(const char * /*name*/);
|
||||
|
||||
// *** Globals ***
|
||||
// Module info
|
||||
static amxx_module_info_s g_ModuleInfo =
|
||||
@ -2417,15 +2429,17 @@ static amxx_module_info_s g_ModuleInfo =
|
||||
MODULE_AUTHOR,
|
||||
MODULE_VERSION,
|
||||
#ifdef MODULE_RELOAD_ON_MAPCHANGE
|
||||
1
|
||||
1,
|
||||
#else // MODULE_RELOAD_ON_MAPCHANGE
|
||||
0
|
||||
0,
|
||||
#endif // MODULE_RELOAD_ON_MAPCHANGE
|
||||
MODULE_LOGTAG
|
||||
};
|
||||
|
||||
// Storage for the requested functions
|
||||
PFN_ADD_NATIVES g_fn_AddNatives;
|
||||
PFN_BUILD_PATHNAME g_fn_BuildPathname;
|
||||
PFN_BUILD_PATHNAME_R g_fn_BuildPathnameR;
|
||||
PFN_GET_AMXADDR g_fn_GetAmxAddr;
|
||||
PFN_PRINT_SRVCONSOLE g_fn_PrintSrvConsole;
|
||||
PFN_GET_MODNAME g_fn_GetModname;
|
||||
@ -2439,7 +2453,7 @@ PFN_GET_AMXSTRINGLEN g_fn_GetAmxStringLen;
|
||||
PFN_FORMAT_AMXSTRING g_fn_FormatAmxString;
|
||||
PFN_COPY_AMXMEMORY g_fn_CopyAmxMemory;
|
||||
PFN_LOG g_fn_Log;
|
||||
PFN_LOG_ERROR g_fn_LogError;
|
||||
PFN_LOG_ERROR g_fn_LogErrorFunc;
|
||||
PFN_RAISE_AMXERROR g_fn_RaiseAmxError;
|
||||
PFN_REGISTER_FORWARD g_fn_RegisterForward;
|
||||
PFN_EXECUTE_FORWARD g_fn_ExecuteForward;
|
||||
@ -2486,6 +2500,9 @@ PFN_AMX_FINDNATIVE g_fn_AmxFindNative;
|
||||
PFN_GETPLAYERFLAGS g_fn_GetPlayerFlags;
|
||||
PFN_GET_PLAYER_EDICT g_fn_GetPlayerEdict;
|
||||
PFN_FORMAT g_fn_Format;
|
||||
PFN_REGISTERFUNCTION g_fn_RegisterFunction;
|
||||
PFN_REQ_FNPTR g_fn_RequestFunction;
|
||||
PFN_AMX_PUSH g_fn_AmxPush;
|
||||
|
||||
// *** Exports ***
|
||||
C_DLLEXPORT int AMXX_Query(int *interfaceVersion, amxx_module_info_s *moduleInfo)
|
||||
@ -2523,15 +2540,19 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
|
||||
if (!reqFnptrFunc)
|
||||
return AMXX_PARAM;
|
||||
|
||||
g_fn_RequestFunction = reqFnptrFunc;
|
||||
|
||||
// Req all known functions
|
||||
// Misc
|
||||
REQFUNC("BuildPathname", g_fn_BuildPathname, PFN_BUILD_PATHNAME);
|
||||
REQFUNC("BuildPathnameR", g_fn_BuildPathnameR, PFN_BUILD_PATHNAME_R);
|
||||
REQFUNC("PrintSrvConsole", g_fn_PrintSrvConsole, PFN_PRINT_SRVCONSOLE);
|
||||
REQFUNC("GetModname", g_fn_GetModname, PFN_GET_MODNAME);
|
||||
REQFUNC("Log", g_fn_Log, PFN_LOG);
|
||||
REQFUNC("LogError", g_fn_LogError, PFN_LOG_ERROR);
|
||||
REQFUNC("LogError", g_fn_LogErrorFunc, PFN_LOG_ERROR);
|
||||
REQFUNC("MergeDefinitionFile", g_fn_MergeDefinition_File, PFN_MERGEDEFINITION_FILE);
|
||||
REQFUNC("Format", g_fn_Format, PFN_FORMAT);
|
||||
REQFUNC("RegisterFunction", g_fn_RegisterFunction, PFN_REGISTERFUNCTION);
|
||||
|
||||
// Amx scripts
|
||||
REQFUNC("GetAmxScript", g_fn_GetAmxScript, PFN_GET_AMXSCRIPT);
|
||||
@ -2590,6 +2611,7 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
|
||||
REQFUNC("GetPlayerHealth", g_fn_GetPlayerHealth, PFN_GET_PLAYER_HEALTH);
|
||||
REQFUNC("GetPlayerFlags", g_fn_GetPlayerFlags, PFN_GETPLAYERFLAGS);
|
||||
REQFUNC("GetPlayerEdict", g_fn_GetPlayerEdict, PFN_GET_PLAYER_EDICT);
|
||||
REQFUNC("amx_Push", g_fn_AmxPush, PFN_AMX_PUSH);
|
||||
|
||||
// Memory
|
||||
REQFUNC_OPT("Allocator", g_fn_Allocator, PFN_ALLOCATOR);
|
||||
@ -2633,7 +2655,19 @@ void MF_Log(const char *fmt, ...)
|
||||
vsprintf(msg, fmt, arglst);
|
||||
va_end(arglst);
|
||||
|
||||
g_fn_Log("[%s] %s", MODULE_NAME, msg);
|
||||
g_fn_Log("[%s] %s", MODULE_LOGTAG, msg);
|
||||
}
|
||||
|
||||
void MF_LogError(AMX *amx, int err, const char *fmt, ...)
|
||||
{
|
||||
// :TODO: Overflow possible here
|
||||
char msg[3072];
|
||||
va_list arglst;
|
||||
va_start(arglst, fmt);
|
||||
vsprintf(msg, fmt, arglst);
|
||||
va_end(arglst);
|
||||
|
||||
g_fn_LogErrorFunc(amx, err, "[%s] %s", MODULE_LOGTAG, msg);
|
||||
}
|
||||
|
||||
|
||||
@ -2643,6 +2677,7 @@ void MF_Log(const char *fmt, ...)
|
||||
void ValidateMacros_DontCallThis_Smiley()
|
||||
{
|
||||
MF_BuildPathname("str", "str", 0);
|
||||
MF_BuildPathnameR(NULL, 0, "%d", 0);
|
||||
MF_FormatAmxString(NULL, 0, 0, NULL);
|
||||
MF_GetAmxAddr(NULL, 0);
|
||||
MF_PrintSrvConsole("str", "str", 0);
|
||||
@ -2684,7 +2719,7 @@ void ValidateMacros_DontCallThis_Smiley()
|
||||
MF_IsPlayerHLTV(0);
|
||||
MF_GetPlayerArmor(0);
|
||||
MF_GetPlayerHealth(0);
|
||||
MF_AmxExec(0, 0, 0, 0);
|
||||
MF_AmxExec(0, 0, 0);
|
||||
MF_AmxExecv(0, 0, 0, 0, 0);
|
||||
MF_AmxFindPublic(0, 0, 0);
|
||||
MF_AmxAllot(0, 0, 0, 0);
|
||||
@ -2696,6 +2731,7 @@ void ValidateMacros_DontCallThis_Smiley()
|
||||
MF_GetPlayerFrags(0);
|
||||
MF_GetPlayerEdict(0);
|
||||
MF_Format("", 4, "str");
|
||||
MF_RegisterFunction(NULL, "");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -31,8 +31,10 @@
|
||||
|
||||
// ***** AMXX stuff *****
|
||||
|
||||
// module interface version is 1
|
||||
#define AMXX_INTERFACE_VERSION 1
|
||||
// module interface version was 1
|
||||
// 2 - added logtag to struct (amxx1.1-rc1)
|
||||
// 3 - added new tagAMX structure (amxx1.5)
|
||||
#define AMXX_INTERFACE_VERSION 3
|
||||
|
||||
// amxx module info
|
||||
struct amxx_module_info_s
|
||||
@ -41,6 +43,7 @@ struct amxx_module_info_s
|
||||
const char *author;
|
||||
const char *version;
|
||||
int reload; // reload on mapchange when nonzero
|
||||
const char *logtag; // added in version 2
|
||||
};
|
||||
|
||||
|
||||
@ -53,15 +56,26 @@ struct amxx_module_info_s
|
||||
|
||||
// *** Small stuff ***
|
||||
// The next section is copied from the amx.h file
|
||||
// Copyright (c) ITB CompuPhase, 1997-2004
|
||||
// Copyright (c) ITB CompuPhase, 1997-2005
|
||||
|
||||
#if defined __LCC__ || defined __DMC__ || defined __linux__
|
||||
#if defined HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
|
||||
#else
|
||||
#if defined __LCC__ || defined __DMC__ || defined LINUX
|
||||
#if defined HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
|
||||
/* The ISO C99 defines the int16_t and int_32t types. If the compiler got
|
||||
* here, these types are probably undefined.
|
||||
*/
|
||||
#if defined __FreeBSD__
|
||||
#if defined __MACH__
|
||||
#include <ppc/types.h>
|
||||
typedef unsigned short int uint16_t;
|
||||
typedef unsigned long int uint32_t;
|
||||
#elif defined __FreeBSD__
|
||||
#include <inttypes.h>
|
||||
#else
|
||||
typedef short int int16_t;
|
||||
@ -83,8 +97,14 @@ struct amxx_module_info_s
|
||||
#define HAVE_I64
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#define HAVE_STDINT_H
|
||||
#endif
|
||||
#if defined _LP64 || defined WIN64 || defined _WIN64
|
||||
#if !defined __64BIT__
|
||||
#define __64BIT__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* calling convention for native functions */
|
||||
#if !defined AMX_NATIVE_CALL
|
||||
@ -104,24 +124,26 @@ struct amxx_module_info_s
|
||||
#define AMXEXPORT
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if !defined SMALL_CELL_SIZE
|
||||
#define SMALL_CELL_SIZE 32 /* by default, use 32-bit cells */
|
||||
#if !defined PAWN_CELL_SIZE
|
||||
#define PAWN_CELL_SIZE 32 /* by default, use 32-bit cells */
|
||||
#endif
|
||||
#if SMALL_CELL_SIZE==32
|
||||
#if PAWN_CELL_SIZE==16
|
||||
typedef uint16_t ucell;
|
||||
typedef int16_t cell;
|
||||
#elif PAWN_CELL_SIZE==32
|
||||
typedef uint32_t ucell;
|
||||
typedef int32_t cell;
|
||||
typedef float REAL;
|
||||
#elif SMALL_CELL_SIZE==64
|
||||
#define REAL float
|
||||
#elif PAWN_CELL_SIZE==64
|
||||
typedef uint64_t ucell;
|
||||
typedef int64_t cell;
|
||||
typedef double REAL;
|
||||
#define REAL double
|
||||
#else
|
||||
#error Unsupported cell size (SMALL_CELL_SIZE)
|
||||
#error Unsupported cell size (PAWN_CELL_SIZE)
|
||||
#endif
|
||||
|
||||
#define UNPACKEDMAX ((1 << (sizeof(cell)-1)*8) - 1)
|
||||
#define UNLIMITED (~1u >> 1)
|
||||
|
||||
struct tagAMX;
|
||||
typedef cell (AMX_NATIVE_CALL *AMX_NATIVE)(struct tagAMX *amx, cell *params);
|
||||
@ -139,21 +161,24 @@ typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
|
||||
#endif
|
||||
|
||||
|
||||
#if defined SN_TARGET_PS2 || defined __GNUC__
|
||||
/* Some compilers do not support the #pragma align, which should be fine. Some
|
||||
* compilers give a warning on unknown #pragmas, which is not so fine...
|
||||
*/
|
||||
#if (defined SN_TARGET_PS2 || defined __GNUC__) && !defined AMX_NO_ALIGN
|
||||
#define AMX_NO_ALIGN
|
||||
#endif
|
||||
|
||||
|
||||
#if defined __GNUC__
|
||||
#define PACKED __attribute__((packed))
|
||||
#else
|
||||
#define PACKED
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined AMX_NO_ALIGN
|
||||
#if defined __linux__
|
||||
#if defined LINUX || defined __FreeBSD__
|
||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||
#elif defined MACOS && defined __MWERKS__
|
||||
#pragma options align=mac68k
|
||||
#else
|
||||
#pragma pack(push)
|
||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||
@ -174,7 +199,7 @@ typedef struct {
|
||||
* fields are valid at all times; many fields are cached in local variables.
|
||||
*/
|
||||
typedef struct tagAMX {
|
||||
unsigned char _FAR *base PACKED; /* points to the AMX header ("amxhdr") plus the code, optionally also the data */
|
||||
unsigned char _FAR *base PACKED; /* points to the AMX header plus the code, optionally also the data */
|
||||
unsigned char _FAR *data PACKED; /* points to separate data+stack+heap, may be NULL */
|
||||
AMX_CALLBACK callback PACKED;
|
||||
AMX_DEBUG debug PACKED; /* debug callback */
|
||||
@ -186,18 +211,15 @@ typedef struct tagAMX {
|
||||
cell stk PACKED; /* stack pointer: relative to base + amxhdr->dat */
|
||||
cell stp PACKED; /* top of the stack: relative to base + amxhdr->dat */
|
||||
int flags PACKED; /* current status, see amx_Flags() */
|
||||
/* for assertions and debug hook */
|
||||
cell curline PACKED;
|
||||
cell curfile PACKED;
|
||||
int dbgcode PACKED;
|
||||
cell dbgaddr PACKED;
|
||||
cell dbgparam PACKED;
|
||||
char _FAR *dbgname PACKED;
|
||||
/* user data */
|
||||
long usertags[AMX_USERNUM] PACKED;
|
||||
//okay userdata[3] in AMX Mod X is for the CPlugin * pointer
|
||||
//we're also gonna set userdata[2] to a special debug structure
|
||||
void _FAR *userdata[AMX_USERNUM] PACKED;
|
||||
/* native functions can raise an error */
|
||||
int error PACKED;
|
||||
/* passing parameters requires a "count" field */
|
||||
int paramcount;
|
||||
/* the sleep opcode needs to store the full AMX status */
|
||||
cell pri PACKED;
|
||||
cell alt PACKED;
|
||||
@ -207,7 +229,7 @@ typedef struct tagAMX {
|
||||
/* support variables for the JIT */
|
||||
int reloc_size PACKED; /* required temporary buffer for relocations */
|
||||
long code_size PACKED; /* estimated memory footprint of the native code */
|
||||
} AMX;
|
||||
} PACKED AMX;
|
||||
|
||||
enum {
|
||||
AMX_ERR_NONE,
|
||||
@ -224,6 +246,7 @@ enum {
|
||||
AMX_ERR_NATIVE, /* native function failed */
|
||||
AMX_ERR_DIVIDE, /* divide by zero */
|
||||
AMX_ERR_SLEEP, /* go into sleepmode - code can be restarted */
|
||||
AMX_ERR_INVSTATE, /* invalid state for this access */
|
||||
|
||||
AMX_ERR_MEMORY = 16, /* out of memory */
|
||||
AMX_ERR_FORMAT, /* invalid file format */
|
||||
@ -929,7 +952,7 @@ void FN_EngineFprintf(FILE *pfile, char *szFmt, ...);
|
||||
#endif // FN_EngineFprintf
|
||||
|
||||
#ifdef FN_PvAllocEntPrivateData
|
||||
void *FN_PvAllocEntPrivateData(edict_t *pEdict, long cb);
|
||||
void *FN_PvAllocEntPrivateData(edict_t *pEdict, int32 cb);
|
||||
#endif // FN_PvAllocEntPrivateData
|
||||
|
||||
#ifdef FN_PvEntPrivateData
|
||||
@ -1883,6 +1906,9 @@ void FN_AMXX_DETACH(void);
|
||||
void FN_AMXX_PLUGINSLOADED(void);
|
||||
#endif // FN_AMXX_PLUGINSLOADED
|
||||
|
||||
// *** Types ***
|
||||
typedef void* (*PFN_REQ_FNPTR)(const char * /*name*/);
|
||||
|
||||
// ***** Module funcs stuff *****
|
||||
enum ForwardExecType
|
||||
{
|
||||
@ -1906,6 +1932,7 @@ enum ForwardParam
|
||||
|
||||
typedef int (*PFN_ADD_NATIVES) (const AMX_NATIVE_INFO * /*list*/);
|
||||
typedef char * (*PFN_BUILD_PATHNAME) (const char * /*format*/, ...);
|
||||
typedef char * (*PFN_BUILD_PATHNAME_R) (char * /*buffer*/, size_t /* maxlen */, const char * /* format */, ...);
|
||||
typedef cell * (*PFN_GET_AMXADDR) (AMX * /*amx*/, cell /*offset*/);
|
||||
typedef void (*PFN_PRINT_SRVCONSOLE) (char * /*format*/, ...);
|
||||
typedef const char * (*PFN_GET_MODNAME) (void);
|
||||
@ -1960,7 +1987,7 @@ typedef void * (*PFN_REALLOCATOR) (const char* /*filename*/, const unsigned
|
||||
const unsigned int /*type*/, const size_t /*size*/, void* /*addr*/ );
|
||||
typedef void (*PFN_DEALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/,
|
||||
const unsigned int /*type*/, const void* /*addr*/ );
|
||||
typedef int (*PFN_AMX_EXEC) (AMX* /*amx*/, cell* /*return val*/, int /*index*/, int /*numparams*/, ... /*params*/);
|
||||
typedef int (*PFN_AMX_EXEC) (AMX* /*amx*/, cell* /*return val*/, int /*index*/);
|
||||
typedef int (*PFN_AMX_EXECV) (AMX* /*amx*/, cell* /*return val*/, int /*index*/, int /*numparams*/, cell[] /*params*/);
|
||||
typedef int (*PFN_AMX_ALLOT) (AMX* /*amx*/, int /*length*/, cell* /*amx_addr*/, cell** /*phys_addr*/);
|
||||
typedef int (*PFN_AMX_FINDPUBLIC) (AMX* /*amx*/, char* /*func name*/, int* /*index*/);
|
||||
@ -1974,9 +2001,12 @@ typedef int (*PFN_REGISTER_SPFORWARD_BYNAME) (AMX * /*amx*/, const char * /*f
|
||||
typedef void (*PFN_UNREGISTER_SPFORWARD) (int /*id*/);
|
||||
typedef void (*PFN_MERGEDEFINITION_FILE) (const char * /*filename*/);
|
||||
typedef const char * (*PFN_FORMAT) (const char * /*fmt*/, ... /*params*/);
|
||||
typedef void (*PFN_REGISTERFUNCTION) (void * /*pfn*/, const char * /*desc*/);
|
||||
typedef int (*PFN_AMX_PUSH) (AMX * /*amx*/, cell /*value*/);
|
||||
|
||||
extern PFN_ADD_NATIVES g_fn_AddNatives;
|
||||
extern PFN_BUILD_PATHNAME g_fn_BuildPathname;
|
||||
extern PFN_BUILD_PATHNAME_R g_fn_BuildPathnameR;
|
||||
extern PFN_GET_AMXADDR g_fn_GetAmxAddr;
|
||||
extern PFN_PRINT_SRVCONSOLE g_fn_PrintSrvConsole;
|
||||
extern PFN_GET_MODNAME g_fn_GetModname;
|
||||
@ -1990,7 +2020,7 @@ extern PFN_GET_AMXSTRINGLEN g_fn_GetAmxStringLen;
|
||||
extern PFN_FORMAT_AMXSTRING g_fn_FormatAmxString;
|
||||
extern PFN_COPY_AMXMEMORY g_fn_CopyAmxMemory;
|
||||
extern PFN_LOG g_fn_Log;
|
||||
extern PFN_LOG_ERROR g_fn_LogError;
|
||||
extern PFN_LOG_ERROR g_fn_LogErrorFunc;
|
||||
extern PFN_RAISE_AMXERROR g_fn_RaiseAmxError;
|
||||
extern PFN_REGISTER_FORWARD g_fn_RegisterForward;
|
||||
extern PFN_EXECUTE_FORWARD g_fn_ExecuteForward;
|
||||
@ -2034,12 +2064,16 @@ extern PFN_GETPLAYERFLAGS g_fn_GetPlayerFlags;
|
||||
extern PFN_GET_PLAYER_EDICT g_fn_GetPlayerEdict;
|
||||
extern PFN_FORMAT g_fn_Format;
|
||||
extern PFN_GET_PLAYER_TEAM g_fn_GetPlayerTeam;
|
||||
extern PFN_REGISTERFUNCTION g_fn_RegisterFunction;
|
||||
extern PFN_REQ_FNPTR g_fn_RequestFunction;
|
||||
extern PFN_AMX_PUSH g_fn_AmxPush;
|
||||
|
||||
#ifdef MAY_NEVER_BE_DEFINED
|
||||
// Function prototypes for intellisense and similar systems
|
||||
// They understand #if 0 so we use #ifdef MAY_NEVER_BE_DEFINED
|
||||
int MF_AddNatives (const AMX_NATIVE_INFO *list) { }
|
||||
char * MF_BuildPathname (const char * format, ...) { }
|
||||
char * MF_BuildPathnameR (char *buffer, size_t maxlen, const char *fmt, ...) { }
|
||||
cell * MF_GetAmxAddr (AMX * amx, cell offset) { }
|
||||
void MF_PrintSrvConsole (char * format, ...) { }
|
||||
const char * MF_GetModname (void) { }
|
||||
@ -2089,10 +2123,15 @@ void MF_UnregisterSPForward (int id) { }
|
||||
int MF_GetPlayerFlags (int id) { }
|
||||
edict_t* MF_GetPlayerEdict (int id) { }
|
||||
const char * MF_Format (const char *fmt, ...) { }
|
||||
void MF_RegisterFunction (void *pfn, const char *description) { }
|
||||
void * MF_RequestFunction (const char *description) { }
|
||||
int MF_AmxPush (AMX *amx, cell *params) { }
|
||||
int MF_AmxExec (AMX *amx, cell *retval, int idx) { }
|
||||
#endif // MAY_NEVER_BE_DEFINED
|
||||
|
||||
#define MF_AddNatives g_fn_AddNatives
|
||||
#define MF_BuildPathname g_fn_BuildPathname
|
||||
#define MF_BuildPathnameR g_fn_BuildPathnameR
|
||||
#define MF_FormatAmxString g_fn_FormatAmxString
|
||||
#define MF_GetAmxAddr g_fn_GetAmxAddr
|
||||
#define MF_PrintSrvConsole g_fn_PrintSrvConsole
|
||||
@ -2106,7 +2145,7 @@ const char * MF_Format (const char *fmt, ...) { }
|
||||
#define MF_GetAmxStringLen g_fn_GetAmxStringLen
|
||||
#define MF_CopyAmxMemory g_fn_CopyAmxMemory
|
||||
void MF_Log(const char *fmt, ...);
|
||||
#define MF_LogError g_fn_LogError
|
||||
void MF_LogError(AMX *amx, int err, const char *fmt, ...);
|
||||
#define MF_RaiseAmxError g_fn_RaiseAmxError
|
||||
#define MF_RegisterForward g_fn_RegisterForward
|
||||
#define MF_ExecuteForward g_fn_ExecuteForward
|
||||
@ -2150,6 +2189,9 @@ void MF_Log(const char *fmt, ...);
|
||||
#define MF_GetPlayerFlags g_fn_GetPlayerFlags
|
||||
#define MF_GetPlayerEdict g_fn_GetPlayerEdict
|
||||
#define MF_Format g_fn_Format
|
||||
#define MF_RegisterFunction g_fn_RegisterFunction
|
||||
#define MF_RequestFunction g_fn_RequestFunction;
|
||||
#define MF_AmxPush g_fn_AmxPush
|
||||
|
||||
/*** Memory ***/
|
||||
void *operator new(size_t reportedSize);
|
||||
|
@ -148,16 +148,16 @@ void amx_command(){
|
||||
{
|
||||
|
||||
print_srvconsole( "%s %s\n", Plugin_info.name, Plugin_info.version);
|
||||
print_srvconsole( "author: %s (%s)\n", Plugin_info.author, Plugin_info.url);
|
||||
print_srvconsole( "compiled: %s\n", __DATE__ ", " __TIME__);
|
||||
#ifdef JIT
|
||||
print_srvconsole( "Core mode: JIT\n");
|
||||
#else
|
||||
#ifdef ASM32
|
||||
print_srvconsole( "Core mode: ASM\n");
|
||||
print_srvconsole( "Authors: %s (%s)\n", "Felix \"SniperBeamer\" Geyer, David \"BAILOPAN\" Anderson, Pavol \"PM OnoTo\" Marko, Jonny \"Got His Gun\" Bergstrom, and Lukasz \"SidLuke\" Wlasinski.", Plugin_info.url);
|
||||
print_srvconsole( "Compiled: %s\n", __DATE__ ", " __TIME__);
|
||||
#if defined JIT && !defined ASM32
|
||||
print_srvconsole( "Core mode: JIT Only\n");
|
||||
#elif !defined JIT && defined ASM32
|
||||
print_srvconsole( "Core mode: ASM32 Only\n");
|
||||
#elif defined JIT && defined ASM32
|
||||
print_srvconsole( "Core mode: JIT+ASM32\n");
|
||||
#else
|
||||
print_srvconsole( "Core mode: Normal\n");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
else if (!strcmp(cmd,"modules"))
|
||||
@ -264,15 +264,9 @@ void amx_command(){
|
||||
|
||||
void plugin_srvcmd()
|
||||
{
|
||||
|
||||
cell ret = 0;
|
||||
int err;
|
||||
const char* cmd = CMD_ARGV(0);
|
||||
|
||||
#ifdef ENABLEEXEPTIONS
|
||||
try{
|
||||
#endif
|
||||
|
||||
CmdMngr::iterator a = g_commands.srvcmdbegin();
|
||||
|
||||
while ( a )
|
||||
@ -280,23 +274,9 @@ void plugin_srvcmd()
|
||||
if ( (*a).matchCommand( cmd ) &&
|
||||
(*a).getPlugin()->isExecutable( (*a).getFunction() ) )
|
||||
{
|
||||
|
||||
if ((err = amx_Exec( (*a).getPlugin()->getAMX(), &ret , (*a).getFunction()
|
||||
, 3 , g_srvindex , (*a).getFlags() , (*a).getId() )) != AMX_ERR_NONE)
|
||||
{
|
||||
LogError((*a).getPlugin()->getAMX(), err, "");
|
||||
}
|
||||
cell ret = executeForwards((*a).getFunction(), g_srvindex, (*a).getFlags(), (*a).getId());
|
||||
if ( ret ) break;
|
||||
}
|
||||
|
||||
++a;
|
||||
}
|
||||
|
||||
#ifdef ENABLEEXEPTIONS
|
||||
}catch( ... )
|
||||
{
|
||||
AMXXLOG_Log( "[AMXX] fatal error at forward function execution");
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@ -471,7 +471,7 @@ static cell AMX_NATIVE_CALL amx_strtok(AMX *amx, cell *params)
|
||||
char token = params[6];
|
||||
//trim
|
||||
int trim = params[7];
|
||||
for (i=0; i<len; i++)
|
||||
for (i=0; i<(unsigned int)len; i++)
|
||||
{
|
||||
if (trim && !done_flag)
|
||||
{
|
||||
@ -521,13 +521,13 @@ static cell AMX_NATIVE_CALL strbreak(AMX *amx, cell *params) /* 5 param */
|
||||
int LeftMax = params[3];
|
||||
int RightMax = params[5];
|
||||
|
||||
for (i=0; i<l; i++) {
|
||||
for (i=0; i<(unsigned int)l; i++) {
|
||||
if (string[i] == '"' && !quote_flag) {
|
||||
quote_flag = true;
|
||||
} else if (string[i] == '"' && quote_flag) {
|
||||
quote_flag = false;
|
||||
}
|
||||
if ((string[i] == ' ') && !quote_flag && !done_flag) {
|
||||
if (isspace(string[i]) && !quote_flag && !done_flag) {
|
||||
done_flag = true;
|
||||
i++;
|
||||
}
|
||||
@ -603,6 +603,14 @@ static cell AMX_NATIVE_CALL amx_ucfirst(AMX *amx, cell *params)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_strlen(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
char *str = get_amxstring(amx, params[1], 0, len);
|
||||
|
||||
return strlen(str);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_trim(AMX *amx, cell *params)
|
||||
{
|
||||
cell *asdf = get_amxaddr(amx, params[1]);
|
||||
@ -641,6 +649,75 @@ static cell AMX_NATIVE_CALL amx_trim(AMX *amx, cell *params)
|
||||
return incr;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL n_strcat(AMX *amx,cell *params)
|
||||
{
|
||||
cell *cdest,*csrc;
|
||||
|
||||
cdest = get_amxaddr(amx, params[1]);
|
||||
csrc = get_amxaddr(amx, params[2]);
|
||||
int num = params[3];
|
||||
while (*cdest && num)
|
||||
{
|
||||
cdest++;
|
||||
num--;
|
||||
}
|
||||
if (!num)
|
||||
return 0;
|
||||
while (*csrc && num)
|
||||
{
|
||||
*cdest++ = *csrc++;
|
||||
num--;
|
||||
}
|
||||
*cdest = 0;
|
||||
|
||||
return params[3] - num;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL n_strcmp(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
char *str1 = get_amxstring(amx, params[1], 0, len);
|
||||
char *str2 = get_amxstring(amx, params[2], 1, len);
|
||||
|
||||
if (params[1])
|
||||
return stricmp(str1, str2);
|
||||
else
|
||||
return strcmp(str1, str2);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL n_strfind(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
char *str = get_amxstring(amx, params[1], 0, len);
|
||||
int sublen;
|
||||
char *sub = get_amxstring(amx, params[2], 1, sublen);
|
||||
|
||||
bool found = false;
|
||||
bool igcase = params[3] ? true : false;
|
||||
if (igcase)
|
||||
{
|
||||
for (int i=0; i<len; i++)
|
||||
{
|
||||
if (str[i] & (1<<5))
|
||||
str[i] &= ~(1<<5);
|
||||
}
|
||||
for (int i=0; i<sublen; i++)
|
||||
{
|
||||
if (str[i] & (1<<5))
|
||||
str[i] &= ~(1<<5);
|
||||
}
|
||||
}
|
||||
if (params[4] > len)
|
||||
return -1;
|
||||
char *pos = &(str[ params[4] ]);
|
||||
char *find = strstr(str, sub);
|
||||
|
||||
if (!find)
|
||||
return -1;
|
||||
|
||||
return (find - str);
|
||||
}
|
||||
|
||||
AMX_NATIVE_INFO string_Natives[] = {
|
||||
{ "add", add },
|
||||
{ "contain", contain },
|
||||
@ -656,6 +733,7 @@ AMX_NATIVE_INFO string_Natives[] = {
|
||||
{ "isspace", is_space },
|
||||
{ "isalpha", is_alpha },
|
||||
{ "num_to_str", numtostr },
|
||||
{ "numtostr", numtostr },
|
||||
{ "parse", parse },
|
||||
{ "replace", replace },
|
||||
{ "setc", setc },
|
||||
@ -663,8 +741,14 @@ AMX_NATIVE_INFO string_Natives[] = {
|
||||
{ "strtolower", strtolower },
|
||||
{ "strtoupper", strtoupper },
|
||||
{ "str_to_num", strtonum },
|
||||
{ "strtonum", strtonum },
|
||||
{ "trim", amx_trim },
|
||||
{ "ucfirst", amx_ucfirst },
|
||||
{ "strtok", amx_strtok },
|
||||
{ "strlen", amx_strlen },
|
||||
{ "strcat", n_strcat },
|
||||
{ "strfind", n_strfind },
|
||||
{ "strcmp", n_strcmp },
|
||||
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
@ -33,6 +33,22 @@
|
||||
|
||||
#include "amxmodx.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#define _vsnprintf vsnprintf
|
||||
#endif
|
||||
|
||||
char *UTIL_VarArgs(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
static char string[4096];
|
||||
|
||||
va_start(ap, fmt);
|
||||
_vsnprintf(string, sizeof(string)-1, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
int UTIL_ReadFlags(const char* c)
|
||||
{
|
||||
int flags = 0;
|
||||
@ -260,17 +276,6 @@ void UTIL_FakeClientCommand(edict_t *pEdict, const char *cmd, const char *arg1,
|
||||
{
|
||||
if (!cmd)
|
||||
return; // no command
|
||||
/*
|
||||
char clCmd[256];
|
||||
snprintf(g_fakecmd.args, 255, "%s%s%s%s%s", cmd,
|
||||
arg1 ? " " : "", arg1 ? arg1 : "",
|
||||
arg2 ? " " : "", arg2 ? arg2 : "");
|
||||
clCmd[255] = 0;
|
||||
CLIENT_COMMAND(pEdict, clCmd);
|
||||
return;
|
||||
*/
|
||||
if (!cmd)
|
||||
return; // no command
|
||||
|
||||
// store command
|
||||
g_fakecmd.argv[0] = cmd;
|
||||
|
@ -1,8 +1,34 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "winres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 0,2,0,0
|
||||
PRODUCTVERSION 0,2,0,0
|
||||
FILEVERSION 1,5,0,1
|
||||
PRODUCTVERSION 1,5,0,1
|
||||
FILEFLAGSMASK 0x17L
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@ -17,14 +43,14 @@ BEGIN
|
||||
BEGIN
|
||||
BLOCK "000004b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "AMX Mod X\0"
|
||||
VALUE "FileDescription", "AMX Mod X\0"
|
||||
VALUE "FileVersion", "0.20\0"
|
||||
VALUE "InternalName", "amxmodx\0"
|
||||
VALUE "LegalCopyright", "Copyright (c) 2004, AMX Mod X Dev Team\0"
|
||||
VALUE "OriginalFilename", "amxx_mm.dll\0"
|
||||
VALUE "ProductName", "AMX Mod X\0"
|
||||
VALUE "ProductVersion", "0.20\0"
|
||||
VALUE "Comments", "AMX Mod X"
|
||||
VALUE "FileDescription", "AMX Mod X"
|
||||
VALUE "FileVersion", "1.50"
|
||||
VALUE "InternalName", "amxmodx"
|
||||
VALUE "LegalCopyright", "Copyright (c) 2004-2005, AMX Mod X Dev Team"
|
||||
VALUE "OriginalFilename", "amxmodx_mm.dll"
|
||||
VALUE "ProductName", "AMX Mod X"
|
||||
VALUE "ProductVersion", "1.50-RC1"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
@ -32,3 +58,45 @@ BEGIN
|
||||
VALUE "Translation", 0x0, 1200
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""winres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* zlib.h -- interface of the 'zlib' general purpose compression library
|
||||
version 1.2.1, November 17th, 2003
|
||||
version 1.2.3, July 18th, 2005
|
||||
|
||||
Copyright (C) 1995-2003 Jean-loup Gailly and Mark Adler
|
||||
Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@ -37,8 +37,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ZLIB_VERSION "1.2.1"
|
||||
#define ZLIB_VERNUM 0x1210
|
||||
#define ZLIB_VERSION "1.2.3"
|
||||
#define ZLIB_VERNUM 0x1230
|
||||
|
||||
/*
|
||||
The 'zlib' compression library provides in-memory compression and
|
||||
@ -53,24 +53,22 @@ extern "C" {
|
||||
application must provide more input and/or consume the output
|
||||
(providing more output space) before each call.
|
||||
|
||||
The compressed data format used by the in-memory functions is the zlib
|
||||
format, which is a zlib wrapper documented in RFC 1950, wrapped around a
|
||||
deflate stream, which is itself documented in RFC 1951.
|
||||
The compressed data format used by default by the in-memory functions is
|
||||
the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
|
||||
around a deflate stream, which is itself documented in RFC 1951.
|
||||
|
||||
The library also supports reading and writing files in gzip (.gz) format
|
||||
with an interface similar to that of stdio using the functions that start
|
||||
with "gz". The gzip format is different from the zlib format. gzip is a
|
||||
gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
|
||||
|
||||
This library can optionally read and write gzip streams in memory as well.
|
||||
|
||||
The zlib format was designed to be compact and fast for use in memory
|
||||
and on communications channels. The gzip format was designed for single-
|
||||
file compression on file systems, has a larger header than zlib to maintain
|
||||
directory information, and uses a different, slower check method than zlib.
|
||||
|
||||
This library does not provide any functions to write gzip files in memory.
|
||||
However such functions could be easily written using zlib's deflate function,
|
||||
the documentation in the gzip RFC, and the examples in gzio.c.
|
||||
|
||||
The library does not install any signal handler. The decoder checks
|
||||
the consistency of the compressed data, so the library should never
|
||||
crash even in case of corrupted input.
|
||||
@ -97,13 +95,36 @@ typedef struct z_stream_s {
|
||||
free_func zfree; /* used to free the internal state */
|
||||
voidpf opaque; /* private data object passed to zalloc and zfree */
|
||||
|
||||
int data_type; /* best guess about the data type: ascii or binary */
|
||||
int data_type; /* best guess about the data type: binary or text */
|
||||
uLong adler; /* adler32 value of the uncompressed data */
|
||||
uLong reserved; /* reserved for future use */
|
||||
} z_stream;
|
||||
|
||||
typedef z_stream FAR *z_streamp;
|
||||
|
||||
/*
|
||||
gzip header information passed to and from zlib routines. See RFC 1952
|
||||
for more details on the meanings of these fields.
|
||||
*/
|
||||
typedef struct gz_header_s {
|
||||
int text; /* true if compressed data believed to be text */
|
||||
uLong time; /* modification time */
|
||||
int xflags; /* extra flags (not used when writing a gzip file) */
|
||||
int os; /* operating system */
|
||||
Bytef *extra; /* pointer to extra field or Z_NULL if none */
|
||||
uInt extra_len; /* extra field length (valid if extra != Z_NULL) */
|
||||
uInt extra_max; /* space at extra (only when reading header) */
|
||||
Bytef *name; /* pointer to zero-terminated file name or Z_NULL */
|
||||
uInt name_max; /* space at name (only when reading header) */
|
||||
Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */
|
||||
uInt comm_max; /* space at comment (only when reading header) */
|
||||
int hcrc; /* true if there was or will be a header crc */
|
||||
int done; /* true when done reading gzip header (not used
|
||||
when writing a gzip file) */
|
||||
} gz_header;
|
||||
|
||||
typedef gz_header FAR *gz_headerp;
|
||||
|
||||
/*
|
||||
The application must update next_in and avail_in when avail_in has
|
||||
dropped to zero. It must update next_out and avail_out when avail_out
|
||||
@ -168,11 +189,13 @@ typedef z_stream FAR *z_streamp;
|
||||
#define Z_FILTERED 1
|
||||
#define Z_HUFFMAN_ONLY 2
|
||||
#define Z_RLE 3
|
||||
#define Z_FIXED 4
|
||||
#define Z_DEFAULT_STRATEGY 0
|
||||
/* compression strategy; see deflateInit2() below for details */
|
||||
|
||||
#define Z_BINARY 0
|
||||
#define Z_ASCII 1
|
||||
#define Z_TEXT 1
|
||||
#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
|
||||
#define Z_UNKNOWN 2
|
||||
/* Possible values of the data_type field (though see inflate()) */
|
||||
|
||||
@ -246,6 +269,10 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
|
||||
and with zero avail_out, it must be called again after making room in the
|
||||
output buffer because there might be more output pending.
|
||||
|
||||
Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
|
||||
decide how much data to accumualte before producing output, in order to
|
||||
maximize compression.
|
||||
|
||||
If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
|
||||
flushed to the output buffer and the output is aligned on a byte boundary, so
|
||||
that the decompressor can get all input data available so far. (In particular
|
||||
@ -257,7 +284,7 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
|
||||
Z_SYNC_FLUSH, and the compression state is reset so that decompression can
|
||||
restart from this point if previous compressed data has been damaged or if
|
||||
random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
|
||||
the compression.
|
||||
compression.
|
||||
|
||||
If deflate returns with avail_out == 0, this function must be called again
|
||||
with the same value of the flush parameter and more output space (updated
|
||||
@ -282,8 +309,8 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
|
||||
deflate() sets strm->adler to the adler32 checksum of all input read
|
||||
so far (that is, total_in bytes).
|
||||
|
||||
deflate() may update data_type if it can make a good guess about
|
||||
the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
|
||||
deflate() may update strm->data_type if it can make a good guess about
|
||||
the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
|
||||
binary. This field is only for information purposes and does not affect
|
||||
the compression algorithm in any manner.
|
||||
|
||||
@ -365,11 +392,11 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
|
||||
The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
|
||||
Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
|
||||
output as possible to the output buffer. Z_BLOCK requests that inflate() stop
|
||||
if and when it get to the next deflate block boundary. When decoding the zlib
|
||||
or gzip format, this will cause inflate() to return immediately after the
|
||||
header and before the first block. When doing a raw inflate, inflate() will
|
||||
go ahead and process the first block, and will return when it gets to the end
|
||||
of that block, or when it runs out of data.
|
||||
if and when it gets to the next deflate block boundary. When decoding the
|
||||
zlib or gzip format, this will cause inflate() to return immediately after
|
||||
the header and before the first block. When doing a raw inflate, inflate()
|
||||
will go ahead and process the first block, and will return when it gets to
|
||||
the end of that block, or when it runs out of data.
|
||||
|
||||
The Z_BLOCK option assists in appending to or combining deflate streams.
|
||||
Also to assist in this, on return inflate() will set strm->data_type to the
|
||||
@ -401,7 +428,7 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
|
||||
because Z_BLOCK is used.
|
||||
|
||||
If a preset dictionary is needed after this call (see inflateSetDictionary
|
||||
below), inflate sets strm-adler to the adler32 checksum of the dictionary
|
||||
below), inflate sets strm->adler to the adler32 checksum of the dictionary
|
||||
chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
|
||||
strm->adler to the adler32 checksum of all output produced so far (that is,
|
||||
total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
|
||||
@ -478,7 +505,8 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
|
||||
16 to windowBits to write a simple gzip header and trailer around the
|
||||
compressed data instead of a zlib wrapper. The gzip header will have no
|
||||
file name, no extra data, no comment, no modification time (set to zero),
|
||||
no header crc, and the operating system will be set to 255 (unknown).
|
||||
no header crc, and the operating system will be set to 255 (unknown). If a
|
||||
gzip stream is being written, strm->adler is a crc32 instead of an adler32.
|
||||
|
||||
The memLevel parameter specifies how much memory should be allocated
|
||||
for the internal compression state. memLevel=1 uses minimum memory but
|
||||
@ -497,7 +525,9 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
|
||||
Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
|
||||
Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
|
||||
parameter only affects the compression ratio but not the correctness of the
|
||||
compressed output even if it is not set appropriately.
|
||||
compressed output even if it is not set appropriately. Z_FIXED prevents the
|
||||
use of dynamic Huffman codes, allowing for a simpler decoder for special
|
||||
applications.
|
||||
|
||||
deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
|
||||
memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
|
||||
@ -526,7 +556,9 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
|
||||
deflateInit or deflateInit2, a part of the dictionary may in effect be
|
||||
discarded, for example if the dictionary is larger than the window size in
|
||||
deflate or deflate2. Thus the strings most likely to be useful should be
|
||||
put at the end of the dictionary, not at the front.
|
||||
put at the end of the dictionary, not at the front. In addition, the
|
||||
current implementation of deflate will use at most the window size minus
|
||||
262 bytes of the provided dictionary.
|
||||
|
||||
Upon return of this function, strm->adler is set to the adler32 value
|
||||
of the dictionary; the decompressor may later use this value to determine
|
||||
@ -592,6 +624,23 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
|
||||
if strm->avail_out was zero.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
|
||||
int good_length,
|
||||
int max_lazy,
|
||||
int nice_length,
|
||||
int max_chain));
|
||||
/*
|
||||
Fine tune deflate's internal compression parameters. This should only be
|
||||
used by someone who understands the algorithm used by zlib's deflate for
|
||||
searching for the best matching string, and even then only by the most
|
||||
fanatic optimizer trying to squeeze out the last compressed bit for their
|
||||
specific input data. Read the deflate.c source code for the meaning of the
|
||||
max_lazy, good_length, nice_length, and max_chain parameters.
|
||||
|
||||
deflateTune() can be called after deflateInit() or deflateInit2(), and
|
||||
returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
|
||||
*/
|
||||
|
||||
ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
|
||||
uLong sourceLen));
|
||||
/*
|
||||
@ -617,6 +666,30 @@ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
|
||||
stream state was inconsistent.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
|
||||
gz_headerp head));
|
||||
/*
|
||||
deflateSetHeader() provides gzip header information for when a gzip
|
||||
stream is requested by deflateInit2(). deflateSetHeader() may be called
|
||||
after deflateInit2() or deflateReset() and before the first call of
|
||||
deflate(). The text, time, os, extra field, name, and comment information
|
||||
in the provided gz_header structure are written to the gzip header (xflag is
|
||||
ignored -- the extra flags are set according to the compression level). The
|
||||
caller must assure that, if not Z_NULL, name and comment are terminated with
|
||||
a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
|
||||
available there. If hcrc is true, a gzip header crc is included. Note that
|
||||
the current versions of the command-line version of gzip (up through version
|
||||
1.3.x) do not support header crc's, and will report that it is a "multi-part
|
||||
gzip file" and give up.
|
||||
|
||||
If deflateSetHeader is not used, the default gzip header has text false,
|
||||
the time set to zero, and os set to 255, with no extra, name, or comment
|
||||
fields. The gzip header is returned to the default state by deflateReset().
|
||||
|
||||
deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
|
||||
stream state was inconsistent.
|
||||
*/
|
||||
|
||||
/*
|
||||
ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
|
||||
int windowBits));
|
||||
@ -649,14 +722,15 @@ ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
|
||||
windowBits can also be greater than 15 for optional gzip decoding. Add
|
||||
32 to windowBits to enable zlib and gzip decoding with automatic header
|
||||
detection, or add 16 to decode only the gzip format (the zlib format will
|
||||
return a Z_DATA_ERROR).
|
||||
return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is
|
||||
a crc32 instead of an adler32.
|
||||
|
||||
inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
|
||||
memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
|
||||
memLevel). msg is set to null if there is no error message. inflateInit2
|
||||
does not perform any decompression apart from reading the zlib header if
|
||||
present: this will be done by inflate(). (So next_in and avail_in may be
|
||||
modified, but next_out and avail_out are unchanged.)
|
||||
memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg
|
||||
is set to null if there is no error message. inflateInit2 does not perform
|
||||
any decompression apart from reading the zlib header if present: this will
|
||||
be done by inflate(). (So next_in and avail_in may be modified, but next_out
|
||||
and avail_out are unchanged.)
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
|
||||
@ -664,11 +738,14 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
|
||||
uInt dictLength));
|
||||
/*
|
||||
Initializes the decompression dictionary from the given uncompressed byte
|
||||
sequence. This function must be called immediately after a call of inflate
|
||||
if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
|
||||
can be determined from the adler32 value returned by this call of
|
||||
inflate. The compressor and decompressor must use exactly the same
|
||||
dictionary (see deflateSetDictionary).
|
||||
sequence. This function must be called immediately after a call of inflate,
|
||||
if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
|
||||
can be determined from the adler32 value returned by that call of inflate.
|
||||
The compressor and decompressor must use exactly the same dictionary (see
|
||||
deflateSetDictionary). For raw inflate, this function can be called
|
||||
immediately after inflateInit2() or inflateReset() and before any call of
|
||||
inflate() to set the dictionary. The application must insure that the
|
||||
dictionary that was used for compression is provided.
|
||||
|
||||
inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
|
||||
parameter is invalid (such as NULL dictionary) or the stream state is
|
||||
@ -719,8 +796,64 @@ ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
|
||||
stream state was inconsistent (such as zalloc or state being NULL).
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
|
||||
int bits,
|
||||
int value));
|
||||
/*
|
||||
ZEXTERN int ZEXPORT inflateBackInit OF((z_stream FAR *strm, int windowBits,
|
||||
This function inserts bits in the inflate input stream. The intent is
|
||||
that this function is used to start inflating at a bit position in the
|
||||
middle of a byte. The provided bits will be used before any bytes are used
|
||||
from next_in. This function should only be used with raw inflate, and
|
||||
should be used before the first inflate() call after inflateInit2() or
|
||||
inflateReset(). bits must be less than or equal to 16, and that many of the
|
||||
least significant bits of value will be inserted in the input.
|
||||
|
||||
inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
|
||||
stream state was inconsistent.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
|
||||
gz_headerp head));
|
||||
/*
|
||||
inflateGetHeader() requests that gzip header information be stored in the
|
||||
provided gz_header structure. inflateGetHeader() may be called after
|
||||
inflateInit2() or inflateReset(), and before the first call of inflate().
|
||||
As inflate() processes the gzip stream, head->done is zero until the header
|
||||
is completed, at which time head->done is set to one. If a zlib stream is
|
||||
being decoded, then head->done is set to -1 to indicate that there will be
|
||||
no gzip header information forthcoming. Note that Z_BLOCK can be used to
|
||||
force inflate() to return immediately after header processing is complete
|
||||
and before any actual data is decompressed.
|
||||
|
||||
The text, time, xflags, and os fields are filled in with the gzip header
|
||||
contents. hcrc is set to true if there is a header CRC. (The header CRC
|
||||
was valid if done is set to one.) If extra is not Z_NULL, then extra_max
|
||||
contains the maximum number of bytes to write to extra. Once done is true,
|
||||
extra_len contains the actual extra field length, and extra contains the
|
||||
extra field, or that field truncated if extra_max is less than extra_len.
|
||||
If name is not Z_NULL, then up to name_max characters are written there,
|
||||
terminated with a zero unless the length is greater than name_max. If
|
||||
comment is not Z_NULL, then up to comm_max characters are written there,
|
||||
terminated with a zero unless the length is greater than comm_max. When
|
||||
any of extra, name, or comment are not Z_NULL and the respective field is
|
||||
not present in the header, then that field is set to Z_NULL to signal its
|
||||
absence. This allows the use of deflateSetHeader() with the returned
|
||||
structure to duplicate the header. However if those fields are set to
|
||||
allocated memory, then the application will need to save those pointers
|
||||
elsewhere so that they can be eventually freed.
|
||||
|
||||
If inflateGetHeader is not used, then the header information is simply
|
||||
discarded. The header is always checked for validity, including the header
|
||||
CRC if present. inflateReset() will reset the process to discard the header
|
||||
information. The application would need to call inflateGetHeader() again to
|
||||
retrieve the header from the next gzip stream.
|
||||
|
||||
inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
|
||||
stream state was inconsistent.
|
||||
*/
|
||||
|
||||
/*
|
||||
ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
|
||||
unsigned char FAR *window));
|
||||
|
||||
Initialize the internal stream state for decompression using inflateBack()
|
||||
@ -744,7 +877,7 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_stream FAR *strm, int windowBits,
|
||||
typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
|
||||
typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
|
||||
|
||||
ZEXTERN int ZEXPORT inflateBack OF((z_stream FAR *strm,
|
||||
ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
|
||||
in_func in, void FAR *in_desc,
|
||||
out_func out, void FAR *out_desc));
|
||||
/*
|
||||
@ -813,7 +946,7 @@ ZEXTERN int ZEXPORT inflateBack OF((z_stream FAR *strm,
|
||||
that inflateBack() cannot return Z_OK.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT inflateBackEnd OF((z_stream FAR *strm));
|
||||
ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
|
||||
/*
|
||||
All memory allocated by inflateBackInit() is freed.
|
||||
|
||||
@ -1087,6 +1220,12 @@ ZEXTERN int ZEXPORT gzeof OF((gzFile file));
|
||||
input stream, otherwise zero.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
|
||||
/*
|
||||
Returns 1 if file is being read directly without decompression, otherwise
|
||||
zero.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT gzclose OF((gzFile file));
|
||||
/*
|
||||
Flushes all pending output if necessary, closes the compressed file
|
||||
@ -1119,7 +1258,6 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
|
||||
*/
|
||||
|
||||
ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
|
||||
|
||||
/*
|
||||
Update a running Adler-32 checksum with the bytes buf[0..len-1] and
|
||||
return the updated checksum. If buf is NULL, this function returns
|
||||
@ -1135,12 +1273,21 @@ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
|
||||
if (adler != original_adler) error();
|
||||
*/
|
||||
|
||||
ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
|
||||
z_off_t len2));
|
||||
/*
|
||||
Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
|
||||
and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
|
||||
each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
|
||||
seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
|
||||
*/
|
||||
|
||||
ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
|
||||
/*
|
||||
Update a running crc with the bytes buf[0..len-1] and return the updated
|
||||
crc. If buf is NULL, this function returns the required initial value
|
||||
for the crc. Pre- and post-conditioning (one's complement) is performed
|
||||
within this function so it shouldn't be done by the application.
|
||||
Update a running CRC-32 with the bytes buf[0..len-1] and return the
|
||||
updated CRC-32. If buf is NULL, this function returns the required initial
|
||||
value for the for the crc. Pre- and post-conditioning (one's complement) is
|
||||
performed within this function so it shouldn't be done by the application.
|
||||
Usage example:
|
||||
|
||||
uLong crc = crc32(0L, Z_NULL, 0);
|
||||
@ -1151,6 +1298,16 @@ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
|
||||
if (crc != original_crc) error();
|
||||
*/
|
||||
|
||||
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
|
||||
|
||||
/*
|
||||
Combine two CRC-32 check values into one. For two sequences of bytes,
|
||||
seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
|
||||
calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
|
||||
check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
|
||||
len2.
|
||||
*/
|
||||
|
||||
|
||||
/* various hacks, don't look :) */
|
||||
|
||||
@ -1167,7 +1324,7 @@ ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
|
||||
int stream_size));
|
||||
ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
|
||||
const char *version, int stream_size));
|
||||
ZEXTERN int ZEXPORT inflateBackInit_ OF((z_stream FAR *strm, int windowBits,
|
||||
ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
|
||||
unsigned char FAR *window,
|
||||
const char *version,
|
||||
int stream_size));
|
||||
@ -1189,7 +1346,7 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_stream FAR *strm, int windowBits,
|
||||
struct internal_state {int dummy;}; /* hack for buggy compilers */
|
||||
#endif
|
||||
|
||||
ZEXTERN const char * ZEXPORT zError OF((int err));
|
||||
ZEXTERN const char * ZEXPORT zError OF((int));
|
||||
ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
|
||||
ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
|
||||
|
||||
|
Binary file not shown.
143
compiler/amxxpc/Binary.cpp
Executable file
143
compiler/amxxpc/Binary.cpp
Executable file
@ -0,0 +1,143 @@
|
||||
#include "Binary.h"
|
||||
|
||||
BinaryWriter::BinaryWriter(FILE *fp)
|
||||
{
|
||||
m_Fp = fp;
|
||||
}
|
||||
|
||||
bool BinaryWriter::WriteAddr(void *buffer, size_t size)
|
||||
{
|
||||
if (fwrite(buffer, size, 1, m_Fp) != 1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BinaryWriter::WriteUInt32(uint32_t num)
|
||||
{
|
||||
if ( !WriteAddr(&num, sizeof(uint32_t)) )
|
||||
throw -1;
|
||||
}
|
||||
|
||||
void BinaryWriter::WriteInt32(int32_t num)
|
||||
{
|
||||
if ( !WriteAddr(&num, sizeof(int32_t)) )
|
||||
throw -1;
|
||||
}
|
||||
|
||||
void BinaryWriter::WriteUInt16(uint16_t num)
|
||||
{
|
||||
if ( !WriteAddr(&num, sizeof(uint16_t)) )
|
||||
throw -1;
|
||||
}
|
||||
|
||||
void BinaryWriter::WriteInt16(int16_t num)
|
||||
{
|
||||
if ( !WriteAddr(&num, sizeof(int16_t)) )
|
||||
throw -1;
|
||||
}
|
||||
|
||||
void BinaryWriter::WriteUInt8(uint8_t num)
|
||||
{
|
||||
if ( !WriteAddr(&num, sizeof(uint8_t)) )
|
||||
throw -1;
|
||||
}
|
||||
|
||||
void BinaryWriter::WriteInt8(int8_t num)
|
||||
{
|
||||
if ( !WriteAddr(&num, sizeof(int8_t)) )
|
||||
throw -1;
|
||||
}
|
||||
|
||||
void BinaryWriter::WriteChars(const char buffer[], size_t chars)
|
||||
{
|
||||
if (!chars)
|
||||
return;
|
||||
|
||||
if (fwrite(buffer, sizeof(char), chars, m_Fp) != chars)
|
||||
throw -1;
|
||||
}
|
||||
|
||||
BinaryReader::BinaryReader(FILE *fp)
|
||||
{
|
||||
m_Fp = fp;
|
||||
}
|
||||
|
||||
bool BinaryReader::ReadAddr(void *buffer, size_t size)
|
||||
{
|
||||
if (fread(buffer, size, 1, m_Fp) != 1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t BinaryReader::ReadUInt32()
|
||||
{
|
||||
uint32_t num;
|
||||
|
||||
if ( !ReadAddr(&num, sizeof(uint32_t)) )
|
||||
throw -1;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
int32_t BinaryReader::ReadInt32()
|
||||
{
|
||||
int32_t num;
|
||||
|
||||
if ( !ReadAddr(&num, sizeof(int32_t)) )
|
||||
throw -1;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
uint16_t BinaryReader::ReadUInt16()
|
||||
{
|
||||
uint16_t num;
|
||||
|
||||
if ( !ReadAddr(&num, sizeof(uint16_t)) )
|
||||
throw -1;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
int16_t BinaryReader::ReadInt16()
|
||||
{
|
||||
int16_t num;
|
||||
|
||||
if ( !ReadAddr(&num, sizeof(int16_t)) )
|
||||
throw -1;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
uint8_t BinaryReader::ReadUInt8()
|
||||
{
|
||||
uint8_t num;
|
||||
|
||||
if ( !ReadAddr(&num, sizeof(uint8_t)) )
|
||||
throw -1;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
int8_t BinaryReader::ReadInt8()
|
||||
{
|
||||
int8_t num;
|
||||
|
||||
if ( !ReadAddr(&num, sizeof(int8_t)) )
|
||||
throw -1;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
char *BinaryReader::ReadChars(char buffer[], size_t chars)
|
||||
{
|
||||
if (!chars)
|
||||
return buffer;
|
||||
|
||||
if (fread(buffer, sizeof(char), chars, m_Fp) != chars)
|
||||
throw -1;
|
||||
|
||||
return buffer;
|
||||
}
|
54
compiler/amxxpc/Binary.h
Executable file
54
compiler/amxxpc/Binary.h
Executable file
@ -0,0 +1,54 @@
|
||||
#ifndef _INCLUDE_BINARY_H
|
||||
#define _INCLUDE_BINARY_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include "amx.h"
|
||||
|
||||
#ifdef WIN32
|
||||
typedef __int8 int8_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
class BinaryReader
|
||||
{
|
||||
public:
|
||||
BinaryReader(FILE *fp);
|
||||
//~BinaryReader();
|
||||
public:
|
||||
uint32_t ReadUInt32();
|
||||
int32_t ReadInt32();
|
||||
uint16_t ReadUInt16();
|
||||
int16_t ReadInt16();
|
||||
uint8_t ReadUInt8();
|
||||
int8_t ReadInt8();
|
||||
char *ReadChars(char buffer[], size_t chars);
|
||||
private:
|
||||
bool ReadAddr(void *buffer, size_t size);
|
||||
private:
|
||||
FILE *m_Fp;
|
||||
};
|
||||
|
||||
class BinaryWriter
|
||||
{
|
||||
public:
|
||||
BinaryWriter(FILE *fp);
|
||||
public:
|
||||
void WriteUInt32(uint32_t num);
|
||||
void WriteInt32(int32_t num);
|
||||
void WriteUInt16(uint16_t num);
|
||||
void WriteInt16(int16_t num);
|
||||
void WriteUInt8(uint8_t num);
|
||||
void WriteInt8(int8_t num);
|
||||
void WriteChars(const char buffer[], size_t chars);
|
||||
private:
|
||||
bool WriteAddr(void *buffer, size_t size);
|
||||
private:
|
||||
FILE *m_Fp;
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_BINARY_H
|
||||
|
46
compiler/amxxpc/Makefile
Executable file
46
compiler/amxxpc/Makefile
Executable file
@ -0,0 +1,46 @@
|
||||
#(C)2004-2005 AMX Mod X Development Team
|
||||
# Makefile written by David "BAILOPAN" Anderson
|
||||
|
||||
### EDIT BELOW FOR OTHER PROJECTS ###
|
||||
|
||||
OPT_FLAGS = -O3 -fno-rtti -funroll-loops -s -pipe
|
||||
DEBUG_FLAGS = -g -ggdb3
|
||||
CPP = g++
|
||||
BINARY = amxxpc
|
||||
|
||||
OBJECTS = amx.cpp amxxpc.cpp Binary.cpp
|
||||
|
||||
LINK = -lz
|
||||
|
||||
INCLUDE = -I. -L.
|
||||
|
||||
ifeq "$(DEBUG)" "true"
|
||||
BIN_DIR = Debug
|
||||
CFLAGS = $(DEBUG_FLAGS)
|
||||
else
|
||||
BIN_DIR = Release
|
||||
CFLAGS = $(OPT_FLAGS)
|
||||
endif
|
||||
|
||||
CFLAGS += -DLINUX -DNDEBUG -Wno-deprecated -fexceptions -DHAVE_STDINT_H -DAMX_ANSIONLY
|
||||
|
||||
OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o)
|
||||
|
||||
$(BIN_DIR)/%.o: %.cpp
|
||||
$(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
all:
|
||||
mkdir -p $(BIN_DIR)
|
||||
$(MAKE) amxxpc
|
||||
|
||||
amxxpc: $(OBJ_LINUX)
|
||||
$(CPP) $(INCLUDE) $(CFLAGS) $(OBJ_LINUX) $(LINK) -ldl -lm -o$(BIN_DIR)/$(BINARY)
|
||||
|
||||
default: all
|
||||
|
||||
clean:
|
||||
rm -rf Release/*.o
|
||||
rm -rf Release/$(BINARY)
|
||||
rm -rf Debug/*.o
|
||||
rm -rf Debug/$(BINARY)
|
||||
|
3984
compiler/amxxpc/amx.cpp
Executable file
3984
compiler/amxxpc/amx.cpp
Executable file
File diff suppressed because it is too large
Load Diff
432
compiler/amxxpc/amx.h
Executable file
432
compiler/amxxpc/amx.h
Executable file
@ -0,0 +1,432 @@
|
||||
/* Pawn Abstract Machine (for the Pawn language)
|
||||
*
|
||||
* Copyright (c) ITB CompuPhase, 1997-2005
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty.
|
||||
* In no event will the authors be held liable for any damages arising from
|
||||
* the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software in
|
||||
* a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined FREEBSD && !defined __FreeBSD__
|
||||
#define __FreeBSD__
|
||||
#endif
|
||||
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
|
||||
#include <sclinux.h>
|
||||
#endif
|
||||
|
||||
#ifndef AMX_H_INCLUDED
|
||||
#define AMX_H_INCLUDED
|
||||
|
||||
#if defined HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#if defined __LCC__ || defined __DMC__ || defined LINUX
|
||||
#if defined HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
|
||||
/* The ISO C99 defines the int16_t and int_32t types. If the compiler got
|
||||
* here, these types are probably undefined.
|
||||
*/
|
||||
#if defined __MACH__
|
||||
#include <ppc/types.h>
|
||||
typedef unsigned short int uint16_t;
|
||||
typedef unsigned long int uint32_t;
|
||||
#elif defined __FreeBSD__
|
||||
#include <inttypes.h>
|
||||
#else
|
||||
typedef short int int16_t;
|
||||
typedef unsigned short int uint16_t;
|
||||
#if defined SN_TARGET_PS2
|
||||
typedef int int32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
#else
|
||||
typedef long int int32_t;
|
||||
typedef unsigned long int uint32_t;
|
||||
#endif
|
||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#define HAVE_I64
|
||||
#elif defined __GNUC__
|
||||
typedef long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
#define HAVE_I64
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#define HAVE_STDINT_H
|
||||
#endif
|
||||
#if defined _LP64 || defined WIN64 || defined _WIN64
|
||||
#if !defined __64BIT__
|
||||
#define __64BIT__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAVE_ALLOCA_H
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32 /* || defined __MSDOS__ */
|
||||
#if !defined alloca
|
||||
#define alloca(n) _alloca(n)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined arraysize
|
||||
#define arraysize(array) (sizeof(array) / sizeof((array)[0]))
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined PAWN_DLL
|
||||
#if !defined AMX_NATIVE_CALL
|
||||
#define AMX_NATIVE_CALL __stdcall
|
||||
#endif
|
||||
#if !defined AMXAPI
|
||||
#define AMXAPI __stdcall
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* calling convention for native functions */
|
||||
#if !defined AMX_NATIVE_CALL
|
||||
#define AMX_NATIVE_CALL
|
||||
#endif
|
||||
/* calling convention for all interface functions and callback functions */
|
||||
#if !defined AMXAPI
|
||||
#if defined STDECL
|
||||
#define AMXAPI __stdcall
|
||||
#elif defined CDECL
|
||||
#define AMXAPI __cdecl
|
||||
#elif defined GCC_HASCLASSVISIBILITY
|
||||
#define AMXAPI __attribute__ ((visibility("default")))
|
||||
#else
|
||||
#define AMXAPI
|
||||
#endif
|
||||
#endif
|
||||
#if !defined AMXEXPORT
|
||||
#define AMXEXPORT
|
||||
#endif
|
||||
|
||||
/* File format version Required AMX version
|
||||
* 0 (original version) 0
|
||||
* 1 (opcodes JUMP.pri, SWITCH and CASETBL) 1
|
||||
* 2 (compressed files) 2
|
||||
* 3 (public variables) 2
|
||||
* 4 (opcodes SWAP.pri/alt and PUSHADDR) 4
|
||||
* 5 (tagnames table) 4
|
||||
* 6 (reformatted header) 6
|
||||
* 7 (name table, opcodes SYMTAG & SYSREQ.D) 7
|
||||
* 8 (opcode STMT, renewed debug interface) 8
|
||||
*/
|
||||
#define CUR_FILE_VERSION 8 /* current file version; also the current AMX version */
|
||||
#define MIN_FILE_VERSION 6 /* lowest supported file format version for the current AMX version */
|
||||
#define MIN_AMX_VERSION 8 /* minimum AMX version needed to support the current file format */
|
||||
|
||||
#if !defined PAWN_CELL_SIZE
|
||||
#define PAWN_CELL_SIZE 32 /* by default, use 32-bit cells */
|
||||
#endif
|
||||
#if PAWN_CELL_SIZE==16
|
||||
typedef uint16_t ucell;
|
||||
typedef int16_t cell;
|
||||
#elif PAWN_CELL_SIZE==32
|
||||
typedef uint32_t ucell;
|
||||
typedef int32_t cell;
|
||||
#elif PAWN_CELL_SIZE==64
|
||||
typedef uint64_t ucell;
|
||||
typedef int64_t cell;
|
||||
#else
|
||||
#error Unsupported cell size (PAWN_CELL_SIZE)
|
||||
#endif
|
||||
|
||||
#define UNPACKEDMAX ((1L << (sizeof(cell)-1)*8) - 1)
|
||||
#define UNLIMITED (~1u >> 1)
|
||||
|
||||
struct tagAMX;
|
||||
typedef cell (AMX_NATIVE_CALL *AMX_NATIVE)(struct tagAMX *amx, cell *params);
|
||||
typedef int (AMXAPI *AMX_CALLBACK)(struct tagAMX *amx, cell index,
|
||||
cell *result, cell *params);
|
||||
typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
|
||||
#if !defined _FAR
|
||||
#define _FAR
|
||||
#endif
|
||||
|
||||
#if defined _MSC_VER
|
||||
#pragma warning(disable:4103) /* disable warning message 4103 that complains
|
||||
* about pragma pack in a header file */
|
||||
#pragma warning(disable:4100) /* "'%$S' : unreferenced formal parameter" */
|
||||
#endif
|
||||
|
||||
/* Some compilers do not support the #pragma align, which should be fine. Some
|
||||
* compilers give a warning on unknown #pragmas, which is not so fine...
|
||||
*/
|
||||
#if (defined SN_TARGET_PS2 || defined __GNUC__) && !defined AMX_NO_ALIGN
|
||||
#define AMX_NO_ALIGN
|
||||
#endif
|
||||
|
||||
#if defined __GNUC__
|
||||
#define PACKED __attribute__((packed))
|
||||
#else
|
||||
#define PACKED
|
||||
#endif
|
||||
|
||||
#if !defined AMX_NO_ALIGN
|
||||
#if defined LINUX || defined __FreeBSD__
|
||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||
#elif defined MACOS && defined __MWERKS__
|
||||
#pragma options align=mac68k
|
||||
#else
|
||||
#pragma pack(push)
|
||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||
#if defined __TURBOC__
|
||||
#pragma option -a- /* "pack" pragma for older Borland compilers */
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct tagAMX_NATIVE_INFO {
|
||||
const char _FAR *name PACKED;
|
||||
AMX_NATIVE func PACKED;
|
||||
} PACKED AMX_NATIVE_INFO;
|
||||
|
||||
#define AMX_USERNUM 4
|
||||
#define sEXPMAX 19 /* maximum name length for file version <= 6 */
|
||||
#define sNAMEMAX 31 /* maximum name length of symbol name */
|
||||
|
||||
typedef struct tagAMX_FUNCSTUB {
|
||||
ucell address PACKED;
|
||||
char name[sEXPMAX+1] PACKED;
|
||||
} PACKED AMX_FUNCSTUB;
|
||||
|
||||
typedef struct tagFUNCSTUBNT {
|
||||
ucell address PACKED;
|
||||
ucell nameofs PACKED; //we need this for amxx to be backwards comaptible
|
||||
} PACKED AMX_FUNCSTUBNT;
|
||||
|
||||
/* The AMX structure is the internal structure for many functions. Not all
|
||||
* fields are valid at all times; many fields are cached in local variables.
|
||||
*/
|
||||
typedef struct tagAMX {
|
||||
unsigned char _FAR *base PACKED; /* points to the AMX header plus the code, optionally also the data */
|
||||
unsigned char _FAR *data PACKED; /* points to separate data+stack+heap, may be NULL */
|
||||
AMX_CALLBACK callback PACKED;
|
||||
AMX_DEBUG debug PACKED; /* debug callback */
|
||||
/* for external functions a few registers must be accessible from the outside */
|
||||
cell cip PACKED; /* instruction pointer: relative to base + amxhdr->cod */
|
||||
cell frm PACKED; /* stack frame base: relative to base + amxhdr->dat */
|
||||
cell hea PACKED; /* top of the heap: relative to base + amxhdr->dat */
|
||||
cell hlw PACKED; /* bottom of the heap: relative to base + amxhdr->dat */
|
||||
cell stk PACKED; /* stack pointer: relative to base + amxhdr->dat */
|
||||
cell stp PACKED; /* top of the stack: relative to base + amxhdr->dat */
|
||||
int flags PACKED; /* current status, see amx_Flags() */
|
||||
/* user data */
|
||||
long usertags[AMX_USERNUM] PACKED;
|
||||
void _FAR *userdata[AMX_USERNUM] PACKED;
|
||||
/* native functions can raise an error */
|
||||
int error PACKED;
|
||||
/* passing parameters requires a "count" field */
|
||||
int paramcount;
|
||||
/* the sleep opcode needs to store the full AMX status */
|
||||
cell pri PACKED;
|
||||
cell alt PACKED;
|
||||
cell reset_stk PACKED;
|
||||
cell reset_hea PACKED;
|
||||
cell sysreq_d PACKED; /* relocated address/value for the SYSREQ.D opcode */
|
||||
/* support variables for the JIT */
|
||||
int reloc_size PACKED; /* required temporary buffer for relocations */
|
||||
long code_size PACKED; /* estimated memory footprint of the native code */
|
||||
} PACKED AMX;
|
||||
|
||||
/* The AMX_HEADER structure is both the memory format as the file format. The
|
||||
* structure is used internaly.
|
||||
*/
|
||||
typedef struct tagAMX_HEADER {
|
||||
int32_t size PACKED; /* size of the "file" */
|
||||
uint16_t magic PACKED; /* signature */
|
||||
char file_version PACKED; /* file format version */
|
||||
char amx_version PACKED; /* required version of the AMX */
|
||||
int16_t flags PACKED;
|
||||
int16_t defsize PACKED; /* size of a definition record */
|
||||
int32_t cod PACKED; /* initial value of COD - code block */
|
||||
int32_t dat PACKED; /* initial value of DAT - data block */
|
||||
int32_t hea PACKED; /* initial value of HEA - start of the heap */
|
||||
int32_t stp PACKED; /* initial value of STP - stack top */
|
||||
int32_t cip PACKED; /* initial value of CIP - the instruction pointer */
|
||||
int32_t publics PACKED; /* offset to the "public functions" table */
|
||||
int32_t natives PACKED; /* offset to the "native functions" table */
|
||||
int32_t libraries PACKED; /* offset to the table of libraries */
|
||||
int32_t pubvars PACKED; /* the "public variables" table */
|
||||
int32_t tags PACKED; /* the "public tagnames" table */
|
||||
int32_t nametable PACKED; /* name table */
|
||||
} PACKED AMX_HEADER;
|
||||
|
||||
//This is always the same for us
|
||||
#define AMX_MAGIC 0xf1e0
|
||||
|
||||
enum {
|
||||
AMX_ERR_NONE,
|
||||
/* reserve the first 15 error codes for exit codes of the abstract machine */
|
||||
AMX_ERR_EXIT, /* forced exit */
|
||||
AMX_ERR_ASSERT, /* assertion failed */
|
||||
AMX_ERR_STACKERR, /* stack/heap collision */
|
||||
AMX_ERR_BOUNDS, /* index out of bounds */
|
||||
AMX_ERR_MEMACCESS, /* invalid memory access */
|
||||
AMX_ERR_INVINSTR, /* invalid instruction */
|
||||
AMX_ERR_STACKLOW, /* stack underflow */
|
||||
AMX_ERR_HEAPLOW, /* heap underflow */
|
||||
AMX_ERR_CALLBACK, /* no callback, or invalid callback */
|
||||
AMX_ERR_NATIVE, /* native function failed */
|
||||
AMX_ERR_DIVIDE, /* divide by zero */
|
||||
AMX_ERR_SLEEP, /* go into sleepmode - code can be restarted */
|
||||
AMX_ERR_INVSTATE, /* invalid state for this access */
|
||||
|
||||
AMX_ERR_MEMORY = 16, /* out of memory */
|
||||
AMX_ERR_FORMAT, /* invalid file format */
|
||||
AMX_ERR_VERSION, /* file is for a newer version of the AMX */
|
||||
AMX_ERR_NOTFOUND, /* function not found */
|
||||
AMX_ERR_INDEX, /* invalid index parameter (bad entry point) */
|
||||
AMX_ERR_DEBUG, /* debugger cannot run */
|
||||
AMX_ERR_INIT, /* AMX not initialized (or doubly initialized) */
|
||||
AMX_ERR_USERDATA, /* unable to set user data field (table full) */
|
||||
AMX_ERR_INIT_JIT, /* cannot initialize the JIT */
|
||||
AMX_ERR_PARAMS, /* parameter error */
|
||||
AMX_ERR_DOMAIN, /* domain error, expression result does not fit in range */
|
||||
AMX_ERR_GENERAL, /* general error (unknown or unspecific error) */
|
||||
};
|
||||
|
||||
/* AMX_FLAG_CHAR16 0x01 no longer used */
|
||||
#define AMX_FLAG_DEBUG 0x02 /* symbolic info. available */
|
||||
#define AMX_FLAG_COMPACT 0x04 /* compact encoding */
|
||||
#define AMX_FLAG_BYTEOPC 0x08 /* opcode is a byte (not a cell) */
|
||||
#define AMX_FLAG_NOCHECKS 0x10 /* no array bounds checking; no STMT opcode */
|
||||
#define AMX_FLAG_NTVREG 0x1000 /* all native functions are registered */
|
||||
#define AMX_FLAG_JITC 0x2000 /* abstract machine is JIT compiled */
|
||||
#define AMX_FLAG_BROWSE 0x4000 /* busy browsing */
|
||||
#define AMX_FLAG_RELOC 0x8000 /* jump/call addresses relocated */
|
||||
|
||||
#define AMX_EXEC_MAIN -1 /* start at program entry point */
|
||||
#define AMX_EXEC_CONT -2 /* continue from last address */
|
||||
|
||||
#define AMX_USERTAG(a,b,c,d) ((a) | ((b)<<8) | ((long)(c)<<16) | ((long)(d)<<24))
|
||||
|
||||
#if !defined AMX_COMPACTMARGIN
|
||||
#define AMX_COMPACTMARGIN 64
|
||||
#endif
|
||||
|
||||
/* for native functions that use floating point parameters, the following
|
||||
* two macros are convenient for casting a "cell" into a "float" type _without_
|
||||
* changing the bit pattern
|
||||
*/
|
||||
#if PAWN_CELL_SIZE==32
|
||||
#define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
|
||||
#define amx_ctof(c) ( * ((float*)&c) ) /* cell to float */
|
||||
#elif PAWN_CELL_SIZE==64
|
||||
#define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
|
||||
#define amx_ctof(c) ( * ((double*)&c) ) /* cell to float */
|
||||
#else
|
||||
#error Unsupported cell size
|
||||
#endif
|
||||
|
||||
#define amx_StrParam(amx,param,result) \
|
||||
do { \
|
||||
cell *amx_cstr_; int amx_length_; \
|
||||
amx_GetAddr((amx), (param), &amx_cstr_); \
|
||||
amx_StrLen(amx_cstr_, &amx_length_); \
|
||||
if (amx_length_ > 0 && \
|
||||
((result) = (void*)alloca((amx_length_ + 1) * sizeof(*(result)))) != NULL) \
|
||||
amx_GetString((char*)(result), amx_cstr_, sizeof(*(result))>1, amx_length_); \
|
||||
else (result) = NULL; \
|
||||
} while (0)
|
||||
|
||||
uint16_t * AMXAPI amx_Align16(uint16_t *v);
|
||||
uint32_t * AMXAPI amx_Align32(uint32_t *v);
|
||||
#if defined _I64_MAX || defined HAVE_I64
|
||||
uint64_t * AMXAPI amx_Align64(uint64_t *v);
|
||||
#endif
|
||||
int AMXAPI amx_Allot(AMX *amx, int cells, cell *amx_addr, cell **phys_addr);
|
||||
int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params);
|
||||
int AMXAPI amx_Cleanup(AMX *amx);
|
||||
int AMXAPI amx_Clone(AMX *amxClone, AMX *amxSource, void *data);
|
||||
int AMXAPI amx_Exec(AMX *amx, cell *retval, int index);
|
||||
int AMXAPI amx_FindNative(AMX *amx, const char *name, int *index);
|
||||
int AMXAPI amx_FindPublic(AMX *amx, const char *funcname, int *index);
|
||||
int AMXAPI amx_FindPubVar(AMX *amx, const char *varname, cell *amx_addr);
|
||||
int AMXAPI amx_FindTagId(AMX *amx, cell tag_id, char *tagname);
|
||||
int AMXAPI amx_Flags(AMX *amx,uint16_t *flags);
|
||||
int AMXAPI amx_GetAddr(AMX *amx,cell amx_addr,cell **phys_addr);
|
||||
int AMXAPI amx_GetNative(AMX *amx, int index, char *funcname);
|
||||
int AMXAPI amx_GetPublic(AMX *amx, int index, char *funcname);
|
||||
int AMXAPI amx_GetPubVar(AMX *amx, int index, char *varname, cell *amx_addr);
|
||||
int AMXAPI amx_GetString(char *dest,const cell *source, int use_wchar, size_t size);
|
||||
int AMXAPI amx_GetTag(AMX *amx, int index, char *tagname, cell *tag_id);
|
||||
int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr);
|
||||
int AMXAPI amx_Init(AMX *amx, void *program);
|
||||
int AMXAPI amx_InitJIT(AMX *amx, void *reloc_table, void *native_code);
|
||||
int AMXAPI amx_MemInfo(AMX *amx, long *codesize, long *datasize, long *stackheap);
|
||||
int AMXAPI amx_NameLength(AMX *amx, int *length);
|
||||
AMX_NATIVE_INFO * AMXAPI amx_NativeInfo(const char *name, AMX_NATIVE func);
|
||||
int AMXAPI amx_NumNatives(AMX *amx, int *number);
|
||||
int AMXAPI amx_NumPublics(AMX *amx, int *number);
|
||||
int AMXAPI amx_NumPubVars(AMX *amx, int *number);
|
||||
int AMXAPI amx_NumTags(AMX *amx, int *number);
|
||||
int AMXAPI amx_Push(AMX *amx, cell value);
|
||||
int AMXAPI amx_PushArray(AMX *amx, cell *amx_addr, cell **phys_addr, const cell array[], int numcells);
|
||||
int AMXAPI amx_PushString(AMX *amx, cell *amx_addr, cell **phys_addr, const char *string, int pack, int use_wchar);
|
||||
int AMXAPI amx_RaiseError(AMX *amx, int error);
|
||||
int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *nativelist, int number);
|
||||
int AMXAPI amx_Release(AMX *amx, cell amx_addr);
|
||||
int AMXAPI amx_SetCallback(AMX *amx, AMX_CALLBACK callback);
|
||||
int AMXAPI amx_SetDebugHook(AMX *amx, AMX_DEBUG debug);
|
||||
int AMXAPI amx_SetString(cell *dest, const char *source, int pack, int use_wchar, size_t size);
|
||||
int AMXAPI amx_SetUserData(AMX *amx, long tag, void *ptr);
|
||||
int AMXAPI amx_StrLen(const cell *cstring, int *length);
|
||||
int AMXAPI amx_UTF8Check(const char *string, int *length);
|
||||
int AMXAPI amx_UTF8Get(const char *string, const char **endptr, cell *value);
|
||||
int AMXAPI amx_UTF8Len(const cell *cstr, int *length);
|
||||
int AMXAPI amx_UTF8Put(char *string, char **endptr, int maxchars, cell value);
|
||||
|
||||
#if PAWN_CELL_SIZE==16
|
||||
#define amx_AlignCell(v) amx_Align16(v)
|
||||
#elif PAWN_CELL_SIZE==32
|
||||
#define amx_AlignCell(v) amx_Align32(v)
|
||||
#elif PAWN_CELL_SIZE==64 && (defined _I64_MAX || defined HAVE_I64)
|
||||
#define amx_AlignCell(v) amx_Align64(v)
|
||||
#else
|
||||
#error Unsupported cell size
|
||||
#endif
|
||||
|
||||
#define amx_RegisterFunc(amx, name, func) \
|
||||
amx_Register((amx), amx_NativeInfo((name),(func)), 1);
|
||||
|
||||
#if !defined AMX_NO_ALIGN
|
||||
#if defined LINUX || defined __FreeBSD__
|
||||
#pragma pack() /* reset default packing */
|
||||
#elif defined MACOS && defined __MWERKS__
|
||||
#pragma options align=reset
|
||||
#else
|
||||
#pragma pack(pop) /* reset previous packing */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AMX_H_INCLUDED */
|
172
compiler/amxxpc/amxdbg.h
Executable file
172
compiler/amxxpc/amxdbg.h
Executable file
@ -0,0 +1,172 @@
|
||||
/* Abstract Machine for the Pawn compiler, debugger support
|
||||
*
|
||||
* This file contains extra definitions that are convenient for debugger
|
||||
* support.
|
||||
*
|
||||
* Copyright (c) ITB CompuPhase, 2005
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty.
|
||||
* In no event will the authors be held liable for any damages arising from
|
||||
* the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software in
|
||||
* a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#ifndef AMXDBG_H_INCLUDED
|
||||
#define AMXDBG_H_INCLUDED
|
||||
|
||||
#ifndef AMX_H_INCLUDED
|
||||
#include "amx.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Some compilers do not support the #pragma align, which should be fine. Some
|
||||
* compilers give a warning on unknown #pragmas, which is not so fine...
|
||||
*/
|
||||
#if defined SN_TARGET_PS2 || defined __GNUC__
|
||||
#define AMX_NO_ALIGN
|
||||
#endif
|
||||
|
||||
#if defined __GNUC__
|
||||
#define PACKED __attribute__((packed))
|
||||
#else
|
||||
#define PACKED
|
||||
#endif
|
||||
|
||||
#if !defined AMX_NO_ALIGN
|
||||
#if defined LINUX || defined __FreeBSD__
|
||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||
#elif defined MACOS && defined __MWERKS__
|
||||
#pragma options align=mac68k
|
||||
#else
|
||||
#pragma pack(push)
|
||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||
#if defined __TURBOC__
|
||||
#pragma option -a- /* "pack" pragma for older Borland compilers */
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct tagAMX_DBG_HDR {
|
||||
int32_t size PACKED; /* size of the debug information chunk */
|
||||
uint16_t magic PACKED; /* signature, must be 0xf1ef */
|
||||
char file_version PACKED; /* file format version */
|
||||
char amx_version PACKED; /* required version of the AMX */
|
||||
int16_t flags PACKED; /* currently unused */
|
||||
int16_t files PACKED; /* number of entries in the "file" table */
|
||||
int16_t lines PACKED; /* number of entries in the "line" table */
|
||||
int16_t symbols PACKED; /* number of entries in the "symbol" table */
|
||||
int16_t tags PACKED; /* number of entries in the "tag" table */
|
||||
int16_t automatons PACKED; /* number of entries in the "automaton" table */
|
||||
int16_t states PACKED; /* number of entries in the "state" table */
|
||||
} AMX_DBG_HDR PACKED;
|
||||
#define AMX_DBG_MAGIC 0xf1ef
|
||||
|
||||
typedef struct tagAMX_DBG_FILE {
|
||||
ucell address PACKED; /* address in the code segment where generated code (for this file) starts */
|
||||
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
||||
} AMX_DBG_FILE PACKED;
|
||||
|
||||
typedef struct tagAMX_DBG_LINE {
|
||||
ucell address PACKED; /* address in the code segment where generated code (for this line) starts */
|
||||
int32_t line PACKED; /* line number */
|
||||
} AMX_DBG_LINE PACKED;
|
||||
|
||||
typedef struct tagAMX_DBG_SYMBOL {
|
||||
ucell address PACKED; /* address in the data segment or relative to the frame */
|
||||
int16_t tag PACKED; /* tag for the symbol */
|
||||
ucell codestart PACKED; /* address in the code segment from which this symbol is valid (in scope) */
|
||||
ucell codeend PACKED; /* address in the code segment until which this symbol is valid (in scope) */
|
||||
char ident PACKED; /* kind of symbol (function/variable) */
|
||||
char vclass PACKED; /* class of symbol (global/local) */
|
||||
int16_t dim PACKED; /* number of dimensions */
|
||||
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
||||
} AMX_DBG_SYMBOL PACKED;
|
||||
|
||||
typedef struct tagAMX_DBG_SYMDIM {
|
||||
int16_t tag PACKED; /* tag for the array dimension */
|
||||
ucell size PACKED; /* size of the array dimension */
|
||||
} AMX_DBG_SYMDIM PACKED;
|
||||
|
||||
typedef struct tagAMX_DBG_TAG {
|
||||
int16_t tag PACKED; /* tag id */
|
||||
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
||||
} AMX_DBG_TAG PACKED;
|
||||
|
||||
typedef struct tagAMX_DBG_MACHINE {
|
||||
int16_t automaton PACKED; /* automaton id */
|
||||
ucell address PACKED; /* address of state variable */
|
||||
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
||||
} AMX_DBG_MACHINE PACKED;
|
||||
|
||||
typedef struct tagAMX_DBG_STATE {
|
||||
int16_t state PACKED; /* state id */
|
||||
int16_t automaton PACKED; /* automaton id */
|
||||
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
||||
} AMX_DBG_STATE PACKED;
|
||||
|
||||
typedef struct tagAMX_DBG {
|
||||
AMX_DBG_HDR _FAR *hdr PACKED; /* points to the AMX_DBG header */
|
||||
AMX_DBG_FILE _FAR **filetbl PACKED;
|
||||
AMX_DBG_LINE _FAR *linetbl PACKED;
|
||||
AMX_DBG_SYMBOL _FAR **symboltbl PACKED;
|
||||
AMX_DBG_TAG _FAR **tagtbl PACKED;
|
||||
AMX_DBG_MACHINE _FAR **automatontbl PACKED;
|
||||
AMX_DBG_STATE _FAR **statetbl PACKED;
|
||||
} AMX_DBG PACKED;
|
||||
|
||||
#if !defined iVARIABLE
|
||||
#define iVARIABLE 1 /* cell that has an address and that can be fetched directly (lvalue) */
|
||||
#define iREFERENCE 2 /* iVARIABLE, but must be dereferenced */
|
||||
#define iARRAY 3
|
||||
#define iREFARRAY 4 /* an array passed by reference (i.e. a pointer) */
|
||||
#define iFUNCTN 9
|
||||
#endif
|
||||
|
||||
|
||||
int AMXAPI dbg_FreeInfo(AMX_DBG *amxdbg);
|
||||
int AMXAPI dbg_LoadInfo(AMX_DBG *amxdbg, FILE *fp);
|
||||
|
||||
int AMXAPI dbg_LookupFile(AMX_DBG *amxdbg, ucell address, const char **filename);
|
||||
int AMXAPI dbg_LookupFunction(AMX_DBG *amxdbg, ucell address, const char **funcname);
|
||||
int AMXAPI dbg_LookupLine(AMX_DBG *amxdbg, ucell address, long *line);
|
||||
|
||||
int AMXAPI dbg_GetFunctionAddress(AMX_DBG *amxdbg, const char *funcname, const char *filename, ucell *address);
|
||||
int AMXAPI dbg_GetLineAddress(AMX_DBG *amxdbg, long line, const char *filename, ucell *address);
|
||||
int AMXAPI dbg_GetAutomatonName(AMX_DBG *amxdbg, int automaton, const char **name);
|
||||
int AMXAPI dbg_GetStateName(AMX_DBG *amxdbg, int state, const char **name);
|
||||
int AMXAPI dbg_GetTagName(AMX_DBG *amxdbg, int tag, const char **name);
|
||||
int AMXAPI dbg_GetVariable(AMX_DBG *amxdbg, const char *symname, ucell scopeaddr, const AMX_DBG_SYMBOL **sym);
|
||||
int AMXAPI dbg_GetArrayDim(AMX_DBG *amxdbg, const AMX_DBG_SYMBOL *sym, const AMX_DBG_SYMDIM **symdim);
|
||||
|
||||
|
||||
#if !defined AMX_NO_ALIGN
|
||||
#if defined LINUX || defined __FreeBSD__
|
||||
#pragma pack() /* reset default packing */
|
||||
#elif defined MACOS && defined __MWERKS__
|
||||
#pragma options align=reset
|
||||
#else
|
||||
#pragma pack(pop) /* reset previous packing */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AMXDBG_H_INCLUDED */
|
376
compiler/amxxpc/amxxpc.cpp
Executable file
376
compiler/amxxpc/amxxpc.cpp
Executable file
@ -0,0 +1,376 @@
|
||||
#include <stdio.h>
|
||||
#ifdef __linux__
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include "zlib.h"
|
||||
#include "amx.h"
|
||||
#include "amxdbg.h"
|
||||
#include "amxxpc.h"
|
||||
#include "Binary.h"
|
||||
|
||||
static PRINTF pc_printf = NULL;
|
||||
|
||||
void ReadFileIntoPl(abl *pl, FILE *fp);
|
||||
bool CompressPl(abl *pl);
|
||||
void Pl2Bh(abl *pl, BinPlugin *bh);
|
||||
void WriteBh(BinaryWriter *bw, BinPlugin *bh);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct abl pl32;
|
||||
struct abl pl64;
|
||||
|
||||
#ifdef _DEBUG
|
||||
printf("debug clamp\n");
|
||||
getchar();
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
HINSTANCE lib = dlmount("./amxxpc32.so");
|
||||
#else
|
||||
HINSTANCE lib = dlmount("amxxpc32.dll");
|
||||
#endif
|
||||
if (!lib)
|
||||
{
|
||||
#ifdef __linux__
|
||||
printf("32bit compiler failed to instantiate: %s\n", dlerror());
|
||||
#else
|
||||
printf("32bit compiler failed to instantiate: %d\n", GetLastError());
|
||||
#endif
|
||||
exit(0);
|
||||
}
|
||||
|
||||
COMPILER sc32 = (COMPILER)dlsym(lib, "Compile32");
|
||||
pc_printf = (PRINTF)dlsym(lib, "pc_printf");
|
||||
|
||||
if (!sc32 || !pc_printf)
|
||||
{
|
||||
#ifdef __linux__
|
||||
printf("32bit compiler failed to link: %p.\n",sc32);
|
||||
#else
|
||||
printf("32bit compiler failed to link: %d.\n", GetLastError());
|
||||
#endif
|
||||
exit(0);
|
||||
}
|
||||
|
||||
pc_printf("Welcome to the AMX Mod X %s Compiler.\n", VERSION_STRING);
|
||||
pc_printf("Copyright (c) 1997-2005 ITB CompuPhase, AMX Mod X Team\n\n");
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
pc_printf("Usage: <file.sma> [options]\n");
|
||||
pc_printf("Use -? or --help to see full options\n\n");
|
||||
getchar();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "-?") || !strcmp(argv[1], "--help"))
|
||||
{
|
||||
show_help();
|
||||
pc_printf("Press any key to continue.\n");
|
||||
getchar();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
sc32(argc, argv);
|
||||
|
||||
char *file = FindFileName(argc, argv);
|
||||
|
||||
if (file == NULL)
|
||||
{
|
||||
pc_printf("Could not locate the output file.\n");
|
||||
exit(0);
|
||||
} else if (strstr(file, ".asm")) {
|
||||
pc_printf("Assembler output succeeded.\n");
|
||||
exit(0);
|
||||
} else {
|
||||
FILE *fp = fopen(file, "rb");
|
||||
if (fp == NULL)
|
||||
{
|
||||
pc_printf("Could not locate output file %s (compile failed).\n", file);
|
||||
exit(0);
|
||||
}
|
||||
ReadFileIntoPl(&pl32, fp);
|
||||
pl32.cellsize = 4;
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
dlclose(lib);
|
||||
unlink(file);
|
||||
|
||||
HINSTANCE lib64 = 0;
|
||||
#ifdef __linux__
|
||||
lib64 = dlmount("./amxxpc64.so");
|
||||
#else
|
||||
lib64 = dlmount("amxxpc64.dll");
|
||||
#endif
|
||||
pc_printf = (PRINTF)dlsym(lib64, "pc_printf");
|
||||
if (!lib64 || !pc_printf)
|
||||
{
|
||||
pc_printf("64bit compiler failed to instantiate.\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
COMPILER sc64 = (COMPILER)dlsym(lib64, "Compile64");
|
||||
|
||||
if (!sc64)
|
||||
{
|
||||
#ifdef __linux__
|
||||
pc_printf("64bit compiler failed to link: %s.\n", dlerror());
|
||||
#else
|
||||
pc_printf("64bit compiler failed to link: %d.\n", GetLastError());
|
||||
#endif
|
||||
exit(0);
|
||||
}
|
||||
|
||||
sc64(argc, argv);
|
||||
|
||||
if (file == NULL)
|
||||
{
|
||||
pc_printf("Could not locate the output file on second pass.\n");
|
||||
exit(0);
|
||||
} else {
|
||||
FILE *fp = fopen(file, "rb");
|
||||
if (fp == NULL)
|
||||
{
|
||||
pc_printf("Could not locate output file on second pass (compile failed).\n");
|
||||
exit(0);
|
||||
}
|
||||
ReadFileIntoPl(&pl64, fp);
|
||||
pl64.cellsize = 8;
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
/////////////
|
||||
// COMPRSSION
|
||||
/////////////
|
||||
|
||||
CompressPl(&pl32);
|
||||
|
||||
CompressPl(&pl64);
|
||||
|
||||
char *newfile = new char[strlen(file)+3];
|
||||
strcpy(newfile, file);
|
||||
if (!strstr(file, ".amxx") && !strstr(file, ".AMXX"))
|
||||
strcat(newfile, "x");
|
||||
|
||||
FILE *fp = fopen(newfile, "wb");
|
||||
if (!fp)
|
||||
{
|
||||
pc_printf("Error trying to write file %s.\n", newfile);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
BinPlugin bh32, bh64;
|
||||
|
||||
Pl2Bh(&pl32, &bh32);
|
||||
Pl2Bh(&pl64, &bh64);
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
BinaryWriter bw(fp);
|
||||
|
||||
bw.WriteUInt32(MAGIC_HEADER2);
|
||||
bw.WriteUInt16(MAGIC_VERSION);
|
||||
bw.WriteUInt8(2);
|
||||
|
||||
//base header
|
||||
int baseaddr = sizeof(int32_t) + sizeof(int16_t) + sizeof(int8_t);
|
||||
//entry is 4 ints and a byte
|
||||
int entrysize = (sizeof(int32_t) * 4) + sizeof(int8_t);
|
||||
//extend this by the two entries we have
|
||||
baseaddr += entrysize * 2;
|
||||
|
||||
bh32.offs = baseaddr;
|
||||
bh64.offs = bh32.offs + bh32.disksize;
|
||||
|
||||
WriteBh(&bw, &bh32);
|
||||
WriteBh(&bw, &bh64);
|
||||
bw.WriteChars(pl32.cmp, pl32.cmpsize);
|
||||
bw.WriteChars(pl64.cmp, pl64.cmpsize);
|
||||
} catch (...) {
|
||||
fclose(fp);
|
||||
unlink(file);
|
||||
pc_printf("Error, failed to write binary\n");
|
||||
dlclose(lib);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
unlink(file);
|
||||
|
||||
pc_printf("Done.\n");
|
||||
|
||||
dlclose(lib64);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void WriteBh(BinaryWriter *bw, BinPlugin *bh)
|
||||
{
|
||||
bw->WriteUInt8(bh->cellsize);
|
||||
bw->WriteUInt32(bh->disksize);
|
||||
bw->WriteUInt32(bh->imagesize);
|
||||
bw->WriteUInt32(bh->memsize);
|
||||
bw->WriteUInt32(bh->offs);
|
||||
}
|
||||
|
||||
void Pl2Bh(abl *pl, BinPlugin *bh)
|
||||
{
|
||||
bh->cellsize = pl->cellsize;
|
||||
bh->disksize = pl->cmpsize;
|
||||
bh->imagesize = pl->size;
|
||||
bh->memsize = pl->stp;
|
||||
}
|
||||
|
||||
bool CompressPl(abl *pl)
|
||||
{
|
||||
pl->cmpsize = compressBound(pl->size);
|
||||
pl->cmp = new char[pl->cmpsize];
|
||||
|
||||
int err = compress((Bytef *)(pl->cmp), (uLongf *)&(pl->cmpsize), (const Bytef *)(pl->data), pl->size);
|
||||
|
||||
delete [] pl->data;
|
||||
pl->data = NULL;
|
||||
|
||||
if (err != Z_OK)
|
||||
{
|
||||
pc_printf("internal error - compression failed on first pass: %d\n", err);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//As of Small 3.0, there's extra debug info in the file we need to get out.
|
||||
//Sadly this is placed somewhere really inconvenient and I'm mad.
|
||||
void ReadFileIntoPl(abl *pl, FILE *fp)
|
||||
{
|
||||
AMX_HEADER hdr;
|
||||
AMX_DBG_HDR dbg;
|
||||
fread(&hdr, sizeof(hdr), 1, fp);
|
||||
amx_Align32((uint32_t *)&hdr.stp);
|
||||
amx_Align32((uint32_t *)&hdr.size);
|
||||
pl->stp = hdr.stp;
|
||||
int size = hdr.size;
|
||||
if (hdr.flags & AMX_FLAG_DEBUG)
|
||||
{
|
||||
fseek(fp, hdr.size, SEEK_SET);
|
||||
fread(&dbg, sizeof(dbg), 1, fp);
|
||||
size += dbg.size;
|
||||
}
|
||||
pl->size = size;
|
||||
pl->data = new char[size];
|
||||
rewind(fp);
|
||||
fread(pl->data, 1, size, fp);
|
||||
}
|
||||
|
||||
//we get the full name of the file here
|
||||
//our job is to a] switch the .sma extension to .amx
|
||||
// and to b] strip everything but the trailing name
|
||||
char *swiext(const char *file, const char *ext, int isO)
|
||||
{
|
||||
int i = 0, pos = -1, j = 0;
|
||||
int fileLen = strlen(file);
|
||||
int extLen = strlen(ext);
|
||||
int max = 0, odirFlag = -1;
|
||||
|
||||
for (i=fileLen-1; i>=0; i--)
|
||||
{
|
||||
if (file[i] == '.' && pos == -1)
|
||||
{
|
||||
pos = i+1;
|
||||
}
|
||||
if ((file[i] == '/' || file[i] == '\\') && !isO)
|
||||
{
|
||||
odirFlag = i+1;
|
||||
//realign pos - we've just stripped fileLen-i chars
|
||||
pos -= i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char *newbuffer = new char[fileLen+strlen(ext)+2];
|
||||
fileLen += strlen(ext);
|
||||
if (odirFlag == -1)
|
||||
{
|
||||
strcpy(newbuffer, file);
|
||||
} else {
|
||||
strcpy(newbuffer, &(file[odirFlag]));
|
||||
}
|
||||
|
||||
if (pos > -1)
|
||||
{
|
||||
for (i=pos; i<fileLen; i++)
|
||||
{
|
||||
if (j < extLen)
|
||||
newbuffer[i] = ext[j++];
|
||||
else
|
||||
break;
|
||||
}
|
||||
newbuffer[i] = '\0';
|
||||
} else {
|
||||
strcat(newbuffer, ".");
|
||||
strcat(newbuffer, ext);
|
||||
}
|
||||
|
||||
return newbuffer;
|
||||
}
|
||||
|
||||
char *FindFileName(int argc, char **argv)
|
||||
{
|
||||
int i = 0;
|
||||
int save = -1;
|
||||
for (i=1; i<argc; i++)
|
||||
{
|
||||
if (argv[i][0] == '-' && argv[i][1] == 'o')
|
||||
{
|
||||
if (argv[i][2] == ' ' || argv[i][2] == '\0')
|
||||
{
|
||||
if (i == argc-1)
|
||||
return NULL;
|
||||
return swiext(&argv[i+1][2], "amx", 1);
|
||||
} else {
|
||||
return swiext(&(argv[i][2]), "amx", 1);
|
||||
}
|
||||
}
|
||||
if (argv[i][0] != '-')
|
||||
{
|
||||
save = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (save>0)
|
||||
{
|
||||
return swiext(argv[save], "amx", 0);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void show_help()
|
||||
{
|
||||
printf("Options:\n");
|
||||
printf("\t-A<num> alignment in bytes of the data segment and the stack\n");
|
||||
printf("\t-a output assembler code\n");
|
||||
printf("\t-C[+/-] compact encoding for output file (default=-)\n");
|
||||
printf("\t-c<name> codepage name or number; e.g. 1252 for Windows Latin-1\n");
|
||||
printf("\t-Dpath active directory path\n");
|
||||
printf("\t-d0 no symbolic information, no run-time checks\n");
|
||||
printf("\t-d1 [default] run-time checks, no symbolic information\n");
|
||||
printf("\t-d2 full debug information and dynamic checking\n");
|
||||
printf("\t-d3 full debug information, dynamic checking, no optimization\n");
|
||||
printf("\t-e<name> set name of error file (quiet compile)\n");
|
||||
printf("\t-H<hwnd> window handle to send a notification message on finish\n");
|
||||
printf("\t-i<name> path for include files\n");
|
||||
printf("\t-l create list file (preprocess only)\n");
|
||||
printf("\t-o<name> set base name of output file\n");
|
||||
printf("\t-p<name> set name of \"prefix\" file\n");
|
||||
printf("\t-r[name] write cross reference report to console or to specified file\n");
|
||||
}
|
70
compiler/amxxpc/amxxpc.h
Executable file
70
compiler/amxxpc/amxxpc.h
Executable file
@ -0,0 +1,70 @@
|
||||
#ifndef _AMXXSC_INCLUDE_H
|
||||
#define _AMXXSC_INCLUDE_H
|
||||
|
||||
#define VERSION_STRING "1.50-300"
|
||||
#define VERSION 03000
|
||||
#define MAGIC_HEADER 0x414D5842
|
||||
#define MAGIC_HEADER2 0x414D5858
|
||||
#define MAGIC_VERSION 0x0300
|
||||
|
||||
#ifdef __linux__
|
||||
# include <dlfcn.h>
|
||||
#else
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __linux__
|
||||
# define dlmount(x) dlopen(x, RTLD_NOW|RTLD_GLOBAL)
|
||||
typedef void* HINSTANCE;
|
||||
#else
|
||||
# define dlsym(x, s) GetProcAddress(x, s)
|
||||
# define dlmount(x) LoadLibrary(x)
|
||||
# define dlclose(x) FreeLibrary(x)
|
||||
#endif
|
||||
|
||||
#include "zlib.h"
|
||||
#include "Binary.h"
|
||||
|
||||
typedef int (*COMPILER)(int argc, char **argv);
|
||||
typedef int (*PRINTF)(const char *message, ...);
|
||||
|
||||
char *FindFileName(int argc, char **argv);
|
||||
char *swiext(const char *file, const char *ext);
|
||||
void show_help();
|
||||
|
||||
|
||||
struct ablhdr
|
||||
{
|
||||
int magic;
|
||||
char size;
|
||||
};
|
||||
|
||||
struct abl
|
||||
{
|
||||
long stp;
|
||||
char cellsize;
|
||||
int size;
|
||||
long cmpsize;
|
||||
char *data;
|
||||
char *cmp;
|
||||
};
|
||||
|
||||
struct BinHeader
|
||||
{
|
||||
int32_t magic;
|
||||
int16_t version;
|
||||
int8_t plugins;
|
||||
};
|
||||
|
||||
struct BinPlugin
|
||||
{
|
||||
int8_t cellsize; //cell size
|
||||
int32_t imagesize; //uncompressed image size
|
||||
int32_t disksize; //compressed image size
|
||||
int32_t memsize; //memory image size
|
||||
int32_t offs; //file offset
|
||||
};
|
||||
|
||||
#endif //_AMXXSC_INCLUDE_H
|
21
compiler/amxxpc/amxxpc.sln
Executable file
21
compiler/amxxpc/amxxpc.sln
Executable file
@ -0,0 +1,21 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 8.00
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "amxxpc", "amxxpc.vcproj", "{39412290-D01C-472F-A439-AB5592A04C08}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
Release = Release
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfiguration) = postSolution
|
||||
{39412290-D01C-472F-A439-AB5592A04C08}.Debug.ActiveCfg = Debug|Win32
|
||||
{39412290-D01C-472F-A439-AB5592A04C08}.Debug.Build.0 = Debug|Win32
|
||||
{39412290-D01C-472F-A439-AB5592A04C08}.Release.ActiveCfg = Release|Win32
|
||||
{39412290-D01C-472F-A439-AB5592A04C08}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||
EndGlobalSection
|
||||
EndGlobal
|
174
compiler/amxxpc/amxxpc.vcproj
Executable file
174
compiler/amxxpc/amxxpc.vcproj
Executable file
@ -0,0 +1,174 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="amxxpc"
|
||||
ProjectGUID="{39412290-D01C-472F-A439-AB5592A04C08}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="Debug"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="5"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="zlib.lib"
|
||||
OutputFile="$(OutDir)/amxxpc.exe"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/amxxpc.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="Release"
|
||||
IntermediateDirectory="Release"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="4"
|
||||
StructMemberAlignment="0"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="FALSE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="zlib.lib"
|
||||
OutputFile="$(OutDir)/amxxpc.exe"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
||||
<File
|
||||
RelativePath=".\amx.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\amxxpc.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Binary.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
|
||||
<File
|
||||
RelativePath=".\amx.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\amxdbg.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\amxxpc.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Binary.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\osdefs.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\resource.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\resource1.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\sclinux.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\zconf.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\zlib.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
|
||||
<File
|
||||
RelativePath=".\amxxpc1.rc">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
72
compiler/amxxpc/amxxpc1.rc
Executable file
72
compiler/amxxpc/amxxpc1.rc
Executable file
@ -0,0 +1,72 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource1.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource1.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
1 ICON "favicon.ico"
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
BIN
compiler/amxxpc/favicon.ico
Executable file
BIN
compiler/amxxpc/favicon.ico
Executable file
Binary file not shown.
After Width: | Height: | Size: 766 B |
15
compiler/amxxpc/getch.h
Executable file
15
compiler/amxxpc/getch.h
Executable file
@ -0,0 +1,15 @@
|
||||
/* Extremely inefficient but portable POSIX getch(), see getch.c */
|
||||
#ifndef GETCH_H
|
||||
#define GETCH_H
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
int getch(void);
|
||||
int kbhit(void);
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GETCH_H */
|
BIN
compiler/amxxpc/libz.a
Executable file
BIN
compiler/amxxpc/libz.a
Executable file
Binary file not shown.
60
compiler/amxxpc/osdefs.h
Executable file
60
compiler/amxxpc/osdefs.h
Executable file
@ -0,0 +1,60 @@
|
||||
/* __MSDOS__ set when compiling for DOS (not Windows)
|
||||
* _Windows set when compiling for any version of Microsoft Windows
|
||||
* __WIN32__ set when compiling for Windows95 or WindowsNT (32 bit mode)
|
||||
* __32BIT__ set when compiling in 32-bit "flat" mode (DOS or Windows)
|
||||
*
|
||||
* Copyright 1998-2002, ITB CompuPhase, The Netherlands.
|
||||
* info@compuphase.com.
|
||||
*/
|
||||
|
||||
#ifndef _OSDEFS_H
|
||||
#define _OSDEFS_H
|
||||
|
||||
/* Every compiler uses different "default" macros to indicate the mode
|
||||
* it is in. Throughout the source, we use the Borland C++ macros, so
|
||||
* the macros of Watcom C/C++ and Microsoft Visual C/C++ are mapped to
|
||||
* those of Borland C++.
|
||||
*/
|
||||
#if defined(__WATCOMC__)
|
||||
# if defined(__WINDOWS__) || defined(__NT__)
|
||||
# define _Windows 1
|
||||
# endif
|
||||
# ifdef __386__
|
||||
# define __32BIT__ 1
|
||||
# endif
|
||||
# if defined(_Windows) && defined(__32BIT__)
|
||||
# define __WIN32__ 1
|
||||
# endif
|
||||
#elif defined(_MSC_VER)
|
||||
# if defined(_WINDOWS) || defined(_WIN32)
|
||||
# define _Windows 1
|
||||
# endif
|
||||
# ifdef _WIN32
|
||||
# define __WIN32__ 1
|
||||
# define __32BIT__ 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined __linux__
|
||||
#include <endian.h>
|
||||
#endif
|
||||
|
||||
/* Linux NOW has these */
|
||||
#if !defined BIG_ENDIAN
|
||||
#define BIG_ENDIAN 4321
|
||||
#endif
|
||||
#if !defined LITTLE_ENDIAN
|
||||
#define LITTLE_ENDIAN 1234
|
||||
#endif
|
||||
|
||||
/* educated guess, BYTE_ORDER is undefined, i386 is common => little endian */
|
||||
#if !defined BYTE_ORDER
|
||||
#if defined UCLINUX
|
||||
#define BYTE_ORDER BIG_ENDIAN
|
||||
#else
|
||||
#define BYTE_ORDER LITTLE_ENDIAN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* _OSDEFS_H */
|
||||
|
17
compiler/amxxpc/resource.h
Executable file
17
compiler/amxxpc/resource.h
Executable file
@ -0,0 +1,17 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by amxxsc.rc
|
||||
//
|
||||
#define ICON 5
|
||||
#define IDI_ICON1 104
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 105
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
16
compiler/amxxpc/resource1.h
Executable file
16
compiler/amxxpc/resource1.h
Executable file
@ -0,0 +1,16 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by amxxsc1.rc
|
||||
//
|
||||
#define IDI_ICON1 101
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 102
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
47
compiler/amxxpc/sclinux.h
Executable file
47
compiler/amxxpc/sclinux.h
Executable file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Things needed to compile under linux.
|
||||
*
|
||||
* Should be reworked totally to use GNU's 'configure'
|
||||
*/
|
||||
#ifndef SCLINUX_H
|
||||
#define SCLINUX_H
|
||||
|
||||
/* getchar() is not a 'cool' replacement for MSDOS getch: Linux/unix depends on the features activated or not about the
|
||||
* controlling terminal's tty. This means that ioctl(2) calls must be performed, for instance to have the controlling
|
||||
* terminal tty's in 'raw' mode, if we want to be able to fetch a single character. This also means that everything must
|
||||
* be put back correctly when the function ends. See GETCH.C for an implementation.
|
||||
*
|
||||
* For interactive use of SRUN/SDBG if would be much better to use GNU's readline package: the user would be able to
|
||||
* have a complete emacs/vi like line editing system.
|
||||
*/
|
||||
#include "getch.h"
|
||||
|
||||
#define stricmp(a,b) strcasecmp(a,b)
|
||||
#define strnicmp(a,b,c) strncasecmp(a,b,c)
|
||||
|
||||
/*
|
||||
* WinWorld wants '\'. Unices do not.
|
||||
*/
|
||||
#define DIRECTORY_SEP_CHAR '/'
|
||||
#define DIRECTORY_SEP_STR "/"
|
||||
|
||||
/*
|
||||
* SC assumes that a computer is Little Endian unless told otherwise. It uses
|
||||
* (and defines) the macros BYTE_ORDER and BIG_ENDIAN.
|
||||
* For Linux, we must overrule these settings with those defined in glibc.
|
||||
*/
|
||||
#if !defined __BYTE_ORDER
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#if defined __OpenBSD__ || defined __FreeBSD__
|
||||
# define __BYTE_ORDER BYTE_ORDER
|
||||
# define __LITTLE_ENDIAN LITTLE_ENDIAN
|
||||
# define __BIG_ENDIAN BIG_ENDIAN
|
||||
#endif
|
||||
|
||||
#if !defined __BYTE_ORDER
|
||||
# error "Can't figure computer byte order (__BYTE_ORDER macro not found)"
|
||||
#endif
|
||||
|
||||
#endif /* SCLINUX_H */
|
155
compiler/amxxpc/testmini.c
Executable file
155
compiler/amxxpc/testmini.c
Executable file
@ -0,0 +1,155 @@
|
||||
/* testmini.c -- very simple test program for the miniLZO library
|
||||
|
||||
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
|
||||
<markus@oberhumer.com>
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// This program shows the basic usage of the LZO library.
|
||||
// We will compress a block of data and decompress again.
|
||||
//
|
||||
// For more information, documentation, example programs and other support
|
||||
// files (like Makefiles and build scripts) please download the full LZO
|
||||
// package from
|
||||
// http://www.oberhumer.com/opensource/lzo/
|
||||
**************************************************************************/
|
||||
|
||||
/* First let's include "minizo.h". */
|
||||
|
||||
#include "minilzo.h"
|
||||
|
||||
|
||||
/* We want to compress the data block at `in' with length `IN_LEN' to
|
||||
* the block at `out'. Because the input block may be incompressible,
|
||||
* we must provide a little more output space in case that compression
|
||||
* is not possible.
|
||||
*/
|
||||
|
||||
#if defined(__LZO_STRICT_16BIT)
|
||||
#define IN_LEN (8*1024)
|
||||
#else
|
||||
#define IN_LEN (128*1024L)
|
||||
#endif
|
||||
#define OUT_LEN (IN_LEN + IN_LEN / 64 + 16 + 3)
|
||||
|
||||
static lzo_byte in [ IN_LEN ];
|
||||
static lzo_byte out [ OUT_LEN ];
|
||||
|
||||
|
||||
/* Work-memory needed for compression. Allocate memory in units
|
||||
* of `lzo_align_t' (instead of `char') to make sure it is properly aligned.
|
||||
*/
|
||||
|
||||
#define HEAP_ALLOC(var,size) \
|
||||
lzo_align_t __LZO_MMODEL var [ ((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t) ]
|
||||
|
||||
static HEAP_ALLOC(wrkmem,LZO1X_1_MEM_COMPRESS);
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int r;
|
||||
lzo_uint in_len;
|
||||
lzo_uint out_len;
|
||||
lzo_uint new_len;
|
||||
|
||||
#if defined(__EMX__)
|
||||
_response(&argc,&argv);
|
||||
_wildcard(&argc,&argv);
|
||||
#endif
|
||||
|
||||
if (argc < 0 && argv == NULL) /* avoid warning about unused args */
|
||||
return 0;
|
||||
|
||||
printf("\nLZO real-time data compression library (v%s, %s).\n",
|
||||
lzo_version_string(), lzo_version_date());
|
||||
printf("Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer\n\n");
|
||||
|
||||
|
||||
/*
|
||||
* Step 1: initialize the LZO library
|
||||
*/
|
||||
if (lzo_init() != LZO_E_OK)
|
||||
{
|
||||
printf("lzo_init() failed !!!\n");
|
||||
return 3;
|
||||
}
|
||||
|
||||
/*
|
||||
* Step 2: prepare the input block that will get compressed.
|
||||
* We just fill it with zeros in this example program,
|
||||
* but you would use your real-world data here.
|
||||
*/
|
||||
in_len = IN_LEN;
|
||||
lzo_memset(in,0,in_len);
|
||||
|
||||
/*
|
||||
* Step 3: compress from `in' to `out' with LZO1X-1
|
||||
*/
|
||||
r = lzo1x_1_compress(in,in_len,out,&out_len,wrkmem);
|
||||
if (r == LZO_E_OK)
|
||||
printf("compressed %lu bytes into %lu bytes\n",
|
||||
(long) in_len, (long) out_len);
|
||||
else
|
||||
{
|
||||
/* this should NEVER happen */
|
||||
printf("internal error - compression failed: %d\n", r);
|
||||
return 2;
|
||||
}
|
||||
/* check for an incompressible block */
|
||||
if (out_len >= in_len)
|
||||
{
|
||||
printf("This block contains incompressible data.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Step 4: decompress again, now going from `out' to `in'
|
||||
*/
|
||||
r = lzo1x_decompress(out,out_len,in,&new_len,NULL);
|
||||
if (r == LZO_E_OK && new_len == in_len)
|
||||
printf("decompressed %lu bytes back into %lu bytes\n",
|
||||
(long) out_len, (long) in_len);
|
||||
else
|
||||
{
|
||||
/* this should NEVER happen */
|
||||
printf("internal error - decompression failed: %d\n", r);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("\nminiLZO simple compression test passed.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
vi:ts=4
|
||||
*/
|
||||
|
323
compiler/amxxpc/zconf.h
Executable file
323
compiler/amxxpc/zconf.h
Executable file
@ -0,0 +1,323 @@
|
||||
/* zconf.h -- configuration of the zlib compression library
|
||||
* Copyright (C) 1995-2003 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#ifndef ZCONF_H
|
||||
#define ZCONF_H
|
||||
|
||||
/*
|
||||
* If you *really* need a unique prefix for all types and library functions,
|
||||
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
|
||||
*/
|
||||
#ifdef Z_PREFIX
|
||||
# define deflateInit_ z_deflateInit_
|
||||
# define deflate z_deflate
|
||||
# define deflateEnd z_deflateEnd
|
||||
# define inflateInit_ z_inflateInit_
|
||||
# define inflate z_inflate
|
||||
# define inflateEnd z_inflateEnd
|
||||
# define deflateInit2_ z_deflateInit2_
|
||||
# define deflateSetDictionary z_deflateSetDictionary
|
||||
# define deflateCopy z_deflateCopy
|
||||
# define deflateReset z_deflateReset
|
||||
# define deflatePrime z_deflatePrime
|
||||
# define deflateParams z_deflateParams
|
||||
# define deflateBound z_deflateBound
|
||||
# define inflateInit2_ z_inflateInit2_
|
||||
# define inflateSetDictionary z_inflateSetDictionary
|
||||
# define inflateSync z_inflateSync
|
||||
# define inflateSyncPoint z_inflateSyncPoint
|
||||
# define inflateCopy z_inflateCopy
|
||||
# define inflateReset z_inflateReset
|
||||
# define compress z_compress
|
||||
# define compress2 z_compress2
|
||||
# define compressBound z_compressBound
|
||||
# define uncompress z_uncompress
|
||||
# define adler32 z_adler32
|
||||
# define crc32 z_crc32
|
||||
# define get_crc_table z_get_crc_table
|
||||
|
||||
# define Byte z_Byte
|
||||
# define uInt z_uInt
|
||||
# define uLong z_uLong
|
||||
# define Bytef z_Bytef
|
||||
# define charf z_charf
|
||||
# define intf z_intf
|
||||
# define uIntf z_uIntf
|
||||
# define uLongf z_uLongf
|
||||
# define voidpf z_voidpf
|
||||
# define voidp z_voidp
|
||||
#endif
|
||||
|
||||
#if defined(__MSDOS__) && !defined(MSDOS)
|
||||
# define MSDOS
|
||||
#endif
|
||||
#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
|
||||
# define OS2
|
||||
#endif
|
||||
#if defined(_WINDOWS) && !defined(WINDOWS)
|
||||
# define WINDOWS
|
||||
#endif
|
||||
#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
|
||||
# define WIN32
|
||||
#endif
|
||||
#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
|
||||
# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
|
||||
# ifndef SYS16BIT
|
||||
# define SYS16BIT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more
|
||||
* than 64k bytes at a time (needed on systems with 16-bit int).
|
||||
*/
|
||||
#ifdef SYS16BIT
|
||||
# define MAXSEG_64K
|
||||
#endif
|
||||
#ifdef MSDOS
|
||||
# define UNALIGNED_OK
|
||||
#endif
|
||||
|
||||
#ifdef __STDC_VERSION__
|
||||
# ifndef STDC
|
||||
# define STDC
|
||||
# endif
|
||||
# if __STDC_VERSION__ >= 199901L
|
||||
# ifndef STDC99
|
||||
# define STDC99
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
|
||||
# define STDC
|
||||
#endif
|
||||
|
||||
#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
|
||||
# define STDC
|
||||
#endif
|
||||
|
||||
#ifndef STDC
|
||||
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
|
||||
# define const /* note: need a more gentle solution here */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Some Mac compilers merge all .h files incorrectly: */
|
||||
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
|
||||
# define NO_DUMMY_DECL
|
||||
#endif
|
||||
|
||||
/* Maximum value for memLevel in deflateInit2 */
|
||||
#ifndef MAX_MEM_LEVEL
|
||||
# ifdef MAXSEG_64K
|
||||
# define MAX_MEM_LEVEL 8
|
||||
# else
|
||||
# define MAX_MEM_LEVEL 9
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
|
||||
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
|
||||
* created by gzip. (Files created by minigzip can still be extracted by
|
||||
* gzip.)
|
||||
*/
|
||||
#ifndef MAX_WBITS
|
||||
# define MAX_WBITS 15 /* 32K LZ77 window */
|
||||
#endif
|
||||
|
||||
/* The memory requirements for deflate are (in bytes):
|
||||
(1 << (windowBits+2)) + (1 << (memLevel+9))
|
||||
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
|
||||
plus a few kilobytes for small objects. For example, if you want to reduce
|
||||
the default memory requirements from 256K to 128K, compile with
|
||||
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
|
||||
Of course this will generally degrade compression (there's no free lunch).
|
||||
|
||||
The memory requirements for inflate are (in bytes) 1 << windowBits
|
||||
that is, 32K for windowBits=15 (default value) plus a few kilobytes
|
||||
for small objects.
|
||||
*/
|
||||
|
||||
/* Type declarations */
|
||||
|
||||
#ifndef OF /* function prototypes */
|
||||
# ifdef STDC
|
||||
# define OF(args) args
|
||||
# else
|
||||
# define OF(args) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The following definitions for FAR are needed only for MSDOS mixed
|
||||
* model programming (small or medium model with some far allocations).
|
||||
* This was tested only with MSC; for other MSDOS compilers you may have
|
||||
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
|
||||
* just define FAR to be empty.
|
||||
*/
|
||||
#ifdef SYS16BIT
|
||||
# if defined(M_I86SM) || defined(M_I86MM)
|
||||
/* MSC small or medium model */
|
||||
# define SMALL_MEDIUM
|
||||
# ifdef _MSC_VER
|
||||
# define FAR _far
|
||||
# else
|
||||
# define FAR far
|
||||
# endif
|
||||
# endif
|
||||
# if (defined(__SMALL__) || defined(__MEDIUM__))
|
||||
/* Turbo C small or medium model */
|
||||
# define SMALL_MEDIUM
|
||||
# ifdef __BORLANDC__
|
||||
# define FAR _far
|
||||
# else
|
||||
# define FAR far
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(WINDOWS) || defined(WIN32)
|
||||
/* If building or using zlib as a DLL, define ZLIB_DLL.
|
||||
* This is not mandatory, but it offers a little performance increase.
|
||||
*/
|
||||
# ifdef ZLIB_DLL
|
||||
# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
|
||||
# ifdef ZLIB_INTERNAL
|
||||
# define ZEXTERN extern __declspec(dllexport)
|
||||
# else
|
||||
# define ZEXTERN extern __declspec(dllimport)
|
||||
# endif
|
||||
# endif
|
||||
# endif /* ZLIB_DLL */
|
||||
/* If building or using zlib with the WINAPI/WINAPIV calling convention,
|
||||
* define ZLIB_WINAPI.
|
||||
* Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
|
||||
*/
|
||||
# ifdef ZLIB_WINAPI
|
||||
# ifdef FAR
|
||||
# undef FAR
|
||||
# endif
|
||||
# include <windows.h>
|
||||
/* No need for _export, use ZLIB.DEF instead. */
|
||||
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
|
||||
# define ZEXPORT WINAPI
|
||||
# ifdef WIN32
|
||||
# define ZEXPORTVA WINAPIV
|
||||
# else
|
||||
# define ZEXPORTVA FAR CDECL
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined (__BEOS__)
|
||||
# ifdef ZLIB_DLL
|
||||
# ifdef ZLIB_INTERNAL
|
||||
# define ZEXPORT __declspec(dllexport)
|
||||
# define ZEXPORTVA __declspec(dllexport)
|
||||
# else
|
||||
# define ZEXPORT __declspec(dllimport)
|
||||
# define ZEXPORTVA __declspec(dllimport)
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef ZEXTERN
|
||||
# define ZEXTERN extern
|
||||
#endif
|
||||
#ifndef ZEXPORT
|
||||
# define ZEXPORT
|
||||
#endif
|
||||
#ifndef ZEXPORTVA
|
||||
# define ZEXPORTVA
|
||||
#endif
|
||||
|
||||
#ifndef FAR
|
||||
# define FAR
|
||||
#endif
|
||||
|
||||
#if !defined(__MACTYPES__)
|
||||
typedef unsigned char Byte; /* 8 bits */
|
||||
#endif
|
||||
typedef unsigned int uInt; /* 16 bits or more */
|
||||
typedef unsigned long uLong; /* 32 bits or more */
|
||||
|
||||
#ifdef SMALL_MEDIUM
|
||||
/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
|
||||
# define Bytef Byte FAR
|
||||
#else
|
||||
typedef Byte FAR Bytef;
|
||||
#endif
|
||||
typedef char FAR charf;
|
||||
typedef int FAR intf;
|
||||
typedef uInt FAR uIntf;
|
||||
typedef uLong FAR uLongf;
|
||||
|
||||
#ifdef STDC
|
||||
typedef void const *voidpc;
|
||||
typedef void FAR *voidpf;
|
||||
typedef void *voidp;
|
||||
#else
|
||||
typedef Byte const *voidpc;
|
||||
typedef Byte FAR *voidpf;
|
||||
typedef Byte *voidp;
|
||||
#endif
|
||||
|
||||
#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
|
||||
# include <sys/types.h> /* for off_t */
|
||||
# include <unistd.h> /* for SEEK_* and off_t */
|
||||
# ifdef VMS
|
||||
# include <unixio.h> /* for off_t */
|
||||
# endif
|
||||
# define z_off_t off_t
|
||||
#endif
|
||||
#ifndef SEEK_SET
|
||||
# define SEEK_SET 0 /* Seek from beginning of file. */
|
||||
# define SEEK_CUR 1 /* Seek from current position. */
|
||||
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
|
||||
#endif
|
||||
#ifndef z_off_t
|
||||
# define z_off_t long
|
||||
#endif
|
||||
|
||||
#if defined(__OS400__)
|
||||
#define NO_vsnprintf
|
||||
#endif
|
||||
|
||||
#if defined(__MVS__)
|
||||
# define NO_vsnprintf
|
||||
# ifdef FAR
|
||||
# undef FAR
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* MVS linker does not support external names larger than 8 bytes */
|
||||
#if defined(__MVS__)
|
||||
# pragma map(deflateInit_,"DEIN")
|
||||
# pragma map(deflateInit2_,"DEIN2")
|
||||
# pragma map(deflateEnd,"DEEND")
|
||||
# pragma map(deflateBound,"DEBND")
|
||||
# pragma map(inflateInit_,"ININ")
|
||||
# pragma map(inflateInit2_,"ININ2")
|
||||
# pragma map(inflateEnd,"INEND")
|
||||
# pragma map(inflateSync,"INSY")
|
||||
# pragma map(inflateSetDictionary,"INSEDI")
|
||||
# pragma map(compressBound,"CMBND")
|
||||
# pragma map(inflate_table,"INTABL")
|
||||
# pragma map(inflate_fast,"INFA")
|
||||
# pragma map(inflate_copyright,"INCOPY")
|
||||
#endif
|
||||
|
||||
#endif /* ZCONF_H */
|
1200
compiler/amxxpc/zlib.h
Executable file
1200
compiler/amxxpc/zlib.h
Executable file
File diff suppressed because it is too large
Load Diff
BIN
compiler/amxxpc/zlib.lib
Executable file
BIN
compiler/amxxpc/zlib.lib
Executable file
Binary file not shown.
168
compiler/compile/compile.bdsproj
Executable file
168
compiler/compile/compile.bdsproj
Executable file
@ -0,0 +1,168 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<BorlandProject>
|
||||
<PersonalityInfo>
|
||||
<Option>
|
||||
<Option Name="Personality">Delphi.Personality</Option>
|
||||
<Option Name="ProjectType"></Option>
|
||||
<Option Name="Version">1.0</Option>
|
||||
<Option Name="GUID">{A176F16A-267E-409C-9712-094AB667FE16}</Option>
|
||||
</Option>
|
||||
</PersonalityInfo>
|
||||
<Delphi.Personality>
|
||||
<Source>
|
||||
<Source Name="MainSource">compile.dpr</Source>
|
||||
</Source>
|
||||
<FileVersion>
|
||||
<FileVersion Name="Version">7.0</FileVersion>
|
||||
</FileVersion>
|
||||
<Compiler>
|
||||
<Compiler Name="A">8</Compiler>
|
||||
<Compiler Name="B">0</Compiler>
|
||||
<Compiler Name="C">1</Compiler>
|
||||
<Compiler Name="D">1</Compiler>
|
||||
<Compiler Name="E">0</Compiler>
|
||||
<Compiler Name="F">0</Compiler>
|
||||
<Compiler Name="G">1</Compiler>
|
||||
<Compiler Name="H">1</Compiler>
|
||||
<Compiler Name="I">1</Compiler>
|
||||
<Compiler Name="J">0</Compiler>
|
||||
<Compiler Name="K">0</Compiler>
|
||||
<Compiler Name="L">1</Compiler>
|
||||
<Compiler Name="M">0</Compiler>
|
||||
<Compiler Name="N">1</Compiler>
|
||||
<Compiler Name="O">1</Compiler>
|
||||
<Compiler Name="P">1</Compiler>
|
||||
<Compiler Name="Q">0</Compiler>
|
||||
<Compiler Name="R">0</Compiler>
|
||||
<Compiler Name="S">0</Compiler>
|
||||
<Compiler Name="T">0</Compiler>
|
||||
<Compiler Name="U">0</Compiler>
|
||||
<Compiler Name="V">1</Compiler>
|
||||
<Compiler Name="W">0</Compiler>
|
||||
<Compiler Name="X">1</Compiler>
|
||||
<Compiler Name="Y">1</Compiler>
|
||||
<Compiler Name="Z">1</Compiler>
|
||||
<Compiler Name="ShowHints">True</Compiler>
|
||||
<Compiler Name="ShowWarnings">True</Compiler>
|
||||
<Compiler Name="UnitAliases">WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;</Compiler>
|
||||
<Compiler Name="NamespacePrefix"></Compiler>
|
||||
<Compiler Name="GenerateDocumentation">False</Compiler>
|
||||
<Compiler Name="DefaultNamespace"></Compiler>
|
||||
<Compiler Name="SymbolDeprecated">True</Compiler>
|
||||
<Compiler Name="SymbolLibrary">True</Compiler>
|
||||
<Compiler Name="SymbolPlatform">True</Compiler>
|
||||
<Compiler Name="SymbolExperimental">True</Compiler>
|
||||
<Compiler Name="UnitLibrary">True</Compiler>
|
||||
<Compiler Name="UnitPlatform">True</Compiler>
|
||||
<Compiler Name="UnitDeprecated">True</Compiler>
|
||||
<Compiler Name="UnitExperimental">True</Compiler>
|
||||
<Compiler Name="HResultCompat">True</Compiler>
|
||||
<Compiler Name="HidingMember">True</Compiler>
|
||||
<Compiler Name="HiddenVirtual">True</Compiler>
|
||||
<Compiler Name="Garbage">True</Compiler>
|
||||
<Compiler Name="BoundsError">True</Compiler>
|
||||
<Compiler Name="ZeroNilCompat">True</Compiler>
|
||||
<Compiler Name="StringConstTruncated">True</Compiler>
|
||||
<Compiler Name="ForLoopVarVarPar">True</Compiler>
|
||||
<Compiler Name="TypedConstVarPar">True</Compiler>
|
||||
<Compiler Name="AsgToTypedConst">True</Compiler>
|
||||
<Compiler Name="CaseLabelRange">True</Compiler>
|
||||
<Compiler Name="ForVariable">True</Compiler>
|
||||
<Compiler Name="ConstructingAbstract">True</Compiler>
|
||||
<Compiler Name="ComparisonFalse">True</Compiler>
|
||||
<Compiler Name="ComparisonTrue">True</Compiler>
|
||||
<Compiler Name="ComparingSignedUnsigned">True</Compiler>
|
||||
<Compiler Name="CombiningSignedUnsigned">True</Compiler>
|
||||
<Compiler Name="UnsupportedConstruct">True</Compiler>
|
||||
<Compiler Name="FileOpen">True</Compiler>
|
||||
<Compiler Name="FileOpenUnitSrc">True</Compiler>
|
||||
<Compiler Name="BadGlobalSymbol">True</Compiler>
|
||||
<Compiler Name="DuplicateConstructorDestructor">True</Compiler>
|
||||
<Compiler Name="InvalidDirective">True</Compiler>
|
||||
<Compiler Name="PackageNoLink">True</Compiler>
|
||||
<Compiler Name="PackageThreadVar">True</Compiler>
|
||||
<Compiler Name="ImplicitImport">True</Compiler>
|
||||
<Compiler Name="HPPEMITIgnored">True</Compiler>
|
||||
<Compiler Name="NoRetVal">True</Compiler>
|
||||
<Compiler Name="UseBeforeDef">True</Compiler>
|
||||
<Compiler Name="ForLoopVarUndef">True</Compiler>
|
||||
<Compiler Name="UnitNameMismatch">True</Compiler>
|
||||
<Compiler Name="NoCFGFileFound">True</Compiler>
|
||||
<Compiler Name="MessageDirective">True</Compiler>
|
||||
<Compiler Name="ImplicitVariants">True</Compiler>
|
||||
<Compiler Name="UnicodeToLocale">True</Compiler>
|
||||
<Compiler Name="LocaleToUnicode">True</Compiler>
|
||||
<Compiler Name="ImagebaseMultiple">True</Compiler>
|
||||
<Compiler Name="SuspiciousTypecast">True</Compiler>
|
||||
<Compiler Name="PrivatePropAccessor">True</Compiler>
|
||||
<Compiler Name="UnsafeType">False</Compiler>
|
||||
<Compiler Name="UnsafeCode">False</Compiler>
|
||||
<Compiler Name="UnsafeCast">False</Compiler>
|
||||
<Compiler Name="OptionTruncated">True</Compiler>
|
||||
<Compiler Name="WideCharReduced">True</Compiler>
|
||||
<Compiler Name="DuplicatesIgnored">True</Compiler>
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Linker Name="MapFile">0</Linker>
|
||||
<Linker Name="OutputObjs">0</Linker>
|
||||
<Linker Name="ConsoleApp">1</Linker>
|
||||
<Linker Name="DebugInfo">False</Linker>
|
||||
<Linker Name="RemoteSymbols">False</Linker>
|
||||
<Linker Name="GenerateDRC">False</Linker>
|
||||
<Linker Name="MinStackSize">16384</Linker>
|
||||
<Linker Name="MaxStackSize">1048576</Linker>
|
||||
<Linker Name="ImageBase">4194304</Linker>
|
||||
<Linker Name="ExeDescription"></Linker>
|
||||
</Linker>
|
||||
<Directories>
|
||||
<Directories Name="OutputDir"></Directories>
|
||||
<Directories Name="UnitOutputDir"></Directories>
|
||||
<Directories Name="PackageDLLOutputDir"></Directories>
|
||||
<Directories Name="PackageDCPOutputDir"></Directories>
|
||||
<Directories Name="SearchPath"></Directories>
|
||||
<Directories Name="Packages"></Directories>
|
||||
<Directories Name="Conditionals"></Directories>
|
||||
<Directories Name="DebugSourceDirs"></Directories>
|
||||
<Directories Name="UsePackages">False</Directories>
|
||||
</Directories>
|
||||
<Parameters>
|
||||
<Parameters Name="RunParams"></Parameters>
|
||||
<Parameters Name="HostApplication"></Parameters>
|
||||
<Parameters Name="Launcher"></Parameters>
|
||||
<Parameters Name="UseLauncher">False</Parameters>
|
||||
<Parameters Name="DebugCWD"></Parameters>
|
||||
<Parameters Name="RemoteHost"></Parameters>
|
||||
<Parameters Name="RemotePath"></Parameters>
|
||||
<Parameters Name="RemoteLauncher"></Parameters>
|
||||
<Parameters Name="RemoteCWD"></Parameters>
|
||||
<Parameters Name="RemoteDebug">False</Parameters>
|
||||
</Parameters>
|
||||
<VersionInfo>
|
||||
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
|
||||
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
|
||||
<VersionInfo Name="MajorVer">1</VersionInfo>
|
||||
<VersionInfo Name="MinorVer">0</VersionInfo>
|
||||
<VersionInfo Name="Release">0</VersionInfo>
|
||||
<VersionInfo Name="Build">0</VersionInfo>
|
||||
<VersionInfo Name="Debug">False</VersionInfo>
|
||||
<VersionInfo Name="PreRelease">False</VersionInfo>
|
||||
<VersionInfo Name="Special">False</VersionInfo>
|
||||
<VersionInfo Name="Private">False</VersionInfo>
|
||||
<VersionInfo Name="DLL">False</VersionInfo>
|
||||
<VersionInfo Name="Locale">1031</VersionInfo>
|
||||
<VersionInfo Name="CodePage">1252</VersionInfo>
|
||||
</VersionInfo>
|
||||
<VersionInfoKeys>
|
||||
<VersionInfoKeys Name="CompanyName"></VersionInfoKeys>
|
||||
<VersionInfoKeys Name="FileDescription"></VersionInfoKeys>
|
||||
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
|
||||
<VersionInfoKeys Name="InternalName"></VersionInfoKeys>
|
||||
<VersionInfoKeys Name="LegalCopyright"></VersionInfoKeys>
|
||||
<VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys>
|
||||
<VersionInfoKeys Name="OriginalFilename"></VersionInfoKeys>
|
||||
<VersionInfoKeys Name="ProductName"></VersionInfoKeys>
|
||||
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
|
||||
<VersionInfoKeys Name="Comments"></VersionInfoKeys>
|
||||
</VersionInfoKeys>
|
||||
</Delphi.Personality>
|
||||
</BorlandProject>
|
@ -43,13 +43,13 @@ var
|
||||
sr: TSearchRec;
|
||||
i: Word;
|
||||
begin
|
||||
WriteLn('//AMXXSC compile.exe');
|
||||
WriteLn('//AMXXPC compile.exe');
|
||||
WriteLn('// by the AMX Mod X Dev Team');
|
||||
WriteLn;
|
||||
|
||||
if not FileExists(ExtractFilePath(ParamStr(0))+'amxxsc.exe') then
|
||||
if not FileExists(ExtractFilePath(ParamStr(0))+COMPILER_EXE) then
|
||||
begin
|
||||
WriteLn('// Could not find amxxsc.exe');
|
||||
WriteLn('// Could not find '+COMPILER_EXE);
|
||||
AppExit;
|
||||
end;
|
||||
|
||||
|
BIN
compiler/compile/compile.exe
Executable file
BIN
compiler/compile/compile.exe
Executable file
Binary file not shown.
BIN
compiler/compile/icon.res
Executable file
BIN
compiler/compile/icon.res
Executable file
Binary file not shown.
@ -36,6 +36,9 @@ interface
|
||||
uses
|
||||
Windows, SysUtils, Classes, Math, IniFiles;
|
||||
|
||||
resourcestring
|
||||
COMPILER_EXE = 'amxxpc.exe';
|
||||
|
||||
procedure AppExit;
|
||||
procedure CompilePlugin(const Name: String);
|
||||
function GetAgeFromDat(const FileName: String): Integer;
|
||||
@ -79,7 +82,7 @@ begin
|
||||
|
||||
try
|
||||
cStart := GetTickCount;
|
||||
if not GetConsoleOutput(ExtractFilePath(ParamStr(0))+'amxxsc.exe "'+FilePath+FileName+'" "-o'+Compiled+'"',Output) then
|
||||
if not GetConsoleOutput(ExtractFilePath(ParamStr(0))+COMPILER_EXE+' "'+FilePath+FileName+'" "-o'+Compiled+'"',Output) then
|
||||
begin
|
||||
WriteLn('// Internal error.');
|
||||
AppExit;
|
||||
|
@ -1,7 +1,7 @@
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
|
||||
FILEVERSION 0,2,0,0
|
||||
PRODUCTVERSION 0,2,0,0
|
||||
FILEVERSION 1,5,0,0
|
||||
PRODUCTVERSION 1,5,0,0
|
||||
FILEOS VOS__WINDOWS32
|
||||
FILETYPE VFT_APP // VFT_APP VFT_DLL
|
||||
//FILEFLGAGS:
|
||||
@ -12,17 +12,17 @@ BEGIN
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "AMXXSC compile.exe\0"
|
||||
VALUE "Comments", "AMXXPC compile.exe\0"
|
||||
//VALUE "CompanyName", "AMXX Development Team\0"
|
||||
VALUE "FileDescription", "AMXXSC compile.exe\0"
|
||||
VALUE "FileVersion", "0.20\0"
|
||||
VALUE "InternalName", "AMXXSC compile.exe\0"
|
||||
VALUE "LegalCopyright", "(c) 2004, AMXX Development Team\0"
|
||||
VALUE "FileDescription", "AMXXPC compile.exe\0"
|
||||
VALUE "FileVersion", "1.5\0"
|
||||
VALUE "InternalName", "AMXXPC compile.exe\0"
|
||||
VALUE "LegalCopyright", "(c) 2004-2005, AMXX Development Team\0"
|
||||
//VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "compile.exe\0"
|
||||
//VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "AMXXSC compile.exe\0"
|
||||
VALUE "ProductVersion", "0.20\0"
|
||||
VALUE "ProductName", "AMXXPC compile.exe\0"
|
||||
VALUE "ProductVersion", "1.5\0"
|
||||
//VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user