OVR: Change the way to walk and rotate with the controller
[mercenary-reloaded.git] / src / libtext / text.c
1 /* Text screens and OSD generator
2  *
3  * (C) 2018 by Andreas Eversberg <jolly@eversberg.eu>
4  * All Rights Reserved
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <stdio.h>
21 #include <stdint.h>
22 #include <stdlib.h>
23 #include "topaz.h"
24
25 #define COLOR(c)        { *rgba++ = palette_red[c]; *rgba++ = palette_green[c]; *rgba++ = palette_blue[c]; *rgba++ = palette_alpha[c]; }
26 #define COLOR_BLUE      0
27 #define COLOR_WHITE     1
28 #define COLOR_BLACK     2
29 #define COLOR_YELLOW    3
30 #define COLOR_RED       4
31 static uint8_t palette_red[5] = { 0x00, 0xff, 0x00, 0xff, 0xdd };
32 static uint8_t palette_green[5] = { 0x55, 0xff, 0x00, 0x88, 0x22 };
33 static uint8_t palette_blue[5] = { 0xaa, 0xff, 0x22, 0x00, 0x22 };
34 static uint8_t palette_alpha[5] = { 0xff, 0xff, 0xff, 0xff, 0xff };
35
36 uint8_t *text_alloc(int image_width, int image_height, uint8_t alpha)
37 {
38         uint8_t *buffer, *rgba;
39         int x, y;
40
41         palette_alpha[COLOR_BLUE] = alpha;
42
43         buffer = calloc(image_width * image_height, 4);
44         if (!buffer)
45                 return NULL;
46
47         /* clear screen */
48         rgba = buffer;
49         for (y = 0; y < image_height; y++) {
50                 for (x = 0; x < image_width; x++)
51                         COLOR(COLOR_BLUE)
52         }
53
54         return buffer;
55 }
56
57 /* render given text to an RGBA image */
58 void text_render(uint8_t *buffer, int image_width, int image_height, const char *text, uint8_t alpha, int color, double start_column, double start_line, int double_height)
59 {
60         uint8_t *rgba;
61         char *font;
62         int x, y, i, j;
63
64         palette_alpha[COLOR_BLUE] = alpha;
65
66         x = start_column * 8.0;
67         y = start_line * ((double_height) ? 16.0 : 8.0);
68         if (x < 0 || y < 0)
69                 return;
70
71         /* render text */
72         while (*text) {
73                 /* newline */
74                 if (*text == '\n') {
75                         y += (double_height) ? 16 : 8;
76                         x = start_column * 8.0;
77                         text++;
78                         continue;
79                 }
80                 /* if no space to the bottom */
81                 if (y + ((double_height) ? 16 : 8) > image_height)
82                         break;
83                 /* if no space to the right */
84                 if (x + 8 > image_width) {
85                         text++;
86                         continue;
87                 }
88                 /* if non visible characters */
89                 if (*text < 32 || *text > 126) {
90                         text++;
91                         continue;
92                 }
93                 /* set pointers */
94                 rgba = buffer + (y * image_width + x) * 4;
95                 font = topaz_data + (*text - 32) * 64 + 7;
96                 for (i = 0; i < 8; i++) {
97                         /* render one line */
98                         for (j = 0; j < 8; j++) {
99                                 if (*font)
100                                         COLOR(color)
101                                 else
102                                         COLOR(COLOR_BLUE)
103                                 font += 8;
104                         }
105                         if (double_height) {
106                                 font -= 64;
107                                 rgba += (image_width - 8) * 4;
108                                 /* render line again */
109                                 for (j = 0; j < 8; j++) {
110                                         if (*font)
111                                                 COLOR(color)
112                                         else
113                                                 COLOR(COLOR_BLUE)
114                                         font += 8;
115                                 }
116                         }
117                         rgba += (image_width - 8) * 4;
118                         font -= 65;
119                 }
120                 x += 8;
121                 text++;
122         }
123 }
124
125 void text_insert_image(uint8_t *buffer, uint8_t palette[][3], const char *pixels, uint8_t alpha)
126 {
127         int y, x;
128
129         for (y = 0; y < 200; y++) {
130                 for (x = 0; x < 320; x++) {
131                         buffer[((2*y+0) * 2*320 + (2*x+0)) * 4 + 0] = palette[(int)(*pixels)][0];
132                         buffer[((2*y+0) * 2*320 + (2*x+0)) * 4 + 1] = palette[(int)(*pixels)][1];
133                         buffer[((2*y+0) * 2*320 + (2*x+0)) * 4 + 2] = palette[(int)(*pixels)][2];
134                         buffer[((2*y+0) * 2*320 + (2*x+0)) * 4 + 3] = alpha;
135
136                         buffer[((2*y+0) * 2*320 + (2*x+1)) * 4 + 0] = palette[(int)(*pixels)][0];
137                         buffer[((2*y+0) * 2*320 + (2*x+1)) * 4 + 1] = palette[(int)(*pixels)][1];
138                         buffer[((2*y+0) * 2*320 + (2*x+1)) * 4 + 2] = palette[(int)(*pixels)][2];
139                         buffer[((2*y+0) * 2*320 + (2*x+1)) * 4 + 3] = alpha;
140
141                         buffer[((2*y+1) * 2*320 + (2*x+0)) * 4 + 0] = palette[(int)(*pixels)][0];
142                         buffer[((2*y+1) * 2*320 + (2*x+0)) * 4 + 1] = palette[(int)(*pixels)][1];
143                         buffer[((2*y+1) * 2*320 + (2*x+0)) * 4 + 2] = palette[(int)(*pixels)][2];
144                         buffer[((2*y+1) * 2*320 + (2*x+0)) * 4 + 3] = alpha;
145
146                         buffer[((2*y+1) * 2*320 + (2*x+1)) * 4 + 0] = palette[(int)(*pixels)][0];
147                         buffer[((2*y+1) * 2*320 + (2*x+1)) * 4 + 1] = palette[(int)(*pixels)][1];
148                         buffer[((2*y+1) * 2*320 + (2*x+1)) * 4 + 2] = palette[(int)(*pixels)][2];
149                         buffer[((2*y+1) * 2*320 + (2*x+1)) * 4 + 3] = alpha;
150                         pixels++;
151                 }
152         }
153 }
154