mirror of
https://github.com/holub/mame
synced 2025-07-06 02:18:09 +03:00
olympia/portrait.cpp: apply some WIP cleanups, make it playable (#10540)
- Make color palette to be b&w for the time being, being more visible to the eye than the previous washed out attempt; - mask sprite area against defined playfield clip rectangle; - fix global sprite Y positions, they mostly follow up current scroll value except for some edge cases; - attempt to fix sprite priorities; - make tilemap bank more logical (?) bitwise;
This commit is contained in:
parent
0cf7e30b41
commit
343e12235c
@ -1,5 +1,5 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Steve Ellenoff, Pierpaolo Prazzoli
|
||||
// copyright-holders:Steve Ellenoff, Pierpaolo Prazzoli, Angelo Salese
|
||||
/**************************************************************************
|
||||
Portraits
|
||||
(c) 1983 Olympia
|
||||
@ -23,16 +23,21 @@ Pierpaolo Prazzoli, xx-07-2004
|
||||
ON ON -> camera test
|
||||
|
||||
TODO:
|
||||
- desperately needs a PCB analysis, particularly for color PROM formation;
|
||||
- add sound;
|
||||
- add colors (maybe not RGB555);
|
||||
- fix sprites positions (zooming?);
|
||||
- fix colors;
|
||||
- several unknown sprite bits;
|
||||
- video priority bits;
|
||||
- offset background scrolling positions (i.e. monkey climbing on trees);
|
||||
- camera device (type?);
|
||||
- misc unknown input/outputs;
|
||||
|
||||
|
||||
RAM Location 9240: Controls what level you are on: 0-3 (for each scene)
|
||||
RAM location $9240: Controls what level you are on: 0-3 (for each scene).
|
||||
Can override in attract mode as well, with:
|
||||
bp 313a,1,{A=2;g}
|
||||
bp 313a,1,{A=3;g}
|
||||
TODO: find a cheat that disables player collision detection
|
||||
(game is not pleasant on that regard)
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
@ -94,7 +99,6 @@ DM81LS95 = TriState buffer
|
||||
#include "portrait.h"
|
||||
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "cpu/mcs48/mcs48.h"
|
||||
#include "machine/gen_latch.h"
|
||||
#include "machine/nvram.h"
|
||||
#include "screen.h"
|
||||
@ -104,6 +108,8 @@ DM81LS95 = TriState buffer
|
||||
void portrait_state::ctrl_w(uint8_t data)
|
||||
{
|
||||
/* bits 4 and 5 are unknown */
|
||||
// TODO: condition for just displaying stored camera image
|
||||
// 0xf8 when capturing for the hi-score new pic, 0xb0 when displaying it from attract mode.
|
||||
|
||||
machine().bookkeeping().coin_counter_w(0, data & 0x01);
|
||||
machine().bookkeeping().coin_counter_w(1, data & 0x02);
|
||||
@ -117,6 +123,8 @@ void portrait_state::ctrl_w(uint8_t data)
|
||||
output().set_value("photo", (data >> 7) & 1);
|
||||
}
|
||||
|
||||
// $9235-$9236 raw scroll values up to 512
|
||||
// $9236 bit 0 defines which of these are used
|
||||
void portrait_state::positive_scroll_w(uint8_t data)
|
||||
{
|
||||
m_scroll = data;
|
||||
@ -124,7 +132,7 @@ void portrait_state::positive_scroll_w(uint8_t data)
|
||||
|
||||
void portrait_state::negative_scroll_w(uint8_t data)
|
||||
{
|
||||
m_scroll = - (data ^ 0xff);
|
||||
m_scroll = 511 - (data ^ 0xff);
|
||||
}
|
||||
|
||||
void portrait_state::portrait_map(address_map &map)
|
||||
@ -135,15 +143,16 @@ void portrait_state::portrait_map(address_map &map)
|
||||
map(0x9000, 0x91ff).ram().share("spriteram");
|
||||
map(0x9200, 0x97ff).ram();
|
||||
map(0xa000, 0xa000).w("soundlatch", FUNC(generic_latch_8_device::write));
|
||||
map(0xa010, 0xa010).nopw(); // ?
|
||||
map(0xa010, 0xa010).nopw(); // more sound? Follows up whatever is happening on screen
|
||||
map(0xa000, 0xa000).portr("DSW1");
|
||||
map(0xa004, 0xa004).portr("DSW2");
|
||||
map(0xa008, 0xa008).portr("SYSTEM").w(FUNC(portrait_state::ctrl_w));
|
||||
map(0xa010, 0xa010).portr("INPUTS");
|
||||
// $a018 reads go to $920f, never really read up?
|
||||
map(0xa018, 0xa018).nopr().w(FUNC(portrait_state::positive_scroll_w));
|
||||
map(0xa019, 0xa019).w(FUNC(portrait_state::negative_scroll_w));
|
||||
map(0xa800, 0xa83f).ram().share("nvram");
|
||||
map(0xffff, 0xffff).nopr();
|
||||
map(0xffff, 0xffff).nopr(); // on POST only, value discarded, likely just a bug
|
||||
}
|
||||
|
||||
|
||||
@ -205,7 +214,7 @@ static INPUT_PORTS_START( portrait )
|
||||
PORT_DIPNAME( 0x40, 0x00, "Ostrich Speed" )
|
||||
PORT_DIPSETTING( 0x00, "Slow" )
|
||||
PORT_DIPSETTING( 0x40, "Quick" )
|
||||
PORT_DIPNAME( 0x80, 0x80, "Obstacles" )
|
||||
PORT_DIPNAME( 0x80, 0x00, "Obstacles" )
|
||||
PORT_DIPSETTING( 0x80, DEF_STR( No ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( Yes ) )
|
||||
|
||||
@ -239,7 +248,7 @@ static const gfx_layout tile_layout =
|
||||
16,16, /* tile width, height */
|
||||
1024, /* number of characters */
|
||||
3, /* bits per pixel */
|
||||
{ 0x8000*8, 0x4000*8, 0x0000*8 }, /* bitplane offsets */
|
||||
{ 0x0000*8, 0x4000*8, 0x8000*8 }, /* bitplane offsets */
|
||||
{
|
||||
RGN_FRAC(1,2)+7, RGN_FRAC(1,2)+6, RGN_FRAC(1,2)+5, RGN_FRAC(1,2)+4,
|
||||
RGN_FRAC(1,2)+3, RGN_FRAC(1,2)+2, RGN_FRAC(1,2)+1, RGN_FRAC(1,2)+0,
|
||||
@ -260,8 +269,10 @@ void portrait_state::portrait(machine_config &config)
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &portrait_state::portrait_map);
|
||||
m_maincpu->set_vblank_int("screen", FUNC(portrait_state::irq0_line_hold));
|
||||
|
||||
i8039_device &audiocpu(I8039(config, "audiocpu", 3120000)); /* ? */
|
||||
audiocpu.set_addrmap(AS_PROGRAM, &portrait_state::portrait_sound_map);
|
||||
I8039(config, m_audiocpu, 3120000); /* ? */
|
||||
m_audiocpu->set_addrmap(AS_PROGRAM, &portrait_state::portrait_sound_map);
|
||||
|
||||
// TODO: PIT8253
|
||||
|
||||
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
|
||||
|
||||
@ -297,23 +308,23 @@ ROM_START( portrait )
|
||||
ROM_LOAD( "port_ma.bin", 0x0800, 0x0800, CRC(ee242e4f) SHA1(fb67e0d136927e04f4fa819f684c97b0d52ee48c) )
|
||||
|
||||
ROM_REGION( 0x20000, "gfx1", 0 )
|
||||
ROM_LOAD( "port_00.a1", 0x00000, 0x2000, CRC(eb3e1c12) SHA1(2d38b66f52546b40553244c8a5c961279559f5b6) ) /*bit plane 1*/
|
||||
ROM_LOAD( "port_10.b1", 0x02000, 0x2000, CRC(0f44e377) SHA1(1955f9f4deab2166f637f43c1f326bd65fc90f6a) ) /*bit plane 1*/
|
||||
ROM_LOAD( "port_00.a1", 0x00000, 0x2000, CRC(eb3e1c12) SHA1(2d38b66f52546b40553244c8a5c961279559f5b6) )
|
||||
ROM_LOAD( "port_10.b1", 0x02000, 0x2000, CRC(0f44e377) SHA1(1955f9f4deab2166f637f43c1f326bd65fc90f6a) )
|
||||
|
||||
ROM_LOAD( "port_02.d1", 0x04000, 0x2000, CRC(bd93a3f9) SHA1(9cb479b8840cafd6043ff0cb9d5ca031dcd332ba) ) /*bit plane 2*/
|
||||
ROM_LOAD( "port_12.e1", 0x06000, 0x2000, CRC(656b9f20) SHA1(c1907aba3d19be79d92cd73784b8e7ae94910da6) ) /*bit plane 2*/
|
||||
ROM_LOAD( "port_02.d1", 0x04000, 0x2000, CRC(bd93a3f9) SHA1(9cb479b8840cafd6043ff0cb9d5ca031dcd332ba) )
|
||||
ROM_LOAD( "port_12.e1", 0x06000, 0x2000, CRC(656b9f20) SHA1(c1907aba3d19be79d92cd73784b8e7ae94910da6) )
|
||||
|
||||
ROM_LOAD( "port_04.g1", 0x08000, 0x2000, CRC(2a99feb5) SHA1(b373d2a2bd28aad6dd7a15a2166e03a8b7a34d9b) ) /*bit plane 3*/
|
||||
ROM_LOAD( "port_14.g1", 0x0a000, 0x2000, CRC(224b7a58) SHA1(b84e70d22d1cab41e5773fc9daa2e4e55ec9d96e) ) /*bit plane 3*/
|
||||
ROM_LOAD( "port_04.g1", 0x08000, 0x2000, CRC(2a99feb5) SHA1(b373d2a2bd28aad6dd7a15a2166e03a8b7a34d9b) )
|
||||
ROM_LOAD( "port_14.g1", 0x0a000, 0x2000, CRC(224b7a58) SHA1(b84e70d22d1cab41e5773fc9daa2e4e55ec9d96e) )
|
||||
|
||||
ROM_LOAD( "port_01.a2", 0x10000, 0x2000, CRC(70d27508) SHA1(d011f85b31bb3aa6f386e8e0edb91df10f4c4eb6) ) /*bit plane 1*/
|
||||
ROM_LOAD( "port_11.b2", 0x12000, 0x2000, CRC(f498e395) SHA1(beb1d12433a350e5b773126de3f2803a9f5620c1) ) /*bit plane 1*/
|
||||
ROM_LOAD( "port_01.a2", 0x10000, 0x2000, CRC(70d27508) SHA1(d011f85b31bb3aa6f386e8e0edb91df10f4c4eb6) )
|
||||
ROM_LOAD( "port_11.b2", 0x12000, 0x2000, CRC(f498e395) SHA1(beb1d12433a350e5b773126de3f2803a9f5620c1) )
|
||||
|
||||
ROM_LOAD( "port_03.d2", 0x14000, 0x2000, CRC(03d4153a) SHA1(7ce69ce6a101870dbfca1a9787fb1e660024bc02) ) /*bit plane 2*/
|
||||
ROM_LOAD( "port_13.e2", 0x16000, 0x2000, CRC(10fa22b8) SHA1(e8f4c24fcdda0ce5e33bc600acd574a232a9bb21) ) /*bit plane 2*/
|
||||
ROM_LOAD( "port_03.d2", 0x14000, 0x2000, CRC(03d4153a) SHA1(7ce69ce6a101870dbfca1a9787fb1e660024bc02) )
|
||||
ROM_LOAD( "port_13.e2", 0x16000, 0x2000, CRC(10fa22b8) SHA1(e8f4c24fcdda0ce5e33bc600acd574a232a9bb21) )
|
||||
|
||||
ROM_LOAD( "port_05.g2", 0x18000, 0x2000, CRC(43ea7951) SHA1(df0ae7fa802365979514063e1d67cdd45ecada90) ) /*bit plane 3*/
|
||||
ROM_LOAD( "port_15.h2", 0x1a000, 0x2000, CRC(ab20b438) SHA1(ea5d60f6a9f06397bd0c6ee028b463c684090c01) ) /*bit plane 3*/
|
||||
ROM_LOAD( "port_05.g2", 0x18000, 0x2000, CRC(43ea7951) SHA1(df0ae7fa802365979514063e1d67cdd45ecada90) )
|
||||
ROM_LOAD( "port_15.h2", 0x1a000, 0x2000, CRC(ab20b438) SHA1(ea5d60f6a9f06397bd0c6ee028b463c684090c01) )
|
||||
|
||||
ROM_REGION( 0x0800, "user1", 0 ) // sound related?
|
||||
ROM_LOAD( "port_sa.bin", 0x0000, 0x0800, CRC(50510897) SHA1(8af0f42699602a5b33500968c958e3784e03377f) )
|
||||
@ -338,19 +349,19 @@ ROM_START( portraita )
|
||||
ROM_LOAD( "port_ma.bin", 0x0800, 0x0800, CRC(ee242e4f) SHA1(fb67e0d136927e04f4fa819f684c97b0d52ee48c) )
|
||||
|
||||
ROM_REGION( 0x20000, "gfx1", 0 )
|
||||
ROM_LOAD( "port_00.a1", 0x00000, 0x2000, CRC(eb3e1c12) SHA1(2d38b66f52546b40553244c8a5c961279559f5b6) ) /*bit plane 1*/
|
||||
ROM_LOAD( "port_10.b1", 0x02000, 0x2000, CRC(0f44e377) SHA1(1955f9f4deab2166f637f43c1f326bd65fc90f6a) ) /*bit plane 1*/
|
||||
ROM_LOAD( "port_02.d1", 0x04000, 0x2000, CRC(bd93a3f9) SHA1(9cb479b8840cafd6043ff0cb9d5ca031dcd332ba) ) /*bit plane 2*/
|
||||
ROM_LOAD( "port_12.e1", 0x06000, 0x2000, CRC(656b9f20) SHA1(c1907aba3d19be79d92cd73784b8e7ae94910da6) ) /*bit plane 2*/
|
||||
ROM_LOAD( "port_04.g1", 0x08000, 0x2000, CRC(2a99feb5) SHA1(b373d2a2bd28aad6dd7a15a2166e03a8b7a34d9b) ) /*bit plane 3*/
|
||||
ROM_LOAD( "port_14.g1", 0x0a000, 0x2000, CRC(224b7a58) SHA1(b84e70d22d1cab41e5773fc9daa2e4e55ec9d96e) ) /*bit plane 3*/
|
||||
ROM_LOAD( "port_00.a1", 0x00000, 0x2000, CRC(eb3e1c12) SHA1(2d38b66f52546b40553244c8a5c961279559f5b6) )
|
||||
ROM_LOAD( "port_10.b1", 0x02000, 0x2000, CRC(0f44e377) SHA1(1955f9f4deab2166f637f43c1f326bd65fc90f6a) )
|
||||
ROM_LOAD( "port_02.d1", 0x04000, 0x2000, CRC(bd93a3f9) SHA1(9cb479b8840cafd6043ff0cb9d5ca031dcd332ba) )
|
||||
ROM_LOAD( "port_12.e1", 0x06000, 0x2000, CRC(656b9f20) SHA1(c1907aba3d19be79d92cd73784b8e7ae94910da6) )
|
||||
ROM_LOAD( "port_04.g1", 0x08000, 0x2000, CRC(2a99feb5) SHA1(b373d2a2bd28aad6dd7a15a2166e03a8b7a34d9b) )
|
||||
ROM_LOAD( "port_14.g1", 0x0a000, 0x2000, CRC(224b7a58) SHA1(b84e70d22d1cab41e5773fc9daa2e4e55ec9d96e) )
|
||||
|
||||
ROM_LOAD( "port_01.a2", 0x10000, 0x2000, CRC(70d27508) SHA1(d011f85b31bb3aa6f386e8e0edb91df10f4c4eb6) ) /*bit plane 1*/
|
||||
ROM_LOAD( "port_11.b2", 0x12000, 0x2000, CRC(f498e395) SHA1(beb1d12433a350e5b773126de3f2803a9f5620c1) ) /*bit plane 1*/
|
||||
ROM_LOAD( "port_03.d2", 0x14000, 0x2000, CRC(03d4153a) SHA1(7ce69ce6a101870dbfca1a9787fb1e660024bc02) ) /*bit plane 2*/
|
||||
ROM_LOAD( "port_13.e2", 0x16000, 0x2000, CRC(10fa22b8) SHA1(e8f4c24fcdda0ce5e33bc600acd574a232a9bb21) ) /*bit plane 2*/
|
||||
ROM_LOAD( "port_05.g2", 0x18000, 0x2000, CRC(43ea7951) SHA1(df0ae7fa802365979514063e1d67cdd45ecada90) ) /*bit plane 3*/
|
||||
ROM_LOAD( "port_15.h2", 0x1a000, 0x2000, CRC(ab20b438) SHA1(ea5d60f6a9f06397bd0c6ee028b463c684090c01) ) /*bit plane 3*/
|
||||
ROM_LOAD( "port_01.a2", 0x10000, 0x2000, CRC(70d27508) SHA1(d011f85b31bb3aa6f386e8e0edb91df10f4c4eb6) )
|
||||
ROM_LOAD( "port_11.b2", 0x12000, 0x2000, CRC(f498e395) SHA1(beb1d12433a350e5b773126de3f2803a9f5620c1) )
|
||||
ROM_LOAD( "port_03.d2", 0x14000, 0x2000, CRC(03d4153a) SHA1(7ce69ce6a101870dbfca1a9787fb1e660024bc02) )
|
||||
ROM_LOAD( "port_13.e2", 0x16000, 0x2000, CRC(10fa22b8) SHA1(e8f4c24fcdda0ce5e33bc600acd574a232a9bb21) )
|
||||
ROM_LOAD( "port_05.g2", 0x18000, 0x2000, CRC(43ea7951) SHA1(df0ae7fa802365979514063e1d67cdd45ecada90) )
|
||||
ROM_LOAD( "port_15.h2", 0x1a000, 0x2000, CRC(ab20b438) SHA1(ea5d60f6a9f06397bd0c6ee028b463c684090c01) )
|
||||
|
||||
ROM_REGION( 0x800, "tileattr", 0 ) // tile attributes (see notes)
|
||||
ROM_LOAD( "93z511.bin", 0x0000, 0x0800, CRC(d66d9036) SHA1(7a25efbd8f2f94a01aad9e2be9cb18da7b9ec1d1) )
|
||||
@ -360,39 +371,6 @@ ROM_START( portraita )
|
||||
ROM_LOAD( "port_pr2.n4", 0x20, 0x0020, CRC(008634f3) SHA1(7cde6b09ede672d562569866d944428198f2ba9c) )
|
||||
ROM_END
|
||||
|
||||
/* tileattr rom
|
||||
|
||||
this appears to be divided into 2 0x400 banks
|
||||
|
||||
0x000 - 0x3ff relates to tiles 0x000-0x0ff
|
||||
|
||||
0x400 - 0x7ff relates to tiles 0x100-0x1ff, 0x200-0x2ff, and 0x300-0x3ff
|
||||
|
||||
every 2 tiles are somehow related to 8 bytes in the data
|
||||
|
||||
so tiles 0x00 and 0x01 use bytes 0x000-0x007
|
||||
0x02 0x008
|
||||
0x04 0x010
|
||||
0x06 0x018
|
||||
0x08 0x020
|
||||
0x0a 0x028
|
||||
0x0c 0x030
|
||||
0x0e 0x038
|
||||
0x10 0x040
|
||||
.......
|
||||
0xfe and 0xff use bytes 0x3f8-0x3ff
|
||||
etc.
|
||||
|
||||
it's probably some kind of lookup table for the colours (6bpp = 8 colours, maybe every 2 tiles share the same 8 colours)
|
||||
I guess either the bank (0/1) can be selected, or bank 0 is hardcoded to tiles 0x000-0x0ff (because tilemaps can use
|
||||
these tiles too, so it's not a case of it being a sprite/tilemap lookup split)
|
||||
|
||||
anyway.. this is why the portraits logo is broken across 3 areas (0x1f2, 0x2f2, 0x3f2) so that they can share the same
|
||||
attributes from this rom
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
GAME( 1983, portrait, 0, portrait, portrait, portrait_state, empty_init, ROT270, "Olympia", "Portraits (set 1)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_WRONG_COLORS | MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1983, portraita,portrait, portrait, portrait, portrait_state, empty_init, ROT270, "Olympia", "Portraits (set 2)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_WRONG_COLORS | MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1983, portraita,portrait, portrait, portrait, portrait_state, empty_init, ROT270, "Olympia", "Portraits (set 2)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_WRONG_COLORS | MACHINE_SUPPORTS_SAVE ) // harder set
|
||||
|
@ -1,10 +1,11 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Steve Ellenoff, Pierpaolo Prazzoli
|
||||
// copyright-holders:Steve Ellenoff, Pierpaolo Prazzoli, Angelo Salese
|
||||
#ifndef MAME_INCLUDES_PORTRAIT_H
|
||||
#define MAME_INCLUDES_PORTRAIT_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cpu/mcs48/mcs48.h"
|
||||
#include "sound/tms5220.h"
|
||||
#include "emupal.h"
|
||||
#include "tilemap.h"
|
||||
@ -15,6 +16,7 @@ public:
|
||||
portrait_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_audiocpu(*this, "audiocpu")
|
||||
, m_gfxdecode(*this, "gfxdecode")
|
||||
, m_palette(*this, "palette")
|
||||
, m_tms(*this, "tms")
|
||||
@ -46,11 +48,12 @@ private:
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
inline void get_tile_info( tile_data &tileinfo, int tile_index, const uint8_t *source );
|
||||
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, u8 priority);
|
||||
void portrait_map(address_map &map);
|
||||
void portrait_sound_map(address_map &map);
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<i8039_device> m_audiocpu;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<palette_device> m_palette;
|
||||
required_device<tms5200_device> m_tms;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Steve Ellenoff, Pierpaolo Prazzoli
|
||||
// copyright-holders:Steve Ellenoff, Pierpaolo Prazzoli, Angelo Salese
|
||||
/***************************************************************************
|
||||
|
||||
Portraits
|
||||
@ -23,6 +23,10 @@ void portrait_state::fgvideo_write(offs_t offset, uint8_t data)
|
||||
m_fgvideoram[offset] = data;
|
||||
}
|
||||
|
||||
// NB: undisplayed areas gets filled at POST but never really used
|
||||
// $8x36-$8x3f / $8x76-$8x7f / $8xb6-$8xbf / $8xf6-$8xff
|
||||
// given that tilemap doesn't really cope well with live editing your best bet in debugging this is
|
||||
// potentially to subscribe these unused areas to a mark_all_dirty() fn.
|
||||
inline void portrait_state::get_tile_info( tile_data &tileinfo, int tile_index, const uint8_t *source )
|
||||
{
|
||||
int attr = source[tile_index*2+0];
|
||||
@ -30,26 +34,25 @@ inline void portrait_state::get_tile_info( tile_data &tileinfo, int tile_index,
|
||||
int flags = 0;
|
||||
int color = 0;
|
||||
|
||||
/* or 0x10 ? */
|
||||
// TODO: always set with bit 4
|
||||
if( attr & 0x20 ) flags = TILE_FLIPY;
|
||||
|
||||
switch( attr & 7 )
|
||||
{
|
||||
case 1:
|
||||
tilenum += 0x200;
|
||||
break;
|
||||
case 3:
|
||||
tilenum += 0x300;
|
||||
break;
|
||||
case 5:
|
||||
tilenum += 0x100;
|
||||
break;
|
||||
}
|
||||
if (attr & 1)
|
||||
tilenum += 0x200;
|
||||
if (attr & 2)
|
||||
tilenum += 0x100;
|
||||
if (attr & 4)
|
||||
tilenum ^= 0x300;
|
||||
|
||||
// TODO: is the wild arrangement above related to how color upper banks should work?
|
||||
// cfr. trees in stage 4 leaving holes against the other layer
|
||||
|
||||
// TODO: kludgy
|
||||
// at worst this is modified at mixing time, outputting sprite color for the status bar.
|
||||
if (tilenum<0x100)
|
||||
color = ((tilenum&0xff)>>1)+0x00;
|
||||
color = ((tilenum&0xfe) >> 1) + 0x00;
|
||||
else
|
||||
color = ((tilenum&0xff)>>1)+0x80;
|
||||
color = ((tilenum&0xfe) >> 1) + 0x80;
|
||||
|
||||
tileinfo.set(0, tilenum, color, flags );
|
||||
}
|
||||
@ -74,37 +77,68 @@ void portrait_state::video_start()
|
||||
save_item(NAME(m_scroll));
|
||||
}
|
||||
|
||||
/* tileattr rom
|
||||
|
||||
this appears to be divided into 2 0x400 banks
|
||||
|
||||
0x000 - 0x3ff relates to tiles 0x000-0x0ff
|
||||
|
||||
0x400 - 0x7ff relates to tiles 0x100-0x1ff, 0x200-0x2ff, and 0x300-0x3ff
|
||||
|
||||
every 2 tiles are somehow related to 8 bytes in the data
|
||||
|
||||
so tiles 0x00 and 0x01 use bytes 0x000-0x007
|
||||
0x02 0x008
|
||||
0x04 0x010
|
||||
0x06 0x018
|
||||
0x08 0x020
|
||||
0x0a 0x028
|
||||
0x0c 0x030
|
||||
0x0e 0x038
|
||||
0x10 0x040
|
||||
.......
|
||||
0xfe and 0xff use bytes 0x3f8-0x3ff
|
||||
etc.
|
||||
|
||||
it's probably some kind of lookup table for the colours (6bpp = 8 colours, maybe every 2 tiles share the same 8 colours)
|
||||
I guess either the bank (0/1) can be selected, or bank 0 is hardcoded to tiles 0x000-0x0ff (because tilemaps can use
|
||||
these tiles too, so it's not a case of it being a sprite/tilemap lookup split)
|
||||
|
||||
anyway.. this is why the portraits logo is broken across 3 areas (0x1f2, 0x2f2, 0x3f2) so that they can share the same
|
||||
attributes from this rom
|
||||
|
||||
*/
|
||||
void portrait_state::portrait_palette(palette_device &palette) const
|
||||
{
|
||||
uint8_t const *const color_prom = memregion("proms")->base();
|
||||
|
||||
/*
|
||||
for (int i = 0; i < 0x40; i++)
|
||||
{
|
||||
int const data = color_prom[i];
|
||||
|
||||
int const r = (data >> 0) & 0x7;
|
||||
int const g = (data >> 3) & 0x3;
|
||||
int const b = (data >> 5) & 0x7;
|
||||
|
||||
palette.set_indirect_color(i, rgb_t(pal3bit(r), pal2bit(g), pal3bit(b)));
|
||||
}
|
||||
*/
|
||||
|
||||
for (int i = 0; i < 0x20; i++)
|
||||
{
|
||||
int const data = (color_prom[i + 0] << 0) | (color_prom[i + 0x20] << 8);
|
||||
|
||||
int const r = (data >> 0) & 0x1f;
|
||||
int const g = (data >> 5) & 0x1f;
|
||||
int const b = (data >> 10) & 0x1f;
|
||||
// TODO: experimental workbench, not using pal*bit intentionally.
|
||||
// 13 valid bits:
|
||||
// [+0x00] bit 0-3, bit 6-4
|
||||
// [+0x20] bit 0-2, bit 7-5
|
||||
// Only bit 0-3 seems to have a valid color ramp, is the rest actually bit mixed?
|
||||
|
||||
palette.set_indirect_color(i, rgb_t(pal5bit(r), pal5bit(g), pal5bit(b)));
|
||||
int ii = (data >> 0) & 0x0f;
|
||||
//int b = ((data >> 4) & 0x7) * ii;
|
||||
//int r = ((data >> 8) & 0x7) * ii;
|
||||
//int g = ((data >> 13) & 0x7) * ii;
|
||||
int r = ii * 0x11;
|
||||
int g = ii * 0x11;
|
||||
int b = ii * 0x11;
|
||||
|
||||
// ?? the lookup seems to reference 0x3f colours, unless 1 bit is priority or similar?
|
||||
palette.set_indirect_color(i + 0x20, rgb_t(pal5bit(r >> 1), pal5bit(g >> 1), pal5bit(b >> 1)));
|
||||
palette.set_indirect_color(i, rgb_t(r, g, b));
|
||||
|
||||
ii = (data >> 1) & 0x0f;
|
||||
r = ii * 0x11;
|
||||
g = ii * 0x11;
|
||||
b = ii * 0x11;
|
||||
|
||||
// ?? the lookup seems to reference 0x3f colours, unless 1 bit is something else (priority?)
|
||||
palette.set_indirect_color(i + 0x20, rgb_t(r, g, b));
|
||||
}
|
||||
|
||||
uint8_t const *const lookup = memregion("tileattr")->base();
|
||||
@ -115,62 +149,70 @@ void portrait_state::portrait_palette(palette_device &palette) const
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void portrait_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
/*
|
||||
* [2]
|
||||
* x--- ---- priority?
|
||||
* -x-- ---- more priority?
|
||||
* \- eagle sprite in stage 4 sets this only,
|
||||
* drawing should really go above the fg layer mountains
|
||||
* (missing tile category?)
|
||||
* --x- ---- flipy
|
||||
* ---x ---- ?
|
||||
* ---- x--- msb Y position?
|
||||
* ---- -x-- msb X position?
|
||||
*/
|
||||
void portrait_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, u8 priority)
|
||||
{
|
||||
uint8_t *source = m_spriteram;
|
||||
uint8_t *finish = source + 0x200;
|
||||
|
||||
while( source < finish )
|
||||
// TODO: is anything beyond byte [3] really just work RAM buffer?
|
||||
for( ; source < finish; source += 0x10 )
|
||||
{
|
||||
int sy = source[0];
|
||||
int sx = source[1];
|
||||
int attr = source[2];
|
||||
/* xx-x---- ?
|
||||
* --x----- flipy
|
||||
* ----x--- msb source[0]
|
||||
* -----x-- msb source[1]
|
||||
*/
|
||||
int tilenum = source[3];
|
||||
u8 attr = source[2];
|
||||
if (BIT(attr, 7) != priority)
|
||||
continue;
|
||||
u16 sy = source[0];
|
||||
u16 sx = source[1];
|
||||
u8 tilenum = source[3];
|
||||
|
||||
int color = ((tilenum&0xff)>>1)+0x00;
|
||||
// TODO: may be given by source[4] and/or source[5] instead
|
||||
u8 color = ((tilenum&0xff)>>1)+0x00;
|
||||
|
||||
int fy = attr & 0x20;
|
||||
int fy = BIT(attr, 5);
|
||||
|
||||
if(attr & 0x04) sx |= 0x100;
|
||||
|
||||
if(attr & 0x08) sy |= 0x100;
|
||||
if (BIT(attr, 2)) sx |= 0x100;
|
||||
if (BIT(attr, 3)) sy |= 0x100;
|
||||
|
||||
sx += (source - m_spriteram) - 8;
|
||||
sx &= 0x1ff;
|
||||
|
||||
sy = (512 - 64) - sy;
|
||||
// TODO: confirm Y calculation
|
||||
// it expects to follow up whatever is the current scroll value (cfr. monkeys climbing trees in stage 1)
|
||||
// but then there are various misc sprites that breaks this rule. Examples are:
|
||||
// - player photo flash;
|
||||
// - death animation sprites;
|
||||
// - capturing photo frame in gameplay;
|
||||
// PC=0x2828 is where all of these odd sprites happens, where:
|
||||
// HL=ROM pointer for destination sprite pointer, IY=sprite pointer source
|
||||
// where they copy the origin of the given sprite, read scroll buffer $9235-36 then apply offset,
|
||||
// with [2] bits 7-6 set high and bits 5-4 copied from the source sprite.
|
||||
// Note that this will break elsewhere by logically using any of the [2] bits,
|
||||
// arguably SW does a very limited use to pinpoint what's the actual scroll disable condition,
|
||||
// it just implicitly don't setup [4] to [7] ...
|
||||
if ((source[5] & 0xf) == 0)
|
||||
sy = (511 - 16) - sy;
|
||||
else
|
||||
sy = ((511 - m_scroll) - 16) - sy;
|
||||
|
||||
/* wrong! */
|
||||
switch( attr & 0xc0 )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
sy &= 0x1ff;
|
||||
|
||||
case 0x40:
|
||||
sy -= m_scroll;
|
||||
break;
|
||||
|
||||
case 0x80:
|
||||
sy -= m_scroll;
|
||||
break;
|
||||
|
||||
case 0xc0:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
m_gfxdecode->gfx(0)->transpen(bitmap,cliprect,
|
||||
tilenum,color,
|
||||
0,fy,
|
||||
sx,sy,7);
|
||||
|
||||
source += 0x10;
|
||||
m_gfxdecode->gfx(0)->transpen(
|
||||
bitmap, cliprect,
|
||||
tilenum, color,
|
||||
0, fy,
|
||||
sx, sy,
|
||||
7);
|
||||
}
|
||||
}
|
||||
|
||||
@ -180,19 +222,23 @@ uint32_t portrait_state::screen_update(screen_device &screen, bitmap_ind16 &bitm
|
||||
|
||||
cliprect_scroll = cliprect_no_scroll = cliprect;
|
||||
|
||||
// TODO: make clipping areas more readable
|
||||
cliprect_no_scroll.min_x = cliprect_no_scroll.max_x - 111;
|
||||
cliprect_scroll.max_x = cliprect_scroll.min_x + 319;
|
||||
|
||||
// status bar
|
||||
m_background->set_scrolly(0, 0);
|
||||
m_foreground->set_scrolly(0, 0);
|
||||
m_background->draw(screen, bitmap, cliprect_no_scroll, 0, 0);
|
||||
m_foreground->draw(screen, bitmap, cliprect_no_scroll, 0, 0);
|
||||
|
||||
// playfield
|
||||
m_background->set_scrolly(0, m_scroll);
|
||||
m_foreground->set_scrolly(0, m_scroll);
|
||||
m_background->draw(screen, bitmap, cliprect_scroll, 0, 0);
|
||||
draw_sprites(bitmap, cliprect_scroll, 0);
|
||||
m_foreground->draw(screen, bitmap, cliprect_scroll, 0, 0);
|
||||
draw_sprites(bitmap, cliprect_scroll, 1);
|
||||
|
||||
draw_sprites(bitmap,cliprect);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user