20int main(
int argc,
char **argv) {
21 absl::InitializeSymbolizer(argv[0]);
23 absl::FailureSignalHandlerOptions options;
24 options.symbolize_stacktrace =
true;
25 options.alarm_on_failure_secs =
true;
26 absl::InstallFailureSignalHandler(options);
30 std::unique_ptr<SDL_Window, SDL_Deleter> window_;
31 std::unique_ptr<SDL_Renderer, SDL_Deleter> renderer_;
32 if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
35 SDL_DisplayMode displayMode;
36 SDL_GetCurrentDisplayMode(0, &displayMode);
37 window_ = std::unique_ptr<SDL_Window, SDL_Deleter>(
38 SDL_CreateWindow(
"Yaze Emulator",
39 SDL_WINDOWPOS_UNDEFINED,
40 SDL_WINDOWPOS_UNDEFINED,
43 SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI),
45 if (window_ ==
nullptr) {
50 renderer_ = std::unique_ptr<SDL_Renderer, SDL_Deleter>(
51 SDL_CreateRenderer(window_.get(), -1,
52 SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC),
54 if (renderer_ ==
nullptr) {
57 SDL_SetRenderDrawBlendMode(renderer_.get(), SDL_BLENDMODE_BLEND);
58 SDL_SetRenderDrawColor(renderer_.get(), 0x00, 0x00, 0x00, 0x00);
61 int audio_frequency_ = 48000;
62 SDL_AudioSpec want, have;
63 SDL_memset(&want, 0,
sizeof(want));
64 want.freq = audio_frequency_;
65 want.format = AUDIO_S16;
69 auto audio_device_ = SDL_OpenAudioDevice(NULL, 0, &want, &have, 0);
70 if (audio_device_ == 0) {
73 auto audio_buffer_ =
new int16_t[audio_frequency_ / 50 * 4];
74 SDL_PauseAudioDevice(audio_device_, 0);
77 yaze_initialize_cocoa();
81 SDL_CreateTexture(renderer_.get(), SDL_PIXELFORMAT_RGBX8888,
82 SDL_TEXTUREACCESS_STREAMING, 512, 480);
83 if (ppu_texture_ == NULL) {
84 printf(
"Failed to create texture: %s\n", SDL_GetError());
90 std::vector<uint8_t> rom_data_;
94 auto count_frequency = SDL_GetPerformanceFrequency();
95 auto last_count = SDL_GetPerformanceCounter();
96 auto time_adder = 0.0;
97 int wanted_frames_ = 0;
98 int wanted_samples_ = 0;
101 if (!rom_.
LoadFromFile(
"inidisp_hammer_0f00.sfc").ok()) {
106 rom_data_ = rom_.
vector();
107 snes_.
Init(rom_data_);
108 wanted_frames_ = 1.0 / (snes_.
Memory().pal_timing() ? 50.0 : 60.0);
109 wanted_samples_ = 48000 / (snes_.
Memory().pal_timing() ? 50 : 60);
114 while (SDL_PollEvent(&event)) {
115 switch (event.type) {
119 rom_data_ = rom_.
vector();
120 snes_.
Init(rom_data_);
121 wanted_frames_ = 1.0 / (snes_.
Memory().pal_timing() ? 50.0 : 60.0);
122 wanted_samples_ = 48000 / (snes_.
Memory().pal_timing() ? 50 : 60);
125 SDL_free(event.drop.file);
131 case SDL_WINDOWEVENT:
132 switch (event.window.event) {
133 case SDL_WINDOWEVENT_CLOSE:
136 case SDL_WINDOWEVENT_SIZE_CHANGED:
147 uint64_t current_count = SDL_GetPerformanceCounter();
148 uint64_t delta = current_count - last_count;
149 last_count = current_count;
150 float seconds = delta / (float)count_frequency;
151 time_adder += seconds;
153 while (time_adder >= wanted_frames_ - 0.002) {
154 time_adder -= wanted_frames_;
159 snes_.
SetSamples(audio_buffer_, wanted_samples_);
160 if (SDL_GetQueuedAudioSize(audio_device_) <= wanted_samples_ * 4 * 6) {
161 SDL_QueueAudio(audio_device_, audio_buffer_, wanted_samples_ * 4);
166 if (SDL_LockTexture(ppu_texture_, NULL, &ppu_pixels_, &ppu_pitch_) !=
168 printf(
"Failed to lock texture: %s\n", SDL_GetError());
171 snes_.
SetPixels(
static_cast<uint8_t *
>(ppu_pixels_));
172 SDL_UnlockTexture(ppu_texture_);
176 SDL_RenderClear(renderer_.get());
177 SDL_RenderCopy(renderer_.get(), ppu_texture_, NULL, NULL);
178 SDL_RenderPresent(renderer_.get());
181 SDL_PauseAudioDevice(audio_device_, 1);
182 SDL_CloseAudioDevice(audio_device_);
183 delete[] audio_buffer_;