void texmgr::KillTex(int iSlot) { if (iSlot < 0) return; if (iSlot >= NUM_TEX) return; // Free old resources: if (m_tex[iSlot].pSurface) { // first, make sure no other sprites reference this texture! int refcount = 0; for (int x=0; x<NUM_TEX; x++) if (m_tex[x].pSurface == m_tex[iSlot].pSurface) refcount++; if (refcount==1) m_tex[iSlot].pSurface->Release(); m_tex[iSlot].pSurface = NULL; } m_tex[iSlot].szFileName[0] = 0; FreeCode(iSlot); }
bool texmgr::RunInitCode(int iSlot, char *szInitCode) { // warning: destroys contents of m_tex[iSlot].m_szExpr, // so be sure to call RunInitCode before writing or // compiling that string! FreeCode(iSlot); FreeVars(iSlot); RegisterBuiltInVariables(iSlot); strcpy(m_tex[iSlot].m_szExpr, szInitCode); bool ret = RecompileExpressions(iSlot); // set default values of output variables: // (by not setting these every frame, we allow the values to persist from frame-to-frame.) *(m_tex[iSlot].var_x) = 0.5; *(m_tex[iSlot].var_y) = 0.5; *(m_tex[iSlot].var_sx) = 1.0; *(m_tex[iSlot].var_sy) = 1.0; *(m_tex[iSlot].var_repeatx) = 1.0; *(m_tex[iSlot].var_repeaty) = 1.0; *(m_tex[iSlot].var_rot) = 0.0; *(m_tex[iSlot].var_flipx) = 0.0; *(m_tex[iSlot].var_flipy) = 0.0; *(m_tex[iSlot].var_r) = 1.0; *(m_tex[iSlot].var_g) = 1.0; *(m_tex[iSlot].var_b) = 1.0; *(m_tex[iSlot].var_a) = 1.0; *(m_tex[iSlot].var_blendmode)= 0.0; *(m_tex[iSlot].var_done) = 0.0; *(m_tex[iSlot].var_burn) = 1.0; #ifndef _NO_EXPR_ if (m_tex[iSlot].m_codehandle) NSEEL_code_execute(m_tex[iSlot].m_codehandle); #endif return ret; }
void CodeBuild(dyncode* Code) { #ifdef DYNCODE dyninst* p; Code->Size = 0; if (Failed) return; for (p=InstBegin;p;p=p->Next) Code->Size += InstSize(p,Code->Size); if (Code->Size > Code->Allocated) { FreeCode(Code); Code->Allocated = (Code->Size + 511) & ~511; Code->Code = (char*) CodeAlloc(Code->Allocated); } if (Code->Code) { char* Addr; CodeLock(Code->Code,Code->Allocated); Addr = Code->Code; for (p=InstBegin;p;p=p->Next) { p->Address = Addr; Addr += InstSize(p,Addr - Code->Code); } for (p=InstBegin;p;p=p->Next) { if (p->ReAlloc && (!p->ReAlloc->Address || !InstReAlloc(p,p->ReAlloc))) { Code->Size = 0; assert(Code->Size); break; } if (p->CodeLarge) memcpy(p->Address,p->CodeLarge,p->CodeSize); else if (p->CodeSize>0) { if (p->CodeSize == sizeof(int32_t)) *(int32_t*)p->Address = p->CodeSmall; else if (p->CodeSize == sizeof(int16_t)) *(int16_t*)p->Address = (int16_t)p->CodeSmall; else memcpy(p->Address,&p->CodeSmall,p->CodeSize); } } if (Code->Code) CodeUnlock(Code->Code,Code->Allocated); #ifdef DUMPCODE if (Code->Code) { char Name[64]; FILE* f; sprintf(Name,"\\code%04x.bin",Code->Size); f = fopen(Name,"wb+"); fwrite(Code->Code,1,Code->Size,f); fclose(f); } #endif } else Code->Size = 0; #else Code->Size = 0; #endif }
void CodeDone(dyncode* p) { FreeInst(); FreeCode(p); }
int texmgr::LoadTex(wchar_t *szFilename, int iSlot, char *szInitCode, char *szCode, float time, int frame, unsigned int ck) { if (iSlot < 0) return TEXMGR_ERR_BAD_INDEX; if (iSlot >= NUM_TEX) return TEXMGR_ERR_BAD_INDEX; // first, if this texture is already loaded, just add another instance. bool bTextureInstanced = false; { for (int x=0; x<NUM_TEX; x++) if (m_tex[x].pSurface && _wcsicmp(m_tex[x].szFileName, szFilename)==0) { memcpy(&m_tex[iSlot], &m_tex[x], sizeof(td_tex)); m_tex[iSlot].m_szExpr[0] = 0; m_tex[iSlot].m_codehandle = 0; bTextureInstanced = true; break; } } if (!bTextureInstanced) { // Free old resources: /* if (m_tex[iSlot].pSurface) { m_tex[iSlot].pSurface->Release(); m_tex[iSlot].pSurface = NULL; }*/ KillTex(iSlot); wcscpy(m_tex[iSlot].szFileName, szFilename); D3DXIMAGE_INFO info; HRESULT hr = pCreateTextureFromFileExW( m_lpDD, szFilename, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, // create a mip chain 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0xFF000000 | ck, &info, NULL, &m_tex[iSlot].pSurface ); if (hr != D3D_OK) { switch(hr) { case E_OUTOFMEMORY: case D3DERR_OUTOFVIDEOMEMORY: return TEXMGR_ERR_OUTOFMEM; default: return TEXMGR_ERR_BADFILE; } } m_tex[iSlot].img_w = info.Width; m_tex[iSlot].img_h = info.Height; /* unsigned int w_img; unsigned int h_img; unsigned int img_color_channels; int ret = Begin_Jpeg_Read(szFilename, &w_img, &h_img, &img_color_channels); switch(ret) { case JPEGSTUFF_ERR_SUCCESS: break; case JPEGSTUFF_ERR_OPENING: return TEXMGR_ERR_OPENING; break; case JPEGSTUFF_ERR_MISC: return TEXMGR_ERR_FORMAT; break; } sprintf(buf, "texmgr: w=%d, h=%d, channels=%d", w_img, h_img, img_color_channels); //g_dumpmsg(buf); m_tex[iSlot].img_w = w_img; m_tex[iSlot].img_h = h_img; if (img_color_channels != 3) { // error: not 24-bit! //g_dumpmsg("texmgr: image not 24-bit"); End_Jpeg_Read(); return TEXMGR_ERR_IMAGE_NOT_24_BIT; } if ((w_img > 2048) || (h_img > 2048)) // RG { // error: too large! //g_dumpmsg("texmgr: image too large"); End_Jpeg_Read(); return TEXMGR_ERR_IMAGE_TOO_LARGE; } if (!TryCreateDDrawSurface(iSlot, w_img, h_img)) { //g_dumpmsg("texmgr: unable to create ddraw surface"); End_Jpeg_Read(); return TEXMGR_ERR_CREATESURFACE_FAILED; } unsigned int w_tex = m_tex[iSlot].tex_w; unsigned int h_tex = m_tex[iSlot].tex_h; unsigned int bpp_tex = m_tex[iSlot].ddpf.dwRGBBitCount; sprintf(buf, "texmgr: created ddraw surface; %d x %d x %d", w_tex, h_tex, bpp_tex); //g_dumpmsg(buf); DDSURFACEDESC2 ddsd; ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2)); ddsd.dwSize = sizeof( ddsd ); if (m_tex[iSlot].pSurface->Lock(0, &ddsd, DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_NOSYSLOCK, 0) != DD_OK) { //g_dumpmsg("texmgr: unable to lock ddraw surface"); End_Jpeg_Read(); m_tex[iSlot].pSurface->Release(); m_tex[iSlot].pSurface = NULL; return TEXMGR_ERR_LOCKSURFACE_FAILED; } // analyze surface pixel format unsigned int zeroBits[3] = { 0, 0, 0 }; unsigned int chopBits[3] = { 8, 8, 8 }; unsigned int mask[3] = { ddsd.ddpfPixelFormat.dwRBitMask, ddsd.ddpfPixelFormat.dwGBitMask, ddsd.ddpfPixelFormat.dwBBitMask }; { int x,y; for (x=0; x<3; x++) { for (y=0; y<32; y++) { if ((mask[x] & (1<<y)) == 0) zeroBits[x]++; else break; } mask[x] >>= zeroBits[x]; for (y=0; y<32; y++) { if ((mask[x] & (1<<y)) != 0) chopBits[x]--; } } } unsigned int ck_r1 = (ck_lo >> 16) & 0xFF; unsigned int ck_g1 = (ck_lo >> 8 ) & 0xFF; unsigned int ck_b1 = (ck_lo ) & 0xFF; unsigned int ck_r2 = (ck_hi >> 16) & 0xFF; unsigned int ck_g2 = (ck_hi >> 8 ) & 0xFF; unsigned int ck_b2 = (ck_hi ) & 0xFF; // read jpeg in & store in directdraw surface // 2. read image into texture if (w_img > w_tex || h_img > h_tex) { // DOWNSAMPLING VERSION unsigned int new_w_img = min(w_tex, w_img); unsigned int new_h_img = min(h_tex, h_img); { char buf[256]; sprintf(buf, "texmgr: downsampling image from %dx%d to %dx%d and storing in %dx%d texture.", w_img,h_img, new_w_img,new_h_img, w_tex,h_tex); //g_dumpmsg(buf); } int downsample_buf[2048*3]; memset(downsample_buf, 0, sizeof(downsample_buf)); float input_lines_per_output_line = h_img/(float)new_h_img; float lines = 0.0f; unsigned int out_y = 0; for (int y=0; y<(int)h_img; y++) { unsigned int x; unsigned char *buf = Jpeg_Read_Next_Line(); if (!buf) { End_Jpeg_Read(); m_tex[iSlot].pSurface->Release(); m_tex[iSlot].pSurface = NULL; return TEXMGR_ERR_CORRUPT_JPEG; } lines += 1.0f; int portion = (int)(min(256, max(0, (input_lines_per_output_line - lines)*256))); for (x=0; x<w_img*3; x++) downsample_buf[x] += ((int)buf[x] * portion) >> 4; if (portion < 256) { // commit this line (out_y) & start a new one if (out_y < h_tex) { float input_cols_per_output_col = w_img/(float)new_w_img; float cols = 0.0f; int out_x = 0; int buf2[2048*3]; memset(buf2, 0, new_w_img*3); for (x=0; x<w_img; x++) { cols += 1.0f; int portion = (int)(min(256, max(0, (input_cols_per_output_col - cols)*256))); buf2[out_x*3 ] += (downsample_buf[x*3 ] * portion) >> 4; buf2[out_x*3+1] += (downsample_buf[x*3+1] * portion) >> 4; buf2[out_x*3+2] += (downsample_buf[x*3+2] * portion) >> 4; if (portion < 256) { cols -= input_cols_per_output_col; portion = 256 - portion; out_x++; buf2[out_x*3 ] = (downsample_buf[x*3 ] * portion) >> 4; buf2[out_x*3+1] = (downsample_buf[x*3+1] * portion) >> 4; buf2[out_x*3+2] = (downsample_buf[x*3+2] * portion) >> 4; } } // now buf2[0..w_tex] has r,g,b colors in it (but scaled) -> SAVE TO TEXTURE. float scale_factor = 1.0f / (float)(16 * 16 * input_cols_per_output_col * input_lines_per_output_line); if (bpp_tex == 16) { unsigned __int16 *dest16 = (unsigned __int16 *)ddsd.lpSurface; unsigned int tex_offset = (ddsd.lPitch/2) * out_y; for (x=0; x<new_w_img; x++) { unsigned int cr = (unsigned int)(buf2[x*3 ]*scale_factor); unsigned int cg = (unsigned int)(buf2[x*3+1]*scale_factor); unsigned int cb = (unsigned int)(buf2[x*3+2]*scale_factor); unsigned int color = (((cr >> chopBits[0]) & mask[0]) << zeroBits[0]) | (((cg >> chopBits[1]) & mask[1]) << zeroBits[1]) | (((cb >> chopBits[2]) & mask[2]) << zeroBits[2]); if (!(cr >= ck_r1 && cr <= ck_r2 && cg >= ck_g1 && cg <= ck_g2 && cb >= ck_b1 && cb <= ck_b2)) color |= ddsd.ddpfPixelFormat.dwRGBAlphaBitMask; dest16[tex_offset++] = color; } } else if (bpp_tex == 32) { unsigned __int32 *dest32 = (unsigned __int32 *)ddsd.lpSurface; unsigned int tex_offset = (ddsd.lPitch/4) * out_y; for (x=0; x<new_w_img; x++) { unsigned int cr = (unsigned int)(buf2[x*3 ]*scale_factor); unsigned int cg = (unsigned int)(buf2[x*3+1]*scale_factor); unsigned int cb = (unsigned int)(buf2[x*3+2]*scale_factor); unsigned int color = (cr << zeroBits[0]) | (cg << zeroBits[1]) | (cb << zeroBits[2]); if (!(cr >= ck_r1 && cr <= ck_r2 && cg >= ck_g1 && cg <= ck_g2 && cb >= ck_b1 && cb <= ck_b2)) color |= ddsd.ddpfPixelFormat.dwRGBAlphaBitMask; dest32[tex_offset++] = color; } } out_y++; } // start next line: lines -= input_lines_per_output_line; portion = 256 - portion; for (x=0; x<w_img*3; x++) downsample_buf[x] = ((int)buf[x] * portion) >> 4; } } m_tex[iSlot].scale_x = new_w_img/(float)w_img; m_tex[iSlot].scale_y = new_h_img/(float)h_img; m_tex[iSlot].img_w = new_w_img; m_tex[iSlot].img_h = new_h_img; w_img = new_w_img; h_img = new_h_img; } else { // 1:1 VERSION if (bpp_tex == 16) { unsigned __int16 *dest16 = (unsigned __int16 *)ddsd.lpSurface; for (int y=0; y<(int)h_img; y++) { unsigned char *buf = Jpeg_Read_Next_Line(); if (!buf) { End_Jpeg_Read(); m_tex[iSlot].pSurface->Release(); m_tex[iSlot].pSurface = NULL; return TEXMGR_ERR_CORRUPT_JPEG; } unsigned int tex_offset = (ddsd.lPitch/2) * y; for (unsigned int x=0; x<w_img; x++) { unsigned int cr = buf[x*3 ]; unsigned int cg = buf[x*3+1]; unsigned int cb = buf[x*3+2]; unsigned int color = (((cr >> chopBits[0]) & mask[0]) << zeroBits[0]) | (((cg >> chopBits[1]) & mask[1]) << zeroBits[1]) | (((cb >> chopBits[2]) & mask[2]) << zeroBits[2]); if (!(cr >= ck_r1 && cr <= ck_r2 && cg >= ck_g1 && cg <= ck_g2 && cb >= ck_b1 && cb <= ck_b2)) color |= ddsd.ddpfPixelFormat.dwRGBAlphaBitMask; dest16[tex_offset++] = color; } } } else if (bpp_tex == 32) { unsigned __int32 *dest32 = (unsigned __int32 *)ddsd.lpSurface; for (int y=0; y<(int)h_img; y++) { unsigned char *buf = Jpeg_Read_Next_Line(); if (!buf) { End_Jpeg_Read(); m_tex[iSlot].pSurface->Release(); m_tex[iSlot].pSurface = NULL; return TEXMGR_ERR_CORRUPT_JPEG; } unsigned int tex_offset = (ddsd.lPitch/4) * y; for (unsigned int x=0; x<w_img; x++) { unsigned int cr = buf[x*3 ]; unsigned int cg = buf[x*3+1]; unsigned int cb = buf[x*3+2]; unsigned int color = (cr << zeroBits[0]) | (cg << zeroBits[1]) | (cb << zeroBits[2]); if (!(cr >= ck_r1 && cr <= ck_r2 && cg >= ck_g1 && cg <= ck_g2 && cb >= ck_b1 && cb <= ck_b2)) color |= ddsd.ddpfPixelFormat.dwRGBAlphaBitMask; dest32[tex_offset++] = color; } } } } m_tex[iSlot].pSurface->Unlock(0); End_Jpeg_Read(); */ } m_tex[iSlot].fStartTime = time; m_tex[iSlot].nStartFrame = frame; int ret = TEXMGR_ERR_SUCCESS; // compile & run init. code: if (!RunInitCode(iSlot, szInitCode)) ret |= TEXMGR_WARN_ERROR_IN_INIT_CODE; // compile & save per-frame code: strcpy(m_tex[iSlot].m_szExpr, szCode); FreeCode(iSlot); if (!RecompileExpressions(iSlot)) ret |= TEXMGR_WARN_ERROR_IN_REG_CODE; //g_dumpmsg("texmgr: success"); return ret; }