Compare commits
606
Commits
softwarecrap
...
neo-kart
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1bd901cee0 | ||
|
|
bf35469684 | ||
|
|
60f29edbca | ||
|
|
60cffe1ed1 | ||
|
|
e77e7d1643 | ||
|
|
5dc22f502e | ||
|
|
7a309c1175 | ||
|
|
9ce5baad9e | ||
|
|
a4aa9a76f2 | ||
|
|
befa25de5c | ||
|
|
83175d5c09 | ||
|
|
d8df8e8778 | ||
|
|
09957d0279 | ||
|
|
9e44985f56 | ||
|
|
b657a84699 | ||
|
|
5ec7835556 | ||
|
|
03a864156d | ||
|
|
c823bf3320 | ||
|
|
4f4d2f1f4c | ||
|
|
1bb389052d | ||
|
|
31fdc5bbc1 | ||
|
|
db3833430d | ||
|
|
6d2212d259 | ||
|
|
83b62e7f53 | ||
|
|
e5b5b53ede | ||
|
|
912c0e7fc4 | ||
|
|
43d232819a | ||
|
|
302eaf60b5 | ||
|
|
84535faa90 | ||
|
|
8c55d3c705 | ||
|
|
75b4b10caa | ||
|
|
1732e927c1 | ||
|
|
ec11b9268f | ||
|
|
a45af4a80c | ||
|
|
df627b6830 | ||
|
|
dfbeaf30ad | ||
|
|
a03f74b125 | ||
|
|
1a01f1299c | ||
|
|
fc5cab4b62 | ||
|
|
c7fcf814ef | ||
|
|
91f0cdbaca | ||
|
|
e50bd4125d | ||
|
|
ded2c8a7c8 | ||
|
|
88ce9fc0a6 | ||
|
|
3c713248b3 | ||
|
|
75f3edcd92 | ||
|
|
081a7779a6 | ||
|
|
6e995207a6 | ||
|
|
3492b77aa0 | ||
|
|
e864901035 | ||
|
|
7ee6de6b6a | ||
|
|
914fed4a1a | ||
|
|
6b1e9751a6 | ||
|
|
afa41fa88e | ||
|
|
53010deb8b | ||
|
|
785c33f5a8 | ||
|
|
dbdbe95164 | ||
|
|
5b7720fe65 | ||
|
|
332369a910 | ||
|
|
b92d3dd7ae | ||
|
|
91c943263e | ||
|
|
3a0419703d | ||
|
|
47011c8e07 | ||
|
|
a0035f6258 | ||
|
|
528ae085e6 | ||
|
|
553b8ccf6b | ||
|
|
bceef0b861 | ||
|
|
53cce6c6bb | ||
|
|
b95047d09f | ||
|
|
c6cb4375f5 | ||
|
|
a07e2b8eda | ||
|
|
98e7002167 | ||
|
|
3428dde3c6 | ||
|
|
13d48f982b | ||
|
|
b2e4dc27e4 | ||
|
|
deddeab049 | ||
|
|
c3a6410822 | ||
|
|
c5915091aa | ||
|
|
4401f0659e | ||
|
|
a0c72d32e8 | ||
|
|
1493045ec4 | ||
|
|
210efb2be7 | ||
|
|
a02fc1de63 | ||
|
|
7755bfc861 | ||
|
|
01172bca77 | ||
|
|
143cbc8587 | ||
|
|
b65f655a8a | ||
|
|
ed04c86369 | ||
|
|
c0eaa17eb3 | ||
|
|
6383a55038 | ||
|
|
574df60d58 | ||
|
|
61ee575cd3 | ||
|
|
bdd963081e | ||
|
|
6b908d7a14 | ||
|
|
7d0d70c094 | ||
|
|
e75c5a9248 | ||
|
|
b8ed5f4f1a | ||
|
|
660d7060e4 | ||
|
|
79c5f57714 | ||
|
|
606d8fbe55 | ||
|
|
edfa116a40 | ||
|
|
55ca0c712f | ||
|
|
16bef488ee | ||
|
|
82d784d9f8 | ||
|
|
103fb2dfc1 | ||
|
|
bba3e1810b | ||
|
|
af5333f63e | ||
|
|
ea77a5fb53 | ||
|
|
a4aef0894b | ||
|
|
bab7972518 | ||
|
|
88853a7aee | ||
|
|
d3339df853 | ||
|
|
385614b448 | ||
|
|
c47ba80f5d | ||
|
|
6de0700f49 | ||
|
|
d9fe52b1a1 | ||
|
|
ccfc476ec0 | ||
|
|
f518b3c48b | ||
|
|
81d52db722 | ||
|
|
df9973da99 | ||
|
|
ca4c779c66 | ||
|
|
7897352175 | ||
|
|
e0e75eac33 | ||
|
|
31d83dd26e | ||
|
|
698a0b811f | ||
|
|
f69609b403 | ||
|
|
56259e3476 | ||
|
|
f3dfa53f31 | ||
|
|
e10d60c08e | ||
|
|
ad4037351f | ||
|
|
f9e1da8c9f | ||
|
|
2f05137af7 | ||
|
|
c305e31c2e | ||
|
|
a55fabe4f9 | ||
|
|
c58848b298 | ||
|
|
ede644d3c4 | ||
|
|
4ff98e62a9 | ||
|
|
e87fd2fff6 | ||
|
|
33e8b10579 | ||
|
|
d11780f62d | ||
|
|
7706aa0bf0 | ||
|
|
cf96e10552 | ||
|
|
1d01e1e6cd | ||
|
|
a5c4759662 | ||
|
|
e7ff1d693b | ||
|
|
9b4354a057 | ||
|
|
51a46ba92c | ||
|
|
31c4e0d59f | ||
|
|
6b246548c3 | ||
|
|
57dda3843a | ||
|
|
b04ac14751 | ||
|
|
5ad8497db2 | ||
|
|
672f07a5ee | ||
|
|
aceffafc4e | ||
|
|
891b3183ed | ||
|
|
26dd066280 | ||
|
|
157ebdb5fe | ||
|
|
5d215ea633 | ||
|
|
e6adc50e2b | ||
|
|
913b374f9b | ||
|
|
9362d5abd4 | ||
|
|
2fb75f7739 | ||
|
|
1a18839f82 | ||
|
|
e7f8e7628f | ||
|
|
07190571a1 | ||
|
|
f04d922fca | ||
|
|
7fa382d4e9 | ||
|
|
97766710c0 | ||
|
|
994ee060a7 | ||
|
|
589c27fdcf | ||
|
|
37a018fda4 | ||
|
|
f49381d1c5 | ||
|
|
573095bbad | ||
|
|
0fdcc8e288 | ||
|
|
03d7e26c3d | ||
|
|
3a5cd835ad | ||
|
|
47a8f081e9 | ||
|
|
ad8d691c11 | ||
|
|
8186696e62 | ||
|
|
183ec22923 | ||
|
|
5376995350 | ||
|
|
acb6e30fad | ||
|
|
fe0dabb177 | ||
|
|
194ae46ce8 | ||
|
|
2e9f1bfe90 | ||
|
|
a82adc4948 | ||
|
|
6440c70a38 | ||
|
|
748eb07c9a | ||
|
|
5be2f591d2 | ||
|
|
f2e4950e89 | ||
|
|
7444c5b826 | ||
|
|
5f6cca68cc | ||
|
|
3d33e5351b | ||
|
|
c6e245450d | ||
|
|
36854a16b7 | ||
|
|
b4ee8229ee | ||
|
|
cf0a3841e8 | ||
|
|
3ebd2257f8 | ||
|
|
844d1967cc | ||
|
|
dac37f8938 | ||
|
|
dd74bc7c2b | ||
|
|
7eec58a834 | ||
|
|
da81998c71 | ||
|
|
d1552e7b71 | ||
|
|
c64e10083b | ||
|
|
43e2be58da | ||
|
|
63b60d2546 | ||
|
|
91ddc709eb | ||
|
|
1bcb67ffb9 | ||
|
|
976177c244 | ||
|
|
a37c81a142 | ||
|
|
58de3a35a0 | ||
|
|
44b8a8a0d8 | ||
|
|
b0f5f4338f | ||
|
|
6457847633 | ||
|
|
69d47a5e53 | ||
|
|
02177a7794 | ||
|
|
65c15126f1 | ||
|
|
76c78b8e63 | ||
|
|
f63342ff0f | ||
|
|
e3410cf34c | ||
|
|
7a129047e7 | ||
|
|
343716b7da | ||
|
|
1687fb9120 | ||
|
|
3e89057c23 | ||
|
|
774587efa6 | ||
|
|
2dc8bf321e | ||
|
|
992813d770 | ||
|
|
46882dee93 | ||
|
|
8bbb7b540f | ||
|
|
f5f1ab036d | ||
|
|
f15d556c05 | ||
|
|
570a664db8 | ||
|
|
52f69324d9 | ||
|
|
ea6016b1ba | ||
|
|
30fcffd63c | ||
|
|
50446bbde4 | ||
|
|
b307033aab | ||
|
|
3e5985833c | ||
|
|
8421f02aab | ||
|
|
b6daafec17 | ||
|
|
fc058b669e | ||
|
|
99214b98b9 | ||
|
|
ab35a44ed9 | ||
|
|
125b82a5bb | ||
|
|
f294ea157f | ||
|
|
486ae052ef | ||
|
|
53b5442dad | ||
|
|
507c5f75bd | ||
|
|
0fb72c579e | ||
|
|
c5d6ac63c5 | ||
|
|
a934c76263 | ||
|
|
0098c3bbc0 | ||
|
|
f3eedc03e6 | ||
|
|
17c71a2528 | ||
|
|
d2ecbd7c6e | ||
|
|
2ce7dc0c37 | ||
|
|
b648424c18 | ||
|
|
301754c857 | ||
|
|
c9a3c4c9b8 | ||
|
|
ce0c8b363a | ||
|
|
9d6c38004c | ||
|
|
19a58cc8c6 | ||
|
|
d855c39da2 | ||
|
|
03f4bfecc1 | ||
|
|
c8d9e4c7b3 | ||
|
|
cb2b8f2e7c | ||
|
|
0272dd4c24 | ||
|
|
3b327937c2 | ||
|
|
f8f2f17184 | ||
|
|
2efaebcf89 | ||
|
|
150c695979 | ||
|
|
6fe87ab05a | ||
|
|
f6613a5555 | ||
|
|
947d5c2739 | ||
|
|
1544706ff4 | ||
|
|
e121d1a8a1 | ||
|
|
badbdbf03f | ||
|
|
3b5495b53a | ||
|
|
545027ae64 | ||
|
|
91896433f8 | ||
|
|
a60074fc8a | ||
|
|
eb82aa14bb | ||
|
|
cb4b640730 | ||
|
|
266d9a3c71 | ||
|
|
7a5a704a15 | ||
|
|
29ed8de935 | ||
|
|
3418cab5de | ||
|
|
e2ce015d49 | ||
|
|
0d0ab3f414 | ||
|
|
22b5bcc7e1 | ||
|
|
34d5d73d7e | ||
|
|
7ae4441731 | ||
|
|
d0b7f6203c | ||
|
|
3757f3ae57 | ||
|
|
8f9366da5a | ||
|
|
b8e55f87a9 | ||
|
|
b469f70e02 | ||
|
|
6df69b24db | ||
|
|
0133a5eb23 | ||
|
|
86712c2c48 | ||
|
|
5195caa3c6 | ||
|
|
684ad38d4b | ||
|
|
c6d292a3d7 | ||
|
|
246414a735 | ||
|
|
429bcffaf8 | ||
|
|
d92e7b138c | ||
|
|
cd51ad2a25 | ||
|
|
8732825404 | ||
|
|
fc37cdcc95 | ||
|
|
2435ec9515 | ||
|
|
623fab8ea8 | ||
|
|
e063345c4b | ||
|
|
27533a1dcd | ||
|
|
d232e0e2c6 | ||
|
|
0475489e24 | ||
|
|
34b35db27f | ||
|
|
b47bc12e48 | ||
|
|
4d102dcf68 | ||
|
|
a8c9663200 | ||
|
|
57660cc5af | ||
|
|
c459e918af | ||
|
|
962abba1b2 | ||
|
|
5297d18f92 | ||
|
|
7853e48a6f | ||
|
|
303d87f69d | ||
|
|
9dcdc9500d | ||
|
|
7723bafff6 | ||
|
|
d74a89c6c1 | ||
|
|
cce443be0b | ||
|
|
81fa3d27bf | ||
|
|
493091cd66 | ||
|
|
c75f5ee961 | ||
|
|
083e0ca2e0 | ||
|
|
79bd89016c | ||
|
|
eca7e38763 | ||
|
|
b5cbfb970f | ||
|
|
74e1cafd9d | ||
|
|
ee7381b67d | ||
|
|
7f93bc305d | ||
|
|
c7931ca69c | ||
|
|
90f06a3289 | ||
|
|
0e344a7e02 | ||
|
|
3f91a4e908 | ||
|
|
fb443c58ab | ||
|
|
b233514b58 | ||
|
|
11615171d1 | ||
|
|
2df4738af2 | ||
|
|
9e62f5bd52 | ||
|
|
80349ae8ee | ||
|
|
06d51f2648 | ||
|
|
fcc810f703 | ||
|
|
d6d70e1525 | ||
|
|
e5f79e061c | ||
|
|
ad3c0a1ffd | ||
|
|
2ef935198a | ||
|
|
dc3b9c648a | ||
|
|
2d610d40b6 | ||
|
|
d2c686f48b | ||
|
|
5cafec3262 | ||
|
|
580c42d167 | ||
|
|
dcfec35e57 | ||
|
|
701bac6e11 | ||
|
|
0c46d593d8 | ||
|
|
b867de0667 | ||
|
|
e207b75c7a | ||
|
|
fc3df5bfe4 | ||
|
|
dfb05b9d39 | ||
|
|
19702daecd | ||
|
|
dde4b4df3b | ||
|
|
c070930a8c | ||
|
|
d36b5f7c59 | ||
|
|
0e517907ce | ||
|
|
739e9716ab | ||
|
|
0e5972d895 | ||
|
|
71975658ca | ||
|
|
6572e29a64 | ||
|
|
41b21c2a0c | ||
|
|
2b19d2e6de | ||
|
|
f99aa3459c | ||
|
|
5bce9d5abf | ||
|
|
abe102649e | ||
|
|
424fcdc63a | ||
|
|
a3fd451c74 | ||
|
|
731fd113d2 | ||
|
|
c9ca1bda5c | ||
|
|
58ea822050 | ||
|
|
671484d6f9 | ||
|
|
e6e74194bc | ||
|
|
04432c8368 | ||
|
|
6782876c0c | ||
|
|
4b09e92d7c | ||
|
|
3266f64fb9 | ||
|
|
2a9886e698 | ||
|
|
1319e3a811 | ||
|
|
6cbb40f874 | ||
|
|
07fd6a3ad4 | ||
|
|
8891869013 | ||
|
|
04fc735e12 | ||
|
|
7b9860f1be | ||
|
|
38f26a2bd8 | ||
|
|
a9750f8cff | ||
|
|
ad86e7f34a | ||
|
|
496435ef3b | ||
|
|
5275b31e7e | ||
|
|
e341991703 | ||
|
|
fb65496507 | ||
|
|
abe52ba440 | ||
|
|
ee5d097201 | ||
|
|
0ea182d04f | ||
|
|
8d737c96c9 | ||
|
|
5c93b90c2e | ||
|
|
41bee850da | ||
|
|
416c2a9e9d | ||
|
|
8fa9fccc79 | ||
|
|
c5a4071a06 | ||
|
|
930e48ad39 | ||
|
|
868678f321 | ||
|
|
8530b6512c | ||
|
|
2a5f487e5f | ||
|
|
141f6c51dc | ||
|
|
1fc9492b30 | ||
|
|
65782d3d75 | ||
|
|
b5cb6dfb9d | ||
|
|
6667e4b8bc | ||
|
|
5e2492a930 | ||
|
|
4f07372e0f | ||
|
|
80a1a97083 | ||
|
|
204476c55d | ||
|
|
8fab258778 | ||
|
|
12059955e5 | ||
|
|
3ca1f957ba | ||
|
|
b11362aec1 | ||
|
|
75630df10e | ||
|
|
4d93abb7ac | ||
|
|
731943f980 | ||
|
|
265dc1f296 | ||
|
|
c449ffcc98 | ||
|
|
34500d32d0 | ||
|
|
d3e5dfc346 | ||
|
|
8ed11107eb | ||
|
|
2f51108783 | ||
|
|
2667a66419 | ||
|
|
0fd073f2f0 | ||
|
|
840cf4e00a | ||
|
|
d5d99f94b7 | ||
|
|
dea19e4416 | ||
|
|
f7612d7398 | ||
|
|
e39182607e | ||
|
|
79f1febbce | ||
|
|
120def9676 | ||
|
|
82562bc20d | ||
|
|
1c51361120 | ||
|
|
c07e79deb7 | ||
|
|
81cb1111b4 | ||
|
|
369307181e | ||
|
|
7881e04e6b | ||
|
|
66a72eb1be | ||
|
|
ad77f11859 | ||
|
|
96d177876f | ||
|
|
dc7392f86b | ||
|
|
6f6252b6f8 | ||
|
|
20b32df2c6 | ||
|
|
d413d02bf7 | ||
|
|
426c0366cc | ||
|
|
d3d3655580 | ||
|
|
d4a011ee6d | ||
|
|
b08118734e | ||
|
|
41ee6de784 | ||
|
|
139d2e6be8 | ||
|
|
a866461b0a | ||
|
|
6f61331d46 | ||
|
|
7731ca9fb2 | ||
|
|
3de0c4f5d8 | ||
|
|
2e602f8861 | ||
|
|
1a7d92a082 | ||
|
|
5aa2a0c821 | ||
|
|
4f2328b8dc | ||
|
|
e929e524a3 | ||
|
|
e6b9f18d3d | ||
|
|
7f197ef84e | ||
|
|
a9d7ca3332 | ||
|
|
a65e586de5 | ||
|
|
7072a50060 | ||
|
|
fc1a367c2e | ||
|
|
3b376d85d4 | ||
|
|
9aca8438a2 | ||
|
|
c2d37dfb61 | ||
|
|
3c3bd0f0ea | ||
|
|
958db336b7 | ||
|
|
342d570b3b | ||
|
|
67457c25df | ||
|
|
a98d46f8a8 | ||
|
|
b2fca84b15 | ||
|
|
2e31169738 | ||
|
|
4cda2c8093 | ||
|
|
73b4e8a988 | ||
|
|
82dbfb4379 | ||
|
|
0e2ff2390a | ||
|
|
220d5db739 | ||
|
|
212d475f50 | ||
|
|
b7fbd0433f | ||
|
|
d28dd96aa0 | ||
|
|
0e46f91c51 | ||
|
|
d6dabacb05 | ||
|
|
4363473955 | ||
|
|
7e5fd4e290 | ||
|
|
191dfbe1bd | ||
|
|
c30a0cd4f1 | ||
|
|
8b06822092 | ||
|
|
98d56a38f5 | ||
|
|
e4bef0e3f4 | ||
|
|
f26e95e7c9 | ||
|
|
c755a4d8b6 | ||
|
|
f39e1a9b70 | ||
|
|
1d5b531ba3 | ||
|
|
a90bd08405 | ||
|
|
1cbb726cab | ||
|
|
ce61d00dcf | ||
|
|
2d92b798c6 | ||
|
|
cc62164a7c | ||
|
|
af510bce93 | ||
|
|
4ba60bedcd | ||
|
|
583bf26129 | ||
|
|
d8c3623141 | ||
|
|
2cd0875da6 | ||
|
|
73d0848f7e | ||
|
|
d757e82e3f | ||
|
|
007238e7dd | ||
|
|
944e019020 | ||
|
|
634f8897b4 | ||
|
|
7651d31c50 | ||
|
|
1702873ab1 | ||
|
|
44e7d5249c | ||
|
|
8ab37040db | ||
|
|
ac203b0ccb | ||
|
|
557546c9c3 | ||
|
|
09c5baa899 | ||
|
|
ea6506f9f4 | ||
|
|
5dd7e548c0 | ||
|
|
b0928f3601 | ||
|
|
52a94dbe78 | ||
|
|
f4ffc19981 | ||
|
|
ac3c117b03 | ||
|
|
1ac008ab02 | ||
|
|
78ff158cb5 | ||
|
|
02b42e4dbb | ||
|
|
82083827ff | ||
|
|
571ea6fbc9 | ||
|
|
8af4a67f5e | ||
|
|
58ac86e3bf | ||
|
|
2bc6c77fce | ||
|
|
1daf06858b | ||
|
|
a4e8ce7f01 | ||
|
|
87d9f09f72 | ||
|
|
ed6e16cdce | ||
|
|
57bb92a36c | ||
|
|
142540e263 | ||
|
|
5a17430747 | ||
|
|
23c84a9e96 | ||
|
|
6bb9dcc216 | ||
|
|
1901e4dbdc | ||
|
|
1657f769da | ||
|
|
c82eb489fe | ||
|
|
9f05befd70 | ||
|
|
f274ed3fd8 | ||
|
|
f6e027abcb | ||
|
|
a92114a854 | ||
|
|
ffb84705d3 | ||
|
|
2f8366b6f9 | ||
|
|
a6f062c126 | ||
|
|
41c24f3bc9 | ||
|
|
af40bdb11b | ||
|
|
00a69e6aed | ||
|
|
04b2d784ce | ||
|
|
a5de51b039 | ||
|
|
4a80e9f20f | ||
|
|
8676769a8f | ||
|
|
2f8c7a81ca | ||
|
|
ac11af6048 | ||
|
|
7c558802a4 | ||
|
|
5a516aa1ad | ||
|
|
4d1b6ed974 | ||
|
|
e8e6bb0499 | ||
|
|
58f94666d1 | ||
|
|
085efaa605 | ||
|
|
6028e392f0 | ||
|
|
fa67dd74a0 | ||
|
|
cb734b50c3 | ||
|
|
087e58b88b | ||
|
|
78b9d67aaa | ||
|
|
a6015e4647 | ||
|
|
fcbe95447a | ||
|
|
760fe392a8 | ||
|
|
5dab606980 | ||
|
|
c265575dfd | ||
|
|
4a1f526ac6 | ||
|
|
497b633661 | ||
|
|
c7f54a98e0 | ||
|
|
7da8c20409 | ||
|
|
116328c7bf | ||
|
|
bd68fef4a2 | ||
|
|
7759d56ad3 | ||
|
|
9c7020a369 | ||
|
|
f8c1903316 | ||
|
|
652423ad14 |
No files matched your search
+31
-2
@@ -2,7 +2,7 @@
|
||||
|
||||
## mobj.localskin and player.localskin fields
|
||||
|
||||
Allow reading and assigning localskins to players. Local skins for other objects aren't supported currently.
|
||||
Allow reading and assigning localskins.
|
||||
|
||||
## mobj.rollsum field
|
||||
|
||||
@@ -20,9 +20,38 @@ Changes vote background texture prefix (game looks for PREFIX + "W" or "C" (depe
|
||||
## hud.add(fn, "vote") and hud.add(fn, "intermission")
|
||||
|
||||
Hud hooks for vote screen and intermission screen. They only get drawer (`v`) as argument.
|
||||
To check if those hooks are available, check if globals FEATURE\_VOTEHUD and FEATURE\_INERMISSIONHUD
|
||||
To check if those hooks are available, check if globals FEATURE\_VOTEHUD and FEATURE\_INTERMISSIONHUD
|
||||
exist.
|
||||
|
||||
## x, y = hud.getOffsets(item)
|
||||
|
||||
Returns the values of the given HUD item's `xoffset`/`yoffset` cvars.
|
||||
Available for any HUD item with offset cvars.
|
||||
|
||||
## x, y, flags = v.getDrawInfo(item)
|
||||
|
||||
Returns the X, Y and flags where the given HUD item will be drawn for the current displayplayer.
|
||||
Available for `item`, `gametypeinfo` and `minimap`.
|
||||
|
||||
## patch, colormap = v.getColorHudPatch(item)
|
||||
|
||||
Returns the patch and colormap to use for the given HUD item. Colorization is based on the user's settings.
|
||||
Available for `item` and `itemmul`.
|
||||
Extra arguments for some items:
|
||||
### item
|
||||
* `small`: true for small item box, false for big item box.
|
||||
* `dark`: true to darken item box. Depends on `darkitembox`.
|
||||
### itemmul
|
||||
* `small`: true for small sticker, false for big sticker.
|
||||
|
||||
## hudcolor = v.getHudColor()
|
||||
|
||||
Returns the displayplayer's HUD color.
|
||||
|
||||
## colorize = v.useColorHud()
|
||||
|
||||
Returns true if colorization is enabled, false otherwise.
|
||||
|
||||
## mobj.spritexscale, mobj.spriteyscale, mobj.spritexoffset, mobj.spriteyoffset, mobj.rollangle, mobj.sloperoll, mobj.rollmodel fields
|
||||
|
||||
Same fields as in SRB2 2.2
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,191 +0,0 @@
|
||||
/* include/curl/curlbuild.h. Generated from curlbuild.h.in by configure. */
|
||||
#ifndef __CURL_CURLBUILD_H
|
||||
#define __CURL_CURLBUILD_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* ================================================================ */
|
||||
/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */
|
||||
/* ================================================================ */
|
||||
|
||||
/*
|
||||
* NOTE 1:
|
||||
* -------
|
||||
*
|
||||
* Nothing in this file is intended to be modified or adjusted by the
|
||||
* curl library user nor by the curl library builder.
|
||||
*
|
||||
* If you think that something actually needs to be changed, adjusted
|
||||
* or fixed in this file, then, report it on the libcurl development
|
||||
* mailing list: http://cool.haxx.se/mailman/listinfo/curl-library/
|
||||
*
|
||||
* This header file shall only export symbols which are 'curl' or 'CURL'
|
||||
* prefixed, otherwise public name space would be polluted.
|
||||
*
|
||||
* NOTE 2:
|
||||
* -------
|
||||
*
|
||||
* Right now you might be staring at file include/curl/curlbuild.h.in or
|
||||
* at file include/curl/curlbuild.h, this is due to the following reason:
|
||||
*
|
||||
* On systems capable of running the configure script, the configure process
|
||||
* will overwrite the distributed include/curl/curlbuild.h file with one that
|
||||
* is suitable and specific to the library being configured and built, which
|
||||
* is generated from the include/curl/curlbuild.h.in template file.
|
||||
*
|
||||
*/
|
||||
|
||||
/* ================================================================ */
|
||||
/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */
|
||||
/* ================================================================ */
|
||||
|
||||
#ifdef CURL_SIZEOF_LONG
|
||||
# error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h"
|
||||
Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined
|
||||
#endif
|
||||
|
||||
#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
|
||||
# error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
|
||||
Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined
|
||||
#endif
|
||||
|
||||
#ifdef CURL_SIZEOF_CURL_SOCKLEN_T
|
||||
# error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
|
||||
Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined
|
||||
#endif
|
||||
|
||||
#ifdef CURL_TYPEOF_CURL_OFF_T
|
||||
# error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
|
||||
Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined
|
||||
#endif
|
||||
|
||||
#ifdef CURL_FORMAT_CURL_OFF_T
|
||||
# error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h"
|
||||
Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined
|
||||
#endif
|
||||
|
||||
#ifdef CURL_FORMAT_CURL_OFF_TU
|
||||
# error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h"
|
||||
Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined
|
||||
#endif
|
||||
|
||||
#ifdef CURL_FORMAT_OFF_T
|
||||
# error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h"
|
||||
Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined
|
||||
#endif
|
||||
|
||||
#ifdef CURL_SIZEOF_CURL_OFF_T
|
||||
# error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
|
||||
Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined
|
||||
#endif
|
||||
|
||||
#ifdef CURL_SUFFIX_CURL_OFF_T
|
||||
# error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h"
|
||||
Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined
|
||||
#endif
|
||||
|
||||
#ifdef CURL_SUFFIX_CURL_OFF_TU
|
||||
# error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h"
|
||||
Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined
|
||||
#endif
|
||||
|
||||
/* ================================================================ */
|
||||
/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */
|
||||
/* ================================================================ */
|
||||
|
||||
/* Configure process defines this to 1 when it finds out that system */
|
||||
/* header file ws2tcpip.h must be included by the external interface. */
|
||||
#define CURL_PULL_WS2TCPIP_H 1
|
||||
#ifdef CURL_PULL_WS2TCPIP_H
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN 1
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# include <winsock2.h>
|
||||
# include <ws2tcpip.h>
|
||||
#endif
|
||||
|
||||
/* Configure process defines this to 1 when it finds out that system */
|
||||
/* header file sys/types.h must be included by the external interface. */
|
||||
#define CURL_PULL_SYS_TYPES_H 1
|
||||
#ifdef CURL_PULL_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
|
||||
/* Configure process defines this to 1 when it finds out that system */
|
||||
/* header file stdint.h must be included by the external interface. */
|
||||
#define CURL_PULL_STDINT_H 1
|
||||
#ifdef CURL_PULL_STDINT_H
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
/* Configure process defines this to 1 when it finds out that system */
|
||||
/* header file inttypes.h must be included by the external interface. */
|
||||
#define CURL_PULL_INTTYPES_H 1
|
||||
#ifdef CURL_PULL_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
|
||||
/* Configure process defines this to 1 when it finds out that system */
|
||||
/* header file sys/socket.h must be included by the external interface. */
|
||||
/* #undef CURL_PULL_SYS_SOCKET_H */
|
||||
#ifdef CURL_PULL_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
/* The size of `long', as computed by sizeof. */
|
||||
#define CURL_SIZEOF_LONG 4
|
||||
|
||||
/* Integral data type used for curl_socklen_t. */
|
||||
#define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
|
||||
|
||||
/* The size of `curl_socklen_t', as computed by sizeof. */
|
||||
#define CURL_SIZEOF_CURL_SOCKLEN_T 4
|
||||
|
||||
/* Data type definition of curl_socklen_t. */
|
||||
typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t;
|
||||
|
||||
/* Signed integral data type used for curl_off_t. */
|
||||
#define CURL_TYPEOF_CURL_OFF_T int64_t
|
||||
|
||||
/* Data type definition of curl_off_t. */
|
||||
typedef CURL_TYPEOF_CURL_OFF_T curl_off_t;
|
||||
|
||||
/* curl_off_t formatting string directive without "%" conversion specifier. */
|
||||
#define CURL_FORMAT_CURL_OFF_T "I64d"
|
||||
|
||||
/* unsigned curl_off_t formatting string without "%" conversion specifier. */
|
||||
#define CURL_FORMAT_CURL_OFF_TU "I64u"
|
||||
|
||||
/* curl_off_t formatting string directive with "%" conversion specifier. */
|
||||
#define CURL_FORMAT_OFF_T "%I64d"
|
||||
|
||||
/* The size of `curl_off_t', as computed by sizeof. */
|
||||
#define CURL_SIZEOF_CURL_OFF_T 8
|
||||
|
||||
/* curl_off_t constant suffix. */
|
||||
#define CURL_SUFFIX_CURL_OFF_T LL
|
||||
|
||||
/* unsigned curl_off_t constant suffix. */
|
||||
#define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
|
||||
#endif /* __CURL_CURLBUILD_H */
|
||||
@@ -1,261 +0,0 @@
|
||||
#ifndef __CURL_CURLRULES_H
|
||||
#define __CURL_CURLRULES_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* ================================================================ */
|
||||
/* COMPILE TIME SANITY CHECKS */
|
||||
/* ================================================================ */
|
||||
|
||||
/*
|
||||
* NOTE 1:
|
||||
* -------
|
||||
*
|
||||
* All checks done in this file are intentionally placed in a public
|
||||
* header file which is pulled by curl/curl.h when an application is
|
||||
* being built using an already built libcurl library. Additionally
|
||||
* this file is also included and used when building the library.
|
||||
*
|
||||
* If compilation fails on this file it is certainly sure that the
|
||||
* problem is elsewhere. It could be a problem in the curlbuild.h
|
||||
* header file, or simply that you are using different compilation
|
||||
* settings than those used to build the library.
|
||||
*
|
||||
* Nothing in this file is intended to be modified or adjusted by the
|
||||
* curl library user nor by the curl library builder.
|
||||
*
|
||||
* Do not deactivate any check, these are done to make sure that the
|
||||
* library is properly built and used.
|
||||
*
|
||||
* You can find further help on the libcurl development mailing list:
|
||||
* http://cool.haxx.se/mailman/listinfo/curl-library/
|
||||
*
|
||||
* NOTE 2
|
||||
* ------
|
||||
*
|
||||
* Some of the following compile time checks are based on the fact
|
||||
* that the dimension of a constant array can not be a negative one.
|
||||
* In this way if the compile time verification fails, the compilation
|
||||
* will fail issuing an error. The error description wording is compiler
|
||||
* dependent but it will be quite similar to one of the following:
|
||||
*
|
||||
* "negative subscript or subscript is too large"
|
||||
* "array must have at least one element"
|
||||
* "-1 is an illegal array size"
|
||||
* "size of array is negative"
|
||||
*
|
||||
* If you are building an application which tries to use an already
|
||||
* built libcurl library and you are getting this kind of errors on
|
||||
* this file, it is a clear indication that there is a mismatch between
|
||||
* how the library was built and how you are trying to use it for your
|
||||
* application. Your already compiled or binary library provider is the
|
||||
* only one who can give you the details you need to properly use it.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Verify that some macros are actually defined.
|
||||
*/
|
||||
|
||||
#ifndef CURL_SIZEOF_LONG
|
||||
# error "CURL_SIZEOF_LONG definition is missing!"
|
||||
Error Compilation_aborted_CURL_SIZEOF_LONG_is_missing
|
||||
#endif
|
||||
|
||||
#ifndef CURL_TYPEOF_CURL_SOCKLEN_T
|
||||
# error "CURL_TYPEOF_CURL_SOCKLEN_T definition is missing!"
|
||||
Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_is_missing
|
||||
#endif
|
||||
|
||||
#ifndef CURL_SIZEOF_CURL_SOCKLEN_T
|
||||
# error "CURL_SIZEOF_CURL_SOCKLEN_T definition is missing!"
|
||||
Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_is_missing
|
||||
#endif
|
||||
|
||||
#ifndef CURL_TYPEOF_CURL_OFF_T
|
||||
# error "CURL_TYPEOF_CURL_OFF_T definition is missing!"
|
||||
Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_is_missing
|
||||
#endif
|
||||
|
||||
#ifndef CURL_FORMAT_CURL_OFF_T
|
||||
# error "CURL_FORMAT_CURL_OFF_T definition is missing!"
|
||||
Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_is_missing
|
||||
#endif
|
||||
|
||||
#ifndef CURL_FORMAT_CURL_OFF_TU
|
||||
# error "CURL_FORMAT_CURL_OFF_TU definition is missing!"
|
||||
Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_is_missing
|
||||
#endif
|
||||
|
||||
#ifndef CURL_FORMAT_OFF_T
|
||||
# error "CURL_FORMAT_OFF_T definition is missing!"
|
||||
Error Compilation_aborted_CURL_FORMAT_OFF_T_is_missing
|
||||
#endif
|
||||
|
||||
#ifndef CURL_SIZEOF_CURL_OFF_T
|
||||
# error "CURL_SIZEOF_CURL_OFF_T definition is missing!"
|
||||
Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_is_missing
|
||||
#endif
|
||||
|
||||
#ifndef CURL_SUFFIX_CURL_OFF_T
|
||||
# error "CURL_SUFFIX_CURL_OFF_T definition is missing!"
|
||||
Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_is_missing
|
||||
#endif
|
||||
|
||||
#ifndef CURL_SUFFIX_CURL_OFF_TU
|
||||
# error "CURL_SUFFIX_CURL_OFF_TU definition is missing!"
|
||||
Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_is_missing
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Macros private to this header file.
|
||||
*/
|
||||
|
||||
#define CurlchkszEQ(t, s) sizeof(t) == s ? 1 : -1
|
||||
|
||||
#define CurlchkszGE(t1, t2) sizeof(t1) >= sizeof(t2) ? 1 : -1
|
||||
|
||||
/*
|
||||
* Verify that the size previously defined and expected for long
|
||||
* is the same as the one reported by sizeof() at compile time.
|
||||
*/
|
||||
|
||||
typedef char
|
||||
__curl_rule_01__
|
||||
[CurlchkszEQ(long, CURL_SIZEOF_LONG)];
|
||||
|
||||
/*
|
||||
* Verify that the size previously defined and expected for
|
||||
* curl_off_t is actually the the same as the one reported
|
||||
* by sizeof() at compile time.
|
||||
*/
|
||||
|
||||
typedef char
|
||||
__curl_rule_02__
|
||||
[CurlchkszEQ(curl_off_t, CURL_SIZEOF_CURL_OFF_T)];
|
||||
|
||||
/*
|
||||
* Verify at compile time that the size of curl_off_t as reported
|
||||
* by sizeof() is greater or equal than the one reported for long
|
||||
* for the current compilation.
|
||||
*/
|
||||
|
||||
typedef char
|
||||
__curl_rule_03__
|
||||
[CurlchkszGE(curl_off_t, long)];
|
||||
|
||||
/*
|
||||
* Verify that the size previously defined and expected for
|
||||
* curl_socklen_t is actually the the same as the one reported
|
||||
* by sizeof() at compile time.
|
||||
*/
|
||||
|
||||
typedef char
|
||||
__curl_rule_04__
|
||||
[CurlchkszEQ(curl_socklen_t, CURL_SIZEOF_CURL_SOCKLEN_T)];
|
||||
|
||||
/*
|
||||
* Verify at compile time that the size of curl_socklen_t as reported
|
||||
* by sizeof() is greater or equal than the one reported for int for
|
||||
* the current compilation.
|
||||
*/
|
||||
|
||||
typedef char
|
||||
__curl_rule_05__
|
||||
[CurlchkszGE(curl_socklen_t, int)];
|
||||
|
||||
/* ================================================================ */
|
||||
/* EXTERNALLY AND INTERNALLY VISIBLE DEFINITIONS */
|
||||
/* ================================================================ */
|
||||
|
||||
/*
|
||||
* CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow
|
||||
* these to be visible and exported by the external libcurl interface API,
|
||||
* while also making them visible to the library internals, simply including
|
||||
* setup.h, without actually needing to include curl.h internally.
|
||||
* If some day this section would grow big enough, all this should be moved
|
||||
* to its own header file.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Figure out if we can use the ## preprocessor operator, which is supported
|
||||
* by ISO/ANSI C and C++. Some compilers support it without setting __STDC__
|
||||
* or __cplusplus so we need to carefully check for them too.
|
||||
*/
|
||||
|
||||
#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
|
||||
defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \
|
||||
defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \
|
||||
defined(__ILEC400__)
|
||||
/* This compiler is believed to have an ISO compatible preprocessor */
|
||||
#define CURL_ISOCPP
|
||||
#else
|
||||
/* This compiler is believed NOT to have an ISO compatible preprocessor */
|
||||
#undef CURL_ISOCPP
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Macros for minimum-width signed and unsigned curl_off_t integer constants.
|
||||
*/
|
||||
|
||||
#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551)
|
||||
# define __CURL_OFF_T_C_HLPR2(x) x
|
||||
# define __CURL_OFF_T_C_HLPR1(x) __CURL_OFF_T_C_HLPR2(x)
|
||||
# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \
|
||||
__CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T)
|
||||
# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \
|
||||
__CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU)
|
||||
#else
|
||||
# ifdef CURL_ISOCPP
|
||||
# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix
|
||||
# else
|
||||
# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix
|
||||
# endif
|
||||
# define __CURL_OFF_T_C_HLPR1(Val,Suffix) __CURL_OFF_T_C_HLPR2(Val,Suffix)
|
||||
# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T)
|
||||
# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get rid of macros private to this header file.
|
||||
*/
|
||||
|
||||
#undef CurlchkszEQ
|
||||
#undef CurlchkszGE
|
||||
|
||||
/*
|
||||
* Get rid of macros not intended to exist beyond this point.
|
||||
*/
|
||||
|
||||
#undef CURL_PULL_WS2TCPIP_H
|
||||
#undef CURL_PULL_SYS_TYPES_H
|
||||
#undef CURL_PULL_SYS_SOCKET_H
|
||||
#undef CURL_PULL_STDINT_H
|
||||
#undef CURL_PULL_INTTYPES_H
|
||||
|
||||
#undef CURL_TYPEOF_CURL_SOCKLEN_T
|
||||
#undef CURL_TYPEOF_CURL_OFF_T
|
||||
|
||||
#ifdef CURL_NO_OLDIES
|
||||
#undef CURL_FORMAT_OFF_T /* not required since 7.19.0 - obsoleted in 7.20.0 */
|
||||
#endif
|
||||
|
||||
#endif /* __CURL_CURLRULES_H */
|
||||
@@ -1 +0,0 @@
|
||||
/* not used */
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+36
-24
@@ -4,7 +4,7 @@ project(libgme)
|
||||
include (CheckCXXCompilerFlag)
|
||||
|
||||
# When version is changed, also change the one in gme/gme.h to match
|
||||
set(GME_VERSION 0.6.2 CACHE INTERNAL "libgme Version")
|
||||
set(GME_VERSION 0.6.3 CACHE INTERNAL "libgme Version")
|
||||
|
||||
# 2.6+ always assumes FATAL_ERROR, but 2.4 and below don't.
|
||||
# Of course, 2.4 might work, in which case you're welcome to drop
|
||||
@@ -48,10 +48,18 @@ if (NOT DEFINED USE_GME_SPC)
|
||||
SET(USE_GME_SPC 1 CACHE BOOL "Enable SNES SPC music emulation")
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED GME_SPC_ISOLATED_ECHO_BUFFER)
|
||||
option(GME_SPC_ISOLATED_ECHO_BUFFER "Enable isolated echo buffer on SPC emulator to allow correct playing of \"dodgy\" SPC files made for various ROM hacks ran on ZSNES" OFF)
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED USE_GME_VGM)
|
||||
SET(USE_GME_VGM 1 CACHE BOOL "Enable Sega VGM/VGZ music emulation")
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED GME_YM2612_EMU)
|
||||
SET(GME_YM2612_EMU "Nuked" CACHE STRING "Which YM2612 emulator to use: \"Nuked\" (LGPLv2.1+), \"MAME\" (GPLv2+), or \"GENS\" (LGPLv2.1+)")
|
||||
endif()
|
||||
|
||||
if (USE_GME_NSFE AND NOT USE_GME_NSF)
|
||||
MESSAGE(" -- NSFE support requires NSF, enabling NSF support. --")
|
||||
SET(USE_GME_NSF 1 CACHE BOOL "Enable NES NSF music emulation" FORCE)
|
||||
@@ -59,32 +67,36 @@ endif()
|
||||
|
||||
option(BUILD_SHARED_LIBS "Build shared library (set to OFF for static library)" ON)
|
||||
|
||||
# Check for GCC "visibility" support.
|
||||
if (CMAKE_COMPILER_IS_GNUCXX)
|
||||
check_cxx_compiler_flag (-fvisibility=hidden __LIBGME_TEST_VISIBILITY)
|
||||
set (ENABLE_VISIBILITY OFF)
|
||||
if (__LIBGME_TEST_VISIBILITY)
|
||||
# get the gcc version
|
||||
exec_program(${CMAKE_CXX_COMPILER} ARGS --version OUTPUT_VARIABLE _gcc_version_info)
|
||||
string (REGEX MATCH "[3-9]\\.[0-9]\\.[0-9]" _gcc_version "${_gcc_version_info}")
|
||||
option(ENABLE_UBSAN "Enable Undefined Behavior Sanitizer error-checking" ON)
|
||||
|
||||
# gcc <4.1 had poor support for symbol visibility
|
||||
if ((${_gcc_version} VERSION_GREATER "4.1") OR (${_gcc_version} VERSION_EQUAL "4.1"))
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
|
||||
set (ENABLE_VISIBILITY ON)
|
||||
add_definitions (-DLIBGME_VISIBILITY)
|
||||
option(BUILD_FRAMEWORK "Build framework instead of dylib (on macOS)" OFF)
|
||||
|
||||
# GCC >= 4.2 also correctly supports making inline members have hidden
|
||||
# visibility by default.
|
||||
if ((${_gcc_version} VERSION_GREATER "4.2") OR (${_gcc_version} VERSION_EQUAL "4.2"))
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden")
|
||||
endif()
|
||||
endif()
|
||||
endif() # test visibility
|
||||
# Check for GCC/Clang "visibility" support.
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
|
||||
OR
|
||||
CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
|
||||
# Cache this result
|
||||
set( LIBGME_HAVE_GCC_VISIBILITY ${ENABLE_VISIBILITY} CACHE BOOL "GCC support for hidden visibility")
|
||||
endif (CMAKE_COMPILER_IS_GNUCXX)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -W -Wextra")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
|
||||
# Assume we have visibility support on any compiler that supports C++11
|
||||
add_definitions (-DLIBGME_VISIBILITY)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -fvisibility-inlines-hidden")
|
||||
|
||||
# Try to protect against undefined behavior from signed integer overflow
|
||||
# This has caused miscompilation of code already and there are other
|
||||
# potential uses; see https://bitbucket.org/mpyne/game-music-emu/issues/18/
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fwrapv")
|
||||
|
||||
if (ENABLE_UBSAN)
|
||||
# GCC needs -static-libubsan
|
||||
if (NOT BUILD_SHARED_LIBS AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -static-libubsan")
|
||||
else()
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined")
|
||||
endif()
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
# Shared library defined here
|
||||
add_subdirectory(gme)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Game_Music_Emu Change Log
|
||||
-------------------------
|
||||
|
||||
Please see the git version history (e.g. git shortlog tags/0.6.0..tags/0.6.1)
|
||||
for the accurate change log.
|
||||
Game_Music_Emu Change Log
|
||||
-------------------------
|
||||
|
||||
Please see the git version history (e.g. git shortlog tags/0.6.0..tags/0.6.1)
|
||||
for the accurate change log.
|
||||
+194
-194
@@ -1,194 +1,194 @@
|
||||
Game_Music_Emu 0.6.0 Design
|
||||
---------------------------
|
||||
This might be slightly out-of-date at times, but will be a big help in
|
||||
understanding the library implementation.
|
||||
|
||||
|
||||
Architecture
|
||||
------------
|
||||
The library is essentially a bunch of independent game music file
|
||||
emulators unified with a common interface.
|
||||
|
||||
Gme_File and Music_Emu provide a common interface to the emulators. The
|
||||
virtual functions are protected rather than public to allow pre- and
|
||||
post-processing of arguments and data in one place. This allows the
|
||||
emulator classes to assume that everything is set up properly when
|
||||
starting a track and playing samples.
|
||||
|
||||
All file input is done with the Data_Reader interface. Many derived
|
||||
classes are present, for the usual disk-based file and block of memory,
|
||||
to specialized adaptors for things like reading a subset of data or
|
||||
combining a block of memory with a Data_Reader to the remaining data.
|
||||
This makes the library much more flexible with regard to the source of
|
||||
game music file data. I still added a specialized load_mem() function to
|
||||
have the emulator keep a pointer to data already read in memory, for
|
||||
those formats whose files can be absolutely huge (GYM, some VGMs). This
|
||||
is important if for some reason the caller must load the data ahead of
|
||||
time, but doesn't want the emulator needlessly making a copy.
|
||||
|
||||
Since silence checking and fading are relatively complex, they are kept
|
||||
separate from basic file loading and track information, which are
|
||||
handled in the base class Gme_File. My original intent was to use
|
||||
Gme_File as the common base class for full emulators and track
|
||||
information-only readers, but implementing the C interface was much
|
||||
simpler if both derived from Music_Emu. User C++ code can still benefit
|
||||
from static checking by using Gme_File where only track information will
|
||||
be accessed.
|
||||
|
||||
Each emulator generally has three components: main emulator, CPU
|
||||
emulator, and sound chip emulator(s). Each component has minimal
|
||||
coupling, so use in a full emulator or stand alone is fairly easy. This
|
||||
modularity really helps reduce complexity. Blip_Buffer helps a lot with
|
||||
simplifying the APU interfaces and implementation.
|
||||
|
||||
The "classic" emulators derive from Classic_Emu, which handles
|
||||
Blip_Buffer filling and multiple channels. It uses Multi_Buffer for
|
||||
output, allowing you to derive a custom buffer that could output each
|
||||
voice to a separate sound channel and do different processing on each.
|
||||
At some point I'm going to implement a better Effects_Buffer that allows
|
||||
individual control of every channel.
|
||||
|
||||
In implementing the C interface, I wanted a way to specify an emulator
|
||||
type that didn't require linking in all the emulators. For each emulator
|
||||
type there is a global object with pointers to functions to create the
|
||||
emulator or a track information reader. The emulator type is thus a
|
||||
pointer to this, which conveniently allows for a NULL value. The user
|
||||
referencing this emulator type object is what ultimately links the
|
||||
emulator in (unless new Foo_Emu is used in C++, of course). This type
|
||||
also serves as a useful substitute for RTTI on older C++ compilers.
|
||||
|
||||
Addendum: I have since added gme_type_list(), which causes all listed
|
||||
emulators to be linked in. To avoid this, I make the list itself
|
||||
editable in blargg_config.h. Having a built-in list allows
|
||||
gme_load_file() to take a path and give back an emulator with the file
|
||||
loaded, which is extremely useful for new users.
|
||||
|
||||
|
||||
Interface conventions
|
||||
----------------------
|
||||
If a function retains a pointer to or replaces the value of an object
|
||||
passed, it takes a pointer so that it will be clear in the caller's
|
||||
source code that care is required.
|
||||
|
||||
Multi-word names have an underscore '_' separator between individual
|
||||
words.
|
||||
|
||||
Functions are named with lowercase words. Functions which perform an
|
||||
action with side-effects are named with a verb phrase (i.e. load, move,
|
||||
run). Functions which return the value of a piece of state are named
|
||||
using a noun phrase (i.e. loaded, moved, running).
|
||||
|
||||
Classes are named with capitalized words. Only the first letter of an
|
||||
acronym is capitalized. Class names are nouns, sometimes suggestive of
|
||||
what they do (i.e. File_Scanner).
|
||||
|
||||
Structure, enumeration, and typedefs to these and built-in types are
|
||||
named using lowercase words with a _t suffix.
|
||||
|
||||
Macros are named with all-uppercase words.
|
||||
|
||||
Internal names which can't be hidden due to technical reasons have an
|
||||
underscore '_' suffix.
|
||||
|
||||
|
||||
Managing Complexity
|
||||
-------------------
|
||||
Complexity has been a factor in most library decisions. Many features
|
||||
have been passed by due to the complexity they would add. Once
|
||||
complexity goes past a certain level, it mentally grasping the library
|
||||
in its entirety, at which point more defects will occur and be hard to
|
||||
find.
|
||||
|
||||
I chose 16-bit signed samples because it seems to be the most common
|
||||
format. Supporting multiple formats would add too much complexity to be
|
||||
worth it. Other formats can be obtained via conversion.
|
||||
|
||||
I've kept interfaces fairly lean, leaving many possible features
|
||||
untapped but easy to add if necessary. For example the classic emulators
|
||||
could have volume and frequency equalization adjusted separately for
|
||||
each channel, since they each have an associated Blip_Synth.
|
||||
|
||||
Source files of 400 lines or less seem to be the best size to limit
|
||||
complexity. In a few cases there is no reasonable way to split longer
|
||||
files, or there is benefit from having the source together in one file.
|
||||
|
||||
|
||||
Preventing Bugs
|
||||
---------------
|
||||
I've done many things to reduce the opportunity for defects. A general
|
||||
principle is to write code so that defects will be as visible as
|
||||
possible. I've used several techniques to achieve this.
|
||||
|
||||
I put assertions at key points where defects seem likely or where
|
||||
corruption due to a defect is likely to be visible. I've also put
|
||||
assertions where violations of the interface are likely. In emulators
|
||||
where I am unsure of exact hardware operation in a particular case, I
|
||||
output a debug-only message noting that this has occurred; many times I
|
||||
haven't implemented a hardware feature because nothing uses it. I've
|
||||
made code brittle where there is no clear reason flexibility; code
|
||||
written to handle every possibility sacrifices quality and reliability
|
||||
to handle vaguely defined situations.
|
||||
|
||||
|
||||
Flexibility through indirection
|
||||
-------------------------------
|
||||
I've tried to allow the most flexibility of modules by using indirection
|
||||
to allow extension by the user. This keeps each module simpler and more
|
||||
focused on its unique task.
|
||||
|
||||
The classic emulators use Multi_Buffer, which potentially allows a
|
||||
separate Blip_Buffer for each channel. This keeps emulators free of
|
||||
typical code to allow output in mono, stereo, panning, etc.
|
||||
|
||||
All emulators use a reader object to access file data, allowing it to be
|
||||
stored in a regular file, compressed archive, memory, or generated
|
||||
on-the-fly. Again, the library can be kept free of the particulars of
|
||||
file access and changes required to support new formats.
|
||||
|
||||
|
||||
Emulators in general
|
||||
--------------------
|
||||
When I wrote the first NES sound emulator, I stored most of the state in
|
||||
an emulator-specific format, with significant redundancy. In the
|
||||
register write function I decoded everything into named variables. I
|
||||
became tired of the verbosity and wanted to more closely model the
|
||||
hardware, so I moved to a style of storing the last written value to
|
||||
each register, along with as little other state as possible, mostly the
|
||||
internal hardware registers. While this involves slightly more
|
||||
recalculation, in most cases the emulation code is of comparable size.
|
||||
It also makes state save/restore (for use in a full emulator) much
|
||||
simpler. Finally, it makes debugging easier since the hardware registers
|
||||
used in emulation are obvious.
|
||||
|
||||
|
||||
CPU Cores
|
||||
---------
|
||||
I've spent lots of time coming up with techniques to optimize the CPU
|
||||
cores. Some of the most important: execute multiple instructions during
|
||||
an emulation call, keep state in local variables to allow register
|
||||
assignment, optimize state representation for most common instructions,
|
||||
defer status flag calculation until actually needed, read program code
|
||||
directly without a call to the memory read function, always pre-fetch
|
||||
the operand byte before decoding instruction, and emulate instructions
|
||||
using common blocks of code.
|
||||
|
||||
I've successfully used Nes_Cpu in a fairly complete NES emulator, and
|
||||
I'd like to make all the CPU emulators suitable for use in emulators. It
|
||||
seems a waste for them to be used only for the small amount of emulation
|
||||
necessary for game music files.
|
||||
|
||||
I debugged the CPU cores by writing a test shell that ran them in
|
||||
parallel with other CPU cores and compared all memory accesses and
|
||||
processor states at each step. This provided good value at little cost.
|
||||
|
||||
The CPU mapping page size is adjustable to allow the best tradeoff
|
||||
between memory/cache usage and handler granularity. The interface allows
|
||||
code to be somewhat independent of the page size.
|
||||
|
||||
I optimize program memory accesses to direct reads rather than calls to
|
||||
the memory read function. My assumption is that it would be difficult to
|
||||
get useful code out of hardware I/O addresses, so no software will
|
||||
intentionally execute out of I/O space. Since the page size can be
|
||||
changed easily, most program memory mapping schemes can be accommodated.
|
||||
This greatly reduces memory access function calls.
|
||||
|
||||
Game_Music_Emu 0.6.0 Design
|
||||
---------------------------
|
||||
This might be slightly out-of-date at times, but will be a big help in
|
||||
understanding the library implementation.
|
||||
|
||||
|
||||
Architecture
|
||||
------------
|
||||
The library is essentially a bunch of independent game music file
|
||||
emulators unified with a common interface.
|
||||
|
||||
Gme_File and Music_Emu provide a common interface to the emulators. The
|
||||
virtual functions are protected rather than public to allow pre- and
|
||||
post-processing of arguments and data in one place. This allows the
|
||||
emulator classes to assume that everything is set up properly when
|
||||
starting a track and playing samples.
|
||||
|
||||
All file input is done with the Data_Reader interface. Many derived
|
||||
classes are present, for the usual disk-based file and block of memory,
|
||||
to specialized adaptors for things like reading a subset of data or
|
||||
combining a block of memory with a Data_Reader to the remaining data.
|
||||
This makes the library much more flexible with regard to the source of
|
||||
game music file data. I still added a specialized load_mem() function to
|
||||
have the emulator keep a pointer to data already read in memory, for
|
||||
those formats whose files can be absolutely huge (GYM, some VGMs). This
|
||||
is important if for some reason the caller must load the data ahead of
|
||||
time, but doesn't want the emulator needlessly making a copy.
|
||||
|
||||
Since silence checking and fading are relatively complex, they are kept
|
||||
separate from basic file loading and track information, which are
|
||||
handled in the base class Gme_File. My original intent was to use
|
||||
Gme_File as the common base class for full emulators and track
|
||||
information-only readers, but implementing the C interface was much
|
||||
simpler if both derived from Music_Emu. User C++ code can still benefit
|
||||
from static checking by using Gme_File where only track information will
|
||||
be accessed.
|
||||
|
||||
Each emulator generally has three components: main emulator, CPU
|
||||
emulator, and sound chip emulator(s). Each component has minimal
|
||||
coupling, so use in a full emulator or stand alone is fairly easy. This
|
||||
modularity really helps reduce complexity. Blip_Buffer helps a lot with
|
||||
simplifying the APU interfaces and implementation.
|
||||
|
||||
The "classic" emulators derive from Classic_Emu, which handles
|
||||
Blip_Buffer filling and multiple channels. It uses Multi_Buffer for
|
||||
output, allowing you to derive a custom buffer that could output each
|
||||
voice to a separate sound channel and do different processing on each.
|
||||
At some point I'm going to implement a better Effects_Buffer that allows
|
||||
individual control of every channel.
|
||||
|
||||
In implementing the C interface, I wanted a way to specify an emulator
|
||||
type that didn't require linking in all the emulators. For each emulator
|
||||
type there is a global object with pointers to functions to create the
|
||||
emulator or a track information reader. The emulator type is thus a
|
||||
pointer to this, which conveniently allows for a NULL value. The user
|
||||
referencing this emulator type object is what ultimately links the
|
||||
emulator in (unless new Foo_Emu is used in C++, of course). This type
|
||||
also serves as a useful substitute for RTTI on older C++ compilers.
|
||||
|
||||
Addendum: I have since added gme_type_list(), which causes all listed
|
||||
emulators to be linked in. To avoid this, I make the list itself
|
||||
editable in blargg_config.h. Having a built-in list allows
|
||||
gme_load_file() to take a path and give back an emulator with the file
|
||||
loaded, which is extremely useful for new users.
|
||||
|
||||
|
||||
Interface conventions
|
||||
----------------------
|
||||
If a function retains a pointer to or replaces the value of an object
|
||||
passed, it takes a pointer so that it will be clear in the caller's
|
||||
source code that care is required.
|
||||
|
||||
Multi-word names have an underscore '_' separator between individual
|
||||
words.
|
||||
|
||||
Functions are named with lowercase words. Functions which perform an
|
||||
action with side-effects are named with a verb phrase (i.e. load, move,
|
||||
run). Functions which return the value of a piece of state are named
|
||||
using a noun phrase (i.e. loaded, moved, running).
|
||||
|
||||
Classes are named with capitalized words. Only the first letter of an
|
||||
acronym is capitalized. Class names are nouns, sometimes suggestive of
|
||||
what they do (i.e. File_Scanner).
|
||||
|
||||
Structure, enumeration, and typedefs to these and built-in types are
|
||||
named using lowercase words with a _t suffix.
|
||||
|
||||
Macros are named with all-uppercase words.
|
||||
|
||||
Internal names which can't be hidden due to technical reasons have an
|
||||
underscore '_' suffix.
|
||||
|
||||
|
||||
Managing Complexity
|
||||
-------------------
|
||||
Complexity has been a factor in most library decisions. Many features
|
||||
have been passed by due to the complexity they would add. Once
|
||||
complexity goes past a certain level, it mentally grasping the library
|
||||
in its entirety, at which point more defects will occur and be hard to
|
||||
find.
|
||||
|
||||
I chose 16-bit signed samples because it seems to be the most common
|
||||
format. Supporting multiple formats would add too much complexity to be
|
||||
worth it. Other formats can be obtained via conversion.
|
||||
|
||||
I've kept interfaces fairly lean, leaving many possible features
|
||||
untapped but easy to add if necessary. For example the classic emulators
|
||||
could have volume and frequency equalization adjusted separately for
|
||||
each channel, since they each have an associated Blip_Synth.
|
||||
|
||||
Source files of 400 lines or less seem to be the best size to limit
|
||||
complexity. In a few cases there is no reasonable way to split longer
|
||||
files, or there is benefit from having the source together in one file.
|
||||
|
||||
|
||||
Preventing Bugs
|
||||
---------------
|
||||
I've done many things to reduce the opportunity for defects. A general
|
||||
principle is to write code so that defects will be as visible as
|
||||
possible. I've used several techniques to achieve this.
|
||||
|
||||
I put assertions at key points where defects seem likely or where
|
||||
corruption due to a defect is likely to be visible. I've also put
|
||||
assertions where violations of the interface are likely. In emulators
|
||||
where I am unsure of exact hardware operation in a particular case, I
|
||||
output a debug-only message noting that this has occurred; many times I
|
||||
haven't implemented a hardware feature because nothing uses it. I've
|
||||
made code brittle where there is no clear reason flexibility; code
|
||||
written to handle every possibility sacrifices quality and reliability
|
||||
to handle vaguely defined situations.
|
||||
|
||||
|
||||
Flexibility through indirection
|
||||
-------------------------------
|
||||
I've tried to allow the most flexibility of modules by using indirection
|
||||
to allow extension by the user. This keeps each module simpler and more
|
||||
focused on its unique task.
|
||||
|
||||
The classic emulators use Multi_Buffer, which potentially allows a
|
||||
separate Blip_Buffer for each channel. This keeps emulators free of
|
||||
typical code to allow output in mono, stereo, panning, etc.
|
||||
|
||||
All emulators use a reader object to access file data, allowing it to be
|
||||
stored in a regular file, compressed archive, memory, or generated
|
||||
on-the-fly. Again, the library can be kept free of the particulars of
|
||||
file access and changes required to support new formats.
|
||||
|
||||
|
||||
Emulators in general
|
||||
--------------------
|
||||
When I wrote the first NES sound emulator, I stored most of the state in
|
||||
an emulator-specific format, with significant redundancy. In the
|
||||
register write function I decoded everything into named variables. I
|
||||
became tired of the verbosity and wanted to more closely model the
|
||||
hardware, so I moved to a style of storing the last written value to
|
||||
each register, along with as little other state as possible, mostly the
|
||||
internal hardware registers. While this involves slightly more
|
||||
recalculation, in most cases the emulation code is of comparable size.
|
||||
It also makes state save/restore (for use in a full emulator) much
|
||||
simpler. Finally, it makes debugging easier since the hardware registers
|
||||
used in emulation are obvious.
|
||||
|
||||
|
||||
CPU Cores
|
||||
---------
|
||||
I've spent lots of time coming up with techniques to optimize the CPU
|
||||
cores. Some of the most important: execute multiple instructions during
|
||||
an emulation call, keep state in local variables to allow register
|
||||
assignment, optimize state representation for most common instructions,
|
||||
defer status flag calculation until actually needed, read program code
|
||||
directly without a call to the memory read function, always pre-fetch
|
||||
the operand byte before decoding instruction, and emulate instructions
|
||||
using common blocks of code.
|
||||
|
||||
I've successfully used Nes_Cpu in a fairly complete NES emulator, and
|
||||
I'd like to make all the CPU emulators suitable for use in emulators. It
|
||||
seems a waste for them to be used only for the small amount of emulation
|
||||
necessary for game music files.
|
||||
|
||||
I debugged the CPU cores by writing a test shell that ran them in
|
||||
parallel with other CPU cores and compared all memory accesses and
|
||||
processor states at each step. This provided good value at little cost.
|
||||
|
||||
The CPU mapping page size is adjustable to allow the best tradeoff
|
||||
between memory/cache usage and handler granularity. The interface allows
|
||||
code to be somewhat independent of the page size.
|
||||
|
||||
I optimize program memory accesses to direct reads rather than calls to
|
||||
the memory read function. My assumption is that it would be difficult to
|
||||
get useful code out of hardware I/O addresses, so no software will
|
||||
intentionally execute out of I/O space. Since the page size can be
|
||||
changed easily, most program memory mapping schemes can be accommodated.
|
||||
This greatly reduces memory access function calls.
|
||||
|
||||
+376
-376
@@ -1,376 +1,376 @@
|
||||
Game_Music_Emu 0.6.2
|
||||
--------------------
|
||||
Author : Shay Green <gblargg@gmail.com>
|
||||
Maintainer : Michael Pyne <mpyne@purinchu.net>
|
||||
Website : https://bitbucket.org/mpyne/game-music-emu/
|
||||
Source : https://bitbucket.org/mpyne/game-music-emu/
|
||||
License : GNU Lesser General Public License (LGPL), see LICENSE.txt
|
||||
|
||||
Contents
|
||||
--------
|
||||
* Overview
|
||||
* Error handling
|
||||
* Emulator types
|
||||
* M3U playlist support
|
||||
* Information fields
|
||||
* Track length
|
||||
* Loading file data
|
||||
* Sound parameters
|
||||
* VGM/GYM YM2413 & YM2612 FM sound
|
||||
* Modular construction
|
||||
* Obscure features
|
||||
* Solving problems
|
||||
* Thanks
|
||||
|
||||
|
||||
Overview
|
||||
--------
|
||||
This library can open game music files, play tracks, and read game and
|
||||
track information tags. To play a game music file, do the following:
|
||||
|
||||
* Open the file with gme_open_file()
|
||||
* Start a track with gme_start_track();
|
||||
* Generate samples as needed with gme_play()
|
||||
* Play samples through speaker using your operating system
|
||||
* Delete emulator when done with gme_delete()
|
||||
|
||||
Your code must arrange for the generated samples to be played through
|
||||
the computer's speaker using whatever method your operating system
|
||||
requires.
|
||||
|
||||
There are many additional features available; you can:
|
||||
|
||||
* Determine of the type of a music file without opening it with
|
||||
gme_identify_*()
|
||||
* Load just the file's information tags with gme_info_only
|
||||
* Load from a block of memory rather than a file with gme_load_data()
|
||||
* Arrange for a fade-out at a particular time with gme_set_fade
|
||||
* Find when a track has ended with gme_track_ended()
|
||||
* Seek to a new time in the track with gme_seek()
|
||||
* Load an extended m3u playlist with gme_load_m3u()
|
||||
* Get a list of the voices (channels) and mute them individually with
|
||||
gme_voice_names() and gme_mute_voice()
|
||||
* Change the playback tempo without affecting pitch with gme_set_tempo()
|
||||
* Adjust treble/bass equalization with gme_set_equalizer()
|
||||
* Associate your own data with an emulator and later get it back with
|
||||
gme_set_user_data()
|
||||
* Register a function of yours to be called back when the emulator is
|
||||
deleted with gme_set_user_cleanup()
|
||||
|
||||
Refer to gme.h for a comprehensive summary of features.
|
||||
|
||||
|
||||
Error handling
|
||||
--------------
|
||||
Functions which can fail have a return type of gme_err_t, which is a
|
||||
pointer to an error string (const char*). If a function is successful it
|
||||
returns NULL. Errors that you can easily avoid are checked with debug
|
||||
assertions; gme_err_t return values are only used for genuine run-time
|
||||
errors that can't be easily predicted in advance (out of memory, I/O
|
||||
errors, incompatible file data). Your code should check all error
|
||||
values.
|
||||
|
||||
When loading a music file in the wrong emulator or trying to load a
|
||||
non-music file, gme_wrong_file_type is returned. You can check for this
|
||||
error in C++ like this:
|
||||
|
||||
gme_err_t err = gme_open_file( path, &emu );
|
||||
if ( err == gme_wrong_file_type )
|
||||
...
|
||||
|
||||
To check for minor problems, call gme_warning() to get a string
|
||||
describing the last warning. Your player should allow the user some way
|
||||
of knowing when this is the case, since these minor errors could affect
|
||||
playback. Without this information the user can't solve problems as
|
||||
well. When playing a track, gme_warning() returns minor playback-related
|
||||
problems (major playback problems end the track immediately and set the
|
||||
warning string).
|
||||
|
||||
|
||||
Emulator types
|
||||
--------------
|
||||
The library includes several game music emulators that each support a
|
||||
different file type. Each is identified by a gme_type_t constant defined
|
||||
in gme.h, for example gme_nsf_emu is for the NSF emulator. If you use
|
||||
gme_open_file() or gme_open_data(), the library does the work of
|
||||
determining the file type and creating an appropriate emulator. If you
|
||||
want more control over this process, read on.
|
||||
|
||||
There are two basic ways to identify a game music file's type: look at
|
||||
its file extension, or read the header data. The library includes
|
||||
functions to help with both methods. The first is preferable because it
|
||||
is fast and the most common way to identify files. Sometimes the
|
||||
extension is lost or wrong, so the header must be read.
|
||||
|
||||
Use gme_identify_extension() to find the correct game music type based
|
||||
on a filename. To identify a file based on its extension and header
|
||||
contents, use gme_identify_file(). If you read the header data yourself,
|
||||
use gme_identify_header().
|
||||
|
||||
If you want to remove support for some music types to reduce your
|
||||
executable size, edit GME_TYPE_LIST in blargg_config.h. For example, to
|
||||
support just NSF and GBS, use this:
|
||||
|
||||
#define GME_TYPE_LIST \
|
||||
gme_nsf_type,\
|
||||
gme_gbs_type
|
||||
|
||||
|
||||
M3U playlist support
|
||||
--------------------
|
||||
The library supports playlists in an extended m3u format with
|
||||
gme_load_m3u() to give track names and times to multi-song formats: AY,
|
||||
GBS, HES, KSS, NSF, NSFE, and SAP. Some aspects of the file format
|
||||
itself is not well-defined so some m3u files won't work properly
|
||||
(particularly those provided with KSS files). Only m3u files referencing
|
||||
a single file are supported; your code must handle m3u files covering
|
||||
more than one game music file, though it can use the built-in m3u
|
||||
parsing provided by the library.
|
||||
|
||||
|
||||
Information fields
|
||||
------------------
|
||||
Support is provided for the various text fields and length information
|
||||
in a file with gme_track_info(). If you just need track information for
|
||||
a file (for example, building a playlist), use gme_new_info() in place
|
||||
of gme_new_emu(), load the file normally, then you can access the track
|
||||
count and info, but nothing else.
|
||||
|
||||
M3U VGM GYM SPC SAP NSFE NSF AY GBS HES KSS
|
||||
-------------------------------------------------------
|
||||
Track Count | * * * * * * * * *
|
||||
|
|
||||
System | * * * * * * * * * *
|
||||
|
|
||||
Game | * * * * * * *
|
||||
|
|
||||
Song | * * * * * * *
|
||||
|
|
||||
Author | * * * * * * * *
|
||||
|
|
||||
Copyright | * * * * * * * *
|
||||
|
|
||||
Comment | * * * *
|
||||
|
|
||||
Dumper | * * * *
|
||||
|
|
||||
Length | * * * * * *
|
||||
|
|
||||
Intro Length| * * *
|
||||
|
|
||||
Loop Length | * * *
|
||||
|
||||
As listed above, the HES and KSS file formats don't include a track
|
||||
count, and tracks are often scattered over the 0-255 range, so an m3u
|
||||
playlist for these is a must.
|
||||
|
||||
Unavailable text fields are set to an empty string and times to -1. Your
|
||||
code should be prepared for any combination of available and unavailable
|
||||
fields, as a particular music file might not use all of the supported
|
||||
fields listed above.
|
||||
|
||||
Currently text fields are truncated to 255 characters. Obscure fields of
|
||||
some formats are not currently decoded; contact me if you want one
|
||||
added.
|
||||
|
||||
|
||||
Track length
|
||||
------------
|
||||
The library leaves it up to you as to when to stop playing a track. You
|
||||
can ask for available length information and then tell the library what
|
||||
time it should start fading the track with gme_set_fade(). By default it
|
||||
also continually checks for 6 or more seconds of silence to mark the end
|
||||
of a track. Here is a reasonable algorithm you can use to decide how
|
||||
long to play a track:
|
||||
|
||||
* If the track length is > 0, use it
|
||||
* If the loop length > 0, play for intro + loop * 2
|
||||
* Otherwise, default to 2.5 minutes (150000 msec)
|
||||
|
||||
If you want to play a track longer than normal, be sure the loop length
|
||||
isn't zero. See Music_Player.cpp around line 145 for example code.
|
||||
|
||||
By default, the library skips silence at the beginning of a track. It
|
||||
also continually checks for the end of a non-looping track by watching
|
||||
for 6 seconds of unbroken silence. When doing this is scans *ahead* by
|
||||
several seconds so it can report the end of the track after only one
|
||||
second of silence has actually played. This feature can be disabled with
|
||||
gme_ignore_silence().
|
||||
|
||||
|
||||
Loading file data
|
||||
-----------------
|
||||
The library allows file data to be loaded in many different ways. All
|
||||
load functions return an error which you should check. The following
|
||||
examples assume these variables:
|
||||
|
||||
Music_Emu* emu;
|
||||
gme_err_t error;
|
||||
|
||||
If you're letting the library determine a file's type, you can use
|
||||
either gme_open_file() or gme_open_data():
|
||||
|
||||
error = gme_open_file( pathname, &emu );
|
||||
error = gme_open_data( pointer, size, &emu );
|
||||
|
||||
If you're manually determining file type and using used gme_new_emu() to
|
||||
create an emulator, you can use the following methods of loading:
|
||||
|
||||
* From a block of memory:
|
||||
|
||||
error = gme_load_data( emu, pointer, size );
|
||||
|
||||
* Have library call your function to read data:
|
||||
|
||||
gme_err_t my_read( void* my_data, void* out, long count )
|
||||
{
|
||||
// code that reads 'count' bytes into 'out' buffer
|
||||
// and return 0 if no error
|
||||
}
|
||||
|
||||
error = gme_load_custom( emu, my_read, file_size, my_data );
|
||||
|
||||
|
||||
Sound parameters
|
||||
----------------
|
||||
All emulators support an arbitrary output sampling rate. A rate of 44100
|
||||
Hz should work well on most systems. Since band-limited synthesis is
|
||||
used, a sampling rate above 48000 Hz is not necessary and will actually
|
||||
reduce sound quality and performance.
|
||||
|
||||
All emulators also support adjustable gain, mainly for the purpose of
|
||||
getting consistent volume between different music formats and avoiding
|
||||
excessive modulation. The gain can only be set *before* setting the
|
||||
emulator's sampling rate, so it's not useful as a general volume
|
||||
control. The default gains of emulators are set so that they give
|
||||
generally similar volumes, though some soundtracks are significantly
|
||||
louder or quieter than normal.
|
||||
|
||||
Some emulators support adjustable treble and bass frequency equalization
|
||||
(AY, GBS, HES, KSS, NSF, NSFE, SAP, VGM) using set_equalizer().
|
||||
Parameters are specified using gme_equalizer_t eq = { treble_dB,
|
||||
bass_freq }. Treble_dB sets the treble level (in dB), where 0.0 dB gives
|
||||
normal treble; -200.0 dB is quite muffled, and 5.0 dB emphasizes treble
|
||||
for an extra crisp sound. Bass_freq sets the frequency where bass
|
||||
response starts to diminish; 15 Hz is normal, 0 Hz gives maximum bass,
|
||||
and 15000 Hz removes all bass. For example, the following makes the
|
||||
sound extra-crisp but lacking bass:
|
||||
|
||||
gme_equalizer_t eq = { 5.0, 1000 };
|
||||
gme_set_equalizer( music_emu, &eq );
|
||||
|
||||
Each emulator's equalization defaults to approximate the particular
|
||||
console's sound quality; this default can be determined by calling
|
||||
equalizer() just after creating the emulator. The Music_Emu::tv_eq
|
||||
profile gives sound as if coming from a TV speaker, and some emulators
|
||||
include other profiles for different versions of the system. For
|
||||
example, to use Famicom sound equalization with the NSF emulator, do the
|
||||
following:
|
||||
|
||||
music_emu->set_equalizer( Nsf_Emu::famicom_eq );
|
||||
|
||||
|
||||
VGM/GYM YM2413 & YM2612 FM sound
|
||||
--------------------------------
|
||||
The library plays Sega Genesis/Mega Drive music using a YM2612 FM sound
|
||||
chip emulator based on the Gens project. Because this has some
|
||||
inaccuracies, other YM2612 emulators can be used in its place by
|
||||
re-implementing the interface in YM2612_Emu.h. Available on my website
|
||||
is a modified version of MAME's YM2612 emulator, which sounds better in
|
||||
some ways and whose author is still making improvements.
|
||||
|
||||
VGM music files using the YM2413 FM sound chip are also supported, but a
|
||||
YM2413 emulator isn't included with the library due to technical
|
||||
reasons. I have put one of the available YM2413 emulators on my website
|
||||
that can be used directly.
|
||||
|
||||
|
||||
Modular construction
|
||||
--------------------
|
||||
The library is made of many fairly independent modules. If you're using
|
||||
only one music file emulator, you can eliminate many of the library
|
||||
sources from your program. Refer to the files list in readme.txt to get
|
||||
a general idea of what can be removed, and be sure to edit GME_TYPE_LIST
|
||||
(see "Emulator types" above). Post to the forum if you'd like me to put
|
||||
together a smaller version for a particular use, as this only takes me a
|
||||
few minutes to do.
|
||||
|
||||
If you want to use one of the individual sound chip emulators (or CPU
|
||||
cores) in your own console emulator, first check the libraries page on
|
||||
my website since I have released several of them as stand alone
|
||||
libraries with included documentation and examples on their use. If you
|
||||
don't find it as a standalone library, contact me and I'll consider
|
||||
separating it.
|
||||
|
||||
The "classic" sound chips use my Blip_Buffer library, which greatly
|
||||
simplifies their implementation and efficiently handles band-limited
|
||||
synthesis. It is also available as a stand alone library with
|
||||
documentation and many examples.
|
||||
|
||||
|
||||
Obscure features
|
||||
----------------
|
||||
The library's flexibility allows many possibilities. Contact me if you
|
||||
want help implementing ideas or removing limitations.
|
||||
|
||||
* Uses no global/static variables, allowing multiple instances of any
|
||||
emulator. This is useful in a music player if you want to allow
|
||||
simultaneous recording or scanning of other tracks while one is already
|
||||
playing. This will also be useful if your platform disallows global
|
||||
data.
|
||||
|
||||
* Emulators that support a custom sound buffer can have *every* voice
|
||||
routed to a different Blip_Buffer, allowing custom processing on each
|
||||
voice. For example you could record a Game Boy track as a 4-channel
|
||||
sound file.
|
||||
|
||||
* Defining BLIP_BUFFER_FAST uses lower quality, less-multiply-intensive
|
||||
synthesis on "classic" emulators, which might help on some really old
|
||||
processors. This significantly lowers sound quality and prevents treble
|
||||
equalization. Try this if your platform's processor isn't fast enough
|
||||
for normal quality. Even on my ten-year-old 400 MHz Mac, this reduces
|
||||
processor usage at most by about 0.6% (from 4% to 3.4%), hardly worth
|
||||
the quality loss.
|
||||
|
||||
|
||||
Solving problems
|
||||
----------------
|
||||
If you're having problems, try the following:
|
||||
|
||||
* If you're getting garbled sound, try this simple siren generator in
|
||||
place of your call to play(). This will quickly tell whether the problem
|
||||
is in the library or in your code.
|
||||
|
||||
static void play_siren( long count, short* out )
|
||||
{
|
||||
static double a, a2;
|
||||
while ( count-- )
|
||||
*out++ = 0x2000 * sin( a += .1 + .05*sin( a2+=.00005 ) );
|
||||
}
|
||||
|
||||
* Enable debugging support in your environment. This enables assertions
|
||||
and other run-time checks.
|
||||
|
||||
* Turn the compiler's optimizer is off. Sometimes an optimizer generates
|
||||
bad code.
|
||||
|
||||
* If multiple threads are being used, ensure that only one at a time is
|
||||
accessing a given set of objects from the library. This library is not
|
||||
in general thread-safe, though independent objects can be used in
|
||||
separate threads.
|
||||
|
||||
* If all else fails, see if the demos work.
|
||||
|
||||
|
||||
Thanks
|
||||
------
|
||||
Big thanks to Chris Moeller (kode54) for help with library testing and
|
||||
feedback, for maintaining the Foobar2000 plugin foo_gep based on it, and
|
||||
for original work on openspc++ that was used when developing Spc_Emu.
|
||||
Brad Martin's excellent OpenSPC SNES DSP emulator worked well from the
|
||||
start. Also thanks to Richard Bannister, Mahendra Tallur, Shazz,
|
||||
nenolod, theHobbit, Johan Samuelsson, and nes6502 for testing, using,
|
||||
and giving feedback for the library in their respective game music
|
||||
players. More recently, Lucas Paul and Michael Pyne have helped nudge the
|
||||
library into a public repository and get its interface more stable for use
|
||||
in shared libraries.
|
||||
Game_Music_Emu 0.6.3
|
||||
--------------------
|
||||
Author : Shay Green <gblargg@gmail.com>
|
||||
Maintainer : Michael Pyne <mpyne@purinchu.net>
|
||||
Website : https://bitbucket.org/mpyne/game-music-emu/
|
||||
Source : https://bitbucket.org/mpyne/game-music-emu/
|
||||
License : GNU Lesser General Public License (LGPL), see LICENSE.txt
|
||||
|
||||
Contents
|
||||
--------
|
||||
* Overview
|
||||
* Error handling
|
||||
* Emulator types
|
||||
* M3U playlist support
|
||||
* Information fields
|
||||
* Track length
|
||||
* Loading file data
|
||||
* Sound parameters
|
||||
* VGM/GYM YM2413 & YM2612 FM sound
|
||||
* Modular construction
|
||||
* Obscure features
|
||||
* Solving problems
|
||||
* Thanks
|
||||
|
||||
|
||||
Overview
|
||||
--------
|
||||
This library can open game music files, play tracks, and read game and
|
||||
track information tags. To play a game music file, do the following:
|
||||
|
||||
* Open the file with gme_open_file()
|
||||
* Start a track with gme_start_track();
|
||||
* Generate samples as needed with gme_play()
|
||||
* Play samples through speaker using your operating system
|
||||
* Delete emulator when done with gme_delete()
|
||||
|
||||
Your code must arrange for the generated samples to be played through
|
||||
the computer's speaker using whatever method your operating system
|
||||
requires.
|
||||
|
||||
There are many additional features available; you can:
|
||||
|
||||
* Determine of the type of a music file without opening it with
|
||||
gme_identify_*()
|
||||
* Load just the file's information tags with gme_info_only
|
||||
* Load from a block of memory rather than a file with gme_load_data()
|
||||
* Arrange for a fade-out at a particular time with gme_set_fade
|
||||
* Find when a track has ended with gme_track_ended()
|
||||
* Seek to a new time in the track with gme_seek()
|
||||
* Load an extended m3u playlist with gme_load_m3u()
|
||||
* Get a list of the voices (channels) and mute them individually with
|
||||
gme_voice_names() and gme_mute_voice()
|
||||
* Change the playback tempo without affecting pitch with gme_set_tempo()
|
||||
* Adjust treble/bass equalization with gme_set_equalizer()
|
||||
* Associate your own data with an emulator and later get it back with
|
||||
gme_set_user_data()
|
||||
* Register a function of yours to be called back when the emulator is
|
||||
deleted with gme_set_user_cleanup()
|
||||
|
||||
Refer to gme.h for a comprehensive summary of features.
|
||||
|
||||
|
||||
Error handling
|
||||
--------------
|
||||
Functions which can fail have a return type of gme_err_t, which is a
|
||||
pointer to an error string (const char*). If a function is successful it
|
||||
returns NULL. Errors that you can easily avoid are checked with debug
|
||||
assertions; gme_err_t return values are only used for genuine run-time
|
||||
errors that can't be easily predicted in advance (out of memory, I/O
|
||||
errors, incompatible file data). Your code should check all error
|
||||
values.
|
||||
|
||||
When loading a music file in the wrong emulator or trying to load a
|
||||
non-music file, gme_wrong_file_type is returned. You can check for this
|
||||
error in C++ like this:
|
||||
|
||||
gme_err_t err = gme_open_file( path, &emu );
|
||||
if ( err == gme_wrong_file_type )
|
||||
...
|
||||
|
||||
To check for minor problems, call gme_warning() to get a string
|
||||
describing the last warning. Your player should allow the user some way
|
||||
of knowing when this is the case, since these minor errors could affect
|
||||
playback. Without this information the user can't solve problems as
|
||||
well. When playing a track, gme_warning() returns minor playback-related
|
||||
problems (major playback problems end the track immediately and set the
|
||||
warning string).
|
||||
|
||||
|
||||
Emulator types
|
||||
--------------
|
||||
The library includes several game music emulators that each support a
|
||||
different file type. Each is identified by a gme_type_t constant defined
|
||||
in gme.h, for example gme_nsf_emu is for the NSF emulator. If you use
|
||||
gme_open_file() or gme_open_data(), the library does the work of
|
||||
determining the file type and creating an appropriate emulator. If you
|
||||
want more control over this process, read on.
|
||||
|
||||
There are two basic ways to identify a game music file's type: look at
|
||||
its file extension, or read the header data. The library includes
|
||||
functions to help with both methods. The first is preferable because it
|
||||
is fast and the most common way to identify files. Sometimes the
|
||||
extension is lost or wrong, so the header must be read.
|
||||
|
||||
Use gme_identify_extension() to find the correct game music type based
|
||||
on a filename. To identify a file based on its extension and header
|
||||
contents, use gme_identify_file(). If you read the header data yourself,
|
||||
use gme_identify_header().
|
||||
|
||||
If you want to remove support for some music types to reduce your
|
||||
executable size, edit GME_TYPE_LIST in blargg_config.h. For example, to
|
||||
support just NSF and GBS, use this:
|
||||
|
||||
#define GME_TYPE_LIST \
|
||||
gme_nsf_type,\
|
||||
gme_gbs_type
|
||||
|
||||
|
||||
M3U playlist support
|
||||
--------------------
|
||||
The library supports playlists in an extended m3u format with
|
||||
gme_load_m3u() to give track names and times to multi-song formats: AY,
|
||||
GBS, HES, KSS, NSF, NSFE, and SAP. Some aspects of the file format
|
||||
itself is not well-defined so some m3u files won't work properly
|
||||
(particularly those provided with KSS files). Only m3u files referencing
|
||||
a single file are supported; your code must handle m3u files covering
|
||||
more than one game music file, though it can use the built-in m3u
|
||||
parsing provided by the library.
|
||||
|
||||
|
||||
Information fields
|
||||
------------------
|
||||
Support is provided for the various text fields and length information
|
||||
in a file with gme_track_info(). If you just need track information for
|
||||
a file (for example, building a playlist), use gme_new_info() in place
|
||||
of gme_new_emu(), load the file normally, then you can access the track
|
||||
count and info, but nothing else.
|
||||
|
||||
M3U VGM GYM SPC SAP NSFE NSF AY GBS HES KSS
|
||||
-------------------------------------------------------
|
||||
Track Count | * * * * * * * * *
|
||||
|
|
||||
System | * * * * * * * * * *
|
||||
|
|
||||
Game | * * * * * * *
|
||||
|
|
||||
Song | * * * * * * *
|
||||
|
|
||||
Author | * * * * * * * *
|
||||
|
|
||||
Copyright | * * * * * * * *
|
||||
|
|
||||
Comment | * * * *
|
||||
|
|
||||
Dumper | * * * *
|
||||
|
|
||||
Length | * * * * * *
|
||||
|
|
||||
Intro Length| * * *
|
||||
|
|
||||
Loop Length | * * *
|
||||
|
||||
As listed above, the HES and KSS file formats don't include a track
|
||||
count, and tracks are often scattered over the 0-255 range, so an m3u
|
||||
playlist for these is a must.
|
||||
|
||||
Unavailable text fields are set to an empty string and times to -1. Your
|
||||
code should be prepared for any combination of available and unavailable
|
||||
fields, as a particular music file might not use all of the supported
|
||||
fields listed above.
|
||||
|
||||
Currently text fields are truncated to 255 characters. Obscure fields of
|
||||
some formats are not currently decoded; contact me if you want one
|
||||
added.
|
||||
|
||||
|
||||
Track length
|
||||
------------
|
||||
The library leaves it up to you as to when to stop playing a track. You
|
||||
can ask for available length information and then tell the library what
|
||||
time it should start fading the track with gme_set_fade(). By default it
|
||||
also continually checks for 6 or more seconds of silence to mark the end
|
||||
of a track. Here is a reasonable algorithm you can use to decide how
|
||||
long to play a track:
|
||||
|
||||
* If the track length is > 0, use it
|
||||
* If the loop length > 0, play for intro + loop * 2
|
||||
* Otherwise, default to 2.5 minutes (150000 msec)
|
||||
|
||||
If you want to play a track longer than normal, be sure the loop length
|
||||
isn't zero. See Music_Player.cpp around line 145 for example code.
|
||||
|
||||
By default, the library skips silence at the beginning of a track. It
|
||||
also continually checks for the end of a non-looping track by watching
|
||||
for 6 seconds of unbroken silence. When doing this is scans *ahead* by
|
||||
several seconds so it can report the end of the track after only one
|
||||
second of silence has actually played. This feature can be disabled with
|
||||
gme_ignore_silence().
|
||||
|
||||
|
||||
Loading file data
|
||||
-----------------
|
||||
The library allows file data to be loaded in many different ways. All
|
||||
load functions return an error which you should check. The following
|
||||
examples assume these variables:
|
||||
|
||||
Music_Emu* emu;
|
||||
gme_err_t error;
|
||||
|
||||
If you're letting the library determine a file's type, you can use
|
||||
either gme_open_file() or gme_open_data():
|
||||
|
||||
error = gme_open_file( pathname, &emu );
|
||||
error = gme_open_data( pointer, size, &emu );
|
||||
|
||||
If you're manually determining file type and using used gme_new_emu() to
|
||||
create an emulator, you can use the following methods of loading:
|
||||
|
||||
* From a block of memory:
|
||||
|
||||
error = gme_load_data( emu, pointer, size );
|
||||
|
||||
* Have library call your function to read data:
|
||||
|
||||
gme_err_t my_read( void* my_data, void* out, long count )
|
||||
{
|
||||
// code that reads 'count' bytes into 'out' buffer
|
||||
// and return 0 if no error
|
||||
}
|
||||
|
||||
error = gme_load_custom( emu, my_read, file_size, my_data );
|
||||
|
||||
|
||||
Sound parameters
|
||||
----------------
|
||||
All emulators support an arbitrary output sampling rate. A rate of 44100
|
||||
Hz should work well on most systems. Since band-limited synthesis is
|
||||
used, a sampling rate above 48000 Hz is not necessary and will actually
|
||||
reduce sound quality and performance.
|
||||
|
||||
All emulators also support adjustable gain, mainly for the purpose of
|
||||
getting consistent volume between different music formats and avoiding
|
||||
excessive modulation. The gain can only be set *before* setting the
|
||||
emulator's sampling rate, so it's not useful as a general volume
|
||||
control. The default gains of emulators are set so that they give
|
||||
generally similar volumes, though some soundtracks are significantly
|
||||
louder or quieter than normal.
|
||||
|
||||
Some emulators support adjustable treble and bass frequency equalization
|
||||
(AY, GBS, HES, KSS, NSF, NSFE, SAP, VGM) using set_equalizer().
|
||||
Parameters are specified using gme_equalizer_t eq = { treble_dB,
|
||||
bass_freq }. Treble_dB sets the treble level (in dB), where 0.0 dB gives
|
||||
normal treble; -200.0 dB is quite muffled, and 5.0 dB emphasizes treble
|
||||
for an extra crisp sound. Bass_freq sets the frequency where bass
|
||||
response starts to diminish; 15 Hz is normal, 0 Hz gives maximum bass,
|
||||
and 15000 Hz removes all bass. For example, the following makes the
|
||||
sound extra-crisp but lacking bass:
|
||||
|
||||
gme_equalizer_t eq = { 5.0, 1000 };
|
||||
gme_set_equalizer( music_emu, &eq );
|
||||
|
||||
Each emulator's equalization defaults to approximate the particular
|
||||
console's sound quality; this default can be determined by calling
|
||||
equalizer() just after creating the emulator. The Music_Emu::tv_eq
|
||||
profile gives sound as if coming from a TV speaker, and some emulators
|
||||
include other profiles for different versions of the system. For
|
||||
example, to use Famicom sound equalization with the NSF emulator, do the
|
||||
following:
|
||||
|
||||
music_emu->set_equalizer( Nsf_Emu::famicom_eq );
|
||||
|
||||
|
||||
VGM/GYM YM2413 & YM2612 FM sound
|
||||
--------------------------------
|
||||
The library plays Sega Genesis/Mega Drive music using a YM2612 FM sound
|
||||
chip emulator based on the Gens project. Because this has some
|
||||
inaccuracies, other YM2612 emulators can be used in its place by
|
||||
re-implementing the interface in YM2612_Emu.h. Available on my website
|
||||
is a modified version of MAME's YM2612 emulator, which sounds better in
|
||||
some ways and whose author is still making improvements.
|
||||
|
||||
VGM music files using the YM2413 FM sound chip are also supported, but a
|
||||
YM2413 emulator isn't included with the library due to technical
|
||||
reasons. I have put one of the available YM2413 emulators on my website
|
||||
that can be used directly.
|
||||
|
||||
|
||||
Modular construction
|
||||
--------------------
|
||||
The library is made of many fairly independent modules. If you're using
|
||||
only one music file emulator, you can eliminate many of the library
|
||||
sources from your program. Refer to the files list in readme.txt to get
|
||||
a general idea of what can be removed, and be sure to edit GME_TYPE_LIST
|
||||
(see "Emulator types" above). Post to the forum if you'd like me to put
|
||||
together a smaller version for a particular use, as this only takes me a
|
||||
few minutes to do.
|
||||
|
||||
If you want to use one of the individual sound chip emulators (or CPU
|
||||
cores) in your own console emulator, first check the libraries page on
|
||||
my website since I have released several of them as stand alone
|
||||
libraries with included documentation and examples on their use. If you
|
||||
don't find it as a standalone library, contact me and I'll consider
|
||||
separating it.
|
||||
|
||||
The "classic" sound chips use my Blip_Buffer library, which greatly
|
||||
simplifies their implementation and efficiently handles band-limited
|
||||
synthesis. It is also available as a stand alone library with
|
||||
documentation and many examples.
|
||||
|
||||
|
||||
Obscure features
|
||||
----------------
|
||||
The library's flexibility allows many possibilities. Contact me if you
|
||||
want help implementing ideas or removing limitations.
|
||||
|
||||
* Uses no global/static variables, allowing multiple instances of any
|
||||
emulator. This is useful in a music player if you want to allow
|
||||
simultaneous recording or scanning of other tracks while one is already
|
||||
playing. This will also be useful if your platform disallows global
|
||||
data.
|
||||
|
||||
* Emulators that support a custom sound buffer can have *every* voice
|
||||
routed to a different Blip_Buffer, allowing custom processing on each
|
||||
voice. For example you could record a Game Boy track as a 4-channel
|
||||
sound file.
|
||||
|
||||
* Defining BLIP_BUFFER_FAST uses lower quality, less-multiply-intensive
|
||||
synthesis on "classic" emulators, which might help on some really old
|
||||
processors. This significantly lowers sound quality and prevents treble
|
||||
equalization. Try this if your platform's processor isn't fast enough
|
||||
for normal quality. Even on my ten-year-old 400 MHz Mac, this reduces
|
||||
processor usage at most by about 0.6% (from 4% to 3.4%), hardly worth
|
||||
the quality loss.
|
||||
|
||||
|
||||
Solving problems
|
||||
----------------
|
||||
If you're having problems, try the following:
|
||||
|
||||
* If you're getting garbled sound, try this simple siren generator in
|
||||
place of your call to play(). This will quickly tell whether the problem
|
||||
is in the library or in your code.
|
||||
|
||||
static void play_siren( long count, short* out )
|
||||
{
|
||||
static double a, a2;
|
||||
while ( count-- )
|
||||
*out++ = 0x2000 * sin( a += .1 + .05*sin( a2+=.00005 ) );
|
||||
}
|
||||
|
||||
* Enable debugging support in your environment. This enables assertions
|
||||
and other run-time checks.
|
||||
|
||||
* Turn the compiler's optimizer is off. Sometimes an optimizer generates
|
||||
bad code.
|
||||
|
||||
* If multiple threads are being used, ensure that only one at a time is
|
||||
accessing a given set of objects from the library. This library is not
|
||||
in general thread-safe, though independent objects can be used in
|
||||
separate threads.
|
||||
|
||||
* If all else fails, see if the demos work.
|
||||
|
||||
|
||||
Thanks
|
||||
------
|
||||
Big thanks to Chris Moeller (kode54) for help with library testing and
|
||||
feedback, for maintaining the Foobar2000 plugin foo_gep based on it, and
|
||||
for original work on openspc++ that was used when developing Spc_Emu.
|
||||
Brad Martin's excellent OpenSPC SNES DSP emulator worked well from the
|
||||
start. Also thanks to Richard Bannister, Mahendra Tallur, Shazz,
|
||||
nenolod, theHobbit, Johan Samuelsson, and nes6502 for testing, using,
|
||||
and giving feedback for the library in their respective game music
|
||||
players. More recently, Lucas Paul and Michael Pyne have helped nudge the
|
||||
library into a public repository and get its interface more stable for use
|
||||
in shared libraries.
|
||||
@@ -0,0 +1,89 @@
|
||||
/* Included at the beginning of library source files, after all other #include lines.
|
||||
* Sets up helpful macros and services used in my source code. They don't need
|
||||
* module an annoying module prefix on their names since they are defined after
|
||||
* all other #include lines. */
|
||||
|
||||
#ifndef BLARGG_SOURCE_H
|
||||
#define BLARGG_SOURCE_H
|
||||
|
||||
/* If debugging is enabled, abort program if expr is false. Meant for checking
|
||||
* internal state and consistency. A failed assertion indicates a bug in the module.
|
||||
* void assert( bool expr ); */
|
||||
#include <assert.h>
|
||||
|
||||
/* If debugging is enabled and expr is false, abort program. Meant for checking
|
||||
* caller-supplied parameters and operations that are outside the control of the
|
||||
* module. A failed requirement indicates a bug outside the module.
|
||||
* void require( bool expr ); */
|
||||
#undef require
|
||||
#define require( expr ) assert( expr )
|
||||
|
||||
/* Use to provide hints to compiler for optimized code layout in situations where we
|
||||
* can almost always expect a conditional to go one way or the other. Should only be
|
||||
* used in situations where an unexpected branch is truly exceptional though! */
|
||||
#undef likely
|
||||
#undef unlikely
|
||||
#ifdef __GNUC__
|
||||
#define likely( x ) __builtin_expect(x, 1)
|
||||
#define unlikely( x ) __builtin_expect(x, 0)
|
||||
#else
|
||||
#define likely( x ) (x)
|
||||
#define unlikely( x ) (x)
|
||||
#endif
|
||||
|
||||
/* Like printf() except output goes to debug log file. Might be defined to do
|
||||
* nothing (not even evaluate its arguments).
|
||||
* void debug_printf( const char* format, ... ); */
|
||||
#if defined(__cplusplus)
|
||||
static inline void blargg_dprintf_( const char* fmt_str, ... ) { (void) fmt_str; }
|
||||
#undef debug_printf
|
||||
#define debug_printf (1) ? (void) 0 : blargg_dprintf_
|
||||
#endif
|
||||
|
||||
/* If enabled, evaluate expr and if false, make debug log entry with source file
|
||||
* and line. Meant for finding situations that should be examined further, but that
|
||||
* don't indicate a problem. In all cases, execution continues normally. */
|
||||
#undef check
|
||||
#define check( expr ) ((void) 0)
|
||||
|
||||
/* If expr yields error string, return it from current function, otherwise continue. */
|
||||
#undef RETURN_ERR
|
||||
#define RETURN_ERR( expr ) do { \
|
||||
blargg_err_t blargg_return_err_ = (expr); \
|
||||
if ( blargg_return_err_ ) return blargg_return_err_; \
|
||||
} while ( 0 )
|
||||
|
||||
/* If ptr is 0, return out of memory error string. */
|
||||
#undef CHECK_ALLOC
|
||||
#define CHECK_ALLOC( ptr ) do { if ( (ptr) == 0 ) return "Out of memory"; } while ( 0 )
|
||||
|
||||
/* TODO: good idea? bad idea? */
|
||||
#undef byte
|
||||
#define byte byte_
|
||||
typedef unsigned char byte;
|
||||
|
||||
/* Setup compiler defines useful for exporting required public API symbols in gme.cpp */
|
||||
#ifndef BLARGG_EXPORT
|
||||
#if defined (_WIN32)
|
||||
#if defined(BLARGG_BUILD_DLL)
|
||||
#define BLARGG_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define BLARGG_EXPORT /* Leave blank: friendly with both static and shared linking */
|
||||
#endif
|
||||
#elif defined (LIBGME_VISIBILITY) && defined(__cplusplus)
|
||||
#define BLARGG_EXPORT __attribute__((visibility ("default")))
|
||||
#else
|
||||
#define BLARGG_EXPORT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* deprecated */
|
||||
#define BLARGG_CHECK_ALLOC CHECK_ALLOC
|
||||
#define BLARGG_RETURN_ERR RETURN_ERR
|
||||
|
||||
/* BLARGG_SOURCE_BEGIN: If defined, #included, allowing redefition of debug_printf and check */
|
||||
#ifdef BLARGG_SOURCE_BEGIN
|
||||
#include BLARGG_SOURCE_BEGIN
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+90
-49
@@ -1,14 +1,16 @@
|
||||
/* Game music emulator library C interface (also usable from C++) */
|
||||
|
||||
/* Game_Music_Emu 0.6.1 */
|
||||
/* Game_Music_Emu 0.6.3 */
|
||||
#ifndef GME_H
|
||||
#define GME_H
|
||||
|
||||
#include "blargg_source.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define GME_VERSION 0x000601 /* 1 byte major, 1 byte minor, 1 byte patch-level */
|
||||
#define GME_VERSION 0x000603 /* 1 byte major, 1 byte minor, 1 byte patch-level */
|
||||
|
||||
/* Error string returned by library functions, or NULL if no error (success) */
|
||||
typedef const char* gme_err_t;
|
||||
@@ -20,41 +22,60 @@ typedef struct Music_Emu Music_Emu;
|
||||
/******** Basic operations ********/
|
||||
|
||||
/* Create emulator and load game music file/data into it. Sets *out to new emulator. */
|
||||
gme_err_t gme_open_file( const char path [], Music_Emu** out, int sample_rate );
|
||||
BLARGG_EXPORT gme_err_t gme_open_file( const char path [], Music_Emu** out, int sample_rate );
|
||||
|
||||
/* Number of tracks available */
|
||||
int gme_track_count( Music_Emu const* );
|
||||
BLARGG_EXPORT int gme_track_count( Music_Emu const* );
|
||||
|
||||
/* Start a track, where 0 is the first track */
|
||||
gme_err_t gme_start_track( Music_Emu*, int index );
|
||||
BLARGG_EXPORT gme_err_t gme_start_track( Music_Emu*, int index );
|
||||
|
||||
/* Generate 'count' 16-bit signed samples info 'out'. Output is in stereo. */
|
||||
gme_err_t gme_play( Music_Emu*, int count, short out [] );
|
||||
BLARGG_EXPORT gme_err_t gme_play( Music_Emu*, int count, short out [] );
|
||||
|
||||
/* Finish using emulator and free memory */
|
||||
void gme_delete( Music_Emu* );
|
||||
BLARGG_EXPORT void gme_delete( Music_Emu* );
|
||||
|
||||
|
||||
/******** Track position/length ********/
|
||||
|
||||
/* Set time to start fading track out. Once fade ends track_ended() returns true.
|
||||
Fade time can be changed while track is playing. */
|
||||
void gme_set_fade( Music_Emu*, int start_msec );
|
||||
BLARGG_EXPORT void gme_set_fade( Music_Emu*, int start_msec );
|
||||
|
||||
/**
|
||||
* If do_autoload_limit is nonzero, then automatically load track length
|
||||
* metadata (if present) and terminate playback once the track length has been
|
||||
* reached. Otherwise playback will continue for an arbitrary period of time
|
||||
* until a prolonged period of silence is detected.
|
||||
*
|
||||
* Not all individual emulators support this setting.
|
||||
*
|
||||
* By default, playback limits are loaded and applied.
|
||||
*
|
||||
* @since 0.6.2
|
||||
*/
|
||||
BLARGG_EXPORT void gme_set_autoload_playback_limit( Music_Emu *, int do_autoload_limit );
|
||||
|
||||
/** See gme_set_autoload_playback_limit.
|
||||
* @since 0.6.2
|
||||
*/
|
||||
BLARGG_EXPORT int gme_autoload_playback_limit( Music_Emu const* );
|
||||
|
||||
/* True if a track has reached its end */
|
||||
int gme_track_ended( Music_Emu const* );
|
||||
BLARGG_EXPORT int gme_track_ended( Music_Emu const* );
|
||||
|
||||
/* Number of milliseconds (1000 = one second) played since beginning of track */
|
||||
int gme_tell( Music_Emu const* );
|
||||
BLARGG_EXPORT int gme_tell( Music_Emu const* );
|
||||
|
||||
/* Number of samples generated since beginning of track */
|
||||
int gme_tell_samples( Music_Emu const* );
|
||||
BLARGG_EXPORT int gme_tell_samples( Music_Emu const* );
|
||||
|
||||
/* Seek to new time in track. Seeking backwards or far forward can take a while. */
|
||||
gme_err_t gme_seek( Music_Emu*, int msec );
|
||||
BLARGG_EXPORT gme_err_t gme_seek( Music_Emu*, int msec );
|
||||
|
||||
/* Equivalent to restarting track then skipping n samples */
|
||||
gme_err_t gme_seek_samples( Music_Emu*, int n );
|
||||
BLARGG_EXPORT gme_err_t gme_seek_samples( Music_Emu*, int n );
|
||||
|
||||
|
||||
/******** Informational ********/
|
||||
@@ -65,24 +86,24 @@ enum { gme_info_only = -1 };
|
||||
|
||||
/* Most recent warning string, or NULL if none. Clears current warning after returning.
|
||||
Warning is also cleared when loading a file and starting a track. */
|
||||
const char* gme_warning( Music_Emu* );
|
||||
BLARGG_EXPORT const char* gme_warning( Music_Emu* );
|
||||
|
||||
/* Load m3u playlist file (must be done after loading music) */
|
||||
gme_err_t gme_load_m3u( Music_Emu*, const char path [] );
|
||||
BLARGG_EXPORT gme_err_t gme_load_m3u( Music_Emu*, const char path [] );
|
||||
|
||||
/* Clear any loaded m3u playlist and any internal playlist that the music format
|
||||
supports (NSFE for example). */
|
||||
void gme_clear_playlist( Music_Emu* );
|
||||
BLARGG_EXPORT void gme_clear_playlist( Music_Emu* );
|
||||
|
||||
/* Gets information for a particular track (length, name, author, etc.).
|
||||
Must be freed after use. */
|
||||
typedef struct gme_info_t gme_info_t;
|
||||
gme_err_t gme_track_info( Music_Emu const*, gme_info_t** out, int track );
|
||||
BLARGG_EXPORT gme_err_t gme_track_info( Music_Emu const*, gme_info_t** out, int track );
|
||||
|
||||
/* Frees track information */
|
||||
void gme_free_info( gme_info_t* );
|
||||
BLARGG_EXPORT void gme_free_info( gme_info_t* );
|
||||
|
||||
struct gme_info_t
|
||||
struct BLARGG_EXPORT gme_info_t
|
||||
{
|
||||
/* times in milliseconds; -1 if unknown */
|
||||
int length; /* total length, if file specifies it */
|
||||
@@ -112,32 +133,32 @@ struct gme_info_t
|
||||
|
||||
/* Adjust stereo echo depth, where 0.0 = off and 1.0 = maximum. Has no effect for
|
||||
GYM, SPC, and Sega Genesis VGM music */
|
||||
void gme_set_stereo_depth( Music_Emu*, double depth );
|
||||
BLARGG_EXPORT void gme_set_stereo_depth( Music_Emu*, double depth );
|
||||
|
||||
/* Disable automatic end-of-track detection and skipping of silence at beginning
|
||||
if ignore is true */
|
||||
void gme_ignore_silence( Music_Emu*, int ignore );
|
||||
BLARGG_EXPORT void gme_ignore_silence( Music_Emu*, int ignore );
|
||||
|
||||
/* Adjust song tempo, where 1.0 = normal, 0.5 = half speed, 2.0 = double speed.
|
||||
Track length as returned by track_info() assumes a tempo of 1.0. */
|
||||
void gme_set_tempo( Music_Emu*, double tempo );
|
||||
BLARGG_EXPORT void gme_set_tempo( Music_Emu*, double tempo );
|
||||
|
||||
/* Number of voices used by currently loaded file */
|
||||
int gme_voice_count( Music_Emu const* );
|
||||
BLARGG_EXPORT int gme_voice_count( Music_Emu const* );
|
||||
|
||||
/* Name of voice i, from 0 to gme_voice_count() - 1 */
|
||||
const char* gme_voice_name( Music_Emu const*, int i );
|
||||
BLARGG_EXPORT const char* gme_voice_name( Music_Emu const*, int i );
|
||||
|
||||
/* Mute/unmute voice i, where voice 0 is first voice */
|
||||
void gme_mute_voice( Music_Emu*, int index, int mute );
|
||||
BLARGG_EXPORT void gme_mute_voice( Music_Emu*, int index, int mute );
|
||||
|
||||
/* Set muting state of all voices at once using a bit mask, where -1 mutes all
|
||||
voices, 0 unmutes them all, 0x01 mutes just the first voice, etc. */
|
||||
void gme_mute_voices( Music_Emu*, int muting_mask );
|
||||
BLARGG_EXPORT void gme_mute_voices( Music_Emu*, int muting_mask );
|
||||
|
||||
/* Frequency equalizer parameters (see gme.txt) */
|
||||
/* Implementers: If modified, also adjust Music_Emu::make_equalizer as needed */
|
||||
typedef struct gme_equalizer_t
|
||||
typedef struct BLARGG_EXPORT gme_equalizer_t
|
||||
{
|
||||
double treble; /* -50.0 = muffled, 0 = flat, +5.0 = extra-crisp */
|
||||
double bass; /* 1 = full bass, 90 = average, 16000 = almost no bass */
|
||||
@@ -146,13 +167,13 @@ typedef struct gme_equalizer_t
|
||||
} gme_equalizer_t;
|
||||
|
||||
/* Get current frequency equalizater parameters */
|
||||
void gme_equalizer( Music_Emu const*, gme_equalizer_t* out );
|
||||
BLARGG_EXPORT void gme_equalizer( Music_Emu const*, gme_equalizer_t* out );
|
||||
|
||||
/* Change frequency equalizer parameters */
|
||||
void gme_set_equalizer( Music_Emu*, gme_equalizer_t const* eq );
|
||||
BLARGG_EXPORT void gme_set_equalizer( Music_Emu*, gme_equalizer_t const* eq );
|
||||
|
||||
/* Enables/disables most accurate sound emulation options */
|
||||
void gme_enable_accuracy( Music_Emu*, int enabled );
|
||||
BLARGG_EXPORT void gme_enable_accuracy( Music_Emu*, int enabled );
|
||||
|
||||
|
||||
/******** Game music types ********/
|
||||
@@ -161,7 +182,7 @@ void gme_enable_accuracy( Music_Emu*, int enabled );
|
||||
typedef const struct gme_type_t_* gme_type_t;
|
||||
|
||||
/* Emulator type constants for each supported file type */
|
||||
extern const gme_type_t
|
||||
extern BLARGG_EXPORT const gme_type_t
|
||||
gme_ay_type,
|
||||
gme_gbs_type,
|
||||
gme_gym_type,
|
||||
@@ -175,69 +196,89 @@ extern const gme_type_t
|
||||
gme_vgz_type;
|
||||
|
||||
/* Type of this emulator */
|
||||
gme_type_t gme_type( Music_Emu const* );
|
||||
BLARGG_EXPORT gme_type_t gme_type( Music_Emu const* );
|
||||
|
||||
/* Pointer to array of all music types, with NULL entry at end. Allows a player linked
|
||||
to this library to support new music types without having to be updated. */
|
||||
gme_type_t const* gme_type_list();
|
||||
BLARGG_EXPORT gme_type_t const* gme_type_list();
|
||||
|
||||
/* Name of game system for this music file type */
|
||||
const char* gme_type_system( gme_type_t );
|
||||
BLARGG_EXPORT const char* gme_type_system( gme_type_t );
|
||||
|
||||
/* True if this music file type supports multiple tracks */
|
||||
int gme_type_multitrack( gme_type_t );
|
||||
BLARGG_EXPORT int gme_type_multitrack( gme_type_t );
|
||||
|
||||
/* whether the pcm output retrieved by gme_play() will have all 8 voices rendered to their
|
||||
* individual stereo channel or (if false) these voices get mixed into one single stereo channel
|
||||
* @since 0.6.2 */
|
||||
BLARGG_EXPORT int gme_multi_channel( Music_Emu const* );
|
||||
|
||||
/******** Advanced file loading ********/
|
||||
|
||||
/* Error returned if file type is not supported */
|
||||
extern const char* const gme_wrong_file_type;
|
||||
extern BLARGG_EXPORT const char* const gme_wrong_file_type;
|
||||
|
||||
/* Same as gme_open_file(), but uses file data already in memory. Makes copy of data. */
|
||||
gme_err_t gme_open_data( void const* data, long size, Music_Emu** out, int sample_rate );
|
||||
/* Same as gme_open_file(), but uses file data already in memory. Makes copy of data.
|
||||
* The resulting Music_Emu object will be set to single channel mode. */
|
||||
BLARGG_EXPORT gme_err_t gme_open_data( void const* data, long size, Music_Emu** out, int sample_rate );
|
||||
|
||||
/* Determine likely game music type based on first four bytes of file. Returns
|
||||
string containing proper file suffix (i.e. "NSF", "SPC", etc.) or "" if
|
||||
file header is not recognized. */
|
||||
const char* gme_identify_header( void const* header );
|
||||
BLARGG_EXPORT const char* gme_identify_header( void const* header );
|
||||
|
||||
/* Get corresponding music type for file path or extension passed in. */
|
||||
gme_type_t gme_identify_extension( const char path_or_extension [] );
|
||||
BLARGG_EXPORT gme_type_t gme_identify_extension( const char path_or_extension [] );
|
||||
|
||||
/**
|
||||
* Get typical file extension for a given music type. This is not a replacement
|
||||
* for a file content identification library (but see gme_identify_header).
|
||||
*
|
||||
* @since 0.6.2
|
||||
*/
|
||||
BLARGG_EXPORT const char* gme_type_extension( gme_type_t music_type );
|
||||
|
||||
/* Determine file type based on file's extension or header (if extension isn't recognized).
|
||||
Sets *type_out to type, or 0 if unrecognized or error. */
|
||||
gme_err_t gme_identify_file( const char path [], gme_type_t* type_out );
|
||||
BLARGG_EXPORT gme_err_t gme_identify_file( const char path [], gme_type_t* type_out );
|
||||
|
||||
/* Create new emulator and set sample rate. Returns NULL if out of memory. If you only need
|
||||
track information, pass gme_info_only for sample_rate. */
|
||||
Music_Emu* gme_new_emu( gme_type_t, int sample_rate );
|
||||
BLARGG_EXPORT Music_Emu* gme_new_emu( gme_type_t, int sample_rate );
|
||||
|
||||
/* Create new multichannel emulator and set sample rate. Returns NULL if out of memory.
|
||||
* If you only need track information, pass gme_info_only for sample_rate.
|
||||
* (see gme_multi_channel for more information on multichannel support)
|
||||
* @since 0.6.2
|
||||
*/
|
||||
BLARGG_EXPORT Music_Emu* gme_new_emu_multi_channel( gme_type_t, int sample_rate );
|
||||
|
||||
/* Load music file into emulator */
|
||||
gme_err_t gme_load_file( Music_Emu*, const char path [] );
|
||||
BLARGG_EXPORT gme_err_t gme_load_file( Music_Emu*, const char path [] );
|
||||
|
||||
/* Load music file from memory into emulator. Makes a copy of data passed. */
|
||||
gme_err_t gme_load_data( Music_Emu*, void const* data, long size );
|
||||
BLARGG_EXPORT gme_err_t gme_load_data( Music_Emu*, void const* data, long size );
|
||||
|
||||
/* Load music file using custom data reader function that will be called to
|
||||
read file data. Most emulators load the entire file in one read call. */
|
||||
typedef gme_err_t (*gme_reader_t)( void* your_data, void* out, int count );
|
||||
gme_err_t gme_load_custom( Music_Emu*, gme_reader_t, long file_size, void* your_data );
|
||||
BLARGG_EXPORT gme_err_t gme_load_custom( Music_Emu*, gme_reader_t, long file_size, void* your_data );
|
||||
|
||||
/* Load m3u playlist file from memory (must be done after loading music) */
|
||||
gme_err_t gme_load_m3u_data( Music_Emu*, void const* data, long size );
|
||||
BLARGG_EXPORT gme_err_t gme_load_m3u_data( Music_Emu*, void const* data, long size );
|
||||
|
||||
|
||||
/******** User data ********/
|
||||
|
||||
/* Set/get pointer to data you want to associate with this emulator.
|
||||
You can use this for whatever you want. */
|
||||
void gme_set_user_data( Music_Emu*, void* new_user_data );
|
||||
void* gme_user_data( Music_Emu const* );
|
||||
BLARGG_EXPORT void gme_set_user_data( Music_Emu*, void* new_user_data );
|
||||
BLARGG_EXPORT void* gme_user_data( Music_Emu const* );
|
||||
|
||||
/* Register cleanup function to be called when deleting emulator, or NULL to
|
||||
clear it. Passes user_data to cleanup function. */
|
||||
typedef void (*gme_user_cleanup_t)( void* user_data );
|
||||
void gme_set_user_cleanup( Music_Emu*, gme_user_cleanup_t func );
|
||||
BLARGG_EXPORT void gme_set_user_cleanup( Music_Emu*, gme_user_cleanup_t func );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
+504
-504
File diff suppressed because it is too large.
Load diff
+241
-231
@@ -1,231 +1,241 @@
|
||||
Game_Music_Emu 0.6.2: Game Music Emulators
|
||||
------------------------------------------
|
||||
Game_Music_Emu is a collection of video game music file emulators that
|
||||
support the following formats and systems:
|
||||
|
||||
AY ZX Spectrum/Amstrad CPC
|
||||
GBS Nintendo Game Boy
|
||||
GYM Sega Genesis/Mega Drive
|
||||
HES NEC TurboGrafx-16/PC Engine
|
||||
KSS MSX Home Computer/other Z80 systems (doesn't support FM sound)
|
||||
NSF/NSFE Nintendo NES/Famicom (with VRC 6, Namco 106, and FME-7 sound)
|
||||
SAP Atari systems using POKEY sound chip
|
||||
SPC Super Nintendo/Super Famicom
|
||||
VGM/VGZ Sega Master System/Mark III, Sega Genesis/Mega Drive,BBC Micro
|
||||
|
||||
Features:
|
||||
* C interface for use in C, C++, and other compatible languages
|
||||
* High emphasis has been placed on making the library very easy to use
|
||||
* One set of common functions work with all emulators the same way
|
||||
* Several code examples, including music player using SDL
|
||||
* Portable code for use on any system with modern or older C++ compilers
|
||||
* Adjustable output sample rate using quality band-limited resampling
|
||||
* Uniform access to text information fields and track timing information
|
||||
* End-of-track fading and automatic look ahead silence detection
|
||||
* Treble/bass and stereo echo for AY/GBS/HES/KSS/NSF/NSFE/SAP/VGM
|
||||
* Tempo can be adjusted and individual voices can be muted while playing
|
||||
* Can read music data from file, memory, or custom reader function/class
|
||||
* Can access track information without having to load into full emulator
|
||||
* M3U track listing support for multi-track formats
|
||||
* Modular design allows elimination of unneeded emulators/features
|
||||
|
||||
This library has been used in game music players for Windows, Linux on
|
||||
several architectures, Mac OS, MorphOS, Xbox, PlayStation Portable,
|
||||
GP2X, and Nintendo DS.
|
||||
|
||||
Author : Shay Green <gblargg@gmail.com>
|
||||
Website: https://bitbucket.org/mpyne/game-music-emu/wiki/Home
|
||||
License: GNU Lesser General Public License (LGPL)
|
||||
|
||||
Current Maintainer: Michael Pyne <mpyne@purinchu.net>
|
||||
|
||||
Getting Started
|
||||
---------------
|
||||
Build a program consisting of demo/basics.c, demo/Wave_Writer.cpp, and
|
||||
all source files in gme/.
|
||||
|
||||
Or, if you have CMake 2.6 or later, execute at a command prompt (from the
|
||||
extracted source directory):
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ../ # <-- Pass any needed CMake flags here
|
||||
make # To build the library
|
||||
cd demo
|
||||
make # To build the demo itself
|
||||
|
||||
Be sure "test.nsf" is in the same directory as the demo program. Running it
|
||||
should generate the recording "out.wav".
|
||||
|
||||
You can use "make install" to install the library. To choose where to install
|
||||
the library to, use the CMake argument "-DCMAKE_INSTALL_PREFIX=/usr/local"
|
||||
(and replace /usr/local with the base path you wish to use). Alternately, you
|
||||
can specify the base path to install to when you run "make install" by passing
|
||||
'DESTDIR=/usr/local' on the make install command line (again, replace
|
||||
/usr/local as appropriate).
|
||||
|
||||
To build a static library instead of shared (the default), pass
|
||||
-DBUILD_SHARED_LIBS=OFF to the cmake command when running cmake.
|
||||
|
||||
A slightly more extensive demo application is available in the player/
|
||||
directory. It requires SDL to build.
|
||||
|
||||
Read gme.txt for more information. Post to the discussion forum for
|
||||
assistance.
|
||||
|
||||
Files
|
||||
-----
|
||||
gme.txt General notes about the library
|
||||
changes.txt Changes made since previous releases
|
||||
design.txt Library design notes
|
||||
license.txt GNU Lesser General Public License
|
||||
CMakeLists.txt CMake build rules
|
||||
|
||||
test.nsf Test file for NSF emulator
|
||||
test.m3u Test m3u playlist for features.c demo
|
||||
|
||||
demo/
|
||||
basics.c Records NSF file to wave sound file
|
||||
features.c Demonstrates many additional features
|
||||
Wave_Writer.h WAVE sound file writer used for demo output
|
||||
Wave_Writer.cpp
|
||||
CMakeLists.txt CMake build rules
|
||||
|
||||
player/ Player using the SDL multimedia library
|
||||
player.cpp Simple music player with waveform display
|
||||
Music_Player.cpp Stand alone player for background music
|
||||
Music_Player.h
|
||||
Audio_Scope.cpp Audio waveform scope
|
||||
Audio_Scope.h
|
||||
CMakeLists.txt CMake build rules
|
||||
|
||||
gme/
|
||||
blargg_config.h Library configuration (modify this file as needed)
|
||||
|
||||
gme.h Library interface header file
|
||||
gme.cpp
|
||||
|
||||
Ay_Emu.h ZX Spectrum AY emulator
|
||||
Ay_Emu.cpp
|
||||
Ay_Apu.cpp
|
||||
Ay_Apu.h
|
||||
Ay_Cpu.cpp
|
||||
Ay_Cpu.h
|
||||
|
||||
Gbs_Emu.h Nintendo Game Boy GBS emulator
|
||||
Gbs_Emu.cpp
|
||||
Gb_Apu.cpp
|
||||
Gb_Apu.h
|
||||
Gb_Cpu.cpp
|
||||
Gb_Cpu.h
|
||||
gb_cpu_io.h
|
||||
Gb_Oscs.cpp
|
||||
Gb_Oscs.h
|
||||
|
||||
Hes_Emu.h TurboGrafx-16/PC Engine HES emulator
|
||||
Hes_Apu.cpp
|
||||
Hes_Apu.h
|
||||
Hes_Cpu.cpp
|
||||
Hes_Cpu.h
|
||||
hes_cpu_io.h
|
||||
Hes_Emu.cpp
|
||||
|
||||
Kss_Emu.h MSX Home Computer/other Z80 systems KSS emulator
|
||||
Kss_Emu.cpp
|
||||
Kss_Cpu.cpp
|
||||
Kss_Cpu.h
|
||||
Kss_Scc_Apu.cpp
|
||||
Kss_Scc_Apu.h
|
||||
Ay_Apu.h
|
||||
Ay_Apu.cpp
|
||||
Sms_Apu.h
|
||||
Sms_Apu.cpp
|
||||
Sms_Oscs.h
|
||||
|
||||
Nsf_Emu.h Nintendo NES NSF/NSFE emulator
|
||||
Nsf_Emu.cpp
|
||||
Nes_Apu.cpp
|
||||
Nes_Apu.h
|
||||
Nes_Cpu.cpp
|
||||
Nes_Cpu.h
|
||||
nes_cpu_io.h
|
||||
Nes_Oscs.cpp
|
||||
Nes_Oscs.h
|
||||
Nes_Fme7_Apu.cpp
|
||||
Nes_Fme7_Apu.h
|
||||
Nes_Namco_Apu.cpp
|
||||
Nes_Namco_Apu.h
|
||||
Nes_Vrc6_Apu.cpp
|
||||
Nes_Vrc6_Apu.h
|
||||
Nsfe_Emu.h NSFE support
|
||||
Nsfe_Emu.cpp
|
||||
|
||||
Spc_Emu.h Super Nintendo SPC emulator
|
||||
Spc_Emu.cpp
|
||||
Snes_Spc.cpp
|
||||
Snes_Spc.h
|
||||
Spc_Cpu.cpp
|
||||
Spc_Cpu.h
|
||||
Spc_Dsp.cpp
|
||||
Spc_Dsp.h
|
||||
Fir_Resampler.cpp
|
||||
Fir_Resampler.h
|
||||
|
||||
Sap_Emu.h Atari SAP emulator
|
||||
Sap_Emu.cpp
|
||||
Sap_Apu.cpp
|
||||
Sap_Apu.h
|
||||
Sap_Cpu.cpp
|
||||
Sap_Cpu.h
|
||||
sap_cpu_io.h
|
||||
|
||||
Vgm_Emu.h Sega VGM emulator
|
||||
Vgm_Emu_Impl.cpp
|
||||
Vgm_Emu_Impl.h
|
||||
Vgm_Emu.cpp
|
||||
Ym2413_Emu.cpp
|
||||
Ym2413_Emu.h
|
||||
Gym_Emu.h Sega Genesis GYM emulator
|
||||
Gym_Emu.cpp
|
||||
Sms_Apu.cpp Common Sega emulator files
|
||||
Sms_Apu.h
|
||||
Sms_Oscs.h
|
||||
Ym2612_Emu.cpp
|
||||
Ym2612_Emu.h
|
||||
Dual_Resampler.cpp
|
||||
Dual_Resampler.h
|
||||
Fir_Resampler.cpp
|
||||
Fir_Resampler.h
|
||||
|
||||
M3u_Playlist.h M3U playlist support
|
||||
M3u_Playlist.cpp
|
||||
|
||||
Effects_Buffer.h Sound buffer with stereo echo and panning
|
||||
Effects_Buffer.cpp
|
||||
|
||||
blargg_common.h Common files needed by all emulators
|
||||
blargg_endian.h
|
||||
blargg_source.h
|
||||
Blip_Buffer.cpp
|
||||
Blip_Buffer.h
|
||||
Gme_File.h
|
||||
Gme_File.cpp
|
||||
Music_Emu.h
|
||||
Music_Emu.cpp
|
||||
Classic_Emu.h
|
||||
Classic_Emu.cpp
|
||||
Multi_Buffer.h
|
||||
Multi_Buffer.cpp
|
||||
Data_Reader.h
|
||||
Data_Reader.cpp
|
||||
|
||||
CMakeLists.txt CMake build rules
|
||||
|
||||
|
||||
Legal
|
||||
-----
|
||||
Game_Music_Emu library copyright (C) 2003-2009 Shay Green.
|
||||
Sega Genesis YM2612 emulator copyright (C) 2002 Stephane Dallongeville.
|
||||
|
||||
--
|
||||
Shay Green <gblargg@gmail.com>
|
||||
Game_Music_Emu 0.6.3: Game Music Emulators
|
||||
------------------------------------------
|
||||
Game_Music_Emu is a collection of video game music file emulators that
|
||||
support the following formats and systems:
|
||||
|
||||
AY ZX Spectrum/Amstrad CPC
|
||||
GBS Nintendo Game Boy
|
||||
GYM Sega Genesis/Mega Drive
|
||||
HES NEC TurboGrafx-16/PC Engine
|
||||
KSS MSX Home Computer/other Z80 systems (doesn't support FM sound)
|
||||
NSF/NSFE Nintendo NES/Famicom (with VRC 6, Namco 106, and FME-7 sound)
|
||||
SAP Atari systems using POKEY sound chip
|
||||
SPC Super Nintendo/Super Famicom
|
||||
VGM/VGZ Sega Master System/Mark III, Sega Genesis/Mega Drive,BBC Micro
|
||||
|
||||
Features:
|
||||
* C interface for use in C, C++, and other compatible languages
|
||||
* High emphasis has been placed on making the library very easy to use
|
||||
* One set of common functions work with all emulators the same way
|
||||
* Several code examples, including music player using SDL
|
||||
* Portable code for use on any system with modern or older C++ compilers
|
||||
* Adjustable output sample rate using quality band-limited resampling
|
||||
* Uniform access to text information fields and track timing information
|
||||
* End-of-track fading and automatic look ahead silence detection
|
||||
* Treble/bass and stereo echo for AY/GBS/HES/KSS/NSF/NSFE/SAP/VGM
|
||||
* Tempo can be adjusted and individual voices can be muted while playing
|
||||
* Can read music data from file, memory, or custom reader function/class
|
||||
* Can access track information without having to load into full emulator
|
||||
* M3U track listing support for multi-track formats
|
||||
* Modular design allows elimination of unneeded emulators/features
|
||||
|
||||
This library has been used in game music players for Windows, Linux on
|
||||
several architectures, Mac OS, MorphOS, Xbox, PlayStation Portable,
|
||||
GP2X, and Nintendo DS.
|
||||
|
||||
Author : Shay Green <gblargg@gmail.com>
|
||||
Website: https://bitbucket.org/mpyne/game-music-emu/wiki/Home
|
||||
License: GNU Lesser General Public License (LGPL)
|
||||
|
||||
Note: When you will use MAME YM2612 emulator, the license of library
|
||||
will be GNU General Public License (GPL) v2.0+!
|
||||
|
||||
Current Maintainer: Michael Pyne <mpyne@purinchu.net>
|
||||
|
||||
Getting Started
|
||||
---------------
|
||||
Build a program consisting of demo/basics.c, demo/Wave_Writer.cpp, and
|
||||
all source files in gme/.
|
||||
|
||||
Or, if you have CMake 2.6 or later, execute at a command prompt (from the
|
||||
extracted source directory):
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ../ # <-- Pass any needed CMake flags here
|
||||
make # To build the library
|
||||
cd demo
|
||||
make # To build the demo itself
|
||||
|
||||
Be sure "test.nsf" is in the same directory as the demo program. Running it
|
||||
should generate the recording "out.wav".
|
||||
|
||||
You can use "make install" to install the library. To choose where to install
|
||||
the library to, use the CMake argument "-DCMAKE_INSTALL_PREFIX=/usr/local"
|
||||
(and replace /usr/local with the base path you wish to use). Alternately, you
|
||||
can specify the base path to install to when you run "make install" by passing
|
||||
'DESTDIR=/usr/local' on the make install command line (again, replace
|
||||
/usr/local as appropriate).
|
||||
|
||||
To build a static library instead of shared (the default), pass
|
||||
-DBUILD_SHARED_LIBS=OFF to the cmake command when running cmake.
|
||||
|
||||
A slightly more extensive demo application is available in the player/
|
||||
directory. It requires SDL to build.
|
||||
|
||||
Read gme.txt for more information. Post to the discussion forum for
|
||||
assistance.
|
||||
|
||||
Files
|
||||
-----
|
||||
gme.txt General notes about the library
|
||||
changes.txt Changes made since previous releases
|
||||
design.txt Library design notes
|
||||
license.txt GNU Lesser General Public License
|
||||
CMakeLists.txt CMake build rules
|
||||
|
||||
test.nsf Test file for NSF emulator
|
||||
test.m3u Test m3u playlist for features.c demo
|
||||
|
||||
demo/
|
||||
basics.c Records NSF file to wave sound file
|
||||
features.c Demonstrates many additional features
|
||||
Wave_Writer.h WAVE sound file writer used for demo output
|
||||
Wave_Writer.cpp
|
||||
CMakeLists.txt CMake build rules
|
||||
|
||||
player/ Player using the SDL multimedia library
|
||||
player.cpp Simple music player with waveform display
|
||||
Music_Player.cpp Stand alone player for background music
|
||||
Music_Player.h
|
||||
Audio_Scope.cpp Audio waveform scope
|
||||
Audio_Scope.h
|
||||
CMakeLists.txt CMake build rules
|
||||
|
||||
gme/
|
||||
blargg_config.h Library configuration (modify this file as needed)
|
||||
|
||||
gme.h Library interface header file
|
||||
gme.cpp
|
||||
|
||||
Ay_Emu.h ZX Spectrum AY emulator
|
||||
Ay_Emu.cpp
|
||||
Ay_Apu.cpp
|
||||
Ay_Apu.h
|
||||
Ay_Cpu.cpp
|
||||
Ay_Cpu.h
|
||||
|
||||
Gbs_Emu.h Nintendo Game Boy GBS emulator
|
||||
Gbs_Emu.cpp
|
||||
Gb_Apu.cpp
|
||||
Gb_Apu.h
|
||||
Gb_Cpu.cpp
|
||||
Gb_Cpu.h
|
||||
gb_cpu_io.h
|
||||
Gb_Oscs.cpp
|
||||
Gb_Oscs.h
|
||||
|
||||
Hes_Emu.h TurboGrafx-16/PC Engine HES emulator
|
||||
Hes_Apu.cpp
|
||||
Hes_Apu.h
|
||||
Hes_Cpu.cpp
|
||||
Hes_Cpu.h
|
||||
hes_cpu_io.h
|
||||
Hes_Emu.cpp
|
||||
|
||||
Kss_Emu.h MSX Home Computer/other Z80 systems KSS emulator
|
||||
Kss_Emu.cpp
|
||||
Kss_Cpu.cpp
|
||||
Kss_Cpu.h
|
||||
Kss_Scc_Apu.cpp
|
||||
Kss_Scc_Apu.h
|
||||
Ay_Apu.h
|
||||
Ay_Apu.cpp
|
||||
Sms_Apu.h
|
||||
Sms_Apu.cpp
|
||||
Sms_Oscs.h
|
||||
|
||||
Nsf_Emu.h Nintendo NES NSF/NSFE emulator
|
||||
Nsf_Emu.cpp
|
||||
Nes_Apu.cpp
|
||||
Nes_Apu.h
|
||||
Nes_Cpu.cpp
|
||||
Nes_Cpu.h
|
||||
nes_cpu_io.h
|
||||
Nes_Oscs.cpp
|
||||
Nes_Oscs.h
|
||||
Nes_Fme7_Apu.cpp
|
||||
Nes_Fme7_Apu.h
|
||||
Nes_Namco_Apu.cpp
|
||||
Nes_Namco_Apu.h
|
||||
Nes_Vrc6_Apu.cpp
|
||||
Nes_Vrc6_Apu.h
|
||||
Nsfe_Emu.h NSFE support
|
||||
Nsfe_Emu.cpp
|
||||
|
||||
Spc_Emu.h Super Nintendo SPC emulator
|
||||
Spc_Emu.cpp
|
||||
Snes_Spc.cpp
|
||||
Snes_Spc.h
|
||||
Spc_Cpu.cpp
|
||||
Spc_Cpu.h
|
||||
Spc_Dsp.cpp
|
||||
Spc_Dsp.h
|
||||
Fir_Resampler.cpp
|
||||
Fir_Resampler.h
|
||||
|
||||
Sap_Emu.h Atari SAP emulator
|
||||
Sap_Emu.cpp
|
||||
Sap_Apu.cpp
|
||||
Sap_Apu.h
|
||||
Sap_Cpu.cpp
|
||||
Sap_Cpu.h
|
||||
sap_cpu_io.h
|
||||
|
||||
Vgm_Emu.h Sega VGM emulator
|
||||
Vgm_Emu_Impl.cpp
|
||||
Vgm_Emu_Impl.h
|
||||
Vgm_Emu.cpp
|
||||
Ym2413_Emu.cpp
|
||||
Ym2413_Emu.h
|
||||
Gym_Emu.h Sega Genesis GYM emulator
|
||||
Gym_Emu.cpp
|
||||
Sms_Apu.cpp Common Sega emulator files
|
||||
Sms_Apu.h
|
||||
Sms_Oscs.h
|
||||
Ym2612_Emu.h
|
||||
Ym2612_GENS.cpp GENS 2.10 YM2612 emulator (LGPLv2.1+ license)
|
||||
Ym2612_GENS.h
|
||||
Ym2612_MAME.cpp MAME YM2612 emulator (GPLv2.0+ license)
|
||||
Ym2612_MAME.h
|
||||
Ym2612_Nuked.cpp Nuked OPN2 emulator (LGPLv2.1+ license)
|
||||
Ym2612_Nuked.h
|
||||
Dual_Resampler.cpp
|
||||
Dual_Resampler.h
|
||||
Fir_Resampler.cpp
|
||||
Fir_Resampler.h
|
||||
|
||||
M3u_Playlist.h M3U playlist support
|
||||
M3u_Playlist.cpp
|
||||
|
||||
Effects_Buffer.h Sound buffer with stereo echo and panning
|
||||
Effects_Buffer.cpp
|
||||
|
||||
blargg_common.h Common files needed by all emulators
|
||||
blargg_endian.h
|
||||
blargg_source.h
|
||||
Blip_Buffer.cpp
|
||||
Blip_Buffer.h
|
||||
Gme_File.h
|
||||
Gme_File.cpp
|
||||
Music_Emu.h
|
||||
Music_Emu.cpp
|
||||
Classic_Emu.h
|
||||
Classic_Emu.cpp
|
||||
Multi_Buffer.h
|
||||
Multi_Buffer.cpp
|
||||
Data_Reader.h
|
||||
Data_Reader.cpp
|
||||
|
||||
CMakeLists.txt CMake build rules
|
||||
|
||||
|
||||
Legal
|
||||
-----
|
||||
Game_Music_Emu library copyright (C) 2003-2009 Shay Green.
|
||||
Sega Genesis YM2612 emulator copyright (C) 2002 Stephane Dallongeville.
|
||||
MAME YM2612 emulator copyright (C) 2003 Jarek Burczynski, Tatsuyuki Satoh
|
||||
Nuked OPN2 emulator copyright (C) 2017 Alexey Khokholov (Nuke.YKT)
|
||||
|
||||
--
|
||||
Shay Green <gblargg@gmail.com>
|
||||
Binary file not shown.
Binary file not shown.
@@ -466,7 +466,6 @@ if(${SRB2_CONFIG_HWRENDER})
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2load.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md3load.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_model.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_trick.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/u_list.c
|
||||
)
|
||||
|
||||
|
||||
+6
-6
@@ -102,6 +102,8 @@ ifeq ($(OS),Windows_NT) # all windows are Windows_NT...
|
||||
MINGW=1
|
||||
SDL=1
|
||||
WINDOWSHELL=1
|
||||
HAVE_DISCORDRPC=0
|
||||
NOUPX=1
|
||||
|
||||
else # if you on the *nix
|
||||
|
||||
@@ -272,7 +274,7 @@ ifdef NOHW
|
||||
else
|
||||
OPTS+=-DHWRENDER
|
||||
OBJS+=$(OBJDIR)/hw_bsp.o $(OBJDIR)/hw_draw.o $(OBJDIR)/hw_light.o \
|
||||
$(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o $(OBJDIR)/hw_trick.o \
|
||||
$(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o \
|
||||
$(OBJDIR)/hw_md2load.o $(OBJDIR)/hw_md3load.o $(OBJDIR)/hw_model.o $(OBJDIR)/u_list.o $(OBJDIR)/hw_batching.o $(OBJDIR)/hw_shaders.o
|
||||
endif
|
||||
|
||||
@@ -286,7 +288,7 @@ else
|
||||
endif
|
||||
else
|
||||
ifdef X86_64
|
||||
ARCHOPTS?=-march=nocona
|
||||
ARCHOPTS?=-march=native -O3 -finline-functions
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -389,9 +391,7 @@ CFLAGS+=-DHAVE_DISCORDRPC -DUSE_STUN
|
||||
OBJS+=$(OBJDIR)/discord.o $(OBJDIR)/stun.o
|
||||
endif
|
||||
|
||||
ifndef NO_LUA
|
||||
include blua/Makefile.cfg
|
||||
endif
|
||||
|
||||
ifdef NOMD5
|
||||
OPTS+=-DNOMD5
|
||||
@@ -721,9 +721,9 @@ $(OBJDIR)/depend.dep:
|
||||
ifndef NOHW
|
||||
$(CC) $(CFLAGS) -MM hardware/*.c >> $(OBJDIR)/depend.ped
|
||||
endif
|
||||
ifndef NO_LUA
|
||||
|
||||
$(CC) $(CFLAGS) -MM blua/*.c >> $(OBJDIR)/depend.ped
|
||||
endif
|
||||
|
||||
@sed -e 's,\(.*\)\.o: ,$(subst /,\/,$(OBJDIR))\/&,g' < $(OBJDIR)/depend.ped > $(OBJDIR)/depend.dep
|
||||
$(REMOVE) $(OBJDIR)/depend.ped
|
||||
@echo "Created dependency file, depend.dep"
|
||||
|
||||
+1
-1
@@ -338,7 +338,7 @@ endif
|
||||
WFLAGS+=-Wfloat-equal
|
||||
#WFLAGS+=-Wtraditional
|
||||
ifdef VCHELP
|
||||
WFLAGS+=-Wdeclaration-after-statement
|
||||
#WFLAGS+=-Wdeclaration-after-statement
|
||||
WFLAGS+=-Wno-error=declaration-after-statement
|
||||
endif
|
||||
WFLAGS+=-Wundef
|
||||
|
||||
@@ -35,11 +35,9 @@ static inline void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cm
|
||||
if (!sonic || sonic->health <= 0)
|
||||
return;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
// Lua can handle it!
|
||||
if (LUAh_BotAI(sonic, tails, cmd))
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (tails->player->pflags & (PF_MACESPIN|PF_ITEMHANG))
|
||||
{
|
||||
@@ -123,11 +121,9 @@ void B_BuildTiccmd(player_t *player, ticcmd_t *cmd)
|
||||
// Bot AI isn't programmed in analog.
|
||||
//CV_SetValue(&cv_analog2, false);
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
// Let Lua scripts build ticcmds
|
||||
if (LUAh_BotTiccmd(player, cmd))
|
||||
return;
|
||||
#endif
|
||||
|
||||
// We don't have any main character AI, sorry. D:
|
||||
if (player-players == consoleplayer)
|
||||
|
||||
@@ -10,8 +10,6 @@ WFLAGS+=-Wno-logical-op
|
||||
endif
|
||||
endif
|
||||
|
||||
OPTS+=-DHAVE_BLUA
|
||||
|
||||
OBJS:=$(OBJS) \
|
||||
$(OBJDIR)/lapi.o \
|
||||
$(OBJDIR)/lbaselib.o \
|
||||
|
||||
+1
-1
@@ -134,7 +134,7 @@ void luaV_gettable (lua_State *L, TValue *t, TValue *key, StkId val) {
|
||||
void luaV_settable (lua_State *L, TValue *t, TValue *key, StkId val) {
|
||||
int loop;
|
||||
for (loop = 0; loop < MAXTAGLOOP; loop++) {
|
||||
TValue *tm;
|
||||
TValue *tm = NULL;
|
||||
if (ttistable(t)) { /* `t' is a table? */
|
||||
Table *h = hvalue(t);
|
||||
TValue *oldval = luaH_set(L, h, key); /* do a primitive set */
|
||||
|
||||
+2
-17
@@ -459,13 +459,11 @@ void COM_AddCommand(const char *name, com_func_t func)
|
||||
{
|
||||
if (!stricmp(name, cmd->name)) //case insensitive now that we have lower and uppercase!
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
// don't I_Error for Lua commands
|
||||
// Lua commands can replace game commands, and they have priority.
|
||||
// BUT, if for some reason we screwed up and made two console commands with the same name,
|
||||
// it's good to have this here so we find out.
|
||||
if (cmd->function != COM_Lua_f)
|
||||
#endif
|
||||
I_Error("Command %s already exists\n", name);
|
||||
|
||||
return;
|
||||
@@ -479,7 +477,6 @@ void COM_AddCommand(const char *name, com_func_t func)
|
||||
com_commands = cmd;
|
||||
}
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
/** Adds a console command for Lua.
|
||||
* No I_Errors allowed; return a negative code instead.
|
||||
*
|
||||
@@ -512,7 +509,6 @@ int COM_AddLuaCommand(const char *name)
|
||||
com_commands = cmd;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Tests if a command exists.
|
||||
*
|
||||
@@ -1445,17 +1441,6 @@ found:
|
||||
var->value = atoi(var->string);
|
||||
|
||||
finish:
|
||||
// See the note above.
|
||||
/* if (var->flags & CV_CHEAT)
|
||||
{
|
||||
boolean newcheats = CV_CheatsEnabled();
|
||||
|
||||
if (!prevcheats && newcheats)
|
||||
CONS_Printf(M_GetText("Cheats have been enabled.\n"));
|
||||
else if (prevcheats && !newcheats)
|
||||
CONS_Printf(M_GetText("Cheats have been disabled.\n"));
|
||||
} */
|
||||
|
||||
if (var->flags & CV_SHOWMODIFONETIME || var->flags & CV_SHOWMODIF)
|
||||
{
|
||||
CONS_Printf(M_GetText("%s set to %s\n"), var->name, var->string);
|
||||
@@ -1466,10 +1451,10 @@ finish:
|
||||
DEBFILE(va("%s set to %s\n", var->name, var->string));
|
||||
}
|
||||
var->flags |= CV_MODIFIED;
|
||||
|
||||
// raise 'on change' code
|
||||
#ifdef HAVE_BLUA
|
||||
LUA_CVarChanged(var->name); // let consolelib know what cvar this is.
|
||||
#endif
|
||||
|
||||
if (var->flags & CV_CALL && !stealth)
|
||||
var->func();
|
||||
|
||||
|
||||
+15
-18
@@ -66,8 +66,8 @@ static INT32 con_curlines; // vid lines currently used by console
|
||||
|
||||
INT32 con_clipviewtop; // (useless)
|
||||
|
||||
static INT32 con_hudlines; // number of console heads up message lines
|
||||
static INT32 con_hudtime[MAXHUDLINES]; // remaining time of display for hud msg lines
|
||||
static UINT8 con_hudlines; // number of console heads up message lines
|
||||
static UINT32 con_hudtime[MAXHUDLINES]; // remaining time of display for hud msg lines
|
||||
|
||||
INT32 con_clearlines; // top screen lines to refresh when view reduced
|
||||
boolean con_hudupdate; // when messages scroll, we need a backgrnd refresh
|
||||
@@ -112,16 +112,18 @@ static void CONS_backcolor_Change(void);
|
||||
#ifdef macintosh
|
||||
#define CON_BUFFERSIZE 4096 // my compiler can't handle local vars >32k
|
||||
#else
|
||||
#define CON_BUFFERSIZE 16384
|
||||
#define CON_BUFFERSIZE 32768
|
||||
#endif
|
||||
|
||||
static char con_buffer[CON_BUFFERSIZE];
|
||||
|
||||
// how many seconds the hud messages lasts on the screen
|
||||
static consvar_t cons_msgtimeout = {"con_hudtime", "5", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
// CV_Unsigned can overflow when multiplied by TICRATE later, so let's use a 3-year limit instead
|
||||
static CV_PossibleValue_t hudtime_cons_t[] = {{0, "MIN"}, {99999999, "MAX"}, {0, NULL}};
|
||||
static consvar_t cons_hudtime = {"con_hudtime", "5", CV_SAVE, hudtime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// number of lines displayed on the HUD
|
||||
static consvar_t cons_hudlines = {"con_hudlines", "5", CV_CALL|CV_SAVE, CV_Unsigned, CONS_hudlines_Change, 0, NULL, NULL, 0, 0, NULL};
|
||||
static CV_PossibleValue_t hudlines_cons_t[] = {{0, "MIN"}, {MAXHUDLINES, "MAX"}, {0, NULL}};
|
||||
static consvar_t cons_hudlines = {"con_hudlines", "5", CV_CALL|CV_SAVE, hudlines_cons_t, CONS_hudlines_Change, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// number of lines console move per frame
|
||||
// (con_speed needs a limit, apparently)
|
||||
@@ -181,11 +183,6 @@ static void CONS_hudlines_Change(void)
|
||||
for (i = 0; i < con_hudlines; i++)
|
||||
con_hudtime[i] = 0;
|
||||
|
||||
if (cons_hudlines.value < 1)
|
||||
cons_hudlines.value = 1;
|
||||
else if (cons_hudlines.value > MAXHUDLINES)
|
||||
cons_hudlines.value = MAXHUDLINES;
|
||||
|
||||
con_hudlines = cons_hudlines.value;
|
||||
|
||||
Unlock_state();
|
||||
@@ -426,7 +423,7 @@ void CON_Init(void)
|
||||
|
||||
Unlock_state();
|
||||
|
||||
CV_RegisterVar(&cons_msgtimeout);
|
||||
CV_RegisterVar(&cons_hudtime);
|
||||
CV_RegisterVar(&cons_hudlines);
|
||||
CV_RegisterVar(&cons_speed);
|
||||
CV_RegisterVar(&cons_height);
|
||||
@@ -743,9 +740,8 @@ void CON_Ticker(void)
|
||||
// make overlay messages disappear after a while
|
||||
for (i = 0; i < con_hudlines; i++)
|
||||
{
|
||||
con_hudtime[i]--;
|
||||
if (con_hudtime[i] < 0)
|
||||
con_hudtime[i] = 0;
|
||||
if (con_hudtime[i])
|
||||
con_hudtime[i]--;
|
||||
}
|
||||
|
||||
Unlock_state();
|
||||
@@ -1244,7 +1240,8 @@ boolean CON_Responder(event_t *ev)
|
||||
static void CON_Linefeed(void)
|
||||
{
|
||||
// set time for heads up messages
|
||||
con_hudtime[con_cy%con_hudlines] = cons_msgtimeout.value*TICRATE;
|
||||
if (con_hudlines)
|
||||
con_hudtime[con_cy%con_hudlines] = cons_hudtime.value*TICRATE;
|
||||
|
||||
con_cy++;
|
||||
con_cx = 0;
|
||||
@@ -1600,7 +1597,7 @@ static void CON_DrawHudlines(void)
|
||||
INT32 charwidth = 8 * con_scalefactor;
|
||||
INT32 charheight = 8 * con_scalefactor;
|
||||
|
||||
if (con_hudlines <= 0)
|
||||
if (!con_hudlines)
|
||||
return;
|
||||
|
||||
if (chat_on && OLDCHAT)
|
||||
@@ -1608,7 +1605,7 @@ static void CON_DrawHudlines(void)
|
||||
else
|
||||
y = 0;
|
||||
|
||||
for (i = con_cy - con_hudlines+1; i <= con_cy; i++)
|
||||
for (i = con_cy - con_hudlines; i <= con_cy; i++)
|
||||
{
|
||||
size_t c;
|
||||
INT32 x;
|
||||
|
||||
+46
-53
@@ -139,7 +139,7 @@ static UINT8 localtextcmd3[MAXTEXTCMD]; // splitscreen == 2
|
||||
static UINT8 localtextcmd4[MAXTEXTCMD]; // splitscreen == 3
|
||||
static tic_t neededtic;
|
||||
SINT8 servernode = 0; // the number of the server node
|
||||
char connectedservername[MAXSERVERNAME];
|
||||
char connectedservername[MAXSERVERNAME+1];
|
||||
/// \brief do we accept new players?
|
||||
/// \todo WORK!
|
||||
boolean acceptnewnode = true;
|
||||
@@ -1138,7 +1138,7 @@ static void GetPackets(void);
|
||||
static cl_mode_t cl_mode = CL_SEARCHING;
|
||||
|
||||
#ifdef HAVE_CURL
|
||||
char http_source[MAX_MIRROR_LENGTH];
|
||||
char http_source[MAX_MIRROR_LENGTH+1];
|
||||
#endif
|
||||
|
||||
static UINT16 cl_lastcheckedfilecount = 0; // used for full file list
|
||||
@@ -1625,7 +1625,12 @@ static void SV_SendPlayerInfo(INT32 node)
|
||||
}
|
||||
|
||||
netbuffer->u.playerinfo[i].node = i;
|
||||
|
||||
// Can't really change this because net compatibility, but the warning is annoying
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstringop-truncation"
|
||||
strncpy(netbuffer->u.playerinfo[i].name, (const char *)&player_names[i], MAXPLAYERNAME+1);
|
||||
#pragma GCC diagnostic pop
|
||||
netbuffer->u.playerinfo[i].name[MAXPLAYERNAME] = '\0';
|
||||
|
||||
//fetch IP address
|
||||
@@ -1929,7 +1934,6 @@ static void CL_LoadReceivedSavegame(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Can't load the level!\n"));
|
||||
Z_Free(savebuffer);
|
||||
save_p = NULL;
|
||||
if (unlink(tmpsave) == -1)
|
||||
@@ -2164,6 +2168,18 @@ static void M_ConfirmConnect(event_t *ev)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void AbortConnection(void)
|
||||
{
|
||||
CURLAbortFile();
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
D_StartTitle();
|
||||
|
||||
// Will be reset by caller. Signals refusal.
|
||||
cl_mode = CL_ABORTED;
|
||||
}
|
||||
|
||||
|
||||
static boolean CL_FinishedFileList(void)
|
||||
{
|
||||
INT32 i;
|
||||
@@ -2176,9 +2192,7 @@ static boolean CL_FinishedFileList(void)
|
||||
}
|
||||
else if (i == 3) // too many files
|
||||
{
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
D_StartTitle();
|
||||
AbortConnection();
|
||||
M_StartMessage(M_GetText(
|
||||
"You have too many WAD files loaded\n"
|
||||
"to add ones the server is using.\n"
|
||||
@@ -2189,9 +2203,7 @@ static boolean CL_FinishedFileList(void)
|
||||
}
|
||||
else if (i == 2) // cannot join for some reason
|
||||
{
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
D_StartTitle();
|
||||
AbortConnection();
|
||||
M_StartMessage(M_GetText(
|
||||
"You have the wrong addons loaded.\n\n"
|
||||
"To play on this server, restart\n"
|
||||
@@ -2228,9 +2240,7 @@ static boolean CL_FinishedFileList(void)
|
||||
{
|
||||
if (!CL_CheckDownloadable()) // nope!
|
||||
{
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
D_StartTitle();
|
||||
AbortConnection();
|
||||
M_StartMessage(M_GetText(
|
||||
"An error occured when trying to\n"
|
||||
"download missing addons.\n"
|
||||
@@ -2455,9 +2465,6 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
|
||||
break;
|
||||
}
|
||||
|
||||
if (curl_running)
|
||||
CURLGetFile();
|
||||
|
||||
if (waitmore)
|
||||
break; // exit the case
|
||||
|
||||
@@ -2491,9 +2498,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
|
||||
{
|
||||
CONS_Printf(M_GetText("Legacy downloader request packet failed.\n"));
|
||||
CONS_Printf(M_GetText("Network game synchronization aborted.\n"));
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
D_StartTitle();
|
||||
AbortConnection();
|
||||
M_StartMessage(M_GetText(
|
||||
"The direct download encountered an error.\n"
|
||||
"See the logfile for more info.\n"
|
||||
@@ -2520,9 +2525,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
|
||||
{
|
||||
CONS_Printf("%d minute wait time exceeded.\n", cv_connectawaittime.value);
|
||||
CONS_Printf(M_GetText("Network game synchronization aborted.\n"));
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
D_StartTitle();
|
||||
AbortConnection();
|
||||
M_StartMessage(va(
|
||||
"%d minute wait time exceeded.\n"
|
||||
"You may retry connection.\n"
|
||||
@@ -2594,9 +2597,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
|
||||
if (!modeattacking && (key == KEY_ESCAPE || key == KEY_JOY1+1 || cl_mode == CL_ABORTED))
|
||||
{
|
||||
CONS_Printf(M_GetText("Network game synchronization aborted.\n"));
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
D_StartTitle();
|
||||
AbortConnection();
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -3186,11 +3187,7 @@ void CL_RemovePlayer(INT32 playernum, INT32 reason)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
LUAh_PlayerQuit(&players[playernum], reason); // Lua hook for player quitting
|
||||
#else
|
||||
(void)reason;
|
||||
#endif
|
||||
|
||||
// Reset player data
|
||||
CL_ClearPlayer(playernum);
|
||||
@@ -3214,13 +3211,9 @@ void CL_RemovePlayer(INT32 playernum, INT32 reason)
|
||||
if (playernum == displayplayers[0] && !demo.playback)
|
||||
displayplayers[0] = consoleplayer; // don't look through someone's view who isn't there
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
LUA_InvalidatePlayer(&players[playernum]);
|
||||
#endif
|
||||
|
||||
/*if (G_TagGametype()) //Check if you still have a game. Location flexible. =P
|
||||
P_CheckSurvivors();
|
||||
else*/ if (G_BattleGametype()) // SRB2Kart
|
||||
if (G_BattleGametype()) // SRB2Kart
|
||||
K_CheckBumpers();
|
||||
else if (G_RaceGametype())
|
||||
P_CheckRacers();
|
||||
@@ -3836,9 +3829,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
||||
#ifdef DUMPCONSISTENCY
|
||||
if (msg == KICK_MSG_CON_FAIL) SV_SavedGame();
|
||||
#endif
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
D_StartTitle();
|
||||
AbortConnection();
|
||||
|
||||
if (msg == KICK_MSG_CON_FAIL)
|
||||
M_StartMessage(M_GetText("Server closed connection\n(Synch failure)\nPress ESC\n"), NULL, MM_NOTHING);
|
||||
@@ -3954,7 +3945,7 @@ static void Command_list_http_logins (void)
|
||||
}
|
||||
#endif/*HAVE_CURL*/
|
||||
|
||||
static CV_PossibleValue_t netticbuffer_cons_t[] = {{0, "MIN"}, {3, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t netticbuffer_cons_t[] = {{0, "MIN"}, {0.5, "0.5"}, {0.7, "0.7"}, {1, "1"}, {2, "2"}, {3, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_netticbuffer = {"netticbuffer", "1", CV_SAVE, netticbuffer_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static void Joinable_OnChange(void);
|
||||
@@ -4099,9 +4090,7 @@ void SV_ResetServer(void)
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
LUA_InvalidatePlayer(&players[i]);
|
||||
#endif
|
||||
playeringame[i] = false;
|
||||
playernode[i] = UINT8_MAX;
|
||||
sprintf(player_names[i], "Player %d", i + 1);
|
||||
@@ -4287,9 +4276,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
||||
if (server && multiplayer && motd[0] != '\0')
|
||||
COM_BufAddText(va("sayto %d %s\n", newplayernum, motd));
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
LUAh_PlayerJoin(newplayernum);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
DRPC_UpdatePresence();
|
||||
@@ -4989,11 +4976,11 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
||||
* \sa HandlePacketFromPlayer
|
||||
*
|
||||
*/
|
||||
static boolean CheckForSpeedHacks(UINT8 p)
|
||||
static boolean CheckForSpeedHacks(UINT8 p, tic_t faketic)
|
||||
{
|
||||
if (netcmds[maketic%TICQUEUE][p].forwardmove > MAXPLMOVE || netcmds[maketic%TICQUEUE][p].forwardmove < -MAXPLMOVE
|
||||
|| netcmds[maketic%TICQUEUE][p].sidemove > MAXPLMOVE || netcmds[maketic%TICQUEUE][p].sidemove < -MAXPLMOVE
|
||||
|| netcmds[maketic%TICQUEUE][p].driftturn > KART_FULLTURN || netcmds[maketic%TICQUEUE][p].driftturn < -KART_FULLTURN)
|
||||
if (netcmds[faketic%TICQUEUE][p].forwardmove > MAXPLMOVE || netcmds[faketic%TICQUEUE][p].forwardmove < -MAXPLMOVE
|
||||
|| netcmds[faketic%TICQUEUE][p].sidemove > MAXPLMOVE || netcmds[faketic%TICQUEUE][p].sidemove < -MAXPLMOVE
|
||||
|| netcmds[faketic%TICQUEUE][p].driftturn > KART_FULLTURN || netcmds[faketic%TICQUEUE][p].driftturn < -KART_FULLTURN)
|
||||
{
|
||||
char buf[2];
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal movement value received from node %d\n"), playernode[p]);
|
||||
@@ -5091,6 +5078,12 @@ static void HandlePacketFromPlayer(SINT8 node)
|
||||
// As long as clients send valid ticcmds, the server can keep running, so reset the timeout
|
||||
/// \todo Use a separate cvar for that kind of timeout?
|
||||
freezetimeout[node] = I_GetTime() + connectiontimeout;
|
||||
|
||||
// If we've alredy received a ticcmd for this tic, just submit it for the next one.
|
||||
tic_t faketic = maketic;
|
||||
if ((!!(netcmds[maketic % TICQUEUE][netconsole].angleturn & TICCMD_RECEIVED))
|
||||
&& (maketic - firstticstosend < TICQUEUE))
|
||||
faketic++;
|
||||
|
||||
// Don't do anything for packets of type NODEKEEPALIVE?
|
||||
// Sryder 2018/07/01: Update the freezetimeout still!
|
||||
@@ -5099,10 +5092,10 @@ static void HandlePacketFromPlayer(SINT8 node)
|
||||
break;
|
||||
|
||||
// Copy ticcmd
|
||||
G_MoveTiccmd(&netcmds[maketic%TICQUEUE][netconsole], &netbuffer->u.clientpak.cmd, 1);
|
||||
G_MoveTiccmd(&netcmds[faketic%TICQUEUE][netconsole], &netbuffer->u.clientpak.cmd, 1);
|
||||
|
||||
// Check ticcmd for "speed hacks"
|
||||
if (CheckForSpeedHacks((UINT8)netconsole))
|
||||
if (CheckForSpeedHacks((UINT8)netconsole, faketic))
|
||||
break;
|
||||
|
||||
// Splitscreen cmd
|
||||
@@ -5111,10 +5104,10 @@ static void HandlePacketFromPlayer(SINT8 node)
|
||||
|| (netbuffer->packettype == PT_CLIENT4CMD || netbuffer->packettype == PT_CLIENT4MIS))
|
||||
&& (nodetoplayer2[node] >= 0))
|
||||
{
|
||||
G_MoveTiccmd(&netcmds[maketic%TICQUEUE][(UINT8)nodetoplayer2[node]],
|
||||
G_MoveTiccmd(&netcmds[faketic%TICQUEUE][(UINT8)nodetoplayer2[node]],
|
||||
&netbuffer->u.client2pak.cmd2, 1);
|
||||
|
||||
if (CheckForSpeedHacks((UINT8)nodetoplayer2[node]))
|
||||
if (CheckForSpeedHacks((UINT8)nodetoplayer2[node], faketic))
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -5122,20 +5115,20 @@ static void HandlePacketFromPlayer(SINT8 node)
|
||||
|| (netbuffer->packettype == PT_CLIENT4CMD || netbuffer->packettype == PT_CLIENT4MIS))
|
||||
&& (nodetoplayer3[node] >= 0))
|
||||
{
|
||||
G_MoveTiccmd(&netcmds[maketic%TICQUEUE][(UINT8)nodetoplayer3[node]],
|
||||
G_MoveTiccmd(&netcmds[faketic%TICQUEUE][(UINT8)nodetoplayer3[node]],
|
||||
&netbuffer->u.client3pak.cmd3, 1);
|
||||
|
||||
if (CheckForSpeedHacks((UINT8)nodetoplayer3[node]))
|
||||
if (CheckForSpeedHacks((UINT8)nodetoplayer3[node], faketic))
|
||||
break;
|
||||
}
|
||||
|
||||
if ((netbuffer->packettype == PT_CLIENT4CMD || netbuffer->packettype == PT_CLIENT4MIS)
|
||||
&& (nodetoplayer4[node] >= 0))
|
||||
{
|
||||
G_MoveTiccmd(&netcmds[maketic%TICQUEUE][(UINT8)nodetoplayer4[node]],
|
||||
G_MoveTiccmd(&netcmds[faketic%TICQUEUE][(UINT8)nodetoplayer4[node]],
|
||||
&netbuffer->u.client4pak.cmd4, 1);
|
||||
|
||||
if (CheckForSpeedHacks((UINT8)nodetoplayer4[node]))
|
||||
if (CheckForSpeedHacks((UINT8)nodetoplayer4[node], faketic))
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -553,7 +553,7 @@ extern boolean dedicated; // For dedicated server
|
||||
extern UINT16 software_MAXPACKETLENGTH;
|
||||
extern boolean acceptnewnode;
|
||||
extern SINT8 servernode;
|
||||
extern char connectedservername[MAXSERVERNAME];
|
||||
extern char connectedservername[MAXSERVERNAME+1];
|
||||
|
||||
void Command_Ping_f(void);
|
||||
extern tic_t connectiontimeout;
|
||||
|
||||
+32
-19
@@ -70,6 +70,8 @@
|
||||
#include "d_protocol.h"
|
||||
#include "m_perfstats.h"
|
||||
|
||||
#include "lua_script.h"
|
||||
|
||||
#ifdef CMAKECONFIG
|
||||
#include "config.h"
|
||||
#else
|
||||
@@ -84,10 +86,6 @@
|
||||
#include "hardware/hw3sound.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
#include "lua_script.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
#include "discord.h"
|
||||
#endif
|
||||
@@ -449,17 +447,14 @@ static void D_Display(void)
|
||||
viewwindowx = 0;
|
||||
viewwindowy = viewheight;
|
||||
}
|
||||
M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0]));
|
||||
break;
|
||||
case 2:
|
||||
viewwindowx = 0;
|
||||
viewwindowy = viewheight;
|
||||
M_Memcpy(ylookup, ylookup3, viewheight*sizeof (ylookup[0]));
|
||||
break;
|
||||
case 3:
|
||||
viewwindowx = viewwidth;
|
||||
viewwindowy = viewheight;
|
||||
M_Memcpy(ylookup, ylookup4, viewheight*sizeof (ylookup[0]));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -469,9 +464,6 @@ static void D_Display(void)
|
||||
}
|
||||
|
||||
R_RenderPlayerView(&players[displayplayers[i]]);
|
||||
|
||||
if (i > 0)
|
||||
M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -771,9 +763,7 @@ void D_SRB2Loop(void)
|
||||
HW3S_EndFrameUpdate();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
LUA_Step();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
if (! dedicated)
|
||||
@@ -970,7 +960,7 @@ static void D_FindAddonsToAutoload(void)
|
||||
|
||||
INT32 i, len;
|
||||
boolean hasprefix = false;
|
||||
char wadsToAutoload[256] = "", renameAutoloadStrings[256] = "";
|
||||
char wadsToAutoload[256] = "";
|
||||
|
||||
// does it exist tho
|
||||
autoloadpath = va("%s"PATHSEP"%s",srb2home,AUTOLOADCONFIGFILENAME);
|
||||
@@ -1074,15 +1064,21 @@ static boolean AddIWAD(void)
|
||||
}
|
||||
}
|
||||
|
||||
// extra graphic patches for saturn specific thingies
|
||||
boolean found_extra_kart;
|
||||
boolean found_extra2_kart;
|
||||
|
||||
boolean snw_speedo; // snowy speedometer check
|
||||
boolean xtra_speedo; // extra speedometer check
|
||||
boolean xtra_speedo_clr; // extra speedometer colour check
|
||||
boolean achi_speedo; // achiiro speedometer check
|
||||
boolean achi_speedo_clr; // extra speedometer colour check
|
||||
boolean clr_hud; // colour hud check
|
||||
boolean big_lap; // bigger lap counter
|
||||
boolean big_lap_color; // bigger lap counter but colour
|
||||
boolean kartzspeedo; // kartZ speedometer
|
||||
boolean statdp; // New stat
|
||||
boolean kartzspeedo; // kartZ speedo
|
||||
boolean statdp; // stat display for extended player setup
|
||||
boolean nametaggfx; // Nametag stuffs
|
||||
boolean driftgaugegfx;
|
||||
|
||||
static void IdentifyVersion(void)
|
||||
{
|
||||
@@ -1444,9 +1440,19 @@ void D_SRB2Main(void)
|
||||
if (found_extra2_kart)
|
||||
mainwads++;
|
||||
|
||||
// now check for speedometer stuff
|
||||
// now check for extra speedometer stuff
|
||||
if (W_CheckMultipleLumps("SP_SMSTC", "K_TRNULL", "SP_MKMH", "SP_MMPH", "SP_MFRAC", "SP_MPERC", NULL))
|
||||
snw_speedo = true;
|
||||
xtra_speedo = true;
|
||||
|
||||
if (W_CheckMultipleLumps("SC_SMSTC", NULL))
|
||||
xtra_speedo_clr = true;
|
||||
|
||||
// now check for achii speedometer stuff
|
||||
if (W_CheckMultipleLumps("SP_AMSTC", "K_TRNULL", "SP_AKMH", "SP_AMPH", "SP_AFRAC", "SP_APERC", NULL))
|
||||
achi_speedo = true;
|
||||
|
||||
if (W_CheckMultipleLumps("SC_AMSTC", "K_TRNULL", "SC_AKMH", "SC_AMPH", "SC_AFRAC", "SC_APERC", NULL))
|
||||
achi_speedo_clr = true;
|
||||
|
||||
// check for bigger lap count
|
||||
if (W_CheckMultipleLumps("K_STLAPB", "K_STLA2B", NULL))
|
||||
@@ -1454,7 +1460,7 @@ void D_SRB2Main(void)
|
||||
|
||||
// now check for colour hud stuff
|
||||
if (W_CheckMultipleLumps("K_SCTIME", "K_SCTIMW", "K_SCLAPS", "K_SCLAPW", \
|
||||
"K_SCBALN", "K_SCBALW", "K_SCKARM", "K_SCTOUT", "K_ISMULC", "K_ITMULC", "K_ITBC","K_ITBCD", "K_ISBC", "K_ISBCD", NULL))
|
||||
"K_SCBALN", "K_SCBALW", "K_SCKARM", "K_SCTOUT", "K_ISMULC", "K_ITMULC", "K_ITBC", "K_ITBCD", "K_ISBC", "K_ISBCD", NULL))
|
||||
clr_hud = true;
|
||||
|
||||
// check for bigger lap count but color** its color bitch
|
||||
@@ -1472,6 +1478,13 @@ void D_SRB2Main(void)
|
||||
if (W_CheckMultipleLumps("K_STATNB", "K_STATN1", "K_STATN2", "K_STATN3", "K_STATN4", \
|
||||
"K_STATN5", "K_STATN6", NULL))
|
||||
statdp = true;
|
||||
|
||||
// Nametag stuffs
|
||||
if (W_CheckMultipleLumps("NTLINE", "NTLINEV", "NTSP", "NTWH", NULL))
|
||||
nametaggfx = true;
|
||||
|
||||
if (W_CheckMultipleLumps("K_DGAU","K_DCAU","K_DGSU","K_DCSU", NULL))
|
||||
driftgaugegfx = true;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
+11
-4
@@ -28,12 +28,19 @@ extern char srb2path[256]; //Alam: SRB2's Home
|
||||
extern boolean found_extra_kart; // for use in k_kart.c
|
||||
extern boolean found_extra2_kart; // for use in k_kart.c
|
||||
|
||||
extern boolean snw_speedo; // snowy speedometer check
|
||||
// extra graphic patches for saturn specific thingies
|
||||
extern boolean xtra_speedo; // extra speedometer check
|
||||
extern boolean xtra_speedo_clr; // extra speedometer colour check
|
||||
extern boolean achi_speedo; // achiiro speedometer check
|
||||
extern boolean achi_speedo_clr; // extra speedometer colour check
|
||||
extern boolean clr_hud; // colour hud check
|
||||
extern boolean big_lap; // bigger lap counter
|
||||
extern boolean big_lap_color; //bigger lap counter but colour
|
||||
extern boolean kartzspeedo; //kartZ speedo
|
||||
extern boolean statdp; //stat display for extended player setup
|
||||
extern boolean big_lap_color; // bigger lap counter but colour
|
||||
extern boolean kartzspeedo; // kartZ speedo
|
||||
extern boolean statdp; // stat display for extended player setup
|
||||
extern boolean nametaggfx; // Nametag stuffs
|
||||
extern boolean driftgaugegfx;
|
||||
|
||||
|
||||
extern boolean autoloading;
|
||||
extern boolean autoloaded;
|
||||
|
||||
+4
-3
@@ -1010,7 +1010,7 @@ void Command_Droprate(void)
|
||||
static boolean ShouldDropPacket(void)
|
||||
{
|
||||
return (packetdropquantity[netbuffer->packettype])
|
||||
|| (packetdroprate != 0 && rand() < (RAND_MAX * (packetdroprate / 100.f))) || packetdroprate == 100;
|
||||
|| (packetdroprate != 0 && rand() < (((double)RAND_MAX) * (packetdroprate / 100.f))) || packetdroprate == 100;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -1171,8 +1171,9 @@ boolean HGetPacket(void)
|
||||
if (netbuffer->checksum != NetbufferChecksum())
|
||||
{
|
||||
DEBFILE("Bad packet checksum\n");
|
||||
//Net_CloseConnection(nodejustjoined ? (doomcom->remotenode | FORCECLOSE) : doomcom->remotenode);
|
||||
Net_CloseConnection(doomcom->remotenode);
|
||||
// Do not disconnect or anything, just ignore the packet.
|
||||
// Bad checksums with UDP tend to happen very scarcely
|
||||
// so they are not normally an issue.
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
+73
-122
@@ -73,9 +73,6 @@ static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum);
|
||||
static void Got_ModifyVotecmd(UINT8 **cp, INT32 playernum);
|
||||
static void Got_PickVotecmd(UINT8 **cp, INT32 playernum);
|
||||
static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum);
|
||||
#ifdef DELFILE
|
||||
static void Got_Delfilecmd(UINT8 **cp, INT32 playernum);
|
||||
#endif
|
||||
static void Got_Addfilecmd(UINT8 **cp, INT32 playernum);
|
||||
static void Got_Pause(UINT8 **cp, INT32 playernum);
|
||||
static void Got_Respawn(UINT8 **cp, INT32 playernum);
|
||||
@@ -144,9 +141,6 @@ static void Command_Addfile(void);
|
||||
static void Command_Addskins(void);
|
||||
static void Command_GLocalSkin(void);
|
||||
static void Command_ListWADS_f(void);
|
||||
#ifdef DELFILE
|
||||
static void Command_Delfile(void);
|
||||
#endif
|
||||
static void Command_RunSOC(void);
|
||||
static void Command_Pause(void);
|
||||
static void Command_Respawn(void);
|
||||
@@ -199,10 +193,8 @@ static void Command_SkinSearch(void);
|
||||
|
||||
#ifdef _DEBUG
|
||||
static void Command_Togglemodified_f(void);
|
||||
#ifdef HAVE_BLUA
|
||||
static void Command_Archivetest_f(void);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// =========================================================================
|
||||
// CLIENT VARIABLES
|
||||
@@ -460,7 +452,7 @@ static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, "
|
||||
consvar_t cv_basenumlaps = {"basenumlaps", "Map default", CV_NETVAR|CV_CALL|CV_CHEAT, basenumlaps_cons_t, BaseNumLaps_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_forceskin = {"forceskin", "Off", CV_NETVAR|CV_CALL|CV_CHEAT, Forceskin_cons_t, ForceSkin_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_fakelocalskin = {"fakelocalskin", "None", CV_SAVE, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_fakelocalskin = {"fakelocalskin", "None", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_downloading = {"downloading", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_allowexitlevel = {"allowexitlevel", "No", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
@@ -513,6 +505,45 @@ consvar_t cv_mute = {"mute", "Off", CV_NETVAR|CV_CALL, CV_OnOff, Mute_OnChange,
|
||||
|
||||
consvar_t cv_sleep = {"cpusleep", "1", CV_SAVE, sleeping_cons_t, NULL, -1, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t nametagtrans_cons_t[] = {
|
||||
{0, "Never"}, {1, "Far only"}, {2, "Dynamic"}, {3, "Always"}, {4, "HUD Trans."}, {0, NULL}};
|
||||
/*static CV_PossibleValue_t nametagscaling_cons_t[] = {
|
||||
{0, "MIN"}, {320, "MAX"}, {0, NULL}};*/
|
||||
static CV_PossibleValue_t nametagdistance_cons_t[] = {
|
||||
{0, "MIN"}, {640, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t nametagmaxplayer_cons_t[] = {
|
||||
{1, "MIN"}, {MAXPLAYERS, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t nametagsize_cons_t[] = {
|
||||
{0, "Off"}, {1, "Small"}, {2, "Minimal"}, {0, NULL}};
|
||||
static CV_PossibleValue_t nametagrestat_cons_t[] = {
|
||||
{0, "Off"}, {1, "Restat"}, {2, "Always"}, {0, NULL}};
|
||||
|
||||
|
||||
consvar_t cv_nametag = {"kartnametag", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_nametagtrans = {"kartnametagtransparency", "Dynamic", CV_SAVE, nametagtrans_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_nametagfacerank = {"kartnametagfacerank", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_nametagrestat = {"kartnametagrestat", "Restat", CV_SAVE, nametagrestat_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_nametagdist = {"kartnametagdist", "320", CV_SAVE, nametagdistance_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_nametagmaxplayers = {"kartnametagmaxplayers", "3", CV_SAVE, nametagmaxplayer_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_nametagmaxlenght = {"kartnametagmaxlenght", "12", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
//consvar_t cv_nametagscaling = {"nametagscaling", "160", CV_SAVE, nametagscaling_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_showownnametag = {"kartnametagshowown", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_smallnametags = {"kartnametagsmall", "Off", CV_SAVE, nametagsize_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_nametaghop = {"kartnametaghop", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_nametagscore = {"kartnametagscore", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_shownametagfinish = {"kartshownametagfinished", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_shownametagspectator = {"kartshownametagspectator", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t driftgaugeoffset_cons_t[] = {
|
||||
{-FRACUNIT*128, "MIN"}, {FRACUNIT*128, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t driftgaugestyle_cons_t[] = {
|
||||
{1, "Default"}, {2, "Small"}, {3, "Big Numbers"}, {4, "Numbers Only"}, {0, NULL}};
|
||||
|
||||
consvar_t cv_driftgauge = {"kartdriftgauge", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_driftgaugeofs = {"kartdriftgaugeoffset", "-20", CV_FLOAT|CV_SAVE, driftgaugeoffset_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_driftgaugetrans = {"kartdriftgaugetransparency", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_driftgaugestyle = {"kartdriftgaugestyle", "1", CV_SAVE, driftgaugestyle_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t skinselectspin_cons_t[] = {
|
||||
{0, "Off"}, {1, "Slow"}, {2, "2"}, {3, "3"}, {4, "4"}, {5, "5"}, {6, "6"}, {7, "7"}, {8, "8"}, {9, "9"}, {10, "Fast"}, {SKINSELECTSPIN_PAIN, "Pain"}, {0, NULL}};
|
||||
consvar_t cv_skinselectspin = {"skinselectspin", "5", CV_SAVE, skinselectspin_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
@@ -573,7 +604,7 @@ const char *netxcmdnames[MAXNETXCMD - 1] =
|
||||
"RANDOMSEED",
|
||||
"RUNSOC",
|
||||
"REQADDFILE",
|
||||
"DELFILE",
|
||||
"DELFILE", // sigh well this prob needs to be still here to not screw up maxnetxcmd
|
||||
"SETMOTD",
|
||||
"RESPAWN",
|
||||
"DEMOTED",
|
||||
@@ -581,10 +612,8 @@ const char *netxcmdnames[MAXNETXCMD - 1] =
|
||||
"MODIFYVOTE",
|
||||
"PICKVOTE",
|
||||
"REMOVEPLAYER",
|
||||
#ifdef HAVE_BLUA
|
||||
"LUACMD",
|
||||
"LUAVAR"
|
||||
#endif
|
||||
};
|
||||
|
||||
// =========================================================================
|
||||
@@ -622,15 +651,10 @@ void D_RegisterServerCommands(void)
|
||||
RegisterNetXCmd(XD_EXITLEVEL, Got_ExitLevelcmd);
|
||||
RegisterNetXCmd(XD_ADDFILE, Got_Addfilecmd);
|
||||
RegisterNetXCmd(XD_REQADDFILE, Got_RequestAddfilecmd);
|
||||
#ifdef DELFILE
|
||||
RegisterNetXCmd(XD_DELFILE, Got_Delfilecmd);
|
||||
#endif
|
||||
RegisterNetXCmd(XD_PAUSE, Got_Pause);
|
||||
RegisterNetXCmd(XD_RESPAWN, Got_Respawn);
|
||||
RegisterNetXCmd(XD_RUNSOC, Got_RunSOCcmd);
|
||||
#ifdef HAVE_BLUA
|
||||
RegisterNetXCmd(XD_LUACMD, Got_Luacmd);
|
||||
#endif
|
||||
|
||||
RegisterNetXCmd(XD_SETUPVOTE, Got_SetupVotecmd);
|
||||
RegisterNetXCmd(XD_MODIFYVOTE, Got_ModifyVotecmd);
|
||||
@@ -667,9 +691,6 @@ void D_RegisterServerCommands(void)
|
||||
COM_AddCommand("localskin", Command_GLocalSkin);
|
||||
COM_AddCommand("listwad", Command_ListWADS_f);
|
||||
|
||||
#ifdef DELFILE
|
||||
COM_AddCommand("delfile", Command_Delfile);
|
||||
#endif
|
||||
COM_AddCommand("runsoc", Command_RunSOC);
|
||||
COM_AddCommand("pause", Command_Pause);
|
||||
COM_AddCommand("respawn", Command_Respawn);
|
||||
@@ -690,9 +711,7 @@ void D_RegisterServerCommands(void)
|
||||
COM_AddCommand("cheats", Command_Cheats_f); // test
|
||||
#ifdef _DEBUG
|
||||
COM_AddCommand("togglemodified", Command_Togglemodified_f);
|
||||
#ifdef HAVE_BLUA
|
||||
COM_AddCommand("archivetest", Command_Archivetest_f);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
COM_AddCommand("replaymarker", Command_ReplayMarker);
|
||||
@@ -732,19 +751,6 @@ void D_RegisterServerCommands(void)
|
||||
CV_RegisterVar(&cv_competitionboxes);
|
||||
CV_RegisterVar(&cv_matchboxes);
|
||||
|
||||
/*CV_RegisterVar(&cv_recycler);
|
||||
CV_RegisterVar(&cv_teleporters);
|
||||
CV_RegisterVar(&cv_superring);
|
||||
CV_RegisterVar(&cv_supersneakers);
|
||||
CV_RegisterVar(&cv_invincibility);
|
||||
CV_RegisterVar(&cv_jumpshield);
|
||||
CV_RegisterVar(&cv_watershield);
|
||||
CV_RegisterVar(&cv_ringshield);
|
||||
CV_RegisterVar(&cv_forceshield);
|
||||
CV_RegisterVar(&cv_bombshield);
|
||||
CV_RegisterVar(&cv_1up);
|
||||
CV_RegisterVar(&cv_eggmanbox);*/
|
||||
|
||||
K_RegisterKartStuff(); // SRB2kart
|
||||
|
||||
CV_RegisterVar(&cv_ringslinger);
|
||||
@@ -815,6 +821,7 @@ void D_RegisterServerCommands(void)
|
||||
CV_RegisterVar(&cv_recordmultiplayerdemos);
|
||||
CV_RegisterVar(&cv_netdemosyncquality);
|
||||
CV_RegisterVar(&cv_maxdemosize);
|
||||
CV_RegisterVar(&cv_nativekeyboard);
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
@@ -889,6 +896,8 @@ void D_RegisterClientCommands(void)
|
||||
// GIF variables
|
||||
CV_RegisterVar(&cv_gif_optimize);
|
||||
CV_RegisterVar(&cv_gif_downscale);
|
||||
CV_RegisterVar(&cv_gif_dynamicdelay);
|
||||
CV_RegisterVar(&cv_gif_localcolortable);
|
||||
|
||||
#ifdef WALLSPLATS
|
||||
CV_RegisterVar(&cv_splats);
|
||||
@@ -1105,6 +1114,26 @@ void D_RegisterClientCommands(void)
|
||||
|
||||
CV_RegisterVar(&cv_soundtest);
|
||||
|
||||
CV_RegisterVar(&cv_nametag);
|
||||
CV_RegisterVar(&cv_nametagtrans);
|
||||
CV_RegisterVar(&cv_nametagfacerank);
|
||||
CV_RegisterVar(&cv_nametagmaxplayers);
|
||||
CV_RegisterVar(&cv_nametagmaxlenght);
|
||||
//CV_RegisterVar(&cv_nametagscaling);
|
||||
CV_RegisterVar(&cv_nametagdist);
|
||||
CV_RegisterVar(&cv_showownnametag);
|
||||
CV_RegisterVar(&cv_smallnametags);
|
||||
CV_RegisterVar(&cv_nametagrestat);
|
||||
CV_RegisterVar(&cv_nametaghop);
|
||||
CV_RegisterVar(&cv_nametagscore);
|
||||
CV_RegisterVar(&cv_shownametagfinish);
|
||||
CV_RegisterVar(&cv_shownametagspectator);
|
||||
|
||||
CV_RegisterVar(&cv_driftgauge);
|
||||
CV_RegisterVar(&cv_driftgaugeofs);
|
||||
CV_RegisterVar(&cv_driftgaugetrans);
|
||||
CV_RegisterVar(&cv_driftgaugestyle);
|
||||
|
||||
CV_RegisterVar(&cv_perfstats);
|
||||
CV_RegisterVar(&cv_ps_thinkframe_page);
|
||||
CV_RegisterVar(&cv_ps_samplesize);
|
||||
@@ -1121,8 +1150,8 @@ void D_RegisterClientCommands(void)
|
||||
CV_RegisterVar(&cv_speed);
|
||||
CV_RegisterVar(&cv_opflags);
|
||||
CV_RegisterVar(&cv_mapthingnum);
|
||||
// CV_RegisterVar(&cv_grid);
|
||||
// CV_RegisterVar(&cv_snapto);
|
||||
//CV_RegisterVar(&cv_grid);
|
||||
//CV_RegisterVar(&cv_snapto);
|
||||
|
||||
// add cheat commands
|
||||
COM_AddCommand("noclip", Command_CheatNoClip_f);
|
||||
@@ -1148,7 +1177,7 @@ void D_RegisterClientCommands(void)
|
||||
#ifdef _DEBUG
|
||||
COM_AddCommand("causecfail", Command_CauseCfail_f);
|
||||
#endif
|
||||
#if defined(HAVE_BLUA) && defined(LUA_ALLOW_BYTECODE)
|
||||
#if defined(LUA_ALLOW_BYTECODE)
|
||||
COM_AddCommand("dumplua", Command_Dumplua_f);
|
||||
#endif
|
||||
|
||||
@@ -1158,6 +1187,8 @@ void D_RegisterClientCommands(void)
|
||||
CV_RegisterVar(&cv_discordasks);
|
||||
#endif
|
||||
|
||||
CV_RegisterVar(&cv_showspecstuff);
|
||||
|
||||
COM_AddCommand("listskins", Command_ListSkins);
|
||||
COM_AddCommand("skinsearch", Command_SkinSearch);
|
||||
}
|
||||
@@ -2916,9 +2947,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
||||
INT32 resetplayer = 1, lastgametype;
|
||||
UINT8 skipprecutscene, FLS;
|
||||
boolean pencoremode;
|
||||
/*#ifdef HAVE_BLUA
|
||||
INT16 mapnumber;
|
||||
#endif*/
|
||||
//INT16 mapnumber;
|
||||
|
||||
forceresetplayers = deferencoremode = false;
|
||||
|
||||
@@ -2984,10 +3013,8 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
||||
if (modeattacking) // i remember moving this here in internal fixed a heisenbug so
|
||||
SetPlayerSkinByNum(0, cv_chooseskin.value-1);
|
||||
|
||||
/*#ifdef HAVE_BLUA
|
||||
mapnumber = M_MapNumber(mapname[3], mapname[4]);
|
||||
LUAh_MapChange(mapnumber);
|
||||
#endif*/
|
||||
//mapnumber = M_MapNumber(mapname[3], mapname[4]);
|
||||
//LUAh_MapChange(mapnumber);
|
||||
|
||||
demo.savemode = (cv_recordmultiplayerdemos.value == 2) ? DSM_WILLAUTOSAVE : DSM_NOTSAVING;
|
||||
demo.savebutton = 0;
|
||||
@@ -4746,42 +4773,6 @@ static void Command_GLocalSkin (void)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DELFILE
|
||||
/** removes the last added pwad at runtime.
|
||||
* Searches for sounds, maps, music and images to remove
|
||||
*/
|
||||
static void Command_Delfile(void)
|
||||
{
|
||||
if (gamestate == GS_LEVEL)
|
||||
{
|
||||
CONS_Printf(M_GetText("You must NOT be in a level to use this.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (netgame && !(server || adminplayer == consoleplayer))
|
||||
{
|
||||
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (numwadfiles <= mainwads)
|
||||
{
|
||||
CONS_Printf(M_GetText("No additional WADs are loaded.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(netgame || multiplayer))
|
||||
{
|
||||
P_DelWadFile();
|
||||
if (mainwads == numwadfiles && modifiedgame)
|
||||
modifiedgame = false;
|
||||
return;
|
||||
}
|
||||
|
||||
SendNetXCmd(XD_DELFILE, NULL, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
|
||||
{
|
||||
char filename[241];
|
||||
@@ -4850,33 +4841,6 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
|
||||
COM_BufAddText(va("addfile %s\n", filename));
|
||||
}
|
||||
|
||||
#ifdef DELFILE
|
||||
static void Got_Delfilecmd(UINT8 **cp, INT32 playernum)
|
||||
{
|
||||
if (playernum != serverplayer && playernum != adminplayer)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal delfile command received from %s\n"), player_names[playernum]);
|
||||
if (server)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
|
||||
buf[0] = (UINT8)playernum;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
return;
|
||||
}
|
||||
(void)cp;
|
||||
|
||||
if (numwadfiles <= mainwads) //sanity
|
||||
return;
|
||||
|
||||
P_DelWadFile();
|
||||
if (mainwads == numwadfiles && modifiedgame)
|
||||
modifiedgame = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void Got_Addfilecmd(UINT8 **cp, INT32 playernum)
|
||||
{
|
||||
char filename[241];
|
||||
@@ -4968,18 +4932,7 @@ static void Command_Version_f(void)
|
||||
#endif
|
||||
|
||||
// OS
|
||||
// Would be nice to use SDL_GetPlatform for this
|
||||
#if defined (_WIN32) || defined (_WIN64)
|
||||
CONS_Printf("Windows ");
|
||||
#elif defined(__linux__)
|
||||
CONS_Printf("Linux ");
|
||||
#elif defined(MACOSX)
|
||||
CONS_Printf("macOS ");
|
||||
#elif defined(UNIXCOMMON)
|
||||
CONS_Printf("Unix (Common) ");
|
||||
#else
|
||||
CONS_Printf("Other OS ");
|
||||
#endif
|
||||
CONS_Printf("%s ", I_GetSysName());
|
||||
|
||||
// Bitness
|
||||
if (sizeof(void*) == 4)
|
||||
@@ -5791,7 +5744,6 @@ static void Command_Togglemodified_f(void)
|
||||
modifiedgame = !modifiedgame;
|
||||
}
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
extern UINT8 *save_p;
|
||||
static void Command_Archivetest_f(void)
|
||||
{
|
||||
@@ -5836,7 +5788,6 @@ static void Command_Archivetest_f(void)
|
||||
CONS_Printf("Done. No crash.\n");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** Makes a change to ::cv_forceskin take effect immediately.
|
||||
*
|
||||
|
||||
+22
-2
@@ -176,6 +176,26 @@ extern consvar_t cv_sleep;
|
||||
#define SKINSELECTSPIN_PAIN 25
|
||||
extern consvar_t cv_skinselectspin;
|
||||
|
||||
extern consvar_t cv_nametag;
|
||||
extern consvar_t cv_nametagtrans;
|
||||
extern consvar_t cv_nametagfacerank;
|
||||
extern consvar_t cv_nametagmaxplayers;
|
||||
extern consvar_t cv_nametagmaxlenght;
|
||||
//extern consvar_t cv_nametagscaling;
|
||||
extern consvar_t cv_nametagdist;
|
||||
extern consvar_t cv_showownnametag;
|
||||
extern consvar_t cv_smallnametags;
|
||||
extern consvar_t cv_nametagrestat;
|
||||
extern consvar_t cv_nametaghop;
|
||||
extern consvar_t cv_nametagscore;
|
||||
extern consvar_t cv_shownametagfinish;
|
||||
extern consvar_t cv_shownametagspectator;
|
||||
|
||||
extern consvar_t cv_driftgauge;
|
||||
extern consvar_t cv_driftgaugeofs;
|
||||
extern consvar_t cv_driftgaugetrans;
|
||||
extern consvar_t cv_driftgaugestyle;
|
||||
|
||||
extern consvar_t cv_perfstats;
|
||||
extern consvar_t cv_ps_thinkframe_page;
|
||||
extern consvar_t cv_ps_samplesize;
|
||||
@@ -183,6 +203,8 @@ extern consvar_t cv_ps_descriptor;
|
||||
|
||||
extern consvar_t cv_showtrackaddon;
|
||||
|
||||
extern consvar_t cv_showspecstuff;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SKINMENUTYPE_SCROLL = 0,
|
||||
@@ -233,10 +255,8 @@ typedef enum
|
||||
XD_PICKVOTE, // 24
|
||||
XD_REMOVEPLAYER,// 25
|
||||
XD_DISCORD, // 26
|
||||
#ifdef HAVE_BLUA
|
||||
XD_LUACMD, // 27
|
||||
XD_LUAVAR, // 28
|
||||
#endif
|
||||
MAXNETXCMD
|
||||
} netxcmd_t;
|
||||
|
||||
|
||||
+75
-59
@@ -825,7 +825,6 @@ void SV_FileSendTicker(void)
|
||||
size_t size;
|
||||
filetx_t *f;
|
||||
INT32 packetsent, ram, i, j;
|
||||
INT32 maxpacketsent;
|
||||
|
||||
if (!filestosend) // No file to send
|
||||
return;
|
||||
@@ -1237,10 +1236,13 @@ void CURLPrepareFile(const char* url, int dfilenum)
|
||||
I_Error("Attempted to download files in -nodownload mode");
|
||||
#endif
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
if (!multi_handle)
|
||||
{
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
multi_handle = curl_multi_init();
|
||||
}
|
||||
|
||||
http_handle = curl_easy_init();
|
||||
multi_handle = curl_multi_init();
|
||||
|
||||
if (http_handle && multi_handle)
|
||||
{
|
||||
@@ -1296,98 +1298,112 @@ void CURLPrepareFile(const char* url, int dfilenum)
|
||||
|
||||
curl_multi_perform(multi_handle, &curl_runninghandles);
|
||||
curl_starttime = time(NULL);
|
||||
|
||||
curl_running = true;
|
||||
|
||||
I_spawn_thread("http-download", (I_thread_fn)CURLGetFile, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void CURLAbortFile(void)
|
||||
{
|
||||
curl_running = false;
|
||||
}
|
||||
|
||||
void CURLGetFile(void)
|
||||
{
|
||||
CURLMcode mc; /* return code used by curl_multi_wait() */
|
||||
CURLcode easyres; /* Return from easy interface */
|
||||
int numfds;
|
||||
CURLMsg *m; /* for picking up messages with the transfer status */
|
||||
CURL *e;
|
||||
int msgs_left; /* how many messages are left */
|
||||
const char *easy_handle_error;
|
||||
boolean running = true;
|
||||
long response_code = 0;
|
||||
static char *filename;
|
||||
|
||||
if (curl_runninghandles)
|
||||
while (running && curl_running)
|
||||
{
|
||||
curl_multi_perform(multi_handle, &curl_runninghandles);
|
||||
|
||||
/* wait for activity, timeout or "nothing" */
|
||||
mc = curl_multi_wait(multi_handle, NULL, 0, 1000, &numfds);
|
||||
|
||||
if (mc != CURLM_OK)
|
||||
if (curl_runninghandles)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "curl_multi_wait() failed, code %d.\n", mc);
|
||||
return;
|
||||
}
|
||||
curl_curfile->currentsize = curl_dlnow;
|
||||
curl_curfile->totalsize = curl_dltotal;
|
||||
}
|
||||
curl_multi_perform(multi_handle, &curl_runninghandles);
|
||||
|
||||
/* See how the transfers went */
|
||||
while ((m = curl_multi_info_read(multi_handle, &msgs_left)))
|
||||
{
|
||||
if (m && (m->msg == CURLMSG_DONE))
|
||||
{
|
||||
e = m->easy_handle;
|
||||
easyres = m->data.result;
|
||||
filename = Z_StrDup(curl_realname);
|
||||
nameonly(filename);
|
||||
if (easyres != CURLE_OK)
|
||||
/* wait for activity, timeout or "nothing" */
|
||||
mc = curl_multi_wait(multi_handle, NULL, 0, 1000, NULL);
|
||||
|
||||
if (mc != CURLM_OK)
|
||||
{
|
||||
if (easyres == CURLE_HTTP_RETURNED_ERROR)
|
||||
curl_easy_getinfo(e, CURLINFO_RESPONSE_CODE, &response_code);
|
||||
|
||||
easy_handle_error = (response_code) ? va("HTTP response code %ld", response_code) : curl_easy_strerror(easyres);
|
||||
curl_curfile->status = FS_FALLBACK;
|
||||
curl_curfile->currentsize = curl_origfilesize;
|
||||
curl_curfile->totalsize = curl_origtotalfilesize;
|
||||
curl_failedwebdownload = true;
|
||||
fclose(curl_curfile->file);
|
||||
remove(curl_curfile->filename);
|
||||
CONS_Printf(M_GetText("Failed to download %s (%s)\n"), filename, easy_handle_error);
|
||||
CONS_Alert(CONS_WARNING, "curl_multi_wait() failed, code %d.\n", mc);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
fclose(curl_curfile->file);
|
||||
curl_curfile->currentsize = curl_dlnow;
|
||||
curl_curfile->totalsize = curl_dltotal;
|
||||
}
|
||||
|
||||
if (checkfilemd5(curl_curfile->filename, curl_curfile->md5sum) == FS_MD5SUMBAD)
|
||||
/* See how the transfers went */
|
||||
while ((m = curl_multi_info_read(multi_handle, &msgs_left)))
|
||||
{
|
||||
if (m && (m->msg == CURLMSG_DONE))
|
||||
{
|
||||
running = false;
|
||||
e = m->easy_handle;
|
||||
easyres = m->data.result;
|
||||
|
||||
filename = Z_StrDup(curl_realname);
|
||||
nameonly(filename);
|
||||
|
||||
if (easyres != CURLE_OK)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("HTTP Download of %s finished but is corrupt or has been modified\n"), filename);
|
||||
if (easyres == CURLE_HTTP_RETURNED_ERROR)
|
||||
curl_easy_getinfo(e, CURLINFO_RESPONSE_CODE, &response_code);
|
||||
|
||||
easy_handle_error = (response_code) ? va("HTTP response code %ld", response_code) : curl_easy_strerror(easyres);
|
||||
curl_curfile->status = FS_FALLBACK;
|
||||
curl_curfile->currentsize = curl_origfilesize;
|
||||
curl_curfile->totalsize = curl_origtotalfilesize;
|
||||
curl_failedwebdownload = true;
|
||||
fclose(curl_curfile->file);
|
||||
remove(curl_curfile->filename);
|
||||
CONS_Printf(M_GetText("Failed to download %s (%s)\n"), filename, easy_handle_error);
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Printf(M_GetText("Finished HTTP download of %s\n"), filename);
|
||||
downloadcompletednum++;
|
||||
downloadcompletedsize += curl_curfile->totalsize;
|
||||
curl_curfile->status = FS_FOUND;
|
||||
fclose(curl_curfile->file);
|
||||
|
||||
if (checkfilemd5(curl_curfile->filename, curl_curfile->md5sum) == FS_MD5SUMBAD)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("HTTP Download of %s finished but is corrupt or has been modified\n"), filename);
|
||||
curl_curfile->status = FS_FALLBACK;
|
||||
curl_failedwebdownload = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Printf(M_GetText("Finished HTTP download of %s\n"), filename);
|
||||
downloadcompletednum++;
|
||||
downloadcompletedsize += curl_curfile->totalsize;
|
||||
curl_curfile->status = FS_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
Z_Free(filename);
|
||||
curl_curfile->file = NULL;
|
||||
curl_transfers--;
|
||||
curl_multi_remove_handle(multi_handle, e);
|
||||
curl_easy_cleanup(e);
|
||||
|
||||
if (!curl_transfers)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Z_Free(filename);
|
||||
curl_curfile->file = NULL;
|
||||
curl_running = false;
|
||||
curl_transfers--;
|
||||
curl_multi_remove_handle(multi_handle, e);
|
||||
curl_easy_cleanup(e);
|
||||
|
||||
if (!curl_transfers)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!curl_transfers)
|
||||
if (!curl_transfers || !curl_running)
|
||||
{
|
||||
curl_multi_cleanup(multi_handle);
|
||||
curl_global_cleanup();
|
||||
multi_handle = NULL;
|
||||
}
|
||||
curl_running = false;
|
||||
}
|
||||
|
||||
HTTP_login *
|
||||
|
||||
@@ -107,6 +107,7 @@ size_t nameonlylength(const char *s);
|
||||
|
||||
#ifdef HAVE_CURL
|
||||
void CURLPrepareFile(const char* url, int dfilenum);
|
||||
void CURLAbortFile(void);
|
||||
void CURLGetFile(void);
|
||||
HTTP_login * CURLGetLogin (const char *url, HTTP_login ***return_prev_next);
|
||||
size_t curlwrite_data(void *ptr, size_t size, size_t nmemb, FILE *stream);
|
||||
|
||||
+12
-678
@@ -31,19 +31,19 @@
|
||||
#include "r_data.h"
|
||||
#include "r_patch.h"
|
||||
#include "r_sky.h"
|
||||
#include "r_draw.h" // translation colormap consts (for lua)
|
||||
#include "fastcmp.h"
|
||||
#include "lua_script.h"
|
||||
#include "lua_glib.h"
|
||||
#include "lua_hook.h"
|
||||
#include "d_clisrv.h"
|
||||
#include "v_video.h" // video flags (for lua)
|
||||
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
|
||||
#include "m_cond.h"
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
#include "v_video.h" // video flags (for lua)
|
||||
#include "r_draw.h" // translation colormap consts (for lua)
|
||||
#endif
|
||||
|
||||
#define REQUIRE_MATHLIB_GUID "{748fcbc8-6480-4013-ac4e-7afce6cab766}"
|
||||
|
||||
// Free slot names
|
||||
@@ -67,104 +67,10 @@ static sfxenum_t get_sfx(const char *word);
|
||||
static UINT16 get_mus(const char *word, UINT8 dehacked_mode);
|
||||
#endif
|
||||
static hudnum_t get_huditem(const char *word);
|
||||
#ifndef HAVE_BLUA
|
||||
static powertype_t get_power(const char *word);
|
||||
#endif
|
||||
|
||||
boolean deh_loaded = false;
|
||||
static int dbg_line;
|
||||
|
||||
#ifdef DELFILE
|
||||
typedef struct undehacked_s
|
||||
{
|
||||
char *undata;
|
||||
struct undehacked_s *next;
|
||||
} undehacked_t;
|
||||
|
||||
static UINT16 unsocwad;
|
||||
static undehacked_t *unsocdata[MAX_WADFILES];
|
||||
static boolean disableundo = false;
|
||||
|
||||
void DEH_WriteUndoline(const char *value, const char *data, undotype_f flags)
|
||||
{
|
||||
const char *eqstr = " = ";
|
||||
const char *space = " ";
|
||||
const char *pader = eqstr;
|
||||
undehacked_t *newdata;
|
||||
|
||||
if (disableundo || !unsocwad)
|
||||
return;
|
||||
|
||||
if ((newdata = malloc(sizeof(*newdata))) == NULL)
|
||||
I_Error("Out of memory for unsoc line");
|
||||
|
||||
if (flags & UNDO_SPACE)
|
||||
pader = space;
|
||||
|
||||
if (flags & UNDO_ENDTEXT && !data)
|
||||
data = space;
|
||||
|
||||
if (value)
|
||||
{
|
||||
const size_t plen = strlen(pader);
|
||||
const char *pound = "#";
|
||||
char *undata = NULL;
|
||||
const size_t elen = strlen(pound);
|
||||
size_t vlen = strlen(value), dlen = 0, len = 1;
|
||||
|
||||
if (*(value+vlen-1) == '\n')
|
||||
vlen--; // lnet not copy the ending \n
|
||||
|
||||
if (flags & UNDO_ENDTEXT)
|
||||
len += elen; // let malloc more space
|
||||
|
||||
if (flags & UNDO_NEWLINE)
|
||||
len++; // more space for the beginning \n
|
||||
|
||||
if (data)
|
||||
{
|
||||
dlen = strlen(data);
|
||||
if (flags & UNDO_CUTLINE && *(data+dlen-1) == '\n')
|
||||
dlen--; // let not copy the ending \n
|
||||
newdata->undata = malloc(vlen+plen+dlen+len);
|
||||
newdata->undata[vlen+plen+dlen+len-1] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
newdata->undata = malloc(vlen+len);
|
||||
newdata->undata[vlen+len-1] = '\0';
|
||||
}
|
||||
|
||||
if (newdata->undata)
|
||||
{
|
||||
undata = newdata->undata;
|
||||
*undata = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
free(newdata);
|
||||
I_Error("Out of memory for unsoc data");
|
||||
}
|
||||
|
||||
if (flags & UNDO_NEWLINE) // let start with \n
|
||||
strcat(undata, "\n");
|
||||
|
||||
strncat(undata, value, vlen);
|
||||
|
||||
if (data) // value+pader+data
|
||||
strncat(strncat(undata, pader, plen), data, dlen);
|
||||
|
||||
if (flags & UNDO_ENDTEXT) // let end the text
|
||||
strncat(undata, pound, elen);
|
||||
}
|
||||
else
|
||||
newdata->undata = NULL;
|
||||
|
||||
newdata->next = unsocdata[unsocwad];
|
||||
unsocdata[unsocwad] = newdata;
|
||||
}
|
||||
#endif
|
||||
|
||||
ATTRINLINE static FUNCINLINE char myfget_color(MYFILE *f)
|
||||
{
|
||||
char c = *f->curpos++;
|
||||
@@ -361,56 +267,6 @@ static void clear_levels(void)
|
||||
P_AllocMapHeader(gamemap-1);
|
||||
}
|
||||
|
||||
/*
|
||||
// Edits an animated texture slot on the array
|
||||
// Tails 12-27-2003
|
||||
static void readAnimTex(MYFILE *f, INT32 num)
|
||||
{
|
||||
char s[MAXLINELEN];
|
||||
char *word;
|
||||
char *word2;
|
||||
INT32 i;
|
||||
|
||||
do {
|
||||
if (myfgets(s, sizeof s, f) != NULL)
|
||||
{
|
||||
if (s[0] == '\n') break;
|
||||
|
||||
tmp = strchr(s, '#');
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
// set the value in the appropriate field
|
||||
|
||||
word = strtok(s, " ");
|
||||
if (word)
|
||||
strupr(word);
|
||||
else
|
||||
break;
|
||||
|
||||
word2 = strtok(NULL, " = ");
|
||||
if (word2)
|
||||
strupr(word2);
|
||||
else
|
||||
break;
|
||||
|
||||
if (word2[strlen(word2)-1] == '\n')
|
||||
word2[strlen(word2)-1] = '\0';
|
||||
|
||||
i = atoi(word2);
|
||||
|
||||
if (fastcmp(word, "START"))
|
||||
strncpy(harddefs[num].startname, word2, 8);
|
||||
if (fastcmp(word, "END"))
|
||||
strncpy(harddefs[num].endname, word2, 8);
|
||||
else if (fastcmp(word, "SPEED")) harddefs[num].speed = i;
|
||||
else if (fastcmp(word, "ISTEXTURE")) harddefs[num].istexture = i;
|
||||
|
||||
else deh_warning("readAnimTex %d: unknown word '%s'", num, word);
|
||||
}
|
||||
} while (s[0] != '\n' && !myfeof(f)); //finish when the line is empty
|
||||
}
|
||||
*/
|
||||
|
||||
static boolean findFreeSlot(INT32 *num)
|
||||
{
|
||||
// Send the character select entry to a free slot.
|
||||
@@ -502,29 +358,7 @@ static void readPlayer(MYFILE *f, INT32 num)
|
||||
word2[strlen(word2)-1] = '\0';
|
||||
i = atoi(word2);
|
||||
|
||||
/*if (fastcmp(word, "PLAYERNAME"))
|
||||
{
|
||||
if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
|
||||
goto done;
|
||||
DEH_WriteUndoline(word, description[num].text, UNDO_NONE);
|
||||
strlcpy(description[num].text, word2, sizeof (description[num].text));
|
||||
for (word2 = description[num].text; *word2; word2++)
|
||||
if (*word2 == '_')
|
||||
*word2 = ' ';
|
||||
PlayerMenu[num].text = description[num].text;
|
||||
}*/
|
||||
/* else if (fastcmp(word, "MENUPOSITION"))
|
||||
{ // Make sure you make MENUPOSITION the first thing under CHARACTER if you're using it!
|
||||
// This is to manually choose a slot and overwrite existing characters! It is NOT necessary for most individual character wads!!
|
||||
#ifdef DELFILE
|
||||
if (disableundo)
|
||||
#endif
|
||||
{
|
||||
slotfound = true;
|
||||
num = i;
|
||||
}
|
||||
} */
|
||||
/*else*/ if (fastcmp(word, "PICNAME"))
|
||||
if (fastcmp(word, "PICNAME"))
|
||||
{
|
||||
if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
|
||||
goto done;
|
||||
@@ -571,11 +405,6 @@ static void readPlayer(MYFILE *f, INT32 num)
|
||||
}
|
||||
} while (!myfeof(f)); // finish when the line is empty
|
||||
|
||||
#ifdef DELFILE
|
||||
if (slotfound)
|
||||
DEH_WriteUndoline("MENUPOSITION", va("%d", num), UNDO_NONE);
|
||||
#endif
|
||||
|
||||
done:
|
||||
Z_Free(s);
|
||||
}
|
||||
@@ -963,7 +792,6 @@ static void readlevelheader(MYFILE *f, INT32 num, INT32 wadnum)
|
||||
// Lua custom options also go above, contents may be case sensitive.
|
||||
if (fastncmp(word, "LUA.", 4))
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
UINT8 j;
|
||||
customoption_t *modoption;
|
||||
|
||||
@@ -997,9 +825,6 @@ static void readlevelheader(MYFILE *f, INT32 num, INT32 wadnum)
|
||||
modoption->option[31] = '\0';
|
||||
strncpy(modoption->value, word2, 255);
|
||||
modoption->value[255] = '\0';
|
||||
#else
|
||||
// Silently ignore.
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1091,7 +916,7 @@ static void readlevelheader(MYFILE *f, INT32 num, INT32 wadnum)
|
||||
if (i && i <= 1035)
|
||||
snprintf(mapheaderinfo[num-1]->musname, 7, "%sM", G_BuildMapName(i));
|
||||
else if (i && i <= 1050)
|
||||
strncpy(mapheaderinfo[num-1]->musname, compat_special_music_slots[i - 1036], 7);
|
||||
strncpy(mapheaderinfo[num-1]->musname, compat_special_music_slots[i - 1036], 6);
|
||||
else
|
||||
mapheaderinfo[num-1]->musname[0] = 0; // becomes empty string
|
||||
mapheaderinfo[num-1]->musname[6] = 0;
|
||||
@@ -1116,7 +941,7 @@ static void readlevelheader(MYFILE *f, INT32 num, INT32 wadnum)
|
||||
else if (fastcmp(word, "SKYNUM"))
|
||||
mapheaderinfo[num-1]->skynum = (INT16)i;
|
||||
else if (fastcmp(word, "INTERSCREEN"))
|
||||
strncpy(mapheaderinfo[num-1]->interscreen, word2, 8);
|
||||
memcpy(mapheaderinfo[num-1]->interscreen, word2, 8);
|
||||
else if (fastcmp(word, "PRECUTSCENENUM"))
|
||||
mapheaderinfo[num-1]->precutscenenum = (UINT8)i;
|
||||
else if (fastcmp(word, "CUTSCENENUM"))
|
||||
@@ -1479,9 +1304,6 @@ static void readcutscene(MYFILE *f, INT32 num)
|
||||
char *word2;
|
||||
char *tmp;
|
||||
INT32 value;
|
||||
#ifdef DELFILE
|
||||
const INT32 oldnumscenes = cutscenes[num]->numscenes;
|
||||
#endif
|
||||
|
||||
// Allocate memory for this cutscene if we don't yet have any
|
||||
if (!cutscenes[num])
|
||||
@@ -1919,10 +1741,8 @@ static void readframe(MYFILE *f, INT32 num)
|
||||
}
|
||||
|
||||
z = 0;
|
||||
#ifdef HAVE_BLUA
|
||||
found = LUA_SetLuaAction(&states[num], actiontocompare);
|
||||
if (!found)
|
||||
#endif
|
||||
while (actionpointers[z].name)
|
||||
{
|
||||
if (fastcmp(actiontocompare, actionpointers[z].name))
|
||||
@@ -1973,21 +1793,7 @@ static void readsound(MYFILE *f, INT32 num, const char *savesfxnames[])
|
||||
else
|
||||
break;
|
||||
|
||||
/* if (fastcmp(word, "OFFSET"))
|
||||
{
|
||||
value -= 150360;
|
||||
if (value <= 64)
|
||||
value /= 8;
|
||||
else if (value <= 260)
|
||||
value = (value+4)/8;
|
||||
else
|
||||
value = (value+8)/8;
|
||||
if (value >= -1 && value < sfx_freeslot0 - 1)
|
||||
S_sfx[num].name = savesfxnames[value+1];
|
||||
else
|
||||
deh_warning("Sound %d: offset out of bounds", num);
|
||||
}
|
||||
else */if (fastcmp(word, "SINGULAR"))
|
||||
if (fastcmp(word, "SINGULAR"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", S_sfx[num].singularity), UNDO_NONE);
|
||||
S_sfx[num].singularity = value;
|
||||
@@ -2171,10 +1977,6 @@ static void reademblemdata(MYFILE *f, INT32 num)
|
||||
// Default sprite and color definitions for lazy people like me
|
||||
if (!emblemlocations[num-1].sprite) switch (emblemlocations[num-1].type)
|
||||
{
|
||||
/*case ET_RINGS:
|
||||
emblemlocations[num-1].sprite = 'R'; break;
|
||||
case ET_SCORE: case ET_NGRADE:
|
||||
emblemlocations[num-1].sprite = 'S'; break;*/
|
||||
case ET_TIME: //case ET_NTIME:
|
||||
emblemlocations[num-1].sprite = 'B'; break;
|
||||
default:
|
||||
@@ -2182,12 +1984,6 @@ static void reademblemdata(MYFILE *f, INT32 num)
|
||||
}
|
||||
if (!emblemlocations[num-1].color) switch (emblemlocations[num-1].type)
|
||||
{
|
||||
/*case ET_RINGS:
|
||||
emblemlocations[num-1].color = SKINCOLOR_GOLD; break;
|
||||
case ET_SCORE:
|
||||
emblemlocations[num-1].color = SKINCOLOR_BROWN; break;
|
||||
case ET_NGRADE:
|
||||
emblemlocations[num-1].color = SKINCOLOR_TEAL; break;*/
|
||||
case ET_TIME: //case ET_NTIME:
|
||||
emblemlocations[num-1].color = SKINCOLOR_GREY; break;
|
||||
default:
|
||||
@@ -2494,34 +2290,6 @@ static void readcondition(UINT8 set, UINT32 id, char *word2)
|
||||
return;
|
||||
}
|
||||
}
|
||||
/*else if ((offset=0) || fastcmp(params[0], "NIGHTSSCORE")
|
||||
|| (++offset && fastcmp(params[0], "NIGHTSTIME"))
|
||||
|| (++offset && fastcmp(params[0], "NIGHTSGRADE")))
|
||||
{
|
||||
PARAMCHECK(2); // one optional one
|
||||
|
||||
ty = UC_NIGHTSSCORE + offset;
|
||||
re = atoi(params[2 + !!(params[3])]);
|
||||
|
||||
// Convert to map number if it appears to be one
|
||||
if (params[1][0] >= 'A' && params[1][0] <= 'Z')
|
||||
x1 = (INT16)M_MapNumber(params[1][0], params[1][1]);
|
||||
else
|
||||
x1 = (INT16)atoi(params[1]);
|
||||
|
||||
if (x1 < 0 || x1 >= NUMMAPS)
|
||||
{
|
||||
deh_warning("Level number %d out of range (1 - %d)", re, NUMMAPS);
|
||||
return;
|
||||
}
|
||||
|
||||
// Mare number (0 for overall)
|
||||
if (params[3]) // Only if we actually got 3 params (so the second one == mare and not requirement)
|
||||
x2 = (INT16)atoi(params[2]);
|
||||
else
|
||||
x2 = 0;
|
||||
|
||||
}*/
|
||||
else if (fastcmp(params[0], "TRIGGER"))
|
||||
{
|
||||
PARAMCHECK(1);
|
||||
@@ -2719,15 +2487,6 @@ static void readpatch(MYFILE *f, const char *name, UINT16 wad)
|
||||
}
|
||||
} while (!myfeof(f));
|
||||
|
||||
// Error checking.
|
||||
/* // Irrelevant. Origins cannot be unsigned.
|
||||
if (patch.originx == UINT16_MAX)
|
||||
I_Error("Patch %s on texture %s has no X position!\n", name, textures[i]->name);
|
||||
|
||||
if (patch.originy == UINT16_MAX)
|
||||
I_Error("Patch %s on texture %s has no Y position!\n", name, textures[i]->name);
|
||||
*/
|
||||
|
||||
// Set the patch as that patch number.
|
||||
textures[i]->patches[j] = patch;
|
||||
|
||||
@@ -2944,7 +2703,7 @@ static void readmaincfg(MYFILE *f)
|
||||
// Also save a time attack folder
|
||||
filenamelen = strlen(gamedatafilename)-4; // Strip off the extension
|
||||
filenamelen = min(filenamelen, sizeof (timeattackfolder));
|
||||
strncpy(timeattackfolder, gamedatafilename, filenamelen);
|
||||
memcpy(timeattackfolder, gamedatafilename, filenamelen);
|
||||
timeattackfolder[min(filenamelen, sizeof (timeattackfolder) - 1)] = '\0';
|
||||
|
||||
strcpy(savegamename, timeattackfolder);
|
||||
@@ -3338,29 +3097,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
}
|
||||
// <Callum> Added translations to this just in case its re-enabled
|
||||
/* else if (fastcmp(word, "POINTER"))
|
||||
{
|
||||
word = strtok(NULL, " "); // get frame
|
||||
word = strtok(NULL, ")");
|
||||
if (word)
|
||||
{
|
||||
i = atoi(word);
|
||||
if (i < NUMSTATES && i >= 0)
|
||||
{
|
||||
if (myfgets(s, MAXLINELEN, f))
|
||||
states[i].action = saveactions[searchvalue(s)];
|
||||
}
|
||||
else
|
||||
{
|
||||
deh_warning("Pointer: Frame %d doesn't exist", i);
|
||||
ignorelines(f);
|
||||
}
|
||||
}
|
||||
else
|
||||
deh_warning("pointer (Frame %d) : missing ')'", i);
|
||||
G_SetGameModified(multiplayer, true);
|
||||
}*/
|
||||
else if (fastcmp(word, "SOUND"))
|
||||
{
|
||||
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
||||
@@ -3375,27 +3111,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
// This is not a major mod.
|
||||
}
|
||||
/* else if (fastcmp(word, "SPRITE"))
|
||||
{
|
||||
if (i < NUMSPRITES && i >= 0)
|
||||
{
|
||||
if (myfgets(s, MAXLINELEN, f))
|
||||
{
|
||||
INT32 k;
|
||||
k = (searchvalue(s) - 151328)/8;
|
||||
if (k >= 0 && k < NUMSPRITES)
|
||||
sprnames[i] = savesprnames[k];
|
||||
else
|
||||
{
|
||||
deh_warning("Sprite %d: offset out of bounds", i);
|
||||
ignorelines(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
deh_warning("Sprite %d doesn't exist",i);
|
||||
// This is not a major mod.
|
||||
}*/
|
||||
else if (fastcmp(word, "HUDITEM"))
|
||||
{
|
||||
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
||||
@@ -3540,9 +3255,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
deh_warning("No word in this line: %s", s);
|
||||
} // end while
|
||||
|
||||
/*if (gamedataadded) -- REFRESHDIR_GAMEDATA murdered this
|
||||
G_LoadGameData();*/
|
||||
|
||||
dbg_line = -1;
|
||||
if (deh_num_warning)
|
||||
{
|
||||
@@ -3563,9 +3275,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump)
|
||||
{
|
||||
MYFILE f;
|
||||
#ifdef DELFILE
|
||||
unsocwad = wad;
|
||||
#endif
|
||||
f.wad = wad;
|
||||
f.size = W_LumpLengthPwad(wad, lump);
|
||||
f.data = Z_Malloc(f.size + 1, PU_STATIC, NULL);
|
||||
@@ -3582,67 +3291,6 @@ void DEH_LoadDehackedLump(lumpnum_t lumpnum)
|
||||
DEH_LoadDehackedLumpPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum));
|
||||
}
|
||||
|
||||
#ifdef DELFILE
|
||||
#define DUMPUNDONE
|
||||
|
||||
// read (un)dehacked lump in wad's memory
|
||||
void DEH_UnloadDehackedWad(UINT16 wad)
|
||||
{
|
||||
undehacked_t *tmp, *curundo = unsocdata[wad];
|
||||
MYFILE f;
|
||||
size_t len = 0;
|
||||
char *data;
|
||||
#ifdef DUMPUNDONE
|
||||
FILE *UNDO = fopen("undo.soc", "wt");
|
||||
#endif
|
||||
CONS_Printf(M_GetText("Unloading WAD SOC edits\n"));
|
||||
while (curundo)
|
||||
{
|
||||
data = curundo->undata;
|
||||
curundo = curundo->next;
|
||||
if (data)
|
||||
len += strlen(data);
|
||||
len += 1;
|
||||
#ifdef DUMPUNDONE
|
||||
if (UNDO)
|
||||
{
|
||||
if (data)
|
||||
fprintf(UNDO, "%s\n", data);
|
||||
else
|
||||
fprintf(UNDO, "\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifndef DUMPUNDONE
|
||||
if (UNDO) fclose(UNDO);
|
||||
#endif
|
||||
if (!len) return;
|
||||
f.size = len;
|
||||
data = f.data = Z_Malloc(f.size + 1, PU_STATIC, NULL);
|
||||
curundo = unsocdata[wad];
|
||||
unsocdata[wad] = NULL;
|
||||
while (curundo)
|
||||
{
|
||||
tmp = curundo;
|
||||
curundo = curundo->next;
|
||||
if (tmp->undata)
|
||||
data += sprintf(data, "%s\n", tmp->undata);
|
||||
else
|
||||
data += sprintf(data, "\n");
|
||||
if (tmp->undata) free(tmp->undata);
|
||||
free(tmp);
|
||||
}
|
||||
f.wad = wad;
|
||||
f.curpos = f.data;
|
||||
f.data[f.size] = 0;
|
||||
disableundo = true;
|
||||
DEH_LoadDehackedFile(&f);
|
||||
disableundo = false;
|
||||
Z_Free(f.data);
|
||||
}
|
||||
#endif //DELFILE
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// CRAZY LIST OF STATE NAMES AND ALL FROM HERE DOWN
|
||||
// TODO: Make this all a seperate file or something, like part of info.c??
|
||||
@@ -3696,63 +3344,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
||||
"S_KART_SPIN",
|
||||
"S_KART_PAIN",
|
||||
"S_KART_SQUISH",
|
||||
/*
|
||||
"S_PLAY_STND",
|
||||
"S_PLAY_TAP1",
|
||||
"S_PLAY_TAP2",
|
||||
"S_PLAY_RUN1",
|
||||
"S_PLAY_RUN2",
|
||||
"S_PLAY_RUN3",
|
||||
"S_PLAY_RUN4",
|
||||
"S_PLAY_RUN5",
|
||||
"S_PLAY_RUN6",
|
||||
"S_PLAY_RUN7",
|
||||
"S_PLAY_RUN8",
|
||||
"S_PLAY_SPD1",
|
||||
"S_PLAY_SPD2",
|
||||
"S_PLAY_SPD3",
|
||||
"S_PLAY_SPD4",
|
||||
"S_PLAY_ATK1",
|
||||
"S_PLAY_ATK2",
|
||||
"S_PLAY_ATK3",
|
||||
"S_PLAY_ATK4",
|
||||
"S_PLAY_SPRING",
|
||||
"S_PLAY_FALL1",
|
||||
"S_PLAY_FALL2",
|
||||
"S_PLAY_ABL1",
|
||||
"S_PLAY_ABL2",
|
||||
"S_PLAY_SPC1",
|
||||
"S_PLAY_SPC2",
|
||||
"S_PLAY_SPC3",
|
||||
"S_PLAY_SPC4",
|
||||
"S_PLAY_CLIMB1",
|
||||
"S_PLAY_CLIMB2",
|
||||
"S_PLAY_CLIMB3",
|
||||
"S_PLAY_CLIMB4",
|
||||
"S_PLAY_CLIMB5",
|
||||
"S_PLAY_GASP",
|
||||
"S_PLAY_PAIN",
|
||||
"S_PLAY_DIE",
|
||||
"S_PLAY_TEETER1",
|
||||
"S_PLAY_TEETER2",
|
||||
"S_PLAY_CARRY",
|
||||
"S_PLAY_SUPERSTAND",
|
||||
"S_PLAY_SUPERWALK1",
|
||||
"S_PLAY_SUPERWALK2",
|
||||
"S_PLAY_SUPERFLY1",
|
||||
"S_PLAY_SUPERFLY2",
|
||||
"S_PLAY_SUPERTEETER",
|
||||
"S_PLAY_SUPERHIT",
|
||||
"S_PLAY_SUPERTRANS1",
|
||||
"S_PLAY_SUPERTRANS2",
|
||||
"S_PLAY_SUPERTRANS3",
|
||||
"S_PLAY_SUPERTRANS4",
|
||||
"S_PLAY_SUPERTRANS5",
|
||||
"S_PLAY_SUPERTRANS6",
|
||||
"S_PLAY_SUPERTRANS7",
|
||||
"S_PLAY_SUPERTRANS8",
|
||||
"S_PLAY_SUPERTRANS9", // This has special significance in the code. If you add more frames, search for it and make the appropriate changes.
|
||||
*/
|
||||
|
||||
// technically the player goes here but it's an infinite tic state
|
||||
"S_OBJPLACE_DUMMY",
|
||||
@@ -7803,14 +7394,12 @@ static const char *const MOBJEFLAG_LIST[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
static const char *const MAPTHINGFLAG_LIST[4] = {
|
||||
NULL,
|
||||
"OBJECTFLIP", // Reverse gravity flag for objects.
|
||||
"OBJECTSPECIAL", // Special flag used with certain objects.
|
||||
"AMBUSH" // Deaf monsters/do not react to sound.
|
||||
};
|
||||
#endif
|
||||
|
||||
static const char *const PLAYERFLAG_LIST[] = {
|
||||
// Flip camera angle with gravity flip prefrence.
|
||||
@@ -7883,7 +7472,6 @@ static const char *const PLAYERFLAG_LIST[] = {
|
||||
NULL // stop loop here.
|
||||
};
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
// Linedef flags
|
||||
static const char *const ML_LIST[16] = {
|
||||
"IMPASSIBLE",
|
||||
@@ -7903,7 +7491,6 @@ static const char *const ML_LIST[16] = {
|
||||
"BOUNCY",
|
||||
"TFERLINE"
|
||||
};
|
||||
#endif
|
||||
|
||||
// This DOES differ from r_draw's Color_Names, unfortunately.
|
||||
// Also includes Super colors
|
||||
@@ -8110,7 +7697,6 @@ static const char *const POWERS_LIST[] = {
|
||||
"INGOOP" // In goop
|
||||
};
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
static const char *const KARTSTUFF_LIST[] = {
|
||||
"POSITION",
|
||||
"OLDPOSITION",
|
||||
@@ -8197,7 +7783,6 @@ static const char *const KARTSTUFF_LIST[] = {
|
||||
"SPECTATEWAIT",
|
||||
"GROWCANCEL"
|
||||
};
|
||||
#endif
|
||||
|
||||
static const char *const HUDITEMS_LIST[] = {
|
||||
"LIVESNAME",
|
||||
@@ -8240,11 +7825,7 @@ static const char *const HUDITEMS_LIST[] = {
|
||||
struct {
|
||||
const char *n;
|
||||
// has to be able to hold both fixed_t and angle_t, so drastic measure!!
|
||||
#ifdef HAVE_BLUA
|
||||
lua_Integer v;
|
||||
#else
|
||||
INT64 v;
|
||||
#endif
|
||||
} const INT_CONST[] = {
|
||||
// If a mod removes some variables here,
|
||||
// please leave the names in-tact and just set
|
||||
@@ -8433,7 +8014,6 @@ struct {
|
||||
{"SF_NOINTERRUPT",SF_NOINTERRUPT},
|
||||
{"SF_X2AWAYSOUND",SF_X2AWAYSOUND},
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
// p_local.h constants
|
||||
{"FLOATSPEED",FLOATSPEED},
|
||||
{"MAXSTEPMOVE",MAXSTEPMOVE},
|
||||
@@ -8741,7 +8321,6 @@ struct {
|
||||
// Custom client features exposed to lua
|
||||
{"FEATURE_INTERMISSIONHUD",1},
|
||||
{"FEATURE_VOTEHUD",1},
|
||||
#endif
|
||||
|
||||
{NULL,0}
|
||||
};
|
||||
@@ -8870,249 +8449,10 @@ static hudnum_t get_huditem(const char *word)
|
||||
return HUD_LIVESNAME;
|
||||
}
|
||||
|
||||
#ifndef HAVE_BLUA
|
||||
static powertype_t get_power(const char *word)
|
||||
{ // Returns the vlaue of pw_ enumerations
|
||||
powertype_t i;
|
||||
if (*word >= '0' && *word <= '9')
|
||||
return atoi(word);
|
||||
if (fastncmp("PW_",word,3))
|
||||
word += 3; // take off the pw_
|
||||
for (i = 0; i < NUMPOWERS; i++)
|
||||
if (fastcmp(word, POWERS_LIST[i]))
|
||||
return i;
|
||||
deh_warning("Couldn't find power named 'pw_%s'",word);
|
||||
return pw_invulnerability;
|
||||
}
|
||||
|
||||
/// \todo Make ANY of this completely over-the-top math craziness obey the order of operations.
|
||||
static fixed_t op_mul(fixed_t a, fixed_t b) { return a*b; }
|
||||
static fixed_t op_div(fixed_t a, fixed_t b) { return a/b; }
|
||||
static fixed_t op_add(fixed_t a, fixed_t b) { return a+b; }
|
||||
static fixed_t op_sub(fixed_t a, fixed_t b) { return a-b; }
|
||||
static fixed_t op_or(fixed_t a, fixed_t b) { return a|b; }
|
||||
static fixed_t op_and(fixed_t a, fixed_t b) { return a&b; }
|
||||
static fixed_t op_lshift(fixed_t a, fixed_t b) { return a<<b; }
|
||||
static fixed_t op_rshift(fixed_t a, fixed_t b) { return a>>b; }
|
||||
|
||||
struct {
|
||||
const char c;
|
||||
fixed_t (*v)(fixed_t,fixed_t);
|
||||
} OPERATIONS[] = {
|
||||
{'*',op_mul},
|
||||
{'/',op_div},
|
||||
{'+',op_add},
|
||||
{'-',op_sub},
|
||||
{'|',op_or},
|
||||
{'&',op_and},
|
||||
{'<',op_lshift},
|
||||
{'>',op_rshift},
|
||||
{0,NULL}
|
||||
};
|
||||
|
||||
// Returns the full word, cut at the first symbol or whitespace
|
||||
static char *read_word(const char *line)
|
||||
{
|
||||
// Part 1: You got the start of the word, now find the end.
|
||||
const char *p;
|
||||
INT32 i;
|
||||
for (p = line+1; *p; p++) {
|
||||
if (*p == ' ' || *p == '\t')
|
||||
break;
|
||||
for (i = 0; OPERATIONS[i].c; i++)
|
||||
if (*p == OPERATIONS[i].c) {
|
||||
i = -1;
|
||||
break;
|
||||
}
|
||||
if (i == -1)
|
||||
break;
|
||||
}
|
||||
|
||||
// Part 2: Make a copy of the word and return it.
|
||||
{
|
||||
size_t len = (p-line);
|
||||
char *word = malloc(len+1);
|
||||
M_Memcpy(word,line,len);
|
||||
word[len] = '\0';
|
||||
return word;
|
||||
}
|
||||
}
|
||||
|
||||
static INT32 operation_pad(const char **word)
|
||||
{ // Brings word the next operation and returns the operation number.
|
||||
INT32 i;
|
||||
for (; **word; (*word)++) {
|
||||
if (**word == ' ' || **word == '\t')
|
||||
continue;
|
||||
for (i = 0; OPERATIONS[i].c; i++)
|
||||
if (**word == OPERATIONS[i].c)
|
||||
{
|
||||
if ((**word == '<' && *(*word+1) == '<') || (**word == '>' && *(*word+1) == '>')) (*word)++; // These operations are two characters long.
|
||||
else if (**word == '<' || **word == '>') continue; // ... do not accept one character long.
|
||||
(*word)++;
|
||||
return i;
|
||||
}
|
||||
deh_warning("Unknown operation '%c'",**word);
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void const_warning(const char *type, const char *word)
|
||||
{
|
||||
deh_warning("Couldn't find %s named '%s'",type,word);
|
||||
}
|
||||
|
||||
static fixed_t find_const(const char **rword)
|
||||
{ // Finds the value of constants and returns it, bringing word to the next operation.
|
||||
INT32 i;
|
||||
fixed_t r;
|
||||
char *word = read_word(*rword);
|
||||
*rword += strlen(word);
|
||||
if ((*word >= '0' && *word <= '9') || *word == '-') { // Parse a number
|
||||
r = atoi(word);
|
||||
free(word);
|
||||
return r;
|
||||
}
|
||||
if (!*(word+1) && // Turn a single A-z symbol into numbers, like sprite frames.
|
||||
((*word >= 'A' && *word <= 'Z') || (*word >= 'a' && *word <= 'z'))) {
|
||||
r = R_Char2Frame(*word);
|
||||
free(word);
|
||||
return r;
|
||||
}
|
||||
if (fastncmp("MF_", word, 3)) {
|
||||
char *p = word+3;
|
||||
for (i = 0; MOBJFLAG_LIST[i]; i++)
|
||||
if (fastcmp(p, MOBJFLAG_LIST[i])) {
|
||||
free(word);
|
||||
return (1<<i);
|
||||
}
|
||||
|
||||
// Not found error
|
||||
const_warning("mobj flag",word);
|
||||
free(word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("MF2_", word, 4)) {
|
||||
char *p = word+4;
|
||||
for (i = 0; MOBJFLAG2_LIST[i]; i++)
|
||||
if (fastcmp(p, MOBJFLAG2_LIST[i])) {
|
||||
free(word);
|
||||
return (1<<i);
|
||||
}
|
||||
|
||||
// Not found error
|
||||
const_warning("mobj flag2",word);
|
||||
free(word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("MFE_", word, 4)) {
|
||||
char *p = word+4;
|
||||
for (i = 0; MOBJEFLAG_LIST[i]; i++)
|
||||
if (fastcmp(p, MOBJEFLAG_LIST[i])) {
|
||||
free(word);
|
||||
return (1<<i);
|
||||
}
|
||||
|
||||
// Not found error
|
||||
const_warning("mobj eflag",word);
|
||||
free(word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("PF_", word, 3)) {
|
||||
char *p = word+3;
|
||||
for (i = 0; PLAYERFLAG_LIST[i]; i++)
|
||||
if (fastcmp(p, PLAYERFLAG_LIST[i])) {
|
||||
free(word);
|
||||
return (1<<i);
|
||||
}
|
||||
if (fastcmp(p, "FULLSTASIS"))
|
||||
return PF_FULLSTASIS;
|
||||
|
||||
// Not found error
|
||||
const_warning("player flag",word);
|
||||
free(word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("S_",word,2)) {
|
||||
r = get_state(word);
|
||||
free(word);
|
||||
return r;
|
||||
}
|
||||
else if (fastncmp("MT_",word,3)) {
|
||||
r = get_mobjtype(word);
|
||||
free(word);
|
||||
return r;
|
||||
}
|
||||
else if (fastncmp("SPR_",word,4)) {
|
||||
r = get_sprite(word);
|
||||
free(word);
|
||||
return r;
|
||||
}
|
||||
else if (fastncmp("SFX_",word,4) || fastncmp("DS",word,2)) {
|
||||
r = get_sfx(word);
|
||||
free(word);
|
||||
return r;
|
||||
}
|
||||
#ifdef MUSICSLOT_COMPATIBILITY
|
||||
else if (fastncmp("MUS_",word,4) || fastncmp("O_",word,2)) {
|
||||
r = get_mus(word, true);
|
||||
free(word);
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
else if (fastncmp("PW_",word,3)) {
|
||||
r = get_power(word);
|
||||
free(word);
|
||||
return r;
|
||||
}
|
||||
else if (fastncmp("HUD_",word,4)) {
|
||||
r = get_huditem(word);
|
||||
free(word);
|
||||
return r;
|
||||
}
|
||||
else if (fastncmp("SKINCOLOR_",word,10)) {
|
||||
char *p = word+10;
|
||||
for (i = 0; i < MAXTRANSLATIONS; i++)
|
||||
if (fastcmp(p, COLOR_ENUMS[i])) {
|
||||
free(word);
|
||||
return i;
|
||||
}
|
||||
const_warning("color",word);
|
||||
free(word);
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; INT_CONST[i].n; i++)
|
||||
if (fastcmp(word,INT_CONST[i].n)) {
|
||||
free(word);
|
||||
return INT_CONST[i].v;
|
||||
}
|
||||
|
||||
// Not found error.
|
||||
const_warning("constant",word);
|
||||
free(word);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Loops through every constant and operation in word and performs its calculations, returning the final value.
|
||||
fixed_t get_number(const char *word)
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
return LUA_EvalMath(word);
|
||||
#else
|
||||
// DESPERATELY NEEDED: Order of operations support! :x
|
||||
fixed_t i = find_const(&word);
|
||||
INT32 o;
|
||||
while(*word) {
|
||||
o = operation_pad(&word);
|
||||
if (o != -1)
|
||||
i = OPERATIONS[o].v(i,find_const(&word));
|
||||
else
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
#endif
|
||||
}
|
||||
|
||||
void DEH_Check(void)
|
||||
@@ -9141,10 +8481,6 @@ void DEH_Check(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
|
||||
// freeslot takes a name (string only!)
|
||||
// and allocates it to the appropriate free slot.
|
||||
// Returns the slot number allocated for it or nil if failed.
|
||||
@@ -9292,7 +8628,7 @@ static int lib_dummysuper(lua_State *L)
|
||||
return luaL_error(L, "Can't call super() outside of hardcode-replacing A_Action functions being called by state changes!"); // convoluted, I know. @_@;;
|
||||
}
|
||||
|
||||
static inline int lib_getenum(lua_State *L)
|
||||
FUNCINLINE static ATTRINLINE int lib_getenum(lua_State *L)
|
||||
{
|
||||
const int UV_MATHLIB = lua_upvalueindex(1);
|
||||
const int GLIB_PROXY = lua_upvalueindex(2);
|
||||
@@ -10082,6 +9418,4 @@ void LUA_SetActionByName(void *state, const char *actiontocompare)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // HAVE_BLUA
|
||||
}
|
||||
@@ -27,12 +27,7 @@ typedef enum
|
||||
UNDO_DONE = 0,
|
||||
} undotype_f;
|
||||
|
||||
#ifdef DELFILE
|
||||
void DEH_WriteUndoline(const char *value, const char *data, undotype_f flags);
|
||||
void DEH_UnloadDehackedWad(UINT16 wad);
|
||||
#else // null the undo lines
|
||||
#define DEH_WriteUndoline(a,b,c)
|
||||
#endif
|
||||
|
||||
void DEH_LoadDehackedLump(lumpnum_t lumpnum);
|
||||
void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump);
|
||||
@@ -43,11 +38,9 @@ void DEH_Check(void);
|
||||
|
||||
fixed_t get_number(const char *word);
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
boolean LUA_SetLuaAction(void *state, const char *actiontocompare);
|
||||
const char *LUA_GetActionName(void *action);
|
||||
void LUA_SetActionByName(void *state, const char *actiontocompare);
|
||||
#endif
|
||||
|
||||
extern boolean deh_loaded;
|
||||
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ struct discordInfo_s discordInfo;
|
||||
|
||||
discordRequest_t *discordRequestList = NULL;
|
||||
|
||||
static char self_ip[IP_SIZE];
|
||||
static char self_ip[IP_SIZE+1];
|
||||
|
||||
boolean drpc_init = false;
|
||||
|
||||
|
||||
+19
-27
@@ -127,8 +127,8 @@ extern char logfilename[1024];
|
||||
#else
|
||||
#define VERSION 1 // Game version
|
||||
#define SUBVERSION 6 // more precise version number
|
||||
#define VERSIONSTRING "Saturn v5.1 "
|
||||
#define VERSIONSTRINGW L"Saturn v5.1"
|
||||
#define VERSIONSTRING "Saturn v5 lugdev Zzz..."
|
||||
#define VERSIONSTRINGW L"Saturn v5 lugdev Zzz..."
|
||||
// Hey! If you change this, add 1 to the MODVERSION below! Otherwise we can't force updates!
|
||||
// And change CMakeLists.txt (not src/, but in root), for CMake users!
|
||||
// AND appveyor.yml, for the build bots!
|
||||
@@ -516,6 +516,22 @@ extern boolean capslock;
|
||||
// i_system.c, replace getchar() once the keyboard has been appropriated
|
||||
INT32 I_GetKey(void);
|
||||
|
||||
/* http://www.cse.yorku.ca/~oz/hash.html */
|
||||
static inline
|
||||
UINT32 quickncasehash (const char *p, size_t n)
|
||||
{
|
||||
size_t i = 0;
|
||||
UINT32 x = 5381;
|
||||
|
||||
while (i < n && p[i])
|
||||
{
|
||||
x = (x * 33) ^ tolower(p[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
#ifndef min // Double-Check with WATTCP-32's cdefs.h
|
||||
#define min(x, y) (((x) < (y)) ? (x) : (y))
|
||||
#endif
|
||||
@@ -561,17 +577,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
|
||||
/// Undefine to use the new method of Gamma correction see colour cube in v_video.c
|
||||
#define BACKWARDSCOMPATCORRECTION
|
||||
|
||||
/// Kalaron/Eternity Engine slope code (SRB2CB ported)
|
||||
#define ESLOPE
|
||||
|
||||
/// Backwards compatibility with SRB2CB's slope linedef types.
|
||||
/// \note A simple shim that prints a warning.
|
||||
#define ESLOPE_TYPESHIM
|
||||
|
||||
/// Delete file while the game is running.
|
||||
/// \note EXTREMELY buggy, tends to crash game.
|
||||
//#define DELFILE
|
||||
|
||||
/// Allows the use of devmode in multiplayer. AKA "fishcake"
|
||||
//#define NETGAME_DEVMODE
|
||||
|
||||
@@ -581,16 +586,9 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
|
||||
/// Dumps the contents of a network save game upon consistency failure for debugging.
|
||||
//#define DUMPCONSISTENCY
|
||||
|
||||
/// Polyobject fake flat code
|
||||
#define POLYOBJECTS_PLANES
|
||||
|
||||
/// See name of player in your crosshair
|
||||
#define SEENAMES
|
||||
|
||||
/// Who put weights on my recycler? ... Inuyasha did.
|
||||
/// \note XMOD port.
|
||||
//#define WEIGHTEDRECYCLER
|
||||
|
||||
/// Allow loading of savegames between different versions of the game.
|
||||
/// \note XMOD port.
|
||||
/// Most modifications should probably enable this.
|
||||
@@ -608,9 +606,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
|
||||
#define CLIENT_LOADINGSCREEN
|
||||
#endif
|
||||
|
||||
/// Experimental tweaks to analog mode. (Needs a lot of work before it's ready for primetime.)
|
||||
//#define REDSANALOG
|
||||
|
||||
/// Backwards compatibility with musicslots.
|
||||
/// \note You should leave this enabled unless you're working with a future SRB2 version.
|
||||
#define MUSICSLOT_COMPATIBILITY
|
||||
@@ -627,12 +622,9 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
|
||||
|
||||
/// Sprite rotation
|
||||
#define ROTSPRITE
|
||||
#define ROTANGLES 72 // Needs to be a divisor of 360 (45, 60, 90, 120...)
|
||||
#define ROTANGLES 180 // Needs to be a divisor of 360 (45, 60, 90, 120...)
|
||||
#define ROTANGDIFF (360 / ROTANGLES)
|
||||
|
||||
/// Hardware renderer: OpenGL
|
||||
#define GL_SHADERS
|
||||
|
||||
#if defined (HAVE_CURL) && ! defined (NONET)
|
||||
#define MASTERSERVER
|
||||
#define HOLEPUNCH
|
||||
|
||||
@@ -179,5 +179,11 @@ char *I_ClipboardPaste(void)
|
||||
|
||||
void I_RegisterSysCommands(void) {}
|
||||
|
||||
|
||||
const char *I_GetSysName(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#include "../sdl/dosstr.c"
|
||||
|
||||
+4
-2
@@ -180,7 +180,8 @@ static void F_SkyScroll(INT32 scrollspeed)
|
||||
y = 0;
|
||||
while (x < w)
|
||||
{
|
||||
V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT, V_SNAPTOTOP|V_SNAPTOLEFT, pat, NULL);
|
||||
//V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT, V_SNAPTOTOP|V_SNAPTOLEFT, pat, NULL);
|
||||
V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT*1.2, V_SNAPTOTOP|V_SNAPTOLEFT, pat, NULL);
|
||||
x += SHORT(pat->width);
|
||||
}
|
||||
|
||||
@@ -188,7 +189,8 @@ static void F_SkyScroll(INT32 scrollspeed)
|
||||
y = BASEVIDHEIGHT - SHORT(pat2->height);
|
||||
while (x < w)
|
||||
{
|
||||
V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTOLEFT, pat2, NULL);
|
||||
//V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTOLEFT, pat2, NULL);
|
||||
V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT*1.2, V_SNAPTOBOTTOM|V_SNAPTOLEFT, pat2, NULL);
|
||||
x += SHORT(pat2->width);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-3
@@ -414,11 +414,13 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
||||
strcpy(&searchpath[searchpathindex[depthleft]],dent->d_name);
|
||||
|
||||
#if defined(__linux__) || defined(__FreeBSD__)
|
||||
if (dent->d_type == DT_UNKNOWN)
|
||||
if (lstat(searchpath,&fsstat) == 0 && S_ISDIR(fsstat.st_mode))
|
||||
if (dent->d_type == DT_UNKNOWN && lstat(searchpath,&fsstat) == 0)
|
||||
{
|
||||
if (S_ISDIR(fsstat.st_mode))
|
||||
dent->d_type = DT_DIR;
|
||||
else if (lstat(searchpath,&fsstat) == 0 && S_ISLNK(fsstat.st_mode))
|
||||
else if (S_ISLNK(fsstat.st_mode))
|
||||
dent->d_type = DT_LNK;
|
||||
}
|
||||
|
||||
// Symlinks aren't always directory symlinks. Dunno if this would resolve recursive
|
||||
// symlinks, but i think stat already does that
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ typedef enum
|
||||
#endif
|
||||
EXT_PK3,
|
||||
EXT_SOC,
|
||||
EXT_LUA, // allowed even if not HAVE_BLUA so that we can yell on load attempt
|
||||
EXT_LUA,
|
||||
NUM_EXT,
|
||||
NUM_EXT_TABLE = NUM_EXT-EXT_START,
|
||||
EXT_LOADED = 0x80
|
||||
|
||||
+14
-402
@@ -182,12 +182,8 @@ boolean gamedataloaded = false;
|
||||
// Time attack data for levels
|
||||
// These are dynamically allocated for space reasons now
|
||||
recorddata_t *mainrecords[NUMMAPS] = {NULL};
|
||||
//nightsdata_t *nightsrecords[NUMMAPS] = {NULL};
|
||||
UINT8 mapvisited[NUMMAPS];
|
||||
|
||||
// Temporary holding place for nights data for the current map
|
||||
//nightsdata_t ntemprecords;
|
||||
|
||||
UINT32 bluescore, redscore; // CTF and Team Match team scores
|
||||
|
||||
// ring count... for PERFECT!
|
||||
@@ -386,10 +382,6 @@ static CV_PossibleValue_t deadzone_cons_t[] = {{FRACUNIT/16, "MIN"}, {FRACUNIT,
|
||||
|
||||
// don't mind me putting these here, I was lazy to figure out where else I could put those without blowing up the compiler.
|
||||
|
||||
// it automatically becomes compact with 20+ players, but if you like it, I guess you can turn that on!
|
||||
// SRB2Kart: irrelevant for us.
|
||||
//consvar_t cv_compactscoreboard= {"compactscoreboard", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// chat timer thingy
|
||||
static CV_PossibleValue_t chattime_cons_t[] = {{1, "MIN"}, {999, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_chattime = {"chattime", "8", CV_SAVE, chattime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
@@ -568,13 +560,6 @@ void G_AllocMainRecordData(INT16 i)
|
||||
memset(mainrecords[i], 0, sizeof(recorddata_t));
|
||||
}
|
||||
|
||||
/*void G_AllocNightsRecordData(INT16 i)
|
||||
{
|
||||
if (!nightsrecords[i])
|
||||
nightsrecords[i] = Z_Malloc(sizeof(nightsdata_t), PU_STATIC, NULL);
|
||||
memset(nightsrecords[i], 0, sizeof(nightsdata_t));
|
||||
}*/
|
||||
|
||||
// MAKE SURE YOU SAVE DATA BEFORE CALLING THIS
|
||||
void G_ClearRecords(void)
|
||||
{
|
||||
@@ -586,11 +571,6 @@ void G_ClearRecords(void)
|
||||
Z_Free(mainrecords[i]);
|
||||
mainrecords[i] = NULL;
|
||||
}
|
||||
/*if (nightsrecords[i])
|
||||
{
|
||||
Z_Free(nightsrecords[i]);
|
||||
nightsrecords[i] = NULL;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -611,170 +591,6 @@ tic_t G_GetBestTime(INT16 map)
|
||||
return mainrecords[map-1]->time;
|
||||
}
|
||||
|
||||
// Not needed
|
||||
/*tic_t G_GetBestLap(INT16 map)
|
||||
{
|
||||
if (!mainrecords[map-1] || mainrecords[map-1]->lap <= 0)
|
||||
return (tic_t)UINT32_MAX;
|
||||
|
||||
return mainrecords[map-1]->lap;
|
||||
}*/
|
||||
|
||||
/*UINT16 G_GetBestRings(INT16 map)
|
||||
{
|
||||
if (!mainrecords[map-1])
|
||||
return 0;
|
||||
|
||||
return mainrecords[map-1]->rings;
|
||||
}*/
|
||||
|
||||
// No NiGHTS records for SRB2Kart
|
||||
/*UINT32 G_GetBestNightsScore(INT16 map, UINT8 mare)
|
||||
{
|
||||
if (!nightsrecords[map-1])
|
||||
return 0;
|
||||
|
||||
return nightsrecords[map-1]->score[mare];
|
||||
}
|
||||
|
||||
tic_t G_GetBestNightsTime(INT16 map, UINT8 mare)
|
||||
{
|
||||
if (!nightsrecords[map-1] || nightsrecords[map-1]->time[mare] <= 0)
|
||||
return (tic_t)UINT32_MAX;
|
||||
|
||||
return nightsrecords[map-1]->time[mare];
|
||||
}
|
||||
|
||||
UINT8 G_GetBestNightsGrade(INT16 map, UINT8 mare)
|
||||
{
|
||||
if (!nightsrecords[map-1])
|
||||
return 0;
|
||||
|
||||
return nightsrecords[map-1]->grade[mare];
|
||||
}
|
||||
|
||||
// For easy adding of NiGHTS records
|
||||
void G_AddTempNightsRecords(UINT32 pscore, tic_t ptime, UINT8 mare)
|
||||
{
|
||||
ntemprecords.score[mare] = pscore;
|
||||
ntemprecords.grade[mare] = P_GetGrade(pscore, gamemap, mare - 1);
|
||||
ntemprecords.time[mare] = ptime;
|
||||
|
||||
// Update nummares
|
||||
// Note that mare "0" is overall, mare "1" is the first real mare
|
||||
if (ntemprecords.nummares < mare)
|
||||
ntemprecords.nummares = mare;
|
||||
}
|
||||
|
||||
void G_SetNightsRecords(void)
|
||||
{
|
||||
INT32 i;
|
||||
UINT32 totalscore = 0;
|
||||
tic_t totaltime = 0;
|
||||
|
||||
const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1;
|
||||
char *gpath;
|
||||
char lastdemo[256], bestdemo[256];
|
||||
|
||||
if (!ntemprecords.nummares)
|
||||
return;
|
||||
|
||||
// Set overall
|
||||
{
|
||||
UINT8 totalrank = 0, realrank = 0;
|
||||
|
||||
for (i = 1; i <= ntemprecords.nummares; ++i)
|
||||
{
|
||||
totalscore += ntemprecords.score[i];
|
||||
totalrank += ntemprecords.grade[i];
|
||||
totaltime += ntemprecords.time[i];
|
||||
}
|
||||
|
||||
// Determine overall grade
|
||||
realrank = (UINT8)((FixedDiv((fixed_t)totalrank << FRACBITS, ntemprecords.nummares << FRACBITS) + (FRACUNIT/2)) >> FRACBITS);
|
||||
|
||||
// You need ALL rainbow As to get a rainbow A overall
|
||||
if (realrank == GRADE_S && (totalrank / ntemprecords.nummares) != GRADE_S)
|
||||
realrank = GRADE_A;
|
||||
|
||||
ntemprecords.score[0] = totalscore;
|
||||
ntemprecords.grade[0] = realrank;
|
||||
ntemprecords.time[0] = totaltime;
|
||||
}
|
||||
|
||||
// Now take all temp records and put them in the actual records
|
||||
{
|
||||
nightsdata_t *maprecords;
|
||||
|
||||
if (!nightsrecords[gamemap-1])
|
||||
G_AllocNightsRecordData(gamemap-1);
|
||||
maprecords = nightsrecords[gamemap-1];
|
||||
|
||||
if (maprecords->nummares != ntemprecords.nummares)
|
||||
maprecords->nummares = ntemprecords.nummares;
|
||||
|
||||
for (i = 0; i < ntemprecords.nummares + 1; ++i)
|
||||
{
|
||||
if (maprecords->score[i] < ntemprecords.score[i])
|
||||
maprecords->score[i] = ntemprecords.score[i];
|
||||
if (maprecords->grade[i] < ntemprecords.grade[i])
|
||||
maprecords->grade[i] = ntemprecords.grade[i];
|
||||
if (!maprecords->time[i] || maprecords->time[i] > ntemprecords.time[i])
|
||||
maprecords->time[i] = ntemprecords.time[i];
|
||||
}
|
||||
}
|
||||
|
||||
memset(&ntemprecords, 0, sizeof(nightsdata_t));
|
||||
|
||||
// Save demo!
|
||||
bestdemo[255] = '\0';
|
||||
lastdemo[255] = '\0';
|
||||
G_SetDemoTime(totaltime, totalscore);
|
||||
G_CheckDemoStatus();
|
||||
|
||||
I_mkdir(va("%s"PATHSEP"replay", srb2home), 0755);
|
||||
I_mkdir(va("%s"PATHSEP"replay"PATHSEP"%s", srb2home, timeattackfolder), 0755);
|
||||
|
||||
if ((gpath = malloc(glen)) == NULL)
|
||||
I_Error("Out of memory for replay filepath\n");
|
||||
|
||||
sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap));
|
||||
snprintf(lastdemo, 255, "%s-last.lmp", gpath);
|
||||
|
||||
if (FIL_FileExists(lastdemo))
|
||||
{
|
||||
UINT8 *buf;
|
||||
size_t len = FIL_ReadFile(lastdemo, &buf);
|
||||
|
||||
snprintf(bestdemo, 255, "%s-time-best.lmp", gpath);
|
||||
if (!FIL_FileExists(bestdemo) || G_CmpDemoTime(bestdemo, lastdemo) & 1)
|
||||
{ // Better time, save this demo.
|
||||
if (FIL_FileExists(bestdemo))
|
||||
remove(bestdemo);
|
||||
FIL_WriteFile(bestdemo, buf, len);
|
||||
CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW RECORD TIME!"), M_GetText("Saved replay as"), bestdemo);
|
||||
}
|
||||
|
||||
snprintf(bestdemo, 255, "%s-score-best.lmp", gpath);
|
||||
if (!FIL_FileExists(bestdemo) || (G_CmpDemoTime(bestdemo, lastdemo) & (1<<1)))
|
||||
{ // Better score, save this demo.
|
||||
if (FIL_FileExists(bestdemo))
|
||||
remove(bestdemo);
|
||||
FIL_WriteFile(bestdemo, buf, len);
|
||||
CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW HIGH SCORE!"), M_GetText("Saved replay as"), bestdemo);
|
||||
}
|
||||
|
||||
//CONS_Printf("%s '%s'\n", M_GetText("Saved replay as"), lastdemo);
|
||||
|
||||
Z_Free(buf);
|
||||
}
|
||||
free(gpath);
|
||||
|
||||
// If the mare count changed, this will update the score display
|
||||
CV_AddValue(&cv_nextmap, 1);
|
||||
CV_AddValue(&cv_nextmap, -1);
|
||||
}*/
|
||||
|
||||
// for consistency among messages: this modifies the game and removes savemoddata.
|
||||
void G_SetGameModified(boolean silent, boolean major)
|
||||
{
|
||||
@@ -832,7 +648,8 @@ const char *G_BuildMapName(INT32 map)
|
||||
map = G_RandMap(G_TOLFlag(cv_newgametype.value), map, false, 0, false, NULL)+1;
|
||||
}
|
||||
|
||||
if (map < 100)
|
||||
|
||||
if (map < 100 && map >= 0) // ...but why use signed integer in first place? idk but this prevents warning (and potential buffer overflow lol)
|
||||
sprintf(&mapname[3], "%.2d", map);
|
||||
else
|
||||
{
|
||||
@@ -1621,10 +1438,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
||||
-Making some galaxy brain autopilot Lua if you're a masochist
|
||||
-Making a Mario Kart 8 Deluxe tier baby mode that steers you away from walls and whatnot. You know what, do what you want!
|
||||
*/
|
||||
#ifdef HAVE_BLUA
|
||||
if (gamestate == GS_LEVEL)
|
||||
LUAh_PlayerCmd(player, cmd);
|
||||
#endif
|
||||
|
||||
//Reset away view if a command is given.
|
||||
if ((cmd->forwardmove || cmd->sidemove || cmd->buttons)
|
||||
@@ -2128,31 +1943,6 @@ boolean G_CouldView(INT32 playernum)
|
||||
return false;
|
||||
}
|
||||
|
||||
// SRB2Kart: we have no team-based modes, YET...
|
||||
/*if (G_GametypeHasTeams())
|
||||
{
|
||||
if (players[consoleplayer].ctfteam
|
||||
&& player->ctfteam != players[consoleplayer].ctfteam)
|
||||
return false;
|
||||
}
|
||||
else if (gametype == GT_HIDEANDSEEK)
|
||||
{
|
||||
if (players[consoleplayer].pflags & PF_TAGIT)
|
||||
return false;
|
||||
}
|
||||
// Other Tag-based gametypes?
|
||||
else if (G_TagGametype())
|
||||
{
|
||||
if (!players[consoleplayer].spectator
|
||||
&& (players[consoleplayer].pflags & PF_TAGIT) != (player->pflags & PF_TAGIT))
|
||||
return false;
|
||||
}
|
||||
else if (G_GametypeHasSpectators() && G_BattleGametype())
|
||||
{
|
||||
if (!players[consoleplayer].spectator)
|
||||
return false;
|
||||
}*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2860,39 +2650,7 @@ void G_PlayerReborn(INT32 player)
|
||||
p->maxlink = 0;
|
||||
|
||||
// If NiGHTS, find lowest mare to start with.
|
||||
p->mare = 0; /*P_FindLowestMare();
|
||||
|
||||
CONS_Debug(DBG_NIGHTS, M_GetText("Current mare is %d\n"), p->mare);
|
||||
|
||||
if (p->mare == 255)
|
||||
p->mare = 0;*/
|
||||
|
||||
// Check to make sure their color didn't change somehow...
|
||||
/*if (G_GametypeHasTeams())
|
||||
{
|
||||
if (p->ctfteam == 1 && p->skincolor != skincolor_redteam)
|
||||
{
|
||||
if (p == &players[consoleplayer])
|
||||
CV_SetValue(&cv_playercolor, skincolor_redteam);
|
||||
else if (p == &players[displayplayers[1]])
|
||||
CV_SetValue(&cv_playercolor2, skincolor_redteam);
|
||||
else if (p == &players[displayplayers[2]])
|
||||
CV_SetValue(&cv_playercolor3, skincolor_redteam);
|
||||
else if (p == &players[displayplayers[3]])
|
||||
CV_SetValue(&cv_playercolor4, skincolor_redteam);
|
||||
}
|
||||
else if (p->ctfteam == 2 && p->skincolor != skincolor_blueteam)
|
||||
{
|
||||
if (p == &players[consoleplayer])
|
||||
CV_SetValue(&cv_playercolor, skincolor_blueteam);
|
||||
else if (p == &players[displayplayers[1]])
|
||||
CV_SetValue(&cv_playercolor2, skincolor_blueteam);
|
||||
else if (p == &players[displayplayers[2]])
|
||||
CV_SetValue(&cv_playercolor3, skincolor_blueteam);
|
||||
else if (p == &players[displayplayers[3]])
|
||||
CV_SetValue(&cv_playercolor4, skincolor_blueteam);
|
||||
}
|
||||
}*/
|
||||
p->mare = 0;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -2954,9 +2712,7 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost)
|
||||
if (starpost) //Don't even bother with looking for a place to spawn.
|
||||
{
|
||||
P_MovePlayerToStarpost(playernum);
|
||||
#ifdef HAVE_BLUA
|
||||
LUAh_PlayerSpawn(&players[playernum]); // Lua hook for player spawning :)
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3012,10 +2768,7 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost)
|
||||
}
|
||||
P_MovePlayerToSpawn(playernum, spawnpoint);
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
LUAh_PlayerSpawn(&players[playernum]); // Lua hook for player spawning :)
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
mapthing_t *G_FindCTFStart(INT32 playernum)
|
||||
@@ -3310,9 +3063,7 @@ void G_DoReborn(INT32 playernum)
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
LUAh_MapChange(gamemap);
|
||||
#endif
|
||||
G_DoLoadLevel(true);
|
||||
}
|
||||
}*/
|
||||
@@ -3413,12 +3164,8 @@ INT32 G_GetGametypeByName(const char *gametypestr)
|
||||
//
|
||||
boolean G_IsSpecialStage(INT32 mapnum)
|
||||
{
|
||||
#if 0
|
||||
return (gametype == GT_COOP && modeattacking != ATTACKING_RECORD && mapnum >= sstage_start && mapnum <= sstage_end);
|
||||
#else
|
||||
(void)mapnum;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
@@ -3430,17 +3177,7 @@ boolean G_IsSpecialStage(INT32 mapnum)
|
||||
boolean G_GametypeUsesLives(void)
|
||||
{
|
||||
// SRB2kart NEEDS no lives
|
||||
#if 0
|
||||
// Coop, Competitive
|
||||
if ((gametype == GT_COOP || gametype == GT_COMPETITION)
|
||||
&& !modeattacking // No lives in Time Attack
|
||||
//&& !G_IsSpecialStage(gamemap)
|
||||
&& !(maptol & TOL_NIGHTS)) // No lives in NiGHTS
|
||||
return true;
|
||||
return false;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
@@ -4149,11 +3886,6 @@ void G_LoadGameData(void)
|
||||
//For records
|
||||
tic_t rectime;
|
||||
tic_t reclap;
|
||||
//UINT32 recscore;
|
||||
//UINT16 recrings;
|
||||
|
||||
//UINT8 recmares;
|
||||
//INT32 curmare;
|
||||
|
||||
// Clear things so previously read gamedata doesn't transfer
|
||||
// to new gamedata
|
||||
@@ -4244,43 +3976,15 @@ void G_LoadGameData(void)
|
||||
{
|
||||
rectime = (tic_t)READUINT32(save_p);
|
||||
reclap = (tic_t)READUINT32(save_p);
|
||||
//recscore = READUINT32(save_p);
|
||||
//recrings = READUINT16(save_p);
|
||||
|
||||
/*if (recrings > 10000 || recscore > MAXSCORE)
|
||||
goto datacorrupt;*/
|
||||
|
||||
if (rectime || reclap)
|
||||
{
|
||||
G_AllocMainRecordData((INT16)i);
|
||||
mainrecords[i]->time = rectime;
|
||||
mainrecords[i]->lap = reclap;
|
||||
//mainrecords[i]->score = recscore;
|
||||
//mainrecords[i]->rings = recrings;
|
||||
}
|
||||
}
|
||||
|
||||
// Nights records
|
||||
/*for (i = 0; i < NUMMAPS; ++i)
|
||||
{
|
||||
if ((recmares = READUINT8(save_p)) == 0)
|
||||
continue;
|
||||
|
||||
G_AllocNightsRecordData((INT16)i);
|
||||
|
||||
for (curmare = 0; curmare < (recmares+1); ++curmare)
|
||||
{
|
||||
nightsrecords[i]->score[curmare] = READUINT32(save_p);
|
||||
nightsrecords[i]->grade[curmare] = READUINT8(save_p);
|
||||
nightsrecords[i]->time[curmare] = (tic_t)READUINT32(save_p);
|
||||
|
||||
if (nightsrecords[i]->grade[curmare] > GRADE_S)
|
||||
goto datacorrupt;
|
||||
}
|
||||
|
||||
nightsrecords[i]->nummares = recmares;
|
||||
}*/
|
||||
|
||||
// done
|
||||
Z_Free(savebuffer);
|
||||
save_p = NULL;
|
||||
@@ -4380,7 +4084,6 @@ void G_SaveGameData(boolean force)
|
||||
|
||||
WRITEUINT32(save_p, timesBeaten);
|
||||
WRITEUINT32(save_p, timesBeatenWithEmeralds);
|
||||
//WRITEUINT32(save_p, timesBeatenUltimate);
|
||||
|
||||
// Main records
|
||||
for (i = 0; i < NUMMAPS; i++)
|
||||
@@ -4389,8 +4092,6 @@ void G_SaveGameData(boolean force)
|
||||
{
|
||||
WRITEUINT32(save_p, mainrecords[i]->time);
|
||||
WRITEUINT32(save_p, mainrecords[i]->lap);
|
||||
//WRITEUINT32(save_p, mainrecords[i]->score);
|
||||
//WRITEUINT16(save_p, mainrecords[i]->rings);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4399,25 +4100,6 @@ void G_SaveGameData(boolean force)
|
||||
}
|
||||
}
|
||||
|
||||
// NiGHTS records
|
||||
/*for (i = 0; i < NUMMAPS; i++)
|
||||
{
|
||||
if (!nightsrecords[i] || !nightsrecords[i]->nummares)
|
||||
{
|
||||
WRITEUINT8(save_p, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
WRITEUINT8(save_p, nightsrecords[i]->nummares);
|
||||
|
||||
for (curmare = 0; curmare < (nightsrecords[i]->nummares + 1); ++curmare)
|
||||
{
|
||||
WRITEUINT32(save_p, nightsrecords[i]->score[curmare]);
|
||||
WRITEUINT8(save_p, nightsrecords[i]->grade[curmare]);
|
||||
WRITEUINT32(save_p, nightsrecords[i]->time[curmare]);
|
||||
}
|
||||
}*/
|
||||
|
||||
length = save_p - savebuffer;
|
||||
|
||||
FIL_WriteFile(va(pandf, srb2home, gamedatafilename), savebuffer, length);
|
||||
@@ -4709,28 +4391,7 @@ void G_InitNew(UINT8 pencoremode, const char *mapname, boolean resetplayer, bool
|
||||
players[i].playerstate = PST_REBORN;
|
||||
players[i].starpostangle = players[i].starpostnum = players[i].starposttime = 0;
|
||||
players[i].starpostx = players[i].starposty = players[i].starpostz = 0;
|
||||
|
||||
#if 0
|
||||
if (netgame || multiplayer)
|
||||
{
|
||||
players[i].lives = cv_startinglives.value;
|
||||
players[i].continues = 0;
|
||||
}
|
||||
else if (pultmode)
|
||||
{
|
||||
players[i].lives = 1;
|
||||
players[i].continues = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
players[i].lives = 3;
|
||||
players[i].continues = 1;
|
||||
}
|
||||
|
||||
players[i].xtralife = 0;
|
||||
#else
|
||||
players[i].lives = 1; // SRB2Kart
|
||||
#endif
|
||||
|
||||
// The latter two should clear by themselves, but just in case
|
||||
players[i].pflags &= ~(PF_TAGIT|PF_TAGGED|PF_FULLSTASIS);
|
||||
@@ -4784,9 +4445,7 @@ void G_InitNew(UINT8 pencoremode, const char *mapname, boolean resetplayer, bool
|
||||
F_StartCustomCutscene(mapheaderinfo[gamemap-1]->precutscenenum-1, true, resetplayer);
|
||||
else
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
LUAh_MapChange(gamemap);
|
||||
#endif
|
||||
G_DoLoadLevel(resetplayer);
|
||||
}
|
||||
|
||||
@@ -5032,10 +4691,8 @@ void G_FreeMapSearch(mapsearchfreq_t *freq, INT32 freqc)
|
||||
INT32 G_FindMapByNameOrCode(const char *mapname, char **realmapnamep)
|
||||
{
|
||||
boolean usemapcode = false;
|
||||
INT32 newmapnum;
|
||||
|
||||
INT32 newmapnum = -1;
|
||||
size_t mapnamelen = strlen(mapname);
|
||||
|
||||
char *p;
|
||||
|
||||
if (mapnamelen == 1)
|
||||
@@ -5109,9 +4766,7 @@ INT32 G_FindMapByNameOrCode(const char *mapname, char **realmapnamep)
|
||||
#define DF_NIGHTSATTACK 0x04 // This demo is from NiGHTS attack and contains its time left, score, and mares!
|
||||
#define DF_ATTACKMASK 0x06 // This demo is from ??? attack and contains ???
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
#define DF_LUAVARS 0x20 // this demo contains extra lua vars; this is mostly used for backwards compability
|
||||
#endif
|
||||
|
||||
#define DF_ATTACKSHIFT 1
|
||||
#define DF_ENCORE 0x40
|
||||
@@ -5274,7 +4929,6 @@ void G_ReadDemoExtraData(void)
|
||||
kartspeed = READUINT8(demo_p);
|
||||
kartweight = READUINT8(demo_p);
|
||||
|
||||
|
||||
if (stricmp(skins[players[p].skin].name, name) != 0)
|
||||
FindClosestSkinForStats(p, kartspeed, kartweight);
|
||||
|
||||
@@ -5383,7 +5037,7 @@ void G_ReadDemoExtraData(void)
|
||||
void G_WriteDemoExtraData(void)
|
||||
{
|
||||
INT32 i;
|
||||
char name[16];
|
||||
char name[17];
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
@@ -5416,7 +5070,7 @@ void G_WriteDemoExtraData(void)
|
||||
{
|
||||
// Name
|
||||
memset(name, 0, 16);
|
||||
strncpy(name, player_names[i], 16);
|
||||
memcpy(name, player_names[i], 15); // Keeping 1 null byte for safety, sorry players with name containing more than 15 characters
|
||||
M_Memcpy(demo_p,name,16);
|
||||
demo_p += 16;
|
||||
}
|
||||
@@ -5689,7 +5343,7 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
|
||||
|
||||
ziptic_p = demo_p++; // the ziptic, written at the end of this function
|
||||
|
||||
#define MAXMOM (0x7FFF<<8)
|
||||
#define MAXMOM (0x7FFF<<8)
|
||||
|
||||
// GZT_XYZ is only useful if you've moved 256 FRACUNITS or more in a single tic.
|
||||
if (abs(ghost->x-oldghost[playernum].x) > MAXMOM
|
||||
@@ -5744,7 +5398,7 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
|
||||
oldghost[playernum].z += oldghost[playernum].momz<<8;
|
||||
}
|
||||
|
||||
#undef MAXMOM
|
||||
#undef MAXMOM
|
||||
|
||||
// Only store the 8 most relevant bits of angle
|
||||
// because exact values aren't too easy to discern to begin with when only 8 angles have different sprites
|
||||
@@ -6763,7 +6417,7 @@ void G_RecordMetal(void)
|
||||
void G_BeginRecording(void)
|
||||
{
|
||||
UINT8 i, p;
|
||||
char name[16];
|
||||
char name[17];
|
||||
player_t *player = &players[consoleplayer];
|
||||
|
||||
char *filename;
|
||||
@@ -6780,11 +6434,9 @@ void G_BeginRecording(void)
|
||||
if (encoremode)
|
||||
demoflags |= DF_ENCORE;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (!modeattacking && gL) // Ghosts don't read luavars, and you shouldn't ever need to save Lua in replays, you doof!
|
||||
// SERIOUSLY THOUGH WHY WOULD YOU LOAD HOSTMOD AND RECORD A GHOST WITH IT !????
|
||||
demoflags |= DF_LUAVARS;
|
||||
#endif
|
||||
|
||||
// Setup header.
|
||||
M_Memcpy(demo_p, DEMOHEADER, 12); demo_p += 12;
|
||||
@@ -6837,11 +6489,6 @@ void G_BeginRecording(void)
|
||||
WRITEUINT32(demo_p,UINT32_MAX); // time
|
||||
WRITEUINT32(demo_p,UINT32_MAX); // lap
|
||||
break;
|
||||
/*case ATTACKING_NIGHTS: // 2
|
||||
demotime_p = demo_p;
|
||||
WRITEUINT32(demo_p,UINT32_MAX); // time
|
||||
WRITEUINT32(demo_p,0); // score
|
||||
break;*/
|
||||
default: // 3
|
||||
break;
|
||||
}
|
||||
@@ -6864,7 +6511,7 @@ void G_BeginRecording(void)
|
||||
|
||||
// Name
|
||||
memset(name, 0, 16);
|
||||
strncpy(name, player_names[p], 16);
|
||||
memcpy(name, player_names[p], 15);
|
||||
M_Memcpy(demo_p,name,16);
|
||||
demo_p += 16;
|
||||
|
||||
@@ -6892,11 +6539,9 @@ void G_BeginRecording(void)
|
||||
|
||||
WRITEUINT8(demo_p, 0xFF); // Denote the end of the player listing
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
// player lua vars, always saved even if empty... Unless it's record attack.
|
||||
if (demoflags & DF_LUAVARS)
|
||||
LUA_ArchiveDemo();
|
||||
#endif
|
||||
|
||||
memset(&oldcmd,0,sizeof(oldcmd));
|
||||
memset(&oldghost,0,sizeof(oldghost));
|
||||
@@ -6951,7 +6596,7 @@ void G_BeginMetal(void)
|
||||
|
||||
void G_WriteStanding(UINT8 ranking, char *name, INT32 skinnum, UINT8 color, UINT32 val)
|
||||
{
|
||||
char temp[16];
|
||||
char temp[17];
|
||||
|
||||
if (demoinfo_p && *(UINT32 *)demoinfo_p == 0)
|
||||
{
|
||||
@@ -6994,12 +6639,6 @@ void G_SetDemoTime(UINT32 ptime, UINT32 plap)
|
||||
WRITEUINT32(demotime_p, plap);
|
||||
demotime_p = NULL;
|
||||
}
|
||||
/*else if (demoflags & DF_NIGHTSATTACK)
|
||||
{
|
||||
WRITEUINT32(demotime_p, ptime);
|
||||
WRITEUINT32(demotime_p, pscore);
|
||||
demotime_p = NULL;
|
||||
}*/
|
||||
}
|
||||
|
||||
static void G_LoadDemoExtraFiles(UINT8 **pp)
|
||||
@@ -7007,7 +6646,7 @@ static void G_LoadDemoExtraFiles(UINT8 **pp)
|
||||
UINT8 totalfiles;
|
||||
char filename[MAX_WADPATH];
|
||||
UINT8 md5sum[16];
|
||||
filestatus_t ncs;
|
||||
filestatus_t ncs = FS_NOTFOUND;
|
||||
boolean toomany = false;
|
||||
boolean alreadyloaded;
|
||||
UINT8 i, j;
|
||||
@@ -7211,11 +6850,6 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname)
|
||||
newtime = READUINT32(p);
|
||||
newlap = READUINT32(p);
|
||||
}
|
||||
/*else if (flags & DF_NIGHTSATTACK)
|
||||
{
|
||||
newtime = READUINT32(p);
|
||||
newscore = READUINT32(p);
|
||||
}*/
|
||||
else // appease compiler
|
||||
return 0;
|
||||
|
||||
@@ -7281,11 +6915,6 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname)
|
||||
oldtime = READUINT32(p);
|
||||
oldlap = READUINT32(p);
|
||||
}
|
||||
/*else if (flags & DF_NIGHTSATTACK)
|
||||
{
|
||||
oldtime = READUINT32(p);
|
||||
oldscore = READUINT32(p);
|
||||
}*/
|
||||
else // appease compiler
|
||||
return UINT8_MAX;
|
||||
|
||||
@@ -7428,13 +7057,6 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
|
||||
if (pdemoflags & DF_ENCORE)
|
||||
pdemo->kartspeed |= DF_ENCORE;
|
||||
|
||||
/*// Temporary info until this is actually present in replays.
|
||||
(void)extrainfo_p;
|
||||
sprintf(pdemo->winnername, "transrights420");
|
||||
pdemo->winnerskin = 1;
|
||||
pdemo->winnercolor = SKINCOLOR_MOONSLAM;
|
||||
pdemo->winnertime = 6666;*/
|
||||
|
||||
// Read standings!
|
||||
count = 0;
|
||||
|
||||
@@ -7724,10 +7346,6 @@ void G_DoPlayDemo(char *defdemoname)
|
||||
hu_demotime = READUINT32(demo_p);
|
||||
hu_demolap = READUINT32(demo_p);
|
||||
break;
|
||||
/*case ATTACKING_NIGHTS: // 2
|
||||
hu_demotime = READUINT32(demo_p);
|
||||
hu_demoscore = READUINT32(demo_p);
|
||||
break;*/
|
||||
default: // 3
|
||||
modeattacking = ATTACKING_NONE;
|
||||
break;
|
||||
@@ -7882,9 +7500,8 @@ void G_DoPlayDemo(char *defdemoname)
|
||||
// didn't start recording right away.
|
||||
demo.deferstart = false;
|
||||
|
||||
/*#ifdef HAVE_BLUA
|
||||
LUAh_MapChange(gamemap);
|
||||
#endif*/
|
||||
//LUAh_MapChange(gamemap);
|
||||
|
||||
displayplayers[0] = consoleplayer = 0;
|
||||
memset(playeringame,0,sizeof(playeringame));
|
||||
|
||||
@@ -7971,7 +7588,6 @@ void G_DoPlayDemo(char *defdemoname)
|
||||
|
||||
// end of player read (the 0xFF marker)
|
||||
// so this is where we are to read our lua variables (if possible!)
|
||||
#ifdef HAVE_BLUA
|
||||
if (demoflags & DF_LUAVARS) // again, used for compability, lua shit will be saved to replays regardless of if it's even been loaded
|
||||
{
|
||||
if (!gL) // No Lua state! ...I guess we'll just start one...
|
||||
@@ -7980,7 +7596,6 @@ void G_DoPlayDemo(char *defdemoname)
|
||||
// No modeattacking check, DF_LUAVARS won't be present here.
|
||||
LUA_UnArchiveDemo();
|
||||
}
|
||||
#endif
|
||||
|
||||
splitscreen = 0;
|
||||
|
||||
@@ -8397,9 +8012,6 @@ void G_UpdateStaffGhostName(lumpnum_t l)
|
||||
case ATTACKING_RECORD: // 1
|
||||
p += 8; // demo time, lap
|
||||
break;
|
||||
/*case ATTACKING_NIGHTS: // 2
|
||||
p += 8; // demo time left, score
|
||||
break;*/
|
||||
default: // 3
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -383,21 +383,7 @@ void HWR_RenderBatches(void)
|
||||
changeState = true;
|
||||
changePolyFlags = true;
|
||||
}
|
||||
if ((cv_grshaders.value && gr_shadersavailable) && (HWR_ShouldUsePaletteRendering()))
|
||||
{
|
||||
if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba ||
|
||||
currentSurfaceInfo.TintColor.rgba != nextSurfaceInfo.TintColor.rgba ||
|
||||
currentSurfaceInfo.FadeColor.rgba != nextSurfaceInfo.FadeColor.rgba ||
|
||||
currentSurfaceInfo.LightInfo.light_level != nextSurfaceInfo.LightInfo.light_level ||
|
||||
currentSurfaceInfo.LightInfo.fade_start != nextSurfaceInfo.LightInfo.fade_start ||
|
||||
currentSurfaceInfo.LightInfo.fade_end != nextSurfaceInfo.LightInfo.fade_end ||
|
||||
currentSurfaceInfo.LightTableId != nextSurfaceInfo.LightTableId)
|
||||
{
|
||||
changeState = true;
|
||||
changeSurfaceInfo = true;
|
||||
}
|
||||
}
|
||||
else if (cv_grshaders.value && gr_shadersavailable)
|
||||
if (cv_grshaders.value && gr_shadersavailable)
|
||||
{
|
||||
if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba ||
|
||||
currentSurfaceInfo.TintColor.rgba != nextSurfaceInfo.TintColor.rgba ||
|
||||
|
||||
@@ -34,6 +34,4 @@ void HWR_SetCurrentTexture(GLMipmap_t *texture);
|
||||
void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, int shader, boolean horizonSpecial);
|
||||
void HWR_RenderBatches(void);
|
||||
|
||||
extern boolean currently_batching;
|
||||
|
||||
#endif
|
||||
@@ -809,12 +809,10 @@ static void AdjustSegs(void)
|
||||
float distv1,distv2,tmp;
|
||||
nearv1 = nearv2 = MYMAX;
|
||||
|
||||
#ifdef POLYOBJECTS
|
||||
// Don't touch polyobject segs. We'll compensate
|
||||
// for this when we go about drawing them.
|
||||
if (lseg->polyseg)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
if (p) {
|
||||
for (j = 0; j < p->numpts; j++)
|
||||
|
||||
+12
-28
@@ -32,6 +32,7 @@ INT32 patchformat = GL_TEXFMT_AP_88; // use alpha for holes
|
||||
INT32 textureformat = GL_TEXFMT_P_8; // use chromakey for hole
|
||||
|
||||
RGBA_t mapPalette[256] = {0}; // the palette for the currently loaded level or menu etc.
|
||||
|
||||
// Returns a pointer to the palette which should be used for caching textures.
|
||||
RGBA_t *HWR_GetTexturePalette(void)
|
||||
{
|
||||
@@ -85,7 +86,6 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
|
||||
position = originy + topdelta;
|
||||
|
||||
yfrac = 0;
|
||||
//yfracstep = (patchcol->length << FRACBITS) / count;
|
||||
if (position < 0)
|
||||
{
|
||||
yfrac = -position<<FRACBITS;
|
||||
@@ -107,18 +107,14 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
|
||||
count--;
|
||||
|
||||
texel = source[yfrac>>FRACBITS];
|
||||
|
||||
alpha = 0xff;
|
||||
|
||||
//Hurdler: not perfect, but better than holes
|
||||
if (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX && (mipmap->flags & TF_CHROMAKEYED))
|
||||
alpha = 0x00;
|
||||
|
||||
//texel = HWR_CHROMAKEY_EQUIVALENTCOLORINDEX;
|
||||
// Lat: Don't do that, some weirdos still use CYAN on their WALLTEXTURES for translucency :V
|
||||
|
||||
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
||||
else if (mipmap->colormap)
|
||||
if (mipmap->colormap)
|
||||
texel = mipmap->colormap[texel];
|
||||
|
||||
// hope compiler will get this switch out of the loops (dreams...)
|
||||
@@ -172,15 +168,10 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap,
|
||||
|
||||
palette = HWR_GetTexturePalette();
|
||||
|
||||
//ncols = (pwidth * pblockwidth) / pwidth;
|
||||
ncols = pwidth;
|
||||
|
||||
// source advance
|
||||
xfrac = 0;
|
||||
//xfracstep = (pwidth << FRACBITS) / pblockwidth;
|
||||
//yfracstep = (pheight << FRACBITS) / pblockheight;
|
||||
//scale_y = (pblockheight << FRACBITS) / pheight;
|
||||
|
||||
xfracstep = FRACUNIT;
|
||||
yfracstep = FRACUNIT;
|
||||
scale_y = FRACUNIT;
|
||||
@@ -254,14 +245,6 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
|
||||
col = x * pblockwidth / texture->width;
|
||||
ncols = ((x2 - x) * pblockwidth) / texture->width;
|
||||
|
||||
/*
|
||||
CONS_Debug(DBG_RENDER, "patch %dx%d texture %dx%d block %dx%d\n",
|
||||
width, height,
|
||||
texture->width, texture->height,
|
||||
pblockwidth, pblockheight);
|
||||
CONS_Debug(DBG_RENDER, " col %d ncols %d x %d\n", col, ncols, x);
|
||||
*/
|
||||
|
||||
// source advance
|
||||
xfrac = 0;
|
||||
if (x1 < 0)
|
||||
@@ -291,7 +274,6 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static UINT8 *MakeBlock(GLMipmap_t *grMipmap)
|
||||
{
|
||||
UINT8 *block;
|
||||
@@ -299,8 +281,8 @@ static UINT8 *MakeBlock(GLMipmap_t *grMipmap)
|
||||
UINT16 bu16 = ((0x00 <<8) | HWR_PATCHES_CHROMAKEY_COLORINDEX);
|
||||
INT32 blocksize = (grMipmap->width * grMipmap->height);
|
||||
|
||||
bpp = format2bpp(grMipmap->format);
|
||||
block = Z_Malloc(blocksize*bpp, PU_HWRCACHE, &(grMipmap->data));;
|
||||
bpp = format2bpp(grMipmap->format);
|
||||
block = Z_Malloc(blocksize*bpp, PU_HWRCACHE, &(grMipmap->data));
|
||||
|
||||
switch (bpp)
|
||||
{
|
||||
@@ -309,7 +291,6 @@ bpp = format2bpp(grMipmap->format);
|
||||
// fill background with chromakey, alpha = 0
|
||||
for (i = 0; i < blocksize; i++)
|
||||
memcpy(block+i*sizeof(UINT16), &bu16, sizeof(UINT16));
|
||||
|
||||
break;
|
||||
case 4: memset(block, 0x00, blocksize*sizeof(UINT32)); break;
|
||||
}
|
||||
@@ -502,12 +483,16 @@ static void FreeMipmapColormap(INT32 patchnum, void *patch)
|
||||
|
||||
// Set the first colormap to the one that comes after it.
|
||||
next = pat->mipmap->nextcolormap;
|
||||
if (!next)
|
||||
break;
|
||||
|
||||
pat->mipmap->nextcolormap = next->nextcolormap;
|
||||
|
||||
// Free image data from memory.
|
||||
if (next->data)
|
||||
Z_Free(next->data);
|
||||
next->data = NULL;
|
||||
HWD.pfnDeleteTexture(next);
|
||||
|
||||
// Free the old colormap mipmap from memory.
|
||||
free(next);
|
||||
@@ -646,6 +631,9 @@ static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum)
|
||||
void HWR_GetFlat(lumpnum_t flatlumpnum, boolean noencoremap)
|
||||
{
|
||||
GLMipmap_t *grmip;
|
||||
|
||||
if (flatlumpnum == LUMPERROR)
|
||||
return;
|
||||
|
||||
grmip = HWR_GetCachedGLPatch(flatlumpnum)->mipmap;
|
||||
|
||||
@@ -662,7 +650,6 @@ void HWR_GetFlat(lumpnum_t flatlumpnum, boolean noencoremap)
|
||||
// If hardware does not have the texture, then call pfnSetTexture to upload it
|
||||
if (!grmip->downloaded)
|
||||
HWD.pfnSetTexture(grmip);
|
||||
|
||||
HWR_SetCurrentTexture(grmip);
|
||||
|
||||
// The system-memory data can be purged now.
|
||||
@@ -778,7 +765,6 @@ void HWR_UnlockCachedPatch(GLPatch_t *gpatch)
|
||||
return;
|
||||
|
||||
Z_ChangeTag(gpatch->mipmap->data, PU_HWRCACHE_UNLOCKED);
|
||||
Z_ChangeTag(gpatch, PU_HWRPATCHINFO_UNLOCKED);
|
||||
}
|
||||
|
||||
GLPatch_t *HWR_GetCachedGLPatchPwad(UINT16 wadnum, UINT16 lumpnum)
|
||||
@@ -888,7 +874,6 @@ static void HWR_CacheFadeMask(GLMipmap_t *grMipmap, lumpnum_t fademasklumpnum)
|
||||
// I DO need to convert this because it isn't power of 2 and we need the alpha
|
||||
}
|
||||
|
||||
|
||||
void HWR_GetFadeMask(lumpnum_t fademasklumpnum)
|
||||
{
|
||||
GLMipmap_t *grmip;
|
||||
@@ -1085,8 +1070,7 @@ UINT32 HWR_GetLightTableID(extracolormap_t *colormap)
|
||||
// call become invalid and must not be used.
|
||||
void HWR_ClearLightTables(void)
|
||||
{
|
||||
//if (vid.glstate == VID_GL_LIBRARY_LOADED) // we have pfnInit which is essentially the same, but it doesent work here for whatever reason, since this should not be done in software renderer ever!
|
||||
if (rendermode == render_opengl)
|
||||
if (vid.glstate == VID_GL_LIBRARY_LOADED)
|
||||
HWD.pfnClearLightTables();
|
||||
}
|
||||
|
||||
|
||||
+12
-3
@@ -165,7 +165,6 @@ typedef struct
|
||||
FLOAT s,t;
|
||||
} FOutVector;
|
||||
|
||||
#ifdef GL_SHADERS
|
||||
// Shader targets used to render specific types of geometry.
|
||||
// A shader target is resolved to an actual shader with HWR_GetShaderFromTarget.
|
||||
// The shader returned may be a base shader or a custom shader.
|
||||
@@ -203,7 +202,6 @@ enum hwdshaderstage
|
||||
|
||||
typedef enum hwdshaderstage hwdshaderstage_t;
|
||||
|
||||
#endif
|
||||
|
||||
// ==========================================================================
|
||||
// RENDER MODES
|
||||
@@ -255,7 +253,17 @@ enum ETextureFlags
|
||||
TF_TRANSPARENT = 0x00000040, // texture with some alpha == 0
|
||||
};
|
||||
|
||||
typedef struct GLMipmap_s FTextureInfo;
|
||||
struct FTextureInfo
|
||||
{
|
||||
UINT32 width, height;
|
||||
UINT32 downloaded;
|
||||
UINT32 format;
|
||||
|
||||
struct GLMipmap_s *texture;
|
||||
struct FTextureInfo *prev, *next;
|
||||
};
|
||||
typedef struct FTextureInfo FTextureInfo;
|
||||
|
||||
|
||||
struct FLightInfo
|
||||
{
|
||||
@@ -279,6 +287,7 @@ typedef struct FSurfaceInfo FSurfaceInfo;
|
||||
|
||||
enum hwdsetspecialstate
|
||||
{
|
||||
HWD_SET_FRAMEBUFFER,
|
||||
HWD_SET_SHADERS,
|
||||
|
||||
HWD_SET_TEXTUREFILTERMODE,
|
||||
|
||||
@@ -234,7 +234,7 @@ void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t
|
||||
}
|
||||
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f)
|
||||
{
|
||||
if ((option & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM))
|
||||
if ((option & (V_SPLITSCREEN|V_SNAPTOTOP)) == (V_SPLITSCREEN|V_SNAPTOTOP))
|
||||
cy += ((float)vid.height/2 - ((float)BASEVIDHEIGHT/2 * dupy));
|
||||
else if (option & V_SNAPTOBOTTOM)
|
||||
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
|
||||
@@ -385,7 +385,7 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
|
||||
}
|
||||
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f)
|
||||
{
|
||||
if ((option & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM))
|
||||
if ((option & (V_SPLITSCREEN|V_SNAPTOTOP)) == (V_SPLITSCREEN|V_SNAPTOTOP))
|
||||
cy += ((float)vid.height/2 - ((float)BASEVIDHEIGHT/2 * dupy));
|
||||
else if (option & V_SNAPTOBOTTOM)
|
||||
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
|
||||
|
||||
@@ -36,8 +36,9 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUI
|
||||
EXPORT void HWRAPI(DrawIndexedTriangles) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, unsigned int *IndexArray);
|
||||
EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags);
|
||||
EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FBOOLEAN StencilMask, FRGBAFloat *ClearColor);
|
||||
EXPORT void HWRAPI(SetTexture) (FTextureInfo *TexInfo);
|
||||
EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *TexInfo);
|
||||
EXPORT void HWRAPI(SetTexture) (GLMipmap_t *TexInfo);
|
||||
EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *TexInfo);
|
||||
EXPORT void HWRAPI(DeleteTexture) (GLMipmap_t *TexInfo);
|
||||
EXPORT void HWRAPI(ReadScreenTexture) (int tex, UINT16 *dst_data);
|
||||
EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip, float farclip);
|
||||
EXPORT void HWRAPI(ClearMipMapCache) (void);
|
||||
@@ -59,7 +60,7 @@ EXPORT void HWRAPI(FlushScreenTextures) (void);
|
||||
EXPORT void HWRAPI(DoScreenWipe) (int wipeStart, int wipeEnd);
|
||||
EXPORT void HWRAPI(DrawScreenTexture) (int tex, FSurfaceInfo *surf, FBITFIELD polyflags);
|
||||
EXPORT void HWRAPI(MakeScreenTexture) (int tex);
|
||||
EXPORT void HWRAPI(DrawScreenFinalTexture) (int tex, int width, int height);
|
||||
EXPORT void HWRAPI(DrawScreenFinalTexture) (int tex, INT32 width, INT32 height);
|
||||
|
||||
EXPORT void HWRAPI(RenderVhsEffect) (fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize);
|
||||
|
||||
@@ -99,6 +100,7 @@ struct hwdriver_s
|
||||
ClearBuffer pfnClearBuffer;
|
||||
SetTexture pfnSetTexture;
|
||||
UpdateTexture pfnUpdateTexture;
|
||||
DeleteTexture pfnDeleteTexture;
|
||||
ReadScreenTexture pfnReadScreenTexture;
|
||||
GClipRect pfnGClipRect;
|
||||
ClearMipMapCache pfnClearMipMapCache;
|
||||
|
||||
+337
-609
File diff suppressed because it is too large.
Load diff
+3
-12
@@ -115,19 +115,15 @@ void HWR_DrawIntermissionBG(void);
|
||||
void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum);
|
||||
void HWR_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize);
|
||||
void HWR_MakeScreenFinalTexture(void);
|
||||
void HWR_DrawScreenFinalTexture(int width, int height);
|
||||
void HWR_DrawScreenFinalTexture(INT32 width, INT32 height);
|
||||
|
||||
// hw_main.c: Planes
|
||||
void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap);
|
||||
void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap);
|
||||
|
||||
#ifdef POLYOBJECTS
|
||||
#ifdef POLYOBJECTS_PLANES
|
||||
void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, FBITFIELD blendmode, UINT8 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap);
|
||||
void HWR_AddPolyObjectPlanes(void);
|
||||
void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// hw_main.c: Segs
|
||||
void HWR_ProcessSeg(void); // Sort of like GLWall::Process in GZDoom
|
||||
@@ -138,10 +134,6 @@ void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo * pSurf, INT32 t
|
||||
void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf);
|
||||
void HWR_DrawSkyBackground(float fpov);
|
||||
|
||||
#ifdef POLYOBJECTS
|
||||
void HWR_AddPolyObjectSegs(void);
|
||||
#endif
|
||||
|
||||
// hw_main.c: BSP
|
||||
void HWR_RenderBSPNode(INT32 bspnum);
|
||||
void HWR_Subsector(size_t num);
|
||||
@@ -163,13 +155,11 @@ extern boolean gr_maphasportals;
|
||||
void HWR_LoadTextures(size_t pnumtextures);
|
||||
RGBA_t *HWR_GetTexturePalette(void);
|
||||
|
||||
// hw_trick.c
|
||||
void HWR_CorrectSWTricks(void);
|
||||
|
||||
void HWR_SetShaderState(void);
|
||||
|
||||
// Console variables
|
||||
extern consvar_t cv_grshaders;
|
||||
extern consvar_t cv_grframebuffer;
|
||||
extern consvar_t cv_grfofcut;
|
||||
extern consvar_t cv_fofzfightfix;
|
||||
extern consvar_t cv_splitwallfix;
|
||||
@@ -198,6 +188,7 @@ extern consvar_t cv_grscreentextures;
|
||||
extern consvar_t cv_grportals;
|
||||
extern consvar_t cv_nostencil;
|
||||
extern consvar_t cv_secbright;
|
||||
extern consvar_t cv_grfastsprites;
|
||||
|
||||
extern CV_PossibleValue_t granisotropicmode_cons_t[];
|
||||
|
||||
|
||||
+13
-13
@@ -243,7 +243,7 @@ static GLTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_
|
||||
|
||||
{
|
||||
png_uint_32 i, pitch = png_get_rowbytes(png_ptr, png_info_ptr);
|
||||
png_bytep PNG_image = Z_Malloc(pitch*height, PU_HWRCACHE, &grpatch->mipmap->data);
|
||||
png_bytep PNG_image = Z_Malloc(pitch*height, PU_HWRMODELTEXTURE, &grpatch->mipmap->data);
|
||||
png_bytepp row_pointers = png_malloc(png_ptr, height * sizeof (png_bytep));
|
||||
for (i = 0; i < height; i++)
|
||||
row_pointers[i] = PNG_image + i*pitch;
|
||||
@@ -323,7 +323,7 @@ static GLTextureFormat_t PCX_Load(const char *filename, int *w, int *h,
|
||||
|
||||
pw = *w = header.xmax - header.xmin + 1;
|
||||
ph = *h = header.ymax - header.ymin + 1;
|
||||
image = Z_Malloc(pw*ph*4, PU_HWRCACHE, &grpatch->mipmap->data);
|
||||
image = Z_Malloc(pw*ph*4, PU_HWRMODELTEXTURE, &grpatch->mipmap->data);
|
||||
|
||||
if (fread(palette, sizeof (UINT8), PALSIZE, file) != PALSIZE)
|
||||
{
|
||||
@@ -712,7 +712,7 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch,
|
||||
grmip->data = NULL;
|
||||
}
|
||||
|
||||
cur = Z_Malloc(size*4, PU_HWRCACHE, &grmip->data);
|
||||
cur = Z_Malloc(size*4, PU_HWRMODELTEXTURE, &grmip->data);
|
||||
memset(cur, 0x00, size*4);
|
||||
|
||||
image = gpatch->mipmap->data;
|
||||
@@ -1062,7 +1062,7 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT
|
||||
if (grmip->downloaded && grmip->data)
|
||||
{
|
||||
HWD.pfnSetTexture(grmip); // found the colormap, set it to the correct texture
|
||||
Z_ChangeTag(grmip->data, PU_HWRCACHE_UNLOCKED);
|
||||
Z_ChangeTag(grmip->data, PU_HWRMODELTEXTURE_UNLOCKED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1084,7 +1084,7 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT
|
||||
HWR_CreateBlendedTexture(gpatch, blendgpatch, newmip, skinnum, color);
|
||||
|
||||
HWD.pfnSetTexture(newmip);
|
||||
Z_ChangeTag(newmip->data, PU_HWRCACHE_UNLOCKED);
|
||||
Z_ChangeTag(newmip->data, PU_HWRMODELTEXTURE_UNLOCKED);
|
||||
}
|
||||
|
||||
|
||||
@@ -1260,30 +1260,30 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
||||
md2->blendgrpatch && ((GLPatch_t *)md2->blendgrpatch)->mipmap->format
|
||||
&& gpatch->width == ((GLPatch_t *)md2->blendgrpatch)->width && gpatch->height == ((GLPatch_t *)md2->blendgrpatch)->height)
|
||||
{
|
||||
INT32 skinnum = TC_DEFAULT;
|
||||
INT32 tcskinnum = TC_DEFAULT;
|
||||
if ((spr->mobj->flags & MF_BOSS) && (spr->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash"
|
||||
{
|
||||
if (spr->mobj->type == MT_CYBRAKDEMON)
|
||||
skinnum = TC_ALLWHITE;
|
||||
tcskinnum = TC_ALLWHITE;
|
||||
else if (spr->mobj->type == MT_METALSONIC_BATTLE)
|
||||
skinnum = TC_METALSONIC;
|
||||
tcskinnum = TC_METALSONIC;
|
||||
else
|
||||
skinnum = TC_BOSS;
|
||||
tcskinnum = TC_BOSS;
|
||||
}
|
||||
else if (spr->mobj->color)
|
||||
{
|
||||
if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
|
||||
{
|
||||
if (spr->mobj->colorized)
|
||||
skinnum = TC_RAINBOW;
|
||||
tcskinnum = TC_RAINBOW;
|
||||
else
|
||||
{
|
||||
skinnum = (INT32)((skin_t*)( (spr->mobj->localskin) ? spr->mobj->localskin : spr->mobj->skin ) - ( (spr->mobj->skinlocal) ? localskins : skins ));
|
||||
tcskinnum = (INT32)((skin_t*)( (spr->mobj->localskin) ? spr->mobj->localskin : spr->mobj->skin ) - ( (spr->mobj->skinlocal) ? localskins : skins ));
|
||||
}
|
||||
}
|
||||
else skinnum = TC_DEFAULT;
|
||||
else tcskinnum = TC_DEFAULT;
|
||||
}
|
||||
HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, skinnum, spr->colormap, (skincolors_t)spr->mobj->color);
|
||||
HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, tcskinnum, spr->colormap, (skincolors_t)spr->mobj->color);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -439,7 +439,7 @@ void HWR_LoadAllCustomShaders(void)
|
||||
|
||||
// read every custom shader
|
||||
for (i = 0; i < numwadfiles; i++)
|
||||
HWR_LoadCustomShadersFromFile(i, (wadfiles[i]->type == RET_PK3));
|
||||
HWR_LoadCustomShadersFromFile(i, W_FileHasFolders(wadfiles[i]));
|
||||
}
|
||||
|
||||
void HWR_LoadCustomShadersFromFile(UINT16 wadnum, boolean PK3)
|
||||
@@ -454,7 +454,7 @@ void HWR_LoadCustomShadersFromFile(UINT16 wadnum, boolean PK3)
|
||||
int i;
|
||||
boolean modified_shaders[NUMSHADERTARGETS] = {0};
|
||||
|
||||
if (!HWR_UseShader())
|
||||
if (!gr_shadersavailable)
|
||||
return;
|
||||
|
||||
lump = HWR_FindShaderDefs(wadnum);
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
#define GLSL_SOFTWARE_TINT_EQUATION \
|
||||
"if (tint_color.a > 0.0) {\n" \
|
||||
"float color_bright = sqrt((base_color.r * base_color.r) + (base_color.g * base_color.g) + (base_color.b * base_color.b));\n" \
|
||||
"float strength = sqrt(9.0 * tint_color.a);\n" \
|
||||
"float strength = sqrt(tint_color.a);\n" \
|
||||
"final_color.r = clamp((color_bright * (tint_color.r * strength)) + (base_color.r * (1.0 - strength)), 0.0, 1.0);\n" \
|
||||
"final_color.g = clamp((color_bright * (tint_color.g * strength)) + (base_color.g * (1.0 - strength)), 0.0, 1.0);\n" \
|
||||
"final_color.b = clamp((color_bright * (tint_color.b * strength)) + (base_color.b * (1.0 - strength)), 0.0, 1.0);\n" \
|
||||
@@ -161,15 +161,15 @@
|
||||
#define GLSL_WATER_TEXEL \
|
||||
"float water_z = (gl_FragCoord.z / gl_FragCoord.w) / 2.0;\n" \
|
||||
"float a = -pi * (water_z * freq) + (leveltime * speed);\n" \
|
||||
"float sdistort = sin(a) * amp;\n" \
|
||||
"float cdistort = cos(a) * amp;\n" \
|
||||
"float sdistort = sin(a) * amp * 1.5;\n" \
|
||||
"float cdistort = cos(a) * amp * 2.2;\n" \
|
||||
"vec4 texel = texture2D(tex, vec2(gl_TexCoord[0].s - sdistort, gl_TexCoord[0].t - cdistort));\n"
|
||||
|
||||
#define GLSL_WATER_FRAGMENT_SHADER \
|
||||
GLSL_FLOOR_FUDGES \
|
||||
"const float freq = 0.025;\n" \
|
||||
"const float freq = 0.03;\n" \
|
||||
"const float amp = 0.025;\n" \
|
||||
"const float speed = 2.0;\n" \
|
||||
"const float speed = 1.6;\n" \
|
||||
"const float pi = 3.14159;\n" \
|
||||
"#ifdef SRB2_PALETTE_RENDERING\n" \
|
||||
"uniform sampler2D tex;\n" \
|
||||
|
||||
@@ -1,919 +0,0 @@
|
||||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (C) 1998-2001 by DooM Legacy Team.
|
||||
//
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file
|
||||
/// \brief special trick routines to make some SW tricks look OK with
|
||||
/// HW rendering. This includes:
|
||||
/// - deepwatereffect (e.g. tnt/map02)
|
||||
/// - invisible staircase (e.g. eternal/map02)
|
||||
/// - floating ceilings (e.g. eternal/map03)
|
||||
///
|
||||
/// It is not guaranteed that it looks identical to the SW mode,
|
||||
/// but it looks in most of the cases far better than having
|
||||
/// holes in the architecture, HOM, etc.
|
||||
///
|
||||
/// It fixes as well missing textures, which are replaced by either
|
||||
/// a default texture or the midtexture.
|
||||
///
|
||||
/// words of notice:
|
||||
/// pseudosectors, as mentioned in this file, are sectors where both
|
||||
/// sidedefs point to the same sector. This expression is also used
|
||||
/// for sectors which are enclosed by another sector but have no
|
||||
/// correct sidedefs at all
|
||||
///
|
||||
/// if a vertex is inside a poly is determined by the angles between
|
||||
/// this vertex and all angles on the linedefs (imagine walking along
|
||||
/// a circle always facing a certain point inside/outside the circle;
|
||||
/// if inside, angle have taken all values [0..pi), otherwise the
|
||||
/// range was < pi/2
|
||||
|
||||
#include <math.h>
|
||||
#include "../doomdef.h"
|
||||
#include "../doomstat.h"
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hw_main.h"
|
||||
#include "hw_glob.h"
|
||||
#include "hw_dll.h"
|
||||
#include "../r_local.h"
|
||||
#include "../i_system.h"
|
||||
|
||||
//
|
||||
// add a line to a sectors list of lines
|
||||
//
|
||||
static void addLineToChain(sector_t *sector, line_t *line)
|
||||
{
|
||||
linechain_t *thisElem = NULL, *nextElem;
|
||||
|
||||
if (!sector)
|
||||
return;
|
||||
|
||||
nextElem = sector->sectorLines;
|
||||
|
||||
while (nextElem) // walk through chain
|
||||
{
|
||||
thisElem = nextElem;
|
||||
nextElem = thisElem->next;
|
||||
}
|
||||
|
||||
// add a new element into the chain
|
||||
if (thisElem)
|
||||
{
|
||||
thisElem->next = malloc(sizeof (linechain_t));
|
||||
if (thisElem->next)
|
||||
{
|
||||
thisElem->next->line = line;
|
||||
thisElem->next->next = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
I_Error("Out of memory in addLineToChain(.)\n");
|
||||
}
|
||||
}
|
||||
else // first element in chain
|
||||
{
|
||||
sector->sectorLines = malloc(sizeof (linechain_t));
|
||||
if (sector->sectorLines)
|
||||
{
|
||||
sector->sectorLines->line = line;
|
||||
sector->sectorLines->next = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
I_Error("Out of memory in addLineToChain(.)\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// We dont want a memory hole, do we?;-)
|
||||
//
|
||||
static void releaseLineChains(void)
|
||||
{
|
||||
linechain_t *thisElem, *nextElem;
|
||||
sector_t *sector;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < numsectors; i++)
|
||||
{
|
||||
sector = §ors[i];
|
||||
nextElem = sector->sectorLines;
|
||||
|
||||
while (nextElem)
|
||||
{
|
||||
thisElem = nextElem;
|
||||
nextElem = thisElem->next;
|
||||
free(thisElem);
|
||||
}
|
||||
|
||||
sector->sectorLines = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// check if a pseudo sector is valid by checking all its linedefs
|
||||
//
|
||||
static boolean isPSectorValid(sector_t *sector)
|
||||
{
|
||||
linechain_t *thisElem, *nextElem;
|
||||
|
||||
if (!sector->pseudoSector) // check only pseudosectors, others dont care
|
||||
{
|
||||
#ifdef PARANOIA
|
||||
CONS_Debug(DBG_RENDER, "Alert! non-pseudosector fed to isPSectorClosed()\n");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
nextElem = sector->sectorLines;
|
||||
|
||||
while (nextElem)
|
||||
{
|
||||
thisElem = nextElem;
|
||||
nextElem = thisElem->next;
|
||||
if (thisElem->line->frontsector != thisElem->line->backsector)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// angles are always phiMax-phiMin [0...2\pi)
|
||||
//
|
||||
FUNCMATH static double phiDiff(double phiMin, double phiMax)
|
||||
{
|
||||
double result;
|
||||
|
||||
result = phiMax-phiMin;
|
||||
|
||||
if (result < 0.0l)
|
||||
result += 2.0l*M_PIl;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// sort phi's so that enclosed angle < \pi
|
||||
//
|
||||
static void sortPhi(double phi1, double phi2, double *phiMin, double *phiMax)
|
||||
{
|
||||
if (phiDiff(phi1, phi2) < M_PIl)
|
||||
{
|
||||
*phiMin = phi1;
|
||||
*phiMax = phi2;
|
||||
}
|
||||
else
|
||||
{
|
||||
*phiMin = phi2;
|
||||
*phiMax = phi1;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// return if angle(phi1, phi2) is bigger than \pi
|
||||
// if so, the vertex lies inside the poly
|
||||
//
|
||||
FUNCMATH static boolean biggerThanPi(double phi1, double phi2)
|
||||
{
|
||||
if (phiDiff(phi1, phi2) > M_PIl)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#define DELTAPHI (M_PIl/100.0l) // some small phi << \pi
|
||||
|
||||
//
|
||||
// calculate bounds for minimum angle
|
||||
//
|
||||
static void phiBounds(double phi1, double phi2, double *phiMin, double *phiMax)
|
||||
{
|
||||
double phi1Tmp, phi2Tmp;
|
||||
double psi1, psi2, psi3, psi4, psi5, psi6, psi7; // for optimization
|
||||
|
||||
sortPhi(phi1, phi2, &phi1Tmp, &phi2Tmp);
|
||||
phi1 = phi1Tmp;
|
||||
phi2 = phi2Tmp;
|
||||
|
||||
// check start condition
|
||||
if (*phiMin > M_PIl || *phiMax > M_PIl)
|
||||
{
|
||||
*phiMin = phi1;
|
||||
*phiMax = phi2;
|
||||
return;
|
||||
}
|
||||
|
||||
// 6 cases:
|
||||
// new angles inbetween phiMin, phiMax -> forget it
|
||||
// new angles enclose phiMin -> set phiMin
|
||||
// new angles enclose phiMax -> set phiMax
|
||||
// new angles completely outside phiMin, phiMax -> leave largest area free
|
||||
// new angles close the range completely!
|
||||
// new angles enlarges range on both sides
|
||||
|
||||
psi1 = phiDiff(*phiMin, phi1);
|
||||
psi2 = phiDiff(*phiMin, phi2);
|
||||
psi3 = phiDiff(*phiMax, phi1);
|
||||
psi4 = phiDiff(*phiMax, phi2);
|
||||
psi5 = phiDiff(*phiMin, *phiMax);
|
||||
psi6 = (double)(2.0l*M_PIl - psi5); // phiDiff(*phiMax, *phiMin);
|
||||
psi7 = (double)(2.0l*M_PIl - psi2); // phiDiff(phi2, *phiMin);
|
||||
|
||||
// case 1 & 5!
|
||||
if ((psi1 <= psi5) && (psi2 <= psi5))
|
||||
{
|
||||
if (psi1 <= psi2) // case 1
|
||||
{
|
||||
return;
|
||||
}
|
||||
else // case 5
|
||||
{
|
||||
// create some artificial interval here not to get into numerical trouble
|
||||
// in fact we know now the sector is completely enclosed -> base for computational optimization
|
||||
*phiMax = 0.0l;
|
||||
*phiMin = DELTAPHI;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// case 2
|
||||
if ((psi1 >= psi5) && (psi2 <= psi5))
|
||||
{
|
||||
*phiMin = phi1;
|
||||
return;
|
||||
}
|
||||
|
||||
// case 3
|
||||
if ((psi3 >= psi6) && (psi4 <= psi6))
|
||||
{
|
||||
*phiMax = phi2;
|
||||
return;
|
||||
}
|
||||
|
||||
// case 4 & 6
|
||||
#ifdef PARANOIA
|
||||
if ((psi3 <= psi6) && (psi4 <= psi6)) // FIXME: isn't this case implicitly true anyway??
|
||||
#endif
|
||||
{
|
||||
if (psi3 <= psi4) //case 4
|
||||
{
|
||||
if (psi3 >= psi7)
|
||||
{
|
||||
*phiMin = phi1;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
*phiMax = phi2;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else // case 6
|
||||
{
|
||||
*phiMin = phi1;
|
||||
*phiMax = phi2;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PARANOIA
|
||||
CONS_Debug(DBG_RENDER, "phiMin = %f, phiMax = %f, phi1 = %f, phi2 = %f\n", *phiMin, *phiMax, phi1, phi2);
|
||||
I_Error("phiBounds() out of range!\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// Check if a vertex lies inside a sector
|
||||
// This works for "well-behaved" convex polygons
|
||||
// If we need it mathematically correct, we need to sort the
|
||||
// linedefs first so we have them in a row, then walk along the linedefs,
|
||||
// but this is a bit overdone
|
||||
//
|
||||
static inline boolean isVertexInside(vertex_t *vertex, sector_t *sector)
|
||||
{
|
||||
double xa, ya, xe, ye;
|
||||
linechain_t *chain;
|
||||
double phiMin, phiMax;
|
||||
double phi1, phi2;
|
||||
|
||||
chain = sector->sectorLines;
|
||||
phiMin = phiMax = 10.0l*M_PIl; // some value > \pi
|
||||
|
||||
while (chain)
|
||||
{
|
||||
// start and end vertex
|
||||
xa = (double)chain->line->v1->x - (double)vertex->x;
|
||||
ya = (double)chain->line->v1->y - (double)vertex->y;
|
||||
xe = (double)chain->line->v2->x - (double)vertex->x;
|
||||
ye = (double)chain->line->v2->y - (double)vertex->y;
|
||||
|
||||
// angle phi of connection between the vertices and the x-axis
|
||||
phi1 = atan2(ya, xa);
|
||||
phi2 = atan2(ye, xe);
|
||||
|
||||
// if we have just started, we can have to create start bounds for phi
|
||||
|
||||
phiBounds(phi1, phi2, &phiMin, &phiMax);
|
||||
chain = chain->next;
|
||||
}
|
||||
|
||||
return biggerThanPi(phiMin, phiMax);
|
||||
}
|
||||
|
||||
|
||||
#define MAXSTACK 256 // Not more than 256 polys in each other?
|
||||
//
|
||||
// generate a list of sectors which enclose the given sector
|
||||
//
|
||||
static void generateStacklist(sector_t *thisSector)
|
||||
{
|
||||
size_t i, stackCnt = 0;
|
||||
sector_t *locStacklist[MAXSTACK];
|
||||
sector_t *checkSector;
|
||||
|
||||
for (i = 0; i < numsectors; i++)
|
||||
{
|
||||
checkSector = §ors[i];
|
||||
|
||||
if (checkSector == thisSector) // dont check self
|
||||
continue;
|
||||
|
||||
// buggy sector?
|
||||
if (!thisSector->sectorLines)
|
||||
continue;
|
||||
|
||||
// check if an arbitrary vertex of thisSector lies inside the checkSector
|
||||
if (isVertexInside(thisSector->sectorLines->line->v1, checkSector))
|
||||
{
|
||||
// if so, the thisSector lies inside the checkSector
|
||||
locStacklist[stackCnt] = checkSector;
|
||||
stackCnt++;
|
||||
|
||||
if (MAXSTACK-1 == stackCnt) // beware of the SIGSEGV! and consider terminating NULL!
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
thisSector->stackList = malloc(sizeof (sector_t *) * (stackCnt+1));
|
||||
if (NULL == thisSector->stackList)
|
||||
{
|
||||
I_Error("Out of memory error in generateStacklist()");
|
||||
}
|
||||
|
||||
locStacklist[stackCnt] = NULL; // terminating NULL
|
||||
|
||||
memcpy(thisSector->stackList, locStacklist, sizeof (sector_t *) * (stackCnt+1));
|
||||
}
|
||||
|
||||
//
|
||||
// Bubble sort the stacklist with rising lineoutlengths
|
||||
//
|
||||
static void sortStacklist(sector_t *sector)
|
||||
{
|
||||
sector_t **list;
|
||||
sector_t *sec1, *sec2;
|
||||
boolean finished;
|
||||
size_t i;
|
||||
|
||||
list = sector->stackList;
|
||||
finished = false;
|
||||
|
||||
if (!*list)
|
||||
return; // nothing to sort
|
||||
|
||||
while (!finished)
|
||||
{
|
||||
i = 0;
|
||||
finished = true;
|
||||
|
||||
while (*(list+i+1))
|
||||
{
|
||||
sec1 = *(list+i);
|
||||
sec2 = *(list+i+1);
|
||||
|
||||
if (sec1->lineoutLength > sec2->lineoutLength)
|
||||
{
|
||||
*(list+i) = sec2;
|
||||
*(list+i+1) = sec1;
|
||||
finished = false;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// length of a line in euclidian sense
|
||||
//
|
||||
static double lineLength(line_t *line)
|
||||
{
|
||||
double dx, dy, length;
|
||||
|
||||
dx = (double) line->v1->x - (double) line->v2->x;
|
||||
dy = (double) line->v1->y - (double) line->v2->y;
|
||||
|
||||
length = hypot(dx, dy);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// length of the sector lineout
|
||||
//
|
||||
static double calcLineoutLength(sector_t *sector)
|
||||
{
|
||||
linechain_t *chain;
|
||||
double length = 0.0L;
|
||||
chain = sector->sectorLines;
|
||||
|
||||
while (chain) // sum up lengths of all lines
|
||||
{
|
||||
length += lineLength(chain->line);
|
||||
chain = chain->next;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate length of the sectors lineout
|
||||
//
|
||||
static void calcLineouts(sector_t *sector)
|
||||
{
|
||||
size_t secCount = 0;
|
||||
sector_t *encSector = *(sector->stackList);
|
||||
|
||||
while (encSector)
|
||||
{
|
||||
if (encSector->lineoutLength < 0.0L) // if length has not yet been calculated
|
||||
{
|
||||
encSector->lineoutLength = calcLineoutLength(encSector);
|
||||
}
|
||||
|
||||
secCount++;
|
||||
encSector = *((sector->stackList) + secCount);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Free Stacklists of all sectors
|
||||
//
|
||||
static void freeStacklists(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < numsectors; i++)
|
||||
{
|
||||
if (sectors[i].stackList)
|
||||
{
|
||||
free(sectors[i].stackList);
|
||||
sectors[i].stackList = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// if more than half of the toptextures are missing
|
||||
//
|
||||
static boolean areToptexturesMissing(sector_t *thisSector)
|
||||
{
|
||||
linechain_t *thisElem, *nextElem = thisSector->sectorLines;
|
||||
sector_t *frontSector, *backSector;
|
||||
size_t nomiss = 0;
|
||||
side_t *sidel, *sider;
|
||||
|
||||
while (nextElem) // walk through chain
|
||||
{
|
||||
thisElem = nextElem;
|
||||
nextElem = thisElem->next;
|
||||
|
||||
frontSector = thisElem->line->frontsector;
|
||||
backSector = thisElem->line->backsector;
|
||||
|
||||
if (frontSector == backSector) // skip damn renderer tricks here
|
||||
continue;
|
||||
|
||||
if (!frontSector || !backSector)
|
||||
continue;
|
||||
|
||||
sider = &sides[thisElem->line->sidenum[0]];
|
||||
sidel = &sides[thisElem->line->sidenum[1]];
|
||||
|
||||
if (backSector->ceilingheight < frontSector->ceilingheight)
|
||||
{
|
||||
if (sider->toptexture != 0)
|
||||
{
|
||||
nomiss++;
|
||||
break; // we can stop here if decision criterium is ==0
|
||||
}
|
||||
}
|
||||
else if (backSector->ceilingheight > frontSector->ceilingheight)
|
||||
{
|
||||
if (sidel->toptexture != 0)
|
||||
{
|
||||
nomiss++;
|
||||
break; // we can stop here if decision criterium is ==0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nomiss == 0;
|
||||
}
|
||||
|
||||
//
|
||||
// are more textures missing than present?
|
||||
//
|
||||
static boolean areBottomtexturesMissing(sector_t *thisSector)
|
||||
{
|
||||
linechain_t *thisElem, *nextElem = thisSector->sectorLines;
|
||||
sector_t *frontSector, *backSector;
|
||||
size_t nomiss = 0;
|
||||
side_t *sidel, *sider;
|
||||
|
||||
while (nextElem) // walk through chain
|
||||
{
|
||||
thisElem = nextElem;
|
||||
nextElem = thisElem->next;
|
||||
|
||||
frontSector = thisElem->line->frontsector;
|
||||
backSector = thisElem->line->backsector;
|
||||
|
||||
if (frontSector == backSector) // skip damn renderer tricks here
|
||||
continue;
|
||||
|
||||
if (!frontSector || !backSector)
|
||||
continue;
|
||||
|
||||
sider = &sides[thisElem->line->sidenum[0]];
|
||||
sidel = &sides[thisElem->line->sidenum[1]];
|
||||
|
||||
if (backSector->floorheight > frontSector->floorheight)
|
||||
{
|
||||
if (sider->bottomtexture != 0)
|
||||
{
|
||||
nomiss++;
|
||||
break; // we can stop here if decision criterium is ==0
|
||||
}
|
||||
}
|
||||
|
||||
else if (backSector->floorheight < frontSector->floorheight)
|
||||
{
|
||||
if (sidel->bottomtexture != 0)
|
||||
{
|
||||
nomiss++;
|
||||
break; // we can stop here if decision criterium is ==0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return missing >= nomiss;
|
||||
return nomiss == 0;
|
||||
}
|
||||
|
||||
//
|
||||
// check if no adjacent sector has same ceiling height
|
||||
//
|
||||
static boolean isCeilingFloating(sector_t *thisSector)
|
||||
{
|
||||
sector_t *adjSector, *refSector = NULL, *frontSector, *backSector;
|
||||
linechain_t *thisElem, *nextElem;
|
||||
|
||||
if (!thisSector)
|
||||
return false;
|
||||
|
||||
nextElem = thisSector->sectorLines;
|
||||
|
||||
while (nextElem) // walk through chain
|
||||
{
|
||||
thisElem = nextElem;
|
||||
nextElem = thisElem->next;
|
||||
|
||||
frontSector = thisElem->line->frontsector;
|
||||
backSector = thisElem->line->backsector;
|
||||
|
||||
if (frontSector == thisSector)
|
||||
adjSector = backSector;
|
||||
else
|
||||
adjSector = frontSector;
|
||||
|
||||
if (!adjSector) // assume floating sectors have surrounding sectors
|
||||
return false;
|
||||
|
||||
#ifdef ESLOPE
|
||||
if (adjSector->c_slope) // Don't bother with slopes
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if (!refSector)
|
||||
{
|
||||
refSector = adjSector;
|
||||
continue;
|
||||
}
|
||||
|
||||
// if adjacent sector has same height or more than one adjacent sector exists -> stop
|
||||
if (thisSector->ceilingheight == adjSector->ceilingheight || refSector != adjSector)
|
||||
return false;
|
||||
}
|
||||
|
||||
// now check for walltextures
|
||||
if (!areToptexturesMissing(thisSector))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// check if no adjacent sector has same ceiling height
|
||||
// FIXME: throw that together with isCeilingFloating??
|
||||
//
|
||||
static boolean isFloorFloating(sector_t *thisSector)
|
||||
{
|
||||
sector_t *adjSector, *refSector = NULL, *frontSector, *backSector;
|
||||
linechain_t *thisElem, *nextElem;
|
||||
|
||||
if (!thisSector)
|
||||
return false;
|
||||
|
||||
nextElem = thisSector->sectorLines;
|
||||
|
||||
while (nextElem) // walk through chain
|
||||
{
|
||||
thisElem = nextElem;
|
||||
nextElem = thisElem->next;
|
||||
|
||||
frontSector = thisElem->line->frontsector;
|
||||
backSector = thisElem->line->backsector;
|
||||
|
||||
if (frontSector == thisSector)
|
||||
adjSector = backSector;
|
||||
else
|
||||
adjSector = frontSector;
|
||||
|
||||
if (!adjSector) // assume floating sectors have surrounding sectors
|
||||
return false;
|
||||
|
||||
#ifdef ESLOPE
|
||||
if (adjSector->f_slope) // Don't bother with slopes
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if (!refSector)
|
||||
{
|
||||
refSector = adjSector;
|
||||
continue;
|
||||
}
|
||||
|
||||
// if adjacent sector has same height or more than one adjacent sector exists -> stop
|
||||
if (thisSector->floorheight == adjSector->floorheight || refSector != adjSector)
|
||||
return false;
|
||||
}
|
||||
|
||||
// now check for walltextures
|
||||
if (!areBottomtexturesMissing(thisSector))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// estimate ceilingheight according to height of adjacent sector
|
||||
//
|
||||
static fixed_t estimateCeilHeight(sector_t *thisSector)
|
||||
{
|
||||
sector_t *adjSector;
|
||||
|
||||
if (!thisSector || !thisSector->sectorLines || !thisSector->sectorLines->line)
|
||||
return 0;
|
||||
|
||||
adjSector = thisSector->sectorLines->line->frontsector;
|
||||
if (adjSector == thisSector)
|
||||
adjSector = thisSector->sectorLines->line->backsector;
|
||||
|
||||
if (!adjSector)
|
||||
return 0;
|
||||
|
||||
return adjSector->ceilingheight;
|
||||
}
|
||||
|
||||
//
|
||||
// estimate ceilingheight according to height of adjacent sector
|
||||
//
|
||||
static fixed_t estimateFloorHeight(sector_t *thisSector)
|
||||
{
|
||||
sector_t *adjSector;
|
||||
|
||||
if (!thisSector || !thisSector->sectorLines || !thisSector->sectorLines->line)
|
||||
return 0;
|
||||
|
||||
adjSector = thisSector->sectorLines->line->frontsector;
|
||||
if (adjSector == thisSector)
|
||||
adjSector = thisSector->sectorLines->line->backsector;
|
||||
|
||||
if (!adjSector)
|
||||
return 0;
|
||||
|
||||
return adjSector->floorheight;
|
||||
}
|
||||
|
||||
#define CORRECT_FLOAT_EXPERIMENTAL
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Some levels have missing sidedefs, which produces HOM, so lets try to compensate for that
|
||||
// and some levels have deep water trick, invisible staircases etc.
|
||||
// --------------------------------------------------------------------------
|
||||
// FIXME: put some nice default texture in legacy.dat and use it
|
||||
void HWR_CorrectSWTricks(void)
|
||||
{
|
||||
size_t i;
|
||||
size_t k;
|
||||
line_t *ld;
|
||||
side_t *sidel = NULL, *sider;
|
||||
sector_t *secl, *secr;
|
||||
sector_t **sectorList;
|
||||
sector_t *outSector;
|
||||
|
||||
if ((0 == cv_grcorrecttricks.value))
|
||||
return;
|
||||
|
||||
// determine lines for sectors
|
||||
for (i = 0; i < numlines; i++)
|
||||
{
|
||||
ld = &lines[i];
|
||||
secr = ld->frontsector;
|
||||
secl = ld->backsector;
|
||||
|
||||
if (secr == secl)
|
||||
{
|
||||
secr->pseudoSector = true; // special renderer trick?
|
||||
addLineToChain(secr, ld);
|
||||
}
|
||||
else
|
||||
{
|
||||
addLineToChain(secr, ld);
|
||||
addLineToChain(secl, ld);
|
||||
}
|
||||
}
|
||||
|
||||
// preprocessing
|
||||
for (i = 0; i < numsectors; i++)
|
||||
{
|
||||
sector_t *checkSector;
|
||||
|
||||
checkSector = §ors[i];
|
||||
|
||||
// identify real pseudosectors first
|
||||
if (checkSector->pseudoSector)
|
||||
{
|
||||
if (!isPSectorValid(checkSector)) // drop invalid pseudo sectors
|
||||
{
|
||||
checkSector->pseudoSector = false;
|
||||
}
|
||||
}
|
||||
|
||||
// determine enclosing sectors for pseudosectors ... used later
|
||||
if (checkSector->pseudoSector)
|
||||
{
|
||||
generateStacklist(checkSector);
|
||||
calcLineouts(checkSector);
|
||||
sortStacklist(checkSector);
|
||||
}
|
||||
}
|
||||
|
||||
// set virtual floor heights for pseudo sectors
|
||||
// required for deep water effect e.g.
|
||||
for (i = 0; i < numsectors; i++)
|
||||
{
|
||||
if (sectors[i].pseudoSector)
|
||||
{
|
||||
sectorList = sectors[i].stackList;
|
||||
k = 0;
|
||||
while (*(sectorList+k))
|
||||
{
|
||||
outSector = *(sectorList+k);
|
||||
if (!outSector->pseudoSector)
|
||||
{
|
||||
sectors[i].virtualFloorheight = outSector->floorheight;
|
||||
sectors[i].virtualCeilingheight = outSector->ceilingheight;
|
||||
break;
|
||||
}
|
||||
k++;
|
||||
}
|
||||
if (*(sectorList+k) == NULL) // sorry, did not work :(
|
||||
{
|
||||
sectors[i].virtualFloorheight = sectors[i].floorheight;
|
||||
sectors[i].virtualCeilingheight = sectors[i].ceilingheight;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef CORRECT_FLOAT_EXPERIMENTAL
|
||||
// correct ceiling/floor heights of totally floating sectors
|
||||
for (i = 0; i < numsectors; i++)
|
||||
{
|
||||
sector_t *floatSector;
|
||||
|
||||
floatSector = §ors[i];
|
||||
|
||||
// correct height of floating sectors
|
||||
if (isCeilingFloating(floatSector))
|
||||
{
|
||||
floatSector->virtualCeilingheight = estimateCeilHeight(floatSector);
|
||||
floatSector->virtualCeiling = true;
|
||||
}
|
||||
if (isFloorFloating(floatSector))
|
||||
{
|
||||
floatSector->virtualFloorheight = estimateFloorHeight(floatSector);
|
||||
floatSector->virtualFloor = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// now for the missing textures
|
||||
for (i = 0; i < numlines; i++)
|
||||
{
|
||||
ld = &lines[i];
|
||||
sider = &sides[ld->sidenum[0]];
|
||||
if (ld->sidenum[1] != 0xffff)
|
||||
sidel = &sides[ld->sidenum[1]];
|
||||
|
||||
secr = ld->frontsector;
|
||||
secl = ld->backsector;
|
||||
|
||||
if (secr == secl) // special renderer trick
|
||||
continue; // we cant correct missing textures here
|
||||
|
||||
if (secl) // only if there is a backsector
|
||||
{
|
||||
if (secr->pseudoSector || secl->pseudoSector)
|
||||
continue;
|
||||
if (!secr->virtualFloor && !secl->virtualFloor)
|
||||
{
|
||||
if (secl->floorheight > secr->floorheight)
|
||||
{
|
||||
// now check if r-sidedef is correct
|
||||
if (sider->bottomtexture == 0)
|
||||
{
|
||||
if (sider->midtexture == 0)
|
||||
sider->bottomtexture = 0; // Tails // More redwall sky shenanigans
|
||||
else
|
||||
sider->bottomtexture = sider->midtexture;
|
||||
}
|
||||
}
|
||||
else if (secl->floorheight < secr->floorheight)
|
||||
{
|
||||
// now check if l-sidedef is correct
|
||||
if (sidel->bottomtexture == 0)
|
||||
{
|
||||
if (sidel->midtexture == 0)
|
||||
sidel->bottomtexture = 0; // Tails // More redwall sky shenanigans
|
||||
else
|
||||
sidel->bottomtexture = sidel->midtexture;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!secr->virtualCeiling && !secl->virtualCeiling)
|
||||
{
|
||||
if (secl->ceilingheight < secr->ceilingheight)
|
||||
{
|
||||
// now check if r-sidedef is correct
|
||||
if (sider->toptexture == 0)
|
||||
{
|
||||
if (sider->midtexture == 0)
|
||||
sider->toptexture = 0; // Tails // When this was REDWALL it was causing issues in the sky sometimes
|
||||
else
|
||||
sider->toptexture = sider->midtexture;
|
||||
}
|
||||
}
|
||||
else if (secl->ceilingheight > secr->ceilingheight)
|
||||
{
|
||||
// now check if l-sidedef is correct
|
||||
if (sidel->toptexture == 0)
|
||||
{
|
||||
if (sidel->midtexture == 0)
|
||||
sidel->toptexture = 0; // Tails // When this was REDWALL it was causing issues in the sky sometimes
|
||||
else
|
||||
sidel->toptexture = sidel->midtexture;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // if (NULL != secl)
|
||||
} // for (i = 0; i < numlines; i++)
|
||||
|
||||
// release all linechains
|
||||
releaseLineChains();
|
||||
freeStacklists();
|
||||
}
|
||||
|
||||
#endif // HWRENDER
|
||||
@@ -556,18 +556,12 @@ EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl)
|
||||
// -----------------+
|
||||
EXPORT void HWRAPI(SetPalette) (RGBA_t *pal)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
myPaletteData[i].s.red = pal[i].s.red;
|
||||
myPaletteData[i].s.green = pal[i].s.green;
|
||||
myPaletteData[i].s.blue = pal[i].s.blue;
|
||||
myPaletteData[i].s.alpha = pal[i].s.alpha;
|
||||
}
|
||||
|
||||
size_t palsize = (sizeof(RGBA_t) * 256);
|
||||
// on a palette change, you have to reload all of the textures
|
||||
Flush();
|
||||
if (memcmp(&myPaletteData, pal, palsize))
|
||||
{
|
||||
memcpy(&myPaletteData, pal, palsize);
|
||||
Flush();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+318
-195
@@ -8,7 +8,7 @@
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file
|
||||
/// \file r_opengl.c
|
||||
/// \brief OpenGL API for Sonic Robo Blast 2
|
||||
|
||||
#if defined (_WIN32)
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "../../r_local.h" // For rendertimefrac, used for the leveltime shader uniform
|
||||
#include "r_opengl.h"
|
||||
#include "r_vbo.h"
|
||||
|
||||
#include "../hw_shaders.h"
|
||||
#include "../hw_main.h"
|
||||
|
||||
// Eeeeh not sure is this right way, but it works < sry :c < sry again it had to go :c
|
||||
@@ -78,8 +78,9 @@ static GLuint lt_downloaded = 0; // currently bound lighttable texture
|
||||
static GLfloat fov = 90.0f;
|
||||
static FBITFIELD CurrentPolyFlags;
|
||||
|
||||
static FTextureInfo *gr_cachetail = NULL;
|
||||
static FTextureInfo *gr_cachehead = NULL;
|
||||
// Linked list of all textures.
|
||||
static FTextureInfo *TexCacheTail = NULL;
|
||||
static FTextureInfo *TexCacheHead = NULL;
|
||||
|
||||
static RGBA_t *textureBuffer = NULL;
|
||||
static size_t textureBufferSize = 0;
|
||||
@@ -113,6 +114,11 @@ static GLfloat modelMatrix[16];
|
||||
static GLfloat projMatrix[16];
|
||||
static GLint viewport[4];
|
||||
|
||||
static boolean GLFramebuffer_IsFuncAvailible(void);
|
||||
|
||||
|
||||
GLuint FramebufferObject, FramebufferTexture, RenderbufferObject;
|
||||
GLboolean FrameBufferEnabled = GL_FALSE, RenderToFramebuffer = GL_FALSE;
|
||||
|
||||
// Sryder: NextTexAvail is broken for these because palette changes or changes to the texture filter or antialiasing
|
||||
// flush all of the stored textures, leaving them unavailable at times such as between levels
|
||||
@@ -425,12 +431,32 @@ typedef void (APIENTRY * PFNglCopyTexImage2D) (GLenum target, GLint level, GLenu
|
||||
static PFNglCopyTexImage2D pglCopyTexImage2D;
|
||||
typedef void (APIENTRY * PFNglCopyTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
static PFNglCopyTexSubImage2D pglCopyTexSubImage2D;
|
||||
#endif
|
||||
|
||||
/* 3.0 functions */
|
||||
#ifdef GL_VERSION_3_0
|
||||
typedef void (APIENTRY * PFNglGenerateMipmap) (GLenum target);
|
||||
static PFNglGenerateMipmap pglGenerateMipmap;
|
||||
|
||||
/* 3.0 functions for framebuffers and renderbuffers */
|
||||
typedef void (APIENTRY * PFNglGenFramebuffers) (GLsizei n, GLuint *ids);
|
||||
static PFNglGenFramebuffers pglGenFramebuffers;
|
||||
typedef void (APIENTRY * PFNglBindFramebuffer) (GLenum target, GLuint framebuffer);
|
||||
static PFNglBindFramebuffer pglBindFramebuffer;
|
||||
typedef void (APIENTRY * PFNglDeleteFramebuffers) (GLsizei n, GLuint *ids);
|
||||
static PFNglDeleteFramebuffers pglDeleteFramebuffers;
|
||||
typedef void (APIENTRY * PFNglFramebufferTexture2D) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
|
||||
static PFNglFramebufferTexture2D pglFramebufferTexture2D;
|
||||
typedef GLenum (APIENTRY * PFNglCheckFramebufferStatus) (GLenum target);
|
||||
static PFNglCheckFramebufferStatus pglCheckFramebufferStatus;
|
||||
typedef void (APIENTRY * PFNglGenRenderbuffers) (GLsizei n, GLuint *renderbuffers);
|
||||
static PFNglGenRenderbuffers pglGenRenderbuffers;
|
||||
typedef void (APIENTRY * PFNglBindRenderbuffer) (GLenum target, GLuint renderbuffer);
|
||||
static PFNglBindRenderbuffer pglBindRenderbuffer;
|
||||
typedef void (APIENTRY * PFNglDeleteRenderbuffers) (GLsizei n, GLuint *renderbuffers);
|
||||
static PFNglDeleteRenderbuffers pglDeleteRenderbuffers;
|
||||
typedef void (APIENTRY * PFNglRenderbufferStorage) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
|
||||
static PFNglRenderbufferStorage pglRenderbufferStorage;
|
||||
typedef void (APIENTRY * PFNglFramebufferRenderbuffer) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLenum renderbuffer);
|
||||
static PFNglFramebufferRenderbuffer pglFramebufferRenderbuffer;
|
||||
#endif
|
||||
|
||||
/* 1.2 functions for 3D textures */
|
||||
@@ -567,7 +593,6 @@ static PFNglStencilFuncSeparate pglStencilFuncSeparate;
|
||||
typedef void (APIENTRY *PFNglStencilOpSeparate) (GLenum, GLenum, GLenum, GLenum);
|
||||
static PFNglStencilOpSeparate pglStencilOpSeparate;
|
||||
|
||||
#ifdef GL_SHADERS
|
||||
typedef GLuint (APIENTRY *PFNglCreateShader) (GLenum);
|
||||
typedef void (APIENTRY *PFNglShaderSource) (GLuint, GLsizei, const GLchar**, GLint*);
|
||||
typedef void (APIENTRY *PFNglCompileShader) (GLuint);
|
||||
@@ -674,31 +699,6 @@ static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAF
|
||||
|
||||
static GLRGBAFloat shader_defaultcolor = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
|
||||
//
|
||||
// Generic vertex shader
|
||||
//
|
||||
|
||||
#define GLSL_FALLBACK_VERTEX_SHADER \
|
||||
"void main()\n" \
|
||||
"{\n" \
|
||||
"gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\n" \
|
||||
"gl_FrontColor = gl_Color;\n" \
|
||||
"gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;\n" \
|
||||
"gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \
|
||||
"}\0"
|
||||
|
||||
//
|
||||
// Generic fragment shader
|
||||
//
|
||||
|
||||
#define GLSL_FALLBACK_FRAGMENT_SHADER \
|
||||
"uniform sampler2D tex;\n" \
|
||||
"uniform vec4 poly_color;\n" \
|
||||
"void main(void) {\n" \
|
||||
"gl_FragColor = texture2D(tex, gl_TexCoord[0].st) * poly_color;\n" \
|
||||
"}\0"
|
||||
|
||||
#endif // GL_SHADERS
|
||||
|
||||
void SetupGLFunc4(void)
|
||||
{
|
||||
@@ -720,7 +720,6 @@ void SetupGLFunc4(void)
|
||||
pglStencilFuncSeparate = GetGLFunc("glStencilFuncSeparate");
|
||||
pglStencilOpSeparate = GetGLFunc("glStencilOpSeparate");
|
||||
|
||||
#ifdef GL_SHADERS
|
||||
pglCreateShader = GetGLFunc("glCreateShader");
|
||||
pglShaderSource = GetGLFunc("glShaderSource");
|
||||
pglCompileShader = GetGLFunc("glCompileShader");
|
||||
@@ -742,19 +741,36 @@ void SetupGLFunc4(void)
|
||||
pglUniform2fv = GetGLFunc("glUniform2fv");
|
||||
pglUniform3fv = GetGLFunc("glUniform3fv");
|
||||
pglGetUniformLocation = GetGLFunc("glGetUniformLocation");
|
||||
#endif
|
||||
|
||||
#ifdef GL_VERSION_3_0
|
||||
pglGenerateMipmap = GetGLFunc("glGenerateMipmap");
|
||||
#endif
|
||||
|
||||
if (GLFramebuffer_IsFuncAvailible())
|
||||
{
|
||||
pglGenFramebuffers = GetGLFunc("glGenFramebuffers");
|
||||
pglBindFramebuffer = GetGLFunc("glBindFramebuffer");
|
||||
pglDeleteFramebuffers = GetGLFunc("glDeleteFramebuffers");
|
||||
pglFramebufferTexture2D = GetGLFunc("glFramebufferTexture2D");
|
||||
pglCheckFramebufferStatus = GetGLFunc("glCheckFramebufferStatus");
|
||||
pglGenRenderbuffers = GetGLFunc("glGenRenderbuffers");
|
||||
pglBindRenderbuffer = GetGLFunc("glBindRenderbuffer");
|
||||
pglDeleteRenderbuffers = GetGLFunc("glDeleteRenderbuffers");
|
||||
pglRenderbufferStorage = GetGLFunc("glRenderbufferStorage");
|
||||
pglFramebufferRenderbuffer = GetGLFunc("glFramebufferRenderbuffer");
|
||||
}
|
||||
}
|
||||
|
||||
static boolean GLFramebuffer_IsFuncAvailible(void)
|
||||
{
|
||||
return((isExtAvailable("GL_ARB_framebuffer_no_attachments",gl_extensions)) &&
|
||||
(isExtAvailable("GL_ARB_framebuffer_object",gl_extensions)) &&
|
||||
(isExtAvailable("GL_ARB_framebuffer_sRGB",gl_extensions)));
|
||||
}
|
||||
|
||||
EXPORT boolean HWRAPI(InitShaders) (void)
|
||||
{
|
||||
#ifdef GL_SHADERS
|
||||
if (!pglUseProgram)
|
||||
return false;
|
||||
|
||||
|
||||
gl_fallback_shader.vertex_shader = Z_StrDup(GLSL_FALLBACK_VERTEX_SHADER);
|
||||
gl_fallback_shader.fragment_shader = Z_StrDup(GLSL_FALLBACK_FRAGMENT_SHADER);
|
||||
|
||||
@@ -765,14 +781,10 @@ EXPORT boolean HWRAPI(InitShaders) (void)
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
EXPORT void HWRAPI(LoadShader) (int slot, char *code, hwdshaderstage_t stage)
|
||||
{
|
||||
#ifdef GL_SHADERS
|
||||
gl_shader_t *shader;
|
||||
|
||||
if (slot < 0 || slot >= HWR_MAXSHADERS)
|
||||
@@ -794,16 +806,10 @@ EXPORT void HWRAPI(LoadShader) (int slot, char *code, hwdshaderstage_t stage)
|
||||
I_Error("LoadShader: invalid shader stage");
|
||||
|
||||
#undef LOADSHADER
|
||||
#else
|
||||
(void)slot;
|
||||
(void)code;
|
||||
(void)stage;
|
||||
#endif
|
||||
}
|
||||
|
||||
EXPORT boolean HWRAPI(CompileShader) (int slot)
|
||||
{
|
||||
#ifdef GL_SHADERS
|
||||
if (slot < 0 || slot >= HWR_MAXSHADERS)
|
||||
I_Error("CompileShader: Invalid slot %d", slot);
|
||||
|
||||
@@ -816,10 +822,6 @@ EXPORT boolean HWRAPI(CompileShader) (int slot)
|
||||
gl_shaders[slot].program = 0;
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
(void)slot;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
@@ -829,7 +831,6 @@ EXPORT boolean HWRAPI(CompileShader) (int slot)
|
||||
|
||||
EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value)
|
||||
{
|
||||
#ifdef GL_SHADERS
|
||||
switch (info)
|
||||
{
|
||||
case HWD_SHADERINFO_LEVELTIME:
|
||||
@@ -838,15 +839,15 @@ EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#else
|
||||
(void)info;
|
||||
(void)value;
|
||||
#endif
|
||||
}
|
||||
|
||||
EXPORT void HWRAPI(SetShader) (int slot)
|
||||
{
|
||||
#ifdef GL_SHADERS
|
||||
if (slot == SHADER_NONE)
|
||||
{
|
||||
UnSetShader();
|
||||
return;
|
||||
}
|
||||
if (gl_allowshaders)
|
||||
{
|
||||
gl_shader_t *next_shader = &gl_shaders[slot]; // the gl_shader_t we are going to switch to
|
||||
@@ -867,26 +868,26 @@ EXPORT void HWRAPI(SetShader) (int slot)
|
||||
|
||||
return;
|
||||
}
|
||||
#else
|
||||
(void)slot;
|
||||
#endif
|
||||
|
||||
gl_shadersenabled = false;
|
||||
}
|
||||
|
||||
EXPORT void HWRAPI(UnSetShader) (void)
|
||||
{
|
||||
#ifdef GL_SHADERS
|
||||
gl_shaderstate.current = NULL;
|
||||
gl_shaderstate.type = 0;
|
||||
gl_shaderstate.program = 0;
|
||||
if (gl_shadersenabled) // don't repeatedly call glUseProgram if not needed
|
||||
{
|
||||
gl_shaderstate.current = NULL;
|
||||
gl_shaderstate.type = 0;
|
||||
gl_shaderstate.program = 0;
|
||||
|
||||
if (pglUseProgram)
|
||||
pglUseProgram(0);
|
||||
#endif
|
||||
if (pglUseProgram)
|
||||
pglUseProgram(0);
|
||||
}
|
||||
|
||||
gl_shadersenabled = false;
|
||||
}
|
||||
|
||||
|
||||
// -----------------+
|
||||
// SetNoTexture : Disable texture
|
||||
// -----------------+
|
||||
@@ -914,7 +915,7 @@ static void GLPerspective(GLfloat fovy, GLfloat aspect)
|
||||
const GLfloat zNear = NEAR_CLIPPING_PLANE;
|
||||
const GLfloat zFar = FAR_CLIPPING_PLANE;
|
||||
const GLfloat radians = (GLfloat)(fovy / 2.0f * M_PIl / 180.0f);
|
||||
const GLfloat sine = sin(radians);
|
||||
const GLfloat sine = (GLfloat)sin(radians);
|
||||
const GLfloat deltaZ = zFar - zNear;
|
||||
GLfloat cotangent;
|
||||
|
||||
@@ -938,13 +939,6 @@ void SetModelView(GLint w, GLint h)
|
||||
{
|
||||
//GL_DBG_Printf("SetModelView(): %dx%d\n", (int)w, (int)h);
|
||||
|
||||
// The screen textures need to be flushed if the width or height change so that they be remade for the correct size
|
||||
if (screen_width != w || screen_height != h)
|
||||
FlushScreenTextures();
|
||||
|
||||
screen_width = w;
|
||||
screen_height = h;
|
||||
|
||||
pglViewport(0, 0, w, h);
|
||||
|
||||
pglMatrixMode(GL_PROJECTION);
|
||||
@@ -976,7 +970,7 @@ void SetStates(void)
|
||||
|
||||
pglEnable(GL_STENCIL_TEST);
|
||||
pglEnable(GL_DEPTH_TEST); // check the depth buffer
|
||||
pglDepthMask(GL_TRUE); // enable writing to depth buffer
|
||||
pglDepthMask(GL_TRUE); // enable writing to depth buffer
|
||||
pglClearDepth(1.0f);
|
||||
pglDepthRange(0.0f, 1.0f);
|
||||
pglDepthFunc(GL_LEQUAL);
|
||||
@@ -996,27 +990,180 @@ void SetStates(void)
|
||||
pglGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix); // added for new coronas' code (without depth buffer)
|
||||
}
|
||||
|
||||
void GLFramebuffer_Generate(void)
|
||||
{
|
||||
if (!GLFramebuffer_IsFuncAvailible())
|
||||
return;
|
||||
|
||||
// Generate the framebuffer
|
||||
if (FramebufferObject == 0)
|
||||
pglGenFramebuffers(1, &FramebufferObject);
|
||||
|
||||
if (pglCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE)
|
||||
GLFramebuffer_GenerateAttachments();
|
||||
}
|
||||
|
||||
void GLFramebuffer_Delete(void)
|
||||
{
|
||||
if (!GLFramebuffer_IsFuncAvailible())
|
||||
return;
|
||||
|
||||
// Unbind the framebuffer
|
||||
pglBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
if (FramebufferObject)
|
||||
pglDeleteFramebuffers(1, &FramebufferObject);
|
||||
|
||||
GLFramebuffer_DeleteAttachments();
|
||||
FramebufferObject = 0;
|
||||
}
|
||||
|
||||
void GLFramebuffer_GenerateAttachments(void)
|
||||
{
|
||||
if (!GLFramebuffer_IsFuncAvailible())
|
||||
return;
|
||||
|
||||
// Bind the framebuffer
|
||||
pglBindFramebuffer(GL_FRAMEBUFFER, FramebufferObject);
|
||||
|
||||
// Generate the framebuffer texture
|
||||
if (FramebufferTexture == 0)
|
||||
{
|
||||
pglGenTextures(1, &FramebufferTexture);
|
||||
pglBindTexture(GL_TEXTURE_2D, FramebufferTexture);
|
||||
pglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, screen_width, screen_height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
pglBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
// Attach the framebuffer texture to the framebuffer
|
||||
pglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, FramebufferTexture, 0);
|
||||
}
|
||||
|
||||
// Generate the renderbuffer
|
||||
if (RenderbufferObject == 0)
|
||||
{
|
||||
pglGenRenderbuffers(1, &RenderbufferObject);
|
||||
|
||||
pglBindRenderbuffer(GL_RENDERBUFFER, RenderbufferObject);
|
||||
pglRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, screen_width, screen_height);
|
||||
pglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, RenderbufferObject);
|
||||
|
||||
// Clear the renderbuffer
|
||||
ClearBuffer(true, true, true, NULL);
|
||||
|
||||
pglBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
}
|
||||
|
||||
// Unbind the framebuffer
|
||||
pglBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void GLFramebuffer_DeleteAttachments(void)
|
||||
{
|
||||
if (!GLFramebuffer_IsFuncAvailible())
|
||||
return;
|
||||
|
||||
// Unbind the framebuffer
|
||||
pglBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
if (FramebufferTexture)
|
||||
pglDeleteTextures(1, &FramebufferTexture);
|
||||
|
||||
if (RenderbufferObject)
|
||||
pglDeleteRenderbuffers(1, &RenderbufferObject);
|
||||
|
||||
FramebufferTexture = 0;
|
||||
RenderbufferObject = 0;
|
||||
}
|
||||
|
||||
void GLFramebuffer_Enable(void)
|
||||
{
|
||||
if (!GLFramebuffer_IsFuncAvailible())
|
||||
return;
|
||||
|
||||
if (FramebufferObject == 0)
|
||||
GLFramebuffer_Generate();
|
||||
else if (FramebufferTexture == 0 || RenderbufferObject == 0)
|
||||
GLFramebuffer_GenerateAttachments();
|
||||
|
||||
pglBindFramebuffer(GL_FRAMEBUFFER, FramebufferObject);
|
||||
pglBindRenderbuffer(GL_RENDERBUFFER, RenderbufferObject);
|
||||
}
|
||||
|
||||
void GLFramebuffer_Disable(void)
|
||||
{
|
||||
if (!GLFramebuffer_IsFuncAvailible())
|
||||
return;
|
||||
|
||||
pglBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
pglBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
}
|
||||
|
||||
// -----------------+
|
||||
// DeleteTexture : Deletes a texture from the GPU and frees its data
|
||||
// -----------------+
|
||||
EXPORT void HWRAPI(DeleteTexture) (GLMipmap_t *pTexInfo)
|
||||
{
|
||||
FTextureInfo *head = TexCacheHead;
|
||||
|
||||
if (!pTexInfo)
|
||||
return;
|
||||
else if (pTexInfo->downloaded)
|
||||
pglDeleteTextures(1, (GLuint *)&pTexInfo->downloaded);
|
||||
|
||||
while (head)
|
||||
{
|
||||
if (head->downloaded == pTexInfo->downloaded)
|
||||
{
|
||||
if (head->next)
|
||||
head->next->prev = head->prev;
|
||||
else // no next -> tail is being deleted -> update TexCacheTail
|
||||
TexCacheTail = head->prev;
|
||||
if (head->prev)
|
||||
head->prev->next = head->next;
|
||||
else // no prev -> head is being deleted -> update TexCacheHead
|
||||
TexCacheHead = head->next;
|
||||
free(head);
|
||||
break;
|
||||
}
|
||||
|
||||
head = head->next;
|
||||
}
|
||||
|
||||
pTexInfo->downloaded = 0;
|
||||
}
|
||||
|
||||
|
||||
// -----------------+
|
||||
// Flush : flush OpenGL textures
|
||||
// : Clear list of downloaded mipmaps
|
||||
// -----------------+
|
||||
void Flush(void)
|
||||
{
|
||||
//GL_DBG_Printf("HWR_Flush()\n");
|
||||
//GL_DBG_Printf ("HWR_Flush()\n");
|
||||
|
||||
while (gr_cachehead)
|
||||
while (TexCacheHead)
|
||||
{
|
||||
// this is not necessary at all, because you have loaded them normally,
|
||||
// and so they already are in your list!
|
||||
if (gr_cachehead->downloaded)
|
||||
pglDeleteTextures(1, (GLuint *)&gr_cachehead->downloaded);
|
||||
gr_cachehead->downloaded = 0;
|
||||
gr_cachehead = gr_cachehead->nextmipmap;
|
||||
}
|
||||
gr_cachetail = gr_cachehead = NULL; //Hurdler: well, gr_cachehead is already NULL
|
||||
FTextureInfo *pTexInfo = TexCacheHead;
|
||||
GLMipmap_t *texture = pTexInfo->texture;
|
||||
|
||||
if (pTexInfo->downloaded)
|
||||
{
|
||||
pglDeleteTextures(1, (GLuint *)&pTexInfo->downloaded);
|
||||
pTexInfo->downloaded = 0;
|
||||
}
|
||||
|
||||
if (texture)
|
||||
texture->downloaded = 0;
|
||||
|
||||
TexCacheHead = pTexInfo->next;
|
||||
free(pTexInfo);
|
||||
}
|
||||
|
||||
TexCacheTail = TexCacheHead = NULL; //Hurdler: well, TexCacheHead is already NULL
|
||||
tex_downloaded = 0;
|
||||
|
||||
|
||||
free(textureBuffer);
|
||||
textureBuffer = NULL;
|
||||
textureBufferSize = 0;
|
||||
@@ -1375,7 +1522,7 @@ static void AllocTextureBuffer(GLMipmap_t *pTexInfo)
|
||||
// -----------------+
|
||||
// UpdateTexture : Updates texture data.
|
||||
// -----------------+
|
||||
EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo)
|
||||
EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo)
|
||||
{
|
||||
// Upload a texture
|
||||
GLuint num = pTexInfo->downloaded;
|
||||
@@ -1387,7 +1534,7 @@ EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo)
|
||||
const GLubyte *pImgData = (const GLubyte *)pTexInfo->data;
|
||||
const GLvoid *ptex = NULL;
|
||||
RGBA_t *tex = NULL;
|
||||
|
||||
|
||||
// Generate a new texture name.
|
||||
if (!num)
|
||||
{
|
||||
@@ -1432,7 +1579,6 @@ EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo)
|
||||
tex[w*j+i].s.alpha = *pImgData;
|
||||
pImgData++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1499,23 +1645,15 @@ EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo)
|
||||
//pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
|
||||
if (MipMap)
|
||||
{
|
||||
if ((majorGL == 1 && minorGL >= 4) || (majorGL == 2))
|
||||
{
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
|
||||
pglTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
|
||||
}
|
||||
#ifdef GL_VERSION_3_0
|
||||
else if (majorGL >= 3)
|
||||
{
|
||||
pglTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
|
||||
pglGenerateMipmap(GL_TEXTURE_2D);
|
||||
}
|
||||
#endif
|
||||
|
||||
pglTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
|
||||
pglGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0);
|
||||
if (pTexInfo->flags & TF_TRANSPARENT)
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff
|
||||
else
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 16);
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4);
|
||||
//pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_LINEAR_MIPMAP_LINEAR);
|
||||
}
|
||||
else
|
||||
@@ -1531,23 +1669,14 @@ EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo)
|
||||
//pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
|
||||
if (MipMap)
|
||||
{
|
||||
if ((majorGL == 1 && minorGL >= 4) || (majorGL == 2))
|
||||
{
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
|
||||
pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
|
||||
}
|
||||
#ifdef GL_VERSION_3_0
|
||||
else if (majorGL >= 3)
|
||||
{
|
||||
pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
|
||||
pglGenerateMipmap(GL_TEXTURE_2D);
|
||||
}
|
||||
#endif
|
||||
pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
|
||||
pglGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0);
|
||||
if (pTexInfo->flags & TF_TRANSPARENT)
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff
|
||||
else
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 16);
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4);
|
||||
//pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_LINEAR_MIPMAP_LINEAR);
|
||||
}
|
||||
else
|
||||
@@ -1562,24 +1691,15 @@ EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo)
|
||||
{
|
||||
if (MipMap)
|
||||
{
|
||||
if ((majorGL == 1 && minorGL >= 4) || (majorGL == 2))
|
||||
{
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
|
||||
pglTexImage2D(GL_TEXTURE_2D, 0, textureformatGL, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
|
||||
}
|
||||
#ifdef GL_VERSION_3_0
|
||||
else if (majorGL >= 3)
|
||||
{
|
||||
pglTexImage2D(GL_TEXTURE_2D, 0, textureformatGL, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
|
||||
pglGenerateMipmap(GL_TEXTURE_2D);
|
||||
}
|
||||
#endif
|
||||
pglTexImage2D(GL_TEXTURE_2D, 0, textureformatGL, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
|
||||
pglGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
// Control the mipmap level of detail
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); // the lower the number, the higer the detail
|
||||
if (pTexInfo->flags & TF_TRANSPARENT)
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff
|
||||
else
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 16);
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 5);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1608,7 +1728,7 @@ EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo)
|
||||
// -----------------+
|
||||
// SetTexture : The mipmap becomes the current texture source
|
||||
// -----------------+
|
||||
EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo)
|
||||
EXPORT void HWRAPI(SetTexture) (GLMipmap_t *pTexInfo)
|
||||
{
|
||||
if (!pTexInfo)
|
||||
{
|
||||
@@ -1625,21 +1745,30 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo)
|
||||
}
|
||||
else
|
||||
{
|
||||
FTextureInfo *newTex = calloc(1, sizeof (*newTex));
|
||||
|
||||
UpdateTexture(pTexInfo);
|
||||
pTexInfo->nextmipmap = NULL;
|
||||
if (gr_cachetail)
|
||||
{ // insertion at the tail
|
||||
gr_cachetail->nextmipmap = pTexInfo;
|
||||
gr_cachetail = pTexInfo;
|
||||
|
||||
newTex->texture = pTexInfo;
|
||||
newTex->downloaded = (UINT32)pTexInfo->downloaded;
|
||||
newTex->width = (UINT32)pTexInfo->width;
|
||||
newTex->height = (UINT32)pTexInfo->height;
|
||||
newTex->format = (UINT32)pTexInfo->format;
|
||||
|
||||
// insertion at the tail
|
||||
if (TexCacheTail)
|
||||
{
|
||||
newTex->prev = TexCacheTail;
|
||||
TexCacheTail->next = newTex;
|
||||
TexCacheTail = newTex;
|
||||
}
|
||||
else // initialization of the linked list
|
||||
gr_cachetail = gr_cachehead = pTexInfo;
|
||||
TexCacheTail = TexCacheHead = newTex;
|
||||
}
|
||||
}
|
||||
|
||||
static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat *tint, GLRGBAFloat *fade)
|
||||
{
|
||||
#ifdef GL_SHADERS
|
||||
gl_shader_t *shader = gl_shaderstate.current;
|
||||
|
||||
if (gl_shadersenabled && (shader != NULL) && pglUseProgram)
|
||||
@@ -1687,9 +1816,9 @@ static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAF
|
||||
|
||||
if (Surface != NULL)
|
||||
{
|
||||
UNIFORM_1(shader->uniforms[gluniform_lighting], Surface->LightInfo.light_level, pglUniform1f);
|
||||
UNIFORM_1(shader->uniforms[gluniform_fade_start], Surface->LightInfo.fade_start, pglUniform1f);
|
||||
UNIFORM_1(shader->uniforms[gluniform_fade_end], Surface->LightInfo.fade_end, pglUniform1f);
|
||||
UNIFORM_1(shader->uniforms[gluniform_lighting], (GLfloat)Surface->LightInfo.light_level, pglUniform1f);
|
||||
UNIFORM_1(shader->uniforms[gluniform_fade_start], (GLfloat)Surface->LightInfo.fade_start, pglUniform1f);
|
||||
UNIFORM_1(shader->uniforms[gluniform_fade_end], (GLfloat)Surface->LightInfo.fade_end, pglUniform1f);
|
||||
}
|
||||
|
||||
UNIFORM_1(shader->uniforms[gluniform_leveltime], ((float)shader_leveltime) / TICRATE, pglUniform1f);
|
||||
@@ -1699,12 +1828,6 @@ static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAF
|
||||
#undef UNIFORM_3
|
||||
#undef UNIFORM_4
|
||||
}
|
||||
#else
|
||||
(void)Surface;
|
||||
(void)poly;
|
||||
(void)tint;
|
||||
(void)fade;
|
||||
#endif
|
||||
}
|
||||
|
||||
static boolean Shader_CompileProgram(gl_shader_t *shader, GLint i)
|
||||
@@ -1843,7 +1966,7 @@ static boolean Shader_CompileProgram(gl_shader_t *shader, GLint i)
|
||||
// code that is common between DrawPolygon and DrawIndexedTriangles
|
||||
// DrawScreenTexture also can use this function for fancier screen texture drawing
|
||||
// the corona thing is there too, i have no idea if that stuff works with DrawIndexedTriangles and batching
|
||||
static void PreparePolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FBITFIELD PolyFlags)
|
||||
static void PreparePolygon(FSurfaceInfo *pSurf, FBITFIELD PolyFlags)
|
||||
{
|
||||
static GLRGBAFloat poly = {0,0,0,0};
|
||||
static GLRGBAFloat tint = {0,0,0,0};
|
||||
@@ -1851,39 +1974,41 @@ static void PreparePolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FBITFIELD
|
||||
|
||||
SetBlend(PolyFlags); //TODO: inline (#pragma..)
|
||||
|
||||
// PolyColor
|
||||
if (pSurf)
|
||||
{
|
||||
// If Modulated, mix the surface colour to the texture
|
||||
// If modulated, mix the surface colour to the texture
|
||||
if (CurrentPolyFlags & PF_Modulated)
|
||||
{
|
||||
// Poly color
|
||||
poly.red = byte2float[pSurf->PolyColor.s.red];
|
||||
poly.green = byte2float[pSurf->PolyColor.s.green];
|
||||
poly.blue = byte2float[pSurf->PolyColor.s.blue];
|
||||
poly.alpha = byte2float[pSurf->PolyColor.s.alpha];
|
||||
|
||||
pglColor4ubv((GLubyte*)&pSurf->PolyColor.s);
|
||||
|
||||
// If the surface is either modulated or colormapped, or both
|
||||
if (CurrentPolyFlags & (PF_Modulated | PF_ColorMapped))
|
||||
{
|
||||
poly.red = byte2float[pSurf->PolyColor.s.red];
|
||||
poly.green = byte2float[pSurf->PolyColor.s.green];
|
||||
poly.blue = byte2float[pSurf->PolyColor.s.blue];
|
||||
poly.alpha = byte2float[pSurf->PolyColor.s.alpha];
|
||||
}
|
||||
|
||||
// Tint color
|
||||
tint.red = byte2float[pSurf->TintColor.s.red];
|
||||
tint.green = byte2float[pSurf->TintColor.s.green];
|
||||
tint.blue = byte2float[pSurf->TintColor.s.blue];
|
||||
tint.alpha = byte2float[pSurf->TintColor.s.alpha];
|
||||
|
||||
// Fade color
|
||||
fade.red = byte2float[pSurf->FadeColor.s.red];
|
||||
fade.green = byte2float[pSurf->FadeColor.s.green];
|
||||
fade.blue = byte2float[pSurf->FadeColor.s.blue];
|
||||
fade.alpha = byte2float[pSurf->FadeColor.s.alpha];
|
||||
|
||||
if (pSurf->LightTableId && pSurf->LightTableId != lt_downloaded)
|
||||
// Only if the surface is colormapped
|
||||
if (CurrentPolyFlags & PF_ColorMapped)
|
||||
{
|
||||
pglActiveTexture(GL_TEXTURE2);
|
||||
pglBindTexture(GL_TEXTURE_2D, pSurf->LightTableId);
|
||||
pglActiveTexture(GL_TEXTURE0);
|
||||
lt_downloaded = pSurf->LightTableId;
|
||||
tint.red = byte2float[pSurf->TintColor.s.red];
|
||||
tint.green = byte2float[pSurf->TintColor.s.green];
|
||||
tint.blue = byte2float[pSurf->TintColor.s.blue];
|
||||
tint.alpha = byte2float[pSurf->TintColor.s.alpha];
|
||||
|
||||
fade.red = byte2float[pSurf->FadeColor.s.red];
|
||||
fade.green = byte2float[pSurf->FadeColor.s.green];
|
||||
fade.blue = byte2float[pSurf->FadeColor.s.blue];
|
||||
fade.alpha = byte2float[pSurf->FadeColor.s.alpha];
|
||||
|
||||
if (pSurf->LightTableId && pSurf->LightTableId != lt_downloaded)
|
||||
{
|
||||
pglActiveTexture(GL_TEXTURE2);
|
||||
pglBindTexture(GL_TEXTURE_2D, pSurf->LightTableId);
|
||||
pglActiveTexture(GL_TEXTURE0);
|
||||
lt_downloaded = pSurf->LightTableId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1895,7 +2020,7 @@ static void PreparePolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FBITFIELD
|
||||
// -----------------+
|
||||
EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags)
|
||||
{
|
||||
PreparePolygon(pSurf, pOutVerts, PolyFlags);
|
||||
PreparePolygon(pSurf, PolyFlags);
|
||||
|
||||
pglVertexPointer(3, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].x);
|
||||
pglTexCoordPointer(2, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].s);
|
||||
@@ -1913,7 +2038,7 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUI
|
||||
|
||||
EXPORT void HWRAPI(DrawIndexedTriangles) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, unsigned int *IndexArray)
|
||||
{
|
||||
PreparePolygon(pSurf, pOutVerts, PolyFlags);
|
||||
PreparePolygon(pSurf, PolyFlags);
|
||||
|
||||
pglVertexPointer(3, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].x);
|
||||
pglTexCoordPointer(2, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].s);
|
||||
@@ -2089,7 +2214,7 @@ static void gld_BuildSky(int row_count, int col_count)
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void RenderDome(INT32 skytexture)
|
||||
static void RenderDome(INT32 skytexnum)
|
||||
{
|
||||
int i, j;
|
||||
int vbosize;
|
||||
@@ -2101,7 +2226,7 @@ static void RenderDome(INT32 skytexture)
|
||||
vbosize = 2 * rows * (columns * 2 + 2) + columns * 2;
|
||||
|
||||
// Build the sky dome! Yes!
|
||||
if (lasttex != skytexture)
|
||||
if (lasttex != skytexnum)
|
||||
{
|
||||
// delete VBO when already exists
|
||||
if (gl_ext_arb_vertex_buffer_object)
|
||||
@@ -2110,7 +2235,7 @@ static void RenderDome(INT32 skytexture)
|
||||
pglDeleteBuffers(1, &vbo->id);
|
||||
}
|
||||
|
||||
lasttex = skytexture;
|
||||
lasttex = skytexnum;
|
||||
gld_BuildSky(rows, columns);
|
||||
|
||||
if (gl_ext_arb_vertex_buffer_object)
|
||||
@@ -2186,6 +2311,13 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value)
|
||||
case HWD_SET_SHADERS:
|
||||
gl_allowshaders = Value;
|
||||
break;
|
||||
|
||||
case HWD_SET_FRAMEBUFFER:
|
||||
FrameBufferEnabled = Value ? GL_TRUE : GL_FALSE;
|
||||
|
||||
if (!GLFramebuffer_IsFuncAvailible())
|
||||
FrameBufferEnabled = GL_FALSE;
|
||||
break;
|
||||
|
||||
case HWD_SET_TEXTUREFILTERMODE:
|
||||
switch (Value)
|
||||
@@ -2222,21 +2354,12 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value)
|
||||
mag_filter = GL_LINEAR;
|
||||
min_filter = GL_NEAREST;
|
||||
}
|
||||
if (majorGL == 1 && minorGL <= 3)
|
||||
|
||||
if (!pglGenerateMipmap)
|
||||
{
|
||||
MipMap = GL_FALSE;
|
||||
min_filter = GL_LINEAR;
|
||||
}
|
||||
#ifdef GL_VERSION_3_0
|
||||
else
|
||||
{
|
||||
if (!pglGenerateMipmap)
|
||||
{
|
||||
MipMap = GL_FALSE;
|
||||
min_filter = GL_LINEAR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Flush(); //??? if we want to change filter mode by texture, remove this
|
||||
break;
|
||||
@@ -2837,7 +2960,7 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
|
||||
|
||||
EXPORT INT32 HWRAPI(GetTextureUsed) (void)
|
||||
{
|
||||
FTextureInfo *tmp = gr_cachehead;
|
||||
FTextureInfo *tmp = TexCacheHead;
|
||||
INT32 res = 0;
|
||||
|
||||
while (tmp)
|
||||
@@ -2854,7 +2977,7 @@ EXPORT INT32 HWRAPI(GetTextureUsed) (void)
|
||||
|
||||
// Add it up!
|
||||
res += tmp->height*tmp->width*bpp;
|
||||
tmp = tmp->nextmipmap;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
return res;
|
||||
@@ -2995,7 +3118,7 @@ EXPORT void HWRAPI(DrawScreenTexture)(int tex, FSurfaceInfo *surf, FBITFIELD pol
|
||||
|
||||
pglBindTexture(GL_TEXTURE_2D, screenTextures[tex]);
|
||||
|
||||
PreparePolygon(surf, NULL, surf ? polyflags : (PF_NoDepthTest));
|
||||
PreparePolygon(surf, surf ? polyflags : (PF_NoDepthTest));
|
||||
if (!surf)
|
||||
pglColor4ubv(white);
|
||||
|
||||
@@ -3228,7 +3351,7 @@ EXPORT void HWRAPI(MakeScreenTexture) (int tex)
|
||||
tex_downloaded = screenTextures[tex];
|
||||
}
|
||||
|
||||
EXPORT void HWRAPI(DrawScreenFinalTexture)(int tex, int width, int height)
|
||||
EXPORT void HWRAPI(DrawScreenFinalTexture)(int tex, INT32 width, INT32 height)
|
||||
{
|
||||
float xfix, yfix;
|
||||
float origaspect, newaspect;
|
||||
@@ -3305,7 +3428,7 @@ EXPORT void HWRAPI(DrawScreenFinalTexture)(int tex, int width, int height)
|
||||
pglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
if (HWR_ShouldUsePaletteRendering())
|
||||
UnSetShader();
|
||||
pglUseProgram(0);
|
||||
|
||||
tex_downloaded = screenTextures[tex];
|
||||
}
|
||||
|
||||
@@ -104,6 +104,18 @@ static PFNglEnableClientState pglEnableClientState;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void GLFramebuffer_Generate(void);
|
||||
void GLFramebuffer_Delete(void);
|
||||
|
||||
void GLFramebuffer_GenerateAttachments(void);
|
||||
void GLFramebuffer_DeleteAttachments(void);
|
||||
|
||||
void GLFramebuffer_Enable(void);
|
||||
void GLFramebuffer_Disable(void);
|
||||
|
||||
extern GLuint FramebufferObject, FramebufferTexture, RenderbufferObject;
|
||||
extern GLboolean FrameBufferEnabled, RenderToFramebuffer;
|
||||
|
||||
// ==========================================================================
|
||||
// GLOBAL
|
||||
// ==========================================================================
|
||||
|
||||
+2
-1
@@ -339,7 +339,8 @@ HMS_unlist (void)
|
||||
if (! hms)
|
||||
return 0;
|
||||
|
||||
curl_easy_setopt(hms->curl, CURLOPT_CUSTOMREQUEST, "POST");
|
||||
curl_easy_setopt(hms->curl, CURLOPT_POST, 1);
|
||||
curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDSIZE, 0);
|
||||
|
||||
ok = HMS_do(hms);
|
||||
HMS_end(hms);
|
||||
|
||||
+62
-193
@@ -42,19 +42,17 @@
|
||||
#include "p_local.h" // camera[]
|
||||
#include "p_tick.h"
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
#include "lua_hud.h"
|
||||
#include "lua_hudlib_drawlist.h"
|
||||
#include "lua_hook.h"
|
||||
#endif
|
||||
|
||||
#include "s_sound.h" // song credits
|
||||
#include "k_kart.h"
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h"
|
||||
#endif
|
||||
|
||||
// coords are scaled
|
||||
#define HU_INPUTX 0
|
||||
#define HU_INPUTY 0
|
||||
@@ -94,9 +92,7 @@ static boolean headsupactive = false;
|
||||
boolean hu_showscores; // draw rankings
|
||||
static char hu_tick;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
static huddrawlist_h luahuddrawlist_scores;
|
||||
#endif
|
||||
|
||||
patch_t *rflagico;
|
||||
patch_t *bflagico;
|
||||
@@ -128,6 +124,9 @@ static patch_t *songcreditbg;
|
||||
// -------
|
||||
static void HU_DrawRankings(void);
|
||||
|
||||
|
||||
consvar_t cv_showspecstuff = {"showspecstuff", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
//======================================================================
|
||||
// KEYBOARD LAYOUTS FOR ENTERING TEXT
|
||||
//======================================================================
|
||||
@@ -349,9 +348,7 @@ void HU_Init(void)
|
||||
// set shift translation table
|
||||
shiftxform = english_shiftxform;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
luahuddrawlist_scores = LUA_HUD_CreateDrawList();
|
||||
#endif
|
||||
|
||||
HU_LoadGraphics();
|
||||
}
|
||||
@@ -555,7 +552,8 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags)
|
||||
const char *newmsg;
|
||||
INT32 spc = 1; // used if nodenum[1] is a space.
|
||||
char *nodenum = (char*) malloc(3);
|
||||
strncpy(nodenum, msg+3, 3);
|
||||
memcpy(nodenum, msg+3, 2);
|
||||
nodenum[2] = '\0';
|
||||
// check for undesirable characters in our "number"
|
||||
if (((nodenum[0] < '0') || (nodenum[0] > '9')) || ((nodenum[1] < '0') || (nodenum[1] > '9')))
|
||||
{
|
||||
@@ -571,15 +569,15 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags)
|
||||
}
|
||||
}
|
||||
// I'm very bad at C, I swear I am, additional checks eww!
|
||||
if (spc != 0)
|
||||
if (spc != 0)
|
||||
{
|
||||
if (msg[5] != ' ')
|
||||
{
|
||||
if (msg[5] != ' ')
|
||||
{
|
||||
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<node> \'.", false);
|
||||
free(nodenum);
|
||||
return;
|
||||
}
|
||||
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<node> \'.", false);
|
||||
free(nodenum);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
target = atoi((const char*) nodenum); // turn that into a number
|
||||
free(nodenum);
|
||||
@@ -887,10 +885,8 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
|
||||
|
||||
// run the lua hook even if we were supposed to eat the msg, netgame consistency goes first.
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUAh_PlayerMsg(playernum, target, flags, msg, spam_eatmsg))
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (spam_eatmsg)
|
||||
return; // don't proceed if we were supposed to eat the message.
|
||||
@@ -1233,7 +1229,8 @@ static void HU_queueChatChar(INT32 c)
|
||||
return;
|
||||
}
|
||||
|
||||
strncpy(nodenum, msg+3, 3);
|
||||
memcpy(nodenum, msg+3, 2);
|
||||
nodenum[2] = '\0';
|
||||
|
||||
// check for undesirable characters in our "number"
|
||||
if (((nodenum[0] < '0') || (nodenum[0] > '9')) || ((nodenum[1] < '0') || (nodenum[1] > '9')))
|
||||
@@ -1944,7 +1941,8 @@ static void HU_DrawChat(void)
|
||||
|
||||
|
||||
nodenum = (char*) malloc(3);
|
||||
strncpy(nodenum, w_chat+3, 3);
|
||||
memcpy(nodenum, w_chat+3, 2);
|
||||
nodenum[2] = '\0';
|
||||
n = atoi((const char*) nodenum); // turn that into a number
|
||||
free(nodenum);
|
||||
// special cases:
|
||||
@@ -1997,8 +1995,6 @@ static void HU_DrawChat(void)
|
||||
|
||||
|
||||
// For anyone who, for some godforsaken reason, likes oldchat.
|
||||
|
||||
|
||||
static void HU_DrawChat_Old(void)
|
||||
{
|
||||
INT32 t = 0, c = 0, y = HU_INPUTY;
|
||||
@@ -2069,164 +2065,6 @@ static void HU_DrawChat_Old(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
// draw the Crosshair, at the exact center of the view.
|
||||
//
|
||||
// Crosshairs are pre-cached at HU_Init
|
||||
|
||||
/*static inline void HU_DrawCrosshair(void)
|
||||
{
|
||||
INT32 i, x, y;
|
||||
|
||||
i = cv_crosshair.value & 3;
|
||||
if (!i)
|
||||
return;
|
||||
|
||||
if ((netgame || multiplayer) && players[displayplayers[0]].spectator)
|
||||
return;
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft)
|
||||
{
|
||||
x = (INT32)gr_basewindowcenterx;
|
||||
y = (INT32)gr_basewindowcentery;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
x = viewwindowx + (viewwidth>>1);
|
||||
y = viewwindowy + (viewheight>>1);
|
||||
}
|
||||
|
||||
V_DrawScaledPatch(x, y, V_NOSCALESTART|V_OFFSET|V_TRANSLUCENT, crosshair[i - 1]);
|
||||
}
|
||||
|
||||
static inline void HU_DrawCrosshair2(void)
|
||||
{
|
||||
INT32 i, x, y;
|
||||
|
||||
i = cv_crosshair2.value & 3;
|
||||
if (!i)
|
||||
return;
|
||||
|
||||
if ((netgame || multiplayer) && players[displayplayers[1]].spectator)
|
||||
return;
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft)
|
||||
{
|
||||
x = (INT32)gr_basewindowcenterx;
|
||||
y = (INT32)gr_basewindowcentery;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
x = viewwindowx + (viewwidth>>1);
|
||||
y = viewwindowy + (viewheight>>1);
|
||||
}
|
||||
|
||||
if (splitscreen)
|
||||
{
|
||||
if (splitscreen > 1)
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft)
|
||||
x += (INT32)gr_viewwidth;
|
||||
else
|
||||
#endif
|
||||
x += viewwidth;
|
||||
else
|
||||
{
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft)
|
||||
y += (INT32)gr_viewheight;
|
||||
else
|
||||
#endif
|
||||
y += viewheight;
|
||||
}
|
||||
|
||||
V_DrawScaledPatch(x, y, V_NOSCALESTART|V_OFFSET|V_TRANSLUCENT, crosshair[i - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void HU_DrawCrosshair3(void)
|
||||
{
|
||||
INT32 i, x, y;
|
||||
|
||||
i = cv_crosshair3.value & 3;
|
||||
if (!i)
|
||||
return;
|
||||
|
||||
if ((netgame || multiplayer) && players[displayplayers[2]].spectator)
|
||||
return;
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft)
|
||||
{
|
||||
x = (INT32)gr_basewindowcenterx;
|
||||
y = (INT32)gr_basewindowcentery;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
x = viewwindowx + (viewwidth>>1);
|
||||
y = viewwindowy + (viewheight>>1);
|
||||
}
|
||||
|
||||
if (splitscreen > 1)
|
||||
{
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft)
|
||||
y += (INT32)gr_viewheight;
|
||||
else
|
||||
#endif
|
||||
y += viewheight;
|
||||
|
||||
V_DrawScaledPatch(x, y, V_NOSCALESTART|V_OFFSET|V_TRANSLUCENT, crosshair[i - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void HU_DrawCrosshair4(void)
|
||||
{
|
||||
INT32 i, x, y;
|
||||
|
||||
i = cv_crosshair4.value & 3;
|
||||
if (!i)
|
||||
return;
|
||||
|
||||
if ((netgame || multiplayer) && players[displayplayers[3]].spectator)
|
||||
return;
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft)
|
||||
{
|
||||
x = (INT32)gr_basewindowcenterx;
|
||||
y = (INT32)gr_basewindowcentery;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
x = viewwindowx + (viewwidth>>1);
|
||||
y = viewwindowy + (viewheight>>1);
|
||||
}
|
||||
|
||||
if (splitscreen > 2)
|
||||
{
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft)
|
||||
{
|
||||
x += (INT32)gr_viewwidth;
|
||||
y += (INT32)gr_viewheight;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
x += viewwidth;
|
||||
y += viewheight;
|
||||
}
|
||||
|
||||
V_DrawScaledPatch(x, y, V_NOSCALESTART|V_OFFSET|V_TRANSLUCENT, crosshair[i - 1]);
|
||||
}
|
||||
}*/
|
||||
|
||||
static void HU_DrawCEcho(void)
|
||||
{
|
||||
INT32 i = 0;
|
||||
@@ -2425,19 +2263,18 @@ void HU_Drawer(void)
|
||||
{
|
||||
if (netgame || multiplayer)
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_HudEnabled(hud_rankings))
|
||||
#endif
|
||||
HU_DrawRankings();
|
||||
#ifdef HAVE_BLUA
|
||||
if (renderisnewtic)
|
||||
{
|
||||
LUA_HUD_ClearDrawList(luahuddrawlist_scores);
|
||||
LUAh_ScoresHUD(luahuddrawlist_scores);
|
||||
}
|
||||
LUA_HUD_DrawList(luahuddrawlist_scores);
|
||||
#endif
|
||||
|
||||
if (renderisnewtic)
|
||||
{
|
||||
LUA_HUD_ClearDrawList(luahuddrawlist_scores);
|
||||
LUAh_ScoresHUD(luahuddrawlist_scores);
|
||||
}
|
||||
|
||||
LUA_HUD_DrawList(luahuddrawlist_scores);
|
||||
}
|
||||
|
||||
if (demo.playback)
|
||||
{
|
||||
HU_DrawDemoInfo();
|
||||
@@ -2585,7 +2422,7 @@ void HU_drawPing(INT32 x, INT32 y, UINT32 lag, INT32 flags)
|
||||
UINT8 barcolor = 31; // color we use for the bars (green, yellow, red or black)
|
||||
SINT8 i = 0;
|
||||
SINT8 yoffset = 6;
|
||||
INT32 dx;
|
||||
//INT32 dx;
|
||||
|
||||
gfxnum = Ping_gfx_num(lag);
|
||||
|
||||
@@ -2685,6 +2522,7 @@ static inline void HU_DrawSpectatorTicker(void)
|
||||
length += dupadjust;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i] && players[i].spectator)
|
||||
{
|
||||
char *pos;
|
||||
@@ -2726,11 +2564,39 @@ static inline void HU_DrawSpectatorTicker(void)
|
||||
V_DrawString(templength - duptweak, height, V_TRANSLUCENT|V_ALLOWLOWERCASE, current);
|
||||
}
|
||||
|
||||
if (cv_showspecstuff.value)
|
||||
{
|
||||
if (players[i].mo)
|
||||
{
|
||||
player_t *p;
|
||||
p = &players[i];
|
||||
|
||||
if (players[i].mo->color)
|
||||
{
|
||||
const UINT8 *colormap;
|
||||
if (players[i].mo->colorized)
|
||||
colormap = R_GetTranslationColormap(TC_RAINBOW, players[i].mo->color, GTC_CACHE);
|
||||
else
|
||||
colormap = R_GetTranslationColormap(players[i].skin, players[i].mo->color, GTC_CACHE);
|
||||
|
||||
if (cv_highresportrait.value)
|
||||
V_DrawSmallMappedPatch((templength - duptweak), height+10, V_TRANSLUCENT, R_GetSkinFaceWant(p), colormap);
|
||||
else
|
||||
V_DrawMappedPatch((templength - duptweak), height+10, V_TRANSLUCENT, R_GetSkinFaceRank(p), colormap);
|
||||
}
|
||||
}
|
||||
|
||||
if (netgame && i != serverplayer)
|
||||
HU_drawPing((templength - duptweak)+8, height-20, playerpingtable[i], V_TRANSLUCENT);
|
||||
}
|
||||
|
||||
if ((length += len) >= dupadjust+8)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// HU_DrawRankings
|
||||
//
|
||||
@@ -2932,7 +2798,10 @@ void HU_DoCEcho(const char *msg)
|
||||
|
||||
I_OutputMsg("%s\n", msg); // print to log
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstringop-truncation" // This is fine, we set null byte later
|
||||
strncpy(cechotext, msg, sizeof(cechotext));
|
||||
#pragma GCC diagnostic pop
|
||||
strncat(cechotext, "\\", sizeof(cechotext) - strlen(cechotext) - 1);
|
||||
cechotext[sizeof(cechotext) - 1] = '\0';
|
||||
cechotimer = cechoduration;
|
||||
|
||||
@@ -369,4 +369,9 @@ const char *I_ClipboardPaste(void);
|
||||
|
||||
void I_RegisterSysCommands(void);
|
||||
|
||||
|
||||
/** \brief Returns the system name.
|
||||
*/
|
||||
const char *I_GetSysName(void);
|
||||
|
||||
#endif
|
||||
@@ -137,4 +137,6 @@ void I_EndRead(void);
|
||||
|
||||
UINT32 I_GetRefreshRate(void);
|
||||
|
||||
void RefreshSDLSurface(void);
|
||||
|
||||
#endif
|
||||
+851
-324
File diff suppressed because it is too large.
Load diff
@@ -18,6 +18,7 @@ void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor);
|
||||
void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color, boolean local);
|
||||
UINT8 K_GetKartColorByName(const char *name);
|
||||
UINT8 K_GetHudColor(void);
|
||||
boolean K_UseColorHud(void);
|
||||
|
||||
void K_RegisterKartStuff(void);
|
||||
|
||||
@@ -96,5 +97,18 @@ void K_drawKartHUD(void);
|
||||
void K_drawKartFreePlay(UINT32 flashtime);
|
||||
void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UINT8 mode);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
INT32 x;
|
||||
INT32 y;
|
||||
INT32 flags;
|
||||
} drawinfo_t;
|
||||
|
||||
patch_t *K_getItemBoxPatch(boolean small, boolean dark);
|
||||
patch_t *K_getItemMulPatch(boolean small);
|
||||
void K_getItemBoxDrawinfo(drawinfo_t *out);
|
||||
void K_getLapsDrawinfo(drawinfo_t *out);
|
||||
void K_getMinimapDrawinfo(drawinfo_t *out);
|
||||
|
||||
// =========================================================================
|
||||
#endif // __K_KART__
|
||||
@@ -13,6 +13,10 @@
|
||||
#ifndef __KEYS_H__
|
||||
#define __KEYS_H__
|
||||
|
||||
#include "console.h"
|
||||
|
||||
extern consvar_t cv_nativekeyboard;
|
||||
|
||||
// These are the key codes as posted by the keyboard handler,
|
||||
// ascii codes are 0->127,
|
||||
// scancodes are 0x80 + 0->127
|
||||
|
||||
+87
-4
@@ -11,7 +11,6 @@
|
||||
/// \brief basic functions for Lua scripting
|
||||
|
||||
#include "doomdef.h"
|
||||
#ifdef HAVE_BLUA
|
||||
#include "p_local.h"
|
||||
#include "p_setup.h" // So we can have P_SetupLevelSky
|
||||
#include "p_slopes.h" // P_GetZAt
|
||||
@@ -25,6 +24,7 @@
|
||||
#include "console.h"
|
||||
#include "k_kart.h" // SRB2Kart
|
||||
#include "d_netcmd.h" // IsPlayerAdmin
|
||||
#include "m_misc.h" // M_MapNumber
|
||||
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
@@ -154,6 +154,23 @@ static int lib_isPlayerAdmin(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
// M_MISC
|
||||
//////////////
|
||||
|
||||
static int lib_mMapNumber(lua_State *L)
|
||||
{
|
||||
const char *arg = luaL_checkstring(L, 1);
|
||||
size_t len = strlen(arg);
|
||||
if (len == 2 || len == 5) {
|
||||
char first = arg[len-2];
|
||||
char second = arg[len-1];
|
||||
lua_pushinteger(L, M_MapNumber(first, second));
|
||||
} else {
|
||||
lua_pushinteger(L, 0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// M_RANDOM
|
||||
//////////////
|
||||
|
||||
@@ -781,6 +798,17 @@ static int lib_pSetObjectMomZ(lua_State *L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pIsLocalPlayer(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
//NOHUD
|
||||
//INLEVEL
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
lua_pushboolean(L, P_IsLocalPlayer(player));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_pRestoreMusic(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
@@ -958,6 +986,19 @@ static int lib_pHomingAttack(lua_State *L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pResetCamera(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
camera_t *cam = *((camera_t **)luaL_checkudata(L, 2, META_CAMERA));
|
||||
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
if (!cam)
|
||||
return LUA_ErrInvalid(L, "camera_t");
|
||||
P_ResetCamera(player, cam);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*static int lib_pSuperReady(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
@@ -1146,6 +1187,17 @@ static int lib_pFloorzAtPos(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_pCeilingzAtPos(lua_State *L)
|
||||
{
|
||||
fixed_t x = luaL_checkfixed(L, 1);
|
||||
fixed_t y = luaL_checkfixed(L, 2);
|
||||
fixed_t z = luaL_checkfixed(L, 3);
|
||||
fixed_t height = luaL_checkfixed(L, 4);
|
||||
//HUDSAFE
|
||||
lua_pushfixed(L, P_CeilingzAtPos(x, y, z, height));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_pDoSpring(lua_State *L)
|
||||
{
|
||||
mobj_t *spring = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
@@ -1635,6 +1687,17 @@ static int lib_pGetZAt(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_pButteredSlope(lua_State *L)
|
||||
{
|
||||
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
NOHUD
|
||||
//INLEVEL
|
||||
if (!mobj)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
P_ButteredSlope(mobj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// R_DEFS
|
||||
////////////
|
||||
|
||||
@@ -1687,6 +1750,20 @@ static int lib_rPointInSubsector(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_rIsPointInSubsector(lua_State *L)
|
||||
{
|
||||
fixed_t x = luaL_checkfixed(L, 1);
|
||||
fixed_t y = luaL_checkfixed(L, 2);
|
||||
subsector_t *sub = R_IsPointInSubsector(x, y);
|
||||
//HUDSAFE
|
||||
//INLEVEL
|
||||
if (sub)
|
||||
LUA_PushUserdata(L, sub, META_SUBSECTOR);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// R_THINGS
|
||||
////////////
|
||||
|
||||
@@ -3008,6 +3085,9 @@ static luaL_Reg lib[] = {
|
||||
{"EvalMath", lib_evalMath},
|
||||
{"IsPlayerAdmin", lib_isPlayerAdmin},
|
||||
|
||||
// m_misc
|
||||
{"M_MapNumber",lib_mMapNumber},
|
||||
|
||||
// m_random
|
||||
{"P_RandomFixed",lib_pRandomFixed},
|
||||
{"P_RandomByte",lib_pRandomByte},
|
||||
@@ -3068,6 +3148,7 @@ static luaL_Reg lib[] = {
|
||||
{"P_InSpaceSector",lib_pInSpaceSector},
|
||||
{"P_InQuicksand",lib_pInQuicksand},
|
||||
{"P_SetObjectMomZ",lib_pSetObjectMomZ},
|
||||
{"P_IsLocalPlayer",lib_pIsLocalPlayer},
|
||||
{"P_RestoreMusic",lib_pRestoreMusic},
|
||||
{"P_SpawnShieldOrb",lib_pSpawnShieldOrb},
|
||||
{"P_SpawnGhostMobj",lib_pSpawnGhostMobj},
|
||||
@@ -3084,6 +3165,7 @@ static luaL_Reg lib[] = {
|
||||
{"P_LookForEnemies",lib_pLookForEnemies},
|
||||
{"P_NukeEnemies",lib_pNukeEnemies},
|
||||
{"P_HomingAttack",lib_pHomingAttack},
|
||||
{"P_ResetCamera",lib_pResetCamera},
|
||||
//{"P_SuperReady",lib_pSuperReady},
|
||||
{"P_Telekinesis",lib_pTelekinesis},
|
||||
|
||||
@@ -3100,6 +3182,7 @@ static luaL_Reg lib[] = {
|
||||
{"P_CheckHoopPosition",lib_pCheckHoopPosition},
|
||||
{"P_RadiusAttack",lib_pRadiusAttack},
|
||||
{"P_FloorzAtPos",lib_pFloorzAtPos},
|
||||
{"P_CeilingzAtPos",lib_pCeilingzAtPos},
|
||||
{"P_DoSpring",lib_pDoSpring},
|
||||
|
||||
// p_inter
|
||||
@@ -3138,6 +3221,7 @@ static luaL_Reg lib[] = {
|
||||
|
||||
// p_slopes
|
||||
{"P_GetZAt",lib_pGetZAt},
|
||||
{"P_ButteredSlope",lib_pButteredSlope},
|
||||
|
||||
// r_defs
|
||||
{"R_PointToAngle",lib_rPointToAngle},
|
||||
@@ -3145,6 +3229,7 @@ static luaL_Reg lib[] = {
|
||||
{"R_PointToDist",lib_rPointToDist},
|
||||
{"R_PointToDist2",lib_rPointToDist2},
|
||||
{"R_PointInSubsector",lib_rPointInSubsector},
|
||||
{"R_IsPointInSubsector",lib_rIsPointInSubsector},
|
||||
|
||||
// r_things (sprite)
|
||||
{"R_Char2Frame",lib_rChar2Frame},
|
||||
@@ -3267,6 +3352,4 @@ int LUA_BaseLib(lua_State *L)
|
||||
lua_pushvalue(L, LUA_GLOBALSINDEX);
|
||||
luaL_register(L, NULL, lib);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -11,7 +11,6 @@
|
||||
/// \brief blockmap library for Lua scripting
|
||||
|
||||
#include "doomdef.h"
|
||||
#ifdef HAVE_BLUA
|
||||
#include "p_local.h"
|
||||
#include "r_main.h" // validcount
|
||||
#include "lua_script.h"
|
||||
@@ -257,6 +256,4 @@ int LUA_BlockmapLib(lua_State *L)
|
||||
{
|
||||
lua_register(L, "searchBlockmap", lib_searchBlockmap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
+53
-13
@@ -11,13 +11,17 @@
|
||||
/// \brief console modifying/etc library for Lua scripting
|
||||
|
||||
#include "doomdef.h"
|
||||
#ifdef HAVE_BLUA
|
||||
#include "fastcmp.h"
|
||||
#include "p_local.h"
|
||||
#include "g_game.h"
|
||||
#include "byteptr.h"
|
||||
#include "z_zone.h"
|
||||
|
||||
#include "d_netfil.h"
|
||||
|
||||
#include "m_menu.h"
|
||||
#include "w_wad.h"
|
||||
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
#include "lua_hud.h" // hud_running errors
|
||||
@@ -187,8 +191,8 @@ static int lib_comAddCommand(lua_State *L)
|
||||
const char *luaname = luaL_checkstring(L, 1);
|
||||
|
||||
// must store in all lowercase
|
||||
char *name = Z_StrDup(luaname);
|
||||
strlwr(name);
|
||||
char *comname = Z_StrDup(luaname);
|
||||
strlwr(comname);
|
||||
|
||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||
NOHUD
|
||||
@@ -221,25 +225,26 @@ static int lib_comAddCommand(lua_State *L)
|
||||
|
||||
lua_pushvalue(L, 3);
|
||||
lua_rawseti(L, -2, 2);
|
||||
lua_setfield(L, -2, name);
|
||||
lua_setfield(L, -2, comname);
|
||||
|
||||
// Try to add the Lua command
|
||||
com_return = COM_AddLuaCommand(name);
|
||||
com_return = COM_AddLuaCommand(comname);
|
||||
|
||||
if (com_return < 0)
|
||||
{ // failed to add -- free the lowercased name and return error
|
||||
Z_Free(name);
|
||||
Z_Free(comname);
|
||||
return luaL_error(L, "Couldn't add a new console command \"%s\"", luaname);
|
||||
}
|
||||
else if (com_return == 1)
|
||||
{ // command existed already -- free our name as the old string will continue to be used
|
||||
CONS_Printf("Replaced command \"%s\"\n", name);
|
||||
Z_Free(name);
|
||||
CONS_Printf("Replaced command \"%s\"\n", comname);
|
||||
Z_Free(comname);
|
||||
}
|
||||
else
|
||||
{ // new command was added -- do NOT free the string as it will forever be used by the console
|
||||
CONS_Printf("Added command \"%s\"\n", name);
|
||||
CONS_Printf("Added command \"%s\"\n", comname);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -315,12 +320,17 @@ static int lib_cvRegisterVar(lua_State *L)
|
||||
const char *k;
|
||||
lua_Integer i;
|
||||
consvar_t *cvar;
|
||||
|
||||
const char* category = NULL;
|
||||
const char* menu_name = NULL;
|
||||
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
lua_settop(L, 1); // Clear out all other possible arguments, leaving only the first one.
|
||||
NOHUD
|
||||
cvar = lua_newuserdata(L, sizeof(consvar_t));
|
||||
luaL_getmetatable(L, META_CVAR);
|
||||
lua_setmetatable(L, -2);
|
||||
boolean hasminmax = false;
|
||||
|
||||
#define FIELDERROR(f, e) luaL_error(L, "bad value for " LUA_QL(f) " in table passed to " LUA_QL("CV_RegisterVar") " (%s)", e);
|
||||
#define TYPEERROR(f, t) FIELDERROR(f, va("%s expected, got %s", lua_typename(L, t), luaL_typename(L, -1)))
|
||||
@@ -386,13 +396,17 @@ static int lib_cvRegisterVar(lua_State *L)
|
||||
if (lua_type(L, 5) != LUA_TSTRING
|
||||
|| lua_type(L, 6) != LUA_TNUMBER)
|
||||
FIELDERROR("PossibleValue", "custom PossibleValue table requires a format of string=integer, i.e. {MIN=0, MAX=9999}");
|
||||
cvpv[i].strvalue = Z_StrDup(lua_tostring(L, 5));
|
||||
char *strvalue = Z_StrDup(lua_tostring(L, 5));
|
||||
if (fasticmp(strvalue, "MIN"))
|
||||
hasminmax = true;
|
||||
cvpv[i].strvalue = strvalue;
|
||||
cvpv[i].value = (INT32)lua_tonumber(L, 6);
|
||||
i++;
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
cvpv[i].value = 0;
|
||||
cvpv[i].strvalue = NULL;
|
||||
hasminmax = false;
|
||||
cvar->PossibleValue = cvpv;
|
||||
} else
|
||||
FIELDERROR("PossibleValue", va("%s or CV_PossibleValue_t expected, got %s", lua_typename(L, LUA_TTABLE), luaL_typename(L, -1)))
|
||||
@@ -406,6 +420,18 @@ static int lib_cvRegisterVar(lua_State *L)
|
||||
lua_pop(L, 1);
|
||||
cvar->func = Lua_OnChange;
|
||||
}
|
||||
else if (((i == 5 && !(cvar->flags & CV_CALL))
|
||||
|| (cvar->flags & CV_CALL && i == 7))
|
||||
|| (k && fasticmp(k, "category")))
|
||||
{
|
||||
category = lua_isnoneornil(L, 4) ? NULL : lua_tostring(L, 4);
|
||||
}
|
||||
else if (((i == 6 && !(cvar->flags & CV_CALL))
|
||||
|| (cvar->flags & CV_CALL && i == 8))
|
||||
|| (k && fasticmp(k, "menuname")))
|
||||
{
|
||||
menu_name = lua_isnoneornil(L, 4) ? NULL : lua_tostring(L, 4);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
#undef FIELDERROR
|
||||
@@ -430,6 +456,22 @@ static int lib_cvRegisterVar(lua_State *L)
|
||||
if (cvar->flags & CV_MODIFIED)
|
||||
return luaL_error(L, "failed to register cvar (probable conflict with internal variable/command names)");
|
||||
|
||||
if (!(((cvar->flags & CV_HIDEN)) || (cvar->flags & CV_NOSHOWHELP)))
|
||||
{
|
||||
if (!category)
|
||||
{
|
||||
char *temp = strdup(wadfiles[numwadfiles - 1]->filename);
|
||||
nameonly(temp);
|
||||
|
||||
category = temp;
|
||||
}
|
||||
|
||||
if (menu_name && menu_name[0] != '\0')
|
||||
M_SlotCvarIntoModMenu(cvar, category, menu_name, hasminmax);
|
||||
else
|
||||
M_SlotCvarIntoModMenu(cvar, category, cvar->name, hasminmax);
|
||||
}
|
||||
|
||||
// return cvar userdata
|
||||
return 1;
|
||||
}
|
||||
@@ -600,6 +642,4 @@ int LUA_ConsoleLib(lua_State *L)
|
||||
lua_pushvalue(L, LUA_GLOBALSINDEX);
|
||||
luaL_register(L, NULL, lib);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
+1
-5
@@ -10,8 +10,6 @@
|
||||
/// \file lua_hook.h
|
||||
/// \brief hooks for Lua scripting
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
|
||||
#include "r_defs.h"
|
||||
#include "d_player.h"
|
||||
|
||||
@@ -112,6 +110,4 @@ boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd); // Allows to write to p
|
||||
|
||||
void LUAh_IntermissionThinker(void); // Hook for Y_Ticker
|
||||
void LUAh_VoteThinker(void); // Hook for Y_VoteTicker
|
||||
#define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink
|
||||
|
||||
#endif
|
||||
#define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink
|
||||
+22
-15
@@ -11,7 +11,6 @@
|
||||
/// \brief hooks for Lua scripting
|
||||
|
||||
#include "doomdef.h"
|
||||
#ifdef HAVE_BLUA
|
||||
#include "doomstat.h"
|
||||
#include "p_mobj.h"
|
||||
#include "g_game.h"
|
||||
@@ -476,12 +475,14 @@ void LUAh_ThinkFrame(void)
|
||||
// variables used by perf stats
|
||||
int hook_index = 0;
|
||||
precise_t time_taken = 0;
|
||||
|
||||
if (!gL || !(hooksAvailable[hook_ThinkFrame/8] & (1<<(hook_ThinkFrame%8))))
|
||||
return;
|
||||
|
||||
|
||||
lua_pushcfunction(gL, LUA_GetErrorMessage);
|
||||
|
||||
for (hookp = roothook; hookp; hookp = hookp->next)
|
||||
{
|
||||
if (hookp->type == hook_ThinkFrame)
|
||||
{
|
||||
if (cv_perfstats.value == 3)
|
||||
@@ -506,8 +507,9 @@ void LUAh_ThinkFrame(void)
|
||||
hook_index++;
|
||||
}
|
||||
}
|
||||
|
||||
lua_pop(gL, 1); // Pop error handler
|
||||
}
|
||||
|
||||
lua_pop(gL, 1); // Pop error handler
|
||||
}
|
||||
|
||||
// Hook for frame (at end of tick, ie after overlays, precipitation, specials)
|
||||
@@ -519,13 +521,13 @@ void LUAh_PostThinkFrame(void)
|
||||
precise_t time_taken = 0;
|
||||
if (!gL || !(hooksAvailable[hook_PostThinkFrame/8] & (1<<(hook_PostThinkFrame%8))))
|
||||
return;
|
||||
|
||||
|
||||
lua_pushcfunction(gL, LUA_GetErrorMessage);
|
||||
|
||||
for (hookp = roothook; hookp; hookp = hookp->next)
|
||||
{
|
||||
if (hookp->type == hook_PostThinkFrame)
|
||||
{
|
||||
{
|
||||
if (cv_perfstats.value == 5)
|
||||
time_taken = I_GetPreciseTime();
|
||||
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
|
||||
@@ -549,6 +551,7 @@ void LUAh_PostThinkFrame(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lua_pop(gL, 1); // Pop error handler
|
||||
}
|
||||
|
||||
@@ -556,12 +559,14 @@ void LUAh_PostThinkFrame(void)
|
||||
void LUAh_IntermissionThinker(void)
|
||||
{
|
||||
hook_p hookp;
|
||||
|
||||
if (!gL || !(hooksAvailable[hook_IntermissionThinker/8] & (1<<(hook_IntermissionThinker%8))))
|
||||
return;
|
||||
|
||||
|
||||
lua_pushcfunction(gL, LUA_GetErrorMessage);
|
||||
|
||||
for (hookp = roothook; hookp; hookp = hookp->next)
|
||||
{
|
||||
if (hookp->type == hook_IntermissionThinker)
|
||||
{
|
||||
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
|
||||
@@ -573,20 +578,23 @@ void LUAh_IntermissionThinker(void)
|
||||
hookp->error = true;
|
||||
}
|
||||
}
|
||||
|
||||
lua_pop(gL, 1); // Pop error handler
|
||||
}
|
||||
|
||||
lua_pop(gL, 1); // Pop error handler
|
||||
}
|
||||
|
||||
// Hook for Y_VoteTicker
|
||||
void LUAh_VoteThinker(void)
|
||||
{
|
||||
hook_p hookp;
|
||||
|
||||
if (!gL || !(hooksAvailable[hook_VoteThinker/8] & (1<<(hook_VoteThinker%8))))
|
||||
return;
|
||||
|
||||
|
||||
lua_pushcfunction(gL, LUA_GetErrorMessage);
|
||||
|
||||
for (hookp = roothook; hookp; hookp = hookp->next)
|
||||
{
|
||||
if (hookp->type == hook_VoteThinker)
|
||||
{
|
||||
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
|
||||
@@ -598,8 +606,9 @@ void LUAh_VoteThinker(void)
|
||||
hookp->error = true;
|
||||
}
|
||||
}
|
||||
|
||||
lua_pop(gL, 1); // Pop error handler
|
||||
}
|
||||
|
||||
lua_pop(gL, 1); // Pop error handler
|
||||
}
|
||||
|
||||
|
||||
@@ -1740,6 +1749,4 @@ boolean LUAh_PlayerExplode(player_t *player, mobj_t *inflictor, mobj_t *source)
|
||||
}
|
||||
lua_settop(gL, 0);
|
||||
return hooked;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -32,6 +32,8 @@ enum hud {
|
||||
hud_wanted,
|
||||
hud_speedometer,
|
||||
hud_statdisplay,
|
||||
hud_nametags,
|
||||
hud_driftgauge,
|
||||
hud_freeplay,
|
||||
hud_rankings, // Tab rankings
|
||||
|
||||
|
||||
+165
-5
@@ -12,7 +12,6 @@
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "fastcmp.h"
|
||||
#ifdef HAVE_BLUA
|
||||
#include "r_defs.h"
|
||||
#include "r_local.h"
|
||||
#include "st_stuff.h" // hudinfo[]
|
||||
@@ -24,6 +23,7 @@
|
||||
#include "v_video.h"
|
||||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
#include "k_kart.h"
|
||||
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
@@ -56,6 +56,8 @@ static const char *const hud_disable_options[] = {
|
||||
"wanted",
|
||||
"speedometer",
|
||||
"statdisplay",
|
||||
"nametags",
|
||||
"driftgauge",
|
||||
"freeplay",
|
||||
"rankings",
|
||||
NULL};
|
||||
@@ -138,6 +140,7 @@ enum cameraf {
|
||||
camera_x,
|
||||
camera_y,
|
||||
camera_z,
|
||||
camera_reset,
|
||||
camera_angle,
|
||||
camera_subsector,
|
||||
camera_floorz,
|
||||
@@ -157,6 +160,7 @@ static const char *const camera_opt[] = {
|
||||
"x",
|
||||
"y",
|
||||
"z",
|
||||
"reset",
|
||||
"angle",
|
||||
"subsector",
|
||||
"floorz",
|
||||
@@ -169,6 +173,58 @@ static const char *const camera_opt[] = {
|
||||
"pnum",
|
||||
NULL};
|
||||
|
||||
enum hudpatch {
|
||||
hudpatch_item = 0,
|
||||
hudpatch_itemmul
|
||||
};
|
||||
|
||||
static const char *const hud_patch_options[] = {
|
||||
"item",
|
||||
"itemmul",
|
||||
NULL};
|
||||
|
||||
enum hudoffsets {
|
||||
hudoffsets_item = 0,
|
||||
hudoffsets_time,
|
||||
hudoffsets_gametypeinfo,
|
||||
hudoffsets_countdown,
|
||||
hudoffsets_speedometer,
|
||||
hudoffsets_position,
|
||||
hudoffsets_minirankings,
|
||||
hudoffsets_startcountdown,
|
||||
hudoffsets_check,
|
||||
hudoffsets_minimap,
|
||||
hudoffsets_wanted,
|
||||
hudoffsets_statdisplay
|
||||
};
|
||||
|
||||
static const char *const hud_offsets_options[] = {
|
||||
"item",
|
||||
"time",
|
||||
"gametypeinfo",
|
||||
"countdown",
|
||||
"speedometer",
|
||||
"position",
|
||||
"minirankings",
|
||||
"startcountdown",
|
||||
"check",
|
||||
"minimap",
|
||||
"wanted",
|
||||
"statdisplay",
|
||||
NULL};
|
||||
|
||||
enum huddrawinfo {
|
||||
huddrawinfo_item = 0,
|
||||
huddrawinfo_gametypeinfo,
|
||||
huddrawinfo_minimap
|
||||
};
|
||||
|
||||
static const char *const hud_drawinfo_options[] = {
|
||||
"item",
|
||||
"gametypeinfo",
|
||||
"minimap",
|
||||
NULL};
|
||||
|
||||
static int lib_getHudInfo(lua_State *L)
|
||||
{
|
||||
UINT32 i;
|
||||
@@ -295,6 +351,9 @@ static int camera_get(lua_State *L)
|
||||
case camera_z:
|
||||
lua_pushinteger(L, cam->z);
|
||||
break;
|
||||
case camera_reset:
|
||||
lua_pushboolean(L, cam->reset);
|
||||
break;
|
||||
case camera_angle:
|
||||
lua_pushinteger(L, cam->angle);
|
||||
break;
|
||||
@@ -744,7 +803,6 @@ static int libd_drawStretched(lua_State *L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int libd_drawNum(lua_State *L)
|
||||
{
|
||||
INT32 x, y, flags, num;
|
||||
@@ -1007,6 +1065,54 @@ static int libd_getColormap(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int libd_getColorHudPatch(lua_State *L)
|
||||
{
|
||||
HUDONLY
|
||||
enum hudpatch option = luaL_checkoption(L, 1, NULL, hud_patch_options);
|
||||
patch_t *patch;
|
||||
UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, K_GetHudColor(), GTC_CACHE);
|
||||
boolean small, dark;
|
||||
|
||||
switch (option) {
|
||||
case hudpatch_item:
|
||||
small = lua_optboolean(L, 2);
|
||||
dark = lua_optboolean(L, 3);
|
||||
patch = K_getItemBoxPatch(small, dark);
|
||||
if (!cv_colorizeditembox.value)
|
||||
colormap = NULL;
|
||||
break;
|
||||
case hudpatch_itemmul:
|
||||
small = lua_optboolean(L, 2);
|
||||
patch = K_getItemMulPatch(small);
|
||||
break;
|
||||
default:
|
||||
return 0; // you shouldn't be here
|
||||
}
|
||||
|
||||
LUA_PushUserdata(L, patch, META_PATCH);
|
||||
if (colormap && K_UseColorHud())
|
||||
LUA_PushUserdata(L, colormap, META_COLORMAP);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int libd_getHudColor(lua_State *L)
|
||||
{
|
||||
HUDONLY
|
||||
lua_pushinteger(L, K_GetHudColor());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int libd_useColorHud(lua_State *L)
|
||||
{
|
||||
HUDONLY
|
||||
lua_pushboolean(L, K_UseColorHud());
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int libd_width(lua_State *L)
|
||||
{
|
||||
HUDONLY
|
||||
@@ -1057,6 +1163,26 @@ static int libd_getlocaltransflag(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int libd_getDrawInfo(lua_State *L)
|
||||
{
|
||||
HUDONLY
|
||||
enum huddrawinfo option = luaL_checkoption(L, 1, NULL, hud_drawinfo_options);
|
||||
drawinfo_t info;
|
||||
|
||||
switch(option) {
|
||||
case huddrawinfo_item: K_getItemBoxDrawinfo(&info); break;
|
||||
case huddrawinfo_gametypeinfo: K_getLapsDrawinfo(&info); break;
|
||||
case huddrawinfo_minimap: K_getMinimapDrawinfo(&info); break;
|
||||
default:
|
||||
return 0; // unreachable
|
||||
}
|
||||
|
||||
lua_pushinteger(L, info.x);
|
||||
lua_pushinteger(L, info.y);
|
||||
lua_pushinteger(L, info.flags);
|
||||
return 3;
|
||||
}
|
||||
|
||||
static luaL_Reg lib_draw[] = {
|
||||
{"patchExists", libd_patchExists},
|
||||
{"cachePatch", libd_cachePatch},
|
||||
@@ -1080,6 +1206,10 @@ static luaL_Reg lib_draw[] = {
|
||||
{"renderer", libd_renderer},
|
||||
{"localTransFlag", libd_getlocaltransflag},
|
||||
{"drawOnMinimap", libd_drawOnMinimap},
|
||||
{"getColorHudPatch", libd_getColorHudPatch},
|
||||
{"getDrawInfo", libd_getDrawInfo},
|
||||
{"getHudColor", libd_getHudColor},
|
||||
{"useColorHud", libd_useColorHud},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
@@ -1170,12 +1300,44 @@ static int lib_hudsetvotebackground(lua_State *L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_hudgetoffsets(lua_State *L)
|
||||
{
|
||||
enum hudoffsets option = luaL_checkoption(L, 1, NULL, hud_offsets_options);
|
||||
INT32 ofx, ofy;
|
||||
|
||||
#define OFS(it) ofx = cv_##it##_xoffset.value; ofy = cv_##it##_yoffset.value; break;
|
||||
#define OFY(it) ofx = 0; ofy = cv_##it##_yoffset.value; break;
|
||||
switch(option) {
|
||||
case hudoffsets_item: OFS(item)
|
||||
case hudoffsets_time: OFS(time)
|
||||
case hudoffsets_gametypeinfo: OFS(laps)
|
||||
case hudoffsets_countdown: OFS(dnft)
|
||||
case hudoffsets_speedometer: OFS(speed)
|
||||
case hudoffsets_position: OFS(posi)
|
||||
case hudoffsets_minirankings: OFS(face)
|
||||
case hudoffsets_startcountdown: OFS(stcd)
|
||||
case hudoffsets_check: OFY(chek)
|
||||
case hudoffsets_minimap: OFS(mini)
|
||||
case hudoffsets_wanted: OFS(want)
|
||||
case hudoffsets_statdisplay: OFS(stat)
|
||||
default:
|
||||
return 0; // unreachable
|
||||
}
|
||||
#undef OFS
|
||||
#undef OFY
|
||||
|
||||
lua_pushinteger(L, ofx);
|
||||
lua_pushinteger(L, ofy);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static luaL_Reg lib_hud[] = {
|
||||
{"enable", lib_hudenable},
|
||||
{"disable", lib_huddisable},
|
||||
{"enabled", lib_hudenabled},
|
||||
{"add", lib_hudadd},
|
||||
{"setVoteBackground", lib_hudsetvotebackground},
|
||||
{"getOffsets", lib_hudgetoffsets},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
@@ -1411,6 +1573,4 @@ void LUAh_VoteHUD(huddrawlist_h list)
|
||||
|
||||
lua_pushlightuserdata(gL, NULL);
|
||||
lua_setfield(gL, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
+1
-4
@@ -11,7 +11,6 @@
|
||||
/// \brief infotable editing library for Lua scripting
|
||||
|
||||
#include "doomdef.h"
|
||||
#ifdef HAVE_BLUA
|
||||
#include "fastcmp.h"
|
||||
#include "info.h"
|
||||
#include "dehacked.h"
|
||||
@@ -984,6 +983,4 @@ int LUA_InfoLib(lua_State *L)
|
||||
lua_setglobal(L, "S_sfx");
|
||||
lua_setglobal(L, "sfxinfo");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
+1
-5
@@ -10,8 +10,6 @@
|
||||
/// \file lua_libs.h
|
||||
/// \brief libraries for Lua scripting
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
|
||||
extern lua_State *gL;
|
||||
|
||||
#define LREG_VALID "VALID_USERDATA"
|
||||
@@ -70,6 +68,4 @@ int LUA_SkinLib(lua_State *L);
|
||||
int LUA_ThinkerLib(lua_State *L);
|
||||
int LUA_MapLib(lua_State *L);
|
||||
int LUA_BlockmapLib(lua_State *L);
|
||||
int LUA_HudLib(lua_State *L);
|
||||
|
||||
#endif
|
||||
int LUA_HudLib(lua_State *L);
|
||||
+3
-4
@@ -11,7 +11,6 @@
|
||||
/// \brief game map library for Lua scripting
|
||||
|
||||
#include "doomdef.h"
|
||||
#ifdef HAVE_BLUA
|
||||
#include "r_state.h"
|
||||
#include "p_local.h"
|
||||
#include "p_setup.h"
|
||||
@@ -268,6 +267,8 @@ static int lib_iterateSectorThinglist(lua_State *L)
|
||||
if (!lua_isnil(L, 1))
|
||||
{
|
||||
thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
if (P_MobjWasRemoved(thing))
|
||||
return luaL_error(L, "current entry in thinglist was removed; avoid calling P_RemoveMobj on entries!");
|
||||
thing = thing->snext;
|
||||
}
|
||||
else
|
||||
@@ -1689,6 +1690,4 @@ int LUA_MapLib(lua_State *L)
|
||||
lua_setmetatable(L, -2);
|
||||
lua_setglobal(L, "mapheaderinfo");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
+1
-4
@@ -11,7 +11,6 @@
|
||||
/// \brief basic math library for Lua scripting
|
||||
|
||||
#include "doomdef.h"
|
||||
#ifdef HAVE_BLUA
|
||||
//#include "fastcmp.h"
|
||||
#include "tables.h"
|
||||
#include "p_local.h"
|
||||
@@ -228,6 +227,4 @@ int LUA_MathLib(lua_State *L)
|
||||
lua_pushvalue(L, LUA_GLOBALSINDEX);
|
||||
luaL_register(L, NULL, lib);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
+1
-4
@@ -13,7 +13,6 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#include "doomdef.h"
|
||||
#ifdef HAVE_BLUA
|
||||
#include "fastcmp.h"
|
||||
#include "r_things.h"
|
||||
#include "r_main.h"
|
||||
@@ -926,6 +925,4 @@ int LUA_MobjLib(lua_State *L)
|
||||
lua_setmetatable(L, -2);
|
||||
lua_setglobal(L, "mapthings");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
+1
-4
@@ -11,7 +11,6 @@
|
||||
/// \brief player object library for Lua scripting
|
||||
|
||||
#include "doomdef.h"
|
||||
#ifdef HAVE_BLUA
|
||||
#include "fastcmp.h"
|
||||
#include "r_main.h"
|
||||
#include "r_things.h"
|
||||
@@ -820,6 +819,4 @@ int LUA_PlayerLib(lua_State *L)
|
||||
lua_setglobal(L, "displayplayers");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
+1
-4
@@ -11,7 +11,6 @@
|
||||
/// \brief Lua scripting basics
|
||||
|
||||
#include "doomdef.h"
|
||||
#ifdef HAVE_BLUA
|
||||
#include "fastcmp.h"
|
||||
#include "dehacked.h"
|
||||
#include "z_zone.h"
|
||||
@@ -1688,6 +1687,4 @@ int Lua_optoption(lua_State *L, int narg,
|
||||
if (fastcmp(lst[i], name))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif // HAVE_BLUA
|
||||
}
|
||||
@@ -10,8 +10,6 @@
|
||||
/// \file lua_script.h
|
||||
/// \brief Lua scripting basics
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
|
||||
#include "m_fixed.h"
|
||||
#include "doomtype.h"
|
||||
#include "d_player.h"
|
||||
@@ -95,5 +93,3 @@ void COM_Lua_f(void);
|
||||
CONS_Alert(CONS_WARNING,"%s\n", warningmsg);\
|
||||
}\
|
||||
}
|
||||
|
||||
#endif
|
||||
+1
-4
@@ -11,7 +11,6 @@
|
||||
/// \brief player skin structure library for Lua scripting
|
||||
|
||||
#include "doomdef.h"
|
||||
#ifdef HAVE_BLUA
|
||||
#include "fastcmp.h"
|
||||
#include "r_things.h"
|
||||
#include "sounds.h"
|
||||
@@ -273,6 +272,4 @@ int LUA_SkinLib(lua_State *L)
|
||||
lua_setglobal(L, "skins");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -11,7 +11,6 @@
|
||||
/// \brief thinker library for Lua scripting
|
||||
|
||||
#include "doomdef.h"
|
||||
#ifdef HAVE_BLUA
|
||||
#include "p_local.h"
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
@@ -131,6 +130,4 @@ int LUA_ThinkerLib(lua_State *L)
|
||||
lua_setfield(L, -2, "iterate");
|
||||
lua_setglobal(L, "thinkers");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
+1
-5
@@ -1,8 +1,6 @@
|
||||
#ifndef __LUA_UDATALIB_H__
|
||||
#define __LUA_UDATALIB_H__
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
@@ -102,6 +100,4 @@ void udatalib_addfields(lua_State *L, int mt, const udata_field_t fields[]);
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
+120
-26
@@ -18,6 +18,9 @@
|
||||
#include "z_zone.h"
|
||||
#include "v_video.h"
|
||||
#include "i_video.h"
|
||||
#include "i_system.h" // I_GetPreciseTime
|
||||
#include "doomstat.h" // singletics
|
||||
#include "st_stuff.h" // st_palette
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h"
|
||||
@@ -26,19 +29,34 @@
|
||||
// GIFs are always little-endian
|
||||
#include "byteptr.h"
|
||||
|
||||
CV_PossibleValue_t gif_dynamicdelay_cons_t[] = {
|
||||
{0, "Off"},
|
||||
{1, "On"},
|
||||
{2, "Accurate, experimental"},
|
||||
{0, NULL}};
|
||||
|
||||
consvar_t cv_gif_optimize = {"gif_optimize", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_gif_downscale = {"gif_downscale", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_gif_dynamicdelay = {"gif_dynamicdelay", "On", CV_SAVE, gif_dynamicdelay_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_gif_localcolortable = {"gif_localcolortable", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
#ifdef HAVE_ANIGIF
|
||||
static boolean gif_optimize = false; // So nobody can do something dumb
|
||||
static boolean gif_downscale = false; // like changing cvars mid output
|
||||
static UINT8 gif_dynamicdelay = (UINT8)0; // and messing something up
|
||||
|
||||
// Palette handling
|
||||
static boolean gif_localcolortable = false;
|
||||
static RGBA_t *gif_headerpalette = NULL;
|
||||
static RGBA_t *gif_framepalette = NULL;
|
||||
|
||||
static FILE *gif_out = NULL;
|
||||
static INT32 gif_frames = 0;
|
||||
static precise_t gif_prevframetime = 0;
|
||||
static UINT32 gif_delayus = 0; // "us" is microseconds
|
||||
static UINT8 gif_writeover = 0;
|
||||
|
||||
|
||||
|
||||
// OPTIMIZE gif output
|
||||
// ---
|
||||
|
||||
@@ -390,18 +408,47 @@ const UINT8 gifhead_base[6] = {0x47,0x49,0x46,0x38,0x39,0x61}; // GIF89a
|
||||
const UINT8 gifhead_nsid[19] = {0x21,0xFF,0x0B, // extension block + size
|
||||
0x4E,0x45,0x54,0x53,0x43,0x41,0x50,0x45,0x32,0x2E,0x30, // NETSCAPE2.0
|
||||
0x03,0x01,0xFF,0xFF,0x00}; // sub-block, repetitions
|
||||
|
||||
//
|
||||
// GIF_getpalette
|
||||
// determine the palette for the current frame.
|
||||
//
|
||||
static RGBA_t *GIF_getpalette(size_t palnum)
|
||||
{
|
||||
// In hardware mode, always returns the local palette
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl && !HWR_ShouldUsePaletteRendering())
|
||||
return pLocalPalette;
|
||||
else
|
||||
#endif
|
||||
return (&pLocalPalette[palnum*256]);
|
||||
}
|
||||
|
||||
//
|
||||
// GIF_palwrite
|
||||
// writes the gif palette.
|
||||
// used both for the header and local color tables.
|
||||
//
|
||||
static UINT8 *GIF_palwrite(UINT8 *p, RGBA_t *pal)
|
||||
{
|
||||
INT32 i;
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
WRITEUINT8(p, pal[i].s.red);
|
||||
WRITEUINT8(p, pal[i].s.green);
|
||||
WRITEUINT8(p, pal[i].s.blue);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
//
|
||||
// GIF_headwrite
|
||||
// writes the gif header to the currently open output file.
|
||||
// NOTE that this code does not accomodate for palette changes.
|
||||
//
|
||||
static void GIF_headwrite(void)
|
||||
{
|
||||
UINT8 *gifhead = Z_Malloc(800, PU_STATIC, NULL);
|
||||
UINT8 *p = gifhead;
|
||||
RGBA_t *c;
|
||||
INT32 i;
|
||||
UINT16 rwidth, rheight;
|
||||
|
||||
if (!gif_out)
|
||||
@@ -422,22 +469,17 @@ static void GIF_headwrite(void)
|
||||
rwidth = vid.width;
|
||||
rheight = vid.height;
|
||||
}
|
||||
|
||||
WRITEUINT16(p, rwidth);
|
||||
WRITEUINT16(p, rheight);
|
||||
|
||||
// colors, aspect, etc
|
||||
WRITEUINT8(p, 0xF7);
|
||||
WRITEUINT8(p, 0xF7); // (0xF7 = 1111 0111)
|
||||
WRITEUINT8(p, 0x00);
|
||||
WRITEUINT8(p, 0x00);
|
||||
|
||||
// write color table
|
||||
for (i = 0; i < 256; ++i)
|
||||
{
|
||||
c = &pLocalPalette[i];
|
||||
WRITEUINT8(p, c->s.red);
|
||||
WRITEUINT8(p, c->s.green);
|
||||
WRITEUINT8(p, c->s.blue);
|
||||
}
|
||||
p = GIF_palwrite(p, gif_headerpalette);
|
||||
|
||||
// write extension block
|
||||
WRITEMEM(p, gifhead_nsid, sizeof(gifhead_nsid));
|
||||
@@ -468,7 +510,7 @@ static void GIF_rgbconvert(UINT8 *linear, UINT8 *scr)
|
||||
size_t src, dest;
|
||||
int x, y;
|
||||
|
||||
InitColorLUT();
|
||||
InitColorLUT(gif_framepalette);
|
||||
|
||||
for (x = 0; x < vid.width; x += scrbuf_downscaleamt)
|
||||
{
|
||||
@@ -495,6 +537,7 @@ static void GIF_framewrite(void)
|
||||
UINT8 *p;
|
||||
UINT8 *movie_screen = screens[2];
|
||||
INT32 blitx, blity, blitw, blith;
|
||||
boolean palchanged;
|
||||
|
||||
if (!gifframe_data)
|
||||
gifframe_data = Z_Malloc(gifframe_size, PU_STATIC, NULL);
|
||||
@@ -502,9 +545,19 @@ static void GIF_framewrite(void)
|
||||
|
||||
if (!gif_out)
|
||||
return;
|
||||
|
||||
// Lactozilla: Compare the header's palette with the current frame's palette and see if it changed.
|
||||
if (gif_localcolortable)
|
||||
{
|
||||
gif_framepalette = GIF_getpalette(max(st_palette, 0));
|
||||
palchanged = memcmp(gif_headerpalette, gif_framepalette, sizeof(RGBA_t) * 256);
|
||||
}
|
||||
else
|
||||
palchanged = false;
|
||||
|
||||
// Compare image data (for optimizing GIF)
|
||||
if (gif_optimize && gif_frames > 0)
|
||||
// If the palette has changed, the entire frame is considered to be different.
|
||||
if (gif_optimize && gif_frames > 0 && (!palchanged))
|
||||
{
|
||||
// before blit movie_screen points to last frame, cur_screen points to this frame
|
||||
UINT8 *cur_screen = screens[0];
|
||||
@@ -548,11 +601,39 @@ static void GIF_framewrite(void)
|
||||
|
||||
// screen regions are handled in GIF_lzw
|
||||
{
|
||||
int d1 = (int)((100.0f/NEWTICRATE)*(gif_frames+1));
|
||||
int d2 = (int)((100.0f/NEWTICRATE)*(gif_frames));
|
||||
UINT16 delay = d1-d2;
|
||||
UINT16 delay = 0;
|
||||
INT32 startline;
|
||||
|
||||
if (gif_dynamicdelay ==(UINT8) 2 && !singletics)
|
||||
{
|
||||
// golden's attempt at creating a "dynamic delay"
|
||||
UINT16 mingifdelay = 10; // minimum gif delay in milliseconds (keep at 10 because gifs can't get more precise).
|
||||
gif_delayus += (I_GetPreciseTime() - gif_prevframetime) / (I_GetPrecisePrecision() / 1000000); // increase delay by how much time was spent between last measurement
|
||||
|
||||
if (gif_delayus/1000 >= mingifdelay) // delay is big enough to be able to effect gif frame delay?
|
||||
{
|
||||
int frames = (gif_delayus/1000) / mingifdelay; // get amount of frames to delay.
|
||||
delay = frames; // set the delay to delay that amount of frames.
|
||||
gif_delayus -= frames*(mingifdelay*1000); // remove frames by the amount of milliseconds they take. don't reset to 0, the microseconds help consistency.
|
||||
}
|
||||
}
|
||||
else if (gif_dynamicdelay ==(UINT8) 1 && !singletics)
|
||||
{
|
||||
float delayf = ceil(100.0f/NEWTICRATE);
|
||||
|
||||
delay = (UINT16)((I_GetPreciseTime() - gif_prevframetime)) / (I_GetPrecisePrecision() / 1000000) /10/1000;
|
||||
|
||||
if (delay < (UINT16)(delayf))
|
||||
delay = (UINT16)(delayf);
|
||||
}
|
||||
else
|
||||
{
|
||||
// the original code
|
||||
int d1 = (int)((100.0f/NEWTICRATE)*(gif_frames+1));
|
||||
int d2 = (int)((100.0f/NEWTICRATE)*(gif_frames));
|
||||
delay = d1-d2;
|
||||
}
|
||||
|
||||
WRITEMEM(p, gifframe_gchead, 4);
|
||||
|
||||
WRITEUINT16(p, delay);
|
||||
@@ -573,7 +654,20 @@ static void GIF_framewrite(void)
|
||||
WRITEUINT16(p, (UINT16)(blity / scrbuf_downscaleamt));
|
||||
WRITEUINT16(p, (UINT16)(blitw / scrbuf_downscaleamt));
|
||||
WRITEUINT16(p, (UINT16)(blith / scrbuf_downscaleamt));
|
||||
WRITEUINT8(p, 0); // no local table of colors
|
||||
|
||||
if (!gif_localcolortable)
|
||||
WRITEUINT8(p, 0); // no local table of colors
|
||||
else
|
||||
{
|
||||
if (palchanged)
|
||||
{
|
||||
// The palettes are different, so write the Local Color Table!
|
||||
WRITEUINT8(p, 0x87); // (0x87 = 1000 0111)
|
||||
p = GIF_palwrite(p, gif_framepalette);
|
||||
}
|
||||
else
|
||||
WRITEUINT8(p, 0); // They are equal, no Local Color Table needed.
|
||||
}
|
||||
|
||||
scrbuf_pos = movie_screen + blitx + (blity * vid.width);
|
||||
scrbuf_writeend = scrbuf_pos + (blitw - 1) + ((blith - 1) * vid.width);
|
||||
@@ -617,6 +711,7 @@ static void GIF_framewrite(void)
|
||||
}
|
||||
fwrite(gifframe_data, 1, (p - gifframe_data), gif_out);
|
||||
++gif_frames;
|
||||
gif_prevframetime = I_GetPreciseTime();
|
||||
}
|
||||
|
||||
|
||||
@@ -631,22 +726,21 @@ static void GIF_framewrite(void)
|
||||
//
|
||||
INT32 GIF_open(const char *filename)
|
||||
{
|
||||
#if 0
|
||||
if (rendermode != render_soft)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("GIFs cannot be taken in non-software modes!\n"));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
gif_out = fopen(filename, "wb");
|
||||
if (!gif_out)
|
||||
return 0;
|
||||
|
||||
gif_optimize = (!!cv_gif_optimize.value);
|
||||
gif_downscale = (!!cv_gif_downscale.value);
|
||||
gif_dynamicdelay = (UINT8)cv_gif_dynamicdelay.value;
|
||||
|
||||
gif_localcolortable = (!!cv_gif_localcolortable.value);
|
||||
gif_headerpalette = GIF_getpalette(0);
|
||||
|
||||
GIF_headwrite();
|
||||
gif_frames = 0;
|
||||
gif_prevframetime = I_GetPreciseTime();
|
||||
gif_delayus = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -27,6 +27,6 @@ void GIF_frame(void);
|
||||
INT32 GIF_close(void);
|
||||
#endif
|
||||
|
||||
extern consvar_t cv_gif_optimize, cv_gif_downscale;
|
||||
extern consvar_t cv_gif_optimize, cv_gif_downscale, cv_gif_dynamicdelay, cv_gif_localcolortable;
|
||||
|
||||
#endif
|
||||
+1
-3
@@ -647,7 +647,7 @@ void Command_CauseCfail_f(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_BLUA) && defined(LUA_ALLOW_BYTECODE)
|
||||
#if defined(LUA_ALLOW_BYTECODE)
|
||||
void Command_Dumplua_f(void)
|
||||
{
|
||||
if (modifiedgame)
|
||||
@@ -891,9 +891,7 @@ static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean c
|
||||
mapthing_t *mt = mapthings;
|
||||
sector_t *sec = player->mo->subsector->sector;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
LUA_InvalidateMapthings();
|
||||
#endif
|
||||
|
||||
mapthings = Z_Realloc(mapthings, ++nummapthings * sizeof (*mapthings), PU_LEVEL, NULL);
|
||||
|
||||
|
||||
+1
-1
@@ -67,7 +67,7 @@ void Command_Weather_f(void);
|
||||
#ifdef _DEBUG
|
||||
void Command_CauseCfail_f(void);
|
||||
#endif
|
||||
#if defined(HAVE_BLUA) && defined(LUA_ALLOW_BYTECODE)
|
||||
#if defined(LUA_ALLOW_BYTECODE)
|
||||
void Command_Dumplua_f(void);
|
||||
#endif
|
||||
|
||||
|
||||
+1
-3
@@ -179,9 +179,7 @@ fixed_t FV2_Distance(const vector2_t *p1, const vector2_t *p2)
|
||||
|
||||
fixed_t FV2_Magnitude(const vector2_t *a_normal)
|
||||
{
|
||||
fixed_t xs = FixedMul(a_normal->x, a_normal->x);
|
||||
fixed_t ys = FixedMul(a_normal->y, a_normal->y);
|
||||
return FixedSqrt(xs + ys);
|
||||
return FixedHypot(a_normal->x, a_normal->y); // Much less prone to overflowing
|
||||
}
|
||||
|
||||
// Also returns the magnitude
|
||||
|
||||
+359
-549
File diff suppressed because it is too large.
Load diff
+13
-8
@@ -147,6 +147,8 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt);
|
||||
|
||||
#define MAXSTRINGLENGTH 32
|
||||
|
||||
#define MAXMENUCCVARS 999
|
||||
|
||||
#define MAXTOOLTIPS 255
|
||||
|
||||
typedef union
|
||||
@@ -171,7 +173,7 @@ typedef struct menuitem_s
|
||||
void *itemaction;
|
||||
|
||||
// hotkey in menu or y of the item
|
||||
UINT8 alphaKey;
|
||||
UINT16 alphaKey;
|
||||
} menuitem_t;
|
||||
|
||||
extern menuitem_t PlayerMenu[MAXSKINS];
|
||||
@@ -289,6 +291,8 @@ void M_PopupMasterServerRules(void);
|
||||
void M_PopupMasterServerConnectError(void);
|
||||
#endif
|
||||
|
||||
void M_SlotCvarIntoModMenu(consvar_t* cvar, const char* category, const char* name, boolean minmax);
|
||||
|
||||
// These defines make it a little easier to make menus
|
||||
#define DEFAULTMENUSTYLE(header, source, prev, x, y)\
|
||||
{\
|
||||
@@ -300,7 +304,7 @@ void M_PopupMasterServerConnectError(void);
|
||||
x, y,\
|
||||
0,\
|
||||
NULL,\
|
||||
NULL\
|
||||
{NULL}\
|
||||
}
|
||||
|
||||
#define DEFAULTSCROLLSTYLE(header, source, prev, x, y)\
|
||||
@@ -313,9 +317,10 @@ void M_PopupMasterServerConnectError(void);
|
||||
x, y,\
|
||||
0,\
|
||||
NULL,\
|
||||
NULL\
|
||||
{NULL}\
|
||||
}
|
||||
|
||||
|
||||
#define PAUSEMENUSTYLE(source, x, y)\
|
||||
{\
|
||||
NULL,\
|
||||
@@ -326,7 +331,7 @@ void M_PopupMasterServerConnectError(void);
|
||||
x, y,\
|
||||
0,\
|
||||
NULL,\
|
||||
NULL\
|
||||
{NULL}\
|
||||
}
|
||||
|
||||
#define CENTERMENUSTYLE(header, source, prev, y)\
|
||||
@@ -339,7 +344,7 @@ void M_PopupMasterServerConnectError(void);
|
||||
BASEVIDWIDTH/2, y,\
|
||||
0,\
|
||||
NULL,\
|
||||
NULL\
|
||||
{NULL}\
|
||||
}
|
||||
|
||||
#define MAPICONMENUSTYLE(header, source, prev)\
|
||||
@@ -352,7 +357,7 @@ void M_PopupMasterServerConnectError(void);
|
||||
24,40,\
|
||||
0,\
|
||||
NULL,\
|
||||
NULL\
|
||||
{NULL}\
|
||||
}
|
||||
|
||||
#define CONTROLMENUSTYLE(source, prev)\
|
||||
@@ -365,7 +370,7 @@ void M_PopupMasterServerConnectError(void);
|
||||
26, 40,\
|
||||
0,\
|
||||
NULL,\
|
||||
NULL\
|
||||
{NULL}\
|
||||
}
|
||||
|
||||
#define IMAGEDEF(source)\
|
||||
@@ -378,7 +383,7 @@ void M_PopupMasterServerConnectError(void);
|
||||
0, 0,\
|
||||
0,\
|
||||
NULL,\
|
||||
NULL\
|
||||
{NULL}\
|
||||
}
|
||||
|
||||
#endif //__X_MENU__
|
||||
+5
-3
@@ -65,6 +65,8 @@ typedef off_t off64_t;
|
||||
#define PRIdS "u"
|
||||
#elif defined(_WIN32) && !defined(__MINGW64__)
|
||||
#define PRIdS "Iu"
|
||||
#elif defined(_WIN32) && defined(__MINGW64__)
|
||||
#define PRIdS PRIuPTR
|
||||
#else
|
||||
#define PRIdS "zu"
|
||||
#endif
|
||||
@@ -996,7 +998,7 @@ static boolean M_SetupaPNG(png_const_charp filename, png_bytep pal)
|
||||
png_init_io(apng_ptr, apng_FILE);
|
||||
|
||||
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
|
||||
png_set_user_limits(apng_ptr, MAXPNGWIDTH, MAXPNGHEIGHT);
|
||||
png_set_user_limits(apng_ptr, MAXVIDWIDTH, MAXVIDHEIGHT);
|
||||
#endif
|
||||
|
||||
//png_set_filter(apng_ptr, 0, PNG_ALL_FILTERS);
|
||||
@@ -1141,7 +1143,7 @@ void M_SaveFrame(void)
|
||||
// paranoia: should be unnecessary without singletics
|
||||
static tic_t oldtic = 0;
|
||||
|
||||
if (oldtic == I_GetTime())
|
||||
if (oldtic == I_GetTime() && !singletics)
|
||||
return;
|
||||
else
|
||||
oldtic = I_GetTime();
|
||||
@@ -1305,7 +1307,7 @@ boolean M_SavePNG(const char *filename, void *data, int width, int height, const
|
||||
png_init_io(png_ptr, png_FILE);
|
||||
|
||||
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
|
||||
png_set_user_limits(png_ptr, MAXPNGWIDTH, MAXPNGHEIGHT);
|
||||
png_set_user_limits(png_ptr, MAXVIDWIDTH, MAXVIDHEIGHT);
|
||||
#endif
|
||||
|
||||
//png_set_filter(png_ptr, 0, PNG_ALL_FILTERS);
|
||||
|
||||
+186
-550
File diff suppressed because it is too large.
Load diff
@@ -2006,6 +2006,20 @@ void T_ThwompSector(levelspecthink_t *thwomp)
|
||||
#undef ceilingwasheight
|
||||
}
|
||||
|
||||
|
||||
static void T_UpdateMobjPlaneZ(sector_t *sec)
|
||||
{
|
||||
msecnode_t *node = sec->touching_thinglist; // things touching this sector
|
||||
mobj_t *mo;
|
||||
while (node)
|
||||
{
|
||||
mo = node->m_thing;
|
||||
mo->floorz = P_FloorzAtPos(mo->x, mo->y, mo->z, mo->height);
|
||||
mo->ceilingz = P_CeilingzAtPos(mo->x, mo->y, mo->z, mo->height);
|
||||
node = node->m_thinglist_next;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// T_NoEnemiesThinker
|
||||
//
|
||||
@@ -3072,6 +3086,7 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover)
|
||||
// no longer exists (can't collide with again)
|
||||
rover->flags &= ~FF_EXISTS;
|
||||
rover->master->frontsector->moved = true;
|
||||
T_UpdateMobjPlaneZ(sec); // prevent objects from floating
|
||||
sec->moved = true;
|
||||
}
|
||||
|
||||
|
||||
+8
-116
@@ -288,43 +288,12 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
if (special->flags & MF_BOSS && special->flags2 & MF2_FRET)
|
||||
return;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUAh_TouchSpecial(special, toucher) || P_MobjWasRemoved(special))
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (special->flags & MF_BOSS)
|
||||
{
|
||||
/*if (special->type == MT_BLACKEGGMAN)
|
||||
{
|
||||
P_DamageMobj(toucher, special, special, 1); // ouch
|
||||
return;
|
||||
}
|
||||
|
||||
if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING))
|
||||
|| (player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING))
|
||||
|| player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object?
|
||||
{
|
||||
if (P_MobjFlip(toucher)*toucher->momz < 0)
|
||||
toucher->momz = -toucher->momz;
|
||||
toucher->momx = -toucher->momx;
|
||||
toucher->momy = -toucher->momy;
|
||||
P_DamageMobj(special, toucher, toucher, 1);
|
||||
}
|
||||
else if (((toucher->z < special->z && !(toucher->eflags & MFE_VERTICALFLIP))
|
||||
|| (toucher->z + toucher->height > special->z + special->height && (toucher->eflags & MFE_VERTICALFLIP)))
|
||||
&& player->charability == CA_FLY
|
||||
&& (player->powers[pw_tailsfly]
|
||||
|| (toucher->state >= &states[S_PLAY_SPC1] && toucher->state <= &states[S_PLAY_SPC4]))) // Tails can shred stuff with his propeller.
|
||||
{
|
||||
toucher->momz = -toucher->momz/2;
|
||||
|
||||
P_DamageMobj(special, toucher, toucher, 1);
|
||||
}
|
||||
// SRB2kart - Removed: No more fly states
|
||||
else*/
|
||||
P_DamageMobj(toucher, special, special, 1);
|
||||
|
||||
P_DamageMobj(toucher, special, special, 1);
|
||||
return;
|
||||
}
|
||||
else if ((special->flags & MF_ENEMY) && !(special->flags & MF_MISSILE)
|
||||
@@ -2163,10 +2132,8 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
||||
target->flags2 &= ~(MF2_SKULLFLY|MF2_NIGHTSPULL);
|
||||
target->health = 0; // This makes it easy to check if something's dead elsewhere.
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUAh_MobjDeath(target, inflictor, source) || P_MobjWasRemoved(target))
|
||||
return;
|
||||
#endif
|
||||
|
||||
// SRB2kart
|
||||
// I wish I knew a better way to do this
|
||||
@@ -3129,11 +3096,7 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN
|
||||
boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage)
|
||||
{
|
||||
player_t *player;
|
||||
#ifdef HAVE_BLUA
|
||||
boolean force = false;
|
||||
#else
|
||||
static const boolean force = false;
|
||||
#endif
|
||||
|
||||
if (objectplacing)
|
||||
return false;
|
||||
@@ -3153,19 +3116,19 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
// Everything above here can't be forced.
|
||||
if (!metalrecording)
|
||||
{
|
||||
UINT8 shouldForce = LUAh_ShouldDamage(target, inflictor, source, damage);
|
||||
if (P_MobjWasRemoved(target))
|
||||
return (shouldForce == 1); // mobj was removed
|
||||
if (P_MobjWasRemoved(source))
|
||||
source = NULL;
|
||||
if (shouldForce == 1)
|
||||
force = true;
|
||||
else if (shouldForce == 2)
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!force)
|
||||
{
|
||||
@@ -3199,10 +3162,8 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||
if (!force && target->fuse) // Invincible
|
||||
return false;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUAh_MobjDamage(target, inflictor, source, damage) || P_MobjWasRemoved(target))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
if (target->health > 1)
|
||||
{
|
||||
@@ -3227,21 +3188,17 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||
if (!force && target->flags2 & MF2_FRET) // Currently flashing from being hit
|
||||
return false;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUAh_MobjDamage(target, inflictor, source, damage) || P_MobjWasRemoved(target))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
if (target->health > 1)
|
||||
target->flags2 |= MF2_FRET;
|
||||
}
|
||||
#ifdef HAVE_BLUA
|
||||
else if (target->flags & MF_ENEMY)
|
||||
{
|
||||
if (LUAh_MobjDamage(target, inflictor, source, damage) || P_MobjWasRemoved(target))
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
player = target->player;
|
||||
|
||||
@@ -3267,18 +3224,16 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||
|| (G_GametypeHasTeams() && target->player->ctfteam == source->player->ctfteam)))
|
||||
return false; // Don't run eachother over in special stages and team games and such
|
||||
}
|
||||
#ifdef HAVE_BLUA
|
||||
|
||||
if (LUAh_MobjDamage(target, inflictor, source, damage))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
P_NiGHTSDamage(target, source); // -5s :(
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef HAVE_BLUA // Add this back here for ACTUAL NORMAL DAMAGE. The funny shit is that the player is barely ever "actually" damaged.
|
||||
if (LUAh_MobjDamage(target, inflictor, source, damage))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
if (!force && inflictor && (inflictor->flags & MF_FIRE))
|
||||
{
|
||||
@@ -3341,72 +3296,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/* // SRB2kart - don't need these
|
||||
else if (metalrecording)
|
||||
{
|
||||
if (!inflictor)
|
||||
inflictor = source;
|
||||
if (inflictor && inflictor->flags & MF_ENEMY)
|
||||
{ // Metal Sonic destroy enemy !!
|
||||
P_KillMobj(inflictor, NULL, target);
|
||||
return false;
|
||||
}
|
||||
else if (inflictor && inflictor->flags & MF_MISSILE)
|
||||
return false; // Metal Sonic walk through flame !!
|
||||
else
|
||||
{ // Oh no! Metal Sonic is hit !!
|
||||
P_ShieldDamage(player, inflictor, source, damage);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (player->powers[pw_invulnerability] || player->powers[pw_flashing] // ignore bouncing & such in invulnerability
|
||||
|| (player->powers[pw_super] && !(ALL7EMERALDS(player->powers[pw_emeralds]) && inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player))))
|
||||
{
|
||||
if (force || (inflictor && (inflictor->flags & MF_MISSILE)
|
||||
&& (inflictor->flags2 & MF2_SUPERFIRE)
|
||||
&& player->powers[pw_super]))
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
if (!LUAh_MobjDamage(target, inflictor, source, damage))
|
||||
#endif
|
||||
P_SuperDamage(player, inflictor, source, damage);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
#ifdef HAVE_BLUA
|
||||
else if (LUAh_MobjDamage(target, inflictor, source, damage))
|
||||
return true;
|
||||
#endif
|
||||
else if (!player->powers[pw_super] && (player->powers[pw_shield] || player->bot)) //If One-Hit Shield
|
||||
{
|
||||
P_ShieldDamage(player, inflictor, source, damage);
|
||||
damage = 0;
|
||||
}
|
||||
else if (player->mo->health > 1) // No shield but have rings.
|
||||
{
|
||||
damage = player->mo->health - 1;
|
||||
P_RingDamage(player, inflictor, source, damage);
|
||||
}
|
||||
else // No shield, no rings, no invincibility.
|
||||
{
|
||||
// To reduce griefing potential, don't allow players to be killed
|
||||
// by friendly fire. Spilling their rings and other items is enough.
|
||||
if (force || !(G_GametypeHasTeams()
|
||||
&& source && source->player && (source->player->ctfteam == player->ctfteam)
|
||||
&& cv_friendlyfire.value))
|
||||
{
|
||||
damage = 1;
|
||||
P_KillPlayer(player, source, damage);
|
||||
}
|
||||
else
|
||||
{
|
||||
damage = 0;
|
||||
P_ShieldDamage(player, inflictor, source, damage);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if (inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player) && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))
|
||||
{
|
||||
@@ -3485,6 +3374,9 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||
P_SetMobjState(target, target->info->painstate);
|
||||
break;
|
||||
}
|
||||
|
||||
if (P_MobjWasRemoved(target))
|
||||
return false;
|
||||
|
||||
if (!P_MobjWasRemoved(target))
|
||||
{
|
||||
|
||||
Loaded 100 of 153 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user