World of Might and Magic  0.2.0
Open reimplementation of Might and Magic 6 7 8 game engine
Файл mm7text_ru.cpp

См. исходные тексты.

Классы

struct  GenderTableEntry
 

Функции

int GetGender (char *ansi_name, int name_len)
 
bool IsSpecialName (const char *ansi_name)
 
int GetSpecialGender (const char *ansi_name)
 
const char * GetSpecialCase (const char *ansi_name, char c)
 
int sprintfex (char *buf, const char *format,...)
 
int sprintfex_internal (char *str)
 

Переменные

struct GenderTableEntry gender_table_caps []
 
struct GenderTableEntry gender_table []
 

Функции

◆ GetGender()

int GetGender ( char *  ansi_name,
int  name_len 
)

См. определение в файле mm7text_ru.cpp строка 553

553  {
554  auto name = (unsigned char *)ansi_name;
555 
556  GenderTableEntry *table = nullptr;
557  unsigned int table_size = 0;
558  if (name[0] >= (unsigned char)'а' && name[0] <= (unsigned char)'я') {
560  table_size = sizeof(gender_table) / sizeof(*gender_table);
561  } else if (name[0] >= (unsigned char)'А' && name[0] <= (unsigned char)'Я') {
563  table_size = sizeof(gender_table_caps) / sizeof(*gender_table_caps);
564  } else {
565  return 0;
566  }
567 
568  int left = 0, right = table_size - 1, match = 0;
569  while (left < right - 1) {
570  match = left + (right - left) / 2;
571  int rval = _mbsncmp(name, (unsigned char *)table[match].name, name_len);
572  if (rval < 0)
573  right = match;
574  else if (!rval)
575  return table[match].gender;
576  else
577  left = match;
578  }
579 
580  logger->Warning(L"sprintfex: unknown gender: %S", name);
581  return 0;
582 }

Перекрестные ссылки gender_table, gender_table_caps, logger и Log::Warning().

Используется в sprintfex_internal().

+ Граф вызовов:
+ Граф вызова функции:

◆ IsSpecialName()

bool IsSpecialName ( const char *  ansi_name)

См. определение в файле mm7text_ru.cpp строка 584

584  {
585  auto name = (unsigned char *)ansi_name;
586  return !_mbsncmp(name, (unsigned char *)"Мэри Джо", 8) ||
587  !_mbsncmp(name, (unsigned char *)"Ли Энн", 6) ||
588  !_mbsncmp(name, (unsigned char *)"Врата в Бездну", 14) ||
589  !_mbsncmp(name, (unsigned char *)"Стены тумана", 12);
590 }

Используется в sprintfex_internal().

+ Граф вызова функции:

◆ GetSpecialGender()

int GetSpecialGender ( const char *  ansi_name)

См. определение в файле mm7text_ru.cpp строка 591

591  {
592  auto name = (unsigned char *)ansi_name;
593  if (!_mbsncmp(name, (unsigned char *)"Мэри Джо", 8)) return 1;
594  if (!_mbsncmp(name, (unsigned char *)"Ли Энн", 6)) return 1;
595  if (!_mbsncmp(name, (unsigned char *)"Врата в Бездну", 14)) return 1;
596  if (!!_mbsncmp(name, (unsigned char *)"Стены тумана", 12)) return 0;
597  return 0;
598 }

Используется в sprintfex_internal().

+ Граф вызова функции:

◆ GetSpecialCase()

const char* GetSpecialCase ( const char *  ansi_name,
char  c 
)

См. определение в файле mm7text_ru.cpp строка 599

599  {
600  auto name = (unsigned char *)ansi_name;
601 
602  if (!_mbsncmp(name, (unsigned char *)"Мэри Джо", 8)) return "Мэри Джо";
603  if (!_mbsncmp(name, (unsigned char *)"Ли Энн", 6)) return "Ли Энн";
604 
605  if (!_mbsncmp(name, (unsigned char *)"Врата в Бездну", 14)) {
606  switch (c) {
607  case 'I':
608  case 'i':
609  return "Врата в Бездну";
610  case 'R':
611  case 'r':
612  return "Врат в Бездну";
613  case 'D':
614  case 'd':
615  return "Вратам в Бездну";
616  case 'V':
617  case 'v':
618  return "Врат в Бездну";
619  case 'T':
620  case 't':
621  return "Вратами в Бездну";
622  case 'P':
623  case 'p':
624  return "Вратах в Бездну";
625  }
626  }
627 
628  if (!_mbsncmp(name, (unsigned char *)"Стены тумана", 12)) {
629  switch (c) {
630  case 'I':
631  case 'i':
632  return "Стены тумана";
633  case 'R':
634  case 'r':
635  return "Стен тумана";
636  case 'D':
637  case 'd':
638  return "Стенам тумана";
639  case 'V':
640  case 'v':
641  return "Стены тумана";
642  case 'T':
643  case 't':
644  return "Стенами тумана";
645  case 'P':
646  case 'p':
647  return "Стенах тумана";
648  }
649  }
650 
651  return nullptr;
652 }

Используется в sprintfex_internal().

+ Граф вызова функции:

◆ sprintfex()

int sprintfex ( char *  buf,
const char *  format,
  ... 
)

См. определение в файле mm7text_ru.cpp строка 654

654  {
655  va_list args_ptr;
656  va_start(args_ptr, format);
657  { vsprintf(buf, format, args_ptr); }
658  va_end(args_ptr);
659 
660  extern int sprintfex_internal(char *buf);
661  return sprintfex_internal(buf);
662 }

Перекрестные ссылки sprintfex_internal().

+ Граф вызовов:

◆ sprintfex_internal()

int sprintfex_internal ( char *  str)

См. определение в файле mm7text_ru.cpp строка 664

664  {
665  auto p = strstr(str, "^");
666  if (!p) return strlen(str);
667 
668  char buf[8192];
669  Assert(strlen(str) < sizeof(buf));
670 
671  int next_integer_token = 0;
672  bool integer_tokens_defined[10] = {false, false, false, false, false,
673  false, false, false, false, false};
674  int integer_tokens[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
675 
676  bool gender_token_defined = false;
677  int gender_token = 0;
678 
679  auto src = buf, dst = p;
680  strcpy(buf, str + (p - str));
681  while (true) {
682  switch (src[1]) {
683  case 'I': {
684  if (src[2] != '[') goto _invalid_token;
685  src += 3; // ^I[
686 
687  Assert(next_integer_token < 10);
688  if (sscanf(src, "%d", &integer_tokens[next_integer_token]))
689  integer_tokens_defined[next_integer_token++] = true;
690 
691  auto int_begin = src;
692  while (*src++ != ']');
693 
694  int int_len = src - int_begin - 1;
695  strncpy(dst, int_begin, int_len);
696  dst += int_len;
697  } break;
698 
699  case 'L': {
700  int integer_token_idx = 0;
701  if (src[2] >= '1' && src[2] <= '9') {
702  if (src[3] != '[') goto _invalid_token;
703  integer_token_idx = src[2] - '1';
704 
705  src += 1;
706  } else if (src[2] != '[') {
707  goto _invalid_token;
708  }
709 
710  Assert(integer_tokens_defined[integer_token_idx]);
711  src += 3; // ^L[
712 
713  auto ending1 = src;
714  while (*src++ != ';');
715  auto ending2 = src;
716  while (*src++ != ';');
717  auto ending3 = src;
718  while (*src++ != ']');
719 
720  char *actual_ending = nullptr;
721  int actual_ending_len = 0;
722 
723  int modulo = abs(integer_tokens[integer_token_idx]) % 10;
724  if (modulo == 1) {
725  actual_ending = ending1;
726  actual_ending_len = ending2 - ending1 - 1;
727  } else if (modulo >= 2 && modulo <= 4) {
728  actual_ending = ending2;
729  actual_ending_len = ending3 - ending2 - 1;
730  } else {
731  actual_ending = ending3;
732  actual_ending_len = src - ending3 - 1;
733  }
734 
735  strncpy(dst, actual_ending, actual_ending_len);
736  dst += actual_ending_len;
737  } break;
738 
739  case 'R': {
740  if (src[2] != '[') goto _invalid_token;
741  Assert(gender_token_defined);
742 
743  src += 3; // ^R[
744 
745  auto ending1 = src;
746  while (*src++ != ';');
747  auto ending2 = src;
748  while (*src++ != ';');
749  auto ending3 = src;
750  while (*src++ != ']');
751 
752  char *actual_ending = nullptr;
753  int actual_ending_len = 0;
754 
755  if (gender_token == 0) {
756  actual_ending = ending1;
757  actual_ending_len = ending2 - ending1 - 1;
758  } else if (gender_token == 1) {
759  actual_ending = ending2;
760  actual_ending_len = ending3 - ending2 - 1;
761  } else if (gender_token == 2) {
762  actual_ending = ending3;
763  actual_ending_len = src - ending3 - 1;
764  } else {
765  Error("Invalid gender token");
766  }
767 
768  strncpy(dst, actual_ending, actual_ending_len);
769  dst += actual_ending_len;
770  } break;
771 
772  case 'P': {
773  if (src[3] != '[') goto _invalid_token;
774  switch (src[2]) {
775  case 'I':
776  case 'i':
777  case 'R':
778  case 'r':
779  case 'D':
780  case 'd':
781  case 'V':
782  case 'v':
783  case 'T':
784  case 't':
785  case 'P':
786  case 'p':
787  break;
788  default:
789  goto _invalid_token;
790  }
791 
792  if (IsSpecialName(src + 4)) {
793  auto name = GetSpecialCase(src + 4, src[2]);
794  int name_len = strlen(name);
795 
796  gender_token = GetSpecialGender(src + 4);
797  gender_token_defined = true;
798 
799  strncpy(dst, name, name_len);
800  dst += name_len;
801  while (*src++ != ']');
802  break;
803  }
804 
805  auto name_begin = src + 4;
806  int name_len = 0;
807  for (int i = 0; name_begin[i] != ']'; ++i) name_len++;
808  gender_token = GetGender(name_begin, name_len);
809  gender_token_defined = true;
810 
811  switch (src[2]) {
812  case 'I':
813  case 'i':
814  case 'V':
815  case 'v':
816  case 'R':
817  case 'r':
818  case 'D':
819  case 'd':
820  case 'T':
821  case 't': {
822  strncpy(dst, name_begin, name_len);
823  dst += name_len;
824  } break;
825 
826  case 'P':
827  case 'p': {
828  auto token_begin = src;
829  int token_len = 1;
830  for (int i = 0; token_begin[i] != ']'; ++i) token_len++;
831  strncpy(dst, token_begin, token_len);
832  dst += token_len;
833  }
834  }
835  while (*src++ != ']');
836  } break;
837 
838  default: {
839  _invalid_token:
840  auto token_begin = src;
841  while (*src++ != ']');
842 
843  int token_len = src - token_begin;
844  char token[1024];
845  strncpy(token, token_begin, token_len);
846  token[token_len] = 0;
847 
848  Error("Invalid format token: %s", token);
849  } break;
850  }
851 
852  *dst = 0;
853 
854  auto copy_begin = src;
855  src = strstr(src, "^");
856  if (!src) {
857  strcpy(dst, copy_begin); // just copy the rest
858  break;
859  }
860 
861  int copy_len = src - copy_begin;
862  strncpy(dst, copy_begin, copy_len);
863  dst += copy_len;
864  }
865 
866  return dst - str;
867 }

Перекрестные ссылки GetGender(), GetSpecialCase(), GetSpecialGender() и IsSpecialName().

Используется в Localization::FormatString() и sprintfex().

+ Граф вызовов:
+ Граф вызова функции:

Переменные

◆ gender_table_caps

struct GenderTableEntry gender_table_caps[]

Используется в GetGender().

◆ gender_table

struct GenderTableEntry gender_table[]
Инициализатор
= {
{"ад", 0}, {"акула", 1}, {"банк", 0}, {"башня", 1},
{"бластер", 0}, {"вампир", 0}, {"вдова", 1}, {"ведьма", 1},
{"витерсмит", 0}, {"владыка", 0}, {"владычица", 1}, {"воин", 0},
{"вор", 0}, {"гидра", 1}, {"глаз", 0}, {"голем", 0},
{"гора", 1}, {"горгулья", 1}, {"город", 0}, {"громовая", 1},
{"двор", 0}, {"джинн", 0}, {"дракон", 0}, {"дух", 0},
{"житель", 0}, {"жительница", 1}, {"зал", 0}, {"защитник", 0},
{"земля", 1}, {"искатель", 0}, {"ифрит", 0}, {"квартира", 1},
{"кольчуга", 1}, {"командир", 0}, {"крыса", 1}, {"лейтенант", 0},
{"луна", 1}, {"людоед", 0}, {"магог", 0}, {"меч", 0},
{"мечник", 0}, {"минотавр", 0}, {"мышь", 1}, {"наемник", 0},
{"огненная", 1}, {"огонь", 0}, {"орк", 0}, {"паук", 0},
{"пещера", 1}, {"пещеры", 1}, {"повелитель", 0}, {"погреб", 0},
{"полигон", 0}, {"приют", 0}, {"птица", 1}, {"птичий", 0},
{"работник", 0}, {"рай", 0}, {"рейнджер", 0}, {"рух", 0},
{"слизень", 0}, {"солдат", 0}, {"титан", 0}, {"трактир", 0},
{"тролль", 0}, {"убийца", 0}, {"улан", 0}, {"училище", 2},
{"шляпа", 1}, {"элементал", 0}}

Используется в GetGender().

right
GLdouble GLdouble right
Definition: SDL_opengl_glext.h:6106
IsSpecialName
bool IsSpecialName(const char *ansi_name)
Definition: mm7text_ru.cpp:584
format
SDL_AudioFormat format
Definition: SDL_audio.h:194
gender_table
struct GenderTableEntry gender_table[]
buf
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: SDL_opengl_glext.h:2483
GetGender
int GetGender(char *ansi_name, int name_len)
Definition: mm7text_ru.cpp:553
p
GLfloat GLfloat p
Definition: SDL_opengl_glext.h:11093
sprintfex_internal
int sprintfex_internal(char *str)
Definition: mm7text_ru.cpp:664
src
GLenum src
Definition: SDL_opengl_glext.h:1740
GetSpecialGender
int GetSpecialGender(const char *ansi_name)
Definition: mm7text_ru.cpp:591
GenderTableEntry
Definition: mm7text_ru.cpp:11
Log::Warning
void Warning(const wchar_t *pFormat,...)
Definition: Log.cpp:28
dst
GLenum GLenum dst
Definition: SDL_opengl_glext.h:1740
gender_table_caps
struct GenderTableEntry gender_table_caps[]
name
EGLImageKHR EGLint * name
Definition: SDL_egl.h:1497
c
const GLubyte * c
Definition: SDL_opengl_glext.h:11096
GetSpecialCase
const char * GetSpecialCase(const char *ansi_name, char c)
Definition: mm7text_ru.cpp:599
logger
Log * logger
Definition: IocContainer.cpp:47
left
GLint left
Definition: SDL_opengl_glext.h:1952
table
GLenum GLsizei GLenum GLenum const void * table
Definition: SDL_opengl_glext.h:3121