#include // isgraph #include "sdl-display.h" #include "images.h" #include "globals.h" #include "applevm.h" #include "apple/appleui.h" // FIXME should be able to omit this include and relay on the xterns, which // would prove it's linking properly #include "apple/font.h" extern const unsigned char ucase_glyphs[512]; extern const unsigned char lcase_glyphs[256]; extern const unsigned char mousetext_glyphs[256]; extern const unsigned char interface_glyphs[256]; #define SCREENINSET_X (18*SDLDISPLAY_SCALE) #define SCREENINSET_Y (13*SDLDISPLAY_SCALE) // RGB map of each of the lowres colors const uint8_t loresPixelColors[16][3] = { { 0, 0, 0 }, // black { 0xAC, 0x12, 0x4C }, // magenta { 0x00, 0x07, 0x83 }, // dark blue { 0xAA, 0x1A, 0xD1 }, // purple { 0x00, 0x83, 0x2F }, // dark green { 0x9F, 0x97, 0x7E }, // drak grey { 0x00, 0x8A, 0xB5 }, // medium blue { 0x9F, 0x9E, 0xFF }, // light blue { 0x7A, 0x5F, 0x00 }, // brown { 0xFF, 0x72, 0x47 }, // orange { 0x78, 0x68, 0x7F }, // light gray { 0xFF, 0x7A, 0xCF }, // pink { 0x6F, 0xE6, 0x2C }, // green { 0xFF, 0xF6, 0x7B }, // yellow { 0x6C, 0xEE, 0xB2 }, // aqua { 0xFF, 0xFF, 0xFF } // white }; SDLDisplay::SDLDisplay() { memset(videoBuffer, 0, sizeof(videoBuffer)); // FIXME: abstract constants screen = SDL_CreateWindow("Aiie!", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SDLDISPLAY_WIDTH, SDLDISPLAY_HEIGHT, SDL_WINDOW_SHOWN); // SDL_RENDERER_SOFTWARE because, at least on my Mac, this has some // serious issues with hardware accelerated drawing (flashing and crashing). renderer = SDL_CreateRenderer(screen, -1, SDL_RENDERER_SOFTWARE); SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); // set to white SDL_RenderClear(renderer); // clear it to the selected color SDL_RenderPresent(renderer); // perform the render } SDLDisplay::~SDLDisplay() { SDL_Quit(); } void SDLDisplay::flush() { SDL_RenderPresent(renderer); } void SDLDisplay::redraw() { // primarily for the device, where it's in and out of the // bios. Draws the background image. printf("redraw background\n"); g_ui->drawStaticUIElement(UIeOverlay); if (g_vm && g_ui) { // determine whether or not a disk is inserted & redraw each drive g_ui->drawOnOffUIElement(UIeDisk1_state, ((AppleVM *)g_vm)->DiskName(0)[0] == '\0'); g_ui->drawOnOffUIElement(UIeDisk2_state, ((AppleVM *)g_vm)->DiskName(1)[0] == '\0'); } } // drawImageOfSizeAt will horizontally scale out the image b/c the // images themselves aren't aware of the double resolution. This is an // inconsistency that probably should be addressed. FIXME? void SDLDisplay::drawImageOfSizeAt(const uint8_t *img, uint16_t sizex, uint8_t sizey, uint16_t wherex, uint8_t wherey) { for (uint8_t y=0; y> 8, g = (color & 0x7E0) >> 3, b = (color & 0x1F) << 3; // Pixel-doubling vertically and horizontally, based on scale for (int yoff=0; yoff= 320) break; // FIXME constant - and pre-scaling, b/c that's in drawCharacter } } void SDLDisplay::clrScr(uint8_t coloridx) { const uint8_t *rgbptr = &loresPixelColors[0][0]; if (coloridx <= 16) rgbptr = loresPixelColors[coloridx]; SDL_SetRenderDrawColor(renderer, rgbptr[0], rgbptr[1], rgbptr[2], 255); // select a color SDL_RenderClear(renderer); // clear it to the selected color SDL_RenderPresent(renderer); // perform the render } // This was called with the expectation that it can draw every one of // the 560x192 pixels that could be addressed. The SDLDISPLAY_SCALE is // basically half the X scale - so a 320-pixel-wide screen can show 40 // columns fine, which means that we need to be creative for 80 columns, // which need to be alpha-blended... void SDLDisplay::cachePixel(uint16_t x, uint16_t y, uint8_t color) { if (SDLDISPLAY_SCALE == 1) { // we need to alpha blend the X because there aren't enough screen pixels. // This takes advantage of the fact that we always call this linearly // for the 80-column text -- we never (?) do partial screen blits, but // always wind up redrawing the entirety. So we can look at the pixel in // the "shared" cell of RAM, and come up with a color between the two. if (x&1) { uint8_t origColor = videoBuffer[(y*SDLDISPLAY_SCALE)*SDLDISPLAY_WIDTH+(x>>1)*SDLDISPLAY_SCALE]; uint8_t newColor = (uint16_t) (origColor + color) / 2; cacheDoubleWidePixel(x>>1,y,newColor); // Else if it's black, we leave whatever was in the other pixel. } else { // The even pixels always draw. cacheDoubleWidePixel(x>>1,y,color); } } else { // we have enough resolution to show all the pixels, so just do it x = (x * SDLDISPLAY_SCALE)/2; for (int yoff=0; yoff