m-chrzan.xyz
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--char.c89
-rw-r--r--harddoomdev.c55
-rw-r--r--harddoomdev.h4
-rw-r--r--private_data.h9
-rw-r--r--surface.c48
5 files changed, 193 insertions, 12 deletions
diff --git a/char.c b/char.c
index b1c52ec..bb70d1b 100644
--- a/char.c
+++ b/char.c
@@ -251,9 +251,96 @@ error_data:
return err;
}
+void free_colors(struct colors_data *colors_data);
+int colors_release(struct inode *inode, struct file *filp)
+{
+ struct colors_data *colors_data;
+
+ colors_data = filp->private_data;
+
+ free_colors(colors_data);
+
+ kfree(colors_data);
+
+ return 0;
+}
+
+struct file_operations colors_fops = {
+ .owner = THIS_MODULE,
+ .release = colors_release
+
+};
+
+int alloc_colors(struct doomdev_ioctl_create_colormaps *params,
+ struct colors_data *colors_data)
+{
+ int err;
+ int not_written;
+
+ colors_data->number = params->num;
+
+ colors_data->colors_cpu =
+ dma_alloc_coherent(colors_data->doom_data->pci_device,
+ HARDDOOM_COLORMAP_SIZE * params->num,
+ &colors_data->colors_dev,
+ GFP_KERNEL);
+ ORFAIL_NULL(colors_data->colors_cpu, -ENOMEM, error_colors);
+
+ not_written = copy_from_user(colors_data->colors_cpu,
+ (void __user *) params->data_ptr,
+ HARDDOOM_COLORMAP_SIZE * params->num);
+
+ if (not_written) {
+ err = -EFAULT;
+ goto error_copy;
+ }
+
+ return 0;
+
+error_copy:
+ dma_free_coherent(colors_data->doom_data->pci_device,
+ HARDDOOM_COLORMAP_SIZE * params->num,
+ colors_data->colors_cpu, colors_data->colors_dev);
+error_colors:
+ return err;
+
+}
+
+void free_colors(struct colors_data *colors_data)
+{
+ dma_free_coherent(colors_data->doom_data->pci_device,
+ HARDDOOM_COLORMAP_SIZE * colors_data->number,
+ colors_data->colors_cpu, colors_data->colors_dev);
+}
+
long doom_create_colormaps(struct file *filp, unsigned long arg)
{
- return -1;
+ int err;
+ struct doomdev_ioctl_create_colormaps *params;
+ struct colors_data *colors_data;
+ int fd;
+ struct doom_data *doom_data;
+
+ params = (struct doomdev_ioctl_create_colormaps *) arg;
+
+ colors_data = kmalloc(sizeof(*colors_data), GFP_KERNEL);
+ ORFAIL_NULL(colors_data, -ENOMEM, error_data);
+ doom_data = container_of(filp->f_inode->i_cdev, struct doom_data, cdev);
+ colors_data->doom_data = doom_data;
+
+ ORFAIL(alloc_colors(params, colors_data), error_colors);
+
+ fd = anon_inode_getfd("doom_colors", &colors_fops, colors_data, 0);
+ ORFAIL(fd, error_inode);
+
+ return fd;
+
+error_inode:
+ free_colors(colors_data);
+error_colors:
+ kfree(colors_data);
+error_data:
+ return err;
}
long doom_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
diff --git a/harddoomdev.c b/harddoomdev.c
index c4489aa..067293e 100644
--- a/harddoomdev.c
+++ b/harddoomdev.c
@@ -149,6 +149,22 @@ void set_flat(struct doom_data *doom_data, dma_addr_t flat_dev)
}
}
+void set_colormap(struct doom_data *doom_data, dma_addr_t colors_dev)
+{
+ if (doom_data->colors_addr != colors_dev) {
+ doom_data->colors_addr = colors_dev;
+ send_command(doom_data, HARDDOOM_CMD_COLORMAP_ADDR(colors_dev));
+ }
+}
+
+void set_trans(struct doom_data *doom_data, dma_addr_t colors_dev)
+{
+ if (doom_data->trans_addr != colors_dev) {
+ doom_data->trans_addr = colors_dev;
+ send_command(doom_data, HARDDOOM_CMD_TRANSLATION_ADDR(colors_dev));
+ }
+}
+
void set_ustart(struct doom_data *doom_data, uint32_t ustart)
{
send_command(doom_data, HARDDOOM_CMD_USTART(ustart));
@@ -211,17 +227,35 @@ void copy_rect(struct surface_data *dst_data, struct surface_data *src_data,
}
void draw_column(struct surface_data *surface_data,
- struct texture_data *texture_data, struct doomdev_column column)
+ struct texture_data *texture_data, struct doomdev_column column,
+ struct colors_data *colors_data, struct colors_data *trans_data,
+ uint8_t flags, uint8_t trans_idx)
{
set_surf_dst_pt(surface_data->doom_data, surface_data->page_table_dev);
set_surf_dims(surface_data->doom_data, surface_data->width, surface_data->height);
- set_texture_pt(surface_data->doom_data, texture_data->page_table_dev);
- set_texture_dims(surface_data->doom_data, texture_data->size, texture_data->height);
+ set_draw_params(surface_data->doom_data, flags);
set_xy_a(surface_data->doom_data, column.x, column.y1);
set_xy_b(surface_data->doom_data, column.x, column.y2);
- set_ustart(surface_data->doom_data, column.ustart);
- set_ustep(surface_data->doom_data, column.ustep);
- set_draw_params(surface_data->doom_data, 0);
+
+ if (!(flags & HARDDOOM_DRAW_PARAMS_FUZZ)) {
+ set_texture_pt(surface_data->doom_data,
+ texture_data->page_table_dev);
+ set_texture_dims(surface_data->doom_data,
+ texture_data->size, texture_data->height);
+ set_ustart(surface_data->doom_data, column.ustart);
+ set_ustep(surface_data->doom_data, column.ustep);
+ }
+
+ if (flags & HARDDOOM_DRAW_PARAMS_FUZZ ||
+ flags & HARDDOOM_DRAW_PARAMS_COLORMAP) {
+ set_colormap(surface_data->doom_data, colors_data->colors_dev +
+ HARDDOOM_COLORMAP_SIZE * column.colormap_idx);
+ }
+
+ if (flags & HARDDOOM_DRAW_PARAMS_TRANSLATE) {
+ set_trans(surface_data->doom_data, trans_data->colors_dev +
+ HARDDOOM_COLORMAP_SIZE * trans_idx);
+ }
send_command(surface_data->doom_data,
HARDDOOM_CMD_DRAW_COLUMN(column.texture_offset));
@@ -284,6 +318,15 @@ void start_dev(struct pci_dev *dev)
doomdev_write(iomem, HARDDOOM_INTR_ENABLE, HARDDOOM_INTR_MASK);
doomdev_write(iomem, HARDDOOM_ENABLE,
HARDDOOM_ENABLE_ALL ^ HARDDOOM_ENABLE_FETCH_CMD);
+
+ set_surf_dst_pt(data, 0);
+ set_surf_src_pt(data, 0);
+ set_texture_pt(data, 0);
+ set_flat(data, 0);
+ set_colormap(data, 0);
+ set_surf_dims(data, 0, 0);
+ set_texture_dims(data, 0, 0);
+ set_draw_params(data, 0);
}
void shutdown_dev(struct pci_dev *dev)
diff --git a/harddoomdev.h b/harddoomdev.h
index 4ddd01e..90d2b51 100644
--- a/harddoomdev.h
+++ b/harddoomdev.h
@@ -20,7 +20,9 @@ void fill_rect(struct surface_data *surface_data, struct doomdev_fill_rect rect)
void copy_rect(struct surface_data *dst_data, struct surface_data *src_data,
struct doomdev_copy_rect rect);
void draw_column(struct surface_data *surface_data,
- struct texture_data *texture_data, struct doomdev_column column);
+ struct texture_data *texture_data, struct doomdev_column column,
+ struct colors_data *colors_data, struct colors_data *trans_data,
+ uint8_t flags, uint8_t trans_idx);
void draw_span(struct surface_data *surface_data, struct flat_data *flat_data,
struct doomdev_span span);
void draw_background(struct surface_data *surface_data,
diff --git a/private_data.h b/private_data.h
index e374f25..65eb948 100644
--- a/private_data.h
+++ b/private_data.h
@@ -65,4 +65,13 @@ struct flat_data {
dma_addr_t flat_dev;
};
+struct colors_data {
+ struct doom_data *doom_data;
+
+ uint32_t number;
+
+ uint8_t *colors_cpu;
+ dma_addr_t colors_dev;
+};
+
#endif
diff --git a/surface.c b/surface.c
index fddc0fe..cbb9406 100644
--- a/surface.c
+++ b/surface.c
@@ -93,17 +93,48 @@ long draw_columns(struct file *filp, unsigned long arg)
struct doomdev_surf_ioctl_draw_columns *param;
struct surface_data *surface_data;
struct texture_data *texture_data;
+ struct colors_data *colors_data;
+ struct colors_data *trans_data;
struct doomdev_column *columns;
struct fd texture_fds;
+ struct fd colors_fds;
+ struct fd trans_fds;
+ uint8_t flags;
+ bool got_colors = false;
+ bool got_trans = false;
int i;
surface_data = filp->private_data;
param = (struct doomdev_surf_ioctl_draw_columns *) arg;
- // temp
- if (param->draw_flags & DOOMDEV_DRAW_FLAGS_FUZZ) {
- return 0x400;
+ flags = param->draw_flags;
+
+ if (flags & DOOMDEV_DRAW_FLAGS_FUZZ ||
+ flags & DOOMDEV_DRAW_FLAGS_COLORMAP) {
+ if (flags & DOOMDEV_DRAW_FLAGS_FUZZ) {
+ flags = DOOMDEV_DRAW_FLAGS_FUZZ;
+ }
+
+ colors_fds = fdget(param->colormaps_fd);
+ colors_data = colors_fds.file->private_data;
+
+ got_colors = true;
+
+ if (surface_data->doom_data != colors_data->doom_data) {
+ return -EINVAL;
+ }
+ }
+
+ if (flags & DOOMDEV_DRAW_FLAGS_TRANSLATE) {
+ trans_fds = fdget(param->translations_fd);
+ trans_data = trans_fds.file->private_data;
+
+ got_trans = true;
+
+ if (surface_data->doom_data != trans_data->doom_data) {
+ return -EINVAL;
+ }
}
texture_fds = fdget(param->texture_fd);
@@ -118,13 +149,22 @@ long draw_columns(struct file *filp, unsigned long arg)
mutex_lock(&surface_data->doom_data->cmd_mutex);
for (i = 0; i < param->columns_num; i++) {
- draw_column(surface_data, texture_data, columns[i]);
+ draw_column(surface_data, texture_data, columns[i], colors_data,
+ trans_data, flags, param->translation_idx);
}
mutex_unlock(&surface_data->doom_data->cmd_mutex);
fdput(texture_fds);
+ if (got_colors) {
+ fdput(colors_fds);
+ }
+
+ if (got_trans) {
+ fdput(trans_fds);
+ }
+
return param->columns_num;
}