void JE_loadPic(SDL_Surface *screen, uint8_t PCXnumber, bool storepal ) { PCXnumber--; FILE *f = dir_fopen_die(data_dir(), "tyrian.pic", "rb"); static bool first = true; if (first) { first = false; uint16_t temp; efread(&temp, sizeof(uint16_t), 1, f); for (int i = 0; i < PCX_NUM; i++) { efread(&pcxpos[i], sizeof(int32_t), 1, f); } pcxpos[PCX_NUM] = ftell_eof(f); } uint32_t size = pcxpos[PCXnumber + 1] - pcxpos[PCXnumber]; uint8_t *buffer = malloc(size); fseek(f, pcxpos[PCXnumber], SEEK_SET); efread(buffer, sizeof(uint8_t), size, f); fclose(f); uint8_t *p = buffer; uint8_t *s; /* screen pointer, 8-bit specific */ s = (uint8_t *)screen->pixels; for (int i = 0; i < 320 * 200; ) { if ((*p & 0xc0) == 0xc0) { i += (*p & 0x3f); memset(s, *(p + 1), (*p & 0x3f)); s += (*p & 0x3f); p += 2; } else { i++; *s = *p; s++; p++; } if (i && (i % 320 == 0)) { s += screen->pitch - 320; } } free(buffer); memcpy(colors, palettes[pcxpal[PCXnumber]], sizeof(colors)); if (storepal) set_palette(colors, 0, 255); }
void JE_loadCompShapes( Sprite2_array *sprite2s, char s ) { char buffer[20]; snprintf(buffer, sizeof(buffer), "newsh%c.shp", tolower((unsigned char)s)); FILE *f = dir_fopen_die(data_dir(), buffer, "rb"); sprite2s->size = ftell_eof(f); JE_loadCompShapesB(sprite2s, f); fclose(f); }
void JE_analyzeLevel( void ) { FILE *f = dir_fopen_die(data_dir(), levelFile, "rb"); efread(&lvlNum, sizeof(JE_word), 1, f); for (int x = 0; x < lvlNum; x++) efread(&lvlPos[x], sizeof(JE_longint), 1, f); lvlPos[lvlNum] = ftell_eof(f); fclose(f); }
void load_music( void ) { if (music_file == NULL) { music_file = dir_fopen_die(data_dir(), "music.mus", "rb"); efread(&song_count, sizeof(song_count), 1, music_file); song_offset = malloc((song_count + 1) * sizeof(song_offset)); efread(song_offset, 4, song_count, music_file); song_offset[song_count] = ftell_eof(music_file); } }
cJSON *load_json( const char *filename ) { FILE *f = dir_fopen_warn(get_user_directory(), filename, "rb"); if (f == NULL) return NULL; size_t buffer_len = ftell_eof(f); char *buffer = malloc(buffer_len + 1); fread(buffer, 1, buffer_len, f); buffer[buffer_len] = '\0'; fclose(f); cJSON *root = cJSON_Parse(buffer); free(buffer); return root; }
void JE_loadConfiguration( void ) { FILE *fi; int z; JE_byte *p; int y; fi = dir_fopen_warn(get_user_directory(), "tyrian.cfg", "rb"); if (fi && ftell_eof(fi) == 20 + sizeof(keySettings)) { /* SYN: I've hardcoded the sizes here because the .CFG file format is fixed anyways, so it's not like they'll change. */ background2 = 0; efread(&background2, 1, 1, fi); efread(&gameSpeed, 1, 1, fi); efread(&inputDevice_, 1, 1, fi); efread(&jConfigure, 1, 1, fi); efread(&versionNum, 1, 1, fi); efread(&processorType, 1, 1, fi); efread(&midiPort, 1, 1, fi); efread(&soundEffects, 1, 1, fi); efread(&gammaCorrection, 1, 1, fi); efread(&difficultyLevel, 1, 1, fi); efread(joyButtonAssign, 1, 4, fi); efread(&tyrMusicVolume, 2, 1, fi); efread(&fxVolume, 2, 1, fi); efread(inputDevice, 1, 2, fi); efread(keySettings, sizeof(*keySettings), COUNTOF(keySettings), fi); fclose(fi); } else { printf("\nInvalid or missing TYRIAN.CFG! Continuing using defaults.\n\n"); soundEffects = 1; memcpy(&keySettings, &defaultKeySettings, sizeof(keySettings)); background2 = true; tyrMusicVolume = fxVolume = 128; gammaCorrection = 0; processorType = 3; gameSpeed = 4; } load_opentyrian_config(); if (tyrMusicVolume > 255) tyrMusicVolume = 255; if (fxVolume > 255) fxVolume = 255; JE_calcFXVol(); set_volume(tyrMusicVolume, fxVolume); fi = dir_fopen_warn(get_user_directory(), "tyrian.sav", "rb"); if (fi) { fseek(fi, 0, SEEK_SET); efread(saveTemp, 1, sizeof(saveTemp), fi); JE_decryptSaveTemp(); /* SYN: The original mostly blasted the save file into raw memory. However, our lives are not so easy, because the C struct is necessarily a different size. So instead we have to loop through each record and load fields manually. *emo tear* :'( */ p = saveTemp; for (z = 0; z < SAVE_FILES_NUM; z++) { memcpy(&saveFiles[z].encode, p, sizeof(JE_word)); p += 2; saveFiles[z].encode = SDL_SwapLE16(saveFiles[z].encode); memcpy(&saveFiles[z].level, p, sizeof(JE_word)); p += 2; saveFiles[z].level = SDL_SwapLE16(saveFiles[z].level); memcpy(&saveFiles[z].items, p, sizeof(JE_PItemsType)); p += sizeof(JE_PItemsType); memcpy(&saveFiles[z].score, p, sizeof(JE_longint)); p += 4; saveFiles[z].score = SDL_SwapLE32(saveFiles[z].score); memcpy(&saveFiles[z].score2, p, sizeof(JE_longint)); p += 4; saveFiles[z].score2 = SDL_SwapLE32(saveFiles[z].score2); /* SYN: Pascal strings are prefixed by a byte holding the length! */ memset(&saveFiles[z].levelName, 0, sizeof(saveFiles[z].levelName)); memcpy(&saveFiles[z].levelName, &p[1], *p); p += 10; /* This was a BYTE array, not a STRING, in the original. Go fig. */ memcpy(&saveFiles[z].name, p, 14); p += 14; memcpy(&saveFiles[z].cubes, p, sizeof(JE_byte)); p++; memcpy(&saveFiles[z].power, p, sizeof(JE_byte) * 2); p += 2; memcpy(&saveFiles[z].episode, p, sizeof(JE_byte)); p++; memcpy(&saveFiles[z].lastItems, p, sizeof(JE_PItemsType)); p += sizeof(JE_PItemsType); memcpy(&saveFiles[z].difficulty, p, sizeof(JE_byte)); p++; memcpy(&saveFiles[z].secretHint, p, sizeof(JE_byte)); p++; memcpy(&saveFiles[z].input1, p, sizeof(JE_byte)); p++; memcpy(&saveFiles[z].input2, p, sizeof(JE_byte)); p++; /* booleans were 1 byte in pascal -- working around it */ Uint8 temp; memcpy(&temp, p, 1); p++; saveFiles[z].gameHasRepeated = temp != 0; memcpy(&saveFiles[z].initialDifficulty, p, sizeof(JE_byte)); p++; memcpy(&saveFiles[z].highScore1, p, sizeof(JE_longint)); p += 4; saveFiles[z].highScore1 = SDL_SwapLE32(saveFiles[z].highScore1); memcpy(&saveFiles[z].highScore2, p, sizeof(JE_longint)); p += 4; saveFiles[z].highScore2 = SDL_SwapLE32(saveFiles[z].highScore2); memset(&saveFiles[z].highScoreName, 0, sizeof(saveFiles[z].highScoreName)); memcpy(&saveFiles[z].highScoreName, &p[1], *p); p += 30; memcpy(&saveFiles[z].highScoreDiff, p, sizeof(JE_byte)); p++; } /* SYN: This is truncating to bytes. I have no idea what this is doing or why. */ /* TODO: Figure out what this is about and make sure it isn't broked. */ editorLevel = (saveTemp[SIZEOF_SAVEGAMETEMP - 5] << 8) | saveTemp[SIZEOF_SAVEGAMETEMP - 6]; fclose(fi); } else { /* We didn't have a save file! Let's make up random stuff! */ editorLevel = 800; for (z = 0; z < 100; z++) { saveTemp[SAVE_FILES_SIZE + z] = initialItemAvail[z]; } for (z = 0; z < SAVE_FILES_NUM; z++) { saveFiles[z].level = 0; for (y = 0; y < 14; y++) { saveFiles[z].name[y] = ' '; } saveFiles[z].name[14] = 0; saveFiles[z].highScore1 = ((mt_rand() % 20) + 1) * 1000; if (z % 6 > 2) { saveFiles[z].highScore2 = ((mt_rand() % 20) + 1) * 1000; strcpy(saveFiles[z].highScoreName, defaultTeamNames[mt_rand() % 22]); } else { strcpy(saveFiles[z].highScoreName, defaultHighScoreNames[mt_rand() % 34]); } } } JE_initProcessorType(); }
/* loadAnim opens the file and loads data from it into the header structs. * It should take care to clean up after itself should an error occur. */ int JE_loadAnim( const char *filename ) { uint32_t i, fileSize; char temp[4]; Curlpnum = -1; InFile = dir_fopen(data_dir(), filename, "rb"); if(InFile == NULL) { return(-1); } fileSize = ftell_eof(InFile); if(fileSize < ANIM_OFFSET) { /* We don't know the exact size our file should be yet, * but we do know it should be way more than this */ fclose(InFile); return(-1); } /* Read in the header. The header is 256 bytes long or so, * but that includes a lot of padding as well as several * vars we really don't care about. We shall check the ID and extract * the handful of vars we care about. Every value in the header that * is constant will be ignored. */ efread(&temp, 1, 4, InFile); /* The ID, should equal "LPF " */ fseek(InFile, 2, SEEK_CUR); /* skip over this word */ efread(&FileHeader.nlps, 2, 1, InFile); /* Number of pages */ efread(&FileHeader.nRecords, 4, 1, InFile); /* Number of records */ if (memcmp(temp, "LPF ", 4) != 0 || FileHeader.nlps == 0 || FileHeader.nRecords == 0 || FileHeader.nlps > 256 || FileHeader.nRecords > 65535) { fclose(InFile); return(-1); } /* Read in headers */ fseek(InFile, PAGEHEADER_OFFSET, SEEK_SET); for (i = 0; i < FileHeader.nlps; i++) { efread(&PageHeader[i].baseRecord, 2, 1, InFile); efread(&PageHeader[i].nRecords, 2, 1, InFile); efread(&PageHeader[i].nBytes, 2, 1, InFile); } /* Now we have enough information to calculate the 'expected' file size. * Our calculation SHOULD be equal to fileSize, but we won't begrudge * padding */ if (fileSize < (FileHeader.nlps-1) * ANI_PAGE_SIZE + ANIM_OFFSET + PageHeader[FileHeader.nlps-1].nBytes + PageHeader[FileHeader.nlps-1].nRecords * 2 + 8) { fclose(InFile); return(-1); } /* Now read in the palette. */ fseek(InFile, PALETTE_OFFSET, SEEK_SET); for (i = 0; i < 256; i++) { efread(&colors[i].b, 1, 1, InFile); efread(&colors[i].g, 1, 1, InFile); efread(&colors[i].r, 1, 1, InFile); efread(&colors[i].unused, 1, 1, InFile); } set_palette(colors, 0, 255); /* Whew! That was hard. Let's go grab some beers! */ return(0); }