PasjaGSM.pl
  Jesteś w: Forum > Najlepszy sposób na zmienianie ustawień w aplikacjach


Najlepszy sposób na zmienianie ustawień w aplikacjach

Forum.PasjaGSM.pl » ...:Sprzęt:... » Nokia » DCT-3 » [DCT3] Modyfikacje HW i SW » NokiX » Programowanie » Najlepszy sposób na zmienianie ustawień w aplikacjach
Poprzedni temat «» Następny temat
Autor Wiadomość
 
yak 
Starszyzna



Telefon: Kilka DCT3
Operator: Vodafone
Pomógł: 20 razy
Wiek: 37
Dołączył: 21 Gru 2004
Posty: 774
Skąd: Bochum / Niemcy
Wysłany: 2006-01-12, 18:09   

Nad supportem dla C++ w nowym SDK sie zastanawiałem ale postanowiłem jednak odpuścić, przynajmniej narazie. Problem jest z tym, że kod wstawiany jest poprzez Rexx'a i zewnetrzne symbole z C maja tam te same nazwy. Tu powstaje problem bo C++ pozwala na przeladowywanie nazw funkcji i sa one zakodowane w takiej dziwnej formie. Muszę to jakoś rozwiązać. Tak naprawdę ten problem występuje częściowo już teraz. Gdy zdefiniujesz np. dwa dispatchery, powiedzmy dispatcher i DISPATCHER to bedziesz mial problem bo dla Rexx'a to sa te same symbole. Jest to coś nad czym muszę jeszcze pogłówkować i jakoś rozwiązać zachowując kompatybilność.
_________________
NokiX Ci się podoba? Kliknij i wyraź to!
^
 
 
 
     
AdSense


druidbartek 
Expert



Telefon: DCT-3
Operator: Era
Pomógł: 39 razy
Wiek: 31
Dołączył: 13 Wrz 2005
Posty: 1006
Skąd: Wrocław
Wysłany: 2006-01-12, 20:02   

witam! postanowiłem ponownie tutaj o tym napisać bo bądź co bądź chodzi o zapisywanie ustawień gry do eepromu. W grze Mine Sweeper pierwotnej wersji miało być dostępne 5 poziomów gry - od 10 do 30 min. W ostatnim momencie zauważyłem że wybierając 5 poziom ustawia się on na 1. Myślałem, że jakoś rozwiążę ten problem ale do tej pory nie udało mi się więc w obecnej wersji mamy do wyboru 10, 15, 20 lub 25 min.

w menu.h dodałem:
Kod:
#define STATE_LEVEL        2


a w menu.c:

Kod:
extern rexx_uint confid_level;
extern const struct menu_item i_level;
static const struct level_dialog level_dialog={NULL,0,NULL,1,5};
static void make_game_menu(void)
{
   // ...
   menu_add_item(1,0,&i_level);
   //...
}
case MSG_D_QUIT_NOW: // called when we get back from some other dispatcher
{
   bajt oldstate=app.state;
   app.state=STATE_MENU;
   if(oldstate==STATE_LEVEL)
   {
      if(message.argv[0]==QNS_OK)
      {
         if(own_get_config(confid_level)+1!=app.level)
         {
            own_set_config(confid_level,app.level-1); /* save the new level to eeprom */
            free_game(); /* cancel last game */
         }
      }
   }
   make_game_menu();
   menu_reopen();
   msg=MSG_R_STAY;
   break;
}
case OMSG_LEVEL:
{
   app.level=own_get_config(confid_level)+1; /* load level from eeprom */
         send_message(MSG_START_HANDLER|MSG_3P,id_level_dialog,&app.level,&level_dialog); /* open level dialog */
   app.state=STATE_LEVEL;
   msg=MSG_NOP;
   break;
}

pozostały kod gry raczej niczego tutaj nie wnosi ponieważ nawet nie uruchamiając gry, będąc cały czas w menu gry problem występuje. Zrobiłem jeszcze próbę jeśli chciałem 6 leveli zrobić. i sutuacja jest identyczna - wchodząc w menu gry do poziom jest dostępne 6 beleczek ( te jak przy głośności itp) ale jeśli ustawię poziom na 5 nacisnę OK i ponownie wejdę do Poziom gry to poziom jest ustawiony na 1. jeśli wybiorę 6, nacisnę OK to poziom ustawia sie na 2. I nie mam pojęcia gdzie tkwi błąd : (
^
 
     
sander18 
Starszyzna
Nie Wie Co Pisze ;)



Telefon: nokie
Operator: Orange
Pomógł: 29 razy
Wiek: 34
Dołączył: 02 Mar 2005
Posty: 512
Skąd: z kątowni ;)
Wysłany: 2006-01-12, 20:13   

a zobacz jak masz w samym skrypcie .nrx:
Kod:
/* creating config ids */
confid_level=create_config_id(2)

w dwoch bitach zapiszesz maksymalnie do 4 leveli i logiczne jest wiec, ze jak ustawiasz 5 to zmienia na jeden a jak ustawiasz 6 to zmienia na 2.
sproboj tak:
Kod:
/* creating config ids */
confid_level=create_config_id(3)

powinno pomoc :]

[ Dodano: 12-01-2006, 20:19 ]
obszerniejsze wyjasnienie:
Kod:
level  wartosc  config_id
       normalnie binarnie
  1        0        00
  2        1        01
  3        2        10
  4        3        11
  5        4       100
  6        5       101

czyli jesli ustawisz level 5 lub 6, a masz do dyspozycji 2 bity, to nie wezmie pod uwage pierwszego bitu... juz chyba powinno byc wszystko jasne :]
_________________
W dżungli amazońskiej odkryto nowy gatunek kameleona. Ma 65 tys. kolorów i polifoniczne dzwonki :D
^
 
 
     
druidbartek 
Expert



Telefon: DCT-3
Operator: Era
Pomógł: 39 razy
Wiek: 31
Dołączył: 13 Wrz 2005
Posty: 1006
Skąd: Wrocław
Wysłany: 2006-01-12, 20:29   

sander18, dzieki, ale osioł ze mnie, nie wiem jak to przeoczyłem

Dopisze jeszcze coś innego. Yak juz wyjaśnił że żeby zarezerwowac więcej niż 1B w eepromie należy używać funkcji eeprom_read i eeprom_write, podobne pytanie zadałem już dotyczące RAMu i otrzymałem odpowiedź mam nadzieję że z eepromem również ją uzyskam. Chodzi mi o to ile mamy do dyspozycji eepromu, tzn nie mam zamiaru pisać aplikacji zbyt łakomej na eeprom, ot tak z ciekawości chciałbym wiedzieć : )
Ostatnio zmieniony przez druidbartek 2006-05-12, 20:42, w całości zmieniany 1 raz  
^
 
     
jaras 
Nowicjusz



Telefon: Nokia 5110
Operator: Plus
Pomógł: 2 razy
Wiek: 44
Dołączył: 09 Kwi 2005
Posty: 62
Skąd: "LAC: 41008" ;-)
Wysłany: 2006-01-13, 09:48   

Witaj, @ yak.

yak napisał/a:
Nad supportem dla C++ w nowym SDK sie zastanawiałem ale postanowiłem jednak odpuścić, przynajmniej narazie. Problem jest z tym, że kod wstawiany jest poprzez Rexx'a i zewnetrzne symbole z C maja tam te same nazwy. Tu powstaje problem bo C++ pozwala na przeladowywanie nazw funkcji i sa one zakodowane w takiej dziwnej formie. Muszę to jakoś rozwiązać. Tak naprawdę ten problem występuje częściowo już teraz. Gdy zdefiniujesz np. dwa dispatchery, powiedzmy dispatcher i DISPATCHER to bedziesz mial problem bo dla Rexx'a to sa te same symbole. Jest to coś nad czym muszę jeszcze pogłówkować i jakoś rozwiązać zachowując kompatybilność.
Poczytałem sobie nieco o tzw. manglowaniu nazw C++ i rzeczywiście, przyznaję, że jest z tym dość spory problem.

Mianowicie, manglowanie nazw C++ nie ma żadnego standardu, a okazuje się nawet, że różne wersje tego samego kompilatora różnie manglują nazwy (gcc także nie jest tu wyjątkiem). Rozumiem więc, dlaczego tak trudno byłoby wprowadzić do SDK obsługę C++.

Jednak ostatnio, przeszukując sobie internet na temat dokumentacji i różnych ciekawostek związanych z procesorem ARM, znalazłem pewien projekt o nazwie WinARM (ale nie myl tego z aplikacyjką do rev-engineeringu DCT-3 o tej samej nazwie!), szerzej opisany i dostępny do ściągnięcia tutaj.

Jest to pakiet różnych i niezbędnych programów służących do szeroko rozumianego programowania procesorów ARM. Pakiet ten zawiera kompilator gcc i g++ wraz z assemblerem as, linkerem i nawet "demanglerem" nazw nm, oprócz tego różne toolsy takie jak debuggery, a nawet Programmers Notepad. Nie muszę chyba pisać, że są tam wszystkie niezbędne pliki nagłówkowe do C, jak i do C++ oraz potrzebne pliki biblioteczne dla kodu ARM. ;-)

Może dałoby się coś zrobić z tym? A może jakoś wykorzystać choćby wspomniany demangler nazw C++? (Oczywiście, wraz z całym kompilatorem gcc w tejże wersji.)

Wszak, z tego, co wyczytałem, to manglowanie w przypadku gcc jeszcze nie jest tak koszmarne, jak np. w przypadku MSVC++ (tam to dopiero jest "jazda": znaki "?" czy "@" w nazwach symboli, to normalka ;-) - tutaj (o ile dobrze zrozumiałem te opisy) jest co najwyżej tylko znak "_" (podkreślenie) i kombinacje małych/dużych liter i cyfr. Wtedy może po prostu przerobić NokiX'owy linker tak, żeby uzwględniał te zmanglowane nazwy.

Jedynym problemem wtedy, jak wspomniałeś, byłoby nierozróżnianie przez Rexx wielkości liter w zmiennych, co przy manglowaniu nazw C++ mogłoby być sporym problemem. No, to mam takiego pomysła ;-), żeby linker ten (NokiX'owy) wyłapywał różne nazwy, które różnią się między sobą tylko wielkością liter i dorabiał na ich końcach jeszcze jakieś charakterystyczne znaki (nie wiem - cyfry, może litery), ewentualnie poprzedzone jakimś znakiem podkreślenia. A potem takie właśnie symbole wstawiał do kodu Rexx, jako symbole zewnętrzne i ewentualnie tylko dorabiał do nich bardziej zrozumiałe w "ludzkim języku" nazwy zmiennych dla reszty kodu Rexx.

Fajnie by było sobie programować Nokię przy użyciu klas i obiektów C++, czyli opakować te wszystkie niewygodne w użyciu dispatchery w ładne klasy, a potem nie martwiąc się już o szczegóły konstrukcyjne danego telefonu czy firmware'u, pisać sobie pod niego aplikacje. :-)

Nie wgłębiałem się jednak aż nadto w szczegóły implementacji NokiX'a, ani też nie "siedzę" w kompilatorach (także gcc), dlatego moją wypowiedź traktuj raczej tylko jako pewną wskazówkę, podpowiedź: "co by tu można wykombinować, żeby działało". Ty zaś, mając z pewnością o wiele większy mózg ode mnie, być może bedziesz lepiej wiedział, co z tą informacją zrobić (a może nawet... olać ;-D).

Pozdrawiam Cię serdecznie.

PS. Nie wykluczam zresztą sytuacji takiej, że mój post jest całkiem tu bezwartościowy, gdyż Ty już dawno ten pakiet WinARM na swoim dysku masz i właśnie głowisz się, jak go dostosować do NokiX'a. ;-)
_________________
Jarosław Krasuski (jaras)
^
 
 
     
yak 
Starszyzna



Telefon: Kilka DCT3
Operator: Vodafone
Pomógł: 20 razy
Wiek: 37
Dołączył: 21 Gru 2004
Posty: 774
Skąd: Bochum / Niemcy
Wysłany: 2006-01-14, 17:46   

Dziekuje za wszystkie wskazówki, niektóre na pewno się przydadza. Nad konstrukcja obecnego SDK spedzilem sporo czasu i nie chcialem go wydłużać przez C++. Teraz jednak znów będę mógł nad tym pogłówkować i za jakiś czas support dla C++ pewnie będzie dodany w jakiejś formie.
_________________
NokiX Ci się podoba? Kliknij i wyraź to!
^
 
 
 
     
druidbartek 
Expert



Telefon: DCT-3
Operator: Era
Pomógł: 39 razy
Wiek: 31
Dołączył: 13 Wrz 2005
Posty: 1006
Skąd: Wrocław
Wysłany: 2006-01-20, 16:13   

witam

jako że nie da rady zrobić czegoś w rodzaju tablicy pól bitowych, a zaraz po sesji biorę się za parę fajnych gierek ( jedna juz mówiłem jaką, reszty nie powiem :p ). W jednej z nich planowałem dość sporych rozmiarów planszę, nawet 20x20 pól żeby się fajnie grało. Trochę głupio by zjadać ponad 400B z RAM-u i kombinowałem ( na zajęciach z algebry :d ) jak to zrobić na bitach. To co tu opisze nie wiem czy jest najlepsze, po prostu nic innego mi nie przychodzi do głowy, co ważniejsze taki zapis pozwala dobrać się do dowolnych bitów i zmieniać je, nie ruszając pozostałych. Jeśli da się zrealizować to prościej, proszę o wskazówki : ]

powiedzmy że każde pole musi być opisane 2 bitami, plansza będzie mieć 20x20 pól. Czyli mam:

Kod:
unsigned char fields[20][5]; // 100B, a w 1B opiszę 4 pola, łącznie 400 pól


zmienna y zmienia wiersz w tablicy od 0 do 19. Zmienna x będzie zmieniać kolumnę w tablicy ( od 0 do 4 ) oraz, dodatkowo odpowiada za to, które bity chcemy użyć. Czyli będzie się zmieniać w zakresie 0-19.
Do tablicy odwołuje się tak:
Kod:
fields[20][x/4];

a to która parę bitów zamierzam używać uzyskam dzięki modulo x%4

teraz zapodam przykład jakiegoś pola w tablicy, niech y = 1, a x to będzie liczba od 4 do 7, czyli mam fields[y][x/4] = 228; // binarnie 0b11100100, taki przykład żeby wszystkie możliwości był czyli 0b11, 0b10, 0b01 i 0b00.

i teraz chcemy odczytać kolejne 2 bity z tej liczby, mam tak:
Kod:
(fields[1][x/4] & (3 << 2*(x%4 )) >> (2 * x%4 )


dla x = 4 mam:
Kod:
(fields[1][4/4] & (3 << 2*(4%4 )) >>  (2 * 4%4 ) // wychodzi 0 dla pierwszej pary bitów bo:
0b11100100 & 0b00000011 co daje  0b00000000 a przesuwając o 0 bitów ciągle daje nam 0

dla x = 5:
Kod:
(fields[1][5/4] & (3 << 2*(5%4 )) >>  (2 * 5%4 ) // co daje 1 czyli 0b01 dla pierwszej pary bitów bo:
0b11100100 & 0b00001100 co daje  0b00000100 a przesuwając o 2 bity ciągle daje nam 1

dla x = 6:
Kod:
(fields[1][6/4] & (3 << 2*( 6%4 )) >> (2 * 6%4 ) co daje 2 czyli 0b10 dla pierwszej pary bitów bo:
0b11100100 & 0b00110000 co daje  0b00100000 a przesuwając o 4 bity ciągle daje nam 2

a dla x = 7:
Kod:
(fields[1][6/4] & (3 << 2*(7%4 )) >> (2 * 6%4 ) co daje 3 czyli 0b11 dla pierwszej pary bitów bo:
0b11100100 & 0b1100000000 co daje  0b11000000 a przesuwając o 6 bitów ciągle daje nam 3

to było odczytywanie, zapis jest w ten sposób:
Kod:
(fields[1][x/4] & ~(3 << 2*(x%4 )) | ( z << 2*(x%4 )), gdzie z to wartość na którą chcemy zmienić dana parę bitów


dla x = 4, wartość 1 pary chce zmienic na 0b11 czyli mam:
Kod:
(fields[1][4/4] & ~(3 << 2*(4%4 )) | ( z << 2*(4%4 )) // co daje 3 czyli 0b11 dla pierwszej pary bitów bo:
0b11100100 & 0b11111100 co daje  0b11100100 a teraz 0b11100100 | 0b00000011 = 0b11100111


dla x = 5, wartość 2 pary chce zmienic na 0b10 czyli mam:
Kod:
(fields[1][x/4] & ~(3 << 2*(x%4 )) | ( z << 2*(x%4 )) // co daje 2 czyli 0b10 dla 2 pary bitów bo:
0b11100100 & 0b11110011 co daje  0b11100000 a teraz 0b11100000 | 0b00001000 = 0b11101000


dla x = 6, wartość 3 pary chce zmienic na 0b01 czyli mam:
Kod:
(fields[1][x/4] & ~(3 << 2*(x%4 )) | ( z << 2*(x%4 )) // co daje 1 czyli 0b01 dla 3 pary bitów bo:
0b11100100 & 0b11001111 co daje  0b11000100 a teraz 0b11000100 | 0b00010000 = 0b11010100


a dla x = 7, wartość 4 pary chce zmienic na 0b00 czyli mam:
Kod:
(fields[1][x/4] & ~(3 << 2*(x%4 )) | ( z << 2*(x%4 ))  // co daje 0 czyli 0b00 dla 4 pary bitów bo:
0b11100100 & 0b00111111 co daje  0b00100100 a teraz 0b00100100 | 0b00000000 = 0b00100100


mam nadzieje, e nigdzie mi się błąd nie zakradła przy przepisywaniu tyyylu cyferek. Mi coś takiego będzie potrzebne na pewno, a jeśli ktoś ma lepszy pomysł to chętnie wysłucham.

pozdrawiam wszystkich,

druidbartek
Ostatnio zmieniony przez druidbartek 2006-01-20, 16:59, w całości zmieniany 1 raz  
^
 
     
yak 
Starszyzna



Telefon: Kilka DCT3
Operator: Vodafone
Pomógł: 20 razy
Wiek: 37
Dołączył: 21 Gru 2004
Posty: 774
Skąd: Bochum / Niemcy
Wysłany: 2006-01-20, 16:29   

Pomysl dobry. Ja tylko chciałem zauważyć, że w C istnieją operatory bitowe które powinny poprawić trochę czytelność (a może i wygenerują krótszy kod). Można je stosować zamiast mnożenia/dzielenia przez potęgi dwójki.

Przesunięcie bitowe w lewo: <<
Przesunięcie bitowe w prawo: >>

Na przykład 5 >> 1 = 3, czy 2 << 3 = 8.
_________________
NokiX Ci się podoba? Kliknij i wyraź to!
^
 
 
 
     
druidbartek 
Expert



Telefon: DCT-3
Operator: Era
Pomógł: 39 razy
Wiek: 31
Dołączył: 13 Wrz 2005
Posty: 1006
Skąd: Wrocław
Wysłany: 2006-05-13, 22:08   

[ Wysłany: 2006-01-20, 17:02 ]
dzieki yak za info ; )
nie wiem dlaczego za pierwszym razem tego wszędzie nie zauważyłem, teraz jest już wszędzie poprawione : )

[ Dodano: 2006-05-13, 23:08 ]
ale pokręciłem to co wyżej napisałem. napisze jeszcze raz w takiej bardziej ludzkiej postaci, może komuś się przyda. Ogólnie ma to zastosowanie do sytuacji jeśli potrzebujemy tablicy o rozmiarze pojedynczego pola 1, 2 lub 4 bitów. Innych wielkości nie biorę pod uwagę bo wtedy i tak się by traciło miejsce (np jesli wziąść pole 3 bitowe to i tak 1 bajta starczy ledwo na 2 pola, to już lepiej wziąść 4 bitowe i też będą 2 ale za to większe ; ])

Powiedzmy że chcemy tablicę o wymiarach 10 na 20 przy czym pojedyncze pole niech będzie 4 bitowe. W nagłówkowym napsałem sobie ot coś takiego:
Kod:
#define TAB_WIDTH   20 // nasza szerokośc tablicy
#define TAB_HEIGHT  10 // a to jej wysokość
#define SIZE_POOL   4 // 1, 2 lub 4 bity na pole

#define SIZE_POOL   4 // 1, 2 lub 4 bity na pole

#if SIZE_POOL == 1
#define SIZE_MASK   1  // 0b1
#elif SIZE_POOL == 2
#define SIZE_MASK   3  // 0b11
#elif SIZE_POOL == 4
#define SIZE_MASK   15 // 0b1111
#else
#error "Bad value for SIZE_POOL!"
#endif

#define SHIFT_POOL  ( SIZE_POOL * (x % ( 8 / SIZE_POOL ) ) )

wszystko raczej jasne. no i dalej to juz z górki:
Kod:
unsigned char table[TAB_HEIGHT][SIZE_POOL*TAB_WIDTH/8];

prosta kalkulacja SIZE_POOL*TAB_WIDTH/8 = 4*20/8=10 a więc tak naprawdę zostanie utworzona tablica 10x10, jednak zapamiętamy w niej 200 wartości (4 bitowych) : ]

kolejny krok to 2 malutkie funkcje żeby wszystko było banalnie proste:
Kod:

// odczyt z tablicy; read_table(y,x) == val odpowiada table[y][x] == val
UBYTE read_table(unsigned char y, unsigned char x)
{
   return ( (table[y][SIZE_POOL*x/8] & ( SIZE_MASK << SHIFT_POOL ) ) >> SHIFT_POOL );
}

// zapis do tablicy; write_table(y,x,val) oznacza tyle co table[y][x] = val
void write_table(unsigned char y, unsigned char x, unsigned char val)
{
   table[y][SIZE_POOL*x/8] = ( ( table[y][SIZE_POOL*x/8] & ( ~( SIZE_MASK << SHIFT_POOL ) ) ) | ( val << SHIFT_POOL ) );
}

wot wsjo, proste co nie?
testowane na saperze i działa :D
^
 
     
Wyświetl posty z ostatnich:   
Odpowiedz do tematu
Nie możesz pisać nowych tematów
Nie możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz głosować w ankietach
Nie możesz załączać plików na tym forum
Nie możesz ściągać załączników na tym forum
Dodaj temat do Ulubionych
Wersja do druku

Skocz do: