Subversion Repositories Projects

Rev

Rev 453 | Rev 490 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
389 cascade 1
/****************************************************************************
2
 *   Copyright (C) 2009 by Claas Anders "CaScAdE" Rathje                    *
3
 *   admiralcascade@gmail.com                                               *
4
 *   Project-URL: http://www.mylifesucks.de/oss/c-osd/                      *
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 2 of the License.         *
9
 *                                                                          *
10
 *   This program is distributed in the hope that it will be useful,        *
11
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
12
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
13
 *   GNU General Public License for more details.                           *
14
 *                                                                          *
15
 *   You should have received a copy of the GNU General Public License      *
16
 *   along with this program; if not, write to the                          *
17
 *   Free Software Foundation, Inc.,                                        *
18
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.              *
19
 ****************************************************************************/
20
 
21
#include <avr/pgmspace.h> 
22
#include "osd_helpers.h"
23
#include "max7456_software_spi.h"
24
 
25
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
26
/* ##########################################################################
27
 * compass stuff
28
 * ##########################################################################*/
29
 
30
/**
31
 * convert the <heading> gotton from NC into an index
32
 */
33
uint8_t heading_conv(uint16_t heading) {
34
    if (heading > 23 && heading < 68) {
35
        //direction = "NE";
36
        return 0;
37
    } else if (heading > 67 && heading < 113) {
38
        //direction = "E ";
39
        return 1;
40
    } else if (heading > 112 && heading < 158) {
41
        //direction = "SE";
42
        return 2;
43
    } else if (heading > 157 && heading < 203) {
44
        //direction = "S ";
45
        return 3;
46
    } else if (heading > 202 && heading < 248) {
47
        //direction = "SW";
48
        return 4;
49
    } else if (heading > 247 && heading < 293) {
50
        //direction = "W ";
51
        return 5;
52
    } else if (heading > 292 && heading < 338) {
53
        //direction = "NW";
54
        return 6;
55
    }
56
    //direction = "N ";
57
    return 7;
58
}
59
 
60
/**
61
 * convert the <heading> gotton from NC into a more
62
 * precise index
63
 */
64
uint8_t heading_fine_conv(uint16_t heading) {
65
        heading = ((heading * 10) + 113) % 3600;
66
        return (heading / 225);
67
}
68
 
69
/**
70
 * draw a compass rose at <x>/<y> for <heading>
71
 */
72
void draw_compass(uint8_t x, uint8_t y, uint16_t heading) {
73
    //char* rose = "---N---O---S---W---N---O---S---W---N---O---S---W";
489 woggle 74
    static char rose[48] PROGMEM = {216, 215, 216, 211, 216, 215, 216, 213, 216, 215, 216, 212,
389 cascade 75
                    216, 215, 216, 214, 216, 215, 216, 211, 216, 215, 216, 213,
76
                    216, 215, 216, 212, 216, 215, 216, 214, 216, 215, 216, 211,
77
                    216, 215, 216, 213, 216, 215, 216, 212, 216, 215, 216, 214};
78
        // the center is char 19 (north), we add the current heading in 8th
79
        // which would be 22.5 degrees, but float would bloat up the code
80
        // and *10 / 225 would take ages... so we take the uncorrect way
81
    uint8_t front = 19 + (heading / 22);
82
    for (uint8_t i = 0; i < 9; i++) {
489 woggle 83
                write_char_xy(x++, y, pgm_read_byte(&rose[front - 4 + i]));
389 cascade 84
    }
85
}
86
 
87
/* ##########################################################################
88
 * battery index
89
 * ##########################################################################*/
90
/**
91
 * draw a battery symbol at <x>/<y> according to <voltage>
92
 */
453 cascade 93
void draw_battery(uint8_t x, uint8_t y, uint8_t min_voltage, uint8_t voltage, uint8_t max_voltage) {
94
        uint8_t percent = (100* (voltage - min_voltage) / (max_voltage - min_voltage));
389 cascade 95
        if (percent > 100) percent = 100;
453 cascade 96
        if (voltage < min_voltage) percent = 0;
389 cascade 97
        write_char_xy(x, y, 0x9d - (percent * 13 / 100));
98
        //write_ndigit_number_u(x, y-1, percent * 13 / 100, 100, 0);
99
}
100
 
101
/* ##########################################################################
102
 * variometer
103
 * ##########################################################################*/
104
/**
105
 * draw variometer arrows at <x>/<y> according to <variometer>
106
 */
107
void draw_variometer(uint8_t x, uint8_t y, int16_t variometer) {
108
        if (variometer == 0) {
109
                write_char_xy(x, y, 0xbb); // plain line
110
        } else if (variometer > 0) { // gain height
111
                switch (variometer / 5){
112
                        case 0:
113
                                //write_char_xy(x, y, 0xba); // smallest arrow up
114
                                write_char_xy(x, y, 0x70); // one arrow up
115
                                break;
116
                        case 1:
117
                                //write_char_xy(x, y, 0xb9); // small arrow up
118
                                write_char_xy(x, y, 0x71); // two arrows up
119
                                break;
120
                        case 2:
121
                                //write_char_xy(x, y, 0xb8); // large arrow up
122
                                write_char_xy(x, y, 0x72); // three arrows up
123
                                break;
124
                        default:
125
                                //write_char_xy(x, y, 0xb7); // largest arrow up
126
                                write_char_xy(x, y, 0x73); // three black arrows up
127
                }
128
        } else { // sink
129
                switch (variometer / -5){
130
                        case 0:
131
                                //write_char_xy(x, y, 0xbc); // smallest arrow down
132
                                write_char_xy(x, y, 0x77); // one arrow down
133
                                break;
134
                        case 1:
135
                                //write_char_xy(x, y, 0xbd); // small arrow down
136
                                write_char_xy(x, y, 0x76); // two arrows down
137
                                break;
138
                        case 2:
139
                                //write_char_xy(x, y, 0xbe); // large arrow down
140
                                write_char_xy(x, y, 0x75); // three arrows down
141
                                break;
142
                        default:
143
                                //write_char_xy(x, y, 0xbf); // largest arrow down
144
                                write_char_xy(x, y, 0x74); // three black arrows down
145
                }
146
        }
147
}
148
 
149
// big vario arrays 
489 woggle 150
const char vario_00[5] PROGMEM = {0x00, 0x00, 0xc2, 0xff, 0xff};
151
const char vario_01[5] PROGMEM = {0x00, 0x00, 0xc2, 0xff, 0xc0};
152
const char vario_02[5] PROGMEM = {0x00, 0x00, 0xc2, 0xff, 0xc1};
153
const char vario_03[5] PROGMEM = {0x00, 0x00, 0xc2, 0xff, 0x00};
154
const char vario_04[5] PROGMEM = {0x00, 0x00, 0xc2, 0xc0, 0x00};
155
const char vario_05[5] PROGMEM = {0x00, 0x00, 0xc2, 0xc1, 0x00};
156
const char vario_06[5] PROGMEM = {0x00, 0x00, 0xc2, 0x00, 0x00};
157
const char vario_07[5] PROGMEM = {0x00, 0x00, 0xbb, 0x00, 0x00};
158
const char vario_08[5] PROGMEM = {0x00, 0x00, 0xc3, 0x00, 0x00};
159
const char vario_09[5] PROGMEM = {0x00, 0xc4, 0xc3, 0x00, 0x00};
160
const char vario_10[5] PROGMEM = {0x00, 0xc5, 0xc3, 0x00, 0x00};
161
const char vario_11[5] PROGMEM = {0x00, 0xff, 0xc3, 0x00, 0x00};
162
const char vario_12[5] PROGMEM = {0xc4, 0xff, 0xc3, 0x00, 0x00};
163
const char vario_13[5] PROGMEM = {0xc5, 0xff, 0xc3, 0x00, 0x00};
164
const char vario_14[5] PROGMEM = {0xff, 0xff, 0xc3, 0x00, 0x00};
165
const char* vario_pnt[15] PROGMEM = {vario_00, vario_01, vario_02, vario_03, vario_04,
389 cascade 166
                                vario_05, vario_06, vario_07, vario_08,
167
                                vario_09, vario_10, vario_11, vario_12,
168
                                vario_13, vario_14};
169
 
170
/**
171
 * draw a bigger vario with middle at <x>/<y> acording to <variometer>
172
 */
173
void draw_big_variometer(uint8_t x, uint8_t y, int16_t variometer) {   
174
        int16_t index = 7 + variometer;
175
        if (index > 14) index = 14;
176
        else if (index < 0) index = 0;
177
 
178
        // TODO: why does write_string_pgm_down(x, y-2, vario_pnt[index], 5);
179
        // not work??? WTF?!
489 woggle 180
        write_string_pgm_down(x, y-2, (const char *) (pgm_read_word ( &(vario_pnt[index]))), 5);
181
#if 0
389 cascade 182
        switch (index) {
183
                case 0: write_string_pgm_down(x, y-2, vario_pnt[0], 5);
184
                        break;
185
                case 1: write_string_pgm_down(x, y-2, vario_pnt[1], 5);
186
                        break;
187
                case 2: write_string_pgm_down(x, y-2, vario_pnt[2], 5);
188
                        break;
189
                case 3: write_string_pgm_down(x, y-2, vario_pnt[3], 5);
190
                        break;
191
                case 4: write_string_pgm_down(x, y-2, vario_pnt[4], 5);
192
                        break;
193
                case 5: write_string_pgm_down(x, y-2, vario_pnt[5], 5);
194
                        break;
195
                case 6: write_string_pgm_down(x, y-2, vario_pnt[6], 5);
196
                        break;
197
                case 7: write_string_pgm_down(x, y-2, vario_pnt[7], 5);
198
                        break;
199
                case 8: write_string_pgm_down(x, y-2, vario_pnt[8], 5);
200
                        break;
201
                case 9: write_string_pgm_down(x, y-2, vario_pnt[9], 5);
202
                        break;
203
                case 10: write_string_pgm_down(x, y-2, vario_pnt[10], 5);
204
                        break;
205
                case 11: write_string_pgm_down(x, y-2, vario_pnt[11], 5);
206
                        break;
207
                case 12: write_string_pgm_down(x, y-2, vario_pnt[12], 5);
208
                        break;
209
                case 13: write_string_pgm_down(x, y-2, vario_pnt[13], 5);
210
                        break;
211
                default: write_string_pgm_down(x, y-2, vario_pnt[14], 5);
489 woggle 212
        }
213
#endif
389 cascade 214
}
215
 
216
/* ##########################################################################
217
 * artificial horizon
218
 * ##########################################################################*/
219
// remember last time displayed values
220
int8_t old_af_x = -1, old_af_y = -1;
221
 
222
/**
223
 * draw roll und nick indicators (could be enhanced to full artificial horizon)
224
 * from line <firstline> to <listlines> for given <nick> and <roll> values
225
 */
226
void draw_artificial_horizon(uint8_t firstline, uint8_t lastline, int16_t nick, int16_t roll) {
227
        char noodle[5] = {225, 225, 226, 227, 227};
228
        uint8_t center_x = 15;
229
        uint8_t center_y = lastline - firstline;
230
        center_y = 7;
231
        write_char_xy(center_x,center_y,228);
232
        uint8_t cpos, nicky, rollx;
233
 
234
        // which line
235
        int8_t ypos =  nick / 20;
236
        // which character from the array?
237
        if (nick < 0) {
238
                cpos = -1*((nick - (ypos * 20))/4);
239
                ypos--;
240
        } else cpos = 4-((nick - (ypos * 20))/4);
241
        if (cpos > 4) cpos = 4;
242
 
243
        nicky = center_y - ypos;
244
        if (nicky > lastline) nicky = lastline;
245
        else if (nicky < firstline) nicky = firstline;
246
 
247
        // ensure roll-borders
248
        rollx = (roll / 8)+15;
249
        if (rollx < 2) rollx = 2;
250
        else if (rollx > 28) rollx = 28;
251
 
252
 
253
        // clear roll
254
        if (old_af_x != rollx && old_af_x >= 0) {
390 cascade 255
                write_char_xy(old_af_x, lastline, 0);
389 cascade 256
        }
257
 
258
        // clear nick
259
        if (old_af_y != nicky && old_af_y >= 0) {
390 cascade 260
                write_char_xy(center_x-1, old_af_y, 0);
261
                write_char_xy(center_x+1, old_af_y, 0);
389 cascade 262
        }
263
 
264
 
265
        // draw nick
390 cascade 266
        write_char_xy(center_x-1, nicky, noodle[cpos]);
267
        write_char_xy(center_x+1, nicky, noodle[cpos]);
389 cascade 268
 
269
        // draw roll
390 cascade 270
        write_char_xy(rollx, lastline, 229);
389 cascade 271
 
272
        // update old vars
273
        old_af_x = rollx;
274
        old_af_y = nicky;
275
 
276
        // debug numbers
277
        //write_3digit_number_u(20,6,cpos);
278
        //write_number_s(20,7,ypos);    
279
        //write_number_s(0,7,nick);             
280
        //write_number_s(18,11,roll);   
281
}
282
 
283
#endif