#include #include #include #include #define FNCross(x1, y1, x2, y2) x1 * y2 - y1 * x2 void Intersect(float& x1, float& y1, float& x2, float& y2, float x3, float y3, float x4, float y4, float& x, float& y) { x = FNCross(x1, y1, x2, y2); y = FNCross(x3, y3, x4, y4); float det = FNCross(x1 - x2, y1 - y2, x3 - x4, y3 - y4); x = FNCross(x, x1 - x2, y, x3 - x4) / det; y = FNCross(x, y1 - y2, y, y3 - y4) / det; } void QuitSDL(SDL_Window* w = nullptr, SDL_Renderer* r = nullptr, SDL_Surface* s[] = nullptr, int numSurfaces = 0, SDL_Texture* t[] = nullptr, int numTextures = 0, TTF_Font* f[] = nullptr, int NumFonts = 0) { if (t != nullptr) for (int nt = 0; nt < numTextures; nt++) SDL_DestroyTexture(t[nt]); if (s != nullptr) for (int ns = 0; ns < numSurfaces; ns++) SDL_FreeSurface(s[ns]); if (f != nullptr) for (int nf = 0; nf < NumFonts; nf++) TTF_CloseFont(f[nf]); if (r != nullptr) SDL_DestroyRenderer(r); if (w != nullptr) SDL_DestroyWindow(w); TTF_Quit(); IMG_Quit(); SDL_Quit(); } void Init() { SDL_Init(SDL_INIT_EVERYTHING); IMG_Init(IMG_INIT_PNG | IMG_INIT_JPG); TTF_Init(); } int main(int args, char* argc[]) { // before SDL init const int WinW{ 600 }; const int WinH{ 400 }; // SDL init Init(); SDL_Window* win{ SDL_CreateWindow("SDL DOOM LIKE ENGINE DEMO", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WinW, WinH, SDL_WINDOW_SHOWN) }; SDL_Renderer* ren{ SDL_CreateRenderer(win, -1, SDL_RENDERER_PRESENTVSYNC) }; // other variables SDL_Event e; bool q{ false }; // player variables float angle = 0.0; float px{ 100 }; float py{ 100 }; // view port rects SDL_Rect Viewport1{ 0, 100, 200, 200 }; SDL_Rect Viewport2{ 200, 100, 200, 200 }; SDL_Rect Viewport3{ 400, 100, 200, 200 }; SDL_Rect Border{0, 0, 200, 200}; // wall variables float wall_x1 = 140; float wall_y1 = 40; float wall_x2 = 140; float wall_y2 = 140; // main loop while (!q) { // render clear SDL_SetRenderDrawColor(ren, 0, 0, 0, 255); SDL_RenderClear(ren); // view box 1 SDL_RenderSetViewport(ren, &Viewport1); SDL_SetRenderDrawColor(ren, 200, 200, 0, 255); SDL_RenderDrawLineF(ren, wall_x1, wall_y1, wall_x2, wall_y2); SDL_SetRenderDrawColor(ren, 255, 255, 255, 255); SDL_RenderDrawLineF(ren, px, py, (cosf(angle) * 8) + px, (sinf(angle) * 8) + py); SDL_RenderSetScale(ren, 2, 2); SDL_RenderDrawPointF(ren, (px / 2), (py / 2)); SDL_RenderSetScale(ren, 1, 1); SDL_SetRenderDrawColor(ren, 0, 0, 250, 255); SDL_RenderDrawRect(ren, &Border); // view box 2 SDL_RenderSetViewport(ren, &Viewport2); // more variables to use float tx1{ wall_x1 - px }; float ty1{ wall_y1 - py }; float tx2{ wall_x2 - px }; float ty2{ wall_y2 - py }; float tz1{ tx1 * cosf(angle) + ty1 * sinf(angle) }; float tz2{ tx2 * cosf(angle) + ty2 * sinf(angle) }; tx1 = tx1 * sinf(angle) - ty1 * cosf(angle); tx2 = tx2 * sinf(angle) - ty2 * cosf(angle); SDL_SetRenderDrawColor(ren, 200, 200, 0, 255); SDL_RenderDrawLineF(ren, 100 - tx1, 100 - tz1, 100 - tx2, 100 - tz2); SDL_SetRenderDrawColor(ren, 255, 255, 255, 255); SDL_RenderDrawLineF(ren, 100, 100, 100, 90); SDL_RenderSetScale(ren, 2, 2); SDL_RenderDrawPointF(ren, 50, 50); SDL_RenderSetScale(ren, 1, 1); SDL_SetRenderDrawColor(ren, 0, 250, 0, 255); SDL_RenderDrawRect(ren, &Border); // view box 3 SDL_RenderSetViewport(ren, &Viewport3); if (tz1 > 0 || tz2 > 0) { float ix1; float iz1; float ix2; float iz2; Intersect(tx1, tz1, tx2, tz2, -0.0001, 0.0001, -20, 5, ix1, iz1); Intersect(tx1, tz1, tx2, tz2, 0.0001, 0.0001, 20, 5, ix2, iz2); if (tz1 <= 0) { if (iz1 > 0) { tx1 = iz1; tz1 = iz1; } else { tx1 = ix2; tz1 = iz2; } } if (tz2 <= 0) { if (iz1 > 0) { tx2 = ix1; tz2 = iz1; } else { tx2 = ix2; tz2 = iz2; } } float x1{ -tx1 * 16 / tz1 }; float y1a{ -50 / tz1 }; float y1b{ 50 / tz1 }; float x2{ -tx2 * 16 / tz2 }; float y2a{ -50 / tz2 }; float y2b{ 50 / tz2 }; SDL_SetRenderDrawColor(ren, 255, 255, 0, 255); SDL_RenderDrawLineF(ren, 50 + x1, 50 + y1a, 50 + x2, 50 + y2a); // top SDL_RenderDrawLineF(ren, 50 + x1, 50 + y1b, 50 + x2, 50 + y2b); // bottom SDL_RenderDrawLineF(ren, 50 + x1, 50 + y1a, 50 + x1, 50 + y1b); // left SDL_RenderDrawLineF(ren, 50 + x2, 50 + y2a, 50 + x2, 50 + y2b); // right } SDL_SetRenderDrawColor(ren, 255, 0, 0, 255); SDL_RenderDrawRect(ren, &Border); SDL_RenderPresent(ren); while (SDL_PollEvent(&e)) { if (e.type == SDL_QUIT) q = true; else if (e.type == SDL_KEYDOWN) { switch (e.key.keysym.sym) { case SDLK_w: px += cosf(angle); py += sinf(angle); break; case SDLK_s: px -= cosf(angle); py -= sinf(angle); break; case SDLK_a: px += sinf(angle); py -= cosf(angle); break; case SDLK_d: px -= sinf(angle); py += cosf(angle); break; case SDLK_q: angle -= 0.1f; break; case SDLK_e: angle += 0.1f; break; } } } } // exit code QuitSDL(win, ren); return 0; }