Subversion Repositories Kolibri OS

Rev

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)jres[j]=icoobr[j+ofs3];
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)jres[j+4]=curobr[j+ofs3];
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
}