Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /****************************************************
- Virtual Collaborative Teams - The base program
- The main module
- ****************************************************/
- #include <windows.h>
- #include <math.h>
- #include <time.h>
- #include <vector>
- #include <iostream>
- #include <gl\gl.h>
- #include <gl\glu.h>
- #include <iterator>
- #include <map>
- #include "objects.h"
- #include "graphics.h"
- #include "net.h"
- using namespace std;
- FILE *f = fopen("vct_log.txt", "w"); // plik do zapisu informacji testowych
- MovableObject *my_car; // obiekt przypisany do tej aplikacji
- Environment env;
- map<int, MovableObject*> other_cars;
- float avg_cycle_time; // sredni czas pomiedzy dwoma kolejnymi cyklami symulacji i wyswietlania
- long time_of_cycle, number_of_cyc; // zmienne pomocnicze potrzebne do obliczania avg_cycle_time
- long time_start = clock();
- unicast_net *uni_reciv; // wsk do obiektu zajmujacego sie odbiorem komunikatow
- unicast_net *uni_send; // -||- wysylaniem komunikatow
- HANDLE threadReciv; // uchwyt wątku odbioru komunikatów
- HANDLE serverStuff;
- HWND main_window; // uchwyt do głównego okna programu
- CRITICAL_SECTION m_cs; // do synchronizacji wątków
- bool if_SHIFT_pressed = false;
- bool if_ID_visible = true; // czy rysowac nr ID przy każdym obiekcie
- bool if_mouse_control = false; // sterowanie za pomocą klawisza myszki
- int mouse_cursor_x = 0, mouse_cursor_y = 0; // położenie kursora myszy
- extern ViewParams viewpar; // ustawienia widoku zdefiniowane w grafice
- long duration_of_day = 800; // czas trwania dnia w [s]
- unsigned long ipAdress; // IP SERWERA
- char* serverIp = "192.168.123.20";
- bool changeServ = false;
- bool iAmServer = false;
- struct Frame // główna struktura służąca do przesyłania informacji
- {
- int iID; // identyfikator obiektu, którego
- int type; // typ ramki: informacja o stateie, informacja o zamknięciu, komunikat tekstowy, ...
- ObjectState state; // położenie, prędkość: środka masy + kątowe, ...
- long sending_time; // tzw. znacznik czasu potrzebny np. do obliczenia opóźnienia
- int iID_receiver; // nr ID odbiorcy wiadomości, jeśli skierowana jest tylko do niego
- char* ip;
- };
- //// parametry serwera
- char* serwerIP;
- bool newserwer = false;
- struct Klient {
- unsigned long ipAdress;
- bool active;
- int packet_last;
- Klient(unsigned long ip, int p, bool act, int pack)
- {
- ipAdress = ip;
- active = act;
- packet_last = pack;
- }
- };
- ////
- //******************************************
- // Funkcja obsługi wątku odbioru komunikatów
- // UWAGA! Odbierane są też komunikaty z własnej aplikacji by porównać obraz ekstrapolowany do rzeczywistego.
- DWORD WINAPI ReceiveThreadFun(void *ptr)
- {
- unicast_net *pmt_net = (unicast_net*)ptr; // wskaźnik do obiektu klasy unicast_net
- Frame frame;
- std::vector<Klient> clients;
- unicast_net *uni_recivS; // wsk do obiektu zajmujacego sie odbiorem komunikatow
- unicast_net *uni_sendS;
- uni_recivS = new unicast_net(10006); // obiekt do odbioru ramek sieciowych
- uni_sendS = new unicast_net(10005);
- while (1)
- {
- int frame_size = pmt_net->reciv((char*)&frame, &ipAdress, sizeof(Frame)); // oczekiwanie na nadejście ramki
- ObjectState state = frame.state;
- //fprintf(f, "odebrano stan iID = %d, ID dla mojego obiektu = %d\n", frame.iID, my_car->iID);
- if (frame.type == 500) //czy to ramka zmiana serwera
- {
- if (changeServ)
- {
- iAmServer = true;
- }
- serverIp = frame.ip;
- }
- // Lock the Critical section
- EnterCriticalSection(&m_cs); // wejście na ścieżkę krytyczną - by inne wątki (np. główny) nie współdzielił
- // tablicy other_cars
- if (frame.iID != my_car->iID) // jeśli to nie mój własny obiekt
- {
- if (other_cars[frame.iID] == NULL) // nie ma jeszcze takiego obiektu w tablicy -> trzeba go
- // stworzyć
- {
- MovableObject *ob = new MovableObject();
- ob->iID = frame.iID;
- other_cars[frame.iID] = ob;
- //fprintf(f, "zarejestrowano %d obcy obiekt o ID = %d\n", iLiczbaCudzychOb - 1, CudzeObiekty[iLiczbaCudzychOb]->iID);
- }
- other_cars[frame.iID]->ChangeState(state); // aktualizacja stateu obiektu obcego
- if (frame.type == 0) //ramka usun klienta
- {
- other_cars.erase(frame.iID);
- }
- }
- //Release the Critical section
- LeaveCriticalSection(&m_cs); // wyjście ze ścieżki krytycznej
- if (iAmServer) {
- bool registered = false;
- struct sockaddr_in dest;
- dest.sin_addr.S_un.S_addr = ipAdress;
- printf("Package received from %s \n", inet_ntoa(dest.sin_addr));
- for (auto &klient : clients)
- {
- if (klient.ipAdress == ipAdress)
- {
- registered = true;
- }
- }
- if (!registered)
- {
- bool isactive = true;
- if (frame.type == 0)
- {
- isactive = false;
- }
- clients.emplace_back(ipAdress, 10006, isactive, 30);
- printf("Client %s created \n", inet_ntoa(dest.sin_addr));
- }
- if (frame.type == 505)
- {
- Frame f;
- f.type = 500; //zmiana serwera
- f.ip = inet_ntoa(dest.sin_addr);
- serwerIP = f.ip;
- //zmien serwer i rozeslj do wszystkich info kto jest serwerem
- for (auto klient : clients)
- {
- uni_send->send((char *)&f, klient.ipAdress, sizeof(Frame));
- }
- iAmServer = false;
- }
- for (int i = 0; i < clients.size(); i++)
- {
- Klient klient = clients[i];
- if (klient.ipAdress == ipAdress)
- {
- if (frame.type == 0)
- {
- klient.active = false;
- }
- else
- {
- klient.active = true;
- klient.packet_last = 30;
- }
- }
- else
- {
- klient.packet_last--;
- }
- if (klient.packet_last < 1)
- {
- klient.active = false;
- }
- dest.sin_addr.S_un.S_addr = klient.ipAdress;
- if (klient.active)
- {
- uni_send->send((char *)&frame, klient.ipAdress, sizeof(Frame));
- printf("%s is active \n", inet_ntoa(dest.sin_addr));
- }
- else
- {
- printf("%s is inactive \n", inet_ntoa(dest.sin_addr));
- clients.erase(clients.begin() + i);
- }
- }
- }
- } // while(1)
- return 1;
- }
- // *****************************************************************
- // **** Wszystko co trzeba zrobić podczas uruchamiania aplikacji
- // **** poza grafiką
- void InteractionInitialisation()
- {
- DWORD dwThreadId, dwThreadId2;
- my_car = new MovableObject(); // tworzenie wlasnego obiektu
- time_of_cycle = clock(); // pomiar aktualnego czasu
- // obiekty sieciowe typu unicast (z podaniem numeru portu)
- uni_reciv = new unicast_net(10005); // obiekt do odbioru ramek sieciowych
- uni_send = new unicast_net(10006); // obiekt do wysyłania ramek
- // uruchomienie wątku obsługującego odbiór komunikatów:
- threadReciv = CreateThread(
- NULL, // no security attributes
- 0, // use default stack size
- ReceiveThreadFun, // thread function
- (void *)uni_reciv, // argument to thread function
- NULL, // use default creation flags
- &dwThreadId); // returns the thread identifier
- SetThreadPriority(threadReciv, THREAD_PRIORITY_HIGHEST);
- printf("start interakcji\n");
- }
- // *****************************************************************
- // **** Wszystko co trzeba zrobić w każdym cyklu działania
- // **** aplikacji poza grafiką
- void VirtualWorldCycle()
- {
- number_of_cyc++;
- if (number_of_cyc % 50 == 0) // jeśli licznik cykli przekroczył pewną wartość, to
- { // należy na nowo obliczyć średni czas cyklu avg_cycle_time
- char text[256];
- long prev_time = time_of_cycle;
- time_of_cycle = clock();
- float fFps = (50 * CLOCKS_PER_SEC) / (float)(time_of_cycle - prev_time);
- if (fFps != 0) avg_cycle_time = 1.0 / fFps; else avg_cycle_time = 1;
- sprintf(text, "WWC-lab 2018/19 temat 1, wersja i (%0.0f fps %0.2fms) ", fFps, 1000.0 / fFps);
- SetWindowText(main_window, text); // wyświetlenie aktualnej ilości klatek/s w pasku okna
- }
- my_car->Simulation(avg_cycle_time); // symulacja własnego obiektu
- Frame frame;
- if (changeServ && !iAmServer)
- {
- frame.type = 505; // wyslij ramke zmiana serwera
- }
- else
- {
- frame.type = 1; // wyslij zwykla ramke
- }
- frame.state = my_car->State(); // state własnego obiektu
- frame.iID = my_car->iID;
- uni_send->send((char*)&frame, serverIp, sizeof(Frame)); // wysłanie komunikatu do pozostałych aplikacji
- }
- // *****************************************************************
- // **** Wszystko co trzeba zrobić podczas zamykania aplikacji
- // **** poza grafiką
- void EndOfInteraction()
- {
- fprintf(f, "Koniec interakcji\n");
- Frame frame;
- frame.state = my_car->State();
- frame.iID = my_car->iID;
- frame.type = 0; // wyslij ramke usun klienta
- uni_send->send((char*)&frame, serverIp, sizeof(Frame));
- fclose(f);
- }
- //deklaracja funkcji obslugi okna
- LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
- HDC g_context = NULL; // uchwyt contextu graficznego
- //funkcja Main - dla Windows
- int WINAPI WinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int nCmdShow)
- {
- //Initilize the critical section
- InitializeCriticalSection(&m_cs);
- MSG message; //innymi slowy "komunikat"
- WNDCLASS main_class; //klasa głównego okna aplikacji
- static char class_name[] = "Klasa_Podstawowa";
- //Definiujemy klase głównego okna aplikacji
- //Okreslamy tu wlasciwosci okna, szczegoly wygladu oraz
- //adres funkcji przetwarzajacej komunikaty
- main_class.style = CS_HREDRAW | CS_VREDRAW;
- main_class.lpfnWndProc = WndProc; //adres funkcji realizującej przetwarzanie meldunków
- main_class.cbClsExtra = 0;
- main_class.cbWndExtra = 0;
- main_class.hInstance = hInstance; //identyfikator procesu przekazany przez MS Windows podczas uruchamiania programu
- main_class.hIcon = 0;
- main_class.hCursor = LoadCursor(0, IDC_ARROW);
- main_class.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
- main_class.lpszMenuName = "Menu";
- main_class.lpszClassName = class_name;
- //teraz rejestrujemy klasę okna głównego
- RegisterClass(&main_class);
- main_window = CreateWindow(class_name, "WWC-lab 2018/19 temat 1 - Architektury sieciowe, wersja i", WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
- 100, 50, 950, 650, NULL, NULL, hInstance, NULL);
- ShowWindow(main_window, nCmdShow);
- //odswiezamy zawartosc okna
- UpdateWindow(main_window);
- // pobranie komunikatu z kolejki jeśli funkcja PeekMessage zwraca wartość inną niż FALSE,
- // w przeciwnym wypadku symulacja wirtualnego świata wraz z wizualizacją
- ZeroMemory(&message, sizeof(message));
- while (message.message != WM_QUIT)
- {
- if (PeekMessage(&message, NULL, 0U, 0U, PM_REMOVE))
- {
- TranslateMessage(&message);
- DispatchMessage(&message);
- }
- else
- {
- VirtualWorldCycle(); // Cykl wirtualnego świata
- InvalidateRect(main_window, NULL, FALSE);
- }
- }
- return (int)message.wParam;
- }
- /********************************************************************
- FUNKCJA OKNA realizujaca przetwarzanie meldunków kierowanych do okna aplikacji*/
- LRESULT CALLBACK WndProc(HWND main_window, UINT message_code, WPARAM wParam, LPARAM lParam)
- {
- switch (message_code)
- {
- case WM_CREATE: //message wysyłany w momencie tworzenia okna
- {
- g_context = GetDC(main_window);
- srand((unsigned)time(NULL));
- int result = GraphicsInitialisation(g_context);
- if (result == 0)
- {
- printf("nie udalo sie otworzyc okna graficznego\n");
- //exit(1);
- }
- InteractionInitialisation();
- SetTimer(main_window, 1, 10, NULL);
- return 0;
- }
- case WM_PAINT:
- {
- PAINTSTRUCT paint;
- HDC context;
- context = BeginPaint(main_window, &paint);
- DrawScene();
- SwapBuffers(context);
- EndPaint(main_window, &paint);
- return 0;
- }
- case WM_TIMER:
- return 0;
- case WM_SIZE:
- {
- int cx = LOWORD(lParam);
- int cy = HIWORD(lParam);
- WindowResize(cx, cy);
- return 0;
- }
- case WM_DESTROY: //obowiązkowa obsługa meldunku o zamknięciu okna
- EndOfInteraction();
- EndOfGraphics();
- ReleaseDC(main_window, g_context);
- KillTimer(main_window, 1);
- //LPDWORD lpExitCode;
- DWORD ExitCode;
- GetExitCodeThread(threadReciv, &ExitCode);
- TerminateThread(threadReciv, ExitCode);
- //ExitThread(ExitCode);
- //Sleep(1000);
- other_cars.clear();
- PostQuitMessage(0);
- return 0;
- case WM_LBUTTONDOWN: //reakcja na lewy przycisk myszki
- {
- int x = LOWORD(lParam);
- int y = HIWORD(lParam);
- if (if_mouse_control)
- my_car->F = 30.0; // siła pchająca do przodu
- break;
- }
- case WM_RBUTTONDOWN: //reakcja na prawy przycisk myszki
- {
- int x = LOWORD(lParam);
- int y = HIWORD(lParam);
- if (if_mouse_control)
- my_car->F = -5.0; // siła pchająca do tylu
- break;
- }
- case WM_MBUTTONDOWN: //reakcja na środkowy przycisk myszki : uaktywnienie/dezaktywacja sterwania myszkowego
- {
- if_mouse_control = 1 - if_mouse_control;
- if (if_mouse_control) my_car->if_keep_steer_wheel = true;
- else my_car->if_keep_steer_wheel = false;
- mouse_cursor_x = LOWORD(lParam);
- mouse_cursor_y = HIWORD(lParam);
- break;
- }
- case WM_LBUTTONUP: //reakcja na puszczenie lewego przycisku myszki
- {
- if (if_mouse_control)
- my_car->F = 0.0; // siła pchająca do przodu
- break;
- }
- case WM_RBUTTONUP: //reakcja na puszczenie lewy przycisk myszki
- {
- if (if_mouse_control)
- my_car->F = 0.0; // siła pchająca do przodu
- break;
- }
- case WM_MOUSEMOVE:
- {
- int x = LOWORD(lParam);
- int y = HIWORD(lParam);
- if (if_mouse_control)
- {
- float wheel_angle = (float)(mouse_cursor_x - x) / 20;
- if (wheel_angle > 60) wheel_angle = 60;
- if (wheel_angle < -60) wheel_angle = -60;
- my_car->state.steering_angle = PI * wheel_angle / 180;
- //my_car->steer_wheel_speed = (float)(mouse_cursor_x - x) / 20;
- }
- break;
- }
- case WM_KEYDOWN:
- {
- switch (LOWORD(wParam))
- {
- case VK_SHIFT:
- {
- if_SHIFT_pressed = 1;
- break;
- }
- case VK_SPACE:
- {
- my_car->breaking_factor = 1.0; // stopień hamowania (reszta zależy od siły docisku i wsp. tarcia)
- break; // 1.0 to maksymalny stopień (np. zablokowanie kół)
- }
- case VK_UP:
- {
- my_car->F = 100.0; // siła pchająca do przodu
- break;
- }
- case VK_DOWN:
- {
- my_car->F = -70.0;
- break;
- }
- case VK_LEFT:
- {
- if (my_car->steer_wheel_speed < 0) {
- my_car->steer_wheel_speed = 0;
- my_car->if_keep_steer_wheel = true;
- }
- else {
- if (if_SHIFT_pressed) my_car->steer_wheel_speed = 0.5;
- else my_car->steer_wheel_speed = 0.25 / 8;
- }
- break;
- }
- case VK_RIGHT:
- {
- if (my_car->steer_wheel_speed > 0) {
- my_car->steer_wheel_speed = 0;
- my_car->if_keep_steer_wheel = true;
- }
- else {
- if (if_SHIFT_pressed) my_car->steer_wheel_speed = -0.5;
- else my_car->steer_wheel_speed = -0.25 / 8;
- }
- break;
- }
- case 'I': // wypisywanie nr ID
- {
- if_ID_visible = 1 - if_ID_visible;
- break;
- }
- case 'W': // cam_distance widoku
- {
- //cam_pos = cam_pos - cam_direct*0.3;
- if (viewpar.cam_distance > 0.5) viewpar.cam_distance /= 1.2;
- else viewpar.cam_distance = 0;
- break;
- }
- case 'S': // przybliżenie widoku
- {
- //cam_pos = cam_pos + cam_direct*0.3;
- if (viewpar.cam_distance > 0) viewpar.cam_distance *= 1.2;
- else viewpar.cam_distance = 0.5;
- break;
- }
- case 'Q': // widok z góry
- {
- if (viewpar.tracking) break;
- viewpar.top_view = 1 - viewpar.top_view;
- if (viewpar.top_view)
- {
- viewpar.cam_pos_1 = viewpar.cam_pos; viewpar.cam_direct_1 = viewpar.cam_direct; viewpar.cam_vertical_1 = viewpar.cam_vertical;
- viewpar.cam_distance_1 = viewpar.cam_distance; viewpar.cam_angle_1 = viewpar.cam_angle;
- viewpar.cam_pos = viewpar.cam_pos_2; viewpar.cam_direct = viewpar.cam_direct_2; viewpar.cam_vertical = viewpar.cam_vertical_2;
- viewpar.cam_distance = viewpar.cam_distance_2; viewpar.cam_angle = viewpar.cam_angle_2;
- }
- else
- {
- viewpar.cam_pos_2 = viewpar.cam_pos; viewpar.cam_direct_2 = viewpar.cam_direct; viewpar.cam_vertical_2 = viewpar.cam_vertical;
- viewpar.cam_distance_2 = viewpar.cam_distance; viewpar.cam_angle_2 = viewpar.cam_angle;
- viewpar.cam_pos = viewpar.cam_pos_1; viewpar.cam_direct = viewpar.cam_direct_1; viewpar.cam_vertical = viewpar.cam_vertical_1;
- viewpar.cam_distance = viewpar.cam_distance_1; viewpar.cam_angle = viewpar.cam_angle_1;
- }
- break;
- }
- case 'E': // obrót kamery ku górze (względem lokalnej osi z)
- {
- viewpar.cam_angle += PI * 5 / 180;
- break;
- }
- case 'D': // obrót kamery ku dołowi (względem lokalnej osi z)
- {
- viewpar.cam_angle -= PI * 5 / 180;
- break;
- }
- case 'A': // włączanie, wyłączanie trybu śledzenia obiektu
- {
- viewpar.tracking = 1 - viewpar.tracking;
- if (viewpar.tracking)
- {
- viewpar.cam_distance = viewpar.cam_distance_3; viewpar.cam_angle = viewpar.cam_angle_3;
- }
- else
- {
- viewpar.cam_distance_3 = viewpar.cam_distance; viewpar.cam_angle_3 = viewpar.cam_angle;
- viewpar.top_view = 0;
- viewpar.cam_pos = viewpar.cam_pos_1; viewpar.cam_direct = viewpar.cam_direct_1; viewpar.cam_vertical = viewpar.cam_vertical_1;
- viewpar.cam_distance = viewpar.cam_distance_1; viewpar.cam_angle = viewpar.cam_angle_1;
- }
- break;
- }
- case 'Z': // zoom - zmniejszenie kąta widzenia
- {
- viewpar.zoom /= 1.1;
- RECT rc;
- GetClientRect(main_window, &rc);
- WindowResize(rc.right - rc.left, rc.bottom - rc.top);
- break;
- }
- case 'X': // zoom - zwiększenie kąta widzenia
- {
- viewpar.zoom *= 1.1;
- RECT rc;
- GetClientRect(main_window, &rc);
- WindowResize(rc.right - rc.left, rc.bottom - rc.top);
- break;
- }
- case 'K': //zmiana serwera
- {
- changeServ = true;
- break;
- }
- case VK_F1: // wywolanie systemu pomocy
- {
- char lan[1024], lan_bie[1024];
- //GetSystemDirectory(lan_sys,1024);
- GetCurrentDirectory(1024, lan_bie);
- strcpy(lan, "C:\\Program Files\\Internet Explorer\\iexplore ");
- strcat(lan, lan_bie);
- strcat(lan, "\\pomoc.htm");
- int wyni = WinExec(lan, SW_NORMAL);
- if (wyni < 32) // proba uruchominia pomocy nie powiodla sie
- {
- strcpy(lan, "C:\\Program Files\\Mozilla Firefox\\firefox ");
- strcat(lan, lan_bie);
- strcat(lan, "\\pomoc.htm");
- wyni = WinExec(lan, SW_NORMAL);
- if (wyni < 32)
- {
- char lan_win[1024];
- GetWindowsDirectory(lan_win, 1024);
- strcat(lan_win, "\\notepad pomoc.txt ");
- wyni = WinExec(lan_win, SW_NORMAL);
- }
- }
- break;
- }
- case VK_ESCAPE:
- {
- SendMessage(main_window, WM_DESTROY, 0, 0);
- break;
- }
- } // switch po klawiszach
- break;
- }
- case WM_KEYUP:
- {
- switch (LOWORD(wParam))
- {
- case VK_SHIFT:
- {
- if_SHIFT_pressed = 0;
- break;
- }
- case VK_SPACE:
- {
- my_car->breaking_factor = 0.0;
- break;
- }
- case VK_UP:
- {
- my_car->F = 0.0;
- break;
- }
- case VK_DOWN:
- {
- my_car->F = 0.0;
- break;
- }
- case VK_LEFT:
- {
- my_car->Fb = 0.00;
- //my_car->state.steering_angle = 0;
- if (my_car->if_keep_steer_wheel) my_car->steer_wheel_speed = -0.25 / 8;
- else my_car->steer_wheel_speed = 0;
- my_car->if_keep_steer_wheel = false;
- break;
- }
- case VK_RIGHT:
- {
- my_car->Fb = 0.00;
- //my_car->state.steering_angle = 0;
- if (my_car->if_keep_steer_wheel) my_car->steer_wheel_speed = 0.25 / 8;
- else my_car->steer_wheel_speed = 0;
- my_car->if_keep_steer_wheel = false;
- break;
- }
- }
- break;
- }
- default: //statedardowa obsługa pozostałych meldunków
- return DefWindowProc(main_window, message_code, wParam, lParam);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement