Как стать автором
Обновить
1
0

Пользователь

Отправить сообщение

В свое время (в 90-х) так же пришлось много поковыряться с файловыми системами используя DE. Очень привык к его функциям и интерфейсу. Потом открыл для себя программу DMDE. Помню радовался как ребенок давно знакомому функционалу, но на новом уровне. Это как открыть для себя Far после NC.

Кстати, напомнили. В начале 90-х в качестве эксперимента подключал MFM HDD от искры 1030 на 10 МБайт к контроллеру RLL от какого то импортного диска. Он даже отформатировался на 15 МБайт. Но был один нюанс. Диски тогда прилично грелись и отформатированный на холодную (сразу после включения) диск после прогрева начинал дико сбоить. Если отформатировать уже прогревшийся диск, то при следующем включении, (пока он холодный) он так же сбоил и загрузиться с него было нельзя. Поэтому приходилось включать диск и ждать пока он прогреется и только после этого загружать DOS. Но лишние мегабайты на диске того стоили. Понятно, что ничего ценного на диске не хранилось.
Да, по обращениям к памяти LZSS конечно тяжелее. Сейчас на быстрых RISC контроллерах это особенно заметно. Раньше на медленных CISC один-два лишних такта на команду не так заметно было.
А в комментарии я имел ввиду что RLE и LZSS (и подобные ему) примерно одинаковы по накладным расходам в сравнении с другими более сложными алгоритмами распаковки.
получается что это работает быстрее, чем RLE за счет того что можно не копировать неизмененные данные.
Распаковка LZSS и RLE по скорости примерно одинаковы. В обоих случаях в выходной буфер должны попасть все данные, а накладные расходы близки.
Как раз вчера сделал декодер RLE в программный фреймбуфер, который потом отсылается в экран.
RLE последовательно только пишет в выходной буфер и не читает из него, так что можно этот поток без проблем писать как в программный так и в аппаратный фреймбуфер. Для LZSS же нужен промежуточный буфер на размер окна кодирования из которого уже можно гнать поток во фреймбуфер.
получилось примерно 18 мс на картинку размером 240*240 16битный цвет
кстати, при использовании изображения с большим количеством цветов что RLE, что LZSS не смогут нормально сжать. Если фактически использовалась картинка только с несколькими цветами, то выгоднее использовать палитру, т.е. индексы цвета меньшей разрядности. Один раз в исходных данных записать соответствие, а далее, в самой картинке, в качестве цвета уже указывать индекс.
либо копирует ранее распакованную цепочку из выходного буфера опять во входной
Извините, описка получилась. Правильно будет:
либо копирует ранее распакованную цепочку из выходного буфера опять в выходной
а почему цепочку сразу нельзя писать в буфер, ведь по сути мы получаем N раз повторить байт M. вроде логично, сразу писать и можно сэкономить немного памяти.
Это будет алгоритм RLE. Он просто пакует повторяющиеся пиксели одного цвета в команды.
LZSS при разжатии либо копирует данные из входного буфера в выходной, либо копирует ранее распакованную цепочку из выходного буфера опять во входной, т.е. нужен произвольный доступ к выходному буферу. Можно ограничить размер выходного буфера размером используемого окна, т.е. максимальным смещением в команде копирования ранее распакованной цепочки.
Существующий в ЖКИ фреймбуфер использовать для этих целей скорее всего не получится. Программный фреймбуфер использовать можно, но это скорее всего усложнит и замедлит декодер.
Программы сжатия на PC и разжатия в контроллере были самописные. Кодирование команд так же свое, заточенное под небольшой размер спрайта. От алгоритма LZSS была взята сама идея повторного использования цепочек данных. Описывать ее здесь смысла нет. Можно почитать, например здесь.

Буфер для разжатого изображения нужно иметь по самой сути LZSS. Он берет оттуда повторяющиеся цепочки данных. Динамически я его не выделял, просто фиксированный буфер под самый большой используемый спрайт.

Главная особенность LZSS — то что он асимметричный. При сравнительно сложном кодере он имеет простой и очень быстрый декодер.

Основное отличие моей реализации LZSS — кодирование команд в потоке заточенное под конкретное применение. Если интересно — распишу подробнее команды и реализацию.
LZSS (это модификация LZ77) тоже древний алгоритм. Тот пример сжатия что я приводил (из своих исходников почти 20 летней давности) без проблем работал на 16-битном контроллере на 16 МГц. Сжатие RLE используемое в PCX не так эффективно для мелких черно-белых спрайтов, а остальные возможности PCX для черно-белых изображений и не нужны.
Хороший редактор. Я в свое время для работы со шрифтами и спрайтами пользовался мелкими самописными утилитками. По тому опыту работы есть парочка предложений в функционал программы:

1. Добавить в генерацию кода на С вариант вывода данных в «графическом» виде:
типа такого
________,________,
________,________,
____OO__,________,
___OOO__,________,
_OOOOO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
_OOOOOOO,O_______,
________,________,
________,________,

________,________,
________,________,
___OOOO_,________,
__OO__OO,________,
_OO____O,O_______,
_OO____O,O_______,
_______O,O_______,
_______O,O_______,
______OO,________,
_____OO_,________,
____OO__,________,
___OO___,________,
__OO____,________,
_OO_____,________,
_OO_____,________,
_OOOOOOO,O_______,
________,________,
________,________,

________,________,
________,________,
___OOOO_,________,
__OO__OO,________,
_OO____O,O_______,
_OO____O,O_______,
_______O,O_______,
______OO,________,
___OOOOO,________,
______OO,________,
_______O,O_______,
_______O,O_______,
_OO____O,O_______,
_OO____O,O_______,
__OO__OO,________,
___OOOO_,________,
________,________,
________,________,


Для этого всего лишь требуется определить
небольшую таблицу
#define	________	0
#define	_______O	1
#define	______O_	2
#define	______OO	3
#define	_____O__	4
#define	_____O_O	5
#define	_____OO_	6
#define	_____OOO	7
#define	____O___	8
#define	____O__O	9
#define	____O_O_	10
#define	____O_OO	11
#define	____OO__	12
#define	____OO_O	13
#define	____OOO_	14
#define	____OOOO	15
#define	___O____	16
#define	___O___O	17
#define	___O__O_	18
#define	___O__OO	19
#define	___O_O__	20
#define	___O_O_O	21
#define	___O_OO_	22
#define	___O_OOO	23
#define	___OO___	24
#define	___OO__O	25
#define	___OO_O_	26
#define	___OO_OO	27
#define	___OOO__	28
#define	___OOO_O	29
#define	___OOOO_	30
#define	___OOOOO	31

и т.д. до 255


2. В этой программе кроме шрифтов можно создавать и спрайты, в том числе для анимации (по типу приведенной в статье). Для этих целей максимальный размер «символа» хорошо бы увеличить хотя бы до 320x240.

3. Для шрифтов больших размеров и спрайтов уже может быть актуально применять сжатие для экономии места. Алгоритм LZSS (c измененным кодированием) неплохо подходит для этого.
Например здесь экономия порядка 3-х кратной получалась
//const char spBigMicro_Data[] = {	/* Size:120 */
/*________,________,________,________,	//1
________,________,________,________,	//2
________,________,________,________,	//3
________,________,________,________,	//4
________,________,________,________,	//5
________,________,________,________,	//6
________,________,________,________,	//7
________,________,________,________,	//8
_____OOO,OOO_____,__OOOOOO,________,	//9
_____OOO,OOO_____,__OOOOOO,________,	//10
_____OOO,OOO_____,__OOOOOO,________,	//11
_____OOO,OOO_____,__OOOOOO,________,	//12
_____OOO,OOO_____,__OOOOOO,________,	//13
_____OOO,OOO_____,__OOOOOO,________,	//14
_____OOO,OOO_____,__OOOOOO,________,	//15
_____OOO,OOO_____,__OOOOOO,________,	//16
_____OOO,OOO_____,__OOOOOO,________,	//17
_____OOO,OOO_____,__OOOOOO,________,	//18
_____OOO,OOO_____,__OOOOOO,________,	//19
_____OOO,OOO_____,__OOOOOO,________,	//20
_____OOO,OOO_____,__OOOOOO,________,	//21
_____OOO,OOO_____,__OOOOOO,________,	//22
_____OOO,OOO_____,__OOOOOO,________,	//23
____OOOO,OOO_____,_OOOOOOO,________,	//24
____OOOO,OOOO____,_OOOOOOO,________,	//25
___OOOOO,OOOOO___,OOOOOOOO,________,	//26
_OOOOOOO,OOOOOOOO,OOOOOOOO,________,	//27
OOOOOOO_,OOOOOOOO,OO_OOOOO,________,	//28
OOOOOO__,_OOOOOOO,O__OOOOO,________,	//29
_OOOO___,__OOOOO_,___OOOOO,________ 	//30
};
const struct TSprite spBigMicro = {27,30,COMPRESS_NONE,spBigMicro_Data};
*/
const char spBigMicro_Data[] = {	/* Size:42 (35%) */
0x28,0x00,
0x00,0xF0,0xE0,0x02,0x07,0xE0,0x3F,0xF3,0xF3,0xF3,0x83,0x02,0x0F,0xE0,0x7F,0x13,
0x00,0xF0,0x13,0x05,0x1F,0xF8,0xFF,0x00,0x7F,0xFF,0x13,0x0B,0xFE,0xFF,0xDF,0x00,
0xFC,0x7F,0x9F,0x00,0x78,0x3E,0x1F,0x00};
const struct TSprite spBigMicro = {27,30,COMPRESS_LZSS,spBigMicro_Data};

//------------------------------------------------------------------

//const char spBigMili_Data[] = {	/* Size:120 */
/*________,________,________,________,	//1
________,________,________,________,	//2
________,________,________,________,	//3
________,________,________,________,	//4
________,________,________,________,	//5
________,________,________,________,	//6
________,________,________,________,	//7
________,OOOOO___,___OOOOO,________,	//8
OOOOO__O,OOOOOOO_,__OOOOOO,OO______,	//9
OOOOO_OO,OOOOOOOO,_OOOOOOO,OOO_____,	//10
OOOOOOOO,OOOOOOOO,OOOOOOOO,OOO_____,	//11
OOOOOOOO,__OOOOOO,OOO__OOO,OOOO____,	//12
OOOOOOO_,___OOOOO,OO____OO,OOOO____,	//13
OOOOOOO_,___OOOOO,OO____OO,OOOO____,	//14
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//15
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//16
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//17
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//18
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//19
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//20
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//21
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//22
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//23
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//24
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//25
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//26
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//27
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//28
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//29
OOOOOO__,___OOOOO,O_____OO,OOOO____ 	//30
};
const struct TSprite spBigMili = {31,30,COMPRESS_NONE,spBigMili_Data};
*/
const char spBigMili_Data[] = {	/* Size:36 (30%) */
0x22,0x00,
0x00,0xF0,0xB0,0x0B,0xF8,0x1F,0x00,0xF9,0xFE,0x3F,0xC0,0xFB,0xFF,0x7F,0xE0,0xFF,
0x10,0x13,0x05,0x3F,0xE7,0xF0,0xFE,0x1F,0xC3,0x43,0x02,0xFC,0x1F,0x83,0xF3,0xF3,
0xF3,0xC3};
const struct TSprite spBigMili = {31,30,COMPRESS_LZSS,spBigMili_Data};

я хотел бы найти дешевое и быстрое устройство Sample-and-Hold, желательно в DIP корпусе, но поиск выдает в основном микросхемы вроде LF398 с временем выборки в 10 мкс. Не нужен быстрый АЦП, нужно лишь быстрое устройство S-and-H и АЦП от Ардуино. Не знаете ли вы таких устройств?

Время дискретных микросхем выборки-хранения ушло. Теперь во многих скоростных АЦП есть встроенная S&H. У этих АЦП получается малое время выборки, а аналоговая полоса сигнала больше максимальной частоты преобразования. Это позволяет оцифровывать сигналы выше частоты преобразования АЦП.
Сейчас ничего не мешает сделать S&H на «рассыпухе». Нужен быстрый ключ, мелкая емкость и буфер с большим входным сопротивлением. Да, и еще чуть чуть мелкой логики, которая будет этим управлять. Все доступно и сравнительно недорого.
Прямо ностальгия на тему «Частотомер — цифровая шкала». Прескалер у PIC-ов тоже хорошо частоту держал.
цифровые потенциометры — схемы совмещающие датчик и АЦП/ЦАП используемые как датчики температуры.

Цифровой потенциометр — это разновидность ЦАПа, предназначенного, в частности, для замены обычных потенциометров. Никакого отношения к АЦП и датчикам он не имеет.
Видимо Вы имели ввиду именно датчики физических величин с цифровым выходом.
Извините, хабр не дает просто плюсануть комментарий.
Полностью с Вами согласен. Без конкретных условий реализации это разговор ни о чем.
Если Вам совсем непонятно, то мой исходный комментарий:
Раньше было популярно кодировать шрифты (и не только) по типу фрагмента под спойлером. И не надо было никаких комментариев с картинками и редактировать удобно.

относился вот к этой картинке автора статьи
картинка автора статьи
image

А я имел в виду вот такое кодирование (специально для делающих вид что не понимают о чем речь, те же символы и без указания каких-либо структур для хранения:
вариант кодирования
________,________,
OO______,________,
OO______,________,
OO______,________,
OO______,________,
OO______,________,
OO______,________,
OO______,________,
OO______,________,
OO______,________,
OO______,________,
OO______,________,
OO______,________,
OOOOOOOO,________,
OOOOOOOO,________,
________,________,

________,________,
OOO_____,__OOO___,
OOOO____,_OOOO___,
OOOO____,_OOOO___,
OOOO____,_OOOO___,
OO_OO___,OO_OO___,
OO_OO___,OO_OO___,
OO_OO___,OO_OO___,
OO_OO___,OO_OO___,
OO__OO_O,O__OO___,
OO__OO_O,O__OO___,
OO__OO_O,O__OO___,
OO___O_O,___OO___,
OO___OOO,___OO___,
OO___OOO,___OO___,
________,________,

________,________,
OO______,_OO_____,
OOO_____,_OO_____,
OOOO____,_OO_____,
OOOO____,_OO_____,
OO_OO___,_OO_____,
OO__OO__,_OO_____,
OO__OO__,_OO_____,
OO___OO_,_OO_____,
OO___OO_,_OO_____,
OO____OO,_OO_____,
OO_____O,OOO_____,
OO_____O,OOO_____,
OO______,OOO_____,
OO______,_OO_____,
________,________,


Можете высказать претензии автору статьи, что он хранит данные неоптимально. Я здесь вообще о хранении даже не упоминал.

PS. Буквально пару замечаний напоследок.

Судя по приведенным числам Вы храните битовый массив посимвольно,…

Нет, посимвольно и к тому же битовым массивом,…

Хм. Я же вроде так и написал? По приведенным Вами байтикам как раз сразу стало понятно как Вы храните данные символа.

Что касается скорости работы в попиксельном режиме, то для цветного экрана, где один пиксель это 1-3 байта это будет оптимальный способ. Для монохромного экрана работа сразу со строкой символа будет в разы быстрее попиксельного режима. С этим надеюсь согласитесь?

Что касается экономии места, занимаемого крупными шрифтами и графикой (спрайтами) то сжатие тем же LZSS адаптированным под небольшой размер блока достаточно эффективно. Вот пример из того же исходника что и в первом комментарии. Экономия порядка 3-х кратной.
Пример
//const char spBigMicro_Data[] = {	/* Size:120 */
/*________,________,________,________,	//1
________,________,________,________,	//2
________,________,________,________,	//3
________,________,________,________,	//4
________,________,________,________,	//5
________,________,________,________,	//6
________,________,________,________,	//7
________,________,________,________,	//8
_____OOO,OOO_____,__OOOOOO,________,	//9
_____OOO,OOO_____,__OOOOOO,________,	//10
_____OOO,OOO_____,__OOOOOO,________,	//11
_____OOO,OOO_____,__OOOOOO,________,	//12
_____OOO,OOO_____,__OOOOOO,________,	//13
_____OOO,OOO_____,__OOOOOO,________,	//14
_____OOO,OOO_____,__OOOOOO,________,	//15
_____OOO,OOO_____,__OOOOOO,________,	//16
_____OOO,OOO_____,__OOOOOO,________,	//17
_____OOO,OOO_____,__OOOOOO,________,	//18
_____OOO,OOO_____,__OOOOOO,________,	//19
_____OOO,OOO_____,__OOOOOO,________,	//20
_____OOO,OOO_____,__OOOOOO,________,	//21
_____OOO,OOO_____,__OOOOOO,________,	//22
_____OOO,OOO_____,__OOOOOO,________,	//23
____OOOO,OOO_____,_OOOOOOO,________,	//24
____OOOO,OOOO____,_OOOOOOO,________,	//25
___OOOOO,OOOOO___,OOOOOOOO,________,	//26
_OOOOOOO,OOOOOOOO,OOOOOOOO,________,	//27
OOOOOOO_,OOOOOOOO,OO_OOOOO,________,	//28
OOOOOO__,_OOOOOOO,O__OOOOO,________,	//29
_OOOO___,__OOOOO_,___OOOOO,________ 	//30
};
const struct TSprite spBigMicro = {27,30,COMPRESS_NONE,spBigMicro_Data};
*/
const char spBigMicro_Data[] = {	/* Size:42 (35%) */
0x28,0x00,
0x00,0xF0,0xE0,0x02,0x07,0xE0,0x3F,0xF3,0xF3,0xF3,0x83,0x02,0x0F,0xE0,0x7F,0x13,
0x00,0xF0,0x13,0x05,0x1F,0xF8,0xFF,0x00,0x7F,0xFF,0x13,0x0B,0xFE,0xFF,0xDF,0x00,
0xFC,0x7F,0x9F,0x00,0x78,0x3E,0x1F,0x00};
const struct TSprite spBigMicro = {27,30,COMPRESS_LZSS,spBigMicro_Data};

//------------------------------------------------------------------

//const char spBigMili_Data[] = {	/* Size:120 */
/*________,________,________,________,	//1
________,________,________,________,	//2
________,________,________,________,	//3
________,________,________,________,	//4
________,________,________,________,	//5
________,________,________,________,	//6
________,________,________,________,	//7
________,OOOOO___,___OOOOO,________,	//8
OOOOO__O,OOOOOOO_,__OOOOOO,OO______,	//9
OOOOO_OO,OOOOOOOO,_OOOOOOO,OOO_____,	//10
OOOOOOOO,OOOOOOOO,OOOOOOOO,OOO_____,	//11
OOOOOOOO,__OOOOOO,OOO__OOO,OOOO____,	//12
OOOOOOO_,___OOOOO,OO____OO,OOOO____,	//13
OOOOOOO_,___OOOOO,OO____OO,OOOO____,	//14
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//15
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//16
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//17
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//18
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//19
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//20
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//21
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//22
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//23
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//24
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//25
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//26
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//27
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//28
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//29
OOOOOO__,___OOOOO,O_____OO,OOOO____ 	//30
};
const struct TSprite spBigMili = {31,30,COMPRESS_NONE,spBigMili_Data};
*/
const char spBigMili_Data[] = {	/* Size:36 (30%) */
0x22,0x00,
0x00,0xF0,0xB0,0x0B,0xF8,0x1F,0x00,0xF9,0xFE,0x3F,0xC0,0xFB,0xFF,0x7F,0xE0,0xFF,
0x10,0x13,0x05,0x3F,0xE7,0xF0,0xFE,0x1F,0xC3,0x43,0x02,0xFC,0x1F,0x83,0xF3,0xF3,
0xF3,0xC3};
const struct TSprite spBigMili = {31,30,COMPRESS_LZSS,spBigMili_Data};

Как вы храните шрифт в памяти (в каких структурах, с выравниванием или без) к этому не имеет никакого отношения.

Еще как имеет. В Вашем варианте символ шириной 12 пикс и высотой 16 пикс займет 256 бит (32 байта), в моем — 192 бита (24 байта).

Еще раз приведу то что Вы пропустили:
Я писал всего лишь о кодировании чисел константами. Если написать в исходном коде константу 0x55 как _0_0_0_0, то от этого занимаемый ею объем не изменится. В обоих случаях один байт.

Структура хранения была приведена в исходном примере лишь для пояснения. Считайте что я её не приводил. Смысл комментария был лишь в константах, но никак не в конкретных способах хранения шрифта.

Вот Вам байты символа «открывающая (левая) круглая скобка» шириной 5 пикс и высотой 12 пикс: 0x44,0x88,0x10,0x42,0x08,0x41,0x08,0x02
Можете попробовать перевести это в Ваш вариант крестиков-ноликов и посмотреть что получится

Вы не уточняли структуру хранения массива шрифта. Судя по приведенным числам Вы храните битовый массив посимвольно, я предполагал, что построчно, как в данном фрагменте
Пример символов как на Вашем скриншоте
________,O_______,________,_____O__,________,OOO_____,
________,O_______,________,_____O__,_______O,________,
________,O_______,________,_____O__,_______O,________,
___OOO__,O_OOO___,__OOO___,_OOOOO__,_OOO__OO,OO______,
__O___O_,OO___O__,_O___O__,O____O__,O___O__O,________,
______O_,O_____O_,O______O,_____O_O,____O__O,________,
___OOOO_,O_____O_,O______O,_____O_O,OOOOO__O,________,
__O___O_,O_____O_,O______O,_____O_O,_______O,________,
_O____O_,O_____O_,O______O,_____O_O,_______O,________,
_O___OO_,O____O__,_O___O__,O___OO__,O___O__O,________,
__OOO_O_,OOOOO___,__OOO___,_OOO_O__,_OOO___O,________,
________,________,________,________,________,________,
________,________,________,________,________,________,
________,________,________,________,________,________,



Нет, размер одного и того же шрифта в моем варианте будет меньше, чем в Вашем (который популярен в инете). Даже с учетом доп. таблицы с шириной символов и даже без использования моей возможности ссылок вместо битовых массивов, которые тоже экономят размер — можно убрать из массива изображения как минимум 17 символов в шрифте с латинницей и кириллицей — А, В, С, Е и т.д.

Вы написали хорошую реализацию, которая Вас устроила. Я рад за Вас (кроме шуток). Просто я с Вами и не спорил по этому поводу если что.

PS. Я оценил шутку "(который популярен в инете)", учитывая возраст исходников. :)
Извините, но Вы чушь в данном случае написали. Я писал всего лишь о кодировании чисел константами. Если написать в исходном коде константу 0x55 как _0_0_0_0, то от этого занимаемый ею объем не изменится. В обоих случаях один байт.
Как вы храните шрифт в памяти (в каких структурах, с выравниванием или без) к этому не имеет никакого отношения. Так же, впрочем, как и моноширинность шрифта. В моем примере, кстати, шрифт пропорциональный. Числа 10 между символами как раз определяют ширину конкретного символа. Из этого шрифта у меня реально были только цифры и несколько спец. символов. Остальные шрифты были не шире 8 бит. В данном случае экономить память небыло никакого смысла. Зато использовалась одна общая функция для вывода.

Кстати, в Вашем варианте хранения никто не запрещает записать массив так же в виде констант (разве что он будет слишком широкий). В результате размер получится абсолютно такой же.

Вообще, удобство редактирования шрифта или картинок прямо в коде наступает лет через… надцать после написания кода. Не нужны лишние утилиты для преобразования, можно сразу видеть в исходном коде графику.
Тому фрагменту кода, что я приводил 19 лет от роду.

Вот этому где то 22 года
; 48 '0'
DB __OOOO__
DB _O____O_
DB _O____O_
DB __OOOO__
DB ________
; 49 '1'
DB ________
DB _O___O__
DB _OOOOOO_
DB _O______
DB ________
; 50 '2'
DB _O___O__
DB _OO___O_
DB _O_O__O_
DB _O_O__O_
DB _O__OO__
; 51 '3'
DB __O__O__
DB _O____O_
DB _O__O_O_
DB _O__O_O_
DB __OO_O__
; 52 '4'
DB __OOO___
DB __O__O__
DB __O___O_
DB _OOOOOO_
DB __O_____
; 53 '5'
DB __O_OOO_
DB _O__O_O_
DB _O__O_O_
DB _O__O_O_
DB __OO__O_
; 54 '6'
DB __OOOO__
DB _O__O_O_
DB _O__O_O_
DB _O__O_O_
DB __OO____
; 55 '7'
DB ______O_
DB _OO___O_
DB ___O__O_
DB ____O_O_
DB _____OO_
; 56 '8'
DB __OO_O__
DB _O__O_O_
DB _O__O_O_
DB _O__O_O_
DB __OO_O__
; 57 '9'
DB ____OO__
DB _O_O__O_
DB _O_O__O_
DB _O_O__O_
DB __OOOO__
; 58 ':'
DB ________
DB _OO_OO__
DB _OO_OO__
DB ________
DB ________
; 59 ';'
DB ________
DB O_O_OO__
DB _OO_OO__
DB ________
DB ________
; 60 '<'
DB ________
DB ___O____
DB __O_O___
DB _O___O__
DB ________
; 61 '='
DB ___O_O__
DB ___O_O__
DB ___O_O__
DB ___O_O__
DB ___O_O__
; 62 '>'
DB ________
DB ________
DB _O___O__
DB __O_O___
DB ___O____
; 63 '?'
DB _____O__
DB ______O_
DB _O_O__O_
DB ____O_O_
DB _____O__
; 64 '@'
DB __OOOO__
DB _O____O_
DB _O_OO_O_
DB _O_OO_O_
DB ___OOO__
; 65 'A'
DB _OOOO___
DB ___O_O__
DB ___O__O_
DB ___O_O__
DB _OOOO___
; 66 'B'
DB _OOOOOO_
DB _O__O_O_
DB _O__O_O_
DB _O__O_O_
DB __OO_O__
; 67 'C'
DB __OOOO__
DB _O____O_
DB _O____O_
DB _O____O_
DB __O__O__
; 68 'D'
DB _OOOOOO_
DB _O____O_
DB _O____O_
DB __O__O__
DB ___OO___
; 69 'E'
DB _OOOOOO_
DB _O__O_O_
DB _O__O_O_
DB _O__O_O_
DB _O____O_
; 70 'F'
DB _OOOOOO_
DB ___O__O_
DB ___O__O_
DB ___O__O_
DB ______O_
; 71 'G'
DB __OOOO__
DB _O____O_
DB _O____O_
DB _O_O__O_
DB _OOO_O__
; 72 'H'
DB _OOOOOO_
DB ___O____
DB ___O____
DB ___O____
DB _OOOOOO_
; 73 'I'
DB ________
DB _O____O_
DB _OOOOOO_
DB _O____O_
DB ________
; 74 'J'
DB __O___O_
DB _O____O_
DB _O____O_
DB _O____O_
DB __OOOOO_
; 75 'K'
DB _OOOOOO_
DB ____O___
DB ___O_O__
DB __O___O_
DB _O____O_
; 76 'L'
DB _OOOOOO_
DB _O______
DB _O______
DB _O______
DB _OO_____
; 77 'M'
DB _OOOOOO_
DB _____O__
DB ___OO___
DB _____O__
DB _OOOOOO_
; 78 'N'
DB _OOOOOO_
DB ____O___
DB ___O____
DB __O_____
DB _OOOOOO_
; 79 'O'
DB __OOOO__
DB _O____O_
DB _O____O_
DB _O____O_
DB __OOOO__
; 80 'P'
DB _OOOOOO_
DB ___O__O_
DB ___O__O_
DB ___O__O_
DB ____OO__
; 81 'Q'
DB __OOOO__
DB _O____O_
DB _O_O__O_
DB __O___O_
DB _O_OOO__
; 82 'R'
DB _OOOOOO_
DB ___O__O_
DB ___O__O_
DB __OO__O_
DB _O__OO__
; 83 'S'
DB __O__O__
DB _O__O_O_
DB _O__O_O_
DB _O__O_O_
DB __OO____
; 84 'T'
DB ______O_
DB ______O_
DB _OOOOOO_
DB ______O_
DB ______O_
; 85 'U'
DB __OOOOO_
DB _O______
DB _O______
DB _O______
DB __OOOOO_


Естественно они генерировались не вручную, а самописными программками (еще под DOS). Зато, чтобы сейчас что то изменить в графике (шрифтах, картинках) те программки не нужны.

И да, устройства, с этим кодом работают до сих пор и код поддерживается.
Это и есть массив констант. Просто вместо скучных столбцов чисел в исходном коде программы из которых надо «в голове» восстанавливать вид закодированной ими картинки мы видим и даже можем легко подредактировать саму картинку.

Столбцы чисел
0x00,0x00,
0x00,0x00,
0x0C,0x00,
0x1C,0x00,
0x7C,0x00,
0x0C,0x00,
0x0C,0x00,
0x0C,0x00,
0x0C,0x00,
0x0C,0x00,
0x0C,0x00,
0x0C,0x00,
0x0C,0x00,
0x0C,0x00,
0x0C,0x00,
0x7F,0x80,
0x00,0x00,
0x00,0x00,


Картинка
________,________,
________,________,
____OO__,________,
___OOO__,________,
_OOOOO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
_OOOOOOO,O_______,
________,________,
________,________,


Для этого всего лишь требуется определить
небольшую таблицу
#define ________ 0
#define _______O 1
#define ______O_ 2
#define ______OO 3
#define _____O__ 4
#define _____O_O 5
#define _____OO_ 6
#define _____OOO 7
#define ____O___ 8
#define ____O__O 9
#define ____O_O_ 10
#define ____O_OO 11
#define ____OO__ 12
#define ____OO_O 13
#define ____OOO_ 14
#define ____OOOO 15
#define ___O____ 16
#define ___O___O 17
#define ___O__O_ 18
#define ___O__OO 19
#define ___O_O__ 20
#define ___O_O_O 21
#define ___O_OO_ 22
#define ___O_OOO 23
#define ___OO___ 24
#define ___OO__O 25
#define ___OO_O_ 26
#define ___OO_OO 27
#define ___OOO__ 28
#define ___OOO_O 29
#define ___OOOO_ 30
#define ___OOOOO 31

и т.д. до 255

Не, я не про создание. Это отдельная история, особенно когда размер шрифта большой.
Я писал именно про кодирование в исходнике. Наглядно и удобно.
Раньше было популярно кодировать шрифты (и не только) по типу фрагмента под спойлером. И не надо было никаких комментариев с картинками и редактировать удобно.

Пример фрагмента шрифта
const char NBigFont[]= {
10,18,

------- 8< --------

10,			//49 '1'
________,________,
________,________,
____OO__,________,
___OOO__,________,
_OOOOO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
_OOOOOOO,O_______,
________,________,
________,________,
10,			//50 '2'
________,________,
________,________,
___OOOO_,________,
__OO__OO,________,
_OO____O,O_______,
_OO____O,O_______,
_______O,O_______,
_______O,O_______,
______OO,________,
_____OO_,________,
____OO__,________,
___OO___,________,
__OO____,________,
_OO_____,________,
_OO_____,________,
_OOOOOOO,O_______,
________,________,
________,________,
10,			//51 '3'
________,________,
________,________,
___OOOO_,________,
__OO__OO,________,
_OO____O,O_______,
_OO____O,O_______,
_______O,O_______,
______OO,________,
___OOOOO,________,
______OO,________,
_______O,O_______,
_______O,O_______,
_OO____O,O_______,
_OO____O,O_______,
__OO__OO,________,
___OOOO_,________,
________,________,
________,________,

--------- 8< ----------

Охлаждать фотодиод для уменьшения собственных шумов в данном случае действительно излишне, а вот держать его в точке максимального SNR напряжением стоит попробовать. Фотоусиление (M) у него неплохое, но нужно стоять вблизи напряжения лавинного пробоя. Сейчас же (без температурной коррекции) видимо приходится далеко уходить от этой точки теряя усиление.
1

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность