Skip to content
This repository was archived by the owner on Oct 28, 2022. It is now read-only.

Commit a0049af

Browse files
committed
texture shuffle for rando levels, new painting, fix bparam matching
1 parent b38c978 commit a0049af

File tree

12 files changed

+319
-203
lines changed

12 files changed

+319
-203
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,5 @@ web/design
6565
# js crap
6666
node_modules/
6767

68-
.data
68+
.data
69+
/*.zip
19 KB
Loading

Config/sm64.vanilla.yml

Lines changed: 49 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ levels:
176176
- name: "Big Boo's Haunt"
177177
course_id: 0x04
178178
properties:
179+
- disable_planes: # the middle layer in BBH will make objects unaccessible
180+
- y_range: [-1428, -206]
179181
- shuffle_painting:
180182
- custom_painting: 'painting_bbh'
181183
- name: "Hazy Maze Cave"
@@ -208,6 +210,7 @@ levels:
208210
- name: 'painting_lll_lower'
209211
segment_index: 23
210212
segment_offset: 0x12800
213+
format: 'rgba16'
211214
size: [64, 32] # width, height
212215
- requires_key: 0x1
213216
- name: "Shifting Sand Land"
@@ -224,6 +227,7 @@ levels:
224227
- name: 'painting_ssl_lower'
225228
segment_index: 23
226229
segment_offset: 0x15800
230+
format: 'rgba16'
227231
size: [64, 32] # width, height
228232
- requires_key: 0x1
229233
- name: "Dire, Dire Docks"
@@ -325,7 +329,7 @@ levels:
325329
course_id: 0x0D
326330
properties:
327331
- shuffle_painting:
328-
- game_painting: 'painting_ttm'
332+
- game_painting: 'painting_thi'
329333
sections:
330334
- name: 'painting_thi_upper'
331335
segment_index: 23
@@ -342,14 +346,14 @@ levels:
342346
course_id: 0x0E
343347
properties:
344348
- shuffle_painting:
345-
- game_painting: 'painting_thi'
349+
- game_painting: 'painting_ttc'
346350
sections:
347-
- name: 'painting_thi_upper'
351+
- name: 'painting_ttc_upper'
348352
segment_index: 23
349353
segment_offset: 0x1D800
350354
format: 'rgba16'
351355
size: [64, 32] # width, height
352-
- name: 'painting_thi_lower'
356+
- name: 'painting_ttc_lower'
353357
segment_index: 23
354358
segment_offset: 0x1E800
355359
format: 'rgba16'
@@ -377,6 +381,7 @@ levels:
377381
- name: "Wing Cap"
378382
course_id: 0x1D
379383
properties:
384+
- fly_stage
380385
- shuffle_painting:
381386
- custom_painting: 'painting_wc'
382387

@@ -526,7 +531,7 @@ object_randomization:
526531
- name: Bob-Omb
527532
match: 0x13003174
528533
- name: Goomba
529-
match: 0x13004770
534+
match: 0x1300472C
530535
- name: Goomba Triplet
531536
match: 0x13004770
532537
- name: Thwomp
@@ -598,24 +603,25 @@ object_randomization:
598603
- bparam2: 0
599604
rules:
600605
- bounding_box: [1000, 100, 100] # length, width, height
601-
- spawn_height: [100, 600]
606+
- spawn_height: [200, 600]
602607
- name: Grounded Ring Formation (8x)
603608
match:
604609
- bparam2: 2
605610
rules:
606611
- bounding_box: [1000, 1000, 100] # length, width, height
607-
- spawn_height: [100, 600]
612+
- spawn_height: [200, 600]
608613
- name: Grounded Arrow (8x)
609614
match:
610615
- bparam2: 4
611616
rules:
612617
- bounding_box: [500, 500, 100] # length, width, height
613-
- spawn_height: [100, 600]
618+
- spawn_height: [200, 600]
614619
- name: Horizontal Floating Line (x5)
615620
match:
616621
- bparam2: 16
617622
rules:
618623
- bounding_box: [600, 100, 100] # length, width, height
624+
- spawn_height: [200, 500]
619625
- name: Vertical Floating Line (x5)
620626
match:
621627
- bparam2: 17
@@ -641,8 +647,9 @@ object_randomization:
641647
objects:
642648
- name: Yellow Coin
643649
match:
644-
- 0x1300090C
645-
- 0x1300091C # For Triggers?
650+
- behaviours:
651+
- 0x1300090C
652+
- 0x1300091C # For Triggers?
646653
- name: Red Coin
647654
match: 0x13003EAC
648655
- name: Blue Coin
@@ -657,8 +664,10 @@ object_randomization:
657664
objects:
658665
- name: Star
659666
match:
660-
- 0x13003E3C
661-
- 0x13003EFC # Hidden
667+
- behaviours:
668+
- 0x13003E3C
669+
- 0x13003EFC # Hidden
670+
- 0x13003E8C # Red Coin Star
662671
- name: Star in Box
663672
match: 0x13002250
664673
rules:
@@ -762,8 +771,6 @@ object_randomization:
762771
match: 0x13002E58
763772
- name: "Pink Bob-Omb (Message)"
764773
match: 0x130031DC
765-
rules:
766-
- underwater: never
767774
- name: "Pink Bob-Omb (Canon)"
768775
match: 0x13003228
769776

@@ -798,6 +805,8 @@ object_randomization:
798805
- course_property: slide
799806
for:
800807
- "Warps"
808+
rules:
809+
- disabled
801810

802811
- name: "Level Special Cases"
803812
objects:
@@ -808,20 +817,27 @@ object_randomization:
808817
for:
809818
- 'Stars'
810819
rules:
811-
- max_y: 1858
820+
- max_y: 1800
812821
- name: "THI: Red Coins / Red Coin Star below Boss Room"
813822
match:
814-
- 0x13003EAC # Red Coin
815-
- 0x13003E8C # Red Coin Star
823+
- course_id: 0x0D
824+
- area_id: 0x2
825+
- behaviours:
826+
- 0x13003EAC # Red Coin
827+
- 0x13003E8C # Red Coin Star
816828
rules:
817829
- max_y: 1750
818830
- name: "WC: Coins within Reach of Platform"
819831
match:
832+
- course_property: fly_stage
820833
- course_id: 0x1D
821834
rules:
835+
- no_floor_required
836+
- min_y: -2260
837+
- max_y: 4064
822838
- distance_to:
823839
- origin: [0, -2047, 0]
824-
max_distance: 6000
840+
max_distance: 5000
825841
for:
826842
- 'Coin'
827843
- 'Coin Formations'
@@ -837,9 +853,18 @@ object_randomization:
837853
- name: "WMotR: Disable Itembox Shuffle"
838854
match:
839855
- course_id: 0x1F
840-
- behaviour: 0x13002250
856+
- behaviours: 0x13002250
841857
rules:
842858
- disabled
859+
- name: "BOB: Disable coin ring shuffle"
860+
match:
861+
- course_id: 0x09
862+
- area_id: 0x01
863+
- behaviours: 0x130008EC
864+
- bparam2: 19
865+
rules:
866+
- disabled
867+
843868

844869
# Define custom painting authors/names
845870
custom_paintings:
@@ -871,4 +896,8 @@ custom_paintings:
871896
- name: painting_wc
872897
file: "Assets/img/custom_paintings/mika/WC.png"
873898
transform:
874-
- type: split-horizontal
899+
- type: split-horizontal
900+
- name: painting_pss
901+
file: "Assets/img/custom_paintings/mika/PSS.png"
902+
transform:
903+
- type: split-horizontal

sm64r/CLI.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,11 @@ def run_with_parsed_args(opt_args : argparse.Namespace):
134134
# initialize texture atlas and dynamic positions
135135
textures = TextureAtlas(rom)
136136
textures.add_dynamic_positions()
137+
textures.load_default_unknown_texture()
137138

138139
# Segment Finder
139140
# rom.match_segments(0xD78271)
141+
# rom.match_segments(0xA8181C) # texture for question mark
140142

141143
start_time = time.time()
142144

sm64r/Config.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
'shuffle_painting[].sections[].name': ["str"],
2828
'requires_key': ["int"],
2929
'loading_zones': ["list"],
30+
'disable_planes': ["list"],
3031
'shuffle_warps': ["list"],
3132
'shuffle_warps[].to': ["list"],
3233
'shuffle_warps[].to[].course_id': ["int"],
@@ -53,7 +54,7 @@
5354

5455
# Which entries are allowed in objects[] (...) .match[]
5556
MATCH_DEFINITIONS = {
56-
'behaviour': ["int", "list"],
57+
'behaviours': ["int", "list"],
5758
'bparam1': ["int"],
5859
'bparam2': ["int"],
5960
'bparam3': ["int"],
@@ -99,6 +100,9 @@ def __init__(self, filename, source):
99100

100101
#print(json.dumps(source, indent=2))
101102

103+
if os.path.exists("sm64_rando_rules.log"):
104+
os.unlink("sm64_rando_rules.log")
105+
102106
if not self.validate(source):
103107
print(f"Validation Error founds:{NL}{NL.join(self.validation_errors)}")
104108
raise TypeError(f"{filename} is invalid")
@@ -221,10 +225,10 @@ def validate_match(self, match, parents):
221225
match_type = entry
222226
match_value = True
223227
elif type(entry) is int:
224-
match_type = "behaviour"
225-
match_value = entry
228+
match_type = "behaviours"
229+
match_value = [entry]
226230
elif type(entry) is list:
227-
match_type = "behaviour"
231+
match_type = "behaviours"
228232
match_value = entry
229233
else:
230234
self.validation_errors.append(f'Invalid Match property in "{" => ".join(parents)}" - supplied an invalid type of rule-set for a match property. Either boolean or key:value')
@@ -516,7 +520,10 @@ def parse_object_table(self, table, rules = None, match = None, exclude = None):
516520
match["behaviours"].append(entry)
517521
if type(entry) is dict:
518522
prop_name = list(entry.keys())[0]
519-
match[prop_name] = entry[prop_name]
523+
if prop_name == "behaviours":
524+
match[prop_name] = [entry[prop_name]]
525+
else:
526+
match[prop_name] = entry[prop_name]
520527

521528
# Exclude Matching
522529
if "exclude" in table:
@@ -646,6 +653,10 @@ def parse(self, source):
646653
if "object_randomization" in source:
647654
self.parse_object_table(source["object_randomization"])
648655

656+
with open("sm64_rando_rules.log", "a") as rule_log:
657+
for object_entry in self.object_entries:
658+
rule_log.write(json.dumps(object_entry) + "\n")
659+
649660
print(f"Configuration '{self.name}' loaded {len(self.object_entries)} object-rule entries")
650661

651662
def has_checksum_configuration(self, checksum):

sm64r/Entities/LevelGeometry.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ def process(self):
181181
self.level_forbidden_boundaries.append(bounding_box)
182182

183183
def plot_placement(self, obj, *targets):
184-
print("plotting debug placement")
184+
#print("plotting placement")
185185
level_traces = []
186186

187187
# Plot level wide boundaries
@@ -454,6 +454,6 @@ def plot(self):
454454
)
455455
)
456456

457-
print(f'plotting {self.level.name} {hex(area_id)}')
457+
#print(f'plotting {self.level.name} {hex(area_id)}')
458458
py.plot(traces, filename=f'dumps/level_plots/{self.level.name}_{hex(area_id)}.html', auto_open=False)
459-
print('done')
459+
#print('done')

sm64r/Parsers/Imaging.py

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
from PIL import Image
2+
import numpy as np
23

34
class N64Image:
45
def __init__(self, img : Image):
56
self.img = img
67
self.bytes_original = self.img.tobytes()
78

8-
def scale_8_to_5(self, val):
9+
@staticmethod
10+
def scale_8_to_5(val):
911
return int(((((val) + 4) * 0x1F) / 0xFF))
1012

13+
@staticmethod
14+
def scale_5_to_8(val):
15+
return int(int(val * 0xFF) / 0x1F)
16+
1117
def read_rgba16(self):
1218
""" Returns the loaded image as a bytearray of the RGBA16 format present on the N64
1319
@@ -20,15 +26,15 @@ def read_rgba16(self):
2026

2127
n64_img_bytes = bytearray(len(self.bytes_original))
2228

23-
for y in range(0, width):
24-
for x in range(0, height):
29+
for y in range(0, height):
30+
for x in range(0, width):
2531
idx = (y * width + x) * 2
2632

2733
(r, g, b, a) = px[x, y]
2834

29-
r_5 = self.scale_8_to_5(r)
30-
g_5 = self.scale_8_to_5(g)
31-
b_5 = self.scale_8_to_5(b)
35+
r_5 = N64Image.scale_8_to_5(r)
36+
g_5 = N64Image.scale_8_to_5(g)
37+
b_5 = N64Image.scale_8_to_5(b)
3238

3339
n64_img_bytes[idx] = int((r_5 << 3) | (g_5 >> 2))
3440
n64_img_bytes[idx+1] = int(((g & 0x03) << 6) | (b_5 << 1) | (1 if a > 0 else 0))
@@ -42,3 +48,33 @@ def parse_image(path):
4248
loaded_img = Image.open(file)
4349

4450
return N64Image(loaded_img)
51+
52+
@staticmethod
53+
def from_ingame(rom, texture):
54+
ingame_bytes = rom.read_bytes(texture.position, texture.size)
55+
56+
width = texture.width
57+
height = texture.height
58+
59+
img_bytes = np.zeros((width, height, 4), dtype="uint8")
60+
for y in range(0, height):
61+
for x in range(0, width):
62+
img_idx = (y * width + x)
63+
idx = img_idx * 2
64+
65+
px1 = ingame_bytes[idx]
66+
px2 = ingame_bytes[idx+1]
67+
68+
r = N64Image.scale_5_to_8((px1 & 0xF8) >> 3)
69+
g = N64Image.scale_5_to_8((px1 & 0x07) << 2 | ((px2 & 0xC0) >> 6))
70+
b = N64Image.scale_5_to_8((px1 & 0x3E) >> 1)
71+
a = 255 if (px2 & 0x1) > 0 else 0
72+
73+
img_bytes[y,x,0] = r
74+
img_bytes[y,x,1] = g
75+
img_bytes[y,x,2] = b
76+
img_bytes[y,x,3] = a
77+
78+
img = Image.fromarray(img_bytes)
79+
#img.show()
80+
return N64Image(img)

0 commit comments

Comments
 (0)