wxwidgets: Hide dumper called "NULL"
[lsnes.git] / include / library / framebuffer.hpp
blob040a18f25264fbfc9ae51d3973284d6cf80e5177
1 #ifndef _library__framebuffer__hpp__included__
2 #define _library__framebuffer__hpp__included__
4 #include <stdexcept>
5 #include <functional>
6 #include <cstdlib>
7 #include <vector>
8 #include <map>
9 #include <set>
10 #include "framebuffer-pixfmt.hpp"
12 namespace framebuffer
14 template<bool X> struct elem {};
15 template<> struct elem<false> { typedef uint32_t t; };
16 template<> struct elem<true> { typedef uint64_t t; };
18 extern unsigned default_shift_r;
19 extern unsigned default_shift_g;
20 extern unsigned default_shift_b;
22 /**
23 * Pixel format auxillary palette.
25 template<bool X>
26 struct auxpalette
28 typedef typename elem<X>::t element_t;
29 uint8_t rshift; //Red shift.
30 uint8_t gshift; //Green shift.
31 uint8_t bshift; //Blue shift.
32 std::vector<element_t> pcache; //Palette cache.
35 /**
36 * Game framebuffer information.
38 struct info
40 /**
41 * Pixel format of framebuffer.
43 pixfmt* type;
44 /**
45 * The physical memory backing the framebuffer.
47 char* mem;
48 /**
49 * Physical width of framebuffer.
51 size_t physwidth;
52 /**
53 * Physical height of framebuffer.
55 size_t physheight;
56 /**
57 * Physical stride of framebuffer (in bytes).
59 size_t physstride;
60 /**
61 * Visible width of framebuffer.
63 size_t width;
64 /**
65 * Visible height of framebuffer.
67 size_t height;
68 /**
69 * Visible stride of framebuffer (in bytes).
71 size_t stride;
72 /**
73 * Visible X offset of framebuffer.
75 size_t offset_x;
76 /**
77 * Visible Y offset of framebuffer.
79 size_t offset_y;
82 template<bool X> struct framebuffer;
84 /**
85 * Raw framebuffer.
87 * This framebuffer is in system format, and can either be backed either by temporary buffer or memory buffer.
89 * Any copying only preserves the visible part.
91 struct raw
93 /**
94 * Create a new framebuffer backed by temporary buffer.
96 * The resulting framebuffer is read-only.
98 * Parameter info: The framebuffer info.
100 raw(const info& finfo) throw(std::bad_alloc);
102 * Create a new framebuffer backed by memory buffer.
104 * The resulting framebuffer can be written to.
106 raw() throw(std::bad_alloc);
108 * Copy a framebuffer.
110 * The resulting copy is writable.
112 * Parameter f: The framebuffer.
114 raw(const raw& f) throw(std::bad_alloc);
116 * Assign a framebuffer.
118 * Parameter f: The framebuffer.
119 * Throws std::runtime_error: The target framebuffer is not writable.
121 raw& operator=(const raw& f) throw(std::bad_alloc, std::runtime_error);
123 * Load contents of framebuffer.
125 * parameter data: The data to load.
126 * throws std::runtime_error: The target framebuffer is not writable.
128 void load(const std::vector<char>& data) throw(std::bad_alloc, std::runtime_error);
130 * Save contents of framebuffer.
132 * parameter data: The vector to write the data to (in format compatible with load()).
134 void save(std::vector<char>& data) throw(std::bad_alloc);
136 * Save contents of framebuffer as a PNG.
138 * parameter file: The filename to save to.
139 * throws std::runtime_error: Can't save the PNG.
141 void save_png(const std::string& file) throw(std::bad_alloc, std::runtime_error);
143 * Get width.
145 * Returns: The width.
147 size_t get_width() const throw();
149 * Get height.
151 * Returns: The height.
153 size_t get_height() const throw();
155 * Get stride.
157 size_t get_stride() const throw();
159 * Get starting address.
161 unsigned char* get_start() const throw();
163 * Get pixel format.
165 pixfmt* get_format() const throw();
167 * Destructor.
169 ~raw();
170 private:
171 bool user_memory; //True if allocated in user memory, false if aliases framebuffer.
172 char* addr; //Address of framebuffer start.
173 pixfmt* fmt; //Format of framebuffer.
174 size_t width; //Width of framebuffer.
175 size_t height; //Height of framebuffer.
176 size_t stride; //Stride in pixels.
177 size_t allocated; //Amount of memory allocated (only meaningful if user_memory=true).
178 template<bool X> friend class fb;
182 struct color;
185 * Rendered framebuffer.
187 * This framebuffer is in RGB32/RGB64 format, and is always backed by memory buffer.
189 template<bool X>
190 struct fb
192 typedef typename elem<X>::t element_t;
194 * Creates framebuffer. The framebuffer dimensions are initially 0x0.
196 fb() throw();
199 * Destructor.
201 ~fb() throw();
204 * Sets the backing memory for framebuffer. The specified memory is not freed if framebuffer is reallocated or
205 * destroyed.
207 * parameter _memory: The memory buffer.
208 * parameter _width: Width of framebuffer.
209 * parameter _height: Height of framebuffer.
210 * parameter _pitch: Distance in bytes between successive scanlines (in pixels).
212 * Note: The _pitch should be multiple of 4, and _memory aligned to 16 bytes.
214 void set(element_t* _memory, size_t _width, size_t _height, size_t _pitch) throw();
217 * Sets the size of the framebuffer. The memory is freed if framebuffer is reallocated or destroyed.
219 * The pitch of resulting framebuffer is the smallest possible.
221 * parameter _width: Width of framebuffer.
222 * parameter _height: Height of framebuffer.
223 * parameter upside_down: If true, image is upside down in memory.
224 * throws std::bad_alloc: Not enough memory.
226 void reallocate(size_t _width, size_t _height, bool upside_down = false) throw(std::bad_alloc);
229 * Set origin
231 * parameter _originx: X coordinate for origin.
232 * parameter _originy: Y coordinate for origin.
234 void set_origin(size_t _originx, size_t _originy) throw();
236 * Get X origin.
238 * Returns: The X origin.
240 size_t get_origin_x() const throw();
242 * Get Y origin.
244 * Returns: The Y origin.
246 size_t get_origin_y() const throw();
248 * Paints raw framebuffer into framebuffer. The upper-left of image will be at origin. Scales the image by given
249 * factors. If the image does not fit with specified scale factors, it is clipped.
251 * parameter scr The framebuffer to paint.
252 * parameter hscale Horizontal scale factor.
253 * parameter vscale Vertical scale factor.
255 void copy_from(raw& scr, size_t hscale, size_t vscale) throw();
258 * Get pointer into specified row.
260 * parameter row: Number of row (must be less than height).
261 * Returns: Pointer into row data.
263 element_t* rowptr(size_t row) throw();
265 * Get pointer into specified row.
267 * parameter row: Number of row (must be less than height).
268 * Returns: Pointer into row data.
270 const element_t* rowptr(size_t row) const throw();
272 * Set palette. Also converts the image data.
274 * parameter r Shift for red component
275 * parameter g Shift for green component
276 * parameter b Shift for blue component
278 void set_palette(uint32_t r, uint32_t g, uint32_t b) throw(std::bad_alloc);
280 * Get stride of image.
282 * Returns: The stride.
284 size_t get_stride() const throw() { return stride; }
286 * Get width of image.
288 * Returns: The width.
290 size_t get_width() const throw() { return width; }
292 * Get height of image.
294 * Returns: The height.
296 size_t get_height() const throw() { return height; }
298 * Get last blit width
300 * Returns: The width.
302 size_t get_last_blit_width() const throw() { return last_blit_w; }
304 * Get last blit height
306 * Returns: The height.
308 size_t get_last_blit_height() const throw() { return last_blit_h; }
310 * Get R palette offset.
312 uint8_t get_palette_r() const throw();
314 * Get G palette offset.
316 uint8_t get_palette_g() const throw();
318 * Get B palette offset.
320 uint8_t get_palette_b() const throw();
321 private:
322 fb(const fb& f);
323 fb& operator=(const fb& f);
324 size_t width; //Width of framebuffer.
325 size_t height; //Height of framebuffer.
326 size_t stride; //Stride in pixels.
327 size_t offset_x; //X offset.
328 size_t offset_y; //Y offset.
329 size_t last_blit_w; //Width of last blit.
330 size_t last_blit_h; //Height of last blit.
331 element_t* mem; //The memory of framebuffer.
332 pixfmt* current_fmt; //Current format of framebuffer.
333 auxpalette<X> auxpal; //Aux palette.
334 bool user_mem; //True if internal memory is used.
335 bool upside_down; //Upside down flag.
336 uint8_t active_rshift; //Red shift.
337 uint8_t active_gshift; //Green shift.
338 uint8_t active_bshift; //Blue shift.
339 friend struct color;
342 struct queue;
345 * Base class for objects to render.
347 struct object
350 * Constructor.
352 object() throw();
354 * Destructor.
356 virtual ~object() throw();
358 * Kill object function. If it returns true, kill the request. Default is to return false.
360 virtual bool kill_request(void* obj) throw();
362 * Return true if myobj and killobj are equal and not NULL.
364 bool kill_request_ifeq(void* myobj, void* killobj);
366 * Draw the object.
368 * parameter scr: The screen to draw it on.
370 virtual void operator()(struct fb<false>& scr) throw() = 0;
371 virtual void operator()(struct fb<true>& scr) throw() = 0;
373 * Clone the object.
375 virtual void clone(struct queue& q) const throw(std::bad_alloc) = 0;
379 * Premultiplied color.
381 struct color
383 uint32_t hi;
384 uint32_t lo;
385 uint64_t hiHI;
386 uint64_t loHI;
387 uint32_t orig;
388 uint16_t origa;
389 uint16_t inv;
390 uint32_t invHI;
392 operator bool() const throw() { return (origa != 0); }
393 bool operator!() const throw() { return (origa == 0); }
395 color() throw()
397 hi = lo = 0;
398 hiHI = loHI = 0;
399 orig = 0;
400 origa = 0;
401 inv = 256;
402 invHI = 65536;
405 color(int64_t color) throw()
407 if(color < 0) {
408 //Transparent.
409 orig = 0;
410 origa = 0;
411 inv = 256;
412 } else {
413 orig = color & 0xFFFFFF;
414 origa = 256 - ((color >> 24) & 0xFF);;
415 inv = 256 - origa;
417 invHI = 256 * static_cast<uint32_t>(inv);
418 set_palette(default_shift_r, default_shift_g, default_shift_b, false);
419 set_palette(default_shift_r << 1, default_shift_g << 1, default_shift_b << 1, true);
420 //std::cerr << "Color " << color << " -> hi=" << hi << " lo=" << lo << " inv=" << inv << std::endl;
422 color(const std::string& color) throw(std::bad_alloc, std::runtime_error);
423 static std::string stringify(int64_t number);
424 void set_palette(unsigned rshift, unsigned gshift, unsigned bshift, bool X) throw();
425 template<bool X> void set_palette(struct fb<X>& s) throw()
427 set_palette(s.active_rshift, s.active_gshift, s.active_bshift, X);
429 uint32_t blend(uint32_t color) throw()
431 uint32_t a, b;
432 a = color & 0xFF00FF;
433 b = (color & 0xFF00FF00) >> 8;
434 return (((a * inv + hi) >> 8) & 0xFF00FF) | ((b * inv + lo) & 0xFF00FF00);
436 void apply(uint32_t& x) throw()
438 x = blend(x);
440 uint64_t blend(uint64_t color) throw()
442 uint64_t a, b;
443 a = color & 0xFFFF0000FFFFULL;
444 b = (color & 0xFFFF0000FFFF0000ULL) >> 16;
445 return (((a * invHI + hiHI) >> 16) & 0xFFFF0000FFFFULL) | ((b * invHI + loHI) &
446 0xFFFF0000FFFF0000ULL);
448 void apply(uint64_t& x) throw()
450 x = blend(x);
452 int64_t asnumber() const throw()
454 if(!origa)
455 return -1;
456 else
457 return orig | ((uint32_t)(256 - origa) << 24);
461 int64_t color_rotate_hue(int64_t color, int count, int steps);
462 int64_t color_adjust_saturation(int64_t color, double adjust);
463 int64_t color_adjust_lightness(int64_t color, double adjust);
466 * Base color name.
468 struct basecolor
470 basecolor(const std::string& name, int64_t value);
474 * Color modifier.
476 struct color_mod
478 color_mod(const std::string& name, std::function<void(int64_t&)> fn);
482 * Bitmap font (8x16).
484 struct font
487 * Bitmap font glyph.
489 struct glyph
491 bool wide; //If set, 16 wide instead of 8.
492 uint32_t* data; //Glyph data. Bitpacked with element padding between rows.
493 size_t offset; //Glyph offset.
497 * Bitmap font layout.
499 struct layout
501 size_t x; //X position.
502 size_t y; //Y position.
503 const glyph* dglyph; //The glyph itself.
506 * Constructor.
508 font() throw(std::bad_alloc);
510 * Load a .hex format font.
512 * Parameter data: The font data.
513 * Parameter size: The font data size in bytes.
514 * Throws std::runtime_error: Bad font data.
516 void load_hex(const char* data, size_t size) throw(std::bad_alloc, std::runtime_error);
518 * Locate glyph.
520 * Parameter glyph: Number of glyph to locate.
521 * Returns: Glyph parameters.
523 const glyph& get_glyph(uint32_t glyph) throw();
525 * Get metrics of string.
527 * Parameter string: The string to get metrics of.
528 * Returns: A pair. First element is width of string, the second is height of string.
530 std::pair<size_t, size_t> get_metrics(const std::string& string) throw();
532 * Layout a string.
534 * Parameter string: The string to get layout of.
535 * Returns: String layout.
537 std::vector<layout> dolayout(const std::string& string) throw(std::bad_alloc);
539 * Get set of all glyph numbers.
541 std::set<uint32_t> get_glyphs_set();
543 * Get bad glyph.
545 const glyph& get_bad_glyph() throw();
547 * Render string to framebuffer.
549 * Parameter framebuffer: The framebuffer to render on.
550 * Parameter x: The x-coordinate to start from.
551 * Parameter y: The y-coordinate to start from.
552 * Parameter text: The text to render.
553 * Parameter fg: The foreground color.
554 * Parameter bg: The background color.
555 * Parameter hdbl: If set, double width horizontally.
556 * Parameter vdbl: If set, double height vertically.
558 template<bool X> void render(struct fb<X>& scr, int32_t x, int32_t y, const std::string& text,
559 color fg, color bg, bool hdbl, bool vdbl) throw();
560 private:
561 glyph bad_glyph;
562 uint32_t bad_glyph_data[4];
563 std::map<uint32_t, glyph> glyphs;
564 size_t tabstop;
565 std::vector<uint32_t> memory;
566 void load_hex_glyph(const char* data, size_t size) throw(std::bad_alloc, std::runtime_error);
570 #define RENDER_PAGE_SIZE 65500
573 * Queue of render operations.
575 struct queue
578 * Applies all objects in the queue in order.
580 * parameter scr: The screen to apply queue to.
582 template<bool X> void run(struct fb<X>& scr) throw();
585 * Frees all objects in the queue without applying them.
587 void clear() throw();
589 * Call kill_request on all objects in queue.
591 void kill_request(void* obj) throw();
593 * Get memory from internal allocator.
595 void* alloc(size_t block) throw(std::bad_alloc);
598 * Call object constructor on internal memory.
600 template<class T, typename... U> void create_add(U... args)
602 add(*new(alloc(sizeof(T))) T(args...));
605 * Copy objects from another render queue.
607 void copy_from(queue& q) throw(std::bad_alloc);
609 * Helper for clone.
611 template<typename T> void clone_helper(const T* obj)
613 create_add<T>(*obj);
616 * Get number of objects.
618 size_t get_object_count()
620 size_t c = 0;
621 struct node* n = queue_head;
622 while(n != NULL) {
623 n = n->next;
624 c++;
626 return c;
629 * Constructor.
631 queue() throw();
633 * Destructor.
635 ~queue() throw();
636 private:
637 void add(struct object& obj) throw(std::bad_alloc);
638 struct node { struct object* obj; struct node* next; bool killed; };
639 struct page { char content[RENDER_PAGE_SIZE]; };
640 struct node* queue_head;
641 struct node* queue_tail;
642 size_t memory_allocated;
643 size_t pages;
644 std::map<size_t, page> memory;
648 * Drop every fourth byte of specified buffer.
650 * Parameter dest: Destination buffer, should be 16-byte aligned.
651 * Parameter src: Source buffer, should be 16-byte aligned.
652 * Parameter units: Number of 4 byte units to copy. Must be multiple of 4.
654 void copy_drop4(uint8_t* dest, const uint32_t* src, size_t units);
657 * Drop every fourth byte of specified buffer and swap first and third.
659 * Parameter dest: Destination buffer, should be 16-byte aligned.
660 * Parameter src: Source buffer, should be 16-byte aligned.
661 * Parameter units: Number of 4 byte units to copy. Must be multiple of 4.
663 void copy_drop4s(uint8_t* dest, const uint32_t* src, size_t units);
666 * Swap every first and third byte out of four
668 * Parameter dest: Destination buffer, should be 16-byte aligned.
669 * Parameter src: Source buffer, should be 16-byte aligned.
670 * Parameter units: Number of 4 byte units to copy. Must be multiple of 4.
672 void copy_swap4(uint8_t* dest, const uint32_t* src, size_t units);
675 * Drop every fourth word of specified buffer.
677 * Parameter dest: Destination buffer, should be 16-byte aligned.
678 * Parameter src: Source buffer, should be 16-byte aligned.
679 * Parameter units: Number of 8 byte units to copy. Must be multiple of 2.
681 void copy_drop4(uint16_t* dest, const uint64_t* src, size_t units);
684 * Drop every fourth byte of specified buffer and swap first and third.
686 * Parameter dest: Destination buffer, should be 16-byte aligned.
687 * Parameter src: Source buffer, should be 16-byte aligned.
688 * Parameter units: Number of 8 byte units to copy. Must be multiple of 2.
690 void copy_drop4s(uint16_t* dest, const uint64_t* src, size_t units);
693 * Swap every first and third byte out of four
695 * Parameter dest: Destination buffer, should be 16-byte aligned.
696 * Parameter src: Source buffer, should be 16-byte aligned.
697 * Parameter units: Number of 8 byte units to copy. Must be multiple of 2.
699 void copy_swap4(uint16_t* dest, const uint64_t* src, size_t units);
703 #endif