Previous 199869 Revisions Next

r34039 Wednesday 24th December, 2014 at 06:31:12 UTC by Fabio Priuli
(MESS) gamegear: moved GG-SMS scaling from VDP file to the machine file;
undone the specific X-Scroll timing introduced to fix Chicago Syndicate, for Game
Gear, because it causes problems with the games Sonic Drift 1 and 2; reduced
the amount of duplicated code in the VDP file. [Enik Land]

out of whatsnew: gamegear units modded to output the image signal to a TV are able
to show games using SMS compatibility mode in full screen, without scaling, while
native GG games are displayed in a centered, smaller image, that is surrounded by
bigger borders. Also, GG units that have the original LCD display replaced by another
LCD display model (not just the back-light) also displays SMS compatibility games
without scaling, and native games with borders. This suggests that the scaling
isn't performed by the VDP and therefore motivated the moving of the scaling code
in this commit.
[src/emu/video]315_5124.c 315_5124.h 315_5313.c
[src/mess/drivers]sms.c
[src/mess/includes]sms.h
[src/mess/machine]sms.c

trunk/src/emu/video/315_5124.c
r242550r242551
7171#define VCOUNT_CHANGE_HPOS    23
7272#define SPROVR_HPOS           24
7373#define SPRCOL_BASEHPOS       59
74#define XSCROLL_HPOS          21
7475#define DISPLAY_DISABLED_HPOS 24 /* not verified, works if above 18 (for 'pstrike2') and below 25 (for 'fantdizzy') */
7576#define DISPLAY_CB_HPOS       2  /* fixes 'roadrash' (SMS game) title scrolling, due to line counter reload timing */
7677
r242550r242551
161162   , m_pause_cb(*this)
162163   , m_space_config("videoram", ENDIANNESS_LITTLE, 8, 14, 0, NULL, *ADDRESS_MAP_NAME(sega315_5124))
163164   , m_palette(*this, "palette")
164   , m_xscroll_hpos(X_SCROLL_HPOS_5124)
165165{
166166}
167167
168168
169sega315_5124_device::sega315_5124_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 cram_size, UINT8 palette_offset, bool supports_224_240, const char *shortname, const char *source, int xscroll_hpos)
169sega315_5124_device::sega315_5124_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 cram_size, UINT8 palette_offset, bool supports_224_240, const char *shortname, const char *source)
170170   : device_t( mconfig, type, name, tag, owner, clock, shortname, __FILE__)
171171   , device_memory_interface(mconfig, *this)
172172   , device_video_interface(mconfig, *this)
r242550r242551
178178   , m_pause_cb(*this)
179179   , m_space_config("videoram", ENDIANNESS_LITTLE, 8, 14, 0, NULL, *ADDRESS_MAP_NAME(sega315_5124))
180180   , m_palette(*this, "palette")
181   , m_xscroll_hpos(xscroll_hpos)
182181{
183182}
184183
185184
186185sega315_5246_device::sega315_5246_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
187   : sega315_5124_device( mconfig, SEGA315_5246, "Sega 315-5246 VDP", tag, owner, clock, SEGA315_5124_CRAM_SIZE, 0, true, "sega315_5246", __FILE__, X_SCROLL_HPOS_5124)
186   : sega315_5124_device( mconfig, SEGA315_5246, "Sega 315-5246 VDP", tag, owner, clock, SEGA315_5124_CRAM_SIZE, 0, true, "sega315_5246", __FILE__)
188187{
189188}
190189
191190
192191sega315_5378_device::sega315_5378_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
193   : sega315_5124_device( mconfig, SEGA315_5378, "Sega 315-5378 VDP", tag, owner, clock, SEGA315_5378_CRAM_SIZE, 0x10, true, "sega315_5378", __FILE__, X_SCROLL_HPOS_5378)
192   : sega315_5124_device( mconfig, SEGA315_5378, "Sega 315-5378 VDP", tag, owner, clock, SEGA315_5378_CRAM_SIZE, 0x10, true, "sega315_5378", __FILE__)
194193{
195194}
196195
r242550r242551
298297{
299298   const int active_scr_start = 46;      /* 9 + 2 + 14 + 8 + 13 */
300299
301   /* The emulation core returns a screen hpos that is one position ahead in comparison
302      with the expected VDP hclock value, if the same range is used (from 0 to width-1). */
300   /* The hcount value returned by the VDP seems to be based on the previous hpos */
303301   int hclock = hpos - 1;
304302   if (hclock < 0)
305303      hclock += SEGA315_5124_WIDTH;
306304
307   /* Calculate and store the new hcount. */
308305   m_hcounter = ((hclock - active_scr_start) >> 1) & 0xff;
309306}
310307
r242550r242551
453450      m_rborder_timer->adjust( m_screen->time_until_pos( vpos, SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH + 256 ), vpos );
454451
455452      /* Draw middle of the border */
456      /* We need to do this through the regular drawing function so it will */
457      /* be included in the gamegear scaling functions */
453      /* We need to do this through the regular drawing function */
454      /* so sprite collisions can occur on the border. */
455      select_sprites( vpos - (vpos_limit - m_frame_timing[ACTIVE_DISPLAY_V]) );
458456      m_draw_timer->adjust( m_screen->time_until_pos( vpos, m_draw_time ), vpos_limit - m_frame_timing[ACTIVE_DISPLAY_V] );
459457      return;
460458   }
r242550r242551
508506      m_rborder_timer->adjust( m_screen->time_until_pos( vpos, SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH + 256 ), vpos );
509507
510508      /* Draw middle of the border */
511      /* We need to do this through the regular drawing function so it will */
512      /* be included in the gamegear scaling functions */
509      /* We need to do this through the regular drawing function */
510      /* so sprite collisions can occur on the border. */
513511      select_sprites( vpos - (vpos_limit + m_frame_timing[TOP_BORDER]) );
514512      m_draw_timer->adjust( m_screen->time_until_pos( vpos, m_draw_time ), vpos_limit + m_frame_timing[TOP_BORDER] );
515513      return;
r242550r242551
572570   if ((m_pending_status & STATUS_HINT) && hpos >= HINT_HPOS)
573571   {
574572      m_pending_status &= ~STATUS_HINT;
575      m_status |= STATUS_HINT;   // fake flag.
573      m_status |= STATUS_HINT;   // fake flag, it is overridden on register read.
576574   }
577575   if ((m_pending_status & STATUS_VINT) && hpos >= VINT_FLAG_HPOS)
578576   {
r242550r242551
691689               m_display_disabled = !(m_reg[0x01] & 0x40);
692690            break;
693691         case 8:
694            if (m_screen->hpos() <= m_xscroll_hpos)
692            if (m_screen->hpos() <= XSCROLL_HPOS)
695693               m_reg8copy = m_reg[0x08];
696694         }
697695
r242550r242551
820818      bit_plane_2 = space().read_byte(((tile_selected << 5) + ((tile_line & 0x07) << 2)) + 0x02);
821819      bit_plane_3 = space().read_byte(((tile_selected << 5) + ((tile_line & 0x07) << 2)) + 0x03);
822820
823      for (pixel_x = 0; pixel_x < 8 ; pixel_x++)
821      for (pixel_x = 0; pixel_x < 8; pixel_x++)
824822      {
825823         UINT8 pen_bit_0, pen_bit_1, pen_bit_2, pen_bit_3;
826824         UINT8 pen_selected;
r242550r242551
834832         if (palette_selected)
835833            pen_selected |= 0x10;
836834
837
838835         if (!horiz_selected)
839836         {
840837            pixel_plot_x = pixel_x;
r242550r242551
843840         {
844841            pixel_plot_x = 7 - pixel_x;
845842         }
843
846844         pixel_plot_x = (0 - (x_scroll & 0x07) + (tile_column << 3) + pixel_plot_x);
847845         if (pixel_plot_x >= 0 && pixel_plot_x < 256)
848846         {
849847            //logerror("%x %x\n", pixel_plot_x, line);
850            line_buffer[pixel_plot_x] = m_current_palette[pen_selected];
848            if (tile_column == 0 && (x_scroll & 0x07))
849            {
850               /* the VDP only draws the first column when it has completely entered
851                  in the screen, else it is filled with the sprite pattern #0 */
852               line_buffer[pixel_plot_x] = m_current_palette[0x10];
853            }
854            else
855            {
856               line_buffer[pixel_plot_x] = m_current_palette[pen_selected];
857            }
851858            priority_selected[pixel_plot_x] = priority_select | (pen_selected & 0x0f);
852859         }
853860      }
r242550r242551
10161023void sega315_5124_device::draw_sprites_mode4( int *line_buffer, int *priority_selected, int line )
10171024{
10181025   bool sprite_col_occurred = false;
1019   int sprite_col_x = SEGA315_5124_WIDTH;
1020   UINT8 collision_buffer[SEGA315_5124_WIDTH];
1026   int sprite_col_x = 255;
1027   UINT8 collision_buffer[256];
10211028   int plot_min_x = 0;
10221029
10231030   if (m_display_disabled || m_sprite_count == 0)
r242550r242551
10271034   if (m_reg[0x00] & 0x20)
10281035      plot_min_x = 8;
10291036
1030   memset(collision_buffer, 0, SEGA315_5124_WIDTH);
1037   memset(collision_buffer, 0, sizeof(collision_buffer));
10311038
10321039   /* Draw sprite layer */
10331040   for (int sprite_buffer_index = m_sprite_count - 1; sprite_buffer_index >= 0; sprite_buffer_index--)
r242550r242551
10411048      UINT8 bit_plane_2 = space().read_byte((sprite_tile_selected << 5) + sprite_pattern_line + 0x02);
10421049      UINT8 bit_plane_3 = space().read_byte((sprite_tile_selected << 5) + sprite_pattern_line + 0x03);
10431050
1044      for (int pixel_x = 0; pixel_x < 8 ; pixel_x++)
1051      for (int pixel_x = 0; pixel_x < 8; pixel_x++)
10451052      {
1053         int pixel_plot_x;
10461054         UINT8 pen_bit_0 = (bit_plane_0 >> (7 - pixel_x)) & 0x01;
10471055         UINT8 pen_bit_1 = (bit_plane_1 >> (7 - pixel_x)) & 0x01;
10481056         UINT8 pen_bit_2 = (bit_plane_2 >> (7 - pixel_x)) & 0x01;
10491057         UINT8 pen_bit_3 = (bit_plane_3 >> (7 - pixel_x)) & 0x01;
10501058         UINT8 pen_selected = (pen_bit_3 << 3 | pen_bit_2 << 2 | pen_bit_1 << 1 | pen_bit_0) | 0x10;
10511059
1052         if (pen_selected == 0x10)       /* Transparent palette so skip draw */
1060         if (pen_selected == 0x10)
10531061         {
1062            /* Transparent palette so skip draw */
10541063            continue;
10551064         }
10561065
10571066         if (m_sprite_zoom > 1)
10581067         {
10591068            /* sprite doubling is enabled */
1060            int pixel_plot_x = sprite_x + (pixel_x << 1);
1061
1062            /* check to prevent going outside of active display area */
1063            if (pixel_plot_x < plot_min_x || pixel_plot_x > 255)
1064            {
1065               continue;
1066            }
1067
1068            if (!(priority_selected[pixel_plot_x] & PRIORITY_BIT))
1069            {
1070               line_buffer[pixel_plot_x] = m_current_palette[pen_selected];
1071               priority_selected[pixel_plot_x] = pen_selected;
1072               line_buffer[pixel_plot_x + 1] = m_current_palette[pen_selected];
1073               priority_selected[pixel_plot_x + 1] = pen_selected;
1074            }
1075            else
1076            {
1077               if (priority_selected[pixel_plot_x] == PRIORITY_BIT)
1078               {
1079                  line_buffer[pixel_plot_x] = m_current_palette[pen_selected];
1080                  priority_selected[pixel_plot_x] = pen_selected;
1081               }
1082               if (priority_selected[pixel_plot_x + 1] == PRIORITY_BIT)
1083               {
1084                  line_buffer[pixel_plot_x + 1] = m_current_palette[pen_selected];
1085                  priority_selected[pixel_plot_x + 1] = pen_selected;
1086               }
1087            }
1088            if (collision_buffer[pixel_plot_x] != 1)
1089            {
1090               collision_buffer[pixel_plot_x] = 1;
1091            }
1092            else
1093            {
1094               sprite_col_occurred = true;
1095               sprite_col_x = MIN(sprite_col_x, pixel_plot_x);
1096            }
1097            if (collision_buffer[pixel_plot_x + 1] != 1)
1098            {
1099               collision_buffer[pixel_plot_x + 1] = 1;
1100            }
1101            else
1102            {
1103               sprite_col_occurred = true;
1104               sprite_col_x = MIN(sprite_col_x, pixel_plot_x);
1105            }
1069            pixel_plot_x = sprite_x + (pixel_x << 1);
11061070         }
11071071         else
11081072         {
1109            int pixel_plot_x = sprite_x + pixel_x;
1073            pixel_plot_x = sprite_x + pixel_x;
1074         }
11101075
1076         /* Draw at pixel position and, if zoomed, at pixel+1 */
1077         for (int zoom = 0; zoom < m_sprite_zoom; zoom++)
1078         {
1079            pixel_plot_x += zoom;
1080
11111081            /* check to prevent going outside of active display area */
11121082            if (pixel_plot_x < plot_min_x || pixel_plot_x > 255)
11131083            {
r242550r242551
11211091            }
11221092            else
11231093            {
1094               /* Check if the higher priority background has transparent pixel */
11241095               if (priority_selected[pixel_plot_x] == PRIORITY_BIT)
11251096               {
11261097                  line_buffer[pixel_plot_x] = m_current_palette[pen_selected];
r242550r242551
11501121void sega315_5124_device::draw_sprites_tms9918_mode( int *line_buffer, int line )
11511122{
11521123   bool sprite_col_occurred = false;
1153   int sprite_col_x = SEGA315_5124_WIDTH;
1154   UINT8 collision_buffer[SEGA315_5124_WIDTH];
1124   int sprite_col_x = 255;
1125   UINT8 collision_buffer[256];
11551126
11561127   if (m_display_disabled || m_sprite_count == 0)
11571128      return;
11581129
1159   memset(collision_buffer, 0, SEGA315_5124_WIDTH);
1130   memset(collision_buffer, 0, sizeof(collision_buffer));
11601131
11611132   /* Draw sprite layer */
11621133   for (int sprite_buffer_index = m_sprite_count - 1; sprite_buffer_index >= 0; sprite_buffer_index--)
r242550r242551
11681139      int sprite_tile_selected = m_sprite_tile_selected[sprite_buffer_index];
11691140      UINT16 sprite_pattern_line = m_sprite_pattern_line[sprite_buffer_index];
11701141
1171      UINT8 pattern = space().read_byte( sprite_pattern_line + sprite_tile_selected * 8 );
1172
1173      for (int pixel_x = 0; pixel_x < 8; pixel_x++)
1142      for (int height = 8; height <= m_sprite_height; height += 8)
11741143      {
1175         if (m_reg[0x01] & 0x01)
1144         if (height == 16)
11761145         {
1177            int pixel_plot_x = sprite_x + pixel_x * 2;
1178
1179            if (pixel_plot_x < 0 || pixel_plot_x > 255)
1180            {
1181               continue;
1182            }
1183
1184            if (pen_selected && (pattern & (1 << (7 - pixel_x))))
1185            {
1186               line_buffer[pixel_plot_x] = m_current_palette[pen_selected];
1187
1188               if (collision_buffer[pixel_plot_x] != 1)
1189               {
1190                  collision_buffer[pixel_plot_x] = 1;
1191               }
1192               else
1193               {
1194                  sprite_col_occurred = true;
1195                  sprite_col_x = MIN(sprite_col_x, pixel_plot_x);
1196               }
1197
1198               line_buffer[pixel_plot_x+1] = m_current_palette[pen_selected];
1199
1200               if (collision_buffer[pixel_plot_x + 1] != 1)
1201               {
1202                  collision_buffer[pixel_plot_x + 1] = 1;
1203               }
1204               else
1205               {
1206                  sprite_col_occurred = true;
1207                  sprite_col_x = MIN(sprite_col_x, pixel_plot_x);
1208               }
1209            }
1146            sprite_tile_selected += 2;
1147            sprite_x += (m_sprite_zoom > 1 ? 16 : 8);
12101148         }
1211         else
1212         {
1213            int pixel_plot_x = sprite_x + pixel_x;
12141149
1215            if (pixel_plot_x < 0 || pixel_plot_x > 255)
1216            {
1217               continue;
1218            }
1150         UINT8 pattern = space().read_byte( sprite_pattern_line + sprite_tile_selected * 8 );
12191151
1152         for (int pixel_x = 0; pixel_x < 8; pixel_x++)
1153         {
12201154            if (pen_selected && (pattern & (1 << (7 - pixel_x))))
12211155            {
1222               line_buffer[pixel_plot_x] = m_current_palette[pen_selected];
1223
1224               if (collision_buffer[pixel_plot_x] != 1)
1156               int pixel_plot_x;
1157               if (m_sprite_zoom > 1)
12251158               {
1226                  collision_buffer[pixel_plot_x] = 1;
1159                  pixel_plot_x = sprite_x + (pixel_x << 1);
12271160               }
12281161               else
12291162               {
1230                  sprite_col_occurred = true;
1231                  sprite_col_x = MIN(sprite_col_x, pixel_plot_x);
1163                  pixel_plot_x = sprite_x + pixel_x;
12321164               }
1233            }
1234         }
1235      }
12361165
1237      if (m_sprite_height == 16)
1238      {
1239         sprite_tile_selected += 2;
1240         pattern = space().read_byte( sprite_pattern_line + sprite_tile_selected * 8 );
1241         sprite_x += (m_sprite_zoom > 1 ? 16 : 8);
1242
1243         for (int pixel_x = 0; pixel_x < 8; pixel_x++)
1244         {
1245            if (m_reg[0x01] & 0x01)
1246            {
1247               int pixel_plot_x = sprite_x + pixel_x * 2;
1248
1249               if (pixel_plot_x < 0 || pixel_plot_x > 255)
1166               /* Draw at pixel position and, if zoomed, at pixel+1 */
1167               for (int zoom = 0; zoom < m_sprite_zoom; zoom++)
12501168               {
1251                  continue;
1252               }
1169                  pixel_plot_x += zoom;
12531170
1254               if (pen_selected && (pattern & (1 << (7 - pixel_x))))
1255               {
1256                  line_buffer[pixel_plot_x] = m_current_palette[pen_selected];
1257
1258                  if (collision_buffer[pixel_plot_x] != 1)
1171                  /* check to prevent going outside of active display area */
1172                  if (pixel_plot_x < 0 || pixel_plot_x > 255)
12591173                  {
1260                     collision_buffer[pixel_plot_x] = 1;
1174                     continue;
12611175                  }
1262                  else
1263                  {
1264                     sprite_col_occurred = true;
1265                     sprite_col_x = MIN(sprite_col_x, pixel_plot_x);
1266                  }
12671176
1268                  line_buffer[pixel_plot_x+1] = m_current_palette[pen_selected];
1269
1270                  if (collision_buffer[pixel_plot_x + 1] != 1)
1271                  {
1272                     collision_buffer[pixel_plot_x + 1] = 1;
1273                  }
1274                  else
1275                  {
1276                     sprite_col_occurred = true;
1277                     sprite_col_x = MIN(sprite_col_x, pixel_plot_x);
1278                  }
1279               }
1280            }
1281            else
1282            {
1283               int pixel_plot_x = sprite_x + pixel_x;
1284
1285               if (pixel_plot_x < 0 || pixel_plot_x > 255)
1286               {
1287                  continue;
1288               }
1289
1290               if (pen_selected && (pattern & (1 << (7 - pixel_x))))
1291               {
12921177                  line_buffer[pixel_plot_x] = m_current_palette[pen_selected];
12931178
12941179                  if (collision_buffer[pixel_plot_x] != 1)
r242550r242551
14031288
14041289void sega315_5124_device::draw_scanline( int pixel_offset_x, int pixel_plot_y, int line )
14051290{
1406   int x;
1407   int *blitline_buffer = m_line_buffer;
1291   int blitline_buffer[256];
14081292   int priority_selected[256];
14091293
14101294   /* Sprite processing is restricted because collisions on top border of extended
r242550r242551
14481332         if ( line >= 0 || ( line >= -13 && m_y_pixels == 192 ) )
14491333         {
14501334            draw_sprites_mode4( blitline_buffer, priority_selected, line );
1451            if ( line >= 0 )
1452            {
1453               /* Fill column 0 with overscan color from m_reg[0x07] */
1454               if (m_reg[0x00] & 0x20)
1455               {
1456                  blitline_buffer[0] = m_current_palette[BACKDROP_COLOR];
1457                  priority_selected[0] = 1;
1458                  blitline_buffer[1] = m_current_palette[BACKDROP_COLOR];
1459                  priority_selected[1] = 1;
1460                  blitline_buffer[2] = m_current_palette[BACKDROP_COLOR];
1461                  priority_selected[2] = 1;
1462                  blitline_buffer[3] = m_current_palette[BACKDROP_COLOR];
1463                  priority_selected[3] = 1;
1464                  blitline_buffer[4] = m_current_palette[BACKDROP_COLOR];
1465                  priority_selected[4] = 1;
1466                  blitline_buffer[5] = m_current_palette[BACKDROP_COLOR];
1467                  priority_selected[5] = 1;
1468                  blitline_buffer[6] = m_current_palette[BACKDROP_COLOR];
1469                  priority_selected[6] = 1;
1470                  blitline_buffer[7] = m_current_palette[BACKDROP_COLOR];
1471                  priority_selected[7] = 1;
1472               }
1473            }
14741335         }
14751336         break;
14761337      }
14771338   }
14781339
1479   UINT32 *p_bitmap = &m_tmpbitmap.pix32(pixel_plot_y + line, pixel_offset_x);
1480   UINT8  *p_y1 = &m_y1_bitmap.pix8(pixel_plot_y + line, pixel_offset_x);
1481
14821340   /* Check if display is disabled or we're below/above active area */
14831341   if (m_display_disabled || line < 0 || line >= m_frame_timing[ACTIVE_DISPLAY_V])
14841342   {
1485      for (x = 0; x < 256; x++)
1486      {
1487         p_bitmap[x] = m_palette->pen(m_current_palette[BACKDROP_COLOR]);
1488         p_y1[x] = 1;
1489      }
1343      rectangle rec;
1344      rec.min_y = rec.max_y = pixel_plot_y + line;
1345
1346      rec.min_x = pixel_offset_x;
1347      rec.max_x = pixel_offset_x + 255;
1348      m_tmpbitmap.fill(m_palette->pen(m_current_palette[BACKDROP_COLOR]), rec);
1349      m_y1_bitmap.fill(1, rec);
14901350   }
14911351   else
14921352   {
1493      for (x = 0; x < 256; x++)
1494      {
1495         p_bitmap[x] = m_palette->pen(blitline_buffer[x]);
1496         p_y1[x] = ( priority_selected[x] & 0x0f ) ? 0 : 1;
1497      }
1353      blit_scanline(blitline_buffer, priority_selected, pixel_offset_x, pixel_plot_y, line);
14981354   }
14991355}
15001356
15011357
1502void sega315_5378_device::draw_scanline( int pixel_offset_x, int pixel_plot_y, int line )
1358void sega315_5124_device::blit_scanline( int *line_buffer, int *priority_selected, int pixel_offset_x, int pixel_plot_y, int line )
15031359{
1504   int x;
1505   int *blitline_buffer = m_line_buffer;
1506   int priority_selected[256];
1360   UINT32 *p_bitmap = &m_tmpbitmap.pix32(pixel_plot_y + line, pixel_offset_x);
1361   UINT8  *p_y1 = &m_y1_bitmap.pix8(pixel_plot_y + line, pixel_offset_x);
1362   int x = 0;
15071363
1508   if ( line < m_frame_timing[ACTIVE_DISPLAY_V] )
1364   if (m_vdp_mode == 4 && m_reg[0x00] & 0x20)
15091365   {
1510      switch( m_vdp_mode )
1366      /* Fill column 0 with overscan color from m_reg[0x07] */
1367      do
15111368      {
1512      case 0:
1513         if ( line >= 0 )
1514         {
1515            draw_scanline_mode0( blitline_buffer, line );
1516         }
1517         if ( line >= 0 || ( line >= -13 && m_y_pixels == 192 ) )
1518         {
1519            draw_sprites_tms9918_mode( blitline_buffer, line );
1520         }
1521         break;
1522
1523      case 2:
1524         if ( line >= 0 )
1525         {
1526            draw_scanline_mode2( blitline_buffer, line );
1527         }
1528         if ( line >= 0 || ( line >= -13 && m_y_pixels == 192 ) )
1529         {
1530            draw_sprites_tms9918_mode( blitline_buffer, line );
1531         }
1532         break;
1533
1534      case 4:
1535      default:
1536         memset(priority_selected, 0, sizeof(priority_selected));
1537         if ( line >= 0 )
1538         {
1539            draw_scanline_mode4( blitline_buffer, priority_selected, line );
1540         }
1541         if ( line >= 0 || ( line >= -13 && m_y_pixels == 192 ) )
1542         {
1543            draw_sprites_mode4( blitline_buffer, priority_selected, line );
1544            if ( line >= 0 )
1545            {
1546               /* Fill column 0 with overscan color from m_reg[0x07] */
1547               if (m_reg[0x00] & 0x20)
1548               {
1549                  blitline_buffer[0] = m_current_palette[BACKDROP_COLOR];
1550                  priority_selected[0] = 1;
1551                  blitline_buffer[1] = m_current_palette[BACKDROP_COLOR];
1552                  priority_selected[1] = 1;
1553                  blitline_buffer[2] = m_current_palette[BACKDROP_COLOR];
1554                  priority_selected[2] = 1;
1555                  blitline_buffer[3] = m_current_palette[BACKDROP_COLOR];
1556                  priority_selected[3] = 1;
1557                  blitline_buffer[4] = m_current_palette[BACKDROP_COLOR];
1558                  priority_selected[4] = 1;
1559                  blitline_buffer[5] = m_current_palette[BACKDROP_COLOR];
1560                  priority_selected[5] = 1;
1561                  blitline_buffer[6] = m_current_palette[BACKDROP_COLOR];
1562                  priority_selected[6] = 1;
1563                  blitline_buffer[7] = m_current_palette[BACKDROP_COLOR];
1564                  priority_selected[7] = 1;
1565               }
1566            }
1567         }
1568         break;
1369         p_bitmap[x] = m_palette->pen(m_current_palette[BACKDROP_COLOR]);
1370         p_y1[x] = 1;
15691371      }
1372      while(++x < 8);
15701373   }
15711374
1572   /* Check if display is disabled or we're below/above active area */
1573   if (m_display_disabled || line < 0 || line >= m_frame_timing[ACTIVE_DISPLAY_V])
1375   do
15741376   {
1575      for (x = 0; x < 256; x++)
1576      {
1577         blitline_buffer[x] = m_current_palette[BACKDROP_COLOR];
1578      }
1377      p_bitmap[x] = m_palette->pen(line_buffer[x]);
1378      p_y1[x] = ( priority_selected[x] & 0x0f ) ? 0 : 1;
15791379   }
1380   while(++x < 256);
1381}
15801382
1383
1384void sega315_5378_device::blit_scanline( int *line_buffer, int *priority_selected, int pixel_offset_x, int pixel_plot_y, int line )
1385{
15811386   if (m_sega315_5124_compatibility_mode)
15821387   {
1583      int *combineline_buffer = m_line_buffer + ((line & 0x03) + 1) * 256;
1584      int plot_x = 48;
1388      sega315_5124_device::blit_scanline(line_buffer, priority_selected, pixel_offset_x, pixel_plot_y, line);
1389   }
1390   else
1391   {
1392      UINT32 *p_bitmap = &m_tmpbitmap.pix32(pixel_plot_y + line, pixel_offset_x);
1393      UINT8  *p_y1 = &m_y1_bitmap.pix8(pixel_plot_y + line, pixel_offset_x);
1394      int x = 0;
15851395
1586      /* Do horizontal scaling */
1587      for (x = 8; x < 248;)
1396      /* border on left side of the GG active screen */
1397      do
15881398      {
1589         int combined;
1590
1591         /* Take red and green from first pixel, and blue from second pixel */
1592         combined = (blitline_buffer[x] & 0x00ff) | (blitline_buffer[x + 1] & 0x0f00);
1593         combineline_buffer[plot_x] = combined;
1594
1595         /* Take red from second pixel, and green and blue from third pixel */
1596         combined = (blitline_buffer[x + 1] & 0x000f) | (blitline_buffer[x + 2] & 0x0ff0);
1597         combineline_buffer[plot_x + 1] = combined;
1598         x += 3;
1599         plot_x += 2;
1399         p_bitmap[x] = m_palette->pen(m_current_palette[BACKDROP_COLOR]);
1400         p_y1[x] = 1; // not verified
16001401      }
1402      while (++x < 48);
16011403
1602      /* Do vertical scaling for a screen with 192 or 224 lines
1603         Lines 0-2 and 221-223 have no effect on the output on the GG screen.
1604         We will calculate the gamegear lines as follows:
1605         GG_0 = 1/6 * SMS_3 + 1/3 * SMS_4 + 1/3 * SMS_5 + 1/6 * SMS_6
1606         GG_1 = 1/6 * SMS_4 + 1/3 * SMS_5 + 1/3 * SMS_6 + 1/6 * SMS_7
1607         GG_2 = 1/6 * SMS_6 + 1/3 * SMS_7 + 1/3 * SMS_8 + 1/6 * SMS_9
1608         GG_3 = 1/6 * SMS_7 + 1/3 * SMS_8 + 1/3 * SMS_9 + 1/6 * SMS_10
1609         GG_4 = 1/6 * SMS_9 + 1/3 * SMS_10 + 1/3 * SMS_11 + 1/6 * SMS_12
1610         .....
1611         GG_142 = 1/6 * SMS_216 + 1/3 * SMS_217 + 1/3 * SMS_218 + 1/6 * SMS_219
1612         GG_143 = 1/6 * SMS_217 + 1/3 * SMS_218 + 1/3 * SMS_219 + 1/6 * SMS_220
1613      */
1404      if ( line >= 24 && line < 168 )
16141405      {
1615         int gg_line;
1616         int my_line = pixel_plot_y + line - (SEGA315_5124_TBORDER_START + SEGA315_5124_NTSC_224_TBORDER_HEIGHT);
1617         int *line1, *line2, *line3, *line4;
1618
1619         /* First make sure there's enough data to draw anything */
1620         /* We need one more line of data if we're on line 8, 11, 14, 17, etc */
1621         if (my_line < 6 || my_line > 220 || ((my_line - 8) % 3 == 0))
1406         do
16221407         {
1623            return;
1408            p_bitmap[x] = m_palette->pen(line_buffer[x]);
1409            p_y1[x] = ( priority_selected[x] & 0x0f ) ? 0 : 1;
16241410         }
1625
1626         gg_line = ((my_line - 6) / 3) * 2;
1627
1628         /* If we're on SMS line 7, 10, 13, etc we're on an odd GG line */
1629         if (my_line % 3)
1411         while (++x < 208);
1412      }
1413      else
1414      {
1415         /* top/bottom GG border */
1416         do
16301417         {
1631            gg_line++;
1418            p_bitmap[x] = m_palette->pen(m_current_palette[BACKDROP_COLOR]);
1419            p_y1[x] = 1; // not verified
16321420         }
1633
1634         /* Calculate the line we will be drawing on */
1635         pixel_plot_y = SEGA315_5124_TBORDER_START + SEGA315_5124_NTSC_192_TBORDER_HEIGHT + 24 + gg_line;
1636
1637         /* Setup our source lines */
1638         line1 = m_line_buffer + (((my_line - 3) & 0x03) + 1) * 256;
1639         line2 = m_line_buffer + (((my_line - 2) & 0x03) + 1) * 256;
1640         line3 = m_line_buffer + (((my_line - 1) & 0x03) + 1) * 256;
1641         line4 = m_line_buffer + (((my_line - 0) & 0x03) + 1) * 256;
1642
1643         for (x = 0 + 48; x < 160 + 48; x++)
1644         {
1645            rgb_t   c1 = m_palette->pen(line1[x]);
1646            rgb_t   c2 = m_palette->pen(line2[x]);
1647            rgb_t   c3 = m_palette->pen(line3[x]);
1648            rgb_t   c4 = m_palette->pen(line4[x]);
1649            m_tmpbitmap.pix32(pixel_plot_y, pixel_offset_x + x) =
1650               rgb_t((c1.r() / 6 + c2.r() / 3 + c3.r() / 3 + c4.r() / 6 ),
1651                  (c1.g() / 6 + c2.g() / 3 + c3.g() / 3 + c4.g() / 6 ),
1652                  (c1.b() / 6 + c2.b() / 3 + c3.b() / 3 + c4.b() / 6 ) );
1653         }
1654         return;
1421         while (++x < 208);
16551422      }
1656      blitline_buffer = combineline_buffer;
1423     
1424      /* border on right side of the GG active screen */
1425      do
1426      {
1427         p_bitmap[x] = m_palette->pen(m_current_palette[BACKDROP_COLOR]);
1428         p_y1[x] = 1; // not verified
1429      }
1430      while (++x < 256);
16571431   }
1658
1659   for (x = 0; x < 256; x++)
1660   {
1661      m_tmpbitmap.pix32(pixel_plot_y + line, pixel_offset_x + x) = m_palette->pen(blitline_buffer[x]);
1662   }
16631432}
16641433
16651434
r242550r242551
18071576
18081577   /* Allocate video RAM */
18091578   astring tempstring;
1810   m_line_buffer = auto_alloc_array(machine(), int, 256 * 5);
18111579
18121580   m_frame_timing = (m_is_pal) ? pal_192 : ntsc_192;
18131581
r242550r242551
18461614   save_item(NAME(m_hcounter));
18471615   save_item(NAME(m_reg));
18481616   save_item(NAME(m_current_palette));
1849   save_pointer(NAME(m_line_buffer), 256 * 5);
18501617   save_item(NAME(m_tmpbitmap));
18511618   save_item(NAME(m_y1_bitmap));
18521619   save_item(NAME(m_draw_time));
r242550r242551
19001667
19011668   /* Clear RAM */
19021669   memset(m_CRAM, 0, sizeof(m_CRAM));
1903   memset(m_line_buffer, 0, 256 * 5 * sizeof(int));
19041670}
19051671
19061672static MACHINE_CONFIG_FRAGMENT( sega315_5124 )
trunk/src/emu/video/315_5124.h
r242550r242551
5959public:
6060   // construction/destruction
6161   sega315_5124_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
62   sega315_5124_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 cram_size, UINT8 palette_offset, bool supports_224_240, const char *shortname, const char *source, int xscroll_hpos = X_SCROLL_HPOS_5124);
62   sega315_5124_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 cram_size, UINT8 palette_offset, bool supports_224_240, const char *shortname, const char *source);
6363
6464   static void set_signal_type(device_t &device, bool is_pal) { downcast<sega315_5124_device &>(device).m_is_pal = is_pal; }
6565
r242550r242551
9090   virtual void set_sega315_5124_compatibility_mode( bool sega315_5124_compatibility_mode ) { };
9191
9292protected:
93   static const int X_SCROLL_HPOS_5124 = 21;
94   static const int X_SCROLL_HPOS_5378 = 41;  // Not verified, needed for Chicago Syndicate
95
9693   void set_display_settings();
9794   virtual void update_palette();
9895   virtual void cram_write(UINT8 data);
9996   virtual void draw_scanline( int pixel_offset_x, int pixel_plot_y, int line );
97   virtual void blit_scanline( int *line_buffer, int *priority_selected, int pixel_offset_x, int pixel_plot_y, int line );
10098   virtual UINT16 get_name_table_row(int row);
10199   void process_line_timer();
100   void select_sprites( int line );
102101   void draw_scanline_mode4( int *line_buffer, int *priority_selected, int line );
103102   void draw_sprites_mode4( int *line_buffer, int *priority_selected, int line );
104103   void draw_sprites_tms9918_mode( int *line_buffer, int line );
105104   void draw_scanline_mode2( int *line_buffer, int line );
106105   void draw_scanline_mode0( int *line_buffer, int line );
107   void select_sprites( int line );
108106   void check_pending_flags();
109107
110108   // device-level overrides
r242550r242551
152150   int              m_sprite_count;
153151   int              m_sprite_height;
154152   int              m_sprite_zoom;
155
156   /* line_buffer will be used to hold 5 lines of line data. Line #0 is the regular blitting area.
157      Lines #1-#4 will be used as a kind of cache to be used for vertical scaling in the gamegear
158      sms compatibility mode. */
159   int              *m_line_buffer;
160153   int              m_current_palette[32];
161154   bool             m_is_pal;             /* false = NTSC, true = PAL */
162155   devcb_write_line m_int_cb;       /* Interrupt callback function */
r242550r242551
183176   static const device_timer_id TIMER_FLAGS = 7;
184177
185178   required_device<palette_device> m_palette;
186   const int        m_xscroll_hpos;
187179};
188180
189181
r242550r242551
212204
213205   virtual void update_palette();
214206   virtual void cram_write(UINT8 data);
215   virtual void draw_scanline( int pixel_offset_x, int pixel_plot_y, int line );
207   virtual void blit_scanline( int *line_buffer, int *priority_selected, int pixel_offset_x, int pixel_plot_y, int line );
216208   virtual UINT16 get_name_table_row(int row);
217209};
218210
trunk/src/emu/video/315_5313.c
r242550r242551
1313const device_type SEGA315_5313 = &device_creator<sega315_5313_device>;
1414
1515sega315_5313_device::sega315_5313_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
16   : sega315_5124_device( mconfig, SEGA315_5313, "Sega 315-5313 Megadrive VDP", tag, owner, clock, SEGA315_5124_CRAM_SIZE, 0, true, "sega315_5313", __FILE__),
16   : sega315_5124_device(mconfig, SEGA315_5313, "Sega 315-5313 Megadrive VDP", tag, owner, clock, SEGA315_5124_CRAM_SIZE, 0, true, "sega315_5313", __FILE__),
1717   m_sndirqline_callback(*this),
1818   m_lv6irqline_callback(*this),
1919   m_lv4irqline_callback(*this),
trunk/src/mess/drivers/sms.c
r242550r242551
766766   MCFG_SCREEN_UPDATE_DRIVER(sms_state, screen_update_gamegear)
767767
768768   MCFG_VIDEO_START_OVERRIDE(sms_state,gamegear)
769   MCFG_VIDEO_RESET_OVERRIDE(sms_state,gamegear)
769770
770771   MCFG_DEVICE_ADD("sms_vdp", SEGA315_5378, 0)
771772   MCFG_SEGA315_5378_SET_SCREEN("screen")
trunk/src/mess/includes/sms.h
r242550r242551
9292
9393   // for gamegear LCD persistence hack
9494   bitmap_rgb32 m_prev_bitmap;
95   bool m_prev_bitmap_copied;
9596
97   // for gamegear SMS mode scaling
98   bitmap_rgb32 m_gg_sms_mode_bitmap;
99   // line_buffer will be used to hold 4 lines of line data as a kind of cache for
100   // vertical scaling in the gamegear sms compatibility mode.
101   int *m_line_buffer;
102
96103   // for 3D glass binocular hack
97104   bitmap_rgb32 m_prevleft_bitmap;
98105   bitmap_rgb32 m_prevright_bitmap;
r242550r242551
168175   DECLARE_MACHINE_START(sms);
169176   DECLARE_MACHINE_RESET(sms);
170177   DECLARE_VIDEO_START(gamegear);
178   DECLARE_VIDEO_RESET(gamegear);
171179   DECLARE_VIDEO_START(sms1);
172180   DECLARE_VIDEO_RESET(sms1);
181   void screen_gg_sms_mode_scaling(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
173182   UINT32 screen_update_gamegear(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
174183   UINT32 screen_update_sms(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
175184   UINT32 screen_update_sms1(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
trunk/src/mess/machine/sms.c
r242550r242551
11861186
11871187VIDEO_START_MEMBER(sms_state,gamegear)
11881188{
1189   m_prev_bitmap_copied = false;
11891190   m_main_scr->register_screen_bitmap(m_prev_bitmap);
1191   m_main_scr->register_screen_bitmap(m_gg_sms_mode_bitmap);
1192   m_line_buffer = auto_alloc_array(machine(), int, 160 * 4);
1193
1194   save_item(NAME(m_prev_bitmap_copied));
11901195   save_item(NAME(m_prev_bitmap));
1196   save_item(NAME(m_gg_sms_mode_bitmap));
1197   save_pointer(NAME(m_line_buffer), 160 * 4);
11911198}
11921199
1193UINT32 sms_state::screen_update_gamegear(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
1200VIDEO_RESET_MEMBER(sms_state,gamegear)
11941201{
1195   int x, y;
1202   if (m_prev_bitmap_copied)
1203   {
1204      m_prev_bitmap.fill(rgb_t::black);
1205      m_prev_bitmap_copied = false;
1206   }
1207   if (m_cartslot->exists() && m_cartslot->m_cart->get_sms_mode())
1208   {
1209      m_gg_sms_mode_bitmap.fill(rgb_t::black);
1210      memset(m_line_buffer, 0, 160 * 4 * sizeof(int));
1211   }
1212}
1213
1214
1215void sms_state::screen_gg_sms_mode_scaling(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
1216{
11961217   bitmap_rgb32 &vdp_bitmap = m_vdp->get_bitmap();
1197   static bool prev_bitmap_copied = false;
1218   const rectangle visarea = screen.visible_area();
11981219
1220   /* Plot positions relative to visarea minimum values */
1221   const int plot_min_x = cliprect.min_x - visarea.min_x;
1222   const int plot_max_x = MIN(cliprect.max_x - visarea.min_x, 159); // avoid m_line_buffer overflow.
1223   const int plot_min_y = cliprect.min_y - visarea.min_y;
1224   const int plot_max_y = cliprect.max_y - visarea.min_y;
1225
1226   /* For each group of 3 SMS pixels, a group of 2 GG pixels is processed.
1227      In case the cliprect coordinates may map any region of the visible area,
1228      take in account the remaining position, if any, of the first group. */
1229   const int plot_x_first_group = plot_min_x - (plot_min_x % 2);
1230   const int plot_y_first_group = plot_min_y - (plot_min_y % 2);
1231
1232   /* Calculation of the minimum scaled value for X */
1233   const int visarea_xcenter = visarea.xcenter();
1234   const int sms_offset_min_x = ((int) (visarea_xcenter - cliprect.min_x) / 2) * 3;
1235   const int sms_min_x = visarea_xcenter - sms_offset_min_x;
1236
1237   /* Calculation of the minimum scaled value for Y */
1238   const int visarea_ycenter = visarea.ycenter();
1239   const int sms_offset_min_y = ((int) (visarea_ycenter - cliprect.min_y) / 2) * 3;
1240   const int sms_min_y = visarea_ycenter - sms_offset_min_y;
1241
1242   int sms_y = sms_min_y;
1243   int plot_y_group = plot_y_first_group;
1244
1245   /* Auxiliary variable for vertical scaling */
1246   int sms_y2 = sms_y - 1;
1247
1248   for (int plot_y = plot_min_y; plot_y <= plot_max_y;)
1249   {
1250      for (int i = (plot_y - plot_y_group); i <= MIN(1, plot_max_y - plot_y_group); i++)
1251      {
1252         /* Include additional lines that have influence over what appears on the LCD */
1253         const int sms_min_y2 = sms_y + i - 1;
1254         const int sms_max_y2 = sms_y + i + 2;
1255
1256         /* Process lines, but skip those already processed before */
1257         for (sms_y2 = MAX(sms_min_y2, sms_y2); sms_y2 <= sms_max_y2; sms_y2++)
1258         {
1259            int *combineline_buffer =  m_line_buffer + (sms_y2 & 0x03) * 160;
1260
1261            if (sms_y2 >= vdp_bitmap.cliprect().min_y && sms_y2 <= vdp_bitmap.cliprect().max_y)
1262            {
1263               UINT32 *vdp_buffer =  &vdp_bitmap.pix32(sms_y2);
1264
1265               int sms_x = sms_min_x;
1266               int plot_x_group = plot_x_first_group;
1267
1268               /* Do horizontal scaling */
1269               for (int plot_x = plot_min_x; plot_x <= plot_max_x;)
1270               {
1271                   for (int j = (plot_x - plot_x_group); j <= MIN(1, plot_max_x - plot_x_group); j++)
1272                  {
1273                     if (sms_x + j >= vdp_bitmap.cliprect().min_x && sms_x + j + 1 <= vdp_bitmap.cliprect().max_x)
1274                     {
1275                        int combined;
1276
1277                        switch (j)
1278                        {
1279                        case 0:
1280                           /* Take red and green from first pixel, and blue from second pixel */
1281                           combined = (vdp_buffer[sms_x] & 0x00ffff00) | (vdp_buffer[sms_x + 1] & 0x000000ff);
1282                           combineline_buffer[plot_x] = combined;
1283                           break;
1284                        case 1:
1285                           /* Take red from second pixel, and green and blue from third pixel */
1286                           combined = (vdp_buffer[sms_x + 1] & 0x00ff0000) | (vdp_buffer[sms_x + 2] & 0x0000ffff);
1287                           combineline_buffer[plot_x + 1] = combined;
1288                           break;
1289                        }
1290                     }
1291                     else
1292                     {
1293                        combineline_buffer[plot_x + j] = 0;
1294                     }
1295                  }
1296                  sms_x += 3;
1297                  plot_x += 2 - (plot_x - plot_x_group);
1298                  plot_x_group = plot_x;
1299               }
1300            }
1301            else
1302            {
1303               memset(combineline_buffer, 0, 160 * sizeof(int));
1304            }
1305         }
1306
1307         /* Do vertical scaling for a screen with 192 or 224 lines
1308            Lines 0-2 and 221-223 have no effect on the output on the GG screen.
1309            We will calculate the gamegear lines as follows:
1310            GG_0 = 1/6 * SMS_3 + 1/3 * SMS_4 + 1/3 * SMS_5 + 1/6 * SMS_6
1311            GG_1 = 1/6 * SMS_4 + 1/3 * SMS_5 + 1/3 * SMS_6 + 1/6 * SMS_7
1312            GG_2 = 1/6 * SMS_6 + 1/3 * SMS_7 + 1/3 * SMS_8 + 1/6 * SMS_9
1313            GG_3 = 1/6 * SMS_7 + 1/3 * SMS_8 + 1/3 * SMS_9 + 1/6 * SMS_10
1314            GG_4 = 1/6 * SMS_9 + 1/3 * SMS_10 + 1/3 * SMS_11 + 1/6 * SMS_12
1315            .....
1316            GG_142 = 1/6 * SMS_216 + 1/3 * SMS_217 + 1/3 * SMS_218 + 1/6 * SMS_219
1317            GG_143 = 1/6 * SMS_217 + 1/3 * SMS_218 + 1/3 * SMS_219 + 1/6 * SMS_220
1318         */
1319         {
1320            int *line1, *line2, *line3, *line4;
1321
1322            /* Setup our source lines */
1323            line1 = m_line_buffer + ((sms_y + i - 1) & 0x03) * 160;
1324            line2 = m_line_buffer + ((sms_y + i - 0) & 0x03) * 160;
1325            line3 = m_line_buffer + ((sms_y + i + 1) & 0x03) * 160;
1326            line4 = m_line_buffer + ((sms_y + i + 2) & 0x03) * 160;
1327
1328            UINT32 *p_bitmap = &bitmap.pix32(visarea.min_y + plot_y + i, visarea.min_x);
1329
1330            for (int plot_x = plot_min_x; plot_x <= plot_max_x; plot_x++)
1331            {
1332               rgb_t   c1 = line1[plot_x];
1333               rgb_t   c2 = line2[plot_x];
1334               rgb_t   c3 = line3[plot_x];
1335               rgb_t   c4 = line4[plot_x];
1336               p_bitmap[plot_x] =
1337                  rgb_t( ( c1.r() / 6 + c2.r() / 3 + c3.r() / 3 + c4.r() / 6 ),
1338                         ( c1.g() / 6 + c2.g() / 3 + c3.g() / 3 + c4.g() / 6 ),
1339                         ( c1.b() / 6 + c2.b() / 3 + c3.b() / 3 + c4.b() / 6 ) );
1340            }
1341         }
1342      }
1343      sms_y += 3;
1344      plot_y += 2 - (plot_y - plot_y_group);
1345      plot_y_group = plot_y;
1346   }
1347}
1348
1349
1350UINT32 sms_state::screen_update_gamegear(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
1351{
1352   bitmap_rgb32 *source_bitmap;
1353
1354   if (m_cartslot->exists() && m_cartslot->m_cart->get_sms_mode())
1355   {
1356      screen_gg_sms_mode_scaling(screen, m_gg_sms_mode_bitmap, cliprect);
1357      source_bitmap = &m_gg_sms_mode_bitmap;
1358   }
1359   else
1360   {
1361      source_bitmap = &m_vdp->get_bitmap();
1362   }
1363
11991364   if (!m_port_persist->read())
12001365   {
1201      copybitmap(bitmap, vdp_bitmap, 0, 0, 0, 0, cliprect);
1202      if (prev_bitmap_copied)
1366      copybitmap(bitmap, *source_bitmap, 0, 0, 0, 0, cliprect);
1367      if (m_prev_bitmap_copied)
12031368      {
12041369         m_prev_bitmap.fill(rgb_t::black);
1205         prev_bitmap_copied = false;
1370         m_prev_bitmap_copied = false;
12061371      }
12071372   }
1208   else if (!prev_bitmap_copied)
1373   else if (!m_prev_bitmap_copied)
12091374   {
1210      copybitmap(bitmap, vdp_bitmap, 0, 0, 0, 0, cliprect);
1211      copybitmap(m_prev_bitmap, vdp_bitmap, 0, 0, 0, 0, cliprect);
1212      prev_bitmap_copied = true;
1375      copybitmap(bitmap, *source_bitmap, 0, 0, 0, 0, cliprect);
1376      copybitmap(m_prev_bitmap, *source_bitmap, 0, 0, 0, 0, cliprect);
1377      m_prev_bitmap_copied = true;
12131378   }
12141379   else
12151380   {
12161381      // HACK: fake LCD persistence effect
12171382      // (it would be better to generalize this in the core, to be used for all LCD systems)
1218      for (y = cliprect.min_y; y <= cliprect.max_y; y++)
1383      for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
12191384      {
12201385         UINT32 *linedst = &bitmap.pix32(y);
1221         UINT32 *line0 = &vdp_bitmap.pix32(y);
1386         UINT32 *line0 = &source_bitmap->pix32(y);
12221387         UINT32 *line1 = &m_prev_bitmap.pix32(y);
1223         for (x = cliprect.min_x; x <= cliprect.max_x; x++)
1388         for (int x = cliprect.min_x; x <= cliprect.max_x; x++)
12241389         {
12251390            UINT32 color0 = line0[x];
12261391            UINT32 color1 = line1[x];
r242550r242551
12361401            linedst[x] = (r << 16) | (g << 8) | b;
12371402         }
12381403      }
1239      copybitmap(m_prev_bitmap, vdp_bitmap, 0, 0, 0, 0, cliprect);
1404      copybitmap(m_prev_bitmap, *source_bitmap, 0, 0, 0, 0, cliprect);
12401405   }
12411406   return 0;
12421407}


Previous 199869 Revisions Next


© 1997-2024 The MAME Team