From patchwork Fri Jan 28 14:40:29 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ales Jurik X-Patchwork-Id: 12860 Received: from mail.tu-berlin.de ([130.149.7.33]) by www.linuxtv.org with esmtp (Exim 4.69) (envelope-from ) id 1PipV6-0005Uj-O6 for vdr@linuxtv.org; Fri, 28 Jan 2011 15:40:37 +0100 X-tubIT-Incoming-IP: 194.228.2.86 Received: from smtp-out1.iol.cz ([194.228.2.86]) by mail.tu-berlin.de (exim-4.74/mailfrontend-d) with esmtp for id 1PipV5-0005UG-2s; Fri, 28 Jan 2011 15:40:36 +0100 Received: from antivir3.iol.cz (antivir3.iplanet.iol.cz [192.168.30.206]) by smtp-out1.iol.cz (Postfix) with ESMTP id C33B239046A; Fri, 28 Jan 2011 15:40:34 +0100 (CET) Received: from localhost (antivir3.iol.cz [127.0.0.1]) by antivir3.iol.cz (Postfix) with ESMTP id B740D4AC036; Fri, 28 Jan 2011 15:40:34 +0100 (CET) X-Virus-Scanned: amavisd-new at iol.cz Received: from antivir3.iol.cz ([127.0.0.1]) by localhost (antivir3.iol.cz [127.0.0.1]) (amavisd-new, port 10124) with LMTP id hQZPNJlUVE-Q; Fri, 28 Jan 2011 15:40:34 +0100 (CET) Received: from port6.iol.cz (unknown [192.168.30.96]) by antivir3.iol.cz (Postfix) with ESMTP id 896D94AC02E; Fri, 28 Jan 2011 15:40:34 +0100 (CET) X-SBRS: None X-SBRS-none: None X-RECVLIST: MTA-OUT-QUICK X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: At0HAJZjQk1YZ3gv/2dsb2JhbAAMhQKbCsFmgnqCVQSMJ4Nf Received: from unknown (HELO [10.0.0.101]) ([88.103.120.47]) by port6.iol.cz with ESMTP; 28 Jan 2011 15:40:34 +0100 Message-ID: <4D42D55D.90904@quick.cz> Date: Fri, 28 Jan 2011 15:40:29 +0100 From: Ales Jurik User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101218 Lightning/1.0b3pre Thunderbird/3.1.7 MIME-Version: 1.0 To: VDR Mailing List , Seppo Ingalsuo X-PMX-Version: 5.5.5.374460, Antispam-Engine: 2.7.1.369594, Antispam-Data: 2011.1.28.143018 X-PMX-Spam: Gauge=IIIIIIII, Probability=8%, Report=' MIME_TEXT_ONLY_MP_MIXED 0.05, MSGID_ADDED_BY_MTA 0.05, BODYTEXTP_SIZE_3000_LESS 0, BODY_SIZE_10000_PLUS 0, __BAT_BOUNDARY 0, __CT 0, __CTYPE_HAS_BOUNDARY 0, __CTYPE_MULTIPART 0, __CTYPE_MULTIPART_MIXED 0, __HAS_MSGID 0, __INT_PROD_MOTORBIKE 0, __MIME_TEXT_ONLY 0, __MIME_VERSION 0, __MOZILLA_MSGID 0, __RUS_OBFU_PHONE 0, __SANE_MSGID 0, __STOCK_PHRASE_7 0, __TO_MALFORMED_2 0, __USER_AGENT 0' X-LSpam-Score: -3.6 (---) X-LSpam-Report: No, score=-3.6 required=5.0 tests=BAYES_00=-2.599, RCVD_IN_DNSWL_LOW=-1 autolearn=ham Subject: [vdr] [PATCH] GOTOX patch for vdr-1.7.16 X-BeenThere: vdr@linuxtv.org X-Mailman-Version: 2.1.11 Precedence: list Reply-To: VDR Mailing List List-Id: VDR Mailing List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 28 Jan 2011 14:40:37 -0000 Status: O X-Status: X-Keywords: X-UID: 24372 Hi, after some time I've improved the gotox patch for vdr - it is now correctly resolving condition for sending diseqc command in cDvbTuner::SetFrontend(void) even if diseqc command doesn't change also with cascaded diseqc switches. So the diseqc is now sent immediately after channel switch and not after frontend tuning is timeouted. It was tested with diseqc.conf entries like this (cascaded: motor <-> uncommitted switch <-> committed switch): S1.0W 11700 V 9750 t V G [E0 10 39 F1] v W30 [E0 10 38 FC] W30 v t S1.0W 99999 V 10600 t V G [E0 10 39 F1] v W30 [E0 10 38 FD] W30 v T S1.0W 11700 H 9750 t V G [E0 10 39 F1] V W30 [E0 10 38 FE] W30 V t S1.0W 99999 H 10600 t V G [E0 10 39 F1] V W30 [E0 10 38 FF] W30 V T S9.0E 11700 V 9750 t V G [E0 10 39 F1] v W30 [E0 10 38 FC] W30 v t S9.0E 99999 V 10600 t V G [E0 10 39 F1] v W30 [E0 10 38 FD] W30 v T S9.0E 11700 H 9750 t V G [E0 10 39 F1] V W30 [E0 10 38 FE] W30 V t S9.0E 99999 H 10600 t V G [E0 10 39 F1] V W30 [E0 10 38 FF] W30 V T BR, Ales diff -rup a/config.c b/config.c --- a/config.c 2010-06-06 12:06:43.000000000 +0200 +++ b/config.c 2011-01-28 14:44:30.888676207 +0100 @@ -326,6 +326,12 @@ cSetup::cSetup(void) LnbFrequLo = 9750; LnbFrequHi = 10600; DiSEqC = 0; + UseGotox = 0; + GotoxSpeed = 100; + GotoxRepeat = 0; + GotoxSN = 0; GotoxLat = 613; GotoxEW = 1; GotoxLong = 236; // Somewhere at Tampere, Finland :^) + GotoxMaxSwing = 60; + GotoxPrevSource = 0; SetSystemTime = 0; TimeSource = 0; TimeTransponder = 0; @@ -517,6 +523,15 @@ bool cSetup::Parse(const char *Name, con else if (!strcasecmp(Name, "LnbFrequLo")) LnbFrequLo = atoi(Value); else if (!strcasecmp(Name, "LnbFrequHi")) LnbFrequHi = atoi(Value); else if (!strcasecmp(Name, "DiSEqC")) DiSEqC = atoi(Value); + else if (!strcasecmp(Name, "UseGotox")) UseGotox = atoi(Value); + else if (!strcasecmp(Name, "GotoxSpeed")) GotoxSpeed = atoi(Value); + else if (!strcasecmp(Name, "GotoxRepeat")) GotoxRepeat = atoi(Value); + else if (!strcasecmp(Name, "GotoxSN")) GotoxSN = atoi(Value); + else if (!strcasecmp(Name, "GotoxLat")) GotoxLat = atoi(Value); + else if (!strcasecmp(Name, "GotoxEW")) GotoxEW = atoi(Value); + else if (!strcasecmp(Name, "GotoxLong")) GotoxLong = atoi(Value); + else if (!strcasecmp(Name, "GotoxMaxSwing")) GotoxMaxSwing = atoi(Value); + else if (!strcasecmp(Name, "GotoxPrevSource")) GotoxPrevSource = atoi(Value); else if (!strcasecmp(Name, "SetSystemTime")) SetSystemTime = atoi(Value); else if (!strcasecmp(Name, "TimeSource")) TimeSource = cSource::FromString(Value); else if (!strcasecmp(Name, "TimeTransponder")) TimeTransponder = atoi(Value); @@ -613,6 +628,15 @@ bool cSetup::Save(void) Store("LnbFrequLo", LnbFrequLo); Store("LnbFrequHi", LnbFrequHi); Store("DiSEqC", DiSEqC); + Store("UseGotox", UseGotox); + Store("GotoxSpeed", GotoxSpeed); + Store("GotoxRepeat", GotoxRepeat); + Store("GotoxSN", GotoxSN); + Store("GotoxLat", GotoxLat); + Store("GotoxEW", GotoxEW); + Store("GotoxLong", GotoxLong); + Store("GotoxMaxSwing", GotoxMaxSwing); + Store("GotoxPrevSource", GotoxPrevSource); Store("SetSystemTime", SetSystemTime); Store("TimeSource", cSource::ToString(TimeSource)); Store("TimeTransponder", TimeTransponder); diff -rup a/config.h b/config.h --- a/config.h 2010-09-12 13:31:21.000000000 +0200 +++ b/config.h 2011-01-28 14:45:10.882778898 +0100 @@ -229,6 +229,15 @@ public: int LnbFrequLo; int LnbFrequHi; int DiSEqC; + int GotoxRepeat; + int GotoxSN; + int GotoxEW; + int GotoxSpeed; + int GotoxLat; + int GotoxLong; + int GotoxMaxSwing; + int UseGotox; + int GotoxPrevSource; int SetSystemTime; int TimeSource; int TimeTransponder; diff -rup a/diseqc.c b/diseqc.c --- a/diseqc.c 2010-02-06 16:43:31.000000000 +0100 +++ b/diseqc.c 2011-01-28 14:46:03.418659831 +0100 @@ -134,6 +134,7 @@ cDiseqc::eDiseqcActions cDiseqc::Execute case 'V': return daVoltage18; case 'A': return daMiniA; case 'B': return daMiniB; + case 'G': return daGotoX; case 'W': *CurrentAction = Wait(*CurrentAction); break; case '[': *CurrentAction = Codes(*CurrentAction); return *CurrentAction ? daCodes : daNone; default: return daNone; diff -rup a/diseqc.h b/diseqc.h --- a/diseqc.h 2010-02-06 16:14:42.000000000 +0100 +++ b/diseqc.h 2011-01-28 14:46:10.495659376 +0100 @@ -22,6 +22,7 @@ public: daVoltage18, daMiniA, daMiniB, + daGotoX, daCodes, }; enum { MaxDiseqcCodes = 6 }; diff -rup a/dvbdevice.c b/dvbdevice.c --- a/dvbdevice.c 2010-05-01 11:47:13.000000000 +0200 +++ b/dvbdevice.c 2011-01-28 14:47:30.655659479 +0100 @@ -15,9 +15,11 @@ #include #include #include +#include #include "channels.h" #include "diseqc.h" #include "dvbci.h" +#include "skins.h" #include "menuitems.h" #include "sourceparams.h" @@ -265,6 +267,7 @@ private: fe_delivery_system frontendType; cChannel channel; const char *diseqcCommands; + int lastSource; eTunerStatus tunerStatus; cMutex mutex; cCondVar locked; @@ -292,6 +295,7 @@ cDvbTuner::cDvbTuner(int Device, int Fd_ lockTimeout = 0; lastTimeoutReport = 0; diseqcCommands = NULL; + lastSource = 0; tunerStatus = tsIdle; if (frontendType == SYS_DVBS || frontendType == SYS_DVBS2) CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); // must explicitly turn on LNB power @@ -365,6 +369,99 @@ static unsigned int FrequencyToHz(unsign return f; } +void HandleGotox(int fd_frontend, int new_source) +{ + + int gotoXTable[10] = { 0x00, 0x02, 0x03, 0x05, 0x06, 0x08, 0x0A, 0x0B, 0x0D, 0x0E }; + int satlong; + int satprev; + float waitseconds = 0; + float waitmaximum = 60; + + if (Setup.UseGotox == 0) + return; + + // Check if zapped into new source position? + if (new_source != Setup.GotoxPrevSource) { + if ((new_source & 0xFF000000) != 0x53000000) + return; // Fail, not S type source + satlong = (new_source & 0x00000FFFF); + satprev = (Setup.GotoxPrevSource & 0x0000FFFF); + if (new_source & 0x00008000) { + satlong ^= 0x0000FFFF; satlong++; satlong *= (-1); + } + if (Setup.GotoxPrevSource & 0x00008000) { + satprev ^= 0x0000FFFF; satprev++; satprev *= (-1); + } + if (Setup.GotoxSpeed > 0) { + waitseconds = fabs(satlong-satprev)/(float)(Setup.GotoxSpeed); + waitmaximum = 10*(float)(Setup.GotoxMaxSwing)/(float)(Setup.GotoxSpeed); + if (waitseconds < 0.0) waitseconds = 0.0; // Should not happen but ... + if (waitseconds > waitmaximum) waitseconds = 2 + waitmaximum; // Limit wait time to +2s over dish max. move + } + int Long=Setup.GotoxEW ? -Setup.GotoxLong : Setup.GotoxLong; + int Lat=Setup.GotoxSN ? -Setup.GotoxLat : Setup.GotoxLat; + double azimuth=M_PI+atan(tan((satlong-Long)*M_PI/1800)/sin(Lat*M_PI/1800)); + double x=acos(cos((satlong-Long)*M_PI/1800)*cos(Lat*M_PI/1800)); + double elevation=atan((cos(x)-0.1513)/sin(x)); + double SatHourangle=180+atan((-cos(elevation)*sin(azimuth))/(sin(elevation)*cos(Lat*M_PI/1800) + -cos(elevation)*sin(Lat*M_PI/1800)*cos(azimuth)))*180/M_PI; + int tmp=(int)(fabs(180-SatHourangle)*10); + tmp=(tmp/10)*0x10 + gotoXTable[ tmp % 10 ]; + int p2=(tmp%0x0100); + int p1=(tmp/0x0100); + if (SatHourangle < 180) + p1 |= 0xe0; + else + p1 |= 0xd0; + + dsyslog("DiSEqC GotoX %d (%d) -> %d (%d), wait time %4.1fs", + satprev, Setup.GotoxPrevSource, satlong, new_source, waitseconds); + +#if 1 + // Set high LNB voltage and tone off, then wait > 15ms + CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); + CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); + usleep(20000); + + // Send 1st GotoX command, then wait > 15ms + uchar gotox_bytes[5] = { 0xe0, 0x31, 0x6e, p1, p2}; + struct dvb_diseqc_master_cmd gotox_cmd; + memcpy(gotox_cmd.msg, gotox_bytes, 5); + gotox_cmd.msg_len = 5; + CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &gotox_cmd)); + usleep(20000); + + // Send repeated GotoX command, then wait > 15ms + if (Setup.GotoxRepeat) { + gotox_bytes[0] = 0xe1; + memcpy(gotox_cmd.msg, gotox_bytes, 5); + CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &gotox_cmd)); + usleep(20000); + } + + { + char mess_move[60]; + snprintf(mess_move,sizeof(mess_move),"Moving dish to %d.%d%s - %ds", \ + (new_source & 0x0800)?-satlong/10:satlong/10, \ + (new_source & 0x0800)?-satlong%10:satlong%10, \ + (new_source & 0x0800)?"E":"W", (int)waitseconds); + // Wait for dish movement and display message approx. for that time + Skins.QueueMessage(mtWarning, mess_move, int(1 + waitseconds - Setup.ChannelInfoTime), 0); + while (waitseconds > 0.0) { + usleep(100000); // 100ms + waitseconds = waitseconds - 100e-3; + } + } + +#endif + + Setup.GotoxPrevSource = new_source; + dsyslog("DiSEqC GotoX done."); + } +} + + bool cDvbTuner::SetFrontend(void) { #define MAXFRONTENDCMDS 16 @@ -394,7 +491,9 @@ bool cDvbTuner::SetFrontend(void) if (Setup.DiSEqC) { cDiseqc *diseqc = Diseqcs.Get(device, channel.Source(), channel.Frequency(), dtp.Polarization()); if (diseqc) { - if (diseqc->Commands() && (!diseqcCommands || strcmp(diseqcCommands, diseqc->Commands()) != 0)) { + if (diseqc->Commands() && (!diseqcCommands || \ + (strcmp(diseqcCommands, diseqc->Commands())) || \ + (strrchr(diseqc->Commands(),'G') && (channel.Source() != lastSource )))) { cDiseqc::eDiseqcActions da; for (char *CurrentAction = NULL; (da = diseqc->Execute(&CurrentAction)) != cDiseqc::daNone; ) { switch (da) { @@ -405,6 +504,7 @@ bool cDvbTuner::SetFrontend(void) case cDiseqc::daVoltage18: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break; case cDiseqc::daMiniA: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A)); break; case cDiseqc::daMiniB: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break; + case cDiseqc::daGotoX: HandleGotox(fd_frontend, channel.Source()); break; case cDiseqc::daCodes: { int n = 0; uchar *codes = diseqc->Codes(n); @@ -420,6 +520,7 @@ bool cDvbTuner::SetFrontend(void) } } diseqcCommands = diseqc->Commands(); + lastSource = channel.Source(); } frequency -= diseqc->Lof(); } @@ -429,6 +530,10 @@ bool cDvbTuner::SetFrontend(void) } } else { + // Send GotoX DiSEqC command if activated in vdr setup. Then wait with high LNB voltage + // estimated time for dish movement + HandleGotox(fd_frontend, channel.Source()); + int tone = SEC_TONE_OFF; if (frequency < (unsigned int)Setup.LnbSLOF) { frequency -= Setup.LnbFrequLo; @@ -541,6 +646,7 @@ void cDvbTuner::Action(void) if (Timer.TimedOut()) { tunerStatus = tsSet; diseqcCommands = NULL; + lastSource = 0; if (time(NULL) - lastTimeoutReport > 60) { // let's not get too many of these isyslog("frontend %d/%d timed out while tuning to channel %d, tp %d", adapter, frontend, channel.Number(), channel.Transponder()); lastTimeoutReport = time(NULL); @@ -551,6 +657,7 @@ void cDvbTuner::Action(void) if (Status & FE_REINIT) { tunerStatus = tsSet; diseqcCommands = NULL; + lastSource = 0; isyslog("frontend %d/%d was reinitialized", adapter, frontend); lastTimeoutReport = 0; continue; diff -rup a/menu.c b/menu.c --- a/menu.c 2010-06-06 11:56:16.000000000 +0200 +++ b/menu.c 2011-01-28 14:50:08.625533824 +0100 @@ -2890,8 +2890,15 @@ void cMenuSetupLNB::Setup(void) Add(new cMenuEditIntItem( tr("Setup.LNB$SLOF (MHz)"), &data.LnbSLOF)); Add(new cMenuEditIntItem( tr("Setup.LNB$Low LNB frequency (MHz)"), &data.LnbFrequLo)); Add(new cMenuEditIntItem( tr("Setup.LNB$High LNB frequency (MHz)"), &data.LnbFrequHi)); - } - + } + Add(new cMenuEditBoolItem(tr("Setup.LNB$Use GotoX dish positioning"), &data.UseGotox)); + if (data.UseGotox) { + Add(new cMenuEditBoolItem(tr("Setup.LNB$Repeat GotoX commands"), &data.GotoxRepeat)); + Add(new cMenuEditIntpItem(tr("Setup.LNB$Latitude"), &data.GotoxLat,0,900,&data.GotoxSN,tr("North"),tr("South"))); + Add(new cMenuEditIntpItem(tr("Setup.LNB$Longitude"), &data.GotoxLong,0,1800,&data.GotoxEW,tr("West"),tr("East"))); + Add(new cMenuEditIntItem(tr("Setup.LNB$GotoxMaxSwing"), &data.GotoxMaxSwing,0,180)); + Add(new cMenuEditIntdItem(tr("Setup.LNB$Rotor speed (deg/s)"), &data.GotoxSpeed, 1, 100)); + } SetCurrent(Get(current)); Display(); } @@ -2899,10 +2906,15 @@ void cMenuSetupLNB::Setup(void) eOSState cMenuSetupLNB::ProcessKey(eKeys Key) { int oldDiSEqC = data.DiSEqC; + int oldUseGotox = data.UseGotox; eOSState state = cMenuSetupBase::ProcessKey(Key); if (Key != kNone && data.DiSEqC != oldDiSEqC) Setup(); + + if (Key != kNone && data.UseGotox != oldUseGotox) + Setup(); + return state; } diff -rup a/menuitems.c b/menuitems.c --- a/menuitems.c 2010-06-06 12:37:08.000000000 +0200 +++ b/menuitems.c 2011-01-28 14:50:21.357534700 +0100 @@ -1113,3 +1113,121 @@ void cMenuSetupPage::SetupStore(const ch if (plugin) plugin->SetupStore(Name, Value); } + +// cMenuEditIntpItem & cMenuEditIntdItem for GotoX function + +void cMenuEditIntpItem::Set(void) +{ + char buf[16]; + snprintf(buf, sizeof(buf), "%d.%d %s", *value/10, *value % 10, *value2 ? trueString : falseString); + SetValue(buf); +} + +void cMenuEditIntdItem::Set(void) +{ + char buf[16]; + snprintf(buf, sizeof(buf), "%d.%d", *value/10, *value % 10); + SetValue(buf); +} + + +cMenuEditIntpItem::cMenuEditIntpItem(const char *Name, int *Value, int Min, int Max,int *Value2, const char *FalseString,const char *TrueString):cMenuEditIntItem(Name, Value, Min, Max) +{ + value = Value; + value2= Value2; + trueString = TrueString; + falseString = FalseString; + min = Min; + max = Max; + Set(); +} + +cMenuEditIntdItem::cMenuEditIntdItem(const char *Name, int *Value, int Min, int Max):cMenuEditIntItem(Name, Value, Min, Max) +{ + value = Value; + min = Min; + max = Max; + Set(); +} + +eOSState cMenuEditIntpItem::ProcessKey(eKeys Key) +{ + eOSState state = cMenuEditItem::ProcessKey(Key); + if (state == osUnknown) + { + int newValue = *value; + int newValue2= *value2; + Key = NORMALKEY(Key); + switch (Key) { + case kNone : break; + case k0...k9: + if (fresh) + { + *value = 0; + fresh = false; + } + newValue = *value * 10 + (Key - k0); + break; + case kLeft : + newValue2 = 0; + fresh = true; + break; + case kRight : + newValue2 = 1; + fresh = true; + break; + default : + if (*value < min) { *value = min; Set(); } + if (*value > max) { *value = max; Set(); } + return state; + } + if ((!fresh || min <= newValue) && newValue <= max) + { + *value = newValue; + *value2 = newValue2; + Set(); + } + state = osContinue; + } + return state; +} + +eOSState cMenuEditIntdItem::ProcessKey(eKeys Key) +{ + eOSState state = cMenuEditItem::ProcessKey(Key); + if (state == osUnknown) + { + int newValue = *value; + Key = NORMALKEY(Key); + switch (Key) { + case kNone : break; + case k0...k9: + if (fresh) + { + *value = 0; + fresh = false; + } + newValue = *value * 10 + (Key - k0); + break; + case kLeft : + newValue = *value - 1; + fresh = true; + break; + case kRight : + newValue = *value + 1; + fresh = true; + break; + default : + if (*value < min) { *value = min; Set(); } + if (*value > max) { *value = max; Set(); } + return state; + } + if ((!fresh || min <= newValue) && newValue <= max) + { + *value = newValue; + Set(); + } + state = osContinue; + } + return state; +} diff -rup a/menuitems.h b/menuitems.h --- a/menuitems.h 2010-06-06 12:32:38.000000000 +0200 +++ b/menuitems.h 2011-01-28 14:50:36.217533731 +0100 @@ -201,4 +201,22 @@ public: void SetPlugin(cPlugin *Plugin); }; +class cMenuEditIntpItem : public cMenuEditIntItem { +protected: + virtual void Set(void); + const char *falseString, *trueString; + int *value2; +public: + cMenuEditIntpItem(const char *Name, int *Value, int Min = 0, int Max = INT_MAX, int *Value2=0, const char *FalseString = "", const char *TrueSting = NULL); + virtual eOSState ProcessKey(eKeys Key); +}; + +class cMenuEditIntdItem : public cMenuEditIntItem { +protected: + virtual void Set(void); +public: + cMenuEditIntdItem(const char *Name, int *Value, int Min = 0, int Max = INT_MAX); + virtual eOSState ProcessKey(eKeys Key); +}; + #endif //__MENUITEMS_H