3 * Iter Vehemens ad Necem (IVAN)
4 * Copyright (C) Timo Kiviluoto
5 * Released under the GNU General
8 * See LICENSING which should be included
9 * along with this file for more details
12 #include "ivancommon.h"
29 ////////////////////////////////////////////////////////////////////////////////
30 #define PUSH_BACK(_c) (*ress)[dpos++] = (_c)
31 #define DECODE_TUPLE(tuple,bytes) \
32 for (tmp = bytes; tmp > 0; tmp--, tuple = (tuple & 0x00ffffff)<<8) \
33 PUSH_BACK((char)((tuple >> 24)&0xff))
35 // returns ress length
36 static int ascii85Decode (char **ress
, const char *srcs
/*, int start, int length*/) {
37 static uint32_t pow85
[5] = { 85*85*85*85UL, 85*85*85UL, 85*85UL, 85UL, 1UL };
38 const uint8_t *data
= (const uint8_t *)srcs
;
39 int len
= strlen(srcs
);
43 int start
= 0, length
= len
;
46 if (start
< 0) start
= 0; else { len
-= start
; data
+= start
; }
47 if (length
< 0 || len
< length
) length
= len
;
50 int xlen = 4*((length+4)/5);
51 kstringReserve(ress, xlen);
55 *ress
= (char *)calloc(1, len
+1);
56 for (int f
= length
; f
> 0; --f
, ++data
) {
58 if (c
<= ' ') continue; // skip blanks
60 case 'z': // zero tuple
62 //xdlog("%s: z inside ascii85 5-tuple\n", file);
72 case '~': // '~>': end of sequence
73 if (f
< 1 || data
[1] != '>') { free(*ress
); return -2; } // error
74 if (count
> 0) { f
= -1; break; }
76 if (c
< '!' || c
> 'u') {
77 //xdlog("%s: bad character in ascii85 region: %#o\n", file, c);
81 tuple
+= ((uint8_t)(c
-'!'))*pow85
[count
++];
83 DECODE_TUPLE(tuple
, 4);
90 // write last (possibly incomplete) tuple
92 tuple
+= pow85
[count
];
93 DECODE_TUPLE(tuple
, count
);
102 static void decodeBA (char *str
, int len
) {
105 for (int f
= 0; f
< len
; ++f
, ++str
) {
115 static void printEC (const char *txt
) {
119 if ((len
= ascii85Decode(&dest
, txt
)) >= 0) {
121 fprintf(stderr
, "%s\n", dest
);
127 static int isStr85Equ (const char *txt
, const char *str
) {
131 if ((len
= ascii85Decode(&dest
, txt
)) >= 0) {
132 res
= (strcmp(dest
+1, str
) == 0); // +1 to ignore '/'
139 static int checkEGG (const char *str
) {
140 if (isStr85Equ("06:]JASq", str
) || isStr85Equ("0/i", str
)) {
142 "H8lZV&6)1>+AZ>m)Cf8;A1/cP+CnS)0OJ`X.QVcHA4^cc5r3=m1c%0D3&c263d?EV6@4&>"
143 "3DYQo;c-FcO+UJ;MOJ$TAYO@/FI]+B?C.L$>%:oPAmh:4Au)>AAU/H;ZakL2I!*!%J;(AK"
144 "NIR#5TXgZ6c'F1%^kml.JW5W8e;ql0V3fQUNfKpng6ppMf&ip-VOX@=jKl;#q\"DJ-_>jG"
145 "8#L;nm]!q;7c+hR6p;tVY#J8P$aTTK%c-OT?)<00,+q*8f&ff9a/+sbU,:`<H*[fk0o]7k"
146 "^l6nRkngc6Tl2Ngs!!P2I%KHG=7n*an'bsgn>!*8s7TLTC+^\\\"W+<=9^%Ol$1A1eR*Be"
147 "gqjEag:M0OnrC4FBY5@QZ&'HYYZ#EHs8t4$5]!22QoJ3`;-&=\\DteO$d6FBqT0E@:iu?N"
148 "a5ePUf^_uEEcjTDKfMpX/9]DFL8N-Ee;*8C5'WgbGortZuh1\\N0;/rJB6'(MSmYiS\"6+"
149 "<NK)KDV3e+Ad[@).W:%.dd'0h=!QUhghQaNNotIZGrpHr-YfEuUpsKW<^@qlZcdTDA!=?W"
150 "Yd+-^`'G8Or)<0-T&CT.i+:mJp(+/M/nLaVb#5$p2jR2<rl7\"XlngcN`mf,[4oK5JLr\\"
151 "m=X'(ue;'*1ik&/@T4*=j5t=<&/e/Q+2=((h`>>uN(#>&#i>2/ajK+=eib1coVe3'D)*75"
152 "m_h;28^M6p6*D854Jj<C^,Q8Wd\"O<)&L/=C$lUAQNN<=eTD:A6kn-=EItXSss.tAS&!;F"
153 "EsgpJTHIYNNnh'`kmX^[`*ELOHGcWbfPOT`J]A8P`=)AS;rYlR$\"-.RG440lK5:Dg?G'2"
154 "['dE=nEm1:k,,Se_=%-6Z*L^J[)EC"
158 if (isStr85Equ("04Jj?B)", str
)) {
160 "IPaSa(`c:T,o9Bq3\\)IY++?+!-S9%P0/OkjE&f$l.OmK'Ai2;ZHn[<,6od7^8;)po:HaP"
161 "m<'+&DRS:/1L7)IA7?WI$8WKTUB2tXg>Zb$.?\"@AIAu;)6B;2_PB5M?oBPDC.F)606Z$V"
162 "=ONd6/5P*LoWKTLQ,d@&;+Ru,\\ESY*rg!l1XrhpJ:\"WKWdOg?l;=RHE:uU9C?aotBqj]"
163 "=k8cZ`rp\"ZO=GjkfD#o]Z\\=6^]+Gf&-UFthT*hN"
167 if (isStr85Equ("04o69A7Tr", str
)) {
169 "Ag7d[&R#Ma9GVV5,S(D;De<T_+W).?,%4n+3cK=%4+0VN@6d\")E].np7l?8gF#cWF7SS_m"
170 "4@V\\nQ;h!WPD2h#@\\RY&G\\LKL=eTP<V-]U)BN^b.DffHkTPnFcCN4B;]8FCqI!p1@H*_"
171 "jHJ<%g']RG*MLqCrbP*XbNL=4D1R[;I(c*<FuesbWmSCF1jTW+rplg;9[S[7eDVl6YsjT"
179 int Main (int argc
, char *argv
[]) {
180 for (int f
= 1; f
< argc
; ++f
) {
181 if (checkEGG(argv
[f
]+1)) exit(1);
184 if (argc
> 1 && (!strcmp(argv
[1], "--version") || !strcmp(argv
[1], "-v"))) {
185 std::cout
<< "Iter Vehemens ad Necem version " << IVAN_VERSION
<< std::endl
;
189 //femath::SetSeed(time(0));
192 game::LoadModuleList();
194 game::InitGlobalValueMap();
196 // some sanity checks
197 if (game::GetGlobalConst("NONE") != 0) ABORT("`NONE` is not 0");
198 if (game::GetGlobalConst("MIRROR") != 1) ABORT("`MIRROR` is not 1");
199 if (game::GetGlobalConst("FLIP") != 2) ABORT("`FLIP` is not 2");
200 if (game::GetGlobalConst("ROTATE") != 4) ABORT("`ROTATE` is not 4");
202 if (game::GetGlobalConst("GOOD") != 1) ABORT("`GOOD` is not 1");
203 if (game::GetGlobalConst("NEUTRAL") != 2) ABORT("`NEUTRAL` is not 2");
204 if (game::GetGlobalConst("EVIL") != 3) ABORT("`EVIL` is not 3");
206 if (game::GetGlobalConst("RUNED_WHIP") != 1) ABORT("`RUNED_WHIP` is not 1");
207 if (game::GetGlobalConst("CHAIN_WHIP") != 2) ABORT("`CHAIN_WHIP` is not 2");
209 if (game::GetGlobalConst("WAND_OF_POLYMORPH") != 1) ABORT("`WAND_OF_POLYMORPH` is not 1");
210 if (game::GetGlobalConst("WAND_OF_STRIKING") != 2) ABORT("`WAND_OF_STRIKING` is not 2");
212 if (game::GetGlobalConst("KHARAZ_ARAD_SHOP") != 127) ABORT("`KHARAZ_ARAD_SHOP` is not 127");
213 if (game::GetGlobalConst("UNDER_WATER_TUNNEL_EXIT") != 128) ABORT("`UNDER_WATER_TUNNEL_EXIT` is not 128");
215 if (game::GetGlobalConst("ALIEN_VESSEL") != 10) ABORT("`ALIEN_VESSEL` is not 10");
217 scriptsystem::Initialize();
218 databasesystem::Initialize();
219 game::InitLuxTable();
220 ivanconfig::Initialize();
222 game::CreateBusyAnimationCache();
223 globalwindowhandler::SetQuitMessageHandler(game::HandleQuitMessage
);
225 protosystem::Initialize();
229 int Select
= iosystem::Menu(
230 igraph::GetMenuGraphic(),
231 v2(RES
.X
/ 2, RES
.Y
/ 2 - 20),
233 CONST_S("Start Game\rContinue Game\rConfiguration\rHighscores\rQuit\r"),
235 CONST_S("Released under the GNU\rGeneral Public License\rMore info: see COPYING\r"),
236 CONST_S("IVAN v" IVAN_VERSION
"\r"),
239 case -1: return 0; // esc
242 igraph::UnLoadMenu();
249 festring LoadName
= iosystem::ContinueMenu(WHITE
, LIGHT_GRAY
, game::GetSavePath());
250 if (LoadName
.GetSize()) {
251 LoadName
.Resize(LoadName
.GetSize()-4);
252 if (game::Init(LoadName
)) {
253 igraph::UnLoadMenu();