~moody/pse

pse/box.go -rw-r--r-- 2.4 KiB
e4de17d5 — Jacob Moody Introduce pse(1) 9 months ago
                                                                                
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
124
125
126
127
128
129
130
131
package pse

import (
	"errors"
	"fmt"
	"io"
	"strconv"
)

type Boxes struct {
	Current uint32
	//We use a slice of pointers to preserve order of pokemon in the boxes.
	//We do this having a empty spot be represented as nil
	Pokemon    [420]*Pokemon
	Names      [14]PkString
	Wallpapers [14]byte

	//The entire box section spans over
	//multiple sections, so we need both
	//the backing store as well as the
	//contigious data
	contData [3968 * 12]byte
	data     [9]*Section
}

func (b *Boxes) Format(f fmt.State, verb rune) {
	switch verb {
	case 'a':
		for i, p := range b.Pokemon {
			if p != nil {
				fmt.Fprintf(f, "%d\t%a\n", i, p)
			}
		}
	}
}

func (b *Boxes) Scan(state fmt.ScanState, verb rune) error {
	for {
		istr, err := state.Token(true, nil)
		switch {
		case err == io.EOF:
			return nil
		case err != nil:
			return err
		case len(istr) == 0:
			return nil
		}
		i, err := strconv.Atoi(string(istr))
		if err != nil {
			return err
		}
		if b.Pokemon[i] != nil {
			_, err = fmt.Fscanln(state, b.Pokemon[i])
			if err != nil {
				return err
			}
		}
	}

}

func (b *Boxes) Load(index int, s *Section) error {
	if index < SectionPCA || index > SectionPCI {
		return errors.New("Boxes.Load: non box index")
	}

	index = index - SectionPCA
	b.data[index] = s
	copy(b.contData[index*3968:(index+1)*3968], s.data[:])
	return nil
}

func (b *Boxes) Commit() error {
	//First we commit things to our contigious buffer
	var err error
	for _, s := range b.Names {
		err = s.Commit(LangEN)
		if err != nil {
			return err
		}
	}
	for _, p := range b.Pokemon {
		if p == nil {
			continue
		}
		err = p.Commit()
		if err != nil {
			return err
		}
	}
	put4(b.Current, b.contData[0:])
	copy(b.contData[0x83C2:], b.Wallpapers[:])

	//Now place our data back in the segmented sections and commit
	for i, s := range b.data {
		copy(b.data[i].data[:], b.contData[i*3968:(i+1)*3968])
		s.Commit()
	}
	return nil
}

func (b *Boxes) Parse() error {
	for i := range b.data {
		if b.data[i] == nil {
			return fmt.Errorf("Boxes.Load: missing section %d", i)
		}
	}
	b.Current = get4(b.contData[0:])

	j := 0
	for i := 0; i < 420*80; i += 80 {
		p, err := NewPokemon(b.contData[0x4+i:0x4+i+80], false)
		if err == nil {
			b.Pokemon[j] = p
		}
		j++
	}

	j = 0
	for i := 0; i < 14*9; i += 9 {
		str, err := NewPkString(b.contData[0x8344+i:0x8344+i+9], LangEN)
		if err != nil {
			return err
		}
		b.Names[j] = *str
	}

	copy(b.Wallpapers[:], b.contData[0x83C2:])

	return nil
}