Advertisement
Guest User

Untitled

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