Инструкция Bip | Разработка приложений для BipOS ( SDK )

MNVolkov

Разработчик
Команда форума
Сообщения
295
Реакции
2,161
Баллы
463
Ваше "умное" устройство
Amazfit Bip
  • Первое сообщение
  • #1
Разработка приложений для BipOS
Software Development Kit (SDK)
MNVolkov BipOS

Вводная часть
Начиная с версии 0.5 MNVolkov MOD полностью переработан код запуска приложений. Теперь каждое приложение - это отдельный файл, хранящийся в ресурсах. Формат исполняемых файлов Arm-elf (или просто "эльф"). Мод получил новое название BipOS. При запуске меню мода происходит сканирование ресурсов на наличие приложений. Для каждой прошивки разное количество ресурсов, а приложения всегда размещаются в конце. Поэтому загрузчик ищет ресурсы по сигнатуре Elf начиная с 930 ресурса. Из найденных приложений формируется список, который помещается в меню "приложения".
Для того чтобы повысить общее удобство и снизить количество несовместимостей разработана система "прошивконезависимых" приложений. Так один и тот же Калькулятор будет работать как на латин 1.1.5.12, так и на нелатин 1.1.2.05. без изменений (необходимо только разместить его в RES файле соответствующей версии). Независимость от прошивки удалось достигнуть за счет применения универсальной библиотеки libbip.a которая содержит адреса функций прошивки. После загрузки эльфа в оперативную память происходит пересчет внутренних адресов функций и переменных т.н. релокация, а так же подмена библиотечных адресов функций на реальные адреса функций в прошивке.


Среда разработки
Для разработки приложений понадобится среда разработки и компилятор. В качестве среды разработки я использую обычный Notepad++ . Наверное, можно настроить Code::Blocks или другую IDE я до этого не дошел, отложил на будущее. Установка специализированной IDE конечно повысит удобство разработки. На среде разработки останавливаться не буду.

Компилятор
Для сборки приложения я применяю GNU Embedded Toolchain for Arm. Для установки необходимо проделать следующие шаги:
  1. Скачать тулчейн можно тут:

    Пожалуйста войдите или зарегистрируйтесь для просмотра скрытого текста.


    Качаем файл gcc-arm-none-eabi-8-2019-q3-update-win32-sha2.exe ( или более свежую редакцию) с таким описанием: Windows 32-bit Installer (Signed for Windows 7 and later)
  2. Можно все установить по умолчанию, в конце установки установить все галочки
  3. Рекомендуется добавить в системный (не пользовательский) PATH путь до папки bin компилятора
Библиотека
Библиотека включает в себя как адреса функций прошивки, так и некоторые функции, которые написаны для облегчения разработки пользовательских приложений, например функции работы с меню. Библиотеку необходимо распаковать в папку на одном уровне с папками приложений. Путь до этой папки будет указан в сценарии сборки.
v.0.5.2
У вас нет разрешения на просмотр содержимого!

v.0.5.1
У вас нет разрешения на просмотр содержимого!

v.0.5
У вас нет разрешения на просмотр содержимого!


Пример приложения
Специально для облегчения вхождения подготовлен пример приложения на языке СИ template_app. Функционал простой: создается рабочий экран приложения, при нажатии в центр экрана меняется цвет фона и надписи.
Этот пример можно использовать в качестве шаблона. Для этого нужно создать новую папку приложения и скопировать в неё файлы примера. Наименование папки приложения в скрипте сборки берется в качестве служебного имени приложения.
Отображаемое в списке приложений наименование необходимо внести в файл label.txt При этом после наименования не должно быть каких либо символов или перевода строки.
Для сборки приложения подготовлен bat файл. Сборка осуществляется путем запуска bat файла внутри папки без параметров. Все параметры компилятора и линковщика совместимые с загрузчиком BipOS внесены в этот скрипт.
Приложение-шаблон:
У вас нет разрешения на просмотр содержимого!

Исходники на GitHub

Пожалуйста войдите или зарегистрируйтесь для просмотра скрытого текста.



Пожалуйста войдите или зарегистрируйтесь для просмотра скрытого текста.



Сборка RES файла и загрузка в часы
Для запуска эльфа необходимо загрузить его в часы. Для этого необходимо поместить его в RES файл. Для сборки RES файлов разработана специальная программа для ПК (Win32) с помощью которой можно добавить в ваш существующий RES файл необходимые приложения. ResPack.exe - это консольное приложение для выполнения простых операций с RES фалами Amazfit Bip: отображение содержимого с краткой информацией по каждому ресурсу, распаковка сырых данных ресурсов, выполнение выравнивания строковых ресурсов версии 61 и 69 для решения проблемы пропадания текста при загрузке кастомных ресурсов, а также добавления произвольных файлов в ресурсы.
Для добавления в существующий RES файл файлов приложений запускаем из командной строки:
Код:
ResPack -a <выходной_RES_файл> <входной_RES_файл> файлы которые надо добавить
Полученный RES файл прошивается в часы обычным способом, например, через GadgetBridge. Для обновления данных в оперативной памяти часы после обновления ресурсов необходимо перезагрузить. Сделать это можно либо через меню настроек выключив и включив часы.
У вас нет разрешения на просмотр содержимого!


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


Обсуждение процесса разработки ведется в этой теме.
 

Вложения

Последнее редактирование модератором:

erekoze

Местный
Сообщения
103
Реакции
211
Баллы
58
Ваше "умное" устройство
Amazfit Bip
Наверное Вы до них не дошли. Приложения в самом конце. Необходимо обязательно выбрать прошивку с BipOS 0.5.2 и ресурсы.
Да я нашел приложения. Спасибо. Но там все те же приложения, что и здесь на форуме. Хотелось бы иметь возможность выкладывать туда свои приложения. Как платно, так и бесплатно.
 

MNVolkov

Разработчик
Команда форума
Сообщения
295
Реакции
2,161
Баллы
463
Ваше "умное" устройство
Amazfit Bip
Да я нашел приложения. Спасибо. Но там все те же приложения, что и здесь на форуме. Хотелось бы иметь возможность выкладывать туда свои приложения. Как платно, так и бесплатно.
Такая возможность есть. Если есть желание - можно включить авторский контент в конструктор LikeApp.
 

erekoze

Местный
Сообщения
103
Реакции
211
Баллы
58
Ваше "умное" устройство
Amazfit Bip
Такая возможность есть. Если есть желание - можно включить авторский контент в конструктор LikeApp.
Как что нибудь годное напишу (если время будет), может выложу. Спасибо!!!
 

ugers

Участник
Сообщения
35
Реакции
124
Баллы
38
Ваше "умное" устройство
Amazfit Bip
3 - мало. Сделайте минимум 12. Иначе, когда-нибудь, получите промах по памяти.
А почему 12? Можете рассказать?
Ведь согласно описанию
char - размер 1 байт.
short - размер 2 байта
int - размер 2 или 4 байта
long - размер 4 байта
 

erekoze

Местный
Сообщения
103
Реакции
211
Баллы
58
Ваше "умное" устройство
Amazfit Bip
Кто нибудь может показать фрагмент кода, как отобразить на экране свою картинку? Заранее спасибо!
 

AlexJey

Разработчик
Команда форума
Сообщения
427
Реакции
1,037
Баллы
223
Ваше "умное" устройство
Amazfit Bip
А почему 12? Можете рассказать?
Ведь согласно описанию
char - размер 1 байт.
short - размер 2 байта
int - размер 2 или 4 байта
long - размер 4 байта
А строка символов, которая будет предоставлять число -2000000000, сколько будет занимать байт? Плюс завершающий символ с кодом 0 ;)
 

MNVolkov

Разработчик
Команда форума
Сообщения
295
Реакции
2,161
Баллы
463
Ваше "умное" устройство
Amazfit Bip
Кто нибудь может показать фрагмент кода, как отобразить на экране свою картинку? Заранее спасибо!
Изучите функцию draw_frame здесь

Пожалуйста войдите или зарегистрируйтесь для просмотра скрытого текста.



Для этого опубликованы исходники, чтобы можно было на примерах понять как что работает.
 

erekoze

Местный
Сообщения
103
Реакции
211
Баллы
58
Ваше "умное" устройство
Amazfit Bip

erekoze

Местный
Сообщения
103
Реакции
211
Баллы
58
Ваше "умное" устройство
Amazfit Bip
Изучите функцию draw_frame здесь

Пожалуйста войдите или зарегистрируйтесь для просмотра скрытого текста.



Для этого опубликованы исходники, чтобы можно было на примерах понять как что работает.
Все ясно. Большое спасибо, использовал как образец в Магическом шаре :)
Авто объединение сообщений:

Новый вопрос :)
Как сохранять данные приложения?
Т.е. использовать функции:
extern int ElfReadSettings (int index_listed, void* buffer, int offset, int len); // чтение секции настроек конкретного эльфа
extern int ElfWriteSettings (int index_listed, void* buffer, int offset, int len); // запись секции настроек конкретного эльфа
Хотелось бы сохранять данные переменных между запусками приложений.
Заранее спасибо!
 
  •  Мне нравится
Реакции: be3

erekoze

Местный
Сообщения
103
Реакции
211
Баллы
58
Ваше "умное" устройство
Amazfit Bip
Так и не смог разобраться с сохранением данных между запусками приложения в память часов.

В файле template.h создал вот такие структуры:

struct app_data_ {
void* ret_f; // адрес функции возврата
Elf_proc_* proc; // указатель на данные запущенного процесса
};
// структура хранения данных
struct creature_state_ {
int health; // количество здоровья
};

В файле template.c создал пользовательскую функцию:

void draw_screen(){
struct app_data_** app_data_p = get_ptr_temp_buf_2(); // указатель на указатель на данные экрана
struct app_data_ * app_data = *app_data_p; // указатель на данные экрана
struct creature_state_** creature_state_p = get_ptr_temp_buf_2(); // указатель на указатель на данные экрана
struct creature_state_ * creature_state = *creature_state_p; // указатель на данные экрана
char crnd[3]; // переменная для вывода результата
set_bg_color(COLOR_BLUE); // Делаем фон синим
fill_screen_bg(); // Заливаем экран фоном
set_graph_callback_to_ram_1(); // Это не понятно зачем..:)
load_font(); // Подгружаем шрифты
set_fg_color(COLOR_YELLOW); // Делаем текст желтым
ElfReadSettings(app_data->proc->index_listed, &creature_state, 0, sizeof(struct creature_state_)); // читаем данные из памяти
if (creature_state->health>100) creature_state->health=0; // если запустили программу 1-й раз то ставим значение здоровья на 0
creature_state->health=creature_state->health+1; // увеличиваем здоровье на 1
ElfWriteSettings(app_data->proc->index_listed, &creature_state, 0, sizeof(struct creature_state_)); // пишем данные в память
_sprintf(crnd, "%d", creature_state->health); // Конвертируем 1-е число int в char
text_out_center(crnd, 88, 80); // Выводим здоровье
};

Данная процедура запускается при старте программы. Процедура подсчитывает кол-во запусков программы и выводит число запусков в центр экрана. То есть, с каждым запуском значение creature_state->health увеличивается на 1, а затем сохраняется в памяти.

Но этого не происходит. Всегда выдает значение 1. Есть подозрение что не правильно работают функции ElfReadSettings и ElfWriteSettings..

Может кто нибудь подскажет в чем проблема?
 

MNVolkov

Разработчик
Команда форума
Сообщения
295
Реакции
2,161
Баллы
463
Ваше "умное" устройство
Amazfit Bip
1. У Вас почему-то двум разным указателям присваивается значение get_ptr_temp_buf_2(), таким образом разные переменные используют одну и ту же область памяти.
2. Сама по себе функция get_ptr_temp_buf_2() не выделяет память, а всего лишь возвращает указатель на область памяти длиной 4 байта, где можно хранить свой указатель на переменную (или структуру данных) полученный от malloc(), которая не уничтожится пока приложение запущено.
3. Если хотите выделять память под структуру creature_state_ каждый раз при запуске draw_screen() то лучше сделать так:
C:
void draw_screen(){
    struct app_data_**  app_data_p = get_ptr_temp_buf_2();  //  указатель на указатель на данные экрана
    struct app_data_ *  app_data = *app_data_p;             //  указатель на данные экрана 
    struct creature_state_ creature_state; // структура для хранения количества запусков, значение уничтожится по завершении draw_screen()
...
}
4. Не относится к вашему вопросу однако в строке char crnd[3]; трёх байт будет маловато, т.к. даже для значения 100 понадобится минимум 4 байта, лучше не рисковать и пставить тут побольше, если планируются только цифры то ставьте 8.
3. Используйте теги [CODE] для публикации кода, так легче его просмотреть и оценить.😉
 

erekoze

Местный
Сообщения
103
Реакции
211
Баллы
58
Ваше "умное" устройство
Amazfit Bip
1. У Вас почему-то двум разным указателям присваивается значение get_ptr_temp_buf_2(), таким образом разные переменные используют одну и ту же область памяти.
2. Сама по себе функция get_ptr_temp_buf_2() не выделяет память, а всего лишь возвращает указатель на область памяти длиной 4 байта, где можно хранить свой указатель на переменную (или структуру данных) полученный от malloc(), которая не уничтожится пока приложение запущено.
3. Если хотите выделять память под структуру creature_state_ каждый раз при запуске draw_screen() то лучше сделать так:
C:
void draw_screen(){
    struct app_data_**  app_data_p = get_ptr_temp_buf_2();  //  указатель на указатель на данные экрана
    struct app_data_ *  app_data = *app_data_p;             //  указатель на данные экрана
    struct creature_state_ creature_state; // структура для хранения количества запусков, значение уничтожится по завершении draw_screen()
...
}
4. Не относится к вашему вопросу однако в строке char crnd[3]; трёх байт будет маловато, т.к. даже для значения 100 понадобится минимум 4 байта, лучше не рисковать и пставить тут побольше, если планируются только цифры то ставьте 8.
3. Используйте теги [CODE] для публикации кода, так легче его просмотреть и оценить.😉
Большое спасибо за консультацию. Буду пробовать.
 

erekoze

Местный
Сообщения
103
Реакции
211
Баллы
58
Ваше "умное" устройство
Amazfit Bip
1. У Вас почему-то двум разным указателям присваивается значение get_ptr_temp_buf_2(), таким образом разные переменные используют одну и ту же область памяти.
2. Сама по себе функция get_ptr_temp_buf_2() не выделяет память, а всего лишь возвращает указатель на область памяти длиной 4 байта, где можно хранить свой указатель на переменную (или структуру данных) полученный от malloc(), которая не уничтожится пока приложение запущено.
3. Если хотите выделять память под структуру creature_state_ каждый раз при запуске draw_screen() то лучше сделать так:
C:
void draw_screen(){
    struct app_data_**  app_data_p = get_ptr_temp_buf_2();  //  указатель на указатель на данные экрана
    struct app_data_ *  app_data = *app_data_p;             //  указатель на данные экрана
    struct creature_state_ creature_state; // структура для хранения количества запусков, значение уничтожится по завершении draw_screen()
...
}
4. Не относится к вашему вопросу однако в строке char crnd[3]; трёх байт будет маловато, т.к. даже для значения 100 понадобится минимум 4 байта, лучше не рисковать и пставить тут побольше, если планируются только цифры то ставьте 8.
3. Используйте теги [CODE] для публикации кода, так легче его просмотреть и оценить.😉
Изменил код в соответствии с Вашими рекомендациями. К сожалению, ничего не поменялось, по прежнему всегда выводит 1 :(

Вот код:
C:
void draw_screen(){
    struct app_data_**  app_data_p = get_ptr_temp_buf_2();  //  указатель на указатель на данные экрана 
    struct app_data_ *  app_data = *app_data_p;             //  указатель на данные экрана
    struct creature_state_ creature_state;                  //  структура хранения данных твари
    char crnd[8];                                           // переменная для вывода результата
    set_bg_color(COLOR_BLUE);       // Делаем фон синим
    fill_screen_bg();               // Заливаем экран фоном
    set_graph_callback_to_ram_1();  // Это не понятно зачем..:)
    load_font();                    // Подгружаем шрифты
    set_fg_color(COLOR_YELLOW);     // Делаем текст желтым  
    ElfReadSettings(app_data->proc->index_listed, &creature_state, 0, sizeof(struct creature_state_)); // читаем данные из памяти
    if (creature_state.health>100) creature_state.health=0; // если запустили программу 1-й раз то ставим значение здоровья твари на 0
    creature_state.health=creature_state.health+1; // увеличиваем здоровье твари на 1
    ElfWriteSettings(app_data->proc->index_listed, &creature_state, 0, sizeof(struct creature_state_)); // пишем данные в память
    _sprintf(crnd, "%d", creature_state.health); // Конвертируем 1-е число int в char
    text_out_center(crnd, 88, 80); // Вывводим здоровье твари
};
Может я что то не так сделал?
 
  •  Мне нравится
Реакции: be3

en_rov

Друг форума
Сообщения
68
Реакции
210
Баллы
38
Ваше "умное" устройство
Amazfit Bip
Большое спасибо за консультацию. Буду пробовать.

Я полагаю, что вы также можете определить creature_state _ вне функций, так что любая функция в этом файле может получить к ней прямой доступ без передачи указателей, например так:


C:
static struct creature_state_ creature_state;   // usable by any function

void draw_screen(){
    struct app_data_**  app_data_p = get_ptr_temp_buf_2();  //  указатель на указатель на данные экрана
    struct app_data_ *  app_data = *app_data_p;             //  указатель на данные экрана
   
...
}

Больше информации

Пожалуйста войдите или зарегистрируйтесь для просмотра скрытого текста.

.

Большое спасибо за консультацию. Буду пробовать.
I believe you can also define creature_state_ outside the functions, so any function in that file can access it directly without passing pointers around, like this:

C:
static struct creature_state_ creature_state;   // usable by any function

void draw_screen(){
    struct app_data_**  app_data_p = get_ptr_temp_buf_2();  //  указатель на указатель на данные экрана
    struct app_data_ *  app_data = *app_data_p;             //  указатель на данные экрана
   
...
}
More info

Пожалуйста войдите или зарегистрируйтесь для просмотра скрытого текста.

 

erekoze

Местный
Сообщения
103
Реакции
211
Баллы
58
Ваше "умное" устройство
Amazfit Bip
Я полагаю, что вы также можете определить creature_state _ вне функций, так что любая функция в этом файле может получить к ней прямой доступ без передачи указателей, например так:


C:
static struct creature_state_ creature_state;   // usable by any function

void draw_screen(){
    struct app_data_**  app_data_p = get_ptr_temp_buf_2();  //  указатель на указатель на данные экрана
    struct app_data_ *  app_data = *app_data_p;             //  указатель на данные экрана
  
...
}

Больше информации

Пожалуйста войдите или зарегистрируйтесь для просмотра скрытого текста.

.

I believe you can also define creature_state_ outside the functions, so any function in that file can access it directly without passing pointers around, like this:

C:
static struct creature_state_ creature_state;   // usable by any function

void draw_screen(){
    struct app_data_**  app_data_p = get_ptr_temp_buf_2();  //  указатель на указатель на данные экрана
    struct app_data_ *  app_data = *app_data_p;             //  указатель на данные экрана
  
...
}
More info

Пожалуйста войдите или зарегистрируйтесь для просмотра скрытого текста.

Thank! I will try.

Спасибо! Попробую.
 
  •  Мне нравится
Реакции: be3

erekoze

Местный
Сообщения
103
Реакции
211
Баллы
58
Ваше "умное" устройство
Amazfit Bip
1. У Вас почему-то двум разным указателям присваивается значение get_ptr_temp_buf_2(), таким образом разные переменные используют одну и ту же область памяти.
2. Сама по себе функция get_ptr_temp_buf_2() не выделяет память, а всего лишь возвращает указатель на область памяти длиной 4 байта, где можно хранить свой указатель на переменную (или структуру данных) полученный от malloc(), которая не уничтожится пока приложение запущено.
3. Если хотите выделять память под структуру creature_state_ каждый раз при запуске draw_screen() то лучше сделать так:
C:
void draw_screen(){
    struct app_data_**  app_data_p = get_ptr_temp_buf_2();  //  указатель на указатель на данные экрана
    struct app_data_ *  app_data = *app_data_p;             //  указатель на данные экрана
    struct creature_state_ creature_state; // структура для хранения количества запусков, значение уничтожится по завершении draw_screen()
...
}
4. Не относится к вашему вопросу однако в строке char crnd[3]; трёх байт будет маловато, т.к. даже для значения 100 понадобится минимум 4 байта, лучше не рисковать и пставить тут побольше, если планируются только цифры то ставьте 8.
3. Используйте теги [CODE] для публикации кода, так легче его просмотреть и оценить.😉
В общем ничего не понятно. Все упростил до предела. Код вот такой с рекомендациями en_rov:

C:
static int n=5;
// пользовательская функция
void draw_screen(){
    struct app_data_**  app_data_p = get_ptr_temp_buf_2();  //  указатель на указатель на данные экрана
    struct app_data_ *  app_data = *app_data_p;             //  указатель на данные экрана
    char c[8];                                              // переменная для вывода результата
    fill_screen_bg();                                       // Заливаем экран фоном
    ElfReadSettings(app_data->proc->index_listed, &n, 0, sizeof(n)); // читаем данные из памяти
    if (n>100) n=0; // если запустили программу 1-й раз то ставим значение на 0
    n++; // увеличиваем на 1
    ElfWriteSettings(app_data->proc->index_listed, &n, 0, sizeof(n)); // пишем данные в память
    _sprintf(c, "%d", n); // Конвертируем число int в char
    text_out_center(c, 88, 80); // Выводим n
};
Выдает 6. Такое ощущение, что ElfReadSettings и ElfWriteSettings у меня не работают. Хотя в Календаре при сохранении темы работают.. ;(

Прилагаю весь проект. Пишу "большую" игру. Все упирается в сохранение данных между запусками. Пожалуйста объясните как пользоваться ElfReadSettings и ElfWriteSettings?
Авто объединение сообщений:

1. У Вас почему-то двум разным указателям присваивается значение get_ptr_temp_buf_2(), таким образом разные переменные используют одну и ту же область памяти.
2. Сама по себе функция get_ptr_temp_buf_2() не выделяет память, а всего лишь возвращает указатель на область памяти длиной 4 байта, где можно хранить свой указатель на переменную (или структуру данных) полученный от malloc(), которая не уничтожится пока приложение запущено.
3. Если хотите выделять память под структуру creature_state_ каждый раз при запуске draw_screen() то лучше сделать так:
C:
void draw_screen(){
    struct app_data_**  app_data_p = get_ptr_temp_buf_2();  //  указатель на указатель на данные экрана
    struct app_data_ *  app_data = *app_data_p;             //  указатель на данные экрана
    struct creature_state_ creature_state; // структура для хранения количества запусков, значение уничтожится по завершении draw_screen()
...
}
4. Не относится к вашему вопросу однако в строке char crnd[3]; трёх байт будет маловато, т.к. даже для значения 100 понадобится минимум 4 байта, лучше не рисковать и пставить тут побольше, если планируются только цифры то ставьте 8.
3. Используйте теги [CODE] для публикации кода, так легче его просмотреть и оценить.😉
Забыл прикрепить проект. Приношу извинения. Прикрепляю.
 

Вложения

  • 22.1 KB Просмотры: 2
Последнее редактирование:

ugers

Участник
Сообщения
35
Реакции
124
Баллы
38
Ваше "умное" устройство
Amazfit Bip
В общем ничего не понятно. Все упростил до предела. Код вот такой с рекомендациями en_rov:

C:
static int n=5;
// пользовательская функция
void draw_screen(){
    struct app_data_**  app_data_p = get_ptr_temp_buf_2();  //  указатель на указатель на данные экрана
    struct app_data_ *  app_data = *app_data_p;             //  указатель на данные экрана
    char c[8];                                              // переменная для вывода результата
    fill_screen_bg();                                       // Заливаем экран фоном
    ElfReadSettings(app_data->proc->index_listed, &n, 0, sizeof(n)); // читаем данные из памяти
    if (n>100) n=0; // если запустили программу 1-й раз то ставим значение на 0
    n++; // увеличиваем на 1
    ElfWriteSettings(app_data->proc->index_listed, &n, 0, sizeof(n)); // пишем данные в память
    _sprintf(c, "%d", n); // Конвертируем число int в char
    text_out_center(c, 88, 80); // Выводим n
};
Выдает 6. Такое ощущение, что ElfReadSettings и ElfWriteSettings у меня не работают. Хотя в Календаре при сохранении темы работают.. ;(

Прилагаю весь проект. Пишу "большую" игру. Все упирается в сохранение данных между запусками. Пожалуйста объясните как пользоваться ElfReadSettings и ElfWriteSettings?
Авто объединение сообщений:


Забыл прикрепить проект. Приношу извинения. Прикрепляю.
А Settings.bin кто будет создавать?) Вот поэтому и не сохраняется:)
Компилятор сам его подхватывает и выделяет в эльфе место под сохранение данных.
А т.к. сейчас у тебя его нет то и сохранять некуда:)
Пример Settings.bin можешь взять с календаря Максима.(По сути это фаил забитый нулями и изменяется он уже в часах при сохранении, можно и стандартные настройки в нем выставить но я пока с эти не разбирался)
 

erekoze

Местный
Сообщения
103
Реакции
211
Баллы
58
Ваше "умное" устройство
Amazfit Bip
А Settings.bin кто будет создавать?) Вот поэтому и не сохраняется:)
Компилятор сам его подхватывает и выделяет в эльфе место под сохранение данных.
А т.к. сейчас у тебя его нет то и сохранять некуда:)
А, это как? И что это за файл? Пожалуйста объясните!!! Заранее спасибо. :)
 

ugers

Участник
Сообщения
35
Реакции
124
Баллы
38
Ваше "умное" устройство
Amazfit Bip
А, это как? И что это за файл? Пожалуйста объясните!!! Заранее спасибо. :)
Я отредактировал прошлый пост)

Пожалуйста войдите или зарегистрируйтесь для просмотра скрытого текста.


фаил

Пожалуйста войдите или зарегистрируйтесь для просмотра скрытого текста.

создается в папке с исходниками эльфа.

Пожалуйста войдите или зарегистрируйтесь для просмотра скрытого текста.


По сути представляет из себя нули(в моем случае). редактируется в hex редакторе. если дружите с hex-ом можно и начальные значения для переменных в нем прописать которые пользователь затем может изменить.
1591627641209.png

В функции ElfWrite вы как раз и задаете смещение для сохранения в этот фаил, а ElfRead читаете из заданного смещения(offset)
 

erekoze

Местный
Сообщения
103
Реакции
211
Баллы
58
Ваше "умное" устройство
Amazfit Bip
Я отредактировал прошлый пост)

Пожалуйста войдите или зарегистрируйтесь для просмотра скрытого текста.


фаил

Пожалуйста войдите или зарегистрируйтесь для просмотра скрытого текста.

создается в папке с исходниками эльфа.

Пожалуйста войдите или зарегистрируйтесь для просмотра скрытого текста.


По сути представляет из себя нули(в моем случае). редактируется в hex редакторе. если дружите с hex-ом можно и начальные значения для переменных в нем прописать которые пользователь затем может изменить.

В функции ElfWrite вы как раз и задаете смещение для сохранения в этот фаил, а ElfRead читаете из заданного смещения(offset)
Большое спасибо! Очень помогли. Буду пробовать.
 

Пользователи, просматривающие эту тему

Сейчас на форуме нет ни одного пользователя.
Сверху Снизу