const char *GenerateEncodingShader(u32 format,API_TYPE ApiType)
{
#ifndef ANDROID
	locale_t locale = newlocale(LC_NUMERIC_MASK, "C", NULL); // New locale for compilation
	locale_t old_locale = uselocale(locale); // Apply the locale for this thread
#endif
	text[sizeof(text) - 1] = 0x7C;  // canary

	char *p = text;

	switch (format)
	{
	case GX_TF_I4:
		WriteI4Encoder(p, ApiType);
		break;
	case GX_TF_I8:
		WriteI8Encoder(p, ApiType);
		break;
	case GX_TF_IA4:
		WriteIA4Encoder(p, ApiType);
		break;
	case GX_TF_IA8:
		WriteIA8Encoder(p, ApiType);
		break;
	case GX_TF_RGB565:
		WriteRGB565Encoder(p, ApiType);
		break;
	case GX_TF_RGB5A3:
		WriteRGB5A3Encoder(p, ApiType);
		break;
	case GX_TF_RGBA8:
		WriteRGBA8Encoder(p, ApiType);
		break;
	case GX_CTF_R4:
		WriteC4Encoder(p, "r", ApiType);
		break;
	case GX_CTF_RA4:
		WriteCC4Encoder(p, "ar", ApiType);
		break;
	case GX_CTF_RA8:
		WriteCC8Encoder(p, "ar", ApiType);
		break;
	case GX_CTF_A8:
		WriteC8Encoder(p, "a", ApiType);
		break;
	case GX_CTF_R8:
		WriteC8Encoder(p, "r", ApiType);
		break;
	case GX_CTF_G8:
		WriteC8Encoder(p, "g", ApiType);
		break;
	case GX_CTF_B8:
		WriteC8Encoder(p, "b", ApiType);
		break;
	case GX_CTF_RG8:
		WriteCC8Encoder(p, "rg", ApiType);
		break;
	case GX_CTF_GB8:
		WriteCC8Encoder(p, "gb", ApiType);
		break;
	case GX_TF_Z8:
		WriteC8Encoder(p, "b", ApiType);
		break;
	case GX_TF_Z16:
		WriteZ16Encoder(p, ApiType);
		break;
	case GX_TF_Z24X8:
		WriteZ24Encoder(p, ApiType);
		break;
	case GX_CTF_Z4:
		WriteC4Encoder(p, "b", ApiType);
		break;
	case GX_CTF_Z8M:
		WriteZ8Encoder(p, "256.0", ApiType);
		break;
	case GX_CTF_Z8L:
		WriteZ8Encoder(p, "65536.0" , ApiType);
		break;
	case GX_CTF_Z16L:
		WriteZ16LEncoder(p, ApiType);
		break;
	default:
		PanicAlert("Unknown texture copy format: 0x%x\n", format);
		break;
	}

	if (text[sizeof(text) - 1] != 0x7C)
		PanicAlert("TextureConversionShader generator - buffer too small, canary has been eaten!");

#ifndef ANDROID
	uselocale(old_locale); // restore locale
	freelocale(locale);
#endif
	return text;
}
const char *GenerateEncodingShader(u32 format,API_TYPE ApiType)
{
	text[sizeof(text) - 1] = 0x7C;  // canary

	char *p = text;

	switch (format)
	{
	case GX_TF_I4:
		WriteI4Encoder(p, ApiType);
		break;
	case GX_TF_I8:
		WriteI8Encoder(p, ApiType);
		break;
	case GX_TF_IA4:
		WriteIA4Encoder(p, ApiType);
		break;
	case GX_TF_IA8:
		WriteIA8Encoder(p, ApiType);
		break;
	case GX_TF_RGB565:
		WriteRGB565Encoder(p, ApiType);
		break;
	case GX_TF_RGB5A3:
		WriteRGB5A3Encoder(p, ApiType);
		break;
	case GX_TF_RGBA8:
		WriteRGBA8Encoder(p, ApiType);
		break;
	case GX_CTF_R4:
		WriteC4Encoder(p, "r", ApiType);
		break;
	case GX_CTF_RA4:
		WriteCC4Encoder(p, "ar", ApiType);
		break;
	case GX_CTF_RA8:
		WriteCC8Encoder(p, "ar", ApiType);
		break;
	case GX_CTF_A8:
		WriteC8Encoder(p, "a", ApiType);
		break;
	case GX_CTF_R8:
		WriteC8Encoder(p, "r", ApiType);
		break;
	case GX_CTF_G8:
		WriteC8Encoder(p, "g", ApiType);
		break;
	case GX_CTF_B8:
		WriteC8Encoder(p, "b", ApiType);
		break;
	case GX_CTF_RG8:
		WriteCC8Encoder(p, "rg", ApiType);
		break;
	case GX_CTF_GB8:
		WriteCC8Encoder(p, "gb", ApiType);
		break;
	case GX_TF_Z8:
		WriteC8Encoder(p, "b", ApiType);
		break;
	case GX_TF_Z16:
		WriteZ16Encoder(p, ApiType);
		break;
	case GX_TF_Z24X8:
		WriteZ24Encoder(p, ApiType);
		break;
	case GX_CTF_Z4:
		WriteC4Encoder(p, "b", ApiType);
		break;
	case GX_CTF_Z8M:
		WriteZ8Encoder(p, "256.0", ApiType);
		break;
	case GX_CTF_Z8L:
		WriteZ8Encoder(p, "65536.0" , ApiType);
		break;
	case GX_CTF_Z16L:
		WriteZ16LEncoder(p, ApiType);
		break;
	default:
		PanicAlert("Unknown texture copy format: 0x%x\n", format);
		break;
	}

	if (text[sizeof(text) - 1] != 0x7C)
		PanicAlert("TextureConversionShader generator - buffer too small, canary has been eaten!");

	return text;
}
const char* GenerateEncodingShader(const EFBCopyParams& params, APIType api_type)
{
  text[sizeof(text) - 1] = 0x7C;  // canary

  char* p = text;

  switch (params.copy_format)
  {
  case EFBCopyFormat::R4:
    if (params.yuv)
      WriteI4Encoder(p, api_type, params);
    else
      WriteC4Encoder(p, "r", api_type, params);
    break;
  case EFBCopyFormat::RA4:
    if (params.yuv)
      WriteIA4Encoder(p, api_type, params);
    else
      WriteCC4Encoder(p, "ar", api_type, params);
    break;
  case EFBCopyFormat::RA8:
    if (params.yuv)
      WriteIA8Encoder(p, api_type, params);
    else
      WriteCC8Encoder(p, "ar", api_type, params);
    break;
  case EFBCopyFormat::RGB565:
    WriteRGB565Encoder(p, api_type, params);
    break;
  case EFBCopyFormat::RGB5A3:
    WriteRGB5A3Encoder(p, api_type, params);
    break;
  case EFBCopyFormat::RGBA8:
    if (params.depth)
      WriteZ24Encoder(p, api_type, params);
    else
      WriteRGBA8Encoder(p, api_type, params);
    break;
  case EFBCopyFormat::A8:
    WriteC8Encoder(p, "a", api_type, params);
    break;
  case EFBCopyFormat::R8_0x1:
  case EFBCopyFormat::R8:
    if (params.yuv)
      WriteI8Encoder(p, api_type, params);
    else
      WriteC8Encoder(p, "r", api_type, params);
    break;
  case EFBCopyFormat::G8:
    if (params.depth)
      WriteZ8Encoder(p, "256.0", api_type, params);  // Z8M
    else
      WriteC8Encoder(p, "g", api_type, params);
    break;
  case EFBCopyFormat::B8:
    if (params.depth)
      WriteZ8Encoder(p, "65536.0", api_type, params);  // Z8L
    else
      WriteC8Encoder(p, "b", api_type, params);
    break;
  case EFBCopyFormat::RG8:
    if (params.depth)
      WriteZ16Encoder(p, api_type, params);  // Z16H
    else
      WriteCC8Encoder(p, "rg", api_type, params);
    break;
  case EFBCopyFormat::GB8:
    if (params.depth)
      WriteZ16LEncoder(p, api_type, params);  // Z16L
    else
      WriteCC8Encoder(p, "gb", api_type, params);
    break;
  default:
    PanicAlert("Invalid EFB Copy Format (0x%X)! (GenerateEncodingShader)",
               static_cast<int>(params.copy_format));
    break;
  }

  if (text[sizeof(text) - 1] != 0x7C)
    PanicAlert("TextureConversionShader generator - buffer too small, canary has been eaten!");

  return text;
}