Files
fmviewer3/project/fm_viewer/cfg/rm_settings_cfg_emt_kr.cpp
2026-02-21 17:11:31 +09:00

269 lines
7.1 KiB
C++

#include "rm_settings_cfg_emt_kr.h"
#include <QFile>
#include <QDebug>
#include <QJsonDocument>
#include <QJsonObject>
#include <Windows.h>
#if (USE_DEVICE_SETTINGS && RM_MODEL_EMT_KR)
unsigned char CFG::data[SETTINGS_CFG_SIZE] = {0,};
unsigned char CFG::stored[SETTINGS_CFG_SIZE] = {0,};
EMTINFO CFG::info = {0,};
QJsonArray CFG::items;
QString CFG::cfgPath = "";
QStringList CFG::model_names = QStringList() << "NM5000" << "NP5000" << "MIRROR5" << "PRO5" << "360X";
uint32_t CFG::model_codes[5] = { NM5000, NP5000, MIRROR5, PRO5, A360X};
bool CFG::_loadJSon()
{
// CLEAR
while(CFG::items.count()) {
CFG::items.pop_back();
}
//QString jsonPath = ":/raw/cfg_5102.json";
QString jsonPath = "";
switch(info.model) {
case NM5000:
jsonPath = ":/raw/cfg_nm5000.json";
break;
case NP5000:
jsonPath = ":/raw/cfg_np5000.json";
break;
case MIRROR5:
jsonPath = ":/raw/cfg_mirror5.json";
break;
case PRO5:
jsonPath = ":/raw/cfg_pro5.json";
break;
case A360X:
jsonPath = ":/raw/cfg_360x.json";
break;
default:
return false;
}
QFile file(jsonPath);
if(file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QByteArray data = file.readAll();
file.close();
CFG::items = QJsonDocument::fromJson(data).array();
}
return true;
}
void CFG::_getItems(QJsonArray& in, QJsonArray& ret)
{
for(int i=0;i<in.size();i++) {
QJsonObject obj = in.at(i).toObject();
if(obj.contains("group") && obj.contains("items")) {
_getItems(obj.value("items").toArray(),ret);
}
else {
ret.append(obj);
}
}
}
void CFG::serializeItems(QJsonArray& citems) {
_getItems(CFG::items,citems);
return;
}
void CFG::setDefault()
{
QJsonArray citems;
serializeItems(citems);
for(int i=0;i<citems.size();i++) {
QJsonObject obj = citems.at(i).toObject();
//qInfo() << obj << __FUNCTION__;
if(obj.contains("default") && obj.contains("offset")) {
QString type = obj.value("type").toString();
if(type == "int") {
int offset = obj.value("offset").toInt();
CFG::data[offset] = obj.value("default").toInt();
//qInfo() << obj << __FUNCTION__;
}
}
}
//qInfo() << items << __FUNCTION__;
}
void CFG::backup()
{
memcpy(CFG::stored,CFG::data,SETTINGS_CFG_SIZE);
}
void CFG::restore()
{
memcpy(CFG::data,CFG::stored,SETTINGS_CFG_SIZE);
}
bool CFG::isEdited()
{
return (0 != memcmp(CFG::stored,CFG::data,SETTINGS_CFG_SIZE-sizeof(_EMTINFO)));
}
CFG_ERROR_CODE CFG::load(QString path)
{
CFG_ERROR_CODE r = CFG_UNKNOWN_ERROR;
if(!QFile::exists(path)) {
return CFG_IO_ERROR;
}
FILE* f = fopen(path.toLocal8Bit(),"r+b");
if(f == NULL) {
return CFG_IO_ERROR;
}
unsigned char d[SETTINGS_CFG_SIZE] = {0,};
size_t read = fread(d,1,SETTINGS_CFG_SIZE,f);
fclose(f);
if(read > 0)
{
cfgPath = path;
memcpy(CFG::data,d,read);
// 나머지 영역 초기화???
if(read == SETTINGS_CFG_SIZE) {
memcpy(&CFG::info,&d[SETTINGS_CFG_SIZE-sizeof(_EMTINFO)],sizeof(_EMTINFO));
//setDefault();
r = verifyInfo();
if(r != CFG_SUCCESS) {
return r;
}
_loadJSon();
}
}
else
{
setDefault();
}
CFG::backup(); // 현재 데이터 보존
// CHECKSUM 확인
if(!appUserSettingCheck()) {
return CFG_CHECKSUM_ERROR;
}
return r;
}
CFG_ERROR_CODE CFG::verifyInfo()
{
if(info.magic != 0xA5A5CC33) {
return CFG_WRONG_FILE;
}
// Magnus : 5101
// Trinity : 5102
// Mirror5 : 5103
// Pro5 : 5104
// 360X : 5105
// qInfo() << info.file1 << info.file2 << __FUNCTION__; // ?? 값이 정확하지 않음
// qInfo() << "MODEL CODE:" << info.model << "FILE SIZE:" << info.file1 << info.file2 << __FUNCTION__;
if(info.model < 5101 || info.model > 5105)
{
return CFG_WRONG_FILE;
}
return CFG_SUCCESS;
}
QString CFG::modelName()
{
for(int i=0;i<model_names.size();i++) {
if(model_codes[i] == info.model) {
return model_names.at(i);
}
}
return "UNKNOWN";
}
uint32_t CFG::version()
{
return info.version;
}
void CFG::clear()
{
memset(CFG::stored,0,SETTINGS_CFG_SIZE);
memset(CFG::data,0,SETTINGS_CFG_SIZE);
}
bool CFG::save(QString path)
{
bool bSuccess = false;
DWORD dwAttrib = ::GetFileAttributes((LPCTSTR)path.utf16());
if((dwAttrib & FILE_ATTRIBUTE_HIDDEN)) {
::SetFileAttributes((LPCTSTR)path.utf16(),FILE_ATTRIBUTE_NORMAL);
}
FILE* f = fopen(path.toLocal8Bit(),"w+b");
if(f != NULL)
{
if(isEdited())
{
CFG::data[SD_VIEWSETTING_OFFSET] = 1;
_updateCheckSum(); // 다시 계산
}
size_t write = 0;
write = fwrite(CFG::data,1,SETTINGS_CFG_SIZE,f);
bSuccess = write > 0;
fclose(f);
::SetFileAttributes((LPCTSTR)path.utf16(),FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN);
}
CFG::backup();
return bSuccess;
}
#define COMBINE_16(h, l) (uint16_t)((((uint16_t)h)<<8) | (uint16_t)l)
uint16_t CFG::checkSum() // appGetSum16_Emt(uint16_t *Buf, uint32_t Size)
{
// 마지막 1은?
uint32_t Size = ((SETTINGS_CFG_SIZE - sizeof(_EMTINFO)) / 2) - 1;
//uint8_t bSettingFileOK = TRUE;
uint16_t* pbuf = (uint16_t*)&data[0];
uint16_t Sum = 0;
uint32_t SumTemp = 0;
while( Size )
{
SumTemp += (uint32_t)pbuf[--Size];
}
Sum = (uint16_t)((uint16_t)((SumTemp >> 16) & 0x0000ffff) | (uint16_t)(SumTemp & 0x0000ffff));
return Sum;
}
void CFG::_updateCheckSum()
{
uint16_t c = checkSum();
data[SETTINGS_CFG_SIZE-sizeof(_EMTINFO)-2] = ((c >> 8) & 0xFF);
data[SETTINGS_CFG_SIZE-sizeof(_EMTINFO)-1] = (c & 0xFF);
}
bool CFG::appUserSettingCheck()
{
/*
uint16_t* pbuf = (uint16_t*)&data[0];
uint16_t checkSum, CalCheckSum;
// 설정 영역의 마지막 2BYTE
uint8_t checkData1 = data[SETTINGS_CFG_SIZE-sizeof(_EMTINFO)-2];
uint8_t checkData2 = data[SETTINGS_CFG_SIZE-sizeof(_EMTINFO)-1];
const uint32_t dataSize = SETTINGS_CFG_SIZE - sizeof(_EMTINFO);
checkSum = COMBINE_16(checkData1, checkData2);
CalCheckSum = appGetSum16_Emt(pbuf, (dataSize / 2)); // sizeof(uiParamSetting_t)
return (checkSum != CalCheckSum);
*/
// 설정 영역의 마지막 2BYTE
uint8_t checkData1 = data[SETTINGS_CFG_SIZE-sizeof(_EMTINFO)-2];
uint8_t checkData2 = data[SETTINGS_CFG_SIZE-sizeof(_EMTINFO)-1];
//qInfo() << "CHECKED:" << COMBINE_16(checkData1,checkData2) << "CALCED:" << checkSum() <<__FUNCTION__;
return (COMBINE_16(checkData1,checkData2) == checkSum());
}
//uint16_t CFG::checkSum()
//{
// uint16_t* pbuf = (uint16_t*)&data[0];
// const uint32_t dataSize = SETTINGS_CFG_SIZE - sizeof(_EMTINFO);
// return appGetSum16_Emt(pbuf, (dataSize / 2) - 1);
//}
#endif // #if (USE_DEVICE_SETTINGS && RM_MODEL_EMT_KR)