summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/psikyo4.cpp
blob: e74dcda308aaf4c28c407194ae0b44aeeaccd6ab (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// license:BSD-3-Clause
// copyright-holders:David Haywood, Paul Priest
/*

Psikyo PS6807 (PS4):
See src/drivers/psikyo4.c for more info

Each sprite has a flag denoting the screen to which it should be drawn.

*/

/*
Vid Regs:

0x3003fe4 -- ??xx???? vblank? 86??0000 always?
0x3003fe8 -- c0c0???? flipscreen for screen 1 and 2 resp.
             ????8080 Screen size select
0x3003fec -- a0000xxx always? is in two working games. 0x00000fff is bank select for gfx test
0x3003ff0 -- 000000ff brightness for screen 1, ffffff00 are probably separate rgb brightness (not used)
0x3003ff4 -- ffffff00 screen 1 clear colour
0x3003ff8 -- 000000ff brightness for screen 2, ffffff00 are probably separate rgb brightness (not used)
0x3003ffc -- ffffff00 screen 2 clear colour

HotDebut: 86010000 00009998 80000000 Small Screen
LodeRnDF: 86010000 00009998 a0000000 Small Screen

HotGmck:  86010000 1f201918 a0000000 Large Screen
HgKairak: 86010000 1f201918 a0000000 Large Screen
*/

#include "emu.h"
#include "includes/psikyo4.h"


/* --- SPRITES --- */
void psikyo4_state::draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect, uint32_t scr)
{
	/*- Sprite Format 0x0000 - 0x2bff -**

	0 hhhh --yy yyyy yyyy | wwww --xx xxxx xxxx  1  Ffpp pppp ---- -nnn | nnnn nnnn nnnn nnnn

	y = ypos
	x = xpos

	h = height
	w = width

	f = flip (x)
	F = flip (y) Unused?

	n = tile number

	p = palette

	**- End Sprite Format -*/

	gfx_element *gfx = m_gfxdecode->gfx(0);
	uint32_t *source = m_spriteram;
	uint16_t *list = (uint16_t *)m_spriteram.target() + 0x2c00/2 + 0x04/2; /* 0x2c00/0x2c02 what are these for, pointers? one for each screen */
	uint16_t listlen = (0xc00/2 - 0x04/2), listcntr = 0;
	bool flipscreen = BIT(m_vidregs[1], (scr == 0 ? 31 : 23));
	int screen_height = (scr == 0 ? m_lscreen : m_rscreen)->visible_area().max_y + 1;

	while (listcntr < listlen)
	{
		uint16_t listdat, sprnum;

		listdat = list[BYTE_XOR_BE(listcntr)];
		sprnum = (listdat & 0x03ff) * 2;

		/* start drawing */
		if ((listdat & 0x8000) == 0 && (listdat & 0x2000) == scr) /* draw only selected screen */
		{
			int loopnum = 0, i, j;
			uint32_t xpos, ypos, tnum, wide, high, colr, flipx, flipy;
			int xstart, ystart, xend, yend, xinc, yinc;

			ypos = (source[sprnum + 0] & 0x03ff0000) >> 16;
			xpos = (source[sprnum + 0] & 0x000003ff) >> 00;

			high = ((source[sprnum + 0] & 0xf0000000) >> (12 + 16)) + 1;
			wide = ((source[sprnum + 0] & 0x0000f000) >> 12) + 1;

			tnum = (source[sprnum + 1] & 0x0007ffff) >> 00;

			colr = (source[sprnum + 1] & 0x3f000000) >> 24;

			flipx = (source[sprnum + 1] & 0x40000000);
			flipy = (source[sprnum + 1] & 0x80000000); /* Guess */

			if (ypos & 0x200) ypos -= 0x400;
			if (xpos & 0x200) xpos -= 0x400;

			if (flipscreen)
			{
				/* Screen Height depends on game */
				ypos = screen_height - ypos - high * 16;
				xpos = 40 * 8 - xpos - wide * 16;
				flipx = !flipx;
				flipy = !flipy;
			}

			if (flipx)  { xstart = wide - 1;  xend = -1;    xinc = -1; }
			else        { xstart = 0;         xend = wide;  xinc = +1; }

			if (flipy)  { ystart = high - 1;  yend = -1;     yinc = -1; }
			else        { ystart = 0;         yend = high;   yinc = +1; }

			for (j = ystart; j != yend; j += yinc)
			{
				for (i = xstart; i != xend; i += xinc)
				{
						gfx->transpen(bitmap,cliprect, tnum + loopnum, colr, flipx, flipy, xpos + 16 * i, ypos + 16 * j, 0);
					loopnum++;
				}
			}
		}
		/* end drawing */
		listcntr++;
		if (listdat & 0x4000)
			break;
	}
}

uint32_t psikyo4_state::screen_update_psikyo4_left(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
	bitmap.fill(0x800, cliprect);
	m_gfxdecode->gfx(0)->set_palette(*m_palette);
	draw_sprites(bitmap, cliprect, 0x0000);
	return 0;
}

uint32_t psikyo4_state::screen_update_psikyo4_right(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
	bitmap.fill(0x800, cliprect);
	m_gfxdecode->gfx(0)->set_palette(*m_palette2);
	draw_sprites(bitmap, cliprect, 0x2000);
	return 0;
}

void psikyo4_state::video_start()
{
	m_gfxdecode->gfx(0)->set_granularity(32); /* 256 colour sprites with palette selectable on 32 colour boundaries */
}