static enum EVSFPrivopLoginResult handle_anonymous_login(struct vsf_session* p_sess, const struct mystr* p_pass_str) { if (!str_isempty(&p_sess->banned_email_str) && str_contains_line(&p_sess->banned_email_str, p_pass_str)) { return kVSFLoginFail; } if (!str_isempty(&p_sess->email_passwords_str) && (!str_contains_line(&p_sess->email_passwords_str, p_pass_str) || str_isempty(p_pass_str))) { return kVSFLoginFail; } /* Store the anonymous identity string */ str_copy(&p_sess->anon_pass_str, p_pass_str); if (str_isempty(&p_sess->anon_pass_str)) { str_alloc_text(&p_sess->anon_pass_str, "?"); } /* "Fix" any characters which might upset the log processing */ str_replace_char(&p_sess->anon_pass_str, ' ', '_'); str_replace_char(&p_sess->anon_pass_str, '\n', '?'); { struct mystr ftp_username_str = INIT_MYSTR; str_alloc_text(&ftp_username_str, tunable_ftp_username); setup_username_globals(p_sess, &ftp_username_str); str_free(&ftp_username_str); } str_free(&p_sess->banned_email_str); str_free(&p_sess->email_passwords_str); return kVSFLoginAnon; }
void _ipmi_sensors_args_validate (struct ipmi_sensors_arguments *cmd_args) { if (cmd_args->groups_length) { int i; for (i = 0; i < cmd_args->groups_length; i++) { int j = 0; int found = 0; while (ipmi_sensor_types[j]) { char sdr_group_name_subst[IPMI_SENSORS_MAX_GROUPS_STRING_LENGTH]; strcpy(sdr_group_name_subst, ipmi_sensor_types[j]); str_replace_char (sdr_group_name_subst, ' ', '_'); str_replace_char (sdr_group_name_subst, '/', '_'); if (!strcasecmp (cmd_args->groups[i], ipmi_sensor_types[j]) || !strcasecmp (cmd_args->groups[i], sdr_group_name_subst)) { found++; break; } j++; } if (!found) { char sdr_group_name_subst[IPMI_SENSORS_MAX_GROUPS_STRING_LENGTH]; strcpy(sdr_group_name_subst, ipmi_oem_sensor_type); str_replace_char (sdr_group_name_subst, ' ', '_'); str_replace_char (sdr_group_name_subst, '/', '_'); if (!strcasecmp (cmd_args->groups[i], ipmi_oem_sensor_type) || !strcasecmp (cmd_args->groups[i], sdr_group_name_subst)) found++; } if (!found) { fprintf(stderr, "invalid sensor group '%s'\n", cmd_args->groups[i]); exit(1); } } } }
static void ftp_write_str_common(struct vsf_session* p_sess, int status, char sep, const struct mystr* p_str) { static struct mystr s_write_buf_str; static struct mystr s_text_mangle_str; int retval; if (tunable_log_ftp_protocol) { str_alloc_ulong(&s_write_buf_str, (unsigned long) status); str_append_char(&s_write_buf_str, sep); str_append_str(&s_write_buf_str, p_str); vsf_log_line(p_sess, kVSFLogEntryFTPOutput, &s_write_buf_str); } str_copy(&s_text_mangle_str, p_str); /* Process the output response according to the specifications.. */ /* Escape telnet characters properly */ str_replace_text(&s_text_mangle_str, "\377", "\377\377"); /* Change \n for \0 in response */ str_replace_char(&s_text_mangle_str, '\n', '\0'); /* Build string to squirt down network */ str_alloc_ulong(&s_write_buf_str, (unsigned long) status); str_append_char(&s_write_buf_str, sep); str_append_str(&s_write_buf_str, &s_text_mangle_str); str_append_text(&s_write_buf_str, "\r\n"); retval = ftp_write_str(p_sess, &s_write_buf_str, kVSFRWControl); if (retval != 0) { die("ftp_write"); } }
static int control_getline(struct mystr* p_str, struct vsf_session* p_sess) { int ret; if (p_sess->p_control_line_buf == 0) { vsf_secbuf_alloc(&p_sess->p_control_line_buf, VSFTP_MAX_COMMAND_LINE); } ret = ftp_getline(p_sess, p_str, p_sess->p_control_line_buf); if (ret == 0) { return ret; } else if (ret < 0) { vsf_cmdio_write_exit(p_sess, FTP_BADCMD, "Input line too long.", 1); } /* As mandated by the FTP specifications.. */ str_replace_char(p_str, '\0', '\n'); /* If the last character is a \r, strip it */ { unsigned int len = str_getlen(p_str); while (len > 0 && str_get_char_at(p_str, len - 1) == '\r') { str_trunc(p_str, len - 1); --len; } } return 1; }
void ContentFeatures::setInventoryTextureCube(std::string top, std::string left, std::string right) { if(g_texturesource == NULL) return; str_replace_char(top, '^', '&'); str_replace_char(left, '^', '&'); str_replace_char(right, '^', '&'); std::string imgname_full; imgname_full += "[inventorycube{"; imgname_full += top; imgname_full += "{"; imgname_full += left; imgname_full += "{"; imgname_full += right; inventory_texture = g_texturesource->getTextureRaw(imgname_full); }
/** * Clear Response string */ void res_clear(char *dst, char *src) { size_t ln; char *tmp; ln = strlen(src); bzero(dst, ln); tmp = (char *) calloc(sizeof(char), ln + 1); str_replace_char(tmp, src, '\r', '\n'); str_trim_doubles(dst, tmp, '\n'); free(tmp); }
static void control_getline(struct mystr* p_str, struct vsf_session* p_sess) { if (p_sess->p_control_line_buf == 0) { vsf_secbuf_alloc(&p_sess->p_control_line_buf, VSFTP_MAX_COMMAND_LINE); } ftp_getline(p_sess, p_str, p_sess->p_control_line_buf); /* As mandated by the FTP specifications.. */ str_replace_char(p_str, '\0', '\n'); /* If the last character is a \r, strip it */ { unsigned int len = str_getlen(p_str); while (len > 0 && str_get_char_at(p_str, len - 1) == '\r') { str_trunc(p_str, len - 1); --len; } } }
static void ftp_getline(struct mystr* p_str) { static char* s_p_readline_buf; if (s_p_readline_buf == 0) { vsf_secbuf_alloc(&s_p_readline_buf, VSFTP_MAX_COMMAND_LINE); } str_netfd_alloc(p_str, VSFTP_COMMAND_FD, '\n', s_p_readline_buf, VSFTP_MAX_COMMAND_LINE); /* As mandated by the FTP specifications.. */ str_replace_char(p_str, '\0', '\n'); /* If the last character is a \r, strip it */ { unsigned int len = str_getlen(p_str); if (len > 0 && str_get_char_at(p_str, len - 1) == '\r') { str_trunc(p_str, len - 1); } } }
char * construct_uri (const char * path, const char * reference) { /* URI */ if (strstr (path, "://")) return str_get (path); /* absolute filename */ #ifdef _WIN32 if (path[0] && path[1] == ':' && path[2] == '\\') #else if (path[0] == '/') #endif return filename_to_uri (path); /* relative path */ const char * slash = strrchr (reference, '/'); if (! slash) return NULL; char * utf8 = str_to_utf8 (path, -1); if (! utf8) return NULL; int pathlen = slash + 1 - reference; char buf[pathlen + 3 * strlen (utf8) + 1]; memcpy (buf, reference, pathlen); if (get_bool (NULL, "convert_backslash")) { SCOPY (tmp, utf8); str_replace_char (tmp, '\\', '/'); str_encode_percent (tmp, -1, buf + pathlen); } else str_encode_percent (utf8, -1, buf + pathlen); str_unref (utf8); return str_get (buf); }
static void vsf_log_do_log_wuftpd_format(struct vsf_session* p_sess, struct mystr* p_str, int succeeded) { static struct mystr s_filename_str; long delta_sec; enum EVSFLogEntryType what = (enum EVSFLogEntryType) p_sess->log_type; /* Date - vsf_sysutil_get_current_date updates cached time */ str_alloc_text(p_str, vsf_sysutil_get_current_date()); str_append_char(p_str, ' '); /* Transfer time (in seconds) */ delta_sec = vsf_sysutil_get_cached_time_sec() - p_sess->log_start_sec; if (delta_sec <= 0) { delta_sec = 1; } str_append_ulong(p_str, (unsigned long) delta_sec); str_append_char(p_str, ' '); /* Remote host name */ str_append_str(p_str, &p_sess->remote_ip_str); str_append_char(p_str, ' '); /* Bytes transferred */ str_append_filesize_t(p_str, p_sess->transfer_size); str_append_char(p_str, ' '); /* Filename */ str_copy(&s_filename_str, &p_sess->log_str); str_replace_char(&s_filename_str, ' ', '_'); str_append_str(p_str, &s_filename_str); str_append_char(p_str, ' '); /* Transfer type (ascii/binary) */ if (p_sess->is_ascii) { str_append_text(p_str, "a "); } else { str_append_text(p_str, "b "); } /* Special action flag - tar, gzip etc. */ str_append_text(p_str, "_ "); /* Direction of transfer */ if (what == kVSFLogEntryUpload) { str_append_text(p_str, "i "); } else { str_append_text(p_str, "o "); } /* Access mode: anonymous/real user, and identity */ if (p_sess->is_anonymous && !p_sess->is_guest) { str_append_text(p_str, "a "); str_append_str(p_str, &p_sess->anon_pass_str); } else { if (p_sess->is_guest) { str_append_text(p_str, "g "); } else { str_append_text(p_str, "r "); } str_append_str(p_str, &p_sess->user_str); } str_append_char(p_str, ' '); /* Service name, authentication method, authentication user id */ str_append_text(p_str, "ftp 0 * "); /* Completion status */ if (succeeded) { str_append_char(p_str, 'c'); } else { str_append_char(p_str, 'i'); } }
static void handle_pasv(struct vsf_session* p_sess, int is_epsv) { static struct mystr s_pasv_res_str; static struct vsf_sysutil_sockaddr* s_p_sockaddr; int bind_retries = 10; unsigned short the_port = 0; int is_ipv6 = vsf_sysutil_sockaddr_is_ipv6(p_sess->p_local_addr); if (is_epsv && !str_isempty(&p_sess->ftp_arg_str)) { int argval; str_upper(&p_sess->ftp_arg_str); if (str_equal_text(&p_sess->ftp_arg_str, "ALL")) { p_sess->epsv_all = 1; vsf_cmdio_write(p_sess, FTP_EPSVALLOK, "EPSV ALL ok."); return; } argval = vsf_sysutil_atoi(str_getbuf(&p_sess->ftp_arg_str)); if (!is_ipv6 || argval != 2) { vsf_cmdio_write(p_sess, FTP_EPSVBAD, "Bad network protocol."); return; } } pasv_cleanup(p_sess); port_cleanup(p_sess); if (is_epsv && is_ipv6) { p_sess->pasv_listen_fd = vsf_sysutil_get_ipv6_sock(); } else { p_sess->pasv_listen_fd = vsf_sysutil_get_ipv4_sock(); } vsf_sysutil_activate_reuseaddr(p_sess->pasv_listen_fd); while (--bind_retries) { int retval; double scaled_port; /* IPPORT_RESERVED */ unsigned short min_port = 1024; unsigned short max_port = 65535; if (tunable_pasv_min_port > min_port && tunable_pasv_min_port <= max_port) { min_port = tunable_pasv_min_port; } if (tunable_pasv_max_port >= min_port && tunable_pasv_max_port < max_port) { max_port = tunable_pasv_max_port; } the_port = vsf_sysutil_get_random_byte(); the_port <<= 8; the_port |= vsf_sysutil_get_random_byte(); scaled_port = (double) min_port; scaled_port += ((double) the_port / (double) 65536) * ((double) max_port - min_port + 1); the_port = (unsigned short) scaled_port; vsf_sysutil_sockaddr_clone(&s_p_sockaddr, p_sess->p_local_addr); vsf_sysutil_sockaddr_set_port(s_p_sockaddr, the_port); retval = vsf_sysutil_bind(p_sess->pasv_listen_fd, s_p_sockaddr); if (!vsf_sysutil_retval_is_error(retval)) { break; } if (vsf_sysutil_get_error() == kVSFSysUtilErrADDRINUSE) { continue; } die("vsf_sysutil_bind"); } if (!bind_retries) { die("vsf_sysutil_bind"); } vsf_sysutil_listen(p_sess->pasv_listen_fd, 1); if (is_epsv) { str_alloc_text(&s_pasv_res_str, "Entering Extended Passive Mode (|||"); str_append_ulong(&s_pasv_res_str, (unsigned long) the_port); str_append_text(&s_pasv_res_str, "|)"); vsf_cmdio_write_str(p_sess, FTP_EPSVOK, &s_pasv_res_str); return; } if (tunable_pasv_address != 0) { /* Report passive address as specified in configuration */ if (vsf_sysutil_inet_aton(tunable_pasv_address, s_p_sockaddr) == 0) { die("invalid pasv_address"); } } str_alloc_text(&s_pasv_res_str, "Entering Passive Mode ("); if (!is_ipv6) { str_append_text(&s_pasv_res_str, vsf_sysutil_inet_ntop(s_p_sockaddr)); } else { const void* p_v4addr = vsf_sysutil_sockaddr_ipv6_v4(s_p_sockaddr); if (p_v4addr) { str_append_text(&s_pasv_res_str, vsf_sysutil_inet_ntoa(p_v4addr)); } } str_replace_char(&s_pasv_res_str, '.', ','); str_append_text(&s_pasv_res_str, ","); str_append_ulong(&s_pasv_res_str, the_port >> 8); str_append_text(&s_pasv_res_str, ","); str_append_ulong(&s_pasv_res_str, the_port & 255); str_append_text(&s_pasv_res_str, ")"); vsf_cmdio_write_str(p_sess, FTP_PASVOK, &s_pasv_res_str); }
gchar * __normalize_key(const gchar* buffer) { return str_replace_char(buffer, '-', '_'); }
bool TextureSource::generateImage(std::string part_of_name, video::IImage *& baseimg) { video::IVideoDriver* driver = m_device->getVideoDriver(); assert(driver); // Stuff starting with [ are special commands if(part_of_name.size() == 0 || part_of_name[0] != '[') { video::IImage *image = m_sourcecache.getOrLoad(part_of_name, m_device); if(image == NULL) { if(part_of_name != ""){ errorstream<<"generateImage(): Could not load image \"" <<part_of_name<<"\""<<" while building texture"<<std::endl; errorstream<<"generateImage(): Creating a dummy" <<" image for \""<<part_of_name<<"\""<<std::endl; } // Just create a dummy image //core::dimension2d<u32> dim(2,2); core::dimension2d<u32> dim(1,1); image = driver->createImage(video::ECF_A8R8G8B8, dim); assert(image); /*image->setPixel(0,0, video::SColor(255,255,0,0)); image->setPixel(1,0, video::SColor(255,0,255,0)); image->setPixel(0,1, video::SColor(255,0,0,255)); image->setPixel(1,1, video::SColor(255,255,0,255));*/ image->setPixel(0,0, video::SColor(255,myrand()%256, myrand()%256,myrand()%256)); /*image->setPixel(1,0, video::SColor(255,myrand()%256, myrand()%256,myrand()%256)); image->setPixel(0,1, video::SColor(255,myrand()%256, myrand()%256,myrand()%256)); image->setPixel(1,1, video::SColor(255,myrand()%256, myrand()%256,myrand()%256));*/ } // If base image is NULL, load as base. if(baseimg == NULL) { //infostream<<"Setting "<<part_of_name<<" as base"<<std::endl; /* Copy it this way to get an alpha channel. Otherwise images with alpha cannot be blitted on images that don't have alpha in the original file. */ core::dimension2d<u32> dim = image->getDimension(); baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); image->copyTo(baseimg); } // Else blit on base. else { //infostream<<"Blitting "<<part_of_name<<" on base"<<std::endl; // Size of the copied area core::dimension2d<u32> dim = image->getDimension(); //core::dimension2d<u32> dim(16,16); // Position to copy the blitted to in the base image core::position2d<s32> pos_to(0,0); // Position to copy the blitted from in the blitted image core::position2d<s32> pos_from(0,0); // Blit /*image->copyToWithAlpha(baseimg, pos_to, core::rect<s32>(pos_from, dim), video::SColor(255,255,255,255), NULL);*/ blit_with_alpha(image, baseimg, pos_from, pos_to, dim); } //cleanup image->drop(); } else { // A special texture modification /*infostream<<"generateImage(): generating special " <<"modification \""<<part_of_name<<"\"" <<std::endl;*/ /* [crack:N:P [cracko:N:P Adds a cracking texture N = animation frame count, P = crack progression */ if(part_of_name.substr(0,6) == "[crack") { if(baseimg == NULL) { errorstream<<"generateImage(): baseimg==NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } // Crack image number and overlay option bool use_overlay = (part_of_name[6] == 'o'); Strfnd sf(part_of_name); sf.next(":"); s32 frame_count = stoi(sf.next(":")); s32 progression = stoi(sf.next(":")); /* Load crack image. It is an image with a number of cracking stages horizontally tiled. */ video::IImage *img_crack = m_sourcecache.getOrLoad( "crack_anylength.png", m_device); if(img_crack && progression >= 0) { draw_crack(img_crack, baseimg, use_overlay, frame_count, progression, driver); img_crack->drop(); } } /* [combine:WxH:X,Y=filename:X,Y=filename2 Creates a bigger texture from an amount of smaller ones */ else if(part_of_name.substr(0,8) == "[combine") { Strfnd sf(part_of_name); sf.next(":"); u32 w0 = stoi(sf.next("x")); u32 h0 = stoi(sf.next(":")); infostream<<"combined w="<<w0<<" h="<<h0<<std::endl; core::dimension2d<u32> dim(w0,h0); if(baseimg == NULL) { baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); baseimg->fill(video::SColor(0,0,0,0)); } while(sf.atend() == false) { u32 x = stoi(sf.next(",")); u32 y = stoi(sf.next("=")); std::string filename = sf.next(":"); infostream<<"Adding \""<<filename <<"\" to combined ("<<x<<","<<y<<")" <<std::endl; video::IImage *img = m_sourcecache.getOrLoad(filename, m_device); if(img) { core::dimension2d<u32> dim = img->getDimension(); infostream<<"Size "<<dim.Width <<"x"<<dim.Height<<std::endl; core::position2d<s32> pos_base(x, y); video::IImage *img2 = driver->createImage(video::ECF_A8R8G8B8, dim); img->copyTo(img2); img->drop(); /*img2->copyToWithAlpha(baseimg, pos_base, core::rect<s32>(v2s32(0,0), dim), video::SColor(255,255,255,255), NULL);*/ blit_with_alpha(img2, baseimg, v2s32(0,0), pos_base, dim); img2->drop(); } else { infostream<<"img==NULL"<<std::endl; } } } /* "[brighten" */ else if(part_of_name.substr(0,9) == "[brighten") { if(baseimg == NULL) { errorstream<<"generateImage(): baseimg==NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } brighten(baseimg); } /* "[noalpha" Make image completely opaque. Used for the leaves texture when in old leaves mode, so that the transparent parts don't look completely black when simple alpha channel is used for rendering. */ else if(part_of_name.substr(0,8) == "[noalpha") { if(baseimg == NULL) { errorstream<<"generateImage(): baseimg==NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } core::dimension2d<u32> dim = baseimg->getDimension(); // Set alpha to full for(u32 y=0; y<dim.Height; y++) for(u32 x=0; x<dim.Width; x++) { video::SColor c = baseimg->getPixel(x,y); c.setAlpha(255); baseimg->setPixel(x,y,c); } } /* "[makealpha:R,G,B" Convert one color to transparent. */ else if(part_of_name.substr(0,11) == "[makealpha:") { if(baseimg == NULL) { errorstream<<"generateImage(): baseimg==NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } Strfnd sf(part_of_name.substr(11)); u32 r1 = stoi(sf.next(",")); u32 g1 = stoi(sf.next(",")); u32 b1 = stoi(sf.next("")); std::string filename = sf.next(""); core::dimension2d<u32> dim = baseimg->getDimension(); /*video::IImage *oldbaseimg = baseimg; baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); oldbaseimg->copyTo(baseimg); oldbaseimg->drop();*/ // Set alpha to full for(u32 y=0; y<dim.Height; y++) for(u32 x=0; x<dim.Width; x++) { video::SColor c = baseimg->getPixel(x,y); u32 r = c.getRed(); u32 g = c.getGreen(); u32 b = c.getBlue(); if(!(r == r1 && g == g1 && b == b1)) continue; c.setAlpha(0); baseimg->setPixel(x,y,c); } } /* "[transformN" Rotates and/or flips the image. N can be a number (between 0 and 7) or a transform name. Rotations are counter-clockwise. 0 I identity 1 R90 rotate by 90 degrees 2 R180 rotate by 180 degrees 3 R270 rotate by 270 degrees 4 FX flip X 5 FXR90 flip X then rotate by 90 degrees 6 FY flip Y 7 FYR90 flip Y then rotate by 90 degrees Note: Transform names can be concatenated to produce their product (applies the first then the second). The resulting transform will be equivalent to one of the eight existing ones, though (see: dihedral group). */ else if(part_of_name.substr(0,10) == "[transform") { if(baseimg == NULL) { errorstream<<"generateImage(): baseimg==NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } u32 transform = parseImageTransform(part_of_name.substr(10)); core::dimension2d<u32> dim = imageTransformDimension( transform, baseimg->getDimension()); video::IImage *image = driver->createImage( baseimg->getColorFormat(), dim); assert(image); imageTransform(transform, baseimg, image); baseimg->drop(); baseimg = image; } /* [inventorycube{topimage{leftimage{rightimage In every subimage, replace ^ with &. Create an "inventory cube". NOTE: This should be used only on its own. Example (a grass block (not actually used in game): "[inventorycube{grass.png{mud.png&grass_side.png{mud.png&grass_side.png" */ else if(part_of_name.substr(0,14) == "[inventorycube") { if(baseimg != NULL) { errorstream<<"generateImage(): baseimg!=NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } str_replace_char(part_of_name, '&', '^'); Strfnd sf(part_of_name); sf.next("{"); std::string imagename_top = sf.next("{"); std::string imagename_left = sf.next("{"); std::string imagename_right = sf.next("{"); // Generate images for the faces of the cube video::IImage *img_top = generateImageFromScratch(imagename_top); video::IImage *img_left = generateImageFromScratch(imagename_left); video::IImage *img_right = generateImageFromScratch(imagename_right); assert(img_top && img_left && img_right); // Create textures from images video::ITexture *texture_top = driver->addTexture( (imagename_top + "__temp__").c_str(), img_top); video::ITexture *texture_left = driver->addTexture( (imagename_left + "__temp__").c_str(), img_left); video::ITexture *texture_right = driver->addTexture( (imagename_right + "__temp__").c_str(), img_right); assert(texture_top && texture_left && texture_right); // Drop images img_top->drop(); img_left->drop(); img_right->drop(); /* Draw a cube mesh into a render target texture */ scene::IMesh* cube = createCubeMesh(v3f(1, 1, 1)); setMeshColor(cube, video::SColor(255, 255, 255, 255)); cube->getMeshBuffer(0)->getMaterial().setTexture(0, texture_top); cube->getMeshBuffer(1)->getMaterial().setTexture(0, texture_top); cube->getMeshBuffer(2)->getMaterial().setTexture(0, texture_right); cube->getMeshBuffer(3)->getMaterial().setTexture(0, texture_right); cube->getMeshBuffer(4)->getMaterial().setTexture(0, texture_left); cube->getMeshBuffer(5)->getMaterial().setTexture(0, texture_left); TextureFromMeshParams params; params.mesh = cube; params.dim.set(64, 64); params.rtt_texture_name = part_of_name + "_RTT"; // We will delete the rtt texture ourselves params.delete_texture_on_shutdown = false; params.camera_position.set(0, 1.0, -1.5); params.camera_position.rotateXZBy(45); params.camera_lookat.set(0, 0, 0); // Set orthogonal projection params.camera_projection_matrix.buildProjectionMatrixOrthoLH( 1.65, 1.65, 0, 100); params.ambient_light.set(1.0, 0.2, 0.2, 0.2); params.light_position.set(10, 100, -50); params.light_color.set(1.0, 0.5, 0.5, 0.5); params.light_radius = 1000; video::ITexture *rtt = generateTextureFromMesh(params); // Drop mesh cube->drop(); // Free textures of images driver->removeTexture(texture_top); driver->removeTexture(texture_left); driver->removeTexture(texture_right); if(rtt == NULL) { baseimg = generateImageFromScratch(imagename_top); return true; } // Create image of render target video::IImage *image = driver->createImage(rtt, v2s32(0,0), params.dim); assert(image); // Cleanup texture driver->removeTexture(rtt); baseimg = driver->createImage(video::ECF_A8R8G8B8, params.dim); if(image) { image->copyTo(baseimg); image->drop(); } } /* [lowpart:percent:filename Adds the lower part of a texture */ else if(part_of_name.substr(0,9) == "[lowpart:") { Strfnd sf(part_of_name); sf.next(":"); u32 percent = stoi(sf.next(":")); std::string filename = sf.next(":"); //infostream<<"power part "<<percent<<"%% of "<<filename<<std::endl; if(baseimg == NULL) baseimg = driver->createImage(video::ECF_A8R8G8B8, v2u32(16,16)); video::IImage *img = m_sourcecache.getOrLoad(filename, m_device); if(img) { core::dimension2d<u32> dim = img->getDimension(); core::position2d<s32> pos_base(0, 0); video::IImage *img2 = driver->createImage(video::ECF_A8R8G8B8, dim); img->copyTo(img2); img->drop(); core::position2d<s32> clippos(0, 0); clippos.Y = dim.Height * (100-percent) / 100; core::dimension2d<u32> clipdim = dim; clipdim.Height = clipdim.Height * percent / 100 + 1; core::rect<s32> cliprect(clippos, clipdim); img2->copyToWithAlpha(baseimg, pos_base, core::rect<s32>(v2s32(0,0), dim), video::SColor(255,255,255,255), &cliprect); img2->drop(); } } /* [verticalframe:N:I Crops a frame of a vertical animation. N = frame count, I = frame index */ else if(part_of_name.substr(0,15) == "[verticalframe:") { Strfnd sf(part_of_name); sf.next(":"); u32 frame_count = stoi(sf.next(":")); u32 frame_index = stoi(sf.next(":")); if(baseimg == NULL){ errorstream<<"generateImage(): baseimg!=NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } v2u32 frame_size = baseimg->getDimension(); if (frame_count) frame_size.Y /= frame_count; video::IImage *img = driver->createImage(video::ECF_A8R8G8B8, frame_size); if(!img){ errorstream<<"generateImage(): Could not create image " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } // Fill target image with transparency img->fill(video::SColor(0,0,0,0)); core::dimension2d<u32> dim = frame_size; core::position2d<s32> pos_dst(0, 0); core::position2d<s32> pos_src(0, frame_index * frame_size.Y); baseimg->copyToWithAlpha(img, pos_dst, core::rect<s32>(pos_src, dim), video::SColor(255,255,255,255), NULL); // Replace baseimg baseimg->drop(); baseimg = img; } else { errorstream<<"generateImage(): Invalid " " modification: \""<<part_of_name<<"\""<<std::endl; } } return true; }
bool generate_image(std::string part_of_name, video::IImage *& baseimg, IrrlichtDevice *device, SourceImageCache *sourcecache) { video::IVideoDriver* driver = device->getVideoDriver(); assert(driver); // Stuff starting with [ are special commands if(part_of_name.size() == 0 || part_of_name[0] != '[') { video::IImage *image = sourcecache->getOrLoad(part_of_name, device); if(image == NULL) { if(part_of_name != ""){ errorstream<<"generate_image(): Could not load image \"" <<part_of_name<<"\""<<" while building texture"<<std::endl; errorstream<<"generate_image(): Creating a dummy" <<" image for \""<<part_of_name<<"\""<<std::endl; } // Just create a dummy image //core::dimension2d<u32> dim(2,2); core::dimension2d<u32> dim(1,1); image = driver->createImage(video::ECF_A8R8G8B8, dim); assert(image); /*image->setPixel(0,0, video::SColor(255,255,0,0)); image->setPixel(1,0, video::SColor(255,0,255,0)); image->setPixel(0,1, video::SColor(255,0,0,255)); image->setPixel(1,1, video::SColor(255,255,0,255));*/ image->setPixel(0,0, video::SColor(255,myrand()%256, myrand()%256,myrand()%256)); /*image->setPixel(1,0, video::SColor(255,myrand()%256, myrand()%256,myrand()%256)); image->setPixel(0,1, video::SColor(255,myrand()%256, myrand()%256,myrand()%256)); image->setPixel(1,1, video::SColor(255,myrand()%256, myrand()%256,myrand()%256));*/ } // If base image is NULL, load as base. if(baseimg == NULL) { //infostream<<"Setting "<<part_of_name<<" as base"<<std::endl; /* Copy it this way to get an alpha channel. Otherwise images with alpha cannot be blitted on images that don't have alpha in the original file. */ core::dimension2d<u32> dim = image->getDimension(); baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); image->copyTo(baseimg); image->drop(); } // Else blit on base. else { //infostream<<"Blitting "<<part_of_name<<" on base"<<std::endl; // Size of the copied area core::dimension2d<u32> dim = image->getDimension(); //core::dimension2d<u32> dim(16,16); // Position to copy the blitted to in the base image core::position2d<s32> pos_to(0,0); // Position to copy the blitted from in the blitted image core::position2d<s32> pos_from(0,0); // Blit image->copyToWithAlpha(baseimg, pos_to, core::rect<s32>(pos_from, dim), video::SColor(255,255,255,255), NULL); // Drop image image->drop(); } } else { // A special texture modification /*infostream<<"generate_image(): generating special " <<"modification \""<<part_of_name<<"\"" <<std::endl;*/ /* This is the simplest of all; it just adds stuff to the name so that a separate texture is created. It is used to make textures for stuff that doesn't want to implement getting the texture from a bigger texture atlas. */ if(part_of_name == "[forcesingle") { // If base image is NULL, create a random color if(baseimg == NULL) { core::dimension2d<u32> dim(1,1); baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); assert(baseimg); baseimg->setPixel(0,0, video::SColor(255,myrand()%256, myrand()%256,myrand()%256)); } } /* [crackN Adds a cracking texture */ else if(part_of_name.substr(0,6) == "[crack") { if(baseimg == NULL) { errorstream<<"generate_image(): baseimg==NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } // Crack image number and overlay option s32 progression = 0; bool use_overlay = false; if(part_of_name.substr(6,1) == "o") { progression = stoi(part_of_name.substr(7)); use_overlay = true; } else { progression = stoi(part_of_name.substr(6)); use_overlay = false; } // Size of the base image core::dimension2d<u32> dim_base = baseimg->getDimension(); /* Load crack image. It is an image with a number of cracking stages horizontally tiled. */ video::IImage *img_crack = sourcecache->getOrLoad("crack.png", device); if(img_crack && progression >= 0) { // Dimension of original image core::dimension2d<u32> dim_crack = img_crack->getDimension(); // Count of crack stages s32 crack_count = dim_crack.Height / dim_crack.Width; // Limit progression if(progression > crack_count-1) progression = crack_count-1; // Dimension of a single crack stage core::dimension2d<u32> dim_crack_cropped( dim_crack.Width, dim_crack.Width ); // Create cropped and scaled crack images video::IImage *img_crack_cropped = driver->createImage( video::ECF_A8R8G8B8, dim_crack_cropped); video::IImage *img_crack_scaled = driver->createImage( video::ECF_A8R8G8B8, dim_base); if(img_crack_cropped && img_crack_scaled) { // Crop crack image v2s32 pos_crack(0, progression*dim_crack.Width); img_crack->copyTo(img_crack_cropped, v2s32(0,0), core::rect<s32>(pos_crack, dim_crack_cropped)); // Scale crack image by copying img_crack_cropped->copyToScaling(img_crack_scaled); // Copy or overlay crack image if(use_overlay) { overlay(baseimg, img_crack_scaled); } else { img_crack_scaled->copyToWithAlpha( baseimg, v2s32(0,0), core::rect<s32>(v2s32(0,0), dim_base), video::SColor(255,255,255,255)); } } if(img_crack_scaled) img_crack_scaled->drop(); if(img_crack_cropped) img_crack_cropped->drop(); img_crack->drop(); } } /* [combine:WxH:X,Y=filename:X,Y=filename2 Creates a bigger texture from an amount of smaller ones */ else if(part_of_name.substr(0,8) == "[combine") { Strfnd sf(part_of_name); sf.next(":"); u32 w0 = stoi(sf.next("x")); u32 h0 = stoi(sf.next(":")); infostream<<"combined w="<<w0<<" h="<<h0<<std::endl; core::dimension2d<u32> dim(w0,h0); baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); while(sf.atend() == false) { u32 x = stoi(sf.next(",")); u32 y = stoi(sf.next("=")); std::string filename = sf.next(":"); infostream<<"Adding \""<<filename <<"\" to combined ("<<x<<","<<y<<")" <<std::endl; video::IImage *img = sourcecache->getOrLoad(filename, device); if(img) { core::dimension2d<u32> dim = img->getDimension(); infostream<<"Size "<<dim.Width <<"x"<<dim.Height<<std::endl; core::position2d<s32> pos_base(x, y); video::IImage *img2 = driver->createImage(video::ECF_A8R8G8B8, dim); img->copyTo(img2); img->drop(); img2->copyToWithAlpha(baseimg, pos_base, core::rect<s32>(v2s32(0,0), dim), video::SColor(255,255,255,255), NULL); img2->drop(); } else { infostream<<"img==NULL"<<std::endl; } } } /* "[brighten" */ else if(part_of_name.substr(0,9) == "[brighten") { if(baseimg == NULL) { errorstream<<"generate_image(): baseimg==NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } brighten(baseimg); } /* "[noalpha" Make image completely opaque. Used for the leaves texture when in old leaves mode, so that the transparent parts don't look completely black when simple alpha channel is used for rendering. */ else if(part_of_name.substr(0,8) == "[noalpha") { if(baseimg == NULL) { errorstream<<"generate_image(): baseimg==NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } core::dimension2d<u32> dim = baseimg->getDimension(); // Set alpha to full for(u32 y=0; y<dim.Height; y++) for(u32 x=0; x<dim.Width; x++) { video::SColor c = baseimg->getPixel(x,y); c.setAlpha(255); baseimg->setPixel(x,y,c); } } /* "[makealpha:R,G,B" Convert one color to transparent. */ else if(part_of_name.substr(0,11) == "[makealpha:") { if(baseimg == NULL) { errorstream<<"generate_image(): baseimg==NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } Strfnd sf(part_of_name.substr(11)); u32 r1 = stoi(sf.next(",")); u32 g1 = stoi(sf.next(",")); u32 b1 = stoi(sf.next("")); std::string filename = sf.next(""); core::dimension2d<u32> dim = baseimg->getDimension(); /*video::IImage *oldbaseimg = baseimg; baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); oldbaseimg->copyTo(baseimg); oldbaseimg->drop();*/ // Set alpha to full for(u32 y=0; y<dim.Height; y++) for(u32 x=0; x<dim.Width; x++) { video::SColor c = baseimg->getPixel(x,y); u32 r = c.getRed(); u32 g = c.getGreen(); u32 b = c.getBlue(); if(!(r == r1 && g == g1 && b == b1)) continue; c.setAlpha(0); baseimg->setPixel(x,y,c); } } /* [inventorycube{topimage{leftimage{rightimage In every subimage, replace ^ with &. Create an "inventory cube". NOTE: This should be used only on its own. Example (a grass block (not actually used in game): "[inventorycube{grass.png{mud.png&grass_side.png{mud.png&grass_side.png" */ else if(part_of_name.substr(0,14) == "[inventorycube") { if(baseimg != NULL) { errorstream<<"generate_image(): baseimg!=NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } str_replace_char(part_of_name, '&', '^'); Strfnd sf(part_of_name); sf.next("{"); std::string imagename_top = sf.next("{"); std::string imagename_left = sf.next("{"); std::string imagename_right = sf.next("{"); // Generate images for the faces of the cube video::IImage *img_top = generate_image_from_scratch( imagename_top, device, sourcecache); video::IImage *img_left = generate_image_from_scratch( imagename_left, device, sourcecache); video::IImage *img_right = generate_image_from_scratch( imagename_right, device, sourcecache); assert(img_top && img_left && img_right); // Create textures from images video::ITexture *texture_top = driver->addTexture( (imagename_top + "__temp__").c_str(), img_top); video::ITexture *texture_left = driver->addTexture( (imagename_left + "__temp__").c_str(), img_left); video::ITexture *texture_right = driver->addTexture( (imagename_right + "__temp__").c_str(), img_right); assert(texture_top && texture_left && texture_right); // Drop images img_top->drop(); img_left->drop(); img_right->drop(); /* Draw a cube mesh into a render target texture */ scene::IMesh* cube = createCubeMesh(v3f(1, 1, 1)); setMeshColor(cube, video::SColor(255, 255, 255, 255)); cube->getMeshBuffer(0)->getMaterial().setTexture(0, texture_top); cube->getMeshBuffer(1)->getMaterial().setTexture(0, texture_top); cube->getMeshBuffer(2)->getMaterial().setTexture(0, texture_right); cube->getMeshBuffer(3)->getMaterial().setTexture(0, texture_right); cube->getMeshBuffer(4)->getMaterial().setTexture(0, texture_left); cube->getMeshBuffer(5)->getMaterial().setTexture(0, texture_left); core::dimension2d<u32> dim(64,64); std::string rtt_texture_name = part_of_name + "_RTT"; v3f camera_position(0, 1.0, -1.5); camera_position.rotateXZBy(45); v3f camera_lookat(0, 0, 0); core::CMatrix4<f32> camera_projection_matrix; // Set orthogonal projection camera_projection_matrix.buildProjectionMatrixOrthoLH( 1.65, 1.65, 0, 100); video::SColorf ambient_light(0.2,0.2,0.2); v3f light_position(10, 100, -50); video::SColorf light_color(0.5,0.5,0.5); f32 light_radius = 1000; video::ITexture *rtt = generateTextureFromMesh( cube, device, dim, rtt_texture_name, camera_position, camera_lookat, camera_projection_matrix, ambient_light, light_position, light_color, light_radius); // Drop mesh cube->drop(); // Free textures of images driver->removeTexture(texture_top); driver->removeTexture(texture_left); driver->removeTexture(texture_right); if(rtt == NULL) { baseimg = generate_image_from_scratch( imagename_top, device, sourcecache); return true; } // Create image of render target video::IImage *image = driver->createImage(rtt, v2s32(0,0), dim); assert(image); baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); if(image) { image->copyTo(baseimg); image->drop(); } } else { errorstream<<"generate_image(): Invalid " " modification: \""<<part_of_name<<"\""<<std::endl; } } return true; }
bool generate_image(std::string part_of_name, video::IImage *& baseimg, IrrlichtDevice *device) { video::IVideoDriver* driver = device->getVideoDriver(); assert(driver); // Stuff starting with [ are special commands if(part_of_name[0] != '[') { // A normal texture; load it from a file std::string path = getTexturePath(part_of_name.c_str()); /*infostream<<"generate_image(): Loading path \""<<path <<"\""<<std::endl;*/ video::IImage *image = driver->createImageFromFile(path.c_str()); if(image == NULL) { infostream<<"generate_image(): Could not load image \"" <<part_of_name<<"\" from path \""<<path<<"\"" <<" while building texture"<<std::endl; //return false; infostream<<"generate_image(): Creating a dummy" <<" image for \""<<part_of_name<<"\""<<std::endl; // Just create a dummy image //core::dimension2d<u32> dim(2,2); core::dimension2d<u32> dim(1,1); image = driver->createImage(video::ECF_A8R8G8B8, dim); assert(image); /*image->setPixel(0,0, video::SColor(255,255,0,0)); image->setPixel(1,0, video::SColor(255,0,255,0)); image->setPixel(0,1, video::SColor(255,0,0,255)); image->setPixel(1,1, video::SColor(255,255,0,255));*/ image->setPixel(0,0, video::SColor(255,myrand()%256, myrand()%256,myrand()%256)); /*image->setPixel(1,0, video::SColor(255,myrand()%256, myrand()%256,myrand()%256)); image->setPixel(0,1, video::SColor(255,myrand()%256, myrand()%256,myrand()%256)); image->setPixel(1,1, video::SColor(255,myrand()%256, myrand()%256,myrand()%256));*/ } // If base image is NULL, load as base. if(baseimg == NULL) { //infostream<<"Setting "<<part_of_name<<" as base"<<std::endl; /* Copy it this way to get an alpha channel. Otherwise images with alpha cannot be blitted on images that don't have alpha in the original file. */ core::dimension2d<u32> dim = image->getDimension(); baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); image->copyTo(baseimg); image->drop(); } // Else blit on base. else { //infostream<<"Blitting "<<part_of_name<<" on base"<<std::endl; // Size of the copied area core::dimension2d<u32> dim = image->getDimension(); //core::dimension2d<u32> dim(16,16); // Position to copy the blitted to in the base image core::position2d<s32> pos_to(0,0); // Position to copy the blitted from in the blitted image core::position2d<s32> pos_from(0,0); // Blit image->copyToWithAlpha(baseimg, pos_to, core::rect<s32>(pos_from, dim), video::SColor(255,255,255,255), NULL); // Drop image image->drop(); } } else { // A special texture modification infostream<<"generate_image(): generating special " <<"modification \""<<part_of_name<<"\"" <<std::endl; /* This is the simplest of all; it just adds stuff to the name so that a separate texture is created. It is used to make textures for stuff that doesn't want to implement getting the texture from a bigger texture atlas. */ if(part_of_name == "[forcesingle") { } /* [crackN Adds a cracking texture */ else if(part_of_name.substr(0,6) == "[crack") { if(baseimg == NULL) { infostream<<"generate_image(): baseimg==NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } // Crack image number u16 progression = stoi(part_of_name.substr(6)); // Size of the base image core::dimension2d<u32> dim_base = baseimg->getDimension(); /* Load crack image. It is an image with a number of cracking stages horizontally tiled. */ video::IImage *img_crack = driver->createImageFromFile( getTexturePath("crack.png").c_str()); if(img_crack) { // Dimension of original image core::dimension2d<u32> dim_crack = img_crack->getDimension(); // Count of crack stages u32 crack_count = dim_crack.Height / dim_crack.Width; // Limit progression if(progression > crack_count-1) progression = crack_count-1; // Dimension of a single scaled crack stage core::dimension2d<u32> dim_crack_scaled_single( dim_base.Width, dim_base.Height ); // Dimension of scaled size core::dimension2d<u32> dim_crack_scaled( dim_crack_scaled_single.Width, dim_crack_scaled_single.Height * crack_count ); // Create scaled crack image video::IImage *img_crack_scaled = driver->createImage( video::ECF_A8R8G8B8, dim_crack_scaled); if(img_crack_scaled) { // Scale crack image by copying img_crack->copyToScaling(img_crack_scaled); // Position to copy the crack from core::position2d<s32> pos_crack_scaled( 0, dim_crack_scaled_single.Height * progression ); // This tiling does nothing currently but is useful for(u32 y0=0; y0<dim_base.Height / dim_crack_scaled_single.Height; y0++) for(u32 x0=0; x0<dim_base.Width / dim_crack_scaled_single.Width; x0++) { // Position to copy the crack to in the base image core::position2d<s32> pos_base( x0*dim_crack_scaled_single.Width, y0*dim_crack_scaled_single.Height ); // Rectangle to copy the crack from on the scaled image core::rect<s32> rect_crack_scaled( pos_crack_scaled, dim_crack_scaled_single ); // Copy it img_crack_scaled->copyToWithAlpha(baseimg, pos_base, rect_crack_scaled, video::SColor(255,255,255,255), NULL); } img_crack_scaled->drop(); } img_crack->drop(); } } /* [combine:WxH:X,Y=filename:X,Y=filename2 Creates a bigger texture from an amount of smaller ones */ else if(part_of_name.substr(0,8) == "[combine") { Strfnd sf(part_of_name); sf.next(":"); u32 w0 = stoi(sf.next("x")); u32 h0 = stoi(sf.next(":")); infostream<<"combined w="<<w0<<" h="<<h0<<std::endl; core::dimension2d<u32> dim(w0,h0); baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); while(sf.atend() == false) { u32 x = stoi(sf.next(",")); u32 y = stoi(sf.next("=")); std::string filename = sf.next(":"); infostream<<"Adding \""<<filename <<"\" to combined ("<<x<<","<<y<<")" <<std::endl; video::IImage *img = driver->createImageFromFile( getTexturePath(filename.c_str()).c_str()); if(img) { core::dimension2d<u32> dim = img->getDimension(); infostream<<"Size "<<dim.Width <<"x"<<dim.Height<<std::endl; core::position2d<s32> pos_base(x, y); video::IImage *img2 = driver->createImage(video::ECF_A8R8G8B8, dim); img->copyTo(img2); img->drop(); img2->copyToWithAlpha(baseimg, pos_base, core::rect<s32>(v2s32(0,0), dim), video::SColor(255,255,255,255), NULL); img2->drop(); } else { infostream<<"img==NULL"<<std::endl; } } } /* [progressbarN Adds a progress bar, 0.0 <= N <= 1.0 */ else if(part_of_name.substr(0,12) == "[progressbar") { if(baseimg == NULL) { infostream<<"generate_image(): baseimg==NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } float value = stof(part_of_name.substr(12)); make_progressbar(value, baseimg); } /* "[noalpha:filename.png" Use an image without it's alpha channel. Used for the leaves texture when in old leaves mode, so that the transparent parts don't look completely black when simple alpha channel is used for rendering. */ else if(part_of_name.substr(0,8) == "[noalpha") { if(baseimg != NULL) { infostream<<"generate_image(): baseimg!=NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } std::string filename = part_of_name.substr(9); std::string path = getTexturePath(filename.c_str()); infostream<<"generate_image(): Loading path \""<<path <<"\""<<std::endl; video::IImage *image = driver->createImageFromFile(path.c_str()); if(image == NULL) { infostream<<"generate_image(): Loading path \"" <<path<<"\" failed"<<std::endl; } else { core::dimension2d<u32> dim = image->getDimension(); baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); // Set alpha to full for(u32 y=0; y<dim.Height; y++) for(u32 x=0; x<dim.Width; x++) { video::SColor c = image->getPixel(x,y); c.setAlpha(255); image->setPixel(x,y,c); } // Blit image->copyTo(baseimg); image->drop(); } } /* "[makealpha:R,G,B:filename.png" Use an image with converting one color to transparent. */ else if(part_of_name.substr(0,11) == "[makealpha:") { if(baseimg != NULL) { infostream<<"generate_image(): baseimg!=NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } Strfnd sf(part_of_name.substr(11)); u32 r1 = stoi(sf.next(",")); u32 g1 = stoi(sf.next(",")); u32 b1 = stoi(sf.next(":")); std::string filename = sf.next(""); std::string path = getTexturePath(filename.c_str()); infostream<<"generate_image(): Loading path \""<<path <<"\""<<std::endl; video::IImage *image = driver->createImageFromFile(path.c_str()); if(image == NULL) { infostream<<"generate_image(): Loading path \"" <<path<<"\" failed"<<std::endl; } else { core::dimension2d<u32> dim = image->getDimension(); baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); for(u32 y=0; y<dim.Height; y++) for(u32 x=0; x<dim.Width; x++) { video::SColor c = image->getPixel(x,y); u32 r = c.getRed(); u32 g = c.getGreen(); u32 b = c.getBlue(); if(!(r == r1 && g == g1 && b == b1)) continue; c.setAlpha(0); image->setPixel(x,y,c); } // Blit image->copyTo(baseimg); image->drop(); } } /* "[makealpha2:R,G,B;R2,G2,B2:filename.png" Use an image with converting two colors to transparent. */ else if(part_of_name.substr(0,12) == "[makealpha2:") { if(baseimg != NULL) { infostream<<"generate_image(): baseimg!=NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } Strfnd sf(part_of_name.substr(12)); u32 r1 = stoi(sf.next(",")); u32 g1 = stoi(sf.next(",")); u32 b1 = stoi(sf.next(";")); u32 r2 = stoi(sf.next(",")); u32 g2 = stoi(sf.next(",")); u32 b2 = stoi(sf.next(":")); std::string filename = sf.next(""); std::string path = getTexturePath(filename.c_str()); infostream<<"generate_image(): Loading path \""<<path <<"\""<<std::endl; video::IImage *image = driver->createImageFromFile(path.c_str()); if(image == NULL) { infostream<<"generate_image(): Loading path \"" <<path<<"\" failed"<<std::endl; } else { core::dimension2d<u32> dim = image->getDimension(); baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); for(u32 y=0; y<dim.Height; y++) for(u32 x=0; x<dim.Width; x++) { video::SColor c = image->getPixel(x,y); u32 r = c.getRed(); u32 g = c.getGreen(); u32 b = c.getBlue(); if(!(r == r1 && g == g1 && b == b1) && !(r == r2 && g == g2 && b == b2)) continue; c.setAlpha(0); image->setPixel(x,y,c); } // Blit image->copyTo(baseimg); image->drop(); } } /* [inventorycube{topimage{leftimage{rightimage In every subimage, replace ^ with &. Create an "inventory cube". NOTE: This should be used only on its own. Example (a grass block (not actually used in game): "[inventorycube{grass.png{mud.png&grass_side.png{mud.png&grass_side.png" */ else if(part_of_name.substr(0,14) == "[inventorycube") { if(baseimg != NULL) { infostream<<"generate_image(): baseimg!=NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; } str_replace_char(part_of_name, '&', '^'); Strfnd sf(part_of_name); sf.next("{"); std::string imagename_top = sf.next("{"); std::string imagename_left = sf.next("{"); std::string imagename_right = sf.next("{"); #if 1 //TODO if(driver->queryFeature(video::EVDF_RENDER_TO_TARGET) == false) { infostream<<"generate_image(): EVDF_RENDER_TO_TARGET" " not supported. Creating fallback image"<<std::endl; baseimg = generate_image_from_scratch( imagename_top, device); return true; } u32 w0 = 64; u32 h0 = 64; //infostream<<"inventorycube w="<<w0<<" h="<<h0<<std::endl; core::dimension2d<u32> dim(w0,h0); // Generate images for the faces of the cube video::IImage *img_top = generate_image_from_scratch( imagename_top, device); video::IImage *img_left = generate_image_from_scratch( imagename_left, device); video::IImage *img_right = generate_image_from_scratch( imagename_right, device); assert(img_top && img_left && img_right); // TODO: Create textures from images video::ITexture *texture_top = driver->addTexture( (imagename_top + "__temp__").c_str(), img_top); assert(texture_top); // Drop images img_top->drop(); img_left->drop(); img_right->drop(); // Create render target texture video::ITexture *rtt = NULL; std::string rtt_name = part_of_name + "_RTT"; rtt = driver->addRenderTargetTexture(dim, rtt_name.c_str(), video::ECF_A8R8G8B8); assert(rtt); // Set render target driver->setRenderTarget(rtt, true, true, video::SColor(0,0,0,0)); // Get a scene manager scene::ISceneManager *smgr_main = device->getSceneManager(); assert(smgr_main); scene::ISceneManager *smgr = smgr_main->createNewSceneManager(); assert(smgr); /* Create scene: - An unit cube is centered at 0,0,0 - Camera looks at cube from Y+, Z- towards Y-, Z+ NOTE: Cube has to be changed to something else because the textures cannot be set individually (or can they?) */ scene::ISceneNode* cube = smgr->addCubeSceneNode(1.0, NULL, -1, v3f(0,0,0), v3f(0, 45, 0)); // Set texture of cube cube->setMaterialTexture(0, texture_top); //cube->setMaterialFlag(video::EMF_LIGHTING, false); cube->setMaterialFlag(video::EMF_ANTI_ALIASING, false); cube->setMaterialFlag(video::EMF_BILINEAR_FILTER, false); scene::ICameraSceneNode* camera = smgr->addCameraSceneNode(0, v3f(0, 1.0, -1.5), v3f(0, 0, 0)); // Set orthogonal projection core::CMatrix4<f32> pm; pm.buildProjectionMatrixOrthoLH(1.65, 1.65, 0, 100); camera->setProjectionMatrix(pm, true); /*scene::ILightSceneNode *light =*/ smgr->addLightSceneNode(0, v3f(-50, 100, 0), video::SColorf(0.5,0.5,0.5), 1000); smgr->setAmbientLight(video::SColorf(0.2,0.2,0.2)); // Render scene driver->beginScene(true, true, video::SColor(0,0,0,0)); smgr->drawAll(); driver->endScene(); // NOTE: The scene nodes should not be dropped, otherwise // smgr->drop() segfaults /*cube->drop(); camera->drop(); light->drop();*/ // Drop scene manager smgr->drop(); // Unset render target driver->setRenderTarget(0, true, true, 0); //TODO: Free textures of images driver->removeTexture(texture_top); // Create image of render target video::IImage *image = driver->createImage(rtt, v2s32(0,0), dim); assert(image); baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); if(image) { image->copyTo(baseimg); image->drop(); } #endif } else { infostream<<"generate_image(): Invalid " " modification: \""<<part_of_name<<"\""<<std::endl; } } return true; }
static gint file_open(gint fmt, gint rate, gint nch) { gchar *filename = NULL, *temp = NULL; gchar * directory; gint pos; gint rv; gint playlist; input.format = fmt; input.frequency = rate; input.channels = nch; playlist = aud_playlist_get_playing (); if (playlist < 0) return 0; pos = aud_playlist_get_position(playlist); tuple = aud_playlist_entry_get_tuple (playlist, pos, FALSE); if (tuple == NULL) return 0; if (filenamefromtags) { gchar * utf8 = aud_playlist_entry_get_title (playlist, pos, FALSE); str_replace_char (utf8, '/', ' '); gchar buf[3 * strlen (utf8) + 1]; str_encode_percent (utf8, -1, buf); str_unref (utf8); filename = g_strdup (buf); } else { temp = aud_playlist_entry_get_filename (playlist, pos); gchar * original = strrchr (temp, '/'); g_return_val_if_fail (original != NULL, 0); filename = g_strdup (original + 1); str_unref (temp); if (!use_suffix) if ((temp = strrchr(filename, '.')) != NULL) *temp = '\0'; } if (prependnumber) { gint number = tuple_get_int(tuple, FIELD_TRACK_NUMBER); if (!tuple || !number) number = pos + 1; temp = g_strdup_printf ("%d%%20%s", number, filename); g_free(filename); filename = temp; } if (save_original) { temp = aud_playlist_entry_get_filename (playlist, pos); directory = g_strdup (temp); str_unref (temp); temp = strrchr (directory, '/'); g_return_val_if_fail (temp != NULL, 0); temp[1] = 0; } else { g_return_val_if_fail (file_path[0], 0); if (file_path[strlen (file_path) - 1] == '/') directory = g_strdup (file_path); else directory = g_strdup_printf ("%s/", file_path); } temp = g_strdup_printf ("%s%s.%s", directory, filename, fileext_str[fileext]); g_free (directory); g_free (filename); filename = temp; output_file = safe_create (filename); g_free (filename); if (output_file == NULL) return 0; convert_init (fmt, plugin->format_required (fmt), nch); rv = (plugin->open)(); samples_written = 0; return rv; }