Example #1
0
void
sys_string_acquire(sys_strings_t *strings, int index, const char *name, int max_len)
{
	sys_string_t *str = strings->strings + index;

	if (index < 0 || index >= SYS_STRINGS_MAX) {
		fprintf(stderr, "[SYSSTR] Error: Attempt to acquire string #%d\n",
			index);
		BREAKPOINT();
	}

	if (str->name
	    && (strcmp(name, str->name)
		|| (str->max_size != max_len))) {
		fprintf(stderr, "[SYSSTR] Error: Attempt to re-acquire existing string #%d;"
			"was '%s', tried to claim as '%s'\n",
			index, str->name, name);
		BREAKPOINT();
	}

	str->name = strdup(name);
	str->max_size = max_len;
	str->value = (char*)sci_malloc(max_len + 1);
	str->value[0] = 0; /* Set to empty string */
}
Example #2
0
static sci_module_t *
_sci_try_open_module(char *filename, char *path, char *struct_name, void **handle)
{
	char *fullname = sci_malloc(strlen(path) + strlen(DIR_SEPARATOR_STR)
				+ strlen(filename));
	sci_module_t *module;
fprintf(stderr,"Trying module %s at %s\n", filename, path);
	strcpy(fullname, path);
	strcat(fullname, DIR_SEPARATOR_STR);
	strcat(fullname, filename);

fprintf(stderr,"Total name is %s\n", fullname);
	*handle = dlopen(fullname, RTLD_NOW);
fprintf(stderr,"Could not open because: %s\n", dlerror());
	free(fullname);

	if (!*handle)
		return NULL;

	module = (sci_module_t *) dlsym(*handle, struct_name);
	if (!module)
		fprintf(stderr,"%s: Failed to find symbol '%s'.\n",
			fullname, struct_name);

	return module;
}
Example #3
0
static exe_handle_t *
lzexe_open(const char *filename)
{
	exe_handle_t *handle;
	guint8 head[0x20];
	guint8 size[2];
	off_t fpos;

	FILE *f = sci_fopen(filename, "rb");

	if (!f)
		return NULL;

	/* Read exe header plus possible lzexe signature. */
	if (fread(head, 1, 0x20, f) != 0x20)
		return NULL;

	/* Verify "MZ" signature, header size == 2 paragraphs and number of
	** overlays == 0.
	*/
	if (UINT16(head) != 0x5a4d || UINT16(head + 8) != 2
	    || UINT16(head + 0x1a) != 0)
		return NULL;

	/* Verify that first relocation item offset is 0x1c. */
	if (UINT16(head + 0x18) != 0x1c)
		return NULL;

	/* Look for lzexe signature. */
	if (memcmp(head + 0x1c, "LZ09", 4)
            && memcmp(head + 0x1c, "LZ91", 4)) {
		return NULL;
	}

	/* Calculate code segment offset in exe file. */
	fpos = (UINT16(head + 0x16) + UINT16(head + 8)) << 4;
	/* Seek to offset 8 of info table at start of code segment. */
	if (fseek(f, fpos + 8, SEEK_SET) == -1)
		return NULL;

	/* Read size of compressed data in paragraphs. */
	if (fread(size, 1, 2, f) != 2)
		return NULL;

	/* Move file pointer to start of compressed data. */
	fpos -= UINT16(size) << 4;
	if (fseek(f, fpos, SEEK_SET) == -1)
		return NULL;

	handle = (exe_handle_t*)sci_malloc(sizeof(exe_handle_t));

	if (!lzexe_init(handle, f)) {
		sci_free(handle);
		return NULL;
	}

	return handle;
}
Example #4
0
static int
mix_init(sfx_pcm_mixer_t *self, sfx_pcm_device_t *device)
{
	self->dev = device;
	self->private_bits /* = P */ = sci_malloc(sizeof(struct mixer_private));
	P->outbuf = P->writebuf = NULL;
	P->lastbuf_len = 0;
	P->compbuf_l = (gint32*)sci_malloc(sizeof(gint32) * device->buf_size);
	P->compbuf_r = (gint32*)sci_malloc(sizeof(gint32) * device->buf_size);
	P->played_this_second = 0;
	P->paused = 0;
#ifdef DEBUG
	sciprintf("[soft-mixer] Initialised device %s v%s (%d Hz, %d/%x)\n",
		  device->name, device->version,
		  device->conf.rate, device->conf.stereo, device->conf.format);
#endif
	return SFX_OK;
}
Example #5
0
void
_scir_add_altsource(resource_t *res, int file, unsigned int file_offset)
{
	resource_source_t *rsrc = (resource_source_t*)sci_malloc(sizeof(resource_source_t));

	rsrc->next = res->alt_sources;
	rsrc->file = file;
	rsrc->file_offset = file_offset;
	res->alt_sources = rsrc;
}
Example #6
0
int main(int argc, char **argv)
{
  int fd1, fd2;
  unsigned char *patch001;
  unsigned char *patch004;
  unsigned int length001, length004;

  if (argc < 2)
    return -1;

  if ((fd1 = open(argv[1], O_RDONLY)) < 0)
    return -1;
  if ((fd2 = open(argv[2], O_RDONLY)) < 0) {
    close(fd1);
    return -1;
  }

  patch001 = (unsigned char *)sci_malloc(65536);
  length001 = read(fd1, patch001, 65536);
  close(fd1);

  patch004 = (unsigned char *)sci_malloc(65536);
  length004 = read(fd2, patch004, 65536);
  close(fd2);

  if (patch001[0] == 0x89 && patch001[1] == 0x00)
    if (patch004[0] == 0x89 && patch004[1] == 0x00)
      analyze(patch001 + 2, length001 - 2, patch004 + 2, length004 - 2);
    else
      analyze(patch001 + 2, length001 - 2, patch004, length004);
  else
    if (patch004[0] == 0x89 && patch004[1] == 0x00)
      analyze(patch001, length001, patch004 + 2, length004 - 2);
    else
      analyze(patch001, length001, patch004, length004);

  free(patch001);
  free(patch004);

  return 0;
}
static object* object_new() {
	object* obj = (object*)sci_malloc(sizeof(object));
	if (obj == 0) return 0;

	obj->parent = 0;
	FLEXARRAY_INIT(object*, obj->children);
	obj->name = 0;
	obj->selector_count = 0;
	obj->selector_numbers = 0;
	obj->methods = 0;
	obj->method_count = 0;

	return obj;
}
Example #8
0
static void
_scir_load_from_patch_file(int fh, resource_t *res, char *filename)
{
	int really_read;

	res->data = (unsigned char*)sci_malloc(res->size);
	really_read = read(fh, res->data, res->size);

	if (really_read < res->size) {
		sciprintf("Error: Read %d bytes from %s but expected %d!\n",
			  really_read, filename, res->size);
		exit(1);
	}

	res->status = SCI_STATUS_ALLOCATED;
}
Example #9
0
void
sys_strings_restore(sys_strings_t *new_strings, sys_strings_t *old_strings)
{
	int i;

	/* First, pad memory */
	for (i = 0; i < SYS_STRINGS_MAX; i++) {
		sys_string_t *s = new_strings->strings + i;
		char *data = s->value;
		if (data) {
			s->value = (char *)sci_malloc(s->max_size + 1);
			strcpy(s->value, data);
			sci_free(data);
		}
	}

	sys_string_set(new_strings, SYS_STRING_SAVEDIR, old_strings->strings[SYS_STRING_SAVEDIR].value);
}
Example #10
0
static void
antialiase_simple(gfx_pixmap_t *pixmap, int mask[], int shift_const, gfx_mode_t *mode)
{
	int x, y, c;
	int bytespp = mode->bytespp;
	int line_size = bytespp * pixmap->xl;
	char *lastline[2];
	char *lastline_p = NULL;
	char *data_p = (char *) pixmap->data;

	lastline[0] = (char*)sci_malloc(line_size);
	lastline[1] = (char*)sci_malloc(line_size);

	for (y = 0; y < pixmap->yl; y++) {
		int visimode = (y > 0 && y+1 < pixmap->yl)? 1 : 0;
		unsigned long last_pixel;

		memcpy(lastline[y & 1], data_p, line_size);
		lastline_p = lastline[(y & 1)^1];

		for (x = 0; x < pixmap->xl; x++) {
			unsigned long result = 0;

			if (x == 1)
				visimode++;
			else if (x+1 == pixmap->xl)
				visimode--;

			for (c = 0; c < 3; c++) {
				unsigned long accum = 0;
				unsigned long reader = 0;
				int y_mode;

				/* Yes, bad compilers will read three times as often as neccessary.
				** This optimization is straightforward to detect (common subexpression
				** elemination), so I prefer to write the stuff semi-legibly...
				*/
				for (y_mode = 0; y_mode < 2; y_mode++)
					if ((y_mode == 0 && y > 0)
					    || (y_mode == 1 && y+1 < pixmap->yl)) {

						char *src = (y_mode)? data_p + line_size : lastline_p;

						if (x > 0) {
							memcpy(&reader, src - bytespp, bytespp);
							accum += ((reader >> shift_const) & mask[c]) << 0;
						}

						memcpy(&reader, src, bytespp);
						accum += ((reader >> shift_const) & mask[c]) << 1;

						if (x+1 < pixmap->xl) {
							memcpy(&reader, src + bytespp, bytespp);
							accum += ((reader >> shift_const) & mask[c]) << 0;
						}
					}

				if (x > 0)
					accum += ((last_pixel >> shift_const) & mask[c]) << 1;

				memcpy(&reader, data_p, bytespp);
				if (c == 2)
					last_pixel = reader;
				accum += ((reader >> shift_const) & mask[c]) << 2;

				if (x+1 < pixmap->xl) {
					memcpy(&reader, data_p + bytespp, bytespp);
					accum += ((reader >> shift_const) & mask[c]) << 1;
				}
Example #11
0
void *
sci_find_module(char *path, char *name, char *type, char *struct_prefix,
		char *file_suffix, int magic, int version, void **handle)
{
	char *module_name = sci_malloc(strlen(type) + strlen(DIR_SEPARATOR_STR)
				 + strlen(name) + strlen(file_suffix)
				 + strlen(MODULE_NAME_SUFFIX) + 1);
	char *struct_name = sci_malloc(strlen(struct_prefix) + strlen(name) + 1);
	char *dir_end;
	char *path_pos = path;
	char path_separator = PATH_SEPARATOR_STR[0];
	sci_module_t *module = NULL;

	strcpy(module_name, type);
	strcat(module_name, DIR_SEPARATOR_STR);
	strcat(module_name, name);
	strcat(module_name, file_suffix);
	strcat(module_name, MODULE_NAME_SUFFIX);

	strcpy(struct_name, struct_prefix);
	strcat(struct_name, name);

	do {
		dir_end = strchr(path_pos, path_separator);
		if (dir_end)
			*dir_end = 0;

		module = _sci_try_open_module(module_name, path_pos,
					      struct_name, handle);

		if (module) {
			if (module->class_magic != magic) {
				fprintf(stderr, "%s at %s is not a %s module, skipping...\n",
					module_name, path_pos, type);
				dlclose(*handle);
				module = NULL;
			} else if (module->class_version != version) {
				fprintf(stderr, "%s at %s has %s module version %d,"
					" expected %d- skipping...\n",
					module_name, path_pos, type, module->class_version,
					version);
				dlclose(*handle);
				module = NULL;
			}
		}

		if (dir_end) {
			*dir_end = path_separator;
			path_pos = dir_end + 1;
		}

	} while (!module && dir_end);

	if (!module) {
		*handle = NULL;
		fprintf(stderr,"%s module '%s' not found in path '%s'.\n",
			type, name, path);
	} else {
		if (dir_end)
			*dir_end = 0;

		printf("Using %s driver '%s', version %s, from '%s'.\n",
		       type, module->module_name, module->module_version,
		       path_pos);

		if (dir_end)
			*dir_end = path_separator;
	}

	free(module_name);
	free(struct_name);

	return (void *) module;
}
Example #12
0
resource_mgr_t *
scir_new_resource_manager(char *dir, int version,
			  char allow_patches, int max_memory)
{
	int resource_error = 0;
	resource_mgr_t *mgr = (resource_mgr_t*)sci_malloc(sizeof(resource_mgr_t));
	char *caller_cwd = sci_getcwd();
	int resmap_version = version;

	if (chdir(dir)) {
		sciprintf("Resmgr: Directory '%s' is invalid!\n", dir);
		free(caller_cwd);
		return NULL;
	}

	mgr->max_memory = max_memory;

	mgr->memory_locked = 0;
	mgr->memory_lru = 0;

	mgr->resource_path = dir;

	mgr->resources = NULL;

	if (version <= SCI_VERSION_01_VGA_ODD
	    /* || version == SCI_VERSION_AUTODETECT -- subsumed by the above line */) {
		resource_error =
			sci0_read_resource_map(dir,
					       &mgr->resources,
					       &mgr->resources_nr,
					       &resmap_version);

		if (resource_error >= SCI_ERROR_CRITICAL) {
			sciprintf("Resmgr: Error while loading resource map: %s\n",
				  sci_error_types[resource_error]);
			if (resource_error == SCI_ERROR_RESMAP_NOT_FOUND)
				sciprintf("Running SCI games without a resource map is not supported ATM\n");
			sci_free(mgr);
			chdir(caller_cwd);
			free(caller_cwd);
			return NULL;
		}

		if (resource_error == SCI_ERROR_RESMAP_NOT_FOUND) {
			/* fixme: Try reading w/o resource.map */
			resource_error = SCI_ERROR_NO_RESOURCE_FILES_FOUND;
		}

		if (resource_error == SCI_ERROR_NO_RESOURCE_FILES_FOUND) {
			/* Initialize empty resource manager */
			_scir_init_trivial(mgr);
			resource_error = 0;
		}

	}

	if ((version == SCI_VERSION_1_EARLY)||
	    (version == SCI_VERSION_1_LATE)||
	    (version == SCI_VERSION_1_1)||
	    ((resmap_version == SCI_VERSION_AUTODETECT)&&(version == SCI_VERSION_AUTODETECT)))
	{
		resource_error =
			sci1_read_resource_map(dir,
					       &mgr->resources,
					       &mgr->resources_nr,
					       &resmap_version);

		if (resource_error >= SCI_ERROR_CRITICAL) {
			sciprintf("Resmgr: Error while loading resource map: %s\n",
				  sci_error_types[resource_error]);
			if (resource_error == SCI_ERROR_RESMAP_NOT_FOUND)
				sciprintf("Running SCI games without a resource map is not supported ATM\n");
			sci_free(mgr);
			chdir(caller_cwd);
			free(caller_cwd);
			return NULL;
		}

		if (resource_error == SCI_ERROR_RESMAP_NOT_FOUND) {
			/* fixme: Try reading w/o resource.map */
			resource_error = SCI_ERROR_NO_RESOURCE_FILES_FOUND;
		}

		if (resource_error == SCI_ERROR_NO_RESOURCE_FILES_FOUND) {
			/* Initialize empty resource manager */
			_scir_init_trivial(mgr);
			resource_error = 0;
		}

		resmap_version = SCI_VERSION_1;
	}
		
	if (!mgr->resources || !mgr->resources_nr) {
		if (mgr->resources) {
			free(mgr->resources);
			mgr->resources = NULL;
		}
		sciprintf("Resmgr: Could not retreive a resource list!\n");
		sci_free(mgr);
		chdir(caller_cwd);
		free(caller_cwd);
		return NULL;
	}

	mgr->lru_first = NULL;
	mgr->lru_last = NULL;

	mgr->allow_patches = allow_patches;

	qsort(mgr->resources, mgr->resources_nr, sizeof(resource_t),
	      resourcecmp); /* Sort resources */

	if (version == SCI_VERSION_AUTODETECT)
		switch (resmap_version) {
		case SCI_VERSION_0:
			if (scir_test_resource(mgr, sci_vocab,
					       VOCAB_RESOURCE_SCI0_MAIN_VOCAB)) {
				version = sci_test_view_type(mgr);
				if (version == SCI_VERSION_01_VGA)
				{
					sciprintf("Resmgr: Detected KQ5 or similar\n");
				} else {
					sciprintf("Resmgr: Detected SCI0\n");
					version = SCI_VERSION_0;
				}
			} else if (scir_test_resource(mgr, sci_vocab,
						      VOCAB_RESOURCE_SCI1_MAIN_VOCAB)) {
				version = sci_test_view_type(mgr);
				if (version == SCI_VERSION_01_VGA)
				{
					sciprintf("Resmgr: Detected KQ5 or similar\n");
				} else {
					if (scir_test_resource(mgr, sci_vocab, 912)) {
						sciprintf("Resmgr: Running KQ1 or similar, using SCI0 resource encoding\n");
						version = SCI_VERSION_0;
					} else {
						version = SCI_VERSION_01;
						sciprintf("Resmgr: Detected SCI01\n");
					}
				}
			} else {
				version = sci_test_view_type(mgr);
				if (version == SCI_VERSION_01_VGA)
				{
					sciprintf("Resmgr: Detected KQ5 or similar\n");
				} else {
					sciprintf("Resmgr: Warning: Could not find vocabulary; assuming SCI0 w/o parser\n");
					version = SCI_VERSION_0;
				}
			} break;
		case SCI_VERSION_01_VGA_ODD:
			version = resmap_version;
			sciprintf("Resmgr: Detected Jones/CD or similar\n");
			break;
		case SCI_VERSION_1:
		{
			resource_t *res = scir_test_resource(mgr, sci_script, 0);
			
			mgr->sci_version = version = SCI_VERSION_1_EARLY;
			_scir_load_resource(mgr, res, 1);
			
			if (res->status == SCI_STATUS_NOMALLOC)
			    mgr->sci_version = version = SCI_VERSION_1_LATE;

			/* No need to handle SCI 1.1 here - it was done in resource_map.c */
			break;
		}
		default:
			sciprintf("Resmgr: Warning: While autodetecting: Couldn't"
				  " determine SCI version!\n");
		}

	if (!resource_error)
	{
		if (version <= SCI_VERSION_01)
			sci0_read_resource_patches(dir,
						   &mgr->resources,
						   &mgr->resources_nr);
		else
			sci1_read_resource_patches(dir,
						   &mgr->resources,
						   &mgr->resources_nr);

		qsort(mgr->resources, mgr->resources_nr, sizeof(resource_t),
		      resourcecmp); /* Sort resources */
	}

	mgr->sci_version = version;

	chdir(caller_cwd);
	free(caller_cwd);

	return mgr;
}
Example #13
0
static void
_scir_init_trivial(resource_mgr_t *mgr)
{
	mgr->resources_nr = 0;
	mgr->resources = (resource_t*)sci_malloc(1);
}
Example #14
0
static void
mix_subscribe(sfx_pcm_mixer_t *self, sfx_pcm_feed_t *feed)
{
	sfx_pcm_feed_state_t *fs;
	ACQUIRE_LOCK();
	if (!self->feeds) {
		self->feeds_allocd = 2;
		self->feeds = (sfx_pcm_feed_state_t*)sci_malloc(sizeof(sfx_pcm_feed_state_t)
					 * self->feeds_allocd);
	} else if (self->feeds_allocd == self->feeds_nr) {
		self->feeds_allocd += 2;
		self->feeds = (sfx_pcm_feed_state_t*)sci_realloc(self->feeds,
					  sizeof(sfx_pcm_feed_state_t)
					  * self->feeds_allocd);
	}

	fs = self->feeds + self->feeds_nr++;
	fs->feed = feed;

	feed->frame_size = SFX_PCM_FRAME_SIZE(feed->conf);

	/*	fs->buf_size = (self->dev->buf_size
			  * (feed->conf.rate
			     + self->dev->conf.rate - 1))
		/ self->dev->conf.rate;
	*/
	/* For the sake of people without 64 bit CPUs: */
	fs->buf_size = 2 + /* Additional safety */
		(self->dev->buf_size *
			(1 + (feed->conf.rate / self->dev->conf.rate)));
fprintf(stderr, " ---> %d/%d/%d/%d = %d\n",
	self->dev->buf_size,
	feed->conf.rate,
	self->dev->conf.rate,
	feed->frame_size,
	fs->buf_size);

	fs->buf = (byte*)sci_malloc(fs->buf_size * feed->frame_size);
fprintf(stderr, " ---> --> %d for %p at %p\n", fs->buf_size * feed->frame_size, (void *)fs, (void *)fs->buf);
{int i; for (i = 0; i < fs->buf_size * feed->frame_size; i++)
fs->buf[i] = 0xa5; }
	fs->scount = urat(0, 1);
	fs->spd = urat(feed->conf.rate, self->dev->conf.rate);
	fs->scount.den = fs->spd.den;
	fs->ch_old.left = 0;
	fs->ch_old.right = 0;
	fs->ch_new.left = 0;
	fs->ch_new.right = 0;
	fs->mode = SFX_PCM_FEED_MODE_ALIVE;

	/* If the feed can't provide us with timestamps, we don't need to wait for it to do so */
	fs->pending_review = (feed->get_timestamp)? 1 : 0;

	fs->frame_bufstart = 0;

#ifdef DEBUG
	sciprintf("[soft-mixer] Subscribed %s-%x (%d Hz, %d/%x) at %d+%d/%d, buffer size %d\n",
		  feed->debug_name, feed->debug_nr, feed->conf.rate, feed->conf.stereo, feed->conf.format,
		  fs->spd.val, fs->spd.nom, fs->spd.den, fs->buf_size);
#endif
	RELEASE_LOCK();
}
Example #15
0
static object* read_object(resource_mgr_t *resmgr, int script, int positions[1000]) {
	resource_t* r = scir_find_resource(resmgr, sci_script, script, 0);
	unsigned char* raw;
	int pos;
	object* obj;

	printf("Searching for object in script %03d\n", script);

	if (r == 0) return 0;

	/*Skip to the next object*/
#ifdef SCRIPT_DEBUG
	printf("pre skip: pos=%#x\n", positions[script]);
#endif
	pos = find_frame(r, 1, positions[script]);
#ifdef SCRIPT_DEBUG
	printf("post skip: pos=%#x\n", pos);
#endif
	if (pos == -1) return 0;
	else positions[script] = pos + get_length(r->data + pos);
#ifdef SCRIPT_DEBUG
	printf("post post: pos=%#x (len=%#x)\n", positions[script], get_length(r->data + pos));
#endif

	/*Construct the object*/
	obj = object_new();
	raw = r->data + pos;

	/*Fill in the name*/
	if (get_selector_count(raw) < 4) obj->name = "<anonymous>";
	else {
		if (get_selector_value(raw, 3))
			obj->name = (char *) r->data + get_selector_value(raw, 3);
		else obj->name = "<null>";
	}

	/*Fill in the class*/
	if (get_selector_count(raw) == 0) obj->parent = object_root;
	else {
		int parent_id = get_selector_value(raw, 1);
		if (parent_id >= fobjects.used) {
			free(obj);
			return 0;
		}
		if (parent_id < 1) obj->parent = object_root;
		else obj->parent = fobjects.data[parent_id];
	}

	/*Add the object to the class*/
	if (!obj->parent) {
		free(obj);
		return 0;
	}
	if (add_child(obj->parent, obj)) {
		free(obj);
		return 0;
	}
	if (add_object(obj)) {
		free(obj);
		return 0;
	}

	/*FIXME: decode selectors here*/

	obj->method_count = get_method_count(raw);
	obj->methods = (script_method**)sci_malloc(obj->method_count * sizeof(script_method));
	if (obj->methods == 0) {
		free(obj);
		return 0;
	} else {
		int i;
		for (i = 0; i < obj->method_count; i++) {
			int number = get_method_number(raw, i);
			int position = get_method_location(raw, i);

			if ((obj->methods[i] = decode_method(r->data + position)) == 0) {
				obj->method_count = i - 1;
				break;
			}
			obj->methods[i]->number = number;
		}
	}

	return obj;
}
Example #16
0
static script_method* decode_method(byte* data) {
	script_method* m;
	int done = 0;
	int pos = 0;
	static int count = 0;

	count++;

	if ((m = (script_method*)sci_malloc(sizeof(script_method))) == 0) return 0;
	FLEXARRAY_INIT(script_opcode, *m);

	while (!done) {
		int op = data[pos] >> 1;
		int size = 2 - (data[pos] & 1);
		int* args[3];
		int arg;
		int old_pos;

		FLEXARRAY_ADD_SPACE(script_opcode, *m, 1, return 0);
		old_pos = pos;
		m->data[m->used-1].pos = pos;
		m->data[m->used-1].opcode = op;

		/*Copy the adresses of the args to an array for convenience*/
		args[0] = &m->data[m->used-1].arg1;
		args[1] = &m->data[m->used-1].arg2;
		args[2] = &m->data[m->used-1].arg3;

		/*Skip past the opcode*/
		pos++;

		for (arg = 0; arg < 4; arg++) {
			switch (formats[op][arg]) {
			case Script_Invalid: { /*Can't happen(tm)*/
				int i;
				printf("Invalid opcode %02X at %04X in method %d\n", op, pos, count);
				for (i = m->used - 9; i < m->used - 1; i++) {
					printf("%s[%02X] ", opcodes[m->data[i].opcode].name, m->data[i].opcode);
					dump(data + m->data[i].pos, m->data[i].size);
				}
				printf("Dump from %04X-%04X\n", pos - 16, pos + 16);
				dump(data + pos - 16, 32);
			}
			break;
			case Script_None: { /*No more args*/
				arg = 4;
			}
			break;
			case Script_Byte: /*Just a one byte arg*/
			case Script_SByte: {
				*args[arg] = data[pos++];
			}
			break;
			case Script_Word: { /*A two byte arg*/
				*args[arg] = getInt16(data + pos);
				pos += 2;
			}
			break;
			case Script_SWord: { /*A signed two-byte arg*/
				int t = getInt16(data + pos);
				if (t&0x8000) *args[arg] = -(t & 0x7FFF);
				else *args[arg] = t;
				pos += 2;
			}
			break;
			case Script_Variable: /*Size of arg depends on LSB in opcode*/
			case Script_SVariable:
			case Script_SRelative:
			case Script_Property:
			case Script_Global:
			case Script_Local:
			case Script_Temp:
			case Script_Param: {
				if (size == 1) *args[arg] = data[pos++];
				else {
					*args[arg] = getInt16(data + pos);
					pos += 2;
				}
			}
			break;
			case Script_End: { /*Special tag for ret*/
				done = 1;
				arg = 4;
			}
			break;
			default: { /*Can't happen(tm)*/
				printf("Unknown argument format %d for op %02X\n", formats[op][arg], op);
			}
			break;
			}
		}
		fflush(stdout);
		if (m->used) m->data[m->used-1].size = pos - old_pos;
	}

	return m;
}