Exemple #1
0
void InitalizeEngine() {
  BeginProfileEntry("Initalize Engine");
  Engine *engine = &g_engine;

#ifdef VENOM_SINGLE_THREADED
  size_t workerCount = 1;
#else VENOM_SINGLE_THREADED
  size_t workerCount = std::thread::hardware_concurrency();
#endif//VENOM_SINGLE_THREADED

  size_t requiredMemory = Align8(workerCount * sizeof(Worker));
  requiredMemory += Align8(WORKER_STACK_MEMORY_SIZE * workerCount);
  U8 *memory = (U8 *)MemoryAllocate(requiredMemory);
  memset(memory, 0x00, requiredMemory);
  engine->workers = (Worker *)memory;
  engine->workerCount = workerCount;
  engine->isRunning = true;
  U8 *currentStackMemoryPtr = memory + Align8(workerCount * sizeof(Worker));
  g_threadID = 0; //Set the main thread's id to 0
  for (size_t i = 0; i < workerCount; i++) {
    Worker *worker = &engine->workers[i];
    worker->workerID = i;
    worker->stackMemory.memory = currentStackMemoryPtr;
    worker->stackMemory.size = WORKER_STACK_MEMORY_SIZE;
    currentStackMemoryPtr += WORKER_STACK_MEMORY_SIZE;
  }

  for (size_t i = 1; i < workerCount; i++) {
    Worker *worker = &engine->workers[i];
    worker->thread = std::thread(WorkerThreadProc, worker);
  }

  { //Initalize physics simulation paramaters
    PhysicsSimulation *sim = &engine->physicsSimulation;
    sim->gravityAcceleration = V3(0.0f, -9.81f, 0.0f);
  }

  InitalizeTerrain(&engine->terrain, 5, 8, 32);


#ifndef VENOM_RELEASE
  OpenGLEnableDebug(&engine->debugLog);
#endif//VENOM_RELEASE
  

  EndProfileEntry();
}
Exemple #2
0
int main(int argc, char *argv[]) {
    sdl_state SDLState = {};

    platform_work_queue HighPriorityQueue = {};
    SDLMakeQueue(&HighPriorityQueue, 6);

    platform_work_queue LowPriorityQueue = {};
    SDLMakeQueue(&LowPriorityQueue, 2);


    GlobalPerfCountFrequency = SDL_GetPerformanceFrequency();

    SDLGetEXEFileName(&SDLState);

    char SourceGameCodeDLLFullpath[SDL_STATE_FILE_NAME_COUNT];
    SDLBuildEXEPathFileName(&SDLState, "handmade.dylib",
                            sizeof(SourceGameCodeDLLFullpath), SourceGameCodeDLLFullpath);

    char TempGameCodeDLLFullpath[SDL_STATE_FILE_NAME_COUNT];
    SDLBuildEXEPathFileName(&SDLState, "handmade_temp.dylib",
                            sizeof(TempGameCodeDLLFullpath), TempGameCodeDLLFullpath);

    char GameCodeLockFullpath[SDL_STATE_FILE_NAME_COUNT];
    SDLBuildEXEPathFileName(&SDLState, "lock.tmp",
                            sizeof(GameCodeLockFullpath), GameCodeLockFullpath);

    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) != 0) {
        printf("Failed to initialize SDL: %s\n", SDL_GetError());
        return -1;
    }

    SDL_Window *Window = SDL_CreateWindow("Handmade Hero",
                                          SDL_WINDOWPOS_CENTERED,
                                          SDL_WINDOWPOS_CENTERED,
                                          960, 540,
                                          SDL_WINDOW_OPENGL);
    if (!Window) {
        printf("Failed to create window: %s\n", SDL_GetError());
        return -1;
    }

    SDLResizeDIBSection(Window, &GlobalBackBuffer, 960, 540);

    // TODO: Set GameUpdateHz by monitor refresh HZ
    real32 GameUpdateHz = 60.0f;
    real32 TargetSecondsPerFrame = 1.0f / GameUpdateHz;

    sdl_sound_output SoundOutput = {};
    SoundOutput.SamplesPerSecond = 48000;
    SoundOutput.BytesPerSample = sizeof(int16) * 2;
    SoundOutput.BufferSize = SoundOutput.SamplesPerSecond * SoundOutput.BytesPerSample;

    SDL_AudioDeviceID Audio = SDLInitSound(SoundOutput.SamplesPerSecond);

    u32 MaxPossibleOverrun = 2 * 4 * sizeof(u16);
    int16 *Samples = (int16 *)mmap(0, (size_t)(SoundOutput.BufferSize + MaxPossibleOverrun),
                                   PROT_READ | PROT_WRITE,
                                   MAP_PRIVATE | MAP_ANON, -1, 0);

    GlobalRunning = true;

#if HANDMADE_INTERNAL
    void *BaseAddress = (void *)Terabytes(2);
#else
    void *BaseAddress = 0;
#endif

    game_memory GameMemory = {};
    GameMemory.PermanentStorageSize = Megabytes(64);
    GameMemory.TransientStorageSize = Gigabytes(256);
    GameMemory.HighPriorityQueue = &HighPriorityQueue;
    GameMemory.LowPriorityQueue = &LowPriorityQueue;

    GameMemory.PlatformAPI.AddEntry = SDLAddEntry;
    GameMemory.PlatformAPI.CompleteAllWork = SDLCompleteAllWork;

    GameMemory.PlatformAPI.GetAllFilesOfTypeBegin = SDLGetAllFilesOfTypeBegin;
    GameMemory.PlatformAPI.GetAllFilesOfTypeEnd = SDLGetAllFilesOfTypeEnd;
    GameMemory.PlatformAPI.OpenNextFile = SDLOpenNextFile;
    GameMemory.PlatformAPI.ReadDataFromFile = SDLReadDataFromFile;
    GameMemory.PlatformAPI.FileError = SDLFileError;

    GameMemory.PlatformAPI.AllocateMemory = SDLAllocateMemory;
    GameMemory.PlatformAPI.DeallocateMemory = SDLDeallocateMemory;

    GameMemory.PlatformAPI.DEBUGFreeFileMemory = DEBUGPlatformFreeFileMemory;
    GameMemory.PlatformAPI.DEBUGReadEntireFile = DEBUGPlatformReadEntireFile;
    GameMemory.PlatformAPI.DEBUGWriteEntireFile = DEBUGPlatformWriteEntireFile;

    SDLState.TotalSize = GameMemory.PermanentStorageSize + GameMemory.TransientStorageSize;

    SDLState.GameMemoryBlock = mmap(BaseAddress,
                                    (size_t) SDLState.TotalSize,
                                    PROT_READ | PROT_WRITE,
                                    MAP_PRIVATE | MAP_ANON, -1, 0);
    GameMemory.PermanentStorage = SDLState.GameMemoryBlock;
    GameMemory.TransientStorage = ((uint8 *) GameMemory.PermanentStorage + GameMemory.PermanentStorageSize);

    if (!(GameMemory.PermanentStorage && GameMemory.TransientStorage)) {
        printf("Failed to allocate game memory\n");
        return -1;
    }

    // TODO: Add game replay support here

    game_input Input[2] = {};
    game_input *NewInput = &Input[0];
    game_input *OldInput = &Input[1];

    uint64 LastCounter = SDL_GetPerformanceCounter();
    uint64 FlipWallClock = SDL_GetPerformanceCounter();

    sdl_game_code Game = SDLLoadGameCode(SourceGameCodeDLLFullpath,
                                         TempGameCodeDLLFullpath,
                                         GameCodeLockFullpath);

    uint64 LastCycleCount = _rdtsc();

    while (GlobalRunning) {
        NewInput->dtForFrame = TargetSecondsPerFrame;

        NewInput->ExecutableReloaded = false;
        time_t NewDLLWriteTime = SDLGetLastWriteTime(SourceGameCodeDLLFullpath);
        if (difftime(NewDLLWriteTime, Game.DLLLastWriteTime) > 0) {
            SDLCompleteAllWork(&HighPriorityQueue);
            SDLCompleteAllWork(&LowPriorityQueue);

            SDLUnloadGameCode(&Game);
            Game = SDLLoadGameCode(SourceGameCodeDLLFullpath,
                                   TempGameCodeDLLFullpath,
                                   GameCodeLockFullpath);
            NewInput->ExecutableReloaded = true;
        }

        game_controller_input *OldKeyboardController = GetController(OldInput, 0);
        game_controller_input *NewKeyboardController = GetController(NewInput, 0);
        *NewKeyboardController = {};
        NewKeyboardController->IsConnected = true;
        for (size_t ButtonIndex = 0; ButtonIndex < ArrayCount(NewKeyboardController->Buttons); ++ButtonIndex) {
            NewKeyboardController->Buttons[ButtonIndex].EndedDown = OldKeyboardController->Buttons[ButtonIndex].EndedDown;
        }

        SDLProcessPendingMessage(&SDLState, NewKeyboardController);

        if (!GlobalPause) {
            Uint32 MouseButtons = SDL_GetMouseState(&NewInput->MouseX, &NewInput->MouseY);
            NewInput->MouseZ = 0;
            SDLProcessKeyboardMessage(&NewInput->MouseButtons[0],
                                      SDL_BUTTON(SDL_BUTTON_LEFT));
            SDLProcessKeyboardMessage(&NewInput->MouseButtons[1],
                                      SDL_BUTTON(SDL_BUTTON_MIDDLE));
            SDLProcessKeyboardMessage(&NewInput->MouseButtons[2],
                                      SDL_BUTTON(SDL_BUTTON_RIGHT));
            SDLProcessKeyboardMessage(&NewInput->MouseButtons[3],
                                      SDL_BUTTON(SDL_BUTTON_X1));
            SDLProcessKeyboardMessage(&NewInput->MouseButtons[4],
                                      SDL_BUTTON(SDL_BUTTON_X2));

            // TODO: Handle Mouse button here

            // TODO: Game controller support here

            game_offscreen_buffer Buffer = {};
            Buffer.Memory = GlobalBackBuffer.Memory;
            Buffer.Width = GlobalBackBuffer.Width;
            Buffer.Height = GlobalBackBuffer.Height;
            Buffer.Pitch = GlobalBackBuffer.Pitch;

            if (Game.UpdateAndRender) {
                Game.UpdateAndRender(&GameMemory, NewInput, &Buffer);
                HandleDebugCycleCounters(&GameMemory);
            }

            // TODO: Game audio support here
            game_sound_output_buffer SoundBuffer = {};
            SoundBuffer.SamplesPerSecond = SoundOutput.SamplesPerSecond;
            SoundBuffer.SampleCount = Align8((u32)(SoundOutput.SamplesPerSecond * TargetSecondsPerFrame));
            SoundBuffer.Samples = Samples;
            if (Game.GetSoundSamples) {
                Game.GetSoundSamples(&GameMemory, &SoundBuffer);
                SDL_QueueAudio(Audio, SoundBuffer.Samples, SoundBuffer.SampleCount * SoundOutput.BytesPerSample);
            }

            SDLDisplayBufferInWindow(&GlobalBackBuffer);

            game_input *Temp = NewInput;
            NewInput = OldInput;
            OldInput = Temp;
        }
    }

    return 0;
}
Exemple #3
0
void test_MemoryAlloc()
{
    MemoryInit((void *)pool, POOL_SIZE);

    ERROR(g_hunk_base == pool);
    ERROR(g_hunk_total_size == POOL_SIZE);
    I32 size = Align16(DYNAMIC_ZONE_SIZE + sizeof(HunkHeader));
    ERROR(g_hunk_low_used == size);
    ERROR(g_hunk_high_used == 0);

    ERROR((U8 *)g_main_zone == pool + sizeof(HunkHeader));
    ERROR(g_main_zone->rover == (MemoryBlock *)(g_main_zone + 1));
    ERROR(g_main_zone->size == DYNAMIC_ZONE_SIZE);

    // ====================
    // test hunk allocation
    // ====================

    void *hunk0 = HunkLowAlloc(1231, "hunk0");
    HunkHeader *hunk0Header = (HunkHeader *)hunk0 - 1;
    I32 hunk0Size = Align16(1231 + sizeof(HunkHeader));
    ERROR(hunk0Header->size == hunk0Size);
    ERROR(hunk0Header->sentinel == HUNK_SENTINEL);
    ERROR(StringCompare(hunk0Header->name, "hunk0") == 0);
    ERROR(g_hunk_low_used == size + hunk0Size);

    void *hunk1 = HunkHighAlloc(3211, "hunk1");
    HunkHeader *hunk1Header = (HunkHeader *)hunk1 - 1;
    I32 hunk1Size = Align16(3211 + sizeof(HunkHeader));
    ERROR(hunk0Header->size == hunk0Size);
    ERROR(hunk0Header->sentinel == HUNK_SENTINEL);
    ERROR(StringCompare(hunk1Header->name, "hunk1") == 0);
    ERROR(g_hunk_high_used == hunk1Size);

    // ====================
    // test zone allocation
    // ====================

    void *zone0 = ZoneTagMalloc(234, 8);
    MemoryBlock *zone0Block = (MemoryBlock *)zone0 - 1;
    I32 zone0Size = Align8(234 + sizeof(MemoryBlock) + 4);
    ERROR(zone0Block->size == zone0Size);
    ERROR(zone0Block->tag == 8);
    ERROR(zone0Block->id == ZONE_ID);
    ERROR(zone0Block->prev == &g_main_zone->tailhead);
    MemoryBlock *freeBlock = zone0Block->next;
    ERROR(freeBlock->tag == 0);

    void *zone1 = ZoneTagMalloc(324, 1);
    void *zone2 = ZoneTagMalloc(432, 2);
    void *zone3 = ZoneTagMalloc(223, 3);
    void *zone4 = ZoneTagMalloc(333, 4);

    ZoneFree(zone1);
    MemoryBlock *zone1Block = (MemoryBlock *)zone1 - 1;
    I32 zone1Size = Align8(324 + sizeof(MemoryBlock) + 4);
    ERROR(zone1Block->tag == 0);
    ERROR(zone1Block->size == zone1Size);
    ERROR(zone1Block->id == ZONE_ID);
    ERROR(zone1Block->prev == (MemoryBlock *)zone0 - 1);
    ERROR(zone1Block->next == (MemoryBlock *)zone2 - 1);

    ZoneFree(zone3);
    MemoryBlock *zone3Block = (MemoryBlock *)zone3 - 1;
    I32 zone3Size = Align8(223 + sizeof(MemoryBlock) + 4);
    ERROR(zone3Block->tag == 0);
    ERROR(zone3Block->size == zone3Size);
    ERROR(zone3Block->id == ZONE_ID);
    ERROR(zone3Block->prev == (MemoryBlock *)zone2 - 1);
    ERROR(zone3Block->next == (MemoryBlock *)zone4 - 1);
    
    ZoneFree(zone2);
    I32 zone2Size = Align8(432 + sizeof(MemoryBlock) + 4);
    ERROR(zone1Block->tag == 0);
    ERROR(zone1Block->size == zone1Size + zone2Size + zone3Size);
    ERROR(zone1Block->prev == (MemoryBlock *)zone0 - 1);
    ERROR(zone1Block->next == (MemoryBlock *)zone4 - 1);

    void *tooBig = ZoneTagMalloc(DYNAMIC_ZONE_SIZE * 2, 22);
    ERROR(tooBig == NULL);

    ZoneClearAll(g_main_zone);
    ERROR(g_main_zone->tailhead.next == g_main_zone->rover);
    ERROR(g_main_zone->tailhead.prev == g_main_zone->rover);
    ERROR(g_main_zone->rover->next == &g_main_zone->tailhead);
    ERROR(g_main_zone->rover->next == &g_main_zone->tailhead);
}