void save_pak(struct paki_args* args) { result_t r; struct pak_file pak; path_norm(args->pakfile, args->pakfile); path_norm(args->path, args->path); r = pak_create(&pak, mem_heap(), args->pakfile, args->compress_mode, 0); if (IS_FAIL(r)) { err_sendtolog(FALSE); return; } r = compress_directory(&pak, args, ""); if (IS_FAIL(r)) { err_sendtolog(FALSE); pak_close(&pak); return; } pak_close(&pak); // report printf(TERM_BOLDWHITE "Saved pak: '%s'\nTotal %d file(s) - %d Error(s), %d Warning(s)\n" TERM_RESET, args->pakfile, args->file_cnt, args->err_cnt, args->warn_cnt); }
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); }
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 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); }
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; }
void eng_release() { if (g_eng == NULL) return; rs_release_resources(); lod_releasemgr(); #if !defined(_DEBUG_) pak_close(&g_eng->data_pak); #endif prf_releasemgr(); sct_release(); wld_releasemgr(); scn_releasemgr(); cmp_releasemgr(); phx_release(); hud_release(); gfx_release(); rs_reportleaks(); rs_releasemgr(); tsk_releasemgr(); if (g_eng->timer != NULL) timer_destroyinstance(g_eng->timer); /* check for main memory leaks */ if (BIT_CHECK(g_eng->params.flags, ENG_FLAG_DEV)) { int leak_cnt = mem_freelist_getleaks(&g_eng->data_freelist, NULL); if (leak_cnt > 0) log_printf(LOG_WARNING, "%d leaks found on dynamic 'data' memory", leak_cnt); } mem_freelist_destroy(&g_eng->data_freelist); mem_stack_destroy(&g_eng->lsr_stack); log_print(LOG_TEXT, "engine released."); if (BIT_CHECK(g_eng->params.flags, ENG_FLAG_CONSOLE)) { log_outputfunc(FALSE, NULL, NULL); con_release(); } FREE(g_eng); g_eng = NULL; }
static VFS_VOID pak_plugin_archive_close( vfs_archive archive) { pak_close((pak*)archive); }
void make_pak(char *input, char *output, bool compress, bool verbose) { time_last = time(NULL); DIR* dir; struct dirent * dent; char* basepath = input; dir = opendir(basepath); if (!dir) { exit(EXIT_FAILURE); } pak_handle_t* handle = pak_open_write(output); printf("Building entry, string and data files..."); fflush(stdout); char dataTempNam[FILENAME_MAX]; gen_random(dataTempNam, 44); char dataTempPath[FILENAME_MAX]; memset(dataTempPath, 0, FILENAME_MAX); sprintf(dataTempPath, "/tmp/%s.data", dataTempNam); char stringTempPath[FILENAME_MAX]; memset(stringTempPath, 0, FILENAME_MAX); sprintf(stringTempPath, "/tmp/%s.string", dataTempNam); char entryTempPath[FILENAME_MAX]; memset(entryTempPath, 0, FILENAME_MAX); sprintf(entryTempPath, "/tmp/%s.entry", dataTempNam); FILE* dataFile = fopen(dataTempPath, "wb"); FILE* entryFile = fopen(entryTempPath, "wb"); FILE* stringFile = fopen(stringTempPath, "wb"); uint64_t idx = 0; while ((dent = readdir(dir)) != NULL) { if ((time(NULL) - time_last) > 1) { printf("."); fflush(stdout); time_last = time(NULL); } if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) continue; curpath[0] = '\0'; strcat(curpath, basepath); idx = pak_file_or_dir(dent, idx, entryFile, stringFile, dataFile, compress, verbose); } printf("\nBuilding pak...\n"); closedir(dir); fclose(dataFile); fclose(stringFile); fclose(entryFile); // now to build the file // first reopen the temp data struct stat64 st; entryFile = fopen(entryTempPath, "rb"); stringFile = fopen(stringTempPath, "rb"); dataFile = fopen(dataTempPath, "rb"); // read entry table stat64(entryTempPath, &st); size_t entryTableSize = st.st_size; size_t entryCount = entryTableSize / sizeof(pak_entry_t); char* entryTableBuf = malloc(entryTableSize); fread(entryTableBuf, 1, entryTableSize, entryFile); // read string table stat64(stringTempPath, &st); size_t stringTableSize = st.st_size; char* stringTableBuf = malloc(stringTableSize); fread(stringTableBuf, 1, stringTableSize, stringFile); // read data table stat64(dataTempPath, &st); size_t dataTableSize = st.st_size; // close files fclose(entryFile); fclose(stringFile); // TODO: Make this manageable pak_set_entry_start(handle, (sizeof(pak_header_t) + 31) & ~31); pak_set_entry_count(handle, entryCount); pak_set_string_table_offset(handle, (handle->header->entry_start + entryTableSize + 31) & ~31); pak_set_string_table_size(handle, stringTableSize); pak_set_data_offset(handle, (handle->header->string_table_offset + stringTableSize + 31) & ~31); // pad buffers size_t paddedEntryBufSize = (entryTableSize + 31) & ~31; char* paddedEntryBuf = malloc(paddedEntryBufSize); pak_clear(paddedEntryBuf, paddedEntryBufSize); memcpy(paddedEntryBuf, entryTableBuf, entryTableSize); free(entryTableBuf); size_t paddedStringBufSize = (stringTableSize + 31) & ~31; char* paddedStringBuf = malloc(paddedStringBufSize); pak_clear(paddedStringBuf, paddedStringBufSize); memcpy(paddedStringBuf, stringTableBuf, stringTableSize); free(stringTableBuf); // write pak FILE* pak = handle->file; if (pak) { fwrite(handle->header, 1, sizeof(pak_header_t), pak); fseeko64(pak, (sizeof(pak_header_t) + 31) & ~31, SEEK_SET); fwrite(paddedEntryBuf, 1, paddedEntryBufSize, pak); fwrite(paddedStringBuf, 1, paddedStringBufSize, pak); size_t bytesRead = 0; size_t blockSize = BUF_SIZ; while(bytesRead < dataTableSize) { if (blockSize > dataTableSize - bytesRead) blockSize = dataTableSize - bytesRead; char buf[blockSize]; size_t nextReadSize = fread(buf, 1, blockSize, dataFile); if (nextReadSize <= 0) break; // error or early EOF! fwrite(buf, 1, nextReadSize, pak); bytesRead += nextReadSize; } } fclose(dataFile); printf("Stored %" PRIu64 " files (%s)\n", pak_get_entry_count(handle), (compress ? "compressed" : "uncompressed")); pak_close(handle); free(paddedEntryBuf); free(paddedStringBuf); remove(entryTempPath); remove(stringTempPath); remove(dataTempPath); }
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; }
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; }