-
Notifications
You must be signed in to change notification settings - Fork 0
/
nvram.cp
672 lines (546 loc) · 19.1 KB
/
nvram.cp
1
/****************************************************************************************//* NVRAM.CP *//****************************************************************************************//* (c) 1995 by Magnet Interactive Studios, inc. All rights reserved. *//****************************************************************************************//* Revision History: *//* v5.6 5/5/95 Icebreaker Golden Master version. By Andrew Looney. *//****************************************************************************************//***************************** WHAT THIS SOFTWARE DOES ********************************** All of the functions in this file relate to the storage and retrieval of NVRAM files.Some are generic NVRAM access functions provided by 3DO, and some are specific toIcebreaker. The later are functions that save and read bit sequences that indicatewhether a given level has been completed, or not.*****************************************************************************************//***** includes (make sure CPlusSwiHack.h is the last one) *****/#include "graphics.h"#include "stdio.h"#include "stdlib.h"#include "mem.h"#include "types.h"#include "hardware.h"#include "event.h"#include "strings.h"#include "access.h"#include "UMemory.h"#include "Form3DO.h"#include "Init3DO.h"#include "Parse3DO.h"#include "Utils3DO.h"#include "audio.h"#include "music.h"/***** Magnet includes *****/#include "icebreaker.h"#include "levels.h"#include "nvram.h"#include "userif.h"#include "PlayMusic.h"/***** special c++ include (this must be last) *****/#include "CPlusSwiHack.h"extern status_file_format stat_file;extern int32 music_state;extern Player ctx;extern int16 g_skill_level;extern unsigned long tracks;extern bool standard_musical_selections;/****************************** FetchDifficultyAndTracks ******************************** The custom selections of musical track and the current setting of the difficulty levelare stored in a single 32 bit word in the NVRAM file. This function retrieves these twovalues. This is done only during initialization.*****************************************************************************************/extern void FetchDifficultyAndTracks (char file_name[]){ Item nvram_file_id; nvram_file_id = OpenDiskFile(file_name); if (nvram_file_id < 0) { printf("Warning: no Icebreaker record file exists.\n"); tracks = 0x3FFFF; g_skill_level = HARD; return; } ReadDiskFile(nvram_file_id, (char *) &stat_file, MAX_FILE_DATA_LENGTH); tracks = stat_file.difficulty_and_tracks & 0x3FFFF; switch (stat_file.difficulty_and_tracks >> 20) { case 1: g_skill_level = EASY; break; case 2: g_skill_level = MEDIUM; break; case 4: g_skill_level = HARD; break; case 8: g_skill_level = INSANE; break; } if (tracks != 0x3FFFF) standard_musical_selections = FALSE; if (CloseDiskFile(nvram_file_id) < 0) printf("Warning: Unable to close NVRAM file.\n");}/****************************** UpdateDifficultyAndTracks ******************************** The custom selections of musical track and the current setting of the difficulty levelare stored in a single 32 bit word in the NVRAM file. This function updates the contentsof the NVRAM file with both of these values. This is done any time either of these valueschanges, so that they are both always kept up to date.*****************************************************************************************/void UpdateDifficultyAndTracks (char file_name[]){ Item nvram_file_id; nvram_file_id = OpenDiskFile(file_name); if (nvram_file_id < 0) { printf("Note: Creating new Icebreaker record file in NVRAM.\n"); if (CreateDiskFile(file_name, MAX_FILE_DATA_LENGTH) < 0) { printf("Error: Unable to create file.\n"); return; } nvram_file_id = OpenDiskFile(file_name); if (nvram_file_id < 0) { printf("Error: Unable to open file after creating it.\n"); return; } memset(&stat_file, 0, sizeof(stat_file)); stat_file.developer_id = MAGNET_3D0_DEVELOPER_ID_NUMBER; if (WriteDiskFile(nvram_file_id, (char *) &stat_file, MAX_FILE_DATA_LENGTH) < 0) printf("Error: NVRAM Write operation failed.\n"); SetEndOfFile(nvram_file_id, MAX_FILE_DATA_LENGTH); } ReadDiskFile(nvram_file_id, (char *) &stat_file, MAX_FILE_DATA_LENGTH); stat_file.difficulty_and_tracks = tracks; switch (g_skill_level) { case EASY: stat_file.difficulty_and_tracks |= 0x100000; break; case MEDIUM: stat_file.difficulty_and_tracks |= 0x200000; break; case HARD: stat_file.difficulty_and_tracks |= 0x400000; break; case INSANE: stat_file.difficulty_and_tracks |= 0x800000; break; } if (WriteDiskFile(nvram_file_id, (char *) &stat_file, MAX_FILE_DATA_LENGTH) < 0) printf("Error: NVRAM Write operation failed.\n"); SetEndOfFile(nvram_file_id, MAX_FILE_DATA_LENGTH); if (CloseDiskFile(nvram_file_id) < 0) printf("Warning: Unable to close NVRAM file.\n");}/********************************* CheckForVictory ************************************* This function is used in 3 cases: a) checking to see if the level just completed is the last one needed to finish the first 30 levels and therefore initiate showing of the victory movie; b) checking to see if the level just completed is the last one needed to finish all 150 levels and therefore initiate display of the "you did it all" screen; c) checking to see if all of the first 30 levels have been completed, for the case in which a user wishes to watch the victory movie from the play movie interface.*****************************************************************************************/bool CheckForVictory (char file_name[], int32 level, int32 number_of_levels_to_check){ Item nvram_file_id; int32 i; int32 holes; int32 most_recent_hole; bool return_value; most_recent_hole = -1; holes = 0; nvram_file_id = OpenDiskFile(file_name); if (nvram_file_id < 0) { printf("Warning: no Icebreaker record file exists.\n"); return(FALSE); } ReadDiskFile(nvram_file_id, (char *) &stat_file, MAX_FILE_DATA_LENGTH); for (i = 0; i < number_of_levels_to_check/2; i++) { if (!((stat_file.level_stats[i]) & 0xF0)) { most_recent_hole = (i * 2) + 1; holes++; } if (!((stat_file.level_stats[i]) & 0x0F)) { most_recent_hole = (i + 1) * 2; holes++; } } if (CloseDiskFile(nvram_file_id) < 0) printf("Warning: Unable to close NVRAM file.\n"); return_value = FALSE; if ((holes == 0) && (level == -100)) { printf("all %ld levels have been completed.\n",number_of_levels_to_check); return_value = TRUE; } if ((holes == 1) && (most_recent_hole == level)) { printf("You've just finished the last of %ld levels.\n",number_of_levels_to_check); return_value = TRUE; } return(return_value);}/*********************************** FakeCompletion ************************************** This function is for testing only. It sets the level flags in the NVRAM file to falsifythe records and give credit for finishing levels that haven't really been finished.*****************************************************************************************/void FakeCompletion(int32 first_level, int32 last_level){int32 i; for (i = first_level; i <= last_level; i++) SetLevelFlagInStatusRecordFile(NVRAM_FILE_NAME, i, RandomNumber(EASY, INSANE));}/*************************** SetLevelFlagInStatusRecordFile ****************************** This function takes as input the name of a level statistics file, a level number, anda skill mode, and then updates the appropriate bit in said level statistics file thatindicates that said level was completed at said skill level setting. If the level statistics file specified does not exist, this function creates it.*****************************************************************************************/void SetLevelFlagInStatusRecordFile (char file_name[], int32 level, int32 mode){ Item nvram_file_id; char temp; if (CheckForVictory (file_name, level, 150)) { STOP_THE_MUSIC; PlayVideoStream(VICTORY_MOVIE); DisplayMessageScreen(YOU_DID_IT_ALL_MESSAGE); } else if (CheckForVictory (file_name, level, 30)) { STOP_THE_MUSIC; PlayVideoStream(VICTORY_MOVIE); } if ((MAXIMUM_LEVELS / 2) > MAX_LEVEL_STAT_ELEMENTS) printf("Warning: More levels exist than there is space for in the stat file.\n"); nvram_file_id = OpenDiskFile(file_name); if (nvram_file_id < 0) { printf("Note: Creating new Icebreaker record file in NVRAM.\n"); if (CreateDiskFile(file_name, MAX_FILE_DATA_LENGTH) < 0) { printf("Error: Unable to create file.\n"); DisplayMessageScreen(NVRAM_FULL_MESSAGE); return; } nvram_file_id = OpenDiskFile(file_name); if (nvram_file_id < 0) { printf("Error: Unable to open file after creating it.\n"); return; } memset(&stat_file, 0, sizeof(stat_file)); stat_file.developer_id = MAGNET_3D0_DEVELOPER_ID_NUMBER; stat_file.difficulty_and_tracks = tracks; switch (g_skill_level) { case EASY: stat_file.difficulty_and_tracks |= 0x100000; break; case MEDIUM: stat_file.difficulty_and_tracks |= 0x200000; break; case HARD: stat_file.difficulty_and_tracks |= 0x400000; break; case INSANE: stat_file.difficulty_and_tracks |= 0x800000; break; } if (WriteDiskFile(nvram_file_id, (char *) &stat_file, MAX_FILE_DATA_LENGTH) < 0) printf("Error: NVRAM Write operation failed.\n"); SetEndOfFile(nvram_file_id, MAX_FILE_DATA_LENGTH); } if ((level < 1) || (level > MAXIMUM_LEVELS)) { if (CloseDiskFile(nvram_file_id) < 0) printf("Warning: Unable to close NVRAM file.\n"); return; } ReadDiskFile(nvram_file_id, (char *) &stat_file, MAX_FILE_DATA_LENGTH); level--; temp = stat_file.level_stats[level/2]; if (level % 2 == 1) { switch (mode) { case EASY: temp |= 0x01; break; case MEDIUM: temp |= 0x02; break; case HARD: temp |= 0x04; break; case INSANE: temp |= 0x08; break; } } else { switch (mode) { case EASY: temp |= 0x10; break; case MEDIUM: temp |= 0x20; break; case HARD: temp |= 0x40; break; case INSANE: temp |= 0x80; break; } } stat_file.level_stats[level/2] = temp; if (WriteDiskFile(nvram_file_id, (char *) &stat_file, MAX_FILE_DATA_LENGTH) < 0) printf("Error: NVRAM Write operation failed.\n"); SetEndOfFile(nvram_file_id, MAX_FILE_DATA_LENGTH); if (CloseDiskFile(nvram_file_id) < 0) printf("Warning: Unable to close NVRAM file.\n");}/******************************** DumpStatusRecordFile *********************************** This function takes as input the name of a level statistics file and generates a listof all the levels that have been completed, in which skill mode settings. This functionwill become pretty much useless after a graphical method for displaying the status recordinformation is developed.*****************************************************************************************/void DumpStatusRecordFile (char file_name[]){ Item nvram_file_id; int32 i; if ((MAXIMUM_LEVELS / 2) > MAX_LEVEL_STAT_ELEMENTS) printf("Warning: More levels exist than there is space for in the stat file.\n"); nvram_file_id = OpenDiskFile(file_name); if (nvram_file_id < 0) { printf("Warning: no Icebreaker record file exists.\n"); return; } ReadDiskFile(nvram_file_id, (char *) &stat_file, MAX_FILE_DATA_LENGTH); if (stat_file.developer_id != MAGNET_3D0_DEVELOPER_ID_NUMBER) printf("Warning: Icebreaker data file does not have proper developer id number!\n"); printf("===========================================================\n"); for (i = 0; i < MAXIMUM_LEVELS/2; i++) { if ((stat_file.level_stats[i]) & 0xF0) { printf("Level %ld completed in these modes: ",(i * 2) + 1); if ((stat_file.level_stats[i]) & 0x10) printf("EASY "); if ((stat_file.level_stats[i]) & 0x20) printf("MEDIUM "); if ((stat_file.level_stats[i]) & 0x40) printf("HARD "); if ((stat_file.level_stats[i]) & 0x80) printf("INSANE "); printf("\n"); } if ((stat_file.level_stats[i]) & 0x0F) { printf("Level %ld completed in these modes: ",((i + 1) * 2)); if ((stat_file.level_stats[i]) & 0x01) printf("EASY "); if ((stat_file.level_stats[i]) & 0x02) printf("MEDIUM "); if ((stat_file.level_stats[i]) & 0x04) printf("HARD "); if ((stat_file.level_stats[i]) & 0x08) printf("INSANE "); printf("\n"); } } printf("===========================================================\n"); if (CloseDiskFile(nvram_file_id) < 0) printf("Warning: Unable to close NVRAM file.\n");}/******************************* ZeroOutStatusRecordFile ********************************* This function takes as input the name of a level statistics file and zeros it out.*****************************************************************************************/void ZeroOutStatusRecordFile (char file_name[]){ Item nvram_file_id; nvram_file_id = OpenDiskFile(file_name); if (nvram_file_id < 0) { printf("Note: Creating new Icebreaker record file in NVRAM.\n"); if (CreateDiskFile(file_name, MAX_FILE_DATA_LENGTH) < 0) { printf("Error: Unable to create file.\n"); DisplayMessageScreen(NVRAM_FULL_MESSAGE); return; } nvram_file_id = OpenDiskFile(file_name); if (nvram_file_id < 0) { printf("Error: Unable to open file after creating it.\n"); return; } } memset(&stat_file, 0, sizeof(stat_file)); stat_file.developer_id = MAGNET_3D0_DEVELOPER_ID_NUMBER; stat_file.difficulty_and_tracks = tracks; switch (g_skill_level) { case EASY: stat_file.difficulty_and_tracks |= 0x100000; break; case MEDIUM: stat_file.difficulty_and_tracks |= 0x200000; break; case HARD: stat_file.difficulty_and_tracks |= 0x400000; break; case INSANE: stat_file.difficulty_and_tracks |= 0x800000; break; } if (WriteDiskFile(nvram_file_id, (char *) &stat_file, MAX_FILE_DATA_LENGTH) < 0) printf("Error: NVRAM Write operation failed.\n"); SetEndOfFile(nvram_file_id, MAX_FILE_DATA_LENGTH); if (nvram_file_id >= 0) if (CloseDiskFile(nvram_file_id) < 0) printf("Warning: Unable to close NVRAM file.\n");}/******************************** GetFileBlockSize ************************************* This function is provided by 3DO for use in accessing files in NVRAM.*****************************************************************************************/Err GetFileBlockSize(Item fileItem, uint32* blockSize){ int32 err; IOInfo fileInfo; FileStatus status; Item ioReqItem; IOReq* ioReqP; *blockSize = 0; ioReqItem = CreateIOReq((char *) NULL, 0, fileItem, 0); if (ioReqItem >= 0) { memset(&fileInfo, 0, sizeof(IOInfo)); fileInfo.ioi_Command = CMD_STATUS; fileInfo.ioi_Recv.iob_Buffer = &status; fileInfo.ioi_Recv.iob_Len = sizeof(FileStatus); ioReqP = (IOReq*) LookupItem(ioReqItem); err = DoIO(ioReqItem, &fileInfo); if (err >= 0) { // see if the device returned an error err = ioReqP->io_Error; } DeleteIOReq(ioReqItem); if (err == 0) *blockSize = status.fs.ds_DeviceBlockSize; } else { err = ioReqItem; } return err;}/********************************* CreateDiskFile ************************************** This function is provided by 3DO for use in accessing files in NVRAM.*****************************************************************************************/Err CreateDiskFile(char* fileName, uint32 numberOfBytes){ Err err; Item fileItem; Item ioReqItem; IOReq* ioReqP; uint32 numberOfBlocks, blockSize; fileItem = CreateFile(fileName); err = (fileItem < 0) ? fileItem : 0; if (err == 0) { fileItem = OpenDiskFile(fileName); err = (fileItem < 0) ? fileItem : 0; if (err == 0) { err = GetFileBlockSize(fileItem, &blockSize); if (err == 0) { numberOfBlocks = (numberOfBytes / blockSize); if ((numberOfBytes % blockSize) > 0) numberOfBlocks++; ioReqItem = CreateIOReq((char *) NULL, 0, fileItem, 0); if (ioReqItem >= 0) { IOInfo fileInfo; memset(&fileInfo, 0, sizeof(IOInfo)); fileInfo.ioi_Command = FILECMD_ALLOCBLOCKS; fileInfo.ioi_Offset = numberOfBlocks; ioReqP = (IOReq*)LookupItem(ioReqItem); err = DoIO(ioReqItem, &fileInfo); if (err >= 0) { // see if device returned an error err = ioReqP->io_Error; } DeleteIOReq(ioReqItem); } else { err = ioReqItem; } } err = CloseDiskFile(fileItem); } else err = fileItem; } return err;}/********************************** WriteDiskFile ************************************** This function is provided by 3DO for use in accessing files in NVRAM.*****************************************************************************************/Err WriteDiskFile(Item fileItem, ubyte *data, int32 numberOfBytes){ int32 err; IOInfo fileInfo; Item ioReqItem; IOReq* ioReqP; err = 0; ioReqItem = CreateIOReq((char *) NULL, 0, fileItem, 0); if (ioReqItem >= 0) { memset(&fileInfo, 0, sizeof(IOInfo)); fileInfo.ioi_Command = CMD_WRITE; fileInfo.ioi_Send.iob_Buffer = data; fileInfo.ioi_Send.iob_Len = (int)numberOfBytes; fileInfo.ioi_Offset = 0; ioReqP = (IOReq*)LookupItem(ioReqItem); err = DoIO(ioReqItem, &fileInfo); // see if the device returned an error if (err >= 0) err = ioReqP->io_Error; DeleteIOReq(ioReqItem); } else err = ioReqItem; return err;}/*********************************** ReadDiskFile ************************************** This function is provided by 3DO for use in accessing files in NVRAM.*****************************************************************************************/Err ReadDiskFile(Item fileItem, ubyte *data, int32 numberOfBytes){ int32 err; IOInfo fileInfo; Item ioReqItem; IOReq* ioReqP; ioReqItem = CreateIOReq((char *) NULL, 0, fileItem, 0); if (ioReqItem >= 0) { memset(&fileInfo, 0, sizeof(IOInfo)); fileInfo.ioi_Command = CMD_READ; fileInfo.ioi_Recv.iob_Buffer = data; fileInfo.ioi_Recv.iob_Len = numberOfBytes; fileInfo.ioi_Offset = 0; ioReqP = (IOReq*)LookupItem(ioReqItem); err = DoIO(ioReqItem, &fileInfo); if (err >= 0) { // see if the device returned an error err = ioReqP->io_Error; } DeleteIOReq(ioReqItem); } else { err = ioReqItem; } return err;}/*********************************** SetEndOfFile ************************************** This function is provided by 3DO for use in accessing files in NVRAM.*****************************************************************************************/Err SetEndOfFile(Item fileItem, int32 endOfFile){ int32 err; IOInfo fileInfo; Item ioReqItem; IOReq* ioReqP; ioReqItem = CreateIOReq((char *) NULL, 0, fileItem, 0); if (ioReqItem >= 0) { memset(&fileInfo, 0, sizeof(IOInfo)); fileInfo.ioi_Command = FILECMD_SETEOF; fileInfo.ioi_Offset = endOfFile; ioReqP = (IOReq*)LookupItem(ioReqItem); err = DoIO(ioReqItem, &fileInfo); if (err >= 0) { // see if the device returned an error err = ioReqP->io_Error; } DeleteIOReq(ioReqItem); } else { err = ioReqItem; } return err;}/************************************* End of File **************************************/