Skip to content

Commit 343c7e7

Browse files
committed
Fix incorrect bitfield size for bitfields larger than 8 bits
1 parent c0eb2ea commit 343c7e7

File tree

5 files changed

+45
-24
lines changed

5 files changed

+45
-24
lines changed

generator_scripts/generate_cpp.py

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
from enum import Enum
22
import os
33
import re
4-
from generator_scripts.common import ArgsFlags, align_value, get_hl2sdk_common_types, locate_input_path, parse_args_as_flags, prepare_out_path
4+
from generator_scripts.common import Helpers, ArgsFlags, align_value, get_hl2sdk_common_types, locate_input_path, parse_args_as_flags, prepare_out_path
55
from generator_scripts.obj_defs import ClassObjectMember, EnumObjectField, ObjectDefinition, ObjectTypes, SubType, SubTypeAtomic, SubTypeTypes
6-
from generator_scripts.schema_file import Helpers, SchemaFile, FileWriter
6+
from generator_scripts.schema_file import SchemaFile, FileWriter
77
import argparse
88

99
args = None
@@ -46,18 +46,37 @@ def class_definition(self, class_obj: ObjectDefinition):
4646
current_offset += 8
4747

4848
bitfield_accum = 0
49+
bitfield_size = 1
50+
bitfield_last_member = 0
4951
previous_member_alignment = 0
5052

51-
for member in class_obj.get_members():
53+
for i, member in enumerate(class_obj.get_members()):
5254
member_size = member.get_type().get_size()
5355
member_alignment = member.get_type().get_alignment()
5456

5557
# Bitfields don't have any offset set
5658
if member.get_type().type == SubTypeTypes.BITFIELD and member.offset == 0:
59+
# If it's a start of a bitfield sequence, find largest alignment needed for it
60+
if bitfield_accum == 0:
61+
for j in range(i, len(class_obj.get_members())):
62+
adv_member = class_obj.get_members()[j]
63+
if adv_member.get_type().type == SubTypeTypes.BITFIELD and adv_member.offset == 0:
64+
size_needed = int((adv_member.get_type().bits_count + 7) / 8)
65+
66+
if size_needed > bitfield_size:
67+
bitfield_size = size_needed
68+
else:
69+
bitfield_last_member = j
70+
break
71+
for j in range(i, bitfield_last_member):
72+
class_obj.get_members()[j].get_type().expected_size = bitfield_size
73+
5774
bitfield_accum += member.get_type().bits_count
5875
else:
5976
if bitfield_accum != 0:
6077
current_offset += int((bitfield_accum + 7) / 8)
78+
bitfield_size = 1
79+
bitfield_last_member = 0
6180
bitfield_accum = 0
6281

6382
# Prevent unnecessary padding caused by alignment but ignore any packed classes
@@ -76,6 +95,8 @@ def class_definition(self, class_obj: ObjectDefinition):
7695

7796
if bitfield_accum != 0:
7897
current_offset += int((bitfield_accum + 7) / 8)
98+
bitfield_size = 1
99+
bitfield_last_member = 0
79100
bitfield_accum = 0
80101

81102
if align_value(current_offset, class_alignment) < class_obj.size:

generator_scripts/generate_cpp_defs.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
from enum import Enum
21
import os
32
from generate_cpp import CppContext, CppWriter
43
from generator_scripts.common import ArgsFlags, locate_input_path, parse_args_as_flags, prepare_out_path, get_hl2sdk_common_types
5-
from generator_scripts.obj_defs import ClassObjectMember, EnumObjectField, ObjectDefinition, ObjectTypes, SubType, SubTypeAtomic, SubTypeTypes
6-
from generator_scripts.schema_file import Helpers, SchemaFile
4+
from generator_scripts.obj_defs import ClassObjectMember, ObjectDefinition, SubTypeAtomic, SubTypeTypes
5+
from generator_scripts.schema_file import SchemaFile
76
import argparse
87

98
args = None

generator_scripts/generator_scripts/common.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,21 @@
22
import os
33
import glob
44

5+
class Helpers:
6+
@staticmethod
7+
def size_to_int(size, signed = False):
8+
match size:
9+
case 1:
10+
return 'uint8' if not signed else 'int8'
11+
case 2:
12+
return 'uint16' if not signed else 'int16'
13+
case 4:
14+
return 'uint32' if not signed else 'int32'
15+
case 8:
16+
return 'uint64' if not signed else 'int64'
17+
case _:
18+
raise Exception(f'Invalid size ({size}) to int was performed!')
19+
520
class ArgsFlags(IntFlag):
621
Empty = 0,
722
AddComments = (1 << 0),

generator_scripts/generator_scripts/obj_defs.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from enum import Enum
22
from typing import Union
33

4-
from generator_scripts.common import align_value
4+
from generator_scripts.common import align_value, Helpers
55

66
alignment_overrides = {
77
'EngineLoopState_t': 8
@@ -280,6 +280,7 @@ def parse_from(obj_list: 'ObjectList', raw_pointer):
280280

281281
class SubTypeBitfield:
282282
bits_count = 0
283+
expected_size = 1
283284

284285
def __init__(self):
285286
pass
@@ -294,7 +295,7 @@ def get_alignment(self):
294295
return 0
295296

296297
def as_str(self, var_name = None):
297-
return f'int8{" " + var_name if var_name is not None else ""} : {self.bits_count}'
298+
return f'{Helpers.size_to_int(self.expected_size)}{" " + var_name if var_name is not None else ""} : {self.bits_count}'
298299

299300
@property
300301
def type(self):

generator_scripts/generator_scripts/schema_file.py

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
from enum import IntFlag
21
import os
32
import json
43
from generator_scripts.common import ArgsFlags
@@ -120,18 +119,4 @@ def write_comment_check(self, comment):
120119
if self.has_flag(ArgsFlags.AddComments):
121120
return self.write_comment(comment)
122121
return self
123-
124-
class Helpers:
125-
@staticmethod
126-
def size_to_int(size, signed = False):
127-
match size:
128-
case 1:
129-
return 'uint8' if not signed else 'int8'
130-
case 2:
131-
return 'uint16' if not signed else 'int16'
132-
case 4:
133-
return 'uint32' if not signed else 'int32'
134-
case 8:
135-
return 'uint64' if not signed else 'int64'
136-
case _:
137-
raise Exception(f'Invalid size ({size}) to int was performed!')
122+

0 commit comments

Comments
 (0)