int win_perform_blit(const struct win_blit_params *blit, int update) { int srcdepth = (blit->srcdepth + 7) / 8; int dstdepth = (blit->dstdepth + 7) / 8; struct rectangle temprect; #ifndef _WIN64 blitter_func blitter; #endif int srcx, srcy; DWORD dw; // if we have a vector dirty array, alter the plan if (blit->vecdirty && !update) if (blit_vectors(blit)) return 1; // determine the starting source X/Y temprect.min_x = blit->srcxoffs; temprect.min_y = blit->srcyoffs; temprect.max_x = blit->srcxoffs + blit->srcwidth - 1; temprect.max_y = blit->srcyoffs + blit->srcheight - 1; win_disorient_rect(&temprect); if (blit->swapxy != blit_swapxy) { blit_srcwidth = blit->srcheight; blit_srcheight = blit->srcwidth; } else { blit_srcwidth = blit->srcwidth; blit_srcheight = blit->srcheight; } if (!blit->swapxy) { srcx = blit->flipx ? (temprect.max_x + 1) : temprect.min_x; srcy = blit->flipy ? (temprect.max_y + 1) : temprect.min_y; } else { srcx = blit->flipy ? (temprect.max_x + 1) : temprect.min_x; srcy = blit->flipx ? (temprect.max_y + 1) : temprect.min_y; } // if anything important has changed, fix it if (blit->srcwidth != active_blitter_params.srcwidth || blit->srcdepth != active_blitter_params.srcdepth || blit->srcpitch != active_blitter_params.srcpitch || blit->dstdepth != active_blitter_params.dstdepth || blit->dstpitch != active_blitter_params.dstpitch || blit->dstyskip != active_blitter_params.dstyskip || blit->dstxscale != active_blitter_params.dstxscale || blit->dstyscale != active_blitter_params.dstyscale || blit->dsteffect != active_blitter_params.dsteffect || blit->flipx != active_blitter_params.flipx || blit->flipy != active_blitter_params.flipy || blit->swapxy != active_blitter_params.swapxy) { // allocate memory for the blitter code and mark it as executable to avoid an access violation if (active_fast_blitter == NULL) active_fast_blitter = VirtualAlloc(NULL, MAX_BLITTER_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); else VirtualProtect(active_fast_blitter, MAX_BLITTER_SIZE, PAGE_EXECUTE_READWRITE, &dw); if (active_update_blitter == NULL) active_update_blitter = VirtualAlloc(NULL, MAX_BLITTER_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); else VirtualProtect(active_update_blitter, MAX_BLITTER_SIZE, PAGE_EXECUTE_READWRITE, &dw); generate_blitter(blit); // protect memory from external undesired changes VirtualProtect(active_fast_blitter, MAX_BLITTER_SIZE, PAGE_EXECUTE, &dw); VirtualProtect(active_update_blitter, MAX_BLITTER_SIZE, PAGE_EXECUTE, &dw); active_blitter_params = *blit; } // copy data to the globals asmblit_srcdata = (UINT8 *)blit->srcdata + blit->srcpitch * srcy + srcdepth * srcx; asmblit_srcheight = blit_srcheight; asmblit_srclookup = blit->srclookup; asmblit_dstdata = (UINT8 *)blit->dstdata + blit->dstpitch * blit->dstyoffs + dstdepth * blit->dstxoffs; asmblit_dstpitch = blit->dstpitch; #ifndef _WIN64 // pick the blitter blitter = update ? (blitter_func)active_update_blitter : (blitter_func)active_fast_blitter; (*blitter)(); #else if ((blit->dstdepth == 15) || (blit->dstdepth == 16)) { int c, c2, s; const UINT8 * src = asmblit_srcdata; UINT8 * dst = asmblit_dstdata; for (c = 0; c < asmblit_srcheight; c++) { for (c2 = 0; c2 < blit->srcwidth; c2++) { const UINT16 col = blit->srclookup[((UINT16*)src)[c2]]; for (s = 0; s < blit->dstxscale; ++s) ((UINT16*)dst)[c2 * blit->dstxscale + s] = col; } for(s = 0; s < blit->dstyscale; ++s) memcpy(dst + blit->dstpitch*(s+1), dst, blit->dstpitch); src += blit->srcpitch; dst += blit->dstpitch * blit->dstyscale; } } else if (blit->dstdepth == 32) { int c, c2, s; const UINT8 * src = asmblit_srcdata; UINT8 * dst = asmblit_dstdata; for (c = 0; c < asmblit_srcheight; c++) { for (c2 = 0; c2 < blit->srcwidth; c2++) { const UINT32 col = blit->srclookup[((UINT16*)src)[c2]]; for (s = 0; s < blit->dstxscale; ++s) ((UINT32*)dst)[c2 * blit->dstxscale + s] = col; } for (s = 0; s < blit->dstyscale; ++s) memcpy(dst + blit->dstpitch*(s + 1), dst, blit->dstpitch); src += blit->srcpitch; dst += blit->dstpitch * blit->dstyscale; } } #endif return 1; }
int win_perform_blit(const struct win_blit_params *blit, int update) { int srcdepth = (blit->srcdepth + 7) / 8; int dstdepth = (blit->dstdepth + 7) / 8; struct rectangle temprect; blitter_func blitter; int srcx, srcy; // if we have a vector dirty array, alter the plan if (blit->vecdirty && !update) if (blit_vectors(blit)) return 1; // determine the starting source X/Y temprect.min_x = blit->srcxoffs; temprect.min_y = blit->srcyoffs; temprect.max_x = blit->srcxoffs + blit->srcwidth - 1; temprect.max_y = blit->srcyoffs + blit->srcheight - 1; if (blit->swapxy || blit->flipx || blit->flipy) win_disorient_rect(&temprect); if (!blit->swapxy) { srcx = blit->flipx ? (temprect.max_x + 1) : temprect.min_x; srcy = blit->flipy ? (temprect.max_y + 1) : temprect.min_y; } else { srcx = blit->flipy ? (temprect.max_x + 1) : temprect.min_x; srcy = blit->flipx ? (temprect.max_y + 1) : temprect.min_y; } // if anything important has changed, fix it if (blit->srcwidth != active_blitter_params.srcwidth || blit->srcdepth != active_blitter_params.srcdepth || blit->srcpitch != active_blitter_params.srcpitch || blit->dstdepth != active_blitter_params.dstdepth || blit->dstpitch != active_blitter_params.dstpitch || blit->dstyskip != active_blitter_params.dstyskip || blit->dstxscale != active_blitter_params.dstxscale || blit->dstyscale != active_blitter_params.dstyscale || blit->dsteffect != active_blitter_params.dsteffect || blit->flipx != active_blitter_params.flipx || blit->flipy != active_blitter_params.flipy || blit->swapxy != active_blitter_params.swapxy) { generate_blitter(blit); active_blitter_params = *blit; } // copy data to the globals asmblit_srcdata = (UINT8 *)blit->srcdata + blit->srcpitch * srcy + srcdepth * srcx; asmblit_srcheight = blit->srcheight; asmblit_srclookup = blit->srclookup; asmblit_dstdata = (UINT8 *)blit->dstdata + blit->dstpitch * blit->dstyoffs + dstdepth * blit->dstxoffs; asmblit_dstpitch = blit->dstpitch; // pick the blitter blitter = update ? (blitter_func)active_update_blitter : (blitter_func)active_fast_blitter; (*blitter)(); return 1; }