void list_pak(struct paki_args* args) { result_t r; struct pak_file pak; r = pak_open(&pak, mem_heap(), args->pakfile, 0); if (IS_FAIL(r)) { err_sendtolog(FALSE); return; } uint cnt = INVALID_INDEX; char* filelist = pak_createfilelist(&pak, mem_heap(), &cnt); pak_close(&pak); if (cnt == 0) { printf(TERM_BOLDWHITE "There are no files in the pak '%s'.\n" TERM_RESET, args->pakfile); return; } if (filelist == NULL) { printf(TERM_BOLDRED "Not enough memory.\n" TERM_RESET); return; } for (uint i = 0; i < cnt; i++) { printf(TERM_WHITE "%s\n" TERM_RESET, filelist + i*DH_PATH_MAX); } printf(TERM_BOLDWHITE "Total %d files in '%s'.\n" TERM_RESET, cnt, args->pakfile); FREE(filelist); }
void GLSL_LoadShader(GLuint *shader_id,char *filename, int type) { PFILE *f; int filesize; int bytes; char * buffer; int wasok; if(!EXTGL_shading_language) { *shader_id=0; sprintf (FANTASY_DEBUG_STRING, "Sorry, this card does not support GLSL\n"); Debug(DEBUG_LEVEL_WARNING); return; } f = pak_open(filename, "rb"); if (f == NULL) { sprintf (FANTASY_DEBUG_STRING, "Shader file %s not found\n",filename); Debug(DEBUG_LEVEL_ERROR); *shader_id=0; return; } // Find file size. pak_fseek(f, 0, SEEK_END); filesize = pak_ftell(f); pak_fseek(f, 0, SEEK_SET); buffer = (char *)malloc(filesize*sizeof(char)+1); if(!buffer) return; // Leemos el shader en memoria y lo almacenamos bytes = pak_read(buffer,1,filesize,f); pak_close(f); buffer[filesize*sizeof(char)] = '\0'; // Create shader if(type == GLSL_VERTEX_SHADER) *shader_id = f_glCreateShaderObjectARB( GL_VERTEX_SHADER_ARB ); else if (type == GLSL_FRAGMENT_SHADER) *shader_id = f_glCreateShaderObjectARB( GL_FRAGMENT_SHADER_ARB ); // Compile shader f_glShaderSourceARB( *shader_id, 1, (const char **)&buffer, NULL ); f_glCompileShaderARB( *shader_id); // Check for errors f_glGetObjectParameterivARB( *shader_id, GL_OBJECT_COMPILE_STATUS_ARB,&wasok); if( !wasok ) { f_glGetInfoLogARB(*shader_id, sizeof(errorString), NULL, errorString); sprintf (FANTASY_DEBUG_STRING, "Error compiling shader %s\n",filename); Debug(DEBUG_LEVEL_ERROR); sprintf (FANTASY_DEBUG_STRING, "%s\n",errorString); Debug(DEBUG_LEVEL_ERROR); *shader_id=0; return; } free(buffer); }
void load_pak(struct paki_args* args) { result_t r; struct pak_file pak; char filename[DH_PATH_MAX]; path_norm(args->pakfile, args->pakfile); path_tounix(args->path, args->path); r = pak_open(&pak, mem_heap(), args->pakfile, 0); if (IS_FAIL(r)) { err_sendtolog(FALSE); return; } uint file_id = pak_findfile(&pak, args->path); if (file_id == INVALID_INDEX) { printf(TERM_BOLDRED "Extract failed: file '%s' not found in pak.\n" TERM_RESET, args->path); pak_close(&pak); return; } path_getfullfilename(filename, args->path); file_t f = fio_createdisk(filename); if (f == NULL) { printf(TERM_BOLDRED "Extract failed: could not create '%s' for writing.\n" TERM_RESET, filename); pak_close(&pak); err_sendtolog(FALSE); return; } file_t src_file = pak_getfile(&pak, mem_heap(), mem_heap(), file_id, 0); if (src_file == NULL) { pak_close(&pak); fio_close(f); err_sendtolog(FALSE); return; } size_t size; struct allocator* alloc; void* buffer = fio_detachmem(src_file, &size, &alloc); fio_write(f, buffer, size, 1); A_FREE(alloc, buffer); fio_close(f); pak_close(&pak); if (BIT_CHECK(args->usage, PAKI_USAGE_VERBOSE)) { printf(TERM_WHITE "%s -> %s\n" TERM_RESET, args->path, filename); } args->file_cnt ++; // report printf(TERM_BOLDWHITE "Finished: total %d file(s) - %d error(s), %d warning(s)\n" TERM_RESET, args->file_cnt, args->err_cnt, args->warn_cnt); }
TSpline *SPLINE_New (char *filename) { int i; PFILE *fp; TSpline *spl; char magic[5]; fp = pak_open (filename, "rb"); assert (fp != NULL); // Check magic pak_read (magic, 1, 4, fp); magic[4] = '\0'; assert (!strcmp (magic, magic_binpoly)); spl = (TSpline *) malloc (sizeof (TSpline)); assert (spl != NULL); spl->tfactor = 1.0f; // Number of nodes => number of polynomials = nodes + 1 pak_read (&spl->nkeys, 4, 1, fp); assert (spl->nkeys != 0); spl->p = (TKey *) malloc ((spl->nkeys + 1) * sizeof (TKey)); assert (spl->p != NULL); for (i=0; i<spl->nkeys; i++) { // Read time pak_read (&spl->p[i].t, 4, 1, fp); // Read polynomial coefficients pak_read (spl->p[i].c, 4, 4, fp); } // Last polynomial spl->p[i].c[0] = 0.0f; spl->p[i].c[1] = 0.0f; spl->p[i].c[2] = 0.0f; pak_read (&spl->p[i].t, 4, 1, fp); pak_read (&spl->p[i].c[3], 4, 1, fp); spl->nkeys ++; pak_close (fp); spl->t0 = spl->p[0].t; spl->t1 = spl->p[i].t; //spl->loop_mode = SPLINE_LOOP_CONSTANT; //spl->loop_mode = SPLINE_LOOP_CONTINUITY; spl->loop_mode = SPLINE_LOOP_MOD; return spl; }
static vfs_archive pak_plugin_archive_open(const VFS_CHAR* archive,const VFS_CHAR* prefix,const VFS_CHAR* passwd) { return (vfs_archive)pak_open(archive,prefix); }
int main(int argc, char **argv) { bool extract = true; char *redirout = (char*)stdout; char *redirerr = (char*)stderr; char *file = NULL; char **files = NULL; pak_file_t *pak = NULL; size_t iter = 0; con_init(); /* * Command line option parsing commences now We only need to support * a few things in the test suite. */ while (argc > 1) { ++argv; --argc; if (argv[0][0] == '-') { if (parsecmd("redirout", &argc, &argv, &redirout, 1, false)) continue; if (parsecmd("redirerr", &argc, &argv, &redirerr, 1, false)) continue; if (parsecmd("file", &argc, &argv, &file, 1, false)) continue; con_change(redirout, redirerr); switch (argv[0][1]) { case 'e': extract = true; continue; case 'c': extract = false; continue; } if (!strcmp(argv[0]+1, "debug")) { OPTS_OPTION_BOOL(OPTION_DEBUG) = true; continue; } if (!strcmp(argv[0]+1, "memchk")) { OPTS_OPTION_BOOL(OPTION_MEMCHK) = true; continue; } if (!strcmp(argv[0]+1, "nocolor")) { con_color(0); continue; } } vec_push(files, argv[0]); } con_change(redirout, redirerr); if (!file) { con_err("-file must be specified for output/input PAK file\n"); vec_free(files); return EXIT_FAILURE; } if (extract) { if (!(pak = pak_open(file, "r"))) { con_err("failed to open PAK file %s\n", file); vec_free(files); return EXIT_FAILURE; } if (!pak_extract_all(pak, "./")) { con_err("failed to extract PAK %s (files may be missing)\n", file); pak_close(pak); vec_free(files); return EXIT_FAILURE; } /* not possible */ pak_close(pak); vec_free(files); stat_info(); return EXIT_SUCCESS; } if (!(pak = pak_open(file, "w"))) { con_err("failed to open PAK %s for writing\n", file); vec_free(files); return EXIT_FAILURE; } for (iter = 0; iter < vec_size(files); iter++) { if (!(pak_insert_one(pak, files[iter]))) { con_err("failed inserting %s for PAK %s\n", files[iter], file); pak_close(pak); vec_free(files); return EXIT_FAILURE; } } /* not possible */ pak_close(pak); vec_free(files); stat_info(); return EXIT_SUCCESS; }
result_t eng_init(const struct init_params* params) { result_t r = RET_OK; ASSERT(g_eng == NULL); g_eng = (struct engine*)ALLOC(sizeof(struct engine), 0); if (g_eng == 0) return err_printn(__FILE__, __LINE__, RET_OUTOFMEMORY); memset(g_eng, 0x00, sizeof(struct engine)); eng_zero(); memcpy(&g_eng->params, params, sizeof(struct init_params)); hw_getinfo(&g_eng->hwinfo, HWINFO_ALL); /* console (before anything else) */ if (BIT_CHECK(params->flags, ENG_FLAG_CONSOLE)) { r |= con_init(params->console_lines_max); if (IS_FAIL(r)) return RET_FAIL; log_outputfunc(TRUE, con_log, NULL); } /* show build options */ #if !defined(FULL_VERSION) #error "must define FULL_VERSION macro" #endif time_t raw_tm; time(&raw_tm); log_printf(LOG_TEXT, "init darkhammer engine v%s build[%s, %s, %s, %s], time: %s", FULL_VERSION, #if defined(_DEBUG_) "debug" #else "release" #endif , #if defined(_PROFILE_) "profile" #else "no-profile" #endif , #if defined(_X86_) "x86" #elif defined(_X64_) "x64" #endif , #if defined(_ENABLEASSERT_) "assert" #else "no-assert" #endif , asctime(localtime(&raw_tm))); /* hardware info */ hw_printinfo(&g_eng->hwinfo, HWINFO_ALL); size_t tmp_sz = params->dev.buffsize_tmp; size_t data_sz = data_sz = params->dev.buffsize_data; tmp_sz = tmp_sz != 0 ? ((size_t)tmp_sz*1024) : FRAME_STACK_SIZE; data_sz = data_sz != 0 ? ((size_t)data_sz*1024) : DATA_SIZE; /* allocators */ /* dynamic allocator for data in dev (editor) mode, stack allocator in game (normal) mode */ if (BIT_CHECK(params->flags, ENG_FLAG_OPTIMIZEMEMORY)) { /* lsr (load-stay-resident) allocator for essential engine data */ r |= mem_stack_create(mem_heap(), &g_eng->lsr_stack, LSR_SIZE, MID_DATA); mem_stack_bindalloc(&g_eng->lsr_stack, &g_eng->lsr_alloc); r |= mem_freelist_create(mem_heap(), &g_eng->data_freelist, data_sz, MID_DATA); mem_freelist_bindalloc(&g_eng->data_freelist, &g_eng->data_alloc); } else { mem_heap_bindalloc(&g_eng->data_alloc); mem_heap_bindalloc(&g_eng->lsr_alloc); g_eng->data_alloc.alloc_fn = eng_allocfn_data; g_eng->data_alloc.alignedalloc_fn = eng_alignedallocfn_data; g_eng->lsr_alloc.alloc_fn = eng_allocfn_lsr; g_eng->lsr_alloc.alignedalloc_fn = eng_alignedallocfn_lsr; r = RET_OK; } if (IS_FAIL(r)) { err_print(__FILE__, __LINE__, "engine init failed: out of memory for allocators"); return RET_FAIL; } /* timer manager and frame timer */ g_eng->timer = timer_createinstance(TRUE); /* add engine's own data path to file-mgr */ if (params->data_path != NULL) { char data_path_ext[DH_PATH_MAX]; path_getfileext(data_path_ext, params->data_path); if (str_isequal_nocase(data_path_ext, "pak")) { if (IS_FAIL(pak_open(&g_eng->data_pak, mem_heap(), params->data_path, 0))) { err_print(__FILE__, __LINE__, "engine init: could not open data pak"); return RET_FAIL; } } else { if (!util_pathisdir(params->data_path)) { err_print(__FILE__, __LINE__, "engine init: data path is not valid"); return RET_FAIL; } fio_addvdir(params->data_path, FALSE); } /* assume that share directory is same as data dir */ path_getdir(g_eng->share_dir, params->data_path); } else { char data_path[DH_PATH_MAX]; char share_dir[DH_PATH_MAX]; #ifndef SHARE_DIR char exe_dir[DH_PATH_MAX]; path_join(share_dir, util_getexedir(exe_dir), "..", NULL); path_norm(share_dir, share_dir); #else path_norm(share_dir, SHARE_DIR); #endif path_join(data_path, share_dir, "data", NULL); if (!util_pathisdir(data_path)) { err_print(__FILE__, __LINE__, "engine init: data path is not valid"); return RET_FAIL; } fio_addvdir(data_path, FALSE); /* set default (config.h configured on build) data dir */ strcpy(g_eng->share_dir, share_dir); } uint rs_flags = 0; /* activate hot loading in DEV mode */ rs_flags |= BIT_CHECK(params->flags, ENG_FLAG_DEV) ? RS_FLAG_HOTLOADING : 0; if (!BIT_CHECK(params->flags, ENG_FLAG_DISABLEBGLOAD)) { rs_flags |= RS_FLAG_PREPARE_BGLOAD; } /* task manager */ uint thread_cnt = maxui(g_eng->hwinfo.cpu_core_cnt - 1, 1); r = tsk_initmgr(thread_cnt, 0, tmp_sz, 0); if (IS_FAIL(r)) { err_print(__FILE__, __LINE__, "engine init failed: could not init task-mgr"); return RET_FAIL; } struct allocator* tmp_alloc = tsk_get_tmpalloc(0); A_SAVE(tmp_alloc); /* resource manager (with only 1 thread for multi-thread loading) */ r = rs_initmgr(rs_flags, 1); if (IS_FAIL(r)) { err_print(__FILE__, __LINE__, "engine init failed: could not init res-mgr"); return RET_FAIL; } rs_set_dataalloc(&g_eng->lsr_alloc); /* graphics renderer */ r = gfx_init(¶ms->gfx); if (IS_FAIL(r)) { err_print(__FILE__, __LINE__, "engine init failed: could not init gfx"); return RET_FAIL; } /* debug HUD */ r = hud_init(BIT_CHECK(params->flags, ENG_FLAG_CONSOLE)); if (IS_FAIL(r)) { err_print(__FILE__, __LINE__, "engine init failed: could not init debug-hud"); return RET_FAIL; } /* Physics */ if (!BIT_CHECK(params->flags, ENG_FLAG_DISABLEPHX)) { r = phx_init(params); if (IS_FAIL(r)) { err_print(__FILE__, __LINE__, "engine init failed: could not init physics"); return RET_FAIL; } } /* component manager */ r = cmp_initmgr(); if (IS_FAIL(r)) { err_print(__FILE__, __LINE__, "engine init failed: could not init cmp-mgr"); return RET_FAIL; } cmp_set_globalalloc(&g_eng->data_alloc, tsk_get_tmpalloc(0)); /* world manager */ r = wld_initmgr(); if (IS_FAIL(r)) { err_print(__FILE__, __LINE__, "engine init failed: could not init world-mgr"); return RET_FAIL; } /* scene manager */ r = scn_initmgr(); if (IS_FAIL(r)) { err_print(__FILE__, __LINE__, "engine init failed: could not init scene-mgr"); return RET_FAIL; } /* init lua */ r = sct_init(¶ms->sct, BIT_CHECK(params->flags, ENG_FLAG_DEV) ? TRUE : FALSE); if (IS_FAIL(r)) { err_print(__FILE__, __LINE__, "engine init failed: could not init script engine"); return RET_FAIL; } /* web-server */ #if defined(_PROFILE_) r = prf_initmgr(); if (IS_FAIL(r)) { log_print(LOG_WARNING, "profiler manager init failed: service will not be available"); prf_releasemgr(); } #endif /* lod-scheme */ r = lod_initmgr(); if (IS_FAIL(r)) { err_print(__FILE__, __LINE__, "engine init failed: could not init lod-scheme"); return RET_FAIL; } /* init basic resources */ r = rs_init_resources(); if (IS_FAIL(r)) { err_print(__FILE__, __LINE__, "engine init failed: coult not init res-mgr resources"); return RET_FAIL; } /* switch back to normal data allocator */ rs_set_dataalloc(&g_eng->data_alloc); /* enable background-loading if res-mgr is prepared for (see above rs_initmgr) */ if (gfx_check_feature(GFX_FEATURE_THREADED_CREATES)) rs_add_flags(RS_FLAG_BGLOADING); log_print(LOG_TEXT, "init ok: ready."); /* init world vars */ eng_world_regvars(); /* engine specific console commnads */ con_register_cmd("showfps", eng_console_showfps, NULL, "showfps [1*/0]"); con_register_cmd("showft", eng_console_showft, NULL, "showft [1*/0]"); con_register_cmd("showgraph", eng_console_showgraph, NULL, "showgraph [ft][fps][drawcalls]"); con_register_cmd("lockfps", eng_console_lockfps, NULL, "lockfps [fps]"); /* execute console commands - should be the final stage if initialization */ if (BIT_CHECK(params->flags, ENG_FLAG_CONSOLE)) { for (uint i = 0; i < params->console_cmds_cnt; i++) { con_exec(params->console_cmds + i*128); } } A_LOAD(tmp_alloc); return RET_OK; }
int Material::MatReader(char *filename) { material *matpointer=NULL; PFILE *p; char cadena[256]; char cadena2[256]; char texname[256]; char *token; char separadores [] = " \t"; int i,j; int nmats=0; // Number of materials int curmat=0; // Material currently being loaded int ntextures; p = pak_open(filename,"r"); if(!p) return -1; while(pak_fgets(cadena,256,p)) { if((cadena[0] == '\n') || (cadena[0] == '#')) continue; // Saltamos comentarios y líneas en blanco token = strtok(cadena,separadores); token2string(token,cadena2); if(!strcmp(cadena2,"nmaterials")) // Leemos el número de materiales y seguimos { token = strtok(NULL,separadores); token2string(token,cadena2); nmats = atoi(cadena2); matpointer = (material *) malloc(nmats * sizeof(material)); if(!matpointer) return -1; continue; } else // En este caso hemos cogido el nombre de un material { if(!nmats) { sprintf (FANTASY_DEBUG_STRING, "Fallo al leer el fichero %s\n",filename); Debug(DEBUG_LEVEL_ERROR); return -1; } if(curmat >= nmats) { sprintf (FANTASY_DEBUG_STRING, "Error en el archivo %s. Tenemos más materiales de los definidos en nmats\n",filename); Debug(DEBUG_LEVEL_ERROR); return -1; } // Inicializamos algunos valores por defecto matpointer[curmat].specular[0] = matpointer[curmat].specular[1] = matpointer[curmat].specular[2] = 0.0f; matpointer[curmat].emission[0] = matpointer[curmat].emission[1] = matpointer[curmat].emission[2] = 0.0f; matpointer[curmat].specular[3] = 1.0f; matpointer[curmat].emission[3] = 1.0f; matpointer[curmat].shininess = 0.0f; // Empezamos con la juerga! strcpy(matpointer[curmat].matname,cadena2); token = strtok(NULL,separadores); // Ahora leemos si es estático o dinámico token2string(token,cadena2); if(!strcmp(cadena2,"static")) // Material estático { matpointer[curmat].shader_based = 0; } else if(!strcmp(cadena2,"shader")) // Shader based material { matpointer[curmat].shader_based = 1; } else { sprintf (FANTASY_DEBUG_STRING, "Material %s no valido. No es static ni shader\n",matpointer[curmat].matname); Debug(DEBUG_LEVEL_ERROR); return -1; } // En caso de ser un shader, lo siguiente son los ficheros de los shader if(matpointer[curmat].shader_based == 1 ) { token = strtok(NULL,separadores); token2string(token,cadena2); if(strcmp(cadena2,"standard")) // If shader_name == "standard", we are using the opengl pipeline GLSL_LoadShader(&(matpointer[curmat].shader.vertexShader),cadena2, GLSL_VERTEX_SHADER); else matpointer[curmat].shader.vertexShader = 0; token = strtok(NULL,separadores); token2string(token,cadena2); // There must always be a fragment shader GLSL_LoadShader(&(matpointer[curmat].shader.fragmentShader),cadena2, GLSL_FRAGMENT_SHADER); // CompileandLinkShader... GLSL_CompileAndLinkShader(&(matpointer[curmat].shader.programObj), matpointer[curmat].shader.vertexShader, matpointer[curmat].shader.fragmentShader); // GetBasicUniforms GLSL_GetUniforms(&(matpointer[curmat])); matpointer[curmat].shader.params.used=0; // no custom parameters to the shader } else // No shader, so let's fill the variables... { matpointer[curmat].shader.vertexShader = 0; matpointer[curmat].shader.fragmentShader = 0; matpointer[curmat].shader.programObj = 0; } token = strtok(NULL,separadores); // Ahora leemos si es opaco o transparente token2string(token,cadena2); if(!strcmp(cadena2,"opaque")) // Material opaco { matpointer[curmat].opaque = 1; matpointer[curmat].blend_type=-1; token = strtok(NULL,separadores); // Ahora leemos si es opaco o transparente token2string(token,cadena2); if(!strcmp(cadena2,"2sided")) // Material con 2 caras { matpointer[curmat].twosided = 1; } else if(!strcmp(cadena2,"1sided")) // Material con 2 caras { matpointer[curmat].twosided = 0; } else { sprintf (FANTASY_DEBUG_STRING, "Material %s no valido. No tiene 1 ni 2 caras\n",matpointer[curmat].matname); Debug(DEBUG_LEVEL_ERROR); return -1; } } else if(!strcmp(cadena2,"transp")) // Material traslúcido { matpointer[curmat].opaque=0; token = strtok(NULL,separadores); // Ahora leemos si es opaco o transparente token2string(token,cadena2); if(!strcmp(cadena2,"2sided")) // Material con 2 caras { matpointer[curmat].twosided = 1; } else if(!strcmp(cadena2,"1sided")) // Material con 2 caras { matpointer[curmat].twosided = 0; } else { sprintf (FANTASY_DEBUG_STRING, "Material %s no valido. No tiene 1 ni 2 caras\n",matpointer[curmat].matname); Debug(DEBUG_LEVEL_ERROR); return -1; } token = strtok(NULL,separadores); // Ahora leemos el tipo de blend token2string(token,cadena2); if(!strcmp(cadena2,"add")) // Blend aditivo { matpointer[curmat].blend_type=BLEND_ADD; } else if(!strcmp(cadena2,"blend")) // Blend normal { matpointer[curmat].blend_type=BLEND_BLEND; } else if(!strcmp(cadena2,"multiply")) // Blend multiplicativo { matpointer[curmat].blend_type=BLEND_MULTIPLY; } else if(!strcmp(cadena2,"sub")) // Blend sustractivo { matpointer[curmat].blend_type=BLEND_SUB; } else { sprintf (FANTASY_DEBUG_STRING, "Material %s no valido. El blend no es valido\n",matpointer[curmat].matname); Debug(DEBUG_LEVEL_ERROR); return -1; } } else { sprintf (FANTASY_DEBUG_STRING, "Material %s no valido. No es opaque ni transp\n",matpointer[curmat].matname); Debug(DEBUG_LEVEL_ERROR); return -1; } // Hasta aquí tenemos el nombre del material, que es estático, su opacidad y el tipo de blend si aplica. // Nos falta leer el número de texturas y las texturas token = strtok(NULL,separadores); token2string(token,cadena2); ntextures= atoi(cadena2); if(ntextures < 0) { sprintf (FANTASY_DEBUG_STRING, "Material %s no valido. No puede tener menos de 0 texturas\n",matpointer[curmat].matname); Debug(DEBUG_LEVEL_ERROR); return -1; } else if(ntextures == 0) { matpointer[curmat].textures=NULL; matpointer[curmat].multitexblend=NULL; matpointer[curmat].texcoordgen=NULL; } else if(ntextures == 1) { matpointer[curmat].textures = (int *) malloc (ntextures * sizeof(int)); matpointer[curmat].multitexblend = (int *) malloc ((ntextures) * sizeof(int)); matpointer[curmat].texcoordgen = (int *) malloc ((ntextures) * sizeof(int));; matpointer[curmat].linearmultiplier = (float *)malloc((ntextures) * sizeof(float)); } else { matpointer[curmat].textures = (int *) malloc (ntextures * sizeof(int)); matpointer[curmat].multitexblend = (int *) malloc ((ntextures) * sizeof(int)); matpointer[curmat].texcoordgen = (int *) malloc ((ntextures) * sizeof(int)); matpointer[curmat].linearmultiplier = (float *)malloc((ntextures) * sizeof(float)); } matpointer[curmat].ntextures = ntextures; // Cargamos las texturas for(i=0;i<ntextures;i++) { token = strtok(NULL,separadores); token2string(token,cadena2); // La carga de la textura la haremos después de conocer si hay cubemap o no! strcpy(texname,cadena2); // Carga del tipo de coordenadas de textura // En caso de usar shader, aunque se ignoren los tipos de coordenada, lo usamos // para saber cuándo una textura es un cubemap... token = strtok(NULL,separadores); token2string(token,cadena2); if((!strcmp(cadena2,"same")) || (!strcmp(cadena2,"uv"))) { matpointer[curmat].texcoordgen[i]=TEXGEN_UV; } else if(!strcmp(cadena2,"eyelinear")) { matpointer[curmat].texcoordgen[i]=TEXGEN_EYE_LINEAR; if(matpointer[curmat].shader_based == 1 ) { sprintf (FANTASY_DEBUG_STRING, "Warning: el material %s está basado en shader, pero se ha seleccionado texgen tipo eyelinear. Pongo UV\n",matpointer[curmat].matname); Debug(DEBUG_LEVEL_ERROR); matpointer[curmat].texcoordgen[i]=TEXGEN_UV; } } else if(!strcmp(cadena2,"objectlinear")) { matpointer[curmat].texcoordgen[i]=TEXGEN_OBJECT_LINEAR; if(matpointer[curmat].shader_based == 1 ) { sprintf (FANTASY_DEBUG_STRING, "Warning: el material %s está basado en shader, pero se ha seleccionado texgen tipo objectlinear. Pongo UV\n",matpointer[curmat].matname); Debug(DEBUG_LEVEL_ERROR); matpointer[curmat].texcoordgen[i]=TEXGEN_UV; } } else if(!strcmp(cadena2,"spheremap")) { matpointer[curmat].texcoordgen[i]=TEXGEN_SPHERE_MAP; if(matpointer[curmat].shader_based == 1 ) { sprintf (FANTASY_DEBUG_STRING, "Warning: el material %s está basado en shader, pero se ha seleccionado texgen tipo spheremap. Pongo UV\n",matpointer[curmat].matname); Debug(DEBUG_LEVEL_ERROR); matpointer[curmat].texcoordgen[i]=TEXGEN_UV; } } else if(!strcmp(cadena2,"cubemap")) { matpointer[curmat].texcoordgen[i]=TEXGEN_CUBE_MAP; } // Ahora podemos cargar la textura if(matpointer[curmat].texcoordgen[i] != TEXGEN_CUBE_MAP) { matpointer[curmat].textures[i] = ConjuntoTexturas->CargaTextura(texname); } else { matpointer[curmat].textures[i] = ConjuntoTexturas->CargaCubeMap(texname); } // Si las coordenadas son eyelinear u objectlinear, cogemos el multiplicador if((matpointer[curmat].texcoordgen[i]==TEXGEN_OBJECT_LINEAR) || (matpointer[curmat].texcoordgen[i]==TEXGEN_EYE_LINEAR)) { token = strtok(NULL,separadores); token2string(token,cadena2); matpointer[curmat].linearmultiplier[i]=atof(cadena2); } // Finalmente, si no es la primera unidad de textura, vemos qué tipo de blend // utiliza esta unidad de textura if((i>0) && (matpointer[curmat].shader_based != 1)) // Para tipo shader no se carga { token = strtok(NULL,separadores); token2string(token,cadena2); if(!strcmp(cadena2,"add")) // Blend aditivo { matpointer[curmat].multitexblend[i]=BLEND_ADD; } else if(!strcmp(cadena2,"modulate")) // Modulate { matpointer[curmat].multitexblend[i]=BLEND_MODULATE; } else if(!strcmp(cadena2,"mask")) // Mask { matpointer[curmat].multitexblend[i]=BLEND_MASK; } else if(!strcmp(cadena2,"mask2")) // Mask { matpointer[curmat].multitexblend[i]=BLEND_MASK2; } else if(!strcmp(cadena2,"dot3")) // Dot3 bump mapping { matpointer[curmat].multitexblend[i]=BLEND_DOT3; } else // Por defecto dejamos replace, para darnos cuenta del error { sprintf (FANTASY_DEBUG_STRING, "Material %s no valido. Multitex blend no valido\n",matpointer[curmat].matname); Debug(DEBUG_LEVEL_ERROR); return -1; } } else matpointer[curmat].multitexblend[i]=BLEND_MODULATE; } // Fin del bucle for // Ahora vamos a cargar los parámetros relativos a la iluminación. Ojo, que son opcionales, // y pueden ir en cualquier orden!!! for(i=0;i<3;i++) { token = strtok(NULL,separadores); if(token == NULL) break; token2string(token,cadena2); if(!strcmp(cadena2,"specular")) { for(j=0;j<3;j++) // Leemos las 4 componentes { token = strtok(NULL,separadores); token2string(token,cadena2); matpointer[curmat].specular[j]=2.0f*atof(cadena2); } matpointer[curmat].specular[3] = 1.0f; } else if(!strcmp(cadena2,"emission")) { for(j=0;j<3;j++) // Leemos las 4 componentes { token = strtok(NULL,separadores); token2string(token,cadena2); matpointer[curmat].emission[j]=atof(cadena2); } matpointer[curmat].emission[j] = 1.0f; } else if((!strcmp(cadena2,"shininess")) || (!strcmp(cadena2,"glossiness"))) { token = strtok(NULL,separadores); token2string(token,cadena2); matpointer[curmat].shininess=atof(cadena2); } else { sprintf (FANTASY_DEBUG_STRING, "Material %s no valido. Parámetros de iluminación no válidos\n",matpointer[curmat].matname); Debug(DEBUG_LEVEL_ERROR); return -1; } } } curmat++; } materiales = matpointer; numero_materiales = nmats; pak_close(p); if(curmat < nmats) { sprintf (FANTASY_DEBUG_STRING, "Fallo al leer el archivo de materiales %s. Hay menos materiales de los definidos en nmats\n",filename); Debug(DEBUG_LEVEL_ERROR); return -1; } return nmats; }