altos/vidtime: Check for value change in normal code, not irq
[fw/altos] / src / draw / ao_draw_int.h
1 /*
2  * Copyright © 2016 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  */
14
15 #ifndef _AO_DRAW_INT_H_
16 #define _AO_DRAW_INT_H_
17
18 static inline uint32_t
19 ao_expand(uint32_t bits)
20 {
21         return ~((bits & 1)-1);
22 }
23
24 static inline uint32_t
25 ao_xor(uint8_t rop, uint32_t fg)
26 {
27         fg = ao_expand(fg);
28
29         return (fg & ao_expand(rop >> 1)) |
30                 (~fg & ao_expand(rop >> 3));
31 }
32
33 static inline uint32_t
34 ao_and(uint8_t rop, uint32_t fg)
35 {
36         fg = ao_expand(fg);
37
38         return (fg & ao_expand(rop ^ (rop >> 1))) |
39                 (~fg & ao_expand((rop>>2) ^ (rop>>3)));
40 }
41
42 static inline uint32_t
43 ao_left(uint32_t bits, int16_t shift) {
44         return bits >> shift;
45 }
46
47 static inline uint32_t
48 ao_right(uint32_t bits, int16_t shift) {
49         return bits << shift;
50 }
51
52 static inline uint32_t
53 ao_right_mask(int16_t x) {
54         if ((AO_UNIT - x) & AO_MASK)
55                 return ao_left(AO_ALLONES,(AO_UNIT - x) & AO_MASK);
56         else
57                 return 0;
58 }
59
60 static inline uint32_t
61 ao_left_mask(int16_t x) {
62         if (x & AO_MASK)
63                 return ao_right(AO_ALLONES, x & AO_MASK);
64         else
65                 return 0;
66 }
67
68 static inline uint32_t
69 ao_bits_mask(int16_t x, int16_t w) {
70         return ao_right(AO_ALLONES, x & AO_MASK) &
71                 ao_left(AO_ALLONES,(AO_UNIT - (x + w)) & AO_MASK);
72 }
73
74 #define ao_mask_bits(x,w,l,n,r) { \
75     n = (w); \
76     r = ao_right_mask((x)+n); \
77     l = ao_left_mask(x); \
78     if (l) { \
79         n -= AO_UNIT - ((x) & AO_MASK); \
80         if (n < 0) { \
81             n = 0; \
82             l &= r; \
83             r = 0; \
84         } \
85     } \
86     n >>= AO_SHIFT; \
87 }
88
89 #define ao_clip(val,min,max) do {               \
90                 if (val < min) {                \
91                         val = min;              \
92                 } else if (val > max) {         \
93                         val = max;              \
94                 }                               \
95         } while (0)
96
97 static inline uint32_t
98 ao_do_mask_rrop(uint32_t dst, uint32_t and, uint32_t xor, uint32_t mask) {
99         return (dst & (and | ~mask)) ^ (xor & mask);
100 }
101
102 static inline uint32_t
103 ao_do_rrop(uint32_t dst, uint32_t and, uint32_t xor) {
104         return (dst & and) ^ xor;
105 }
106
107 void
108 ao_blt(uint32_t         *src_line,
109        int16_t          src_stride,
110        int16_t          src_x,
111        uint32_t         *dst_line,
112        int16_t          dst_stride,
113        int16_t          dst_x,
114        int16_t          width,
115        int16_t          height,
116        uint8_t          rop,
117        uint8_t          reverse,
118        uint8_t          upsidedown);
119
120 void
121 ao_solid(uint32_t       and,
122          uint32_t       xor,
123          uint32_t       *dst,
124          int16_t        dst_stride,
125          int16_t        dst_x,
126          int16_t        width,
127          int16_t        height);
128
129 int16_t
130 ao_glyph(const struct ao_bitmap *dst,
131          int16_t                x,
132          int16_t                y,
133          uint8_t                c,
134          uint8_t                rop);
135
136 #endif /* _AO_DRAW_INT_H_ */