summaryrefslogtreecommitdiff
path: root/apps/plugins/pdbox/PDa/intern
ModeNameSize
-rw-r--r--biquad~.c3679logplain
-rw-r--r--bp~.c3537logplain
-rw-r--r--clip~.c1283logplain
-rw-r--r--cos_table.c343788logplain
-rw-r--r--cos_table.h239logplain
-rw-r--r--cos~.c1753logplain
-rw-r--r--dbtopow~.c1354logplain
-rw-r--r--dbtorms~.c1356logplain
-rw-r--r--delay.h933logplain
-rw-r--r--delread~.c3099logplain
-rw-r--r--delwrite~.c2339logplain
-rw-r--r--env~.c3604logplain
-rw-r--r--ftom~.c1357logplain
-rw-r--r--hip~.c2200logplain
-rw-r--r--intern_setup.c2566logplain
-rw-r--r--line~.c2431logplain
-rw-r--r--lop~.c2151logplain
-rw-r--r--makefile354logplain
-rw-r--r--mtof~.c1324logplain
-rw-r--r--noise~.c1097logplain
-rw-r--r--osc~.c2159logplain
-rw-r--r--phasor~.c1731logplain
-rw-r--r--powtodb~.c1354logplain
-rw-r--r--print~.c1743logplain
-rw-r--r--rmstodb~.c1349logplain
-rw-r--r--rsqrt~.c3194logplain
-rw-r--r--samphold~.c1905logplain
-rw-r--r--sformat.h1965logplain
-rw-r--r--sfread~.c6640logplain
-rw-r--r--sfwrite~.c5706logplain
-rw-r--r--snapshot~.c1391logplain
-rw-r--r--sqrt~.c2097logplain
-rw-r--r--tabosc4~.c3344logplain
-rw-r--r--tabplay~.c3419logplain
-rw-r--r--tabread.c1331logplain
-rw-r--r--tabread4~.c2592logplain
-rw-r--r--tabread~.c2469logplain
-rw-r--r--tabreceive~.c1529logplain
-rw-r--r--tabsend~.c2378logplain
-rw-r--r--tabwrite.c2150logplain
-rw-r--r--tabwrite~.c3344logplain
-rw-r--r--threshold~.c4223logplain
-rw-r--r--vcf~.c3310logplain
-rw-r--r--vd~.c2547logplain
-rw-r--r--vline~.c4998logplain
-rw-r--r--vsnapshot~.c2082logplain
-rw-r--r--wrap~.c1107logplain
a> 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903
/***************************************************************************
*             __________               __   ___.
*   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
*   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
*   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
*   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
*                     \/            \/     \/    \/            \/
* $Id$
*
* New greyscale framework
* Core & miscellaneous functions
*
* This is a generic framework to display 129 shades of grey on low-depth
* bitmap LCDs (Archos b&w, Iriver & Ipod 4-grey) within plugins.
*
* Copyright (C) 2008 Jens Arnold
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/

#include "plugin.h"
#include "grey.h"

#if defined(HAVE_ADJUSTABLE_CPU_FREQ) && \
    (defined(CPU_PP) || (CONFIG_LCD == LCD_TL0350A))
#define NEED_BOOST
#endif

#ifndef SIMULATOR

#if defined ARCHOS_RECORDER     /* verified */  \
 || defined ARCHOS_FMRECORDER   /* should be identical */  \
 || defined ARCHOS_RECORDERV2   /* should be identical */  \
 || defined ARCHOS_ONDIOFM      /* verified */  \
 || defined ARCHOS_ONDIOSP      /* verified */
/* Average measurements of a Recorder v1, an Ondio FM, a backlight-modded 
 * Ondio FM, and an Ondio SP. */
static const unsigned char lcdlinear[256] = {
  5,   8,  10,  12,  14,  16,  18,  20,  22,  24,  26,  28,  29,  31,  33,  35,
 37,  39,  40,  42,  43,  45,  46,  48,  49,  50,  51,  53,  54,  55,  57,  58,
 59,  60,  61,  62,  63,  64,  65,  66,  67,  68,  68,  69,  70,  71,  71,  72,
 73,  74,  74,  75,  76,  77,  77,  78,  79,  79,  80,  80,  81,  81,  82,  82,
 83,  84,  84,  85,  86,  86,  87,  87,  88,  88,  89,  89,  90,  90,  91,  91,
 92,  92,  93,  93,  94,  94,  95,  95,  96,  96,  97,  98,  98,  99, 100, 100,
101, 101, 102, 103, 103, 104, 105, 105, 106, 106, 107, 107, 108, 108, 109, 109,
110, 110, 111, 112, 112, 113, 114, 114, 115, 115, 116, 117, 117, 118, 119, 119,
120, 120, 121, 122, 123, 123, 124, 125, 126, 126, 127, 128, 129, 129, 130, 131,
132, 132, 133, 134, 135, 135, 136, 137, 138, 138, 139, 140, 140, 141, 141, 142,
143, 144, 145, 146, 147, 147, 148, 149, 150, 151, 152, 153, 154, 154, 155, 156,
157, 158, 159, 160, 161, 161, 162, 163, 164, 165, 166, 167, 168, 168, 169, 170,
171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 184, 185, 186, 187,
188, 189, 191, 192, 194, 195, 197, 198, 199, 200, 202, 203, 204, 205, 207, 208,
209, 210, 212, 213, 215, 216, 218, 219, 220, 221, 222, 223, 225, 226, 227, 228,
229, 230, 232, 233, 234, 235, 237, 238, 239, 240, 242, 243, 244, 246, 247, 248
};
/* The actual LCD scanrate varies a lot with temperature on these targets */
#define LCD_SCANRATE 67 /* Hz */

#elif defined IAUDIO_M3         /* verified */
/* Average measurements of 2 iAudio remotes connected to an M3. */
static const unsigned char lcdlinear[256] = {
  5,   9,  13,  17,  21,  26,  30,  34,  38,  42,  46,  50,  54,  58,  62,  66,
 70,  73,  76,  78,  80,  82,  84,  86,  88,  90,  91,  92,  94,  95,  96,  97,
 98,  99,  99, 100, 101, 102, 102, 103, 104, 104, 105, 105, 106, 107, 107, 108,
109, 109, 110, 110, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116,
117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 121, 122, 122, 123, 123, 123,
124, 124, 124, 125, 125, 126, 126, 126, 127, 127, 127, 128, 128, 129, 129, 129,
130, 130, 131, 131, 132, 132, 133, 133, 134, 134, 134, 135, 135, 136, 136, 136,
137, 137, 137, 138, 138, 139, 139, 139, 140, 140, 141, 141, 142, 142, 143, 143,
144, 144, 145, 145, 146, 147, 147, 148, 149, 149, 150, 150, 151, 151, 152, 152,
153, 153, 154, 154, 155, 155, 156, 156, 157, 157, 158, 158, 159, 160, 160, 161,
162, 162, 163, 164, 164, 165, 166, 167, 168, 168, 169, 169, 170, 171, 171, 172,
173, 173, 174, 175, 176, 176, 177, 178, 179, 179, 180, 181, 182, 182, 183, 184,
185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 198, 199, 200, 201,
202, 203, 204, 205, 207, 208, 209, 210, 211, 212, 213, 214, 216, 217, 218, 219,
220, 221, 222, 223, 225, 226, 227, 228, 229, 230, 231, 232, 234, 235, 236, 237,
238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 249, 250, 251, 252
};
/* The actual LCD scanrate is 3x as high, but 150 Hz or 75 Hz cause a too high
 * CPU load (> 50 %). Even at 50Hz, greyscale display is rather smooth. Average
 * from 2 iAudio remotes. */
#define LCD_SCANRATE 50 /* Hz */

#elif defined IAUDIO_M5         /* verified */
/* Measurement of one iAudio M5L */
static const unsigned char lcdlinear[256] = {
  4,   6,   8,  10,  11,  13,  15,  17,  19,  21,  22,  24,  25,  27,  28,  30,
 32,  33,  35,  36,  37,  39,  40,  42,  43,  44,  45,  46,  48,  49,  50,  51,
 52,  52,  53,  54,  55,  55,  56,  57,  58,  58,  59,  60,  61,  61,  62,  63,
 64,  64,  65,  65,  66,  66,  67,  67,  68,  68,  69,  70,  70,  71,  72,  72,
 73,  73,  74,  75,  75,  76,  77,  77,  78,  78,  79,  79,  80,  80,  81,  81,
 82,  82,  83,  84,  84,  85,  86,  86,  87,  87,  88,  89,  89,  90,  91,  91,
 92,  92,  93,  93,  94,  94,  95,  95,  96,  96,  97,  98,  98,  99, 100, 100,
101, 101, 102, 102, 103, 103, 104, 104, 105, 105, 106, 106, 107, 107, 108, 108,
109, 109, 110, 110, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116,
117, 117, 118, 119, 119, 120, 121, 121, 122, 122, 123, 124, 124, 125, 126, 126,
127, 127, 128, 129, 130, 130, 131, 132, 133, 133, 134, 135, 135, 136, 137, 137,
138, 139, 140, 141, 142, 142, 143, 144, 145, 146, 147, 148, 149, 149, 150, 151,
152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 163, 164, 165, 167, 168, 169,
170, 172, 173, 175, 177, 179, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198,
200, 202, 204, 205, 207, 209, 210, 212, 214, 216, 218, 219, 221, 223, 224, 226,
228, 230, 231, 233, 235, 236, 237, 239, 241, 243, 244, 246, 248, 249, 250, 252
};
#define LCD_SCANRATE 73 /* Hz */

#elif defined IPOD_1G2G         /* verified */
/* Average measurements of an iPod 1st Gen (0x00010001) and an iPod 2nd Gen
 * (0x00020000), measured with both backlight off & backlight on (flipped
 * curves) and medium load (white background when measuring with backlight on),
 * as the curve is load dependent (the controller's step-up converter doesn't
 * provide enough juice). Table is for backlight_off state. */
static const unsigned char lcdlinear[256] = {
  4,   6,   8,   9,  11,  13,  14,  16,  17,  18,  20,  21,  23,  24,  26,  27,
 29,  30,  31,  32,  34,  35,  36,  37,  38,  39,  40,  41,  41,  42,  43,  44,
 45,  45,  46,  47,  47,  48,  49,  49,  50,  50,  51,  51,  52,  52,  53,  53,
 54,  54,  54,  55,  55,  56,  56,  56,  57,  57,  57,  58,  58,  59,  59,  59,
 60,  60,  60,  61,  61,  62,  62,  62,  63,  63,  63,  64,  64,  65,  65,  65,
 66,  66,  67,  67,  68,  68,  69,  69,  70,  70,  71,  71,  72,  72,  73,  73,
 74,  74,  74,  75,  75,  76,  76,  76,  77,  77,  78,  78,  79,  79,  80,  80,
 81,  81,  82,  82,  83,  83,  84,  84,  85,  85,  86,  86,  87,  87,  88,  88,
 89,  89,  90,  91,  92,  92,  93,  94,  95,  95,  96,  97,  97,  98,  99,  99,
100, 100, 101, 102, 102, 103, 104, 104, 105, 105, 106, 107, 107, 108, 109, 109,
110, 110, 111, 112, 113, 113, 114, 115, 116, 116, 117, 118, 119, 119, 120, 121,
122, 122, 123, 124, 125, 125, 126, 127, 128, 129, 130, 131, 131, 132, 133, 134,
135, 137, 138, 139, 141, 142, 144, 145, 146, 147, 149, 150, 151, 152, 154, 155,
156, 158, 159, 161, 162, 164, 165, 167, 169, 171, 172, 174, 175, 177, 178, 180,
182, 184, 186, 188, 189, 191, 193, 195, 197, 199, 201, 203, 206, 208, 210, 212,
214, 217, 219, 221, 224, 226, 229, 231, 233, 236, 238, 240, 243, 245, 247, 250
};
/* Average from an iPod 1st Gen and an iPod 2nd Gen */
#define LCD_SCANRATE 96 /* Hz */

#elif defined IPOD_MINI2G       /* verified */  \
   || defined IPOD_MINI         /* should be identical */  \
   || defined IPOD_3G           /* TODO: verify */  \
   || defined IPOD_4G           /* TODO: verify */
/* Measurement of one iPod Mini G2 */
static const unsigned char lcdlinear[256] = {
  2,   5,   7,  10,  12,  15,  17,  20,  22,  24,  26,  28,  30,  32,  34,  36,
 38,  40,  41,  42,  44,  45,  46,  47,  48,  49,  50,  50,  51,  52,  52,  53,
 54,  54,  55,  55,  56,  56,  57,  57,  58,  58,  58,  59,  59,  60,  60,  60,
 61,  61,  61,  62,  62,  63,  63,  63,  64,  64,  64,  64,  65,  65,  65,  65,
 66,  66,  66,  66,  67,  67,  67,  67,  68,  68,  68,  68,  69,  69,  69,  69,
 70,  70,  70,  70,  71,  71,  71,  71,  72,  72,  72,  73,  73,  74,  74,  74,
 75,  75,  75,  75,  76,  76,  76,  76,  77,  77,  77,  78,  78,  79,  79,  79,
 80,  80,  80,  81,  81,  82,  82,  82,  83,  83,  83,  84,  84,  85,  85,  85,
 86,  86,  86,  87,  87,  88,  88,  88,  89,  89,  90,  90,  91,  91,  92,  92,
 93,  93,  94,  94,  95,  95,  96,  96,  97,  97,  98,  99,  99, 100, 101, 101,
102, 102, 103, 104, 104, 105, 106, 106, 107, 108, 109, 110, 110, 111, 112, 113,
114, 115, 115, 116, 117, 118, 118, 119, 120, 121, 121, 122, 123, 124, 124, 125,
126, 127, 128, 129, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140,
141, 142, 143, 144, 146, 147, 148, 149, 150, 151, 153, 154, 155, 156, 158, 159,
160, 162, 163, 165, 166, 168, 169, 171, 172, 175, 177, 180, 182, 185, 187, 190,
192, 196, 199, 203, 206, 210, 213, 217, 220, 223, 227, 230, 234, 238, 242, 246
};
/* Average of an iPod Mini G2 and 2 3rd Gen iPods. */
#define LCD_SCANRATE 87 /* Hz */

#elif defined IRIVER_H100_SERIES /* verified */
/* Measurement of one Iriver H140 */
static const unsigned char lcdlinear[256] = {
  5,   8,  12,  15,  18,  22,  25,  28,  31,  34,  36,  39,  42,  44,  47,  50,
 53,  55,  57,  59,  62,  64,  66,  68,  70,  71,  72,  73,  75,  76,  77,  78,
 79,  80,  80,  81,  82,  83,  83,  84,  85,  85,  86,  86,  87,  87,  88,  88,
 89,  89,  90,  90,  91,  91,  92,  92,  93,  93,  93,  94,  94,  95,  95,  95,
 96,  96,  96,  97,  97,  98,  98,  98,  99,  99,  99, 100, 100, 101, 101, 101,
102, 102, 102, 103, 103, 104, 104, 104, 105, 105, 106, 106, 107, 107, 108, 108,
109, 109, 109, 110, 110, 111, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115,
116, 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123,
124, 124, 125, 125, 126, 127, 127, 128, 129, 129, 130, 130, 131, 131, 132, 132,
133, 133, 134, 135, 135, 136, 137, 137, 138, 138, 139, 139, 140, 140, 141, 141,
142, 142, 143, 143, 144, 145, 145, 146, 147, 147, 148, 148, 149, 150, 150, 151,
152, 152, 153, 153, 154, 155, 155, 156, 157, 157, 158, 159, 160, 160, 161, 162,
163, 164, 165, 166, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177,
178, 179, 181, 182, 183, 184, 186, 187, 188, 189, 191, 192, 193, 194, 196, 197,
198, 200, 202, 203, 205, 207, 208, 210, 212, 214, 215, 217, 218, 220, 221, 223,
224, 226, 228, 229, 231, 233, 235, 236, 238, 240, 241, 242, 244, 245, 246, 248
};
#define LCD_SCANRATE 70 /* Hz */

#elif defined MROBE_100 /* verified */
/* Average measurements of 2 m:robe 100 s */
static const unsigned char lcdlinear[256] = {
 10,  14,  18,  22,  26,  30,  34,  38,  42,  46,  49,  53,  56,  60,  63,  67,
 70,  73,  76,  79,  81,  84,  87,  90,  92,  95,  97, 100, 102, 105, 107, 110,
112, 114, 116, 118, 119, 121, 123, 125, 126, 128, 130, 131, 133, 135, 136, 138,
139, 141, 142, 143, 144, 146, 147, 148, 149, 150, 151, 152, 154, 155, 156, 157,
158, 159, 160, 161, 161, 162, 163, 164, 165, 166, 167, 168, 168, 169, 170, 171,
172, 172, 173, 173, 174, 174, 175, 175, 176, 176, 177, 178, 178, 179, 180, 180,
181, 181, 182, 182, 183, 183, 184, 184, 185, 185, 186, 186, 187, 187, 188, 188,
189, 189, 190, 190, 191, 191, 192, 192, 193, 193, 193, 194, 194, 195, 195, 195,
196, 196, 197, 197, 198, 198, 199, 199, 200, 200, 200, 201, 201, 202, 202, 202,
203, 203, 204, 204, 205, 205, 206, 206, 207, 207, 207, 208, 208, 209, 209, 209,
210, 210, 210, 211, 211, 212, 212, 212, 213, 213, 213, 214, 214, 215, 215, 215,
216, 216, 216, 217, 217, 218, 218, 218, 219, 219, 219, 220, 220, 221, 221, 221,
222, 222, 222, 223, 223, 224, 224, 224, 225, 225, 225, 226, 226, 227, 227, 227,
228, 228, 229, 229, 230, 230, 231, 231, 232, 232, 232, 233, 233, 234, 234, 234,
235, 235, 235, 236, 236, 237, 237, 237, 238, 238, 238, 239, 239, 240, 240, 240,
241, 241, 242, 242, 243, 243, 244, 244, 247, 248, 248, 249, 250, 250, 251, 252
};
#define LCD_SCANRATE 51 /* Hz */

#else  /* not yet calibrated targets - generic linear mapping */
/* TODO: calibrate iFP7xx */
static const unsigned char lcdlinear[256] = {
  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,
 16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,  30,  31,
 32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,
 48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,
 64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,
 80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,
 96,  97,  98,  99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
};
/* generic default */
#define LCD_SCANRATE 70 /* Hz */

#endif
#else /* SIMULATOR */
/* undo a (generic) PC display gamma of 2.0 to simulate target behaviour */
static const unsigned char lcdlinear[256] = {
  0,  16,  23,  28,  32,  36,  39,  42,  45,  48,  50,  53,  55,  58,  60,  62,
 64,  66,  68,  70,  71,  73,  75,  77,  78,  80,  81,  83,  84,  86,  87,  89,
 90,  92,  93,  94,  96,  97,  98, 100, 101, 102, 103, 105, 106, 107, 108, 109,
111, 112, 113, 114, 115, 116, 117, 118, 119, 121, 122, 123, 124, 125, 126, 127,
128, 129, 130, 131, 132, 133, 134, 135, 135, 136, 137, 138, 139, 140, 141, 142,
143, 144, 145, 145, 146, 147, 148, 149, 150, 151, 151, 152, 153, 154, 155, 156,
156, 157, 158, 159, 160, 160, 161, 162, 163, 164, 164, 165, 166, 167, 167, 168,
169, 170, 170, 171, 172, 173, 173, 174, 175, 176, 176, 177, 178, 179, 179, 180,
181, 181, 182, 183, 183, 184, 185, 186, 186, 187, 188, 188, 189, 190, 190, 191,
192, 192, 193, 194, 194, 195, 196, 196, 197, 198, 198, 199, 199, 200, 201, 201,
202, 203, 203, 204, 204, 205, 206, 206, 207, 208, 208, 209, 209, 210, 211, 211,
212, 212, 213, 214, 214, 215, 215, 216, 217, 217, 218, 218, 219, 220, 220, 221,
221, 222, 222, 223, 224, 224, 225, 225, 226, 226, 227, 228, 228, 229, 229, 230,
230, 231, 231, 232, 233, 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238,
239, 240, 240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 247,
247, 248, 248, 249, 249, 250, 250, 251, 251, 252, 252, 253, 253, 254, 254, 255
};
#endif /* SIMULATOR */

/* Prototypes */
static inline void _deferred_update(void) __attribute__ ((always_inline));
static int exp_s16p16(int x);
static int log_s16p16(int x);
static void grey_screendump_hook(int fd);
static void fill_gvalues(void);
#ifdef SIMULATOR
static unsigned long _grey_get_pixel(int x, int y);
#else
static void _timer_isr(void);
#endif


#if defined(HAVE_BACKLIGHT_INVERSION) && !defined(SIMULATOR)
static void invert_gvalues(void)
{
    unsigned char *val, *end;
    unsigned char rev_tab[256];
    unsigned i;
    unsigned last_i = 0;
    unsigned x = 0;
    unsigned last_x;
    
    /* Step 1: Calculate a transposed table for undoing the old mapping */
    for (i = 0; i < 256; i++)
    {
        last_x = x;
        x = _grey_info.gvalue[i];
        if (x > last_x)
        {
            rev_tab[last_x++] = (last_i + i) / 2;
            while (x > last_x)
                rev_tab[last_x++] = i;
            last_i = i;
        }
    }
    rev_tab[last_x++] = (last_i + 255) / 2;
    while (256 > last_x)
        rev_tab[last_x++] = 255;

    /* Step 2: Calculate new mapping */
    fill_gvalues();

    /* Step 3: Transpose all pixel values */
    val = _grey_info.values;
    end = val + _GREY_MULUQ(_grey_info.width, _grey_info.height);

    do
        *val = _grey_info.gvalue[rev_tab[*val]];
    while (++val < end);
}
#endif

/* Update LCD areas not covered by the greyscale overlay */
static inline void _deferred_update(void)
{
    int x1 = MAX(_grey_info.x, 0);
    int x2 = MIN(_grey_info.x + _grey_info.width, LCD_WIDTH);
    int y1 = MAX(_grey_info.y, 0);
    int y2 = MIN(_grey_info.y + _grey_info.height, LCD_HEIGHT);

    if (y1 > 0)  /* refresh part above overlay, full width */
        _grey_info.rb->lcd_update_rect(0, 0, LCD_WIDTH, y1);

    if (y2 < LCD_HEIGHT) /* refresh part below overlay, full width */
        _grey_info.rb->lcd_update_rect(0, y2, LCD_WIDTH, LCD_HEIGHT - y2);

    if (x1 > 0) /* refresh part to the left of overlay */
        _grey_info.rb->lcd_update_rect(0, y1, x1, y2 - y1);

    if (x2 < LCD_WIDTH) /* refresh part to the right of overlay */
        _grey_info.rb->lcd_update_rect(x2, y1, LCD_WIDTH - x2, y2 - y1);
}

#ifdef SIMULATOR

/* Callback function for grey_ub_gray_bitmap_part() to read a pixel from the
 * greybuffer. Note that x and y are in LCD coordinates, not greybuffer
 * coordinates! */
static unsigned long _grey_get_pixel(int x, int y)
{
    int xg = x - _grey_info.x;
    int yg = y - _grey_info.y;
#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
    int idx = _grey_info.width * yg + xg;
#else /* vertical packing or vertical interleaved */
    int idx = _grey_info.width * (yg & ~_GREY_BMASK) 
            + (xg << _GREY_BSHIFT) + (~yg & _GREY_BMASK);
#endif

    return _grey_info.values[idx] + (1 << LCD_DEPTH);
}

#else /* !SIMULATOR */

/* Timer interrupt handler: display next frame */
static void _timer_isr(void)
{
#if defined(HAVE_BACKLIGHT_INVERSION) && !defined(SIMULATOR)
    unsigned long check = _grey_info.rb->is_backlight_on(true) 
                        ? 0 : _GREY_BACKLIGHT_ON;
    
    if ((_grey_info.flags & (_GREY_BACKLIGHT_ON|GREY_RAWMAPPED)) == check)
    {
        _grey_info.flags ^= _GREY_BACKLIGHT_ON;
        invert_gvalues();
        return; /* don't overload this timer slot */
    }
#endif
#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
    _grey_info.rb->lcd_blit_grey_phase(_grey_info.values, _grey_info.phases,
                                       _grey_info.bx, _grey_info.y,
                                       _grey_info.bwidth, _grey_info.height,
                                       _grey_info.width);
#else /* vertical packing or vertical interleaved */
    _grey_info.rb->lcd_blit_grey_phase(_grey_info.values, _grey_info.phases,
                                       _grey_info.x, _grey_info.by,
                                       _grey_info.width, _grey_info.bheight,
                                       _grey_info.width);
#endif

    if (_grey_info.flags & _GREY_DEFERRED_UPDATE) /* lcd_update() requested? */
    {
        _deferred_update();
        _grey_info.flags &= ~_GREY_DEFERRED_UPDATE; /* clear request */
    }
}

#endif /* !SIMULATOR */

/* fixed point exp() */
static int exp_s16p16(int x)
{
    int t;
    int y = 0x00010000;

    if (x < 0) x += 0xb1721,            y >>= 16;
    t = x - 0x58b91; if (t >= 0) x = t, y <<= 8;
    t = x - 0x2c5c8; if (t >= 0) x = t, y <<= 4;
    t = x - 0x162e4; if (t >= 0) x = t, y <<= 2;