diff --git a/src/apps/Jamfile b/src/apps/Jamfile index 6b72fb40fb..e2114f3240 100644 --- a/src/apps/Jamfile +++ b/src/apps/Jamfile @@ -15,6 +15,7 @@ SubInclude HAIKU_TOP src apps icon-o-matic ; SubInclude HAIKU_TOP src apps installer ; SubInclude HAIKU_TOP src apps magnify ; SubInclude HAIKU_TOP src apps mail ; +SubInclude HAIKU_TOP src apps mandelbrot ; SubInclude HAIKU_TOP src apps mediaplayer ; SubInclude HAIKU_TOP src apps midiplayer ; SubInclude HAIKU_TOP src apps networkstatus ; diff --git a/src/apps/mandelbrot/Jamfile b/src/apps/mandelbrot/Jamfile new file mode 100644 index 0000000000..2f14c9f517 --- /dev/null +++ b/src/apps/mandelbrot/Jamfile @@ -0,0 +1,11 @@ +SubDir HAIKU_TOP src apps mandelbrot ; + +SetSubDirSupportedPlatformsBeOSCompatible ; +AddSubDirSupportedPlatforms libbe_test ; + +Application Mandelbrot : + main.cpp + tsb.cpp + : be + : Mandelbrot.rdef ; + diff --git a/src/apps/mandelbrot/LICENSE b/src/apps/mandelbrot/LICENSE new file mode 100644 index 0000000000..86a4268fa9 --- /dev/null +++ b/src/apps/mandelbrot/LICENSE @@ -0,0 +1,31 @@ +---------------------- +Be Sample Code License +---------------------- + +Copyright 1991-1999, Be Incorporated. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions, and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions, and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/apps/mandelbrot/Mandelbrot.rdef b/src/apps/mandelbrot/Mandelbrot.rdef new file mode 100644 index 0000000000..1488304f28 --- /dev/null +++ b/src/apps/mandelbrot/Mandelbrot.rdef @@ -0,0 +1,60 @@ +resource large_icon +{ + $"FFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFF001B1C1B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FF003F1B1C1B1C1C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FF0015153F1B1C1B1C1C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FF00150A16153F3F1B1C1B1C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FF00150A0B0B15153F1B1C1B1C1C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FF00150A0B000B0A16153F1B1C1B1C1C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FF00150A0B0000000B0A16153F3F1B1C1B1C0000FFFFFFFFFFFFFFFFFFFFFFFF" + $"FF00150A0B00000000000B0A16153F3F1B1C1B1C0000FFFFFFFFFFFFFFFFFFFF" + $"FF00150A0B000000000000000B0A16153F3F1B1C1B1C0000FFFFFFFFFFFFFFFF" + $"FF00150A0B000000000000FC3E920A0B15153F3F1B1C1B3F00FFFFFFFFFFFFFF" + $"FF00150A0B0000000000FC0000FC3E670A0B15163F3F3F0E00FFFFFFFFFFFFFF" + $"FF00150A0B000000000000000000007494730B0B15150F0F00FFFFFFFFFFFFFF" + $"FF00150A0B0000000000000000000043FC743E1B16150F0F29FFFFFFFFFFFFFF" + $"FF00150A0B0000FC0000000000000000FC943E1B16150F0F29FFFFFFFFFFFFFF" + $"FF00150A0B0069FC00000000000000006F94941C15150F0F00FFFFFFFFFFFFFF" + $"FF00150A0BFC3EFE000000000000000094736D1C15150F0F00FFFFFFFFFFFFFF" + $"FF00150A0B3E5E4300000000000000FCFC3E5E4116150F0F01FFFFFFFFFFFFFF" + $"FF00150A0B7394FCFC0000000000000000947E4116150F0F01FFFFFFFFFFFFFF" + $"FF00150A0B6D7394FCFC000000FCFC0000747E4116150F0F01FFFFFFFFFFFFFF" + $"FF00150A0B1C6D6E693EFEFC946E3EFE6994FC1B15160F0E00FFFFFFFFFFFFFF" + $"FF0015150B1B1C1C6D737494947394949473944682140F0F00FFFFFFFFFFFFFF" + $"FF11000015151C1B1C1C3EFEFC6D6D6D6D6D941C15150F0F00FFFFFFFFFFFFFF" + $"FFFF1111000015151C1B1C1C6D6D6D6D6D6D3E1C1516AE1000FFFFFFFFFFFFFF" + $"FFFFFFFF1111000015151C1B1C1C67676D6D731C15150F0F001111FFFFFFFFFF" + $"FFFFFFFFFFFF1111000015151C1B1C1C6D6D6E1C15150F0F0011111111FFFFFF" + $"FFFFFFFFFFFFFFFF1111000015151C1B1C1CFC1B15160F0E00111111111111FF" + $"FFFFFFFFFFFFFFFFFFFF1111000015151C1B1C1C15150F0F001111111111FFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFF1111000015151C1B16150F0F0011111111FFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFF11110000151515160E0F00111111FFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1111000015150F00111111FFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1111000000111111FFFFFFFFFFFF" +}; + +resource mini_icon +{ + $"FF000000FFFFFFFFFFFFFFFFFFFFFFFF" + $"00151B1C0000FFFFFFFFFFFFFFFFFFFF" + $"00150A161B1C0000FFFFFFFFFFFFFFFF" + $"00150A000B151C1C0000FFFFFFFFFFFF" + $"00150A0000000B151C1C0000FFFFFFFF" + $"00150A000000FC0A0B151C0F00FFFFFF" + $"00150A0000FC00FC940A160E00FFFFFF" + $"00150A0000000000941C150F00FFFFFF" + $"00150A00FC000000FC1B150F00FFFFFF" + $"00150A9494FC00FC001B150F00FFFFFF" + $"00150A1C1C9494FCFC1B150F00FFFFFF" + $"11000015151C1B6D6D1C150F00FFFFFF" + $"FFFF11000015151C1B1C150F001111FF" + $"FFFFFFFF11000015151C150F00111111" + $"FFFFFFFFFFFF11000015150F001111FF" + $"FFFFFFFFFFFFFFFF110000001111FFFF" +}; + +resource app_signature "application/x-vnd.Be-MAND"; + +resource app_flags B_MULTIPLE_LAUNCH; + diff --git a/src/apps/mandelbrot/main.cpp b/src/apps/mandelbrot/main.cpp new file mode 100644 index 0000000000..2394baa409 --- /dev/null +++ b/src/apps/mandelbrot/main.cpp @@ -0,0 +1,237 @@ +//****************************************************************************** +// +// File: main.cpp +// +//****************************************************************************** + +/* + Copyright 1993-1999, Be Incorporated. All Rights Reserved. + This file may be used under the terms of the Be Sample Code License. +*/ + +#include + +#ifndef _OS_H +#include +#endif +#ifndef _APPLICATION_H +#include +#endif +#ifndef _ROSTER_H +#include +#endif +#ifndef _BITMAP_H +#include +#endif +#ifndef _MENU_ITEM_H +#include +#endif +#ifndef _MENU_H +#include +#endif +#ifndef _MENU_BAR_H +#include +#endif +#ifndef _SCROLL_VIEW_H +#include +#endif +#ifndef _ALERT_H +#include +#endif + +#include + + +#include "tsb.h" + +#include + +/*------------------------------------------------------------*/ +/* Those are the menu item id's of the main window */ + +#define P1 0x60 +#define P2 0x61 +#define P3 0x62 +#define P4 0x63 + +/*------------------------------------------------------------*/ + +class TMainWindow : public BWindow { +public: + TMainWindow(BRect bound, char *name, window_type type, + long flags); +virtual void MessageReceived(BMessage *an_event); +virtual void FrameResized(float, float); +virtual bool QuitRequested(); + +virtual void UpdateScrollBars(); + +private: + TShowBit *the_view; +}; + +/*------------------------------------------------------------*/ + +TMainWindow::TMainWindow(BRect bound, char *name, window_type type, long flags) + : BWindow(bound, name, type, flags) +{ + BMenu *a_menu; + BRect a_rect; + BScrollView *scroll_view; + BMenuBar *menubar; + TShowBit *my_view; + BMenuItem *item; + + Lock(); + + a_rect.Set( 0, 0, 1000, 15); + menubar = new BMenuBar(a_rect, "MB"); + + a_menu = new BMenu("File"); + a_menu->AddItem(new BMenuItem("Quit", new BMessage(B_QUIT_REQUESTED), 'Q')); + menubar->AddItem(a_menu); + + a_menu = new BMenu("Palette"); + a_menu->AddItem(new BMenuItem("Palette1", new BMessage(P1))); + a_menu->AddItem(new BMenuItem("Palette2", new BMessage(P2))); + a_menu->AddItem(item = new BMenuItem("Palette3", new BMessage(P3))); + a_menu->AddItem(new BMenuItem("Palette4", new BMessage(P4))); + menubar->AddItem(a_menu); + + item->SetMarked(TRUE); + a_menu->SetRadioMode(TRUE); + + a_menu = new BMenu("Iterations"); + a_menu->AddItem(new BMenuItem("128", new BMessage(128))); + a_menu->AddItem(item = new BMenuItem("256", new BMessage(256))); + a_menu->AddItem(new BMenuItem("384", new BMessage(384))); + a_menu->AddItem(new BMenuItem("512", new BMessage(512))); + a_menu->AddItem(new BMenuItem("768", new BMessage(768))); + a_menu->AddItem(new BMenuItem("1024", new BMessage(1024))); + menubar->AddItem(a_menu); + + item->SetMarked(TRUE); + a_menu->SetRadioMode(TRUE); + + AddChild(menubar); + float mb_height = menubar->Bounds().Height(); + + a_rect.Set(0, mb_height + 1, 188 - B_V_SCROLL_BAR_WIDTH, + 188 - B_H_SCROLL_BAR_HEIGHT); + the_view = my_view = new TShowBit(a_rect, B_FOLLOW_ALL | B_WILL_DRAW); + scroll_view = new BScrollView("scroll view", my_view, B_FOLLOW_ALL, B_WILL_DRAW, + TRUE, TRUE, B_NO_BORDER); +// my_view->ResizeBy(-1, -1); + AddChild(scroll_view); + SetSizeLimits(80, size_x + 13, 80 + 20, size_y + mb_height + 1 + 13); + ResizeTo(size_x + 13, size_y + mb_height + 1 + 13); + SetPulseRate(150000); + UpdateScrollBars(); + Show(); + Unlock(); +} + +/*------------------------------------------------------------*/ + +void TMainWindow::UpdateScrollBars() +{ + BScrollView* scrollview; + BScrollBar* scrollbar; + BRect visible_extent; + BRect total_extent; + BRect bound; + BRect my_bounds; + long max; + + Lock(); + if ((scrollview = (BScrollView*)FindView("scroll view"))) { + bound.Set(0, 0, size_x, size_y); + my_bounds = Bounds(); + + visible_extent = bound & my_bounds; + total_extent = bound | my_bounds; + + scrollbar = scrollview->ScrollBar(B_HORIZONTAL); + max = (long) (bound.Width() - my_bounds.Width()); + if (max < 0) + max = 0; + scrollbar->SetRange(0, max); + scrollbar->SetProportion(visible_extent.Width() / total_extent.Width()); + + scrollbar = scrollview->ScrollBar(B_VERTICAL); + max = (long) (bound.Height() - my_bounds.Height()); + if (max < 0) + max = 0; + scrollbar->SetRange(0, max); + scrollbar->SetProportion(visible_extent.Height() / total_extent.Height()); + } + Unlock(); +} + +//------------------------------------------------------------ +void TMainWindow::FrameResized(float, float) +{ + UpdateScrollBars(); +} + +/*------------------------------------------------------------*/ + +bool TMainWindow::QuitRequested() +{ + if (the_view->busy) { + the_view->exit_now = TRUE; + PostMessage(B_QUIT_REQUESTED); + return FALSE; + } + + be_app->PostMessage(B_QUIT_REQUESTED); + return(TRUE); +} + +/*------------------------------------------------------------*/ + +void TMainWindow::MessageReceived(BMessage *an_event) +{ + + switch(an_event->what) { + case P1 : + case P2 : + case P3 : + case P4 : + the_view->set_palette(an_event->what - P1); + break; + + case 128 : + case 256 : + case 384 : + case 512 : + case 768 : + case 1024 : + the_view->set_iter(an_event->what); + break; + + default: + inherited::MessageReceived(an_event); + break; + } +} + +/*------------------------------------------------------------*/ + +int main(int, char**) +{ + BApplication *my_app; + TMainWindow *a_window; + BRect a_rect; + + set_thread_priority(find_thread(NULL), B_DISPLAY_PRIORITY); + + my_app = new BApplication("application/x-vnd.Be-MAND"); + + a_rect.Set(100, 100, 288, 288); + a_window = new TMainWindow(a_rect, "Mandelbrot", B_DOCUMENT_WINDOW, + B_WILL_ACCEPT_FIRST_CLICK); + my_app->Run(); + + delete my_app; +} diff --git a/src/apps/mandelbrot/tsb.cpp b/src/apps/mandelbrot/tsb.cpp new file mode 100644 index 0000000000..d03973929d --- /dev/null +++ b/src/apps/mandelbrot/tsb.cpp @@ -0,0 +1,584 @@ +//****************************************************************************** +// +// File: tsb.cpp +// +//****************************************************************************** + +/* + Copyright 1993-1999, Be Incorporated. All Rights Reserved. + This file may be used under the terms of the Be Sample Code License. +*/ + +#include +#include + +#include +#include +#include +#include + +#include "tsb.h" + +#ifndef _INTERFACE_DEFS_H +#include +#endif + +/*------------------------------------------------------------*/ + +TShowBit *tsbb; + +/*------------------------------------------------------------*/ +long niter = 256; +/*------------------------------------------------------------*/ + +uchar palette[256]; + +/*------------------------------------------------------------*/ + +void TShowBit::MouseDown(BPoint where) +{ + if (!this->Window()->IsActive()) { + this->Window()->Activate(TRUE); + this->Window()->UpdateIfNeeded(); + } + + if (busy) + return; + + if ((modifiers() & B_SHIFT_KEY) == 0) { + change_selection(where.x, where.y); + if ((selection.bottom - selection.top) < 4) + return; + } + redraw_mand(); +} + +/*------------------------------------------------------------*/ + +void TShowBit::redraw_mand() +{ + double px0; + double py0; + double scale0; + + if (modifiers() & B_SHIFT_KEY) { + px -= (scale / 2.0); + py -= (scale / 2.0); + scale *= 2.0; + } + else { + px0 = px + (scale * (selection.left / (1.0*size_x))); + py0 = py + (scale * (selection.top / (1.0*size_x))); + scale0 = scale * ((selection.bottom-selection.top) / (1.0*size_x)); + + px = px0; py = py0; scale = scale0; + } + selection.Set(-1000, -1000, -1000, -1000); + mand(px, py, scale, scale); + +} + +/*------------------------------------------------------------*/ + +void TShowBit::set_iter(long it) +{ + if (it != iter) { + iter = it; + niter = it; + selection.Set(-1000, -1000, -1000, -1000); + mand(px, py, scale, scale); + } +} + +/*------------------------------------------------------------*/ + +void TShowBit::set_palette(long code) +{ + rgb_color c; + long i; + + BScreen screen( Window() ); + + if (code == 0) { + for (i = 0; i < 256; i++) + palette[i] = (i >> 1) & 0x1f; + } + if (code == 1) { + for (i = 0; i < 256; i++) { + c.red = i * 4; + c.green = i * 7; + c.blue = 256-(i - i * 5); + palette[i] = screen.IndexForColor(c); + } + } + + if (code == 2) { + for (i = 0; i < 256; i++) { + c.red = (i * 7); + c.green = i/2; + c.blue = 256-(i * 3); + palette[i] = screen.IndexForColor(c); + } + } + + if (code == 3) { + for (i = 0; i < 256; i++) { + c.red = 256-(i * 6); + c.green = (i * 7); + c.blue = 0; + palette[i] = screen.IndexForColor(c); + } + } + mand(px, py, scale, scale); +} + +/*------------------------------------------------------------*/ + +TShowBit::TShowBit(BRect r, long flags) : + BView(r, "", flags, B_WILL_DRAW | B_PULSE_NEEDED) +{ + BRect bitmap_r; + char *bits; + + busy = FALSE; + exit_now = FALSE; + tsbb = this; + bitmap_r.Set(0, 0, size_x - 1, size_y - 1); + selection.Set(-1000, -1000, -1000, -1000); + iter = 256; + + the_bitmap = new BBitmap(bitmap_r, B_COLOR_8_BIT); + bits = (char *)the_bitmap->Bits(); + memset(bits, 0x00, size_x*size_y); + px = -1.5; + py = -1.5; + scale = 3.0; + set_palette(2); +} + +/*------------------------------------------------------------*/ + +TShowBit::~TShowBit() +{ + delete the_bitmap; +} + +/*------------------------------------------------------------*/ + +void TShowBit::Draw(BRect update_rect) +{ + DrawBitmap(the_bitmap, BPoint(0, 0)); +} + + +/*------------------------------------------------------------*/ + + +int iterate1(double a, double b) +{ + double x; + double y; + double xsq; + double ysq; + double ctwo = 2.0, cfour = 4.0; + int i = 0, iter = niter; + + x = 0.0; + y = 0.0; + + while (i < iter) { + xsq = x * x; + ysq = y * y; + y = (ctwo * x * y) + b; + i++; + x = a + (xsq - ysq); + + if ((xsq + ysq) > cfour) + return(i); + } + return(i); +} + +/*------------------------------------------------------------*/ +//extern "C" int iterate(float a, float b); +/*------------------------------------------------------------*/ + +int iterate(float a, float b) +{ + float x; + float y; + float xsq; + float ysq; +// These are variables, because the metaware compiler would reload the +// constants from memory each time through the loop rather than leave them +// in registers. Lovely. + float ctwo = 2.0, cfour = 4.0; + long i; + int iter = niter; + + x = 0.0; + y = 0.0; + i = 0; + + while (i < iter) { + xsq = x * x; + ysq = y * y; + y = (ctwo * x * y) + b; + i++; + x = a + (xsq - ysq); + + if ((xsq + ysq) > cfour) + return(i); + } + return(i); +} + +/*------------------------------------------------------------*/ + +double vvx; +double vvy; +double ssx; +char t1_done; +char t2_done; + +/*------------------------------------------------------------*/ + +long __calc1(void *arg) +{ + tsbb->manda(vvx, vvy, ssx, ssx); + return B_NO_ERROR; +} + +/*------------------------------------------------------------*/ + +long __calc2(void *arg) +{ + tsbb->mandb(vvx, vvy, ssx, ssx); + return B_NO_ERROR; +} + +/*------------------------------------------------------------*/ + +uchar tmp[256]; +uchar pc[32][32]; +uchar tmp1[256]; + +/*------------------------------------------------------------*/ + +void TShowBit::mand(double vx, double vy, double sx, double sy) +{ + vvx = vx; vvy = vy; ssx = sx; + t1_done = 0; t2_done = 0; + + precompute(vx, vy, sx, sy); + + resume_thread(spawn_thread(__calc1, "calc1", B_NORMAL_PRIORITY, NULL)); + resume_thread(spawn_thread(__calc2, "calc2", B_NORMAL_PRIORITY, NULL)); + busy = TRUE; +} + +/*------------------------------------------------------------*/ + +void TShowBit::Pulse() +{ +// PRINT(("pulsing (%d)\n", busy)); + if (busy) { + Draw(BRect(0,0,0,0)); + if (t1_done && t2_done) { + busy = FALSE; + exit_now = FALSE; + } + } +} + +/*------------------------------------------------------------*/ + +void TShowBit::precompute(double vx, double vy, double sx, double sy) +{ + long x, y; + double cx, cy; + double scale = sx; + + sx = sx / (32.0); + sy = sy / (32.0); + cy = vy; + + for (y = 0; y < 32; y++) { + cy += sy; + cx = vx; + if (scale < 0.000025 || niter != 256) { + for (x = 0; x < 32; x++) { + cx += sx; + pc[x][y] = iterate1(cx, cy); + } + } + else + for (x = 0; x < 32; x++) { + cx += sx; + pc[x][y] = iterate(cx, cy); + } + } +} + +/*------------------------------------------------------------*/ + +void TShowBit::mandb(double vx, double vy, double sx, double sy) +{ + long x, y; + long bx; + double cx, cy; + char v; + uchar *bits = (uchar *)the_bitmap->Bits(); + uchar *b0; + long y12; + long x12; + double scale = sx; + + sx = sx / (size_x * 1.0); + sy = sy / (size_y * 1.0); + cy = vy; + + cy += sy; + sy *= 2.0; + for (y = 1; y < size_y; y+=2) { + y12 = y / 12; + cy += sy; + cx = vx; + b0 = bits + (y * size_x); + for (bx = 0; bx < size_x; bx += 12) { + x12 = (bx+6) / 12; + v = pc[x12][y12]; + + if (exit_now) + goto done; + + if (v == pc[x12+1][y12] && + v == pc[x12][y12+1] && + v == pc[x12-1][y12] && + v == pc[x12][y12-1] && + v == pc[x12-2][y12]) { + for (x = bx; x < (bx+12); x++) { + cx += sx; + *b0++ = palette[v]; + } + } + else { + if (scale < 0.000025 || niter != 256) { + for (x = bx; x < (bx+12); x++) { + cx += sx; + v = iterate1(cx, cy); + *b0++ = palette[v]; + } + } + else + for (x = bx; x < (bx+12); x++) { + cx += sx; + v = iterate(cx, cy); + *b0++ = palette[v]; + } + } + } + } +done: + t2_done = 1; +} + +/*------------------------------------------------------------*/ + +void TShowBit::manda(double vx, double vy, double sx, double sy) +{ + long x, y; + long bx; + double cx, cy; + char v; + uchar *bits = (uchar *)the_bitmap->Bits(); + uchar *b0; + long y12; + long x12; + double scale = sx; + + sx = sx / (size_x * 1.0); + sy = sy / (size_y * 1.0); + cy = vy; + + sy *= 2.0; + for (y = 0; y < size_y; y+=2) { + y12 = y / 12; + cy += sy; + cx = vx; + b0 = bits + (y * size_x); + for (bx = 0; bx < size_x; bx += 12) { + x12 = (bx+6) / 12; + v = pc[x12][y12]; + + if (exit_now) + goto done; + + if (v == pc[x12+1][y12] && + v == pc[x12][y12+1] && + v == pc[x12-1][y12] && + v == pc[x12][y12-1] && + v == pc[x12-2][y12]) { + for (x = bx; x < (bx+12); x++) { + cx += sx; + *b0++ = palette[v]; + } + } + else { + if (scale < 0.000025 || niter != 256) { + for (x = bx; x < (bx+12); x++) { + cx += sx; + v = iterate1(cx, cy); + *b0++ = palette[v]; + } + } + else + for (x = bx; x < (bx+12); x++) { + cx += sx; + v = iterate(cx, cy); + *b0++ = palette[v]; + } + } + } + } +done: + t1_done = 1; +} + + +/*------------------------------------------------------------*/ + +long TShowBit::limit_v(long v) +{ + if (v > (size_y - 1)) + v = (size_y - 1); + + if (v < 0) + v = 0; + return(v); +} + +/*------------------------------------------------------------*/ + +long TShowBit::limit_h(long v) +{ + if (v > (size_x - 1)) + v = size_x - 1; + + if (v < 0) + v = 0; + return(v); +} + +/*------------------------------------------------------------*/ + +BRect TShowBit::sort_rect(BRect *aRect) +{ + BRect tmp_rect; + long tmp; + + tmp_rect = *aRect; + if (tmp_rect.bottom < tmp_rect.top) { + tmp = (long)tmp_rect.top; + tmp_rect.top = tmp_rect.bottom; + tmp_rect.bottom = tmp; + } + + if (tmp_rect.left > tmp_rect.right) { + tmp = (long) tmp_rect.right; + tmp_rect.right = tmp_rect.left; + tmp_rect.left = tmp; + } + + tmp_rect.top = limit_v(tmp_rect.top); + tmp_rect.left = limit_h(tmp_rect.left); + tmp_rect.bottom = limit_v(tmp_rect.bottom); + tmp_rect.right = limit_h(tmp_rect.right); + + return(tmp_rect); +} + +/*------------------------------------------------------------*/ + +void TShowBit::clip(long *h, long *v) +{ + if (*h > (size_x - 1)) + *h = (size_x - 1); + if (*h < 0) + *h = 0; + if (*v > (size_y - 1)) + *v = size_y - 1; + if (*v < 0) + *v = 0; +} + +/*------------------------------------------------------------*/ + +char TShowBit::has_selection() +{ + if (((selection.bottom - selection.top) + (selection.right - selection.left)) < 5) + return 0; + else + return 1; +} + +/*------------------------------------------------------------*/ + +void TShowBit::change_selection(long h, long v) +{ + ulong buttons; + long h0; + long v0; + BRect new_select; + BRect old_select; + BRect tmp_rect; + long max; + long width, height; + + clip(&h, &v); + new_select.top = v; + new_select.left = h; + old_select = selection; + + SetDrawingMode(B_OP_INVERT); + + do { + BPoint where; + GetMouse(&where, &buttons); + h0 = (long) where.x; + v0 = (long) where.y; + width = h0 - h; + height = v0 - v; + max= ((v0>v) ^ (height < width)) ? height : width; + + h0 = h+max; v0 = v+max; + + clip(&h0, &v0); + new_select.right = h0; + new_select.bottom = v0; + + if ((old_select.top != new_select.top) || + (old_select.bottom != new_select.bottom) || + (old_select.right != new_select.right) || + (old_select.left != new_select.left)) { + + tmp_rect = sort_rect(&new_select); + StrokeRect(tmp_rect); + + tmp_rect = sort_rect(&old_select); + StrokeRect(tmp_rect); + + old_select = new_select; + Flush(); + } + + snooze(20000); + } while(buttons); + + selection = sort_rect(&new_select); + if (!has_selection()) { + StrokeRect(selection); + selection.Set(-1000, -1000, -1000, -1000); + } + SetDrawingMode(B_OP_COPY); +} diff --git a/src/apps/mandelbrot/tsb.h b/src/apps/mandelbrot/tsb.h new file mode 100644 index 0000000000..b96536543c --- /dev/null +++ b/src/apps/mandelbrot/tsb.h @@ -0,0 +1,58 @@ +/* + Copyright 1999, Be Incorporated. All Rights Reserved. + This file may be used under the terms of the Be Sample Code License. +*/ + +#ifndef _VIEW_H +#include +#endif +#ifndef _BITMAP_H +#include +#endif + +#include + +#ifndef TSB +#define TSB + +/*------------------------------------------------------------*/ + +#define size_x 384 +#define size_y 384 + +/*------------------------------------------------------------*/ + +class TShowBit : public BView { +public: + BBitmap *the_bitmap; + bool busy; + bool exit_now; + BRect selection; + double px; + double py; + double scale; + long iter; + + TShowBit(BRect r, long flags); +virtual ~TShowBit(); +virtual void Draw(BRect); +virtual void MouseDown(BPoint where); +virtual void Pulse(); + void mand(double vx, double vy, double sx, double sy); + long limit_v(long v); + long limit_h(long h); + BRect sort_rect(BRect *aRect); + void clip(long *h, long *v); + void change_selection(long h, long v); + char has_selection(); + void redraw_mand(); + void mandb(double vx, double vy, double sx, double sy); + void manda(double vx, double vy, double sx, double sy); + void set_palette(long code); + void set_iter(long i); + void precompute(double vx, double vy, double sx, double sy); +}; + +/*------------------------------------------------------------*/ + +#endif diff --git a/src/apps/mandelbrot/tsb1.cpp b/src/apps/mandelbrot/tsb1.cpp new file mode 100644 index 0000000000..4acde1b15f --- /dev/null +++ b/src/apps/mandelbrot/tsb1.cpp @@ -0,0 +1,442 @@ +//****************************************************************************** +// +// File: main.cpp +// +// Description: show pixmap main test program. +// +// Written by: Benoit Schillings +// +// Change History: +// +// 7/31/92 bgs new today +// +//****************************************************************************** + +/* + Copyright 1992-1999, Be Incorporated. All Rights Reserved. + This file may be used under the terms of the Be Sample Code License. +*/ + +#include +#include + +#include "tsb.h" + +/*------------------------------------------------------------*/ + +TShowBit *tsbb; + +/*------------------------------------------------------------*/ + +uchar palette[256]; + +/*------------------------------------------------------------*/ + +void TShowBit::MouseDown(BPoint where) +{ + if ((Modifiers() & SHIFT_KEY) == 0) { + change_selection(where.x, where.y); + } + redraw_mand(); +} + +/*------------------------------------------------------------*/ + +void TShowBit::redraw_mand() +{ + float px0; + float py0; + float scale0; + + if (Modifiers() & SHIFT_KEY) { + px -= (scale / 2.0); + py -= (scale / 2.0); + scale *= 2.0; + } + else { + px0 = px + (scale * (selection.left / (1.0*size_x))); + py0 = py + (scale * (selection.top / (1.0*size_x))); + scale0 = scale * ((selection.bottom-selection.top) / (1.0*size_x)); + + px = px0; py = py0; scale = scale0; + } + + selection.Set(-1000, -1000, -1000, -1000); + mand(px, py, scale, scale); +} + +/*------------------------------------------------------------*/ + +void TShowBit::set_palette(long code) +{ + rgb_color c; + long i; + + if (code == 0) { + for (i = 0; i < 256; i++) + palette[i] = (i >> 1) & 0x1f; + } + if (code == 1) { + for (i = 0; i < 256; i++) { + c.red = i; + c.green = 0; + c.blue = 256-i; + palette[i] = index_for_color(c); + } + } + + if (code == 2) { + for (i = 0; i < 256; i++) { + c.red = i; + c.green = i/2; + c.blue = 256-i; + palette[i] = index_for_color(c); + } + } + + if (code == 3) { + for (i = 0; i < 256; i++) { + c.red = 256-i; + c.green = i; + c.blue = 0; + palette[i] = index_for_color(c); + } + } +} + +/*------------------------------------------------------------*/ + +void TShowBit::TShowBit(BRect r, long flags) : + BView(r, "", flags, WILL_DRAW) +{ + BRect bitmap_r; + long ref; + long i; + char *bits; + + tsbb = this; + set_palette(0); + exit_now = 0; + bitmap_r.Set(0, 0, size_x - 1, size_y - 1); + selection.Set(-1000, -1000, -1000, -1000); + + the_bitmap = new BBitmap(bitmap_r, COLOR_8_BIT); + bits = (char *)the_bitmap->Bits(); + memset(bits, 0x00, size_x*size_y); + px = -1.5; + py = -1.5; + scale = 3.0; +} + +/*------------------------------------------------------------*/ + +TShowBit::~TShowBit() +{ + delete the_bitmap; +} + +/*------------------------------------------------------------*/ + +void TShowBit::Draw(BRect update_rect) +{ + DrawBitmap(the_bitmap, BPoint(0, 0)); +} + + +/*------------------------------------------------------------*/ + +void TShowBit::demo() +{ +} + +/*------------------------------------------------------------*/ +extern "C" int iterate(float a, float b); +/*------------------------------------------------------------*/ + +float vvx; +float vvy; +float ssx; +char t1_done; +char t2_done; + +/*------------------------------------------------------------*/ + +void __calc1() +{ + tsbb->manda(vvx, vvy, ssx, ssx); +} + +/*------------------------------------------------------------*/ + +void __calc2() +{ + tsbb->mandb(vvx, vvy, ssx, ssx); +} + +/*------------------------------------------------------------*/ + +uchar tmp[256]; +uchar pc[32][32]; +uchar tmp1[256]; + +/*------------------------------------------------------------*/ + +void TShowBit::mand(float vx, float vy, float sx, float sy) +{ + vvx = vx; vvy = vy; ssx = sx; + t1_done = 0; t2_done = 0; + + precompute(vx, vy, sx, sy); + + resume_thread(spawn_thread(__calc1, "calc1", 20, 0, 0)); + resume_thread(spawn_thread(__calc2, "calc2", 20, 0, 0)); + while(1) { + snooze(100000); + Draw(BRect(0,0,0,0)); + if (t1_done && t2_done) + break; + } + Draw(BRect(0,0,0,0)); +} + +/*------------------------------------------------------------*/ + +void TShowBit::precompute(float vx, float vy, float sx, float sy) +{ + long x, y; + long i; + long nx, ny; + float cx, cy; + char v; + char *p; + + sx = sx / (32.0); + sy = sy / (32.0); + cy = vy; + + for (y = 0; y < 32; y++) { + cy += sy; + cx = vx; + for (x = 0; x < 32; x++) { + cx += sx; + pc[x][y] = iterate(cx, cy); + } + } +} + +/*------------------------------------------------------------*/ + +void TShowBit::mandb(float vx, float vy, float sx, float sy) +{ + long x, y; + long bx; + long i; + long nx, ny; + float cx, cy; + char v; + char *p; + uchar *bits = (char *)the_bitmap->Bits(); + uchar *b0; + long y12; + long x12; + + sx = sx / (size_x * 1.0); + sy = sy / (size_y * 1.0); + cy = vy; + + cy += sy; + sy *= 2.0; + for (y = 1; y < size_y; y+=2) { + y12 = y / 12; + cy += sy; + cx = vx; + b0 = bits + (y * size_x); + for (bx = 0; bx < size_x; bx += 12) { + for (x = bx; x < (bx+12); x++) { + cx += sx; + v = iterate(cx, cy); + *b0++ = palette[v]; + } + } + } + t2_done = 1; +} + +/*------------------------------------------------------------*/ + + +void TShowBit::manda(float vx, float vy, float sx, float sy) +{ + long x, y; + long i; + long nx, ny; + long bx; + float cx, cy; + char v; + char *p; + uchar *bits = (char *)the_bitmap->Bits(); + uchar *b0; + long y12; + long x12; + + sx = sx / (size_x * 1.0); + sy = sy / (size_y * 1.0); + cy = vy; + + sy *= 2.0; + for (y = 0; y < size_y; y+=2) { + y12 = y / 12; + cy += sy; + cx = vx; + b0 = bits + (y * size_x); + for (bx = 0; bx < size_x; bx += 12) { + for (x = bx; x < (bx+12); x++) { + cx += sx; + v = iterate(cx, cy); + *b0++ = palette[v]; + } + } + } + t1_done = 1; +} + + +/*------------------------------------------------------------*/ + +long TShowBit::limit_v(long v) +{ + if (v > (size_y - 1)) + v = (size_y - 1); + + if (v < 0) + v = 0; + return(v); +} + +/*------------------------------------------------------------*/ + +long TShowBit::limit_h(long v) +{ + if (v > (size_x - 1)) + v = size_x - 1; + + if (v < 0) + v = 0; + return(v); +} + +/*------------------------------------------------------------*/ + +BRect TShowBit::sort_rect(BRect *aRect) +{ + BRect tmp_rect; + long tmp; + + tmp_rect = *aRect; + if (tmp_rect.bottom < tmp_rect.top) { + tmp = tmp_rect.top; + tmp_rect.top = tmp_rect.bottom; + tmp_rect.bottom = tmp; + } + + if (tmp_rect.left > tmp_rect.right) { + tmp = tmp_rect.right; + tmp_rect.right = tmp_rect.left; + tmp_rect.left = tmp; + } + + tmp_rect.top = limit_v(tmp_rect.top); + tmp_rect.left = limit_h(tmp_rect.left); + tmp_rect.bottom = limit_v(tmp_rect.bottom); + tmp_rect.right = limit_h(tmp_rect.right); + + return(tmp_rect); +} + +/*------------------------------------------------------------*/ + +void TShowBit::clip(long *h, long *v) +{ + if (*h > (size_x - 1)) + *h = (size_x - 1); + if (*h < 0) + *h = 0; + if (*v > (size_y - 1)) + *v = size_y - 1; + if (*v < 0) + *v = 0; +} + +/*------------------------------------------------------------*/ + +char TShowBit::has_selection() +{ + if (((selection.bottom - selection.top) + (selection.right - selection.left)) < 5) + return 0; + else + return 1; +} + +/*------------------------------------------------------------*/ + +void TShowBit::change_selection(long h, long v) +{ + ulong buttons; + long h0; + long v0; + BRect new_select; + BRect old_select; + BRect tmp_rect; + long max; + long width, height; + + clip(&h, &v); + new_select.top = v; + new_select.left = h; + old_select = selection; + + SetDrawingMode(OP_INVERT); + + do { + BPoint where; + GetMouse(&where, &buttons); + h0 = where.x; + v0 = where.y; + width = h0 - h; + height = v0 - v; + if (height > width) + max = height; + else + max = height; + + h0 = h+max; v0 = v+max; + + clip(&h0, &v0); + new_select.right = h0; + new_select.bottom = v0; + + if ((old_select.top != new_select.top) || + (old_select.bottom != new_select.bottom) || + (old_select.right != new_select.right) || + (old_select.left != new_select.left)) { + + tmp_rect = sort_rect(&new_select); + StrokeRect(tmp_rect); + + tmp_rect = sort_rect(&old_select); + StrokeRect(tmp_rect); + + old_select = new_select; + Flush(); + } + + sleept(20); + } while(buttons); + + selection = sort_rect(&new_select); + if (!has_selection()) { + StrokeRect(selection); + selection.Set(-1000, -1000, -1000, -1000); + } + SetDrawingMode(OP_COPY); +}