Lua: Add gui.textH, gui.textV, gui.textHV
[lsnes.git] / include / core / render.hpp
blob2c1600f9ab17109ec3e931598646e1159c2a08e5
1 #ifndef _render__hpp__included__
2 #define _render__hpp__included__
5 #include <cstdint>
6 #include <string>
7 #include <list>
8 #include <vector>
9 #include <stdexcept>
10 #include <iostream>
12 /**
13 * Low color (32768 colors) screen from buffer.
15 struct lcscreen
17 /**
18 * Create new screen from bsnes output data.
20 * parameter mem The output buffer from bsnes.
21 * parameter hires True if in hires mode (512-wide lines instead of 256-wide).
22 * parameter interlace True if in interlace mode.
23 * parameter overscan True if overscan is enabled.
24 * parameter region True if PAL, false if NTSC.
26 lcscreen(const uint32_t* mem, bool hires, bool interlace, bool overscan, bool region) throw();
28 /**
29 * Create new memory-backed screen. The resulting screen can be written to.
31 lcscreen() throw();
32 /**
33 * Create new screen with specified contents and size.
35 * parameter mem: Memory to use as frame data. 1 element per pixel. Left-to-Right, top-to-bottom order.
36 * parameter _width: Width of the screen to create.
37 * parameter _height: Height of the screen to create.
39 lcscreen(const uint32_t* mem, uint32_t _width, uint32_t _height) throw();
40 /**
41 * Copy the screen.
43 * The assigned copy is always writable.
45 * parameter ls: The source screen.
46 * throws std::bad_alloc: Not enough memory.
48 lcscreen(const lcscreen& ls) throw(std::bad_alloc);
49 /**
50 * Assign the screen.
52 * parameter ls: The source screen.
53 * returns: Reference to target screen.
54 * throws std::bad_alloc: Not enough memory.
55 * throws std::runtime_error: The target screen is not writable.
57 lcscreen& operator=(const lcscreen& ls) throw(std::bad_alloc, std::runtime_error);
58 /**
59 * Load contents of screen.
61 * parameter data: The data to load.
62 * throws std::bad_alloc: Not enough memory.
63 * throws std::runtime_error: The target screen is not writable.
65 void load(const std::vector<char>& data) throw(std::bad_alloc, std::runtime_error);
66 /**
67 * Save contents of screen.
69 * parameter data: The vector to write the data to (in format compatible with load()).
70 * throws std::bad_alloc: Not enough memory.
72 void save(std::vector<char>& data) throw(std::bad_alloc);
73 /**
74 * Save contents of screen as a PNG.
76 * parameter file: The filename to save to.
77 * throws std::bad_alloc: Not enough memory.
78 * throws std::runtime_error: Can't save the PNG.
80 void save_png(const std::string& file) throw(std::bad_alloc, std::runtime_error);
82 /**
83 * Destructor.
85 ~lcscreen();
87 /**
88 * True if memory is allocated by new[] and should be freed by the destructor., false otherwise. Also signals
89 * writablity.
91 bool user_memory;
93 /**
94 * Memory, 1 element per pixel in left-to-right, top-to-bottom order, 15 low bits of each element used.
96 const uint32_t* memory;
98 /**
99 * Number of elements (not bytes) between two successive scanlines.
101 uint32_t pitch;
104 * Width of image.
106 uint32_t width;
109 * Height of image.
111 uint32_t height;
114 * Image allocated size (only valid for user_memory=true).
116 size_t allocated;
120 * Hicolor modifiable screen.
122 struct screen
125 * Creates screen. The screen dimensions are initially 0x0.
127 screen() throw();
130 * Destructor.
132 ~screen() throw();
135 * Sets the backing memory for screen. The specified memory is not freed if screen is reallocated or destroyed.
137 * parameter _memory: The memory buffer.
138 * parameter _width: Width of screen.
139 * parameter _height: Height of screen.
140 * parameter _pitch: Distance in bytes between successive scanlines.
142 void set(uint32_t* _memory, uint32_t _width, uint32_t _height, uint32_t _pitch) throw();
145 * Sets the size of the screen. The memory is freed if screen is reallocated or destroyed.
147 * parameter _width: Width of screen.
148 * parameter _height: Height of screen.
149 * parameter upside_down: If true, image is upside down in memory.
150 * throws std::bad_alloc: Not enough memory.
152 void reallocate(uint32_t _width, uint32_t _height, bool upside_down = false) throw(std::bad_alloc);
155 * Set origin
157 * parameter _originx: X coordinate for origin.
158 * parameter _originy: Y coordinate for origin.
160 void set_origin(uint32_t _originx, uint32_t _originy) throw();
163 * Paints low-color screen into screen. The upper-left of image will be at origin. Scales the image by given factors.
164 * If the image does not fit with specified scale factors, it is clipped.
166 * parameter scr The screen to paint.
167 * parameter hscale Horizontal scale factor.
168 * parameter vscale Vertical scale factor.
170 void copy_from(lcscreen& scr, uint32_t hscale, uint32_t vscale) throw();
173 * Get pointer into specified row.
175 * parameter row: Number of row (must be less than height).
177 uint32_t* rowptr(uint32_t row) throw();
180 * Set palette. Also converts the image data.
182 * parameter r Shift for red component
183 * parameter g Shift for green component
184 * parameter b Shift for blue component
186 void set_palette(uint32_t r, uint32_t g, uint32_t b);
189 * Active palette
191 uint32_t* palette;
192 uint32_t palette_r;
193 uint32_t palette_g;
194 uint32_t palette_b;
197 * Backing memory for this screen.
199 uint32_t* memory;
202 * True if memory is given by user and must not be freed.
204 bool user_memory;
207 * Width of screen.
209 uint32_t width;
212 * Height of screen.
214 uint32_t height;
217 * Distance between lines in bytes.
219 size_t pitch;
222 * True if image is upside down in memory.
224 bool flipped;
227 * X-coordinate of origin.
229 uint32_t originx;
232 * Y-coordinate of origin.
234 uint32_t originy;
237 * Returns color value with specified (r,g,b) values (scale 0-255).
239 * parameter r: Red component.
240 * parameter g: Green component.
241 * parameter b: Blue component.
242 * returns: color element value.
244 uint32_t make_color(uint8_t r, uint8_t g, uint8_t b) throw();
245 private:
246 screen(const screen&);
247 screen& operator=(const screen&);
251 * Base class for objects to render.
253 struct render_object
256 * Destructor.
258 virtual ~render_object() throw();
261 * Draw the object.
263 * parameter scr: The screen to draw it on.
265 virtual void operator()(struct screen& scr) throw() = 0;
271 * Premultiplied color.
273 struct premultiplied_color
275 uint32_t hi;
276 uint32_t lo;
277 uint16_t inv;
278 premultiplied_color(int64_t color) throw()
280 if(color < 0) {
281 //Transparent.
282 hi = 0;
283 lo = 0;
284 inv = 256;
285 } else {
286 uint32_t c = (color & 0xFFFFFF);
287 uint16_t a = 256 - ((color >> 24) & 0xFF);
288 hi = c & 0xFF00FF;
289 lo = c & 0x00FF00;
290 hi *= a;
291 lo *= a;
292 inv = 256 - a;
294 //std::cerr << "Color " << color << " -> hi=" << hi << " lo=" << lo << " inv=" << inv << std::endl;
296 uint32_t blend(uint32_t color) throw()
298 uint32_t a, b;
299 a = color & 0xFF00FF;
300 b = color & 0x00FF00;
301 return (((a * inv + hi) >> 8) & 0xFF00FF) | (((b * inv + lo) >> 8) & 0x00FF00);
303 void apply(uint32_t& x) throw()
305 x = blend(x);
310 * Queue of render operations.
312 struct render_queue
315 * Adds new object to render queue. The object must be allocated by new.
317 * parameter obj: The object to add
318 * throws std::bad_alloc: Not enough memory.
320 void add(struct render_object& obj) throw(std::bad_alloc);
323 * Applies all objects in the queue in order, freeing them in progress.
325 * parameter scr: The screen to apply queue to.
327 void run(struct screen& scr) throw();
330 * Frees all objects in the queue without applying them.
332 void clear() throw();
335 * Destructor.
337 ~render_queue() throw();
338 private:
339 std::list<struct render_object*> q;
344 * Clip range inside another.
346 * parameter origin: Origin coordinate.
347 * parameter size: Dimension size.
348 * parameter base: Base coordinate.
349 * parameter minc: Minimum coordinate relative to base. Updated.
350 * parameter maxc: Maximum coordinate relative to base. Updated.
352 void clip_range(uint32_t origin, uint32_t size, int32_t base, int32_t& minc, int32_t& maxc) throw();
355 * Initialize font data.
357 void do_init_font();
360 * Read font data for glyph.
362 * parameter codepoint: Code point of glyph.
363 * parameter x: X position to render into.
364 * parameter y: Y position to render into.
365 * parameter orig_x: X position at start of row.
366 * parameter next_x: X position for next glyph is written here.
367 * parameter next_y: Y position for next glyph is written here.
368 * returns: Two components: First is width of character, second is pointer to font data (NULL if blank glyph).
370 std::pair<uint32_t, const uint32_t*> find_glyph(uint32_t codepoint, int32_t x, int32_t y, int32_t orig_x,
371 int32_t& next_x, int32_t& next_y, bool hdbl = false, bool vdbl = false) throw();
374 * Render text into screen.
376 * parameter _x: The x position to render to (relative to origin).
377 * parameter _y: The y position to render to (relative to origin).
378 * parameter _text: The text to render (UTF-8).
379 * parameter _fg: Foreground color.
380 * parameter _bg: Background color.
381 * parameter _hdbl: If true, draw text using double width.
382 * parameter _vdbl: If true, draw text using double height.
383 * throws std::bad_alloc: Not enough memory.
385 void render_text(struct screen& scr, int32_t _x, int32_t _y, const std::string& _text, premultiplied_color _fg,
386 premultiplied_color _bg, bool _hdbl = false, bool _vdbl = false) throw(std::bad_alloc);
388 #endif