Advertisement
qtinio

hmmmm main

Apr 24th, 2019
255
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 33.57 KB | None | 0 0
  1. /****************************************************
  2. Wirtualne zespoly robocze - przykladowy projekt w C++
  3. Do zadań dotyczących współpracy, ekstrapolacji i
  4. autonomicznych obiektów
  5. ****************************************************/
  6.  
  7. #include <windows.h>
  8. #include <math.h>
  9. #include <time.h>
  10. #include <string>
  11. #include <gl\gl.h>
  12. #include <gl\glu.h>
  13. #include <iterator>
  14. #include <map>
  15. using namespace std;
  16.  
  17. #include "objects.h"
  18. #include "graphics.h"
  19. #include "net.h"
  20.  
  21.  
  22. bool if_different_skills = true; // czy zró¿nicowanie umiejêtnoœci (dla ka¿dego pojazdu losowane s¹ umiejêtnoœci
  23. // zbierania gotówki i paliwa)
  24.  
  25. FILE *f = fopen("vct_log.txt", "w"); // plik do zapisu informacji testowych
  26.  
  27. MovableObject *my_vehicle; // Object przypisany do tej aplikacji
  28.  
  29. Terrain terrain;
  30. map<int, MovableObject*> network_vehicles;
  31. // ****************************************************************************
  32. int tim = -1;
  33. float wysylka = -1;
  34. int procent_uzgodniony = 0;
  35. float stare_money = 0;
  36.  
  37. float fDt; // sredni czas pomiedzy dwoma kolejnymi cyklami symulacji i wyswietlania
  38. long VW_cycle_time, counter_of_simulations; // zmienne pomocnicze potrzebne do obliczania fDt
  39. long start_time = clock(); // czas od poczatku dzialania aplikacji
  40. long group_existing_time = clock(); // czas od pocz¹tku istnienia grupy roboczej (czas od uruchom. pierwszej aplikacji)
  41.  
  42. multicast_net *multi_reciv; // wsk do obiektu zajmujacego sie odbiorem komunikatow
  43. multicast_net *multi_send; // -||- wysylaniem komunikatow
  44.  
  45. HANDLE threadReciv; // uchwyt w¹tku odbioru komunikatów
  46. extern HWND main_window;
  47. CRITICAL_SECTION m_cs; // do synchronizacji wątków
  48.  
  49. bool SHIFT_pressed = 0;
  50. bool CTRL_pressed = 0;
  51. bool ALT_pressed = 0;
  52. bool L_pressed = 0;
  53. //bool rejestracja_uczestnikow = true; // rejestracja trwa do momentu wziêcia przedmiotu przez któregokolwiek uczestnika,
  54. // w przeciwnym razie trzeba by przesy³aæ ca³y state œrodowiska nowicjuszowi
  55.  
  56. // Parametry widoku:
  57. extern ViewParameters par_view;
  58.  
  59. bool mouse_control = 0; // sterowanie pojazdem za pomoc¹ myszki
  60. int cursor_x, cursor_y; // polo¿enie kursora myszki w chwili w³¹czenia sterowania
  61.  
  62. extern float TransferSending(int ID_receiver, int transfer_type, float transfer_value);
  63. // *********************************************
  64. int zaznaczony_id = -1;
  65. int procent = 50;
  66. // ***********************************************
  67. enum frame_types {
  68. OBJECT_STATE, ITEM_TAKING, ITEM_RENEWAL, COLLISION, TRANSFER, ZAPRASZALAK, PRZYJAZNIALAK, NEGOCJALAK, AKCEPTOWALAK
  69. };
  70.  
  71. enum transfer_types { MONEY, FUEL};
  72.  
  73. struct Frame
  74. {
  75. int iID;
  76. int frame_type;
  77. ObjectState state;
  78.  
  79. int iID_receiver; // nr ID adresata wiadomoœci (pozostali uczestnicy powinni wiadomoœæ zignorowaæ)
  80.  
  81. int item_number; // nr przedmiotu, który zosta³ wziêty lub odzyskany
  82. Vector3 vdV_collision; // wektor prêdkoœci wyjœciowej po kolizji (uczestnik o wskazanym adresie powinien
  83. // przyj¹æ t¹ prêdkoœæ)
  84.  
  85. int transfer_type; // gotówka, paliwo
  86. float transfer_value; // iloœæ gotówki lub paliwa
  87. int team_number;
  88.  
  89. long existing_time; // czas jaki uplyn¹³ od uruchomienia programu
  90. };
  91.  
  92.  
  93. //******************************************
  94. // Funkcja obs³ugi w¹tku odbioru komunikatów
  95. DWORD WINAPI ReceiveThreadFunction(void *ptr)
  96. {
  97. multicast_net *pmt_net = (multicast_net*)ptr; // wskaŸnik do obiektu klasy multicast_net
  98. int size; // liczba bajtów ramki otrzymanej z sieci
  99. Frame frame;
  100. ObjectState state;
  101.  
  102. while (1)
  103. {
  104. size = pmt_net->reciv((char*)&frame, sizeof(Frame)); // oczekiwanie na nadejœcie ramki
  105. // Lock the Critical section
  106. EnterCriticalSection(&m_cs); // wejście na ścieżkę krytyczną - by inne wątki (np. główny) nie współdzielił
  107. if (wysylka != -1) {
  108. Frame frame;
  109. frame.frame_type = TRANSFER;
  110. frame.iID_receiver = tim;
  111. frame.transfer_type = MONEY;
  112. frame.transfer_value = wysylka;
  113. frame.iID = my_vehicle->iID;
  114. multi_send->send((char*)&frame, sizeof(Frame));
  115. my_vehicle->state.money -= frame.transfer_value;
  116. wysylka = -1;
  117. }
  118. switch (frame.frame_type)
  119. {
  120. case OBJECT_STATE: // podstawowy typ ramki informuj¹cej o stanie obiektu
  121. {
  122. state = frame.state;
  123. //fprintf(f,"odebrano state iID = %d, ID dla mojego obiektu = %d\n",state.iID,my_vehicle->iID);
  124. if ((frame.iID != my_vehicle->iID)) // jeœli to nie mój w³asny Object
  125. {
  126.  
  127. if ((network_vehicles.size() == 0) || (network_vehicles[frame.iID] == NULL)) // nie ma jeszcze takiego obiektu w tablicy -> trzeba go stworzyæ
  128. {
  129. MovableObject *ob = new MovableObject(&terrain);
  130. ob->iID = frame.iID;
  131. network_vehicles[frame.iID] = ob;
  132. if (frame.existing_time > group_existing_time) group_existing_time = frame.existing_time;
  133. ob->ChangeState(state); // aktualizacja stanu obiektu obcego
  134. terrain.InsertObjectIntoSectors(ob);
  135. // wys³anie nowemu uczestnikowi informacji o wszystkich wziêtych przedmiotach:
  136. for (long i = 0; i < terrain.number_of_items; i++)
  137. if ((terrain.p[i].to_take == 0) && (terrain.p[i].if_taken_by_me))
  138. {
  139. Frame frame;
  140. frame.frame_type = ITEM_TAKING;
  141. frame.item_number = i;
  142. frame.state = my_vehicle->State();
  143. frame.iID = my_vehicle->iID;
  144. int iSIZE = multi_send->send((char*)&frame, sizeof(Frame));
  145. }
  146.  
  147. }
  148. else if ((network_vehicles.size() > 0) && (network_vehicles[frame.iID] != NULL))
  149. {
  150. terrain.DeleteObjectsFromSectors(network_vehicles[frame.iID]);
  151. network_vehicles[frame.iID]->ChangeState(state); // aktualizacja stanu obiektu obcego
  152. terrain.InsertObjectIntoSectors(network_vehicles[frame.iID]);
  153. }
  154.  
  155. }
  156. break;
  157. }
  158. case ITEM_TAKING: // frame informuj¹ca, ¿e ktoœ wzi¹³ przedmiot o podanym numerze
  159. {
  160. state = frame.state;
  161. if ((frame.item_number < terrain.number_of_items) && (frame.iID != my_vehicle->iID))
  162. {
  163. terrain.p[frame.item_number].to_take = 0;
  164. terrain.p[frame.item_number].if_taken_by_me = 0;
  165. }
  166. break;
  167. }
  168. case ITEM_RENEWAL: // frame informujaca, ¿e przedmiot wczeœniej wziêty pojawi³ siê znowu w tym samym miejscu
  169. {
  170. if (frame.item_number < terrain.number_of_items)
  171. terrain.p[frame.item_number].to_take = 1;
  172. break;
  173. }
  174. case COLLISION: // frame informuj¹ca o tym, ¿e Object uleg³ kolizji
  175. {
  176. if (frame.iID_receiver == my_vehicle->iID) // ID pojazdu, który uczestniczy³ w kolizji zgadza siê z moim ID
  177. {
  178. my_vehicle->vdV_collision = frame.vdV_collision; // przepisuje poprawkê w³asnej prêdkoœci
  179. my_vehicle->iID_collider = my_vehicle->iID; // ustawiam nr. kolidujacego jako w³asny na znak, ¿e powinienem poprawiæ prêdkoœæ
  180. }
  181. break;
  182. }
  183. case TRANSFER: // frame informuj¹ca o przelewie pieniê¿nym lub przekazaniu towaru
  184. {
  185. if (frame.iID_receiver == my_vehicle->iID) // ID pojazdu, ktory otrzymal przelew zgadza siê z moim ID
  186. {
  187. if (frame.transfer_type == MONEY)
  188. my_vehicle->state.money += frame.transfer_value;
  189. else if (frame.transfer_type == FUEL)
  190. my_vehicle->state.amount_of_fuel += frame.transfer_value;
  191.  
  192. // nale¿a³oby jeszcze przelew potwierdziæ (w UDP ramki mog¹ byæ gubione!)
  193. }
  194. break;
  195. }
  196. case NEGOCJALAK:
  197. {
  198. if (frame.iID_receiver == my_vehicle->iID && frame.iID == tim) {
  199.  
  200. int procent_otrzymany = frame.transfer_value;
  201. LPCSTR a;
  202. std::string s = std::to_string(procent_otrzymany) + " procent, zgoda?";
  203. a = (LPCSTR)s.c_str();
  204. LPCSTR b;
  205. std::string ss = "Negocjacja";
  206. b = (LPCSTR)ss.c_str();
  207. int co_teraz = MessageBox(nullptr, a, b, MB_YESNOCANCEL | MB_ICONQUESTION);
  208. if ( co_teraz == IDYES) // or IDNO, depending
  209. {
  210. procent_uzgodniony = procent_otrzymany;
  211. Frame frame;
  212. frame.frame_type = AKCEPTOWALAK;
  213. frame.iID_receiver = tim;
  214. frame.transfer_type = 0;
  215. frame.transfer_value = procent_otrzymany;
  216. frame.iID = my_vehicle->iID;
  217. multi_send->send((char*)&frame, sizeof(Frame));
  218. }
  219. if (co_teraz == IDNO) // or IDNO, depending
  220. {
  221. Frame frame;
  222. frame.frame_type = NEGOCJALAK;
  223. frame.iID_receiver = tim;
  224. frame.transfer_type = 0;
  225. frame.transfer_value = procent;
  226. frame.iID = my_vehicle->iID;
  227. multi_send->send((char*)&frame, sizeof(Frame));
  228. }
  229. }
  230. break;
  231. }
  232. case AKCEPTOWALAK:
  233. {
  234. procent_uzgodniony = frame.transfer_value;
  235. break;
  236. }
  237. case ZAPRASZALAK:
  238. {
  239. if (frame.iID_receiver == my_vehicle->iID) {
  240.  
  241. LPCSTR a;
  242. std::string s = std::to_string(frame.iID);
  243. a = (LPCSTR)s.c_str();
  244. LPCSTR b;
  245. std::string ss = "Zaproszenie";
  246. b = (LPCSTR)ss.c_str();
  247.  
  248. if (MessageBox(nullptr, a, b, MB_YESNO) == IDYES) // or IDNO, depending
  249. {
  250. tim = frame.iID;
  251. Frame frame;
  252. frame.frame_type = PRZYJAZNIALAK;
  253. frame.iID_receiver = tim;
  254. frame.transfer_type = 0;
  255. frame.transfer_value = 0;
  256. frame.iID = my_vehicle->iID;
  257. multi_send->send((char*)&frame, sizeof(Frame));
  258. }
  259.  
  260. }
  261. break;
  262. }
  263. case PRZYJAZNIALAK: {
  264. if (frame.iID_receiver == my_vehicle->iID) {
  265. tim = frame.iID;
  266. }
  267. break;
  268. }
  269. } // switch po typach ramek
  270. // Opuszczenie ścieżki krytycznej / Release the Critical section
  271. LeaveCriticalSection(&m_cs); // wyjście ze ścieżki krytycznej
  272. } // while(1)
  273. return 1;
  274. }
  275.  
  276. // *****************************************************************
  277. // **** Wszystko co trzeba zrobiæ podczas uruchamiania aplikacji
  278. // **** poza grafik¹
  279. void InteractionInitialisation()
  280. {
  281. DWORD dwThreadId;
  282.  
  283. my_vehicle = new MovableObject(&terrain); // tworzenie wlasnego obiektu
  284. if (if_different_skills == false)
  285. my_vehicle->planting_skills = my_vehicle->money_collection_skills = my_vehicle->fuel_collection_skills = 1.0;
  286.  
  287. VW_cycle_time = clock(); // pomiar aktualnego czasu
  288.  
  289. // obiekty sieciowe typu multicast (z podaniem adresu WZR oraz numeru portu)
  290. multi_reciv = new multicast_net("224.10.120.70", 10997); // Object do odbioru ramek sieciowych
  291. multi_send = new multicast_net("224.10.120.70", 10997); // Object do wysy³ania ramek
  292.  
  293. // uruchomienie watku obslugujacego odbior komunikatow
  294. threadReciv = CreateThread(
  295. NULL, // no security attributes
  296. 0, // use default stack size
  297. ReceiveThreadFunction, // thread function
  298. (void *)multi_reciv, // argument to thread function
  299. 0, // use default creation flags
  300. &dwThreadId); // returns the thread identifier
  301.  
  302. }
  303.  
  304.  
  305. // *****************************************************************
  306. // **** Wszystko co trzeba zrobiæ w ka¿dym cyklu dzia³ania
  307. // **** aplikacji poza grafik¹
  308. void VirtualWorldCycle()
  309. {
  310. counter_of_simulations++;
  311. if (stare_money != my_vehicle->state.money) {
  312. if (procent_uzgodniony != 0) {
  313. wysylka = (my_vehicle->state.money - stare_money) * procent_uzgodniony / 100;
  314. my_vehicle->state.money -= (my_vehicle->state.money - stare_money) * procent_uzgodniony / 100;
  315. }
  316. }
  317.  
  318. stare_money = my_vehicle->state.money;
  319.  
  320. // obliczenie œredniego czasu pomiêdzy dwoma kolejnnymi symulacjami po to, by zachowaæ fizycznych
  321. if (counter_of_simulations % 50 == 0) // jeœli licznik cykli przekroczy³ pewn¹ wartoœæ, to
  322. { // nale¿y na nowo obliczyæ œredni czas cyklu fDt
  323. char text[200];
  324. long prev_time = VW_cycle_time;
  325. VW_cycle_time = clock();
  326. float fFps = (50 * CLOCKS_PER_SEC) / (float)(VW_cycle_time - prev_time);
  327. if (fFps != 0) fDt = 1.0 / fFps; else fDt = 1;
  328.  
  329. sprintf(par_view.inscription1, " %0.0f_fps, fuel = %0.2f, money = %d\n, negocjacja = %i %%\n", fFps, my_vehicle->state.amount_of_fuel, my_vehicle->state.money, procent);
  330. sprintf(par_view.inscription2, "Kolizja_z_obiektem_o_ID = %d", my_vehicle->iID_collider);
  331. if (counter_of_simulations % 500 == 0) sprintf(par_view.inscription2, "");
  332. }
  333.  
  334.  
  335.  
  336. terrain.DeleteObjectsFromSectors(my_vehicle);
  337. my_vehicle->Simulation(fDt); // symulacja w³asnego obiektu
  338. terrain.InsertObjectIntoSectors(my_vehicle);
  339.  
  340.  
  341. if ((my_vehicle->iID_collider > -1) && // wykryto kolizjê - wysy³am specjaln¹ ramkê, by poinformowaæ o tym drugiego uczestnika
  342. (my_vehicle->iID_collider != my_vehicle->iID)) // oczywiœcie wtedy, gdy nie chodzi o mój pojazd
  343. {
  344. Frame frame;
  345. frame.frame_type = COLLISION;
  346. frame.iID_receiver = my_vehicle->iID_collider;
  347. frame.vdV_collision = my_vehicle->vdV_collision;
  348. frame.iID = my_vehicle->iID;
  349. int iRozmiar = multi_send->send((char*)&frame, sizeof(Frame));
  350.  
  351. char text[128];
  352. sprintf(par_view.inscription2, "Kolizja_z_obiektem_o_ID = %d", my_vehicle->iID_collider);
  353. //SetWindowText(main_window,text);
  354.  
  355. my_vehicle->iID_collider = -1;
  356. }
  357.  
  358. // wyslanie komunikatu o stanie obiektu przypisanego do aplikacji (my_vehicle):
  359.  
  360. Frame frame;
  361. frame.frame_type = OBJECT_STATE;
  362. frame.state = my_vehicle->State(); // state w³asnego obiektu
  363. frame.iID = my_vehicle->iID;
  364. frame.existing_time = clock() - start_time;
  365. int iRozmiar = multi_send->send((char*)&frame, sizeof(Frame));
  366.  
  367.  
  368.  
  369. // wziêcie przedmiotu -> wysy³anie ramki
  370. if (my_vehicle->number_of_taking_item > -1)
  371. {
  372. Frame frame;
  373. frame.frame_type = ITEM_TAKING;
  374. frame.item_number = my_vehicle->number_of_taking_item;
  375. frame.state = my_vehicle->State();
  376. frame.iID = my_vehicle->iID;
  377. int iRozmiar = multi_send->send((char*)&frame, sizeof(Frame));
  378.  
  379. sprintf(par_view.inscription2, "Wziecie_przedmiotu_o_wartosci_ %f", my_vehicle->taking_value);
  380.  
  381. my_vehicle->number_of_taking_item = -1;
  382. my_vehicle->taking_value = 0;
  383. }
  384.  
  385. // odnawianie siê przedmiotu -> wysy³anie ramki
  386. if (my_vehicle->number_of_renewed_item > -1)
  387. { // jeœli min¹³ pewnien okres czasu przedmiot mo¿e zostaæ przywrócony
  388. Frame frame;
  389. frame.frame_type = ITEM_RENEWAL;
  390. frame.item_number = my_vehicle->number_of_renewed_item;
  391. frame.iID = my_vehicle->iID;
  392. int iRozmiar = multi_send->send((char*)&frame, sizeof(Frame));
  393.  
  394.  
  395. my_vehicle->number_of_renewed_item = -1;
  396. }
  397.  
  398. }
  399.  
  400. // *****************************************************************
  401. // **** Wszystko co trzeba zrobiæ podczas zamykania aplikacji
  402. // **** poza grafik¹
  403. void EndOfInteraction()
  404. {
  405. fprintf(f, "Koniec interakcji\n");
  406. fclose(f);
  407. }
  408.  
  409. // Funkcja wysylajaca ramke z przekazem, zwraca zrealizowan¹ wartoœæ przekazu
  410. float TransferSending(int ID_receiver, int transfer_type, float transfer_value)
  411. {
  412. Frame frame;
  413. frame.frame_type = TRANSFER;
  414. frame.iID_receiver = ID_receiver;
  415. frame.transfer_type = transfer_type;
  416. frame.transfer_value = transfer_value;
  417. frame.iID = my_vehicle->iID;
  418.  
  419. // tutaj nale¿a³oby uzyskaæ potwierdzenie przekazu zanim sumy zostan¹ odjête
  420. if (transfer_type == MONEY)
  421. {
  422. if (my_vehicle->state.money < transfer_value)
  423. frame.transfer_value = my_vehicle->state.money;
  424. my_vehicle->state.money -= frame.transfer_value;
  425. sprintf(par_view.inscription2, "Przelew_sumy_ %f _na_rzecz_ID_ %d", transfer_value, ID_receiver);
  426. }
  427. else if (transfer_type == FUEL)
  428. {
  429. if (my_vehicle->state.amount_of_fuel < transfer_value)
  430. frame.transfer_value = my_vehicle->state.amount_of_fuel;
  431. my_vehicle->state.amount_of_fuel -= frame.transfer_value;
  432. sprintf(par_view.inscription2, "Przekazanie_paliwa_w_ilosci_ %f _na_rzecz_ID_ %d", transfer_value, ID_receiver);
  433. }
  434.  
  435. if (frame.transfer_value > 0)
  436. int iRozmiar = multi_send->send((char*)&frame, sizeof(Frame));
  437.  
  438. return frame.transfer_value;
  439. }
  440.  
  441.  
  442.  
  443.  
  444.  
  445. //deklaracja funkcji obslugi okna
  446. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  447.  
  448.  
  449. HWND main_window; // uchwyt do okna aplikacji
  450. HDC g_context = NULL; // uchwyt kontekstu graficznego
  451.  
  452. bool terrain_edition_mode = 0;
  453.  
  454. //funkcja Main - dla Windows
  455. int WINAPI WinMain(HINSTANCE hInstance,
  456. HINSTANCE hPrevInstance,
  457. LPSTR lpCmdLine,
  458. int nCmdShow)
  459. {
  460. //Initilize the critical section:
  461. InitializeCriticalSection(&m_cs);
  462.  
  463. MSG system_message; //innymi slowy "komunikat"
  464. WNDCLASS window_class; //klasa głównego okna aplikacji
  465.  
  466. static char class_name[] = "Basic";
  467.  
  468. //Definiujemy klase głównego okna aplikacji
  469. //Okreslamy tu wlasciwosci okna, szczegoly wygladu oraz
  470. //adres funkcji przetwarzajacej komunikaty
  471. window_class.style = CS_HREDRAW | CS_VREDRAW;
  472. window_class.lpfnWndProc = WndProc; //adres funkcji realizującej przetwarzanie meldunków
  473. window_class.cbClsExtra = 0;
  474. window_class.cbWndExtra = 0;
  475. window_class.hInstance = hInstance; //identyfikator procesu przekazany przez MS Windows podczas uruchamiania programu
  476. window_class.hIcon = 0;
  477. window_class.hCursor = LoadCursor(0, IDC_ARROW);
  478. window_class.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
  479. window_class.lpszMenuName = "Menu";
  480. window_class.lpszClassName = class_name;
  481.  
  482. //teraz rejestrujemy klasę okna głównego
  483. RegisterClass(&window_class);
  484.  
  485. /*tworzymy main_window główne
  486. main_window będzie miało zmienne rozmiary, listwę z tytułem, menu systemowym
  487. i przyciskami do zwijania do ikony i rozwijania na cały ekran, po utworzeniu
  488. będzie widoczne na ekranie */
  489. main_window = CreateWindow(class_name, "WZR 2018/19, temat 3, wersja i ", WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
  490. 100, 100, 1200, 800, NULL, NULL, hInstance, NULL);
  491.  
  492.  
  493. ShowWindow(main_window, nCmdShow);
  494.  
  495. //odswiezamy zawartosc okna
  496. UpdateWindow(main_window);
  497.  
  498.  
  499.  
  500. // GŁÓWNA PĘTLA PROGRAMU
  501.  
  502. // pobranie komunikatu z kolejki jeśli funkcja PeekMessage zwraca wartość inną niż FALSE,
  503. // w przeciwnym wypadku symulacja wirtualnego świata wraz z wizualizacją
  504. ZeroMemory(&system_message, sizeof(system_message));
  505. while (system_message.message != WM_QUIT)
  506. {
  507. if (PeekMessage(&system_message, NULL, 0U, 0U, PM_REMOVE))
  508. {
  509. TranslateMessage(&system_message);
  510. DispatchMessage(&system_message);
  511. }
  512. else
  513. {
  514. VirtualWorldCycle(); // Cykl wirtualnego świata
  515. InvalidateRect(main_window, NULL, FALSE);
  516. }
  517. }
  518.  
  519. return (int)system_message.wParam;
  520. }
  521.  
  522. // ************************************************************************
  523. // **** Obs³uga klawiszy s³u¿¹cych do sterowania obiektami lub
  524. // **** widokami
  525. void MessagesHandling(UINT message_type, WPARAM wParam, LPARAM lParam)
  526. {
  527.  
  528. int LCONTROL = GetKeyState(VK_LCONTROL);
  529. int RCONTROL = GetKeyState(VK_RCONTROL);
  530. int LALT = GetKeyState(VK_LMENU);
  531. int RALT = GetKeyState(VK_RMENU);
  532.  
  533.  
  534. switch (message_type)
  535. {
  536.  
  537. case WM_LBUTTONDOWN: //reakcja na lewy przycisk myszki
  538. {
  539. int x = LOWORD(lParam);
  540. int y = HIWORD(lParam);
  541. if (mouse_control)
  542. my_vehicle->F = my_vehicle->F_max; // si³a pchaj¹ca do przodu
  543.  
  544. break;
  545. }
  546. case WM_RBUTTONDOWN: //reakcja na prawy przycisk myszki
  547. {
  548. int x = LOWORD(lParam);
  549. int y = HIWORD(lParam);
  550. int LSHIFT = GetKeyState(VK_LSHIFT); // sprawdzenie czy lewy Shift wciśnięty, jeśli tak, to LSHIFT == 1
  551. int RSHIFT = GetKeyState(VK_RSHIFT);
  552.  
  553. if (mouse_control)
  554. my_vehicle->F = -my_vehicle->F_max / 2; // si³a pchaj¹ca do tylu
  555. else if (wParam & MK_SHIFT) // odznaczanie wszystkich obiektów
  556. {
  557. for (long i = 0; i < terrain.number_of_selected_items; i++)
  558. terrain.p[terrain.selected_items[i]].if_selected = 0;
  559. terrain.number_of_selected_items = 0;
  560. }
  561. else // zaznaczenie obiektów
  562. {
  563. RECT r;
  564. //GetWindowRect(main_window,&r);
  565. GetClientRect(main_window, &r);
  566. //Vector3 w = Cursor3dCoordinates(x, r.bottom - r.top - y);
  567. Vector3 w = terrain.Cursor3D_CoordinatesWithoutParallax(x, r.bottom - r.top - y);
  568.  
  569.  
  570. //float radius = (w - point_click).length();
  571. float min_dist = 1e10;
  572. long index_min = -1;
  573. bool if_movable_obj;
  574. for (map<int, MovableObject*>::iterator it = network_vehicles.begin(); it != network_vehicles.end(); ++it)
  575. {
  576. if (it->second)
  577. {
  578. MovableObject *ob = it->second;
  579. float xx, yy, zz;
  580. ScreenCoordinates(&xx, &yy, &zz, ob->state.vPos);
  581. yy = r.bottom - r.top - yy;
  582. float odl_kw = (xx - x)*(xx - x) + (yy - y)*(yy - y);
  583. if (min_dist > odl_kw)
  584. {
  585. min_dist = odl_kw;
  586. index_min = ob->iID;
  587. if_movable_obj = 1;
  588. }
  589. }
  590. }
  591.  
  592.  
  593. // trzeba to przerobić na wersję sektorową, gdyż przedmiotów może być dużo!
  594. // niestety nie jest to proste.
  595.  
  596. //Item **wsk_prz = NULL;
  597. //long liczba_prz_w_prom = terrain.ItemsInRadius(&wsk_prz, w,100);
  598.  
  599. for (long i = 0; i < terrain.number_of_items; i++)
  600. {
  601. float xx, yy, zz;
  602. Vector3 placement;
  603. if ((terrain.p[i].type == ITEM_EDGE) || (terrain.p[i].type == ITEM_WALL))
  604. {
  605. placement = (terrain.p[terrain.p[i].param_i[0]].vPos + terrain.p[terrain.p[i].param_i[1]].vPos) / 2;
  606. }
  607. else
  608. placement = terrain.p[i].vPos;
  609. ScreenCoordinates(&xx, &yy, &zz, placement);
  610. yy = r.bottom - r.top - yy;
  611. float odl_kw = (xx - x)*(xx - x) + (yy - y)*(yy - y);
  612. if (min_dist > odl_kw)
  613. {
  614. min_dist = odl_kw;
  615. index_min = i;
  616. if_movable_obj = 0;
  617. }
  618. }
  619.  
  620. if (index_min > -1)
  621. {
  622. //fprintf(f,"zaznaczono przedmiot %d pol = (%f, %f, %f)\n",ind_min,terrain.p[ind_min].vPos.x,terrain.p[ind_min].vPos.y,terrain.p[ind_min].vPos.z);
  623. //terrain.p[ind_min].if_selected = 1 - terrain.p[ind_min].if_selected;
  624. if (if_movable_obj)
  625. {
  626. network_vehicles[index_min]->if_selected = 1 - network_vehicles[index_min]->if_selected;
  627.  
  628. if (network_vehicles[index_min]->if_selected) {
  629. sprintf(par_view.inscription2, "zaznaczono_ obiekt_ID_%d", network_vehicles[index_min]->iID);
  630. zaznaczony_id = network_vehicles[index_min]->iID;
  631. }
  632. }
  633. else
  634. {
  635. terrain.SelectUnselectItemOrGroup(index_min);
  636. }
  637. //char lan[256];
  638. //sprintf(lan, "klikniêto w przedmiot %d pol = (%f, %f, %f)\n",ind_min,terrain.p[ind_min].vPos.x,terrain.p[ind_min].vPos.y,terrain.p[ind_min].vPos.z);
  639. //SetWindowText(main_window,lan);
  640. }
  641. Vector3 point_click = Cursor3dCoordinates(x, r.bottom - r.top - y);
  642.  
  643. }
  644.  
  645. break;
  646. }
  647. case WM_MBUTTONDOWN: //reakcja na œrodkowy przycisk myszki : uaktywnienie/dezaktywacja sterwania myszkowego
  648. {
  649. mouse_control = 1 - mouse_control;
  650. cursor_x = LOWORD(lParam);
  651. cursor_y = HIWORD(lParam);
  652. break;
  653. }
  654. case WM_LBUTTONUP: //reakcja na puszczenie lewego przycisku myszki
  655. {
  656. if (mouse_control)
  657. my_vehicle->F = 0.0; // si³a pchaj¹ca do przodu
  658. break;
  659. }
  660. case WM_RBUTTONUP: //reakcja na puszczenie lewy przycisk myszki
  661. {
  662. if (mouse_control)
  663. my_vehicle->F = 0.0; // si³a pchaj¹ca do przodu
  664. break;
  665. }
  666. case WM_MOUSEMOVE:
  667. {
  668. int x = LOWORD(lParam);
  669. int y = HIWORD(lParam);
  670. if (mouse_control)
  671. {
  672. float wheel_turn_angle = (float)(cursor_x - x) / 20;
  673. if (wheel_turn_angle > 45) wheel_turn_angle = 45;
  674. if (wheel_turn_angle < -45) wheel_turn_angle = -45;
  675. my_vehicle->state.wheel_turn_angle = PI*wheel_turn_angle / 180;
  676. }
  677. break;
  678. }
  679. case WM_MOUSEWHEEL: // ruch kó³kiem myszy -> przybli¿anie, oddalanie widoku
  680. {
  681. int zDelta = GET_WHEEL_DELTA_WPARAM(wParam); // dodatni do przodu, ujemny do ty³u
  682. //fprintf(f,"zDelta = %d\n",zDelta); // zwykle +-120, jak siê bardzo szybko zakrêci to czasmi wyjdzie +-240
  683. if (zDelta > 0){
  684. if (par_view.distance > 0.5) par_view.distance /= 1.2;
  685. else par_view.distance = 0;
  686. }
  687. else {
  688. if (par_view.distance > 0) par_view.distance *= 1.2;
  689. else par_view.distance = 0.5;
  690. }
  691.  
  692. break;
  693. }
  694. case WM_KEYDOWN:
  695. {
  696.  
  697. switch (LOWORD(wParam))
  698. {
  699. case VK_SHIFT:
  700. {
  701. SHIFT_pressed = 1;
  702. break;
  703. }
  704. case VK_CONTROL:
  705. {
  706. CTRL_pressed = 1;
  707. break;
  708. }
  709. case VK_MENU:
  710. {
  711. ALT_pressed = 1;
  712. break;
  713. }
  714.  
  715. case VK_SPACE:
  716. {
  717. my_vehicle->breaking_degree = 1.0; // stopieñ hamowania (reszta zale¿y od si³y docisku i wsp. tarcia)
  718. break; // 1.0 to maksymalny stopieñ (np. zablokowanie kó³)
  719. }
  720. case VK_UP:
  721. {
  722. if (CTRL_pressed && par_view.top_view)
  723. par_view.shift_to_bottom += par_view.distance / 2; // przesunięcie widoku z kamery w górę
  724. else
  725. my_vehicle->F = my_vehicle->F_max; // si³a pchaj¹ca do przodu
  726. break;
  727. }
  728. case VK_DOWN:
  729. {
  730. if (CTRL_pressed && par_view.top_view)
  731. par_view.shift_to_bottom -= par_view.distance / 2; // przesunięcie widoku z kamery w dół
  732. else
  733. my_vehicle->F = -my_vehicle->F_max / 2; // sila pchajaca do tylu
  734. break;
  735. }
  736. case VK_LEFT:
  737. {
  738. if (CTRL_pressed && par_view.top_view)
  739. par_view.shift_to_right += par_view.distance / 2;
  740. else
  741. {
  742. if (my_vehicle->steer_wheel_speed < 0) {
  743. my_vehicle->steer_wheel_speed = 0;
  744. my_vehicle->if_keep_steer_wheel = true;
  745. }
  746. else {
  747. if (SHIFT_pressed) my_vehicle->steer_wheel_speed = 0.5;
  748. else my_vehicle->steer_wheel_speed = 0.5 / 4;
  749. }
  750. }
  751.  
  752. break;
  753. }
  754. case VK_RIGHT:
  755. {
  756. if (CTRL_pressed && par_view.top_view)
  757. par_view.shift_to_right -= par_view.distance / 2;
  758. else
  759. {
  760. if (my_vehicle->steer_wheel_speed > 0) {
  761. my_vehicle->steer_wheel_speed = 0;
  762. my_vehicle->if_keep_steer_wheel = true;
  763. }
  764. else {
  765. if (SHIFT_pressed) my_vehicle->steer_wheel_speed = -0.5;
  766. else my_vehicle->steer_wheel_speed = -0.5 / 4;
  767. }
  768. }
  769. break;
  770. }
  771. case VK_HOME:
  772. {
  773. if (CTRL_pressed && par_view.top_view)
  774. par_view.shift_to_right = par_view.shift_to_bottom = 0;
  775.  
  776. break;
  777. }
  778. case 'W': // przybli¿enie widoku
  779. {
  780. //initial_camera_position = initial_camera_position - initial_camera_direction*0.3;
  781. if (par_view.distance > 0.5)par_view.distance /= 1.2;
  782. else par_view.distance = 0;
  783. break;
  784. }
  785. case 'S': // distance widoku
  786. {
  787. //initial_camera_position = initial_camera_position + initial_camera_direction*0.3;
  788. if (par_view.distance > 0) par_view.distance *= 1.2;
  789. else par_view.distance = 0.5;
  790. break;
  791. }
  792. case 'Q': // widok z góry
  793. {
  794. par_view.top_view = 1 - par_view.top_view;
  795. if (par_view.top_view)
  796. SetWindowText(main_window, "Włączono widok z góry!");
  797. else
  798. SetWindowText(main_window, "Wyłączono widok z góry.");
  799. break;
  800. }
  801. case 'E': // obrót kamery ku górze (wzglêdem lokalnej osi z)
  802. {
  803. par_view.cam_angle_z += PI * 5 / 180;
  804. break;
  805. }
  806. case 'D': // obrót kamery ku do³owi (wzglêdem lokalnej osi z)
  807. {
  808. par_view.cam_angle_z -= PI * 5 / 180;
  809. break;
  810. }
  811. case 'A': // w³¹czanie, wy³¹czanie trybu œledzenia obiektu
  812. {
  813. par_view.tracking = 1 - par_view.tracking;
  814. break;
  815. }
  816. case 'Z': // zoom - zmniejszenie k¹ta widzenia
  817. {
  818. par_view.zoom /= 1.1;
  819. RECT rc;
  820. GetClientRect(main_window, &rc);
  821. WindowSizeChange(rc.right - rc.left, rc.bottom - rc.top);
  822. break;
  823. }
  824. case 'X': // zoom - zwiêkszenie k¹ta widzenia
  825. {
  826. par_view.zoom *= 1.1;
  827. RECT rc;
  828. GetClientRect(main_window, &rc);
  829. WindowSizeChange(rc.right - rc.left, rc.bottom - rc.top);
  830. break;
  831. }
  832.  
  833. case 'F': // przekazanie 10 kg paliwa pojazdom zaznaczonym
  834. {
  835. for (map<int, MovableObject*>::iterator it = network_vehicles.begin(); it != network_vehicles.end(); ++it)
  836. {
  837. if (it->second)
  838. {
  839. MovableObject *ob = it->second;
  840. if (ob->if_selected)
  841. float ilosc_p = TransferSending(ob->iID, FUEL, 10);
  842. }
  843. }
  844. break;
  845. }
  846. case 'N':
  847. {// NEGACJACJEEEEEEE
  848. if (tim != -1) {
  849. Frame frame;
  850. frame.frame_type = NEGOCJALAK;
  851. frame.iID_receiver = tim;
  852. frame.transfer_type = 0;
  853. frame.transfer_value = procent;
  854. frame.iID = my_vehicle->iID;
  855. multi_send->send((char*)&frame, sizeof(Frame));
  856. }
  857. break;
  858. }
  859. case 'M':
  860. {// rozpoczęcie zaznaczania metodą maguw ognia
  861. if (zaznaczony_id != -1) {
  862. Frame frame;
  863. frame.frame_type = ZAPRASZALAK;
  864. frame.iID_receiver = zaznaczony_id;
  865. frame.transfer_type = 0;
  866. frame.transfer_value = 0;
  867. frame.iID = my_vehicle->iID;
  868. multi_send->send((char*)&frame, sizeof(Frame));
  869.  
  870. }
  871.  
  872. break;
  873. }
  874. case '8':
  875. {
  876. long prev_time = VW_cycle_time;
  877. VW_cycle_time = clock();
  878. float fFps = (50 * CLOCKS_PER_SEC) / (float)(VW_cycle_time - prev_time);
  879. procent += 1;
  880. sprintf(par_view.inscription1, " %0.0f_fps, fuel = %0.2f, money = %d\n, negocjacja = %i %%\n", fFps, my_vehicle->state.amount_of_fuel, my_vehicle->state.money, procent);
  881. break;
  882. }
  883. case '2':
  884. {
  885. long prev_time = VW_cycle_time;
  886. VW_cycle_time = clock();
  887. float fFps = (50 * CLOCKS_PER_SEC) / (float)(VW_cycle_time - prev_time);
  888. procent -= 1;
  889. sprintf(par_view.inscription1, " %0.0f_fps, fuel = %0.2f, money = %d\n, negocjacja = %i %%\n", fFps, my_vehicle->state.amount_of_fuel, my_vehicle->state.money, procent);
  890. break;
  891. }
  892. case 'G': // przekazanie 100 jednostek gotowki pojazdom zaznaczonym
  893. {
  894. for (map<int, MovableObject*>::iterator it = network_vehicles.begin(); it != network_vehicles.end(); ++it)
  895. {
  896. if (it->second)
  897. {
  898. MovableObject *ob = it->second;
  899. if (ob->if_selected)
  900. float ilosc_p = TransferSending(ob->iID, MONEY, 100);
  901. }
  902. }
  903. break;
  904. }
  905.  
  906. case 'L': // rozpoczęcie zaznaczania metodą lasso
  907. L_pressed = true;
  908. break;
  909.  
  910.  
  911. } // switch po klawiszach
  912.  
  913.  
  914. break;
  915. }
  916.  
  917. case WM_KEYUP:
  918. {
  919. switch (LOWORD(wParam))
  920. {
  921. case VK_SHIFT:
  922. {
  923. SHIFT_pressed = 0;
  924. break;
  925. }
  926. case VK_CONTROL:
  927. {
  928. CTRL_pressed = 0;
  929. break;
  930. }
  931. case VK_MENU:
  932. {
  933. ALT_pressed = 0;
  934. break;
  935. }
  936. case 'L': // zakonczenie zaznaczania metodą lasso
  937. L_pressed = false;
  938. break;
  939. case VK_SPACE:
  940. {
  941. my_vehicle->breaking_degree = 0.0;
  942. break;
  943. }
  944. case VK_UP:
  945. {
  946. my_vehicle->F = 0.0;
  947.  
  948. break;
  949. }
  950. case VK_DOWN:
  951. {
  952. my_vehicle->F = 0.0;
  953. break;
  954. }
  955. case VK_LEFT:
  956. {
  957. if (my_vehicle->if_keep_steer_wheel) my_vehicle->steer_wheel_speed = -0.5 / 4;
  958. else my_vehicle->steer_wheel_speed = 0;
  959. my_vehicle->if_keep_steer_wheel = false;
  960. break;
  961. }
  962. case VK_RIGHT:
  963. {
  964. if (my_vehicle->if_keep_steer_wheel) my_vehicle->steer_wheel_speed = 0.5 / 4;
  965. else my_vehicle->steer_wheel_speed = 0;
  966. my_vehicle->if_keep_steer_wheel = false;
  967. break;
  968. }
  969.  
  970. }
  971.  
  972. break;
  973. }
  974.  
  975. } // switch po komunikatach
  976. }
  977.  
  978. /********************************************************************
  979. FUNKCJA OKNA realizujaca przetwarzanie meldunków kierowanych do okna aplikacji*/
  980. LRESULT CALLBACK WndProc(HWND main_window, UINT message_type, WPARAM wParam, LPARAM lParam)
  981. {
  982.  
  983. // PONIŻSZA INSTRUKCJA DEFINIUJE REAKCJE APLIKACJI NA POSZCZEGÓLNE MELDUNKI
  984.  
  985. MessagesHandling(message_type, wParam, lParam);
  986.  
  987. switch (message_type)
  988. {
  989. case WM_CREATE: //system_message wysyłany w momencie tworzenia okna
  990. {
  991.  
  992. g_context = GetDC(main_window);
  993.  
  994. srand((unsigned)time(NULL));
  995. int result = GraphicsInitialization(g_context);
  996. if (result == 0)
  997. {
  998. printf("nie udalo sie otworzyc okna graficznego\n");
  999. //exit(1);
  1000. }
  1001.  
  1002. InteractionInitialisation();
  1003.  
  1004. SetTimer(main_window, 1, 10, NULL);
  1005.  
  1006. return 0;
  1007. }
  1008. case WM_KEYDOWN:
  1009. {
  1010. switch (LOWORD(wParam))
  1011. {
  1012. case VK_F1: // wywolanie systemu pomocy
  1013. {
  1014. char lan[1024], lan_bie[1024];
  1015. //GetSystemDirectory(lan_sys,1024);
  1016. GetCurrentDirectory(1024, lan_bie);
  1017. strcpy(lan, "C:\\Program Files\\Internet Explorer\\iexplore ");
  1018. strcat(lan, lan_bie);
  1019. strcat(lan, "\\pomoc.htm");
  1020. int wyni = WinExec(lan, SW_NORMAL);
  1021. if (wyni < 32) // proba uruchominia pomocy nie powiodla sie
  1022. {
  1023. strcpy(lan, "C:\\Program Files\\Mozilla Firefox\\firefox ");
  1024. strcat(lan, lan_bie);
  1025. strcat(lan, "\\pomoc.htm");
  1026. wyni = WinExec(lan, SW_NORMAL);
  1027. if (wyni < 32)
  1028. {
  1029. char lan_win[1024];
  1030. GetWindowsDirectory(lan_win, 1024);
  1031. strcat(lan_win, "\\notepad pomoc.txt ");
  1032. wyni = WinExec(lan_win, SW_NORMAL);
  1033. }
  1034. }
  1035. break;
  1036. }
  1037. case VK_F4: // włączanie/ wyłączanie trybu edycji terrainu
  1038. {
  1039. terrain_edition_mode = 1 - terrain_edition_mode;
  1040. if (terrain_edition_mode)
  1041. SetWindowText(main_window, "TRYB EDYCJI TERENU F2-SaveMapToFile, F1-pomoc");
  1042. else
  1043. SetWindowText(main_window, "WYJSCIE Z TRYBU EDYCJI TERENU");
  1044. break;
  1045. }
  1046. case VK_ESCAPE: // wyjście z programu
  1047. {
  1048. SendMessage(main_window, WM_DESTROY, 0, 0);
  1049. break;
  1050. }
  1051. }
  1052. return 0;
  1053. }
  1054.  
  1055. case WM_PAINT:
  1056. {
  1057. PAINTSTRUCT paint;
  1058. HDC context;
  1059. context = BeginPaint(main_window, &paint);
  1060.  
  1061. DrawScene();
  1062. SwapBuffers(context);
  1063.  
  1064. EndPaint(main_window, &paint);
  1065.  
  1066.  
  1067.  
  1068. return 0;
  1069. }
  1070.  
  1071. case WM_TIMER:
  1072.  
  1073. return 0;
  1074.  
  1075. case WM_SIZE:
  1076. {
  1077. int cx = LOWORD(lParam);
  1078. int cy = HIWORD(lParam);
  1079.  
  1080. WindowSizeChange(cx, cy);
  1081.  
  1082. return 0;
  1083. }
  1084.  
  1085. case WM_DESTROY: //obowiązkowa obsługa meldunku o zamknięciu okna
  1086. if (lParam == 100)
  1087. MessageBox(main_window, "Jest zbyt późno na dołączenie do wirtualnego świata. Trzeba to zrobić zanim inni uczestnicy zmienią jego state.", "Zamknięcie programu", MB_OK);
  1088.  
  1089. EndOfInteraction();
  1090. EndOfGraphics();
  1091.  
  1092. ReleaseDC(main_window, g_context);
  1093. KillTimer(main_window, 1);
  1094.  
  1095. PostQuitMessage(0);
  1096. return 0;
  1097.  
  1098. default: //standardowa obsługa pozostałych meldunków
  1099. return DefWindowProc(main_window, message_type, wParam, lParam);
  1100. }
  1101.  
  1102. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement