-
Notifications
You must be signed in to change notification settings - Fork 1
/
libpoke.py
123 lines (90 loc) · 3.37 KB
/
libpoke.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
from libpoke_types.poke import *
from libpoke_types.savefile import NUM_SECTORS_PER_SLOT, SECTOR_SIZE, SaveChunk
class Savefile:
DATA_SIZE = SECTOR_SIZE * NUM_SECTORS_PER_SLOT
DATA_EMPTY = b'\xFF' * DATA_SIZE
PC_BUFFER_COUNT = 420
PC_BUFFER_ENTRY_SIZE = 80
PC_BUFFER_SIZE = PC_BUFFER_ENTRY_SIZE * PC_BUFFER_COUNT
PC_SCREEN_ROWS = 6
PC_SCREEN_COLUMNS = 5
PC_SCREEN_SLOTS_COUNT = PC_SCREEN_ROWS * PC_SCREEN_COLUMNS
PC_SCREEN_FULL_BYTES = PC_BUFFER_ENTRY_SIZE * PC_SCREEN_SLOTS_COUNT
def __init__(self, buf):
self.data = bytearray(buf)
self.view = memoryview(self.data)
def GetChunkView(self, raw_index: int) -> SaveChunk:
offs = SECTOR_SIZE * raw_index
view = self.view[offs:offs+SECTOR_SIZE]
return SaveChunk.from_buffer(view)
def GetChunkViewsInOrder(self) -> "list[SaveChunk]":
views = [None] * NUM_SECTORS_PER_SLOT
for i in range(len(views)):
view = self.GetChunkView(i)
views[view.ID] = view
return views
def GetCopyOfPC(self):
res = bytearray(self.PC_BUFFER_SIZE)
offs = 0
chunks = self.GetChunkViewsInOrder()
for i in range(5, 14):
chunk = chunks[i]
len = chunk.GetLength()
len = min(len, self.PC_BUFFER_SIZE - offs)
if i == 5:
len -= 4
res[offs:offs+len] = chunk.data[4:len+4]
else:
res[offs:offs+len] = chunk.data[0:len]
offs += len
assert offs == self.PC_BUFFER_SIZE, "bruh 1"
return res
def SetCopyOfPC(self, buf):
offs = 0
chunks = self.GetChunkViewsInOrder()
for i in range(5, 14):
chunk = chunks[i]
len = chunk.GetLength()
len = min(len, self.PC_BUFFER_SIZE - offs)
if i == 5:
len -= 4
chunk.data[4:len+4] = buf[offs:offs+len]
else:
chunk.data[0:len] = buf[offs:offs+len]
offs += len
assert offs == self.PC_BUFFER_SIZE, "bruh 2"
def GetValidationError(self):
view = self.GetChunkView(0)
err = view.GetError()
if err:
return err
n_index = view.save_index
n_chunk = view.ID
for i in range(NUM_SECTORS_PER_SLOT):
view = self.GetChunkView(i)
if view.save_index != n_index:
return 3
if view.ID != n_chunk:
return 4
n_chunk += 1
if n_chunk == NUM_SECTORS_PER_SLOT:
n_chunk = 0
return 0
def Fixup(self):
for i in range(NUM_SECTORS_PER_SLOT):
view = self.GetChunkView(i)
view.Regenerate()
def SelectBestIndex(arg1: Savefile, arg2: Savefile):
nbest = None
n_idx = 0
if not arg1.GetValidationError():
n_id = arg1.GetChunkView(0).save_index
if n_id >= n_idx:
n_idx = n_id
nbest = 0
if not arg2.GetValidationError():
n_id = arg2.GetChunkView(0).save_index
if n_id >= n_idx:
n_idx = n_id
nbest = 1
return nbest