Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
6446 | GerdtR | 1 | #define _RES_ |
2 | |||
3 | #ifdef _WIN32_ |
||
4 | #include |
||
5 | #endif |
||
6 | |||
7 | #pragma option -w-pin |
||
8 | |||
9 | #include |
||
10 | #include |
||
11 | |||
12 | #include "tok.h" |
||
13 | #include "port.h" |
||
14 | #include "res.h" |
||
15 | |||
16 | RES *listres; //таблица ресурсов |
||
17 | int numres=0; //текущее число ресурсов |
||
18 | int maxres=0; //максимальное число ресурсов |
||
19 | |||
20 | unsigned short *sortidx; //масив отсортированых индексов ресурсов |
||
21 | RES *curtres; //текущая таблица ресурсов |
||
22 | |||
23 | unsigned char *resbuf; |
||
24 | unsigned int cursizeresbuf; |
||
25 | unsigned int curposbuf=0; |
||
26 | unsigned int iconcount=0; //число иконок |
||
27 | unsigned int cursorcount=0; //число курсоров |
||
28 | unsigned int numidres; //число ресурсов с разным id |
||
29 | unsigned int numlangres=0; //число ресурсов с языками |
||
30 | unsigned int numhlangres=0; //число узлов с языками |
||
31 | unsigned short langdef=0; |
||
32 | unsigned short numzerotype=0; |
||
33 | |||
34 | _STRINGS_ *strinfo=NULL; |
||
35 | int numstrtbl=0; |
||
36 | |||
37 | struct TUSE{ |
||
38 | unsigned short id; |
||
39 | unsigned short count; |
||
40 | char *tname; //имя типа |
||
41 | }*tuse=NULL; |
||
42 | |||
43 | unsigned int numtyperes=0; //число типов ресурсов |
||
44 | |||
45 | void AddType(unsigned short type,char *tname=NULL) |
||
46 | { |
||
47 | if(tuse==NULL){ |
||
48 | tuse=(TUSE *)MALLOC(sizeof(TUSE)); |
||
49 | tuse->id=type; |
||
50 | tuse->count=1; |
||
51 | if(type==0)tuse->tname=tname; |
||
52 | numtyperes=1; |
||
53 | return; |
||
54 | } |
||
55 | for(unsigned int i=0;i |
||
56 | if(type==(tuse+i)->id){ |
||
57 | if(type==0&&stricmp(tname,(tuse+i)->tname)!=0)continue; |
||
58 | (tuse+i)->count++; |
||
59 | return; |
||
60 | } |
||
61 | } |
||
62 | tuse=(TUSE *)REALLOC(tuse,sizeof(TUSE)*(numtyperes+1)); |
||
63 | (tuse+numtyperes)->id=type; |
||
64 | (tuse+numtyperes)->count=1; |
||
65 | if(type==0)(tuse+numtyperes)->tname=tname; |
||
66 | numtyperes++; |
||
67 | } |
||
68 | |||
69 | static unsigned int idnum; |
||
70 | static char idname[IDLENGTH]; |
||
71 | static char resname[IDLENGTH]; |
||
72 | static int restok; |
||
73 | |||
74 | void InitBufRes(); //инициализировать буфер для ресурса |
||
75 | void CheckResBuf(unsigned int size); //проверить и если надо увеличить буфер |
||
76 | void AddWString(unsigned char *name); //добавить строку в ресурс |
||
77 | void AddNumOrd(unsigned char *name); //добавить ординал/строку |
||
78 | void r_Accelerators(); |
||
79 | void r_Dialog(); |
||
80 | void r_Icon(); |
||
81 | void r_Bitmap(); |
||
82 | void r_Menu(); |
||
83 | void r_Cursor(); |
||
84 | void r_Accelerators(); |
||
85 | void r_Font(); |
||
86 | void r_Stringtable(); |
||
87 | void r_Rcdata(); |
||
88 | void GetFileName(char *name); |
||
89 | unsigned char *LoadFileBin(char *name); |
||
90 | unsigned short GetFlag(_STRINGS_ *type,int num); |
||
91 | void r_Language(); |
||
92 | void r_Version(); |
||
93 | void NewResourse(); |
||
94 | |||
95 | |||
96 | void badformat(char *name) |
||
97 | { |
||
98 | char buf[80]; |
||
99 | sprintf(buf,"bad format in '%s'",name); |
||
100 | preerror(buf); |
||
101 | while(tok!=tk_endline&&tok!=tk_eof)nexttok(); |
||
102 | } |
||
103 | |||
104 | void expectedrescommand() |
||
105 | { |
||
106 | preerror("expected resourse command"); |
||
107 | while(tok!=tk_endline&&tok!=tk_eof)nexttok(); |
||
108 | } |
||
109 | |||
110 | void equalres() |
||
111 | { |
||
112 | preerror("two resource with equal 'id'"); |
||
113 | } |
||
114 | |||
115 | void badico() |
||
116 | { |
||
117 | preerror("not load binare image"); |
||
118 | while(tok!=tk_endline&&tok!=tk_eof)nexttok(); |
||
119 | } |
||
120 | |||
121 | extern int CheckResName(char *name); |
||
122 | /* |
||
123 | void SaveFile(char *name) |
||
124 | { |
||
125 | FILE *inih; |
||
126 | if((inih=fopen(name,"wb"))!=NULL){ |
||
127 | fwrite(resbuf,1,curposbuf,inih); |
||
128 | fclose(inih); |
||
129 | } |
||
130 | } */ |
||
131 | |||
132 | void input_res() |
||
133 | { |
||
134 | scanlexmode=RESLEX; |
||
135 | nexttok(); |
||
136 | while(tok!=tk_eof){ |
||
137 | while(tok==tk_semicolon||tok==tk_endline)nexttok(); |
||
138 | while(tok==tk_question){ |
||
139 | directive();//обработка директив |
||
140 | while(tok==tk_semicolon||tok==tk_endline)nexttok(); |
||
141 | } |
||
142 | if(scanlexmode!=RESLEX||tok==tk_eof)break; |
||
143 | idname[0]=0; |
||
144 | resname[0]=0; |
||
145 | idnum=0; |
||
146 | restok=-1; |
||
147 | switch(tok){ |
||
148 | case tk_number: |
||
149 | idnum=itok.number; |
||
150 | nexttok(); |
||
151 | break; |
||
152 | case tk_id: |
||
153 | case tk_ID: |
||
154 | strcpy(idname,itok.name); |
||
155 | strupr(idname); |
||
156 | nexttok(); |
||
157 | break; |
||
158 | case tk_rescommand: |
||
159 | restok=itok.number; |
||
160 | nexttok(); |
||
161 | break; |
||
162 | default: |
||
163 | // printf("line %u: tok=%u\n",linenumber,tok); |
||
164 | unuseableinput(); break; |
||
165 | } |
||
166 | if(restok==-1){ |
||
167 | if(tok==tk_number)restok=CRT_NEWRESOURCE; |
||
168 | else if(tok!=tk_rescommand){ |
||
169 | if(strlen(itok.name)/*&&tok2==tk_string*/){ |
||
170 | restok=0; |
||
171 | strcpy(resname,itok.name); |
||
172 | nexttok(); |
||
173 | NewResourse(); |
||
174 | continue; |
||
175 | } |
||
176 | expectedrescommand(); |
||
177 | } |
||
178 | else{ |
||
179 | restok=itok.number; |
||
180 | nexttok(); |
||
181 | } |
||
182 | } |
||
183 | switch(restok){ |
||
184 | case rc_accelerators: |
||
185 | r_Accelerators(); |
||
186 | break; |
||
187 | case rc_dialogex: |
||
188 | case rc_dialog: |
||
189 | r_Dialog(); |
||
190 | break; |
||
191 | case rc_icon: |
||
192 | r_Icon(); |
||
193 | break; |
||
194 | case rc_bitmap: |
||
195 | r_Bitmap(); |
||
196 | break; |
||
197 | case rc_menuex: |
||
198 | case rc_menu: |
||
199 | r_Menu(); |
||
200 | break; |
||
201 | case rc_cursor: |
||
202 | r_Cursor(); |
||
203 | break; |
||
204 | case rc_font: |
||
205 | r_Font(); |
||
206 | break; |
||
207 | case rc_stringtable: |
||
208 | r_Stringtable(); |
||
209 | break; |
||
210 | case rc_rcdata: |
||
211 | r_Rcdata(); |
||
212 | break; |
||
213 | case rc_language: |
||
214 | r_Language(); |
||
215 | break; |
||
216 | case rc_versioninfo: |
||
217 | r_Version(); |
||
218 | break; |
||
219 | case CRT_NEWRESOURCE: |
||
220 | restok=itok.number; |
||
221 | nexttok(); |
||
222 | NewResourse(); |
||
223 | break; |
||
224 | default: |
||
225 | expectedrescommand(); |
||
226 | nexttok(); |
||
227 | break; |
||
228 | } |
||
229 | } |
||
230 | } |
||
231 | |||
232 | void GetResBlock() |
||
233 | { |
||
234 | if(numres==0){ |
||
235 | maxres=DRESNUM; |
||
236 | listres=(RES *)MALLOC(DRESNUM*sizeof(RES)); |
||
237 | memset(listres,0,DRESNUM*sizeof(RES));//очистить таблицу |
||
238 | } |
||
239 | else{ |
||
240 | if((numres+1)==maxres){ |
||
241 | listres=(RES *)REALLOC(listres,sizeof(RES)*(maxres+DRESNUM)); |
||
242 | memset(listres+maxres,0,DRESNUM*sizeof(RES));//очистить таблицу |
||
243 | maxres+=DRESNUM; |
||
244 | } |
||
245 | } |
||
246 | curtres=listres+numres; |
||
247 | curtres->lang=langdef; |
||
248 | numres++; |
||
249 | } |
||
250 | |||
251 | int OpenBlock() |
||
252 | { |
||
253 | while(tok==tk_endline)nexttok(); |
||
254 | if(tok==tk_openbrace||(tok==tk_rescommand&&itok.number==rc_begin)){ |
||
255 | nexttok(); |
||
256 | while(tok==tk_endline)nexttok(); |
||
257 | return TRUE; |
||
258 | } |
||
259 | return FALSE; |
||
260 | } |
||
261 | |||
262 | int CloseBlock() |
||
263 | { |
||
264 | while(tok==tk_endline)nexttok(); |
||
265 | if(tok==tk_closebrace||(tok==tk_rescommand&&itok.number==rc_end)){ |
||
266 | nexttok(); |
||
267 | while(tok==tk_endline)nexttok(); |
||
268 | return TRUE; |
||
269 | } |
||
270 | return FALSE; |
||
271 | } |
||
272 | |||
273 | unsigned int GetNumber(int par) |
||
274 | { |
||
275 | unsigned int num=0; |
||
276 | if(tok==tk_number||(tok==tk_minus&&tok2==tk_number))num=doconstdwordmath(); |
||
277 | else{ |
||
278 | numexpected(par); |
||
279 | nexttok(); |
||
280 | } |
||
281 | return num; |
||
282 | } |
||
283 | |||
284 | void GetOrdinal(unsigned char **name,int par) |
||
285 | { |
||
286 | NameOrdinal Temp; |
||
287 | if(tok==tk_number){ |
||
288 | Temp.ordinal[0]=0xffff; |
||
289 | Temp.ordinal[1]=(unsigned short)doconstdwordmath(); |
||
290 | } |
||
291 | else if(tok==tk_string){ |
||
292 | Temp.name=(unsigned char *)BackString((char *)string); |
||
293 | nexttok(); |
||
294 | } |
||
295 | else numexpected(par); |
||
296 | *name=Temp.name; |
||
297 | } |
||
298 | |||
299 | void GetRectangle(unsigned char *buf,int par) |
||
300 | { |
||
301 | int i; |
||
302 | for(i=0;i<4;){ |
||
303 | *(unsigned short *)&buf[i*2]=(unsigned short)GetNumber(i+par); |
||
304 | i++; |
||
305 | if(tok==tk_endline)break; |
||
306 | expecting(tk_camma); |
||
307 | } |
||
308 | if(i!=4)preerror("expecting window rectangle (4 signed integers)"); |
||
309 | } |
||
310 | |||
311 | void AddWString(unsigned char *name) |
||
312 | { |
||
313 | unsigned int pos; |
||
314 | //unsigned char c; |
||
315 | if(name==NULL){ |
||
316 | CheckResBuf(2); |
||
317 | curposbuf+=2; |
||
318 | } |
||
319 | else{ |
||
320 | pos=(strlen((char *)name)+1)*3; |
||
321 | CheckResBuf(pos); |
||
322 | pos=MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,(char *)name,-1,(wchar_t *)&resbuf[curposbuf],pos); |
||
323 | curposbuf+=pos*2; |
||
324 | } |
||
325 | } |
||
326 | |||
327 | void AddNumOrd(unsigned char *name) |
||
328 | { |
||
329 | NameOrdinal Temp; |
||
330 | Temp.name=name; |
||
331 | if(Temp.ordinal[0]==0xFFFF){ |
||
332 | CheckResBuf(4); |
||
333 | *(unsigned short *)&resbuf[curposbuf]=Temp.ordinal[0]; |
||
334 | *(unsigned short *)&resbuf[curposbuf+2]=Temp.ordinal[1]; |
||
335 | curposbuf+=4; |
||
336 | } |
||
337 | else AddWString(name); |
||
338 | } |
||
339 | |||
340 | void InitBufRes() |
||
341 | { |
||
342 | resbuf=(unsigned char *)MALLOC(SIZERESBUF); |
||
343 | memset(resbuf,0,SIZERESBUF);//очистить таблицу |
||
344 | curposbuf=0; |
||
345 | cursizeresbuf=SIZERESBUF; |
||
346 | } |
||
347 | |||
348 | void CheckResBuf(unsigned int size) |
||
349 | { |
||
350 | while((size+curposbuf)>=cursizeresbuf){ |
||
351 | resbuf=(unsigned char *)REALLOC(resbuf,cursizeresbuf+SIZERESBUF); |
||
352 | memset(resbuf+cursizeresbuf,0,SIZERESBUF);//очистить таблицу |
||
353 | cursizeresbuf+=SIZERESBUF; |
||
354 | } |
||
355 | } |
||
356 | |||
357 | void FreeOrdinal(unsigned char *name) |
||
358 | { |
||
359 | NameOrdinal Temp; |
||
360 | if(name){ |
||
361 | Temp.name=name; |
||
362 | if(Temp.ordinal[0]!=0xFFFF)free(name); |
||
363 | } |
||
364 | } |
||
365 | |||
366 | unsigned short GetFlag(_STRINGS_ *type,int num) |
||
367 | { |
||
368 | for(int i=0;i |
||
369 | if(stricmp(itok.name,(type+i)->id)==0){ |
||
370 | return (type+i)->val; |
||
371 | } |
||
372 | } |
||
373 | return 0; |
||
374 | } |
||
375 | |||
376 | void r_Language() |
||
377 | { |
||
378 | unsigned short langsec; |
||
379 | langdef=(unsigned short)GetNumber(1); |
||
380 | expecting(tk_camma); |
||
381 | langsec=(unsigned short)GetNumber(2)*langdef*256; |
||
382 | langdef|=langsec; |
||
383 | while(tok!=tk_endline&&tok!=tk_eof)nexttok(); |
||
384 | } |
||
385 | |||
386 | void r_Stringtable() |
||
387 | { |
||
388 | #define MAXSTRTABINFO 64 |
||
389 | static int maxstrinf=MAXSTRTABINFO; |
||
390 | int num; |
||
391 | int j; |
||
392 | if(strinfo==NULL)strinfo=(_STRINGS_ *)MALLOC(sizeof(_STRINGS_)*MAXSTRTABINFO); |
||
393 | while(tok!=tk_endline&&tok!=tk_eof)nexttok(); |
||
394 | if(!OpenBlock())badformat("STRINGTABLE"); //добавить новую |
||
395 | do{ |
||
396 | num=GetNumber(1); |
||
397 | for(j=0;j |
||
398 | if(num==(strinfo+j)->val)preerror("String ID is already used"); |
||
399 | } |
||
400 | (strinfo+numstrtbl)->val=(short)num; |
||
401 | if(tok==tk_camma)nexttok(); |
||
402 | if(tok!=tk_string)badformat("STRINGTABLE"); |
||
403 | (strinfo+numstrtbl)->id=BackString((char *)string); |
||
404 | nexttok(); |
||
405 | numstrtbl++; |
||
406 | if(numstrtbl>=maxstrinf){ |
||
407 | maxstrinf+=MAXSTRTABINFO; |
||
408 | strinfo=(_STRINGS_ *)REALLOC(strinfo,maxstrinf*sizeof(_STRINGS_)); |
||
409 | } |
||
410 | }while(!CloseBlock()&&tok!=tk_eof); |
||
411 | } |
||
412 | |||
413 | void CreatStrTabRes() |
||
414 | { |
||
415 | unsigned int i,num,j; |
||
416 | int idnum=0; |
||
417 | int usesec; |
||
418 | for(i=0;i<65536;){ |
||
419 | idnum++; |
||
420 | usesec=FALSE; |
||
421 | for(int ii=0;ii<16;ii++,i++){ |
||
422 | for(j=0;j |
||
423 | if(i==(strinfo+j)->val){ |
||
424 | if(usesec==FALSE){ |
||
425 | usesec=TRUE; |
||
426 | InitBufRes(); |
||
427 | curposbuf=ii*2; |
||
428 | } |
||
429 | char *name=(strinfo+j)->id; |
||
430 | *(unsigned short *)&resbuf[curposbuf]=(unsigned short)strlen(name); |
||
431 | curposbuf+=2; |
||
432 | AddWString((unsigned char *)name); |
||
433 | free(name); |
||
434 | curposbuf-=4; |
||
435 | break; |
||
436 | } |
||
437 | } |
||
438 | curposbuf+=2; |
||
439 | } |
||
440 | if(usesec){ |
||
441 | GetResBlock(); |
||
442 | curtres->type=CRT_STRING; |
||
443 | AddType(CRT_STRING); |
||
444 | curtres->res=(unsigned char *)REALLOC(resbuf,curposbuf); |
||
445 | curtres->size=curposbuf; |
||
446 | curtres->id=idnum; |
||
447 | } |
||
448 | } |
||
449 | free(strinfo); |
||
450 | } |
||
451 | |||
452 | void domenu(unsigned int exts) |
||
453 | { |
||
454 | unsigned char *name; |
||
455 | unsigned int lastpos; |
||
456 | unsigned long help; |
||
457 | if(OpenBlock()){ |
||
458 | do{ |
||
459 | if(tok!=tk_rescommand)badformat("MENU"); |
||
460 | lastpos=(exts==TRUE?curposbuf+12:curposbuf); |
||
461 | CheckResBuf(18); |
||
462 | restok=itok.number; |
||
463 | nexttok(); |
||
464 | switch(restok){ |
||
465 | case rc_menuitem: |
||
466 | if(tok==tk_string){ |
||
467 | name=(unsigned char *)BackString((char *)string); |
||
468 | nexttok(); |
||
469 | if(tok==tk_camma){ |
||
470 | nexttok(); |
||
471 | if(exts){ |
||
472 | if(tok!=tk_camma)*(unsigned long *)&resbuf[curposbuf+8]=GetNumber(2); |
||
473 | if(tok==tk_camma){ |
||
474 | nexttok(); |
||
475 | if(tok!=tk_camma)*(unsigned long *)&resbuf[curposbuf]=GetNumber(3); |
||
476 | if(tok==tk_camma){ |
||
477 | do{ |
||
478 | nexttok(); |
||
479 | if(tok==tk_number)*(unsigned long *)&resbuf[curposbuf+4]|=itok.number; |
||
480 | else *(unsigned long *)&resbuf[curposbuf+4]|=GetFlag((_STRINGS_ *)&typemenu,NUMMENUPOPUP); |
||
481 | nexttok(); |
||
482 | }while(tok==tk_or); |
||
483 | } |
||
484 | } |
||
485 | } |
||
486 | else{ |
||
487 | if(tok!=tk_camma)*(unsigned short *)&resbuf[curposbuf+2]=(unsigned short)GetNumber(2); |
||
488 | if(tok==tk_camma){ |
||
489 | do{ |
||
490 | nexttok(); |
||
491 | if(tok==tk_number)*(unsigned short *)&resbuf[curposbuf]|=(unsigned short)itok.number; |
||
492 | else *(unsigned short *)&resbuf[curposbuf]|=GetFlag((_STRINGS_ *)&typemenu,NUMMENUPOPUP); |
||
493 | nexttok(); |
||
494 | }while(tok==tk_or||tok==tk_camma); |
||
495 | } |
||
496 | } |
||
497 | } |
||
498 | curposbuf+=(exts==FALSE?4:14); |
||
499 | AddWString(name); |
||
500 | if(exts){ |
||
501 | CheckResBuf(2); |
||
502 | curposbuf=Align(curposbuf,4); |
||
503 | } |
||
504 | free(name); |
||
505 | } |
||
506 | else if(stricmp(itok.name,"SEPARATOR")==0){ |
||
507 | if(exts){ |
||
508 | *(unsigned long *)&resbuf[curposbuf]=0x800; |
||
509 | curposbuf+=16; |
||
510 | } |
||
511 | else curposbuf+=6; |
||
512 | nexttok(); |
||
513 | } |
||
514 | else badformat("MENU"); |
||
515 | break; |
||
516 | case rc_popup: |
||
517 | help=0; |
||
518 | if(tok!=tk_string)badformat("MENU"); |
||
519 | name=(unsigned char *)BackString((char *)string); |
||
520 | *(unsigned short *)&resbuf[lastpos]=(exts==FALSE?0x10:1); |
||
521 | nexttok(); |
||
522 | if(tok==tk_camma){ |
||
523 | if(exts){ |
||
524 | nexttok(); |
||
525 | if(tok!=tk_camma)*(unsigned long *)&resbuf[curposbuf+8]=GetNumber(2); |
||
526 | if(tok==tk_camma){ |
||
527 | nexttok(); |
||
528 | if(tok!=tk_camma)*(unsigned long *)&resbuf[curposbuf]=GetNumber(3); |
||
529 | if(tok==tk_camma){ |
||
530 | do{ |
||
531 | nexttok(); |
||
532 | if(tok==tk_number)*(unsigned long *)&resbuf[curposbuf+4]|=itok.number; |
||
533 | else *(unsigned long *)&resbuf[curposbuf+4]|=GetFlag((_STRINGS_ *)&typemenu,NUMMENUPOPUP); |
||
534 | nexttok(); |
||
535 | }while(tok==tk_or); |
||
536 | } |
||
537 | if(tok==tk_camma){ |
||
538 | nexttok(); |
||
539 | help=GetNumber(5); |
||
540 | } |
||
541 | } |
||
542 | } |
||
543 | else{ |
||
544 | do{ |
||
545 | nexttok(); |
||
546 | if(tok==tk_number)*(unsigned short *)&resbuf[curposbuf]|=(unsigned short)itok.number; |
||
547 | else *(unsigned short *)&resbuf[curposbuf]|=GetFlag((_STRINGS_ *)&typemenu,NUMMENUPOPUP); |
||
548 | nexttok(); |
||
549 | }while(tok==tk_or); |
||
550 | } |
||
551 | } |
||
552 | curposbuf+=(exts==FALSE?2:14); |
||
553 | AddWString(name); |
||
554 | if(exts){ |
||
555 | CheckResBuf(6); |
||
556 | curposbuf=Align(curposbuf,4); |
||
557 | *(unsigned long *)&resbuf[curposbuf]=help; |
||
558 | curposbuf+=4; |
||
559 | } |
||
560 | if(name)free(name); |
||
561 | domenu(exts); |
||
562 | break; |
||
563 | default: |
||
564 | badformat("MENU"); |
||
565 | break; |
||
566 | } |
||
567 | }while(!CloseBlock()&&tok!=tk_eof); |
||
568 | resbuf[lastpos]|=0x80; |
||
569 | } |
||
570 | else badformat("MENU"); |
||
571 | } |
||
572 | |||
573 | void r_Menu() |
||
574 | { |
||
575 | unsigned int exts=FALSE; |
||
576 | if(restok==rc_menuex)exts=TRUE; |
||
577 | GetResBlock(); |
||
578 | curtres->type=CRT_MENU; |
||
579 | if(idname[0]==0)curtres->id=idnum; |
||
580 | else curtres->name=BackString(idname); |
||
581 | AddType(CRT_MENU); |
||
582 | InitBufRes(); |
||
583 | while(tok!=tk_endline)nexttok(); |
||
584 | if(tok==tk_rescommand&&itok.number==rc_language){ |
||
585 | unsigned short olang; |
||
586 | olang=langdef; |
||
587 | nexttok(); |
||
588 | r_Language(); |
||
589 | curtres->lang=langdef; |
||
590 | langdef=olang; |
||
591 | } |
||
592 | if(exts){ |
||
593 | *(unsigned long *)&resbuf[0]=0x00040001; |
||
594 | curposbuf=8; |
||
595 | } |
||
596 | else curposbuf=4; |
||
597 | domenu(exts); |
||
598 | curtres->res=(unsigned char *)REALLOC(resbuf,curposbuf); |
||
599 | curtres->size=curposbuf; |
||
600 | } |
||
601 | |||
602 | void r_Rcdata() |
||
603 | { |
||
604 | GetResBlock(); |
||
605 | curtres->type=CRT_RCDATA; |
||
606 | if(idname[0]==0)curtres->id=idnum; |
||
607 | else curtres->name=BackString(idname); |
||
608 | AddType(CRT_RCDATA); |
||
609 | char name[256]; |
||
610 | name[0]=0; |
||
611 | GetFileName(name); |
||
612 | if(name[0]!=0)resbuf=LoadFileBin(name); |
||
613 | else if(tok==tk_string)resbuf=LoadFileBin((char *)string); |
||
614 | else{ |
||
615 | InitBufRes(); |
||
616 | if(!OpenBlock())badformat("RCDATA"); |
||
617 | do{ |
||
618 | if(tok==tk_number||(tok==tk_minus&&tok2==tk_number)){ |
||
619 | CheckResBuf(2); |
||
620 | *(unsigned short *)&resbuf[curposbuf]=(unsigned short)GetNumber(0); |
||
621 | curposbuf+=2; |
||
622 | } |
||
623 | else if(tok==tk_string){ |
||
624 | CheckResBuf(itok.number); |
||
625 | for(int i=0;i |
||
626 | nexttok(); |
||
627 | } |
||
628 | else if(tok==tk_id||tok==tk_ID){ |
||
629 | CheckResBuf(strlen(itok.name)); |
||
630 | unsigned char c; |
||
631 | int j=0; |
||
632 | for(;;){ |
||
633 | c=itok.name[j++]; |
||
634 | if(c==0)break; |
||
635 | resbuf[curposbuf++]=c; |
||
636 | } |
||
637 | nexttok(); |
||
638 | } |
||
639 | if(tok==tk_rescommand&&itok.number==rc_characteristics){ |
||
640 | nexttok(); |
||
641 | CheckResBuf(4); |
||
642 | *(unsigned long *)&resbuf[curposbuf]=GetNumber(0); |
||
643 | curposbuf+=4; |
||
644 | } |
||
645 | else badformat("RCDATA"); |
||
646 | if(tok==tk_camma||tok==tk_semicolon)nexttok(); |
||
647 | }while(!CloseBlock()&&tok!=tk_eof); |
||
648 | } |
||
649 | curtres->res=(unsigned char *)REALLOC(resbuf,curposbuf); |
||
650 | curtres->size=curposbuf; |
||
651 | } |
||
652 | |||
653 | void GetVersPar(unsigned char *buf) |
||
654 | { |
||
655 | nexttok(); |
||
656 | *(unsigned short *)&buf[2]=(unsigned short)GetNumber(1); |
||
657 | expecting(tk_camma); |
||
658 | *(unsigned short *)&buf[0]=(unsigned short)GetNumber(2); |
||
659 | expecting(tk_camma); |
||
660 | *(unsigned short *)&buf[6]=(unsigned short)GetNumber(3); |
||
661 | expecting(tk_camma); |
||
662 | *(unsigned short *)&buf[4]=(unsigned short)GetNumber(4); |
||
663 | } |
||
664 | |||
665 | void GetBlockInfo() |
||
666 | { |
||
667 | int startpos; |
||
668 | do{ |
||
669 | startpos=curposbuf; |
||
670 | CheckResBuf(6); |
||
671 | curposbuf+=6; |
||
672 | if(stricmp("BLOCK",itok.name)==0){ |
||
673 | nexttok(); |
||
674 | if(tok!=tk_string)stringexpected(); |
||
675 | CheckResBuf((itok.number+1)*2+2); |
||
676 | AddWString((unsigned char *)string); |
||
677 | curposbuf=Align(curposbuf,4); |
||
678 | nexttok(); |
||
679 | if(OpenBlock())GetBlockInfo(); |
||
680 | else badformat("VERSIONINFO"); |
||
681 | } |
||
682 | else if(stricmp("VALUE",itok.name)==0){ |
||
683 | nexttok(); |
||
684 | if(tok!=tk_string)stringexpected(); |
||
685 | CheckResBuf((itok.number+1)*2+2); |
||
686 | AddWString((unsigned char *)string); |
||
687 | curposbuf=Align(curposbuf,4); |
||
688 | nexttok(); |
||
689 | if(tok2==tk_string){ |
||
690 | expecting(tk_camma); |
||
691 | CheckResBuf((itok.number+1)*2+2); |
||
692 | AddWString((unsigned char *)string); |
||
693 | *(unsigned short *)&resbuf[startpos+4]=1; |
||
694 | *(unsigned short *)&resbuf[startpos+2]=(unsigned short)itok.number; |
||
695 | nexttok(); |
||
696 | } |
||
697 | else{ |
||
698 | do{ |
||
699 | nexttok(); |
||
700 | CheckResBuf(4); |
||
701 | *(unsigned short *)&resbuf[curposbuf]=(unsigned short)GetNumber(0); |
||
702 | curposbuf+=2; |
||
703 | *(unsigned short *)&resbuf[startpos+2]+=2; |
||
704 | }while(tok==tk_camma); |
||
705 | // nexttok(); |
||
706 | } |
||
707 | } |
||
708 | else badformat("VERSIONINFO"); |
||
709 | *(unsigned short *)&resbuf[startpos]=(unsigned short)(curposbuf-startpos); |
||
710 | curposbuf=Align(curposbuf,4); |
||
711 | }while(CloseBlock()==FALSE); |
||
712 | } |
||
713 | |||
714 | void r_Version() |
||
715 | { |
||
716 | GetResBlock(); |
||
717 | InitBufRes(); |
||
718 | curtres->type=CRT_VERSION; |
||
719 | curtres->id=1; |
||
720 | AddType(CRT_VERSION); |
||
721 | *(unsigned short *)&resbuf[2]=0x34; |
||
722 | // if(idname[0]==0)stringexpected(); |
||
723 | if(idname[0]==0)curtres->id=idnum; |
||
724 | else curtres->name=BackString(idname); |
||
725 | curposbuf=6; |
||
726 | AddWString((unsigned char *)"VS_VERSION_INFO"); |
||
727 | curposbuf=Align(curposbuf,4); |
||
728 | *(unsigned long *)&resbuf[curposbuf]=0xfeef04bd; |
||
729 | *(unsigned long *)&resbuf[curposbuf+4]=0x00010000; |
||
730 | curposbuf+=8; |
||
731 | while(!OpenBlock()&&tok!=tk_eof){ |
||
732 | switch(GetFlag((_STRINGS_ *)&typeversion,7)){ |
||
733 | case v_fv: |
||
734 | GetVersPar(resbuf+curposbuf); |
||
735 | break; |
||
736 | case v_pv: |
||
737 | GetVersPar(resbuf+curposbuf+8); |
||
738 | break; |
||
739 | case v_ffm: |
||
740 | nexttok(); |
||
741 | *(unsigned long *)&resbuf[curposbuf+16]=(unsigned long)GetNumber(0); |
||
742 | break; |
||
743 | case v_ff: |
||
744 | nexttok(); |
||
745 | *(unsigned long *)&resbuf[curposbuf+20]=(unsigned long)GetNumber(0); |
||
746 | break; |
||
747 | case v_fo: |
||
748 | nexttok(); |
||
749 | *(unsigned long *)&resbuf[curposbuf+24]=(unsigned long)GetNumber(0); |
||
750 | break; |
||
751 | case v_ft: |
||
752 | nexttok(); |
||
753 | *(unsigned long *)&resbuf[curposbuf+28]=(unsigned long)GetNumber(0); |
||
754 | break; |
||
755 | case v_fs: |
||
756 | nexttok(); |
||
757 | *(unsigned long *)&resbuf[curposbuf+32]=(unsigned long)GetNumber(0); |
||
758 | break; |
||
759 | default: |
||
760 | badformat("VERSIONINFO"); |
||
761 | break; |
||
762 | } |
||
763 | } |
||
764 | curposbuf+=44; |
||
765 | GetBlockInfo(); |
||
766 | *(unsigned short *)&resbuf[0]=(unsigned short)curposbuf; |
||
767 | curtres->res=(unsigned char *)REALLOC(resbuf,curposbuf); |
||
768 | curtres->size=curposbuf; |
||
769 | } |
||
770 | |||
771 | void r_Dialog() |
||
772 | { |
||
773 | unsigned char *name=NULL; |
||
774 | unsigned char *font=NULL; |
||
775 | int sizefont=0,i; |
||
776 | NameOrdinal Menu; |
||
777 | NameOrdinal Class; |
||
778 | unsigned int poscount; //позиция счетчика элементов |
||
779 | unsigned int exts=FALSE; |
||
780 | //unsigned short id; |
||
781 | Menu.name=NULL; |
||
782 | Class.name=NULL; |
||
783 | if(restok==rc_dialogex)exts=TRUE; |
||
784 | GetResBlock(); |
||
785 | curtres->type=CRT_DIALOG; |
||
786 | if(idname[0]==0)curtres->id=idnum; |
||
787 | else curtres->name=BackString(idname); |
||
788 | AddType(CRT_DIALOG); |
||
789 | InitBufRes(); |
||
790 | if(exts){ |
||
791 | *(unsigned long *)&resbuf[0]=0xFFFF0001; |
||
792 | curposbuf=8; |
||
793 | poscount=16; |
||
794 | *(unsigned long *)&resbuf[12]=0x80880000;//WS_POPUP|WS_BORDER|WS_SYSMENU; //установки по умолчанию |
||
795 | } |
||
796 | else{ |
||
797 | *(unsigned long *)&resbuf[0]=0x80880000;//WS_POPUP|WS_BORDER|WS_SYSMENU; //установки по умолчанию |
||
798 | curposbuf=0; |
||
799 | poscount=8; |
||
800 | } |
||
801 | if(tok2!=tk_camma){ //пропускаем возможные первые два параметра |
||
802 | nexttok(); |
||
803 | if(tok2!=tk_camma){ |
||
804 | nexttok(); |
||
805 | if(tok2!=tk_camma)badformat("DIALOG"); |
||
806 | } |
||
807 | } |
||
808 | GetRectangle(&resbuf[curposbuf+10],1); |
||
809 | //определить место для IDHelp |
||
810 | if(tok!=tk_endline&&exts)/**(unsigned long *)&resbuf[curposbuf]=*/GetNumber(0); |
||
811 | while(!OpenBlock()&&tok!=tk_eof){ |
||
812 | if(tok!=tk_rescommand)expectedrescommand(); |
||
813 | switch(itok.number){ |
||
814 | case rc_style: |
||
815 | nexttok(); |
||
816 | *(unsigned long *)&resbuf[exts==TRUE?12:0]=GetNumber(1); |
||
817 | break; |
||
818 | case rc_caption: |
||
819 | nexttok(); |
||
820 | if(tok!=tk_string)stringexpected(); |
||
821 | name=(unsigned char *)BackString((char *)string); |
||
822 | nexttok(); |
||
823 | break; |
||
824 | case rc_font: |
||
825 | nexttok(); |
||
826 | sizefont=GetNumber(1); |
||
827 | expecting(tk_camma); |
||
828 | if(tok!=tk_string)stringexpected(); |
||
829 | font=(unsigned char *)BackString((char *)string); |
||
830 | nexttok(); |
||
831 | break; |
||
832 | case rc_class: |
||
833 | nexttok(); |
||
834 | GetOrdinal(&Class.name,1); |
||
835 | // if(tok!=tk_string)stringexpected(); |
||
836 | // Class.name=(unsigned char *)BackString((char *)string); |
||
837 | // nexttok(); |
||
838 | break; |
||
839 | case rc_exstyle: |
||
840 | nexttok(); |
||
841 | *(unsigned long *)&resbuf[exts==TRUE?8:4]=GetNumber(1); |
||
842 | break; |
||
843 | case rc_language: |
||
844 | unsigned short olang; |
||
845 | olang=langdef; |
||
846 | nexttok(); |
||
847 | r_Language(); |
||
848 | curtres->lang=langdef; |
||
849 | langdef=olang; |
||
850 | break; |
||
851 | default: |
||
852 | if(exts&&itok.number==rc_menu){ |
||
853 | nexttok(); |
||
854 | GetOrdinal(&Menu.name,1); |
||
855 | } |
||
856 | else badformat("DIALOG"); |
||
857 | break; |
||
858 | } |
||
859 | while(tok==tk_endline)nexttok(); |
||
860 | } |
||
861 | //доформировываем диалог |
||
862 | curposbuf=exts==TRUE?26:18; |
||
863 | AddNumOrd(Menu.name); |
||
864 | FreeOrdinal(Menu.name); |
||
865 | AddNumOrd(Class.name); |
||
866 | FreeOrdinal(Class.name); |
||
867 | AddWString(name); |
||
868 | if(name)free(name); |
||
869 | if(sizefont){ |
||
870 | resbuf[exts==TRUE?12:0]|=0x40; |
||
871 | *(unsigned short *)&resbuf[curposbuf]=(unsigned short)sizefont; |
||
872 | curposbuf+=2; |
||
873 | if(exts){ |
||
874 | *(unsigned int *)&resbuf[curposbuf]=0x01000000; |
||
875 | curposbuf+=4; |
||
876 | } |
||
877 | AddWString(font); |
||
878 | free(font); |
||
879 | } |
||
880 | while(!CloseBlock()&&tok!=tk_eof){ |
||
881 | // do{ |
||
882 | if(tok!=tk_rescommand)expectedrescommand(); |
||
883 | restok=itok.number; |
||
884 | nexttok(); |
||
885 | curposbuf=Align(curposbuf,4); |
||
886 | CheckResBuf(34); |
||
887 | name=Menu.name=NULL; |
||
888 | i=1; |
||
889 | if(exts)curposbuf+=8; |
||
890 | *(unsigned short *)&resbuf[curposbuf+(exts==TRUE?16:18)]=0XFFFF; |
||
891 | *(unsigned short *)&resbuf[curposbuf+(exts==TRUE?18:20)]=defdialog[restok].dclass; |
||
892 | *(unsigned long *)&resbuf[curposbuf]=defdialog[restok].style|0x50000000; |
||
893 | switch(restok){ |
||
894 | case rc_control: |
||
895 | GetOrdinal(&Menu.name,1); |
||
896 | expecting(tk_camma); |
||
897 | while(tok==tk_endline)nexttok(); |
||
898 | if(exts)*(unsigned int *)&resbuf[curposbuf+12]=(unsigned int)GetNumber(2); |
||
899 | else *(unsigned short *)&resbuf[curposbuf+16]=(unsigned short)GetNumber(2); |
||
900 | expecting(tk_camma); |
||
901 | while(tok==tk_endline)nexttok(); |
||
902 | if(tok==tk_number)*(unsigned short *)&resbuf[curposbuf+(exts==TRUE?18:20)]=(unsigned short)itok.number; |
||
903 | else{ |
||
904 | if(tok==tk_string)strncpy(itok.name,(char *)string,IDLENGTH); |
||
905 | i=GetFlag((_STRINGS_ *)&typeclass,6); |
||
906 | if(!i)name=(unsigned char *)BackString((char *)string); |
||
907 | else *(unsigned short *)&resbuf[curposbuf+(exts==TRUE?18:20)]=(unsigned short)i; |
||
908 | } |
||
909 | nextexpecting2(tk_camma); |
||
910 | while(tok==tk_endline)nexttok(); |
||
911 | *(unsigned long *)&resbuf[curposbuf]|=GetNumber(4); |
||
912 | expecting(tk_camma); |
||
913 | while(tok==tk_endline)nexttok(); |
||
914 | GetRectangle(&resbuf[curposbuf+(exts==TRUE?4:8)],5); |
||
915 | if(exts&&tok==tk_number)*(unsigned long *)&resbuf[curposbuf-4]=GetNumber(9); |
||
916 | while(tok!=tk_endline&&tok!=tk_eof&&tok!=tk_rescommand)nexttok(); //пропуск излишних параметров |
||
917 | break; |
||
918 | case rc_auto3state: |
||
919 | case rc_autocheckbox: |
||
920 | case rc_autoradiobutton: |
||
921 | case rc_checkbox: |
||
922 | case rc_ctext: |
||
923 | case rc_defpushbutton: |
||
924 | case rc_groupbox: |
||
925 | case rc_ltext: |
||
926 | case rc_pushbox: |
||
927 | case rc_pushbutton: |
||
928 | case rc_radiobutton: |
||
929 | case rc_rtext: |
||
930 | case rc_state3: |
||
931 | if(tok!=tk_string)stringexpected(); |
||
932 | Menu.name=(unsigned char *)BackString((char *)string); |
||
933 | nexttok(); |
||
934 | if(tok==tk_camma)nexttok(); |
||
935 | while(tok==tk_endline&&tok!=tk_eof)nexttok(); |
||
936 | i++; |
||
937 | case rc_combobox: |
||
938 | case rc_edittext: |
||
939 | case rc_listbox: |
||
940 | case rc_scrollbar: |
||
941 | if(exts)*(unsigned int *)&resbuf[curposbuf+12]=(unsigned int)GetNumber(i); |
||
942 | else *(unsigned short *)&resbuf[curposbuf+16]=(unsigned short)GetNumber(i); |
||
943 | expecting(tk_camma); |
||
944 | while(tok==tk_endline)nexttok(); |
||
945 | GetRectangle(&resbuf[curposbuf+(exts==TRUE?4:8)],i+1); |
||
946 | if(tok!=tk_endline){ |
||
947 | *(unsigned long *)&resbuf[curposbuf]|=(unsigned long)GetNumber(i+5); |
||
948 | if(tok==tk_camma){ |
||
949 | nexttok(); |
||
950 | *(unsigned long *)&resbuf[curposbuf+(exts==TRUE?-4:4)]=(unsigned long)GetNumber(i+6); |
||
951 | } |
||
952 | } |
||
953 | if(exts&&tok==tk_number)*(unsigned long *)&resbuf[curposbuf-4]=GetNumber(i+9); |
||
954 | while(tok!=tk_endline&&tok!=tk_eof&&tok!=tk_rescommand)nexttok(); //пропуск излишних параметров |
||
955 | break; |
||
956 | case rc_icon: |
||
957 | GetOrdinal(&Menu.name,1); |
||
958 | expecting(tk_camma); |
||
959 | while(tok==tk_endline)nexttok(); |
||
960 | if(exts)*(unsigned int *)&resbuf[curposbuf+12]=(unsigned int)GetNumber(2); |
||
961 | else *(unsigned short *)&resbuf[curposbuf+16]=(unsigned short)GetNumber(2); |
||
962 | expecting(tk_camma); |
||
963 | while(tok==tk_endline)nexttok(); |
||
964 | *(unsigned short *)&resbuf[curposbuf+(exts==TRUE?4:8)]=(unsigned short)GetNumber(3); |
||
965 | expecting(tk_camma); |
||
966 | while(tok==tk_endline)nexttok(); |
||
967 | *(unsigned short *)&resbuf[curposbuf+(exts==TRUE?6:10)]=(unsigned short)GetNumber(4); |
||
968 | if(tok==tk_camma){ |
||
969 | nexttok(); |
||
970 | *(unsigned short *)&resbuf[curposbuf+(exts==TRUE?8:12)]=(unsigned short)GetNumber(5); |
||
971 | if(tok==tk_camma){ |
||
972 | nexttok(); |
||
973 | *(unsigned short *)&resbuf[curposbuf+(exts==TRUE?10:14)]=(unsigned short)GetNumber(6); |
||
974 | if(tok==tk_camma){ |
||
975 | nexttok(); |
||
976 | *(unsigned long *)&resbuf[curposbuf]|=GetNumber(7); |
||
977 | } |
||
978 | } |
||
979 | } |
||
980 | break; |
||
981 | default: |
||
982 | badformat("DIALOG"); |
||
983 | break; |
||
984 | } |
||
985 | while(tok==tk_endline)nexttok(); |
||
986 | *(unsigned short *)&resbuf[poscount]=(unsigned short)(*(unsigned short *)&resbuf[poscount]+1); |
||
987 | curposbuf+=(exts==TRUE?20:22); |
||
988 | if(name){ |
||
989 | curposbuf-=4; |
||
990 | AddWString(name); |
||
991 | free(name); |
||
992 | } |
||
993 | if(Menu.name){ |
||
994 | AddNumOrd(Menu.name); |
||
995 | FreeOrdinal(Menu.name); |
||
996 | } |
||
997 | else curposbuf+=2; |
||
998 | CheckResBuf(6); |
||
999 | curposbuf+=2; |
||
1000 | // }while(!CloseBlock()&&tok!=tk_eof); |
||
1001 | } |
||
1002 | curtres->res=(unsigned char *)REALLOC(resbuf,curposbuf); |
||
1003 | curtres->size=curposbuf; |
||
1004 | } |
||
1005 | |||
1006 | void GetFileName(char *name) |
||
1007 | { |
||
1008 | while(tok!=tk_string&&tok!=tk_endline&&tok!=tk_eof){ |
||
1009 | int i; |
||
1010 | for(i=0;i<7;i++){ |
||
1011 | if(stricmp(itok.name,typemem[i].id)==0)break; |
||
1012 | } |
||
1013 | if(i==7){ |
||
1014 | strcpy(name,itok.name); |
||
1015 | i=strlen(itok.name); |
||
1016 | name[i++]=cha2; |
||
1017 | for(;;){ |
||
1018 | cha2=input[inptr2++]; |
||
1019 | if(cha2<=0x20)break; |
||
1020 | name[i++]=cha2; |
||
1021 | } |
||
1022 | name[i]=0; |
||
1023 | break; |
||
1024 | } |
||
1025 | nexttok(); |
||
1026 | } |
||
1027 | } |
||
1028 | |||
1029 | unsigned char *LoadFileBin(char *name) |
||
1030 | { |
||
1031 | int inico; |
||
1032 | unsigned char *bitobr; |
||
1033 | if((inico=open(name,O_BINARY|O_RDONLY))==-1){ |
||
1034 | badinfile(name); |
||
1035 | return NULL; |
||
1036 | } |
||
1037 | if((curposbuf=getfilelen(inico))==0){ |
||
1038 | badinfile(name); |
||
1039 | close(inico); |
||
1040 | return NULL; |
||
1041 | } |
||
1042 | bitobr=(unsigned char *)MALLOC(curposbuf); |
||
1043 | if((unsigned int)read(inico,bitobr,curposbuf)!=curposbuf){ |
||
1044 | errorreadingfile(name); |
||
1045 | close(inico); |
||
1046 | free(bitobr); |
||
1047 | return NULL; |
||
1048 | } |
||
1049 | close(inico); |
||
1050 | nexttok(); |
||
1051 | return bitobr; |
||
1052 | } |
||
1053 | |||
1054 | unsigned char *LoadBitmap() |
||
1055 | { |
||
1056 | //загрузить |
||
1057 | unsigned char *bitobr=NULL; |
||
1058 | char name[80]; |
||
1059 | curposbuf=0; |
||
1060 | name[0]=0; |
||
1061 | GetFileName(name); |
||
1062 | if(name[0]!=0)bitobr=LoadFileBin(name); |
||
1063 | else if(tok==tk_endline){ //нет имени файла |
||
1064 | InitBufRes(); |
||
1065 | if(!OpenBlock()){ |
||
1066 | badico(); |
||
1067 | return NULL; |
||
1068 | } |
||
1069 | do{ |
||
1070 | inptr=inptr2; |
||
1071 | cha=cha2; |
||
1072 | if(tok!=tk_singlquote)badico(); |
||
1073 | whitespace(); //пропуск незначащих символов |
||
1074 | CheckResBuf(16); |
||
1075 | displaytokerrors=1; |
||
1076 | do{ |
||
1077 | unsigned char hold=0; |
||
1078 | for(int i=0;i<2;i++){ |
||
1079 | hold*=(unsigned char)16; |
||
1080 | if(isdigit(cha))hold+=(unsigned char)(cha-'0'); |
||
1081 | else if(isxdigit(cha))hold+=(unsigned char)((cha&0x5f)-'7'); |
||
1082 | else expectederror("hexadecimal digit"); |
||
1083 | nextchar(); |
||
1084 | } |
||
1085 | resbuf[curposbuf++]=hold; |
||
1086 | whitespace(); //пропуск незначащих символов |
||
1087 | }while(cha!='\''&&cha!=26); |
||
1088 | inptr2=inptr; |
||
1089 | cha2=cha; |
||
1090 | linenum2=linenumber; |
||
1091 | nexttok(); |
||
1092 | nexttok(); |
||
1093 | }while(!CloseBlock()&&tok!=tk_eof); |
||
1094 | bitobr=(unsigned char *)REALLOC(resbuf,curposbuf); |
||
1095 | } |
||
1096 | else if(tok==tk_string)bitobr=LoadFileBin((char *)string); |
||
1097 | return bitobr; |
||
1098 | } |
||
1099 | |||
1100 | void r_Bitmap() |
||
1101 | { |
||
1102 | unsigned int size; |
||
1103 | unsigned char *bitobr; |
||
1104 | if((bitobr=LoadBitmap())==NULL)return; |
||
1105 | size=curposbuf-14; |
||
1106 | GetResBlock(); //битмар |
||
1107 | curtres->type=CRT_BITMAP; |
||
1108 | if(idname[0]==0)curtres->id=idnum; |
||
1109 | else curtres->name=BackString(idname); |
||
1110 | curtres->size=size; |
||
1111 | curtres->res=(unsigned char *)MALLOC(size); |
||
1112 | AddType(CRT_BITMAP); |
||
1113 | memcpy(curtres->res,bitobr+14,size); |
||
1114 | free(bitobr); |
||
1115 | } |
||
1116 | |||
1117 | void NewResourse() |
||
1118 | { |
||
1119 | unsigned char *bitobr=NULL; |
||
1120 | char name[256]; |
||
1121 | GetResBlock(); |
||
1122 | if(resname[0]==0)curtres->type=restok; |
||
1123 | else curtres->tname=BackString(resname); |
||
1124 | if(idname[0]==0)curtres->id=idnum; |
||
1125 | else curtres->name=BackString(idname); |
||
1126 | AddType(restok,curtres->tname); |
||
1127 | name[0]=0; |
||
1128 | GetFileName(name); |
||
1129 | if(name[0]!=0)bitobr=LoadFileBin(name); |
||
1130 | else if(tok==tk_string)bitobr=LoadFileBin((char *)string); |
||
1131 | else stringexpected(); |
||
1132 | if(bitobr!=NULL){ |
||
1133 | curtres->res=bitobr; |
||
1134 | curtres->size=curposbuf; |
||
1135 | } |
||
1136 | nexttok(); |
||
1137 | } |
||
1138 | |||
1139 | void r_Font() |
||
1140 | { |
||
1141 | unsigned char *fontobr; |
||
1142 | if((fontobr=LoadBitmap())==NULL)return; |
||
1143 | if((unsigned short)curposbuf==*(unsigned short *)&fontobr[2]){ |
||
1144 | GetResBlock(); //фонт |
||
1145 | curtres->type=CRT_FONT; |
||
1146 | if(idname[0]==0)curtres->id=idnum; |
||
1147 | else curtres->name=BackString(idname); |
||
1148 | curtres->size=curposbuf; |
||
1149 | curtres->res=fontobr; |
||
1150 | AddType(CRT_FONT); |
||
1151 | } |
||
1152 | } |
||
1153 | |||
1154 | void r_Icon() |
||
1155 | { |
||
1156 | unsigned char *icoobr; |
||
1157 | unsigned long size; |
||
1158 | //загрузить иконку |
||
1159 | if((icoobr=LoadBitmap())==NULL)return; |
||
1160 | GetResBlock(); //группа икон |
||
1161 | curtres->type=CRT_GROUP_ICON; |
||
1162 | if(idname[0]==0)curtres->id=idnum; |
||
1163 | else curtres->name=BackString(idname); |
||
1164 | AddType(CRT_GROUP_ICON); |
||
1165 | unsigned int countico=*(unsigned short *)&icoobr[4]; //число иконок |
||
1166 | int sizeicohead=sizeof(_ICOHEAD_)+(sizeof(_RESDIR_)*countico); |
||
1167 | curtres->size=sizeicohead; |
||
1168 | curtres->res=(unsigned char *)MALLOC(sizeicohead); |
||
1169 | unsigned char *icohead=curtres->res; |
||
1170 | unsigned int i; |
||
1171 | for(i=0;i<6;i++)icohead[i]=icoobr[i]; //заголовок |
||
1172 | unsigned int ofs=6; |
||
1173 | unsigned int ofs2=6; |
||
1174 | for(i=0;i |
||
1175 | int j; |
||
1176 | for(j=0;j<12;j++)icohead[j+ofs]=icoobr[j+ofs2]; //описание иконки |
||
1177 | iconcount++; |
||
1178 | *(unsigned short *)&icohead[ofs+12]=(unsigned short)iconcount; //ее номер |
||
1179 | GetResBlock(); //образ иконки |
||
1180 | curtres->type=CRT_ICON; |
||
1181 | curtres->id=iconcount; |
||
1182 | curtres->size=size=*(unsigned long *)&icohead[ofs+8]; |
||
1183 | curtres->res=(unsigned char *)MALLOC(size); |
||
1184 | AddType(CRT_ICON); |
||
1185 | unsigned int ofs3=*(unsigned int *)&icoobr[ofs2+12]; |
||
1186 | for(j=0;(unsigned int)j |
||
1187 | ofs+=sizeof(_RESDIR_); |
||
1188 | ofs2+=sizeof(_RESDIR_)+2; |
||
1189 | } |
||
1190 | free(icoobr); |
||
1191 | } |
||
1192 | |||
1193 | void r_Cursor() |
||
1194 | { |
||
1195 | unsigned char *curobr; |
||
1196 | unsigned long size; |
||
1197 | //загрузить курсор |
||
1198 | if((curobr=LoadBitmap())==NULL)return; |
||
1199 | GetResBlock(); //группа курсоров |
||
1200 | curtres->type=CRT_GROUP_CURSOR; |
||
1201 | if(idname[0]==0)curtres->id=idnum; |
||
1202 | else curtres->name=BackString(idname); |
||
1203 | AddType(CRT_GROUP_CURSOR); |
||
1204 | unsigned int countcur=*(unsigned short *)&curobr[4]; //число курсоров в файле |
||
1205 | int sizecurhead=sizeof(_ICOHEAD_)+(sizeof(_CURDIR_)*countcur); |
||
1206 | curtres->size=sizecurhead; |
||
1207 | curtres->res=(unsigned char *)MALLOC(sizecurhead); |
||
1208 | unsigned char *curhead=curtres->res; |
||
1209 | unsigned int i; |
||
1210 | for(i=0;i<6;i++)curhead[i]=curobr[i]; //заголовок |
||
1211 | unsigned int ofs=6; |
||
1212 | unsigned int ofs2=6; |
||
1213 | for(i=0;i |
||
1214 | cursorcount++; |
||
1215 | *(unsigned short *)&curhead[ofs]=curobr[ofs2]; |
||
1216 | *(unsigned short *)&curhead[ofs+2]=curobr[ofs2+1]; |
||
1217 | *(unsigned long *)&curhead[ofs+4]=0x10001; |
||
1218 | *(unsigned short *)&curhead[ofs+12]=(unsigned short)cursorcount; //ее номер |
||
1219 | GetResBlock(); //образ курсора |
||
1220 | curtres->type=CRT_CURSOR; |
||
1221 | curtres->id=cursorcount; |
||
1222 | curtres->size=size=*(unsigned long *)&curhead[ofs+8]=*(unsigned long *)&curobr[ofs2+8]+4; |
||
1223 | curtres->res=(unsigned char *)MALLOC(size); |
||
1224 | AddType(CRT_CURSOR); |
||
1225 | unsigned int ofs3=*(unsigned int *)&curobr[ofs2+12]; |
||
1226 | *(unsigned short *)&curtres->res[0]=*(unsigned short *)&curobr[ofs2+4]; |
||
1227 | *(unsigned short *)&curtres->res[2]=*(unsigned short *)&curobr[ofs2+6]; |
||
1228 | size-=4; |
||
1229 | for(int j=0;(unsigned int)j |
||
1230 | ofs+=sizeof(_CURDIR_); |
||
1231 | ofs2+=sizeof(_CURDIR_)+2; |
||
1232 | } |
||
1233 | free(curobr); |
||
1234 | } |
||
1235 | |||
1236 | void r_Accelerators() |
||
1237 | { |
||
1238 | GetResBlock(); |
||
1239 | curtres->type=CRT_ACCELERATOR; |
||
1240 | if(idname[0]==0)curtres->id=idnum; |
||
1241 | else curtres->name=BackString(idname); |
||
1242 | AddType(CRT_ACCELERATOR); |
||
1243 | InitBufRes(); |
||
1244 | if(OpenBlock()){ |
||
1245 | do{ |
||
1246 | CheckResBuf(8); |
||
1247 | if(tok==tk_string){ |
||
1248 | unsigned char c; |
||
1249 | c=string[0]; |
||
1250 | if(c=='^'){ |
||
1251 | c=string[1]; |
||
1252 | if(c<0x40)preerror("Unsolved symbol for Contrl");//error |
||
1253 | c-=0x40; |
||
1254 | } |
||
1255 | *(unsigned short *)&resbuf[curposbuf+2]=(unsigned short)c; |
||
1256 | nexttok(); |
||
1257 | } |
||
1258 | else{ |
||
1259 | *(unsigned short *)&resbuf[curposbuf+2]=(unsigned short)GetNumber(1); |
||
1260 | } |
||
1261 | expecting(tk_camma); |
||
1262 | *(unsigned short *)&resbuf[curposbuf+4]=(unsigned short)GetNumber(2); |
||
1263 | if(tok==tk_camma){ |
||
1264 | nexttok(); |
||
1265 | if(tok==tk_number)*(unsigned short *)&resbuf[curposbuf]|=(unsigned short)itok.number; |
||
1266 | *(unsigned short *)&resbuf[curposbuf]|=GetFlag((_STRINGS_ *)&typeacceler,5);//GetAccerFlag(); |
||
1267 | nexttok(); |
||
1268 | while(tok!=tk_endline){ |
||
1269 | if(tok==tk_camma)nexttok(); |
||
1270 | if(tok==tk_number)*(unsigned short *)&resbuf[curposbuf]|=(unsigned short)itok.number; |
||
1271 | *(unsigned short *)&resbuf[curposbuf]|=GetFlag((_STRINGS_ *)&typeacceler,5);//GetAccerFlag(); |
||
1272 | nexttok(); |
||
1273 | } |
||
1274 | } |
||
1275 | curposbuf+=8; |
||
1276 | }while(!CloseBlock()&&tok!=tk_eof); |
||
1277 | resbuf[curposbuf-8]|=0x80; |
||
1278 | } |
||
1279 | else badformat("ACCELERATORS"); |
||
1280 | curtres->res=(unsigned char *)REALLOC(resbuf,curposbuf); |
||
1281 | curtres->size=curposbuf; |
||
1282 | } |
||
1283 | |||
1284 | void SortRes() |
||
1285 | { |
||
1286 | int i,j,k; |
||
1287 | int sortpos=0; //позиция в списке сортировки |
||
1288 | for(i=0;i |
||
1289 | for(j=i+1;j |
||
1290 | TUSE buf; |
||
1291 | if((tuse+i)->id>(tuse+j)->id){ |
||
1292 | buf.id=(tuse+i)->id; |
||
1293 | buf.count=(tuse+i)->count; |
||
1294 | buf.tname=(tuse+i)->tname; |
||
1295 | (tuse+i)->id=(tuse+j)->id; |
||
1296 | (tuse+i)->count=(tuse+j)->count; |
||
1297 | (tuse+i)->tname=(tuse+j)->tname; |
||
1298 | (tuse+j)->count=buf.count; |
||
1299 | (tuse+j)->id=buf.id; |
||
1300 | (tuse+j)->tname=buf.tname; |
||
1301 | } |
||
1302 | if((tuse+i)->id==(tuse+j)->id){ |
||
1303 | if(stricmp((tuse+i)->tname,(tuse+j)->tname)>0){ |
||
1304 | buf.count=(tuse+i)->count; |
||
1305 | buf.tname=(tuse+i)->tname; |
||
1306 | (tuse+i)->count=(tuse+j)->count; |
||
1307 | (tuse+i)->tname=(tuse+j)->tname; |
||
1308 | (tuse+j)->count=buf.count; |
||
1309 | (tuse+j)->tname=buf.tname; |
||
1310 | } |
||
1311 | } |
||
1312 | } |
||
1313 | if((tuse+i)->id==0)numzerotype++; |
||
1314 | } |
||
1315 | |||
1316 | sortidx=(unsigned short *)MALLOC(sizeof(unsigned short)*numres); |
||
1317 | for(i=0;i |
||
1318 | for(k=0,j=0;j |
||
1319 | if((tuse+i)->id==(listres+j)->type){ |
||
1320 | if((listres+j)->lang){ |
||
1321 | numlangres++; |
||
1322 | numhlangres++; |
||
1323 | } |
||
1324 | if((tuse+i)->count==1){ |
||
1325 | sortidx[sortpos++]=(unsigned short)j; |
||
1326 | break; |
||
1327 | } |
||
1328 | else{ |
||
1329 | if(k==0)sortidx[sortpos++]=(unsigned short)j; |
||
1330 | else{ |
||
1331 | int m=k; //число элементов с данным типом |
||
1332 | int n=sortpos-k; |
||
1333 | do{ |
||
1334 | m--; |
||
1335 | if((listres+j)->name==NULL&&(listres+sortidx[m+n])->name==NULL){ |
||
1336 | if((listres+j)->id>=(listres+sortidx[m+n])->id){//новый больше |
||
1337 | if((listres+j)->id==(listres+sortidx[m+n])->id){ //равны |
||
1338 | numidres--; |
||
1339 | numlangres++; |
||
1340 | if((listres+j)->lang==0){ |
||
1341 | numlangres++; |
||
1342 | numhlangres++; |
||
1343 | } |
||
1344 | if((listres+j)->lang==(listres+sortidx[m+n])->lang)equalres(); |
||
1345 | if((listres+j)->lang>(listres+sortidx[m+n])->lang){ //у нового язык старше |
||
1346 | sortidx[n+m+1]=(unsigned short)j; //добавить в конец |
||
1347 | break; |
||
1348 | } |
||
1349 | } |
||
1350 | else{ |
||
1351 | sortidx[n+m+1]=(unsigned short)j; //добавить в конец |
||
1352 | break; |
||
1353 | } |
||
1354 | } |
||
1355 | sortidx[n+m+1]=sortidx[n+m]; //сдвинуть |
||
1356 | } |
||
1357 | else if((listres+j)->name==NULL&&(listres+sortidx[m+n])->name!=NULL){ |
||
1358 | sortidx[n+m+1]=(unsigned short)j; |
||
1359 | break; |
||
1360 | } |
||
1361 | else if((listres+j)->name!=NULL&&(listres+sortidx[m+n])->name==NULL){ |
||
1362 | sortidx[n+m+1]=sortidx[n+m]; |
||
1363 | } |
||
1364 | else{ |
||
1365 | int cmp; |
||
1366 | if((cmp=strcmp((listres+j)->name,(listres+sortidx[m+n])->name))>=0){ |
||
1367 | if(cmp==0){ |
||
1368 | numidres--; |
||
1369 | numlangres++; |
||
1370 | if((listres+j)->lang==0){ |
||
1371 | numlangres++; |
||
1372 | numhlangres++; |
||
1373 | } |
||
1374 | // numhlangres--; |
||
1375 | if((listres+j)->lang==(listres+sortidx[m+n])->lang)equalres(); |
||
1376 | if((listres+j)->lang>(listres+sortidx[m+n])->lang){ |
||
1377 | sortidx[n+m+1]=(unsigned short)j; |
||
1378 | break; |
||
1379 | } |
||
1380 | } |
||
1381 | else{ |
||
1382 | sortidx[n+m+1]=(unsigned short)j; |
||
1383 | break; |
||
1384 | } |
||
1385 | } |
||
1386 | sortidx[n+m+1]=sortidx[n+m]; |
||
1387 | } |
||
1388 | if(m==0)sortidx[sortpos-k]=(unsigned short)j; |
||
1389 | }while(m>0); |
||
1390 | sortpos++; |
||
1391 | } |
||
1392 | } |
||
1393 | k++; |
||
1394 | } |
||
1395 | } |
||
1396 | } |
||
1397 | /* |
||
1398 | for(i=0;i |
||
1399 | printf("type=%-5uid=%-10u type=%-5uid=%u\n",(listres+sortidx[i])->type,(listres+sortidx[i])->id, |
||
1400 | (listres+i)->type,(listres+i)->id); |
||
1401 | } |
||
1402 | */ |
||
1403 | } |
||
1404 | |||
1405 | |||
1406 | int MakeRes(unsigned long ofsres,LISTRELOC **listrel) |
||
1407 | { |
||
1408 | int i,j; |
||
1409 | unsigned long nextofs; |
||
1410 | unsigned int startlang,ofsback; |
||
1411 | unsigned int startofsdata,startdata; |
||
1412 | int numrel=0; |
||
1413 | RES *curres; |
||
1414 | LISTRELOC *listr=NULL; |
||
1415 | linenumber=0; |
||
1416 | InitBufRes(); |
||
1417 | numidres=numres; |
||
1418 | SortRes(); |
||
1419 | //создать корневой уровень |
||
1420 | *(unsigned short *)&resbuf[12]=(unsigned short)numzerotype; |
||
1421 | *(unsigned short *)&resbuf[14]=(unsigned short)(numtyperes-numzerotype); |
||
1422 | curposbuf=16; |
||
1423 | nextofs=numtyperes*8+16; |
||
1424 | //расчет размеров уровней |
||
1425 | startlang=curposbuf+numtyperes*24+numidres*8; |
||
1426 | startofsdata=startlang+numhlangres*16+numlangres*8; |
||
1427 | startdata=startofsdata+numres*16; |
||
1428 | CheckResBuf(startdata-curposbuf); |
||
1429 | for(i=0;i |
||
1430 | if((tuse+i)->id==0){ |
||
1431 | *(unsigned long *)&resbuf[curposbuf]=startdata|0x80000000; |
||
1432 | curres=listres+sortidx[i]; |
||
1433 | int len=strlen(curres->tname); |
||
1434 | CheckResBuf(startdata-curposbuf+len*2+4); |
||
1435 | *(unsigned short *)&resbuf[startdata]=(unsigned short)len; |
||
1436 | unsigned char c; |
||
1437 | len=0; |
||
1438 | startdata+=2; |
||
1439 | for(;;){ |
||
1440 | c=curres->tname[len++]; |
||
1441 | if(c==0)break; |
||
1442 | resbuf[startdata]=c; |
||
1443 | startdata+=2; |
||
1444 | } |
||
1445 | free(curres->tname); |
||
1446 | } |
||
1447 | else *(unsigned long *)&resbuf[curposbuf]=(tuse+i)->id; |
||
1448 | *(unsigned long *)&resbuf[curposbuf+4]=nextofs|0x80000000; |
||
1449 | nextofs+=(tuse+i)->count*8+16; |
||
1450 | curposbuf+=8; |
||
1451 | } |
||
1452 | //расчет размеров уровней |
||
1453 | /* startlang=curposbuf+numtyperes*16+numidres*8; |
||
1454 | startofsdata=startlang+numhlangres*16+numlangres*8; |
||
1455 | startdata=startofsdata+numres*16; |
||
1456 | CheckResBuf(startdata-curposbuf);*/ |
||
1457 | //создать уровень имен и языка |
||
1458 | curres=listres+sortidx[0]; |
||
1459 | for(j=0;j |
||
1460 | ofsback=curposbuf+12; |
||
1461 | curposbuf+=16; |
||
1462 | unsigned int type=curres->type; |
||
1463 | while((unsigned int)curres->type==type){ |
||
1464 | int k=j; |
||
1465 | if(curres->name){ //добавить имя |
||
1466 | if(j<(numres-1)&&type==(unsigned int)(listres+sortidx[j+1])->type&& |
||
1467 | (listres+sortidx[j+1])->name!=NULL) |
||
1468 | while(strcmp(curres->name,(listres+sortidx[j+1])->name)==0)j++; |
||
1469 | *(unsigned short *)&resbuf[ofsback]=(unsigned short)(*(unsigned short *)&resbuf[ofsback]+1); |
||
1470 | *(unsigned long *)&resbuf[curposbuf]=startdata|0x80000000; |
||
1471 | int len=strlen(curres->name); |
||
1472 | CheckResBuf(startdata-curposbuf+len*2+4); |
||
1473 | *(unsigned short *)&resbuf[startdata]=(unsigned short)len; |
||
1474 | unsigned char c; |
||
1475 | len=0; |
||
1476 | startdata+=2; |
||
1477 | for(;;){ |
||
1478 | c=curres->name[len++]; |
||
1479 | if(c==0)break; |
||
1480 | resbuf[startdata]=c; |
||
1481 | startdata+=2; |
||
1482 | } |
||
1483 | // startdata=Align(startdata,4); |
||
1484 | free(curres->name); |
||
1485 | } |
||
1486 | else{ //добавить id |
||
1487 | if(j<(numres-1)&&type==(unsigned int)(listres+sortidx[j+1])->type) |
||
1488 | while(curres->id==(listres+sortidx[j+1])->id)j++; |
||
1489 | *(unsigned short *)&resbuf[ofsback+2]=(unsigned short)(*(unsigned short *)&resbuf[ofsback+2]+1); |
||
1490 | *(unsigned long *)&resbuf[curposbuf]=curres->id; |
||
1491 | } |
||
1492 | curposbuf+=4; |
||
1493 | if(j!=k){ //несколько имен с разными языками |
||
1494 | *(unsigned long *)&resbuf[curposbuf]=startlang|0x80000000; |
||
1495 | *(unsigned long *)&resbuf[startlang+12]=j-k+1; |
||
1496 | startlang+=16; |
||
1497 | for(;k<=j;k++){ |
||
1498 | *(unsigned long *)&resbuf[startlang]=(listres+sortidx[k])->lang; |
||
1499 | *(unsigned long *)&resbuf[startlang+4]=startofsdata; |
||
1500 | startlang+=8; |
||
1501 | startofsdata+=16; |
||
1502 | } |
||
1503 | } |
||
1504 | else{ |
||
1505 | if(curres->lang){//указан язык |
||
1506 | *(unsigned long *)&resbuf[curposbuf]=startlang|0x80000000; |
||
1507 | resbuf[startlang+14]=1; |
||
1508 | startlang+=16; |
||
1509 | *(unsigned long *)&resbuf[startlang]=curres->lang; |
||
1510 | *(unsigned long *)&resbuf[startlang+4]=startofsdata; |
||
1511 | startlang+=8; |
||
1512 | } |
||
1513 | else *(unsigned long *)&resbuf[curposbuf]=startofsdata; |
||
1514 | startofsdata+=16; |
||
1515 | } |
||
1516 | curposbuf+=4; |
||
1517 | j++; |
||
1518 | if(j==numres)break; |
||
1519 | curres=listres+sortidx[j]; |
||
1520 | } |
||
1521 | } |
||
1522 | curposbuf=startlang; |
||
1523 | //создать уровень смещений данных |
||
1524 | for(i=0;i |
||
1525 | startdata=Align(startdata,4); |
||
1526 | curres=listres+sortidx[i]; |
||
1527 | *(unsigned long *)&resbuf[curposbuf]=startdata+ofsres; |
||
1528 | if(!numrel)listr=(LISTRELOC *)MALLOC(sizeof(LISTRELOC)); |
||
1529 | else listr=(LISTRELOC *)REALLOC(listr,(numrel+1)*sizeof(LISTRELOC)); |
||
1530 | (listr+numrel)->val=curposbuf; |
||
1531 | numrel++; |
||
1532 | curposbuf+=4; |
||
1533 | *(unsigned long *)&resbuf[curposbuf]=curres->size; |
||
1534 | curposbuf+=12; |
||
1535 | CheckResBuf(startdata-curposbuf+curres->size); |
||
1536 | memcpy(resbuf+startdata,curres->res,curres->size); |
||
1537 | free(curres->res); |
||
1538 | startdata+=curres->size; |
||
1539 | } |
||
1540 | curposbuf=startdata; |
||
1541 | nextofs=Align(curposbuf,FILEALIGN); |
||
1542 | CheckResBuf(nextofs-curposbuf); |
||
1543 | // SaveFile("resorse"); |
||
1544 | *listrel=listr; |
||
1545 | return numrel; |
||
1546 | } |