+ private float DrawScale;
+
+ private Engine:Palette *Palette = NULL destroywith g_object_unref;
+ private Engine:Texture *DetailTexture = NULL destroywith g_object_unref;
+
+ private struct engine_texture_data **mipmap_data;
+ private unsigned char mipmap_count;
+
+ interface U:Object:Loadable
+ private int load(U:Object *uo)
+ {
+ struct engine_texture_data **data;
+ Self *self = SELF(uo);
+
+ if (upkg_export_seek(uo->pkg_file, 0, SEEK_SET) != 0)
+ return -1;
+
+ data = malloc(self->_priv->mipmap_count * sizeof *data);
+ if (!data)
+ return -1;
+
+ for (int i = 0; i < self->_priv->mipmap_count; i++) {
+ data[i] = decode_mipmap(uo);
+ if (!data[i]) {
+ u_err(uo, "error decoding mipmap level %d", i);
+
+ /* Unwind the allocations. */
+ for (; i >= 0; i--)
+ free(data[i]);
+ free(data);
+ return -1;
+ }
+ }
+
+ self->_priv->mipmap_data = data;
+ return 0;
+ }
+
+ interface U:Object:Loadable
+ private void unload(U:Object *uo)
+ {
+ Self *self = SELF(uo);
+
+ for (int i = 0; i < self->_priv->mipmap_count; i++)
+ free(self->_priv->mipmap_data[i]);
+ free(self->_priv->mipmap_data);
+ self->_priv->mipmap_data = NULL;
+ }
+
+ interface U:Object:Exportable
+ private int export_name(U:Object *uo, char *buf, size_t n)
+ {
+ return snprintf(buf, n, "%s.pcx", uo->pkg_file->name);
+ }
+
+ interface U:Object:Exportable
+ private int export(U:Object *uo, FILE *f)
+ {
+ Self *self = SELF(uo);
+ struct engine_texture_data *data;
+ struct pcx_head head;
+
+ if (!self->_priv->mipmap_data || !self->_priv->Palette)
+ return -1;
+ data = self->_priv->mipmap_data[0];
+
+ head.width = data->width;
+ head.height = data->height;
+
+ if (pcx_init_header(&head) != 0)
+ return -1;
+ if (fwrite(head.encoded, sizeof head.encoded, 1, f) != 1)
+ return -1;
+
+ for (unsigned i = 0; i < head.height; i++) {
+ if (pcx_write_scanline(&head, data->data+i*data->width,
+ f) != 0) {
+ return -1;
+ }
+ }
+
+ if (pcx_write_palette(self->_priv->Palette, f) != 0)
+ return -1;
+
+ return 0;
+ }
+
+ override (U:Object) int deserialize(U:Object *uo)
+ {
+ struct upkg_file *f = uo->pkg_file;
+ Self *self = SELF(uo);
+
+ PARENT_HANDLER(uo);
+
+ if (upkg_export_read(f, &self->_priv->mipmap_count, 1) != 1)
+ return -1;
+ if (self->_priv->mipmap_count == 0)
+ return -1;
+
+ f->base += 1;
+ f->len -= 1;
+ upkg_export_seek(f, 0, SEEK_SET);
+
+ return 0;
+ }