Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pret
GitHub Repository: pret/pokered
Path: blob/master/engine/menus/save.asm
1271 views
1
TryLoadSaveFile:
2
call ClearScreen
3
call LoadFontTilePatterns
4
call LoadTextBoxTilePatterns
5
call LoadMainData
6
jr c, .badsum
7
call LoadCurrentBoxData
8
jr c, .badsum
9
call LoadPartyAndDexData
10
jr c, .badsum
11
ld a, $2 ; good checksum
12
jr .done
13
.badsum
14
ld hl, wStatusFlags5
15
push hl
16
set BIT_NO_TEXT_DELAY, [hl]
17
ld hl, FileDataDestroyedText
18
call PrintText
19
ld c, 100
20
call DelayFrames
21
pop hl
22
res BIT_NO_TEXT_DELAY, [hl]
23
ld a, $1 ; bad checksum
24
.done
25
ld [wSaveFileStatus], a
26
ret
27
28
FileDataDestroyedText:
29
text_far _FileDataDestroyedText
30
text_end
31
32
LoadMainData:
33
ld a, RAMG_SRAM_ENABLE
34
ld [rRAMG], a
35
ld a, BMODE_ADVANCED
36
ld [rBMODE], a
37
ASSERT BANK("Save Data") == BMODE_ADVANCED
38
ld [rRAMB], a
39
; This vc_hook does not have to be in any particular location.
40
; It is defined here because it refers to the same labels as the two lines below.
41
vc_hook Unknown_save_limit
42
ld hl, sGameData
43
ld bc, sGameDataEnd - sGameData
44
call CalcCheckSum
45
ld c, a
46
ld a, [sMainDataCheckSum]
47
cp c
48
jp z, .checkSumMatched
49
50
; If the computed checksum didn't match the saved on, try again.
51
ld hl, sGameData
52
ld bc, sGameDataEnd - sGameData
53
call CalcCheckSum
54
ld c, a
55
ld a, [sMainDataCheckSum]
56
cp c
57
jp nz, CheckSumFailed
58
59
.checkSumMatched
60
ld hl, sPlayerName
61
ld de, wPlayerName
62
ld bc, NAME_LENGTH
63
call CopyData
64
ld hl, sMainData
65
ld de, wMainDataStart
66
ld bc, wMainDataEnd - wMainDataStart
67
call CopyData
68
ld hl, wCurMapTileset
69
set BIT_NO_PREVIOUS_MAP, [hl]
70
ld hl, sSpriteData
71
ld de, wSpriteDataStart
72
ld bc, wSpriteDataEnd - wSpriteDataStart
73
call CopyData
74
ld a, [sTileAnimations]
75
ldh [hTileAnimations], a
76
77
; this part is redundant, LoadCurrentBoxData is always called next
78
ld hl, sCurBoxData
79
ld de, wBoxDataStart
80
ld bc, wBoxDataEnd - wBoxDataStart
81
call CopyData
82
83
and a
84
jp GoodCheckSum
85
86
LoadCurrentBoxData:
87
ld a, RAMG_SRAM_ENABLE
88
ld [rRAMG], a
89
ld a, BMODE_ADVANCED
90
ld [rBMODE], a
91
ASSERT BANK("Save Data") == BMODE_ADVANCED
92
ld [rRAMB], a
93
ld hl, sGameData
94
ld bc, sGameDataEnd - sGameData
95
call CalcCheckSum
96
ld c, a
97
ld a, [sMainDataCheckSum]
98
cp c
99
jr nz, CheckSumFailed
100
ld hl, sCurBoxData
101
ld de, wBoxDataStart
102
ld bc, wBoxDataEnd - wBoxDataStart
103
call CopyData
104
and a
105
jp GoodCheckSum
106
107
LoadPartyAndDexData:
108
ld a, RAMG_SRAM_ENABLE
109
ld [rRAMG], a
110
ld a, BMODE_ADVANCED
111
ld [rBMODE], a
112
ASSERT BANK("Save Data") == BMODE_ADVANCED
113
ld [rRAMB], a
114
ld hl, sGameData
115
ld bc, sGameDataEnd - sGameData
116
call CalcCheckSum
117
ld c, a
118
ld a, [sMainDataCheckSum]
119
cp c
120
jp nz, CheckSumFailed
121
ld hl, sPartyData
122
ld de, wPartyDataStart
123
ld bc, wPartyDataEnd - wPartyDataStart
124
call CopyData
125
ld hl, sMainData
126
ld de, wPokedexOwned
127
ld bc, wPokedexSeenEnd - wPokedexOwned
128
call CopyData
129
and a
130
jp GoodCheckSum
131
132
CheckSumFailed:
133
scf
134
; fallthrough
135
136
GoodCheckSum:
137
ld a, BMODE_SIMPLE ; preserve flags
138
ld [rBMODE], a
139
ASSERT RAMG_SRAM_DISABLE == BMODE_SIMPLE
140
ld [rRAMG], a
141
ret
142
143
TryLoadSaveFileIgnoreChecksum: ; unreferenced
144
; don't update wSaveFileStatus upon success or failure
145
; don't display warning in case of failed checksum
146
call LoadMainData
147
call LoadCurrentBoxData
148
jp LoadPartyAndDexData
149
150
SaveMenu:
151
farcall PrintSaveScreenText
152
ld hl, WouldYouLikeToSaveText
153
call SaveTheGame_YesOrNo
154
and a ;|0 = Yes|1 = No|
155
ret nz
156
ld a, [wSaveFileStatus]
157
dec a
158
jr z, .save
159
call CheckPreviousSaveFile
160
jr z, .save
161
ld hl, OlderFileWillBeErasedText
162
call SaveTheGame_YesOrNo
163
and a
164
ret nz
165
.save
166
call SaveGameData
167
hlcoord 1, 13
168
lb bc, 4, 18
169
call ClearScreenArea
170
hlcoord 1, 14
171
ld de, NowSavingString
172
call PlaceString
173
ld c, 120
174
call DelayFrames
175
ld hl, GameSavedText
176
call PrintText
177
ld a, SFX_SAVE
178
call PlaySoundWaitForCurrent
179
call WaitForSoundToFinish
180
ld c, 30
181
jp DelayFrames
182
183
NowSavingString:
184
db "Now saving...@"
185
186
SaveTheGame_YesOrNo:
187
call PrintText
188
hlcoord 0, 7
189
lb bc, 8, 1
190
ld a, TWO_OPTION_MENU
191
ld [wTextBoxID], a
192
call DisplayTextBoxID
193
ld a, [wCurrentMenuItem]
194
ret
195
196
WouldYouLikeToSaveText:
197
text_far _WouldYouLikeToSaveText
198
text_end
199
200
GameSavedText:
201
text_far _GameSavedText
202
text_end
203
204
OlderFileWillBeErasedText:
205
text_far _OlderFileWillBeErasedText
206
text_end
207
208
SaveMainData:
209
ld a, RAMG_SRAM_ENABLE
210
ld [rRAMG], a
211
ld a, BMODE_ADVANCED
212
ld [rBMODE], a
213
ASSERT BANK("Save Data") == BMODE_ADVANCED
214
ld [rRAMB], a
215
216
ld hl, wPlayerName
217
ld de, sPlayerName
218
ld bc, NAME_LENGTH
219
call CopyData
220
ld hl, wMainDataStart
221
ld de, sMainData
222
ld bc, wMainDataEnd - wMainDataStart
223
call CopyData
224
ld hl, wSpriteDataStart
225
ld de, sSpriteData
226
ld bc, wSpriteDataEnd - wSpriteDataStart
227
call CopyData
228
ld hl, wBoxDataStart
229
230
; this part is redundant, SaveCurrentBoxData is always called next
231
ld de, sCurBoxData
232
ld bc, wBoxDataEnd - wBoxDataStart
233
call CopyData
234
ldh a, [hTileAnimations]
235
ld [sTileAnimations], a
236
237
ld hl, sGameData
238
ld bc, sGameDataEnd - sGameData
239
call CalcCheckSum
240
ld [sMainDataCheckSum], a
241
xor a
242
ld [rBMODE], a
243
ld [rRAMG], a
244
ret
245
246
SaveCurrentBoxData:
247
ld a, RAMG_SRAM_ENABLE
248
ld [rRAMG], a
249
ld a, BMODE_ADVANCED
250
ld [rBMODE], a
251
ASSERT BANK("Save Data") == BMODE_ADVANCED
252
ld [rRAMB], a
253
ld hl, wBoxDataStart
254
ld de, sCurBoxData
255
ld bc, wBoxDataEnd - wBoxDataStart
256
call CopyData
257
ld hl, sGameData
258
ld bc, sGameDataEnd - sGameData
259
call CalcCheckSum
260
ld [sMainDataCheckSum], a
261
xor a
262
ld [rBMODE], a
263
ld [rRAMG], a
264
ret
265
266
SavePartyAndDexData:
267
ld a, RAMG_SRAM_ENABLE
268
ld [rRAMG], a
269
ld a, BMODE_ADVANCED
270
ld [rBMODE], a
271
ASSERT BANK("Save Data") == BMODE_ADVANCED
272
ld [rRAMB], a
273
ld hl, wPartyDataStart
274
ld de, sPartyData
275
ld bc, wPartyDataEnd - wPartyDataStart
276
call CopyData
277
ld hl, wPokedexOwned ; pokédex only
278
ld de, sMainData
279
ld bc, wPokedexSeenEnd - wPokedexOwned
280
call CopyData
281
ld hl, sGameData
282
ld bc, sGameDataEnd - sGameData
283
call CalcCheckSum
284
ld [sMainDataCheckSum], a
285
xor a
286
ld [rBMODE], a
287
ld [rRAMG], a
288
ret
289
290
SaveGameData::
291
ld a, $2
292
ld [wSaveFileStatus], a
293
call SaveMainData
294
call SaveCurrentBoxData
295
jp SavePartyAndDexData
296
297
CalcCheckSum:
298
;Check Sum (result[1 byte] is complemented)
299
ld d, 0
300
.loop
301
ld a, [hli]
302
add d
303
ld d, a
304
dec bc
305
ld a, b
306
or c
307
jr nz, .loop
308
ld a, d
309
cpl
310
ret
311
312
CalcIndividualBoxCheckSums:
313
ld hl, sBox1 ; sBox7
314
ld de, sBank2IndividualBoxChecksums ; sBank3IndividualBoxChecksums
315
ld b, NUM_BOXES / 2
316
.loop
317
push bc
318
push de
319
ld bc, wBoxDataEnd - wBoxDataStart
320
call CalcCheckSum
321
pop de
322
ld [de], a
323
inc de
324
pop bc
325
dec b
326
jr nz, .loop
327
ret
328
329
GetBoxSRAMLocation:
330
; in: a = box num
331
; out: b = box SRAM bank, hl = pointer to start of box
332
ld hl, BoxSRAMPointerTable
333
ld a, [wCurrentBoxNum]
334
and BOX_NUM_MASK
335
cp NUM_BOXES / 2
336
ld b, 2
337
jr c, .next
338
inc b
339
sub NUM_BOXES / 2
340
.next
341
ld e, a
342
ld d, 0
343
add hl, de
344
add hl, de
345
ld a, [hli]
346
ld h, [hl]
347
ld l, a
348
ret
349
350
BoxSRAMPointerTable:
351
dw sBox1 ; sBox7
352
dw sBox2 ; sBox8
353
dw sBox3 ; sBox9
354
dw sBox4 ; sBox10
355
dw sBox5 ; sBox11
356
dw sBox6 ; sBox12
357
358
ChangeBox::
359
ld hl, WhenYouChangeBoxText
360
call PrintText
361
call YesNoChoice
362
ld a, [wCurrentMenuItem]
363
and a
364
ret nz ; return if No was chosen
365
ld hl, wCurrentBoxNum
366
bit BIT_HAS_CHANGED_BOXES, [hl] ; is it the first time player is changing the box?
367
call z, EmptyAllSRAMBoxes ; if so, empty all boxes in SRAM
368
call DisplayChangeBoxMenu
369
call UpdateSprites
370
ld hl, hUILayoutFlags
371
set BIT_DOUBLE_SPACED_MENU, [hl]
372
call HandleMenuInput
373
ld hl, hUILayoutFlags
374
res BIT_DOUBLE_SPACED_MENU, [hl]
375
bit B_PAD_B, a
376
ret nz
377
call GetBoxSRAMLocation
378
ld e, l
379
ld d, h
380
ld hl, wBoxDataStart
381
call CopyBoxToOrFromSRAM ; copy old box from WRAM to SRAM
382
ld a, [wCurrentMenuItem]
383
set BIT_HAS_CHANGED_BOXES, a
384
ld [wCurrentBoxNum], a
385
call GetBoxSRAMLocation
386
ld de, wBoxDataStart
387
call CopyBoxToOrFromSRAM ; copy new box from SRAM to WRAM
388
ld hl, wCurMapTextPtr
389
ld de, wChangeBoxSavedMapTextPointer
390
ld a, [hli]
391
ld [de], a
392
inc de
393
ld a, [hl]
394
ld [de], a
395
call RestoreMapTextPointer
396
call SaveGameData
397
ld hl, wChangeBoxSavedMapTextPointer
398
call SetMapTextPointer
399
ld a, SFX_SAVE
400
call PlaySoundWaitForCurrent
401
call WaitForSoundToFinish
402
ret
403
404
WhenYouChangeBoxText:
405
text_far _WhenYouChangeBoxText
406
text_end
407
408
CopyBoxToOrFromSRAM:
409
; copy an entire box from hl to de with b as the SRAM bank
410
push hl
411
ld a, RAMG_SRAM_ENABLE
412
ld [rRAMG], a
413
ld a, BMODE_ADVANCED
414
ld [rBMODE], a
415
ld a, b
416
ld [rRAMB], a
417
ld bc, wBoxDataEnd - wBoxDataStart
418
call CopyData
419
pop hl
420
421
; mark the source box as an empty box
422
xor a
423
ld [hli], a
424
dec a
425
ld [hl], a
426
427
ld hl, sBox1 ; sBox7
428
ld bc, sBank2AllBoxesChecksum - sBox1
429
call CalcCheckSum
430
ld [sBank2AllBoxesChecksum], a ; sBank3AllBoxesChecksum
431
call CalcIndividualBoxCheckSums
432
xor a
433
ld [rBMODE], a
434
ld [rRAMG], a
435
ret
436
437
DisplayChangeBoxMenu:
438
xor a
439
ldh [hAutoBGTransferEnabled], a
440
ld a, PAD_A | PAD_B
441
ld [wMenuWatchedKeys], a
442
ld a, 11
443
ld [wMaxMenuItem], a
444
ld a, 1
445
ld [wTopMenuItemY], a
446
ld a, 12
447
ld [wTopMenuItemX], a
448
xor a
449
ld [wMenuWatchMovingOutOfBounds], a
450
ld a, [wCurrentBoxNum]
451
and BOX_NUM_MASK
452
ld [wCurrentMenuItem], a
453
ld [wLastMenuItem], a
454
hlcoord 0, 0
455
ld b, 2
456
ld c, 9
457
call TextBoxBorder
458
ld hl, ChooseABoxText
459
call PrintText
460
hlcoord 11, 0
461
ld b, 12
462
ld c, 7
463
call TextBoxBorder
464
ld hl, hUILayoutFlags
465
set BIT_SINGLE_SPACED_LINES, [hl]
466
ld de, BoxNames
467
hlcoord 13, 1
468
call PlaceString
469
ld hl, hUILayoutFlags
470
res BIT_SINGLE_SPACED_LINES, [hl]
471
ld a, [wCurrentBoxNum]
472
and BOX_NUM_MASK
473
cp 9
474
jr c, .singleDigitBoxNum
475
sub 9
476
hlcoord 8, 2
477
ld [hl], "1"
478
add "0"
479
jr .next
480
.singleDigitBoxNum
481
add "1"
482
.next
483
ldcoord_a 9, 2
484
hlcoord 1, 2
485
ld de, BoxNoText
486
call PlaceString
487
call GetMonCountsForAllBoxes
488
hlcoord 18, 1
489
ld de, wBoxMonCounts
490
ld bc, SCREEN_WIDTH
491
ld a, NUM_BOXES
492
.loop
493
push af
494
ld a, [de]
495
and a ; is the box empty?
496
jr z, .skipPlacingPokeball
497
ld [hl], $78 ; place pokeball tile next to box name if box not empty
498
.skipPlacingPokeball
499
add hl, bc
500
inc de
501
pop af
502
dec a
503
jr nz, .loop
504
ld a, 1
505
ldh [hAutoBGTransferEnabled], a
506
ret
507
508
ChooseABoxText:
509
text_far _ChooseABoxText
510
text_end
511
512
BoxNames:
513
db "BOX 1"
514
next "BOX 2"
515
next "BOX 3"
516
next "BOX 4"
517
next "BOX 5"
518
next "BOX 6"
519
next "BOX 7"
520
next "BOX 8"
521
next "BOX 9"
522
next "BOX10"
523
next "BOX11"
524
next "BOX12@"
525
526
BoxNoText:
527
db "BOX No.@"
528
529
EmptyAllSRAMBoxes:
530
; marks all boxes in SRAM as empty (initialisation for the first time the
531
; player changes the box)
532
ld a, RAMG_SRAM_ENABLE
533
ld [rRAMG], a
534
ld a, BMODE_ADVANCED
535
ld [rBMODE], a
536
ld a, BANK("Saved Boxes 1")
537
ld [rRAMB], a
538
call EmptySRAMBoxesInBank
539
ld a, BANK("Saved Boxes 2")
540
ld [rRAMB], a
541
call EmptySRAMBoxesInBank
542
xor a
543
ld [rBMODE], a
544
ld [rRAMG], a
545
ret
546
547
EmptySRAMBoxesInBank:
548
; marks every box in the current SRAM bank as empty
549
ld hl, sBox1 ; sBox7
550
call EmptySRAMBox
551
ld hl, sBox2 ; sBox8
552
call EmptySRAMBox
553
ld hl, sBox3 ; sBox9
554
call EmptySRAMBox
555
ld hl, sBox4 ; sBox10
556
call EmptySRAMBox
557
ld hl, sBox5 ; sBox11
558
call EmptySRAMBox
559
ld hl, sBox6 ; sBox12
560
call EmptySRAMBox
561
ld hl, sBox1 ; sBox7
562
ld bc, sBank2AllBoxesChecksum - sBox1
563
call CalcCheckSum
564
ld [sBank2AllBoxesChecksum], a ; sBank3AllBoxesChecksum
565
call CalcIndividualBoxCheckSums
566
ret
567
568
EmptySRAMBox:
569
xor a
570
ld [hli], a
571
dec a
572
ld [hl], a
573
ret
574
575
GetMonCountsForAllBoxes:
576
ld hl, wBoxMonCounts
577
push hl
578
ld a, RAMG_SRAM_ENABLE
579
ld [rRAMG], a
580
ld a, BMODE_ADVANCED
581
ld [rBMODE], a
582
ld a, BANK("Saved Boxes 1")
583
ld [rRAMB], a
584
call GetMonCountsForBoxesInBank
585
ld a, BANK("Saved Boxes 2")
586
ld [rRAMB], a
587
call GetMonCountsForBoxesInBank
588
xor a
589
ld [rBMODE], a
590
ld [rRAMG], a
591
pop hl
592
593
; copy the count for the current box from WRAM
594
ld a, [wCurrentBoxNum]
595
and BOX_NUM_MASK
596
ld c, a
597
ld b, 0
598
add hl, bc
599
ld a, [wBoxCount]
600
ld [hl], a
601
602
ret
603
604
GetMonCountsForBoxesInBank:
605
ld a, [sBox1] ; sBox7
606
ld [hli], a
607
ld a, [sBox2] ; sBox8
608
ld [hli], a
609
ld a, [sBox3] ; sBox9
610
ld [hli], a
611
ld a, [sBox4] ; sBox10
612
ld [hli], a
613
ld a, [sBox5] ; sBox11
614
ld [hli], a
615
ld a, [sBox6] ; sBox12
616
ld [hli], a
617
ret
618
619
; check if we're trying to save over a different playthrough
620
; return result in zero flag
621
; z set: a valid save file was found, and saved PlayerID is different from wPlayerID
622
CheckPreviousSaveFile:
623
ld a, RAMG_SRAM_ENABLE
624
ld [rRAMG], a
625
ld a, BMODE_ADVANCED
626
ld [rBMODE], a
627
ASSERT BANK("Save Data") == BMODE_ADVANCED
628
ld [rRAMB], a
629
ld a, [sPlayerName]
630
and a
631
jr z, .next
632
ld hl, sGameData
633
ld bc, sGameDataEnd - sGameData
634
call CalcCheckSum
635
ld c, a
636
ld a, [sMainDataCheckSum]
637
cp c
638
jr nz, .next ; return z set if save data is corrupted
639
ld hl, sMainData + (wPlayerID - wMainDataStart) ; player ID
640
ld a, [hli]
641
ld h, [hl]
642
ld l, a
643
ld a, [wPlayerID]
644
cp l
645
jr nz, .next
646
ld a, [wPlayerID + 1]
647
cp h
648
.next
649
ld a, BMODE_SIMPLE
650
ld [rBMODE], a
651
ASSERT RAMG_SRAM_DISABLE == BMODE_SIMPLE
652
ld [rRAMG], a
653
ret
654
655
SaveHallOfFameTeams:
656
ld a, [wNumHoFTeams]
657
dec a
658
cp HOF_TEAM_CAPACITY
659
jr nc, .shiftHOFTeams
660
ld hl, sHallOfFame
661
ld bc, HOF_TEAM
662
call AddNTimes
663
ld e, l
664
ld d, h
665
ld hl, wHallOfFame
666
ld bc, HOF_TEAM
667
jr HallOfFame_Copy
668
669
.shiftHOFTeams
670
; if the space designated for HOF teams is full, then shift all HOF teams to the next slot, making space for the new HOF team
671
; this deletes the last HOF team though
672
ld hl, sHallOfFame + HOF_TEAM
673
ld de, sHallOfFame
674
ld bc, HOF_TEAM * (HOF_TEAM_CAPACITY - 1)
675
call HallOfFame_Copy
676
ld hl, wHallOfFame
677
ld de, sHallOfFame + HOF_TEAM * (HOF_TEAM_CAPACITY - 1)
678
ld bc, HOF_TEAM
679
jr HallOfFame_Copy
680
681
LoadHallOfFameTeams:
682
ld hl, sHallOfFame
683
ld bc, HOF_TEAM
684
ld a, [wHoFTeamIndex]
685
call AddNTimes
686
ld de, wHallOfFame
687
ld bc, HOF_TEAM
688
; fallthrough
689
690
HallOfFame_Copy:
691
ld a, RAMG_SRAM_ENABLE
692
ld [rRAMG], a
693
ld a, BMODE_ADVANCED
694
ld [rBMODE], a
695
xor a
696
ld [rRAMB], a
697
call CopyData
698
xor a
699
ld [rBMODE], a
700
ld [rRAMG], a
701
ret
702
703
; Fill SRAM with $ff, erasing save data. Used by DoClearSaveDialogue
704
ClearAllSRAMBanks:
705
ld a, RAMG_SRAM_ENABLE
706
ld [rRAMG], a
707
ld a, BMODE_ADVANCED
708
ld [rBMODE], a
709
xor a
710
call .PadSRAM_FF
711
ld a, 1
712
call .PadSRAM_FF
713
ld a, 2
714
call .PadSRAM_FF
715
ld a, 3
716
call .PadSRAM_FF
717
xor a
718
ld [rBMODE], a
719
ld [rRAMG], a
720
ret
721
722
.PadSRAM_FF
723
ld [rRAMB], a
724
ld hl, STARTOF(SRAM)
725
ld bc, SIZEOF(SRAM)
726
ld a, $ff
727
jp FillMemory
728
729