private byte[] GetUserResData(int resId, int offset, int len) { try { if (_userResFile == null) { _userResFile = ResFile.Load(tbUserResFile.Text); var data = new byte[len]; if (offset + len > _userResFile.Resources[resId].Length) { return(null); } Buffer.BlockCopy(_userResFile.Resources[resId], 0, data, 0, len); return(data); } } catch { Debug.WriteLine("Exception GetUserResData"); } return(null); }
/// <summary> /// Разгребатель прилетевших от прокси обратных вызовов функций /// </summary> /// <param name="args">аргументы функций</param> /// <returns></returns> private unsafe object CallbackParser(object[] args) { if (args == null || args.Length == 0 || args[0] == null) { return(null); } switch (args[0]) { // Отрабатываем все функции графического отображения и относящиеся к ним case FunctionNames.DRAW_FILLED_RECT: ucScreen.DrawFilledRect((int)args[1], (int)args[2], (int)args[3], (int)args[4]); break; case FunctionNames.DRAW_FILLED_RECT_BG: ucScreen.DrawFilledRectBg((int)args[1], (int)args[2], (int)args[3], (int)args[4]); break; case FunctionNames.DRAW_RECT: ucScreen.DrawRect((int)args[1], (int)args[2], (int)args[3], (int)args[4]); break; case FunctionNames.DRAW_HORIZONTAL_LINE: ucScreen.DrawLine((int)args[2], (int)args[1], (int)args[3], (int)args[1]); break; case FunctionNames.DRAW_VERTICAL_LINE: ucScreen.DrawLine((int)args[1], (int)args[2], (int)args[1], (int)args[3]); break; case FunctionNames.FILL_SCREEN_BG: ucScreen.FillScreenBg(); break; case FunctionNames.TEXT_OUT: ucScreen.TextOut(args[1].ToString(), (int)args[2], (int)args[3]); break; case FunctionNames.TEXT_OUT_CENTER: ucScreen.TextOutCenter(args[1].ToString(), (int)args[2], (int)args[3]); break; case FunctionNames.SET_FG_COLOR: ucScreen.SetFgColor(WatchScreen.GetColorFromGRBInt((int)args[1])); break; case FunctionNames.SET_BG_COLOR: ucScreen.SetBgColor(WatchScreen.GetColorFromGRBInt((int)args[1])); break; case FunctionNames.GET_TEXT_HEIGHT: return(ucScreen.GetTextHeight()); case FunctionNames.TEXT_WIDTH: return(ucScreen.GetTextWidth(args[1].ToString())); case FunctionNames.REPAINT_SCREEN_LINES: if (_useSharedVideoMemory) { _sharedMemoryViewStream.Position = 0; _sharedMemoryViewStream.Read(_videoMemory, 0, 15488); ucScreen.SetVideoData(_videoMemory); } ucScreen.RepaintScreenLines((int)args[1], (int)args[2]); if (ucScreen.InvokeRequired) { try { Invoke(new Action(() => { ucScreen.Refresh(); })); } catch { Debug.WriteLine("Exception CallbackParser REPAINT_SCREEN_LINES"); } } else { ucScreen.Refresh(); } break; case FunctionNames.SHOW_ELF_RES_BY_ID: try { if (_userResFile == null) { _userResFile = ResFile.Load(tbUserResFile.Text); } var resImage = new ResImage(_userResFile.Resources[(int)args[2]]); ucScreen.DrawImage(resImage.Bitmap, (int)args[3], (int)args[4]); } catch { Debug.WriteLine("Exception CallbackParser SHOW_ELF_RES_BY_ID"); } return(0); case FunctionNames.SHOW_RES_BY_ID: ShowResById((int)args[1], (int)args[2], (int)args[3]); return(0); case FunctionNames.GET_RES_PARAMS: { var res = GetUserResImage((int)args[2]); if (res == null) { return(-1); } var bmp = res.Bitmap; var param = new ResParam { Width = (short)bmp.Width, Height = (short)bmp.Height }; CopyStructToUnmanagedMemory(param, (IntPtr)args[3]); return(0); } case FunctionNames.READ_ELF_RES_BY_ID: { // only own resources if ((int)args[1] != -1) { return(-1); } var data = GetUserResData(/*resId*/ (int)args[2], /*offset*/ (int)args[3], (int)args[5] /*len*/); Marshal.Copy(data, 0, (IntPtr)args[4], data.Length); return(0); } case FunctionNames.SHOW_BIG_DIGITS: ShowBigDigit((int)args[1], args[2].ToString(), (int)args[3], (int)args[4], (int)args[5]); break; case FunctionNames.LOG_PRINTF: DebugWriteLine(args[1].ToString()); return(0); case FunctionNames.GET_LAST_HEARTRATE: int heartRate = 0; if (nudHeartRate.InvokeRequired) { Invoke(new Action(() => { heartRate = (int)nudHeartRate.Value; })); } else { heartRate = (int)nudHeartRate.Value; } return(heartRate); case FunctionNames.GET_HRM_STRUCT: HrmData hrmData = new HrmData(); if (nudHeartRate.InvokeRequired) { Invoke(new Action(() => { hrmData = new HrmData { heart_rate = (byte)nudHeartRate.Value, last_hr = (byte)nudHeartRate.Value, ret_code = (byte)(cbHeartRateMeasurementComplited.Checked ? 0 : 5) }; })); } else { hrmData = new HrmData { heart_rate = (byte)nudHeartRate.Value, last_hr = (byte)nudHeartRate.Value, ret_code = (byte)(cbHeartRateMeasurementComplited.Checked ? 0 : 5) } }; if (_hrmDataPointer == IntPtr.Zero) { _hrmDataPointer = Marshal.AllocHGlobal(Marshal.SizeOf(hrmData)); } Marshal.StructureToPtr(hrmData, _hrmDataPointer, false); return(_hrmDataPointer.ToInt32()); case FunctionNames.GET_NAVI_DATA: NaviData naviData = new NaviData(); if (cbGeoLocationMeasurementComplited.InvokeRequired) { Invoke(new Action(() => { var alt = GetFloatFromText(tbAltitude.Text); var lat = GetFloatFromText(tbLatitude.Text); var lon = GetFloatFromText(tbLongitude.Text); naviData = new NaviData { ready = (cbPressureMeasurementComplited.Checked ? 1 : 0) | (cbGeoLocationMeasurementComplited.Checked ? 0x0e : 0), pressure = (uint)((float)nudPressure.Value * 133.322f), altitude = alt, latitude = (int)(3e6 * Math.Abs(lat)), ns = lat < 0 ? 0 : 1, longitude = (int)(3e6 * Math.Abs(lon)), ew = lon < 0 ? 2 : 3 }; })); } else { var alt = GetFloatFromText(tbAltitude.Text); var lat = GetFloatFromText(tbLatitude.Text); var lon = GetFloatFromText(tbLongitude.Text); naviData = new NaviData { ready = (cbPressureMeasurementComplited.Checked ? 1 : 0) | (cbGeoLocationMeasurementComplited.Checked ? 0x0e : 0), pressure = (uint)((float)nudPressure.Value * 133.322f), altitude = alt, latitude = (int)(3e6 * Math.Abs(lat)), ns = lat < 0 ? 1 : 0, longitude = (int)(3e6 * Math.Abs(lon)), ew = lon < 0 ? 2 : 3 }; } CopyStructToUnmanagedMemory(naviData, (IntPtr)args[1]); break; case FunctionNames.IS_GPS_FIXED: int isGpsFixed = 0; if (cbGeoLocationMeasurementComplited.InvokeRequired) { Invoke(new Action(() => { isGpsFixed = cbGeoLocationMeasurementComplited.Checked ? 1 : 0; })); } else { isGpsFixed = cbGeoLocationMeasurementComplited.Checked ? 1 : 0; } return(isGpsFixed); case FunctionNames.GET_SELECTED_LOCALE: LocaleEnum locale = LocaleEnum.ru_RU; if (cbLocale.InvokeRequired) { Invoke(new Action(() => { locale = GetCurrentLocale(); })); } else { locale = GetCurrentLocale(); } return((int)locale); case FunctionNames.SHARED_MEMORY_ENABLED: _useSharedVideoMemory = OpenFileMapping(); return(_useSharedVideoMemory ? 1 : 0); // заглушки case FunctionNames.VIBRATE: case FunctionNames.SET_UPDATE_PERIOD: return(0); case FunctionNames.LOAD_FONT: case FunctionNames.REG_MENU: break; default: Debug.WriteLine($"UNKNOWN FUNCTION: {args[0]}"); break; } return(null); }