X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Fgame_sp%2Ffile.c;h=2b8a1755fbd66d1ad559fe76ad9c86dbf4132b19;hp=5a525214b44576414d5e68a76578e6316d15aa6d;hb=c6d59064aa782b8ad71eddac2797fdc50e4858f9;hpb=f926e522aef77158e0011ae5ad2cf8805509d6d1 diff --git a/src/game_sp/file.c b/src/game_sp/file.c index 5a525214..2b8a1755 100644 --- a/src/game_sp/file.c +++ b/src/game_sp/file.c @@ -7,12 +7,20 @@ /* functions for loading Supaplex level */ /* ------------------------------------------------------------------------- */ +void setTapeInfoToDefaults_SP() +{ + native_sp_level.demo.is_available = FALSE; + native_sp_level.demo.length = 0; +} + void setLevelInfoToDefaults_SP() { LevelInfoType *header = &native_sp_level.header; char *empty_title = "-------- EMPTY --------"; int i, x, y; + native_sp_level.game_sp = &game_sp; + native_sp_level.width = SP_STD_PLAYFIELD_WIDTH; native_sp_level.height = SP_STD_PLAYFIELD_HEIGHT; @@ -47,8 +55,7 @@ void setLevelInfoToDefaults_SP() for (i = 0; i < SP_HEADER_SIZE; i++) native_sp_level.header_raw_bytes[i] = 0x20; - native_sp_level.demo.is_available = FALSE; - native_sp_level.demo.length = 0; + setTapeInfoToDefaults_SP(); } void copyInternalEngineVars_SP() @@ -105,10 +112,8 @@ void copyInternalEngineVars_SP() int count; int i, x, y; -#if 1 for (i = 0; preceding_playfield_memory[i] != NULL; i++) preceding_buffer_size += 8; /* eight 16-bit integer values */ -#endif /* needed for engine snapshots */ game_sp.preceding_buffer_size = preceding_buffer_size; @@ -122,25 +127,13 @@ void copyInternalEngineVars_SP() FieldMax = (FieldWidth * FieldHeight) + HeaderSize - 1; LevelMax = (FieldWidth * FieldHeight) - 1; - FileMax = FieldMax + native_sp_level.demo.length; + /* (add one byte for the level number stored as first byte of demo data) */ + FileMax = FieldMax + native_sp_level.demo.length + 1; - PlayField8 = REDIM_1D(sizeof(byte), 0, FileMax + 1 - 1); - DisPlayField = REDIM_1D(sizeof(byte), 0, FieldMax + 1 - 1); -#if 1 + PlayField8 = REDIM_1D(sizeof(byte), 0, FileMax); + DisPlayField = REDIM_1D(sizeof(byte), 0, FieldMax); PlayField16 = REDIM_1D(sizeof(int), -preceding_buffer_size, FieldMax); -#else - PlayField16 = REDIM_1D(sizeof(int), -FieldWidth, FieldMax); -#endif -#if 1 - -#if 0 - /* fill preceding playfield buffer zone with (indestructible) "hardware" */ - for (i = -FieldWidth; i < 0; i++) - PlayField16[i] = 0x20; -#endif - -#if 1 count = 0; for (i = 0; preceding_playfield_memory[i] != NULL; i++) { @@ -169,7 +162,6 @@ void copyInternalEngineVars_SP() s++; } } -#endif count = 0; for (y = 0; y < native_sp_level.height; y++) @@ -187,46 +179,6 @@ void copyInternalEngineVars_SP() PlayField8[i] = 0; } -#if 0 - { - static int x = 0; - - if (x == 1) - { - printf("++++++++"); - printf("----------\n"); - for (i = 0; i < preceding_buffer_size + FieldMax; i++) - { - int x = PlayField16[-preceding_buffer_size + i]; - - printf("%c%c", x & 0xff, x >> 8); - } - printf("----------\n"); - exit(0); - } - - x++; - } -#endif - -#else - - for (i = 0; y = 0; y < native_sp_level.height; y++) - { - for (x = 0; x < native_sp_level.width; x++) - { - PlayField8[i] = native_sp_level.playfield[x][y]; - - PlayField16[i] = PlayField8[i]; - DisPlayField[i] = PlayField8[i]; - PlayField8[i] = 0; - - i++; - } - } - -#endif - if (native_sp_level.demo.is_available) { DemoAvailable = True; @@ -234,30 +186,20 @@ void copyInternalEngineVars_SP() PlayField8[FieldMax + 1] = native_sp_level.demo.level_nr; for (i = 0; i < native_sp_level.demo.length; i++) - PlayField8[FieldMax + i + 2] = native_sp_level.demo.data[i]; + PlayField8[FieldMax + 2 + i] = native_sp_level.demo.data[i]; } AnimationPosTable = REDIM_1D(sizeof(int), 0, LevelMax - 2 * FieldWidth); AnimationSubTable = REDIM_1D(sizeof(byte), 0, LevelMax - 2 * FieldWidth); TerminalState = REDIM_1D(sizeof(byte), 0, FieldMax + 1 - 1); - DemoPointer = FieldMax + 1; - DemoOffset = DemoPointer; - DemoKeyRepeatCounter = 0; - GravityFlag = LInfo.InitialGravity; FreezeZonks = LInfo.InitialFreezeZonks; #if 1 /* this is set by main game tape code to native random generator directly */ #else - -#if 1 - printf("::: file.c: copyInternalEngineVars_SP(): RandomSeed = LInfo.DemoRandomSeed\n"); -#endif - RandomSeed = LInfo.DemoRandomSeed; - #endif LevelLoaded = True; @@ -305,10 +247,6 @@ static void LoadNativeLevelFromFileStream_SP(FILE *file, int width, int height, /* number of special ("gravity") port entries below (maximum 10 allowed) */ header->SpecialPortCount = getFile8Bit(file); -#if 0 - printf("::: num_special_ports == %d\n", header->SpecialPortCount); -#endif - /* database of properties of up to 10 special ports (6 bytes per port) */ for (i = 0; i < SP_MAX_SPECIAL_PORTS; i++) { @@ -321,16 +259,6 @@ static void LoadNativeLevelFromFileStream_SP(FILE *file, int width, int height, which is 2 bytes per tile) */ port->PortLocation = getFile16BitBE(file); /* yes, big endian */ -#if 0 - { - int port_x = (port->PortLocation / 2) % SP_PLAYFIELD_WIDTH; - int port_y = (port->PortLocation / 2) / SP_PLAYFIELD_WIDTH; - - printf("::: %d: port_location == %d => (%d, %d)\n", - i, port->PortLocation, port_x, port_y); - } -#endif - /* change gravity: 1 == "turn on", anything else (0) == "turn off" */ port->Gravity = getFile8Bit(file); @@ -351,11 +279,6 @@ static void LoadNativeLevelFromFileStream_SP(FILE *file, int width, int height, /* random seed used for recorded demos */ header->DemoRandomSeed = getFile16BitLE(file); /* yes, little endian */ - // header->DemoRandomSeed = getFile16BitBE(file); /* !!! TEST ONLY !!! */ - -#if 0 - printf("::: file.c: DemoRandomSeed == %d\n", header->DemoRandomSeed); -#endif /* auto-determine number of infotrons if it was stored as "0" -- see above */ if (header->InfotronsNeeded == 0) @@ -657,3 +580,64 @@ boolean LoadNativeLevel_SP(char *filename, int level_pos) return TRUE; } + +void SaveNativeLevel_SP(char *filename) +{ + LevelInfoType *header = &native_sp_level.header; + FILE *file; + int i, x, y; + + if (!(file = fopen(filename, MODE_WRITE))) + { + Error(ERR_WARN, "cannot save native level file '%s'", filename); + + return; + } + + /* write level playfield (width * height == 60 * 24 tiles == 1440 bytes) */ + for (y = 0; y < native_sp_level.height; y++) + for (x = 0; x < native_sp_level.width; x++) + putFile8Bit(file, native_sp_level.playfield[x][y]); + + /* write level header (96 bytes) */ + + WriteUnusedBytesToFile(file, 4); + + putFile8Bit(file, header->InitialGravity); + putFile8Bit(file, header->Version); + + for (i = 0; i < SP_LEVEL_NAME_LEN; i++) + putFile8Bit(file, header->LevelTitle[i]); + + putFile8Bit(file, header->InitialFreezeZonks); + putFile8Bit(file, header->InfotronsNeeded); + putFile8Bit(file, header->SpecialPortCount); + + for (i = 0; i < SP_MAX_SPECIAL_PORTS; i++) + { + SpecialPortType *port = &header->SpecialPort[i]; + + putFile16BitBE(file, port->PortLocation); + putFile8Bit(file, port->Gravity); + putFile8Bit(file, port->FreezeZonks); + putFile8Bit(file, port->FreezeEnemies); + + WriteUnusedBytesToFile(file, 1); + } + + putFile8Bit(file, header->SpeedByte); + putFile8Bit(file, header->CheckSumByte); + putFile16BitLE(file, header->DemoRandomSeed); + + /* also save demo tape, if available */ + + if (native_sp_level.demo.is_available) + { + putFile8Bit(file, native_sp_level.demo.level_nr); + + for (i = 0; i < native_sp_level.demo.length; i++) + putFile8Bit(file, native_sp_level.demo.data[i]); + } + + fclose(file); +}