#include #include #include #include #include #include #include #include #include double getTime() { struct timespec tv; clock_gettime(CLOCK_MONOTONIC, &tv); return tv.tv_sec + tv.tv_nsec / 1000000000.0; } void addTile(Cygnet::ResourceBuilder &builder, const char *path) { static size_t id = 0; SDL_Surface *surf = IMG_Load(path); builder.addTile(id++, surf->pixels); SDL_FreeSurface(surf); } Cygnet::RenderSprite loadSprite(Cygnet::ResourceBuilder &builder, const char *path, int fh) { SDL_Surface *surf = IMG_Load(path); auto sprite = builder.addSprite(path, surf->pixels, surf->w, surf->h, fh); SDL_FreeSurface(surf); return sprite; } Cygnet::RenderSprite loadSprite(Cygnet::ResourceBuilder &builder, const char *path) { SDL_Surface *surf = IMG_Load(path); auto sprite = builder.addSprite(path, surf->pixels, surf->w, surf->h); SDL_FreeSurface(surf); return sprite; } int main() { SDL_Init(SDL_INIT_VIDEO); IMG_Init(IMG_INIT_PNG); Cygnet::Window win("Cygnet Test", 680, 680); Cygnet::Renderer rnd; Cygnet::ResourceBuilder rbuilder(rnd); for (auto path: { "core.mod/assets/tile/dirt.png", "core.mod/assets/tile/grass.png", "core.mod/assets/tile/leaves.png", "core.mod/assets/tile/stone.png", "core.mod/assets/tile/torch.png", "core.mod/assets/tile/tree-trunk.png", }) addTile(rbuilder, path); unsigned char animTexture[32*32*4*3]; for (size_t i = 0; i < 3; ++i) { int col = 100 * i + 50;; for (size_t y = 0; y < 32; ++y) { for (size_t x = 0; x < 32; ++x) { animTexture[i * 32 * 32 * 4 + y * 32 * 4 + x * 4 + 0] = col; animTexture[i * 32 * 32 * 4 + y * 32 * 4 + x * 4 + 1] = col; animTexture[i * 32 * 32 * 4 + y * 32 * 4 + x * 4 + 2] = col; animTexture[i * 32 * 32 * 4 + y * 32 * 4 + x * 4 + 3] = 255; } } } rbuilder.addTile(10, animTexture, 3); Cygnet::RenderSprite playerSprite = loadSprite( rbuilder, "core.mod/assets/entity/player-still.png", 64); Cygnet::ResourceManager resources(std::move(rbuilder)); Cygnet::RenderChunk chunk; { uint16_t tiles[SwanCommon::CHUNK_WIDTH * SwanCommon::CHUNK_HEIGHT]; memset(tiles, 0, sizeof(tiles)); tiles[0] = 1; tiles[1] = 2; tiles[2] = 3; for (int y = 0; y < 8; ++y) { for (int x = 0; x < 8; ++x) { tiles[y * SwanCommon::CHUNK_WIDTH + x] = 10; } } tiles[10] = 10; chunk = rnd.createChunk(tiles); } Cygnet::RenderCamera cam = { .pos = { 0, 0 }, .size = win.size(), .zoom = 1, }; float animAcc = 0; bool keys[512] = { 0 }; double tileAnimAcc = 0; double fpsAcc = 0; double prevTime = getTime() - 1/60.0; int frames = 0; float x = 0, y = 0; while (true) { double currTime = getTime(); double dt = currTime - prevTime; prevTime = currTime; animAcc += dt; fpsAcc += dt; frames += 1; if (fpsAcc >= 2) { std::cerr << "FPS: " << (frames / 2.0) << '\n'; fpsAcc -= 2; frames = 0; } tileAnimAcc += dt; if (tileAnimAcc >= 0.5) { resources.tick(); tileAnimAcc -= 0.5; } SDL_Event evt; while (SDL_PollEvent(&evt)) { switch (evt.type) { case SDL_QUIT: goto exit; case SDL_WINDOWEVENT: switch (evt.window.event) { case SDL_WINDOWEVENT_SIZE_CHANGED: win.onResize(evt.window.data1, evt.window.data2); cam.size = win.size(); break; } break; case SDL_MOUSEWHEEL: cam.zoom += evt.wheel.y * 0.1 * cam.zoom; break; case SDL_KEYDOWN: keys[evt.key.keysym.scancode] = true; break; case SDL_KEYUP: keys[evt.key.keysym.scancode] = false; break; } } if (keys[SDL_SCANCODE_A]) { x -= 1 * dt; } if (keys[SDL_SCANCODE_D]) { x += 1 * dt; } if (keys[SDL_SCANCODE_W]) { y -= 1 * dt; } if (keys[SDL_SCANCODE_S]) { y += 1 * dt; } rnd.drawChunk(chunk, {0, 0}); rnd.drawSprite(playerSprite, Cygnet::Mat3gf{}.translate({x, y}), (int)animAcc % 2); cam.pos = {x + 0.5f, y + 0.5f}; win.clear(); rnd.draw(cam); win.flip(); } exit: IMG_Quit(); SDL_Quit(); }