#include "StdAfx.h" #include "frontends/sdl/sdlframe.h" #include "frontends/sdl/utils.h" #include "frontends/common2/programoptions.h" #include "Interface.h" #include "Core.h" #include "Utilities.h" #include "Log.h" #include #include #include #include SDLFrame::SDLFrame(const EmulatorOptions & options) { Video & video = GetVideo(); const int width = video.GetFrameBufferWidth(); const int height = video.GetFrameBufferHeight(); const int sw = video.GetFrameBufferBorderlessWidth(); const int sh = video.GetFrameBufferBorderlessHeight(); std::cerr << std::fixed << std::setprecision(2); myWindow.reset(SDL_CreateWindow(g_pAppTitle.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, sw, sh, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE), SDL_DestroyWindow); if (!myWindow) { std::cerr << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl; return; } SetApplicationIcon(); myRenderer.reset(SDL_CreateRenderer(myWindow.get(), options.sdlDriver, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC), SDL_DestroyRenderer); if (!myRenderer) { std::cout << "SDL_CreateRenderer Error: " << SDL_GetError() << std::endl; return; } const Uint32 format = SDL_PIXELFORMAT_ARGB8888; printRendererInfo(std::cerr, myRenderer, format, options.sdlDriver); myTexture.reset(SDL_CreateTexture(myRenderer.get(), format, SDL_TEXTUREACCESS_STATIC, width, height), SDL_DestroyTexture); myRect.x = video.GetFrameBufferBorderWidth(); myRect.y = video.GetFrameBufferBorderHeight(); myRect.w = video.GetFrameBufferBorderlessWidth(); myRect.h = video.GetFrameBufferBorderlessHeight(); myPitch = video.GetFrameBufferWidth() * sizeof(bgra_t); } void SDLFrame::FrameRefreshStatus(int drawflags) { if (drawflags & DRAW_TITLE) { GetAppleWindowTitle(); SDL_SetWindowTitle(myWindow.get(), g_pAppTitle.c_str()); } } void SDLFrame::SetApplicationIcon() { const std::string path = myResourcePath + "APPLEWIN.ICO"; std::shared_ptr icon(IMG_Load(path.c_str()), SDL_FreeSurface); if (icon) { SDL_SetWindowIcon(myWindow.get(), icon.get()); } } void SDLFrame::UpdateTexture() { SDL_UpdateTexture(myTexture.get(), nullptr, myFramebuffer.data(), myPitch); } void SDLFrame::RenderPresent() { SDL_RenderCopyEx(myRenderer.get(), myTexture.get(), &myRect, nullptr, 0.0, nullptr, SDL_FLIP_VERTICAL); SDL_RenderPresent(myRenderer.get()); } void SDLFrame::VideoPresentScreen() { UpdateTexture(); RenderPresent(); } const std::shared_ptr & SDLFrame::GetWindow() const { return myWindow; } void SDLFrame::GetBitmap(LPCSTR lpBitmapName, LONG cb, LPVOID lpvBits) { const std::string filename = getBitmapFilename(lpBitmapName); const std::string path = myResourcePath + filename; std::shared_ptr surface(SDL_LoadBMP(path.c_str()), SDL_FreeSurface); if (surface) { SDL_LockSurface(surface.get()); const char * source = static_cast(surface->pixels); const size_t size = surface->h * surface->w / 8; const size_t requested = cb; const size_t copied = std::min(requested, size); char * dest = static_cast(lpvBits); for (size_t i = 0; i < copied; ++i) { const size_t offset = i * 8; char val = 0; for (size_t j = 0; j < 8; ++j) { const char pixel = *(source + offset + j); val = (val << 1) | pixel; } dest[i] = val; } SDL_UnlockSurface(surface.get()); } else { CommonFrame::GetBitmap(lpBitmapName, cb, lpvBits); } } int SDLFrame::FrameMessageBox(LPCSTR lpText, LPCSTR lpCaption, UINT uType) { // tabs do not render properly std::string s(lpText); std::replace(s.begin(), s.end(), '\t', ' '); SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, lpCaption, s.c_str(), nullptr); return IDOK; }