utilUpdateSystemColorMaps();
int main(int argc, char **argv){  fprintf(stderr, "VisualBoyAdvance version %s [SDL]\n", VERSION);  arg0 = argv[0];    captureDir[0] = 0;  saveDir[0] = 0;  batteryDir[0] = 0;  ipsname[0] = 0;    int op = -1;  frameSkip = 2;  gbBorderOn = 0;  parseDebug = true;  sdlReadPreferences();  sdlPrintUsage = 0;    while((op = getopt_long(argc,                          argv,                          "FNT:Y:G:D:b:c:df:hi:p::s:t:v:1234",                          sdlOptions,                          NULL)) != -1) {    switch(op) {    case 0:      // long option already processed by getopt_long      break;    case 'b':      useBios = true;      if(optarg == NULL) {        fprintf(stderr, "Missing BIOS file name\n");        exit(-1);      }      strcpy(biosFileName, optarg);      break;    case 'c':      {        if(optarg == NULL) {          fprintf(stderr, "Missing config file name\n");          exit(-1);        }        FILE *f = fopen(optarg, "r");        if(f == NULL) {          fprintf(stderr, "File not found %s\n", optarg);          exit(-1);        }        sdlReadPreferences(f);        fclose(f);      }      break;    case 'd':      debugger = true;      break;    case 'h':      sdlPrintUsage = 1;      break;    case 'i':      if(optarg == NULL) {        fprintf(stderr, "Missing IPS name\n");        exit(-1);        strcpy(ipsname, optarg);      }      break;    case 'Y':      yuv = true;      if(optarg) {        yuvType = atoi(optarg);        switch(yuvType) {        case 0:          yuvType = SDL_YV12_OVERLAY;          break;        case 1:          yuvType = SDL_UYVY_OVERLAY;          break;        case 2:          yuvType = SDL_YVYU_OVERLAY;          break;        case 3:          yuvType = SDL_YUY2_OVERLAY;          break;        case 4:          yuvType = SDL_IYUV_OVERLAY;          break;        default:          yuvType = SDL_YV12_OVERLAY;        }      } else        yuvType = SDL_YV12_OVERLAY;      break;    case 'G':      dbgMain = remoteStubMain;      dbgSignal = remoteStubSignal;      dbgOutput = remoteOutput;      debugger = true;      debuggerStub = true;      if(optarg) {        char *s = optarg;        if(strncmp(s,"tcp:", 4) == 0) {          s+=4;          int port = atoi(s);          remoteSetProtocol(0);          remoteSetPort(port);        } else if(strcmp(s,"tcp") == 0) {          remoteSetProtocol(0);        } else if(strcmp(s, "pipe") == 0) {          remoteSetProtocol(1);        } else {          fprintf(stderr, "Unknown protocol %s\n", s);          exit(-1);        }      } else {        remoteSetProtocol(0);      }      break;    case 'N':      parseDebug = false;      break;    case 'D':      if(optarg) {        systemDebug = atoi(optarg);      } else {        systemDebug = 1;      }      break;    case 'F':      fullscreen = 1;      mouseCounter = 120;      break;    case 'f':      if(optarg) {        filter = atoi(optarg);      } else {        filter = 0;      }      break;    case 'p':#ifdef PROFILING      if(optarg) {        cpuEnableProfiling(atoi(optarg));      } else        cpuEnableProfiling(100);#endif      break;    case 'S':      sdlFlashSize = atoi(optarg);      if(sdlFlashSize < 0 || sdlFlashSize > 1)        sdlFlashSize = 0;      break;    case 's':      if(optarg) {        int a = atoi(optarg);        if(a >= 0 && a <= 9) {          gbFrameSkip = a;          frameSkip = a;        }      } else {        frameSkip = 2;        gbFrameSkip = 0;      }      break;    case 't':      if(optarg) {        int a = atoi(optarg);        if(a < 0 || a > 5)          a = 0;        cpuSaveType = a;      }      break;    case 'T':      if(optarg) {        int t = atoi(optarg);        if(t < 5 || t > 1000)          t = 0;        throttle = t;      }      break;    case 'v':      if(optarg) {        systemVerbose = atoi(optarg);      } else         systemVerbose = 0;      break;    case '1':      sizeOption = 0;      break;    case '2':      sizeOption = 1;      break;    case '3':      sizeOption = 2;      break;    case '4':      sizeOption = 3;      break;    case '?':      sdlPrintUsage = 1;      break;    }  }  if(sdlPrintUsage) {    usage(argv[0]);    exit(-1);  }#ifdef MMX  if(disableMMX)    cpu_mmx = 0;#endif  if(rewindTimer)    rewindMemory = (char *)malloc(8*REWIND_SIZE);  if(sdlFlashSize == 0)    flashSetSize(0x10000);  else    flashSetSize(0x20000);  rtcEnable(sdlRtcEnable ? true : false);  agbPrintEnable(sdlAgbPrint ? true : false);    if(!debuggerStub) {    if(optind >= argc) {      systemMessage(0,"Missing image name");      usage(argv[0]);      exit(-1);    }  }  if(filter) {    sizeOption = 1;  }  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;  }  systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;  if(optind < argc) {    char *szFile = argv[optind];    utilGetBaseName(szFile, filename);    char *p = strrchr(filename, '.');    if(p)      *p = 0;    if(ipsname[0] == 0)      sprintf(ipsname, "%s.ips", filename);        bool failed = false;    IMAGE_TYPE type = utilFindType(szFile);    if(type == IMAGE_UNKNOWN) {      systemMessage(0, "Unknown file type %s", szFile);      exit(-1);    }    cartridgeType = (int)type;        if(type == IMAGE_GB) {      failed = !gbLoadRom(szFile);      if(!failed) {        cartridgeType = 1;        emulator = GBSystem;        if(sdlAutoIPS) {          int size = gbRomSize;          utilApplyIPS(ipsname, &gbRom, &size);          if(size != gbRomSize) {            extern bool gbUpdateSizes();            gbUpdateSizes();            gbReset();          }        }      }    } else if(type == IMAGE_GBA) {      int size = CPULoadRom(szFile);      failed = (size == 0);      if(!failed) {        //        if(cpuEnhancedDetection && cpuSaveType == 0) {        //          utilGBAFindSave(rom, size);        //        }        sdlApplyPerImagePreferences();                cartridgeType = 0;        emulator = GBASystem;        /* disabled due to problems        if(removeIntros && rom != NULL) {          WRITE32LE(&rom[0], 0xea00002e);        }        */                CPUInit(biosFileName, useBios);        CPUReset();        if(sdlAutoIPS) {          int size = 0x2000000;          utilApplyIPS(ipsname, &rom, &size);          if(size != 0x2000000) {            CPUReset();          }        }      }    }        if(failed) {      systemMessage(0, "Failed to load file %s", szFile);      exit(-1);    }  } else {    cartridgeType = 0;    strcpy(filename, "gnu_stub");    rom = (u8 *)malloc(0x2000000);    workRAM = (u8 *)calloc(1, 0x40000);    bios = (u8 *)calloc(1,0x4000);    internalRAM = (u8 *)calloc(1,0x8000);    paletteRAM = (u8 *)calloc(1,0x400);    vram = (u8 *)calloc(1, 0x20000);    oam = (u8 *)calloc(1, 0x400);    pix = (u8 *)calloc(1, 4 * 240 * 160);    ioMem = (u8 *)calloc(1, 0x400);    emulator = GBASystem;        CPUInit(biosFileName, useBios);    CPUReset();      }    sdlReadBattery();    if(debuggerStub)     remoteInit();    int flags = SDL_INIT_VIDEO|SDL_INIT_AUDIO|    SDL_INIT_TIMER|SDL_INIT_NOPARACHUTE;  if(soundOffFlag)    flags ^= SDL_INIT_AUDIO;    if(SDL_Init(flags)) {    systemMessage(0, "Failed to init SDL: %s", SDL_GetError());    exit(-1);  }  if(SDL_InitSubSystem(SDL_INIT_JOYSTICK)) {    systemMessage(0, "Failed to init joystick support: %s", SDL_GetError());  }    sdlCheckKeys();    if(cartridgeType == 0) {    srcWidth = 240;    srcHeight = 160;    systemFrameSkip = frameSkip;  } else if (cartridgeType == 1) {    if(gbBorderOn) {      srcWidth = 256;      srcHeight = 224;      gbBorderLineSkip = 256;      gbBorderColumnSkip = 48;      gbBorderRowSkip = 40;    } else {            srcWidth = 160;      srcHeight = 144;      gbBorderLineSkip = 160;      gbBorderColumnSkip = 0;      gbBorderRowSkip = 0;    }    systemFrameSkip = gbFrameSkip;  } else {    srcWidth = 320;    srcHeight = 240;  }    destWidth = (sizeOption+1)*srcWidth;  destHeight = (sizeOption+1)*srcHeight;    surface = SDL_SetVideoMode(destWidth, destHeight, 16,                             SDL_ANYFORMAT|SDL_HWSURFACE|SDL_DOUBLEBUF|                             (fullscreen ? SDL_FULLSCREEN : 0));    if(surface == NULL) {    systemMessage(0, "Failed to set video mode");    SDL_Quit();    exit(-1);  }    systemRedShift = sdlCalculateShift(surface->format->Rmask);  systemGreenShift = sdlCalculateShift(surface->format->Gmask);  systemBlueShift = sdlCalculateShift(surface->format->Bmask);    systemColorDepth = surface->format->BitsPerPixel;  if(systemColorDepth == 15)    systemColorDepth = 16;  if(yuv) {    Init_Overlay(surface, yuvType);    systemColorDepth = 32;    systemRedShift = 3;    systemGreenShift = 11;    systemBlueShift =  19;  }    if(systemColorDepth != 16 && systemColorDepth != 24 &&     systemColorDepth != 32) {    fprintf(stderr,"Unsupported color depth '%d'.\nOnly 16, 24 and 32 bit color depths are supported\n", systemColorDepth);    exit(-1);  }#ifndef C_CORE  sdlMakeStretcher(srcWidth);#else  switch(systemColorDepth) {  case 16:    sdlStretcher = sdlStretcher16[sizeOption];    break;  case 24:    sdlStretcher = sdlStretcher24[sizeOption];    break;  case 32:    sdlStretcher = sdlStretcher32[sizeOption];    break;  default:    fprintf(stderr, "Unsupported resolution: %d\n", systemColorDepth);    exit(-1);  }#endif  fprintf(stderr,"Color depth: %d\n", systemColorDepth);    if(systemColorDepth == 16) {    if(sdlCalculateMaskWidth(surface->format->Gmask) == 6) {      Init_2xSaI(565);      RGB_LOW_BITS_MASK = 0x821;    } else {      Init_2xSaI(555);      RGB_LOW_BITS_MASK = 0x421;          }    if(cartridgeType == 2) {      for(int i = 0; i < 0x10000; i++) {        systemColorMap16[i] = (((i >> 1) & 0x1f) << systemBlueShift) |          (((i & 0x7c0) >> 6) << systemGreenShift) |          (((i & 0xf800) >> 11) << systemRedShift);        }          } else {      for(int i = 0; i < 0x10000; i++) {        systemColorMap16[i] = ((i & 0x1f) << systemRedShift) |          (((i & 0x3e0) >> 5) << systemGreenShift) |          (((i & 0x7c00) >> 10) << systemBlueShift);        }    }    srcPitch = srcWidth * 2+4;  } else {    if(systemColorDepth != 32)      filterFunction = NULL;    RGB_LOW_BITS_MASK = 0x010101;    if(systemColorDepth == 32) {      Init_2xSaI(32);    }    for(int i = 0; i < 0x10000; i++) {      systemColorMap32[i] = ((i & 0x1f) << systemRedShift) |        (((i & 0x3e0) >> 5) << systemGreenShift) |        (((i & 0x7c00) >> 10) << systemBlueShift);      }    if(systemColorDepth == 32)      srcPitch = srcWidth*4 + 4;    else      srcPitch = srcWidth*3;  }  if(systemColorDepth != 32) {    switch(filter) {    case 0:      filterFunction = NULL;      break;    case 1:      filterFunction = ScanlinesTV;      break;    case 2:      filterFunction = _2xSaI;      break;    case 3:      filterFunction = Super2xSaI;      break;    case 4:      filterFunction = SuperEagle;      break;    case 5:      filterFunction = Pixelate;      break;    case 6:      filterFunction = MotionBlur;      break;    case 7:      filterFunction = AdMame2x;      break;    case 8:      filterFunction = Simple2x;      break;    case 9:      filterFunction = Bilinear;      break;    case 10:      filterFunction = BilinearPlus;      break;    case 11:      filterFunction = Scanlines;      break;    case 12:      filterFunction = hq2x;      break;    case 13:      filterFunction = lq2x;      break;    default:      filterFunction = NULL;      break;    }  } else {    switch(filter) {    case 0:      filterFunction = NULL;      break;    case 1:      filterFunction = ScanlinesTV32;      break;    case 2:      filterFunction = _2xSaI32;      break;    case 3:      filterFunction = Super2xSaI32;      break;    case 4:      filterFunction = SuperEagle32;      break;    case 5:      filterFunction = Pixelate32;      break;    case 6:      filterFunction = MotionBlur32;      break;    case 7:      filterFunction = AdMame2x32;      break;    case 8:      filterFunction = Simple2x32;      break;    case 9:      filterFunction = Bilinear32;      break;    case 10:      filterFunction = BilinearPlus32;      break;    case 11:      filterFunction = Scanlines32;      break;    case 12:      filterFunction = hq2x32;      break;    case 13:      filterFunction = lq2x32;      break;    default:      filterFunction = NULL;      break;    }  }    if(systemColorDepth == 16) {    switch(ifbType) {    case 0:    default:      ifbFunction = NULL;      break;    case 1:      ifbFunction = MotionBlurIB;      break;    case 2:      ifbFunction = SmartIB;      break;    }  } else if(systemColorDepth == 32) {    switch(ifbType) {    case 0:    default:      ifbFunction = NULL;      break;    case 1:      ifbFunction = MotionBlurIB32;      break;    case 2:      ifbFunction = SmartIB32;      break;    }  } else    ifbFunction = NULL;  if(delta == NULL) {    delta = (u8*)malloc(322*242*4);    memset(delta, 255, 322*242*4);  }    emulating = 1;  renderedFrames = 0;  if(!soundOffFlag)    soundInit();  autoFrameSkipLastTime = throttleLastTime = systemGetClock();    SDL_WM_SetCaption("VisualBoyAdvance", NULL);  while(emulating) {    if(!paused && active) {      if(debugger && emulator.emuHasDebugger)        dbgMain();      else {        emulator.emuMain(emulator.emuCount);        if(rewindSaveNeeded && rewindMemory && emulator.emuWriteMemState) {          rewindCount++;          if(rewindCount > 8)            rewindCount = 8;          if(emulator.emuWriteMemState &&             emulator.emuWriteMemState(&rewindMemory[rewindPos*REWIND_SIZE],                                        REWIND_SIZE)) {            rewindPos = ++rewindPos & 7;            if(rewindCount == 8)              rewindTopPos = ++rewindTopPos & 7;          }        }        rewindSaveNeeded = false;      }    } else {      SDL_Delay(500);    }    sdlPollEvents();    if(mouseCounter) {      mouseCounter--;      if(mouseCounter == 0)        SDL_ShowCursor(SDL_DISABLE);    }  }    emulating = 0;  fprintf(stderr,"Shutting down\n");  remoteCleanUp();  soundShutdown();  if(gbRom != NULL || rom != NULL) {    sdlWriteBattery();    emulator.emuCleanUp();  }  if(delta) {    free(delta);    delta = NULL;  }    SDL_Quit();  return 0;}