| 1 | /* |
| 2 | gfx.h: a software canvas (1280x720, 0xAARRGGBB in native u32s) and what |
| 3 | the UI draws on it. The PS3 backend copies the finished canvas to the screen. |
| 4 | */ |
| 5 | #ifndef GFX_H |
| 6 | #define GFX_H |
| 7 |
|
| 8 | #include <stdint.h> |
| 9 |
|
| 10 | typedef struct { |
| 11 | int w, h; |
| 12 | uint32_t *px; // 0xAARRGGBB |
| 13 | int opaque; // every pixel's alpha is 255 (rows can be copied whole) |
| 14 | int rev; // bumped (image_touch) when px changes: the GPU's copy is made again |
| 15 | void *gpu; // the GPU's copy (gfx.c's) |
| 16 | } image_t; |
| 17 |
|
| 18 | void gfx_init(uint32_t *canvas, int w, int h); |
| 19 | uint32_t *gfx_canvas(void); |
| 20 |
|
| 21 | void gfx_clip(int x, int y, int w, int h); // later draws stay inside |
| 22 | void gfx_unclip(void); |
| 23 | void gfx_clip_get(int *x, int *y, int *w, int *h); |
| 24 |
|
| 25 | void gfx_clear(uint32_t argb); |
| 26 | void gfx_rect(int x, int y, int w, int h, uint32_t argb); // alpha-blended |
| 27 | void gfx_round_rect(int x, int y, int w, int h, int r, uint32_t argb); |
| 28 | void gfx_vgradient(int x, int y, int w, int h, uint32_t top, uint32_t bottom); |
| 29 | // opaque, with a fine grain so dark gradients don't band (cached, copied in rows) |
| 30 | void gfx_vgradient_noise(int x, int y, int w, int h, uint32_t top, uint32_t bottom); |
| 31 | void gfx_hgradient(int x, int y, int w, int h, uint32_t left, uint32_t right); |
| 32 | void gfx_circle(int cx, int cy, int r, uint32_t argb); |
| 33 |
|
| 34 | // draws img scaled into the box (bilinear when it shrinks or grows); radius rounds the corners |
| 35 | void gfx_image(const image_t *img, int x, int y, int w, int h, int radius, int alpha); |
| 36 | // the same, but turned round (left to right) when the mirror's on: art that has a side |
| 37 | void gfx_image_flip(const image_t *img, int x, int y, int w, int h, int radius, int alpha); |
| 38 |
|
| 39 | // right to left (Arabic): clip, rect, round_rect, circle and image are drawn mirrored across |
| 40 | // the canvas; text isn't (font.c places it); the other calls aren't mirrored (the UI doesn't use them) |
| 41 | void gfx_mirror(int on); |
| 42 | int gfx_mirrored(void); |
| 43 | // part of img (sx, sy, sw, sh) into the box, its colour multiplied by top at the top and bottom at |
| 44 | // the bottom, blended between (0xffffffff: as it is; an alpha fading down fades it in) |
| 45 | void gfx_image_part(const image_t *img, int sx, int sy, int sw, int sh, int x, int y, int w, int h, |
| 46 | uint32_t top, uint32_t bottom); |
| 47 |
|
| 48 | // img's alpha as a stencil, filled with one colour (white icons, tinted) |
| 49 | void gfx_tint(const image_t *img, int sx, int sw, int x, int y, uint32_t argb); |
| 50 |
|
| 51 | // a coverage mask (fonts): 8 bit alpha, w*h, drawn in one colour |
| 52 | void gfx_mask(const uint8_t *mask, int mw, int mh, int pitch, int x, int y, uint32_t argb); |
| 53 |
|
| 54 | // icons drawn from shapes, size = box side |
| 55 | enum { ICON_PLAY, ICON_PAUSE, ICON_NEXT, ICON_PREV, ICON_SHUFFLE, ICON_REPEAT, ICON_NOTE, |
| 56 | ICON_PERSON, ICON_ALBUM, ICON_LIST, ICON_GEAR, ICON_WAVE, ICON_SEARCH, ICON_REPEAT_ONE, ICON_HOME, ICON_GRID, ICON_QUEUE, NUM_ICONS }; |
| 57 | void gfx_icon(int icon, int x, int y, int size, uint32_t argb); |
| 58 |
|
| 59 | /* |
| 60 | The GPU path: with it on, the calls above build a list of quads (gpu.h) |
| 61 | that the platform draws, instead of drawing on the canvas. scale is the |
| 62 | display's pixels per canvas unit (1.5 at 1080p): masks (text, icons, |
| 63 | rounded corners) are made that much finer. |
| 64 | */ |
| 65 | void gfx_gpu_enable(float scale); |
| 66 | int gfx_gpu(void); |
| 67 | float gfx_scale(void); // 1 without the GPU |
| 68 | // with the GPU, later draws move by dx, dy canvas units (a fraction of one, to land on a |
| 69 | // display pixel between canvas units: smooth scrolling at 1080p); nothing without it |
| 70 | void gfx_offset(float dx, float dy); |
| 71 | void gfx_frame_begin(void); // before a frame's drawing |
| 72 | void gfx_frame_end(void); // after it: the list goes to the platform |
| 73 | void gfx_masks_reset(void); // the glyph bitmaps were freed (their pointers are stale) |
| 74 | int gfx_wants_redraw(void); // something didn't fit this frame: draw the next one in full |
| 75 | // a glyph made at gfx_scale(): drawn mw/scale x mh/scale canvas units at x, y (canvas units) |
| 76 | void gfx_mask_scaled(const uint8_t *mask, int mw, int mh, int pitch, float x, float y, uint32_t argb); |
| 77 |
|
| 78 | image_t *image_new(int w, int h); |
| 79 | void image_touch(image_t *img); // its pixels changed |
| 80 | void image_free(image_t *img); |
| 81 | // decodes JPEG/PNG and fits it into w x h (cover: crops to fill); NULL if it can't |
| 82 | image_t *image_decode(const void *data, int len, int w, int h); |
| 83 | // the same for drawing at w x h: at the screen's resolution with the GPU at 1080p (up to the picture's own) |
| 84 | image_t *image_decode_screen(const void *data, int len, int w, int h); |
| 85 | uint32_t image_average(const image_t *img); // for tinting backgrounds |
| 86 |
|
| 87 | static inline uint32_t argb(int a, int r, int g, int b) |
| 88 | { |
| 89 | return ((uint32_t)a << 24) | ((uint32_t)r << 16) | ((uint32_t)g << 8) | (uint32_t)b; |
| 90 | } |
| 91 | static inline uint32_t with_alpha(uint32_t c, int a) |
| 92 | { |
| 93 | return (c & 0xffffff) | ((uint32_t)a << 24); |
| 94 | } |
| 95 |
|
| 96 | #endif |