Page 1 of 1

Magic Numbers System

Posted: Sat Sep 07, 2013 12:56 pm
by StarBootics
Hello everyone,

A Magic Numbers System similar to the one used by ID Software for their MD2 and MD3 3D models used by the Quake 2 and Quake 3 engine.

I have created a command to convert 4 and 8 characters string into a Long or Quad number and convert them back to string using a similar technics.

If they can be useful for someone else.

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : Magic Numbers System
; File Name : Magic Numbers System.pb
; File version: 1.0.0
; Programming : OK
; Programmed by : StarBootics
; Date : 07-09-2013
; Last Update : 07-09-2013
; PureBasic code : V5.20 beta 17 LTS
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Notes :
;
; This Magic Number system is similar to the 
; one used in MD2, MD3 ID Software files for
; the Quake 3 engine.
;
; The technics consist of encoding a 4 characters
; string into an Int32 number. 
;
; For controling specific file versioning system
; I need to encode a 6 characters string in the 
; same way so I use a Quad instead of Long. 
;
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Procedure.l String_To_MagicLongNumber(String.s)
  
  If Len(String) > 4
    ProcedureReturn -1
  Else
    
    Char00 = Asc(Mid(String, 4, 1))
    Char01 = Asc(Mid(String, 3, 1))
    Char02 = Asc(Mid(String, 2, 1))
    Char03 = Asc(Mid(String, 1, 1))
    
    MagicLongNumber.l = Char00 << 24 + Char01 << 16 + Char02 << 8 + Char03
    
  EndIf
  
  ProcedureReturn MagicLongNumber
EndProcedure

Procedure.q String_To_MagicQuadNumber(String.s)
  
  If Len(String) > 8
    ProcedureReturn -1
  Else
    
    Char00 = Asc(Mid(String, 8, 1))
    Char01 = Asc(Mid(String, 7, 1))
    Char02 = Asc(Mid(String, 6, 1))
    Char03 = Asc(Mid(String, 5, 1))
    Char04 = Asc(Mid(String, 4, 1))
    Char05 = Asc(Mid(String, 3, 1))
    Char06 = Asc(Mid(String, 2, 1))
    Char07 = Asc(Mid(String, 1, 1))
    
    MagicQuadNumber.q = Char00 << 56 + Char01 << 48 + Char02 << 40 + Char03 << 32 + Char04 << 24 + Char05 << 16 + Char06 << 8 + Char07
    
  EndIf
  
  ProcedureReturn MagicQuadNumber
EndProcedure

Procedure.s MagicLongNumber_To_String(MagicNum.l)
  
  Char03 = MagicNum >> 24 & $FF
  Char02 = MagicNum >> 16 & $FF
  Char01 = MagicNum >> 8 & $FF
  Char00 = MagicNum & $FF
  
  ProcedureReturn Chr(Char00) + Chr(Char01) + Chr(Char02) + Chr(Char03)
EndProcedure

Procedure.s MagicQuadNumber_To_String(MagicNum.q)
  
  Char07 = MagicNum >> 56 & $FF
  Char06 = MagicNum >> 48 & $FF
  Char05 = MagicNum >> 40 & $FF
  Char04 = MagicNum >> 32 & $FF
  Char03 = MagicNum >> 24 & $FF
  Char02 = MagicNum >> 16 & $FF
  Char01 = MagicNum >> 8 & $FF
  Char00 = MagicNum & $FF
  
  ProcedureReturn Chr(Char00) + Chr(Char01) + Chr(Char02) + Chr(Char03) + Chr(Char04) + Chr(Char05) + Chr(Char06) + Chr(Char07)
EndProcedure

CompilerIf #PB_Compiler_IsMainFile 
  
  MagicLongNum.l = String_To_MagicLongNumber("IDP3")
  Debug MagicLongNum
  Debug MagicLongNumber_To_String(MagicLongNum)
  
  Debug ""
  
  MagicQuadNum.q = String_To_MagicQuadNumber("V1.0.2.0")
  Debug MagicQuadNum
  Debug MagicQuadNumber_To_String(MagicQuadNum)
  
CompilerEndIf

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
Best regards.
StarBootics

Re: Magic Numbers System

Posted: Sat Sep 07, 2013 9:22 pm
by HeX0R
Isn't it the same as this:

Code: Select all

MagicLongNum.l = PeekL(@"IDP3")
Debug MagicLongNum
Debug PeekS(@MagicLongNum, 4)
   
MagicQuadNum.q = PeekQ(@"V1.0.2.0")
Debug MagicQuadNum
Debug PeekS(@MagicQuadNum, 8)
?

Re: Magic Numbers System

Posted: Sat Sep 07, 2013 9:27 pm
by ts-soft
Is not the same, you're code doesn't support UNICODE :mrgreen:

Re: Magic Numbers System

Posted: Sat Sep 07, 2013 9:28 pm
by luis
Sure :mrgreen:

Re: Magic Numbers System

Posted: Sat Sep 07, 2013 9:32 pm
by HeX0R
ts-soft wrote:Is not the same, you're code doesn't support UNICODE :mrgreen:
HaHa, o.k. you're right. :lol:

Re: Magic Numbers System

Posted: Sat Sep 07, 2013 10:12 pm
by luis
Not much longer anyway :wink:

Code: Select all

*p = AllocateMemory(9)

PokeS(*p, "IDP3", -1, #PB_Ascii) : MagicLongNum.l = PeekL(*p)
Debug MagicLongNum
Debug PeekS(@MagicLongNum, 4, #PB_Ascii)

FillMemory(*p, 9)

PokeS(*p, "V1.0.2.0", -1, #PB_Ascii) : MagicQuadNum.q = PeekQ(*p)
Debug MagicQuadNum
Debug PeekS(@MagicQuadNum, 8, #PB_Ascii)

FreeMemory(*p)
But thanks for sharing starbootics, more than a way to do something is always appreciated and instructive, I think :wink:

Re: Magic Numbers System

Posted: Sun Sep 08, 2013 1:30 am
by StarBootics
Hello everyone,

In my example, since Character values are always between 0 and 255 it's the same thing as encoding a color from the red, green and blue components :

Code: Select all

Color = Blue << 16 + Green << 8 + Red
This were I get the idea about how a 4 characters string can be encoded inside a long variable and a 8 characters string can be encoded inside a quad variable. In unicode mode it will probably possible to encode a 4 characters string inside a Quad but I don't tested this yet.

Best regards
StarBootics