static void CL_Beams_SetupBuiltinTexture(void) { // beam direction is horizontal in the lightning texture int texwidth = 128; int texheight = 64; float r, g, b, intensity, thickness = texheight * 0.25f, border = thickness + 2.0f, ithickness = 1.0f / thickness, center, n; int x, y; unsigned char *data; skinframe_t *skinframe; float centersamples[17][2]; // make a repeating noise pattern for the beam path for (x = 0; x < 16; x++) { centersamples[x][0] = lhrandom(border, texheight - border); centersamples[x][1] = lhrandom(0.2f, 1.00f); } centersamples[16][0] = centersamples[0][0]; centersamples[16][1] = centersamples[0][1]; data = (unsigned char *)Mem_Alloc(tempmempool, texwidth * texheight * 4); // iterate by columns and draw the entire column of pixels for (x = 0; x < texwidth; x++) { r = x * 16.0f / texwidth; y = (int)r; g = r - y; center = centersamples[y][0] * (1.0f - g) + centersamples[y+1][0] * g; n = centersamples[y][1] * (1.0f - g) + centersamples[y + 1][1] * g; for (y = 0; y < texheight; y++) { intensity = 1.0f - fabs((y - center) * ithickness); if (intensity > 0) { intensity = pow(intensity * n, 2); r = intensity * 1.000f * 255.0f; g = intensity * 2.000f * 255.0f; b = intensity * 4.000f * 255.0f; data[(y * texwidth + x) * 4 + 2] = (unsigned char)(bound(0, r, 255)); data[(y * texwidth + x) * 4 + 1] = (unsigned char)(bound(0, g, 255)); data[(y * texwidth + x) * 4 + 0] = (unsigned char)(bound(0, b, 255)); } else intensity = 0.0f; data[(y * texwidth + x) * 4 + 3] = (unsigned char)255; } } skinframe = R_SkinFrame_LoadInternalBGRA("lightningbeam", TEXF_FORCELINEAR, data, texwidth, texheight, 0, 0, 0, false); Mod_LoadCustomMaterial(r_main_mempool, &cl_beams_builtintexture, "cl_beams_builtintexture", 0, MATERIALFLAG_WALL | MATERIALFLAG_ADD | MATERIALFLAG_BLENDED | MATERIALFLAG_NOCULLFACE | MATERIALFLAG_VERTEXCOLOR | MATERIALFLAG_ALPHAGEN_VERTEX, skinframe); Mem_Free(data); }
static int R_LoadSkyBox(void) { int i, j, success; int indices[4] = {0,1,2,3}; char name[MAX_INPUTLINE]; unsigned char *image_buffer; unsigned char *temp; char vabuf[1024]; R_UnloadSkyBox(); if (!skyname[0]) return true; for (j=0; j<3; j++) { success = 0; for (i=0; i<6; i++) { if (dpsnprintf(name, sizeof(name), "%s_%s", skyname, suffix[j][i].suffix) < 0 || !(image_buffer = loadimagepixelsbgra(name, false, false, false, NULL))) { if (dpsnprintf(name, sizeof(name), "%s%s", skyname, suffix[j][i].suffix) < 0 || !(image_buffer = loadimagepixelsbgra(name, false, false, false, NULL))) { if (dpsnprintf(name, sizeof(name), "env/%s%s", skyname, suffix[j][i].suffix) < 0 || !(image_buffer = loadimagepixelsbgra(name, false, false, false, NULL))) { if (dpsnprintf(name, sizeof(name), "gfx/env/%s%s", skyname, suffix[j][i].suffix) < 0 || !(image_buffer = loadimagepixelsbgra(name, false, false, false, NULL))) continue; } } } temp = (unsigned char *)Mem_Alloc(tempmempool, image_width*image_height*4); Image_CopyMux (temp, image_buffer, image_width, image_height, suffix[j][i].flipx, suffix[j][i].flipy, suffix[j][i].flipdiagonal, 4, 4, indices); skyboxskinframe[i] = R_SkinFrame_LoadInternalBGRA(va(vabuf, sizeof(vabuf), "skyboxside%d", i), TEXF_CLAMP | (gl_texturecompression_sky.integer ? TEXF_COMPRESS : 0), temp, image_width, image_height, vid.sRGB3D); Mem_Free(image_buffer); Mem_Free(temp); success++; } if (success) break; } if (j == 3) return false; if (developer_loading.integer) Con_Printf("loading skybox \"%s\"\n", name); return true; }
static void Mod_Sprite_SharedSetup(const unsigned char *datapointer, int version, const unsigned int *palette, qboolean additive) { int i, j, groupframes, realframes, x, y, origin[2], width, height; qboolean fullbright; dspriteframetype_t *pinframetype; dspriteframe_t *pinframe; dspritegroup_t *pingroup; dspriteinterval_t *pinintervals; skinframe_t *skinframe; float modelradius, interval; char name[MAX_QPATH], fogname[MAX_QPATH]; const void *startframes; int texflags = (r_mipsprites.integer ? TEXF_MIPMAP : 0) | ((gl_texturecompression.integer && gl_texturecompression_sprites.integer) ? TEXF_COMPRESS : 0) | TEXF_ISSPRITE | TEXF_PICMIP | TEXF_ALPHA | TEXF_CLAMP; modelradius = 0; if (loadmodel->numframes < 1) Host_Error ("Mod_Sprite_SharedSetup: Invalid # of frames: %d", loadmodel->numframes); // LordHavoc: hack to allow sprites to be non-fullbright fullbright = true; for (i = 0;i < MAX_QPATH && loadmodel->name[i];i++) if (loadmodel->name[i] == '!') fullbright = false; // // load the frames // startframes = datapointer; realframes = 0; for (i = 0;i < loadmodel->numframes;i++) { pinframetype = (dspriteframetype_t *)datapointer; datapointer += sizeof(dspriteframetype_t); if (LittleLong (pinframetype->type) == SPR_SINGLE) groupframes = 1; else { pingroup = (dspritegroup_t *)datapointer; datapointer += sizeof(dspritegroup_t); groupframes = LittleLong(pingroup->numframes); datapointer += sizeof(dspriteinterval_t) * groupframes; } for (j = 0;j < groupframes;j++) { pinframe = (dspriteframe_t *)datapointer; if (version == SPRITE32_VERSION) datapointer += sizeof(dspriteframe_t) + LittleLong(pinframe->width) * LittleLong(pinframe->height) * 4; else //if (version == SPRITE_VERSION || version == SPRITEHL_VERSION) datapointer += sizeof(dspriteframe_t) + LittleLong(pinframe->width) * LittleLong(pinframe->height); } realframes += groupframes; } loadmodel->animscenes = (animscene_t *)Mem_Alloc(loadmodel->mempool, sizeof(animscene_t) * loadmodel->numframes); loadmodel->sprite.sprdata_frames = (mspriteframe_t *)Mem_Alloc(loadmodel->mempool, sizeof(mspriteframe_t) * realframes); loadmodel->num_textures = realframes; loadmodel->num_texturesperskin = 1; loadmodel->data_textures = (texture_t *)Mem_Alloc(loadmodel->mempool, sizeof(texture_t) * loadmodel->num_textures); datapointer = (unsigned char *)startframes; realframes = 0; for (i = 0;i < loadmodel->numframes;i++) { pinframetype = (dspriteframetype_t *)datapointer; datapointer += sizeof(dspriteframetype_t); if (LittleLong (pinframetype->type) == SPR_SINGLE) { groupframes = 1; interval = 0.1f; } else { pingroup = (dspritegroup_t *)datapointer; datapointer += sizeof(dspritegroup_t); groupframes = LittleLong(pingroup->numframes); pinintervals = (dspriteinterval_t *)datapointer; datapointer += sizeof(dspriteinterval_t) * groupframes; interval = LittleFloat(pinintervals[0].interval); if (interval < 0.01f) Host_Error("Mod_Sprite_SharedSetup: invalid interval"); } dpsnprintf(loadmodel->animscenes[i].name, sizeof(loadmodel->animscenes[i].name), "frame %i", i); loadmodel->animscenes[i].firstframe = realframes; loadmodel->animscenes[i].framecount = groupframes; loadmodel->animscenes[i].framerate = 1.0f / interval; loadmodel->animscenes[i].loop = true; for (j = 0;j < groupframes;j++) { pinframe = (dspriteframe_t *)datapointer; datapointer += sizeof(dspriteframe_t); origin[0] = LittleLong (pinframe->origin[0]); origin[1] = LittleLong (pinframe->origin[1]); width = LittleLong (pinframe->width); height = LittleLong (pinframe->height); loadmodel->sprite.sprdata_frames[realframes].left = origin[0]; loadmodel->sprite.sprdata_frames[realframes].right = origin[0] + width; loadmodel->sprite.sprdata_frames[realframes].up = origin[1]; loadmodel->sprite.sprdata_frames[realframes].down = origin[1] - height; x = (int)max(loadmodel->sprite.sprdata_frames[realframes].left * loadmodel->sprite.sprdata_frames[realframes].left, loadmodel->sprite.sprdata_frames[realframes].right * loadmodel->sprite.sprdata_frames[realframes].right); y = (int)max(loadmodel->sprite.sprdata_frames[realframes].up * loadmodel->sprite.sprdata_frames[realframes].up, loadmodel->sprite.sprdata_frames[realframes].down * loadmodel->sprite.sprdata_frames[realframes].down); if (modelradius < x + y) modelradius = x + y; if (cls.state != ca_dedicated) { skinframe = NULL; // note: Nehahra's null.spr has width == 0 and height == 0 if (width > 0 && height > 0) { if (groupframes > 1) { dpsnprintf (name, sizeof(name), "%s_%i_%i", loadmodel->name, i, j); dpsnprintf (fogname, sizeof(fogname), "%s_%i_%ifog", loadmodel->name, i, j); } else { dpsnprintf (name, sizeof(name), "%s_%i", loadmodel->name, i); dpsnprintf (fogname, sizeof(fogname), "%s_%ifog", loadmodel->name, i); } if (!(skinframe = R_SkinFrame_LoadExternal(name, texflags | TEXF_COMPRESS, false))) { unsigned char *pixels = (unsigned char *) Mem_Alloc(loadmodel->mempool, width*height*4); if (version == SPRITE32_VERSION) { for (x = 0;x < width*height;x++) { pixels[x*4+2] = datapointer[x*4+0]; pixels[x*4+1] = datapointer[x*4+1]; pixels[x*4+0] = datapointer[x*4+2]; pixels[x*4+3] = datapointer[x*4+3]; } } else //if (version == SPRITEHL_VERSION || version == SPRITE_VERSION) Image_Copy8bitBGRA(datapointer, pixels, width*height, palette ? palette : palette_bgra_transparent); skinframe = R_SkinFrame_LoadInternalBGRA(name, texflags, pixels, width, height, false); // texflags |= TEXF_COMPRESS; Mem_Free(pixels); } } if (skinframe == NULL) skinframe = R_SkinFrame_LoadMissing(); Mod_SpriteSetupTexture(&loadmodel->data_textures[realframes], skinframe, fullbright, additive); } if (version == SPRITE32_VERSION) datapointer += width * height * 4; else //if (version == SPRITE_VERSION || version == SPRITEHL_VERSION) datapointer += width * height; realframes++; } } modelradius = sqrt(modelradius); for (i = 0;i < 3;i++) { loadmodel->normalmins[i] = loadmodel->yawmins[i] = loadmodel->rotatedmins[i] = -modelradius; loadmodel->normalmaxs[i] = loadmodel->yawmaxs[i] = loadmodel->rotatedmaxs[i] = modelradius; } loadmodel->radius = modelradius; loadmodel->radius2 = modelradius * modelradius; }
static void r_lightningbeams_setuptexture(void) { #if 0 #define BEAMWIDTH 128 #define BEAMHEIGHT 64 #define PATHPOINTS 8 int i, j, px, py, nearestpathindex, imagenumber; float particlex, particley, particlexv, particleyv, dx, dy, s, maxpathstrength; unsigned char *pixels; int *image; struct lightningpathnode_s { float x, y, strength; } path[PATHPOINTS], temppath; image = Mem_Alloc(tempmempool, BEAMWIDTH * BEAMHEIGHT * sizeof(int)); pixels = Mem_Alloc(tempmempool, BEAMWIDTH * BEAMHEIGHT * sizeof(unsigned char[4])); for (imagenumber = 0, maxpathstrength = 0.0339476;maxpathstrength < 0.5;imagenumber++, maxpathstrength += 0.01) { for (i = 0;i < PATHPOINTS;i++) { path[i].x = lhrandom(0, 1); path[i].y = lhrandom(0.2, 0.8); path[i].strength = lhrandom(0, 1); } for (i = 0;i < PATHPOINTS;i++) { for (j = i + 1;j < PATHPOINTS;j++) { if (path[j].x < path[i].x) { temppath = path[j]; path[j] = path[i]; path[i] = temppath; } } } particlex = path[0].x; particley = path[0].y; particlexv = lhrandom(0, 0.02); particlexv = lhrandom(-0.02, 0.02); memset(image, 0, BEAMWIDTH * BEAMHEIGHT * sizeof(int)); for (i = 0;i < 65536;i++) { for (nearestpathindex = 0;nearestpathindex < PATHPOINTS;nearestpathindex++) if (path[nearestpathindex].x > particlex) break; nearestpathindex %= PATHPOINTS; dx = path[nearestpathindex].x + lhrandom(-0.01, 0.01);dx = bound(0, dx, 1) - particlex;if (dx < 0) dx += 1; dy = path[nearestpathindex].y + lhrandom(-0.01, 0.01);dy = bound(0, dy, 1) - particley; s = path[nearestpathindex].strength / sqrt(dx*dx+dy*dy); particlexv = particlexv /* (1 - lhrandom(0.08, 0.12))*/ + dx * s; particleyv = particleyv /* (1 - lhrandom(0.08, 0.12))*/ + dy * s; particlex += particlexv * maxpathstrength;particlex -= (int) particlex; particley += particleyv * maxpathstrength;particley = bound(0, particley, 1); px = particlex * BEAMWIDTH; py = particley * BEAMHEIGHT; if (px >= 0 && py >= 0 && px < BEAMWIDTH && py < BEAMHEIGHT) image[py*BEAMWIDTH+px] += 16; } for (py = 0;py < BEAMHEIGHT;py++) { for (px = 0;px < BEAMWIDTH;px++) { pixels[(py*BEAMWIDTH+px)*4+2] = bound(0, image[py*BEAMWIDTH+px] * 1.0f, 255.0f); pixels[(py*BEAMWIDTH+px)*4+1] = bound(0, image[py*BEAMWIDTH+px] * 1.0f, 255.0f); pixels[(py*BEAMWIDTH+px)*4+0] = bound(0, image[py*BEAMWIDTH+px] * 1.0f, 255.0f); pixels[(py*BEAMWIDTH+px)*4+3] = 255; } } Image_WriteTGABGRA(va(vabuf, sizeof(vabuf), "lightningbeam%i.tga", imagenumber), BEAMWIDTH, BEAMHEIGHT, pixels); } r_lightningbeamtexture = R_LoadTexture2D(r_lightningbeamtexturepool, "lightningbeam", BEAMWIDTH, BEAMHEIGHT, pixels, TEXTYPE_BGRA, TEXF_FORCELINEAR, NULL); Mem_Free(pixels); Mem_Free(image); #else #define BEAMWIDTH 64 #define BEAMHEIGHT 128 float r, g, b, intensity, fx, width, center; int x, y; unsigned char *data, *noise1, *noise2; data = (unsigned char *)Mem_Alloc(tempmempool, BEAMWIDTH * BEAMHEIGHT * 4); noise1 = (unsigned char *)Mem_Alloc(tempmempool, BEAMHEIGHT * BEAMHEIGHT); noise2 = (unsigned char *)Mem_Alloc(tempmempool, BEAMHEIGHT * BEAMHEIGHT); fractalnoise(noise1, BEAMHEIGHT, BEAMHEIGHT / 8); fractalnoise(noise2, BEAMHEIGHT, BEAMHEIGHT / 16); for (y = 0;y < BEAMHEIGHT;y++) { width = 0.15;//((noise1[y * BEAMHEIGHT] * (1.0f / 256.0f)) * 0.1f + 0.1f); center = (noise1[y * BEAMHEIGHT + (BEAMHEIGHT / 2)] / 256.0f) * (1.0f - width * 2.0f) + width; for (x = 0;x < BEAMWIDTH;x++, fx++) { fx = (((float) x / BEAMWIDTH) - center) / width; intensity = 1.0f - sqrt(fx * fx); if (intensity > 0) intensity = pow(intensity, 2) * ((noise2[y * BEAMHEIGHT + x] * (1.0f / 256.0f)) * 0.33f + 0.66f); intensity = bound(0, intensity, 1); r = intensity * 1.0f; g = intensity * 1.0f; b = intensity * 1.0f; data[(y * BEAMWIDTH + x) * 4 + 2] = (unsigned char)(bound(0, r, 1) * 255.0f); data[(y * BEAMWIDTH + x) * 4 + 1] = (unsigned char)(bound(0, g, 1) * 255.0f); data[(y * BEAMWIDTH + x) * 4 + 0] = (unsigned char)(bound(0, b, 1) * 255.0f); data[(y * BEAMWIDTH + x) * 4 + 3] = (unsigned char)255; } } r_lightningbeamtexture = R_SkinFrame_LoadInternalBGRA("lightningbeam", TEXF_FORCELINEAR, data, BEAMWIDTH, BEAMHEIGHT, false); Mem_Free(noise1); Mem_Free(noise2); Mem_Free(data); #endif }
static void Curl_EndDownload(downloadinfo *di, CurlStatus status, CURLcode error, const char *content_type_) { char content_type[64]; qboolean ok = false; if(!curl_dll) return; switch(status) { case CURL_DOWNLOAD_SUCCESS: ok = true; di->callback(CURLCBSTATUS_OK, di->bytes_received, di->buffer, di->callback_data); break; case CURL_DOWNLOAD_FAILED: di->callback(CURLCBSTATUS_FAILED, di->bytes_received, di->buffer, di->callback_data); break; case CURL_DOWNLOAD_ABORTED: di->callback(CURLCBSTATUS_ABORTED, di->bytes_received, di->buffer, di->callback_data); break; case CURL_DOWNLOAD_SERVERERROR: // reopen to enforce it to have zero bytes again if(di->stream) { FS_Close(di->stream); di->stream = FS_OpenRealFile(di->filename, "wb", false); } if(di->callback) di->callback(error ? (int) error : CURLCBSTATUS_SERVERERROR, di->bytes_received, di->buffer, di->callback_data); break; default: if(di->callback) di->callback(CURLCBSTATUS_UNKNOWN, di->bytes_received, di->buffer, di->callback_data); break; } if(content_type_) strlcpy(content_type, content_type_, sizeof(content_type)); else *content_type = 0; if(di->curle) { qcurl_multi_remove_handle(curlm, di->curle); qcurl_easy_cleanup(di->curle); if(di->slist) qcurl_slist_free_all(di->slist); } if(!di->callback && ok && !di->bytes_received) { Con_Printf("ERROR: empty file\n"); ok = false; } if(di->stream) FS_Close(di->stream); #define CLEAR_AND_RETRY() \ do \ { \ di->stream = FS_OpenRealFile(di->filename, "wb", false); \ FS_Close(di->stream); \ if(di->startpos && !di->callback) \ { \ Curl_Begin(di->url, di->extraheaders, di->maxspeed, di->filename, di->loadtype, di->forthismap, di->post_content_type, di->postbuf, di->postbufsize, NULL, 0, NULL, NULL); \ di->forthismap = false; \ } \ } \ while(0) if(ok && di->loadtype == LOADTYPE_PAK) { ok = FS_AddPack(di->filename, NULL, true); if(!ok) CLEAR_AND_RETRY(); } else if(ok && di->loadtype == LOADTYPE_CACHEPIC) { const char *p; unsigned char *pixels = NULL; p = di->filename; #ifdef WE_ARE_EVIL if(!strncmp(p, "dlcache/", 8)) p += 8; #endif pixels = decode_image(di, content_type); if(pixels) Draw_NewPic(p, image_width, image_height, true, pixels); else CLEAR_AND_RETRY(); } else if(ok && di->loadtype == LOADTYPE_SKINFRAME) { const char *p; unsigned char *pixels = NULL; p = di->filename; #ifdef WE_ARE_EVIL if(!strncmp(p, "dlcache/", 8)) p += 8; #endif pixels = decode_image(di, content_type); if(pixels) R_SkinFrame_LoadInternalBGRA(p, TEXF_FORCE_RELOAD | TEXF_MIPMAP | TEXF_ALPHA, pixels, image_width, image_height, false); // TODO what sRGB argument to put here? else CLEAR_AND_RETRY(); } if(di->prev) di->prev->next = di->next; else downloads = di->next; if(di->next) di->next->prev = di->prev; --numdownloads; if(di->forthismap) { if(ok) ++numdownloads_success; else ++numdownloads_fail; } Z_Free(di); }