Skip to content
Browse files

MegaZeux 2.80c release.

  • Loading branch information...
1 parent 75617b7 commit 4782ebcc2c27390dd8e81645107362fa987690de @ajs1984 committed Aug 11, 2008
Showing with 1,218 additions and 414 deletions.
  1. +1 −1 Makefile
  2. +2 −2 Makefile.linux
  3. +60 −37 audio.cpp
  4. +3 −2 board.cpp
  5. +2 −2 board.h
  6. +6 −1 build.txt
  7. +52 −0 changelog.txt
  8. +2 −0 char_ed.cpp
  9. +13 −0 config.txt
  10. +35 −0 configure.cpp
  11. +2 −0 configure.h
  12. +99 −61 counter.cpp
  13. +10 −8 decrypt.cpp
  14. +83 −76 edit.cpp
  15. +2 −24 edit_di.cpp
  16. +4 −0 error.cpp
  17. +364 −0 fsafeopen.cpp
  18. +33 −0 fsafeopen.h
  19. +30 −10 game.cpp
  20. +7 −3 game2.cpp
  21. +26 −11 getpw.cpp
  22. +5 −5 graphics.cpp
  23. +67 −6 help.doc
  24. +10 −8 intake.cpp
  25. +8 −0 main.cpp
  26. +6 −0 port.txt
  27. +10 −5 rasm.cpp
  28. +6 −3 robo_ed.cpp
  29. +79 −49 robot.cpp
  30. +1 −0 robot.h
  31. +117 −83 runrobo2.cpp
  32. +0 −1 sfx.cpp
  33. +10 −3 sprite.cpp
  34. +4 −0 window.cpp
  35. +58 −12 world.cpp
  36. +1 −1 world.h
View
2 Makefile
@@ -10,7 +10,7 @@ OBJS = main.o graphics.o window.o hexchar.o event.o \
PREFIX = /usr
-BIN = mzx280b.exe
+BIN = mzx280c.exe
CC = gcc
CPP = g++
View
4 Makefile.linux
@@ -6,11 +6,11 @@ OBJS = main.o graphics.o window.o hexchar.o event.o \
idarray.o delay.o game2.o expr.o sprite.o runrobo2.o \
mzm.o decrypt.o audio.o edit.o edit_di.o block.o \
char_ed.o pal_ed.o param.o sfx_edit.o fill.o rasm.o \
- robo_ed.o configure.o
+ robo_ed.o configure.o fsafeopen.o
PREFIX = /usr
-BIN = mzx280b
+BIN = mzx280c
CC = gcc
CPP = g++
View
97 audio.cpp
@@ -36,6 +36,7 @@
#include "data.h"
#include "configure.h"
#include "gdm2s3m.h"
+#include "fsafeopen.h"
struct _ModPlugFile
{
@@ -72,8 +73,8 @@ void audio_callback(void *userdata, Uint8 *stream, int len)
// Reset position
audio.current_mod->mSoundFile.SetCurrentPos(0);
// Read anew remaining bytes
- ModPlug_Read(audio.current_mod, audio.mod_buffer + read_len,
- len - read_len);
+ ModPlug_Read(audio.current_mod, audio.mod_buffer + read_len,
+ len - read_len);
}
}
else
@@ -232,10 +233,42 @@ void init_audio(config_info *conf)
NULL
};
+ if(conf->oversampling_on)
+ {
+ audio.mod_settings.mFlags = MODPLUG_ENABLE_OVERSAMPLING;
+ }
+
audio.mod_settings.mFrequency = 44100;
audio.mod_settings.mChannels = 2;
audio.mod_settings.mBits = 16;
- audio.mod_settings.mResamplingMode = MODPLUG_RESAMPLE_LINEAR;
+
+ switch(conf->resampling_mode)
+ {
+ case 0:
+ {
+ audio.mod_settings.mResamplingMode = MODPLUG_RESAMPLE_NEAREST;
+ break;
+ }
+
+ case 1:
+ {
+ audio.mod_settings.mResamplingMode = MODPLUG_RESAMPLE_LINEAR;
+ break;
+ }
+
+ case 2:
+ {
+ audio.mod_settings.mResamplingMode = MODPLUG_RESAMPLE_SPLINE;
+ break;
+ }
+
+ case 3:
+ {
+ audio.mod_settings.mResamplingMode = MODPLUG_RESAMPLE_FIR;
+ break;
+ }
+ }
+
audio.mod_settings.mLoopCount = -1;
ModPlug_SetSettings(&audio.mod_settings);
@@ -252,20 +285,23 @@ void load_mod(char *filename)
char *input_buffer;
int file_size;
int extension_pos = strlen(filename) - 4;
- char new_file[256];
+ char new_file[MAX_PATH];
if(extension_pos && !strcasecmp(filename + extension_pos, ".gdm"))
{
- struct stat file_info;
+ char translated_filename_src[MAX_PATH];
+ char translated_filename_dest[MAX_PATH];
// GDM -> S3M
strcpy(new_file, filename);
memcpy(new_file + extension_pos, ".s3m", 4);
- if(stat(new_file, &file_info))
+ fsafetranslate(filename, translated_filename_src);
+
+ if(fsafetranslate(new_file, translated_filename_dest) < 0)
{
// If it doesn't exist, create it by converting.
- convert_gdm_s3m(filename, new_file);
+ convert_gdm_s3m(translated_filename_src, new_file);
}
filename = new_file;
@@ -274,7 +310,7 @@ void load_mod(char *filename)
if(audio.mod_playing)
end_mod();
- input_file = fopen(filename, "rb");
+ input_file = fsafeopen(filename, "rb");
if(input_file)
{
@@ -304,7 +340,6 @@ void end_mod(void)
void play_sample(int freq, char *filename)
{
- struct stat file_info;
FILE *input_file;
char *input_buffer;
int file_size;
@@ -313,23 +348,29 @@ void play_sample(int freq, char *filename)
// FIXME - destroy least recently used?
if(audio.num_samples_playing >= MAX_SAMS)
- return;
+ return;
- if((extension_pos >= 0) && !strcasecmp(filename + extension_pos, ".sam"))
+ if(extension_pos && !strcasecmp(filename + extension_pos, ".sam"))
{
- // SAM -> WAV
+ char translated_filename_src[MAX_PATH];
+ char translated_filename_dest[MAX_PATH];
+
+ // GDM -> S3M
strcpy(new_file, filename);
memcpy(new_file + extension_pos, ".wav", 4);
- if(stat(new_file, &file_info))
+ fsafetranslate(filename, translated_filename_src);
+
+ if(fsafetranslate(new_file, translated_filename_dest) < 0)
{
- // Create it
- convert_sam_to_wav(filename, new_file);
+ // If it doesn't exist, create it by converting.
+ convert_sam_to_wav(translated_filename_src, new_file);
}
+
filename = new_file;
}
- input_file = fopen(filename, "rb");
+ input_file = fsafeopen(filename, "rb");
if(input_file)
{
@@ -344,31 +385,14 @@ void play_sample(int freq, char *filename)
if(sample_loaded)
{
- int sample_length = sample_loaded->mSoundFile.Ins[1].nLength;
-
// A little hack to modify the pitch
sample_loaded->mSoundFile.Ins[1].nC4Speed = (freq_conversion / freq) / 2;
sample_loaded->mSoundFile.Ins[2].nC4Speed = (freq_conversion / freq) / 2;
sample_loaded->mSoundFile.Ins[1].nVolume = (256 * sound_gvol) / 8;
sample_loaded->mSoundFile.Ins[2].nVolume = (256 * sound_gvol) / 8;
- // This number is pretty much obtained via experimentation. It can probably
- // stand to be a little higher.
- sample_length /= 110;
-
- if(sample_length < 256)
- {
- sample_loaded->mSoundFile.Patterns[0][0].param = sample_length;
- sample_loaded->mSoundFile.Patterns[0][2].command = CMD_PATTERNBREAK;
- }
- else
- {
- int row_duration = sample_length / 255;
- sample_loaded->mSoundFile.Patterns[0][0].param = 255;
- if(row_duration < 62)
- sample_loaded->mSoundFile.Patterns[0][2 + row_duration].command =
- CMD_PATTERNBREAK;
- }
+ // This number is pretty much obtained via experimentation. It can probably
+ // stand to be a little higher.
// Find a free position to put it
for(i = 0; i < 16; i++)
@@ -384,7 +408,7 @@ void play_sample(int freq, char *filename)
}
free(input_buffer);
- fclose(input_file);
+ fclose(input_file);
}
}
@@ -567,4 +591,3 @@ void convert_sam_to_wav(char *source_name, char *dest_name)
fclose(source);
fclose(dest);
}
-
View
5 board.cpp
@@ -201,6 +201,7 @@ void load_board_direct(Board *cur_board, FILE *fp, int savegame)
{
cur_board->board_dir[i] = fgetc(fp);
}
+
cur_board->restart_if_zapped = fgetc(fp);
cur_board->time_limit = fgetw(fp);
cur_board->last_key = fgetc(fp);
@@ -598,8 +599,8 @@ void save_RLE2_plane(char *plane, FILE *fp, int size)
current_char = plane[i];
runsize = 1;
- while((plane[i + 1] == current_char) && (runsize < 127) &&
- (i < (size - 1)))
+ while((i < (size - 1)) && (plane[i + 1] == current_char) &&
+ (runsize < 127))
{
i++;
runsize++;
View
4 board.h
@@ -32,7 +32,7 @@ struct _Board
{
int size;
- char board_name[BOARD_NAME_SIZE];
+ char board_name[32];
int board_width;
int board_height;
@@ -47,7 +47,7 @@ struct _Board
char *overlay;
char *overlay_color;
- char mod_playing[FILENAME_SIZE];
+ char mod_playing[256];
int viewport_x;
int viewport_y;
int viewport_width;
View
7 build.txt
@@ -10,11 +10,16 @@ Next, you need the correct libraries installed, which are the
SDL: http://www.libsdl.org/
-libmodplug: http://sourceforge.net/projects/libmodplug/
+libmodplug: http://prdownloads.sourceforge.net/modplug-xmms/
gdm2s3m: http://mzx.bitpack.net/gdm2s3m-1.1.tar.gz
(should also show up on other sites soon)
+NOTE: As of this writing, libmodplug (version 0.7) has a bug that
+doesn't allow it to correctly load 2-channel FT2 saved mods. There
+is a patch included to rectify this; you should patch libmodplug
+before building if you have this version.
+
Now, you need GCC installed and GNU make to actually build. Currently,
GCC on Windows and Linux are supported. Use Makefile.linux to build on
Linux, and the vanilla Makefile to build on Windows. As of this writing,
View
52 changelog.txt
@@ -1,3 +1,55 @@
++ Fixed issues with the commands counter not being reset
++ Color intensity now gets reset when you enter the editor
++ SAMs got cutoff sometimes now.. fixed
++ Fixed bug where loading a world with empty boards could change the starting,
+ endgame, and death boards
++ Fixed bug where you could text enter off the bottom of the board, causing
+ problems
++ Fixed bug involving cutting/clearing the entire robot in the robot editor
+ while not at the first line
++ Fixed robot name entry for global robot not disappearing on small boards
++ Fixed bug where you could duplicate the player by holding down a direction
+ as a saved game loads
++ Fixed bug where you could go to line 0 in the robot editor
++ Saving an MZM now auto-adds the .mzm extension...
++ Fixed black screen on quicksave
++ Fixed bug where opening a file didn't close the old one if one was open
+ (so it'd eventually crash MZX)
++ Changed alt+backspace behavior in intake so it doesn't exit
++ Added clipping for refx/refy/width/height for sprites (less than 0 at
+ initialization, greater than board width/height at draw)
++ Fixed direction parsing for move all
++ Fixed bug where creating things on top of the player would use a slot
+ for robots/scrolls/signs/sensors instead of just copy to the buffer
++ Added ability to use chars as immediates in Robotic commands
+ (ie, set "$str.0" 'a')
++ Added options to enable oversampling and specify resampling mode in
+ the config file (higher quality audio)
++ Building with patched modplug that fixes loading 2-channel mods
+ outputted by FT2. If you're building yourself, see build.txt.
++ Fixed inability to mouse click in alt + h mode
++ Fixed ability to mouse click outside of board range
++ Should work better for Linux users; case insensitivity for file opens
+ has been added.
++ Fixed close bug that was affecting Linux builds (may affect more)
++ Keypad enter works where normal enter works now
++ Fixed disappearing cursor when cancelling out of abandon changes box
+ when loading a new world in the editor
++ Fixed problems when loading/saving robots outside of ID range (do not
+ hardcode ID's people)
++ Fixed problem with NO BOARD exits being set to something else when
+ empty boards were being stripped or when worlds were being imported
++ Fixed bug where auto-decrypting worlds didn't work if the XOR value
+ was negative
++ Fixed problem with rid not working the first cycle
++ Fixed inability to interpolate (with &&'s) counter names larger than
+ 14
++ Added new robot mem counter in debug box (only kb precise, rounds up)
++ Fixed ability to clone the player on non-title board after testing
++ Lengthened size of mod name buffers
++ Fixed bug where send x y doesn't work from the global robot
++ Fixed a few bugs that could cause MZX to crash
+
August 11, 2004 - MZX 2.80b
+ Made it possible for robots to move through teleporters
View
2 char_ed.cpp
@@ -297,6 +297,7 @@ int char_editor(World *mzx_world)
break;
}
+ case SDLK_KP_ENTER:
case SDLK_RETURN:
{
int new_char = char_selection(current_char);
@@ -705,6 +706,7 @@ int smzx_char_editor(World *mzx_world)
break;
}
+ case SDLK_KP_ENTER:
case SDLK_RETURN:
{
int new_char = char_selection(current_char);
View
13 config.txt
@@ -53,6 +53,19 @@
#audio_buffer = 2048
+# Allow music to be sampled at higher precision. Increases CPU
+# usage but increases audio quality as well.
+
+#enable_oversampling = 0
+
+# Set resampling mode. Choices are:
+# none (fastest, poor quality)
+# linear (fast, good quality)
+# cubic (slow, great quality)
+# fir (very slow, excellent quality)
+
+#resampling_mode = linear
+
# Whether music/samples should be played or not.
# Does not include PC speaker effects.
View
35 configure.cpp
@@ -255,6 +255,37 @@ void config_startup_file(config_info *conf, char *name, char *value)
strcpy(conf->startup_file, value);
}
+void config_enable_oversampling(config_info *conf, char *name, char *value)
+{
+ conf->oversampling_on = strtol(value, NULL, 10);
+}
+
+void config_resampling_mode(config_info *conf, char *name, char *value)
+{
+ if(!strcmp(value, "none"))
+ {
+ conf->resampling_mode = 0;
+ }
+ else
+
+ if(!strcmp(value, "linear"))
+ {
+ conf->resampling_mode = 1;
+ }
+ else
+
+ if(!strcmp(value, "cubic"))
+ {
+ conf->resampling_mode = 2;
+ }
+ else
+
+ if(!strcmp(value, "fir"))
+ {
+ conf->resampling_mode = 3;
+ }
+}
+
config_entry config_options[] =
{
{ "audio_buffer", config_set_audio_buffer },
@@ -274,6 +305,7 @@ config_entry config_options[] =
{ "default_invalid_status", config_default_invald },
{ "disassemble_base", config_disassemble_base },
{ "disassemble_extras", config_disassemble_extras },
+ { "enable_oversampling", config_enable_oversampling },
{ "force_height_multiplier", config_set_multiplier },
{ "force_resolution", config_set_resolution },
{ "fullscreen", config_set_fullscreen },
@@ -286,6 +318,7 @@ config_entry config_options[] =
{ "music_volume", config_set_mod_volume },
{ "mzx_speed", config_set_mzx_speed },
{ "pc_speaker_on", config_set_pc_speaker },
+ { "resampling_mode", config_resampling_mode },
{ "sample_volume", config_set_sam_volume },
{ "save_file", config_save_file },
{ "startup_file", config_startup_file }
@@ -328,6 +361,8 @@ config_info default_options =
// Audio options
2048,
+ 0,
+ 1,
7,
7,
1,
View
2 configure.h
@@ -35,6 +35,8 @@ struct _config_info
// Audio options
int buffer_size;
+ int oversampling_on;
+ int resampling_mode;
int music_volume;
int sam_volume;
int music_on;
View
160 counter.cpp
@@ -37,6 +37,7 @@
#include "robot.h"
#include "audio.h"
#include "rasm.h"
+#include "fsafeopen.h"
typedef int (* builtin_read_function)(World *mzx_world,
Function_counter *counter, char *name, int id);
@@ -341,7 +342,10 @@ void board_id_write(World *mzx_world, Function_counter *counter,
Board *src_board = mzx_world->current_board;
int offset = get_counter(mzx_world, "board_x", id) +
(get_counter(mzx_world, "board_y", id) * src_board->board_width);
- src_board->level_id[offset] = value;
+
+ if(((value < 122) || (value == 127)) &&
+ (src_board->level_id[offset] < 122))
+ src_board->level_id[offset] = value;
}
void board_param_write(World *mzx_world, Function_counter *counter,
@@ -350,7 +354,9 @@ void board_param_write(World *mzx_world, Function_counter *counter,
Board *src_board = mzx_world->current_board;
int offset = get_counter(mzx_world, "board_x", id) +
(get_counter(mzx_world, "board_y", id) * src_board->board_width);
- src_board->level_param[offset] = value;
+
+ if(src_board->level_id[offset] < 122)
+ src_board->level_param[offset] = value;
}
int red_value_read(World *mzx_world, Function_counter *counter,
@@ -664,13 +670,21 @@ void spr_refx_write(World *mzx_world, Function_counter *counter,
char *name, int value, int id)
{
int spr_num = strtol(name + 3, NULL, 10) & (MAX_SPRITES - 1) & 0xFF;
- (mzx_world->sprite_list[spr_num])->ref_x = value;
+
+ if(value < 0)
+ value = 0;
+
+ (mzx_world->sprite_list[spr_num])->ref_x = value;
}
void spr_refy_write(World *mzx_world, Function_counter *counter,
char *name, int value, int id)
{
int spr_num = strtol(name + 3, NULL, 10) & (MAX_SPRITES - 1) & 0xFF;
+
+ if(value < 0)
+ value = 0;
+
(mzx_world->sprite_list[spr_num])->ref_y = value;
}
@@ -1096,13 +1110,13 @@ void int2bin_write(World *mzx_world, Function_counter *counter,
int commands_read(World *mzx_world, Function_counter *counter,
char *name, int id)
{
- return commands;
+ return mzx_world->commands;
}
void commands_write(World *mzx_world, Function_counter *counter,
char *name, int value, int id)
{
- commands = value;
+ mzx_world->commands = value;
}
int fread_open_read(World *mzx_world, Function_counter *counter,
@@ -1297,37 +1311,13 @@ int robot_id_read(World *mzx_world, Function_counter *counter,
int robot_id_n_read(World *mzx_world, Function_counter *counter,
char *name, int id)
{
- Board *src_board = mzx_world->current_board;
- int first, last;
- if(find_robot(src_board, name + 9, &first, &last))
- {
- Robot *cur_robot = src_board->robot_list_name_sorted[first];
- // This is a cheap trick for now since robots don't have
- // a back-reference for ID's
- int offset = cur_robot->xpos +
- (cur_robot->ypos * src_board->board_width);
- return src_board->level_param[offset];
- }
-
- return -1;
+ return get_robot_id(mzx_world->current_board, name + 9);
}
int rid_read(World *mzx_world, Function_counter *counter,
char *name, int id)
{
- Board *src_board = mzx_world->current_board;
- int first, last;
- if(find_robot(src_board, name + 3, &first, &last))
- {
- Robot *cur_robot = src_board->robot_list_name_sorted[first];
- // This is a cheap trick for now since robots don't have
- // a back-reference for ID's
- int offset = cur_robot->xpos +
- (cur_robot->ypos * src_board->board_width);
- return src_board->level_param[offset];
- }
-
- return -1;
+ return get_robot_id(mzx_world->current_board, name + 3);
}
int r_read(World *mzx_world, Function_counter *counter,
@@ -1682,7 +1672,11 @@ int set_counter_special(World *mzx_world, int spec_type,
if(char_value[0])
{
char_value[12] = 0;
- mzx_world->input_file = fopen(char_value, "rb");
+
+ if(mzx_world->input_file)
+ fclose(mzx_world->input_file);
+
+ mzx_world->input_file = fsafeopen(char_value, "rb");
}
else
{
@@ -1699,7 +1693,11 @@ int set_counter_special(World *mzx_world, int spec_type,
if(char_value[0])
{
char_value[12] = 0;
- mzx_world->output_file = fopen(char_value, "wb");
+
+ if(mzx_world->output_file)
+ fclose(mzx_world->output_file);
+
+ mzx_world->output_file = fsafeopen(char_value, "wb");
}
else
{
@@ -1716,7 +1714,11 @@ int set_counter_special(World *mzx_world, int spec_type,
if(char_value[0])
{
char_value[12] = 0;
- mzx_world->output_file = fopen(char_value, "ab");
+
+ if(mzx_world->output_file)
+ fclose(mzx_world->output_file);
+
+ mzx_world->output_file = fsafeopen(char_value, "ab");
}
else
{
@@ -1733,7 +1735,11 @@ int set_counter_special(World *mzx_world, int spec_type,
if(char_value[0])
{
char_value[12] = 0;
- mzx_world->output_file = fopen(char_value, "r+b");
+
+ if(mzx_world->output_file)
+ fclose(mzx_world->output_file);
+
+ mzx_world->output_file = fsafeopen(char_value, "r+b");
}
else
{
@@ -1761,8 +1767,7 @@ int set_counter_special(World *mzx_world, int spec_type,
case FOPEN_SAVE_WORLD:
{
- int faded = get_fade_status();
- save_world(mzx_world, char_value, 0, faded);
+ save_world(mzx_world, char_value, 0, 0);
return 0;
}
@@ -1785,28 +1790,35 @@ int set_counter_special(World *mzx_world, int spec_type,
if(new_program)
{
+ Board *src_board = mzx_world->current_board;
Robot *cur_robot;
int robot_id = id;
if(value != -1)
robot_id = value;
- cur_robot = mzx_world->current_board->robot_list[robot_id];
-
- reallocate_robot(cur_robot, new_size);
- memcpy(cur_robot->program, new_program, new_size);
- free(new_program);
- cur_robot->cur_prog_line = 1;
-
- return 1;
+ if(robot_id <= src_board->num_robots)
+ {
+ cur_robot = mzx_world->current_board->robot_list[robot_id];
+
+ if(cur_robot != NULL)
+ {
+ reallocate_robot(cur_robot, new_size);
+ memcpy(cur_robot->program, new_program, new_size);
+ free(new_program);
+ cur_robot->cur_prog_line = 1;
+ return 1;
+ }
+ }
}
return 0;
}
case FOPEN_LOAD_BC:
{
- FILE *bc_file = fopen(char_value, "rb");
+ FILE *bc_file = fsafeopen(char_value, "rb");
+ Board *src_board = mzx_world->current_board;
int new_size;
if(bc_file)
@@ -1817,19 +1829,27 @@ int set_counter_special(World *mzx_world, int spec_type,
if(value != -1)
robot_id = value;
- cur_robot = mzx_world->current_board->robot_list[robot_id];
+ if(robot_id <= src_board->num_robots)
+ {
+ cur_robot = mzx_world->current_board->robot_list[robot_id];
+
+ if(cur_robot != NULL)
+ {
+ fseek(bc_file, 0, SEEK_END);
+ new_size = ftell(bc_file);
+ fseek(bc_file, 0, SEEK_SET);
- fseek(bc_file, 0, SEEK_END);
- new_size = ftell(bc_file);
- fseek(bc_file, 0, SEEK_SET);
+ reallocate_robot(cur_robot, new_size);
+ fread(cur_robot->program, new_size, 1, bc_file);
+ cur_robot->cur_prog_line = 1;
- reallocate_robot(cur_robot, new_size);
- fread(cur_robot->program, new_size, 1, bc_file);
- cur_robot->cur_prog_line = 1;
+ fclose(bc_file);
- fclose(bc_file);
+ return 1;
+ }
+ }
- return 1;
+ fclose(bc_file);
}
return 0;
@@ -1838,6 +1858,7 @@ int set_counter_special(World *mzx_world, int spec_type,
case FOPEN_SAVE_ROBOT:
{
Robot *cur_robot;
+ Board *src_board = mzx_world->current_board;
int robot_id = id;
int allow_extras = mzx_world->conf.disassemble_extras;
int base = mzx_world->conf.disassemble_base;
@@ -1846,8 +1867,17 @@ int set_counter_special(World *mzx_world, int spec_type,
robot_id = value;
cur_robot = mzx_world->current_board->robot_list[robot_id];
- disassemble_file(char_value, cur_robot->program,
- allow_extras, base);
+
+ if(robot_id <= src_board->num_robots)
+ {
+ cur_robot = mzx_world->current_board->robot_list[robot_id];
+
+ if(cur_robot != NULL)
+ {
+ disassemble_file(char_value, cur_robot->program,
+ allow_extras, base);
+ }
+ }
return 0;
}
@@ -1860,15 +1890,23 @@ int set_counter_special(World *mzx_world, int spec_type,
if(bc_file)
{
Robot *cur_robot;
+ Board *src_board = mzx_world->current_board;
int robot_id = id;
if(value != -1)
robot_id = value;
- cur_robot = mzx_world->current_board->robot_list[robot_id];
- fwrite(cur_robot->program, cur_robot->program_length, 1, bc_file);
-
- fclose(bc_file);
+ if(robot_id <= src_board->num_robots)
+ {
+ cur_robot = mzx_world->current_board->robot_list[robot_id];
+
+ if(cur_robot != NULL)
+ {
+ fwrite(cur_robot->program, cur_robot->program_length, 1, bc_file);
+ }
+ }
+
+ fclose(bc_file);
}
return 0;
View
18 decrypt.cpp
@@ -34,7 +34,9 @@ int get_pw_xor_code(char *password, int pro_method)
// Clear pw after first null
for(i = strlen(password); i < 16; i++)
+ {
password[i] = 0;
+ }
for(i = 0; i < 15; i++)
{
@@ -46,13 +48,13 @@ int get_pw_xor_code(char *password, int pro_method)
if(i & 1)
{
- work += password[i]; // Add (even byte)
+ work += (signed char)password[i]; // Add (even byte)
if(work > 255)
work ^= 257; // Wraparound from add
}
else
{
- work ^= password[i]; // XOR (odd byte);
+ work ^= (signed char)password[i]; // XOR (odd byte);
}
}
// To factor in protection method, add it in and roll one last time
@@ -79,9 +81,9 @@ void decrypt(char *file_name)
int pro_method;
int i;
int len;
- int num_boards;
- int offset_low_byte;
- int xor_val;
+ char num_boards;
+ char offset_low_byte;
+ char xor_val;
char password[15];
char *file_buffer;
char *src_ptr;
@@ -148,14 +150,14 @@ void decrypt(char *file_name)
src_ptr += 4;
- num_boards = (*src_ptr) ^ xor_val;
+ num_boards = ((*src_ptr) ^ xor_val);
src_ptr++;
// If custom SFX is there, run through and skip it
if(!num_boards)
{
- int sfx_length = src_ptr[0] ^ xor_val;
- sfx_length |= (src_ptr[1] ^ xor_val) << 8;
+ int sfx_length = (char)(src_ptr[0] ^ xor_val);
+ sfx_length |= ((char)(src_ptr[1] ^ xor_val)) << 8;
src_ptr += sfx_length + 2;
num_boards = (*src_ptr) ^ xor_val;
src_ptr++;
View
159 edit.cpp
@@ -416,69 +416,72 @@ int place_current_at_xy(World *mzx_world, int id, int color, int param,
if(!overlay_edit)
{
- if(id == 127)
- {
- id_remove_top(mzx_world, mzx_world->player_x, mzx_world->player_y);
- mzx_world->player_x = x;
- mzx_world->player_y = y;
- }
- else
-
- if((id == 123) || (id == 124))
- {
- if((old_id == 123) || (old_id == 124))
- {
- int old_param = src_board->level_param[offset];
- replace_robot(src_board, copy_robot, old_param);
- src_board->level_color[offset] = color;
- return old_param;
- }
-
- param = duplicate_robot(src_board, copy_robot, x, y);
- if(param != -1)
- {
- (src_board->robot_list[param])->xpos = x;
- (src_board->robot_list[param])->ypos = y;
- (src_board->robot_list[param])->used = 1;
- }
- }
- else
-
- if((id == 125) || (id == 126))
- {
- if((old_id == 125) || (old_id == 126))
- {
- int old_param = src_board->level_param[offset];
- replace_scroll(src_board, copy_scroll, old_param);
- src_board->level_color[offset] = color;
- return old_param;
- }
-
- param = duplicate_scroll(src_board, copy_scroll);
- if(param != -1)
- (src_board->scroll_list[param])->used = 1;
- }
- else
-
- if(id == 122)
- {
- if((old_id == 123) || (old_id == 124))
- {
- int old_param = src_board->level_param[offset];
- replace_sensor(src_board, copy_sensor, old_param);
- src_board->level_color[offset] = color;
- return old_param;
- }
-
- param = duplicate_sensor(src_board, copy_sensor);
- if(param != -1)
- (src_board->sensor_list[param])->used = 1;
- }
-
- if(param != -1)
- {
- place_at_xy(mzx_world, id, color, param, x, y);
- }
+ if(old_id != 127)
+ {
+ if(id == 127)
+ {
+ id_remove_top(mzx_world, mzx_world->player_x, mzx_world->player_y);
+ mzx_world->player_x = x;
+ mzx_world->player_y = y;
+ }
+ else
+
+ if((id == 123) || (id == 124))
+ {
+ if((old_id == 123) || (old_id == 124))
+ {
+ int old_param = src_board->level_param[offset];
+ replace_robot(src_board, copy_robot, old_param);
+ src_board->level_color[offset] = color;
+ return old_param;
+ }
+
+ param = duplicate_robot(src_board, copy_robot, x, y);
+ if(param != -1)
+ {
+ (src_board->robot_list[param])->xpos = x;
+ (src_board->robot_list[param])->ypos = y;
+ (src_board->robot_list[param])->used = 1;
+ }
+ }
+ else
+
+ if((id == 125) || (id == 126))
+ {
+ if((old_id == 125) || (old_id == 126))
+ {
+ int old_param = src_board->level_param[offset];
+ replace_scroll(src_board, copy_scroll, old_param);
+ src_board->level_color[offset] = color;
+ return old_param;
+ }
+
+ param = duplicate_scroll(src_board, copy_scroll);
+ if(param != -1)
+ (src_board->scroll_list[param])->used = 1;
+ }
+ else
+
+ if(id == 122)
+ {
+ if((old_id == 123) || (old_id == 124))
+ {
+ int old_param = src_board->level_param[offset];
+ replace_sensor(src_board, copy_sensor, old_param);
+ src_board->level_color[offset] = color;
+ return old_param;
+ }
+
+ param = duplicate_sensor(src_board, copy_sensor);
+ if(param != -1)
+ (src_board->sensor_list[param])->used = 1;
+ }
+
+ if(param != -1)
+ {
+ place_at_xy(mzx_world, id, color, param, x, y);
+ }
+ }
}
else
{
@@ -558,6 +561,8 @@ void thing_menu(World *mzx_world, int menu_number, int *new_id,
int id, color, param;
int chosen;
int old_id = *new_id;
+ Board *src_board = mzx_world->current_board;
+ int at_id = src_board->level_id[x + (y * src_board->board_width)];
cursor_off();
chosen =
@@ -710,6 +715,8 @@ void edit_world(World *mzx_world)
mzx_world->version = VERSION;
+ set_palette_intensity(100);
+
if(mzx_world->active)
{
clear_world(mzx_world);
@@ -965,11 +972,13 @@ void edit_world(World *mzx_world)
}
else
- if((mouse_y < edit_screen_height) && (edit_screen_height == 19))
+ if(mouse_y < edit_screen_height)
{
cursor_board_x = mouse_x + scroll_x;
cursor_board_y = mouse_y + scroll_y;
+ fix_scroll();
+
if(get_mouse_status() == SDL_BUTTON(3))
{
grab_at_xy(mzx_world, &current_id, &current_color,
@@ -1622,8 +1631,8 @@ void edit_world(World *mzx_world)
modified = 0;
}
- cursor_solid();
}
+ cursor_solid();
}
else
{
@@ -1706,7 +1715,7 @@ void edit_world(World *mzx_world)
// Sound effects
char *sfx_ext[] = { ".SFX", NULL };
if(!choose_file(sfx_ext, import_name,
- "Choose palette to import", 0))
+ "Choose SFX file to import", 0))
{
FILE *sfx_file;
@@ -1876,6 +1885,7 @@ void edit_world(World *mzx_world)
add_ext(export_name, ".sfx");
sfx_file = fopen(export_name, "wb");
+
if(mzx_world->custom_sfx_on)
fwrite(mzx_world->custom_sfx, 69, 50, sfx_file);
else
@@ -1938,6 +1948,7 @@ void edit_world(World *mzx_world)
break;
}
+ case SDLK_KP_ENTER:
case SDLK_RETURN:
{
if(draw_mode == 3)
@@ -2201,6 +2212,7 @@ void edit_world(World *mzx_world)
if(!save_file_dialog(mzx_world, "Export", "Save as: ", mzm_name_buffer))
{
+ add_ext(mzm_name_buffer, ".mzm");
if(overlay_edit)
{
save_mzm(mzx_world, mzm_name_buffer, start_x, start_y,
@@ -2255,7 +2267,7 @@ void edit_world(World *mzx_world)
}
}
- if(cursor_board_y < board_height)
+ if(cursor_board_y < (board_height - 1))
{
cursor_board_y++;
@@ -2714,13 +2726,9 @@ void edit_world(World *mzx_world)
{
int fade;
int current_board_id = mzx_world->current_board_id;
- char current_name[128];
char tempfile_name[128];
- tmpnam(tempfile_name);
- strcpy(current_name, current_world);
-
- save_world(mzx_world, tempfile_name, 0, 0);
+ save_world(mzx_world, "__test.mzx", 0, 0);
vquick_fadeout();
cursor_off();
@@ -2735,17 +2743,16 @@ void edit_world(World *mzx_world)
strcpy(mzx_world->real_mod_playing, src_board->mod_playing);
play_game(mzx_world, 1);
- reload_world(mzx_world, tempfile_name, &fade);
+ reload_world(mzx_world, "__test.mzx", &fade);
scroll_color = 15;
- find_player(mzx_world);
mzx_world->current_board_id = current_board_id;
mzx_world->current_board = mzx_world->board_list[current_board_id];
+ find_player(mzx_world);
synchronize_board_values();
insta_fadein();
fix_mod();
- unlink(tempfile_name);
+ unlink("__test.mzx");
- strcpy(current_world, current_name);
cursor_solid();
}
else
View
26 edit_di.cpp
@@ -602,37 +602,15 @@ void global_info(World *mzx_world)
if(intake(cur_robot->robot_name, 14, 34, 13, 15, 1, 0) != SDLK_ESCAPE)
{
+ restore_screen();
+ save_screen();
set_context(87);
robot_editor(mzx_world, cur_robot);
pop_context();
}
}
} while(redo);
-// FIXME - global robot editing
-/*
- if(ran_dialog == 5)
- {
- m_hide();
- save_screen();
- draw_window_box(16, 12, 50, 14, EC_DEBUG_BOX,
- EC_DEBUG_BOX_DARK, EC_DEBUG_BOX_CORNER, 1, 1);
- write_string("Name for robot:", 18, 13, EC_DEBUG_LABEL, 0);
- m_show();
- if(intake(robots[NUM_ROBOTS].robot_name,14,34,13,current_pg_seg,15,1,
- 0)==27)
- {
- restore_screen(current_pg_seg);
- pop_context();
- return;
- }
- restore_screen(current_pg_seg);
- set_context(87);
- robot_editor(NUM_ROBOTS);//Global robot
- pop_context();
- }
-*/
-
pop_context();
}
View
4 error.cpp
@@ -175,6 +175,10 @@ int error(char *string, char type, char options, unsigned int code)
restore_screen();
m_show();
if(ret == 4) // Exit the program
+ {
+ SDL_Quit();
exit(-1);
+ }
+
return ret;
}
View
364 fsafeopen.cpp
@@ -0,0 +1,364 @@
+/* $Id$
+ * MegaZeux
+ *
+ * Copyright (C) 2004 Alistair Strachan <alistair@devzero.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/stat.h>
+
+#include "fsafeopen.h"
+
+#ifndef __WIN32__
+
+#include <dirent.h>
+//
+// convert to lowercase
+//
+
+void case1(char *string)
+{
+ int i, len = strlen(string);
+
+ // lowercase it
+ for(i = 0; i < len; i++)
+ {
+ string[i] = tolower(string[i]);
+ }
+}
+
+//
+// convert to uppercase
+//
+
+void case2(char *string)
+{
+ int i, len = strlen(string);
+
+ // uppercase it
+ for(i = 0; i < len; i++)
+ {
+ string[i] = toupper(string[i]);
+ }
+}
+
+//
+// convert from anything to filename.EXT
+//
+
+void case3(char *string)
+{
+ int i, len = strlen(string);
+
+ // upper case extension
+ for(i = len; i > 0; i--)
+ {
+ string[i] = toupper(string[i]);
+
+ // last separator
+ if(string[i] == '.')
+ break;
+ }
+
+ // lowercase rest
+ for(i--; i >= 0; i--)
+ {
+ string[i] = tolower (string[i]);
+ }
+}
+
+//
+// convert from anything to FILENAME.ext
+//
+
+void case4(char *string)
+{
+ int i, len = strlen(string);
+
+ // lowercase extension
+ for(i = len; i > 0; i--)
+ {
+ string[i] = tolower(string[i]);
+
+ // last separator
+ if(string[i] == '.')
+ break;
+ }
+
+ // uppercase rest
+ for(i--; i >= 0; i--)
+ {
+ string[i] = toupper(string[i]);
+ }
+}
+
+//
+// brute force method; returns -1 if no permutation can be found to work
+//
+
+int case5(char *path, char *string)
+{
+ int i, ret = -1, dirlen = string - path;
+ struct dirent *inode;
+ char newpath[MAX_PATH];
+ DIR *wd;
+
+ // reconstruct wd
+ memcpy(newpath, "./", 2);
+ // copy everything sans last token
+ if(dirlen > 0)
+ memcpy(newpath + 2, path, dirlen - 1);
+
+ // open directory
+ wd = opendir(newpath);
+
+ if(wd != NULL)
+ {
+ while(ret != 0)
+ {
+ // check against inodes in this directory
+ inode = readdir(wd);
+
+ // check for null
+ if(inode == NULL)
+ break;
+
+ if(strcasecmp(inode->d_name, string) == 0)
+ {
+ // update inode lookup
+ strcpy(string, inode->d_name);
+
+ // success
+ ret = 0;
+ }
+ }
+
+ // close working dir
+ closedir(wd);
+ }
+
+ // return code
+ return ret;
+}
+
+int match(char *path)
+{
+ int i, file = 0, pathlen = strlen(path);
+ char *oldtoken, *token = NULL;
+ struct stat inode;
+
+ //
+ // FOUR likely permutations on files, and two likely permutations on
+ // directories before we start having to do anything fancy:
+ //
+ // filename.ext FILENAME.EXT filename.EXT FILENAME.ext
+ // directory DIRECTORY
+ //
+
+ while(1)
+ {
+
+ if(token == NULL)
+ {
+ // initial token
+ token = strtok(path, "/");
+ }
+ else
+ {
+ // subsequent tokens
+ token = strtok(NULL, "/");
+
+ // this token is the file
+ if(token == NULL)
+ {
+ for(i = 0; i < 5; i++)
+ {
+ // check file
+ if(stat(path, &inode) == 0)
+ break;
+
+ // try normal cases, then try brute force
+ switch(i)
+ {
+ case 0:
+ {
+ case1(oldtoken);
+ break;
+ }
+
+ case 1:
+ {
+ case2(oldtoken);
+ break;
+ }
+
+ case 2:
+ {
+ case3(oldtoken);
+ break;
+ }
+
+ case 3:
+ {
+ case4(oldtoken);
+ break;
+ }
+
+ default:
+ {
+ // try brute force
+ if(case5(path, oldtoken) < 0)
+ return -1;
+ }
+ }
+ }
+ break;
+ }
+
+ for(i = 0; i < 3; i++)
+ {
+ // check directory
+ if(stat(path, &inode) == 0)
+ break;
+
+ // try normal cases, then try brute force
+ switch(i)
+ {
+ case 0:
+ {
+ case1(oldtoken);
+ break;
+ }
+
+ case 1:
+ {
+ case2(oldtoken);
+ break;
+ }
+
+ default:
+ {
+ // try brute force
+ if(case5(path, oldtoken) < 0)
+ return -1;
+ }
+ }
+ }
+
+ // hack previous token; insert delimeter
+ oldtoken[strlen(oldtoken)] = '/';
+ }
+
+ // backup last token pointer
+ oldtoken = token;
+ }
+
+ // all ok
+ return 0;
+}
+#endif // !__WIN32__
+
+int fsafetranslate(const char *path, char *newpath)
+{
+ char *filename, *ret = NULL;
+ struct stat inode;
+ int i, pathlen;
+
+ // check for exploit
+ if(path == NULL)
+ return -1;
+
+ // get length of path
+ pathlen = strlen (path);
+
+ if(pathlen < 1)
+ return -1;
+
+ // copy string (including \0)
+ memcpy(newpath, path, pathlen + 1);
+
+ // convert all path delimeters to UNIX style, obsoleting windows legacy
+ for(i = 0; i < pathlen; i++)
+ {
+ if(newpath[i] == '\\')
+ newpath[i] = '/';
+ }
+
+ //
+ // OK before we do anything, we need to make some security checks. MZX games
+ // shouldn't be able to open C:\Windows\Explorer.exe and overwrite it, so
+ // we need to filter out any absolute pathnames, or relative pathnames
+ // including "..". Do so here.
+ //
+
+ // check top-level absolutes, windows and Linux */
+ if(newpath[0] == '/')
+ return -1;
+
+ if(pathlen > 1)
+ {
+ // windows drive letters
+ if(((newpath[0] >= 'A') && (newpath[0] <= 'Z')) ||
+ ((newpath[0] >= 'a') && (newpath[0] <= 'z')))
+ {
+ if(newpath[1] == ':')
+ return -1;
+ }
+
+ // reject any pathname including /../
+ for(i = 0; i < pathlen; i++)
+ {
+ if(strncmp(newpath + i, "..", 2) == 0)
+ {
+ // no need for delimeters -- any .. is invalid
+ if((i == 0) || pathlen < 4)
+ return -1;
+
+ // check for delimeters (file...ext is valid!)
+ if((newpath[i - 1] == '/') && (newpath[i + 2] == '/'))
+ return -1;
+ }
+ }
+ }
+
+ // see if file is already there
+ if(stat(newpath, &inode) != 0)
+ {
+#ifndef __WIN32__
+ if(match(newpath) < 0)
+#endif // __WIN32__
+ return -1;
+ }
+
+ // all ok
+ return 0;
+}
+
+FILE *fsafeopen(const char *path, const char *mode)
+{
+ char newpath[MAX_PATH];
+
+ // validate pathname, and optionally retrieve a better name
+ if(fsafetranslate(path, newpath) < 0)
+ return NULL;
+
+ // try opening the file
+ return fopen(newpath, mode);
+}
View
33 fsafeopen.h
@@ -0,0 +1,33 @@
+/* $Id$
+ * MegaZeux
+ *
+ * Copyright (C) 2004 Alistair Strachan <alistair@devzero.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef FSAFEOPEN_H
+#define FSAFEOPEN_H
+
+#ifndef __WIN32__
+
+#define MAX_PATH 512
+
+#endif
+
+int fsafetranslate(const char *path, char *newpath);
+FILE *fsafeopen(const char *path, const char *mode);
+
+#endif
View
40 game.cpp
@@ -269,6 +269,7 @@ void title_screen(World *mzx_world)
break;
}
+ case SDLK_KP_ENTER:
case SDLK_RETURN: // Enter
{
int fade_status = get_fade_status();
@@ -534,7 +535,7 @@ void title_screen(World *mzx_world)
if(reload_savegame(mzx_world, curr_sav, &fadein))
{
- vquick_fadeout();
+ vquick_fadeout();
}
else
{
@@ -1234,6 +1235,7 @@ void play_game(World *mzx_world, int fadein)
break;
}
+ case SDLK_KP_ENTER:
case SDLK_RETURN: // Enter
{
send_robot_all(mzx_world, "KeyEnter");
@@ -1381,6 +1383,8 @@ void play_game(World *mzx_world, int fadein)
load_mod(src_board->mod_playing);
strcpy(mzx_world->real_mod_playing, src_board->mod_playing);
+ find_player(mzx_world);
+
strcpy(curr_sav, save_file_name);
send_robot_def(mzx_world, 0, 10);
dead = 0;
@@ -1496,13 +1500,10 @@ void play_game(World *mzx_world, int fadein)
(src_board->level_under_id[mzx_world->player_x +
(src_board->board_width * mzx_world->player_y)] == 122)))
{
- int fade_status;
+ int fade_status = get_fade_status();
// Save entire game
save_world(mzx_world, curr_sav, 1, fade_status);
-
- if(fade_status)
- insta_fadeout();
}
}
break;
@@ -1525,6 +1526,9 @@ void play_game(World *mzx_world, int fadein)
// Reset this
src_board = mzx_world->current_board;
+
+ find_player(mzx_world);
+
// Swap in starting board
load_mod(src_board->mod_playing);
strcpy(mzx_world->real_mod_playing, src_board->mod_playing);
@@ -3108,9 +3112,6 @@ int update(World *mzx_world, int game, int *fadein)
if(mzx_world->swapped)
{
- mzx_world->current_board_id = mzx_world->first_board;
- mzx_world->current_board =
- mzx_world->board_list[mzx_world->current_board_id];
src_board = mzx_world->current_board;
load_mod(src_board->mod_playing);
strcpy(mzx_world->real_mod_playing, src_board->mod_playing);
@@ -3157,6 +3158,7 @@ int update(World *mzx_world, int game, int *fadein)
strcmp(src_board->mod_playing, "*"))
update_music = 1;
+
level_id = src_board->level_id;
level_param = src_board->level_param;
level_color = src_board->level_color;
@@ -3373,6 +3375,13 @@ void find_player(World *mzx_world)
char *level_id = src_board->level_id;
int offset;
+ if((mzx_world->player_x > board_width) ||
+ (mzx_world->player_y > board_height))
+ {
+ mzx_world->player_x = 0;
+ mzx_world->player_y = 0;
+ }
+
if(level_id[mzx_world->player_x +
(mzx_world->player_y * board_width)] != 127)
{
@@ -3454,20 +3463,31 @@ int give_key(World *mzx_world, int color)
void draw_debug_box(World *mzx_world, int x, int y, int d_x, int d_y)
{
Board *src_board = mzx_world->current_board;
+ int i;
+ int robot_mem = 0;
+
draw_window_box(x, y, x + 19, y + 5, EC_DEBUG_BOX, EC_DEBUG_BOX_DARK,
EC_DEBUG_BOX_CORNER, 0, 1);
write_string
(
- "X/Y: /\n"
- "Board:\n",
+ "X/Y: / \n"
+ "Board: \n"
+ "Robot mem: kb\n",
x + 1, y + 1, EC_DEBUG_LABEL, 0
);
write_number(d_x, EC_DEBUG_NUMBER, x + 8, y + 1, 5);
write_number(d_y, EC_DEBUG_NUMBER, x + 14, y + 1, 5);
write_number(mzx_world->current_board_id, EC_DEBUG_NUMBER, x + 18, y + 2, 0, 1);
+ for(i = 0; i < src_board->num_robots; i++)
+ {
+ robot_mem += (src_board->robot_list_name_sorted[i])->program_length;
+ }
+
+ write_number((robot_mem + 512) / 1024, EC_DEBUG_NUMBER, x + 12, y + 3, 5, 0);
+
if(*(src_board->mod_playing) != 0)
{
if(strlen(src_board->mod_playing) > 12)
View
10 game2.cpp
@@ -1740,16 +1740,20 @@ void update_board(World *mzx_world)
for(y = board_height - 1; y >= 0; y--)
{
- last_offset = level_offset;
for(x = board_width - 1; x >= 0; x--)
{
current_id = level_id[level_offset];
if((current_id == 123) || (current_id == 124))
- {
+ {
current_param = level_param[level_offset];
// May change the source board (with swap world or load game)
run_robot(mzx_world, -current_param, x, y);
- src_board = mzx_world->current_board;
+
+ if(mzx_world->swapped)
+ {
+ // Swapped world; get out of here
+ return;
+ }
}
level_offset--;
}
View
37 getpw.cpp
@@ -22,7 +22,6 @@
#include <stdio.h>
#include <dir.h>
#include <string.h>
-#include "meminter.h"
char magic_code[16] = "æRëòmMJ·‡²’ˆÞ‘$";
int pro_method, pw_size;
@@ -77,6 +76,7 @@ int main(int argc, char *argv[])
{
FILE *source;
FILE *dest;
+
int i;
int len;
printf("\n\n");
@@ -92,7 +92,8 @@ int main(int argc, char *argv[])
if(pro_method)
{
- //Password
+ printf("deprotecting %d\n", pro_method);
+ // Password
fread(password, 1, 15, source);
// First, normalize password...
for(i = 0; i < 15; i++)
@@ -105,6 +106,13 @@ int main(int argc, char *argv[])
// Show!
printf("Password: %s\n", password);
+ for(i = 0; i < strlen(password); i++)
+ {
+ printf("(%d) ", (unsigned char)password[i]);
+ }
+
+ printf("\n");
+
// Deprotect?
if((argc > 2) && ((argv[2][1] == 'd') || (argv[2][1] == 'D')))
{
@@ -128,8 +136,12 @@ int main(int argc, char *argv[])
fputc(0, dest);
fseek(source, 19, SEEK_CUR);
+ printf("saving magic string\n");
fputs("M\x02\x11", dest);
len -= 44;
+
+ printf("saving decrypted file\n");
+
for(; len > 0; len--)
{
fputc(fgetc(source) ^ xor_val, dest);
@@ -140,7 +152,9 @@ int main(int argc, char *argv[])
fseek(source, 4245, SEEK_SET);
fseek(dest, 4230, SEEK_SET);
- offset_low_byte = fgetc(source) ^ xor_val;
+ printf("fixing global robot offset\n");
+
+ offset_low_byte = (fgetc(source) ^ xor_val) & 0xFF;
fputc(offset_low_byte - 15, dest);
if(offset_low_byte < 15)
{
@@ -154,18 +168,19 @@ int main(int argc, char *argv[])
fputc(fgetc(source) ^ xor_val, dest);
fputc(fgetc(source) ^ xor_val, dest);
- num_boards = fgetc(source) ^ xor_val;
+ num_boards = (fgetc(source) ^ xor_val) & 0xFF;
+
// If custom SFX is there, run through and skip it
if(!num_boards)
{
- int sfx_length = fgetc(source) ^ xor_val;
- sfx_length |= (fgetc(source) ^ xor_val) << 8;
+ int sfx_length = (fgetc(source) ^ xor_val) & 0xFF;
+ sfx_length |= ((fgetc(source) ^ xor_val) & 0xFF) << 8;
fseek(source, sfx_length, SEEK_CUR);
printf("%d\n", sfx_length);
- num_boards = fgetc(source) ^ xor_val;
+ num_boards = (fgetc(source) ^ xor_val) & 0xFF;
}
- printf("%d\n", num_boards);
+ printf("fixing boards, %d boards\n", num_boards);
// Skip titles
fseek(source, 25 * num_boards, SEEK_CUR);
@@ -180,11 +195,9 @@ int main(int argc, char *argv[])
// Skip length
fseek(source, 4, SEEK_CUR);
fseek(dest, 4, SEEK_CUR);
- printf("dest %d\n", ftell(dest));
- printf("source %d\n", ftell(source));
// Get offset
- offset_low_byte = fgetc(source) ^ xor_val;
+ offset_low_byte = (fgetc(source) ^ xor_val) & 0xFF;
fputc(offset_low_byte - 15, dest);
if(offset_low_byte < 15)
{
@@ -202,7 +215,9 @@ int main(int argc, char *argv[])
}
}
else
+ {
printf("No password!\n\a");
+ }
fclose(source);
View
10 graphics.cpp
@@ -30,6 +30,7 @@
#include "delay.h"
#include "world.h"
#include "configure.h"
+#include "fsafeopen.h"
graphics_data graphics;
@@ -795,7 +796,7 @@ void ec_read_char(Uint8 chr, char *matrix)
Sint32 ec_load_set(char *name)
{
- FILE *fp = fopen(name, "rb");
+ FILE *fp = fsafeopen(name, "rb");
if(fp == NULL)
return -1;
@@ -808,7 +809,7 @@ Sint32 ec_load_set(char *name)
Sint32 ec_load_set_secondary(char *name, Uint8 *dest)
{
- FILE *fp = fopen(name, "rb");
+ FILE *fp = fsafeopen(name, "rb");
if(fp == NULL)
return -1;
@@ -822,7 +823,7 @@ Sint32 ec_load_set_secondary(char *name, Uint8 *dest)
Sint32 ec_load_set_var(char *name, Uint8 pos)
{
Uint32 size = 256;
- FILE *fp = fopen(name, "rb");
+ FILE *fp = fsafeopen(name, "rb");
if(fp == NULL)
return -1;
@@ -965,7 +966,7 @@ void update_palette()
void load_palette(char *fname)
{
- FILE *pal_file = fopen(fname, "rb");
+ FILE *pal_file = fsafeopen(fname, "rb");
if(pal_file)
{
@@ -1396,7 +1397,6 @@ void m_move(int x, int y)
graphics.mouse_y = y;
}
-// FIXME - Implement this using SDL
void dump_screen()
{
int i;
View
73 help.doc
@@ -1,6 +1,6 @@
@1
@1 ~fM ~bE G ~3A Z ~bE U ~fX
- @1 ~e2.80b
+ @1 ~e2.80c
@1
:072: ~eTable of Contents
@@ -34,11 +34,11 @@
>#ERRORMES.HLP:1st:Error Messages
>#MEGAZEUX.HLP:1st:MegaZeux Limitations
>#IFYOUFIN.HLP:1st:If You Find a Bug...
->#NEWINVER.HLP:1st:NEW in Version 2.80b!
+>#NEWINVER.HLP:1st:NEW in Version 2.80c!
$** Credits and Acknowledgments **
-$Mzx 2.80b Thanks & Beta testers:
+$Mzx 2.80c Thanks & Beta testers:
$Wervyn
$Exophase
$Quasar84
@@ -95,7 +95,7 @@ $~EWelcome to MegaZeux! Use the arrow keys to Scroll
$~Ethis text, and ESC when you are done reading.
$~BPress END to learn about the NEW FEATURES in
-$~BMegaZeux 2.80b!
+$~BMegaZeux 2.80c!
As you may already know, MegaZeux is a game system which
allows you to play almost limitless worlds in dated yet
@@ -133,7 +133,7 @@ the game.
>#CONTROLS.HLP:091:Controls
>#THEWORLD.HLP:1st:The World Editor
->#NEWINVER.HLP:1st:WHAT'S NEW in version 2.80b!
+>#NEWINVER.HLP:1st:WHAT'S NEW in version 2.80c!
#CONTROLS.HLP
:091:Controls
@@ -6374,7 +6374,68 @@ the target character set.
>#MAIN.HLP:072:Table of Contents
#NEWINVER.HLP
-:1st:NEW in Version 2.80b!
+:1st:NEW in Version 2.80c!
+
+August 16, 2004 - MZX 2.80c
++ Fixed issues with the commands counter not being reset
++ Color intensity now gets reset when you enter the editor
++ SAMs got cut off sometimes now.. fixed
++ Fixed bug where loading a world with empty boards could
+ change the starting, endgame, and death boards
++ Fixed bug where you could text enter off the bottom of the
+ board, causing problems
++ Fixed bug involving cutting/clearing the entire robot in the
+ robot editor while not at the first line
++ Fixed robot name entry for global robot not disappearing on
+ small boards
++ Fixed bug where you could duplicate the player by holding
+ down a direction as a saved game loads
++ Fixed bug where you could go to line 0 in the robot editor
++ Saving an MZM now auto-adds the .mzm extension...
++ Fixed black screen on quicksave
++ Fixed bug where opening a file didn't close the old one if
+ one was open (so it'd eventually crash MZX)
++ Changed alt+backspace behavior in intake so it doesn't exit
++ Added clipping for refx/refy/width/height for sprites (less
+ than 0 at initialization, greater than board width/height at
+ draw)
++ Fixed direction parsing for move all
++ Fixed bug where creating things on top of the player would
+ use a slot for robots/scrolls/signs/sensors instead of just
+ copy to the buffer
++ Added ability to use chars as immediates in Robotic commands
+ (ie, set "$str.0" 'a')
++ Added options to enable oversampling and specify resampling
+ mode in the config file (higher quality audio)
++ Building with patched modplug that fixes loading 2-channel
+ mods outputted by FT2. If you're building yourself, see
+ build.txt.
++ Fixed inability to mouse click in alt + h mode
++ Fixed ability to mouse click outside of board range
++ Should work better for Linux users; case insensitivity for
+ file opens has been added.
++ Fixed close bug that was affecting Linux builds (may affect
+ more)
++ Keypad enter works where normal enter works now
++ Fixed disappearing cursor when cancelling out of abandon
+ changes box when loading a new world in the editor
++ Fixed problems when loading/saving robots outside of ID range
+ (do not hardcode ID's people)
++ Fixed problem with NO BOARD exits being set to something else
+ when empty boards were being stripped or when worlds were
+ being imported
++ Fixed bug where auto-decrypting worlds didn't work if the XOR
+ value was negative
++ Fixed problem with rid not working the first cycle
++ Fixed inability to interpolate (with &&'s) counter names
+ larger than 14
++ Added new robot mem counter in debug box (only kb precise,
+ rounds up)
++ Fixed ability to clone the player on non-title board after
+ testing
++ Lengthened size of mod name buffers
++ Fixed bug where send x y doesn't work from the global robot
++ Fixed a few bugs that could cause MZX to crash
August 11, 2004 - MZX 2.80b
View
18 intake.cpp
@@ -228,6 +228,7 @@ int intake(char *string, int max_len, char x, char y,
break;
}
+ case SDLK_KP_ENTER:
case SDLK_RETURN:
{
// Enter
@@ -361,21 +362,22 @@ int intake(char *string, int max_len, char x, char y,
case SDLK_BACKSPACE:
{
// Backspace, at 0 it might exit
- if(currx == 0)
+ if(get_alt_status(keycode_SDL))
+ {
+ // Alt-backspace, erase input
+ curr_len = currx = 0;
+ string[0] = 0;
+ }
+ else
+
+ if(currx == 0)
{
if(exit_type == 2)
{
done = 1;
}
}
- else
- if(get_alt_status(keycode_SDL))
- {
- // Alt-backspace, erase input
- curr_len = currx = 0;
- string[0] = 0;
- }
else
{
// Move all back 1, decreasing string length
View
8 main.cpp
@@ -115,5 +115,13 @@ int main(int argc, char **argv)
vquick_fadeout();
+ if(mzx_world.active)
+ {
+ clear_world(&mzx_world);
+ clear_global_data(&mzx_world);
+ }
+
+ SDL_Quit();
+
return 0;
}
View
6 port.txt
@@ -156,6 +156,8 @@ are the changes:
- The same goes for strings, which may now have any name, so long as
it begins with a dollar sign ($). The same conventions regarding
strings in 2.68+ still apply (see 268_info.txt for more information)
+- Local2 and local3 no longer have dangerous side-effects. Local4
+ through local32 are also available per-robot now.
A warning: I have tried my best to make it impossible to exceed these
limits, however, you may be able to somehow. If you do, don't save the
@@ -253,6 +255,10 @@ original as possible. These are the differences:
in the char editor. You may also select a default SMZX charset.
- Anywhere you can enter a line of text you can now press ctrl + left
and ctrl + right to go to the previous/next word.
+- This isn't totally limited to the editor, but now everywhere a
+ selection box shows up (such as for files, boards, items) you can
+ press multiple keys to seek to a specific entry. Furthermore, in
+ file selection boxes you can press backspace to go up a directory.
- The SMZX char editor has been changed quite a bit. First, to use, you
must be in SMZX modes 1-3 (toggle using F11).
View
15 rasm.cpp
@@ -4,6 +4,7 @@
#include <stdlib.h>
#include "rasm.h"
+#include "fsafeopen.h"
int cm3[] = { IGNORE_FOR, IMM_U16 | STRING };
int cm4[] = { IMM_U16 | STRING };
@@ -1324,10 +1325,14 @@ int match_command(mzx_command *cmd, char *error_buffer)
if((cmd->param_types[i3] & command_list[i].param_types[i2]) !=
cmd->param_types[i3])
{
- print_error(i3, error_buffer, cmd->param_types[i3],
- command_list[i].param_types[i2]);
-
- break;
+ // Can allow char if imm is allowed
+ if(!((cmd->param_types[i3] & CHARACTER) &&
+ (command_list[i].param_types[i2] & (IMM_S16 | IMM_U16))))
+ {
+ print_error(i3, error_buffer, cmd->param_types[i3],
+ command_list[i].param_types[i2]);
+ break;
+ }
}
i3++;
@@ -1727,7 +1732,7 @@ int assemble_command(int command_number, mzx_command *cmd, void *params[32],
char *assemble_file(char *name, int *size)
{
- FILE *input_file = fopen(name, "rt");
+ FILE *input_file = fsafeopen(name, "rt");
char line_buffer[256];
char bytecode_buffer[256];
char error_buffer[256];
View
9 robo_ed.cpp
@@ -36,6 +36,7 @@
#include "char_ed.h"
#include "helpsys.h"
#include "edit.h"
+#include "fsafeopen.h"
#define combine_colors(a, b) \
(a) | (b << 4) \
@@ -471,6 +472,7 @@ void robot_editor(World *mzx_world, Robot *cur_robot)
break;
}
+ case SDLK_KP_ENTER:
case SDLK_RETURN:
{
if(current_x)
@@ -799,8 +801,8 @@ void robot_editor(World *mzx_world, Robot *cur_robot)
if(line > total_lines)
line = total_lines;
-