//------------------------------------------------- // get_scaled_bitmap_and_bounds - return a // scaled bitmap and bounding rect for a char //------------------------------------------------- public void get_scaled_bitmap_and_bounds(bitmap_argb32 dest, float height, float aspect, char32_t chnum, out rectangle bounds) { bounds = default; glyph gl = get_char(chnum); // on entry, assume x0,y0 are the top,left coordinate of the cell and add // the character bounding box to that position float scale = m_scale * height; bounds.min_x = (int)((float)(gl.xoffs) * scale * aspect); bounds.min_y = 0; // compute x1,y1 from there based on the bitmap size bounds.set_width((int)((float)(gl.bmwidth) * scale * aspect)); bounds.set_height((int)((float)(m_height) * scale)); // if the bitmap isn't big enough, bail if (dest.width() < bounds.width() || dest.height() < bounds.height()) { return; } // if no texture, fill the target if (gl.texture == null) { dest.fill(0); return; } throw new emu_unimplemented(); #if false // scale the font bitmap_argb32 tempbitmap = new bitmap_argb32(&dest.pix(0), bounds.width(), bounds.height(), dest.rowpixels()); render_texture.hq_scale(tempbitmap, gl.bitmap, gl.bitmap.cliprect(), null); #endif }
} //void set_config(const atari_motion_objects_config &config) { static_cast<atari_motion_objects_config &>(*this) = config; } //void set_xoffset(int xoffset) { m_xoffset = xoffset; } // getters //int bank() const { return m_bank; } //int xscroll() const { return m_xscroll; } //int yscroll() const { return m_yscroll; } //std::vector<uint32_t> &code_lookup() { return m_codelookup; } //std::vector<uint8_t> &color_lookup() { return m_colorlookup; } //std::vector<uint8_t> &gfx_lookup() { return m_gfxlookup; } // setters //void set_bank(int bank) { m_bank = bank; } //void set_xscroll(int xscroll) { m_xscroll = xscroll & m_bitmapxmask; } //void set_yscroll(int yscroll) { m_yscroll = yscroll & m_bitmapymask; } //void set_scroll(int xscroll, int yscroll) { set_xscroll(xscroll); set_yscroll(yscroll); } //void set_slipram(uint16_t *ram) { m_slipram = ram; } // rendering //------------------------------------------------- // draw: Render the motion objects to the // destination bitmap. //------------------------------------------------- protected override void draw(bitmap_ind16 bitmap, rectangle cliprect) { // compute start/stop bands int startband = ((cliprect.top() + (int)m_yscroll - m_atari_motion_objects_config.m_slipoffset) & m_bitmapymask) >> m_slipshift; int stopband = ((cliprect.bottom() + (int)m_yscroll - m_atari_motion_objects_config.m_slipoffset) & m_bitmapymask) >> m_slipshift; if (startband > stopband) { startband -= m_bitmapheight >> m_slipshift; } if (m_slipshift == 0) { stopband = startband; } // loop over SLIP bands for (int band = startband; band <= stopband; band++) { // compute the starting link and clip for the current band rectangle bandclip = cliprect; int link = 0; if (m_slipshift != 0) { // extract the link from the SLIP RAM link = (m_slipram[band & m_sliprammask] >> m_linkmask.shift()) & m_linkmask.mask(); // compute minimum Y and wrap around if necessary bandclip.min_y = ((band << m_slipshift) - (int)m_yscroll + m_atari_motion_objects_config.m_slipoffset) & m_bitmapymask; if (bandclip.min_y >= bitmap.height()) { bandclip.min_y -= m_bitmapheight; } // maximum Y is based on the minimum bandclip.set_height(1 << m_slipshift); // keep within the cliprect bandclip &= cliprect; } // if this matches the last link, we don't need to re-process the list build_active_list(link); // initialize the parameters m_next_xpos = 123456; // safety check if (m_activelist == m_activelast.Buffer && m_activelast.Offset == 0) //if (m_activelist == m_activelast) { continue; } // set the start and end points Pointer <uint16_t> first; //uint16_t *first, *last; Pointer <uint16_t> last; int step; if (m_atari_motion_objects_config.m_reverse) { first = m_activelast - 4; last = new Pointer <uint16_t>(m_activelist); step = -4; } else { first = new Pointer <uint16_t>(m_activelist); last = m_activelast - 4; step = 4; } // render the mos for (Pointer <uint16_t> current = new Pointer <uint16_t>(first); ; current += step) //for (uint16_t *current = first; ; current += step) { render_object(bitmap, bandclip, current); if (current.Buffer == last.Buffer && current.Offset == last.Offset) //if (current == last) { break; } } } }