//Perform frame by frame updates and blits. Set the stream //state to STOP if there are no more frames to update. void RenderToSurface(BITMAP *vscreen) { //update each frame if (g_pSample->Update(0, NULL, NULL, 0) != S_OK) { g_bAppactive = FALSE; g_pMMStream->SetState(STREAMSTATE_STOP); } else { g_bAppactive = TRUE; acquire_screen(); // Because vscreen is a DX Video Bitmap, it can be stretched // onto the screen (also a Video Bmp) but not onto a memory // bitmap (which is what "screen" is when using gfx filters) if (is_video_bitmap(screen)) { stretch_blit(vscreen, screen, 0, 0, vscreen->w, vscreen->h, screen->w / 2 - newWidth / 2, screen->h / 2 - newHeight / 2, newWidth, newHeight); } else { blit(vscreen, vsMemory, 0, 0, 0, 0, vscreen->w, vscreen->h); stretch_blit(vsMemory, screen, 0, 0, vscreen->w, vscreen->h, screen->w / 2 - newWidth / 2, screen->h / 2 - newHeight / 2, newWidth, newHeight); } release_screen(); render_to_screen(screen, 0, 0); // if we're not playing AVI sound, poll the game MP3 if (!useSound) update_polled_stuff_and_crossfade(); } }
/* ddraw_do_stretch_blit: * Accelerated stretch_blit, stretch_sprite, stretch_masked_blit */ static void ddraw_do_stretch_blit(struct BITMAP *source, struct BITMAP *dest, int source_x, int source_y, int source_width, int source_height, int dest_x, int dest_y, int dest_width, int dest_height, int masked) { RECT dest_rect, source_rect; DDCOLORKEY src_key; HRESULT hr; BITMAP *dest_parent; BITMAP *source_parent; dest_rect.left = dest_x + dest->x_ofs; dest_rect.top = dest_y + dest->y_ofs; dest_rect.right = dest_x + dest->x_ofs + dest_width; dest_rect.bottom = dest_y + dest->y_ofs + dest_height; source_rect.left = source_x + source->x_ofs; source_rect.top = source_y + source->y_ofs; source_rect.right = source_x + source->x_ofs + source_width; source_rect.bottom = source_y + source->y_ofs + source_height; src_key.dwColorSpaceLowValue = source->vtable->mask_color; src_key.dwColorSpaceHighValue = source->vtable->mask_color; if ( ( (masked && (gfx_capabilities & GFX_HW_VRAM_STRETCH_BLIT_MASKED)) || (!masked && (gfx_capabilities & GFX_HW_VRAM_STRETCH_BLIT)) ) && ( is_video_bitmap(source) || is_system_bitmap(source) ) ) { /* find parents */ dest_parent = dest; while (dest_parent->id & BMP_ID_SUB) dest_parent = (BITMAP *)dest_parent->extra; source_parent = source; while (source_parent->id & BMP_ID_SUB) source_parent = (BITMAP *)source_parent->extra; _enter_gfx_critical(); gfx_directx_release_lock(dest); gfx_directx_release_lock(source); IDirectDrawSurface2_SetColorKey(DDRAW_SURFACE_OF(source_parent)->id, DDCKEY_SRCBLT, &src_key); hr = IDirectDrawSurface2_Blt(DDRAW_SURFACE_OF(dest_parent)->id, &dest_rect, DDRAW_SURFACE_OF(source_parent)->id, &source_rect, (masked ? DDBLT_KEYSRC : 0) | DDBLT_WAIT, NULL); _exit_gfx_critical(); if (FAILED(hr)) _TRACE(PREFIX_E "Blt failed (%x)\n", hr); /* only for windowed mode */ if ((gfx_driver->id == GFX_DIRECTX_WIN) && (dest_parent == gfx_directx_forefront_bitmap)) win_gfx_driver->paint(&dest_rect); } else { /* have to use the original software version */ _orig_stretch_blit(source, dest, source_x, source_y, source_width, source_height, dest_x, dest_y, dest_width, dest_height, masked); } }
/* request_video_bitmap: * Triple buffering function: triggers a swap to display the specified * video memory bitmap object, which will take place on the next retrace. */ int request_video_bitmap(BITMAP *bitmap) { if ((!is_video_bitmap(bitmap)) || (bitmap->w != SCREEN_W) || (bitmap->h != SCREEN_H) || (_dispsw_status)) return -1; if (gfx_driver->request_video_bitmap) return gfx_driver->request_video_bitmap(bitmap); return request_scroll(bitmap->x_ofs, bitmap->y_ofs); }
/* show_video_bitmap: * Page flipping function: swaps to display the specified video memory * bitmap object (this must be the same size as the physical screen). */ int show_video_bitmap(BITMAP *bitmap) { if ((!is_video_bitmap(bitmap)) || (bitmap->w != SCREEN_W) || (bitmap->h != SCREEN_H) || (_dispsw_status)) return -1; if (gfx_driver->show_video_bitmap) return gfx_driver->show_video_bitmap(bitmap); return scroll_screen(bitmap->x_ofs, bitmap->y_ofs); }
/* _xaccel_draw_sprite: * Accelerated draw_sprite. */ static void _xaccel_draw_sprite(BITMAP *bmp, BITMAP *sprite, int x, int y) { int sx, sy, w, h; if (is_video_bitmap(sprite)) { sx = 0; sy = 0; w = sprite->w; h = sprite->h; if (bmp->clip) { if (x < bmp->cl) { sx += bmp->cl - x; w -= bmp->cl - x; x = bmp->cl; } if (y < bmp->ct) { sy += bmp->ct - y; h -= bmp->ct - y; y = bmp->ct; } if (x + w > bmp->cr) w = bmp->cr - x; if (w <= 0) return; if (y + h > bmp->cb) h = bmp->cb - y; if (h <= 0) return; } sx += sprite->x_ofs; sy += sprite->y_ofs; x += bmp->x_ofs; y += bmp->y_ofs; XLOCK(); XDGACopyTransparentArea(_xwin.display, _xwin.screen, sx, sy, w, h, x, y, sprite->vtable->mask_color); XUNLOCK(); bmp->id &= ~BMP_ID_LOCKED; } else _orig_draw_sprite(bmp, sprite, x, y); }
/* _xaccel_masked_blit: * Accelerated masked_blit. */ static void _xaccel_masked_blit(BITMAP *source, BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height) { if (is_video_bitmap(source)) { source_x += source->x_ofs; source_y += source->y_ofs; dest_x += dest->x_ofs; dest_y += dest->y_ofs; XLOCK(); XDGACopyTransparentArea(_xwin.display, _xwin.screen, source_x, source_y, width, height, dest_x, dest_y, source->vtable->mask_color); XUNLOCK(); dest->id &= ~BMP_ID_LOCKED; } else _orig_masked_blit(source, dest, source_x, source_y, dest_x, dest_y, width, height); }
/* ddraw_masked_blit: * Accelerated masked blitting routine. */ static void photon_masked_blit(BITMAP *source, BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height) { struct Ph_rect source_rect = { { source_x + source->x_ofs, source_y + source->y_ofs }, { source_x + source->x_ofs + width - 1, source_y + source->y_ofs + height - 1 } }; struct Ph_rect dest_rect = { { dest_x + dest->x_ofs, dest_y + dest->y_ofs }, { dest_x + dest->x_ofs + width - 1, dest_y + dest->y_ofs + height - 1 } }; struct BITMAP *dest_parent, *source_parent; if (is_video_bitmap(source)) { if (!chroma_on) { PgChromaOn(); chroma_on = TRUE; } /* find parents */ source_parent = source; while (source_parent->id & BMP_ID_SUB) source_parent = (BITMAP *)source_parent->extra; dest_parent = dest; while (dest_parent->id & BMP_ID_SUB) dest_parent = (BITMAP *)dest_parent->extra; PgContextBlit(BMP_EXTRA(source_parent)->context, &source_rect, BMP_EXTRA(dest_parent)->context, &dest_rect); /* only for windowed mode */ if (dest_parent == pseudo_screen) ph_update_window(&dest_rect); } else { /* have to use the original software version */ _orig_masked_blit(source, dest, source_x, source_y, dest_x, dest_y, width, height); } }
/* photon_draw_sprite: * Accelerated sprite drawing routine. */ static void photon_draw_sprite(BITMAP *bmp, BITMAP *sprite, int x, int y) { int sx, sy, w, h; if (is_video_bitmap(sprite)) { sx = sprite->x_ofs; sy = sprite->y_ofs; w = sprite->w; h = sprite->h; if (bmp->clip) { if (x < bmp->cl) { sx += bmp->cl - x; w -= bmp->cl - x; x = bmp->cl; } if (y < bmp->ct) { sy += bmp->ct - y; h -= bmp->ct - y; y = bmp->ct; } if (x + w > bmp->cr) w = bmp->cr - x; if (w <= 0) return; if (y + h > bmp->cb) h = bmp->cb - y; if (h <= 0) return; } photon_masked_blit(sprite, bmp, sx, sy, x, y, w, h); } else { /* have to use the original software version */ _orig_draw_sprite(bmp, sprite, x, y); } }
/* ddraw_draw_sprite: * Accelerated sprite drawing routine. */ static void ddraw_draw_sprite(BITMAP * bmp, BITMAP * sprite, int x, int y) { int sx, sy, w, h; if (is_video_bitmap(sprite) || is_system_bitmap(sprite)) { sx = 0; /* sprite->x_ofs & sprite->y_ofs will be accounted for in ddraw_masked_blit */ sy = 0; w = sprite->w; h = sprite->h; if (bmp->clip) { if (x < bmp->cl) { sx += bmp->cl - x; w -= bmp->cl - x; x = bmp->cl; } if (y < bmp->ct) { sy += bmp->ct - y; h -= bmp->ct - y; y = bmp->ct; } if (x + w > bmp->cr) w = bmp->cr - x; if (w <= 0) return; if (y + h > bmp->cb) h = bmp->cb - y; if (h <= 0) return; } ddraw_masked_blit(sprite, bmp, sx, sy, x, y, w, h); } else { /* have to use the original software version */ _orig_draw_sprite(bmp, sprite, x, y); } }
int uip_vgamode(void) { int depth, rate; unsigned long screenbase; for (rate = 60; rate <= 70; rate += 10) { for (depth = 15; depth <= 16; depth++) { LOG_VERBOSE(("Trying mode 640x480 depth %d rate %d", depth, rate)); set_color_depth(depth); request_refresh_rate(rate); if ((set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 480 * 2) < 0)) { LOG_VERBOSE(("Mode not supported")); continue; } if (SCREEN_W != 640 || SCREEN_H != 480) { LOG_CRITICAL(("Screen not approriate for depth %d rate %d", depth, rate)); continue; } goto WHEE; } } LOG_CRITICAL(("Failed to find suitable mode")); return 1; WHEE: uip_vga = 1; if (uip_forceredshift != -1 && uip_forcegreenshift != -1 && uip_forceblueshift != -1) { uip_uipinfo->redshift = uip_forceredshift; uip_uipinfo->greenshift = uip_forcegreenshift; uip_uipinfo->blueshift = uip_forceblueshift; } else { uip_uipinfo->redshift = ui_topbit(makecol(255, 0, 0)) - 4; uip_uipinfo->greenshift = ui_topbit(makecol(0, 255, 0)) - 4; uip_uipinfo->blueshift = ui_topbit(makecol(0, 0, 255)) - 4; } if ((uip_bank0 = create_video_bitmap(640, 480)) == NULL || (uip_bank1 = create_video_bitmap(640, 480)) == NULL) { uip_textmode(); LOG_CRITICAL(("Failed to allocate memory pages")); return 1; } if (is_linear_bitmap(uip_bank0) == 0 || is_linear_bitmap(uip_bank1) == 0 || is_video_bitmap(uip_bank0) == 0 || is_video_bitmap(uip_bank1) == 0) { uip_textmode(); LOG_CRITICAL(("Allocated bitmaps not suitable or linear addressing mode " "not supported by hardware")); return 1; } /* don't you just hate MS platforms? */ __djgpp_nearptr_enable(); __dpmi_get_segment_base_address(uip_bank0->seg, &screenbase); uip_uipinfo->screenmem0 = (uint8 *)(screenbase + uip_bank0->line[0] - __djgpp_base_address); __dpmi_get_segment_base_address(uip_bank1->seg, &screenbase); uip_uipinfo->screenmem1 = (uint8 *)(screenbase + uip_bank1->line[0] - __djgpp_base_address); uip_uipinfo->linewidth = 2 * VIRTUAL_W; /* 16 bit */ uip_displaybank(0); /* set current to 0th bank */ uip_clearscreen(); /* clear bank */ ui_setupscreen(); /* setup bank */ uip_displaybank(-1); /* toggle bank */ uip_clearscreen(); /* clear bank */ ui_setupscreen(); /* setup bank */ if (install_keyboard() == -1) { uip_textmode(); LOG_CRITICAL(("Unable to initialise keyboard")); return 1; } if (uip_bank0->y_ofs != 0 || uip_bank1->y_ofs != 480) { uip_textmode(); LOG_CRITICAL(("sorry, I don't understand this video layout")); return 1; } keyboard_lowlevel_callback = uip_keyboardhandler; uip_keypoll = keyboard_needs_poll()? 1 : 0; return 0; }
/* destroy_bitmap: * Destroys a memory bitmap. */ void destroy_bitmap(BITMAP *bitmap) { VRAM_BITMAP *prev, *pos; if (bitmap) { if (is_video_bitmap(bitmap)) { /* special case for getting rid of video memory bitmaps */ ASSERT(!_dispsw_status); prev = NULL; pos = vram_bitmap_list; while (pos) { if (pos->bmp == bitmap) { if (prev) prev->next_y = pos->next_y; else vram_bitmap_list = pos->next_y; if (pos->x < 0) { /* the driver is in charge of this object */ gfx_driver->destroy_video_bitmap(bitmap); _AL_FREE(pos); return; } /* Update cached bitmap size using worst case scenario: * the bitmap lies between two holes whose size is the cached * size on each axis respectively. */ failed_bitmap_w = failed_bitmap_w * 2 + ((bitmap->w + 15) & ~15); if (failed_bitmap_w > BMP_MAX_SIZE) failed_bitmap_w = BMP_MAX_SIZE; failed_bitmap_h = failed_bitmap_h * 2 + bitmap->h; if (failed_bitmap_h > BMP_MAX_SIZE) failed_bitmap_h = BMP_MAX_SIZE; _AL_FREE(pos); break; } prev = pos; pos = pos->next_y; } _unregister_switch_bitmap(bitmap); } else if (is_system_bitmap(bitmap)) { /* special case for getting rid of system memory bitmaps */ ASSERT(gfx_driver != NULL); if (gfx_driver->destroy_system_bitmap) { gfx_driver->destroy_system_bitmap(bitmap); return; } } /* normal memory or sub-bitmap destruction */ if (system_driver->destroy_bitmap) { if (system_driver->destroy_bitmap(bitmap)) return; } if (bitmap->dat) _AL_FREE(bitmap->dat); _AL_FREE(bitmap); } }
void SuperEagle_ex(uint8 *src, uint32 src_pitch, uint8 *unused, ALLEGRO_BITMAP *dest, uint32 width, uint32 height) { int j, v; unsigned int x, y; int sbpp = BYTES_PER_PIXEL(bitmap_color_depth(dest)); unsigned long color[12]; unsigned char **src_line = new unsigned char*[4]; unsigned char **dst_line = new unsigned char*[2]; /* Point to the first 3 lines. */ src_line[0] = src; src_line[1] = src; src_line[2] = src + src_pitch; src_line[3] = src + src_pitch * 2; /* Can we write the results directly? */ if (is_video_bitmap(dest) || is_planar_bitmap(dest)) { //dst_line[0] = malloc(sizeof(char) * sbpp * width); //dst_line[1] = malloc(sizeof(char) * sbpp * width); dst_line[0] = new unsigned char[sbpp*width]; dst_line[1] = new unsigned char[sbpp*width]; v = 1; } else { dst_line[0] = dest->line[0]; dst_line[1] = dest->line[1]; v = 0; } /* Set destination */ bmp_select(dest); x = 0, y = 0; if (PixelsPerMask == 2) { unsigned short *sbp; sbp = (unsigned short*)src_line[0]; color[0] = *sbp; color[1] = color[0]; color[2] = color[0]; color[3] = color[0]; color[4] = *(sbp + 1); color[5] = *(sbp + 2); sbp = (unsigned short*)src_line[2]; color[6] = *sbp; color[7] = color[6]; color[8] = *(sbp + 1); color[9] = *(sbp + 2); sbp = (unsigned short*)src_line[3]; color[10] = *sbp; color[11] = *(sbp + 1); } else { unsigned long *lbp; lbp = (unsigned long*)src_line[0]; color[0] = *lbp; color[1] = color[0]; color[2] = color[0]; color[3] = color[0]; color[4] = *(lbp + 1); color[5] = *(lbp + 2); lbp = (unsigned long*)src_line[2]; color[6] = *lbp; color[7] = color[6]; color[8] = *(lbp + 1); color[9] = *(lbp + 2); lbp = (unsigned long*)src_line[3]; color[10] = *lbp; color[11] = *(lbp + 1); } for (y = 0; y < height; y++) { /* Todo: x = width - 2, x = width - 1 */ for (x = 0; x < width; x++) { unsigned long product1a, product1b, product2a, product2b; //--------------------------------------- B1 B2 0 1 // 4 5 6 S2 -> 2 3 4 5 // 1 2 3 S1 6 7 8 9 // A1 A2 10 11 if (color[7] == color[4] && color[3] != color[8]) { product1b = product2a = color[7]; if ((color[6] == color[7]) || (color[4] == color[1])) product1a = INTERPOLATE(color[7], INTERPOLATE(color[7], color[3])); else product1a = INTERPOLATE(color[3], color[4]); if ((color[4] == color[5]) || (color[7] == color[10])) product2b = INTERPOLATE(color[7], INTERPOLATE(color[7], color[8])); else product2b = INTERPOLATE(color[7], color[8]); } else if (color[3] == color[8] && color[7] != color[4]) { product2b = product1a = color[3]; if ((color[0] == color[3]) || (color[5] == color[9])) product1b = INTERPOLATE(color[3], INTERPOLATE(color[3], color[4])); else product1b = INTERPOLATE(color[3], color[1]); if ((color[8] == color[11]) || (color[2] == color[3])) product2a = INTERPOLATE(color[3], INTERPOLATE(color[3], color[2])); else product2a = INTERPOLATE(color[7], color[8]); } else if (color[3] == color[8] && color[7] == color[4]) { register int r = 0; r += GET_RESULT(color[4], color[3], color[6], color[10]); r += GET_RESULT(color[4], color[3], color[2], color[0]); r += GET_RESULT(color[4], color[3], color[11], color[9]); r += GET_RESULT(color[4], color[3], color[1], color[5]); if (r > 0) { product1b = product2a = color[7]; product1a = product2b = INTERPOLATE(color[3], color[4]); } else if (r < 0) { product2b = product1a = color[3]; product1b = product2a = INTERPOLATE(color[3], color[4]); } else { product2b = product1a = color[3]; product1b = product2a = color[7]; } } else { product2b = product1a = INTERPOLATE(color[7], color[4]); product2b = Q_INTERPOLATE(color[8], color[8], color[8], product2b); product1a = Q_INTERPOLATE(color[3], color[3], color[3], product1a); product2a = product1b = INTERPOLATE(color[3], color[8]); product2a = Q_INTERPOLATE(color[7], color[7], color[7], product2a); product1b = Q_INTERPOLATE(color[4], color[4], color[4], product1b); } if (PixelsPerMask == 2) { *((unsigned long *) (&dst_line[0][x * 4])) = product1a | (product1b << 16); *((unsigned long *) (&dst_line[1][x * 4])) = product2a | (product2b << 16); } else { *((unsigned long *) (&dst_line[0][x * 8])) = product1a; *((unsigned long *) (&dst_line[0][x * 8 + 4])) = product1b; *((unsigned long *) (&dst_line[1][x * 8])) = product2a; *((unsigned long *) (&dst_line[1][x * 8 + 4])) = product2b; } /* Move color matrix forward */ color[0] = color[1]; color[2] = color[3]; color[3] = color[4]; color[4] = color[5]; color[6] = color[7]; color[7] = color[8]; color[8] = color[9]; color[10] = color[11]; if (x < width - 2) { x += 2; if (PixelsPerMask == 2) { color[1] = *(((unsigned short*)src_line[0]) + x); if (x < width) { color[5] = *(((unsigned short*)src_line[1]) + x + 1); color[9] = *(((unsigned short*)src_line[2]) + x + 1); } color[11] = *(((unsigned short*)src_line[3]) + x); } else { color[1] = *(((unsigned long*)src_line[0]) + x); if (x < width) { color[5] = *(((unsigned long*)src_line[1]) + x + 1); color[9] = *(((unsigned long*)src_line[2]) + x + 1); } color[11] = *(((unsigned long*)src_line[3]) + x); } x -= 2; } } /* We're done with one line, so we shift the source lines up */ src_line[0] = src_line[1]; src_line[1] = src_line[2]; src_line[2] = src_line[3]; /* Read next line */ if (y + 3 >= height) src_line[3] = src_line[2]; else src_line[3] = src_line[2] + src_pitch; /* Then shift the color matrix up */ if (PixelsPerMask == 2) { unsigned short *sbp; sbp = (unsigned short*)src_line[0]; color[0] = *sbp; color[1] = *(sbp + 1); sbp = (unsigned short*)src_line[1]; color[2] = *sbp; color[3] = color[2]; color[4] = *(sbp + 1); color[5] = *(sbp + 2); sbp = (unsigned short*)src_line[2]; color[6] = *sbp; color[7] = color[6]; color[8] = *(sbp + 1); color[9] = *(sbp + 2); sbp = (unsigned short*)src_line[3]; color[10] = *sbp; color[11] = *(sbp + 1); } else { unsigned long *lbp; lbp = (unsigned long*)src_line[0]; color[0] = *lbp; color[1] = *(lbp + 1); lbp = (unsigned long*)src_line[1]; color[2] = *lbp; color[3] = color[2]; color[4] = *(lbp + 1); color[5] = *(lbp + 2); lbp = (unsigned long*)src_line[2]; color[6] = *lbp; color[7] = color[6]; color[8] = *(lbp + 1); color[9] = *(lbp + 2); lbp = (unsigned long*)src_line[3]; color[10] = *lbp; color[11] = *(lbp + 1); } /* Write the 2 lines, if not already done so */ if (v) { unsigned long dst_addr; dst_addr = bmp_write_line(dest, y * 2); for (j = 0; j < dest->w * sbpp; j += sizeof(long)) bmp_write32(dst_addr + j, *((unsigned long *) (dst_line[0] + j))); dst_addr = bmp_write_line(dest, y * 2 + 1); for (j = 0; j < dest->w * sbpp; j += sizeof(long)) bmp_write32(dst_addr + j, *((unsigned long *) (dst_line[1] + j))); } else { if (y < height - 1) { dst_line[0] = dest->line[y * 2 + 2]; dst_line[1] = dest->line[y * 2 + 3]; } } } bmp_unwrite_line(dest); if (v) { delete dst_line[0]; delete dst_line[1]; } delete[] src_line; delete[] dst_line; }