อุปกรณ์เช่น Game Boy Advance บรรลุอัตราเฟรมของพวกเขาอย่างไร


31

ฉันออกแบบอุปกรณ์เล่นเกมมือถือของฉันโดยใช้ไมโครคอนโทรลเลอร์ AVR และจอแสดงผล OLED ขนาดเล็ก

ฉันเริ่มด้วยหน้าจอขาวดำขนาด 128x64 พิกเซลและสามารถวาดได้อย่างสบาย ๆ ด้วยความเร็วมากกว่า 60 เฟรมต่อวินาที

เมื่อเร็ว ๆ นี้ฉันได้ทำการปรับปรุงใหม่เพื่อใช้ RGB OLED, 128x128 พิกเซลโดยไม่ต้องคิดมากเกินไปที่จะพบว่าฉันทำได้เพียงประมาณ 4 FPS หลังจากความคิดและการปรับโครงสร้างอย่างระมัดระวังฉันสามารถรับได้ถึง ~ 12fps หากฉันไม่สนใจทำสิ่งอื่นมากเกินไป!

คำถามของฉันคือ - อุปกรณ์อย่าง GBA (Game Boy Advance) บรรลุอัตราเฟรมที่เกือบ 60fps อย่างไร ฉันคิดว่าจะมี 'หน่วยประมวลผลกราฟิก' แยกจากกัน แต่รู้ว่าฉันจะยังคงได้รับคอขวดถ่ายโอนข้อมูลการแสดงผลไปยังที่

ฉันยังสงสัยเกี่ยวกับการใช้ส่วนต่อประสานแบบขนาน 8 บิตที่ส่วนใหญ่ของหน้าจอเหล่านี้มักจะมีซึ่งอาจทำให้ฉันเร็วขึ้น 8x ยกเว้นว่า MCUs ที่ทันสมัยไม่มีแนวโน้มที่จะมีอินเตอร์เฟซแบบขนานฮาร์ดแวร์เหมือนที่ทำสำหรับซีเรียลและบิต การต่อสู้มีแนวโน้มที่จะกินมากขึ้นของความเร็ว

ตัวเลือกอื่น ๆ ที่มีอยู่?

ปัจจุบันฉันใช้ ATmega1284P เชื่อมต่อกับคอนโทรลเลอร์ SSD1306 OLED ผ่าน USART-SPI นั่นคือรุ่นขาวดำ

หน้าจอสีเป็น SSD1351 ซึ่งเดิมไม่ได้เชื่อมต่อกับฮาร์ดแวร์ SPI ฉันไม่เชื่อว่ามันจะสร้างความแตกต่างมากพอมันเป็นเพียงภาพรวมช้าเกินไป

ฉันรู้ว่าฉันสามารถใช้งาน MCU ได้เร็วขึ้น แต่ฉันต้องการทราบตัวเลือกอื่น ๆ ที่ฉันสามารถสำรวจได้ - โปรเซสเซอร์ GBA ช้ากว่า 1284 ของฉันมาก!


6
"ฉันจะยังคงมีปัญหาคอขวดโอนข้อมูลการแสดงผลไปยังที่นั้น" DSI มีสี่เลนแต่ละช่องมากถึง 1.2Gbits / วินาที ฉันปล่อยให้การคำนวณที่เหลืออยู่กับคุณ
Oldfart

1
เช่นเดียวกับกราฟิกใด ๆ ในอุปกรณ์วิดีโอเกมใด ๆ มีหน่วยความจำที่จะจัดการกับกราฟิก ตามที่เว็บไซต์นี้มีที่อยู่สำหรับกราฟิกเสียง ฯลฯ คำแนะนำจะถูกเก็บไว้ที่นั่น สมมติว่ามีข้อมูลไม่มากที่จะสร้างความขัดแย้งกับเวลาในการปฏิบัติงานมันจะเรียกใช้คำแนะนำเหล่านั้นเพื่อโหลดข้อมูลกราฟิกอย่างง่ายดาย
KingDuken

5
buy the display without the controller on it and make your own controller
old_timer

4
@immibis: Almost surely some awful I2C- or SPI-based controller. Hobbyist stuff is full of overpriced slow stuff like that when you can get a friggin' 400+ dpi iPhone screen for $20 because of economies of scale.
R..

6
@R.. I just want to point out that the reason for these hobbyist controllers is so that they can interface to almost any processor, since you make it sound like they're useless. You wouldn't be able to interface to an iPhone screen easily, if at all. It probably connects to a dedicated and maybe custom graphics processor.
user253751

คำตอบ:


64

Other answers cover your question pretty well at an abstract level (hardware), but having actual experience with the GBA in particular I figured a more detailed explanation may be worth while.

The GBA had many drawing modes and settings which could be used to control how the graphics processor interpreted the video RAM, but one thing was inescapable: the frame rate. The graphic processor was drawing to the screen in a nearly (more on this below) constant loop. (This is likely the most relevant bit for your question.)

It would draw one line at a time taking a very short break between each. After drawing the last line for the frame it would take a break roughly equal to the time it takes to draw 30 lines. Then start again. The timing of each line, and the timing of each frame were all predetermined and set in stone. In a lot of ways the graphics processor was really the master of that system and you needed to write your games around its behavior, because it would continue doing what it did whether you were ready or not.

Roughly 75-80% of the time it was actively pushing to the screen. What frame rates could you accomplish if you were doing the same?

That 80% of the time was also what the CPU had to process user input, calculate game state, and load sprites/tiles to areas of VRAM that were currently off screen (or at least not included in the current line being drawn).

The 20% between frames, was all the CPU had to tweak video settings or RAM that would impact the whole next frame.

At the end of each line, the graphics processor would send a line sync interrupt to the CPU. This interrupt could be used to tweak settings on a few sprites, or a few background layers (this is how you can get an effect like a conical spotlight, by changing the size and location of one of the rectangular masks between each line drawn. As far as the hardware is concerned all those regions are rectangular.). You have to be careful to keep these updates small and finish before the graphic processor starts drawing the next line or you can get ugly results. Any time spent processing these interrupts also cut into that 80% of the CPU's processing time...

For games that got the most out of this system, neither the CPU nor the graphic processor ever took a real break; each were chasing the other around the loop updating what the other wasn't currently looking at.


5
Welcome and well put.
Mindwin

2
Some "newer" systems like the Nintendo DS got around the fixed framerate limitation by adding the VCOUNT register to delay the next frame for a configurable amount of time (usually to help multiplayer games synchronize).
forest

21

The key feature of all the games consoles that distinguished them from early PCs and virtually all home computers(1) was hardware sprites.

The linked GBA programming guide shows how they work from the main processor point of view. Bitmaps representing player, background, enemies etc are loaded into one area of memory. Another area of memory specifies the location of the sprites. So instead of having to re-write all of video RAM every frame, which takes a lot of instructions, the processor just has to update the location of the sprites.

The video processor can then work pixel by pixel to determine which sprite to draw at that point.

However, this requires dual-port RAM shared between the two, and I think in the GBA the video processor is on the same chip as the main ARM and secondary Z80 processor.

(1) Notable exception: Amiga


Only a nit -- the really early arcade games had the sprites in a ROM associated with the graphics processor, not a dual-port RAM. I have no clue if that was also the case with the early consoles, although it certainly could have been done that way.
TimWescott

@TimWescott the GBA did have multiple drawing modes and I don't have experience with most so this may not be universally true but, I don't think any of those modes had direct access to the ROMs(on cartridge): Typically all the tile/sprite/palette data had to be transferred from the ROM to the video memory and the graphics processor worked on it from there.
Mr.Mindor

@Mr.Mindor Sorry if I wasn't clear -- I'm not pretending to knowledge about how the GB or GBA did it. I was just commenting on the really early Nintendo arcade games back in the late 70's and early 80's, that had all of us wondering how in h*** they did that.
TimWescott

@TimWescott: I think the same was true of the NES, though the ROM in question was located within the Game Paks.
supercat

19

"My question is - how did a device like the GBA achieve a frame rate of nearly 60fps?"

To answer just the question, they did it with a graphics processer. I'm pretty sure the Game Boy used sprite graphics. At a top level, that means that the graphics processor gets loaded things like an image of a background, and an image of Mario, and an image of Princess Peach, etc. Then the main processor issues commands like "show the background offset by this much in x and y, overlay Mario image #3 at this x, y position", etc. So the main processor is absolutely positively not concerned with drawing each pixel, and the graphics processor is absolutely positively not concerned with computing the state of the game. Each is optimized for what it needs to do, and the result is a pretty good video game without using a lot of computation power.


7
Calling it a "graphics processor" exaggerates what it does, suggesting it's some sort of CPU of it's own. It's just a video controller, which is basically a complicated kind of sequencer. As it counts up horizontal and vertical pixels, it fetches title and/or sprite data, put them in shift registers, and combines the output of the shift registers into an output pixel. It's not capable of running a program like an actual "GPU" graphics processor.
Ross Ridge

14

The GBA had a pretty slow processor. The ARM7 is very nice; they just ran it slow and gave it next to no resources.

There is a reason why a lot of Nintendo games at that point and before were side-scrollers. HARDWARE. It is all done in hardware. You had multiple layers of tiles plus one or more sprites and the hardware did all the work to extract pixels from those tables and drive the display.

You build the tile set up front and then had a smallish memory that was a tile map. Want the lower left tile to be tile 7? You put a 7 in that memory location. Want the next tile over to be tile 19? In the tile set, you put a 19 there, and so on for each layer that you have enabled. For the sprite, you simply set the x/y address. You can also do scaling and rotation by setting some registers and the hardware takes care of the rest.

Mode 7, if I remember right, was a pixel mode, but that was like a traditional video card where you put bytes in that cover the color for a pixel and the hardware takes care of the video refresh. I think you could ping pong or at least when you had a new frame you could flip them, but I don't remember right. Again, the processor was fairly underclocked for that day and age and didn't have too many fast resources. So while some games were mode 7, a lot were tile based side-scrollers...

If you want a solution that is a high frame rate, you need to design that solution. You can't just take any old display you find and talk to it via SPI or I²C or something like that. Put at least one framebuffer in front of it, ideally two, and have row and column control if possible over that display.

A number of the displays I suspect you are buying have a controller on them that you are actually talking to. If you want GBA/console type performance you create/implement the controller. Or you buy/build with a GPU/video chip/logic blob, and use HDMI or other common interface into a stock monitor.

Just because a bicycle has tires and a chain and gears doesn't mean it can go as fast as a motorcycle. You need to design the system to meet your performance needs, end to end. You can put that bicycle wheel on that motorcycle, but it won't perform as desired; all of the components have to be part of the overall design.

Asteroids worked this way too; it only needed one 6502. The vector graphics were done with separate logic; the 6502 sent a tiny string of data to the vector graphics controller, which used a ROM and that data to do the xy plotting of the beam and z, on/off... Some standups had separate processors to handle audio and video separate from the processor computing the game. Of course today the video is handled by some hundreds, if not thousands, of processors that are separate from the main processor...


I swear I remember mode7 being shoehorned by marketing as a response to Sega's "hyper mode" or something... maybe "Super FX?" en.wikipedia.org/wiki/Mode_7
Caleb Jay

coranac.com/tonc/text/bitmaps.htm#sec-modes I may have remembered it wrong I am thinking of maybe mode 5, or one of the bitmap modes, there are some tile modes with sprites and bitmap/framebuffer mode or modes. maybe there is a 7. didnt know about the one you linked but that is good to know.
old_timer

hmm reading more on mode 7 and its not just a mode. Anyway the GBA has tile modes and bitmap modes which are slower as you have to be responsible for every pixel where the tile modes one byte in the tile map produces many pixels. They also leveraged the size of the busses (width) and speed of the memory, and a rom pipeline cache thing to help get stuff (instructions) out of the rom a bit faster. But from day one you were struggling to get software to run at a decent rate and thankfully the logic took care of most of the video work.
old_timer

if you look at these displays that you are buying that have these parallel 8 bit or 4 bit or spi or i2c interfaces those are in your way for performance, you want the raw display without those controllers and then you can control how the display is managed, build a framebuffer or two so you can ping/pong and a fast interface from your cpu to the framebuffer. assuming you start with a fast enough display in the first place.
old_timer

7

how did a device like the GBA achieve a frame rate of nearly 60fps?

Hardware.

It's got graphics memory, which may or may not share the same bus as program/data memory... but the important bit is that it has a graphics processor which reads the memory 60 times per second and sends the data to the LCD using an optimized interface which is designed to do this efficiently.

You can do the same with any modern microcontroller equipped with a "LCD interface" peripheral, for example the LPC4330 although this might be way overkill. Of course you will need a compatible LCD panel.

With modern fast microcontrollers (ie, ARM not AVR) and such a tiny screen, you probably won't need sprites or a blitter to accelerate graphics operations. With a 8-bit AVR it might be slow.

But no matter the cpu, bit banging the interface to the display is going to suck.

I believe the Atari 2600 used CPU bit-banging to send the picture to the TV. That's a little bit obsolete.


Even the 2600 had hardware sprites, although a very limited number (two players and two bullets I think)
pjc50

2
@pjc50, the Atari 2600 sort of had hardware sprites. Like every other part of the graphics subsystem, they were one-dimensional objects. If the programmer wanted something other than a set of vertical lines, the program needed to update the sprites after each row was drawn to the screen.
Mark

1
@Mark: The 2600 definitely had hardware sprites. The hardware only controlled horizontal positioning, but the sprites on the 2600 made it possible for games to produce games that were far more colorful than any of its competitors.
supercat
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.