1 #include "framebuffer.hpp"
2 #include "instance.hpp"
8 void render_backbuffer(struct instance
& inst
)
11 for(unsigned i
= 0; i
< 200; i
++) {
12 for(unsigned j
= 0; j
< 320; j
++) {
13 for(unsigned k
= 0; k
< FB_SCALE
; k
++)
14 inst
.framebuffer
[FB_MAJSTRIDE
* i
+ FB_SCALE
* j
+ k
] = inst
.origbuffer
[
17 for(unsigned k
= 1; k
< FB_SCALE
; k
++)
18 memcpy(inst
.framebuffer
+ (FB_MAJSTRIDE
* i
+ k
* FB_WIDTH
),
19 inst
.framebuffer
+ FB_MAJSTRIDE
* i
, FB_WIDTH
* sizeof(uint32_t));
21 //Calculate overlap region.
22 for(unsigned i
= 0; i
< 200; i
++) {
23 uint32_t high
= 0x00000000U
;
24 for(unsigned j
= 0; j
< 320; j
++)
25 high
|= inst
.origbuffer
[320 * i
+ j
];
26 if(high
& 0xFF000000U
) {
27 inst
.overlap_start
= FB_SCALE
* i
;
31 for(unsigned i
= inst
.overlap_start
/ FB_SCALE
; i
< 200; i
++) {
32 uint32_t low
= 0xFFFFFFFFU
;
33 for(unsigned j
= 0; j
< 320; j
++)
34 low
&= inst
.origbuffer
[320 * i
+ j
];
35 if((low
& 0xFF000000U
) == 0xFF000000U
) {
36 inst
.overlap_end
= FB_SCALE
* i
;
42 void render_framebuffer_update(struct instance
& inst
, uint16_t x
, uint16_t y
, uint16_t w
, uint16_t h
)
46 for(unsigned i
= y
; i
< y
+ h
&& i
< 200; i
++) {
47 for(unsigned j
= x
; j
< x
+ w
&& j
< 320; j
++) {
48 for(unsigned k
= 0; k
< FB_SCALE
; k
++)
49 inst
.framebuffer
[FB_MAJSTRIDE
* i
+ FB_SCALE
* j
+ k
] = inst
.origbuffer
[
52 for(unsigned k
= 1; k
< FB_SCALE
; k
++)
53 memcpy(inst
.framebuffer
+ (FB_MAJSTRIDE
* i
+ FB_SCALE
* x
+ k
* FB_WIDTH
),
54 inst
.framebuffer
+ FB_MAJSTRIDE
* i
+ FB_SCALE
* x
, FB_SCALE
* w
*
59 void render_framebuffer_vline(struct instance
& inst
, uint16_t x
, uint16_t y1
, uint16_t y2
, uint32_t color
)
61 for(unsigned i
= y1
; i
<= y2
&& i
< 200; i
++) {
62 for(unsigned k
= 0; k
< FB_SCALE
; k
++)
63 inst
.framebuffer
[FB_MAJSTRIDE
* i
+ x
+ k
* FB_WIDTH
] = 0xFF000000U
| color
;
67 char decode(const char* ch
)
75 void draw_block2(struct instance
& inst
, const char* pointer
, uint16_t position
, uint32_t c1
, uint32_t c2
,
78 static const uint8_t tbl
[3][6] = {{27, 9, 3, 1}, {32, 16, 8, 4, 2, 1}, {32, 16, 8, 4, 2, 1}};
79 static const uint8_t tbl2
[3][3] = {{4, 6, 6}, {3, 2, 2}, {0, 0, 1}};
82 uint8_t type
= decode(pointer
++);
83 uint16_t width
= decode(pointer
++);
84 if(width
> 63) width
= (width
- 64) * 64 + decode(pointer
++);
85 uint16_t height
= decode(pointer
++);
86 if(height
> 63) height
= (height
- 64) * 64 + decode(pointer
++);
87 uint16_t origptr
= position
;
90 for(unsigned y
= 0; y
< height
; y
++) {
91 for(unsigned x
= 0; x
< width
; x
++) {
93 reg
= decode(pointer
++);
94 uint8_t p
= ((reg
/ tbl
[type
][mod
]) % tbl2
[1][type
]) << tbl2
[2][type
];
95 mod
= (mod
+ 1) % tbl2
[0][type
];
97 inst
.origbuffer
[position
] = (p
> 1) ? c2
: c1
;
99 inst
.origbuffer
[position
] = 0;
102 position
+= (320 - width
);
104 render_framebuffer_update(inst
, origptr
% 320, origptr
/ 320, width
, height
);
107 void draw_block(struct instance
& inst
, const uint8_t* pointer
, uint16_t position
, uint32_t c1
, uint32_t c2
,
112 uint16_t width
= *(pointer
++);
113 uint16_t height
= *(pointer
++);
114 uint16_t origptr
= position
;
115 for(unsigned y
= 0; y
< height
; y
++) {
116 for(unsigned x
= 0; x
< width
; x
++) {
117 uint8_t p
= *(pointer
++);
119 inst
.origbuffer
[position
] = (p
> 1) ? c2
: c1
;
121 inst
.origbuffer
[position
] = 0;
124 position
+= (320 - width
);
126 render_framebuffer_update(inst
, origptr
% 320, origptr
/ 320, width
, height
);
129 void draw_message(struct instance
& inst
, const char* pointer
, uint32_t c1
, uint32_t c2
)
133 uint16_t width
= decode(pointer
++);
134 if(width
> 63) width
= (width
- 64) * 64 + decode(pointer
++);
135 uint16_t height
= decode(pointer
++);
136 if(height
> 63) height
= (height
- 64) * 64 + decode(pointer
++);
137 uint16_t x
= (320 - width
) / 2;
138 uint16_t y
= (200 - height
) / 2;
139 uint16_t p
= 320 * y
+ x
;
140 draw_block2(inst
, op
, p
, c1
, c2
);
143 void draw_distance_column(struct instance
& inst
, uint16_t col
, uint32_t c
)
145 uint16_t minline
= 0x8f;
146 uint16_t maxline
= 0x8f;
147 uint16_t ptr
= 320 * 0x8f + 0x2a + (col
/ FB_SCALE
);
148 uint32_t px
= inst
.origbuffer
[ptr
] ;
149 while(inst
.origbuffer
[ptr
] == px
)
153 while(inst
.origbuffer
[ptr
] == px
)
155 maxline
= ptr
/ 320 - 1;
156 render_framebuffer_vline(inst
, col
+ FB_SCALE
* 0x2a, minline
, maxline
, c
| 0xFF000000U
);
159 void blink_between(struct instance
& inst
, unsigned x
, unsigned y
, unsigned w
, unsigned h
, uint32_t c1
,
164 uint32_t c1x
= c1
| 0xFF000000U
;
165 uint32_t c2x
= c2
| 0xFF000000U
;
166 for(unsigned j
= y
; j
< y
+ h
; j
++)
167 for(unsigned i
= x
; i
< x
+ w
; i
++) {
168 if((inst
.origbuffer
[320 * j
+ i
] & 0xFFFFFF) == c1
)
169 inst
.origbuffer
[320 * j
+ i
] = c2x
;
170 else if((inst
.origbuffer
[320 * j
+ i
] & 0xFFFFFF) == c2
)
171 inst
.origbuffer
[320 * j
+ i
] = c1x
;
173 render_framebuffer_update(inst
, x
, y
, w
, h
);
176 void draw_bitmap(struct instance
& inst
, const uint32_t* bitmap
, unsigned x
, unsigned y
)
178 for(unsigned j
= 0; j
< bitmap
[1]; j
++)
179 for(unsigned i
= 0; i
< bitmap
[0]; i
++)
180 inst
.framebuffer
[(y
+ j
) * FB_WIDTH
+ (x
+ i
)] = bitmap
[j
* bitmap
[0] + i
+ 2];