void HiRes5Engine::loadSong(Common::ReadStream &stream) { while (true) { const byte period = stream.readByte(); if (stream.err() || stream.eos()) error("Error loading song"); if (period == 0xff) return; byte length = stream.readByte(); if (stream.err() || stream.eos()) error("Error loading song"); const uint kLoopCycles = 20; // Delay loop cycles double freq = 0.0; // This computation ignores CPU cycles spent on overflow handling and // speaker control. As a result, our tone frequencies will be slightly // higher than those on original hardware. if (period != 0) freq = kClock / 2.0 / (period * kLoopCycles); const double len = (length > 0 ? length - 1 : 255) * 256 * kLoopCycles * 1000 / (double)kClock; _song.push_back(Tone(freq, len)); } }
void Game_Picture::UpdateSprite() { if (!sprite) return; if (data.name.empty()) return; sprite->SetX((int)data.current_x); sprite->SetY((int)data.current_y); sprite->SetZ(1100 + data.ID); sprite->SetZoomX(data.current_magnify / 100.0); sprite->SetZoomY(data.current_magnify / 100.0); sprite->SetOx((int)(sprite->GetBitmap()->GetWidth() / 2)); sprite->SetOy((int)(sprite->GetBitmap()->GetHeight() / 2)); sprite->SetAngle(data.effect_mode == 1 ? data.current_rotation : 0.0); sprite->SetWaverPhase(data.effect_mode == 2 ? data.current_waver : 0.0); sprite->SetWaverDepth(data.effect_mode == 2 ? data.current_effect * 2 : 0); sprite->SetOpacity( (int)(255 * (100 - data.current_top_trans) / 100), (int)(255 * (100 - data.current_bot_trans) / 100)); if (data.current_bot_trans != data.current_top_trans) sprite->SetBushDepth(sprite->GetHeight() / 2); sprite->SetTone(Tone((int) (data.current_red * 128 / 100), (int) (data.current_green * 128 / 100), (int) (data.current_blue * 128 / 100), (int) (data.current_sat * 128 / 100))); }
void BattleAnimation::DrawAt(int x, int y) { if (!sprite) return; // Initialization failed if (IsDone()) return; const RPG::AnimationFrame& anim_frame = animation.frames[frame]; std::vector<RPG::AnimationCellData>::const_iterator it; for (it = anim_frame.cells.begin(); it != anim_frame.cells.end(); ++it) { const RPG::AnimationCellData& cell = *it; if (!cell.valid) { // Skip unused cells (they are created by deleting cells in the // animation editor, resulting in gaps) continue; } sprite->SetX(cell.x + x); sprite->SetY(cell.y + y); int sx = cell.cell_id % 5; int sy = cell.cell_id / 5; int size = large ? 128 : 96; sprite->SetSrcRect(Rect(sx * size, sy * size, size, size)); sprite->SetOx(size / 2); sprite->SetOy(size / 2); sprite->SetTone(Tone(cell.tone_red * 128 / 100, cell.tone_green * 128 / 100, cell.tone_blue * 128 / 100, cell.tone_gray * 128 / 100)); sprite->SetOpacity(255 * (100 - cell.transparency) / 100); sprite->SetZoomX(cell.zoom / 100.0); sprite->SetZoomY(cell.zoom / 100.0); sprite->Draw(); } }
Window_ShopParty::Window_ShopParty(int ix, int iy, int iwidth, int iheight) : Window_Base(ix, iy, iwidth, iheight) { SetContents(Bitmap::Create(width - 16, height - 16)); contents->SetTransparentColor(windowskin->GetTransparentColor()); cycle = 0; item_id = 0; const std::vector<Game_Actor*>& actors = Game_Party::GetActors(); for (size_t i = 0; i < actors.size() && i < 4; i++) { Game_Actor *actor = actors[i]; const std::string& sprite_name = actor->GetCharacterName(); int sprite_id = actor->GetCharacterIndex(); BitmapRef bm = Cache::Charset(sprite_name); int width = bm->GetWidth() / 4 / 3; int height = bm->GetHeight() / 2 / 4; for (int j = 0; j < 3; j++) { int sx = ((sprite_id % 4) * 3 + j) * width; int sy = ((sprite_id / 4) * 4 + 2) * height; Rect src(sx, sy, width, height); for (int k = 0; k < 2; k++) { BitmapRef bm2 = Bitmap::Create(width, height, true); bm2->SetTransparentColor(bm->GetTransparentColor()); bm2->Clear(); bm2->Blit(0, 0, *bm, src, 255); if (k == 0) bm2->ToneBlit(0, 0, *bm2, bm2->GetRect(), Tone(0, 0, 0, 255)); bitmaps[i][j][k] = bm2; } } } Refresh(); }
void HiRes5Engine::animateLights() const { int index; byte color = 0x2a; for (index = 4; index >= 0; --index) drawLight(index, color); index = 4; while (!g_engine->shouldQuit()) { drawLight(index, color ^ 0x7f); // There's a delay here in the original engine. We leave it out as // we're already slower than the original without any delay. const uint kLoopCycles = 25; const byte period = (index + 1) << 4; const double freq = kClock / 2.0 / (period * kLoopCycles); const double len = 128 * period * kLoopCycles * 1000 / (double)kClock; Tones tone; tone.push_back(Tone(freq, len)); if (playTones(tone, false, true)) break; drawLight(index, color ^ 0xff); if (--index < 0) { index = 4; color ^= 0xff; } } }
void main(void) { SetJobName("Beeper", 6); while (1) { Sleep(50); Tone(150,10); } }
void Surface::EffectsBlit(int x, int y, Bitmap* src, Rect src_rect, int top_opacity, int bottom_opacity, int opacity_split, const Tone& tone, double zoom_x, double zoom_y, double angle, int waver_depth, double waver_phase) { bool rotate = angle != 0.0; bool scale = zoom_x != 1.0 || zoom_y != 1.0; bool waver = waver_depth != 0; bool tone_change = tone != Tone(); bool opacity = (opacity_split <= 0) ? (top_opacity < 255) : (opacity_split >= src_rect.height) ? (bottom_opacity < 255) : (top_opacity < 255 || bottom_opacity < 255); opacity = top_opacity < 255 || bottom_opacity < 255; Surface* draw = (Surface*) NULL; if (tone_change) { if (!rotate && !scale && !opacity && !waver) { ToneBlit(x, y, src, src_rect, tone); return; } bool transparent = src->GetTransparent(); draw = CreateSurface(src_rect.width, src_rect.height, transparent); if (transparent) draw->Clear(); draw->ToneBlit(0, 0, src, src_rect, tone); src = draw; src_rect.x = 0; src_rect.y = 0; } if (rotate) { Matrix fwd = Matrix::Setup(angle, zoom_x, zoom_y, src_rect.x, src_rect.y, x, y); EffectsBlit(fwd, src, src_rect, top_opacity, bottom_opacity, opacity_split); } else if (scale) EffectsBlit(x, y, src, src_rect, top_opacity, bottom_opacity, opacity_split, zoom_x, zoom_y, waver_depth, waver_phase); else EffectsBlit(x, y, src, src_rect, top_opacity, bottom_opacity, opacity_split, waver_depth, waver_phase); if (draw != NULL) delete draw; }
// Constructor Sprite::Sprite() : type(TypeSprite), visible(true), x(0), y(0), z(0), ox(0), oy(0), flash_duration(0), flash_frame(0), needs_refresh(true), bitmap_changed(true), src_rect_effect(Rect()), opacity_top_effect(255), opacity_bottom_effect(128), bush_effect(0), tone_effect(Tone()), flipx_effect(false), flipy_effect(false), zoom_x_effect(1.0), zoom_y_effect(1.0), angle_effect(0.0), waver_effect_depth(0), waver_effect_phase(0.0), flash_effect(Color(0,0,0,0)), bitmap_effects_src_rect(Rect()), bitmap_effects_valid(false), current_tone(Tone()), current_flash(Color(0,0,0,0)), current_flip_x(false), current_flip_y(false) { Graphics::RegisterDrawable(this); }
void Bitmap::EffectsBlit(int x, int y, Bitmap const& src, Rect const& src_rect_, int top_opacity, int bottom_opacity, int opacity_split, const Tone& tone, double zoom_x, double zoom_y, double angle, int waver_depth, double waver_phase) { Rect src_rect = src_rect_; bool rotate = angle != 0.0; bool scale = zoom_x != 1.0 || zoom_y != 1.0; bool waver = waver_depth != 0; bool tone_change = tone != Tone(); bool opacity = (opacity_split <= 0) ? (top_opacity < 255) : (opacity_split >= src_rect.height) ? (bottom_opacity < 255) : (top_opacity < 255 || bottom_opacity < 255); opacity = top_opacity < 255 || bottom_opacity < 255; Bitmap const* draw = &src; BitmapRef draw_; if (tone_change) { if (!rotate && !scale && !opacity && !waver) { ToneBlit(x, y, src, src_rect, tone); return; } bool transparent = src.GetTransparent(); draw_ = Create(src_rect.width, src_rect.height, transparent); if (transparent) draw_->Clear(); draw_->ToneBlit(0, 0, src, src_rect, tone); draw = draw_.get(); src_rect.x = 0; src_rect.y = 0; } if (rotate) { Matrix fwd = Matrix::Setup(angle, zoom_x, zoom_y, src_rect.x, src_rect.y, x, y); EffectsBlit(fwd, src, src_rect, top_opacity, bottom_opacity, opacity_split); } else if (scale) EffectsBlit(x, y, *draw, src_rect, top_opacity, bottom_opacity, opacity_split, zoom_x, zoom_y, waver_depth, waver_phase); else EffectsBlit(x, y, *draw, src_rect, top_opacity, bottom_opacity, opacity_split, waver_depth, waver_phase); }
Spectrum Analyzer::computeSnac(const QVector<double> acf, const QVector<double> signal) const { Spectrum snac(m_sampleSize); const quint32 W = m_sampleSize; qreal mSum = 2 * acf[0]; int tau = 0; for (auto &s : snac) { s = Tone(tau, 2 * acf[tau] / mSum); ++tau; const auto m1 = signal[tau - 1]; const auto m2 = signal[W - tau]; mSum -= m1 * m1 + m2 * m2; } return snac; }
void BitmapScreen::ClearEffects() { needs_refresh = true; opacity_top_effect = 255; opacity_bottom_effect = 128; bush_effect = 0; tone_effect = Tone(); src_rect_effect = Rect(0, 0, 0, 0); flipx_effect = false; flipy_effect = false; zoom_x_effect = 1.0; zoom_y_effect = 1.0; angle_effect = 0.0; waver_effect_depth = 0; waver_effect_phase = 0.0; flash_effect = Color(0,0,0,0); }
void BitmapScreen::BlitScreenIntern(Bitmap const& draw_bitmap, int x, int y, Rect const& src_rect, bool need_scale, int bush_y) { if (! &draw_bitmap) return; BitmapRef dst = DisplayUi->GetDisplaySurface(); int opacity_split = bush_y; double zoom_x = need_scale ? zoom_x_effect : 1.0; double zoom_y = need_scale ? zoom_y_effect : 1.0; dst->EffectsBlit(x, y, draw_bitmap, src_rect, opacity_top_effect, opacity_bottom_effect, opacity_split, Tone(), zoom_x, zoom_y, angle_effect * 3.14159 / 180, waver_effect_depth, waver_effect_phase); }
void Sound(u8 pin, u8 note, u16 duration, u8 vol) { // Frequency table in French : http://fr.wikipedia.org/wiki/Note_de_musique // and in English http://liutaiomottola.com/formulae/freqtab.htm // freq. must be > 3000Hz so notes are taken from the 8th octave //const u16 freq[] = {2093,2217,2349,2489,2637,2793,2959,3135,3322,3520,3729,3951,4186}; //const u16 freq[] = {4186,4434,4698,4978,5274,5587,5919,6271,6644,7040,7458,7902,8372}; const u16 freq[] = {4189,4437,4687,4966,5281,5597,5905,6250,6637,7075,7425,7894,8333}; if (vol > 10) { vol = 10; // max. volume is 10 } vol = vol * 5; // max. volume is reach for 50% duty Tone(pin, freq[note-1], duration); }
void Window_ShopParty::OnCharsetSpriteReady(FileRequestResult* /* result */, int party_index) { Game_Actor *actor = Main_Data::game_party->GetActors()[party_index]; const std::string& sprite_name = actor->GetSpriteName(); int sprite_id = actor->GetSpriteIndex(); BitmapRef bm = Cache::Charset(sprite_name); int width = bm->GetWidth() / 4 / 3; int height = bm->GetHeight() / 2 / 4; for (int j = 0; j < 3; j++) { int sx = ((sprite_id % 4) * 3 + j) * width; int sy = ((sprite_id / 4) * 4 + 2) * height; Rect src(sx, sy, width, height); for (int k = 0; k < 2; k++) { BitmapRef bm2 = Bitmap::Create(width, height, true); bm2->Clear(); bm2->Blit(0, 0, *bm, src, 255); if (k == 0) bm2->ToneBlit(0, 0, *bm2, bm2->GetRect(), Tone(128, 128, 128, 0), Opacity::opaque); bitmaps[party_index][j][k] = bm2; } } }
BitmapRef Sprite::Refresh(Rect& rect) { if (zoom_x_effect != 1.0 && zoom_y_effect != 1.0 && angle_effect != 0.0 && waver_effect_depth != 0) { // TODO: Out of bounds check adjustments for zoom, angle and waver // but even without this will catch most of the cases if (Rect(x - ox, y - oy, GetWidth(), GetHeight()).IsOutOfBounds(Rect(0, 0, SCREEN_TARGET_WIDTH, SCREEN_TARGET_HEIGHT))) { return BitmapRef(); }; } rect.Adjust(bitmap->GetWidth(), bitmap->GetHeight()); bool no_tone = tone_effect == Tone(); bool no_flash = flash_effect.alpha == 0; bool no_flip = !flipx_effect && !flipy_effect; bool no_effects = no_tone && no_flash && no_flip; bool effects_changed = tone_effect != current_tone || flash_effect != current_flash || flipx_effect != current_flip_x || flipy_effect != current_flip_y; bool effects_rect_changed = rect != bitmap_effects_src_rect; if (effects_changed || effects_rect_changed || bitmap_changed) { bitmap_effects_valid = false; } if (no_effects) return bitmap; if (bitmap_effects && bitmap_effects_valid) return bitmap_effects; BitmapRef src_bitmap; if (no_effects) src_bitmap = bitmap; else if (bitmap_effects_valid) src_bitmap = bitmap_effects; else { current_tone = tone_effect; current_flash = flash_effect; current_flip_x = flipx_effect; current_flip_y = flipy_effect; if (bitmap_effects && bitmap_effects->GetWidth() < rect.x + rect.width && bitmap_effects->GetHeight() < rect.y + rect.height) { bitmap_effects.reset(); } if (!bitmap_effects) bitmap_effects = Bitmap::Create(bitmap->GetWidth(), bitmap->GetHeight(), true); bitmap_effects->Clear(); if (no_tone && no_flash) bitmap_effects->FlipBlit(rect.x, rect.y, *bitmap, rect, flipx_effect, flipy_effect, Opacity::opaque); else if (no_flip && no_flash) bitmap_effects->ToneBlit(rect.x, rect.y, *bitmap, rect, tone_effect, Opacity::opaque); else if (no_flip && no_tone) bitmap_effects->BlendBlit(rect.x, rect.y, *bitmap, rect, flash_effect, Opacity::opaque); else if (no_flash) { bitmap_effects->ToneBlit(rect.x, rect.y, *bitmap, rect, tone_effect, Opacity::opaque); bitmap_effects->Flip(rect, flipx_effect, flipy_effect); } else if (no_tone) { bitmap_effects->BlendBlit(rect.x, rect.y, *bitmap, rect, flash_effect, Opacity::opaque); bitmap_effects->Flip(rect, flipx_effect, flipy_effect); } else if (no_flip) { bitmap_effects->ToneBlit(rect.x, rect.y, *bitmap, rect, tone_effect, Opacity::opaque); bitmap_effects->BlendBlit(rect.x, rect.y, *bitmap_effects, rect, flash_effect, Opacity::opaque); } else { bitmap_effects->ToneBlit(rect.x, rect.y, *bitmap, rect, tone_effect, Opacity::opaque); bitmap_effects->BlendBlit(rect.x, rect.y, *bitmap_effects, rect, flash_effect, Opacity::opaque); bitmap_effects->Flip(rect, flipx_effect, flipy_effect); } bitmap_effects_src_rect = rect; bitmap_effects_valid = true; src_bitmap = bitmap_effects; } return src_bitmap; }
void Game_Picture::UpdateSprite() { RPG::SavePicture& data = GetData(); if (!sprite) return; if (data.name.empty()) return; // RPG Maker 2k3 1.12: Spritesheets if (HasSpritesheet() && (data.spritesheet_frame != last_spritesheet_frame || !sheet_bitmap)) { // Usage of an additional bitmap instead of Subrect is necessary because the Subrect // approach will fail while the bitmap is rotated because the outer parts will be // visible for degrees != 90 * n if (!sheet_bitmap) { int frame_width = whole_bitmap->GetWidth() / data.spritesheet_cols; int frame_height = whole_bitmap->GetHeight() / data.spritesheet_rows; sheet_bitmap = Bitmap::Create(frame_width, frame_height); } last_spritesheet_frame = data.spritesheet_frame; int sx = sheet_bitmap->GetWidth() * ((last_spritesheet_frame - 1) % data.spritesheet_cols); int sy = sheet_bitmap->GetHeight() * ((last_spritesheet_frame - 1) / data.spritesheet_cols % data.spritesheet_rows); Rect r(sx, sy, sheet_bitmap->GetWidth(), sheet_bitmap->GetHeight()); sheet_bitmap->Clear(); if (last_spritesheet_frame > 0 && last_spritesheet_frame <= data.spritesheet_cols * data.spritesheet_rows) { sheet_bitmap->Blit(0, 0, *whole_bitmap, r, Opacity::opaque); } sprite->SetBitmap(sheet_bitmap); } int x = data.current_x; int y = data.current_y; if (data.flags.affected_by_shake) { x -= Main_Data::game_data.screen.shake_position; y += Main_Data::game_data.screen.shake_position_y; } sprite->SetX(x); sprite->SetY(y); if (Player::IsMajorUpdatedVersion()) { // Battle Animations are above pictures int priority = Drawable::GetPriorityForMapLayer(data.map_layer); if (priority > 0) { sprite->SetZ(priority + z_mask + data.ID); } } else { // Battle Animations are below pictures sprite->SetZ(Priority_PictureOld + data.ID); } sprite->SetZoomX(data.current_magnify / 100.0); sprite->SetZoomY(data.current_magnify / 100.0); sprite->SetOx(sprite->GetBitmap()->GetWidth() / 2); sprite->SetOy(sprite->GetBitmap()->GetHeight() / 2); sprite->SetAngle(data.effect_mode != 2 ? data.current_rotation * 360 / 256 : 0.0); sprite->SetWaverPhase(data.effect_mode == 2 ? data.current_waver : 0.0); sprite->SetWaverDepth(data.effect_mode == 2 ? data.current_effect * 2 : 0); sprite->SetOpacity( (int)(255 * (100 - data.current_top_trans) / 100), (int)(255 * (100 - data.current_bot_trans) / 100)); if (data.current_bot_trans != data.current_top_trans) sprite->SetBushDepth(sprite->GetHeight() / 2); auto tone = Tone((int) (data.current_red * 128 / 100), (int) (data.current_green * 128 / 100), (int) (data.current_blue * 128 / 100), (int) (data.current_sat * 128 / 100)); if (data.flags.affected_by_tint) { auto screen_tone = Main_Data::game_screen->GetTone(); tone = Blend(tone, screen_tone); } sprite->SetTone(tone); if (data.flags.affected_by_flash) { int flash_level = 0; int flash_time = 0; auto flash = Main_Data::game_screen->GetFlash(flash_level, flash_time); if (flash_time > 0) { flash.alpha = flash_level; sprite->Flash(flash, flash_time); } } }
/****************************************************************************** * Interpret the command line and scan the given GIF file. * ******************************************************************************/ void main(int argc, char **argv) { int i, j, k, Error, NumFiles, Size, Row, Col, Width, Height, ExtCode, Count, ColorMapSize, GraphDriver, GraphMode, Sum, HelpFlag = FALSE, BGIPathFlag = FALSE, BGIUserDriverFlag = FALSE, ZoomFlag = FALSE; GifRecordType RecordType; GifByteType *Extension; char Str[80], *BGIUserDriverNameMode, **FileName = NULL; GifRowType *ScreenBuffer; GifFileType *GifFile; struct text_info TextInfo; /* So we can restore starting text mode. */ if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint, &BGIPathFlag, &BGIPath, &BGIUserDriverFlag, &BGIUserDriverNameMode, &ZoomFlag, &ZoomFactor, &BeepsDisabled, &HelpFlag, &NumFiles, &FileName)) != FALSE || (NumFiles > 1 && !HelpFlag)) { if (Error) GAPrintErrMsg(Error); else if (NumFiles > 1) GIF_MESSAGE("Error in command line parsing - one GIF file please."); GAPrintHowTo(CtrlStr); exit(1); } if (HelpFlag) { fprintf(stderr, VersionStr); GAPrintHowTo(CtrlStr); exit(0); } if (BGIUserDriverFlag) { /* Use the driver supplied by the user! */ BGIInstallUserDriver(BGIUserDriverNameMode); installuserdriver(BGIUserDriverName, detectVGA); GraphDriver = BGI_USER_INSTALL; } else { /* Sense type of display we have and attempt to load right driver. */ detectgraph(&GraphDriver, &GraphMode); if (GraphDriver < 0) GIF_EXIT("BGI Auto detect: No graphics device detected."); } /* Put in the following any graphic driver specific setup: */ switch (GraphDriver) { case CGA: GraphMode = CGAHI; break; case EGA: GraphMode = EGAHI; break; case EGA64: GraphMode = EGA64HI; break; case EGAMONO: GraphMode = EGAMONOHI; break; case HERCMONO: GraphMode = HERCMONOHI; break; case VGA: GraphMode = VGAHI; break; case BGI_USER_INSTALL: GraphDriver = DETECT; GraphMode = BGIUserDriverMode; break; default: GIF_EXIT("Requested graphic device is not supported."); break; } if (NumFiles == 1) { GifFileName = *FileName; if ((GifFile = DGifOpenFileName(*FileName)) == NULL) { PrintGifError(); exit(-1); } } else { /* Use the stdin instead: */ GifFileName = "Stdin"; setmode(0, O_BINARY); if ((GifFile = DGifOpenFileHandle(0)) == NULL) { PrintGifError(); exit(-1); } } /* Allocate the screen as vector of column of rows. We cannt allocate */ /* the all screen at once, as this broken minded CPU can allocate up to */ /* 64k at a time and our image can be bigger than that: */ /* Note this screen is device independent - its the screen as defined by */ /* the GIF file parameters itself. */ if ((ScreenBuffer = (GifRowType *) malloc(GifFile -> SHeight * sizeof(GifRowType *))) == NULL) GIF_EXIT("Failed to allocate memory required, aborted."); Size = GifFile -> SWidth * sizeof(GifPixelType);/* Size in bytes of one row.*/ if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL) /* First row. */ GIF_EXIT("Failed to allocate memory required, aborted."); for (i = 0; i < GifFile -> SWidth; i++) /* Set its color to BackGround. */ ScreenBuffer[0][i] = GifFile -> SBackGroundColor; MaximumScreenHeight = GifFile -> SHeight - 1; for (i = 1; i < GifFile -> SHeight; i++) { /* Allocate the other rows, and set their color to background too: */ if ((ScreenBuffer[i] = (GifRowType) malloc(Size)) == NULL) { if (i > 30) { /* Free some memory for the BGI driver and auxilary. */ for (j = 1; j < 28; j++) free((char *) ScreenBuffer[i - j]); MaximumScreenHeight = i - 28; fprintf(stderr, "\n%s: Failed to allocate all memory required, last line %d.\n", PROGRAM_NAME, MaximumScreenHeight); break; } else GIF_EXIT("Failed to allocate memory required, aborted."); } memcpy(ScreenBuffer[i], ScreenBuffer[0], Size); } /* Scan the content of the GIF file and load the image(s) in: */ do { if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) { PrintGifError(); break; } switch (RecordType) { case IMAGE_DESC_RECORD_TYPE: if (DGifGetImageDesc(GifFile) == GIF_ERROR) { PrintGifError(); exit(-1); } Row = GifFile -> ITop; /* Image Position relative to Screen. */ Col = GifFile -> ILeft; Width = GifFile -> IWidth; Height = GifFile -> IHeight; GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ", PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height); if (GifFile -> ILeft + GifFile -> IWidth > GifFile -> SWidth || GifFile -> ITop + GifFile -> IHeight > GifFile -> SHeight) { fprintf(stderr, "Image %d is not confined to screen dimension, aborted.\n"); exit(-2); } if (GifFile -> IInterlace) { /* Need to perform 4 passes on the images: */ for (Count = i = 0; i < 4; i++) for (j = Row + InterlacedOffset[i]; j < Row + Height; j += InterlacedJumps[i]) { GifQprintf("\b\b\b\b%-4d", Count++); if (DGifGetLine(GifFile, &ScreenBuffer[MIN(j, MaximumScreenHeight)][Col], Width) == GIF_ERROR) { PrintGifError(); exit(-1); } } } else { for (i = 0; i < Height; i++, Row++) { GifQprintf("\b\b\b\b%-4d", i); if (DGifGetLine(GifFile, &ScreenBuffer[MIN(Row, MaximumScreenHeight)][Col], Width) == GIF_ERROR) { PrintGifError(); MaximumScreenHeight = MIN(i - 1, MaximumScreenHeight); } } } break; case EXTENSION_RECORD_TYPE: /* Skip any extension blocks in file: */ if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) { PrintGifError(); exit(-1); } while (Extension != NULL) { if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) { PrintGifError(); exit(-1); } } break; case TERMINATE_RECORD_TYPE: break; default: /* Should be traps by DGifGetRecordType. */ break; } } while (RecordType != TERMINATE_RECORD_TYPE); /* Lets display it - set the global variables required and do it: */ BackGround = GifFile -> SBackGroundColor; ColorMap = (GifFile -> IColorMap ? GifFile -> IColorMap : GifFile -> SColorMap); ColorMapSize = 1 << (GifFile -> IColorMap ? GifFile -> IBitsPerPixel : GifFile -> SBitsPerPixel); gettextinfo(&TextInfo); /* Save current mode so we can recover. */ initgraph(&GraphDriver, &GraphMode, BGIPath); if (graphresult() != grOk) /* Error occured during init. */ GIF_EXIT("Graphics System Error, failed to initialize driver."); if (getmaxcolor() + 1 < ColorMapSize) { sprintf(Str, "GIF Image color map (%d) is too big for device (%d).\n", ColorMapSize, getmaxcolor() + 1); closegraph(); GIF_EXIT(Str); } /* Initialize hardware pallete and also select fore/background color. */ BackGround = ForeGround = 1; Sum = ((int) ColorMap[1].Red) + ((int) ColorMap[1].Green) + ((int) ColorMap[1].Blue); j = k = Sum; for (i = 0; i < ColorMapSize; i++) { setrgbpalette(i, ColorMap[i].Red >> 2, ColorMap[i].Green >> 2, ColorMap[i].Blue >> 2); Sum = ((int) ColorMap[i].Red) + ((int) ColorMap[i].Green) + ((int) ColorMap[i].Blue); if (i != 0 && Sum > j) { /* Dont use color 0. */ ForeGround = i; j = Sum; } if (i != 0 && Sum <= k) { /* Dont use color 0. */ BackGround = i; k = Sum; } } DeviceMaxX = getmaxx(); /* Read size of physical screen. */ DeviceMaxY = getmaxy(); ScreenWidth = GifFile -> SWidth; ScreenHeight = MIN(GifFile -> SHeight, MaximumScreenHeight); Tone(500, 10); DisplayScreen(ScreenBuffer, GifFile); if (DGifCloseFile(GifFile) == GIF_ERROR) { PrintGifError(); closegraph(); exit(-1); } closegraph(); textmode(TextInfo.currmode); }
/****************************************************************************** * Given the screen buffer, display it: * * The following commands are available (case insensitive). * * 1. Four arrow to move along the screen (only if ScreenBuffer > physical * * screen in that direction. * * 2. C - goto cursor mode - print current color & position in GIF screen * * of the current pixel cursor is on. * * 3. D - zoom out by factor of 2. * * 4. R - redraw current image. * * 5. S - Print Current status/options. * * 6. U - zoom in by factor of 2. * * 7. ' ' - stop drawing current image. * * 8. ESC - to quit. * ******************************************************************************/ static void DisplayScreen(GifRowType *ScreenBuffer, GifFileType *GifFile) { int DeviceTop, DeviceLeft, /* Where ScreenBuffer is to mapped to ours. */ ScreenTop, ScreenLeft, /* Porsion of ScreenBuffer to start display. */ XPanning, YPanning, /* Amount to move using the arrows. */ GetK, DrawIt = TRUE; XPanning = DeviceMaxX / 2; YPanning = DeviceMaxY / 2; SetPosition(SET_POSITION_RESET, &ScreenLeft, &ScreenTop, &DeviceLeft, &DeviceTop, 0, 0); do { if (DrawIt && !MyKbHit()) { DrawScreen(ScreenBuffer, ScreenLeft, ScreenTop, DeviceLeft, DeviceTop); Tone(2000, 200); } DrawIt = TRUE; switch (GetK = GetKey()) { case 'C': DoCursorMode(ScreenBuffer, ScreenLeft, ScreenTop, DeviceLeft, DeviceTop); DrawIt = TRUE; break; case 'D': if (ZoomFactor > 1) { ZoomFactor >>= 1; SetPosition(SET_POSITION_ZOOM_D, &ScreenLeft, &ScreenTop, &DeviceLeft, &DeviceTop, 0, 0); } else { Tone(1000, 100); DrawIt = FALSE; } break; case 'R': break; case 'S': PrintSettingStatus(GifFile); break; case 'U': if (ZoomFactor < 256) { ZoomFactor <<= 1; SetPosition(SET_POSITION_ZOOM_U, &ScreenLeft, &ScreenTop, &DeviceLeft, &DeviceTop, 0, 0); } else { Tone(1000, 100); DrawIt = FALSE; } break; case KEY_ESC: break; case KEY_LEFT: SetPosition(SET_POSITION_PAN, &ScreenLeft, &ScreenTop, &DeviceLeft, &DeviceTop, -XPanning, 0); break; case KEY_RIGHT: SetPosition(SET_POSITION_PAN, &ScreenLeft, &ScreenTop, &DeviceLeft, &DeviceTop, XPanning, 0); break; case KEY_UP: SetPosition(SET_POSITION_PAN, &ScreenLeft, &ScreenTop, &DeviceLeft, &DeviceTop, 0, -YPanning); break; case KEY_DOWN: SetPosition(SET_POSITION_PAN, &ScreenLeft, &ScreenTop, &DeviceLeft, &DeviceTop, 0, YPanning); break; default: DrawIt = FALSE; Tone(800, 100); Tone(300, 200); break; }
Tone Game_Screen::GetTone() { return Tone((int) ((data.tint_current_red) * 128 / 100), (int) ((data.tint_current_green) * 128 / 100), (int) ((data.tint_current_blue) * 128 / 100), (int) ((data.tint_current_sat) * 128 / 100)); }
BitmapRef BitmapScreen::Refresh(Rect& rect, bool& need_scale, int& bush_y) { need_scale = false; rect.Adjust(bitmap->GetWidth(), bitmap->GetHeight()); if (rect.IsOutOfBounds(bitmap->GetWidth(), bitmap->GetHeight())) return BitmapRef(); bool no_tone = tone_effect == Tone(); bool no_flash = flash_effect.alpha == 0; bool no_flip = !flipx_effect && !flipy_effect; bool no_effects = no_tone && no_flash && no_flip; bool no_zoom = zoom_x_effect == 1.0 && zoom_y_effect == 1.0; bool effects_changed = tone_effect != current_tone || flash_effect != current_flash || flipx_effect != current_flip_x || flipy_effect != current_flip_y; bool effects_rect_changed = rect != bitmap_effects_src_rect; if (effects_changed || effects_rect_changed || bitmap_changed) { bitmap_effects_valid = false; bitmap_scale_valid = false; } if (no_effects && no_zoom) return bitmap; if (bitmap_effects != NULL && bitmap_effects_valid && no_zoom) return bitmap_effects; BitmapRef src_bitmap; if (no_effects) src_bitmap = bitmap; else if (bitmap_effects_valid) src_bitmap = bitmap_effects; else { current_tone = tone_effect; current_flash = flash_effect; current_flip_x = flipx_effect; current_flip_y = flipy_effect; if (bitmap_effects != NULL && bitmap_effects->GetWidth() < rect.x + rect.width && bitmap_effects->GetHeight() < rect.y + rect.height) { bitmap_effects.reset(); } if (!bitmap_effects) bitmap_effects = Bitmap::Create(bitmap->GetWidth(), bitmap->GetHeight(), true); bitmap_effects->Clear(); if (no_tone && no_flash) bitmap_effects->FlipBlit(rect.x, rect.y, *bitmap, rect, flipx_effect, flipy_effect); else if (no_flip && no_flash) bitmap_effects->ToneBlit(rect.x, rect.y, *bitmap, rect, tone_effect); else if (no_flip && no_tone) bitmap_effects->BlendBlit(rect.x, rect.y, *bitmap, rect, flash_effect); else if (no_flash) { bitmap_effects->ToneBlit(rect.x, rect.y, *bitmap, rect, tone_effect); bitmap_effects->Flip(rect, flipx_effect, flipy_effect); } else if (no_tone) { bitmap_effects->BlendBlit(rect.x, rect.y, *bitmap, rect, flash_effect); bitmap_effects->Flip(rect, flipx_effect, flipy_effect); } else if (no_flip) { bitmap_effects->BlendBlit(rect.x, rect.y, *bitmap, rect, flash_effect); bitmap_effects->ToneBlit(rect.x, rect.y, *bitmap_effects, rect, tone_effect); } else { bitmap_effects->BlendBlit(rect.x, rect.y, *bitmap, rect, flash_effect); bitmap_effects->ToneBlit(rect.x, rect.y, *bitmap_effects, rect, tone_effect); bitmap_effects->Flip(rect, flipx_effect, flipy_effect); } bitmap_effects_src_rect = rect; bitmap_effects_valid = true; src_bitmap = bitmap_effects; } if (no_zoom || angle_effect != 0.0) return src_bitmap; int zoomed_width = (int)(rect.width * zoom_x_effect); int zoomed_height = (int)(rect.height * zoom_y_effect); if (zoomed_width > 640 || zoomed_height > 640) { need_scale = true; return src_bitmap; } bool zoom_changed = zoom_x_effect != current_zoom_x || zoom_y_effect != current_zoom_y; bool scale_rect_changed = rect != bitmap_scale_src_rect; if (zoom_changed || scale_rect_changed) bitmap_scale_valid = false; if (bitmap_scale != NULL && bitmap_scale_valid) { bush_y = bush_y * bitmap_scale->GetHeight() / rect.height; rect = bitmap_scale->GetRect(); return bitmap_scale; } current_zoom_x = zoom_x_effect; current_zoom_y = zoom_y_effect; bitmap_scale.reset(); bitmap_scale = src_bitmap->Resample(zoomed_width, zoomed_height, rect); bitmap_scale_src_rect = rect; bitmap_scale_valid = true; bush_y = bush_y * bitmap_scale->GetHeight() / rect.height; rect = bitmap_scale->GetRect(); return bitmap_scale; }
void PixmanBitmap::ToneBlit(int x, int y, Bitmap* _src, Rect src_rect, const Tone &tone) { if (tone == Tone()) { if (_src != this) Blit(x, y, _src, src_rect, 255); return; } PixmanBitmap* src = (PixmanBitmap*) _src; if (_src != this) pixman_image_composite32(PIXMAN_OP_SRC, src->bitmap, (pixman_image_t*) NULL, bitmap, src_rect.x, src_rect.y, 0, 0, x, y, src_rect.width, src_rect.height); if (tone.gray == 0) { pixman_color_t tcolor = {tone.red << 8, tone.green << 8, tone.blue << 8, 0xFFFF}; pixman_image_t *timage = pixman_image_create_solid_fill(&tcolor); pixman_image_composite32(PIXMAN_OP_ADD, timage, src->bitmap, bitmap, src_rect.x, src_rect.y, 0, 0, x, y, src_rect.width, src_rect.height); pixman_image_unref(timage); } else { pixman_rectangle16_t rect = {0, 0, src_rect.width, src_rect.height}; PixmanBitmap *gray = new PixmanBitmap(src, src_rect, GetTransparent()); pixman_color_t gcolor = {0, 0, 0, 0xFFFF}; pixman_image_fill_rectangles(PIXMAN_OP_HSL_SATURATION, gray->bitmap, &gcolor, 1, &rect); pixman_color_t acolor = {0, 0, 0, tone.gray << 8}; pixman_image_fill_rectangles(PIXMAN_OP_IN_REVERSE, gray->bitmap, &acolor, 1, &rect); pixman_image_composite32(PIXMAN_OP_ATOP, gray->bitmap, (pixman_image_t*) NULL, bitmap, src_rect.x, src_rect.y, 0, 0, x, y, src_rect.width, src_rect.height); pixman_color_t tcolor = {tone.red << 8, tone.green << 8, tone.blue << 8, 0xFFFF}; pixman_image_t *timage = pixman_image_create_solid_fill(&tcolor); pixman_image_composite32(PIXMAN_OP_ADD, timage, src->bitmap, bitmap, src_rect.x, src_rect.y, 0, 0, x, y, src_rect.width, src_rect.height); pixman_image_unref(timage); delete gray; } RefreshCallback(); }