Subversion Repositories Kolibri OS

Rev

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