Subversion Repositories svn.mios32

Rev

Rev 2186 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2182 hawkeye 1
// $Id: screen.c 1223 2011-06-23 21:26:52Z hawkeye $
2
 
3
#include <mios32.h>
4
 
2183 hawkeye 5
#include <stdarg.h>
2184 hawkeye 6
#include <string.h>
2183 hawkeye 7
 
2182 hawkeye 8
#include <glcd_font.h>
9
#include <app_lcd.h>
10
 
2183 hawkeye 11
#include "gfx_resources.h"
2182 hawkeye 12
#include "voxelspace.h"
13
 
14
 
15
// -------------------------------------------------------------------------------------------
16
// SSD 1322 Screen routines by Hawkeye
17
 
2184 hawkeye 18
// --- globals ---
19
 
2182 hawkeye 20
u8 screen[64][128];             // Screen buffer [y][x]
21
 
2184 hawkeye 22
u8 screenShowLoopaLogo_;
2185 hawkeye 23
u8 screenClipNumberSelected_ = 0;
24
s8 screenRecordingClipNumber_ = -1;
2184 hawkeye 25
u16 screenClipStepPosition_[8];
26
u16 screenClipStepLength_[8];
2185 hawkeye 27
u32 screenSongStep_ = 0;
2186 hawkeye 28
char screenFlashMessage_[40];
29
u8 screenFlashMessageFrameCtr_;
2183 hawkeye 30
 
2184 hawkeye 31
unsigned char* fontptr_ = (unsigned char*) fontsmall_pixdata;
32
u16 fontchar_bytewidth_ = 3;    // bytes to copy for a line of character pixel data
33
u16 fontchar_height_ = 12;      // lines to copy for a full-height character
34
u16 fontline_bytewidth_ = 95*3; // bytes per font pixdata line (character layout all in one line)
35
 
36
 
37
/**
38
 * Set the bold font
39
 *
40
 */
41
void setFontBold()
2183 hawkeye 42
{
2184 hawkeye 43
   fontptr_ = (unsigned char*) fontbold_pixdata;
44
   fontchar_bytewidth_ = 5;
45
   fontchar_height_ = 18;
46
   fontline_bytewidth_ = 95 * 5;
2183 hawkeye 47
}
48
// ----------------------------------------------------------------------------------------
49
 
50
 
2184 hawkeye 51
/**
52
 * Set the normal font
53
 *
54
 */
55
void setFontNormal()
2183 hawkeye 56
{
2184 hawkeye 57
   fontptr_ = (unsigned char*) fontnormal_pixdata;
58
   fontchar_bytewidth_ = 5;
59
   fontchar_height_ = 18;
60
   fontline_bytewidth_ = 95 * 5;
2183 hawkeye 61
}
62
// ----------------------------------------------------------------------------------------
63
 
2184 hawkeye 64
 
65
/**
66
 * Set the small font
67
 *
68
 */
69
void setFontSmall()
70
{
71
   fontptr_ = (unsigned char*) fontsmall_pixdata;
72
   fontchar_bytewidth_ = 3;
73
   fontchar_height_ = 12;
74
   fontline_bytewidth_ = 95 * 3;
75
}
76
// ----------------------------------------------------------------------------------------
77
 
78
 
79
/**
80
 * Display the given string at the given pixel coordinates
81
 * output to screen output buffer, the next display() will render it to hardware
82
 * provides clipping support, coordinates can be offscreen/negative for scrolling fx
83
 *
84
 */
2183 hawkeye 85
void printString(int xPixCoord /* even! */, int yPixCoord, const char *str)
86
{
87
   unsigned stringpos = 0;
88
 
89
   while (*str != '\0')
90
   {
91
      int c = *str++;
92
      unsigned x;
93
 
94
      // in-font coordinates
95
      unsigned f_y = 0;
2184 hawkeye 96
      unsigned f_x = (c-32) * fontchar_bytewidth_;
2183 hawkeye 97
 
98
      // screenbuf target coordinates
99
      unsigned s_y = yPixCoord;
2184 hawkeye 100
      unsigned s_x = xPixCoord / 2 + stringpos * fontchar_bytewidth_; // 2 pixels per byte, require even xPixCoord start coordinate
2183 hawkeye 101
 
2184 hawkeye 102
      while (f_y < fontchar_height_)
2183 hawkeye 103
      {
104
         if (s_y >= 0 && s_y < 64) // clip y offscreen
105
         {
106
            unsigned char* sdata = (unsigned char*) screen + s_y * 128 + s_x;
2184 hawkeye 107
            unsigned char* fdata = (unsigned char*) fontptr_ + f_y * fontline_bytewidth_ + f_x;
2183 hawkeye 108
            unsigned c_s_x = s_x;
109
 
2184 hawkeye 110
            for (x = 0; x <fontchar_bytewidth_; x++)
2183 hawkeye 111
            {
112
               if (c_s_x >= 0 && c_s_x < 128)
113
                  if (*fdata)
114
                     *sdata = *fdata;  // inner loop: copy 2 pixels, if onscreen
115
 
116
               c_s_x++;
117
               fdata++;
118
               sdata++;
119
            }
120
         }
121
 
122
         f_y++;
123
         s_y++;
124
      }
125
 
126
      stringpos++;
127
   }
128
}
129
// ----------------------------------------------------------------------------------------
130
 
131
 
2184 hawkeye 132
/**
133
 * Display the given formatted string at the given pixel coordinates
134
 * output to screen output buffer, the next display() will render it to hardware
135
 * provides clipping support, coordinates can be offscreen/negative for scrolling fx
136
 *
137
 */
2183 hawkeye 138
void printFormattedString(int xPixCoord /* even! */, int yPixCoord, const char* format, ...)
139
{
140
   char buffer[64]; // TODO: tmp!!! Provide a streamed COM method later!
141
   va_list args;
142
 
143
   va_start(args, format);
144
   vsprintf((char *)buffer, format, args);
145
   return printString(xPixCoord, yPixCoord, buffer);
146
}
147
// ----------------------------------------------------------------------------------------
148
 
149
 
2184 hawkeye 150
 
151
/**
152
 * Display a loopa slot time indicator
2185 hawkeye 153
 * Format: [clipPos:clipLength]
154
 *         times are in steps/quarternotes
2184 hawkeye 155
 *
156
 *         the time indicator will be rendered inverted, if this is the selected clip/active clip
157
 *         the display position depends on the slot number, slot #0 is upper left, slot #7 is lower right
158
 *
159
 */
2185 hawkeye 160
void displayClipPosition(u8 clipNumber)
2184 hawkeye 161
{
162
   char buffer[16];
163
 
2185 hawkeye 164
   u8 loopStartChar = '<';
165
   u8 loopEndChar = '=';
2184 hawkeye 166
 
2185 hawkeye 167
   u16 stepLength = screenClipStepLength_[clipNumber];
168
   u16 stepPos = screenClipStepPosition_[clipNumber];
169
   u8 isSelected = (clipNumber == screenClipNumberSelected_);
170
   u8 isRecording = (clipNumber == screenRecordingClipNumber_);
2184 hawkeye 171
 
2185 hawkeye 172
   if (!isRecording)
173
   {
174
      if (stepLength == 0)
175
         sprintf((char *)buffer, "           ");
176
      else if (stepLength > 999)
177
         sprintf((char *)buffer, "%c%04d>%4d%c", loopStartChar, stepPos, stepLength, loopEndChar);
178
      else if (stepLength > 99)
179
         sprintf((char *)buffer, " %c%03d>%3d%c ", loopStartChar, stepPos, stepLength, loopEndChar);
180
      else if (stepLength > 9)
181
         sprintf((char *)buffer, "  %c%02d>%2d%c  ", loopStartChar, stepPos, stepLength, loopEndChar);
182
   }
183
   else
184
   {
185
      sprintf((char *)buffer, ":: %05d ;;", screenSongStep_);
186
   }
187
 
188
   u8 xPixCoord = (clipNumber % 4) * 64;
189
   u8 yPixCoord = clipNumber < 4 ? 0 : 56;
2184 hawkeye 190
   u8 fontHeight = 7;
191
   u8 fontByteWidth = 3;
192
   u8 fontLineByteWidth = 16*3;
193
 
194
   char *str = buffer;
195
   u8 stringpos = 0;
196
   while (*str != '\0')
197
   {
198
      int c = *str++;
199
 
200
      if (c == ' ')  // Map string space to font space
201
         c = '/';
202
 
203
      unsigned x;
204
 
205
      // in-font coordinates
206
      unsigned f_y = 0;
207
      unsigned f_x = (c-47) * fontByteWidth;
208
 
209
      // screenbuf target coordinates
210
      unsigned s_y = yPixCoord;
211
      unsigned s_x = xPixCoord / 2 + stringpos * fontByteWidth; // 2 pixels per byte, require even xPixCoord start coordinate
212
 
213
      while (f_y < fontHeight)
214
      {
215
         if (s_y >= 0 && s_y < 64) // clip y offscreen
216
         {
217
            unsigned char* sdata = (unsigned char*) screen + s_y * 128 + s_x;
218
            unsigned char* fdata = (unsigned char*) digitstiny_pixdata + f_y * fontLineByteWidth + f_x;
219
            unsigned c_s_x = s_x;
220
 
221
            for (x = 0; x <fontByteWidth; x++)
222
            {
223
               if (c_s_x >= 0 && c_s_x < 128)
224
               {
225
                  if (!isSelected)
226
                  {
227
                     if (*fdata)
228
                        *sdata = *fdata;  // inner loop: copy 2 pixels, if onscreen
229
                  }
230
                  else
231
                  {
232
                     // "invert" font
233
                     u8 first = *fdata >> 4;
234
                     u8 second = *fdata % 16;
235
 
236
                     first = 15-first;
237
                     second = 15-second;
238
                     *sdata = (first << 4) + second;
239
                  }
240
               }
241
 
242
               c_s_x++;
243
               fdata++;
244
               sdata++;
245
            }
246
         }
247
 
248
         f_y++;
249
         s_y++;
250
      }
251
 
252
      stringpos++;
253
   }
254
}
255
// ----------------------------------------------------------------------------------------
256
 
257
 
258
/**
259
 * If showLogo is true, draw the MBLoopa Logo (usually during unit startup)
260
 *
261
 */
262
void screenShowLoopaLogo(u8 showLogo)
263
{
264
   screenShowLoopaLogo_ = showLogo;
265
}
266
// ----------------------------------------------------------------------------------------
267
 
268
 
269
/**
270
 * Set the currently selected clip
271
 *
272
 */
273
void screenSetClipSelected(u8 clipNumber)
274
{
2185 hawkeye 275
   screenClipNumberSelected_ = clipNumber;
2184 hawkeye 276
}
277
// ----------------------------------------------------------------------------------------
278
 
279
 
280
/**
2185 hawkeye 281
 * Set the currently recorded-to clip
2184 hawkeye 282
 *
283
 */
2185 hawkeye 284
void screenSetClipRecording(u8 clipNumber, u8 recordingActiveFlag)
2184 hawkeye 285
{
2185 hawkeye 286
   if (recordingActiveFlag)
287
      screenRecordingClipNumber_ = clipNumber;
288
   else
289
      screenRecordingClipNumber_ = -1;
2184 hawkeye 290
}
291
// ----------------------------------------------------------------------------------------
292
 
293
 
294
/**
2185 hawkeye 295
 * Set the length of a clip
296
 *
297
 */
298
void screenSetClipLength(u8 clipNumber, u16 stepLength)
299
{
300
   DEBUG_MSG("[screenSetClipLength] clip: %d steplength: %d", clipNumber, stepLength);
301
   screenClipStepLength_[clipNumber] = stepLength;
302
}
303
// ----------------------------------------------------------------------------------------
304
 
305
 
306
/**
2184 hawkeye 307
 * Set the position info of a clip
308
 *
309
 */
2185 hawkeye 310
void screenSetClipPosition(u8 clipNumber, u16 stepPosition)
2184 hawkeye 311
{
2187 hawkeye 312
   DEBUG_MSG("[screenSetClipPosition] clip: %u stepPosition: %u", clipNumber, stepPosition);
2184 hawkeye 313
   screenClipStepPosition_[clipNumber] = stepPosition;
314
}
315
// ----------------------------------------------------------------------------------------
316
 
317
 
2185 hawkeye 318
/**
319
 * Set the global song step position (e.g. for displaying the recording-clip step)
320
 *
321
 */
322
void screenSetSongStep(u32 stepPosition)
323
{
324
   screenSongStep_ = stepPosition;
325
}
326
// ----------------------------------------------------------------------------------------
327
 
328
 
329
/**
2186 hawkeye 330
 * Flash a short-lived message to the center of the screen
331
 *
332
 */
333
void screenFormattedFlashMessage(const char* format, ...)
334
{
335
   va_list args;
336
 
337
   va_start(args, format);
338
   vsprintf((char *)screenFlashMessage_, format, args);
339
   screenFlashMessageFrameCtr_ = 10;
340
}
341
// ----------------------------------------------------------------------------------------
342
 
343
 
344
 
345
/**
2185 hawkeye 346
 * Display the current screen buffer
347
 *
348
 */
2182 hawkeye 349
void display(void)
350
{
351
   u8 i, j;
352
 
2184 hawkeye 353
   if (screenShowLoopaLogo_)
354
   {
355
      // Startup/initial session loading: Render the MBLoopa Logo
356
      setFontBold();
2186 hawkeye 357
      printFormattedString(82, 10, "MBLoopA V1");
2184 hawkeye 358
      setFontSmall();
359
      printFormattedString(64, 32, "(C) Hawkeye, TK. 2015");
360
      printFormattedString(52, 44, "MIDIbox hardware platform");
361
   }
362
   else
363
   {
364
      // Render normal operations fonts/menus
2183 hawkeye 365
 
2184 hawkeye 366
      // printFormattedString(0, 51, "%s %s %u:%u", screenMode, screenFile, screenPosBar, screenPosStep % 16);
367
 
2185 hawkeye 368
      u8 clip;
369
      for (clip = 0; clip < 8; clip++)
370
         displayClipPosition(clip);
2184 hawkeye 371
   }
372
 
2186 hawkeye 373
   if (screenFlashMessageFrameCtr_)
374
   {
375
      setFontNormal();
376
      u8 len = strlen(screenFlashMessage_);
377
      u8 xpos = 128 - len * 5;
378
      u16 displacement = 10 - screenFlashMessageFrameCtr_;
379
      displacement = (displacement * displacement) / 3;
380
      printFormattedString(xpos, 26 - displacement, screenFlashMessage_);
381
 
382
      screenFlashMessageFrameCtr_--;
383
   }
384
 
2182 hawkeye 385
   // Push screen buffer
386
   for (j = 0; j < 64; j++)
387
   {
388
      APP_LCD_Cmd(0x15);
389
      APP_LCD_Data(0+0x1c);
390
 
391
      APP_LCD_Cmd(0x75);
392
      APP_LCD_Data(j);
393
 
394
      APP_LCD_Cmd(0x5c);
395
 
396
      u8 bgcol = j < 6 ? ((j << 4) + j) : 0;
397
      for (i = 0; i < 128; i++)
398
      {
399
         APP_LCD_Data(screen[j][i]);
400
         screen[j][i] = bgcol;
401
         i++;
402
         APP_LCD_Data(screen[j][i]);
403
         screen[j][i] = bgcol;
404
      }
405
   }
406
 
407
}
408
// ----------------------------------------------------------------------------------------
409
 
410
 
2185 hawkeye 411
/**
412
 * Render test screen, one half is "full on" for flicker tests
413
 * one half contains a color gradient pattern
414
 *
415
 */
2182 hawkeye 416
void testScreen()
417
{
418
  u16 x = 0;
419
  u16 y = 0;
420
 
421
  for (y = 0; y < 64; y++)
422
  {
423
     APP_LCD_Cmd(0x15);
424
     APP_LCD_Data(0x1c);
425
 
426
     APP_LCD_Cmd(0x75);
427
     APP_LCD_Data(y);
428
 
429
     APP_LCD_Cmd(0x5c);
430
 
431
     for (x = 0; x < 64; x++)
432
     {
433
        if (x < 32)
434
        {  // half screen pattern
435
 
436
           if (x || 4 == 0 || y || 4 == 0)
437
           {
438
              APP_LCD_Data(y & 0x0f);
439
              APP_LCD_Data(0);
440
           }
441
           else
442
           {
443
              APP_LCD_Data(0x00);
444
              APP_LCD_Data(0x00);
445
           }
446
        }
447
        else // half screen "white"
448
        {
449
           APP_LCD_Data(0xff);
450
           APP_LCD_Data(0xff);
451
        }
452
     }
453
  }
454
 
455
  while(1);
456
}
457
// -------------------------------------------------------------------------------------------