Advertisement
qtinio

policyjny main

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