1 //////////////////////////////////////////////////////////////////////////////////////// 2 // 3 // Nestopia - NES/Famicom emulator written in C++ 4 // 5 // Copyright (C) 2003-2008 Martin Freij 6 // 7 // This file is part of Nestopia. 8 // 9 // Nestopia is free software; you can redistribute it and/or modify 10 // it under the terms of the GNU General Public License as published by 11 // the Free Software Foundation; either version 2 of the License, or 12 // (at your option) any later version. 13 // 14 // Nestopia is distributed in the hope that it will be useful, 15 // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 // GNU General Public License for more details. 18 // 19 // You should have received a copy of the GNU General Public License 20 // along with Nestopia; if not, write to the Free Software 21 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 // 23 //////////////////////////////////////////////////////////////////////////////////////// 24 25 #ifndef NST_API_VIDEO_H 26 #define NST_API_VIDEO_H 27 28 #include "NstApi.hpp" 29 30 #ifdef NST_PRAGMA_ONCE 31 #pragma once 32 #endif 33 34 #if NST_ICC >= 810 35 #pragma warning( push ) 36 #pragma warning( disable : 304 444 ) 37 #elif NST_MSVC >= 1200 38 #pragma warning( push ) 39 #pragma warning( disable : 4512 ) 40 #endif 41 42 namespace Nes 43 { 44 namespace Core 45 { 46 namespace Video 47 { 48 /** 49 * Video output context. 50 */ 51 class Output 52 { 53 struct Locker; 54 struct Unlocker; 55 56 public: 57 58 enum 59 { 60 WIDTH = 256, 61 HEIGHT = 240, 62 NTSC_WIDTH = 602 63 }; 64 65 /** 66 * Pointer to surface memory to be written to. Size must be equal to 67 * or greater than bitsPerPixel/8 * NES screen width * NES screen height. 68 */ 69 void* pixels; 70 71 /** 72 * Distance in bytes for each line in the surface memory. 73 * Must be equal to or greater than the actual NES screen width. 74 * Value is allowed to be negative. 75 */ 76 long pitch; 77 Output(void * v=0,long p=0)78 Output(void* v=0,long p=0) 79 : pixels(v), pitch(p) {} 80 81 /** 82 * Surface lock callback prototype. 83 * 84 * Called right before the core is about to render to the surface. 85 * 86 * @param userData optional user data 87 * @param output object to this class 88 * @return true if surface is valid and can be written to 89 */ 90 typedef bool (NST_CALLBACK *LockCallback) (void* userData,Output& output); 91 92 /** 93 * Surface unlock callback prototype. 94 * 95 * Called when the core has finished rendering to the surface and a previous locked was made. 96 * 97 * @param userData optional user data 98 * @param output object to this class 99 */ 100 typedef void (NST_CALLBACK *UnlockCallback) (void* userData,Output& output); 101 102 /** 103 * Surface lock callback manager. 104 * 105 * Static object used for adding the user defined callback. 106 */ 107 static Locker lockCallback; 108 109 /** 110 * Surface unlock callback manager. 111 * 112 * Static object used for adding the user defined callback. 113 */ 114 static Unlocker unlockCallback; 115 }; 116 117 /** 118 * Surface lock callback invoker. 119 * 120 * Used internally by the core. 121 */ 122 struct Output::Locker : UserCallback<Output::LockCallback> 123 { operator ()Nes::Core::Video::Output::Locker124 bool operator () (Output& output) const 125 { 126 return (!function || function( userdata, output )) && output.pixels && output.pitch; 127 } 128 }; 129 130 /** 131 * Surface unlock callback invoker. 132 * 133 * Used internally by the core. 134 */ 135 struct Output::Unlocker : UserCallback<Output::UnlockCallback> 136 { operator ()Nes::Core::Video::Output::Unlocker137 void operator () (Output& output) const 138 { 139 if (function) 140 function( userdata, output ); 141 } 142 }; 143 } 144 } 145 146 namespace Api 147 { 148 /** 149 * Video interface. 150 */ 151 class Video : public Base 152 { 153 public: 154 155 /** 156 * Interface constructor. 157 * 158 * @param instance emulator instance 159 */ 160 template<typename T> Video(T & instance)161 Video(T& instance) 162 : Base(instance) {} 163 164 /** 165 * Video output context. 166 */ 167 typedef Core::Video::Output Output; 168 169 enum 170 { 171 MIN_BRIGHTNESS = -100, 172 DEFAULT_BRIGHTNESS = 0, 173 MAX_BRIGHTNESS = +100, 174 MIN_SATURATION = -100, 175 DEFAULT_SATURATION = 0, 176 DEFAULT_SATURATION_COMP = 0, 177 DEFAULT_SATURATION_SVIDEO = 0, 178 DEFAULT_SATURATION_RGB = 0, 179 DEFAULT_SATURATION_MONO = -100, 180 MAX_SATURATION = +100, 181 MIN_CONTRAST = -100, 182 DEFAULT_CONTRAST = 0, 183 MAX_CONTRAST = +100, 184 MIN_SHARPNESS = -100, 185 DEFAULT_SHARPNESS_COMP = 0, 186 DEFAULT_SHARPNESS_SVIDEO = 20, 187 DEFAULT_SHARPNESS_RGB = 20, 188 DEFAULT_SHARPNESS_MONO = 0, 189 MAX_SHARPNESS = +100, 190 MIN_COLOR_RESOLUTION = -100, 191 DEFAULT_COLOR_RESOLUTION_COMP = 0, 192 DEFAULT_COLOR_RESOLUTION_SVIDEO = 20, 193 DEFAULT_COLOR_RESOLUTION_RGB = 70, 194 DEFAULT_COLOR_RESOLUTION_MONO = 0, 195 MAX_COLOR_RESOLUTION = +100, 196 MIN_COLOR_BLEED = -100, 197 DEFAULT_COLOR_BLEED_COMP = 0, 198 DEFAULT_COLOR_BLEED_SVIDEO = 0, 199 DEFAULT_COLOR_BLEED_RGB = -100, 200 DEFAULT_COLOR_BLEED_MONO = 0, 201 MAX_COLOR_BLEED = +100, 202 MIN_COLOR_ARTIFACTS = -100, 203 DEFAULT_COLOR_ARTIFACTS_COMP = 0, 204 DEFAULT_COLOR_ARTIFACTS_SVIDEO = -100, 205 DEFAULT_COLOR_ARTIFACTS_RGB = -100, 206 DEFAULT_COLOR_ARTIFACTS_MONO = 5, 207 MAX_COLOR_ARTIFACTS = +100, 208 MIN_COLOR_FRINGING = -100, 209 DEFAULT_COLOR_FRINGING_COMP = 0, 210 DEFAULT_COLOR_FRINGING_SVIDEO = -100, 211 DEFAULT_COLOR_FRINGING_RGB = -100, 212 DEFAULT_COLOR_FRINGING_MONO = 5, 213 MAX_COLOR_FRINGING = +100, 214 MIN_HUE = -45, 215 DEFAULT_HUE = 0, 216 MAX_HUE = +45 217 }; 218 219 /** 220 * Allows the PPU to render more than eight sprites per line. 221 * 222 * @param state true to allow it, default is false 223 * @return result code 224 */ 225 Result EnableUnlimSprites(bool state) throw(); 226 227 /** 228 * Checks if the PPU sprite software extension is enabled. 229 * 230 * @return true if enabled 231 */ 232 bool AreUnlimSpritesEnabled() const throw(); 233 234 /** 235 * Returns the current brightness. 236 * 237 * @return brightness value in the range -100 to 100 238 */ 239 int GetBrightness() const throw(); 240 241 /** 242 * Returns the current saturation. 243 * 244 * @return saturation value in the range -100 to 100 245 */ 246 int GetSaturation() const throw(); 247 248 /** 249 * Returns the current contrast. 250 * 251 * @return contrast value in the range -100 to 100 252 */ 253 int GetContrast() const throw(); 254 255 /** 256 * Returns the current sharpness for the NTSC filter. 257 * 258 * @return sharpness value in the range -100 to 100 259 */ 260 int GetSharpness() const throw(); 261 262 /** 263 * Returns the current color resolution for the NTSC filter. 264 * 265 * @return color resolution value in the range -100 to 100 266 */ 267 int GetColorResolution() const throw(); 268 269 /** 270 * Returns the current color bleed for the NTSC filter. 271 * 272 * @return color bleed value in the range -100 to 100 273 */ 274 int GetColorBleed() const throw(); 275 276 /** 277 * Returns the current color artifacts for the NTSC filter. 278 * 279 * @return color artifacts value in the range -100 to 100 280 */ 281 int GetColorArtifacts() const throw(); 282 283 /** 284 * Returns the current color fringing for the NTSC filter. 285 * 286 * @return color fringing value in the range -100 to 100 287 */ 288 int GetColorFringing() const throw(); 289 290 /** 291 * Returns the current hue. 292 * 293 * @return hue value in the range -45 to 45 294 */ 295 int GetHue() const throw(); 296 297 /** 298 * Returns whenever the xbr filters blends pixels or not 299 */ 300 bool GetBlend() const throw(); 301 302 /** 303 * Returns how the xbr filters rounds corners 304 */ 305 int GetCornerRounding() const throw(); 306 307 /** 308 * Sets the brightness. 309 * 310 * @param value brightness in the range -100 to 100, default is 0 311 * @return result code 312 */ 313 Result SetBrightness(int value) throw(); 314 315 /** 316 * Sets the saturation. 317 * 318 * @param value saturation in the range -100 to 100, default is 0 319 * @return result code 320 */ 321 Result SetSaturation(int value) throw(); 322 323 /** 324 * Sets the contrast. 325 * 326 * @param value contrast in the range -100 to 100, default is 0 327 * @return result code 328 */ 329 Result SetContrast(int value) throw(); 330 331 /** 332 * Sets the sharpness for the NTSC filter. 333 * 334 * @param value sharpness in the range -100 to 100, default is 0 335 * @return result code 336 */ 337 Result SetSharpness(int value) throw(); 338 339 /** 340 * Sets the color resolution for the NTSC filter. 341 * 342 * @param value color resolution in the range -100 to 100, default is 0 343 * @return result code 344 */ 345 Result SetColorResolution(int value) throw(); 346 347 /** 348 * Sets the color bleed for the NTSC filter. 349 * 350 * @param value color bleed in the range -100 to 100, default is 0 351 * @return result code 352 */ 353 Result SetColorBleed(int value) throw(); 354 355 /** 356 * Sets the color artifacts for the NTSC filter. 357 * 358 * @param value color artifacts in the range -100 to 100, default is 0 359 * @return result code 360 */ 361 Result SetColorArtifacts(int value) throw(); 362 363 /** 364 * Sets the color fringing for the NTSC filter. 365 * 366 * @param value fringing in the range -100 to 100, default is 0 367 * @return result code 368 */ 369 Result SetColorFringing(int value) throw(); 370 371 /** 372 * Sets the hue. 373 * 374 * @param value hue in the range -45 to 45, default is 0 375 * @return result code 376 */ 377 Result SetHue(int value) throw(); 378 379 /** 380 * Sets whenever the xbr filters is to blend pixels or not. 381 */ 382 Result SetBlend(bool value) throw(); 383 384 /** 385 * Sets whenever the xbr filters is to round corners or not. 386 */ 387 Result SetCornerRounding(int value) throw(); 388 389 /** 390 * Quickfix for blank screen issue. 391 */ 392 void ClearFilterUpdateFlag() throw(); 393 394 /** 395 * Enables field merging for the NTSC filter. 396 * 397 * @param state true to enable 398 */ 399 void EnableFieldMerging(bool state) throw(); 400 401 /** 402 * Checks if NTSC filter field merging is enabled. 403 * 404 * @return true if enabled 405 */ 406 bool IsFieldMergingEnabled() const throw(); 407 408 /** 409 * Performs a manual blit to the video output object. 410 * 411 * The core calls this method internally for each frame. 412 * 413 * @param output video output object to blit to 414 * @return result code 415 */ 416 Result Blit(Output& output) throw(); 417 418 /** 419 * YUV decoder presets. 420 */ 421 enum DecoderPreset 422 { 423 /** 424 * Canonical (default) 425 */ 426 DECODER_CANONICAL, 427 /** 428 * Consumer 429 */ 430 DECODER_CONSUMER, 431 /** 432 * Alternative 433 */ 434 DECODER_ALTERNATIVE 435 }; 436 437 /** 438 * YUV decoder context. 439 */ 440 struct Decoder 441 { 442 /** 443 * Constructor. 444 * 445 * @param preset preset, canonical by default 446 */ 447 Decoder(DecoderPreset preset=DECODER_CANONICAL) throw(); 448 449 /** 450 * Tests for equality. 451 * 452 * @param decoder object to compare 453 * @return true if equal 454 */ 455 bool operator == (const Decoder& decoder) const throw(); 456 457 /** 458 * Tests for non-equality. 459 * 460 * @param decoder object to compare 461 * @return true if non-equal 462 */ 463 bool operator != (const Decoder& decoder) const throw(); 464 465 enum 466 { 467 AXIS_RY, 468 AXIS_GY, 469 AXIS_BY, 470 NUM_AXES 471 }; 472 473 struct 474 { 475 float gain; 476 uint angle; 477 } axes[NUM_AXES]; 478 479 bool boostYellow; 480 }; 481 482 /** 483 * Sets the YUV decoder. 484 * 485 * @param decoder decoder 486 * @return result code 487 */ 488 Result SetDecoder(const Decoder& decoder) throw(); 489 490 /** 491 * Returns the current YUV decoder. 492 * 493 * @return current decoder 494 */ 495 const Decoder& GetDecoder() const throw(); 496 497 /** 498 * Palette interface. 499 */ 500 class Palette 501 { 502 Core::Machine& emulator; 503 504 public: 505 506 /** 507 * Interface constructor 508 * 509 * @param instance emulator instance 510 */ Palette(Core::Machine & instance)511 Palette(Core::Machine& instance) 512 : emulator(instance) {} 513 514 enum 515 { 516 NUM_ENTRIES = 64, 517 NUM_ENTRIES_EXT = 512 518 }; 519 520 /** 521 * Custom palette types. 522 */ 523 enum CustomType 524 { 525 /** 526 * Standard palette. 64 colors. 527 */ 528 STD_PALETTE = NUM_ENTRIES, 529 /** 530 * Extended palette. 512 colors with emphasis included in it. 531 */ 532 EXT_PALETTE = NUM_ENTRIES_EXT 533 }; 534 535 /** 536 * Palette modes 537 */ 538 enum Mode 539 { 540 /** 541 * YUV (default) 542 */ 543 MODE_YUV, 544 /** 545 * RGB 546 */ 547 MODE_RGB, 548 /** 549 * Custom 550 */ 551 MODE_CUSTOM 552 }; 553 554 /** 555 * RGB colors. 556 */ 557 typedef const uchar (*Colors)[3]; 558 559 /** 560 * Returns the current palette mode. 561 * 562 * @return current mode 563 */ 564 Mode GetMode() const throw(); 565 566 /** 567 * Returns the default palette mode. 568 * 569 * @return default palette mode 570 */ 571 Mode GetDefaultMode() const throw(); 572 573 /** 574 * Sets the custom palette. 575 * 576 * @param colors RGB color data 577 * @param type custom palette type 578 */ 579 Result SetCustom(Colors colors,CustomType type=STD_PALETTE) throw(); 580 581 /** 582 * Returns the custom palette. 583 * 584 * @param colors RGB colors to be filled 585 * @param type custom palette type 586 * @return number of colors written 587 */ 588 uint GetCustom(uchar (*colors)[3],CustomType type) const throw(); 589 590 /** 591 * Resets the custom palette. 592 */ 593 void ResetCustom() throw(); 594 595 /** 596 * Returns the custom palette type. 597 * 598 * @return custom palette type 599 */ 600 CustomType GetCustomType() const throw(); 601 602 /** 603 * Return the current palette colors. 604 * 605 * @return palette colors 606 */ 607 Colors GetColors() const throw(); 608 609 /** 610 * Sets the palette mode. 611 * 612 * @param mode palette mode 613 * @return result code 614 */ 615 Result SetMode(Mode mode) throw(); 616 }; 617 618 /** 619 * Returns the palette interface. 620 * 621 * @return palette interface 622 */ GetPalette()623 Palette GetPalette() 624 { 625 return emulator; 626 } 627 628 /** 629 * Render state context. 630 */ 631 struct RenderState 632 { 633 RenderState() throw(); 634 635 /** 636 * Pixel context. 637 */ 638 struct Bits 639 { 640 /** 641 * RGB bit mask. 642 */ 643 struct Mask 644 { 645 ulong r,g,b; 646 }; 647 648 /** 649 * RGB bit mask. 650 */ 651 Mask mask; 652 653 /** 654 * Bits per pixel. 655 */ 656 uint count; 657 }; 658 659 /** 660 * Pixel context. 661 */ 662 Bits bits; 663 664 /** 665 * Screen width. 666 */ 667 ushort width; 668 669 /** 670 * Screen height. 671 */ 672 ushort height; 673 674 /** 675 * Video Filter. 676 */ 677 enum Filter 678 { 679 /** 680 * No filter (default). 681 */ 682 FILTER_NONE, 683 /** 684 * NTSC filter. 685 */ 686 FILTER_NTSC 687 #ifndef NST_NO_SCALEX 688 , 689 /** 690 * Scale2x filter. 691 */ 692 FILTER_SCALE2X, 693 /** 694 * Scale3x filter. 695 */ 696 FILTER_SCALE3X 697 #endif 698 #ifndef NST_NO_HQ2X 699 , 700 /** 701 * Hq2x filter. 702 */ 703 FILTER_HQ2X, 704 /** 705 * Hq3x filter. 706 */ 707 FILTER_HQ3X, 708 /** 709 * Hq4x filter. 710 */ 711 FILTER_HQ4X 712 #endif 713 #ifndef NST_NO_2XSAI 714 , 715 /** 716 * 2xSaI filter. 717 */ 718 FILTER_2XSAI 719 #endif 720 #ifndef NST_NO_XBR 721 , 722 FILTER_2XBR, 723 FILTER_3XBR, 724 FILTER_4XBR 725 #endif 726 }; 727 728 /** 729 * Scale factors. 730 */ 731 enum Scale 732 { 733 SCALE_NONE = 1 734 #ifndef NST_NO_SCALEX 735 ,SCALE_SCALE2X = 2 736 ,SCALE_SCALE3X = 3 737 #endif 738 #ifndef NST_NO_HQ2X 739 ,SCALE_HQ2X = 2 740 ,SCALE_HQ3X = 3 741 #endif 742 #ifndef NST_NO_2XSAI 743 ,SCALE_2XSAI = 2 744 #endif 745 }; 746 747 /** 748 * Filter. 749 */ 750 Filter filter; 751 }; 752 753 /** 754 * Sets the render state. 755 * 756 * @param state render state to be set 757 * @return result code 758 */ 759 Result SetRenderState(const RenderState& state) throw(); 760 761 /** 762 * Returns the current render state. 763 * 764 * @param state object to be filled 765 * @return result code 766 */ 767 Result GetRenderState(RenderState& state) const throw(); 768 }; 769 } 770 } 771 772 #if NST_MSVC >= 1200 || NST_ICC >= 810 773 #pragma warning( pop ) 774 #endif 775 776 #endif 777