Author Topic: Why does Blockland improperly detect CPU names?  (Read 804 times)

I've noticed at the start of console log that the game mistakes processors for much older processors. For example, it mistakes a Core i7 as a Pentium II. I know that Torque is a pretty old engine itself, but is it actually too outdated to properly detect modern CPUs? Just curious.
Also, I've noticed that the game actually checks for ancient graphics accelerators (in this case, the Voodoo2).

Says I got a Pentium III when I have a Core 2 Duo


There's a much better way to tell people this.

console.log
Code: [Select]
Processor Init:
   Intel (unknown, Pentium Pro/II/III family), ~3.40 Ghz
     (timed at roughly 3.38 Ghz)

Quote from: Blockteen's Steam Profile
Intel Core i3-4130 CPU 3.40GHz
whhhhaa

Probs cause the engine is so old that these processors didn't exist at all / were extremely rare and overpriced back then

wtf i never noticed this. i went and looked through help at the console.logs and it's definitely common; if it doesn't show up as just "unknown" then it'll show up as a pentium.

i guess it's just the engine being too old?

It can probably only detect the hardware from their little (10 year old) database.
If the speed is faster than their fastest hardware, it automatically picks that.

Intel processors are probably detected as pentium because back in 2001-2 or whatever the pentium processor line was the only one Intel actually made that could run torque.
The game uses ASM code to determine the processor somehow (I can't read the ASM script but I assume from annotations it's fetching the model/manufacturer code)
Code: [Select]
;-----------------------------------------------------------------------------
; Torque Game Engine
; Copyright (C) GarageGames.com, Inc.
;-----------------------------------------------------------------------------

        
segment .text

; syntax: export_fn <function name>
%macro export_fn 1
   %ifdef LINUX
   ; No underscore needed for ELF object files
   global %1
   %1:
   %else
   global _%1
   _%1:
   %endif
%endmacro

; push registers
%macro pushreg 0
;    pushad
    push ebx
    push ebp
    push esi
    push edi
%endmacro

; pop registers
%macro popreg 0
    pop edi
    pop esi
    pop ebp
    pop ebx
;    popad
%endmacro
      
; void detectX86CPUInfo(char *vendor, U32 *processor, U32 *properties);
export_fn detectX86CPUInfo
   push         ebp
   mov          ebp, esp

   pushreg

   push         edx
   push         ecx
   pushfd
   pushfd                        ; save EFLAGS to stack
   pop          eax              ; move EFLAGS into EAX
   mov          ebx, eax
   xor          eax, 0x200000    ; flip bit 21
   push         eax
   popfd                         ; restore EFLAGS
   pushfd
   pop          eax
   cmp          eax, ebx
   jz           EXIT             ; doesn't support CPUID instruction

   ;
   ; get vendor information using CPUID eax == 0
   xor          eax, eax
   cpuid

   ; store the vendor tag (12 bytes in ebx, edx, ecx) in the first parameter,
   ; which should be a char[13]
   push         eax             ; save eax
   mov          eax, [ebp+8]    ; store the char* address in eax
   mov          [eax], ebx      ; move ebx into the first 4 bytes
   add          eax, 4          ; advance the char* 4 bytes
   mov          [eax], edx      ; move edx into the next 4 bytes
   add          eax, 4          ; advance the char* 4 bytes
   mov          [eax], ecx      ; move ecx into the last 4 bytes
   pop          eax             ; restore eax
        
   ; get generic extended CPUID info
   mov          eax, 1
   cpuid                         ; eax=1, so cpuid queries feature information

   and          eax, 0x0FF0
   push         ecx
   mov          ecx, [ebp+12]
   mov          [ecx], eax      ; just store the model bits in processor param
   mov          ecx, [ebp+16]
   mov          [ecx], edx      ; set properties param
   pop          ecx

   ; want to check for 3DNow(tm).  
   ; need to see if extended cpuid functions present.
   mov          eax, 0x80000000
   cpuid
   cmp          eax, 0x80000000
   jbe          MAYBE_3DLATER
   mov          eax, 0x80000001
   cpuid
   ; 3DNow if bit 31 set -> put bit in our properties        
   and          edx, 0x80000000  
   push         eax
   mov          eax, [ebp+16]
   or           [eax], edx
   pop          eax
MAYBE_3DLATER:
EXIT:
   popfd
   pop          ecx
   pop          edx

   popreg

   pop          ebp
   ret

then it's done by this code here from platformCPU.cc:

Code: [Select]
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------


#include "platform/platform.h"
#include "core/stringTable.h"

enum CPUFlags
{
   BIT_FPU     = BIT(0),
   BIT_RDTSC   = BIT(4),
   BIT_MMX     = BIT(23),
   BIT_SSE     = BIT(25),
   BIT_3DNOW   = BIT(31),
};

// fill the specified structure with information obtained from asm code
void SetProcessorInfo(Platform::SystemInfo_struct::Processor& pInfo,
   char* vendor, U32 processor, U32 properties)
{
   Platform::SystemInfo.processor.properties |= (properties & BIT_FPU)   ? CPU_PROP_FPU : 0;
   Platform::SystemInfo.processor.properties |= (properties & BIT_RDTSC) ? CPU_PROP_RDTSC : 0;
   Platform::SystemInfo.processor.properties |= (properties & BIT_MMX)   ? CPU_PROP_MMX : 0;

   if (dStricmp(vendor, "GenuineIntel") == 0)
   {
      pInfo.properties |= (properties & BIT_SSE) ? CPU_PROP_SSE : 0;
      pInfo.type = CPU_Intel_Unknown;
      // switch on processor family code
      switch ((processor >> 8) & 0x0f)
      {
         case 4:
            pInfo.type = CPU_Intel_486;
            pInfo.name = StringTable->insert("Intel 486 class");
            break;

            // Pentium Family
         case 5:
            // switch on processor model code
            switch ((processor >> 4) & 0xf)
            {
               case 1:
               case 2:
               case 3:
                  pInfo.type = CPU_Intel_Pentium;
                  pInfo.name = StringTable->insert("Intel Pentium");
                  break;
               case 4:
                  pInfo.type = CPU_Intel_PentiumMMX;
                  pInfo.name = StringTable->insert("Intel Pentium MMX");
                  break;
               default:
                  pInfo.type = CPU_Intel_Pentium;
                  pInfo.name = StringTable->insert( "Intel (unknown, Pentium family)" );
                  break;
            }
            break;

            // Pentium Pro/II/II family
         case 6:
            // switch on processor model code
            switch ((processor >> 4) & 0xf)
            {
               case 1:
                  pInfo.type = CPU_Intel_PentiumPro;
                  pInfo.name = StringTable->insert("Intel Pentium Pro");
                  break;
               case 3:
               case 5:
                  pInfo.type = CPU_Intel_PentiumII;
                  pInfo.name = StringTable->insert("Intel Pentium II");
                  break;
               case 6:
                  pInfo.type = CPU_Intel_PentiumCeleron;
                  pInfo.name = StringTable->insert("Intel Pentium Celeron");
                  break;
               case 7:
               case 8:
               case 10:
               case 11:
                  pInfo.type = CPU_Intel_PentiumIII;
                  pInfo.name = StringTable->insert("Intel Pentium III");
                  break;
               default:
                  pInfo.type = CPU_Intel_PentiumPro;
                  pInfo.name = StringTable->insert( "Intel (unknown, Pentium Pro/II/III family)" );
                  break;
            }
            break;

            // Pentium4 Family
         case 0xf:
            pInfo.type = CPU_Intel_Pentium4;
            pInfo.name = StringTable->insert( "Intel Pentium 4" );
            break;

         default:
            pInfo.type = CPU_Intel_Unknown;
            pInfo.name = StringTable->insert( "Intel (unknown)" );
            break;
      }
   }
   //--------------------------------------
   else
      if (dStricmp(vendor, "AuthenticAMD") == 0)
      {
         // AthlonXP processors support SSE
         pInfo.properties |= (properties & BIT_SSE) ? CPU_PROP_SSE : 0;
         pInfo.properties |= (properties & BIT_3DNOW) ? CPU_PROP_3DNOW : 0;
         // switch on processor family code
         switch ((processor >> 8) & 0xf)
         {
            // K6 Family
            case 5:
               // switch on processor model code
               switch ((processor >> 4) & 0xf)
               {
                  case 0:
                  case 1:
                  case 2:
                  case 3:
                     pInfo.type = CPU_AMD_K6_3;
                     pInfo.name = StringTable->insert("AMD K5");
                     break;
                  case 4:
                  case 5:
                  case 6:
                  case 7:
                     pInfo.type = CPU_AMD_K6;
                     pInfo.name = StringTable->insert("AMD K6");
                     break;
                  case 8:
                     pInfo.type = CPU_AMD_K6_2;
                     pInfo.name = StringTable->insert("AMD K6-2");
                     break;
                  case 9:
                  case 10:
                  case 11:
                  case 12:
                  case 13:
                  case 14:
                  case 15:
                     pInfo.type = CPU_AMD_K6_3;
                     pInfo.name = StringTable->insert("AMD K6-3");
                     break;
               }
               break;

               // Athlon Family
            case 6:
               pInfo.type = CPU_AMD_Athlon;
               pInfo.name = StringTable->insert("AMD Athlon");
               break;

            default:
               pInfo.type = CPU_AMD_Unknown;
               pInfo.name = StringTable->insert("AMD (unknown)");
               break;
         }
      }
   //--------------------------------------
      else
         if (dStricmp(vendor, "CyrixInstead") == 0)
         {
            switch (processor)
            {
               case 0x520:
                  pInfo.type = CPU_Cyrix_6x86;
                  pInfo.name = StringTable->insert("Cyrix 6x86");
                  break;
               case 0x440:
                  pInfo.type = CPU_Cyrix_MediaGX;
                  pInfo.name = StringTable->insert("Cyrix Media GX");
                  break;
               case 0x600:
                  pInfo.type = CPU_Cyrix_6x86MX;
                  pInfo.name = StringTable->insert("Cyrix 6x86mx/MII");
                  break;
               case 0x540:
                  pInfo.type = CPU_Cyrix_GXm;
                  pInfo.name = StringTable->insert("Cyrix GXm");
                  break;
               default:
                  pInfo.type = CPU_Cyrix_Unknown;
                  pInfo.name = StringTable->insert("Cyrix (unknown)");
                  break;
            }
         }
}

There you go. See how the little switch here only "knows" the model and submodel of Pentium cores?

Hey, I'm also surprised I still have the original torque source.
Anyway, I'm sure it's a non-issue but all it would probably take to fix this is some modifications to these two files. If anyone had any idea what the hardware numbers for the i3 are, that is, because I can't find them anywhere.
« Last Edit: July 08, 2016, 05:41:23 PM by chrisbot6 »