Subversion Repositories Kolibri OS

Rev

Rev 8925 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
8824 IgorA 1
#include 
2
#include 
3
#include 
4
#include 
5
#include 
6
#include 
7
#include 
8875 IgorA 8
#include 
8824 IgorA 9
 
10
using namespace Kolibri;
11
 
12
const char header[] = "Blocks";
13
char library_path[2048];
14
 
15
OpenDialog_data ofd;
16
unsigned char procinfo[1024];
17
char plugin_path[4096], openfile_path[4096], filename_area[256];
8909 IgorA 18
od_filter filter1 = { 7, "BJS\0\0" };
8824 IgorA 19
 
20
namespace Kolibri{
21
	char CurrentDirectoryPath[2048];
22
}
23
 
24
struct BlockList{
25
	unsigned char* name;
26
	long int id_l, p_cou;
27
	float* vert_d;
28
	float* norm_d;
29
};
30
 
31
BlockList* b_list = 0;
32
long int b_count;
33
 
34
unsigned char* b_data = 0;
35
unsigned char* f_data = 0;
36
 
37
struct ColorList{
38
	unsigned char* name;
39
	long int color;
40
};
41
 
8909 IgorA 42
const long C_COUNT_MAX = 32;
43
const long TOOLBAR_H = 29;
8824 IgorA 44
ColorList c_list[C_COUNT_MAX];
45
long c_count = 0;
46
 
47
struct ModelList{
48
	char* name;
49
	long int color, t_cr;
50
	float x,y,z, r_x,r_y,r_z;
8919 IgorA 51
	unsigned long level;
52
	long int id_l;
8824 IgorA 53
};
54
 
55
ModelList* model_list = 0;
56
long int m_count;
57
 
58
TinyGLContext ctx1;
59
float angle_x = 135.0, angle_y = 0.0, angle_z = 0.0, delt_size = 3.0,
60
	scale_o = 0.1, trans_z = 0.0;
61
double rat_h = 1.0;
62
bool mouse_drag = false;
63
short mouse_x, mouse_y;
64
float angle_dwm, //~ wnd_w/180 - прибавление углов поворота сцены при вращении мышей
65
	angle_dhm;   //~ wnd_h/180
66
 
67
float light_position[] = {-30.0, 80.0, -50.0, 1.0}; //Расположение источника [0][1][2]
68
	//[3] = (0.0 - бесконечно удаленный источник, 1.0 - источник света на определенном расстоянии)
69
float light_dir[] = {0.0,0.0,0.0}; //направление лампы
70
 
71
float mat_specular[] = {0.3, 0.3, 0.3, 1.0}; //Цвет блика
72
float mat_shininess = 3.0; //Размер блика (обратная пропорция)
73
float white_light[] = {1.0, 1.0, 1.0, 1.0}; //Цвет и интенсивность освещения, генерируемого источником
74
float lmodel_ambient[] = {0.3, 0.3, 0.3, 1.0}; //Параметры фонового освещения
75
 
8875 IgorA 76
char str1[] = "Show active level";
8919 IgorA 77
check_box check1 = { {16,310,20,4}, 8, 0xffffff, 0x808080, 0xffffff, str1, ch_flag_middle };
78
scrollbar sb_tcr = { 200,100,19,4, 16, 1, 20,1,0, 0x808080, 0xffffff, 0x0};
8875 IgorA 79
 
8824 IgorA 80
void SetLight()
81
{
82
	glLightfv(GL_LIGHT0, GL_POSITION, light_position);
83
	glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light_dir);
84
 
85
	glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light);
86
	glLightfv(GL_LIGHT0, GL_SPECULAR, white_light);
87
 
88
	glEnable(GL_COLOR_MATERIAL);
89
	glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
90
	glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
91
	glMaterialf(GL_FRONT, GL_SHININESS, mat_shininess);
92
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
93
 
94
	glEnable(GL_LIGHTING);
95
	glEnable(GL_LIGHT0);
96
}
97
 
98
long list_get_id(char* name)
99
{
100
	long i;
101
	long n = strchr(name, '\'')-name;
102
	if(n) name[n] = 0;
103
	for(i=0;i
104
		if(!strcmp(name,b_list[i].name)) return b_list[i].id_l;
105
	}
106
	return b_list[0].id_l; //not found
107
}
108
 
109
long color_get_id(char* name)
110
{
111
	long i;
112
	char* buf;
113
	for(i=0;i
114
		buf = strchr(c_list[i].name, '=');
115
		if(buf){
116
			buf[0]=0;
117
			while(buf>c_list[i].name && buf[-1]==' '){
118
				buf--; buf[0]=0;
119
			};
120
		}
121
		while(name[0]==' '){
122
			name++;
123
		};
124
		if(!strcmp(name,c_list[i].name)) return i;
125
	}
126
	return -1; //not found
127
}
128
 
129
void draw_3d()
130
{
131
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //очистим буфер цвета и глубины
132
	glPushMatrix();
133
 
134
	if(b_list){
135
		SetLight();
136
		glTranslatef(0.0,0.0,0.5);
137
		glScalef(scale_o*rat_h,-scale_o,scale_o/4.0); // z/2.0
138
		glTranslatef(0.0, trans_z, 0.0);
139
		glRotatef(angle_x,1.0,0.0,0.0);
140
		glRotatef(angle_y,0.0,1.0,0.0);
141
		glRotatef(angle_z,0.0,0.0,1.0);
142
 
143
		long i;
144
		if(model_list){
145
			unsigned long pu_cou=0, pu_lvl=0;
146
			for(i=0;i
147
				while(model_list[i].level<=pu_lvl && pu_cou){
148
					pu_cou--;
149
					pu_lvl--;
150
					glPopMatrix();
151
				};
152
				pu_lvl=model_list[i].level;
153
				pu_cou++;
154
				glPushMatrix();
155
				glTranslatef(model_list[i].x, model_list[i].y, model_list[i].z);
156
				glRotatef(model_list[i].r_x, 1.0,0.0,0.0);
157
				glRotatef(model_list[i].r_y, 0.0,1.0,0.0);
158
				glRotatef(model_list[i].r_z, 0.0,0.0,1.0);
8875 IgorA 159
				if((check1.flags&ch_flag_en && model_list[i].t_cr==sb_tcr.position)||
160
				(!(check1.flags&ch_flag_en) && model_list[i].t_cr<=sb_tcr.position)){
8824 IgorA 161
				glColor3ub((model_list[i].color>>16)&255,
162
					(model_list[i].color>> 8)&255,
163
					model_list[i].color&255);
164
				glCallList(model_list[i].id_l);
8875 IgorA 165
				}
8824 IgorA 166
			}
167
			while(pu_cou){
168
				pu_cou--;
169
				glPopMatrix();
170
			};
171
		}
172
		else{
173
			glColor3f(1.0, 1.0, 0.0);
174
			glCallList(b_list[0].id_l);
175
		}
176
	}
177
 
178
	glPopMatrix();
179
}
180
 
181
void compile_list(BlockList *list){
182
	long int i;
183
	list->id_l = glGenLists(1);
184
	if(list->id_l<1) return; //not found
185
	glNewList(list->id_l, GL_COMPILE);
186
		glBegin(GL_TRIANGLES);
187
		for(i=0;ip_cou;i++){
188
			glNormal3fv((float*)(list->norm_d+i*3));
189
			glVertex3fv((float*)(list->vert_d+i*3));
190
		}
191
		glEnd();
192
	glEndList();
193
}
194
 
195
bool init_block(){
196
	FileInfoBlock* file;
197
	unsigned long int k;
198
 
8919 IgorA 199
	k = strlen(CurrentDirectoryPath);
200
	while(CurrentDirectoryPath[k] != '\\' && CurrentDirectoryPath[k] != '/' && k) {k--;};
201
	memcpy(library_path,CurrentDirectoryPath,k);
8925 IgorA 202
	if(library_path[k-1] != '/'){
203
		library_path[k] = '/';
204
		k++;
205
	}
8919 IgorA 206
	strcpy(library_path+k,"block.bin");
207
 
208
	file = FileOpen(library_path);
8824 IgorA 209
	if (!file){
8919 IgorA 210
		MessageBox("Error open file 'block.bin', file not found");
8824 IgorA 211
		return false;
212
	}
213
	k = FileGetLength(file);
214
	if (k > 0){
215
		if(b_data) delete b_data;
216
		b_data = new unsigned char[k];
217
 
218
		if (b_data){
219
			if(FileRead(file, b_data, k) != k){
220
				delete b_data; b_data = 0;
221
			}
222
			else if((long&)b_data[0]==0x4b43504b){ //"KPCK"
223
				k = (long&)b_data[4];
224
				f_data = new unsigned char[k];
225
				unpack(b_data, f_data);
226
				delete b_data;
227
				b_data = f_data;
228
				f_data = 0;
229
			}
230
		}
8919 IgorA 231
		FileClose(file);
232
	}
233
	else {
234
		MessageBox("Error open file 'block.bin', file length == 0");
235
		FileClose(file);
236
		return false;
8824 IgorA 237
	}
8919 IgorA 238
 
8824 IgorA 239
	if (b_data){
240
		unsigned long i=0, n=0;
241
		b_count=0;
242
		while((long&)b_data[i] && i
243
			while(b_data[i]){ i++; };
244
			i = (i|3)+1;
245
			i += 4+((long&)b_data[i])*24;
246
			b_count++;
247
		};
248
		b_list = new BlockList[b_count];
249
		i=0;
250
		while((long&)b_data[i] && i
251
			b_list[n].name = (unsigned char*)(b_data+i);
252
			while(b_data[i]){ i++; };
253
			i = (i|3)+1;
254
			b_list[n].p_cou = (long&)b_data[i];
255
			i += 4;
256
			b_list[n].vert_d = (float*)(b_data+i);
257
			i += b_list[n].p_cou*12;
258
			b_list[n].norm_d = (float*)(b_data+i);
259
			i += b_list[n].p_cou*12;
260
			compile_list(&b_list[n]);
261
			n++;
262
		};
8919 IgorA 263
	}
264
	else {
265
		MessageBox("Error open file 'block.bin', can't unpack file");
266
	}
8824 IgorA 267
	return (bool)b_data;
268
}
269
 
270
bool init_model()
271
{
8875 IgorA 272
	long i, n, max_time=0;
8824 IgorA 273
	char *ft = strstr(f_data, "const");
274
	char *fe; //end ']'
275
	char *fp; //perv ','
276
 
277
	c_count=0;
278
	while(ft && c_count
279
		fp = ft+5;
280
		while(fp[0]==' ') fp++;
281
		c_list[c_count].name = fp;
282
		ft = strchr(ft, '=')+1;
283
		fe = strchr(ft, ';');
284
		fe[0] = 0;
285
		c_list[c_count].color = StrToInt(ft);
286
		fe[0] = ';';
287
		c_count++;
288
		ft = strstr(ft, "const");
289
	}
290
 
291
	float mz_min=0.0, mz_max=0.0;
292
	ft = strstr(f_data, "model_list");
293
	if(ft==0) return false;
294
 
295
	m_count=0;
296
	fe=strchr(ft, ';');
297
	if(fe==0) return false;
298
	do{
299
		ft=strchr(ft, '[');
300
		ft=strchr(ft, ']');
301
		if(ft && ft
302
	}while(ft && ft
303
 
304
	if(model_list) delete model_list;
305
	model_list = new ModelList[m_count];
306
 
307
	ft = strstr(f_data, "model_list");
308
	ft=strchr(ft, '[')+1;
309
	for(i=0;i
310
		ft=strchr(ft, '[')+1;
311
		fe=strchr(ft, ']')+1;
312
		ft=strchr(ft, '\'')+1;
313
		model_list[i].name = ft;
314
		ft=strchr(ft, ',')+1; //color
315
 
316
		fp=ft;
317
		ft=strchr(ft, ',')+1;
318
		ft[-1]=0;
319
		n=color_get_id(fp);
320
		if(n>-1){
321
			model_list[i].color=c_list[n].color;
322
		}
323
		else{
324
			model_list[i].color=StrToInt(fp);
325
		}
326
 
327
		fp=ft;
328
		ft=strchr(ft, ',')+1;
329
		ft[-1]=0;
330
		model_list[i].t_cr=StrToInt(fp);
8875 IgorA 331
		if(model_list[i].t_cr>max_time) max_time=model_list[i].t_cr;
8824 IgorA 332
 
333
		fp=ft;
334
		ft=strchr(ft, ',')+1;
335
		ft[-1]=0;
336
		model_list[i].x=StrToDouble(fp);
337
 
338
		fp=ft;
339
		ft=strchr(ft, ',')+1;
340
		ft[-1]=0;
341
		model_list[i].y=StrToDouble(fp);
342
 
343
		fp=ft;
344
		ft=strchr(ft, ',')+1;
345
		ft[-1]=0;
346
		model_list[i].z=StrToDouble(fp);
347
 
348
		fp=ft;
349
		ft=strchr(ft, ',')+1;
350
		ft[-1]=0;
351
		model_list[i].r_x=StrToDouble(fp);
352
 
353
		fp=ft;
354
		ft=strchr(ft, ',')+1;
355
		ft[-1]=0;
356
		model_list[i].r_y=StrToDouble(fp);
357
 
358
		fp=ft;
359
		ft=strchr(ft, ',')+1;
360
		if(!ft || fe
361
			ft=fe;
362
			model_list[i].level=0;
363
			if(mz_min>model_list[i].z) mz_min=model_list[i].z;
364
			if(mz_max
365
		}
366
		ft[-1]=0;
367
		model_list[i].r_z=StrToDouble(fp);
368
		if(ft!=fe){
369
			fp=ft;
370
			ft=fe;
371
			ft[-1]=0;
372
			model_list[i].level=StrToInt(fp);
373
		}
374
		model_list[i].id_l = list_get_id(model_list[i].name);
375
	}
376
	trans_z = (mz_max-mz_min)/2.0;
377
	scale_o = .5/trans_z;
378
	angle_x = 135.0;
379
	angle_z = -45.0;
8875 IgorA 380
	sb_tcr.max_area = max_time+1;
381
	sb_tcr.position = max_time;
8824 IgorA 382
 
383
	return true;
384
}
385
 
386
void KolibriOnPaint(void);
387
 
388
void __stdcall DrawWindow()
389
{
390
	asm{
391
		push ebx
392
		mcall SF_REDRAW,SSF_BEGIN_DRAW
393
	}
394
	KolibriOnPaint();
395
	asm{
396
		mcall SF_REDRAW,SSF_END_DRAW
397
		pop ebx
398
	}
399
}
400
 
8849 IgorA 401
bool OpenModel(char* f_path)
402
{
403
	FileInfoBlock* file;
404
	unsigned long int k;
405
 
406
	file = FileOpen(f_path);
407
	if (!file){
408
		SetWindowCaption("Error open file ...");
409
		return false;
410
	}
411
	k = FileGetLength(file);
412
	if (k > 0){
413
		if(f_data) delete f_data;
414
		f_data = new unsigned char[k];
415
		if (f_data){
416
			if (FileRead(file, f_data, k) != k){
417
				delete f_data; f_data = 0;
418
			}
419
			else{
420
				init_model();
421
				draw_3d();
422
				SetWindowCaption(ofd.openfile_path);
423
				Redraw(1);
424
			}
425
		}
426
	}
427
	FileClose(file);
428
	return (bool)f_data;
429
}
430
 
8824 IgorA 431
bool KolibriOnStart(TStartData &kos_start, TThreadData /*th*/)
432
{
433
	kos_start.Left = 10;
434
	kos_start.Top = 40;
435
	kos_start.Width = 640;
436
	kos_start.Height = 480;
8875 IgorA 437
	kos_start.WinData.WindowColor = 0x333333;
8824 IgorA 438
	kos_start.WinData.WindowType = 0x33; // 0x34 - fixed, 0x33 - not fixed
439
	kos_start.WinData.Title = header;
440
 
441
	if(LoadLibrary("proc_lib.obj", library_path, "/sys/lib/proc_lib.obj", &import_proc_lib))
442
	{
443
		ofd.procinfo = procinfo;
444
		ofd.com_area_name = "FFFFFFFF_open_dialog";
445
		ofd.com_area = 0;
446
		ofd.opendir_path = plugin_path;
9585 vitalkrilo 447
		ofd.dir_default_path = "/sys";
448
		ofd.start_path = "/sys/File managers/opendial";
8824 IgorA 449
		ofd.draw_window = DrawWindow;
450
		ofd.status = 0;
451
		ofd.openfile_path = openfile_path;
452
		ofd.filename_area = filename_area;
453
		ofd.filter_area = &filter1;
454
		ofd.x_size = 420;
455
		ofd.x_start = 10;
456
		ofd.y_size = 320;
457
		ofd.y_start = 10;
458
		OpenDialog_Init(&ofd);
459
	} else return false;
8875 IgorA 460
	if(LoadLibrary("box_lib.obj", library_path, "/sys/lib/box_lib.obj", &import_box_lib))
461
	{
462
		check_box_init(&check1);
463
		sb_tcr.ar_offset=1;
464
	} else return false;
8824 IgorA 465
	if(LoadLibrary("tinygl.obj", library_path, "/sys/lib/tinygl.obj", &import_tinygl))
466
	{
8875 IgorA 467
		long h = kos_start.Height-TOOLBAR_H;
468
		kosglMakeCurrent(0,TOOLBAR_H,kos_start.Width,h,&ctx1);
469
		rat_h = h;
8824 IgorA 470
		rat_h /= kos_start.Width;
471
		angle_dwm = kos_start.Width/180.0;
8875 IgorA 472
		angle_dhm = h/180.0;
8824 IgorA 473
		glEnable(GL_DEPTH_TEST);
474
		glClearColor(0.2,0.2,0.2,0.0);
475
		glEnable(GL_NORMALIZE);
8849 IgorA 476
		if(init_block()){
477
			if(CommandLine[0]) OpenModel(CommandLine);
478
			return true;
479
		}
480
	}
481
	return false;
8824 IgorA 482
}
483
 
484
void KolibriOnPaint(void)
485
{
486
	kosglSwapBuffers();
487
 
488
	// If button have ID 1, this is close button
8875 IgorA 489
	DrawButton(2,0xf0f0f0, 10,4,50,19);
490
	DrawText(20,10,0,"Open");
8919 IgorA 491
	DrawRect(70,7, 24,18, 0x333333);
492
	DrawText(70,7,(1<<24)|0xffffff,DoubleToStr(sb_tcr.position,0,true));
8875 IgorA 493
	sb_tcr.all_redraw=1;
494
	scrollbar_h_draw(&sb_tcr);
495
	check_box_draw(&check1);
8824 IgorA 496
}
497
 
498
void KolibriOnButton(long id, TThreadData /*th*/)
499
{
500
	switch(id){
501
	case 2:
502
		ofd.type = 0; // 0 - open
503
		OpenDialog_Start(&ofd);
8849 IgorA 504
		if(ofd.status==1) OpenModel(ofd.openfile_path);
8824 IgorA 505
		//break;
506
	};
507
}
508
 
509
void KolibriOnKeyPress(TThreadData /*th*/)
510
{
511
	long key = GetKey();
512
	switch(key){
513
	case 178: //Up
514
		angle_x+=delt_size;
515
		draw_3d();
516
		kosglSwapBuffers();
517
		break;
518
	case 177: //Down
519
		angle_x-=delt_size;
520
		draw_3d();
521
		kosglSwapBuffers();
522
		break;
523
	case 176: //Left
524
		angle_z+=delt_size;
525
		draw_3d();
526
		kosglSwapBuffers();
527
		break;
528
	case 179: //Right
529
		angle_z-=delt_size;
530
		draw_3d();
531
		kosglSwapBuffers();
532
		//break;
533
	};
534
}
535
 
536
void KolibriOnMouse(TThreadData /*th*/)
537
{
538
	short m_x_old, m_y_old;
539
 
8875 IgorA 540
	long f, m = sb_tcr.position;
541
	f = check1.flags;
542
	scrollbar_h_mouse(&sb_tcr);
543
	check_box_mouse(&check1);
544
	if(sb_tcr.position!=m || check1.flags!=f){
545
		draw_3d();
546
		Invalidate();
547
		return;
548
	}
549
 
550
	m = GetMouseButton();
8824 IgorA 551
	if(m&1 && mouse_drag){
552
		//mouse l. but. move
553
		m_x_old = mouse_x;
554
		m_y_old = mouse_y;
555
		GetMousePosPicture(mouse_x, mouse_y);
556
 
557
		//если курсор движется по оси y (вверх или вниз) то поворот делаем вокруг оси x
558
		angle_x -= (m_y_old - mouse_y) / angle_dwm;
559
 
560
		//если курсор движется по оси x (влево или вправо) то поворот делаем вокруг оси z
561
		angle_z -= (m_x_old - mouse_x) / angle_dhm;
562
 
563
		draw_3d();
564
		kosglSwapBuffers();
565
	}
566
	if(m&0x10000){
567
		//mouse l. but. up
568
		mouse_drag=false;
569
	}
570
	if(m&0x100){
571
		//mouse l. but. press
572
		GetMousePosPicture(mouse_x, mouse_y);
8875 IgorA 573
		if(mouse_x>0 && mouse_y>TOOLBAR_H) mouse_drag=true;
8824 IgorA 574
	}
575
 
576
	GetMouseScrollData(m_x_old, m_y_old);
577
	if(m_y_old<0 && scale_o<0.5){
578
		scale_o *= 1.414213562;
579
		draw_3d();
580
		kosglSwapBuffers();
581
	}
582
	else if(m_y_old>0 && scale_o>0.005){
583
		scale_o /= 1.414213562;
584
		draw_3d();
585
		kosglSwapBuffers();
586
	}
587
}
588
 
8919 IgorA 589
void KolibriOnSize(int [], TThreadData /*th*/)
8824 IgorA 590
{
591
	unsigned short int width, height;
592
	GetClientSize(width, height);
593
	if(!width || !height) return;
8909 IgorA 594
	width--;
8875 IgorA 595
	height-=TOOLBAR_H;
8824 IgorA 596
	if(width<100) width=100;
597
	if(height<80) height=80;
598
	rat_h = (float)height / (float)width;
599
	angle_dwm = (float)width/180.0;
600
	angle_dhm = (float)height/180.0;
601
	glViewport(0, 0, width, height);
602
	draw_3d();
603
}
604
 
605
bool KolibriOnClose(TThreadData /*th*/)
606
{
607
	if(b_data){
608
		delete b_data;
609
		delete b_list;
610
	}
611
	if(f_data) delete f_data;
612
	if(model_list) delete model_list;
613
	return true;
9585 vitalkrilo 614
}