log("Error offscreen CreateSurface %08x\n", hret);
winlog("Error offscreen CreateSurface %08x\n", hret);
BOOL initDirectDraw(){  sizeX = 240;  sizeY = 160;  switch(videoOption) {  case VIDEO_1X:    surfaceSizeX = sizeX;    surfaceSizeY = sizeY;    break;  case VIDEO_2X:    surfaceSizeX = sizeX * 2;    surfaceSizeY = sizeY * 2;    break;  case VIDEO_3X:    surfaceSizeX = sizeX * 3;    surfaceSizeY = sizeY * 3;    break;  case VIDEO_4X:    surfaceSizeX = sizeX * 4;    surfaceSizeY = sizeY * 4;    break;  case VIDEO_320x240:  case VIDEO_640x480:  case VIDEO_800x600:  case VIDEO_OTHER:    {      int scaleX = (fsWidth / sizeX);      int scaleY = (fsHeight / sizeY);      int min = scaleX < scaleY ? scaleX : scaleY;      surfaceSizeX = sizeX * min;      surfaceSizeY = sizeY * min;      if(fullScreenStretch) {        surfaceSizeX = fsWidth;        surfaceSizeY = fsHeight;      }    }    break;  }    rect.left = 0;  rect.top = 0;  rect.right = sizeX;  rect.bottom = sizeY;  dest.left = 0;  dest.top = 0;  dest.right = surfaceSizeX;  dest.bottom = surfaceSizeY;  DWORD style = WS_POPUP | WS_VISIBLE;  DWORD styleEx = 0;    if(videoOption <= VIDEO_4X)    style |= WS_OVERLAPPEDWINDOW;  else    styleEx = WS_EX_TOPMOST;  if(videoOption <= VIDEO_4X)    AdjustWindowRectEx(&dest, style, TRUE, styleEx);  else    AdjustWindowRectEx(&dest, style, FALSE, styleEx);      int winSizeX = dest.right-dest.left;  int winSizeY = dest.bottom-dest.top;  int x = 0;  int y = 0;  if(videoOption <= VIDEO_4X) {    x = windowPositionX;    y = windowPositionY;  }    // Create a window  hWindow = CreateWindowEx(styleEx,                           "GBA",                           "VisualBoyAdvance",                           style,                           x,                           y,                           winSizeX,                           winSizeY,                           NULL,                           NULL,                           hInstance,                           NULL);    if (!hWindow) {    log("Error creating Window %08x\n", GetLastError());    //    errorMessage(myLoadString(IDS_ERROR_DISP_FAILED));    return FALSE;  }    ShowWindow(hWindow, nCmdShow);  UpdateWindow(hWindow);  SetFocus(hWindow);  updateMenuBar();    adjustDestRect();    GUID *guid = NULL;  if(ddrawEmulationOnly)    guid = (GUID *)DDCREATE_EMULATIONONLY;  ddrawDLL = LoadLibrary("DDRAW.DLL");  HRESULT (WINAPI *DDrawCreateEx)(GUID *,LPVOID *,REFIID,IUnknown *);    if(ddrawDLL != NULL) {        DDrawCreateEx = (HRESULT (WINAPI *)(GUID *,LPVOID *,REFIID,IUnknown *))      GetProcAddress(ddrawDLL, "DirectDrawCreateEx");    if(DDrawCreateEx == NULL) {      directXMessage("DirectDrawCreateEx");      return FALSE;    }  } else {    directXMessage("DDRAW.DLL");    return FALSE;  }    HRESULT hret = DDrawCreateEx(guid,                               (void **)&pDirectDraw,                               IID_IDirectDraw7,                               NULL);      if(hret != DD_OK) {    log("Error creating DirectDraw object %08x\n", hret);    if(ddrawEmulationOnly) {      // disable emulation only setting in case of failure      regSetDwordValue("ddrawEmulationOnly", 0);    }    //    errorMessage(myLoadString(IDS_ERROR_DISP_DRAWCREATE), hret);    return FALSE;  }  mode320Available = FALSE;  mode640Available = FALSE;  mode800Available = FALSE;  // check for available fullscreen modes  pDirectDraw->EnumDisplayModes(DDEDM_STANDARDVGAMODES, NULL, NULL,                                checkModesAvailable);    DWORD flags = DDSCL_NORMAL;  if(videoOption >= VIDEO_320x240)    flags = DDSCL_ALLOWMODEX |      DDSCL_ALLOWREBOOT |      DDSCL_EXCLUSIVE |      DDSCL_FULLSCREEN;    hret = pDirectDraw->SetCooperativeLevel(hWindow,                                            flags);  if(hret != DD_OK) {    log("Error SetCooperativeLevel %08x\n", hret);        //    errorMessage(myLoadString(IDS_ERROR_DISP_DRAWLEVEL), hret);    return FALSE;  }    if(videoOption > VIDEO_4X) {    hret = pDirectDraw->SetDisplayMode(fsWidth,                                       fsHeight,                                       fsColorDepth,                                       0,                                       0);    if(hret != DD_OK) {      videoOption = VIDEO_1X;      regSetDwordValue("video", videoOption);      //      errorMessage(myLoadString(IDS_ERROR_DISP_DRAWSET), hret);      return FALSE;    }  }    DDSURFACEDESC2 ddsd;  ZeroMemory(&ddsd,sizeof(ddsd));  ddsd.dwSize = sizeof(ddsd);  ddsd.dwFlags = DDSD_CAPS;  ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;  if(videoOption > VIDEO_4X) {    if(tripleBuffering) {      // setup triple buffering      ddsd.dwFlags |= DDSD_BACKBUFFERCOUNT;      ddsd.ddsCaps.dwCaps |= DDSCAPS_COMPLEX | DDSCAPS_FLIP;      ddsd.dwBackBufferCount = 2;    }  }    hret = pDirectDraw->CreateSurface(&ddsd, &ddsPrimary, NULL);  if(hret != DD_OK) {    log("Error primary CreateSurface %08x\n", hret);        //    errorMessage(myLoadString(IDS_ERROR_DISP_DRAWSURFACE), hret);    return FALSE;  }  if(videoOption > VIDEO_4X && tripleBuffering) {    DDSCAPS2 caps;    ZeroMemory(&caps, sizeof(caps));    // this gets the third surface. The front one is the primary,    // the second is the backbuffer and the third is the flip    // surface    caps.dwCaps = DDSCAPS_BACKBUFFER;        hret = ddsPrimary->GetAttachedSurface(&caps, &ddsFlip);    if(hret != DD_OK) {      systemMessage(0, "Failed to get attached surface %08x", hret);      return FALSE;    }    winClearFlipSurfaces();  }  // create clipper in all modes to avoid paint problems  //  if(videoOption <= VIDEO_4X) {    hret = pDirectDraw->CreateClipper(0, &ddsClipper, NULL);    if(hret == DD_OK) {      ddsClipper->SetHWnd(0, hWindow);      if(videoOption > VIDEO_4X) {        if(tripleBuffering)          ddsFlip->SetClipper(ddsClipper);        else          ddsPrimary->SetClipper(ddsClipper);      } else        ddsPrimary->SetClipper(ddsClipper);    }    //  }  ZeroMemory(&ddsd, sizeof(ddsd));  ddsd.dwSize = sizeof(ddsd);  ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;  ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;  if(ddrawUseVideoMemory)    ddsd.ddsCaps.dwCaps |= (DDSCAPS_LOCALVIDMEM|DDSCAPS_VIDEOMEMORY);  if(videoOption == VIDEO_320x240) {    ddsd.dwWidth = 320;    ddsd.dwHeight = 240;  } else {    ddsd.dwWidth = 256*2; //240;      ddsd.dwHeight = 240*2; //160;  }  hret = pDirectDraw->CreateSurface(&ddsd, &ddsOffscreen, NULL);  if(hret != DD_OK) {    log("Error offscreen CreateSurface %08x\n", hret);        if(ddrawUseVideoMemory) {      regSetDwordValue("ddrawUseVideoMemory", 0);    }        //    errorMessage(myLoadString(IDS_ERROR_DISP_DRAWSURFACE2), hret);    return FALSE;  }    ZeroMemory(&ddsd, sizeof(ddsd));  ddsd.dwSize = sizeof(ddsd);    hret = ddsOffscreen->GetSurfaceDesc(&ddsd);    DDPIXELFORMAT px;  px.dwSize = sizeof(px);  hret = ddsOffscreen->GetPixelFormat(&px);  switch(px.dwRGBBitCount) {  case 15:  case 16:    systemColorDepth = 16;    break;  case 24:    systemColorDepth = 24;    filterFunction = NULL;    break;  case 32:    systemColorDepth = 32;    break;  default:    systemMessage(IDS_ERROR_DISP_COLOR, "Unsupported display setting for color depth: %d bits. \nWindows desktop must be in either 16-bit, 24-bit or 32-bit mode for this program to work in window mode.",px.dwRGBBitCount);    return FALSE;  }  systemRedShift = ffs(px.dwRBitMask);  systemGreenShift = ffs(px.dwGBitMask);  systemBlueShift = ffs(px.dwBBitMask);#ifdef MMX  if(!disableMMX)    cpu_mmx = detectMMX();  else    cpu_mmx = 0;#endif    if((px.dwFlags&DDPF_RGB) != 0 &&     px.dwRBitMask == 0xF800 &&     px.dwGBitMask == 0x07E0 &&     px.dwBBitMask == 0x001F) {    systemGreenShift++;    Init_2xSaI(565);    RGB_LOW_BITS_MASK=0x821;  } else if((px.dwFlags&DDPF_RGB) != 0 &&            px.dwRBitMask == 0x7C00 &&            px.dwGBitMask == 0x03E0 &&            px.dwBBitMask == 0x001F) {    Init_2xSaI(555);    RGB_LOW_BITS_MASK=0x421;  } else if((px.dwFlags&DDPF_RGB) != 0 &&            px.dwRBitMask == 0x001F &&            px.dwGBitMask == 0x07E0 &&            px.dwBBitMask == 0xF800) {    systemGreenShift++;    Init_2xSaI(565);    RGB_LOW_BITS_MASK=0x821;  } else if((px.dwFlags&DDPF_RGB) != 0 &&            px.dwRBitMask == 0x001F &&            px.dwGBitMask == 0x03E0 &&            px.dwBBitMask == 0x7C00) {    Init_2xSaI(555);    RGB_LOW_BITS_MASK=0x421;  } else {    // 32-bit or 24-bit    if(systemColorDepth == 32 || systemColorDepth == 24) {      systemRedShift += 3;      systemGreenShift += 3;      systemBlueShift += 3;      if(systemColorDepth == 32)        Init_2xSaI(32);    }  }  switch(systemColorDepth) {  case 16:    {      for(int i = 0; i < 0x10000; i++) {        systemColorMap16[i] = ((i & 0x1f) << systemRedShift) |          (((i & 0x3e0) >> 5) << systemGreenShift) |          (((i & 0x7c00) >> 10) << systemBlueShift);      }    }    break;  case 24:  case 32:    {      for(int i = 0; i < 0x10000; i++) {        systemColorMap32[i] = ((i & 0x1f) << systemRedShift) |          (((i & 0x3e0) >> 5) << systemGreenShift) |          (((i & 0x7c00) >> 10) << systemBlueShift);      }          }    break;  }  for(int i = 0; i < 24;) {    systemGbPalette[i++] = (0x1f) | (0x1f << 5) | (0x1f << 10);    systemGbPalette[i++] = (0x15) | (0x15 << 5) | (0x15 << 10);    systemGbPalette[i++] = (0x0c) | (0x0c << 5) | (0x0c << 10);    systemGbPalette[i++] = 0;  }  updateFilter();  updateIFB();    DragAcceptFiles(hWindow, TRUE);    return TRUE;}