1 #ifndef _library__framebuffer__hpp__included__
2 #define _library__framebuffer__hpp__included__
9 template<bool X
> struct framebufferelem
{};
10 template<> struct framebufferelem
<false> { typedef uint32_t t
; };
11 template<> struct framebufferelem
<true> { typedef uint64_t t
; };
14 * Pixel format auxillary palette.
17 struct pixel_format_aux_palette
19 typedef typename framebufferelem
<X
>::t element_t
;
20 uint8_t rshift
; //Red shift.
21 uint8_t gshift
; //Green shift.
22 uint8_t bshift
; //Blue shift.
23 std::vector
<element_t
> pcache
; //Palette cache.
32 virtual ~pixel_format() throw();
34 * Register the pixel format.
36 pixel_format() throw(std::bad_alloc
);
38 * Decode pixel format data into RGB24 data (R, G, B).
40 virtual void decode(uint8_t* target
, const uint8_t* src
, size_t width
)
43 * Decode pixel format data into RGB (with specified byte order).
45 virtual void decode(uint32_t* target
, const uint8_t* src
, size_t width
,
46 const pixel_format_aux_palette
<false>& auxp
) throw() = 0;
48 * Decode pixel format data into RGB (with specified byte order).
50 virtual void decode(uint64_t* target
, const uint8_t* src
, size_t width
,
51 const pixel_format_aux_palette
<true>& auxp
) throw() = 0;
55 virtual void set_palette(pixel_format_aux_palette
<false>& auxp
, uint8_t rshift
, uint8_t gshift
,
56 uint8_t bshift
) throw(std::bad_alloc
) = 0;
60 virtual void set_palette(pixel_format_aux_palette
<true>& auxp
, uint8_t rshift
, uint8_t gshift
,
61 uint8_t bshift
) throw(std::bad_alloc
) = 0;
63 * Bytes per pixel in data.
65 virtual uint8_t get_bpp() throw() = 0;
67 * Bytes per pixel in ss data.
69 virtual uint8_t get_ss_bpp() throw() = 0;
71 * Screenshot magic (0 for the old format).
73 virtual uint32_t get_magic() throw() = 0;
77 * Game framebuffer information.
79 struct framebuffer_info
82 * Pixel format of framebuffer.
86 * The physical memory backing the framebuffer.
90 * Physical width of framebuffer.
94 * Physical height of framebuffer.
98 * Physical stride of framebuffer (in bytes).
102 * Visible width of framebuffer.
106 * Visible height of framebuffer.
110 * Visible stride of framebuffer (in bytes).
114 * Visible X offset of framebuffer.
118 * Visible Y offset of framebuffer.
123 template<bool X
> struct framebuffer
;
128 * This framebuffer is in system format, and can either be backed either by temporary buffer or memory buffer.
130 * Any copying only preserves the visible part.
132 struct framebuffer_raw
135 * Create a new framebuffer backed by temporary buffer.
137 * The resulting framebuffer is read-only.
139 * Parameter info: The framebuffer info.
141 framebuffer_raw(const framebuffer_info
& info
) throw(std::bad_alloc
);
143 * Create a new framebuffer backed by memory buffer.
145 * The resulting framebuffer can be written to.
147 framebuffer_raw() throw(std::bad_alloc
);
149 * Copy a framebuffer.
151 * The resulting copy is writable.
153 * Parameter f: The framebuffer.
155 framebuffer_raw(const framebuffer_raw
& f
) throw(std::bad_alloc
);
157 * Assign a framebuffer.
159 * Parameter f: The framebuffer.
160 * Throws std::runtime_error: The target framebuffer is not writable.
162 framebuffer_raw
& operator=(const framebuffer_raw
& f
) throw(std::bad_alloc
, std::runtime_error
);
164 * Load contents of framebuffer.
166 * parameter data: The data to load.
167 * throws std::runtime_error: The target framebuffer is not writable.
169 void load(const std::vector
<char>& data
) throw(std::bad_alloc
, std::runtime_error
);
171 * Save contents of framebuffer.
173 * parameter data: The vector to write the data to (in format compatible with load()).
175 void save(std::vector
<char>& data
) throw(std::bad_alloc
);
177 * Save contents of framebuffer as a PNG.
179 * parameter file: The filename to save to.
180 * throws std::runtime_error: Can't save the PNG.
182 void save_png(const std::string
& file
) throw(std::bad_alloc
, std::runtime_error
);
186 * Returns: The width.
188 size_t get_width() const throw();
192 * Returns: The height.
194 size_t get_height() const throw();
200 bool user_memory
; //True if allocated in user memory, false if aliases framebuffer.
201 char* addr
; //Address of framebuffer start.
202 pixel_format
* fmt
; //Format of framebuffer.
203 size_t width
; //Width of framebuffer.
204 size_t height
; //Height of framebuffer.
205 size_t stride
; //Stride in pixels.
206 size_t allocated
; //Amount of memory allocated (only meaningful if user_memory=true).
207 template<bool X
> friend class framebuffer
;
211 struct premultiplied_color
;
214 * Rendered framebuffer.
216 * This framebuffer is in RGB32/RGB64 format, and is always backed by memory buffer.
221 typedef typename framebufferelem
<X
>::t element_t
;
223 * Creates framebuffer. The framebuffer dimensions are initially 0x0.
225 framebuffer() throw();
230 ~framebuffer() throw();
233 * Sets the backing memory for framebuffer. The specified memory is not freed if framebuffer is reallocated or
236 * parameter _memory: The memory buffer.
237 * parameter _width: Width of framebuffer.
238 * parameter _height: Height of framebuffer.
239 * parameter _pitch: Distance in bytes between successive scanlines (in pixels).
241 void set(element_t
* _memory
, size_t _width
, size_t _height
, size_t _pitch
) throw();
244 * Sets the size of the framebuffer. The memory is freed if framebuffer is reallocated or destroyed.
246 * The pitch of resulting framebuffer is the smallest possible.
248 * parameter _width: Width of framebuffer.
249 * parameter _height: Height of framebuffer.
250 * parameter upside_down: If true, image is upside down in memory.
251 * throws std::bad_alloc: Not enough memory.
253 void reallocate(size_t _width
, size_t _height
, bool upside_down
= false) throw(std::bad_alloc
);
258 * parameter _originx: X coordinate for origin.
259 * parameter _originy: Y coordinate for origin.
261 void set_origin(size_t _originx
, size_t _originy
) throw();
265 * Returns: The X origin.
267 size_t get_origin_x() const throw();
271 * Returns: The Y origin.
273 size_t get_origin_y() const throw();
275 * Paints raw framebuffer into framebuffer. The upper-left of image will be at origin. Scales the image by given
276 * factors. If the image does not fit with specified scale factors, it is clipped.
278 * parameter scr The framebuffer to paint.
279 * parameter hscale Horizontal scale factor.
280 * parameter vscale Vertical scale factor.
282 void copy_from(framebuffer_raw
& scr
, size_t hscale
, size_t vscale
) throw();
285 * Get pointer into specified row.
287 * parameter row: Number of row (must be less than height).
288 * Returns: Pointer into row data.
290 element_t
* rowptr(size_t row
) throw();
292 * Get pointer into specified row.
294 * parameter row: Number of row (must be less than height).
295 * Returns: Pointer into row data.
297 const element_t
* rowptr(size_t row
) const throw();
299 * Set palette. Also converts the image data.
301 * parameter r Shift for red component
302 * parameter g Shift for green component
303 * parameter b Shift for blue component
305 void set_palette(uint32_t r
, uint32_t g
, uint32_t b
) throw(std::bad_alloc
);
307 * Get width of image.
309 * Returns: The width.
311 size_t get_width() const throw();
313 * Get height of image.
315 * Returns: The height.
317 size_t get_height() const throw();
319 * Get R palette offset.
321 uint8_t get_palette_r() const throw();
323 * Get G palette offset.
325 uint8_t get_palette_g() const throw();
327 * Get B palette offset.
329 uint8_t get_palette_b() const throw();
331 framebuffer(const framebuffer
& f
);
332 framebuffer
& operator=(const framebuffer
& f
);
333 size_t width
; //Width of framebuffer.
334 size_t height
; //Height of framebuffer.
335 size_t stride
; //Stride in pixels.
336 size_t offset_x
; //X offset.
337 size_t offset_y
; //Y offset.
338 element_t
* mem
; //The memory of framebuffer.
339 pixel_format
* current_fmt
; //Current format of framebuffer.
340 pixel_format_aux_palette
<X
> auxpal
; //Aux palette.
341 bool user_mem
; //True if internal memory is used.
342 bool upside_down
; //Upside down flag.
343 uint8_t active_rshift
; //Red shift.
344 uint8_t active_gshift
; //Green shift.
345 uint8_t active_bshift
; //Blue shift.
346 friend struct premultiplied_color
;
350 * Base class for objects to render.
357 render_object() throw();
361 virtual ~render_object() throw();
363 * Kill object function. If it returns true, kill the request. Default is to return false.
365 virtual bool kill_request(void* obj
) throw();
367 * Return true if myobj and killobj are equal and not NULL.
369 bool kill_request_ifeq(void* myobj
, void* killobj
);
373 * parameter scr: The screen to draw it on.
375 virtual void operator()(struct framebuffer
<false>& scr
) throw() = 0;
376 virtual void operator()(struct framebuffer
<true>& scr
) throw() = 0;
382 * Premultiplied color.
384 struct premultiplied_color
395 operator bool() const throw() { return (origa
!= 0); }
396 bool operator!() const throw() { return (origa
== 0); }
398 premultiplied_color() throw()
408 premultiplied_color(int64_t color
) throw()
416 orig
= color
& 0xFFFFFF;
417 origa
= 256 - ((color
>> 24) & 0xFF);;
420 invHI
= 256 * static_cast<uint32_t>(inv
);
421 set_palette(16, 8, 0, false);
422 set_palette(32, 16, 0, true);
423 //std::cerr << "Color " << color << " -> hi=" << hi << " lo=" << lo << " inv=" << inv << std::endl;
425 void set_palette(unsigned rshift
, unsigned gshift
, unsigned bshift
, bool X
) throw();
426 template<bool X
> void set_palette(struct framebuffer
<X
>& s
) throw()
428 set_palette(s
.active_rshift
, s
.active_gshift
, s
.active_bshift
, X
);
430 uint32_t blend(uint32_t color
) throw()
433 a
= color
& 0xFF00FF;
434 b
= (color
& 0xFF00FF00) >> 8;
435 return (((a
* inv
+ hi
) >> 8) & 0xFF00FF) | ((b
* inv
+ lo
) & 0xFF00FF00);
437 void apply(uint32_t& x
) throw()
441 uint64_t blend(uint64_t color
) throw()
444 a
= color
& 0xFFFF0000FFFFULL
;
445 b
= (color
& 0xFFFF0000FFFF0000ULL
) >> 16;
446 return (((a
* invHI
+ hiHI
) >> 16) & 0xFFFF0000FFFFULL
) | ((b
* invHI
+ loHI
) & 0xFFFF0000FFFF0000ULL
);
448 void apply(uint64_t& x
) throw()
456 * Bitmap font (8x16).
465 bool wide
; //If set, 16 wide instead of 8.
466 uint32_t* data
; //Glyph data. Bitpacked with element padding between rows.
467 size_t offset
; //Glyph offset.
471 * Bitmap font layout.
475 size_t x
; //X position.
476 size_t y
; //Y position.
477 const glyph
* dglyph
; //The glyph itself.
482 bitmap_font() throw(std::bad_alloc
);
484 * Load a .hex format font.
486 * Parameter data: The font data.
487 * Parameter size: The font data size in bytes.
488 * Throws std::runtime_error: Bad font data.
490 void load_hex(const char* data
, size_t size
) throw(std::bad_alloc
, std::runtime_error
);
494 * Parameter glyph: Number of glyph to locate.
495 * Returns: Glyph parameters.
497 const glyph
& get_glyph(uint32_t glyph
) throw();
499 * Get metrics of string.
501 * Parameter string: The string to get metrics of.
502 * Returns: A pair. First element is width of string, the second is height of string.
504 std::pair
<size_t, size_t> get_metrics(const std::string
& string
) throw();
508 * Parameter string: The string to get layout of.
509 * Returns: String layout.
511 std::vector
<layout
> dolayout(const std::string
& string
) throw(std::bad_alloc
);
513 * Render string to framebuffer.
515 * Parameter framebuffer: The framebuffer to render on.
516 * Parameter x: The x-coordinate to start from.
517 * Parameter y: The y-coordinate to start from.
518 * Parameter text: The text to render.
519 * Parameter fg: The foreground color.
520 * Parameter bg: The background color.
521 * Parameter hdbl: If set, double width horizontally.
522 * Parameter vdbl: If set, double height vertically.
524 template<bool X
> void render(struct framebuffer
<X
>& scr
, int32_t x
, int32_t y
, const std::string
& text
,
525 premultiplied_color fg
, premultiplied_color bg
, bool hdbl
, bool vdbl
) throw();
528 uint32_t bad_glyph_data
[4];
529 std::map
<uint32_t, glyph
> glyphs
;
531 std::vector
<uint32_t> memory
;
532 void load_hex_glyph(const char* data
, size_t size
) throw(std::bad_alloc
, std::runtime_error
);
536 #define RENDER_PAGE_SIZE 65500
539 * Queue of render operations.
544 * Applies all objects in the queue in order.
546 * parameter scr: The screen to apply queue to.
548 template<bool X
> void run(struct framebuffer
<X
>& scr
) throw();
551 * Frees all objects in the queue without applying them.
553 void clear() throw();
555 * Call kill_request on all objects in queue.
557 void kill_request(void* obj
) throw();
559 * Get memory from internal allocator.
561 void* alloc(size_t block
) throw(std::bad_alloc
);
564 * Call object constructor on internal memory.
566 template<class T
, typename
... U
> void create_add(U
... args
)
568 add(*new(alloc(sizeof(T
))) T(args
...));
574 render_queue() throw();
578 ~render_queue() throw();
580 void add(struct render_object
& obj
) throw(std::bad_alloc
);
581 struct node
{ struct render_object
* obj
; struct node
* next
; bool killed
; };
582 struct page
{ char content
[RENDER_PAGE_SIZE
]; };
583 struct node
* queue_head
;
584 struct node
* queue_tail
;
585 size_t memory_allocated
;
587 std::map
<size_t, page
> memory
;
591 * Clip range inside another.
593 * parameter origin: Origin coordinate.
594 * parameter size: Dimension size.
595 * parameter base: Base coordinate.
596 * parameter minc: Minimum coordinate relative to base. Updated.
597 * parameter maxc: Maximum coordinate relative to base. Updated.
599 void clip_range(uint32_t origin
, uint32_t size
, int32_t base
, int32_t& minc
, int32_t& maxc
) throw();