~ubuntu-branches/debian/sid/mame/sid

« back to all changes in this revision

Viewing changes to mess/src/mame/video/policetr.c

  • Committer: Package Import Robot
  • Author(s): Jordi Mallach, Jordi Mallach, Emmanuel Kasper
  • Date: 2011-12-19 22:56:27 UTC
  • mfrom: (0.1.2)
  • Revision ID: package-import@ubuntu.com-20111219225627-ub5oga1oys4ogqzm
Tags: 0.144-1
[ Jordi Mallach ]
* Fix syntax errors in DEP5 copyright file (lintian).
* Use a versioned copyright Format specification field.
* Update Vcs-* URLs.
* Move transitional packages to the new metapackages section, and make
  them priority extra.
* Remove references to GNU/Linux and MESS sources from copyright.
* Add build variables for s390x.
* Use .xz tarballs as it cuts 4MB for the upstream sources.
* Add nplayers.ini as a patch. Update copyright file to add CC-BY-SA-3.0.

[ Emmanuel Kasper ]
* New upstream release. Closes: #651538.
* Add Free Desktop compliant png icons of various sizes taken from
  the hydroxygen iconset
* Mess is now built from a new source package, to avoid possible source
  incompatibilities between mame and the mess overlay.
* Mame-tools are not built from the mame source package anymore, but
  from the mess source package

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/***************************************************************************
2
 
 
3
 
    P&P Marketing Police Trainer hardware
4
 
 
5
 
***************************************************************************/
6
 
 
7
 
#include "emu.h"
8
 
#include "cpu/mips/r3000.h"
9
 
#include "includes/policetr.h"
10
 
 
11
 
 
12
 
/* constants */
13
 
#define SRCBITMAP_WIDTH         4096
14
 
 
15
 
#define DSTBITMAP_WIDTH         512
16
 
#define DSTBITMAP_HEIGHT        256
17
 
 
18
 
 
19
 
/*************************************
20
 
 *
21
 
 *  Video system start
22
 
 *
23
 
 *************************************/
24
 
 
25
 
VIDEO_START( policetr )
26
 
{
27
 
        policetr_state *state = machine.driver_data<policetr_state>();
28
 
        /* the source bitmap is in ROM */
29
 
        state->m_srcbitmap = machine.region("gfx1")->base();
30
 
 
31
 
        /* compute the height */
32
 
        state->m_srcbitmap_height_mask = (machine.region("gfx1")->bytes() / SRCBITMAP_WIDTH) - 1;
33
 
 
34
 
        /* the destination bitmap is not directly accessible to the CPU */
35
 
        state->m_dstbitmap = auto_alloc_array(machine, UINT8, DSTBITMAP_WIDTH * DSTBITMAP_HEIGHT);
36
 
}
37
 
 
38
 
 
39
 
 
40
 
/*************************************
41
 
 *
42
 
 *  Display list processor
43
 
 *
44
 
 *************************************/
45
 
 
46
 
static void render_display_list(running_machine &machine, offs_t offset)
47
 
{
48
 
        policetr_state *state = machine.driver_data<policetr_state>();
49
 
        /* mask against the R3000 address space */
50
 
        offset &= 0x1fffffff;
51
 
 
52
 
        /* loop over all items */
53
 
        while (offset != 0x1fffffff)
54
 
        {
55
 
                UINT32 *entry = &state->m_rambase[offset / 4];
56
 
                UINT32 srcx = entry[0] & 0xfffffff;
57
 
                UINT32 srcy = entry[1] & ((state->m_srcbitmap_height_mask << 16) | 0xffff);
58
 
                UINT32 srcxstep = entry[2];
59
 
                UINT32 srcystep = entry[3];
60
 
                int dstw = (entry[4] & 0x1ff) + 1;
61
 
                int dsth = ((entry[4] >> 12) & 0x1ff) + 1;
62
 
                int dstx = entry[5] & 0x1ff;
63
 
                int dsty = (entry[5] >> 12) & 0x1ff;
64
 
                UINT8 mask = ~entry[6] >> 16;
65
 
                UINT8 color = (entry[6] >> 24) & ~mask;
66
 
                UINT32 curx, cury;
67
 
                int x, y;
68
 
 
69
 
                if (dstx > state->m_render_clip.max_x)
70
 
                {
71
 
                        dstw -= (512 - dstx);
72
 
                        dstx = 0;
73
 
                }
74
 
                /* apply X clipping */
75
 
                if (dstx < state->m_render_clip.min_x)
76
 
                {
77
 
                        srcx += srcxstep * (state->m_render_clip.min_x - dstx);
78
 
                        dstw -= state->m_render_clip.min_x - dstx;
79
 
                        dstx = state->m_render_clip.min_x;
80
 
                }
81
 
                if (dstx + dstw > state->m_render_clip.max_x)
82
 
                        dstw = state->m_render_clip.max_x - dstx + 1;
83
 
 
84
 
                /* apply Y clipping */
85
 
                if (dsty < state->m_render_clip.min_y)
86
 
                {
87
 
                        srcy += srcystep * (state->m_render_clip.min_y - dsty);
88
 
                        dsth -= state->m_render_clip.min_y - dsty;
89
 
                        dsty = state->m_render_clip.min_y;
90
 
                }
91
 
                if (dsty + dsth > state->m_render_clip.max_y)
92
 
                        dsth = state->m_render_clip.max_y - dsty + 1;
93
 
 
94
 
                /* special case for fills */
95
 
                if (srcxstep == 0 && srcystep == 0)
96
 
                {
97
 
                        /* prefetch the pixel */
98
 
                        UINT8 pixel = state->m_srcbitmap[((srcy >> 16) * state->m_srcbitmap_height_mask) * SRCBITMAP_WIDTH + (srcx >> 16) % SRCBITMAP_WIDTH];
99
 
                        pixel = color | (pixel & mask);
100
 
 
101
 
                        /* loop over rows and columns */
102
 
                        if (dstw > 0)
103
 
                                for (y = 0; y < dsth; y++)
104
 
                                {
105
 
                                        UINT8 *dst = &state->m_dstbitmap[(dsty + y) * DSTBITMAP_WIDTH + dstx];
106
 
                                        memset(dst, pixel, dstw);
107
 
                                }
108
 
                }
109
 
 
110
 
                /* otherwise, standard render */
111
 
                else
112
 
                {
113
 
                        /* loop over rows */
114
 
                        for (y = 0, cury = srcy; y < dsth; y++, cury += srcystep)
115
 
                        {
116
 
                                UINT8 *src = &state->m_srcbitmap[((cury >> 16) & state->m_srcbitmap_height_mask) * SRCBITMAP_WIDTH];
117
 
                                UINT8 *dst = &state->m_dstbitmap[(dsty + y) * DSTBITMAP_WIDTH + dstx];
118
 
 
119
 
                                /* loop over columns */
120
 
                                for (x = 0, curx = srcx; x < dstw; x++, curx += srcxstep)
121
 
                                {
122
 
                                        UINT8 pixel = src[(curx >> 16) % SRCBITMAP_WIDTH];
123
 
                                        if (pixel)
124
 
                                                dst[x] = color | (pixel & mask);
125
 
                                }
126
 
                        }
127
 
                }
128
 
 
129
 
                /* advance to the next link */
130
 
                offset = entry[7] & 0x1fffffff;
131
 
        }
132
 
}
133
 
 
134
 
 
135
 
 
136
 
/*************************************
137
 
 *
138
 
 *  Video controller writes
139
 
 *
140
 
 *************************************/
141
 
 
142
 
WRITE32_HANDLER( policetr_video_w )
143
 
{
144
 
        policetr_state *state = space->machine().driver_data<policetr_state>();
145
 
        /* we assume 4-byte accesses */
146
 
        if (mem_mask)
147
 
                logerror("%08X: policetr_video_w access with mask %08X\n", cpu_get_previouspc(&space->device()), mem_mask);
148
 
 
149
 
        /* 4 offsets */
150
 
        switch (offset)
151
 
        {
152
 
                /* offset 0 specifies the start address of a display list */
153
 
                case 0:
154
 
                        render_display_list(space->machine(), data);
155
 
                        break;
156
 
 
157
 
                /* offset 1 specifies a latch value in the upper 8 bits */
158
 
                case 1:
159
 
                        state->m_video_latch = data >> 24;
160
 
                        break;
161
 
 
162
 
                /* offset 2 has various meanings based on the latch */
163
 
                case 2:
164
 
                {
165
 
                        switch (state->m_video_latch)
166
 
                        {
167
 
                                /* latch 0x04 specifies the source X offset for a source bitmap pixel read */
168
 
                                case 0x04:
169
 
                                        state->m_src_xoffs = data >> 16;
170
 
                                        break;
171
 
 
172
 
                                /* latch 0x14 specifies the source Y offset for a source bitmap pixel read */
173
 
                                case 0x14:
174
 
                                        state->m_src_yoffs = data >> 16;
175
 
                                        break;
176
 
 
177
 
                                /* latch 0x20 specifies the top/left corners of the render cliprect */
178
 
                                case 0x20:
179
 
                                        state->m_render_clip.min_y = (data >> 12) & 0xfff;
180
 
                                        state->m_render_clip.min_x = data & 0xfff;
181
 
                                        break;
182
 
 
183
 
                                /* latch 0x30 specifies the bottom/right corners of the render cliprect */
184
 
                                case 0x30:
185
 
                                        state->m_render_clip.max_y = (data >> 12) & 0xfff;
186
 
                                        state->m_render_clip.max_x = data & 0xfff;
187
 
                                        break;
188
 
 
189
 
                                /* latch 0x50 allows a direct write to the destination bitmap */
190
 
                                case 0x50:
191
 
                                        if (ACCESSING_BITS_24_31 && state->m_dst_xoffs < DSTBITMAP_WIDTH && state->m_dst_yoffs < DSTBITMAP_HEIGHT)
192
 
                                                state->m_dstbitmap[state->m_dst_yoffs * DSTBITMAP_WIDTH + state->m_dst_xoffs] = data >> 24;
193
 
                                        break;
194
 
 
195
 
                                /* log anything else */
196
 
                                default:
197
 
                                        logerror("%08X: policetr_video_w(2) = %08X & %08X with latch %02X\n", cpu_get_previouspc(&space->device()), data, mem_mask, state->m_video_latch);
198
 
                                        break;
199
 
                        }
200
 
                        break;
201
 
                }
202
 
 
203
 
                /* offset 3 has various meanings based on the latch */
204
 
                case 3:
205
 
                {
206
 
                        switch (state->m_video_latch)
207
 
                        {
208
 
                                /* latch 0x00 is unknown; 0, 1, and 2 get written into the upper 12 bits before rendering */
209
 
                                case 0x00:
210
 
                                        if (data != (0 << 20) && data != (1 << 20) && data != (2 << 20))
211
 
                                                logerror("%08X: policetr_video_w(3) = %08X & %08X with latch %02X\n", cpu_get_previouspc(&space->device()), data, mem_mask, state->m_video_latch);
212
 
                                        break;
213
 
 
214
 
                                /* latch 0x10 specifies destination bitmap X and Y offsets */
215
 
                                case 0x10:
216
 
                                        state->m_dst_yoffs = (data >> 12) & 0xfff;
217
 
                                        state->m_dst_xoffs = data & 0xfff;
218
 
                                        break;
219
 
 
220
 
                                /* latch 0x20 is unknown; either 0xef or 0x100 is written every IRQ4 */
221
 
                                case 0x20:
222
 
                                        if (data != (0x100 << 12) && data != (0xef << 12))
223
 
                                                logerror("%08X: policetr_video_w(3) = %08X & %08X with latch %02X\n", cpu_get_previouspc(&space->device()), data, mem_mask, state->m_video_latch);
224
 
                                        break;
225
 
 
226
 
                                /* latch 0x40 is unknown; a 0 is written every IRQ4 */
227
 
                                case 0x40:
228
 
                                        if (data != 0)
229
 
                                                logerror("%08X: policetr_video_w(3) = %08X & %08X with latch %02X\n", cpu_get_previouspc(&space->device()), data, mem_mask, state->m_video_latch);
230
 
                                        break;
231
 
 
232
 
                                /* latch 0x50 clears IRQ4 */
233
 
                                case 0x50:
234
 
                                        cputag_set_input_line(space->machine(), "maincpu", R3000_IRQ4, CLEAR_LINE);
235
 
                                        break;
236
 
 
237
 
                                /* latch 0x60 clears IRQ5 */
238
 
                                case 0x60:
239
 
                                        cputag_set_input_line(space->machine(), "maincpu", R3000_IRQ5, CLEAR_LINE);
240
 
                                        break;
241
 
 
242
 
                                /* log anything else */
243
 
                                default:
244
 
                                        logerror("%08X: policetr_video_w(3) = %08X & %08X with latch %02X\n", cpu_get_previouspc(&space->device()), data, mem_mask, state->m_video_latch);
245
 
                                        break;
246
 
                        }
247
 
                        break;
248
 
                }
249
 
        }
250
 
}
251
 
 
252
 
 
253
 
 
254
 
/*************************************
255
 
 *
256
 
 *  Video controller reads
257
 
 *
258
 
 *************************************/
259
 
 
260
 
READ32_HANDLER( policetr_video_r )
261
 
{
262
 
        policetr_state *state = space->machine().driver_data<policetr_state>();
263
 
        int inputval;
264
 
        int width = space->machine().primary_screen->width();
265
 
        int height = space->machine().primary_screen->height();
266
 
 
267
 
        /* the value read is based on the latch */
268
 
        switch (state->m_video_latch)
269
 
        {
270
 
                /* latch 0x00 is player 1's gun X coordinate */
271
 
                case 0x00:
272
 
                        inputval = ((input_port_read(space->machine(), "GUNX1") & 0xff) * width) >> 8;
273
 
                        inputval += 0x50;
274
 
                        return (inputval << 20) | 0x20000000;
275
 
 
276
 
                /* latch 0x01 is player 1's gun Y coordinate */
277
 
                case 0x01:
278
 
                        inputval = ((input_port_read(space->machine(), "GUNY1") & 0xff) * height) >> 8;
279
 
                        inputval += 0x17;
280
 
                        return (inputval << 20);
281
 
 
282
 
                /* latch 0x02 is player 2's gun X coordinate */
283
 
                case 0x02:
284
 
                        inputval = ((input_port_read(space->machine(), "GUNX2") & 0xff) * width) >> 8;
285
 
                        inputval += 0x50;
286
 
                        return (inputval << 20) | 0x20000000;
287
 
 
288
 
                /* latch 0x03 is player 2's gun Y coordinate */
289
 
                case 0x03:
290
 
                        inputval = ((input_port_read(space->machine(), "GUNY2") & 0xff) * height) >> 8;
291
 
                        inputval += 0x17;
292
 
                        return (inputval << 20);
293
 
 
294
 
                /* latch 0x04 is the pixel value in the ROM at the specified address */
295
 
                case 0x04:
296
 
                        return state->m_srcbitmap[(state->m_src_yoffs & state->m_srcbitmap_height_mask) * SRCBITMAP_WIDTH + state->m_src_xoffs % SRCBITMAP_WIDTH] << 24;
297
 
 
298
 
                /* latch 0x50 is read at IRQ 4; the top 2 bits are checked. If they're not 0,
299
 
            they skip the rest of the interrupt processing */
300
 
                case 0x50:
301
 
                        return 0;
302
 
        }
303
 
 
304
 
        /* log anything else */
305
 
        logerror("%08X: policetr_video_r with latch %02X\n", cpu_get_previouspc(&space->device()), state->m_video_latch);
306
 
        return 0;
307
 
}
308
 
 
309
 
 
310
 
 
311
 
 
312
 
/*************************************
313
 
 *
314
 
 *  Palette access
315
 
 *
316
 
 *************************************/
317
 
 
318
 
WRITE32_HANDLER( policetr_palette_offset_w )
319
 
{
320
 
        policetr_state *state = space->machine().driver_data<policetr_state>();
321
 
        if (ACCESSING_BITS_16_23)
322
 
        {
323
 
                state->m_palette_offset = (data >> 16) & 0xff;
324
 
                state->m_palette_index = 0;
325
 
        }
326
 
}
327
 
 
328
 
 
329
 
WRITE32_HANDLER( policetr_palette_data_w )
330
 
{
331
 
        policetr_state *state = space->machine().driver_data<policetr_state>();
332
 
        if (ACCESSING_BITS_16_23)
333
 
        {
334
 
                state->m_palette_data[state->m_palette_index] = (data >> 16) & 0xff;
335
 
                if (++state->m_palette_index == 3)
336
 
                {
337
 
                        palette_set_color(space->machine(), state->m_palette_offset, MAKE_RGB(state->m_palette_data[0], state->m_palette_data[1], state->m_palette_data[2]));
338
 
                        state->m_palette_index = 0;
339
 
                }
340
 
        }
341
 
}
342
 
 
343
 
 
344
 
 
345
 
/*************************************
346
 
 *
347
 
 *  Main refresh
348
 
 *
349
 
 *************************************/
350
 
 
351
 
SCREEN_UPDATE( policetr )
352
 
{
353
 
        policetr_state *state = screen->machine().driver_data<policetr_state>();
354
 
        int width = cliprect->max_x - cliprect->min_x + 1;
355
 
        int y;
356
 
 
357
 
        /* render all the scanlines from the dstbitmap to MAME's bitmap */
358
 
        for (y = cliprect->min_y; y <= cliprect->max_y; y++)
359
 
                draw_scanline8(bitmap, cliprect->min_x, y, width, &state->m_dstbitmap[DSTBITMAP_WIDTH * y + cliprect->min_x], NULL);
360
 
 
361
 
        return 0;
362
 
}