Unit ** __stdcall FindUnitsPoint(uint16_t y) { REG_EAX(int, x); x &= 0xffff; Rect16 area(x, y, x + 1, y + 1); return unit_search->FindUnitsRect(Rect16(x, y, x + 1, y + 1)); }
void DrawScreen() { const auto relaxed = std::memory_order_relaxed; // Overflowing is fine draw_counter.store(draw_counter.load(relaxed) + 1, relaxed); // The load screen code likes to draw screen after every grp loaded, // and this function is a lot slower than the original one if (*bw::load_screen != nullptr) { static bool drawn_load_screen_once; if (drawn_load_screen_once) return; drawn_load_screen_once = true; } PerfClock clock; StaticPerfClock::Clear(); Surface *game_screen = &*bw::game_screen; if (!game_screen->image) return; *bw::current_canvas = game_screen; if (*bw::no_draw) { memset(game_screen->image, 0, game_screen->w * game_screen->h); Rect32 area(0, 0, resolution::screen_width, resolution::screen_height); bw::CopyToFrameBuffer(&area); } else { DrawParam param; for (int i = 7; i >= 0; i--) { DrawLayer *layer = &(bw::draw_layers[i]); if (!layer->draw) continue; if (!(layer->flags & 0x21)) { if (bw::ContainsDirtyArea(layer->area.left, layer->area.top, layer->area.left + layer->area.right, layer->area.top + layer->area.bottom)) layer->flags |= 0x4; else if (~layer->flags & 0x2) continue; } param.area = Rect16(0 - layer->area.left, 0 - layer->area.top, -1 - layer->area.left + resolution::screen_width, -1 - layer->area.top + resolution::screen_height); param.w = resolution::screen_width; param.h = resolution::screen_height; (*layer->Draw)(0, 0, layer->func_param, ¶m); layer->flags &= ~0x7; } } if (*bw::trans_list && *bw::game_screen_redraw_trans) { // Ew... bw::STransBind(*bw::game_screen_redraw_trans); bw::STrans437(*bw::trans_list, &bw::screen_redraw_tiles[0], 3, &*bw::game_screen_redraw_trans); bw::CopyGameScreenToFramebuf(); std::fill(bw::screen_redraw_tiles.begin(), bw::screen_redraw_tiles.end(), 0); } memcpy(fake_screenbuf_2, fake_screenbuf, resolution::screen_width * resolution::screen_height); for (drawhook &hook : draw_hooks) { (*hook.func)(fake_screenbuf_2, resolution::screen_width, resolution::screen_height); } uint8_t *surface; int width; if ((*bw::SDrawLockSurface_Import)(0, 0, &surface, &width, 0)) { for (unsigned int i = 0; i < resolution::screen_height; i++) memcpy(surface + i * width, fake_screenbuf_2 + i * resolution::screen_width, resolution::screen_width); (*bw::SDrawUnlockSurface_Import)(0, surface, 0, 0); } // if (!*bw::no_draw && *bw::draw_layers[0].draw) // { // // } *bw::current_canvas = nullptr; auto time = clock.GetTime(); if (!*bw::is_paused && time > 12.0) { perf_log->Log("DrawScreen %f ms\n", time); perf_log->Indent(2); while (auto clock = StaticPerfClock::PopNext()) { perf_log->Log("%s: %d times, %f ms\n", clock->GetName(), clock->GetOldCount(), clock->GetOldTime()); } perf_log->Indent(-2); } }