From ee44f668eb52027c90d256ee76e9af3db6ce4741 Mon Sep 17 00:00:00 2001 From: Stefano Ceccherini Date: Mon, 26 Dec 2005 14:54:04 +0000 Subject: [PATCH] Added page_flipper as a test for BWindowScreen (thanks to Stephan for sending it to me) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15675 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/tests/kits/game/Jamfile | 1 + src/tests/kits/game/page_flipper/Jamfile | 7 + .../kits/game/page_flipper/page_flip.cpp | 227 ++++++++++++++++++ 3 files changed, 235 insertions(+) create mode 100644 src/tests/kits/game/page_flipper/Jamfile create mode 100644 src/tests/kits/game/page_flipper/page_flip.cpp diff --git a/src/tests/kits/game/Jamfile b/src/tests/kits/game/Jamfile index 0ccc72c97f..574aa046e8 100644 --- a/src/tests/kits/game/Jamfile +++ b/src/tests/kits/game/Jamfile @@ -5,3 +5,4 @@ SubInclude HAIKU_TOP src tests kits game set_mouse_position_test ; SubInclude HAIKU_TOP src tests kits game simple_game_sound_test ; SubInclude HAIKU_TOP src tests kits game direct_window_test ; SubInclude HAIKU_TOP src tests kits game direct_window_info_test ; +SubInclude HAIKU_TOP src tests kits game page_flipper ; diff --git a/src/tests/kits/game/page_flipper/Jamfile b/src/tests/kits/game/page_flipper/Jamfile new file mode 100644 index 0000000000..ae4308c1ca --- /dev/null +++ b/src/tests/kits/game/page_flipper/Jamfile @@ -0,0 +1,7 @@ +SubDir HAIKU_TOP src tests kits game page_flipper ; + +SimpleTest page_flipper + : page_flip.cpp + : game be root +; + diff --git a/src/tests/kits/game/page_flipper/page_flip.cpp b/src/tests/kits/game/page_flipper/page_flip.cpp new file mode 100644 index 0000000000..f5bacb7c02 --- /dev/null +++ b/src/tests/kits/game/page_flipper/page_flip.cpp @@ -0,0 +1,227 @@ +/* + Copyright 1999, Be Incorporated. All Rights Reserved. + This file may be used under the terms of the Be Sample Code License. +*/ + +#include +#include +#include +#include + +typedef long (*blit_hook)(long,long,long,long,long,long); +typedef long (*sync_hook)(); + +class NApplication:public BApplication { +public: + NApplication(); + bool is_quitting; // So that the WindowScreen knows what + // to do when disconnected. +private: + bool QuitRequested(); + void ReadyToRun(); +}; + +class NWindowScreen:public BWindowScreen { +public: + NWindowScreen(status_t*); +private: + void ScreenConnected(bool); + long MyCode(); + static long Entry(void*); + thread_id tid; + sem_id sem; + area_id area; + uint8* save_buffer; + uint8* frame_buffer; + ulong line_length; + bool thread_is_locked; // small hack to allow to quit the + // app from ScreenConnected() + blit_hook blit; // hooks to the graphics driver functions + sync_hook sync; +}; + +int main(int, char**) { + NApplication app; +} + +NApplication::NApplication() + :BApplication("application/x-vnd.Be-sample-jbq1") { + Run(); // see you in ReadyToRun() +} + +void NApplication::ReadyToRun() { + status_t ret=B_ERROR; + is_quitting=false; + NWindowScreen* ws=new NWindowScreen(&ret); +// exit if constructing the WindowScreen failed. + if ((ws==NULL)||(retPostMessage(B_QUIT_REQUESTED); + return; + } +// get the hardware acceleration hooks. get them each time +// the WindowScreen is connected, because of multiple +// monitor support + blit=(blit_hook)CardHookAt(7); + sync=(sync_hook)CardHookAt(10); +// cannot work with no hardware blitting + if (blit==NULL) { + be_app->PostMessage(B_QUIT_REQUESTED); + return; + } +// get the framebuffer-related info, each time the +// WindowScreen is connected (multiple monitor) + frame_buffer=(uint8*)(CardInfo()->frame_buffer); + line_length=FrameBufferInfo()->bytes_per_row; + if (tid==0) { +// clean the framebuffer + memset(frame_buffer,0,2048*line_length); +// spawn the rendering thread. exit if an error occurs. + if (((tid=spawn_thread(Entry,"rendering thread", + B_URGENT_DISPLAY_PRIORITY,this))PostMessage(B_QUIT_REQUESTED); + } else for (int y=0;y<2048;y++) +// restore the framebuffer when switching back from +// another workspace. + memcpy(frame_buffer+y*line_length, + save_buffer+640*y,640); +// set our color list. + rgb_color palette[256]; + for (int i=0;i<128;i++) { + rgb_color c1={i*2,i*2,i*2}; + rgb_color c2={127+i,2*i,254}; + palette[i]=c1; + palette[i+128]=c2; + } + SetColorList(palette); +// allow the rendering thread to run. + thread_is_locked=false; + release_sem(sem); + } else { +// block the rendering thread. + if (!thread_is_locked) { + acquire_sem(sem); + thread_is_locked=true; + } +// kill the rendering and clean up when quitting + if ((((NApplication*)be_app)->is_quitting)) { + status_t ret; + kill_thread(tid); + wait_for_thread(tid,&ret); + delete_sem(sem); + delete_area(area); + } else { +// set the color list black so that the screen doesn't seem +// to freeze while saving the framebuffer + rgb_color c={0,0,0}; + rgb_color palette[256]; + for (int i=0;i<256;i++) + palette[i]=c; + SetColorList(palette); + +// save the framebuffer + for (int y=0;y<2048;y++) + memcpy(save_buffer+640*y, + frame_buffer+y*line_length,640); + } + } +} + +long NWindowScreen::Entry(void* p) { + return ((NWindowScreen*)p)->MyCode(); +} + +long NWindowScreen::MyCode() { +// gain access to the framebuffer before writing to it. + + acquire_sem(sem); + + for (int j=1440;j<2048;j++) { + for (int i=0;i<640;i++) { +// draw the backgroud ripple pattern + float val=63.99*(1+cos(2*M_PI*((i-320)*(i-320) + +(j-1744)*(j-1744))/1216)); + frame_buffer[i+line_length*j]=int(val); + } + } + ulong numframe=0; + bigtime_t trgt=0; + ulong y_origin; + uint8* current_frame; + while(true) { +// the framebuffer coordinates of the next frame + y_origin=480*(numframe%3); +// and a pointer to it + current_frame=frame_buffer+y_origin*line_length; +// copy the background + int ytop=numframe%608,ybot=ytop+479; + if (ybot<608) { + blit(0,1440+ytop,0,y_origin,639,479); + } else { + blit(0,1440+ytop,0,y_origin,639,1086-ybot); + blit(0,1440,0,y_origin+1087-ybot,639,ybot-608); + } +// calculate the circle position. doing such calculations +// between blit() and sync() is a good idea. + uint32 x=(uint32)(287.99*(1+sin(numframe/72.))); + uint32 y=(uint32)(207.99*(1+sin(numframe/52.))); + if (sync) sync(); +// draw the circle + for (int j=0;j<64;j++) { + for (int i=0;i<64;i++) { + if ((i-31)*(i-32)+(j-31)*(j-32)<=1024) + current_frame[x+i+line_length*(y+j)]+=128; + } + } +// release the semaphore while waiting. gotta release it +// at some point or nasty things will happen! + release_sem(sem); +// try to sync with the vertical retrace + if (BScreen(this).WaitForRetrace()!=B_OK) { +// we're doing some triple buffering. unwanted things would +// happen if we rendered more pictures than the card can +// display. we here make sure not to render more than 55.5 +// pictures per second if the card does not support retrace +// syncing + if (system_time()